From fb3849bf1ebd1a7a2761283d8d023f17b1afeef5 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 4 Jul 2020 12:39:21 +0200 Subject: [PATCH 001/314] Bump to 0.41-SNAPSHOT --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ba9bac540..7c0f3b6b4 100644 --- a/build.gradle +++ b/build.gradle @@ -47,7 +47,7 @@ ext.libs = [ ] allprojects { - version = '0.40' + version = '0.41-SNAPSHOT' configurations { compilerLib From 2ec45f22dcc920f0c77be9d18d49211cef219314 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 7 Jul 2020 09:35:22 +0200 Subject: [PATCH 002/314] Updated README + update gradle --- README.md | 7 +- changelog-0.38.txt | 36 -------- changelog-0.39.md | 104 ----------------------- gradle/wrapper/gradle-wrapper.properties | 2 +- 4 files changed, 3 insertions(+), 146 deletions(-) delete mode 100644 changelog-0.38.txt delete mode 100644 changelog-0.39.md diff --git a/README.md b/README.md index 4d951e102..a2adbe70f 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,10 @@ ![emuStudio Build](https://github.com/emustudio/emuStudio/workflows/emuStudio%20Build/badge.svg) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) -Buy Me A Coffee - [emuStudio](https://www.emustudio.net/) is a desktop application used for computer emulation and writing programs for emulated computers. It extensible; it encourages developers to write their own computer emulators. The main goal of emuStudio is to support the "compile-load-emulate" workflow, aiming at students or anyone to help to learn about older but important computers or even abstract machines. - -Nowadays, the ability to write programs for vintage computers is probably not quite interesting for the market, -but I guess emulation has always been more about fun, nostalgia, and culture - trying to keep alive something which was outstanding at its peak, and preserve memories. emuStudio is very appropriate for use at schools, e.g. when students are doing first steps in assembler, or when they are taught about computer history. For example, emuStudio is used at the [Technical University of Košice](http://www.fei.tuke.sk/en) since 2007. @@ -66,6 +61,8 @@ which includes information like: - Which git branch to use - Which rules needs to be followed +Buy Me A Coffee + ### Related projects There exist some additional projects, which are used by emuStudio, useful for contributors: diff --git a/changelog-0.38.txt b/changelog-0.38.txt deleted file mode 100644 index fc33dabf5..000000000 --- a/changelog-0.38.txt +++ /dev/null @@ -1,36 +0,0 @@ -Changelog of emuStudio 0.37b -> 0.38b -===================================== - -- Add possibility to modify settings of plug-ins in abstract schema - editor by double-clicking on an element or with using pop-up menu - with right-click on an element. - -- Fixed several bugs in abstract schema drawing - -- Added pop-up menu when user right clicks on an element in abstract schema -- Add ability to resize elements in abstract schema -- Add useGrid, gridGap and width/height of all elements into schema and configuration file - -- Fixed debug table column title: mnemo to opcode -- Created listener for possibility to call updates on debug table by any plugins. - -- Fixed bug: when deleted last computer in computers dialog, exception was thrown -- Changed Vector to ArrayList in HighlightThread - -- Fixed bug in text editor: file saving - -- Fixed bug in 'view of computer' - devices were shown weirdly - -- Fixed synchronization problems in automatized emulation execution -- Added new parameter "--nogui" that won't show GUI in the automatization - -- Fixed automatization, now "auto" setting is set to "true" if the emulation is automatized. - Plugins may read this setting to determine this. - -- Fixed possible NullPointerExceptions throws when disassembler is not implemented inside a CPU - -- Re-implement pagination in the debug table - -- Next try to overcome thread deadlock bug connected with syntax highlighting :( - -- Make all rows in debug table visible diff --git a/changelog-0.39.md b/changelog-0.39.md deleted file mode 100644 index a788d109b..000000000 --- a/changelog-0.39.md +++ /dev/null @@ -1,104 +0,0 @@ -Release Notes for emuStudio version 0.39 -(c) Copyright 2006-2017, Peter Jakubčo - -# New computers: -- RASP (raspc-rasp, rasp-cpu, rasp-mem) - thanks to Michal Šipoš -- SSEM (as-ssem, ssem-cpu, ssem-mem, ssem-display) -- re-implemented BrainDuck - -# Whole project: -- introduced logging using logback+slf4j -- introduced Maven 3 for dependency and project management -- new user documentation was created -- new developer's guide was created -- new website was created -- emulation automation was fixed for all machines (MITS Altair, RAM, RASP, BrainDuck, SSEM) -- lots of refactorings -- introduction of Travis CI - -# main-module: -- rewritten debugger and disassembler -- introduced pagination in debugger -- introduced saving computer schema to image -- better place location of splitter for editor / compiler output -- fixed GUI problems -- "previous instruction" just decrements program counter -- fixed syntax highlighting -- fixed: on breakpoint, instruction list was not pointing at current (next) instruction -- fixed: on 'pages backwards' button when the input window is cancelled, NullPointerException appeared in log -- fixed: when file was not saved before compilation, on most compilers NullPointerException appeared in log -- fixed: in source code editor, when open file is cancelled, compiler output window was cleared -- find/replace dialog is now possible to be cancelled with ESC key -- schema editor: enable breaking connection lines with movable pins -- fixed undo/redo capability -- fixed: deadlock in source code editor - -# as-8080: -- fixed `db 'if'` -- added command line -- fixed compiling `ani` instruction -- better error recovery implementation -- fixed: relative path to include files did not work - -# as-z80: -- fixed `db 'if'` does not work -- added command line -- better error recovery implementation -- fixed: relative path to include files did not work - -# 8080-cpu: -- introduced real-time program dumping -- refactorted + thoroughly tested -- fixed: PC change did not update the status panel GUI -- fixed decoder and disassembler (bug in edigen) -- fixed: `inc` and `dcr` instructions - -# z80-cpu: -- introduced real-time program dumping -- refactorted + thoroughly tested -- fixed: PC change did not update the status panel GUI -- fixed: z80 JR xx,label incorrectly calculated offset -- refactored GUI - -# 88-disk: -- introduced Java NIO to improve performance - -# 88-sio: -- fixed: status port manipulation -- add ability to bind to multiple CPU ports -- fixed: NPE in MITS 88-SIO - -# standard-mem: -- add possibility to load image at runtime with a button -- add possibility to find a sequence - -# adm3A-terminal: -- fixed cursor blinking -- fixed: terminal did not accept CTRL+C -- fixed: terminal could load custom font - -# ramc-ram -- added command line -- better error recovery implementation - -# ram-cpu: -- IP change does not update the status panel GUI -- Introduce 'label' column in debug table - -# ram-mem -- problem with loading programs - -# abstractTape-ram -- canceling the edit of the symbol in the abstract tape does not work -- display a number of registers it's pointing at - -# brainc-brainduck -- added command line -- reimplemented to real brainfuck language - -# brainduck-cpu: -- fixed: when BrainDuck CPU was reset, it did not clear memory -- introduced profiler for improving performance - -# brainduck-terminal: -- reimplemented diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 84a906615..ac33e9944 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From aa02b176e080e7b8b2654f3e0428731bf9061c52 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 7 Jul 2020 15:32:35 +0200 Subject: [PATCH 003/314] [#162] Tiny refactoring --- .../plugins/device/mits88disk/DeviceImpl.java | 42 +- .../plugins/device/mits88disk/Drive.java | 363 ---------------- .../device/mits88disk/drive/Drive.java | 402 ++++++++++++++++++ .../mits88disk/drive/DriveCollection.java | 50 +++ .../mits88disk/drive/DriveListener.java | 8 + .../mits88disk/drive/DriveParameters.java | 27 ++ .../device/mits88disk/gui/DiskGui.java | 22 +- .../device/mits88disk/gui/SettingsDialog.java | 43 +- .../device/mits88disk/ports/ControlPort.java | 8 +- .../device/mits88disk/ports/DataPort.java | 24 +- .../device/mits88disk/ports/StatusPort.java | 8 +- .../plugins/device/mits88disk/DriveTest.java | 47 +- 12 files changed, 572 insertions(+), 472 deletions(-) delete mode 100644 plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/Drive.java create mode 100644 plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/Drive.java create mode 100644 plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveCollection.java create mode 100644 plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveListener.java create mode 100644 plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveParameters.java diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/DeviceImpl.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/DeviceImpl.java index 6e44f65ac..5d60dcf59 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/DeviceImpl.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/DeviceImpl.java @@ -28,6 +28,8 @@ import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.device.mits88disk.drive.Drive; +import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; import net.emustudio.plugins.device.mits88disk.gui.DiskGui; import net.emustudio.plugins.device.mits88disk.gui.SettingsDialog; import net.emustudio.plugins.device.mits88disk.ports.ControlPort; @@ -49,12 +51,10 @@ public class DeviceImpl extends AbstractDevice { private final static Logger LOGGER = LoggerFactory.getLogger(DeviceImpl.class); - private final static int DRIVES_COUNT = 16; public final static int DEFAULT_CPU_PORT1 = 0x8; public final static int DEFAULT_CPU_PORT2 = 0x9; public final static int DEFAULT_CPU_PORT3 = 0xA; - private final List drives = new ArrayList<>(); private final StatusPort statusPort; private final ControlPort controlPort; private final DataPort dataPort; @@ -65,26 +65,22 @@ public class DeviceImpl extends AbstractDevice { private int port1CPU; private int port2CPU; private int port3CPU; - private int currentDrive; + private DiskGui gui; + private final DriveCollection drives = new DriveCollection(); public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); this.guiNotSupported = settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); - for (int i = 0; i < DRIVES_COUNT; i++) { - drives.add(new Drive(i)); - } - - this.currentDrive = 0; // TODO: what should be here? port1CPU = DEFAULT_CPU_PORT1; port2CPU = DEFAULT_CPU_PORT2; port3CPU = DEFAULT_CPU_PORT3; - statusPort = new StatusPort(this); - controlPort = new ControlPort(this); - dataPort = new DataPort(this); + statusPort = new StatusPort(drives); + controlPort = new ControlPort(drives); + dataPort = new DataPort(drives); } @Override @@ -138,7 +134,7 @@ public void destroy() { cpuContext.detachDevice(0x9); cpuContext.detachDevice(0xA); } - drives.clear(); + drives.destroy(); } @Override @@ -148,14 +144,6 @@ public void showSettings(JFrame parent) { } } - public Drive getCurrentDrive() { - return drives.get(currentDrive); - } - - public void setCurrentDrive(int index) { - currentDrive = index; - } - @Override public boolean isShowSettingsSupported() { return !guiNotSupported; @@ -166,16 +154,13 @@ private void readSettings() { port2CPU = settings.getInt(SettingsConstants.PORT2_CPU, DEFAULT_CPU_PORT2); port3CPU = settings.getInt(SettingsConstants.PORT3_CPU, DEFAULT_CPU_PORT3); - for (int i = 0; i < DRIVES_COUNT; i++) { - Drive drive = drives.get(i); - + drives.foreach((i, drive) -> { int sectorLength = settings.getInt(SettingsConstants.SECTOR_LENGTH + i, Drive.DEFAULT_SECTOR_LENGTH); - drive.setSectorLength(sectorLength); - int sectorsCount = settings.getInt(SettingsConstants.SECTORS_COUNT + i, Drive.DEFAULT_SECTORS_COUNT); - drive.setSectorsCount(sectorsCount); - String imagePath = settings.getString(SettingsConstants.IMAGE + i, null); + + drive.setSectorLength(sectorLength); + drive.setSectorsCount(sectorsCount); Optional.ofNullable(imagePath).ifPresent(path -> { try { drive.mount(Path.of(path)); @@ -187,7 +172,8 @@ private void readSettings() { ); } }); - } + return null; + }); } private int attachPort(int diskPortNumber, DeviceContext diskPort, int cpuPort) throws PluginInitializationException { diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/Drive.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/Drive.java deleted file mode 100644 index 04a60e813..000000000 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/Drive.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88disk; - -import net.jcip.annotations.Immutable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.SeekableByteChannel; -import java.nio.file.Files; -import java.nio.file.OpenOption; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.util.HashSet; -import java.util.Set; - -/** - * Performs disk operations on single drive. - */ -public class Drive { - private static final Logger LOGGER = LoggerFactory.getLogger(Drive.class); - - public final static short DEFAULT_SECTORS_COUNT = 32; - public final static short DEFAULT_SECTOR_LENGTH = 137; - - private volatile int sectorsCount = DEFAULT_SECTORS_COUNT; - private volatile int sectorLength = DEFAULT_SECTOR_LENGTH; - - private volatile int track; - private volatile int sector; - private volatile int sectorOffset; - - private Path mountedFloppy = null; - private SeekableByteChannel imageChannel; - private boolean selected = false; - - private volatile DriveListener listener; - private final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1); - - private final int index; - - /* - 7 6 5 4 3 2 1 0 - +---+---+---+---+---+---+---+---+ - | R | Z | I | X | X | H | M | W | - +---+---+---+---+---+---+---+---+ - - W - When 0, write circuit ready to write another byte. - M - When 0, head movement is allowed - H - When 0, indicates head is loaded for read/write - X - not used (will be 0) - I - When 0, indicates interrupts enabled (not used this emulator) - Z - When 0, indicates head is on track 0 - R - When 0, indicates that read circuit has new byte to read - */ - private short port1status; - private short port2status; - - @Immutable - public static final class DriveParameters { - public final short port1status; - public final short port2status; - - public final int track; - public final int sector; - public final int sectorOffset; - - public final Path mountedFloppy; - - public DriveParameters(short port1status, short port2status, int track, int sector, int sectorOffset, - Path mountedFloppy) { - this.port1status = port1status; - this.port2status = port2status; - this.track = track; - this.sector = sector; - this.sectorOffset = sectorOffset; - this.mountedFloppy = mountedFloppy; - } - } - - public interface DriveListener { - - void driveSelect(boolean sel); - - void driveParamsChanged(DriveParameters parameters); - } - - public Drive(int index) { - this.index = index; - init(); - } - - private void init() { - track = 0; - sector = 0; - sectorOffset = 0; - port1status = 0xE7; // 11100111b - port2status = 0xC1; - } - - public void setSectorsCount(int sectorsCount) { - if (sectorsCount <= 0) { - throw new IllegalArgumentException("[drive=" + index + "] Sectors count must be > 0"); - } - this.sectorsCount = sectorsCount; - init(); - } - - public void setSectorLength(int sectorLength) { - if (sectorLength <= 0) { - throw new IllegalArgumentException("[drive=" + index + "] Sector length must be > 0"); - } - this.sectorLength = sectorLength; - init(); - } - - public int getSectorsCount() { - return sectorsCount; - } - - public int getSectorLength() { - return sectorLength; - } - - public void setDriveListener(DriveListener listener) { - this.listener = listener; - } - - private void notifyDiskSelected() { - DriveListener tmpListener = listener; - if (tmpListener != null) { - tmpListener.driveSelect(selected); - } - } - - private void notifyParamsChanged() { - DriveListener tmpListener = listener; - if (tmpListener != null) { - tmpListener.driveParamsChanged(new DriveParameters( - port1status, port2status, track, sector, sectorOffset, mountedFloppy - )); - } - } - - public DriveParameters getDriveParameters() { - return new DriveParameters(port1status, port2status, track, sector, sectorOffset, mountedFloppy); - } - - boolean isSelected() { - return selected; - } - - public void select() { - if (mountedFloppy == null) { - LOGGER.warn("[drive={}] Could not select drive; image is not mounted", index); - } else { - selected = true; - port1status = 0xE5; // 11100101b - port2status = 0xC1; // 11000001b - sector = 0; - sectorOffset = 0; - if (track == 0) { - port1status &= 0xBF; // 10111111b - } // head is on track 0 - notifyDiskSelected(); - notifyParamsChanged(); - } - } - - public void deselect() { - selected = false; - port1status = 0xE7; - port2status = 0xC1; - notifyDiskSelected(); - notifyParamsChanged(); - } - - public void mount(Path imagePath) throws IOException { - if (!Files.exists(imagePath) || Files.isDirectory(imagePath) || !Files.isReadable(imagePath)) { - throw new FileNotFoundException("Image file is not readable or does not exist"); - } - - umount(); - this.mountedFloppy = imagePath; - Set optionSet = new HashSet<>(); - optionSet.add(StandardOpenOption.READ); - optionSet.add(StandardOpenOption.WRITE); - - imageChannel = Files.newByteChannel(imagePath, optionSet); - } - - public void umount() { - if (selected) { - deselect(); - } - mountedFloppy = null; - try { - if (imageChannel != null) { - imageChannel.close(); - } - } catch (IOException e) { - LOGGER.error("[drive={}] Could not un-mount disk image", index, e); - } - } - - public Path getImagePath() { - return mountedFloppy; - } - - public short getPort1status() { - return port1status; - } - - public short getPort2status() { - return port2status; - } - - public void writeToPort2(short val) { - if ((val & 0x01) != 0) { /* Step head in */ - track++; - sector = 0; - sectorOffset = 0; - } - if ((val & 0x02) != 0) { /* Step head out */ - track--; - if (track < 0) { - track = 0; - port1status &= 0xBF; // head is on track 0 - } - sector = 0; - sectorOffset = 0; - } - if ((val & 0x04) != 0) { /* Head load */ - // 11111011 - port1status &= 0xFB; /* turn on head loaded bit */ - port1status &= 0x7F; /* turn on 'read data available */ - - port2status = (short) ((sector << 1) & 0x3E | 0xC0); - } - if ((val & 0x08) != 0) { /* Head Unload */ - port1status |= 0x04; /* turn off 'head loaded' */ - port1status |= 0x80; /* turn off 'read data avail */ - - sector = 0; - sectorOffset = 0; - } - /* Interrupts & head current are ignored */ - if ((val & 0x80) != 0) { /* write sequence start */ - sectorOffset = 0; // sectorLength-1; - port1status &= 0xFE; /* enter new write data on */ - } - notifyParamsChanged(); - } - - public void nextSectorIfHeadIsLoaded() { - if (((~port1status) & 0x04) != 0) { /* head loaded? */ - sector = (short) ((sector + 1) % 32); - sectorOffset = 0; - port2status = (short) ((sector << 1) & 0x3E | 0xC0); - } else { - // head not loaded - sector true is 1 (false) - port2status = 0xC1; - } - notifyParamsChanged(); - } - - public void writeData(int data) throws IOException { - byteBuffer.clear(); - byteBuffer.put((byte) (data & 0xFF)); - byteBuffer.flip(); - - try { - imageChannel.position(sectorsCount * sectorLength * track + sectorLength * sector + sectorOffset); - imageChannel.write(byteBuffer); - } finally { - sectorOffset = (short) ((sectorOffset + 1) % sectorLength); - if (sectorOffset == 0) { - port1status |= 1; /* ENWD off */ - } - notifyParamsChanged(); - } - } - - public short readData() throws IOException { - if (mountedFloppy == null) { - return 0; - } -// LOGGER.info("[T={}, S={}, O={}, imagePos={}] Reading", track, sector, sectorOffset, -// sectorsPerTrack * sectorLength * track + sectorLength * sector + sectorOffset -// ); - imageChannel.position(sectorsCount * sectorLength * track + sectorLength * sector + sectorOffset); - try { - byteBuffer.clear(); - int bytesRead = imageChannel.read(byteBuffer); - if (bytesRead != byteBuffer.capacity()) { - throw new IOException("[drive=" + index + "] Could not read data from disk image"); - } - byteBuffer.flip(); - return (short) (byteBuffer.get() & 0xFF); - } finally { - sectorOffset = (short) ((sectorOffset + 1) % sectorLength); - notifyParamsChanged(); - } - } - - public int getSector() { - return sector; - } - - public int getTrack() { - return track; - } - - public int getOffset() { - return sectorOffset; - } - -// public String portStatusToString(short status) { -// StringBuilder sb = new StringBuilder(); -// sb.append("DRIVE[" + index + "] "); -// -// if ((status & 1) == 0) { -// sb.append("W "); -// } -// if ((status & 2) == 0) { -// sb.append("M "); -// } -// if ((status & 4) == 0) { -// sb.append("H "); -// } -// if ((status & 32) == 0) { -// sb.append("I "); -// } -// if ((status & 64) == 0) { -// sb.append("Z "); -// } -// if ((status & 128) == 0) { -// sb.append("R"); -// } -// -// return sb.toString(); -// } - -} diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/Drive.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/Drive.java new file mode 100644 index 000000000..c2c2902f1 --- /dev/null +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/Drive.java @@ -0,0 +1,402 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2020 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.mits88disk.drive; + +import net.jcip.annotations.ThreadSafe; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.SeekableByteChannel; +import java.nio.file.Files; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * Performs disk operations on single drive. + */ +@ThreadSafe +public class Drive { + private static final Logger LOGGER = LoggerFactory.getLogger(Drive.class); + + public final static short DEFAULT_SECTORS_COUNT = 32; + public final static short DEFAULT_SECTOR_LENGTH = 137; + + private final int driveIndex; + + private final ReadWriteLock positionLock = new ReentrantReadWriteLock(); + private int track; + private int sector; + private int sectorOffset; + private int sectorsCount = DEFAULT_SECTORS_COUNT; + private int sectorLength = DEFAULT_SECTOR_LENGTH; + + private final ReadWriteLock mountLock = new ReentrantReadWriteLock(); + private Path mountedFloppy = null; + private SeekableByteChannel imageChannel; + private boolean selected = false; + + private final List listeners = new CopyOnWriteArrayList<>(); + private final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1); + + + /* + 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+ + | R | Z | I | X | X | H | M | W | + +---+---+---+---+---+---+---+---+ + + W - When 0, write circuit ready to write another byte. + M - When 0, head movement is allowed + H - When 0, indicates head is loaded for read/write + X - not used (will be 0) + I - When 0, indicates interrupts enabled (not used this emulator) + Z - When 0, indicates head is on track 0 + R - When 0, indicates that read circuit has new byte to read + */ + private short port1status; + private short port2status; + + public Drive(int driveIndex) { + this.driveIndex = driveIndex; + reset(); + } + + public void setSectorsCount(int sectorsCount) { + if (sectorsCount <= 0) { + throw new IllegalArgumentException("[drive=" + driveIndex + "] Sectors count must be > 0"); + } + inWriteLock(() -> this.sectorsCount = sectorsCount); + reset(); + } + + public void setSectorLength(int sectorLength) { + if (sectorLength <= 0) { + throw new IllegalArgumentException("[drive=" + driveIndex + "] Sector length must be > 0"); + } + inWriteLock(() -> this.sectorLength = sectorLength); + reset(); + } + + public int getSectorsCount() { + return inReadLock(() -> sectorsCount); + } + + public int getSectorLength() { + return inReadLock(() -> sectorLength); + } + + public void addDriveListener(DriveListener listener) { + this.listeners.add(listener); + } + + public DriveParameters getDriveParameters() { + return inReadLock( + () -> new DriveParameters(port1status, port2status, track, sector, sectorOffset, mountedFloppy) + ); + } + + public boolean isSelected() { + return selected; + } + + public void select() { + if (mountedFloppy == null) { + LOGGER.warn("[drive={}] Could not select drive; image is not mounted", driveIndex); + } else { + inWriteLock(() -> { + selected = true; + port1status = 0xE5; // 11100101b + port2status = 0xC1; // 11000001b + sector = 0; + sectorOffset = 0; + if (track == 0) { + port1status &= 0xBF; // 10111111b + } // head is on track 0 + }); + notifyDiskSelected(); + notifyParamsChanged(); + } + } + + public void deselect() { + inWriteLock(() -> { + selected = false; + port1status = 0xE7; + port2status = 0xC1; + }); + notifyDiskSelected(); + notifyParamsChanged(); + } + + public void mount(Path imagePath) throws IOException { + if (!Files.exists(imagePath) || Files.isDirectory(imagePath) || !Files.isReadable(imagePath)) { + throw new FileNotFoundException("Image file is not readable or does not exist"); + } + + umount(); + this.mountedFloppy = imagePath; + Set optionSet = new HashSet<>(); + optionSet.add(StandardOpenOption.READ); + optionSet.add(StandardOpenOption.WRITE); + + imageChannel = Files.newByteChannel(imagePath, optionSet); + } + + public void umount() { + if (inReadLock(() -> selected)) { + deselect(); + } + mountedFloppy = null; + try { + if (imageChannel != null) { + imageChannel.close(); + } + } catch (IOException e) { + LOGGER.error("[drive={}] Could not un-mount disk image", driveIndex, e); + } + } + + public Path getImagePath() { + return mountedFloppy; + } + + public short getPort1status() { + return inReadLock(() -> port1status); + } + + public short getPort2status() { + return inReadLock(() -> port2status); + } + + public void writeToPort2(short val) { + inWriteLock(() -> { + if ((val & 0x01) != 0) { /* Step head in */ + track++; + sector = 0; + sectorOffset = 0; + } + if ((val & 0x02) != 0) { /* Step head out */ + track--; + if (track < 0) { + track = 0; + port1status &= 0xBF; // head is on track 0 + } + sector = 0; + sectorOffset = 0; + } + if ((val & 0x04) != 0) { /* Head load */ + // 11111011 + port1status &= 0xFB; /* turn on head loaded bit */ + port1status &= 0x7F; /* turn on 'read data available */ + + port2status = (short) ((sector << 1) & 0x3E | 0xC0); + } + if ((val & 0x08) != 0) { /* Head Unload */ + port1status |= 0x04; /* turn off 'head loaded' */ + port1status |= 0x80; /* turn off 'read data avail */ + + sector = 0; + sectorOffset = 0; + } + /* Interrupts & head current are ignored */ + if ((val & 0x80) != 0) { /* write sequence start */ + sectorOffset = 0; // sectorLength-1; + port1status &= 0xFE; /* enter new write data on */ + } + }); + notifyParamsChanged(); + } + + public void nextSectorIfHeadIsLoaded() { + inWriteLock(() -> { + if (((~port1status) & 0x04) != 0) { /* head loaded? */ + sector = (short) ((sector + 1) % 32); + sectorOffset = 0; + port2status = (short) ((sector << 1) & 0x3E | 0xC0); + } else { + // head not loaded - sector true is 1 (false) + port2status = 0xC1; + } + }); + notifyParamsChanged(); + } + + public void writeData(int data) { + inWriteLock(() -> { + byteBuffer.clear(); + byteBuffer.put((byte) (data & 0xFF)); + byteBuffer.flip(); + + try { + imageChannel.position(sectorsCount * sectorLength * track + sectorLength * sector + sectorOffset); + imageChannel.write(byteBuffer); + } catch (IOException ex) { + throw new RuntimeException(ex); + } finally { + sectorOffset = (short) ((sectorOffset + 1) % sectorLength); + if (sectorOffset == 0) { + port1status |= 1; /* ENWD off */ + } + } + }); + notifyParamsChanged(); + } + + public short readData() { + if (mountedFloppy == null) { + return 0; + } +// LOGGER.trace("[T={}, S={}, O={}, imagePos={}] Reading", track, sector, sectorOffset, +// sectorsPerTrack * sectorLength * track + sectorLength * sector + sectorOffset +// ); + short result = inWriteLock(() -> { + try { + imageChannel.position(sectorsCount * sectorLength * track + sectorLength * sector + sectorOffset); + byteBuffer.clear(); + int bytesRead = imageChannel.read(byteBuffer); + if (bytesRead != byteBuffer.capacity()) { + throw new IOException("[drive=" + driveIndex + "] Could not read data from disk image"); + } + byteBuffer.flip(); + return (short) (byteBuffer.get() & 0xFF); + } catch (IOException ex) { + throw new RuntimeException(ex); + } finally { + sectorOffset = (short) ((sectorOffset + 1) % sectorLength); + } + }); + notifyParamsChanged(); + return result; + } + + public int getSector() { + return inReadLock(() -> sector); + } + + public int getTrack() { + return inReadLock(() -> track); + } + + public int getOffset() { + return inReadLock(() -> sectorOffset); + } + + public String portStatusToString(short status) { + StringBuilder sb = new StringBuilder(); + sb.append("DRIVE[" + driveIndex + "] "); + + if ((status & 1) == 0) { + sb.append("W "); + } + if ((status & 2) == 0) { + sb.append("M "); + } + if ((status & 4) == 0) { + sb.append("H "); + } + if ((status & 32) == 0) { + sb.append("I "); + } + if ((status & 64) == 0) { + sb.append("Z "); + } + if ((status & 128) == 0) { + sb.append("R"); + } + + return sb.toString(); + } + + private void reset() { + inWriteLock(() -> { + track = 0; + sector = 0; + sectorOffset = 0; + port1status = 0xE7; // 11100111b + port2status = 0xC1; + }); + } + + private void notifyDiskSelected() { + boolean tmpSelected = inReadLock(() -> selected); + for (DriveListener listener : listeners) { + listener.driveSelect(tmpSelected); + } + } + + private void notifyParamsChanged() { + DriveParameters parameters = inReadLock(() -> new DriveParameters( + port1status, port2status, track, sector, sectorOffset, mountedFloppy + )); + for (DriveListener listener : listeners) { + listener.driveParamsChanged(parameters); + } + } + + private T inWriteLock(Callable action) { + positionLock.writeLock().lock(); + try { + return action.call(); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + positionLock.writeLock().unlock(); + } + } + + private void inWriteLock(Runnable action) { + positionLock.writeLock().lock(); + try { + action.run(); + } finally { + positionLock.writeLock().unlock(); + } + } + + private T inReadLock(Callable action) { + positionLock.readLock().lock(); + try { + return action.call(); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + positionLock.readLock().unlock(); + } + } + + private void inReadLock(Runnable action) { + positionLock.readLock().lock(); + try { + action.run(); + } finally { + positionLock.readLock().unlock(); + } + } +} diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveCollection.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveCollection.java new file mode 100644 index 000000000..a02d8346e --- /dev/null +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveCollection.java @@ -0,0 +1,50 @@ +package net.emustudio.plugins.device.mits88disk.drive; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Supplier; + +public class DriveCollection implements Iterable { + private final static int DRIVES_COUNT = 16; + private final List drives = new ArrayList<>(); + + private volatile int currentDrive; + + public DriveCollection() { + for (int i = 0; i < DRIVES_COUNT; i++) { + drives.add(new Drive(i)); + } + + this.currentDrive = 0; // TODO: what should be here? + } + + public void destroy() { + drives.clear(); + } + + public Drive getCurrentDrive() { + return drives.get(currentDrive); + } + + public void setCurrentDrive(int index) { + currentDrive = index; + } + + public Iterator iterator() { + return drives.iterator(); + } + + public Drive get(int index) { + return drives.get(index); + } + + public void foreach(BiFunction function) { + int i = 0; + for (Drive drive : drives) { + function.apply(i, drive); + i++; + } + } +} diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveListener.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveListener.java new file mode 100644 index 000000000..2b0ab830c --- /dev/null +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveListener.java @@ -0,0 +1,8 @@ +package net.emustudio.plugins.device.mits88disk.drive; + +public interface DriveListener { + + void driveSelect(boolean sel); + + void driveParamsChanged(DriveParameters parameters); +} diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveParameters.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveParameters.java new file mode 100644 index 000000000..89d046f3d --- /dev/null +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveParameters.java @@ -0,0 +1,27 @@ +package net.emustudio.plugins.device.mits88disk.drive; + +import net.jcip.annotations.Immutable; + +import java.nio.file.Path; + +@Immutable +public final class DriveParameters { + public final short port1status; + public final short port2status; + + public final int track; + public final int sector; + public final int sectorOffset; + + public final Path mountedFloppy; + + public DriveParameters(short port1status, short port2status, int track, int sector, int sectorOffset, + Path mountedFloppy) { + this.port1status = port1status; + this.port2status = port2status; + this.track = track; + this.sector = sector; + this.sectorOffset = sectorOffset; + this.mountedFloppy = mountedFloppy; + } +} diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DiskGui.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DiskGui.java index 54c44a43e..c9f916898 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DiskGui.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DiskGui.java @@ -18,13 +18,14 @@ */ package net.emustudio.plugins.device.mits88disk.gui; -import net.emustudio.plugins.device.mits88disk.Drive; +import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; +import net.emustudio.plugins.device.mits88disk.drive.DriveListener; +import net.emustudio.plugins.device.mits88disk.drive.DriveParameters; import javax.swing.*; import javax.swing.border.TitledBorder; import java.awt.*; import java.awt.event.KeyEvent; -import java.util.List; import java.util.Objects; import static net.emustudio.emulib.runtime.helpers.RadixUtils.formatBinaryString; @@ -49,7 +50,7 @@ public class DiskGui extends JDialog { new DriveButton("O", () -> updateDriveInfo(14)), new DriveButton("P", () -> updateDriveInfo(15)), }; - private final List drives; + private final DriveCollection drives; private final JLabel lblOffset = createMonospacedLabel("0"); private final JLabel lblSector = createMonospacedLabel("0"); @@ -58,23 +59,24 @@ public class DiskGui extends JDialog { private final JLabel lblPort2Status = createMonospacedLabel("00000000"); private final JTextArea txtMountedImage = new JTextArea(); - public DiskGui(JFrame parent, List drives) { + public DiskGui(JFrame parent, DriveCollection drives) { super(parent); this.drives = Objects.requireNonNull(drives); initComponents(); setLocationRelativeTo(parent); - for (int index = 0; index < drives.size(); index++) { - drives.get(index).setDriveListener(new GUIDriveListener(index)); - } + drives.foreach((i, drive) -> { + drive.addDriveListener(new GUIDriveListener(i)); + return null; + }); } private void updateDriveInfo(int index) { updateDriveInfo(drives.get(index).getDriveParameters()); } - private void updateDriveInfo(Drive.DriveParameters parameters) { + private void updateDriveInfo(DriveParameters parameters) { lblPort1Status.setText(formatBinaryString(parameters.port1status, 8)); lblPort2Status.setText(formatBinaryString(parameters.port2status, 8)); @@ -308,7 +310,7 @@ private static JLabel createMonospacedLabel(String text) { return label; } - private class GUIDriveListener implements Drive.DriveListener { + private class GUIDriveListener implements DriveListener { private final int index; private GUIDriveListener(int index) { @@ -321,7 +323,7 @@ public void driveSelect(final boolean selected) { } @Override - public void driveParamsChanged(final Drive.DriveParameters parameters) { + public void driveParamsChanged(final DriveParameters parameters) { SwingUtilities.invokeLater(() -> updateDriveInfo(parameters)); } } diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/SettingsDialog.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/SettingsDialog.java index 82afff380..0da7f7e2d 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/SettingsDialog.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/SettingsDialog.java @@ -23,8 +23,9 @@ import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; -import net.emustudio.plugins.device.mits88disk.Drive; import net.emustudio.plugins.device.mits88disk.SettingsConstants; +import net.emustudio.plugins.device.mits88disk.drive.Drive; +import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +34,6 @@ import java.awt.event.KeyEvent; import java.io.FileNotFoundException; import java.nio.file.Path; -import java.util.List; import java.util.Objects; import java.util.Optional; @@ -45,9 +45,9 @@ public class SettingsDialog extends JDialog { private final Dialogs dialogs; private final PluginSettings settings; - private final List drives; + private final DriveCollection drives; - public SettingsDialog(JFrame parent, PluginSettings settings, List drives, Dialogs dialogs) { + public SettingsDialog(JFrame parent, PluginSettings settings, DriveCollection drives, Dialogs dialogs) { super(parent, true); this.settings = Objects.requireNonNull(settings); @@ -82,20 +82,23 @@ private void writeSettings() { settings.setInt(SettingsConstants.PORT2_CPU, radixUtils.parseRadix(txtPort2.getText())); settings.setInt(SettingsConstants.PORT3_CPU, radixUtils.parseRadix(txtPort3.getText())); - for (int i = 0; i < drives.size(); i++) { - Drive drive = drives.get(i); - - settings.setInt(SettingsConstants.SECTORS_COUNT + i, drive.getSectorsCount()); - settings.setInt(SettingsConstants.SECTOR_LENGTH + i, drive.getSectorLength()); - - Path imagePath = drive.getImagePath(); - if (imagePath != null) { - settings.setString(SettingsConstants.IMAGE + i, imagePath.toAbsolutePath().toString()); - } else { - settings.remove(SettingsConstants.IMAGE + i); + drives.foreach((i, drive) -> { + try { + settings.setInt(SettingsConstants.SECTORS_COUNT + i, drive.getSectorsCount()); + settings.setInt(SettingsConstants.SECTOR_LENGTH + i, drive.getSectorLength()); + + Path imagePath = drive.getImagePath(); + if (imagePath != null) { + settings.setString(SettingsConstants.IMAGE + i, imagePath.toAbsolutePath().toString()); + } else { + settings.remove(SettingsConstants.IMAGE + i); + } + } catch (CannotUpdateSettingException e) { + throw new RuntimeException(e); } - } - } catch (CannotUpdateSettingException e) { + return null; + }); + } catch (CannotUpdateSettingException | RuntimeException e) { LOGGER.error("Could not write MITS 88-DISK settings", e); dialogs.showError("Could not write settings. Please see log for more details.", "MITS 88-DISK"); } @@ -439,11 +442,7 @@ private void cmbDriveItemStateChanged(java.awt.event.ItemEvent evt) { } private void txtImageFileInputMethodTextChanged() { - if (txtImageFile.getText().equals("")) { - btnMount.setEnabled(false); - } else { - btnMount.setEnabled(true); - } + btnMount.setEnabled(!txtImageFile.getText().equals("")); } private void btnUnmountActionPerformed(java.awt.event.ActionEvent evt) { diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/ControlPort.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/ControlPort.java index bcb292569..6668f4cee 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/ControlPort.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/ControlPort.java @@ -19,8 +19,8 @@ package net.emustudio.plugins.device.mits88disk.ports; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.device.mits88disk.DeviceImpl; -import net.emustudio.plugins.device.mits88disk.Drive; +import net.emustudio.plugins.device.mits88disk.drive.Drive; +import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; import java.util.Objects; @@ -31,9 +31,9 @@ * OUT: set flags */ public class ControlPort implements DeviceContext { - private final DeviceImpl disk; + private final DriveCollection disk; - public ControlPort(DeviceImpl disk) { + public ControlPort(DriveCollection disk) { this.disk = Objects.requireNonNull(disk); } diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/DataPort.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/DataPort.java index a4831bd10..2e863abc9 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/DataPort.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/DataPort.java @@ -19,9 +19,7 @@ package net.emustudio.plugins.device.mits88disk.ports; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.device.mits88disk.DeviceImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; import java.util.Objects; @@ -32,32 +30,20 @@ * OUT: write data */ public class DataPort implements DeviceContext { - private final static Logger LOGGER = LoggerFactory.getLogger(DataPort.class); + private final DriveCollection disk; - private final DeviceImpl disk; - - public DataPort(DeviceImpl disk) { + public DataPort(DriveCollection disk) { this.disk = Objects.requireNonNull(disk); } @Override public Short readData() { - short data = 0; - try { - data = disk.getCurrentDrive().readData(); - } catch (Exception e) { - LOGGER.error("Could not read from disk", e); - } - return data; + return disk.getCurrentDrive().readData(); } @Override public void writeData(Short data) { - try { - disk.getCurrentDrive().writeData(data); - } catch (Exception e) { - LOGGER.error("Could not write to disk", e); - } + disk.getCurrentDrive().writeData(data); } @Override diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/StatusPort.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/StatusPort.java index e21600659..bdace0518 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/StatusPort.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/StatusPort.java @@ -19,8 +19,8 @@ package net.emustudio.plugins.device.mits88disk.ports; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.device.mits88disk.DeviceImpl; -import net.emustudio.plugins.device.mits88disk.Drive; +import net.emustudio.plugins.device.mits88disk.drive.Drive; +import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; import java.util.Objects; @@ -31,9 +31,9 @@ * OUT: select/unselect drive */ public class StatusPort implements DeviceContext { - private final DeviceImpl disk; + private final DriveCollection disk; - public StatusPort(DeviceImpl disk) { + public StatusPort(DriveCollection disk) { this.disk = Objects.requireNonNull(disk); } diff --git a/plugins/device/88-disk/src/test/java/net/emustudio/plugins/device/mits88disk/DriveTest.java b/plugins/device/88-disk/src/test/java/net/emustudio/plugins/device/mits88disk/DriveTest.java index cb148b873..d6ee82946 100644 --- a/plugins/device/88-disk/src/test/java/net/emustudio/plugins/device/mits88disk/DriveTest.java +++ b/plugins/device/88-disk/src/test/java/net/emustudio/plugins/device/mits88disk/DriveTest.java @@ -18,6 +18,9 @@ */ package net.emustudio.plugins.device.mits88disk; +import net.emustudio.plugins.device.mits88disk.drive.Drive; +import net.emustudio.plugins.device.mits88disk.drive.DriveListener; +import net.emustudio.plugins.device.mits88disk.drive.DriveParameters; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Rule; @@ -62,7 +65,7 @@ private void assertImageContent(int dataStart) throws Exception { public void testInitialDriveParameters() { Drive drive = new Drive(0); - Drive.DriveParameters params = drive.getDriveParameters(); + DriveParameters params = drive.getDriveParameters(); assertEquals(0, params.sector); assertEquals(0, params.sectorOffset); assertEquals(0, params.track); @@ -102,7 +105,7 @@ public void testUmountClearsMountImageInDriveParams() throws IOException { drive.mount(testImageFile); drive.umount(); - Drive.DriveParameters params = drive.getDriveParameters(); + DriveParameters params = drive.getDriveParameters(); assertNull(params.mountedFloppy); } @@ -115,7 +118,7 @@ public void testDriveParametersAfterSelect() throws Exception { drive.mount(testImageFile); drive.select(); - Drive.DriveParameters params = drive.getDriveParameters(); + DriveParameters params = drive.getDriveParameters(); assertEquals(0xA5, params.port1status); assertEquals(0xC1, params.port2status); @@ -134,7 +137,7 @@ public void testDriveParametersAfterSelectThenDeselect() throws Exception { drive.select(); drive.deselect(); - Drive.DriveParameters params = drive.getDriveParameters(); + DriveParameters params = drive.getDriveParameters(); assertEquals(0, params.sector); assertEquals(0, params.sectorOffset); assertEquals(0, params.track); @@ -236,15 +239,15 @@ public void testWriteAllData() throws Exception { @Test public void testDriveListenerIsCalledWhenDiskIsSelected() throws Exception { - Drive.DriveListener listener = EasyMock.createMock(Drive.DriveListener.class); + DriveListener listener = EasyMock.createMock(DriveListener.class); listener.driveSelect(true); expectLastCall().once(); - listener.driveParamsChanged(anyObject(Drive.DriveParameters.class)); + listener.driveParamsChanged(anyObject(DriveParameters.class)); expectLastCall().once(); replay(listener); Drive drive = new Drive(0); - drive.setDriveListener(listener); + drive.addDriveListener(listener); drive.mount(testImageFile); drive.select(); @@ -253,17 +256,17 @@ public void testDriveListenerIsCalledWhenDiskIsSelected() throws Exception { @Test public void testDriveListenerIsCalledWhenDiskIsDeselected() throws Exception { - Drive.DriveListener listener = EasyMock.createMock(Drive.DriveListener.class); + DriveListener listener = EasyMock.createMock(DriveListener.class); listener.driveSelect(false); expectLastCall().once(); - listener.driveParamsChanged(anyObject(Drive.DriveParameters.class)); + listener.driveParamsChanged(anyObject(DriveParameters.class)); expectLastCall().once(); replay(listener); Drive drive = new Drive(0); drive.mount(testImageFile); drive.select(); - drive.setDriveListener(listener); + drive.addDriveListener(listener); drive.deselect(); verify(listener); @@ -271,15 +274,15 @@ public void testDriveListenerIsCalledWhenDiskIsDeselected() throws Exception { @Test public void testDriveListenerIsCalledWhenSectorNumberIsChanged() throws Exception { - Drive.DriveListener listener = EasyMock.createMock(Drive.DriveListener.class); - listener.driveParamsChanged(anyObject(Drive.DriveParameters.class)); + DriveListener listener = EasyMock.createMock(DriveListener.class); + listener.driveParamsChanged(anyObject(DriveParameters.class)); expectLastCall().once(); replay(listener); Drive drive = new Drive(0); drive.mount(testImageFile); drive.select(); - drive.setDriveListener(listener); + drive.addDriveListener(listener); drive.nextSectorIfHeadIsLoaded(); verify(listener); @@ -287,8 +290,8 @@ public void testDriveListenerIsCalledWhenSectorNumberIsChanged() throws Exceptio @Test public void testDriveListenerIsCalledWhenDataAreRead() throws Exception { - Drive.DriveListener listener = EasyMock.createMock(Drive.DriveListener.class); - listener.driveParamsChanged(anyObject(Drive.DriveParameters.class)); + DriveListener listener = EasyMock.createMock(DriveListener.class); + listener.driveParamsChanged(anyObject(DriveParameters.class)); expectLastCall().once(); replay(listener); @@ -296,7 +299,7 @@ public void testDriveListenerIsCalledWhenDataAreRead() throws Exception { drive.mount(testImageFile); drive.select(); drive.writeToPort2((short) 0x04); - drive.setDriveListener(listener); + drive.addDriveListener(listener); drive.readData(); verify(listener); @@ -304,8 +307,8 @@ public void testDriveListenerIsCalledWhenDataAreRead() throws Exception { @Test public void testDriveListenerIsCalledWhenDataAreWritten() throws Exception { - Drive.DriveListener listener = EasyMock.createMock(Drive.DriveListener.class); - listener.driveParamsChanged(anyObject(Drive.DriveParameters.class)); + DriveListener listener = EasyMock.createMock(DriveListener.class); + listener.driveParamsChanged(anyObject(DriveParameters.class)); expectLastCall().once(); replay(listener); @@ -314,7 +317,7 @@ public void testDriveListenerIsCalledWhenDataAreWritten() throws Exception { drive.select(); drive.writeToPort2((short) 0x04); drive.writeToPort2((short) 0x80); - drive.setDriveListener(listener); + drive.addDriveListener(listener); drive.writeData(1); verify(listener); @@ -322,15 +325,15 @@ public void testDriveListenerIsCalledWhenDataAreWritten() throws Exception { @Test public void testDriveListenerIsCalledWhenFlagsAreSet() throws Exception { - Drive.DriveListener listener = EasyMock.createMock(Drive.DriveListener.class); - listener.driveParamsChanged(anyObject(Drive.DriveParameters.class)); + DriveListener listener = EasyMock.createMock(DriveListener.class); + listener.driveParamsChanged(anyObject(DriveParameters.class)); expectLastCall().once(); replay(listener); Drive drive = new Drive(0); drive.mount(testImageFile); drive.select(); - drive.setDriveListener(listener); + drive.addDriveListener(listener); drive.writeToPort2((short) 0x04); verify(listener); From 4a695601be9d5511b7a351ae289cc5980d9b2a04 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 19 Jul 2020 11:03:26 +0200 Subject: [PATCH 004/314] [#186] Fix 88-disk writing --- .../device/mits88disk/drive/Drive.java | 172 +++++++++--------- .../mits88disk/drive/DriveCollection.java | 16 +- .../mits88disk/drive/DriveParameters.java | 49 +++++ .../device/mits88disk/gui/DiskGui.java | 10 +- .../device/mits88disk/ports/ControlPort.java | 10 +- .../device/mits88disk/ports/DataPort.java | 5 +- .../device/mits88disk/ports/StatusPort.java | 14 +- 7 files changed, 162 insertions(+), 114 deletions(-) diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/Drive.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/Drive.java index c2c2902f1..8386bfe16 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/Drive.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/Drive.java @@ -48,6 +48,15 @@ public class Drive { public final static short DEFAULT_SECTORS_COUNT = 32; public final static short DEFAULT_SECTOR_LENGTH = 137; + public static final short DEAD_DRIVE = 0b11100111; + private static final short ALIVE_DRIVE = 0b11100101; + private static final short MASK_TRACK0 = 0b10111111; + + public static final short SECTOR0 = 0b11000001; + + private static final short MASK_HEAD_LOAD = 0b11111011; + private static final short MASK_DATA_AVAILABLE = 0b01111111; + private final int driveIndex; private final ReadWriteLock positionLock = new ReentrantReadWriteLock(); @@ -57,7 +66,6 @@ public class Drive { private int sectorsCount = DEFAULT_SECTORS_COUNT; private int sectorLength = DEFAULT_SECTOR_LENGTH; - private final ReadWriteLock mountLock = new ReentrantReadWriteLock(); private Path mountedFloppy = null; private SeekableByteChannel imageChannel; private boolean selected = false; @@ -67,7 +75,7 @@ public class Drive { /* - 7 6 5 4 3 2 1 0 + 7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ | R | Z | I | X | X | H | M | W | +---+---+---+---+---+---+---+---+ @@ -80,8 +88,8 @@ public class Drive { Z - When 0, indicates head is on track 0 R - When 0, indicates that read circuit has new byte to read */ - private short port1status; - private short port2status; + private short port1status = DEAD_DRIVE; + private short port2status = SECTOR0; public Drive(int driveIndex) { this.driveIndex = driveIndex; @@ -118,7 +126,7 @@ public void addDriveListener(DriveListener listener) { public DriveParameters getDriveParameters() { return inReadLock( - () -> new DriveParameters(port1status, port2status, track, sector, sectorOffset, mountedFloppy) + () -> new DriveParameters(port1status, port2status, track, sector, getOffset(), mountedFloppy) ); } @@ -130,31 +138,38 @@ public void select() { if (mountedFloppy == null) { LOGGER.warn("[drive={}] Could not select drive; image is not mounted", driveIndex); } else { - inWriteLock(() -> { - selected = true; - port1status = 0xE5; // 11100101b - port2status = 0xC1; // 11000001b - sector = 0; - sectorOffset = 0; - if (track == 0) { - port1status &= 0xBF; // 10111111b - } // head is on track 0 - }); + selectInternal(); notifyDiskSelected(); notifyParamsChanged(); } } - public void deselect() { + private void selectInternal() { inWriteLock(() -> { - selected = false; - port1status = 0xE7; - port2status = 0xC1; + selected = true; + port1status = ALIVE_DRIVE; + port2status = SECTOR0; + sector = 0; + sectorOffset = sectorLength; + if (track == 0) { + port1status &= MASK_TRACK0; + } }); + } + + public void deselect() { + deselectInternal(); notifyDiskSelected(); notifyParamsChanged(); } + private void deselectInternal() { + inWriteLock(() -> { + selected = false; + port1status = DEAD_DRIVE; + }); + } + public void mount(Path imagePath) throws IOException { if (!Files.exists(imagePath) || Files.isDirectory(imagePath) || !Files.isReadable(imagePath)) { throw new FileNotFoundException("Image file is not readable or does not exist"); @@ -192,15 +207,23 @@ public short getPort1status() { } public short getPort2status() { - return inReadLock(() -> port2status); + return inReadLock(() -> { + if (((~port1status) & (~MASK_HEAD_LOAD)) != 0) { + return port2status; + } else { + return (short) 0; + } + }); } public void writeToPort2(short val) { inWriteLock(() -> { if ((val & 0x01) != 0) { /* Step head in */ track++; + // TODO: do not allow more tracks than available sector = 0; - sectorOffset = 0; + sectorOffset = sectorLength; + port2status = SECTOR0; } if ((val & 0x02) != 0) { /* Step head out */ track--; @@ -209,25 +232,28 @@ public void writeToPort2(short val) { port1status &= 0xBF; // head is on track 0 } sector = 0; - sectorOffset = 0; + sectorOffset = sectorLength; + port2status = SECTOR0; } if ((val & 0x04) != 0) { /* Head load */ - // 11111011 - port1status &= 0xFB; /* turn on head loaded bit */ - port1status &= 0x7F; /* turn on 'read data available */ - + port1status &= MASK_HEAD_LOAD; + port1status &= MASK_DATA_AVAILABLE; port2status = (short) ((sector << 1) & 0x3E | 0xC0); + if (sectorOffset != 0) { + port2status |= 1; // SR0 = false + } } if ((val & 0x08) != 0) { /* Head Unload */ - port1status |= 0x04; /* turn off 'head loaded' */ - port1status |= 0x80; /* turn off 'read data avail */ - + port1status |= (~MASK_HEAD_LOAD); /* turn off 'head loaded' */ + port1status |= (~MASK_DATA_AVAILABLE); /* turn off 'read data avail */ sector = 0; - sectorOffset = 0; + sectorOffset = sectorLength; + port2status = SECTOR0; } /* Interrupts & head current are ignored */ if ((val & 0x80) != 0) { /* write sequence start */ - sectorOffset = 0; // sectorLength-1; + sectorOffset = 0; + port2status &= 0xFE; // SR0 = true port1status &= 0xFE; /* enter new write data on */ } }); @@ -236,13 +262,10 @@ public void writeToPort2(short val) { public void nextSectorIfHeadIsLoaded() { inWriteLock(() -> { - if (((~port1status) & 0x04) != 0) { /* head loaded? */ - sector = (short) ((sector + 1) % 32); - sectorOffset = 0; + if (((~port1status) & (~MASK_HEAD_LOAD)) != 0) { /* head loaded? */ + sector = (short) ((sector + 1) % sectorsCount); + sectorOffset = sectorLength; port2status = (short) ((sector << 1) & 0x3E | 0xC0); - } else { - // head not loaded - sector true is 1 (false) - port2status = 0xC1; } }); notifyParamsChanged(); @@ -254,16 +277,21 @@ public void writeData(int data) { byteBuffer.put((byte) (data & 0xFF)); byteBuffer.flip(); + if (sectorOffset == sectorLength) { + port1status |= 1; /* ENWD off */ + port2status &= 0xFE; // SR0 = TRUE + return; + } + + int pos = sectorsCount * sectorLength * track + sectorLength * sector + sectorOffset; try { - imageChannel.position(sectorsCount * sectorLength * track + sectorLength * sector + sectorOffset); + imageChannel.position(pos); imageChannel.write(byteBuffer); } catch (IOException ex) { throw new RuntimeException(ex); } finally { - sectorOffset = (short) ((sectorOffset + 1) % sectorLength); - if (sectorOffset == 0) { - port1status |= 1; /* ENWD off */ - } + sectorOffset = (sectorOffset == sectorLength) ? sectorLength : (sectorOffset + 1); + port2status |= 1; } }); notifyParamsChanged(); @@ -273,12 +301,10 @@ public short readData() { if (mountedFloppy == null) { return 0; } -// LOGGER.trace("[T={}, S={}, O={}, imagePos={}] Reading", track, sector, sectorOffset, -// sectorsPerTrack * sectorLength * track + sectorLength * sector + sectorOffset -// ); short result = inWriteLock(() -> { try { - imageChannel.position(sectorsCount * sectorLength * track + sectorLength * sector + sectorOffset); + int offset = (sectorOffset == sectorLength) ? 0 : sectorOffset; + imageChannel.position(sectorsCount * sectorLength * track + sectorLength * sector + offset); byteBuffer.clear(); int bytesRead = imageChannel.read(byteBuffer); if (bytesRead != byteBuffer.capacity()) { @@ -289,7 +315,12 @@ public short readData() { } catch (IOException ex) { throw new RuntimeException(ex); } finally { - sectorOffset = (short) ((sectorOffset + 1) % sectorLength); + sectorOffset = (sectorOffset == sectorLength) ? 1 : (sectorOffset + 1); + if (sectorOffset == sectorLength) { + port2status &= 0xFE; + } else { + port2status |= 1; + } } }); notifyParamsChanged(); @@ -305,42 +336,16 @@ public int getTrack() { } public int getOffset() { - return inReadLock(() -> sectorOffset); - } - - public String portStatusToString(short status) { - StringBuilder sb = new StringBuilder(); - sb.append("DRIVE[" + driveIndex + "] "); - - if ((status & 1) == 0) { - sb.append("W "); - } - if ((status & 2) == 0) { - sb.append("M "); - } - if ((status & 4) == 0) { - sb.append("H "); - } - if ((status & 32) == 0) { - sb.append("I "); - } - if ((status & 64) == 0) { - sb.append("Z "); - } - if ((status & 128) == 0) { - sb.append("R"); - } - - return sb.toString(); + return inReadLock(() -> sectorOffset == sectorLength ? 0 : sectorOffset); } private void reset() { inWriteLock(() -> { track = 0; sector = 0; - sectorOffset = 0; - port1status = 0xE7; // 11100111b - port2status = 0xC1; + sectorOffset = sectorLength; + port1status = DEAD_DRIVE; + port2status = SECTOR0; }); } @@ -352,9 +357,7 @@ private void notifyDiskSelected() { } private void notifyParamsChanged() { - DriveParameters parameters = inReadLock(() -> new DriveParameters( - port1status, port2status, track, sector, sectorOffset, mountedFloppy - )); + DriveParameters parameters = getDriveParameters(); for (DriveListener listener : listeners) { listener.driveParamsChanged(parameters); } @@ -390,13 +393,4 @@ private T inReadLock(Callable action) { positionLock.readLock().unlock(); } } - - private void inReadLock(Runnable action) { - positionLock.readLock().lock(); - try { - action.run(); - } finally { - positionLock.readLock().unlock(); - } - } } diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveCollection.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveCollection.java index a02d8346e..fcc364073 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveCollection.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveCollection.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.function.BiFunction; -import java.util.function.Supplier; public class DriveCollection implements Iterable { private final static int DRIVES_COUNT = 16; @@ -17,21 +17,29 @@ public DriveCollection() { drives.add(new Drive(i)); } - this.currentDrive = 0; // TODO: what should be here? + this.currentDrive = DRIVES_COUNT; } public void destroy() { drives.clear(); } - public Drive getCurrentDrive() { - return drives.get(currentDrive); + public Optional getCurrentDrive() { + return (currentDrive >= DRIVES_COUNT || currentDrive < 0) ? + Optional.empty() : Optional.of(drives.get(currentDrive)); } public void setCurrentDrive(int index) { + if (index < 0 || index >= DRIVES_COUNT) { + throw new IllegalArgumentException("Index of drive must be between 0 and " + DRIVES_COUNT); + } currentDrive = index; } + public void unsetCurrentDrive() { + currentDrive = DRIVES_COUNT; + } + public Iterator iterator() { return drives.iterator(); } diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveParameters.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveParameters.java index 89d046f3d..35046edf5 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveParameters.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveParameters.java @@ -1,5 +1,6 @@ package net.emustudio.plugins.device.mits88disk.drive; +import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.jcip.annotations.Immutable; import java.nio.file.Path; @@ -7,7 +8,10 @@ @Immutable public final class DriveParameters { public final short port1status; + public final String port1statusString; + public final short port2status; + public final String port2statusString; public final int track; public final int sector; @@ -18,10 +22,55 @@ public final class DriveParameters { public DriveParameters(short port1status, short port2status, int track, int sector, int sectorOffset, Path mountedFloppy) { this.port1status = port1status; + this.port1statusString = port1StatusString(port1status); + this.port2status = port2status; + this.port2statusString = port2StatusString(port2status); + this.track = track; this.sector = sector; this.sectorOffset = sectorOffset; this.mountedFloppy = mountedFloppy; } + + public static String port1StatusString(int status) { + String sb = ""; + + if ((status & 128) == 0) sb += "R "; + else sb += ". "; + + if ((status & 64) == 0) sb += "Z "; + else sb += ". "; + + if ((status & 32) == 0) sb += "I "; + else sb += ". "; + + if ((status & 4) == 0) sb += "H "; + else sb += ". "; + + if ((status & 2) == 0) sb += "M "; + else sb += ". "; + + if ((status & 1) == 0) sb += "W "; + else sb += ". "; + + return sb; + } + + public static String port2StatusString(int status) { + boolean sr0 = (status & 1) == 0; + int offset = (status >>> 1) & 0b11111; + + return (sr0 ? "(SR0) " : " ") + "0x" + RadixUtils.formatByteHexString(offset); + } + + @Override + public String toString() { + return + "T=" + RadixUtils.formatByteHexString(track) + + "; S=" + RadixUtils.formatByteHexString(sector) + + "; O=" + RadixUtils.formatByteHexString(sectorOffset) + + "; port1=[" + port1statusString + "]" + + "; port2=[" + port2statusString + "]"; + } } diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DiskGui.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DiskGui.java index c9f916898..f42721375 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DiskGui.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DiskGui.java @@ -18,6 +18,7 @@ */ package net.emustudio.plugins.device.mits88disk.gui; +import net.emustudio.plugins.device.mits88disk.drive.Drive; import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; import net.emustudio.plugins.device.mits88disk.drive.DriveListener; import net.emustudio.plugins.device.mits88disk.drive.DriveParameters; @@ -28,7 +29,6 @@ import java.awt.event.KeyEvent; import java.util.Objects; -import static net.emustudio.emulib.runtime.helpers.RadixUtils.formatBinaryString; import static net.emustudio.plugins.device.mits88disk.gui.Constants.MONOSPACED_PLAIN; public class DiskGui extends JDialog { @@ -55,8 +55,8 @@ public class DiskGui extends JDialog { private final JLabel lblOffset = createMonospacedLabel("0"); private final JLabel lblSector = createMonospacedLabel("0"); private final JLabel lblTrack = createMonospacedLabel("0"); - private final JLabel lblPort1Status = createMonospacedLabel("11100111"); - private final JLabel lblPort2Status = createMonospacedLabel("00000000"); + private final JLabel lblPort1Status = createMonospacedLabel(DriveParameters.port1StatusString(Drive.DEAD_DRIVE)); + private final JLabel lblPort2Status = createMonospacedLabel(DriveParameters.port2StatusString(Drive.SECTOR0)); private final JTextArea txtMountedImage = new JTextArea(); public DiskGui(JFrame parent, DriveCollection drives) { @@ -77,8 +77,8 @@ private void updateDriveInfo(int index) { } private void updateDriveInfo(DriveParameters parameters) { - lblPort1Status.setText(formatBinaryString(parameters.port1status, 8)); - lblPort2Status.setText(formatBinaryString(parameters.port2status, 8)); + lblPort1Status.setText(parameters.port1statusString); + lblPort2Status.setText(parameters.port2statusString); lblSector.setText(String.valueOf(parameters.sector)); lblTrack.setText(String.valueOf(parameters.track)); diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/ControlPort.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/ControlPort.java index 6668f4cee..b6f47a980 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/ControlPort.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/ControlPort.java @@ -39,15 +39,15 @@ public ControlPort(DriveCollection disk) { @Override public Short readData() { - Drive currentDrive = disk.getCurrentDrive(); - currentDrive.nextSectorIfHeadIsLoaded(); - - return currentDrive.getPort2status(); + return disk.getCurrentDrive().map(drive -> { + drive.nextSectorIfHeadIsLoaded(); + return drive.getPort2status(); + }).orElse(Drive.SECTOR0); } @Override public void writeData(Short val) { - disk.getCurrentDrive().writeToPort2(val); + disk.getCurrentDrive().ifPresent(drive -> drive.writeToPort2(val)); } @Override diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/DataPort.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/DataPort.java index 2e863abc9..1636ddebd 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/DataPort.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/DataPort.java @@ -19,6 +19,7 @@ package net.emustudio.plugins.device.mits88disk.ports; import net.emustudio.emulib.plugins.device.DeviceContext; +import net.emustudio.plugins.device.mits88disk.drive.Drive; import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; import java.util.Objects; @@ -38,12 +39,12 @@ public DataPort(DriveCollection disk) { @Override public Short readData() { - return disk.getCurrentDrive().readData(); + return disk.getCurrentDrive().map(Drive::readData).orElse((short)0); } @Override public void writeData(Short data) { - disk.getCurrentDrive().writeData(data); + disk.getCurrentDrive().ifPresent(drive -> drive.writeData(data)); } @Override diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/StatusPort.java b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/StatusPort.java index bdace0518..6a228485d 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/StatusPort.java +++ b/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/StatusPort.java @@ -39,21 +39,17 @@ public StatusPort(DriveCollection disk) { @Override public Short readData() { - // interpret port1 status - return disk.getCurrentDrive().getPort1status(); + return disk.getCurrentDrive().map(Drive::getPort1status).orElse(Drive.DEAD_DRIVE); } @Override public void writeData(Short value) { - // select device - disk.setCurrentDrive(value & 0x0F); - Drive drive = disk.getCurrentDrive(); if ((value & 0x80) != 0) { - // disable device - drive.deselect(); - disk.setCurrentDrive(0xFF); + disk.getCurrentDrive().ifPresent(Drive::deselect); + disk.unsetCurrentDrive(); } else { - drive.select(); + disk.setCurrentDrive(value & 0x0F); + disk.getCurrentDrive().ifPresent(Drive::select); } } From a51df143276b2678302c8f9f86b3481074db822f Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 7 Aug 2020 09:06:56 +0200 Subject: [PATCH 005/314] Updated README --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a2adbe70f..4e0a53513 100644 --- a/README.md +++ b/README.md @@ -12,15 +12,15 @@ since 2007. ## Available emulators -* [MITS Altair8800](https://www.emustudio.net/docuser/mits_altair_8800/index/) +* [MITS Altair8800](https://www.emustudio.net/documentation/user/altair8800/) -* [Manchester SSEM](https://www.emustudio.net/docuser/ssem/index/) +* [Manchester SSEM](https://www.emustudio.net/documentation/user/ssem/) -* [Random Access Machine (RAM)](https://www.emustudio.net/docuser/ram/index/) +* [Random Access Machine (RAM)](https://www.emustudio.net/documentation/user/ram/) -* [Random Access Stored Program (RASP)](https://www.emustudio.net/docuser/rasp/index/) +* [Random Access Stored Program (RASP)](https://www.emustudio.net/documentation/user/rasp/) -* [BrainDuck (brainfuck interpreter)](https://www.emustudio.net/docuser/brainduck/index/) +* [BrainDuck (brainfuck interpreter)](https://www.emustudio.net/documentation/user/brainduck/) ## BIG THANKS @@ -48,12 +48,12 @@ Then, unzip the tar/zip file (`emuStudio-xxx.zip`) and run it using command: NOTE: Currently supported are Linux and Windows. Mac is NOT supported, but it might work to some extent. -For more information, please read [user documentation](https://www.emustudio.net/docs/). +For more information, please read [user documentation](https://www.emustudio.net/documentation/user/introduction/). ## Contributing Anyone can contribute. Before start, please read -[developer documentation](https://www.emustudio.net/devel/), +[developer documentation](https://www.emustudio.net/documentation/developer/introduction/), which includes information like: - Which tools to use and how to set up the environment From b374f69e63eab9e17a011d882af30f1b4eb9bb4d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 30 Sep 2020 08:32:47 +0200 Subject: [PATCH 006/314] [#185] Rename 88-DISK to 88-DCDD --- application/build.gradle | 6 +-- plugins/device/{88-disk => 88-dcdd}/README.md | 4 +- .../device/{88-disk => 88-dcdd}/build.gradle | 0 .../plugins/device/mits88dcdd}/Command.java | 4 +- .../device/mits88dcdd}/CommandLine.java | 21 +++----- .../device/mits88dcdd}/DeviceImpl.java | 47 ++++++++---------- .../plugins/device/mits88dcdd/Resources.java | 42 ++++++++++++++++ .../plugins/device/mits88dcdd}/Runner.java | 2 +- .../device/mits88dcdd}/SettingsConstants.java | 2 +- .../device/mits88dcdd}/cpmfs/CpmFile.java | 2 +- .../mits88dcdd}/cpmfs/CpmFileSystem.java | 2 +- .../device/mits88dcdd}/cpmfs/DriveIO.java | 2 +- .../device/mits88dcdd}/cpmfs/Position.java | 2 +- .../cpmfs/commands/CatSubCommand.java | 4 +- .../cpmfs/commands/CpmfsCommand.java | 8 +-- .../cpmfs/commands/DownloadSubCommand.java | 4 +- .../cpmfs/commands/InfoSubCommand.java | 4 +- .../cpmfs/commands/ListSubCommand.java | 6 +-- .../device/mits88dcdd}/drive/Drive.java | 2 +- .../mits88dcdd}/drive/DriveCollection.java | 2 +- .../mits88dcdd}/drive/DriveListener.java | 2 +- .../mits88dcdd}/drive/DriveParameters.java | 2 +- .../device/mits88dcdd}/gui/Constants.java | 4 +- .../device/mits88dcdd}/gui/DiskGui.java | 15 +++--- .../device/mits88dcdd}/gui/DriveButton.java | 8 +-- .../mits88dcdd}/gui/SettingsDialog.java | 19 +++---- .../device/mits88dcdd}/ports/ControlPort.java | 10 ++-- .../device/mits88dcdd}/ports/DataPort.java | 10 ++-- .../device/mits88dcdd}/ports/StatusPort.java | 10 ++-- .../plugins/device/mits88dcdd}/gui/off.gif | Bin .../plugins/device/mits88dcdd}/gui/on.gif | Bin .../device/mits88dcdd}/version.properties | 0 .../src/main/scripts/88-disk | 0 .../src/main/scripts/88-disk.bat | 6 +-- .../device/mits88dcdd}/DeviceImplTest.java | 2 +- .../plugins/device/mits88dcdd}/DriveTest.java | 8 +-- settings.gradle | 2 +- 37 files changed, 150 insertions(+), 114 deletions(-) rename plugins/device/{88-disk => 88-dcdd}/README.md (74%) rename plugins/device/{88-disk => 88-dcdd}/build.gradle (100%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/Command.java (50%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/CommandLine.java (78%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/DeviceImpl.java (81%) create mode 100644 plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Resources.java rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/Runner.java (94%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/SettingsConstants.java (95%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/cpmfs/CpmFile.java (97%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/cpmfs/CpmFileSystem.java (99%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/cpmfs/DriveIO.java (98%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/cpmfs/Position.java (95%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/cpmfs/commands/CatSubCommand.java (74%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/cpmfs/commands/CpmfsCommand.java (87%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/cpmfs/commands/DownloadSubCommand.java (89%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/cpmfs/commands/InfoSubCommand.java (73%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/cpmfs/commands/ListSubCommand.java (70%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/drive/Drive.java (99%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/drive/DriveCollection.java (96%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/drive/DriveListener.java (70%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/drive/DriveParameters.java (97%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/gui/Constants.java (72%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/gui/DiskGui.java (97%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/gui/DriveButton.java (78%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/gui/SettingsDialog.java (97%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/ports/ControlPort.java (83%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/ports/DataPort.java (83%) rename plugins/device/{88-disk/src/main/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd}/ports/StatusPort.java (84%) rename plugins/device/{88-disk/src/main/resources/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd}/gui/off.gif (100%) rename plugins/device/{88-disk/src/main/resources/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd}/gui/on.gif (100%) rename plugins/device/{88-disk/src/main/resources/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd}/version.properties (100%) rename plugins/device/{88-disk => 88-dcdd}/src/main/scripts/88-disk (100%) rename plugins/device/{88-disk => 88-dcdd}/src/main/scripts/88-disk.bat (94%) rename plugins/device/{88-disk/src/test/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd}/DeviceImplTest.java (95%) rename plugins/device/{88-disk/src/test/java/net/emustudio/plugins/device/mits88disk => 88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd}/DriveTest.java (97%) diff --git a/application/build.gradle b/application/build.gradle index ffec6f634..cec7fba1c 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -69,7 +69,7 @@ dependencies { providedRuntime project(":plugins:cpu:ssem-cpu") providedRuntime project(":plugins:device:abstract-tape") - providedRuntime project(":plugins:device:88-disk") + providedRuntime project(":plugins:device:88-dcdd") providedRuntime project(":plugins:device:88-sio") providedRuntime project(":plugins:device:adm3A-terminal") providedRuntime project(":plugins:device:brainduck-terminal") @@ -202,7 +202,7 @@ distributions { into('device') { include '*.jar' from(output(":plugins:device:abstract-tape")) - from(output(":plugins:device:88-disk")) + from(output(":plugins:device:88-dcdd")) from(output(":plugins:device:88-sio")) from(output(":plugins:device:adm3A-terminal")) from(output(":plugins:device:brainduck-terminal")) @@ -223,7 +223,7 @@ distributions { into "bin" } } - ["88-disk"].collect { device -> + ["88-dcdd"].collect { device -> from(scripts(":plugins:device:$device")) { into "bin" } diff --git a/plugins/device/88-disk/README.md b/plugins/device/88-dcdd/README.md similarity index 74% rename from plugins/device/88-disk/README.md rename to plugins/device/88-dcdd/README.md index 1defe51f4..a27113236 100644 --- a/plugins/device/88-disk/README.md +++ b/plugins/device/88-dcdd/README.md @@ -1,6 +1,6 @@ -# 88-disk +# 88-DCDD -This project is emulator of device MITS 88-DISK. +This project is emulator of device MITS 88-DCDD It is part of [emuStudio](https://www.emustudio.net/). The official documentation can be found [here](https://www.emustudio.net/docuser/mits_altair_8800/index/#DISK-88) diff --git a/plugins/device/88-disk/build.gradle b/plugins/device/88-dcdd/build.gradle similarity index 100% rename from plugins/device/88-disk/build.gradle rename to plugins/device/88-dcdd/build.gradle diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/Command.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Command.java similarity index 50% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/Command.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Command.java index 5341df093..a19b1440f 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/Command.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Command.java @@ -1,6 +1,6 @@ -package net.emustudio.plugins.device.mits88disk; +package net.emustudio.plugins.device.mits88dcdd; -import net.emustudio.plugins.device.mits88disk.cpmfs.DriveIO; +import net.emustudio.plugins.device.mits88dcdd.cpmfs.DriveIO; import java.io.IOException; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/CommandLine.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/CommandLine.java similarity index 78% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/CommandLine.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/CommandLine.java index 3a5ce1353..a8e140d00 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/CommandLine.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/CommandLine.java @@ -1,7 +1,7 @@ -package net.emustudio.plugins.device.mits88disk; +package net.emustudio.plugins.device.mits88dcdd; -import net.emustudio.plugins.device.mits88disk.cpmfs.DriveIO; -import net.emustudio.plugins.device.mits88disk.cpmfs.commands.CpmfsCommand; +import net.emustudio.plugins.device.mits88dcdd.cpmfs.DriveIO; +import net.emustudio.plugins.device.mits88dcdd.cpmfs.commands.CpmfsCommand; import org.kohsuke.args4j.*; import org.kohsuke.args4j.spi.SubCommand; import org.kohsuke.args4j.spi.SubCommandHandler; @@ -12,9 +12,9 @@ import java.io.IOException; import java.nio.file.Path; import java.nio.file.StandardOpenOption; -import java.util.MissingResourceException; import java.util.Optional; -import java.util.ResourceBundle; + +import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; public class CommandLine { private final static Logger LOGGER = LoggerFactory.getLogger(CommandLine.class); @@ -48,7 +48,7 @@ public static Optional parse(String[] args) { parser.parseArgument(args); if (commandLine.help) { - System.out.println("MITS 88-DISK emuStudio plug-in, version " + getVersion()); + System.out.println(DIALOG_TITLE + " emuStudio plug-in, version " + Resources.getVersion()); parser.printUsage(System.err); System.exit(0); @@ -73,13 +73,4 @@ private Runnable createCommand() { } }; } - - private static String getVersion() { - try { - ResourceBundle bundle = ResourceBundle.getBundle("net.sf.net.emustudio.devices.mits88disk.version"); - return bundle.getString("version"); - } catch (MissingResourceException e) { - return "(unknown)"; - } - } } diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/DeviceImpl.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java similarity index 81% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/DeviceImpl.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java index 5d60dcf59..46ea414b5 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/DeviceImpl.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk; +package net.emustudio.plugins.device.mits88dcdd; import net.emustudio.emulib.plugins.PluginInitializationException; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; @@ -28,13 +28,13 @@ import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; -import net.emustudio.plugins.device.mits88disk.drive.Drive; -import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; -import net.emustudio.plugins.device.mits88disk.gui.DiskGui; -import net.emustudio.plugins.device.mits88disk.gui.SettingsDialog; -import net.emustudio.plugins.device.mits88disk.ports.ControlPort; -import net.emustudio.plugins.device.mits88disk.ports.DataPort; -import net.emustudio.plugins.device.mits88disk.ports.StatusPort; +import net.emustudio.plugins.device.mits88dcdd.drive.Drive; +import net.emustudio.plugins.device.mits88dcdd.drive.DriveCollection; +import net.emustudio.plugins.device.mits88dcdd.gui.DiskGui; +import net.emustudio.plugins.device.mits88dcdd.gui.SettingsDialog; +import net.emustudio.plugins.device.mits88dcdd.ports.ControlPort; +import net.emustudio.plugins.device.mits88dcdd.ports.DataPort; +import net.emustudio.plugins.device.mits88dcdd.ports.StatusPort; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,11 +43,12 @@ import java.nio.file.Path; import java.util.*; +import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; + @PluginRoot( type = PLUGIN_TYPE.DEVICE, - title = "MITS 88-DISK device" + title = "MITS 88-DCDD device" ) -@SuppressWarnings("unused") public class DeviceImpl extends AbstractDevice { private final static Logger LOGGER = LoggerFactory.getLogger(DeviceImpl.class); @@ -110,17 +111,17 @@ public void showGUI(JFrame parent) { @Override public String getVersion() { - return getResourceBundle().map(b -> b.getString("version")).orElse("(unknown)"); + return Resources.getVersion(); } @Override public String getCopyright() { - return getResourceBundle().map(b -> b.getString("copyright")).orElse("(unknown)"); + return Resources.getCopyright(); } @Override public String getDescription() { - return "MITS 88-DISK floppy disk controller."; + return DIALOG_TITLE + " floppy disk controller."; } @Override @@ -168,7 +169,7 @@ private void readSettings() { LOGGER.error("Could not mount image file {}", path, ex); applicationApi.getDialogs().showError( "Could not mount image file: " + path + ". Please see log file for more details.", - "MITS 88-DISK" + "MITS 88-DCDD" ); } }); @@ -189,35 +190,27 @@ private int attachPort(int diskPortNumber, DeviceContext diskPort, int cp portNumber = dialogs.readInteger( "Port " + diskPortNumber + " could not be attached to CPU port " + cpuPort + "." + "\nPlease enter another CPU port:", - "88-DISK" + DIALOG_TITLE ).orElseThrow(() -> new PluginInitializationException( - this, ": 88-DISK (port " + diskPortNumber + ") can not be attached to default CPU port " + cpuPort + this, ": " + DIALOG_TITLE + " (port " + diskPortNumber + ") can not be attached to default CPU port " + cpuPort )); enteredValid = true; } catch (NumberFormatException e) { - dialogs.showError("Invalid number format", "MITS 88-DISK"); + dialogs.showError("Invalid number format", DIALOG_TITLE); } } if (!cpuContext.attachDevice(diskPort, portNumber)) { dialogs.showError( "Port " + diskPortNumber + " still cannot be attached to provided CPU port " + portNumber, - "MITS 88-DISK" + DIALOG_TITLE ); throw new PluginInitializationException( - this, ": 88-DISK (port " + diskPortNumber + ") can not be attached to CPU port " + portNumber + this, ": " + DIALOG_TITLE + " (port " + diskPortNumber + ") can not be attached to CPU port " + portNumber ); } return portNumber; } } - - private Optional getResourceBundle() { - try { - return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.device.mits88disk.version")); - } catch (MissingResourceException e) { - return Optional.empty(); - } - } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Resources.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Resources.java new file mode 100644 index 000000000..f3d3e231b --- /dev/null +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Resources.java @@ -0,0 +1,42 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2020 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.mits88dcdd; + +import java.util.MissingResourceException; +import java.util.Optional; +import java.util.ResourceBundle; + +public class Resources { + + public static Optional getResourceBundle() { + try { + return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.device.mits88dcdd.version")); + } catch (MissingResourceException e) { + return Optional.empty(); + } + } + + public static String getVersion() { + return getResourceBundle().map(b -> b.getString("version")).orElse("(unknown)"); + } + + public static String getCopyright() { + return getResourceBundle().map(b -> b.getString("copyright")).orElse("(unknown)"); + } +} diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/Runner.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Runner.java similarity index 94% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/Runner.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Runner.java index f64772adf..8262be611 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/Runner.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Runner.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk; +package net.emustudio.plugins.device.mits88dcdd; public class Runner { diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/SettingsConstants.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/SettingsConstants.java similarity index 95% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/SettingsConstants.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/SettingsConstants.java index 6352c7a8b..c4b9fbcea 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/SettingsConstants.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/SettingsConstants.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk; +package net.emustudio.plugins.device.mits88dcdd; public class SettingsConstants { public static final String PORT1_CPU = "port1CPU"; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/CpmFile.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFile.java similarity index 97% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/CpmFile.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFile.java index e39a7f785..6c52d4cf4 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/CpmFile.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFile.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk.cpmfs; +package net.emustudio.plugins.device.mits88dcdd.cpmfs; import net.jcip.annotations.Immutable; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/CpmFileSystem.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFileSystem.java similarity index 99% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/CpmFileSystem.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFileSystem.java index c4477ab82..67413cd6f 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/CpmFileSystem.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFileSystem.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.device.mits88disk.cpmfs; +package net.emustudio.plugins.device.mits88dcdd.cpmfs; import net.jcip.annotations.NotThreadSafe; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/DriveIO.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DriveIO.java similarity index 98% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/DriveIO.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DriveIO.java index 0e31f12ff..adc933430 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/DriveIO.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DriveIO.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk.cpmfs; +package net.emustudio.plugins.device.mits88dcdd.cpmfs; import java.io.IOException; import java.nio.ByteBuffer; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/Position.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/Position.java similarity index 95% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/Position.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/Position.java index 666483f18..e07a8b2b3 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/Position.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/Position.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk.cpmfs; +package net.emustudio.plugins.device.mits88dcdd.cpmfs; class Position { int track; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/CatSubCommand.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/CatSubCommand.java similarity index 74% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/CatSubCommand.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/CatSubCommand.java index 70105155b..3da8a271d 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/CatSubCommand.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/CatSubCommand.java @@ -1,6 +1,6 @@ -package net.emustudio.plugins.device.mits88disk.cpmfs.commands; +package net.emustudio.plugins.device.mits88dcdd.cpmfs.commands; -import net.emustudio.plugins.device.mits88disk.cpmfs.CpmFileSystem; +import net.emustudio.plugins.device.mits88dcdd.cpmfs.CpmFileSystem; import org.kohsuke.args4j.Argument; import java.io.IOException; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/CpmfsCommand.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/CpmfsCommand.java similarity index 87% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/CpmfsCommand.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/CpmfsCommand.java index dac167582..3eeadb4a4 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/CpmfsCommand.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/CpmfsCommand.java @@ -1,8 +1,8 @@ -package net.emustudio.plugins.device.mits88disk.cpmfs.commands; +package net.emustudio.plugins.device.mits88dcdd.cpmfs.commands; -import net.emustudio.plugins.device.mits88disk.Command; -import net.emustudio.plugins.device.mits88disk.cpmfs.CpmFileSystem; -import net.emustudio.plugins.device.mits88disk.cpmfs.DriveIO; +import net.emustudio.plugins.device.mits88dcdd.Command; +import net.emustudio.plugins.device.mits88dcdd.cpmfs.CpmFileSystem; +import net.emustudio.plugins.device.mits88dcdd.cpmfs.DriveIO; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; import org.kohsuke.args4j.spi.SubCommand; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/DownloadSubCommand.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/DownloadSubCommand.java similarity index 89% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/DownloadSubCommand.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/DownloadSubCommand.java index 4b088d869..6eac9df42 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/DownloadSubCommand.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/DownloadSubCommand.java @@ -1,6 +1,6 @@ -package net.emustudio.plugins.device.mits88disk.cpmfs.commands; +package net.emustudio.plugins.device.mits88dcdd.cpmfs.commands; -import net.emustudio.plugins.device.mits88disk.cpmfs.CpmFileSystem; +import net.emustudio.plugins.device.mits88dcdd.cpmfs.CpmFileSystem; import org.kohsuke.args4j.Argument; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/InfoSubCommand.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/InfoSubCommand.java similarity index 73% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/InfoSubCommand.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/InfoSubCommand.java index f58edbb86..f383853d6 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/InfoSubCommand.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/InfoSubCommand.java @@ -1,6 +1,6 @@ -package net.emustudio.plugins.device.mits88disk.cpmfs.commands; +package net.emustudio.plugins.device.mits88dcdd.cpmfs.commands; -import net.emustudio.plugins.device.mits88disk.cpmfs.CpmFileSystem; +import net.emustudio.plugins.device.mits88dcdd.cpmfs.CpmFileSystem; import java.io.IOException; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/ListSubCommand.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/ListSubCommand.java similarity index 70% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/ListSubCommand.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/ListSubCommand.java index 447a2790c..f4e7029d4 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/cpmfs/commands/ListSubCommand.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/commands/ListSubCommand.java @@ -1,7 +1,7 @@ -package net.emustudio.plugins.device.mits88disk.cpmfs.commands; +package net.emustudio.plugins.device.mits88dcdd.cpmfs.commands; -import net.emustudio.plugins.device.mits88disk.cpmfs.CpmFile; -import net.emustudio.plugins.device.mits88disk.cpmfs.CpmFileSystem; +import net.emustudio.plugins.device.mits88dcdd.cpmfs.CpmFile; +import net.emustudio.plugins.device.mits88dcdd.cpmfs.CpmFileSystem; import java.io.IOException; import java.util.Collection; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/Drive.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java similarity index 99% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/Drive.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java index 8386bfe16..58966d446 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/Drive.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk.drive; +package net.emustudio.plugins.device.mits88dcdd.drive; import net.jcip.annotations.ThreadSafe; import org.slf4j.Logger; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveCollection.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java similarity index 96% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveCollection.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java index fcc364073..211cc23c0 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveCollection.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.device.mits88disk.drive; +package net.emustudio.plugins.device.mits88dcdd.drive; import java.util.ArrayList; import java.util.Iterator; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveListener.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveListener.java similarity index 70% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveListener.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveListener.java index 2b0ab830c..c7eab3117 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveListener.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveListener.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.device.mits88disk.drive; +package net.emustudio.plugins.device.mits88dcdd.drive; public interface DriveListener { diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveParameters.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveParameters.java similarity index 97% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveParameters.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveParameters.java index 35046edf5..b4b00fd3f 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/drive/DriveParameters.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveParameters.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.device.mits88disk.drive; +package net.emustudio.plugins.device.mits88dcdd.drive; import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.jcip.annotations.Immutable; diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/Constants.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/Constants.java similarity index 72% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/Constants.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/Constants.java index 9d112424f..2569fd90e 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/Constants.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/Constants.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.device.mits88disk.gui; +package net.emustudio.plugins.device.mits88dcdd.gui; import java.awt.*; @@ -6,4 +6,6 @@ public class Constants { public static Font DIALOG_PLAIN = new Font(Font.DIALOG, Font.PLAIN, 12); public static Font MONOSPACED_PLAIN = new Font(Font.MONOSPACED, Font.PLAIN, 12); public static Font MONOSPACED_BOLD = new Font(Font.MONOSPACED, Font.BOLD, 12); + + public static String DIALOG_TITLE = "MITS 88-DCDD"; } diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DiskGui.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java similarity index 97% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DiskGui.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java index f42721375..d657e52a4 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DiskGui.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java @@ -16,12 +16,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk.gui; +package net.emustudio.plugins.device.mits88dcdd.gui; -import net.emustudio.plugins.device.mits88disk.drive.Drive; -import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; -import net.emustudio.plugins.device.mits88disk.drive.DriveListener; -import net.emustudio.plugins.device.mits88disk.drive.DriveParameters; +import net.emustudio.plugins.device.mits88dcdd.drive.Drive; +import net.emustudio.plugins.device.mits88dcdd.drive.DriveCollection; +import net.emustudio.plugins.device.mits88dcdd.drive.DriveListener; +import net.emustudio.plugins.device.mits88dcdd.drive.DriveParameters; import javax.swing.*; import javax.swing.border.TitledBorder; @@ -29,7 +29,8 @@ import java.awt.event.KeyEvent; import java.util.Objects; -import static net.emustudio.plugins.device.mits88disk.gui.Constants.MONOSPACED_PLAIN; +import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; +import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.MONOSPACED_PLAIN; public class DiskGui extends JDialog { private final DriveButton[] driveButtons = new DriveButton[]{ @@ -117,7 +118,7 @@ private void initComponents() { setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); - setTitle("MITS 88-DISK (floppy)"); + setTitle(DIALOG_TITLE); setResizable(false); panelDiskSelection.setBorder(BorderFactory.createTitledBorder(null, "Disk selection", diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DriveButton.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DriveButton.java similarity index 78% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DriveButton.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DriveButton.java index ddfd461a9..cb6f90a02 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/DriveButton.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DriveButton.java @@ -1,12 +1,12 @@ -package net.emustudio.plugins.device.mits88disk.gui; +package net.emustudio.plugins.device.mits88dcdd.gui; import javax.swing.*; -import static net.emustudio.plugins.device.mits88disk.gui.Constants.MONOSPACED_PLAIN; +import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.MONOSPACED_PLAIN; public class DriveButton extends JToggleButton { - private final static String ICON_OFF = "/net/emustudio/plugins/device/mits88disk/gui/off.gif"; - private final static String ICON_ON = "/net/emustudio/plugins/device/mits88disk/gui/on.gif"; + private final static String ICON_OFF = "/net/emustudio/plugins/device/mits88dcdd/gui/off.gif"; + private final static String ICON_ON = "/net/emustudio/plugins/device/mits88dcdd/gui/on.gif"; public DriveButton(String text, Runnable action) { super(text, new ImageIcon(DriveButton.class.getResource(ICON_OFF))); diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/SettingsDialog.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java similarity index 97% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/SettingsDialog.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java index 0da7f7e2d..a3369a4ac 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/gui/SettingsDialog.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java @@ -16,16 +16,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk.gui; +package net.emustudio.plugins.device.mits88dcdd.gui; import net.emustudio.emulib.runtime.CannotUpdateSettingException; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; -import net.emustudio.plugins.device.mits88disk.SettingsConstants; -import net.emustudio.plugins.device.mits88disk.drive.Drive; -import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; +import net.emustudio.plugins.device.mits88dcdd.SettingsConstants; +import net.emustudio.plugins.device.mits88dcdd.drive.Drive; +import net.emustudio.plugins.device.mits88dcdd.drive.DriveCollection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,8 +37,9 @@ import java.util.Objects; import java.util.Optional; -import static net.emustudio.plugins.device.mits88disk.DeviceImpl.*; -import static net.emustudio.plugins.device.mits88disk.gui.Constants.DIALOG_PLAIN; +import static net.emustudio.plugins.device.mits88dcdd.DeviceImpl.*; +import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_PLAIN; +import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; public class SettingsDialog extends JDialog { private final static Logger LOGGER = LoggerFactory.getLogger(SettingsDialog.class); @@ -99,8 +100,8 @@ private void writeSettings() { return null; }); } catch (CannotUpdateSettingException | RuntimeException e) { - LOGGER.error("Could not write MITS 88-DISK settings", e); - dialogs.showError("Could not write settings. Please see log for more details.", "MITS 88-DISK"); + LOGGER.error("Could not write " + DIALOG_TITLE + " settings", e); + dialogs.showError("Could not write settings. Please see log for more details.", DIALOG_TITLE); } } @@ -154,7 +155,7 @@ private void initComponents() { setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); - setTitle("MITS 88-DISK Settings"); + setTitle(DIALOG_TITLE + " Settings"); jTabbedPane1.setFont(jTabbedPane1.getFont()); diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/ControlPort.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/ControlPort.java similarity index 83% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/ControlPort.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/ControlPort.java index b6f47a980..0ba7b24b6 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/ControlPort.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/ControlPort.java @@ -16,14 +16,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk.ports; +package net.emustudio.plugins.device.mits88dcdd.ports; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.device.mits88disk.drive.Drive; -import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; +import net.emustudio.plugins.device.mits88dcdd.drive.Drive; +import net.emustudio.plugins.device.mits88dcdd.drive.DriveCollection; import java.util.Objects; +import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; + /** * Port 2, Control port. *

@@ -57,7 +59,7 @@ public Class getDataType() { @Override public String toString() { - return "88-DISK Control Port"; + return DIALOG_TITLE + " Control Port"; } } diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/DataPort.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/DataPort.java similarity index 83% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/DataPort.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/DataPort.java index 1636ddebd..f93bd0d60 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/DataPort.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/DataPort.java @@ -16,14 +16,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk.ports; +package net.emustudio.plugins.device.mits88dcdd.ports; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.device.mits88disk.drive.Drive; -import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; +import net.emustudio.plugins.device.mits88dcdd.drive.Drive; +import net.emustudio.plugins.device.mits88dcdd.drive.DriveCollection; import java.util.Objects; +import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; + /** * Port 3, Data port. *

@@ -54,6 +56,6 @@ public Class getDataType() { @Override public String toString() { - return "88-DISK Data Port"; + return DIALOG_TITLE + " Data Port"; } } diff --git a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/StatusPort.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/StatusPort.java similarity index 84% rename from plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/StatusPort.java rename to plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/StatusPort.java index 6a228485d..cd583d6ac 100644 --- a/plugins/device/88-disk/src/main/java/net/emustudio/plugins/device/mits88disk/ports/StatusPort.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/StatusPort.java @@ -16,14 +16,16 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk.ports; +package net.emustudio.plugins.device.mits88dcdd.ports; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.device.mits88disk.drive.Drive; -import net.emustudio.plugins.device.mits88disk.drive.DriveCollection; +import net.emustudio.plugins.device.mits88dcdd.drive.Drive; +import net.emustudio.plugins.device.mits88dcdd.drive.DriveCollection; import java.util.Objects; +import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; + /** * Port 1, Status port. *

@@ -60,6 +62,6 @@ public Class getDataType() { @Override public String toString() { - return "88-DISK Status Port"; + return DIALOG_TITLE + " Status Port"; } } diff --git a/plugins/device/88-disk/src/main/resources/net/emustudio/plugins/device/mits88disk/gui/off.gif b/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/off.gif similarity index 100% rename from plugins/device/88-disk/src/main/resources/net/emustudio/plugins/device/mits88disk/gui/off.gif rename to plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/off.gif diff --git a/plugins/device/88-disk/src/main/resources/net/emustudio/plugins/device/mits88disk/gui/on.gif b/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/on.gif similarity index 100% rename from plugins/device/88-disk/src/main/resources/net/emustudio/plugins/device/mits88disk/gui/on.gif rename to plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/on.gif diff --git a/plugins/device/88-disk/src/main/resources/net/emustudio/plugins/device/mits88disk/version.properties b/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/version.properties similarity index 100% rename from plugins/device/88-disk/src/main/resources/net/emustudio/plugins/device/mits88disk/version.properties rename to plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/version.properties diff --git a/plugins/device/88-disk/src/main/scripts/88-disk b/plugins/device/88-dcdd/src/main/scripts/88-disk similarity index 100% rename from plugins/device/88-disk/src/main/scripts/88-disk rename to plugins/device/88-dcdd/src/main/scripts/88-disk diff --git a/plugins/device/88-disk/src/main/scripts/88-disk.bat b/plugins/device/88-dcdd/src/main/scripts/88-disk.bat similarity index 94% rename from plugins/device/88-disk/src/main/scripts/88-disk.bat rename to plugins/device/88-dcdd/src/main/scripts/88-disk.bat index 568a1f8cf..c83f93dfc 100644 --- a/plugins/device/88-disk/src/main/scripts/88-disk.bat +++ b/plugins/device/88-dcdd/src/main/scripts/88-disk.bat @@ -1,7 +1,7 @@ @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem -@rem 88-disk startup script for Windows +@rem 88-dcdd startup script for Windows @rem @rem ########################################################################## @@ -68,9 +68,9 @@ set CMD_LINE_ARGS=%* set CMD_LINE_ARGS=%* -set CLASSPATH="%APP_HOME%\device\88-disk.jar;%APP_HOME%\lib\*" +set CLASSPATH="%APP_HOME%\device\88-dcdd.jar;%APP_HOME%\lib\*" -@rem Execute 88-disk +@rem Execute 88-dcdd "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %M88_DISK_OPTS% -classpath "%CLASSPATH%" net.emustudio.plugins.device.mits88disk.Runner %CMD_LINE_ARGS% :end diff --git a/plugins/device/88-disk/src/test/java/net/emustudio/plugins/device/mits88disk/DeviceImplTest.java b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DeviceImplTest.java similarity index 95% rename from plugins/device/88-disk/src/test/java/net/emustudio/plugins/device/mits88disk/DeviceImplTest.java rename to plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DeviceImplTest.java index b63a3eaba..8ad537fca 100644 --- a/plugins/device/88-disk/src/test/java/net/emustudio/plugins/device/mits88disk/DeviceImplTest.java +++ b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DeviceImplTest.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.device.mits88disk; +package net.emustudio.plugins.device.mits88dcdd; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; diff --git a/plugins/device/88-disk/src/test/java/net/emustudio/plugins/device/mits88disk/DriveTest.java b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java similarity index 97% rename from plugins/device/88-disk/src/test/java/net/emustudio/plugins/device/mits88disk/DriveTest.java rename to plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java index d6ee82946..6a09120fa 100644 --- a/plugins/device/88-disk/src/test/java/net/emustudio/plugins/device/mits88disk/DriveTest.java +++ b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java @@ -16,11 +16,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88disk; +package net.emustudio.plugins.device.mits88dcdd; -import net.emustudio.plugins.device.mits88disk.drive.Drive; -import net.emustudio.plugins.device.mits88disk.drive.DriveListener; -import net.emustudio.plugins.device.mits88disk.drive.DriveParameters; +import net.emustudio.plugins.device.mits88dcdd.drive.Drive; +import net.emustudio.plugins.device.mits88dcdd.drive.DriveListener; +import net.emustudio.plugins.device.mits88dcdd.drive.DriveParameters; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Rule; diff --git a/settings.gradle b/settings.gradle index fe42f27c1..b75030374 100644 --- a/settings.gradle +++ b/settings.gradle @@ -35,7 +35,7 @@ include ':plugins:cpu:rasp-cpu' include ':plugins:cpu:ssem-cpu' include ':plugins:cpu:z80-cpu' -include ':plugins:device:88-disk' +include ':plugins:device:88-dcdd' include ':plugins:device:88-sio' include ':plugins:device:abstract-tape' include ':plugins:device:adm3A-terminal' From 668024e6d6b6b6b99fa9c11b55f9022feedb68a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Jakub=C4=8Do?= Date: Tue, 1 Dec 2020 08:16:09 +0100 Subject: [PATCH 007/314] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000..56761238f --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,67 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ develop, master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ develop ] + schedule: + - cron: '37 12 * * 2' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'cpp', 'java' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From b254284e5c687878b45d1f347c638ea8290854f4 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 1 Dec 2020 18:46:23 +0100 Subject: [PATCH 008/314] Removed codeql analysis pipeline --- .github/workflows/codeql-analysis.yml | 67 --------------------------- 1 file changed, 67 deletions(-) delete mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 56761238f..000000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,67 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ develop, master ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ develop ] - schedule: - - cron: '37 12 * * 2' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - language: [ 'cpp', 'java' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: - # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 From e3e0f4b566fead036d3819e761158ea4266ad6d3 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 1 Dec 2020 18:52:04 +0100 Subject: [PATCH 009/314] [#185] Renamed MITS 88-DISK scripts --- .../88-dcdd/src/main/scripts/{88-disk => 88-dcdd} | 10 +++++----- .../src/main/scripts/{88-disk.bat => 88-dcdd.bat} | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) rename plugins/device/88-dcdd/src/main/scripts/{88-disk => 88-dcdd} (94%) rename plugins/device/88-dcdd/src/main/scripts/{88-disk.bat => 88-dcdd.bat} (87%) diff --git a/plugins/device/88-dcdd/src/main/scripts/88-disk b/plugins/device/88-dcdd/src/main/scripts/88-dcdd similarity index 94% rename from plugins/device/88-dcdd/src/main/scripts/88-disk rename to plugins/device/88-dcdd/src/main/scripts/88-dcdd index 06d745ec5..8d0eb190e 100755 --- a/plugins/device/88-dcdd/src/main/scripts/88-disk +++ b/plugins/device/88-dcdd/src/main/scripts/88-dcdd @@ -2,7 +2,7 @@ ############################################################################## ## -## 88-disk start up script for UN*X +## 88-dcdd start up script for UN*X ## ############################################################################## @@ -24,10 +24,10 @@ cd "`dirname \"$PRG\"`/.." >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null -APP_NAME="88-disk" +APP_NAME="88-dcdd" APP_BASE_NAME=`basename "$0"` -# Add default JVM options here. You can also use JAVA_OPTS and M88_DISK_OPTS to pass JVM options to this script. +# Add default JVM options here. You can also use JAVA_OPTS and M88_DCDD_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. @@ -64,7 +64,7 @@ case "`uname`" in ;; esac -CLASSPATH="$APP_HOME/device/88-disk.jar:$APP_HOME/lib/*" +CLASSPATH="$APP_HOME/device/88-dcdd.jar:$APP_HOME/lib/*" # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then @@ -162,6 +162,6 @@ save () { APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $M88_DISK_OPTS -classpath "\"$CLASSPATH\"" net.emustudio.plugins.device.mits88disk.Runner "$APP_ARGS" +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $M88_DCDD_OPTS -classpath "\"$CLASSPATH\"" net.emustudio.plugins.device.mits88dcdd.Runner "$APP_ARGS" exec "$JAVACMD" "$@" diff --git a/plugins/device/88-dcdd/src/main/scripts/88-disk.bat b/plugins/device/88-dcdd/src/main/scripts/88-dcdd.bat similarity index 87% rename from plugins/device/88-dcdd/src/main/scripts/88-disk.bat rename to plugins/device/88-dcdd/src/main/scripts/88-dcdd.bat index c83f93dfc..e9582c183 100644 --- a/plugins/device/88-dcdd/src/main/scripts/88-disk.bat +++ b/plugins/device/88-dcdd/src/main/scripts/88-dcdd.bat @@ -16,7 +16,7 @@ set APP_HOME=%DIRNAME%.. @rem Resolve any "." and ".." in APP_HOME to make it shorter. for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi -@rem Add default JVM options here. You can also use JAVA_OPTS and M88_DISK_OPTS to pass JVM options to this script. +@rem Add default JVM options here. You can also use JAVA_OPTS and M88_DCDD_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= @rem Find java.exe @@ -71,16 +71,16 @@ set CMD_LINE_ARGS=%* set CLASSPATH="%APP_HOME%\device\88-dcdd.jar;%APP_HOME%\lib\*" @rem Execute 88-dcdd -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %M88_DISK_OPTS% -classpath "%CLASSPATH%" net.emustudio.plugins.device.mits88disk.Runner %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %M88_DCDD_OPTS% -classpath "%CLASSPATH%" net.emustudio.plugins.device.mits88dcdd.Runner %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail -rem Set variable M88_DISK_EXIT_CONSOLE if you need the _script_ return code instead of +rem Set variable M88_DCDD_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%M88_DISK_EXIT_CONSOLE%" exit 1 +if not "" == "%M88_DCDD_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd From 3b7e49c6ff4198cf43f8586a6f7aef7e0ed4c1a3 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 18 Jan 2021 09:03:46 +0100 Subject: [PATCH 010/314] Update Gradle to 6.8 --- gradle/wrapper/gradle-wrapper.jar | Bin 58695 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 ++ gradlew.bat | 22 ++++------------------ 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index f3d88b1c2faf2fc91d853cd5d4242b5547257070..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644 GIT binary patch delta 12842 zcmY+q1ymhDmoSOmQr324hm`&0SZbS3R18r37J8Z0F-T>@gIK` zatajf2b1lO#&E_RnGDF51uk%8Wcxm3`%Yhe7Psx?*?eZ?8M9_+G(?L=s^OG1n#S(NP3gF?2Mr2^f5E7sM~iVC`Rn;(-^MZ zZu*ZXB;XmgvPls(e#)MMTObsEx9oNz-K?AmQ8pP&P7vqx*=5zxjU+ye_1R<%KSg1? z7H&Yh))(Ke!Pa+aVuWxPKa_~Qo_IH}*;tV8n~O*Xa?t3P^9=L%=wOL1=~{LVv}mU8Q#e6s>v}iV8cDP|EdY)`dp≶7^21 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

XiM^r_M1uFTw)(UPqqUJ zed7DJQvOpplYJoNl`A3a2Zr~v)Y}K|*%d7?8;dC*Af}0=(EXrk7hP8PM4v)ZawEv0 z5j5q_6vilv4*ppZ3Wke7%8b`odJu26#YseA?$sP8?@d?TpACTX`G^?%K=Hly9Y$Tj z5`i!}-WH0lQ3yt-&Pf&Z)OxjKfAZ3X`YI2)5o@9EiOA}?kX`^rk;yaOh^Li4VHcT& zd6ztJz^`H!8>cL)a%?Lnofzo0$WPrgkNcP#u@{%~EvA7g#go z+Q4$Q^o_MJTE0G_&9@cgp)WF>2zo>AG}C|(~E^_?ijc2EQ>> zFH1Lxc@i!gDHxvEsrfc+Kiz3Q6Z*NM+U6DH6*-Fv{YDY4>U&eegGH~Xmk~!sd6fw2 z!6^4(MZWhzf(xs6BHy=oS+dir0_JW(j*AIu$9&&p@}T;&6s7(yYidEdkp6pk9}Z(F zk6lG`d!HcJWP{7X)&P5FW;XWU6;zke2e+g*#1kW4L0Auj5pVA45Bhzt{8lj)XyMHu z0p;Q}t*NLnXbGQOTC9WdOQsX;_yLThOP$mzcEbqSBifmDecV;Fqhtm#KxfJTMhY!K zw{1L9za2QtuIWXu0ZYm@Uy72(9^vYajuP$(VAKn+&Jp z!%S;#BqO;02)n~6pFYK8oRC6wXx@kyb?VENM7l?NFg)%^=q4aZ* zwVCZxA8lalF&n`vk#gxD@!9~Aktc+h2UUUax3q2XKQLuL@CpVEpx2IyiH3bALY+Oi zDydtacE1Z|$z5qsCG=%F{}8_ozwieWuM4VcDesuu+wX&YjHm^Ryx)pVtiSLpch7<` zIw9QM%I;(VG9~#Rw2JNt+;?_=O2lA#YSudpgsM`e&(}1 zGdj7U)St4`+Cj#Vn>a;Bj~Q3S1G54;gzq)`b_Hh~ip(`BK#GMkI*RUcK+6ycjl?QN zP%sH5*R$$6A&8j8O4iFJhuHMXLJm|drH+=!_{`60&+tC8*m3Z=YsR@~%eaZyWQI|W zie7;BRL6`LR+4B{%FY~;-^*1GGTCLp!U6VoS36GUAWv$Rcc#|a7DD01{QPB=VyT)? z+1ZV>P=bP1;>v-+j0;BwenO`EKcIbmB3$r*@a~=?5#KB_R$3bTg zOjEutZmWuylIJQEM?28D!4uA#0CZEJHar0TFAW|NwP;WL|EIb_L2>;}e*N!K9E61S zH&u@m!n#CH{C_j}{#ybCRU8z7`Cs{b>@bxSkp3lOm`qAYgB>npnw%V>w}t_+S_Z)s zFhGKq^e%m@=^@sD0CJdAK=`Upbr}?}N zf;snqpt#dOwhxFg82(%Tw=ND+@`O0JGeOWd7-3R8A%Yu%FhiaYXD>p?t2+o%_1CKE z{g(>=g%}X(O%M!}KZK%$7-F<34wD-24`y$WLDv6z?ty=_b)Oi*x&?v}3j0f`AV3HL zWPAYw!XNs-1EmZ9=d=$6LAJISVJ4&gQM5=bh{!f0OmFNz8oMnGgOl_RK5VPP3@87C zpLS$muCo5YTmOslSjFLb`AXIJ@1|O{pm5r z9MxUb-8HMe*|TpFa%dE?+7}MVQ-A-N8wvtq85ROU2%KYt4etC52X0%W08haQgGSU| zvw=K$djTYSLy@4My_Te_8JcZp8Oozg{-ey>*Nm7BkGrX(M~HU6N16U>DSj<`;cy`u zR?0B23zx|*o1V=#fLZ=wd6*NfWjC`pqA^mt>DTZjGBeX`0ZK>Qgxz+37Dyb#NT4WT zl@7Lmh{WdY*h%e_bo6(oXKw=`(9=mft10fOR4< zCOUungtJZPAM~qw4Ydy9PhvYTi1ZRqR5nY)?OX2O3FJ6VXy&`&H%^U|d>N>@f zQ}Cd;DV}_bNiVTW8HcUJDRvXCUwGx|(r2-KbXY>jpd!~jmt(

p*eWM!w;MI3hb2}DlKZV3$r+FsPh`1u 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 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell From d205a3648c26956df80d9a5a77f8d9e0bcc31746 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 18 Jan 2021 11:58:38 +0100 Subject: [PATCH 011/314] Upgrade Gradle + JFlex --- build.gradle | 9 +++++---- gradle/wrapper/gradle-wrapper.properties | 2 +- plugins/compiler/as-8080/.gitignore | 1 + plugins/compiler/as-8080/build.gradle | 4 ++-- .../emustudio/plugins/compiler/as8080/TokenImpl.java | 3 +-- plugins/compiler/as-8080/src/main/jflex/lexer.jflex | 10 +++++----- plugins/compiler/as-ssem/.gitignore | 1 + plugins/compiler/as-ssem/build.gradle | 4 ++-- plugins/compiler/as-ssem/src/main/jflex/lexer.jflex | 10 +++++----- .../net/emustudio/plugins/compiler/ssem/LexerTest.java | 9 --------- plugins/compiler/as-z80/.gitignore | 1 + plugins/compiler/as-z80/build.gradle | 4 ++-- .../emustudio/plugins/compiler/asZ80/TokenImpl.java | 3 +-- plugins/compiler/as-z80/src/main/jflex/lexer.jflex | 10 +++++----- plugins/compiler/brainc-brainduck/.gitignore | 1 + plugins/compiler/brainc-brainduck/build.gradle | 4 ++-- .../brainc-brainduck/src/main/jflex/lexer.jflex | 4 ++-- plugins/compiler/ramc-ram/.gitignore | 1 + plugins/compiler/ramc-ram/build.gradle | 4 ++-- plugins/compiler/ramc-ram/src/main/jflex/lexer.jflex | 8 ++++---- plugins/compiler/raspc-rasp/.gitignore | 1 + plugins/compiler/raspc-rasp/build.gradle | 4 ++-- plugins/compiler/raspc-rasp/src/main/cup/parser.cup | 3 +-- plugins/compiler/raspc-rasp/src/main/jflex/lexer.jflex | 10 +++++----- 24 files changed, 53 insertions(+), 58 deletions(-) create mode 100644 plugins/compiler/as-8080/.gitignore create mode 100644 plugins/compiler/as-ssem/.gitignore create mode 100644 plugins/compiler/as-z80/.gitignore create mode 100644 plugins/compiler/brainc-brainduck/.gitignore create mode 100644 plugins/compiler/ramc-ram/.gitignore create mode 100644 plugins/compiler/raspc-rasp/.gitignore diff --git a/build.gradle b/build.gradle index 7c0f3b6b4..55c7a0f4c 100644 --- a/build.gradle +++ b/build.gradle @@ -36,14 +36,14 @@ ext.libs = [ logback : "ch.qos.logback:logback-classic:1.2.3", args4j : "args4j:args4j:2.33", - tomlj : "com.electronwill.night-config:toml:3.6.2", + tomlj : "com.electronwill.night-config:toml:3.6.3", - editor : "com.fifesoft:rsyntaxtextarea:3.1.1", - editorDialogs : "com.fifesoft:rstaui:3.1.0", + editor : "com.fifesoft:rsyntaxtextarea:3.1.2", + editorDialogs : "com.fifesoft:rstaui:3.1.1", junit : "junit:junit:4.13", easyMock : "org.easymock:easymock:4.2", - mockito : "org.mockito:mockito-all:1.9.5" + mockito : "org.mockito:mockito-all:1.10.19" ] allprojects { @@ -92,5 +92,6 @@ allprojects { subprojects { repositories { mavenCentral() + mavenLocal() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index da9702f9e..80cf08e74 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/plugins/compiler/as-8080/.gitignore b/plugins/compiler/as-8080/.gitignore new file mode 100644 index 000000000..a5b9d2748 --- /dev/null +++ b/plugins/compiler/as-8080/.gitignore @@ -0,0 +1 @@ +src/main/java/net/emustudio/plugins/compiler/as8080/LexerImpl.java diff --git a/plugins/compiler/as-8080/build.gradle b/plugins/compiler/as-8080/build.gradle index d453f5a16..f5dcd5bad 100644 --- a/plugins/compiler/as-8080/build.gradle +++ b/plugins/compiler/as-8080/build.gradle @@ -21,7 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'org.xbib.gradle.plugin.jflex' version "1.2.1" + id 'org.xbib.gradle.plugin.jflex' version "1.5.0" id "com.github.andrescv.jcup" version "1.0" } @@ -44,7 +44,7 @@ sourceSets.main.java { } jflex { - generateDir = project.file("${buildDir}/generated-sources/jflex/net/emustudio/plugins/compiler/as8080") + no_backup = true } jcup { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/TokenImpl.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/TokenImpl.java index 7d1b59743..56c81cc31 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/TokenImpl.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/TokenImpl.java @@ -27,7 +27,6 @@ public class TokenImpl extends ComplexSymbol implements Token, Symbols { public final static int ERROR_DECIMAL_SIZE = 0xA01; public final static int ERROR_UNCLOSED_CHAR = 0xA02; public final static int ERROR_UNCLOSED_STRING = 0xA03; - public final static int ERROR_UNKNOWN_TOKEN = 0xA05; private final int category; private final int lexerState; @@ -73,7 +72,7 @@ public String getErrorString() { return "Char is not closed with single quote (')"; case ERROR_UNCLOSED_STRING: return "String is not closed with single quote (')"; - case ERROR_UNKNOWN_TOKEN: + case ERROR: return "Unknown token"; } return ""; diff --git a/plugins/compiler/as-8080/src/main/jflex/lexer.jflex b/plugins/compiler/as-8080/src/main/jflex/lexer.jflex index 34c07d2d1..7e45a29e4 100644 --- a/plugins/compiler/as-8080/src/main/jflex/lexer.jflex +++ b/plugins/compiler/as-8080/src/main/jflex/lexer.jflex @@ -63,14 +63,14 @@ import java.io.Reader; } private TokenImpl token(int id, int category) { - Location left = new Location("", yyline+1,yycolumn+1,yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), yychar+yylength()); + Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); + Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); return new TokenImpl(id, category, zzLexicalState, yytext(), left, right); } private TokenImpl token(int id, int category, Object value) { - Location left = new Location("", yyline+1,yycolumn+1,yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), yychar+yylength()); + Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); + Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); return new TokenImpl(id, category, zzLexicalState, yytext(), left, right, value); } %} @@ -344,5 +344,5 @@ Label ={Identifier}[\:] return token(TokenImpl.TLABEL, Token.LABEL, val); } . { - return token(TokenImpl.ERROR_UNKNOWN_TOKEN, Token.ERROR); + return token(TokenImpl.error, Token.ERROR); } diff --git a/plugins/compiler/as-ssem/.gitignore b/plugins/compiler/as-ssem/.gitignore new file mode 100644 index 000000000..628279988 --- /dev/null +++ b/plugins/compiler/as-ssem/.gitignore @@ -0,0 +1 @@ +src/main/java/net/emustudio/plugins/compiler/ssem/LexerImpl.java diff --git a/plugins/compiler/as-ssem/build.gradle b/plugins/compiler/as-ssem/build.gradle index 5fc791d4b..6811a6cb2 100644 --- a/plugins/compiler/as-ssem/build.gradle +++ b/plugins/compiler/as-ssem/build.gradle @@ -21,7 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'org.xbib.gradle.plugin.jflex' version "1.2.1" + id 'org.xbib.gradle.plugin.jflex' version "1.5.0" id "com.github.andrescv.jcup" version "1.0" } @@ -42,7 +42,7 @@ sourceSets.main.java.srcDirs = [ ] jflex { - generateDir = project.file("${buildDir}/generated-sources/jflex/net/emustudio/plugins/compiler/ssem") + no_backup = true } jcup { diff --git a/plugins/compiler/as-ssem/src/main/jflex/lexer.jflex b/plugins/compiler/as-ssem/src/main/jflex/lexer.jflex index 9e621b2d2..163e3769f 100644 --- a/plugins/compiler/as-ssem/src/main/jflex/lexer.jflex +++ b/plugins/compiler/as-ssem/src/main/jflex/lexer.jflex @@ -66,14 +66,14 @@ import java.io.Reader; } private TokenImpl token(int id, int category) { - Location left = new Location("", yyline+1,yycolumn+1,yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), yychar+yylength()); + Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); + Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); return new TokenImpl(id, category, zzLexicalState, yytext(), left, right); } private TokenImpl token(int id, int category, Object value) { - Location left = new Location("", yyline+1,yycolumn+1,yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), yychar+yylength()); + Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); + Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); return new TokenImpl(id, category, zzLexicalState, yytext(), left, right, value); } %} @@ -167,5 +167,5 @@ binnumber = [01]+ /* error fallback */ . { - return token(Token.ERROR, Token.ERROR); + return token(TokenImpl.error, Token.ERROR); } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java index d40e75c1c..d43c3320f 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java @@ -38,7 +38,6 @@ public void testNumberUpperBoundary() throws Exception { TokenImpl token = lexer.next_token(); assertEquals(Token.LITERAL, token.getType()); - assertEquals(TokenImpl.NUMBER, token.getID()); assertEquals(31, token.value); } @@ -48,7 +47,6 @@ public void testNumberLowerBoundary() throws Exception { TokenImpl token = lexer.next_token(); assertEquals(Token.LITERAL, token.getType()); - assertEquals(TokenImpl.NUMBER, token.getID()); assertEquals(0, token.value); } @@ -58,14 +56,12 @@ public void testNumber() throws Exception { TokenImpl token = lexer.next_token(); assertEquals(Token.LITERAL, token.getType()); - assertEquals(TokenImpl.NUMBER, token.getID()); assertEquals(22, token.value); } private void checkInstruction(int id, LexerImpl lexer) throws IOException { TokenImpl token = lexer.next_token(); assertEquals(Token.RESERVED, token.getType()); - assertEquals(id, token.getID()); } private void checkInstructionWithOperand(int id, LexerImpl lexer) throws IOException { @@ -73,7 +69,6 @@ private void checkInstructionWithOperand(int id, LexerImpl lexer) throws IOExcep TokenImpl token = lexer.next_token(); assertEquals(Token.LITERAL, token.getType()); - assertEquals(TokenImpl.NUMBER, token.getID()); } @Test @@ -99,12 +94,10 @@ public void testInstructionInComment() throws Exception { LexerImpl lexer = lexer("// cmp"); TokenImpl token = lexer.next_token(); - assertEquals(TokenImpl.TCOMMENT, token.getID()); assertEquals(Token.COMMENT, token.getType()); token = lexer.next_token(); assertEquals(Token.TEOF, token.getType()); - assertEquals(TokenImpl.EOF, token.getID()); } @Test @@ -113,11 +106,9 @@ public void testBinaryNumber() throws Exception { TokenImpl token = lexer.next_token(); assertEquals(Token.PREPROCESSOR, token.getType()); - assertEquals(TokenImpl.BNUM, token.getID()); assertEquals(LexerImpl.BIN, token.getLexerState()); token = lexer.next_token(); assertEquals(Token.LITERAL, token.getType()); - assertEquals(TokenImpl.NUMBER, token.getID()); } } diff --git a/plugins/compiler/as-z80/.gitignore b/plugins/compiler/as-z80/.gitignore new file mode 100644 index 000000000..4c20bab5e --- /dev/null +++ b/plugins/compiler/as-z80/.gitignore @@ -0,0 +1 @@ +src/main/java/net/emustudio/plugins/compiler/asZ80/LexerImpl.java diff --git a/plugins/compiler/as-z80/build.gradle b/plugins/compiler/as-z80/build.gradle index 15228481e..afe44a6a3 100644 --- a/plugins/compiler/as-z80/build.gradle +++ b/plugins/compiler/as-z80/build.gradle @@ -21,7 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'org.xbib.gradle.plugin.jflex' version "1.2.1" + id 'org.xbib.gradle.plugin.jflex' version "1.5.0" id "com.github.andrescv.jcup" version "1.0" } @@ -41,7 +41,7 @@ sourceSets.main.java.srcDirs = [ ] jflex { - generateDir = project.file("${buildDir}/generated-sources/jflex/net/emustudio/plugins/compiler/asZ80") + no_backup = true } jcup { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/TokenImpl.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/TokenImpl.java index 220009928..2629408e0 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/TokenImpl.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/TokenImpl.java @@ -26,7 +26,6 @@ public class TokenImpl extends ComplexSymbol implements Token, Symbols { public final static int ERROR_DECIMAL_SIZE = 0xA01; public final static int ERROR_UNCLOSED_CHAR = 0xA02; public final static int ERROR_UNCLOSED_STRING = 0xA03; - public final static int ERROR_UNKNOWN_TOKEN = 0xA04; private final int category; private final int lexerState; @@ -68,7 +67,7 @@ public String getErrorString() { return "Char is not closed with single quote (')"; case ERROR_UNCLOSED_STRING: return "String is not closed with single quote (')"; - case ERROR_UNKNOWN_TOKEN: + case ERROR: return "Unknown token"; } return ""; diff --git a/plugins/compiler/as-z80/src/main/jflex/lexer.jflex b/plugins/compiler/as-z80/src/main/jflex/lexer.jflex index dfce0e457..1921e59c4 100644 --- a/plugins/compiler/as-z80/src/main/jflex/lexer.jflex +++ b/plugins/compiler/as-z80/src/main/jflex/lexer.jflex @@ -63,14 +63,14 @@ import java.io.*; } private TokenImpl token(int id, int category) { - Location left = new Location("", yyline+1,yycolumn+1,yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), yychar+yylength()); + Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); + Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); return new TokenImpl(id, category, zzLexicalState, yytext(), left, right); } private TokenImpl token(int id, int category, Object value) { - Location left = new Location("", yyline+1,yycolumn+1,yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), yychar+yylength()); + Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); + Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); return new TokenImpl(id, category, zzLexicalState, yytext(), left, right, value); } %} @@ -648,5 +648,5 @@ Label ={Identifier}[\:] } . { yybegin(YYINITIAL); - return token(TokenImpl.ERROR_UNKNOWN_TOKEN, Token.ERROR); + return token(TokenImpl.error, Token.ERROR); } diff --git a/plugins/compiler/brainc-brainduck/.gitignore b/plugins/compiler/brainc-brainduck/.gitignore new file mode 100644 index 000000000..05b38061e --- /dev/null +++ b/plugins/compiler/brainc-brainduck/.gitignore @@ -0,0 +1 @@ +src/main/java/net/emustudio/plugins/compiler/brainc/LexerImpl.java diff --git a/plugins/compiler/brainc-brainduck/build.gradle b/plugins/compiler/brainc-brainduck/build.gradle index 2eb7bad6b..2f2296b6e 100644 --- a/plugins/compiler/brainc-brainduck/build.gradle +++ b/plugins/compiler/brainc-brainduck/build.gradle @@ -21,7 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'org.xbib.gradle.plugin.jflex' version "1.2.1" + id 'org.xbib.gradle.plugin.jflex' version "1.5.0" id "com.github.andrescv.jcup" version "1.0" } @@ -41,7 +41,7 @@ sourceSets.main.java.srcDirs = [ ] jflex { - generateDir = project.file("${buildDir}/generated-sources/jflex/net/emustudio/plugins/compiler/brainc") + no_backup = true } jcup { diff --git a/plugins/compiler/brainc-brainduck/src/main/jflex/lexer.jflex b/plugins/compiler/brainc-brainduck/src/main/jflex/lexer.jflex index 97da06589..3ab18e72e 100644 --- a/plugins/compiler/brainc-brainduck/src/main/jflex/lexer.jflex +++ b/plugins/compiler/brainc-brainduck/src/main/jflex/lexer.jflex @@ -63,8 +63,8 @@ import java.io.IOException; } private TokenImpl token(int id, int category) { - Location left = new Location("", yyline+1,yycolumn+1,yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), yychar+yylength()); + Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); + Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); return new TokenImpl(id, category, zzLexicalState, yytext(), left, right); } %} diff --git a/plugins/compiler/ramc-ram/.gitignore b/plugins/compiler/ramc-ram/.gitignore new file mode 100644 index 000000000..85bec40d5 --- /dev/null +++ b/plugins/compiler/ramc-ram/.gitignore @@ -0,0 +1 @@ +src/main/java/net/emustudio/plugins/compiler/ramc/LexerImpl.java diff --git a/plugins/compiler/ramc-ram/build.gradle b/plugins/compiler/ramc-ram/build.gradle index fa4ac3351..87a0ec9ff 100644 --- a/plugins/compiler/ramc-ram/build.gradle +++ b/plugins/compiler/ramc-ram/build.gradle @@ -21,7 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'org.xbib.gradle.plugin.jflex' version "1.2.1" + id 'org.xbib.gradle.plugin.jflex' version "1.5.0" id "com.github.andrescv.jcup" version "1.0" } @@ -41,7 +41,7 @@ sourceSets.main.java.srcDirs = [ ] jflex { - generateDir = project.file("${buildDir}/generated-sources/jflex/net/emustudio/plugins/compiler/ramc") + no_backup = true } jcup { diff --git a/plugins/compiler/ramc-ram/src/main/jflex/lexer.jflex b/plugins/compiler/ramc-ram/src/main/jflex/lexer.jflex index f38566db3..cf3c6fc33 100644 --- a/plugins/compiler/ramc-ram/src/main/jflex/lexer.jflex +++ b/plugins/compiler/ramc-ram/src/main/jflex/lexer.jflex @@ -64,14 +64,14 @@ import java.io.IOException; } private TokenImpl token(int id, int category) { - Location left = new Location("", yyline+1,yycolumn+1,yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), yychar+yylength()); + Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); + Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); return new TokenImpl(id, category, zzLexicalState, yytext(), left, right); } private TokenImpl token(int id, int category, Object value) { - Location left = new Location("", yyline+1,yycolumn+1,yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), yychar+yylength()); + Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); + Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); return new TokenImpl(id, category, zzLexicalState, yytext(), left, right, value); } %} diff --git a/plugins/compiler/raspc-rasp/.gitignore b/plugins/compiler/raspc-rasp/.gitignore new file mode 100644 index 000000000..10f745958 --- /dev/null +++ b/plugins/compiler/raspc-rasp/.gitignore @@ -0,0 +1 @@ +src/main/java/net/emustudio/plugins/compiler/raspc/LexerImpl.java diff --git a/plugins/compiler/raspc-rasp/build.gradle b/plugins/compiler/raspc-rasp/build.gradle index 00b1f8827..8809ace16 100644 --- a/plugins/compiler/raspc-rasp/build.gradle +++ b/plugins/compiler/raspc-rasp/build.gradle @@ -21,7 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'org.xbib.gradle.plugin.jflex' version "1.2.1" + id 'org.xbib.gradle.plugin.jflex' version "1.5.0" id "com.github.andrescv.jcup" version "1.0" } @@ -41,7 +41,7 @@ sourceSets.main.java.srcDirs = [ ] jflex { - generateDir = project.file("${buildDir}/generated-sources/jflex/net/emustudio/plugins/compiler/raspc") + no_backup = true } jcup { diff --git a/plugins/compiler/raspc-rasp/src/main/cup/parser.cup b/plugins/compiler/raspc-rasp/src/main/cup/parser.cup index 604a8c234..51c5a07d9 100644 --- a/plugins/compiler/raspc-rasp/src/main/cup/parser.cup +++ b/plugins/compiler/raspc-rasp/src/main/cup/parser.cup @@ -79,7 +79,7 @@ parser code{: } :}; -terminal READ, WRITE, LOAD, STORE, ADD, SUB, MUL, DIV, JMP, JZ, JGTZ, HALT, ORG, SEPARATOR_EOL, TCOMMENT, OPERATOR_CONSTANT, ERROR_UNKNOWN_TOKEN; +terminal READ, WRITE, LOAD, STORE, ADD, SUB, MUL, DIV, JMP, JZ, JGTZ, HALT, ORG, SEPARATOR_EOL, TCOMMENT, OPERATOR_CONSTANT; terminal Integer NUMBER; terminal String TLABEL, IDENT; terminal TINPUT; @@ -93,7 +93,6 @@ non terminal Statement Statement; non terminal InstructionImpl Instruction; non terminal InstructionImpl JumpInstruction; non terminal Input Input; -non terminal Integer MaybeOrg; start with SourceCode; diff --git a/plugins/compiler/raspc-rasp/src/main/jflex/lexer.jflex b/plugins/compiler/raspc-rasp/src/main/jflex/lexer.jflex index aabb7be0f..eb388eca9 100644 --- a/plugins/compiler/raspc-rasp/src/main/jflex/lexer.jflex +++ b/plugins/compiler/raspc-rasp/src/main/jflex/lexer.jflex @@ -64,14 +64,14 @@ import java.io.Reader; } private TokenImpl token(int id, int category) { - Location left = new Location("", yyline+1,yycolumn+1,yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), yychar+yylength()); + Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); + Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); return new TokenImpl(id, category, zzLexicalState, yytext(), left, right); } private TokenImpl token(int id, int category, Object value) { - Location left = new Location("", yyline+1,yycolumn+1,yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), yychar+yylength()); + Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); + Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); return new TokenImpl(id, category, zzLexicalState, yytext(), left, right, value); } %} @@ -172,7 +172,7 @@ operator_constant = "=" /*error occurence*/ [^] { - return token(TokenImpl.ERROR_UNKNOWN_TOKEN, Token.ERROR); + return token(TokenImpl.error, Token.ERROR); } From 3d850948a784757c7aad891e519ce86ef21e9868 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 12 Feb 2021 13:58:07 +0100 Subject: [PATCH 012/314] [#185] Fix configuration & main class --- application/src/main/files/config/MITSAltair8800.toml | 4 ++-- application/src/main/files/config/MITSAltair8800Z80.toml | 4 ++-- plugins/device/88-dcdd/build.gradle | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/application/src/main/files/config/MITSAltair8800.toml b/application/src/main/files/config/MITSAltair8800.toml index 2ab043962..ffc1a9c33 100644 --- a/application/src/main/files/config/MITSAltair8800.toml +++ b/application/src/main/files/config/MITSAltair8800.toml @@ -51,8 +51,8 @@ name = "MITS Altair8800" [[DEVICE]] schemaPoint = "220,60" - path = "88-disk.jar" - name = "88-disk" + path = "88-dcdd.jar" + name = "88-dcdd" id = "ad934179-3690-4bbc-b6ab-f4634346927a" type = "DEVICE" diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index f86bad0b5..7dd921b75 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -46,8 +46,8 @@ name = "MITS Altair8800 (Z80)" # antiAliasing = true [[DEVICE]] schemaPoint = "340,140" - path = "88-disk.jar" - name = "88-disk" + path = "88-dcdd.jar" + name = "88-dcdd" id = "c94d0e9b-f394-4a71-94b0-87d0f970a3fd" type = "DEVICE" diff --git a/plugins/device/88-dcdd/build.gradle b/plugins/device/88-dcdd/build.gradle index fc29996a3..f7e60c2e4 100644 --- a/plugins/device/88-dcdd/build.gradle +++ b/plugins/device/88-dcdd/build.gradle @@ -39,7 +39,7 @@ dependencies { jar { archiveVersion = '' manifest { - attributes manifestAttributes('net.emustudio.plugins.device.mits88disk.Runner') + attributes manifestAttributes('net.emustudio.plugins.device.mits88dcdd.Runner') } } From c1309ea53ac0b26d4f7b768fa11624a6712d3ddb Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 12 Feb 2021 15:26:40 +0100 Subject: [PATCH 013/314] [#184] Rename standard-mem to byte-mem --- application/build.gradle | 4 ++-- .../src/main/files/config/MITSAltair8800.toml | 4 ++-- .../main/files/config/MITSAltair8800Z80.toml | 4 ++-- plugins/device/simhPseudo-z80/build.gradle | 2 +- .../plugins/device/simh/DeviceImpl.java | 4 ++-- .../plugins/device/simh/PseudoContext.java | 6 +++--- plugins/memory/byte-mem/README.md | 5 +++++ .../{standard-mem => byte-mem}/build.gradle | 0 .../memory/bytemem}/MemoryContextImpl.java | 8 ++++---- .../plugins/memory/bytemem}/MemoryImpl.java | 16 ++++++++-------- .../plugins/memory/bytemem}/RangeTree.java | 6 +++--- .../memory/bytemem/api/ByteMemoryContext.java} | 8 ++++---- .../plugins/memory/bytemem}/gui/Constants.java | 2 +- .../memory/bytemem}/gui/FindSequenceDialog.java | 6 +++--- .../memory/bytemem}/gui/KeyboardHandler.java | 6 +++--- .../plugins/memory/bytemem}/gui/MemoryGui.java | 10 +++++----- .../memory/bytemem}/gui/SettingsDialog.java | 14 +++++++------- .../gui/actions/FindSequenceAction.java | 4 ++-- .../bytemem}/gui/model/FileImagesModel.java | 2 +- .../bytemem}/gui/model/MemoryTableModel.java | 4 ++-- .../memory/bytemem}/gui/model/ROMmodel.java | 6 +++--- .../memory/bytemem}/gui/model/TableMemory.java | 4 ++-- .../memory/bytemem}/gui/document-open.png | Bin .../memory/bytemem}/gui/document-save.png | Bin .../plugins/memory/bytemem}/gui/edit-clear.png | Bin .../plugins/memory/bytemem}/gui/edit-find.png | Bin .../plugins/memory/bytemem}/gui/find-text.png | Bin .../memory/bytemem}/gui/format-indent-more.png | Bin .../memory/bytemem}/gui/preferences-system.png | Bin .../plugins/memory/bytemem}/version.properties | 0 .../plugins/memory/bytemem}/MemoryImplTest.java | 2 +- .../plugins/memory/bytemem}/RangeTreeTest.java | 2 +- plugins/memory/standard-mem/README.md | 6 ------ settings.gradle | 2 +- 34 files changed, 68 insertions(+), 69 deletions(-) create mode 100644 plugins/memory/byte-mem/README.md rename plugins/memory/{standard-mem => byte-mem}/build.gradle (100%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/MemoryContextImpl.java (97%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/MemoryImpl.java (94%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/RangeTree.java (92%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard/api/StandardMemoryContext.java => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java} (93%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/gui/Constants.java (80%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/gui/FindSequenceDialog.java (97%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/gui/KeyboardHandler.java (96%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/gui/MemoryGui.java (98%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/gui/SettingsDialog.java (98%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/gui/actions/FindSequenceAction.java (96%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/gui/model/FileImagesModel.java (98%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/gui/model/MemoryTableModel.java (97%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/gui/model/ROMmodel.java (90%) rename plugins/memory/{standard-mem/src/main/java/net/emustudio/plugins/memory/standard => byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem}/gui/model/TableMemory.java (97%) rename plugins/memory/{standard-mem/src/main/resources/net/emustudio/plugins/memory/standard => byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem}/gui/document-open.png (100%) rename plugins/memory/{standard-mem/src/main/resources/net/emustudio/plugins/memory/standard => byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem}/gui/document-save.png (100%) rename plugins/memory/{standard-mem/src/main/resources/net/emustudio/plugins/memory/standard => byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem}/gui/edit-clear.png (100%) rename plugins/memory/{standard-mem/src/main/resources/net/emustudio/plugins/memory/standard => byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem}/gui/edit-find.png (100%) rename plugins/memory/{standard-mem/src/main/resources/net/emustudio/plugins/memory/standard => byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem}/gui/find-text.png (100%) rename plugins/memory/{standard-mem/src/main/resources/net/emustudio/plugins/memory/standard => byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem}/gui/format-indent-more.png (100%) rename plugins/memory/{standard-mem/src/main/resources/net/emustudio/plugins/memory/standard => byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem}/gui/preferences-system.png (100%) rename plugins/memory/{standard-mem/src/main/resources/net/emustudio/plugins/memory/standard => byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem}/version.properties (100%) rename plugins/memory/{standard-mem/src/test/java/net/emustudio/plugins/memory/standard => byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem}/MemoryImplTest.java (96%) rename plugins/memory/{standard-mem/src/test/java/net/emustudio/plugins/memory/standard => byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem}/RangeTreeTest.java (98%) delete mode 100644 plugins/memory/standard-mem/README.md diff --git a/application/build.gradle b/application/build.gradle index cec7fba1c..b6e05cffe 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -59,7 +59,7 @@ dependencies { providedRuntime project(":plugins:memory:rasp-mem") providedRuntime project(":plugins:memory:brainduck-mem") providedRuntime project(":plugins:memory:ssem-mem") - providedRuntime project(":plugins:memory:standard-mem") + providedRuntime project(":plugins:memory:byte-mem") providedRuntime project(":plugins:cpu:8080-cpu") providedRuntime project(":plugins:cpu:brainduck-cpu") @@ -186,7 +186,7 @@ distributions { from(output(":plugins:memory:rasp-mem")) from(output(":plugins:memory:brainduck-mem")) from(output(":plugins:memory:ssem-mem")) - from(output(":plugins:memory:standard-mem")) + from(output(":plugins:memory:byte-mem")) } into('cpu') { diff --git a/application/src/main/files/config/MITSAltair8800.toml b/application/src/main/files/config/MITSAltair8800.toml index ffc1a9c33..9d2b4b86e 100644 --- a/application/src/main/files/config/MITSAltair8800.toml +++ b/application/src/main/files/config/MITSAltair8800.toml @@ -2,8 +2,8 @@ name = "MITS Altair8800" [MEMORY] schemaPoint = "80,180" - path = "standard-mem.jar" - name = "standard-mem" + path = "byte-mem.jar" + name = "byte-mem" id = "fee24374-8d28-4472-85ef-e8ef182f44e3" type = "MEMORY" diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index 7dd921b75..21d218180 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -2,8 +2,8 @@ name = "MITS Altair8800 (Z80)" [MEMORY] schemaPoint = "80,220" - path = "standard-mem.jar" - name = "standard-mem" + path = "byte-mem.jar" + name = "byte-mem" id = "1e13a25d-fb23-4061-853a-5fe996b03281" type = "MEMORY" diff --git a/plugins/device/simhPseudo-z80/build.gradle b/plugins/device/simhPseudo-z80/build.gradle index 8ff9882ef..3f6bdf949 100644 --- a/plugins/device/simhPseudo-z80/build.gradle +++ b/plugins/device/simhPseudo-z80/build.gradle @@ -29,7 +29,7 @@ dependencies { cpuLib project(":plugins:cpu:8080-cpu") cpuLib project(":plugins:cpu:z80-cpu") - memoryLib project(":plugins:memory:standard-mem") + memoryLib project(":plugins:memory:byte-mem") testImplementation libs.junit testImplementation libs.slf4JSimple diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java index 5777b8bc0..d55324f0c 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java @@ -26,7 +26,7 @@ import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; -import net.emustudio.plugins.memory.standard.api.StandardMemoryContext; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import javax.swing.*; import java.util.MissingResourceException; @@ -53,7 +53,7 @@ public void initialize() throws PluginInitializationException { ContextPool contextPool = applicationApi.getContextPool(); ExtendedContext cpu = contextPool.getCPUContext(pluginID, ExtendedContext.class); - StandardMemoryContext mem = contextPool.getMemoryContext(pluginID, StandardMemoryContext.class); + ByteMemoryContext mem = contextPool.getMemoryContext(pluginID, ByteMemoryContext.class); context.setMemory(mem); diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java index 3402a7dc1..4174e77c6 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java @@ -19,7 +19,7 @@ package net.emustudio.plugins.device.simh; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.memory.standard.api.StandardMemoryContext; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,7 +29,7 @@ class PseudoContext implements DeviceContext { private final static Logger LOGGER = LoggerFactory.getLogger(PseudoContext.class); - private StandardMemoryContext mem; + private ByteMemoryContext mem; /* SIMH pseudo device status registers */ /* ZSDOS clock definitions */ @@ -90,7 +90,7 @@ class PseudoContext implements DeviceContext { private final static int SECONDS_PER_HOUR = (60 * SECONDS_PER_MINUTE); private final static int SECONDS_PER_DAY = (24 * SECONDS_PER_HOUR); - void setMemory(StandardMemoryContext mem) { + void setMemory(ByteMemoryContext mem) { this.mem = mem; } diff --git a/plugins/memory/byte-mem/README.md b/plugins/memory/byte-mem/README.md new file mode 100644 index 000000000..029f7a4de --- /dev/null +++ b/plugins/memory/byte-mem/README.md @@ -0,0 +1,5 @@ +# byte-mem + +This project is emulator of "byte" operating memory for various machines (memory operating on byte cells). It is part of [emuStudio](https://www.emustudio.net/). + +The official documentation can be found [here](https://www.emustudio.net/docuser/mits_altair_8800/index/#operating-memory-code-standard-mem-code) diff --git a/plugins/memory/standard-mem/build.gradle b/plugins/memory/byte-mem/build.gradle similarity index 100% rename from plugins/memory/standard-mem/build.gradle rename to plugins/memory/byte-mem/build.gradle diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/MemoryContextImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java similarity index 97% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/MemoryContextImpl.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java index a4f7fc8d9..a47dfe744 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/MemoryContextImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java @@ -16,13 +16,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard; +package net.emustudio.plugins.memory.bytemem; import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.memory.AbstractMemoryContext; import net.emustudio.emulib.runtime.helpers.IntelHEX; import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.plugins.memory.standard.api.StandardMemoryContext; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import java.io.EOFException; import java.io.FileNotFoundException; @@ -32,8 +32,8 @@ import java.util.List; import java.util.Objects; -@PluginContext(id = "Standard Memory") -public class MemoryContextImpl extends AbstractMemoryContext implements StandardMemoryContext { +@PluginContext(id = "Byte Memory") +public class MemoryContextImpl extends AbstractMemoryContext implements ByteMemoryContext { final static int DEFAULT_MEM_SIZE = 65536; private final RangeTree romRanges = new RangeTree(); diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/MemoryImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java similarity index 94% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/MemoryImpl.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java index 6170bfa49..298469a9e 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/MemoryImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard; +package net.emustudio.plugins.memory.bytemem; import net.emustudio.emulib.plugins.PluginInitializationException; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; @@ -24,8 +24,8 @@ import net.emustudio.emulib.plugins.memory.AbstractMemory; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.*; -import net.emustudio.plugins.memory.standard.api.StandardMemoryContext; -import net.emustudio.plugins.memory.standard.gui.MemoryGui; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; +import net.emustudio.plugins.memory.bytemem.gui.MemoryGui; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +38,7 @@ @PluginRoot( type = PLUGIN_TYPE.MEMORY, - title = "Standard operating memory" + title = "Byte-cell based operating memory" ) @SuppressWarnings("unused") public class MemoryImpl extends AbstractMemory { @@ -55,7 +55,7 @@ public MemoryImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s this.context = new MemoryContextImpl(applicationApi.getDialogs()); try { ContextPool contextPool = applicationApi.getContextPool(); - contextPool.register(pluginID, context, StandardMemoryContext.class); + contextPool.register(pluginID, context, ByteMemoryContext.class); contextPool.register(pluginID, context, MemoryContext.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register memory context", e); @@ -77,7 +77,7 @@ public String getCopyright() { @Override public String getDescription() { - return "Operating memory suitable for most of CPUs"; + return "Operating memory suitable for most of modern CPUs. One memory cell is a byte."; } @Override @@ -199,7 +199,7 @@ public void saveROMRanges() throws CannotUpdateSettingException { } int i = 0; - for (StandardMemoryContext.AddressRange range : context.getReadOnly()) { + for (ByteMemoryContext.AddressRange range : context.getReadOnly()) { settings.setInt("ROMfrom" + i, range.getStartAddress()); settings.setInt("ROMto" + i, range.getStopAddress()); i++; @@ -229,7 +229,7 @@ public boolean isShowSettingsSupported() { private Optional getResourceBundle() { try { - return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.memory.standard.version")); + return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.memory.bytemem.version")); } catch (MissingResourceException e) { return Optional.empty(); } diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/RangeTree.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/RangeTree.java similarity index 92% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/RangeTree.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/RangeTree.java index 4cf113e07..43c7f78a0 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/RangeTree.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/RangeTree.java @@ -16,9 +16,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard; +package net.emustudio.plugins.memory.bytemem; -import net.emustudio.plugins.memory.standard.api.StandardMemoryContext; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import java.util.ArrayList; import java.util.List; @@ -69,7 +69,7 @@ public boolean isIn(int value) { return values.contains(value); } - public final static class Range implements StandardMemoryContext.AddressRange { + public final static class Range implements ByteMemoryContext.AddressRange { public final int from; public final int to; diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/api/StandardMemoryContext.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java similarity index 93% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/api/StandardMemoryContext.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java index c5b436c9e..3d5e76947 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/api/StandardMemoryContext.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard.api; +package net.emustudio.plugins.memory.bytemem.api; import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.memory.MemoryContext; @@ -24,12 +24,12 @@ import java.util.List; /** - * Extended memory context. + * "Byte" memory context. *

* Supports bank switching, ROM ranges, and loading HEX/BIN files. */ -@PluginContext(id = "Standard memory") -public interface StandardMemoryContext extends MemoryContext { +@PluginContext(id = "Byte memory") +public interface ByteMemoryContext extends MemoryContext { /** * This interface represents a range of addresses in the memory. diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/Constants.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java similarity index 80% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/Constants.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java index 3a5b1e7e0..3589d03b6 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/Constants.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.memory.standard.gui; +package net.emustudio.plugins.memory.bytemem.gui; import java.awt.*; diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/FindSequenceDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java similarity index 97% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/FindSequenceDialog.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java index 3124c7019..3fdf21994 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/FindSequenceDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java @@ -16,11 +16,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard.gui; +package net.emustudio.plugins.memory.bytemem.gui; import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.plugins.memory.standard.gui.actions.FindSequenceAction; -import net.emustudio.plugins.memory.standard.gui.model.MemoryTableModel; +import net.emustudio.plugins.memory.bytemem.gui.actions.FindSequenceAction; +import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; import javax.swing.*; import java.awt.event.KeyEvent; diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/KeyboardHandler.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/KeyboardHandler.java similarity index 96% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/KeyboardHandler.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/KeyboardHandler.java index 8ff44bd8a..206c59c3a 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/KeyboardHandler.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/KeyboardHandler.java @@ -16,10 +16,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard.gui; +package net.emustudio.plugins.memory.bytemem.gui; -import net.emustudio.plugins.memory.standard.gui.model.MemoryTableModel; -import net.emustudio.plugins.memory.standard.gui.model.TableMemory; +import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; +import net.emustudio.plugins.memory.bytemem.gui.model.TableMemory; import javax.swing.*; import java.awt.event.KeyAdapter; diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/MemoryGui.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java similarity index 98% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/MemoryGui.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java index ac8806a70..08a77d945 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/MemoryGui.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java @@ -16,15 +16,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard.gui; +package net.emustudio.plugins.memory.bytemem.gui; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; -import net.emustudio.plugins.memory.standard.gui.model.MemoryTableModel; -import net.emustudio.plugins.memory.standard.gui.model.TableMemory; -import net.emustudio.plugins.memory.standard.MemoryContextImpl; -import net.emustudio.plugins.memory.standard.MemoryImpl; +import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; +import net.emustudio.plugins.memory.bytemem.gui.model.TableMemory; +import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; +import net.emustudio.plugins.memory.bytemem.MemoryImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/SettingsDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java similarity index 98% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/SettingsDialog.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java index 0fca20f63..15daeb94e 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/SettingsDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java @@ -16,19 +16,19 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard.gui; +package net.emustudio.plugins.memory.bytemem.gui; import net.emustudio.emulib.runtime.CannotUpdateSettingException; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; -import net.emustudio.plugins.memory.standard.MemoryContextImpl; -import net.emustudio.plugins.memory.standard.MemoryImpl; -import net.emustudio.plugins.memory.standard.RangeTree; -import net.emustudio.plugins.memory.standard.gui.model.FileImagesModel; -import net.emustudio.plugins.memory.standard.gui.model.ROMmodel; -import net.emustudio.plugins.memory.standard.gui.model.TableMemory; +import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; +import net.emustudio.plugins.memory.bytemem.MemoryImpl; +import net.emustudio.plugins.memory.bytemem.RangeTree; +import net.emustudio.plugins.memory.bytemem.gui.model.FileImagesModel; +import net.emustudio.plugins.memory.bytemem.gui.model.ROMmodel; +import net.emustudio.plugins.memory.bytemem.gui.model.TableMemory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/actions/FindSequenceAction.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/FindSequenceAction.java similarity index 96% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/actions/FindSequenceAction.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/FindSequenceAction.java index acc172410..3fd1445f9 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/actions/FindSequenceAction.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/FindSequenceAction.java @@ -1,8 +1,8 @@ -package net.emustudio.plugins.memory.standard.gui.actions; +package net.emustudio.plugins.memory.bytemem.gui.actions; import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.plugins.memory.standard.gui.model.MemoryTableModel; +import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/FileImagesModel.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/FileImagesModel.java similarity index 98% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/FileImagesModel.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/FileImagesModel.java index e60584e95..17c238ce5 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/FileImagesModel.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/FileImagesModel.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard.gui.model; +package net.emustudio.plugins.memory.bytemem.gui.model; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/MemoryTableModel.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java similarity index 97% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/MemoryTableModel.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java index bd462a562..7fc28fe80 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/MemoryTableModel.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java @@ -16,9 +16,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard.gui.model; +package net.emustudio.plugins.memory.bytemem.gui.model; -import net.emustudio.plugins.memory.standard.MemoryContextImpl; +import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; import javax.swing.table.AbstractTableModel; import java.util.Objects; diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/ROMmodel.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/ROMmodel.java similarity index 90% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/ROMmodel.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/ROMmodel.java index 5512cc71d..7e5fbf03a 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/ROMmodel.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/ROMmodel.java @@ -16,10 +16,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard.gui.model; +package net.emustudio.plugins.memory.bytemem.gui.model; -import net.emustudio.plugins.memory.standard.api.StandardMemoryContext.AddressRange; -import net.emustudio.plugins.memory.standard.MemoryContextImpl; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext.AddressRange; +import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; import javax.swing.table.AbstractTableModel; import java.util.Objects; diff --git a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/TableMemory.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/TableMemory.java similarity index 97% rename from plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/TableMemory.java rename to plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/TableMemory.java index 5d6280c95..95e749413 100644 --- a/plugins/memory/standard-mem/src/main/java/net/emustudio/plugins/memory/standard/gui/model/TableMemory.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/TableMemory.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard.gui.model; +package net.emustudio.plugins.memory.bytemem.gui.model; import net.emustudio.emulib.runtime.helpers.RadixUtils; @@ -28,7 +28,7 @@ import java.awt.*; import java.util.Objects; -import static net.emustudio.plugins.memory.standard.gui.Constants.MONOSPACED_PLAIN; +import static net.emustudio.plugins.memory.bytemem.gui.Constants.MONOSPACED_PLAIN; public class TableMemory extends JTable { private final MemoryTableModel tableModel; diff --git a/plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/document-open.png b/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/document-open.png similarity index 100% rename from plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/document-open.png rename to plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/document-open.png diff --git a/plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/document-save.png b/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/document-save.png similarity index 100% rename from plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/document-save.png rename to plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/document-save.png diff --git a/plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/edit-clear.png b/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/edit-clear.png similarity index 100% rename from plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/edit-clear.png rename to plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/edit-clear.png diff --git a/plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/edit-find.png b/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/edit-find.png similarity index 100% rename from plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/edit-find.png rename to plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/edit-find.png diff --git a/plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/find-text.png b/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/find-text.png similarity index 100% rename from plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/find-text.png rename to plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/find-text.png diff --git a/plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/format-indent-more.png b/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/format-indent-more.png similarity index 100% rename from plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/format-indent-more.png rename to plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/format-indent-more.png diff --git a/plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/preferences-system.png b/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/preferences-system.png similarity index 100% rename from plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/gui/preferences-system.png rename to plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/gui/preferences-system.png diff --git a/plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/version.properties b/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/version.properties similarity index 100% rename from plugins/memory/standard-mem/src/main/resources/net/emustudio/plugins/memory/standard/version.properties rename to plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/version.properties diff --git a/plugins/memory/standard-mem/src/test/java/net/emustudio/plugins/memory/standard/MemoryImplTest.java b/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/MemoryImplTest.java similarity index 96% rename from plugins/memory/standard-mem/src/test/java/net/emustudio/plugins/memory/standard/MemoryImplTest.java rename to plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/MemoryImplTest.java index a4506870f..4168e5e83 100644 --- a/plugins/memory/standard-mem/src/test/java/net/emustudio/plugins/memory/standard/MemoryImplTest.java +++ b/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/MemoryImplTest.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.memory.standard; +package net.emustudio.plugins.memory.bytemem; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; diff --git a/plugins/memory/standard-mem/src/test/java/net/emustudio/plugins/memory/standard/RangeTreeTest.java b/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/RangeTreeTest.java similarity index 98% rename from plugins/memory/standard-mem/src/test/java/net/emustudio/plugins/memory/standard/RangeTreeTest.java rename to plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/RangeTreeTest.java index 6aecba8dd..dad831101 100644 --- a/plugins/memory/standard-mem/src/test/java/net/emustudio/plugins/memory/standard/RangeTreeTest.java +++ b/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/RangeTreeTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.memory.standard; +package net.emustudio.plugins.memory.bytemem; import org.junit.Test; diff --git a/plugins/memory/standard-mem/README.md b/plugins/memory/standard-mem/README.md deleted file mode 100644 index 785517df5..000000000 --- a/plugins/memory/standard-mem/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# standard-mem - -This project is emulator of "standard" operating memory for various machines. -It is part of [emuStudio](https://www.emustudio.net/). - -The official documentation can be found [here](https://www.emustudio.net/docuser/mits_altair_8800/index/#operating-memory-code-standard-mem-code) diff --git a/settings.gradle b/settings.gradle index b75030374..17a699ac6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -47,4 +47,4 @@ include ':plugins:memory:brainduck-mem' include ':plugins:memory:ram-mem' include ':plugins:memory:rasp-mem' include ':plugins:memory:ssem-mem' -include ':plugins:memory:standard-mem' +include ':plugins:memory:byte-mem' From b928514a41ed41d53c26ae86425a2a9ceaff70fb Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 12 Feb 2021 15:31:20 +0100 Subject: [PATCH 014/314] [#184] Fix icon --- .../plugins/memory/bytemem/gui/MemoryGui.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java index 08a77d945..df0a8340d 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java @@ -166,13 +166,13 @@ private void initComponents() { setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); - setTitle("Standard Operating Memory"); + setTitle("Byte Operating Memory"); setSize(new java.awt.Dimension(794, 629)); jToolBar1.setFloatable(false); jToolBar1.setRollover(true); - btnLoadImage.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/standard/gui/document-open.png"))); + btnLoadImage.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/document-open.png"))); btnLoadImage.setToolTipText("Load image..."); btnLoadImage.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); btnLoadImage.setFocusable(false); @@ -181,7 +181,7 @@ private void initComponents() { btnLoadImage.addActionListener(this::btnLoadImageActionPerformed); jToolBar1.add(btnLoadImage); - btnDump.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/standard/gui/document-save.png"))); + btnDump.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/document-save.png"))); btnDump.setToolTipText("Dump (save) memory..."); btnDump.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); btnDump.setFocusable(false); @@ -191,7 +191,7 @@ private void initComponents() { jToolBar1.add(btnDump); jToolBar1.addSeparator(); - btnGotoAddress.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/standard/gui/format-indent-more.png"))); + btnGotoAddress.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/format-indent-more.png"))); btnGotoAddress.setToolTipText("Go to address..."); btnGotoAddress.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); btnGotoAddress.setFocusable(false); @@ -200,7 +200,7 @@ private void initComponents() { btnGotoAddress.addActionListener(this::btnGotoAddressActionPerformed); jToolBar1.add(btnGotoAddress); - btnFind.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/standard/gui/edit-find.png"))); + btnFind.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/edit-find.png"))); btnFind.setToolTipText("Find sequence..."); btnFind.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); btnFind.setFocusable(false); @@ -210,7 +210,7 @@ private void initComponents() { jToolBar1.add(btnFind); jToolBar1.addSeparator(); - btnClean.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/standard/gui/edit-clear.png"))); + btnClean.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/edit-clear.png"))); btnClean.setToolTipText("Erase memory"); btnClean.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); btnClean.setFocusable(false); @@ -220,7 +220,7 @@ private void initComponents() { jToolBar1.add(btnClean); jToolBar1.addSeparator(); - btnSettings.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/standard/gui/preferences-system.png"))); + btnSettings.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/preferences-system.png"))); btnSettings.setToolTipText("Settings..."); btnSettings.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); btnSettings.setFocusable(false); From d289ee5293458f861929531994d89f4d4877080c Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 27 Feb 2021 10:31:30 +0100 Subject: [PATCH 015/314] [#182] Set dirty=false to textPane --- .../main/java/net/emustudio/application/gui/editor/REditor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/application/src/main/java/net/emustudio/application/gui/editor/REditor.java b/application/src/main/java/net/emustudio/application/gui/editor/REditor.java index 0008dac82..a6b220769 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/REditor.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/REditor.java @@ -107,6 +107,7 @@ public void keyTyped(KeyEvent e) { } else { sourceFileExtensions = Collections.emptyList(); } + textPane.setDirty(false); } @Override From d436ec7ab4971bcdaba783f3099e8fa2f1a03a8a Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 27 Feb 2021 10:41:33 +0100 Subject: [PATCH 016/314] [#180] Reset SSEM display on GUI init --- .../net/emustudio/plugins/device/ssem/display/DisplayGui.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java index c06555d7f..59671dc20 100644 --- a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java +++ b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java @@ -38,6 +38,7 @@ class DisplayGui extends JDialog { setLocationRelativeTo(parent); scrollPane.setViewportView(displayPanel); + displayPanel.reset(memory); initListener(); } @@ -49,7 +50,7 @@ public void memoryChanged(int bytePosition) { displayPanel.reset(memory); } else { int row = bytePosition / 4; - displayPanel.writeRow(memory.readWord(row * 4), row); + displayPanel.writeRow(memory.readWord(bytePosition), row); } } From c8fc09c27e03e78df482ece93fff7cbb687fd8b1 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 3 Mar 2021 18:26:05 +0100 Subject: [PATCH 017/314] [#195] Fix glitches on windows --- application/build.gradle | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/application/build.gradle b/application/build.gradle index b6e05cffe..deaf64314 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -86,7 +86,10 @@ dependencies { application { applicationName = 'emuStudio' mainClassName = 'net.emustudio.application.Runner' - applicationDefaultJvmArgs = ['-Dawt.useSystemAAFontSettings=on', '-Dswing.aatext=true', '-Dsun.java2d.xrender=true'] + applicationDefaultJvmArgs = [ + '-Dawt.useSystemAAFontSettings=on', '-Dswing.aatext=true', '-Dsun.java2d.xrender=true', '-Dsun.java2d.d3d=false', + '-Dsun.java2d.noddraw=true' + ] executableDir = '' } From 1231ae772903d3bc374c05c05f9f5c96a7d6ef56 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 1 Apr 2021 08:19:22 +0200 Subject: [PATCH 018/314] [#197] 8080-compiler: Fix RST instruction size --- .../plugins/compiler/as8080/tree/OC_Expr.java | 64 ++++++++++--------- .../plugins/compiler/as8080/OC_ExprTest.java | 20 ++++++ 2 files changed, 54 insertions(+), 30 deletions(-) create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_ExprTest.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java index 1c620d684..14cf61bc7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java @@ -25,41 +25,48 @@ import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; public class OC_Expr extends OpCodeNode { - private final static Set INSTRUCTION_WITH_SIZE_3 = new HashSet<>(); private final static Map OPCODES_BASE_198 = new HashMap<>(); private final static Map OPCODES_BASE_34 = new HashMap<>(); private final static Map OPCODES_BASE_194 = new HashMap<>(); private final static Map OPCODES_BASE_196 = new HashMap<>(); + private final static Map INSTRUCTION_SIZE = new HashMap<>(); + static { - INSTRUCTION_WITH_SIZE_3.add("sta"); - INSTRUCTION_WITH_SIZE_3.add("lda"); - INSTRUCTION_WITH_SIZE_3.add("shld"); - INSTRUCTION_WITH_SIZE_3.add("lhld"); - INSTRUCTION_WITH_SIZE_3.add("jmp"); - INSTRUCTION_WITH_SIZE_3.add("jc"); - INSTRUCTION_WITH_SIZE_3.add("jnc"); - INSTRUCTION_WITH_SIZE_3.add("jz"); - INSTRUCTION_WITH_SIZE_3.add("jnz"); - INSTRUCTION_WITH_SIZE_3.add("jm"); - INSTRUCTION_WITH_SIZE_3.add("jp"); - INSTRUCTION_WITH_SIZE_3.add("jpe"); - INSTRUCTION_WITH_SIZE_3.add("jpo"); - INSTRUCTION_WITH_SIZE_3.add("call"); - INSTRUCTION_WITH_SIZE_3.add("cc"); - INSTRUCTION_WITH_SIZE_3.add("cnc"); - INSTRUCTION_WITH_SIZE_3.add("cz"); - INSTRUCTION_WITH_SIZE_3.add("cnz"); - INSTRUCTION_WITH_SIZE_3.add("cm"); - INSTRUCTION_WITH_SIZE_3.add("cp"); - INSTRUCTION_WITH_SIZE_3.add("cpe"); - INSTRUCTION_WITH_SIZE_3.add("cpo"); - INSTRUCTION_WITH_SIZE_3.add("rst"); + INSTRUCTION_SIZE.put("sta", 3); + INSTRUCTION_SIZE.put("lda", 3); + INSTRUCTION_SIZE.put("shld", 3); + INSTRUCTION_SIZE.put("lhld", 3); + INSTRUCTION_SIZE.put("jmp", 3); + INSTRUCTION_SIZE.put("jc", 3); + INSTRUCTION_SIZE.put("jnc", 3); + INSTRUCTION_SIZE.put("jz", 3); + INSTRUCTION_SIZE.put("jnz", 3); + INSTRUCTION_SIZE.put("jm", 3); + INSTRUCTION_SIZE.put("jp", 3); + INSTRUCTION_SIZE.put("jpe", 3); + INSTRUCTION_SIZE.put("jpo", 3); + INSTRUCTION_SIZE.put("call", 3); + INSTRUCTION_SIZE.put("cc", 3); + INSTRUCTION_SIZE.put("cnc", 3); + INSTRUCTION_SIZE.put("cz", 3); + INSTRUCTION_SIZE.put("cnz", 3); + INSTRUCTION_SIZE.put("cm", 3); + INSTRUCTION_SIZE.put("cp", 3); + INSTRUCTION_SIZE.put("cpe", 3); + INSTRUCTION_SIZE.put("cpo", 3); + INSTRUCTION_SIZE.put("rst", 1); + INSTRUCTION_SIZE.put("adi", 2); + INSTRUCTION_SIZE.put("aci", 2); + INSTRUCTION_SIZE.put("sui", 2); + INSTRUCTION_SIZE.put("sbi", 2); + INSTRUCTION_SIZE.put("ani", 2); + INSTRUCTION_SIZE.put("xri", 2); + INSTRUCTION_SIZE.put("ori", 2); + INSTRUCTION_SIZE.put("cpi", 2); OPCODES_BASE_198.put("adi", 0); OPCODES_BASE_198.put("aci", 8); @@ -106,10 +113,7 @@ public OC_Expr(String mnemo, ExprNode expr, int line, int column) { @Override public int getSize() { - if (INSTRUCTION_WITH_SIZE_3.contains(mnemo)) { - return 3; - } - return 2; + return INSTRUCTION_SIZE.get(mnemo); } @Override diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_ExprTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_ExprTest.java new file mode 100644 index 000000000..a23fea8c1 --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_ExprTest.java @@ -0,0 +1,20 @@ +package net.emustudio.plugins.compiler.as8080; + +import org.junit.Test; + +public class OC_ExprTest extends AbstractCompilerTest { + + @Test + public void testRST() throws Exception { + compile( + "JMP EXAMPLE\n" + + "RST 00H\n" + + "EXAMPLE:\n" + + "MVI A,01H" + ); + + assertProgram( + 0xC3, 0x04, 0x00, 0xC7, 0x3E, 0x01 + ); + } +} From 6db2aee993d0fbfee3d151da23237dca37ba18af Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 1 Apr 2021 08:24:19 +0200 Subject: [PATCH 019/314] [#197] Add missing in,out instructions to map --- .../net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java index 14cf61bc7..4071a2375 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java @@ -67,6 +67,8 @@ public class OC_Expr extends OpCodeNode { INSTRUCTION_SIZE.put("xri", 2); INSTRUCTION_SIZE.put("ori", 2); INSTRUCTION_SIZE.put("cpi", 2); + INSTRUCTION_SIZE.put("in", 2); + INSTRUCTION_SIZE.put("out", 2); OPCODES_BASE_198.put("adi", 0); OPCODES_BASE_198.put("aci", 8); @@ -113,6 +115,7 @@ public OC_Expr(String mnemo, ExprNode expr, int line, int column) { @Override public int getSize() { + System.out.println("Getting size: " + mnemo); return INSTRUCTION_SIZE.get(mnemo); } From 0722162dce13e7c2fc72d180f4ce1a4256ed9beb Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 1 Apr 2021 08:26:22 +0200 Subject: [PATCH 020/314] [#197] Removed println --- .../java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java index 4071a2375..a5ba1e743 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java @@ -115,7 +115,6 @@ public OC_Expr(String mnemo, ExprNode expr, int line, int column) { @Override public int getSize() { - System.out.println("Getting size: " + mnemo); return INSTRUCTION_SIZE.get(mnemo); } From 88376d4d8886b1044eb49eb1523858048b609fd8 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 1 Apr 2021 12:57:21 +0200 Subject: [PATCH 021/314] [#197] Add test for Z80 --- .../plugins/compiler/asZ80/OC_ExprTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_ExprTest.java diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_ExprTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_ExprTest.java new file mode 100644 index 000000000..7a8cad776 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_ExprTest.java @@ -0,0 +1,20 @@ +package net.emustudio.plugins.compiler.asZ80; + +import org.junit.Test; + +public class OC_ExprTest extends AbstractCompilerTest { + + @Test + public void testRST() throws Exception { + compile( + "JP EXAMPLE\n" + + "RST 0\n" + + "EXAMPLE:\n" + + "LD A, 1\n" + ); + + assertProgram( + 0xC3, 0x04, 0x00, 0xC7, 0x3E, 0x01 + ); + } +} From b88efe7509893c1bb1a28865b661f1785767a3b0 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 1 Apr 2021 13:32:14 +0200 Subject: [PATCH 022/314] [#194] Allow EQU, SET forward referrences --- .../plugins/compiler/as8080/CompilerImpl.java | 2 +- .../plugins/compiler/as8080/Namespace.java | 4 ++++ .../as8080/tree/AddressValueNode.java | 5 ++++ .../compiler/as8080/tree/ArithNode.java | 14 ++++++++--- .../compiler/as8080/tree/DBDataNode.java | 9 ++++++++ .../compiler/as8080/tree/DSDataNode.java | 9 +++++++- .../compiler/as8080/tree/DWDataNode.java | 9 +++++++- .../compiler/as8080/tree/DataNode.java | 7 ++++++ .../as8080/tree/DecimalValueNode.java | 5 ++++ .../compiler/as8080/tree/EquPseudoNode.java | 4 ++-- .../plugins/compiler/as8080/tree/IdExpr.java | 11 +++++++-- .../compiler/as8080/tree/IfPseudoNode.java | 9 ++++++++ .../as8080/tree/IncludePseudoNode.java | 11 +++++++++ .../compiler/as8080/tree/InstructionNode.java | 8 +++++++ .../compiler/as8080/tree/LabelNode.java | 16 ++++++++++--- .../compiler/as8080/tree/MacroCallPseudo.java | 10 ++++++++ .../compiler/as8080/tree/MacroPseudoNode.java | 11 +++++++++ .../plugins/compiler/as8080/tree/OC_Expr.java | 7 ++++++ .../compiler/as8080/tree/OC_NoParams.java | 5 ++++ .../plugins/compiler/as8080/tree/OC_Reg.java | 7 ++++++ .../compiler/as8080/tree/OC_RegExpr.java | 8 +++++++ .../compiler/as8080/tree/OC_RegReg.java | 8 +++++++ .../compiler/as8080/tree/OC_Regpair.java | 7 ++++++ .../compiler/as8080/tree/OC_RegpairExpr.java | 8 +++++++ .../compiler/as8080/tree/OrgPseudoNode.java | 7 ++++++ .../compiler/as8080/tree/SetPseudoNode.java | 8 +++++++ .../as8080/treeAbstract/ExprNode.java | 7 ++++++ .../as8080/ConstantsAndVariablesTest.java | 23 +++++++++++++++++-- 28 files changed, 224 insertions(+), 15 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java index aca7c3f1c..60d20ffc1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java @@ -175,7 +175,7 @@ private IntelHEX compileToHex(String inputFileName) throws Exception { // don't worry about deadlock } if (env.getPassNeedCount() != 0) { - throw new Exception("Error: could not evaulate all expressions"); + throw new Exception("Could not evaluate: " + env.getPassNeedView()); } stat.pass4(hex, env); return hex; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Namespace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Namespace.java index ece1b1604..e2ba31970 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Namespace.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Namespace.java @@ -121,6 +121,10 @@ public InstructionNode getPassNeed(int index) { return passNeed.get(index); } + public List getPassNeedView() { + return Collections.unmodifiableList(passNeed); + } + public void removePassNeed(int index) { passNeed.remove(index); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/AddressValueNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/AddressValueNode.java index dfcfb6866..15f8b5d61 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/AddressValueNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/AddressValueNode.java @@ -28,4 +28,9 @@ public int eval(Namespace env, int curr_addr) { this.value = curr_addr; return curr_addr; } + + @Override + public String toString() { + return "AddressValueNode{value="+ value +"}"; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/ArithNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/ArithNode.java index 5fd341d6a..2760f4e08 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/ArithNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/ArithNode.java @@ -22,9 +22,9 @@ import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; public class ArithNode extends ExprNode { - private ExprNode left; - private ExprNode right; - private String operator; + private final ExprNode left; + private final ExprNode right; + private final String operator; public ArithNode(ExprNode left, ExprNode right, String operator) { this.left = left; @@ -83,4 +83,12 @@ public int eval(Namespace env, int curr_addr) throws Exception { return this.value; } + @Override + public String toString() { + return "ArithNode{" + + "left=" + left + + ", right=" + right + + ", operator='" + operator + '\'' + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java index 3d6ef80eb..0163a524c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java @@ -88,4 +88,13 @@ public void pass4(IntelHEX hex) throws Exception { opcode.pass4(hex); } } + + @Override + public String toString() { + return "DBDataNode{" + + "expression=" + expression + + ", literalString='" + literalString + '\'' + + ", opcode=" + opcode + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java index f652f7b78..d9e0bedba 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java @@ -29,7 +29,7 @@ public class DSDataNode extends DataValueNode { - private ExprNode expression; + private final ExprNode expression; public DSDataNode(ExprNode expr, int line, int column) { super(line, column); @@ -64,4 +64,11 @@ public void pass4(IntelHEX hex) throws Exception { str.append("00".repeat(Math.max(0, expression.getValue()))); hex.putCode(str.toString()); } + + @Override + public String toString() { + return "DSDataNode{" + + "expression=" + expression + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java index 528768c76..428259064 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java @@ -25,7 +25,7 @@ import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; public class DWDataNode extends DataValueNode { - private ExprNode expression; + private final ExprNode expression; public DWDataNode(ExprNode expr, int line, int column) { super(line, column); @@ -54,4 +54,11 @@ public void pass4(IntelHEX hex) throws Exception { hex.putCode(expression.getEncValue(false)); } + + @Override + public String toString() { + return "DWDataNode{" + + "expression=" + expression + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java index 3bb1195be..3e5e14fd9 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java @@ -60,4 +60,11 @@ public void pass4(IntelHEX hex) throws Exception { dataValue.pass4(hex); } } + + @Override + public String toString() { + return "DataNode{" + + "dataValues=" + dataValues + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DecimalValueNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DecimalValueNode.java index 95dfdf1df..1962b91e5 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DecimalValueNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DecimalValueNode.java @@ -38,4 +38,9 @@ public int getSize() { public int eval(Namespace env, int curr_addr) throws Exception { return value; } + + @Override + public String toString() { + return "DecimalValueNode{value="+ value +"}"; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java index 790ae7302..e57ff2f9f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java @@ -25,8 +25,8 @@ import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoNode; public class EquPseudoNode extends PseudoNode { - private ExprNode expr; - private String mnemo; + private final ExprNode expr; + private final String mnemo; public EquPseudoNode(String id, ExprNode expr, int line, int column) { super(line, column); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java index 9132ab6f8..5f6e19b47 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java @@ -24,7 +24,7 @@ import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; public class IdExpr extends ExprNode { - private String name; + private final String name; public IdExpr(String name) { this.name = name; @@ -56,7 +56,14 @@ public int eval(Namespace env, int curr_addr) throws Exception { this.value = set.getValue(); return this.value; } else { - throw new UnknownIdentifierException(this.name); + throw new NeedMorePassException(0,0); } } + + @Override + public String toString() { + return "IdExpr{" + + "name='" + name + '\'' + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java index 9b85c1172..e7f61e385 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java @@ -79,4 +79,13 @@ public void pass4(IntelHEX hex) throws Exception { stat.pass4(hex); } } + + @Override + public String toString() { + return "IfPseudoNode{" + + "expr=" + expr + + ", stat=" + stat + + ", condTrue=" + condTrue + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java index f5877b66a..420d053a9 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java @@ -112,6 +112,7 @@ public int pass2(Namespace parentEnv, int addr_start) throws Exception { @Override public void pass4(IntelHEX hex) throws Exception { while (program.pass3(namespace)) { + // ignore } if (namespace.getPassNeedCount() != 0) { throw new Exception("Error: can't evaluate all expressions"); @@ -123,4 +124,14 @@ public void pass4(IntelHEX hex) throws Exception { public String getName() { return fileName; } + + @Override + public String toString() { + return "IncludePseudoNode{" + + "fileName='" + fileName + '\'' + + ", compiler=" + compiler + + ", program=" + program + + ", namespace=" + namespace + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java index 3fcf2608d..6379f1eeb 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java @@ -102,4 +102,12 @@ boolean getIncludeLoops(String filename) { return false; } + @Override + public String toString() { + return "InstructionNode{" + + "label=" + label + + ", codePseudo=" + codePseudo + + ", current_address=" + current_address + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/LabelNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/LabelNode.java index ce3519a26..9904a87dc 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/LabelNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/LabelNode.java @@ -19,10 +19,10 @@ package net.emustudio.plugins.compiler.as8080.tree; public class LabelNode { - private String name; + private final String name; private Integer address; - private int line; - private int column; + private final int line; + private final int column; public LabelNode(String name, int line, int column) { this.name = name; @@ -51,4 +51,14 @@ public int getColumn() { public String getName() { return name; } + + @Override + public String toString() { + return "LabelNode{" + + "name='" + name + '\'' + + ", address=" + address + + ", line=" + line + + ", column=" + column + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java index b260a2839..145fd80c8 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java @@ -82,4 +82,14 @@ public String getName() { public void pass4(IntelHEX hex) { hex.addTable(statHex.getTable()); } + + @Override + public String toString() { + return "MacroCallPseudo{" + + "params=" + params + + ", macro=" + macro + + ", statHex=" + statHex + + ", mnemo='" + mnemo + '\'' + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java index a76a2386b..6c40abe24 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java @@ -99,4 +99,15 @@ private void createNewEnvForMacro(Namespace env) { public void pass4(IntelHEX hex) throws Exception { stat.pass4(hex, newEnv); } + + @Override + public String toString() { + return "MacroPseudoNode{" + + "newEnv=" + newEnv + + ", params=" + params + + ", call_params=" + call_params + + ", stat=" + stat + + ", mnemo='" + mnemo + '\'' + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java index a5ba1e743..57bb37d86 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java @@ -193,4 +193,11 @@ public void pass4(IntelHEX hex) throws Exception { } hex.putCode(code); } + + @Override + public String toString() { + return "OC_Expr{" + + "expr=" + expr + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java index 5a210cdcf..ac9367262 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java @@ -120,4 +120,9 @@ public void pass4(IntelHEX hex) { } hex.putCode(String.format("%1$02X", opCode)); } + + @Override + public String toString() { + return "OC_NoParams{mnemo="+mnemo+"}"; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java index 90a328dce..7d552feb8 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java @@ -79,4 +79,11 @@ public void pass4(IntelHEX hex) { hex.putCode(String.format("%1$02X", opCode)); } + + @Override + public String toString() { + return "OC_Reg{" + + "reg=" + reg + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java index 7ba4444bb..5c4012e94 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java @@ -62,4 +62,12 @@ public void pass4(IntelHEX hex) throws Exception { hex.putCode(String.format("%1$02X", opCode)); hex.putCode(expr.getEncValue(true)); } + + @Override + public String toString() { + return "OC_RegExpr{" + + "reg=" + reg + + ", expr=" + expr + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java index dd98f9bdb..4e05352d1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java @@ -55,4 +55,12 @@ public void pass4(IntelHEX hex) { opCode |= reg_src; hex.putCode(String.format("%1$02X", opCode)); } + + @Override + public String toString() { + return "OC_RegReg{" + + "reg_src=" + reg_src + + ", reg_dst=" + reg_dst + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java index 4912974f5..cad454f03 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java @@ -70,4 +70,11 @@ public void pass4(IntelHEX hex) { hex.putCode(String.format("%1$02X", opCode)); } + + @Override + public String toString() { + return "OC_Regpair{" + + "regpair=" + regpair + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java index c057705fa..d7689c43c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java @@ -51,4 +51,12 @@ public void pass4(IntelHEX hex) { hex.putCode(String.format("%1$02X", opCode)); hex.putCode(expr.getEncValue(false)); } + + @Override + public String toString() { + return "OC_RegpairExpr{" + + "regpair=" + regpair + + ", expr=" + expr + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java index 5e5291ec1..97afa7ff5 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java @@ -63,4 +63,11 @@ public int pass2(Namespace parentEnv, int addr_start) throws Exception { public void pass4(IntelHEX hex) { hex.setNextAddress(expr.getValue()); } + + @Override + public String toString() { + return "OrgPseudoNode{" + + "expr=" + expr + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java index 98b3162fe..1608fcf47 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java @@ -60,4 +60,12 @@ public int pass2(Namespace env, int addr_start) throws Exception { @Override public void pass4(IntelHEX hex) { } + + @Override + public String toString() { + return "SetPseudoNode{" + + "expr=" + expr + + ", mnemo='" + mnemo + '\'' + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/ExprNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/ExprNode.java index 9682878e7..96f087617 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/ExprNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/ExprNode.java @@ -45,4 +45,11 @@ public String getEncValue(boolean oneByte) { return String.format("%02X%02X", (value & 0xFF), ((value >> 8) & 0xFF)); } } + + @Override + public String toString() { + return "ExprNode{" + + "value=" + value + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java index 2b95acb49..3a390bc51 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java @@ -48,13 +48,15 @@ public void testConstantAsLabelWorks() throws Exception { ); } - @Test(expected = Exception.class) - public void testRecursiveConstantDefinitionsDoesNotWork() throws Exception { + @Test + public void testRecursiveConstantDefinitionsWorks() throws Exception { compile( "here equ there\n" + "there equ here\n" + "jz here" ); + + assertProgram(0xCA, 0, 0); } @Test(expected = Exception.class) @@ -94,4 +96,21 @@ public void testCannotDefineConstantBecauseIdentifierIsAlreadyDefined() throws E "here: db 4\nhere equ 1\n" ); } + + @Test + public void testForwardReferenceOfConstantShouldWork() throws Exception { + compile("LXI SP,STACK\n" + + "TEMPP: DW TEMP0\n" + + "TEMP0: DS 1\n" + + "STACK EQU TEMPP+256"); + + assertProgram( + 0x31, 0x2C, 0x01, 0, 0, 0 + ); + } + + @Test(expected = Exception.class) + public void testUnknownIdentifier() throws Exception { + compile("LXI SP,STACK"); + } } From 226c9d1e761ef19d93d914480a6f5b0705ac8ae2 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 1 Apr 2021 14:09:30 +0200 Subject: [PATCH 023/314] [#194] Fix forward references for Z80 assembler --- .../UnknownIdentifierException.java | 26 ------------------- .../plugins/compiler/as8080/tree/IdExpr.java | 1 - .../plugins/compiler/asZ80/CompilerImpl.java | 2 +- .../plugins/compiler/asZ80/Namespace.java | 4 +++ .../UnknownIdentifierException.java | 26 ------------------- .../compiler/asZ80/tree/Identifier.java | 9 +++---- .../asZ80/ConstantsAndVariablesTest.java | 20 +++++++++++++- 7 files changed, 28 insertions(+), 60 deletions(-) delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownIdentifierException.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnknownIdentifierException.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownIdentifierException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownIdentifierException.java deleted file mode 100644 index 587bb0cd2..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownIdentifierException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.exceptions; - -public class UnknownIdentifierException extends Exception { - - public UnknownIdentifierException(String which) { - super("Unknown identifier: " + which); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java index 5f6e19b47..17c2d5ed2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java @@ -20,7 +20,6 @@ import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.as8080.exceptions.UnknownIdentifierException; import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; public class IdExpr extends ExprNode { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerImpl.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerImpl.java index 12273281b..1125acd6c 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerImpl.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerImpl.java @@ -176,7 +176,7 @@ private IntelHEX compileToHex(String inputFileName) throws Exception { // don't worry about deadlock } if (env.getPassNeedCount() != 0) { - throw new Exception("Error: can't evaluate all expressions"); + throw new Exception("Could not evaluate: " + env.getPassNeedView()); } stat.pass4(hex, env); return hex; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Namespace.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Namespace.java index 74e8639b8..fdbc220eb 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Namespace.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Namespace.java @@ -125,6 +125,10 @@ public int getPassNeedCount() { return passNeed.size(); } + public List getPassNeedView() { + return Collections.unmodifiableList(passNeed); + } + public Row getPassNeed(int index) { return passNeed.get(index); } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnknownIdentifierException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnknownIdentifierException.java deleted file mode 100644 index ecbaa42d6..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnknownIdentifierException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.exceptions; - -public class UnknownIdentifierException extends CompilerException { - - public UnknownIdentifierException(int line, int col, String which) { - super(line, col, "Unknown identifier: " + which); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Identifier.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Identifier.java index 52d592529..2a8dbfbb1 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Identifier.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Identifier.java @@ -20,13 +20,12 @@ import net.emustudio.plugins.compiler.asZ80.Namespace; import net.emustudio.plugins.compiler.asZ80.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.asZ80.exceptions.UnknownIdentifierException; import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; public class Identifier extends Expression { - private String name; - private int line; - private int col; + private final String name; + private final int line; + private final int col; public Identifier(String name, int line, int col) { this.name = name; @@ -61,7 +60,7 @@ public int eval(Namespace env, int curr_addr) throws Exception { this.value = set.getValue(); return this.value; } else { - throw new UnknownIdentifierException(line, col, this.name); + throw new NeedMorePassException(line, col); } } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/ConstantsAndVariablesTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/ConstantsAndVariablesTest.java index 6a169cb69..a81c5f8fb 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/ConstantsAndVariablesTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/ConstantsAndVariablesTest.java @@ -48,13 +48,14 @@ public void testConstantAsLabelWorks() throws Exception { ); } - @Test(expected = Exception.class) + @Test public void testRecursiveConstantDefinitionsDoesNotWork() throws Exception { compile( "here equ there\n" + "there equ here\n" + "jp z, here" ); + assertProgram(0xCA, 0, 0); } @Test(expected = Exception.class) @@ -95,4 +96,21 @@ public void testCannotDefineConstantBecauseIdentifierIsAlreadyDefined() throws E "here: db 4\nhere equ 1\n" ); } + + @Test + public void testForwardReferenceOfConstantShouldWork() throws Exception { + compile("LD SP,STACK\n" + + "TEMPP: DW TEMP0\n" + + "TEMP0: DS 1\n" + + "STACK EQU TEMPP+256"); + + assertProgram( + 0x31, 0x03, 0x01, 0x05, 0, 0 + ); + } + + @Test(expected = Exception.class) + public void testUnknownIdentifier() throws Exception { + compile("LD SP,STACK"); + } } From bb57d983f3bb7520495c9692ff8ff520f6096fed Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 1 Apr 2021 14:16:09 +0200 Subject: [PATCH 024/314] [#194] Fix --- .../plugins/compiler/as8080/ConstantsAndVariablesTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java index 3a390bc51..8d79e9bd3 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java @@ -105,7 +105,7 @@ public void testForwardReferenceOfConstantShouldWork() throws Exception { "STACK EQU TEMPP+256"); assertProgram( - 0x31, 0x2C, 0x01, 0, 0, 0 + 0x31, 0x03, 0x01, 5, 0, 0 ); } From 714a017e300fefdaf3b586004ac99319f6f84043 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 8 Apr 2021 07:51:39 +0200 Subject: [PATCH 025/314] [#181] Fix slowness and wrong reading memory --- .../plugins/cpu/ssem/EmulatorEngine.java | 46 ++++++++++++++++--- .../adm3a/interaction/KeyboardFromFile.java | 2 +- .../device/ssem/display/DisplayGui.java | 2 +- .../device/ssem/display/DisplayPanel.java | 15 ++---- .../memory/ssem/MemoryContextImpl.java | 9 ++-- 5 files changed, 51 insertions(+), 23 deletions(-) diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java index 00b66575d..ed5d7387b 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java @@ -28,7 +28,6 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.LockSupport; public class EmulatorEngine { private final static Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); @@ -57,7 +56,7 @@ void reset(int startingPos) { CPU.RunState step() { Byte[] instruction = memory.readWord(CI.addAndGet(4)); - byte line = (byte)(NumberUtils.reverseBits(instruction[0] & 0b11111000, 8)); + byte line = (byte) (NumberUtils.reverseBits(instruction[0] & 0b11111000, 8)); int lineAddress = line * 4; int opcode = instruction[1] & 7; @@ -136,12 +135,40 @@ CPU.RunState run() { return CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; } if (waitNanos > 0) { - LockSupport.parkNanos(waitNanos); + try { + sleepNanos(waitNanos); + } catch (InterruptedException ex) { + // ignored; will be considered in the beginning of the loop + } } } return currentRunState; } + final static long SLEEP_PRECISION = TimeUnit.MILLISECONDS.toNanos(2); + final static long SPIN_YIELD_PRECISION = TimeUnit.MILLISECONDS.toNanos(2); + + // On Windows, both Thread.sleep() and LockSupport.parkNanos() are veeery unprecise :( + // https://stackoverflow.com/questions/824110/accurate-sleep-for-java-on-windows + public static void sleepNanos(long nanoDuration) throws InterruptedException { + final long end = System.nanoTime() + nanoDuration; + long timeLeft = nanoDuration; + do { + if (timeLeft > SLEEP_PRECISION) + Thread.sleep(1); + else if (timeLeft > SPIN_YIELD_PRECISION) + Thread.yield(); + + timeLeft = end - System.nanoTime(); + } while (timeLeft > 0); + } + + private void fakeInstr() { + Acc.addAndGet(readInt(0)); + if (Acc.get() > 0) Acc.addAndGet(1000); + else Acc.addAndGet(-1000); + } + private void fakeStep() { Byte[] instruction = memory.readWord(CI.get()); @@ -151,16 +178,23 @@ private void fakeStep() { switch (opcode) { case 0: + fakeInstr(); case 1: + fakeInstr(); case 2: + fakeInstr(); case 3: + fakeInstr(); case 4: + fakeInstr(); case 6: + fakeInstr(); case 7: + fakeInstr(); break; } - Acc.addAndGet(- memory.read(line % MEMORY_CELLS)); + Acc.addAndGet(-memory.read(line % MEMORY_CELLS)); } @@ -169,12 +203,12 @@ private void measureAverageInstructionNanos() { int oldAcc = Acc.get(); long start = System.nanoTime(); - for (int i = 0; i < INSTRUCTIONS_PER_SECOND; i++) { + for (int i = 0; i < 5 * INSTRUCTIONS_PER_SECOND; i++) { fakeStep(); } long elapsed = System.nanoTime() - start; - averageInstructionNanos = elapsed / INSTRUCTIONS_PER_SECOND; + averageInstructionNanos = elapsed / (5 * INSTRUCTIONS_PER_SECOND); CI.set(oldCI); Acc.set(oldAcc); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java index d4cfe0bf3..750aba781 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java @@ -60,7 +60,7 @@ public void process() { while ((key = input.read()) != -1) { inputReceived((short) key); if (delayInMilliseconds > 0) { - LockSupport.parkNanos(delayInMilliseconds * 1000000); + LockSupport.parkNanos(delayInMilliseconds * 1000000L); } } } catch (Exception e) { diff --git a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java index 59671dc20..37e613123 100644 --- a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java +++ b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java @@ -50,7 +50,7 @@ public void memoryChanged(int bytePosition) { displayPanel.reset(memory); } else { int row = bytePosition / 4; - displayPanel.writeRow(memory.readWord(bytePosition), row); + displayPanel.writeRow(memory.readWord(row * 4), row); } } diff --git a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java index 3a94c30f4..991d507cd 100644 --- a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java +++ b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java @@ -33,7 +33,7 @@ public class DisplayPanel extends JPanel { private final static int CELL_SIZE = 32; private final static int ROWS = 32; - private final boolean[][] memory = new boolean[CELL_SIZE][CELL_SIZE]; + private final boolean[][] memory = new boolean[ROWS][CELL_SIZE]; DisplayPanel() { super.setBackground(Color.BLACK); @@ -42,13 +42,8 @@ public class DisplayPanel extends JPanel { void writeRow(Byte[] value, int row) { int number = NumberUtils.readInt(value, NumberUtils.Strategy.BIG_ENDIAN); - Boolean[] bits = String - .format("%" + CELL_SIZE + "s", Integer.toBinaryString(number)) - .chars() - .mapToObj(c -> c == '1').toArray(Boolean[]::new); - - for (int i = 0; i < ROWS; i++) { - memory[row][i] = bits[i]; + for (int i = 0; i < CELL_SIZE; i++) { + memory[row][i] = (number & (1 << (CELL_SIZE - i - 1))) != 0; } repaint(); } @@ -62,8 +57,8 @@ void clear() { void reset(MemoryContext memory) { clear(); - for (int i = 0; i < 4 * 32; i += 4) { - writeRow(memory.readWord(i), i / 4); + for (int i = 0; i < ROWS; i++) { + writeRow(memory.readWord(i * 4), i); } } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java index a3b854c5d..1ab48f4b1 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java @@ -53,12 +53,11 @@ public void write(int to, Byte val) { } @Override - public void writeWord(int to, Byte[] cells) { + public void writeWord(int bytePosition, Byte[] cells) { int i = 0; - for (byte cell : cells) { - memory[to + i] = cell; - notifyMemoryChanged(to + i); - i++; + for(byte b: cells) { + memory[bytePosition + (i++)] = b; + notifyMemoryChanged(bytePosition + i - 1); } } From 65191b3388f74a7cfb746bb4e5399be848882111 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 3 May 2021 07:55:17 +0200 Subject: [PATCH 026/314] [#201] First draft on SSEM ANTLR4 parser --- plugins/compiler/as-ssem/.gitignore | 2 +- plugins/compiler/as-ssem/build.gradle | 40 ++++++++++++- .../as-ssem/src/main/antlr/SSEMLexer.g4 | 57 +++++++++++++++++++ .../as-ssem/src/main/antlr/SSEMParser.g4 | 29 ++++++++++ .../compiler/ssem/CompileException.java | 2 +- .../compiler/ssem/ast/CodeGenerator.java | 41 +++++++++++++ .../compiler/ssem/ast/Instruction.java | 49 ++++++++++++++++ .../plugins/compiler/ssem/ast/Program.java | 49 ++++++++++++++++ .../compiler/ssem/ast/ProgramParser.java | 48 ++++++++++++++++ .../plugins/compiler/ssem/ParserTest.java | 22 +++++++ .../compiler/ssem/ast/CodeGeneratorTest.java | 52 +++++++++++++++++ 11 files changed, 386 insertions(+), 5 deletions(-) create mode 100644 plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 create mode 100644 plugins/compiler/as-ssem/src/main/antlr/SSEMParser.g4 create mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/CodeGenerator.java create mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java create mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java create mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java create mode 100644 plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/CodeGeneratorTest.java diff --git a/plugins/compiler/as-ssem/.gitignore b/plugins/compiler/as-ssem/.gitignore index 628279988..1f3145080 100644 --- a/plugins/compiler/as-ssem/.gitignore +++ b/plugins/compiler/as-ssem/.gitignore @@ -1 +1 @@ -src/main/java/net/emustudio/plugins/compiler/ssem/LexerImpl.java +*.tokens diff --git a/plugins/compiler/as-ssem/build.gradle b/plugins/compiler/as-ssem/build.gradle index 6811a6cb2..062010b45 100644 --- a/plugins/compiler/as-ssem/build.gradle +++ b/plugins/compiler/as-ssem/build.gradle @@ -21,11 +21,16 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'idea' id 'org.xbib.gradle.plugin.jflex' version "1.5.0" id "com.github.andrescv.jcup" version "1.0" + id 'antlr' } dependencies { + antlr "org.antlr:antlr4:4.9.2" + compile "org.antlr:antlr4-runtime:4.9.2" + implementation libs.emuLib implementation libs.slf4JApi implementation libs.jcipAnnotations @@ -37,9 +42,31 @@ dependencies { testImplementation libs.slf4JSimple } -sourceSets.main.java.srcDirs = [ - "${buildDir}/generated-sources/jflex", "${buildDir}/generated-sources/cup", 'src/main/java' -] +generateGrammarSource { + maxHeapSize = "128m" + arguments += ['-package', 'net.emustudio.plugins.compiler.ssem', '-visitor', '-no-listener'] + outputDirectory = file("${buildDir}/generated-src/antlr/main/net/emustudio/plugins/compiler/ssem") +} +compileJava.dependsOn generateGrammarSource + +sourceSets { + generated { + java.srcDir "${buildDir}/generated-src/antlr/main" + } + main { + java.srcDirs = [ + "${buildDir}/generated-sources/jflex", "${buildDir}/generated-sources/cup", + 'src/main/java', "${buildDir}/generated-src/antlr/main" + ] + } +} +compileJava.source sourceSets.generated.java, sourceSets.main.java + +idea { + module { + sourceDirs += file("build/generated-src/antlr") + } +} jflex { no_backup = true @@ -82,3 +109,10 @@ copy { from('src/main/scripts') into "$buildDir/libs/scripts" } + + +test { + testLogging { + events "passed", "skipped", "failed" + } +} diff --git a/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 b/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 new file mode 100644 index 000000000..dd5ac79b5 --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 @@ -0,0 +1,57 @@ +lexer grammar SSEMLexer; + +tokens { + COMMENT, + EOL, + JMP, JRP, JPR, JMR, LDN, STO, SUB, CMP, SKN, STP, HLT, + START, NUM, BNUM, + NUMBER, HEXNUMBER +} + +WS : (' ' | '\t') -> skip; +COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]*; +EOL: '\r'? '\n'; + +fragment J: [jJ]; +fragment M: [mM]; +fragment P: [pP]; +fragment R: [rR]; +fragment L: [lL]; +fragment D: [dD]; +fragment N: [nN]; +fragment S: [sS]; +fragment T: [tT]; +fragment O: [oO]; +fragment U: [uU]; +fragment B: [bB]; +fragment C: [cC]; +fragment K: [kK]; +fragment H: [hH]; +fragment A: [aA]; +fragment I: [iI]; + +// reserved +JMP: J M P; +JRP: J R P; +JPR: J P R; +JMR: J M R; +LDN: L D N; +STO: S T O; +SUB: S U B; +CMP: C M P; +SKN: S K N; +STP: S T P; +HLT: H L T; + +// preprocessor +START: S T A R T; +NUM: N U M; +BNUM: ((B N U M) | (B I N S)) -> pushMode(BIN); + +// literals +NUMBER: [\-]? [0-9]+; +HEXNUMBER: [\-]? ('0x'|'0X') [0-9a-fA-F]+; + +mode BIN; +BWS : (' ' | '\t') -> skip; +BinaryNumber: [01]+ -> popMode; diff --git a/plugins/compiler/as-ssem/src/main/antlr/SSEMParser.g4 b/plugins/compiler/as-ssem/src/main/antlr/SSEMParser.g4 new file mode 100644 index 000000000..6ec95b724 --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/antlr/SSEMParser.g4 @@ -0,0 +1,29 @@ +parser grammar SSEMParser; + +options { + tokenVocab = SSEMLexer; +} + +start: + (line EOL line)* EOF + | line EOF + ; + +line: + linenumber=(NUMBER|HEXNUMBER) command=statement? comment + | comment + ; + +comment: COMMENT? ; + +statement: + instr=START + | instr=JPR operand=(NUMBER|HEXNUMBER) + | instr=LDN operand=(NUMBER|HEXNUMBER) + | instr=STO operand=(NUMBER|HEXNUMBER) + | instr=SUB operand=(NUMBER|HEXNUMBER) + | instr=CMP + | instr=STP + | instr=NUM operand=(NUMBER|HEXNUMBER) + | instr=BNUM operand=BinaryNumber + ; diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java index aac3f202e..274ae98a8 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.ssem; -public class CompileException extends Exception { +public class CompileException extends RuntimeException { public CompileException(String message) { super(message); diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/CodeGenerator.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/CodeGenerator.java new file mode 100644 index 000000000..257f15bfa --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/CodeGenerator.java @@ -0,0 +1,41 @@ +package net.emustudio.plugins.compiler.ssem.ast; + +import net.emustudio.emulib.runtime.helpers.NumberUtils; +import net.emustudio.plugins.compiler.ssem.CompileException; +import net.emustudio.plugins.compiler.ssem.SSEMParser; + +import java.nio.ByteBuffer; + +public class CodeGenerator { + private final ByteBuffer code = ByteBuffer.allocate(33 * 4); // one is for start line + + public ByteBuffer generateCode(Program program) { + code.position(0); + code.putInt(program.getStartLine()); + + program.forEach((line, instruction) -> { + code.position(4 * line); + if (instruction.tokenType == SSEMParser.BNUM || instruction.tokenType == SSEMParser.NUM) { + code.putInt(instruction.operand); + } else { + writeInstruction(instruction.getOpcode(), instruction.operand); + } + }); + return code.clear(); + } + + private void writeInstruction(int opcode, int operand) { + if (operand < 0 || operand > 31) { + throw new CompileException("Operand must be between <0, 31>; it was " + operand); + } + + byte address = (byte)(NumberUtils.reverseBits((byte)(operand & 0xFF), 8) & 0xF8); + // 5 bits address + 3 empty bits + code.put(address); + // next: 5 empty bits + 3 bit instruction + code.put((byte)(opcode & 0xFF)); + // 16 empty bits + code.put((byte)0); + code.put((byte)0); + } +} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java new file mode 100644 index 000000000..f998ca55c --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java @@ -0,0 +1,49 @@ +package net.emustudio.plugins.compiler.ssem.ast; + +import net.emustudio.plugins.compiler.ssem.CompileException; +import net.emustudio.plugins.compiler.ssem.SSEMParser; +import net.jcip.annotations.Immutable; + +import java.util.Map; + +@Immutable +public class Instruction { + private final static Map OPCODES = Map.of( + SSEMParser.JMP, (byte)0, // 000 + SSEMParser.SUB, (byte)1, // 001 + SSEMParser.LDN, (byte)2, // 010 + SSEMParser.CMP, (byte)3, // 011 + SSEMParser.JRP, (byte)4, // 100 + SSEMParser.STO, (byte)6, // 110 + SSEMParser.STP, (byte)7, // 111, + SSEMParser.BNUM, (byte)0, + SSEMParser.NUM, (byte)0 + ); + + public final int tokenType; + public final int operand; + + public Instruction(int tokenType) { + if (!OPCODES.containsKey(tokenType)) { + throw new CompileException("Unknown instruction"); + } + this.tokenType = tokenType; + this.operand = 0; + } + + public Instruction(int tokenType, int operand) { + if (!OPCODES.containsKey(tokenType)) { + throw new CompileException("Unknown instruction"); + } + this.tokenType = tokenType; + this.operand = operand; + } + + public int getOpcode() { + return OPCODES.get(tokenType); + } + + public String toString() { + return String.format("%02d %02d", getOpcode(), operand); + } +} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java new file mode 100644 index 000000000..570467c99 --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java @@ -0,0 +1,49 @@ +package net.emustudio.plugins.compiler.ssem.ast; + +import net.emustudio.plugins.compiler.ssem.CompileException; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; + +public class Program { + private int startLine; + private boolean startLineDefined; + + private final Map instructions = new HashMap<>(); + + public void setStartLine(int startLine) { + if (startLineDefined) { + throw new CompileException("Start line is already defined!"); + } + this.startLine = startLine; + startLineDefined = true; + } + + public int getStartLine() { + return startLine; + } + + public void add(int line, Instruction instruction) { + if (instructions.containsKey(line)) { + throw new CompileException("Duplicate line definition: " + line); + } + if (line > 31) { + throw new CompileException("Line number is out of bounds <0;31>: " + line); + } + instructions.put(line, instruction); + } + + public void forEach(BiConsumer processor) { + instructions.forEach(processor); + } + + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(startLine).append(" start\n"); + forEach((line, instr) -> { + buffer.append(String.format("%02d %s\n", line, instr)); + }); + return buffer.toString(); + } +} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java new file mode 100644 index 000000000..a58a8f1fe --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java @@ -0,0 +1,48 @@ +package net.emustudio.plugins.compiler.ssem.ast; + +import net.emustudio.plugins.compiler.ssem.SSEMParser; +import net.emustudio.plugins.compiler.ssem.SSEMParserBaseVisitor; +import org.antlr.v4.runtime.Token; + +public class ProgramParser extends SSEMParserBaseVisitor { + private final Program program = new Program(); + + @Override + public Program visitLine(SSEMParser.LineContext ctx) { + if (ctx.linenumber != null) { + int line = parseNumber(ctx.linenumber); + + if (ctx.command != null) { + int operand = 0; + if (ctx.command.operand != null) { + if (ctx.command.instr.getType() == SSEMParser.BNUM) { + operand = Integer.parseInt(ctx.command.operand.getText(), 2); + } else { + operand = parseNumber(ctx.command.operand); + } + } + + int instrType = ctx.command.instr.getType(); + if (instrType == SSEMParser.START) { + program.setStartLine(line); + } else { + program.add(line, new Instruction(instrType, operand)); + } + } + } + return program; + } + + private int parseNumber(Token token) { + if (token.getType() == SSEMParser.HEXNUMBER) { + return Integer.decode(token.getText()); + } else { + // Do not use decode because we don't support octal numbers + return Integer.parseUnsignedInt(token.getText()); + } + } + + public Program getProgram() { + return program; + } +} diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java index d93f62b89..9c25cd6af 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java @@ -35,6 +35,28 @@ public class ParserTest { + // PASS: + // -- COMMENT + // + // 01 STP -- COMMENT + + // FAIL: + // STP + + // PASS: + // 01 + + // PASS: + // -- + + // PASS: + // + + // FAIL: + // 01 STP 01 STP + + + private ParserImpl program(String program) { return new ParserImpl( new LexerImpl(new StringReader(program)), diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/CodeGeneratorTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/CodeGeneratorTest.java new file mode 100644 index 000000000..d1dd0ae41 --- /dev/null +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/CodeGeneratorTest.java @@ -0,0 +1,52 @@ +package net.emustudio.plugins.compiler.ssem.ast; + +import net.emustudio.plugins.compiler.ssem.SSEMLexer; +import net.emustudio.plugins.compiler.ssem.SSEMParser; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.ConsoleErrorListener; +import org.antlr.v4.runtime.tree.ParseTree; +import org.junit.Test; + +import java.nio.ByteBuffer; + +public class CodeGeneratorTest { + + @Test + public void testSomething() { + String program = + "10 start\n" + + "10 stp"; + + SSEMLexer lexer = new SSEMLexer(CharStreams.fromString(program)); + lexer.addErrorListener(new ConsoleErrorListener()); + + CommonTokenStream tokens = new CommonTokenStream(lexer); + SSEMParser parser = new SSEMParser(tokens); + + parser.addErrorListener(new ConsoleErrorListener()); + ParseTree tree = parser.start(); + + ProgramParser programParser = new ProgramParser(); + programParser.visit(tree); + + Program programx = programParser.getProgram(); + System.out.println(programx); + + CodeGenerator code = new CodeGenerator(); + ByteBuffer buffer = code.generateCode(programx); + + printProgram(buffer); + } + + + private void printProgram(ByteBuffer program) { + byte[] array = program.array(); + for (int i = 0; i < 32; i++) { + for (int j = 0; j < 4; j++) { + System.out.printf("%02d ", array[i * 4 + j]); + } + System.out.println(); + } + } +} From 470a28d6444f93fac2f6688e2e96a45e38d96c2d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 22 May 2021 06:52:20 +0200 Subject: [PATCH 027/314] [#201] Rewrite SSEM compiler + emuStudio to support ANTLR --- application/build.gradle | 99 +++---- .../application/gui/editor/REditor.java | 7 +- .../application/gui/editor/RTokenMaker.java | 108 +++---- .../gui/editor/RTokenMakerWrapper.java | 10 +- build.gradle | 7 +- gradle/wrapper/gradle-wrapper.properties | 2 +- plugins/compiler/as-ssem/build.gradle | 19 +- .../as-ssem/src/main/antlr/SSEMLexer.g4 | 8 +- .../compiler/as-ssem/src/main/cup/parser.cup | 124 -------- .../plugins/compiler/ssem/CodeGenerator.java | 104 ++----- .../compiler/ssem/CompileException.java | 12 + .../plugins/compiler/ssem/CompilerImpl.java | 137 +++++++-- .../compiler/ssem/MemoryAndFileOutput.java | 61 ---- .../compiler/ssem/ParserErrorListener.java | 18 ++ .../compiler/ssem/SeekableOutputStream.java | 28 -- .../plugins/compiler/ssem/TokenImpl.java | 85 ------ .../compiler/ssem/ast/CodeGenerator.java | 41 --- .../compiler/ssem/ast/Instruction.java | 14 + .../plugins/compiler/ssem/ast/Program.java | 7 +- .../plugins/compiler/ssem/tree/ASTnode.java | 25 -- .../compiler/ssem/tree/ASTvisitor.java | 29 -- .../plugins/compiler/ssem/tree/Constant.java | 51 ---- .../compiler/ssem/tree/Instruction.java | 114 -------- .../plugins/compiler/ssem/tree/Program.java | 49 ---- .../as-ssem/src/main/jflex/lexer.jflex | 171 ----------- .../compiler/ssem/CodeGeneratorTest.java | 123 -------- .../plugins/compiler/ssem/LexerTest.java | 174 ++++++----- .../plugins/compiler/ssem/ParserTest.java | 269 +++++++++--------- .../plugins/compiler/ssem/RunnerTest.java | 6 +- .../compiler/ssem/ast/CodeGeneratorTest.java | 52 ---- .../compiler/ssem/ast/ProgramParserTest.java | 109 +++++++ .../plugins/cpu/ssem/AutomaticEmulation.java | 2 +- .../plugins/cpu/ssem/EmulatorEngine.java | 8 +- .../plugins/cpu/ssem/gui/CpuPanel.java | 4 +- .../plugins/cpu/ssem/EmulatorEngineTest.java | 3 +- .../device/ssem/display/DisplayGui.java | 3 +- .../device/ssem/display/DisplayPanel.java | 2 +- .../memory/ssem/MemoryContextImpl.java | 24 +- .../memory/ssem/gui/MemoryTableModel.java | 6 +- .../memory/ssem/MemoryContextImplTest.java | 11 +- .../plugins/memory/ssem/MemoryImplTest.java | 2 - .../memory/ssem/gui/MemoryTableModelTest.java | 16 +- settings.gradle | 40 +-- 43 files changed, 685 insertions(+), 1499 deletions(-) delete mode 100644 plugins/compiler/as-ssem/src/main/cup/parser.cup delete mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/MemoryAndFileOutput.java create mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ParserErrorListener.java delete mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SeekableOutputStream.java delete mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/TokenImpl.java delete mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/CodeGenerator.java delete mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/ASTnode.java delete mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/ASTvisitor.java delete mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Constant.java delete mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Instruction.java delete mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Program.java delete mode 100644 plugins/compiler/as-ssem/src/main/jflex/lexer.jflex delete mode 100644 plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/CodeGeneratorTest.java delete mode 100644 plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/CodeGeneratorTest.java create mode 100644 plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java diff --git a/application/build.gradle b/application/build.gradle index deaf64314..e69da5fac 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -39,6 +39,7 @@ dependencies { extraLibs libs.emuLib implementation libs.jcipAnnotations + implementation libs.antlrRuntime extraLibs libs.editor extraLibs libs.editorDialogs @@ -48,32 +49,32 @@ dependencies { extraLibs libs.slf4JApi extraLibsRuntime libs.javaCupRuntime - providedRuntime project(":plugins:compiler:as-8080") +// providedRuntime project(":plugins:compiler:as-8080") providedRuntime project(":plugins:compiler:as-ssem") - providedRuntime project(":plugins:compiler:as-z80") - providedRuntime project(":plugins:compiler:brainc-brainduck") - providedRuntime project(":plugins:compiler:ramc-ram") - providedRuntime project(":plugins:compiler:raspc-rasp") - - providedRuntime project(":plugins:memory:ram-mem") - providedRuntime project(":plugins:memory:rasp-mem") - providedRuntime project(":plugins:memory:brainduck-mem") +// providedRuntime project(":plugins:compiler:as-z80") +// providedRuntime project(":plugins:compiler:brainc-brainduck") +// providedRuntime project(":plugins:compiler:ramc-ram") +// providedRuntime project(":plugins:compiler:raspc-rasp") + +// providedRuntime project(":plugins:memory:ram-mem") + // providedRuntime project(":plugins:memory:rasp-mem") + // providedRuntime project(":plugins:memory:brainduck-mem") providedRuntime project(":plugins:memory:ssem-mem") - providedRuntime project(":plugins:memory:byte-mem") + // providedRuntime project(":plugins:memory:byte-mem") - providedRuntime project(":plugins:cpu:8080-cpu") - providedRuntime project(":plugins:cpu:brainduck-cpu") - providedRuntime project(":plugins:cpu:ram-cpu") - providedRuntime project(":plugins:cpu:rasp-cpu") - providedRuntime project(":plugins:cpu:z80-cpu") + // providedRuntime project(":plugins:cpu:8080-cpu") + // providedRuntime project(":plugins:cpu:brainduck-cpu") +// providedRuntime project(":plugins:cpu:ram-cpu") + // providedRuntime project(":plugins:cpu:rasp-cpu") + // providedRuntime project(":plugins:cpu:z80-cpu") providedRuntime project(":plugins:cpu:ssem-cpu") - providedRuntime project(":plugins:device:abstract-tape") - providedRuntime project(":plugins:device:88-dcdd") - providedRuntime project(":plugins:device:88-sio") - providedRuntime project(":plugins:device:adm3A-terminal") - providedRuntime project(":plugins:device:brainduck-terminal") - providedRuntime project(":plugins:device:simhPseudo-z80") +// providedRuntime project(":plugins:device:abstract-tape") +// providedRuntime project(":plugins:device:88-dcdd") +// providedRuntime project(":plugins:device:88-sio") +// providedRuntime project(":plugins:device:adm3A-terminal") +// providedRuntime project(":plugins:device:brainduck-terminal") +// providedRuntime project(":plugins:device:simhPseudo-z80") providedRuntime project(":plugins:device:ssem-display") testImplementation libs.junit @@ -175,62 +176,64 @@ distributions { into('compiler') { include '*.jar' - from(output(":plugins:compiler:as-8080")) - from(output(":plugins:compiler:as-z80")) +// from(output(":plugins:compiler:as-8080")) + // from(output(":plugins:compiler:as-z80")) from(output(":plugins:compiler:as-ssem")) - from(output(":plugins:compiler:brainc-brainduck")) - from(output(":plugins:compiler:ramc-ram")) - from(output(":plugins:compiler:raspc-rasp")) + // from(output(":plugins:compiler:brainc-brainduck")) + // from(output(":plugins:compiler:ramc-ram")) + //from(output(":plugins:compiler:raspc-rasp")) } into('memory') { include '*.jar' - from(output(":plugins:memory:ram-mem")) - from(output(":plugins:memory:rasp-mem")) - from(output(":plugins:memory:brainduck-mem")) +// from(output(":plugins:memory:ram-mem")) + // from(output(":plugins:memory:rasp-mem")) + // from(output(":plugins:memory:brainduck-mem")) from(output(":plugins:memory:ssem-mem")) - from(output(":plugins:memory:byte-mem")) + // from(output(":plugins:memory:byte-mem")) } into('cpu') { include '*.jar' - from(output(":plugins:cpu:8080-cpu")) - from(output(":plugins:cpu:brainduck-cpu")) - from(output(":plugins:cpu:ram-cpu")) - from(output(":plugins:cpu:rasp-cpu")) - from(output(":plugins:cpu:z80-cpu")) +// from(output(":plugins:cpu:8080-cpu")) + // from(output(":plugins:cpu:brainduck-cpu")) + // from(output(":plugins:cpu:ram-cpu")) + // from(output(":plugins:cpu:rasp-cpu")) + // from(output(":plugins:cpu:z80-cpu")) from(output(":plugins:cpu:ssem-cpu")) } into('device') { include '*.jar' - from(output(":plugins:device:abstract-tape")) - from(output(":plugins:device:88-dcdd")) - from(output(":plugins:device:88-sio")) - from(output(":plugins:device:adm3A-terminal")) - from(output(":plugins:device:brainduck-terminal")) - from(output(":plugins:device:simhPseudo-z80")) +// from(output(":plugins:device:abstract-tape")) + // from(output(":plugins:device:88-dcdd")) + // from(output(":plugins:device:88-sio")) + // from(output(":plugins:device:adm3A-terminal")) + //from(output(":plugins:device:brainduck-terminal")) + // from(output(":plugins:device:simhPseudo-z80")) from(output(":plugins:device:ssem-display")) } // Examples - ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"].collect { compiler -> + //["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"] + ["as-ssem"].collect { compiler -> from(examples(":plugins:compiler:$compiler")) { into "examples/$compiler" } } // Scripts - ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"].collect { compiler -> + // ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"] + ["as-ssem"].collect { compiler -> from(scripts(":plugins:compiler:$compiler")) { into "bin" } } - ["88-dcdd"].collect { device -> - from(scripts(":plugins:device:$device")) { - into "bin" - } - } +// ["88-dcdd"].collect { device -> +// from(scripts(":plugins:device:$device")) { +// into "bin" +// } +// } } } } diff --git a/application/src/main/java/net/emustudio/application/gui/editor/REditor.java b/application/src/main/java/net/emustudio/application/gui/editor/REditor.java index a6b220769..b6dc37adb 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/REditor.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/REditor.java @@ -19,7 +19,6 @@ import java.awt.event.MouseWheelListener; import java.io.File; import java.io.IOException; -import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.List; @@ -51,7 +50,7 @@ public REditor(Dialogs dialogs, Compiler compiler) { UnicodeWriter.setWriteUtf8BOM(false); - textPane.setCodeFoldingEnabled(true); + textPane.setCodeFoldingEnabled(false); textPane.setEncoding(StandardCharsets.UTF_8.name()); textPane.setAnimateBracketMatching(true); textPane.setAutoIndentEnabled(true); @@ -99,7 +98,7 @@ public void keyTyped(KeyEvent e) { if (compiler != null) { sourceFileExtensions = compiler.getSourceFileExtensions(); - RTokenMakerWrapper unusedButUseful = new RTokenMakerWrapper(compiler.getLexer(new StringReader(textPane.getText()))); + RTokenMakerWrapper unusedButUseful = new RTokenMakerWrapper(compiler); AbstractTokenMakerFactory atmf = (AbstractTokenMakerFactory) TokenMakerFactory.getDefaultInstance(); atmf.putMapping("text/emustudio", RTokenMakerWrapper.class.getName()); @@ -176,7 +175,7 @@ public boolean saveFileAs() { isnew = false; return true; } catch (IOException e) { - LOGGER.error("Could not save file: " + savedPath.get().toString(), e); + LOGGER.error("Could not save file: " + savedPath.get(), e); dialogs.showError("Cannot save current file. Please see log file for details."); } } diff --git a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java index 8a7b941b4..00ac9e3b5 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java @@ -1,82 +1,62 @@ package net.emustudio.application.gui.editor; -import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; +import net.emustudio.emulib.plugins.compiler.Compiler; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.Lexer; import org.fife.ui.rsyntaxtextarea.AbstractTokenMaker; import org.fife.ui.rsyntaxtextarea.Token; import org.fife.ui.rsyntaxtextarea.TokenMap; import javax.swing.text.Segment; -import java.io.IOException; -import java.io.StringReader; import java.util.Objects; -import static net.emustudio.emulib.plugins.compiler.Token.*; - public class RTokenMaker extends AbstractTokenMaker { - private final LexicalAnalyzer lexicalAnalyzer; + private final Compiler compiler; - public RTokenMaker(LexicalAnalyzer lexicalAnalyzer) { - this.lexicalAnalyzer = Objects.requireNonNull(lexicalAnalyzer); + public RTokenMaker(Compiler compiler) { + this.compiler = Objects.requireNonNull(compiler); } @Override public Token getTokenList(Segment text, int initialTokenType, int startOffset) { resetTokenList(); + Lexer lexer = compiler.createLexer(CharStreams.fromString(Objects.requireNonNull(text).toString())); + int previousEnd = -1; + int previousStartOffset = -1; - int offset = text.offset; - int count = text.count; - int end = offset + count; - - // Token starting offsets are always of the form: - // 'startOffset + (currentTokenStart-offset)', but since startOffset and - // offset are constant, tokens' starting positions become: - // 'newStartOffset+currentTokenStart'. - int newStartOffset = startOffset - offset; - - lexicalAnalyzer.reset(new StringReader(text.toString()), 0, offset, 0); - int lastOffset = offset; - for (int i = offset; i < end; ) { + while (!lexer._hitEOF) { try { - int expectedTokenStart = i; + org.antlr.v4.runtime.Token token = lexer.nextToken(); + int emuStudioType = compiler.convertLexerTokenType(token.getType()); + int tokenMakerType = getTokenMakerType(emuStudioType); - net.emustudio.emulib.plugins.compiler.Token token = lexicalAnalyzer.getToken(); - int tokenStart = token.getOffset(); - int tokenEnd = tokenStart + token.getLength() - 1; - int skipChars = token.getLength(); + String tokenText = token.getText(); + int tokenStartIndex = token.getStartIndex(); + int tokenLength = tokenText.length() - 1; + if (token.getType() == org.antlr.v4.runtime.Token.EOF) { + tokenLength = 0; + } - if (token.getType() != TEOF && token.getLength() > 0) { - int tokenMakerType = getTokenMakerType(token.getType()); - if (tokenStart > expectedTokenStart) { - skipChars += tokenStart - expectedTokenStart; - // fill the gap - addToken( - text, expectedTokenStart, tokenStart - 1, Token.WHITESPACE, - newStartOffset + expectedTokenStart - ); - lastOffset = tokenStart - 1; - } + int start = text.offset + tokenStartIndex; + int end = text.offset + tokenStartIndex + tokenLength; + int tokenStartOffset = startOffset + tokenStartIndex; + if (previousEnd == -1 && tokenStartIndex != 0) { + // we have a gap in the beginning! Let's treat this gap as ERROR + addToken(text, text.offset, start - 1, Token.ERROR_CHAR, startOffset); + } else if (previousEnd != -1 && start != (previousEnd + 1)) { + // we have a gap in the middle! Let's treat this gap as ERROR addToken( - text, tokenStart, tokenEnd, tokenMakerType, newStartOffset + tokenStart + text, previousEnd + 1, start - 1, Token.ERROR_CHAR, previousStartOffset + 1 ); - lastOffset = tokenEnd; - } else { - // fill the gap - addToken( - text, expectedTokenStart, end - 1, Token.WHITESPACE, newStartOffset + expectedTokenStart - ); - lastOffset = end - 1; - break; } + previousEnd = end; + previousStartOffset = tokenStartOffset; - i += skipChars; - } catch (IOException donotlogit) { - donotlogit.printStackTrace(); + addToken(text, start, end, tokenMakerType, tokenStartOffset); + } catch (Exception ignore) { } } - if (offset == end || lastOffset < end - 1) { - addNullToken(); - } return firstToken; } @@ -87,28 +67,28 @@ public TokenMap getWordsToHighlight() { private static int getTokenMakerType(int emuStudioTokenType) { switch (emuStudioTokenType) { - case TEOF: - return Token.NULL; - case RESERVED: + case net.emustudio.emulib.plugins.compiler.Token.RESERVED: return Token.RESERVED_WORD; - case PREPROCESSOR: + case net.emustudio.emulib.plugins.compiler.Token.PREPROCESSOR: return Token.PREPROCESSOR; - case REGISTER: + case net.emustudio.emulib.plugins.compiler.Token.REGISTER: return Token.RESERVED_WORD_2; - case SEPARATOR: + case net.emustudio.emulib.plugins.compiler.Token.SEPARATOR: return Token.SEPARATOR; - case OPERATOR: + case net.emustudio.emulib.plugins.compiler.Token.OPERATOR: return Token.OPERATOR; - case COMMENT: + case net.emustudio.emulib.plugins.compiler.Token.COMMENT: return Token.COMMENT_MARKUP; - case LITERAL: + case net.emustudio.emulib.plugins.compiler.Token.LITERAL: return Token.LITERAL_NUMBER_DECIMAL_INT; - case IDENTIFIER: + case net.emustudio.emulib.plugins.compiler.Token.IDENTIFIER: return Token.IDENTIFIER; - case LABEL: + case net.emustudio.emulib.plugins.compiler.Token.LABEL: return Token.ANNOTATION; - case ERROR: + case net.emustudio.emulib.plugins.compiler.Token.ERROR: return Token.ERROR_IDENTIFIER; + case net.emustudio.emulib.plugins.compiler.Token.TEOF: + return Token.NULL; } return Token.WHITESPACE; } diff --git a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMakerWrapper.java b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMakerWrapper.java index 7cb70158e..1fb678394 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMakerWrapper.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMakerWrapper.java @@ -1,7 +1,9 @@ package net.emustudio.application.gui.editor; -import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; -import org.fife.ui.rsyntaxtextarea.*; +import net.emustudio.emulib.plugins.compiler.Compiler; +import org.fife.ui.rsyntaxtextarea.OccurrenceMarker; +import org.fife.ui.rsyntaxtextarea.Token; +import org.fife.ui.rsyntaxtextarea.TokenMaker; import javax.swing.*; import javax.swing.text.Segment; @@ -9,8 +11,8 @@ public class RTokenMakerWrapper implements TokenMaker { private static RTokenMaker WRAPPED; - public RTokenMakerWrapper(LexicalAnalyzer lexicalAnalyzer) { - WRAPPED = new RTokenMaker(lexicalAnalyzer); + public RTokenMakerWrapper(Compiler compiler) { + WRAPPED = new RTokenMaker(compiler); } @SuppressWarnings("unused") diff --git a/build.gradle b/build.gradle index 55c7a0f4c..9ec65e3c2 100644 --- a/build.gradle +++ b/build.gradle @@ -24,11 +24,12 @@ ext.versions = [ ] ext.libs = [ - emuLib : "net.emustudio:emulib:11.5.0", - cpuTestSuite : "net.emustudio:cpu-testsuite_11.5:1.1.0", + emuLib : "net.emustudio:emulib:11.6.0-SNAPSHOT", + cpuTestSuite : "net.emustudio:cpu-testsuite_11.6:1.2.0-SNAPSHOT", javaCupRuntime : "com.github.vbmacher:java-cup-runtime:11b-20160615", jcipAnnotations: "net.jcip:jcip-annotations:1.0", + antlrRuntime : "org.antlr:antlr4-runtime:4.9.2", slf4JApi : "org.slf4j:slf4j-api:${versions.slf4j}", slf4JSimple : "org.slf4j:slf4j-simple:${versions.slf4j}", @@ -91,7 +92,7 @@ allprojects { subprojects { repositories { - mavenCentral() mavenLocal() + mavenCentral() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 80cf08e74..d435ce29d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/plugins/compiler/as-ssem/build.gradle b/plugins/compiler/as-ssem/build.gradle index 062010b45..e5b0e6a75 100644 --- a/plugins/compiler/as-ssem/build.gradle +++ b/plugins/compiler/as-ssem/build.gradle @@ -22,14 +22,12 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' id 'idea' - id 'org.xbib.gradle.plugin.jflex' version "1.5.0" - id "com.github.andrescv.jcup" version "1.0" id 'antlr' } dependencies { antlr "org.antlr:antlr4:4.9.2" - compile "org.antlr:antlr4-runtime:4.9.2" + implementation "org.antlr:antlr4-runtime:4.9.2" implementation libs.emuLib implementation libs.slf4JApi @@ -55,7 +53,6 @@ sourceSets { } main { java.srcDirs = [ - "${buildDir}/generated-sources/jflex", "${buildDir}/generated-sources/cup", 'src/main/java', "${buildDir}/generated-src/antlr/main" ] } @@ -68,18 +65,6 @@ idea { } } -jflex { - no_backup = true -} - -jcup { - input = file('src/main/cup/parser.cup') - destdir = file("${buildDir}/generated-sources/cup/net/emustudio/plugins/compiler/ssem") - parser = 'ParserImpl' - symbols = 'Symbols' - iface = true -} - jar { archiveVersion = '' manifest { @@ -91,7 +76,7 @@ processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ "project.version": project.version, - "today.year": new Date().format("yyyy") + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 b/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 index dd5ac79b5..7cc2c6965 100644 --- a/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 +++ b/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 @@ -2,13 +2,13 @@ lexer grammar SSEMLexer; tokens { COMMENT, - EOL, + EOL, WS, BWS, JMP, JRP, JPR, JMR, LDN, STO, SUB, CMP, SKN, STP, HLT, START, NUM, BNUM, - NUMBER, HEXNUMBER + NUMBER, HEXNUMBER, BinaryNumber } -WS : (' ' | '\t') -> skip; +WS : (' ' | '\t') -> channel(HIDDEN); COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]*; EOL: '\r'? '\n'; @@ -53,5 +53,5 @@ NUMBER: [\-]? [0-9]+; HEXNUMBER: [\-]? ('0x'|'0X') [0-9a-fA-F]+; mode BIN; -BWS : (' ' | '\t') -> skip; +BWS : (' ' | '\t') -> channel(HIDDEN); BinaryNumber: [01]+ -> popMode; diff --git a/plugins/compiler/as-ssem/src/main/cup/parser.cup b/plugins/compiler/as-ssem/src/main/cup/parser.cup deleted file mode 100644 index be85fcb67..000000000 --- a/plugins/compiler/as-ssem/src/main/cup/parser.cup +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ssem; - -import java_cup.runtime.ComplexSymbolFactory; -import net.emustudio.emulib.plugins.compiler.CompilerMessage; -import net.emustudio.emulib.plugins.compiler.Token; -import net.emustudio.plugins.compiler.ssem.tree.ASTnode; -import net.emustudio.plugins.compiler.ssem.tree.Constant; -import net.emustudio.plugins.compiler.ssem.tree.Instruction; -import net.emustudio.plugins.compiler.ssem.tree.Program; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -parser code {: - private CompilerImpl compiler; // cannot be final because cup generates garbage constructors - private boolean syntaxErrors; - - public ParserImpl(LexerImpl lexer, CompilerImpl compiler) { - super(lexer, new ComplexSymbolFactory()); - this.compiler = Objects.requireNonNull(compiler); - } - - public void reset() { - syntaxErrors = false; - } - - @Override - public void report_fatal_error(String message, Object info) throws Exception { - done_parsing(); - report_error(message, info); - throw new Exception("Can't recover from previous error(s)"); - } - - @Override - public void report_error(String messageText, Object current) { - syntaxErrors = true; - - Token token = (Token)current; - - messageText += ":" + token.getErrorString() + " ('" + token.getText() + "')"; - - List expectedTokenIds = expected_token_ids() - .stream() - .map(this::symbl_name_from_id) - .collect(Collectors.toList()); - - if (!expectedTokenIds.isEmpty()) { - messageText += "\nExpected tokens: " + expectedTokenIds; - } - - CompilerMessage message = new CompilerMessage( - CompilerMessage.MessageType.TYPE_ERROR, messageText, token.getLine()+1, token.getColumn() - ); - - compiler.notifyOnMessage(message); - } - - public boolean hasSyntaxErrors() { - return syntaxErrors; - } - -:}; - -terminal JMP, JPR, LDN, STO, SUB, CMP, STP, NUM, BNUM; -terminal SEPARATOR_EOL, TCOMMENT; -terminal Integer NUMBER; -terminal START; - -non terminal Program Program; -non terminal ASTnode Statement; -non terminal Instruction Instruction; -non terminal Constant Constant; -non terminal Comment; - -start with Program; - -Program ::= NUMBER:c Statement:s Program:p {: if (s != null) p.statement(c, s); RESULT = p; :} - | NUMBER:c Comment SEPARATOR_EOL Program:p {: RESULT = p; :} - | Comment SEPARATOR_EOL Program:p {: RESULT = p; :} - | START SEPARATOR_EOL Program:p {: p.nextLineStarts(); RESULT = p; :} - | /* empty program */ {: RESULT = new Program(); :} - ; - -Statement ::= Instruction:i Comment SEPARATOR_EOL {: RESULT = i; :} - | Constant:c Comment SEPARATOR_EOL {: RESULT = c; :} - ; - -Instruction ::= JMP NUMBER:line {: RESULT = Instruction.jmp(line); :} - | JPR NUMBER:line {: RESULT = Instruction.jrp(line); :} - | LDN NUMBER:line {: RESULT = Instruction.ldn(line); :} - | STO NUMBER:line {: RESULT = Instruction.sto(line); :} - | SUB NUMBER:line {: RESULT = Instruction.sub(line); :} - | CMP {: RESULT = Instruction.cmp(); :} - | STP {: RESULT = Instruction.stp(); :} - | error - ; - -Constant ::= NUM NUMBER:raw {: RESULT = new Constant(raw); :} - | BNUM NUMBER:raw {: RESULT = new Constant(raw); :} - ; - -Comment ::= TCOMMENT - | /* no comment*/ - ; - diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java index 0c7e10918..527408e58 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java @@ -1,86 +1,40 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ package net.emustudio.plugins.compiler.ssem; import net.emustudio.emulib.runtime.helpers.NumberUtils; -import net.emustudio.plugins.compiler.ssem.tree.ASTvisitor; -import net.emustudio.plugins.compiler.ssem.tree.Constant; -import net.emustudio.plugins.compiler.ssem.tree.Instruction; - -import java.io.IOException; -import java.util.Objects; - -public class CodeGenerator implements ASTvisitor, AutoCloseable { - private final SeekableOutputStream writer; - private int currentLine; - - public CodeGenerator(SeekableOutputStream writer) { - this.writer = Objects.requireNonNull(writer); - } - - @Override - public void setCurrentLine(int line) { - this.currentLine = line; +import net.emustudio.plugins.compiler.ssem.ast.Program; + +import java.nio.ByteBuffer; + +public class CodeGenerator { + private final ByteBuffer code = ByteBuffer.allocate(33 * 4); // one is for start line + + public ByteBuffer generateCode(Program program) { + code.position(0); + code.putInt(program.getStartLine()); + + program.forEach((line, instruction) -> { + code.position(4 * (line + 1)); + if (instruction.tokenType == SSEMParser.BNUM || instruction.tokenType == SSEMParser.NUM) { + code.putInt(instruction.operand); + } else { + writeInstruction(instruction.getOpcode(), instruction.operand); + } + }); + return code.clear(); } - @Override - public void visit(Instruction instruction) throws CompileException, IOException { - byte address = instruction.getOperand().orElse((byte) 0); - - if (address < 0 || address > 31) { - throw new CompileException("Operand must be between <0, 31>; it was " + address); + private void writeInstruction(int opcode, int operand) { + if (operand < 0 || operand > 31) { + throw new CompileException("Operand must be between <0, 31>; it was " + operand); } - // Instruction has 32 bits, i.e. 4 bytes - int addressSSEM = NumberUtils.reverseBits(address, 8) & 0xF8; - writer.seek(4 * currentLine); - - writer.write(addressSSEM); // address + 3 empty bits - + byte address = (byte)(NumberUtils.reverseBits((byte)(operand & 0xFF), 8) & 0xF8); + // 5 bits address + 3 empty bits + code.put(address); // next: 5 empty bits + 3 bit instruction - int opcode = instruction.getOpcode() & 7; - writer.write(opcode); - + code.put((byte)(opcode & 0xFF)); // 16 empty bits - writer.write(new byte[2]); - } - - @Override - public void visit(Constant constant) throws Exception { - int number = constant.getNumber(); - - writer.seek(4 * currentLine); - writeInt(number); - } - - private void writeInt(int value) throws IOException { - Byte[] word = new Byte[4]; - NumberUtils.writeInt(value, word, NumberUtils.Strategy.REVERSE_BITS); - - writer.write(word[0]); - writer.write(word[1]); - writer.write(word[2]); - writer.write(word[3]); - } - - @Override - public void close() throws Exception { - writer.close(); + code.put((byte)0); + code.put((byte)0); } } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java index 274ae98a8..4852689a3 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java @@ -19,9 +19,21 @@ package net.emustudio.plugins.compiler.ssem; public class CompileException extends RuntimeException { + final int line; + final int column; public CompileException(String message) { + this(message, -1, -1); + } + + public CompileException(String message, int line, int column) { super(message); + this.line = line; + this.column = column; } + @Override + public String toString() { + return "line " + line + ":" + column + " " + super.getMessage(); + } } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java index aef21d002..c7d2a8d6a 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java @@ -22,20 +22,25 @@ import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; import net.emustudio.emulib.plugins.annotations.PluginRoot; import net.emustudio.emulib.plugins.compiler.AbstractCompiler; -import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; import net.emustudio.emulib.plugins.compiler.SourceFileExtension; +import net.emustudio.emulib.plugins.compiler.Token; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextNotFoundException; import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.helpers.NumberUtils; import net.emustudio.emulib.runtime.helpers.RadixUtils; -import net.emustudio.plugins.compiler.ssem.tree.Program; +import net.emustudio.plugins.compiler.ssem.ast.Program; +import net.emustudio.plugins.compiler.ssem.ast.ProgramParser; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.tree.ParseTree; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.FileReader; -import java.io.Reader; +import java.io.*; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; import java.util.*; @PluginRoot( @@ -51,13 +56,8 @@ public class CompilerImpl extends AbstractCompiler { private MemoryContext memory; private int programLocation; - private final LexerImpl lexer; - private final ParserImpl parser; - public CompilerImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); - lexer = new LexerImpl(null); - parser = new ParserImpl(lexer, this); } @SuppressWarnings("unchecked") @@ -77,6 +77,11 @@ public void initialize() { }); } + @Override + public void parse(Parser parser) { + ((SSEMParser) parser).start(); + } + @Override public boolean compile(String inputFileName, String outputFileName) { notifyCompileStart(); @@ -87,29 +92,36 @@ public boolean compile(String inputFileName, String outputFileName) { } try (Reader reader = new FileReader(inputFileName)) { - try (CodeGenerator codeGenerator = new CodeGenerator(new MemoryAndFileOutput(outputFileName, memory))) { - lexer.reset(reader, 0, 0, 0); - parser.reset(); + Lexer lexer = createLexer(CharStreams.fromReader(reader)); + lexer.addErrorListener(new ParserErrorListener()); + CommonTokenStream tokens = new CommonTokenStream(lexer); - Program program = (Program) parser.parse().value; - if (program == null) { - throw new Exception("Unexpected end of file"); - } - if (parser.hasSyntaxErrors()) { - throw new Exception("One or more errors has been found, cannot continue."); - } + SSEMParser parser = createParser(tokens); + parser.addErrorListener(new ParserErrorListener()); + + ParseTree tree = parser.start(); + ProgramParser programParser = new ProgramParser(); + programParser.visit(tree); - program.accept(codeGenerator); - programLocation = program.getStartLine() * 4; - notifyInfo( - "Compile was successful (program starts at " + RadixUtils.formatWordHexString(programLocation) - + "). Output: " + outputFileName - ); + Program program = programParser.getProgram(); + CodeGenerator codeGenerator = new CodeGenerator(); + ByteBuffer code = codeGenerator.generateCode(program); + + if (code.hasRemaining()) { + writeToFile(code, outputFileName); + writeToMemory(code); } + + programLocation = program.getStartLine() * 4; + + notifyInfo(String.format( + "Compile was successful (program starts at %s). Output: %s", + RadixUtils.formatWordHexString(programLocation), outputFileName + )); } catch (Exception e) { + e.printStackTrace(); LOGGER.trace("Compilation error.", e); - notifyError("Compilation error: " + e.getMessage()); - + notifyError(e.toString()); return false; } finally { notifyCompileFinish(); @@ -118,6 +130,24 @@ public boolean compile(String inputFileName, String outputFileName) { return true; } + private void writeToFile(ByteBuffer code, String outputFileName) throws IOException { + code.rewind(); + try (FileChannel channel = new FileOutputStream(outputFileName, false).getChannel()) { + channel.write(code); + } + } + + private void writeToMemory(ByteBuffer code) { + if (memory != null) { + code.rewind(); + code.position(4); // First 4 bytes is start line + byte[] data = new byte[code.remaining()]; + code.get(data); + memory.clear(); + memory.write(0, NumberUtils.nativeBytesToBytes(data)); + } + } + @Override public boolean compile(String inputFileName) { String outputFileName = Objects.requireNonNull(inputFileName); @@ -131,13 +161,58 @@ public boolean compile(String inputFileName) { } @Override - public int getProgramLocation() { - return programLocation; + public SSEMLexer createLexer(CharStream input) { + SSEMLexer lexer = new SSEMLexer(input); + lexer.removeErrorListeners(); + return lexer; + } + + @Override + public SSEMParser createParser(TokenStream tokenStream) { + SSEMParser parser = new SSEMParser(tokenStream); + parser.removeErrorListeners(); + return parser; } @Override - public LexicalAnalyzer getLexer(Reader reader) { - return new LexerImpl(reader); + public int convertLexerTokenType(int tokenType) { + switch (tokenType) { + case SSEMLexer.COMMENT: + return Token.COMMENT; + case SSEMLexer.EOL: + case SSEMLexer.WS: + case SSEMLexer.BWS: + return Token.WHITESPACE; + case SSEMLexer.JMP: + case SSEMLexer.JRP: + case SSEMLexer.JPR: + case SSEMLexer.JMR: + case SSEMLexer.LDN: + case SSEMLexer.STO: + case SSEMLexer.SKN: + case SSEMLexer.SUB: + case SSEMLexer.CMP: + case SSEMLexer.STP: + case SSEMLexer.HLT: + return Token.RESERVED; + case SSEMLexer.START: + return Token.LABEL; + case SSEMLexer.NUM: + case SSEMLexer.BNUM: + return Token.PREPROCESSOR; + case SSEMLexer.NUMBER: + case SSEMLexer.HEXNUMBER: + case SSEMLexer.BinaryNumber: + return Token.LITERAL; + case SSEMLexer.EOF: + return Token.TEOF; + } + return Token.ERROR; + } + + @Override + public int getProgramLocation() { + return programLocation; } @Override diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/MemoryAndFileOutput.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/MemoryAndFileOutput.java deleted file mode 100644 index 72685b67b..000000000 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/MemoryAndFileOutput.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ssem; - -import net.emustudio.emulib.plugins.memory.MemoryContext; -import net.jcip.annotations.NotThreadSafe; - -import java.io.IOException; -import java.io.RandomAccessFile; - -@NotThreadSafe -public class MemoryAndFileOutput extends SeekableOutputStream { - private final RandomAccessFile file; - private final MemoryContext memoryContext; - private int position = 0; - - public MemoryAndFileOutput(String filename, MemoryContext memoryContext) throws IOException { - this.file = new RandomAccessFile(filename, "rw"); - this.memoryContext = memoryContext; - } - - @Override - public void write(int b) throws IOException { - if (memoryContext != null) { - memoryContext.write(position, (byte) (b & 0xFF)); - } - file.write(b); - position++; - } - - @Override - public void seek(int position) throws IOException { - this.position = position; - file.seek(position); - } - - @Override - public void close() throws IOException { - try { - file.close(); - } finally { - super.close(); - } - } -} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ParserErrorListener.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ParserErrorListener.java new file mode 100644 index 000000000..1f29a19d5 --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ParserErrorListener.java @@ -0,0 +1,18 @@ +package net.emustudio.plugins.compiler.ssem; + +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; + +class ParserErrorListener extends BaseErrorListener { + @Override + public void syntaxError( + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { + throw new CompileException(msg, line, charPositionInLine); + } +} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SeekableOutputStream.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SeekableOutputStream.java deleted file mode 100644 index cb25835e8..000000000 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SeekableOutputStream.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ssem; - -import java.io.IOException; -import java.io.OutputStream; - -public abstract class SeekableOutputStream extends OutputStream { - - public abstract void seek(int position) throws IOException; - -} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/TokenImpl.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/TokenImpl.java deleted file mode 100644 index 8bd794e80..000000000 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/TokenImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ssem; - -import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol; -import java_cup.runtime.ComplexSymbolFactory.Location; -import net.emustudio.emulib.plugins.compiler.Token; - -public class TokenImpl extends ComplexSymbol implements Token, Symbols { - private final int category; - private final int lexerState; - - public TokenImpl(int id, int category, int lexerState, String text, Location left, Location right) { - super(text, id, left, right); - this.category = category; - this.lexerState = lexerState; - } - - public TokenImpl(int id, int category, int lexerState, String text, Location left, Location right, Object value) { - super(text, id, left, right, value); - this.category = category; - this.lexerState = lexerState; - } - - @Override - public int getID() { - return super.sym; - } - - @Override - public int getType() { - return category; - } - - @Override - public int getLine() { - return getLeft().getLine(); - } - - @Override - public int getColumn() { - return getLeft().getColumn(); - } - - @Override - public int getOffset() { - return getLeft().getOffset(); - } - - @Override - public int getLength() { - return getRight().getOffset() - getLeft().getOffset(); - } - - @Override - public String getErrorString() { - return (getType() == ERROR) ? "Invalid token" : ""; - } - - @Override - public String getText() { - return getName(); - } - - @Override - public int getLexerState() { - return lexerState; - } -} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/CodeGenerator.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/CodeGenerator.java deleted file mode 100644 index 257f15bfa..000000000 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/CodeGenerator.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.emustudio.plugins.compiler.ssem.ast; - -import net.emustudio.emulib.runtime.helpers.NumberUtils; -import net.emustudio.plugins.compiler.ssem.CompileException; -import net.emustudio.plugins.compiler.ssem.SSEMParser; - -import java.nio.ByteBuffer; - -public class CodeGenerator { - private final ByteBuffer code = ByteBuffer.allocate(33 * 4); // one is for start line - - public ByteBuffer generateCode(Program program) { - code.position(0); - code.putInt(program.getStartLine()); - - program.forEach((line, instruction) -> { - code.position(4 * line); - if (instruction.tokenType == SSEMParser.BNUM || instruction.tokenType == SSEMParser.NUM) { - code.putInt(instruction.operand); - } else { - writeInstruction(instruction.getOpcode(), instruction.operand); - } - }); - return code.clear(); - } - - private void writeInstruction(int opcode, int operand) { - if (operand < 0 || operand > 31) { - throw new CompileException("Operand must be between <0, 31>; it was " + operand); - } - - byte address = (byte)(NumberUtils.reverseBits((byte)(operand & 0xFF), 8) & 0xF8); - // 5 bits address + 3 empty bits - code.put(address); - // next: 5 empty bits + 3 bit instruction - code.put((byte)(opcode & 0xFF)); - // 16 empty bits - code.put((byte)0); - code.put((byte)0); - } -} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java index f998ca55c..728f8fb80 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java @@ -5,6 +5,7 @@ import net.jcip.annotations.Immutable; import java.util.Map; +import java.util.Objects; @Immutable public class Instruction { @@ -46,4 +47,17 @@ public int getOpcode() { public String toString() { return String.format("%02d %02d", getOpcode(), operand); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Instruction that = (Instruction) o; + return tokenType == that.tokenType && operand == that.operand; + } + + @Override + public int hashCode() { + return Objects.hash(tokenType, operand); + } } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java index 570467c99..512397e69 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java @@ -2,6 +2,7 @@ import net.emustudio.plugins.compiler.ssem.CompileException; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.function.BiConsumer; @@ -14,7 +15,7 @@ public class Program { public void setStartLine(int startLine) { if (startLineDefined) { - throw new CompileException("Start line is already defined!"); + throw new CompileException("Start line is already defined (at line " + startLine + ")!"); } this.startLine = startLine; startLineDefined = true; @@ -38,6 +39,10 @@ public void forEach(BiConsumer processor) { instructions.forEach(processor); } + public Map getInstructions() { + return Collections.unmodifiableMap(instructions); + } + public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(startLine).append(" start\n"); diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/ASTnode.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/ASTnode.java deleted file mode 100644 index 6f606776b..000000000 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/ASTnode.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ssem.tree; - -public interface ASTnode { - - void accept(ASTvisitor visitor) throws Exception; - -} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/ASTvisitor.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/ASTvisitor.java deleted file mode 100644 index b3d81c50d..000000000 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/ASTvisitor.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ssem.tree; - -public interface ASTvisitor { - - void setCurrentLine(int line); - - void visit(Instruction instruction) throws Exception; - - void visit(Constant constant) throws Exception; - -} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Constant.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Constant.java deleted file mode 100644 index 15fbd5555..000000000 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Constant.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ssem.tree; - -public class Constant implements ASTnode { - private final int number; - - public Constant(int number) { - this.number = number; - } - - @Override - public void accept(ASTvisitor visitor) throws Exception { - visitor.visit(this); - } - - public int getNumber() { - return number; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Constant constant = (Constant) o; - - return number == constant.number; - } - - @Override - public int hashCode() { - return number; - } -} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Instruction.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Instruction.java deleted file mode 100644 index d54fb2329..000000000 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Instruction.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ssem.tree; - -import net.emustudio.plugins.compiler.ssem.CompileException; - -import java.util.Optional; - -public class Instruction implements ASTnode { - public final static byte JMP = 0; // 000 - public final static byte JRP = 4; // 100 - public final static byte LDN = 2; // 010 - public final static byte STO = 6; // 110 - public final static byte SUB = 1; // 001 - public final static byte CMP = 3; // 011 - public final static byte STP = 7; // 111 - private final static String[] INSTRUCTION_STRING = new String[]{ - "JMP", "SUB", "LDN", "CMP", "JRP", null, "STO", "STP" - }; - - private final int opcode; - private final Byte operand; - - private Instruction(int opcode, int operand) throws CompileException { - if (operand > 31 || operand < 0) { - throw new CompileException("Instruction operand must be in range <0,31>!"); - } - this.operand = (byte) (operand & 0xFF); - this.opcode = opcode; - } - - private Instruction(int opcode) { - this.operand = null; - this.opcode = opcode; - } - - public int getOpcode() { - return opcode; - } - - public Optional getOperand() { - return Optional.ofNullable(operand); - } - - public static Instruction jmp(int address) throws CompileException { - return new Instruction(JMP, address); - } - - public static Instruction jrp(int address) throws CompileException { - return new Instruction(JRP, address); - } - - public static Instruction ldn(int address) throws CompileException { - return new Instruction(LDN, address); - } - - public static Instruction sto(int address) throws CompileException { - return new Instruction(STO, address); - } - - public static Instruction sub(int address) throws CompileException { - return new Instruction(SUB, address); - } - - public static Instruction cmp() { - return new Instruction(CMP); - } - - public static Instruction stp() { - return new Instruction(STP); - } - - @Override - public void accept(ASTvisitor visitor) throws Exception { - visitor.visit(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Instruction that = (Instruction) o; - return opcode == that.opcode && Optional.ofNullable(operand).equals(Optional.ofNullable(that.operand)); - } - - @Override - public int hashCode() { - int result = opcode; - result = 31 * result + Optional.ofNullable(operand).hashCode(); - return result; - } - - @Override - public String toString() { - return INSTRUCTION_STRING[opcode] + " " + Optional.ofNullable(operand); - } -} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Program.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Program.java deleted file mode 100644 index f1fbc924f..000000000 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/tree/Program.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ssem.tree; - -import java.util.HashMap; -import java.util.Map; - -public class Program implements ASTnode { - private final Map nodes = new HashMap<>(); - private int startLine = 0; - private int previousLine = 0; - - public void statement(int line, ASTnode node) { - previousLine = line; - nodes.put(line, node); - } - - public void nextLineStarts() { - this.startLine = previousLine; - } - - public int getStartLine() { - return startLine; - } - - @Override - public void accept(ASTvisitor visitor) throws Exception { - for (Map.Entry node : nodes.entrySet()) { - visitor.setCurrentLine(node.getKey()); - node.getValue().accept(visitor); - } - } -} diff --git a/plugins/compiler/as-ssem/src/main/jflex/lexer.jflex b/plugins/compiler/as-ssem/src/main/jflex/lexer.jflex deleted file mode 100644 index 163e3769f..000000000 --- a/plugins/compiler/as-ssem/src/main/jflex/lexer.jflex +++ /dev/null @@ -1,171 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ssem; - -import java_cup.runtime.ComplexSymbolFactory.Location; -import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; -import net.emustudio.emulib.plugins.compiler.Token; -import net.emustudio.emulib.runtime.helpers.NumberUtils; -import net.emustudio.emulib.runtime.helpers.RadixUtils; - -import java.io.IOException; -import java.io.Reader; - -%% - -/* options */ -%class LexerImpl -%cup -%public -%implements LexicalAnalyzer, Symbols -%line -%column -%char -%caseless -%unicode -%type TokenImpl - -%{ - - @Override - public Token getToken() throws IOException { - return next_token(); - } - - @Override - public void reset(Reader in, int yyline, int yychar, int yycolumn) { - yyreset(in); - this.yyline = yyline; - this.yychar = yychar; - this.yycolumn = yycolumn; - } - - @Override - public void reset(Reader in, int line, int offset, int column, int lexerState) { - yyreset(in); - this.yyline = line; - this.yychar = offset; - this.yycolumn = column; - this.zzLexicalState = lexerState; - } - - private TokenImpl token(int id, int category) { - Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); - return new TokenImpl(id, category, zzLexicalState, yytext(), left, right); - } - - private TokenImpl token(int id, int category, Object value) { - Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); - return new TokenImpl(id, category, zzLexicalState, yytext(), left, right, value); - } -%} - -%eofval{ - return token(EOF, Token.TEOF); -%eofval} - -comment = "//"[^\r\n]* -comment2 = "--"[^\r\n]* -comment3 = ";"[^\r\n]* -eol = \r|\n|\r\n -space = [ \t\f]+ -number = \-?[0-9]+ -hexnumber = \-?0x[0-9a-fA-F]+ -binnumber = [01]+ - -%xstate BIN - -%% - - { - /* reserved words */ - "jmp" { return token(JMP, Token.RESERVED); } - "jrp" { return token(JPR, Token.RESERVED); } - "jpr" { return token(JPR, Token.RESERVED); } - "jmr" { return token(JPR, Token.RESERVED); } - "ldn" { return token(LDN, Token.RESERVED); } - "sto" { return token(STO, Token.RESERVED); } - "sub" { return token(SUB, Token.RESERVED); } - "cmp" { return token(CMP, Token.RESERVED); } - "skn" { return token(CMP, Token.RESERVED); } - "stp" { return token(STP, Token.RESERVED); } - "hlt" { return token(STP, Token.RESERVED); } - - /* special */ - "start:" { return token(START, Token.PREPROCESSOR); } - "num" { return token(NUM, Token.PREPROCESSOR); } - "bnum" { - yybegin(BIN); - return token(BNUM, Token.PREPROCESSOR); - } - "bins" { - yybegin(BIN); - return token(BNUM, Token.PREPROCESSOR); - } - - /* comment */ - {comment} { return token(TCOMMENT, Token.COMMENT); } - {comment2} { return token(TCOMMENT, Token.COMMENT); } - {comment3} { return token(TCOMMENT, Token.COMMENT); } - - /* literals */ - {number} { - int num = Integer.parseInt(yytext(), 10); - return token(NUMBER, Token.LITERAL, num); - } - - {hexnumber} { - int num = Integer.decode(yytext()); - return token(NUMBER, Token.LITERAL, num); - } -} - -/* separators */ - {eol} { - return token(SEPARATOR_EOL, Token.SEPARATOR); -} - {space} { /* ignore white spaces */ } - - { - - {binnumber} { - yybegin(YYINITIAL); - - byte[] numberArray = RadixUtils.convertToNumber(yytext(), 2, 4); - int num = NumberUtils.reverseBits( - NumberUtils.readInt( - NumberUtils.toObjectArray(numberArray), NumberUtils.Strategy.LITTLE_ENDIAN - ), 32 - ); - - return token(NUMBER, Token.LITERAL, num); - } - - . { - yybegin(YYINITIAL); - } - -} - -/* error fallback */ -. { - return token(TokenImpl.error, Token.ERROR); -} diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/CodeGeneratorTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/CodeGeneratorTest.java deleted file mode 100644 index f89c3dc8a..000000000 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/CodeGeneratorTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ssem; - -import net.emustudio.plugins.compiler.ssem.tree.Instruction; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; - -import static org.junit.Assert.assertArrayEquals; - -public class CodeGeneratorTest { - - private SeekableByteArrayOutputStream out; - private CodeGenerator codeGenerator; - - @Before - public void setUp() throws Exception { - out = new SeekableByteArrayOutputStream(32); - codeGenerator = new CodeGenerator(out); - } - - @After - public void tearDown() throws Exception { - codeGenerator.close(); - } - - @Test - public void testCMP() throws Exception { - codeGenerator.visit(Instruction.cmp()); - - assertArrayEquals(new byte[]{0, Instruction.CMP, 0, 0}, out.toArray()); - } - - @Test - public void testSTP() throws Exception { - codeGenerator.visit(Instruction.stp()); - - assertArrayEquals(new byte[]{0, Instruction.STP, 0, 0}, out.toArray()); - } - - @Test - public void testJMP() throws Exception { - codeGenerator.visit(Instruction.jmp((byte) 6)); - - assertArrayEquals(new byte[]{0x60, Instruction.JMP, 0, 0}, out.toArray()); - } - - @Test - public void testJRP() throws Exception { - codeGenerator.visit(Instruction.jrp((byte) 23)); - - assertArrayEquals(new byte[]{(byte) 0xE8, Instruction.JRP, 0, 0}, out.toArray()); - } - - @Test - public void testLDN() throws Exception { - codeGenerator.visit(Instruction.ldn((byte) 12)); - - assertArrayEquals(new byte[]{(byte) 0x30, Instruction.LDN, 0, 0}, out.toArray()); - } - - @Test - public void testSTO() throws Exception { - codeGenerator.visit(Instruction.sto((byte) 30)); - - assertArrayEquals(new byte[]{(byte) 0x78, Instruction.STO, 0, 0}, out.toArray()); - } - - @Test - public void testSUB() throws Exception { - codeGenerator.visit(Instruction.sub((byte) 18)); - - assertArrayEquals(new byte[]{(byte) 0x48, Instruction.SUB, 0, 0}, out.toArray()); - } - - private static class SeekableByteArrayOutputStream extends SeekableOutputStream { - private final byte[] array; - private int pos; - private int length; - - public SeekableByteArrayOutputStream(int count) { - this.array = new byte[count]; - } - - @Override - public void seek(int position) throws IOException { - length = Math.max(position, pos); - pos = position; - } - - @Override - public void write(int b) throws IOException { - array[pos] = (byte) b; - pos++; - length = Math.max(pos, length); - } - - public byte[] toArray() { - byte[] tmp = new byte[length]; - System.arraycopy(array, 0, tmp, 0, length); - return tmp; - } - } -} diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java index d43c3320f..1aa6598d6 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java @@ -18,97 +18,89 @@ */ package net.emustudio.plugins.compiler.ssem; -import net.emustudio.emulib.plugins.compiler.Token; -import org.junit.Test; - -import java.io.IOException; -import java.io.StringReader; - -import static org.junit.Assert.assertEquals; - public class LexerTest { - LexerImpl lexer(String tokens) { - return new LexerImpl(new StringReader(tokens)); - } - - @Test - public void testNumberUpperBoundary() throws Exception { - LexerImpl lexer = lexer("31"); - - TokenImpl token = lexer.next_token(); - assertEquals(Token.LITERAL, token.getType()); - assertEquals(31, token.value); - } - - @Test - public void testNumberLowerBoundary() throws Exception { - LexerImpl lexer = lexer("0"); - - TokenImpl token = lexer.next_token(); - assertEquals(Token.LITERAL, token.getType()); - assertEquals(0, token.value); - } - - @Test - public void testNumber() throws Exception { - LexerImpl lexer = lexer("22"); - - TokenImpl token = lexer.next_token(); - assertEquals(Token.LITERAL, token.getType()); - assertEquals(22, token.value); - } - - private void checkInstruction(int id, LexerImpl lexer) throws IOException { - TokenImpl token = lexer.next_token(); - assertEquals(Token.RESERVED, token.getType()); - } - - private void checkInstructionWithOperand(int id, LexerImpl lexer) throws IOException { - checkInstruction(id, lexer); - - TokenImpl token = lexer.next_token(); - assertEquals(Token.LITERAL, token.getType()); - } - - @Test - public void testInstructionsWithOperand() throws Exception { - checkInstructionWithOperand(TokenImpl.JMP, lexer("jmp 12")); - checkInstructionWithOperand(TokenImpl.JPR, lexer("jrp 12")); - checkInstructionWithOperand(TokenImpl.JPR, lexer("jpr 12")); - checkInstructionWithOperand(TokenImpl.JPR, lexer("jmr 12")); - checkInstructionWithOperand(TokenImpl.LDN, lexer("ldn 12")); - checkInstructionWithOperand(TokenImpl.STO, lexer("sto 12")); - checkInstructionWithOperand(TokenImpl.SUB, lexer("sub 12")); - } - - @Test - public void testInstructionsWithoutOperand() throws Exception { - checkInstruction(TokenImpl.CMP, lexer("cmp")); - checkInstruction(TokenImpl.CMP, lexer("skn")); - checkInstruction(TokenImpl.STP, lexer("stp")); - } - - @Test - public void testInstructionInComment() throws Exception { - LexerImpl lexer = lexer("// cmp"); - TokenImpl token = lexer.next_token(); - - assertEquals(Token.COMMENT, token.getType()); - - token = lexer.next_token(); - assertEquals(Token.TEOF, token.getType()); - } - - @Test - public void testBinaryNumber() throws Exception { - LexerImpl lexer = lexer("BNUM 10011011111000101111110000111111\n"); - - TokenImpl token = lexer.next_token(); - assertEquals(Token.PREPROCESSOR, token.getType()); - assertEquals(LexerImpl.BIN, token.getLexerState()); - - token = lexer.next_token(); - assertEquals(Token.LITERAL, token.getType()); - } +// LexerImpl lexer(String tokens) { +// return new LexerImpl(new StringReader(tokens)); +// } +// +// @Test +// public void testNumberUpperBoundary() throws Exception { +// LexerImpl lexer = lexer("31"); +// +// TokenImpl token = lexer.next_token(); +// assertEquals(Token.LITERAL, token.getType()); +// assertEquals(31, token.value); +// } +// +// @Test +// public void testNumberLowerBoundary() throws Exception { +// LexerImpl lexer = lexer("0"); +// +// TokenImpl token = lexer.next_token(); +// assertEquals(Token.LITERAL, token.getType()); +// assertEquals(0, token.value); +// } +// +// @Test +// public void testNumber() throws Exception { +// LexerImpl lexer = lexer("22"); +// +// TokenImpl token = lexer.next_token(); +// assertEquals(Token.LITERAL, token.getType()); +// assertEquals(22, token.value); +// } +// +// private void checkInstruction(int id, LexerImpl lexer) throws IOException { +// TokenImpl token = lexer.next_token(); +// assertEquals(Token.RESERVED, token.getType()); +// } +// +// private void checkInstructionWithOperand(int id, LexerImpl lexer) throws IOException { +// checkInstruction(id, lexer); +// +// TokenImpl token = lexer.next_token(); +// assertEquals(Token.LITERAL, token.getType()); +// } +// +// @Test +// public void testInstructionsWithOperand() throws Exception { +// checkInstructionWithOperand(TokenImpl.JMP, lexer("jmp 12")); +// checkInstructionWithOperand(TokenImpl.JPR, lexer("jrp 12")); +// checkInstructionWithOperand(TokenImpl.JPR, lexer("jpr 12")); +// checkInstructionWithOperand(TokenImpl.JPR, lexer("jmr 12")); +// checkInstructionWithOperand(TokenImpl.LDN, lexer("ldn 12")); +// checkInstructionWithOperand(TokenImpl.STO, lexer("sto 12")); +// checkInstructionWithOperand(TokenImpl.SUB, lexer("sub 12")); +// } +// +// @Test +// public void testInstructionsWithoutOperand() throws Exception { +// checkInstruction(TokenImpl.CMP, lexer("cmp")); +// checkInstruction(TokenImpl.CMP, lexer("skn")); +// checkInstruction(TokenImpl.STP, lexer("stp")); +// } +// +// @Test +// public void testInstructionInComment() throws Exception { +// LexerImpl lexer = lexer("// cmp"); +// TokenImpl token = lexer.next_token(); +// +// assertEquals(Token.COMMENT, token.getType()); +// +// token = lexer.next_token(); +// assertEquals(Token.TEOF, token.getType()); +// } +// +// @Test +// public void testBinaryNumber() throws Exception { +// LexerImpl lexer = lexer("BNUM 10011011111000101111110000111111\n"); +// +// TokenImpl token = lexer.next_token(); +// assertEquals(Token.PREPROCESSOR, token.getType()); +// assertEquals(LexerImpl.BIN, token.getLexerState()); +// +// token = lexer.next_token(); +// assertEquals(Token.LITERAL, token.getType()); +// } } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java index 9c25cd6af..d7cd3fc71 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java @@ -18,21 +18,6 @@ */ package net.emustudio.plugins.compiler.ssem; -import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.plugins.compiler.ssem.tree.ASTvisitor; -import net.emustudio.plugins.compiler.ssem.tree.Constant; -import net.emustudio.plugins.compiler.ssem.tree.Instruction; -import net.emustudio.plugins.compiler.ssem.tree.Program; -import org.junit.Test; - -import java.io.StringReader; -import java.util.Arrays; -import java.util.Deque; -import java.util.LinkedList; - -import static org.junit.Assert.*; - public class ParserTest { // PASS: @@ -56,131 +41,131 @@ public class ParserTest { // 01 STP 01 STP - - private ParserImpl program(String program) { - return new ParserImpl( - new LexerImpl(new StringReader(program)), - new CompilerImpl(0, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE) - ); - } - - @Test - public void testInstructions() throws Exception { - ParserImpl parser = program( - "0 cmp // comment\n" + - "1 stp\n" + - "2 jmp 22\n" + - "3 jrp 0\n" + - "4 ldn 31\n" + - "5 sto 10\n" + - "6 sub 15\n" - ); - - Program program = (Program) parser.parse().value; - assertFalse(parser.hasSyntaxErrors()); - - Deque expectedInstructions = new LinkedList<>(Arrays.asList( - Instruction.cmp(), - Instruction.stp(), - Instruction.jmp((byte) 22), - Instruction.jrp((byte) 0), - Instruction.ldn((byte) 31), - Instruction.sto((byte) 10), - Instruction.sub((byte) 15) - )); - program.accept(new ASTvisitor() { - - @Override - public void setCurrentLine(int line) { - - } - - @Override - public void visit(Instruction instruction) { - assertEquals(expectedInstructions.removeFirst(), instruction); - } - - @Override - public void visit(Constant constant) { - fail("Didn't expect a constant"); - } - }); - } - - - @Test(expected = Exception.class) - public void testInstructionWithoutEOL() throws Exception { - ParserImpl parser = program("0 jmp 1"); - - parser.parse(); - } - - @Test - public void testInstructionWithoutProperArgument() throws Exception { - ParserImpl parser = program("0 jmp ffff\n"); - - parser.parse(); - assertTrue(parser.hasSyntaxErrors()); - } - - @Test - public void testConstantIsTranslatedCorrectly() throws Exception { - ParserImpl parser = program( - "0 NUM 5\n" - ); - - Program program = (Program) parser.parse().value; - - assertFalse(parser.hasSyntaxErrors()); - assertConstant(program, 5); - } - - @Test - public void testHexadecimalConstant() throws Exception { - ParserImpl parser = program( - "0 NUM -0x20\n" - ); - - Program program = (Program) parser.parse().value; - assertFalse(parser.hasSyntaxErrors()); - - assertConstant(program, -32); - } - - @Test - public void testStartingPointIsAccepted() throws Exception { - ParserImpl parser = program("0 jmp 1\nstart:\n3 cmp\n"); - - Program program = (Program) parser.parse().value; - assertFalse(parser.hasSyntaxErrors()); - assertEquals(3, program.getStartLine()); - } - - @Test - public void testIndexOfLineThenCommentWorks() throws Exception { - ParserImpl parser = program("0 --comment\n"); - - Program program = (Program) parser.parse().value; - assertFalse(parser.hasSyntaxErrors()); - } - - private void assertConstant(Program program, int value) throws Exception { - program.accept(new ASTvisitor() { - - @Override - public void setCurrentLine(int line) { - - } - - @Override - public void visit(Instruction instruction) { - fail("Didn't expect an instruction"); - } - - @Override - public void visit(Constant constant) { - assertEquals(new Constant(value), constant); - } - }); - } +// +// private ParserImpl program(String program) { +// return new ParserImpl( +// new LexerImpl(new StringReader(program)), +// new CompilerImpl(0, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE) +// ); +// } +// +// @Test +// public void testInstructions() throws Exception { +// ParserImpl parser = program( +// "0 cmp // comment\n" + +// "1 stp\n" + +// "2 jmp 22\n" + +// "3 jrp 0\n" + +// "4 ldn 31\n" + +// "5 sto 10\n" + +// "6 sub 15\n" +// ); +// +// Program program = (Program) parser.parse().value; +// assertFalse(parser.hasSyntaxErrors()); +// +// Deque expectedInstructions = new LinkedList<>(Arrays.asList( +// Instruction.cmp(), +// Instruction.stp(), +// Instruction.jmp((byte) 22), +// Instruction.jrp((byte) 0), +// Instruction.ldn((byte) 31), +// Instruction.sto((byte) 10), +// Instruction.sub((byte) 15) +// )); +// program.accept(new ASTvisitor() { +// +// @Override +// public void setCurrentLine(int line) { +// +// } +// +// @Override +// public void visit(Instruction instruction) { +// assertEquals(expectedInstructions.removeFirst(), instruction); +// } +// +// @Override +// public void visit(Constant constant) { +// fail("Didn't expect a constant"); +// } +// }); +// } +// +// +// @Test(expected = Exception.class) +// public void testInstructionWithoutEOL() throws Exception { +// ParserImpl parser = program("0 jmp 1"); +// +// parser.parse(); +// } +// +// @Test +// public void testInstructionWithoutProperArgument() throws Exception { +// ParserImpl parser = program("0 jmp ffff\n"); +// +// parser.parse(); +// assertTrue(parser.hasSyntaxErrors()); +// } +// +// @Test +// public void testConstantIsTranslatedCorrectly() throws Exception { +// ParserImpl parser = program( +// "0 NUM 5\n" +// ); +// +// Program program = (Program) parser.parse().value; +// +// assertFalse(parser.hasSyntaxErrors()); +// assertConstant(program, 5); +// } +// +// @Test +// public void testHexadecimalConstant() throws Exception { +// ParserImpl parser = program( +// "0 NUM -0x20\n" +// ); +// +// Program program = (Program) parser.parse().value; +// assertFalse(parser.hasSyntaxErrors()); +// +// assertConstant(program, -32); +// } +// +// @Test +// public void testStartingPointIsAccepted() throws Exception { +// ParserImpl parser = program("0 jmp 1\nstart:\n3 cmp\n"); +// +// Program program = (Program) parser.parse().value; +// assertFalse(parser.hasSyntaxErrors()); +// assertEquals(3, program.getStartLine()); +// } +// +// @Test +// public void testIndexOfLineThenCommentWorks() throws Exception { +// ParserImpl parser = program("0 --comment\n"); +// +// Program program = (Program) parser.parse().value; +// assertFalse(parser.hasSyntaxErrors()); +// } +// +// private void assertConstant(Program program, int value) throws Exception { +// program.accept(new ASTvisitor() { +// +// @Override +// public void setCurrentLine(int line) { +// +// } +// +// @Override +// public void visit(Instruction instruction) { +// fail("Didn't expect an instruction"); +// } +// +// @Override +// public void visit(Constant constant) { +// assertEquals(new Constant(value), constant); +// } +// }); +// } } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java index b7de30ba2..1d6ed5ad4 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java @@ -27,6 +27,7 @@ import java.nio.file.StandardOpenOption; import java.util.List; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; public class RunnerTest { @@ -44,7 +45,10 @@ public void testCommandLine() throws Exception { List lines = Files.readAllLines(outputFile.toPath()); assertEquals(1, lines.size()); - assertEquals("\150\6\0\0", lines.get(0)); + byte[] expected = new byte[33 * 4]; // 32 words of 32 bits + 4 bytes for startLine + expected[4] = 104; + expected[5] = 6; + assertArrayEquals(expected, lines.get(0).getBytes()); } @Test diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/CodeGeneratorTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/CodeGeneratorTest.java deleted file mode 100644 index d1dd0ae41..000000000 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/CodeGeneratorTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.emustudio.plugins.compiler.ssem.ast; - -import net.emustudio.plugins.compiler.ssem.SSEMLexer; -import net.emustudio.plugins.compiler.ssem.SSEMParser; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.ConsoleErrorListener; -import org.antlr.v4.runtime.tree.ParseTree; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class CodeGeneratorTest { - - @Test - public void testSomething() { - String program = - "10 start\n" + - "10 stp"; - - SSEMLexer lexer = new SSEMLexer(CharStreams.fromString(program)); - lexer.addErrorListener(new ConsoleErrorListener()); - - CommonTokenStream tokens = new CommonTokenStream(lexer); - SSEMParser parser = new SSEMParser(tokens); - - parser.addErrorListener(new ConsoleErrorListener()); - ParseTree tree = parser.start(); - - ProgramParser programParser = new ProgramParser(); - programParser.visit(tree); - - Program programx = programParser.getProgram(); - System.out.println(programx); - - CodeGenerator code = new CodeGenerator(); - ByteBuffer buffer = code.generateCode(programx); - - printProgram(buffer); - } - - - private void printProgram(ByteBuffer program) { - byte[] array = program.array(); - for (int i = 0; i < 32; i++) { - for (int j = 0; j < 4; j++) { - System.out.printf("%02d ", array[i * 4 + j]); - } - System.out.println(); - } - } -} diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java new file mode 100644 index 000000000..19acc3894 --- /dev/null +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java @@ -0,0 +1,109 @@ +package net.emustudio.plugins.compiler.ssem.ast; + +import net.emustudio.plugins.compiler.ssem.SSEMLexer; +import net.emustudio.plugins.compiler.ssem.SSEMParser; +import org.antlr.v4.runtime.ANTLRErrorStrategy; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTree; +import org.junit.Test; + +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class ProgramParserTest { + + @Test + public void testParseEmptyLine() { + Program program = parseProgram(""); + assertTrue(program.getInstructions().isEmpty()); + } + + @Test + public void testParseLineNumberOnly() { + Program program = parseProgram("10"); + assertTrue(program.getInstructions().isEmpty()); + } + + @Test + public void testParseHexLineNumber() { + Program program = parseProgram("0x10"); + assertTrue(program.getInstructions().isEmpty()); + } + + @Test + public void testParseInstructions() { + Program program = parseProgram( + "01 LDN 29\n" + + "-- 01 ldn 30\n" + + "; 01 LDN 30\n" + + "# 01 ldn 30\n" + + "04 SUB 30 --comment1\n" + + "05 STO 31 # comment2\n" + + "06 STP ; comment3\n" + + "07 CMP\n" + + "08 NUM 4\n" + + "09 BNUM 100\n\n\n" + ); + Map instructions = program.getInstructions(); + assertEquals(7, instructions.size()); + assertEquals(new Instruction(SSEMParser.LDN, 29), instructions.get(1)); + assertEquals(new Instruction(SSEMParser.SUB, 30), instructions.get(4)); + assertEquals(new Instruction(SSEMParser.STO, 31), instructions.get(5)); + assertEquals(new Instruction(SSEMParser.STP), instructions.get(6)); + assertEquals(new Instruction(SSEMParser.CMP), instructions.get(7)); + assertEquals(new Instruction(SSEMParser.NUM, 4), instructions.get(8)); + assertEquals(new Instruction(SSEMParser.BNUM, 4), instructions.get(9)); + } + + @Test + public void testParseError() { + String program = "001 B INS 011010"; + SSEMLexer lexer = new SSEMLexer(CharStreams.fromString(program)); + List tokens = new ArrayList<>(); + while (!lexer._hitEOF) { + tokens.add(lexer.nextToken()); + } + System.out.println(tokens); + } + + private void printProgram(ByteBuffer program) { + byte[] array = program.array(); + for (int i = 0; i < 32; i++) { + for (int j = 0; j < 4; j++) { + System.out.printf("%02d ", array[i * 4 + j]); + } + System.out.println(); + } + } + + private Program parseProgram(String program) { + return parse(createParser(program)); + } + + private Program parseProgram(String program, ANTLRErrorStrategy errorHandler) { + SSEMParser parser = createParser(program); + parser.setErrorHandler(errorHandler); + return parse(parser); + } + + private SSEMParser createParser(String program) { + SSEMLexer lexer = new SSEMLexer(CharStreams.fromString(program)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + return new SSEMParser(tokens); + } + + private Program parse(SSEMParser parser) { + ParseTree tree = parser.start(); + ProgramParser programParser = new ProgramParser(); + programParser.visit(tree); + return programParser.getProgram(); + } +} diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/AutomaticEmulation.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/AutomaticEmulation.java index 5a3df5105..f36268ff0 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/AutomaticEmulation.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/AutomaticEmulation.java @@ -75,7 +75,7 @@ private void snapshot() { Byte[][] memorySnapshot = new Byte[memory.getSize() / 4][4]; for (int i = 0; i < memorySnapshot.length; i++) { - Byte[] word = memory.readWord(i * 4); + Byte[] word = memory.read(i * 4, 4); System.arraycopy(word, 0, memorySnapshot[i], 0, 4); } diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java index 00b66575d..372cbc0ac 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java @@ -55,7 +55,7 @@ void reset(int startingPos) { } CPU.RunState step() { - Byte[] instruction = memory.readWord(CI.addAndGet(4)); + Byte[] instruction = memory.read(CI.addAndGet(4), 4); byte line = (byte)(NumberUtils.reverseBits(instruction[0] & 0b11111000, 8)); int lineAddress = line * 4; @@ -102,14 +102,14 @@ private int readLineAddress(int lineAddress) { } private int readInt(int line) { - Byte[] word = memory.readWord(line); + Byte[] word = memory.read(line, 4); return NumberUtils.readInt(word, Strategy.REVERSE_BITS); } private void writeInt(int lineAddress, int value) { Byte[] word = new Byte[4]; NumberUtils.writeInt(value, word, Strategy.REVERSE_BITS); - memory.writeWord(lineAddress, word); + memory.write(lineAddress, word); } CPU.RunState run() { @@ -143,7 +143,7 @@ CPU.RunState run() { } private void fakeStep() { - Byte[] instruction = memory.readWord(CI.get()); + Byte[] instruction = memory.read(CI.get(), 4); int line = NumberUtils.reverseBits(instruction[0], 8); int opcode = instruction[1] & 3; diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java index 3e09697df..2e26178ed 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java @@ -62,9 +62,9 @@ public void internalStateChanged() { txtBinCI.setText(formatBinary(ci)); try { - Byte[] mCI = memory.readWord(ci); + Byte[] mCI = memory.read(ci, 4); byte line = (byte) NumberUtils.reverseBits(mCI[0] & 0b11111000, 8); - Byte[] mLine = memory.readWord(line * 4); + Byte[] mLine = memory.read(line * 4, 4); txtMCI.setText(String.format("%08x", NumberUtils.readInt(mCI, NumberUtils.Strategy.REVERSE_BITS))); txtLine.setText(String.format("%02x", line)); diff --git a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java index 187a73f7b..a3c225155 100644 --- a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java +++ b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java @@ -46,7 +46,6 @@ public void setUp() { CpuImpl cpuImpl = new CpuImpl(0L, applicationApi, PluginSettings.UNAVAILABLE); memoryStub = new ByteMemoryStub(NumberUtils.Strategy.REVERSE_BITS); - memoryStub.setWordCellsCount(4); engine = new EmulatorEngine(memoryStub, cpuImpl); } @@ -81,7 +80,7 @@ public void testAddition() { engine.reset(0); assertEquals(CPU.RunState.STATE_STOPPED_NORMAL, engine.run()); - assertEquals(8, NumberUtils.readInt(memoryStub.readWord(31 * 4), memoryStub.getWordReadingStrategy())); + assertEquals(8, NumberUtils.readInt(memoryStub.read(31 * 4, 4), memoryStub.getWordReadingStrategy())); } @Test(timeout = 500) diff --git a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java index 59671dc20..08784183e 100644 --- a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java +++ b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java @@ -50,7 +50,8 @@ public void memoryChanged(int bytePosition) { displayPanel.reset(memory); } else { int row = bytePosition / 4; - displayPanel.writeRow(memory.readWord(bytePosition), row); + int rowBytePosition = row * 4; + displayPanel.writeRow(memory.read(rowBytePosition, 4), row); } } diff --git a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java index 3a94c30f4..577d213e6 100644 --- a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java +++ b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java @@ -63,7 +63,7 @@ void clear() { void reset(MemoryContext memory) { clear(); for (int i = 0; i < 4 * 32; i += 4) { - writeRow(memory.readWord(i), i / 4); + writeRow(memory.read(i, 4), i / 4); } } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java index a3b854c5d..a5ac44388 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java @@ -28,7 +28,11 @@ public class MemoryContextImpl extends AbstractMemoryContext { public static final int NUMBER_OF_CELLS = 32 * 4; // byte type is atomic in JVM memory model - private final byte[] memory = new byte[NUMBER_OF_CELLS]; + private final Byte[] memory = new Byte[NUMBER_OF_CELLS]; + + public MemoryContextImpl() { + Arrays.fill(memory, (byte) 0); + } @Override public void clear() { @@ -42,23 +46,23 @@ public Byte read(int from) { } @Override - public Byte[] readWord(int from) { - return new Byte[]{memory[from], memory[from + 1], memory[from + 2], memory[from + 3]}; + public Byte[] read(int from, int count) { + Byte[] result = new Byte[count]; + System.arraycopy(memory, from, result, 0, count); + return result; } @Override - public void write(int to, Byte val) { - memory[to] = val; + public void write(int to, Byte value) { + memory[to] = value; notifyMemoryChanged(to); } @Override - public void writeWord(int to, Byte[] cells) { - int i = 0; - for (byte cell : cells) { - memory[to + i] = cell; + public void write(int to, Byte[] values, int count) { + System.arraycopy(values, 0, memory, to, count); + for (int i = 0; i < values.length; i++) { notifyMemoryChanged(to + i); - i++; } } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java index bc6fc76e6..ca4574695 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java @@ -106,7 +106,7 @@ private byte[] readLineBits(Byte[] line) { @Override public Object getValueAt(int rowIndex, int columnIndex) { try { - Byte[] row = memory.readWord(rowIndex * 4); + Byte[] row = memory.read(rowIndex * 4, 4); int value = NumberUtils.readInt(row, NumberUtils.Strategy.REVERSE_BITS); switch (columnIndex) { @@ -129,7 +129,7 @@ public Object getValueAt(int rowIndex, int columnIndex) { public void setValueAt(Object aValue, int rowIndex, int columnIndex) { if (isCellEditable(rowIndex, columnIndex)) { try { - Byte[] row = memory.readWord(rowIndex * 4); + Byte[] row = memory.read(rowIndex * 4, 4); String str = String.valueOf(aValue); if (columnIndex == COLUMN_HEX_VALUE) { @@ -139,7 +139,7 @@ public void setValueAt(Object aValue, int rowIndex, int columnIndex) { } else if (columnIndex >= 0 && columnIndex < 33) { writeBit(str, columnIndex, row); } - memory.writeWord(rowIndex * 4, row); + memory.write(rowIndex * 4, row); fireTableCellUpdated(rowIndex, columnIndex); } catch (Exception e) { diff --git a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryContextImplTest.java b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryContextImplTest.java index e1a37dc33..42142365b 100644 --- a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryContextImplTest.java +++ b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryContextImplTest.java @@ -19,7 +19,6 @@ package net.emustudio.plugins.memory.ssem; import net.emustudio.emulib.plugins.memory.Memory; -import net.emustudio.plugins.memory.ssem.MemoryContextImpl; import org.junit.Test; import static org.easymock.EasyMock.*; @@ -113,17 +112,17 @@ public void testClassTypeIsByte() { } @Test - public void testReadWordIsSupported() { - assertArrayEquals(new Byte[]{0, 0, 0, 0}, new MemoryContextImpl().readWord(0)); + public void testReadArrayIsSupported() { + assertArrayEquals(new Byte[]{0, 0, 0, 0}, new MemoryContextImpl().read(0, 4)); } @Test - public void testWriteWordIsSupported() { + public void testWriteArrayIsSupported() { MemoryContextImpl mem = new MemoryContextImpl(); Byte[] row = new Byte[]{1, 2, 3, 4}; - mem.writeWord(0, row); + mem.write(0, row); - assertArrayEquals(row, mem.readWord(0)); + assertArrayEquals(row, mem.read(0, 4)); } } diff --git a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryImplTest.java b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryImplTest.java index a9c34a3d3..58052d0da 100644 --- a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryImplTest.java +++ b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryImplTest.java @@ -22,8 +22,6 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.plugins.memory.ssem.MemoryContextImpl; -import net.emustudio.plugins.memory.ssem.MemoryImpl; import org.junit.Before; import org.junit.Test; diff --git a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModelTest.java b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModelTest.java index dee07e25d..0db2143a9 100644 --- a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModelTest.java +++ b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModelTest.java @@ -66,8 +66,8 @@ public void testSetBinaryValueCellsMemoryWrite() { Byte[] row = new Byte[]{1, 2, 3, 4}; Byte[] modified = new Byte[]{1, 2, (byte) 0x83, 4}; // 16th bit set to 1, but original 3 wasnt'modified - expect(memoryContext.readWord(10 * 4)).andReturn(row); - memoryContext.writeWord(eq(10 * 4), aryEq(modified)); + expect(memoryContext.read(10 * 4, 4)).andReturn(row); + memoryContext.write(eq(10 * 4), aryEq(modified)); expectLastCall().once(); replay(memoryContext); @@ -84,8 +84,8 @@ public void testSetHexValueCellsMemoryWrite() { Byte[] row = new Byte[]{1, 2, 3, 4}; Byte[] modified = new Byte[]{(byte) 0xFF, 0, 0, 0}; - expect(memoryContext.readWord(10 * 4)).andReturn(row); - memoryContext.writeWord(eq(10 * 4), aryEq(modified)); + expect(memoryContext.read(10 * 4, 4)).andReturn(row); + memoryContext.write(eq(10 * 4), aryEq(modified)); expectLastCall().once(); replay(memoryContext); @@ -102,8 +102,8 @@ public void testSetCharValueCellsMemoryWrite() { Byte[] row = new Byte[]{1, 2, 3, 4}; Byte[] modified = new Byte[]{0x56, (byte) 0xf6, 0x16, (byte) 0x86}; - expect(memoryContext.readWord(10 * 4)).andReturn(row); - memoryContext.writeWord(eq(10 * 4), aryEq(modified)); + expect(memoryContext.read(10 * 4, 4)).andReturn(row); + memoryContext.write(eq(10 * 4), aryEq(modified)); expectLastCall().once(); replay(memoryContext); @@ -135,7 +135,7 @@ public void testGetValueCallsMemoryRead() { Byte[] row = new Byte[4]; NumberUtils.writeInt(0x61686F6A, row, NumberUtils.Strategy.REVERSE_BITS); - expect(memoryContext.readWord(10 * 4)).andReturn(row).anyTimes(); + expect(memoryContext.read(10 * 4, 4)).andReturn(row).anyTimes(); replay(memoryContext); MemoryTableModel model = new MemoryTableModel(memoryContext); @@ -149,7 +149,7 @@ public void testGetValueCallsMemoryRead() { public void testGetValueAtInvalidIndexDoesNotThrow() { MemoryContext memoryContext = createMock(MemoryContext.class); - expect(memoryContext.readWord(-4)).andThrow(new IndexOutOfBoundsException()).times(2); + expect(memoryContext.read(-4, 4)).andThrow(new IndexOutOfBoundsException()).times(2); replay(memoryContext); MemoryTableModel model = new MemoryTableModel(memoryContext); diff --git a/settings.gradle b/settings.gradle index 17a699ac6..f2f585d25 100644 --- a/settings.gradle +++ b/settings.gradle @@ -21,30 +21,30 @@ rootProject.name = 'emuStudio' include ':application' -include ':plugins:compiler:as-8080' +//include ':plugins:compiler:as-8080' include ':plugins:compiler:as-ssem' -include ':plugins:compiler:as-z80' -include ':plugins:compiler:brainc-brainduck' -include ':plugins:compiler:ramc-ram' -include ':plugins:compiler:raspc-rasp' +//include ':plugins:compiler:as-z80' +//include ':plugins:compiler:brainc-brainduck' +//include ':plugins:compiler:ramc-ram' +//include ':plugins:compiler:raspc-rasp' -include ':plugins:cpu:8080-cpu' -include ':plugins:cpu:brainduck-cpu' -include ':plugins:cpu:ram-cpu' -include ':plugins:cpu:rasp-cpu' +//include ':plugins:cpu:8080-cpu' +//include ':plugins:cpu:brainduck-cpu' +//include ':plugins:cpu:ram-cpu' +//include ':plugins:cpu:rasp-cpu' include ':plugins:cpu:ssem-cpu' -include ':plugins:cpu:z80-cpu' +//include ':plugins:cpu:z80-cpu' -include ':plugins:device:88-dcdd' -include ':plugins:device:88-sio' -include ':plugins:device:abstract-tape' -include ':plugins:device:adm3A-terminal' -include ':plugins:device:brainduck-terminal' -include ':plugins:device:simhPseudo-z80' +//include ':plugins:device:88-dcdd' +//include ':plugins:device:88-sio' +//include ':plugins:device:abstract-tape' +//include ':plugins:device:adm3A-terminal' +//include ':plugins:device:brainduck-terminal' +//include ':plugins:device:simhPseudo-z80' include ':plugins:device:ssem-display' -include ':plugins:memory:brainduck-mem' -include ':plugins:memory:ram-mem' -include ':plugins:memory:rasp-mem' +//include ':plugins:memory:brainduck-mem' +//include ':plugins:memory:ram-mem' +//include ':plugins:memory:rasp-mem' include ':plugins:memory:ssem-mem' -include ':plugins:memory:byte-mem' +//include ':plugins:memory:byte-mem' From e0059f0519614380174ac0b9aff88fce74fca366 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 22 May 2021 08:17:30 +0200 Subject: [PATCH 028/314] [#201] SSEM Lexer tests --- .../application/gui/editor/RTokenMaker.java | 23 +-- .../as-ssem/src/main/antlr/SSEMLexer.g4 | 2 + .../plugins/compiler/ssem/CompilerImpl.java | 74 ++----- .../compiler/ssem/LexicalAnalyzerImpl.java | 80 ++++++++ .../plugins/compiler/ssem/LexerTest.java | 187 ++++++++++-------- .../compiler/ssem/ast/ProgramParserTest.java | 1 + 6 files changed, 217 insertions(+), 150 deletions(-) create mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/LexicalAnalyzerImpl.java diff --git a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java index 00ac9e3b5..a9b46418a 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java @@ -1,8 +1,7 @@ package net.emustudio.application.gui.editor; import net.emustudio.emulib.plugins.compiler.Compiler; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.Lexer; +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; import org.fife.ui.rsyntaxtextarea.AbstractTokenMaker; import org.fife.ui.rsyntaxtextarea.Token; import org.fife.ui.rsyntaxtextarea.TokenMap; @@ -20,20 +19,17 @@ public RTokenMaker(Compiler compiler) { @Override public Token getTokenList(Segment text, int initialTokenType, int startOffset) { resetTokenList(); - Lexer lexer = compiler.createLexer(CharStreams.fromString(Objects.requireNonNull(text).toString())); + LexicalAnalyzer lexer = compiler.createLexer((Objects.requireNonNull(text).toString())); int previousEnd = -1; int previousStartOffset = -1; - while (!lexer._hitEOF) { + for (net.emustudio.emulib.plugins.compiler.Token token : lexer) { try { - org.antlr.v4.runtime.Token token = lexer.nextToken(); - int emuStudioType = compiler.convertLexerTokenType(token.getType()); - int tokenMakerType = getTokenMakerType(emuStudioType); + int tokenMakerType = getTokenMakerType(token.getType()); - String tokenText = token.getText(); - int tokenStartIndex = token.getStartIndex(); - int tokenLength = tokenText.length() - 1; - if (token.getType() == org.antlr.v4.runtime.Token.EOF) { + int tokenStartIndex = token.getOffset(); + int tokenLength = token.getLength() - 1; + if (token.getType() == net.emustudio.emulib.plugins.compiler.Token.EOF) { tokenLength = 0; } @@ -54,7 +50,8 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { previousStartOffset = tokenStartOffset; addToken(text, start, end, tokenMakerType, tokenStartOffset); - } catch (Exception ignore) { + } catch (Exception ignored) { + } } return firstToken; @@ -87,7 +84,7 @@ private static int getTokenMakerType(int emuStudioTokenType) { return Token.ANNOTATION; case net.emustudio.emulib.plugins.compiler.Token.ERROR: return Token.ERROR_IDENTIFIER; - case net.emustudio.emulib.plugins.compiler.Token.TEOF: + case net.emustudio.emulib.plugins.compiler.Token.EOF: return Token.NULL; } return Token.WHITESPACE; diff --git a/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 b/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 index 7cc2c6965..264491539 100644 --- a/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 +++ b/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 @@ -51,7 +51,9 @@ BNUM: ((B N U M) | (B I N S)) -> pushMode(BIN); // literals NUMBER: [\-]? [0-9]+; HEXNUMBER: [\-]? ('0x'|'0X') [0-9a-fA-F]+; +ERROR : .; mode BIN; BWS : (' ' | '\t') -> channel(HIDDEN); BinaryNumber: [01]+ -> popMode; +BERROR : .; diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java index c7d2a8d6a..9bee5d8ac 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java @@ -22,8 +22,8 @@ import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; import net.emustudio.emulib.plugins.annotations.PluginRoot; import net.emustudio.emulib.plugins.compiler.AbstractCompiler; +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; import net.emustudio.emulib.plugins.compiler.SourceFileExtension; -import net.emustudio.emulib.plugins.compiler.Token; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextNotFoundException; @@ -38,7 +38,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.*; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.*; @@ -77,11 +80,6 @@ public void initialize() { }); } - @Override - public void parse(Parser parser) { - ((SSEMParser) parser).start(); - } - @Override public boolean compile(String inputFileName, String outputFileName) { notifyCompileStart(); @@ -161,53 +159,9 @@ public boolean compile(String inputFileName) { } @Override - public SSEMLexer createLexer(CharStream input) { - SSEMLexer lexer = new SSEMLexer(input); - lexer.removeErrorListeners(); - return lexer; - } - - @Override - public SSEMParser createParser(TokenStream tokenStream) { - SSEMParser parser = new SSEMParser(tokenStream); - parser.removeErrorListeners(); - return parser; - } - - @Override - public int convertLexerTokenType(int tokenType) { - switch (tokenType) { - case SSEMLexer.COMMENT: - return Token.COMMENT; - case SSEMLexer.EOL: - case SSEMLexer.WS: - case SSEMLexer.BWS: - return Token.WHITESPACE; - case SSEMLexer.JMP: - case SSEMLexer.JRP: - case SSEMLexer.JPR: - case SSEMLexer.JMR: - case SSEMLexer.LDN: - case SSEMLexer.STO: - case SSEMLexer.SKN: - case SSEMLexer.SUB: - case SSEMLexer.CMP: - case SSEMLexer.STP: - case SSEMLexer.HLT: - return Token.RESERVED; - case SSEMLexer.START: - return Token.LABEL; - case SSEMLexer.NUM: - case SSEMLexer.BNUM: - return Token.PREPROCESSOR; - case SSEMLexer.NUMBER: - case SSEMLexer.HEXNUMBER: - case SSEMLexer.BinaryNumber: - return Token.LITERAL; - case SSEMLexer.EOF: - return Token.TEOF; - } - return Token.ERROR; + public LexicalAnalyzer createLexer(String s) { + SSEMLexer lexer = createLexer(CharStreams.fromString(s)); + return new LexicalAnalyzerImpl(lexer); } @Override @@ -235,6 +189,18 @@ public String getDescription() { return "Assembler of SSEM computer language"; } + private SSEMLexer createLexer(CharStream input) { + SSEMLexer lexer = new SSEMLexer(input); + lexer.removeErrorListeners(); + return lexer; + } + + private SSEMParser createParser(TokenStream tokenStream) { + SSEMParser parser = new SSEMParser(tokenStream); + parser.removeErrorListeners(); + return parser; + } + private Optional getResourceBundle() { try { return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.compiler.ssem.version")); diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/LexicalAnalyzerImpl.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/LexicalAnalyzerImpl.java new file mode 100644 index 000000000..7b4ed8317 --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/LexicalAnalyzerImpl.java @@ -0,0 +1,80 @@ +package net.emustudio.plugins.compiler.ssem; + +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; +import net.emustudio.emulib.plugins.compiler.Token; + +import java.util.Objects; + +public class LexicalAnalyzerImpl implements LexicalAnalyzer { + private final SSEMLexer lexer; + + public LexicalAnalyzerImpl(SSEMLexer lexer) { + this.lexer = Objects.requireNonNull(lexer); + } + + @Override + public Token nextToken() { + org.antlr.v4.runtime.Token token = lexer.nextToken(); + return new Token() { + @Override + public int getType() { + return convertLexerTokenType(token.getType()); + } + + @Override + public int getOffset() { + return token.getStartIndex(); + } + + @Override + public int getLength() { + return token.getText().length(); + } + + @Override + public String getText() { + return token.getText(); + } + }; + } + + @Override + public boolean isAtEOF() { + return lexer._hitEOF; + } + + private int convertLexerTokenType(int tokenType) { + switch (tokenType) { + case SSEMLexer.COMMENT: + return Token.COMMENT; + case SSEMLexer.EOL: + case SSEMLexer.WS: + case SSEMLexer.BWS: + return Token.WHITESPACE; + case SSEMLexer.JMP: + case SSEMLexer.JRP: + case SSEMLexer.JPR: + case SSEMLexer.JMR: + case SSEMLexer.LDN: + case SSEMLexer.STO: + case SSEMLexer.SKN: + case SSEMLexer.SUB: + case SSEMLexer.CMP: + case SSEMLexer.STP: + case SSEMLexer.HLT: + return Token.RESERVED; + case SSEMLexer.START: + return Token.LABEL; + case SSEMLexer.NUM: + case SSEMLexer.BNUM: + return Token.PREPROCESSOR; + case SSEMLexer.NUMBER: + case SSEMLexer.HEXNUMBER: + case SSEMLexer.BinaryNumber: + return Token.LITERAL; + case SSEMLexer.EOF: + return Token.EOF; + } + return Token.ERROR; + } +} diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java index 1aa6598d6..680d606a7 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java @@ -18,89 +18,110 @@ */ package net.emustudio.plugins.compiler.ssem; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.Token; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import static org.junit.Assert.assertEquals; + public class LexerTest { -// LexerImpl lexer(String tokens) { -// return new LexerImpl(new StringReader(tokens)); -// } -// -// @Test -// public void testNumberUpperBoundary() throws Exception { -// LexerImpl lexer = lexer("31"); -// -// TokenImpl token = lexer.next_token(); -// assertEquals(Token.LITERAL, token.getType()); -// assertEquals(31, token.value); -// } -// -// @Test -// public void testNumberLowerBoundary() throws Exception { -// LexerImpl lexer = lexer("0"); -// -// TokenImpl token = lexer.next_token(); -// assertEquals(Token.LITERAL, token.getType()); -// assertEquals(0, token.value); -// } -// -// @Test -// public void testNumber() throws Exception { -// LexerImpl lexer = lexer("22"); -// -// TokenImpl token = lexer.next_token(); -// assertEquals(Token.LITERAL, token.getType()); -// assertEquals(22, token.value); -// } -// -// private void checkInstruction(int id, LexerImpl lexer) throws IOException { -// TokenImpl token = lexer.next_token(); -// assertEquals(Token.RESERVED, token.getType()); -// } -// -// private void checkInstructionWithOperand(int id, LexerImpl lexer) throws IOException { -// checkInstruction(id, lexer); -// -// TokenImpl token = lexer.next_token(); -// assertEquals(Token.LITERAL, token.getType()); -// } -// -// @Test -// public void testInstructionsWithOperand() throws Exception { -// checkInstructionWithOperand(TokenImpl.JMP, lexer("jmp 12")); -// checkInstructionWithOperand(TokenImpl.JPR, lexer("jrp 12")); -// checkInstructionWithOperand(TokenImpl.JPR, lexer("jpr 12")); -// checkInstructionWithOperand(TokenImpl.JPR, lexer("jmr 12")); -// checkInstructionWithOperand(TokenImpl.LDN, lexer("ldn 12")); -// checkInstructionWithOperand(TokenImpl.STO, lexer("sto 12")); -// checkInstructionWithOperand(TokenImpl.SUB, lexer("sub 12")); -// } -// -// @Test -// public void testInstructionsWithoutOperand() throws Exception { -// checkInstruction(TokenImpl.CMP, lexer("cmp")); -// checkInstruction(TokenImpl.CMP, lexer("skn")); -// checkInstruction(TokenImpl.STP, lexer("stp")); -// } -// -// @Test -// public void testInstructionInComment() throws Exception { -// LexerImpl lexer = lexer("// cmp"); -// TokenImpl token = lexer.next_token(); -// -// assertEquals(Token.COMMENT, token.getType()); -// -// token = lexer.next_token(); -// assertEquals(Token.TEOF, token.getType()); -// } -// -// @Test -// public void testBinaryNumber() throws Exception { -// LexerImpl lexer = lexer("BNUM 10011011111000101111110000111111\n"); -// -// TokenImpl token = lexer.next_token(); -// assertEquals(Token.PREPROCESSOR, token.getType()); -// assertEquals(LexerImpl.BIN, token.getLexerState()); -// -// token = lexer.next_token(); -// assertEquals(Token.LITERAL, token.getType()); -// } + @Test + public void testParseError() { + assertTokenTypes("B I", SSEMLexer.ERROR, SSEMLexer.WS, SSEMLexer.ERROR, SSEMLexer.EOF); + assertTokenTypes("BINS ha", SSEMLexer.BNUM, SSEMLexer.BWS, SSEMLexer.BERROR, SSEMLexer.BERROR, SSEMLexer.EOF); + } + + @Test + public void testParseReservedWords() { + assertTokenTypesForCaseVariations("jmp", SSEMLexer.JMP, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("jrp", SSEMLexer.JRP, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("jpr", SSEMLexer.JPR, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("jmr", SSEMLexer.JMR, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("ldn", SSEMLexer.LDN, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("sto", SSEMLexer.STO, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("sub", SSEMLexer.SUB, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("cmp", SSEMLexer.CMP, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("skn", SSEMLexer.SKN, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("stp", SSEMLexer.STP, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("hlt", SSEMLexer.HLT, SSEMLexer.EOF); + } + + @Test + public void testParsePreprocessor() { + assertTokenTypesForCaseVariations("start", SSEMLexer.START, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("num", SSEMLexer.NUM, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("bnum", SSEMLexer.BNUM, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("bins", SSEMLexer.BNUM, SSEMLexer.EOF); + } + + @Test + public void testParseWhitespaces() { + assertTokenTypes(" ", SSEMLexer.WS, SSEMLexer.EOF); + assertTokenTypes("\t", SSEMLexer.WS, SSEMLexer.EOF); + assertTokenTypes("\n", SSEMLexer.EOL, SSEMLexer.EOF); + assertTokenTypes("", SSEMLexer.EOF); + } + + @Test + public void testParseComments() { + assertTokenTypes("-- comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); + assertTokenTypes("# comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); + assertTokenTypes("// comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); + assertTokenTypes("; comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); + } + + @Test + public void testLiterals() { + assertTokenTypes("10", SSEMLexer.NUMBER, SSEMLexer.EOF); + assertTokenTypes("0xAF", SSEMLexer.HEXNUMBER, SSEMLexer.EOF); + assertTokenTypes("BINS 1010", SSEMLexer.BNUM, SSEMLexer.BWS, SSEMLexer.BinaryNumber, SSEMLexer.EOF); + } + + private List getTokens(String variation) { + SSEMLexer lexer = new SSEMLexer(CharStreams.fromString(variation)); + CommonTokenStream stream = new CommonTokenStream(lexer); + stream.fill(); + return stream.getTokens(); + } + + private void assertTokenTypes(String variation, int... expectedTypes) { + List tokens = getTokens(variation); + assertTokenTypes(tokens, expectedTypes); + } + + private void assertTokenTypes(List tokens, int... expectedTypes) { + assertEquals(expectedTypes.length, tokens.size()); + for (int i = 0; i < expectedTypes.length; i++) { + Token token = tokens.get(i); + assertEquals(expectedTypes[i], token.getType()); + } + } + + private void assertTokenTypesForCaseVariations(String base, int... expectedTypes) { + Random r = new Random(); + List variations = new ArrayList<>(); + variations.add(base); + variations.add(base.toLowerCase()); + variations.add(base.toUpperCase()); + for (int i = 0; i < 5; i++) { + byte[] chars = base.getBytes(); + for (int j = 0; j < base.length(); j++) { + if (r.nextBoolean()) { + chars[j] = Character.valueOf((char)chars[j]).toString().toUpperCase().getBytes()[0]; + } else { + chars[j] = Character.valueOf((char)chars[j]).toString().toLowerCase().getBytes()[0]; + } + } + variations.add(new String(chars)); + } + for (String variation : variations) { + assertTokenTypes(variation, expectedTypes); + } + } } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java index 19acc3894..5156ca047 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java @@ -67,6 +67,7 @@ public void testParseInstructions() { public void testParseError() { String program = "001 B INS 011010"; SSEMLexer lexer = new SSEMLexer(CharStreams.fromString(program)); + lexer.removeErrorListeners(); List tokens = new ArrayList<>(); while (!lexer._hitEOF) { tokens.add(lexer.nextToken()); From fec61d017952d9a5cab714861ae36f7ad8b0d917 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 22 May 2021 09:18:06 +0200 Subject: [PATCH 029/314] [#201] SSEM: Add more parser tests --- .../plugins/compiler/ssem/CodeGenerator.java | 4 - .../compiler/ssem/ast/Instruction.java | 9 +- .../plugins/compiler/ssem/LexerTest.java | 52 +--- .../plugins/compiler/ssem/ParserTest.java | 275 +++++++----------- .../plugins/compiler/ssem/Utils.java | 93 ++++++ .../compiler/ssem/ast/ProgramParserTest.java | 110 ------- 6 files changed, 208 insertions(+), 335 deletions(-) create mode 100644 plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java delete mode 100644 plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java index 527408e58..bb669fa8b 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java @@ -24,10 +24,6 @@ public ByteBuffer generateCode(Program program) { } private void writeInstruction(int opcode, int operand) { - if (operand < 0 || operand > 31) { - throw new CompileException("Operand must be between <0, 31>; it was " + operand); - } - byte address = (byte)(NumberUtils.reverseBits((byte)(operand & 0xFF), 8) & 0xF8); // 5 bits address + 3 empty bits code.put(address); diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java index 728f8fb80..3b6a5b68d 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java @@ -25,17 +25,16 @@ public class Instruction { public final int operand; public Instruction(int tokenType) { - if (!OPCODES.containsKey(tokenType)) { - throw new CompileException("Unknown instruction"); - } - this.tokenType = tokenType; - this.operand = 0; + this(tokenType, 0); } public Instruction(int tokenType, int operand) { if (!OPCODES.containsKey(tokenType)) { throw new CompileException("Unknown instruction"); } + if (operand < 0 || operand > 31) { + throw new CompileException("Operand must be between <0, 31>; it was " + operand); + } this.tokenType = tokenType; this.operand = operand; } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java index 680d606a7..535aa83e4 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java @@ -18,16 +18,10 @@ */ package net.emustudio.plugins.compiler.ssem; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.Token; import org.junit.Test; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import static org.junit.Assert.assertEquals; +import static net.emustudio.plugins.compiler.ssem.Utils.assertTokenTypes; +import static net.emustudio.plugins.compiler.ssem.Utils.assertTokenTypesForCaseVariations; public class LexerTest { @@ -82,46 +76,4 @@ public void testLiterals() { assertTokenTypes("0xAF", SSEMLexer.HEXNUMBER, SSEMLexer.EOF); assertTokenTypes("BINS 1010", SSEMLexer.BNUM, SSEMLexer.BWS, SSEMLexer.BinaryNumber, SSEMLexer.EOF); } - - private List getTokens(String variation) { - SSEMLexer lexer = new SSEMLexer(CharStreams.fromString(variation)); - CommonTokenStream stream = new CommonTokenStream(lexer); - stream.fill(); - return stream.getTokens(); - } - - private void assertTokenTypes(String variation, int... expectedTypes) { - List tokens = getTokens(variation); - assertTokenTypes(tokens, expectedTypes); - } - - private void assertTokenTypes(List tokens, int... expectedTypes) { - assertEquals(expectedTypes.length, tokens.size()); - for (int i = 0; i < expectedTypes.length; i++) { - Token token = tokens.get(i); - assertEquals(expectedTypes[i], token.getType()); - } - } - - private void assertTokenTypesForCaseVariations(String base, int... expectedTypes) { - Random r = new Random(); - List variations = new ArrayList<>(); - variations.add(base); - variations.add(base.toLowerCase()); - variations.add(base.toUpperCase()); - for (int i = 0; i < 5; i++) { - byte[] chars = base.getBytes(); - for (int j = 0; j < base.length(); j++) { - if (r.nextBoolean()) { - chars[j] = Character.valueOf((char)chars[j]).toString().toUpperCase().getBytes()[0]; - } else { - chars[j] = Character.valueOf((char)chars[j]).toString().toLowerCase().getBytes()[0]; - } - } - variations.add(new String(chars)); - } - for (String variation : variations) { - assertTokenTypes(variation, expectedTypes); - } - } } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java index d7cd3fc71..aba9f4bc1 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java @@ -1,171 +1,114 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ package net.emustudio.plugins.compiler.ssem; +import net.emustudio.plugins.compiler.ssem.ast.Program; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.ssem.Utils.assertInstructions; +import static net.emustudio.plugins.compiler.ssem.Utils.parseProgram; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + public class ParserTest { - // PASS: - // -- COMMENT - // - // 01 STP -- COMMENT - - // FAIL: - // STP - - // PASS: - // 01 - - // PASS: - // -- - - // PASS: - // - - // FAIL: - // 01 STP 01 STP - - -// -// private ParserImpl program(String program) { -// return new ParserImpl( -// new LexerImpl(new StringReader(program)), -// new CompilerImpl(0, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE) -// ); -// } -// -// @Test -// public void testInstructions() throws Exception { -// ParserImpl parser = program( -// "0 cmp // comment\n" + -// "1 stp\n" + -// "2 jmp 22\n" + -// "3 jrp 0\n" + -// "4 ldn 31\n" + -// "5 sto 10\n" + -// "6 sub 15\n" -// ); -// -// Program program = (Program) parser.parse().value; -// assertFalse(parser.hasSyntaxErrors()); -// -// Deque expectedInstructions = new LinkedList<>(Arrays.asList( -// Instruction.cmp(), -// Instruction.stp(), -// Instruction.jmp((byte) 22), -// Instruction.jrp((byte) 0), -// Instruction.ldn((byte) 31), -// Instruction.sto((byte) 10), -// Instruction.sub((byte) 15) -// )); -// program.accept(new ASTvisitor() { -// -// @Override -// public void setCurrentLine(int line) { -// -// } -// -// @Override -// public void visit(Instruction instruction) { -// assertEquals(expectedInstructions.removeFirst(), instruction); -// } -// -// @Override -// public void visit(Constant constant) { -// fail("Didn't expect a constant"); -// } -// }); -// } -// -// -// @Test(expected = Exception.class) -// public void testInstructionWithoutEOL() throws Exception { -// ParserImpl parser = program("0 jmp 1"); -// -// parser.parse(); -// } -// -// @Test -// public void testInstructionWithoutProperArgument() throws Exception { -// ParserImpl parser = program("0 jmp ffff\n"); -// -// parser.parse(); -// assertTrue(parser.hasSyntaxErrors()); -// } -// -// @Test -// public void testConstantIsTranslatedCorrectly() throws Exception { -// ParserImpl parser = program( -// "0 NUM 5\n" -// ); -// -// Program program = (Program) parser.parse().value; -// -// assertFalse(parser.hasSyntaxErrors()); -// assertConstant(program, 5); -// } -// -// @Test -// public void testHexadecimalConstant() throws Exception { -// ParserImpl parser = program( -// "0 NUM -0x20\n" -// ); -// -// Program program = (Program) parser.parse().value; -// assertFalse(parser.hasSyntaxErrors()); -// -// assertConstant(program, -32); -// } -// -// @Test -// public void testStartingPointIsAccepted() throws Exception { -// ParserImpl parser = program("0 jmp 1\nstart:\n3 cmp\n"); -// -// Program program = (Program) parser.parse().value; -// assertFalse(parser.hasSyntaxErrors()); -// assertEquals(3, program.getStartLine()); -// } -// -// @Test -// public void testIndexOfLineThenCommentWorks() throws Exception { -// ParserImpl parser = program("0 --comment\n"); -// -// Program program = (Program) parser.parse().value; -// assertFalse(parser.hasSyntaxErrors()); -// } -// -// private void assertConstant(Program program, int value) throws Exception { -// program.accept(new ASTvisitor() { -// -// @Override -// public void setCurrentLine(int line) { -// -// } -// -// @Override -// public void visit(Instruction instruction) { -// fail("Didn't expect an instruction"); -// } -// -// @Override -// public void visit(Constant constant) { -// assertEquals(new Constant(value), constant); -// } -// }); -// } + @Test + public void testParseEmptyLine() { + Program program = parseProgram(""); + assertTrue(program.getInstructions().isEmpty()); + } + + @Test + public void testParseLineNumberOnly() { + Program program = parseProgram("10"); + assertTrue(program.getInstructions().isEmpty()); + } + + @Test + public void testParseHexLineNumber() { + Program program = parseProgram("0x10"); + assertTrue(program.getInstructions().isEmpty()); + } + + @Test + public void testLineThenCommentWorks() { + Program program = parseProgram("0x10 -- comment"); + assertTrue(program.getInstructions().isEmpty()); + } + + @Test + public void testCommentOnly() { + Program program = parseProgram("-- comment"); + assertTrue(program.getInstructions().isEmpty()); + } + + @Test + public void testEolOnly() { + Program program = parseProgram("\n"); + assertTrue(program.getInstructions().isEmpty()); + } + + @Test + public void testParseInstructions() { + Program program = parseProgram( + "01 LDN 0x1F\n" + + "-- 01 ldn 30\n" + + "; 01 LDN 30\n" + + "# 01 ldn 30\n" + + "04 SUB 30 --comment1\n" + + "05 STO 31 # comment2\n" + + "06 STP ; comment3\n" + + "07 CMP\n" + + "08 NUM 4\n" + + "09 BNUM 100\n\n\n" + ); + assertInstructions( + program, + new Utils.ParsedInstruction(1, SSEMParser.LDN, 0x1F), + new Utils.ParsedInstruction(4, SSEMParser.SUB, 30), + new Utils.ParsedInstruction(5, SSEMParser.STO, 31), + new Utils.ParsedInstruction(6, SSEMParser.STP, 0), + new Utils.ParsedInstruction(7, SSEMParser.CMP, 0), + new Utils.ParsedInstruction(8, SSEMParser.NUM, 4), + new Utils.ParsedInstruction(9, SSEMParser.BNUM, 4) + ); + } + + @Test + public void testStartingPointIsAccepted() { + Program program = parseProgram( + "02 start\n" + + "01 LDN 21\n" + + "02 STP" + ); + assertEquals(2, program.getStartLine()); + } + + @Test(expected = CompileException.class) + public void testOperandBounds() { + parseProgram("01 ldn 99\n"); + } + + @Test(expected = CompileException.class) + public void testLineBounds() { + parseProgram("99 ldn 1\n"); + } + + @Test(expected = CompileException.class) + public void testParseInstructionWithoutOperand() { + parseProgram("01 ldn"); + } + + @Test(expected = CompileException.class) + public void testParseInstructionWithWrongArgument() { + parseProgram("01 ldn fff"); + } + + @Test(expected = CompileException.class) + public void testParseInstructionWithoutLine() { + parseProgram("stp"); + } + + @Test(expected = CompileException.class) + public void testParseTwoInstructionsWithoutEol() { + parseProgram("01 stp 02 stp"); + } } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java new file mode 100644 index 000000000..9abbea0ab --- /dev/null +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java @@ -0,0 +1,93 @@ +package net.emustudio.plugins.compiler.ssem; + +import net.emustudio.plugins.compiler.ssem.ast.Instruction; +import net.emustudio.plugins.compiler.ssem.ast.Program; +import net.emustudio.plugins.compiler.ssem.ast.ProgramParser; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTree; + +import java.util.*; + +import static org.junit.Assert.assertEquals; + +public class Utils { + + public static List getTokens(String variation) { + SSEMLexer lexer = new SSEMLexer(CharStreams.fromString(variation)); + CommonTokenStream stream = new CommonTokenStream(lexer); + stream.fill(); + return stream.getTokens(); + } + + public static Program parseProgram(String program) { + SSEMLexer lexer = new SSEMLexer(CharStreams.fromString(program)); + lexer.removeErrorListeners(); + CommonTokenStream tokens = new CommonTokenStream(lexer); + SSEMParser parser = new SSEMParser(tokens); + parser.removeErrorListeners(); + parser.addErrorListener(new ParserErrorListener()); + + ParseTree tree = parser.start(); + ProgramParser programParser = new ProgramParser(); + programParser.visit(tree); + return programParser.getProgram(); + } + + + public static void assertTokenTypes(String variation, int... expectedTypes) { + List tokens = getTokens(variation); + assertTokenTypes(tokens, expectedTypes); + } + + public static void assertTokenTypes(List tokens, int... expectedTypes) { + assertEquals(expectedTypes.length, tokens.size()); + for (int i = 0; i < expectedTypes.length; i++) { + Token token = tokens.get(i); + assertEquals(expectedTypes[i], token.getType()); + } + } + + public static void assertTokenTypesForCaseVariations(String base, int... expectedTypes) { + Random r = new Random(); + List variations = new ArrayList<>(); + variations.add(base); + variations.add(base.toLowerCase()); + variations.add(base.toUpperCase()); + for (int i = 0; i < 5; i++) { + byte[] chars = base.getBytes(); + for (int j = 0; j < base.length(); j++) { + if (r.nextBoolean()) { + chars[j] = Character.valueOf((char)chars[j]).toString().toUpperCase().getBytes()[0]; + } else { + chars[j] = Character.valueOf((char)chars[j]).toString().toLowerCase().getBytes()[0]; + } + } + variations.add(new String(chars)); + } + for (String variation : variations) { + assertTokenTypes(variation, expectedTypes); + } + } + + public static void assertInstructions(Program program, ParsedInstruction... instructions) { + Map pinstr = program.getInstructions(); + assertEquals(instructions.length, pinstr.size()); + for (ParsedInstruction instruction : instructions) { + assertEquals(new Instruction(instruction.opcode, instruction.operand), pinstr.get(instruction.line)); + } + } + + public static class ParsedInstruction { + public final int line; + public final int opcode; + public final int operand; + + public ParsedInstruction(int line, int opcode, int operand) { + this.line = line; + this.opcode = opcode; + this.operand = operand; + } + } +} diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java deleted file mode 100644 index 5156ca047..000000000 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParserTest.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.emustudio.plugins.compiler.ssem.ast; - -import net.emustudio.plugins.compiler.ssem.SSEMLexer; -import net.emustudio.plugins.compiler.ssem.SSEMParser; -import org.antlr.v4.runtime.ANTLRErrorStrategy; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.tree.ParseTree; -import org.junit.Test; - -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class ProgramParserTest { - - @Test - public void testParseEmptyLine() { - Program program = parseProgram(""); - assertTrue(program.getInstructions().isEmpty()); - } - - @Test - public void testParseLineNumberOnly() { - Program program = parseProgram("10"); - assertTrue(program.getInstructions().isEmpty()); - } - - @Test - public void testParseHexLineNumber() { - Program program = parseProgram("0x10"); - assertTrue(program.getInstructions().isEmpty()); - } - - @Test - public void testParseInstructions() { - Program program = parseProgram( - "01 LDN 29\n" + - "-- 01 ldn 30\n" + - "; 01 LDN 30\n" + - "# 01 ldn 30\n" + - "04 SUB 30 --comment1\n" + - "05 STO 31 # comment2\n" + - "06 STP ; comment3\n" + - "07 CMP\n" + - "08 NUM 4\n" + - "09 BNUM 100\n\n\n" - ); - Map instructions = program.getInstructions(); - assertEquals(7, instructions.size()); - assertEquals(new Instruction(SSEMParser.LDN, 29), instructions.get(1)); - assertEquals(new Instruction(SSEMParser.SUB, 30), instructions.get(4)); - assertEquals(new Instruction(SSEMParser.STO, 31), instructions.get(5)); - assertEquals(new Instruction(SSEMParser.STP), instructions.get(6)); - assertEquals(new Instruction(SSEMParser.CMP), instructions.get(7)); - assertEquals(new Instruction(SSEMParser.NUM, 4), instructions.get(8)); - assertEquals(new Instruction(SSEMParser.BNUM, 4), instructions.get(9)); - } - - @Test - public void testParseError() { - String program = "001 B INS 011010"; - SSEMLexer lexer = new SSEMLexer(CharStreams.fromString(program)); - lexer.removeErrorListeners(); - List tokens = new ArrayList<>(); - while (!lexer._hitEOF) { - tokens.add(lexer.nextToken()); - } - System.out.println(tokens); - } - - private void printProgram(ByteBuffer program) { - byte[] array = program.array(); - for (int i = 0; i < 32; i++) { - for (int j = 0; j < 4; j++) { - System.out.printf("%02d ", array[i * 4 + j]); - } - System.out.println(); - } - } - - private Program parseProgram(String program) { - return parse(createParser(program)); - } - - private Program parseProgram(String program, ANTLRErrorStrategy errorHandler) { - SSEMParser parser = createParser(program); - parser.setErrorHandler(errorHandler); - return parse(parser); - } - - private SSEMParser createParser(String program) { - SSEMLexer lexer = new SSEMLexer(CharStreams.fromString(program)); - CommonTokenStream tokens = new CommonTokenStream(lexer); - return new SSEMParser(tokens); - } - - private Program parse(SSEMParser parser) { - ParseTree tree = parser.start(); - ProgramParser programParser = new ProgramParser(); - programParser.visit(tree); - return programParser.getProgram(); - } -} From 504ba20d75590aeed4e6cf1897f3ba55f4cd1bf2 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 22 May 2021 09:22:27 +0200 Subject: [PATCH 030/314] [#201] SSEM: Remove default parser listeners --- .../java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java index 9bee5d8ac..dd94d6886 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java @@ -91,10 +91,12 @@ public boolean compile(String inputFileName, String outputFileName) { try (Reader reader = new FileReader(inputFileName)) { Lexer lexer = createLexer(CharStreams.fromReader(reader)); + lexer.removeErrorListeners(); lexer.addErrorListener(new ParserErrorListener()); CommonTokenStream tokens = new CommonTokenStream(lexer); SSEMParser parser = createParser(tokens); + parser.removeErrorListeners(); parser.addErrorListener(new ParserErrorListener()); ParseTree tree = parser.start(); From 60212b010dd9e6d49c59c3d51cec7e876e09cf66 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 29 May 2021 10:45:15 +0200 Subject: [PATCH 031/314] [#201] Fix SSEM compiler issues + set caret to error line --- .../gui/actions/CompileAction.java | 9 ++- .../application/gui/editor/Editor.java | 9 ++- .../application/gui/editor/REditor.java | 23 +++--- .../application/gui/editor/RTokenMaker.java | 2 +- .../as-ssem/src/main/antlr/SSEMLexer.g4 | 17 +---- .../as-ssem/src/main/antlr/SSEMParser.g4 | 1 + .../plugins/compiler/ssem/CodeGenerator.java | 4 +- .../compiler/ssem/CompileException.java | 6 +- .../plugins/compiler/ssem/CompilerChecks.java | 36 ++++++++++ .../compiler/ssem/LexicalAnalyzerImpl.java | 17 +++-- .../compiler/ssem/ParserErrorListener.java | 2 +- .../plugins/compiler/ssem/Position.java | 28 ++++++++ .../plugins/compiler/ssem/Runner.java | 4 +- .../{CompilerImpl.java => SSEMCompiler.java} | 24 +++---- .../compiler/ssem/ast/Instruction.java | 31 ++++---- .../plugins/compiler/ssem/ast/Program.java | 25 +++---- .../compiler/ssem/ast/ProgramParser.java | 70 +++++++++++++++---- .../plugins/compiler/ssem/LexerTest.java | 8 +-- .../plugins/compiler/ssem/ParserTest.java | 45 ++++++++++++ ...lerImplTest.java => SSEMCompilerTest.java} | 6 +- .../plugins/compiler/ssem/Utils.java | 5 +- 21 files changed, 257 insertions(+), 115 deletions(-) create mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java create mode 100644 plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/Position.java rename plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/{CompilerImpl.java => SSEMCompiler.java} (92%) rename plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/{CompilerImplTest.java => SSEMCompilerTest.java} (96%) diff --git a/application/src/main/java/net/emustudio/application/gui/actions/CompileAction.java b/application/src/main/java/net/emustudio/application/gui/actions/CompileAction.java index cc7a96880..30b0e394b 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/CompileAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/CompileAction.java @@ -25,7 +25,11 @@ public class CompileAction extends AbstractAction { public CompileAction(VirtualComputer computer, Dialogs dialogs, Editor editor, Supplier runState, JTextArea compilerOutput, Runnable updateTitle) { - super("Compile", new ImageIcon(CompileAction.class.getResource("/net/emustudio/application/gui/dialogs/compile.png"))); + super("Compile", + new ImageIcon(Objects.requireNonNull( + CompileAction.class.getResource("/net/emustudio/application/gui/dialogs/compile.png") + )) + ); this.computer = Objects.requireNonNull(computer); this.dialogs = Objects.requireNonNull(dialogs); @@ -48,6 +52,7 @@ public void onStart() { @Override public void onMessage(CompilerMessage message) { compilerOutput.append(message.getFormattedMessage() + "\n"); + editor.setPosition(message.getLine(), message.getColumn()); } @Override @@ -77,7 +82,7 @@ public void actionPerformed(ActionEvent actionEvent) { computer.getCPU().ifPresent(cpu -> cpu.reset(programStart)); } catch (Exception e) { - compilerOutput.append("Could not compile file: " + e.toString() + "\n"); + compilerOutput.append("Could not compile file: " + e + "\n"); } }); } diff --git a/application/src/main/java/net/emustudio/application/gui/editor/Editor.java b/application/src/main/java/net/emustudio/application/gui/editor/Editor.java index a9e5f3841..65f41a481 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/Editor.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/Editor.java @@ -31,10 +31,15 @@ public interface Editor extends SearchListener { Component getView(); - JComponent getErrorStrip(); - void grabFocus(); + /** + * Set caret position. + * @param line line (if -1 does nothing) + * @param column column (if -1 only sets the line) + */ + void setPosition(int line, int column); + Optional getCurrentFile(); } diff --git a/application/src/main/java/net/emustudio/application/gui/editor/REditor.java b/application/src/main/java/net/emustudio/application/gui/editor/REditor.java index b6dc37adb..213c30355 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/REditor.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/REditor.java @@ -13,6 +13,7 @@ import org.slf4j.LoggerFactory; import javax.swing.*; +import javax.swing.text.BadLocationException; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -33,7 +34,6 @@ public class REditor implements Editor { private final TextEditorPane textPane = new TextEditorPane(RTextArea.INSERT_MODE, true); private final RTextScrollPane scrollPane = new RTextScrollPane(textPane); - private final ErrorStrip errorStrip; private final Dialogs dialogs; private final List sourceFileExtensions; @@ -94,8 +94,6 @@ public void keyTyped(KeyEvent e) { }); setupSyntaxTheme(); - errorStrip = new ErrorStrip(textPane); - if (compiler != null) { sourceFileExtensions = compiler.getSourceFileExtensions(); RTokenMakerWrapper unusedButUseful = new RTokenMakerWrapper(compiler); @@ -114,11 +112,6 @@ public Component getView() { return scrollPane; } - @Override - public JComponent getErrorStrip() { - return errorStrip; - } - @Override public void clearMarkedOccurences() { SearchEngine.find(textPane, new SearchContext()); @@ -129,6 +122,20 @@ public void grabFocus() { textPane.grabFocus(); } + @Override + public void setPosition(int line, int column) { + if (line >= 0) { + try { + int position = textPane.getLineStartOffset(Math.max(0, line - 1)); + if (column >= 0) { + position += column; + } + textPane.setCaretPosition(position); + } catch (BadLocationException ignored) { + } + } + } + @Override public boolean isDirty() { return textPane.isDirty(); diff --git a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java index a9b46418a..ebc1d1583 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java @@ -28,7 +28,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { int tokenMakerType = getTokenMakerType(token.getType()); int tokenStartIndex = token.getOffset(); - int tokenLength = token.getLength() - 1; + int tokenLength = token.getText().length() - 1; if (token.getType() == net.emustudio.emulib.plugins.compiler.Token.EOF) { tokenLength = 0; } diff --git a/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 b/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 index 264491539..9c4ee847b 100644 --- a/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 +++ b/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 @@ -1,12 +1,5 @@ lexer grammar SSEMLexer; -tokens { - COMMENT, - EOL, WS, BWS, - JMP, JRP, JPR, JMR, LDN, STO, SUB, CMP, SKN, STP, HLT, - START, NUM, BNUM, - NUMBER, HEXNUMBER, BinaryNumber -} WS : (' ' | '\t') -> channel(HIDDEN); COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]*; @@ -32,16 +25,12 @@ fragment I: [iI]; // reserved JMP: J M P; -JRP: J R P; -JPR: J P R; -JMR: J M R; +JPR: (J P R) | (J R P) | (J M R); LDN: L D N; STO: S T O; SUB: S U B; -CMP: C M P; -SKN: S K N; -STP: S T P; -HLT: H L T; +CMP: (C M P) | (S K N); +STP: (S T P) | (H L T); // preprocessor START: S T A R T; diff --git a/plugins/compiler/as-ssem/src/main/antlr/SSEMParser.g4 b/plugins/compiler/as-ssem/src/main/antlr/SSEMParser.g4 index 6ec95b724..1a6d9c8f7 100644 --- a/plugins/compiler/as-ssem/src/main/antlr/SSEMParser.g4 +++ b/plugins/compiler/as-ssem/src/main/antlr/SSEMParser.g4 @@ -18,6 +18,7 @@ comment: COMMENT? ; statement: instr=START + | instr=JMP operand=(NUMBER|HEXNUMBER) | instr=JPR operand=(NUMBER|HEXNUMBER) | instr=LDN operand=(NUMBER|HEXNUMBER) | instr=STO operand=(NUMBER|HEXNUMBER) diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java index bb669fa8b..4da428894 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java @@ -15,7 +15,7 @@ public ByteBuffer generateCode(Program program) { program.forEach((line, instruction) -> { code.position(4 * (line + 1)); if (instruction.tokenType == SSEMParser.BNUM || instruction.tokenType == SSEMParser.NUM) { - code.putInt(instruction.operand); + code.putInt((int)instruction.operand); } else { writeInstruction(instruction.getOpcode(), instruction.operand); } @@ -23,7 +23,7 @@ public ByteBuffer generateCode(Program program) { return code.clear(); } - private void writeInstruction(int opcode, int operand) { + private void writeInstruction(int opcode, long operand) { byte address = (byte)(NumberUtils.reverseBits((byte)(operand & 0xFF), 8) & 0xF8); // 5 bits address + 3 empty bits code.put(address); diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java index 4852689a3..8ef5f7ae1 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompileException.java @@ -22,11 +22,7 @@ public class CompileException extends RuntimeException { final int line; final int column; - public CompileException(String message) { - this(message, -1, -1); - } - - public CompileException(String message, int line, int column) { + public CompileException(int line, int column, String message) { super(message); this.line = line; this.column = column; diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java new file mode 100644 index 000000000..2c8cdf2f0 --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java @@ -0,0 +1,36 @@ +package net.emustudio.plugins.compiler.ssem; + +public class CompilerChecks { + + public static void checkStartLineDefined(boolean defined, Position pos, int startLine) { + if (defined) { + throw new CompileException(pos.line, pos.column, "Start line is already defined (at line " + startLine + ")!"); + } + } + + public static void checkLineOutOfBounds(Position pos, int line) { + if (line < 0 || line > 31) { + throw new CompileException(pos.line, pos.column, "Line number is out of bounds <0;31>: " + line); + } + } + + public static void checkDuplicateLineDefinition(boolean duplicate, Position pos, int line) { + if (duplicate) { + throw new CompileException(pos.line, pos.column, "Duplicate line definition: " + line); + } + } + + public static void checkUnknownInstruction(boolean unknown, Position pos) { + if (unknown) { + throw new CompileException(pos.line, pos.column, "Unrecognized instruction"); + } + } + + public static void checkOperandOutOfBounds(Position pos, int tokenType, long operand) { + if (tokenType != SSEMLexer.BNUM && tokenType != SSEMLexer.NUM && (operand < 0 || operand > 31)) { + throw new CompileException( + pos.line, pos.column, "Operand must be between <0, 31>; it was " + operand + ); + } + } +} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/LexicalAnalyzerImpl.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/LexicalAnalyzerImpl.java index 7b4ed8317..a78fc3baa 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/LexicalAnalyzerImpl.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/LexicalAnalyzerImpl.java @@ -2,7 +2,10 @@ import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; import net.emustudio.emulib.plugins.compiler.Token; +import org.antlr.v4.runtime.CharStreams; +import java.io.IOException; +import java.io.InputStream; import java.util.Objects; public class LexicalAnalyzerImpl implements LexicalAnalyzer { @@ -26,11 +29,6 @@ public int getOffset() { return token.getStartIndex(); } - @Override - public int getLength() { - return token.getText().length(); - } - @Override public String getText() { return token.getText(); @@ -43,6 +41,11 @@ public boolean isAtEOF() { return lexer._hitEOF; } + @Override + public void reset(InputStream inputStream) throws IOException { + lexer.setInputStream(CharStreams.fromStream(inputStream)); + } + private int convertLexerTokenType(int tokenType) { switch (tokenType) { case SSEMLexer.COMMENT: @@ -52,16 +55,12 @@ private int convertLexerTokenType(int tokenType) { case SSEMLexer.BWS: return Token.WHITESPACE; case SSEMLexer.JMP: - case SSEMLexer.JRP: case SSEMLexer.JPR: - case SSEMLexer.JMR: case SSEMLexer.LDN: case SSEMLexer.STO: - case SSEMLexer.SKN: case SSEMLexer.SUB: case SSEMLexer.CMP: case SSEMLexer.STP: - case SSEMLexer.HLT: return Token.RESERVED; case SSEMLexer.START: return Token.LABEL; diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ParserErrorListener.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ParserErrorListener.java index 1f29a19d5..c86d38379 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ParserErrorListener.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ParserErrorListener.java @@ -13,6 +13,6 @@ public void syntaxError( int charPositionInLine, String msg, RecognitionException e) { - throw new CompileException(msg, line, charPositionInLine); + throw new CompileException(line, charPositionInLine, msg); } } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/Position.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/Position.java new file mode 100644 index 000000000..f54a2e591 --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/Position.java @@ -0,0 +1,28 @@ +package net.emustudio.plugins.compiler.ssem; + +import net.jcip.annotations.Immutable; +import org.antlr.v4.runtime.Token; + +@Immutable +public class Position { + public final static Position UNKNOWN = new Position(-1, -1); + + public final int line; + public final int column; + + public Position(int line, int column) { + this.line = line; + this.column = column; + } + + public static Position of(Token token) { + if (token == null) { + return UNKNOWN; + } + return new Position(token.getLine(), token.getCharPositionInLine()); + } + + public static Position unknown() { + return UNKNOWN; + } +} diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/Runner.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/Runner.java index a5ac08f60..6b02d6ed7 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/Runner.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/Runner.java @@ -38,7 +38,7 @@ public static void main(String... args) { printHelp(); return; } else if (arg.equals("--version") || arg.equals("-v")) { - System.out.println(new CompilerImpl(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE).getVersion()); + System.out.println(new SSEMCompiler(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE).getVersion()); return; } else { break; @@ -59,7 +59,7 @@ public static void main(String... args) { outputFile += ".bin"; } - CompilerImpl compiler = new CompilerImpl(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE); + SSEMCompiler compiler = new SSEMCompiler(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE); compiler.addCompilerListener(new CompilerListener() { @Override public void onStart() { diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java similarity index 92% rename from plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java rename to plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java index dd94d6886..1a4cc8c71 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerImpl.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java @@ -34,7 +34,6 @@ import net.emustudio.plugins.compiler.ssem.ast.Program; import net.emustudio.plugins.compiler.ssem.ast.ProgramParser; import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.tree.ParseTree; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,15 +50,15 @@ title = "SSEM Assembler" ) @SuppressWarnings("unused") -public class CompilerImpl extends AbstractCompiler { - private static final Logger LOGGER = LoggerFactory.getLogger(CompilerImpl.class); +public class SSEMCompiler extends AbstractCompiler { + private static final Logger LOGGER = LoggerFactory.getLogger(SSEMCompiler.class); private static final List SOURCE_FILE_EXTENSIONS = List.of( new SourceFileExtension("ssem", "SSEM source file") ); private MemoryContext memory; private int programLocation; - public CompilerImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { + public SSEMCompiler(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); } @@ -91,17 +90,14 @@ public boolean compile(String inputFileName, String outputFileName) { try (Reader reader = new FileReader(inputFileName)) { Lexer lexer = createLexer(CharStreams.fromReader(reader)); - lexer.removeErrorListeners(); lexer.addErrorListener(new ParserErrorListener()); CommonTokenStream tokens = new CommonTokenStream(lexer); SSEMParser parser = createParser(tokens); - parser.removeErrorListeners(); parser.addErrorListener(new ParserErrorListener()); - ParseTree tree = parser.start(); ProgramParser programParser = new ProgramParser(); - programParser.visit(tree); + programParser.visit(parser.start()); Program program = programParser.getProgram(); CodeGenerator codeGenerator = new CodeGenerator(); @@ -115,13 +111,15 @@ public boolean compile(String inputFileName, String outputFileName) { programLocation = program.getStartLine() * 4; notifyInfo(String.format( - "Compile was successful (program starts at %s). Output: %s", + "Compile was successful. Output: %s\nProgram starts at %s", RadixUtils.formatWordHexString(programLocation), outputFileName )); - } catch (Exception e) { - e.printStackTrace(); - LOGGER.trace("Compilation error.", e); - notifyError(e.toString()); + } catch (CompileException e) { + notifyError(e.line, e.column, e.getMessage()); + return false; + } catch (IOException e) { + notifyError("Compilation error: " + e); + LOGGER.error("Compilation error", e); return false; } finally { notifyCompileFinish(); diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java index 3b6a5b68d..833360272 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java @@ -1,40 +1,35 @@ package net.emustudio.plugins.compiler.ssem.ast; -import net.emustudio.plugins.compiler.ssem.CompileException; +import net.emustudio.plugins.compiler.ssem.Position; import net.emustudio.plugins.compiler.ssem.SSEMParser; import net.jcip.annotations.Immutable; import java.util.Map; import java.util.Objects; +import static net.emustudio.plugins.compiler.ssem.CompilerChecks.checkOperandOutOfBounds; +import static net.emustudio.plugins.compiler.ssem.CompilerChecks.checkUnknownInstruction; + @Immutable public class Instruction { private final static Map OPCODES = Map.of( SSEMParser.JMP, (byte)0, // 000 - SSEMParser.SUB, (byte)1, // 001 + SSEMParser.JPR, (byte)4, // 100 SSEMParser.LDN, (byte)2, // 010 - SSEMParser.CMP, (byte)3, // 011 - SSEMParser.JRP, (byte)4, // 100 SSEMParser.STO, (byte)6, // 110 + SSEMParser.SUB, (byte)1, // 001 + SSEMParser.CMP, (byte)3, // 011 SSEMParser.STP, (byte)7, // 111, - SSEMParser.BNUM, (byte)0, - SSEMParser.NUM, (byte)0 + SSEMParser.NUM, (byte)0, + SSEMParser.BNUM, (byte)0 ); public final int tokenType; - public final int operand; - - public Instruction(int tokenType) { - this(tokenType, 0); - } + public final long operand; - public Instruction(int tokenType, int operand) { - if (!OPCODES.containsKey(tokenType)) { - throw new CompileException("Unknown instruction"); - } - if (operand < 0 || operand > 31) { - throw new CompileException("Operand must be between <0, 31>; it was " + operand); - } + public Instruction(int tokenType, long operand, Position instrPosition, Position operandPosition) { + checkUnknownInstruction(!OPCODES.containsKey(tokenType), instrPosition); + checkOperandOutOfBounds(operandPosition, tokenType, operand); this.tokenType = tokenType; this.operand = operand; } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java index 512397e69..3401e5335 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java @@ -1,22 +1,23 @@ package net.emustudio.plugins.compiler.ssem.ast; -import net.emustudio.plugins.compiler.ssem.CompileException; +import net.emustudio.plugins.compiler.ssem.Position; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.function.BiConsumer; +import static net.emustudio.plugins.compiler.ssem.CompilerChecks.*; + public class Program { private int startLine; private boolean startLineDefined; private final Map instructions = new HashMap<>(); - public void setStartLine(int startLine) { - if (startLineDefined) { - throw new CompileException("Start line is already defined (at line " + startLine + ")!"); - } + public void setStartLine(int startLine, Position pos) { + checkStartLineDefined(startLineDefined, pos, this.startLine); + checkLineOutOfBounds(pos, startLine); this.startLine = startLine; startLineDefined = true; } @@ -25,13 +26,9 @@ public int getStartLine() { return startLine; } - public void add(int line, Instruction instruction) { - if (instructions.containsKey(line)) { - throw new CompileException("Duplicate line definition: " + line); - } - if (line > 31) { - throw new CompileException("Line number is out of bounds <0;31>: " + line); - } + public void add(int line, Instruction instruction, Position pos) { + checkDuplicateLineDefinition(instructions.containsKey(line), pos, line); + checkLineOutOfBounds(pos, line); instructions.put(line, instruction); } @@ -46,9 +43,7 @@ public Map getInstructions() { public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(startLine).append(" start\n"); - forEach((line, instr) -> { - buffer.append(String.format("%02d %s\n", line, instr)); - }); + forEach((line, instr) -> buffer.append(String.format("%02d %s\n", line, instr))); return buffer.toString(); } } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java index a58a8f1fe..00fb38a3f 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java @@ -1,5 +1,7 @@ package net.emustudio.plugins.compiler.ssem.ast; +import net.emustudio.plugins.compiler.ssem.CompileException; +import net.emustudio.plugins.compiler.ssem.Position; import net.emustudio.plugins.compiler.ssem.SSEMParser; import net.emustudio.plugins.compiler.ssem.SSEMParserBaseVisitor; import org.antlr.v4.runtime.Token; @@ -10,35 +12,73 @@ public class ProgramParser extends SSEMParserBaseVisitor { @Override public Program visitLine(SSEMParser.LineContext ctx) { if (ctx.linenumber != null) { - int line = parseNumber(ctx.linenumber); + int line = parsePositiveInteger(ctx.linenumber); if (ctx.command != null) { - int operand = 0; - if (ctx.command.operand != null) { - if (ctx.command.instr.getType() == SSEMParser.BNUM) { - operand = Integer.parseInt(ctx.command.operand.getText(), 2); + Token tokenInstr = ctx.command.instr; + Token tokenOperand = ctx.command.operand; + + long operand = 0; + if (tokenOperand != null) { + if (tokenInstr.getType() == SSEMParser.BNUM) { + operand = parseBinary(tokenOperand); } else { - operand = parseNumber(ctx.command.operand); + operand = parseNumber(tokenOperand); } } - int instrType = ctx.command.instr.getType(); + int instrType = tokenInstr.getType(); if (instrType == SSEMParser.START) { - program.setStartLine(line); + program.setStartLine(line, Position.of(ctx.linenumber)); } else { - program.add(line, new Instruction(instrType, operand)); + program.add( + line, + new Instruction(instrType, operand, Position.of(tokenInstr), Position.of(tokenOperand)), + Position.of(ctx.linenumber) + ); } } } return program; } - private int parseNumber(Token token) { - if (token.getType() == SSEMParser.HEXNUMBER) { - return Integer.decode(token.getText()); - } else { - // Do not use decode because we don't support octal numbers - return Integer.parseUnsignedInt(token.getText()); + private long parseBinary(Token token) { + try { + return Long.parseLong(token.getText(), 2); + } catch (NumberFormatException e) { + throw new CompileException( + token.getLine(), token.getCharPositionInLine(), "Could not parse number: " + token.getText() + ); + } + } + + private long parseNumber(Token token) { + try { + if (token.getType() == SSEMParser.HEXNUMBER) { + return Long.decode(token.getText()); + } else { + // Do not use decode because we don't support octal numbers + return Long.parseLong(token.getText()); + } + } catch (NumberFormatException e) { + throw new CompileException( + token.getLine(), token.getCharPositionInLine(), "Could not parse number: " + token.getText() + ); + } + } + + private int parsePositiveInteger(Token token) { + try { + if (token.getType() == SSEMParser.HEXNUMBER) { + return Integer.decode(token.getText()); + } else { + // Do not use decode because we don't support octal numbers + return Integer.parseUnsignedInt(token.getText()); + } + } catch (NumberFormatException e) { + throw new CompileException( + token.getLine(), token.getCharPositionInLine(), "Could not parse number: " + token.getText() + ); } } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java index 535aa83e4..120224ab2 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java @@ -34,16 +34,16 @@ public void testParseError() { @Test public void testParseReservedWords() { assertTokenTypesForCaseVariations("jmp", SSEMLexer.JMP, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("jrp", SSEMLexer.JRP, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("jrp", SSEMLexer.JPR, SSEMLexer.EOF); assertTokenTypesForCaseVariations("jpr", SSEMLexer.JPR, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("jmr", SSEMLexer.JMR, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("jmr", SSEMLexer.JPR, SSEMLexer.EOF); assertTokenTypesForCaseVariations("ldn", SSEMLexer.LDN, SSEMLexer.EOF); assertTokenTypesForCaseVariations("sto", SSEMLexer.STO, SSEMLexer.EOF); assertTokenTypesForCaseVariations("sub", SSEMLexer.SUB, SSEMLexer.EOF); assertTokenTypesForCaseVariations("cmp", SSEMLexer.CMP, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("skn", SSEMLexer.SKN, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("skn", SSEMLexer.CMP, SSEMLexer.EOF); assertTokenTypesForCaseVariations("stp", SSEMLexer.STP, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("hlt", SSEMLexer.HLT, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("hlt", SSEMLexer.STP, SSEMLexer.EOF); } @Test diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java index aba9f4bc1..ad8f0dc81 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java @@ -72,6 +72,45 @@ public void testParseInstructions() { ); } + @Test + public void testParseAllInstructions() { + Program program = parseProgram( + "01 jmp 0x1F\n" + + "02 jrp 0x1F\n" + + "03 jpr 0x1F\n" + + "04 jmr 0x1F\n" + + "05 ldn 0x1F\n" + + "06 sto 0x1F\n" + + "07 sub 0x1F\n" + + "08 cmp\n" + + "09 skn\n" + + "10 stp\n" + + "11 hlt\n" + ); + assertInstructions( + program, + new Utils.ParsedInstruction(1, SSEMParser.JMP, 0x1F), + new Utils.ParsedInstruction(2, SSEMParser.JPR, 0x1F), + new Utils.ParsedInstruction(3, SSEMParser.JPR, 0x1F), + new Utils.ParsedInstruction(4, SSEMParser.JPR, 0x1F), + new Utils.ParsedInstruction(5, SSEMParser.LDN, 0x1F), + new Utils.ParsedInstruction(6, SSEMParser.STO, 0x1F), + new Utils.ParsedInstruction(7, SSEMParser.SUB, 0x1F), + new Utils.ParsedInstruction(8, SSEMParser.CMP, 0), + new Utils.ParsedInstruction(9, SSEMParser.CMP, 0), + new Utils.ParsedInstruction(10, SSEMParser.STP, 0), + new Utils.ParsedInstruction(11, SSEMParser.STP, 0) + ); + } + + @Test + public void testParseNegativeNumber() { + Program program = parseProgram( + "01 NUM -3" + ); + assertInstructions(program, new Utils.ParsedInstruction(1, SSEMLexer.NUM, -3)); + } + @Test public void testStartingPointIsAccepted() { Program program = parseProgram( @@ -82,6 +121,12 @@ public void testStartingPointIsAccepted() { assertEquals(2, program.getStartLine()); } + @Test + public void testParseLongBinaryNumber() { + Program program = parseProgram("0000 BINS 11001000000000000000000000000000"); + assertEquals(3355443200L, program.getInstructions().get(0).operand); + } + @Test(expected = CompileException.class) public void testOperandBounds() { parseProgram("01 ldn 99\n"); diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/CompilerImplTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java similarity index 96% rename from plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/CompilerImplTest.java rename to plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java index 7668a2560..f6ae3db2d 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/CompilerImplTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java @@ -38,8 +38,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -public class CompilerImplTest { - private CompilerImpl compiler; +public class SSEMCompilerTest { + private SSEMCompiler compiler; private MemoryStub memoryStub; @Rule @@ -57,7 +57,7 @@ public void setUp() throws Exception { expect(applicationApi.getContextPool()).andReturn(pool).anyTimes(); replay(applicationApi); - compiler = new CompilerImpl(0L, applicationApi, PluginSettings.UNAVAILABLE); + compiler = new SSEMCompiler(0L, applicationApi, PluginSettings.UNAVAILABLE); compiler.initialize(); } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java index 9abbea0ab..855ea5dd6 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java @@ -75,7 +75,10 @@ public static void assertInstructions(Program program, ParsedInstruction... inst Map pinstr = program.getInstructions(); assertEquals(instructions.length, pinstr.size()); for (ParsedInstruction instruction : instructions) { - assertEquals(new Instruction(instruction.opcode, instruction.operand), pinstr.get(instruction.line)); + assertEquals( + new Instruction(instruction.opcode, instruction.operand, Position.unknown(), Position.unknown()), + pinstr.get(instruction.line) + ); } } From 440c55eea124daf144601bd3895461011c24d9b1 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 29 May 2021 10:54:32 +0200 Subject: [PATCH 032/314] [#201] Refactoring --- .../plugins/compiler/ssem/CompilerChecks.java | 14 ++++++ .../compiler/ssem/ast/ProgramParser.java | 47 +++++++------------ .../plugins/cpu/ssem/EmulatorEngine.java | 6 +-- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java index 2c8cdf2f0..a8699d8eb 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java @@ -1,5 +1,9 @@ package net.emustudio.plugins.compiler.ssem; +import org.antlr.v4.runtime.Token; + +import java.util.function.Function; + public class CompilerChecks { public static void checkStartLineDefined(boolean defined, Position pos, int startLine) { @@ -33,4 +37,14 @@ public static void checkOperandOutOfBounds(Position pos, int tokenType, long ope ); } } + + public static T checkedParseNumber(Token token, Function parser) { + try { + return parser.apply(token); + } catch (NumberFormatException e) { + throw new CompileException( + token.getLine(), token.getCharPositionInLine(), "Could not parse number: " + token.getText() + ); + } + } } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java index 00fb38a3f..53c74a08d 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java @@ -1,11 +1,12 @@ package net.emustudio.plugins.compiler.ssem.ast; -import net.emustudio.plugins.compiler.ssem.CompileException; import net.emustudio.plugins.compiler.ssem.Position; import net.emustudio.plugins.compiler.ssem.SSEMParser; import net.emustudio.plugins.compiler.ssem.SSEMParserBaseVisitor; import org.antlr.v4.runtime.Token; +import static net.emustudio.plugins.compiler.ssem.CompilerChecks.checkedParseNumber; + public class ProgramParser extends SSEMParserBaseVisitor { private final Program program = new Program(); @@ -42,47 +43,33 @@ public Program visitLine(SSEMParser.LineContext ctx) { return program; } + public Program getProgram() { + return program; + } + private long parseBinary(Token token) { - try { - return Long.parseLong(token.getText(), 2); - } catch (NumberFormatException e) { - throw new CompileException( - token.getLine(), token.getCharPositionInLine(), "Could not parse number: " + token.getText() - ); - } + return checkedParseNumber(token, t -> Long.parseLong(t.getText(), 2)); } private long parseNumber(Token token) { - try { - if (token.getType() == SSEMParser.HEXNUMBER) { - return Long.decode(token.getText()); + return checkedParseNumber(token, t -> { + if (t.getType() == SSEMParser.HEXNUMBER) { + return Long.decode(t.getText()); } else { // Do not use decode because we don't support octal numbers - return Long.parseLong(token.getText()); + return Long.parseLong(t.getText()); } - } catch (NumberFormatException e) { - throw new CompileException( - token.getLine(), token.getCharPositionInLine(), "Could not parse number: " + token.getText() - ); - } + }); } private int parsePositiveInteger(Token token) { - try { - if (token.getType() == SSEMParser.HEXNUMBER) { - return Integer.decode(token.getText()); + return checkedParseNumber(token, t -> { + if (t.getType() == SSEMParser.HEXNUMBER) { + return Integer.decode(t.getText()); } else { // Do not use decode because we don't support octal numbers - return Integer.parseUnsignedInt(token.getText()); + return Integer.parseUnsignedInt(t.getText()); } - } catch (NumberFormatException e) { - throw new CompileException( - token.getLine(), token.getCharPositionInLine(), "Could not parse number: " + token.getText() - ); - } - } - - public Program getProgram() { - return program; + }); } } diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java index 372cbc0ac..8c49ee6ee 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java @@ -71,7 +71,7 @@ CPU.RunState step() { return CPU.RunState.STATE_STOPPED_BREAK; } break; - case 4: // JPR + case 4: // JPR, JRP, JMR CI.addAndGet(readLineAddress(lineAddress)); break; case 2: // LDN @@ -84,12 +84,12 @@ CPU.RunState step() { case 1: // SUB Acc.addAndGet(-readInt(lineAddress)); break; - case 3: // CMP / SKN + case 3: // CMP, SKN if (Acc.get() < 0) { CI.addAndGet(4); } break; - case 7: // STP / HLT + case 7: // STP, HLT return CPU.RunState.STATE_STOPPED_NORMAL; default: return CPU.RunState.STATE_STOPPED_BAD_INSTR; From 6483c69fe69d026706ec16e85610d4a1d3ad91f6 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 29 May 2021 11:11:22 +0200 Subject: [PATCH 033/314] [#201] Updated some SSEM programs --- .../src/main/examples/bcs-division.ssem | 44 +++++++++++ .../as-ssem/src/main/examples/medclock.ssem | 74 +++++++++++-------- .../as-ssem/src/main/examples/nightmare.ssem | 72 ++++++++++-------- .../src/main/examples/noodle-timer.ssem | 10 +++ .../as-ssem/src/main/examples/parabola.ssem | 38 ++++++++++ .../as-ssem/src/main/examples/primegen.ssem | 6 ++ 6 files changed, 181 insertions(+), 63 deletions(-) create mode 100644 plugins/compiler/as-ssem/src/main/examples/bcs-division.ssem create mode 100644 plugins/compiler/as-ssem/src/main/examples/parabola.ssem diff --git a/plugins/compiler/as-ssem/src/main/examples/bcs-division.ssem b/plugins/compiler/as-ssem/src/main/examples/bcs-division.ssem new file mode 100644 index 000000000..0ffee590d --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/examples/bcs-division.ssem @@ -0,0 +1,44 @@ +; The UK schools winner of the 1998 SSEM Programming Competition. +; +; An implementation of "division by repeated subtraction". +; +; Written by: Brendan Campbell +; Obtained from: The 1998 SSEM Programming Competition. +; Description: Integer division, giving quotient and remainder. +; Parameter Lines: 28: Dividend +; 29: Divisor +; Result Lines: 30: Quotient +; 31: Remainder + +00 BNUM 00000000000000000000011110000000 +01 BINS 10111000000000100000010001000000 +02 BINS 11011000000001100000011110000000 +03 BINS 00111000000000100000010001000000 +04 BINS 01011000000001100000011110000000 +05 BINS 01011000000000100000000000000000 +06 BINS 10111000000000010000011111000000 +07 BINS 00111000000001100000000010000000 +08 BINS 00000000000000110000000010000000 +09 BINS 10011000000000000000010010000000 +10 BINS 11011000000000010000001100000000 +11 BINS 11111000000001100000000000000000 +12 BINS 00000000000001110000010000000000 +13 BINS 01111000000000100000010000000000 +14 BINS 00011000000000010000010000000000 +15 BINS 01111000000001100000010000000000 +16 BINS 01111000000000100000011111000000 +17 BINS 01111000000001100000000000000000 +18 BINS 11101000000000000000001111000000 +19 BNUM 00000000000000000000010000000000 +20 BNUM 00000000000000000000010000000000 +21 BNUM 00000000000000000000010000000000 +22 BNUM 00000000000000000000001111000000 +23 BNUM 01000000000000000000000000000000 +24 BNUM 10000000000000000000000000000000 +25 BNUM 00110000000000000000000000000000 +26 BNUM 00000000000000000000000000000000 +27 BNUM 00000000000000000000000000000000 +28 BNUM 01011001010000000000000000000000 +29 BNUM 01010100000000000000000000000000 +30 BNUM 00000000000000000000000000000000 +31 BNUM 00000000000000000000000000000000 diff --git a/plugins/compiler/as-ssem/src/main/examples/medclock.ssem b/plugins/compiler/as-ssem/src/main/examples/medclock.ssem index 3217ccdcd..63f0bbfdd 100644 --- a/plugins/compiler/as-ssem/src/main/examples/medclock.ssem +++ b/plugins/compiler/as-ssem/src/main/examples/medclock.ssem @@ -1,31 +1,43 @@ -0001 BINS 11011000000000100000000010000000 -0002 BINS 00111000000000010000000101000000 -0003 BINS 00000000000000110000001000100000 -0004 BINS 00111000000000000000010010010000 -0005 BINS 11111000000000100010100000001010 -0006 BINS 00000000000001100101000010000101 -0007 BINS 00000000000000100111001010100111 -0008 BINS 00000000000000010101001010100101 -0009 BINS 11111000000001100101001010100101 -0010 BINS 00000000000000110101001010100101 -0011 BINS 00111000000001000111111111111111 -0012 BINS 10111000000000000100000000000001 -0013 BINS 00111000000000100100000111000001 -0014 BINS 11111000000001100100001000100001 -0015 BINS 01111000000000100100010000010001 -0016 BINS 00000000000001100100100000001001 -0017 BINS 00000000000000100111100000001111 -0018 BINS 00000000000000010000000000000000 -0019 BINS 01111000000001100110001111000111 -0020 BINS 01011000000000010010001010101010 -0021 BINS 00000000000000110010001010010010 -0022 BINS 10111000000000000010001010010010 -0023 BINS 00111000000000100001110011000111 -0024 BINS 01111000000001100000000000000000 -0025 BINS 10111000000000000000000000000000 -0026 BINS 00000000000111111111111111111111 -0027 BINS 01101110100110011111111111111111 -0028 BINS 10000000000000000000000000000000 -0029 BINS 00000000000000000000000000000000 -0030 BINS 11111111111111111111111111111111 -0031 BINS 11111111111111111111111111111111 +; (The "dog kennel" on the right hand side of the code is the University of Manchester logo.) +; +; Written by: John Deane of Australia. +; Obtained from: The 1998 SSEM Programming Competition. +; Description: "Mediaeval analog clock which displays the hour as the number of zeroes counted from the left in location 30. +; The fraction of the hour is displayed in location 31 where each 0 from the left indicates 1/32 hour (about 2 minutes)." +; Parameter Lines: 27: initial value for the timing interval counter. See code below. +; Result Lines: 30: hours display +; 31: 1/32 hour display +; (run time display) + +01 BINS 11011000000000100000000010000000 +02 BINS 00111000000000010000000101000000 +03 BINS 00000000000000110000001000100000 +04 BINS 00111000000000000000010010010000 +05 BINS 11111000000000100010100000001010 +06 BINS 00000000000001100101000010000101 +07 BINS 00000000000000100111001010100111 +08 BINS 00000000000000010101001010100101 +09 BINS 11111000000001100101001010100101 +10 BINS 00000000000000110101001010100101 +11 BINS 00111000000001000111111111111111 +12 BINS 10111000000000000100000000000001 +13 BINS 00111000000000100100000111000001 +14 BINS 11111000000001100100001000100001 +15 BINS 01111000000000100100010000010001 +16 BINS 00000000000001100100100000001001 +17 BINS 00000000000000100111100000001111 +18 BINS 00000000000000010000000000000000 +19 BINS 01111000000001100110001111000111 +20 BINS 01011000000000010010001010101010 +21 BINS 00000000000000110010001010010010 +22 BINS 10111000000000000010001010010010 +23 BINS 00111000000000100001110011000111 +24 BINS 01111000000001100000000000000000 +25 BINS 10111000000000000000000000000000 +26 BNUM 00000000000111111111111111111111 +27 BNUM 01101110100110011111111111111111 -- timing counter for original machine +27 BNUM 10111111111111111111111111111111 -- timing counter to speed up simulation +28 BNUM 10000000000000000000000000000000 +29 BNUM 00000000000000000000000000000000 +30 BNUM 11111111111111111111111111111111 +31 BNUM 11111111111111111111111111111111 diff --git a/plugins/compiler/as-ssem/src/main/examples/nightmare.ssem b/plugins/compiler/as-ssem/src/main/examples/nightmare.ssem index 0d537d44b..dff35cb70 100644 --- a/plugins/compiler/as-ssem/src/main/examples/nightmare.ssem +++ b/plugins/compiler/as-ssem/src/main/examples/nightmare.ssem @@ -1,32 +1,40 @@ -0000 BINS 00000110101001000100000100000100 -0001 BINS 10011011111100100010000010001000 -0002 BINS 10000010000101101000100001010000 -0003 BINS 00000010000100110100001001100000 -0004 BINS 11101011111100011010101010010100 -0005 BINS 10000000110000010001000010101001 -0006 BINS 10000001111000010000100100001100 -0007 BINS 10000001111000010000011000000010 -0008 BINS 10011000000001101000011001000001 -0009 BINS 10101001111000100100100100000010 -0010 BINS 00000001111000110011010010000100 -0011 BINS 01101001111000010011000001001000 -0012 BINS 11101001111000010100100000110000 -0013 BINS 10101000110001101000010000110000 -0014 BINS 10100001111000010000001001001000 -0015 BINS 00010011111101100000000110000100 -0016 BINS 00000111111110010000000010000010 -0017 BINS 10000011111101101111111111111111 -0018 BINS 10101001111000100110011001100110 -0019 BINS 10101000110001101111111111111111 -0020 BINS 00011000110000001111111111111111 -0021 BINS 01100000000000000000000000000000 -0022 BINS 11100000000000000000000000000000 -0023 BINS 11111111111111111111111111111111 -0024 BINS 00000000000000000000000000000000 -0025 BINS 00000000000000011111000000100000 -0026 BINS 00000000000000100000100001010000 -0027 BINS 00000000000000100010100000100000 -0028 BINS 00000001111110100000100000111000 -0029 BINS 00000010000000011111000000100000 -0030 BINS 00011110011110001000000000100000 -0031 BINS 00111111111111111110000001010000 +; Written by: Frank Hurley. +; Obtained from: The 1998 SSEM Programming Competition. +; Description: "The program is an animation of a giant baby and Tom chasing after each other for eternity underneath +; a jumble of bulbs, switches, cables, smoke and iron. Viewable on store tube. The program does not +; terminate and the animation cycles every 8 seconds @ 700 ips. Blurred vision helps." +; Parameter Lines: - +; Result Lines: (run-time display) + +00 BNUM 00000110101001000100000100000100 +01 BINS 10011011111100100010000010001000 +02 BINS 10000010000101101000100001010000 +03 BINS 00000010000100110100001001100000 +04 BINS 11101011111100011010101010010100 +05 BINS 10000000110000010001000010101001 +06 BINS 10000001111000010000100100001100 +07 BINS 10000001111000010000011000000010 +08 BINS 10011000000001101000011001000001 +09 BINS 10101001111000100100100100000010 +10 BINS 00000001111000110011010010000100 +11 BINS 01101001111000010011000001001000 +12 BINS 11101001111000010100100000110000 +13 BINS 10101000110001101000010000110000 +14 BINS 10100001111000010000001001001000 +15 BINS 00010011111101100000000110000100 +16 BINS 00000111111110010000000010000010 +17 BINS 10000011111101101111111111111111 +18 BINS 10101001111000100110011001100110 +19 BINS 10101000110001101111111111111111 +20 BINS 00011000110000001111111111111111 +21 BNUM 01100000000000000000000000000000 +22 BNUM 11100000000000000000000000000000 +23 BNUM 11111111111111111111111111111111 +24 BNUM 00000000000000000000000000000000 +25 BNUM 00000000000000011111000000100000 +26 BNUM 00000000000000100000100001010000 +27 BNUM 00000000000000100010100000100000 +28 BNUM 00000001111110100000100000111000 +29 BNUM 00000010000000011111000000100000 +30 BNUM 00011110011110001000000000100000 +31 BNUM 00111111111111111110000001010000 diff --git a/plugins/compiler/as-ssem/src/main/examples/noodle-timer.ssem b/plugins/compiler/as-ssem/src/main/examples/noodle-timer.ssem index 05849bb7d..635591f46 100644 --- a/plugins/compiler/as-ssem/src/main/examples/noodle-timer.ssem +++ b/plugins/compiler/as-ssem/src/main/examples/noodle-timer.ssem @@ -1,3 +1,13 @@ +; The Winner of the 1998 SSEM Programming Competition! +; +; Written by: Yasuaki Watanabe of Japan. +; Obtained from: The 1998 SSEM Programming Competition. +; Description: "This is a three minutes timer program. If you want to eat instant noodles, use this program. Start +; the program after pour hot water into the cup. Open the cover and start to eat if the "Stop" indicator +; is illuminated. I promise you that the noodles taste good." +; Parameter Lines: 31: initial value for the timing interval counter. See values in code below. +; Result Lines: (run-time display) + 00 BNUM 00000000000000000000000000000000 01 BINS 10011011111000101111110000111111 02 BINS 00111000100001100000000000000000 diff --git a/plugins/compiler/as-ssem/src/main/examples/parabola.ssem b/plugins/compiler/as-ssem/src/main/examples/parabola.ssem new file mode 100644 index 000000000..fddc07626 --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/examples/parabola.ssem @@ -0,0 +1,38 @@ +; Written by: Magnus Olsson of Sweden. +; Obtained from: The 1998 SSEM Programming Competition. +; Description: "uses the CRT as an X-Y display to plot a parabola by setting bits in the unused upper half of lines 1-22. +; The parabola is computed as the solution of a difference equation." +; Parameter Lines: - +; Result Lines: (see description) + +01 LDN 29 +02 SUB 29 +03 STO 29 +04 CMP +05 STP +06 LDN 29 +07 STO 29 +08 LDN 22 +09 SUB 29 +10 STO 30 +11 LDN 30 +12 STO 22 +13 LDN 8 +14 SUB 28 +15 STO 30 +16 LDN 30 +17 STO 8 +18 SUB 27 +19 STO 12 +20 LDN 28 +21 SUB 26 +22 STO 28 +23 LDN 28 +24 STO 28 +25 JMP 31 +26 NUM 1 +27 NUM -8192 +28 NUM -6 +29 NUM 131072 +30 NUM 0 +31 NUM 0 diff --git a/plugins/compiler/as-ssem/src/main/examples/primegen.ssem b/plugins/compiler/as-ssem/src/main/examples/primegen.ssem index 4940bcb38..6bd8ec5cf 100644 --- a/plugins/compiler/as-ssem/src/main/examples/primegen.ssem +++ b/plugins/compiler/as-ssem/src/main/examples/primegen.ssem @@ -1,3 +1,9 @@ +; Written by: Bas Wijnen of Holland. +; Obtained from: The 1998 SSEM Programming Competition. +; Description: Each time the program is run (pressing the EXEC button) the next prime number in the sequence is generated. +; Parameter Lines: - +; Result Lines: 21: generated primes + 0000 JMP 24 0001 LDN 21 0002 STO 21 From 7964653c381d865614140bc4fd86cf750580ad33 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 3 Jun 2021 20:35:28 +0200 Subject: [PATCH 034/314] [#201 #203] Many SSEM fixes --- .../as-ssem/src/main/gen/SSEMLexer.interp | 92 ++++++++ .../as-ssem/src/main/gen/SSEMLexer.java | 199 ++++++++++++++++++ .../plugins/compiler/ssem/CodeGenerator.java | 4 +- .../plugins/cpu/ssem/EmulatorEngine.java | 2 +- .../plugins/cpu/ssem/gui/CpuPanel.java | 62 +++++- .../plugins/memory/ssem/gui/CellRenderer.java | 8 +- .../plugins/memory/ssem/gui/Constants.java | 4 +- .../memory/ssem/gui/MemoryTableModel.java | 20 +- .../memory/ssem/gui/RowHeaderRenderer.java | 2 +- .../memory/ssem/gui/MemoryTableModelTest.java | 21 +- 10 files changed, 400 insertions(+), 14 deletions(-) create mode 100644 plugins/compiler/as-ssem/src/main/gen/SSEMLexer.interp create mode 100644 plugins/compiler/as-ssem/src/main/gen/SSEMLexer.java diff --git a/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.interp b/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.interp new file mode 100644 index 000000000..60df1ad91 --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.interp @@ -0,0 +1,92 @@ +token literal names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +WS +COMMENT +EOL +JMP +JPR +LDN +STO +SUB +CMP +STP +START +NUM +BNUM +NUMBER +HEXNUMBER +ERROR +BWS +BinaryNumber +BERROR + +rule names: +WS +COMMENT +EOL +J +M +P +R +L +D +N +S +T +O +U +B +C +K +H +A +I +JMP +JPR +LDN +STO +SUB +CMP +STP +START +NUM +BNUM +NUMBER +HEXNUMBER +ERROR +BWS +BinaryNumber +BERROR + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE +BIN + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 21, 243, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 86, 10, 3, 3, 3, 7, 3, 89, 10, 3, 12, 3, 14, 3, 92, 11, 3, 3, 4, 5, 4, 95, 10, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 5, 23, 149, 10, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 5, 27, 171, 10, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 5, 28, 181, 10, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 5, 31, 203, 10, 31, 3, 31, 3, 31, 3, 32, 5, 32, 208, 10, 32, 3, 32, 6, 32, 211, 10, 32, 13, 32, 14, 32, 212, 3, 33, 5, 33, 216, 10, 33, 3, 33, 3, 33, 3, 33, 3, 33, 5, 33, 222, 10, 33, 3, 33, 6, 33, 225, 10, 33, 13, 33, 14, 33, 226, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 6, 36, 236, 10, 36, 13, 36, 14, 36, 237, 3, 36, 3, 36, 3, 37, 3, 37, 2, 2, 38, 4, 3, 6, 4, 8, 5, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 6, 46, 7, 48, 8, 50, 9, 52, 10, 54, 11, 56, 12, 58, 13, 60, 14, 62, 15, 64, 16, 66, 17, 68, 18, 70, 19, 72, 20, 74, 21, 4, 2, 3, 26, 4, 2, 11, 11, 34, 34, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 76, 76, 108, 108, 4, 2, 79, 79, 111, 111, 4, 2, 82, 82, 114, 114, 4, 2, 84, 84, 116, 116, 4, 2, 78, 78, 110, 110, 4, 2, 70, 70, 102, 102, 4, 2, 80, 80, 112, 112, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 81, 81, 113, 113, 4, 2, 87, 87, 119, 119, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 77, 77, 109, 109, 4, 2, 74, 74, 106, 106, 4, 2, 67, 67, 99, 99, 4, 2, 75, 75, 107, 107, 3, 2, 47, 47, 3, 2, 50, 59, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 51, 2, 239, 2, 4, 3, 2, 2, 2, 2, 6, 3, 2, 2, 2, 2, 8, 3, 2, 2, 2, 2, 44, 3, 2, 2, 2, 2, 46, 3, 2, 2, 2, 2, 48, 3, 2, 2, 2, 2, 50, 3, 2, 2, 2, 2, 52, 3, 2, 2, 2, 2, 54, 3, 2, 2, 2, 2, 56, 3, 2, 2, 2, 2, 58, 3, 2, 2, 2, 2, 60, 3, 2, 2, 2, 2, 62, 3, 2, 2, 2, 2, 64, 3, 2, 2, 2, 2, 66, 3, 2, 2, 2, 2, 68, 3, 2, 2, 2, 3, 70, 3, 2, 2, 2, 3, 72, 3, 2, 2, 2, 3, 74, 3, 2, 2, 2, 4, 76, 3, 2, 2, 2, 6, 85, 3, 2, 2, 2, 8, 94, 3, 2, 2, 2, 10, 98, 3, 2, 2, 2, 12, 100, 3, 2, 2, 2, 14, 102, 3, 2, 2, 2, 16, 104, 3, 2, 2, 2, 18, 106, 3, 2, 2, 2, 20, 108, 3, 2, 2, 2, 22, 110, 3, 2, 2, 2, 24, 112, 3, 2, 2, 2, 26, 114, 3, 2, 2, 2, 28, 116, 3, 2, 2, 2, 30, 118, 3, 2, 2, 2, 32, 120, 3, 2, 2, 2, 34, 122, 3, 2, 2, 2, 36, 124, 3, 2, 2, 2, 38, 126, 3, 2, 2, 2, 40, 128, 3, 2, 2, 2, 42, 130, 3, 2, 2, 2, 44, 132, 3, 2, 2, 2, 46, 148, 3, 2, 2, 2, 48, 150, 3, 2, 2, 2, 50, 154, 3, 2, 2, 2, 52, 158, 3, 2, 2, 2, 54, 170, 3, 2, 2, 2, 56, 180, 3, 2, 2, 2, 58, 182, 3, 2, 2, 2, 60, 188, 3, 2, 2, 2, 62, 202, 3, 2, 2, 2, 64, 207, 3, 2, 2, 2, 66, 215, 3, 2, 2, 2, 68, 228, 3, 2, 2, 2, 70, 230, 3, 2, 2, 2, 72, 235, 3, 2, 2, 2, 74, 241, 3, 2, 2, 2, 76, 77, 9, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 79, 8, 2, 2, 2, 79, 5, 3, 2, 2, 2, 80, 81, 7, 49, 2, 2, 81, 86, 7, 49, 2, 2, 82, 83, 7, 47, 2, 2, 83, 86, 7, 47, 2, 2, 84, 86, 9, 3, 2, 2, 85, 80, 3, 2, 2, 2, 85, 82, 3, 2, 2, 2, 85, 84, 3, 2, 2, 2, 86, 90, 3, 2, 2, 2, 87, 89, 10, 4, 2, 2, 88, 87, 3, 2, 2, 2, 89, 92, 3, 2, 2, 2, 90, 88, 3, 2, 2, 2, 90, 91, 3, 2, 2, 2, 91, 7, 3, 2, 2, 2, 92, 90, 3, 2, 2, 2, 93, 95, 7, 15, 2, 2, 94, 93, 3, 2, 2, 2, 94, 95, 3, 2, 2, 2, 95, 96, 3, 2, 2, 2, 96, 97, 7, 12, 2, 2, 97, 9, 3, 2, 2, 2, 98, 99, 9, 5, 2, 2, 99, 11, 3, 2, 2, 2, 100, 101, 9, 6, 2, 2, 101, 13, 3, 2, 2, 2, 102, 103, 9, 7, 2, 2, 103, 15, 3, 2, 2, 2, 104, 105, 9, 8, 2, 2, 105, 17, 3, 2, 2, 2, 106, 107, 9, 9, 2, 2, 107, 19, 3, 2, 2, 2, 108, 109, 9, 10, 2, 2, 109, 21, 3, 2, 2, 2, 110, 111, 9, 11, 2, 2, 111, 23, 3, 2, 2, 2, 112, 113, 9, 12, 2, 2, 113, 25, 3, 2, 2, 2, 114, 115, 9, 13, 2, 2, 115, 27, 3, 2, 2, 2, 116, 117, 9, 14, 2, 2, 117, 29, 3, 2, 2, 2, 118, 119, 9, 15, 2, 2, 119, 31, 3, 2, 2, 2, 120, 121, 9, 16, 2, 2, 121, 33, 3, 2, 2, 2, 122, 123, 9, 17, 2, 2, 123, 35, 3, 2, 2, 2, 124, 125, 9, 18, 2, 2, 125, 37, 3, 2, 2, 2, 126, 127, 9, 19, 2, 2, 127, 39, 3, 2, 2, 2, 128, 129, 9, 20, 2, 2, 129, 41, 3, 2, 2, 2, 130, 131, 9, 21, 2, 2, 131, 43, 3, 2, 2, 2, 132, 133, 5, 10, 5, 2, 133, 134, 5, 12, 6, 2, 134, 135, 5, 14, 7, 2, 135, 45, 3, 2, 2, 2, 136, 137, 5, 10, 5, 2, 137, 138, 5, 14, 7, 2, 138, 139, 5, 16, 8, 2, 139, 149, 3, 2, 2, 2, 140, 141, 5, 10, 5, 2, 141, 142, 5, 16, 8, 2, 142, 143, 5, 14, 7, 2, 143, 149, 3, 2, 2, 2, 144, 145, 5, 10, 5, 2, 145, 146, 5, 12, 6, 2, 146, 147, 5, 16, 8, 2, 147, 149, 3, 2, 2, 2, 148, 136, 3, 2, 2, 2, 148, 140, 3, 2, 2, 2, 148, 144, 3, 2, 2, 2, 149, 47, 3, 2, 2, 2, 150, 151, 5, 18, 9, 2, 151, 152, 5, 20, 10, 2, 152, 153, 5, 22, 11, 2, 153, 49, 3, 2, 2, 2, 154, 155, 5, 24, 12, 2, 155, 156, 5, 26, 13, 2, 156, 157, 5, 28, 14, 2, 157, 51, 3, 2, 2, 2, 158, 159, 5, 24, 12, 2, 159, 160, 5, 30, 15, 2, 160, 161, 5, 32, 16, 2, 161, 53, 3, 2, 2, 2, 162, 163, 5, 34, 17, 2, 163, 164, 5, 12, 6, 2, 164, 165, 5, 14, 7, 2, 165, 171, 3, 2, 2, 2, 166, 167, 5, 24, 12, 2, 167, 168, 5, 36, 18, 2, 168, 169, 5, 22, 11, 2, 169, 171, 3, 2, 2, 2, 170, 162, 3, 2, 2, 2, 170, 166, 3, 2, 2, 2, 171, 55, 3, 2, 2, 2, 172, 173, 5, 24, 12, 2, 173, 174, 5, 26, 13, 2, 174, 175, 5, 14, 7, 2, 175, 181, 3, 2, 2, 2, 176, 177, 5, 38, 19, 2, 177, 178, 5, 18, 9, 2, 178, 179, 5, 26, 13, 2, 179, 181, 3, 2, 2, 2, 180, 172, 3, 2, 2, 2, 180, 176, 3, 2, 2, 2, 181, 57, 3, 2, 2, 2, 182, 183, 5, 24, 12, 2, 183, 184, 5, 26, 13, 2, 184, 185, 5, 40, 20, 2, 185, 186, 5, 16, 8, 2, 186, 187, 5, 26, 13, 2, 187, 59, 3, 2, 2, 2, 188, 189, 5, 22, 11, 2, 189, 190, 5, 30, 15, 2, 190, 191, 5, 12, 6, 2, 191, 61, 3, 2, 2, 2, 192, 193, 5, 32, 16, 2, 193, 194, 5, 22, 11, 2, 194, 195, 5, 30, 15, 2, 195, 196, 5, 12, 6, 2, 196, 203, 3, 2, 2, 2, 197, 198, 5, 32, 16, 2, 198, 199, 5, 42, 21, 2, 199, 200, 5, 22, 11, 2, 200, 201, 5, 24, 12, 2, 201, 203, 3, 2, 2, 2, 202, 192, 3, 2, 2, 2, 202, 197, 3, 2, 2, 2, 203, 204, 3, 2, 2, 2, 204, 205, 8, 31, 3, 2, 205, 63, 3, 2, 2, 2, 206, 208, 9, 22, 2, 2, 207, 206, 3, 2, 2, 2, 207, 208, 3, 2, 2, 2, 208, 210, 3, 2, 2, 2, 209, 211, 9, 23, 2, 2, 210, 209, 3, 2, 2, 2, 211, 212, 3, 2, 2, 2, 212, 210, 3, 2, 2, 2, 212, 213, 3, 2, 2, 2, 213, 65, 3, 2, 2, 2, 214, 216, 9, 22, 2, 2, 215, 214, 3, 2, 2, 2, 215, 216, 3, 2, 2, 2, 216, 221, 3, 2, 2, 2, 217, 218, 7, 50, 2, 2, 218, 222, 7, 122, 2, 2, 219, 220, 7, 50, 2, 2, 220, 222, 7, 90, 2, 2, 221, 217, 3, 2, 2, 2, 221, 219, 3, 2, 2, 2, 222, 224, 3, 2, 2, 2, 223, 225, 9, 24, 2, 2, 224, 223, 3, 2, 2, 2, 225, 226, 3, 2, 2, 2, 226, 224, 3, 2, 2, 2, 226, 227, 3, 2, 2, 2, 227, 67, 3, 2, 2, 2, 228, 229, 11, 2, 2, 2, 229, 69, 3, 2, 2, 2, 230, 231, 9, 2, 2, 2, 231, 232, 3, 2, 2, 2, 232, 233, 8, 35, 2, 2, 233, 71, 3, 2, 2, 2, 234, 236, 9, 25, 2, 2, 235, 234, 3, 2, 2, 2, 236, 237, 3, 2, 2, 2, 237, 235, 3, 2, 2, 2, 237, 238, 3, 2, 2, 2, 238, 239, 3, 2, 2, 2, 239, 240, 8, 36, 4, 2, 240, 73, 3, 2, 2, 2, 241, 242, 11, 2, 2, 2, 242, 75, 3, 2, 2, 2, 17, 2, 3, 85, 90, 94, 148, 170, 180, 202, 207, 212, 215, 221, 226, 237, 5, 2, 3, 2, 7, 3, 2, 6, 2, 2] \ No newline at end of file diff --git a/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.java b/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.java new file mode 100644 index 000000000..c007eabe9 --- /dev/null +++ b/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.java @@ -0,0 +1,199 @@ +// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 by ANTLR 4.9.1 +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class SSEMLexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.9.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + WS=1, COMMENT=2, EOL=3, JMP=4, JPR=5, LDN=6, STO=7, SUB=8, CMP=9, STP=10, + START=11, NUM=12, BNUM=13, NUMBER=14, HEXNUMBER=15, ERROR=16, BWS=17, + BinaryNumber=18, BERROR=19; + public static final int + BIN=1; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE", "BIN" + }; + + private static String[] makeRuleNames() { + return new String[] { + "WS", "COMMENT", "EOL", "J", "M", "P", "R", "L", "D", "N", "S", "T", + "O", "U", "B", "C", "K", "H", "A", "I", "JMP", "JPR", "LDN", "STO", "SUB", + "CMP", "STP", "START", "NUM", "BNUM", "NUMBER", "HEXNUMBER", "ERROR", + "BWS", "BinaryNumber", "BERROR" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "WS", "COMMENT", "EOL", "JMP", "JPR", "LDN", "STO", "SUB", "CMP", + "STP", "START", "NUM", "BNUM", "NUMBER", "HEXNUMBER", "ERROR", "BWS", + "BinaryNumber", "BERROR" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public SSEMLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "SSEMLexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\25\u00f3\b\1\b\1"+ + "\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t"+ + "\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4"+ + "\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4"+ + "\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4"+ + " \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3"+ + "\3\5\3V\n\3\3\3\7\3Y\n\3\f\3\16\3\\\13\3\3\4\5\4_\n\4\3\4\3\4\3\5\3\5"+ + "\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\16"+ + "\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3\22\3\22\3\23\3\23\3\24\3\24\3\25"+ + "\3\25\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27"+ + "\3\27\3\27\3\27\5\27\u0095\n\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31"+ + "\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\5\33\u00ab"+ + "\n\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\5\34\u00b5\n\34\3\35\3\35"+ + "\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3\37"+ + "\3\37\3\37\3\37\3\37\5\37\u00cb\n\37\3\37\3\37\3 \5 \u00d0\n \3 \6 \u00d3"+ + "\n \r \16 \u00d4\3!\5!\u00d8\n!\3!\3!\3!\3!\5!\u00de\n!\3!\6!\u00e1\n"+ + "!\r!\16!\u00e2\3\"\3\"\3#\3#\3#\3#\3$\6$\u00ec\n$\r$\16$\u00ed\3$\3$\3"+ + "%\3%\2\2&\4\3\6\4\b\5\n\2\f\2\16\2\20\2\22\2\24\2\26\2\30\2\32\2\34\2"+ + "\36\2 \2\"\2$\2&\2(\2*\2,\6.\7\60\b\62\t\64\n\66\138\f:\r<\16>\17@\20"+ + "B\21D\22F\23H\24J\25\4\2\3\32\4\2\13\13\"\"\4\2%%==\4\2\f\f\17\17\4\2"+ + "LLll\4\2OOoo\4\2RRrr\4\2TTtt\4\2NNnn\4\2FFff\4\2PPpp\4\2UUuu\4\2VVvv\4"+ + "\2QQqq\4\2WWww\4\2DDdd\4\2EEee\4\2MMmm\4\2JJjj\4\2CCcc\4\2KKkk\3\2//\3"+ + "\2\62;\5\2\62;CHch\3\2\62\63\2\u00ef\2\4\3\2\2\2\2\6\3\2\2\2\2\b\3\2\2"+ + "\2\2,\3\2\2\2\2.\3\2\2\2\2\60\3\2\2\2\2\62\3\2\2\2\2\64\3\2\2\2\2\66\3"+ + "\2\2\2\28\3\2\2\2\2:\3\2\2\2\2<\3\2\2\2\2>\3\2\2\2\2@\3\2\2\2\2B\3\2\2"+ + "\2\2D\3\2\2\2\3F\3\2\2\2\3H\3\2\2\2\3J\3\2\2\2\4L\3\2\2\2\6U\3\2\2\2\b"+ + "^\3\2\2\2\nb\3\2\2\2\fd\3\2\2\2\16f\3\2\2\2\20h\3\2\2\2\22j\3\2\2\2\24"+ + "l\3\2\2\2\26n\3\2\2\2\30p\3\2\2\2\32r\3\2\2\2\34t\3\2\2\2\36v\3\2\2\2"+ + " x\3\2\2\2\"z\3\2\2\2$|\3\2\2\2&~\3\2\2\2(\u0080\3\2\2\2*\u0082\3\2\2"+ + "\2,\u0084\3\2\2\2.\u0094\3\2\2\2\60\u0096\3\2\2\2\62\u009a\3\2\2\2\64"+ + "\u009e\3\2\2\2\66\u00aa\3\2\2\28\u00b4\3\2\2\2:\u00b6\3\2\2\2<\u00bc\3"+ + "\2\2\2>\u00ca\3\2\2\2@\u00cf\3\2\2\2B\u00d7\3\2\2\2D\u00e4\3\2\2\2F\u00e6"+ + "\3\2\2\2H\u00eb\3\2\2\2J\u00f1\3\2\2\2LM\t\2\2\2MN\3\2\2\2NO\b\2\2\2O"+ + "\5\3\2\2\2PQ\7\61\2\2QV\7\61\2\2RS\7/\2\2SV\7/\2\2TV\t\3\2\2UP\3\2\2\2"+ + "UR\3\2\2\2UT\3\2\2\2VZ\3\2\2\2WY\n\4\2\2XW\3\2\2\2Y\\\3\2\2\2ZX\3\2\2"+ + "\2Z[\3\2\2\2[\7\3\2\2\2\\Z\3\2\2\2]_\7\17\2\2^]\3\2\2\2^_\3\2\2\2_`\3"+ + "\2\2\2`a\7\f\2\2a\t\3\2\2\2bc\t\5\2\2c\13\3\2\2\2de\t\6\2\2e\r\3\2\2\2"+ + "fg\t\7\2\2g\17\3\2\2\2hi\t\b\2\2i\21\3\2\2\2jk\t\t\2\2k\23\3\2\2\2lm\t"+ + "\n\2\2m\25\3\2\2\2no\t\13\2\2o\27\3\2\2\2pq\t\f\2\2q\31\3\2\2\2rs\t\r"+ + "\2\2s\33\3\2\2\2tu\t\16\2\2u\35\3\2\2\2vw\t\17\2\2w\37\3\2\2\2xy\t\20"+ + "\2\2y!\3\2\2\2z{\t\21\2\2{#\3\2\2\2|}\t\22\2\2}%\3\2\2\2~\177\t\23\2\2"+ + "\177\'\3\2\2\2\u0080\u0081\t\24\2\2\u0081)\3\2\2\2\u0082\u0083\t\25\2"+ + "\2\u0083+\3\2\2\2\u0084\u0085\5\n\5\2\u0085\u0086\5\f\6\2\u0086\u0087"+ + "\5\16\7\2\u0087-\3\2\2\2\u0088\u0089\5\n\5\2\u0089\u008a\5\16\7\2\u008a"+ + "\u008b\5\20\b\2\u008b\u0095\3\2\2\2\u008c\u008d\5\n\5\2\u008d\u008e\5"+ + "\20\b\2\u008e\u008f\5\16\7\2\u008f\u0095\3\2\2\2\u0090\u0091\5\n\5\2\u0091"+ + "\u0092\5\f\6\2\u0092\u0093\5\20\b\2\u0093\u0095\3\2\2\2\u0094\u0088\3"+ + "\2\2\2\u0094\u008c\3\2\2\2\u0094\u0090\3\2\2\2\u0095/\3\2\2\2\u0096\u0097"+ + "\5\22\t\2\u0097\u0098\5\24\n\2\u0098\u0099\5\26\13\2\u0099\61\3\2\2\2"+ + "\u009a\u009b\5\30\f\2\u009b\u009c\5\32\r\2\u009c\u009d\5\34\16\2\u009d"+ + "\63\3\2\2\2\u009e\u009f\5\30\f\2\u009f\u00a0\5\36\17\2\u00a0\u00a1\5 "+ + "\20\2\u00a1\65\3\2\2\2\u00a2\u00a3\5\"\21\2\u00a3\u00a4\5\f\6\2\u00a4"+ + "\u00a5\5\16\7\2\u00a5\u00ab\3\2\2\2\u00a6\u00a7\5\30\f\2\u00a7\u00a8\5"+ + "$\22\2\u00a8\u00a9\5\26\13\2\u00a9\u00ab\3\2\2\2\u00aa\u00a2\3\2\2\2\u00aa"+ + "\u00a6\3\2\2\2\u00ab\67\3\2\2\2\u00ac\u00ad\5\30\f\2\u00ad\u00ae\5\32"+ + "\r\2\u00ae\u00af\5\16\7\2\u00af\u00b5\3\2\2\2\u00b0\u00b1\5&\23\2\u00b1"+ + "\u00b2\5\22\t\2\u00b2\u00b3\5\32\r\2\u00b3\u00b5\3\2\2\2\u00b4\u00ac\3"+ + "\2\2\2\u00b4\u00b0\3\2\2\2\u00b59\3\2\2\2\u00b6\u00b7\5\30\f\2\u00b7\u00b8"+ + "\5\32\r\2\u00b8\u00b9\5(\24\2\u00b9\u00ba\5\20\b\2\u00ba\u00bb\5\32\r"+ + "\2\u00bb;\3\2\2\2\u00bc\u00bd\5\26\13\2\u00bd\u00be\5\36\17\2\u00be\u00bf"+ + "\5\f\6\2\u00bf=\3\2\2\2\u00c0\u00c1\5 \20\2\u00c1\u00c2\5\26\13\2\u00c2"+ + "\u00c3\5\36\17\2\u00c3\u00c4\5\f\6\2\u00c4\u00cb\3\2\2\2\u00c5\u00c6\5"+ + " \20\2\u00c6\u00c7\5*\25\2\u00c7\u00c8\5\26\13\2\u00c8\u00c9\5\30\f\2"+ + "\u00c9\u00cb\3\2\2\2\u00ca\u00c0\3\2\2\2\u00ca\u00c5\3\2\2\2\u00cb\u00cc"+ + "\3\2\2\2\u00cc\u00cd\b\37\3\2\u00cd?\3\2\2\2\u00ce\u00d0\t\26\2\2\u00cf"+ + "\u00ce\3\2\2\2\u00cf\u00d0\3\2\2\2\u00d0\u00d2\3\2\2\2\u00d1\u00d3\t\27"+ + "\2\2\u00d2\u00d1\3\2\2\2\u00d3\u00d4\3\2\2\2\u00d4\u00d2\3\2\2\2\u00d4"+ + "\u00d5\3\2\2\2\u00d5A\3\2\2\2\u00d6\u00d8\t\26\2\2\u00d7\u00d6\3\2\2\2"+ + "\u00d7\u00d8\3\2\2\2\u00d8\u00dd\3\2\2\2\u00d9\u00da\7\62\2\2\u00da\u00de"+ + "\7z\2\2\u00db\u00dc\7\62\2\2\u00dc\u00de\7Z\2\2\u00dd\u00d9\3\2\2\2\u00dd"+ + "\u00db\3\2\2\2\u00de\u00e0\3\2\2\2\u00df\u00e1\t\30\2\2\u00e0\u00df\3"+ + "\2\2\2\u00e1\u00e2\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e2\u00e3\3\2\2\2\u00e3"+ + "C\3\2\2\2\u00e4\u00e5\13\2\2\2\u00e5E\3\2\2\2\u00e6\u00e7\t\2\2\2\u00e7"+ + "\u00e8\3\2\2\2\u00e8\u00e9\b#\2\2\u00e9G\3\2\2\2\u00ea\u00ec\t\31\2\2"+ + "\u00eb\u00ea\3\2\2\2\u00ec\u00ed\3\2\2\2\u00ed\u00eb\3\2\2\2\u00ed\u00ee"+ + "\3\2\2\2\u00ee\u00ef\3\2\2\2\u00ef\u00f0\b$\4\2\u00f0I\3\2\2\2\u00f1\u00f2"+ + "\13\2\2\2\u00f2K\3\2\2\2\21\2\3UZ^\u0094\u00aa\u00b4\u00ca\u00cf\u00d4"+ + "\u00d7\u00dd\u00e2\u00ed\5\2\3\2\7\3\2\6\2\2"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java index 4da428894..2c909d694 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java @@ -14,8 +14,10 @@ public ByteBuffer generateCode(Program program) { program.forEach((line, instruction) -> { code.position(4 * (line + 1)); - if (instruction.tokenType == SSEMParser.BNUM || instruction.tokenType == SSEMParser.NUM) { + if (instruction.tokenType == SSEMParser.BNUM) { code.putInt((int)instruction.operand); + } else if (instruction.tokenType == SSEMParser.NUM) { + code.putInt((int)NumberUtils.reverseBits(instruction.operand, 32)); } else { writeInstruction(instruction.getOpcode(), instruction.operand); } diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java index 8c49ee6ee..2cfcf15ff 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java @@ -72,7 +72,7 @@ CPU.RunState step() { } break; case 4: // JPR, JRP, JMR - CI.addAndGet(readLineAddress(lineAddress)); + CI.addAndGet(readInt(lineAddress)*4); break; case 2: // LDN int tmp = readInt(lineAddress); diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java index 2e26178ed..967e96a8a 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java @@ -57,7 +57,9 @@ public void internalStateChanged() { int ci = engine.CI.get(); txtA.setText(String.format("%08x", acc)); + txtDecA.setText(String.format("%d", acc)); txtCI.setText(String.format("%08x", ci / 4)); + txtDecCI.setText(String.format("%d", ci / 4)); txtBinA.setText(formatBinary(acc)); txtBinCI.setText(formatBinary(ci)); @@ -70,12 +72,20 @@ public void internalStateChanged() { txtLine.setText(String.format("%02x", line)); txtMLine.setText(String.format("%08x", NumberUtils.readInt(mLine, NumberUtils.Strategy.REVERSE_BITS))); + txtDecMCI.setText(String.format("%d", NumberUtils.readInt(mCI, NumberUtils.Strategy.REVERSE_BITS))); + txtDecLine.setText(String.format("%d", line)); + txtDecMLine.setText(String.format("%d", NumberUtils.readInt(mLine, NumberUtils.Strategy.REVERSE_BITS))); + txtBinMCI.setText(formatBinary(NumberUtils.readInt(mCI, NumberUtils.Strategy.BIG_ENDIAN))); txtBinLine.setText(formatBinary(line, 8)); txtBinMLine.setText(formatBinary(NumberUtils.readInt(mLine, NumberUtils.Strategy.BIG_ENDIAN))); } catch (IndexOutOfBoundsException e) { + txtLine.setText("?"); + txtDecLine.setText("?"); txtMCI.setText("?"); + txtDecMCI.setText("?"); txtMLine.setText("?"); + txtDecMLine.setText("?"); txtBinMCI.setText("?"); txtBinMLine.setText("?"); } @@ -107,18 +117,23 @@ private void initComponents() { JLabel jLabel2 = new JLabel(); JLabel jLabel3 = new JLabel(); txtCI = new JTextField(); + txtDecCI = new JTextField(); txtA = new JTextField(); + txtDecA = new JTextField(); txtBinA = new JTextField(); txtBinCI = new JTextField(); JPanel jPanel3 = new JPanel(); JLabel jLabel4 = new JLabel(); JLabel jLabel5 = new JLabel(); txtMLine = new JTextField(); + txtDecMLine = new JTextField(); txtMCI = new JTextField(); + txtDecMCI = new JTextField(); txtBinMCI = new JTextField(); txtBinMLine = new JTextField(); JLabel jLabel6 = new JLabel(); txtLine = new JTextField(); + txtDecLine = new JTextField(); txtBinLine = new JTextField(); jPanel1.setBorder(BorderFactory.createTitledBorder("Run control")); @@ -173,11 +188,21 @@ private void initComponents() { txtCI.setHorizontalAlignment(JTextField.RIGHT); txtCI.setText("0"); + txtDecCI.setEditable(false); + txtDecCI.setFont(MONOSPACED_PLAIN); + txtDecCI.setHorizontalAlignment(JTextField.RIGHT); + txtDecCI.setText("0"); + txtA.setEditable(false); txtA.setFont(MONOSPACED_PLAIN); txtA.setHorizontalAlignment(JTextField.RIGHT); txtA.setText("0"); + txtDecA.setEditable(false); + txtDecA.setFont(MONOSPACED_PLAIN); + txtDecA.setHorizontalAlignment(JTextField.RIGHT); + txtDecA.setText("0"); + txtBinA.setEditable(false); txtBinA.setFont(MONOSPACED_PLAIN); txtBinA.setHorizontalAlignment(JTextField.RIGHT); @@ -202,6 +227,10 @@ private void initComponents() { .addComponent(txtA, GroupLayout.DEFAULT_SIZE, 81, Short.MAX_VALUE) .addComponent(txtCI)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(txtDecA, GroupLayout.DEFAULT_SIZE, 81, Short.MAX_VALUE) + .addComponent(txtDecCI)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(txtBinCI) .addComponent(txtBinA)) @@ -214,11 +243,13 @@ private void initComponents() { .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(jLabel2) .addComponent(txtA, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDecA, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE) .addComponent(txtBinA, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(jLabel3) .addComponent(txtCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDecCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(txtBinCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -238,11 +269,21 @@ private void initComponents() { txtMLine.setHorizontalAlignment(JTextField.RIGHT); txtMLine.setText("0"); + txtDecMLine.setEditable(false); + txtDecMLine.setFont(MONOSPACED_PLAIN); + txtDecMLine.setHorizontalAlignment(JTextField.RIGHT); + txtDecMLine.setText("0"); + txtMCI.setEditable(false); txtMCI.setFont(MONOSPACED_PLAIN); txtMCI.setHorizontalAlignment(JTextField.RIGHT); txtMCI.setText("0"); + txtDecMCI.setEditable(false); + txtDecMCI.setFont(MONOSPACED_PLAIN); + txtDecMCI.setHorizontalAlignment(JTextField.RIGHT); + txtDecMCI.setText("0"); + txtBinMCI.setEditable(false); txtBinMCI.setFont(MONOSPACED_PLAIN); txtBinMCI.setHorizontalAlignment(JTextField.RIGHT); @@ -262,6 +303,11 @@ private void initComponents() { txtLine.setHorizontalAlignment(JTextField.RIGHT); txtLine.setText("0"); + txtDecLine.setEditable(false); + txtDecLine.setFont(MONOSPACED_PLAIN); + txtDecLine.setHorizontalAlignment(JTextField.RIGHT); + txtDecLine.setText("0"); + txtBinLine.setEditable(false); txtBinLine.setFont(MONOSPACED_PLAIN); txtBinLine.setHorizontalAlignment(JTextField.RIGHT); @@ -279,6 +325,8 @@ private void initComponents() { .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(txtMLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtDecMLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(txtBinMLine)) .addGroup(jPanel3Layout.createSequentialGroup() .addGap(14, 14, 14) @@ -290,10 +338,14 @@ private void initComponents() { .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(txtMCI, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtDecMCI, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(txtBinMCI)) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(txtLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtDecLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(txtBinLine))))) .addContainerGap()) ); @@ -304,16 +356,19 @@ private void initComponents() { .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(jLabel4) .addComponent(txtMCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDecMCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(txtBinMCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(jLabel6) .addComponent(txtLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDecLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(txtBinLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(jLabel5) .addComponent(txtMLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDecMLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(txtBinMLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -347,14 +402,19 @@ private void initComponents() { private JLabel lblRunState; private JLabel lblSpeed; private JTextField txtA; + private JTextField txtDecA; private JTextField txtBinA; - private JTextField txtBinCI; private JTextField txtBinLine; private JTextField txtBinMCI; private JTextField txtBinMLine; private JTextField txtCI; + private JTextField txtDecCI; + private JTextField txtBinCI; private JTextField txtLine; + private JTextField txtDecLine; private JTextField txtMCI; + private JTextField txtDecMCI; private JTextField txtMLine; + private JTextField txtDecMLine; // End of variables declaration//GEN-END:variables } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/CellRenderer.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/CellRenderer.java index 30890efc3..1460c0d2f 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/CellRenderer.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/CellRenderer.java @@ -36,7 +36,7 @@ class CellRenderer extends JLabel implements TableCellRenderer { String[] rowNames = new String[model.getColumnCount()]; for (int i = 0; i < rowNames.length; i++) { - rowNames[i] = String.format("%02X", i); + rowNames[i] = String.format("%02X / %02d", i, i); } rowHeader = new JList<>(rowNames); rowHeader.setCellRenderer(rowHeaderRenderer); @@ -73,7 +73,11 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole setFont(DEFAULT_FONT); } - setBackground(back); + if (MemoryTableModel.isBitLine(column)) { + setBackground(COLOR_BACK_LINE); + } else { + setBackground(back); + } setForeground(front); } setText(value.toString()); diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/Constants.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/Constants.java index c21650cf7..cf800c622 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/Constants.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/Constants.java @@ -26,6 +26,8 @@ public final class Constants { public final static Color COLOR_FORE = Color.BLACK; public final static Color COLOR_FORE_UNIMPORTANT = Color.DARK_GRAY; + public final static Color COLOR_BACK_LINE = new Color(0xF3, 0xE3, 0xEC); + public final static Font DEFAULT_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 12); public final static Font BOLD_FONT = new Font(Font.MONOSPACED, Font.BOLD, 12); @@ -38,6 +40,6 @@ public final class Constants { TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, - 10 * CHAR_WIDTH, 5 * CHAR_WIDTH + 10 * CHAR_WIDTH, 10 * CHAR_WIDTH, 5 * CHAR_WIDTH }; } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java index ca4574695..05b1bd96f 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java @@ -31,10 +31,11 @@ public class MemoryTableModel extends AbstractTableModel { private final static Logger LOGGER = LoggerFactory.getLogger(MemoryTableModel.class); final static int COLUMN_HEX_VALUE = 32; - final static int COLUMN_RAW_VALUE = 33; + final static int COLUMN_DEC_VALUE = 33; + final static int COLUMN_RAW_VALUE = 34; private final static int ROW_COUNT = 32; - private final static int COLUMN_COUNT = 2 + 32; + private final static int COLUMN_COUNT = 3 + 32; private final MemoryContext memory; @@ -78,9 +79,11 @@ static boolean isBitLine(int column) { public String getColumnName(int columnIndex) { switch (columnIndex) { case COLUMN_HEX_VALUE: - return "Value (hex)"; + return "Hex"; + case COLUMN_DEC_VALUE: + return "Dec"; case COLUMN_RAW_VALUE: - return "Raw"; + return "Char"; } if (isBitLine(columnIndex)) { return "L"; @@ -112,6 +115,8 @@ public Object getValueAt(int rowIndex, int columnIndex) { switch (columnIndex) { case COLUMN_HEX_VALUE: return RadixUtils.formatDwordHexString(value).toUpperCase(); + case COLUMN_DEC_VALUE: + return String.valueOf(value); case COLUMN_RAW_VALUE: return "" + (char) ((value >>> 24) & 0xFF) + (char) ((value >>> 16) & 0xFF) + (char) ((value >>> 8) & 0xFF) + (char) (value & 0xFF); @@ -134,6 +139,8 @@ public void setValueAt(Object aValue, int rowIndex, int columnIndex) { if (columnIndex == COLUMN_HEX_VALUE) { writeHex(str, row); + } else if (columnIndex == COLUMN_DEC_VALUE) { + writeHex(str, row); } else if (columnIndex == COLUMN_RAW_VALUE) { writeChar((String) aValue, row); } else if (columnIndex >= 0 && columnIndex < 33) { @@ -187,12 +194,13 @@ private void writeBit(String aValue, int columnIndex, Byte[] row) { @Override public boolean isCellEditable(int rowIndex, int columnIndex) { - return columnIndex >= 0 && columnIndex <= 33; + return columnIndex >= 0 && columnIndex <= 34; } void dataChangedAt(int address) { + int row = address / 4; for (int i = 0; i < COLUMN_COUNT; i++) { - fireTableCellUpdated(address, i); + fireTableCellUpdated(row, i); } } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/RowHeaderRenderer.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/RowHeaderRenderer.java index 09cb259db..076f9f87d 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/RowHeaderRenderer.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/RowHeaderRenderer.java @@ -28,7 +28,7 @@ class RowHeaderRenderer extends JLabel implements ListCellRenderer { private int height; RowHeaderRenderer() { - super.setBorder(UIManager.getBorder("TableHeader.cellBorder")); + super.setBorder(UIManager.getBorder("Button.border")); super.setHorizontalAlignment(CENTER); super.setFont(Constants.DEFAULT_FONT); } diff --git a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModelTest.java b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModelTest.java index 0db2143a9..cfba2455d 100644 --- a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModelTest.java +++ b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModelTest.java @@ -37,8 +37,9 @@ public void testEditableAreOnlyValueColumns() { MemoryTableModel model = new MemoryTableModel(createMock(MemoryContext.class)); assertTrue(model.isCellEditable(0, MemoryTableModel.COLUMN_HEX_VALUE)); + assertTrue(model.isCellEditable(0, MemoryTableModel.COLUMN_DEC_VALUE)); assertTrue(model.isCellEditable(0, MemoryTableModel.COLUMN_RAW_VALUE)); - assertFalse(model.isCellEditable(0, 34)); + assertFalse(model.isCellEditable(0, 35)); for (int i = 0; i < 32; i++) { assertTrue(model.isCellEditable(0, i)); @@ -95,6 +96,24 @@ public void testSetHexValueCellsMemoryWrite() { verify(memoryContext); } + @Test + public void testSetDecValueCellsMemoryWrite() { + MemoryContext memoryContext = createMock(MemoryContext.class); + + Byte[] row = new Byte[]{1, 2, 3, 4}; + Byte[] modified = new Byte[]{(byte) 0xFF, 0, 0, 0}; + + expect(memoryContext.read(10 * 4, 4)).andReturn(row); + memoryContext.write(eq(10 * 4), aryEq(modified)); + expectLastCall().once(); + replay(memoryContext); + + MemoryTableModel model = new MemoryTableModel(memoryContext); + model.setValueAt("0xFF", 10, MemoryTableModel.COLUMN_DEC_VALUE); + + verify(memoryContext); + } + @Test public void testSetCharValueCellsMemoryWrite() { MemoryContext memoryContext = createMock(MemoryContext.class); From 7172c10ef5e61b0faa32088d40c851c2bde67c49 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 30 Aug 2021 09:19:34 +0200 Subject: [PATCH 035/314] [#201] Optimizations: compiler, memory, CPU + Introduction of "data" opcode in CPU --- .../{api => }/ApplicationApiImpl.java | 2 +- .../net/emustudio/application/Runner.java | 2 +- .../application/gui/debugtable/CallFlow.java | 2 +- .../virtualcomputer/VirtualComputer.java | 22 +++---- build.gradle | 2 +- .../as-ssem/src/main/examples/diffeqt.ssem | 31 ---------- .../plugins/compiler/ssem/CodeGenerator.java | 14 ++--- .../plugins/compiler/ssem/SSEMCompiler.java | 12 ++-- .../plugins/compiler/ssem/RunnerTest.java | 14 +++-- .../compiler/ssem/SSEMCompilerTest.java | 2 +- plugins/cpu/8080-cpu/build.gradle | 11 +++- plugins/cpu/8080-cpu/src/main/edigen/cpu.eds | 2 + .../plugins/cpu/intel8080/EmulatorEngine.java | 6 +- plugins/cpu/ssem-cpu/build.gradle | 12 +++- plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds | 11 ++-- .../plugins/cpu/ssem/EmulatorEngine.java | 7 ++- .../plugins/cpu/ssem/DecoderTest.java | 33 ++++++++++ .../device/ssem/display/DisplayPanel.java | 62 +++++++------------ .../memory/ssem/MemoryContextImpl.java | 5 +- settings.gradle | 8 ++- 20 files changed, 132 insertions(+), 128 deletions(-) rename application/src/main/java/net/emustudio/application/{api => }/ApplicationApiImpl.java (97%) delete mode 100644 plugins/compiler/as-ssem/src/main/examples/diffeqt.ssem create mode 100644 plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DecoderTest.java diff --git a/application/src/main/java/net/emustudio/application/api/ApplicationApiImpl.java b/application/src/main/java/net/emustudio/application/ApplicationApiImpl.java similarity index 97% rename from application/src/main/java/net/emustudio/application/api/ApplicationApiImpl.java rename to application/src/main/java/net/emustudio/application/ApplicationApiImpl.java index cca115071..bbd48d5d5 100644 --- a/application/src/main/java/net/emustudio/application/api/ApplicationApiImpl.java +++ b/application/src/main/java/net/emustudio/application/ApplicationApiImpl.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.application.api; +package net.emustudio.application; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; diff --git a/application/src/main/java/net/emustudio/application/Runner.java b/application/src/main/java/net/emustudio/application/Runner.java index 06dc4cba9..a7017616a 100644 --- a/application/src/main/java/net/emustudio/application/Runner.java +++ b/application/src/main/java/net/emustudio/application/Runner.java @@ -18,7 +18,6 @@ */ package net.emustudio.application; -import net.emustudio.application.api.ApplicationApiImpl; import net.emustudio.application.configuration.ApplicationConfig; import net.emustudio.application.configuration.ComputerConfig; import net.emustudio.application.configuration.ConfigFiles; @@ -65,6 +64,7 @@ public static void main(String[] args) { Path configFile = Path.of("emuStudio.toml"); if (Files.notExists(configFile)) { + LOGGER.warn("No configuration file found; creating empty one"); Files.createFile(configFile); } ApplicationConfig applicationConfig = ApplicationConfig.fromFile( diff --git a/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java b/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java index 0c7750661..b3c15283d 100644 --- a/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java +++ b/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java @@ -46,7 +46,7 @@ void updateCache(int currentLocation) { } flowGraph.put(currentLocation, nextPosition); } catch (RuntimeException ex) { - LOGGER.error("Could not update call-flow cache", ex); + LOGGER.warn("Could not update call-flow cache", ex); } } diff --git a/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java b/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java index 30c26f5d2..f58c74b53 100644 --- a/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java +++ b/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java @@ -39,6 +39,7 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; import java.util.stream.IntStream; +import java.util.stream.Stream; import static net.emustudio.application.internal.Reflection.doesImplement; @@ -71,18 +72,18 @@ public VirtualComputer(ComputerConfig computerConfig, Map plug }); } - public ComputerConfig getComputerConfig() { + public ComputerConfig getComputerConfig() { return computerConfig; } public void initialize(ContextPoolImpl contextPool) throws PluginInitializationException { contextPool.setComputer(this); - List pluginsToInitialize = List.of( + List pluginsToInitialize = Stream.of( pluginsByType.getOrDefault(PLUGIN_TYPE.COMPILER, Collections.emptyList()), pluginsByType.getOrDefault(PLUGIN_TYPE.MEMORY, Collections.emptyList()), pluginsByType.getOrDefault(PLUGIN_TYPE.CPU, Collections.emptyList()), pluginsByType.getOrDefault(PLUGIN_TYPE.DEVICE, Collections.emptyList()) - ).stream().flatMap(Collection::stream).collect(Collectors.toList()); + ).flatMap(Collection::stream).collect(Collectors.toList()); pluginsToInitialize.forEach(meta -> Unchecked.run(meta.pluginInstance::initialize)); } @@ -140,12 +141,11 @@ public static VirtualComputer create(ComputerConfig computerConfig, ApplicationA private static Map loadPlugins(ComputerConfig computerConfig, ApplicationApi applicationApi, ApplicationConfig applicationConfig, ConfigFiles configFiles) throws IOException, InvalidPluginException { - List pluginConfigs = List.of( - computerConfig.getCompiler(), - computerConfig.getCPU(), - computerConfig.getMemory() - ).stream() - .map(opt -> opt.map(List::of).orElse(Collections.emptyList())) + List pluginConfigs = Stream.of( + computerConfig.getCompiler(), + computerConfig.getCPU(), + computerConfig.getMemory() + ).map(opt -> opt.map(List::of).orElse(Collections.emptyList())) .flatMap(List::stream) .collect(Collectors.toList()); pluginConfigs.addAll(computerConfig.getDevices()); @@ -198,12 +198,12 @@ private static Map constructPlugins(ComputerConfig computerCon } private static Plugin createPluginInstance(long pluginID, Class mainClass, ApplicationApi applicationApi, - PluginSettings pluginSettings) throws InvalidPluginException { + PluginSettings pluginSettings) throws InvalidPluginException { Objects.requireNonNull(mainClass); Objects.requireNonNull(applicationApi); // First parameter of constructor is plug-in ID - Class[] constructorParams = { long.class, ApplicationApi.class, PluginSettings.class }; + Class[] constructorParams = {long.class, ApplicationApi.class, PluginSettings.class}; try { Constructor constructor = mainClass.getDeclaredConstructor(constructorParams); diff --git a/build.gradle b/build.gradle index 9ec65e3c2..529c751a2 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ ext.versions = [ ] ext.libs = [ - emuLib : "net.emustudio:emulib:11.6.0-SNAPSHOT", + emuLib : "net.emustudio:emulib:11.7.0-SNAPSHOT", cpuTestSuite : "net.emustudio:cpu-testsuite_11.6:1.2.0-SNAPSHOT", javaCupRuntime : "com.github.vbmacher:java-cup-runtime:11b-20160615", diff --git a/plugins/compiler/as-ssem/src/main/examples/diffeqt.ssem b/plugins/compiler/as-ssem/src/main/examples/diffeqt.ssem deleted file mode 100644 index 9afa79029..000000000 --- a/plugins/compiler/as-ssem/src/main/examples/diffeqt.ssem +++ /dev/null @@ -1,31 +0,0 @@ -0001 LDN 29 -0002 SUB 29 -0003 STO 29 -0004 CMP -0005 STP -0006 LDN 29 -0007 STO 29 -0008 LDN 22 -0009 SUB 29 -0010 STO 30 -0011 LDN 30 -0012 STO 22 -0013 LDN 8 -0014 SUB 28 -0015 STO 30 -0016 LDN 30 -0017 STO 8 -0018 SUB 27 -0019 STO 12 -0020 LDN 28 -0021 SUB 26 -0022 STO 28 -0023 LDN 28 -0024 STO 28 -0025 JMP 31 -0026 NUM 1 -0027 NUM -8192 -0028 NUM -6 -0029 NUM 131072 -0030 NUM 0 -0031 NUM 0 diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java index 2c909d694..9a7cd639a 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java @@ -15,9 +15,9 @@ public ByteBuffer generateCode(Program program) { program.forEach((line, instruction) -> { code.position(4 * (line + 1)); if (instruction.tokenType == SSEMParser.BNUM) { - code.putInt((int)instruction.operand); + code.putInt((int) instruction.operand); } else if (instruction.tokenType == SSEMParser.NUM) { - code.putInt((int)NumberUtils.reverseBits(instruction.operand, 32)); + code.putInt((int) NumberUtils.reverseBits(instruction.operand, 32)); } else { writeInstruction(instruction.getOpcode(), instruction.operand); } @@ -26,13 +26,7 @@ public ByteBuffer generateCode(Program program) { } private void writeInstruction(int opcode, long operand) { - byte address = (byte)(NumberUtils.reverseBits((byte)(operand & 0xFF), 8) & 0xF8); - // 5 bits address + 3 empty bits - code.put(address); - // next: 5 empty bits + 3 bit instruction - code.put((byte)(opcode & 0xFF)); - // 16 empty bits - code.put((byte)0); - code.put((byte)0); + int instruction = (int)((((operand & 0x1F) << 27)) | (((opcode & 0x07) << 16))); + code.putInt(NumberUtils.reverseBits(instruction, 32)); } } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java index 1a4cc8c71..00c0ca103 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java @@ -70,7 +70,7 @@ public void initialize() { memory = pool.getMemoryContext(pluginID, MemoryContext.class); if (memory.getDataType() != Byte.class) { throw new InvalidContextException( - "Unexpected memory cell type. Expected Short but was: " + memory.getDataType() + "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() ); } } catch (InvalidContextException | ContextNotFoundException e) { @@ -84,10 +84,6 @@ public boolean compile(String inputFileName, String outputFileName) { notifyCompileStart(); notifyInfo(getTitle() + ", version " + getVersion()); - if (memory == null) { - notifyWarning("Memory is not available."); - } - try (Reader reader = new FileReader(inputFileName)) { Lexer lexer = createLexer(CharStreams.fromReader(reader)); lexer.addErrorListener(new ParserErrorListener()); @@ -111,8 +107,8 @@ public boolean compile(String inputFileName, String outputFileName) { programLocation = program.getStartLine() * 4; notifyInfo(String.format( - "Compile was successful. Output: %s\nProgram starts at %s", - RadixUtils.formatWordHexString(programLocation), outputFileName + "Compile was successful.\n\tOutput: %s\n\tProgram starts at 0x%s", + outputFileName, RadixUtils.formatWordHexString(programLocation) )); } catch (CompileException e) { notifyError(e.line, e.column, e.getMessage()); @@ -143,6 +139,8 @@ private void writeToMemory(ByteBuffer code) { code.get(data); memory.clear(); memory.write(0, NumberUtils.nativeBytesToBytes(data)); + } else { + notifyWarning("Memory is not available."); } } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java index 1d6ed5ad4..6e5395212 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java @@ -42,13 +42,15 @@ public void testCommandLine() throws Exception { Runner.main("--output", outputFile.getPath(), sourceFile.getPath()); - List lines = Files.readAllLines(outputFile.toPath()); + byte[] bytes = Files.readAllBytes(outputFile.toPath()); - assertEquals(1, lines.size()); - byte[] expected = new byte[33 * 4]; // 32 words of 32 bits + 4 bytes for startLine - expected[4] = 104; - expected[5] = 6; - assertArrayEquals(expected, lines.get(0).getBytes()); + // 32 words of 32 bits + 4 bytes for startLine + assertEquals(33 * 4, bytes.length); + + byte[] expected = new byte[33 * 4]; + expected[6] = 0x60; + expected[7] = 0x0D; + assertArrayEquals(expected, bytes); } @Test diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java index f6ae3db2d..9a316f1ad 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java @@ -97,7 +97,7 @@ public void testSTO() throws Exception { ); assertProgram( - 0x68, 6, 0, 0 + 0, 0, 0x60, 0x0D ); } } diff --git a/plugins/cpu/8080-cpu/build.gradle b/plugins/cpu/8080-cpu/build.gradle index e463112ee..f984bacd8 100644 --- a/plugins/cpu/8080-cpu/build.gradle +++ b/plugins/cpu/8080-cpu/build.gradle @@ -19,14 +19,21 @@ import org.apache.tools.ant.filters.ReplaceTokens +buildscript { + repositories { + mavenLocal() + mavenCentral() + } +} + plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.2.0' + id 'net.emustudio.edigen-plugin' version '1.4.0' } repositories { + mavenLocal() mavenCentral() - jcenter() } dependencies { diff --git a/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds b/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds index 93cba9164..4d1f48bba 100644 --- a/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds @@ -1,3 +1,5 @@ +root instruction; + instruction = "nop": 00000000 | "xchg": 0xEB | "sphl": 0xF9 | "xthl": 0xE3 | "daa": 0x27 | "cma": 0x2F | "rlc": 00000111 | "rrc": 00001111 | "ral": 0x17 | "rar": 0x1F | "stc": 0x37 | "cmc": 0x3F | "pchl": 0xE9 | "ret": 0xC9 | "rnz": 0xC0 | "rz": 0xC8 | "rnc": 0xD0 | "rc": 0xD8 | "rpo": 0xE0 | "rpe": 0xE8 | "rp": 0xF0 | "rm": 0xF8 | "ei": 0xFB | "di": 0xF3 | "hlt": 0x76 | diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java index 3eff52748..167f61bd6 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java @@ -258,12 +258,12 @@ private void auxCarry(int before, int sumWith) { } private int readWord(int address) { - Short[] read = memory.readWord(address); + Short[] read = memory.read(address, 2); return (read[1] << 8) | read[0]; } private void writeWord(int address, int value) { - memory.writeWord(address, new Short[]{(short) (value & 0xFF), (short) ((value >>> 8) & 0xFF)}); + memory.write(address, new Short[]{(short) (value & 0xFF), (short) ((value >>> 8) & 0xFF)}, 2); } private static final Method[] DISPATCH_TABLE = new Method[256]; @@ -428,7 +428,7 @@ private int O31_RAR(short OP) { private int O34_SHLD(short OP) { int DAR = readWord(PC); PC = (PC + 2) & 0xFFFF; - memory.writeWord(DAR, new Short[]{(short) regs[REG_L], (short) regs[REG_H]}); + memory.write(DAR, new Short[]{(short) regs[REG_L], (short) regs[REG_H]}, 2); return 16; } diff --git a/plugins/cpu/ssem-cpu/build.gradle b/plugins/cpu/ssem-cpu/build.gradle index 567bbdbd4..bda6c24ed 100644 --- a/plugins/cpu/ssem-cpu/build.gradle +++ b/plugins/cpu/ssem-cpu/build.gradle @@ -19,14 +19,21 @@ import org.apache.tools.ant.filters.ReplaceTokens +buildscript { + repositories { + mavenLocal() + mavenCentral() + } +} + plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.2.0' + id 'net.emustudio.edigen-plugin' version '1.4.0' } repositories { + mavenLocal() mavenCentral() - jcenter() } dependencies { @@ -46,6 +53,7 @@ jar { } } + edigen { decoderName = 'net.emustudio.plugins.cpu.ssem.DecoderImpl' disassemblerName = 'net.emustudio.plugins.cpu.ssem.DisassemblerImpl' diff --git a/plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds b/plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds index 6e1d70d4a..60dd35da3 100644 --- a/plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds @@ -1,3 +1,5 @@ +root instruction, data; + instruction = "JMP": line(5) ignore8(8) 000 ignore16(16) | "JPR": line(5) ignore8(8) 100 ignore16(16) | "LDN": line(5) ignore8(8) 010 ignore16(16) | @@ -6,13 +8,10 @@ instruction = "JMP": line(5) ignore8(8) 000 ignore16(16) | "CMP": 00000 ignore8(8) 011 ignore16(16) | "STP": 00000 ignore8(8) 111 ignore16(16); -line = arg: arg(5); - -ignore8 = arg: arg(8); - -ignore16 = arg: arg(16); +data = data: data(32); %% -"%s %d" = instruction line(shift_left, shift_left, shift_left, bit_reverse, absolute) ignore8 ignore16; +"%s %d" = instruction line ignore8 ignore16; "%s" = instruction ignore8 ignore16; +"%x" = data; diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java index 2cfcf15ff..c8e5dec21 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java @@ -35,6 +35,7 @@ public class EmulatorEngine { public final static int INSTRUCTIONS_PER_SECOND = 700; private final static int MEMORY_CELLS = 32 * 4; + private final static int LINE_MASK = 0b11111000; private final CPU cpu; private final MemoryContext memory; @@ -57,7 +58,7 @@ void reset(int startingPos) { CPU.RunState step() { Byte[] instruction = memory.read(CI.addAndGet(4), 4); - byte line = (byte)(NumberUtils.reverseBits(instruction[0] & 0b11111000, 8)); + byte line = (byte)(NumberUtils.reverseBits(instruction[0] & LINE_MASK, 8)); int lineAddress = line * 4; int opcode = instruction[1] & 7; @@ -98,7 +99,7 @@ CPU.RunState step() { } private int readLineAddress(int lineAddress) { - return 4 * NumberUtils.reverseBits(memory.read(lineAddress) & 0b11111000, 8); + return 4 * NumberUtils.reverseBits(memory.read(lineAddress) & LINE_MASK, 8); } private int readInt(int line) { @@ -145,7 +146,7 @@ CPU.RunState run() { private void fakeStep() { Byte[] instruction = memory.read(CI.get(), 4); - int line = NumberUtils.reverseBits(instruction[0], 8); + int line = NumberUtils.reverseBits(instruction[0] & LINE_MASK, 8); int opcode = instruction[1] & 3; CI.updateAndGet(ci -> (ci + 4) % MEMORY_CELLS); diff --git a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DecoderTest.java b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DecoderTest.java new file mode 100644 index 000000000..90984ed67 --- /dev/null +++ b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DecoderTest.java @@ -0,0 +1,33 @@ +package net.emustudio.plugins.cpu.ssem; + +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; +import net.emustudio.emulib.plugins.cpu.DecodedInstruction; +import net.emustudio.emulib.plugins.cpu.DisassembledInstruction; +import net.emustudio.emulib.plugins.cpu.InvalidInstructionException; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.helpers.NumberUtils; +import org.junit.Test; + +import static org.easymock.EasyMock.createNiceMock; +import static org.junit.Assert.assertEquals; + +public class DecoderTest { + + @Test + public void testInstructionIsDecodedProperly() { + ByteMemoryStub memory = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); + memory.setMemory(new short[]{ + 0, 0, 0, 0, + 0x9B, 0xE2, 0xFC, 0x3F + }); + + DecoderImpl decoder = new DecoderImpl(memory); + DisassemblerImpl disassembler = new DisassemblerImpl(memory, decoder); + DisassembledInstruction instr = disassembler.disassemble(4); + + assertEquals(4, instr.getAddress()); + assertEquals("LDN 27", instr.getMnemo()); + assertEquals("9B E2 FC 3F", instr.getOpCode()); + } + +} diff --git a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java index 577d213e6..183d52048 100644 --- a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java +++ b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java @@ -28,50 +28,43 @@ @ThreadSafe public class DisplayPanel extends JPanel { + private final static int CELL_SIZE_BITS = 32; + private final static int CELL_SIZE_BYTES = CELL_SIZE_BITS / 8; + private final static int PIXEL_SIZE = 10; - private final static int PIXEL_SIZE_PLUS_GAP = PIXEL_SIZE + 2; - private final static int CELL_SIZE = 32; - private final static int ROWS = 32; + private final static int PIXEL_SIZE_WITH_GAP = PIXEL_SIZE + 2; - private final boolean[][] memory = new boolean[CELL_SIZE][CELL_SIZE]; + private final boolean[][] memory = new boolean[CELL_SIZE_BITS][CELL_SIZE_BITS]; DisplayPanel() { super.setBackground(Color.BLACK); super.setDoubleBuffered(true); } - void writeRow(Byte[] value, int row) { - int number = NumberUtils.readInt(value, NumberUtils.Strategy.BIG_ENDIAN); - Boolean[] bits = String - .format("%" + CELL_SIZE + "s", Integer.toBinaryString(number)) - .chars() - .mapToObj(c -> c == '1').toArray(Boolean[]::new); - - for (int i = 0; i < ROWS; i++) { - memory[row][i] = bits[i]; - } - repaint(); - } - - void clear() { - for (boolean[] memoryRow : memory) { + void reset(MemoryContext memory) { + for (boolean[] memoryRow : this.memory) { Arrays.fill(memoryRow, false); } + for (int i = 0; i < CELL_SIZE_BITS; i++) { + Byte[] value = memory.read(i * CELL_SIZE_BYTES, CELL_SIZE_BYTES); + writeRow(value, i); + } repaint(); } - void reset(MemoryContext memory) { - clear(); - for (int i = 0; i < 4 * 32; i += 4) { - writeRow(memory.read(i, 4), i / 4); + void writeRow(Byte[] value, int row) { + int number = NumberUtils.readInt(value, NumberUtils.Strategy.REVERSE_BITS); + for (int i = 0; i < CELL_SIZE_BITS; i++) { + memory[row][i] = (((number >>> i) & 1) == 1); } + repaint(); } @Override public void paintComponent(Graphics g) { Dimension size = getSize(); - int startX = size.width / 2 - (CELL_SIZE / 2) * PIXEL_SIZE_PLUS_GAP - PIXEL_SIZE; - int startY = size.height / 2 - (ROWS / 2) * PIXEL_SIZE_PLUS_GAP; + int startX = size.width / 2 - (CELL_SIZE_BITS / 2) * PIXEL_SIZE_WITH_GAP - PIXEL_SIZE; + int startY = size.height / 2 - (CELL_SIZE_BITS / 2) * PIXEL_SIZE_WITH_GAP; g.setColor(Color.BLACK); g.fillRect(0, 0, size.width, size.height); @@ -80,23 +73,16 @@ public void paintComponent(Graphics g) { for (int j = 0; j < memory[i].length; j++) { if (memory[i][j]) { g.setColor(Color.GREEN); - g.fillRect( - startX + j * PIXEL_SIZE_PLUS_GAP, - startY + i * PIXEL_SIZE_PLUS_GAP, - PIXEL_SIZE, - PIXEL_SIZE - ); } else { g.setColor(Color.DARK_GRAY); - g.fillRect( - startX + j * PIXEL_SIZE_PLUS_GAP, - startY + i * PIXEL_SIZE_PLUS_GAP, - PIXEL_SIZE, - PIXEL_SIZE - ); } + g.fillRect( + startX + j * PIXEL_SIZE_WITH_GAP, + startY + i * PIXEL_SIZE_WITH_GAP, + PIXEL_SIZE, + PIXEL_SIZE + ); } } } - } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java index a5ac44388..487d2a92c 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java @@ -19,6 +19,7 @@ package net.emustudio.plugins.memory.ssem; import net.emustudio.emulib.plugins.memory.AbstractMemoryContext; +import net.emustudio.emulib.runtime.helpers.NumberUtils; import net.jcip.annotations.ThreadSafe; import java.util.Arrays; @@ -47,9 +48,7 @@ public Byte read(int from) { @Override public Byte[] read(int from, int count) { - Byte[] result = new Byte[count]; - System.arraycopy(memory, from, result, 0, count); - return result; + return Arrays.copyOfRange(memory, from, from + count); // from+count can be >= memory.length } @Override diff --git a/settings.gradle b/settings.gradle index f2f585d25..de5615a93 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,6 +17,11 @@ * along with this program. If not, see . */ +pluginManagement { + includeBuild '/home/vbmacher/projects/emustudio/edigen-gradle-plugin' +} + + rootProject.name = 'emuStudio' include ':application' @@ -28,7 +33,7 @@ include ':plugins:compiler:as-ssem' //include ':plugins:compiler:ramc-ram' //include ':plugins:compiler:raspc-rasp' -//include ':plugins:cpu:8080-cpu' +include ':plugins:cpu:8080-cpu' //include ':plugins:cpu:brainduck-cpu' //include ':plugins:cpu:ram-cpu' //include ':plugins:cpu:rasp-cpu' @@ -48,3 +53,4 @@ include ':plugins:device:ssem-display' //include ':plugins:memory:rasp-mem' include ':plugins:memory:ssem-mem' //include ':plugins:memory:byte-mem' + From af092a80cda3d92d5e4b8dd6540d1d4755c69efd Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 30 Aug 2021 10:30:34 +0200 Subject: [PATCH 036/314] [#201] Fix SSEM code generator --- .../plugins/compiler/ssem/CodeGenerator.java | 3 ++- .../plugins/compiler/ssem/RunnerTest.java | 7 ++---- .../compiler/ssem/SSEMCompilerTest.java | 24 ++++++++++++------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java index 9a7cd639a..26aa39016 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java @@ -19,6 +19,7 @@ public ByteBuffer generateCode(Program program) { } else if (instruction.tokenType == SSEMParser.NUM) { code.putInt((int) NumberUtils.reverseBits(instruction.operand, 32)); } else { + System.out.println(instruction); writeInstruction(instruction.getOpcode(), instruction.operand); } }); @@ -26,7 +27,7 @@ public ByteBuffer generateCode(Program program) { } private void writeInstruction(int opcode, long operand) { - int instruction = (int)((((operand & 0x1F) << 27)) | (((opcode & 0x07) << 16))); + int instruction = (int)((operand & 0x1F) | (((opcode & 0x07) << 12))); code.putInt(NumberUtils.reverseBits(instruction, 32)); } } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java index 6e5395212..38ee0ce90 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java @@ -25,7 +25,6 @@ import java.io.File; import java.nio.file.Files; import java.nio.file.StandardOpenOption; -import java.util.List; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -48,8 +47,8 @@ public void testCommandLine() throws Exception { assertEquals(33 * 4, bytes.length); byte[] expected = new byte[33 * 4]; - expected[6] = 0x60; - expected[7] = 0x0D; + expected[4] = 0x68; + expected[5] = 0x06; assertArrayEquals(expected, bytes); } @@ -67,6 +66,4 @@ public void testCommandLineNonexistantSourceFileDoesNotThrow() { public void testCommandLinePrintVersion() { Runner.main("--version"); } - - } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java index 9a316f1ad..dc6900101 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java @@ -31,12 +31,13 @@ import org.junit.rules.TemporaryFolder; import java.io.File; +import java.lang.reflect.Array; import java.nio.file.Files; import java.nio.file.StandardOpenOption; +import java.util.Arrays; import static org.easymock.EasyMock.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.*; public class SSEMCompilerTest { private SSEMCompiler compiler; @@ -72,12 +73,16 @@ private void compile(String content) throws Exception { } private void assertProgram(int... bytes) { - for (int i = 0; i < bytes.length; i++) { - assertEquals( - String.format("%d. expected=%x, but was=%x", i, bytes[i], memoryStub.read(i)), - bytes[i], (int) memoryStub.read(i) - ); - } + Byte[] value = memoryStub.read(0, bytes.length); + + assertArrayEquals( + String.format( + "Expected=%x, but was=%x", + NumberUtils.readInt(bytes, NumberUtils.Strategy.BIG_ENDIAN), + NumberUtils.readInt(value, NumberUtils.Strategy.BIG_ENDIAN) + ), + NumberUtils.nativeIntsToNativeBytes(bytes), NumberUtils.numbersToNativeBytes(value) + ); } @Test @@ -96,8 +101,9 @@ public void testSTO() throws Exception { "0 sto 22\n" ); + // 01101000 00000110 0000 0000 assertProgram( - 0, 0, 0x60, 0x0D + 0x68, 6, 0, 0 ); } } From 0cb5c62c2872a6c64d6ed121ef5ed352839d9e8e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 3 Sep 2021 11:11:31 +0200 Subject: [PATCH 037/314] [#201] Fixed tests --- .../compiler/ssem/SSEMCompilerTest.java | 26 ++++++++--- plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds | 2 +- .../plugins/cpu/ssem/DecoderTest.java | 33 ------------- .../plugins/cpu/ssem/DisassemblerTest.java | 46 +++++++++++++++++++ 4 files changed, 66 insertions(+), 41 deletions(-) delete mode 100644 plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DecoderTest.java create mode 100644 plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DisassemblerTest.java diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java index dc6900101..7f0a797d5 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java @@ -97,13 +97,25 @@ public void testCopyrightIsKnown() { @Test public void testSTO() throws Exception { - compile( - "0 sto 22\n" - ); + compile("00 STO 22\n"); + assertProgram(0x68, 6, 0, 0); + } - // 01101000 00000110 0000 0000 - assertProgram( - 0x68, 6, 0, 0 - ); + @Test + public void testLDN() throws Exception { + compile("00 LDN 29"); + assertProgram(0xB8,4,0,0); + } + + @Test + public void testSUB() throws Exception { + compile("00 SUB 30"); + assertProgram(0x78,8,0,0); + } + + @Test + public void testSTP() throws Exception { + compile("00 STP"); + assertProgram(0,0x0E,0,0); } } diff --git a/plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds b/plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds index 60dd35da3..830f7abda 100644 --- a/plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds @@ -12,6 +12,6 @@ data = data: data(32); %% -"%s %d" = instruction line ignore8 ignore16; +"%s %d" = instruction line(bit_reverse) ignore8 ignore16; "%s" = instruction ignore8 ignore16; "%x" = data; diff --git a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DecoderTest.java b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DecoderTest.java deleted file mode 100644 index 90984ed67..000000000 --- a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DecoderTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.emustudio.plugins.cpu.ssem; - -import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; -import net.emustudio.emulib.plugins.cpu.DecodedInstruction; -import net.emustudio.emulib.plugins.cpu.DisassembledInstruction; -import net.emustudio.emulib.plugins.cpu.InvalidInstructionException; -import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.helpers.NumberUtils; -import org.junit.Test; - -import static org.easymock.EasyMock.createNiceMock; -import static org.junit.Assert.assertEquals; - -public class DecoderTest { - - @Test - public void testInstructionIsDecodedProperly() { - ByteMemoryStub memory = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); - memory.setMemory(new short[]{ - 0, 0, 0, 0, - 0x9B, 0xE2, 0xFC, 0x3F - }); - - DecoderImpl decoder = new DecoderImpl(memory); - DisassemblerImpl disassembler = new DisassemblerImpl(memory, decoder); - DisassembledInstruction instr = disassembler.disassemble(4); - - assertEquals(4, instr.getAddress()); - assertEquals("LDN 27", instr.getMnemo()); - assertEquals("9B E2 FC 3F", instr.getOpCode()); - } - -} diff --git a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DisassemblerTest.java b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DisassemblerTest.java new file mode 100644 index 000000000..bec0bcbeb --- /dev/null +++ b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DisassemblerTest.java @@ -0,0 +1,46 @@ +package net.emustudio.plugins.cpu.ssem; + +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; +import net.emustudio.emulib.plugins.cpu.DecodedInstruction; +import net.emustudio.emulib.plugins.cpu.DisassembledInstruction; +import net.emustudio.emulib.plugins.cpu.InvalidInstructionException; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.ContextPool; +import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.helpers.Bits; +import net.emustudio.emulib.runtime.helpers.NumberUtils; +import org.junit.Test; + +import static net.emustudio.plugins.cpu.ssem.DecoderImpl.LINE; +import static org.easymock.EasyMock.*; +import static org.easymock.EasyMock.replay; +import static org.junit.Assert.assertEquals; + +public class DisassemblerTest { + private final ByteMemoryStub memory = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); + private final DecoderImpl decoder = new DecoderImpl(memory); + private final DisassemblerImpl disassembler = new DisassemblerImpl(memory, decoder); + + @Test + public void testLDN() { + memory.setMemory(new short[]{ + 0x9B, 0xE2, 0xFC, 0x3F + }); + + DisassembledInstruction instr = disassembler.disassemble(0); + assertEquals("LDN 25", instr.getMnemo()); + assertEquals("9B E2 FC 3F", instr.getOpCode()); + } + + @Test + public void testSTO() { + memory.setMemory(new short[]{ + 0,0,0,0, + 0x68, 0x06, 0x00, 0x00 + }); + + DisassembledInstruction instr = disassembler.disassemble(4); + assertEquals("STO 22", instr.getMnemo()); + assertEquals("68 06 00 00", instr.getOpCode()); + } +} From e05ee04964de069afcc575e2f38a159c85fbded9 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 3 Sep 2021 11:23:55 +0200 Subject: [PATCH 038/314] [#201] SSEM: Fix code generator --- .../plugins/compiler/ssem/CodeGenerator.java | 3 +-- .../emustudio/plugins/compiler/ssem/RunnerTest.java | 2 +- .../plugins/compiler/ssem/SSEMCompilerTest.java | 13 ++++++------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java index 26aa39016..47dc3b583 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java @@ -19,7 +19,6 @@ public ByteBuffer generateCode(Program program) { } else if (instruction.tokenType == SSEMParser.NUM) { code.putInt((int) NumberUtils.reverseBits(instruction.operand, 32)); } else { - System.out.println(instruction); writeInstruction(instruction.getOpcode(), instruction.operand); } }); @@ -27,7 +26,7 @@ public ByteBuffer generateCode(Program program) { } private void writeInstruction(int opcode, long operand) { - int instruction = (int)((operand & 0x1F) | (((opcode & 0x07) << 12))); + int instruction = (int)((operand & 0x1F) | (((opcode & 0x07) << 13))); code.putInt(NumberUtils.reverseBits(instruction, 32)); } } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java index 38ee0ce90..b0ef6a85d 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java @@ -48,7 +48,7 @@ public void testCommandLine() throws Exception { byte[] expected = new byte[33 * 4]; expected[4] = 0x68; - expected[5] = 0x06; + expected[5] = 0x03; assertArrayEquals(expected, bytes); } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java index 7f0a797d5..6f3775052 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java @@ -31,13 +31,12 @@ import org.junit.rules.TemporaryFolder; import java.io.File; -import java.lang.reflect.Array; import java.nio.file.Files; import java.nio.file.StandardOpenOption; -import java.util.Arrays; import static org.easymock.EasyMock.*; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertNotEquals; public class SSEMCompilerTest { private SSEMCompiler compiler; @@ -98,24 +97,24 @@ public void testCopyrightIsKnown() { @Test public void testSTO() throws Exception { compile("00 STO 22\n"); - assertProgram(0x68, 6, 0, 0); + assertProgram(0x68, 3, 0, 0); } @Test public void testLDN() throws Exception { compile("00 LDN 29"); - assertProgram(0xB8,4,0,0); + assertProgram(0xB8,2,0,0); } @Test public void testSUB() throws Exception { compile("00 SUB 30"); - assertProgram(0x78,8,0,0); + assertProgram(0x78,4,0,0); } @Test public void testSTP() throws Exception { compile("00 STP"); - assertProgram(0,0x0E,0,0); + assertProgram(0,7,0,0); } } From 948ed1b11a44ef0244392a68e7f8d425f9003c60 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 3 Sep 2021 12:18:12 +0200 Subject: [PATCH 039/314] [#201] Fix code generator --- .../emustudio/plugins/compiler/ssem/CodeGenerator.java | 4 ++-- .../net/emustudio/plugins/compiler/ssem/RunnerTest.java | 2 +- .../emustudio/plugins/compiler/ssem/SSEMCompilerTest.java | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java index 47dc3b583..b8e7d4a67 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java @@ -26,7 +26,7 @@ public ByteBuffer generateCode(Program program) { } private void writeInstruction(int opcode, long operand) { - int instruction = (int)((operand & 0x1F) | (((opcode & 0x07) << 13))); - code.putInt(NumberUtils.reverseBits(instruction, 32)); + int instruction = NumberUtils.reverseBits((int)operand & 0x1F, 32) | ((opcode & 0x07) << 16); + code.putInt(instruction); } } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java index b0ef6a85d..413cf6e3b 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/RunnerTest.java @@ -48,7 +48,7 @@ public void testCommandLine() throws Exception { byte[] expected = new byte[33 * 4]; expected[4] = 0x68; - expected[5] = 0x03; + expected[5] = 0x6; assertArrayEquals(expected, bytes); } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java index 6f3775052..38e6c5f7d 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java @@ -97,24 +97,24 @@ public void testCopyrightIsKnown() { @Test public void testSTO() throws Exception { compile("00 STO 22\n"); - assertProgram(0x68, 3, 0, 0); + assertProgram(0x68, 0x6, 0, 0); } @Test public void testLDN() throws Exception { compile("00 LDN 29"); - assertProgram(0xB8,2,0,0); + assertProgram(0xB8,0x2,0,0); } @Test public void testSUB() throws Exception { compile("00 SUB 30"); - assertProgram(0x78,4,0,0); + assertProgram(0x78,0x1,0,0); } @Test public void testSTP() throws Exception { compile("00 STP"); - assertProgram(0,7,0,0); + assertProgram(0,0x7,0,0); } } From 9be699a3af693d62310fbba5ec1142f86309b6f6 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 4 Sep 2021 12:40:42 +0200 Subject: [PATCH 040/314] [#201] SSEM: Improve time sleeping + estimation --- .../plugins/cpu/intel8080/EmulatorEngine.java | 5 +- .../emustudio/plugins/cpu/ssem/CpuImpl.java | 2 +- .../plugins/cpu/ssem/EmulatorEngine.java | 187 +++++++++--------- .../plugins/cpu/ssem/TimingEstimator.java | 119 +++++++++++ .../plugins/cpu/ssem/EmulatorEngineTest.java | 35 ++-- .../plugins/memory/ssem/gui/MemoryGui.java | 19 +- .../memory/ssem/gui/MemoryTableModel.java | 7 + 7 files changed, 251 insertions(+), 123 deletions(-) create mode 100644 plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/TimingEstimator.java diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java index 167f61bd6..3ff51b1a6 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java @@ -20,6 +20,7 @@ import net.emustudio.emulib.plugins.cpu.CPU; import net.emustudio.emulib.plugins.memory.MemoryContext; +import net.emustudio.emulib.runtime.helpers.SleepUtils; import net.emustudio.plugins.cpu.intel8080.api.CpuEngine; import net.emustudio.plugins.cpu.intel8080.api.DispatchListener; import net.emustudio.plugins.cpu.intel8080.api.FrequencyChangedListener; @@ -32,7 +33,6 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.locks.LockSupport; public class EmulatorEngine implements CpuEngine { private static final Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); @@ -62,6 +62,7 @@ public class EmulatorEngine implements CpuEngine { private final ContextImpl context; private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); + private final SleepUtils.Sleep sleep = SleepUtils.sleep; private long executedCycles = 0; private volatile DispatchListener dispatchListener; @@ -145,7 +146,7 @@ public CPU.RunState run(CPU cpu) { endTime = System.nanoTime() - startTime; if (endTime < slice) { // time correction - LockSupport.parkNanos(slice - endTime); + sleep.sleep(slice - endTime); } } return currentRunState; diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/CpuImpl.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/CpuImpl.java index 24ad05367..d2774f1b5 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/CpuImpl.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/CpuImpl.java @@ -70,7 +70,7 @@ public void initialize() throws PluginInitializationException { } Decoder decoder = new DecoderImpl(memory); disassembler = new DisassemblerImpl(memory, decoder); - engine = new EmulatorEngine(memory, this); + engine = new EmulatorEngine(memory, this::isBreakpointSet); if (settings.getBoolean(PluginSettings.EMUSTUDIO_AUTO, false)) { automaticEmulation = new AutomaticEmulation(this, engine, memory); diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java index c8e5dec21..5fafc8fa6 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java @@ -19,35 +19,64 @@ package net.emustudio.plugins.cpu.ssem; import net.emustudio.emulib.plugins.cpu.CPU; +import net.emustudio.emulib.plugins.cpu.DecodedInstruction; +import net.emustudio.emulib.plugins.cpu.Decoder; +import net.emustudio.emulib.plugins.cpu.InvalidInstructionException; import net.emustudio.emulib.plugins.memory.MemoryContext; +import net.emustudio.emulib.runtime.helpers.Bits; import net.emustudio.emulib.runtime.helpers.NumberUtils; import net.emustudio.emulib.runtime.helpers.NumberUtils.Strategy; +import net.emustudio.emulib.runtime.helpers.SleepUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Objects; -import java.util.concurrent.TimeUnit; +import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.LockSupport; +import java.util.function.Function; + +import static net.emustudio.plugins.cpu.ssem.DecoderImpl.LINE; public class EmulatorEngine { private final static Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); public final static int INSTRUCTIONS_PER_SECOND = 700; - private final static int MEMORY_CELLS = 32 * 4; - private final static int LINE_MASK = 0b11111000; + final static int LINE_MASK = 0b11111000; + + private final SleepUtils.Sleep sleep = SleepUtils.sleep; + private final TimingEstimator estimator = new TimingEstimator(); + private volatile long waitNanos = -1; - private final CPU cpu; private final MemoryContext memory; + private final Decoder decoder; + private final Function isBreakpointSet; public final AtomicInteger Acc = new AtomicInteger(); public final AtomicInteger CI = new AtomicInteger(); - private volatile long averageInstructionNanos; + private static final Method[] DISPATCH_TABLE = new Method[8]; + private final Bits emptyBits = new Bits(0, 0); + + static { + try { + DISPATCH_TABLE[0] = EmulatorEngine.class.getDeclaredMethod("op_jmp", int.class); + DISPATCH_TABLE[1] = EmulatorEngine.class.getDeclaredMethod("op_sub", int.class); + DISPATCH_TABLE[2] = EmulatorEngine.class.getDeclaredMethod("op_ldn", int.class); + DISPATCH_TABLE[3] = EmulatorEngine.class.getDeclaredMethod("op_cmp", int.class); + DISPATCH_TABLE[4] = EmulatorEngine.class.getDeclaredMethod("op_jpr", int.class); + DISPATCH_TABLE[6] = EmulatorEngine.class.getDeclaredMethod("op_sto", int.class); + DISPATCH_TABLE[7] = EmulatorEngine.class.getDeclaredMethod("op_stp", int.class); + } catch (NoSuchMethodException e) { + LOGGER.error("Could not set up dispatch table. The emulator won't work correctly", e); + } + } - EmulatorEngine(MemoryContext memory, CPU cpu) { + EmulatorEngine(MemoryContext memory, Function isBreakpointSet) { this.memory = Objects.requireNonNull(memory); - this.cpu = Objects.requireNonNull(cpu); + this.isBreakpointSet = Objects.requireNonNull(isBreakpointSet); + this.decoder = new DecoderImpl(memory); } void reset(int startingPos) { @@ -56,48 +85,65 @@ void reset(int startingPos) { } CPU.RunState step() { - Byte[] instruction = memory.read(CI.addAndGet(4), 4); - - byte line = (byte)(NumberUtils.reverseBits(instruction[0] & LINE_MASK, 8)); - int lineAddress = line * 4; - int opcode = instruction[1] & 7; - - switch (opcode) { - case 0: // JMP - int oldCi = CI.get() - 4; - int newLineAddress = readLineAddress(lineAddress); - CI.set(newLineAddress); - if (newLineAddress == oldCi) { - // endless loop detected; - return CPU.RunState.STATE_STOPPED_BREAK; - } - break; - case 4: // JPR, JRP, JMR - CI.addAndGet(readInt(lineAddress)*4); - break; - case 2: // LDN - int tmp = readInt(lineAddress); - Acc.set((tmp != 0) ? -tmp : 0); - break; - case 6: // STO - writeInt(lineAddress, Acc.get()); - break; - case 1: // SUB - Acc.addAndGet(-readInt(lineAddress)); - break; - case 3: // CMP, SKN - if (Acc.get() < 0) { - CI.addAndGet(4); - } - break; - case 7: // STP, HLT - return CPU.RunState.STATE_STOPPED_NORMAL; - default: + try { + DecodedInstruction instruction = decoder.decode(CI.addAndGet(4)); + int lineAddress = Optional.ofNullable(instruction.getBits(LINE)).orElse(emptyBits).reverseBits().bits * 4; + int opcode = instruction.getImage()[1] & 7; + + Method instr = DISPATCH_TABLE[opcode]; + if (instr == null) { return CPU.RunState.STATE_STOPPED_BAD_INSTR; + } + return (CPU.RunState) instr.invoke(this, lineAddress); + + } catch (InvalidInstructionException | InvocationTargetException | IllegalAccessException e) { + return CPU.RunState.STATE_STOPPED_BAD_INSTR; } + } + + private CPU.RunState op_jmp(int lineAddress) { + int oldCi = CI.get() - 4; + int newLineAddress = readLineAddress(lineAddress); + CI.set(newLineAddress); + if (newLineAddress == oldCi) { + // endless loop detected; + return CPU.RunState.STATE_STOPPED_BREAK; + } + return CPU.RunState.STATE_RUNNING; + } + + private CPU.RunState op_jpr(int lineAddress) { + CI.addAndGet(readInt(lineAddress) * 4); return CPU.RunState.STATE_RUNNING; } + private CPU.RunState op_ldn(int lineAddress) { + Acc.set(-readInt(lineAddress)); + return CPU.RunState.STATE_RUNNING; + } + + private CPU.RunState op_sto(int lineAddress) { + writeInt(lineAddress, Acc.get()); + return CPU.RunState.STATE_RUNNING; + } + + private CPU.RunState op_sub(int lineAddress) { + Acc.addAndGet(-readInt(lineAddress)); + return CPU.RunState.STATE_RUNNING; + } + + private CPU.RunState op_cmp(int lineAddress) { + if (Acc.get() < 0) { + CI.addAndGet(4); + } + return CPU.RunState.STATE_RUNNING; + } + + private CPU.RunState op_stp(int lineAddress) { + return CPU.RunState.STATE_STOPPED_NORMAL; + } + + private int readLineAddress(int lineAddress) { return 4 * NumberUtils.reverseBits(memory.read(lineAddress) & LINE_MASK, 8); } @@ -114,15 +160,16 @@ private void writeInt(int lineAddress, int value) { } CPU.RunState run() { - if (averageInstructionNanos == 0) { - measureAverageInstructionNanos(); + if (waitNanos < 0) { + waitNanos = estimator.estimateWaitNanos(INSTRUCTIONS_PER_SECOND); + LOGGER.debug("Estimated wait nanos: " + waitNanos); } + CPU.RunState currentRunState = CPU.RunState.STATE_RUNNING; - long waitNanos = TimeUnit.SECONDS.toNanos(1) / averageInstructionNanos; while (!Thread.currentThread().isInterrupted() && currentRunState == CPU.RunState.STATE_RUNNING) { try { - if (cpu.isBreakpointSet(CI.get())) { + if (isBreakpointSet.apply(CI.get())) { return CPU.RunState.STATE_STOPPED_BREAK; } currentRunState = step(); @@ -136,48 +183,8 @@ CPU.RunState run() { LOGGER.debug("Unexpected error", e); return CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; } - if (waitNanos > 0) { - LockSupport.parkNanos(waitNanos); - } + sleep.sleep(waitNanos); } return currentRunState; } - - private void fakeStep() { - Byte[] instruction = memory.read(CI.get(), 4); - - int line = NumberUtils.reverseBits(instruction[0] & LINE_MASK, 8); - int opcode = instruction[1] & 3; - CI.updateAndGet(ci -> (ci + 4) % MEMORY_CELLS); - - switch (opcode) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 6: - case 7: - break; - } - - Acc.addAndGet(- memory.read(line % MEMORY_CELLS)); - } - - - private void measureAverageInstructionNanos() { - int oldCI = CI.get(); - int oldAcc = Acc.get(); - - long start = System.nanoTime(); - for (int i = 0; i < INSTRUCTIONS_PER_SECOND; i++) { - fakeStep(); - } - long elapsed = System.nanoTime() - start; - - averageInstructionNanos = elapsed / INSTRUCTIONS_PER_SECOND; - - CI.set(oldCI); - Acc.set(oldAcc); - } } diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/TimingEstimator.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/TimingEstimator.java new file mode 100644 index 000000000..7f81e5692 --- /dev/null +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/TimingEstimator.java @@ -0,0 +1,119 @@ +package net.emustudio.plugins.cpu.ssem; + +import net.emustudio.emulib.plugins.memory.AbstractMemoryContext; +import net.emustudio.emulib.plugins.memory.MemoryContext; +import net.emustudio.emulib.runtime.helpers.NumberUtils; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +public class TimingEstimator { + private final short[] memory = new short[]{ + 0x06, 0xA4, 0x41, 0x04, + 0x9B, 0xF2, 0x20, 0x88, + 0x82, 0x16, 0x88, 0x50, + 0x02, 0x13, 0x42, 0x60, + 0xEB, 0xF1, 0xAA, 0x94, + 0x80, 0xC1, 0x10, 0xA9, + 0x81, 0xE1, 0x09, 0x0C, + 0x81, 0xE1, 0x06, 0x02, + 0x98, 0x06, 0x86, 0x41, + 0xA9, 0xE2, 0x49, 0x02, + 0x01, 0xE3, 0x34, 0x84, + 0x69, 0xE1, 0x30, 0x48, + 0xE9, 0xE1, 0x48, 0x30, + 0xA8, 0xC6, 0x84, 0x30, + 0xA1, 0xE1, 0x02, 0x48, + 0x13, 0xF6, 0x01, 0x84, + 0x07, 0xF9, 0x00, 0x82, + 0x83, 0xF6, 0xFF, 0xFF, + 0xA9, 0xE2, 0x66, 0x66, + 0xA8, 0xC6, 0xFF, 0xFF, + 0x18, 0xC0, 0xFF, 0xFF, + 0x60, 0x00, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xF0, 0x20, + 0x00, 0x02, 0x08, 0x50, + 0x00, 0x02, 0x28, 0x20, + 0x01, 0xFA, 0x08, 0x38, + 0x02, 0x01, 0xF0, 0x20, + 0x1E, 0x78, 0x80, 0x20, + 0x3F, 0xFF, 0xE0, 0x50 + }; + + private final MemoryContext memoryContext = new AbstractMemoryContext<>() { + + @Override + public Byte read(int position) { + return (byte) memory[position]; + } + + @Override + public Byte[] read(int position, int length) { + return NumberUtils.nativeShortsToBytes(Arrays.copyOfRange(memory, position, position + length)); + } + + @Override + public void write(int position, Byte value) { + memory[position] = value; + } + + @Override + public void write(int position, Byte[] bytes, int length) { + System.arraycopy(bytes, 0, memory, position, length); + } + + @Override + public Class getDataType() { + return Byte.class; + } + + @Override + public void clear() { + + } + + @Override + public int getSize() { + return memory.length; + } + }; + + public long estimateWaitNanos(int instructionsPerSecond) { + EmulatorEngine engine = new EmulatorEngine(memoryContext, position -> false); + + int testInstructionsCount = 5000; + assert(testInstructionsCount > instructionsPerSecond); + double coeff = (double)instructionsPerSecond / testInstructionsCount; + + long start = System.nanoTime(); + for (int i = 0; i < testInstructionsCount; i++) { + engine.step(); + } + long t1 = System.nanoTime() - start; + + // we want 700 per second + // instructions go much faster on host computer + // we estimate how long takes X instructions to perform over time + // we now time T1 .... X instructions (assuming X > 700) + // T2 .... 700 instructions + // ------------------------------------ + // T2 : T1 = 700 : X + // T2 = T1 * 700 / X + + double t2 = t1 * coeff; + assert(t1 > t2); + + + // T2 is the real time needed to perform 700 instructions, it it much less than 1 second + // we want 700 instructions/second + // + // so after 700 instructions we should wait 1 second - T2 + // If we wanted to wait after each instruction (more smooth), then: + // wait = (1 second - T2) / 700 + + return (long)((TimeUnit.SECONDS.toNanos(1) - t2) / instructionsPerSecond); + } +} diff --git a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java index a3c225155..a7ab6ded0 100644 --- a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java +++ b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java @@ -21,14 +21,10 @@ import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.cpu.testsuite.memory.MemoryStub; import net.emustudio.emulib.plugins.cpu.CPU; -import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; import org.junit.Before; import org.junit.Test; -import static org.easymock.EasyMock.*; import static org.junit.Assert.assertEquals; public class EmulatorEngineTest { @@ -37,33 +33,24 @@ public class EmulatorEngineTest { @Before public void setUp() { - ContextPool contextPool = createNiceMock(ContextPool.class); - replay(contextPool); - - ApplicationApi applicationApi = createNiceMock(ApplicationApi.class); - expect(applicationApi.getContextPool()).andReturn(contextPool).anyTimes(); - replay(applicationApi); - - CpuImpl cpuImpl = new CpuImpl(0L, applicationApi, PluginSettings.UNAVAILABLE); memoryStub = new ByteMemoryStub(NumberUtils.Strategy.REVERSE_BITS); - engine = new EmulatorEngine(memoryStub, cpuImpl); + engine = new EmulatorEngine(memoryStub, p -> false); } @Test public void testAddition() { /* -01: LDN 29 -- A = -X -02: SUB 30 -- A = -X - Y -03: STO 31 -- store -Sum -04: LDN 31 -- A = -(-Sum) -05: STO 31 -- store Sum -06: HLT - -29: NUM 5 -- X Parameter -30: NUM 3 -- Y Parameter -31: -- Sum Result will appear here -*/ + 01: LDN 29 -- A = -X + 02: SUB 30 -- A = -X - Y + 03: STO 31 -- store -Sum + 04: LDN 31 -- A = -(-Sum) + 05: STO 31 -- store Sum + 06: HLT + 29: NUM 5 -- X Parameter + 30: NUM 3 -- Y Parameter + 31: -- Sum Result will appear here + */ memoryStub.setMemory(new short[]{ 0, 0, 0, 0, 0xB8, 0x02, 0, 0, diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java index 5bd62854b..753ceab2e 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java @@ -56,35 +56,42 @@ public MemoryGui(JFrame parent, MemoryContext memory) { private void initComponents() { scrollPane = new JScrollPane(); - JToolBar jToolBar1 = new JToolBar(); + JToolBar toolBar = new JToolBar(); JButton btnClear = new JButton(); + JButton btnDump = new JButton(); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); setTitle("SSEM Memory (Williams-Killburn Tube)"); - jToolBar1.setFloatable(false); - jToolBar1.setRollover(true); + toolBar.setFloatable(false); + toolBar.setRollover(true); btnClear.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/ssem/gui/clear.png"))); btnClear.setFocusable(false); btnClear.setHorizontalTextPosition(SwingConstants.CENTER); btnClear.setVerticalTextPosition(SwingConstants.BOTTOM); btnClear.addActionListener(this::btnClearActionPerformed); - jToolBar1.add(btnClear); + + btnDump.setText("Dump to console"); + btnDump.setFocusable(false); + btnDump.addActionListener(e -> tableModel.dump()); + + toolBar.add(btnClear); + toolBar.add(btnDump); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 965, Short.MAX_VALUE) - .addComponent(jToolBar1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(toolBar, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jToolBar1, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE) + .addComponent(toolBar, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 455, Short.MAX_VALUE)) ); diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java index 05b1bd96f..dacb71706 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java @@ -43,6 +43,13 @@ public class MemoryTableModel extends AbstractTableModel { this.memory = Objects.requireNonNull(memory); } + public void dump() { + for (int i = 0; i < 32; i++) { + Byte[] v = memory.read(i * 4, 4); + System.out.printf("0x%02X, 0x%02X, 0x%02X, 0x%02X,\n", v[0], v[1], v[2], v[3]); + } + } + @Override public int getRowCount() { return ROW_COUNT; From e3950f84ede373f1ec2022bc74ba6a1a4b5aeb85 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 6 Sep 2021 11:55:02 +0200 Subject: [PATCH 041/314] [#201] Rewrite as-8080 gramar to ANTLR --- plugins/compiler/as-8080/build.gradle | 48 +- .../as-8080/src/main/antlr/As8080Lexer.g4 | 173 ++++++ .../as-8080/src/main/antlr/As8080Lexer.tokens | 137 +++++ .../as-8080/src/main/antlr/As8080Parser.g4 | 175 ++++++ .../src/main/antlr/gen/As8080Lexer.interp | 425 +++++++++++++++ .../src/main/antlr/gen/As8080Lexer.java | 506 ++++++++++++++++++ .../src/main/antlr/gen/As8080Lexer.tokens | 137 +++++ .../as-8080/src/main/gen/As8080Lexer.interp | 425 +++++++++++++++ .../as-8080/src/main/gen/As8080Lexer.java | 506 ++++++++++++++++++ .../as-8080/src/main/gen/As8080Lexer.tokens | 137 +++++ .../plugins/compiler/as8080/CompilerImpl.java | 2 +- .../compiler/as8080/tree/DBDataNode.java | 6 +- .../compiler/as8080/tree/DSDataNode.java | 4 +- .../compiler/as8080/tree/DWDataNode.java | 4 +- .../compiler/as8080/tree/DataNode.java | 2 +- .../compiler/as8080/tree/EquPseudoNode.java | 2 +- .../compiler/as8080/tree/IfPseudoNode.java | 2 +- .../as8080/tree/IncludePseudoNode.java | 4 +- .../compiler/as8080/tree/InstructionNode.java | 2 +- .../compiler/as8080/tree/MacroCallPseudo.java | 4 +- .../compiler/as8080/tree/MacroPseudoNode.java | 2 +- .../plugins/compiler/as8080/tree/OC_Expr.java | 4 +- .../compiler/as8080/tree/OC_NoParams.java | 4 +- .../plugins/compiler/as8080/tree/OC_Reg.java | 4 +- .../compiler/as8080/tree/OC_RegExpr.java | 6 +- .../compiler/as8080/tree/OC_RegReg.java | 4 +- .../compiler/as8080/tree/OC_Regpair.java | 4 +- .../compiler/as8080/tree/OC_RegpairExpr.java | 6 +- .../compiler/as8080/tree/OrgPseudoNode.java | 2 +- .../compiler/as8080/tree/SetPseudoNode.java | 2 +- .../compiler/as8080/tree/Statement.java | 2 +- .../as8080/treeAbstract/CodePseudoNode.java | 2 +- .../as8080/treeAbstract/DataValueNode.java | 2 +- plugins/compiler/as-ssem/build.gradle | 2 - settings.gradle | 4 +- 35 files changed, 2692 insertions(+), 59 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 create mode 100644 plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens create mode 100644 plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 create mode 100644 plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.interp create mode 100644 plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.java create mode 100644 plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.tokens create mode 100644 plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp create mode 100644 plugins/compiler/as-8080/src/main/gen/As8080Lexer.java create mode 100644 plugins/compiler/as-8080/src/main/gen/As8080Lexer.tokens diff --git a/plugins/compiler/as-8080/build.gradle b/plugins/compiler/as-8080/build.gradle index f5dcd5bad..0746ce51a 100644 --- a/plugins/compiler/as-8080/build.gradle +++ b/plugins/compiler/as-8080/build.gradle @@ -21,14 +21,18 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'org.xbib.gradle.plugin.jflex' version "1.5.0" - id "com.github.andrescv.jcup" version "1.0" + id 'idea' + id 'antlr' } dependencies { + antlr "org.antlr:antlr4:4.9.2" + implementation "org.antlr:antlr4-runtime:4.9.2" + implementation libs.emuLib implementation libs.slf4JApi - implementation libs.javaCupRuntime + implementation libs.jcipAnnotations + implementation libs.javaCupRuntime // TODO: remove testImplementation libs.cpuTestSuite testImplementation libs.junit @@ -36,23 +40,29 @@ dependencies { testImplementation libs.slf4JSimple } -sourceSets.main.java { - srcDirs = [ - "${buildDir}/generated-sources/jflex", "${buildDir}/generated-sources/cup", 'src/main/java' - ] - exclude "${buildDir}/generated-sources/cup/net/emustudio/plugins/compiler/as8080" +generateGrammarSource { + maxHeapSize = "128m" + arguments += ['-package', 'net.emustudio.plugins.compiler.as8080', '-visitor', '-no-listener'] + outputDirectory = file("${buildDir}/generated-src/antlr/main/net/emustudio/plugins/compiler/as8080") } +compileJava.dependsOn generateGrammarSource -jflex { - no_backup = true +sourceSets { + generated { + java.srcDir "${buildDir}/generated-src/antlr/main" + } + main { + java.srcDirs = [ + 'src/main/java', "${buildDir}/generated-src/antlr/main" + ] + } } +compileJava.source sourceSets.generated.java, sourceSets.main.java -jcup { - input = file('src/main/cup/parser.cup') - destdir = file("${buildDir}/generated-sources/cup/net/emustudio/plugins/compiler/as8080") - parser = 'ParserImpl' - symbols = 'Symbols' - iface = true +idea { + module { + sourceDirs += file("build/generated-src/antlr") + } } jar { @@ -84,3 +94,9 @@ copy { from('src/main/scripts') into "$buildDir/libs/scripts" } + +test { + testLogging { + events "passed", "skipped", "failed" + } +} diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 new file mode 100644 index 000000000..ead226d5e --- /dev/null +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 @@ -0,0 +1,173 @@ +lexer grammar As8080Lexer; + + +WS : (' ' | '\t' | '\f') -> channel(HIDDEN); +COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]*; +EOL: '\r'? '\n'; + +fragment A: [aA]; +fragment B: [bB]; +fragment C: [cC]; +fragment D: [dD]; +fragment E: [eE]; +fragment F: [fF]; +fragment G: [gG]; +fragment H: [hH]; +fragment I: [iI]; +fragment J: [jJ]; +fragment L: [lL]; +fragment M: [mM]; +fragment N: [nN]; +fragment O: [oO]; +fragment P: [pP]; +fragment Q: [qQ]; +fragment R: [rR]; +fragment S: [sS]; +fragment T: [tT]; +fragment U: [uU]; +fragment V: [vV]; +fragment W: [wW]; +fragment X: [xX]; +fragment Z: [zZ]; + + +// reserved +OPCODE_STC: S T C; +OPCODE_CMC: C M C; +OPCODE_INR: I N R; +OPCODE_DCR: D C R; +OPCODE_CMA: C M A; +OPCODE_DAA: D A A; +OPCODE_NOP: N O P; +OPCODE_MOV: M O V; +OPCODE_STAX: S T A X; +OPCODE_LDAX: L D A X; +OPCODE_ADD: A D D; +OPCODE_ADC: A D C; +OPCODE_SUB: S U B; +OPCODE_SBB: S B B; +OPCODE_ANA: A N A; +OPCODE_XRA: X R A; +OPCODE_ORA: O R A; +OPCODE_CMP: C M P; +OPCODE_RLC: R L C; +OPCODE_RRC: R R C; +OPCODE_RAL: R A L; +OPCODE_RAR: R A R; +OPCODE_PUSH: P U S H; +OPCODE_POP: P O P; +OPCODE_DAD: D A D; +OPCODE_INX: I N X; +OPCODE_DCX: D C X; +OPCODE_XCHG: X C H G; +OPCODE_XTHL: X T H L; +OPCODE_SPHL: S P H L; +OPCODE_LXI: L X I; +OPCODE_MVI: M V I; +OPCODE_ADI: A D I; +OPCODE_ACI: A C I; +OPCODE_SUI: S U I; +OPCODE_SBI: S B I; +OPCODE_ANI: A N I; +OPCODE_XRI: X R I; +OPCODE_ORI: O R I; +OPCODE_CPI: C P I; +OPCODE_STA: S T A; +OPCODE_LDA: L D A; +OPCODE_SHLD: S H L D; +OPCODE_LHLD: L H L D; +OPCODE_PCHL: P C H L; +OPCODE_JMP: J M P; +OPCODE_JC: J C; +OPCODE_JNC: J N C; +OPCODE_JZ: J Z; +OPCODE_JNZ: J N Z; +OPCODE_JP: J P; +OPCODE_JM: J M; +OPCODE_JPE: J P E; +OPCODE_JPO: J P O; +OPCODE_CALL: C A L L; +OPCODE_CC: C C; +OPCODE_CNC: C N C; +OPCODE_CZ: C Z; +OPCODE_CNZ: C N Z; +OPCODE_CP: C P; +OPCODE_CM: C M; +OPCODE_CPE: C P E; +OPCODE_CPO: C P O; +OPCODE_RET: R E T; +OPCODE_RC: R C; +OPCODE_RNC: R N C; +OPCODE_RZ: R Z; +OPCODE_RNZ: R N Z; +OPCODE_RM: R M; +OPCODE_RP: R P; +OPCODE_RPE: R P E; +OPCODE_RPO: R P O; +OPCODE_RST: R S T; +OPCODE_EI: E I; +OPCODE_DI: D I; +OPCODE_IN: I N; +OPCODE_OUT: O U T; +OPCODE_HLT: H L T; + +// preprocessor +PREP_ORG: O R G; +PREP_EQU: E Q U; +PREP_SET: S E T; +PREP_INCLUDE: I N C L U D E; +PREP_IF: I F; +PREP_ENDIF: E N D I F; +PREP_MACRO: M A C R O; +PREP_ENDM: E N D M; +PREP_DB: D B; +PREP_DW: D W; +PREP_DS: D S; +PREP_ADDR: '$'; + +// registers +REG_A: A; +REG_B: B; +REG_C: C; +REG_D: D; +REG_E: E; +REG_H: H; +REG_L: L; +REG_M: M; +REG_PSW: P S W; +REG_SP: S P; + +// separators +SEP_LPAR: '('; +SEP_RPAR: ')'; +SEP_COMMA: ','; + +// operators +OP_ADD: '+'; +OP_SUBTRACT: '-'; +OP_MULTIPLY: '*'; +OP_DIVIDE: '/'; +OP_EQUAL: '='; +OP_MOD: M O D; +OP_SHR: S H R; +OP_SHL: S H L; +OP_NOT: N O T; +OP_AND: A N D; +OP_OR: O R; +OP_XOR: X O R; + +// literals +LIT_NUMBER: [\-]? [0-9]+ D?; +LIT_HEXNUMBER_1: [\-]? ('0x'|'0X') [0-9a-fA-F]+; +LIT_HEXNUMBER_2: [\-]? [0-9a-fA-F]+ H; +LIT_OCTNUMBER: [\-]? [0-7]+ [oOqQ]; +LIT_BINNUMBER: [01]+ B; +LIT_STRING_1: ['] [^']+ [']; +LIT_STRING_2: '"' [^"]+ '"'; + +// other + +ID_IDENTIFIER: [a-zA-Z_?@] [a-zA-Z_?@0-9]*; +ID_LABEL: [a-zA-Z_?@] [a-zA-Z_?@0-9]* ':'; + +ERROR : .; diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens new file mode 100644 index 000000000..a522a3c4c --- /dev/null +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens @@ -0,0 +1,137 @@ +WS=1 +COMMENT=2 +EOL=3 +OPCODE_STC=4 +OPCODE_CMC=5 +OPCODE_INR=6 +OPCODE_DCR=7 +OPCODE_CMA=8 +OPCODE_DAA=9 +OPCODE_NOP=10 +OPCODE_MOV=11 +OPCODE_STAX=12 +OPCODE_LDAX=13 +OPCODE_ADD=14 +OPCODE_ADC=15 +OPCODE_SUB=16 +OPCODE_SBB=17 +OPCODE_ANA=18 +OPCODE_XRA=19 +OPCODE_ORA=20 +OPCODE_CMP=21 +OPCODE_RLC=22 +OPCODE_RRC=23 +OPCODE_RAL=24 +OPCODE_RAR=25 +OPCODE_PUSH=26 +OPCODE_POP=27 +OPCODE_DAD=28 +OPCODE_INX=29 +OPCODE_DCX=30 +OPCODE_XCHG=31 +OPCODE_XTHL=32 +OPCODE_SPHL=33 +OPCODE_LXI=34 +OPCODE_MVI=35 +OPCODE_ADI=36 +OPCODE_ACI=37 +OPCODE_SUI=38 +OPCODE_SBI=39 +OPCODE_ANI=40 +OPCODE_XRI=41 +OPCODE_ORI=42 +OPCODE_CPI=43 +OPCODE_STA=44 +OPCODE_LDA=45 +OPCODE_SHLD=46 +OPCODE_LHLD=47 +OPCODE_PCHL=48 +OPCODE_JMP=49 +OPCODE_JC=50 +OPCODE_JNC=51 +OPCODE_JZ=52 +OPCODE_JNZ=53 +OPCODE_JP=54 +OPCODE_JM=55 +OPCODE_JPE=56 +OPCODE_JPO=57 +OPCODE_CALL=58 +OPCODE_CC=59 +OPCODE_CNC=60 +OPCODE_CZ=61 +OPCODE_CNZ=62 +OPCODE_CP=63 +OPCODE_CM=64 +OPCODE_CPE=65 +OPCODE_CPO=66 +OPCODE_RET=67 +OPCODE_RC=68 +OPCODE_RNC=69 +OPCODE_RZ=70 +OPCODE_RNZ=71 +OPCODE_RM=72 +OPCODE_RP=73 +OPCODE_RPE=74 +OPCODE_RPO=75 +OPCODE_RST=76 +OPCODE_EI=77 +OPCODE_DI=78 +OPCODE_IN=79 +OPCODE_OUT=80 +OPCODE_HLT=81 +PREP_ORG=82 +PREP_EQU=83 +PREP_SET=84 +PREP_INCLUDE=85 +PREP_IF=86 +PREP_ENDIF=87 +PREP_MACRO=88 +PREP_ENDM=89 +PREP_DB=90 +PREP_DW=91 +PREP_DS=92 +PREP_ADDR=93 +REG_A=94 +REG_B=95 +REG_C=96 +REG_D=97 +REG_E=98 +REG_H=99 +REG_L=100 +REG_M=101 +REG_PSW=102 +REG_SP=103 +SEP_LPAR=104 +SEP_RPAR=105 +SEP_COMMA=106 +OP_ADD=107 +OP_SUBTRACT=108 +OP_MULTIPLY=109 +OP_DIVIDE=110 +OP_EQUAL=111 +OP_MOD=112 +OP_SHR=113 +OP_SHL=114 +OP_NOT=115 +OP_AND=116 +OP_OR=117 +OP_XOR=118 +LIT_NUMBER=119 +LIT_HEXNUMBER_1=120 +LIT_HEXNUMBER_2=121 +LIT_OCTNUMBER=122 +LIT_BINNUMBER=123 +LIT_STRING_1=124 +LIT_STRING_2=125 +ID_IDENTIFIER=126 +ID_LABEL=127 +ERROR=128 +'$'=93 +'('=104 +')'=105 +','=106 +'+'=107 +'-'=108 +'*'=109 +'/'=110 +'='=111 diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 new file mode 100644 index 000000000..ac1df0f81 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -0,0 +1,175 @@ +parser grammar As8080Parser; + +options { + tokenVocab = As8080Lexer; +} + +rStart: + (rLine EOL rLine)* EOF + | rLine EOF + ; + +rLine: + label=ID_LABEL? statement=rStatement? rComment + | rComment + ; + +rComment: COMMENT? ; + +rStatement: + instr=rInstruction + | pseudo=rPseudoCode + | data=rData + ; + +rInstruction: + opcode=OPCODE_STC + | opcode=OPCODE_CMC + | opcode=OPCODE_CMA + | opcode=OPCODE_DAA + | opcode=OPCODE_NOP + | opcode=OPCODE_RLC + | opcode=OPCODE_RRC + | opcode=OPCODE_RAL + | opcode=OPCODE_RAR + | opcode=OPCODE_XCHG + | opcode=OPCODE_XTHL + | opcode=OPCODE_SPHL + | opcode=OPCODE_PCHL + | opcode=OPCODE_RET + | opcode=OPCODE_RC + | opcode=OPCODE_RNC + | opcode=OPCODE_RZ + | opcode=OPCODE_RNZ + | opcode=OPCODE_RM + | opcode=OPCODE_RP + | opcode=OPCODE_RPE + | opcode=OPCODE_RPO + | opcode=OPCODE_EI + | opcode=OPCODE_DI + | opcode=OPCODE_HLT + | opcode=OPCODE_INR reg=rRegister + | opcode=OPCODE_DCR reg=rRegister + | opcode=OPCODE_ADD reg=rRegister + | opcode=OPCODE_ADC reg=rRegister + | opcode=OPCODE_SUB reg=rRegister + | opcode=OPCODE_SBB reg=rRegister + | opcode=OPCODE_ANA reg=rRegister + | opcode=OPCODE_XRA reg=rRegister + | opcode=OPCODE_ORA reg=rRegister + | opcode=OPCODE_CMP reg=rRegister + | opcode=OPCODE_MOV dst=rRegister SEP_COMMA src=rRegister + | opcode=OPCODE_STAX regpair=(REG_B|REG_D) + | opcode=OPCODE_LDAX regpair=(REG_B|REG_D) + | opcode=OPCODE_PUSH regpair=(REG_B|REG_D|REG_H|REG_PSW) + | opcode=OPCODE_POP regpair=(REG_B|REG_D|REG_H|REG_PSW) + | opcode=OPCODE_DAD regpair=(REG_B|REG_D|REG_H|REG_SP) + | opcode=OPCODE_INX regpair=(REG_B|REG_D|REG_H|REG_SP) + | opcode=OPCODE_DCX regpair=(REG_B|REG_D|REG_H|REG_SP) + | opcode=OPCODE_LXI regpair=(REG_B|REG_D|REG_H|REG_SP) SEP_COMMA expr=rExpression + | opcode=OPCODE_MVI reg=rRegister SEP_COMMA expr=rExpression + | opcode=OPCODE_ADI expr=rExpression + | opcode=OPCODE_ACI expr=rExpression + | opcode=OPCODE_SUI expr=rExpression + | opcode=OPCODE_SBI expr=rExpression + | opcode=OPCODE_ANI expr=rExpression + | opcode=OPCODE_XRI expr=rExpression + | opcode=OPCODE_ORI expr=rExpression + | opcode=OPCODE_CPI expr=rExpression + | opcode=OPCODE_STA expr=rExpression + | opcode=OPCODE_LDA expr=rExpression + | opcode=OPCODE_SHLD expr=rExpression + | opcode=OPCODE_LHLD expr=rExpression + | opcode=OPCODE_JMP expr=rExpression + | opcode=OPCODE_JC expr=rExpression + | opcode=OPCODE_JNC expr=rExpression + | opcode=OPCODE_JZ expr=rExpression + | opcode=OPCODE_JNZ expr=rExpression + | opcode=OPCODE_JM expr=rExpression + | opcode=OPCODE_JP expr=rExpression + | opcode=OPCODE_JPE expr=rExpression + | opcode=OPCODE_JPO expr=rExpression + | opcode=OPCODE_CALL expr=rExpression + | opcode=OPCODE_CC expr=rExpression + | opcode=OPCODE_CNC expr=rExpression + | opcode=OPCODE_CZ expr=rExpression + | opcode=OPCODE_CNZ expr=rExpression + | opcode=OPCODE_CM expr=rExpression + | opcode=OPCODE_CP expr=rExpression + | opcode=OPCODE_CPE expr=rExpression + | opcode=OPCODE_CPO expr=rExpression + | opcode=OPCODE_RST expr=rExpression + | opcode=OPCODE_IN expr=rExpression + | opcode=OPCODE_OUT expr=rExpression + ; + +rRegister: + REG_A + | REG_B + | REG_C + | REG_D + | REG_E + | REG_H + | REG_L + | REG_M + ; + +rPseudoCode: + PREP_ORG expr=rExpression + | id=ID_IDENTIFIER PREP_EQU expr=rExpression + | id=ID_IDENTIFIER PREP_SET expr=rExpression + | PREP_IF expr=rExpression rComment EOL statement=rStatement EOL PREP_ENDIF + | id=ID_IDENTIFIER PREP_MACRO macro=rMacro? rComment EOL statement=rStatement PREP_ENDM + | id=ID_IDENTIFIER macroCall=rMacroCall + | PREP_INCLUDE filename=(LIT_STRING_1|LIT_STRING_2) + ; + +rMacro: + id=ID_IDENTIFIER (SEP_COMMA ids=ID_IDENTIFIER)* + ; + +// todo: assign variables?? +rMacroCall: + expr=rExpression (SEP_COMMA exprs=rExpression)* + ; + +rData: + PREP_DB db=rDB + | PREP_DW dw=rDW + | PREP_DS ds=rExpression + ; + +rDB: + data=rDBdata (SEP_COMMA data=rDBdata)* + ; + +rDW: + data=rDWdata (SEP_COMMA data=rDWdata)* + ; + +rDBdata: + expr=rExpression + | str=(LIT_STRING_1|LIT_STRING_2) + | instr=rInstruction + ; + +rDWdata: + expr=rExpression + ; + +rExpression: + SEP_LPAR expr=rExpression SEP_RPAR + | num=LIT_NUMBER + | num=LIT_HEXNUMBER_1 + | num=LIT_HEXNUMBER_2 + | num=LIT_OCTNUMBER + | num=LIT_BINNUMBER + | id=PREP_ADDR + | id=ID_IDENTIFIER + | unaryop=(OP_ADD|OP_SUBTRACT) expr=rExpression + | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD|OP_SHL|OP_SHR) expr2=rExpression + | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression + | unaryop=OP_NOT expr=rExpression + | expr1=rExpression op=OP_AND expr2=rExpression + | expr1=rExpression op=(OP_OR|OP_XOR) expr2=rExpression + ; diff --git a/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.interp b/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.interp new file mode 100644 index 000000000..ad3f351ce --- /dev/null +++ b/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.interp @@ -0,0 +1,425 @@ +token literal names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'$' +null +null +null +null +null +null +null +null +null +null +'(' +')' +',' +'+' +'-' +'*' +'/' +'=' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +WS +COMMENT +EOL +OPCODE_STC +OPCODE_CMC +OPCODE_INR +OPCODE_DCR +OPCODE_CMA +OPCODE_DAA +OPCODE_NOP +OPCODE_MOV +OPCODE_STAX +OPCODE_LDAX +OPCODE_ADD +OPCODE_ADC +OPCODE_SUB +OPCODE_SBB +OPCODE_ANA +OPCODE_XRA +OPCODE_ORA +OPCODE_CMP +OPCODE_RLC +OPCODE_RRC +OPCODE_RAL +OPCODE_RAR +OPCODE_PUSH +OPCODE_POP +OPCODE_DAD +OPCODE_INX +OPCODE_DCX +OPCODE_XCHG +OPCODE_XTHL +OPCODE_SPHL +OPCODE_LXI +OPCODE_MVI +OPCODE_ADI +OPCODE_ACI +OPCODE_SUI +OPCODE_SBI +OPCODE_ANI +OPCODE_XRI +OPCODE_ORI +OPCODE_CPI +OPCODE_STA +OPCODE_LDA +OPCODE_SHLD +OPCODE_LHLD +OPCODE_PCHL +OPCODE_JMP +OPCODE_JC +OPCODE_JNC +OPCODE_JZ +OPCODE_JNZ +OPCODE_JP +OPCODE_JM +OPCODE_JPE +OPCODE_JPO +OPCODE_CALL +OPCODE_CC +OPCODE_CNC +OPCODE_CZ +OPCODE_CNZ +OPCODE_CP +OPCODE_CM +OPCODE_CPE +OPCODE_CPO +OPCODE_RET +OPCODE_RC +OPCODE_RNC +OPCODE_RZ +OPCODE_RNZ +OPCODE_RM +OPCODE_RP +OPCODE_RPE +OPCODE_RPO +OPCODE_RST +OPCODE_EI +OPCODE_DI +OPCODE_IN +OPCODE_OUT +OPCODE_HLT +PREP_ORG +PREP_EQU +PREP_SET +PREP_INCLUDE +PREP_IF +PREP_ENDIF +PREP_MACRO +PREP_ENDM +PREP_DB +PREP_DW +PREP_DS +PREP_ADDR +REG_A +REG_B +REG_C +REG_D +REG_E +REG_H +REG_L +REG_M +REG_PSW +REG_SP +SEP_LPAR +SEP_RPAR +SEP_COMMA +OP_ADD +OP_SUBTRACT +OP_MULTIPLY +OP_DIVIDE +OP_EQUAL +OP_MOD +OP_SHR +OP_SHL +OP_NOT +OP_AND +OP_OR +OP_XOR +LIT_NUMBER +LIT_HEXNUMBER_1 +LIT_HEXNUMBER_2 +LIT_OCTNUMBER +LIT_BINNUMBER +LIT_STRING_1 +LIT_STRING_2 +ID_IDENTIFIER +ID_LABEL +ERROR + +rule names: +WS +COMMENT +EOL +A +B +C +D +E +F +G +H +I +J +L +M +N +O +P +Q +R +S +T +U +V +W +X +Z +OPCODE_STC +OPCODE_CMC +OPCODE_INR +OPCODE_DCR +OPCODE_CMA +OPCODE_DAA +OPCODE_NOP +OPCODE_MOV +OPCODE_STAX +OPCODE_LDAX +OPCODE_ADD +OPCODE_ADC +OPCODE_SUB +OPCODE_SBB +OPCODE_ANA +OPCODE_XRA +OPCODE_ORA +OPCODE_CMP +OPCODE_RLC +OPCODE_RRC +OPCODE_RAL +OPCODE_RAR +OPCODE_PUSH +OPCODE_POP +OPCODE_DAD +OPCODE_INX +OPCODE_DCX +OPCODE_XCHG +OPCODE_XTHL +OPCODE_SPHL +OPCODE_LXI +OPCODE_MVI +OPCODE_ADI +OPCODE_ACI +OPCODE_SUI +OPCODE_SBI +OPCODE_ANI +OPCODE_XRI +OPCODE_ORI +OPCODE_CPI +OPCODE_STA +OPCODE_LDA +OPCODE_SHLD +OPCODE_LHLD +OPCODE_PCHL +OPCODE_JMP +OPCODE_JC +OPCODE_JNC +OPCODE_JZ +OPCODE_JNZ +OPCODE_JP +OPCODE_JM +OPCODE_JPE +OPCODE_JPO +OPCODE_CALL +OPCODE_CC +OPCODE_CNC +OPCODE_CZ +OPCODE_CNZ +OPCODE_CP +OPCODE_CM +OPCODE_CPE +OPCODE_CPO +OPCODE_RET +OPCODE_RC +OPCODE_RNC +OPCODE_RZ +OPCODE_RNZ +OPCODE_RM +OPCODE_RP +OPCODE_RPE +OPCODE_RPO +OPCODE_RST +OPCODE_EI +OPCODE_DI +OPCODE_IN +OPCODE_OUT +OPCODE_HLT +PREP_ORG +PREP_EQU +PREP_SET +PREP_INCLUDE +PREP_IF +PREP_ENDIF +PREP_MACRO +PREP_ENDM +PREP_DB +PREP_DW +PREP_DS +PREP_ADDR +REG_A +REG_B +REG_C +REG_D +REG_E +REG_H +REG_L +REG_M +REG_PSW +REG_SP +SEP_LPAR +SEP_RPAR +SEP_COMMA +OP_ADD +OP_SUBTRACT +OP_MULTIPLY +OP_DIVIDE +OP_EQUAL +OP_MOD +OP_SHR +OP_SHL +OP_NOT +OP_AND +OP_OR +OP_XOR +LIT_NUMBER +LIT_HEXNUMBER_1 +LIT_HEXNUMBER_2 +LIT_OCTNUMBER +LIT_BINNUMBER +LIT_STRING_1 +LIT_STRING_2 +ID_IDENTIFIER +ID_LABEL +ERROR + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 130, 887, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 317, 10, 3, 3, 3, 7, 3, 320, 10, 3, 12, 3, 14, 3, 323, 11, 3, 3, 4, 5, 4, 326, 10, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 105, 3, 105, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 130, 3, 130, 3, 131, 3, 131, 3, 132, 3, 132, 3, 133, 3, 133, 3, 134, 3, 134, 3, 135, 3, 135, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 138, 3, 138, 3, 139, 3, 139, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 5, 144, 803, 10, 144, 3, 144, 6, 144, 806, 10, 144, 13, 144, 14, 144, 807, 3, 144, 5, 144, 811, 10, 144, 3, 145, 5, 145, 814, 10, 145, 3, 145, 3, 145, 3, 145, 3, 145, 5, 145, 820, 10, 145, 3, 145, 6, 145, 823, 10, 145, 13, 145, 14, 145, 824, 3, 146, 5, 146, 828, 10, 146, 3, 146, 6, 146, 831, 10, 146, 13, 146, 14, 146, 832, 3, 146, 3, 146, 3, 147, 5, 147, 838, 10, 147, 3, 147, 6, 147, 841, 10, 147, 13, 147, 14, 147, 842, 3, 147, 3, 147, 3, 148, 6, 148, 848, 10, 148, 13, 148, 14, 148, 849, 3, 148, 3, 148, 3, 149, 3, 149, 6, 149, 856, 10, 149, 13, 149, 14, 149, 857, 3, 149, 3, 149, 3, 150, 3, 150, 6, 150, 864, 10, 150, 13, 150, 14, 150, 865, 3, 150, 3, 150, 3, 151, 3, 151, 7, 151, 872, 10, 151, 12, 151, 14, 151, 875, 11, 151, 3, 152, 3, 152, 7, 152, 879, 10, 152, 12, 152, 14, 152, 882, 11, 152, 3, 152, 3, 152, 3, 153, 3, 153, 2, 2, 154, 3, 3, 5, 4, 7, 5, 9, 2, 11, 2, 13, 2, 15, 2, 17, 2, 19, 2, 21, 2, 23, 2, 25, 2, 27, 2, 29, 2, 31, 2, 33, 2, 35, 2, 37, 2, 39, 2, 41, 2, 43, 2, 45, 2, 47, 2, 49, 2, 51, 2, 53, 2, 55, 2, 57, 6, 59, 7, 61, 8, 63, 9, 65, 10, 67, 11, 69, 12, 71, 13, 73, 14, 75, 15, 77, 16, 79, 17, 81, 18, 83, 19, 85, 20, 87, 21, 89, 22, 91, 23, 93, 24, 95, 25, 97, 26, 99, 27, 101, 28, 103, 29, 105, 30, 107, 31, 109, 32, 111, 33, 113, 34, 115, 35, 117, 36, 119, 37, 121, 38, 123, 39, 125, 40, 127, 41, 129, 42, 131, 43, 133, 44, 135, 45, 137, 46, 139, 47, 141, 48, 143, 49, 145, 50, 147, 51, 149, 52, 151, 53, 153, 54, 155, 55, 157, 56, 159, 57, 161, 58, 163, 59, 165, 60, 167, 61, 169, 62, 171, 63, 173, 64, 175, 65, 177, 66, 179, 67, 181, 68, 183, 69, 185, 70, 187, 71, 189, 72, 191, 73, 193, 74, 195, 75, 197, 76, 199, 77, 201, 78, 203, 79, 205, 80, 207, 81, 209, 82, 211, 83, 213, 84, 215, 85, 217, 86, 219, 87, 221, 88, 223, 89, 225, 90, 227, 91, 229, 92, 231, 93, 233, 94, 235, 95, 237, 96, 239, 97, 241, 98, 243, 99, 245, 100, 247, 101, 249, 102, 251, 103, 253, 104, 255, 105, 257, 106, 259, 107, 261, 108, 263, 109, 265, 110, 267, 111, 269, 112, 271, 113, 273, 114, 275, 115, 277, 116, 279, 117, 281, 118, 283, 119, 285, 120, 287, 121, 289, 122, 291, 123, 293, 124, 295, 125, 297, 126, 299, 127, 301, 128, 303, 129, 305, 130, 3, 2, 40, 5, 2, 11, 11, 14, 14, 34, 34, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 92, 92, 124, 124, 3, 2, 47, 47, 3, 2, 50, 59, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 4, 2, 41, 41, 96, 96, 4, 2, 36, 36, 96, 96, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 2, 881, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 157, 3, 2, 2, 2, 2, 159, 3, 2, 2, 2, 2, 161, 3, 2, 2, 2, 2, 163, 3, 2, 2, 2, 2, 165, 3, 2, 2, 2, 2, 167, 3, 2, 2, 2, 2, 169, 3, 2, 2, 2, 2, 171, 3, 2, 2, 2, 2, 173, 3, 2, 2, 2, 2, 175, 3, 2, 2, 2, 2, 177, 3, 2, 2, 2, 2, 179, 3, 2, 2, 2, 2, 181, 3, 2, 2, 2, 2, 183, 3, 2, 2, 2, 2, 185, 3, 2, 2, 2, 2, 187, 3, 2, 2, 2, 2, 189, 3, 2, 2, 2, 2, 191, 3, 2, 2, 2, 2, 193, 3, 2, 2, 2, 2, 195, 3, 2, 2, 2, 2, 197, 3, 2, 2, 2, 2, 199, 3, 2, 2, 2, 2, 201, 3, 2, 2, 2, 2, 203, 3, 2, 2, 2, 2, 205, 3, 2, 2, 2, 2, 207, 3, 2, 2, 2, 2, 209, 3, 2, 2, 2, 2, 211, 3, 2, 2, 2, 2, 213, 3, 2, 2, 2, 2, 215, 3, 2, 2, 2, 2, 217, 3, 2, 2, 2, 2, 219, 3, 2, 2, 2, 2, 221, 3, 2, 2, 2, 2, 223, 3, 2, 2, 2, 2, 225, 3, 2, 2, 2, 2, 227, 3, 2, 2, 2, 2, 229, 3, 2, 2, 2, 2, 231, 3, 2, 2, 2, 2, 233, 3, 2, 2, 2, 2, 235, 3, 2, 2, 2, 2, 237, 3, 2, 2, 2, 2, 239, 3, 2, 2, 2, 2, 241, 3, 2, 2, 2, 2, 243, 3, 2, 2, 2, 2, 245, 3, 2, 2, 2, 2, 247, 3, 2, 2, 2, 2, 249, 3, 2, 2, 2, 2, 251, 3, 2, 2, 2, 2, 253, 3, 2, 2, 2, 2, 255, 3, 2, 2, 2, 2, 257, 3, 2, 2, 2, 2, 259, 3, 2, 2, 2, 2, 261, 3, 2, 2, 2, 2, 263, 3, 2, 2, 2, 2, 265, 3, 2, 2, 2, 2, 267, 3, 2, 2, 2, 2, 269, 3, 2, 2, 2, 2, 271, 3, 2, 2, 2, 2, 273, 3, 2, 2, 2, 2, 275, 3, 2, 2, 2, 2, 277, 3, 2, 2, 2, 2, 279, 3, 2, 2, 2, 2, 281, 3, 2, 2, 2, 2, 283, 3, 2, 2, 2, 2, 285, 3, 2, 2, 2, 2, 287, 3, 2, 2, 2, 2, 289, 3, 2, 2, 2, 2, 291, 3, 2, 2, 2, 2, 293, 3, 2, 2, 2, 2, 295, 3, 2, 2, 2, 2, 297, 3, 2, 2, 2, 2, 299, 3, 2, 2, 2, 2, 301, 3, 2, 2, 2, 2, 303, 3, 2, 2, 2, 2, 305, 3, 2, 2, 2, 3, 307, 3, 2, 2, 2, 5, 316, 3, 2, 2, 2, 7, 325, 3, 2, 2, 2, 9, 329, 3, 2, 2, 2, 11, 331, 3, 2, 2, 2, 13, 333, 3, 2, 2, 2, 15, 335, 3, 2, 2, 2, 17, 337, 3, 2, 2, 2, 19, 339, 3, 2, 2, 2, 21, 341, 3, 2, 2, 2, 23, 343, 3, 2, 2, 2, 25, 345, 3, 2, 2, 2, 27, 347, 3, 2, 2, 2, 29, 349, 3, 2, 2, 2, 31, 351, 3, 2, 2, 2, 33, 353, 3, 2, 2, 2, 35, 355, 3, 2, 2, 2, 37, 357, 3, 2, 2, 2, 39, 359, 3, 2, 2, 2, 41, 361, 3, 2, 2, 2, 43, 363, 3, 2, 2, 2, 45, 365, 3, 2, 2, 2, 47, 367, 3, 2, 2, 2, 49, 369, 3, 2, 2, 2, 51, 371, 3, 2, 2, 2, 53, 373, 3, 2, 2, 2, 55, 375, 3, 2, 2, 2, 57, 377, 3, 2, 2, 2, 59, 381, 3, 2, 2, 2, 61, 385, 3, 2, 2, 2, 63, 389, 3, 2, 2, 2, 65, 393, 3, 2, 2, 2, 67, 397, 3, 2, 2, 2, 69, 401, 3, 2, 2, 2, 71, 405, 3, 2, 2, 2, 73, 409, 3, 2, 2, 2, 75, 414, 3, 2, 2, 2, 77, 419, 3, 2, 2, 2, 79, 423, 3, 2, 2, 2, 81, 427, 3, 2, 2, 2, 83, 431, 3, 2, 2, 2, 85, 435, 3, 2, 2, 2, 87, 439, 3, 2, 2, 2, 89, 443, 3, 2, 2, 2, 91, 447, 3, 2, 2, 2, 93, 451, 3, 2, 2, 2, 95, 455, 3, 2, 2, 2, 97, 459, 3, 2, 2, 2, 99, 463, 3, 2, 2, 2, 101, 467, 3, 2, 2, 2, 103, 472, 3, 2, 2, 2, 105, 476, 3, 2, 2, 2, 107, 480, 3, 2, 2, 2, 109, 484, 3, 2, 2, 2, 111, 488, 3, 2, 2, 2, 113, 493, 3, 2, 2, 2, 115, 498, 3, 2, 2, 2, 117, 503, 3, 2, 2, 2, 119, 507, 3, 2, 2, 2, 121, 511, 3, 2, 2, 2, 123, 515, 3, 2, 2, 2, 125, 519, 3, 2, 2, 2, 127, 523, 3, 2, 2, 2, 129, 527, 3, 2, 2, 2, 131, 531, 3, 2, 2, 2, 133, 535, 3, 2, 2, 2, 135, 539, 3, 2, 2, 2, 137, 543, 3, 2, 2, 2, 139, 547, 3, 2, 2, 2, 141, 551, 3, 2, 2, 2, 143, 556, 3, 2, 2, 2, 145, 561, 3, 2, 2, 2, 147, 566, 3, 2, 2, 2, 149, 570, 3, 2, 2, 2, 151, 573, 3, 2, 2, 2, 153, 577, 3, 2, 2, 2, 155, 580, 3, 2, 2, 2, 157, 584, 3, 2, 2, 2, 159, 587, 3, 2, 2, 2, 161, 590, 3, 2, 2, 2, 163, 594, 3, 2, 2, 2, 165, 598, 3, 2, 2, 2, 167, 603, 3, 2, 2, 2, 169, 606, 3, 2, 2, 2, 171, 610, 3, 2, 2, 2, 173, 613, 3, 2, 2, 2, 175, 617, 3, 2, 2, 2, 177, 620, 3, 2, 2, 2, 179, 623, 3, 2, 2, 2, 181, 627, 3, 2, 2, 2, 183, 631, 3, 2, 2, 2, 185, 635, 3, 2, 2, 2, 187, 638, 3, 2, 2, 2, 189, 642, 3, 2, 2, 2, 191, 645, 3, 2, 2, 2, 193, 649, 3, 2, 2, 2, 195, 652, 3, 2, 2, 2, 197, 655, 3, 2, 2, 2, 199, 659, 3, 2, 2, 2, 201, 663, 3, 2, 2, 2, 203, 667, 3, 2, 2, 2, 205, 670, 3, 2, 2, 2, 207, 673, 3, 2, 2, 2, 209, 676, 3, 2, 2, 2, 211, 680, 3, 2, 2, 2, 213, 684, 3, 2, 2, 2, 215, 688, 3, 2, 2, 2, 217, 692, 3, 2, 2, 2, 219, 696, 3, 2, 2, 2, 221, 704, 3, 2, 2, 2, 223, 707, 3, 2, 2, 2, 225, 713, 3, 2, 2, 2, 227, 719, 3, 2, 2, 2, 229, 724, 3, 2, 2, 2, 231, 727, 3, 2, 2, 2, 233, 730, 3, 2, 2, 2, 235, 733, 3, 2, 2, 2, 237, 735, 3, 2, 2, 2, 239, 737, 3, 2, 2, 2, 241, 739, 3, 2, 2, 2, 243, 741, 3, 2, 2, 2, 245, 743, 3, 2, 2, 2, 247, 745, 3, 2, 2, 2, 249, 747, 3, 2, 2, 2, 251, 749, 3, 2, 2, 2, 253, 751, 3, 2, 2, 2, 255, 755, 3, 2, 2, 2, 257, 758, 3, 2, 2, 2, 259, 760, 3, 2, 2, 2, 261, 762, 3, 2, 2, 2, 263, 764, 3, 2, 2, 2, 265, 766, 3, 2, 2, 2, 267, 768, 3, 2, 2, 2, 269, 770, 3, 2, 2, 2, 271, 772, 3, 2, 2, 2, 273, 774, 3, 2, 2, 2, 275, 778, 3, 2, 2, 2, 277, 782, 3, 2, 2, 2, 279, 786, 3, 2, 2, 2, 281, 790, 3, 2, 2, 2, 283, 794, 3, 2, 2, 2, 285, 797, 3, 2, 2, 2, 287, 802, 3, 2, 2, 2, 289, 813, 3, 2, 2, 2, 291, 827, 3, 2, 2, 2, 293, 837, 3, 2, 2, 2, 295, 847, 3, 2, 2, 2, 297, 853, 3, 2, 2, 2, 299, 861, 3, 2, 2, 2, 301, 869, 3, 2, 2, 2, 303, 876, 3, 2, 2, 2, 305, 885, 3, 2, 2, 2, 307, 308, 9, 2, 2, 2, 308, 309, 3, 2, 2, 2, 309, 310, 8, 2, 2, 2, 310, 4, 3, 2, 2, 2, 311, 312, 7, 49, 2, 2, 312, 317, 7, 49, 2, 2, 313, 314, 7, 47, 2, 2, 314, 317, 7, 47, 2, 2, 315, 317, 9, 3, 2, 2, 316, 311, 3, 2, 2, 2, 316, 313, 3, 2, 2, 2, 316, 315, 3, 2, 2, 2, 317, 321, 3, 2, 2, 2, 318, 320, 10, 4, 2, 2, 319, 318, 3, 2, 2, 2, 320, 323, 3, 2, 2, 2, 321, 319, 3, 2, 2, 2, 321, 322, 3, 2, 2, 2, 322, 6, 3, 2, 2, 2, 323, 321, 3, 2, 2, 2, 324, 326, 7, 15, 2, 2, 325, 324, 3, 2, 2, 2, 325, 326, 3, 2, 2, 2, 326, 327, 3, 2, 2, 2, 327, 328, 7, 12, 2, 2, 328, 8, 3, 2, 2, 2, 329, 330, 9, 5, 2, 2, 330, 10, 3, 2, 2, 2, 331, 332, 9, 6, 2, 2, 332, 12, 3, 2, 2, 2, 333, 334, 9, 7, 2, 2, 334, 14, 3, 2, 2, 2, 335, 336, 9, 8, 2, 2, 336, 16, 3, 2, 2, 2, 337, 338, 9, 9, 2, 2, 338, 18, 3, 2, 2, 2, 339, 340, 9, 10, 2, 2, 340, 20, 3, 2, 2, 2, 341, 342, 9, 11, 2, 2, 342, 22, 3, 2, 2, 2, 343, 344, 9, 12, 2, 2, 344, 24, 3, 2, 2, 2, 345, 346, 9, 13, 2, 2, 346, 26, 3, 2, 2, 2, 347, 348, 9, 14, 2, 2, 348, 28, 3, 2, 2, 2, 349, 350, 9, 15, 2, 2, 350, 30, 3, 2, 2, 2, 351, 352, 9, 16, 2, 2, 352, 32, 3, 2, 2, 2, 353, 354, 9, 17, 2, 2, 354, 34, 3, 2, 2, 2, 355, 356, 9, 18, 2, 2, 356, 36, 3, 2, 2, 2, 357, 358, 9, 19, 2, 2, 358, 38, 3, 2, 2, 2, 359, 360, 9, 20, 2, 2, 360, 40, 3, 2, 2, 2, 361, 362, 9, 21, 2, 2, 362, 42, 3, 2, 2, 2, 363, 364, 9, 22, 2, 2, 364, 44, 3, 2, 2, 2, 365, 366, 9, 23, 2, 2, 366, 46, 3, 2, 2, 2, 367, 368, 9, 24, 2, 2, 368, 48, 3, 2, 2, 2, 369, 370, 9, 25, 2, 2, 370, 50, 3, 2, 2, 2, 371, 372, 9, 26, 2, 2, 372, 52, 3, 2, 2, 2, 373, 374, 9, 27, 2, 2, 374, 54, 3, 2, 2, 2, 375, 376, 9, 28, 2, 2, 376, 56, 3, 2, 2, 2, 377, 378, 5, 43, 22, 2, 378, 379, 5, 45, 23, 2, 379, 380, 5, 13, 7, 2, 380, 58, 3, 2, 2, 2, 381, 382, 5, 13, 7, 2, 382, 383, 5, 31, 16, 2, 383, 384, 5, 13, 7, 2, 384, 60, 3, 2, 2, 2, 385, 386, 5, 25, 13, 2, 386, 387, 5, 33, 17, 2, 387, 388, 5, 41, 21, 2, 388, 62, 3, 2, 2, 2, 389, 390, 5, 15, 8, 2, 390, 391, 5, 13, 7, 2, 391, 392, 5, 41, 21, 2, 392, 64, 3, 2, 2, 2, 393, 394, 5, 13, 7, 2, 394, 395, 5, 31, 16, 2, 395, 396, 5, 9, 5, 2, 396, 66, 3, 2, 2, 2, 397, 398, 5, 15, 8, 2, 398, 399, 5, 9, 5, 2, 399, 400, 5, 9, 5, 2, 400, 68, 3, 2, 2, 2, 401, 402, 5, 33, 17, 2, 402, 403, 5, 35, 18, 2, 403, 404, 5, 37, 19, 2, 404, 70, 3, 2, 2, 2, 405, 406, 5, 31, 16, 2, 406, 407, 5, 35, 18, 2, 407, 408, 5, 49, 25, 2, 408, 72, 3, 2, 2, 2, 409, 410, 5, 43, 22, 2, 410, 411, 5, 45, 23, 2, 411, 412, 5, 9, 5, 2, 412, 413, 5, 53, 27, 2, 413, 74, 3, 2, 2, 2, 414, 415, 5, 29, 15, 2, 415, 416, 5, 15, 8, 2, 416, 417, 5, 9, 5, 2, 417, 418, 5, 53, 27, 2, 418, 76, 3, 2, 2, 2, 419, 420, 5, 9, 5, 2, 420, 421, 5, 15, 8, 2, 421, 422, 5, 15, 8, 2, 422, 78, 3, 2, 2, 2, 423, 424, 5, 9, 5, 2, 424, 425, 5, 15, 8, 2, 425, 426, 5, 13, 7, 2, 426, 80, 3, 2, 2, 2, 427, 428, 5, 43, 22, 2, 428, 429, 5, 47, 24, 2, 429, 430, 5, 11, 6, 2, 430, 82, 3, 2, 2, 2, 431, 432, 5, 43, 22, 2, 432, 433, 5, 11, 6, 2, 433, 434, 5, 11, 6, 2, 434, 84, 3, 2, 2, 2, 435, 436, 5, 9, 5, 2, 436, 437, 5, 33, 17, 2, 437, 438, 5, 9, 5, 2, 438, 86, 3, 2, 2, 2, 439, 440, 5, 53, 27, 2, 440, 441, 5, 41, 21, 2, 441, 442, 5, 9, 5, 2, 442, 88, 3, 2, 2, 2, 443, 444, 5, 35, 18, 2, 444, 445, 5, 41, 21, 2, 445, 446, 5, 9, 5, 2, 446, 90, 3, 2, 2, 2, 447, 448, 5, 13, 7, 2, 448, 449, 5, 31, 16, 2, 449, 450, 5, 37, 19, 2, 450, 92, 3, 2, 2, 2, 451, 452, 5, 41, 21, 2, 452, 453, 5, 29, 15, 2, 453, 454, 5, 13, 7, 2, 454, 94, 3, 2, 2, 2, 455, 456, 5, 41, 21, 2, 456, 457, 5, 41, 21, 2, 457, 458, 5, 13, 7, 2, 458, 96, 3, 2, 2, 2, 459, 460, 5, 41, 21, 2, 460, 461, 5, 9, 5, 2, 461, 462, 5, 29, 15, 2, 462, 98, 3, 2, 2, 2, 463, 464, 5, 41, 21, 2, 464, 465, 5, 9, 5, 2, 465, 466, 5, 41, 21, 2, 466, 100, 3, 2, 2, 2, 467, 468, 5, 37, 19, 2, 468, 469, 5, 47, 24, 2, 469, 470, 5, 43, 22, 2, 470, 471, 5, 23, 12, 2, 471, 102, 3, 2, 2, 2, 472, 473, 5, 37, 19, 2, 473, 474, 5, 35, 18, 2, 474, 475, 5, 37, 19, 2, 475, 104, 3, 2, 2, 2, 476, 477, 5, 15, 8, 2, 477, 478, 5, 9, 5, 2, 478, 479, 5, 15, 8, 2, 479, 106, 3, 2, 2, 2, 480, 481, 5, 25, 13, 2, 481, 482, 5, 33, 17, 2, 482, 483, 5, 53, 27, 2, 483, 108, 3, 2, 2, 2, 484, 485, 5, 15, 8, 2, 485, 486, 5, 13, 7, 2, 486, 487, 5, 53, 27, 2, 487, 110, 3, 2, 2, 2, 488, 489, 5, 53, 27, 2, 489, 490, 5, 13, 7, 2, 490, 491, 5, 23, 12, 2, 491, 492, 5, 21, 11, 2, 492, 112, 3, 2, 2, 2, 493, 494, 5, 53, 27, 2, 494, 495, 5, 45, 23, 2, 495, 496, 5, 23, 12, 2, 496, 497, 5, 29, 15, 2, 497, 114, 3, 2, 2, 2, 498, 499, 5, 43, 22, 2, 499, 500, 5, 37, 19, 2, 500, 501, 5, 23, 12, 2, 501, 502, 5, 29, 15, 2, 502, 116, 3, 2, 2, 2, 503, 504, 5, 29, 15, 2, 504, 505, 5, 53, 27, 2, 505, 506, 5, 25, 13, 2, 506, 118, 3, 2, 2, 2, 507, 508, 5, 31, 16, 2, 508, 509, 5, 49, 25, 2, 509, 510, 5, 25, 13, 2, 510, 120, 3, 2, 2, 2, 511, 512, 5, 9, 5, 2, 512, 513, 5, 15, 8, 2, 513, 514, 5, 25, 13, 2, 514, 122, 3, 2, 2, 2, 515, 516, 5, 9, 5, 2, 516, 517, 5, 13, 7, 2, 517, 518, 5, 25, 13, 2, 518, 124, 3, 2, 2, 2, 519, 520, 5, 43, 22, 2, 520, 521, 5, 47, 24, 2, 521, 522, 5, 25, 13, 2, 522, 126, 3, 2, 2, 2, 523, 524, 5, 43, 22, 2, 524, 525, 5, 11, 6, 2, 525, 526, 5, 25, 13, 2, 526, 128, 3, 2, 2, 2, 527, 528, 5, 9, 5, 2, 528, 529, 5, 33, 17, 2, 529, 530, 5, 25, 13, 2, 530, 130, 3, 2, 2, 2, 531, 532, 5, 53, 27, 2, 532, 533, 5, 41, 21, 2, 533, 534, 5, 25, 13, 2, 534, 132, 3, 2, 2, 2, 535, 536, 5, 35, 18, 2, 536, 537, 5, 41, 21, 2, 537, 538, 5, 25, 13, 2, 538, 134, 3, 2, 2, 2, 539, 540, 5, 13, 7, 2, 540, 541, 5, 37, 19, 2, 541, 542, 5, 25, 13, 2, 542, 136, 3, 2, 2, 2, 543, 544, 5, 43, 22, 2, 544, 545, 5, 45, 23, 2, 545, 546, 5, 9, 5, 2, 546, 138, 3, 2, 2, 2, 547, 548, 5, 29, 15, 2, 548, 549, 5, 15, 8, 2, 549, 550, 5, 9, 5, 2, 550, 140, 3, 2, 2, 2, 551, 552, 5, 43, 22, 2, 552, 553, 5, 23, 12, 2, 553, 554, 5, 29, 15, 2, 554, 555, 5, 15, 8, 2, 555, 142, 3, 2, 2, 2, 556, 557, 5, 29, 15, 2, 557, 558, 5, 23, 12, 2, 558, 559, 5, 29, 15, 2, 559, 560, 5, 15, 8, 2, 560, 144, 3, 2, 2, 2, 561, 562, 5, 37, 19, 2, 562, 563, 5, 13, 7, 2, 563, 564, 5, 23, 12, 2, 564, 565, 5, 29, 15, 2, 565, 146, 3, 2, 2, 2, 566, 567, 5, 27, 14, 2, 567, 568, 5, 31, 16, 2, 568, 569, 5, 37, 19, 2, 569, 148, 3, 2, 2, 2, 570, 571, 5, 27, 14, 2, 571, 572, 5, 13, 7, 2, 572, 150, 3, 2, 2, 2, 573, 574, 5, 27, 14, 2, 574, 575, 5, 33, 17, 2, 575, 576, 5, 13, 7, 2, 576, 152, 3, 2, 2, 2, 577, 578, 5, 27, 14, 2, 578, 579, 5, 55, 28, 2, 579, 154, 3, 2, 2, 2, 580, 581, 5, 27, 14, 2, 581, 582, 5, 33, 17, 2, 582, 583, 5, 55, 28, 2, 583, 156, 3, 2, 2, 2, 584, 585, 5, 27, 14, 2, 585, 586, 5, 37, 19, 2, 586, 158, 3, 2, 2, 2, 587, 588, 5, 27, 14, 2, 588, 589, 5, 31, 16, 2, 589, 160, 3, 2, 2, 2, 590, 591, 5, 27, 14, 2, 591, 592, 5, 37, 19, 2, 592, 593, 5, 17, 9, 2, 593, 162, 3, 2, 2, 2, 594, 595, 5, 27, 14, 2, 595, 596, 5, 37, 19, 2, 596, 597, 5, 35, 18, 2, 597, 164, 3, 2, 2, 2, 598, 599, 5, 13, 7, 2, 599, 600, 5, 9, 5, 2, 600, 601, 5, 29, 15, 2, 601, 602, 5, 29, 15, 2, 602, 166, 3, 2, 2, 2, 603, 604, 5, 13, 7, 2, 604, 605, 5, 13, 7, 2, 605, 168, 3, 2, 2, 2, 606, 607, 5, 13, 7, 2, 607, 608, 5, 33, 17, 2, 608, 609, 5, 13, 7, 2, 609, 170, 3, 2, 2, 2, 610, 611, 5, 13, 7, 2, 611, 612, 5, 55, 28, 2, 612, 172, 3, 2, 2, 2, 613, 614, 5, 13, 7, 2, 614, 615, 5, 33, 17, 2, 615, 616, 5, 55, 28, 2, 616, 174, 3, 2, 2, 2, 617, 618, 5, 13, 7, 2, 618, 619, 5, 37, 19, 2, 619, 176, 3, 2, 2, 2, 620, 621, 5, 13, 7, 2, 621, 622, 5, 31, 16, 2, 622, 178, 3, 2, 2, 2, 623, 624, 5, 13, 7, 2, 624, 625, 5, 37, 19, 2, 625, 626, 5, 17, 9, 2, 626, 180, 3, 2, 2, 2, 627, 628, 5, 13, 7, 2, 628, 629, 5, 37, 19, 2, 629, 630, 5, 35, 18, 2, 630, 182, 3, 2, 2, 2, 631, 632, 5, 41, 21, 2, 632, 633, 5, 17, 9, 2, 633, 634, 5, 45, 23, 2, 634, 184, 3, 2, 2, 2, 635, 636, 5, 41, 21, 2, 636, 637, 5, 13, 7, 2, 637, 186, 3, 2, 2, 2, 638, 639, 5, 41, 21, 2, 639, 640, 5, 33, 17, 2, 640, 641, 5, 13, 7, 2, 641, 188, 3, 2, 2, 2, 642, 643, 5, 41, 21, 2, 643, 644, 5, 55, 28, 2, 644, 190, 3, 2, 2, 2, 645, 646, 5, 41, 21, 2, 646, 647, 5, 33, 17, 2, 647, 648, 5, 55, 28, 2, 648, 192, 3, 2, 2, 2, 649, 650, 5, 41, 21, 2, 650, 651, 5, 31, 16, 2, 651, 194, 3, 2, 2, 2, 652, 653, 5, 41, 21, 2, 653, 654, 5, 37, 19, 2, 654, 196, 3, 2, 2, 2, 655, 656, 5, 41, 21, 2, 656, 657, 5, 37, 19, 2, 657, 658, 5, 17, 9, 2, 658, 198, 3, 2, 2, 2, 659, 660, 5, 41, 21, 2, 660, 661, 5, 37, 19, 2, 661, 662, 5, 35, 18, 2, 662, 200, 3, 2, 2, 2, 663, 664, 5, 41, 21, 2, 664, 665, 5, 43, 22, 2, 665, 666, 5, 45, 23, 2, 666, 202, 3, 2, 2, 2, 667, 668, 5, 17, 9, 2, 668, 669, 5, 25, 13, 2, 669, 204, 3, 2, 2, 2, 670, 671, 5, 15, 8, 2, 671, 672, 5, 25, 13, 2, 672, 206, 3, 2, 2, 2, 673, 674, 5, 25, 13, 2, 674, 675, 5, 33, 17, 2, 675, 208, 3, 2, 2, 2, 676, 677, 5, 35, 18, 2, 677, 678, 5, 47, 24, 2, 678, 679, 5, 45, 23, 2, 679, 210, 3, 2, 2, 2, 680, 681, 5, 23, 12, 2, 681, 682, 5, 29, 15, 2, 682, 683, 5, 45, 23, 2, 683, 212, 3, 2, 2, 2, 684, 685, 5, 35, 18, 2, 685, 686, 5, 41, 21, 2, 686, 687, 5, 21, 11, 2, 687, 214, 3, 2, 2, 2, 688, 689, 5, 17, 9, 2, 689, 690, 5, 39, 20, 2, 690, 691, 5, 47, 24, 2, 691, 216, 3, 2, 2, 2, 692, 693, 5, 43, 22, 2, 693, 694, 5, 17, 9, 2, 694, 695, 5, 45, 23, 2, 695, 218, 3, 2, 2, 2, 696, 697, 5, 25, 13, 2, 697, 698, 5, 33, 17, 2, 698, 699, 5, 13, 7, 2, 699, 700, 5, 29, 15, 2, 700, 701, 5, 47, 24, 2, 701, 702, 5, 15, 8, 2, 702, 703, 5, 17, 9, 2, 703, 220, 3, 2, 2, 2, 704, 705, 5, 25, 13, 2, 705, 706, 5, 19, 10, 2, 706, 222, 3, 2, 2, 2, 707, 708, 5, 17, 9, 2, 708, 709, 5, 33, 17, 2, 709, 710, 5, 15, 8, 2, 710, 711, 5, 25, 13, 2, 711, 712, 5, 19, 10, 2, 712, 224, 3, 2, 2, 2, 713, 714, 5, 31, 16, 2, 714, 715, 5, 9, 5, 2, 715, 716, 5, 13, 7, 2, 716, 717, 5, 41, 21, 2, 717, 718, 5, 35, 18, 2, 718, 226, 3, 2, 2, 2, 719, 720, 5, 17, 9, 2, 720, 721, 5, 33, 17, 2, 721, 722, 5, 15, 8, 2, 722, 723, 5, 31, 16, 2, 723, 228, 3, 2, 2, 2, 724, 725, 5, 15, 8, 2, 725, 726, 5, 11, 6, 2, 726, 230, 3, 2, 2, 2, 727, 728, 5, 15, 8, 2, 728, 729, 5, 51, 26, 2, 729, 232, 3, 2, 2, 2, 730, 731, 5, 15, 8, 2, 731, 732, 5, 43, 22, 2, 732, 234, 3, 2, 2, 2, 733, 734, 7, 38, 2, 2, 734, 236, 3, 2, 2, 2, 735, 736, 5, 9, 5, 2, 736, 238, 3, 2, 2, 2, 737, 738, 5, 11, 6, 2, 738, 240, 3, 2, 2, 2, 739, 740, 5, 13, 7, 2, 740, 242, 3, 2, 2, 2, 741, 742, 5, 15, 8, 2, 742, 244, 3, 2, 2, 2, 743, 744, 5, 17, 9, 2, 744, 246, 3, 2, 2, 2, 745, 746, 5, 23, 12, 2, 746, 248, 3, 2, 2, 2, 747, 748, 5, 29, 15, 2, 748, 250, 3, 2, 2, 2, 749, 750, 5, 31, 16, 2, 750, 252, 3, 2, 2, 2, 751, 752, 5, 37, 19, 2, 752, 753, 5, 43, 22, 2, 753, 754, 5, 51, 26, 2, 754, 254, 3, 2, 2, 2, 755, 756, 5, 43, 22, 2, 756, 757, 5, 37, 19, 2, 757, 256, 3, 2, 2, 2, 758, 759, 7, 42, 2, 2, 759, 258, 3, 2, 2, 2, 760, 761, 7, 43, 2, 2, 761, 260, 3, 2, 2, 2, 762, 763, 7, 46, 2, 2, 763, 262, 3, 2, 2, 2, 764, 765, 7, 45, 2, 2, 765, 264, 3, 2, 2, 2, 766, 767, 7, 47, 2, 2, 767, 266, 3, 2, 2, 2, 768, 769, 7, 44, 2, 2, 769, 268, 3, 2, 2, 2, 770, 771, 7, 49, 2, 2, 771, 270, 3, 2, 2, 2, 772, 773, 7, 63, 2, 2, 773, 272, 3, 2, 2, 2, 774, 775, 5, 31, 16, 2, 775, 776, 5, 35, 18, 2, 776, 777, 5, 15, 8, 2, 777, 274, 3, 2, 2, 2, 778, 779, 5, 43, 22, 2, 779, 780, 5, 23, 12, 2, 780, 781, 5, 41, 21, 2, 781, 276, 3, 2, 2, 2, 782, 783, 5, 43, 22, 2, 783, 784, 5, 23, 12, 2, 784, 785, 5, 29, 15, 2, 785, 278, 3, 2, 2, 2, 786, 787, 5, 33, 17, 2, 787, 788, 5, 35, 18, 2, 788, 789, 5, 45, 23, 2, 789, 280, 3, 2, 2, 2, 790, 791, 5, 9, 5, 2, 791, 792, 5, 33, 17, 2, 792, 793, 5, 15, 8, 2, 793, 282, 3, 2, 2, 2, 794, 795, 5, 35, 18, 2, 795, 796, 5, 41, 21, 2, 796, 284, 3, 2, 2, 2, 797, 798, 5, 53, 27, 2, 798, 799, 5, 35, 18, 2, 799, 800, 5, 41, 21, 2, 800, 286, 3, 2, 2, 2, 801, 803, 9, 29, 2, 2, 802, 801, 3, 2, 2, 2, 802, 803, 3, 2, 2, 2, 803, 805, 3, 2, 2, 2, 804, 806, 9, 30, 2, 2, 805, 804, 3, 2, 2, 2, 806, 807, 3, 2, 2, 2, 807, 805, 3, 2, 2, 2, 807, 808, 3, 2, 2, 2, 808, 810, 3, 2, 2, 2, 809, 811, 5, 15, 8, 2, 810, 809, 3, 2, 2, 2, 810, 811, 3, 2, 2, 2, 811, 288, 3, 2, 2, 2, 812, 814, 9, 29, 2, 2, 813, 812, 3, 2, 2, 2, 813, 814, 3, 2, 2, 2, 814, 819, 3, 2, 2, 2, 815, 816, 7, 50, 2, 2, 816, 820, 7, 122, 2, 2, 817, 818, 7, 50, 2, 2, 818, 820, 7, 90, 2, 2, 819, 815, 3, 2, 2, 2, 819, 817, 3, 2, 2, 2, 820, 822, 3, 2, 2, 2, 821, 823, 9, 31, 2, 2, 822, 821, 3, 2, 2, 2, 823, 824, 3, 2, 2, 2, 824, 822, 3, 2, 2, 2, 824, 825, 3, 2, 2, 2, 825, 290, 3, 2, 2, 2, 826, 828, 9, 29, 2, 2, 827, 826, 3, 2, 2, 2, 827, 828, 3, 2, 2, 2, 828, 830, 3, 2, 2, 2, 829, 831, 9, 31, 2, 2, 830, 829, 3, 2, 2, 2, 831, 832, 3, 2, 2, 2, 832, 830, 3, 2, 2, 2, 832, 833, 3, 2, 2, 2, 833, 834, 3, 2, 2, 2, 834, 835, 5, 23, 12, 2, 835, 292, 3, 2, 2, 2, 836, 838, 9, 29, 2, 2, 837, 836, 3, 2, 2, 2, 837, 838, 3, 2, 2, 2, 838, 840, 3, 2, 2, 2, 839, 841, 9, 32, 2, 2, 840, 839, 3, 2, 2, 2, 841, 842, 3, 2, 2, 2, 842, 840, 3, 2, 2, 2, 842, 843, 3, 2, 2, 2, 843, 844, 3, 2, 2, 2, 844, 845, 9, 33, 2, 2, 845, 294, 3, 2, 2, 2, 846, 848, 9, 34, 2, 2, 847, 846, 3, 2, 2, 2, 848, 849, 3, 2, 2, 2, 849, 847, 3, 2, 2, 2, 849, 850, 3, 2, 2, 2, 850, 851, 3, 2, 2, 2, 851, 852, 5, 11, 6, 2, 852, 296, 3, 2, 2, 2, 853, 855, 9, 35, 2, 2, 854, 856, 9, 36, 2, 2, 855, 854, 3, 2, 2, 2, 856, 857, 3, 2, 2, 2, 857, 855, 3, 2, 2, 2, 857, 858, 3, 2, 2, 2, 858, 859, 3, 2, 2, 2, 859, 860, 9, 35, 2, 2, 860, 298, 3, 2, 2, 2, 861, 863, 7, 36, 2, 2, 862, 864, 9, 37, 2, 2, 863, 862, 3, 2, 2, 2, 864, 865, 3, 2, 2, 2, 865, 863, 3, 2, 2, 2, 865, 866, 3, 2, 2, 2, 866, 867, 3, 2, 2, 2, 867, 868, 7, 36, 2, 2, 868, 300, 3, 2, 2, 2, 869, 873, 9, 38, 2, 2, 870, 872, 9, 39, 2, 2, 871, 870, 3, 2, 2, 2, 872, 875, 3, 2, 2, 2, 873, 871, 3, 2, 2, 2, 873, 874, 3, 2, 2, 2, 874, 302, 3, 2, 2, 2, 875, 873, 3, 2, 2, 2, 876, 880, 9, 38, 2, 2, 877, 879, 9, 39, 2, 2, 878, 877, 3, 2, 2, 2, 879, 882, 3, 2, 2, 2, 880, 878, 3, 2, 2, 2, 880, 881, 3, 2, 2, 2, 881, 883, 3, 2, 2, 2, 882, 880, 3, 2, 2, 2, 883, 884, 7, 60, 2, 2, 884, 304, 3, 2, 2, 2, 885, 886, 11, 2, 2, 2, 886, 306, 3, 2, 2, 2, 21, 2, 316, 321, 325, 802, 807, 810, 813, 819, 824, 827, 832, 837, 842, 849, 857, 865, 873, 880, 3, 2, 3, 2] \ No newline at end of file diff --git a/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.java b/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.java new file mode 100644 index 000000000..4dc054c3f --- /dev/null +++ b/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.java @@ -0,0 +1,506 @@ +// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 by ANTLR 4.9.1 +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class As8080Lexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.9.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + WS=1, COMMENT=2, EOL=3, OPCODE_STC=4, OPCODE_CMC=5, OPCODE_INR=6, OPCODE_DCR=7, + OPCODE_CMA=8, OPCODE_DAA=9, OPCODE_NOP=10, OPCODE_MOV=11, OPCODE_STAX=12, + OPCODE_LDAX=13, OPCODE_ADD=14, OPCODE_ADC=15, OPCODE_SUB=16, OPCODE_SBB=17, + OPCODE_ANA=18, OPCODE_XRA=19, OPCODE_ORA=20, OPCODE_CMP=21, OPCODE_RLC=22, + OPCODE_RRC=23, OPCODE_RAL=24, OPCODE_RAR=25, OPCODE_PUSH=26, OPCODE_POP=27, + OPCODE_DAD=28, OPCODE_INX=29, OPCODE_DCX=30, OPCODE_XCHG=31, OPCODE_XTHL=32, + OPCODE_SPHL=33, OPCODE_LXI=34, OPCODE_MVI=35, OPCODE_ADI=36, OPCODE_ACI=37, + OPCODE_SUI=38, OPCODE_SBI=39, OPCODE_ANI=40, OPCODE_XRI=41, OPCODE_ORI=42, + OPCODE_CPI=43, OPCODE_STA=44, OPCODE_LDA=45, OPCODE_SHLD=46, OPCODE_LHLD=47, + OPCODE_PCHL=48, OPCODE_JMP=49, OPCODE_JC=50, OPCODE_JNC=51, OPCODE_JZ=52, + OPCODE_JNZ=53, OPCODE_JP=54, OPCODE_JM=55, OPCODE_JPE=56, OPCODE_JPO=57, + OPCODE_CALL=58, OPCODE_CC=59, OPCODE_CNC=60, OPCODE_CZ=61, OPCODE_CNZ=62, + OPCODE_CP=63, OPCODE_CM=64, OPCODE_CPE=65, OPCODE_CPO=66, OPCODE_RET=67, + OPCODE_RC=68, OPCODE_RNC=69, OPCODE_RZ=70, OPCODE_RNZ=71, OPCODE_RM=72, + OPCODE_RP=73, OPCODE_RPE=74, OPCODE_RPO=75, OPCODE_RST=76, OPCODE_EI=77, + OPCODE_DI=78, OPCODE_IN=79, OPCODE_OUT=80, OPCODE_HLT=81, PREP_ORG=82, + PREP_EQU=83, PREP_SET=84, PREP_INCLUDE=85, PREP_IF=86, PREP_ENDIF=87, + PREP_MACRO=88, PREP_ENDM=89, PREP_DB=90, PREP_DW=91, PREP_DS=92, PREP_ADDR=93, + REG_A=94, REG_B=95, REG_C=96, REG_D=97, REG_E=98, REG_H=99, REG_L=100, + REG_M=101, REG_PSW=102, REG_SP=103, SEP_LPAR=104, SEP_RPAR=105, SEP_COMMA=106, + OP_ADD=107, OP_SUBTRACT=108, OP_MULTIPLY=109, OP_DIVIDE=110, OP_EQUAL=111, + OP_MOD=112, OP_SHR=113, OP_SHL=114, OP_NOT=115, OP_AND=116, OP_OR=117, + OP_XOR=118, LIT_NUMBER=119, LIT_HEXNUMBER_1=120, LIT_HEXNUMBER_2=121, + LIT_OCTNUMBER=122, LIT_BINNUMBER=123, LIT_STRING_1=124, LIT_STRING_2=125, + ID_IDENTIFIER=126, ID_LABEL=127, ERROR=128; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "WS", "COMMENT", "EOL", "A", "B", "C", "D", "E", "F", "G", "H", "I", + "J", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", + "Z", "OPCODE_STC", "OPCODE_CMC", "OPCODE_INR", "OPCODE_DCR", "OPCODE_CMA", + "OPCODE_DAA", "OPCODE_NOP", "OPCODE_MOV", "OPCODE_STAX", "OPCODE_LDAX", + "OPCODE_ADD", "OPCODE_ADC", "OPCODE_SUB", "OPCODE_SBB", "OPCODE_ANA", + "OPCODE_XRA", "OPCODE_ORA", "OPCODE_CMP", "OPCODE_RLC", "OPCODE_RRC", + "OPCODE_RAL", "OPCODE_RAR", "OPCODE_PUSH", "OPCODE_POP", "OPCODE_DAD", + "OPCODE_INX", "OPCODE_DCX", "OPCODE_XCHG", "OPCODE_XTHL", "OPCODE_SPHL", + "OPCODE_LXI", "OPCODE_MVI", "OPCODE_ADI", "OPCODE_ACI", "OPCODE_SUI", + "OPCODE_SBI", "OPCODE_ANI", "OPCODE_XRI", "OPCODE_ORI", "OPCODE_CPI", + "OPCODE_STA", "OPCODE_LDA", "OPCODE_SHLD", "OPCODE_LHLD", "OPCODE_PCHL", + "OPCODE_JMP", "OPCODE_JC", "OPCODE_JNC", "OPCODE_JZ", "OPCODE_JNZ", "OPCODE_JP", + "OPCODE_JM", "OPCODE_JPE", "OPCODE_JPO", "OPCODE_CALL", "OPCODE_CC", + "OPCODE_CNC", "OPCODE_CZ", "OPCODE_CNZ", "OPCODE_CP", "OPCODE_CM", "OPCODE_CPE", + "OPCODE_CPO", "OPCODE_RET", "OPCODE_RC", "OPCODE_RNC", "OPCODE_RZ", "OPCODE_RNZ", + "OPCODE_RM", "OPCODE_RP", "OPCODE_RPE", "OPCODE_RPO", "OPCODE_RST", "OPCODE_EI", + "OPCODE_DI", "OPCODE_IN", "OPCODE_OUT", "OPCODE_HLT", "PREP_ORG", "PREP_EQU", + "PREP_SET", "PREP_INCLUDE", "PREP_IF", "PREP_ENDIF", "PREP_MACRO", "PREP_ENDM", + "PREP_DB", "PREP_DW", "PREP_DS", "PREP_ADDR", "REG_A", "REG_B", "REG_C", + "REG_D", "REG_E", "REG_H", "REG_L", "REG_M", "REG_PSW", "REG_SP", "SEP_LPAR", + "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE", + "OP_EQUAL", "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", + "OP_XOR", "LIT_NUMBER", "LIT_HEXNUMBER_1", "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", + "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", + "ERROR" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, "'$'", null, null, + null, null, null, null, null, null, null, null, "'('", "')'", "','", + "'+'", "'-'", "'*'", "'/'", "'='" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "WS", "COMMENT", "EOL", "OPCODE_STC", "OPCODE_CMC", "OPCODE_INR", + "OPCODE_DCR", "OPCODE_CMA", "OPCODE_DAA", "OPCODE_NOP", "OPCODE_MOV", + "OPCODE_STAX", "OPCODE_LDAX", "OPCODE_ADD", "OPCODE_ADC", "OPCODE_SUB", + "OPCODE_SBB", "OPCODE_ANA", "OPCODE_XRA", "OPCODE_ORA", "OPCODE_CMP", + "OPCODE_RLC", "OPCODE_RRC", "OPCODE_RAL", "OPCODE_RAR", "OPCODE_PUSH", + "OPCODE_POP", "OPCODE_DAD", "OPCODE_INX", "OPCODE_DCX", "OPCODE_XCHG", + "OPCODE_XTHL", "OPCODE_SPHL", "OPCODE_LXI", "OPCODE_MVI", "OPCODE_ADI", + "OPCODE_ACI", "OPCODE_SUI", "OPCODE_SBI", "OPCODE_ANI", "OPCODE_XRI", + "OPCODE_ORI", "OPCODE_CPI", "OPCODE_STA", "OPCODE_LDA", "OPCODE_SHLD", + "OPCODE_LHLD", "OPCODE_PCHL", "OPCODE_JMP", "OPCODE_JC", "OPCODE_JNC", + "OPCODE_JZ", "OPCODE_JNZ", "OPCODE_JP", "OPCODE_JM", "OPCODE_JPE", "OPCODE_JPO", + "OPCODE_CALL", "OPCODE_CC", "OPCODE_CNC", "OPCODE_CZ", "OPCODE_CNZ", + "OPCODE_CP", "OPCODE_CM", "OPCODE_CPE", "OPCODE_CPO", "OPCODE_RET", "OPCODE_RC", + "OPCODE_RNC", "OPCODE_RZ", "OPCODE_RNZ", "OPCODE_RM", "OPCODE_RP", "OPCODE_RPE", + "OPCODE_RPO", "OPCODE_RST", "OPCODE_EI", "OPCODE_DI", "OPCODE_IN", "OPCODE_OUT", + "OPCODE_HLT", "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_INCLUDE", "PREP_IF", + "PREP_ENDIF", "PREP_MACRO", "PREP_ENDM", "PREP_DB", "PREP_DW", "PREP_DS", + "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", "REG_E", "REG_H", "REG_L", + "REG_M", "REG_PSW", "REG_SP", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", + "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_MOD", "OP_SHR", + "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", "OP_XOR", "LIT_NUMBER", "LIT_HEXNUMBER_1", + "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", "LIT_BINNUMBER", "LIT_STRING_1", + "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", "ERROR" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public As8080Lexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "As8080Lexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u0082\u0377\b\1\4"+ + "\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n"+ + "\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ + "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+ + "\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t"+ + " \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t"+ + "+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64"+ + "\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t"+ + "=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4"+ + "I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\t"+ + "T\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_"+ + "\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k"+ + "\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv"+ + "\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080\t"+ + "\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084"+ + "\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089"+ + "\t\u0089\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c\t\u008c\4\u008d\t\u008d"+ + "\4\u008e\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090\4\u0091\t\u0091\4\u0092"+ + "\t\u0092\4\u0093\t\u0093\4\u0094\t\u0094\4\u0095\t\u0095\4\u0096\t\u0096"+ + "\4\u0097\t\u0097\4\u0098\t\u0098\4\u0099\t\u0099\3\2\3\2\3\2\3\2\3\3\3"+ + "\3\3\3\3\3\3\3\5\3\u013d\n\3\3\3\7\3\u0140\n\3\f\3\16\3\u0143\13\3\3\4"+ + "\5\4\u0146\n\4\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n"+ + "\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3\22"+ + "\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\31"+ + "\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36"+ + "\3\36\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3!\3\"\3\"\3\"\3\"\3#\3"+ + "#\3#\3#\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3(\3"+ + "(\3(\3(\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3+\3+\3,\3,\3,\3,\3-\3-\3-\3-\3"+ + ".\3.\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\61\3\61\3\61\3\61\3\62\3"+ + "\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\65\3\65\3"+ + "\65\3\65\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\38\38\38\38\38\39\39"+ + "\39\39\39\3:\3:\3:\3:\3:\3;\3;\3;\3;\3<\3<\3<\3<\3=\3=\3=\3=\3>\3>\3>"+ + "\3>\3?\3?\3?\3?\3@\3@\3@\3@\3A\3A\3A\3A\3B\3B\3B\3B\3C\3C\3C\3C\3D\3D"+ + "\3D\3D\3E\3E\3E\3E\3F\3F\3F\3F\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3I"+ + "\3I\3I\3J\3J\3J\3J\3K\3K\3K\3L\3L\3L\3L\3M\3M\3M\3N\3N\3N\3N\3O\3O\3O"+ + "\3P\3P\3P\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3S\3S\3S\3S\3S\3T\3T\3T\3U\3U\3U\3U"+ + "\3V\3V\3V\3W\3W\3W\3W\3X\3X\3X\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3\\\3"+ + "\\\3\\\3\\\3]\3]\3]\3^\3^\3^\3^\3_\3_\3_\3`\3`\3`\3`\3a\3a\3a\3b\3b\3"+ + "b\3c\3c\3c\3c\3d\3d\3d\3d\3e\3e\3e\3e\3f\3f\3f\3g\3g\3g\3h\3h\3h\3i\3"+ + "i\3i\3i\3j\3j\3j\3j\3k\3k\3k\3k\3l\3l\3l\3l\3m\3m\3m\3m\3n\3n\3n\3n\3"+ + "n\3n\3n\3n\3o\3o\3o\3p\3p\3p\3p\3p\3p\3q\3q\3q\3q\3q\3q\3r\3r\3r\3r\3"+ + "r\3s\3s\3s\3t\3t\3t\3u\3u\3u\3v\3v\3w\3w\3x\3x\3y\3y\3z\3z\3{\3{\3|\3"+ + "|\3}\3}\3~\3~\3\177\3\177\3\177\3\177\3\u0080\3\u0080\3\u0080\3\u0081"+ + "\3\u0081\3\u0082\3\u0082\3\u0083\3\u0083\3\u0084\3\u0084\3\u0085\3\u0085"+ + "\3\u0086\3\u0086\3\u0087\3\u0087\3\u0088\3\u0088\3\u0089\3\u0089\3\u0089"+ + "\3\u0089\3\u008a\3\u008a\3\u008a\3\u008a\3\u008b\3\u008b\3\u008b\3\u008b"+ + "\3\u008c\3\u008c\3\u008c\3\u008c\3\u008d\3\u008d\3\u008d\3\u008d\3\u008e"+ + "\3\u008e\3\u008e\3\u008f\3\u008f\3\u008f\3\u008f\3\u0090\5\u0090\u0323"+ + "\n\u0090\3\u0090\6\u0090\u0326\n\u0090\r\u0090\16\u0090\u0327\3\u0090"+ + "\5\u0090\u032b\n\u0090\3\u0091\5\u0091\u032e\n\u0091\3\u0091\3\u0091\3"+ + "\u0091\3\u0091\5\u0091\u0334\n\u0091\3\u0091\6\u0091\u0337\n\u0091\r\u0091"+ + "\16\u0091\u0338\3\u0092\5\u0092\u033c\n\u0092\3\u0092\6\u0092\u033f\n"+ + "\u0092\r\u0092\16\u0092\u0340\3\u0092\3\u0092\3\u0093\5\u0093\u0346\n"+ + "\u0093\3\u0093\6\u0093\u0349\n\u0093\r\u0093\16\u0093\u034a\3\u0093\3"+ + "\u0093\3\u0094\6\u0094\u0350\n\u0094\r\u0094\16\u0094\u0351\3\u0094\3"+ + "\u0094\3\u0095\3\u0095\6\u0095\u0358\n\u0095\r\u0095\16\u0095\u0359\3"+ + "\u0095\3\u0095\3\u0096\3\u0096\6\u0096\u0360\n\u0096\r\u0096\16\u0096"+ + "\u0361\3\u0096\3\u0096\3\u0097\3\u0097\7\u0097\u0368\n\u0097\f\u0097\16"+ + "\u0097\u036b\13\u0097\3\u0098\3\u0098\7\u0098\u036f\n\u0098\f\u0098\16"+ + "\u0098\u0372\13\u0098\3\u0098\3\u0098\3\u0099\3\u0099\2\2\u009a\3\3\5"+ + "\4\7\5\t\2\13\2\r\2\17\2\21\2\23\2\25\2\27\2\31\2\33\2\35\2\37\2!\2#\2"+ + "%\2\'\2)\2+\2-\2/\2\61\2\63\2\65\2\67\29\6;\7=\b?\tA\nC\13E\fG\rI\16K"+ + "\17M\20O\21Q\22S\23U\24W\25Y\26[\27]\30_\31a\32c\33e\34g\35i\36k\37m "+ + "o!q\"s#u$w%y&{\'}(\177)\u0081*\u0083+\u0085,\u0087-\u0089.\u008b/\u008d"+ + "\60\u008f\61\u0091\62\u0093\63\u0095\64\u0097\65\u0099\66\u009b\67\u009d"+ + "8\u009f9\u00a1:\u00a3;\u00a5<\u00a7=\u00a9>\u00ab?\u00ad@\u00afA\u00b1"+ + "B\u00b3C\u00b5D\u00b7E\u00b9F\u00bbG\u00bdH\u00bfI\u00c1J\u00c3K\u00c5"+ + "L\u00c7M\u00c9N\u00cbO\u00cdP\u00cfQ\u00d1R\u00d3S\u00d5T\u00d7U\u00d9"+ + "V\u00dbW\u00ddX\u00dfY\u00e1Z\u00e3[\u00e5\\\u00e7]\u00e9^\u00eb_\u00ed"+ + "`\u00efa\u00f1b\u00f3c\u00f5d\u00f7e\u00f9f\u00fbg\u00fdh\u00ffi\u0101"+ + "j\u0103k\u0105l\u0107m\u0109n\u010bo\u010dp\u010fq\u0111r\u0113s\u0115"+ + "t\u0117u\u0119v\u011bw\u011dx\u011fy\u0121z\u0123{\u0125|\u0127}\u0129"+ + "~\u012b\177\u012d\u0080\u012f\u0081\u0131\u0082\3\2(\5\2\13\13\16\16\""+ + "\"\4\2%%==\4\2\f\f\17\17\4\2CCcc\4\2DDdd\4\2EEee\4\2FFff\4\2GGgg\4\2H"+ + "Hhh\4\2IIii\4\2JJjj\4\2KKkk\4\2LLll\4\2NNnn\4\2OOoo\4\2PPpp\4\2QQqq\4"+ + "\2RRrr\4\2SSss\4\2TTtt\4\2UUuu\4\2VVvv\4\2WWww\4\2XXxx\4\2YYyy\4\2ZZz"+ + "z\4\2\\\\||\3\2//\3\2\62;\5\2\62;CHch\3\2\629\6\2QQSSqqss\3\2\62\63\3"+ + "\2))\4\2))``\4\2$$``\5\2A\\aac|\6\2\62;A\\aac|\2\u0371\2\3\3\2\2\2\2\5"+ + "\3\2\2\2\2\7\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3"+ + "\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2"+ + "\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2"+ + "[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3"+ + "\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2"+ + "\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2"+ + "\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089"+ + "\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2"+ + "\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b"+ + "\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2"+ + "\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad"+ + "\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2"+ + "\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf"+ + "\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2"+ + "\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1"+ + "\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2"+ + "\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3"+ + "\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9\3\2\2\2\2\u00eb\3\2\2"+ + "\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1\3\2\2\2\2\u00f3\3\2\2\2\2\u00f5"+ + "\3\2\2\2\2\u00f7\3\2\2\2\2\u00f9\3\2\2\2\2\u00fb\3\2\2\2\2\u00fd\3\2\2"+ + "\2\2\u00ff\3\2\2\2\2\u0101\3\2\2\2\2\u0103\3\2\2\2\2\u0105\3\2\2\2\2\u0107"+ + "\3\2\2\2\2\u0109\3\2\2\2\2\u010b\3\2\2\2\2\u010d\3\2\2\2\2\u010f\3\2\2"+ + "\2\2\u0111\3\2\2\2\2\u0113\3\2\2\2\2\u0115\3\2\2\2\2\u0117\3\2\2\2\2\u0119"+ + "\3\2\2\2\2\u011b\3\2\2\2\2\u011d\3\2\2\2\2\u011f\3\2\2\2\2\u0121\3\2\2"+ + "\2\2\u0123\3\2\2\2\2\u0125\3\2\2\2\2\u0127\3\2\2\2\2\u0129\3\2\2\2\2\u012b"+ + "\3\2\2\2\2\u012d\3\2\2\2\2\u012f\3\2\2\2\2\u0131\3\2\2\2\3\u0133\3\2\2"+ + "\2\5\u013c\3\2\2\2\7\u0145\3\2\2\2\t\u0149\3\2\2\2\13\u014b\3\2\2\2\r"+ + "\u014d\3\2\2\2\17\u014f\3\2\2\2\21\u0151\3\2\2\2\23\u0153\3\2\2\2\25\u0155"+ + "\3\2\2\2\27\u0157\3\2\2\2\31\u0159\3\2\2\2\33\u015b\3\2\2\2\35\u015d\3"+ + "\2\2\2\37\u015f\3\2\2\2!\u0161\3\2\2\2#\u0163\3\2\2\2%\u0165\3\2\2\2\'"+ + "\u0167\3\2\2\2)\u0169\3\2\2\2+\u016b\3\2\2\2-\u016d\3\2\2\2/\u016f\3\2"+ + "\2\2\61\u0171\3\2\2\2\63\u0173\3\2\2\2\65\u0175\3\2\2\2\67\u0177\3\2\2"+ + "\29\u0179\3\2\2\2;\u017d\3\2\2\2=\u0181\3\2\2\2?\u0185\3\2\2\2A\u0189"+ + "\3\2\2\2C\u018d\3\2\2\2E\u0191\3\2\2\2G\u0195\3\2\2\2I\u0199\3\2\2\2K"+ + "\u019e\3\2\2\2M\u01a3\3\2\2\2O\u01a7\3\2\2\2Q\u01ab\3\2\2\2S\u01af\3\2"+ + "\2\2U\u01b3\3\2\2\2W\u01b7\3\2\2\2Y\u01bb\3\2\2\2[\u01bf\3\2\2\2]\u01c3"+ + "\3\2\2\2_\u01c7\3\2\2\2a\u01cb\3\2\2\2c\u01cf\3\2\2\2e\u01d3\3\2\2\2g"+ + "\u01d8\3\2\2\2i\u01dc\3\2\2\2k\u01e0\3\2\2\2m\u01e4\3\2\2\2o\u01e8\3\2"+ + "\2\2q\u01ed\3\2\2\2s\u01f2\3\2\2\2u\u01f7\3\2\2\2w\u01fb\3\2\2\2y\u01ff"+ + "\3\2\2\2{\u0203\3\2\2\2}\u0207\3\2\2\2\177\u020b\3\2\2\2\u0081\u020f\3"+ + "\2\2\2\u0083\u0213\3\2\2\2\u0085\u0217\3\2\2\2\u0087\u021b\3\2\2\2\u0089"+ + "\u021f\3\2\2\2\u008b\u0223\3\2\2\2\u008d\u0227\3\2\2\2\u008f\u022c\3\2"+ + "\2\2\u0091\u0231\3\2\2\2\u0093\u0236\3\2\2\2\u0095\u023a\3\2\2\2\u0097"+ + "\u023d\3\2\2\2\u0099\u0241\3\2\2\2\u009b\u0244\3\2\2\2\u009d\u0248\3\2"+ + "\2\2\u009f\u024b\3\2\2\2\u00a1\u024e\3\2\2\2\u00a3\u0252\3\2\2\2\u00a5"+ + "\u0256\3\2\2\2\u00a7\u025b\3\2\2\2\u00a9\u025e\3\2\2\2\u00ab\u0262\3\2"+ + "\2\2\u00ad\u0265\3\2\2\2\u00af\u0269\3\2\2\2\u00b1\u026c\3\2\2\2\u00b3"+ + "\u026f\3\2\2\2\u00b5\u0273\3\2\2\2\u00b7\u0277\3\2\2\2\u00b9\u027b\3\2"+ + "\2\2\u00bb\u027e\3\2\2\2\u00bd\u0282\3\2\2\2\u00bf\u0285\3\2\2\2\u00c1"+ + "\u0289\3\2\2\2\u00c3\u028c\3\2\2\2\u00c5\u028f\3\2\2\2\u00c7\u0293\3\2"+ + "\2\2\u00c9\u0297\3\2\2\2\u00cb\u029b\3\2\2\2\u00cd\u029e\3\2\2\2\u00cf"+ + "\u02a1\3\2\2\2\u00d1\u02a4\3\2\2\2\u00d3\u02a8\3\2\2\2\u00d5\u02ac\3\2"+ + "\2\2\u00d7\u02b0\3\2\2\2\u00d9\u02b4\3\2\2\2\u00db\u02b8\3\2\2\2\u00dd"+ + "\u02c0\3\2\2\2\u00df\u02c3\3\2\2\2\u00e1\u02c9\3\2\2\2\u00e3\u02cf\3\2"+ + "\2\2\u00e5\u02d4\3\2\2\2\u00e7\u02d7\3\2\2\2\u00e9\u02da\3\2\2\2\u00eb"+ + "\u02dd\3\2\2\2\u00ed\u02df\3\2\2\2\u00ef\u02e1\3\2\2\2\u00f1\u02e3\3\2"+ + "\2\2\u00f3\u02e5\3\2\2\2\u00f5\u02e7\3\2\2\2\u00f7\u02e9\3\2\2\2\u00f9"+ + "\u02eb\3\2\2\2\u00fb\u02ed\3\2\2\2\u00fd\u02ef\3\2\2\2\u00ff\u02f3\3\2"+ + "\2\2\u0101\u02f6\3\2\2\2\u0103\u02f8\3\2\2\2\u0105\u02fa\3\2\2\2\u0107"+ + "\u02fc\3\2\2\2\u0109\u02fe\3\2\2\2\u010b\u0300\3\2\2\2\u010d\u0302\3\2"+ + "\2\2\u010f\u0304\3\2\2\2\u0111\u0306\3\2\2\2\u0113\u030a\3\2\2\2\u0115"+ + "\u030e\3\2\2\2\u0117\u0312\3\2\2\2\u0119\u0316\3\2\2\2\u011b\u031a\3\2"+ + "\2\2\u011d\u031d\3\2\2\2\u011f\u0322\3\2\2\2\u0121\u032d\3\2\2\2\u0123"+ + "\u033b\3\2\2\2\u0125\u0345\3\2\2\2\u0127\u034f\3\2\2\2\u0129\u0355\3\2"+ + "\2\2\u012b\u035d\3\2\2\2\u012d\u0365\3\2\2\2\u012f\u036c\3\2\2\2\u0131"+ + "\u0375\3\2\2\2\u0133\u0134\t\2\2\2\u0134\u0135\3\2\2\2\u0135\u0136\b\2"+ + "\2\2\u0136\4\3\2\2\2\u0137\u0138\7\61\2\2\u0138\u013d\7\61\2\2\u0139\u013a"+ + "\7/\2\2\u013a\u013d\7/\2\2\u013b\u013d\t\3\2\2\u013c\u0137\3\2\2\2\u013c"+ + "\u0139\3\2\2\2\u013c\u013b\3\2\2\2\u013d\u0141\3\2\2\2\u013e\u0140\n\4"+ + "\2\2\u013f\u013e\3\2\2\2\u0140\u0143\3\2\2\2\u0141\u013f\3\2\2\2\u0141"+ + "\u0142\3\2\2\2\u0142\6\3\2\2\2\u0143\u0141\3\2\2\2\u0144\u0146\7\17\2"+ + "\2\u0145\u0144\3\2\2\2\u0145\u0146\3\2\2\2\u0146\u0147\3\2\2\2\u0147\u0148"+ + "\7\f\2\2\u0148\b\3\2\2\2\u0149\u014a\t\5\2\2\u014a\n\3\2\2\2\u014b\u014c"+ + "\t\6\2\2\u014c\f\3\2\2\2\u014d\u014e\t\7\2\2\u014e\16\3\2\2\2\u014f\u0150"+ + "\t\b\2\2\u0150\20\3\2\2\2\u0151\u0152\t\t\2\2\u0152\22\3\2\2\2\u0153\u0154"+ + "\t\n\2\2\u0154\24\3\2\2\2\u0155\u0156\t\13\2\2\u0156\26\3\2\2\2\u0157"+ + "\u0158\t\f\2\2\u0158\30\3\2\2\2\u0159\u015a\t\r\2\2\u015a\32\3\2\2\2\u015b"+ + "\u015c\t\16\2\2\u015c\34\3\2\2\2\u015d\u015e\t\17\2\2\u015e\36\3\2\2\2"+ + "\u015f\u0160\t\20\2\2\u0160 \3\2\2\2\u0161\u0162\t\21\2\2\u0162\"\3\2"+ + "\2\2\u0163\u0164\t\22\2\2\u0164$\3\2\2\2\u0165\u0166\t\23\2\2\u0166&\3"+ + "\2\2\2\u0167\u0168\t\24\2\2\u0168(\3\2\2\2\u0169\u016a\t\25\2\2\u016a"+ + "*\3\2\2\2\u016b\u016c\t\26\2\2\u016c,\3\2\2\2\u016d\u016e\t\27\2\2\u016e"+ + ".\3\2\2\2\u016f\u0170\t\30\2\2\u0170\60\3\2\2\2\u0171\u0172\t\31\2\2\u0172"+ + "\62\3\2\2\2\u0173\u0174\t\32\2\2\u0174\64\3\2\2\2\u0175\u0176\t\33\2\2"+ + "\u0176\66\3\2\2\2\u0177\u0178\t\34\2\2\u01788\3\2\2\2\u0179\u017a\5+\26"+ + "\2\u017a\u017b\5-\27\2\u017b\u017c\5\r\7\2\u017c:\3\2\2\2\u017d\u017e"+ + "\5\r\7\2\u017e\u017f\5\37\20\2\u017f\u0180\5\r\7\2\u0180<\3\2\2\2\u0181"+ + "\u0182\5\31\r\2\u0182\u0183\5!\21\2\u0183\u0184\5)\25\2\u0184>\3\2\2\2"+ + "\u0185\u0186\5\17\b\2\u0186\u0187\5\r\7\2\u0187\u0188\5)\25\2\u0188@\3"+ + "\2\2\2\u0189\u018a\5\r\7\2\u018a\u018b\5\37\20\2\u018b\u018c\5\t\5\2\u018c"+ + "B\3\2\2\2\u018d\u018e\5\17\b\2\u018e\u018f\5\t\5\2\u018f\u0190\5\t\5\2"+ + "\u0190D\3\2\2\2\u0191\u0192\5!\21\2\u0192\u0193\5#\22\2\u0193\u0194\5"+ + "%\23\2\u0194F\3\2\2\2\u0195\u0196\5\37\20\2\u0196\u0197\5#\22\2\u0197"+ + "\u0198\5\61\31\2\u0198H\3\2\2\2\u0199\u019a\5+\26\2\u019a\u019b\5-\27"+ + "\2\u019b\u019c\5\t\5\2\u019c\u019d\5\65\33\2\u019dJ\3\2\2\2\u019e\u019f"+ + "\5\35\17\2\u019f\u01a0\5\17\b\2\u01a0\u01a1\5\t\5\2\u01a1\u01a2\5\65\33"+ + "\2\u01a2L\3\2\2\2\u01a3\u01a4\5\t\5\2\u01a4\u01a5\5\17\b\2\u01a5\u01a6"+ + "\5\17\b\2\u01a6N\3\2\2\2\u01a7\u01a8\5\t\5\2\u01a8\u01a9\5\17\b\2\u01a9"+ + "\u01aa\5\r\7\2\u01aaP\3\2\2\2\u01ab\u01ac\5+\26\2\u01ac\u01ad\5/\30\2"+ + "\u01ad\u01ae\5\13\6\2\u01aeR\3\2\2\2\u01af\u01b0\5+\26\2\u01b0\u01b1\5"+ + "\13\6\2\u01b1\u01b2\5\13\6\2\u01b2T\3\2\2\2\u01b3\u01b4\5\t\5\2\u01b4"+ + "\u01b5\5!\21\2\u01b5\u01b6\5\t\5\2\u01b6V\3\2\2\2\u01b7\u01b8\5\65\33"+ + "\2\u01b8\u01b9\5)\25\2\u01b9\u01ba\5\t\5\2\u01baX\3\2\2\2\u01bb\u01bc"+ + "\5#\22\2\u01bc\u01bd\5)\25\2\u01bd\u01be\5\t\5\2\u01beZ\3\2\2\2\u01bf"+ + "\u01c0\5\r\7\2\u01c0\u01c1\5\37\20\2\u01c1\u01c2\5%\23\2\u01c2\\\3\2\2"+ + "\2\u01c3\u01c4\5)\25\2\u01c4\u01c5\5\35\17\2\u01c5\u01c6\5\r\7\2\u01c6"+ + "^\3\2\2\2\u01c7\u01c8\5)\25\2\u01c8\u01c9\5)\25\2\u01c9\u01ca\5\r\7\2"+ + "\u01ca`\3\2\2\2\u01cb\u01cc\5)\25\2\u01cc\u01cd\5\t\5\2\u01cd\u01ce\5"+ + "\35\17\2\u01ceb\3\2\2\2\u01cf\u01d0\5)\25\2\u01d0\u01d1\5\t\5\2\u01d1"+ + "\u01d2\5)\25\2\u01d2d\3\2\2\2\u01d3\u01d4\5%\23\2\u01d4\u01d5\5/\30\2"+ + "\u01d5\u01d6\5+\26\2\u01d6\u01d7\5\27\f\2\u01d7f\3\2\2\2\u01d8\u01d9\5"+ + "%\23\2\u01d9\u01da\5#\22\2\u01da\u01db\5%\23\2\u01dbh\3\2\2\2\u01dc\u01dd"+ + "\5\17\b\2\u01dd\u01de\5\t\5\2\u01de\u01df\5\17\b\2\u01dfj\3\2\2\2\u01e0"+ + "\u01e1\5\31\r\2\u01e1\u01e2\5!\21\2\u01e2\u01e3\5\65\33\2\u01e3l\3\2\2"+ + "\2\u01e4\u01e5\5\17\b\2\u01e5\u01e6\5\r\7\2\u01e6\u01e7\5\65\33\2\u01e7"+ + "n\3\2\2\2\u01e8\u01e9\5\65\33\2\u01e9\u01ea\5\r\7\2\u01ea\u01eb\5\27\f"+ + "\2\u01eb\u01ec\5\25\13\2\u01ecp\3\2\2\2\u01ed\u01ee\5\65\33\2\u01ee\u01ef"+ + "\5-\27\2\u01ef\u01f0\5\27\f\2\u01f0\u01f1\5\35\17\2\u01f1r\3\2\2\2\u01f2"+ + "\u01f3\5+\26\2\u01f3\u01f4\5%\23\2\u01f4\u01f5\5\27\f\2\u01f5\u01f6\5"+ + "\35\17\2\u01f6t\3\2\2\2\u01f7\u01f8\5\35\17\2\u01f8\u01f9\5\65\33\2\u01f9"+ + "\u01fa\5\31\r\2\u01fav\3\2\2\2\u01fb\u01fc\5\37\20\2\u01fc\u01fd\5\61"+ + "\31\2\u01fd\u01fe\5\31\r\2\u01fex\3\2\2\2\u01ff\u0200\5\t\5\2\u0200\u0201"+ + "\5\17\b\2\u0201\u0202\5\31\r\2\u0202z\3\2\2\2\u0203\u0204\5\t\5\2\u0204"+ + "\u0205\5\r\7\2\u0205\u0206\5\31\r\2\u0206|\3\2\2\2\u0207\u0208\5+\26\2"+ + "\u0208\u0209\5/\30\2\u0209\u020a\5\31\r\2\u020a~\3\2\2\2\u020b\u020c\5"+ + "+\26\2\u020c\u020d\5\13\6\2\u020d\u020e\5\31\r\2\u020e\u0080\3\2\2\2\u020f"+ + "\u0210\5\t\5\2\u0210\u0211\5!\21\2\u0211\u0212\5\31\r\2\u0212\u0082\3"+ + "\2\2\2\u0213\u0214\5\65\33\2\u0214\u0215\5)\25\2\u0215\u0216\5\31\r\2"+ + "\u0216\u0084\3\2\2\2\u0217\u0218\5#\22\2\u0218\u0219\5)\25\2\u0219\u021a"+ + "\5\31\r\2\u021a\u0086\3\2\2\2\u021b\u021c\5\r\7\2\u021c\u021d\5%\23\2"+ + "\u021d\u021e\5\31\r\2\u021e\u0088\3\2\2\2\u021f\u0220\5+\26\2\u0220\u0221"+ + "\5-\27\2\u0221\u0222\5\t\5\2\u0222\u008a\3\2\2\2\u0223\u0224\5\35\17\2"+ + "\u0224\u0225\5\17\b\2\u0225\u0226\5\t\5\2\u0226\u008c\3\2\2\2\u0227\u0228"+ + "\5+\26\2\u0228\u0229\5\27\f\2\u0229\u022a\5\35\17\2\u022a\u022b\5\17\b"+ + "\2\u022b\u008e\3\2\2\2\u022c\u022d\5\35\17\2\u022d\u022e\5\27\f\2\u022e"+ + "\u022f\5\35\17\2\u022f\u0230\5\17\b\2\u0230\u0090\3\2\2\2\u0231\u0232"+ + "\5%\23\2\u0232\u0233\5\r\7\2\u0233\u0234\5\27\f\2\u0234\u0235\5\35\17"+ + "\2\u0235\u0092\3\2\2\2\u0236\u0237\5\33\16\2\u0237\u0238\5\37\20\2\u0238"+ + "\u0239\5%\23\2\u0239\u0094\3\2\2\2\u023a\u023b\5\33\16\2\u023b\u023c\5"+ + "\r\7\2\u023c\u0096\3\2\2\2\u023d\u023e\5\33\16\2\u023e\u023f\5!\21\2\u023f"+ + "\u0240\5\r\7\2\u0240\u0098\3\2\2\2\u0241\u0242\5\33\16\2\u0242\u0243\5"+ + "\67\34\2\u0243\u009a\3\2\2\2\u0244\u0245\5\33\16\2\u0245\u0246\5!\21\2"+ + "\u0246\u0247\5\67\34\2\u0247\u009c\3\2\2\2\u0248\u0249\5\33\16\2\u0249"+ + "\u024a\5%\23\2\u024a\u009e\3\2\2\2\u024b\u024c\5\33\16\2\u024c\u024d\5"+ + "\37\20\2\u024d\u00a0\3\2\2\2\u024e\u024f\5\33\16\2\u024f\u0250\5%\23\2"+ + "\u0250\u0251\5\21\t\2\u0251\u00a2\3\2\2\2\u0252\u0253\5\33\16\2\u0253"+ + "\u0254\5%\23\2\u0254\u0255\5#\22\2\u0255\u00a4\3\2\2\2\u0256\u0257\5\r"+ + "\7\2\u0257\u0258\5\t\5\2\u0258\u0259\5\35\17\2\u0259\u025a\5\35\17\2\u025a"+ + "\u00a6\3\2\2\2\u025b\u025c\5\r\7\2\u025c\u025d\5\r\7\2\u025d\u00a8\3\2"+ + "\2\2\u025e\u025f\5\r\7\2\u025f\u0260\5!\21\2\u0260\u0261\5\r\7\2\u0261"+ + "\u00aa\3\2\2\2\u0262\u0263\5\r\7\2\u0263\u0264\5\67\34\2\u0264\u00ac\3"+ + "\2\2\2\u0265\u0266\5\r\7\2\u0266\u0267\5!\21\2\u0267\u0268\5\67\34\2\u0268"+ + "\u00ae\3\2\2\2\u0269\u026a\5\r\7\2\u026a\u026b\5%\23\2\u026b\u00b0\3\2"+ + "\2\2\u026c\u026d\5\r\7\2\u026d\u026e\5\37\20\2\u026e\u00b2\3\2\2\2\u026f"+ + "\u0270\5\r\7\2\u0270\u0271\5%\23\2\u0271\u0272\5\21\t\2\u0272\u00b4\3"+ + "\2\2\2\u0273\u0274\5\r\7\2\u0274\u0275\5%\23\2\u0275\u0276\5#\22\2\u0276"+ + "\u00b6\3\2\2\2\u0277\u0278\5)\25\2\u0278\u0279\5\21\t\2\u0279\u027a\5"+ + "-\27\2\u027a\u00b8\3\2\2\2\u027b\u027c\5)\25\2\u027c\u027d\5\r\7\2\u027d"+ + "\u00ba\3\2\2\2\u027e\u027f\5)\25\2\u027f\u0280\5!\21\2\u0280\u0281\5\r"+ + "\7\2\u0281\u00bc\3\2\2\2\u0282\u0283\5)\25\2\u0283\u0284\5\67\34\2\u0284"+ + "\u00be\3\2\2\2\u0285\u0286\5)\25\2\u0286\u0287\5!\21\2\u0287\u0288\5\67"+ + "\34\2\u0288\u00c0\3\2\2\2\u0289\u028a\5)\25\2\u028a\u028b\5\37\20\2\u028b"+ + "\u00c2\3\2\2\2\u028c\u028d\5)\25\2\u028d\u028e\5%\23\2\u028e\u00c4\3\2"+ + "\2\2\u028f\u0290\5)\25\2\u0290\u0291\5%\23\2\u0291\u0292\5\21\t\2\u0292"+ + "\u00c6\3\2\2\2\u0293\u0294\5)\25\2\u0294\u0295\5%\23\2\u0295\u0296\5#"+ + "\22\2\u0296\u00c8\3\2\2\2\u0297\u0298\5)\25\2\u0298\u0299\5+\26\2\u0299"+ + "\u029a\5-\27\2\u029a\u00ca\3\2\2\2\u029b\u029c\5\21\t\2\u029c\u029d\5"+ + "\31\r\2\u029d\u00cc\3\2\2\2\u029e\u029f\5\17\b\2\u029f\u02a0\5\31\r\2"+ + "\u02a0\u00ce\3\2\2\2\u02a1\u02a2\5\31\r\2\u02a2\u02a3\5!\21\2\u02a3\u00d0"+ + "\3\2\2\2\u02a4\u02a5\5#\22\2\u02a5\u02a6\5/\30\2\u02a6\u02a7\5-\27\2\u02a7"+ + "\u00d2\3\2\2\2\u02a8\u02a9\5\27\f\2\u02a9\u02aa\5\35\17\2\u02aa\u02ab"+ + "\5-\27\2\u02ab\u00d4\3\2\2\2\u02ac\u02ad\5#\22\2\u02ad\u02ae\5)\25\2\u02ae"+ + "\u02af\5\25\13\2\u02af\u00d6\3\2\2\2\u02b0\u02b1\5\21\t\2\u02b1\u02b2"+ + "\5\'\24\2\u02b2\u02b3\5/\30\2\u02b3\u00d8\3\2\2\2\u02b4\u02b5\5+\26\2"+ + "\u02b5\u02b6\5\21\t\2\u02b6\u02b7\5-\27\2\u02b7\u00da\3\2\2\2\u02b8\u02b9"+ + "\5\31\r\2\u02b9\u02ba\5!\21\2\u02ba\u02bb\5\r\7\2\u02bb\u02bc\5\35\17"+ + "\2\u02bc\u02bd\5/\30\2\u02bd\u02be\5\17\b\2\u02be\u02bf\5\21\t\2\u02bf"+ + "\u00dc\3\2\2\2\u02c0\u02c1\5\31\r\2\u02c1\u02c2\5\23\n\2\u02c2\u00de\3"+ + "\2\2\2\u02c3\u02c4\5\21\t\2\u02c4\u02c5\5!\21\2\u02c5\u02c6\5\17\b\2\u02c6"+ + "\u02c7\5\31\r\2\u02c7\u02c8\5\23\n\2\u02c8\u00e0\3\2\2\2\u02c9\u02ca\5"+ + "\37\20\2\u02ca\u02cb\5\t\5\2\u02cb\u02cc\5\r\7\2\u02cc\u02cd\5)\25\2\u02cd"+ + "\u02ce\5#\22\2\u02ce\u00e2\3\2\2\2\u02cf\u02d0\5\21\t\2\u02d0\u02d1\5"+ + "!\21\2\u02d1\u02d2\5\17\b\2\u02d2\u02d3\5\37\20\2\u02d3\u00e4\3\2\2\2"+ + "\u02d4\u02d5\5\17\b\2\u02d5\u02d6\5\13\6\2\u02d6\u00e6\3\2\2\2\u02d7\u02d8"+ + "\5\17\b\2\u02d8\u02d9\5\63\32\2\u02d9\u00e8\3\2\2\2\u02da\u02db\5\17\b"+ + "\2\u02db\u02dc\5+\26\2\u02dc\u00ea\3\2\2\2\u02dd\u02de\7&\2\2\u02de\u00ec"+ + "\3\2\2\2\u02df\u02e0\5\t\5\2\u02e0\u00ee\3\2\2\2\u02e1\u02e2\5\13\6\2"+ + "\u02e2\u00f0\3\2\2\2\u02e3\u02e4\5\r\7\2\u02e4\u00f2\3\2\2\2\u02e5\u02e6"+ + "\5\17\b\2\u02e6\u00f4\3\2\2\2\u02e7\u02e8\5\21\t\2\u02e8\u00f6\3\2\2\2"+ + "\u02e9\u02ea\5\27\f\2\u02ea\u00f8\3\2\2\2\u02eb\u02ec\5\35\17\2\u02ec"+ + "\u00fa\3\2\2\2\u02ed\u02ee\5\37\20\2\u02ee\u00fc\3\2\2\2\u02ef\u02f0\5"+ + "%\23\2\u02f0\u02f1\5+\26\2\u02f1\u02f2\5\63\32\2\u02f2\u00fe\3\2\2\2\u02f3"+ + "\u02f4\5+\26\2\u02f4\u02f5\5%\23\2\u02f5\u0100\3\2\2\2\u02f6\u02f7\7*"+ + "\2\2\u02f7\u0102\3\2\2\2\u02f8\u02f9\7+\2\2\u02f9\u0104\3\2\2\2\u02fa"+ + "\u02fb\7.\2\2\u02fb\u0106\3\2\2\2\u02fc\u02fd\7-\2\2\u02fd\u0108\3\2\2"+ + "\2\u02fe\u02ff\7/\2\2\u02ff\u010a\3\2\2\2\u0300\u0301\7,\2\2\u0301\u010c"+ + "\3\2\2\2\u0302\u0303\7\61\2\2\u0303\u010e\3\2\2\2\u0304\u0305\7?\2\2\u0305"+ + "\u0110\3\2\2\2\u0306\u0307\5\37\20\2\u0307\u0308\5#\22\2\u0308\u0309\5"+ + "\17\b\2\u0309\u0112\3\2\2\2\u030a\u030b\5+\26\2\u030b\u030c\5\27\f\2\u030c"+ + "\u030d\5)\25\2\u030d\u0114\3\2\2\2\u030e\u030f\5+\26\2\u030f\u0310\5\27"+ + "\f\2\u0310\u0311\5\35\17\2\u0311\u0116\3\2\2\2\u0312\u0313\5!\21\2\u0313"+ + "\u0314\5#\22\2\u0314\u0315\5-\27\2\u0315\u0118\3\2\2\2\u0316\u0317\5\t"+ + "\5\2\u0317\u0318\5!\21\2\u0318\u0319\5\17\b\2\u0319\u011a\3\2\2\2\u031a"+ + "\u031b\5#\22\2\u031b\u031c\5)\25\2\u031c\u011c\3\2\2\2\u031d\u031e\5\65"+ + "\33\2\u031e\u031f\5#\22\2\u031f\u0320\5)\25\2\u0320\u011e\3\2\2\2\u0321"+ + "\u0323\t\35\2\2\u0322\u0321\3\2\2\2\u0322\u0323\3\2\2\2\u0323\u0325\3"+ + "\2\2\2\u0324\u0326\t\36\2\2\u0325\u0324\3\2\2\2\u0326\u0327\3\2\2\2\u0327"+ + "\u0325\3\2\2\2\u0327\u0328\3\2\2\2\u0328\u032a\3\2\2\2\u0329\u032b\5\17"+ + "\b\2\u032a\u0329\3\2\2\2\u032a\u032b\3\2\2\2\u032b\u0120\3\2\2\2\u032c"+ + "\u032e\t\35\2\2\u032d\u032c\3\2\2\2\u032d\u032e\3\2\2\2\u032e\u0333\3"+ + "\2\2\2\u032f\u0330\7\62\2\2\u0330\u0334\7z\2\2\u0331\u0332\7\62\2\2\u0332"+ + "\u0334\7Z\2\2\u0333\u032f\3\2\2\2\u0333\u0331\3\2\2\2\u0334\u0336\3\2"+ + "\2\2\u0335\u0337\t\37\2\2\u0336\u0335\3\2\2\2\u0337\u0338\3\2\2\2\u0338"+ + "\u0336\3\2\2\2\u0338\u0339\3\2\2\2\u0339\u0122\3\2\2\2\u033a\u033c\t\35"+ + "\2\2\u033b\u033a\3\2\2\2\u033b\u033c\3\2\2\2\u033c\u033e\3\2\2\2\u033d"+ + "\u033f\t\37\2\2\u033e\u033d\3\2\2\2\u033f\u0340\3\2\2\2\u0340\u033e\3"+ + "\2\2\2\u0340\u0341\3\2\2\2\u0341\u0342\3\2\2\2\u0342\u0343\5\27\f\2\u0343"+ + "\u0124\3\2\2\2\u0344\u0346\t\35\2\2\u0345\u0344\3\2\2\2\u0345\u0346\3"+ + "\2\2\2\u0346\u0348\3\2\2\2\u0347\u0349\t \2\2\u0348\u0347\3\2\2\2\u0349"+ + "\u034a\3\2\2\2\u034a\u0348\3\2\2\2\u034a\u034b\3\2\2\2\u034b\u034c\3\2"+ + "\2\2\u034c\u034d\t!\2\2\u034d\u0126\3\2\2\2\u034e\u0350\t\"\2\2\u034f"+ + "\u034e\3\2\2\2\u0350\u0351\3\2\2\2\u0351\u034f\3\2\2\2\u0351\u0352\3\2"+ + "\2\2\u0352\u0353\3\2\2\2\u0353\u0354\5\13\6\2\u0354\u0128\3\2\2\2\u0355"+ + "\u0357\t#\2\2\u0356\u0358\t$\2\2\u0357\u0356\3\2\2\2\u0358\u0359\3\2\2"+ + "\2\u0359\u0357\3\2\2\2\u0359\u035a\3\2\2\2\u035a\u035b\3\2\2\2\u035b\u035c"+ + "\t#\2\2\u035c\u012a\3\2\2\2\u035d\u035f\7$\2\2\u035e\u0360\t%\2\2\u035f"+ + "\u035e\3\2\2\2\u0360\u0361\3\2\2\2\u0361\u035f\3\2\2\2\u0361\u0362\3\2"+ + "\2\2\u0362\u0363\3\2\2\2\u0363\u0364\7$\2\2\u0364\u012c\3\2\2\2\u0365"+ + "\u0369\t&\2\2\u0366\u0368\t\'\2\2\u0367\u0366\3\2\2\2\u0368\u036b\3\2"+ + "\2\2\u0369\u0367\3\2\2\2\u0369\u036a\3\2\2\2\u036a\u012e\3\2\2\2\u036b"+ + "\u0369\3\2\2\2\u036c\u0370\t&\2\2\u036d\u036f\t\'\2\2\u036e\u036d\3\2"+ + "\2\2\u036f\u0372\3\2\2\2\u0370\u036e\3\2\2\2\u0370\u0371\3\2\2\2\u0371"+ + "\u0373\3\2\2\2\u0372\u0370\3\2\2\2\u0373\u0374\7<\2\2\u0374\u0130\3\2"+ + "\2\2\u0375\u0376\13\2\2\2\u0376\u0132\3\2\2\2\25\2\u013c\u0141\u0145\u0322"+ + "\u0327\u032a\u032d\u0333\u0338\u033b\u0340\u0345\u034a\u0351\u0359\u0361"+ + "\u0369\u0370\3\2\3\2"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.tokens b/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.tokens new file mode 100644 index 000000000..a522a3c4c --- /dev/null +++ b/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.tokens @@ -0,0 +1,137 @@ +WS=1 +COMMENT=2 +EOL=3 +OPCODE_STC=4 +OPCODE_CMC=5 +OPCODE_INR=6 +OPCODE_DCR=7 +OPCODE_CMA=8 +OPCODE_DAA=9 +OPCODE_NOP=10 +OPCODE_MOV=11 +OPCODE_STAX=12 +OPCODE_LDAX=13 +OPCODE_ADD=14 +OPCODE_ADC=15 +OPCODE_SUB=16 +OPCODE_SBB=17 +OPCODE_ANA=18 +OPCODE_XRA=19 +OPCODE_ORA=20 +OPCODE_CMP=21 +OPCODE_RLC=22 +OPCODE_RRC=23 +OPCODE_RAL=24 +OPCODE_RAR=25 +OPCODE_PUSH=26 +OPCODE_POP=27 +OPCODE_DAD=28 +OPCODE_INX=29 +OPCODE_DCX=30 +OPCODE_XCHG=31 +OPCODE_XTHL=32 +OPCODE_SPHL=33 +OPCODE_LXI=34 +OPCODE_MVI=35 +OPCODE_ADI=36 +OPCODE_ACI=37 +OPCODE_SUI=38 +OPCODE_SBI=39 +OPCODE_ANI=40 +OPCODE_XRI=41 +OPCODE_ORI=42 +OPCODE_CPI=43 +OPCODE_STA=44 +OPCODE_LDA=45 +OPCODE_SHLD=46 +OPCODE_LHLD=47 +OPCODE_PCHL=48 +OPCODE_JMP=49 +OPCODE_JC=50 +OPCODE_JNC=51 +OPCODE_JZ=52 +OPCODE_JNZ=53 +OPCODE_JP=54 +OPCODE_JM=55 +OPCODE_JPE=56 +OPCODE_JPO=57 +OPCODE_CALL=58 +OPCODE_CC=59 +OPCODE_CNC=60 +OPCODE_CZ=61 +OPCODE_CNZ=62 +OPCODE_CP=63 +OPCODE_CM=64 +OPCODE_CPE=65 +OPCODE_CPO=66 +OPCODE_RET=67 +OPCODE_RC=68 +OPCODE_RNC=69 +OPCODE_RZ=70 +OPCODE_RNZ=71 +OPCODE_RM=72 +OPCODE_RP=73 +OPCODE_RPE=74 +OPCODE_RPO=75 +OPCODE_RST=76 +OPCODE_EI=77 +OPCODE_DI=78 +OPCODE_IN=79 +OPCODE_OUT=80 +OPCODE_HLT=81 +PREP_ORG=82 +PREP_EQU=83 +PREP_SET=84 +PREP_INCLUDE=85 +PREP_IF=86 +PREP_ENDIF=87 +PREP_MACRO=88 +PREP_ENDM=89 +PREP_DB=90 +PREP_DW=91 +PREP_DS=92 +PREP_ADDR=93 +REG_A=94 +REG_B=95 +REG_C=96 +REG_D=97 +REG_E=98 +REG_H=99 +REG_L=100 +REG_M=101 +REG_PSW=102 +REG_SP=103 +SEP_LPAR=104 +SEP_RPAR=105 +SEP_COMMA=106 +OP_ADD=107 +OP_SUBTRACT=108 +OP_MULTIPLY=109 +OP_DIVIDE=110 +OP_EQUAL=111 +OP_MOD=112 +OP_SHR=113 +OP_SHL=114 +OP_NOT=115 +OP_AND=116 +OP_OR=117 +OP_XOR=118 +LIT_NUMBER=119 +LIT_HEXNUMBER_1=120 +LIT_HEXNUMBER_2=121 +LIT_OCTNUMBER=122 +LIT_BINNUMBER=123 +LIT_STRING_1=124 +LIT_STRING_2=125 +ID_IDENTIFIER=126 +ID_LABEL=127 +ERROR=128 +'$'=93 +'('=104 +')'=105 +','=106 +'+'=107 +'-'=108 +'*'=109 +'/'=110 +'='=111 diff --git a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp new file mode 100644 index 000000000..ad3f351ce --- /dev/null +++ b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp @@ -0,0 +1,425 @@ +token literal names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'$' +null +null +null +null +null +null +null +null +null +null +'(' +')' +',' +'+' +'-' +'*' +'/' +'=' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +WS +COMMENT +EOL +OPCODE_STC +OPCODE_CMC +OPCODE_INR +OPCODE_DCR +OPCODE_CMA +OPCODE_DAA +OPCODE_NOP +OPCODE_MOV +OPCODE_STAX +OPCODE_LDAX +OPCODE_ADD +OPCODE_ADC +OPCODE_SUB +OPCODE_SBB +OPCODE_ANA +OPCODE_XRA +OPCODE_ORA +OPCODE_CMP +OPCODE_RLC +OPCODE_RRC +OPCODE_RAL +OPCODE_RAR +OPCODE_PUSH +OPCODE_POP +OPCODE_DAD +OPCODE_INX +OPCODE_DCX +OPCODE_XCHG +OPCODE_XTHL +OPCODE_SPHL +OPCODE_LXI +OPCODE_MVI +OPCODE_ADI +OPCODE_ACI +OPCODE_SUI +OPCODE_SBI +OPCODE_ANI +OPCODE_XRI +OPCODE_ORI +OPCODE_CPI +OPCODE_STA +OPCODE_LDA +OPCODE_SHLD +OPCODE_LHLD +OPCODE_PCHL +OPCODE_JMP +OPCODE_JC +OPCODE_JNC +OPCODE_JZ +OPCODE_JNZ +OPCODE_JP +OPCODE_JM +OPCODE_JPE +OPCODE_JPO +OPCODE_CALL +OPCODE_CC +OPCODE_CNC +OPCODE_CZ +OPCODE_CNZ +OPCODE_CP +OPCODE_CM +OPCODE_CPE +OPCODE_CPO +OPCODE_RET +OPCODE_RC +OPCODE_RNC +OPCODE_RZ +OPCODE_RNZ +OPCODE_RM +OPCODE_RP +OPCODE_RPE +OPCODE_RPO +OPCODE_RST +OPCODE_EI +OPCODE_DI +OPCODE_IN +OPCODE_OUT +OPCODE_HLT +PREP_ORG +PREP_EQU +PREP_SET +PREP_INCLUDE +PREP_IF +PREP_ENDIF +PREP_MACRO +PREP_ENDM +PREP_DB +PREP_DW +PREP_DS +PREP_ADDR +REG_A +REG_B +REG_C +REG_D +REG_E +REG_H +REG_L +REG_M +REG_PSW +REG_SP +SEP_LPAR +SEP_RPAR +SEP_COMMA +OP_ADD +OP_SUBTRACT +OP_MULTIPLY +OP_DIVIDE +OP_EQUAL +OP_MOD +OP_SHR +OP_SHL +OP_NOT +OP_AND +OP_OR +OP_XOR +LIT_NUMBER +LIT_HEXNUMBER_1 +LIT_HEXNUMBER_2 +LIT_OCTNUMBER +LIT_BINNUMBER +LIT_STRING_1 +LIT_STRING_2 +ID_IDENTIFIER +ID_LABEL +ERROR + +rule names: +WS +COMMENT +EOL +A +B +C +D +E +F +G +H +I +J +L +M +N +O +P +Q +R +S +T +U +V +W +X +Z +OPCODE_STC +OPCODE_CMC +OPCODE_INR +OPCODE_DCR +OPCODE_CMA +OPCODE_DAA +OPCODE_NOP +OPCODE_MOV +OPCODE_STAX +OPCODE_LDAX +OPCODE_ADD +OPCODE_ADC +OPCODE_SUB +OPCODE_SBB +OPCODE_ANA +OPCODE_XRA +OPCODE_ORA +OPCODE_CMP +OPCODE_RLC +OPCODE_RRC +OPCODE_RAL +OPCODE_RAR +OPCODE_PUSH +OPCODE_POP +OPCODE_DAD +OPCODE_INX +OPCODE_DCX +OPCODE_XCHG +OPCODE_XTHL +OPCODE_SPHL +OPCODE_LXI +OPCODE_MVI +OPCODE_ADI +OPCODE_ACI +OPCODE_SUI +OPCODE_SBI +OPCODE_ANI +OPCODE_XRI +OPCODE_ORI +OPCODE_CPI +OPCODE_STA +OPCODE_LDA +OPCODE_SHLD +OPCODE_LHLD +OPCODE_PCHL +OPCODE_JMP +OPCODE_JC +OPCODE_JNC +OPCODE_JZ +OPCODE_JNZ +OPCODE_JP +OPCODE_JM +OPCODE_JPE +OPCODE_JPO +OPCODE_CALL +OPCODE_CC +OPCODE_CNC +OPCODE_CZ +OPCODE_CNZ +OPCODE_CP +OPCODE_CM +OPCODE_CPE +OPCODE_CPO +OPCODE_RET +OPCODE_RC +OPCODE_RNC +OPCODE_RZ +OPCODE_RNZ +OPCODE_RM +OPCODE_RP +OPCODE_RPE +OPCODE_RPO +OPCODE_RST +OPCODE_EI +OPCODE_DI +OPCODE_IN +OPCODE_OUT +OPCODE_HLT +PREP_ORG +PREP_EQU +PREP_SET +PREP_INCLUDE +PREP_IF +PREP_ENDIF +PREP_MACRO +PREP_ENDM +PREP_DB +PREP_DW +PREP_DS +PREP_ADDR +REG_A +REG_B +REG_C +REG_D +REG_E +REG_H +REG_L +REG_M +REG_PSW +REG_SP +SEP_LPAR +SEP_RPAR +SEP_COMMA +OP_ADD +OP_SUBTRACT +OP_MULTIPLY +OP_DIVIDE +OP_EQUAL +OP_MOD +OP_SHR +OP_SHL +OP_NOT +OP_AND +OP_OR +OP_XOR +LIT_NUMBER +LIT_HEXNUMBER_1 +LIT_HEXNUMBER_2 +LIT_OCTNUMBER +LIT_BINNUMBER +LIT_STRING_1 +LIT_STRING_2 +ID_IDENTIFIER +ID_LABEL +ERROR + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 130, 887, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 317, 10, 3, 3, 3, 7, 3, 320, 10, 3, 12, 3, 14, 3, 323, 11, 3, 3, 4, 5, 4, 326, 10, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 105, 3, 105, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 130, 3, 130, 3, 131, 3, 131, 3, 132, 3, 132, 3, 133, 3, 133, 3, 134, 3, 134, 3, 135, 3, 135, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 138, 3, 138, 3, 139, 3, 139, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 5, 144, 803, 10, 144, 3, 144, 6, 144, 806, 10, 144, 13, 144, 14, 144, 807, 3, 144, 5, 144, 811, 10, 144, 3, 145, 5, 145, 814, 10, 145, 3, 145, 3, 145, 3, 145, 3, 145, 5, 145, 820, 10, 145, 3, 145, 6, 145, 823, 10, 145, 13, 145, 14, 145, 824, 3, 146, 5, 146, 828, 10, 146, 3, 146, 6, 146, 831, 10, 146, 13, 146, 14, 146, 832, 3, 146, 3, 146, 3, 147, 5, 147, 838, 10, 147, 3, 147, 6, 147, 841, 10, 147, 13, 147, 14, 147, 842, 3, 147, 3, 147, 3, 148, 6, 148, 848, 10, 148, 13, 148, 14, 148, 849, 3, 148, 3, 148, 3, 149, 3, 149, 6, 149, 856, 10, 149, 13, 149, 14, 149, 857, 3, 149, 3, 149, 3, 150, 3, 150, 6, 150, 864, 10, 150, 13, 150, 14, 150, 865, 3, 150, 3, 150, 3, 151, 3, 151, 7, 151, 872, 10, 151, 12, 151, 14, 151, 875, 11, 151, 3, 152, 3, 152, 7, 152, 879, 10, 152, 12, 152, 14, 152, 882, 11, 152, 3, 152, 3, 152, 3, 153, 3, 153, 2, 2, 154, 3, 3, 5, 4, 7, 5, 9, 2, 11, 2, 13, 2, 15, 2, 17, 2, 19, 2, 21, 2, 23, 2, 25, 2, 27, 2, 29, 2, 31, 2, 33, 2, 35, 2, 37, 2, 39, 2, 41, 2, 43, 2, 45, 2, 47, 2, 49, 2, 51, 2, 53, 2, 55, 2, 57, 6, 59, 7, 61, 8, 63, 9, 65, 10, 67, 11, 69, 12, 71, 13, 73, 14, 75, 15, 77, 16, 79, 17, 81, 18, 83, 19, 85, 20, 87, 21, 89, 22, 91, 23, 93, 24, 95, 25, 97, 26, 99, 27, 101, 28, 103, 29, 105, 30, 107, 31, 109, 32, 111, 33, 113, 34, 115, 35, 117, 36, 119, 37, 121, 38, 123, 39, 125, 40, 127, 41, 129, 42, 131, 43, 133, 44, 135, 45, 137, 46, 139, 47, 141, 48, 143, 49, 145, 50, 147, 51, 149, 52, 151, 53, 153, 54, 155, 55, 157, 56, 159, 57, 161, 58, 163, 59, 165, 60, 167, 61, 169, 62, 171, 63, 173, 64, 175, 65, 177, 66, 179, 67, 181, 68, 183, 69, 185, 70, 187, 71, 189, 72, 191, 73, 193, 74, 195, 75, 197, 76, 199, 77, 201, 78, 203, 79, 205, 80, 207, 81, 209, 82, 211, 83, 213, 84, 215, 85, 217, 86, 219, 87, 221, 88, 223, 89, 225, 90, 227, 91, 229, 92, 231, 93, 233, 94, 235, 95, 237, 96, 239, 97, 241, 98, 243, 99, 245, 100, 247, 101, 249, 102, 251, 103, 253, 104, 255, 105, 257, 106, 259, 107, 261, 108, 263, 109, 265, 110, 267, 111, 269, 112, 271, 113, 273, 114, 275, 115, 277, 116, 279, 117, 281, 118, 283, 119, 285, 120, 287, 121, 289, 122, 291, 123, 293, 124, 295, 125, 297, 126, 299, 127, 301, 128, 303, 129, 305, 130, 3, 2, 40, 5, 2, 11, 11, 14, 14, 34, 34, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 92, 92, 124, 124, 3, 2, 47, 47, 3, 2, 50, 59, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 4, 2, 41, 41, 96, 96, 4, 2, 36, 36, 96, 96, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 2, 881, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 157, 3, 2, 2, 2, 2, 159, 3, 2, 2, 2, 2, 161, 3, 2, 2, 2, 2, 163, 3, 2, 2, 2, 2, 165, 3, 2, 2, 2, 2, 167, 3, 2, 2, 2, 2, 169, 3, 2, 2, 2, 2, 171, 3, 2, 2, 2, 2, 173, 3, 2, 2, 2, 2, 175, 3, 2, 2, 2, 2, 177, 3, 2, 2, 2, 2, 179, 3, 2, 2, 2, 2, 181, 3, 2, 2, 2, 2, 183, 3, 2, 2, 2, 2, 185, 3, 2, 2, 2, 2, 187, 3, 2, 2, 2, 2, 189, 3, 2, 2, 2, 2, 191, 3, 2, 2, 2, 2, 193, 3, 2, 2, 2, 2, 195, 3, 2, 2, 2, 2, 197, 3, 2, 2, 2, 2, 199, 3, 2, 2, 2, 2, 201, 3, 2, 2, 2, 2, 203, 3, 2, 2, 2, 2, 205, 3, 2, 2, 2, 2, 207, 3, 2, 2, 2, 2, 209, 3, 2, 2, 2, 2, 211, 3, 2, 2, 2, 2, 213, 3, 2, 2, 2, 2, 215, 3, 2, 2, 2, 2, 217, 3, 2, 2, 2, 2, 219, 3, 2, 2, 2, 2, 221, 3, 2, 2, 2, 2, 223, 3, 2, 2, 2, 2, 225, 3, 2, 2, 2, 2, 227, 3, 2, 2, 2, 2, 229, 3, 2, 2, 2, 2, 231, 3, 2, 2, 2, 2, 233, 3, 2, 2, 2, 2, 235, 3, 2, 2, 2, 2, 237, 3, 2, 2, 2, 2, 239, 3, 2, 2, 2, 2, 241, 3, 2, 2, 2, 2, 243, 3, 2, 2, 2, 2, 245, 3, 2, 2, 2, 2, 247, 3, 2, 2, 2, 2, 249, 3, 2, 2, 2, 2, 251, 3, 2, 2, 2, 2, 253, 3, 2, 2, 2, 2, 255, 3, 2, 2, 2, 2, 257, 3, 2, 2, 2, 2, 259, 3, 2, 2, 2, 2, 261, 3, 2, 2, 2, 2, 263, 3, 2, 2, 2, 2, 265, 3, 2, 2, 2, 2, 267, 3, 2, 2, 2, 2, 269, 3, 2, 2, 2, 2, 271, 3, 2, 2, 2, 2, 273, 3, 2, 2, 2, 2, 275, 3, 2, 2, 2, 2, 277, 3, 2, 2, 2, 2, 279, 3, 2, 2, 2, 2, 281, 3, 2, 2, 2, 2, 283, 3, 2, 2, 2, 2, 285, 3, 2, 2, 2, 2, 287, 3, 2, 2, 2, 2, 289, 3, 2, 2, 2, 2, 291, 3, 2, 2, 2, 2, 293, 3, 2, 2, 2, 2, 295, 3, 2, 2, 2, 2, 297, 3, 2, 2, 2, 2, 299, 3, 2, 2, 2, 2, 301, 3, 2, 2, 2, 2, 303, 3, 2, 2, 2, 2, 305, 3, 2, 2, 2, 3, 307, 3, 2, 2, 2, 5, 316, 3, 2, 2, 2, 7, 325, 3, 2, 2, 2, 9, 329, 3, 2, 2, 2, 11, 331, 3, 2, 2, 2, 13, 333, 3, 2, 2, 2, 15, 335, 3, 2, 2, 2, 17, 337, 3, 2, 2, 2, 19, 339, 3, 2, 2, 2, 21, 341, 3, 2, 2, 2, 23, 343, 3, 2, 2, 2, 25, 345, 3, 2, 2, 2, 27, 347, 3, 2, 2, 2, 29, 349, 3, 2, 2, 2, 31, 351, 3, 2, 2, 2, 33, 353, 3, 2, 2, 2, 35, 355, 3, 2, 2, 2, 37, 357, 3, 2, 2, 2, 39, 359, 3, 2, 2, 2, 41, 361, 3, 2, 2, 2, 43, 363, 3, 2, 2, 2, 45, 365, 3, 2, 2, 2, 47, 367, 3, 2, 2, 2, 49, 369, 3, 2, 2, 2, 51, 371, 3, 2, 2, 2, 53, 373, 3, 2, 2, 2, 55, 375, 3, 2, 2, 2, 57, 377, 3, 2, 2, 2, 59, 381, 3, 2, 2, 2, 61, 385, 3, 2, 2, 2, 63, 389, 3, 2, 2, 2, 65, 393, 3, 2, 2, 2, 67, 397, 3, 2, 2, 2, 69, 401, 3, 2, 2, 2, 71, 405, 3, 2, 2, 2, 73, 409, 3, 2, 2, 2, 75, 414, 3, 2, 2, 2, 77, 419, 3, 2, 2, 2, 79, 423, 3, 2, 2, 2, 81, 427, 3, 2, 2, 2, 83, 431, 3, 2, 2, 2, 85, 435, 3, 2, 2, 2, 87, 439, 3, 2, 2, 2, 89, 443, 3, 2, 2, 2, 91, 447, 3, 2, 2, 2, 93, 451, 3, 2, 2, 2, 95, 455, 3, 2, 2, 2, 97, 459, 3, 2, 2, 2, 99, 463, 3, 2, 2, 2, 101, 467, 3, 2, 2, 2, 103, 472, 3, 2, 2, 2, 105, 476, 3, 2, 2, 2, 107, 480, 3, 2, 2, 2, 109, 484, 3, 2, 2, 2, 111, 488, 3, 2, 2, 2, 113, 493, 3, 2, 2, 2, 115, 498, 3, 2, 2, 2, 117, 503, 3, 2, 2, 2, 119, 507, 3, 2, 2, 2, 121, 511, 3, 2, 2, 2, 123, 515, 3, 2, 2, 2, 125, 519, 3, 2, 2, 2, 127, 523, 3, 2, 2, 2, 129, 527, 3, 2, 2, 2, 131, 531, 3, 2, 2, 2, 133, 535, 3, 2, 2, 2, 135, 539, 3, 2, 2, 2, 137, 543, 3, 2, 2, 2, 139, 547, 3, 2, 2, 2, 141, 551, 3, 2, 2, 2, 143, 556, 3, 2, 2, 2, 145, 561, 3, 2, 2, 2, 147, 566, 3, 2, 2, 2, 149, 570, 3, 2, 2, 2, 151, 573, 3, 2, 2, 2, 153, 577, 3, 2, 2, 2, 155, 580, 3, 2, 2, 2, 157, 584, 3, 2, 2, 2, 159, 587, 3, 2, 2, 2, 161, 590, 3, 2, 2, 2, 163, 594, 3, 2, 2, 2, 165, 598, 3, 2, 2, 2, 167, 603, 3, 2, 2, 2, 169, 606, 3, 2, 2, 2, 171, 610, 3, 2, 2, 2, 173, 613, 3, 2, 2, 2, 175, 617, 3, 2, 2, 2, 177, 620, 3, 2, 2, 2, 179, 623, 3, 2, 2, 2, 181, 627, 3, 2, 2, 2, 183, 631, 3, 2, 2, 2, 185, 635, 3, 2, 2, 2, 187, 638, 3, 2, 2, 2, 189, 642, 3, 2, 2, 2, 191, 645, 3, 2, 2, 2, 193, 649, 3, 2, 2, 2, 195, 652, 3, 2, 2, 2, 197, 655, 3, 2, 2, 2, 199, 659, 3, 2, 2, 2, 201, 663, 3, 2, 2, 2, 203, 667, 3, 2, 2, 2, 205, 670, 3, 2, 2, 2, 207, 673, 3, 2, 2, 2, 209, 676, 3, 2, 2, 2, 211, 680, 3, 2, 2, 2, 213, 684, 3, 2, 2, 2, 215, 688, 3, 2, 2, 2, 217, 692, 3, 2, 2, 2, 219, 696, 3, 2, 2, 2, 221, 704, 3, 2, 2, 2, 223, 707, 3, 2, 2, 2, 225, 713, 3, 2, 2, 2, 227, 719, 3, 2, 2, 2, 229, 724, 3, 2, 2, 2, 231, 727, 3, 2, 2, 2, 233, 730, 3, 2, 2, 2, 235, 733, 3, 2, 2, 2, 237, 735, 3, 2, 2, 2, 239, 737, 3, 2, 2, 2, 241, 739, 3, 2, 2, 2, 243, 741, 3, 2, 2, 2, 245, 743, 3, 2, 2, 2, 247, 745, 3, 2, 2, 2, 249, 747, 3, 2, 2, 2, 251, 749, 3, 2, 2, 2, 253, 751, 3, 2, 2, 2, 255, 755, 3, 2, 2, 2, 257, 758, 3, 2, 2, 2, 259, 760, 3, 2, 2, 2, 261, 762, 3, 2, 2, 2, 263, 764, 3, 2, 2, 2, 265, 766, 3, 2, 2, 2, 267, 768, 3, 2, 2, 2, 269, 770, 3, 2, 2, 2, 271, 772, 3, 2, 2, 2, 273, 774, 3, 2, 2, 2, 275, 778, 3, 2, 2, 2, 277, 782, 3, 2, 2, 2, 279, 786, 3, 2, 2, 2, 281, 790, 3, 2, 2, 2, 283, 794, 3, 2, 2, 2, 285, 797, 3, 2, 2, 2, 287, 802, 3, 2, 2, 2, 289, 813, 3, 2, 2, 2, 291, 827, 3, 2, 2, 2, 293, 837, 3, 2, 2, 2, 295, 847, 3, 2, 2, 2, 297, 853, 3, 2, 2, 2, 299, 861, 3, 2, 2, 2, 301, 869, 3, 2, 2, 2, 303, 876, 3, 2, 2, 2, 305, 885, 3, 2, 2, 2, 307, 308, 9, 2, 2, 2, 308, 309, 3, 2, 2, 2, 309, 310, 8, 2, 2, 2, 310, 4, 3, 2, 2, 2, 311, 312, 7, 49, 2, 2, 312, 317, 7, 49, 2, 2, 313, 314, 7, 47, 2, 2, 314, 317, 7, 47, 2, 2, 315, 317, 9, 3, 2, 2, 316, 311, 3, 2, 2, 2, 316, 313, 3, 2, 2, 2, 316, 315, 3, 2, 2, 2, 317, 321, 3, 2, 2, 2, 318, 320, 10, 4, 2, 2, 319, 318, 3, 2, 2, 2, 320, 323, 3, 2, 2, 2, 321, 319, 3, 2, 2, 2, 321, 322, 3, 2, 2, 2, 322, 6, 3, 2, 2, 2, 323, 321, 3, 2, 2, 2, 324, 326, 7, 15, 2, 2, 325, 324, 3, 2, 2, 2, 325, 326, 3, 2, 2, 2, 326, 327, 3, 2, 2, 2, 327, 328, 7, 12, 2, 2, 328, 8, 3, 2, 2, 2, 329, 330, 9, 5, 2, 2, 330, 10, 3, 2, 2, 2, 331, 332, 9, 6, 2, 2, 332, 12, 3, 2, 2, 2, 333, 334, 9, 7, 2, 2, 334, 14, 3, 2, 2, 2, 335, 336, 9, 8, 2, 2, 336, 16, 3, 2, 2, 2, 337, 338, 9, 9, 2, 2, 338, 18, 3, 2, 2, 2, 339, 340, 9, 10, 2, 2, 340, 20, 3, 2, 2, 2, 341, 342, 9, 11, 2, 2, 342, 22, 3, 2, 2, 2, 343, 344, 9, 12, 2, 2, 344, 24, 3, 2, 2, 2, 345, 346, 9, 13, 2, 2, 346, 26, 3, 2, 2, 2, 347, 348, 9, 14, 2, 2, 348, 28, 3, 2, 2, 2, 349, 350, 9, 15, 2, 2, 350, 30, 3, 2, 2, 2, 351, 352, 9, 16, 2, 2, 352, 32, 3, 2, 2, 2, 353, 354, 9, 17, 2, 2, 354, 34, 3, 2, 2, 2, 355, 356, 9, 18, 2, 2, 356, 36, 3, 2, 2, 2, 357, 358, 9, 19, 2, 2, 358, 38, 3, 2, 2, 2, 359, 360, 9, 20, 2, 2, 360, 40, 3, 2, 2, 2, 361, 362, 9, 21, 2, 2, 362, 42, 3, 2, 2, 2, 363, 364, 9, 22, 2, 2, 364, 44, 3, 2, 2, 2, 365, 366, 9, 23, 2, 2, 366, 46, 3, 2, 2, 2, 367, 368, 9, 24, 2, 2, 368, 48, 3, 2, 2, 2, 369, 370, 9, 25, 2, 2, 370, 50, 3, 2, 2, 2, 371, 372, 9, 26, 2, 2, 372, 52, 3, 2, 2, 2, 373, 374, 9, 27, 2, 2, 374, 54, 3, 2, 2, 2, 375, 376, 9, 28, 2, 2, 376, 56, 3, 2, 2, 2, 377, 378, 5, 43, 22, 2, 378, 379, 5, 45, 23, 2, 379, 380, 5, 13, 7, 2, 380, 58, 3, 2, 2, 2, 381, 382, 5, 13, 7, 2, 382, 383, 5, 31, 16, 2, 383, 384, 5, 13, 7, 2, 384, 60, 3, 2, 2, 2, 385, 386, 5, 25, 13, 2, 386, 387, 5, 33, 17, 2, 387, 388, 5, 41, 21, 2, 388, 62, 3, 2, 2, 2, 389, 390, 5, 15, 8, 2, 390, 391, 5, 13, 7, 2, 391, 392, 5, 41, 21, 2, 392, 64, 3, 2, 2, 2, 393, 394, 5, 13, 7, 2, 394, 395, 5, 31, 16, 2, 395, 396, 5, 9, 5, 2, 396, 66, 3, 2, 2, 2, 397, 398, 5, 15, 8, 2, 398, 399, 5, 9, 5, 2, 399, 400, 5, 9, 5, 2, 400, 68, 3, 2, 2, 2, 401, 402, 5, 33, 17, 2, 402, 403, 5, 35, 18, 2, 403, 404, 5, 37, 19, 2, 404, 70, 3, 2, 2, 2, 405, 406, 5, 31, 16, 2, 406, 407, 5, 35, 18, 2, 407, 408, 5, 49, 25, 2, 408, 72, 3, 2, 2, 2, 409, 410, 5, 43, 22, 2, 410, 411, 5, 45, 23, 2, 411, 412, 5, 9, 5, 2, 412, 413, 5, 53, 27, 2, 413, 74, 3, 2, 2, 2, 414, 415, 5, 29, 15, 2, 415, 416, 5, 15, 8, 2, 416, 417, 5, 9, 5, 2, 417, 418, 5, 53, 27, 2, 418, 76, 3, 2, 2, 2, 419, 420, 5, 9, 5, 2, 420, 421, 5, 15, 8, 2, 421, 422, 5, 15, 8, 2, 422, 78, 3, 2, 2, 2, 423, 424, 5, 9, 5, 2, 424, 425, 5, 15, 8, 2, 425, 426, 5, 13, 7, 2, 426, 80, 3, 2, 2, 2, 427, 428, 5, 43, 22, 2, 428, 429, 5, 47, 24, 2, 429, 430, 5, 11, 6, 2, 430, 82, 3, 2, 2, 2, 431, 432, 5, 43, 22, 2, 432, 433, 5, 11, 6, 2, 433, 434, 5, 11, 6, 2, 434, 84, 3, 2, 2, 2, 435, 436, 5, 9, 5, 2, 436, 437, 5, 33, 17, 2, 437, 438, 5, 9, 5, 2, 438, 86, 3, 2, 2, 2, 439, 440, 5, 53, 27, 2, 440, 441, 5, 41, 21, 2, 441, 442, 5, 9, 5, 2, 442, 88, 3, 2, 2, 2, 443, 444, 5, 35, 18, 2, 444, 445, 5, 41, 21, 2, 445, 446, 5, 9, 5, 2, 446, 90, 3, 2, 2, 2, 447, 448, 5, 13, 7, 2, 448, 449, 5, 31, 16, 2, 449, 450, 5, 37, 19, 2, 450, 92, 3, 2, 2, 2, 451, 452, 5, 41, 21, 2, 452, 453, 5, 29, 15, 2, 453, 454, 5, 13, 7, 2, 454, 94, 3, 2, 2, 2, 455, 456, 5, 41, 21, 2, 456, 457, 5, 41, 21, 2, 457, 458, 5, 13, 7, 2, 458, 96, 3, 2, 2, 2, 459, 460, 5, 41, 21, 2, 460, 461, 5, 9, 5, 2, 461, 462, 5, 29, 15, 2, 462, 98, 3, 2, 2, 2, 463, 464, 5, 41, 21, 2, 464, 465, 5, 9, 5, 2, 465, 466, 5, 41, 21, 2, 466, 100, 3, 2, 2, 2, 467, 468, 5, 37, 19, 2, 468, 469, 5, 47, 24, 2, 469, 470, 5, 43, 22, 2, 470, 471, 5, 23, 12, 2, 471, 102, 3, 2, 2, 2, 472, 473, 5, 37, 19, 2, 473, 474, 5, 35, 18, 2, 474, 475, 5, 37, 19, 2, 475, 104, 3, 2, 2, 2, 476, 477, 5, 15, 8, 2, 477, 478, 5, 9, 5, 2, 478, 479, 5, 15, 8, 2, 479, 106, 3, 2, 2, 2, 480, 481, 5, 25, 13, 2, 481, 482, 5, 33, 17, 2, 482, 483, 5, 53, 27, 2, 483, 108, 3, 2, 2, 2, 484, 485, 5, 15, 8, 2, 485, 486, 5, 13, 7, 2, 486, 487, 5, 53, 27, 2, 487, 110, 3, 2, 2, 2, 488, 489, 5, 53, 27, 2, 489, 490, 5, 13, 7, 2, 490, 491, 5, 23, 12, 2, 491, 492, 5, 21, 11, 2, 492, 112, 3, 2, 2, 2, 493, 494, 5, 53, 27, 2, 494, 495, 5, 45, 23, 2, 495, 496, 5, 23, 12, 2, 496, 497, 5, 29, 15, 2, 497, 114, 3, 2, 2, 2, 498, 499, 5, 43, 22, 2, 499, 500, 5, 37, 19, 2, 500, 501, 5, 23, 12, 2, 501, 502, 5, 29, 15, 2, 502, 116, 3, 2, 2, 2, 503, 504, 5, 29, 15, 2, 504, 505, 5, 53, 27, 2, 505, 506, 5, 25, 13, 2, 506, 118, 3, 2, 2, 2, 507, 508, 5, 31, 16, 2, 508, 509, 5, 49, 25, 2, 509, 510, 5, 25, 13, 2, 510, 120, 3, 2, 2, 2, 511, 512, 5, 9, 5, 2, 512, 513, 5, 15, 8, 2, 513, 514, 5, 25, 13, 2, 514, 122, 3, 2, 2, 2, 515, 516, 5, 9, 5, 2, 516, 517, 5, 13, 7, 2, 517, 518, 5, 25, 13, 2, 518, 124, 3, 2, 2, 2, 519, 520, 5, 43, 22, 2, 520, 521, 5, 47, 24, 2, 521, 522, 5, 25, 13, 2, 522, 126, 3, 2, 2, 2, 523, 524, 5, 43, 22, 2, 524, 525, 5, 11, 6, 2, 525, 526, 5, 25, 13, 2, 526, 128, 3, 2, 2, 2, 527, 528, 5, 9, 5, 2, 528, 529, 5, 33, 17, 2, 529, 530, 5, 25, 13, 2, 530, 130, 3, 2, 2, 2, 531, 532, 5, 53, 27, 2, 532, 533, 5, 41, 21, 2, 533, 534, 5, 25, 13, 2, 534, 132, 3, 2, 2, 2, 535, 536, 5, 35, 18, 2, 536, 537, 5, 41, 21, 2, 537, 538, 5, 25, 13, 2, 538, 134, 3, 2, 2, 2, 539, 540, 5, 13, 7, 2, 540, 541, 5, 37, 19, 2, 541, 542, 5, 25, 13, 2, 542, 136, 3, 2, 2, 2, 543, 544, 5, 43, 22, 2, 544, 545, 5, 45, 23, 2, 545, 546, 5, 9, 5, 2, 546, 138, 3, 2, 2, 2, 547, 548, 5, 29, 15, 2, 548, 549, 5, 15, 8, 2, 549, 550, 5, 9, 5, 2, 550, 140, 3, 2, 2, 2, 551, 552, 5, 43, 22, 2, 552, 553, 5, 23, 12, 2, 553, 554, 5, 29, 15, 2, 554, 555, 5, 15, 8, 2, 555, 142, 3, 2, 2, 2, 556, 557, 5, 29, 15, 2, 557, 558, 5, 23, 12, 2, 558, 559, 5, 29, 15, 2, 559, 560, 5, 15, 8, 2, 560, 144, 3, 2, 2, 2, 561, 562, 5, 37, 19, 2, 562, 563, 5, 13, 7, 2, 563, 564, 5, 23, 12, 2, 564, 565, 5, 29, 15, 2, 565, 146, 3, 2, 2, 2, 566, 567, 5, 27, 14, 2, 567, 568, 5, 31, 16, 2, 568, 569, 5, 37, 19, 2, 569, 148, 3, 2, 2, 2, 570, 571, 5, 27, 14, 2, 571, 572, 5, 13, 7, 2, 572, 150, 3, 2, 2, 2, 573, 574, 5, 27, 14, 2, 574, 575, 5, 33, 17, 2, 575, 576, 5, 13, 7, 2, 576, 152, 3, 2, 2, 2, 577, 578, 5, 27, 14, 2, 578, 579, 5, 55, 28, 2, 579, 154, 3, 2, 2, 2, 580, 581, 5, 27, 14, 2, 581, 582, 5, 33, 17, 2, 582, 583, 5, 55, 28, 2, 583, 156, 3, 2, 2, 2, 584, 585, 5, 27, 14, 2, 585, 586, 5, 37, 19, 2, 586, 158, 3, 2, 2, 2, 587, 588, 5, 27, 14, 2, 588, 589, 5, 31, 16, 2, 589, 160, 3, 2, 2, 2, 590, 591, 5, 27, 14, 2, 591, 592, 5, 37, 19, 2, 592, 593, 5, 17, 9, 2, 593, 162, 3, 2, 2, 2, 594, 595, 5, 27, 14, 2, 595, 596, 5, 37, 19, 2, 596, 597, 5, 35, 18, 2, 597, 164, 3, 2, 2, 2, 598, 599, 5, 13, 7, 2, 599, 600, 5, 9, 5, 2, 600, 601, 5, 29, 15, 2, 601, 602, 5, 29, 15, 2, 602, 166, 3, 2, 2, 2, 603, 604, 5, 13, 7, 2, 604, 605, 5, 13, 7, 2, 605, 168, 3, 2, 2, 2, 606, 607, 5, 13, 7, 2, 607, 608, 5, 33, 17, 2, 608, 609, 5, 13, 7, 2, 609, 170, 3, 2, 2, 2, 610, 611, 5, 13, 7, 2, 611, 612, 5, 55, 28, 2, 612, 172, 3, 2, 2, 2, 613, 614, 5, 13, 7, 2, 614, 615, 5, 33, 17, 2, 615, 616, 5, 55, 28, 2, 616, 174, 3, 2, 2, 2, 617, 618, 5, 13, 7, 2, 618, 619, 5, 37, 19, 2, 619, 176, 3, 2, 2, 2, 620, 621, 5, 13, 7, 2, 621, 622, 5, 31, 16, 2, 622, 178, 3, 2, 2, 2, 623, 624, 5, 13, 7, 2, 624, 625, 5, 37, 19, 2, 625, 626, 5, 17, 9, 2, 626, 180, 3, 2, 2, 2, 627, 628, 5, 13, 7, 2, 628, 629, 5, 37, 19, 2, 629, 630, 5, 35, 18, 2, 630, 182, 3, 2, 2, 2, 631, 632, 5, 41, 21, 2, 632, 633, 5, 17, 9, 2, 633, 634, 5, 45, 23, 2, 634, 184, 3, 2, 2, 2, 635, 636, 5, 41, 21, 2, 636, 637, 5, 13, 7, 2, 637, 186, 3, 2, 2, 2, 638, 639, 5, 41, 21, 2, 639, 640, 5, 33, 17, 2, 640, 641, 5, 13, 7, 2, 641, 188, 3, 2, 2, 2, 642, 643, 5, 41, 21, 2, 643, 644, 5, 55, 28, 2, 644, 190, 3, 2, 2, 2, 645, 646, 5, 41, 21, 2, 646, 647, 5, 33, 17, 2, 647, 648, 5, 55, 28, 2, 648, 192, 3, 2, 2, 2, 649, 650, 5, 41, 21, 2, 650, 651, 5, 31, 16, 2, 651, 194, 3, 2, 2, 2, 652, 653, 5, 41, 21, 2, 653, 654, 5, 37, 19, 2, 654, 196, 3, 2, 2, 2, 655, 656, 5, 41, 21, 2, 656, 657, 5, 37, 19, 2, 657, 658, 5, 17, 9, 2, 658, 198, 3, 2, 2, 2, 659, 660, 5, 41, 21, 2, 660, 661, 5, 37, 19, 2, 661, 662, 5, 35, 18, 2, 662, 200, 3, 2, 2, 2, 663, 664, 5, 41, 21, 2, 664, 665, 5, 43, 22, 2, 665, 666, 5, 45, 23, 2, 666, 202, 3, 2, 2, 2, 667, 668, 5, 17, 9, 2, 668, 669, 5, 25, 13, 2, 669, 204, 3, 2, 2, 2, 670, 671, 5, 15, 8, 2, 671, 672, 5, 25, 13, 2, 672, 206, 3, 2, 2, 2, 673, 674, 5, 25, 13, 2, 674, 675, 5, 33, 17, 2, 675, 208, 3, 2, 2, 2, 676, 677, 5, 35, 18, 2, 677, 678, 5, 47, 24, 2, 678, 679, 5, 45, 23, 2, 679, 210, 3, 2, 2, 2, 680, 681, 5, 23, 12, 2, 681, 682, 5, 29, 15, 2, 682, 683, 5, 45, 23, 2, 683, 212, 3, 2, 2, 2, 684, 685, 5, 35, 18, 2, 685, 686, 5, 41, 21, 2, 686, 687, 5, 21, 11, 2, 687, 214, 3, 2, 2, 2, 688, 689, 5, 17, 9, 2, 689, 690, 5, 39, 20, 2, 690, 691, 5, 47, 24, 2, 691, 216, 3, 2, 2, 2, 692, 693, 5, 43, 22, 2, 693, 694, 5, 17, 9, 2, 694, 695, 5, 45, 23, 2, 695, 218, 3, 2, 2, 2, 696, 697, 5, 25, 13, 2, 697, 698, 5, 33, 17, 2, 698, 699, 5, 13, 7, 2, 699, 700, 5, 29, 15, 2, 700, 701, 5, 47, 24, 2, 701, 702, 5, 15, 8, 2, 702, 703, 5, 17, 9, 2, 703, 220, 3, 2, 2, 2, 704, 705, 5, 25, 13, 2, 705, 706, 5, 19, 10, 2, 706, 222, 3, 2, 2, 2, 707, 708, 5, 17, 9, 2, 708, 709, 5, 33, 17, 2, 709, 710, 5, 15, 8, 2, 710, 711, 5, 25, 13, 2, 711, 712, 5, 19, 10, 2, 712, 224, 3, 2, 2, 2, 713, 714, 5, 31, 16, 2, 714, 715, 5, 9, 5, 2, 715, 716, 5, 13, 7, 2, 716, 717, 5, 41, 21, 2, 717, 718, 5, 35, 18, 2, 718, 226, 3, 2, 2, 2, 719, 720, 5, 17, 9, 2, 720, 721, 5, 33, 17, 2, 721, 722, 5, 15, 8, 2, 722, 723, 5, 31, 16, 2, 723, 228, 3, 2, 2, 2, 724, 725, 5, 15, 8, 2, 725, 726, 5, 11, 6, 2, 726, 230, 3, 2, 2, 2, 727, 728, 5, 15, 8, 2, 728, 729, 5, 51, 26, 2, 729, 232, 3, 2, 2, 2, 730, 731, 5, 15, 8, 2, 731, 732, 5, 43, 22, 2, 732, 234, 3, 2, 2, 2, 733, 734, 7, 38, 2, 2, 734, 236, 3, 2, 2, 2, 735, 736, 5, 9, 5, 2, 736, 238, 3, 2, 2, 2, 737, 738, 5, 11, 6, 2, 738, 240, 3, 2, 2, 2, 739, 740, 5, 13, 7, 2, 740, 242, 3, 2, 2, 2, 741, 742, 5, 15, 8, 2, 742, 244, 3, 2, 2, 2, 743, 744, 5, 17, 9, 2, 744, 246, 3, 2, 2, 2, 745, 746, 5, 23, 12, 2, 746, 248, 3, 2, 2, 2, 747, 748, 5, 29, 15, 2, 748, 250, 3, 2, 2, 2, 749, 750, 5, 31, 16, 2, 750, 252, 3, 2, 2, 2, 751, 752, 5, 37, 19, 2, 752, 753, 5, 43, 22, 2, 753, 754, 5, 51, 26, 2, 754, 254, 3, 2, 2, 2, 755, 756, 5, 43, 22, 2, 756, 757, 5, 37, 19, 2, 757, 256, 3, 2, 2, 2, 758, 759, 7, 42, 2, 2, 759, 258, 3, 2, 2, 2, 760, 761, 7, 43, 2, 2, 761, 260, 3, 2, 2, 2, 762, 763, 7, 46, 2, 2, 763, 262, 3, 2, 2, 2, 764, 765, 7, 45, 2, 2, 765, 264, 3, 2, 2, 2, 766, 767, 7, 47, 2, 2, 767, 266, 3, 2, 2, 2, 768, 769, 7, 44, 2, 2, 769, 268, 3, 2, 2, 2, 770, 771, 7, 49, 2, 2, 771, 270, 3, 2, 2, 2, 772, 773, 7, 63, 2, 2, 773, 272, 3, 2, 2, 2, 774, 775, 5, 31, 16, 2, 775, 776, 5, 35, 18, 2, 776, 777, 5, 15, 8, 2, 777, 274, 3, 2, 2, 2, 778, 779, 5, 43, 22, 2, 779, 780, 5, 23, 12, 2, 780, 781, 5, 41, 21, 2, 781, 276, 3, 2, 2, 2, 782, 783, 5, 43, 22, 2, 783, 784, 5, 23, 12, 2, 784, 785, 5, 29, 15, 2, 785, 278, 3, 2, 2, 2, 786, 787, 5, 33, 17, 2, 787, 788, 5, 35, 18, 2, 788, 789, 5, 45, 23, 2, 789, 280, 3, 2, 2, 2, 790, 791, 5, 9, 5, 2, 791, 792, 5, 33, 17, 2, 792, 793, 5, 15, 8, 2, 793, 282, 3, 2, 2, 2, 794, 795, 5, 35, 18, 2, 795, 796, 5, 41, 21, 2, 796, 284, 3, 2, 2, 2, 797, 798, 5, 53, 27, 2, 798, 799, 5, 35, 18, 2, 799, 800, 5, 41, 21, 2, 800, 286, 3, 2, 2, 2, 801, 803, 9, 29, 2, 2, 802, 801, 3, 2, 2, 2, 802, 803, 3, 2, 2, 2, 803, 805, 3, 2, 2, 2, 804, 806, 9, 30, 2, 2, 805, 804, 3, 2, 2, 2, 806, 807, 3, 2, 2, 2, 807, 805, 3, 2, 2, 2, 807, 808, 3, 2, 2, 2, 808, 810, 3, 2, 2, 2, 809, 811, 5, 15, 8, 2, 810, 809, 3, 2, 2, 2, 810, 811, 3, 2, 2, 2, 811, 288, 3, 2, 2, 2, 812, 814, 9, 29, 2, 2, 813, 812, 3, 2, 2, 2, 813, 814, 3, 2, 2, 2, 814, 819, 3, 2, 2, 2, 815, 816, 7, 50, 2, 2, 816, 820, 7, 122, 2, 2, 817, 818, 7, 50, 2, 2, 818, 820, 7, 90, 2, 2, 819, 815, 3, 2, 2, 2, 819, 817, 3, 2, 2, 2, 820, 822, 3, 2, 2, 2, 821, 823, 9, 31, 2, 2, 822, 821, 3, 2, 2, 2, 823, 824, 3, 2, 2, 2, 824, 822, 3, 2, 2, 2, 824, 825, 3, 2, 2, 2, 825, 290, 3, 2, 2, 2, 826, 828, 9, 29, 2, 2, 827, 826, 3, 2, 2, 2, 827, 828, 3, 2, 2, 2, 828, 830, 3, 2, 2, 2, 829, 831, 9, 31, 2, 2, 830, 829, 3, 2, 2, 2, 831, 832, 3, 2, 2, 2, 832, 830, 3, 2, 2, 2, 832, 833, 3, 2, 2, 2, 833, 834, 3, 2, 2, 2, 834, 835, 5, 23, 12, 2, 835, 292, 3, 2, 2, 2, 836, 838, 9, 29, 2, 2, 837, 836, 3, 2, 2, 2, 837, 838, 3, 2, 2, 2, 838, 840, 3, 2, 2, 2, 839, 841, 9, 32, 2, 2, 840, 839, 3, 2, 2, 2, 841, 842, 3, 2, 2, 2, 842, 840, 3, 2, 2, 2, 842, 843, 3, 2, 2, 2, 843, 844, 3, 2, 2, 2, 844, 845, 9, 33, 2, 2, 845, 294, 3, 2, 2, 2, 846, 848, 9, 34, 2, 2, 847, 846, 3, 2, 2, 2, 848, 849, 3, 2, 2, 2, 849, 847, 3, 2, 2, 2, 849, 850, 3, 2, 2, 2, 850, 851, 3, 2, 2, 2, 851, 852, 5, 11, 6, 2, 852, 296, 3, 2, 2, 2, 853, 855, 9, 35, 2, 2, 854, 856, 9, 36, 2, 2, 855, 854, 3, 2, 2, 2, 856, 857, 3, 2, 2, 2, 857, 855, 3, 2, 2, 2, 857, 858, 3, 2, 2, 2, 858, 859, 3, 2, 2, 2, 859, 860, 9, 35, 2, 2, 860, 298, 3, 2, 2, 2, 861, 863, 7, 36, 2, 2, 862, 864, 9, 37, 2, 2, 863, 862, 3, 2, 2, 2, 864, 865, 3, 2, 2, 2, 865, 863, 3, 2, 2, 2, 865, 866, 3, 2, 2, 2, 866, 867, 3, 2, 2, 2, 867, 868, 7, 36, 2, 2, 868, 300, 3, 2, 2, 2, 869, 873, 9, 38, 2, 2, 870, 872, 9, 39, 2, 2, 871, 870, 3, 2, 2, 2, 872, 875, 3, 2, 2, 2, 873, 871, 3, 2, 2, 2, 873, 874, 3, 2, 2, 2, 874, 302, 3, 2, 2, 2, 875, 873, 3, 2, 2, 2, 876, 880, 9, 38, 2, 2, 877, 879, 9, 39, 2, 2, 878, 877, 3, 2, 2, 2, 879, 882, 3, 2, 2, 2, 880, 878, 3, 2, 2, 2, 880, 881, 3, 2, 2, 2, 881, 883, 3, 2, 2, 2, 882, 880, 3, 2, 2, 2, 883, 884, 7, 60, 2, 2, 884, 304, 3, 2, 2, 2, 885, 886, 11, 2, 2, 2, 886, 306, 3, 2, 2, 2, 21, 2, 316, 321, 325, 802, 807, 810, 813, 819, 824, 827, 832, 837, 842, 849, 857, 865, 873, 880, 3, 2, 3, 2] \ No newline at end of file diff --git a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.java b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.java new file mode 100644 index 000000000..4dc054c3f --- /dev/null +++ b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.java @@ -0,0 +1,506 @@ +// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 by ANTLR 4.9.1 +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class As8080Lexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.9.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + WS=1, COMMENT=2, EOL=3, OPCODE_STC=4, OPCODE_CMC=5, OPCODE_INR=6, OPCODE_DCR=7, + OPCODE_CMA=8, OPCODE_DAA=9, OPCODE_NOP=10, OPCODE_MOV=11, OPCODE_STAX=12, + OPCODE_LDAX=13, OPCODE_ADD=14, OPCODE_ADC=15, OPCODE_SUB=16, OPCODE_SBB=17, + OPCODE_ANA=18, OPCODE_XRA=19, OPCODE_ORA=20, OPCODE_CMP=21, OPCODE_RLC=22, + OPCODE_RRC=23, OPCODE_RAL=24, OPCODE_RAR=25, OPCODE_PUSH=26, OPCODE_POP=27, + OPCODE_DAD=28, OPCODE_INX=29, OPCODE_DCX=30, OPCODE_XCHG=31, OPCODE_XTHL=32, + OPCODE_SPHL=33, OPCODE_LXI=34, OPCODE_MVI=35, OPCODE_ADI=36, OPCODE_ACI=37, + OPCODE_SUI=38, OPCODE_SBI=39, OPCODE_ANI=40, OPCODE_XRI=41, OPCODE_ORI=42, + OPCODE_CPI=43, OPCODE_STA=44, OPCODE_LDA=45, OPCODE_SHLD=46, OPCODE_LHLD=47, + OPCODE_PCHL=48, OPCODE_JMP=49, OPCODE_JC=50, OPCODE_JNC=51, OPCODE_JZ=52, + OPCODE_JNZ=53, OPCODE_JP=54, OPCODE_JM=55, OPCODE_JPE=56, OPCODE_JPO=57, + OPCODE_CALL=58, OPCODE_CC=59, OPCODE_CNC=60, OPCODE_CZ=61, OPCODE_CNZ=62, + OPCODE_CP=63, OPCODE_CM=64, OPCODE_CPE=65, OPCODE_CPO=66, OPCODE_RET=67, + OPCODE_RC=68, OPCODE_RNC=69, OPCODE_RZ=70, OPCODE_RNZ=71, OPCODE_RM=72, + OPCODE_RP=73, OPCODE_RPE=74, OPCODE_RPO=75, OPCODE_RST=76, OPCODE_EI=77, + OPCODE_DI=78, OPCODE_IN=79, OPCODE_OUT=80, OPCODE_HLT=81, PREP_ORG=82, + PREP_EQU=83, PREP_SET=84, PREP_INCLUDE=85, PREP_IF=86, PREP_ENDIF=87, + PREP_MACRO=88, PREP_ENDM=89, PREP_DB=90, PREP_DW=91, PREP_DS=92, PREP_ADDR=93, + REG_A=94, REG_B=95, REG_C=96, REG_D=97, REG_E=98, REG_H=99, REG_L=100, + REG_M=101, REG_PSW=102, REG_SP=103, SEP_LPAR=104, SEP_RPAR=105, SEP_COMMA=106, + OP_ADD=107, OP_SUBTRACT=108, OP_MULTIPLY=109, OP_DIVIDE=110, OP_EQUAL=111, + OP_MOD=112, OP_SHR=113, OP_SHL=114, OP_NOT=115, OP_AND=116, OP_OR=117, + OP_XOR=118, LIT_NUMBER=119, LIT_HEXNUMBER_1=120, LIT_HEXNUMBER_2=121, + LIT_OCTNUMBER=122, LIT_BINNUMBER=123, LIT_STRING_1=124, LIT_STRING_2=125, + ID_IDENTIFIER=126, ID_LABEL=127, ERROR=128; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "WS", "COMMENT", "EOL", "A", "B", "C", "D", "E", "F", "G", "H", "I", + "J", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", + "Z", "OPCODE_STC", "OPCODE_CMC", "OPCODE_INR", "OPCODE_DCR", "OPCODE_CMA", + "OPCODE_DAA", "OPCODE_NOP", "OPCODE_MOV", "OPCODE_STAX", "OPCODE_LDAX", + "OPCODE_ADD", "OPCODE_ADC", "OPCODE_SUB", "OPCODE_SBB", "OPCODE_ANA", + "OPCODE_XRA", "OPCODE_ORA", "OPCODE_CMP", "OPCODE_RLC", "OPCODE_RRC", + "OPCODE_RAL", "OPCODE_RAR", "OPCODE_PUSH", "OPCODE_POP", "OPCODE_DAD", + "OPCODE_INX", "OPCODE_DCX", "OPCODE_XCHG", "OPCODE_XTHL", "OPCODE_SPHL", + "OPCODE_LXI", "OPCODE_MVI", "OPCODE_ADI", "OPCODE_ACI", "OPCODE_SUI", + "OPCODE_SBI", "OPCODE_ANI", "OPCODE_XRI", "OPCODE_ORI", "OPCODE_CPI", + "OPCODE_STA", "OPCODE_LDA", "OPCODE_SHLD", "OPCODE_LHLD", "OPCODE_PCHL", + "OPCODE_JMP", "OPCODE_JC", "OPCODE_JNC", "OPCODE_JZ", "OPCODE_JNZ", "OPCODE_JP", + "OPCODE_JM", "OPCODE_JPE", "OPCODE_JPO", "OPCODE_CALL", "OPCODE_CC", + "OPCODE_CNC", "OPCODE_CZ", "OPCODE_CNZ", "OPCODE_CP", "OPCODE_CM", "OPCODE_CPE", + "OPCODE_CPO", "OPCODE_RET", "OPCODE_RC", "OPCODE_RNC", "OPCODE_RZ", "OPCODE_RNZ", + "OPCODE_RM", "OPCODE_RP", "OPCODE_RPE", "OPCODE_RPO", "OPCODE_RST", "OPCODE_EI", + "OPCODE_DI", "OPCODE_IN", "OPCODE_OUT", "OPCODE_HLT", "PREP_ORG", "PREP_EQU", + "PREP_SET", "PREP_INCLUDE", "PREP_IF", "PREP_ENDIF", "PREP_MACRO", "PREP_ENDM", + "PREP_DB", "PREP_DW", "PREP_DS", "PREP_ADDR", "REG_A", "REG_B", "REG_C", + "REG_D", "REG_E", "REG_H", "REG_L", "REG_M", "REG_PSW", "REG_SP", "SEP_LPAR", + "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE", + "OP_EQUAL", "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", + "OP_XOR", "LIT_NUMBER", "LIT_HEXNUMBER_1", "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", + "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", + "ERROR" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, "'$'", null, null, + null, null, null, null, null, null, null, null, "'('", "')'", "','", + "'+'", "'-'", "'*'", "'/'", "'='" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "WS", "COMMENT", "EOL", "OPCODE_STC", "OPCODE_CMC", "OPCODE_INR", + "OPCODE_DCR", "OPCODE_CMA", "OPCODE_DAA", "OPCODE_NOP", "OPCODE_MOV", + "OPCODE_STAX", "OPCODE_LDAX", "OPCODE_ADD", "OPCODE_ADC", "OPCODE_SUB", + "OPCODE_SBB", "OPCODE_ANA", "OPCODE_XRA", "OPCODE_ORA", "OPCODE_CMP", + "OPCODE_RLC", "OPCODE_RRC", "OPCODE_RAL", "OPCODE_RAR", "OPCODE_PUSH", + "OPCODE_POP", "OPCODE_DAD", "OPCODE_INX", "OPCODE_DCX", "OPCODE_XCHG", + "OPCODE_XTHL", "OPCODE_SPHL", "OPCODE_LXI", "OPCODE_MVI", "OPCODE_ADI", + "OPCODE_ACI", "OPCODE_SUI", "OPCODE_SBI", "OPCODE_ANI", "OPCODE_XRI", + "OPCODE_ORI", "OPCODE_CPI", "OPCODE_STA", "OPCODE_LDA", "OPCODE_SHLD", + "OPCODE_LHLD", "OPCODE_PCHL", "OPCODE_JMP", "OPCODE_JC", "OPCODE_JNC", + "OPCODE_JZ", "OPCODE_JNZ", "OPCODE_JP", "OPCODE_JM", "OPCODE_JPE", "OPCODE_JPO", + "OPCODE_CALL", "OPCODE_CC", "OPCODE_CNC", "OPCODE_CZ", "OPCODE_CNZ", + "OPCODE_CP", "OPCODE_CM", "OPCODE_CPE", "OPCODE_CPO", "OPCODE_RET", "OPCODE_RC", + "OPCODE_RNC", "OPCODE_RZ", "OPCODE_RNZ", "OPCODE_RM", "OPCODE_RP", "OPCODE_RPE", + "OPCODE_RPO", "OPCODE_RST", "OPCODE_EI", "OPCODE_DI", "OPCODE_IN", "OPCODE_OUT", + "OPCODE_HLT", "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_INCLUDE", "PREP_IF", + "PREP_ENDIF", "PREP_MACRO", "PREP_ENDM", "PREP_DB", "PREP_DW", "PREP_DS", + "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", "REG_E", "REG_H", "REG_L", + "REG_M", "REG_PSW", "REG_SP", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", + "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_MOD", "OP_SHR", + "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", "OP_XOR", "LIT_NUMBER", "LIT_HEXNUMBER_1", + "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", "LIT_BINNUMBER", "LIT_STRING_1", + "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", "ERROR" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public As8080Lexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "As8080Lexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u0082\u0377\b\1\4"+ + "\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n"+ + "\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ + "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+ + "\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t"+ + " \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t"+ + "+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64"+ + "\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t"+ + "=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4"+ + "I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\t"+ + "T\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_"+ + "\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k"+ + "\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv"+ + "\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080\t"+ + "\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084"+ + "\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089"+ + "\t\u0089\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c\t\u008c\4\u008d\t\u008d"+ + "\4\u008e\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090\4\u0091\t\u0091\4\u0092"+ + "\t\u0092\4\u0093\t\u0093\4\u0094\t\u0094\4\u0095\t\u0095\4\u0096\t\u0096"+ + "\4\u0097\t\u0097\4\u0098\t\u0098\4\u0099\t\u0099\3\2\3\2\3\2\3\2\3\3\3"+ + "\3\3\3\3\3\3\3\5\3\u013d\n\3\3\3\7\3\u0140\n\3\f\3\16\3\u0143\13\3\3\4"+ + "\5\4\u0146\n\4\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n"+ + "\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3\22"+ + "\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\31"+ + "\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36"+ + "\3\36\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3!\3\"\3\"\3\"\3\"\3#\3"+ + "#\3#\3#\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3(\3"+ + "(\3(\3(\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3+\3+\3,\3,\3,\3,\3-\3-\3-\3-\3"+ + ".\3.\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\61\3\61\3\61\3\61\3\62\3"+ + "\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\65\3\65\3"+ + "\65\3\65\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\38\38\38\38\38\39\39"+ + "\39\39\39\3:\3:\3:\3:\3:\3;\3;\3;\3;\3<\3<\3<\3<\3=\3=\3=\3=\3>\3>\3>"+ + "\3>\3?\3?\3?\3?\3@\3@\3@\3@\3A\3A\3A\3A\3B\3B\3B\3B\3C\3C\3C\3C\3D\3D"+ + "\3D\3D\3E\3E\3E\3E\3F\3F\3F\3F\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3I"+ + "\3I\3I\3J\3J\3J\3J\3K\3K\3K\3L\3L\3L\3L\3M\3M\3M\3N\3N\3N\3N\3O\3O\3O"+ + "\3P\3P\3P\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3S\3S\3S\3S\3S\3T\3T\3T\3U\3U\3U\3U"+ + "\3V\3V\3V\3W\3W\3W\3W\3X\3X\3X\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3\\\3"+ + "\\\3\\\3\\\3]\3]\3]\3^\3^\3^\3^\3_\3_\3_\3`\3`\3`\3`\3a\3a\3a\3b\3b\3"+ + "b\3c\3c\3c\3c\3d\3d\3d\3d\3e\3e\3e\3e\3f\3f\3f\3g\3g\3g\3h\3h\3h\3i\3"+ + "i\3i\3i\3j\3j\3j\3j\3k\3k\3k\3k\3l\3l\3l\3l\3m\3m\3m\3m\3n\3n\3n\3n\3"+ + "n\3n\3n\3n\3o\3o\3o\3p\3p\3p\3p\3p\3p\3q\3q\3q\3q\3q\3q\3r\3r\3r\3r\3"+ + "r\3s\3s\3s\3t\3t\3t\3u\3u\3u\3v\3v\3w\3w\3x\3x\3y\3y\3z\3z\3{\3{\3|\3"+ + "|\3}\3}\3~\3~\3\177\3\177\3\177\3\177\3\u0080\3\u0080\3\u0080\3\u0081"+ + "\3\u0081\3\u0082\3\u0082\3\u0083\3\u0083\3\u0084\3\u0084\3\u0085\3\u0085"+ + "\3\u0086\3\u0086\3\u0087\3\u0087\3\u0088\3\u0088\3\u0089\3\u0089\3\u0089"+ + "\3\u0089\3\u008a\3\u008a\3\u008a\3\u008a\3\u008b\3\u008b\3\u008b\3\u008b"+ + "\3\u008c\3\u008c\3\u008c\3\u008c\3\u008d\3\u008d\3\u008d\3\u008d\3\u008e"+ + "\3\u008e\3\u008e\3\u008f\3\u008f\3\u008f\3\u008f\3\u0090\5\u0090\u0323"+ + "\n\u0090\3\u0090\6\u0090\u0326\n\u0090\r\u0090\16\u0090\u0327\3\u0090"+ + "\5\u0090\u032b\n\u0090\3\u0091\5\u0091\u032e\n\u0091\3\u0091\3\u0091\3"+ + "\u0091\3\u0091\5\u0091\u0334\n\u0091\3\u0091\6\u0091\u0337\n\u0091\r\u0091"+ + "\16\u0091\u0338\3\u0092\5\u0092\u033c\n\u0092\3\u0092\6\u0092\u033f\n"+ + "\u0092\r\u0092\16\u0092\u0340\3\u0092\3\u0092\3\u0093\5\u0093\u0346\n"+ + "\u0093\3\u0093\6\u0093\u0349\n\u0093\r\u0093\16\u0093\u034a\3\u0093\3"+ + "\u0093\3\u0094\6\u0094\u0350\n\u0094\r\u0094\16\u0094\u0351\3\u0094\3"+ + "\u0094\3\u0095\3\u0095\6\u0095\u0358\n\u0095\r\u0095\16\u0095\u0359\3"+ + "\u0095\3\u0095\3\u0096\3\u0096\6\u0096\u0360\n\u0096\r\u0096\16\u0096"+ + "\u0361\3\u0096\3\u0096\3\u0097\3\u0097\7\u0097\u0368\n\u0097\f\u0097\16"+ + "\u0097\u036b\13\u0097\3\u0098\3\u0098\7\u0098\u036f\n\u0098\f\u0098\16"+ + "\u0098\u0372\13\u0098\3\u0098\3\u0098\3\u0099\3\u0099\2\2\u009a\3\3\5"+ + "\4\7\5\t\2\13\2\r\2\17\2\21\2\23\2\25\2\27\2\31\2\33\2\35\2\37\2!\2#\2"+ + "%\2\'\2)\2+\2-\2/\2\61\2\63\2\65\2\67\29\6;\7=\b?\tA\nC\13E\fG\rI\16K"+ + "\17M\20O\21Q\22S\23U\24W\25Y\26[\27]\30_\31a\32c\33e\34g\35i\36k\37m "+ + "o!q\"s#u$w%y&{\'}(\177)\u0081*\u0083+\u0085,\u0087-\u0089.\u008b/\u008d"+ + "\60\u008f\61\u0091\62\u0093\63\u0095\64\u0097\65\u0099\66\u009b\67\u009d"+ + "8\u009f9\u00a1:\u00a3;\u00a5<\u00a7=\u00a9>\u00ab?\u00ad@\u00afA\u00b1"+ + "B\u00b3C\u00b5D\u00b7E\u00b9F\u00bbG\u00bdH\u00bfI\u00c1J\u00c3K\u00c5"+ + "L\u00c7M\u00c9N\u00cbO\u00cdP\u00cfQ\u00d1R\u00d3S\u00d5T\u00d7U\u00d9"+ + "V\u00dbW\u00ddX\u00dfY\u00e1Z\u00e3[\u00e5\\\u00e7]\u00e9^\u00eb_\u00ed"+ + "`\u00efa\u00f1b\u00f3c\u00f5d\u00f7e\u00f9f\u00fbg\u00fdh\u00ffi\u0101"+ + "j\u0103k\u0105l\u0107m\u0109n\u010bo\u010dp\u010fq\u0111r\u0113s\u0115"+ + "t\u0117u\u0119v\u011bw\u011dx\u011fy\u0121z\u0123{\u0125|\u0127}\u0129"+ + "~\u012b\177\u012d\u0080\u012f\u0081\u0131\u0082\3\2(\5\2\13\13\16\16\""+ + "\"\4\2%%==\4\2\f\f\17\17\4\2CCcc\4\2DDdd\4\2EEee\4\2FFff\4\2GGgg\4\2H"+ + "Hhh\4\2IIii\4\2JJjj\4\2KKkk\4\2LLll\4\2NNnn\4\2OOoo\4\2PPpp\4\2QQqq\4"+ + "\2RRrr\4\2SSss\4\2TTtt\4\2UUuu\4\2VVvv\4\2WWww\4\2XXxx\4\2YYyy\4\2ZZz"+ + "z\4\2\\\\||\3\2//\3\2\62;\5\2\62;CHch\3\2\629\6\2QQSSqqss\3\2\62\63\3"+ + "\2))\4\2))``\4\2$$``\5\2A\\aac|\6\2\62;A\\aac|\2\u0371\2\3\3\2\2\2\2\5"+ + "\3\2\2\2\2\7\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3"+ + "\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2"+ + "\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2"+ + "[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3"+ + "\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2"+ + "\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2"+ + "\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089"+ + "\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2"+ + "\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b"+ + "\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2"+ + "\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad"+ + "\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2"+ + "\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf"+ + "\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2"+ + "\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1"+ + "\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2"+ + "\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3"+ + "\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9\3\2\2\2\2\u00eb\3\2\2"+ + "\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1\3\2\2\2\2\u00f3\3\2\2\2\2\u00f5"+ + "\3\2\2\2\2\u00f7\3\2\2\2\2\u00f9\3\2\2\2\2\u00fb\3\2\2\2\2\u00fd\3\2\2"+ + "\2\2\u00ff\3\2\2\2\2\u0101\3\2\2\2\2\u0103\3\2\2\2\2\u0105\3\2\2\2\2\u0107"+ + "\3\2\2\2\2\u0109\3\2\2\2\2\u010b\3\2\2\2\2\u010d\3\2\2\2\2\u010f\3\2\2"+ + "\2\2\u0111\3\2\2\2\2\u0113\3\2\2\2\2\u0115\3\2\2\2\2\u0117\3\2\2\2\2\u0119"+ + "\3\2\2\2\2\u011b\3\2\2\2\2\u011d\3\2\2\2\2\u011f\3\2\2\2\2\u0121\3\2\2"+ + "\2\2\u0123\3\2\2\2\2\u0125\3\2\2\2\2\u0127\3\2\2\2\2\u0129\3\2\2\2\2\u012b"+ + "\3\2\2\2\2\u012d\3\2\2\2\2\u012f\3\2\2\2\2\u0131\3\2\2\2\3\u0133\3\2\2"+ + "\2\5\u013c\3\2\2\2\7\u0145\3\2\2\2\t\u0149\3\2\2\2\13\u014b\3\2\2\2\r"+ + "\u014d\3\2\2\2\17\u014f\3\2\2\2\21\u0151\3\2\2\2\23\u0153\3\2\2\2\25\u0155"+ + "\3\2\2\2\27\u0157\3\2\2\2\31\u0159\3\2\2\2\33\u015b\3\2\2\2\35\u015d\3"+ + "\2\2\2\37\u015f\3\2\2\2!\u0161\3\2\2\2#\u0163\3\2\2\2%\u0165\3\2\2\2\'"+ + "\u0167\3\2\2\2)\u0169\3\2\2\2+\u016b\3\2\2\2-\u016d\3\2\2\2/\u016f\3\2"+ + "\2\2\61\u0171\3\2\2\2\63\u0173\3\2\2\2\65\u0175\3\2\2\2\67\u0177\3\2\2"+ + "\29\u0179\3\2\2\2;\u017d\3\2\2\2=\u0181\3\2\2\2?\u0185\3\2\2\2A\u0189"+ + "\3\2\2\2C\u018d\3\2\2\2E\u0191\3\2\2\2G\u0195\3\2\2\2I\u0199\3\2\2\2K"+ + "\u019e\3\2\2\2M\u01a3\3\2\2\2O\u01a7\3\2\2\2Q\u01ab\3\2\2\2S\u01af\3\2"+ + "\2\2U\u01b3\3\2\2\2W\u01b7\3\2\2\2Y\u01bb\3\2\2\2[\u01bf\3\2\2\2]\u01c3"+ + "\3\2\2\2_\u01c7\3\2\2\2a\u01cb\3\2\2\2c\u01cf\3\2\2\2e\u01d3\3\2\2\2g"+ + "\u01d8\3\2\2\2i\u01dc\3\2\2\2k\u01e0\3\2\2\2m\u01e4\3\2\2\2o\u01e8\3\2"+ + "\2\2q\u01ed\3\2\2\2s\u01f2\3\2\2\2u\u01f7\3\2\2\2w\u01fb\3\2\2\2y\u01ff"+ + "\3\2\2\2{\u0203\3\2\2\2}\u0207\3\2\2\2\177\u020b\3\2\2\2\u0081\u020f\3"+ + "\2\2\2\u0083\u0213\3\2\2\2\u0085\u0217\3\2\2\2\u0087\u021b\3\2\2\2\u0089"+ + "\u021f\3\2\2\2\u008b\u0223\3\2\2\2\u008d\u0227\3\2\2\2\u008f\u022c\3\2"+ + "\2\2\u0091\u0231\3\2\2\2\u0093\u0236\3\2\2\2\u0095\u023a\3\2\2\2\u0097"+ + "\u023d\3\2\2\2\u0099\u0241\3\2\2\2\u009b\u0244\3\2\2\2\u009d\u0248\3\2"+ + "\2\2\u009f\u024b\3\2\2\2\u00a1\u024e\3\2\2\2\u00a3\u0252\3\2\2\2\u00a5"+ + "\u0256\3\2\2\2\u00a7\u025b\3\2\2\2\u00a9\u025e\3\2\2\2\u00ab\u0262\3\2"+ + "\2\2\u00ad\u0265\3\2\2\2\u00af\u0269\3\2\2\2\u00b1\u026c\3\2\2\2\u00b3"+ + "\u026f\3\2\2\2\u00b5\u0273\3\2\2\2\u00b7\u0277\3\2\2\2\u00b9\u027b\3\2"+ + "\2\2\u00bb\u027e\3\2\2\2\u00bd\u0282\3\2\2\2\u00bf\u0285\3\2\2\2\u00c1"+ + "\u0289\3\2\2\2\u00c3\u028c\3\2\2\2\u00c5\u028f\3\2\2\2\u00c7\u0293\3\2"+ + "\2\2\u00c9\u0297\3\2\2\2\u00cb\u029b\3\2\2\2\u00cd\u029e\3\2\2\2\u00cf"+ + "\u02a1\3\2\2\2\u00d1\u02a4\3\2\2\2\u00d3\u02a8\3\2\2\2\u00d5\u02ac\3\2"+ + "\2\2\u00d7\u02b0\3\2\2\2\u00d9\u02b4\3\2\2\2\u00db\u02b8\3\2\2\2\u00dd"+ + "\u02c0\3\2\2\2\u00df\u02c3\3\2\2\2\u00e1\u02c9\3\2\2\2\u00e3\u02cf\3\2"+ + "\2\2\u00e5\u02d4\3\2\2\2\u00e7\u02d7\3\2\2\2\u00e9\u02da\3\2\2\2\u00eb"+ + "\u02dd\3\2\2\2\u00ed\u02df\3\2\2\2\u00ef\u02e1\3\2\2\2\u00f1\u02e3\3\2"+ + "\2\2\u00f3\u02e5\3\2\2\2\u00f5\u02e7\3\2\2\2\u00f7\u02e9\3\2\2\2\u00f9"+ + "\u02eb\3\2\2\2\u00fb\u02ed\3\2\2\2\u00fd\u02ef\3\2\2\2\u00ff\u02f3\3\2"+ + "\2\2\u0101\u02f6\3\2\2\2\u0103\u02f8\3\2\2\2\u0105\u02fa\3\2\2\2\u0107"+ + "\u02fc\3\2\2\2\u0109\u02fe\3\2\2\2\u010b\u0300\3\2\2\2\u010d\u0302\3\2"+ + "\2\2\u010f\u0304\3\2\2\2\u0111\u0306\3\2\2\2\u0113\u030a\3\2\2\2\u0115"+ + "\u030e\3\2\2\2\u0117\u0312\3\2\2\2\u0119\u0316\3\2\2\2\u011b\u031a\3\2"+ + "\2\2\u011d\u031d\3\2\2\2\u011f\u0322\3\2\2\2\u0121\u032d\3\2\2\2\u0123"+ + "\u033b\3\2\2\2\u0125\u0345\3\2\2\2\u0127\u034f\3\2\2\2\u0129\u0355\3\2"+ + "\2\2\u012b\u035d\3\2\2\2\u012d\u0365\3\2\2\2\u012f\u036c\3\2\2\2\u0131"+ + "\u0375\3\2\2\2\u0133\u0134\t\2\2\2\u0134\u0135\3\2\2\2\u0135\u0136\b\2"+ + "\2\2\u0136\4\3\2\2\2\u0137\u0138\7\61\2\2\u0138\u013d\7\61\2\2\u0139\u013a"+ + "\7/\2\2\u013a\u013d\7/\2\2\u013b\u013d\t\3\2\2\u013c\u0137\3\2\2\2\u013c"+ + "\u0139\3\2\2\2\u013c\u013b\3\2\2\2\u013d\u0141\3\2\2\2\u013e\u0140\n\4"+ + "\2\2\u013f\u013e\3\2\2\2\u0140\u0143\3\2\2\2\u0141\u013f\3\2\2\2\u0141"+ + "\u0142\3\2\2\2\u0142\6\3\2\2\2\u0143\u0141\3\2\2\2\u0144\u0146\7\17\2"+ + "\2\u0145\u0144\3\2\2\2\u0145\u0146\3\2\2\2\u0146\u0147\3\2\2\2\u0147\u0148"+ + "\7\f\2\2\u0148\b\3\2\2\2\u0149\u014a\t\5\2\2\u014a\n\3\2\2\2\u014b\u014c"+ + "\t\6\2\2\u014c\f\3\2\2\2\u014d\u014e\t\7\2\2\u014e\16\3\2\2\2\u014f\u0150"+ + "\t\b\2\2\u0150\20\3\2\2\2\u0151\u0152\t\t\2\2\u0152\22\3\2\2\2\u0153\u0154"+ + "\t\n\2\2\u0154\24\3\2\2\2\u0155\u0156\t\13\2\2\u0156\26\3\2\2\2\u0157"+ + "\u0158\t\f\2\2\u0158\30\3\2\2\2\u0159\u015a\t\r\2\2\u015a\32\3\2\2\2\u015b"+ + "\u015c\t\16\2\2\u015c\34\3\2\2\2\u015d\u015e\t\17\2\2\u015e\36\3\2\2\2"+ + "\u015f\u0160\t\20\2\2\u0160 \3\2\2\2\u0161\u0162\t\21\2\2\u0162\"\3\2"+ + "\2\2\u0163\u0164\t\22\2\2\u0164$\3\2\2\2\u0165\u0166\t\23\2\2\u0166&\3"+ + "\2\2\2\u0167\u0168\t\24\2\2\u0168(\3\2\2\2\u0169\u016a\t\25\2\2\u016a"+ + "*\3\2\2\2\u016b\u016c\t\26\2\2\u016c,\3\2\2\2\u016d\u016e\t\27\2\2\u016e"+ + ".\3\2\2\2\u016f\u0170\t\30\2\2\u0170\60\3\2\2\2\u0171\u0172\t\31\2\2\u0172"+ + "\62\3\2\2\2\u0173\u0174\t\32\2\2\u0174\64\3\2\2\2\u0175\u0176\t\33\2\2"+ + "\u0176\66\3\2\2\2\u0177\u0178\t\34\2\2\u01788\3\2\2\2\u0179\u017a\5+\26"+ + "\2\u017a\u017b\5-\27\2\u017b\u017c\5\r\7\2\u017c:\3\2\2\2\u017d\u017e"+ + "\5\r\7\2\u017e\u017f\5\37\20\2\u017f\u0180\5\r\7\2\u0180<\3\2\2\2\u0181"+ + "\u0182\5\31\r\2\u0182\u0183\5!\21\2\u0183\u0184\5)\25\2\u0184>\3\2\2\2"+ + "\u0185\u0186\5\17\b\2\u0186\u0187\5\r\7\2\u0187\u0188\5)\25\2\u0188@\3"+ + "\2\2\2\u0189\u018a\5\r\7\2\u018a\u018b\5\37\20\2\u018b\u018c\5\t\5\2\u018c"+ + "B\3\2\2\2\u018d\u018e\5\17\b\2\u018e\u018f\5\t\5\2\u018f\u0190\5\t\5\2"+ + "\u0190D\3\2\2\2\u0191\u0192\5!\21\2\u0192\u0193\5#\22\2\u0193\u0194\5"+ + "%\23\2\u0194F\3\2\2\2\u0195\u0196\5\37\20\2\u0196\u0197\5#\22\2\u0197"+ + "\u0198\5\61\31\2\u0198H\3\2\2\2\u0199\u019a\5+\26\2\u019a\u019b\5-\27"+ + "\2\u019b\u019c\5\t\5\2\u019c\u019d\5\65\33\2\u019dJ\3\2\2\2\u019e\u019f"+ + "\5\35\17\2\u019f\u01a0\5\17\b\2\u01a0\u01a1\5\t\5\2\u01a1\u01a2\5\65\33"+ + "\2\u01a2L\3\2\2\2\u01a3\u01a4\5\t\5\2\u01a4\u01a5\5\17\b\2\u01a5\u01a6"+ + "\5\17\b\2\u01a6N\3\2\2\2\u01a7\u01a8\5\t\5\2\u01a8\u01a9\5\17\b\2\u01a9"+ + "\u01aa\5\r\7\2\u01aaP\3\2\2\2\u01ab\u01ac\5+\26\2\u01ac\u01ad\5/\30\2"+ + "\u01ad\u01ae\5\13\6\2\u01aeR\3\2\2\2\u01af\u01b0\5+\26\2\u01b0\u01b1\5"+ + "\13\6\2\u01b1\u01b2\5\13\6\2\u01b2T\3\2\2\2\u01b3\u01b4\5\t\5\2\u01b4"+ + "\u01b5\5!\21\2\u01b5\u01b6\5\t\5\2\u01b6V\3\2\2\2\u01b7\u01b8\5\65\33"+ + "\2\u01b8\u01b9\5)\25\2\u01b9\u01ba\5\t\5\2\u01baX\3\2\2\2\u01bb\u01bc"+ + "\5#\22\2\u01bc\u01bd\5)\25\2\u01bd\u01be\5\t\5\2\u01beZ\3\2\2\2\u01bf"+ + "\u01c0\5\r\7\2\u01c0\u01c1\5\37\20\2\u01c1\u01c2\5%\23\2\u01c2\\\3\2\2"+ + "\2\u01c3\u01c4\5)\25\2\u01c4\u01c5\5\35\17\2\u01c5\u01c6\5\r\7\2\u01c6"+ + "^\3\2\2\2\u01c7\u01c8\5)\25\2\u01c8\u01c9\5)\25\2\u01c9\u01ca\5\r\7\2"+ + "\u01ca`\3\2\2\2\u01cb\u01cc\5)\25\2\u01cc\u01cd\5\t\5\2\u01cd\u01ce\5"+ + "\35\17\2\u01ceb\3\2\2\2\u01cf\u01d0\5)\25\2\u01d0\u01d1\5\t\5\2\u01d1"+ + "\u01d2\5)\25\2\u01d2d\3\2\2\2\u01d3\u01d4\5%\23\2\u01d4\u01d5\5/\30\2"+ + "\u01d5\u01d6\5+\26\2\u01d6\u01d7\5\27\f\2\u01d7f\3\2\2\2\u01d8\u01d9\5"+ + "%\23\2\u01d9\u01da\5#\22\2\u01da\u01db\5%\23\2\u01dbh\3\2\2\2\u01dc\u01dd"+ + "\5\17\b\2\u01dd\u01de\5\t\5\2\u01de\u01df\5\17\b\2\u01dfj\3\2\2\2\u01e0"+ + "\u01e1\5\31\r\2\u01e1\u01e2\5!\21\2\u01e2\u01e3\5\65\33\2\u01e3l\3\2\2"+ + "\2\u01e4\u01e5\5\17\b\2\u01e5\u01e6\5\r\7\2\u01e6\u01e7\5\65\33\2\u01e7"+ + "n\3\2\2\2\u01e8\u01e9\5\65\33\2\u01e9\u01ea\5\r\7\2\u01ea\u01eb\5\27\f"+ + "\2\u01eb\u01ec\5\25\13\2\u01ecp\3\2\2\2\u01ed\u01ee\5\65\33\2\u01ee\u01ef"+ + "\5-\27\2\u01ef\u01f0\5\27\f\2\u01f0\u01f1\5\35\17\2\u01f1r\3\2\2\2\u01f2"+ + "\u01f3\5+\26\2\u01f3\u01f4\5%\23\2\u01f4\u01f5\5\27\f\2\u01f5\u01f6\5"+ + "\35\17\2\u01f6t\3\2\2\2\u01f7\u01f8\5\35\17\2\u01f8\u01f9\5\65\33\2\u01f9"+ + "\u01fa\5\31\r\2\u01fav\3\2\2\2\u01fb\u01fc\5\37\20\2\u01fc\u01fd\5\61"+ + "\31\2\u01fd\u01fe\5\31\r\2\u01fex\3\2\2\2\u01ff\u0200\5\t\5\2\u0200\u0201"+ + "\5\17\b\2\u0201\u0202\5\31\r\2\u0202z\3\2\2\2\u0203\u0204\5\t\5\2\u0204"+ + "\u0205\5\r\7\2\u0205\u0206\5\31\r\2\u0206|\3\2\2\2\u0207\u0208\5+\26\2"+ + "\u0208\u0209\5/\30\2\u0209\u020a\5\31\r\2\u020a~\3\2\2\2\u020b\u020c\5"+ + "+\26\2\u020c\u020d\5\13\6\2\u020d\u020e\5\31\r\2\u020e\u0080\3\2\2\2\u020f"+ + "\u0210\5\t\5\2\u0210\u0211\5!\21\2\u0211\u0212\5\31\r\2\u0212\u0082\3"+ + "\2\2\2\u0213\u0214\5\65\33\2\u0214\u0215\5)\25\2\u0215\u0216\5\31\r\2"+ + "\u0216\u0084\3\2\2\2\u0217\u0218\5#\22\2\u0218\u0219\5)\25\2\u0219\u021a"+ + "\5\31\r\2\u021a\u0086\3\2\2\2\u021b\u021c\5\r\7\2\u021c\u021d\5%\23\2"+ + "\u021d\u021e\5\31\r\2\u021e\u0088\3\2\2\2\u021f\u0220\5+\26\2\u0220\u0221"+ + "\5-\27\2\u0221\u0222\5\t\5\2\u0222\u008a\3\2\2\2\u0223\u0224\5\35\17\2"+ + "\u0224\u0225\5\17\b\2\u0225\u0226\5\t\5\2\u0226\u008c\3\2\2\2\u0227\u0228"+ + "\5+\26\2\u0228\u0229\5\27\f\2\u0229\u022a\5\35\17\2\u022a\u022b\5\17\b"+ + "\2\u022b\u008e\3\2\2\2\u022c\u022d\5\35\17\2\u022d\u022e\5\27\f\2\u022e"+ + "\u022f\5\35\17\2\u022f\u0230\5\17\b\2\u0230\u0090\3\2\2\2\u0231\u0232"+ + "\5%\23\2\u0232\u0233\5\r\7\2\u0233\u0234\5\27\f\2\u0234\u0235\5\35\17"+ + "\2\u0235\u0092\3\2\2\2\u0236\u0237\5\33\16\2\u0237\u0238\5\37\20\2\u0238"+ + "\u0239\5%\23\2\u0239\u0094\3\2\2\2\u023a\u023b\5\33\16\2\u023b\u023c\5"+ + "\r\7\2\u023c\u0096\3\2\2\2\u023d\u023e\5\33\16\2\u023e\u023f\5!\21\2\u023f"+ + "\u0240\5\r\7\2\u0240\u0098\3\2\2\2\u0241\u0242\5\33\16\2\u0242\u0243\5"+ + "\67\34\2\u0243\u009a\3\2\2\2\u0244\u0245\5\33\16\2\u0245\u0246\5!\21\2"+ + "\u0246\u0247\5\67\34\2\u0247\u009c\3\2\2\2\u0248\u0249\5\33\16\2\u0249"+ + "\u024a\5%\23\2\u024a\u009e\3\2\2\2\u024b\u024c\5\33\16\2\u024c\u024d\5"+ + "\37\20\2\u024d\u00a0\3\2\2\2\u024e\u024f\5\33\16\2\u024f\u0250\5%\23\2"+ + "\u0250\u0251\5\21\t\2\u0251\u00a2\3\2\2\2\u0252\u0253\5\33\16\2\u0253"+ + "\u0254\5%\23\2\u0254\u0255\5#\22\2\u0255\u00a4\3\2\2\2\u0256\u0257\5\r"+ + "\7\2\u0257\u0258\5\t\5\2\u0258\u0259\5\35\17\2\u0259\u025a\5\35\17\2\u025a"+ + "\u00a6\3\2\2\2\u025b\u025c\5\r\7\2\u025c\u025d\5\r\7\2\u025d\u00a8\3\2"+ + "\2\2\u025e\u025f\5\r\7\2\u025f\u0260\5!\21\2\u0260\u0261\5\r\7\2\u0261"+ + "\u00aa\3\2\2\2\u0262\u0263\5\r\7\2\u0263\u0264\5\67\34\2\u0264\u00ac\3"+ + "\2\2\2\u0265\u0266\5\r\7\2\u0266\u0267\5!\21\2\u0267\u0268\5\67\34\2\u0268"+ + "\u00ae\3\2\2\2\u0269\u026a\5\r\7\2\u026a\u026b\5%\23\2\u026b\u00b0\3\2"+ + "\2\2\u026c\u026d\5\r\7\2\u026d\u026e\5\37\20\2\u026e\u00b2\3\2\2\2\u026f"+ + "\u0270\5\r\7\2\u0270\u0271\5%\23\2\u0271\u0272\5\21\t\2\u0272\u00b4\3"+ + "\2\2\2\u0273\u0274\5\r\7\2\u0274\u0275\5%\23\2\u0275\u0276\5#\22\2\u0276"+ + "\u00b6\3\2\2\2\u0277\u0278\5)\25\2\u0278\u0279\5\21\t\2\u0279\u027a\5"+ + "-\27\2\u027a\u00b8\3\2\2\2\u027b\u027c\5)\25\2\u027c\u027d\5\r\7\2\u027d"+ + "\u00ba\3\2\2\2\u027e\u027f\5)\25\2\u027f\u0280\5!\21\2\u0280\u0281\5\r"+ + "\7\2\u0281\u00bc\3\2\2\2\u0282\u0283\5)\25\2\u0283\u0284\5\67\34\2\u0284"+ + "\u00be\3\2\2\2\u0285\u0286\5)\25\2\u0286\u0287\5!\21\2\u0287\u0288\5\67"+ + "\34\2\u0288\u00c0\3\2\2\2\u0289\u028a\5)\25\2\u028a\u028b\5\37\20\2\u028b"+ + "\u00c2\3\2\2\2\u028c\u028d\5)\25\2\u028d\u028e\5%\23\2\u028e\u00c4\3\2"+ + "\2\2\u028f\u0290\5)\25\2\u0290\u0291\5%\23\2\u0291\u0292\5\21\t\2\u0292"+ + "\u00c6\3\2\2\2\u0293\u0294\5)\25\2\u0294\u0295\5%\23\2\u0295\u0296\5#"+ + "\22\2\u0296\u00c8\3\2\2\2\u0297\u0298\5)\25\2\u0298\u0299\5+\26\2\u0299"+ + "\u029a\5-\27\2\u029a\u00ca\3\2\2\2\u029b\u029c\5\21\t\2\u029c\u029d\5"+ + "\31\r\2\u029d\u00cc\3\2\2\2\u029e\u029f\5\17\b\2\u029f\u02a0\5\31\r\2"+ + "\u02a0\u00ce\3\2\2\2\u02a1\u02a2\5\31\r\2\u02a2\u02a3\5!\21\2\u02a3\u00d0"+ + "\3\2\2\2\u02a4\u02a5\5#\22\2\u02a5\u02a6\5/\30\2\u02a6\u02a7\5-\27\2\u02a7"+ + "\u00d2\3\2\2\2\u02a8\u02a9\5\27\f\2\u02a9\u02aa\5\35\17\2\u02aa\u02ab"+ + "\5-\27\2\u02ab\u00d4\3\2\2\2\u02ac\u02ad\5#\22\2\u02ad\u02ae\5)\25\2\u02ae"+ + "\u02af\5\25\13\2\u02af\u00d6\3\2\2\2\u02b0\u02b1\5\21\t\2\u02b1\u02b2"+ + "\5\'\24\2\u02b2\u02b3\5/\30\2\u02b3\u00d8\3\2\2\2\u02b4\u02b5\5+\26\2"+ + "\u02b5\u02b6\5\21\t\2\u02b6\u02b7\5-\27\2\u02b7\u00da\3\2\2\2\u02b8\u02b9"+ + "\5\31\r\2\u02b9\u02ba\5!\21\2\u02ba\u02bb\5\r\7\2\u02bb\u02bc\5\35\17"+ + "\2\u02bc\u02bd\5/\30\2\u02bd\u02be\5\17\b\2\u02be\u02bf\5\21\t\2\u02bf"+ + "\u00dc\3\2\2\2\u02c0\u02c1\5\31\r\2\u02c1\u02c2\5\23\n\2\u02c2\u00de\3"+ + "\2\2\2\u02c3\u02c4\5\21\t\2\u02c4\u02c5\5!\21\2\u02c5\u02c6\5\17\b\2\u02c6"+ + "\u02c7\5\31\r\2\u02c7\u02c8\5\23\n\2\u02c8\u00e0\3\2\2\2\u02c9\u02ca\5"+ + "\37\20\2\u02ca\u02cb\5\t\5\2\u02cb\u02cc\5\r\7\2\u02cc\u02cd\5)\25\2\u02cd"+ + "\u02ce\5#\22\2\u02ce\u00e2\3\2\2\2\u02cf\u02d0\5\21\t\2\u02d0\u02d1\5"+ + "!\21\2\u02d1\u02d2\5\17\b\2\u02d2\u02d3\5\37\20\2\u02d3\u00e4\3\2\2\2"+ + "\u02d4\u02d5\5\17\b\2\u02d5\u02d6\5\13\6\2\u02d6\u00e6\3\2\2\2\u02d7\u02d8"+ + "\5\17\b\2\u02d8\u02d9\5\63\32\2\u02d9\u00e8\3\2\2\2\u02da\u02db\5\17\b"+ + "\2\u02db\u02dc\5+\26\2\u02dc\u00ea\3\2\2\2\u02dd\u02de\7&\2\2\u02de\u00ec"+ + "\3\2\2\2\u02df\u02e0\5\t\5\2\u02e0\u00ee\3\2\2\2\u02e1\u02e2\5\13\6\2"+ + "\u02e2\u00f0\3\2\2\2\u02e3\u02e4\5\r\7\2\u02e4\u00f2\3\2\2\2\u02e5\u02e6"+ + "\5\17\b\2\u02e6\u00f4\3\2\2\2\u02e7\u02e8\5\21\t\2\u02e8\u00f6\3\2\2\2"+ + "\u02e9\u02ea\5\27\f\2\u02ea\u00f8\3\2\2\2\u02eb\u02ec\5\35\17\2\u02ec"+ + "\u00fa\3\2\2\2\u02ed\u02ee\5\37\20\2\u02ee\u00fc\3\2\2\2\u02ef\u02f0\5"+ + "%\23\2\u02f0\u02f1\5+\26\2\u02f1\u02f2\5\63\32\2\u02f2\u00fe\3\2\2\2\u02f3"+ + "\u02f4\5+\26\2\u02f4\u02f5\5%\23\2\u02f5\u0100\3\2\2\2\u02f6\u02f7\7*"+ + "\2\2\u02f7\u0102\3\2\2\2\u02f8\u02f9\7+\2\2\u02f9\u0104\3\2\2\2\u02fa"+ + "\u02fb\7.\2\2\u02fb\u0106\3\2\2\2\u02fc\u02fd\7-\2\2\u02fd\u0108\3\2\2"+ + "\2\u02fe\u02ff\7/\2\2\u02ff\u010a\3\2\2\2\u0300\u0301\7,\2\2\u0301\u010c"+ + "\3\2\2\2\u0302\u0303\7\61\2\2\u0303\u010e\3\2\2\2\u0304\u0305\7?\2\2\u0305"+ + "\u0110\3\2\2\2\u0306\u0307\5\37\20\2\u0307\u0308\5#\22\2\u0308\u0309\5"+ + "\17\b\2\u0309\u0112\3\2\2\2\u030a\u030b\5+\26\2\u030b\u030c\5\27\f\2\u030c"+ + "\u030d\5)\25\2\u030d\u0114\3\2\2\2\u030e\u030f\5+\26\2\u030f\u0310\5\27"+ + "\f\2\u0310\u0311\5\35\17\2\u0311\u0116\3\2\2\2\u0312\u0313\5!\21\2\u0313"+ + "\u0314\5#\22\2\u0314\u0315\5-\27\2\u0315\u0118\3\2\2\2\u0316\u0317\5\t"+ + "\5\2\u0317\u0318\5!\21\2\u0318\u0319\5\17\b\2\u0319\u011a\3\2\2\2\u031a"+ + "\u031b\5#\22\2\u031b\u031c\5)\25\2\u031c\u011c\3\2\2\2\u031d\u031e\5\65"+ + "\33\2\u031e\u031f\5#\22\2\u031f\u0320\5)\25\2\u0320\u011e\3\2\2\2\u0321"+ + "\u0323\t\35\2\2\u0322\u0321\3\2\2\2\u0322\u0323\3\2\2\2\u0323\u0325\3"+ + "\2\2\2\u0324\u0326\t\36\2\2\u0325\u0324\3\2\2\2\u0326\u0327\3\2\2\2\u0327"+ + "\u0325\3\2\2\2\u0327\u0328\3\2\2\2\u0328\u032a\3\2\2\2\u0329\u032b\5\17"+ + "\b\2\u032a\u0329\3\2\2\2\u032a\u032b\3\2\2\2\u032b\u0120\3\2\2\2\u032c"+ + "\u032e\t\35\2\2\u032d\u032c\3\2\2\2\u032d\u032e\3\2\2\2\u032e\u0333\3"+ + "\2\2\2\u032f\u0330\7\62\2\2\u0330\u0334\7z\2\2\u0331\u0332\7\62\2\2\u0332"+ + "\u0334\7Z\2\2\u0333\u032f\3\2\2\2\u0333\u0331\3\2\2\2\u0334\u0336\3\2"+ + "\2\2\u0335\u0337\t\37\2\2\u0336\u0335\3\2\2\2\u0337\u0338\3\2\2\2\u0338"+ + "\u0336\3\2\2\2\u0338\u0339\3\2\2\2\u0339\u0122\3\2\2\2\u033a\u033c\t\35"+ + "\2\2\u033b\u033a\3\2\2\2\u033b\u033c\3\2\2\2\u033c\u033e\3\2\2\2\u033d"+ + "\u033f\t\37\2\2\u033e\u033d\3\2\2\2\u033f\u0340\3\2\2\2\u0340\u033e\3"+ + "\2\2\2\u0340\u0341\3\2\2\2\u0341\u0342\3\2\2\2\u0342\u0343\5\27\f\2\u0343"+ + "\u0124\3\2\2\2\u0344\u0346\t\35\2\2\u0345\u0344\3\2\2\2\u0345\u0346\3"+ + "\2\2\2\u0346\u0348\3\2\2\2\u0347\u0349\t \2\2\u0348\u0347\3\2\2\2\u0349"+ + "\u034a\3\2\2\2\u034a\u0348\3\2\2\2\u034a\u034b\3\2\2\2\u034b\u034c\3\2"+ + "\2\2\u034c\u034d\t!\2\2\u034d\u0126\3\2\2\2\u034e\u0350\t\"\2\2\u034f"+ + "\u034e\3\2\2\2\u0350\u0351\3\2\2\2\u0351\u034f\3\2\2\2\u0351\u0352\3\2"+ + "\2\2\u0352\u0353\3\2\2\2\u0353\u0354\5\13\6\2\u0354\u0128\3\2\2\2\u0355"+ + "\u0357\t#\2\2\u0356\u0358\t$\2\2\u0357\u0356\3\2\2\2\u0358\u0359\3\2\2"+ + "\2\u0359\u0357\3\2\2\2\u0359\u035a\3\2\2\2\u035a\u035b\3\2\2\2\u035b\u035c"+ + "\t#\2\2\u035c\u012a\3\2\2\2\u035d\u035f\7$\2\2\u035e\u0360\t%\2\2\u035f"+ + "\u035e\3\2\2\2\u0360\u0361\3\2\2\2\u0361\u035f\3\2\2\2\u0361\u0362\3\2"+ + "\2\2\u0362\u0363\3\2\2\2\u0363\u0364\7$\2\2\u0364\u012c\3\2\2\2\u0365"+ + "\u0369\t&\2\2\u0366\u0368\t\'\2\2\u0367\u0366\3\2\2\2\u0368\u036b\3\2"+ + "\2\2\u0369\u0367\3\2\2\2\u0369\u036a\3\2\2\2\u036a\u012e\3\2\2\2\u036b"+ + "\u0369\3\2\2\2\u036c\u0370\t&\2\2\u036d\u036f\t\'\2\2\u036e\u036d\3\2"+ + "\2\2\u036f\u0372\3\2\2\2\u0370\u036e\3\2\2\2\u0370\u0371\3\2\2\2\u0371"+ + "\u0373\3\2\2\2\u0372\u0370\3\2\2\2\u0373\u0374\7<\2\2\u0374\u0130\3\2"+ + "\2\2\u0375\u0376\13\2\2\2\u0376\u0132\3\2\2\2\25\2\u013c\u0141\u0145\u0322"+ + "\u0327\u032a\u032d\u0333\u0338\u033b\u0340\u0345\u034a\u0351\u0359\u0361"+ + "\u0369\u0370\3\2\3\2"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.tokens b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.tokens new file mode 100644 index 000000000..a522a3c4c --- /dev/null +++ b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.tokens @@ -0,0 +1,137 @@ +WS=1 +COMMENT=2 +EOL=3 +OPCODE_STC=4 +OPCODE_CMC=5 +OPCODE_INR=6 +OPCODE_DCR=7 +OPCODE_CMA=8 +OPCODE_DAA=9 +OPCODE_NOP=10 +OPCODE_MOV=11 +OPCODE_STAX=12 +OPCODE_LDAX=13 +OPCODE_ADD=14 +OPCODE_ADC=15 +OPCODE_SUB=16 +OPCODE_SBB=17 +OPCODE_ANA=18 +OPCODE_XRA=19 +OPCODE_ORA=20 +OPCODE_CMP=21 +OPCODE_RLC=22 +OPCODE_RRC=23 +OPCODE_RAL=24 +OPCODE_RAR=25 +OPCODE_PUSH=26 +OPCODE_POP=27 +OPCODE_DAD=28 +OPCODE_INX=29 +OPCODE_DCX=30 +OPCODE_XCHG=31 +OPCODE_XTHL=32 +OPCODE_SPHL=33 +OPCODE_LXI=34 +OPCODE_MVI=35 +OPCODE_ADI=36 +OPCODE_ACI=37 +OPCODE_SUI=38 +OPCODE_SBI=39 +OPCODE_ANI=40 +OPCODE_XRI=41 +OPCODE_ORI=42 +OPCODE_CPI=43 +OPCODE_STA=44 +OPCODE_LDA=45 +OPCODE_SHLD=46 +OPCODE_LHLD=47 +OPCODE_PCHL=48 +OPCODE_JMP=49 +OPCODE_JC=50 +OPCODE_JNC=51 +OPCODE_JZ=52 +OPCODE_JNZ=53 +OPCODE_JP=54 +OPCODE_JM=55 +OPCODE_JPE=56 +OPCODE_JPO=57 +OPCODE_CALL=58 +OPCODE_CC=59 +OPCODE_CNC=60 +OPCODE_CZ=61 +OPCODE_CNZ=62 +OPCODE_CP=63 +OPCODE_CM=64 +OPCODE_CPE=65 +OPCODE_CPO=66 +OPCODE_RET=67 +OPCODE_RC=68 +OPCODE_RNC=69 +OPCODE_RZ=70 +OPCODE_RNZ=71 +OPCODE_RM=72 +OPCODE_RP=73 +OPCODE_RPE=74 +OPCODE_RPO=75 +OPCODE_RST=76 +OPCODE_EI=77 +OPCODE_DI=78 +OPCODE_IN=79 +OPCODE_OUT=80 +OPCODE_HLT=81 +PREP_ORG=82 +PREP_EQU=83 +PREP_SET=84 +PREP_INCLUDE=85 +PREP_IF=86 +PREP_ENDIF=87 +PREP_MACRO=88 +PREP_ENDM=89 +PREP_DB=90 +PREP_DW=91 +PREP_DS=92 +PREP_ADDR=93 +REG_A=94 +REG_B=95 +REG_C=96 +REG_D=97 +REG_E=98 +REG_H=99 +REG_L=100 +REG_M=101 +REG_PSW=102 +REG_SP=103 +SEP_LPAR=104 +SEP_RPAR=105 +SEP_COMMA=106 +OP_ADD=107 +OP_SUBTRACT=108 +OP_MULTIPLY=109 +OP_DIVIDE=110 +OP_EQUAL=111 +OP_MOD=112 +OP_SHR=113 +OP_SHL=114 +OP_NOT=115 +OP_AND=116 +OP_OR=117 +OP_XOR=118 +LIT_NUMBER=119 +LIT_HEXNUMBER_1=120 +LIT_HEXNUMBER_2=121 +LIT_OCTNUMBER=122 +LIT_BINNUMBER=123 +LIT_STRING_1=124 +LIT_STRING_2=125 +ID_IDENTIFIER=126 +ID_LABEL=127 +ERROR=128 +'$'=93 +'('=104 +')'=105 +','=106 +'+'=107 +'-'=108 +'*'=109 +'/'=110 +'='=111 diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java index 60d20ffc1..74480d67f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java @@ -28,7 +28,7 @@ import net.emustudio.emulib.runtime.ContextNotFoundException; import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.tree.Statement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java index 0163a524c..ce5567a10 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.ValueTooBigException; import net.emustudio.plugins.compiler.as8080.treeAbstract.DataValueNode; @@ -81,9 +81,9 @@ public void pass4(IntelHEX hex) throws Exception { if (expression.getValue() < -128) { throw new ValueTooBigException(line, column, expression.getValue(), -128); } - hex.putCode(expression.getEncValue(true)); + hex.add(expression.getEncValue(true)); } else if (literalString != null) { - hex.putCode(this.getEncString(literalString)); + hex.add(this.getEncString(literalString)); } else if (opcode != null) { opcode.pass4(hex); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java index d9e0bedba..cc15e7b46 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.AmbiguousException; import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; @@ -62,7 +62,7 @@ public void pass4(IntelHEX hex) throws Exception { } str.append("00".repeat(Math.max(0, expression.getValue()))); - hex.putCode(str.toString()); + hex.add(str.toString()); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java index 428259064..bc739b157 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.ValueTooBigException; import net.emustudio.plugins.compiler.as8080.treeAbstract.DataValueNode; @@ -52,7 +52,7 @@ public void pass4(IntelHEX hex) throws Exception { throw new ValueTooBigException(line, column, expression.getValue(), -32768); } - hex.putCode(expression.getEncValue(false)); + hex.add(expression.getEncValue(false)); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java index 3e5e14fd9..60aeb5bbb 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.treeAbstract.CodeNode; import net.emustudio.plugins.compiler.as8080.treeAbstract.DataValueNode; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java index e57ff2f9f..d40221ebb 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.AlreadyDefinedException; import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java index e7f61e385..705d0e1c7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.AmbiguousException; import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java index 420d053a9..242bcf370 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java @@ -18,11 +18,9 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.CompilerImpl; -import net.emustudio.plugins.compiler.as8080.LexerImpl; import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.ParserImpl; import net.emustudio.plugins.compiler.as8080.exceptions.CompilerException; import net.emustudio.plugins.compiler.as8080.exceptions.UnexpectedEOFException; import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoNode; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java index 6379f1eeb..ce938e65a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; import net.emustudio.plugins.compiler.as8080.treeAbstract.CodePseudoNode; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java index 145fd80c8..16a233da1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.AmbiguousException; import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; @@ -80,7 +80,7 @@ public String getName() { @Override public void pass4(IntelHEX hex) { - hex.addTable(statHex.getTable()); + hex.add(statHex.getTable()); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java index 6c40abe24..2237032b4 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.InvalidMacroParamsCountException; import net.emustudio.plugins.compiler.as8080.exceptions.UnknownMacroParametersException; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java index 57bb37d86..4768be422 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.ValueTooBigException; import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; @@ -191,7 +191,7 @@ public void pass4(IntelHEX hex) throws Exception { code += expr.getEncValue(false); } } - hex.putCode(code); + hex.add(code); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java index ac9367262..8832aa39e 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; @@ -118,7 +118,7 @@ public void pass4(IntelHEX hex) { opCode = 118; break; } - hex.putCode(String.format("%1$02X", opCode)); + hex.add(String.format("%1$02X", opCode)); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java index 7d552feb8..7e31d34ae 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; @@ -77,7 +77,7 @@ public void pass4(IntelHEX hex) { break; } - hex.putCode(String.format("%1$02X", opCode)); + hex.add(String.format("%1$02X", opCode)); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java index 5c4012e94..554485c07 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.ValueTooBigException; import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; @@ -59,8 +59,8 @@ public void pass4(IntelHEX hex) throws Exception { throw new ValueTooBigException(line, column, expr.getValue(), 0xFF); } opCode |= (reg << 3); - hex.putCode(String.format("%1$02X", opCode)); - hex.putCode(expr.getEncValue(true)); + hex.add(String.format("%1$02X", opCode)); + hex.add(expr.getEncValue(true)); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java index 4e05352d1..b04d8eb5e 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.CompilerException; import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; @@ -53,7 +53,7 @@ public void pass4(IntelHEX hex) { int opCode = 64; opCode |= (reg_dst << 3); opCode |= reg_src; - hex.putCode(String.format("%1$02X", opCode)); + hex.add(String.format("%1$02X", opCode)); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java index cad454f03..f69fa7b62 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; @@ -68,7 +68,7 @@ public void pass4(IntelHEX hex) { break; } - hex.putCode(String.format("%1$02X", opCode)); + hex.add(String.format("%1$02X", opCode)); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java index d7689c43c..dc45ed710 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; @@ -48,8 +48,8 @@ public int pass2(Namespace parentEnv, int addr_start) throws Exception { @Override public void pass4(IntelHEX hex) { int opCode = 1 | (regpair << 4); - hex.putCode(String.format("%1$02X", opCode)); - hex.putCode(expr.getEncValue(false)); + hex.add(String.format("%1$02X", opCode)); + hex.add(expr.getEncValue(false)); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java index 97afa7ff5..b60ce9000 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.AmbiguousException; import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java index 1608fcf47..78e6f6163 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.AlreadyDefinedException; import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/Statement.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/Statement.java index e205cfaf0..f5ac361b6 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/Statement.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/Statement.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoBlock; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodePseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodePseudoNode.java index 539a80c8d..fbf7aeadd 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodePseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodePseudoNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.treeAbstract; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; public abstract class CodePseudoNode { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/DataValueNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/DataValueNode.java index da7a9c4ab..468ee65df 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/DataValueNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/DataValueNode.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.treeAbstract; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; public abstract class DataValueNode { diff --git a/plugins/compiler/as-ssem/build.gradle b/plugins/compiler/as-ssem/build.gradle index e5b0e6a75..5575363ce 100644 --- a/plugins/compiler/as-ssem/build.gradle +++ b/plugins/compiler/as-ssem/build.gradle @@ -32,7 +32,6 @@ dependencies { implementation libs.emuLib implementation libs.slf4JApi implementation libs.jcipAnnotations - implementation libs.javaCupRuntime testImplementation libs.cpuTestSuite testImplementation libs.junit @@ -95,7 +94,6 @@ copy { into "$buildDir/libs/scripts" } - test { testLogging { events "passed", "skipped", "failed" diff --git a/settings.gradle b/settings.gradle index de5615a93..49e706ab1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,7 +26,7 @@ rootProject.name = 'emuStudio' include ':application' -//include ':plugins:compiler:as-8080' +include ':plugins:compiler:as-8080' include ':plugins:compiler:as-ssem' //include ':plugins:compiler:as-z80' //include ':plugins:compiler:brainc-brainduck' @@ -52,5 +52,5 @@ include ':plugins:device:ssem-display' //include ':plugins:memory:ram-mem' //include ':plugins:memory:rasp-mem' include ':plugins:memory:ssem-mem' -//include ':plugins:memory:byte-mem' +include ':plugins:memory:byte-mem' From 0b4ed48266a3bd9dabbd5821c19320624dc53ad0 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 3 Oct 2021 11:24:08 +0200 Subject: [PATCH 042/314] [#201] WIP --- .../as-8080/src/main/antlr/As8080Lexer.g4 | 5 +- .../as-8080/src/main/antlr/As8080Parser.g4 | 207 ++++--- .../as-8080/src/main/gen/As8080Lexer.interp | 2 +- .../as-8080/src/main/gen/As8080Lexer.java | 528 +++++++++--------- .../compiler/as8080/Assembler8080.java | 246 ++++++++ .../plugins/compiler/as8080/CompilerImpl.java | 192 ------- .../compiler/as8080/LexicalAnalyzerImpl.java | 194 +++++++ .../compiler/as8080/ParserErrorListener.java | 19 + .../plugins/compiler/as8080/Runner.java | 4 +- .../plugins/compiler/as8080/TokenImpl.java | 100 ---- .../compiler/as8080/ast/AbstractNode.java | 20 + .../compiler/as8080/ast/NameSpace.java | 17 + .../plugins/compiler/as8080/ast/Node.java | 10 + .../plugins/compiler/as8080/ast/Program.java | 9 + .../compiler/as8080/ast/data/Data.java | 6 + .../compiler/as8080/ast/data/DataDB.java | 4 + .../compiler/as8080/ast/data/DataDS.java | 9 + .../compiler/as8080/ast/data/DataDW.java | 4 + .../compiler/as8080/ast/expr/Expr.java | 6 + .../compiler/as8080/ast/expr/ExprBin.java | 10 + .../as8080/ast/expr/ExprCurrentAddress.java | 4 + .../compiler/as8080/ast/expr/ExprDec.java | 10 + .../compiler/as8080/ast/expr/ExprHex1.java | 10 + .../compiler/as8080/ast/expr/ExprHex2.java | 10 + .../compiler/as8080/ast/expr/ExprId.java | 13 + .../compiler/as8080/ast/expr/ExprInfix.java | 10 + .../compiler/as8080/ast/expr/ExprOct.java | 10 + .../compiler/as8080/ast/expr/ExprParens.java | 4 + .../compiler/as8080/ast/expr/ExprUnary.java | 8 + .../compiler/as8080/ast/instr/Instr.java | 6 + .../compiler/as8080/ast/instr/InstrExpr.java | 16 + .../as8080/ast/instr/InstrNoArgs.java | 15 + .../compiler/as8080/ast/instr/InstrReg.java | 10 + .../as8080/ast/instr/InstrRegExpr.java | 11 + .../as8080/ast/instr/InstrRegPair.java | 10 + .../as8080/ast/instr/InstrRegPairExpr.java | 11 + .../as8080/ast/instr/InstrRegReg.java | 10 + .../compiler/as8080/ast/pseudo/Pseudo.java | 6 + .../compiler/as8080/ast/pseudo/PseudoEqu.java | 11 + .../compiler/as8080/ast/pseudo/PseudoIf.java | 10 + .../as8080/ast/pseudo/PseudoInclude.java | 4 + .../as8080/ast/pseudo/PseudoMacroCall.java | 4 + .../as8080/ast/pseudo/PseudoMacroDef.java | 4 + .../compiler/as8080/ast/pseudo/PseudoOrg.java | 11 + .../compiler/as8080/ast/pseudo/PseudoSet.java | 10 + .../exceptions/AlreadyDefinedException.java | 2 +- .../as8080/exceptions/AmbiguousException.java | 2 +- ...erException.java => CompileException.java} | 18 +- .../InvalidMacroParamsCountException.java | 2 +- .../exceptions/NeedMorePassException.java | 2 +- .../exceptions/NegativeValueException.java | 2 +- .../exceptions/UndefinedMacroException.java | 2 +- .../exceptions/UnexpectedEOFException.java | 2 +- .../UnknownMacroParametersException.java | 2 +- .../exceptions/ValueTooBigException.java | 2 +- .../as8080/tree/IncludePseudoNode.java | 70 +-- .../compiler/as8080/tree/MacroCallPseudo.java | 2 +- .../compiler/as8080/tree/OC_RegReg.java | 4 +- .../compiler/as8080/visitors/AllVisitors.java | 10 + .../as8080/visitors/CreateProgramVisitor.java | 21 + .../compiler/as8080/visitors/DataVisitor.java | 27 + .../compiler/as8080/visitors/ExprVisitor.java | 53 ++ .../as8080/visitors/InstrVisitor.java | 43 ++ .../as8080/visitors/PseudoVisitor.java | 43 ++ .../as8080/visitors/StatementVisitor.java | 22 + .../compiler/as8080/AbstractCompilerTest.java | 10 +- ...erImplTest.java => Assembler8080Test.java} | 4 +- .../as8080/ConstantsAndVariablesTest.java | 2 + .../plugins/compiler/as8080/DataTest.java | 6 +- .../plugins/compiler/as8080/IfNodeTest.java | 2 + .../plugins/compiler/as8080/IncludeTest.java | 2 + .../plugins/compiler/as8080/LexerTest.java | 70 +++ .../plugins/compiler/as8080/MacroTest.java | 2 + .../plugins/compiler/as8080/OC_ExprTest.java | 2 + .../plugins/compiler/as8080/OC_RegTest.java | 2 + .../plugins/compiler/as8080/ORGTest.java | 6 +- .../plugins/compiler/as8080/RunnerTest.java | 2 + .../plugins/compiler/as8080/Utils.java | 55 ++ 78 files changed, 1581 insertions(+), 735 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/TokenImpl.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/AbstractNode.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprBin.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprDec.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex1.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex2.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprOct.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprParens.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/{CompilerException.java => CompileException.java} (73%) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{CompilerImplTest.java => Assembler8080Test.java} (97%) create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 index ead226d5e..b12934b6e 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 @@ -1,5 +1,8 @@ lexer grammar As8080Lexer; +options { + backtrack=false; +} WS : (' ' | '\t' | '\f') -> channel(HIDDEN); COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]*; @@ -158,7 +161,7 @@ OP_XOR: X O R; // literals LIT_NUMBER: [\-]? [0-9]+ D?; -LIT_HEXNUMBER_1: [\-]? ('0x'|'0X') [0-9a-fA-F]+; +LIT_HEXNUMBER_1: [\-]? '0' X [0-9a-fA-F]+; LIT_HEXNUMBER_2: [\-]? [0-9a-fA-F]+ H; LIT_OCTNUMBER: [\-]? [0-7]+ [oOqQ]; LIT_BINNUMBER: [01]+ B; diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index ac1df0f81..da53d4e15 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -23,84 +23,84 @@ rStatement: ; rInstruction: - opcode=OPCODE_STC - | opcode=OPCODE_CMC - | opcode=OPCODE_CMA - | opcode=OPCODE_DAA - | opcode=OPCODE_NOP - | opcode=OPCODE_RLC - | opcode=OPCODE_RRC - | opcode=OPCODE_RAL - | opcode=OPCODE_RAR - | opcode=OPCODE_XCHG - | opcode=OPCODE_XTHL - | opcode=OPCODE_SPHL - | opcode=OPCODE_PCHL - | opcode=OPCODE_RET - | opcode=OPCODE_RC - | opcode=OPCODE_RNC - | opcode=OPCODE_RZ - | opcode=OPCODE_RNZ - | opcode=OPCODE_RM - | opcode=OPCODE_RP - | opcode=OPCODE_RPE - | opcode=OPCODE_RPO - | opcode=OPCODE_EI - | opcode=OPCODE_DI - | opcode=OPCODE_HLT - | opcode=OPCODE_INR reg=rRegister - | opcode=OPCODE_DCR reg=rRegister - | opcode=OPCODE_ADD reg=rRegister - | opcode=OPCODE_ADC reg=rRegister - | opcode=OPCODE_SUB reg=rRegister - | opcode=OPCODE_SBB reg=rRegister - | opcode=OPCODE_ANA reg=rRegister - | opcode=OPCODE_XRA reg=rRegister - | opcode=OPCODE_ORA reg=rRegister - | opcode=OPCODE_CMP reg=rRegister - | opcode=OPCODE_MOV dst=rRegister SEP_COMMA src=rRegister - | opcode=OPCODE_STAX regpair=(REG_B|REG_D) - | opcode=OPCODE_LDAX regpair=(REG_B|REG_D) - | opcode=OPCODE_PUSH regpair=(REG_B|REG_D|REG_H|REG_PSW) - | opcode=OPCODE_POP regpair=(REG_B|REG_D|REG_H|REG_PSW) - | opcode=OPCODE_DAD regpair=(REG_B|REG_D|REG_H|REG_SP) - | opcode=OPCODE_INX regpair=(REG_B|REG_D|REG_H|REG_SP) - | opcode=OPCODE_DCX regpair=(REG_B|REG_D|REG_H|REG_SP) - | opcode=OPCODE_LXI regpair=(REG_B|REG_D|REG_H|REG_SP) SEP_COMMA expr=rExpression - | opcode=OPCODE_MVI reg=rRegister SEP_COMMA expr=rExpression - | opcode=OPCODE_ADI expr=rExpression - | opcode=OPCODE_ACI expr=rExpression - | opcode=OPCODE_SUI expr=rExpression - | opcode=OPCODE_SBI expr=rExpression - | opcode=OPCODE_ANI expr=rExpression - | opcode=OPCODE_XRI expr=rExpression - | opcode=OPCODE_ORI expr=rExpression - | opcode=OPCODE_CPI expr=rExpression - | opcode=OPCODE_STA expr=rExpression - | opcode=OPCODE_LDA expr=rExpression - | opcode=OPCODE_SHLD expr=rExpression - | opcode=OPCODE_LHLD expr=rExpression - | opcode=OPCODE_JMP expr=rExpression - | opcode=OPCODE_JC expr=rExpression - | opcode=OPCODE_JNC expr=rExpression - | opcode=OPCODE_JZ expr=rExpression - | opcode=OPCODE_JNZ expr=rExpression - | opcode=OPCODE_JM expr=rExpression - | opcode=OPCODE_JP expr=rExpression - | opcode=OPCODE_JPE expr=rExpression - | opcode=OPCODE_JPO expr=rExpression - | opcode=OPCODE_CALL expr=rExpression - | opcode=OPCODE_CC expr=rExpression - | opcode=OPCODE_CNC expr=rExpression - | opcode=OPCODE_CZ expr=rExpression - | opcode=OPCODE_CNZ expr=rExpression - | opcode=OPCODE_CM expr=rExpression - | opcode=OPCODE_CP expr=rExpression - | opcode=OPCODE_CPE expr=rExpression - | opcode=OPCODE_CPO expr=rExpression - | opcode=OPCODE_RST expr=rExpression - | opcode=OPCODE_IN expr=rExpression - | opcode=OPCODE_OUT expr=rExpression + opcode=OPCODE_STC # instrNoArgs + | opcode=OPCODE_CMC # instrNoArgs + | opcode=OPCODE_CMA # instrNoArgs + | opcode=OPCODE_DAA # instrNoArgs + | opcode=OPCODE_NOP # instrNoArgs + | opcode=OPCODE_RLC # instrNoArgs + | opcode=OPCODE_RRC # instrNoArgs + | opcode=OPCODE_RAL # instrNoArgs + | opcode=OPCODE_RAR # instrNoArgs + | opcode=OPCODE_XCHG # instrNoArgs + | opcode=OPCODE_XTHL # instrNoArgs + | opcode=OPCODE_SPHL # instrNoArgs + | opcode=OPCODE_PCHL # instrNoArgs + | opcode=OPCODE_RET # instrNoArgs + | opcode=OPCODE_RC # instrNoArgs + | opcode=OPCODE_RNC # instrNoArgs + | opcode=OPCODE_RZ # instrNoArgs + | opcode=OPCODE_RNZ # instrNoArgs + | opcode=OPCODE_RM # instrNoArgs + | opcode=OPCODE_RP # instrNoArgs + | opcode=OPCODE_RPE # instrNoArgs + | opcode=OPCODE_RPO # instrNoArgs + | opcode=OPCODE_EI # instrNoArgs + | opcode=OPCODE_DI # instrNoArgs + | opcode=OPCODE_HLT # instrNoArgs + | opcode=OPCODE_INR reg=rRegister # instrReg + | opcode=OPCODE_DCR reg=rRegister # instrReg + | opcode=OPCODE_ADD reg=rRegister # instrReg + | opcode=OPCODE_ADC reg=rRegister # instrReg + | opcode=OPCODE_SUB reg=rRegister # instrReg + | opcode=OPCODE_SBB reg=rRegister # instrReg + | opcode=OPCODE_ANA reg=rRegister # instrReg + | opcode=OPCODE_XRA reg=rRegister # instrReg + | opcode=OPCODE_ORA reg=rRegister # instrReg + | opcode=OPCODE_CMP reg=rRegister # instrReg + | opcode=OPCODE_MOV dst=rRegister SEP_COMMA src=rRegister # instrRegReg + | opcode=OPCODE_STAX regpair=(REG_B|REG_D) # instrRegPair + | opcode=OPCODE_LDAX regpair=(REG_B|REG_D) # instrRegPair + | opcode=OPCODE_PUSH regpair=(REG_B|REG_D|REG_H|REG_PSW) # instrRegPair + | opcode=OPCODE_POP regpair=(REG_B|REG_D|REG_H|REG_PSW) # instrRegPair + | opcode=OPCODE_DAD regpair=(REG_B|REG_D|REG_H|REG_SP) # instrRegPair + | opcode=OPCODE_INX regpair=(REG_B|REG_D|REG_H|REG_SP) # instrRegPair + | opcode=OPCODE_DCX regpair=(REG_B|REG_D|REG_H|REG_SP) # instrRegPair + | opcode=OPCODE_LXI regpair=(REG_B|REG_D|REG_H|REG_SP) SEP_COMMA expr=rExpression # instrRegPairExpr + | opcode=OPCODE_MVI reg=rRegister SEP_COMMA expr=rExpression # instrRegExpr + | opcode=OPCODE_ADI expr=rExpression # instrExpr + | opcode=OPCODE_ACI expr=rExpression # instrExpr + | opcode=OPCODE_SUI expr=rExpression # instrExpr + | opcode=OPCODE_SBI expr=rExpression # instrExpr + | opcode=OPCODE_ANI expr=rExpression # instrExpr + | opcode=OPCODE_XRI expr=rExpression # instrExpr + | opcode=OPCODE_ORI expr=rExpression # instrExpr + | opcode=OPCODE_CPI expr=rExpression # instrExpr + | opcode=OPCODE_STA expr=rExpression # instrExpr + | opcode=OPCODE_LDA expr=rExpression # instrExpr + | opcode=OPCODE_SHLD expr=rExpression # instrExpr + | opcode=OPCODE_LHLD expr=rExpression # instrExpr + | opcode=OPCODE_JMP expr=rExpression # instrExpr + | opcode=OPCODE_JC expr=rExpression # instrExpr + | opcode=OPCODE_JNC expr=rExpression # instrExpr + | opcode=OPCODE_JZ expr=rExpression # instrExpr + | opcode=OPCODE_JNZ expr=rExpression # instrExpr + | opcode=OPCODE_JM expr=rExpression # instrExpr + | opcode=OPCODE_JP expr=rExpression # instrExpr + | opcode=OPCODE_JPE expr=rExpression # instrExpr + | opcode=OPCODE_JPO expr=rExpression # instrExpr + | opcode=OPCODE_CALL expr=rExpression # instrExpr + | opcode=OPCODE_CC expr=rExpression # instrExpr + | opcode=OPCODE_CNC expr=rExpression # instrExpr + | opcode=OPCODE_CZ expr=rExpression # instrExpr + | opcode=OPCODE_CNZ expr=rExpression # instrExpr + | opcode=OPCODE_CM expr=rExpression # instrExpr + | opcode=OPCODE_CP expr=rExpression # instrExpr + | opcode=OPCODE_CPE expr=rExpression # instrExpr + | opcode=OPCODE_CPO expr=rExpression # instrExpr + | opcode=OPCODE_RST expr=rExpression # instrExpr + | opcode=OPCODE_IN expr=rExpression # instrExpr + | opcode=OPCODE_OUT expr=rExpression # instrExpr ; rRegister: @@ -115,28 +115,27 @@ rRegister: ; rPseudoCode: - PREP_ORG expr=rExpression - | id=ID_IDENTIFIER PREP_EQU expr=rExpression - | id=ID_IDENTIFIER PREP_SET expr=rExpression - | PREP_IF expr=rExpression rComment EOL statement=rStatement EOL PREP_ENDIF - | id=ID_IDENTIFIER PREP_MACRO macro=rMacro? rComment EOL statement=rStatement PREP_ENDM - | id=ID_IDENTIFIER macroCall=rMacroCall - | PREP_INCLUDE filename=(LIT_STRING_1|LIT_STRING_2) + PREP_ORG expr=rExpression # pseudoOrg + | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu + | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoSet + | PREP_IF expr=rExpression rComment EOL statement=rStatement EOL PREP_ENDIF # pseudoIf + | id=ID_IDENTIFIER PREP_MACRO macro=rMacro? rComment EOL statement=rStatement PREP_ENDM # pseudoMacroDef + | id=ID_IDENTIFIER macroArgs=rMacroArguments? # pseudoMacroCall + | PREP_INCLUDE filename=(LIT_STRING_1|LIT_STRING_2) # pseudoInclude ; rMacro: id=ID_IDENTIFIER (SEP_COMMA ids=ID_IDENTIFIER)* ; -// todo: assign variables?? -rMacroCall: +rMacroArguments: expr=rExpression (SEP_COMMA exprs=rExpression)* ; rData: - PREP_DB db=rDB - | PREP_DW dw=rDW - | PREP_DS ds=rExpression + PREP_DB data=rDB # dataDB + | PREP_DW data=rDW # dataDW + | PREP_DS data=rExpression # dataDS ; rDB: @@ -158,18 +157,18 @@ rDWdata: ; rExpression: - SEP_LPAR expr=rExpression SEP_RPAR - | num=LIT_NUMBER - | num=LIT_HEXNUMBER_1 - | num=LIT_HEXNUMBER_2 - | num=LIT_OCTNUMBER - | num=LIT_BINNUMBER - | id=PREP_ADDR - | id=ID_IDENTIFIER - | unaryop=(OP_ADD|OP_SUBTRACT) expr=rExpression - | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD|OP_SHL|OP_SHR) expr2=rExpression - | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression - | unaryop=OP_NOT expr=rExpression - | expr1=rExpression op=OP_AND expr2=rExpression - | expr1=rExpression op=(OP_OR|OP_XOR) expr2=rExpression + SEP_LPAR expr=rExpression SEP_RPAR # exprParens + | num=LIT_NUMBER # exprDec + | num=LIT_HEXNUMBER_1 # exprHex1 + | num=LIT_HEXNUMBER_2 # exprHex2 + | num=LIT_OCTNUMBER # exprOct + | num=LIT_BINNUMBER # exprBin + | PREP_ADDR # exprCurrentAddress + | id=ID_IDENTIFIER # exprId + | unaryop=(OP_ADD|OP_SUBTRACT) expr=rExpression # exprUnary + | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD|OP_SHL|OP_SHR) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression # exprInfix + | unaryop=OP_NOT expr=rExpression # exprUnary + | expr1=rExpression op=OP_AND expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_OR|OP_XOR) expr2=rExpression # exprInfix ; diff --git a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp index ad3f351ce..74ee276ac 100644 --- a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp +++ b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp @@ -422,4 +422,4 @@ mode names: DEFAULT_MODE atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 130, 887, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 317, 10, 3, 3, 3, 7, 3, 320, 10, 3, 12, 3, 14, 3, 323, 11, 3, 3, 4, 5, 4, 326, 10, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 105, 3, 105, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 130, 3, 130, 3, 131, 3, 131, 3, 132, 3, 132, 3, 133, 3, 133, 3, 134, 3, 134, 3, 135, 3, 135, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 138, 3, 138, 3, 139, 3, 139, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 5, 144, 803, 10, 144, 3, 144, 6, 144, 806, 10, 144, 13, 144, 14, 144, 807, 3, 144, 5, 144, 811, 10, 144, 3, 145, 5, 145, 814, 10, 145, 3, 145, 3, 145, 3, 145, 3, 145, 5, 145, 820, 10, 145, 3, 145, 6, 145, 823, 10, 145, 13, 145, 14, 145, 824, 3, 146, 5, 146, 828, 10, 146, 3, 146, 6, 146, 831, 10, 146, 13, 146, 14, 146, 832, 3, 146, 3, 146, 3, 147, 5, 147, 838, 10, 147, 3, 147, 6, 147, 841, 10, 147, 13, 147, 14, 147, 842, 3, 147, 3, 147, 3, 148, 6, 148, 848, 10, 148, 13, 148, 14, 148, 849, 3, 148, 3, 148, 3, 149, 3, 149, 6, 149, 856, 10, 149, 13, 149, 14, 149, 857, 3, 149, 3, 149, 3, 150, 3, 150, 6, 150, 864, 10, 150, 13, 150, 14, 150, 865, 3, 150, 3, 150, 3, 151, 3, 151, 7, 151, 872, 10, 151, 12, 151, 14, 151, 875, 11, 151, 3, 152, 3, 152, 7, 152, 879, 10, 152, 12, 152, 14, 152, 882, 11, 152, 3, 152, 3, 152, 3, 153, 3, 153, 2, 2, 154, 3, 3, 5, 4, 7, 5, 9, 2, 11, 2, 13, 2, 15, 2, 17, 2, 19, 2, 21, 2, 23, 2, 25, 2, 27, 2, 29, 2, 31, 2, 33, 2, 35, 2, 37, 2, 39, 2, 41, 2, 43, 2, 45, 2, 47, 2, 49, 2, 51, 2, 53, 2, 55, 2, 57, 6, 59, 7, 61, 8, 63, 9, 65, 10, 67, 11, 69, 12, 71, 13, 73, 14, 75, 15, 77, 16, 79, 17, 81, 18, 83, 19, 85, 20, 87, 21, 89, 22, 91, 23, 93, 24, 95, 25, 97, 26, 99, 27, 101, 28, 103, 29, 105, 30, 107, 31, 109, 32, 111, 33, 113, 34, 115, 35, 117, 36, 119, 37, 121, 38, 123, 39, 125, 40, 127, 41, 129, 42, 131, 43, 133, 44, 135, 45, 137, 46, 139, 47, 141, 48, 143, 49, 145, 50, 147, 51, 149, 52, 151, 53, 153, 54, 155, 55, 157, 56, 159, 57, 161, 58, 163, 59, 165, 60, 167, 61, 169, 62, 171, 63, 173, 64, 175, 65, 177, 66, 179, 67, 181, 68, 183, 69, 185, 70, 187, 71, 189, 72, 191, 73, 193, 74, 195, 75, 197, 76, 199, 77, 201, 78, 203, 79, 205, 80, 207, 81, 209, 82, 211, 83, 213, 84, 215, 85, 217, 86, 219, 87, 221, 88, 223, 89, 225, 90, 227, 91, 229, 92, 231, 93, 233, 94, 235, 95, 237, 96, 239, 97, 241, 98, 243, 99, 245, 100, 247, 101, 249, 102, 251, 103, 253, 104, 255, 105, 257, 106, 259, 107, 261, 108, 263, 109, 265, 110, 267, 111, 269, 112, 271, 113, 273, 114, 275, 115, 277, 116, 279, 117, 281, 118, 283, 119, 285, 120, 287, 121, 289, 122, 291, 123, 293, 124, 295, 125, 297, 126, 299, 127, 301, 128, 303, 129, 305, 130, 3, 2, 40, 5, 2, 11, 11, 14, 14, 34, 34, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 92, 92, 124, 124, 3, 2, 47, 47, 3, 2, 50, 59, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 4, 2, 41, 41, 96, 96, 4, 2, 36, 36, 96, 96, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 2, 881, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 157, 3, 2, 2, 2, 2, 159, 3, 2, 2, 2, 2, 161, 3, 2, 2, 2, 2, 163, 3, 2, 2, 2, 2, 165, 3, 2, 2, 2, 2, 167, 3, 2, 2, 2, 2, 169, 3, 2, 2, 2, 2, 171, 3, 2, 2, 2, 2, 173, 3, 2, 2, 2, 2, 175, 3, 2, 2, 2, 2, 177, 3, 2, 2, 2, 2, 179, 3, 2, 2, 2, 2, 181, 3, 2, 2, 2, 2, 183, 3, 2, 2, 2, 2, 185, 3, 2, 2, 2, 2, 187, 3, 2, 2, 2, 2, 189, 3, 2, 2, 2, 2, 191, 3, 2, 2, 2, 2, 193, 3, 2, 2, 2, 2, 195, 3, 2, 2, 2, 2, 197, 3, 2, 2, 2, 2, 199, 3, 2, 2, 2, 2, 201, 3, 2, 2, 2, 2, 203, 3, 2, 2, 2, 2, 205, 3, 2, 2, 2, 2, 207, 3, 2, 2, 2, 2, 209, 3, 2, 2, 2, 2, 211, 3, 2, 2, 2, 2, 213, 3, 2, 2, 2, 2, 215, 3, 2, 2, 2, 2, 217, 3, 2, 2, 2, 2, 219, 3, 2, 2, 2, 2, 221, 3, 2, 2, 2, 2, 223, 3, 2, 2, 2, 2, 225, 3, 2, 2, 2, 2, 227, 3, 2, 2, 2, 2, 229, 3, 2, 2, 2, 2, 231, 3, 2, 2, 2, 2, 233, 3, 2, 2, 2, 2, 235, 3, 2, 2, 2, 2, 237, 3, 2, 2, 2, 2, 239, 3, 2, 2, 2, 2, 241, 3, 2, 2, 2, 2, 243, 3, 2, 2, 2, 2, 245, 3, 2, 2, 2, 2, 247, 3, 2, 2, 2, 2, 249, 3, 2, 2, 2, 2, 251, 3, 2, 2, 2, 2, 253, 3, 2, 2, 2, 2, 255, 3, 2, 2, 2, 2, 257, 3, 2, 2, 2, 2, 259, 3, 2, 2, 2, 2, 261, 3, 2, 2, 2, 2, 263, 3, 2, 2, 2, 2, 265, 3, 2, 2, 2, 2, 267, 3, 2, 2, 2, 2, 269, 3, 2, 2, 2, 2, 271, 3, 2, 2, 2, 2, 273, 3, 2, 2, 2, 2, 275, 3, 2, 2, 2, 2, 277, 3, 2, 2, 2, 2, 279, 3, 2, 2, 2, 2, 281, 3, 2, 2, 2, 2, 283, 3, 2, 2, 2, 2, 285, 3, 2, 2, 2, 2, 287, 3, 2, 2, 2, 2, 289, 3, 2, 2, 2, 2, 291, 3, 2, 2, 2, 2, 293, 3, 2, 2, 2, 2, 295, 3, 2, 2, 2, 2, 297, 3, 2, 2, 2, 2, 299, 3, 2, 2, 2, 2, 301, 3, 2, 2, 2, 2, 303, 3, 2, 2, 2, 2, 305, 3, 2, 2, 2, 3, 307, 3, 2, 2, 2, 5, 316, 3, 2, 2, 2, 7, 325, 3, 2, 2, 2, 9, 329, 3, 2, 2, 2, 11, 331, 3, 2, 2, 2, 13, 333, 3, 2, 2, 2, 15, 335, 3, 2, 2, 2, 17, 337, 3, 2, 2, 2, 19, 339, 3, 2, 2, 2, 21, 341, 3, 2, 2, 2, 23, 343, 3, 2, 2, 2, 25, 345, 3, 2, 2, 2, 27, 347, 3, 2, 2, 2, 29, 349, 3, 2, 2, 2, 31, 351, 3, 2, 2, 2, 33, 353, 3, 2, 2, 2, 35, 355, 3, 2, 2, 2, 37, 357, 3, 2, 2, 2, 39, 359, 3, 2, 2, 2, 41, 361, 3, 2, 2, 2, 43, 363, 3, 2, 2, 2, 45, 365, 3, 2, 2, 2, 47, 367, 3, 2, 2, 2, 49, 369, 3, 2, 2, 2, 51, 371, 3, 2, 2, 2, 53, 373, 3, 2, 2, 2, 55, 375, 3, 2, 2, 2, 57, 377, 3, 2, 2, 2, 59, 381, 3, 2, 2, 2, 61, 385, 3, 2, 2, 2, 63, 389, 3, 2, 2, 2, 65, 393, 3, 2, 2, 2, 67, 397, 3, 2, 2, 2, 69, 401, 3, 2, 2, 2, 71, 405, 3, 2, 2, 2, 73, 409, 3, 2, 2, 2, 75, 414, 3, 2, 2, 2, 77, 419, 3, 2, 2, 2, 79, 423, 3, 2, 2, 2, 81, 427, 3, 2, 2, 2, 83, 431, 3, 2, 2, 2, 85, 435, 3, 2, 2, 2, 87, 439, 3, 2, 2, 2, 89, 443, 3, 2, 2, 2, 91, 447, 3, 2, 2, 2, 93, 451, 3, 2, 2, 2, 95, 455, 3, 2, 2, 2, 97, 459, 3, 2, 2, 2, 99, 463, 3, 2, 2, 2, 101, 467, 3, 2, 2, 2, 103, 472, 3, 2, 2, 2, 105, 476, 3, 2, 2, 2, 107, 480, 3, 2, 2, 2, 109, 484, 3, 2, 2, 2, 111, 488, 3, 2, 2, 2, 113, 493, 3, 2, 2, 2, 115, 498, 3, 2, 2, 2, 117, 503, 3, 2, 2, 2, 119, 507, 3, 2, 2, 2, 121, 511, 3, 2, 2, 2, 123, 515, 3, 2, 2, 2, 125, 519, 3, 2, 2, 2, 127, 523, 3, 2, 2, 2, 129, 527, 3, 2, 2, 2, 131, 531, 3, 2, 2, 2, 133, 535, 3, 2, 2, 2, 135, 539, 3, 2, 2, 2, 137, 543, 3, 2, 2, 2, 139, 547, 3, 2, 2, 2, 141, 551, 3, 2, 2, 2, 143, 556, 3, 2, 2, 2, 145, 561, 3, 2, 2, 2, 147, 566, 3, 2, 2, 2, 149, 570, 3, 2, 2, 2, 151, 573, 3, 2, 2, 2, 153, 577, 3, 2, 2, 2, 155, 580, 3, 2, 2, 2, 157, 584, 3, 2, 2, 2, 159, 587, 3, 2, 2, 2, 161, 590, 3, 2, 2, 2, 163, 594, 3, 2, 2, 2, 165, 598, 3, 2, 2, 2, 167, 603, 3, 2, 2, 2, 169, 606, 3, 2, 2, 2, 171, 610, 3, 2, 2, 2, 173, 613, 3, 2, 2, 2, 175, 617, 3, 2, 2, 2, 177, 620, 3, 2, 2, 2, 179, 623, 3, 2, 2, 2, 181, 627, 3, 2, 2, 2, 183, 631, 3, 2, 2, 2, 185, 635, 3, 2, 2, 2, 187, 638, 3, 2, 2, 2, 189, 642, 3, 2, 2, 2, 191, 645, 3, 2, 2, 2, 193, 649, 3, 2, 2, 2, 195, 652, 3, 2, 2, 2, 197, 655, 3, 2, 2, 2, 199, 659, 3, 2, 2, 2, 201, 663, 3, 2, 2, 2, 203, 667, 3, 2, 2, 2, 205, 670, 3, 2, 2, 2, 207, 673, 3, 2, 2, 2, 209, 676, 3, 2, 2, 2, 211, 680, 3, 2, 2, 2, 213, 684, 3, 2, 2, 2, 215, 688, 3, 2, 2, 2, 217, 692, 3, 2, 2, 2, 219, 696, 3, 2, 2, 2, 221, 704, 3, 2, 2, 2, 223, 707, 3, 2, 2, 2, 225, 713, 3, 2, 2, 2, 227, 719, 3, 2, 2, 2, 229, 724, 3, 2, 2, 2, 231, 727, 3, 2, 2, 2, 233, 730, 3, 2, 2, 2, 235, 733, 3, 2, 2, 2, 237, 735, 3, 2, 2, 2, 239, 737, 3, 2, 2, 2, 241, 739, 3, 2, 2, 2, 243, 741, 3, 2, 2, 2, 245, 743, 3, 2, 2, 2, 247, 745, 3, 2, 2, 2, 249, 747, 3, 2, 2, 2, 251, 749, 3, 2, 2, 2, 253, 751, 3, 2, 2, 2, 255, 755, 3, 2, 2, 2, 257, 758, 3, 2, 2, 2, 259, 760, 3, 2, 2, 2, 261, 762, 3, 2, 2, 2, 263, 764, 3, 2, 2, 2, 265, 766, 3, 2, 2, 2, 267, 768, 3, 2, 2, 2, 269, 770, 3, 2, 2, 2, 271, 772, 3, 2, 2, 2, 273, 774, 3, 2, 2, 2, 275, 778, 3, 2, 2, 2, 277, 782, 3, 2, 2, 2, 279, 786, 3, 2, 2, 2, 281, 790, 3, 2, 2, 2, 283, 794, 3, 2, 2, 2, 285, 797, 3, 2, 2, 2, 287, 802, 3, 2, 2, 2, 289, 813, 3, 2, 2, 2, 291, 827, 3, 2, 2, 2, 293, 837, 3, 2, 2, 2, 295, 847, 3, 2, 2, 2, 297, 853, 3, 2, 2, 2, 299, 861, 3, 2, 2, 2, 301, 869, 3, 2, 2, 2, 303, 876, 3, 2, 2, 2, 305, 885, 3, 2, 2, 2, 307, 308, 9, 2, 2, 2, 308, 309, 3, 2, 2, 2, 309, 310, 8, 2, 2, 2, 310, 4, 3, 2, 2, 2, 311, 312, 7, 49, 2, 2, 312, 317, 7, 49, 2, 2, 313, 314, 7, 47, 2, 2, 314, 317, 7, 47, 2, 2, 315, 317, 9, 3, 2, 2, 316, 311, 3, 2, 2, 2, 316, 313, 3, 2, 2, 2, 316, 315, 3, 2, 2, 2, 317, 321, 3, 2, 2, 2, 318, 320, 10, 4, 2, 2, 319, 318, 3, 2, 2, 2, 320, 323, 3, 2, 2, 2, 321, 319, 3, 2, 2, 2, 321, 322, 3, 2, 2, 2, 322, 6, 3, 2, 2, 2, 323, 321, 3, 2, 2, 2, 324, 326, 7, 15, 2, 2, 325, 324, 3, 2, 2, 2, 325, 326, 3, 2, 2, 2, 326, 327, 3, 2, 2, 2, 327, 328, 7, 12, 2, 2, 328, 8, 3, 2, 2, 2, 329, 330, 9, 5, 2, 2, 330, 10, 3, 2, 2, 2, 331, 332, 9, 6, 2, 2, 332, 12, 3, 2, 2, 2, 333, 334, 9, 7, 2, 2, 334, 14, 3, 2, 2, 2, 335, 336, 9, 8, 2, 2, 336, 16, 3, 2, 2, 2, 337, 338, 9, 9, 2, 2, 338, 18, 3, 2, 2, 2, 339, 340, 9, 10, 2, 2, 340, 20, 3, 2, 2, 2, 341, 342, 9, 11, 2, 2, 342, 22, 3, 2, 2, 2, 343, 344, 9, 12, 2, 2, 344, 24, 3, 2, 2, 2, 345, 346, 9, 13, 2, 2, 346, 26, 3, 2, 2, 2, 347, 348, 9, 14, 2, 2, 348, 28, 3, 2, 2, 2, 349, 350, 9, 15, 2, 2, 350, 30, 3, 2, 2, 2, 351, 352, 9, 16, 2, 2, 352, 32, 3, 2, 2, 2, 353, 354, 9, 17, 2, 2, 354, 34, 3, 2, 2, 2, 355, 356, 9, 18, 2, 2, 356, 36, 3, 2, 2, 2, 357, 358, 9, 19, 2, 2, 358, 38, 3, 2, 2, 2, 359, 360, 9, 20, 2, 2, 360, 40, 3, 2, 2, 2, 361, 362, 9, 21, 2, 2, 362, 42, 3, 2, 2, 2, 363, 364, 9, 22, 2, 2, 364, 44, 3, 2, 2, 2, 365, 366, 9, 23, 2, 2, 366, 46, 3, 2, 2, 2, 367, 368, 9, 24, 2, 2, 368, 48, 3, 2, 2, 2, 369, 370, 9, 25, 2, 2, 370, 50, 3, 2, 2, 2, 371, 372, 9, 26, 2, 2, 372, 52, 3, 2, 2, 2, 373, 374, 9, 27, 2, 2, 374, 54, 3, 2, 2, 2, 375, 376, 9, 28, 2, 2, 376, 56, 3, 2, 2, 2, 377, 378, 5, 43, 22, 2, 378, 379, 5, 45, 23, 2, 379, 380, 5, 13, 7, 2, 380, 58, 3, 2, 2, 2, 381, 382, 5, 13, 7, 2, 382, 383, 5, 31, 16, 2, 383, 384, 5, 13, 7, 2, 384, 60, 3, 2, 2, 2, 385, 386, 5, 25, 13, 2, 386, 387, 5, 33, 17, 2, 387, 388, 5, 41, 21, 2, 388, 62, 3, 2, 2, 2, 389, 390, 5, 15, 8, 2, 390, 391, 5, 13, 7, 2, 391, 392, 5, 41, 21, 2, 392, 64, 3, 2, 2, 2, 393, 394, 5, 13, 7, 2, 394, 395, 5, 31, 16, 2, 395, 396, 5, 9, 5, 2, 396, 66, 3, 2, 2, 2, 397, 398, 5, 15, 8, 2, 398, 399, 5, 9, 5, 2, 399, 400, 5, 9, 5, 2, 400, 68, 3, 2, 2, 2, 401, 402, 5, 33, 17, 2, 402, 403, 5, 35, 18, 2, 403, 404, 5, 37, 19, 2, 404, 70, 3, 2, 2, 2, 405, 406, 5, 31, 16, 2, 406, 407, 5, 35, 18, 2, 407, 408, 5, 49, 25, 2, 408, 72, 3, 2, 2, 2, 409, 410, 5, 43, 22, 2, 410, 411, 5, 45, 23, 2, 411, 412, 5, 9, 5, 2, 412, 413, 5, 53, 27, 2, 413, 74, 3, 2, 2, 2, 414, 415, 5, 29, 15, 2, 415, 416, 5, 15, 8, 2, 416, 417, 5, 9, 5, 2, 417, 418, 5, 53, 27, 2, 418, 76, 3, 2, 2, 2, 419, 420, 5, 9, 5, 2, 420, 421, 5, 15, 8, 2, 421, 422, 5, 15, 8, 2, 422, 78, 3, 2, 2, 2, 423, 424, 5, 9, 5, 2, 424, 425, 5, 15, 8, 2, 425, 426, 5, 13, 7, 2, 426, 80, 3, 2, 2, 2, 427, 428, 5, 43, 22, 2, 428, 429, 5, 47, 24, 2, 429, 430, 5, 11, 6, 2, 430, 82, 3, 2, 2, 2, 431, 432, 5, 43, 22, 2, 432, 433, 5, 11, 6, 2, 433, 434, 5, 11, 6, 2, 434, 84, 3, 2, 2, 2, 435, 436, 5, 9, 5, 2, 436, 437, 5, 33, 17, 2, 437, 438, 5, 9, 5, 2, 438, 86, 3, 2, 2, 2, 439, 440, 5, 53, 27, 2, 440, 441, 5, 41, 21, 2, 441, 442, 5, 9, 5, 2, 442, 88, 3, 2, 2, 2, 443, 444, 5, 35, 18, 2, 444, 445, 5, 41, 21, 2, 445, 446, 5, 9, 5, 2, 446, 90, 3, 2, 2, 2, 447, 448, 5, 13, 7, 2, 448, 449, 5, 31, 16, 2, 449, 450, 5, 37, 19, 2, 450, 92, 3, 2, 2, 2, 451, 452, 5, 41, 21, 2, 452, 453, 5, 29, 15, 2, 453, 454, 5, 13, 7, 2, 454, 94, 3, 2, 2, 2, 455, 456, 5, 41, 21, 2, 456, 457, 5, 41, 21, 2, 457, 458, 5, 13, 7, 2, 458, 96, 3, 2, 2, 2, 459, 460, 5, 41, 21, 2, 460, 461, 5, 9, 5, 2, 461, 462, 5, 29, 15, 2, 462, 98, 3, 2, 2, 2, 463, 464, 5, 41, 21, 2, 464, 465, 5, 9, 5, 2, 465, 466, 5, 41, 21, 2, 466, 100, 3, 2, 2, 2, 467, 468, 5, 37, 19, 2, 468, 469, 5, 47, 24, 2, 469, 470, 5, 43, 22, 2, 470, 471, 5, 23, 12, 2, 471, 102, 3, 2, 2, 2, 472, 473, 5, 37, 19, 2, 473, 474, 5, 35, 18, 2, 474, 475, 5, 37, 19, 2, 475, 104, 3, 2, 2, 2, 476, 477, 5, 15, 8, 2, 477, 478, 5, 9, 5, 2, 478, 479, 5, 15, 8, 2, 479, 106, 3, 2, 2, 2, 480, 481, 5, 25, 13, 2, 481, 482, 5, 33, 17, 2, 482, 483, 5, 53, 27, 2, 483, 108, 3, 2, 2, 2, 484, 485, 5, 15, 8, 2, 485, 486, 5, 13, 7, 2, 486, 487, 5, 53, 27, 2, 487, 110, 3, 2, 2, 2, 488, 489, 5, 53, 27, 2, 489, 490, 5, 13, 7, 2, 490, 491, 5, 23, 12, 2, 491, 492, 5, 21, 11, 2, 492, 112, 3, 2, 2, 2, 493, 494, 5, 53, 27, 2, 494, 495, 5, 45, 23, 2, 495, 496, 5, 23, 12, 2, 496, 497, 5, 29, 15, 2, 497, 114, 3, 2, 2, 2, 498, 499, 5, 43, 22, 2, 499, 500, 5, 37, 19, 2, 500, 501, 5, 23, 12, 2, 501, 502, 5, 29, 15, 2, 502, 116, 3, 2, 2, 2, 503, 504, 5, 29, 15, 2, 504, 505, 5, 53, 27, 2, 505, 506, 5, 25, 13, 2, 506, 118, 3, 2, 2, 2, 507, 508, 5, 31, 16, 2, 508, 509, 5, 49, 25, 2, 509, 510, 5, 25, 13, 2, 510, 120, 3, 2, 2, 2, 511, 512, 5, 9, 5, 2, 512, 513, 5, 15, 8, 2, 513, 514, 5, 25, 13, 2, 514, 122, 3, 2, 2, 2, 515, 516, 5, 9, 5, 2, 516, 517, 5, 13, 7, 2, 517, 518, 5, 25, 13, 2, 518, 124, 3, 2, 2, 2, 519, 520, 5, 43, 22, 2, 520, 521, 5, 47, 24, 2, 521, 522, 5, 25, 13, 2, 522, 126, 3, 2, 2, 2, 523, 524, 5, 43, 22, 2, 524, 525, 5, 11, 6, 2, 525, 526, 5, 25, 13, 2, 526, 128, 3, 2, 2, 2, 527, 528, 5, 9, 5, 2, 528, 529, 5, 33, 17, 2, 529, 530, 5, 25, 13, 2, 530, 130, 3, 2, 2, 2, 531, 532, 5, 53, 27, 2, 532, 533, 5, 41, 21, 2, 533, 534, 5, 25, 13, 2, 534, 132, 3, 2, 2, 2, 535, 536, 5, 35, 18, 2, 536, 537, 5, 41, 21, 2, 537, 538, 5, 25, 13, 2, 538, 134, 3, 2, 2, 2, 539, 540, 5, 13, 7, 2, 540, 541, 5, 37, 19, 2, 541, 542, 5, 25, 13, 2, 542, 136, 3, 2, 2, 2, 543, 544, 5, 43, 22, 2, 544, 545, 5, 45, 23, 2, 545, 546, 5, 9, 5, 2, 546, 138, 3, 2, 2, 2, 547, 548, 5, 29, 15, 2, 548, 549, 5, 15, 8, 2, 549, 550, 5, 9, 5, 2, 550, 140, 3, 2, 2, 2, 551, 552, 5, 43, 22, 2, 552, 553, 5, 23, 12, 2, 553, 554, 5, 29, 15, 2, 554, 555, 5, 15, 8, 2, 555, 142, 3, 2, 2, 2, 556, 557, 5, 29, 15, 2, 557, 558, 5, 23, 12, 2, 558, 559, 5, 29, 15, 2, 559, 560, 5, 15, 8, 2, 560, 144, 3, 2, 2, 2, 561, 562, 5, 37, 19, 2, 562, 563, 5, 13, 7, 2, 563, 564, 5, 23, 12, 2, 564, 565, 5, 29, 15, 2, 565, 146, 3, 2, 2, 2, 566, 567, 5, 27, 14, 2, 567, 568, 5, 31, 16, 2, 568, 569, 5, 37, 19, 2, 569, 148, 3, 2, 2, 2, 570, 571, 5, 27, 14, 2, 571, 572, 5, 13, 7, 2, 572, 150, 3, 2, 2, 2, 573, 574, 5, 27, 14, 2, 574, 575, 5, 33, 17, 2, 575, 576, 5, 13, 7, 2, 576, 152, 3, 2, 2, 2, 577, 578, 5, 27, 14, 2, 578, 579, 5, 55, 28, 2, 579, 154, 3, 2, 2, 2, 580, 581, 5, 27, 14, 2, 581, 582, 5, 33, 17, 2, 582, 583, 5, 55, 28, 2, 583, 156, 3, 2, 2, 2, 584, 585, 5, 27, 14, 2, 585, 586, 5, 37, 19, 2, 586, 158, 3, 2, 2, 2, 587, 588, 5, 27, 14, 2, 588, 589, 5, 31, 16, 2, 589, 160, 3, 2, 2, 2, 590, 591, 5, 27, 14, 2, 591, 592, 5, 37, 19, 2, 592, 593, 5, 17, 9, 2, 593, 162, 3, 2, 2, 2, 594, 595, 5, 27, 14, 2, 595, 596, 5, 37, 19, 2, 596, 597, 5, 35, 18, 2, 597, 164, 3, 2, 2, 2, 598, 599, 5, 13, 7, 2, 599, 600, 5, 9, 5, 2, 600, 601, 5, 29, 15, 2, 601, 602, 5, 29, 15, 2, 602, 166, 3, 2, 2, 2, 603, 604, 5, 13, 7, 2, 604, 605, 5, 13, 7, 2, 605, 168, 3, 2, 2, 2, 606, 607, 5, 13, 7, 2, 607, 608, 5, 33, 17, 2, 608, 609, 5, 13, 7, 2, 609, 170, 3, 2, 2, 2, 610, 611, 5, 13, 7, 2, 611, 612, 5, 55, 28, 2, 612, 172, 3, 2, 2, 2, 613, 614, 5, 13, 7, 2, 614, 615, 5, 33, 17, 2, 615, 616, 5, 55, 28, 2, 616, 174, 3, 2, 2, 2, 617, 618, 5, 13, 7, 2, 618, 619, 5, 37, 19, 2, 619, 176, 3, 2, 2, 2, 620, 621, 5, 13, 7, 2, 621, 622, 5, 31, 16, 2, 622, 178, 3, 2, 2, 2, 623, 624, 5, 13, 7, 2, 624, 625, 5, 37, 19, 2, 625, 626, 5, 17, 9, 2, 626, 180, 3, 2, 2, 2, 627, 628, 5, 13, 7, 2, 628, 629, 5, 37, 19, 2, 629, 630, 5, 35, 18, 2, 630, 182, 3, 2, 2, 2, 631, 632, 5, 41, 21, 2, 632, 633, 5, 17, 9, 2, 633, 634, 5, 45, 23, 2, 634, 184, 3, 2, 2, 2, 635, 636, 5, 41, 21, 2, 636, 637, 5, 13, 7, 2, 637, 186, 3, 2, 2, 2, 638, 639, 5, 41, 21, 2, 639, 640, 5, 33, 17, 2, 640, 641, 5, 13, 7, 2, 641, 188, 3, 2, 2, 2, 642, 643, 5, 41, 21, 2, 643, 644, 5, 55, 28, 2, 644, 190, 3, 2, 2, 2, 645, 646, 5, 41, 21, 2, 646, 647, 5, 33, 17, 2, 647, 648, 5, 55, 28, 2, 648, 192, 3, 2, 2, 2, 649, 650, 5, 41, 21, 2, 650, 651, 5, 31, 16, 2, 651, 194, 3, 2, 2, 2, 652, 653, 5, 41, 21, 2, 653, 654, 5, 37, 19, 2, 654, 196, 3, 2, 2, 2, 655, 656, 5, 41, 21, 2, 656, 657, 5, 37, 19, 2, 657, 658, 5, 17, 9, 2, 658, 198, 3, 2, 2, 2, 659, 660, 5, 41, 21, 2, 660, 661, 5, 37, 19, 2, 661, 662, 5, 35, 18, 2, 662, 200, 3, 2, 2, 2, 663, 664, 5, 41, 21, 2, 664, 665, 5, 43, 22, 2, 665, 666, 5, 45, 23, 2, 666, 202, 3, 2, 2, 2, 667, 668, 5, 17, 9, 2, 668, 669, 5, 25, 13, 2, 669, 204, 3, 2, 2, 2, 670, 671, 5, 15, 8, 2, 671, 672, 5, 25, 13, 2, 672, 206, 3, 2, 2, 2, 673, 674, 5, 25, 13, 2, 674, 675, 5, 33, 17, 2, 675, 208, 3, 2, 2, 2, 676, 677, 5, 35, 18, 2, 677, 678, 5, 47, 24, 2, 678, 679, 5, 45, 23, 2, 679, 210, 3, 2, 2, 2, 680, 681, 5, 23, 12, 2, 681, 682, 5, 29, 15, 2, 682, 683, 5, 45, 23, 2, 683, 212, 3, 2, 2, 2, 684, 685, 5, 35, 18, 2, 685, 686, 5, 41, 21, 2, 686, 687, 5, 21, 11, 2, 687, 214, 3, 2, 2, 2, 688, 689, 5, 17, 9, 2, 689, 690, 5, 39, 20, 2, 690, 691, 5, 47, 24, 2, 691, 216, 3, 2, 2, 2, 692, 693, 5, 43, 22, 2, 693, 694, 5, 17, 9, 2, 694, 695, 5, 45, 23, 2, 695, 218, 3, 2, 2, 2, 696, 697, 5, 25, 13, 2, 697, 698, 5, 33, 17, 2, 698, 699, 5, 13, 7, 2, 699, 700, 5, 29, 15, 2, 700, 701, 5, 47, 24, 2, 701, 702, 5, 15, 8, 2, 702, 703, 5, 17, 9, 2, 703, 220, 3, 2, 2, 2, 704, 705, 5, 25, 13, 2, 705, 706, 5, 19, 10, 2, 706, 222, 3, 2, 2, 2, 707, 708, 5, 17, 9, 2, 708, 709, 5, 33, 17, 2, 709, 710, 5, 15, 8, 2, 710, 711, 5, 25, 13, 2, 711, 712, 5, 19, 10, 2, 712, 224, 3, 2, 2, 2, 713, 714, 5, 31, 16, 2, 714, 715, 5, 9, 5, 2, 715, 716, 5, 13, 7, 2, 716, 717, 5, 41, 21, 2, 717, 718, 5, 35, 18, 2, 718, 226, 3, 2, 2, 2, 719, 720, 5, 17, 9, 2, 720, 721, 5, 33, 17, 2, 721, 722, 5, 15, 8, 2, 722, 723, 5, 31, 16, 2, 723, 228, 3, 2, 2, 2, 724, 725, 5, 15, 8, 2, 725, 726, 5, 11, 6, 2, 726, 230, 3, 2, 2, 2, 727, 728, 5, 15, 8, 2, 728, 729, 5, 51, 26, 2, 729, 232, 3, 2, 2, 2, 730, 731, 5, 15, 8, 2, 731, 732, 5, 43, 22, 2, 732, 234, 3, 2, 2, 2, 733, 734, 7, 38, 2, 2, 734, 236, 3, 2, 2, 2, 735, 736, 5, 9, 5, 2, 736, 238, 3, 2, 2, 2, 737, 738, 5, 11, 6, 2, 738, 240, 3, 2, 2, 2, 739, 740, 5, 13, 7, 2, 740, 242, 3, 2, 2, 2, 741, 742, 5, 15, 8, 2, 742, 244, 3, 2, 2, 2, 743, 744, 5, 17, 9, 2, 744, 246, 3, 2, 2, 2, 745, 746, 5, 23, 12, 2, 746, 248, 3, 2, 2, 2, 747, 748, 5, 29, 15, 2, 748, 250, 3, 2, 2, 2, 749, 750, 5, 31, 16, 2, 750, 252, 3, 2, 2, 2, 751, 752, 5, 37, 19, 2, 752, 753, 5, 43, 22, 2, 753, 754, 5, 51, 26, 2, 754, 254, 3, 2, 2, 2, 755, 756, 5, 43, 22, 2, 756, 757, 5, 37, 19, 2, 757, 256, 3, 2, 2, 2, 758, 759, 7, 42, 2, 2, 759, 258, 3, 2, 2, 2, 760, 761, 7, 43, 2, 2, 761, 260, 3, 2, 2, 2, 762, 763, 7, 46, 2, 2, 763, 262, 3, 2, 2, 2, 764, 765, 7, 45, 2, 2, 765, 264, 3, 2, 2, 2, 766, 767, 7, 47, 2, 2, 767, 266, 3, 2, 2, 2, 768, 769, 7, 44, 2, 2, 769, 268, 3, 2, 2, 2, 770, 771, 7, 49, 2, 2, 771, 270, 3, 2, 2, 2, 772, 773, 7, 63, 2, 2, 773, 272, 3, 2, 2, 2, 774, 775, 5, 31, 16, 2, 775, 776, 5, 35, 18, 2, 776, 777, 5, 15, 8, 2, 777, 274, 3, 2, 2, 2, 778, 779, 5, 43, 22, 2, 779, 780, 5, 23, 12, 2, 780, 781, 5, 41, 21, 2, 781, 276, 3, 2, 2, 2, 782, 783, 5, 43, 22, 2, 783, 784, 5, 23, 12, 2, 784, 785, 5, 29, 15, 2, 785, 278, 3, 2, 2, 2, 786, 787, 5, 33, 17, 2, 787, 788, 5, 35, 18, 2, 788, 789, 5, 45, 23, 2, 789, 280, 3, 2, 2, 2, 790, 791, 5, 9, 5, 2, 791, 792, 5, 33, 17, 2, 792, 793, 5, 15, 8, 2, 793, 282, 3, 2, 2, 2, 794, 795, 5, 35, 18, 2, 795, 796, 5, 41, 21, 2, 796, 284, 3, 2, 2, 2, 797, 798, 5, 53, 27, 2, 798, 799, 5, 35, 18, 2, 799, 800, 5, 41, 21, 2, 800, 286, 3, 2, 2, 2, 801, 803, 9, 29, 2, 2, 802, 801, 3, 2, 2, 2, 802, 803, 3, 2, 2, 2, 803, 805, 3, 2, 2, 2, 804, 806, 9, 30, 2, 2, 805, 804, 3, 2, 2, 2, 806, 807, 3, 2, 2, 2, 807, 805, 3, 2, 2, 2, 807, 808, 3, 2, 2, 2, 808, 810, 3, 2, 2, 2, 809, 811, 5, 15, 8, 2, 810, 809, 3, 2, 2, 2, 810, 811, 3, 2, 2, 2, 811, 288, 3, 2, 2, 2, 812, 814, 9, 29, 2, 2, 813, 812, 3, 2, 2, 2, 813, 814, 3, 2, 2, 2, 814, 819, 3, 2, 2, 2, 815, 816, 7, 50, 2, 2, 816, 820, 7, 122, 2, 2, 817, 818, 7, 50, 2, 2, 818, 820, 7, 90, 2, 2, 819, 815, 3, 2, 2, 2, 819, 817, 3, 2, 2, 2, 820, 822, 3, 2, 2, 2, 821, 823, 9, 31, 2, 2, 822, 821, 3, 2, 2, 2, 823, 824, 3, 2, 2, 2, 824, 822, 3, 2, 2, 2, 824, 825, 3, 2, 2, 2, 825, 290, 3, 2, 2, 2, 826, 828, 9, 29, 2, 2, 827, 826, 3, 2, 2, 2, 827, 828, 3, 2, 2, 2, 828, 830, 3, 2, 2, 2, 829, 831, 9, 31, 2, 2, 830, 829, 3, 2, 2, 2, 831, 832, 3, 2, 2, 2, 832, 830, 3, 2, 2, 2, 832, 833, 3, 2, 2, 2, 833, 834, 3, 2, 2, 2, 834, 835, 5, 23, 12, 2, 835, 292, 3, 2, 2, 2, 836, 838, 9, 29, 2, 2, 837, 836, 3, 2, 2, 2, 837, 838, 3, 2, 2, 2, 838, 840, 3, 2, 2, 2, 839, 841, 9, 32, 2, 2, 840, 839, 3, 2, 2, 2, 841, 842, 3, 2, 2, 2, 842, 840, 3, 2, 2, 2, 842, 843, 3, 2, 2, 2, 843, 844, 3, 2, 2, 2, 844, 845, 9, 33, 2, 2, 845, 294, 3, 2, 2, 2, 846, 848, 9, 34, 2, 2, 847, 846, 3, 2, 2, 2, 848, 849, 3, 2, 2, 2, 849, 847, 3, 2, 2, 2, 849, 850, 3, 2, 2, 2, 850, 851, 3, 2, 2, 2, 851, 852, 5, 11, 6, 2, 852, 296, 3, 2, 2, 2, 853, 855, 9, 35, 2, 2, 854, 856, 9, 36, 2, 2, 855, 854, 3, 2, 2, 2, 856, 857, 3, 2, 2, 2, 857, 855, 3, 2, 2, 2, 857, 858, 3, 2, 2, 2, 858, 859, 3, 2, 2, 2, 859, 860, 9, 35, 2, 2, 860, 298, 3, 2, 2, 2, 861, 863, 7, 36, 2, 2, 862, 864, 9, 37, 2, 2, 863, 862, 3, 2, 2, 2, 864, 865, 3, 2, 2, 2, 865, 863, 3, 2, 2, 2, 865, 866, 3, 2, 2, 2, 866, 867, 3, 2, 2, 2, 867, 868, 7, 36, 2, 2, 868, 300, 3, 2, 2, 2, 869, 873, 9, 38, 2, 2, 870, 872, 9, 39, 2, 2, 871, 870, 3, 2, 2, 2, 872, 875, 3, 2, 2, 2, 873, 871, 3, 2, 2, 2, 873, 874, 3, 2, 2, 2, 874, 302, 3, 2, 2, 2, 875, 873, 3, 2, 2, 2, 876, 880, 9, 38, 2, 2, 877, 879, 9, 39, 2, 2, 878, 877, 3, 2, 2, 2, 879, 882, 3, 2, 2, 2, 880, 878, 3, 2, 2, 2, 880, 881, 3, 2, 2, 2, 881, 883, 3, 2, 2, 2, 882, 880, 3, 2, 2, 2, 883, 884, 7, 60, 2, 2, 884, 304, 3, 2, 2, 2, 885, 886, 11, 2, 2, 2, 886, 306, 3, 2, 2, 2, 21, 2, 316, 321, 325, 802, 807, 810, 813, 819, 824, 827, 832, 837, 842, 849, 857, 865, 873, 880, 3, 2, 3, 2] \ No newline at end of file +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 130, 883, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 317, 10, 3, 3, 3, 7, 3, 320, 10, 3, 12, 3, 14, 3, 323, 11, 3, 3, 4, 5, 4, 326, 10, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 105, 3, 105, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 130, 3, 130, 3, 131, 3, 131, 3, 132, 3, 132, 3, 133, 3, 133, 3, 134, 3, 134, 3, 135, 3, 135, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 138, 3, 138, 3, 139, 3, 139, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 5, 144, 803, 10, 144, 3, 144, 6, 144, 806, 10, 144, 13, 144, 14, 144, 807, 3, 144, 5, 144, 811, 10, 144, 3, 145, 5, 145, 814, 10, 145, 3, 145, 3, 145, 3, 145, 6, 145, 819, 10, 145, 13, 145, 14, 145, 820, 3, 146, 5, 146, 824, 10, 146, 3, 146, 6, 146, 827, 10, 146, 13, 146, 14, 146, 828, 3, 146, 3, 146, 3, 147, 5, 147, 834, 10, 147, 3, 147, 6, 147, 837, 10, 147, 13, 147, 14, 147, 838, 3, 147, 3, 147, 3, 148, 6, 148, 844, 10, 148, 13, 148, 14, 148, 845, 3, 148, 3, 148, 3, 149, 3, 149, 6, 149, 852, 10, 149, 13, 149, 14, 149, 853, 3, 149, 3, 149, 3, 150, 3, 150, 6, 150, 860, 10, 150, 13, 150, 14, 150, 861, 3, 150, 3, 150, 3, 151, 3, 151, 7, 151, 868, 10, 151, 12, 151, 14, 151, 871, 11, 151, 3, 152, 3, 152, 7, 152, 875, 10, 152, 12, 152, 14, 152, 878, 11, 152, 3, 152, 3, 152, 3, 153, 3, 153, 2, 2, 154, 3, 3, 5, 4, 7, 5, 9, 2, 11, 2, 13, 2, 15, 2, 17, 2, 19, 2, 21, 2, 23, 2, 25, 2, 27, 2, 29, 2, 31, 2, 33, 2, 35, 2, 37, 2, 39, 2, 41, 2, 43, 2, 45, 2, 47, 2, 49, 2, 51, 2, 53, 2, 55, 2, 57, 6, 59, 7, 61, 8, 63, 9, 65, 10, 67, 11, 69, 12, 71, 13, 73, 14, 75, 15, 77, 16, 79, 17, 81, 18, 83, 19, 85, 20, 87, 21, 89, 22, 91, 23, 93, 24, 95, 25, 97, 26, 99, 27, 101, 28, 103, 29, 105, 30, 107, 31, 109, 32, 111, 33, 113, 34, 115, 35, 117, 36, 119, 37, 121, 38, 123, 39, 125, 40, 127, 41, 129, 42, 131, 43, 133, 44, 135, 45, 137, 46, 139, 47, 141, 48, 143, 49, 145, 50, 147, 51, 149, 52, 151, 53, 153, 54, 155, 55, 157, 56, 159, 57, 161, 58, 163, 59, 165, 60, 167, 61, 169, 62, 171, 63, 173, 64, 175, 65, 177, 66, 179, 67, 181, 68, 183, 69, 185, 70, 187, 71, 189, 72, 191, 73, 193, 74, 195, 75, 197, 76, 199, 77, 201, 78, 203, 79, 205, 80, 207, 81, 209, 82, 211, 83, 213, 84, 215, 85, 217, 86, 219, 87, 221, 88, 223, 89, 225, 90, 227, 91, 229, 92, 231, 93, 233, 94, 235, 95, 237, 96, 239, 97, 241, 98, 243, 99, 245, 100, 247, 101, 249, 102, 251, 103, 253, 104, 255, 105, 257, 106, 259, 107, 261, 108, 263, 109, 265, 110, 267, 111, 269, 112, 271, 113, 273, 114, 275, 115, 277, 116, 279, 117, 281, 118, 283, 119, 285, 120, 287, 121, 289, 122, 291, 123, 293, 124, 295, 125, 297, 126, 299, 127, 301, 128, 303, 129, 305, 130, 3, 2, 40, 5, 2, 11, 11, 14, 14, 34, 34, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 92, 92, 124, 124, 3, 2, 47, 47, 3, 2, 50, 59, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 4, 2, 41, 41, 96, 96, 4, 2, 36, 36, 96, 96, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 2, 876, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 157, 3, 2, 2, 2, 2, 159, 3, 2, 2, 2, 2, 161, 3, 2, 2, 2, 2, 163, 3, 2, 2, 2, 2, 165, 3, 2, 2, 2, 2, 167, 3, 2, 2, 2, 2, 169, 3, 2, 2, 2, 2, 171, 3, 2, 2, 2, 2, 173, 3, 2, 2, 2, 2, 175, 3, 2, 2, 2, 2, 177, 3, 2, 2, 2, 2, 179, 3, 2, 2, 2, 2, 181, 3, 2, 2, 2, 2, 183, 3, 2, 2, 2, 2, 185, 3, 2, 2, 2, 2, 187, 3, 2, 2, 2, 2, 189, 3, 2, 2, 2, 2, 191, 3, 2, 2, 2, 2, 193, 3, 2, 2, 2, 2, 195, 3, 2, 2, 2, 2, 197, 3, 2, 2, 2, 2, 199, 3, 2, 2, 2, 2, 201, 3, 2, 2, 2, 2, 203, 3, 2, 2, 2, 2, 205, 3, 2, 2, 2, 2, 207, 3, 2, 2, 2, 2, 209, 3, 2, 2, 2, 2, 211, 3, 2, 2, 2, 2, 213, 3, 2, 2, 2, 2, 215, 3, 2, 2, 2, 2, 217, 3, 2, 2, 2, 2, 219, 3, 2, 2, 2, 2, 221, 3, 2, 2, 2, 2, 223, 3, 2, 2, 2, 2, 225, 3, 2, 2, 2, 2, 227, 3, 2, 2, 2, 2, 229, 3, 2, 2, 2, 2, 231, 3, 2, 2, 2, 2, 233, 3, 2, 2, 2, 2, 235, 3, 2, 2, 2, 2, 237, 3, 2, 2, 2, 2, 239, 3, 2, 2, 2, 2, 241, 3, 2, 2, 2, 2, 243, 3, 2, 2, 2, 2, 245, 3, 2, 2, 2, 2, 247, 3, 2, 2, 2, 2, 249, 3, 2, 2, 2, 2, 251, 3, 2, 2, 2, 2, 253, 3, 2, 2, 2, 2, 255, 3, 2, 2, 2, 2, 257, 3, 2, 2, 2, 2, 259, 3, 2, 2, 2, 2, 261, 3, 2, 2, 2, 2, 263, 3, 2, 2, 2, 2, 265, 3, 2, 2, 2, 2, 267, 3, 2, 2, 2, 2, 269, 3, 2, 2, 2, 2, 271, 3, 2, 2, 2, 2, 273, 3, 2, 2, 2, 2, 275, 3, 2, 2, 2, 2, 277, 3, 2, 2, 2, 2, 279, 3, 2, 2, 2, 2, 281, 3, 2, 2, 2, 2, 283, 3, 2, 2, 2, 2, 285, 3, 2, 2, 2, 2, 287, 3, 2, 2, 2, 2, 289, 3, 2, 2, 2, 2, 291, 3, 2, 2, 2, 2, 293, 3, 2, 2, 2, 2, 295, 3, 2, 2, 2, 2, 297, 3, 2, 2, 2, 2, 299, 3, 2, 2, 2, 2, 301, 3, 2, 2, 2, 2, 303, 3, 2, 2, 2, 2, 305, 3, 2, 2, 2, 3, 307, 3, 2, 2, 2, 5, 316, 3, 2, 2, 2, 7, 325, 3, 2, 2, 2, 9, 329, 3, 2, 2, 2, 11, 331, 3, 2, 2, 2, 13, 333, 3, 2, 2, 2, 15, 335, 3, 2, 2, 2, 17, 337, 3, 2, 2, 2, 19, 339, 3, 2, 2, 2, 21, 341, 3, 2, 2, 2, 23, 343, 3, 2, 2, 2, 25, 345, 3, 2, 2, 2, 27, 347, 3, 2, 2, 2, 29, 349, 3, 2, 2, 2, 31, 351, 3, 2, 2, 2, 33, 353, 3, 2, 2, 2, 35, 355, 3, 2, 2, 2, 37, 357, 3, 2, 2, 2, 39, 359, 3, 2, 2, 2, 41, 361, 3, 2, 2, 2, 43, 363, 3, 2, 2, 2, 45, 365, 3, 2, 2, 2, 47, 367, 3, 2, 2, 2, 49, 369, 3, 2, 2, 2, 51, 371, 3, 2, 2, 2, 53, 373, 3, 2, 2, 2, 55, 375, 3, 2, 2, 2, 57, 377, 3, 2, 2, 2, 59, 381, 3, 2, 2, 2, 61, 385, 3, 2, 2, 2, 63, 389, 3, 2, 2, 2, 65, 393, 3, 2, 2, 2, 67, 397, 3, 2, 2, 2, 69, 401, 3, 2, 2, 2, 71, 405, 3, 2, 2, 2, 73, 409, 3, 2, 2, 2, 75, 414, 3, 2, 2, 2, 77, 419, 3, 2, 2, 2, 79, 423, 3, 2, 2, 2, 81, 427, 3, 2, 2, 2, 83, 431, 3, 2, 2, 2, 85, 435, 3, 2, 2, 2, 87, 439, 3, 2, 2, 2, 89, 443, 3, 2, 2, 2, 91, 447, 3, 2, 2, 2, 93, 451, 3, 2, 2, 2, 95, 455, 3, 2, 2, 2, 97, 459, 3, 2, 2, 2, 99, 463, 3, 2, 2, 2, 101, 467, 3, 2, 2, 2, 103, 472, 3, 2, 2, 2, 105, 476, 3, 2, 2, 2, 107, 480, 3, 2, 2, 2, 109, 484, 3, 2, 2, 2, 111, 488, 3, 2, 2, 2, 113, 493, 3, 2, 2, 2, 115, 498, 3, 2, 2, 2, 117, 503, 3, 2, 2, 2, 119, 507, 3, 2, 2, 2, 121, 511, 3, 2, 2, 2, 123, 515, 3, 2, 2, 2, 125, 519, 3, 2, 2, 2, 127, 523, 3, 2, 2, 2, 129, 527, 3, 2, 2, 2, 131, 531, 3, 2, 2, 2, 133, 535, 3, 2, 2, 2, 135, 539, 3, 2, 2, 2, 137, 543, 3, 2, 2, 2, 139, 547, 3, 2, 2, 2, 141, 551, 3, 2, 2, 2, 143, 556, 3, 2, 2, 2, 145, 561, 3, 2, 2, 2, 147, 566, 3, 2, 2, 2, 149, 570, 3, 2, 2, 2, 151, 573, 3, 2, 2, 2, 153, 577, 3, 2, 2, 2, 155, 580, 3, 2, 2, 2, 157, 584, 3, 2, 2, 2, 159, 587, 3, 2, 2, 2, 161, 590, 3, 2, 2, 2, 163, 594, 3, 2, 2, 2, 165, 598, 3, 2, 2, 2, 167, 603, 3, 2, 2, 2, 169, 606, 3, 2, 2, 2, 171, 610, 3, 2, 2, 2, 173, 613, 3, 2, 2, 2, 175, 617, 3, 2, 2, 2, 177, 620, 3, 2, 2, 2, 179, 623, 3, 2, 2, 2, 181, 627, 3, 2, 2, 2, 183, 631, 3, 2, 2, 2, 185, 635, 3, 2, 2, 2, 187, 638, 3, 2, 2, 2, 189, 642, 3, 2, 2, 2, 191, 645, 3, 2, 2, 2, 193, 649, 3, 2, 2, 2, 195, 652, 3, 2, 2, 2, 197, 655, 3, 2, 2, 2, 199, 659, 3, 2, 2, 2, 201, 663, 3, 2, 2, 2, 203, 667, 3, 2, 2, 2, 205, 670, 3, 2, 2, 2, 207, 673, 3, 2, 2, 2, 209, 676, 3, 2, 2, 2, 211, 680, 3, 2, 2, 2, 213, 684, 3, 2, 2, 2, 215, 688, 3, 2, 2, 2, 217, 692, 3, 2, 2, 2, 219, 696, 3, 2, 2, 2, 221, 704, 3, 2, 2, 2, 223, 707, 3, 2, 2, 2, 225, 713, 3, 2, 2, 2, 227, 719, 3, 2, 2, 2, 229, 724, 3, 2, 2, 2, 231, 727, 3, 2, 2, 2, 233, 730, 3, 2, 2, 2, 235, 733, 3, 2, 2, 2, 237, 735, 3, 2, 2, 2, 239, 737, 3, 2, 2, 2, 241, 739, 3, 2, 2, 2, 243, 741, 3, 2, 2, 2, 245, 743, 3, 2, 2, 2, 247, 745, 3, 2, 2, 2, 249, 747, 3, 2, 2, 2, 251, 749, 3, 2, 2, 2, 253, 751, 3, 2, 2, 2, 255, 755, 3, 2, 2, 2, 257, 758, 3, 2, 2, 2, 259, 760, 3, 2, 2, 2, 261, 762, 3, 2, 2, 2, 263, 764, 3, 2, 2, 2, 265, 766, 3, 2, 2, 2, 267, 768, 3, 2, 2, 2, 269, 770, 3, 2, 2, 2, 271, 772, 3, 2, 2, 2, 273, 774, 3, 2, 2, 2, 275, 778, 3, 2, 2, 2, 277, 782, 3, 2, 2, 2, 279, 786, 3, 2, 2, 2, 281, 790, 3, 2, 2, 2, 283, 794, 3, 2, 2, 2, 285, 797, 3, 2, 2, 2, 287, 802, 3, 2, 2, 2, 289, 813, 3, 2, 2, 2, 291, 823, 3, 2, 2, 2, 293, 833, 3, 2, 2, 2, 295, 843, 3, 2, 2, 2, 297, 849, 3, 2, 2, 2, 299, 857, 3, 2, 2, 2, 301, 865, 3, 2, 2, 2, 303, 872, 3, 2, 2, 2, 305, 881, 3, 2, 2, 2, 307, 308, 9, 2, 2, 2, 308, 309, 3, 2, 2, 2, 309, 310, 8, 2, 2, 2, 310, 4, 3, 2, 2, 2, 311, 312, 7, 49, 2, 2, 312, 317, 7, 49, 2, 2, 313, 314, 7, 47, 2, 2, 314, 317, 7, 47, 2, 2, 315, 317, 9, 3, 2, 2, 316, 311, 3, 2, 2, 2, 316, 313, 3, 2, 2, 2, 316, 315, 3, 2, 2, 2, 317, 321, 3, 2, 2, 2, 318, 320, 10, 4, 2, 2, 319, 318, 3, 2, 2, 2, 320, 323, 3, 2, 2, 2, 321, 319, 3, 2, 2, 2, 321, 322, 3, 2, 2, 2, 322, 6, 3, 2, 2, 2, 323, 321, 3, 2, 2, 2, 324, 326, 7, 15, 2, 2, 325, 324, 3, 2, 2, 2, 325, 326, 3, 2, 2, 2, 326, 327, 3, 2, 2, 2, 327, 328, 7, 12, 2, 2, 328, 8, 3, 2, 2, 2, 329, 330, 9, 5, 2, 2, 330, 10, 3, 2, 2, 2, 331, 332, 9, 6, 2, 2, 332, 12, 3, 2, 2, 2, 333, 334, 9, 7, 2, 2, 334, 14, 3, 2, 2, 2, 335, 336, 9, 8, 2, 2, 336, 16, 3, 2, 2, 2, 337, 338, 9, 9, 2, 2, 338, 18, 3, 2, 2, 2, 339, 340, 9, 10, 2, 2, 340, 20, 3, 2, 2, 2, 341, 342, 9, 11, 2, 2, 342, 22, 3, 2, 2, 2, 343, 344, 9, 12, 2, 2, 344, 24, 3, 2, 2, 2, 345, 346, 9, 13, 2, 2, 346, 26, 3, 2, 2, 2, 347, 348, 9, 14, 2, 2, 348, 28, 3, 2, 2, 2, 349, 350, 9, 15, 2, 2, 350, 30, 3, 2, 2, 2, 351, 352, 9, 16, 2, 2, 352, 32, 3, 2, 2, 2, 353, 354, 9, 17, 2, 2, 354, 34, 3, 2, 2, 2, 355, 356, 9, 18, 2, 2, 356, 36, 3, 2, 2, 2, 357, 358, 9, 19, 2, 2, 358, 38, 3, 2, 2, 2, 359, 360, 9, 20, 2, 2, 360, 40, 3, 2, 2, 2, 361, 362, 9, 21, 2, 2, 362, 42, 3, 2, 2, 2, 363, 364, 9, 22, 2, 2, 364, 44, 3, 2, 2, 2, 365, 366, 9, 23, 2, 2, 366, 46, 3, 2, 2, 2, 367, 368, 9, 24, 2, 2, 368, 48, 3, 2, 2, 2, 369, 370, 9, 25, 2, 2, 370, 50, 3, 2, 2, 2, 371, 372, 9, 26, 2, 2, 372, 52, 3, 2, 2, 2, 373, 374, 9, 27, 2, 2, 374, 54, 3, 2, 2, 2, 375, 376, 9, 28, 2, 2, 376, 56, 3, 2, 2, 2, 377, 378, 5, 43, 22, 2, 378, 379, 5, 45, 23, 2, 379, 380, 5, 13, 7, 2, 380, 58, 3, 2, 2, 2, 381, 382, 5, 13, 7, 2, 382, 383, 5, 31, 16, 2, 383, 384, 5, 13, 7, 2, 384, 60, 3, 2, 2, 2, 385, 386, 5, 25, 13, 2, 386, 387, 5, 33, 17, 2, 387, 388, 5, 41, 21, 2, 388, 62, 3, 2, 2, 2, 389, 390, 5, 15, 8, 2, 390, 391, 5, 13, 7, 2, 391, 392, 5, 41, 21, 2, 392, 64, 3, 2, 2, 2, 393, 394, 5, 13, 7, 2, 394, 395, 5, 31, 16, 2, 395, 396, 5, 9, 5, 2, 396, 66, 3, 2, 2, 2, 397, 398, 5, 15, 8, 2, 398, 399, 5, 9, 5, 2, 399, 400, 5, 9, 5, 2, 400, 68, 3, 2, 2, 2, 401, 402, 5, 33, 17, 2, 402, 403, 5, 35, 18, 2, 403, 404, 5, 37, 19, 2, 404, 70, 3, 2, 2, 2, 405, 406, 5, 31, 16, 2, 406, 407, 5, 35, 18, 2, 407, 408, 5, 49, 25, 2, 408, 72, 3, 2, 2, 2, 409, 410, 5, 43, 22, 2, 410, 411, 5, 45, 23, 2, 411, 412, 5, 9, 5, 2, 412, 413, 5, 53, 27, 2, 413, 74, 3, 2, 2, 2, 414, 415, 5, 29, 15, 2, 415, 416, 5, 15, 8, 2, 416, 417, 5, 9, 5, 2, 417, 418, 5, 53, 27, 2, 418, 76, 3, 2, 2, 2, 419, 420, 5, 9, 5, 2, 420, 421, 5, 15, 8, 2, 421, 422, 5, 15, 8, 2, 422, 78, 3, 2, 2, 2, 423, 424, 5, 9, 5, 2, 424, 425, 5, 15, 8, 2, 425, 426, 5, 13, 7, 2, 426, 80, 3, 2, 2, 2, 427, 428, 5, 43, 22, 2, 428, 429, 5, 47, 24, 2, 429, 430, 5, 11, 6, 2, 430, 82, 3, 2, 2, 2, 431, 432, 5, 43, 22, 2, 432, 433, 5, 11, 6, 2, 433, 434, 5, 11, 6, 2, 434, 84, 3, 2, 2, 2, 435, 436, 5, 9, 5, 2, 436, 437, 5, 33, 17, 2, 437, 438, 5, 9, 5, 2, 438, 86, 3, 2, 2, 2, 439, 440, 5, 53, 27, 2, 440, 441, 5, 41, 21, 2, 441, 442, 5, 9, 5, 2, 442, 88, 3, 2, 2, 2, 443, 444, 5, 35, 18, 2, 444, 445, 5, 41, 21, 2, 445, 446, 5, 9, 5, 2, 446, 90, 3, 2, 2, 2, 447, 448, 5, 13, 7, 2, 448, 449, 5, 31, 16, 2, 449, 450, 5, 37, 19, 2, 450, 92, 3, 2, 2, 2, 451, 452, 5, 41, 21, 2, 452, 453, 5, 29, 15, 2, 453, 454, 5, 13, 7, 2, 454, 94, 3, 2, 2, 2, 455, 456, 5, 41, 21, 2, 456, 457, 5, 41, 21, 2, 457, 458, 5, 13, 7, 2, 458, 96, 3, 2, 2, 2, 459, 460, 5, 41, 21, 2, 460, 461, 5, 9, 5, 2, 461, 462, 5, 29, 15, 2, 462, 98, 3, 2, 2, 2, 463, 464, 5, 41, 21, 2, 464, 465, 5, 9, 5, 2, 465, 466, 5, 41, 21, 2, 466, 100, 3, 2, 2, 2, 467, 468, 5, 37, 19, 2, 468, 469, 5, 47, 24, 2, 469, 470, 5, 43, 22, 2, 470, 471, 5, 23, 12, 2, 471, 102, 3, 2, 2, 2, 472, 473, 5, 37, 19, 2, 473, 474, 5, 35, 18, 2, 474, 475, 5, 37, 19, 2, 475, 104, 3, 2, 2, 2, 476, 477, 5, 15, 8, 2, 477, 478, 5, 9, 5, 2, 478, 479, 5, 15, 8, 2, 479, 106, 3, 2, 2, 2, 480, 481, 5, 25, 13, 2, 481, 482, 5, 33, 17, 2, 482, 483, 5, 53, 27, 2, 483, 108, 3, 2, 2, 2, 484, 485, 5, 15, 8, 2, 485, 486, 5, 13, 7, 2, 486, 487, 5, 53, 27, 2, 487, 110, 3, 2, 2, 2, 488, 489, 5, 53, 27, 2, 489, 490, 5, 13, 7, 2, 490, 491, 5, 23, 12, 2, 491, 492, 5, 21, 11, 2, 492, 112, 3, 2, 2, 2, 493, 494, 5, 53, 27, 2, 494, 495, 5, 45, 23, 2, 495, 496, 5, 23, 12, 2, 496, 497, 5, 29, 15, 2, 497, 114, 3, 2, 2, 2, 498, 499, 5, 43, 22, 2, 499, 500, 5, 37, 19, 2, 500, 501, 5, 23, 12, 2, 501, 502, 5, 29, 15, 2, 502, 116, 3, 2, 2, 2, 503, 504, 5, 29, 15, 2, 504, 505, 5, 53, 27, 2, 505, 506, 5, 25, 13, 2, 506, 118, 3, 2, 2, 2, 507, 508, 5, 31, 16, 2, 508, 509, 5, 49, 25, 2, 509, 510, 5, 25, 13, 2, 510, 120, 3, 2, 2, 2, 511, 512, 5, 9, 5, 2, 512, 513, 5, 15, 8, 2, 513, 514, 5, 25, 13, 2, 514, 122, 3, 2, 2, 2, 515, 516, 5, 9, 5, 2, 516, 517, 5, 13, 7, 2, 517, 518, 5, 25, 13, 2, 518, 124, 3, 2, 2, 2, 519, 520, 5, 43, 22, 2, 520, 521, 5, 47, 24, 2, 521, 522, 5, 25, 13, 2, 522, 126, 3, 2, 2, 2, 523, 524, 5, 43, 22, 2, 524, 525, 5, 11, 6, 2, 525, 526, 5, 25, 13, 2, 526, 128, 3, 2, 2, 2, 527, 528, 5, 9, 5, 2, 528, 529, 5, 33, 17, 2, 529, 530, 5, 25, 13, 2, 530, 130, 3, 2, 2, 2, 531, 532, 5, 53, 27, 2, 532, 533, 5, 41, 21, 2, 533, 534, 5, 25, 13, 2, 534, 132, 3, 2, 2, 2, 535, 536, 5, 35, 18, 2, 536, 537, 5, 41, 21, 2, 537, 538, 5, 25, 13, 2, 538, 134, 3, 2, 2, 2, 539, 540, 5, 13, 7, 2, 540, 541, 5, 37, 19, 2, 541, 542, 5, 25, 13, 2, 542, 136, 3, 2, 2, 2, 543, 544, 5, 43, 22, 2, 544, 545, 5, 45, 23, 2, 545, 546, 5, 9, 5, 2, 546, 138, 3, 2, 2, 2, 547, 548, 5, 29, 15, 2, 548, 549, 5, 15, 8, 2, 549, 550, 5, 9, 5, 2, 550, 140, 3, 2, 2, 2, 551, 552, 5, 43, 22, 2, 552, 553, 5, 23, 12, 2, 553, 554, 5, 29, 15, 2, 554, 555, 5, 15, 8, 2, 555, 142, 3, 2, 2, 2, 556, 557, 5, 29, 15, 2, 557, 558, 5, 23, 12, 2, 558, 559, 5, 29, 15, 2, 559, 560, 5, 15, 8, 2, 560, 144, 3, 2, 2, 2, 561, 562, 5, 37, 19, 2, 562, 563, 5, 13, 7, 2, 563, 564, 5, 23, 12, 2, 564, 565, 5, 29, 15, 2, 565, 146, 3, 2, 2, 2, 566, 567, 5, 27, 14, 2, 567, 568, 5, 31, 16, 2, 568, 569, 5, 37, 19, 2, 569, 148, 3, 2, 2, 2, 570, 571, 5, 27, 14, 2, 571, 572, 5, 13, 7, 2, 572, 150, 3, 2, 2, 2, 573, 574, 5, 27, 14, 2, 574, 575, 5, 33, 17, 2, 575, 576, 5, 13, 7, 2, 576, 152, 3, 2, 2, 2, 577, 578, 5, 27, 14, 2, 578, 579, 5, 55, 28, 2, 579, 154, 3, 2, 2, 2, 580, 581, 5, 27, 14, 2, 581, 582, 5, 33, 17, 2, 582, 583, 5, 55, 28, 2, 583, 156, 3, 2, 2, 2, 584, 585, 5, 27, 14, 2, 585, 586, 5, 37, 19, 2, 586, 158, 3, 2, 2, 2, 587, 588, 5, 27, 14, 2, 588, 589, 5, 31, 16, 2, 589, 160, 3, 2, 2, 2, 590, 591, 5, 27, 14, 2, 591, 592, 5, 37, 19, 2, 592, 593, 5, 17, 9, 2, 593, 162, 3, 2, 2, 2, 594, 595, 5, 27, 14, 2, 595, 596, 5, 37, 19, 2, 596, 597, 5, 35, 18, 2, 597, 164, 3, 2, 2, 2, 598, 599, 5, 13, 7, 2, 599, 600, 5, 9, 5, 2, 600, 601, 5, 29, 15, 2, 601, 602, 5, 29, 15, 2, 602, 166, 3, 2, 2, 2, 603, 604, 5, 13, 7, 2, 604, 605, 5, 13, 7, 2, 605, 168, 3, 2, 2, 2, 606, 607, 5, 13, 7, 2, 607, 608, 5, 33, 17, 2, 608, 609, 5, 13, 7, 2, 609, 170, 3, 2, 2, 2, 610, 611, 5, 13, 7, 2, 611, 612, 5, 55, 28, 2, 612, 172, 3, 2, 2, 2, 613, 614, 5, 13, 7, 2, 614, 615, 5, 33, 17, 2, 615, 616, 5, 55, 28, 2, 616, 174, 3, 2, 2, 2, 617, 618, 5, 13, 7, 2, 618, 619, 5, 37, 19, 2, 619, 176, 3, 2, 2, 2, 620, 621, 5, 13, 7, 2, 621, 622, 5, 31, 16, 2, 622, 178, 3, 2, 2, 2, 623, 624, 5, 13, 7, 2, 624, 625, 5, 37, 19, 2, 625, 626, 5, 17, 9, 2, 626, 180, 3, 2, 2, 2, 627, 628, 5, 13, 7, 2, 628, 629, 5, 37, 19, 2, 629, 630, 5, 35, 18, 2, 630, 182, 3, 2, 2, 2, 631, 632, 5, 41, 21, 2, 632, 633, 5, 17, 9, 2, 633, 634, 5, 45, 23, 2, 634, 184, 3, 2, 2, 2, 635, 636, 5, 41, 21, 2, 636, 637, 5, 13, 7, 2, 637, 186, 3, 2, 2, 2, 638, 639, 5, 41, 21, 2, 639, 640, 5, 33, 17, 2, 640, 641, 5, 13, 7, 2, 641, 188, 3, 2, 2, 2, 642, 643, 5, 41, 21, 2, 643, 644, 5, 55, 28, 2, 644, 190, 3, 2, 2, 2, 645, 646, 5, 41, 21, 2, 646, 647, 5, 33, 17, 2, 647, 648, 5, 55, 28, 2, 648, 192, 3, 2, 2, 2, 649, 650, 5, 41, 21, 2, 650, 651, 5, 31, 16, 2, 651, 194, 3, 2, 2, 2, 652, 653, 5, 41, 21, 2, 653, 654, 5, 37, 19, 2, 654, 196, 3, 2, 2, 2, 655, 656, 5, 41, 21, 2, 656, 657, 5, 37, 19, 2, 657, 658, 5, 17, 9, 2, 658, 198, 3, 2, 2, 2, 659, 660, 5, 41, 21, 2, 660, 661, 5, 37, 19, 2, 661, 662, 5, 35, 18, 2, 662, 200, 3, 2, 2, 2, 663, 664, 5, 41, 21, 2, 664, 665, 5, 43, 22, 2, 665, 666, 5, 45, 23, 2, 666, 202, 3, 2, 2, 2, 667, 668, 5, 17, 9, 2, 668, 669, 5, 25, 13, 2, 669, 204, 3, 2, 2, 2, 670, 671, 5, 15, 8, 2, 671, 672, 5, 25, 13, 2, 672, 206, 3, 2, 2, 2, 673, 674, 5, 25, 13, 2, 674, 675, 5, 33, 17, 2, 675, 208, 3, 2, 2, 2, 676, 677, 5, 35, 18, 2, 677, 678, 5, 47, 24, 2, 678, 679, 5, 45, 23, 2, 679, 210, 3, 2, 2, 2, 680, 681, 5, 23, 12, 2, 681, 682, 5, 29, 15, 2, 682, 683, 5, 45, 23, 2, 683, 212, 3, 2, 2, 2, 684, 685, 5, 35, 18, 2, 685, 686, 5, 41, 21, 2, 686, 687, 5, 21, 11, 2, 687, 214, 3, 2, 2, 2, 688, 689, 5, 17, 9, 2, 689, 690, 5, 39, 20, 2, 690, 691, 5, 47, 24, 2, 691, 216, 3, 2, 2, 2, 692, 693, 5, 43, 22, 2, 693, 694, 5, 17, 9, 2, 694, 695, 5, 45, 23, 2, 695, 218, 3, 2, 2, 2, 696, 697, 5, 25, 13, 2, 697, 698, 5, 33, 17, 2, 698, 699, 5, 13, 7, 2, 699, 700, 5, 29, 15, 2, 700, 701, 5, 47, 24, 2, 701, 702, 5, 15, 8, 2, 702, 703, 5, 17, 9, 2, 703, 220, 3, 2, 2, 2, 704, 705, 5, 25, 13, 2, 705, 706, 5, 19, 10, 2, 706, 222, 3, 2, 2, 2, 707, 708, 5, 17, 9, 2, 708, 709, 5, 33, 17, 2, 709, 710, 5, 15, 8, 2, 710, 711, 5, 25, 13, 2, 711, 712, 5, 19, 10, 2, 712, 224, 3, 2, 2, 2, 713, 714, 5, 31, 16, 2, 714, 715, 5, 9, 5, 2, 715, 716, 5, 13, 7, 2, 716, 717, 5, 41, 21, 2, 717, 718, 5, 35, 18, 2, 718, 226, 3, 2, 2, 2, 719, 720, 5, 17, 9, 2, 720, 721, 5, 33, 17, 2, 721, 722, 5, 15, 8, 2, 722, 723, 5, 31, 16, 2, 723, 228, 3, 2, 2, 2, 724, 725, 5, 15, 8, 2, 725, 726, 5, 11, 6, 2, 726, 230, 3, 2, 2, 2, 727, 728, 5, 15, 8, 2, 728, 729, 5, 51, 26, 2, 729, 232, 3, 2, 2, 2, 730, 731, 5, 15, 8, 2, 731, 732, 5, 43, 22, 2, 732, 234, 3, 2, 2, 2, 733, 734, 7, 38, 2, 2, 734, 236, 3, 2, 2, 2, 735, 736, 5, 9, 5, 2, 736, 238, 3, 2, 2, 2, 737, 738, 5, 11, 6, 2, 738, 240, 3, 2, 2, 2, 739, 740, 5, 13, 7, 2, 740, 242, 3, 2, 2, 2, 741, 742, 5, 15, 8, 2, 742, 244, 3, 2, 2, 2, 743, 744, 5, 17, 9, 2, 744, 246, 3, 2, 2, 2, 745, 746, 5, 23, 12, 2, 746, 248, 3, 2, 2, 2, 747, 748, 5, 29, 15, 2, 748, 250, 3, 2, 2, 2, 749, 750, 5, 31, 16, 2, 750, 252, 3, 2, 2, 2, 751, 752, 5, 37, 19, 2, 752, 753, 5, 43, 22, 2, 753, 754, 5, 51, 26, 2, 754, 254, 3, 2, 2, 2, 755, 756, 5, 43, 22, 2, 756, 757, 5, 37, 19, 2, 757, 256, 3, 2, 2, 2, 758, 759, 7, 42, 2, 2, 759, 258, 3, 2, 2, 2, 760, 761, 7, 43, 2, 2, 761, 260, 3, 2, 2, 2, 762, 763, 7, 46, 2, 2, 763, 262, 3, 2, 2, 2, 764, 765, 7, 45, 2, 2, 765, 264, 3, 2, 2, 2, 766, 767, 7, 47, 2, 2, 767, 266, 3, 2, 2, 2, 768, 769, 7, 44, 2, 2, 769, 268, 3, 2, 2, 2, 770, 771, 7, 49, 2, 2, 771, 270, 3, 2, 2, 2, 772, 773, 7, 63, 2, 2, 773, 272, 3, 2, 2, 2, 774, 775, 5, 31, 16, 2, 775, 776, 5, 35, 18, 2, 776, 777, 5, 15, 8, 2, 777, 274, 3, 2, 2, 2, 778, 779, 5, 43, 22, 2, 779, 780, 5, 23, 12, 2, 780, 781, 5, 41, 21, 2, 781, 276, 3, 2, 2, 2, 782, 783, 5, 43, 22, 2, 783, 784, 5, 23, 12, 2, 784, 785, 5, 29, 15, 2, 785, 278, 3, 2, 2, 2, 786, 787, 5, 33, 17, 2, 787, 788, 5, 35, 18, 2, 788, 789, 5, 45, 23, 2, 789, 280, 3, 2, 2, 2, 790, 791, 5, 9, 5, 2, 791, 792, 5, 33, 17, 2, 792, 793, 5, 15, 8, 2, 793, 282, 3, 2, 2, 2, 794, 795, 5, 35, 18, 2, 795, 796, 5, 41, 21, 2, 796, 284, 3, 2, 2, 2, 797, 798, 5, 53, 27, 2, 798, 799, 5, 35, 18, 2, 799, 800, 5, 41, 21, 2, 800, 286, 3, 2, 2, 2, 801, 803, 9, 29, 2, 2, 802, 801, 3, 2, 2, 2, 802, 803, 3, 2, 2, 2, 803, 805, 3, 2, 2, 2, 804, 806, 9, 30, 2, 2, 805, 804, 3, 2, 2, 2, 806, 807, 3, 2, 2, 2, 807, 805, 3, 2, 2, 2, 807, 808, 3, 2, 2, 2, 808, 810, 3, 2, 2, 2, 809, 811, 5, 15, 8, 2, 810, 809, 3, 2, 2, 2, 810, 811, 3, 2, 2, 2, 811, 288, 3, 2, 2, 2, 812, 814, 9, 29, 2, 2, 813, 812, 3, 2, 2, 2, 813, 814, 3, 2, 2, 2, 814, 815, 3, 2, 2, 2, 815, 816, 7, 50, 2, 2, 816, 818, 5, 53, 27, 2, 817, 819, 9, 31, 2, 2, 818, 817, 3, 2, 2, 2, 819, 820, 3, 2, 2, 2, 820, 818, 3, 2, 2, 2, 820, 821, 3, 2, 2, 2, 821, 290, 3, 2, 2, 2, 822, 824, 9, 29, 2, 2, 823, 822, 3, 2, 2, 2, 823, 824, 3, 2, 2, 2, 824, 826, 3, 2, 2, 2, 825, 827, 9, 31, 2, 2, 826, 825, 3, 2, 2, 2, 827, 828, 3, 2, 2, 2, 828, 826, 3, 2, 2, 2, 828, 829, 3, 2, 2, 2, 829, 830, 3, 2, 2, 2, 830, 831, 5, 23, 12, 2, 831, 292, 3, 2, 2, 2, 832, 834, 9, 29, 2, 2, 833, 832, 3, 2, 2, 2, 833, 834, 3, 2, 2, 2, 834, 836, 3, 2, 2, 2, 835, 837, 9, 32, 2, 2, 836, 835, 3, 2, 2, 2, 837, 838, 3, 2, 2, 2, 838, 836, 3, 2, 2, 2, 838, 839, 3, 2, 2, 2, 839, 840, 3, 2, 2, 2, 840, 841, 9, 33, 2, 2, 841, 294, 3, 2, 2, 2, 842, 844, 9, 34, 2, 2, 843, 842, 3, 2, 2, 2, 844, 845, 3, 2, 2, 2, 845, 843, 3, 2, 2, 2, 845, 846, 3, 2, 2, 2, 846, 847, 3, 2, 2, 2, 847, 848, 5, 11, 6, 2, 848, 296, 3, 2, 2, 2, 849, 851, 9, 35, 2, 2, 850, 852, 9, 36, 2, 2, 851, 850, 3, 2, 2, 2, 852, 853, 3, 2, 2, 2, 853, 851, 3, 2, 2, 2, 853, 854, 3, 2, 2, 2, 854, 855, 3, 2, 2, 2, 855, 856, 9, 35, 2, 2, 856, 298, 3, 2, 2, 2, 857, 859, 7, 36, 2, 2, 858, 860, 9, 37, 2, 2, 859, 858, 3, 2, 2, 2, 860, 861, 3, 2, 2, 2, 861, 859, 3, 2, 2, 2, 861, 862, 3, 2, 2, 2, 862, 863, 3, 2, 2, 2, 863, 864, 7, 36, 2, 2, 864, 300, 3, 2, 2, 2, 865, 869, 9, 38, 2, 2, 866, 868, 9, 39, 2, 2, 867, 866, 3, 2, 2, 2, 868, 871, 3, 2, 2, 2, 869, 867, 3, 2, 2, 2, 869, 870, 3, 2, 2, 2, 870, 302, 3, 2, 2, 2, 871, 869, 3, 2, 2, 2, 872, 876, 9, 38, 2, 2, 873, 875, 9, 39, 2, 2, 874, 873, 3, 2, 2, 2, 875, 878, 3, 2, 2, 2, 876, 874, 3, 2, 2, 2, 876, 877, 3, 2, 2, 2, 877, 879, 3, 2, 2, 2, 878, 876, 3, 2, 2, 2, 879, 880, 7, 60, 2, 2, 880, 304, 3, 2, 2, 2, 881, 882, 11, 2, 2, 2, 882, 306, 3, 2, 2, 2, 20, 2, 316, 321, 325, 802, 807, 810, 813, 820, 823, 828, 833, 838, 845, 853, 861, 869, 876, 3, 2, 3, 2] \ No newline at end of file diff --git a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.java b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.java index 4dc054c3f..36b10dbd5 100644 --- a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.java +++ b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.java @@ -181,7 +181,7 @@ public As8080Lexer(CharStream input) { public ATN getATN() { return _ATN; } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u0082\u0377\b\1\4"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u0082\u0373\b\1\4"+ "\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n"+ "\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+ @@ -231,270 +231,268 @@ public As8080Lexer(CharStream input) { "\3\u008e\3\u008e\3\u008f\3\u008f\3\u008f\3\u008f\3\u0090\5\u0090\u0323"+ "\n\u0090\3\u0090\6\u0090\u0326\n\u0090\r\u0090\16\u0090\u0327\3\u0090"+ "\5\u0090\u032b\n\u0090\3\u0091\5\u0091\u032e\n\u0091\3\u0091\3\u0091\3"+ - "\u0091\3\u0091\5\u0091\u0334\n\u0091\3\u0091\6\u0091\u0337\n\u0091\r\u0091"+ - "\16\u0091\u0338\3\u0092\5\u0092\u033c\n\u0092\3\u0092\6\u0092\u033f\n"+ - "\u0092\r\u0092\16\u0092\u0340\3\u0092\3\u0092\3\u0093\5\u0093\u0346\n"+ - "\u0093\3\u0093\6\u0093\u0349\n\u0093\r\u0093\16\u0093\u034a\3\u0093\3"+ - "\u0093\3\u0094\6\u0094\u0350\n\u0094\r\u0094\16\u0094\u0351\3\u0094\3"+ - "\u0094\3\u0095\3\u0095\6\u0095\u0358\n\u0095\r\u0095\16\u0095\u0359\3"+ - "\u0095\3\u0095\3\u0096\3\u0096\6\u0096\u0360\n\u0096\r\u0096\16\u0096"+ - "\u0361\3\u0096\3\u0096\3\u0097\3\u0097\7\u0097\u0368\n\u0097\f\u0097\16"+ - "\u0097\u036b\13\u0097\3\u0098\3\u0098\7\u0098\u036f\n\u0098\f\u0098\16"+ - "\u0098\u0372\13\u0098\3\u0098\3\u0098\3\u0099\3\u0099\2\2\u009a\3\3\5"+ - "\4\7\5\t\2\13\2\r\2\17\2\21\2\23\2\25\2\27\2\31\2\33\2\35\2\37\2!\2#\2"+ - "%\2\'\2)\2+\2-\2/\2\61\2\63\2\65\2\67\29\6;\7=\b?\tA\nC\13E\fG\rI\16K"+ - "\17M\20O\21Q\22S\23U\24W\25Y\26[\27]\30_\31a\32c\33e\34g\35i\36k\37m "+ - "o!q\"s#u$w%y&{\'}(\177)\u0081*\u0083+\u0085,\u0087-\u0089.\u008b/\u008d"+ - "\60\u008f\61\u0091\62\u0093\63\u0095\64\u0097\65\u0099\66\u009b\67\u009d"+ - "8\u009f9\u00a1:\u00a3;\u00a5<\u00a7=\u00a9>\u00ab?\u00ad@\u00afA\u00b1"+ - "B\u00b3C\u00b5D\u00b7E\u00b9F\u00bbG\u00bdH\u00bfI\u00c1J\u00c3K\u00c5"+ - "L\u00c7M\u00c9N\u00cbO\u00cdP\u00cfQ\u00d1R\u00d3S\u00d5T\u00d7U\u00d9"+ - "V\u00dbW\u00ddX\u00dfY\u00e1Z\u00e3[\u00e5\\\u00e7]\u00e9^\u00eb_\u00ed"+ - "`\u00efa\u00f1b\u00f3c\u00f5d\u00f7e\u00f9f\u00fbg\u00fdh\u00ffi\u0101"+ - "j\u0103k\u0105l\u0107m\u0109n\u010bo\u010dp\u010fq\u0111r\u0113s\u0115"+ - "t\u0117u\u0119v\u011bw\u011dx\u011fy\u0121z\u0123{\u0125|\u0127}\u0129"+ - "~\u012b\177\u012d\u0080\u012f\u0081\u0131\u0082\3\2(\5\2\13\13\16\16\""+ - "\"\4\2%%==\4\2\f\f\17\17\4\2CCcc\4\2DDdd\4\2EEee\4\2FFff\4\2GGgg\4\2H"+ - "Hhh\4\2IIii\4\2JJjj\4\2KKkk\4\2LLll\4\2NNnn\4\2OOoo\4\2PPpp\4\2QQqq\4"+ - "\2RRrr\4\2SSss\4\2TTtt\4\2UUuu\4\2VVvv\4\2WWww\4\2XXxx\4\2YYyy\4\2ZZz"+ - "z\4\2\\\\||\3\2//\3\2\62;\5\2\62;CHch\3\2\629\6\2QQSSqqss\3\2\62\63\3"+ - "\2))\4\2))``\4\2$$``\5\2A\\aac|\6\2\62;A\\aac|\2\u0371\2\3\3\2\2\2\2\5"+ - "\3\2\2\2\2\7\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3"+ - "\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2"+ - "\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2"+ - "[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3"+ - "\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2"+ - "\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2"+ - "\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089"+ - "\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2"+ - "\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b"+ - "\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2"+ - "\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad"+ - "\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2"+ - "\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf"+ - "\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2"+ - "\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1"+ - "\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2"+ - "\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3"+ - "\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9\3\2\2\2\2\u00eb\3\2\2"+ - "\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1\3\2\2\2\2\u00f3\3\2\2\2\2\u00f5"+ - "\3\2\2\2\2\u00f7\3\2\2\2\2\u00f9\3\2\2\2\2\u00fb\3\2\2\2\2\u00fd\3\2\2"+ - "\2\2\u00ff\3\2\2\2\2\u0101\3\2\2\2\2\u0103\3\2\2\2\2\u0105\3\2\2\2\2\u0107"+ - "\3\2\2\2\2\u0109\3\2\2\2\2\u010b\3\2\2\2\2\u010d\3\2\2\2\2\u010f\3\2\2"+ - "\2\2\u0111\3\2\2\2\2\u0113\3\2\2\2\2\u0115\3\2\2\2\2\u0117\3\2\2\2\2\u0119"+ - "\3\2\2\2\2\u011b\3\2\2\2\2\u011d\3\2\2\2\2\u011f\3\2\2\2\2\u0121\3\2\2"+ - "\2\2\u0123\3\2\2\2\2\u0125\3\2\2\2\2\u0127\3\2\2\2\2\u0129\3\2\2\2\2\u012b"+ - "\3\2\2\2\2\u012d\3\2\2\2\2\u012f\3\2\2\2\2\u0131\3\2\2\2\3\u0133\3\2\2"+ - "\2\5\u013c\3\2\2\2\7\u0145\3\2\2\2\t\u0149\3\2\2\2\13\u014b\3\2\2\2\r"+ - "\u014d\3\2\2\2\17\u014f\3\2\2\2\21\u0151\3\2\2\2\23\u0153\3\2\2\2\25\u0155"+ - "\3\2\2\2\27\u0157\3\2\2\2\31\u0159\3\2\2\2\33\u015b\3\2\2\2\35\u015d\3"+ - "\2\2\2\37\u015f\3\2\2\2!\u0161\3\2\2\2#\u0163\3\2\2\2%\u0165\3\2\2\2\'"+ - "\u0167\3\2\2\2)\u0169\3\2\2\2+\u016b\3\2\2\2-\u016d\3\2\2\2/\u016f\3\2"+ - "\2\2\61\u0171\3\2\2\2\63\u0173\3\2\2\2\65\u0175\3\2\2\2\67\u0177\3\2\2"+ - "\29\u0179\3\2\2\2;\u017d\3\2\2\2=\u0181\3\2\2\2?\u0185\3\2\2\2A\u0189"+ - "\3\2\2\2C\u018d\3\2\2\2E\u0191\3\2\2\2G\u0195\3\2\2\2I\u0199\3\2\2\2K"+ - "\u019e\3\2\2\2M\u01a3\3\2\2\2O\u01a7\3\2\2\2Q\u01ab\3\2\2\2S\u01af\3\2"+ - "\2\2U\u01b3\3\2\2\2W\u01b7\3\2\2\2Y\u01bb\3\2\2\2[\u01bf\3\2\2\2]\u01c3"+ - "\3\2\2\2_\u01c7\3\2\2\2a\u01cb\3\2\2\2c\u01cf\3\2\2\2e\u01d3\3\2\2\2g"+ - "\u01d8\3\2\2\2i\u01dc\3\2\2\2k\u01e0\3\2\2\2m\u01e4\3\2\2\2o\u01e8\3\2"+ - "\2\2q\u01ed\3\2\2\2s\u01f2\3\2\2\2u\u01f7\3\2\2\2w\u01fb\3\2\2\2y\u01ff"+ - "\3\2\2\2{\u0203\3\2\2\2}\u0207\3\2\2\2\177\u020b\3\2\2\2\u0081\u020f\3"+ - "\2\2\2\u0083\u0213\3\2\2\2\u0085\u0217\3\2\2\2\u0087\u021b\3\2\2\2\u0089"+ - "\u021f\3\2\2\2\u008b\u0223\3\2\2\2\u008d\u0227\3\2\2\2\u008f\u022c\3\2"+ - "\2\2\u0091\u0231\3\2\2\2\u0093\u0236\3\2\2\2\u0095\u023a\3\2\2\2\u0097"+ - "\u023d\3\2\2\2\u0099\u0241\3\2\2\2\u009b\u0244\3\2\2\2\u009d\u0248\3\2"+ - "\2\2\u009f\u024b\3\2\2\2\u00a1\u024e\3\2\2\2\u00a3\u0252\3\2\2\2\u00a5"+ - "\u0256\3\2\2\2\u00a7\u025b\3\2\2\2\u00a9\u025e\3\2\2\2\u00ab\u0262\3\2"+ - "\2\2\u00ad\u0265\3\2\2\2\u00af\u0269\3\2\2\2\u00b1\u026c\3\2\2\2\u00b3"+ - "\u026f\3\2\2\2\u00b5\u0273\3\2\2\2\u00b7\u0277\3\2\2\2\u00b9\u027b\3\2"+ - "\2\2\u00bb\u027e\3\2\2\2\u00bd\u0282\3\2\2\2\u00bf\u0285\3\2\2\2\u00c1"+ - "\u0289\3\2\2\2\u00c3\u028c\3\2\2\2\u00c5\u028f\3\2\2\2\u00c7\u0293\3\2"+ - "\2\2\u00c9\u0297\3\2\2\2\u00cb\u029b\3\2\2\2\u00cd\u029e\3\2\2\2\u00cf"+ - "\u02a1\3\2\2\2\u00d1\u02a4\3\2\2\2\u00d3\u02a8\3\2\2\2\u00d5\u02ac\3\2"+ - "\2\2\u00d7\u02b0\3\2\2\2\u00d9\u02b4\3\2\2\2\u00db\u02b8\3\2\2\2\u00dd"+ - "\u02c0\3\2\2\2\u00df\u02c3\3\2\2\2\u00e1\u02c9\3\2\2\2\u00e3\u02cf\3\2"+ - "\2\2\u00e5\u02d4\3\2\2\2\u00e7\u02d7\3\2\2\2\u00e9\u02da\3\2\2\2\u00eb"+ - "\u02dd\3\2\2\2\u00ed\u02df\3\2\2\2\u00ef\u02e1\3\2\2\2\u00f1\u02e3\3\2"+ - "\2\2\u00f3\u02e5\3\2\2\2\u00f5\u02e7\3\2\2\2\u00f7\u02e9\3\2\2\2\u00f9"+ - "\u02eb\3\2\2\2\u00fb\u02ed\3\2\2\2\u00fd\u02ef\3\2\2\2\u00ff\u02f3\3\2"+ - "\2\2\u0101\u02f6\3\2\2\2\u0103\u02f8\3\2\2\2\u0105\u02fa\3\2\2\2\u0107"+ - "\u02fc\3\2\2\2\u0109\u02fe\3\2\2\2\u010b\u0300\3\2\2\2\u010d\u0302\3\2"+ - "\2\2\u010f\u0304\3\2\2\2\u0111\u0306\3\2\2\2\u0113\u030a\3\2\2\2\u0115"+ - "\u030e\3\2\2\2\u0117\u0312\3\2\2\2\u0119\u0316\3\2\2\2\u011b\u031a\3\2"+ - "\2\2\u011d\u031d\3\2\2\2\u011f\u0322\3\2\2\2\u0121\u032d\3\2\2\2\u0123"+ - "\u033b\3\2\2\2\u0125\u0345\3\2\2\2\u0127\u034f\3\2\2\2\u0129\u0355\3\2"+ - "\2\2\u012b\u035d\3\2\2\2\u012d\u0365\3\2\2\2\u012f\u036c\3\2\2\2\u0131"+ - "\u0375\3\2\2\2\u0133\u0134\t\2\2\2\u0134\u0135\3\2\2\2\u0135\u0136\b\2"+ - "\2\2\u0136\4\3\2\2\2\u0137\u0138\7\61\2\2\u0138\u013d\7\61\2\2\u0139\u013a"+ - "\7/\2\2\u013a\u013d\7/\2\2\u013b\u013d\t\3\2\2\u013c\u0137\3\2\2\2\u013c"+ - "\u0139\3\2\2\2\u013c\u013b\3\2\2\2\u013d\u0141\3\2\2\2\u013e\u0140\n\4"+ - "\2\2\u013f\u013e\3\2\2\2\u0140\u0143\3\2\2\2\u0141\u013f\3\2\2\2\u0141"+ - "\u0142\3\2\2\2\u0142\6\3\2\2\2\u0143\u0141\3\2\2\2\u0144\u0146\7\17\2"+ - "\2\u0145\u0144\3\2\2\2\u0145\u0146\3\2\2\2\u0146\u0147\3\2\2\2\u0147\u0148"+ - "\7\f\2\2\u0148\b\3\2\2\2\u0149\u014a\t\5\2\2\u014a\n\3\2\2\2\u014b\u014c"+ - "\t\6\2\2\u014c\f\3\2\2\2\u014d\u014e\t\7\2\2\u014e\16\3\2\2\2\u014f\u0150"+ - "\t\b\2\2\u0150\20\3\2\2\2\u0151\u0152\t\t\2\2\u0152\22\3\2\2\2\u0153\u0154"+ - "\t\n\2\2\u0154\24\3\2\2\2\u0155\u0156\t\13\2\2\u0156\26\3\2\2\2\u0157"+ - "\u0158\t\f\2\2\u0158\30\3\2\2\2\u0159\u015a\t\r\2\2\u015a\32\3\2\2\2\u015b"+ - "\u015c\t\16\2\2\u015c\34\3\2\2\2\u015d\u015e\t\17\2\2\u015e\36\3\2\2\2"+ - "\u015f\u0160\t\20\2\2\u0160 \3\2\2\2\u0161\u0162\t\21\2\2\u0162\"\3\2"+ - "\2\2\u0163\u0164\t\22\2\2\u0164$\3\2\2\2\u0165\u0166\t\23\2\2\u0166&\3"+ - "\2\2\2\u0167\u0168\t\24\2\2\u0168(\3\2\2\2\u0169\u016a\t\25\2\2\u016a"+ - "*\3\2\2\2\u016b\u016c\t\26\2\2\u016c,\3\2\2\2\u016d\u016e\t\27\2\2\u016e"+ - ".\3\2\2\2\u016f\u0170\t\30\2\2\u0170\60\3\2\2\2\u0171\u0172\t\31\2\2\u0172"+ - "\62\3\2\2\2\u0173\u0174\t\32\2\2\u0174\64\3\2\2\2\u0175\u0176\t\33\2\2"+ - "\u0176\66\3\2\2\2\u0177\u0178\t\34\2\2\u01788\3\2\2\2\u0179\u017a\5+\26"+ - "\2\u017a\u017b\5-\27\2\u017b\u017c\5\r\7\2\u017c:\3\2\2\2\u017d\u017e"+ - "\5\r\7\2\u017e\u017f\5\37\20\2\u017f\u0180\5\r\7\2\u0180<\3\2\2\2\u0181"+ - "\u0182\5\31\r\2\u0182\u0183\5!\21\2\u0183\u0184\5)\25\2\u0184>\3\2\2\2"+ - "\u0185\u0186\5\17\b\2\u0186\u0187\5\r\7\2\u0187\u0188\5)\25\2\u0188@\3"+ - "\2\2\2\u0189\u018a\5\r\7\2\u018a\u018b\5\37\20\2\u018b\u018c\5\t\5\2\u018c"+ - "B\3\2\2\2\u018d\u018e\5\17\b\2\u018e\u018f\5\t\5\2\u018f\u0190\5\t\5\2"+ - "\u0190D\3\2\2\2\u0191\u0192\5!\21\2\u0192\u0193\5#\22\2\u0193\u0194\5"+ - "%\23\2\u0194F\3\2\2\2\u0195\u0196\5\37\20\2\u0196\u0197\5#\22\2\u0197"+ - "\u0198\5\61\31\2\u0198H\3\2\2\2\u0199\u019a\5+\26\2\u019a\u019b\5-\27"+ - "\2\u019b\u019c\5\t\5\2\u019c\u019d\5\65\33\2\u019dJ\3\2\2\2\u019e\u019f"+ - "\5\35\17\2\u019f\u01a0\5\17\b\2\u01a0\u01a1\5\t\5\2\u01a1\u01a2\5\65\33"+ - "\2\u01a2L\3\2\2\2\u01a3\u01a4\5\t\5\2\u01a4\u01a5\5\17\b\2\u01a5\u01a6"+ - "\5\17\b\2\u01a6N\3\2\2\2\u01a7\u01a8\5\t\5\2\u01a8\u01a9\5\17\b\2\u01a9"+ - "\u01aa\5\r\7\2\u01aaP\3\2\2\2\u01ab\u01ac\5+\26\2\u01ac\u01ad\5/\30\2"+ - "\u01ad\u01ae\5\13\6\2\u01aeR\3\2\2\2\u01af\u01b0\5+\26\2\u01b0\u01b1\5"+ - "\13\6\2\u01b1\u01b2\5\13\6\2\u01b2T\3\2\2\2\u01b3\u01b4\5\t\5\2\u01b4"+ - "\u01b5\5!\21\2\u01b5\u01b6\5\t\5\2\u01b6V\3\2\2\2\u01b7\u01b8\5\65\33"+ - "\2\u01b8\u01b9\5)\25\2\u01b9\u01ba\5\t\5\2\u01baX\3\2\2\2\u01bb\u01bc"+ - "\5#\22\2\u01bc\u01bd\5)\25\2\u01bd\u01be\5\t\5\2\u01beZ\3\2\2\2\u01bf"+ - "\u01c0\5\r\7\2\u01c0\u01c1\5\37\20\2\u01c1\u01c2\5%\23\2\u01c2\\\3\2\2"+ - "\2\u01c3\u01c4\5)\25\2\u01c4\u01c5\5\35\17\2\u01c5\u01c6\5\r\7\2\u01c6"+ - "^\3\2\2\2\u01c7\u01c8\5)\25\2\u01c8\u01c9\5)\25\2\u01c9\u01ca\5\r\7\2"+ - "\u01ca`\3\2\2\2\u01cb\u01cc\5)\25\2\u01cc\u01cd\5\t\5\2\u01cd\u01ce\5"+ - "\35\17\2\u01ceb\3\2\2\2\u01cf\u01d0\5)\25\2\u01d0\u01d1\5\t\5\2\u01d1"+ - "\u01d2\5)\25\2\u01d2d\3\2\2\2\u01d3\u01d4\5%\23\2\u01d4\u01d5\5/\30\2"+ - "\u01d5\u01d6\5+\26\2\u01d6\u01d7\5\27\f\2\u01d7f\3\2\2\2\u01d8\u01d9\5"+ - "%\23\2\u01d9\u01da\5#\22\2\u01da\u01db\5%\23\2\u01dbh\3\2\2\2\u01dc\u01dd"+ - "\5\17\b\2\u01dd\u01de\5\t\5\2\u01de\u01df\5\17\b\2\u01dfj\3\2\2\2\u01e0"+ - "\u01e1\5\31\r\2\u01e1\u01e2\5!\21\2\u01e2\u01e3\5\65\33\2\u01e3l\3\2\2"+ - "\2\u01e4\u01e5\5\17\b\2\u01e5\u01e6\5\r\7\2\u01e6\u01e7\5\65\33\2\u01e7"+ - "n\3\2\2\2\u01e8\u01e9\5\65\33\2\u01e9\u01ea\5\r\7\2\u01ea\u01eb\5\27\f"+ - "\2\u01eb\u01ec\5\25\13\2\u01ecp\3\2\2\2\u01ed\u01ee\5\65\33\2\u01ee\u01ef"+ - "\5-\27\2\u01ef\u01f0\5\27\f\2\u01f0\u01f1\5\35\17\2\u01f1r\3\2\2\2\u01f2"+ - "\u01f3\5+\26\2\u01f3\u01f4\5%\23\2\u01f4\u01f5\5\27\f\2\u01f5\u01f6\5"+ - "\35\17\2\u01f6t\3\2\2\2\u01f7\u01f8\5\35\17\2\u01f8\u01f9\5\65\33\2\u01f9"+ - "\u01fa\5\31\r\2\u01fav\3\2\2\2\u01fb\u01fc\5\37\20\2\u01fc\u01fd\5\61"+ - "\31\2\u01fd\u01fe\5\31\r\2\u01fex\3\2\2\2\u01ff\u0200\5\t\5\2\u0200\u0201"+ - "\5\17\b\2\u0201\u0202\5\31\r\2\u0202z\3\2\2\2\u0203\u0204\5\t\5\2\u0204"+ - "\u0205\5\r\7\2\u0205\u0206\5\31\r\2\u0206|\3\2\2\2\u0207\u0208\5+\26\2"+ - "\u0208\u0209\5/\30\2\u0209\u020a\5\31\r\2\u020a~\3\2\2\2\u020b\u020c\5"+ - "+\26\2\u020c\u020d\5\13\6\2\u020d\u020e\5\31\r\2\u020e\u0080\3\2\2\2\u020f"+ - "\u0210\5\t\5\2\u0210\u0211\5!\21\2\u0211\u0212\5\31\r\2\u0212\u0082\3"+ - "\2\2\2\u0213\u0214\5\65\33\2\u0214\u0215\5)\25\2\u0215\u0216\5\31\r\2"+ - "\u0216\u0084\3\2\2\2\u0217\u0218\5#\22\2\u0218\u0219\5)\25\2\u0219\u021a"+ - "\5\31\r\2\u021a\u0086\3\2\2\2\u021b\u021c\5\r\7\2\u021c\u021d\5%\23\2"+ - "\u021d\u021e\5\31\r\2\u021e\u0088\3\2\2\2\u021f\u0220\5+\26\2\u0220\u0221"+ - "\5-\27\2\u0221\u0222\5\t\5\2\u0222\u008a\3\2\2\2\u0223\u0224\5\35\17\2"+ - "\u0224\u0225\5\17\b\2\u0225\u0226\5\t\5\2\u0226\u008c\3\2\2\2\u0227\u0228"+ - "\5+\26\2\u0228\u0229\5\27\f\2\u0229\u022a\5\35\17\2\u022a\u022b\5\17\b"+ - "\2\u022b\u008e\3\2\2\2\u022c\u022d\5\35\17\2\u022d\u022e\5\27\f\2\u022e"+ - "\u022f\5\35\17\2\u022f\u0230\5\17\b\2\u0230\u0090\3\2\2\2\u0231\u0232"+ - "\5%\23\2\u0232\u0233\5\r\7\2\u0233\u0234\5\27\f\2\u0234\u0235\5\35\17"+ - "\2\u0235\u0092\3\2\2\2\u0236\u0237\5\33\16\2\u0237\u0238\5\37\20\2\u0238"+ - "\u0239\5%\23\2\u0239\u0094\3\2\2\2\u023a\u023b\5\33\16\2\u023b\u023c\5"+ - "\r\7\2\u023c\u0096\3\2\2\2\u023d\u023e\5\33\16\2\u023e\u023f\5!\21\2\u023f"+ - "\u0240\5\r\7\2\u0240\u0098\3\2\2\2\u0241\u0242\5\33\16\2\u0242\u0243\5"+ - "\67\34\2\u0243\u009a\3\2\2\2\u0244\u0245\5\33\16\2\u0245\u0246\5!\21\2"+ - "\u0246\u0247\5\67\34\2\u0247\u009c\3\2\2\2\u0248\u0249\5\33\16\2\u0249"+ - "\u024a\5%\23\2\u024a\u009e\3\2\2\2\u024b\u024c\5\33\16\2\u024c\u024d\5"+ - "\37\20\2\u024d\u00a0\3\2\2\2\u024e\u024f\5\33\16\2\u024f\u0250\5%\23\2"+ - "\u0250\u0251\5\21\t\2\u0251\u00a2\3\2\2\2\u0252\u0253\5\33\16\2\u0253"+ - "\u0254\5%\23\2\u0254\u0255\5#\22\2\u0255\u00a4\3\2\2\2\u0256\u0257\5\r"+ - "\7\2\u0257\u0258\5\t\5\2\u0258\u0259\5\35\17\2\u0259\u025a\5\35\17\2\u025a"+ - "\u00a6\3\2\2\2\u025b\u025c\5\r\7\2\u025c\u025d\5\r\7\2\u025d\u00a8\3\2"+ - "\2\2\u025e\u025f\5\r\7\2\u025f\u0260\5!\21\2\u0260\u0261\5\r\7\2\u0261"+ - "\u00aa\3\2\2\2\u0262\u0263\5\r\7\2\u0263\u0264\5\67\34\2\u0264\u00ac\3"+ - "\2\2\2\u0265\u0266\5\r\7\2\u0266\u0267\5!\21\2\u0267\u0268\5\67\34\2\u0268"+ - "\u00ae\3\2\2\2\u0269\u026a\5\r\7\2\u026a\u026b\5%\23\2\u026b\u00b0\3\2"+ - "\2\2\u026c\u026d\5\r\7\2\u026d\u026e\5\37\20\2\u026e\u00b2\3\2\2\2\u026f"+ - "\u0270\5\r\7\2\u0270\u0271\5%\23\2\u0271\u0272\5\21\t\2\u0272\u00b4\3"+ - "\2\2\2\u0273\u0274\5\r\7\2\u0274\u0275\5%\23\2\u0275\u0276\5#\22\2\u0276"+ - "\u00b6\3\2\2\2\u0277\u0278\5)\25\2\u0278\u0279\5\21\t\2\u0279\u027a\5"+ - "-\27\2\u027a\u00b8\3\2\2\2\u027b\u027c\5)\25\2\u027c\u027d\5\r\7\2\u027d"+ - "\u00ba\3\2\2\2\u027e\u027f\5)\25\2\u027f\u0280\5!\21\2\u0280\u0281\5\r"+ - "\7\2\u0281\u00bc\3\2\2\2\u0282\u0283\5)\25\2\u0283\u0284\5\67\34\2\u0284"+ - "\u00be\3\2\2\2\u0285\u0286\5)\25\2\u0286\u0287\5!\21\2\u0287\u0288\5\67"+ - "\34\2\u0288\u00c0\3\2\2\2\u0289\u028a\5)\25\2\u028a\u028b\5\37\20\2\u028b"+ - "\u00c2\3\2\2\2\u028c\u028d\5)\25\2\u028d\u028e\5%\23\2\u028e\u00c4\3\2"+ - "\2\2\u028f\u0290\5)\25\2\u0290\u0291\5%\23\2\u0291\u0292\5\21\t\2\u0292"+ - "\u00c6\3\2\2\2\u0293\u0294\5)\25\2\u0294\u0295\5%\23\2\u0295\u0296\5#"+ - "\22\2\u0296\u00c8\3\2\2\2\u0297\u0298\5)\25\2\u0298\u0299\5+\26\2\u0299"+ - "\u029a\5-\27\2\u029a\u00ca\3\2\2\2\u029b\u029c\5\21\t\2\u029c\u029d\5"+ - "\31\r\2\u029d\u00cc\3\2\2\2\u029e\u029f\5\17\b\2\u029f\u02a0\5\31\r\2"+ - "\u02a0\u00ce\3\2\2\2\u02a1\u02a2\5\31\r\2\u02a2\u02a3\5!\21\2\u02a3\u00d0"+ - "\3\2\2\2\u02a4\u02a5\5#\22\2\u02a5\u02a6\5/\30\2\u02a6\u02a7\5-\27\2\u02a7"+ - "\u00d2\3\2\2\2\u02a8\u02a9\5\27\f\2\u02a9\u02aa\5\35\17\2\u02aa\u02ab"+ - "\5-\27\2\u02ab\u00d4\3\2\2\2\u02ac\u02ad\5#\22\2\u02ad\u02ae\5)\25\2\u02ae"+ - "\u02af\5\25\13\2\u02af\u00d6\3\2\2\2\u02b0\u02b1\5\21\t\2\u02b1\u02b2"+ - "\5\'\24\2\u02b2\u02b3\5/\30\2\u02b3\u00d8\3\2\2\2\u02b4\u02b5\5+\26\2"+ - "\u02b5\u02b6\5\21\t\2\u02b6\u02b7\5-\27\2\u02b7\u00da\3\2\2\2\u02b8\u02b9"+ - "\5\31\r\2\u02b9\u02ba\5!\21\2\u02ba\u02bb\5\r\7\2\u02bb\u02bc\5\35\17"+ - "\2\u02bc\u02bd\5/\30\2\u02bd\u02be\5\17\b\2\u02be\u02bf\5\21\t\2\u02bf"+ - "\u00dc\3\2\2\2\u02c0\u02c1\5\31\r\2\u02c1\u02c2\5\23\n\2\u02c2\u00de\3"+ - "\2\2\2\u02c3\u02c4\5\21\t\2\u02c4\u02c5\5!\21\2\u02c5\u02c6\5\17\b\2\u02c6"+ - "\u02c7\5\31\r\2\u02c7\u02c8\5\23\n\2\u02c8\u00e0\3\2\2\2\u02c9\u02ca\5"+ - "\37\20\2\u02ca\u02cb\5\t\5\2\u02cb\u02cc\5\r\7\2\u02cc\u02cd\5)\25\2\u02cd"+ - "\u02ce\5#\22\2\u02ce\u00e2\3\2\2\2\u02cf\u02d0\5\21\t\2\u02d0\u02d1\5"+ - "!\21\2\u02d1\u02d2\5\17\b\2\u02d2\u02d3\5\37\20\2\u02d3\u00e4\3\2\2\2"+ - "\u02d4\u02d5\5\17\b\2\u02d5\u02d6\5\13\6\2\u02d6\u00e6\3\2\2\2\u02d7\u02d8"+ - "\5\17\b\2\u02d8\u02d9\5\63\32\2\u02d9\u00e8\3\2\2\2\u02da\u02db\5\17\b"+ - "\2\u02db\u02dc\5+\26\2\u02dc\u00ea\3\2\2\2\u02dd\u02de\7&\2\2\u02de\u00ec"+ - "\3\2\2\2\u02df\u02e0\5\t\5\2\u02e0\u00ee\3\2\2\2\u02e1\u02e2\5\13\6\2"+ - "\u02e2\u00f0\3\2\2\2\u02e3\u02e4\5\r\7\2\u02e4\u00f2\3\2\2\2\u02e5\u02e6"+ - "\5\17\b\2\u02e6\u00f4\3\2\2\2\u02e7\u02e8\5\21\t\2\u02e8\u00f6\3\2\2\2"+ - "\u02e9\u02ea\5\27\f\2\u02ea\u00f8\3\2\2\2\u02eb\u02ec\5\35\17\2\u02ec"+ - "\u00fa\3\2\2\2\u02ed\u02ee\5\37\20\2\u02ee\u00fc\3\2\2\2\u02ef\u02f0\5"+ - "%\23\2\u02f0\u02f1\5+\26\2\u02f1\u02f2\5\63\32\2\u02f2\u00fe\3\2\2\2\u02f3"+ - "\u02f4\5+\26\2\u02f4\u02f5\5%\23\2\u02f5\u0100\3\2\2\2\u02f6\u02f7\7*"+ - "\2\2\u02f7\u0102\3\2\2\2\u02f8\u02f9\7+\2\2\u02f9\u0104\3\2\2\2\u02fa"+ - "\u02fb\7.\2\2\u02fb\u0106\3\2\2\2\u02fc\u02fd\7-\2\2\u02fd\u0108\3\2\2"+ - "\2\u02fe\u02ff\7/\2\2\u02ff\u010a\3\2\2\2\u0300\u0301\7,\2\2\u0301\u010c"+ - "\3\2\2\2\u0302\u0303\7\61\2\2\u0303\u010e\3\2\2\2\u0304\u0305\7?\2\2\u0305"+ - "\u0110\3\2\2\2\u0306\u0307\5\37\20\2\u0307\u0308\5#\22\2\u0308\u0309\5"+ - "\17\b\2\u0309\u0112\3\2\2\2\u030a\u030b\5+\26\2\u030b\u030c\5\27\f\2\u030c"+ - "\u030d\5)\25\2\u030d\u0114\3\2\2\2\u030e\u030f\5+\26\2\u030f\u0310\5\27"+ - "\f\2\u0310\u0311\5\35\17\2\u0311\u0116\3\2\2\2\u0312\u0313\5!\21\2\u0313"+ - "\u0314\5#\22\2\u0314\u0315\5-\27\2\u0315\u0118\3\2\2\2\u0316\u0317\5\t"+ - "\5\2\u0317\u0318\5!\21\2\u0318\u0319\5\17\b\2\u0319\u011a\3\2\2\2\u031a"+ - "\u031b\5#\22\2\u031b\u031c\5)\25\2\u031c\u011c\3\2\2\2\u031d\u031e\5\65"+ - "\33\2\u031e\u031f\5#\22\2\u031f\u0320\5)\25\2\u0320\u011e\3\2\2\2\u0321"+ - "\u0323\t\35\2\2\u0322\u0321\3\2\2\2\u0322\u0323\3\2\2\2\u0323\u0325\3"+ - "\2\2\2\u0324\u0326\t\36\2\2\u0325\u0324\3\2\2\2\u0326\u0327\3\2\2\2\u0327"+ - "\u0325\3\2\2\2\u0327\u0328\3\2\2\2\u0328\u032a\3\2\2\2\u0329\u032b\5\17"+ - "\b\2\u032a\u0329\3\2\2\2\u032a\u032b\3\2\2\2\u032b\u0120\3\2\2\2\u032c"+ - "\u032e\t\35\2\2\u032d\u032c\3\2\2\2\u032d\u032e\3\2\2\2\u032e\u0333\3"+ - "\2\2\2\u032f\u0330\7\62\2\2\u0330\u0334\7z\2\2\u0331\u0332\7\62\2\2\u0332"+ - "\u0334\7Z\2\2\u0333\u032f\3\2\2\2\u0333\u0331\3\2\2\2\u0334\u0336\3\2"+ - "\2\2\u0335\u0337\t\37\2\2\u0336\u0335\3\2\2\2\u0337\u0338\3\2\2\2\u0338"+ - "\u0336\3\2\2\2\u0338\u0339\3\2\2\2\u0339\u0122\3\2\2\2\u033a\u033c\t\35"+ - "\2\2\u033b\u033a\3\2\2\2\u033b\u033c\3\2\2\2\u033c\u033e\3\2\2\2\u033d"+ - "\u033f\t\37\2\2\u033e\u033d\3\2\2\2\u033f\u0340\3\2\2\2\u0340\u033e\3"+ - "\2\2\2\u0340\u0341\3\2\2\2\u0341\u0342\3\2\2\2\u0342\u0343\5\27\f\2\u0343"+ - "\u0124\3\2\2\2\u0344\u0346\t\35\2\2\u0345\u0344\3\2\2\2\u0345\u0346\3"+ - "\2\2\2\u0346\u0348\3\2\2\2\u0347\u0349\t \2\2\u0348\u0347\3\2\2\2\u0349"+ - "\u034a\3\2\2\2\u034a\u0348\3\2\2\2\u034a\u034b\3\2\2\2\u034b\u034c\3\2"+ - "\2\2\u034c\u034d\t!\2\2\u034d\u0126\3\2\2\2\u034e\u0350\t\"\2\2\u034f"+ - "\u034e\3\2\2\2\u0350\u0351\3\2\2\2\u0351\u034f\3\2\2\2\u0351\u0352\3\2"+ - "\2\2\u0352\u0353\3\2\2\2\u0353\u0354\5\13\6\2\u0354\u0128\3\2\2\2\u0355"+ - "\u0357\t#\2\2\u0356\u0358\t$\2\2\u0357\u0356\3\2\2\2\u0358\u0359\3\2\2"+ - "\2\u0359\u0357\3\2\2\2\u0359\u035a\3\2\2\2\u035a\u035b\3\2\2\2\u035b\u035c"+ - "\t#\2\2\u035c\u012a\3\2\2\2\u035d\u035f\7$\2\2\u035e\u0360\t%\2\2\u035f"+ - "\u035e\3\2\2\2\u0360\u0361\3\2\2\2\u0361\u035f\3\2\2\2\u0361\u0362\3\2"+ - "\2\2\u0362\u0363\3\2\2\2\u0363\u0364\7$\2\2\u0364\u012c\3\2\2\2\u0365"+ - "\u0369\t&\2\2\u0366\u0368\t\'\2\2\u0367\u0366\3\2\2\2\u0368\u036b\3\2"+ - "\2\2\u0369\u0367\3\2\2\2\u0369\u036a\3\2\2\2\u036a\u012e\3\2\2\2\u036b"+ - "\u0369\3\2\2\2\u036c\u0370\t&\2\2\u036d\u036f\t\'\2\2\u036e\u036d\3\2"+ - "\2\2\u036f\u0372\3\2\2\2\u0370\u036e\3\2\2\2\u0370\u0371\3\2\2\2\u0371"+ - "\u0373\3\2\2\2\u0372\u0370\3\2\2\2\u0373\u0374\7<\2\2\u0374\u0130\3\2"+ - "\2\2\u0375\u0376\13\2\2\2\u0376\u0132\3\2\2\2\25\2\u013c\u0141\u0145\u0322"+ - "\u0327\u032a\u032d\u0333\u0338\u033b\u0340\u0345\u034a\u0351\u0359\u0361"+ - "\u0369\u0370\3\2\3\2"; + "\u0091\6\u0091\u0333\n\u0091\r\u0091\16\u0091\u0334\3\u0092\5\u0092\u0338"+ + "\n\u0092\3\u0092\6\u0092\u033b\n\u0092\r\u0092\16\u0092\u033c\3\u0092"+ + "\3\u0092\3\u0093\5\u0093\u0342\n\u0093\3\u0093\6\u0093\u0345\n\u0093\r"+ + "\u0093\16\u0093\u0346\3\u0093\3\u0093\3\u0094\6\u0094\u034c\n\u0094\r"+ + "\u0094\16\u0094\u034d\3\u0094\3\u0094\3\u0095\3\u0095\6\u0095\u0354\n"+ + "\u0095\r\u0095\16\u0095\u0355\3\u0095\3\u0095\3\u0096\3\u0096\6\u0096"+ + "\u035c\n\u0096\r\u0096\16\u0096\u035d\3\u0096\3\u0096\3\u0097\3\u0097"+ + "\7\u0097\u0364\n\u0097\f\u0097\16\u0097\u0367\13\u0097\3\u0098\3\u0098"+ + "\7\u0098\u036b\n\u0098\f\u0098\16\u0098\u036e\13\u0098\3\u0098\3\u0098"+ + "\3\u0099\3\u0099\2\2\u009a\3\3\5\4\7\5\t\2\13\2\r\2\17\2\21\2\23\2\25"+ + "\2\27\2\31\2\33\2\35\2\37\2!\2#\2%\2\'\2)\2+\2-\2/\2\61\2\63\2\65\2\67"+ + "\29\6;\7=\b?\tA\nC\13E\fG\rI\16K\17M\20O\21Q\22S\23U\24W\25Y\26[\27]\30"+ + "_\31a\32c\33e\34g\35i\36k\37m o!q\"s#u$w%y&{\'}(\177)\u0081*\u0083+\u0085"+ + ",\u0087-\u0089.\u008b/\u008d\60\u008f\61\u0091\62\u0093\63\u0095\64\u0097"+ + "\65\u0099\66\u009b\67\u009d8\u009f9\u00a1:\u00a3;\u00a5<\u00a7=\u00a9"+ + ">\u00ab?\u00ad@\u00afA\u00b1B\u00b3C\u00b5D\u00b7E\u00b9F\u00bbG\u00bd"+ + "H\u00bfI\u00c1J\u00c3K\u00c5L\u00c7M\u00c9N\u00cbO\u00cdP\u00cfQ\u00d1"+ + "R\u00d3S\u00d5T\u00d7U\u00d9V\u00dbW\u00ddX\u00dfY\u00e1Z\u00e3[\u00e5"+ + "\\\u00e7]\u00e9^\u00eb_\u00ed`\u00efa\u00f1b\u00f3c\u00f5d\u00f7e\u00f9"+ + "f\u00fbg\u00fdh\u00ffi\u0101j\u0103k\u0105l\u0107m\u0109n\u010bo\u010d"+ + "p\u010fq\u0111r\u0113s\u0115t\u0117u\u0119v\u011bw\u011dx\u011fy\u0121"+ + "z\u0123{\u0125|\u0127}\u0129~\u012b\177\u012d\u0080\u012f\u0081\u0131"+ + "\u0082\3\2(\5\2\13\13\16\16\"\"\4\2%%==\4\2\f\f\17\17\4\2CCcc\4\2DDdd"+ + "\4\2EEee\4\2FFff\4\2GGgg\4\2HHhh\4\2IIii\4\2JJjj\4\2KKkk\4\2LLll\4\2N"+ + "Nnn\4\2OOoo\4\2PPpp\4\2QQqq\4\2RRrr\4\2SSss\4\2TTtt\4\2UUuu\4\2VVvv\4"+ + "\2WWww\4\2XXxx\4\2YYyy\4\2ZZzz\4\2\\\\||\3\2//\3\2\62;\5\2\62;CHch\3\2"+ + "\629\6\2QQSSqqss\3\2\62\63\3\2))\4\2))``\4\2$$``\5\2A\\aac|\6\2\62;A\\"+ + "aac|\2\u036c\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\29\3\2\2\2\2;\3\2\2\2"+ + "\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I"+ + "\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2"+ + "\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2"+ + "\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o"+ + "\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2"+ + "\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085"+ + "\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2"+ + "\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097"+ + "\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2"+ + "\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9"+ + "\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2"+ + "\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb"+ + "\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2"+ + "\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd"+ + "\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2"+ + "\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df"+ + "\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2"+ + "\2\2\u00e9\3\2\2\2\2\u00eb\3\2\2\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1"+ + "\3\2\2\2\2\u00f3\3\2\2\2\2\u00f5\3\2\2\2\2\u00f7\3\2\2\2\2\u00f9\3\2\2"+ + "\2\2\u00fb\3\2\2\2\2\u00fd\3\2\2\2\2\u00ff\3\2\2\2\2\u0101\3\2\2\2\2\u0103"+ + "\3\2\2\2\2\u0105\3\2\2\2\2\u0107\3\2\2\2\2\u0109\3\2\2\2\2\u010b\3\2\2"+ + "\2\2\u010d\3\2\2\2\2\u010f\3\2\2\2\2\u0111\3\2\2\2\2\u0113\3\2\2\2\2\u0115"+ + "\3\2\2\2\2\u0117\3\2\2\2\2\u0119\3\2\2\2\2\u011b\3\2\2\2\2\u011d\3\2\2"+ + "\2\2\u011f\3\2\2\2\2\u0121\3\2\2\2\2\u0123\3\2\2\2\2\u0125\3\2\2\2\2\u0127"+ + "\3\2\2\2\2\u0129\3\2\2\2\2\u012b\3\2\2\2\2\u012d\3\2\2\2\2\u012f\3\2\2"+ + "\2\2\u0131\3\2\2\2\3\u0133\3\2\2\2\5\u013c\3\2\2\2\7\u0145\3\2\2\2\t\u0149"+ + "\3\2\2\2\13\u014b\3\2\2\2\r\u014d\3\2\2\2\17\u014f\3\2\2\2\21\u0151\3"+ + "\2\2\2\23\u0153\3\2\2\2\25\u0155\3\2\2\2\27\u0157\3\2\2\2\31\u0159\3\2"+ + "\2\2\33\u015b\3\2\2\2\35\u015d\3\2\2\2\37\u015f\3\2\2\2!\u0161\3\2\2\2"+ + "#\u0163\3\2\2\2%\u0165\3\2\2\2\'\u0167\3\2\2\2)\u0169\3\2\2\2+\u016b\3"+ + "\2\2\2-\u016d\3\2\2\2/\u016f\3\2\2\2\61\u0171\3\2\2\2\63\u0173\3\2\2\2"+ + "\65\u0175\3\2\2\2\67\u0177\3\2\2\29\u0179\3\2\2\2;\u017d\3\2\2\2=\u0181"+ + "\3\2\2\2?\u0185\3\2\2\2A\u0189\3\2\2\2C\u018d\3\2\2\2E\u0191\3\2\2\2G"+ + "\u0195\3\2\2\2I\u0199\3\2\2\2K\u019e\3\2\2\2M\u01a3\3\2\2\2O\u01a7\3\2"+ + "\2\2Q\u01ab\3\2\2\2S\u01af\3\2\2\2U\u01b3\3\2\2\2W\u01b7\3\2\2\2Y\u01bb"+ + "\3\2\2\2[\u01bf\3\2\2\2]\u01c3\3\2\2\2_\u01c7\3\2\2\2a\u01cb\3\2\2\2c"+ + "\u01cf\3\2\2\2e\u01d3\3\2\2\2g\u01d8\3\2\2\2i\u01dc\3\2\2\2k\u01e0\3\2"+ + "\2\2m\u01e4\3\2\2\2o\u01e8\3\2\2\2q\u01ed\3\2\2\2s\u01f2\3\2\2\2u\u01f7"+ + "\3\2\2\2w\u01fb\3\2\2\2y\u01ff\3\2\2\2{\u0203\3\2\2\2}\u0207\3\2\2\2\177"+ + "\u020b\3\2\2\2\u0081\u020f\3\2\2\2\u0083\u0213\3\2\2\2\u0085\u0217\3\2"+ + "\2\2\u0087\u021b\3\2\2\2\u0089\u021f\3\2\2\2\u008b\u0223\3\2\2\2\u008d"+ + "\u0227\3\2\2\2\u008f\u022c\3\2\2\2\u0091\u0231\3\2\2\2\u0093\u0236\3\2"+ + "\2\2\u0095\u023a\3\2\2\2\u0097\u023d\3\2\2\2\u0099\u0241\3\2\2\2\u009b"+ + "\u0244\3\2\2\2\u009d\u0248\3\2\2\2\u009f\u024b\3\2\2\2\u00a1\u024e\3\2"+ + "\2\2\u00a3\u0252\3\2\2\2\u00a5\u0256\3\2\2\2\u00a7\u025b\3\2\2\2\u00a9"+ + "\u025e\3\2\2\2\u00ab\u0262\3\2\2\2\u00ad\u0265\3\2\2\2\u00af\u0269\3\2"+ + "\2\2\u00b1\u026c\3\2\2\2\u00b3\u026f\3\2\2\2\u00b5\u0273\3\2\2\2\u00b7"+ + "\u0277\3\2\2\2\u00b9\u027b\3\2\2\2\u00bb\u027e\3\2\2\2\u00bd\u0282\3\2"+ + "\2\2\u00bf\u0285\3\2\2\2\u00c1\u0289\3\2\2\2\u00c3\u028c\3\2\2\2\u00c5"+ + "\u028f\3\2\2\2\u00c7\u0293\3\2\2\2\u00c9\u0297\3\2\2\2\u00cb\u029b\3\2"+ + "\2\2\u00cd\u029e\3\2\2\2\u00cf\u02a1\3\2\2\2\u00d1\u02a4\3\2\2\2\u00d3"+ + "\u02a8\3\2\2\2\u00d5\u02ac\3\2\2\2\u00d7\u02b0\3\2\2\2\u00d9\u02b4\3\2"+ + "\2\2\u00db\u02b8\3\2\2\2\u00dd\u02c0\3\2\2\2\u00df\u02c3\3\2\2\2\u00e1"+ + "\u02c9\3\2\2\2\u00e3\u02cf\3\2\2\2\u00e5\u02d4\3\2\2\2\u00e7\u02d7\3\2"+ + "\2\2\u00e9\u02da\3\2\2\2\u00eb\u02dd\3\2\2\2\u00ed\u02df\3\2\2\2\u00ef"+ + "\u02e1\3\2\2\2\u00f1\u02e3\3\2\2\2\u00f3\u02e5\3\2\2\2\u00f5\u02e7\3\2"+ + "\2\2\u00f7\u02e9\3\2\2\2\u00f9\u02eb\3\2\2\2\u00fb\u02ed\3\2\2\2\u00fd"+ + "\u02ef\3\2\2\2\u00ff\u02f3\3\2\2\2\u0101\u02f6\3\2\2\2\u0103\u02f8\3\2"+ + "\2\2\u0105\u02fa\3\2\2\2\u0107\u02fc\3\2\2\2\u0109\u02fe\3\2\2\2\u010b"+ + "\u0300\3\2\2\2\u010d\u0302\3\2\2\2\u010f\u0304\3\2\2\2\u0111\u0306\3\2"+ + "\2\2\u0113\u030a\3\2\2\2\u0115\u030e\3\2\2\2\u0117\u0312\3\2\2\2\u0119"+ + "\u0316\3\2\2\2\u011b\u031a\3\2\2\2\u011d\u031d\3\2\2\2\u011f\u0322\3\2"+ + "\2\2\u0121\u032d\3\2\2\2\u0123\u0337\3\2\2\2\u0125\u0341\3\2\2\2\u0127"+ + "\u034b\3\2\2\2\u0129\u0351\3\2\2\2\u012b\u0359\3\2\2\2\u012d\u0361\3\2"+ + "\2\2\u012f\u0368\3\2\2\2\u0131\u0371\3\2\2\2\u0133\u0134\t\2\2\2\u0134"+ + "\u0135\3\2\2\2\u0135\u0136\b\2\2\2\u0136\4\3\2\2\2\u0137\u0138\7\61\2"+ + "\2\u0138\u013d\7\61\2\2\u0139\u013a\7/\2\2\u013a\u013d\7/\2\2\u013b\u013d"+ + "\t\3\2\2\u013c\u0137\3\2\2\2\u013c\u0139\3\2\2\2\u013c\u013b\3\2\2\2\u013d"+ + "\u0141\3\2\2\2\u013e\u0140\n\4\2\2\u013f\u013e\3\2\2\2\u0140\u0143\3\2"+ + "\2\2\u0141\u013f\3\2\2\2\u0141\u0142\3\2\2\2\u0142\6\3\2\2\2\u0143\u0141"+ + "\3\2\2\2\u0144\u0146\7\17\2\2\u0145\u0144\3\2\2\2\u0145\u0146\3\2\2\2"+ + "\u0146\u0147\3\2\2\2\u0147\u0148\7\f\2\2\u0148\b\3\2\2\2\u0149\u014a\t"+ + "\5\2\2\u014a\n\3\2\2\2\u014b\u014c\t\6\2\2\u014c\f\3\2\2\2\u014d\u014e"+ + "\t\7\2\2\u014e\16\3\2\2\2\u014f\u0150\t\b\2\2\u0150\20\3\2\2\2\u0151\u0152"+ + "\t\t\2\2\u0152\22\3\2\2\2\u0153\u0154\t\n\2\2\u0154\24\3\2\2\2\u0155\u0156"+ + "\t\13\2\2\u0156\26\3\2\2\2\u0157\u0158\t\f\2\2\u0158\30\3\2\2\2\u0159"+ + "\u015a\t\r\2\2\u015a\32\3\2\2\2\u015b\u015c\t\16\2\2\u015c\34\3\2\2\2"+ + "\u015d\u015e\t\17\2\2\u015e\36\3\2\2\2\u015f\u0160\t\20\2\2\u0160 \3\2"+ + "\2\2\u0161\u0162\t\21\2\2\u0162\"\3\2\2\2\u0163\u0164\t\22\2\2\u0164$"+ + "\3\2\2\2\u0165\u0166\t\23\2\2\u0166&\3\2\2\2\u0167\u0168\t\24\2\2\u0168"+ + "(\3\2\2\2\u0169\u016a\t\25\2\2\u016a*\3\2\2\2\u016b\u016c\t\26\2\2\u016c"+ + ",\3\2\2\2\u016d\u016e\t\27\2\2\u016e.\3\2\2\2\u016f\u0170\t\30\2\2\u0170"+ + "\60\3\2\2\2\u0171\u0172\t\31\2\2\u0172\62\3\2\2\2\u0173\u0174\t\32\2\2"+ + "\u0174\64\3\2\2\2\u0175\u0176\t\33\2\2\u0176\66\3\2\2\2\u0177\u0178\t"+ + "\34\2\2\u01788\3\2\2\2\u0179\u017a\5+\26\2\u017a\u017b\5-\27\2\u017b\u017c"+ + "\5\r\7\2\u017c:\3\2\2\2\u017d\u017e\5\r\7\2\u017e\u017f\5\37\20\2\u017f"+ + "\u0180\5\r\7\2\u0180<\3\2\2\2\u0181\u0182\5\31\r\2\u0182\u0183\5!\21\2"+ + "\u0183\u0184\5)\25\2\u0184>\3\2\2\2\u0185\u0186\5\17\b\2\u0186\u0187\5"+ + "\r\7\2\u0187\u0188\5)\25\2\u0188@\3\2\2\2\u0189\u018a\5\r\7\2\u018a\u018b"+ + "\5\37\20\2\u018b\u018c\5\t\5\2\u018cB\3\2\2\2\u018d\u018e\5\17\b\2\u018e"+ + "\u018f\5\t\5\2\u018f\u0190\5\t\5\2\u0190D\3\2\2\2\u0191\u0192\5!\21\2"+ + "\u0192\u0193\5#\22\2\u0193\u0194\5%\23\2\u0194F\3\2\2\2\u0195\u0196\5"+ + "\37\20\2\u0196\u0197\5#\22\2\u0197\u0198\5\61\31\2\u0198H\3\2\2\2\u0199"+ + "\u019a\5+\26\2\u019a\u019b\5-\27\2\u019b\u019c\5\t\5\2\u019c\u019d\5\65"+ + "\33\2\u019dJ\3\2\2\2\u019e\u019f\5\35\17\2\u019f\u01a0\5\17\b\2\u01a0"+ + "\u01a1\5\t\5\2\u01a1\u01a2\5\65\33\2\u01a2L\3\2\2\2\u01a3\u01a4\5\t\5"+ + "\2\u01a4\u01a5\5\17\b\2\u01a5\u01a6\5\17\b\2\u01a6N\3\2\2\2\u01a7\u01a8"+ + "\5\t\5\2\u01a8\u01a9\5\17\b\2\u01a9\u01aa\5\r\7\2\u01aaP\3\2\2\2\u01ab"+ + "\u01ac\5+\26\2\u01ac\u01ad\5/\30\2\u01ad\u01ae\5\13\6\2\u01aeR\3\2\2\2"+ + "\u01af\u01b0\5+\26\2\u01b0\u01b1\5\13\6\2\u01b1\u01b2\5\13\6\2\u01b2T"+ + "\3\2\2\2\u01b3\u01b4\5\t\5\2\u01b4\u01b5\5!\21\2\u01b5\u01b6\5\t\5\2\u01b6"+ + "V\3\2\2\2\u01b7\u01b8\5\65\33\2\u01b8\u01b9\5)\25\2\u01b9\u01ba\5\t\5"+ + "\2\u01baX\3\2\2\2\u01bb\u01bc\5#\22\2\u01bc\u01bd\5)\25\2\u01bd\u01be"+ + "\5\t\5\2\u01beZ\3\2\2\2\u01bf\u01c0\5\r\7\2\u01c0\u01c1\5\37\20\2\u01c1"+ + "\u01c2\5%\23\2\u01c2\\\3\2\2\2\u01c3\u01c4\5)\25\2\u01c4\u01c5\5\35\17"+ + "\2\u01c5\u01c6\5\r\7\2\u01c6^\3\2\2\2\u01c7\u01c8\5)\25\2\u01c8\u01c9"+ + "\5)\25\2\u01c9\u01ca\5\r\7\2\u01ca`\3\2\2\2\u01cb\u01cc\5)\25\2\u01cc"+ + "\u01cd\5\t\5\2\u01cd\u01ce\5\35\17\2\u01ceb\3\2\2\2\u01cf\u01d0\5)\25"+ + "\2\u01d0\u01d1\5\t\5\2\u01d1\u01d2\5)\25\2\u01d2d\3\2\2\2\u01d3\u01d4"+ + "\5%\23\2\u01d4\u01d5\5/\30\2\u01d5\u01d6\5+\26\2\u01d6\u01d7\5\27\f\2"+ + "\u01d7f\3\2\2\2\u01d8\u01d9\5%\23\2\u01d9\u01da\5#\22\2\u01da\u01db\5"+ + "%\23\2\u01dbh\3\2\2\2\u01dc\u01dd\5\17\b\2\u01dd\u01de\5\t\5\2\u01de\u01df"+ + "\5\17\b\2\u01dfj\3\2\2\2\u01e0\u01e1\5\31\r\2\u01e1\u01e2\5!\21\2\u01e2"+ + "\u01e3\5\65\33\2\u01e3l\3\2\2\2\u01e4\u01e5\5\17\b\2\u01e5\u01e6\5\r\7"+ + "\2\u01e6\u01e7\5\65\33\2\u01e7n\3\2\2\2\u01e8\u01e9\5\65\33\2\u01e9\u01ea"+ + "\5\r\7\2\u01ea\u01eb\5\27\f\2\u01eb\u01ec\5\25\13\2\u01ecp\3\2\2\2\u01ed"+ + "\u01ee\5\65\33\2\u01ee\u01ef\5-\27\2\u01ef\u01f0\5\27\f\2\u01f0\u01f1"+ + "\5\35\17\2\u01f1r\3\2\2\2\u01f2\u01f3\5+\26\2\u01f3\u01f4\5%\23\2\u01f4"+ + "\u01f5\5\27\f\2\u01f5\u01f6\5\35\17\2\u01f6t\3\2\2\2\u01f7\u01f8\5\35"+ + "\17\2\u01f8\u01f9\5\65\33\2\u01f9\u01fa\5\31\r\2\u01fav\3\2\2\2\u01fb"+ + "\u01fc\5\37\20\2\u01fc\u01fd\5\61\31\2\u01fd\u01fe\5\31\r\2\u01fex\3\2"+ + "\2\2\u01ff\u0200\5\t\5\2\u0200\u0201\5\17\b\2\u0201\u0202\5\31\r\2\u0202"+ + "z\3\2\2\2\u0203\u0204\5\t\5\2\u0204\u0205\5\r\7\2\u0205\u0206\5\31\r\2"+ + "\u0206|\3\2\2\2\u0207\u0208\5+\26\2\u0208\u0209\5/\30\2\u0209\u020a\5"+ + "\31\r\2\u020a~\3\2\2\2\u020b\u020c\5+\26\2\u020c\u020d\5\13\6\2\u020d"+ + "\u020e\5\31\r\2\u020e\u0080\3\2\2\2\u020f\u0210\5\t\5\2\u0210\u0211\5"+ + "!\21\2\u0211\u0212\5\31\r\2\u0212\u0082\3\2\2\2\u0213\u0214\5\65\33\2"+ + "\u0214\u0215\5)\25\2\u0215\u0216\5\31\r\2\u0216\u0084\3\2\2\2\u0217\u0218"+ + "\5#\22\2\u0218\u0219\5)\25\2\u0219\u021a\5\31\r\2\u021a\u0086\3\2\2\2"+ + "\u021b\u021c\5\r\7\2\u021c\u021d\5%\23\2\u021d\u021e\5\31\r\2\u021e\u0088"+ + "\3\2\2\2\u021f\u0220\5+\26\2\u0220\u0221\5-\27\2\u0221\u0222\5\t\5\2\u0222"+ + "\u008a\3\2\2\2\u0223\u0224\5\35\17\2\u0224\u0225\5\17\b\2\u0225\u0226"+ + "\5\t\5\2\u0226\u008c\3\2\2\2\u0227\u0228\5+\26\2\u0228\u0229\5\27\f\2"+ + "\u0229\u022a\5\35\17\2\u022a\u022b\5\17\b\2\u022b\u008e\3\2\2\2\u022c"+ + "\u022d\5\35\17\2\u022d\u022e\5\27\f\2\u022e\u022f\5\35\17\2\u022f\u0230"+ + "\5\17\b\2\u0230\u0090\3\2\2\2\u0231\u0232\5%\23\2\u0232\u0233\5\r\7\2"+ + "\u0233\u0234\5\27\f\2\u0234\u0235\5\35\17\2\u0235\u0092\3\2\2\2\u0236"+ + "\u0237\5\33\16\2\u0237\u0238\5\37\20\2\u0238\u0239\5%\23\2\u0239\u0094"+ + "\3\2\2\2\u023a\u023b\5\33\16\2\u023b\u023c\5\r\7\2\u023c\u0096\3\2\2\2"+ + "\u023d\u023e\5\33\16\2\u023e\u023f\5!\21\2\u023f\u0240\5\r\7\2\u0240\u0098"+ + "\3\2\2\2\u0241\u0242\5\33\16\2\u0242\u0243\5\67\34\2\u0243\u009a\3\2\2"+ + "\2\u0244\u0245\5\33\16\2\u0245\u0246\5!\21\2\u0246\u0247\5\67\34\2\u0247"+ + "\u009c\3\2\2\2\u0248\u0249\5\33\16\2\u0249\u024a\5%\23\2\u024a\u009e\3"+ + "\2\2\2\u024b\u024c\5\33\16\2\u024c\u024d\5\37\20\2\u024d\u00a0\3\2\2\2"+ + "\u024e\u024f\5\33\16\2\u024f\u0250\5%\23\2\u0250\u0251\5\21\t\2\u0251"+ + "\u00a2\3\2\2\2\u0252\u0253\5\33\16\2\u0253\u0254\5%\23\2\u0254\u0255\5"+ + "#\22\2\u0255\u00a4\3\2\2\2\u0256\u0257\5\r\7\2\u0257\u0258\5\t\5\2\u0258"+ + "\u0259\5\35\17\2\u0259\u025a\5\35\17\2\u025a\u00a6\3\2\2\2\u025b\u025c"+ + "\5\r\7\2\u025c\u025d\5\r\7\2\u025d\u00a8\3\2\2\2\u025e\u025f\5\r\7\2\u025f"+ + "\u0260\5!\21\2\u0260\u0261\5\r\7\2\u0261\u00aa\3\2\2\2\u0262\u0263\5\r"+ + "\7\2\u0263\u0264\5\67\34\2\u0264\u00ac\3\2\2\2\u0265\u0266\5\r\7\2\u0266"+ + "\u0267\5!\21\2\u0267\u0268\5\67\34\2\u0268\u00ae\3\2\2\2\u0269\u026a\5"+ + "\r\7\2\u026a\u026b\5%\23\2\u026b\u00b0\3\2\2\2\u026c\u026d\5\r\7\2\u026d"+ + "\u026e\5\37\20\2\u026e\u00b2\3\2\2\2\u026f\u0270\5\r\7\2\u0270\u0271\5"+ + "%\23\2\u0271\u0272\5\21\t\2\u0272\u00b4\3\2\2\2\u0273\u0274\5\r\7\2\u0274"+ + "\u0275\5%\23\2\u0275\u0276\5#\22\2\u0276\u00b6\3\2\2\2\u0277\u0278\5)"+ + "\25\2\u0278\u0279\5\21\t\2\u0279\u027a\5-\27\2\u027a\u00b8\3\2\2\2\u027b"+ + "\u027c\5)\25\2\u027c\u027d\5\r\7\2\u027d\u00ba\3\2\2\2\u027e\u027f\5)"+ + "\25\2\u027f\u0280\5!\21\2\u0280\u0281\5\r\7\2\u0281\u00bc\3\2\2\2\u0282"+ + "\u0283\5)\25\2\u0283\u0284\5\67\34\2\u0284\u00be\3\2\2\2\u0285\u0286\5"+ + ")\25\2\u0286\u0287\5!\21\2\u0287\u0288\5\67\34\2\u0288\u00c0\3\2\2\2\u0289"+ + "\u028a\5)\25\2\u028a\u028b\5\37\20\2\u028b\u00c2\3\2\2\2\u028c\u028d\5"+ + ")\25\2\u028d\u028e\5%\23\2\u028e\u00c4\3\2\2\2\u028f\u0290\5)\25\2\u0290"+ + "\u0291\5%\23\2\u0291\u0292\5\21\t\2\u0292\u00c6\3\2\2\2\u0293\u0294\5"+ + ")\25\2\u0294\u0295\5%\23\2\u0295\u0296\5#\22\2\u0296\u00c8\3\2\2\2\u0297"+ + "\u0298\5)\25\2\u0298\u0299\5+\26\2\u0299\u029a\5-\27\2\u029a\u00ca\3\2"+ + "\2\2\u029b\u029c\5\21\t\2\u029c\u029d\5\31\r\2\u029d\u00cc\3\2\2\2\u029e"+ + "\u029f\5\17\b\2\u029f\u02a0\5\31\r\2\u02a0\u00ce\3\2\2\2\u02a1\u02a2\5"+ + "\31\r\2\u02a2\u02a3\5!\21\2\u02a3\u00d0\3\2\2\2\u02a4\u02a5\5#\22\2\u02a5"+ + "\u02a6\5/\30\2\u02a6\u02a7\5-\27\2\u02a7\u00d2\3\2\2\2\u02a8\u02a9\5\27"+ + "\f\2\u02a9\u02aa\5\35\17\2\u02aa\u02ab\5-\27\2\u02ab\u00d4\3\2\2\2\u02ac"+ + "\u02ad\5#\22\2\u02ad\u02ae\5)\25\2\u02ae\u02af\5\25\13\2\u02af\u00d6\3"+ + "\2\2\2\u02b0\u02b1\5\21\t\2\u02b1\u02b2\5\'\24\2\u02b2\u02b3\5/\30\2\u02b3"+ + "\u00d8\3\2\2\2\u02b4\u02b5\5+\26\2\u02b5\u02b6\5\21\t\2\u02b6\u02b7\5"+ + "-\27\2\u02b7\u00da\3\2\2\2\u02b8\u02b9\5\31\r\2\u02b9\u02ba\5!\21\2\u02ba"+ + "\u02bb\5\r\7\2\u02bb\u02bc\5\35\17\2\u02bc\u02bd\5/\30\2\u02bd\u02be\5"+ + "\17\b\2\u02be\u02bf\5\21\t\2\u02bf\u00dc\3\2\2\2\u02c0\u02c1\5\31\r\2"+ + "\u02c1\u02c2\5\23\n\2\u02c2\u00de\3\2\2\2\u02c3\u02c4\5\21\t\2\u02c4\u02c5"+ + "\5!\21\2\u02c5\u02c6\5\17\b\2\u02c6\u02c7\5\31\r\2\u02c7\u02c8\5\23\n"+ + "\2\u02c8\u00e0\3\2\2\2\u02c9\u02ca\5\37\20\2\u02ca\u02cb\5\t\5\2\u02cb"+ + "\u02cc\5\r\7\2\u02cc\u02cd\5)\25\2\u02cd\u02ce\5#\22\2\u02ce\u00e2\3\2"+ + "\2\2\u02cf\u02d0\5\21\t\2\u02d0\u02d1\5!\21\2\u02d1\u02d2\5\17\b\2\u02d2"+ + "\u02d3\5\37\20\2\u02d3\u00e4\3\2\2\2\u02d4\u02d5\5\17\b\2\u02d5\u02d6"+ + "\5\13\6\2\u02d6\u00e6\3\2\2\2\u02d7\u02d8\5\17\b\2\u02d8\u02d9\5\63\32"+ + "\2\u02d9\u00e8\3\2\2\2\u02da\u02db\5\17\b\2\u02db\u02dc\5+\26\2\u02dc"+ + "\u00ea\3\2\2\2\u02dd\u02de\7&\2\2\u02de\u00ec\3\2\2\2\u02df\u02e0\5\t"+ + "\5\2\u02e0\u00ee\3\2\2\2\u02e1\u02e2\5\13\6\2\u02e2\u00f0\3\2\2\2\u02e3"+ + "\u02e4\5\r\7\2\u02e4\u00f2\3\2\2\2\u02e5\u02e6\5\17\b\2\u02e6\u00f4\3"+ + "\2\2\2\u02e7\u02e8\5\21\t\2\u02e8\u00f6\3\2\2\2\u02e9\u02ea\5\27\f\2\u02ea"+ + "\u00f8\3\2\2\2\u02eb\u02ec\5\35\17\2\u02ec\u00fa\3\2\2\2\u02ed\u02ee\5"+ + "\37\20\2\u02ee\u00fc\3\2\2\2\u02ef\u02f0\5%\23\2\u02f0\u02f1\5+\26\2\u02f1"+ + "\u02f2\5\63\32\2\u02f2\u00fe\3\2\2\2\u02f3\u02f4\5+\26\2\u02f4\u02f5\5"+ + "%\23\2\u02f5\u0100\3\2\2\2\u02f6\u02f7\7*\2\2\u02f7\u0102\3\2\2\2\u02f8"+ + "\u02f9\7+\2\2\u02f9\u0104\3\2\2\2\u02fa\u02fb\7.\2\2\u02fb\u0106\3\2\2"+ + "\2\u02fc\u02fd\7-\2\2\u02fd\u0108\3\2\2\2\u02fe\u02ff\7/\2\2\u02ff\u010a"+ + "\3\2\2\2\u0300\u0301\7,\2\2\u0301\u010c\3\2\2\2\u0302\u0303\7\61\2\2\u0303"+ + "\u010e\3\2\2\2\u0304\u0305\7?\2\2\u0305\u0110\3\2\2\2\u0306\u0307\5\37"+ + "\20\2\u0307\u0308\5#\22\2\u0308\u0309\5\17\b\2\u0309\u0112\3\2\2\2\u030a"+ + "\u030b\5+\26\2\u030b\u030c\5\27\f\2\u030c\u030d\5)\25\2\u030d\u0114\3"+ + "\2\2\2\u030e\u030f\5+\26\2\u030f\u0310\5\27\f\2\u0310\u0311\5\35\17\2"+ + "\u0311\u0116\3\2\2\2\u0312\u0313\5!\21\2\u0313\u0314\5#\22\2\u0314\u0315"+ + "\5-\27\2\u0315\u0118\3\2\2\2\u0316\u0317\5\t\5\2\u0317\u0318\5!\21\2\u0318"+ + "\u0319\5\17\b\2\u0319\u011a\3\2\2\2\u031a\u031b\5#\22\2\u031b\u031c\5"+ + ")\25\2\u031c\u011c\3\2\2\2\u031d\u031e\5\65\33\2\u031e\u031f\5#\22\2\u031f"+ + "\u0320\5)\25\2\u0320\u011e\3\2\2\2\u0321\u0323\t\35\2\2\u0322\u0321\3"+ + "\2\2\2\u0322\u0323\3\2\2\2\u0323\u0325\3\2\2\2\u0324\u0326\t\36\2\2\u0325"+ + "\u0324\3\2\2\2\u0326\u0327\3\2\2\2\u0327\u0325\3\2\2\2\u0327\u0328\3\2"+ + "\2\2\u0328\u032a\3\2\2\2\u0329\u032b\5\17\b\2\u032a\u0329\3\2\2\2\u032a"+ + "\u032b\3\2\2\2\u032b\u0120\3\2\2\2\u032c\u032e\t\35\2\2\u032d\u032c\3"+ + "\2\2\2\u032d\u032e\3\2\2\2\u032e\u032f\3\2\2\2\u032f\u0330\7\62\2\2\u0330"+ + "\u0332\5\65\33\2\u0331\u0333\t\37\2\2\u0332\u0331\3\2\2\2\u0333\u0334"+ + "\3\2\2\2\u0334\u0332\3\2\2\2\u0334\u0335\3\2\2\2\u0335\u0122\3\2\2\2\u0336"+ + "\u0338\t\35\2\2\u0337\u0336\3\2\2\2\u0337\u0338\3\2\2\2\u0338\u033a\3"+ + "\2\2\2\u0339\u033b\t\37\2\2\u033a\u0339\3\2\2\2\u033b\u033c\3\2\2\2\u033c"+ + "\u033a\3\2\2\2\u033c\u033d\3\2\2\2\u033d\u033e\3\2\2\2\u033e\u033f\5\27"+ + "\f\2\u033f\u0124\3\2\2\2\u0340\u0342\t\35\2\2\u0341\u0340\3\2\2\2\u0341"+ + "\u0342\3\2\2\2\u0342\u0344\3\2\2\2\u0343\u0345\t \2\2\u0344\u0343\3\2"+ + "\2\2\u0345\u0346\3\2\2\2\u0346\u0344\3\2\2\2\u0346\u0347\3\2\2\2\u0347"+ + "\u0348\3\2\2\2\u0348\u0349\t!\2\2\u0349\u0126\3\2\2\2\u034a\u034c\t\""+ + "\2\2\u034b\u034a\3\2\2\2\u034c\u034d\3\2\2\2\u034d\u034b\3\2\2\2\u034d"+ + "\u034e\3\2\2\2\u034e\u034f\3\2\2\2\u034f\u0350\5\13\6\2\u0350\u0128\3"+ + "\2\2\2\u0351\u0353\t#\2\2\u0352\u0354\t$\2\2\u0353\u0352\3\2\2\2\u0354"+ + "\u0355\3\2\2\2\u0355\u0353\3\2\2\2\u0355\u0356\3\2\2\2\u0356\u0357\3\2"+ + "\2\2\u0357\u0358\t#\2\2\u0358\u012a\3\2\2\2\u0359\u035b\7$\2\2\u035a\u035c"+ + "\t%\2\2\u035b\u035a\3\2\2\2\u035c\u035d\3\2\2\2\u035d\u035b\3\2\2\2\u035d"+ + "\u035e\3\2\2\2\u035e\u035f\3\2\2\2\u035f\u0360\7$\2\2\u0360\u012c\3\2"+ + "\2\2\u0361\u0365\t&\2\2\u0362\u0364\t\'\2\2\u0363\u0362\3\2\2\2\u0364"+ + "\u0367\3\2\2\2\u0365\u0363\3\2\2\2\u0365\u0366\3\2\2\2\u0366\u012e\3\2"+ + "\2\2\u0367\u0365\3\2\2\2\u0368\u036c\t&\2\2\u0369\u036b\t\'\2\2\u036a"+ + "\u0369\3\2\2\2\u036b\u036e\3\2\2\2\u036c\u036a\3\2\2\2\u036c\u036d\3\2"+ + "\2\2\u036d\u036f\3\2\2\2\u036e\u036c\3\2\2\2\u036f\u0370\7<\2\2\u0370"+ + "\u0130\3\2\2\2\u0371\u0372\13\2\2\2\u0372\u0132\3\2\2\2\24\2\u013c\u0141"+ + "\u0145\u0322\u0327\u032a\u032d\u0334\u0337\u033c\u0341\u0346\u034d\u0355"+ + "\u035d\u0365\u036c\3\2\3\2"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java new file mode 100644 index 000000000..0d29908d9 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -0,0 +1,246 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2020 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.compiler.as8080; + +import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; +import net.emustudio.emulib.plugins.annotations.PluginRoot; +import net.emustudio.emulib.plugins.compiler.AbstractCompiler; +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; +import net.emustudio.emulib.plugins.compiler.SourceFileExtension; +import net.emustudio.emulib.plugins.memory.MemoryContext; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.ContextNotFoundException; +import net.emustudio.emulib.runtime.InvalidContextException; +import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.helpers.RadixUtils; +import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; +import org.antlr.v4.runtime.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.*; + +@PluginRoot( + type = PLUGIN_TYPE.COMPILER, + title = "Intel 8080 Assembler" +) +@SuppressWarnings("unused") +public class Assembler8080 extends AbstractCompiler { + private final static Logger LOGGER = LoggerFactory.getLogger(Assembler8080.class); + private final static List SOURCE_FILE_EXTENSIONS = List.of( + new SourceFileExtension("asm", "Assembler source file"), + new SourceFileExtension("inc", "Include file") + ); + + private MemoryContext memory; + private int programLocation; + + public Assembler8080(long pluginID, ApplicationApi applicationApi, PluginSettings pluginSettings) { + super(pluginID, applicationApi, pluginSettings); + } + + @SuppressWarnings("unchecked") + @Override + public void initialize() { + Optional.ofNullable(applicationApi.getContextPool()).ifPresent(pool -> { + try { + memory = pool.getMemoryContext(pluginID, MemoryContext.class); + if (memory.getDataType() != Byte.class) { + throw new InvalidContextException( + "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() + ); + } + } catch (InvalidContextException | ContextNotFoundException e) { + LOGGER.warn("Memory is not available", e); + } + }); + } + + @Override + public String getVersion() { + return getResourceBundle().map(b -> b.getString("version")).orElse("(unknown)"); + } + + @Override + public String getCopyright() { + return getResourceBundle().map(b -> b.getString("copyright")).orElse("(unknown)"); + } + + @Override + public String getDescription() { + return "Lightly modified/extended clone of original Intel's 8080 assembler."; + } + + @Override + public LexicalAnalyzer createLexer(String s) { + As8080Lexer lexer = createLexer(CharStreams.fromString(s)); + return new LexicalAnalyzerImpl(lexer); + } + + @Override + public boolean compile(String inputFileName, String outputFileName) { + notifyCompileStart(); + notifyInfo(getTitle() + ", version " + getVersion()); + + try (Reader reader = new FileReader(inputFileName)) { + Lexer lexer = createLexer(CharStreams.fromReader(reader)); + lexer.addErrorListener(new ParserErrorListener()); + CommonTokenStream tokens = new CommonTokenStream(lexer); + + As8080Parser parser = createParser(tokens); + parser.addErrorListener(new ParserErrorListener()); + + + +// ProgramParser programParser = new ProgramParser(); +// programParser.visit(parser.start()); +// +// Program program = programParser.getProgram(); +// CodeGenerator codeGenerator = new CodeGenerator(); +// ByteBuffer code = codeGenerator.generateCode(program); +// +// if (code.hasRemaining()) { +// writeToFile(code, outputFileName); +// writeToMemory(code); +// } + + // programLocation = program.getStartLine() * 4; + + notifyInfo(String.format( + "Compile was successful.\n\tOutput: %s\n\tProgram starts at 0x%s", + outputFileName, RadixUtils.formatWordHexString(programLocation) + )); + } catch (CompileException e) { + notifyError(e.line, e.column, e.getMessage()); + return false; + } catch (IOException e) { + notifyError("Compilation error: " + e); + LOGGER.error("Compilation error", e); + return false; + } finally { + notifyCompileFinish(); + } + + return true; + +// try { +// IntelHEX hex = compileToHex(inputFileName); +// +// hex.generate(outputFileName); +// programLocation = hex.getProgramLocation(); +// notifyInfo("Compilation was successful.\n Output file: " + outputFileName); +// +// if (memory != null) { +// hex.loadIntoMemory(memory); +// notifyInfo("Compiled file was loaded into memory."); +// } else { +// notifyWarning("Memory is not available."); +// } +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// LOGGER.trace("Compiler exception", e); +// notifyError("Compilation error: " + e.getMessage()); +// return false; +// } finally { +// notifyCompileFinish(); +// } + } + + @Override + public boolean compile(String inputFileName) { + String outputFileName = Objects.requireNonNull(inputFileName); + SourceFileExtension srcExtension = SOURCE_FILE_EXTENSIONS.get(0); + + int i = inputFileName.lastIndexOf("." + srcExtension.getExtension()); + if (i >= 0) { + outputFileName = outputFileName.substring(0, i); + } + return compile(inputFileName, outputFileName + ".hex"); + } + + @Override + public int getProgramLocation() { + return programLocation; + } + + @Override + public List getSourceFileExtensions() { + return SOURCE_FILE_EXTENSIONS; + } + +// private IntelHEX compileToHex(String inputFileName) throws Exception { +// Objects.requireNonNull(inputFileName); +// +// notifyInfo(getTitle() + ", version " + getVersion()); +// +// Object parsedAST; +// IntelHEX hex = new IntelHEX(); +// +// try (Reader reader = new FileReader(inputFileName)) { +// lexer.reset(reader, 0, 0, 0); +// parser.reset(); +// parsedAST = parser.parse().value; +// +// if (parsedAST == null) { +// throw new Exception("Unexpected end of file"); +// } +// if (parser.hasSyntaxErrors()) { +// throw new Exception("One or more errors has been found, cannot continue."); +// } +// +// // do several passes for compiling +// Statement stat = (Statement) parsedAST; +// Namespace env = new Namespace(inputFileName); +// stat.pass1(env); // create symbol table +// stat.pass2(0); // try to evaluate all expressions + compute relative addresses +// while (stat.pass3(env)) { +// // don't worry about deadlock +// } +// if (env.getPassNeedCount() != 0) { +// throw new Exception("Could not evaluate: " + env.getPassNeedView()); +// } +// stat.pass4(hex, env); +// return hex; +// } +// } + + private Optional getResourceBundle() { + try { + return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.compiler.as8080.version")); + } catch (MissingResourceException e) { + return Optional.empty(); + } + } + + private As8080Lexer createLexer(CharStream input) { + As8080Lexer lexer = new As8080Lexer(input); + lexer.removeErrorListeners(); + return lexer; + } + + private As8080Parser createParser(TokenStream tokenStream) { + As8080Parser parser = new As8080Parser(tokenStream); + parser.removeErrorListeners(); + return parser; + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java deleted file mode 100644 index 74480d67f..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompilerImpl.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080; - -import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; -import net.emustudio.emulib.plugins.annotations.PluginRoot; -import net.emustudio.emulib.plugins.compiler.AbstractCompiler; -import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; -import net.emustudio.emulib.plugins.compiler.SourceFileExtension; -import net.emustudio.emulib.plugins.memory.MemoryContext; -import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.ContextNotFoundException; -import net.emustudio.emulib.runtime.InvalidContextException; -import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.tree.Statement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.FileReader; -import java.io.Reader; -import java.util.*; - -@PluginRoot( - type = PLUGIN_TYPE.COMPILER, - title = "Intel 8080 Assembler" -) -@SuppressWarnings("unused") -public class CompilerImpl extends AbstractCompiler { - private final static Logger LOGGER = LoggerFactory.getLogger(CompilerImpl.class); - private final static List SOURCE_FILE_EXTENSIONS = List.of( - new SourceFileExtension("asm", "Assembler source file"), - new SourceFileExtension("inc", "Include file") - ); - - private final LexerImpl lexer; - private final ParserImpl parser; - private MemoryContext memory; - private int programLocation; - - public CompilerImpl(long pluginID, ApplicationApi applicationApi, PluginSettings pluginSettings) { - super(pluginID, applicationApi, pluginSettings); - lexer = new LexerImpl(null); - parser = new ParserImpl(lexer, this); - } - - @SuppressWarnings("unchecked") - @Override - public void initialize() { - Optional.ofNullable(applicationApi.getContextPool()).ifPresent(pool -> { - try { - memory = pool.getMemoryContext(pluginID, MemoryContext.class); - if (memory.getDataType() != Short.class) { - throw new InvalidContextException( - "Unexpected memory cell type. Expected Short but was: " + memory.getDataType() - ); - } - } catch (ContextNotFoundException | InvalidContextException e) { - LOGGER.warn("Memory context is not available", e); - } - }); - } - - @Override - public String getVersion() { - return getResourceBundle().map(b -> b.getString("version")).orElse("(unknown)"); - } - - @Override - public String getCopyright() { - return getResourceBundle().map(b -> b.getString("copyright")).orElse("(unknown)"); - } - - @Override - public String getDescription() { - return "Light modified clone of original Intel's 8080 assembler."; - } - - @Override - public LexicalAnalyzer getLexer(Reader in) { - return new LexerImpl(in); - } - - @Override - public boolean compile(String inputFileName, String outputFileName) { - try { - notifyCompileStart(); - IntelHEX hex = compileToHex(inputFileName); - - hex.generate(outputFileName); - programLocation = hex.getProgramLocation(); - notifyInfo("Compilation was successful.\n Output file: " + outputFileName); - - if (memory != null) { - hex.loadIntoMemory(memory); - notifyInfo("Compiled file was loaded into memory."); - } else { - notifyWarning("Memory is not available."); - } - return true; - } catch (Exception e) { - e.printStackTrace(); - LOGGER.trace("Compiler exception", e); - notifyError("Compilation error: " + e.getMessage()); - return false; - } finally { - notifyCompileFinish(); - } - } - - @Override - public boolean compile(String inputFileName) { - int i = inputFileName.lastIndexOf(".asm"); - - String outputFileName = inputFileName; - if (i >= 0) { - outputFileName = outputFileName.substring(0, i); - } - outputFileName += ".hex"; - return compile(inputFileName, outputFileName); - } - - @Override - public int getProgramLocation() { - return programLocation; - } - - @Override - public List getSourceFileExtensions() { - return SOURCE_FILE_EXTENSIONS; - } - - private IntelHEX compileToHex(String inputFileName) throws Exception { - Objects.requireNonNull(inputFileName); - - notifyInfo(getTitle() + ", version " + getVersion()); - - Object parsedAST; - IntelHEX hex = new IntelHEX(); - - try (Reader reader = new FileReader(inputFileName)) { - lexer.reset(reader, 0, 0, 0); - parser.reset(); - parsedAST = parser.parse().value; - - if (parsedAST == null) { - throw new Exception("Unexpected end of file"); - } - if (parser.hasSyntaxErrors()) { - throw new Exception("One or more errors has been found, cannot continue."); - } - - // do several passes for compiling - Statement stat = (Statement) parsedAST; - Namespace env = new Namespace(inputFileName); - stat.pass1(env); // create symbol table - stat.pass2(0); // try to evaluate all expressions + compute relative addresses - while (stat.pass3(env)) { - // don't worry about deadlock - } - if (env.getPassNeedCount() != 0) { - throw new Exception("Could not evaluate: " + env.getPassNeedView()); - } - stat.pass4(hex, env); - return hex; - } - } - - private Optional getResourceBundle() { - try { - return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.compiler.as8080.version")); - } catch (MissingResourceException e) { - return Optional.empty(); - } - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java new file mode 100644 index 000000000..444ccd500 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java @@ -0,0 +1,194 @@ +package net.emustudio.plugins.compiler.as8080; + +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; +import net.emustudio.emulib.plugins.compiler.Token; +import org.antlr.v4.runtime.CharStreams; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Objects; + +import static net.emustudio.plugins.compiler.as8080.As8080Lexer.*; + +public class LexicalAnalyzerImpl implements LexicalAnalyzer { + private final As8080Lexer lexer; + private static final int[] tokenMap = new int[As8080Lexer.ERROR + 1]; // As8080Lexer.ERROR is the highest number + + static { + tokenMap[COMMENT] = Token.COMMENT; + tokenMap[EOL] = Token.WHITESPACE; + tokenMap[WS] = Token.WHITESPACE; + tokenMap[OPCODE_STC] = Token.RESERVED; + tokenMap[OPCODE_CMC] = Token.RESERVED; + tokenMap[OPCODE_INR] = Token.RESERVED; + tokenMap[OPCODE_DCR] = Token.RESERVED; + tokenMap[OPCODE_CMA] = Token.RESERVED; + tokenMap[OPCODE_DAA] = Token.RESERVED; + tokenMap[OPCODE_NOP] = Token.RESERVED; + tokenMap[OPCODE_MOV] = Token.RESERVED; + tokenMap[OPCODE_STAX] = Token.RESERVED; + tokenMap[OPCODE_LDAX] = Token.RESERVED; + tokenMap[OPCODE_ADD] = Token.RESERVED; + tokenMap[OPCODE_ADC] = Token.RESERVED; + tokenMap[OPCODE_SUB] = Token.RESERVED; + tokenMap[OPCODE_SBB] = Token.RESERVED; + tokenMap[OPCODE_ANA] = Token.RESERVED; + tokenMap[OPCODE_XRA] = Token.RESERVED; + tokenMap[OPCODE_ORA] = Token.RESERVED; + tokenMap[OPCODE_CMP] = Token.RESERVED; + tokenMap[OPCODE_RLC] = Token.RESERVED; + tokenMap[OPCODE_RRC] = Token.RESERVED; + tokenMap[OPCODE_RAL] = Token.RESERVED; + tokenMap[OPCODE_RAR] = Token.RESERVED; + tokenMap[OPCODE_PUSH] = Token.RESERVED; + tokenMap[OPCODE_POP] = Token.RESERVED; + tokenMap[OPCODE_DAD] = Token.RESERVED; + tokenMap[OPCODE_INX] = Token.RESERVED; + tokenMap[OPCODE_DCX] = Token.RESERVED; + tokenMap[OPCODE_XCHG] = Token.RESERVED; + tokenMap[OPCODE_XTHL] = Token.RESERVED; + tokenMap[OPCODE_SPHL] = Token.RESERVED; + tokenMap[OPCODE_LXI] = Token.RESERVED; + tokenMap[OPCODE_MVI] = Token.RESERVED; + tokenMap[OPCODE_ADI] = Token.RESERVED; + tokenMap[OPCODE_ACI] = Token.RESERVED; + tokenMap[OPCODE_SUI] = Token.RESERVED; + tokenMap[OPCODE_SBI] = Token.RESERVED; + tokenMap[OPCODE_ANI] = Token.RESERVED; + tokenMap[OPCODE_XRI] = Token.RESERVED; + tokenMap[OPCODE_ORI] = Token.RESERVED; + tokenMap[OPCODE_CPI] = Token.RESERVED; + tokenMap[OPCODE_STA] = Token.RESERVED; + tokenMap[OPCODE_LDA] = Token.RESERVED; + tokenMap[OPCODE_SHLD] = Token.RESERVED; + tokenMap[OPCODE_LHLD] = Token.RESERVED; + tokenMap[OPCODE_PCHL] = Token.RESERVED; + tokenMap[OPCODE_JMP] = Token.RESERVED; + tokenMap[OPCODE_JC] = Token.RESERVED; + tokenMap[OPCODE_JNC] = Token.RESERVED; + tokenMap[OPCODE_JZ] = Token.RESERVED; + tokenMap[OPCODE_JNZ] = Token.RESERVED; + tokenMap[OPCODE_JP] = Token.RESERVED; + tokenMap[OPCODE_JM] = Token.RESERVED; + tokenMap[OPCODE_JPE] = Token.RESERVED; + tokenMap[OPCODE_JPO] = Token.RESERVED; + tokenMap[OPCODE_CALL] = Token.RESERVED; + tokenMap[OPCODE_CC] = Token.RESERVED; + tokenMap[OPCODE_CNC] = Token.RESERVED; + tokenMap[OPCODE_CZ] = Token.RESERVED; + tokenMap[OPCODE_CNZ] = Token.RESERVED; + tokenMap[OPCODE_CP] = Token.RESERVED; + tokenMap[OPCODE_CM] = Token.RESERVED; + tokenMap[OPCODE_CPE] = Token.RESERVED; + tokenMap[OPCODE_CPO] = Token.RESERVED; + tokenMap[OPCODE_RET] = Token.RESERVED; + tokenMap[OPCODE_RC] = Token.RESERVED; + tokenMap[OPCODE_RNC] = Token.RESERVED; + tokenMap[OPCODE_RZ] = Token.RESERVED; + tokenMap[OPCODE_RNZ] = Token.RESERVED; + tokenMap[OPCODE_RM] = Token.RESERVED; + tokenMap[OPCODE_RP] = Token.RESERVED; + tokenMap[OPCODE_RPE] = Token.RESERVED; + tokenMap[OPCODE_RPO] = Token.RESERVED; + tokenMap[OPCODE_RST] = Token.RESERVED; + tokenMap[OPCODE_EI] = Token.RESERVED; + tokenMap[OPCODE_DI] = Token.RESERVED; + tokenMap[OPCODE_IN] = Token.RESERVED; + tokenMap[OPCODE_OUT] = Token.RESERVED; + tokenMap[OPCODE_HLT] = Token.RESERVED; + + tokenMap[PREP_ORG] = Token.PREPROCESSOR; + tokenMap[PREP_EQU] = Token.PREPROCESSOR; + tokenMap[PREP_SET] = Token.PREPROCESSOR; + tokenMap[PREP_INCLUDE] = Token.PREPROCESSOR; + tokenMap[PREP_IF] = Token.PREPROCESSOR; + tokenMap[PREP_ENDIF] = Token.PREPROCESSOR; + tokenMap[PREP_MACRO] = Token.PREPROCESSOR; + tokenMap[PREP_ENDM] = Token.PREPROCESSOR; + tokenMap[PREP_DB] = Token.PREPROCESSOR; + tokenMap[PREP_DW] = Token.PREPROCESSOR; + tokenMap[PREP_DS] = Token.PREPROCESSOR; + tokenMap[PREP_ADDR] = Token.PREPROCESSOR; + + tokenMap[REG_A] = Token.REGISTER; + tokenMap[REG_B] = Token.REGISTER; + tokenMap[REG_C] = Token.REGISTER; + tokenMap[REG_D] = Token.REGISTER; + tokenMap[REG_E] = Token.REGISTER; + tokenMap[REG_H] = Token.REGISTER; + tokenMap[REG_L] = Token.REGISTER; + tokenMap[REG_M] = Token.REGISTER; + tokenMap[REG_PSW] = Token.REGISTER; + tokenMap[REG_SP] = Token.REGISTER; + + tokenMap[SEP_LPAR] = Token.SEPARATOR; + tokenMap[SEP_RPAR] = Token.SEPARATOR; + tokenMap[SEP_COMMA] = Token.SEPARATOR; + + tokenMap[OP_ADD] = Token.OPERATOR; + tokenMap[OP_SUBTRACT] = Token.OPERATOR; + tokenMap[OP_MULTIPLY] = Token.OPERATOR; + tokenMap[OP_DIVIDE] = Token.OPERATOR; + tokenMap[OP_EQUAL] = Token.OPERATOR; + tokenMap[OP_MOD] = Token.OPERATOR; + tokenMap[OP_SHR] = Token.OPERATOR; + tokenMap[OP_SHL] = Token.OPERATOR; + tokenMap[OP_NOT] = Token.OPERATOR; + tokenMap[OP_AND] = Token.OPERATOR; + tokenMap[OP_OR] = Token.OPERATOR; + tokenMap[OP_XOR] = Token.OPERATOR; + + tokenMap[LIT_NUMBER] =Token.LITERAL; + tokenMap[LIT_HEXNUMBER_1] =Token.LITERAL; + tokenMap[LIT_HEXNUMBER_2] =Token.LITERAL; + tokenMap[LIT_OCTNUMBER] =Token.LITERAL; + tokenMap[LIT_BINNUMBER] =Token.LITERAL; + tokenMap[LIT_STRING_1] =Token.LITERAL; + tokenMap[LIT_STRING_2] =Token.LITERAL; + + tokenMap[ID_IDENTIFIER] = Token.IDENTIFIER; + tokenMap[ID_LABEL] = Token.IDENTIFIER; + + tokenMap[ERROR] = Token.ERROR; + } + + + public LexicalAnalyzerImpl(As8080Lexer lexer) { + this.lexer = Objects.requireNonNull(lexer); + } + + @Override + public Token nextToken() { + org.antlr.v4.runtime.Token token = lexer.nextToken(); + return new Token() { + @Override + public int getType() { + return convertLexerTokenType(token.getType()); + } + + @Override + public int getOffset() { + return token.getStartIndex(); + } + + @Override + public String getText() { + return token.getText(); + } + }; + } + + @Override + public boolean isAtEOF() { + return lexer._hitEOF; + } + + @Override + public void reset(InputStream inputStream) throws IOException { + lexer.setInputStream(CharStreams.fromStream(inputStream)); + } + + private int convertLexerTokenType(int tokenType) { + return tokenMap[tokenType]; + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java new file mode 100644 index 000000000..7d59b4743 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java @@ -0,0 +1,19 @@ +package net.emustudio.plugins.compiler.as8080; + +import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; + +class ParserErrorListener extends BaseErrorListener { + @Override + public void syntaxError( + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { + throw new CompileException(charPositionInLine, line, msg); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Runner.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Runner.java index 09aefc43d..84737e271 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Runner.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Runner.java @@ -38,7 +38,7 @@ public static void main(String... args) { printHelp(); return; } else if (arg.equals("--version") || arg.equals("-v")) { - System.out.println(new CompilerImpl(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE).getVersion()); + System.out.println(new Assembler8080(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE).getVersion()); return; } else { break; @@ -59,7 +59,7 @@ public static void main(String... args) { outputFile += ".hex"; } - CompilerImpl compiler = new CompilerImpl(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE); + Assembler8080 compiler = new Assembler8080(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE); compiler.addCompilerListener(new CompilerListener() { @Override public void onStart() { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/TokenImpl.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/TokenImpl.java deleted file mode 100644 index 56c81cc31..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/TokenImpl.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080; - -import java_cup.runtime.ComplexSymbolFactory.Location; -import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol; -import net.emustudio.emulib.plugins.compiler.Token; - -public class TokenImpl extends ComplexSymbol implements Token, Symbols { - - public final static int ERROR_DECIMAL_SIZE = 0xA01; - public final static int ERROR_UNCLOSED_CHAR = 0xA02; - public final static int ERROR_UNCLOSED_STRING = 0xA03; - - private final int category; - private final int lexerState; - - public TokenImpl(int id, int category, int lexerState, String text, Location left, Location right) { - super(text, id, left, right); - this.category = category; - this.lexerState = lexerState; - } - - public TokenImpl(int id, int category, int lexerState, String text, Location left, Location right, Object value) { - super(text, id, left, right, value); - this.category = category; - this.lexerState = lexerState; - } - - @Override - public int getID() { - return super.sym; - } - - @Override - public int getType() { - return this.category; - } - - @Override - public String getText() { - return getName(); - } - - @Override - public int getLexerState() { - return lexerState; - } - - @Override - public String getErrorString() { - switch (super.sym) { - case ERROR_DECIMAL_SIZE: - return "Literal has too big size (max. is 65535)"; - case ERROR_UNCLOSED_CHAR: - return "Char is not closed with single quote (')"; - case ERROR_UNCLOSED_STRING: - return "String is not closed with single quote (')"; - case ERROR: - return "Unknown token"; - } - return ""; - } - - @Override - public int getLine() { - return getLeft().getLine(); - } - - @Override - public int getColumn() { - return getLeft().getColumn(); - } - - @Override - public int getOffset() { - return getLeft().getOffset(); - } - - @Override - public int getLength() { - return getRight().getOffset() - getLeft().getOffset(); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/AbstractNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/AbstractNode.java new file mode 100644 index 000000000..ab2064452 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/AbstractNode.java @@ -0,0 +1,20 @@ +package net.emustudio.plugins.compiler.as8080.ast; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class AbstractNode implements Node { + protected final List children = new ArrayList<>(); + + @Override + public void addChild(Node node) { + children.add(Objects.requireNonNull(node)); + } + + @Override + public List getChildren() { + return Collections.unmodifiableList(children); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java new file mode 100644 index 000000000..42c389d23 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java @@ -0,0 +1,17 @@ +package net.emustudio.plugins.compiler.as8080.ast; + +import org.antlr.v4.runtime.Token; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +public class NameSpace { + + private final Map labels = new HashMap<>(); + + public void addLabel(Token token) { + labels.putIfAbsent(token.getText().toLowerCase(Locale.ENGLISH), token); + } + +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java new file mode 100644 index 000000000..552aaded6 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast; + +import java.util.List; + +public interface Node { + + void addChild(Node node); + + List getChildren(); +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java new file mode 100644 index 000000000..62ecef4a7 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java @@ -0,0 +1,9 @@ +package net.emustudio.plugins.compiler.as8080.ast; + +public class Program extends AbstractNode { + private final NameSpace nameSpace = new NameSpace(); + + public NameSpace env() { + return nameSpace; + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java new file mode 100644 index 000000000..8dfa67a7a --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java @@ -0,0 +1,6 @@ +package net.emustudio.plugins.compiler.as8080.ast.data; + +import net.emustudio.plugins.compiler.as8080.ast.AbstractNode; + +public abstract class Data extends AbstractNode { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java new file mode 100644 index 000000000..7b0465b8a --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java @@ -0,0 +1,4 @@ +package net.emustudio.plugins.compiler.as8080.ast.data; + +public class DataDB extends Data { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java new file mode 100644 index 000000000..e43f2d48f --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java @@ -0,0 +1,9 @@ +package net.emustudio.plugins.compiler.as8080.ast.data; + +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; + +public class DataDS extends Data { + public DataDS(Expr expr) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java new file mode 100644 index 000000000..128253e8c --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java @@ -0,0 +1,4 @@ +package net.emustudio.plugins.compiler.as8080.ast.data; + +public class DataDW extends Data { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java new file mode 100644 index 000000000..a94585089 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java @@ -0,0 +1,6 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +import net.emustudio.plugins.compiler.as8080.ast.AbstractNode; + +public abstract class Expr extends AbstractNode { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprBin.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprBin.java new file mode 100644 index 000000000..31591dc6c --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprBin.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +import org.antlr.v4.runtime.Token; + +public class ExprBin extends Expr { + + public ExprBin(Token number) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java new file mode 100644 index 000000000..f925eda70 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java @@ -0,0 +1,4 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +public class ExprCurrentAddress extends Expr { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprDec.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprDec.java new file mode 100644 index 000000000..9dad612ee --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprDec.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +import org.antlr.v4.runtime.Token; + +public class ExprDec extends Expr { + + public ExprDec(Token number) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex1.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex1.java new file mode 100644 index 000000000..d53c2455d --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex1.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +import org.antlr.v4.runtime.Token; + +public class ExprHex1 extends Expr { + + public ExprHex1(Token number) { + // TODO: parse + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex2.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex2.java new file mode 100644 index 000000000..944cabfc9 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex2.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +import org.antlr.v4.runtime.Token; + +public class ExprHex2 extends Expr { + + public ExprHex2(Token number) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java new file mode 100644 index 000000000..d5fee8f62 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java @@ -0,0 +1,13 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +public class ExprId extends Expr { + private final Token id; + + public ExprId(Token id) { + this.id = Objects.requireNonNull(id); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java new file mode 100644 index 000000000..23741019c --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +import org.antlr.v4.runtime.Token; + +public class ExprInfix extends Expr { + + public ExprInfix(Token op, Expr left, Expr right) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprOct.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprOct.java new file mode 100644 index 000000000..14e50cf2f --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprOct.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +import org.antlr.v4.runtime.Token; + +public class ExprOct extends Expr { + + public ExprOct(Token number) { + // TODO: parse + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprParens.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprParens.java new file mode 100644 index 000000000..36785cd5b --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprParens.java @@ -0,0 +1,4 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +public class ExprParens extends Expr { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java new file mode 100644 index 000000000..ac6b65306 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -0,0 +1,8 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +public class ExprUnary extends Expr { + + public ExprUnary(int unaryOp, Expr expr) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java new file mode 100644 index 000000000..cec3ffeff --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java @@ -0,0 +1,6 @@ +package net.emustudio.plugins.compiler.as8080.ast.instr; + +import net.emustudio.plugins.compiler.as8080.ast.AbstractNode; + +public abstract class Instr extends AbstractNode { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java new file mode 100644 index 000000000..ba4507c81 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -0,0 +1,16 @@ +package net.emustudio.plugins.compiler.as8080.ast.instr; + +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +public class InstrExpr extends Instr { + private final Token opcode; + private final Expr expr; + + public InstrExpr(Token opcode, Expr expr) { + this.opcode = Objects.requireNonNull(opcode); + this.expr = Objects.requireNonNull(expr); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java new file mode 100644 index 000000000..921da308d --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java @@ -0,0 +1,15 @@ +package net.emustudio.plugins.compiler.as8080.ast.instr; + +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +public class InstrNoArgs extends Instr { + private final Token opcode; + + public InstrNoArgs(Token opcode) { + this.opcode = Objects.requireNonNull(opcode); + } + + +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java new file mode 100644 index 000000000..c7cc575a7 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.instr; + +import org.antlr.v4.runtime.Token; + +public class InstrReg extends Instr { + + public InstrReg(Token opcode, Token reg) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java new file mode 100644 index 000000000..6c77f9d0d --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java @@ -0,0 +1,11 @@ +package net.emustudio.plugins.compiler.as8080.ast.instr; + +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import org.antlr.v4.runtime.Token; + +public class InstrRegExpr extends Instr { + + public InstrRegExpr(Token opcode, Token reg, Expr expr) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java new file mode 100644 index 000000000..e7f2dfe4f --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.instr; + +import org.antlr.v4.runtime.Token; + +public class InstrRegPair extends Instr { + + public InstrRegPair(Token opcode, Token regPair) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java new file mode 100644 index 000000000..cd56a7e07 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java @@ -0,0 +1,11 @@ +package net.emustudio.plugins.compiler.as8080.ast.instr; + +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import org.antlr.v4.runtime.Token; + +public class InstrRegPairExpr extends Instr { + + public InstrRegPairExpr(Token opcode, Token regPair, Expr expr) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java new file mode 100644 index 000000000..66040b91c --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.instr; + +import org.antlr.v4.runtime.Token; + +public class InstrRegReg extends Instr { + + public InstrRegReg(Token opcode, Token dst, Token src) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java new file mode 100644 index 000000000..40282e7e1 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java @@ -0,0 +1,6 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + +import net.emustudio.plugins.compiler.as8080.ast.AbstractNode; + +public abstract class Pseudo extends AbstractNode { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java new file mode 100644 index 000000000..9aeefae39 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java @@ -0,0 +1,11 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import org.antlr.v4.runtime.Token; + +public class PseudoEqu extends Pseudo { + + public PseudoEqu(Token id, Expr expr) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java new file mode 100644 index 000000000..3f27c73a1 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; + +public class PseudoIf extends Pseudo { + public PseudoIf(Expr expr, Node node) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java new file mode 100644 index 000000000..7cb5ff038 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java @@ -0,0 +1,4 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + +public class PseudoInclude extends Pseudo { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java new file mode 100644 index 000000000..ede8456e7 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java @@ -0,0 +1,4 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + +public class PseudoMacroCall extends Pseudo { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java new file mode 100644 index 000000000..59134b352 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java @@ -0,0 +1,4 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + +public class PseudoMacroDef extends Pseudo { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java new file mode 100644 index 000000000..79e8ef644 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java @@ -0,0 +1,11 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; + +public class PseudoOrg extends Pseudo { + + + public PseudoOrg(Expr expr) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java new file mode 100644 index 000000000..3c95bc057 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import org.antlr.v4.runtime.Token; + +public class PseudoSet extends Pseudo { + public PseudoSet(Token id, Expr expr) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDefinedException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDefinedException.java index 93700ebb7..d5c610de9 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDefinedException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDefinedException.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.exceptions; -public class AlreadyDefinedException extends CompilerException { +public class AlreadyDefinedException extends CompileException { public AlreadyDefinedException(int line, int column, String what) { super(line, column, what + " is already defined!"); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AmbiguousException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AmbiguousException.java index 980a01b07..34b4610c5 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AmbiguousException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AmbiguousException.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.exceptions; -public class AmbiguousException extends CompilerException { +public class AmbiguousException extends CompileException { public AmbiguousException(int line, int column, String whatIsAmbiguous) { super(line, column, whatIsAmbiguous + " is ambiguous!"); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CompilerException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CompileException.java similarity index 73% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CompilerException.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CompileException.java index f9d843b12..8232c640c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CompilerException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CompileException.java @@ -18,29 +18,21 @@ */ package net.emustudio.plugins.compiler.as8080.exceptions; -public class CompilerException extends Exception { - private final int line; - private final int column; +public class CompileException extends RuntimeException { + public final int line; + public final int column; - public CompilerException(int column, int line, String message) { + public CompileException(int column, int line, String message) { super("[" + line + "," + column + "] " + message); this.column = column; this.line = line; } - public CompilerException(int column, int line, String message, Throwable cause) { + public CompileException(int column, int line, String message, Throwable cause) { super("[" + line + "," + column + "] " + message, cause); this.column = column; this.line = line; } - - public int getColumn() { - return column; - } - - public int getLine() { - return line; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InvalidMacroParamsCountException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InvalidMacroParamsCountException.java index 41275c9f3..80ccc0efd 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InvalidMacroParamsCountException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InvalidMacroParamsCountException.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.exceptions; -public class InvalidMacroParamsCountException extends CompilerException { +public class InvalidMacroParamsCountException extends CompileException { public InvalidMacroParamsCountException(int column, int line, String name, int expected, int was) { super(column, line, "Invalid macro(" + name + ") parameters count, expected " + expected + ", but was " + was); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NeedMorePassException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NeedMorePassException.java index f931d8b59..a9f4138c2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NeedMorePassException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NeedMorePassException.java @@ -24,7 +24,7 @@ * Expression with forward reference for label can't be evaulated without knowing a value of the label (its address that * label is pointing at). */ -public class NeedMorePassException extends CompilerException { +public class NeedMorePassException extends CompileException { public NeedMorePassException(int line, int column) { super(line, column, ""); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NegativeValueException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NegativeValueException.java index d481349bb..3f2134e5b 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NegativeValueException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NegativeValueException.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.exceptions; -public class NegativeValueException extends CompilerException { +public class NegativeValueException extends CompileException { public NegativeValueException(int line, int column, int value) { super(line, column, "Value(" + value + ") cannot be negative!"); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UndefinedMacroException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UndefinedMacroException.java index 95d632d46..1d2f1e6ff 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UndefinedMacroException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UndefinedMacroException.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.exceptions; -public class UndefinedMacroException extends CompilerException { +public class UndefinedMacroException extends CompileException { public UndefinedMacroException(int column, int line, String macroName) { super(column, line, "Undefined macro: " + macroName); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnexpectedEOFException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnexpectedEOFException.java index cdb6e10da..a2257db2d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnexpectedEOFException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnexpectedEOFException.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.exceptions; -public class UnexpectedEOFException extends CompilerException { +public class UnexpectedEOFException extends CompileException { public UnexpectedEOFException(int line, int column, String filename) { super(line, column, "Unexpected end of file (" + filename + ")"); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownMacroParametersException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownMacroParametersException.java index b060cbce6..ed6198008 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownMacroParametersException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownMacroParametersException.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.exceptions; -public class UnknownMacroParametersException extends CompilerException { +public class UnknownMacroParametersException extends CompileException { public UnknownMacroParametersException(int column, int line, String name) { super(column, line, "Unknown macro(" + name + ") parameters"); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/ValueTooBigException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/ValueTooBigException.java index c848d5660..9abb96405 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/ValueTooBigException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/ValueTooBigException.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080.exceptions; -public class ValueTooBigException extends CompilerException { +public class ValueTooBigException extends CompileException { public ValueTooBigException(int line, int column, int currentValue, int maximumValue) { super(column, line, "Value (" + currentValue + ") too large (maximum is " + maximumValue + ")"); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java index 242bcf370..933ade454 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java @@ -19,9 +19,9 @@ package net.emustudio.plugins.compiler.as8080.tree; import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.CompilerImpl; +import net.emustudio.plugins.compiler.as8080.Assembler8080; import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.CompilerException; +import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; import net.emustudio.plugins.compiler.as8080.exceptions.UnexpectedEOFException; import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoNode; @@ -32,11 +32,11 @@ public class IncludePseudoNode extends PseudoNode { private final String fileName; - private final CompilerImpl compiler; + private final Assembler8080 compiler; private Statement program; private Namespace namespace; - public IncludePseudoNode(String filename, int line, int column, CompilerImpl compiler) { + public IncludePseudoNode(String filename, int line, int column, Assembler8080 compiler) { super(line, column); this.fileName = filename.replace("\\", File.separator); this.compiler = compiler; @@ -68,37 +68,37 @@ boolean isEqualName(String tmpFileName) { } void pass1(List includefiles, Namespace parentEnv) throws Exception { - try { - namespace = new Namespace(parentEnv.getInputFile().getAbsolutePath()); - - File file = findIncludeFile(fileName); - FileReader f = new FileReader(file); - LexerImpl lexer = new LexerImpl(f); - ParserImpl parser = new ParserImpl(lexer, compiler); - - parser.setReportPrefixString(file.getName() + ": "); - Object s = parser.parse().value; - parser.setReportPrefixString(null); - - if (s == null) { - throw new UnexpectedEOFException(line, column, file.getAbsolutePath()); - } - - program = (Statement) s; - program.addIncludeFiles(includefiles); - namespace = parentEnv; - - if (program.getIncludeLoops(file.getAbsolutePath())) { - throw new CompilerException(line, column, "Infinite INCLUDE loop (" + file.getAbsolutePath() + ")"); - } - program.pass1(namespace); // create symbol table - } catch (CompilerException e) { - throw e; - } catch (IOException e) { - throw new CompilerException(line, column, fileName + ": " + e.getMessage(), e); - } catch (Exception e) { - throw new CompilerException(line, column, e.getMessage(), e); - } +// try { +// namespace = new Namespace(parentEnv.getInputFile().getAbsolutePath()); +// +// File file = findIncludeFile(fileName); +// FileReader f = new FileReader(file); +// LexerImpl lexer = new LexerImpl(f); +// ParserImpl parser = new ParserImpl(lexer, compiler); +// +// parser.setReportPrefixString(file.getName() + ": "); +// Object s = parser.parse().value; +// parser.setReportPrefixString(null); +// +// if (s == null) { +// throw new UnexpectedEOFException(line, column, file.getAbsolutePath()); +// } +// +// program = (Statement) s; +// program.addIncludeFiles(includefiles); +// namespace = parentEnv; +// +// if (program.getIncludeLoops(file.getAbsolutePath())) { +// throw new CompileException(line, column, "Infinite INCLUDE loop (" + file.getAbsolutePath() + ")"); +// } +// program.pass1(namespace); // create symbol table +// } catch (CompileException e) { +// throw e; +// } catch (IOException e) { +// throw new CompileException(line, column, fileName + ": " + e.getMessage(), e); +// } catch (Exception e) { +// throw new CompileException(line, column, e.getMessage(), e); +// } } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java index 16a233da1..045481dd1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java @@ -80,7 +80,7 @@ public String getName() { @Override public void pass4(IntelHEX hex) { - hex.add(statHex.getTable()); + //hex.add(statHex.getTable()); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java index b04d8eb5e..eaea9039f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.CompilerException; +import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; // only for mov instruction @@ -43,7 +43,7 @@ public int getSize() { @Override public int pass2(Namespace parentEnv, int addr_start) throws Exception { if ((reg_src == reg_dst) && (reg_src == 6)) { - throw new CompilerException(line, column, "Can't use M register on both src and dst"); + throw new CompileException(line, column, "Can't use M register on both src and dst"); } return addr_start + 1; } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java new file mode 100644 index 000000000..cf325c6c4 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +public class AllVisitors { + + static PseudoVisitor pseudo = new PseudoVisitor(); + static ExprVisitor expr = new ExprVisitor(); + static InstrVisitor instr = new InstrVisitor(); + static DataVisitor data = new DataVisitor(); + static StatementVisitor statement = new StatementVisitor(); +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java new file mode 100644 index 000000000..f377437ae --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java @@ -0,0 +1,21 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Program; + +import java.util.Optional; + +/** + * The visitor creates internal AST (= "Program") of the parse tree. + */ +public class CreateProgramVisitor extends As8080ParserBaseVisitor { + private final Program program = new Program(); + + @Override + public Program visitRLine(As8080Parser.RLineContext ctx) { + Optional.ofNullable(ctx.label).ifPresent(program.env()::addLabel); + program.addChild(AllVisitors.statement.visit(ctx.statement)); + return program; + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java new file mode 100644 index 000000000..0eba7125d --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java @@ -0,0 +1,27 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.data.Data; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; + +public class DataVisitor extends As8080ParserBaseVisitor { + + @Override + public Data visitDataDB(As8080Parser.DataDBContext ctx) { + + return new DataDB(); + } + + @Override + public Data visitDataDW(As8080Parser.DataDWContext ctx) { + return new DataDW(); + } + + @Override + public Data visitDataDS(As8080Parser.DataDSContext ctx) { + return new DataDS(AllVisitors.expr.visit(ctx.data)); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java new file mode 100644 index 000000000..48250f3a5 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java @@ -0,0 +1,53 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.expr.*; + +public class ExprVisitor extends As8080ParserBaseVisitor { + + @Override + public Expr visitExprOct(As8080Parser.ExprOctContext ctx) { + return new ExprOct(ctx.num); + } + + @Override + public Expr visitExprHex1(As8080Parser.ExprHex1Context ctx) { + return new ExprHex1(ctx.num); + } + + @Override + public Expr visitExprHex2(As8080Parser.ExprHex2Context ctx) { + return new ExprHex2(ctx.num); + } + + @Override + public Expr visitExprDec(As8080Parser.ExprDecContext ctx) { + return new ExprDec(ctx.num); + } + + @Override + public Expr visitExprBin(As8080Parser.ExprBinContext ctx) { + return new ExprBin(ctx.num); + } + + @Override + public Expr visitExprId(As8080Parser.ExprIdContext ctx) { + return new ExprId(ctx.id); + } + + @Override + public Expr visitExprUnary(As8080Parser.ExprUnaryContext ctx) { + return new ExprUnary(ctx.unaryop.getType(), visit(ctx.expr)); + } + + @Override + public Expr visitExprInfix(As8080Parser.ExprInfixContext ctx) { + return new ExprInfix(ctx.op, visit(ctx.expr1), visit(ctx.expr2)); + } + + @Override + public Expr visitExprCurrentAddress(As8080Parser.ExprCurrentAddressContext ctx) { + return new ExprCurrentAddress(); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java new file mode 100644 index 000000000..4116e009c --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java @@ -0,0 +1,43 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.instr.*; + +public class InstrVisitor extends As8080ParserBaseVisitor { + + @Override + public Instr visitInstrNoArgs(As8080Parser.InstrNoArgsContext ctx) { + return new InstrNoArgs(ctx.opcode); + } + + @Override + public Instr visitInstrReg(As8080Parser.InstrRegContext ctx) { + return new InstrReg(ctx.opcode, ctx.reg.start); + } + + @Override + public Instr visitInstrRegReg(As8080Parser.InstrRegRegContext ctx) { + return new InstrRegReg(ctx.opcode, ctx.dst.start, ctx.src.start); + } + + @Override + public Instr visitInstrRegPair(As8080Parser.InstrRegPairContext ctx) { + return new InstrRegPair(ctx.opcode, ctx.regpair); + } + + @Override + public Instr visitInstrRegPairExpr(As8080Parser.InstrRegPairExprContext ctx) { + return new InstrRegPairExpr(ctx.opcode, ctx.regpair, AllVisitors.expr.visit(ctx.expr)); + } + + @Override + public Instr visitInstrRegExpr(As8080Parser.InstrRegExprContext ctx) { + return new InstrRegExpr(ctx.opcode, ctx.reg.start, AllVisitors.expr.visit(ctx.expr)); + } + + @Override + public Instr visitInstrExpr(As8080Parser.InstrExprContext ctx) { + return new InstrExpr(ctx.opcode, AllVisitors.expr.visit(ctx.expr)); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java new file mode 100644 index 000000000..474d72996 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java @@ -0,0 +1,43 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; + +public class PseudoVisitor extends As8080ParserBaseVisitor { + + @Override + public Pseudo visitPseudoOrg(As8080Parser.PseudoOrgContext ctx) { + return new PseudoOrg(AllVisitors.expr.visit(ctx.expr)); + } + + @Override + public Pseudo visitPseudoEqu(As8080Parser.PseudoEquContext ctx) { + return new PseudoEqu(ctx.id, AllVisitors.expr.visit(ctx.expr)); + } + + @Override + public Pseudo visitPseudoSet(As8080Parser.PseudoSetContext ctx) { + return new PseudoSet(ctx.id, AllVisitors.expr.visit(ctx.expr)); + } + + @Override + public Pseudo visitPseudoIf(As8080Parser.PseudoIfContext ctx) { + return new PseudoIf(AllVisitors.expr.visit(ctx.expr), AllVisitors.statement.visit(ctx.statement)); + } + + @Override + public Pseudo visitPseudoMacroDef(As8080Parser.PseudoMacroDefContext ctx) { + return new PseudoMacroDef(); + } + + @Override + public Pseudo visitPseudoMacroCall(As8080Parser.PseudoMacroCallContext ctx) { + return new PseudoMacroCall(); + } + + @Override + public Pseudo visitPseudoInclude(As8080Parser.PseudoIncludeContext ctx) { + return new PseudoInclude(); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java new file mode 100644 index 000000000..a16f02e97 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java @@ -0,0 +1,22 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Node; + +public class StatementVisitor extends As8080ParserBaseVisitor { + + @Override + public Node visitRStatement(As8080Parser.RStatementContext ctx) { + if (ctx.instr != null) { + return AllVisitors.instr.visit(ctx.instr); + } + if (ctx.data != null) { + return AllVisitors.data.visit(ctx.data); + } + if (ctx.pseudo != null) { + return AllVisitors.pseudo.visit(ctx.pseudo); + } + throw new RuntimeException("No statement!"); + } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/AbstractCompilerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/AbstractCompilerTest.java index cad9c4dc5..098233aa5 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/AbstractCompilerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/AbstractCompilerTest.java @@ -18,6 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080; +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.cpu.testsuite.memory.MemoryStub; import net.emustudio.cpu.testsuite.memory.ShortMemoryStub; import net.emustudio.emulib.plugins.compiler.CompilerListener; @@ -27,7 +28,6 @@ import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; -import net.emustudio.plugins.compiler.as8080.CompilerImpl; import org.junit.Before; import org.junit.Rule; import org.junit.rules.TemporaryFolder; @@ -40,8 +40,8 @@ import static org.junit.Assert.assertEquals; public abstract class AbstractCompilerTest { - protected CompilerImpl compiler; - protected MemoryStub memoryStub; + protected Assembler8080 compiler; + protected MemoryStub memoryStub; @Rule public TemporaryFolder folder = new TemporaryFolder(); @@ -49,7 +49,7 @@ public abstract class AbstractCompilerTest { @SuppressWarnings("unchecked") @Before public void setUp() throws Exception { - memoryStub = new ShortMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); + memoryStub = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); ContextPool contextPool = createNiceMock(ContextPool.class); expect(contextPool.getMemoryContext(0, MemoryContext.class)).andReturn(memoryStub).anyTimes(); @@ -59,7 +59,7 @@ public void setUp() throws Exception { expect(applicationApi.getContextPool()).andReturn(contextPool); replay(applicationApi); - compiler = new CompilerImpl(0L, applicationApi, PluginSettings.UNAVAILABLE); + compiler = new Assembler8080(0L, applicationApi, PluginSettings.UNAVAILABLE); compiler.addCompilerListener(new CompilerListener() { @Override public void onStart() { diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/CompilerImplTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Assembler8080Test.java similarity index 97% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/CompilerImplTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Assembler8080Test.java index 533b8d303..b8a96e636 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/CompilerImplTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Assembler8080Test.java @@ -18,11 +18,13 @@ */ package net.emustudio.plugins.compiler.as8080; +import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.assertNotEquals; -public class CompilerImplTest extends AbstractCompilerTest { +@Ignore +public class Assembler8080Test extends AbstractCompilerTest { @Test public void testVersionIsKnown() { diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java index 8d79e9bd3..8ef617d2d 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java @@ -18,8 +18,10 @@ */ package net.emustudio.plugins.compiler.as8080; +import org.junit.Ignore; import org.junit.Test; +@Ignore public class ConstantsAndVariablesTest extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/DataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/DataTest.java index 85894867c..081c8fe59 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/DataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/DataTest.java @@ -18,8 +18,10 @@ */ package net.emustudio.plugins.compiler.as8080; +import org.junit.Ignore; import org.junit.Test; +@Ignore public class DataTest extends AbstractCompilerTest { @Test @@ -162,8 +164,8 @@ public void testDSwithNegativeValueDoesNotWork() throws Exception { @Test public void testDSbreaksPreviousMemoryContent() throws Exception { - memoryStub.write(0, (short) 0x10); - memoryStub.write(1, (short) 0x11); + memoryStub.write(0, (byte) 0x10); + memoryStub.write(1, (byte) 0x11); compile( "ds 2\n" + "now: mov a,b\n" diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IfNodeTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IfNodeTest.java index 73f199b98..4e9a5d60f 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IfNodeTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IfNodeTest.java @@ -18,8 +18,10 @@ */ package net.emustudio.plugins.compiler.as8080; +import org.junit.Ignore; import org.junit.Test; +@Ignore public class IfNodeTest extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IncludeTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IncludeTest.java index ebaf4da3f..659c310ef 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IncludeTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IncludeTest.java @@ -18,10 +18,12 @@ */ package net.emustudio.plugins.compiler.as8080; +import org.junit.Ignore; import org.junit.Test; import java.io.File; +@Ignore public class IncludeTest extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java new file mode 100644 index 000000000..c1edef38e --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java @@ -0,0 +1,70 @@ +package net.emustudio.plugins.compiler.as8080; + +import org.junit.Test; + +import static net.emustudio.plugins.compiler.as8080.As8080Lexer.*; +import static net.emustudio.plugins.compiler.as8080.Utils.assertTokenTypes; + +public class LexerTest { + + @Test + public void testParseError() { + assertTokenTypes("B &", REG_B, WS, ERROR, EOF); + assertTokenTypes("0x 9o 22b", ERROR, WS, ERROR, WS, ERROR, EOF); + } + + @Test + public void testParseHexNumbers() { + assertTokenTypes( + "0x5F 0X5F 5fh 5fH 5Fh 0xG", + LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, ERROR, EOF + ); + assertTokenTypes("-5h -0xFF", LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, EOF); + } + +// @Test +// public void testParseReservedWords() { +// assertTokenTypesForCaseVariations("jmp", SSEMLexer.JMP, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("jrp", SSEMLexer.JPR, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("jpr", SSEMLexer.JPR, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("jmr", SSEMLexer.JPR, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("ldn", SSEMLexer.LDN, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("sto", SSEMLexer.STO, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("sub", SSEMLexer.SUB, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("cmp", SSEMLexer.CMP, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("skn", SSEMLexer.CMP, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("stp", SSEMLexer.STP, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("hlt", SSEMLexer.STP, SSEMLexer.EOF); +// } +// +// @Test +// public void testParsePreprocessor() { +// assertTokenTypesForCaseVariations("start", SSEMLexer.START, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("num", SSEMLexer.NUM, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("bnum", SSEMLexer.BNUM, SSEMLexer.EOF); +// assertTokenTypesForCaseVariations("bins", SSEMLexer.BNUM, SSEMLexer.EOF); +// } +// +// @Test +// public void testParseWhitespaces() { +// assertTokenTypes(" ", SSEMLexer.WS, SSEMLexer.EOF); +// assertTokenTypes("\t", SSEMLexer.WS, SSEMLexer.EOF); +// assertTokenTypes("\n", SSEMLexer.EOL, SSEMLexer.EOF); +// assertTokenTypes("", SSEMLexer.EOF); +// } +// +// @Test +// public void testParseComments() { +// assertTokenTypes("-- comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); +// assertTokenTypes("# comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); +// assertTokenTypes("// comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); +// assertTokenTypes("; comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); +// } +// +// @Test +// public void testLiterals() { +// assertTokenTypes("10", SSEMLexer.NUMBER, SSEMLexer.EOF); +// assertTokenTypes("0xAF", SSEMLexer.HEXNUMBER, SSEMLexer.EOF); +// assertTokenTypes("BINS 1010", SSEMLexer.BNUM, SSEMLexer.BWS, SSEMLexer.BinaryNumber, SSEMLexer.EOF); +// } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/MacroTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/MacroTest.java index 573a6f3e0..cea2522ff 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/MacroTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/MacroTest.java @@ -18,8 +18,10 @@ */ package net.emustudio.plugins.compiler.as8080; +import org.junit.Ignore; import org.junit.Test; +@Ignore public class MacroTest extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_ExprTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_ExprTest.java index a23fea8c1..520b22086 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_ExprTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_ExprTest.java @@ -1,7 +1,9 @@ package net.emustudio.plugins.compiler.as8080; +import org.junit.Ignore; import org.junit.Test; +@Ignore public class OC_ExprTest extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_RegTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_RegTest.java index 28d6d8ac2..d6624215f 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_RegTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_RegTest.java @@ -20,10 +20,12 @@ import net.emustudio.plugins.compiler.as8080.tree.OC_Reg; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.assertEquals; +@Ignore public class OC_RegTest extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ORGTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ORGTest.java index c5949a4ca..ea5fe6b24 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ORGTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ORGTest.java @@ -20,12 +20,14 @@ import net.emustudio.plugins.compiler.as8080.tree.OrgPseudoNode; import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; +import org.junit.Ignore; import org.junit.Test; import java.io.File; import static org.junit.Assert.assertEquals; +@Ignore public class ORGTest extends AbstractCompilerTest { @Test @@ -135,8 +137,8 @@ public void testORGwithJumpForwards() throws Exception { @Test public void testORGdoesNotBreakPreviousMemoryContent() throws Exception { - memoryStub.write(0, (short) 0x10); - memoryStub.write(1, (short) 0x11); + memoryStub.write(0, (byte) 0x10); + memoryStub.write(1, (byte) 0x11); compile( "org 2\n" + "now: mov a,b\n" diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java index 94d6ad1c7..b968a0383 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java @@ -18,6 +18,7 @@ */ package net.emustudio.plugins.compiler.as8080; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -29,6 +30,7 @@ import static org.junit.Assert.assertEquals; +@Ignore public class RunnerTest { @Rule diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java new file mode 100644 index 000000000..a8852cd33 --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -0,0 +1,55 @@ +package net.emustudio.plugins.compiler.as8080; + +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.Token; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import static org.junit.Assert.assertEquals; + +public class Utils { + public static List getTokens(String variation) { + As8080Lexer lexer = new As8080Lexer(CharStreams.fromString(variation)); + CommonTokenStream stream = new CommonTokenStream(lexer); + stream.fill(); + return stream.getTokens(); + } + + public static void assertTokenTypes(String variation, int... expectedTypes) { + List tokens = getTokens(variation); + assertTokenTypes(tokens, expectedTypes); + } + + public static void assertTokenTypes(List tokens, int... expectedTypes) { + assertEquals("Tokens: " + tokens, expectedTypes.length, tokens.size()); + for (int i = 0; i < expectedTypes.length; i++) { + Token token = tokens.get(i); + assertEquals(expectedTypes[i], token.getType()); + } + } + + public static void assertTokenTypesForCaseVariations(String base, int... expectedTypes) { + Random r = new Random(); + List variations = new ArrayList<>(); + variations.add(base); + variations.add(base.toLowerCase()); + variations.add(base.toUpperCase()); + for (int i = 0; i < 5; i++) { + byte[] chars = base.getBytes(); + for (int j = 0; j < base.length(); j++) { + if (r.nextBoolean()) { + chars[j] = Character.valueOf((char) chars[j]).toString().toUpperCase().getBytes()[0]; + } else { + chars[j] = Character.valueOf((char) chars[j]).toString().toLowerCase().getBytes()[0]; + } + } + variations.add(new String(chars)); + } + for (String variation : variations) { + assertTokenTypes(variation, expectedTypes); + } + } +} From b6e5178996984e88ce7405142adc46dd740680d7 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 25 Nov 2021 14:51:18 +0100 Subject: [PATCH 043/314] [#201] Initial ANTLR for 8080asm --- plugins/compiler/as-8080/.gitignore | 3 +- .../as-8080/src/main/antlr/As8080Lexer.g4 | 41 +- .../as-8080/src/main/antlr/As8080Lexer.tokens | 71 +-- .../src/main/antlr/gen/As8080Lexer.interp | 425 --------------- .../src/main/antlr/gen/As8080Lexer.java | 506 ------------------ .../src/main/antlr/gen/As8080Lexer.tokens | 137 ----- .../as-8080/src/main/gen/As8080Lexer.interp | 425 --------------- .../as-8080/src/main/gen/As8080Lexer.java | 504 ----------------- .../as-8080/src/main/gen/As8080Lexer.tokens | 137 ----- .../compiler/as8080/Assembler8080.java | 4 +- .../plugins/compiler/as8080/Lexer.java | 194 +++++++ .../plugins/compiler/as8080/ast/Program.java | 11 + .../compiler/as8080/ast/Statement.java | 4 + .../as8080/visitors/ProgramVisitor.java | 31 ++ .../plugins/compiler/as8080/LexerTest.java | 274 ++++++++-- .../plugins/compiler/as8080/Utils.java | 4 +- 16 files changed, 523 insertions(+), 2248 deletions(-) delete mode 100644 plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.interp delete mode 100644 plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.java delete mode 100644 plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.tokens delete mode 100644 plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp delete mode 100644 plugins/compiler/as-8080/src/main/gen/As8080Lexer.java delete mode 100644 plugins/compiler/as-8080/src/main/gen/As8080Lexer.tokens create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ProgramVisitor.java diff --git a/plugins/compiler/as-8080/.gitignore b/plugins/compiler/as-8080/.gitignore index a5b9d2748..a37c70406 100644 --- a/plugins/compiler/as-8080/.gitignore +++ b/plugins/compiler/as-8080/.gitignore @@ -1 +1,2 @@ -src/main/java/net/emustudio/plugins/compiler/as8080/LexerImpl.java +/src/main/antlr/gen/ +/src/main/gen/ diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 index b12934b6e..b812bbd6d 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 @@ -1,11 +1,7 @@ lexer grammar As8080Lexer; -options { - backtrack=false; -} - -WS : (' ' | '\t' | '\f') -> channel(HIDDEN); -COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]*; +COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]* -> skip; +COMMENT2: '/*' .*? '*/' -> skip; EOL: '\r'? '\n'; fragment A: [aA]; @@ -140,17 +136,7 @@ REG_M: M; REG_PSW: P S W; REG_SP: S P; -// separators -SEP_LPAR: '('; -SEP_RPAR: ')'; -SEP_COMMA: ','; - // operators -OP_ADD: '+'; -OP_SUBTRACT: '-'; -OP_MULTIPLY: '*'; -OP_DIVIDE: '/'; -OP_EQUAL: '='; OP_MOD: M O D; OP_SHR: S H R; OP_SHL: S H L; @@ -160,17 +146,32 @@ OP_OR: O R; OP_XOR: X O R; // literals -LIT_NUMBER: [\-]? [0-9]+ D?; LIT_HEXNUMBER_1: [\-]? '0' X [0-9a-fA-F]+; +LIT_NUMBER: [\-]? [0-9]+ D?; LIT_HEXNUMBER_2: [\-]? [0-9a-fA-F]+ H; LIT_OCTNUMBER: [\-]? [0-7]+ [oOqQ]; LIT_BINNUMBER: [01]+ B; -LIT_STRING_1: ['] [^']+ [']; -LIT_STRING_2: '"' [^"]+ '"'; +LIT_STRING_1: '\'' ~[']* '\''; +LIT_STRING_2: '"' ~["]* '"'; // other ID_IDENTIFIER: [a-zA-Z_?@] [a-zA-Z_?@0-9]*; ID_LABEL: [a-zA-Z_?@] [a-zA-Z_?@0-9]* ':'; -ERROR : .; +ERROR : ~[+* \t\f(),=/-]+; // below: everything which does not require space + +//\+\* +// separators - not requiring space inbetween +SEP_LPAR: '('; +SEP_RPAR: ')'; +SEP_COMMA: ','; + +// operators not requiring space inbetween +OP_ADD: '+'; +OP_SUBTRACT: '-'; +OP_MULTIPLY: '*'; +OP_DIVIDE: '/'; +OP_EQUAL: '='; + +WS : [ \t\f]+ -> skip; diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens index a522a3c4c..070cfdfa4 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens @@ -1,5 +1,5 @@ -WS=1 -COMMENT=2 +COMMENT=1 +COMMENT2=2 EOL=3 OPCODE_STC=4 OPCODE_CMC=5 @@ -101,37 +101,38 @@ REG_L=100 REG_M=101 REG_PSW=102 REG_SP=103 -SEP_LPAR=104 -SEP_RPAR=105 -SEP_COMMA=106 -OP_ADD=107 -OP_SUBTRACT=108 -OP_MULTIPLY=109 -OP_DIVIDE=110 -OP_EQUAL=111 -OP_MOD=112 -OP_SHR=113 -OP_SHL=114 -OP_NOT=115 -OP_AND=116 -OP_OR=117 -OP_XOR=118 -LIT_NUMBER=119 -LIT_HEXNUMBER_1=120 -LIT_HEXNUMBER_2=121 -LIT_OCTNUMBER=122 -LIT_BINNUMBER=123 -LIT_STRING_1=124 -LIT_STRING_2=125 -ID_IDENTIFIER=126 -ID_LABEL=127 -ERROR=128 +OP_MOD=104 +OP_SHR=105 +OP_SHL=106 +OP_NOT=107 +OP_AND=108 +OP_OR=109 +OP_XOR=110 +LIT_HEXNUMBER_1=111 +LIT_NUMBER=112 +LIT_HEXNUMBER_2=113 +LIT_OCTNUMBER=114 +LIT_BINNUMBER=115 +LIT_STRING_1=116 +LIT_STRING_2=117 +ID_IDENTIFIER=118 +ID_LABEL=119 +ERROR=120 +SEP_LPAR=121 +SEP_RPAR=122 +SEP_COMMA=123 +OP_ADD=124 +OP_SUBTRACT=125 +OP_MULTIPLY=126 +OP_DIVIDE=127 +OP_EQUAL=128 +WS=129 '$'=93 -'('=104 -')'=105 -','=106 -'+'=107 -'-'=108 -'*'=109 -'/'=110 -'='=111 +'('=121 +')'=122 +','=123 +'+'=124 +'-'=125 +'*'=126 +'/'=127 +'='=128 diff --git a/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.interp b/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.interp deleted file mode 100644 index ad3f351ce..000000000 --- a/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.interp +++ /dev/null @@ -1,425 +0,0 @@ -token literal names: -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -'$' -null -null -null -null -null -null -null -null -null -null -'(' -')' -',' -'+' -'-' -'*' -'/' -'=' -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null - -token symbolic names: -null -WS -COMMENT -EOL -OPCODE_STC -OPCODE_CMC -OPCODE_INR -OPCODE_DCR -OPCODE_CMA -OPCODE_DAA -OPCODE_NOP -OPCODE_MOV -OPCODE_STAX -OPCODE_LDAX -OPCODE_ADD -OPCODE_ADC -OPCODE_SUB -OPCODE_SBB -OPCODE_ANA -OPCODE_XRA -OPCODE_ORA -OPCODE_CMP -OPCODE_RLC -OPCODE_RRC -OPCODE_RAL -OPCODE_RAR -OPCODE_PUSH -OPCODE_POP -OPCODE_DAD -OPCODE_INX -OPCODE_DCX -OPCODE_XCHG -OPCODE_XTHL -OPCODE_SPHL -OPCODE_LXI -OPCODE_MVI -OPCODE_ADI -OPCODE_ACI -OPCODE_SUI -OPCODE_SBI -OPCODE_ANI -OPCODE_XRI -OPCODE_ORI -OPCODE_CPI -OPCODE_STA -OPCODE_LDA -OPCODE_SHLD -OPCODE_LHLD -OPCODE_PCHL -OPCODE_JMP -OPCODE_JC -OPCODE_JNC -OPCODE_JZ -OPCODE_JNZ -OPCODE_JP -OPCODE_JM -OPCODE_JPE -OPCODE_JPO -OPCODE_CALL -OPCODE_CC -OPCODE_CNC -OPCODE_CZ -OPCODE_CNZ -OPCODE_CP -OPCODE_CM -OPCODE_CPE -OPCODE_CPO -OPCODE_RET -OPCODE_RC -OPCODE_RNC -OPCODE_RZ -OPCODE_RNZ -OPCODE_RM -OPCODE_RP -OPCODE_RPE -OPCODE_RPO -OPCODE_RST -OPCODE_EI -OPCODE_DI -OPCODE_IN -OPCODE_OUT -OPCODE_HLT -PREP_ORG -PREP_EQU -PREP_SET -PREP_INCLUDE -PREP_IF -PREP_ENDIF -PREP_MACRO -PREP_ENDM -PREP_DB -PREP_DW -PREP_DS -PREP_ADDR -REG_A -REG_B -REG_C -REG_D -REG_E -REG_H -REG_L -REG_M -REG_PSW -REG_SP -SEP_LPAR -SEP_RPAR -SEP_COMMA -OP_ADD -OP_SUBTRACT -OP_MULTIPLY -OP_DIVIDE -OP_EQUAL -OP_MOD -OP_SHR -OP_SHL -OP_NOT -OP_AND -OP_OR -OP_XOR -LIT_NUMBER -LIT_HEXNUMBER_1 -LIT_HEXNUMBER_2 -LIT_OCTNUMBER -LIT_BINNUMBER -LIT_STRING_1 -LIT_STRING_2 -ID_IDENTIFIER -ID_LABEL -ERROR - -rule names: -WS -COMMENT -EOL -A -B -C -D -E -F -G -H -I -J -L -M -N -O -P -Q -R -S -T -U -V -W -X -Z -OPCODE_STC -OPCODE_CMC -OPCODE_INR -OPCODE_DCR -OPCODE_CMA -OPCODE_DAA -OPCODE_NOP -OPCODE_MOV -OPCODE_STAX -OPCODE_LDAX -OPCODE_ADD -OPCODE_ADC -OPCODE_SUB -OPCODE_SBB -OPCODE_ANA -OPCODE_XRA -OPCODE_ORA -OPCODE_CMP -OPCODE_RLC -OPCODE_RRC -OPCODE_RAL -OPCODE_RAR -OPCODE_PUSH -OPCODE_POP -OPCODE_DAD -OPCODE_INX -OPCODE_DCX -OPCODE_XCHG -OPCODE_XTHL -OPCODE_SPHL -OPCODE_LXI -OPCODE_MVI -OPCODE_ADI -OPCODE_ACI -OPCODE_SUI -OPCODE_SBI -OPCODE_ANI -OPCODE_XRI -OPCODE_ORI -OPCODE_CPI -OPCODE_STA -OPCODE_LDA -OPCODE_SHLD -OPCODE_LHLD -OPCODE_PCHL -OPCODE_JMP -OPCODE_JC -OPCODE_JNC -OPCODE_JZ -OPCODE_JNZ -OPCODE_JP -OPCODE_JM -OPCODE_JPE -OPCODE_JPO -OPCODE_CALL -OPCODE_CC -OPCODE_CNC -OPCODE_CZ -OPCODE_CNZ -OPCODE_CP -OPCODE_CM -OPCODE_CPE -OPCODE_CPO -OPCODE_RET -OPCODE_RC -OPCODE_RNC -OPCODE_RZ -OPCODE_RNZ -OPCODE_RM -OPCODE_RP -OPCODE_RPE -OPCODE_RPO -OPCODE_RST -OPCODE_EI -OPCODE_DI -OPCODE_IN -OPCODE_OUT -OPCODE_HLT -PREP_ORG -PREP_EQU -PREP_SET -PREP_INCLUDE -PREP_IF -PREP_ENDIF -PREP_MACRO -PREP_ENDM -PREP_DB -PREP_DW -PREP_DS -PREP_ADDR -REG_A -REG_B -REG_C -REG_D -REG_E -REG_H -REG_L -REG_M -REG_PSW -REG_SP -SEP_LPAR -SEP_RPAR -SEP_COMMA -OP_ADD -OP_SUBTRACT -OP_MULTIPLY -OP_DIVIDE -OP_EQUAL -OP_MOD -OP_SHR -OP_SHL -OP_NOT -OP_AND -OP_OR -OP_XOR -LIT_NUMBER -LIT_HEXNUMBER_1 -LIT_HEXNUMBER_2 -LIT_OCTNUMBER -LIT_BINNUMBER -LIT_STRING_1 -LIT_STRING_2 -ID_IDENTIFIER -ID_LABEL -ERROR - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 130, 887, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 317, 10, 3, 3, 3, 7, 3, 320, 10, 3, 12, 3, 14, 3, 323, 11, 3, 3, 4, 5, 4, 326, 10, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 105, 3, 105, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 130, 3, 130, 3, 131, 3, 131, 3, 132, 3, 132, 3, 133, 3, 133, 3, 134, 3, 134, 3, 135, 3, 135, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 138, 3, 138, 3, 139, 3, 139, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 5, 144, 803, 10, 144, 3, 144, 6, 144, 806, 10, 144, 13, 144, 14, 144, 807, 3, 144, 5, 144, 811, 10, 144, 3, 145, 5, 145, 814, 10, 145, 3, 145, 3, 145, 3, 145, 3, 145, 5, 145, 820, 10, 145, 3, 145, 6, 145, 823, 10, 145, 13, 145, 14, 145, 824, 3, 146, 5, 146, 828, 10, 146, 3, 146, 6, 146, 831, 10, 146, 13, 146, 14, 146, 832, 3, 146, 3, 146, 3, 147, 5, 147, 838, 10, 147, 3, 147, 6, 147, 841, 10, 147, 13, 147, 14, 147, 842, 3, 147, 3, 147, 3, 148, 6, 148, 848, 10, 148, 13, 148, 14, 148, 849, 3, 148, 3, 148, 3, 149, 3, 149, 6, 149, 856, 10, 149, 13, 149, 14, 149, 857, 3, 149, 3, 149, 3, 150, 3, 150, 6, 150, 864, 10, 150, 13, 150, 14, 150, 865, 3, 150, 3, 150, 3, 151, 3, 151, 7, 151, 872, 10, 151, 12, 151, 14, 151, 875, 11, 151, 3, 152, 3, 152, 7, 152, 879, 10, 152, 12, 152, 14, 152, 882, 11, 152, 3, 152, 3, 152, 3, 153, 3, 153, 2, 2, 154, 3, 3, 5, 4, 7, 5, 9, 2, 11, 2, 13, 2, 15, 2, 17, 2, 19, 2, 21, 2, 23, 2, 25, 2, 27, 2, 29, 2, 31, 2, 33, 2, 35, 2, 37, 2, 39, 2, 41, 2, 43, 2, 45, 2, 47, 2, 49, 2, 51, 2, 53, 2, 55, 2, 57, 6, 59, 7, 61, 8, 63, 9, 65, 10, 67, 11, 69, 12, 71, 13, 73, 14, 75, 15, 77, 16, 79, 17, 81, 18, 83, 19, 85, 20, 87, 21, 89, 22, 91, 23, 93, 24, 95, 25, 97, 26, 99, 27, 101, 28, 103, 29, 105, 30, 107, 31, 109, 32, 111, 33, 113, 34, 115, 35, 117, 36, 119, 37, 121, 38, 123, 39, 125, 40, 127, 41, 129, 42, 131, 43, 133, 44, 135, 45, 137, 46, 139, 47, 141, 48, 143, 49, 145, 50, 147, 51, 149, 52, 151, 53, 153, 54, 155, 55, 157, 56, 159, 57, 161, 58, 163, 59, 165, 60, 167, 61, 169, 62, 171, 63, 173, 64, 175, 65, 177, 66, 179, 67, 181, 68, 183, 69, 185, 70, 187, 71, 189, 72, 191, 73, 193, 74, 195, 75, 197, 76, 199, 77, 201, 78, 203, 79, 205, 80, 207, 81, 209, 82, 211, 83, 213, 84, 215, 85, 217, 86, 219, 87, 221, 88, 223, 89, 225, 90, 227, 91, 229, 92, 231, 93, 233, 94, 235, 95, 237, 96, 239, 97, 241, 98, 243, 99, 245, 100, 247, 101, 249, 102, 251, 103, 253, 104, 255, 105, 257, 106, 259, 107, 261, 108, 263, 109, 265, 110, 267, 111, 269, 112, 271, 113, 273, 114, 275, 115, 277, 116, 279, 117, 281, 118, 283, 119, 285, 120, 287, 121, 289, 122, 291, 123, 293, 124, 295, 125, 297, 126, 299, 127, 301, 128, 303, 129, 305, 130, 3, 2, 40, 5, 2, 11, 11, 14, 14, 34, 34, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 92, 92, 124, 124, 3, 2, 47, 47, 3, 2, 50, 59, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 4, 2, 41, 41, 96, 96, 4, 2, 36, 36, 96, 96, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 2, 881, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 157, 3, 2, 2, 2, 2, 159, 3, 2, 2, 2, 2, 161, 3, 2, 2, 2, 2, 163, 3, 2, 2, 2, 2, 165, 3, 2, 2, 2, 2, 167, 3, 2, 2, 2, 2, 169, 3, 2, 2, 2, 2, 171, 3, 2, 2, 2, 2, 173, 3, 2, 2, 2, 2, 175, 3, 2, 2, 2, 2, 177, 3, 2, 2, 2, 2, 179, 3, 2, 2, 2, 2, 181, 3, 2, 2, 2, 2, 183, 3, 2, 2, 2, 2, 185, 3, 2, 2, 2, 2, 187, 3, 2, 2, 2, 2, 189, 3, 2, 2, 2, 2, 191, 3, 2, 2, 2, 2, 193, 3, 2, 2, 2, 2, 195, 3, 2, 2, 2, 2, 197, 3, 2, 2, 2, 2, 199, 3, 2, 2, 2, 2, 201, 3, 2, 2, 2, 2, 203, 3, 2, 2, 2, 2, 205, 3, 2, 2, 2, 2, 207, 3, 2, 2, 2, 2, 209, 3, 2, 2, 2, 2, 211, 3, 2, 2, 2, 2, 213, 3, 2, 2, 2, 2, 215, 3, 2, 2, 2, 2, 217, 3, 2, 2, 2, 2, 219, 3, 2, 2, 2, 2, 221, 3, 2, 2, 2, 2, 223, 3, 2, 2, 2, 2, 225, 3, 2, 2, 2, 2, 227, 3, 2, 2, 2, 2, 229, 3, 2, 2, 2, 2, 231, 3, 2, 2, 2, 2, 233, 3, 2, 2, 2, 2, 235, 3, 2, 2, 2, 2, 237, 3, 2, 2, 2, 2, 239, 3, 2, 2, 2, 2, 241, 3, 2, 2, 2, 2, 243, 3, 2, 2, 2, 2, 245, 3, 2, 2, 2, 2, 247, 3, 2, 2, 2, 2, 249, 3, 2, 2, 2, 2, 251, 3, 2, 2, 2, 2, 253, 3, 2, 2, 2, 2, 255, 3, 2, 2, 2, 2, 257, 3, 2, 2, 2, 2, 259, 3, 2, 2, 2, 2, 261, 3, 2, 2, 2, 2, 263, 3, 2, 2, 2, 2, 265, 3, 2, 2, 2, 2, 267, 3, 2, 2, 2, 2, 269, 3, 2, 2, 2, 2, 271, 3, 2, 2, 2, 2, 273, 3, 2, 2, 2, 2, 275, 3, 2, 2, 2, 2, 277, 3, 2, 2, 2, 2, 279, 3, 2, 2, 2, 2, 281, 3, 2, 2, 2, 2, 283, 3, 2, 2, 2, 2, 285, 3, 2, 2, 2, 2, 287, 3, 2, 2, 2, 2, 289, 3, 2, 2, 2, 2, 291, 3, 2, 2, 2, 2, 293, 3, 2, 2, 2, 2, 295, 3, 2, 2, 2, 2, 297, 3, 2, 2, 2, 2, 299, 3, 2, 2, 2, 2, 301, 3, 2, 2, 2, 2, 303, 3, 2, 2, 2, 2, 305, 3, 2, 2, 2, 3, 307, 3, 2, 2, 2, 5, 316, 3, 2, 2, 2, 7, 325, 3, 2, 2, 2, 9, 329, 3, 2, 2, 2, 11, 331, 3, 2, 2, 2, 13, 333, 3, 2, 2, 2, 15, 335, 3, 2, 2, 2, 17, 337, 3, 2, 2, 2, 19, 339, 3, 2, 2, 2, 21, 341, 3, 2, 2, 2, 23, 343, 3, 2, 2, 2, 25, 345, 3, 2, 2, 2, 27, 347, 3, 2, 2, 2, 29, 349, 3, 2, 2, 2, 31, 351, 3, 2, 2, 2, 33, 353, 3, 2, 2, 2, 35, 355, 3, 2, 2, 2, 37, 357, 3, 2, 2, 2, 39, 359, 3, 2, 2, 2, 41, 361, 3, 2, 2, 2, 43, 363, 3, 2, 2, 2, 45, 365, 3, 2, 2, 2, 47, 367, 3, 2, 2, 2, 49, 369, 3, 2, 2, 2, 51, 371, 3, 2, 2, 2, 53, 373, 3, 2, 2, 2, 55, 375, 3, 2, 2, 2, 57, 377, 3, 2, 2, 2, 59, 381, 3, 2, 2, 2, 61, 385, 3, 2, 2, 2, 63, 389, 3, 2, 2, 2, 65, 393, 3, 2, 2, 2, 67, 397, 3, 2, 2, 2, 69, 401, 3, 2, 2, 2, 71, 405, 3, 2, 2, 2, 73, 409, 3, 2, 2, 2, 75, 414, 3, 2, 2, 2, 77, 419, 3, 2, 2, 2, 79, 423, 3, 2, 2, 2, 81, 427, 3, 2, 2, 2, 83, 431, 3, 2, 2, 2, 85, 435, 3, 2, 2, 2, 87, 439, 3, 2, 2, 2, 89, 443, 3, 2, 2, 2, 91, 447, 3, 2, 2, 2, 93, 451, 3, 2, 2, 2, 95, 455, 3, 2, 2, 2, 97, 459, 3, 2, 2, 2, 99, 463, 3, 2, 2, 2, 101, 467, 3, 2, 2, 2, 103, 472, 3, 2, 2, 2, 105, 476, 3, 2, 2, 2, 107, 480, 3, 2, 2, 2, 109, 484, 3, 2, 2, 2, 111, 488, 3, 2, 2, 2, 113, 493, 3, 2, 2, 2, 115, 498, 3, 2, 2, 2, 117, 503, 3, 2, 2, 2, 119, 507, 3, 2, 2, 2, 121, 511, 3, 2, 2, 2, 123, 515, 3, 2, 2, 2, 125, 519, 3, 2, 2, 2, 127, 523, 3, 2, 2, 2, 129, 527, 3, 2, 2, 2, 131, 531, 3, 2, 2, 2, 133, 535, 3, 2, 2, 2, 135, 539, 3, 2, 2, 2, 137, 543, 3, 2, 2, 2, 139, 547, 3, 2, 2, 2, 141, 551, 3, 2, 2, 2, 143, 556, 3, 2, 2, 2, 145, 561, 3, 2, 2, 2, 147, 566, 3, 2, 2, 2, 149, 570, 3, 2, 2, 2, 151, 573, 3, 2, 2, 2, 153, 577, 3, 2, 2, 2, 155, 580, 3, 2, 2, 2, 157, 584, 3, 2, 2, 2, 159, 587, 3, 2, 2, 2, 161, 590, 3, 2, 2, 2, 163, 594, 3, 2, 2, 2, 165, 598, 3, 2, 2, 2, 167, 603, 3, 2, 2, 2, 169, 606, 3, 2, 2, 2, 171, 610, 3, 2, 2, 2, 173, 613, 3, 2, 2, 2, 175, 617, 3, 2, 2, 2, 177, 620, 3, 2, 2, 2, 179, 623, 3, 2, 2, 2, 181, 627, 3, 2, 2, 2, 183, 631, 3, 2, 2, 2, 185, 635, 3, 2, 2, 2, 187, 638, 3, 2, 2, 2, 189, 642, 3, 2, 2, 2, 191, 645, 3, 2, 2, 2, 193, 649, 3, 2, 2, 2, 195, 652, 3, 2, 2, 2, 197, 655, 3, 2, 2, 2, 199, 659, 3, 2, 2, 2, 201, 663, 3, 2, 2, 2, 203, 667, 3, 2, 2, 2, 205, 670, 3, 2, 2, 2, 207, 673, 3, 2, 2, 2, 209, 676, 3, 2, 2, 2, 211, 680, 3, 2, 2, 2, 213, 684, 3, 2, 2, 2, 215, 688, 3, 2, 2, 2, 217, 692, 3, 2, 2, 2, 219, 696, 3, 2, 2, 2, 221, 704, 3, 2, 2, 2, 223, 707, 3, 2, 2, 2, 225, 713, 3, 2, 2, 2, 227, 719, 3, 2, 2, 2, 229, 724, 3, 2, 2, 2, 231, 727, 3, 2, 2, 2, 233, 730, 3, 2, 2, 2, 235, 733, 3, 2, 2, 2, 237, 735, 3, 2, 2, 2, 239, 737, 3, 2, 2, 2, 241, 739, 3, 2, 2, 2, 243, 741, 3, 2, 2, 2, 245, 743, 3, 2, 2, 2, 247, 745, 3, 2, 2, 2, 249, 747, 3, 2, 2, 2, 251, 749, 3, 2, 2, 2, 253, 751, 3, 2, 2, 2, 255, 755, 3, 2, 2, 2, 257, 758, 3, 2, 2, 2, 259, 760, 3, 2, 2, 2, 261, 762, 3, 2, 2, 2, 263, 764, 3, 2, 2, 2, 265, 766, 3, 2, 2, 2, 267, 768, 3, 2, 2, 2, 269, 770, 3, 2, 2, 2, 271, 772, 3, 2, 2, 2, 273, 774, 3, 2, 2, 2, 275, 778, 3, 2, 2, 2, 277, 782, 3, 2, 2, 2, 279, 786, 3, 2, 2, 2, 281, 790, 3, 2, 2, 2, 283, 794, 3, 2, 2, 2, 285, 797, 3, 2, 2, 2, 287, 802, 3, 2, 2, 2, 289, 813, 3, 2, 2, 2, 291, 827, 3, 2, 2, 2, 293, 837, 3, 2, 2, 2, 295, 847, 3, 2, 2, 2, 297, 853, 3, 2, 2, 2, 299, 861, 3, 2, 2, 2, 301, 869, 3, 2, 2, 2, 303, 876, 3, 2, 2, 2, 305, 885, 3, 2, 2, 2, 307, 308, 9, 2, 2, 2, 308, 309, 3, 2, 2, 2, 309, 310, 8, 2, 2, 2, 310, 4, 3, 2, 2, 2, 311, 312, 7, 49, 2, 2, 312, 317, 7, 49, 2, 2, 313, 314, 7, 47, 2, 2, 314, 317, 7, 47, 2, 2, 315, 317, 9, 3, 2, 2, 316, 311, 3, 2, 2, 2, 316, 313, 3, 2, 2, 2, 316, 315, 3, 2, 2, 2, 317, 321, 3, 2, 2, 2, 318, 320, 10, 4, 2, 2, 319, 318, 3, 2, 2, 2, 320, 323, 3, 2, 2, 2, 321, 319, 3, 2, 2, 2, 321, 322, 3, 2, 2, 2, 322, 6, 3, 2, 2, 2, 323, 321, 3, 2, 2, 2, 324, 326, 7, 15, 2, 2, 325, 324, 3, 2, 2, 2, 325, 326, 3, 2, 2, 2, 326, 327, 3, 2, 2, 2, 327, 328, 7, 12, 2, 2, 328, 8, 3, 2, 2, 2, 329, 330, 9, 5, 2, 2, 330, 10, 3, 2, 2, 2, 331, 332, 9, 6, 2, 2, 332, 12, 3, 2, 2, 2, 333, 334, 9, 7, 2, 2, 334, 14, 3, 2, 2, 2, 335, 336, 9, 8, 2, 2, 336, 16, 3, 2, 2, 2, 337, 338, 9, 9, 2, 2, 338, 18, 3, 2, 2, 2, 339, 340, 9, 10, 2, 2, 340, 20, 3, 2, 2, 2, 341, 342, 9, 11, 2, 2, 342, 22, 3, 2, 2, 2, 343, 344, 9, 12, 2, 2, 344, 24, 3, 2, 2, 2, 345, 346, 9, 13, 2, 2, 346, 26, 3, 2, 2, 2, 347, 348, 9, 14, 2, 2, 348, 28, 3, 2, 2, 2, 349, 350, 9, 15, 2, 2, 350, 30, 3, 2, 2, 2, 351, 352, 9, 16, 2, 2, 352, 32, 3, 2, 2, 2, 353, 354, 9, 17, 2, 2, 354, 34, 3, 2, 2, 2, 355, 356, 9, 18, 2, 2, 356, 36, 3, 2, 2, 2, 357, 358, 9, 19, 2, 2, 358, 38, 3, 2, 2, 2, 359, 360, 9, 20, 2, 2, 360, 40, 3, 2, 2, 2, 361, 362, 9, 21, 2, 2, 362, 42, 3, 2, 2, 2, 363, 364, 9, 22, 2, 2, 364, 44, 3, 2, 2, 2, 365, 366, 9, 23, 2, 2, 366, 46, 3, 2, 2, 2, 367, 368, 9, 24, 2, 2, 368, 48, 3, 2, 2, 2, 369, 370, 9, 25, 2, 2, 370, 50, 3, 2, 2, 2, 371, 372, 9, 26, 2, 2, 372, 52, 3, 2, 2, 2, 373, 374, 9, 27, 2, 2, 374, 54, 3, 2, 2, 2, 375, 376, 9, 28, 2, 2, 376, 56, 3, 2, 2, 2, 377, 378, 5, 43, 22, 2, 378, 379, 5, 45, 23, 2, 379, 380, 5, 13, 7, 2, 380, 58, 3, 2, 2, 2, 381, 382, 5, 13, 7, 2, 382, 383, 5, 31, 16, 2, 383, 384, 5, 13, 7, 2, 384, 60, 3, 2, 2, 2, 385, 386, 5, 25, 13, 2, 386, 387, 5, 33, 17, 2, 387, 388, 5, 41, 21, 2, 388, 62, 3, 2, 2, 2, 389, 390, 5, 15, 8, 2, 390, 391, 5, 13, 7, 2, 391, 392, 5, 41, 21, 2, 392, 64, 3, 2, 2, 2, 393, 394, 5, 13, 7, 2, 394, 395, 5, 31, 16, 2, 395, 396, 5, 9, 5, 2, 396, 66, 3, 2, 2, 2, 397, 398, 5, 15, 8, 2, 398, 399, 5, 9, 5, 2, 399, 400, 5, 9, 5, 2, 400, 68, 3, 2, 2, 2, 401, 402, 5, 33, 17, 2, 402, 403, 5, 35, 18, 2, 403, 404, 5, 37, 19, 2, 404, 70, 3, 2, 2, 2, 405, 406, 5, 31, 16, 2, 406, 407, 5, 35, 18, 2, 407, 408, 5, 49, 25, 2, 408, 72, 3, 2, 2, 2, 409, 410, 5, 43, 22, 2, 410, 411, 5, 45, 23, 2, 411, 412, 5, 9, 5, 2, 412, 413, 5, 53, 27, 2, 413, 74, 3, 2, 2, 2, 414, 415, 5, 29, 15, 2, 415, 416, 5, 15, 8, 2, 416, 417, 5, 9, 5, 2, 417, 418, 5, 53, 27, 2, 418, 76, 3, 2, 2, 2, 419, 420, 5, 9, 5, 2, 420, 421, 5, 15, 8, 2, 421, 422, 5, 15, 8, 2, 422, 78, 3, 2, 2, 2, 423, 424, 5, 9, 5, 2, 424, 425, 5, 15, 8, 2, 425, 426, 5, 13, 7, 2, 426, 80, 3, 2, 2, 2, 427, 428, 5, 43, 22, 2, 428, 429, 5, 47, 24, 2, 429, 430, 5, 11, 6, 2, 430, 82, 3, 2, 2, 2, 431, 432, 5, 43, 22, 2, 432, 433, 5, 11, 6, 2, 433, 434, 5, 11, 6, 2, 434, 84, 3, 2, 2, 2, 435, 436, 5, 9, 5, 2, 436, 437, 5, 33, 17, 2, 437, 438, 5, 9, 5, 2, 438, 86, 3, 2, 2, 2, 439, 440, 5, 53, 27, 2, 440, 441, 5, 41, 21, 2, 441, 442, 5, 9, 5, 2, 442, 88, 3, 2, 2, 2, 443, 444, 5, 35, 18, 2, 444, 445, 5, 41, 21, 2, 445, 446, 5, 9, 5, 2, 446, 90, 3, 2, 2, 2, 447, 448, 5, 13, 7, 2, 448, 449, 5, 31, 16, 2, 449, 450, 5, 37, 19, 2, 450, 92, 3, 2, 2, 2, 451, 452, 5, 41, 21, 2, 452, 453, 5, 29, 15, 2, 453, 454, 5, 13, 7, 2, 454, 94, 3, 2, 2, 2, 455, 456, 5, 41, 21, 2, 456, 457, 5, 41, 21, 2, 457, 458, 5, 13, 7, 2, 458, 96, 3, 2, 2, 2, 459, 460, 5, 41, 21, 2, 460, 461, 5, 9, 5, 2, 461, 462, 5, 29, 15, 2, 462, 98, 3, 2, 2, 2, 463, 464, 5, 41, 21, 2, 464, 465, 5, 9, 5, 2, 465, 466, 5, 41, 21, 2, 466, 100, 3, 2, 2, 2, 467, 468, 5, 37, 19, 2, 468, 469, 5, 47, 24, 2, 469, 470, 5, 43, 22, 2, 470, 471, 5, 23, 12, 2, 471, 102, 3, 2, 2, 2, 472, 473, 5, 37, 19, 2, 473, 474, 5, 35, 18, 2, 474, 475, 5, 37, 19, 2, 475, 104, 3, 2, 2, 2, 476, 477, 5, 15, 8, 2, 477, 478, 5, 9, 5, 2, 478, 479, 5, 15, 8, 2, 479, 106, 3, 2, 2, 2, 480, 481, 5, 25, 13, 2, 481, 482, 5, 33, 17, 2, 482, 483, 5, 53, 27, 2, 483, 108, 3, 2, 2, 2, 484, 485, 5, 15, 8, 2, 485, 486, 5, 13, 7, 2, 486, 487, 5, 53, 27, 2, 487, 110, 3, 2, 2, 2, 488, 489, 5, 53, 27, 2, 489, 490, 5, 13, 7, 2, 490, 491, 5, 23, 12, 2, 491, 492, 5, 21, 11, 2, 492, 112, 3, 2, 2, 2, 493, 494, 5, 53, 27, 2, 494, 495, 5, 45, 23, 2, 495, 496, 5, 23, 12, 2, 496, 497, 5, 29, 15, 2, 497, 114, 3, 2, 2, 2, 498, 499, 5, 43, 22, 2, 499, 500, 5, 37, 19, 2, 500, 501, 5, 23, 12, 2, 501, 502, 5, 29, 15, 2, 502, 116, 3, 2, 2, 2, 503, 504, 5, 29, 15, 2, 504, 505, 5, 53, 27, 2, 505, 506, 5, 25, 13, 2, 506, 118, 3, 2, 2, 2, 507, 508, 5, 31, 16, 2, 508, 509, 5, 49, 25, 2, 509, 510, 5, 25, 13, 2, 510, 120, 3, 2, 2, 2, 511, 512, 5, 9, 5, 2, 512, 513, 5, 15, 8, 2, 513, 514, 5, 25, 13, 2, 514, 122, 3, 2, 2, 2, 515, 516, 5, 9, 5, 2, 516, 517, 5, 13, 7, 2, 517, 518, 5, 25, 13, 2, 518, 124, 3, 2, 2, 2, 519, 520, 5, 43, 22, 2, 520, 521, 5, 47, 24, 2, 521, 522, 5, 25, 13, 2, 522, 126, 3, 2, 2, 2, 523, 524, 5, 43, 22, 2, 524, 525, 5, 11, 6, 2, 525, 526, 5, 25, 13, 2, 526, 128, 3, 2, 2, 2, 527, 528, 5, 9, 5, 2, 528, 529, 5, 33, 17, 2, 529, 530, 5, 25, 13, 2, 530, 130, 3, 2, 2, 2, 531, 532, 5, 53, 27, 2, 532, 533, 5, 41, 21, 2, 533, 534, 5, 25, 13, 2, 534, 132, 3, 2, 2, 2, 535, 536, 5, 35, 18, 2, 536, 537, 5, 41, 21, 2, 537, 538, 5, 25, 13, 2, 538, 134, 3, 2, 2, 2, 539, 540, 5, 13, 7, 2, 540, 541, 5, 37, 19, 2, 541, 542, 5, 25, 13, 2, 542, 136, 3, 2, 2, 2, 543, 544, 5, 43, 22, 2, 544, 545, 5, 45, 23, 2, 545, 546, 5, 9, 5, 2, 546, 138, 3, 2, 2, 2, 547, 548, 5, 29, 15, 2, 548, 549, 5, 15, 8, 2, 549, 550, 5, 9, 5, 2, 550, 140, 3, 2, 2, 2, 551, 552, 5, 43, 22, 2, 552, 553, 5, 23, 12, 2, 553, 554, 5, 29, 15, 2, 554, 555, 5, 15, 8, 2, 555, 142, 3, 2, 2, 2, 556, 557, 5, 29, 15, 2, 557, 558, 5, 23, 12, 2, 558, 559, 5, 29, 15, 2, 559, 560, 5, 15, 8, 2, 560, 144, 3, 2, 2, 2, 561, 562, 5, 37, 19, 2, 562, 563, 5, 13, 7, 2, 563, 564, 5, 23, 12, 2, 564, 565, 5, 29, 15, 2, 565, 146, 3, 2, 2, 2, 566, 567, 5, 27, 14, 2, 567, 568, 5, 31, 16, 2, 568, 569, 5, 37, 19, 2, 569, 148, 3, 2, 2, 2, 570, 571, 5, 27, 14, 2, 571, 572, 5, 13, 7, 2, 572, 150, 3, 2, 2, 2, 573, 574, 5, 27, 14, 2, 574, 575, 5, 33, 17, 2, 575, 576, 5, 13, 7, 2, 576, 152, 3, 2, 2, 2, 577, 578, 5, 27, 14, 2, 578, 579, 5, 55, 28, 2, 579, 154, 3, 2, 2, 2, 580, 581, 5, 27, 14, 2, 581, 582, 5, 33, 17, 2, 582, 583, 5, 55, 28, 2, 583, 156, 3, 2, 2, 2, 584, 585, 5, 27, 14, 2, 585, 586, 5, 37, 19, 2, 586, 158, 3, 2, 2, 2, 587, 588, 5, 27, 14, 2, 588, 589, 5, 31, 16, 2, 589, 160, 3, 2, 2, 2, 590, 591, 5, 27, 14, 2, 591, 592, 5, 37, 19, 2, 592, 593, 5, 17, 9, 2, 593, 162, 3, 2, 2, 2, 594, 595, 5, 27, 14, 2, 595, 596, 5, 37, 19, 2, 596, 597, 5, 35, 18, 2, 597, 164, 3, 2, 2, 2, 598, 599, 5, 13, 7, 2, 599, 600, 5, 9, 5, 2, 600, 601, 5, 29, 15, 2, 601, 602, 5, 29, 15, 2, 602, 166, 3, 2, 2, 2, 603, 604, 5, 13, 7, 2, 604, 605, 5, 13, 7, 2, 605, 168, 3, 2, 2, 2, 606, 607, 5, 13, 7, 2, 607, 608, 5, 33, 17, 2, 608, 609, 5, 13, 7, 2, 609, 170, 3, 2, 2, 2, 610, 611, 5, 13, 7, 2, 611, 612, 5, 55, 28, 2, 612, 172, 3, 2, 2, 2, 613, 614, 5, 13, 7, 2, 614, 615, 5, 33, 17, 2, 615, 616, 5, 55, 28, 2, 616, 174, 3, 2, 2, 2, 617, 618, 5, 13, 7, 2, 618, 619, 5, 37, 19, 2, 619, 176, 3, 2, 2, 2, 620, 621, 5, 13, 7, 2, 621, 622, 5, 31, 16, 2, 622, 178, 3, 2, 2, 2, 623, 624, 5, 13, 7, 2, 624, 625, 5, 37, 19, 2, 625, 626, 5, 17, 9, 2, 626, 180, 3, 2, 2, 2, 627, 628, 5, 13, 7, 2, 628, 629, 5, 37, 19, 2, 629, 630, 5, 35, 18, 2, 630, 182, 3, 2, 2, 2, 631, 632, 5, 41, 21, 2, 632, 633, 5, 17, 9, 2, 633, 634, 5, 45, 23, 2, 634, 184, 3, 2, 2, 2, 635, 636, 5, 41, 21, 2, 636, 637, 5, 13, 7, 2, 637, 186, 3, 2, 2, 2, 638, 639, 5, 41, 21, 2, 639, 640, 5, 33, 17, 2, 640, 641, 5, 13, 7, 2, 641, 188, 3, 2, 2, 2, 642, 643, 5, 41, 21, 2, 643, 644, 5, 55, 28, 2, 644, 190, 3, 2, 2, 2, 645, 646, 5, 41, 21, 2, 646, 647, 5, 33, 17, 2, 647, 648, 5, 55, 28, 2, 648, 192, 3, 2, 2, 2, 649, 650, 5, 41, 21, 2, 650, 651, 5, 31, 16, 2, 651, 194, 3, 2, 2, 2, 652, 653, 5, 41, 21, 2, 653, 654, 5, 37, 19, 2, 654, 196, 3, 2, 2, 2, 655, 656, 5, 41, 21, 2, 656, 657, 5, 37, 19, 2, 657, 658, 5, 17, 9, 2, 658, 198, 3, 2, 2, 2, 659, 660, 5, 41, 21, 2, 660, 661, 5, 37, 19, 2, 661, 662, 5, 35, 18, 2, 662, 200, 3, 2, 2, 2, 663, 664, 5, 41, 21, 2, 664, 665, 5, 43, 22, 2, 665, 666, 5, 45, 23, 2, 666, 202, 3, 2, 2, 2, 667, 668, 5, 17, 9, 2, 668, 669, 5, 25, 13, 2, 669, 204, 3, 2, 2, 2, 670, 671, 5, 15, 8, 2, 671, 672, 5, 25, 13, 2, 672, 206, 3, 2, 2, 2, 673, 674, 5, 25, 13, 2, 674, 675, 5, 33, 17, 2, 675, 208, 3, 2, 2, 2, 676, 677, 5, 35, 18, 2, 677, 678, 5, 47, 24, 2, 678, 679, 5, 45, 23, 2, 679, 210, 3, 2, 2, 2, 680, 681, 5, 23, 12, 2, 681, 682, 5, 29, 15, 2, 682, 683, 5, 45, 23, 2, 683, 212, 3, 2, 2, 2, 684, 685, 5, 35, 18, 2, 685, 686, 5, 41, 21, 2, 686, 687, 5, 21, 11, 2, 687, 214, 3, 2, 2, 2, 688, 689, 5, 17, 9, 2, 689, 690, 5, 39, 20, 2, 690, 691, 5, 47, 24, 2, 691, 216, 3, 2, 2, 2, 692, 693, 5, 43, 22, 2, 693, 694, 5, 17, 9, 2, 694, 695, 5, 45, 23, 2, 695, 218, 3, 2, 2, 2, 696, 697, 5, 25, 13, 2, 697, 698, 5, 33, 17, 2, 698, 699, 5, 13, 7, 2, 699, 700, 5, 29, 15, 2, 700, 701, 5, 47, 24, 2, 701, 702, 5, 15, 8, 2, 702, 703, 5, 17, 9, 2, 703, 220, 3, 2, 2, 2, 704, 705, 5, 25, 13, 2, 705, 706, 5, 19, 10, 2, 706, 222, 3, 2, 2, 2, 707, 708, 5, 17, 9, 2, 708, 709, 5, 33, 17, 2, 709, 710, 5, 15, 8, 2, 710, 711, 5, 25, 13, 2, 711, 712, 5, 19, 10, 2, 712, 224, 3, 2, 2, 2, 713, 714, 5, 31, 16, 2, 714, 715, 5, 9, 5, 2, 715, 716, 5, 13, 7, 2, 716, 717, 5, 41, 21, 2, 717, 718, 5, 35, 18, 2, 718, 226, 3, 2, 2, 2, 719, 720, 5, 17, 9, 2, 720, 721, 5, 33, 17, 2, 721, 722, 5, 15, 8, 2, 722, 723, 5, 31, 16, 2, 723, 228, 3, 2, 2, 2, 724, 725, 5, 15, 8, 2, 725, 726, 5, 11, 6, 2, 726, 230, 3, 2, 2, 2, 727, 728, 5, 15, 8, 2, 728, 729, 5, 51, 26, 2, 729, 232, 3, 2, 2, 2, 730, 731, 5, 15, 8, 2, 731, 732, 5, 43, 22, 2, 732, 234, 3, 2, 2, 2, 733, 734, 7, 38, 2, 2, 734, 236, 3, 2, 2, 2, 735, 736, 5, 9, 5, 2, 736, 238, 3, 2, 2, 2, 737, 738, 5, 11, 6, 2, 738, 240, 3, 2, 2, 2, 739, 740, 5, 13, 7, 2, 740, 242, 3, 2, 2, 2, 741, 742, 5, 15, 8, 2, 742, 244, 3, 2, 2, 2, 743, 744, 5, 17, 9, 2, 744, 246, 3, 2, 2, 2, 745, 746, 5, 23, 12, 2, 746, 248, 3, 2, 2, 2, 747, 748, 5, 29, 15, 2, 748, 250, 3, 2, 2, 2, 749, 750, 5, 31, 16, 2, 750, 252, 3, 2, 2, 2, 751, 752, 5, 37, 19, 2, 752, 753, 5, 43, 22, 2, 753, 754, 5, 51, 26, 2, 754, 254, 3, 2, 2, 2, 755, 756, 5, 43, 22, 2, 756, 757, 5, 37, 19, 2, 757, 256, 3, 2, 2, 2, 758, 759, 7, 42, 2, 2, 759, 258, 3, 2, 2, 2, 760, 761, 7, 43, 2, 2, 761, 260, 3, 2, 2, 2, 762, 763, 7, 46, 2, 2, 763, 262, 3, 2, 2, 2, 764, 765, 7, 45, 2, 2, 765, 264, 3, 2, 2, 2, 766, 767, 7, 47, 2, 2, 767, 266, 3, 2, 2, 2, 768, 769, 7, 44, 2, 2, 769, 268, 3, 2, 2, 2, 770, 771, 7, 49, 2, 2, 771, 270, 3, 2, 2, 2, 772, 773, 7, 63, 2, 2, 773, 272, 3, 2, 2, 2, 774, 775, 5, 31, 16, 2, 775, 776, 5, 35, 18, 2, 776, 777, 5, 15, 8, 2, 777, 274, 3, 2, 2, 2, 778, 779, 5, 43, 22, 2, 779, 780, 5, 23, 12, 2, 780, 781, 5, 41, 21, 2, 781, 276, 3, 2, 2, 2, 782, 783, 5, 43, 22, 2, 783, 784, 5, 23, 12, 2, 784, 785, 5, 29, 15, 2, 785, 278, 3, 2, 2, 2, 786, 787, 5, 33, 17, 2, 787, 788, 5, 35, 18, 2, 788, 789, 5, 45, 23, 2, 789, 280, 3, 2, 2, 2, 790, 791, 5, 9, 5, 2, 791, 792, 5, 33, 17, 2, 792, 793, 5, 15, 8, 2, 793, 282, 3, 2, 2, 2, 794, 795, 5, 35, 18, 2, 795, 796, 5, 41, 21, 2, 796, 284, 3, 2, 2, 2, 797, 798, 5, 53, 27, 2, 798, 799, 5, 35, 18, 2, 799, 800, 5, 41, 21, 2, 800, 286, 3, 2, 2, 2, 801, 803, 9, 29, 2, 2, 802, 801, 3, 2, 2, 2, 802, 803, 3, 2, 2, 2, 803, 805, 3, 2, 2, 2, 804, 806, 9, 30, 2, 2, 805, 804, 3, 2, 2, 2, 806, 807, 3, 2, 2, 2, 807, 805, 3, 2, 2, 2, 807, 808, 3, 2, 2, 2, 808, 810, 3, 2, 2, 2, 809, 811, 5, 15, 8, 2, 810, 809, 3, 2, 2, 2, 810, 811, 3, 2, 2, 2, 811, 288, 3, 2, 2, 2, 812, 814, 9, 29, 2, 2, 813, 812, 3, 2, 2, 2, 813, 814, 3, 2, 2, 2, 814, 819, 3, 2, 2, 2, 815, 816, 7, 50, 2, 2, 816, 820, 7, 122, 2, 2, 817, 818, 7, 50, 2, 2, 818, 820, 7, 90, 2, 2, 819, 815, 3, 2, 2, 2, 819, 817, 3, 2, 2, 2, 820, 822, 3, 2, 2, 2, 821, 823, 9, 31, 2, 2, 822, 821, 3, 2, 2, 2, 823, 824, 3, 2, 2, 2, 824, 822, 3, 2, 2, 2, 824, 825, 3, 2, 2, 2, 825, 290, 3, 2, 2, 2, 826, 828, 9, 29, 2, 2, 827, 826, 3, 2, 2, 2, 827, 828, 3, 2, 2, 2, 828, 830, 3, 2, 2, 2, 829, 831, 9, 31, 2, 2, 830, 829, 3, 2, 2, 2, 831, 832, 3, 2, 2, 2, 832, 830, 3, 2, 2, 2, 832, 833, 3, 2, 2, 2, 833, 834, 3, 2, 2, 2, 834, 835, 5, 23, 12, 2, 835, 292, 3, 2, 2, 2, 836, 838, 9, 29, 2, 2, 837, 836, 3, 2, 2, 2, 837, 838, 3, 2, 2, 2, 838, 840, 3, 2, 2, 2, 839, 841, 9, 32, 2, 2, 840, 839, 3, 2, 2, 2, 841, 842, 3, 2, 2, 2, 842, 840, 3, 2, 2, 2, 842, 843, 3, 2, 2, 2, 843, 844, 3, 2, 2, 2, 844, 845, 9, 33, 2, 2, 845, 294, 3, 2, 2, 2, 846, 848, 9, 34, 2, 2, 847, 846, 3, 2, 2, 2, 848, 849, 3, 2, 2, 2, 849, 847, 3, 2, 2, 2, 849, 850, 3, 2, 2, 2, 850, 851, 3, 2, 2, 2, 851, 852, 5, 11, 6, 2, 852, 296, 3, 2, 2, 2, 853, 855, 9, 35, 2, 2, 854, 856, 9, 36, 2, 2, 855, 854, 3, 2, 2, 2, 856, 857, 3, 2, 2, 2, 857, 855, 3, 2, 2, 2, 857, 858, 3, 2, 2, 2, 858, 859, 3, 2, 2, 2, 859, 860, 9, 35, 2, 2, 860, 298, 3, 2, 2, 2, 861, 863, 7, 36, 2, 2, 862, 864, 9, 37, 2, 2, 863, 862, 3, 2, 2, 2, 864, 865, 3, 2, 2, 2, 865, 863, 3, 2, 2, 2, 865, 866, 3, 2, 2, 2, 866, 867, 3, 2, 2, 2, 867, 868, 7, 36, 2, 2, 868, 300, 3, 2, 2, 2, 869, 873, 9, 38, 2, 2, 870, 872, 9, 39, 2, 2, 871, 870, 3, 2, 2, 2, 872, 875, 3, 2, 2, 2, 873, 871, 3, 2, 2, 2, 873, 874, 3, 2, 2, 2, 874, 302, 3, 2, 2, 2, 875, 873, 3, 2, 2, 2, 876, 880, 9, 38, 2, 2, 877, 879, 9, 39, 2, 2, 878, 877, 3, 2, 2, 2, 879, 882, 3, 2, 2, 2, 880, 878, 3, 2, 2, 2, 880, 881, 3, 2, 2, 2, 881, 883, 3, 2, 2, 2, 882, 880, 3, 2, 2, 2, 883, 884, 7, 60, 2, 2, 884, 304, 3, 2, 2, 2, 885, 886, 11, 2, 2, 2, 886, 306, 3, 2, 2, 2, 21, 2, 316, 321, 325, 802, 807, 810, 813, 819, 824, 827, 832, 837, 842, 849, 857, 865, 873, 880, 3, 2, 3, 2] \ No newline at end of file diff --git a/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.java b/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.java deleted file mode 100644 index 4dc054c3f..000000000 --- a/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.java +++ /dev/null @@ -1,506 +0,0 @@ -// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 by ANTLR 4.9.1 -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class As8080Lexer extends Lexer { - static { RuntimeMetaData.checkVersion("4.9.1", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - WS=1, COMMENT=2, EOL=3, OPCODE_STC=4, OPCODE_CMC=5, OPCODE_INR=6, OPCODE_DCR=7, - OPCODE_CMA=8, OPCODE_DAA=9, OPCODE_NOP=10, OPCODE_MOV=11, OPCODE_STAX=12, - OPCODE_LDAX=13, OPCODE_ADD=14, OPCODE_ADC=15, OPCODE_SUB=16, OPCODE_SBB=17, - OPCODE_ANA=18, OPCODE_XRA=19, OPCODE_ORA=20, OPCODE_CMP=21, OPCODE_RLC=22, - OPCODE_RRC=23, OPCODE_RAL=24, OPCODE_RAR=25, OPCODE_PUSH=26, OPCODE_POP=27, - OPCODE_DAD=28, OPCODE_INX=29, OPCODE_DCX=30, OPCODE_XCHG=31, OPCODE_XTHL=32, - OPCODE_SPHL=33, OPCODE_LXI=34, OPCODE_MVI=35, OPCODE_ADI=36, OPCODE_ACI=37, - OPCODE_SUI=38, OPCODE_SBI=39, OPCODE_ANI=40, OPCODE_XRI=41, OPCODE_ORI=42, - OPCODE_CPI=43, OPCODE_STA=44, OPCODE_LDA=45, OPCODE_SHLD=46, OPCODE_LHLD=47, - OPCODE_PCHL=48, OPCODE_JMP=49, OPCODE_JC=50, OPCODE_JNC=51, OPCODE_JZ=52, - OPCODE_JNZ=53, OPCODE_JP=54, OPCODE_JM=55, OPCODE_JPE=56, OPCODE_JPO=57, - OPCODE_CALL=58, OPCODE_CC=59, OPCODE_CNC=60, OPCODE_CZ=61, OPCODE_CNZ=62, - OPCODE_CP=63, OPCODE_CM=64, OPCODE_CPE=65, OPCODE_CPO=66, OPCODE_RET=67, - OPCODE_RC=68, OPCODE_RNC=69, OPCODE_RZ=70, OPCODE_RNZ=71, OPCODE_RM=72, - OPCODE_RP=73, OPCODE_RPE=74, OPCODE_RPO=75, OPCODE_RST=76, OPCODE_EI=77, - OPCODE_DI=78, OPCODE_IN=79, OPCODE_OUT=80, OPCODE_HLT=81, PREP_ORG=82, - PREP_EQU=83, PREP_SET=84, PREP_INCLUDE=85, PREP_IF=86, PREP_ENDIF=87, - PREP_MACRO=88, PREP_ENDM=89, PREP_DB=90, PREP_DW=91, PREP_DS=92, PREP_ADDR=93, - REG_A=94, REG_B=95, REG_C=96, REG_D=97, REG_E=98, REG_H=99, REG_L=100, - REG_M=101, REG_PSW=102, REG_SP=103, SEP_LPAR=104, SEP_RPAR=105, SEP_COMMA=106, - OP_ADD=107, OP_SUBTRACT=108, OP_MULTIPLY=109, OP_DIVIDE=110, OP_EQUAL=111, - OP_MOD=112, OP_SHR=113, OP_SHL=114, OP_NOT=115, OP_AND=116, OP_OR=117, - OP_XOR=118, LIT_NUMBER=119, LIT_HEXNUMBER_1=120, LIT_HEXNUMBER_2=121, - LIT_OCTNUMBER=122, LIT_BINNUMBER=123, LIT_STRING_1=124, LIT_STRING_2=125, - ID_IDENTIFIER=126, ID_LABEL=127, ERROR=128; - public static String[] channelNames = { - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }; - - public static String[] modeNames = { - "DEFAULT_MODE" - }; - - private static String[] makeRuleNames() { - return new String[] { - "WS", "COMMENT", "EOL", "A", "B", "C", "D", "E", "F", "G", "H", "I", - "J", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", - "Z", "OPCODE_STC", "OPCODE_CMC", "OPCODE_INR", "OPCODE_DCR", "OPCODE_CMA", - "OPCODE_DAA", "OPCODE_NOP", "OPCODE_MOV", "OPCODE_STAX", "OPCODE_LDAX", - "OPCODE_ADD", "OPCODE_ADC", "OPCODE_SUB", "OPCODE_SBB", "OPCODE_ANA", - "OPCODE_XRA", "OPCODE_ORA", "OPCODE_CMP", "OPCODE_RLC", "OPCODE_RRC", - "OPCODE_RAL", "OPCODE_RAR", "OPCODE_PUSH", "OPCODE_POP", "OPCODE_DAD", - "OPCODE_INX", "OPCODE_DCX", "OPCODE_XCHG", "OPCODE_XTHL", "OPCODE_SPHL", - "OPCODE_LXI", "OPCODE_MVI", "OPCODE_ADI", "OPCODE_ACI", "OPCODE_SUI", - "OPCODE_SBI", "OPCODE_ANI", "OPCODE_XRI", "OPCODE_ORI", "OPCODE_CPI", - "OPCODE_STA", "OPCODE_LDA", "OPCODE_SHLD", "OPCODE_LHLD", "OPCODE_PCHL", - "OPCODE_JMP", "OPCODE_JC", "OPCODE_JNC", "OPCODE_JZ", "OPCODE_JNZ", "OPCODE_JP", - "OPCODE_JM", "OPCODE_JPE", "OPCODE_JPO", "OPCODE_CALL", "OPCODE_CC", - "OPCODE_CNC", "OPCODE_CZ", "OPCODE_CNZ", "OPCODE_CP", "OPCODE_CM", "OPCODE_CPE", - "OPCODE_CPO", "OPCODE_RET", "OPCODE_RC", "OPCODE_RNC", "OPCODE_RZ", "OPCODE_RNZ", - "OPCODE_RM", "OPCODE_RP", "OPCODE_RPE", "OPCODE_RPO", "OPCODE_RST", "OPCODE_EI", - "OPCODE_DI", "OPCODE_IN", "OPCODE_OUT", "OPCODE_HLT", "PREP_ORG", "PREP_EQU", - "PREP_SET", "PREP_INCLUDE", "PREP_IF", "PREP_ENDIF", "PREP_MACRO", "PREP_ENDM", - "PREP_DB", "PREP_DW", "PREP_DS", "PREP_ADDR", "REG_A", "REG_B", "REG_C", - "REG_D", "REG_E", "REG_H", "REG_L", "REG_M", "REG_PSW", "REG_SP", "SEP_LPAR", - "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE", - "OP_EQUAL", "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", - "OP_XOR", "LIT_NUMBER", "LIT_HEXNUMBER_1", "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", - "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", - "ERROR" - }; - } - public static final String[] ruleNames = makeRuleNames(); - - private static String[] makeLiteralNames() { - return new String[] { - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, "'$'", null, null, - null, null, null, null, null, null, null, null, "'('", "')'", "','", - "'+'", "'-'", "'*'", "'/'", "'='" - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - null, "WS", "COMMENT", "EOL", "OPCODE_STC", "OPCODE_CMC", "OPCODE_INR", - "OPCODE_DCR", "OPCODE_CMA", "OPCODE_DAA", "OPCODE_NOP", "OPCODE_MOV", - "OPCODE_STAX", "OPCODE_LDAX", "OPCODE_ADD", "OPCODE_ADC", "OPCODE_SUB", - "OPCODE_SBB", "OPCODE_ANA", "OPCODE_XRA", "OPCODE_ORA", "OPCODE_CMP", - "OPCODE_RLC", "OPCODE_RRC", "OPCODE_RAL", "OPCODE_RAR", "OPCODE_PUSH", - "OPCODE_POP", "OPCODE_DAD", "OPCODE_INX", "OPCODE_DCX", "OPCODE_XCHG", - "OPCODE_XTHL", "OPCODE_SPHL", "OPCODE_LXI", "OPCODE_MVI", "OPCODE_ADI", - "OPCODE_ACI", "OPCODE_SUI", "OPCODE_SBI", "OPCODE_ANI", "OPCODE_XRI", - "OPCODE_ORI", "OPCODE_CPI", "OPCODE_STA", "OPCODE_LDA", "OPCODE_SHLD", - "OPCODE_LHLD", "OPCODE_PCHL", "OPCODE_JMP", "OPCODE_JC", "OPCODE_JNC", - "OPCODE_JZ", "OPCODE_JNZ", "OPCODE_JP", "OPCODE_JM", "OPCODE_JPE", "OPCODE_JPO", - "OPCODE_CALL", "OPCODE_CC", "OPCODE_CNC", "OPCODE_CZ", "OPCODE_CNZ", - "OPCODE_CP", "OPCODE_CM", "OPCODE_CPE", "OPCODE_CPO", "OPCODE_RET", "OPCODE_RC", - "OPCODE_RNC", "OPCODE_RZ", "OPCODE_RNZ", "OPCODE_RM", "OPCODE_RP", "OPCODE_RPE", - "OPCODE_RPO", "OPCODE_RST", "OPCODE_EI", "OPCODE_DI", "OPCODE_IN", "OPCODE_OUT", - "OPCODE_HLT", "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_INCLUDE", "PREP_IF", - "PREP_ENDIF", "PREP_MACRO", "PREP_ENDM", "PREP_DB", "PREP_DW", "PREP_DS", - "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", "REG_E", "REG_H", "REG_L", - "REG_M", "REG_PSW", "REG_SP", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", - "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_MOD", "OP_SHR", - "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", "OP_XOR", "LIT_NUMBER", "LIT_HEXNUMBER_1", - "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", "LIT_BINNUMBER", "LIT_STRING_1", - "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", "ERROR" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - - public As8080Lexer(CharStream input) { - super(input); - _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - @Override - public String getGrammarFileName() { return "As8080Lexer.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public String[] getChannelNames() { return channelNames; } - - @Override - public String[] getModeNames() { return modeNames; } - - @Override - public ATN getATN() { return _ATN; } - - public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u0082\u0377\b\1\4"+ - "\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n"+ - "\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ - "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+ - "\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t"+ - " \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t"+ - "+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64"+ - "\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t"+ - "=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4"+ - "I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\t"+ - "T\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_"+ - "\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k"+ - "\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv"+ - "\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080\t"+ - "\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084"+ - "\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089"+ - "\t\u0089\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c\t\u008c\4\u008d\t\u008d"+ - "\4\u008e\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090\4\u0091\t\u0091\4\u0092"+ - "\t\u0092\4\u0093\t\u0093\4\u0094\t\u0094\4\u0095\t\u0095\4\u0096\t\u0096"+ - "\4\u0097\t\u0097\4\u0098\t\u0098\4\u0099\t\u0099\3\2\3\2\3\2\3\2\3\3\3"+ - "\3\3\3\3\3\3\3\5\3\u013d\n\3\3\3\7\3\u0140\n\3\f\3\16\3\u0143\13\3\3\4"+ - "\5\4\u0146\n\4\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n"+ - "\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3\22"+ - "\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\31"+ - "\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36"+ - "\3\36\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3!\3\"\3\"\3\"\3\"\3#\3"+ - "#\3#\3#\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3(\3"+ - "(\3(\3(\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3+\3+\3,\3,\3,\3,\3-\3-\3-\3-\3"+ - ".\3.\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\61\3\61\3\61\3\61\3\62\3"+ - "\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\65\3\65\3"+ - "\65\3\65\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\38\38\38\38\38\39\39"+ - "\39\39\39\3:\3:\3:\3:\3:\3;\3;\3;\3;\3<\3<\3<\3<\3=\3=\3=\3=\3>\3>\3>"+ - "\3>\3?\3?\3?\3?\3@\3@\3@\3@\3A\3A\3A\3A\3B\3B\3B\3B\3C\3C\3C\3C\3D\3D"+ - "\3D\3D\3E\3E\3E\3E\3F\3F\3F\3F\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3I"+ - "\3I\3I\3J\3J\3J\3J\3K\3K\3K\3L\3L\3L\3L\3M\3M\3M\3N\3N\3N\3N\3O\3O\3O"+ - "\3P\3P\3P\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3S\3S\3S\3S\3S\3T\3T\3T\3U\3U\3U\3U"+ - "\3V\3V\3V\3W\3W\3W\3W\3X\3X\3X\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3\\\3"+ - "\\\3\\\3\\\3]\3]\3]\3^\3^\3^\3^\3_\3_\3_\3`\3`\3`\3`\3a\3a\3a\3b\3b\3"+ - "b\3c\3c\3c\3c\3d\3d\3d\3d\3e\3e\3e\3e\3f\3f\3f\3g\3g\3g\3h\3h\3h\3i\3"+ - "i\3i\3i\3j\3j\3j\3j\3k\3k\3k\3k\3l\3l\3l\3l\3m\3m\3m\3m\3n\3n\3n\3n\3"+ - "n\3n\3n\3n\3o\3o\3o\3p\3p\3p\3p\3p\3p\3q\3q\3q\3q\3q\3q\3r\3r\3r\3r\3"+ - "r\3s\3s\3s\3t\3t\3t\3u\3u\3u\3v\3v\3w\3w\3x\3x\3y\3y\3z\3z\3{\3{\3|\3"+ - "|\3}\3}\3~\3~\3\177\3\177\3\177\3\177\3\u0080\3\u0080\3\u0080\3\u0081"+ - "\3\u0081\3\u0082\3\u0082\3\u0083\3\u0083\3\u0084\3\u0084\3\u0085\3\u0085"+ - "\3\u0086\3\u0086\3\u0087\3\u0087\3\u0088\3\u0088\3\u0089\3\u0089\3\u0089"+ - "\3\u0089\3\u008a\3\u008a\3\u008a\3\u008a\3\u008b\3\u008b\3\u008b\3\u008b"+ - "\3\u008c\3\u008c\3\u008c\3\u008c\3\u008d\3\u008d\3\u008d\3\u008d\3\u008e"+ - "\3\u008e\3\u008e\3\u008f\3\u008f\3\u008f\3\u008f\3\u0090\5\u0090\u0323"+ - "\n\u0090\3\u0090\6\u0090\u0326\n\u0090\r\u0090\16\u0090\u0327\3\u0090"+ - "\5\u0090\u032b\n\u0090\3\u0091\5\u0091\u032e\n\u0091\3\u0091\3\u0091\3"+ - "\u0091\3\u0091\5\u0091\u0334\n\u0091\3\u0091\6\u0091\u0337\n\u0091\r\u0091"+ - "\16\u0091\u0338\3\u0092\5\u0092\u033c\n\u0092\3\u0092\6\u0092\u033f\n"+ - "\u0092\r\u0092\16\u0092\u0340\3\u0092\3\u0092\3\u0093\5\u0093\u0346\n"+ - "\u0093\3\u0093\6\u0093\u0349\n\u0093\r\u0093\16\u0093\u034a\3\u0093\3"+ - "\u0093\3\u0094\6\u0094\u0350\n\u0094\r\u0094\16\u0094\u0351\3\u0094\3"+ - "\u0094\3\u0095\3\u0095\6\u0095\u0358\n\u0095\r\u0095\16\u0095\u0359\3"+ - "\u0095\3\u0095\3\u0096\3\u0096\6\u0096\u0360\n\u0096\r\u0096\16\u0096"+ - "\u0361\3\u0096\3\u0096\3\u0097\3\u0097\7\u0097\u0368\n\u0097\f\u0097\16"+ - "\u0097\u036b\13\u0097\3\u0098\3\u0098\7\u0098\u036f\n\u0098\f\u0098\16"+ - "\u0098\u0372\13\u0098\3\u0098\3\u0098\3\u0099\3\u0099\2\2\u009a\3\3\5"+ - "\4\7\5\t\2\13\2\r\2\17\2\21\2\23\2\25\2\27\2\31\2\33\2\35\2\37\2!\2#\2"+ - "%\2\'\2)\2+\2-\2/\2\61\2\63\2\65\2\67\29\6;\7=\b?\tA\nC\13E\fG\rI\16K"+ - "\17M\20O\21Q\22S\23U\24W\25Y\26[\27]\30_\31a\32c\33e\34g\35i\36k\37m "+ - "o!q\"s#u$w%y&{\'}(\177)\u0081*\u0083+\u0085,\u0087-\u0089.\u008b/\u008d"+ - "\60\u008f\61\u0091\62\u0093\63\u0095\64\u0097\65\u0099\66\u009b\67\u009d"+ - "8\u009f9\u00a1:\u00a3;\u00a5<\u00a7=\u00a9>\u00ab?\u00ad@\u00afA\u00b1"+ - "B\u00b3C\u00b5D\u00b7E\u00b9F\u00bbG\u00bdH\u00bfI\u00c1J\u00c3K\u00c5"+ - "L\u00c7M\u00c9N\u00cbO\u00cdP\u00cfQ\u00d1R\u00d3S\u00d5T\u00d7U\u00d9"+ - "V\u00dbW\u00ddX\u00dfY\u00e1Z\u00e3[\u00e5\\\u00e7]\u00e9^\u00eb_\u00ed"+ - "`\u00efa\u00f1b\u00f3c\u00f5d\u00f7e\u00f9f\u00fbg\u00fdh\u00ffi\u0101"+ - "j\u0103k\u0105l\u0107m\u0109n\u010bo\u010dp\u010fq\u0111r\u0113s\u0115"+ - "t\u0117u\u0119v\u011bw\u011dx\u011fy\u0121z\u0123{\u0125|\u0127}\u0129"+ - "~\u012b\177\u012d\u0080\u012f\u0081\u0131\u0082\3\2(\5\2\13\13\16\16\""+ - "\"\4\2%%==\4\2\f\f\17\17\4\2CCcc\4\2DDdd\4\2EEee\4\2FFff\4\2GGgg\4\2H"+ - "Hhh\4\2IIii\4\2JJjj\4\2KKkk\4\2LLll\4\2NNnn\4\2OOoo\4\2PPpp\4\2QQqq\4"+ - "\2RRrr\4\2SSss\4\2TTtt\4\2UUuu\4\2VVvv\4\2WWww\4\2XXxx\4\2YYyy\4\2ZZz"+ - "z\4\2\\\\||\3\2//\3\2\62;\5\2\62;CHch\3\2\629\6\2QQSSqqss\3\2\62\63\3"+ - "\2))\4\2))``\4\2$$``\5\2A\\aac|\6\2\62;A\\aac|\2\u0371\2\3\3\2\2\2\2\5"+ - "\3\2\2\2\2\7\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3"+ - "\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2"+ - "\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2"+ - "[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3"+ - "\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2"+ - "\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2"+ - "\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089"+ - "\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2"+ - "\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b"+ - "\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2"+ - "\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad"+ - "\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2"+ - "\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf"+ - "\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2"+ - "\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1"+ - "\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2"+ - "\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3"+ - "\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9\3\2\2\2\2\u00eb\3\2\2"+ - "\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1\3\2\2\2\2\u00f3\3\2\2\2\2\u00f5"+ - "\3\2\2\2\2\u00f7\3\2\2\2\2\u00f9\3\2\2\2\2\u00fb\3\2\2\2\2\u00fd\3\2\2"+ - "\2\2\u00ff\3\2\2\2\2\u0101\3\2\2\2\2\u0103\3\2\2\2\2\u0105\3\2\2\2\2\u0107"+ - "\3\2\2\2\2\u0109\3\2\2\2\2\u010b\3\2\2\2\2\u010d\3\2\2\2\2\u010f\3\2\2"+ - "\2\2\u0111\3\2\2\2\2\u0113\3\2\2\2\2\u0115\3\2\2\2\2\u0117\3\2\2\2\2\u0119"+ - "\3\2\2\2\2\u011b\3\2\2\2\2\u011d\3\2\2\2\2\u011f\3\2\2\2\2\u0121\3\2\2"+ - "\2\2\u0123\3\2\2\2\2\u0125\3\2\2\2\2\u0127\3\2\2\2\2\u0129\3\2\2\2\2\u012b"+ - "\3\2\2\2\2\u012d\3\2\2\2\2\u012f\3\2\2\2\2\u0131\3\2\2\2\3\u0133\3\2\2"+ - "\2\5\u013c\3\2\2\2\7\u0145\3\2\2\2\t\u0149\3\2\2\2\13\u014b\3\2\2\2\r"+ - "\u014d\3\2\2\2\17\u014f\3\2\2\2\21\u0151\3\2\2\2\23\u0153\3\2\2\2\25\u0155"+ - "\3\2\2\2\27\u0157\3\2\2\2\31\u0159\3\2\2\2\33\u015b\3\2\2\2\35\u015d\3"+ - "\2\2\2\37\u015f\3\2\2\2!\u0161\3\2\2\2#\u0163\3\2\2\2%\u0165\3\2\2\2\'"+ - "\u0167\3\2\2\2)\u0169\3\2\2\2+\u016b\3\2\2\2-\u016d\3\2\2\2/\u016f\3\2"+ - "\2\2\61\u0171\3\2\2\2\63\u0173\3\2\2\2\65\u0175\3\2\2\2\67\u0177\3\2\2"+ - "\29\u0179\3\2\2\2;\u017d\3\2\2\2=\u0181\3\2\2\2?\u0185\3\2\2\2A\u0189"+ - "\3\2\2\2C\u018d\3\2\2\2E\u0191\3\2\2\2G\u0195\3\2\2\2I\u0199\3\2\2\2K"+ - "\u019e\3\2\2\2M\u01a3\3\2\2\2O\u01a7\3\2\2\2Q\u01ab\3\2\2\2S\u01af\3\2"+ - "\2\2U\u01b3\3\2\2\2W\u01b7\3\2\2\2Y\u01bb\3\2\2\2[\u01bf\3\2\2\2]\u01c3"+ - "\3\2\2\2_\u01c7\3\2\2\2a\u01cb\3\2\2\2c\u01cf\3\2\2\2e\u01d3\3\2\2\2g"+ - "\u01d8\3\2\2\2i\u01dc\3\2\2\2k\u01e0\3\2\2\2m\u01e4\3\2\2\2o\u01e8\3\2"+ - "\2\2q\u01ed\3\2\2\2s\u01f2\3\2\2\2u\u01f7\3\2\2\2w\u01fb\3\2\2\2y\u01ff"+ - "\3\2\2\2{\u0203\3\2\2\2}\u0207\3\2\2\2\177\u020b\3\2\2\2\u0081\u020f\3"+ - "\2\2\2\u0083\u0213\3\2\2\2\u0085\u0217\3\2\2\2\u0087\u021b\3\2\2\2\u0089"+ - "\u021f\3\2\2\2\u008b\u0223\3\2\2\2\u008d\u0227\3\2\2\2\u008f\u022c\3\2"+ - "\2\2\u0091\u0231\3\2\2\2\u0093\u0236\3\2\2\2\u0095\u023a\3\2\2\2\u0097"+ - "\u023d\3\2\2\2\u0099\u0241\3\2\2\2\u009b\u0244\3\2\2\2\u009d\u0248\3\2"+ - "\2\2\u009f\u024b\3\2\2\2\u00a1\u024e\3\2\2\2\u00a3\u0252\3\2\2\2\u00a5"+ - "\u0256\3\2\2\2\u00a7\u025b\3\2\2\2\u00a9\u025e\3\2\2\2\u00ab\u0262\3\2"+ - "\2\2\u00ad\u0265\3\2\2\2\u00af\u0269\3\2\2\2\u00b1\u026c\3\2\2\2\u00b3"+ - "\u026f\3\2\2\2\u00b5\u0273\3\2\2\2\u00b7\u0277\3\2\2\2\u00b9\u027b\3\2"+ - "\2\2\u00bb\u027e\3\2\2\2\u00bd\u0282\3\2\2\2\u00bf\u0285\3\2\2\2\u00c1"+ - "\u0289\3\2\2\2\u00c3\u028c\3\2\2\2\u00c5\u028f\3\2\2\2\u00c7\u0293\3\2"+ - "\2\2\u00c9\u0297\3\2\2\2\u00cb\u029b\3\2\2\2\u00cd\u029e\3\2\2\2\u00cf"+ - "\u02a1\3\2\2\2\u00d1\u02a4\3\2\2\2\u00d3\u02a8\3\2\2\2\u00d5\u02ac\3\2"+ - "\2\2\u00d7\u02b0\3\2\2\2\u00d9\u02b4\3\2\2\2\u00db\u02b8\3\2\2\2\u00dd"+ - "\u02c0\3\2\2\2\u00df\u02c3\3\2\2\2\u00e1\u02c9\3\2\2\2\u00e3\u02cf\3\2"+ - "\2\2\u00e5\u02d4\3\2\2\2\u00e7\u02d7\3\2\2\2\u00e9\u02da\3\2\2\2\u00eb"+ - "\u02dd\3\2\2\2\u00ed\u02df\3\2\2\2\u00ef\u02e1\3\2\2\2\u00f1\u02e3\3\2"+ - "\2\2\u00f3\u02e5\3\2\2\2\u00f5\u02e7\3\2\2\2\u00f7\u02e9\3\2\2\2\u00f9"+ - "\u02eb\3\2\2\2\u00fb\u02ed\3\2\2\2\u00fd\u02ef\3\2\2\2\u00ff\u02f3\3\2"+ - "\2\2\u0101\u02f6\3\2\2\2\u0103\u02f8\3\2\2\2\u0105\u02fa\3\2\2\2\u0107"+ - "\u02fc\3\2\2\2\u0109\u02fe\3\2\2\2\u010b\u0300\3\2\2\2\u010d\u0302\3\2"+ - "\2\2\u010f\u0304\3\2\2\2\u0111\u0306\3\2\2\2\u0113\u030a\3\2\2\2\u0115"+ - "\u030e\3\2\2\2\u0117\u0312\3\2\2\2\u0119\u0316\3\2\2\2\u011b\u031a\3\2"+ - "\2\2\u011d\u031d\3\2\2\2\u011f\u0322\3\2\2\2\u0121\u032d\3\2\2\2\u0123"+ - "\u033b\3\2\2\2\u0125\u0345\3\2\2\2\u0127\u034f\3\2\2\2\u0129\u0355\3\2"+ - "\2\2\u012b\u035d\3\2\2\2\u012d\u0365\3\2\2\2\u012f\u036c\3\2\2\2\u0131"+ - "\u0375\3\2\2\2\u0133\u0134\t\2\2\2\u0134\u0135\3\2\2\2\u0135\u0136\b\2"+ - "\2\2\u0136\4\3\2\2\2\u0137\u0138\7\61\2\2\u0138\u013d\7\61\2\2\u0139\u013a"+ - "\7/\2\2\u013a\u013d\7/\2\2\u013b\u013d\t\3\2\2\u013c\u0137\3\2\2\2\u013c"+ - "\u0139\3\2\2\2\u013c\u013b\3\2\2\2\u013d\u0141\3\2\2\2\u013e\u0140\n\4"+ - "\2\2\u013f\u013e\3\2\2\2\u0140\u0143\3\2\2\2\u0141\u013f\3\2\2\2\u0141"+ - "\u0142\3\2\2\2\u0142\6\3\2\2\2\u0143\u0141\3\2\2\2\u0144\u0146\7\17\2"+ - "\2\u0145\u0144\3\2\2\2\u0145\u0146\3\2\2\2\u0146\u0147\3\2\2\2\u0147\u0148"+ - "\7\f\2\2\u0148\b\3\2\2\2\u0149\u014a\t\5\2\2\u014a\n\3\2\2\2\u014b\u014c"+ - "\t\6\2\2\u014c\f\3\2\2\2\u014d\u014e\t\7\2\2\u014e\16\3\2\2\2\u014f\u0150"+ - "\t\b\2\2\u0150\20\3\2\2\2\u0151\u0152\t\t\2\2\u0152\22\3\2\2\2\u0153\u0154"+ - "\t\n\2\2\u0154\24\3\2\2\2\u0155\u0156\t\13\2\2\u0156\26\3\2\2\2\u0157"+ - "\u0158\t\f\2\2\u0158\30\3\2\2\2\u0159\u015a\t\r\2\2\u015a\32\3\2\2\2\u015b"+ - "\u015c\t\16\2\2\u015c\34\3\2\2\2\u015d\u015e\t\17\2\2\u015e\36\3\2\2\2"+ - "\u015f\u0160\t\20\2\2\u0160 \3\2\2\2\u0161\u0162\t\21\2\2\u0162\"\3\2"+ - "\2\2\u0163\u0164\t\22\2\2\u0164$\3\2\2\2\u0165\u0166\t\23\2\2\u0166&\3"+ - "\2\2\2\u0167\u0168\t\24\2\2\u0168(\3\2\2\2\u0169\u016a\t\25\2\2\u016a"+ - "*\3\2\2\2\u016b\u016c\t\26\2\2\u016c,\3\2\2\2\u016d\u016e\t\27\2\2\u016e"+ - ".\3\2\2\2\u016f\u0170\t\30\2\2\u0170\60\3\2\2\2\u0171\u0172\t\31\2\2\u0172"+ - "\62\3\2\2\2\u0173\u0174\t\32\2\2\u0174\64\3\2\2\2\u0175\u0176\t\33\2\2"+ - "\u0176\66\3\2\2\2\u0177\u0178\t\34\2\2\u01788\3\2\2\2\u0179\u017a\5+\26"+ - "\2\u017a\u017b\5-\27\2\u017b\u017c\5\r\7\2\u017c:\3\2\2\2\u017d\u017e"+ - "\5\r\7\2\u017e\u017f\5\37\20\2\u017f\u0180\5\r\7\2\u0180<\3\2\2\2\u0181"+ - "\u0182\5\31\r\2\u0182\u0183\5!\21\2\u0183\u0184\5)\25\2\u0184>\3\2\2\2"+ - "\u0185\u0186\5\17\b\2\u0186\u0187\5\r\7\2\u0187\u0188\5)\25\2\u0188@\3"+ - "\2\2\2\u0189\u018a\5\r\7\2\u018a\u018b\5\37\20\2\u018b\u018c\5\t\5\2\u018c"+ - "B\3\2\2\2\u018d\u018e\5\17\b\2\u018e\u018f\5\t\5\2\u018f\u0190\5\t\5\2"+ - "\u0190D\3\2\2\2\u0191\u0192\5!\21\2\u0192\u0193\5#\22\2\u0193\u0194\5"+ - "%\23\2\u0194F\3\2\2\2\u0195\u0196\5\37\20\2\u0196\u0197\5#\22\2\u0197"+ - "\u0198\5\61\31\2\u0198H\3\2\2\2\u0199\u019a\5+\26\2\u019a\u019b\5-\27"+ - "\2\u019b\u019c\5\t\5\2\u019c\u019d\5\65\33\2\u019dJ\3\2\2\2\u019e\u019f"+ - "\5\35\17\2\u019f\u01a0\5\17\b\2\u01a0\u01a1\5\t\5\2\u01a1\u01a2\5\65\33"+ - "\2\u01a2L\3\2\2\2\u01a3\u01a4\5\t\5\2\u01a4\u01a5\5\17\b\2\u01a5\u01a6"+ - "\5\17\b\2\u01a6N\3\2\2\2\u01a7\u01a8\5\t\5\2\u01a8\u01a9\5\17\b\2\u01a9"+ - "\u01aa\5\r\7\2\u01aaP\3\2\2\2\u01ab\u01ac\5+\26\2\u01ac\u01ad\5/\30\2"+ - "\u01ad\u01ae\5\13\6\2\u01aeR\3\2\2\2\u01af\u01b0\5+\26\2\u01b0\u01b1\5"+ - "\13\6\2\u01b1\u01b2\5\13\6\2\u01b2T\3\2\2\2\u01b3\u01b4\5\t\5\2\u01b4"+ - "\u01b5\5!\21\2\u01b5\u01b6\5\t\5\2\u01b6V\3\2\2\2\u01b7\u01b8\5\65\33"+ - "\2\u01b8\u01b9\5)\25\2\u01b9\u01ba\5\t\5\2\u01baX\3\2\2\2\u01bb\u01bc"+ - "\5#\22\2\u01bc\u01bd\5)\25\2\u01bd\u01be\5\t\5\2\u01beZ\3\2\2\2\u01bf"+ - "\u01c0\5\r\7\2\u01c0\u01c1\5\37\20\2\u01c1\u01c2\5%\23\2\u01c2\\\3\2\2"+ - "\2\u01c3\u01c4\5)\25\2\u01c4\u01c5\5\35\17\2\u01c5\u01c6\5\r\7\2\u01c6"+ - "^\3\2\2\2\u01c7\u01c8\5)\25\2\u01c8\u01c9\5)\25\2\u01c9\u01ca\5\r\7\2"+ - "\u01ca`\3\2\2\2\u01cb\u01cc\5)\25\2\u01cc\u01cd\5\t\5\2\u01cd\u01ce\5"+ - "\35\17\2\u01ceb\3\2\2\2\u01cf\u01d0\5)\25\2\u01d0\u01d1\5\t\5\2\u01d1"+ - "\u01d2\5)\25\2\u01d2d\3\2\2\2\u01d3\u01d4\5%\23\2\u01d4\u01d5\5/\30\2"+ - "\u01d5\u01d6\5+\26\2\u01d6\u01d7\5\27\f\2\u01d7f\3\2\2\2\u01d8\u01d9\5"+ - "%\23\2\u01d9\u01da\5#\22\2\u01da\u01db\5%\23\2\u01dbh\3\2\2\2\u01dc\u01dd"+ - "\5\17\b\2\u01dd\u01de\5\t\5\2\u01de\u01df\5\17\b\2\u01dfj\3\2\2\2\u01e0"+ - "\u01e1\5\31\r\2\u01e1\u01e2\5!\21\2\u01e2\u01e3\5\65\33\2\u01e3l\3\2\2"+ - "\2\u01e4\u01e5\5\17\b\2\u01e5\u01e6\5\r\7\2\u01e6\u01e7\5\65\33\2\u01e7"+ - "n\3\2\2\2\u01e8\u01e9\5\65\33\2\u01e9\u01ea\5\r\7\2\u01ea\u01eb\5\27\f"+ - "\2\u01eb\u01ec\5\25\13\2\u01ecp\3\2\2\2\u01ed\u01ee\5\65\33\2\u01ee\u01ef"+ - "\5-\27\2\u01ef\u01f0\5\27\f\2\u01f0\u01f1\5\35\17\2\u01f1r\3\2\2\2\u01f2"+ - "\u01f3\5+\26\2\u01f3\u01f4\5%\23\2\u01f4\u01f5\5\27\f\2\u01f5\u01f6\5"+ - "\35\17\2\u01f6t\3\2\2\2\u01f7\u01f8\5\35\17\2\u01f8\u01f9\5\65\33\2\u01f9"+ - "\u01fa\5\31\r\2\u01fav\3\2\2\2\u01fb\u01fc\5\37\20\2\u01fc\u01fd\5\61"+ - "\31\2\u01fd\u01fe\5\31\r\2\u01fex\3\2\2\2\u01ff\u0200\5\t\5\2\u0200\u0201"+ - "\5\17\b\2\u0201\u0202\5\31\r\2\u0202z\3\2\2\2\u0203\u0204\5\t\5\2\u0204"+ - "\u0205\5\r\7\2\u0205\u0206\5\31\r\2\u0206|\3\2\2\2\u0207\u0208\5+\26\2"+ - "\u0208\u0209\5/\30\2\u0209\u020a\5\31\r\2\u020a~\3\2\2\2\u020b\u020c\5"+ - "+\26\2\u020c\u020d\5\13\6\2\u020d\u020e\5\31\r\2\u020e\u0080\3\2\2\2\u020f"+ - "\u0210\5\t\5\2\u0210\u0211\5!\21\2\u0211\u0212\5\31\r\2\u0212\u0082\3"+ - "\2\2\2\u0213\u0214\5\65\33\2\u0214\u0215\5)\25\2\u0215\u0216\5\31\r\2"+ - "\u0216\u0084\3\2\2\2\u0217\u0218\5#\22\2\u0218\u0219\5)\25\2\u0219\u021a"+ - "\5\31\r\2\u021a\u0086\3\2\2\2\u021b\u021c\5\r\7\2\u021c\u021d\5%\23\2"+ - "\u021d\u021e\5\31\r\2\u021e\u0088\3\2\2\2\u021f\u0220\5+\26\2\u0220\u0221"+ - "\5-\27\2\u0221\u0222\5\t\5\2\u0222\u008a\3\2\2\2\u0223\u0224\5\35\17\2"+ - "\u0224\u0225\5\17\b\2\u0225\u0226\5\t\5\2\u0226\u008c\3\2\2\2\u0227\u0228"+ - "\5+\26\2\u0228\u0229\5\27\f\2\u0229\u022a\5\35\17\2\u022a\u022b\5\17\b"+ - "\2\u022b\u008e\3\2\2\2\u022c\u022d\5\35\17\2\u022d\u022e\5\27\f\2\u022e"+ - "\u022f\5\35\17\2\u022f\u0230\5\17\b\2\u0230\u0090\3\2\2\2\u0231\u0232"+ - "\5%\23\2\u0232\u0233\5\r\7\2\u0233\u0234\5\27\f\2\u0234\u0235\5\35\17"+ - "\2\u0235\u0092\3\2\2\2\u0236\u0237\5\33\16\2\u0237\u0238\5\37\20\2\u0238"+ - "\u0239\5%\23\2\u0239\u0094\3\2\2\2\u023a\u023b\5\33\16\2\u023b\u023c\5"+ - "\r\7\2\u023c\u0096\3\2\2\2\u023d\u023e\5\33\16\2\u023e\u023f\5!\21\2\u023f"+ - "\u0240\5\r\7\2\u0240\u0098\3\2\2\2\u0241\u0242\5\33\16\2\u0242\u0243\5"+ - "\67\34\2\u0243\u009a\3\2\2\2\u0244\u0245\5\33\16\2\u0245\u0246\5!\21\2"+ - "\u0246\u0247\5\67\34\2\u0247\u009c\3\2\2\2\u0248\u0249\5\33\16\2\u0249"+ - "\u024a\5%\23\2\u024a\u009e\3\2\2\2\u024b\u024c\5\33\16\2\u024c\u024d\5"+ - "\37\20\2\u024d\u00a0\3\2\2\2\u024e\u024f\5\33\16\2\u024f\u0250\5%\23\2"+ - "\u0250\u0251\5\21\t\2\u0251\u00a2\3\2\2\2\u0252\u0253\5\33\16\2\u0253"+ - "\u0254\5%\23\2\u0254\u0255\5#\22\2\u0255\u00a4\3\2\2\2\u0256\u0257\5\r"+ - "\7\2\u0257\u0258\5\t\5\2\u0258\u0259\5\35\17\2\u0259\u025a\5\35\17\2\u025a"+ - "\u00a6\3\2\2\2\u025b\u025c\5\r\7\2\u025c\u025d\5\r\7\2\u025d\u00a8\3\2"+ - "\2\2\u025e\u025f\5\r\7\2\u025f\u0260\5!\21\2\u0260\u0261\5\r\7\2\u0261"+ - "\u00aa\3\2\2\2\u0262\u0263\5\r\7\2\u0263\u0264\5\67\34\2\u0264\u00ac\3"+ - "\2\2\2\u0265\u0266\5\r\7\2\u0266\u0267\5!\21\2\u0267\u0268\5\67\34\2\u0268"+ - "\u00ae\3\2\2\2\u0269\u026a\5\r\7\2\u026a\u026b\5%\23\2\u026b\u00b0\3\2"+ - "\2\2\u026c\u026d\5\r\7\2\u026d\u026e\5\37\20\2\u026e\u00b2\3\2\2\2\u026f"+ - "\u0270\5\r\7\2\u0270\u0271\5%\23\2\u0271\u0272\5\21\t\2\u0272\u00b4\3"+ - "\2\2\2\u0273\u0274\5\r\7\2\u0274\u0275\5%\23\2\u0275\u0276\5#\22\2\u0276"+ - "\u00b6\3\2\2\2\u0277\u0278\5)\25\2\u0278\u0279\5\21\t\2\u0279\u027a\5"+ - "-\27\2\u027a\u00b8\3\2\2\2\u027b\u027c\5)\25\2\u027c\u027d\5\r\7\2\u027d"+ - "\u00ba\3\2\2\2\u027e\u027f\5)\25\2\u027f\u0280\5!\21\2\u0280\u0281\5\r"+ - "\7\2\u0281\u00bc\3\2\2\2\u0282\u0283\5)\25\2\u0283\u0284\5\67\34\2\u0284"+ - "\u00be\3\2\2\2\u0285\u0286\5)\25\2\u0286\u0287\5!\21\2\u0287\u0288\5\67"+ - "\34\2\u0288\u00c0\3\2\2\2\u0289\u028a\5)\25\2\u028a\u028b\5\37\20\2\u028b"+ - "\u00c2\3\2\2\2\u028c\u028d\5)\25\2\u028d\u028e\5%\23\2\u028e\u00c4\3\2"+ - "\2\2\u028f\u0290\5)\25\2\u0290\u0291\5%\23\2\u0291\u0292\5\21\t\2\u0292"+ - "\u00c6\3\2\2\2\u0293\u0294\5)\25\2\u0294\u0295\5%\23\2\u0295\u0296\5#"+ - "\22\2\u0296\u00c8\3\2\2\2\u0297\u0298\5)\25\2\u0298\u0299\5+\26\2\u0299"+ - "\u029a\5-\27\2\u029a\u00ca\3\2\2\2\u029b\u029c\5\21\t\2\u029c\u029d\5"+ - "\31\r\2\u029d\u00cc\3\2\2\2\u029e\u029f\5\17\b\2\u029f\u02a0\5\31\r\2"+ - "\u02a0\u00ce\3\2\2\2\u02a1\u02a2\5\31\r\2\u02a2\u02a3\5!\21\2\u02a3\u00d0"+ - "\3\2\2\2\u02a4\u02a5\5#\22\2\u02a5\u02a6\5/\30\2\u02a6\u02a7\5-\27\2\u02a7"+ - "\u00d2\3\2\2\2\u02a8\u02a9\5\27\f\2\u02a9\u02aa\5\35\17\2\u02aa\u02ab"+ - "\5-\27\2\u02ab\u00d4\3\2\2\2\u02ac\u02ad\5#\22\2\u02ad\u02ae\5)\25\2\u02ae"+ - "\u02af\5\25\13\2\u02af\u00d6\3\2\2\2\u02b0\u02b1\5\21\t\2\u02b1\u02b2"+ - "\5\'\24\2\u02b2\u02b3\5/\30\2\u02b3\u00d8\3\2\2\2\u02b4\u02b5\5+\26\2"+ - "\u02b5\u02b6\5\21\t\2\u02b6\u02b7\5-\27\2\u02b7\u00da\3\2\2\2\u02b8\u02b9"+ - "\5\31\r\2\u02b9\u02ba\5!\21\2\u02ba\u02bb\5\r\7\2\u02bb\u02bc\5\35\17"+ - "\2\u02bc\u02bd\5/\30\2\u02bd\u02be\5\17\b\2\u02be\u02bf\5\21\t\2\u02bf"+ - "\u00dc\3\2\2\2\u02c0\u02c1\5\31\r\2\u02c1\u02c2\5\23\n\2\u02c2\u00de\3"+ - "\2\2\2\u02c3\u02c4\5\21\t\2\u02c4\u02c5\5!\21\2\u02c5\u02c6\5\17\b\2\u02c6"+ - "\u02c7\5\31\r\2\u02c7\u02c8\5\23\n\2\u02c8\u00e0\3\2\2\2\u02c9\u02ca\5"+ - "\37\20\2\u02ca\u02cb\5\t\5\2\u02cb\u02cc\5\r\7\2\u02cc\u02cd\5)\25\2\u02cd"+ - "\u02ce\5#\22\2\u02ce\u00e2\3\2\2\2\u02cf\u02d0\5\21\t\2\u02d0\u02d1\5"+ - "!\21\2\u02d1\u02d2\5\17\b\2\u02d2\u02d3\5\37\20\2\u02d3\u00e4\3\2\2\2"+ - "\u02d4\u02d5\5\17\b\2\u02d5\u02d6\5\13\6\2\u02d6\u00e6\3\2\2\2\u02d7\u02d8"+ - "\5\17\b\2\u02d8\u02d9\5\63\32\2\u02d9\u00e8\3\2\2\2\u02da\u02db\5\17\b"+ - "\2\u02db\u02dc\5+\26\2\u02dc\u00ea\3\2\2\2\u02dd\u02de\7&\2\2\u02de\u00ec"+ - "\3\2\2\2\u02df\u02e0\5\t\5\2\u02e0\u00ee\3\2\2\2\u02e1\u02e2\5\13\6\2"+ - "\u02e2\u00f0\3\2\2\2\u02e3\u02e4\5\r\7\2\u02e4\u00f2\3\2\2\2\u02e5\u02e6"+ - "\5\17\b\2\u02e6\u00f4\3\2\2\2\u02e7\u02e8\5\21\t\2\u02e8\u00f6\3\2\2\2"+ - "\u02e9\u02ea\5\27\f\2\u02ea\u00f8\3\2\2\2\u02eb\u02ec\5\35\17\2\u02ec"+ - "\u00fa\3\2\2\2\u02ed\u02ee\5\37\20\2\u02ee\u00fc\3\2\2\2\u02ef\u02f0\5"+ - "%\23\2\u02f0\u02f1\5+\26\2\u02f1\u02f2\5\63\32\2\u02f2\u00fe\3\2\2\2\u02f3"+ - "\u02f4\5+\26\2\u02f4\u02f5\5%\23\2\u02f5\u0100\3\2\2\2\u02f6\u02f7\7*"+ - "\2\2\u02f7\u0102\3\2\2\2\u02f8\u02f9\7+\2\2\u02f9\u0104\3\2\2\2\u02fa"+ - "\u02fb\7.\2\2\u02fb\u0106\3\2\2\2\u02fc\u02fd\7-\2\2\u02fd\u0108\3\2\2"+ - "\2\u02fe\u02ff\7/\2\2\u02ff\u010a\3\2\2\2\u0300\u0301\7,\2\2\u0301\u010c"+ - "\3\2\2\2\u0302\u0303\7\61\2\2\u0303\u010e\3\2\2\2\u0304\u0305\7?\2\2\u0305"+ - "\u0110\3\2\2\2\u0306\u0307\5\37\20\2\u0307\u0308\5#\22\2\u0308\u0309\5"+ - "\17\b\2\u0309\u0112\3\2\2\2\u030a\u030b\5+\26\2\u030b\u030c\5\27\f\2\u030c"+ - "\u030d\5)\25\2\u030d\u0114\3\2\2\2\u030e\u030f\5+\26\2\u030f\u0310\5\27"+ - "\f\2\u0310\u0311\5\35\17\2\u0311\u0116\3\2\2\2\u0312\u0313\5!\21\2\u0313"+ - "\u0314\5#\22\2\u0314\u0315\5-\27\2\u0315\u0118\3\2\2\2\u0316\u0317\5\t"+ - "\5\2\u0317\u0318\5!\21\2\u0318\u0319\5\17\b\2\u0319\u011a\3\2\2\2\u031a"+ - "\u031b\5#\22\2\u031b\u031c\5)\25\2\u031c\u011c\3\2\2\2\u031d\u031e\5\65"+ - "\33\2\u031e\u031f\5#\22\2\u031f\u0320\5)\25\2\u0320\u011e\3\2\2\2\u0321"+ - "\u0323\t\35\2\2\u0322\u0321\3\2\2\2\u0322\u0323\3\2\2\2\u0323\u0325\3"+ - "\2\2\2\u0324\u0326\t\36\2\2\u0325\u0324\3\2\2\2\u0326\u0327\3\2\2\2\u0327"+ - "\u0325\3\2\2\2\u0327\u0328\3\2\2\2\u0328\u032a\3\2\2\2\u0329\u032b\5\17"+ - "\b\2\u032a\u0329\3\2\2\2\u032a\u032b\3\2\2\2\u032b\u0120\3\2\2\2\u032c"+ - "\u032e\t\35\2\2\u032d\u032c\3\2\2\2\u032d\u032e\3\2\2\2\u032e\u0333\3"+ - "\2\2\2\u032f\u0330\7\62\2\2\u0330\u0334\7z\2\2\u0331\u0332\7\62\2\2\u0332"+ - "\u0334\7Z\2\2\u0333\u032f\3\2\2\2\u0333\u0331\3\2\2\2\u0334\u0336\3\2"+ - "\2\2\u0335\u0337\t\37\2\2\u0336\u0335\3\2\2\2\u0337\u0338\3\2\2\2\u0338"+ - "\u0336\3\2\2\2\u0338\u0339\3\2\2\2\u0339\u0122\3\2\2\2\u033a\u033c\t\35"+ - "\2\2\u033b\u033a\3\2\2\2\u033b\u033c\3\2\2\2\u033c\u033e\3\2\2\2\u033d"+ - "\u033f\t\37\2\2\u033e\u033d\3\2\2\2\u033f\u0340\3\2\2\2\u0340\u033e\3"+ - "\2\2\2\u0340\u0341\3\2\2\2\u0341\u0342\3\2\2\2\u0342\u0343\5\27\f\2\u0343"+ - "\u0124\3\2\2\2\u0344\u0346\t\35\2\2\u0345\u0344\3\2\2\2\u0345\u0346\3"+ - "\2\2\2\u0346\u0348\3\2\2\2\u0347\u0349\t \2\2\u0348\u0347\3\2\2\2\u0349"+ - "\u034a\3\2\2\2\u034a\u0348\3\2\2\2\u034a\u034b\3\2\2\2\u034b\u034c\3\2"+ - "\2\2\u034c\u034d\t!\2\2\u034d\u0126\3\2\2\2\u034e\u0350\t\"\2\2\u034f"+ - "\u034e\3\2\2\2\u0350\u0351\3\2\2\2\u0351\u034f\3\2\2\2\u0351\u0352\3\2"+ - "\2\2\u0352\u0353\3\2\2\2\u0353\u0354\5\13\6\2\u0354\u0128\3\2\2\2\u0355"+ - "\u0357\t#\2\2\u0356\u0358\t$\2\2\u0357\u0356\3\2\2\2\u0358\u0359\3\2\2"+ - "\2\u0359\u0357\3\2\2\2\u0359\u035a\3\2\2\2\u035a\u035b\3\2\2\2\u035b\u035c"+ - "\t#\2\2\u035c\u012a\3\2\2\2\u035d\u035f\7$\2\2\u035e\u0360\t%\2\2\u035f"+ - "\u035e\3\2\2\2\u0360\u0361\3\2\2\2\u0361\u035f\3\2\2\2\u0361\u0362\3\2"+ - "\2\2\u0362\u0363\3\2\2\2\u0363\u0364\7$\2\2\u0364\u012c\3\2\2\2\u0365"+ - "\u0369\t&\2\2\u0366\u0368\t\'\2\2\u0367\u0366\3\2\2\2\u0368\u036b\3\2"+ - "\2\2\u0369\u0367\3\2\2\2\u0369\u036a\3\2\2\2\u036a\u012e\3\2\2\2\u036b"+ - "\u0369\3\2\2\2\u036c\u0370\t&\2\2\u036d\u036f\t\'\2\2\u036e\u036d\3\2"+ - "\2\2\u036f\u0372\3\2\2\2\u0370\u036e\3\2\2\2\u0370\u0371\3\2\2\2\u0371"+ - "\u0373\3\2\2\2\u0372\u0370\3\2\2\2\u0373\u0374\7<\2\2\u0374\u0130\3\2"+ - "\2\2\u0375\u0376\13\2\2\2\u0376\u0132\3\2\2\2\25\2\u013c\u0141\u0145\u0322"+ - "\u0327\u032a\u032d\u0333\u0338\u033b\u0340\u0345\u034a\u0351\u0359\u0361"+ - "\u0369\u0370\3\2\3\2"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file diff --git a/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.tokens b/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.tokens deleted file mode 100644 index a522a3c4c..000000000 --- a/plugins/compiler/as-8080/src/main/antlr/gen/As8080Lexer.tokens +++ /dev/null @@ -1,137 +0,0 @@ -WS=1 -COMMENT=2 -EOL=3 -OPCODE_STC=4 -OPCODE_CMC=5 -OPCODE_INR=6 -OPCODE_DCR=7 -OPCODE_CMA=8 -OPCODE_DAA=9 -OPCODE_NOP=10 -OPCODE_MOV=11 -OPCODE_STAX=12 -OPCODE_LDAX=13 -OPCODE_ADD=14 -OPCODE_ADC=15 -OPCODE_SUB=16 -OPCODE_SBB=17 -OPCODE_ANA=18 -OPCODE_XRA=19 -OPCODE_ORA=20 -OPCODE_CMP=21 -OPCODE_RLC=22 -OPCODE_RRC=23 -OPCODE_RAL=24 -OPCODE_RAR=25 -OPCODE_PUSH=26 -OPCODE_POP=27 -OPCODE_DAD=28 -OPCODE_INX=29 -OPCODE_DCX=30 -OPCODE_XCHG=31 -OPCODE_XTHL=32 -OPCODE_SPHL=33 -OPCODE_LXI=34 -OPCODE_MVI=35 -OPCODE_ADI=36 -OPCODE_ACI=37 -OPCODE_SUI=38 -OPCODE_SBI=39 -OPCODE_ANI=40 -OPCODE_XRI=41 -OPCODE_ORI=42 -OPCODE_CPI=43 -OPCODE_STA=44 -OPCODE_LDA=45 -OPCODE_SHLD=46 -OPCODE_LHLD=47 -OPCODE_PCHL=48 -OPCODE_JMP=49 -OPCODE_JC=50 -OPCODE_JNC=51 -OPCODE_JZ=52 -OPCODE_JNZ=53 -OPCODE_JP=54 -OPCODE_JM=55 -OPCODE_JPE=56 -OPCODE_JPO=57 -OPCODE_CALL=58 -OPCODE_CC=59 -OPCODE_CNC=60 -OPCODE_CZ=61 -OPCODE_CNZ=62 -OPCODE_CP=63 -OPCODE_CM=64 -OPCODE_CPE=65 -OPCODE_CPO=66 -OPCODE_RET=67 -OPCODE_RC=68 -OPCODE_RNC=69 -OPCODE_RZ=70 -OPCODE_RNZ=71 -OPCODE_RM=72 -OPCODE_RP=73 -OPCODE_RPE=74 -OPCODE_RPO=75 -OPCODE_RST=76 -OPCODE_EI=77 -OPCODE_DI=78 -OPCODE_IN=79 -OPCODE_OUT=80 -OPCODE_HLT=81 -PREP_ORG=82 -PREP_EQU=83 -PREP_SET=84 -PREP_INCLUDE=85 -PREP_IF=86 -PREP_ENDIF=87 -PREP_MACRO=88 -PREP_ENDM=89 -PREP_DB=90 -PREP_DW=91 -PREP_DS=92 -PREP_ADDR=93 -REG_A=94 -REG_B=95 -REG_C=96 -REG_D=97 -REG_E=98 -REG_H=99 -REG_L=100 -REG_M=101 -REG_PSW=102 -REG_SP=103 -SEP_LPAR=104 -SEP_RPAR=105 -SEP_COMMA=106 -OP_ADD=107 -OP_SUBTRACT=108 -OP_MULTIPLY=109 -OP_DIVIDE=110 -OP_EQUAL=111 -OP_MOD=112 -OP_SHR=113 -OP_SHL=114 -OP_NOT=115 -OP_AND=116 -OP_OR=117 -OP_XOR=118 -LIT_NUMBER=119 -LIT_HEXNUMBER_1=120 -LIT_HEXNUMBER_2=121 -LIT_OCTNUMBER=122 -LIT_BINNUMBER=123 -LIT_STRING_1=124 -LIT_STRING_2=125 -ID_IDENTIFIER=126 -ID_LABEL=127 -ERROR=128 -'$'=93 -'('=104 -')'=105 -','=106 -'+'=107 -'-'=108 -'*'=109 -'/'=110 -'='=111 diff --git a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp deleted file mode 100644 index 74ee276ac..000000000 --- a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.interp +++ /dev/null @@ -1,425 +0,0 @@ -token literal names: -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -'$' -null -null -null -null -null -null -null -null -null -null -'(' -')' -',' -'+' -'-' -'*' -'/' -'=' -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null - -token symbolic names: -null -WS -COMMENT -EOL -OPCODE_STC -OPCODE_CMC -OPCODE_INR -OPCODE_DCR -OPCODE_CMA -OPCODE_DAA -OPCODE_NOP -OPCODE_MOV -OPCODE_STAX -OPCODE_LDAX -OPCODE_ADD -OPCODE_ADC -OPCODE_SUB -OPCODE_SBB -OPCODE_ANA -OPCODE_XRA -OPCODE_ORA -OPCODE_CMP -OPCODE_RLC -OPCODE_RRC -OPCODE_RAL -OPCODE_RAR -OPCODE_PUSH -OPCODE_POP -OPCODE_DAD -OPCODE_INX -OPCODE_DCX -OPCODE_XCHG -OPCODE_XTHL -OPCODE_SPHL -OPCODE_LXI -OPCODE_MVI -OPCODE_ADI -OPCODE_ACI -OPCODE_SUI -OPCODE_SBI -OPCODE_ANI -OPCODE_XRI -OPCODE_ORI -OPCODE_CPI -OPCODE_STA -OPCODE_LDA -OPCODE_SHLD -OPCODE_LHLD -OPCODE_PCHL -OPCODE_JMP -OPCODE_JC -OPCODE_JNC -OPCODE_JZ -OPCODE_JNZ -OPCODE_JP -OPCODE_JM -OPCODE_JPE -OPCODE_JPO -OPCODE_CALL -OPCODE_CC -OPCODE_CNC -OPCODE_CZ -OPCODE_CNZ -OPCODE_CP -OPCODE_CM -OPCODE_CPE -OPCODE_CPO -OPCODE_RET -OPCODE_RC -OPCODE_RNC -OPCODE_RZ -OPCODE_RNZ -OPCODE_RM -OPCODE_RP -OPCODE_RPE -OPCODE_RPO -OPCODE_RST -OPCODE_EI -OPCODE_DI -OPCODE_IN -OPCODE_OUT -OPCODE_HLT -PREP_ORG -PREP_EQU -PREP_SET -PREP_INCLUDE -PREP_IF -PREP_ENDIF -PREP_MACRO -PREP_ENDM -PREP_DB -PREP_DW -PREP_DS -PREP_ADDR -REG_A -REG_B -REG_C -REG_D -REG_E -REG_H -REG_L -REG_M -REG_PSW -REG_SP -SEP_LPAR -SEP_RPAR -SEP_COMMA -OP_ADD -OP_SUBTRACT -OP_MULTIPLY -OP_DIVIDE -OP_EQUAL -OP_MOD -OP_SHR -OP_SHL -OP_NOT -OP_AND -OP_OR -OP_XOR -LIT_NUMBER -LIT_HEXNUMBER_1 -LIT_HEXNUMBER_2 -LIT_OCTNUMBER -LIT_BINNUMBER -LIT_STRING_1 -LIT_STRING_2 -ID_IDENTIFIER -ID_LABEL -ERROR - -rule names: -WS -COMMENT -EOL -A -B -C -D -E -F -G -H -I -J -L -M -N -O -P -Q -R -S -T -U -V -W -X -Z -OPCODE_STC -OPCODE_CMC -OPCODE_INR -OPCODE_DCR -OPCODE_CMA -OPCODE_DAA -OPCODE_NOP -OPCODE_MOV -OPCODE_STAX -OPCODE_LDAX -OPCODE_ADD -OPCODE_ADC -OPCODE_SUB -OPCODE_SBB -OPCODE_ANA -OPCODE_XRA -OPCODE_ORA -OPCODE_CMP -OPCODE_RLC -OPCODE_RRC -OPCODE_RAL -OPCODE_RAR -OPCODE_PUSH -OPCODE_POP -OPCODE_DAD -OPCODE_INX -OPCODE_DCX -OPCODE_XCHG -OPCODE_XTHL -OPCODE_SPHL -OPCODE_LXI -OPCODE_MVI -OPCODE_ADI -OPCODE_ACI -OPCODE_SUI -OPCODE_SBI -OPCODE_ANI -OPCODE_XRI -OPCODE_ORI -OPCODE_CPI -OPCODE_STA -OPCODE_LDA -OPCODE_SHLD -OPCODE_LHLD -OPCODE_PCHL -OPCODE_JMP -OPCODE_JC -OPCODE_JNC -OPCODE_JZ -OPCODE_JNZ -OPCODE_JP -OPCODE_JM -OPCODE_JPE -OPCODE_JPO -OPCODE_CALL -OPCODE_CC -OPCODE_CNC -OPCODE_CZ -OPCODE_CNZ -OPCODE_CP -OPCODE_CM -OPCODE_CPE -OPCODE_CPO -OPCODE_RET -OPCODE_RC -OPCODE_RNC -OPCODE_RZ -OPCODE_RNZ -OPCODE_RM -OPCODE_RP -OPCODE_RPE -OPCODE_RPO -OPCODE_RST -OPCODE_EI -OPCODE_DI -OPCODE_IN -OPCODE_OUT -OPCODE_HLT -PREP_ORG -PREP_EQU -PREP_SET -PREP_INCLUDE -PREP_IF -PREP_ENDIF -PREP_MACRO -PREP_ENDM -PREP_DB -PREP_DW -PREP_DS -PREP_ADDR -REG_A -REG_B -REG_C -REG_D -REG_E -REG_H -REG_L -REG_M -REG_PSW -REG_SP -SEP_LPAR -SEP_RPAR -SEP_COMMA -OP_ADD -OP_SUBTRACT -OP_MULTIPLY -OP_DIVIDE -OP_EQUAL -OP_MOD -OP_SHR -OP_SHL -OP_NOT -OP_AND -OP_OR -OP_XOR -LIT_NUMBER -LIT_HEXNUMBER_1 -LIT_HEXNUMBER_2 -LIT_OCTNUMBER -LIT_BINNUMBER -LIT_STRING_1 -LIT_STRING_2 -ID_IDENTIFIER -ID_LABEL -ERROR - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 130, 883, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 317, 10, 3, 3, 3, 7, 3, 320, 10, 3, 12, 3, 14, 3, 323, 11, 3, 3, 4, 5, 4, 326, 10, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 105, 3, 105, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 130, 3, 130, 3, 131, 3, 131, 3, 132, 3, 132, 3, 133, 3, 133, 3, 134, 3, 134, 3, 135, 3, 135, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 138, 3, 138, 3, 139, 3, 139, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 5, 144, 803, 10, 144, 3, 144, 6, 144, 806, 10, 144, 13, 144, 14, 144, 807, 3, 144, 5, 144, 811, 10, 144, 3, 145, 5, 145, 814, 10, 145, 3, 145, 3, 145, 3, 145, 6, 145, 819, 10, 145, 13, 145, 14, 145, 820, 3, 146, 5, 146, 824, 10, 146, 3, 146, 6, 146, 827, 10, 146, 13, 146, 14, 146, 828, 3, 146, 3, 146, 3, 147, 5, 147, 834, 10, 147, 3, 147, 6, 147, 837, 10, 147, 13, 147, 14, 147, 838, 3, 147, 3, 147, 3, 148, 6, 148, 844, 10, 148, 13, 148, 14, 148, 845, 3, 148, 3, 148, 3, 149, 3, 149, 6, 149, 852, 10, 149, 13, 149, 14, 149, 853, 3, 149, 3, 149, 3, 150, 3, 150, 6, 150, 860, 10, 150, 13, 150, 14, 150, 861, 3, 150, 3, 150, 3, 151, 3, 151, 7, 151, 868, 10, 151, 12, 151, 14, 151, 871, 11, 151, 3, 152, 3, 152, 7, 152, 875, 10, 152, 12, 152, 14, 152, 878, 11, 152, 3, 152, 3, 152, 3, 153, 3, 153, 2, 2, 154, 3, 3, 5, 4, 7, 5, 9, 2, 11, 2, 13, 2, 15, 2, 17, 2, 19, 2, 21, 2, 23, 2, 25, 2, 27, 2, 29, 2, 31, 2, 33, 2, 35, 2, 37, 2, 39, 2, 41, 2, 43, 2, 45, 2, 47, 2, 49, 2, 51, 2, 53, 2, 55, 2, 57, 6, 59, 7, 61, 8, 63, 9, 65, 10, 67, 11, 69, 12, 71, 13, 73, 14, 75, 15, 77, 16, 79, 17, 81, 18, 83, 19, 85, 20, 87, 21, 89, 22, 91, 23, 93, 24, 95, 25, 97, 26, 99, 27, 101, 28, 103, 29, 105, 30, 107, 31, 109, 32, 111, 33, 113, 34, 115, 35, 117, 36, 119, 37, 121, 38, 123, 39, 125, 40, 127, 41, 129, 42, 131, 43, 133, 44, 135, 45, 137, 46, 139, 47, 141, 48, 143, 49, 145, 50, 147, 51, 149, 52, 151, 53, 153, 54, 155, 55, 157, 56, 159, 57, 161, 58, 163, 59, 165, 60, 167, 61, 169, 62, 171, 63, 173, 64, 175, 65, 177, 66, 179, 67, 181, 68, 183, 69, 185, 70, 187, 71, 189, 72, 191, 73, 193, 74, 195, 75, 197, 76, 199, 77, 201, 78, 203, 79, 205, 80, 207, 81, 209, 82, 211, 83, 213, 84, 215, 85, 217, 86, 219, 87, 221, 88, 223, 89, 225, 90, 227, 91, 229, 92, 231, 93, 233, 94, 235, 95, 237, 96, 239, 97, 241, 98, 243, 99, 245, 100, 247, 101, 249, 102, 251, 103, 253, 104, 255, 105, 257, 106, 259, 107, 261, 108, 263, 109, 265, 110, 267, 111, 269, 112, 271, 113, 273, 114, 275, 115, 277, 116, 279, 117, 281, 118, 283, 119, 285, 120, 287, 121, 289, 122, 291, 123, 293, 124, 295, 125, 297, 126, 299, 127, 301, 128, 303, 129, 305, 130, 3, 2, 40, 5, 2, 11, 11, 14, 14, 34, 34, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 92, 92, 124, 124, 3, 2, 47, 47, 3, 2, 50, 59, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 4, 2, 41, 41, 96, 96, 4, 2, 36, 36, 96, 96, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 2, 876, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, 2, 2, 2, 153, 3, 2, 2, 2, 2, 155, 3, 2, 2, 2, 2, 157, 3, 2, 2, 2, 2, 159, 3, 2, 2, 2, 2, 161, 3, 2, 2, 2, 2, 163, 3, 2, 2, 2, 2, 165, 3, 2, 2, 2, 2, 167, 3, 2, 2, 2, 2, 169, 3, 2, 2, 2, 2, 171, 3, 2, 2, 2, 2, 173, 3, 2, 2, 2, 2, 175, 3, 2, 2, 2, 2, 177, 3, 2, 2, 2, 2, 179, 3, 2, 2, 2, 2, 181, 3, 2, 2, 2, 2, 183, 3, 2, 2, 2, 2, 185, 3, 2, 2, 2, 2, 187, 3, 2, 2, 2, 2, 189, 3, 2, 2, 2, 2, 191, 3, 2, 2, 2, 2, 193, 3, 2, 2, 2, 2, 195, 3, 2, 2, 2, 2, 197, 3, 2, 2, 2, 2, 199, 3, 2, 2, 2, 2, 201, 3, 2, 2, 2, 2, 203, 3, 2, 2, 2, 2, 205, 3, 2, 2, 2, 2, 207, 3, 2, 2, 2, 2, 209, 3, 2, 2, 2, 2, 211, 3, 2, 2, 2, 2, 213, 3, 2, 2, 2, 2, 215, 3, 2, 2, 2, 2, 217, 3, 2, 2, 2, 2, 219, 3, 2, 2, 2, 2, 221, 3, 2, 2, 2, 2, 223, 3, 2, 2, 2, 2, 225, 3, 2, 2, 2, 2, 227, 3, 2, 2, 2, 2, 229, 3, 2, 2, 2, 2, 231, 3, 2, 2, 2, 2, 233, 3, 2, 2, 2, 2, 235, 3, 2, 2, 2, 2, 237, 3, 2, 2, 2, 2, 239, 3, 2, 2, 2, 2, 241, 3, 2, 2, 2, 2, 243, 3, 2, 2, 2, 2, 245, 3, 2, 2, 2, 2, 247, 3, 2, 2, 2, 2, 249, 3, 2, 2, 2, 2, 251, 3, 2, 2, 2, 2, 253, 3, 2, 2, 2, 2, 255, 3, 2, 2, 2, 2, 257, 3, 2, 2, 2, 2, 259, 3, 2, 2, 2, 2, 261, 3, 2, 2, 2, 2, 263, 3, 2, 2, 2, 2, 265, 3, 2, 2, 2, 2, 267, 3, 2, 2, 2, 2, 269, 3, 2, 2, 2, 2, 271, 3, 2, 2, 2, 2, 273, 3, 2, 2, 2, 2, 275, 3, 2, 2, 2, 2, 277, 3, 2, 2, 2, 2, 279, 3, 2, 2, 2, 2, 281, 3, 2, 2, 2, 2, 283, 3, 2, 2, 2, 2, 285, 3, 2, 2, 2, 2, 287, 3, 2, 2, 2, 2, 289, 3, 2, 2, 2, 2, 291, 3, 2, 2, 2, 2, 293, 3, 2, 2, 2, 2, 295, 3, 2, 2, 2, 2, 297, 3, 2, 2, 2, 2, 299, 3, 2, 2, 2, 2, 301, 3, 2, 2, 2, 2, 303, 3, 2, 2, 2, 2, 305, 3, 2, 2, 2, 3, 307, 3, 2, 2, 2, 5, 316, 3, 2, 2, 2, 7, 325, 3, 2, 2, 2, 9, 329, 3, 2, 2, 2, 11, 331, 3, 2, 2, 2, 13, 333, 3, 2, 2, 2, 15, 335, 3, 2, 2, 2, 17, 337, 3, 2, 2, 2, 19, 339, 3, 2, 2, 2, 21, 341, 3, 2, 2, 2, 23, 343, 3, 2, 2, 2, 25, 345, 3, 2, 2, 2, 27, 347, 3, 2, 2, 2, 29, 349, 3, 2, 2, 2, 31, 351, 3, 2, 2, 2, 33, 353, 3, 2, 2, 2, 35, 355, 3, 2, 2, 2, 37, 357, 3, 2, 2, 2, 39, 359, 3, 2, 2, 2, 41, 361, 3, 2, 2, 2, 43, 363, 3, 2, 2, 2, 45, 365, 3, 2, 2, 2, 47, 367, 3, 2, 2, 2, 49, 369, 3, 2, 2, 2, 51, 371, 3, 2, 2, 2, 53, 373, 3, 2, 2, 2, 55, 375, 3, 2, 2, 2, 57, 377, 3, 2, 2, 2, 59, 381, 3, 2, 2, 2, 61, 385, 3, 2, 2, 2, 63, 389, 3, 2, 2, 2, 65, 393, 3, 2, 2, 2, 67, 397, 3, 2, 2, 2, 69, 401, 3, 2, 2, 2, 71, 405, 3, 2, 2, 2, 73, 409, 3, 2, 2, 2, 75, 414, 3, 2, 2, 2, 77, 419, 3, 2, 2, 2, 79, 423, 3, 2, 2, 2, 81, 427, 3, 2, 2, 2, 83, 431, 3, 2, 2, 2, 85, 435, 3, 2, 2, 2, 87, 439, 3, 2, 2, 2, 89, 443, 3, 2, 2, 2, 91, 447, 3, 2, 2, 2, 93, 451, 3, 2, 2, 2, 95, 455, 3, 2, 2, 2, 97, 459, 3, 2, 2, 2, 99, 463, 3, 2, 2, 2, 101, 467, 3, 2, 2, 2, 103, 472, 3, 2, 2, 2, 105, 476, 3, 2, 2, 2, 107, 480, 3, 2, 2, 2, 109, 484, 3, 2, 2, 2, 111, 488, 3, 2, 2, 2, 113, 493, 3, 2, 2, 2, 115, 498, 3, 2, 2, 2, 117, 503, 3, 2, 2, 2, 119, 507, 3, 2, 2, 2, 121, 511, 3, 2, 2, 2, 123, 515, 3, 2, 2, 2, 125, 519, 3, 2, 2, 2, 127, 523, 3, 2, 2, 2, 129, 527, 3, 2, 2, 2, 131, 531, 3, 2, 2, 2, 133, 535, 3, 2, 2, 2, 135, 539, 3, 2, 2, 2, 137, 543, 3, 2, 2, 2, 139, 547, 3, 2, 2, 2, 141, 551, 3, 2, 2, 2, 143, 556, 3, 2, 2, 2, 145, 561, 3, 2, 2, 2, 147, 566, 3, 2, 2, 2, 149, 570, 3, 2, 2, 2, 151, 573, 3, 2, 2, 2, 153, 577, 3, 2, 2, 2, 155, 580, 3, 2, 2, 2, 157, 584, 3, 2, 2, 2, 159, 587, 3, 2, 2, 2, 161, 590, 3, 2, 2, 2, 163, 594, 3, 2, 2, 2, 165, 598, 3, 2, 2, 2, 167, 603, 3, 2, 2, 2, 169, 606, 3, 2, 2, 2, 171, 610, 3, 2, 2, 2, 173, 613, 3, 2, 2, 2, 175, 617, 3, 2, 2, 2, 177, 620, 3, 2, 2, 2, 179, 623, 3, 2, 2, 2, 181, 627, 3, 2, 2, 2, 183, 631, 3, 2, 2, 2, 185, 635, 3, 2, 2, 2, 187, 638, 3, 2, 2, 2, 189, 642, 3, 2, 2, 2, 191, 645, 3, 2, 2, 2, 193, 649, 3, 2, 2, 2, 195, 652, 3, 2, 2, 2, 197, 655, 3, 2, 2, 2, 199, 659, 3, 2, 2, 2, 201, 663, 3, 2, 2, 2, 203, 667, 3, 2, 2, 2, 205, 670, 3, 2, 2, 2, 207, 673, 3, 2, 2, 2, 209, 676, 3, 2, 2, 2, 211, 680, 3, 2, 2, 2, 213, 684, 3, 2, 2, 2, 215, 688, 3, 2, 2, 2, 217, 692, 3, 2, 2, 2, 219, 696, 3, 2, 2, 2, 221, 704, 3, 2, 2, 2, 223, 707, 3, 2, 2, 2, 225, 713, 3, 2, 2, 2, 227, 719, 3, 2, 2, 2, 229, 724, 3, 2, 2, 2, 231, 727, 3, 2, 2, 2, 233, 730, 3, 2, 2, 2, 235, 733, 3, 2, 2, 2, 237, 735, 3, 2, 2, 2, 239, 737, 3, 2, 2, 2, 241, 739, 3, 2, 2, 2, 243, 741, 3, 2, 2, 2, 245, 743, 3, 2, 2, 2, 247, 745, 3, 2, 2, 2, 249, 747, 3, 2, 2, 2, 251, 749, 3, 2, 2, 2, 253, 751, 3, 2, 2, 2, 255, 755, 3, 2, 2, 2, 257, 758, 3, 2, 2, 2, 259, 760, 3, 2, 2, 2, 261, 762, 3, 2, 2, 2, 263, 764, 3, 2, 2, 2, 265, 766, 3, 2, 2, 2, 267, 768, 3, 2, 2, 2, 269, 770, 3, 2, 2, 2, 271, 772, 3, 2, 2, 2, 273, 774, 3, 2, 2, 2, 275, 778, 3, 2, 2, 2, 277, 782, 3, 2, 2, 2, 279, 786, 3, 2, 2, 2, 281, 790, 3, 2, 2, 2, 283, 794, 3, 2, 2, 2, 285, 797, 3, 2, 2, 2, 287, 802, 3, 2, 2, 2, 289, 813, 3, 2, 2, 2, 291, 823, 3, 2, 2, 2, 293, 833, 3, 2, 2, 2, 295, 843, 3, 2, 2, 2, 297, 849, 3, 2, 2, 2, 299, 857, 3, 2, 2, 2, 301, 865, 3, 2, 2, 2, 303, 872, 3, 2, 2, 2, 305, 881, 3, 2, 2, 2, 307, 308, 9, 2, 2, 2, 308, 309, 3, 2, 2, 2, 309, 310, 8, 2, 2, 2, 310, 4, 3, 2, 2, 2, 311, 312, 7, 49, 2, 2, 312, 317, 7, 49, 2, 2, 313, 314, 7, 47, 2, 2, 314, 317, 7, 47, 2, 2, 315, 317, 9, 3, 2, 2, 316, 311, 3, 2, 2, 2, 316, 313, 3, 2, 2, 2, 316, 315, 3, 2, 2, 2, 317, 321, 3, 2, 2, 2, 318, 320, 10, 4, 2, 2, 319, 318, 3, 2, 2, 2, 320, 323, 3, 2, 2, 2, 321, 319, 3, 2, 2, 2, 321, 322, 3, 2, 2, 2, 322, 6, 3, 2, 2, 2, 323, 321, 3, 2, 2, 2, 324, 326, 7, 15, 2, 2, 325, 324, 3, 2, 2, 2, 325, 326, 3, 2, 2, 2, 326, 327, 3, 2, 2, 2, 327, 328, 7, 12, 2, 2, 328, 8, 3, 2, 2, 2, 329, 330, 9, 5, 2, 2, 330, 10, 3, 2, 2, 2, 331, 332, 9, 6, 2, 2, 332, 12, 3, 2, 2, 2, 333, 334, 9, 7, 2, 2, 334, 14, 3, 2, 2, 2, 335, 336, 9, 8, 2, 2, 336, 16, 3, 2, 2, 2, 337, 338, 9, 9, 2, 2, 338, 18, 3, 2, 2, 2, 339, 340, 9, 10, 2, 2, 340, 20, 3, 2, 2, 2, 341, 342, 9, 11, 2, 2, 342, 22, 3, 2, 2, 2, 343, 344, 9, 12, 2, 2, 344, 24, 3, 2, 2, 2, 345, 346, 9, 13, 2, 2, 346, 26, 3, 2, 2, 2, 347, 348, 9, 14, 2, 2, 348, 28, 3, 2, 2, 2, 349, 350, 9, 15, 2, 2, 350, 30, 3, 2, 2, 2, 351, 352, 9, 16, 2, 2, 352, 32, 3, 2, 2, 2, 353, 354, 9, 17, 2, 2, 354, 34, 3, 2, 2, 2, 355, 356, 9, 18, 2, 2, 356, 36, 3, 2, 2, 2, 357, 358, 9, 19, 2, 2, 358, 38, 3, 2, 2, 2, 359, 360, 9, 20, 2, 2, 360, 40, 3, 2, 2, 2, 361, 362, 9, 21, 2, 2, 362, 42, 3, 2, 2, 2, 363, 364, 9, 22, 2, 2, 364, 44, 3, 2, 2, 2, 365, 366, 9, 23, 2, 2, 366, 46, 3, 2, 2, 2, 367, 368, 9, 24, 2, 2, 368, 48, 3, 2, 2, 2, 369, 370, 9, 25, 2, 2, 370, 50, 3, 2, 2, 2, 371, 372, 9, 26, 2, 2, 372, 52, 3, 2, 2, 2, 373, 374, 9, 27, 2, 2, 374, 54, 3, 2, 2, 2, 375, 376, 9, 28, 2, 2, 376, 56, 3, 2, 2, 2, 377, 378, 5, 43, 22, 2, 378, 379, 5, 45, 23, 2, 379, 380, 5, 13, 7, 2, 380, 58, 3, 2, 2, 2, 381, 382, 5, 13, 7, 2, 382, 383, 5, 31, 16, 2, 383, 384, 5, 13, 7, 2, 384, 60, 3, 2, 2, 2, 385, 386, 5, 25, 13, 2, 386, 387, 5, 33, 17, 2, 387, 388, 5, 41, 21, 2, 388, 62, 3, 2, 2, 2, 389, 390, 5, 15, 8, 2, 390, 391, 5, 13, 7, 2, 391, 392, 5, 41, 21, 2, 392, 64, 3, 2, 2, 2, 393, 394, 5, 13, 7, 2, 394, 395, 5, 31, 16, 2, 395, 396, 5, 9, 5, 2, 396, 66, 3, 2, 2, 2, 397, 398, 5, 15, 8, 2, 398, 399, 5, 9, 5, 2, 399, 400, 5, 9, 5, 2, 400, 68, 3, 2, 2, 2, 401, 402, 5, 33, 17, 2, 402, 403, 5, 35, 18, 2, 403, 404, 5, 37, 19, 2, 404, 70, 3, 2, 2, 2, 405, 406, 5, 31, 16, 2, 406, 407, 5, 35, 18, 2, 407, 408, 5, 49, 25, 2, 408, 72, 3, 2, 2, 2, 409, 410, 5, 43, 22, 2, 410, 411, 5, 45, 23, 2, 411, 412, 5, 9, 5, 2, 412, 413, 5, 53, 27, 2, 413, 74, 3, 2, 2, 2, 414, 415, 5, 29, 15, 2, 415, 416, 5, 15, 8, 2, 416, 417, 5, 9, 5, 2, 417, 418, 5, 53, 27, 2, 418, 76, 3, 2, 2, 2, 419, 420, 5, 9, 5, 2, 420, 421, 5, 15, 8, 2, 421, 422, 5, 15, 8, 2, 422, 78, 3, 2, 2, 2, 423, 424, 5, 9, 5, 2, 424, 425, 5, 15, 8, 2, 425, 426, 5, 13, 7, 2, 426, 80, 3, 2, 2, 2, 427, 428, 5, 43, 22, 2, 428, 429, 5, 47, 24, 2, 429, 430, 5, 11, 6, 2, 430, 82, 3, 2, 2, 2, 431, 432, 5, 43, 22, 2, 432, 433, 5, 11, 6, 2, 433, 434, 5, 11, 6, 2, 434, 84, 3, 2, 2, 2, 435, 436, 5, 9, 5, 2, 436, 437, 5, 33, 17, 2, 437, 438, 5, 9, 5, 2, 438, 86, 3, 2, 2, 2, 439, 440, 5, 53, 27, 2, 440, 441, 5, 41, 21, 2, 441, 442, 5, 9, 5, 2, 442, 88, 3, 2, 2, 2, 443, 444, 5, 35, 18, 2, 444, 445, 5, 41, 21, 2, 445, 446, 5, 9, 5, 2, 446, 90, 3, 2, 2, 2, 447, 448, 5, 13, 7, 2, 448, 449, 5, 31, 16, 2, 449, 450, 5, 37, 19, 2, 450, 92, 3, 2, 2, 2, 451, 452, 5, 41, 21, 2, 452, 453, 5, 29, 15, 2, 453, 454, 5, 13, 7, 2, 454, 94, 3, 2, 2, 2, 455, 456, 5, 41, 21, 2, 456, 457, 5, 41, 21, 2, 457, 458, 5, 13, 7, 2, 458, 96, 3, 2, 2, 2, 459, 460, 5, 41, 21, 2, 460, 461, 5, 9, 5, 2, 461, 462, 5, 29, 15, 2, 462, 98, 3, 2, 2, 2, 463, 464, 5, 41, 21, 2, 464, 465, 5, 9, 5, 2, 465, 466, 5, 41, 21, 2, 466, 100, 3, 2, 2, 2, 467, 468, 5, 37, 19, 2, 468, 469, 5, 47, 24, 2, 469, 470, 5, 43, 22, 2, 470, 471, 5, 23, 12, 2, 471, 102, 3, 2, 2, 2, 472, 473, 5, 37, 19, 2, 473, 474, 5, 35, 18, 2, 474, 475, 5, 37, 19, 2, 475, 104, 3, 2, 2, 2, 476, 477, 5, 15, 8, 2, 477, 478, 5, 9, 5, 2, 478, 479, 5, 15, 8, 2, 479, 106, 3, 2, 2, 2, 480, 481, 5, 25, 13, 2, 481, 482, 5, 33, 17, 2, 482, 483, 5, 53, 27, 2, 483, 108, 3, 2, 2, 2, 484, 485, 5, 15, 8, 2, 485, 486, 5, 13, 7, 2, 486, 487, 5, 53, 27, 2, 487, 110, 3, 2, 2, 2, 488, 489, 5, 53, 27, 2, 489, 490, 5, 13, 7, 2, 490, 491, 5, 23, 12, 2, 491, 492, 5, 21, 11, 2, 492, 112, 3, 2, 2, 2, 493, 494, 5, 53, 27, 2, 494, 495, 5, 45, 23, 2, 495, 496, 5, 23, 12, 2, 496, 497, 5, 29, 15, 2, 497, 114, 3, 2, 2, 2, 498, 499, 5, 43, 22, 2, 499, 500, 5, 37, 19, 2, 500, 501, 5, 23, 12, 2, 501, 502, 5, 29, 15, 2, 502, 116, 3, 2, 2, 2, 503, 504, 5, 29, 15, 2, 504, 505, 5, 53, 27, 2, 505, 506, 5, 25, 13, 2, 506, 118, 3, 2, 2, 2, 507, 508, 5, 31, 16, 2, 508, 509, 5, 49, 25, 2, 509, 510, 5, 25, 13, 2, 510, 120, 3, 2, 2, 2, 511, 512, 5, 9, 5, 2, 512, 513, 5, 15, 8, 2, 513, 514, 5, 25, 13, 2, 514, 122, 3, 2, 2, 2, 515, 516, 5, 9, 5, 2, 516, 517, 5, 13, 7, 2, 517, 518, 5, 25, 13, 2, 518, 124, 3, 2, 2, 2, 519, 520, 5, 43, 22, 2, 520, 521, 5, 47, 24, 2, 521, 522, 5, 25, 13, 2, 522, 126, 3, 2, 2, 2, 523, 524, 5, 43, 22, 2, 524, 525, 5, 11, 6, 2, 525, 526, 5, 25, 13, 2, 526, 128, 3, 2, 2, 2, 527, 528, 5, 9, 5, 2, 528, 529, 5, 33, 17, 2, 529, 530, 5, 25, 13, 2, 530, 130, 3, 2, 2, 2, 531, 532, 5, 53, 27, 2, 532, 533, 5, 41, 21, 2, 533, 534, 5, 25, 13, 2, 534, 132, 3, 2, 2, 2, 535, 536, 5, 35, 18, 2, 536, 537, 5, 41, 21, 2, 537, 538, 5, 25, 13, 2, 538, 134, 3, 2, 2, 2, 539, 540, 5, 13, 7, 2, 540, 541, 5, 37, 19, 2, 541, 542, 5, 25, 13, 2, 542, 136, 3, 2, 2, 2, 543, 544, 5, 43, 22, 2, 544, 545, 5, 45, 23, 2, 545, 546, 5, 9, 5, 2, 546, 138, 3, 2, 2, 2, 547, 548, 5, 29, 15, 2, 548, 549, 5, 15, 8, 2, 549, 550, 5, 9, 5, 2, 550, 140, 3, 2, 2, 2, 551, 552, 5, 43, 22, 2, 552, 553, 5, 23, 12, 2, 553, 554, 5, 29, 15, 2, 554, 555, 5, 15, 8, 2, 555, 142, 3, 2, 2, 2, 556, 557, 5, 29, 15, 2, 557, 558, 5, 23, 12, 2, 558, 559, 5, 29, 15, 2, 559, 560, 5, 15, 8, 2, 560, 144, 3, 2, 2, 2, 561, 562, 5, 37, 19, 2, 562, 563, 5, 13, 7, 2, 563, 564, 5, 23, 12, 2, 564, 565, 5, 29, 15, 2, 565, 146, 3, 2, 2, 2, 566, 567, 5, 27, 14, 2, 567, 568, 5, 31, 16, 2, 568, 569, 5, 37, 19, 2, 569, 148, 3, 2, 2, 2, 570, 571, 5, 27, 14, 2, 571, 572, 5, 13, 7, 2, 572, 150, 3, 2, 2, 2, 573, 574, 5, 27, 14, 2, 574, 575, 5, 33, 17, 2, 575, 576, 5, 13, 7, 2, 576, 152, 3, 2, 2, 2, 577, 578, 5, 27, 14, 2, 578, 579, 5, 55, 28, 2, 579, 154, 3, 2, 2, 2, 580, 581, 5, 27, 14, 2, 581, 582, 5, 33, 17, 2, 582, 583, 5, 55, 28, 2, 583, 156, 3, 2, 2, 2, 584, 585, 5, 27, 14, 2, 585, 586, 5, 37, 19, 2, 586, 158, 3, 2, 2, 2, 587, 588, 5, 27, 14, 2, 588, 589, 5, 31, 16, 2, 589, 160, 3, 2, 2, 2, 590, 591, 5, 27, 14, 2, 591, 592, 5, 37, 19, 2, 592, 593, 5, 17, 9, 2, 593, 162, 3, 2, 2, 2, 594, 595, 5, 27, 14, 2, 595, 596, 5, 37, 19, 2, 596, 597, 5, 35, 18, 2, 597, 164, 3, 2, 2, 2, 598, 599, 5, 13, 7, 2, 599, 600, 5, 9, 5, 2, 600, 601, 5, 29, 15, 2, 601, 602, 5, 29, 15, 2, 602, 166, 3, 2, 2, 2, 603, 604, 5, 13, 7, 2, 604, 605, 5, 13, 7, 2, 605, 168, 3, 2, 2, 2, 606, 607, 5, 13, 7, 2, 607, 608, 5, 33, 17, 2, 608, 609, 5, 13, 7, 2, 609, 170, 3, 2, 2, 2, 610, 611, 5, 13, 7, 2, 611, 612, 5, 55, 28, 2, 612, 172, 3, 2, 2, 2, 613, 614, 5, 13, 7, 2, 614, 615, 5, 33, 17, 2, 615, 616, 5, 55, 28, 2, 616, 174, 3, 2, 2, 2, 617, 618, 5, 13, 7, 2, 618, 619, 5, 37, 19, 2, 619, 176, 3, 2, 2, 2, 620, 621, 5, 13, 7, 2, 621, 622, 5, 31, 16, 2, 622, 178, 3, 2, 2, 2, 623, 624, 5, 13, 7, 2, 624, 625, 5, 37, 19, 2, 625, 626, 5, 17, 9, 2, 626, 180, 3, 2, 2, 2, 627, 628, 5, 13, 7, 2, 628, 629, 5, 37, 19, 2, 629, 630, 5, 35, 18, 2, 630, 182, 3, 2, 2, 2, 631, 632, 5, 41, 21, 2, 632, 633, 5, 17, 9, 2, 633, 634, 5, 45, 23, 2, 634, 184, 3, 2, 2, 2, 635, 636, 5, 41, 21, 2, 636, 637, 5, 13, 7, 2, 637, 186, 3, 2, 2, 2, 638, 639, 5, 41, 21, 2, 639, 640, 5, 33, 17, 2, 640, 641, 5, 13, 7, 2, 641, 188, 3, 2, 2, 2, 642, 643, 5, 41, 21, 2, 643, 644, 5, 55, 28, 2, 644, 190, 3, 2, 2, 2, 645, 646, 5, 41, 21, 2, 646, 647, 5, 33, 17, 2, 647, 648, 5, 55, 28, 2, 648, 192, 3, 2, 2, 2, 649, 650, 5, 41, 21, 2, 650, 651, 5, 31, 16, 2, 651, 194, 3, 2, 2, 2, 652, 653, 5, 41, 21, 2, 653, 654, 5, 37, 19, 2, 654, 196, 3, 2, 2, 2, 655, 656, 5, 41, 21, 2, 656, 657, 5, 37, 19, 2, 657, 658, 5, 17, 9, 2, 658, 198, 3, 2, 2, 2, 659, 660, 5, 41, 21, 2, 660, 661, 5, 37, 19, 2, 661, 662, 5, 35, 18, 2, 662, 200, 3, 2, 2, 2, 663, 664, 5, 41, 21, 2, 664, 665, 5, 43, 22, 2, 665, 666, 5, 45, 23, 2, 666, 202, 3, 2, 2, 2, 667, 668, 5, 17, 9, 2, 668, 669, 5, 25, 13, 2, 669, 204, 3, 2, 2, 2, 670, 671, 5, 15, 8, 2, 671, 672, 5, 25, 13, 2, 672, 206, 3, 2, 2, 2, 673, 674, 5, 25, 13, 2, 674, 675, 5, 33, 17, 2, 675, 208, 3, 2, 2, 2, 676, 677, 5, 35, 18, 2, 677, 678, 5, 47, 24, 2, 678, 679, 5, 45, 23, 2, 679, 210, 3, 2, 2, 2, 680, 681, 5, 23, 12, 2, 681, 682, 5, 29, 15, 2, 682, 683, 5, 45, 23, 2, 683, 212, 3, 2, 2, 2, 684, 685, 5, 35, 18, 2, 685, 686, 5, 41, 21, 2, 686, 687, 5, 21, 11, 2, 687, 214, 3, 2, 2, 2, 688, 689, 5, 17, 9, 2, 689, 690, 5, 39, 20, 2, 690, 691, 5, 47, 24, 2, 691, 216, 3, 2, 2, 2, 692, 693, 5, 43, 22, 2, 693, 694, 5, 17, 9, 2, 694, 695, 5, 45, 23, 2, 695, 218, 3, 2, 2, 2, 696, 697, 5, 25, 13, 2, 697, 698, 5, 33, 17, 2, 698, 699, 5, 13, 7, 2, 699, 700, 5, 29, 15, 2, 700, 701, 5, 47, 24, 2, 701, 702, 5, 15, 8, 2, 702, 703, 5, 17, 9, 2, 703, 220, 3, 2, 2, 2, 704, 705, 5, 25, 13, 2, 705, 706, 5, 19, 10, 2, 706, 222, 3, 2, 2, 2, 707, 708, 5, 17, 9, 2, 708, 709, 5, 33, 17, 2, 709, 710, 5, 15, 8, 2, 710, 711, 5, 25, 13, 2, 711, 712, 5, 19, 10, 2, 712, 224, 3, 2, 2, 2, 713, 714, 5, 31, 16, 2, 714, 715, 5, 9, 5, 2, 715, 716, 5, 13, 7, 2, 716, 717, 5, 41, 21, 2, 717, 718, 5, 35, 18, 2, 718, 226, 3, 2, 2, 2, 719, 720, 5, 17, 9, 2, 720, 721, 5, 33, 17, 2, 721, 722, 5, 15, 8, 2, 722, 723, 5, 31, 16, 2, 723, 228, 3, 2, 2, 2, 724, 725, 5, 15, 8, 2, 725, 726, 5, 11, 6, 2, 726, 230, 3, 2, 2, 2, 727, 728, 5, 15, 8, 2, 728, 729, 5, 51, 26, 2, 729, 232, 3, 2, 2, 2, 730, 731, 5, 15, 8, 2, 731, 732, 5, 43, 22, 2, 732, 234, 3, 2, 2, 2, 733, 734, 7, 38, 2, 2, 734, 236, 3, 2, 2, 2, 735, 736, 5, 9, 5, 2, 736, 238, 3, 2, 2, 2, 737, 738, 5, 11, 6, 2, 738, 240, 3, 2, 2, 2, 739, 740, 5, 13, 7, 2, 740, 242, 3, 2, 2, 2, 741, 742, 5, 15, 8, 2, 742, 244, 3, 2, 2, 2, 743, 744, 5, 17, 9, 2, 744, 246, 3, 2, 2, 2, 745, 746, 5, 23, 12, 2, 746, 248, 3, 2, 2, 2, 747, 748, 5, 29, 15, 2, 748, 250, 3, 2, 2, 2, 749, 750, 5, 31, 16, 2, 750, 252, 3, 2, 2, 2, 751, 752, 5, 37, 19, 2, 752, 753, 5, 43, 22, 2, 753, 754, 5, 51, 26, 2, 754, 254, 3, 2, 2, 2, 755, 756, 5, 43, 22, 2, 756, 757, 5, 37, 19, 2, 757, 256, 3, 2, 2, 2, 758, 759, 7, 42, 2, 2, 759, 258, 3, 2, 2, 2, 760, 761, 7, 43, 2, 2, 761, 260, 3, 2, 2, 2, 762, 763, 7, 46, 2, 2, 763, 262, 3, 2, 2, 2, 764, 765, 7, 45, 2, 2, 765, 264, 3, 2, 2, 2, 766, 767, 7, 47, 2, 2, 767, 266, 3, 2, 2, 2, 768, 769, 7, 44, 2, 2, 769, 268, 3, 2, 2, 2, 770, 771, 7, 49, 2, 2, 771, 270, 3, 2, 2, 2, 772, 773, 7, 63, 2, 2, 773, 272, 3, 2, 2, 2, 774, 775, 5, 31, 16, 2, 775, 776, 5, 35, 18, 2, 776, 777, 5, 15, 8, 2, 777, 274, 3, 2, 2, 2, 778, 779, 5, 43, 22, 2, 779, 780, 5, 23, 12, 2, 780, 781, 5, 41, 21, 2, 781, 276, 3, 2, 2, 2, 782, 783, 5, 43, 22, 2, 783, 784, 5, 23, 12, 2, 784, 785, 5, 29, 15, 2, 785, 278, 3, 2, 2, 2, 786, 787, 5, 33, 17, 2, 787, 788, 5, 35, 18, 2, 788, 789, 5, 45, 23, 2, 789, 280, 3, 2, 2, 2, 790, 791, 5, 9, 5, 2, 791, 792, 5, 33, 17, 2, 792, 793, 5, 15, 8, 2, 793, 282, 3, 2, 2, 2, 794, 795, 5, 35, 18, 2, 795, 796, 5, 41, 21, 2, 796, 284, 3, 2, 2, 2, 797, 798, 5, 53, 27, 2, 798, 799, 5, 35, 18, 2, 799, 800, 5, 41, 21, 2, 800, 286, 3, 2, 2, 2, 801, 803, 9, 29, 2, 2, 802, 801, 3, 2, 2, 2, 802, 803, 3, 2, 2, 2, 803, 805, 3, 2, 2, 2, 804, 806, 9, 30, 2, 2, 805, 804, 3, 2, 2, 2, 806, 807, 3, 2, 2, 2, 807, 805, 3, 2, 2, 2, 807, 808, 3, 2, 2, 2, 808, 810, 3, 2, 2, 2, 809, 811, 5, 15, 8, 2, 810, 809, 3, 2, 2, 2, 810, 811, 3, 2, 2, 2, 811, 288, 3, 2, 2, 2, 812, 814, 9, 29, 2, 2, 813, 812, 3, 2, 2, 2, 813, 814, 3, 2, 2, 2, 814, 815, 3, 2, 2, 2, 815, 816, 7, 50, 2, 2, 816, 818, 5, 53, 27, 2, 817, 819, 9, 31, 2, 2, 818, 817, 3, 2, 2, 2, 819, 820, 3, 2, 2, 2, 820, 818, 3, 2, 2, 2, 820, 821, 3, 2, 2, 2, 821, 290, 3, 2, 2, 2, 822, 824, 9, 29, 2, 2, 823, 822, 3, 2, 2, 2, 823, 824, 3, 2, 2, 2, 824, 826, 3, 2, 2, 2, 825, 827, 9, 31, 2, 2, 826, 825, 3, 2, 2, 2, 827, 828, 3, 2, 2, 2, 828, 826, 3, 2, 2, 2, 828, 829, 3, 2, 2, 2, 829, 830, 3, 2, 2, 2, 830, 831, 5, 23, 12, 2, 831, 292, 3, 2, 2, 2, 832, 834, 9, 29, 2, 2, 833, 832, 3, 2, 2, 2, 833, 834, 3, 2, 2, 2, 834, 836, 3, 2, 2, 2, 835, 837, 9, 32, 2, 2, 836, 835, 3, 2, 2, 2, 837, 838, 3, 2, 2, 2, 838, 836, 3, 2, 2, 2, 838, 839, 3, 2, 2, 2, 839, 840, 3, 2, 2, 2, 840, 841, 9, 33, 2, 2, 841, 294, 3, 2, 2, 2, 842, 844, 9, 34, 2, 2, 843, 842, 3, 2, 2, 2, 844, 845, 3, 2, 2, 2, 845, 843, 3, 2, 2, 2, 845, 846, 3, 2, 2, 2, 846, 847, 3, 2, 2, 2, 847, 848, 5, 11, 6, 2, 848, 296, 3, 2, 2, 2, 849, 851, 9, 35, 2, 2, 850, 852, 9, 36, 2, 2, 851, 850, 3, 2, 2, 2, 852, 853, 3, 2, 2, 2, 853, 851, 3, 2, 2, 2, 853, 854, 3, 2, 2, 2, 854, 855, 3, 2, 2, 2, 855, 856, 9, 35, 2, 2, 856, 298, 3, 2, 2, 2, 857, 859, 7, 36, 2, 2, 858, 860, 9, 37, 2, 2, 859, 858, 3, 2, 2, 2, 860, 861, 3, 2, 2, 2, 861, 859, 3, 2, 2, 2, 861, 862, 3, 2, 2, 2, 862, 863, 3, 2, 2, 2, 863, 864, 7, 36, 2, 2, 864, 300, 3, 2, 2, 2, 865, 869, 9, 38, 2, 2, 866, 868, 9, 39, 2, 2, 867, 866, 3, 2, 2, 2, 868, 871, 3, 2, 2, 2, 869, 867, 3, 2, 2, 2, 869, 870, 3, 2, 2, 2, 870, 302, 3, 2, 2, 2, 871, 869, 3, 2, 2, 2, 872, 876, 9, 38, 2, 2, 873, 875, 9, 39, 2, 2, 874, 873, 3, 2, 2, 2, 875, 878, 3, 2, 2, 2, 876, 874, 3, 2, 2, 2, 876, 877, 3, 2, 2, 2, 877, 879, 3, 2, 2, 2, 878, 876, 3, 2, 2, 2, 879, 880, 7, 60, 2, 2, 880, 304, 3, 2, 2, 2, 881, 882, 11, 2, 2, 2, 882, 306, 3, 2, 2, 2, 20, 2, 316, 321, 325, 802, 807, 810, 813, 820, 823, 828, 833, 838, 845, 853, 861, 869, 876, 3, 2, 3, 2] \ No newline at end of file diff --git a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.java b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.java deleted file mode 100644 index 36b10dbd5..000000000 --- a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.java +++ /dev/null @@ -1,504 +0,0 @@ -// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 by ANTLR 4.9.1 -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class As8080Lexer extends Lexer { - static { RuntimeMetaData.checkVersion("4.9.1", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - WS=1, COMMENT=2, EOL=3, OPCODE_STC=4, OPCODE_CMC=5, OPCODE_INR=6, OPCODE_DCR=7, - OPCODE_CMA=8, OPCODE_DAA=9, OPCODE_NOP=10, OPCODE_MOV=11, OPCODE_STAX=12, - OPCODE_LDAX=13, OPCODE_ADD=14, OPCODE_ADC=15, OPCODE_SUB=16, OPCODE_SBB=17, - OPCODE_ANA=18, OPCODE_XRA=19, OPCODE_ORA=20, OPCODE_CMP=21, OPCODE_RLC=22, - OPCODE_RRC=23, OPCODE_RAL=24, OPCODE_RAR=25, OPCODE_PUSH=26, OPCODE_POP=27, - OPCODE_DAD=28, OPCODE_INX=29, OPCODE_DCX=30, OPCODE_XCHG=31, OPCODE_XTHL=32, - OPCODE_SPHL=33, OPCODE_LXI=34, OPCODE_MVI=35, OPCODE_ADI=36, OPCODE_ACI=37, - OPCODE_SUI=38, OPCODE_SBI=39, OPCODE_ANI=40, OPCODE_XRI=41, OPCODE_ORI=42, - OPCODE_CPI=43, OPCODE_STA=44, OPCODE_LDA=45, OPCODE_SHLD=46, OPCODE_LHLD=47, - OPCODE_PCHL=48, OPCODE_JMP=49, OPCODE_JC=50, OPCODE_JNC=51, OPCODE_JZ=52, - OPCODE_JNZ=53, OPCODE_JP=54, OPCODE_JM=55, OPCODE_JPE=56, OPCODE_JPO=57, - OPCODE_CALL=58, OPCODE_CC=59, OPCODE_CNC=60, OPCODE_CZ=61, OPCODE_CNZ=62, - OPCODE_CP=63, OPCODE_CM=64, OPCODE_CPE=65, OPCODE_CPO=66, OPCODE_RET=67, - OPCODE_RC=68, OPCODE_RNC=69, OPCODE_RZ=70, OPCODE_RNZ=71, OPCODE_RM=72, - OPCODE_RP=73, OPCODE_RPE=74, OPCODE_RPO=75, OPCODE_RST=76, OPCODE_EI=77, - OPCODE_DI=78, OPCODE_IN=79, OPCODE_OUT=80, OPCODE_HLT=81, PREP_ORG=82, - PREP_EQU=83, PREP_SET=84, PREP_INCLUDE=85, PREP_IF=86, PREP_ENDIF=87, - PREP_MACRO=88, PREP_ENDM=89, PREP_DB=90, PREP_DW=91, PREP_DS=92, PREP_ADDR=93, - REG_A=94, REG_B=95, REG_C=96, REG_D=97, REG_E=98, REG_H=99, REG_L=100, - REG_M=101, REG_PSW=102, REG_SP=103, SEP_LPAR=104, SEP_RPAR=105, SEP_COMMA=106, - OP_ADD=107, OP_SUBTRACT=108, OP_MULTIPLY=109, OP_DIVIDE=110, OP_EQUAL=111, - OP_MOD=112, OP_SHR=113, OP_SHL=114, OP_NOT=115, OP_AND=116, OP_OR=117, - OP_XOR=118, LIT_NUMBER=119, LIT_HEXNUMBER_1=120, LIT_HEXNUMBER_2=121, - LIT_OCTNUMBER=122, LIT_BINNUMBER=123, LIT_STRING_1=124, LIT_STRING_2=125, - ID_IDENTIFIER=126, ID_LABEL=127, ERROR=128; - public static String[] channelNames = { - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }; - - public static String[] modeNames = { - "DEFAULT_MODE" - }; - - private static String[] makeRuleNames() { - return new String[] { - "WS", "COMMENT", "EOL", "A", "B", "C", "D", "E", "F", "G", "H", "I", - "J", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", - "Z", "OPCODE_STC", "OPCODE_CMC", "OPCODE_INR", "OPCODE_DCR", "OPCODE_CMA", - "OPCODE_DAA", "OPCODE_NOP", "OPCODE_MOV", "OPCODE_STAX", "OPCODE_LDAX", - "OPCODE_ADD", "OPCODE_ADC", "OPCODE_SUB", "OPCODE_SBB", "OPCODE_ANA", - "OPCODE_XRA", "OPCODE_ORA", "OPCODE_CMP", "OPCODE_RLC", "OPCODE_RRC", - "OPCODE_RAL", "OPCODE_RAR", "OPCODE_PUSH", "OPCODE_POP", "OPCODE_DAD", - "OPCODE_INX", "OPCODE_DCX", "OPCODE_XCHG", "OPCODE_XTHL", "OPCODE_SPHL", - "OPCODE_LXI", "OPCODE_MVI", "OPCODE_ADI", "OPCODE_ACI", "OPCODE_SUI", - "OPCODE_SBI", "OPCODE_ANI", "OPCODE_XRI", "OPCODE_ORI", "OPCODE_CPI", - "OPCODE_STA", "OPCODE_LDA", "OPCODE_SHLD", "OPCODE_LHLD", "OPCODE_PCHL", - "OPCODE_JMP", "OPCODE_JC", "OPCODE_JNC", "OPCODE_JZ", "OPCODE_JNZ", "OPCODE_JP", - "OPCODE_JM", "OPCODE_JPE", "OPCODE_JPO", "OPCODE_CALL", "OPCODE_CC", - "OPCODE_CNC", "OPCODE_CZ", "OPCODE_CNZ", "OPCODE_CP", "OPCODE_CM", "OPCODE_CPE", - "OPCODE_CPO", "OPCODE_RET", "OPCODE_RC", "OPCODE_RNC", "OPCODE_RZ", "OPCODE_RNZ", - "OPCODE_RM", "OPCODE_RP", "OPCODE_RPE", "OPCODE_RPO", "OPCODE_RST", "OPCODE_EI", - "OPCODE_DI", "OPCODE_IN", "OPCODE_OUT", "OPCODE_HLT", "PREP_ORG", "PREP_EQU", - "PREP_SET", "PREP_INCLUDE", "PREP_IF", "PREP_ENDIF", "PREP_MACRO", "PREP_ENDM", - "PREP_DB", "PREP_DW", "PREP_DS", "PREP_ADDR", "REG_A", "REG_B", "REG_C", - "REG_D", "REG_E", "REG_H", "REG_L", "REG_M", "REG_PSW", "REG_SP", "SEP_LPAR", - "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE", - "OP_EQUAL", "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", - "OP_XOR", "LIT_NUMBER", "LIT_HEXNUMBER_1", "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", - "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", - "ERROR" - }; - } - public static final String[] ruleNames = makeRuleNames(); - - private static String[] makeLiteralNames() { - return new String[] { - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, "'$'", null, null, - null, null, null, null, null, null, null, null, "'('", "')'", "','", - "'+'", "'-'", "'*'", "'/'", "'='" - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - null, "WS", "COMMENT", "EOL", "OPCODE_STC", "OPCODE_CMC", "OPCODE_INR", - "OPCODE_DCR", "OPCODE_CMA", "OPCODE_DAA", "OPCODE_NOP", "OPCODE_MOV", - "OPCODE_STAX", "OPCODE_LDAX", "OPCODE_ADD", "OPCODE_ADC", "OPCODE_SUB", - "OPCODE_SBB", "OPCODE_ANA", "OPCODE_XRA", "OPCODE_ORA", "OPCODE_CMP", - "OPCODE_RLC", "OPCODE_RRC", "OPCODE_RAL", "OPCODE_RAR", "OPCODE_PUSH", - "OPCODE_POP", "OPCODE_DAD", "OPCODE_INX", "OPCODE_DCX", "OPCODE_XCHG", - "OPCODE_XTHL", "OPCODE_SPHL", "OPCODE_LXI", "OPCODE_MVI", "OPCODE_ADI", - "OPCODE_ACI", "OPCODE_SUI", "OPCODE_SBI", "OPCODE_ANI", "OPCODE_XRI", - "OPCODE_ORI", "OPCODE_CPI", "OPCODE_STA", "OPCODE_LDA", "OPCODE_SHLD", - "OPCODE_LHLD", "OPCODE_PCHL", "OPCODE_JMP", "OPCODE_JC", "OPCODE_JNC", - "OPCODE_JZ", "OPCODE_JNZ", "OPCODE_JP", "OPCODE_JM", "OPCODE_JPE", "OPCODE_JPO", - "OPCODE_CALL", "OPCODE_CC", "OPCODE_CNC", "OPCODE_CZ", "OPCODE_CNZ", - "OPCODE_CP", "OPCODE_CM", "OPCODE_CPE", "OPCODE_CPO", "OPCODE_RET", "OPCODE_RC", - "OPCODE_RNC", "OPCODE_RZ", "OPCODE_RNZ", "OPCODE_RM", "OPCODE_RP", "OPCODE_RPE", - "OPCODE_RPO", "OPCODE_RST", "OPCODE_EI", "OPCODE_DI", "OPCODE_IN", "OPCODE_OUT", - "OPCODE_HLT", "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_INCLUDE", "PREP_IF", - "PREP_ENDIF", "PREP_MACRO", "PREP_ENDM", "PREP_DB", "PREP_DW", "PREP_DS", - "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", "REG_E", "REG_H", "REG_L", - "REG_M", "REG_PSW", "REG_SP", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", - "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_MOD", "OP_SHR", - "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", "OP_XOR", "LIT_NUMBER", "LIT_HEXNUMBER_1", - "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", "LIT_BINNUMBER", "LIT_STRING_1", - "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", "ERROR" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - - public As8080Lexer(CharStream input) { - super(input); - _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - @Override - public String getGrammarFileName() { return "As8080Lexer.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public String[] getChannelNames() { return channelNames; } - - @Override - public String[] getModeNames() { return modeNames; } - - @Override - public ATN getATN() { return _ATN; } - - public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u0082\u0373\b\1\4"+ - "\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n"+ - "\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ - "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+ - "\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t"+ - " \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t"+ - "+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64"+ - "\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t"+ - "=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4"+ - "I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\t"+ - "T\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_"+ - "\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k"+ - "\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv"+ - "\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080\t"+ - "\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084"+ - "\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089"+ - "\t\u0089\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c\t\u008c\4\u008d\t\u008d"+ - "\4\u008e\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090\4\u0091\t\u0091\4\u0092"+ - "\t\u0092\4\u0093\t\u0093\4\u0094\t\u0094\4\u0095\t\u0095\4\u0096\t\u0096"+ - "\4\u0097\t\u0097\4\u0098\t\u0098\4\u0099\t\u0099\3\2\3\2\3\2\3\2\3\3\3"+ - "\3\3\3\3\3\3\3\5\3\u013d\n\3\3\3\7\3\u0140\n\3\f\3\16\3\u0143\13\3\3\4"+ - "\5\4\u0146\n\4\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n"+ - "\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3\22"+ - "\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\31"+ - "\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36"+ - "\3\36\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3!\3\"\3\"\3\"\3\"\3#\3"+ - "#\3#\3#\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3(\3"+ - "(\3(\3(\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3+\3+\3,\3,\3,\3,\3-\3-\3-\3-\3"+ - ".\3.\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\61\3\61\3\61\3\61\3\62\3"+ - "\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\65\3\65\3"+ - "\65\3\65\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\38\38\38\38\38\39\39"+ - "\39\39\39\3:\3:\3:\3:\3:\3;\3;\3;\3;\3<\3<\3<\3<\3=\3=\3=\3=\3>\3>\3>"+ - "\3>\3?\3?\3?\3?\3@\3@\3@\3@\3A\3A\3A\3A\3B\3B\3B\3B\3C\3C\3C\3C\3D\3D"+ - "\3D\3D\3E\3E\3E\3E\3F\3F\3F\3F\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3I"+ - "\3I\3I\3J\3J\3J\3J\3K\3K\3K\3L\3L\3L\3L\3M\3M\3M\3N\3N\3N\3N\3O\3O\3O"+ - "\3P\3P\3P\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3S\3S\3S\3S\3S\3T\3T\3T\3U\3U\3U\3U"+ - "\3V\3V\3V\3W\3W\3W\3W\3X\3X\3X\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3\\\3"+ - "\\\3\\\3\\\3]\3]\3]\3^\3^\3^\3^\3_\3_\3_\3`\3`\3`\3`\3a\3a\3a\3b\3b\3"+ - "b\3c\3c\3c\3c\3d\3d\3d\3d\3e\3e\3e\3e\3f\3f\3f\3g\3g\3g\3h\3h\3h\3i\3"+ - "i\3i\3i\3j\3j\3j\3j\3k\3k\3k\3k\3l\3l\3l\3l\3m\3m\3m\3m\3n\3n\3n\3n\3"+ - "n\3n\3n\3n\3o\3o\3o\3p\3p\3p\3p\3p\3p\3q\3q\3q\3q\3q\3q\3r\3r\3r\3r\3"+ - "r\3s\3s\3s\3t\3t\3t\3u\3u\3u\3v\3v\3w\3w\3x\3x\3y\3y\3z\3z\3{\3{\3|\3"+ - "|\3}\3}\3~\3~\3\177\3\177\3\177\3\177\3\u0080\3\u0080\3\u0080\3\u0081"+ - "\3\u0081\3\u0082\3\u0082\3\u0083\3\u0083\3\u0084\3\u0084\3\u0085\3\u0085"+ - "\3\u0086\3\u0086\3\u0087\3\u0087\3\u0088\3\u0088\3\u0089\3\u0089\3\u0089"+ - "\3\u0089\3\u008a\3\u008a\3\u008a\3\u008a\3\u008b\3\u008b\3\u008b\3\u008b"+ - "\3\u008c\3\u008c\3\u008c\3\u008c\3\u008d\3\u008d\3\u008d\3\u008d\3\u008e"+ - "\3\u008e\3\u008e\3\u008f\3\u008f\3\u008f\3\u008f\3\u0090\5\u0090\u0323"+ - "\n\u0090\3\u0090\6\u0090\u0326\n\u0090\r\u0090\16\u0090\u0327\3\u0090"+ - "\5\u0090\u032b\n\u0090\3\u0091\5\u0091\u032e\n\u0091\3\u0091\3\u0091\3"+ - "\u0091\6\u0091\u0333\n\u0091\r\u0091\16\u0091\u0334\3\u0092\5\u0092\u0338"+ - "\n\u0092\3\u0092\6\u0092\u033b\n\u0092\r\u0092\16\u0092\u033c\3\u0092"+ - "\3\u0092\3\u0093\5\u0093\u0342\n\u0093\3\u0093\6\u0093\u0345\n\u0093\r"+ - "\u0093\16\u0093\u0346\3\u0093\3\u0093\3\u0094\6\u0094\u034c\n\u0094\r"+ - "\u0094\16\u0094\u034d\3\u0094\3\u0094\3\u0095\3\u0095\6\u0095\u0354\n"+ - "\u0095\r\u0095\16\u0095\u0355\3\u0095\3\u0095\3\u0096\3\u0096\6\u0096"+ - "\u035c\n\u0096\r\u0096\16\u0096\u035d\3\u0096\3\u0096\3\u0097\3\u0097"+ - "\7\u0097\u0364\n\u0097\f\u0097\16\u0097\u0367\13\u0097\3\u0098\3\u0098"+ - "\7\u0098\u036b\n\u0098\f\u0098\16\u0098\u036e\13\u0098\3\u0098\3\u0098"+ - "\3\u0099\3\u0099\2\2\u009a\3\3\5\4\7\5\t\2\13\2\r\2\17\2\21\2\23\2\25"+ - "\2\27\2\31\2\33\2\35\2\37\2!\2#\2%\2\'\2)\2+\2-\2/\2\61\2\63\2\65\2\67"+ - "\29\6;\7=\b?\tA\nC\13E\fG\rI\16K\17M\20O\21Q\22S\23U\24W\25Y\26[\27]\30"+ - "_\31a\32c\33e\34g\35i\36k\37m o!q\"s#u$w%y&{\'}(\177)\u0081*\u0083+\u0085"+ - ",\u0087-\u0089.\u008b/\u008d\60\u008f\61\u0091\62\u0093\63\u0095\64\u0097"+ - "\65\u0099\66\u009b\67\u009d8\u009f9\u00a1:\u00a3;\u00a5<\u00a7=\u00a9"+ - ">\u00ab?\u00ad@\u00afA\u00b1B\u00b3C\u00b5D\u00b7E\u00b9F\u00bbG\u00bd"+ - "H\u00bfI\u00c1J\u00c3K\u00c5L\u00c7M\u00c9N\u00cbO\u00cdP\u00cfQ\u00d1"+ - "R\u00d3S\u00d5T\u00d7U\u00d9V\u00dbW\u00ddX\u00dfY\u00e1Z\u00e3[\u00e5"+ - "\\\u00e7]\u00e9^\u00eb_\u00ed`\u00efa\u00f1b\u00f3c\u00f5d\u00f7e\u00f9"+ - "f\u00fbg\u00fdh\u00ffi\u0101j\u0103k\u0105l\u0107m\u0109n\u010bo\u010d"+ - "p\u010fq\u0111r\u0113s\u0115t\u0117u\u0119v\u011bw\u011dx\u011fy\u0121"+ - "z\u0123{\u0125|\u0127}\u0129~\u012b\177\u012d\u0080\u012f\u0081\u0131"+ - "\u0082\3\2(\5\2\13\13\16\16\"\"\4\2%%==\4\2\f\f\17\17\4\2CCcc\4\2DDdd"+ - "\4\2EEee\4\2FFff\4\2GGgg\4\2HHhh\4\2IIii\4\2JJjj\4\2KKkk\4\2LLll\4\2N"+ - "Nnn\4\2OOoo\4\2PPpp\4\2QQqq\4\2RRrr\4\2SSss\4\2TTtt\4\2UUuu\4\2VVvv\4"+ - "\2WWww\4\2XXxx\4\2YYyy\4\2ZZzz\4\2\\\\||\3\2//\3\2\62;\5\2\62;CHch\3\2"+ - "\629\6\2QQSSqqss\3\2\62\63\3\2))\4\2))``\4\2$$``\5\2A\\aac|\6\2\62;A\\"+ - "aac|\2\u036c\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\29\3\2\2\2\2;\3\2\2\2"+ - "\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I"+ - "\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2"+ - "\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2"+ - "\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o"+ - "\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2"+ - "\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085"+ - "\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2"+ - "\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097"+ - "\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2"+ - "\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9"+ - "\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2"+ - "\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb"+ - "\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2"+ - "\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd"+ - "\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2"+ - "\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df"+ - "\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2"+ - "\2\2\u00e9\3\2\2\2\2\u00eb\3\2\2\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1"+ - "\3\2\2\2\2\u00f3\3\2\2\2\2\u00f5\3\2\2\2\2\u00f7\3\2\2\2\2\u00f9\3\2\2"+ - "\2\2\u00fb\3\2\2\2\2\u00fd\3\2\2\2\2\u00ff\3\2\2\2\2\u0101\3\2\2\2\2\u0103"+ - "\3\2\2\2\2\u0105\3\2\2\2\2\u0107\3\2\2\2\2\u0109\3\2\2\2\2\u010b\3\2\2"+ - "\2\2\u010d\3\2\2\2\2\u010f\3\2\2\2\2\u0111\3\2\2\2\2\u0113\3\2\2\2\2\u0115"+ - "\3\2\2\2\2\u0117\3\2\2\2\2\u0119\3\2\2\2\2\u011b\3\2\2\2\2\u011d\3\2\2"+ - "\2\2\u011f\3\2\2\2\2\u0121\3\2\2\2\2\u0123\3\2\2\2\2\u0125\3\2\2\2\2\u0127"+ - "\3\2\2\2\2\u0129\3\2\2\2\2\u012b\3\2\2\2\2\u012d\3\2\2\2\2\u012f\3\2\2"+ - "\2\2\u0131\3\2\2\2\3\u0133\3\2\2\2\5\u013c\3\2\2\2\7\u0145\3\2\2\2\t\u0149"+ - "\3\2\2\2\13\u014b\3\2\2\2\r\u014d\3\2\2\2\17\u014f\3\2\2\2\21\u0151\3"+ - "\2\2\2\23\u0153\3\2\2\2\25\u0155\3\2\2\2\27\u0157\3\2\2\2\31\u0159\3\2"+ - "\2\2\33\u015b\3\2\2\2\35\u015d\3\2\2\2\37\u015f\3\2\2\2!\u0161\3\2\2\2"+ - "#\u0163\3\2\2\2%\u0165\3\2\2\2\'\u0167\3\2\2\2)\u0169\3\2\2\2+\u016b\3"+ - "\2\2\2-\u016d\3\2\2\2/\u016f\3\2\2\2\61\u0171\3\2\2\2\63\u0173\3\2\2\2"+ - "\65\u0175\3\2\2\2\67\u0177\3\2\2\29\u0179\3\2\2\2;\u017d\3\2\2\2=\u0181"+ - "\3\2\2\2?\u0185\3\2\2\2A\u0189\3\2\2\2C\u018d\3\2\2\2E\u0191\3\2\2\2G"+ - "\u0195\3\2\2\2I\u0199\3\2\2\2K\u019e\3\2\2\2M\u01a3\3\2\2\2O\u01a7\3\2"+ - "\2\2Q\u01ab\3\2\2\2S\u01af\3\2\2\2U\u01b3\3\2\2\2W\u01b7\3\2\2\2Y\u01bb"+ - "\3\2\2\2[\u01bf\3\2\2\2]\u01c3\3\2\2\2_\u01c7\3\2\2\2a\u01cb\3\2\2\2c"+ - "\u01cf\3\2\2\2e\u01d3\3\2\2\2g\u01d8\3\2\2\2i\u01dc\3\2\2\2k\u01e0\3\2"+ - "\2\2m\u01e4\3\2\2\2o\u01e8\3\2\2\2q\u01ed\3\2\2\2s\u01f2\3\2\2\2u\u01f7"+ - "\3\2\2\2w\u01fb\3\2\2\2y\u01ff\3\2\2\2{\u0203\3\2\2\2}\u0207\3\2\2\2\177"+ - "\u020b\3\2\2\2\u0081\u020f\3\2\2\2\u0083\u0213\3\2\2\2\u0085\u0217\3\2"+ - "\2\2\u0087\u021b\3\2\2\2\u0089\u021f\3\2\2\2\u008b\u0223\3\2\2\2\u008d"+ - "\u0227\3\2\2\2\u008f\u022c\3\2\2\2\u0091\u0231\3\2\2\2\u0093\u0236\3\2"+ - "\2\2\u0095\u023a\3\2\2\2\u0097\u023d\3\2\2\2\u0099\u0241\3\2\2\2\u009b"+ - "\u0244\3\2\2\2\u009d\u0248\3\2\2\2\u009f\u024b\3\2\2\2\u00a1\u024e\3\2"+ - "\2\2\u00a3\u0252\3\2\2\2\u00a5\u0256\3\2\2\2\u00a7\u025b\3\2\2\2\u00a9"+ - "\u025e\3\2\2\2\u00ab\u0262\3\2\2\2\u00ad\u0265\3\2\2\2\u00af\u0269\3\2"+ - "\2\2\u00b1\u026c\3\2\2\2\u00b3\u026f\3\2\2\2\u00b5\u0273\3\2\2\2\u00b7"+ - "\u0277\3\2\2\2\u00b9\u027b\3\2\2\2\u00bb\u027e\3\2\2\2\u00bd\u0282\3\2"+ - "\2\2\u00bf\u0285\3\2\2\2\u00c1\u0289\3\2\2\2\u00c3\u028c\3\2\2\2\u00c5"+ - "\u028f\3\2\2\2\u00c7\u0293\3\2\2\2\u00c9\u0297\3\2\2\2\u00cb\u029b\3\2"+ - "\2\2\u00cd\u029e\3\2\2\2\u00cf\u02a1\3\2\2\2\u00d1\u02a4\3\2\2\2\u00d3"+ - "\u02a8\3\2\2\2\u00d5\u02ac\3\2\2\2\u00d7\u02b0\3\2\2\2\u00d9\u02b4\3\2"+ - "\2\2\u00db\u02b8\3\2\2\2\u00dd\u02c0\3\2\2\2\u00df\u02c3\3\2\2\2\u00e1"+ - "\u02c9\3\2\2\2\u00e3\u02cf\3\2\2\2\u00e5\u02d4\3\2\2\2\u00e7\u02d7\3\2"+ - "\2\2\u00e9\u02da\3\2\2\2\u00eb\u02dd\3\2\2\2\u00ed\u02df\3\2\2\2\u00ef"+ - "\u02e1\3\2\2\2\u00f1\u02e3\3\2\2\2\u00f3\u02e5\3\2\2\2\u00f5\u02e7\3\2"+ - "\2\2\u00f7\u02e9\3\2\2\2\u00f9\u02eb\3\2\2\2\u00fb\u02ed\3\2\2\2\u00fd"+ - "\u02ef\3\2\2\2\u00ff\u02f3\3\2\2\2\u0101\u02f6\3\2\2\2\u0103\u02f8\3\2"+ - "\2\2\u0105\u02fa\3\2\2\2\u0107\u02fc\3\2\2\2\u0109\u02fe\3\2\2\2\u010b"+ - "\u0300\3\2\2\2\u010d\u0302\3\2\2\2\u010f\u0304\3\2\2\2\u0111\u0306\3\2"+ - "\2\2\u0113\u030a\3\2\2\2\u0115\u030e\3\2\2\2\u0117\u0312\3\2\2\2\u0119"+ - "\u0316\3\2\2\2\u011b\u031a\3\2\2\2\u011d\u031d\3\2\2\2\u011f\u0322\3\2"+ - "\2\2\u0121\u032d\3\2\2\2\u0123\u0337\3\2\2\2\u0125\u0341\3\2\2\2\u0127"+ - "\u034b\3\2\2\2\u0129\u0351\3\2\2\2\u012b\u0359\3\2\2\2\u012d\u0361\3\2"+ - "\2\2\u012f\u0368\3\2\2\2\u0131\u0371\3\2\2\2\u0133\u0134\t\2\2\2\u0134"+ - "\u0135\3\2\2\2\u0135\u0136\b\2\2\2\u0136\4\3\2\2\2\u0137\u0138\7\61\2"+ - "\2\u0138\u013d\7\61\2\2\u0139\u013a\7/\2\2\u013a\u013d\7/\2\2\u013b\u013d"+ - "\t\3\2\2\u013c\u0137\3\2\2\2\u013c\u0139\3\2\2\2\u013c\u013b\3\2\2\2\u013d"+ - "\u0141\3\2\2\2\u013e\u0140\n\4\2\2\u013f\u013e\3\2\2\2\u0140\u0143\3\2"+ - "\2\2\u0141\u013f\3\2\2\2\u0141\u0142\3\2\2\2\u0142\6\3\2\2\2\u0143\u0141"+ - "\3\2\2\2\u0144\u0146\7\17\2\2\u0145\u0144\3\2\2\2\u0145\u0146\3\2\2\2"+ - "\u0146\u0147\3\2\2\2\u0147\u0148\7\f\2\2\u0148\b\3\2\2\2\u0149\u014a\t"+ - "\5\2\2\u014a\n\3\2\2\2\u014b\u014c\t\6\2\2\u014c\f\3\2\2\2\u014d\u014e"+ - "\t\7\2\2\u014e\16\3\2\2\2\u014f\u0150\t\b\2\2\u0150\20\3\2\2\2\u0151\u0152"+ - "\t\t\2\2\u0152\22\3\2\2\2\u0153\u0154\t\n\2\2\u0154\24\3\2\2\2\u0155\u0156"+ - "\t\13\2\2\u0156\26\3\2\2\2\u0157\u0158\t\f\2\2\u0158\30\3\2\2\2\u0159"+ - "\u015a\t\r\2\2\u015a\32\3\2\2\2\u015b\u015c\t\16\2\2\u015c\34\3\2\2\2"+ - "\u015d\u015e\t\17\2\2\u015e\36\3\2\2\2\u015f\u0160\t\20\2\2\u0160 \3\2"+ - "\2\2\u0161\u0162\t\21\2\2\u0162\"\3\2\2\2\u0163\u0164\t\22\2\2\u0164$"+ - "\3\2\2\2\u0165\u0166\t\23\2\2\u0166&\3\2\2\2\u0167\u0168\t\24\2\2\u0168"+ - "(\3\2\2\2\u0169\u016a\t\25\2\2\u016a*\3\2\2\2\u016b\u016c\t\26\2\2\u016c"+ - ",\3\2\2\2\u016d\u016e\t\27\2\2\u016e.\3\2\2\2\u016f\u0170\t\30\2\2\u0170"+ - "\60\3\2\2\2\u0171\u0172\t\31\2\2\u0172\62\3\2\2\2\u0173\u0174\t\32\2\2"+ - "\u0174\64\3\2\2\2\u0175\u0176\t\33\2\2\u0176\66\3\2\2\2\u0177\u0178\t"+ - "\34\2\2\u01788\3\2\2\2\u0179\u017a\5+\26\2\u017a\u017b\5-\27\2\u017b\u017c"+ - "\5\r\7\2\u017c:\3\2\2\2\u017d\u017e\5\r\7\2\u017e\u017f\5\37\20\2\u017f"+ - "\u0180\5\r\7\2\u0180<\3\2\2\2\u0181\u0182\5\31\r\2\u0182\u0183\5!\21\2"+ - "\u0183\u0184\5)\25\2\u0184>\3\2\2\2\u0185\u0186\5\17\b\2\u0186\u0187\5"+ - "\r\7\2\u0187\u0188\5)\25\2\u0188@\3\2\2\2\u0189\u018a\5\r\7\2\u018a\u018b"+ - "\5\37\20\2\u018b\u018c\5\t\5\2\u018cB\3\2\2\2\u018d\u018e\5\17\b\2\u018e"+ - "\u018f\5\t\5\2\u018f\u0190\5\t\5\2\u0190D\3\2\2\2\u0191\u0192\5!\21\2"+ - "\u0192\u0193\5#\22\2\u0193\u0194\5%\23\2\u0194F\3\2\2\2\u0195\u0196\5"+ - "\37\20\2\u0196\u0197\5#\22\2\u0197\u0198\5\61\31\2\u0198H\3\2\2\2\u0199"+ - "\u019a\5+\26\2\u019a\u019b\5-\27\2\u019b\u019c\5\t\5\2\u019c\u019d\5\65"+ - "\33\2\u019dJ\3\2\2\2\u019e\u019f\5\35\17\2\u019f\u01a0\5\17\b\2\u01a0"+ - "\u01a1\5\t\5\2\u01a1\u01a2\5\65\33\2\u01a2L\3\2\2\2\u01a3\u01a4\5\t\5"+ - "\2\u01a4\u01a5\5\17\b\2\u01a5\u01a6\5\17\b\2\u01a6N\3\2\2\2\u01a7\u01a8"+ - "\5\t\5\2\u01a8\u01a9\5\17\b\2\u01a9\u01aa\5\r\7\2\u01aaP\3\2\2\2\u01ab"+ - "\u01ac\5+\26\2\u01ac\u01ad\5/\30\2\u01ad\u01ae\5\13\6\2\u01aeR\3\2\2\2"+ - "\u01af\u01b0\5+\26\2\u01b0\u01b1\5\13\6\2\u01b1\u01b2\5\13\6\2\u01b2T"+ - "\3\2\2\2\u01b3\u01b4\5\t\5\2\u01b4\u01b5\5!\21\2\u01b5\u01b6\5\t\5\2\u01b6"+ - "V\3\2\2\2\u01b7\u01b8\5\65\33\2\u01b8\u01b9\5)\25\2\u01b9\u01ba\5\t\5"+ - "\2\u01baX\3\2\2\2\u01bb\u01bc\5#\22\2\u01bc\u01bd\5)\25\2\u01bd\u01be"+ - "\5\t\5\2\u01beZ\3\2\2\2\u01bf\u01c0\5\r\7\2\u01c0\u01c1\5\37\20\2\u01c1"+ - "\u01c2\5%\23\2\u01c2\\\3\2\2\2\u01c3\u01c4\5)\25\2\u01c4\u01c5\5\35\17"+ - "\2\u01c5\u01c6\5\r\7\2\u01c6^\3\2\2\2\u01c7\u01c8\5)\25\2\u01c8\u01c9"+ - "\5)\25\2\u01c9\u01ca\5\r\7\2\u01ca`\3\2\2\2\u01cb\u01cc\5)\25\2\u01cc"+ - "\u01cd\5\t\5\2\u01cd\u01ce\5\35\17\2\u01ceb\3\2\2\2\u01cf\u01d0\5)\25"+ - "\2\u01d0\u01d1\5\t\5\2\u01d1\u01d2\5)\25\2\u01d2d\3\2\2\2\u01d3\u01d4"+ - "\5%\23\2\u01d4\u01d5\5/\30\2\u01d5\u01d6\5+\26\2\u01d6\u01d7\5\27\f\2"+ - "\u01d7f\3\2\2\2\u01d8\u01d9\5%\23\2\u01d9\u01da\5#\22\2\u01da\u01db\5"+ - "%\23\2\u01dbh\3\2\2\2\u01dc\u01dd\5\17\b\2\u01dd\u01de\5\t\5\2\u01de\u01df"+ - "\5\17\b\2\u01dfj\3\2\2\2\u01e0\u01e1\5\31\r\2\u01e1\u01e2\5!\21\2\u01e2"+ - "\u01e3\5\65\33\2\u01e3l\3\2\2\2\u01e4\u01e5\5\17\b\2\u01e5\u01e6\5\r\7"+ - "\2\u01e6\u01e7\5\65\33\2\u01e7n\3\2\2\2\u01e8\u01e9\5\65\33\2\u01e9\u01ea"+ - "\5\r\7\2\u01ea\u01eb\5\27\f\2\u01eb\u01ec\5\25\13\2\u01ecp\3\2\2\2\u01ed"+ - "\u01ee\5\65\33\2\u01ee\u01ef\5-\27\2\u01ef\u01f0\5\27\f\2\u01f0\u01f1"+ - "\5\35\17\2\u01f1r\3\2\2\2\u01f2\u01f3\5+\26\2\u01f3\u01f4\5%\23\2\u01f4"+ - "\u01f5\5\27\f\2\u01f5\u01f6\5\35\17\2\u01f6t\3\2\2\2\u01f7\u01f8\5\35"+ - "\17\2\u01f8\u01f9\5\65\33\2\u01f9\u01fa\5\31\r\2\u01fav\3\2\2\2\u01fb"+ - "\u01fc\5\37\20\2\u01fc\u01fd\5\61\31\2\u01fd\u01fe\5\31\r\2\u01fex\3\2"+ - "\2\2\u01ff\u0200\5\t\5\2\u0200\u0201\5\17\b\2\u0201\u0202\5\31\r\2\u0202"+ - "z\3\2\2\2\u0203\u0204\5\t\5\2\u0204\u0205\5\r\7\2\u0205\u0206\5\31\r\2"+ - "\u0206|\3\2\2\2\u0207\u0208\5+\26\2\u0208\u0209\5/\30\2\u0209\u020a\5"+ - "\31\r\2\u020a~\3\2\2\2\u020b\u020c\5+\26\2\u020c\u020d\5\13\6\2\u020d"+ - "\u020e\5\31\r\2\u020e\u0080\3\2\2\2\u020f\u0210\5\t\5\2\u0210\u0211\5"+ - "!\21\2\u0211\u0212\5\31\r\2\u0212\u0082\3\2\2\2\u0213\u0214\5\65\33\2"+ - "\u0214\u0215\5)\25\2\u0215\u0216\5\31\r\2\u0216\u0084\3\2\2\2\u0217\u0218"+ - "\5#\22\2\u0218\u0219\5)\25\2\u0219\u021a\5\31\r\2\u021a\u0086\3\2\2\2"+ - "\u021b\u021c\5\r\7\2\u021c\u021d\5%\23\2\u021d\u021e\5\31\r\2\u021e\u0088"+ - "\3\2\2\2\u021f\u0220\5+\26\2\u0220\u0221\5-\27\2\u0221\u0222\5\t\5\2\u0222"+ - "\u008a\3\2\2\2\u0223\u0224\5\35\17\2\u0224\u0225\5\17\b\2\u0225\u0226"+ - "\5\t\5\2\u0226\u008c\3\2\2\2\u0227\u0228\5+\26\2\u0228\u0229\5\27\f\2"+ - "\u0229\u022a\5\35\17\2\u022a\u022b\5\17\b\2\u022b\u008e\3\2\2\2\u022c"+ - "\u022d\5\35\17\2\u022d\u022e\5\27\f\2\u022e\u022f\5\35\17\2\u022f\u0230"+ - "\5\17\b\2\u0230\u0090\3\2\2\2\u0231\u0232\5%\23\2\u0232\u0233\5\r\7\2"+ - "\u0233\u0234\5\27\f\2\u0234\u0235\5\35\17\2\u0235\u0092\3\2\2\2\u0236"+ - "\u0237\5\33\16\2\u0237\u0238\5\37\20\2\u0238\u0239\5%\23\2\u0239\u0094"+ - "\3\2\2\2\u023a\u023b\5\33\16\2\u023b\u023c\5\r\7\2\u023c\u0096\3\2\2\2"+ - "\u023d\u023e\5\33\16\2\u023e\u023f\5!\21\2\u023f\u0240\5\r\7\2\u0240\u0098"+ - "\3\2\2\2\u0241\u0242\5\33\16\2\u0242\u0243\5\67\34\2\u0243\u009a\3\2\2"+ - "\2\u0244\u0245\5\33\16\2\u0245\u0246\5!\21\2\u0246\u0247\5\67\34\2\u0247"+ - "\u009c\3\2\2\2\u0248\u0249\5\33\16\2\u0249\u024a\5%\23\2\u024a\u009e\3"+ - "\2\2\2\u024b\u024c\5\33\16\2\u024c\u024d\5\37\20\2\u024d\u00a0\3\2\2\2"+ - "\u024e\u024f\5\33\16\2\u024f\u0250\5%\23\2\u0250\u0251\5\21\t\2\u0251"+ - "\u00a2\3\2\2\2\u0252\u0253\5\33\16\2\u0253\u0254\5%\23\2\u0254\u0255\5"+ - "#\22\2\u0255\u00a4\3\2\2\2\u0256\u0257\5\r\7\2\u0257\u0258\5\t\5\2\u0258"+ - "\u0259\5\35\17\2\u0259\u025a\5\35\17\2\u025a\u00a6\3\2\2\2\u025b\u025c"+ - "\5\r\7\2\u025c\u025d\5\r\7\2\u025d\u00a8\3\2\2\2\u025e\u025f\5\r\7\2\u025f"+ - "\u0260\5!\21\2\u0260\u0261\5\r\7\2\u0261\u00aa\3\2\2\2\u0262\u0263\5\r"+ - "\7\2\u0263\u0264\5\67\34\2\u0264\u00ac\3\2\2\2\u0265\u0266\5\r\7\2\u0266"+ - "\u0267\5!\21\2\u0267\u0268\5\67\34\2\u0268\u00ae\3\2\2\2\u0269\u026a\5"+ - "\r\7\2\u026a\u026b\5%\23\2\u026b\u00b0\3\2\2\2\u026c\u026d\5\r\7\2\u026d"+ - "\u026e\5\37\20\2\u026e\u00b2\3\2\2\2\u026f\u0270\5\r\7\2\u0270\u0271\5"+ - "%\23\2\u0271\u0272\5\21\t\2\u0272\u00b4\3\2\2\2\u0273\u0274\5\r\7\2\u0274"+ - "\u0275\5%\23\2\u0275\u0276\5#\22\2\u0276\u00b6\3\2\2\2\u0277\u0278\5)"+ - "\25\2\u0278\u0279\5\21\t\2\u0279\u027a\5-\27\2\u027a\u00b8\3\2\2\2\u027b"+ - "\u027c\5)\25\2\u027c\u027d\5\r\7\2\u027d\u00ba\3\2\2\2\u027e\u027f\5)"+ - "\25\2\u027f\u0280\5!\21\2\u0280\u0281\5\r\7\2\u0281\u00bc\3\2\2\2\u0282"+ - "\u0283\5)\25\2\u0283\u0284\5\67\34\2\u0284\u00be\3\2\2\2\u0285\u0286\5"+ - ")\25\2\u0286\u0287\5!\21\2\u0287\u0288\5\67\34\2\u0288\u00c0\3\2\2\2\u0289"+ - "\u028a\5)\25\2\u028a\u028b\5\37\20\2\u028b\u00c2\3\2\2\2\u028c\u028d\5"+ - ")\25\2\u028d\u028e\5%\23\2\u028e\u00c4\3\2\2\2\u028f\u0290\5)\25\2\u0290"+ - "\u0291\5%\23\2\u0291\u0292\5\21\t\2\u0292\u00c6\3\2\2\2\u0293\u0294\5"+ - ")\25\2\u0294\u0295\5%\23\2\u0295\u0296\5#\22\2\u0296\u00c8\3\2\2\2\u0297"+ - "\u0298\5)\25\2\u0298\u0299\5+\26\2\u0299\u029a\5-\27\2\u029a\u00ca\3\2"+ - "\2\2\u029b\u029c\5\21\t\2\u029c\u029d\5\31\r\2\u029d\u00cc\3\2\2\2\u029e"+ - "\u029f\5\17\b\2\u029f\u02a0\5\31\r\2\u02a0\u00ce\3\2\2\2\u02a1\u02a2\5"+ - "\31\r\2\u02a2\u02a3\5!\21\2\u02a3\u00d0\3\2\2\2\u02a4\u02a5\5#\22\2\u02a5"+ - "\u02a6\5/\30\2\u02a6\u02a7\5-\27\2\u02a7\u00d2\3\2\2\2\u02a8\u02a9\5\27"+ - "\f\2\u02a9\u02aa\5\35\17\2\u02aa\u02ab\5-\27\2\u02ab\u00d4\3\2\2\2\u02ac"+ - "\u02ad\5#\22\2\u02ad\u02ae\5)\25\2\u02ae\u02af\5\25\13\2\u02af\u00d6\3"+ - "\2\2\2\u02b0\u02b1\5\21\t\2\u02b1\u02b2\5\'\24\2\u02b2\u02b3\5/\30\2\u02b3"+ - "\u00d8\3\2\2\2\u02b4\u02b5\5+\26\2\u02b5\u02b6\5\21\t\2\u02b6\u02b7\5"+ - "-\27\2\u02b7\u00da\3\2\2\2\u02b8\u02b9\5\31\r\2\u02b9\u02ba\5!\21\2\u02ba"+ - "\u02bb\5\r\7\2\u02bb\u02bc\5\35\17\2\u02bc\u02bd\5/\30\2\u02bd\u02be\5"+ - "\17\b\2\u02be\u02bf\5\21\t\2\u02bf\u00dc\3\2\2\2\u02c0\u02c1\5\31\r\2"+ - "\u02c1\u02c2\5\23\n\2\u02c2\u00de\3\2\2\2\u02c3\u02c4\5\21\t\2\u02c4\u02c5"+ - "\5!\21\2\u02c5\u02c6\5\17\b\2\u02c6\u02c7\5\31\r\2\u02c7\u02c8\5\23\n"+ - "\2\u02c8\u00e0\3\2\2\2\u02c9\u02ca\5\37\20\2\u02ca\u02cb\5\t\5\2\u02cb"+ - "\u02cc\5\r\7\2\u02cc\u02cd\5)\25\2\u02cd\u02ce\5#\22\2\u02ce\u00e2\3\2"+ - "\2\2\u02cf\u02d0\5\21\t\2\u02d0\u02d1\5!\21\2\u02d1\u02d2\5\17\b\2\u02d2"+ - "\u02d3\5\37\20\2\u02d3\u00e4\3\2\2\2\u02d4\u02d5\5\17\b\2\u02d5\u02d6"+ - "\5\13\6\2\u02d6\u00e6\3\2\2\2\u02d7\u02d8\5\17\b\2\u02d8\u02d9\5\63\32"+ - "\2\u02d9\u00e8\3\2\2\2\u02da\u02db\5\17\b\2\u02db\u02dc\5+\26\2\u02dc"+ - "\u00ea\3\2\2\2\u02dd\u02de\7&\2\2\u02de\u00ec\3\2\2\2\u02df\u02e0\5\t"+ - "\5\2\u02e0\u00ee\3\2\2\2\u02e1\u02e2\5\13\6\2\u02e2\u00f0\3\2\2\2\u02e3"+ - "\u02e4\5\r\7\2\u02e4\u00f2\3\2\2\2\u02e5\u02e6\5\17\b\2\u02e6\u00f4\3"+ - "\2\2\2\u02e7\u02e8\5\21\t\2\u02e8\u00f6\3\2\2\2\u02e9\u02ea\5\27\f\2\u02ea"+ - "\u00f8\3\2\2\2\u02eb\u02ec\5\35\17\2\u02ec\u00fa\3\2\2\2\u02ed\u02ee\5"+ - "\37\20\2\u02ee\u00fc\3\2\2\2\u02ef\u02f0\5%\23\2\u02f0\u02f1\5+\26\2\u02f1"+ - "\u02f2\5\63\32\2\u02f2\u00fe\3\2\2\2\u02f3\u02f4\5+\26\2\u02f4\u02f5\5"+ - "%\23\2\u02f5\u0100\3\2\2\2\u02f6\u02f7\7*\2\2\u02f7\u0102\3\2\2\2\u02f8"+ - "\u02f9\7+\2\2\u02f9\u0104\3\2\2\2\u02fa\u02fb\7.\2\2\u02fb\u0106\3\2\2"+ - "\2\u02fc\u02fd\7-\2\2\u02fd\u0108\3\2\2\2\u02fe\u02ff\7/\2\2\u02ff\u010a"+ - "\3\2\2\2\u0300\u0301\7,\2\2\u0301\u010c\3\2\2\2\u0302\u0303\7\61\2\2\u0303"+ - "\u010e\3\2\2\2\u0304\u0305\7?\2\2\u0305\u0110\3\2\2\2\u0306\u0307\5\37"+ - "\20\2\u0307\u0308\5#\22\2\u0308\u0309\5\17\b\2\u0309\u0112\3\2\2\2\u030a"+ - "\u030b\5+\26\2\u030b\u030c\5\27\f\2\u030c\u030d\5)\25\2\u030d\u0114\3"+ - "\2\2\2\u030e\u030f\5+\26\2\u030f\u0310\5\27\f\2\u0310\u0311\5\35\17\2"+ - "\u0311\u0116\3\2\2\2\u0312\u0313\5!\21\2\u0313\u0314\5#\22\2\u0314\u0315"+ - "\5-\27\2\u0315\u0118\3\2\2\2\u0316\u0317\5\t\5\2\u0317\u0318\5!\21\2\u0318"+ - "\u0319\5\17\b\2\u0319\u011a\3\2\2\2\u031a\u031b\5#\22\2\u031b\u031c\5"+ - ")\25\2\u031c\u011c\3\2\2\2\u031d\u031e\5\65\33\2\u031e\u031f\5#\22\2\u031f"+ - "\u0320\5)\25\2\u0320\u011e\3\2\2\2\u0321\u0323\t\35\2\2\u0322\u0321\3"+ - "\2\2\2\u0322\u0323\3\2\2\2\u0323\u0325\3\2\2\2\u0324\u0326\t\36\2\2\u0325"+ - "\u0324\3\2\2\2\u0326\u0327\3\2\2\2\u0327\u0325\3\2\2\2\u0327\u0328\3\2"+ - "\2\2\u0328\u032a\3\2\2\2\u0329\u032b\5\17\b\2\u032a\u0329\3\2\2\2\u032a"+ - "\u032b\3\2\2\2\u032b\u0120\3\2\2\2\u032c\u032e\t\35\2\2\u032d\u032c\3"+ - "\2\2\2\u032d\u032e\3\2\2\2\u032e\u032f\3\2\2\2\u032f\u0330\7\62\2\2\u0330"+ - "\u0332\5\65\33\2\u0331\u0333\t\37\2\2\u0332\u0331\3\2\2\2\u0333\u0334"+ - "\3\2\2\2\u0334\u0332\3\2\2\2\u0334\u0335\3\2\2\2\u0335\u0122\3\2\2\2\u0336"+ - "\u0338\t\35\2\2\u0337\u0336\3\2\2\2\u0337\u0338\3\2\2\2\u0338\u033a\3"+ - "\2\2\2\u0339\u033b\t\37\2\2\u033a\u0339\3\2\2\2\u033b\u033c\3\2\2\2\u033c"+ - "\u033a\3\2\2\2\u033c\u033d\3\2\2\2\u033d\u033e\3\2\2\2\u033e\u033f\5\27"+ - "\f\2\u033f\u0124\3\2\2\2\u0340\u0342\t\35\2\2\u0341\u0340\3\2\2\2\u0341"+ - "\u0342\3\2\2\2\u0342\u0344\3\2\2\2\u0343\u0345\t \2\2\u0344\u0343\3\2"+ - "\2\2\u0345\u0346\3\2\2\2\u0346\u0344\3\2\2\2\u0346\u0347\3\2\2\2\u0347"+ - "\u0348\3\2\2\2\u0348\u0349\t!\2\2\u0349\u0126\3\2\2\2\u034a\u034c\t\""+ - "\2\2\u034b\u034a\3\2\2\2\u034c\u034d\3\2\2\2\u034d\u034b\3\2\2\2\u034d"+ - "\u034e\3\2\2\2\u034e\u034f\3\2\2\2\u034f\u0350\5\13\6\2\u0350\u0128\3"+ - "\2\2\2\u0351\u0353\t#\2\2\u0352\u0354\t$\2\2\u0353\u0352\3\2\2\2\u0354"+ - "\u0355\3\2\2\2\u0355\u0353\3\2\2\2\u0355\u0356\3\2\2\2\u0356\u0357\3\2"+ - "\2\2\u0357\u0358\t#\2\2\u0358\u012a\3\2\2\2\u0359\u035b\7$\2\2\u035a\u035c"+ - "\t%\2\2\u035b\u035a\3\2\2\2\u035c\u035d\3\2\2\2\u035d\u035b\3\2\2\2\u035d"+ - "\u035e\3\2\2\2\u035e\u035f\3\2\2\2\u035f\u0360\7$\2\2\u0360\u012c\3\2"+ - "\2\2\u0361\u0365\t&\2\2\u0362\u0364\t\'\2\2\u0363\u0362\3\2\2\2\u0364"+ - "\u0367\3\2\2\2\u0365\u0363\3\2\2\2\u0365\u0366\3\2\2\2\u0366\u012e\3\2"+ - "\2\2\u0367\u0365\3\2\2\2\u0368\u036c\t&\2\2\u0369\u036b\t\'\2\2\u036a"+ - "\u0369\3\2\2\2\u036b\u036e\3\2\2\2\u036c\u036a\3\2\2\2\u036c\u036d\3\2"+ - "\2\2\u036d\u036f\3\2\2\2\u036e\u036c\3\2\2\2\u036f\u0370\7<\2\2\u0370"+ - "\u0130\3\2\2\2\u0371\u0372\13\2\2\2\u0372\u0132\3\2\2\2\24\2\u013c\u0141"+ - "\u0145\u0322\u0327\u032a\u032d\u0334\u0337\u033c\u0341\u0346\u034d\u0355"+ - "\u035d\u0365\u036c\3\2\3\2"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file diff --git a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.tokens b/plugins/compiler/as-8080/src/main/gen/As8080Lexer.tokens deleted file mode 100644 index a522a3c4c..000000000 --- a/plugins/compiler/as-8080/src/main/gen/As8080Lexer.tokens +++ /dev/null @@ -1,137 +0,0 @@ -WS=1 -COMMENT=2 -EOL=3 -OPCODE_STC=4 -OPCODE_CMC=5 -OPCODE_INR=6 -OPCODE_DCR=7 -OPCODE_CMA=8 -OPCODE_DAA=9 -OPCODE_NOP=10 -OPCODE_MOV=11 -OPCODE_STAX=12 -OPCODE_LDAX=13 -OPCODE_ADD=14 -OPCODE_ADC=15 -OPCODE_SUB=16 -OPCODE_SBB=17 -OPCODE_ANA=18 -OPCODE_XRA=19 -OPCODE_ORA=20 -OPCODE_CMP=21 -OPCODE_RLC=22 -OPCODE_RRC=23 -OPCODE_RAL=24 -OPCODE_RAR=25 -OPCODE_PUSH=26 -OPCODE_POP=27 -OPCODE_DAD=28 -OPCODE_INX=29 -OPCODE_DCX=30 -OPCODE_XCHG=31 -OPCODE_XTHL=32 -OPCODE_SPHL=33 -OPCODE_LXI=34 -OPCODE_MVI=35 -OPCODE_ADI=36 -OPCODE_ACI=37 -OPCODE_SUI=38 -OPCODE_SBI=39 -OPCODE_ANI=40 -OPCODE_XRI=41 -OPCODE_ORI=42 -OPCODE_CPI=43 -OPCODE_STA=44 -OPCODE_LDA=45 -OPCODE_SHLD=46 -OPCODE_LHLD=47 -OPCODE_PCHL=48 -OPCODE_JMP=49 -OPCODE_JC=50 -OPCODE_JNC=51 -OPCODE_JZ=52 -OPCODE_JNZ=53 -OPCODE_JP=54 -OPCODE_JM=55 -OPCODE_JPE=56 -OPCODE_JPO=57 -OPCODE_CALL=58 -OPCODE_CC=59 -OPCODE_CNC=60 -OPCODE_CZ=61 -OPCODE_CNZ=62 -OPCODE_CP=63 -OPCODE_CM=64 -OPCODE_CPE=65 -OPCODE_CPO=66 -OPCODE_RET=67 -OPCODE_RC=68 -OPCODE_RNC=69 -OPCODE_RZ=70 -OPCODE_RNZ=71 -OPCODE_RM=72 -OPCODE_RP=73 -OPCODE_RPE=74 -OPCODE_RPO=75 -OPCODE_RST=76 -OPCODE_EI=77 -OPCODE_DI=78 -OPCODE_IN=79 -OPCODE_OUT=80 -OPCODE_HLT=81 -PREP_ORG=82 -PREP_EQU=83 -PREP_SET=84 -PREP_INCLUDE=85 -PREP_IF=86 -PREP_ENDIF=87 -PREP_MACRO=88 -PREP_ENDM=89 -PREP_DB=90 -PREP_DW=91 -PREP_DS=92 -PREP_ADDR=93 -REG_A=94 -REG_B=95 -REG_C=96 -REG_D=97 -REG_E=98 -REG_H=99 -REG_L=100 -REG_M=101 -REG_PSW=102 -REG_SP=103 -SEP_LPAR=104 -SEP_RPAR=105 -SEP_COMMA=106 -OP_ADD=107 -OP_SUBTRACT=108 -OP_MULTIPLY=109 -OP_DIVIDE=110 -OP_EQUAL=111 -OP_MOD=112 -OP_SHR=113 -OP_SHL=114 -OP_NOT=115 -OP_AND=116 -OP_OR=117 -OP_XOR=118 -LIT_NUMBER=119 -LIT_HEXNUMBER_1=120 -LIT_HEXNUMBER_2=121 -LIT_OCTNUMBER=122 -LIT_BINNUMBER=123 -LIT_STRING_1=124 -LIT_STRING_2=125 -ID_IDENTIFIER=126 -ID_LABEL=127 -ERROR=128 -'$'=93 -'('=104 -')'=105 -','=106 -'+'=107 -'-'=108 -'*'=109 -'/'=110 -'='=111 diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index 0d29908d9..e2c9309cd 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -93,7 +93,7 @@ public String getDescription() { @Override public LexicalAnalyzer createLexer(String s) { As8080Lexer lexer = createLexer(CharStreams.fromString(s)); - return new LexicalAnalyzerImpl(lexer); + return new Lexer(lexer); } @Override @@ -102,7 +102,7 @@ public boolean compile(String inputFileName, String outputFileName) { notifyInfo(getTitle() + ", version " + getVersion()); try (Reader reader = new FileReader(inputFileName)) { - Lexer lexer = createLexer(CharStreams.fromReader(reader)); + org.antlr.v4.runtime.Lexer lexer = createLexer(CharStreams.fromReader(reader)); lexer.addErrorListener(new ParserErrorListener()); CommonTokenStream tokens = new CommonTokenStream(lexer); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java new file mode 100644 index 000000000..9260be44f --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java @@ -0,0 +1,194 @@ +package net.emustudio.plugins.compiler.as8080; + +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; +import net.emustudio.emulib.plugins.compiler.Token; +import org.antlr.v4.runtime.CharStreams; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Objects; + +import static net.emustudio.plugins.compiler.as8080.As8080Lexer.*; + +public class Lexer implements LexicalAnalyzer { + private final As8080Lexer lexer; + private static final int[] tokenMap = new int[As8080Lexer.ERROR + 1]; // As8080Lexer.ERROR is the highest number + + static { + tokenMap[COMMENT] = Token.COMMENT; + tokenMap[EOL] = Token.WHITESPACE; + tokenMap[WS] = Token.WHITESPACE; + tokenMap[OPCODE_STC] = Token.RESERVED; + tokenMap[OPCODE_CMC] = Token.RESERVED; + tokenMap[OPCODE_INR] = Token.RESERVED; + tokenMap[OPCODE_DCR] = Token.RESERVED; + tokenMap[OPCODE_CMA] = Token.RESERVED; + tokenMap[OPCODE_DAA] = Token.RESERVED; + tokenMap[OPCODE_NOP] = Token.RESERVED; + tokenMap[OPCODE_MOV] = Token.RESERVED; + tokenMap[OPCODE_STAX] = Token.RESERVED; + tokenMap[OPCODE_LDAX] = Token.RESERVED; + tokenMap[OPCODE_ADD] = Token.RESERVED; + tokenMap[OPCODE_ADC] = Token.RESERVED; + tokenMap[OPCODE_SUB] = Token.RESERVED; + tokenMap[OPCODE_SBB] = Token.RESERVED; + tokenMap[OPCODE_ANA] = Token.RESERVED; + tokenMap[OPCODE_XRA] = Token.RESERVED; + tokenMap[OPCODE_ORA] = Token.RESERVED; + tokenMap[OPCODE_CMP] = Token.RESERVED; + tokenMap[OPCODE_RLC] = Token.RESERVED; + tokenMap[OPCODE_RRC] = Token.RESERVED; + tokenMap[OPCODE_RAL] = Token.RESERVED; + tokenMap[OPCODE_RAR] = Token.RESERVED; + tokenMap[OPCODE_PUSH] = Token.RESERVED; + tokenMap[OPCODE_POP] = Token.RESERVED; + tokenMap[OPCODE_DAD] = Token.RESERVED; + tokenMap[OPCODE_INX] = Token.RESERVED; + tokenMap[OPCODE_DCX] = Token.RESERVED; + tokenMap[OPCODE_XCHG] = Token.RESERVED; + tokenMap[OPCODE_XTHL] = Token.RESERVED; + tokenMap[OPCODE_SPHL] = Token.RESERVED; + tokenMap[OPCODE_LXI] = Token.RESERVED; + tokenMap[OPCODE_MVI] = Token.RESERVED; + tokenMap[OPCODE_ADI] = Token.RESERVED; + tokenMap[OPCODE_ACI] = Token.RESERVED; + tokenMap[OPCODE_SUI] = Token.RESERVED; + tokenMap[OPCODE_SBI] = Token.RESERVED; + tokenMap[OPCODE_ANI] = Token.RESERVED; + tokenMap[OPCODE_XRI] = Token.RESERVED; + tokenMap[OPCODE_ORI] = Token.RESERVED; + tokenMap[OPCODE_CPI] = Token.RESERVED; + tokenMap[OPCODE_STA] = Token.RESERVED; + tokenMap[OPCODE_LDA] = Token.RESERVED; + tokenMap[OPCODE_SHLD] = Token.RESERVED; + tokenMap[OPCODE_LHLD] = Token.RESERVED; + tokenMap[OPCODE_PCHL] = Token.RESERVED; + tokenMap[OPCODE_JMP] = Token.RESERVED; + tokenMap[OPCODE_JC] = Token.RESERVED; + tokenMap[OPCODE_JNC] = Token.RESERVED; + tokenMap[OPCODE_JZ] = Token.RESERVED; + tokenMap[OPCODE_JNZ] = Token.RESERVED; + tokenMap[OPCODE_JP] = Token.RESERVED; + tokenMap[OPCODE_JM] = Token.RESERVED; + tokenMap[OPCODE_JPE] = Token.RESERVED; + tokenMap[OPCODE_JPO] = Token.RESERVED; + tokenMap[OPCODE_CALL] = Token.RESERVED; + tokenMap[OPCODE_CC] = Token.RESERVED; + tokenMap[OPCODE_CNC] = Token.RESERVED; + tokenMap[OPCODE_CZ] = Token.RESERVED; + tokenMap[OPCODE_CNZ] = Token.RESERVED; + tokenMap[OPCODE_CP] = Token.RESERVED; + tokenMap[OPCODE_CM] = Token.RESERVED; + tokenMap[OPCODE_CPE] = Token.RESERVED; + tokenMap[OPCODE_CPO] = Token.RESERVED; + tokenMap[OPCODE_RET] = Token.RESERVED; + tokenMap[OPCODE_RC] = Token.RESERVED; + tokenMap[OPCODE_RNC] = Token.RESERVED; + tokenMap[OPCODE_RZ] = Token.RESERVED; + tokenMap[OPCODE_RNZ] = Token.RESERVED; + tokenMap[OPCODE_RM] = Token.RESERVED; + tokenMap[OPCODE_RP] = Token.RESERVED; + tokenMap[OPCODE_RPE] = Token.RESERVED; + tokenMap[OPCODE_RPO] = Token.RESERVED; + tokenMap[OPCODE_RST] = Token.RESERVED; + tokenMap[OPCODE_EI] = Token.RESERVED; + tokenMap[OPCODE_DI] = Token.RESERVED; + tokenMap[OPCODE_IN] = Token.RESERVED; + tokenMap[OPCODE_OUT] = Token.RESERVED; + tokenMap[OPCODE_HLT] = Token.RESERVED; + + tokenMap[PREP_ORG] = Token.PREPROCESSOR; + tokenMap[PREP_EQU] = Token.PREPROCESSOR; + tokenMap[PREP_SET] = Token.PREPROCESSOR; + tokenMap[PREP_INCLUDE] = Token.PREPROCESSOR; + tokenMap[PREP_IF] = Token.PREPROCESSOR; + tokenMap[PREP_ENDIF] = Token.PREPROCESSOR; + tokenMap[PREP_MACRO] = Token.PREPROCESSOR; + tokenMap[PREP_ENDM] = Token.PREPROCESSOR; + tokenMap[PREP_DB] = Token.PREPROCESSOR; + tokenMap[PREP_DW] = Token.PREPROCESSOR; + tokenMap[PREP_DS] = Token.PREPROCESSOR; + tokenMap[PREP_ADDR] = Token.PREPROCESSOR; + + tokenMap[REG_A] = Token.REGISTER; + tokenMap[REG_B] = Token.REGISTER; + tokenMap[REG_C] = Token.REGISTER; + tokenMap[REG_D] = Token.REGISTER; + tokenMap[REG_E] = Token.REGISTER; + tokenMap[REG_H] = Token.REGISTER; + tokenMap[REG_L] = Token.REGISTER; + tokenMap[REG_M] = Token.REGISTER; + tokenMap[REG_PSW] = Token.REGISTER; + tokenMap[REG_SP] = Token.REGISTER; + + tokenMap[SEP_LPAR] = Token.SEPARATOR; + tokenMap[SEP_RPAR] = Token.SEPARATOR; + tokenMap[SEP_COMMA] = Token.SEPARATOR; + + tokenMap[OP_ADD] = Token.OPERATOR; + tokenMap[OP_SUBTRACT] = Token.OPERATOR; + tokenMap[OP_MULTIPLY] = Token.OPERATOR; + tokenMap[OP_DIVIDE] = Token.OPERATOR; + tokenMap[OP_EQUAL] = Token.OPERATOR; + tokenMap[OP_MOD] = Token.OPERATOR; + tokenMap[OP_SHR] = Token.OPERATOR; + tokenMap[OP_SHL] = Token.OPERATOR; + tokenMap[OP_NOT] = Token.OPERATOR; + tokenMap[OP_AND] = Token.OPERATOR; + tokenMap[OP_OR] = Token.OPERATOR; + tokenMap[OP_XOR] = Token.OPERATOR; + + tokenMap[LIT_NUMBER] =Token.LITERAL; + tokenMap[LIT_HEXNUMBER_1] =Token.LITERAL; + tokenMap[LIT_HEXNUMBER_2] =Token.LITERAL; + tokenMap[LIT_OCTNUMBER] =Token.LITERAL; + tokenMap[LIT_BINNUMBER] =Token.LITERAL; + tokenMap[LIT_STRING_1] =Token.LITERAL; + tokenMap[LIT_STRING_2] =Token.LITERAL; + + tokenMap[ID_IDENTIFIER] = Token.IDENTIFIER; + tokenMap[ID_LABEL] = Token.IDENTIFIER; + + tokenMap[ERROR] = Token.ERROR; + } + + + public Lexer(As8080Lexer lexer) { + this.lexer = Objects.requireNonNull(lexer); + } + + @Override + public Token nextToken() { + org.antlr.v4.runtime.Token token = lexer.nextToken(); + return new Token() { + @Override + public int getType() { + return convertLexerTokenType(token.getType()); + } + + @Override + public int getOffset() { + return token.getStartIndex(); + } + + @Override + public String getText() { + return token.getText(); + } + }; + } + + @Override + public boolean isAtEOF() { + return lexer._hitEOF; + } + + @Override + public void reset(InputStream inputStream) throws IOException { + lexer.setInputStream(CharStreams.fromStream(inputStream)); + } + + private int convertLexerTokenType(int tokenType) { + return tokenMap[tokenType]; + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java index 62ecef4a7..f790e0b35 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java @@ -1,9 +1,20 @@ package net.emustudio.plugins.compiler.as8080.ast; +import net.emustudio.plugins.compiler.as8080.ast.instr.Instr; + +import java.util.LinkedList; +import java.util.List; + public class Program extends AbstractNode { private final NameSpace nameSpace = new NameSpace(); + private final List instructions = new LinkedList<>(); public NameSpace env() { return nameSpace; } + + public Program addIntruction(Instr instr) { + instructions.add(instr); + return this; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java new file mode 100644 index 000000000..4b2c5be6d --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java @@ -0,0 +1,4 @@ +package net.emustudio.plugins.compiler.as8080.ast; + +public class Statement { +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ProgramVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ProgramVisitor.java new file mode 100644 index 000000000..7293c9fa1 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ProgramVisitor.java @@ -0,0 +1,31 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.visitors.InstrVisitor; + +import java.util.Optional; + +public class ProgramVisitor extends As8080ParserBaseVisitor { + private final Program program = new Program(); + + @Override + public Program visitRLine(As8080Parser.RLineContext ctx) { + Optional.ofNullable(ctx.label).ifPresent(program.env()::addLabel); + return super.visitRLine(ctx); + } + + @Override + public Program visitRStatement(As8080Parser.RStatementContext ctx) { + Optional.ofNullable(ctx.instr).ifPresent(i -> program.addIntruction(new InstrVisitor().visit(i))); + //Optional.ofNullable(ctx.pseudo).ifPresent(p -> ); + // Optional.ofNullable(ctx.data).ifPresent(d -> ); + + return program; + } + + + + +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java index c1edef38e..49d597f17 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java @@ -4,67 +4,233 @@ import static net.emustudio.plugins.compiler.as8080.As8080Lexer.*; import static net.emustudio.plugins.compiler.as8080.Utils.assertTokenTypes; +import static net.emustudio.plugins.compiler.as8080.Utils.assertTokenTypesIgnoreCase; public class LexerTest { @Test - public void testParseError() { - assertTokenTypes("B &", REG_B, WS, ERROR, EOF); - assertTokenTypes("0x 9o 22b", ERROR, WS, ERROR, WS, ERROR, EOF); + public void testParseError1() { + assertTokenTypes("B &", REG_B, ERROR, EOF); } @Test - public void testParseHexNumbers() { + public void testParseError2() { + assertTokenTypes("0x 9o 22b", ERROR, ERROR, ERROR, EOF); + } + + @Test + public void testParseHex1() { + assertTokenTypes("0x1 0x0 -0x5f -0xFffF 0x1BC", LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, EOF); + } + + @Test + public void testParseHex2() { + assertTokenTypes( + "1h 0h -5Fh -FFFFh 1BCh 5h -5h", + LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, EOF + ); + } + + @Test + public void testParseDecimal() { assertTokenTypes( - "0x5F 0X5F 5fh 5fH 5Fh 0xG", - LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, ERROR, EOF + "0 1 -2 3 -4 5 66 999", + LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, EOF ); - assertTokenTypes("-5h -0xFF", LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, EOF); - } - -// @Test -// public void testParseReservedWords() { -// assertTokenTypesForCaseVariations("jmp", SSEMLexer.JMP, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("jrp", SSEMLexer.JPR, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("jpr", SSEMLexer.JPR, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("jmr", SSEMLexer.JPR, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("ldn", SSEMLexer.LDN, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("sto", SSEMLexer.STO, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("sub", SSEMLexer.SUB, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("cmp", SSEMLexer.CMP, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("skn", SSEMLexer.CMP, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("stp", SSEMLexer.STP, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("hlt", SSEMLexer.STP, SSEMLexer.EOF); -// } -// -// @Test -// public void testParsePreprocessor() { -// assertTokenTypesForCaseVariations("start", SSEMLexer.START, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("num", SSEMLexer.NUM, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("bnum", SSEMLexer.BNUM, SSEMLexer.EOF); -// assertTokenTypesForCaseVariations("bins", SSEMLexer.BNUM, SSEMLexer.EOF); -// } -// -// @Test -// public void testParseWhitespaces() { -// assertTokenTypes(" ", SSEMLexer.WS, SSEMLexer.EOF); -// assertTokenTypes("\t", SSEMLexer.WS, SSEMLexer.EOF); -// assertTokenTypes("\n", SSEMLexer.EOL, SSEMLexer.EOF); -// assertTokenTypes("", SSEMLexer.EOF); -// } -// -// @Test -// public void testParseComments() { -// assertTokenTypes("-- comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); -// assertTokenTypes("# comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); -// assertTokenTypes("// comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); -// assertTokenTypes("; comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); -// } -// -// @Test -// public void testLiterals() { -// assertTokenTypes("10", SSEMLexer.NUMBER, SSEMLexer.EOF); -// assertTokenTypes("0xAF", SSEMLexer.HEXNUMBER, SSEMLexer.EOF); -// assertTokenTypes("BINS 1010", SSEMLexer.BNUM, SSEMLexer.BWS, SSEMLexer.BinaryNumber, SSEMLexer.EOF); -// } + } + + @Test + public void testParseOctal() { + assertTokenTypes("-6o 7q 11q -345O", LIT_OCTNUMBER, LIT_OCTNUMBER, LIT_OCTNUMBER, LIT_OCTNUMBER, EOF); + } + + @Test + public void testParseBinary() { + assertTokenTypes("10101010101010101010110b", LIT_BINNUMBER, EOF); + } + + @Test + public void testParseString1() { + assertTokenTypes("'' 'sss'", LIT_STRING_1, LIT_STRING_1, EOF); + assertTokenTypes("'\nsss'", LIT_STRING_1, EOF); + } + + @Test + public void testParseString2() { + assertTokenTypes("\"\" \"sss\"", LIT_STRING_2, LIT_STRING_2, EOF); + assertTokenTypes("\"\nsss\"", LIT_STRING_2, EOF); + } + + @Test + public void testParseString1Error() { + assertTokenTypes("'open", ERROR, EOF); + } + + @Test + public void testParseString2Error() { + assertTokenTypes("\"open", ERROR, EOF); + } + + @Test + public void testParseComment1() { + assertTokenTypes("// comment fun1", EOF); + assertTokenTypes("# comment fun1", EOF); + assertTokenTypes("; comment fun1", EOF); + } + + @Test + public void testParseComment2() { + assertTokenTypes("/*\n*\n* comment fun1\n\n*/", EOF); + } + + @Test + public void testParseOpcodes() { + assertTokenTypesIgnoreCase("STC", OPCODE_STC, EOF); + assertTokenTypesIgnoreCase("CMC", OPCODE_CMC, EOF); + assertTokenTypesIgnoreCase("CMA", OPCODE_CMA, EOF); + assertTokenTypesIgnoreCase("DAA", OPCODE_DAA, EOF); + assertTokenTypesIgnoreCase("NOP", OPCODE_NOP, EOF); + assertTokenTypesIgnoreCase("RLC", OPCODE_RLC, EOF); + assertTokenTypesIgnoreCase("RRC", OPCODE_RRC, EOF); + assertTokenTypesIgnoreCase("RAL", OPCODE_RAL, EOF); + assertTokenTypesIgnoreCase("RAR", OPCODE_RAR, EOF); + assertTokenTypesIgnoreCase("XCHG", OPCODE_XCHG, EOF); + assertTokenTypesIgnoreCase("XTHL", OPCODE_XTHL, EOF); + assertTokenTypesIgnoreCase("SPHL", OPCODE_SPHL, EOF); + assertTokenTypesIgnoreCase("PCHL", OPCODE_PCHL, EOF); + assertTokenTypesIgnoreCase("RET", OPCODE_RET, EOF); + assertTokenTypesIgnoreCase("RC", OPCODE_RC, EOF); + assertTokenTypesIgnoreCase("RNC", OPCODE_RNC, EOF); + assertTokenTypesIgnoreCase("RZ", OPCODE_RZ, EOF); + assertTokenTypesIgnoreCase("RNZ", OPCODE_RNZ, EOF); + assertTokenTypesIgnoreCase("RM", OPCODE_RM, EOF); + assertTokenTypesIgnoreCase("RP", OPCODE_RP, EOF); + assertTokenTypesIgnoreCase("RPE", OPCODE_RPE, EOF); + assertTokenTypesIgnoreCase("RPO", OPCODE_RPO, EOF); + assertTokenTypesIgnoreCase("EI", OPCODE_EI, EOF); + assertTokenTypesIgnoreCase("DI", OPCODE_DI, EOF); + assertTokenTypesIgnoreCase("HLT", OPCODE_HLT, EOF); + assertTokenTypesIgnoreCase("INR", OPCODE_INR, EOF); + assertTokenTypesIgnoreCase("DCR", OPCODE_DCR, EOF); + assertTokenTypesIgnoreCase("ADD", OPCODE_ADD, EOF); + assertTokenTypesIgnoreCase("ADC", OPCODE_ADC, EOF); + assertTokenTypesIgnoreCase("SUB", OPCODE_SUB, EOF); + assertTokenTypesIgnoreCase("SBB", OPCODE_SBB, EOF); + assertTokenTypesIgnoreCase("ANA", OPCODE_ANA, EOF); + assertTokenTypesIgnoreCase("XRA", OPCODE_XRA, EOF); + assertTokenTypesIgnoreCase("ORA", OPCODE_ORA, EOF); + assertTokenTypesIgnoreCase("CMP", OPCODE_CMP, EOF); + assertTokenTypesIgnoreCase("MOV", OPCODE_MOV, EOF); + assertTokenTypesIgnoreCase("STAX", OPCODE_STAX, EOF); + assertTokenTypesIgnoreCase("LDAX", OPCODE_LDAX, EOF); + assertTokenTypesIgnoreCase("PUSH", OPCODE_PUSH, EOF); + assertTokenTypesIgnoreCase("POP", OPCODE_POP, EOF); + assertTokenTypesIgnoreCase("DAD", OPCODE_DAD, EOF); + assertTokenTypesIgnoreCase("INX", OPCODE_INX, EOF); + assertTokenTypesIgnoreCase("DCX", OPCODE_DCX, EOF); + assertTokenTypesIgnoreCase("LXI", OPCODE_LXI, EOF); + assertTokenTypesIgnoreCase("MVI", OPCODE_MVI, EOF); + assertTokenTypesIgnoreCase("ADI", OPCODE_ADI, EOF); + assertTokenTypesIgnoreCase("ACI", OPCODE_ACI, EOF); + assertTokenTypesIgnoreCase("SUI", OPCODE_SUI, EOF); + assertTokenTypesIgnoreCase("SBI", OPCODE_SBI, EOF); + assertTokenTypesIgnoreCase("ANI", OPCODE_ANI, EOF); + assertTokenTypesIgnoreCase("XRI", OPCODE_XRI, EOF); + assertTokenTypesIgnoreCase("ORI", OPCODE_ORI, EOF); + assertTokenTypesIgnoreCase("CPI", OPCODE_CPI, EOF); + assertTokenTypesIgnoreCase("STA", OPCODE_STA, EOF); + assertTokenTypesIgnoreCase("LDA", OPCODE_LDA, EOF); + assertTokenTypesIgnoreCase("SHLD", OPCODE_SHLD, EOF); + assertTokenTypesIgnoreCase("LHLD", OPCODE_LHLD, EOF); + assertTokenTypesIgnoreCase("JMP", OPCODE_JMP, EOF); + assertTokenTypesIgnoreCase("JC", OPCODE_JC, EOF); + assertTokenTypesIgnoreCase("JNC", OPCODE_JNC, EOF); + assertTokenTypesIgnoreCase("JZ", OPCODE_JZ, EOF); + assertTokenTypesIgnoreCase("JNZ", OPCODE_JNZ, EOF); + assertTokenTypesIgnoreCase("JM", OPCODE_JM, EOF); + assertTokenTypesIgnoreCase("JP", OPCODE_JP, EOF); + assertTokenTypesIgnoreCase("JPE", OPCODE_JPE, EOF); + assertTokenTypesIgnoreCase("JPO", OPCODE_JPO, EOF); + assertTokenTypesIgnoreCase("CALL", OPCODE_CALL, EOF); + assertTokenTypesIgnoreCase("CC", OPCODE_CC, EOF); + assertTokenTypesIgnoreCase("CNC", OPCODE_CNC, EOF); + assertTokenTypesIgnoreCase("CZ", OPCODE_CZ, EOF); + assertTokenTypesIgnoreCase("CNZ", OPCODE_CNZ, EOF); + assertTokenTypesIgnoreCase("CM", OPCODE_CM, EOF); + assertTokenTypesIgnoreCase("CP", OPCODE_CP, EOF); + assertTokenTypesIgnoreCase("CPE", OPCODE_CPE, EOF); + assertTokenTypesIgnoreCase("CPO", OPCODE_CPO, EOF); + assertTokenTypesIgnoreCase("RST", OPCODE_RST, EOF); + assertTokenTypesIgnoreCase("IN", OPCODE_IN, EOF); + assertTokenTypesIgnoreCase("OUT", OPCODE_OUT, EOF); + } + + @Test + public void testParsePreprocessor() { + assertTokenTypesIgnoreCase("ORG", PREP_ORG, EOF); + assertTokenTypesIgnoreCase("EQU", PREP_EQU, EOF); + assertTokenTypesIgnoreCase("SET", PREP_SET, EOF); + assertTokenTypesIgnoreCase("INCLUDE", PREP_INCLUDE, EOF); + assertTokenTypesIgnoreCase("IF", PREP_IF, EOF); + assertTokenTypesIgnoreCase("ENDIF", PREP_ENDIF, EOF); + assertTokenTypesIgnoreCase("MACRO", PREP_MACRO, EOF); + assertTokenTypesIgnoreCase("ENDM", PREP_ENDM, EOF); + assertTokenTypesIgnoreCase("DB", PREP_DB, EOF); + assertTokenTypesIgnoreCase("DW", PREP_DW, EOF); + assertTokenTypesIgnoreCase("DS", PREP_DS, EOF); + assertTokenTypesIgnoreCase("$", PREP_ADDR, EOF); + } + + @Test + public void testRegisters() { + assertTokenTypesIgnoreCase("A", REG_A, EOF); + assertTokenTypesIgnoreCase("B", REG_B, EOF); + assertTokenTypesIgnoreCase("C", REG_C, EOF); + assertTokenTypesIgnoreCase("D", REG_D, EOF); + assertTokenTypesIgnoreCase("E", REG_E, EOF); + assertTokenTypesIgnoreCase("H", REG_H, EOF); + assertTokenTypesIgnoreCase("L", REG_L, EOF); + assertTokenTypesIgnoreCase("M", REG_M, EOF); + assertTokenTypesIgnoreCase("PSW", REG_PSW, EOF); + assertTokenTypesIgnoreCase("SP", REG_SP, EOF); + } + + @Test + public void testSeparators() { + assertTokenTypes("(),", SEP_LPAR, SEP_RPAR, SEP_COMMA, EOF); + } + + @Test + public void testOperators1() { + assertTokenTypes("+-*/=", OP_ADD, OP_SUBTRACT, OP_MULTIPLY, OP_DIVIDE, OP_EQUAL, EOF); + } + + @Test + public void testOperators2() { + assertTokenTypesIgnoreCase("MOD", OP_MOD, EOF); + assertTokenTypesIgnoreCase("SHR", OP_SHR, EOF); + assertTokenTypesIgnoreCase("SHL", OP_SHL, EOF); + assertTokenTypesIgnoreCase("NOT", OP_NOT, EOF); + assertTokenTypesIgnoreCase("AND", OP_AND, EOF); + assertTokenTypesIgnoreCase("OR", OP_OR, EOF); + assertTokenTypesIgnoreCase("XOR", OP_XOR, EOF); + } + + @Test + public void testIdentifier() { + assertTokenTypes("u @ ? _", ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, EOF); + assertTokenTypes("a@ abc ZZ_ H005", ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, EOF); + } + + @Test + public void testLabel() { + assertTokenTypes("u: @: ?: _:", ID_LABEL, ID_LABEL, ID_LABEL, ID_LABEL, EOF); + assertTokenTypes("a@: abc: ZZ_: H005:", ID_LABEL, ID_LABEL, ID_LABEL, ID_LABEL, EOF); + assertTokenTypes("a:", ID_LABEL, EOF); + } + + @Test + public void testCombineSpaceWithNoSpaceTokens() { + assertTokenTypes("abc=(XOR,MOD)", ID_IDENTIFIER, OP_EQUAL, SEP_LPAR, OP_XOR, SEP_COMMA, OP_MOD, SEP_RPAR, EOF); + } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java index a8852cd33..d1e7a2ffd 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -27,11 +27,11 @@ public static void assertTokenTypes(List tokens, int... expectedTypes) { assertEquals("Tokens: " + tokens, expectedTypes.length, tokens.size()); for (int i = 0; i < expectedTypes.length; i++) { Token token = tokens.get(i); - assertEquals(expectedTypes[i], token.getType()); + assertEquals(token.toString(), expectedTypes[i], token.getType()); } } - public static void assertTokenTypesForCaseVariations(String base, int... expectedTypes) { + public static void assertTokenTypesIgnoreCase(String base, int... expectedTypes) { Random r = new Random(); List variations = new ArrayList<>(); variations.add(base); From 0f61e8b5a3ca186c43025114240092bd0f1873bd Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 25 Nov 2021 15:44:18 +0100 Subject: [PATCH 044/314] [#201] fix --- .../as-8080/src/main/antlr/As8080Lexer.g4 | 4 ++-- .../as-8080/src/main/antlr/As8080Parser.g4 | 23 ++++++++----------- .../plugins/compiler/as8080/LexerTest.java | 5 ++++ .../plugins/compiler/as8080/ParserTest.java | 15 ++++++++++++ .../plugins/compiler/as8080/Utils.java | 9 ++++++++ 5 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 index b812bbd6d..e55622863 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 @@ -2,7 +2,6 @@ lexer grammar As8080Lexer; COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]* -> skip; COMMENT2: '/*' .*? '*/' -> skip; -EOL: '\r'? '\n'; fragment A: [aA]; fragment B: [bB]; @@ -159,7 +158,7 @@ LIT_STRING_2: '"' ~["]* '"'; ID_IDENTIFIER: [a-zA-Z_?@] [a-zA-Z_?@0-9]*; ID_LABEL: [a-zA-Z_?@] [a-zA-Z_?@0-9]* ':'; -ERROR : ~[+* \t\f(),=/-]+; // below: everything which does not require space +ERROR : ~[+* \t\f\r\n(),=/-]+; // below: everything which does not require space //\+\* // separators - not requiring space inbetween @@ -175,3 +174,4 @@ OP_DIVIDE: '/'; OP_EQUAL: '='; WS : [ \t\f]+ -> skip; +EOL: '\r'? '\n'; diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index da53d4e15..78d501ab7 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -5,16 +5,11 @@ options { } rStart: - (rLine EOL rLine)* EOF - | rLine EOF + EOL* rLine? (EOL+ rLine)* EOL* EOF ; rLine: - label=ID_LABEL? statement=rStatement? rComment - | rComment - ; - -rComment: COMMENT? ; + label=ID_LABEL? statement=rStatement; rStatement: instr=rInstruction @@ -115,13 +110,13 @@ rRegister: ; rPseudoCode: - PREP_ORG expr=rExpression # pseudoOrg - | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu - | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoSet - | PREP_IF expr=rExpression rComment EOL statement=rStatement EOL PREP_ENDIF # pseudoIf - | id=ID_IDENTIFIER PREP_MACRO macro=rMacro? rComment EOL statement=rStatement PREP_ENDM # pseudoMacroDef - | id=ID_IDENTIFIER macroArgs=rMacroArguments? # pseudoMacroCall - | PREP_INCLUDE filename=(LIT_STRING_1|LIT_STRING_2) # pseudoInclude + PREP_ORG expr=rExpression # pseudoOrg + | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu + | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoSet + | PREP_IF expr=rExpression EOL statement=rStatement EOL PREP_ENDIF # pseudoIf + | id=ID_IDENTIFIER PREP_MACRO macro=rMacro? EOL statement=rStatement PREP_ENDM # pseudoMacroDef + | id=ID_IDENTIFIER macroArgs=rMacroArguments? # pseudoMacroCall + | PREP_INCLUDE filename=(LIT_STRING_1|LIT_STRING_2) # pseudoInclude ; rMacro: diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java index 49d597f17..3cfbe36be 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java @@ -8,6 +8,11 @@ public class LexerTest { + @Test + public void testParseEols() { + assertTokenTypes("\n\n\n\n\n", EOL, EOL, EOL, EOL, EOL, EOF); + } + @Test public void testParseError1() { assertTokenTypes("B &", REG_B, ERROR, EOF); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java new file mode 100644 index 000000000..3a77183cd --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java @@ -0,0 +1,15 @@ +package net.emustudio.plugins.compiler.as8080; + +import org.antlr.v4.runtime.tree.ParseTree; +import org.junit.Test; + +public class ParserTest { + + @Test + public void testParse() { + ParseTree tree = Utils.parse("stc\nmvi a, 5"); + + System.out.println(tree.toStringTree()); + + } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java index d1e7a2ffd..d54a82130 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -3,6 +3,7 @@ import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTree; import java.util.ArrayList; import java.util.List; @@ -18,6 +19,14 @@ public static List getTokens(String variation) { return stream.getTokens(); } + public static ParseTree parse(String program) { + As8080Lexer lexer = new As8080Lexer(CharStreams.fromString(program)); + CommonTokenStream stream = new CommonTokenStream(lexer); + As8080Parser parser = new As8080Parser(stream); + stream.fill(); + return parser.rStart(); + } + public static void assertTokenTypes(String variation, int... expectedTypes) { List tokens = getTokens(variation); assertTokenTypes(tokens, expectedTypes); From f84bed467e489f3f47b028c96705207c8582188a Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 3 Dec 2021 11:01:08 +0100 Subject: [PATCH 045/314] [#201] as-8080: fixed grammar + finish 1st phase visitors --- .../as-8080/src/main/antlr/As8080Lexer.g4 | 2 +- .../as-8080/src/main/antlr/As8080Lexer.tokens | 272 +++++++++--------- .../as-8080/src/main/antlr/As8080Parser.g4 | 118 ++++---- .../compiler/as8080/CommonParsers.java | 46 +++ .../plugins/compiler/as8080/ast/Label.java | 10 + .../plugins/compiler/as8080/ast/Program.java | 12 +- .../compiler/as8080/ast/Statement.java | 3 +- .../compiler/as8080/ast/data/Data.java | 2 +- .../compiler/as8080/ast/data/DataDB.java | 12 + .../compiler/as8080/ast/data/DataDW.java | 6 + .../compiler/as8080/ast/expr/ExprBin.java | 10 - .../compiler/as8080/ast/expr/ExprDec.java | 10 - .../compiler/as8080/ast/expr/ExprHex1.java | 10 - .../compiler/as8080/ast/expr/ExprHex2.java | 10 - .../compiler/as8080/ast/expr/ExprId.java | 6 +- .../compiler/as8080/ast/expr/ExprNumber.java | 8 + .../compiler/as8080/ast/expr/ExprOct.java | 10 - .../compiler/as8080/ast/expr/ExprParens.java | 4 - .../as8080/ast/pseudo/PseudoInclude.java | 6 + .../as8080/ast/pseudo/PseudoMacroCall.java | 8 + .../as8080/ast/pseudo/PseudoMacroDef.java | 8 + .../compiler/as8080/visitors/AllVisitors.java | 1 + .../as8080/visitors/CreateProgramVisitor.java | 11 +- .../compiler/as8080/visitors/DataVisitor.java | 42 ++- .../compiler/as8080/visitors/ExprVisitor.java | 13 +- .../as8080/visitors/InstrVisitor.java | 11 +- .../compiler/as8080/visitors/LineVisitor.java | 25 ++ .../as8080/visitors/ProgramVisitor.java | 31 -- .../as8080/visitors/PseudoVisitor.java | 57 +++- .../as8080/visitors/StatementVisitor.java | 8 +- .../compiler/as8080/visitors/Visitors.java | 12 + .../compiler/as8080/CommonParsersTest.java | 75 +++++ 32 files changed, 522 insertions(+), 337 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprBin.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprDec.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex1.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex2.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprOct.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprParens.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/LineVisitor.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ProgramVisitor.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/CommonParsersTest.java diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 index e55622863..0e1636ca0 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 @@ -156,7 +156,7 @@ LIT_STRING_2: '"' ~["]* '"'; // other ID_IDENTIFIER: [a-zA-Z_?@] [a-zA-Z_?@0-9]*; -ID_LABEL: [a-zA-Z_?@] [a-zA-Z_?@0-9]* ':'; +ID_LABEL: ID_IDENTIFIER ':'; ERROR : ~[+* \t\f\r\n(),=/-]+; // below: everything which does not require space diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens index 070cfdfa4..cf48b0b9d 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens @@ -1,138 +1,138 @@ COMMENT=1 COMMENT2=2 -EOL=3 -OPCODE_STC=4 -OPCODE_CMC=5 -OPCODE_INR=6 -OPCODE_DCR=7 -OPCODE_CMA=8 -OPCODE_DAA=9 -OPCODE_NOP=10 -OPCODE_MOV=11 -OPCODE_STAX=12 -OPCODE_LDAX=13 -OPCODE_ADD=14 -OPCODE_ADC=15 -OPCODE_SUB=16 -OPCODE_SBB=17 -OPCODE_ANA=18 -OPCODE_XRA=19 -OPCODE_ORA=20 -OPCODE_CMP=21 -OPCODE_RLC=22 -OPCODE_RRC=23 -OPCODE_RAL=24 -OPCODE_RAR=25 -OPCODE_PUSH=26 -OPCODE_POP=27 -OPCODE_DAD=28 -OPCODE_INX=29 -OPCODE_DCX=30 -OPCODE_XCHG=31 -OPCODE_XTHL=32 -OPCODE_SPHL=33 -OPCODE_LXI=34 -OPCODE_MVI=35 -OPCODE_ADI=36 -OPCODE_ACI=37 -OPCODE_SUI=38 -OPCODE_SBI=39 -OPCODE_ANI=40 -OPCODE_XRI=41 -OPCODE_ORI=42 -OPCODE_CPI=43 -OPCODE_STA=44 -OPCODE_LDA=45 -OPCODE_SHLD=46 -OPCODE_LHLD=47 -OPCODE_PCHL=48 -OPCODE_JMP=49 -OPCODE_JC=50 -OPCODE_JNC=51 -OPCODE_JZ=52 -OPCODE_JNZ=53 -OPCODE_JP=54 -OPCODE_JM=55 -OPCODE_JPE=56 -OPCODE_JPO=57 -OPCODE_CALL=58 -OPCODE_CC=59 -OPCODE_CNC=60 -OPCODE_CZ=61 -OPCODE_CNZ=62 -OPCODE_CP=63 -OPCODE_CM=64 -OPCODE_CPE=65 -OPCODE_CPO=66 -OPCODE_RET=67 -OPCODE_RC=68 -OPCODE_RNC=69 -OPCODE_RZ=70 -OPCODE_RNZ=71 -OPCODE_RM=72 -OPCODE_RP=73 -OPCODE_RPE=74 -OPCODE_RPO=75 -OPCODE_RST=76 -OPCODE_EI=77 -OPCODE_DI=78 -OPCODE_IN=79 -OPCODE_OUT=80 -OPCODE_HLT=81 -PREP_ORG=82 -PREP_EQU=83 -PREP_SET=84 -PREP_INCLUDE=85 -PREP_IF=86 -PREP_ENDIF=87 -PREP_MACRO=88 -PREP_ENDM=89 -PREP_DB=90 -PREP_DW=91 -PREP_DS=92 -PREP_ADDR=93 -REG_A=94 -REG_B=95 -REG_C=96 -REG_D=97 -REG_E=98 -REG_H=99 -REG_L=100 -REG_M=101 -REG_PSW=102 -REG_SP=103 -OP_MOD=104 -OP_SHR=105 -OP_SHL=106 -OP_NOT=107 -OP_AND=108 -OP_OR=109 -OP_XOR=110 -LIT_HEXNUMBER_1=111 -LIT_NUMBER=112 -LIT_HEXNUMBER_2=113 -LIT_OCTNUMBER=114 -LIT_BINNUMBER=115 -LIT_STRING_1=116 -LIT_STRING_2=117 -ID_IDENTIFIER=118 -ID_LABEL=119 -ERROR=120 -SEP_LPAR=121 -SEP_RPAR=122 -SEP_COMMA=123 -OP_ADD=124 -OP_SUBTRACT=125 -OP_MULTIPLY=126 -OP_DIVIDE=127 -OP_EQUAL=128 -WS=129 -'$'=93 -'('=121 -')'=122 -','=123 -'+'=124 -'-'=125 -'*'=126 -'/'=127 -'='=128 +OPCODE_STC=3 +OPCODE_CMC=4 +OPCODE_INR=5 +OPCODE_DCR=6 +OPCODE_CMA=7 +OPCODE_DAA=8 +OPCODE_NOP=9 +OPCODE_MOV=10 +OPCODE_STAX=11 +OPCODE_LDAX=12 +OPCODE_ADD=13 +OPCODE_ADC=14 +OPCODE_SUB=15 +OPCODE_SBB=16 +OPCODE_ANA=17 +OPCODE_XRA=18 +OPCODE_ORA=19 +OPCODE_CMP=20 +OPCODE_RLC=21 +OPCODE_RRC=22 +OPCODE_RAL=23 +OPCODE_RAR=24 +OPCODE_PUSH=25 +OPCODE_POP=26 +OPCODE_DAD=27 +OPCODE_INX=28 +OPCODE_DCX=29 +OPCODE_XCHG=30 +OPCODE_XTHL=31 +OPCODE_SPHL=32 +OPCODE_LXI=33 +OPCODE_MVI=34 +OPCODE_ADI=35 +OPCODE_ACI=36 +OPCODE_SUI=37 +OPCODE_SBI=38 +OPCODE_ANI=39 +OPCODE_XRI=40 +OPCODE_ORI=41 +OPCODE_CPI=42 +OPCODE_STA=43 +OPCODE_LDA=44 +OPCODE_SHLD=45 +OPCODE_LHLD=46 +OPCODE_PCHL=47 +OPCODE_JMP=48 +OPCODE_JC=49 +OPCODE_JNC=50 +OPCODE_JZ=51 +OPCODE_JNZ=52 +OPCODE_JP=53 +OPCODE_JM=54 +OPCODE_JPE=55 +OPCODE_JPO=56 +OPCODE_CALL=57 +OPCODE_CC=58 +OPCODE_CNC=59 +OPCODE_CZ=60 +OPCODE_CNZ=61 +OPCODE_CP=62 +OPCODE_CM=63 +OPCODE_CPE=64 +OPCODE_CPO=65 +OPCODE_RET=66 +OPCODE_RC=67 +OPCODE_RNC=68 +OPCODE_RZ=69 +OPCODE_RNZ=70 +OPCODE_RM=71 +OPCODE_RP=72 +OPCODE_RPE=73 +OPCODE_RPO=74 +OPCODE_RST=75 +OPCODE_EI=76 +OPCODE_DI=77 +OPCODE_IN=78 +OPCODE_OUT=79 +OPCODE_HLT=80 +PREP_ORG=81 +PREP_EQU=82 +PREP_SET=83 +PREP_INCLUDE=84 +PREP_IF=85 +PREP_ENDIF=86 +PREP_MACRO=87 +PREP_ENDM=88 +PREP_DB=89 +PREP_DW=90 +PREP_DS=91 +PREP_ADDR=92 +REG_A=93 +REG_B=94 +REG_C=95 +REG_D=96 +REG_E=97 +REG_H=98 +REG_L=99 +REG_M=100 +REG_PSW=101 +REG_SP=102 +OP_MOD=103 +OP_SHR=104 +OP_SHL=105 +OP_NOT=106 +OP_AND=107 +OP_OR=108 +OP_XOR=109 +LIT_HEXNUMBER_1=110 +LIT_NUMBER=111 +LIT_HEXNUMBER_2=112 +LIT_OCTNUMBER=113 +LIT_BINNUMBER=114 +LIT_STRING_1=115 +LIT_STRING_2=116 +ID_IDENTIFIER=117 +ID_LABEL=118 +ERROR=119 +SEP_LPAR=120 +SEP_RPAR=121 +SEP_COMMA=122 +OP_ADD=123 +OP_SUBTRACT=124 +OP_MULTIPLY=125 +OP_DIVIDE=126 +OP_EQUAL=127 +WS=128 +EOL=129 +'$'=92 +'('=120 +')'=121 +','=122 +'+'=123 +'-'=124 +'*'=125 +'/'=126 +'='=127 diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index 78d501ab7..2d9e6a918 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -5,11 +5,11 @@ options { } rStart: - EOL* rLine? (EOL+ rLine)* EOL* EOF + EOL* rLine (EOL+ rLine)* EOL* EOF ; rLine: - label=ID_LABEL? statement=rStatement; + label=ID_LABEL? EOL* statement=rStatement?; rStatement: instr=rInstruction @@ -18,6 +18,44 @@ rStatement: ; rInstruction: + r8bitInstruction # instr8bit + | opcode=OPCODE_MVI reg=rRegister SEP_COMMA expr=rExpression # instrRegExpr + | opcode=OPCODE_LXI regpair=(REG_B|REG_D|REG_H|REG_SP) SEP_COMMA expr=rExpression # instrRegPairExpr + | opcode=OPCODE_LDA expr=rExpression # instrExpr + | opcode=OPCODE_STA expr=rExpression # instrExpr + | opcode=OPCODE_LHLD expr=rExpression # instrExpr + | opcode=OPCODE_SHLD expr=rExpression # instrExpr + | opcode=OPCODE_ADI expr=rExpression # instrExpr + | opcode=OPCODE_ACI expr=rExpression # instrExpr + | opcode=OPCODE_SUI expr=rExpression # instrExpr + | opcode=OPCODE_SBI expr=rExpression # instrExpr + | opcode=OPCODE_ANI expr=rExpression # instrExpr + | opcode=OPCODE_ORI expr=rExpression # instrExpr + | opcode=OPCODE_XRI expr=rExpression # instrExpr + | opcode=OPCODE_CPI expr=rExpression # instrExpr + | opcode=OPCODE_JMP expr=rExpression # instrExpr + | opcode=OPCODE_JC expr=rExpression # instrExpr + | opcode=OPCODE_JNC expr=rExpression # instrExpr + | opcode=OPCODE_JZ expr=rExpression # instrExpr + | opcode=OPCODE_JNZ expr=rExpression # instrExpr + | opcode=OPCODE_JM expr=rExpression # instrExpr + | opcode=OPCODE_JP expr=rExpression # instrExpr + | opcode=OPCODE_JPE expr=rExpression # instrExpr + | opcode=OPCODE_JPO expr=rExpression # instrExpr + | opcode=OPCODE_CALL expr=rExpression # instrExpr + | opcode=OPCODE_CC expr=rExpression # instrExpr + | opcode=OPCODE_CNC expr=rExpression # instrExpr + | opcode=OPCODE_CZ expr=rExpression # instrExpr + | opcode=OPCODE_CNZ expr=rExpression # instrExpr + | opcode=OPCODE_CM expr=rExpression # instrExpr + | opcode=OPCODE_CP expr=rExpression # instrExpr + | opcode=OPCODE_CPE expr=rExpression # instrExpr + | opcode=OPCODE_CPO expr=rExpression # instrExpr + | opcode=OPCODE_IN expr=rExpression # instrExpr + | opcode=OPCODE_OUT expr=rExpression # instrExpr + ; + +r8bitInstruction: opcode=OPCODE_STC # instrNoArgs | opcode=OPCODE_CMC # instrNoArgs | opcode=OPCODE_CMA # instrNoArgs @@ -61,41 +99,7 @@ rInstruction: | opcode=OPCODE_DAD regpair=(REG_B|REG_D|REG_H|REG_SP) # instrRegPair | opcode=OPCODE_INX regpair=(REG_B|REG_D|REG_H|REG_SP) # instrRegPair | opcode=OPCODE_DCX regpair=(REG_B|REG_D|REG_H|REG_SP) # instrRegPair - | opcode=OPCODE_LXI regpair=(REG_B|REG_D|REG_H|REG_SP) SEP_COMMA expr=rExpression # instrRegPairExpr - | opcode=OPCODE_MVI reg=rRegister SEP_COMMA expr=rExpression # instrRegExpr - | opcode=OPCODE_ADI expr=rExpression # instrExpr - | opcode=OPCODE_ACI expr=rExpression # instrExpr - | opcode=OPCODE_SUI expr=rExpression # instrExpr - | opcode=OPCODE_SBI expr=rExpression # instrExpr - | opcode=OPCODE_ANI expr=rExpression # instrExpr - | opcode=OPCODE_XRI expr=rExpression # instrExpr - | opcode=OPCODE_ORI expr=rExpression # instrExpr - | opcode=OPCODE_CPI expr=rExpression # instrExpr - | opcode=OPCODE_STA expr=rExpression # instrExpr - | opcode=OPCODE_LDA expr=rExpression # instrExpr - | opcode=OPCODE_SHLD expr=rExpression # instrExpr - | opcode=OPCODE_LHLD expr=rExpression # instrExpr - | opcode=OPCODE_JMP expr=rExpression # instrExpr - | opcode=OPCODE_JC expr=rExpression # instrExpr - | opcode=OPCODE_JNC expr=rExpression # instrExpr - | opcode=OPCODE_JZ expr=rExpression # instrExpr - | opcode=OPCODE_JNZ expr=rExpression # instrExpr - | opcode=OPCODE_JM expr=rExpression # instrExpr - | opcode=OPCODE_JP expr=rExpression # instrExpr - | opcode=OPCODE_JPE expr=rExpression # instrExpr - | opcode=OPCODE_JPO expr=rExpression # instrExpr - | opcode=OPCODE_CALL expr=rExpression # instrExpr - | opcode=OPCODE_CC expr=rExpression # instrExpr - | opcode=OPCODE_CNC expr=rExpression # instrExpr - | opcode=OPCODE_CZ expr=rExpression # instrExpr - | opcode=OPCODE_CNZ expr=rExpression # instrExpr - | opcode=OPCODE_CM expr=rExpression # instrExpr - | opcode=OPCODE_CP expr=rExpression # instrExpr - | opcode=OPCODE_CPE expr=rExpression # instrExpr - | opcode=OPCODE_CPO expr=rExpression # instrExpr - | opcode=OPCODE_RST expr=rExpression # instrExpr - | opcode=OPCODE_IN expr=rExpression # instrExpr - | opcode=OPCODE_OUT expr=rExpression # instrExpr + | opcode=OPCODE_RST expr=rExpression # instr8bitExpr ; rRegister: @@ -110,41 +114,33 @@ rRegister: ; rPseudoCode: - PREP_ORG expr=rExpression # pseudoOrg - | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu - | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoSet - | PREP_IF expr=rExpression EOL statement=rStatement EOL PREP_ENDIF # pseudoIf - | id=ID_IDENTIFIER PREP_MACRO macro=rMacro? EOL statement=rStatement PREP_ENDM # pseudoMacroDef - | id=ID_IDENTIFIER macroArgs=rMacroArguments? # pseudoMacroCall - | PREP_INCLUDE filename=(LIT_STRING_1|LIT_STRING_2) # pseudoInclude + PREP_ORG expr=rExpression # pseudoOrg + | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu + | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoSet + | PREP_IF expr=rExpression EOL statement=rStatement EOL+ PREP_ENDIF # pseudoIf + | id=ID_IDENTIFIER PREP_MACRO params=rMacroParameters? (EOL+ rLine)+ EOL+ PREP_ENDM # pseudoMacroDef + | id=ID_IDENTIFIER args=rMacroArguments? # pseudoMacroCall + | PREP_INCLUDE filename=(LIT_STRING_1|LIT_STRING_2) # pseudoInclude ; -rMacro: - id=ID_IDENTIFIER (SEP_COMMA ids=ID_IDENTIFIER)* +rMacroParameters: + id=ID_IDENTIFIER (SEP_COMMA ID_IDENTIFIER)* ; rMacroArguments: - expr=rExpression (SEP_COMMA exprs=rExpression)* + expr=rExpression (SEP_COMMA rExpression)* ; rData: - PREP_DB data=rDB # dataDB - | PREP_DW data=rDW # dataDW - | PREP_DS data=rExpression # dataDS - ; - -rDB: - data=rDBdata (SEP_COMMA data=rDBdata)* - ; - -rDW: - data=rDWdata (SEP_COMMA data=rDWdata)* + PREP_DB data=rDBdata (SEP_COMMA rDBdata)* # dataDB + | PREP_DW data=rDWdata (SEP_COMMA rDWdata)* # dataDW + | PREP_DS data=rExpression # dataDS ; rDBdata: expr=rExpression | str=(LIT_STRING_1|LIT_STRING_2) - | instr=rInstruction + | instr=r8bitInstruction ; rDWdata: @@ -152,8 +148,7 @@ rDWdata: ; rExpression: - SEP_LPAR expr=rExpression SEP_RPAR # exprParens - | num=LIT_NUMBER # exprDec + num=LIT_NUMBER # exprDec | num=LIT_HEXNUMBER_1 # exprHex1 | num=LIT_HEXNUMBER_2 # exprHex2 | num=LIT_OCTNUMBER # exprOct @@ -166,4 +161,5 @@ rExpression: | unaryop=OP_NOT expr=rExpression # exprUnary | expr1=rExpression op=OP_AND expr2=rExpression # exprInfix | expr1=rExpression op=(OP_OR|OP_XOR) expr2=rExpression # exprInfix + | SEP_LPAR expr=rExpression SEP_RPAR # exprParens ; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java new file mode 100644 index 000000000..cab5dc4cf --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java @@ -0,0 +1,46 @@ +package net.emustudio.plugins.compiler.as8080; + +import org.antlr.v4.runtime.Token; + +public class CommonParsers { + + public static String parseLitString(Token token) { + // LIT_STRING_1: '\'' ~[']* '\''; + // LIT_STRING_2: '"' ~["]* '"'; + String text = token.getText(); + return text.substring(1, text.length() - 1); + } + + public static int parseLitHex1(Token token) { + // LIT_HEXNUMBER_1: [\-]? '0' X [0-9a-fA-F]+; + return Integer.decode(token.getText()); + } + + public static int parseLitHex2(Token token) { + // LIT_HEXNUMBER_2: [\-]? [0-9a-fA-F]+ H; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 16); + } + + public static int parseLitOct(Token token) { + // LIT_OCTNUMBER: [\-]? [0-7]+ [oOqQ]; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 8); + } + + public static int parseLitDec(Token token) { + // LIT_NUMBER: [\-]? [0-9]+ D? + String rawText = token.getText(); + if (rawText.endsWith("d") || rawText.endsWith("D")) { + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 10); + } else { + return Integer.parseInt(rawText, 10); + } + } + + public static int parseLitBin(Token token) { + // LIT_BINNUMBER: [01]+ B; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 2); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java new file mode 100644 index 000000000..d93c088ef --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast; + +import org.antlr.v4.runtime.Token; + +public class Label extends AbstractNode { + + public Label(Token label) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java index f790e0b35..5fa429710 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java @@ -1,20 +1,12 @@ package net.emustudio.plugins.compiler.as8080.ast; -import net.emustudio.plugins.compiler.as8080.ast.instr.Instr; - -import java.util.LinkedList; -import java.util.List; - public class Program extends AbstractNode { private final NameSpace nameSpace = new NameSpace(); - private final List instructions = new LinkedList<>(); + public NameSpace env() { return nameSpace; } - public Program addIntruction(Instr instr) { - instructions.add(instr); - return this; - } + } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java index 4b2c5be6d..0d198bfad 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java @@ -1,4 +1,5 @@ package net.emustudio.plugins.compiler.as8080.ast; -public class Statement { +public class Statement extends AbstractNode { + } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java index 8dfa67a7a..71cadcc0d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java @@ -2,5 +2,5 @@ import net.emustudio.plugins.compiler.as8080.ast.AbstractNode; -public abstract class Data extends AbstractNode { +public class Data extends AbstractNode { } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java index 7b0465b8a..a81d7ca75 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java @@ -1,4 +1,16 @@ package net.emustudio.plugins.compiler.as8080.ast.data; +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import net.emustudio.plugins.compiler.as8080.ast.instr.Instr; + public class DataDB extends Data { + + public DataDB(Expr expr) { + } + + public DataDB(String string) { + } + + public DataDB(Instr instr) { + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java index 128253e8c..c42544006 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java @@ -1,4 +1,10 @@ package net.emustudio.plugins.compiler.as8080.ast.data; +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; + public class DataDW extends Data { + + public DataDW(Expr expr) { + // expr=rExpression + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprBin.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprBin.java deleted file mode 100644 index 31591dc6c..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprBin.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast.expr; - -import org.antlr.v4.runtime.Token; - -public class ExprBin extends Expr { - - public ExprBin(Token number) { - - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprDec.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprDec.java deleted file mode 100644 index 9dad612ee..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprDec.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast.expr; - -import org.antlr.v4.runtime.Token; - -public class ExprDec extends Expr { - - public ExprDec(Token number) { - - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex1.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex1.java deleted file mode 100644 index d53c2455d..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex1.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast.expr; - -import org.antlr.v4.runtime.Token; - -public class ExprHex1 extends Expr { - - public ExprHex1(Token number) { - // TODO: parse - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex2.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex2.java deleted file mode 100644 index 944cabfc9..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprHex2.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast.expr; - -import org.antlr.v4.runtime.Token; - -public class ExprHex2 extends Expr { - - public ExprHex2(Token number) { - - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java index d5fee8f62..a69e567ca 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java @@ -1,13 +1,11 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import org.antlr.v4.runtime.Token; - import java.util.Objects; public class ExprId extends Expr { - private final Token id; + private final String id; - public ExprId(Token id) { + public ExprId(String id) { this.id = Objects.requireNonNull(id); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java new file mode 100644 index 000000000..30b270846 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java @@ -0,0 +1,8 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +public class ExprNumber extends Expr { + + public ExprNumber(int number) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprOct.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprOct.java deleted file mode 100644 index 14e50cf2f..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprOct.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast.expr; - -import org.antlr.v4.runtime.Token; - -public class ExprOct extends Expr { - - public ExprOct(Token number) { - // TODO: parse - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprParens.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprParens.java deleted file mode 100644 index 36785cd5b..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprParens.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast.expr; - -public class ExprParens extends Expr { -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java index 7cb5ff038..4d45b68a2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java @@ -1,4 +1,10 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; +import org.antlr.v4.runtime.Token; + public class PseudoInclude extends Pseudo { + + public PseudoInclude(Token fileName) { + + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java index ede8456e7..5682f441a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java @@ -1,4 +1,12 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import org.antlr.v4.runtime.Token; + +import java.util.List; + public class PseudoMacroCall extends Pseudo { + + public PseudoMacroCall(Token id, List arguments) { + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java index 59134b352..ae23c48b9 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java @@ -1,4 +1,12 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; +import net.emustudio.plugins.compiler.as8080.ast.Statement; +import org.antlr.v4.runtime.Token; + +import java.util.List; + public class PseudoMacroDef extends Pseudo { + + public PseudoMacroDef(Token id, List parameters, List statements) { + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java index cf325c6c4..badf8bb87 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java @@ -7,4 +7,5 @@ public class AllVisitors { static InstrVisitor instr = new InstrVisitor(); static DataVisitor data = new DataVisitor(); static StatementVisitor statement = new StatementVisitor(); + static LineVisitor line = new LineVisitor(); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java index f377437ae..1e92725c2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java @@ -4,18 +4,21 @@ import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; -import java.util.Optional; +import java.util.Objects; /** * The visitor creates internal AST (= "Program") of the parse tree. */ public class CreateProgramVisitor extends As8080ParserBaseVisitor { - private final Program program = new Program(); + private final Program program; + + public CreateProgramVisitor(Program program) { + this.program = Objects.requireNonNull(program); + } @Override public Program visitRLine(As8080Parser.RLineContext ctx) { - Optional.ofNullable(ctx.label).ifPresent(program.env()::addLabel); - program.addChild(AllVisitors.statement.visit(ctx.statement)); + program.addChild(Visitors.line.visitRLine(ctx)); return program; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java index 0eba7125d..4597b3976 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java @@ -1,7 +1,8 @@ package net.emustudio.plugins.compiler.as8080.visitors; -import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.As8080Parser.*; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.CommonParsers; import net.emustudio.plugins.compiler.as8080.ast.data.Data; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; @@ -10,18 +11,47 @@ public class DataVisitor extends As8080ParserBaseVisitor { @Override - public Data visitDataDB(As8080Parser.DataDBContext ctx) { + public Data visitDataDB(DataDBContext ctx) { + Data data = new Data(); - return new DataDB(); + if (ctx.data.expr != null) { + data.addChild(new DataDB(AllVisitors.expr.visit(ctx.data.expr))); + } else if (ctx.data.instr != null) { + data.addChild(new DataDB(AllVisitors.instr.visit(ctx.data.instr))); + } else { + data.addChild(new DataDB(CommonParsers.parseLitString(ctx.data.str))); + } + for (RDBdataContext next : ctx.rDBdata()) { + if (next.expr != null) { + data.addChild(new DataDB(AllVisitors.expr.visit(next.expr))); + } else if (next.instr != null) { + data.addChild(new DataDB(AllVisitors.instr.visit(next.instr))); + } else { + data.addChild(new DataDB(CommonParsers.parseLitString(next.str))); + } + } + + return data; } @Override - public Data visitDataDW(As8080Parser.DataDWContext ctx) { - return new DataDW(); + public Data visitDataDW(DataDWContext ctx) { + Data data = new Data(); + + if (ctx.data.expr != null) { + data.addChild(new DataDW(AllVisitors.expr.visit(ctx.data.expr))); + } + for (RDWdataContext next : ctx.rDWdata()) { + if (next.expr != null) { + data.addChild(new DataDW(AllVisitors.expr.visit(next.expr))); + } + } + + return data; } @Override - public Data visitDataDS(As8080Parser.DataDSContext ctx) { + public Data visitDataDS(DataDSContext ctx) { return new DataDS(AllVisitors.expr.visit(ctx.data)); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java index 48250f3a5..a8cba0c2a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java @@ -2,38 +2,39 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.CommonParsers; import net.emustudio.plugins.compiler.as8080.ast.expr.*; public class ExprVisitor extends As8080ParserBaseVisitor { @Override public Expr visitExprOct(As8080Parser.ExprOctContext ctx) { - return new ExprOct(ctx.num); + return new ExprNumber(CommonParsers.parseLitOct(ctx.num)); } @Override public Expr visitExprHex1(As8080Parser.ExprHex1Context ctx) { - return new ExprHex1(ctx.num); + return new ExprNumber(CommonParsers.parseLitHex1(ctx.num)); } @Override public Expr visitExprHex2(As8080Parser.ExprHex2Context ctx) { - return new ExprHex2(ctx.num); + return new ExprNumber(CommonParsers.parseLitHex2(ctx.num)); } @Override public Expr visitExprDec(As8080Parser.ExprDecContext ctx) { - return new ExprDec(ctx.num); + return new ExprNumber(CommonParsers.parseLitDec(ctx.num)); } @Override public Expr visitExprBin(As8080Parser.ExprBinContext ctx) { - return new ExprBin(ctx.num); + return new ExprNumber(CommonParsers.parseLitBin(ctx.num)); } @Override public Expr visitExprId(As8080Parser.ExprIdContext ctx) { - return new ExprId(ctx.id); + return new ExprId(ctx.id.getText()); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java index 4116e009c..80f78c325 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java @@ -28,16 +28,21 @@ public Instr visitInstrRegPair(As8080Parser.InstrRegPairContext ctx) { @Override public Instr visitInstrRegPairExpr(As8080Parser.InstrRegPairExprContext ctx) { - return new InstrRegPairExpr(ctx.opcode, ctx.regpair, AllVisitors.expr.visit(ctx.expr)); + return new InstrRegPairExpr(ctx.opcode, ctx.regpair, Visitors.expr.visit(ctx.expr)); } @Override public Instr visitInstrRegExpr(As8080Parser.InstrRegExprContext ctx) { - return new InstrRegExpr(ctx.opcode, ctx.reg.start, AllVisitors.expr.visit(ctx.expr)); + return new InstrRegExpr(ctx.opcode, ctx.reg.start, Visitors.expr.visit(ctx.expr)); } @Override public Instr visitInstrExpr(As8080Parser.InstrExprContext ctx) { - return new InstrExpr(ctx.opcode, AllVisitors.expr.visit(ctx.expr)); + return new InstrExpr(ctx.opcode, Visitors.expr.visit(ctx.expr)); + } + + @Override + public Instr visitInstr8bitExpr(As8080Parser.Instr8bitExprContext ctx) { + return new InstrExpr(ctx.opcode, Visitors.expr.visit(ctx.expr)); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/LineVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/LineVisitor.java new file mode 100644 index 000000000..81a69b2d7 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/LineVisitor.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Label; +import net.emustudio.plugins.compiler.as8080.ast.Statement; + +import java.util.Optional; + +public class LineVisitor extends As8080ParserBaseVisitor { + private Statement statement; + + @Override + public Statement visitRLine(As8080Parser.RLineContext ctx) { + statement = new Statement(); + Optional.ofNullable(ctx.label).ifPresent(label -> statement.addChild(new Label(label))); + return visitChildren(ctx); + } + + @Override + public Statement visitRStatement(As8080Parser.RStatementContext ctx) { + statement.addChild(Visitors.statement.visitRStatement(ctx)); + return statement; + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ProgramVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ProgramVisitor.java deleted file mode 100644 index 7293c9fa1..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ProgramVisitor.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.visitors; - -import net.emustudio.plugins.compiler.as8080.As8080Parser; -import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; -import net.emustudio.plugins.compiler.as8080.ast.Program; -import net.emustudio.plugins.compiler.as8080.visitors.InstrVisitor; - -import java.util.Optional; - -public class ProgramVisitor extends As8080ParserBaseVisitor { - private final Program program = new Program(); - - @Override - public Program visitRLine(As8080Parser.RLineContext ctx) { - Optional.ofNullable(ctx.label).ifPresent(program.env()::addLabel); - return super.visitRLine(ctx); - } - - @Override - public Program visitRStatement(As8080Parser.RStatementContext ctx) { - Optional.ofNullable(ctx.instr).ifPresent(i -> program.addIntruction(new InstrVisitor().visit(i))); - //Optional.ofNullable(ctx.pseudo).ifPresent(p -> ); - // Optional.ofNullable(ctx.data).ifPresent(d -> ); - - return program; - } - - - - -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java index 474d72996..fdd8e32dc 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java @@ -1,43 +1,70 @@ package net.emustudio.plugins.compiler.as8080.visitors; -import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.As8080Parser.*; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Statement; +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.TerminalNode; + +import java.util.ArrayList; +import java.util.List; public class PseudoVisitor extends As8080ParserBaseVisitor { @Override - public Pseudo visitPseudoOrg(As8080Parser.PseudoOrgContext ctx) { - return new PseudoOrg(AllVisitors.expr.visit(ctx.expr)); + public Pseudo visitPseudoOrg(PseudoOrgContext ctx) { + return new PseudoOrg(Visitors.expr.visit(ctx.expr)); } @Override - public Pseudo visitPseudoEqu(As8080Parser.PseudoEquContext ctx) { - return new PseudoEqu(ctx.id, AllVisitors.expr.visit(ctx.expr)); + public Pseudo visitPseudoEqu(PseudoEquContext ctx) { + return new PseudoEqu(ctx.id, Visitors.expr.visit(ctx.expr)); } @Override - public Pseudo visitPseudoSet(As8080Parser.PseudoSetContext ctx) { - return new PseudoSet(ctx.id, AllVisitors.expr.visit(ctx.expr)); + public Pseudo visitPseudoSet(PseudoSetContext ctx) { + return new PseudoSet(ctx.id, Visitors.expr.visit(ctx.expr)); } @Override - public Pseudo visitPseudoIf(As8080Parser.PseudoIfContext ctx) { - return new PseudoIf(AllVisitors.expr.visit(ctx.expr), AllVisitors.statement.visit(ctx.statement)); + public Pseudo visitPseudoIf(PseudoIfContext ctx) { + return new PseudoIf(Visitors.expr.visit(ctx.expr), Visitors.statement.visit(ctx.statement)); } @Override - public Pseudo visitPseudoMacroDef(As8080Parser.PseudoMacroDefContext ctx) { - return new PseudoMacroDef(); + public Pseudo visitPseudoMacroDef(PseudoMacroDefContext ctx) { + List params = new ArrayList<>(); + if (ctx.params != null) { + params.add(ctx.params.id); + for (TerminalNode next : ctx.params.ID_IDENTIFIER()) { + params.add(next.getSymbol()); + } + } + + List statements = new ArrayList<>(); + for (RLineContext line : ctx.rLine()) { + statements.add(AllVisitors.line.visitRLine(line)); + } + + return new PseudoMacroDef(ctx.id, params, statements); } @Override - public Pseudo visitPseudoMacroCall(As8080Parser.PseudoMacroCallContext ctx) { - return new PseudoMacroCall(); + public Pseudo visitPseudoMacroCall(PseudoMacroCallContext ctx) { + List arguments = new ArrayList<>(); + if (ctx.args != null) { + arguments.add(AllVisitors.expr.visit(ctx.args.expr)); + for (RExpressionContext next : ctx.args.rExpression()) { + arguments.add(AllVisitors.expr.visit(next)); + } + } + return new PseudoMacroCall(ctx.id, arguments); } @Override - public Pseudo visitPseudoInclude(As8080Parser.PseudoIncludeContext ctx) { - return new PseudoInclude(); + public Pseudo visitPseudoInclude(PseudoIncludeContext ctx) { + return new PseudoInclude(ctx.filename); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java index a16f02e97..6f26815f0 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java @@ -9,14 +9,14 @@ public class StatementVisitor extends As8080ParserBaseVisitor { @Override public Node visitRStatement(As8080Parser.RStatementContext ctx) { if (ctx.instr != null) { - return AllVisitors.instr.visit(ctx.instr); + return Visitors.instr.visit(ctx.instr); } if (ctx.data != null) { - return AllVisitors.data.visit(ctx.data); + return Visitors.data.visit(ctx.data); } if (ctx.pseudo != null) { - return AllVisitors.pseudo.visit(ctx.pseudo); + return Visitors.pseudo.visit(ctx.pseudo); } - throw new RuntimeException("No statement!"); + throw new IllegalStateException("No statement defined!"); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java new file mode 100644 index 000000000..60ee9624f --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java @@ -0,0 +1,12 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +public class Visitors { + + static PseudoVisitor pseudo = new PseudoVisitor(); + static ExprVisitor expr = new ExprVisitor(); + static InstrVisitor instr = new InstrVisitor(); + static DataVisitor data = new DataVisitor(); + static StatementVisitor statement = new StatementVisitor(); + static LineVisitor line = new LineVisitor(); + +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/CommonParsersTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/CommonParsersTest.java new file mode 100644 index 000000000..6df64ab44 --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/CommonParsersTest.java @@ -0,0 +1,75 @@ +package net.emustudio.plugins.compiler.as8080; + +import org.antlr.v4.runtime.Token; +import org.junit.Test; + +import java.util.List; + +import static net.emustudio.plugins.compiler.as8080.Utils.assertTokenTypes; +import static net.emustudio.plugins.compiler.as8080.Utils.getTokens; +import static org.junit.Assert.assertEquals; + +public class CommonParsersTest { + + @Test + public void testParseLitString() { + List tokens = getTokens("'te\"x\"t1' \"te'x't2\""); + assertTokenTypes(tokens, As8080Parser.LIT_STRING_1, As8080Parser.LIT_STRING_2, As8080Parser.EOF); + assertEquals("te\"x\"t1", CommonParsers.parseLitString(tokens.get(0))); + assertEquals("te'x't2", CommonParsers.parseLitString(tokens.get(1))); + } + + @Test + public void testParseLitHex1() { + List tokens = getTokens("-0x22F 0XAA55"); + assertTokenTypes(tokens, As8080Parser.LIT_HEXNUMBER_1, As8080Parser.LIT_HEXNUMBER_1, As8080Parser.EOF); + assertEquals(-0x22F, CommonParsers.parseLitHex1(tokens.get(0))); + assertEquals(0xAA55, CommonParsers.parseLitHex1(tokens.get(1))); + } + + @Test + public void testParseLitHex2() { + List tokens = getTokens("-022Fh AA55H"); + assertTokenTypes(tokens, As8080Parser.LIT_HEXNUMBER_2, As8080Parser.LIT_HEXNUMBER_2, As8080Parser.EOF); + assertEquals(-0x22F, CommonParsers.parseLitHex2(tokens.get(0))); + assertEquals(0xAA55, CommonParsers.parseLitHex2(tokens.get(1))); + } + + @Test + public void testParseLitOct() { + List tokens = getTokens("-22q 55O 77Q -001o"); + assertTokenTypes( + tokens, + As8080Parser.LIT_OCTNUMBER, As8080Parser.LIT_OCTNUMBER, As8080Parser.LIT_OCTNUMBER, + As8080Parser.LIT_OCTNUMBER, As8080Parser.EOF + ); + assertEquals(-18, CommonParsers.parseLitOct(tokens.get(0))); + assertEquals(45, CommonParsers.parseLitOct(tokens.get(1))); + assertEquals(63, CommonParsers.parseLitOct(tokens.get(2))); + assertEquals(-1, CommonParsers.parseLitOct(tokens.get(3))); + } + + @Test + public void testParseLitDec() { + List tokens = getTokens("-22 55 00"); + assertTokenTypes( + tokens, + As8080Parser.LIT_NUMBER, As8080Parser.LIT_NUMBER, As8080Parser.LIT_NUMBER, As8080Parser.EOF + ); + assertEquals(-22, CommonParsers.parseLitDec(tokens.get(0))); + assertEquals(55, CommonParsers.parseLitDec(tokens.get(1))); + assertEquals(0, CommonParsers.parseLitDec(tokens.get(2))); + } + + @Test + public void testParseLitBin() { + List tokens = getTokens("000b 0101101b 111b"); + assertTokenTypes( + tokens, + As8080Parser.LIT_BINNUMBER, As8080Parser.LIT_BINNUMBER, As8080Parser.LIT_BINNUMBER, As8080Parser.EOF + ); + assertEquals(0, CommonParsers.parseLitBin(tokens.get(0))); + assertEquals(45, CommonParsers.parseLitBin(tokens.get(1))); + assertEquals(7, CommonParsers.parseLitBin(tokens.get(2))); + } +} From 9e496deadacf8b668a5ff781ceb548efde02dde0 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 3 Dec 2021 11:08:01 +0100 Subject: [PATCH 046/314] [#201] fix build --- .../plugins/cpu/intel8080/EmulatorEngine.java | 3 +-- .../net/emustudio/plugins/cpu/ssem/EmulatorEngine.java | 3 +-- settings.gradle | 10 +++++----- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java index 3ff51b1a6..28c1c5792 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java @@ -62,7 +62,6 @@ public class EmulatorEngine implements CpuEngine { private final ContextImpl context; private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); - private final SleepUtils.Sleep sleep = SleepUtils.sleep; private long executedCycles = 0; private volatile DispatchListener dispatchListener; @@ -146,7 +145,7 @@ public CPU.RunState run(CPU cpu) { endTime = System.nanoTime() - startTime; if (endTime < slice) { // time correction - sleep.sleep(slice - endTime); + SleepUtils.preciseSleepNanos(slice - endTime); } } return currentRunState; diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java index 5fafc8fa6..7e8bc5f7a 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java @@ -45,7 +45,6 @@ public class EmulatorEngine { public final static int INSTRUCTIONS_PER_SECOND = 700; final static int LINE_MASK = 0b11111000; - private final SleepUtils.Sleep sleep = SleepUtils.sleep; private final TimingEstimator estimator = new TimingEstimator(); private volatile long waitNanos = -1; @@ -183,7 +182,7 @@ CPU.RunState run() { LOGGER.debug("Unexpected error", e); return CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; } - sleep.sleep(waitNanos); + SleepUtils.preciseSleepNanos(waitNanos); } return currentRunState; } diff --git a/settings.gradle b/settings.gradle index 49e706ab1..2f4baa7f6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -40,10 +40,10 @@ include ':plugins:cpu:8080-cpu' include ':plugins:cpu:ssem-cpu' //include ':plugins:cpu:z80-cpu' -//include ':plugins:device:88-dcdd' -//include ':plugins:device:88-sio' -//include ':plugins:device:abstract-tape' -//include ':plugins:device:adm3A-terminal' +include ':plugins:device:88-dcdd' +include ':plugins:device:88-sio' +include ':plugins:device:abstract-tape' +include ':plugins:device:adm3A-terminal' //include ':plugins:device:brainduck-terminal' //include ':plugins:device:simhPseudo-z80' include ':plugins:device:ssem-display' @@ -52,5 +52,5 @@ include ':plugins:device:ssem-display' //include ':plugins:memory:ram-mem' //include ':plugins:memory:rasp-mem' include ':plugins:memory:ssem-mem' -include ':plugins:memory:byte-mem' +//include ':plugins:memory:byte-mem' From 7c6b0dd9f0d1661a96d7ffc21e15a70096d7eb8a Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 4 Dec 2021 12:53:36 +0100 Subject: [PATCH 047/314] [#201] as-8080: parse instructions --- .../as-8080/src/main/antlr/As8080Parser.g4 | 2 +- .../compiler/as8080/CommonParsers.java | 200 ++++++++++++++++++ .../compiler/as8080/ast/AbstractNode.java | 20 -- .../plugins/compiler/as8080/ast/Label.java | 2 +- .../plugins/compiler/as8080/ast/Node.java | 35 ++- .../plugins/compiler/as8080/ast/Program.java | 2 +- .../compiler/as8080/ast/Statement.java | 2 +- .../compiler/as8080/ast/data/Data.java | 4 +- .../compiler/as8080/ast/expr/Expr.java | 4 +- .../compiler/as8080/ast/instr/Instr.java | 4 +- .../compiler/as8080/ast/instr/InstrExpr.java | 6 +- .../as8080/ast/instr/InstrNoArgs.java | 6 +- .../compiler/as8080/ast/instr/InstrReg.java | 4 +- .../as8080/ast/instr/InstrRegExpr.java | 2 +- .../as8080/ast/instr/InstrRegPair.java | 2 +- .../as8080/ast/instr/InstrRegPairExpr.java | 2 +- .../as8080/ast/instr/InstrRegReg.java | 2 +- .../compiler/as8080/ast/pseudo/Pseudo.java | 4 +- .../as8080/visitors/InstrVisitor.java | 18 +- .../plugins/compiler/as8080/ParserTest.java | 20 +- .../plugins/compiler/as8080/Utils.java | 11 + 21 files changed, 294 insertions(+), 58 deletions(-) delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/AbstractNode.java diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index 2d9e6a918..4f51e4525 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -148,7 +148,7 @@ rDWdata: ; rExpression: - num=LIT_NUMBER # exprDec + num=LIT_NUMBER # exprDec | num=LIT_HEXNUMBER_1 # exprHex1 | num=LIT_HEXNUMBER_2 # exprHex2 | num=LIT_OCTNUMBER # exprOct diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java index cab5dc4cf..60a616b45 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java @@ -1,7 +1,10 @@ package net.emustudio.plugins.compiler.as8080; +import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; import org.antlr.v4.runtime.Token; +import java.util.Locale; + public class CommonParsers { public static String parseLitString(Token token) { @@ -43,4 +46,201 @@ public static int parseLitBin(Token token) { String rawText = token.getText(); return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 2); } + + public static int parseOpcode(Token token) { + switch (token.getText().toLowerCase(Locale.ENGLISH)) { + case "mvi": + return 6; + case "lxi": + return 1; + case "lda": + return 0x3A; + case "sta": + return 0x32; + case "lhld": + return 0x2A; + case "shld": + return 0x22; + case "adi": + return 0xC6; + case "aci": + return 0xCE; + case "sui": + return 0xD6; + case "sbi": + return 0xDE; + case "ani": + return 0xE6; + case "ori": + return 0xF6; + case "xri": + return 0xEE; + case "cpi": + return 0xFE; + case "jmp": + return 0xC3; + case "jc": + return 0xDA; + case "jnc": + return 0xD2; + case "jz": + return 0xCA; + case "jnz": + return 0xC2; + case "jm": + return 0xFA; + case "jp": + return 0xF2; + case "jpe": + return 0xEA; + case "jpo": + return 0xE2; + case "call": + return 0xCD; + case "cc": + return 0xDC; + case "cnc": + return 0xD4; + case "cnz": + return 0xC4; + case "cm": + return 0xFC; + case "cp": + return 0xF4; + case "cpe": + return 0xEC; + case "cpo": + return 0xE4; + case "in": + return 0xDB; + case "out": + return 0xD3; + case "stc": + return 0x37; + case "cmc": + return 0x3F; + case "cma": + return 0x2F; + case "daa": + return 0x27; + case "nop": + return 0; + case "rlc": + return 7; + case "rrc": + return 0xF; + case "ral": + return 0x17; + case "rar": + return 0x1F; + case "xchg": + return 0xEB; + case "xthl": + return 0xE3; + case "sphl": + return 0xF9; + case "pchl": + return 0xE9; + case "ret": + return 0xC9; + case "rc": + return 0xD8; + case "rnc": + return 0xD0; + case "rz": + return 0xC8; + case "rnz": + return 0xC0; + case "rm": + return 0xF8; + case "rp": + return 0xF0; + case "rpe": + return 0xE8; + case "rpo": + return 0xE0; + case "ei": + return 0xFB; + case "di": + return 0xF3; + case "hlt": + return 0x76; + case "inr": + return 4; + case "dcr": + return 5; + case "add": + return 0x80; + case "adc": + return 0x88; + case "sub": + return 0x90; + case "sbb": + return 0x98; + case "ana": + return 0xA0; + case "xra": + return 0xA8; + case "ora": + return 0xB0; + case "cmp": + return 0xB8; + case "mov": + return 0x40; + case "stax": + return 2; + case "ldax": + return 0xA; + case "push": + return 0xC5; + case "pop": + return 0xC1; + case "dad": + return 9; + case "inx": + return 3; + case "dcx": + return 0xB; + case "rst": + return 0xC7; + } + throw new CompileException(token.getCharPositionInLine(), token.getLine(), "Unknown instruction opcode: " + token.getText()); + } + + public static int parseReg(Token token) { + switch (token.getText().toLowerCase(Locale.ENGLISH)) { + case "a": + return 7; + case "b": + return 0; + case "c": + return 1; + case "d": + return 2; + case "e": + return 3; + case "h": + return 4; + case "l": + return 5; + case "m": + return 6; + } + throw new CompileException(token.getCharPositionInLine(), token.getLine(), "Unknown register: " + token.getText()); + } + + public static int parseRegPair(Token token) { + switch (token.getText().toLowerCase(Locale.ENGLISH)) { + case "b": + return 0; + case "d": + return 1; + case "h": + return 2; + case "psw": + case "sp": + return 3; + } + throw new CompileException(token.getCharPositionInLine(), token.getLine(), "Unknown register pair: " + token.getText()); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/AbstractNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/AbstractNode.java deleted file mode 100644 index ab2064452..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/AbstractNode.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -public class AbstractNode implements Node { - protected final List children = new ArrayList<>(); - - @Override - public void addChild(Node node) { - children.add(Objects.requireNonNull(node)); - } - - @Override - public List getChildren() { - return Collections.unmodifiableList(children); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java index d93c088ef..cfcbcb7ae 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java @@ -2,7 +2,7 @@ import org.antlr.v4.runtime.Token; -public class Label extends AbstractNode { +public class Label extends Node { public Label(Token label) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 552aaded6..a0117e4cb 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -1,10 +1,39 @@ package net.emustudio.plugins.compiler.as8080.ast; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Objects; -public interface Node { +public abstract class Node { - void addChild(Node node); + protected final List children = new ArrayList<>(); - List getChildren(); + public Node addChild(Node node) { + children.add(Objects.requireNonNull(node)); + return this; + } + + public List getChildren() { + return Collections.unmodifiableList(children); + } + + public Node getChild(int index) { + return children.get(index); + } + + @Override + public String toString() { + return toString(0); + } + + private String toString(int indent) { + String spaces = new String(new char[indent]).replace("\0", " "); + StringBuilder builder = new StringBuilder(spaces); + builder.append(getClass().getSimpleName()).append("\n"); + for (Node child : children) { + builder.append(child.toString(indent + 2)); + } + return builder.toString(); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java index 5fa429710..f61da7d94 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080.ast; -public class Program extends AbstractNode { +public class Program extends Node { private final NameSpace nameSpace = new NameSpace(); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java index 0d198bfad..3c875c111 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java @@ -1,5 +1,5 @@ package net.emustudio.plugins.compiler.as8080.ast; -public class Statement extends AbstractNode { +public class Statement extends Node { } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java index 71cadcc0d..349f51952 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080.ast.data; -import net.emustudio.plugins.compiler.as8080.ast.AbstractNode; +import net.emustudio.plugins.compiler.as8080.ast.Node; -public class Data extends AbstractNode { +public class Data extends Node { } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java index a94585089..051436417 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import net.emustudio.plugins.compiler.as8080.ast.AbstractNode; +import net.emustudio.plugins.compiler.as8080.ast.Node; -public abstract class Expr extends AbstractNode { +public abstract class Expr extends Node { } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java index cec3ffeff..00f8a074f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -import net.emustudio.plugins.compiler.as8080.ast.AbstractNode; +import net.emustudio.plugins.compiler.as8080.ast.Node; -public abstract class Instr extends AbstractNode { +public abstract class Instr extends Node { } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index ba4507c81..fa2adaf96 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -6,11 +6,11 @@ import java.util.Objects; public class InstrExpr extends Instr { - private final Token opcode; + private final int opcode; private final Expr expr; - public InstrExpr(Token opcode, Expr expr) { - this.opcode = Objects.requireNonNull(opcode); + public InstrExpr(int opcode, Expr expr) { + this.opcode = opcode; this.expr = Objects.requireNonNull(expr); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java index 921da308d..cf283a8a9 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java @@ -5,10 +5,10 @@ import java.util.Objects; public class InstrNoArgs extends Instr { - private final Token opcode; + private final int opcode; - public InstrNoArgs(Token opcode) { - this.opcode = Objects.requireNonNull(opcode); + public InstrNoArgs(int opcode) { + this.opcode = opcode; } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java index c7cc575a7..a30665916 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java @@ -1,10 +1,8 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -import org.antlr.v4.runtime.Token; - public class InstrReg extends Instr { - public InstrReg(Token opcode, Token reg) { + public InstrReg(int opcode, int reg) { } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java index 6c77f9d0d..7696e90a9 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java @@ -5,7 +5,7 @@ public class InstrRegExpr extends Instr { - public InstrRegExpr(Token opcode, Token reg, Expr expr) { + public InstrRegExpr(int opcode, int reg, Expr expr) { } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java index e7f2dfe4f..99b7e8d31 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java @@ -4,7 +4,7 @@ public class InstrRegPair extends Instr { - public InstrRegPair(Token opcode, Token regPair) { + public InstrRegPair(int opcode, int regPair) { } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java index cd56a7e07..228a1a045 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java @@ -5,7 +5,7 @@ public class InstrRegPairExpr extends Instr { - public InstrRegPairExpr(Token opcode, Token regPair, Expr expr) { + public InstrRegPairExpr(int opcode, int regPair, Expr expr) { } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java index 66040b91c..d2d9814f0 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java @@ -4,7 +4,7 @@ public class InstrRegReg extends Instr { - public InstrRegReg(Token opcode, Token dst, Token src) { + public InstrRegReg(int opcode, int dst, int src) { } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java index 40282e7e1..6b01caf66 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; -import net.emustudio.plugins.compiler.as8080.ast.AbstractNode; +import net.emustudio.plugins.compiler.as8080.ast.Node; -public abstract class Pseudo extends AbstractNode { +public abstract class Pseudo extends Node { } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java index 80f78c325..c975341a7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java @@ -4,45 +4,47 @@ import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; import net.emustudio.plugins.compiler.as8080.ast.instr.*; +import static net.emustudio.plugins.compiler.as8080.CommonParsers.*; + public class InstrVisitor extends As8080ParserBaseVisitor { @Override public Instr visitInstrNoArgs(As8080Parser.InstrNoArgsContext ctx) { - return new InstrNoArgs(ctx.opcode); + return new InstrNoArgs(parseOpcode(ctx.opcode)); } @Override public Instr visitInstrReg(As8080Parser.InstrRegContext ctx) { - return new InstrReg(ctx.opcode, ctx.reg.start); + return new InstrReg(parseOpcode(ctx.opcode), parseReg(ctx.reg.start)); } @Override public Instr visitInstrRegReg(As8080Parser.InstrRegRegContext ctx) { - return new InstrRegReg(ctx.opcode, ctx.dst.start, ctx.src.start); + return new InstrRegReg(parseOpcode(ctx.opcode), parseReg(ctx.dst.start), parseReg(ctx.src.start)); } @Override public Instr visitInstrRegPair(As8080Parser.InstrRegPairContext ctx) { - return new InstrRegPair(ctx.opcode, ctx.regpair); + return new InstrRegPair(parseOpcode(ctx.opcode), parseRegPair(ctx.regpair)); } @Override public Instr visitInstrRegPairExpr(As8080Parser.InstrRegPairExprContext ctx) { - return new InstrRegPairExpr(ctx.opcode, ctx.regpair, Visitors.expr.visit(ctx.expr)); + return new InstrRegPairExpr(parseOpcode(ctx.opcode), parseRegPair(ctx.regpair), Visitors.expr.visit(ctx.expr)); } @Override public Instr visitInstrRegExpr(As8080Parser.InstrRegExprContext ctx) { - return new InstrRegExpr(ctx.opcode, ctx.reg.start, Visitors.expr.visit(ctx.expr)); + return new InstrRegExpr(parseOpcode(ctx.opcode), parseReg(ctx.reg.start), Visitors.expr.visit(ctx.expr)); } @Override public Instr visitInstrExpr(As8080Parser.InstrExprContext ctx) { - return new InstrExpr(ctx.opcode, Visitors.expr.visit(ctx.expr)); + return new InstrExpr(parseOpcode(ctx.opcode), Visitors.expr.visit(ctx.expr)); } @Override public Instr visitInstr8bitExpr(As8080Parser.Instr8bitExprContext ctx) { - return new InstrExpr(ctx.opcode, Visitors.expr.visit(ctx.expr)); + return new InstrExpr(parseOpcode(ctx.opcode), Visitors.expr.visit(ctx.expr)); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java index 3a77183cd..81abd8bdb 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java @@ -1,15 +1,31 @@ package net.emustudio.plugins.compiler.as8080; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.Statement; +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.as8080.visitors.CreateProgramVisitor; import org.antlr.v4.runtime.tree.ParseTree; import org.junit.Test; +import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; + public class ParserTest { @Test public void testParse() { ParseTree tree = Utils.parse("stc\nmvi a, 5"); + Program program = new Program(); + CreateProgramVisitor visitor = new CreateProgramVisitor(program); - System.out.println(tree.toStringTree()); - + visitor.visit(tree); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new InstrNoArgs(0))) + .addChild(new Statement() + .addChild(new InstrRegExpr(0, 0, new Expr() {}))), + program + ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java index d54a82130..10a1efc16 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -1,5 +1,6 @@ package net.emustudio.plugins.compiler.as8080; +import net.emustudio.plugins.compiler.as8080.ast.Node; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.Token; @@ -61,4 +62,14 @@ public static void assertTokenTypesIgnoreCase(String base, int... expectedTypes) assertTokenTypes(variation, expectedTypes); } } + + public static void assertTrees(Node expected, Node result) { + assertEquals("Children size does not match", expected.getChildren().size(), result.getChildren().size()); + assertEquals("Nodes are different", expected.getClass(), result.getClass()); + for (int i = 0; i < expected.getChildren().size(); i++) { + Node expectedChild = expected.getChild(i); + Node resultChild = result.getChild(i); + assertTrees(expectedChild, resultChild); + } + } } From b9e6e2935592ace85786d704606431e10df8f6b9 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 5 Dec 2021 15:30:21 +0100 Subject: [PATCH 048/314] [#201] as-8080: wip --- .../as-8080/src/main/antlr/As8080Parser.g4 | 12 +- .../compiler/as8080/CommonParsers.java | 5 + .../plugins/compiler/as8080/Lexer.java | 2 +- .../plugins/compiler/as8080/ast/Label.java | 4 +- .../compiler/as8080/ast/data/DataDB.java | 12 +- .../compiler/as8080/ast/data/DataDS.java | 4 +- .../compiler/as8080/ast/data/DataDW.java | 7 +- .../as8080/ast/data/DataPlainString.java | 10 ++ .../compiler/as8080/ast/expr/ExprInfix.java | 6 +- .../compiler/as8080/ast/expr/ExprUnary.java | 4 +- .../compiler/as8080/ast/instr/InstrExpr.java | 11 +- .../as8080/ast/instr/InstrNoArgs.java | 4 - .../as8080/ast/instr/InstrRegExpr.java | 7 +- .../as8080/ast/instr/InstrRegPair.java | 2 - .../as8080/ast/instr/InstrRegPairExpr.java | 6 +- .../as8080/ast/instr/InstrRegReg.java | 2 - .../compiler/as8080/ast/pseudo/PseudoEqu.java | 3 +- .../compiler/as8080/ast/pseudo/PseudoIf.java | 4 +- .../as8080/ast/pseudo/PseudoInclude.java | 4 +- .../as8080/ast/pseudo/PseudoMacroCall.java | 8 +- .../as8080/ast/pseudo/PseudoMacroDef.java | 11 +- .../compiler/as8080/ast/pseudo/PseudoOrg.java | 3 +- .../compiler/as8080/ast/pseudo/PseudoSet.java | 3 +- .../compiler/as8080/visitors/AllVisitors.java | 11 -- .../as8080/visitors/CreateProgramVisitor.java | 6 +- .../compiler/as8080/visitors/DataVisitor.java | 32 ++-- .../compiler/as8080/visitors/ExprVisitor.java | 9 +- .../as8080/visitors/InstrVisitor.java | 24 ++- .../compiler/as8080/visitors/LineVisitor.java | 27 +++- .../as8080/visitors/PseudoVisitor.java | 49 +++--- .../as8080/visitors/StatementVisitor.java | 22 --- .../compiler/as8080/visitors/Visitors.java | 1 - .../compiler/as8080/ParseDataTest.java | 112 +++++++++++++ .../compiler/as8080/ParseInstrTest.java | 92 +++++++++++ .../compiler/as8080/ParsePseudoTest.java | 150 ++++++++++++++++++ .../plugins/compiler/as8080/ParserTest.java | 31 ---- .../plugins/compiler/as8080/RunnerTest.java | 6 +- .../plugins/compiler/as8080/Utils.java | 19 ++- 38 files changed, 521 insertions(+), 204 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java delete mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index 4f51e4525..65342340f 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -117,24 +117,24 @@ rPseudoCode: PREP_ORG expr=rExpression # pseudoOrg | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoSet - | PREP_IF expr=rExpression EOL statement=rStatement EOL+ PREP_ENDIF # pseudoIf + | PREP_IF expr=rExpression (EOL+ rLine)+ EOL+ PREP_ENDIF # pseudoIf | id=ID_IDENTIFIER PREP_MACRO params=rMacroParameters? (EOL+ rLine)+ EOL+ PREP_ENDM # pseudoMacroDef | id=ID_IDENTIFIER args=rMacroArguments? # pseudoMacroCall | PREP_INCLUDE filename=(LIT_STRING_1|LIT_STRING_2) # pseudoInclude ; rMacroParameters: - id=ID_IDENTIFIER (SEP_COMMA ID_IDENTIFIER)* + ID_IDENTIFIER (SEP_COMMA ID_IDENTIFIER)* ; rMacroArguments: - expr=rExpression (SEP_COMMA rExpression)* + rExpression (SEP_COMMA rExpression)* ; rData: - PREP_DB data=rDBdata (SEP_COMMA rDBdata)* # dataDB - | PREP_DW data=rDWdata (SEP_COMMA rDWdata)* # dataDW - | PREP_DS data=rExpression # dataDS + PREP_DB rDBdata (SEP_COMMA rDBdata)* # dataDB + | PREP_DW rDWdata (SEP_COMMA rDWdata)* # dataDW + | PREP_DS data=rExpression # dataDS ; rDBdata: diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java index 60a616b45..029f26c08 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java @@ -243,4 +243,9 @@ public static int parseRegPair(Token token) { } throw new CompileException(token.getCharPositionInLine(), token.getLine(), "Unknown register pair: " + token.getText()); } + + public static String parseLabel(Token token) { + String rawText = token.getText(); + return rawText.substring(0, rawText.length() - 1); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java index 9260be44f..feb62d0dd 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java @@ -12,7 +12,7 @@ public class Lexer implements LexicalAnalyzer { private final As8080Lexer lexer; - private static final int[] tokenMap = new int[As8080Lexer.ERROR + 1]; // As8080Lexer.ERROR is the highest number + private static final int[] tokenMap = new int[As8080Lexer.EOL + 1]; // As8080Lexer.ERROR is the highest number static { tokenMap[COMMENT] = Token.COMMENT; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java index cfcbcb7ae..6d6c75045 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java @@ -1,10 +1,8 @@ package net.emustudio.plugins.compiler.as8080.ast; -import org.antlr.v4.runtime.Token; - public class Label extends Node { - public Label(Token label) { + public Label(String label) { } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java index a81d7ca75..f85befe8d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java @@ -1,16 +1,8 @@ package net.emustudio.plugins.compiler.as8080.ast.data; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; -import net.emustudio.plugins.compiler.as8080.ast.instr.Instr; - public class DataDB extends Data { - public DataDB(Expr expr) { - } - - public DataDB(String string) { - } - - public DataDB(Instr instr) { + public DataDB() { + // child is string, expr or 8-bit instruction } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java index e43f2d48f..a622faffe 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java @@ -3,7 +3,9 @@ import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; public class DataDS extends Data { - public DataDS(Expr expr) { + public DataDS() { + // child is expr + // expr cannot be negative } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java index c42544006..bb95ddcda 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java @@ -1,10 +1,9 @@ package net.emustudio.plugins.compiler.as8080.ast.data; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; - public class DataDW extends Data { - public DataDW(Expr expr) { - // expr=rExpression + public DataDW() { + // child is expr + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java new file mode 100644 index 000000000..135e9391b --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java @@ -0,0 +1,10 @@ +package net.emustudio.plugins.compiler.as8080.ast.data; + +import net.emustudio.plugins.compiler.as8080.ast.Node; + +public class DataPlainString extends Node { + + public DataPlainString(String string) { + + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index 23741019c..91dab9e88 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -1,10 +1,8 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import org.antlr.v4.runtime.Token; - public class ExprInfix extends Expr { - public ExprInfix(Token op, Expr left, Expr right) { - + public ExprInfix(int op) { + // children are: left, right } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index ac6b65306..538bd7664 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -2,7 +2,7 @@ public class ExprUnary extends Expr { - public ExprUnary(int unaryOp, Expr expr) { - + public ExprUnary(int unaryOp) { + // child is expr } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index fa2adaf96..49eadec6a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -1,16 +1,11 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; -import org.antlr.v4.runtime.Token; - -import java.util.Objects; - public class InstrExpr extends Instr { private final int opcode; - private final Expr expr; - public InstrExpr(int opcode, Expr expr) { + public InstrExpr(int opcode) { this.opcode = opcode; - this.expr = Objects.requireNonNull(expr); + + // child is expr } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java index cf283a8a9..e9e8cb1e2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java @@ -1,9 +1,5 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -import org.antlr.v4.runtime.Token; - -import java.util.Objects; - public class InstrNoArgs extends Instr { private final int opcode; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java index 7696e90a9..b400234d7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java @@ -1,11 +1,8 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; -import org.antlr.v4.runtime.Token; - public class InstrRegExpr extends Instr { - public InstrRegExpr(int opcode, int reg, Expr expr) { - + public InstrRegExpr(int opcode, int reg) { + // child is expr } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java index 99b7e8d31..ba38f38da 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java @@ -1,7 +1,5 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -import org.antlr.v4.runtime.Token; - public class InstrRegPair extends Instr { public InstrRegPair(int opcode, int regPair) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java index 228a1a045..7cd7c5032 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java @@ -1,11 +1,9 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; -import org.antlr.v4.runtime.Token; - public class InstrRegPairExpr extends Instr { - public InstrRegPairExpr(int opcode, int regPair, Expr expr) { + public InstrRegPairExpr(int opcode, int regPair) { + // child is expr } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java index d2d9814f0..33547dd1a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java @@ -1,7 +1,5 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -import org.antlr.v4.runtime.Token; - public class InstrRegReg extends Instr { public InstrRegReg(int opcode, int dst, int src) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java index 9aeefae39..40815cc23 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java @@ -5,7 +5,8 @@ public class PseudoEqu extends Pseudo { - public PseudoEqu(Token id, Expr expr) { + public PseudoEqu(String id) { + // expr is the only child } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java index 3f27c73a1..fcbd30994 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java @@ -4,7 +4,9 @@ import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; public class PseudoIf extends Pseudo { - public PseudoIf(Expr expr, Node node) { + public PseudoIf() { + // expr is the first child + // statement is the second child } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java index 4d45b68a2..0b19f1cde 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java @@ -1,10 +1,8 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; -import org.antlr.v4.runtime.Token; - public class PseudoInclude extends Pseudo { - public PseudoInclude(Token fileName) { + public PseudoInclude(String fileName) { } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java index 5682f441a..adc9a9e70 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java @@ -1,12 +1,8 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; -import org.antlr.v4.runtime.Token; - -import java.util.List; - public class PseudoMacroCall extends Pseudo { - public PseudoMacroCall(Token id, List arguments) { + public PseudoMacroCall(String id) { + // children are exprs (arguments) } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java index ae23c48b9..243ff3534 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java @@ -1,12 +1,13 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; -import net.emustudio.plugins.compiler.as8080.ast.Statement; -import org.antlr.v4.runtime.Token; - -import java.util.List; +import java.util.Objects; public class PseudoMacroDef extends Pseudo { + private final String id; - public PseudoMacroDef(Token id, List parameters, List statements) { + public PseudoMacroDef(String id) { + this.id = Objects.requireNonNull(id); + // parameters are the first children + // statements are followed } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java index 79e8ef644..ec20cbd74 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java @@ -5,7 +5,8 @@ public class PseudoOrg extends Pseudo { - public PseudoOrg(Expr expr) { + public PseudoOrg() { + // expr is the only child } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java index 3c95bc057..5a188cdf2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java @@ -4,7 +4,8 @@ import org.antlr.v4.runtime.Token; public class PseudoSet extends Pseudo { - public PseudoSet(Token id, Expr expr) { + public PseudoSet(String id) { + // expr is the only child } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java deleted file mode 100644 index badf8bb87..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/AllVisitors.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.visitors; - -public class AllVisitors { - - static PseudoVisitor pseudo = new PseudoVisitor(); - static ExprVisitor expr = new ExprVisitor(); - static InstrVisitor instr = new InstrVisitor(); - static DataVisitor data = new DataVisitor(); - static StatementVisitor statement = new StatementVisitor(); - static LineVisitor line = new LineVisitor(); -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java index 1e92725c2..df0dcd9c8 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java @@ -3,6 +3,7 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.Statement; import java.util.Objects; @@ -18,7 +19,10 @@ public CreateProgramVisitor(Program program) { @Override public Program visitRLine(As8080Parser.RLineContext ctx) { - program.addChild(Visitors.line.visitRLine(ctx)); + Statement statement = Visitors.line.visitRLine(ctx); + if (statement != null) { + program.addChild(statement); + } return program; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java index 4597b3976..c9d3c5daa 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java @@ -3,31 +3,23 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser.*; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; import net.emustudio.plugins.compiler.as8080.CommonParsers; -import net.emustudio.plugins.compiler.as8080.ast.data.Data; -import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; -import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; -import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.data.*; public class DataVisitor extends As8080ParserBaseVisitor { @Override public Data visitDataDB(DataDBContext ctx) { Data data = new Data(); + DataDB db = new DataDB(); + data.addChild(db); - if (ctx.data.expr != null) { - data.addChild(new DataDB(AllVisitors.expr.visit(ctx.data.expr))); - } else if (ctx.data.instr != null) { - data.addChild(new DataDB(AllVisitors.instr.visit(ctx.data.instr))); - } else { - data.addChild(new DataDB(CommonParsers.parseLitString(ctx.data.str))); - } for (RDBdataContext next : ctx.rDBdata()) { if (next.expr != null) { - data.addChild(new DataDB(AllVisitors.expr.visit(next.expr))); + db.addChild(Visitors.expr.visit(next.expr)); } else if (next.instr != null) { - data.addChild(new DataDB(AllVisitors.instr.visit(next.instr))); + db.addChild(Visitors.instr.visit(next.instr)); } else { - data.addChild(new DataDB(CommonParsers.parseLitString(next.str))); + db.addChild(new DataPlainString(CommonParsers.parseLitString(next.str))); } } @@ -37,13 +29,12 @@ public Data visitDataDB(DataDBContext ctx) { @Override public Data visitDataDW(DataDWContext ctx) { Data data = new Data(); + DataDW dw = new DataDW(); + data.addChild(dw); - if (ctx.data.expr != null) { - data.addChild(new DataDW(AllVisitors.expr.visit(ctx.data.expr))); - } for (RDWdataContext next : ctx.rDWdata()) { if (next.expr != null) { - data.addChild(new DataDW(AllVisitors.expr.visit(next.expr))); + dw.addChild(Visitors.expr.visit(next.expr)); } } @@ -52,6 +43,9 @@ public Data visitDataDW(DataDWContext ctx) { @Override public Data visitDataDS(DataDSContext ctx) { - return new DataDS(AllVisitors.expr.visit(ctx.data)); + DataDS ds = new DataDS(); + ds.addChild(Visitors.expr.visit(ctx.data)); + + return ds; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java index a8cba0c2a..7cca21e32 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java @@ -39,12 +39,17 @@ public Expr visitExprId(As8080Parser.ExprIdContext ctx) { @Override public Expr visitExprUnary(As8080Parser.ExprUnaryContext ctx) { - return new ExprUnary(ctx.unaryop.getType(), visit(ctx.expr)); + ExprUnary unary = new ExprUnary(ctx.unaryop.getType()); + unary.addChild(visit(ctx.expr)); + return unary; } @Override public Expr visitExprInfix(As8080Parser.ExprInfixContext ctx) { - return new ExprInfix(ctx.op, visit(ctx.expr1), visit(ctx.expr2)); + ExprInfix infix = new ExprInfix(ctx.op.getType()); + infix.addChild(visit(ctx.expr1)); + infix.addChild(visit(ctx.expr2)); + return infix; } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java index c975341a7..eaa3a6486 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java @@ -10,41 +10,49 @@ public class InstrVisitor extends As8080ParserBaseVisitor { @Override public Instr visitInstrNoArgs(As8080Parser.InstrNoArgsContext ctx) { - return new InstrNoArgs(parseOpcode(ctx.opcode)); + return new InstrNoArgs(ctx.opcode.getType()); } @Override public Instr visitInstrReg(As8080Parser.InstrRegContext ctx) { - return new InstrReg(parseOpcode(ctx.opcode), parseReg(ctx.reg.start)); + return new InstrReg(ctx.opcode.getType(), parseReg(ctx.reg.start)); } @Override public Instr visitInstrRegReg(As8080Parser.InstrRegRegContext ctx) { - return new InstrRegReg(parseOpcode(ctx.opcode), parseReg(ctx.dst.start), parseReg(ctx.src.start)); + return new InstrRegReg(ctx.opcode.getType(), parseReg(ctx.dst.start), parseReg(ctx.src.start)); } @Override public Instr visitInstrRegPair(As8080Parser.InstrRegPairContext ctx) { - return new InstrRegPair(parseOpcode(ctx.opcode), parseRegPair(ctx.regpair)); + return new InstrRegPair(ctx.opcode.getType(), parseRegPair(ctx.regpair)); } @Override public Instr visitInstrRegPairExpr(As8080Parser.InstrRegPairExprContext ctx) { - return new InstrRegPairExpr(parseOpcode(ctx.opcode), parseRegPair(ctx.regpair), Visitors.expr.visit(ctx.expr)); + InstrRegPairExpr instr = new InstrRegPairExpr(ctx.opcode.getType(), parseRegPair(ctx.regpair)); + instr.addChild(Visitors.expr.visit(ctx.expr)); + return instr; } @Override public Instr visitInstrRegExpr(As8080Parser.InstrRegExprContext ctx) { - return new InstrRegExpr(parseOpcode(ctx.opcode), parseReg(ctx.reg.start), Visitors.expr.visit(ctx.expr)); + InstrRegExpr instr = new InstrRegExpr(ctx.opcode.getType(), parseReg(ctx.reg.start)); + instr.addChild(Visitors.expr.visit(ctx.expr)); + return instr; } @Override public Instr visitInstrExpr(As8080Parser.InstrExprContext ctx) { - return new InstrExpr(parseOpcode(ctx.opcode), Visitors.expr.visit(ctx.expr)); + InstrExpr instr = new InstrExpr(ctx.opcode.getType()); + instr.addChild(Visitors.expr.visit(ctx.expr)); + return instr; } @Override public Instr visitInstr8bitExpr(As8080Parser.Instr8bitExprContext ctx) { - return new InstrExpr(parseOpcode(ctx.opcode), Visitors.expr.visit(ctx.expr)); + InstrExpr instr = new InstrExpr(ctx.opcode.getType()); + instr.addChild(Visitors.expr.visit(ctx.expr)); + return instr; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/LineVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/LineVisitor.java index 81a69b2d7..c8db4402f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/LineVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/LineVisitor.java @@ -3,23 +3,34 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; import net.emustudio.plugins.compiler.as8080.ast.Label; +import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Statement; import java.util.Optional; -public class LineVisitor extends As8080ParserBaseVisitor { - private Statement statement; +import static net.emustudio.plugins.compiler.as8080.CommonParsers.parseLabel; + +public class LineVisitor extends As8080ParserBaseVisitor { @Override public Statement visitRLine(As8080Parser.RLineContext ctx) { - statement = new Statement(); - Optional.ofNullable(ctx.label).ifPresent(label -> statement.addChild(new Label(label))); - return visitChildren(ctx); + Statement statement = new Statement(); + Optional.ofNullable(ctx.label).ifPresent(label -> statement.addChild(new Label(parseLabel(label)))); + if (ctx.statement != null) { + statement.addChild(visit(ctx.statement)); + } + return statement; } @Override - public Statement visitRStatement(As8080Parser.RStatementContext ctx) { - statement.addChild(Visitors.statement.visitRStatement(ctx)); - return statement; + public Node visitRStatement(As8080Parser.RStatementContext ctx) { + if (ctx.instr != null) { + return Visitors.instr.visit(ctx.instr); + } else if (ctx.data != null) { + return Visitors.data.visit(ctx.data); + } else if (ctx.pseudo != null) { + return Visitors.pseudo.visit(ctx.pseudo); + } + throw new IllegalStateException("No statement defined!"); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java index fdd8e32dc..7d723ab28 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java @@ -2,69 +2,74 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser.*; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; -import net.emustudio.plugins.compiler.as8080.ast.Statement; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; -import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; -import java.util.ArrayList; -import java.util.List; +import static net.emustudio.plugins.compiler.as8080.CommonParsers.parseLitString; public class PseudoVisitor extends As8080ParserBaseVisitor { @Override public Pseudo visitPseudoOrg(PseudoOrgContext ctx) { - return new PseudoOrg(Visitors.expr.visit(ctx.expr)); + PseudoOrg pseudo = new PseudoOrg(); + pseudo.addChild(Visitors.expr.visit(ctx.expr)); + return pseudo; } @Override public Pseudo visitPseudoEqu(PseudoEquContext ctx) { - return new PseudoEqu(ctx.id, Visitors.expr.visit(ctx.expr)); + PseudoEqu pseudo = new PseudoEqu(ctx.id.getText()); + pseudo.addChild(Visitors.expr.visit(ctx.expr)); + return pseudo; } @Override public Pseudo visitPseudoSet(PseudoSetContext ctx) { - return new PseudoSet(ctx.id, Visitors.expr.visit(ctx.expr)); + PseudoSet pseudo = new PseudoSet(ctx.id.getText()); + pseudo.addChild(Visitors.expr.visit(ctx.expr)); + return pseudo; } @Override public Pseudo visitPseudoIf(PseudoIfContext ctx) { - return new PseudoIf(Visitors.expr.visit(ctx.expr), Visitors.statement.visit(ctx.statement)); + PseudoIf pseudo = new PseudoIf(); + pseudo.addChild(Visitors.expr.visit(ctx.expr)); + for (RLineContext line : ctx.rLine()) { + pseudo.addChild(Visitors.line.visitRLine(line)); + } + return pseudo; } @Override public Pseudo visitPseudoMacroDef(PseudoMacroDefContext ctx) { - List params = new ArrayList<>(); + PseudoMacroDef pseudo = new PseudoMacroDef(ctx.id.getText()); + if (ctx.params != null) { - params.add(ctx.params.id); for (TerminalNode next : ctx.params.ID_IDENTIFIER()) { - params.add(next.getSymbol()); + pseudo.addChild(new ExprId(next.getSymbol().getText())); } } - - List statements = new ArrayList<>(); for (RLineContext line : ctx.rLine()) { - statements.add(AllVisitors.line.visitRLine(line)); + pseudo.addChild(Visitors.line.visitRLine(line)); } - - return new PseudoMacroDef(ctx.id, params, statements); + return pseudo; } @Override public Pseudo visitPseudoMacroCall(PseudoMacroCallContext ctx) { - List arguments = new ArrayList<>(); + PseudoMacroCall pseudo = new PseudoMacroCall(ctx.id.getText()); + if (ctx.args != null) { - arguments.add(AllVisitors.expr.visit(ctx.args.expr)); for (RExpressionContext next : ctx.args.rExpression()) { - arguments.add(AllVisitors.expr.visit(next)); + pseudo.addChild(Visitors.expr.visit(next)); } } - return new PseudoMacroCall(ctx.id, arguments); + return pseudo; } @Override public Pseudo visitPseudoInclude(PseudoIncludeContext ctx) { - return new PseudoInclude(ctx.filename); + return new PseudoInclude(parseLitString(ctx.filename)); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java deleted file mode 100644 index 6f26815f0..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/StatementVisitor.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.visitors; - -import net.emustudio.plugins.compiler.as8080.As8080Parser; -import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; -import net.emustudio.plugins.compiler.as8080.ast.Node; - -public class StatementVisitor extends As8080ParserBaseVisitor { - - @Override - public Node visitRStatement(As8080Parser.RStatementContext ctx) { - if (ctx.instr != null) { - return Visitors.instr.visit(ctx.instr); - } - if (ctx.data != null) { - return Visitors.data.visit(ctx.data); - } - if (ctx.pseudo != null) { - return Visitors.pseudo.visit(ctx.pseudo); - } - throw new IllegalStateException("No statement defined!"); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java index 60ee9624f..b85b6206e 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java @@ -6,7 +6,6 @@ public class Visitors { static ExprVisitor expr = new ExprVisitor(); static InstrVisitor instr = new InstrVisitor(); static DataVisitor data = new DataVisitor(); - static StatementVisitor statement = new StatementVisitor(); static LineVisitor line = new LineVisitor(); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java new file mode 100644 index 000000000..a20994cfb --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java @@ -0,0 +1,112 @@ +package net.emustudio.plugins.compiler.as8080; + +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.Statement; +import net.emustudio.plugins.compiler.as8080.ast.data.*; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; +import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; + +public class ParseDataTest { + + @Test + public void testDBstring1() { + Program program = parseProgram("db 'hello,world!'"); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new Data() + .addChild(new DataDB() + .addChild(new DataPlainString("hello,world!"))))), + program + ); + } + + @Test + public void testDBstring2() { + Program program = parseProgram("db \"hello,world!\""); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new Data() + .addChild(new DataDB() + .addChild(new DataPlainString("hello,world!"))))), + program + ); + } + + @Test + public void testDBinstruction() { + Program program = parseProgram("db stc"); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new Data() + .addChild(new DataDB() + .addChild(new InstrNoArgs(0))))), + program + ); + } + + @Test + public void testMultipleDB() { + Program program = parseProgram("db -1,2,3"); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new Data() + .addChild(new DataDB() + .addChild(new ExprNumber(-1)) + .addChild(new ExprNumber(2)) + .addChild(new ExprNumber(3))))), + program + ); + } + + @Test + public void testDBwithNegativeValue() { + Program program = parseProgram("db -1"); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new Data() + .addChild(new DataDB().addChild(new ExprNumber(-1))))), + program + ); + } + + @Test + public void testMultipleDW() { + Program program = parseProgram("dw -1,2,3"); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new Data() + .addChild(new DataDW() + .addChild(new ExprNumber(-1))) + .addChild(new ExprNumber(2)) + .addChild(new ExprNumber(3)))), + program + ); + } + + @Test + public void testDWwithNegativeValue() { + Program program = parseProgram("dw -1"); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new Data() + .addChild(new DataDW() + .addChild(new ExprNumber(-1))))), + program + ); + } + + @Test + public void testDS() { + Program program = parseProgram("ds 0x55"); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new DataDS() + .addChild(new ExprNumber(0x55)))), + program + ); + } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java new file mode 100644 index 000000000..4ee87141a --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java @@ -0,0 +1,92 @@ +package net.emustudio.plugins.compiler.as8080; + +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.Statement; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrReg; +import org.junit.Test; + +import java.util.Map; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; +import static net.emustudio.plugins.compiler.as8080.Utils.*; + +public class ParseInstrTest { + + @Test + public void testInstrNoArgs() { + assertInstrNoArgs("stc", OPCODE_STC); + assertInstrNoArgs("cmc", OPCODE_CMC); + assertInstrNoArgs("daa", OPCODE_DAA); + assertInstrNoArgs("nop", OPCODE_NOP); + assertInstrNoArgs("rlc", OPCODE_RLC); + assertInstrNoArgs("rrc", OPCODE_RRC); + assertInstrNoArgs("ral", OPCODE_RAL); + assertInstrNoArgs("rar", OPCODE_RAR); + assertInstrNoArgs("xchg", OPCODE_XCHG); + assertInstrNoArgs("xthl", OPCODE_XTHL); + assertInstrNoArgs("sphl", OPCODE_SPHL); + assertInstrNoArgs("pchl", OPCODE_PCHL); + assertInstrNoArgs("ret", OPCODE_RET); + assertInstrNoArgs("rc", OPCODE_RC); + assertInstrNoArgs("rnc", OPCODE_RNC); + assertInstrNoArgs("rz", OPCODE_RZ); + assertInstrNoArgs("rnz", OPCODE_RNZ); + assertInstrNoArgs("rm", OPCODE_RM); + assertInstrNoArgs("rp", OPCODE_RP); + assertInstrNoArgs("rpe", OPCODE_RPE); + assertInstrNoArgs("rpo", OPCODE_RPO); + assertInstrNoArgs("ei", OPCODE_EI); + assertInstrNoArgs("di", OPCODE_DI); + assertInstrNoArgs("hlt", OPCODE_HLT); + } + + @Test + public void testInstrReg() { + assertInstrReg("inr", OPCODE_INR); + assertInstrReg("dcr", OPCODE_DCR); + assertInstrReg("add", OPCODE_ADD); + assertInstrReg("adc", OPCODE_ADC); + assertInstrReg("sub", OPCODE_SUB); + assertInstrReg("sbb", OPCODE_SBB); + assertInstrReg("ana", OPCODE_ANA); + assertInstrReg("xra", OPCODE_XRA); + assertInstrReg("ora", OPCODE_ORA); + assertInstrReg("cmp", OPCODE_CMP); + } + + private void assertInstrNoArgs(String instr, int instrType) { + forStringCaseVariations(instr, variation -> { + Program program = parseProgram(variation); + assertTrees(new Program().addChild(new Statement().addChild(new InstrNoArgs(instrType))), program); + }); + } + + private void assertInstrReg(String instr, int instrType) { + Map registers = Map.of( + "a", REG_A, + "b", REG_B, + "c", REG_C, + "d", REG_D, + "e", REG_E, + "h", REG_H, + "l", REG_L, + "m", REG_M + ); + + forStringCaseVariations(instr, instrVariation -> { + for (Map.Entry register : registers.entrySet()) { + forStringCaseVariations(register.getKey(), registerVariation -> { + String row = instrVariation + " " + registerVariation; + Program program = parseProgram(row); + assertTrees( + new Program() + .addChild(new Statement() + .addChild(new InstrReg(instrType, register.getValue()))), + program + ); + }); + } + }); + } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java new file mode 100644 index 000000000..cf28b9595 --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java @@ -0,0 +1,150 @@ +package net.emustudio.plugins.compiler.as8080; + +import net.emustudio.plugins.compiler.as8080.ast.Label; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.Statement; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.as8080.As8080Lexer.*; +import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; +import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; + +public class ParsePseudoTest { + + @Test + public void testConstant() { + Program program = parseProgram("here equ 0x55"); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new PseudoEqu("here") + .addChild(new ExprNumber(0x55)))), + program + ); + } + + @Test + public void testVariable() { + Program program = parseProgram("here set 0x55"); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new PseudoSet("here") + .addChild(new ExprNumber(0x55)))), + program + ); + } + + @Test + public void testOrg() { + Program program = parseProgram("org 55+88"); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new PseudoOrg() + .addChild(new ExprInfix(OP_ADD) + .addChild(new ExprNumber(55)) + .addChild(new ExprNumber(88))))), + program + ); + } + + @Test + public void testIf() { + Program program = parseProgram("if 1\n" + + " rrc\n" + + " rrc\n" + + "endif"); + + assertTrees(new Program() + .addChild(new Statement() + .addChild(new PseudoIf() + .addChild(new ExprNumber(1)) + .addChild(new Statement() + .addChild(new InstrNoArgs(OPCODE_RRC))) + .addChild(new Statement() + .addChild(new InstrNoArgs(OPCODE_RRC))))), + program + ); + } + + @Test + public void testTwoLabelsInsideIf() { + Program program = parseProgram("if 1\n" + + " label1:\n" + + " label2:\n" + + "endif"); + + assertTrees(new Program() + .addChild(new Statement() + .addChild(new PseudoIf() + .addChild(new ExprNumber(1)) + .addChild(new Statement() + .addChild(new Label("label1"))) + .addChild(new Statement() + .addChild(new Label("label2"))))), + program + ); + } + + @Test + public void testInclude() { + Program program = parseProgram("include 'filename.asm'"); + assertTrees(new Program() + .addChild(new Statement() + .addChild(new PseudoInclude("filename.asm"))), + program + ); + } + + @Test + public void testMacroDef() { + Program program = parseProgram("shrt macro param1, param2\n" + + " rrc\n" + + " heylabel: ani 7Fh\n" + + "endm\n\n"); + + Node expected = new Program() + .addChild(new Statement() + .addChild(new PseudoMacroDef("shrt") + .addChild(new ExprId("param1")) + .addChild(new ExprId("param2")) + .addChild(new Statement() + .addChild(new InstrNoArgs(OPCODE_RRC))) + .addChild(new Statement() + .addChild(new Label("heylabel")) + .addChild(new InstrExpr(OPCODE_ANI) + .addChild(new ExprNumber(0x7F)))))) + .addChild(new Statement()); + + assertTrees(expected, program); + } + + @Test + public void testMacroCallNoParams() { + Program program = parseProgram("shrt"); + + Node expected = new Program() + .addChild(new Statement() + .addChild(new PseudoMacroCall("shrt"))); + + assertTrees(expected, program); + } + + @Test + public void testMacroCallWithParams() { + Program program = parseProgram("shrt param1, 45"); + + Node expected = new Program() + .addChild(new Statement() + .addChild(new PseudoMacroCall("shrt") + .addChild(new ExprId("param1")) + .addChild(new ExprNumber(45)))); + + assertTrees(expected, program); + } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java deleted file mode 100644 index 81abd8bdb..000000000 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParserTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.emustudio.plugins.compiler.as8080; - -import net.emustudio.plugins.compiler.as8080.ast.Program; -import net.emustudio.plugins.compiler.as8080.ast.Statement; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; -import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; -import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; -import net.emustudio.plugins.compiler.as8080.visitors.CreateProgramVisitor; -import org.antlr.v4.runtime.tree.ParseTree; -import org.junit.Test; - -import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; - -public class ParserTest { - - @Test - public void testParse() { - ParseTree tree = Utils.parse("stc\nmvi a, 5"); - Program program = new Program(); - CreateProgramVisitor visitor = new CreateProgramVisitor(program); - - visitor.visit(tree); - assertTrees(new Program() - .addChild(new Statement() - .addChild(new InstrNoArgs(0))) - .addChild(new Statement() - .addChild(new InstrRegExpr(0, 0, new Expr() {}))), - program - ); - } -} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java index b968a0383..f652c9aef 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java @@ -52,17 +52,17 @@ public void testCommandLine() throws Exception { } @Test - public void testCommandLinePrintHelp() throws Exception { + public void testCommandLinePrintHelp() { Runner.main("--help"); } @Test - public void testCommandLineNonexistantSourceFileDoesNotThrow() throws Exception { + public void testCommandLineNonexistantSourceFileDoesNotThrow() { Runner.main("slfjkdf"); } @Test - public void testCommandLinePrintVersion() throws Exception { + public void testCommandLinePrintVersion() { Runner.main("--version"); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java index 10a1efc16..5a063ed2a 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -1,6 +1,8 @@ package net.emustudio.plugins.compiler.as8080; import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.visitors.CreateProgramVisitor; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.Token; @@ -9,6 +11,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.function.Consumer; import static org.junit.Assert.assertEquals; @@ -28,6 +31,14 @@ public static ParseTree parse(String program) { return parser.rStart(); } + public static Program parseProgram(String programString) { + ParseTree tree = Utils.parse(programString); + Program program = new Program(); + CreateProgramVisitor visitor = new CreateProgramVisitor(program); + visitor.visit(tree); + return program; + } + public static void assertTokenTypes(String variation, int... expectedTypes) { List tokens = getTokens(variation); assertTokenTypes(tokens, expectedTypes); @@ -42,6 +53,10 @@ public static void assertTokenTypes(List tokens, int... expectedTypes) { } public static void assertTokenTypesIgnoreCase(String base, int... expectedTypes) { + forStringCaseVariations(base, variation -> assertTokenTypes(variation, expectedTypes)); + } + + public static void forStringCaseVariations(String base, Consumer f) { Random r = new Random(); List variations = new ArrayList<>(); variations.add(base); @@ -58,8 +73,8 @@ public static void assertTokenTypesIgnoreCase(String base, int... expectedTypes) } variations.add(new String(chars)); } - for (String variation : variations) { - assertTokenTypes(variation, expectedTypes); + for (String variation: variations) { + f.accept(variation); } } From 3a4cf03e298baaf8ab4753eed0fe4b842ce487d0 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 7 Dec 2021 11:32:50 +0100 Subject: [PATCH 049/314] [#201] as-8080 tests --- .../compiler/as8080/ParseInstrTest.java | 165 ++++++++++++++++-- .../plugins/compiler/as8080/Utils.java | 32 ++++ 2 files changed, 184 insertions(+), 13 deletions(-) diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java index 4ee87141a..3b39c469b 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java @@ -2,10 +2,14 @@ import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.Statement; -import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; -import net.emustudio.plugins.compiler.as8080.ast.instr.InstrReg; +import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprCurrentAddress; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.instr.*; import org.junit.Test; +import java.util.Locale; import java.util.Map; import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; @@ -55,6 +59,124 @@ public void testInstrReg() { assertInstrReg("cmp", OPCODE_CMP); } + @Test + public void testInstrExpr() { + assertInstrExpr("lda", OPCODE_LDA); + assertInstrExpr("sta", OPCODE_STA); + assertInstrExpr("lhld", OPCODE_LHLD); + assertInstrExpr("shld", OPCODE_SHLD); + assertInstrExpr("adi", OPCODE_ADI); + assertInstrExpr("aci", OPCODE_ACI); + assertInstrExpr("sui", OPCODE_SUI); + assertInstrExpr("sbi", OPCODE_SBI); + assertInstrExpr("ani", OPCODE_ANI); + assertInstrExpr("ori", OPCODE_ORI); + assertInstrExpr("xri", OPCODE_XRI); + assertInstrExpr("cpi", OPCODE_CPI); + assertInstrExpr("jmp", OPCODE_JMP); + assertInstrExpr("jc", OPCODE_JC); + assertInstrExpr("jnc", OPCODE_JNC); + assertInstrExpr("jz", OPCODE_JZ); + assertInstrExpr("jnz", OPCODE_JNZ); + assertInstrExpr("jm", OPCODE_JM); + assertInstrExpr("jp", OPCODE_JP); + assertInstrExpr("jpe", OPCODE_JPE); + assertInstrExpr("jpo", OPCODE_JPO); + assertInstrExpr("call", OPCODE_CALL); + assertInstrExpr("cc", OPCODE_CC); + assertInstrExpr("cnc", OPCODE_CNC); + assertInstrExpr("cz", OPCODE_CZ); + assertInstrExpr("cnz", OPCODE_CNZ); + assertInstrExpr("cm", OPCODE_CM); + assertInstrExpr("cp", OPCODE_CP); + assertInstrExpr("cpe", OPCODE_CPE); + assertInstrExpr("cpo", OPCODE_CPO); + assertInstrExpr("in", OPCODE_IN); + assertInstrExpr("out", OPCODE_OUT); + assertInstrExpr("rst", OPCODE_RST); + } + + @Test + public void testRegPair() { + assertInstrRegPair("stax", OPCODE_STAX, regPairsBD); + assertInstrRegPair("ldax", OPCODE_LDAX, regPairsBD); + assertInstrRegPair("dad", OPCODE_DAD, regPairsBDHSP); + assertInstrRegPair("inx", OPCODE_INX, regPairsBDHSP); + assertInstrRegPair("dcx", OPCODE_DCX, regPairsBDHSP); + assertInstrRegPair("push", OPCODE_PUSH, regPairsBDHPSW); + assertInstrRegPair("pop", OPCODE_POP, regPairsBDHPSW); + } + + @Test + public void testMVI() { + Expr expr = (Expr) new ExprInfix(OP_ADD) + .addChild(new ExprCurrentAddress()) + .addChild(new ExprNumber(5)); + + forStringCaseVariations("mvi", instrVariation -> { + for (Map.Entry register : registers.entrySet()) { + forStringCaseVariations(register.getKey(), registerVariation -> { + String row = instrVariation + " " + registerVariation + ", $ + 5"; + Program program = parseProgram(row); + assertTrees( + new Program() + .addChild(new Statement() + .addChild(new InstrRegExpr(OPCODE_MVI, register.getValue()) + .addChild(expr))), + program + ); + }); + } + }); + } + + @Test + public void testLXI() { + Expr expr = (Expr) new ExprInfix(OP_ADD) + .addChild(new ExprCurrentAddress()) + .addChild(new ExprNumber(5)); + + forStringCaseVariations("lxi", instrVariation -> { + for (Map.Entry regPair : regPairsBDHSP.entrySet()) { + forStringCaseVariations(regPair.getKey(), registerVariation -> { + String row = instrVariation + " " + registerVariation + ", $ + 5"; + Program program = parseProgram(row); + assertTrees( + new Program() + .addChild(new Statement() + .addChild(new InstrRegPairExpr(OPCODE_LXI, regPair.getValue()) + .addChild(expr))), + program + ); + }); + } + }); + } + + @Test + public void testMOV() { + forStringCaseVariations("mov", instrVariation -> { + for (Map.Entry register1 : registers.entrySet()) { + forStringCaseVariations(register1.getKey(), registerVariation1 -> { + for (Map.Entry register2 : registers.entrySet()) { + forStringCaseVariations(register2.getKey(), registerVariation2 -> { + if (!registerVariation1.toLowerCase(Locale.ENGLISH).equals("m") || !registerVariation1.equals(registerVariation2)) { + String row = instrVariation + " " + registerVariation1 + ", " + registerVariation2; + Program program = parseProgram(row); + assertTrees( + new Program() + .addChild(new Statement() + .addChild(new InstrRegReg(OPCODE_MOV, register1.getValue(), register2.getValue()))), + program + ); + } + }); + } + }); + } + }); + } + private void assertInstrNoArgs(String instr, int instrType) { forStringCaseVariations(instr, variation -> { Program program = parseProgram(variation); @@ -63,17 +185,6 @@ private void assertInstrNoArgs(String instr, int instrType) { } private void assertInstrReg(String instr, int instrType) { - Map registers = Map.of( - "a", REG_A, - "b", REG_B, - "c", REG_C, - "d", REG_D, - "e", REG_E, - "h", REG_H, - "l", REG_L, - "m", REG_M - ); - forStringCaseVariations(instr, instrVariation -> { for (Map.Entry register : registers.entrySet()) { forStringCaseVariations(register.getKey(), registerVariation -> { @@ -89,4 +200,32 @@ private void assertInstrReg(String instr, int instrType) { } }); } + + private void assertInstrExpr(String instr, int instrType) { + Expr expr = (Expr) new ExprInfix(OP_ADD) + .addChild(new ExprCurrentAddress()) + .addChild(new ExprNumber(5)); + + forStringCaseVariations(instr, variation -> { + Program program = parseProgram(variation + " $ + 5"); + assertTrees(new Program().addChild(new Statement().addChild(new InstrExpr(instrType).addChild(expr))), program); + }); + } + + private void assertInstrRegPair(String instr, int instrType, Map regPairs) { + forStringCaseVariations(instr, instrVariation -> { + for (Map.Entry regPair : regPairs.entrySet()) { + forStringCaseVariations(regPair.getKey(), registerVariation -> { + String row = instrVariation + " " + registerVariation; + Program program = parseProgram(row); + assertTrees( + new Program() + .addChild(new Statement() + .addChild(new InstrRegPair(instrType, regPair.getValue()))), + program + ); + }); + } + }); + } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java index 5a063ed2a..fc8c57df8 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -10,12 +10,44 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Random; import java.util.function.Consumer; +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; +import static net.emustudio.plugins.compiler.as8080.As8080Parser.REG_M; import static org.junit.Assert.assertEquals; public class Utils { + public static Map registers = Map.of( + "a", REG_A, + "b", REG_B, + "c", REG_C, + "d", REG_D, + "e", REG_E, + "h", REG_H, + "l", REG_L, + "m", REG_M + ); + + public static Map regPairsBD = Map.of( + "b", REG_B, + "d", REG_D + ); + public static Map regPairsBDHSP = Map.of( + "b", REG_B, + "d", REG_D, + "h", REG_H, + "sp", REG_SP + ); + public static Map regPairsBDHPSW = Map.of( + "b", REG_B, + "d", REG_D, + "h", REG_H, + "psw", REG_PSW + ); + + public static List getTokens(String variation) { As8080Lexer lexer = new As8080Lexer(CharStreams.fromString(variation)); CommonTokenStream stream = new CommonTokenStream(lexer); From fb65a958e80c5da518123f7a133e206c981e0c43 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 7 Dec 2021 12:28:28 +0100 Subject: [PATCH 050/314] [#201] Fix test --- .../{DataVisitor.java => CreateDataVisitor.java} | 2 +- .../{ExprVisitor.java => CreateExprVisitor.java} | 2 +- .../{InstrVisitor.java => CreateInstrVisitor.java} | 2 +- .../{LineVisitor.java => CreateLineVisitor.java} | 2 +- .../{PseudoVisitor.java => CreatePseudoVisitor.java} | 2 +- .../plugins/compiler/as8080/visitors/Visitors.java | 10 +++++----- .../plugins/compiler/as8080/ParseDataTest.java | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/{DataVisitor.java => CreateDataVisitor.java} (95%) rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/{ExprVisitor.java => CreateExprVisitor.java} (96%) rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/{InstrVisitor.java => CreateInstrVisitor.java} (96%) rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/{LineVisitor.java => CreateLineVisitor.java} (94%) rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/{PseudoVisitor.java => CreatePseudoVisitor.java} (96%) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java similarity index 95% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java index c9d3c5daa..bdc112a25 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/DataVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java @@ -5,7 +5,7 @@ import net.emustudio.plugins.compiler.as8080.CommonParsers; import net.emustudio.plugins.compiler.as8080.ast.data.*; -public class DataVisitor extends As8080ParserBaseVisitor { +public class CreateDataVisitor extends As8080ParserBaseVisitor { @Override public Data visitDataDB(DataDBContext ctx) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java similarity index 96% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java index 7cca21e32..fa8f8b623 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java @@ -5,7 +5,7 @@ import net.emustudio.plugins.compiler.as8080.CommonParsers; import net.emustudio.plugins.compiler.as8080.ast.expr.*; -public class ExprVisitor extends As8080ParserBaseVisitor { +public class CreateExprVisitor extends As8080ParserBaseVisitor { @Override public Expr visitExprOct(As8080Parser.ExprOctContext ctx) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateInstrVisitor.java similarity index 96% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateInstrVisitor.java index eaa3a6486..a646481b1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/InstrVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateInstrVisitor.java @@ -6,7 +6,7 @@ import static net.emustudio.plugins.compiler.as8080.CommonParsers.*; -public class InstrVisitor extends As8080ParserBaseVisitor { +public class CreateInstrVisitor extends As8080ParserBaseVisitor { @Override public Instr visitInstrNoArgs(As8080Parser.InstrNoArgsContext ctx) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/LineVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java similarity index 94% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/LineVisitor.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java index c8db4402f..1bb659c5c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/LineVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java @@ -10,7 +10,7 @@ import static net.emustudio.plugins.compiler.as8080.CommonParsers.parseLabel; -public class LineVisitor extends As8080ParserBaseVisitor { +public class CreateLineVisitor extends As8080ParserBaseVisitor { @Override public Statement visitRLine(As8080Parser.RLineContext ctx) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java similarity index 96% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java index 7d723ab28..8dee782f8 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/PseudoVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java @@ -8,7 +8,7 @@ import static net.emustudio.plugins.compiler.as8080.CommonParsers.parseLitString; -public class PseudoVisitor extends As8080ParserBaseVisitor { +public class CreatePseudoVisitor extends As8080ParserBaseVisitor { @Override public Pseudo visitPseudoOrg(PseudoOrgContext ctx) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java index b85b6206e..a832c27ac 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java @@ -2,10 +2,10 @@ public class Visitors { - static PseudoVisitor pseudo = new PseudoVisitor(); - static ExprVisitor expr = new ExprVisitor(); - static InstrVisitor instr = new InstrVisitor(); - static DataVisitor data = new DataVisitor(); - static LineVisitor line = new LineVisitor(); + static CreatePseudoVisitor pseudo = new CreatePseudoVisitor(); + static CreateExprVisitor expr = new CreateExprVisitor(); + static CreateInstrVisitor instr = new CreateInstrVisitor(); + static CreateDataVisitor data = new CreateDataVisitor(); + static CreateLineVisitor line = new CreateLineVisitor(); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java index a20994cfb..7e3a648e0 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java @@ -80,9 +80,9 @@ public void testMultipleDW() { .addChild(new Statement() .addChild(new Data() .addChild(new DataDW() - .addChild(new ExprNumber(-1))) + .addChild(new ExprNumber(-1)) .addChild(new ExprNumber(2)) - .addChild(new ExprNumber(3)))), + .addChild(new ExprNumber(3))))), program ); } From 2171f3a797bc463f33bda586b54dfaf65ea0f8af Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 8 Dec 2021 08:26:45 +0100 Subject: [PATCH 051/314] [#201] ExpandInclude visitor --- .../plugins/compiler/as8080/ast/Label.java | 19 ++- .../plugins/compiler/as8080/ast/Node.java | 28 ++++- .../compiler/as8080/ast/NodeVisitor.java | 118 ++++++++++++++++++ .../plugins/compiler/as8080/ast/Program.java | 8 ++ .../compiler/as8080/ast/Statement.java | 5 - .../compiler/as8080/ast/data/Data.java | 6 - .../compiler/as8080/ast/data/DataDB.java | 13 +- .../compiler/as8080/ast/data/DataDS.java | 12 +- .../compiler/as8080/ast/data/DataDW.java | 12 +- .../as8080/ast/data/DataPlainString.java | 19 ++- .../compiler/as8080/ast/expr/Expr.java | 6 - .../as8080/ast/expr/ExprCurrentAddress.java | 14 ++- .../compiler/as8080/ast/expr/ExprId.java | 20 ++- .../compiler/as8080/ast/expr/ExprInfix.java | 20 ++- .../compiler/as8080/ast/expr/ExprNumber.java | 21 +++- .../compiler/as8080/ast/expr/ExprUnary.java | 20 ++- .../compiler/as8080/ast/instr/Instr.java | 6 - .../compiler/as8080/ast/instr/InstrExpr.java | 21 +++- .../as8080/ast/instr/InstrNoArgs.java | 18 ++- .../compiler/as8080/ast/instr/InstrReg.java | 21 +++- .../as8080/ast/instr/InstrRegExpr.java | 22 +++- .../as8080/ast/instr/InstrRegPair.java | 21 +++- .../as8080/ast/instr/InstrRegPairExpr.java | 21 +++- .../as8080/ast/instr/InstrRegReg.java | 23 +++- .../compiler/as8080/ast/pseudo/Pseudo.java | 6 - .../compiler/as8080/ast/pseudo/PseudoEqu.java | 20 ++- .../compiler/as8080/ast/pseudo/PseudoIf.java | 12 +- .../as8080/ast/pseudo/PseudoInclude.java | 22 +++- .../as8080/ast/pseudo/PseudoMacroCall.java | 22 +++- .../as8080/ast/pseudo/PseudoMacroDef.java | 20 ++- .../compiler/as8080/ast/pseudo/PseudoOrg.java | 13 +- .../compiler/as8080/ast/pseudo/PseudoSet.java | 21 +++- .../as8080/exceptions/CompileException.java | 4 +- .../as8080/visitors/CreateDataVisitor.java | 37 +++--- .../as8080/visitors/CreateExprVisitor.java | 41 +++--- .../as8080/visitors/CreateInstrVisitor.java | 37 +++--- .../as8080/visitors/CreateLineVisitor.java | 22 ++-- .../as8080/visitors/CreateProgramVisitor.java | 4 +- .../as8080/visitors/CreatePseudoVisitor.java | 39 +++--- .../visitors/ExpandIncludesVisitor.java | 37 ++++++ .../compiler/as8080/ParseDataTest.java | 60 ++++----- .../compiler/as8080/ParseInstrTest.java | 46 +++---- .../compiler/as8080/ParsePseudoTest.java | 78 +++++------- .../visitors/ExpandIncludesVisitorTest.java | 44 +++++++ 44 files changed, 790 insertions(+), 289 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java index 6d6c75045..28af08134 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java @@ -1,8 +1,25 @@ package net.emustudio.plugins.compiler.as8080.ast; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +import static net.emustudio.plugins.compiler.as8080.CommonParsers.parseLabel; + public class Label extends Node { + public final String label; - public Label(String label) { + public Label(int line, int column, String label) { + super(line, column); + this.label = Objects.requireNonNull(label); + } + + public Label(Token label) { + this(label.getLine(), label.getCharPositionInLine(), parseLabel(label)); + } + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index a0117e4cb..4f3fc239f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -1,15 +1,20 @@ package net.emustudio.plugins.compiler.as8080.ast; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; +import java.util.*; public abstract class Node { - + protected Node parent; protected final List children = new ArrayList<>(); + public final int line; + public final int column; + + public Node(int line, int column) { + this.line = line; + this.column = column; + } public Node addChild(Node node) { + node.parent = this; children.add(Objects.requireNonNull(node)); return this; } @@ -18,10 +23,23 @@ public List getChildren() { return Collections.unmodifiableList(children); } + public Optional getParent() { + return Optional.ofNullable(parent); + } + public Node getChild(int index) { return children.get(index); } + public void removeChild(Node node) { + node.parent = null; + children.remove(node); + } + + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + @Override public String toString() { return toString(0); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java new file mode 100644 index 000000000..eabd2cc90 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java @@ -0,0 +1,118 @@ +package net.emustudio.plugins.compiler.as8080.ast; + +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; +import net.emustudio.plugins.compiler.as8080.ast.expr.*; +import net.emustudio.plugins.compiler.as8080.ast.instr.*; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; + +public class NodeVisitor { + + public void visit(Node node) { + visitChildren(node); + } + + public void visit(DataDB node) { + visitChildren(node); + } + + public void visit(DataDW node) { + visitChildren(node); + } + + public void visit(DataDS node) { + visitChildren(node); + } + + public void visit(DataPlainString node) { + visitChildren(node); + } + + public void visit(ExprCurrentAddress node) { + visitChildren(node); + } + + public void visit(ExprInfix node) { + visitChildren(node); + } + + public void visit(ExprId node) { + visitChildren(node); + } + + public void visit(ExprNumber node) { + visitChildren(node); + } + + public void visit(ExprUnary node) { + visitChildren(node); + } + + public void visit(InstrExpr node) { + visitChildren(node); + } + + public void visit(InstrNoArgs node) { + visitChildren(node); + } + + public void visit(InstrReg node) { + visitChildren(node); + } + + public void visit(InstrRegExpr node) { + visitChildren(node); + } + + public void visit(InstrRegPair node) { + visitChildren(node); + } + + public void visit(InstrRegPairExpr node) { + visitChildren(node); + } + + public void visit(InstrRegReg node) { + visitChildren(node); + } + + public void visit(PseudoEqu node) { + visitChildren(node); + } + + public void visit(PseudoIf node) { + visitChildren(node); + } + + public void visit(PseudoInclude node) { + visitChildren(node); + } + + public void visit(PseudoMacroCall node) { + visitChildren(node); + } + + public void visit(PseudoMacroDef node) { + visitChildren(node); + } + + public void visit(PseudoOrg node) { + visitChildren(node); + } + + public void visit(PseudoSet node) { + visitChildren(node); + } + + public void visit(Label node) { + visitChildren(node); + } + + private void visitChildren(Node node) { + for (Node child : node.getChildren()) { + child.accept(this); + } + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java index f61da7d94..e1000d20f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java @@ -3,6 +3,14 @@ public class Program extends Node { private final NameSpace nameSpace = new NameSpace(); + public Program(int line, int column) { + super(line, column); + } + + public Program() { + this(0, 0); + } + public NameSpace env() { return nameSpace; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java deleted file mode 100644 index 3c875c111..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Statement.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast; - -public class Statement extends Node { - -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java deleted file mode 100644 index 349f51952..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/Data.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast.data; - -import net.emustudio.plugins.compiler.as8080.ast.Node; - -public class Data extends Node { -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java index f85befe8d..be4486bbe 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java @@ -1,8 +1,17 @@ package net.emustudio.plugins.compiler.as8080.ast.data; -public class DataDB extends Data { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; - public DataDB() { +public class DataDB extends Node { + + public DataDB(int line, int column) { + super(line, column); // child is string, expr or 8-bit instruction } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java index a622faffe..fe18fa4d2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java @@ -1,11 +1,17 @@ package net.emustudio.plugins.compiler.as8080.ast.data; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; -public class DataDS extends Data { - public DataDS() { +public class DataDS extends Node { + public DataDS(int line, int column) { + super(line, column); // child is expr // expr cannot be negative + } + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java index bb95ddcda..b6942edb6 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java @@ -1,9 +1,17 @@ package net.emustudio.plugins.compiler.as8080.ast.data; -public class DataDW extends Data { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; - public DataDW() { +public class DataDW extends Node { + + public DataDW(int line, int column) { + super(line, column); // child is expr + } + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java index 135e9391b..8c375d5d6 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java @@ -1,10 +1,27 @@ package net.emustudio.plugins.compiler.as8080.ast.data; import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +import static net.emustudio.plugins.compiler.as8080.CommonParsers.parseLitString; public class DataPlainString extends Node { + public final String string; - public DataPlainString(String string) { + public DataPlainString(int line, int column, String string) { + super(line, column); + this.string = Objects.requireNonNull(string); + } + + public DataPlainString(Token string) { + this(string.getLine(), string.getCharPositionInLine(), parseLitString(string)); + } + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java deleted file mode 100644 index 051436417..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/Expr.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast.expr; - -import net.emustudio.plugins.compiler.as8080.ast.Node; - -public abstract class Expr extends Node { -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java index f925eda70..4b6f75dff 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java @@ -1,4 +1,16 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -public class ExprCurrentAddress extends Expr { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; + +public class ExprCurrentAddress extends Node { + + public ExprCurrentAddress(int line, int column) { + super(line, column); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java index a69e567ca..a426700c3 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java @@ -1,11 +1,25 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; + import java.util.Objects; -public class ExprId extends Expr { - private final String id; +public class ExprId extends Node { + public final String id; - public ExprId(String id) { + public ExprId(int line, int column, String id) { + super(line, column); this.id = Objects.requireNonNull(id); } + + public ExprId(Token id) { + this(id.getLine(), id.getCharPositionInLine(), id.getText()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index 91dab9e88..3b813bfa9 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -1,8 +1,24 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -public class ExprInfix extends Expr { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public ExprInfix(int op) { +public class ExprInfix extends Node { + public final int operation; + + public ExprInfix(int line, int column, int op) { + super(line, column); + this.operation = op; // children are: left, right } + + public ExprInfix(Token op) { + this(op.getLine(), op.getCharPositionInLine(), op.getType()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java index 30b270846..75a9fa7a7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java @@ -1,8 +1,25 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -public class ExprNumber extends Expr { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public ExprNumber(int number) { +import java.util.function.Function; +public class ExprNumber extends Node { + public final int number; + + public ExprNumber(int line, int column, int number) { + super(line, column); + this.number = number; + } + + public ExprNumber(Token number, Function parser) { + this(number.getLine(), number.getCharPositionInLine(), parser.apply(number)); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index 538bd7664..f1d9140e8 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -1,8 +1,24 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -public class ExprUnary extends Expr { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public ExprUnary(int unaryOp) { +public class ExprUnary extends Node { + public final int operation; + + public ExprUnary(int line, int column, int op) { + super(line, column); + this.operation = op; // child is expr } + + public ExprUnary(Token op) { + this(op.getLine(), op.getCharPositionInLine(), op.getType()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java deleted file mode 100644 index 00f8a074f..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/Instr.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast.instr; - -import net.emustudio.plugins.compiler.as8080.ast.Node; - -public abstract class Instr extends Node { -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index 49eadec6a..2ac2cfed2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -1,11 +1,24 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -public class InstrExpr extends Instr { - private final int opcode; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public InstrExpr(int opcode) { - this.opcode = opcode; +public class InstrExpr extends Node { + public final int opcode; + public InstrExpr(int line, int column, int opcode) { + super(line, column); + this.opcode = opcode; // child is expr } + + public InstrExpr(Token opcode) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java index e9e8cb1e2..237e8c795 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java @@ -1,11 +1,23 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -public class InstrNoArgs extends Instr { - private final int opcode; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public InstrNoArgs(int opcode) { +public class InstrNoArgs extends Node { + public final int opcode; + + public InstrNoArgs(int line, int column, int opcode) { + super(line, column); this.opcode = opcode; } + public InstrNoArgs(Token opcode) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); + } + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java index a30665916..8decf5c77 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java @@ -1,8 +1,25 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -public class InstrReg extends Instr { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public InstrReg(int opcode, int reg) { +public class InstrReg extends Node { + public final int opcode; + public final int reg; + public InstrReg(int line, int column, int opcode, int reg) { + super(line, column); + this.opcode = opcode; + this.reg = reg; + } + + public InstrReg(Token opcode, Token reg) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java index b400234d7..236e0f901 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java @@ -1,8 +1,26 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -public class InstrRegExpr extends Instr { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public InstrRegExpr(int opcode, int reg) { +public class InstrRegExpr extends Node { + public final int opcode; + public final int reg; + + public InstrRegExpr(int line, int column, int opcode, int reg) { + super(line, column); + this.opcode = opcode; + this.reg = reg; // child is expr } + + public InstrRegExpr(Token opcode, Token reg) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java index ba38f38da..6e19f8cfa 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java @@ -1,8 +1,25 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -public class InstrRegPair extends Instr { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public InstrRegPair(int opcode, int regPair) { +public class InstrRegPair extends Node { + public final int opcode; + public final int regPair; + public InstrRegPair(int line, int column, int opcode, int regPair) { + super(line, column); + this.opcode = opcode; + this.regPair = regPair; + } + + public InstrRegPair(Token opcode, Token regPair) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java index 7cd7c5032..04b0ff380 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java @@ -1,9 +1,26 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -public class InstrRegPairExpr extends Instr { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public InstrRegPairExpr(int opcode, int regPair) { +public class InstrRegPairExpr extends Node { + public final int opcode; + public final int regPair; + + public InstrRegPairExpr(int line, int column, int opcode, int regPair) { + super(line, column); + this.opcode = opcode; + this.regPair = regPair; // child is expr + } + + public InstrRegPairExpr(Token opcode, Token regPair) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); + } + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java index 33547dd1a..2a9a8f783 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java @@ -1,8 +1,27 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; -public class InstrRegReg extends Instr { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public InstrRegReg(int opcode, int dst, int src) { +public class InstrRegReg extends Node { + public final int opcode; + public final int srcReg; + public final int dstReg; + public InstrRegReg(int line, int column, int opcode, int dst, int src) { + super(line, column); + this.opcode = opcode; + this.srcReg = src; + this.dstReg = dst; + } + + public InstrRegReg(Token opcode, Token dst, Token src) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), dst.getType(), src.getType()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java deleted file mode 100644 index 6b01caf66..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/Pseudo.java +++ /dev/null @@ -1,6 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast.pseudo; - -import net.emustudio.plugins.compiler.as8080.ast.Node; - -public abstract class Pseudo extends Node { -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java index 40815cc23..fd7b280e7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java @@ -1,12 +1,26 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; -public class PseudoEqu extends Pseudo { +import java.util.Objects; - public PseudoEqu(String id) { +public class PseudoEqu extends Node { + public final String id; + + public PseudoEqu(int line, int column, String id) { + super(line, column); + this.id = Objects.requireNonNull(id); // expr is the only child + } + + public PseudoEqu(Token id) { + this(id.getLine(), id.getCharPositionInLine(), id.getText()); + } + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java index fcbd30994..ed6c2a3d3 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java @@ -1,12 +1,18 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; -public class PseudoIf extends Pseudo { - public PseudoIf() { +public class PseudoIf extends Node { + + public PseudoIf(int line, int column) { + super(line, column); // expr is the first child // statement is the second child + } + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java index 0b19f1cde..f8a858c72 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java @@ -1,8 +1,26 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; -public class PseudoInclude extends Pseudo { +import net.emustudio.plugins.compiler.as8080.CommonParsers; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public PseudoInclude(String fileName) { +import java.util.Objects; +public class PseudoInclude extends Node { + public final String filename; + + public PseudoInclude(int line, int column, String fileName) { + super(line, column); + this.filename = Objects.requireNonNull(fileName); + } + + public PseudoInclude(Token fileName) { + this(fileName.getLine(), fileName.getCharPositionInLine(), CommonParsers.parseLitString(fileName)); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java index adc9a9e70..8fc5285da 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java @@ -1,8 +1,26 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; -public class PseudoMacroCall extends Pseudo { +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; - public PseudoMacroCall(String id) { +import java.util.Objects; + +public class PseudoMacroCall extends Node { + public final String id; + + public PseudoMacroCall(int line, int column, String id) { + super(line, column); + this.id = Objects.requireNonNull(id); // children are exprs (arguments) } + + public PseudoMacroCall(Token id) { + this(id.getLine(), id.getCharPositionInLine(), id.getText()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java index 243ff3534..4089fafc3 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java @@ -1,13 +1,27 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import org.antlr.v4.runtime.Token; + import java.util.Objects; -public class PseudoMacroDef extends Pseudo { - private final String id; +public class PseudoMacroDef extends Node { + public final String id; - public PseudoMacroDef(String id) { + public PseudoMacroDef(int line, int column, String id) { + super(line, column); this.id = Objects.requireNonNull(id); // parameters are the first children // statements are followed } + + public PseudoMacroDef(Token id) { + this(id.getLine(), id.getCharPositionInLine(), id.getText()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java index ec20cbd74..2c67b35cf 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java @@ -1,12 +1,17 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; -public class PseudoOrg extends Pseudo { +public class PseudoOrg extends Node { - - public PseudoOrg() { + public PseudoOrg(int line, int column) { + super(line, column); // expr is the only child + } + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java index 5a188cdf2..d53ca4360 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java @@ -1,11 +1,26 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; -public class PseudoSet extends Pseudo { - public PseudoSet(String id) { +import java.util.Objects; + +public class PseudoSet extends Node { + public final String id; + + public PseudoSet(int line, int column, String id) { + super(line, column); + this.id = Objects.requireNonNull(id); // expr is the only child + } + + public PseudoSet(Token id) { + this(id.getLine(), id.getCharPositionInLine(), id.getText()); + } + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CompileException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CompileException.java index 8232c640c..e11d24808 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CompileException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CompileException.java @@ -22,14 +22,14 @@ public class CompileException extends RuntimeException { public final int line; public final int column; - public CompileException(int column, int line, String message) { + public CompileException(int line, int column, String message) { super("[" + line + "," + column + "] " + message); this.column = column; this.line = line; } - public CompileException(int column, int line, String message, Throwable cause) { + public CompileException(int line, int column, String message, Throwable cause) { super("[" + line + "," + column + "] " + message, cause); this.column = column; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java index bdc112a25..eb7602a71 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java @@ -2,16 +2,19 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser.*; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; -import net.emustudio.plugins.compiler.as8080.CommonParsers; -import net.emustudio.plugins.compiler.as8080.ast.data.*; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; +import org.antlr.v4.runtime.Token; -public class CreateDataVisitor extends As8080ParserBaseVisitor { +public class CreateDataVisitor extends As8080ParserBaseVisitor { @Override - public Data visitDataDB(DataDBContext ctx) { - Data data = new Data(); - DataDB db = new DataDB(); - data.addChild(db); + public Node visitDataDB(DataDBContext ctx) { + Token start = ctx.getStart(); + DataDB db = new DataDB(start.getLine(), start.getCharPositionInLine()); for (RDBdataContext next : ctx.rDBdata()) { if (next.expr != null) { @@ -19,18 +22,16 @@ public Data visitDataDB(DataDBContext ctx) { } else if (next.instr != null) { db.addChild(Visitors.instr.visit(next.instr)); } else { - db.addChild(new DataPlainString(CommonParsers.parseLitString(next.str))); + db.addChild(new DataPlainString(next.str)); } } - - return data; + return db; } @Override - public Data visitDataDW(DataDWContext ctx) { - Data data = new Data(); - DataDW dw = new DataDW(); - data.addChild(dw); + public Node visitDataDW(DataDWContext ctx) { + Token start = ctx.getStart(); + DataDW dw = new DataDW(start.getLine(), start.getCharPositionInLine()); for (RDWdataContext next : ctx.rDWdata()) { if (next.expr != null) { @@ -38,14 +39,14 @@ public Data visitDataDW(DataDWContext ctx) { } } - return data; + return dw; } @Override - public Data visitDataDS(DataDSContext ctx) { - DataDS ds = new DataDS(); + public Node visitDataDS(DataDSContext ctx) { + Token start = ctx.getStart(); + DataDS ds = new DataDS(start.getLine(), start.getCharPositionInLine()); ds.addChild(Visitors.expr.visit(ctx.data)); - return ds; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java index fa8f8b623..4aeb5b4b9 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java @@ -3,57 +3,60 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; import net.emustudio.plugins.compiler.as8080.CommonParsers; +import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.expr.*; +import org.antlr.v4.runtime.Token; -public class CreateExprVisitor extends As8080ParserBaseVisitor { +public class CreateExprVisitor extends As8080ParserBaseVisitor { @Override - public Expr visitExprOct(As8080Parser.ExprOctContext ctx) { - return new ExprNumber(CommonParsers.parseLitOct(ctx.num)); + public Node visitExprOct(As8080Parser.ExprOctContext ctx) { + return new ExprNumber(ctx.num, CommonParsers::parseLitOct); } @Override - public Expr visitExprHex1(As8080Parser.ExprHex1Context ctx) { - return new ExprNumber(CommonParsers.parseLitHex1(ctx.num)); + public Node visitExprHex1(As8080Parser.ExprHex1Context ctx) { + return new ExprNumber(ctx.num, CommonParsers::parseLitHex1); } @Override - public Expr visitExprHex2(As8080Parser.ExprHex2Context ctx) { - return new ExprNumber(CommonParsers.parseLitHex2(ctx.num)); + public Node visitExprHex2(As8080Parser.ExprHex2Context ctx) { + return new ExprNumber(ctx.num, CommonParsers::parseLitHex2); } @Override - public Expr visitExprDec(As8080Parser.ExprDecContext ctx) { - return new ExprNumber(CommonParsers.parseLitDec(ctx.num)); + public Node visitExprDec(As8080Parser.ExprDecContext ctx) { + return new ExprNumber(ctx.num, CommonParsers::parseLitDec); } @Override - public Expr visitExprBin(As8080Parser.ExprBinContext ctx) { - return new ExprNumber(CommonParsers.parseLitBin(ctx.num)); + public Node visitExprBin(As8080Parser.ExprBinContext ctx) { + return new ExprNumber(ctx.num, CommonParsers::parseLitBin); } @Override - public Expr visitExprId(As8080Parser.ExprIdContext ctx) { - return new ExprId(ctx.id.getText()); + public Node visitExprId(As8080Parser.ExprIdContext ctx) { + return new ExprId(ctx.id); } @Override - public Expr visitExprUnary(As8080Parser.ExprUnaryContext ctx) { - ExprUnary unary = new ExprUnary(ctx.unaryop.getType()); + public Node visitExprUnary(As8080Parser.ExprUnaryContext ctx) { + ExprUnary unary = new ExprUnary(ctx.unaryop); unary.addChild(visit(ctx.expr)); return unary; } @Override - public Expr visitExprInfix(As8080Parser.ExprInfixContext ctx) { - ExprInfix infix = new ExprInfix(ctx.op.getType()); + public Node visitExprInfix(As8080Parser.ExprInfixContext ctx) { + ExprInfix infix = new ExprInfix(ctx.op); infix.addChild(visit(ctx.expr1)); infix.addChild(visit(ctx.expr2)); return infix; } @Override - public Expr visitExprCurrentAddress(As8080Parser.ExprCurrentAddressContext ctx) { - return new ExprCurrentAddress(); + public Node visitExprCurrentAddress(As8080Parser.ExprCurrentAddressContext ctx) { + Token start = ctx.getStart(); + return new ExprCurrentAddress(start.getLine(), start.getCharPositionInLine()); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateInstrVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateInstrVisitor.java index a646481b1..1a9e959bc 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateInstrVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateInstrVisitor.java @@ -2,56 +2,55 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.instr.*; -import static net.emustudio.plugins.compiler.as8080.CommonParsers.*; - -public class CreateInstrVisitor extends As8080ParserBaseVisitor { +public class CreateInstrVisitor extends As8080ParserBaseVisitor { @Override - public Instr visitInstrNoArgs(As8080Parser.InstrNoArgsContext ctx) { - return new InstrNoArgs(ctx.opcode.getType()); + public Node visitInstrNoArgs(As8080Parser.InstrNoArgsContext ctx) { + return new InstrNoArgs(ctx.opcode); } @Override - public Instr visitInstrReg(As8080Parser.InstrRegContext ctx) { - return new InstrReg(ctx.opcode.getType(), parseReg(ctx.reg.start)); + public Node visitInstrReg(As8080Parser.InstrRegContext ctx) { + return new InstrReg(ctx.opcode, ctx.reg.getStart()); } @Override - public Instr visitInstrRegReg(As8080Parser.InstrRegRegContext ctx) { - return new InstrRegReg(ctx.opcode.getType(), parseReg(ctx.dst.start), parseReg(ctx.src.start)); + public Node visitInstrRegReg(As8080Parser.InstrRegRegContext ctx) { + return new InstrRegReg(ctx.opcode, ctx.dst.getStart(), ctx.src.getStart()); } @Override - public Instr visitInstrRegPair(As8080Parser.InstrRegPairContext ctx) { - return new InstrRegPair(ctx.opcode.getType(), parseRegPair(ctx.regpair)); + public Node visitInstrRegPair(As8080Parser.InstrRegPairContext ctx) { + return new InstrRegPair(ctx.opcode, ctx.regpair); } @Override - public Instr visitInstrRegPairExpr(As8080Parser.InstrRegPairExprContext ctx) { - InstrRegPairExpr instr = new InstrRegPairExpr(ctx.opcode.getType(), parseRegPair(ctx.regpair)); + public Node visitInstrRegPairExpr(As8080Parser.InstrRegPairExprContext ctx) { + InstrRegPairExpr instr = new InstrRegPairExpr(ctx.opcode, ctx.regpair); instr.addChild(Visitors.expr.visit(ctx.expr)); return instr; } @Override - public Instr visitInstrRegExpr(As8080Parser.InstrRegExprContext ctx) { - InstrRegExpr instr = new InstrRegExpr(ctx.opcode.getType(), parseReg(ctx.reg.start)); + public Node visitInstrRegExpr(As8080Parser.InstrRegExprContext ctx) { + InstrRegExpr instr = new InstrRegExpr(ctx.opcode, ctx.reg.getStart()); instr.addChild(Visitors.expr.visit(ctx.expr)); return instr; } @Override - public Instr visitInstrExpr(As8080Parser.InstrExprContext ctx) { - InstrExpr instr = new InstrExpr(ctx.opcode.getType()); + public Node visitInstrExpr(As8080Parser.InstrExprContext ctx) { + InstrExpr instr = new InstrExpr(ctx.opcode); instr.addChild(Visitors.expr.visit(ctx.expr)); return instr; } @Override - public Instr visitInstr8bitExpr(As8080Parser.Instr8bitExprContext ctx) { - InstrExpr instr = new InstrExpr(ctx.opcode.getType()); + public Node visitInstr8bitExpr(As8080Parser.Instr8bitExprContext ctx) { + InstrExpr instr = new InstrExpr(ctx.opcode); instr.addChild(Visitors.expr.visit(ctx.expr)); return instr; } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java index 1bb659c5c..b781efb90 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java @@ -4,20 +4,24 @@ import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; import net.emustudio.plugins.compiler.as8080.ast.Label; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.Statement; - -import java.util.Optional; - -import static net.emustudio.plugins.compiler.as8080.CommonParsers.parseLabel; public class CreateLineVisitor extends As8080ParserBaseVisitor { @Override - public Statement visitRLine(As8080Parser.RLineContext ctx) { - Statement statement = new Statement(); - Optional.ofNullable(ctx.label).ifPresent(label -> statement.addChild(new Label(parseLabel(label)))); + public Node visitRLine(As8080Parser.RLineContext ctx) { + Node label = null; + if (ctx.label != null) { + label = new Label(ctx.label); + } + Node statement = null; if (ctx.statement != null) { - statement.addChild(visit(ctx.statement)); + statement = visit(ctx.statement); + } + if (label != null) { + if (statement != null) { + label.addChild(statement); + } + return label; } return statement; } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java index df0dcd9c8..7ebe6f3be 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java @@ -2,8 +2,8 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; -import net.emustudio.plugins.compiler.as8080.ast.Statement; import java.util.Objects; @@ -19,7 +19,7 @@ public CreateProgramVisitor(Program program) { @Override public Program visitRLine(As8080Parser.RLineContext ctx) { - Statement statement = Visitors.line.visitRLine(ctx); + Node statement = Visitors.line.visitRLine(ctx); if (statement != null) { program.addChild(statement); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java index 8dee782f8..06bdb707b 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java @@ -2,38 +2,41 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser.*; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; +import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; -import static net.emustudio.plugins.compiler.as8080.CommonParsers.parseLitString; - -public class CreatePseudoVisitor extends As8080ParserBaseVisitor { +public class CreatePseudoVisitor extends As8080ParserBaseVisitor { @Override - public Pseudo visitPseudoOrg(PseudoOrgContext ctx) { - PseudoOrg pseudo = new PseudoOrg(); + public Node visitPseudoOrg(PseudoOrgContext ctx) { + Token start = ctx.getStart(); + PseudoOrg pseudo = new PseudoOrg(start.getLine(), start.getCharPositionInLine()); pseudo.addChild(Visitors.expr.visit(ctx.expr)); return pseudo; } @Override - public Pseudo visitPseudoEqu(PseudoEquContext ctx) { - PseudoEqu pseudo = new PseudoEqu(ctx.id.getText()); + public Node visitPseudoEqu(PseudoEquContext ctx) { + PseudoEqu pseudo = new PseudoEqu(ctx.id); pseudo.addChild(Visitors.expr.visit(ctx.expr)); return pseudo; } @Override - public Pseudo visitPseudoSet(PseudoSetContext ctx) { - PseudoSet pseudo = new PseudoSet(ctx.id.getText()); + public Node visitPseudoSet(PseudoSetContext ctx) { + PseudoSet pseudo = new PseudoSet(ctx.id); pseudo.addChild(Visitors.expr.visit(ctx.expr)); return pseudo; } @Override - public Pseudo visitPseudoIf(PseudoIfContext ctx) { - PseudoIf pseudo = new PseudoIf(); + public Node visitPseudoIf(PseudoIfContext ctx) { + Token start = ctx.getStart(); + + PseudoIf pseudo = new PseudoIf(start.getLine(), start.getCharPositionInLine()); pseudo.addChild(Visitors.expr.visit(ctx.expr)); for (RLineContext line : ctx.rLine()) { pseudo.addChild(Visitors.line.visitRLine(line)); @@ -42,12 +45,12 @@ public Pseudo visitPseudoIf(PseudoIfContext ctx) { } @Override - public Pseudo visitPseudoMacroDef(PseudoMacroDefContext ctx) { - PseudoMacroDef pseudo = new PseudoMacroDef(ctx.id.getText()); + public Node visitPseudoMacroDef(PseudoMacroDefContext ctx) { + PseudoMacroDef pseudo = new PseudoMacroDef(ctx.id); if (ctx.params != null) { for (TerminalNode next : ctx.params.ID_IDENTIFIER()) { - pseudo.addChild(new ExprId(next.getSymbol().getText())); + pseudo.addChild(new ExprId(next.getSymbol())); } } for (RLineContext line : ctx.rLine()) { @@ -57,8 +60,8 @@ public Pseudo visitPseudoMacroDef(PseudoMacroDefContext ctx) { } @Override - public Pseudo visitPseudoMacroCall(PseudoMacroCallContext ctx) { - PseudoMacroCall pseudo = new PseudoMacroCall(ctx.id.getText()); + public Node visitPseudoMacroCall(PseudoMacroCallContext ctx) { + PseudoMacroCall pseudo = new PseudoMacroCall(ctx.id); if (ctx.args != null) { for (RExpressionContext next : ctx.args.rExpression()) { @@ -69,7 +72,7 @@ public Pseudo visitPseudoMacroCall(PseudoMacroCallContext ctx) { } @Override - public Pseudo visitPseudoInclude(PseudoIncludeContext ctx) { - return new PseudoInclude(parseLitString(ctx.filename)); + public Node visitPseudoInclude(PseudoIncludeContext ctx) { + return new PseudoInclude(ctx.filename); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java new file mode 100644 index 000000000..113c69964 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java @@ -0,0 +1,37 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.As8080Lexer; +import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoInclude; +import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTree; + +import java.io.IOException; + +public class ExpandIncludesVisitor extends NodeVisitor { + + @Override + public void visit(PseudoInclude node) { + try { + As8080Lexer lexer = new As8080Lexer(CharStreams.fromFileName(node.filename)); + CommonTokenStream stream = new CommonTokenStream(lexer); + As8080Parser parser = new As8080Parser(stream); + stream.fill(); + ParseTree tree = parser.rStart(); + Program program = new Program(node.line, node.column); + + new CreateProgramVisitor(program).visit(tree); + + node.getParent().ifPresent(parent -> { + parent.removeChild(node); + parent.addChild(program); + }); + } catch (IOException e) { + throw new CompileException(node.line, node.column, "Could not read file: " + node.filename, e); + } + } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java index 7e3a648e0..d1cd0340b 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java @@ -1,8 +1,10 @@ package net.emustudio.plugins.compiler.as8080; import net.emustudio.plugins.compiler.as8080.ast.Program; -import net.emustudio.plugins.compiler.as8080.ast.Statement; -import net.emustudio.plugins.compiler.as8080.ast.data.*; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import org.junit.Test; @@ -16,10 +18,8 @@ public class ParseDataTest { public void testDBstring1() { Program program = parseProgram("db 'hello,world!'"); assertTrees(new Program() - .addChild(new Statement() - .addChild(new Data() - .addChild(new DataDB() - .addChild(new DataPlainString("hello,world!"))))), + .addChild(new DataDB(0, 0) + .addChild(new DataPlainString(0, 0, "hello,world!"))), program ); } @@ -28,10 +28,8 @@ public void testDBstring1() { public void testDBstring2() { Program program = parseProgram("db \"hello,world!\""); assertTrees(new Program() - .addChild(new Statement() - .addChild(new Data() - .addChild(new DataDB() - .addChild(new DataPlainString("hello,world!"))))), + .addChild(new DataDB(0, 0) + .addChild(new DataPlainString(0, 0, "hello,world!"))), program ); } @@ -40,10 +38,8 @@ public void testDBstring2() { public void testDBinstruction() { Program program = parseProgram("db stc"); assertTrees(new Program() - .addChild(new Statement() - .addChild(new Data() - .addChild(new DataDB() - .addChild(new InstrNoArgs(0))))), + .addChild(new DataDB(0, 0) + .addChild(new InstrNoArgs(0, 0, 0))), program ); } @@ -52,12 +48,10 @@ public void testDBinstruction() { public void testMultipleDB() { Program program = parseProgram("db -1,2,3"); assertTrees(new Program() - .addChild(new Statement() - .addChild(new Data() - .addChild(new DataDB() - .addChild(new ExprNumber(-1)) - .addChild(new ExprNumber(2)) - .addChild(new ExprNumber(3))))), + .addChild(new DataDB(0, 0) + .addChild(new ExprNumber(0, 0, -1)) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))), program ); } @@ -66,9 +60,8 @@ public void testMultipleDB() { public void testDBwithNegativeValue() { Program program = parseProgram("db -1"); assertTrees(new Program() - .addChild(new Statement() - .addChild(new Data() - .addChild(new DataDB().addChild(new ExprNumber(-1))))), + .addChild(new DataDB(0, 0) + .addChild(new ExprNumber(0, 0, -1))), program ); } @@ -77,12 +70,10 @@ public void testDBwithNegativeValue() { public void testMultipleDW() { Program program = parseProgram("dw -1,2,3"); assertTrees(new Program() - .addChild(new Statement() - .addChild(new Data() - .addChild(new DataDW() - .addChild(new ExprNumber(-1)) - .addChild(new ExprNumber(2)) - .addChild(new ExprNumber(3))))), + .addChild(new DataDW(0, 0) + .addChild(new ExprNumber(0, 0, -1)) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))), program ); } @@ -91,10 +82,8 @@ public void testMultipleDW() { public void testDWwithNegativeValue() { Program program = parseProgram("dw -1"); assertTrees(new Program() - .addChild(new Statement() - .addChild(new Data() - .addChild(new DataDW() - .addChild(new ExprNumber(-1))))), + .addChild(new DataDW(0, 0) + .addChild(new ExprNumber(0, 0, -1))), program ); } @@ -103,9 +92,8 @@ public void testDWwithNegativeValue() { public void testDS() { Program program = parseProgram("ds 0x55"); assertTrees(new Program() - .addChild(new Statement() - .addChild(new DataDS() - .addChild(new ExprNumber(0x55)))), + .addChild(new DataDS(0, 0) + .addChild(new ExprNumber(0, 0, 0x55))), program ); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java index 3b39c469b..54d79f155 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java @@ -1,8 +1,7 @@ package net.emustudio.plugins.compiler.as8080; +import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; -import net.emustudio.plugins.compiler.as8080.ast.Statement; -import net.emustudio.plugins.compiler.as8080.ast.expr.Expr; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprCurrentAddress; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; @@ -109,9 +108,9 @@ public void testRegPair() { @Test public void testMVI() { - Expr expr = (Expr) new ExprInfix(OP_ADD) - .addChild(new ExprCurrentAddress()) - .addChild(new ExprNumber(5)); + Node expr = new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); forStringCaseVariations("mvi", instrVariation -> { for (Map.Entry register : registers.entrySet()) { @@ -120,9 +119,8 @@ public void testMVI() { Program program = parseProgram(row); assertTrees( new Program() - .addChild(new Statement() - .addChild(new InstrRegExpr(OPCODE_MVI, register.getValue()) - .addChild(expr))), + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, register.getValue()) + .addChild(expr)), program ); }); @@ -132,9 +130,9 @@ public void testMVI() { @Test public void testLXI() { - Expr expr = (Expr) new ExprInfix(OP_ADD) - .addChild(new ExprCurrentAddress()) - .addChild(new ExprNumber(5)); + Node expr = new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); forStringCaseVariations("lxi", instrVariation -> { for (Map.Entry regPair : regPairsBDHSP.entrySet()) { @@ -143,9 +141,8 @@ public void testLXI() { Program program = parseProgram(row); assertTrees( new Program() - .addChild(new Statement() - .addChild(new InstrRegPairExpr(OPCODE_LXI, regPair.getValue()) - .addChild(expr))), + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, regPair.getValue()) + .addChild(expr)), program ); }); @@ -165,8 +162,7 @@ public void testMOV() { Program program = parseProgram(row); assertTrees( new Program() - .addChild(new Statement() - .addChild(new InstrRegReg(OPCODE_MOV, register1.getValue(), register2.getValue()))), + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, register1.getValue(), register2.getValue())), program ); } @@ -180,7 +176,7 @@ public void testMOV() { private void assertInstrNoArgs(String instr, int instrType) { forStringCaseVariations(instr, variation -> { Program program = parseProgram(variation); - assertTrees(new Program().addChild(new Statement().addChild(new InstrNoArgs(instrType))), program); + assertTrees(new Program().addChild(new InstrNoArgs(0, 0, instrType)), program); }); } @@ -191,9 +187,7 @@ private void assertInstrReg(String instr, int instrType) { String row = instrVariation + " " + registerVariation; Program program = parseProgram(row); assertTrees( - new Program() - .addChild(new Statement() - .addChild(new InstrReg(instrType, register.getValue()))), + new Program().addChild(new InstrReg(0, 0, instrType, register.getValue())), program ); }); @@ -202,13 +196,13 @@ private void assertInstrReg(String instr, int instrType) { } private void assertInstrExpr(String instr, int instrType) { - Expr expr = (Expr) new ExprInfix(OP_ADD) - .addChild(new ExprCurrentAddress()) - .addChild(new ExprNumber(5)); + Node expr = new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); forStringCaseVariations(instr, variation -> { Program program = parseProgram(variation + " $ + 5"); - assertTrees(new Program().addChild(new Statement().addChild(new InstrExpr(instrType).addChild(expr))), program); + assertTrees(new Program().addChild(new InstrExpr(0, 0, instrType).addChild(expr)), program); }); } @@ -219,9 +213,7 @@ private void assertInstrRegPair(String instr, int instrType, Map Date: Wed, 8 Dec 2021 12:41:46 +0100 Subject: [PATCH 052/314] [#201] Fix expand include visitor --- .../compiler/as8080/Assembler8080.java | 20 ++++++- .../plugins/compiler/as8080/ast/Node.java | 2 +- .../compiler/as8080/ast/NodeVisitor.java | 6 +- .../plugins/compiler/as8080/ast/Program.java | 30 ++++++++-- .../visitors/ExpandIncludesVisitor.java | 33 ++++++++++- .../visitors/FindDeclarationsVisitor.java | 57 +++++++++++++++++++ .../plugins/compiler/as8080/IncludeTest.java | 2 +- .../plugins/compiler/as8080/Utils.java | 1 + .../visitors/ExpandIncludesVisitorTest.java | 48 ++++++++++++++++ 9 files changed, 189 insertions(+), 10 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index e2c9309cd..260c87588 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -29,8 +29,16 @@ import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.RadixUtils; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; -import org.antlr.v4.runtime.*; +import net.emustudio.plugins.compiler.as8080.visitors.CreateProgramVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.ExpandIncludesVisitor; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.TokenStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -109,6 +117,16 @@ public boolean compile(String inputFileName, String outputFileName) { As8080Parser parser = createParser(tokens); parser.addErrorListener(new ParserErrorListener()); + Program program = new Program(); + new CreateProgramVisitor(program).visit(parser.rStart()); + + NodeVisitor[] visitors = new NodeVisitor[] { + new ExpandIncludesVisitor() + }; + + for (NodeVisitor visitor : visitors) { + visitor.visit(program); + } // ProgramParser programParser = new ProgramParser(); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 4f3fc239f..404a964ea 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -20,7 +20,7 @@ public Node addChild(Node node) { } public List getChildren() { - return Collections.unmodifiableList(children); + return List.copyOf(children); } public Optional getParent() { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java index eabd2cc90..44af0f1fa 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java @@ -14,6 +14,10 @@ public void visit(Node node) { visitChildren(node); } + public void visit(Program node) { + visitChildren(node); + } + public void visit(DataDB node) { visitChildren(node); } @@ -110,7 +114,7 @@ public void visit(Label node) { visitChildren(node); } - private void visitChildren(Node node) { + protected void visitChildren(Node node) { for (Node child : node.getChildren()) { child.accept(this); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java index e1000d20f..b81a99057 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java @@ -1,20 +1,40 @@ package net.emustudio.plugins.compiler.as8080.ast; +import java.util.Objects; +import java.util.Optional; + public class Program extends Node { - private final NameSpace nameSpace = new NameSpace(); + private final NameSpace env; + private String filename; - public Program(int line, int column) { + public Program(int line, int column, NameSpace env) { super(line, column); + this.env = Objects.requireNonNull(env); + } + + public Program(NameSpace env) { + this(0, 0, env); } public Program() { - this(0, 0); + this(new NameSpace()); } + public void setFileName(String filename) { + this.filename = filename; + } - public NameSpace env() { - return nameSpace; + public Optional getFileName() { + return Optional.ofNullable(filename); } + public NameSpace env() { + return env; + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java index 113c69964..c03d3a926 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java @@ -2,6 +2,7 @@ import net.emustudio.plugins.compiler.as8080.As8080Lexer; import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoInclude; @@ -11,21 +12,51 @@ import org.antlr.v4.runtime.tree.ParseTree; import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; public class ExpandIncludesVisitor extends NodeVisitor { + private NameSpace parentEnv; + private final Set includedFiles; + + public ExpandIncludesVisitor() { + this.includedFiles = Collections.emptySet(); + } + + public ExpandIncludesVisitor(Set includedFiles) { + this.includedFiles = Objects.requireNonNull(includedFiles); + } + + @Override + public void visit(Program node) { + parentEnv = node.env(); + visitChildren(node); + } @Override public void visit(PseudoInclude node) { + if (includedFiles.contains(node.filename)) { + throw new CompileException(node.line, node.column, "Infinite INCLUDE loop detected"); + } + try { As8080Lexer lexer = new As8080Lexer(CharStreams.fromFileName(node.filename)); CommonTokenStream stream = new CommonTokenStream(lexer); As8080Parser parser = new As8080Parser(stream); stream.fill(); ParseTree tree = parser.rStart(); - Program program = new Program(node.line, node.column); + Program program = new Program(node.line, node.column, parentEnv); + program.setFileName(node.filename); new CreateProgramVisitor(program).visit(tree); + Set alreadyIncludedFiles = new HashSet<>(includedFiles); + alreadyIncludedFiles.add(node.filename); + + new ExpandIncludesVisitor(alreadyIncludedFiles).visit(program); + node.getParent().ifPresent(parent -> { parent.removeChild(node); parent.addChild(program); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java new file mode 100644 index 000000000..ea2075b6f --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java @@ -0,0 +1,57 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Label; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoSet; + +public class FindDeclarationsVisitor extends NodeVisitor { + private NameSpace env; + + @Override + public void visit(Program node) { + this.env = node.env(); + visitChildren(node); + } + + @Override + public void visit(PseudoEqu node) { + super.visit(node); + } + + @Override + public void visit(PseudoMacroDef node) { + super.visit(node); + } + + @Override + public void visit(PseudoSet node) { + super.visit(node); + } + + @Override + public void visit(Label node) { + super.visit(node); + } + + @Override + public void visit(DataDB node) { + super.visit(node); + } + + @Override + public void visit(DataDW node) { + super.visit(node); + } + + @Override + public void visit(DataDS node) { + super.visit(node); + } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IncludeTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IncludeTest.java index 659c310ef..4e8755a60 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IncludeTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IncludeTest.java @@ -35,7 +35,7 @@ public void testIncludeAndForwardCall() throws Exception { ); assertProgram( - 0xCD, 03, 00, 0x3E, 0, 0xC9 + 0xCD, 0x03, 0x00, 0x3E, 0, 0xC9 ); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java index fc8c57df8..c6e601e5d 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -1,5 +1,6 @@ package net.emustudio.plugins.compiler.as8080; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.visitors.CreateProgramVisitor; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java index 12aa59699..ff32226ca 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java @@ -7,13 +7,22 @@ import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; public class ExpandIncludesVisitorTest { + @Rule + public TemporaryFolder folder = new TemporaryFolder(); @Test public void testExpandInclude() { @@ -34,6 +43,27 @@ public void testExpandInclude() { assertTrees(expected, program); } + @Test + public void testExpandIncludeTwoTimes() throws IOException { + File file = folder.newFile("file-a.asm"); + write(file, "rrc"); + + Program program = parseProgram( + "include '" + file.getPath() + "'\n" + + "include '" + file.getPath() +"'" + ); + ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); + visitor.visit(program); + + Node expected = new Program() + .addChild(new Program() + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC))) + .addChild(new Program() + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC))); + + assertTrees(expected, program); + } + @Test(expected = CompileException.class) public void testNonExistingFileThrows() { Program program = parseProgram("cmc\ninclude 'non-existant.asm'"); @@ -41,4 +71,22 @@ public void testNonExistingFileThrows() { visitor.visit(program); } + @Test(expected = CompileException.class) + public void testIndefiniteLoopDetected() throws IOException { + File fileA = folder.newFile("file-a.asm"); + File fileB = folder.newFile("file-b.asm"); + + write(fileA, "include '" + fileB.getPath() + "'"); + write(fileB, "include '" + fileA.getPath() + "'"); + + Program program = parseProgram("include '" + fileA.getPath() + "'"); + ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); + visitor.visit(program); + } + + private void write(File file, String content) throws IOException { + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + writer.write(content); + writer.close(); + } } From 1d002bae55f9c6df8994a8d010fef727bcfd12f3 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 9 Dec 2021 11:21:39 +0100 Subject: [PATCH 053/314] [#201] as-8080:wip --- .../as-8080/src/main/antlr/As8080Parser.g4 | 19 +++---- .../compiler/as8080/Assembler8080.java | 5 +- .../compiler/as8080/ParserErrorListener.java | 9 +++- .../plugins/compiler/as8080/ast/Label.java | 19 +++++++ .../compiler/as8080/ast/NameSpace.java | 31 +++++++++-- .../plugins/compiler/as8080/ast/Node.java | 9 +++- .../compiler/as8080/ast/NodeVisitor.java | 4 ++ .../as8080/ast/data/DataPlainString.java | 19 +++++++ .../compiler/as8080/ast/expr/ExprId.java | 19 +++++++ .../compiler/as8080/ast/expr/ExprInfix.java | 19 +++++++ .../compiler/as8080/ast/expr/ExprNumber.java | 19 +++++++ .../compiler/as8080/ast/expr/ExprUnary.java | 19 +++++++ .../compiler/as8080/ast/instr/InstrExpr.java | 19 +++++++ .../as8080/ast/instr/InstrNoArgs.java | 19 +++++++ .../compiler/as8080/ast/instr/InstrReg.java | 23 +++++++++ .../as8080/ast/instr/InstrRegExpr.java | 23 +++++++++ .../as8080/ast/instr/InstrRegPair.java | 23 +++++++++ .../as8080/ast/instr/InstrRegPairExpr.java | 23 +++++++++ .../as8080/ast/instr/InstrRegReg.java | 25 +++++++++ .../compiler/as8080/ast/pseudo/PseudoEqu.java | 19 +++++++ .../as8080/ast/pseudo/PseudoInclude.java | 19 +++++++ .../as8080/ast/pseudo/PseudoMacroCall.java | 19 +++++++ .../as8080/ast/pseudo/PseudoMacroDef.java | 19 +++++++ .../compiler/as8080/ast/pseudo/PseudoSet.java | 19 +++++++ .../exceptions/AlreadyDeclaredException.java | 9 ++++ .../exceptions/CouldNotReadFileException.java | 9 ++++ .../InfiniteIncludeLoopException.java | 9 ++++ .../exceptions/SyntaxErrorException.java | 11 ++++ .../visitors/ExpandIncludesVisitor.java | 19 +++---- .../visitors/FindDeclarationsVisitor.java | 37 +++----------- .../compiler/as8080/ParsePseudoTest.java | 45 ++++++++++++++++ .../plugins/compiler/as8080/Utils.java | 4 +- .../visitors/ExpandIncludesVisitorTest.java | 7 +-- .../visitors/FindDeclarationsVisitorTest.java | 51 +++++++++++++++++++ 34 files changed, 577 insertions(+), 65 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDeclaredException.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CouldNotReadFileException.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InfiniteIncludeLoopException.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/SyntaxErrorException.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitorTest.java diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index 65342340f..36229d5f9 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -5,11 +5,12 @@ options { } rStart: - EOL* rLine (EOL+ rLine)* EOL* EOF + EOL* rLine? (EOL+ rLine)* EOL* EOF ; rLine: - label=ID_LABEL? EOL* statement=rStatement?; + label=ID_LABEL? EOL* statement=rStatement + | label=ID_LABEL; rStatement: instr=rInstruction @@ -114,13 +115,13 @@ rRegister: ; rPseudoCode: - PREP_ORG expr=rExpression # pseudoOrg - | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu - | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoSet - | PREP_IF expr=rExpression (EOL+ rLine)+ EOL+ PREP_ENDIF # pseudoIf - | id=ID_IDENTIFIER PREP_MACRO params=rMacroParameters? (EOL+ rLine)+ EOL+ PREP_ENDM # pseudoMacroDef - | id=ID_IDENTIFIER args=rMacroArguments? # pseudoMacroCall - | PREP_INCLUDE filename=(LIT_STRING_1|LIT_STRING_2) # pseudoInclude + PREP_ORG expr=rExpression # pseudoOrg + | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu + | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoSet + | PREP_IF expr=rExpression EOL (rLine EOL)* EOL* PREP_ENDIF # pseudoIf + | id=ID_IDENTIFIER PREP_MACRO params=rMacroParameters? EOL (rLine EOL)* EOL* PREP_ENDM # pseudoMacroDef + | id=ID_IDENTIFIER args=rMacroArguments? # pseudoMacroCall + | PREP_INCLUDE filename=(LIT_STRING_1|LIT_STRING_2) # pseudoInclude ; rMacroParameters: diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index 260c87588..a1ec15e4b 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -35,6 +35,7 @@ import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; import net.emustudio.plugins.compiler.as8080.visitors.CreateProgramVisitor; import net.emustudio.plugins.compiler.as8080.visitors.ExpandIncludesVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.FindDeclarationsVisitor; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; @@ -115,13 +116,15 @@ public boolean compile(String inputFileName, String outputFileName) { CommonTokenStream tokens = new CommonTokenStream(lexer); As8080Parser parser = createParser(tokens); + parser.removeErrorListeners(); parser.addErrorListener(new ParserErrorListener()); Program program = new Program(); new CreateProgramVisitor(program).visit(parser.rStart()); NodeVisitor[] visitors = new NodeVisitor[] { - new ExpandIncludesVisitor() + new ExpandIncludesVisitor(), + new FindDeclarationsVisitor() }; for (NodeVisitor visitor : visitors) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java index 7d59b4743..69cd91629 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080; -import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; +import net.emustudio.plugins.compiler.as8080.exceptions.SyntaxErrorException; import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Recognizer; @@ -14,6 +14,11 @@ public void syntaxError( int charPositionInLine, String msg, RecognitionException e) { - throw new CompileException(charPositionInLine, line, msg); + + if (e == null) { + throw new SyntaxErrorException(line, charPositionInLine, msg); + } else { + throw new SyntaxErrorException(line, charPositionInLine, msg, e); + } } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java index 28af08134..40a6fa62e 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java @@ -22,4 +22,23 @@ public Label(Token label) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "Label(" + label +")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Label label1 = (Label) o; + return Objects.equals(label, label1.label); + } + + @Override + public int hashCode() { + return label != null ? label.hashCode() : 0; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java index 42c389d23..65cb30563 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java @@ -1,17 +1,40 @@ package net.emustudio.plugins.compiler.as8080.ast; -import org.antlr.v4.runtime.Token; +import net.emustudio.plugins.compiler.as8080.exceptions.AlreadyDeclaredException; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.Optional; public class NameSpace { - private final Map labels = new HashMap<>(); + private final Map declarations = new HashMap<>(); + private final Map macros = new HashMap<>(); - public void addLabel(Token token) { - labels.putIfAbsent(token.getText().toLowerCase(Locale.ENGLISH), token); + public void addDeclaration(String id, Node node) { + String idLower = id.toLowerCase(Locale.ENGLISH); + + if (declarations.containsKey(idLower)) { + throw new AlreadyDeclaredException(node.line, node.column, id); + } + declarations.put(idLower, node); + } + + public void addMacro(String id, Node node) { + String idLower = id.toLowerCase(Locale.ENGLISH); + + if (macros.containsKey(idLower)) { + throw new AlreadyDeclaredException(node.line, node.column, id); + } + macros.put(idLower, node); } + public Optional getDeclaration(String id) { + return Optional.ofNullable(declarations.get(id.toLowerCase(Locale.ENGLISH))); + } + + public Optional getMacro(String id) { + return Optional.ofNullable(macros.get(id.toLowerCase(Locale.ENGLISH))); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 404a964ea..6923607d3 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -48,10 +48,17 @@ public String toString() { private String toString(int indent) { String spaces = new String(new char[indent]).replace("\0", " "); StringBuilder builder = new StringBuilder(spaces); - builder.append(getClass().getSimpleName()).append("\n"); + builder.append(toStringShallow()); + if (!children.isEmpty()) { + builder.append("\n"); + } for (Node child : children) { builder.append(child.toString(indent + 2)); } return builder.toString(); } + + protected String toStringShallow() { + return getClass().getSimpleName(); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java index 44af0f1fa..83c17178d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java @@ -9,12 +9,16 @@ import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; public class NodeVisitor { + protected NameSpace env; public void visit(Node node) { visitChildren(node); } public void visit(Program node) { + if (env == null) { + this.env = node.env(); + } visitChildren(node); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java index 8c375d5d6..46cad2826 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java @@ -24,4 +24,23 @@ public DataPlainString(Token string) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "DataPlainString('" + string + "')"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + DataPlainString that = (DataPlainString) o; + return Objects.equals(string, that.string); + } + + @Override + public int hashCode() { + return string != null ? string.hashCode() : 0; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java index a426700c3..b4990b22d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java @@ -22,4 +22,23 @@ public ExprId(Token id) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "ExprId(" + id + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ExprId exprId = (ExprId) o; + return Objects.equals(id, exprId.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index 3b813bfa9..fbb788723 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -21,4 +21,23 @@ public ExprInfix(Token op) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "ExprInfix(" + operation + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ExprInfix infix = (ExprInfix) o; + return operation == infix.operation; + } + + @Override + public int hashCode() { + return operation; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java index 75a9fa7a7..29c42a96e 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java @@ -22,4 +22,23 @@ public ExprNumber(Token number, Function parser) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "ExprNumber(" + number + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ExprNumber that = (ExprNumber) o; + return number == that.number; + } + + @Override + public int hashCode() { + return number; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index f1d9140e8..7fe36f879 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -21,4 +21,23 @@ public ExprUnary(Token op) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "ExprUnary(" + operation + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ExprUnary exprUnary = (ExprUnary) o; + return operation == exprUnary.operation; + } + + @Override + public int hashCode() { + return operation; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index 2ac2cfed2..2cf5847a5 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -21,4 +21,23 @@ public InstrExpr(Token opcode) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "InstrExpr(" + opcode + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrExpr instrExpr = (InstrExpr) o; + return opcode == instrExpr.opcode; + } + + @Override + public int hashCode() { + return opcode; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java index 237e8c795..60a38c24f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java @@ -20,4 +20,23 @@ public InstrNoArgs(Token opcode) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "InstrNoArgs(" + opcode + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrNoArgs that = (InstrNoArgs) o; + return opcode == that.opcode; + } + + @Override + public int hashCode() { + return opcode; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java index 8decf5c77..672e8a188 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java @@ -22,4 +22,27 @@ public InstrReg(Token opcode, Token reg) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "InstrReg(" + opcode + "," + reg +")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrReg instrReg = (InstrReg) o; + + if (opcode != instrReg.opcode) return false; + return reg == instrReg.reg; + } + + @Override + public int hashCode() { + int result = opcode; + result = 31 * result + reg; + return result; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java index 236e0f901..6cfb4df08 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java @@ -23,4 +23,27 @@ public InstrRegExpr(Token opcode, Token reg) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "InstrRegExpr(" + opcode + "," + reg +")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrRegExpr that = (InstrRegExpr) o; + + if (opcode != that.opcode) return false; + return reg == that.reg; + } + + @Override + public int hashCode() { + int result = opcode; + result = 31 * result + reg; + return result; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java index 6e19f8cfa..d5eb65bc0 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java @@ -22,4 +22,27 @@ public InstrRegPair(Token opcode, Token regPair) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "InstrRegPair(" + opcode + "," + regPair +")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrRegPair that = (InstrRegPair) o; + + if (opcode != that.opcode) return false; + return regPair == that.regPair; + } + + @Override + public int hashCode() { + int result = opcode; + result = 31 * result + regPair; + return result; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java index 04b0ff380..2d3d3ac28 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java @@ -23,4 +23,27 @@ public InstrRegPairExpr(Token opcode, Token regPair) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "InstrRegPairExpr(" + opcode + "," + regPair +")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrRegPairExpr that = (InstrRegPairExpr) o; + + if (opcode != that.opcode) return false; + return regPair == that.regPair; + } + + @Override + public int hashCode() { + int result = opcode; + result = 31 * result + regPair; + return result; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java index 2a9a8f783..a17d1dc47 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java @@ -24,4 +24,29 @@ public InstrRegReg(Token opcode, Token dst, Token src) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "InstrRegReg(" + opcode + ","+ dstReg +","+ srcReg +")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrRegReg that = (InstrRegReg) o; + + if (opcode != that.opcode) return false; + if (srcReg != that.srcReg) return false; + return dstReg == that.dstReg; + } + + @Override + public int hashCode() { + int result = opcode; + result = 31 * result + srcReg; + result = 31 * result + dstReg; + return result; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java index fd7b280e7..a59a9319c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java @@ -23,4 +23,23 @@ public PseudoEqu(Token id) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "PseudoEqu(" + id + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoEqu pseudoEqu = (PseudoEqu) o; + return Objects.equals(id, pseudoEqu.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java index f8a858c72..f8b07a056 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java @@ -23,4 +23,23 @@ public PseudoInclude(Token fileName) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "PseudoInclude('" + filename + "')"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoInclude that = (PseudoInclude) o; + return Objects.equals(filename, that.filename); + } + + @Override + public int hashCode() { + return filename != null ? filename.hashCode() : 0; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java index 8fc5285da..881d2b37d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java @@ -23,4 +23,23 @@ public PseudoMacroCall(Token id) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "PseudoMacroCall(" + id + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoMacroCall that = (PseudoMacroCall) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java index 4089fafc3..33b113bde 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java @@ -24,4 +24,23 @@ public PseudoMacroDef(Token id) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "PseudoMacroDef(" + id + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoMacroDef that = (PseudoMacroDef) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java index d53ca4360..1dbe6a5a5 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java @@ -23,4 +23,23 @@ public PseudoSet(Token id) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected String toStringShallow() { + return "PseudoSet(" + id + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoSet pseudoSet = (PseudoSet) o; + return Objects.equals(id, pseudoSet.id); + } + + @Override + public int hashCode() { + return id != null ? id.hashCode() : 0; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDeclaredException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDeclaredException.java new file mode 100644 index 000000000..ab05bdde0 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDeclaredException.java @@ -0,0 +1,9 @@ +package net.emustudio.plugins.compiler.as8080.exceptions; + +public class AlreadyDeclaredException extends CompileException { + private final static String MSG = " was already declared"; + + public AlreadyDeclaredException(int line, int column, String message) { + super(line, column, message + MSG); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CouldNotReadFileException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CouldNotReadFileException.java new file mode 100644 index 000000000..5324a9366 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CouldNotReadFileException.java @@ -0,0 +1,9 @@ +package net.emustudio.plugins.compiler.as8080.exceptions; + +public class CouldNotReadFileException extends CompileException { + private final static String MSG = "Could not read file: "; + + public CouldNotReadFileException(int line, int column, String filename, Throwable cause) { + super(line, column, MSG + filename, cause); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InfiniteIncludeLoopException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InfiniteIncludeLoopException.java new file mode 100644 index 000000000..b8945abfe --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InfiniteIncludeLoopException.java @@ -0,0 +1,9 @@ +package net.emustudio.plugins.compiler.as8080.exceptions; + +public class InfiniteIncludeLoopException extends CompileException { + private static final String MSG = "Infinite include loop detected"; + + public InfiniteIncludeLoopException(int line, int column) { + super(line, column, MSG); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/SyntaxErrorException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/SyntaxErrorException.java new file mode 100644 index 000000000..8d663b282 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/SyntaxErrorException.java @@ -0,0 +1,11 @@ +package net.emustudio.plugins.compiler.as8080.exceptions; + +public class SyntaxErrorException extends CompileException { + public SyntaxErrorException(int line, int column, String message) { + super(line, column, message); + } + + public SyntaxErrorException(int line, int column, String message, Throwable cause) { + super(line, column, message, cause); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java index c03d3a926..4bff4824f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java @@ -2,11 +2,11 @@ import net.emustudio.plugins.compiler.as8080.As8080Lexer; import net.emustudio.plugins.compiler.as8080.As8080Parser; -import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoInclude; -import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; +import net.emustudio.plugins.compiler.as8080.exceptions.CouldNotReadFileException; +import net.emustudio.plugins.compiler.as8080.exceptions.InfiniteIncludeLoopException; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; @@ -18,8 +18,7 @@ import java.util.Set; public class ExpandIncludesVisitor extends NodeVisitor { - private NameSpace parentEnv; - private final Set includedFiles; + private final Set includedFiles; // TODO: windows platform case-insensitive! public ExpandIncludesVisitor() { this.includedFiles = Collections.emptySet(); @@ -29,16 +28,10 @@ public ExpandIncludesVisitor(Set includedFiles) { this.includedFiles = Objects.requireNonNull(includedFiles); } - @Override - public void visit(Program node) { - parentEnv = node.env(); - visitChildren(node); - } - @Override public void visit(PseudoInclude node) { if (includedFiles.contains(node.filename)) { - throw new CompileException(node.line, node.column, "Infinite INCLUDE loop detected"); + throw new InfiniteIncludeLoopException(node.line, node.column); } try { @@ -47,7 +40,7 @@ public void visit(PseudoInclude node) { As8080Parser parser = new As8080Parser(stream); stream.fill(); ParseTree tree = parser.rStart(); - Program program = new Program(node.line, node.column, parentEnv); + Program program = new Program(node.line, node.column, env); program.setFileName(node.filename); new CreateProgramVisitor(program).visit(tree); @@ -62,7 +55,7 @@ public void visit(PseudoInclude node) { parent.addChild(program); }); } catch (IOException e) { - throw new CompileException(node.line, node.column, "Could not read file: " + node.filename, e); + throw new CouldNotReadFileException(node.line, node.column, node.filename, e); } } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java index ea2075b6f..0198a3a92 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java @@ -1,57 +1,32 @@ package net.emustudio.plugins.compiler.as8080.visitors; import net.emustudio.plugins.compiler.as8080.ast.Label; -import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; -import net.emustudio.plugins.compiler.as8080.ast.Program; -import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; -import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; -import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoSet; public class FindDeclarationsVisitor extends NodeVisitor { - private NameSpace env; - - @Override - public void visit(Program node) { - this.env = node.env(); - visitChildren(node); - } @Override public void visit(PseudoEqu node) { - super.visit(node); + env.addDeclaration(node.id, node); } @Override public void visit(PseudoMacroDef node) { - super.visit(node); + env.addMacro(node.id, node); + visitChildren(node); } @Override public void visit(PseudoSet node) { - super.visit(node); + env.addDeclaration(node.id, node); } @Override public void visit(Label node) { - super.visit(node); - } - - @Override - public void visit(DataDB node) { - super.visit(node); - } - - @Override - public void visit(DataDW node) { - super.visit(node); - } - - @Override - public void visit(DataDS node) { - super.visit(node); + env.addDeclaration(node.label, node); + visitChildren(node); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java index 1a9bc4ef1..6f7abcfdf 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java @@ -9,8 +9,11 @@ import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; +import net.emustudio.plugins.compiler.as8080.exceptions.SyntaxErrorException; import org.junit.Test; +import java.util.List; + import static net.emustudio.plugins.compiler.as8080.As8080Lexer.*; import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; @@ -65,6 +68,28 @@ public void testIf() { ); } + @Test + public void testIfEmpty() { + List programs = List.of( + "if 1\n\n\nendif", + "if 1\n\nendif", + "if 1\nendif" + ); + + for (String src : programs) { + Program program = parseProgram(src); + Node expected = new Program() + .addChild(new PseudoIf(0,0) + .addChild(new ExprNumber(0,0,1))); + assertTrees(expected, program); + } + } + + @Test(expected = SyntaxErrorException.class) + public void testIfEndifMustBeOnNewLine() { + parseProgram("if 1\nrrc\nrrc endif"); + } + @Test public void testTwoLabelsInsideIf() { Program program = parseProgram("if 1\n" @@ -109,6 +134,26 @@ public void testMacroDef() { assertTrees(expected, program); } + @Test + public void testMacroDefEmpty() { + List programs = List.of( + "shrt macro\n\n\nendm", + "shrt macro\n\nendm", + "shrt macro\nendm" + ); + + for (String src : programs) { + Program program = parseProgram(src); + Node expected = new Program().addChild(new PseudoMacroDef(0, 0, "shrt")); + assertTrees(expected, program); + } + } + + @Test(expected = SyntaxErrorException.class) + public void testMacroDefEndmMustBeOnNewLine() { + parseProgram("shrt macro\nrrc\nrrc endm"); + } + @Test public void testMacroCallNoParams() { Program program = parseProgram("shrt"); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java index c6e601e5d..dfca49357 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -60,12 +60,14 @@ public static ParseTree parse(String program) { As8080Lexer lexer = new As8080Lexer(CharStreams.fromString(program)); CommonTokenStream stream = new CommonTokenStream(lexer); As8080Parser parser = new As8080Parser(stream); + parser.removeErrorListeners(); + parser.addErrorListener(new ParserErrorListener()); stream.fill(); return parser.rStart(); } public static Program parseProgram(String programString) { - ParseTree tree = Utils.parse(programString); + ParseTree tree = parse(programString); Program program = new Program(); CreateProgramVisitor visitor = new CreateProgramVisitor(program); visitor.visit(tree); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java index ff32226ca..ea49d7147 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java @@ -6,7 +6,8 @@ import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; -import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; +import net.emustudio.plugins.compiler.as8080.exceptions.CouldNotReadFileException; +import net.emustudio.plugins.compiler.as8080.exceptions.InfiniteIncludeLoopException; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -64,14 +65,14 @@ public void testExpandIncludeTwoTimes() throws IOException { assertTrees(expected, program); } - @Test(expected = CompileException.class) + @Test(expected = CouldNotReadFileException.class) public void testNonExistingFileThrows() { Program program = parseProgram("cmc\ninclude 'non-existant.asm'"); ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); visitor.visit(program); } - @Test(expected = CompileException.class) + @Test(expected = InfiniteIncludeLoopException.class) public void testIndefiniteLoopDetected() throws IOException { File fileA = folder.newFile("file-a.asm"); File fileB = folder.newFile("file-b.asm"); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitorTest.java new file mode 100644 index 000000000..0e44bc4b9 --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitorTest.java @@ -0,0 +1,51 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Label; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoSet; +import org.junit.Test; + +import java.util.Optional; + +import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; +import static org.junit.Assert.assertEquals; + +public class FindDeclarationsVisitorTest { + + @Test + public void testDeclarationsAreFound() { + Program program = parseProgram("label:\nconstant equ 1\nvariable set 1\nxxx macro\nendm"); + FindDeclarationsVisitor visitor = new FindDeclarationsVisitor(); + visitor.visit(program); + + NameSpace env = program.env(); + assertEquals(Optional.of(new Label(0,0, "label")), env.getDeclaration("LABEL")); + assertEquals(Optional.of(new PseudoEqu(0,0, "constant")), env.getDeclaration("cOnStanT")); + assertEquals( + Optional.of(new PseudoSet(0,0, "variable") + .addChild(new ExprNumber(0,0,1))), + env.getDeclaration("VarIable") + ); + assertEquals(Optional.of(new PseudoMacroDef(0,0,"xxx")), env.getMacro("XXX")); + } + + @Test + public void testMacrosAndDeclarationsAreIndependent() { + + } + + @Test + public void testDeclarationAlreadyDefined() { + + } + + @Test + public void testMacroAlreadyDefined() { + + } + +} From 6012302a4059db7e75255bca86f1b038dbd7d16b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 10 Dec 2021 11:53:49 +0100 Subject: [PATCH 054/314] [#201] use released edigen 1.4 --- settings.gradle | 5 ----- 1 file changed, 5 deletions(-) diff --git a/settings.gradle b/settings.gradle index 2f4baa7f6..e2fb0be6d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,11 +17,6 @@ * along with this program. If not, see . */ -pluginManagement { - includeBuild '/home/vbmacher/projects/emustudio/edigen-gradle-plugin' -} - - rootProject.name = 'emuStudio' include ':application' From 4f174a724a0643c40595e8d5ac6dfa0905bbdad4 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 13 Dec 2021 13:42:11 +0100 Subject: [PATCH 055/314] [#201] check declarations visitor --- .../compiler/as8080/Assembler8080.java | 5 +- .../visitors/CheckDeclarationsVisitor.java | 68 +++++++++++++++++++ .../visitors/FindDeclarationsVisitor.java | 32 --------- .../CheckDeclarationsVisitorTest.java | 59 ++++++++++++++++ .../visitors/FindDeclarationsVisitorTest.java | 51 -------------- 5 files changed, 129 insertions(+), 86 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java delete mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitorTest.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index a1ec15e4b..59bf4d20d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -29,13 +29,12 @@ import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.RadixUtils; -import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; import net.emustudio.plugins.compiler.as8080.visitors.CreateProgramVisitor; import net.emustudio.plugins.compiler.as8080.visitors.ExpandIncludesVisitor; -import net.emustudio.plugins.compiler.as8080.visitors.FindDeclarationsVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.CheckDeclarationsVisitor; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; @@ -124,7 +123,7 @@ public boolean compile(String inputFileName, String outputFileName) { NodeVisitor[] visitors = new NodeVisitor[] { new ExpandIncludesVisitor(), - new FindDeclarationsVisitor() + new CheckDeclarationsVisitor() }; for (NodeVisitor visitor : visitors) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java new file mode 100644 index 000000000..09dd5a9cd --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java @@ -0,0 +1,68 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Label; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoSet; +import net.emustudio.plugins.compiler.as8080.exceptions.AlreadyDeclaredException; + +import java.util.*; + +public class CheckDeclarationsVisitor extends NodeVisitor { + private final Set declarations = new HashSet<>(); + private final Set macros = new HashSet<>(); + private final Set variables = new HashSet<>(); + + @Override + public void visit(PseudoEqu node) { + addDeclaration(node.id, node); + } + + @Override + public void visit(PseudoMacroDef node) { + addMacro(node.id, node); + visitChildren(node); + } + + @Override + public void visit(PseudoSet node) { + addVariable(node.id, node); + } + + @Override + public void visit(Label node) { + addDeclaration(node.label, node); + visitChildren(node); + } + + private void addVariable(String id, Node node) { + addDeclaration(id, true, node); + } + + private void addDeclaration(String id, Node node) { + addDeclaration(id, false, node); + } + + private void addDeclaration(String id, boolean isVariable, Node node) { + String idLower = id.toLowerCase(Locale.ENGLISH); + + if (declarations.contains(idLower) && (!isVariable || !variables.contains(id))) { + throw new AlreadyDeclaredException(node.line, node.column, id); + } + declarations.add(idLower); + if (isVariable) { + variables.add(idLower); + } + } + + private void addMacro(String id, Node node) { + String idLower = id.toLowerCase(Locale.ENGLISH); + + if (macros.contains(idLower)) { + throw new AlreadyDeclaredException(node.line, node.column, id); + } + macros.add(idLower); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java deleted file mode 100644 index 0198a3a92..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitor.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.visitors; - -import net.emustudio.plugins.compiler.as8080.ast.Label; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoSet; - -public class FindDeclarationsVisitor extends NodeVisitor { - - @Override - public void visit(PseudoEqu node) { - env.addDeclaration(node.id, node); - } - - @Override - public void visit(PseudoMacroDef node) { - env.addMacro(node.id, node); - visitChildren(node); - } - - @Override - public void visit(PseudoSet node) { - env.addDeclaration(node.id, node); - } - - @Override - public void visit(Label node) { - env.addDeclaration(node.label, node); - visitChildren(node); - } -} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java new file mode 100644 index 000000000..5cf1b676a --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java @@ -0,0 +1,59 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.exceptions.AlreadyDeclaredException; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; + +public class CheckDeclarationsVisitorTest { + + @Test + public void testDeclarationsAreFound() { + Program program = parseProgram("label:\nconstant equ 1\nvariable set 1\nxxx macro\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + } + + @Test + public void testVariableTwoTimesPass() { + Program program = parseProgram("var set 1\nvar set 2"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + } + + @Test(expected = AlreadyDeclaredException.class) + public void testConstantTwoTimesCannotBeDefined() { + Program program = parseProgram("var equ 1\nvar equ 2"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + } + + @Test(expected = AlreadyDeclaredException.class) + public void testVarCannotBeDefinedIfAnotherDeclarationExists() { + Program program = parseProgram("var equ 1\nvar set 2"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + } + + @Test + public void testMacrosAndDeclarationsAreIndependent() { + Program program = parseProgram("label:\nlabel macro\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + } + + @Test(expected = AlreadyDeclaredException.class) + public void testLabelThenConstantAlreadyDeclared() { + Program program = parseProgram("label:\nlabel equ 1"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + } + + @Test(expected = AlreadyDeclaredException.class) + public void testMacroAlreadyDeclared() { + Program program = parseProgram("label macro\nendm\nlabel macro\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitorTest.java deleted file mode 100644 index 0e44bc4b9..000000000 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/FindDeclarationsVisitorTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.visitors; - -import net.emustudio.plugins.compiler.as8080.ast.Label; -import net.emustudio.plugins.compiler.as8080.ast.NameSpace; -import net.emustudio.plugins.compiler.as8080.ast.Program; -import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoSet; -import org.junit.Test; - -import java.util.Optional; - -import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; -import static org.junit.Assert.assertEquals; - -public class FindDeclarationsVisitorTest { - - @Test - public void testDeclarationsAreFound() { - Program program = parseProgram("label:\nconstant equ 1\nvariable set 1\nxxx macro\nendm"); - FindDeclarationsVisitor visitor = new FindDeclarationsVisitor(); - visitor.visit(program); - - NameSpace env = program.env(); - assertEquals(Optional.of(new Label(0,0, "label")), env.getDeclaration("LABEL")); - assertEquals(Optional.of(new PseudoEqu(0,0, "constant")), env.getDeclaration("cOnStanT")); - assertEquals( - Optional.of(new PseudoSet(0,0, "variable") - .addChild(new ExprNumber(0,0,1))), - env.getDeclaration("VarIable") - ); - assertEquals(Optional.of(new PseudoMacroDef(0,0,"xxx")), env.getMacro("XXX")); - } - - @Test - public void testMacrosAndDeclarationsAreIndependent() { - - } - - @Test - public void testDeclarationAlreadyDefined() { - - } - - @Test - public void testMacroAlreadyDefined() { - - } - -} From aecb0d9969b78598e267f3a7c51b7c42c3f275fd Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 14 Dec 2021 10:25:24 +0100 Subject: [PATCH 056/314] [#201] as-8080: expand macros visitor --- .../compiler/as8080/Assembler8080.java | 4 +- .../plugins/compiler/as8080/CompileError.java | 46 ++++++++ .../compiler/as8080/ParserErrorListener.java | 2 +- .../plugins/compiler/as8080/ast/Label.java | 5 + .../compiler/as8080/ast/NameSpace.java | 37 ++---- .../plugins/compiler/as8080/ast/Node.java | 25 ++++- .../compiler/as8080/ast/NodeVisitor.java | 10 ++ .../plugins/compiler/as8080/ast/Program.java | 7 ++ .../compiler/as8080/ast/data/DataDB.java | 5 + .../compiler/as8080/ast/data/DataDS.java | 5 + .../compiler/as8080/ast/data/DataDW.java | 5 + .../as8080/ast/data/DataPlainString.java | 5 + .../as8080/ast/expr/ExprCurrentAddress.java | 5 + .../compiler/as8080/ast/expr/ExprId.java | 5 + .../compiler/as8080/ast/expr/ExprInfix.java | 5 + .../compiler/as8080/ast/expr/ExprNumber.java | 5 + .../compiler/as8080/ast/expr/ExprUnary.java | 5 + .../compiler/as8080/ast/instr/InstrExpr.java | 5 + .../as8080/ast/instr/InstrNoArgs.java | 5 + .../compiler/as8080/ast/instr/InstrReg.java | 5 + .../as8080/ast/instr/InstrRegExpr.java | 5 + .../as8080/ast/instr/InstrRegPair.java | 5 + .../as8080/ast/instr/InstrRegPairExpr.java | 5 + .../as8080/ast/instr/InstrRegReg.java | 5 + .../compiler/as8080/ast/pseudo/PseudoEqu.java | 5 + .../compiler/as8080/ast/pseudo/PseudoIf.java | 5 + .../as8080/ast/pseudo/PseudoInclude.java | 5 + .../as8080/ast/pseudo/PseudoMacroCall.java | 5 + .../as8080/ast/pseudo/PseudoMacroDef.java | 4 + .../compiler/as8080/ast/pseudo/PseudoOrg.java | 5 + .../compiler/as8080/ast/pseudo/PseudoSet.java | 5 + .../InfiniteIncludeLoopException.java | 9 -- .../{ => used}/AlreadyDeclaredException.java | 4 +- .../{ => used}/CouldNotReadFileException.java | 4 +- .../as8080/exceptions/used/FatalError.java | 19 ++++ .../{ => used}/SyntaxErrorException.java | 4 +- .../visitors/CheckDeclarationsVisitor.java | 11 +- .../visitors/ExpandIncludesVisitor.java | 15 +-- .../as8080/visitors/ExpandMacrosVisitor.java | 78 +++++++++++++ .../compiler/as8080/ParsePseudoTest.java | 2 +- .../plugins/compiler/as8080/Utils.java | 10 ++ .../CheckDeclarationsVisitorTest.java | 15 ++- .../visitors/ExpandIncludesVisitorTest.java | 39 +++---- .../as8080/visitors/ExpandMacrosTest.java | 106 ++++++++++++++++++ 44 files changed, 477 insertions(+), 89 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InfiniteIncludeLoopException.java rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/{ => used}/AlreadyDeclaredException.java (65%) rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/{ => used}/CouldNotReadFileException.java (67%) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/FatalError.java rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/{ => used}/SyntaxErrorException.java (69%) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index 59bf4d20d..2b515541c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -35,6 +35,7 @@ import net.emustudio.plugins.compiler.as8080.visitors.CreateProgramVisitor; import net.emustudio.plugins.compiler.as8080.visitors.ExpandIncludesVisitor; import net.emustudio.plugins.compiler.as8080.visitors.CheckDeclarationsVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.ExpandMacrosVisitor; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; @@ -123,7 +124,8 @@ public boolean compile(String inputFileName, String outputFileName) { NodeVisitor[] visitors = new NodeVisitor[] { new ExpandIncludesVisitor(), - new CheckDeclarationsVisitor() + new CheckDeclarationsVisitor(), + new ExpandMacrosVisitor() }; for (NodeVisitor visitor : visitors) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java new file mode 100644 index 000000000..3adeab47c --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java @@ -0,0 +1,46 @@ +package net.emustudio.plugins.compiler.as8080; + +import net.emustudio.plugins.compiler.as8080.ast.Node; + +import java.io.IOException; +import java.util.Objects; + +public class CompileError { + public static final int ERROR_ALREADY_DECLARED = 1; + public static final int ERROR_INFINITE_LOOP_DETECTED = 2; + public static final int ERROR_CANNOT_READ_FILE = 3; + public static final int ERROR_NOT_DEFINED = 4; + + public final int line; + public final int column; + public final String msg; + public final int errorCode; + + private CompileError(int line, int column, int errorCode, String msg) { + this.line = line; + this.column = column; + this.errorCode = errorCode; + this.msg = Objects.requireNonNull(msg); + } + + private CompileError(Node node, int errorCode, String msg) { + this(node.line, node.column, errorCode, msg); + } + + + public static CompileError alreadyDeclared(Node node, String what) { + return new CompileError(node, ERROR_ALREADY_DECLARED, what + " was already declared"); + } + + public static CompileError infiniteLoopDetected(Node node, String what) { + return new CompileError(node, ERROR_INFINITE_LOOP_DETECTED, "Infinite " + what + " loop detected"); + } + + public static CompileError couldNotReadFile(Node node, String filename, IOException e) { + return new CompileError(node, ERROR_CANNOT_READ_FILE, "Could not read file: " + filename + " (" + e.getMessage() + ")"); + } + + public static CompileError notDefined(Node node, String what) { + return new CompileError(node, ERROR_NOT_DEFINED, "Not defined: " + what); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java index 69cd91629..dd06f6077 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080; -import net.emustudio.plugins.compiler.as8080.exceptions.SyntaxErrorException; +import net.emustudio.plugins.compiler.as8080.exceptions.used.SyntaxErrorException; import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Recognizer; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java index 40a6fa62e..63bce9a94 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java @@ -28,6 +28,11 @@ protected String toStringShallow() { return "Label(" + label +")"; } + @Override + protected Node mkCopy() { + return new Label(line, column, label); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java index 65cb30563..02b26ef6c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java @@ -1,40 +1,17 @@ package net.emustudio.plugins.compiler.as8080.ast; -import net.emustudio.plugins.compiler.as8080.exceptions.AlreadyDeclaredException; +import net.emustudio.plugins.compiler.as8080.CompileError; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; +import java.util.*; public class NameSpace { + private final List errors = new ArrayList<>(); - private final Map declarations = new HashMap<>(); - private final Map macros = new HashMap<>(); - - public void addDeclaration(String id, Node node) { - String idLower = id.toLowerCase(Locale.ENGLISH); - - if (declarations.containsKey(idLower)) { - throw new AlreadyDeclaredException(node.line, node.column, id); - } - declarations.put(idLower, node); - } - - public void addMacro(String id, Node node) { - String idLower = id.toLowerCase(Locale.ENGLISH); - - if (macros.containsKey(idLower)) { - throw new AlreadyDeclaredException(node.line, node.column, id); - } - macros.put(idLower, node); - } - - public Optional getDeclaration(String id) { - return Optional.ofNullable(declarations.get(id.toLowerCase(Locale.ENGLISH))); + public void error(CompileError error) { + errors.add(Objects.requireNonNull(error)); } - public Optional getMacro(String id) { - return Optional.ofNullable(macros.get(id.toLowerCase(Locale.ENGLISH))); + public boolean hasError(int errorCode) { + return errors.stream().anyMatch(e -> e.errorCode == errorCode); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 6923607d3..19ca3e60c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -15,10 +15,17 @@ public Node(int line, int column) { public Node addChild(Node node) { node.parent = this; - children.add(Objects.requireNonNull(node)); + children.add(node); return this; } + public void addChildren(List nodes) { + for (Node node : nodes) { + node.parent = this; + } + children.addAll(nodes); + } + public List getChildren() { return List.copyOf(children); } @@ -36,6 +43,12 @@ public void removeChild(Node node) { children.remove(node); } + public Optional remove() { + Optional parent = getParent(); + parent.ifPresent(p -> p.removeChild(this)); + return parent; + } + public void accept(NodeVisitor visitor) { visitor.visit(this); } @@ -61,4 +74,14 @@ private String toString(int indent) { protected String toStringShallow() { return getClass().getSimpleName(); } + + protected abstract Node mkCopy(); + + public Node copy() { + Node copied = mkCopy(); + for (Node child : children) { + copied.addChild(child.copy()); + } + return copied; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java index 83c17178d..e349d56f1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java @@ -1,5 +1,6 @@ package net.emustudio.plugins.compiler.as8080.ast; +import net.emustudio.plugins.compiler.as8080.CompileError; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; @@ -7,10 +8,19 @@ import net.emustudio.plugins.compiler.as8080.ast.expr.*; import net.emustudio.plugins.compiler.as8080.ast.instr.*; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; +import net.emustudio.plugins.compiler.as8080.exceptions.used.FatalError; public class NodeVisitor { protected NameSpace env; + protected void error(CompileError error) { + env.error(error); + } + + protected void fatalError(CompileError error) { + FatalError.now(error); + } + public void visit(Node node) { visitChildren(node); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java index b81a99057..427187cc8 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java @@ -37,4 +37,11 @@ public NameSpace env() { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected Node mkCopy() { + Program program = new Program(line, column, env); + program.setFileName(filename); + return program; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java index be4486bbe..a90117ac0 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java @@ -14,4 +14,9 @@ public DataDB(int line, int column) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected Node mkCopy() { + return new DataDB(line, column); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java index fe18fa4d2..c6bcbec6b 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java @@ -14,4 +14,9 @@ public DataDS(int line, int column) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected Node mkCopy() { + return new DataDS(line, column); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java index b6942edb6..be606c469 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java @@ -14,4 +14,9 @@ public DataDW(int line, int column) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected Node mkCopy() { + return new DataDW(line, column); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java index 46cad2826..7774a4e9d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java @@ -30,6 +30,11 @@ protected String toStringShallow() { return "DataPlainString('" + string + "')"; } + @Override + protected Node mkCopy() { + return new DataPlainString(line, column, string); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java index 4b6f75dff..222742f13 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java @@ -13,4 +13,9 @@ public ExprCurrentAddress(int line, int column) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected Node mkCopy() { + return new ExprCurrentAddress(line, column); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java index b4990b22d..df7030100 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java @@ -28,6 +28,11 @@ protected String toStringShallow() { return "ExprId(" + id + ")"; } + @Override + protected Node mkCopy() { + return new ExprId(line, column, id); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index fbb788723..18fe5c67c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -27,6 +27,11 @@ protected String toStringShallow() { return "ExprInfix(" + operation + ")"; } + @Override + protected Node mkCopy() { + return new ExprInfix(line, column, operation); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java index 29c42a96e..5f15c7a7d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java @@ -28,6 +28,11 @@ protected String toStringShallow() { return "ExprNumber(" + number + ")"; } + @Override + protected Node mkCopy() { + return new ExprNumber(line, column, number); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index 7fe36f879..579e20018 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -27,6 +27,11 @@ protected String toStringShallow() { return "ExprUnary(" + operation + ")"; } + @Override + protected Node mkCopy() { + return new ExprUnary(line, column, operation); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index 2cf5847a5..205822dbd 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -27,6 +27,11 @@ protected String toStringShallow() { return "InstrExpr(" + opcode + ")"; } + @Override + protected Node mkCopy() { + return new InstrExpr(line, column, opcode); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java index 60a38c24f..079eb71b7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java @@ -26,6 +26,11 @@ protected String toStringShallow() { return "InstrNoArgs(" + opcode + ")"; } + @Override + protected Node mkCopy() { + return new InstrNoArgs(line, column, opcode); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java index 672e8a188..7a96e3e5a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java @@ -28,6 +28,11 @@ protected String toStringShallow() { return "InstrReg(" + opcode + "," + reg +")"; } + @Override + protected Node mkCopy() { + return new InstrReg(line, column, opcode, reg); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java index 6cfb4df08..acbdf045d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java @@ -29,6 +29,11 @@ protected String toStringShallow() { return "InstrRegExpr(" + opcode + "," + reg +")"; } + @Override + protected Node mkCopy() { + return new InstrRegExpr(line, column, opcode, reg); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java index d5eb65bc0..7f157a7b5 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java @@ -28,6 +28,11 @@ protected String toStringShallow() { return "InstrRegPair(" + opcode + "," + regPair +")"; } + @Override + protected Node mkCopy() { + return new InstrRegPair(line, column, opcode, regPair); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java index 2d3d3ac28..428de2770 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java @@ -29,6 +29,11 @@ protected String toStringShallow() { return "InstrRegPairExpr(" + opcode + "," + regPair +")"; } + @Override + protected Node mkCopy() { + return new InstrRegPairExpr(line, column, opcode, regPair); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java index a17d1dc47..ad857755d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java @@ -30,6 +30,11 @@ protected String toStringShallow() { return "InstrRegReg(" + opcode + ","+ dstReg +","+ srcReg +")"; } + @Override + protected Node mkCopy() { + return new InstrRegReg(line, column, opcode, dstReg, srcReg); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java index a59a9319c..3d614778a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java @@ -29,6 +29,11 @@ protected String toStringShallow() { return "PseudoEqu(" + id + ")"; } + @Override + protected Node mkCopy() { + return new PseudoEqu(line, column, id); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java index ed6c2a3d3..adcc257ad 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java @@ -15,4 +15,9 @@ public PseudoIf(int line, int column) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected Node mkCopy() { + return new PseudoIf(line, column); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java index f8b07a056..2fa53a545 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java @@ -29,6 +29,11 @@ protected String toStringShallow() { return "PseudoInclude('" + filename + "')"; } + @Override + protected Node mkCopy() { + return new PseudoInclude(line, column, filename); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java index 881d2b37d..aa9b147e1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java @@ -29,6 +29,11 @@ protected String toStringShallow() { return "PseudoMacroCall(" + id + ")"; } + @Override + protected Node mkCopy() { + return new PseudoMacroCall(line, column, id); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java index 33b113bde..ce38e29de 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java @@ -43,4 +43,8 @@ public boolean equals(Object o) { public int hashCode() { return id != null ? id.hashCode() : 0; } + + public PseudoMacroDef mkCopy() { + return new PseudoMacroDef(line, column, id); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java index 2c67b35cf..d11bc6c40 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java @@ -14,4 +14,9 @@ public PseudoOrg(int line, int column) { public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + protected Node mkCopy() { + return new PseudoOrg(line, column); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java index 1dbe6a5a5..4dd7b180a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java @@ -29,6 +29,11 @@ protected String toStringShallow() { return "PseudoSet(" + id + ")"; } + @Override + protected Node mkCopy() { + return new PseudoSet(line, column, id); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InfiniteIncludeLoopException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InfiniteIncludeLoopException.java deleted file mode 100644 index b8945abfe..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InfiniteIncludeLoopException.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.exceptions; - -public class InfiniteIncludeLoopException extends CompileException { - private static final String MSG = "Infinite include loop detected"; - - public InfiniteIncludeLoopException(int line, int column) { - super(line, column, MSG); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDeclaredException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/AlreadyDeclaredException.java similarity index 65% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDeclaredException.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/AlreadyDeclaredException.java index ab05bdde0..c4c035c4d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDeclaredException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/AlreadyDeclaredException.java @@ -1,4 +1,6 @@ -package net.emustudio.plugins.compiler.as8080.exceptions; +package net.emustudio.plugins.compiler.as8080.exceptions.used; + +import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; public class AlreadyDeclaredException extends CompileException { private final static String MSG = " was already declared"; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CouldNotReadFileException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/CouldNotReadFileException.java similarity index 67% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CouldNotReadFileException.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/CouldNotReadFileException.java index 5324a9366..3d0183456 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/CouldNotReadFileException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/CouldNotReadFileException.java @@ -1,4 +1,6 @@ -package net.emustudio.plugins.compiler.as8080.exceptions; +package net.emustudio.plugins.compiler.as8080.exceptions.used; + +import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; public class CouldNotReadFileException extends CompileException { private final static String MSG = "Could not read file: "; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/FatalError.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/FatalError.java new file mode 100644 index 000000000..a7c3244c1 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/FatalError.java @@ -0,0 +1,19 @@ +package net.emustudio.plugins.compiler.as8080.exceptions.used; + +import net.emustudio.plugins.compiler.as8080.CompileError; +import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; + +public class FatalError extends CompileException { + + public FatalError(int line, int column, String why) { + super(line, column, "Fatal error (cannot continue): " + why); + } + + public static void now(int line, int column, String why) { + throw new FatalError(line, column, why); + } + + public static void now(CompileError error) { + now(error.line, error.column, error.msg); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/SyntaxErrorException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/SyntaxErrorException.java similarity index 69% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/SyntaxErrorException.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/SyntaxErrorException.java index 8d663b282..e4dd732bf 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/SyntaxErrorException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/SyntaxErrorException.java @@ -1,4 +1,6 @@ -package net.emustudio.plugins.compiler.as8080.exceptions; +package net.emustudio.plugins.compiler.as8080.exceptions.used; + +import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; public class SyntaxErrorException extends CompileException { public SyntaxErrorException(int line, int column, String message) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java index 09dd5a9cd..f020f13cd 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java @@ -6,9 +6,12 @@ import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoSet; -import net.emustudio.plugins.compiler.as8080.exceptions.AlreadyDeclaredException; -import java.util.*; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; + +import static net.emustudio.plugins.compiler.as8080.CompileError.alreadyDeclared; public class CheckDeclarationsVisitor extends NodeVisitor { private final Set declarations = new HashSet<>(); @@ -49,7 +52,7 @@ private void addDeclaration(String id, boolean isVariable, Node node) { String idLower = id.toLowerCase(Locale.ENGLISH); if (declarations.contains(idLower) && (!isVariable || !variables.contains(id))) { - throw new AlreadyDeclaredException(node.line, node.column, id); + error(alreadyDeclared(node, id)); } declarations.add(idLower); if (isVariable) { @@ -61,7 +64,7 @@ private void addMacro(String id, Node node) { String idLower = id.toLowerCase(Locale.ENGLISH); if (macros.contains(idLower)) { - throw new AlreadyDeclaredException(node.line, node.column, id); + error(alreadyDeclared(node, id)); } macros.add(idLower); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java index 4bff4824f..45f07c175 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java @@ -5,8 +5,6 @@ import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoInclude; -import net.emustudio.plugins.compiler.as8080.exceptions.CouldNotReadFileException; -import net.emustudio.plugins.compiler.as8080.exceptions.InfiniteIncludeLoopException; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; @@ -17,6 +15,9 @@ import java.util.Objects; import java.util.Set; +import static net.emustudio.plugins.compiler.as8080.CompileError.couldNotReadFile; +import static net.emustudio.plugins.compiler.as8080.CompileError.infiniteLoopDetected; + public class ExpandIncludesVisitor extends NodeVisitor { private final Set includedFiles; // TODO: windows platform case-insensitive! @@ -31,7 +32,7 @@ public ExpandIncludesVisitor(Set includedFiles) { @Override public void visit(PseudoInclude node) { if (includedFiles.contains(node.filename)) { - throw new InfiniteIncludeLoopException(node.line, node.column); + fatalError(infiniteLoopDetected(node, "include")); } try { @@ -47,15 +48,11 @@ public void visit(PseudoInclude node) { Set alreadyIncludedFiles = new HashSet<>(includedFiles); alreadyIncludedFiles.add(node.filename); - new ExpandIncludesVisitor(alreadyIncludedFiles).visit(program); - node.getParent().ifPresent(parent -> { - parent.removeChild(node); - parent.addChild(program); - }); + node.remove().ifPresent(parent -> parent.addChildren(program.getChildren())); // TODO: custom error space? } catch (IOException e) { - throw new CouldNotReadFileException(node.line, node.column, node.filename, e); + error(couldNotReadFile(node, node.filename, e)); } } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java new file mode 100644 index 000000000..7b74e5a2a --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java @@ -0,0 +1,78 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroCall; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; + +import java.util.*; + +import static net.emustudio.plugins.compiler.as8080.CompileError.infiniteLoopDetected; +import static net.emustudio.plugins.compiler.as8080.CompileError.notDefined; + +/** + * Expands macros. It means - find macro definitions, remove them from the parent node and put them as a child under + * each macro call. It supports forward references too. + * + * It doesn't mean the macro expansion will be used in code yet. + */ +public class ExpandMacrosVisitor extends NodeVisitor { + private final Map macros = new HashMap<>(); + private final Map> forwardMacroCalls = new HashMap<>(); + + @Override + public void visit(Program node) { + visitChildren(node); + for (Map.Entry> entry : forwardMacroCalls.entrySet()) { + error(notDefined(entry.getValue().get(0), "Macro '" + entry.getKey() + "'")); + } + } + + @Override + public void visit(PseudoMacroDef node) { + String id = node.id.toLowerCase(Locale.ENGLISH); + + // save macro + macros.put(id, node); + node.remove(); + + // expand macro if we had earlier calls (as a forward reference) + if (forwardMacroCalls.containsKey(id)) { + for (Node macroCall : forwardMacroCalls.get(id)) { + macroCall.addChild(node.copy()); + } + forwardMacroCalls.remove(id); + } + visitChildren(node); + } + + @Override + public void visit(PseudoMacroCall node) { + String id = node.id.toLowerCase(Locale.ENGLISH); + if (macros.containsKey(id)) { + node.addChild(macros.get(id).copy()); + } else { + // maybe the macro is defined later + forwardMacroCalls.putIfAbsent(id, new ArrayList<>()); + List macroCalls = forwardMacroCalls.get(id); + macroCalls.add(node); + } + checkInfiniteLoop(node); + } + + private void checkInfiniteLoop(PseudoMacroCall node) { + String id = node.id.toLowerCase(Locale.ENGLISH); + Optional parent = node.getParent(); + while (parent.isPresent()) { + Node parentValue = parent.get(); + if (parentValue instanceof PseudoMacroDef) { + String parentId = ((PseudoMacroDef) parentValue).id.toLowerCase(Locale.ENGLISH); + if (parentId.equals(id)) { + fatalError(infiniteLoopDetected(node, "macro call '" + id + "'")); + } + } + parent = parent.get().getParent(); + } + } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java index 6f7abcfdf..a2d7fe4d5 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java @@ -9,7 +9,7 @@ import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; -import net.emustudio.plugins.compiler.as8080.exceptions.SyntaxErrorException; +import net.emustudio.plugins.compiler.as8080.exceptions.used.SyntaxErrorException; import org.junit.Test; import java.util.List; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java index dfca49357..fb6d13025 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -9,6 +9,10 @@ import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.ParseTree; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -122,4 +126,10 @@ public static void assertTrees(Node expected, Node result) { assertTrees(expectedChild, resultChild); } } + + public static void write(File file, String content) throws IOException { + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + writer.write(content); + writer.close(); + } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java index 5cf1b676a..d9db578d3 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java @@ -1,10 +1,11 @@ package net.emustudio.plugins.compiler.as8080.visitors; import net.emustudio.plugins.compiler.as8080.ast.Program; -import net.emustudio.plugins.compiler.as8080.exceptions.AlreadyDeclaredException; import org.junit.Test; +import static net.emustudio.plugins.compiler.as8080.CompileError.ERROR_ALREADY_DECLARED; import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; +import static org.junit.Assert.assertTrue; public class CheckDeclarationsVisitorTest { @@ -22,18 +23,20 @@ public void testVariableTwoTimesPass() { visitor.visit(program); } - @Test(expected = AlreadyDeclaredException.class) + @Test public void testConstantTwoTimesCannotBeDefined() { Program program = parseProgram("var equ 1\nvar equ 2"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); } - @Test(expected = AlreadyDeclaredException.class) + @Test public void testVarCannotBeDefinedIfAnotherDeclarationExists() { Program program = parseProgram("var equ 1\nvar set 2"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); } @Test @@ -43,17 +46,19 @@ public void testMacrosAndDeclarationsAreIndependent() { visitor.visit(program); } - @Test(expected = AlreadyDeclaredException.class) + @Test public void testLabelThenConstantAlreadyDeclared() { Program program = parseProgram("label:\nlabel equ 1"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); } - @Test(expected = AlreadyDeclaredException.class) + @Test public void testMacroAlreadyDeclared() { Program program = parseProgram("label macro\nendm\nlabel macro\nendm"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java index ea49d7147..068d771e5 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java @@ -6,20 +6,18 @@ import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; -import net.emustudio.plugins.compiler.as8080.exceptions.CouldNotReadFileException; -import net.emustudio.plugins.compiler.as8080.exceptions.InfiniteIncludeLoopException; +import net.emustudio.plugins.compiler.as8080.exceptions.used.FatalError; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import java.io.BufferedWriter; import java.io.File; -import java.io.FileWriter; import java.io.IOException; import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; -import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; -import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; +import static net.emustudio.plugins.compiler.as8080.CompileError.ERROR_CANNOT_READ_FILE; +import static net.emustudio.plugins.compiler.as8080.Utils.*; +import static org.junit.Assert.assertTrue; public class ExpandIncludesVisitorTest { @Rule @@ -34,12 +32,10 @@ public void testExpandInclude() { Node expected = new Program() .addChild(new InstrNoArgs(0, 0, OPCODE_CMC)) - .addChild(new Program() - .addChild(new Label(0, 0, "sample") - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new ExprNumber(0, 0, 0)))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RET)) - ); + .addChild(new Label(0, 0, "sample") + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RET)); assertTrees(expected, program); } @@ -51,28 +47,27 @@ public void testExpandIncludeTwoTimes() throws IOException { Program program = parseProgram( "include '" + file.getPath() + "'\n" + - "include '" + file.getPath() +"'" + "include '" + file.getPath() + "'" ); ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); visitor.visit(program); Node expected = new Program() - .addChild(new Program() - .addChild(new InstrNoArgs(0, 0, OPCODE_RRC))) - .addChild(new Program() - .addChild(new InstrNoArgs(0, 0, OPCODE_RRC))); + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)); assertTrees(expected, program); } - @Test(expected = CouldNotReadFileException.class) + @Test public void testNonExistingFileThrows() { Program program = parseProgram("cmc\ninclude 'non-existant.asm'"); ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); visitor.visit(program); + assertTrue(program.env().hasError(ERROR_CANNOT_READ_FILE)); } - @Test(expected = InfiniteIncludeLoopException.class) + @Test(expected = FatalError.class) public void testIndefiniteLoopDetected() throws IOException { File fileA = folder.newFile("file-a.asm"); File fileB = folder.newFile("file-b.asm"); @@ -84,10 +79,4 @@ public void testIndefiniteLoopDetected() throws IOException { ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); visitor.visit(program); } - - private void write(File file, String content) throws IOException { - BufferedWriter writer = new BufferedWriter(new FileWriter(file)); - writer.write(content); - writer.close(); - } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java new file mode 100644 index 000000000..101fba740 --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java @@ -0,0 +1,106 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroCall; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; +import net.emustudio.plugins.compiler.as8080.exceptions.used.FatalError; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; + +import static net.emustudio.plugins.compiler.as8080.Utils.*; + +public class ExpandMacrosTest { + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void testMacroDefinitionThenMacroCall() { + Program program = parseProgram("x macro\nendm\nx"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program + ); + } + + @Test + public void testMacroCallThenMacroDefinition() { + Program program = parseProgram("x\nx macro\nendm"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program + ); + } + + @Test + public void testMacroCallThenMacroDefinitionThenMacroCall() { + Program program = parseProgram("x\nx macro\nendm\nx"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program + ); + } + + @Test + public void testMacroCallThenMacroDefinitionInsideInclude() throws IOException { + File file = folder.newFile("file.asm"); + write(file, "x macro\nendm"); + + Program program = parseProgram("x\ninclude '" + file.getPath() + "'"); + ExpandIncludesVisitor includesVisitor = new ExpandIncludesVisitor(); + includesVisitor.visit(program); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program + ); + } + + @Test(expected = FatalError.class) + public void testTheSameMacroCallInsideMacroDefinition() { + Program program = parseProgram("x macro\nx\nendm"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + } + + @Test + public void testMacroCallWithArguments() { + Program program = parseProgram("x 1,2,3\nx macro q,r,t\nendm"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3)) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprId(0, 0, "t")))), + program + ); + } +} From 8fe436408332859e96c7e6e07b9cbe7d1c6bfba1 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 19 Dec 2021 21:54:30 +0100 Subject: [PATCH 057/314] [#201] as-8080: fix declarations visitor --- .../plugins/compiler/as8080/CompileError.java | 10 +++ .../compiler/as8080/ast/NameSpace.java | 11 ++++ .../plugins/compiler/as8080/ast/Node.java | 5 +- .../compiler/as8080/ast/NodeVisitor.java | 8 +++ .../ast/pseudo/PseudoMacroArgument.java | 25 +++++++ .../ast/pseudo/PseudoMacroParameter.java | 26 ++++++++ .../visitors/CheckDeclarationsVisitor.java | 66 +++++++++++++++++-- .../as8080/visitors/CreatePseudoVisitor.java | 7 +- .../compiler/as8080/ParsePseudoTest.java | 12 ++-- .../CheckDeclarationsVisitorTest.java | 64 ++++++++++++++++++ .../as8080/visitors/ExpandMacrosTest.java | 20 ++++-- 11 files changed, 231 insertions(+), 23 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java index 3adeab47c..4ac659d24 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java @@ -43,4 +43,14 @@ public static CompileError couldNotReadFile(Node node, String filename, IOExcept public static CompileError notDefined(Node node, String what) { return new CompileError(node, ERROR_NOT_DEFINED, "Not defined: " + what); } + + @Override + public String toString() { + return "CompileError{" + + "line=" + line + + ", column=" + column + + ", msg='" + msg + '\'' + + ", errorCode=" + errorCode + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java index 02b26ef6c..e40605ded 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java @@ -14,4 +14,15 @@ public void error(CompileError error) { public boolean hasError(int errorCode) { return errors.stream().anyMatch(e -> e.errorCode == errorCode); } + + public boolean hasNoErrors() { + return errors.isEmpty(); + } + + @Override + public String toString() { + return "NameSpace{" + + "errors=" + errors + + '}'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 19ca3e60c..528165c5b 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -62,11 +62,8 @@ private String toString(int indent) { String spaces = new String(new char[indent]).replace("\0", " "); StringBuilder builder = new StringBuilder(spaces); builder.append(toStringShallow()); - if (!children.isEmpty()) { - builder.append("\n"); - } for (Node child : children) { - builder.append(child.toString(indent + 2)); + builder.append("\n").append(child.toString(indent + 2)); } return builder.toString(); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java index e349d56f1..1ae873612 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java @@ -112,6 +112,14 @@ public void visit(PseudoMacroCall node) { visitChildren(node); } + public void visit(PseudoMacroArgument node) { + visitChildren(node); + } + + public void visit(PseudoMacroParameter node) { + visitChildren(node); + } + public void visit(PseudoMacroDef node) { visitChildren(node); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java new file mode 100644 index 000000000..e975b4e0c --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; + +/** + * Macro call arguments are passed when macro is called. + */ +public class PseudoMacroArgument extends Node { + + public PseudoMacroArgument() { + super(0, 0); + // the only child is expr + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new PseudoMacroArgument(); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java new file mode 100644 index 000000000..56f957b4d --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java @@ -0,0 +1,26 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + + +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; + +/** + * Macro definition parameter + */ +public class PseudoMacroParameter extends Node { + + public PseudoMacroParameter() { + super(0, 0); + // the only child is ExprId + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new PseudoMacroParameter(); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java index f020f13cd..1d3abf9b1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java @@ -3,21 +3,39 @@ import net.emustudio.plugins.compiler.as8080.ast.Label; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroParameter; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoSet; -import java.util.HashSet; -import java.util.Locale; -import java.util.Set; +import java.util.*; import static net.emustudio.plugins.compiler.as8080.CompileError.alreadyDeclared; +/** + * Checks if all declarations are valid: + * - ID of constant,variable and macro can be used just once in whole program. + * - macro parameters should not conflict with: + * - declarations in and out of the macro scope + * - previously declared parameters in current or parent macros if the current one is nested + */ public class CheckDeclarationsVisitor extends NodeVisitor { - private final Set declarations = new HashSet<>(); + private final Set allDeclarations = new HashSet<>(); private final Set macros = new HashSet<>(); private final Set variables = new HashSet<>(); + // for checking collisions with other declarations (e.g. forward referenced labels) + private final Set allMacroParams = new HashSet<>(); + + // for checking marco param names in nested macros + private final List> macroParamsInScope = new ArrayList<>(); + + // for easier removal of current macro params from macroParamsInScope when the macro definition ends + private Set currentMacroParams; + + private boolean insideMacroParameter = false; + @Override public void visit(PseudoEqu node) { addDeclaration(node.id, node); @@ -26,7 +44,10 @@ public void visit(PseudoEqu node) { @Override public void visit(PseudoMacroDef node) { addMacro(node.id, node); + currentMacroParams = new HashSet<>(); + macroParamsInScope.add(currentMacroParams); visitChildren(node); + macroParamsInScope.remove(macroParamsInScope.size() - 1); } @Override @@ -40,6 +61,20 @@ public void visit(Label node) { visitChildren(node); } + @Override + public void visit(PseudoMacroParameter node) { + insideMacroParameter = true; + visitChildren(node); + insideMacroParameter = false; + } + + @Override + public void visit(ExprId node) { + if (insideMacroParameter) { + addMacroParameter(node.id, node); + } + } + private void addVariable(String id, Node node) { addDeclaration(id, true, node); } @@ -51,10 +86,10 @@ private void addDeclaration(String id, Node node) { private void addDeclaration(String id, boolean isVariable, Node node) { String idLower = id.toLowerCase(Locale.ENGLISH); - if (declarations.contains(idLower) && (!isVariable || !variables.contains(id))) { + if (allMacroParams.contains(idLower) || buildDeclarations().contains(idLower) && (!isVariable || !variables.contains(id))) { error(alreadyDeclared(node, id)); } - declarations.add(idLower); + allDeclarations.add(idLower); if (isVariable) { variables.add(idLower); } @@ -62,10 +97,27 @@ private void addDeclaration(String id, boolean isVariable, Node node) { private void addMacro(String id, Node node) { String idLower = id.toLowerCase(Locale.ENGLISH); - if (macros.contains(idLower)) { error(alreadyDeclared(node, id)); } macros.add(idLower); } + + private void addMacroParameter(String id, Node node) { + String idLower = id.toLowerCase(Locale.ENGLISH); + if (buildDeclarations().contains(idLower) || macros.contains(idLower)) { + error(alreadyDeclared(node, id)); + } + currentMacroParams.add(idLower); + allMacroParams.add(idLower); + } + + private Set buildDeclarations() { + Set allDeclarations = new HashSet<>(); + for (Set parameters : macroParamsInScope) { + allDeclarations.addAll(parameters); + } + allDeclarations.addAll(this.allDeclarations); + return allDeclarations; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java index 06bdb707b..c7b707946 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java @@ -50,7 +50,9 @@ public Node visitPseudoMacroDef(PseudoMacroDefContext ctx) { if (ctx.params != null) { for (TerminalNode next : ctx.params.ID_IDENTIFIER()) { - pseudo.addChild(new ExprId(next.getSymbol())); + PseudoMacroParameter parameter = new PseudoMacroParameter(); + parameter.addChild(new ExprId(next.getSymbol())); + pseudo.addChild(parameter); } } for (RLineContext line : ctx.rLine()) { @@ -65,7 +67,8 @@ public Node visitPseudoMacroCall(PseudoMacroCallContext ctx) { if (ctx.args != null) { for (RExpressionContext next : ctx.args.rExpression()) { - pseudo.addChild(Visitors.expr.visit(next)); + PseudoMacroArgument argument = new PseudoMacroArgument(); + pseudo.addChild(argument.addChild(Visitors.expr.visit(next))); } } return pseudo; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java index a2d7fe4d5..143df220b 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java @@ -124,8 +124,10 @@ public void testMacroDef() { Node expected = new Program() .addChild(new PseudoMacroDef(0, 0, "shrt") - .addChild(new ExprId(0, 0, "param1")) - .addChild(new ExprId(0, 0, "param2")) + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "param1"))) + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "param2"))) .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) .addChild(new Label(0, 0, "heylabel") .addChild(new InstrExpr(0, 0, OPCODE_ANI) @@ -167,8 +169,10 @@ public void testMacroCallWithParams() { Node expected = new Program() .addChild(new PseudoMacroCall(0, 0, "shrt") - .addChild(new ExprId(0, 0, "param1")) - .addChild(new ExprNumber(0, 0, 45))); + .addChild(new PseudoMacroArgument() + .addChild(new ExprId(0, 0, "param1"))) + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 45)))); assertTrees(expected, program); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java index d9db578d3..91d8da8d3 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java @@ -61,4 +61,68 @@ public void testMacroAlreadyDeclared() { visitor.visit(program); assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); } + + @Test + public void testMacroParametersCollideWithLabel() { + Program program = parseProgram("label: x macro label\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroParametersCollideWithConstant() { + Program program = parseProgram("const equ 1\nx macro const\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroParametersCollideWithVariable() { + Program program = parseProgram("variable set 1\nx macro variable\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroParametersCollideParentMacroParameters() { + Program program = parseProgram("x macro f,g,n\ny macro p,g,o\nendm\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroParametersAfterMacroEndStillCollideWithLabel() { + Program program = parseProgram("x macro tt\nendm\ntt:"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroParametersCollideWithConstantInsideMacro() { + Program program = parseProgram("x macro tt\ntt equ 1\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroNameCollidesWithParameterName() { + Program program = parseProgram("x macro x\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroReuseParameterNamesIsPossible() { + Program program = parseProgram("x macro t\nendm\ny macro t\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasNoErrors()); + } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java index 101fba740..b99e65118 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java @@ -3,8 +3,10 @@ import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroArgument; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroCall; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroParameter; import net.emustudio.plugins.compiler.as8080.exceptions.used.FatalError; import org.junit.Rule; import org.junit.Test; @@ -93,13 +95,19 @@ public void testMacroCallWithArguments() { assertTrees(new Program() .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new ExprNumber(0, 0, 1)) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3)) + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 3))) .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new ExprId(0, 0, "q")) - .addChild(new ExprId(0, 0, "r")) - .addChild(new ExprId(0, 0, "t")))), + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "r"))) + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "t"))))), program ); } From 742935d512884b2d6fa322a62b785875cd2d042a Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 20 Dec 2021 07:18:36 +0100 Subject: [PATCH 058/314] [#201] as-8080: integrate macros visitor --- .../compiler/as8080/Assembler8080.java | 8 +-- .../visitors/IntegrateMacrosVisitor.java | 66 +++++++++++++++++++ .../visitors/IntegrateMacrosVisitorTest.java | 54 +++++++++++++++ 3 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitor.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitorTest.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index 2b515541c..748f79450 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -32,10 +32,7 @@ import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; -import net.emustudio.plugins.compiler.as8080.visitors.CreateProgramVisitor; -import net.emustudio.plugins.compiler.as8080.visitors.ExpandIncludesVisitor; -import net.emustudio.plugins.compiler.as8080.visitors.CheckDeclarationsVisitor; -import net.emustudio.plugins.compiler.as8080.visitors.ExpandMacrosVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.*; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; @@ -125,7 +122,8 @@ public boolean compile(String inputFileName, String outputFileName) { NodeVisitor[] visitors = new NodeVisitor[] { new ExpandIncludesVisitor(), new CheckDeclarationsVisitor(), - new ExpandMacrosVisitor() + new ExpandMacrosVisitor(), + new IntegrateMacrosVisitor() }; for (NodeVisitor visitor : visitors) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitor.java new file mode 100644 index 000000000..65a33d9ac --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitor.java @@ -0,0 +1,66 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroArgument; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroCall; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroParameter; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** + * Replaces ExprIds inside macro definition with macro arguments, and removes PseudoMacroCall + PseudoMacroDef. + * Macro expansions disappear and just code remains. + */ +public class IntegrateMacrosVisitor extends NodeVisitor { + private final List macroParameters = new ArrayList<>(); + private final List macroArguments = new ArrayList<>(); + + private boolean insideMacroParameter; + private boolean insideMacroDef; + + @Override + public void visit(ExprId node) { + String id = node.id.toLowerCase(Locale.ENGLISH); + + if (insideMacroParameter) { + macroParameters.add(id); + } else if (insideMacroDef) { + int index = macroParameters.indexOf(id); + Node argument = macroArguments.get(index); + node.remove().ifPresent(p -> p.addChild(argument)); + } + } + + @Override + public void visit(PseudoMacroArgument node) { + macroArguments.add(node.getChild(0)); + node.remove(); + } + + @Override + public void visit(PseudoMacroParameter node) { + insideMacroParameter = true; + visitChildren(node); + node.remove(); + insideMacroParameter = false; + } + + @Override + public void visit(PseudoMacroDef node) { + insideMacroDef = true; + visitChildren(node); + node.remove().ifPresent(p -> p.addChildren(node.getChildren())); + insideMacroDef = false; + } + + @Override + public void visit(PseudoMacroCall node) { + visitChildren(node); + node.remove().ifPresent(p -> p.addChildren(node.getChildren())); + } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitorTest.java new file mode 100644 index 000000000..e8f914143 --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitorTest.java @@ -0,0 +1,54 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; +import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; + +public class IntegrateMacrosVisitorTest { + + @Test + public void testMacroArgumentsAreExpanded() { + Node program = new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "r"))) + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "t"))) + .addChild(new InstrRegExpr(0,0,OPCODE_MVI, REG_A) + .addChild(new ExprId(0,0,"q"))) + .addChild(new PseudoEqu(0,0,"uu") + .addChild(new ExprInfix(0,0, OP_ADD) + .addChild(new ExprId(0,0,"r")) + .addChild(new ExprId(0,0,"t")))))); + + IntegrateMacrosVisitor visitor = new IntegrateMacrosVisitor(); + visitor.visit(program); + + assertTrees(new Program() + .addChild(new InstrRegExpr(0,0,OPCODE_MVI, REG_A) + .addChild(new ExprNumber(0,0,1))) + .addChild(new PseudoEqu(0,0, "uu") + .addChild(new ExprInfix(0,0,OP_ADD) + .addChild(new ExprNumber(0,0,2)) + .addChild(new ExprNumber(0,0,3)))), + program + ); + } +} From 5c3513e86dca03b9f28401525359c288e9505761 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 28 Dec 2021 08:51:42 +0100 Subject: [PATCH 059/314] [#201] as-8080: EvaluateExprVisitor --- .../as-8080/src/main/antlr/As8080Parser.g4 | 1 + .../compiler/as8080/Assembler8080.java | 6 +- .../plugins/compiler/as8080/CompileError.java | 20 ++ .../plugins/compiler/as8080/Either.java | 37 +++ .../{CommonParsers.java => ParsingUtils.java} | 6 +- .../compiler/as8080/ast/Evaluated.java | 46 ++++ .../plugins/compiler/as8080/ast/Label.java | 49 ---- .../compiler/as8080/ast/NameSpace.java | 15 + .../compiler/as8080/ast/NeedMorePass.java | 18 ++ .../plugins/compiler/as8080/ast/Node.java | 36 +++ .../compiler/as8080/ast/NodeVisitor.java | 19 +- .../compiler/as8080/ast/data/DataDS.java | 6 +- .../compiler/as8080/ast/data/DataDW.java | 2 +- .../as8080/ast/data/DataPlainString.java | 17 +- .../as8080/ast/expr/ExprCurrentAddress.java | 20 +- .../compiler/as8080/ast/expr/ExprId.java | 15 +- .../compiler/as8080/ast/expr/ExprInfix.java | 69 ++++- .../compiler/as8080/ast/expr/ExprNumber.java | 11 +- .../compiler/as8080/ast/expr/ExprUnary.java | 49 +++- .../compiler/as8080/ast/instr/InstrExpr.java | 28 ++ .../as8080/ast/pseudo/PseudoInclude.java | 4 +- .../as8080/ast/pseudo/PseudoLabel.java | 68 +++++ .../visitors/CheckDeclarationsVisitor.java | 73 ++++- .../as8080/visitors/CreateDataVisitor.java | 3 +- .../as8080/visitors/CreateExprVisitor.java | 12 +- .../as8080/visitors/CreateLineVisitor.java | 4 +- .../as8080/visitors/EvaluateExprVisitor.java | 257 ++++++++++++++++++ .../visitors/ExpandIncludesVisitor.java | 3 + .../as8080/visitors/ExpandMacrosVisitor.java | 9 +- .../visitors/IntegrateMacrosVisitor.java | 66 ----- .../visitors/SortMacroArgumentsVisitor.java | 99 +++++++ .../compiler/as8080/ParsePseudoTest.java | 8 +- ...ParsersTest.java => ParsingUtilsTest.java} | 34 +-- .../plugins/compiler/as8080/Utils.java | 1 + .../CheckDeclarationsVisitorTest.java | 51 +++- .../visitors/EvaluateExprVisitorTest.java | 6 + .../visitors/ExpandIncludesVisitorTest.java | 4 +- .../as8080/visitors/ExpandMacrosTest.java | 7 + .../visitors/IntegrateMacrosVisitorTest.java | 54 ---- .../SortMacroArgumentsVisitorTest.java | 169 ++++++++++++ 40 files changed, 1148 insertions(+), 254 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Either.java rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/{CommonParsers.java => ParsingUtils.java} (98%) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NeedMorePass.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitor.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{CommonParsersTest.java => ParsingUtilsTest.java} (62%) create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java delete mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitorTest.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index 36229d5f9..4affb5606 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -159,6 +159,7 @@ rExpression: | unaryop=(OP_ADD|OP_SUBTRACT) expr=rExpression # exprUnary | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD|OP_SHL|OP_SHR) expr2=rExpression # exprInfix | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression # exprInfix + | expr1=rExpression op=OP_EQUAL expr2=rExpression # exprInfix | unaryop=OP_NOT expr=rExpression # exprUnary | expr1=rExpression op=OP_AND expr2=rExpression # exprInfix | expr1=rExpression op=(OP_OR|OP_XOR) expr2=rExpression # exprInfix diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index 748f79450..abab55bfe 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -123,7 +123,11 @@ public boolean compile(String inputFileName, String outputFileName) { new ExpandIncludesVisitor(), new CheckDeclarationsVisitor(), new ExpandMacrosVisitor(), - new IntegrateMacrosVisitor() + new SortMacroArgumentsVisitor(), + // macro expansion could bring re-definition of declarations, but we cannot check declarations again + // until the macro is properly integrated (b/c we could see multiple macro defs on multiple calls) + new CheckDeclarationsVisitor(), + new EvaluateExprVisitor() }; for (NodeVisitor visitor : visitors) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java index 4ac659d24..3ec113a1e 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java @@ -10,6 +10,10 @@ public class CompileError { public static final int ERROR_INFINITE_LOOP_DETECTED = 2; public static final int ERROR_CANNOT_READ_FILE = 3; public static final int ERROR_NOT_DEFINED = 4; + public static final int ERROR_AMBIGUOUS_EXPRESSION = 5; + public static final int ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK = 6; + public static final int ERROR_DECLARATION_REFERENCES_ITSELF = 7; + public static final int ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH = 8; public final int line; public final int column; @@ -44,6 +48,22 @@ public static CompileError notDefined(Node node, String what) { return new CompileError(node, ERROR_NOT_DEFINED, "Not defined: " + what); } + public static CompileError ambiguousExpression(Node node) { + return new CompileError(node, ERROR_AMBIGUOUS_EXPRESSION, "Ambiguous expression"); + } + + public static CompileError ifExpressionReferencesOwnBlock(Node node) { + return new CompileError(node, ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK, "If expression references declaration in its own block"); + } + + public static CompileError declarationReferencesItself(Node node) { + return new CompileError(node, ERROR_DECLARATION_REFERENCES_ITSELF, "Declaration references itself"); + } + + public static CompileError macroArgumentsDoNotMatch(Node node) { + return new CompileError(node, ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH, "Macro call arguments do not match with defined parameters"); + } + @Override public String toString() { return "CompileError{" + diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Either.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Either.java new file mode 100644 index 000000000..36f179016 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Either.java @@ -0,0 +1,37 @@ +package net.emustudio.plugins.compiler.as8080; + +import java.util.Optional; + +public class Either { + public final L left; + public final R right; + + private Either(L left, R right) { + this.left = left; + this.right = right; + } + + public Optional left() { + return Optional.ofNullable(left); + } + + public Optional right() { + return Optional.ofNullable(right); + } + + public boolean isLeft() { + return left != null; + } + + public boolean isRight() { + return right != null; + } + + public static Either ofLeft(L left) { + return new Either<>(left, (R) null); + } + + public static Either ofRight(R right) { + return new Either<>((L) null, right); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParsingUtils.java similarity index 98% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParsingUtils.java index 029f26c08..6e7fd102d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CommonParsers.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParsingUtils.java @@ -5,7 +5,7 @@ import java.util.Locale; -public class CommonParsers { +public class ParsingUtils { public static String parseLitString(Token token) { // LIT_STRING_1: '\'' ~[']* '\''; @@ -248,4 +248,8 @@ public static String parseLabel(Token token) { String rawText = token.getText(); return rawText.substring(0, rawText.length() - 1); } + + public static String normalizeId(String id) { + return id.toLowerCase(Locale.ENGLISH); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java new file mode 100644 index 000000000..70b2a83ee --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java @@ -0,0 +1,46 @@ +package net.emustudio.plugins.compiler.as8080.ast; + +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; + +import java.util.Objects; + +public class Evaluated extends Node { + public final int address; + public final int sizeBytes; + + public Evaluated(int line, int column, int address, int sizeBytes) { + super(line, column); + this.address = address; + this.sizeBytes = sizeBytes; + + // children are sizeBytes * 1-byte ExprNumbers + } + + public int getValue() { + return ((ExprNumber) getChild(0)).number; + } + + @Override + protected Node mkCopy() { + return new Evaluated(line, column, address, sizeBytes); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + Evaluated evaluated = (Evaluated) o; + return address == evaluated.address && sizeBytes == evaluated.sizeBytes; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), address, sizeBytes); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java deleted file mode 100644 index 63bce9a94..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Label.java +++ /dev/null @@ -1,49 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast; - -import org.antlr.v4.runtime.Token; - -import java.util.Objects; - -import static net.emustudio.plugins.compiler.as8080.CommonParsers.parseLabel; - -public class Label extends Node { - public final String label; - - public Label(int line, int column, String label) { - super(line, column); - this.label = Objects.requireNonNull(label); - } - - public Label(Token label) { - this(label.getLine(), label.getCharPositionInLine(), parseLabel(label)); - } - - @Override - public void accept(NodeVisitor visitor) { - visitor.visit(this); - } - - @Override - protected String toStringShallow() { - return "Label(" + label +")"; - } - - @Override - protected Node mkCopy() { - return new Label(line, column, label); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Label label1 = (Label) o; - return Objects.equals(label, label1.label); - } - - @Override - public int hashCode() { - return label != null ? label.hashCode() : 0; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java index e40605ded..25246261b 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java @@ -1,11 +1,13 @@ package net.emustudio.plugins.compiler.as8080.ast; import net.emustudio.plugins.compiler.as8080.CompileError; +import net.emustudio.plugins.compiler.as8080.Either; import java.util.*; public class NameSpace { private final List errors = new ArrayList<>(); + private final Map> definitions = new HashMap<>(); public void error(CompileError error) { errors.add(Objects.requireNonNull(error)); @@ -19,6 +21,19 @@ public boolean hasNoErrors() { return errors.isEmpty(); } + public void put(String id, Either value) { + definitions.put(id, value); + } + + public void remove(String id) { + definitions.remove(id); + } + + public Optional> get(String id) { + return Optional.ofNullable(definitions.get(id)); + } + + @Override public String toString() { return "NameSpace{" + diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NeedMorePass.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NeedMorePass.java new file mode 100644 index 000000000..cae4c5d6c --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NeedMorePass.java @@ -0,0 +1,18 @@ +package net.emustudio.plugins.compiler.as8080.ast; + +public class NeedMorePass extends Node { + + public NeedMorePass(int line, int column) { + super(line, column); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new NeedMorePass(line, column); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 528165c5b..7f5fe6c57 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -1,5 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast; +import net.emustudio.plugins.compiler.as8080.Either; + import java.util.*; public abstract class Node { @@ -13,6 +15,12 @@ public Node(int line, int column) { this.column = column; } + public Node addChildFirst(Node node) { + node.parent = this; + children.add(0, node); + return this; + } + public Node addChild(Node node) { node.parent = this; children.add(node); @@ -30,6 +38,15 @@ public List getChildren() { return List.copyOf(children); } + public Optional collectChild(Class cl) { + for (Node child : children) { + if (cl.isInstance(child)) { + return Optional.of((T) child); + } + } + return Optional.empty(); + } + public Optional getParent() { return Optional.ofNullable(parent); } @@ -49,6 +66,12 @@ public Optional remove() { return parent; } + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + NeedMorePass needMorePass = new NeedMorePass(line, column); + needMorePass.addChild(this); + return Either.ofLeft(needMorePass); + } + public void accept(NodeVisitor visitor) { visitor.visit(this); } @@ -81,4 +104,17 @@ public Node copy() { } return copied; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Node node = (Node) o; + return line == node.line && column == node.column && Objects.equals(parent, node.parent); + } + + @Override + public int hashCode() { + return Objects.hash(parent, line, column); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java index 1ae873612..a78a67293 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java @@ -10,6 +10,8 @@ import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; import net.emustudio.plugins.compiler.as8080.exceptions.used.FatalError; +import java.util.List; + public class NodeVisitor { protected NameSpace env; @@ -132,7 +134,15 @@ public void visit(PseudoSet node) { visitChildren(node); } - public void visit(Label node) { + public void visit(PseudoLabel node) { + visitChildren(node); + } + + public void visit(Evaluated node) { + visitChildren(node); + } + + public void visit(NeedMorePass node) { visitChildren(node); } @@ -141,4 +151,11 @@ protected void visitChildren(Node node) { child.accept(this); } } + + protected void visitChildren(Node node, int skipFirstN) { + List children = node.getChildren(); + for (int i = skipFirstN; i < children.size(); i++) { + children.get(i).accept(this); + } + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java index c6bcbec6b..6a0f87726 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java @@ -3,11 +3,13 @@ import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +/** + * "Data Store" node. Inserts some space. + * Child is an expression which must not use forward references and must not be negative. + */ public class DataDS extends Node { public DataDS(int line, int column) { super(line, column); - // child is expr - // expr cannot be negative } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java index be606c469..64b6b292f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java @@ -7,7 +7,7 @@ public class DataDW extends Node { public DataDW(int line, int column) { super(line, column); - // child is expr + // child is expr 2 byte } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java index 7774a4e9d..98adb5f50 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java @@ -1,12 +1,13 @@ package net.emustudio.plugins.compiler.as8080.ast.data; -import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.Either; +import net.emustudio.plugins.compiler.as8080.ast.*; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import org.antlr.v4.runtime.Token; import java.util.Objects; -import static net.emustudio.plugins.compiler.as8080.CommonParsers.parseLitString; +import static net.emustudio.plugins.compiler.as8080.ParsingUtils.parseLitString; public class DataPlainString extends Node { public final String string; @@ -20,6 +21,16 @@ public DataPlainString(Token string) { this(string.getLine(), string.getCharPositionInLine(), parseLitString(string)); } + @Override + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + int sizeBytes = string.length(); + Evaluated evaluated = new Evaluated(line, column, currentAddress, sizeBytes); + for (byte b : string.getBytes()) { + evaluated.addChild(new ExprNumber(line, column, b)); + } + return Either.ofRight(evaluated); + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java index 222742f13..e9f24e18f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.Either; +import net.emustudio.plugins.compiler.as8080.ast.*; public class ExprCurrentAddress extends Node { @@ -18,4 +18,20 @@ public void accept(NodeVisitor visitor) { protected Node mkCopy() { return new ExprCurrentAddress(line, column); } + + @Override + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); + evaluated.addChild(new ExprNumber(line, column, currentAddress)); + return Either.ofRight(evaluated); + } + + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env, boolean evalLeft) { + if (evalLeft) { + NeedMorePass needMorePass = new NeedMorePass(line, column); + needMorePass.addChild(this); + return Either.ofLeft(needMorePass); + } + return eval(currentAddress, expectedSizeBytes, env); + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java index df7030100..8a3baeb4d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java @@ -1,11 +1,13 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.Either; +import net.emustudio.plugins.compiler.as8080.ast.*; import org.antlr.v4.runtime.Token; import java.util.Objects; +import static net.emustudio.plugins.compiler.as8080.ParsingUtils.normalizeId; + public class ExprId extends Node { public final String id; @@ -18,6 +20,15 @@ public ExprId(Token id) { this(id.getLine(), id.getCharPositionInLine(), id.getText()); } + @Override + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + return env.get(normalizeId(id)).orElseGet(() -> { + NeedMorePass needMorePass = new NeedMorePass(line, column); + needMorePass.addChild(this); + return Either.ofLeft(needMorePass); + }); + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index 18fe5c67c..de3da6cdd 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -1,15 +1,41 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.Either; +import net.emustudio.plugins.compiler.as8080.ast.*; import org.antlr.v4.runtime.Token; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.BiFunction; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; + public class ExprInfix extends Node { - public final int operation; + private final static Map> infixOps = new HashMap<>(); + private final BiFunction operation; + public final int operationCode; + + static { + infixOps.putAll(Map.of( + OP_ADD, Integer::sum, + OP_SUBTRACT, (x, y) -> x - y, + OP_DIVIDE, (x, y) -> x / y, // can throw! + OP_MULTIPLY, (x, y) -> x * y, + OP_MOD, (x, y) -> x % y, + OP_AND, (x, y) -> x & y, + OP_OR, (x, y) -> x | y, + OP_XOR, (x, y) -> x ^ y, + OP_SHL, (x, y) -> x << y, + OP_SHR, (x, y) -> x >>> y + )); + infixOps.put(OP_EQUAL, (x, y) -> ((x.equals(y)) ? 1 : 0)); + } public ExprInfix(int line, int column, int op) { super(line, column); - this.operation = op; + this.operationCode = op; + this.operation = Objects.requireNonNull(infixOps.get(op), "Unknown infix operation"); // children are: left, right } @@ -22,27 +48,50 @@ public void accept(NodeVisitor visitor) { visitor.visit(this); } + @Override + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + Node leftChild = getChild(0); + Node rightChild = getChild(1); + + Either left = leftChild.eval(currentAddress, expectedSizeBytes, env); + Either right = rightChild.eval(currentAddress, expectedSizeBytes, env); + + if (left.isRight() && right.isRight()) { + int l = left.right.getValue(); + int r = right.right.getValue(); + int result = operation.apply(l, r); + + Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); + evaluated.addChild(new ExprNumber(line, column, result)); + return Either.ofRight(evaluated); + } + + NeedMorePass needMorePass = new NeedMorePass(line, column); + needMorePass.addChild(this); + return Either.ofLeft(needMorePass); + } + @Override protected String toStringShallow() { - return "ExprInfix(" + operation + ")"; + return "ExprInfix(" + operationCode + ")"; } @Override protected Node mkCopy() { - return new ExprInfix(line, column, operation); + return new ExprInfix(line, column, operationCode); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - - ExprInfix infix = (ExprInfix) o; - return operation == infix.operation; + if (!super.equals(o)) return false; + ExprInfix exprInfix = (ExprInfix) o; + return operationCode == exprInfix.operationCode; } @Override public int hashCode() { - return operation; + return Objects.hash(super.hashCode(), operationCode); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java index 5f15c7a7d..c21772460 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.Either; +import net.emustudio.plugins.compiler.as8080.ast.*; import org.antlr.v4.runtime.Token; import java.util.function.Function; @@ -18,6 +18,13 @@ public ExprNumber(Token number, Function parser) { this(number.getLine(), number.getCharPositionInLine(), parser.apply(number)); } + @Override + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); + evaluated.addChild(new ExprNumber(line, column, number)); + return Either.ofRight(evaluated); + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index 579e20018..c1f187366 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -1,15 +1,28 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.Either; +import net.emustudio.plugins.compiler.as8080.ast.*; import org.antlr.v4.runtime.Token; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; + public class ExprUnary extends Node { - public final int operation; + private final static Map> unaryOps = Map.of( + OP_ADD, x -> x, + OP_SUBTRACT, x -> -x, + OP_NOT, x -> ~x + ); + private final Function operation; + public final int operationCode; public ExprUnary(int line, int column, int op) { super(line, column); - this.operation = op; + this.operationCode = op; + this.operation = Objects.requireNonNull(unaryOps.get(op), "Unknown unary operation"); // child is expr } @@ -22,27 +35,45 @@ public void accept(NodeVisitor visitor) { visitor.visit(this); } + @Override + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + Node child = getChild(0); + Either childEval = child.eval(currentAddress, expectedSizeBytes, env); + if (childEval.isRight()) { + int value = childEval.right.getValue(); + int result = operation.apply(value); + + Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); + evaluated.addChild(new ExprNumber(line, column, result)); + return Either.ofRight(evaluated); + } + + NeedMorePass needMorePass = new NeedMorePass(line, column); + needMorePass.addChild(this); + return Either.ofLeft(needMorePass); + } + @Override protected String toStringShallow() { - return "ExprUnary(" + operation + ")"; + return "ExprUnary(" + operationCode + ")"; } @Override protected Node mkCopy() { - return new ExprUnary(line, column, operation); + return new ExprUnary(line, column, operationCode); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - + if (!super.equals(o)) return false; ExprUnary exprUnary = (ExprUnary) o; - return operation == exprUnary.operation; + return operationCode == exprUnary.operationCode; } @Override public int hashCode() { - return operation; + return Objects.hash(super.hashCode(), operationCode); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index 205822dbd..b7fda095d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -4,8 +4,27 @@ import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; +import java.util.HashSet; +import java.util.Set; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; + public class InstrExpr extends Node { public final int opcode; + private final static Set twoBytes = new HashSet<>(); + + static { + twoBytes.add(OPCODE_ADI); + twoBytes.add(OPCODE_ACI); + twoBytes.add(OPCODE_SUI); + twoBytes.add(OPCODE_SBI); + twoBytes.add(OPCODE_ANI); + twoBytes.add(OPCODE_ORI); + twoBytes.add(OPCODE_XRI); + twoBytes.add(OPCODE_CPI); + twoBytes.add(OPCODE_IN); + twoBytes.add(OPCODE_OUT); + } public InstrExpr(int line, int column, int opcode) { super(line, column); @@ -17,6 +36,15 @@ public InstrExpr(Token opcode) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); } + public int getExprSizeBytes() { + if (opcode == OPCODE_RST) { + return 0; + } else if (twoBytes.contains(opcode)) { + return 1; + } + return 2; // address + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java index 2fa53a545..7a03ecf35 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; -import net.emustudio.plugins.compiler.as8080.CommonParsers; +import net.emustudio.plugins.compiler.as8080.ParsingUtils; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; @@ -16,7 +16,7 @@ public PseudoInclude(int line, int column, String fileName) { } public PseudoInclude(Token fileName) { - this(fileName.getLine(), fileName.getCharPositionInLine(), CommonParsers.parseLitString(fileName)); + this(fileName.getLine(), fileName.getCharPositionInLine(), ParsingUtils.parseLitString(fileName)); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java new file mode 100644 index 000000000..8cf36b4fc --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java @@ -0,0 +1,68 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + +import net.emustudio.plugins.compiler.as8080.Either; +import net.emustudio.plugins.compiler.as8080.ast.*; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +import static net.emustudio.plugins.compiler.as8080.ParsingUtils.parseLabel; + +public class PseudoLabel extends Node { + public final String label; + + public PseudoLabel(int line, int column, String label) { + super(line, column); + this.label = Objects.requireNonNull(label); + } + + public PseudoLabel(Token label) { + this(label.getLine(), label.getCharPositionInLine(), parseLabel(label)); + } + + @Override + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); + evaluated.addChild(new ExprNumber(line, column, currentAddress)); + return Either.ofRight(evaluated); + } + + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env, boolean evalLeft) { + if (evalLeft) { + NeedMorePass needMorePass = new NeedMorePass(line, column); + needMorePass.addChild(this); + return Either.ofLeft(needMorePass); + } + return eval(currentAddress, expectedSizeBytes, env); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "Label(" + label +")"; + } + + @Override + protected Node mkCopy() { + return new PseudoLabel(line, column, label); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoLabel pseudoLabel1 = (PseudoLabel) o; + return Objects.equals(label, pseudoLabel1.label); + } + + @Override + public int hashCode() { + return label != null ? label.hashCode() : 0; + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java index 1d3abf9b1..1754c76db 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java @@ -1,24 +1,26 @@ package net.emustudio.plugins.compiler.as8080.visitors; -import net.emustudio.plugins.compiler.as8080.ast.Label; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroParameter; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoSet; import java.util.*; -import static net.emustudio.plugins.compiler.as8080.CompileError.alreadyDeclared; +import static net.emustudio.plugins.compiler.as8080.CompileError.*; +import static net.emustudio.plugins.compiler.as8080.ParsingUtils.normalizeId; /** * Checks if all declarations are valid: - * - ID of constant,variable and macro can be used just once in whole program. + * - ID of constant,variable and macro can be used just once in the whole program. + * - ID of constant and macro cannot reference itself in the declaration + * - ID of variable cannot reference itself in the declaration only if it wasn't already declared * - macro parameters should not conflict with: * - declarations in and out of the macro scope * - previously declared parameters in current or parent macros if the current one is nested + * - if expressions should not reference declarations inside that if (including all nested ifs) + * + * - cyclic references will be checked in evaluator since it requires > 1 passes */ public class CheckDeclarationsVisitor extends NodeVisitor { private final Set allDeclarations = new HashSet<>(); @@ -34,11 +36,20 @@ public class CheckDeclarationsVisitor extends NodeVisitor { // for easier removal of current macro params from macroParamsInScope when the macro definition ends private Set currentMacroParams; + // if expr references + private final Set currentIfReferences = new HashSet<>(); + private boolean insideMacroParameter = false; + private int insideIfLevel = 0; // if nesting level, to know how long to keep currentIfReferences + private boolean insideIfExpr = false; + + private String currentDeclarationId; @Override public void visit(PseudoEqu node) { addDeclaration(node.id, node); + currentDeclarationId = normalizeId(node.id); + visitChildren(node); } @Override @@ -52,11 +63,13 @@ public void visit(PseudoMacroDef node) { @Override public void visit(PseudoSet node) { + currentDeclarationId = normalizeId(node.id); + visitChildren(node); addVariable(node.id, node); } @Override - public void visit(Label node) { + public void visit(PseudoLabel node) { addDeclaration(node.label, node); visitChildren(node); } @@ -73,6 +86,27 @@ public void visit(ExprId node) { if (insideMacroParameter) { addMacroParameter(node.id, node); } + if (insideIfExpr) { + addIfReference(node); + } + String idLower = normalizeId(node.id); + if (!variables.contains(idLower) && idLower.equals(currentDeclarationId)) { + error(declarationReferencesItself(node)); + } + } + + @Override + public void visit(PseudoIf node) { + insideIfLevel++; + insideIfExpr = true; + visit(node.getChild(0)); // visiting only expr + insideIfExpr = false; + visitChildren(node, 1); + insideIfLevel--; + + if (insideIfLevel == 0) { + currentIfReferences.clear(); + } } private void addVariable(String id, Node node) { @@ -84,14 +118,20 @@ private void addDeclaration(String id, Node node) { } private void addDeclaration(String id, boolean isVariable, Node node) { - String idLower = id.toLowerCase(Locale.ENGLISH); + String normId = normalizeId(id); + + if (currentIfReferences.contains(normId)) { + error(ifExpressionReferencesOwnBlock(node)); + } - if (allMacroParams.contains(idLower) || buildDeclarations().contains(idLower) && (!isVariable || !variables.contains(id))) { + // if we're in macro (arbitrary nesting level) and it has param named the same way -> error + // if there exist any declaration with that name, but either this declaration is not a variable or the name was taken by not a variable + if (allMacroParams.contains(normId) || buildDeclarations().contains(normId) && (!isVariable || !variables.contains(id))) { error(alreadyDeclared(node, id)); } - allDeclarations.add(idLower); + allDeclarations.add(normId); if (isVariable) { - variables.add(idLower); + variables.add(normId); } } @@ -112,6 +152,15 @@ private void addMacroParameter(String id, Node node) { allMacroParams.add(idLower); } + private void addIfReference(ExprId node) { + String idLower = node.id.toLowerCase(Locale.ENGLISH); + if (currentIfReferences.contains(idLower)) { + error(ifExpressionReferencesOwnBlock(node)); + } else { + currentIfReferences.add(idLower); + } + } + private Set buildDeclarations() { Set allDeclarations = new HashSet<>(); for (Set parameters : macroParamsInScope) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java index eb7602a71..b9b4d1ac5 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java @@ -22,7 +22,8 @@ public Node visitDataDB(DataDBContext ctx) { } else if (next.instr != null) { db.addChild(Visitors.instr.visit(next.instr)); } else { - db.addChild(new DataPlainString(next.str)); + DataPlainString str = new DataPlainString(next.str); + db.addChild(str); } } return db; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java index 4aeb5b4b9..d9fc45f5c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java @@ -2,7 +2,7 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; -import net.emustudio.plugins.compiler.as8080.CommonParsers; +import net.emustudio.plugins.compiler.as8080.ParsingUtils; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.expr.*; import org.antlr.v4.runtime.Token; @@ -11,27 +11,27 @@ public class CreateExprVisitor extends As8080ParserBaseVisitor { @Override public Node visitExprOct(As8080Parser.ExprOctContext ctx) { - return new ExprNumber(ctx.num, CommonParsers::parseLitOct); + return new ExprNumber(ctx.num, ParsingUtils::parseLitOct); } @Override public Node visitExprHex1(As8080Parser.ExprHex1Context ctx) { - return new ExprNumber(ctx.num, CommonParsers::parseLitHex1); + return new ExprNumber(ctx.num, ParsingUtils::parseLitHex1); } @Override public Node visitExprHex2(As8080Parser.ExprHex2Context ctx) { - return new ExprNumber(ctx.num, CommonParsers::parseLitHex2); + return new ExprNumber(ctx.num, ParsingUtils::parseLitHex2); } @Override public Node visitExprDec(As8080Parser.ExprDecContext ctx) { - return new ExprNumber(ctx.num, CommonParsers::parseLitDec); + return new ExprNumber(ctx.num, ParsingUtils::parseLitDec); } @Override public Node visitExprBin(As8080Parser.ExprBinContext ctx) { - return new ExprNumber(ctx.num, CommonParsers::parseLitBin); + return new ExprNumber(ctx.num, ParsingUtils::parseLitBin); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java index b781efb90..a66cc4616 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java @@ -2,7 +2,7 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; -import net.emustudio.plugins.compiler.as8080.ast.Label; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoLabel; import net.emustudio.plugins.compiler.as8080.ast.Node; public class CreateLineVisitor extends As8080ParserBaseVisitor { @@ -11,7 +11,7 @@ public class CreateLineVisitor extends As8080ParserBaseVisitor { public Node visitRLine(As8080Parser.RLineContext ctx) { Node label = null; if (ctx.label != null) { - label = new Label(ctx.label); + label = new PseudoLabel(ctx.label); } Node statement = null; if (ctx.statement != null) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java new file mode 100644 index 000000000..e30736482 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -0,0 +1,257 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.Either; +import net.emustudio.plugins.compiler.as8080.ast.*; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; +import net.emustudio.plugins.compiler.as8080.ast.expr.*; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegPairExpr; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; + +import java.util.*; +import java.util.stream.Collectors; + +import static net.emustudio.plugins.compiler.as8080.CompileError.ambiguousExpression; +import static net.emustudio.plugins.compiler.as8080.ParsingUtils.normalizeId; + +/** + * The goal is to replace all Expr* with Evaluated + *

+ * - replace ExprId (referencing PseudoEqu, PseudoSet, PseudoLabel or PseudoMacroArgument) with value + * - replace ExprCurrentAddress with the current address + * - address changes after processing Expr*, DataDS, PseudoOrg + * - eliminate or include code block of PseudoIf if expr evaluates to 1 + * + * After finishing this visitor, there should be: + * - no PseudoEqu + * - no ExprId + * - no PseudoIf + * - no PseudoLabel + */ +public class EvaluateExprVisitor extends NodeVisitor { + private int currentAddress = 0; + private int expectedBytes = 0; + private boolean doNotEvaluateCurrentAddress = false; + + private Either latestEval; + private Set needMorePassThings = new HashSet<>(); + private final Map> macroArguments = new HashMap<>(); + private String currentMacro; + + @Override + public void visit(Program node) { + currentAddress = 0; + visitChildren(node); + + Set oldNeedMorePass; + while (!needMorePassThings.isEmpty()) { + oldNeedMorePass = needMorePassThings; + needMorePassThings = new HashSet<>(); + currentAddress = 0; + visitChildren(node); + + // at least one thing must disappear from "oldNeedMorePass"; + // doesn't matter if something is added - since the source code is final, also additions must be final. + boolean atLeastOneResolved = false; + for (Node oldNode : oldNeedMorePass) { + if (!needMorePassThings.contains(oldNode)) { + atLeastOneResolved = true; + break; + } + } + if (!atLeastOneResolved) { + // there is a cycle + for (Node unresolved : needMorePassThings) { + error(ambiguousExpression(unresolved)); + } + break; + } + } + + } + + @Override + public void visit(DataDB node) { + expectedBytes = 1; + visitChildren(node); + } + + @Override + public void visit(DataDW node) { + expectedBytes = 2; + visitChildren(node); + } + + @Override + public void visit(DataDS node) { + expectedBytes = 0; + visitChildren(node); + if (latestEval.isRight()) { + // TODO: check 2 bytes + currentAddress += latestEval.right.getValue(); + } else { + // we don't know now how the address changes since we can't evaluate the expr yet + doNotEvaluateCurrentAddress = true; + } + } + + @Override + public void visit(PseudoEqu node) { + expectedBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) + visitChildren(node); + env.put(normalizeId(node.id), latestEval); + if (latestEval.isRight()) { + node.remove(); // we don't need to re-evaluate the constant + } + } + + @Override + public void visit(PseudoSet node) { + expectedBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) + visitChildren(node); + env.put(normalizeId(node.id), latestEval); + } + + @Override + public void visit(PseudoLabel node) { + Either eval = node.eval(currentAddress, 2, env, doNotEvaluateCurrentAddress); + env.put(normalizeId(node.label), eval); + if (eval.isRight()) { + node.remove(); // we don't need to re-evaluate label + } else { + needMorePassThings.add(node); + } + } + + @Override + public void visit(PseudoOrg node) { + expectedBytes = 0; + visitChildren(node); + if (latestEval.isRight()) { + currentAddress = latestEval.right.getValue(); + } else { + // if we can't evaluate current address now, we cannot evaluate it below too + doNotEvaluateCurrentAddress = true; + } + } + + @Override + public void visit(PseudoIf node) { + expectedBytes = 0; + visit(node.getChild(0)); + + Optional expr = node.collectChild(Evaluated.class); + boolean includeBlock = expr.filter(p -> p.getValue() != 0).isPresent(); + boolean excludeBlock = expr.filter(p -> p.getValue() == 0).isPresent(); + + if (includeBlock) { + List codeChildren = node.getChildren().stream().skip(1).collect(Collectors.toList()); + node.remove().ifPresent(p -> p.addChildren(codeChildren)); + visitChildren(node, 1); + } else if (excludeBlock) { + node.remove(); + } else { + // expr needs more pass - it means all exprCurrentAddress and pseudoLabel evaluations below must be ignored + // until this expr is evaluated + doNotEvaluateCurrentAddress = true; + } + } + + @Override + public void visit(InstrExpr node) { + expectedBytes = node.getExprSizeBytes(); + visitChildren(node); + currentAddress++; // opcode + } + + @Override + public void visit(InstrRegExpr node) { + expectedBytes = 1; + visitChildren(node); + currentAddress++; // opcode + } + + @Override + public void visit(InstrRegPairExpr node) { + expectedBytes = 2; + visitChildren(node); + currentAddress++; // opcode + } + + @Override + public void visit(PseudoMacroCall node) { + currentMacro = normalizeId(node.id); + macroArguments.put(currentMacro, new ArrayList<>()); + visitChildren(node); + + // on macro exit, remove current macro arguments from env + for (String macroParameter : macroArguments.get(currentMacro)) { + env.remove(macroParameter); + } + macroArguments.remove(currentMacro); + } + + @Override + public void visit(PseudoMacroArgument node) { + expectedBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) + visitChildren(node, 1); // expected two children: ExprId and Expr* + + node.collectChild(ExprId.class).ifPresent(exprId -> { + String macroParameter = normalizeId(exprId.id); + macroArguments.get(currentMacro).add(macroParameter); + env.put(macroParameter, latestEval); + }); + } + + @Override + public void visit(DataPlainString node) { + Either eval = node.eval(currentAddress, -1, env); + node.remove().ifPresent(p -> p.addChild(eval.right)); + currentAddress += eval.right.sizeBytes; + } + + @Override + public void visit(Evaluated node) { + latestEval = Either.ofRight(node); + currentAddress += expectedBytes; + } + + @Override + public void visit(ExprInfix node) { + evalExpr(node); + } + + @Override + public void visit(ExprNumber node) { + evalExpr(node); + } + + @Override + public void visit(ExprUnary node) { + evalExpr(node); + } + + @Override + public void visit(ExprCurrentAddress node) { + evalExpr(node); + } + + @Override + public void visit(ExprId node) { + evalExpr(node); + } + + private void evalExpr(Node node) { + latestEval = node.eval(currentAddress, expectedBytes, env); + if (latestEval.isRight()) { + node.remove().ifPresent(p -> p.addChild(latestEval.right)); + } else { + needMorePassThings.add(node); + } + currentAddress += expectedBytes; + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java index 45f07c175..39ae78641 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java @@ -18,6 +18,9 @@ import static net.emustudio.plugins.compiler.as8080.CompileError.couldNotReadFile; import static net.emustudio.plugins.compiler.as8080.CompileError.infiniteLoopDetected; +/** + * Integrate "include" files and remove PseudoInclude + */ public class ExpandIncludesVisitor extends NodeVisitor { private final Set includedFiles; // TODO: windows platform case-insensitive! diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java index 7b74e5a2a..a9c74b136 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java @@ -10,6 +10,7 @@ import static net.emustudio.plugins.compiler.as8080.CompileError.infiniteLoopDetected; import static net.emustudio.plugins.compiler.as8080.CompileError.notDefined; +import static net.emustudio.plugins.compiler.as8080.ParsingUtils.normalizeId; /** * Expands macros. It means - find macro definitions, remove them from the parent node and put them as a child under @@ -31,7 +32,7 @@ public void visit(Program node) { @Override public void visit(PseudoMacroDef node) { - String id = node.id.toLowerCase(Locale.ENGLISH); + String id = normalizeId(node.id); // save macro macros.put(id, node); @@ -49,7 +50,7 @@ public void visit(PseudoMacroDef node) { @Override public void visit(PseudoMacroCall node) { - String id = node.id.toLowerCase(Locale.ENGLISH); + String id = normalizeId(node.id); if (macros.containsKey(id)) { node.addChild(macros.get(id).copy()); } else { @@ -62,12 +63,12 @@ public void visit(PseudoMacroCall node) { } private void checkInfiniteLoop(PseudoMacroCall node) { - String id = node.id.toLowerCase(Locale.ENGLISH); + String id = normalizeId(node.id); Optional parent = node.getParent(); while (parent.isPresent()) { Node parentValue = parent.get(); if (parentValue instanceof PseudoMacroDef) { - String parentId = ((PseudoMacroDef) parentValue).id.toLowerCase(Locale.ENGLISH); + String parentId = normalizeId(((PseudoMacroDef) parentValue).id); if (parentId.equals(id)) { fatalError(infiniteLoopDetected(node, "macro call '" + id + "'")); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitor.java deleted file mode 100644 index 65a33d9ac..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitor.java +++ /dev/null @@ -1,66 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.visitors; - -import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; -import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroArgument; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroCall; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroParameter; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -/** - * Replaces ExprIds inside macro definition with macro arguments, and removes PseudoMacroCall + PseudoMacroDef. - * Macro expansions disappear and just code remains. - */ -public class IntegrateMacrosVisitor extends NodeVisitor { - private final List macroParameters = new ArrayList<>(); - private final List macroArguments = new ArrayList<>(); - - private boolean insideMacroParameter; - private boolean insideMacroDef; - - @Override - public void visit(ExprId node) { - String id = node.id.toLowerCase(Locale.ENGLISH); - - if (insideMacroParameter) { - macroParameters.add(id); - } else if (insideMacroDef) { - int index = macroParameters.indexOf(id); - Node argument = macroArguments.get(index); - node.remove().ifPresent(p -> p.addChild(argument)); - } - } - - @Override - public void visit(PseudoMacroArgument node) { - macroArguments.add(node.getChild(0)); - node.remove(); - } - - @Override - public void visit(PseudoMacroParameter node) { - insideMacroParameter = true; - visitChildren(node); - node.remove(); - insideMacroParameter = false; - } - - @Override - public void visit(PseudoMacroDef node) { - insideMacroDef = true; - visitChildren(node); - node.remove().ifPresent(p -> p.addChildren(node.getChildren())); - insideMacroDef = false; - } - - @Override - public void visit(PseudoMacroCall node) { - visitChildren(node); - node.remove().ifPresent(p -> p.addChildren(node.getChildren())); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java new file mode 100644 index 000000000..ae1ab4262 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java @@ -0,0 +1,99 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroArgument; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroCall; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroParameter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static net.emustudio.plugins.compiler.as8080.CompileError.macroArgumentsDoNotMatch; +import static net.emustudio.plugins.compiler.as8080.ParsingUtils.normalizeId; + +/** + * Connects macro parameters with arguments. + * Example input: + *

+ * PseudoMacroCall
+ *   PseudoMacroArgument
+ *     ExprNumber(1)
+ *   PseudoMacroArgument
+ *     ExprNumber(2)
+ *   PseudoMacroDef
+ *     PseudoMacroParameter
+ *       ExprId(q)
+ *     PseudoMacroParameter
+ *       ExprId(r)
+ *     ...
+ * 
+ *

+ * Example output: + *

+ * PseudoMacroCall
+ *   PseudoMacroArgument
+ *     ExprId(q)
+ *     ExprNumber(1)
+ *   PseudoMacroArgument
+ *     ExprId(r)
+ *     ExprNumber(2)
+ *   ...
+ * 
+ */ +public class SortMacroArgumentsVisitor extends NodeVisitor { + + private final Map> macroArguments = new HashMap<>(); + private final Map> macroParameters = new HashMap<>(); + private String currentMacroCall; + private String currentMacroDef; + + @Override + public void visit(PseudoMacroCall node) { + currentMacroCall = normalizeId(node.id); + macroArguments.put(currentMacroCall, new ArrayList<>()); + visitChildren(node); + } + + @Override + public void visit(PseudoMacroArgument node) { + macroArguments.get(currentMacroCall).add(node); + } + + @Override + public void visit(PseudoMacroDef node) { + currentMacroDef = normalizeId(node.id); + macroParameters.put(currentMacroDef, new ArrayList<>()); + + String origMacroDef = currentMacroDef; // we can have macro calls inside this macro + visitChildren(node); + + // there should not be recursive macro calls (assured by ExpandMacrosVisitor) + List origMacroParams = macroParameters.get(origMacroDef); + List origMacroArguments = macroArguments.get(origMacroDef); + + if (origMacroArguments.size() != origMacroParams.size()) { + error(macroArgumentsDoNotMatch(node)); // better would be to have macro call instead of macro def + } else { + for (int i = 0; i < origMacroArguments.size(); i++) { + Node macroParam = origMacroParams.get(i); + macroParam.remove(); + + Node macroArgument = origMacroArguments.get(i); + macroParam + .collectChild(ExprId.class) + .ifPresentOrElse(macroArgument::addChildFirst, () -> error(macroArgumentsDoNotMatch(node))); + } + node.remove().ifPresent(p -> p.addChildren(node.getChildren())); + } + } + + @Override + public void visit(PseudoMacroParameter node) { + macroParameters.get(currentMacroDef).add(node); + } +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java index 143df220b..835be8406 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080; -import net.emustudio.plugins.compiler.as8080.ast.Label; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoLabel; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; @@ -100,8 +100,8 @@ public void testTwoLabelsInsideIf() { assertTrees(new Program() .addChild(new PseudoIf(0, 0) .addChild(new ExprNumber(0, 0, 1)) - .addChild(new Label(0, 0, "label1")) - .addChild(new Label(0, 0, "label2"))), + .addChild(new PseudoLabel(0, 0, "label1")) + .addChild(new PseudoLabel(0, 0, "label2"))), program ); } @@ -129,7 +129,7 @@ public void testMacroDef() { .addChild(new PseudoMacroParameter() .addChild(new ExprId(0, 0, "param2"))) .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) - .addChild(new Label(0, 0, "heylabel") + .addChild(new PseudoLabel(0, 0, "heylabel") .addChild(new InstrExpr(0, 0, OPCODE_ANI) .addChild(new ExprNumber(0, 0, 0x7F))))); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/CommonParsersTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsingUtilsTest.java similarity index 62% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/CommonParsersTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsingUtilsTest.java index 6df64ab44..f732cce0f 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/CommonParsersTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsingUtilsTest.java @@ -9,30 +9,30 @@ import static net.emustudio.plugins.compiler.as8080.Utils.getTokens; import static org.junit.Assert.assertEquals; -public class CommonParsersTest { +public class ParsingUtilsTest { @Test public void testParseLitString() { List tokens = getTokens("'te\"x\"t1' \"te'x't2\""); assertTokenTypes(tokens, As8080Parser.LIT_STRING_1, As8080Parser.LIT_STRING_2, As8080Parser.EOF); - assertEquals("te\"x\"t1", CommonParsers.parseLitString(tokens.get(0))); - assertEquals("te'x't2", CommonParsers.parseLitString(tokens.get(1))); + assertEquals("te\"x\"t1", ParsingUtils.parseLitString(tokens.get(0))); + assertEquals("te'x't2", ParsingUtils.parseLitString(tokens.get(1))); } @Test public void testParseLitHex1() { List tokens = getTokens("-0x22F 0XAA55"); assertTokenTypes(tokens, As8080Parser.LIT_HEXNUMBER_1, As8080Parser.LIT_HEXNUMBER_1, As8080Parser.EOF); - assertEquals(-0x22F, CommonParsers.parseLitHex1(tokens.get(0))); - assertEquals(0xAA55, CommonParsers.parseLitHex1(tokens.get(1))); + assertEquals(-0x22F, ParsingUtils.parseLitHex1(tokens.get(0))); + assertEquals(0xAA55, ParsingUtils.parseLitHex1(tokens.get(1))); } @Test public void testParseLitHex2() { List tokens = getTokens("-022Fh AA55H"); assertTokenTypes(tokens, As8080Parser.LIT_HEXNUMBER_2, As8080Parser.LIT_HEXNUMBER_2, As8080Parser.EOF); - assertEquals(-0x22F, CommonParsers.parseLitHex2(tokens.get(0))); - assertEquals(0xAA55, CommonParsers.parseLitHex2(tokens.get(1))); + assertEquals(-0x22F, ParsingUtils.parseLitHex2(tokens.get(0))); + assertEquals(0xAA55, ParsingUtils.parseLitHex2(tokens.get(1))); } @Test @@ -43,10 +43,10 @@ public void testParseLitOct() { As8080Parser.LIT_OCTNUMBER, As8080Parser.LIT_OCTNUMBER, As8080Parser.LIT_OCTNUMBER, As8080Parser.LIT_OCTNUMBER, As8080Parser.EOF ); - assertEquals(-18, CommonParsers.parseLitOct(tokens.get(0))); - assertEquals(45, CommonParsers.parseLitOct(tokens.get(1))); - assertEquals(63, CommonParsers.parseLitOct(tokens.get(2))); - assertEquals(-1, CommonParsers.parseLitOct(tokens.get(3))); + assertEquals(-18, ParsingUtils.parseLitOct(tokens.get(0))); + assertEquals(45, ParsingUtils.parseLitOct(tokens.get(1))); + assertEquals(63, ParsingUtils.parseLitOct(tokens.get(2))); + assertEquals(-1, ParsingUtils.parseLitOct(tokens.get(3))); } @Test @@ -56,9 +56,9 @@ public void testParseLitDec() { tokens, As8080Parser.LIT_NUMBER, As8080Parser.LIT_NUMBER, As8080Parser.LIT_NUMBER, As8080Parser.EOF ); - assertEquals(-22, CommonParsers.parseLitDec(tokens.get(0))); - assertEquals(55, CommonParsers.parseLitDec(tokens.get(1))); - assertEquals(0, CommonParsers.parseLitDec(tokens.get(2))); + assertEquals(-22, ParsingUtils.parseLitDec(tokens.get(0))); + assertEquals(55, ParsingUtils.parseLitDec(tokens.get(1))); + assertEquals(0, ParsingUtils.parseLitDec(tokens.get(2))); } @Test @@ -68,8 +68,8 @@ public void testParseLitBin() { tokens, As8080Parser.LIT_BINNUMBER, As8080Parser.LIT_BINNUMBER, As8080Parser.LIT_BINNUMBER, As8080Parser.EOF ); - assertEquals(0, CommonParsers.parseLitBin(tokens.get(0))); - assertEquals(45, CommonParsers.parseLitBin(tokens.get(1))); - assertEquals(7, CommonParsers.parseLitBin(tokens.get(2))); + assertEquals(0, ParsingUtils.parseLitBin(tokens.get(0))); + assertEquals(45, ParsingUtils.parseLitBin(tokens.get(1))); + assertEquals(7, ParsingUtils.parseLitBin(tokens.get(2))); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java index fb6d13025..90be070fa 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -123,6 +123,7 @@ public static void assertTrees(Node expected, Node result) { for (int i = 0; i < expected.getChildren().size(); i++) { Node expectedChild = expected.getChild(i); Node resultChild = result.getChild(i); + assertEquals(expectedChild, resultChild); assertTrees(expectedChild, resultChild); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java index 91d8da8d3..7d6b6b5a9 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java @@ -3,7 +3,7 @@ import net.emustudio.plugins.compiler.as8080.ast.Program; import org.junit.Test; -import static net.emustudio.plugins.compiler.as8080.CompileError.ERROR_ALREADY_DECLARED; +import static net.emustudio.plugins.compiler.as8080.CompileError.*; import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; import static org.junit.Assert.assertTrue; @@ -125,4 +125,53 @@ public void testMacroReuseParameterNamesIsPossible() { visitor.visit(program); assertTrue(program.env().hasNoErrors()); } + + @Test + public void testIfExpressionReferencesOwnBlockDeclarations() { + Program program = parseProgram("if var + 1\nvar set -1\nendif"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK)); + } + + @Test + public void testNestedIfExpressionReferencesOwnBlockDeclarations() { + Program program = parseProgram("if var + 1\nif 0\nvar:\nendif\nendif"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK)); + } + + @Test + public void testSelfReferencingConstant() { + Program program = parseProgram("self equ self + 1"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_DECLARATION_REFERENCES_ITSELF)); + } + + @Test + public void testSelfReferencingNoneExistingVariableIsNotFine() { + Program program = parseProgram("self set self + 1"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_DECLARATION_REFERENCES_ITSELF)); + } + + @Test + public void testSelfReferencingExistingVariableIsFine() { + Program program = parseProgram("self set 1\n self set self + 1"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testDeclarationsReferencingInCycle() { + Program program = parseProgram("one equ two\ntwo equ three\nthree equ one"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + System.out.println(program); + System.out.println(program.env()); + } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java new file mode 100644 index 000000000..d736e42a6 --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -0,0 +1,6 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +public class EvaluateExprVisitorTest { + + +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java index 068d771e5..44e1de53f 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080.visitors; -import net.emustudio.plugins.compiler.as8080.ast.Label; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoLabel; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; @@ -32,7 +32,7 @@ public void testExpandInclude() { Node expected = new Program() .addChild(new InstrNoArgs(0, 0, OPCODE_CMC)) - .addChild(new Label(0, 0, "sample") + .addChild(new PseudoLabel(0, 0, "sample") .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) .addChild(new ExprNumber(0, 0, 0)))) .addChild(new InstrNoArgs(0, 0, OPCODE_RET)); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java index b99e65118..ba6f33d34 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java @@ -87,6 +87,13 @@ public void testTheSameMacroCallInsideMacroDefinition() { macrosVisitor.visit(program); } + @Test(expected = FatalError.class) + public void testRecursiveMacroCallComplex() { + Program program = parseProgram("x macro\ny\nendm\ny macro\nx\nendm"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + } + @Test public void testMacroCallWithArguments() { Program program = parseProgram("x 1,2,3\nx macro q,r,t\nendm"); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitorTest.java deleted file mode 100644 index e8f914143..000000000 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/IntegrateMacrosVisitorTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.visitors; - -import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.Program; -import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; -import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; -import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; -import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; -import org.junit.Test; - -import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; -import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; - -public class IntegrateMacrosVisitorTest { - - @Test - public void testMacroArgumentsAreExpanded() { - Node program = new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument() - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroArgument() - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter() - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoMacroParameter() - .addChild(new ExprId(0, 0, "r"))) - .addChild(new PseudoMacroParameter() - .addChild(new ExprId(0, 0, "t"))) - .addChild(new InstrRegExpr(0,0,OPCODE_MVI, REG_A) - .addChild(new ExprId(0,0,"q"))) - .addChild(new PseudoEqu(0,0,"uu") - .addChild(new ExprInfix(0,0, OP_ADD) - .addChild(new ExprId(0,0,"r")) - .addChild(new ExprId(0,0,"t")))))); - - IntegrateMacrosVisitor visitor = new IntegrateMacrosVisitor(); - visitor.visit(program); - - assertTrees(new Program() - .addChild(new InstrRegExpr(0,0,OPCODE_MVI, REG_A) - .addChild(new ExprNumber(0,0,1))) - .addChild(new PseudoEqu(0,0, "uu") - .addChild(new ExprInfix(0,0,OP_ADD) - .addChild(new ExprNumber(0,0,2)) - .addChild(new ExprNumber(0,0,3)))), - program - ); - } -} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java new file mode 100644 index 000000000..6ca73d725 --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java @@ -0,0 +1,169 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; +import static net.emustudio.plugins.compiler.as8080.CompileError.ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH; +import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; +import static org.junit.Assert.assertTrue; + +public class SortMacroArgumentsVisitorTest { + + @Test + public void testMacroArgumentsAreConnectedWithIds() { + Node program = new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "r"))) + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "t"))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoEqu(0, 0, "uu") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprId(0, 0, "t")))))); + + SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); + visitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument() + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument() + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument() + .addChild(new ExprId(0, 0, "t")) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoEqu(0, 0, "uu") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprId(0, 0, "t"))))), + program + ); + } + + @Test + public void testMultipleMacroCalls() { + Node program = new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "q"))))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "q"))))); + + SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); + visitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument() + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument() + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 2)))), + program + ); + } + + @Test + public void testNestedMacroCallWithSameNamedArgs() { + Node program = new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "y") + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "q"))))))); + + SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument() + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument() + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 3))))), + program + ); + } + + @Test + public void testMoreMacroArgumentsThanParameters() { + Program program = new Program(); + program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "q"))))); + + SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH)); + } + + @Test + public void testMoreMacroParametersThanArguments() { + Program program = new Program(); + program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument() + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter() + .addChild(new ExprId(0, 0, "r"))))); + + SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH)); + } +} From dd1ae0ac1fa023be84bde5debe89cbb097f7d7bb Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 28 Dec 2021 20:06:43 +0100 Subject: [PATCH 060/314] [#201] as-8080: some tests --- .../compiler/as8080/ast/Evaluated.java | 8 ++ .../as8080/visitors/EvaluateExprVisitor.java | 5 +- .../visitors/EvaluateExprVisitorTest.java | 94 ++++++++++++++++++- 3 files changed, 105 insertions(+), 2 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java index 70b2a83ee..66e8a4dda 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java @@ -43,4 +43,12 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(super.hashCode(), address, sizeBytes); } + + @Override + protected String toStringShallow() { + return "Evaluated(" + + "addr=" + address + + ", size=" + sizeBytes + + ')'; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index e30736482..a18774f8c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -44,6 +44,10 @@ public class EvaluateExprVisitor extends NodeVisitor { @Override public void visit(Program node) { + if (env == null) { + this.env = node.env(); + } + currentAddress = 0; visitChildren(node); @@ -71,7 +75,6 @@ public void visit(Program node) { break; } } - } @Override diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index d736e42a6..1698319e1 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -1,6 +1,98 @@ package net.emustudio.plugins.compiler.as8080.visitors; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.OP_ADD; +import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; + public class EvaluateExprVisitorTest { - + @Test + public void testEvaluateDB() { + Program program = new Program(); + program.addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2)) + ).addChild(new DataPlainString(0, 0, "hello"))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 0, 1) + .addChild(new ExprNumber(0, 0, 3)) + ).addChild(new Evaluated(0, 0, 1, 5) + .addChild(new ExprNumber(0, 0, 'h')) + .addChild(new ExprNumber(0, 0, 'e')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'o')))), + program + ); + } + + @Test + public void testEvaluateDW() { + Program program = new Program(); + program + .addChild(new DataDW(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new DataDW(0, 0) + .addChild(new ExprNumber(0, 0, 0))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 0, 2) + .addChild(new ExprNumber(0, 0, 3)))) + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 2, 2) + .addChild(new ExprNumber(0, 0, 0)))), + program + ); + } + + @Test + public void testEvaluateDS() { + Program program = new Program(); + program + .addChild(new DataDS(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new DataDB(0, 0) + .addChild(new ExprNumber(0, 0, 0))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 0, 0) + .addChild(new ExprNumber(0, 0, 3)))) + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 3, 1) + .addChild(new ExprNumber(0, 0, 0)))), + program + ); + } + + } From e2a0a219d6c7ae7211ead499ec74dbf732987e8e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 30 Dec 2021 08:45:19 +0100 Subject: [PATCH 061/314] [#201] as-8080: test --- .../compiler/as8080/ast/Evaluated.java | 10 +++- .../as8080/visitors/EvaluateExprVisitor.java | 6 ++- .../visitors/EvaluateExprVisitorTest.java | 49 +++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java index 66e8a4dda..3e9b6e147 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java @@ -6,7 +6,7 @@ public class Evaluated extends Node { public final int address; - public final int sizeBytes; + private int sizeBytes; public Evaluated(int line, int column, int address, int sizeBytes) { super(line, column); @@ -20,6 +20,14 @@ public int getValue() { return ((ExprNumber) getChild(0)).number; } + public int getSizeBytes() { + return sizeBytes; + } + + public void setSizeBytes(int sizeBytes) { + this.sizeBytes = sizeBytes; + } + @Override protected Node mkCopy() { return new Evaluated(line, column, address, sizeBytes); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index a18774f8c..6915c9bca 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -95,7 +95,9 @@ public void visit(DataDS node) { visitChildren(node); if (latestEval.isRight()) { // TODO: check 2 bytes - currentAddress += latestEval.right.getValue(); + int value = latestEval.right.getValue(); + currentAddress += value; + latestEval.right.setSizeBytes(value); } else { // we don't know now how the address changes since we can't evaluate the expr yet doNotEvaluateCurrentAddress = true; @@ -214,7 +216,7 @@ public void visit(PseudoMacroArgument node) { public void visit(DataPlainString node) { Either eval = node.eval(currentAddress, -1, env); node.remove().ifPresent(p -> p.addChild(eval.right)); - currentAddress += eval.right.sizeBytes; + currentAddress += eval.right.getSizeBytes(); } @Override diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index 1698319e1..62de4125d 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -1,17 +1,25 @@ package net.emustudio.plugins.compiler.as8080.visitors; +import net.emustudio.plugins.compiler.as8080.Either; import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.NeedMorePass; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoLabel; import org.junit.Test; import static net.emustudio.plugins.compiler.as8080.As8080Parser.OP_ADD; +import static net.emustudio.plugins.compiler.as8080.CompileError.ERROR_AMBIGUOUS_EXPRESSION; import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class EvaluateExprVisitorTest { @@ -94,5 +102,46 @@ public void testEvaluateDS() { ); } + @Test + public void testEvaluateDSambiguous() { + Program program = new Program(); + program + .addChild(new DataDS(0, 0) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new PseudoLabel(0, 0, "label")); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_AMBIGUOUS_EXPRESSION)); + } + + @Test + public void testEvaluateDScontReference() { + Program program = new Program(); + program + .addChild(new DataDS(0, 0) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new PseudoEqu(0, 0, "label") + .addChild(new ExprNumber(0, 0, 5))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + + Either label = program.env().get("label").orElseThrow(); + assertTrue(label.isRight()); + assertEquals(5, label.right.getSizeBytes()); + assertEquals(0, label.right.address); + + assertTrees( + new Program() + .addChild(new DataDS(0, 0) + .addChild(new ExprId(0, 0, "label"))), + program + ); + } + } From a49e2f95a45243c36a6c8206a1a6b93ee9c7e6e9 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 30 Dec 2021 17:50:24 +0100 Subject: [PATCH 062/314] [#201] as-8080: wip --- .../compiler/as8080/ast/Evaluated.java | 5 - .../compiler/as8080/ast/NameSpace.java | 6 +- .../compiler/as8080/ast/NeedMorePass.java | 18 --- .../plugins/compiler/as8080/ast/Node.java | 8 +- .../compiler/as8080/ast/NodeVisitor.java | 4 - .../as8080/ast/data/DataPlainString.java | 7 +- .../as8080/ast/expr/ExprCurrentAddress.java | 11 +- .../compiler/as8080/ast/expr/ExprId.java | 13 +- .../compiler/as8080/ast/expr/ExprInfix.java | 15 +-- .../compiler/as8080/ast/expr/ExprNumber.java | 7 +- .../compiler/as8080/ast/expr/ExprUnary.java | 14 +-- .../compiler/as8080/ast/instr/InstrExpr.java | 5 - .../as8080/ast/instr/InstrNoArgs.java | 5 - .../compiler/as8080/ast/instr/InstrReg.java | 7 -- .../as8080/ast/instr/InstrRegExpr.java | 7 -- .../as8080/ast/instr/InstrRegPair.java | 7 -- .../as8080/ast/instr/InstrRegPairExpr.java | 7 -- .../as8080/ast/instr/InstrRegReg.java | 8 -- .../compiler/as8080/ast/pseudo/PseudoEqu.java | 5 - .../as8080/ast/pseudo/PseudoInclude.java | 5 - .../as8080/ast/pseudo/PseudoLabel.java | 13 +- .../as8080/ast/pseudo/PseudoMacroCall.java | 5 - .../as8080/ast/pseudo/PseudoMacroDef.java | 5 - .../compiler/as8080/ast/pseudo/PseudoSet.java | 5 - .../as8080/visitors/EvaluateExprVisitor.java | 8 +- .../visitors/EvaluateExprVisitorTest.java | 117 +++++++++++++++++- 26 files changed, 141 insertions(+), 176 deletions(-) delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NeedMorePass.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java index 3e9b6e147..7d10e96df 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java @@ -47,11 +47,6 @@ public boolean equals(Object o) { return address == evaluated.address && sizeBytes == evaluated.sizeBytes; } - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), address, sizeBytes); - } - @Override protected String toStringShallow() { return "Evaluated(" + diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java index 25246261b..05fb1c4a3 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java @@ -7,7 +7,7 @@ public class NameSpace { private final List errors = new ArrayList<>(); - private final Map> definitions = new HashMap<>(); + private final Map> definitions = new HashMap<>(); public void error(CompileError error) { errors.add(Objects.requireNonNull(error)); @@ -21,7 +21,7 @@ public boolean hasNoErrors() { return errors.isEmpty(); } - public void put(String id, Either value) { + public void put(String id, Either value) { definitions.put(id, value); } @@ -29,7 +29,7 @@ public void remove(String id) { definitions.remove(id); } - public Optional> get(String id) { + public Optional> get(String id) { return Optional.ofNullable(definitions.get(id)); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NeedMorePass.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NeedMorePass.java deleted file mode 100644 index cae4c5d6c..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NeedMorePass.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast; - -public class NeedMorePass extends Node { - - public NeedMorePass(int line, int column) { - super(line, column); - } - - @Override - public void accept(NodeVisitor visitor) { - visitor.visit(this); - } - - @Override - protected Node mkCopy() { - return new NeedMorePass(line, column); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 7f5fe6c57..cd44bf798 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -66,10 +66,8 @@ public Optional remove() { return parent; } - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { - NeedMorePass needMorePass = new NeedMorePass(line, column); - needMorePass.addChild(this); - return Either.ofLeft(needMorePass); + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + return Either.ofLeft(this); } public void accept(NodeVisitor visitor) { @@ -115,6 +113,6 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(parent, line, column); + return System.identityHashCode(this); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java index a78a67293..367169f39 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java @@ -142,10 +142,6 @@ public void visit(Evaluated node) { visitChildren(node); } - public void visit(NeedMorePass node) { - visitChildren(node); - } - protected void visitChildren(Node node) { for (Node child : node.getChildren()) { child.accept(this); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java index 98adb5f50..e282d0d29 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java @@ -22,7 +22,7 @@ public DataPlainString(Token string) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { int sizeBytes = string.length(); Evaluated evaluated = new Evaluated(line, column, currentAddress, sizeBytes); for (byte b : string.getBytes()) { @@ -54,9 +54,4 @@ public boolean equals(Object o) { DataPlainString that = (DataPlainString) o; return Objects.equals(string, that.string); } - - @Override - public int hashCode() { - return string != null ? string.hashCode() : 0; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java index e9f24e18f..0c6b7bca2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java @@ -20,18 +20,13 @@ protected Node mkCopy() { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); evaluated.addChild(new ExprNumber(line, column, currentAddress)); return Either.ofRight(evaluated); } - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env, boolean evalLeft) { - if (evalLeft) { - NeedMorePass needMorePass = new NeedMorePass(line, column); - needMorePass.addChild(this); - return Either.ofLeft(needMorePass); - } - return eval(currentAddress, expectedSizeBytes, env); + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env, boolean evalLeft) { + return evalLeft ? Either.ofLeft(this) : eval(currentAddress, expectedSizeBytes, env); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java index 8a3baeb4d..d2b0c199b 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java @@ -21,12 +21,8 @@ public ExprId(Token id) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { - return env.get(normalizeId(id)).orElseGet(() -> { - NeedMorePass needMorePass = new NeedMorePass(line, column); - needMorePass.addChild(this); - return Either.ofLeft(needMorePass); - }); + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + return env.get(normalizeId(id)).orElseGet(() -> Either.ofLeft(this)); } @Override @@ -52,9 +48,4 @@ public boolean equals(Object o) { ExprId exprId = (ExprId) o; return Objects.equals(id, exprId.id); } - - @Override - public int hashCode() { - return id != null ? id.hashCode() : 0; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index de3da6cdd..1dd87e9f6 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -49,12 +49,12 @@ public void accept(NodeVisitor visitor) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { Node leftChild = getChild(0); Node rightChild = getChild(1); - Either left = leftChild.eval(currentAddress, expectedSizeBytes, env); - Either right = rightChild.eval(currentAddress, expectedSizeBytes, env); + Either left = leftChild.eval(currentAddress, expectedSizeBytes, env); + Either right = rightChild.eval(currentAddress, expectedSizeBytes, env); if (left.isRight() && right.isRight()) { int l = left.right.getValue(); @@ -66,9 +66,7 @@ public Either eval(int currentAddress, int expectedSize return Either.ofRight(evaluated); } - NeedMorePass needMorePass = new NeedMorePass(line, column); - needMorePass.addChild(this); - return Either.ofLeft(needMorePass); + return Either.ofLeft(this); } @Override @@ -89,9 +87,4 @@ public boolean equals(Object o) { ExprInfix exprInfix = (ExprInfix) o; return operationCode == exprInfix.operationCode; } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), operationCode); - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java index c21772460..34333842d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java @@ -19,7 +19,7 @@ public ExprNumber(Token number, Function parser) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); evaluated.addChild(new ExprNumber(line, column, number)); return Either.ofRight(evaluated); @@ -48,9 +48,4 @@ public boolean equals(Object o) { ExprNumber that = (ExprNumber) o; return number == that.number; } - - @Override - public int hashCode() { - return number; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index c1f187366..8c873a615 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -36,9 +36,9 @@ public void accept(NodeVisitor visitor) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { Node child = getChild(0); - Either childEval = child.eval(currentAddress, expectedSizeBytes, env); + Either childEval = child.eval(currentAddress, expectedSizeBytes, env); if (childEval.isRight()) { int value = childEval.right.getValue(); int result = operation.apply(value); @@ -47,10 +47,7 @@ public Either eval(int currentAddress, int expectedSize evaluated.addChild(new ExprNumber(line, column, result)); return Either.ofRight(evaluated); } - - NeedMorePass needMorePass = new NeedMorePass(line, column); - needMorePass.addChild(this); - return Either.ofLeft(needMorePass); + return Either.ofLeft(this); } @Override @@ -71,9 +68,4 @@ public boolean equals(Object o) { ExprUnary exprUnary = (ExprUnary) o; return operationCode == exprUnary.operationCode; } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), operationCode); - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index b7fda095d..84bbe9208 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -68,9 +68,4 @@ public boolean equals(Object o) { InstrExpr instrExpr = (InstrExpr) o; return opcode == instrExpr.opcode; } - - @Override - public int hashCode() { - return opcode; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java index 079eb71b7..fcf8feeaa 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java @@ -39,9 +39,4 @@ public boolean equals(Object o) { InstrNoArgs that = (InstrNoArgs) o; return opcode == that.opcode; } - - @Override - public int hashCode() { - return opcode; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java index 7a96e3e5a..7d8637f93 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java @@ -43,11 +43,4 @@ public boolean equals(Object o) { if (opcode != instrReg.opcode) return false; return reg == instrReg.reg; } - - @Override - public int hashCode() { - int result = opcode; - result = 31 * result + reg; - return result; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java index acbdf045d..d841ab869 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java @@ -44,11 +44,4 @@ public boolean equals(Object o) { if (opcode != that.opcode) return false; return reg == that.reg; } - - @Override - public int hashCode() { - int result = opcode; - result = 31 * result + reg; - return result; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java index 7f157a7b5..72ed0211c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java @@ -43,11 +43,4 @@ public boolean equals(Object o) { if (opcode != that.opcode) return false; return regPair == that.regPair; } - - @Override - public int hashCode() { - int result = opcode; - result = 31 * result + regPair; - return result; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java index 428de2770..6211be8a5 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java @@ -44,11 +44,4 @@ public boolean equals(Object o) { if (opcode != that.opcode) return false; return regPair == that.regPair; } - - @Override - public int hashCode() { - int result = opcode; - result = 31 * result + regPair; - return result; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java index ad857755d..8ee1887ba 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java @@ -46,12 +46,4 @@ public boolean equals(Object o) { if (srcReg != that.srcReg) return false; return dstReg == that.dstReg; } - - @Override - public int hashCode() { - int result = opcode; - result = 31 * result + srcReg; - result = 31 * result + dstReg; - return result; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java index 3d614778a..02b7bc265 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java @@ -42,9 +42,4 @@ public boolean equals(Object o) { PseudoEqu pseudoEqu = (PseudoEqu) o; return Objects.equals(id, pseudoEqu.id); } - - @Override - public int hashCode() { - return id != null ? id.hashCode() : 0; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java index 7a03ecf35..7509d3f33 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java @@ -42,9 +42,4 @@ public boolean equals(Object o) { PseudoInclude that = (PseudoInclude) o; return Objects.equals(filename, that.filename); } - - @Override - public int hashCode() { - return filename != null ? filename.hashCode() : 0; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java index 8cf36b4fc..64ccc04eb 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java @@ -22,17 +22,15 @@ public PseudoLabel(Token label) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); evaluated.addChild(new ExprNumber(line, column, currentAddress)); return Either.ofRight(evaluated); } - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env, boolean evalLeft) { + public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env, boolean evalLeft) { if (evalLeft) { - NeedMorePass needMorePass = new NeedMorePass(line, column); - needMorePass.addChild(this); - return Either.ofLeft(needMorePass); + return Either.ofLeft(this); } return eval(currentAddress, expectedSizeBytes, env); } @@ -60,9 +58,4 @@ public boolean equals(Object o) { PseudoLabel pseudoLabel1 = (PseudoLabel) o; return Objects.equals(label, pseudoLabel1.label); } - - @Override - public int hashCode() { - return label != null ? label.hashCode() : 0; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java index aa9b147e1..f709ddc14 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java @@ -42,9 +42,4 @@ public boolean equals(Object o) { PseudoMacroCall that = (PseudoMacroCall) o; return Objects.equals(id, that.id); } - - @Override - public int hashCode() { - return id != null ? id.hashCode() : 0; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java index ce38e29de..c520a87ae 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java @@ -39,11 +39,6 @@ public boolean equals(Object o) { return Objects.equals(id, that.id); } - @Override - public int hashCode() { - return id != null ? id.hashCode() : 0; - } - public PseudoMacroDef mkCopy() { return new PseudoMacroDef(line, column, id); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java index 4dd7b180a..9a2055a62 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java @@ -42,9 +42,4 @@ public boolean equals(Object o) { PseudoSet pseudoSet = (PseudoSet) o; return Objects.equals(id, pseudoSet.id); } - - @Override - public int hashCode() { - return id != null ? id.hashCode() : 0; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 6915c9bca..47569918d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -37,7 +37,7 @@ public class EvaluateExprVisitor extends NodeVisitor { private int expectedBytes = 0; private boolean doNotEvaluateCurrentAddress = false; - private Either latestEval; + private Either latestEval; private Set needMorePassThings = new HashSet<>(); private final Map> macroArguments = new HashMap<>(); private String currentMacro; @@ -123,7 +123,7 @@ public void visit(PseudoSet node) { @Override public void visit(PseudoLabel node) { - Either eval = node.eval(currentAddress, 2, env, doNotEvaluateCurrentAddress); + Either eval = node.eval(currentAddress, 2, env, doNotEvaluateCurrentAddress); env.put(normalizeId(node.label), eval); if (eval.isRight()) { node.remove(); // we don't need to re-evaluate label @@ -214,7 +214,7 @@ public void visit(PseudoMacroArgument node) { @Override public void visit(DataPlainString node) { - Either eval = node.eval(currentAddress, -1, env); + Either eval = node.eval(currentAddress, -1, env); node.remove().ifPresent(p -> p.addChild(eval.right)); currentAddress += eval.right.getSizeBytes(); } @@ -251,8 +251,10 @@ public void visit(ExprId node) { } private void evalExpr(Node node) { + System.out.println("EVAL " + node.toString()); latestEval = node.eval(currentAddress, expectedBytes, env); if (latestEval.isRight()) { + System.out.println("RIG: " + node + " " + node.getParent().get()); node.remove().ifPresent(p -> p.addChild(latestEval.right)); } else { needMorePassThings.add(node); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index 62de4125d..4d6310143 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -2,20 +2,27 @@ import net.emustudio.plugins.compiler.as8080.Either; import net.emustudio.plugins.compiler.as8080.ast.Evaluated; -import net.emustudio.plugins.compiler.as8080.ast.NeedMorePass; +import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprCurrentAddress; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoIf; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoLabel; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoSet; import org.junit.Test; -import static net.emustudio.plugins.compiler.as8080.As8080Parser.OP_ADD; +import java.util.List; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; import static net.emustudio.plugins.compiler.as8080.CompileError.ERROR_AMBIGUOUS_EXPRESSION; import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; import static org.junit.Assert.assertEquals; @@ -117,7 +124,7 @@ public void testEvaluateDSambiguous() { } @Test - public void testEvaluateDScontReference() { + public void testEvaluateDSconstReference() { Program program = new Program(); program .addChild(new DataDS(0, 0) @@ -130,7 +137,7 @@ public void testEvaluateDScontReference() { assertTrue(program.env().hasNoErrors()); - Either label = program.env().get("label").orElseThrow(); + Either label = program.env().get("label").orElseThrow(); assertTrue(label.isRight()); assertEquals(5, label.right.getSizeBytes()); assertEquals(0, label.right.address); @@ -143,5 +150,107 @@ public void testEvaluateDScontReference() { ); } + @Test + public void testEvaluateEQUfivePasses() { + Program program = new Program(); + program + .addChild(new PseudoEqu(0, 0, "one") + .addChild(new ExprId(0, 0, "two"))) + .addChild(new PseudoEqu(0, 0, "two") + .addChild(new ExprId(0, 0, "three"))) + .addChild(new PseudoEqu(0, 0, "three") + .addChild(new ExprId(0, 0, "four"))) + .addChild(new PseudoEqu(0, 0, "four") + .addChild(new ExprId(0, 0, "five"))) + .addChild(new PseudoEqu(0, 0, "five") + .addChild(new ExprCurrentAddress(0, 0))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + assertTrees(new Program(), program); + + List constants = List.of("one", "two", "three", "four", "five"); + for (String c : constants) { + Either constant = program.env().get(c).orElseThrow(); + assertTrue(constant.isRight()); + assertEquals(0, constant.right.getSizeBytes()); + assertEquals(0, constant.right.address); + assertEquals(0, constant.right.getValue()); + } + } + + @Test + public void testEvaluateIFwithForwardConst() { + Program program = new Program(); + program + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoIf(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprCurrentAddress(0, 0)))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + System.out.println(program); + + assertTrees( + new Program() + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0, 0, 0, 1) + .addChild(new ExprNumber(0, 0, 6)))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 2, 1) + .addChild(new ExprNumber(0, 0, 0)))), + program + ); + } + + @Test + public void testEvaluateSETforwardTwoTimes() { + Program program = new Program(); + program + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new ExprNumber(0, 0, 2))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + System.out.println(program); + System.out.println(program.env()); + + assertTrees( + new Program() + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0, 0, 0, 1) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new Evaluated(0, 0, 2, 0) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) + .addChild(new Evaluated(0, 0, 2, 1) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new Evaluated(0, 0, 4, 0) + .addChild(new ExprNumber(0, 0, 2)))), + program + ); + } + } From e91ad12095f4c2ca41f17a9079d9ee36c64e0cf7 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 31 Dec 2021 16:45:53 +0100 Subject: [PATCH 063/314] [#201] as-8080: wip --- .../compiler/as8080/ast/Evaluated.java | 36 +----------- .../plugins/compiler/as8080/ast/Node.java | 17 ++++-- .../compiler/as8080/ast/NodeVisitor.java | 4 ++ .../as8080/ast/data/DataPlainString.java | 5 +- .../as8080/ast/expr/ExprCurrentAddress.java | 8 +-- .../compiler/as8080/ast/expr/ExprId.java | 2 +- .../compiler/as8080/ast/expr/ExprInfix.java | 8 +-- .../compiler/as8080/ast/expr/ExprNumber.java | 4 +- .../compiler/as8080/ast/expr/ExprUnary.java | 6 +- .../as8080/ast/pseudo/PseudoIfExpression.java | 20 +++++++ .../as8080/ast/pseudo/PseudoLabel.java | 11 ++-- .../as8080/visitors/CreateDataVisitor.java | 8 +-- .../as8080/visitors/CreateInstrVisitor.java | 8 +-- .../as8080/visitors/CreateLineVisitor.java | 6 +- .../as8080/visitors/CreateProgramVisitor.java | 2 +- .../as8080/visitors/CreatePseudoVisitor.java | 17 +++--- .../{Visitors.java => CreateVisitors.java} | 2 +- .../as8080/visitors/EvaluateExprVisitor.java | 36 +++++++----- .../visitors/EvaluateExprVisitorTest.java | 55 ++++++++++--------- 19 files changed, 131 insertions(+), 124 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIfExpression.java rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/{Visitors.java => CreateVisitors.java} (92%) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java index 7d10e96df..39ef53d29 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java @@ -2,17 +2,10 @@ import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; -import java.util.Objects; - public class Evaluated extends Node { - public final int address; - private int sizeBytes; - public Evaluated(int line, int column, int address, int sizeBytes) { + public Evaluated(int line, int column) { super(line, column); - this.address = address; - this.sizeBytes = sizeBytes; - // children are sizeBytes * 1-byte ExprNumbers } @@ -20,38 +13,13 @@ public int getValue() { return ((ExprNumber) getChild(0)).number; } - public int getSizeBytes() { - return sizeBytes; - } - - public void setSizeBytes(int sizeBytes) { - this.sizeBytes = sizeBytes; - } - @Override protected Node mkCopy() { - return new Evaluated(line, column, address, sizeBytes); + return new Evaluated(line, column); } @Override public void accept(NodeVisitor visitor) { visitor.visit(this); } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - Evaluated evaluated = (Evaluated) o; - return address == evaluated.address && sizeBytes == evaluated.sizeBytes; - } - - @Override - protected String toStringShallow() { - return "Evaluated(" + - "addr=" + address + - ", size=" + sizeBytes + - ')'; - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index cd44bf798..5f51f78ec 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -10,6 +10,8 @@ public abstract class Node { public final int line; public final int column; + private int address; + public Node(int line, int column) { this.line = line; this.column = column; @@ -66,7 +68,15 @@ public Optional remove() { return parent; } - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + public int getAddress() { + return address; + } + + public void setAddress(int address) { + this.address = address; + } + + public Either eval(int currentAddress, NameSpace env) { return Either.ofLeft(this); } @@ -110,9 +120,4 @@ public boolean equals(Object o) { Node node = (Node) o; return line == node.line && column == node.column && Objects.equals(parent, node.parent); } - - @Override - public int hashCode() { - return System.identityHashCode(this); - } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java index 367169f39..1ddf64449 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java @@ -106,6 +106,10 @@ public void visit(PseudoIf node) { visitChildren(node); } + public void visit(PseudoIfExpression node) { + visitChildren(node); + } + public void visit(PseudoInclude node) { visitChildren(node); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java index e282d0d29..087cbd313 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java @@ -22,9 +22,8 @@ public DataPlainString(Token string) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { - int sizeBytes = string.length(); - Evaluated evaluated = new Evaluated(line, column, currentAddress, sizeBytes); + public Either eval(int currentAddress, NameSpace env) { + Evaluated evaluated = new Evaluated(line, column); for (byte b : string.getBytes()) { evaluated.addChild(new ExprNumber(line, column, b)); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java index 0c6b7bca2..576adc0eb 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java @@ -20,13 +20,13 @@ protected Node mkCopy() { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { - Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); + public Either eval(int currentAddress, NameSpace env) { + Evaluated evaluated = new Evaluated(line, column); evaluated.addChild(new ExprNumber(line, column, currentAddress)); return Either.ofRight(evaluated); } - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env, boolean evalLeft) { - return evalLeft ? Either.ofLeft(this) : eval(currentAddress, expectedSizeBytes, env); + public Either eval(int currentAddress, NameSpace env, boolean evalLeft) { + return evalLeft ? Either.ofLeft(this) : eval(currentAddress, env); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java index d2b0c199b..92275a1b2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java @@ -21,7 +21,7 @@ public ExprId(Token id) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + public Either eval(int currentAddress, NameSpace env) { return env.get(normalizeId(id)).orElseGet(() -> Either.ofLeft(this)); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index 1dd87e9f6..e7d24f223 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -49,19 +49,19 @@ public void accept(NodeVisitor visitor) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + public Either eval(int currentAddress, NameSpace env) { Node leftChild = getChild(0); Node rightChild = getChild(1); - Either left = leftChild.eval(currentAddress, expectedSizeBytes, env); - Either right = rightChild.eval(currentAddress, expectedSizeBytes, env); + Either left = leftChild.eval(currentAddress, env); + Either right = rightChild.eval(currentAddress, env); if (left.isRight() && right.isRight()) { int l = left.right.getValue(); int r = right.right.getValue(); int result = operation.apply(l, r); - Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); + Evaluated evaluated = new Evaluated(line, column); evaluated.addChild(new ExprNumber(line, column, result)); return Either.ofRight(evaluated); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java index 34333842d..409e27ede 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java @@ -19,8 +19,8 @@ public ExprNumber(Token number, Function parser) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { - Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); + public Either eval(int currentAddress, NameSpace env) { + Evaluated evaluated = new Evaluated(line, column); evaluated.addChild(new ExprNumber(line, column, number)); return Either.ofRight(evaluated); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index 8c873a615..60e7f3f94 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -36,14 +36,14 @@ public void accept(NodeVisitor visitor) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { + public Either eval(int currentAddress, NameSpace env) { Node child = getChild(0); - Either childEval = child.eval(currentAddress, expectedSizeBytes, env); + Either childEval = child.eval(currentAddress, env); if (childEval.isRight()) { int value = childEval.right.getValue(); int result = operation.apply(value); - Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); + Evaluated evaluated = new Evaluated(line, column); evaluated.addChild(new ExprNumber(line, column, result)); return Either.ofRight(evaluated); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIfExpression.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIfExpression.java new file mode 100644 index 000000000..e0fa02978 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIfExpression.java @@ -0,0 +1,20 @@ +package net.emustudio.plugins.compiler.as8080.ast.pseudo; + +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; + +public class PseudoIfExpression extends Node { + public PseudoIfExpression(int line, int column) { + super(line, column); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new PseudoIfExpression(line, column); + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java index 64ccc04eb..d1614878d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java @@ -22,17 +22,14 @@ public PseudoLabel(Token label) { } @Override - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env) { - Evaluated evaluated = new Evaluated(line, column, currentAddress, expectedSizeBytes); + public Either eval(int currentAddress, NameSpace env) { + Evaluated evaluated = new Evaluated(line, column); evaluated.addChild(new ExprNumber(line, column, currentAddress)); return Either.ofRight(evaluated); } - public Either eval(int currentAddress, int expectedSizeBytes, NameSpace env, boolean evalLeft) { - if (evalLeft) { - return Either.ofLeft(this); - } - return eval(currentAddress, expectedSizeBytes, env); + public Either eval(int currentAddress, NameSpace env, boolean evalLeft) { + return evalLeft ? Either.ofLeft(this) : eval(currentAddress, env); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java index b9b4d1ac5..714d4832a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java @@ -18,9 +18,9 @@ public Node visitDataDB(DataDBContext ctx) { for (RDBdataContext next : ctx.rDBdata()) { if (next.expr != null) { - db.addChild(Visitors.expr.visit(next.expr)); + db.addChild(CreateVisitors.expr.visit(next.expr)); } else if (next.instr != null) { - db.addChild(Visitors.instr.visit(next.instr)); + db.addChild(CreateVisitors.instr.visit(next.instr)); } else { DataPlainString str = new DataPlainString(next.str); db.addChild(str); @@ -36,7 +36,7 @@ public Node visitDataDW(DataDWContext ctx) { for (RDWdataContext next : ctx.rDWdata()) { if (next.expr != null) { - dw.addChild(Visitors.expr.visit(next.expr)); + dw.addChild(CreateVisitors.expr.visit(next.expr)); } } @@ -47,7 +47,7 @@ public Node visitDataDW(DataDWContext ctx) { public Node visitDataDS(DataDSContext ctx) { Token start = ctx.getStart(); DataDS ds = new DataDS(start.getLine(), start.getCharPositionInLine()); - ds.addChild(Visitors.expr.visit(ctx.data)); + ds.addChild(CreateVisitors.expr.visit(ctx.data)); return ds; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateInstrVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateInstrVisitor.java index 1a9e959bc..970ef4f1e 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateInstrVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateInstrVisitor.java @@ -30,28 +30,28 @@ public Node visitInstrRegPair(As8080Parser.InstrRegPairContext ctx) { @Override public Node visitInstrRegPairExpr(As8080Parser.InstrRegPairExprContext ctx) { InstrRegPairExpr instr = new InstrRegPairExpr(ctx.opcode, ctx.regpair); - instr.addChild(Visitors.expr.visit(ctx.expr)); + instr.addChild(CreateVisitors.expr.visit(ctx.expr)); return instr; } @Override public Node visitInstrRegExpr(As8080Parser.InstrRegExprContext ctx) { InstrRegExpr instr = new InstrRegExpr(ctx.opcode, ctx.reg.getStart()); - instr.addChild(Visitors.expr.visit(ctx.expr)); + instr.addChild(CreateVisitors.expr.visit(ctx.expr)); return instr; } @Override public Node visitInstrExpr(As8080Parser.InstrExprContext ctx) { InstrExpr instr = new InstrExpr(ctx.opcode); - instr.addChild(Visitors.expr.visit(ctx.expr)); + instr.addChild(CreateVisitors.expr.visit(ctx.expr)); return instr; } @Override public Node visitInstr8bitExpr(As8080Parser.Instr8bitExprContext ctx) { InstrExpr instr = new InstrExpr(ctx.opcode); - instr.addChild(Visitors.expr.visit(ctx.expr)); + instr.addChild(CreateVisitors.expr.visit(ctx.expr)); return instr; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java index a66cc4616..621285cce 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java @@ -29,11 +29,11 @@ public Node visitRLine(As8080Parser.RLineContext ctx) { @Override public Node visitRStatement(As8080Parser.RStatementContext ctx) { if (ctx.instr != null) { - return Visitors.instr.visit(ctx.instr); + return CreateVisitors.instr.visit(ctx.instr); } else if (ctx.data != null) { - return Visitors.data.visit(ctx.data); + return CreateVisitors.data.visit(ctx.data); } else if (ctx.pseudo != null) { - return Visitors.pseudo.visit(ctx.pseudo); + return CreateVisitors.pseudo.visit(ctx.pseudo); } throw new IllegalStateException("No statement defined!"); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java index 7ebe6f3be..0dab1295f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateProgramVisitor.java @@ -19,7 +19,7 @@ public CreateProgramVisitor(Program program) { @Override public Program visitRLine(As8080Parser.RLineContext ctx) { - Node statement = Visitors.line.visitRLine(ctx); + Node statement = CreateVisitors.line.visitRLine(ctx); if (statement != null) { program.addChild(statement); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java index c7b707946..7a29c3842 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java @@ -14,21 +14,21 @@ public class CreatePseudoVisitor extends As8080ParserBaseVisitor { public Node visitPseudoOrg(PseudoOrgContext ctx) { Token start = ctx.getStart(); PseudoOrg pseudo = new PseudoOrg(start.getLine(), start.getCharPositionInLine()); - pseudo.addChild(Visitors.expr.visit(ctx.expr)); + pseudo.addChild(CreateVisitors.expr.visit(ctx.expr)); return pseudo; } @Override public Node visitPseudoEqu(PseudoEquContext ctx) { PseudoEqu pseudo = new PseudoEqu(ctx.id); - pseudo.addChild(Visitors.expr.visit(ctx.expr)); + pseudo.addChild(CreateVisitors.expr.visit(ctx.expr)); return pseudo; } @Override public Node visitPseudoSet(PseudoSetContext ctx) { PseudoSet pseudo = new PseudoSet(ctx.id); - pseudo.addChild(Visitors.expr.visit(ctx.expr)); + pseudo.addChild(CreateVisitors.expr.visit(ctx.expr)); return pseudo; } @@ -37,9 +37,12 @@ public Node visitPseudoIf(PseudoIfContext ctx) { Token start = ctx.getStart(); PseudoIf pseudo = new PseudoIf(start.getLine(), start.getCharPositionInLine()); - pseudo.addChild(Visitors.expr.visit(ctx.expr)); + Node expr = CreateVisitors.expr.visit(ctx.expr); + PseudoIfExpression ifExpr = new PseudoIfExpression(expr.line, expr.column); + ifExpr.addChild(expr); + pseudo.addChild(ifExpr); for (RLineContext line : ctx.rLine()) { - pseudo.addChild(Visitors.line.visitRLine(line)); + pseudo.addChild(CreateVisitors.line.visitRLine(line)); } return pseudo; } @@ -56,7 +59,7 @@ public Node visitPseudoMacroDef(PseudoMacroDefContext ctx) { } } for (RLineContext line : ctx.rLine()) { - pseudo.addChild(Visitors.line.visitRLine(line)); + pseudo.addChild(CreateVisitors.line.visitRLine(line)); } return pseudo; } @@ -68,7 +71,7 @@ public Node visitPseudoMacroCall(PseudoMacroCallContext ctx) { if (ctx.args != null) { for (RExpressionContext next : ctx.args.rExpression()) { PseudoMacroArgument argument = new PseudoMacroArgument(); - pseudo.addChild(argument.addChild(Visitors.expr.visit(next))); + pseudo.addChild(argument.addChild(CreateVisitors.expr.visit(next))); } } return pseudo; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateVisitors.java similarity index 92% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateVisitors.java index a832c27ac..006901480 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/Visitors.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateVisitors.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080.visitors; -public class Visitors { +public class CreateVisitors { static CreatePseudoVisitor pseudo = new CreatePseudoVisitor(); static CreateExprVisitor expr = new CreateExprVisitor(); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 47569918d..43fcc9ce5 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -79,25 +79,25 @@ public void visit(Program node) { @Override public void visit(DataDB node) { + node.setAddress(currentAddress); expectedBytes = 1; visitChildren(node); } @Override public void visit(DataDW node) { + node.setAddress(currentAddress); expectedBytes = 2; visitChildren(node); } @Override public void visit(DataDS node) { + node.setAddress(currentAddress); expectedBytes = 0; visitChildren(node); if (latestEval.isRight()) { - // TODO: check 2 bytes - int value = latestEval.right.getValue(); - currentAddress += value; - latestEval.right.setSizeBytes(value); + currentAddress += latestEval.right.getValue(); } else { // we don't know now how the address changes since we can't evaluate the expr yet doNotEvaluateCurrentAddress = true; @@ -123,7 +123,7 @@ public void visit(PseudoSet node) { @Override public void visit(PseudoLabel node) { - Either eval = node.eval(currentAddress, 2, env, doNotEvaluateCurrentAddress); + Either eval = node.eval(currentAddress, env, doNotEvaluateCurrentAddress); env.put(normalizeId(node.label), eval); if (eval.isRight()) { node.remove(); // we don't need to re-evaluate label @@ -134,6 +134,7 @@ public void visit(PseudoLabel node) { @Override public void visit(PseudoOrg node) { + node.setAddress(currentAddress); expectedBytes = 0; visitChildren(node); if (latestEval.isRight()) { @@ -147,9 +148,13 @@ public void visit(PseudoOrg node) { @Override public void visit(PseudoIf node) { expectedBytes = 0; - visit(node.getChild(0)); + Optional expr = node + .collectChild(PseudoIfExpression.class) + .flatMap(p -> { + visit(p); + return p.collectChild(Evaluated.class); + }); - Optional expr = node.collectChild(Evaluated.class); boolean includeBlock = expr.filter(p -> p.getValue() != 0).isPresent(); boolean excludeBlock = expr.filter(p -> p.getValue() == 0).isPresent(); @@ -168,6 +173,7 @@ public void visit(PseudoIf node) { @Override public void visit(InstrExpr node) { + node.setAddress(currentAddress); expectedBytes = node.getExprSizeBytes(); visitChildren(node); currentAddress++; // opcode @@ -175,6 +181,7 @@ public void visit(InstrExpr node) { @Override public void visit(InstrRegExpr node) { + node.setAddress(currentAddress); expectedBytes = 1; visitChildren(node); currentAddress++; // opcode @@ -182,6 +189,7 @@ public void visit(InstrRegExpr node) { @Override public void visit(InstrRegPairExpr node) { + node.setAddress(currentAddress); expectedBytes = 2; visitChildren(node); currentAddress++; // opcode @@ -214,9 +222,9 @@ public void visit(PseudoMacroArgument node) { @Override public void visit(DataPlainString node) { - Either eval = node.eval(currentAddress, -1, env); + Either eval = node.eval(currentAddress, env); node.remove().ifPresent(p -> p.addChild(eval.right)); - currentAddress += eval.right.getSizeBytes(); + currentAddress += node.string.length(); } @Override @@ -251,11 +259,13 @@ public void visit(ExprId node) { } private void evalExpr(Node node) { - System.out.println("EVAL " + node.toString()); - latestEval = node.eval(currentAddress, expectedBytes, env); + latestEval = node.eval(currentAddress, env); if (latestEval.isRight()) { - System.out.println("RIG: " + node + " " + node.getParent().get()); - node.remove().ifPresent(p -> p.addChild(latestEval.right)); + node.remove().ifPresent(p -> { + Evaluated evaluated = (Evaluated) latestEval.right.copy(); + evaluated.setAddress(currentAddress); + p.addChild(evaluated); + }); } else { needMorePassThings.add(node); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index 4d6310143..3ddfd203c 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -14,10 +14,7 @@ import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoEqu; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoIf; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoLabel; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoSet; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; import org.junit.Test; import java.util.List; @@ -45,9 +42,9 @@ public void testEvaluateDB() { assertTrees( new Program() .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 0, 1) - .addChild(new ExprNumber(0, 0, 3)) - ).addChild(new Evaluated(0, 0, 1, 5) + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 'h')) .addChild(new ExprNumber(0, 0, 'e')) .addChild(new ExprNumber(0, 0, 'l')) @@ -74,13 +71,15 @@ public void testEvaluateDW() { assertTrees( new Program() .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0, 0, 2) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 3)))) .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0, 2, 2) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 0)))), program ); + assertEquals(0, program.getChild(0).getAddress()); + assertEquals(2, program.getChild(1).getAddress()); } @Test @@ -100,13 +99,15 @@ public void testEvaluateDS() { assertTrees( new Program() .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0, 0, 0, 0) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 3)))) .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 3, 1) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 0)))), program ); + assertEquals(0, program.getChild(0).getAddress()); + assertEquals(3, program.getChild(1).getAddress()); } @Test @@ -139,13 +140,13 @@ public void testEvaluateDSconstReference() { Either label = program.env().get("label").orElseThrow(); assertTrue(label.isRight()); - assertEquals(5, label.right.getSizeBytes()); - assertEquals(0, label.right.address); + assertEquals(0, label.right.getAddress()); assertTrees( new Program() .addChild(new DataDS(0, 0) - .addChild(new ExprId(0, 0, "label"))), + .addChild(new Evaluated(0,0) + .addChild(new ExprNumber(0,0, 5)))), program ); } @@ -175,8 +176,7 @@ public void testEvaluateEQUfivePasses() { for (String c : constants) { Either constant = program.env().get(c).orElseThrow(); assertTrue(constant.isRight()); - assertEquals(0, constant.right.getSizeBytes()); - assertEquals(0, constant.right.address); + assertEquals(0, constant.right.getAddress()); assertEquals(0, constant.right.getValue()); } } @@ -188,9 +188,10 @@ public void testEvaluateIFwithForwardConst() { .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) .addChild(new ExprId(0, 0, "const"))) .addChild(new PseudoIf(0, 0) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 2)))) .addChild(new InstrExpr(0, 0, OPCODE_RST) .addChild(new ExprNumber(0, 0, 0)))) .addChild(new PseudoEqu(0, 0, "const") @@ -201,18 +202,18 @@ public void testEvaluateIFwithForwardConst() { EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); - System.out.println(program); - assertTrees( new Program() .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0, 0, 0, 1) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 6)))) .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 2, 1) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 0)))), program ); + assertEquals(0, program.getChild(0).getAddress()); + assertEquals(2, program.getChild(1).getAddress()); } @Test @@ -237,16 +238,16 @@ public void testEvaluateSETforwardTwoTimes() { assertTrees( new Program() .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0, 0, 0, 1) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 1)))) .addChild(new PseudoSet(0, 0, "const") - .addChild(new Evaluated(0, 0, 2, 0) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 1)))) .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) - .addChild(new Evaluated(0, 0, 2, 1) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 1)))) .addChild(new PseudoSet(0, 0, "const") - .addChild(new Evaluated(0, 0, 4, 0) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 2)))), program ); From 07fa06e8ec74514fd695e7dc09521d0902b72e13 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 1 Jan 2022 16:55:24 +0100 Subject: [PATCH 064/314] [#201] as-8080: wip --- .../compiler/as8080/ast/NameSpace.java | 8 +-- .../plugins/compiler/as8080/ast/Node.java | 11 ++-- .../as8080/ast/data/DataPlainString.java | 11 ++-- .../as8080/ast/expr/ExprCurrentAddress.java | 16 +++-- .../compiler/as8080/ast/expr/ExprId.java | 11 ++-- .../compiler/as8080/ast/expr/ExprInfix.java | 23 ++++--- .../compiler/as8080/ast/expr/ExprNumber.java | 11 ++-- .../compiler/as8080/ast/expr/ExprUnary.java | 30 +++++---- .../as8080/ast/pseudo/PseudoLabel.java | 15 +++-- .../as8080/visitors/EvaluateExprVisitor.java | 66 +++++++++---------- .../visitors/EvaluateExprVisitorTest.java | 54 +++++++++++---- 11 files changed, 153 insertions(+), 103 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java index 05fb1c4a3..fa4457987 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java @@ -7,7 +7,7 @@ public class NameSpace { private final List errors = new ArrayList<>(); - private final Map> definitions = new HashMap<>(); + private final Map> definitions = new HashMap<>(); public void error(CompileError error) { errors.add(Objects.requireNonNull(error)); @@ -21,7 +21,7 @@ public boolean hasNoErrors() { return errors.isEmpty(); } - public void put(String id, Either value) { + public void put(String id, Optional value) { definitions.put(id, value); } @@ -29,8 +29,8 @@ public void remove(String id) { definitions.remove(id); } - public Optional> get(String id) { - return Optional.ofNullable(definitions.get(id)); + public Optional get(String id) { + return Optional.ofNullable(definitions.get(id)).flatMap(e -> e); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 5f51f78ec..f7f5f526d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -1,8 +1,9 @@ package net.emustudio.plugins.compiler.as8080.ast; -import net.emustudio.plugins.compiler.as8080.Either; - -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; public abstract class Node { protected Node parent; @@ -76,8 +77,8 @@ public void setAddress(int address) { this.address = address; } - public Either eval(int currentAddress, NameSpace env) { - return Either.ofLeft(this); + public Optional eval(int currentAddress, NameSpace env) { + return Optional.empty(); } public void accept(NodeVisitor visitor) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java index 087cbd313..09dfa7b90 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java @@ -1,11 +1,14 @@ package net.emustudio.plugins.compiler.as8080.ast.data; -import net.emustudio.plugins.compiler.as8080.Either; -import net.emustudio.plugins.compiler.as8080.ast.*; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import org.antlr.v4.runtime.Token; import java.util.Objects; +import java.util.Optional; import static net.emustudio.plugins.compiler.as8080.ParsingUtils.parseLitString; @@ -22,12 +25,12 @@ public DataPlainString(Token string) { } @Override - public Either eval(int currentAddress, NameSpace env) { + public Optional eval(int currentAddress, NameSpace env) { Evaluated evaluated = new Evaluated(line, column); for (byte b : string.getBytes()) { evaluated.addChild(new ExprNumber(line, column, b)); } - return Either.ofRight(evaluated); + return Optional.of(evaluated); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java index 576adc0eb..5cfc696db 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java @@ -1,7 +1,11 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import net.emustudio.plugins.compiler.as8080.Either; -import net.emustudio.plugins.compiler.as8080.ast.*; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; + +import java.util.Optional; public class ExprCurrentAddress extends Node { @@ -20,13 +24,13 @@ protected Node mkCopy() { } @Override - public Either eval(int currentAddress, NameSpace env) { + public Optional eval(int currentAddress, NameSpace env) { Evaluated evaluated = new Evaluated(line, column); evaluated.addChild(new ExprNumber(line, column, currentAddress)); - return Either.ofRight(evaluated); + return Optional.of(evaluated); } - public Either eval(int currentAddress, NameSpace env, boolean evalLeft) { - return evalLeft ? Either.ofLeft(this) : eval(currentAddress, env); + public Optional eval(int currentAddress, NameSpace env, boolean evalLeft) { + return evalLeft ? Optional.empty() : eval(currentAddress, env); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java index 92275a1b2..1ae7c83eb 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java @@ -1,10 +1,13 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import net.emustudio.plugins.compiler.as8080.Either; -import net.emustudio.plugins.compiler.as8080.ast.*; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.Objects; +import java.util.Optional; import static net.emustudio.plugins.compiler.as8080.ParsingUtils.normalizeId; @@ -21,8 +24,8 @@ public ExprId(Token id) { } @Override - public Either eval(int currentAddress, NameSpace env) { - return env.get(normalizeId(id)).orElseGet(() -> Either.ofLeft(this)); + public Optional eval(int currentAddress, NameSpace env) { + return env.get(normalizeId(id)); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index e7d24f223..d623b08c4 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -1,12 +1,15 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import net.emustudio.plugins.compiler.as8080.Either; -import net.emustudio.plugins.compiler.as8080.ast.*; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.function.BiFunction; import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; @@ -49,24 +52,24 @@ public void accept(NodeVisitor visitor) { } @Override - public Either eval(int currentAddress, NameSpace env) { + public Optional eval(int currentAddress, NameSpace env) { Node leftChild = getChild(0); Node rightChild = getChild(1); - Either left = leftChild.eval(currentAddress, env); - Either right = rightChild.eval(currentAddress, env); + Optional left = leftChild.eval(currentAddress, env); + Optional right = rightChild.eval(currentAddress, env); - if (left.isRight() && right.isRight()) { - int l = left.right.getValue(); - int r = right.right.getValue(); + if (left.isPresent() && right.isPresent()) { + int l = left.get().getValue(); + int r = right.get().getValue(); int result = operation.apply(l, r); Evaluated evaluated = new Evaluated(line, column); evaluated.addChild(new ExprNumber(line, column, result)); - return Either.ofRight(evaluated); + return Optional.of(evaluated); } - return Either.ofLeft(this); + return Optional.empty(); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java index 409e27ede..17ad56dcd 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java @@ -1,9 +1,12 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import net.emustudio.plugins.compiler.as8080.Either; -import net.emustudio.plugins.compiler.as8080.ast.*; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; +import java.util.Optional; import java.util.function.Function; public class ExprNumber extends Node { @@ -19,10 +22,10 @@ public ExprNumber(Token number, Function parser) { } @Override - public Either eval(int currentAddress, NameSpace env) { + public Optional eval(int currentAddress, NameSpace env) { Evaluated evaluated = new Evaluated(line, column); evaluated.addChild(new ExprNumber(line, column, number)); - return Either.ofRight(evaluated); + return Optional.of(evaluated); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index 60e7f3f94..3414629df 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -1,18 +1,21 @@ package net.emustudio.plugins.compiler.as8080.ast.expr; -import net.emustudio.plugins.compiler.as8080.Either; -import net.emustudio.plugins.compiler.as8080.ast.*; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.function.Function; import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; public class ExprUnary extends Node { private final static Map> unaryOps = Map.of( - OP_ADD, x -> x, + OP_ADD, x -> x, OP_SUBTRACT, x -> -x, OP_NOT, x -> ~x ); @@ -36,18 +39,17 @@ public void accept(NodeVisitor visitor) { } @Override - public Either eval(int currentAddress, NameSpace env) { - Node child = getChild(0); - Either childEval = child.eval(currentAddress, env); - if (childEval.isRight()) { - int value = childEval.right.getValue(); - int result = operation.apply(value); + public Optional eval(int currentAddress, NameSpace env) { + return getChild(0) + .eval(currentAddress, env) + .map(childEval -> { + int value = childEval.getValue(); + int result = operation.apply(value); - Evaluated evaluated = new Evaluated(line, column); - evaluated.addChild(new ExprNumber(line, column, result)); - return Either.ofRight(evaluated); - } - return Either.ofLeft(this); + Evaluated evaluated = new Evaluated(line, column); + evaluated.addChild(new ExprNumber(line, column, result)); + return evaluated; + }); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java index d1614878d..02ded2fcf 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java @@ -1,11 +1,14 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; -import net.emustudio.plugins.compiler.as8080.Either; -import net.emustudio.plugins.compiler.as8080.ast.*; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import org.antlr.v4.runtime.Token; import java.util.Objects; +import java.util.Optional; import static net.emustudio.plugins.compiler.as8080.ParsingUtils.parseLabel; @@ -22,14 +25,14 @@ public PseudoLabel(Token label) { } @Override - public Either eval(int currentAddress, NameSpace env) { + public Optional eval(int currentAddress, NameSpace env) { Evaluated evaluated = new Evaluated(line, column); evaluated.addChild(new ExprNumber(line, column, currentAddress)); - return Either.ofRight(evaluated); + return Optional.of(evaluated); } - public Either eval(int currentAddress, NameSpace env, boolean evalLeft) { - return evalLeft ? Either.ofLeft(this) : eval(currentAddress, env); + public Optional eval(int currentAddress, NameSpace env, boolean evalLeft) { + return evalLeft ? Optional.empty() : eval(currentAddress, env); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 43fcc9ce5..fb8d2df9a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -1,7 +1,9 @@ package net.emustudio.plugins.compiler.as8080.visitors; -import net.emustudio.plugins.compiler.as8080.Either; -import net.emustudio.plugins.compiler.as8080.ast.*; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; @@ -25,7 +27,7 @@ * - replace ExprCurrentAddress with the current address * - address changes after processing Expr*, DataDS, PseudoOrg * - eliminate or include code block of PseudoIf if expr evaluates to 1 - * + *

* After finishing this visitor, there should be: * - no PseudoEqu * - no ExprId @@ -37,7 +39,7 @@ public class EvaluateExprVisitor extends NodeVisitor { private int expectedBytes = 0; private boolean doNotEvaluateCurrentAddress = false; - private Either latestEval; + private Optional latestEval; private Set needMorePassThings = new HashSet<>(); private final Map> macroArguments = new HashMap<>(); private String currentMacro; @@ -96,12 +98,10 @@ public void visit(DataDS node) { node.setAddress(currentAddress); expectedBytes = 0; visitChildren(node); - if (latestEval.isRight()) { - currentAddress += latestEval.right.getValue(); - } else { - // we don't know now how the address changes since we can't evaluate the expr yet - doNotEvaluateCurrentAddress = true; - } + latestEval.ifPresentOrElse( + e -> currentAddress += e.getValue(), + () -> doNotEvaluateCurrentAddress = true + ); } @Override @@ -109,9 +109,9 @@ public void visit(PseudoEqu node) { expectedBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) visitChildren(node); env.put(normalizeId(node.id), latestEval); - if (latestEval.isRight()) { - node.remove(); // we don't need to re-evaluate the constant - } + + // we don't need to re-evaluate the constant + latestEval.ifPresent(e -> node.remove()); } @Override @@ -123,13 +123,12 @@ public void visit(PseudoSet node) { @Override public void visit(PseudoLabel node) { - Either eval = node.eval(currentAddress, env, doNotEvaluateCurrentAddress); + Optional eval = node.eval(currentAddress, env, doNotEvaluateCurrentAddress); env.put(normalizeId(node.label), eval); - if (eval.isRight()) { - node.remove(); // we don't need to re-evaluate label - } else { - needMorePassThings.add(node); - } + eval.ifPresentOrElse( + e -> node.remove(), // we don't need to re-evaluate label + () -> needMorePassThings.add(node) + ); } @Override @@ -137,12 +136,10 @@ public void visit(PseudoOrg node) { node.setAddress(currentAddress); expectedBytes = 0; visitChildren(node); - if (latestEval.isRight()) { - currentAddress = latestEval.right.getValue(); - } else { - // if we can't evaluate current address now, we cannot evaluate it below too - doNotEvaluateCurrentAddress = true; - } + latestEval.ifPresentOrElse( + e -> currentAddress = e.getValue(), + () -> doNotEvaluateCurrentAddress = true + ); } @Override @@ -222,14 +219,14 @@ public void visit(PseudoMacroArgument node) { @Override public void visit(DataPlainString node) { - Either eval = node.eval(currentAddress, env); - node.remove().ifPresent(p -> p.addChild(eval.right)); + node.eval(currentAddress, env) + .ifPresent(e -> node.remove().ifPresent(p -> p.addChild(e))); currentAddress += node.string.length(); } @Override public void visit(Evaluated node) { - latestEval = Either.ofRight(node); + latestEval = Optional.of(node); currentAddress += expectedBytes; } @@ -260,15 +257,14 @@ public void visit(ExprId node) { private void evalExpr(Node node) { latestEval = node.eval(currentAddress, env); - if (latestEval.isRight()) { - node.remove().ifPresent(p -> { - Evaluated evaluated = (Evaluated) latestEval.right.copy(); + latestEval.ifPresentOrElse( + e -> node.remove().ifPresent(p -> { + Evaluated evaluated = (Evaluated) e.copy(); evaluated.setAddress(currentAddress); p.addChild(evaluated); - }); - } else { - needMorePassThings.add(node); - } + }), + () -> needMorePassThings.add(node) + ); currentAddress += expectedBytes; } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index 3ddfd203c..c3901255c 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -1,8 +1,6 @@ package net.emustudio.plugins.compiler.as8080.visitors; -import net.emustudio.plugins.compiler.as8080.Either; import net.emustudio.plugins.compiler.as8080.ast.Evaluated; -import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; @@ -18,6 +16,7 @@ import org.junit.Test; import java.util.List; +import java.util.Optional; import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; import static net.emustudio.plugins.compiler.as8080.CompileError.ERROR_AMBIGUOUS_EXPRESSION; @@ -138,15 +137,15 @@ public void testEvaluateDSconstReference() { assertTrue(program.env().hasNoErrors()); - Either label = program.env().get("label").orElseThrow(); - assertTrue(label.isRight()); - assertEquals(0, label.right.getAddress()); + Optional label = program.env().get("label"); + assertTrue(label.isPresent()); + assertEquals(0, label.get().getAddress()); assertTrees( new Program() .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0,0) - .addChild(new ExprNumber(0,0, 5)))), + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 5)))), program ); } @@ -174,10 +173,10 @@ public void testEvaluateEQUfivePasses() { List constants = List.of("one", "two", "three", "four", "five"); for (String c : constants) { - Either constant = program.env().get(c).orElseThrow(); - assertTrue(constant.isRight()); - assertEquals(0, constant.right.getAddress()); - assertEquals(0, constant.right.getValue()); + Optional constant = program.env().get(c); + assertTrue(constant.isPresent()); + assertEquals(0, constant.get().getAddress()); + assertEquals(0, constant.get().getValue()); } } @@ -253,5 +252,38 @@ public void testEvaluateSETforwardTwoTimes() { ); } + @Test + public void testEvaluateSETforwardMoreTimes() { + Program program = new Program(); + program + .addChild(new DataDB(0, 0) + .addChild(new ExprId(0, 0, "id"))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + System.out.println(program); + System.out.println(program.env()); + + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 2)))), + program + ); + } } From 188ec4b95f8b262c21d45fd192b858b500e74dcf Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 2 Jan 2022 09:57:50 +0100 Subject: [PATCH 065/314] [#201] as-8080: wip --- .../plugins/compiler/as8080/ast/Node.java | 3 +- .../as8080/visitors/EvaluateExprVisitor.java | 39 +++++++++++++------ .../visitors/EvaluateExprVisitorTest.java | 6 --- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index f7f5f526d..270d639d2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.Optional; public abstract class Node { @@ -119,6 +118,6 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Node node = (Node) o; - return line == node.line && column == node.column && Objects.equals(parent, node.parent); + return line == node.line && column == node.column; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index fb8d2df9a..75dd3ea3b 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -38,9 +38,13 @@ public class EvaluateExprVisitor extends NodeVisitor { private int currentAddress = 0; private int expectedBytes = 0; private boolean doNotEvaluateCurrentAddress = false; + private final Set doNotEvaluateVariables = new HashSet<>(); + private final Set forwardReferences = new HashSet<>(); private Optional latestEval; private Set needMorePassThings = new HashSet<>(); + + private final Map> macroArguments = new HashMap<>(); private String currentMacro; @@ -57,7 +61,12 @@ public void visit(Program node) { while (!needMorePassThings.isEmpty()) { oldNeedMorePass = needMorePassThings; needMorePassThings = new HashSet<>(); + currentAddress = 0; + doNotEvaluateCurrentAddress = false; + doNotEvaluateVariables.clear(); + forwardReferences.clear(); + visitChildren(node); // at least one thing must disappear from "oldNeedMorePass"; @@ -117,8 +126,14 @@ public void visit(PseudoEqu node) { @Override public void visit(PseudoSet node) { expectedBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) - visitChildren(node); - env.put(normalizeId(node.id), latestEval); + String normalizedId = normalizeId(node.id); + if (!doNotEvaluateVariables.contains(normalizedId)) { + visitChildren(node); + env.put(normalizedId, latestEval); + } + if (forwardReferences.contains(normalizedId)) { + doNotEvaluateVariables.add(normalizedId); + } } @Override @@ -210,11 +225,12 @@ public void visit(PseudoMacroArgument node) { expectedBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) visitChildren(node, 1); // expected two children: ExprId and Expr* - node.collectChild(ExprId.class).ifPresent(exprId -> { - String macroParameter = normalizeId(exprId.id); - macroArguments.get(currentMacro).add(macroParameter); - env.put(macroParameter, latestEval); - }); + node.collectChild(ExprId.class) + .ifPresent(exprId -> { + String macroParameter = normalizeId(exprId.id); + macroArguments.get(currentMacro).add(macroParameter); + env.put(macroParameter, latestEval); + }); } @Override @@ -253,16 +269,15 @@ public void visit(ExprCurrentAddress node) { @Override public void visit(ExprId node) { evalExpr(node); + if (latestEval.isEmpty()) { + forwardReferences.add(normalizeId(node.id)); + } } private void evalExpr(Node node) { latestEval = node.eval(currentAddress, env); latestEval.ifPresentOrElse( - e -> node.remove().ifPresent(p -> { - Evaluated evaluated = (Evaluated) e.copy(); - evaluated.setAddress(currentAddress); - p.addChild(evaluated); - }), + e -> node.remove().ifPresent(p -> p.addChild(e)), () -> needMorePassThings.add(node) ); currentAddress += expectedBytes; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index c3901255c..f5257f6e9 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -231,9 +231,6 @@ public void testEvaluateSETforwardTwoTimes() { EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); - System.out.println(program); - System.out.println(program.env()); - assertTrees( new Program() .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) @@ -268,9 +265,6 @@ public void testEvaluateSETforwardMoreTimes() { EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); - System.out.println(program); - System.out.println(program.env()); - assertTrees( new Program() .addChild(new DataDB(0, 0) From 5f977362e33948a040799674562b34a8abdda226 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 2 Jan 2022 10:02:41 +0100 Subject: [PATCH 066/314] [#201] as-8080: wip --- .../as8080/visitors/EvaluateExprVisitor.java | 1 - .../visitors/EvaluateExprVisitorTest.java | 31 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 75dd3ea3b..2317fe721 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -44,7 +44,6 @@ public class EvaluateExprVisitor extends NodeVisitor { private Optional latestEval; private Set needMorePassThings = new HashSet<>(); - private final Map> macroArguments = new HashMap<>(); private String currentMacro; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index f5257f6e9..6cc20182e 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -280,4 +280,35 @@ public void testEvaluateSETforwardMoreTimes() { ); } + @Test + public void testTwoSETthenReference() { + Program program = new Program(); + program + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new DataDB(0, 0) + .addChild(new ExprId(0, 0, "id"))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 2)))), + program + ); + } + } From df3db33d22dae53686d04a02a721e4022259d3b5 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 2 Jan 2022 10:11:52 +0100 Subject: [PATCH 067/314] [#201] comment --- .../as8080/visitors/EvaluateExprVisitor.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 2317fe721..52bc6df5c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -129,9 +129,15 @@ public void visit(PseudoSet node) { if (!doNotEvaluateVariables.contains(normalizedId)) { visitChildren(node); env.put(normalizedId, latestEval); - } - if (forwardReferences.contains(normalizedId)) { - doNotEvaluateVariables.add(normalizedId); + + if (forwardReferences.contains(normalizedId)) { + // if there are forward references for this ID and the variable is redefined (defined more than once), + // the second pass would evaluate the reference with the latest variable redefinition instead of the + // first definition which appears after the reference. The reason is that references are evaluated by + // looking at env - and env contains previously defined values which are "inherited" in upcoming passes. + // So in the second pass env would contain the latest definition from the previous pass. + doNotEvaluateVariables.add(normalizedId); + } } } From bb6b3e54e089c854437fb46d9ad00ef9c091bc2b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 11 Jan 2022 11:54:43 +0100 Subject: [PATCH 068/314] [#201] Tests + fixes + evaluated has 1 child --- .../plugins/compiler/as8080/ast/Node.java | 6 +- .../compiler/as8080/ast/NodeVisitor.java | 5 - .../as8080/ast/data/DataPlainString.java | 59 ----------- .../as8080/ast/expr/ExprCurrentAddress.java | 14 ++- .../compiler/as8080/ast/expr/ExprId.java | 2 +- .../compiler/as8080/ast/expr/ExprInfix.java | 2 +- .../compiler/as8080/ast/expr/ExprNumber.java | 2 +- .../compiler/as8080/ast/expr/ExprUnary.java | 2 +- .../as8080/ast/pseudo/PseudoLabel.java | 14 ++- .../as8080/visitors/CreateDataVisitor.java | 11 ++- .../as8080/visitors/EvaluateExprVisitor.java | 16 ++- .../as8080/visitors/ExpandMacrosVisitor.java | 21 ++-- .../compiler/as8080/ParseDataTest.java | 24 +++-- .../compiler/as8080/ParsePseudoTest.java | 12 ++- .../visitors/EvaluateExprVisitorTest.java | 99 +++++++++++++++++-- .../as8080/visitors/ExpandMacrosTest.java | 2 +- 16 files changed, 158 insertions(+), 133 deletions(-) delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 270d639d2..7b3e5b8a7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -76,7 +76,7 @@ public void setAddress(int address) { this.address = address; } - public Optional eval(int currentAddress, NameSpace env) { + public Optional eval(Optional currentAddress, NameSpace env) { return Optional.empty(); } @@ -116,8 +116,6 @@ public Node copy() { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Node node = (Node) o; - return line == node.line && column == node.column; + return !(o == null || getClass() != o.getClass()); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java index 1ddf64449..14fb04698 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java @@ -4,7 +4,6 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; -import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; import net.emustudio.plugins.compiler.as8080.ast.expr.*; import net.emustudio.plugins.compiler.as8080.ast.instr.*; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; @@ -46,10 +45,6 @@ public void visit(DataDS node) { visitChildren(node); } - public void visit(DataPlainString node) { - visitChildren(node); - } - public void visit(ExprCurrentAddress node) { visitChildren(node); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java deleted file mode 100644 index 09dfa7b90..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataPlainString.java +++ /dev/null @@ -1,59 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.ast.data; - -import net.emustudio.plugins.compiler.as8080.ast.Evaluated; -import net.emustudio.plugins.compiler.as8080.ast.NameSpace; -import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; -import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; -import org.antlr.v4.runtime.Token; - -import java.util.Objects; -import java.util.Optional; - -import static net.emustudio.plugins.compiler.as8080.ParsingUtils.parseLitString; - -public class DataPlainString extends Node { - public final String string; - - public DataPlainString(int line, int column, String string) { - super(line, column); - this.string = Objects.requireNonNull(string); - } - - public DataPlainString(Token string) { - this(string.getLine(), string.getCharPositionInLine(), parseLitString(string)); - } - - @Override - public Optional eval(int currentAddress, NameSpace env) { - Evaluated evaluated = new Evaluated(line, column); - for (byte b : string.getBytes()) { - evaluated.addChild(new ExprNumber(line, column, b)); - } - return Optional.of(evaluated); - } - - @Override - public void accept(NodeVisitor visitor) { - visitor.visit(this); - } - - @Override - protected String toStringShallow() { - return "DataPlainString('" + string + "')"; - } - - @Override - protected Node mkCopy() { - return new DataPlainString(line, column, string); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - DataPlainString that = (DataPlainString) o; - return Objects.equals(string, that.string); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java index 5cfc696db..946e73314 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java @@ -24,13 +24,11 @@ protected Node mkCopy() { } @Override - public Optional eval(int currentAddress, NameSpace env) { - Evaluated evaluated = new Evaluated(line, column); - evaluated.addChild(new ExprNumber(line, column, currentAddress)); - return Optional.of(evaluated); - } - - public Optional eval(int currentAddress, NameSpace env, boolean evalLeft) { - return evalLeft ? Optional.empty() : eval(currentAddress, env); + public Optional eval(Optional currentAddress, NameSpace env) { + return currentAddress.map(addr -> { + Evaluated evaluated = new Evaluated(line, column); + evaluated.addChild(new ExprNumber(line, column, addr)); + return evaluated; + }); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java index 1ae7c83eb..6c81d8540 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java @@ -24,7 +24,7 @@ public ExprId(Token id) { } @Override - public Optional eval(int currentAddress, NameSpace env) { + public Optional eval(Optional currentAddress, NameSpace env) { return env.get(normalizeId(id)); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index d623b08c4..f73af6be0 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -52,7 +52,7 @@ public void accept(NodeVisitor visitor) { } @Override - public Optional eval(int currentAddress, NameSpace env) { + public Optional eval(Optional currentAddress, NameSpace env) { Node leftChild = getChild(0); Node rightChild = getChild(1); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java index 17ad56dcd..7fe8c08ae 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java @@ -22,7 +22,7 @@ public ExprNumber(Token number, Function parser) { } @Override - public Optional eval(int currentAddress, NameSpace env) { + public Optional eval(Optional currentAddress, NameSpace env) { Evaluated evaluated = new Evaluated(line, column); evaluated.addChild(new ExprNumber(line, column, number)); return Optional.of(evaluated); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index 3414629df..c67b0a598 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -39,7 +39,7 @@ public void accept(NodeVisitor visitor) { } @Override - public Optional eval(int currentAddress, NameSpace env) { + public Optional eval(Optional currentAddress, NameSpace env) { return getChild(0) .eval(currentAddress, env) .map(childEval -> { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java index 02ded2fcf..01bcfe3b1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java @@ -25,14 +25,12 @@ public PseudoLabel(Token label) { } @Override - public Optional eval(int currentAddress, NameSpace env) { - Evaluated evaluated = new Evaluated(line, column); - evaluated.addChild(new ExprNumber(line, column, currentAddress)); - return Optional.of(evaluated); - } - - public Optional eval(int currentAddress, NameSpace env, boolean evalLeft) { - return evalLeft ? Optional.empty() : eval(currentAddress, env); + public Optional eval(Optional currentAddress, NameSpace env) { + return currentAddress.map(addr -> { + Evaluated evaluated = new Evaluated(line, column); + evaluated.addChild(new ExprNumber(line, column, addr)); + return evaluated; + }); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java index 714d4832a..c715210c6 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java @@ -6,9 +6,11 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; -import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import org.antlr.v4.runtime.Token; +import static net.emustudio.plugins.compiler.as8080.ParsingUtils.parseLitString; + public class CreateDataVisitor extends As8080ParserBaseVisitor { @Override @@ -22,8 +24,11 @@ public Node visitDataDB(DataDBContext ctx) { } else if (next.instr != null) { db.addChild(CreateVisitors.instr.visit(next.instr)); } else { - DataPlainString str = new DataPlainString(next.str); - db.addChild(str); + Token token = next.str; + String text = parseLitString(next.str); + for (byte c : text.getBytes()) { + db.addChild(new ExprNumber(token.getLine(), token.getCharPositionInLine(), c)); + } } } return db; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 52bc6df5c..a233e8c07 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -7,7 +7,6 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; -import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; import net.emustudio.plugins.compiler.as8080.ast.expr.*; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; @@ -143,7 +142,7 @@ public void visit(PseudoSet node) { @Override public void visit(PseudoLabel node) { - Optional eval = node.eval(currentAddress, env, doNotEvaluateCurrentAddress); + Optional eval = node.eval(getCurrentAddress(), env); env.put(normalizeId(node.label), eval); eval.ifPresentOrElse( e -> node.remove(), // we don't need to re-evaluate label @@ -238,13 +237,6 @@ public void visit(PseudoMacroArgument node) { }); } - @Override - public void visit(DataPlainString node) { - node.eval(currentAddress, env) - .ifPresent(e -> node.remove().ifPresent(p -> p.addChild(e))); - currentAddress += node.string.length(); - } - @Override public void visit(Evaluated node) { latestEval = Optional.of(node); @@ -279,8 +271,12 @@ public void visit(ExprId node) { } } + private Optional getCurrentAddress() { + return doNotEvaluateCurrentAddress ? Optional.empty() : Optional.of(currentAddress); + } + private void evalExpr(Node node) { - latestEval = node.eval(currentAddress, env); + latestEval = node.eval(getCurrentAddress(), env); latestEval.ifPresentOrElse( e -> node.remove().ifPresent(p -> p.addChild(e)), () -> needMorePassThings.add(node) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java index a9c74b136..aac918c97 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java @@ -20,12 +20,12 @@ */ public class ExpandMacrosVisitor extends NodeVisitor { private final Map macros = new HashMap<>(); - private final Map> forwardMacroCalls = new HashMap<>(); + private final Map> forwardMacroCalls = new HashMap<>(); @Override public void visit(Program node) { visitChildren(node); - for (Map.Entry> entry : forwardMacroCalls.entrySet()) { + for (Map.Entry> entry : forwardMacroCalls.entrySet()) { error(notDefined(entry.getValue().get(0), "Macro '" + entry.getKey() + "'")); } } @@ -40,12 +40,14 @@ public void visit(PseudoMacroDef node) { // expand macro if we had earlier calls (as a forward reference) if (forwardMacroCalls.containsKey(id)) { - for (Node macroCall : forwardMacroCalls.get(id)) { - macroCall.addChild(node.copy()); + for (PseudoMacroCall macroCall : forwardMacroCalls.remove(id)) { + Node def = node.copy(); + macroCall.addChild(def); + visitChildren(def); // b/c original node does not have a parent } - forwardMacroCalls.remove(id); + } else { + visitChildren(node); } - visitChildren(node); } @Override @@ -53,19 +55,20 @@ public void visit(PseudoMacroCall node) { String id = normalizeId(node.id); if (macros.containsKey(id)) { node.addChild(macros.get(id).copy()); + checkInfiniteLoop(node); } else { // maybe the macro is defined later forwardMacroCalls.putIfAbsent(id, new ArrayList<>()); - List macroCalls = forwardMacroCalls.get(id); + List macroCalls = forwardMacroCalls.get(id); macroCalls.add(node); } - checkInfiniteLoop(node); } private void checkInfiniteLoop(PseudoMacroCall node) { String id = normalizeId(node.id); Optional parent = node.getParent(); while (parent.isPresent()) { + // search all parents to the top for PseudoMacroDef Node parentValue = parent.get(); if (parentValue instanceof PseudoMacroDef) { String parentId = normalizeId(((PseudoMacroDef) parentValue).id); @@ -73,7 +76,7 @@ private void checkInfiniteLoop(PseudoMacroCall node) { fatalError(infiniteLoopDetected(node, "macro call '" + id + "'")); } } - parent = parent.get().getParent(); + parent = parentValue.getParent(); } } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java index d1cd0340b..172ac5c25 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java @@ -4,11 +4,11 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; -import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import org.junit.Test; +import static net.emustudio.plugins.compiler.as8080.As8080Parser.OPCODE_STC; import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; @@ -16,20 +16,28 @@ public class ParseDataTest { @Test public void testDBstring1() { - Program program = parseProgram("db 'hello,world!'"); + Program program = parseProgram("db 'hello'"); assertTrees(new Program() .addChild(new DataDB(0, 0) - .addChild(new DataPlainString(0, 0, "hello,world!"))), + .addChild(new ExprNumber(0, 0, 'h')) + .addChild(new ExprNumber(0, 0, 'e')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'o'))), program ); } @Test public void testDBstring2() { - Program program = parseProgram("db \"hello,world!\""); + Program program = parseProgram("db \"hello\""); assertTrees(new Program() .addChild(new DataDB(0, 0) - .addChild(new DataPlainString(0, 0, "hello,world!"))), + .addChild(new ExprNumber(0, 0, 'h')) + .addChild(new ExprNumber(0, 0, 'e')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'o'))), program ); } @@ -37,9 +45,11 @@ public void testDBstring2() { @Test public void testDBinstruction() { Program program = parseProgram("db stc"); - assertTrees(new Program() + System.out.println(program); + assertTrees( + new Program() .addChild(new DataDB(0, 0) - .addChild(new InstrNoArgs(0, 0, 0))), + .addChild(new InstrNoArgs(0, 0, OPCODE_STC))), program ); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java index 835be8406..fbd3a6b7b 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java @@ -1,6 +1,5 @@ package net.emustudio.plugins.compiler.as8080; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoLabel; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; @@ -61,7 +60,8 @@ public void testIf() { assertTrees(new Program() .addChild(new PseudoIf(0, 0) - .addChild(new ExprNumber(0, 0, 1)) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 1))) .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) .addChild(new InstrNoArgs(0, 0, OPCODE_RRC))), program @@ -79,8 +79,9 @@ public void testIfEmpty() { for (String src : programs) { Program program = parseProgram(src); Node expected = new Program() - .addChild(new PseudoIf(0,0) - .addChild(new ExprNumber(0,0,1))); + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 1)))); assertTrees(expected, program); } } @@ -99,7 +100,8 @@ public void testTwoLabelsInsideIf() { assertTrees(new Program() .addChild(new PseudoIf(0, 0) - .addChild(new ExprNumber(0, 0, 1)) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 1))) .addChild(new PseudoLabel(0, 0, "label1")) .addChild(new PseudoLabel(0, 0, "label2"))), program diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index 6cc20182e..f41e7a7c2 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -5,7 +5,6 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; -import net.emustudio.plugins.compiler.as8080.ast.data.DataPlainString; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprCurrentAddress; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; @@ -29,11 +28,17 @@ public class EvaluateExprVisitorTest { @Test public void testEvaluateDB() { Program program = new Program(); - program.addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 1)) - .addChild(new ExprNumber(0, 0, 2)) - ).addChild(new DataPlainString(0, 0, "hello"))); + program + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 'h')) + .addChild(new ExprNumber(0, 0, 'e')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'o')) + ); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -44,10 +49,14 @@ public void testEvaluateDB() { .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 3))) .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 'h')) - .addChild(new ExprNumber(0, 0, 'e')) - .addChild(new ExprNumber(0, 0, 'l')) - .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'h'))) + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 'e'))) + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 'l'))) + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 'l'))) + .addChild(new Evaluated(0, 0) .addChild(new ExprNumber(0, 0, 'o')))), program ); @@ -215,6 +224,44 @@ public void testEvaluateIFwithForwardConst() { assertEquals(2, program.getChild(1).getAddress()); } + @Test + public void testEvaluateIFwithForwardAddressReference() { + Program program = new Program(); + program + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "const")))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprCurrentAddress(0, 0)))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_AMBIGUOUS_EXPRESSION)); + } + + @Test + public void testEvaluateIFexcludeBlock() { + Program program = new Program(); + program + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new ExprNumber(0, 0, 0)))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees(new Program(), program); + } + @Test public void testEvaluateSETforwardTwoTimes() { Program program = new Program(); @@ -311,4 +358,36 @@ public void testTwoSETthenReference() { ); } + @Test + public void testEvaluateLABEL() { + Program program = new Program(); + program + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label")))) + .addChild(new PseudoLabel(0, 0, "label")); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 4))) + .addChild(new Evaluated(0, 0) + .addChild(new ExprNumber(0, 0, 5)))), + program + ); + } + } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java index ba6f33d34..db67870ec 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java @@ -88,7 +88,7 @@ public void testTheSameMacroCallInsideMacroDefinition() { } @Test(expected = FatalError.class) - public void testRecursiveMacroCallComplex() { + public void testMacroCallComplexInfiniteLoop() { Program program = parseProgram("x macro\ny\nendm\ny macro\nx\nendm"); ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); macrosVisitor.visit(program); From d0dc0c6c306dda482dfb833d8eaa05afa69ab42a Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 11 Jan 2022 12:11:31 +0100 Subject: [PATCH 069/314] [#201] Evaluated has value --- .../compiler/as8080/ast/Evaluated.java | 23 +++--- .../as8080/ast/expr/ExprCurrentAddress.java | 6 +- .../compiler/as8080/ast/expr/ExprInfix.java | 10 +-- .../compiler/as8080/ast/expr/ExprNumber.java | 4 +- .../compiler/as8080/ast/expr/ExprUnary.java | 9 +-- .../as8080/ast/pseudo/PseudoLabel.java | 7 +- .../as8080/visitors/EvaluateExprVisitor.java | 8 +- .../visitors/EvaluateExprVisitorTest.java | 80 +++++++------------ 8 files changed, 52 insertions(+), 95 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java index 39ef53d29..0ceab1fba 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java @@ -1,25 +1,30 @@ package net.emustudio.plugins.compiler.as8080.ast; -import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; - public class Evaluated extends Node { + public final int value; - public Evaluated(int line, int column) { + public Evaluated(int line, int column, int value) { super(line, column); - // children are sizeBytes * 1-byte ExprNumbers - } - - public int getValue() { - return ((ExprNumber) getChild(0)).number; + this.value = value; } @Override protected Node mkCopy() { - return new Evaluated(line, column); + return new Evaluated(line, column, value); } @Override public void accept(NodeVisitor visitor) { visitor.visit(this); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + Evaluated evaluated = (Evaluated) o; + return value == evaluated.value; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java index 946e73314..27c7f7df7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java @@ -25,10 +25,6 @@ protected Node mkCopy() { @Override public Optional eval(Optional currentAddress, NameSpace env) { - return currentAddress.map(addr -> { - Evaluated evaluated = new Evaluated(line, column); - evaluated.addChild(new ExprNumber(line, column, addr)); - return evaluated; - }); + return currentAddress.map(addr -> new Evaluated(line, column, addr)); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index f73af6be0..4dddd2281 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -60,13 +60,9 @@ public Optional eval(Optional currentAddress, NameSpace env) Optional right = rightChild.eval(currentAddress, env); if (left.isPresent() && right.isPresent()) { - int l = left.get().getValue(); - int r = right.get().getValue(); - int result = operation.apply(l, r); - - Evaluated evaluated = new Evaluated(line, column); - evaluated.addChild(new ExprNumber(line, column, result)); - return Optional.of(evaluated); + int l = left.get().value; + int r = right.get().value; + return Optional.of(new Evaluated(line, column, operation.apply(l, r))); } return Optional.empty(); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java index 7fe8c08ae..4a99fbdb7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java @@ -23,9 +23,7 @@ public ExprNumber(Token number, Function parser) { @Override public Optional eval(Optional currentAddress, NameSpace env) { - Evaluated evaluated = new Evaluated(line, column); - evaluated.addChild(new ExprNumber(line, column, number)); - return Optional.of(evaluated); + return Optional.of(new Evaluated(line, column, number)); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index c67b0a598..a9d9daaa9 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -42,14 +42,7 @@ public void accept(NodeVisitor visitor) { public Optional eval(Optional currentAddress, NameSpace env) { return getChild(0) .eval(currentAddress, env) - .map(childEval -> { - int value = childEval.getValue(); - int result = operation.apply(value); - - Evaluated evaluated = new Evaluated(line, column); - evaluated.addChild(new ExprNumber(line, column, result)); - return evaluated; - }); + .map(childEval -> new Evaluated(line, column, operation.apply(childEval.value))); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java index 01bcfe3b1..23946089d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java @@ -4,7 +4,6 @@ import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; -import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import org.antlr.v4.runtime.Token; import java.util.Objects; @@ -26,11 +25,7 @@ public PseudoLabel(Token label) { @Override public Optional eval(Optional currentAddress, NameSpace env) { - return currentAddress.map(addr -> { - Evaluated evaluated = new Evaluated(line, column); - evaluated.addChild(new ExprNumber(line, column, addr)); - return evaluated; - }); + return currentAddress.map(addr -> new Evaluated(line, column, addr)); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index a233e8c07..2de0bb0df 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -106,7 +106,7 @@ public void visit(DataDS node) { expectedBytes = 0; visitChildren(node); latestEval.ifPresentOrElse( - e -> currentAddress += e.getValue(), + e -> currentAddress += e.value, () -> doNotEvaluateCurrentAddress = true ); } @@ -156,7 +156,7 @@ public void visit(PseudoOrg node) { expectedBytes = 0; visitChildren(node); latestEval.ifPresentOrElse( - e -> currentAddress = e.getValue(), + e -> currentAddress = e.value, () -> doNotEvaluateCurrentAddress = true ); } @@ -171,8 +171,8 @@ public void visit(PseudoIf node) { return p.collectChild(Evaluated.class); }); - boolean includeBlock = expr.filter(p -> p.getValue() != 0).isPresent(); - boolean excludeBlock = expr.filter(p -> p.getValue() == 0).isPresent(); + boolean includeBlock = expr.filter(p -> p.value != 0).isPresent(); + boolean excludeBlock = expr.filter(p -> p.value == 0).isPresent(); if (includeBlock) { List codeChildren = node.getChildren().stream().skip(1).collect(Collectors.toList()); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index f41e7a7c2..16d2b9ca7 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -46,18 +46,12 @@ public void testEvaluateDB() { assertTrees( new Program() .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 'h'))) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 'e'))) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 'l'))) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 'l'))) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 'o')))), + .addChild(new Evaluated(0, 0, 3)) + .addChild(new Evaluated(0, 0, 'h')) + .addChild(new Evaluated(0, 0, 'e')) + .addChild(new Evaluated(0, 0, 'l')) + .addChild(new Evaluated(0, 0, 'l')) + .addChild(new Evaluated(0, 0, 'o'))), program ); } @@ -79,11 +73,9 @@ public void testEvaluateDW() { assertTrees( new Program() .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 3)))) + .addChild(new Evaluated(0, 0, 3))) .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 0)))), + .addChild(new Evaluated(0, 0, 0))), program ); assertEquals(0, program.getChild(0).getAddress()); @@ -107,11 +99,9 @@ public void testEvaluateDS() { assertTrees( new Program() .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 3)))) + .addChild(new Evaluated(0, 0, 3))) .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 0)))), + .addChild(new Evaluated(0, 0, 0))), program ); assertEquals(0, program.getChild(0).getAddress()); @@ -153,8 +143,7 @@ public void testEvaluateDSconstReference() { assertTrees( new Program() .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 5)))), + .addChild(new Evaluated(0, 0, 5))), program ); } @@ -185,7 +174,7 @@ public void testEvaluateEQUfivePasses() { Optional constant = program.env().get(c); assertTrue(constant.isPresent()); assertEquals(0, constant.get().getAddress()); - assertEquals(0, constant.get().getValue()); + assertEquals(0, constant.get().value); } } @@ -213,11 +202,9 @@ public void testEvaluateIFwithForwardConst() { assertTrees( new Program() .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 6)))) + .addChild(new Evaluated(0, 0, 6))) .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 0)))), + .addChild(new Evaluated(0, 0, 0))), program ); assertEquals(0, program.getChild(0).getAddress()); @@ -281,17 +268,13 @@ public void testEvaluateSETforwardTwoTimes() { assertTrees( new Program() .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new Evaluated(0, 0, 1))) .addChild(new PseudoSet(0, 0, "const") - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new Evaluated(0, 0, 1))) .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new Evaluated(0, 0, 1))) .addChild(new PseudoSet(0, 0, "const") - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 2)))), + .addChild(new Evaluated(0, 0, 2))), program ); } @@ -315,14 +298,11 @@ public void testEvaluateSETforwardMoreTimes() { assertTrees( new Program() .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new Evaluated(0, 0, 1))) .addChild(new PseudoSet(0, 0, "id") - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new Evaluated(0, 0, 1))) .addChild(new PseudoSet(0, 0, "id") - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 2)))), + .addChild(new Evaluated(0, 0, 2))), program ); } @@ -346,14 +326,11 @@ public void testTwoSETthenReference() { assertTrees( new Program() .addChild(new PseudoSet(0, 0, "id") - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new Evaluated(0, 0, 1))) .addChild(new PseudoSet(0, 0, "id") - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new Evaluated(0, 0, 2))) .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 2)))), + .addChild(new Evaluated(0, 0, 2))), program ); } @@ -380,12 +357,9 @@ public void testEvaluateLABEL() { assertTrees( new Program() .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 4))) - .addChild(new Evaluated(0, 0) - .addChild(new ExprNumber(0, 0, 5)))), + .addChild(new Evaluated(0, 0, 3)) + .addChild(new Evaluated(0, 0, 4)) + .addChild(new Evaluated(0, 0, 5))), program ); } From b31bd46d9ce03b02ced288a20f03b2a18432f039 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 12 Jan 2022 10:37:24 +0100 Subject: [PATCH 070/314] [#201] as-8080: fix macro calls --- .../compiler/as8080/ast/Evaluated.java | 5 ++ .../ast/pseudo/PseudoMacroArgument.java | 6 +- .../ast/pseudo/PseudoMacroParameter.java | 6 +- .../as8080/visitors/CreatePseudoVisitor.java | 6 +- .../as8080/visitors/EvaluateExprVisitor.java | 25 ++++-- .../compiler/as8080/ParsePseudoTest.java | 8 +- .../visitors/EvaluateExprVisitorTest.java | 87 +++++++++++++++++++ .../as8080/visitors/ExpandMacrosTest.java | 12 +-- .../SortMacroArgumentsVisitorTest.java | 54 ++++++------ 9 files changed, 158 insertions(+), 51 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java index 0ceab1fba..62eba053d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java @@ -27,4 +27,9 @@ public boolean equals(Object o) { Evaluated evaluated = (Evaluated) o; return value == evaluated.value; } + + @Override + protected String toStringShallow() { + return "Evaluated(" + value + ")"; + } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java index e975b4e0c..34becfcdf 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java @@ -8,8 +8,8 @@ */ public class PseudoMacroArgument extends Node { - public PseudoMacroArgument() { - super(0, 0); + public PseudoMacroArgument(int line, int column) { + super(line, column); // the only child is expr } @@ -20,6 +20,6 @@ public void accept(NodeVisitor visitor) { @Override protected Node mkCopy() { - return new PseudoMacroArgument(); + return new PseudoMacroArgument(line, column); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java index 56f957b4d..8199802d1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java @@ -9,8 +9,8 @@ */ public class PseudoMacroParameter extends Node { - public PseudoMacroParameter() { - super(0, 0); + public PseudoMacroParameter(int line, int column) { + super(line, column); // the only child is ExprId } @@ -21,6 +21,6 @@ public void accept(NodeVisitor visitor) { @Override protected Node mkCopy() { - return new PseudoMacroParameter(); + return new PseudoMacroParameter(line, column); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java index 7a29c3842..f3bc6a510 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java @@ -53,7 +53,8 @@ public Node visitPseudoMacroDef(PseudoMacroDefContext ctx) { if (ctx.params != null) { for (TerminalNode next : ctx.params.ID_IDENTIFIER()) { - PseudoMacroParameter parameter = new PseudoMacroParameter(); + Token symbol = next.getSymbol(); + PseudoMacroParameter parameter = new PseudoMacroParameter(symbol.getLine(), symbol.getCharPositionInLine()); parameter.addChild(new ExprId(next.getSymbol())); pseudo.addChild(parameter); } @@ -70,7 +71,8 @@ public Node visitPseudoMacroCall(PseudoMacroCallContext ctx) { if (ctx.args != null) { for (RExpressionContext next : ctx.args.rExpression()) { - PseudoMacroArgument argument = new PseudoMacroArgument(); + Token start = next.getStart(); + PseudoMacroArgument argument = new PseudoMacroArgument(start.getLine(), start.getCharPositionInLine()); pseudo.addChild(argument.addChild(CreateVisitors.expr.visit(next))); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 2de0bb0df..3d13bb9f8 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -44,7 +44,7 @@ public class EvaluateExprVisitor extends NodeVisitor { private Set needMorePassThings = new HashSet<>(); private final Map> macroArguments = new HashMap<>(); - private String currentMacro; + private String currentMacroId; @Override public void visit(Program node) { @@ -213,15 +213,28 @@ public void visit(InstrRegPairExpr node) { @Override public void visit(PseudoMacroCall node) { - currentMacro = normalizeId(node.id); - macroArguments.put(currentMacro, new ArrayList<>()); + // save old current macro, including its params + String oldCurrentMacroId = currentMacroId; + Map> oldMacroParams = new HashMap<>(); + if (oldCurrentMacroId != null) { + for (String macroParameter : macroArguments.get(oldCurrentMacroId)) { + oldMacroParams.put(macroParameter, env.get(macroParameter)); + } + } + + currentMacroId = normalizeId(node.id); + macroArguments.put(currentMacroId, new ArrayList<>()); visitChildren(node); // on macro exit, remove current macro arguments from env - for (String macroParameter : macroArguments.get(currentMacro)) { + for (String macroParameter : macroArguments.get(currentMacroId)) { env.remove(macroParameter); } - macroArguments.remove(currentMacro); + // and put back old current macro arguments to env + oldMacroParams.forEach((macroParam, expr) -> env.put(macroParam, expr)); + + macroArguments.remove(currentMacroId); + currentMacroId = oldCurrentMacroId; } @Override @@ -232,7 +245,7 @@ public void visit(PseudoMacroArgument node) { node.collectChild(ExprId.class) .ifPresent(exprId -> { String macroParameter = normalizeId(exprId.id); - macroArguments.get(currentMacro).add(macroParameter); + macroArguments.get(currentMacroId).add(macroParameter); env.put(macroParameter, latestEval); }); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java index fbd3a6b7b..04170c785 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java @@ -126,9 +126,9 @@ public void testMacroDef() { Node expected = new Program() .addChild(new PseudoMacroDef(0, 0, "shrt") - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "param1"))) - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "param2"))) .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) .addChild(new PseudoLabel(0, 0, "heylabel") @@ -171,9 +171,9 @@ public void testMacroCallWithParams() { Node expected = new Program() .addChild(new PseudoMacroCall(0, 0, "shrt") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "param1"))) - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 45)))); assertTrees(expected, program); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index 16d2b9ca7..5f05d7130 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -11,6 +11,7 @@ import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegPairExpr; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; import org.junit.Test; @@ -364,4 +365,90 @@ public void testEvaluateLABEL() { ); } + @Test + public void testEvaluateMacroCalls() { + Program program = new Program(); + program + .addChild(new PseudoLabel(0, 0, "label")) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "addr")) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "addr")))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "addr")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))), + program + ); + } + + @Test + public void testEvaluateMacroCallAmbiguous() { + Program program = new Program(); + program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "label")) + .addChild(new ExprId(0, 0, "addr"))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "addr")))) + .addChild(new PseudoLabel(0, 0, "label")); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_AMBIGUOUS_EXPRESSION)); + } + + @Test + public void testEvaluateMacroScopedArguments() { + Program program = new Program(); + program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new ExprNumber(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "arg"))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "arg")))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "arg")))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))), + program + ); + } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java index db67870ec..080a3cb7b 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java @@ -102,18 +102,18 @@ public void testMacroCallWithArguments() { assertTrees(new Program() .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 3))) .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "r"))) - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "t"))))), program ); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java index 6ca73d725..b179e17d0 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java @@ -20,18 +20,18 @@ public class SortMacroArgumentsVisitorTest { public void testMacroArgumentsAreConnectedWithIds() { Node program = new Program() .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 3))) .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "r"))) - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "t"))) .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) .addChild(new ExprId(0, 0, "q"))) @@ -45,13 +45,13 @@ public void testMacroArgumentsAreConnectedWithIds() { assertTrees(new Program() .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "q")) .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "r")) .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "t")) .addChild(new ExprNumber(0, 0, 3))) .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) @@ -68,16 +68,16 @@ public void testMacroArgumentsAreConnectedWithIds() { public void testMultipleMacroCalls() { Node program = new Program() .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 1))) .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "q"))))) .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 2))) .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "q"))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); @@ -85,11 +85,11 @@ public void testMultipleMacroCalls() { assertTrees(new Program() .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "q")) .addChild(new ExprNumber(0, 0, 1)))) .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "q")) .addChild(new ExprNumber(0, 0, 2)))), program @@ -100,16 +100,16 @@ public void testMultipleMacroCalls() { public void testNestedMacroCallWithSameNamedArgs() { Node program = new Program() .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 1))) .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "q"))) .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 3))) .addChild(new PseudoMacroDef(0, 0, "y") - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "q"))))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); @@ -118,11 +118,11 @@ public void testNestedMacroCallWithSameNamedArgs() { assertTrees( new Program() .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "q")) .addChild(new ExprNumber(0, 0, 1))) .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "q")) .addChild(new ExprNumber(0, 0, 3))))), program @@ -134,12 +134,12 @@ public void testMoreMacroArgumentsThanParameters() { Program program = new Program(); program .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 2))) .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "q"))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); @@ -153,12 +153,12 @@ public void testMoreMacroParametersThanArguments() { Program program = new Program(); program .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument() + .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprNumber(0, 0, 1))) .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoMacroParameter() + .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "r"))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); From 4361c7ecaaef6b5aa49dc4c2b30a73ffc88715d3 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 13 Jan 2022 18:28:46 +0100 Subject: [PATCH 071/314] [#201] as-8080: test and fix expr parsing + evaluation --- .../as-8080/src/main/antlr/As8080Lexer.g4 | 8 +- .../as-8080/src/main/antlr/As8080Parser.g4 | 31 ++-- .../compiler/as8080/LexicalAnalyzerImpl.java | 2 +- .../compiler/as8080/ParserErrorListener.java | 1 + .../as8080/visitors/CreateExprVisitor.java | 5 + .../compiler/as8080/ParseDataTest.java | 31 +++- .../compiler/as8080/ParseExprTest.java | 170 ++++++++++++++++++ 7 files changed, 224 insertions(+), 24 deletions(-) create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseExprTest.java diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 index 0e1636ca0..0c8836725 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 @@ -145,10 +145,10 @@ OP_OR: O R; OP_XOR: X O R; // literals -LIT_HEXNUMBER_1: [\-]? '0' X [0-9a-fA-F]+; -LIT_NUMBER: [\-]? [0-9]+ D?; -LIT_HEXNUMBER_2: [\-]? [0-9a-fA-F]+ H; -LIT_OCTNUMBER: [\-]? [0-7]+ [oOqQ]; +LIT_HEXNUMBER_1: '0' X [0-9a-fA-F]+; +LIT_NUMBER: [0-9]+ D?; +LIT_HEXNUMBER_2: [0-9a-fA-F]+ H; +LIT_OCTNUMBER: [0-7]+ [oOqQ]; LIT_BINNUMBER: [01]+ B; LIT_STRING_1: '\'' ~[']* '\''; LIT_STRING_2: '"' ~["]* '"'; diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index 4affb5606..3109ffcce 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -149,19 +149,20 @@ rDWdata: ; rExpression: - num=LIT_NUMBER # exprDec - | num=LIT_HEXNUMBER_1 # exprHex1 - | num=LIT_HEXNUMBER_2 # exprHex2 - | num=LIT_OCTNUMBER # exprOct - | num=LIT_BINNUMBER # exprBin - | PREP_ADDR # exprCurrentAddress - | id=ID_IDENTIFIER # exprId - | unaryop=(OP_ADD|OP_SUBTRACT) expr=rExpression # exprUnary - | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD|OP_SHL|OP_SHR) expr2=rExpression # exprInfix - | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression # exprInfix - | expr1=rExpression op=OP_EQUAL expr2=rExpression # exprInfix - | unaryop=OP_NOT expr=rExpression # exprUnary - | expr1=rExpression op=OP_AND expr2=rExpression # exprInfix - | expr1=rExpression op=(OP_OR|OP_XOR) expr2=rExpression # exprInfix - | SEP_LPAR expr=rExpression SEP_RPAR # exprParens + unaryop=(OP_ADD|OP_SUBTRACT|OP_NOT) expr=rExpression # exprUnary + | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_SHL|OP_SHR) expr2=rExpression # exprInfix + | expr1=rExpression op=OP_AND expr2=rExpression # exprInfix + | expr1=rExpression op=OP_XOR expr2=rExpression # exprInfix + | expr1=rExpression op=OP_OR expr2=rExpression # exprInfix + | expr1=rExpression op=OP_EQUAL expr2=rExpression # exprInfix + | SEP_LPAR expr=rExpression SEP_RPAR # exprParens + | num=LIT_NUMBER # exprDec + | num=LIT_HEXNUMBER_1 # exprHex1 + | num=LIT_HEXNUMBER_2 # exprHex2 + | num=LIT_OCTNUMBER # exprOct + | num=LIT_BINNUMBER # exprBin + | PREP_ADDR # exprCurrentAddress + | id=ID_IDENTIFIER # exprId ; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java index 444ccd500..2d5283439 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java @@ -12,7 +12,7 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { private final As8080Lexer lexer; - private static final int[] tokenMap = new int[As8080Lexer.ERROR + 1]; // As8080Lexer.ERROR is the highest number + private static final int[] tokenMap = new int[As8080Lexer.EOL + 1]; // As8080Lexer.ERROR is the highest number static { tokenMap[COMMENT] = Token.COMMENT; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java index dd06f6077..aea84ab0c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java @@ -6,6 +6,7 @@ import org.antlr.v4.runtime.Recognizer; class ParserErrorListener extends BaseErrorListener { + // TODO: parse message expected tokens to token categories @Override public void syntaxError( Recognizer recognizer, diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java index d9fc45f5c..ceca1f124 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java @@ -54,6 +54,11 @@ public Node visitExprInfix(As8080Parser.ExprInfixContext ctx) { return infix; } + @Override + public Node visitExprParens(As8080Parser.ExprParensContext ctx) { + return visit(ctx.expr); + } + @Override public Node visitExprCurrentAddress(As8080Parser.ExprCurrentAddressContext ctx) { Token start = ctx.getStart(); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java index 172ac5c25..635fcda1c 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java @@ -5,10 +5,12 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprUnary; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import org.junit.Test; import static net.emustudio.plugins.compiler.as8080.As8080Parser.OPCODE_STC; +import static net.emustudio.plugins.compiler.as8080.As8080Parser.OP_SUBTRACT; import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; @@ -59,7 +61,8 @@ public void testMultipleDB() { Program program = parseProgram("db -1,2,3"); assertTrees(new Program() .addChild(new DataDB(0, 0) - .addChild(new ExprNumber(0, 0, -1)) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) .addChild(new ExprNumber(0, 0, 2)) .addChild(new ExprNumber(0, 0, 3))), program @@ -71,7 +74,25 @@ public void testDBwithNegativeValue() { Program program = parseProgram("db -1"); assertTrees(new Program() .addChild(new DataDB(0, 0) - .addChild(new ExprNumber(0, 0, -1))), + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1)))), + program + ); + } + + @Test + public void testMultipleDBstringNumberString() { + Program program = parseProgram("db -1,'hello',3"); + assertTrees(new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 'h')) + .addChild(new ExprNumber(0, 0, 'e')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'o')) + .addChild(new ExprNumber(0, 0, 3))), program ); } @@ -81,7 +102,8 @@ public void testMultipleDW() { Program program = parseProgram("dw -1,2,3"); assertTrees(new Program() .addChild(new DataDW(0, 0) - .addChild(new ExprNumber(0, 0, -1)) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) .addChild(new ExprNumber(0, 0, 2)) .addChild(new ExprNumber(0, 0, 3))), program @@ -93,7 +115,8 @@ public void testDWwithNegativeValue() { Program program = parseProgram("dw -1"); assertTrees(new Program() .addChild(new DataDW(0, 0) - .addChild(new ExprNumber(0, 0, -1))), + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1)))), program ); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseExprTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseExprTest.java new file mode 100644 index 000000000..87f59df20 --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseExprTest.java @@ -0,0 +1,170 @@ +package net.emustudio.plugins.compiler.as8080; + +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprUnary; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; +import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; +import static net.emustudio.plugins.compiler.as8080.Utils.parseProgram; + +public class ParseExprTest { + + @Test + public void testPrioritiesAddMul() { + Program program = parseProgram("db 2+3*4"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 3)) + .addChild(new ExprNumber(0, 0, 4))))), + program + ); + } + + @Test + public void testPrioritiesMulAdd() { + Program program = parseProgram("db 2*3+4"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4)))), + program + ); + } + + @Test + public void testAssociativityPlusMinus() { + Program program = parseProgram("db 2-3+4-9"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4))) + .addChild(new ExprNumber(0, 0, 9)))), + program + ); + } + + @Test + public void testAssociativitMulDiv() { + Program program = parseProgram("db 2/3*4/9"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4))) + .addChild(new ExprNumber(0, 0, 9)))), + program + ); + } + + @Test + public void testPrecedencePlusMinusMulDivMod() { + Program program = parseProgram("db 2+3*4-9/2 mod 3"); + System.out.println(program); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 3)) + .addChild(new ExprNumber(0, 0, 4)))) + .addChild(new ExprInfix(0, 0, OP_MOD) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprNumber(0, 0, 9)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 3))))), + program + ); + } + + @Test + public void testAssociativityEqual() { + Program program = parseProgram("db 1 + 2 + 2 = 5 = 5 = 6 - 1"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprInfix(0, 0, OP_ADD) // 1 + 2 + 2 associates to left + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) // ... = 5 associates to right + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) // minus has > precedence than = + .addChild(new ExprNumber(0, 0, 6)) + .addChild(new ExprNumber(0, 0, 1))))))), + program + ); + } + + @Test + public void testAndMulXorDivNotPlusMinus() { + Program program = parseProgram("db not 1 and 2 or 2 xor 5 = - 5 * 6 shl 4 - 1 shr 2"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprInfix(0, 0, OP_OR) + .addChild(new ExprInfix(0, 0, OP_AND) + .addChild(new ExprUnary(0, 0, OP_NOT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 5)))) + .addChild(new ExprInfix(0, 0, OP_SHR) // shl/shr associates to the right + .addChild(new ExprInfix(0, 0, OP_SHL) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))), + program + ); + } + + @Test + public void testParenthesis() { + Program program = parseProgram("db (2 + 3) * (4 - 2)"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 2))))), + program + ); + } +} From 9c7d2a2ef737026ab0061533463b04c5a955d85f Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 14 Jan 2022 07:49:11 +0100 Subject: [PATCH 072/314] [#201] as-8080: check expression sizes --- .../compiler/as8080/Assembler8080.java | 3 +- .../plugins/compiler/as8080/CompileError.java | 9 + .../plugins/compiler/as8080/Either.java | 37 ---- .../compiler/as8080/ast/NameSpace.java | 1 - .../visitors/CheckExprSizesVisitor.java | 65 +++++++ .../as8080/visitors/EvaluateExprVisitor.java | 28 +-- .../as8080/visitors/GenerateCodeVisitor.java | 6 + .../plugins/compiler/as8080/LexerTest.java | 13 +- .../compiler/as8080/ParsingUtilsTest.java | 18 +- .../visitors/CheckExprSizesVisitorTest.java | 176 ++++++++++++++++++ 10 files changed, 290 insertions(+), 66 deletions(-) delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Either.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index abab55bfe..3f5e26183 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -127,7 +127,8 @@ public boolean compile(String inputFileName, String outputFileName) { // macro expansion could bring re-definition of declarations, but we cannot check declarations again // until the macro is properly integrated (b/c we could see multiple macro defs on multiple calls) new CheckDeclarationsVisitor(), - new EvaluateExprVisitor() + new EvaluateExprVisitor(), + new CheckExprSizesVisitor() }; for (NodeVisitor visitor : visitors) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java index 3ec113a1e..cdfe4689a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java @@ -14,6 +14,7 @@ public class CompileError { public static final int ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK = 6; public static final int ERROR_DECLARATION_REFERENCES_ITSELF = 7; public static final int ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH = 8; + public static final int ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED = 9; public final int line; public final int column; @@ -64,6 +65,14 @@ public static CompileError macroArgumentsDoNotMatch(Node node) { return new CompileError(node, ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH, "Macro call arguments do not match with defined parameters"); } + public static CompileError expressionIsBiggerThanExpected(Node node, int expectedBytes, int wasBytes) { + return new CompileError( + node, + ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED, + "Expression (" + wasBytes + " bytes) is bigger than expected (" + expectedBytes + " byte(s))" + ); + } + @Override public String toString() { return "CompileError{" + diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Either.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Either.java deleted file mode 100644 index 36f179016..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Either.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.emustudio.plugins.compiler.as8080; - -import java.util.Optional; - -public class Either { - public final L left; - public final R right; - - private Either(L left, R right) { - this.left = left; - this.right = right; - } - - public Optional left() { - return Optional.ofNullable(left); - } - - public Optional right() { - return Optional.ofNullable(right); - } - - public boolean isLeft() { - return left != null; - } - - public boolean isRight() { - return right != null; - } - - public static Either ofLeft(L left) { - return new Either<>(left, (R) null); - } - - public static Either ofRight(R right) { - return new Either<>((L) null, right); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java index fa4457987..f92344b47 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java @@ -1,7 +1,6 @@ package net.emustudio.plugins.compiler.as8080.ast; import net.emustudio.plugins.compiler.as8080.CompileError; -import net.emustudio.plugins.compiler.as8080.Either; import java.util.*; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java new file mode 100644 index 000000000..22582549d --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java @@ -0,0 +1,65 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegPairExpr; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoOrg; + +import static net.emustudio.plugins.compiler.as8080.CompileError.expressionIsBiggerThanExpected; + +/** + * Checks proper sizes of evaluated nodes + */ +public class CheckExprSizesVisitor extends NodeVisitor { + private int expectedBytes; + + @Override + public void visit(DataDB node) { + expectedBytes = 1; + visitChildren(node); + } + + @Override + public void visit(DataDW node) { + expectedBytes = 2; + visitChildren(node); + } + + @Override + public void visit(DataDS node) { + expectedBytes = 2; + visitChildren(node); + } + + @Override + public void visit(InstrRegExpr node) { + expectedBytes = 1; + visitChildren(node); + } + + @Override + public void visit(InstrRegPairExpr node) { + expectedBytes = 2; + visitChildren(node); + } + + @Override + public void visit(PseudoOrg node) { + expectedBytes = 2; + visitChildren(node); + } + + @Override + public void visit(Evaluated node) { + long maxNumber = Long.MAX_VALUE >>> (63 - expectedBytes * 8); + if (node.value != (node.value & maxNumber)) { + int wasBits = (int)Math.ceil(Math.log10(node.value) / Math.log10(2)) + 1; + int wasBytes = wasBits / 8 + wasBits % 8; + error(expressionIsBiggerThanExpected(node, expectedBytes, wasBytes)); + } + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 3d13bb9f8..4fc25c7f4 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -35,7 +35,7 @@ */ public class EvaluateExprVisitor extends NodeVisitor { private int currentAddress = 0; - private int expectedBytes = 0; + private int sizeBytes = 0; private boolean doNotEvaluateCurrentAddress = false; private final Set doNotEvaluateVariables = new HashSet<>(); private final Set forwardReferences = new HashSet<>(); @@ -89,21 +89,21 @@ public void visit(Program node) { @Override public void visit(DataDB node) { node.setAddress(currentAddress); - expectedBytes = 1; + sizeBytes = 1; visitChildren(node); } @Override public void visit(DataDW node) { node.setAddress(currentAddress); - expectedBytes = 2; + sizeBytes = 2; visitChildren(node); } @Override public void visit(DataDS node) { node.setAddress(currentAddress); - expectedBytes = 0; + sizeBytes = 0; visitChildren(node); latestEval.ifPresentOrElse( e -> currentAddress += e.value, @@ -113,7 +113,7 @@ public void visit(DataDS node) { @Override public void visit(PseudoEqu node) { - expectedBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) + sizeBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) visitChildren(node); env.put(normalizeId(node.id), latestEval); @@ -123,7 +123,7 @@ public void visit(PseudoEqu node) { @Override public void visit(PseudoSet node) { - expectedBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) + sizeBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) String normalizedId = normalizeId(node.id); if (!doNotEvaluateVariables.contains(normalizedId)) { visitChildren(node); @@ -153,7 +153,7 @@ public void visit(PseudoLabel node) { @Override public void visit(PseudoOrg node) { node.setAddress(currentAddress); - expectedBytes = 0; + sizeBytes = 0; visitChildren(node); latestEval.ifPresentOrElse( e -> currentAddress = e.value, @@ -163,7 +163,7 @@ public void visit(PseudoOrg node) { @Override public void visit(PseudoIf node) { - expectedBytes = 0; + sizeBytes = 0; Optional expr = node .collectChild(PseudoIfExpression.class) .flatMap(p -> { @@ -190,7 +190,7 @@ public void visit(PseudoIf node) { @Override public void visit(InstrExpr node) { node.setAddress(currentAddress); - expectedBytes = node.getExprSizeBytes(); + sizeBytes = node.getExprSizeBytes(); visitChildren(node); currentAddress++; // opcode } @@ -198,7 +198,7 @@ public void visit(InstrExpr node) { @Override public void visit(InstrRegExpr node) { node.setAddress(currentAddress); - expectedBytes = 1; + sizeBytes = 1; visitChildren(node); currentAddress++; // opcode } @@ -206,7 +206,7 @@ public void visit(InstrRegExpr node) { @Override public void visit(InstrRegPairExpr node) { node.setAddress(currentAddress); - expectedBytes = 2; + sizeBytes = 2; visitChildren(node); currentAddress++; // opcode } @@ -239,7 +239,7 @@ public void visit(PseudoMacroCall node) { @Override public void visit(PseudoMacroArgument node) { - expectedBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) + sizeBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) visitChildren(node, 1); // expected two children: ExprId and Expr* node.collectChild(ExprId.class) @@ -253,7 +253,7 @@ public void visit(PseudoMacroArgument node) { @Override public void visit(Evaluated node) { latestEval = Optional.of(node); - currentAddress += expectedBytes; + currentAddress += sizeBytes; } @Override @@ -294,6 +294,6 @@ private void evalExpr(Node node) { e -> node.remove().ifPresent(p -> p.addChild(e)), () -> needMorePassThings.add(node) ); - currentAddress += expectedBytes; + currentAddress += sizeBytes; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java new file mode 100644 index 000000000..89bd62324 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java @@ -0,0 +1,6 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; + +public class GenerateCodeVisitor extends NodeVisitor { +} diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java index 3cfbe36be..feb9d179f 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java @@ -25,14 +25,18 @@ public void testParseError2() { @Test public void testParseHex1() { - assertTokenTypes("0x1 0x0 -0x5f -0xFffF 0x1BC", LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, EOF); + assertTokenTypes( + "0x1 0x0 -0x5f -0xFffF 0x1BC", + LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, OP_SUBTRACT, LIT_HEXNUMBER_1, OP_SUBTRACT, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, EOF + ); } @Test public void testParseHex2() { assertTokenTypes( "1h 0h -5Fh -FFFFh 1BCh 5h -5h", - LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, EOF + LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, + LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, EOF ); } @@ -40,13 +44,14 @@ public void testParseHex2() { public void testParseDecimal() { assertTokenTypes( "0 1 -2 3 -4 5 66 999", - LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, EOF + LIT_NUMBER, LIT_NUMBER, OP_SUBTRACT, LIT_NUMBER, LIT_NUMBER, OP_SUBTRACT, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, + LIT_NUMBER, EOF ); } @Test public void testParseOctal() { - assertTokenTypes("-6o 7q 11q -345O", LIT_OCTNUMBER, LIT_OCTNUMBER, LIT_OCTNUMBER, LIT_OCTNUMBER, EOF); + assertTokenTypes("-6o 7q 11q -345O", OP_SUBTRACT, LIT_OCTNUMBER, LIT_OCTNUMBER, LIT_OCTNUMBER, OP_SUBTRACT, LIT_OCTNUMBER, EOF); } @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsingUtilsTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsingUtilsTest.java index f732cce0f..fa3509956 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsingUtilsTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsingUtilsTest.java @@ -21,42 +21,42 @@ public void testParseLitString() { @Test public void testParseLitHex1() { - List tokens = getTokens("-0x22F 0XAA55"); + List tokens = getTokens("0x22F 0XAA55"); assertTokenTypes(tokens, As8080Parser.LIT_HEXNUMBER_1, As8080Parser.LIT_HEXNUMBER_1, As8080Parser.EOF); - assertEquals(-0x22F, ParsingUtils.parseLitHex1(tokens.get(0))); + assertEquals(0x22F, ParsingUtils.parseLitHex1(tokens.get(0))); assertEquals(0xAA55, ParsingUtils.parseLitHex1(tokens.get(1))); } @Test public void testParseLitHex2() { - List tokens = getTokens("-022Fh AA55H"); + List tokens = getTokens("022Fh AA55H"); assertTokenTypes(tokens, As8080Parser.LIT_HEXNUMBER_2, As8080Parser.LIT_HEXNUMBER_2, As8080Parser.EOF); - assertEquals(-0x22F, ParsingUtils.parseLitHex2(tokens.get(0))); + assertEquals(0x22F, ParsingUtils.parseLitHex2(tokens.get(0))); assertEquals(0xAA55, ParsingUtils.parseLitHex2(tokens.get(1))); } @Test public void testParseLitOct() { - List tokens = getTokens("-22q 55O 77Q -001o"); + List tokens = getTokens("22q 55O 77Q 001o"); assertTokenTypes( tokens, As8080Parser.LIT_OCTNUMBER, As8080Parser.LIT_OCTNUMBER, As8080Parser.LIT_OCTNUMBER, As8080Parser.LIT_OCTNUMBER, As8080Parser.EOF ); - assertEquals(-18, ParsingUtils.parseLitOct(tokens.get(0))); + assertEquals(18, ParsingUtils.parseLitOct(tokens.get(0))); assertEquals(45, ParsingUtils.parseLitOct(tokens.get(1))); assertEquals(63, ParsingUtils.parseLitOct(tokens.get(2))); - assertEquals(-1, ParsingUtils.parseLitOct(tokens.get(3))); + assertEquals(1, ParsingUtils.parseLitOct(tokens.get(3))); } @Test public void testParseLitDec() { - List tokens = getTokens("-22 55 00"); + List tokens = getTokens("22 55 00"); assertTokenTypes( tokens, As8080Parser.LIT_NUMBER, As8080Parser.LIT_NUMBER, As8080Parser.LIT_NUMBER, As8080Parser.EOF ); - assertEquals(-22, ParsingUtils.parseLitDec(tokens.get(0))); + assertEquals(22, ParsingUtils.parseLitDec(tokens.get(0))); assertEquals(55, ParsingUtils.parseLitDec(tokens.get(1))); assertEquals(0, ParsingUtils.parseLitDec(tokens.get(2))); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java new file mode 100644 index 000000000..b5da5f19f --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java @@ -0,0 +1,176 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegPairExpr; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoOrg; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; +import static net.emustudio.plugins.compiler.as8080.CompileError.ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED; +import static org.junit.Assert.assertTrue; + +public class CheckExprSizesVisitorTest { + + @Test + public void testDBoneByte() { + Program program = new Program(); + program + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0,0, 0xFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testDBtwoBytes() { + Program program = new Program(); + program + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0,0, 0xFF)) + .addChild(new Evaluated(0,0, 0x100))); // bad size + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testDWtwoBytes() { + Program program = new Program(); + program + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0,0, 0xFFFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testDWthreeBytes() { + Program program = new Program(); + program + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0,0, 0xFFFF)) + .addChild(new Evaluated(0,0, 0x10000))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testDStwoBytes() { + Program program = new Program(); + program + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0,0, 0xFFFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testDSthreeBytes() { + Program program = new Program(); + program + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0,0, 0x10000))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testInstrRegExprOneByte() { + Program program = new Program(); + program + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0,0, 0xFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testInstrRegExprTwoBytes() { + Program program = new Program(); + program + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0,0, 0x100))); // bad size + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testInstrRegPairExprTwoBytes() { + Program program = new Program(); + program + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0,0, 0xFFFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testInstrRegPairExprThreeBytes() { + Program program = new Program(); + program + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0,0, 0x10000))); // bad size + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testPseudoOrgTwoBytes() { + Program program = new Program(); + program + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0,0, 0xFFFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testPseudoOrgThreeBytes() { + Program program = new Program(); + program + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0,0, 0x10000))); // bad size + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } +} From 2869577b8116d46e4c78eb1b858477707ed90171 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 14 Jan 2022 08:17:58 +0100 Subject: [PATCH 073/314] [#201] as-8080: draft of code generator --- .../compiler/as8080/Assembler8080.java | 109 +++++------------- .../compiler/as8080/ast/NameSpace.java | 3 + .../as8080/visitors/GenerateCodeVisitor.java | 72 ++++++++++++ 3 files changed, 102 insertions(+), 82 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index 3f5e26183..cce9023ce 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -29,6 +29,7 @@ import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.RadixUtils; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; @@ -119,6 +120,7 @@ public boolean compile(String inputFileName, String outputFileName) { Program program = new Program(); new CreateProgramVisitor(program).visit(parser.rStart()); + IntelHEX hex = new IntelHEX(); NodeVisitor[] visitors = new NodeVisitor[] { new ExpandIncludesVisitor(), new CheckDeclarationsVisitor(), @@ -128,67 +130,46 @@ public boolean compile(String inputFileName, String outputFileName) { // until the macro is properly integrated (b/c we could see multiple macro defs on multiple calls) new CheckDeclarationsVisitor(), new EvaluateExprVisitor(), - new CheckExprSizesVisitor() + new CheckExprSizesVisitor(), + new GenerateCodeVisitor(hex) }; for (NodeVisitor visitor : visitors) { visitor.visit(program); } - -// ProgramParser programParser = new ProgramParser(); -// programParser.visit(parser.start()); -// -// Program program = programParser.getProgram(); -// CodeGenerator codeGenerator = new CodeGenerator(); -// ByteBuffer code = codeGenerator.generateCode(program); -// -// if (code.hasRemaining()) { -// writeToFile(code, outputFileName); -// writeToMemory(code); -// } - - // programLocation = program.getStartLine() * 4; - - notifyInfo(String.format( - "Compile was successful.\n\tOutput: %s\n\tProgram starts at 0x%s", - outputFileName, RadixUtils.formatWordHexString(programLocation) - )); + programLocation = 0; + if (program.env().hasNoErrors()) { + hex.generate(outputFileName); + programLocation = hex.findProgramLocation(); + + notifyInfo(String.format( + "Compile was successful.\n\tOutput: %s\n\tProgram starts at 0x%s", + outputFileName, RadixUtils.formatWordHexString(programLocation) + )); + + if (memory != null) { + hex.loadIntoMemory(memory, b -> b); + notifyInfo("Compiled file was loaded into memory."); + } else { + notifyWarning("Memory is not available."); + } + return true; + } else { + for (CompileError error : program.env().getErrors()) { + notifyError(error.line, error.column, error.msg); + } + return false; + } } catch (CompileException e) { notifyError(e.line, e.column, e.getMessage()); return false; } catch (IOException e) { notifyError("Compilation error: " + e); - LOGGER.error("Compilation error", e); return false; } finally { notifyCompileFinish(); } - - return true; - -// try { -// IntelHEX hex = compileToHex(inputFileName); -// -// hex.generate(outputFileName); -// programLocation = hex.getProgramLocation(); -// notifyInfo("Compilation was successful.\n Output file: " + outputFileName); -// -// if (memory != null) { -// hex.loadIntoMemory(memory); -// notifyInfo("Compiled file was loaded into memory."); -// } else { -// notifyWarning("Memory is not available."); -// } -// return true; -// } catch (Exception e) { -// e.printStackTrace(); -// LOGGER.trace("Compiler exception", e); -// notifyError("Compilation error: " + e.getMessage()); -// return false; -// } finally { -// notifyCompileFinish(); -// } } @Override @@ -213,42 +194,6 @@ public List getSourceFileExtensions() { return SOURCE_FILE_EXTENSIONS; } -// private IntelHEX compileToHex(String inputFileName) throws Exception { -// Objects.requireNonNull(inputFileName); -// -// notifyInfo(getTitle() + ", version " + getVersion()); -// -// Object parsedAST; -// IntelHEX hex = new IntelHEX(); -// -// try (Reader reader = new FileReader(inputFileName)) { -// lexer.reset(reader, 0, 0, 0); -// parser.reset(); -// parsedAST = parser.parse().value; -// -// if (parsedAST == null) { -// throw new Exception("Unexpected end of file"); -// } -// if (parser.hasSyntaxErrors()) { -// throw new Exception("One or more errors has been found, cannot continue."); -// } -// -// // do several passes for compiling -// Statement stat = (Statement) parsedAST; -// Namespace env = new Namespace(inputFileName); -// stat.pass1(env); // create symbol table -// stat.pass2(0); // try to evaluate all expressions + compute relative addresses -// while (stat.pass3(env)) { -// // don't worry about deadlock -// } -// if (env.getPassNeedCount() != 0) { -// throw new Exception("Could not evaluate: " + env.getPassNeedView()); -// } -// stat.pass4(hex, env); -// return hex; -// } -// } - private Optional getResourceBundle() { try { return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.compiler.as8080.version")); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java index f92344b47..388a1b5c6 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java @@ -32,6 +32,9 @@ public Optional get(String id) { return Optional.ofNullable(definitions.get(id)).flatMap(e -> e); } + public List getErrors() { + return Collections.unmodifiableList(errors); + } @Override public String toString() { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java index 89bd62324..1fa188b3d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java @@ -1,6 +1,78 @@ package net.emustudio.plugins.compiler.as8080.visitors; +import net.emustudio.emulib.runtime.io.IntelHEX; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.instr.*; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoOrg; + +import java.util.Objects; public class GenerateCodeVisitor extends NodeVisitor { + private final IntelHEX hex; + + private int currentAddress; + private Evaluated lastEval; + + public GenerateCodeVisitor(IntelHEX hex) { + this.hex = Objects.requireNonNull(hex); + } + + @Override + public void visit(DataDB node) { + super.visit(node); + } + + @Override + public void visit(DataDW node) { + super.visit(node); + } + + @Override + public void visit(DataDS node) { + super.visit(node); + } + + @Override + public void visit(InstrExpr node) { + super.visit(node); + } + + @Override + public void visit(InstrNoArgs node) { + super.visit(node); + } + + @Override + public void visit(InstrReg node) { + super.visit(node); + } + + @Override + public void visit(InstrRegExpr node) { + super.visit(node); + } + + @Override + public void visit(InstrRegPair node) { + super.visit(node); + } + + @Override + public void visit(InstrRegPairExpr node) { + super.visit(node); + } + + @Override + public void visit(InstrRegReg node) { + super.visit(node); + } + + @Override + public void visit(PseudoOrg node) { + super.visit(node); + } } From c73341e74dccf6402d7b14cb4b9242e040461e6e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 15 Jan 2022 09:14:31 +0100 Subject: [PATCH 074/314] [#201] as-8080: code generator --- .../plugins/compiler/as8080/CompileError.java | 24 +- .../plugins/compiler/as8080/ParsingUtils.java | 188 +-------- .../compiler/as8080/ast/instr/InstrExpr.java | 56 +++ .../as8080/ast/instr/InstrNoArgs.java | 38 ++ .../compiler/as8080/ast/instr/InstrReg.java | 40 +- .../as8080/ast/instr/InstrRegExpr.java | 9 +- .../as8080/ast/instr/InstrRegPair.java | 32 +- .../as8080/ast/instr/InstrRegPairExpr.java | 7 +- .../as8080/ast/instr/InstrRegReg.java | 8 +- .../visitors/CheckExprSizesVisitor.java | 13 + .../as8080/visitors/GenerateCodeVisitor.java | 65 ++- .../visitors/CheckExprSizesVisitorTest.java | 40 ++ .../visitors/GenerateCodeVisitorTest.java | 399 ++++++++++++++++++ 13 files changed, 709 insertions(+), 210 deletions(-) create mode 100644 plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java index cdfe4689a..e6128be54 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java @@ -15,6 +15,8 @@ public class CompileError { public static final int ERROR_DECLARATION_REFERENCES_ITSELF = 7; public static final int ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH = 8; public static final int ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED = 9; + public static final int ERROR_VALUE_MUST_BE_POSITIVE = 10; + public static final int ERROR_VALUE_IS_BIGGER_THAN_EXPECTED = 11; public final int line; public final int column; @@ -42,7 +44,9 @@ public static CompileError infiniteLoopDetected(Node node, String what) { } public static CompileError couldNotReadFile(Node node, String filename, IOException e) { - return new CompileError(node, ERROR_CANNOT_READ_FILE, "Could not read file: " + filename + " (" + e.getMessage() + ")"); + return new CompileError( + node, ERROR_CANNOT_READ_FILE, "Could not read file: " + filename + " (" + e.getMessage() + ")" + ); } public static CompileError notDefined(Node node, String what) { @@ -54,7 +58,9 @@ public static CompileError ambiguousExpression(Node node) { } public static CompileError ifExpressionReferencesOwnBlock(Node node) { - return new CompileError(node, ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK, "If expression references declaration in its own block"); + return new CompileError( + node, ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK, "If expression references declaration in its own block" + ); } public static CompileError declarationReferencesItself(Node node) { @@ -62,7 +68,9 @@ public static CompileError declarationReferencesItself(Node node) { } public static CompileError macroArgumentsDoNotMatch(Node node) { - return new CompileError(node, ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH, "Macro call arguments do not match with defined parameters"); + return new CompileError( + node, ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH, "Macro call arguments do not match with defined parameters" + ); } public static CompileError expressionIsBiggerThanExpected(Node node, int expectedBytes, int wasBytes) { @@ -73,6 +81,16 @@ public static CompileError expressionIsBiggerThanExpected(Node node, int expecte ); } + public static CompileError valueMustBePositive(Node node) { + return new CompileError(node, ERROR_VALUE_MUST_BE_POSITIVE, "Value must be positive"); + } + + public static CompileError valueIsBiggerThanExpected(Node node, int expectedValue) { + return new CompileError( + node, ERROR_VALUE_IS_BIGGER_THAN_EXPECTED, "Value is bigger than expected (" + expectedValue + ")" + ); + } + @Override public String toString() { return "CompileError{" + diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParsingUtils.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParsingUtils.java index 6e7fd102d..c39bcaf5d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParsingUtils.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParsingUtils.java @@ -49,200 +49,14 @@ public static int parseLitBin(Token token) { public static int parseOpcode(Token token) { switch (token.getText().toLowerCase(Locale.ENGLISH)) { - case "mvi": - return 6; - case "lxi": - return 1; - case "lda": - return 0x3A; - case "sta": - return 0x32; - case "lhld": - return 0x2A; - case "shld": - return 0x22; - case "adi": - return 0xC6; - case "aci": - return 0xCE; - case "sui": - return 0xD6; - case "sbi": - return 0xDE; - case "ani": - return 0xE6; - case "ori": - return 0xF6; - case "xri": - return 0xEE; - case "cpi": - return 0xFE; - case "jmp": - return 0xC3; - case "jc": - return 0xDA; - case "jnc": - return 0xD2; - case "jz": - return 0xCA; - case "jnz": - return 0xC2; - case "jm": - return 0xFA; - case "jp": - return 0xF2; - case "jpe": - return 0xEA; - case "jpo": - return 0xE2; - case "call": - return 0xCD; - case "cc": - return 0xDC; - case "cnc": - return 0xD4; - case "cnz": - return 0xC4; - case "cm": - return 0xFC; - case "cp": - return 0xF4; - case "cpe": - return 0xEC; - case "cpo": - return 0xE4; - case "in": - return 0xDB; - case "out": - return 0xD3; - case "stc": - return 0x37; - case "cmc": - return 0x3F; - case "cma": - return 0x2F; - case "daa": - return 0x27; - case "nop": - return 0; - case "rlc": - return 7; - case "rrc": - return 0xF; - case "ral": - return 0x17; - case "rar": - return 0x1F; - case "xchg": - return 0xEB; - case "xthl": - return 0xE3; - case "sphl": - return 0xF9; - case "pchl": - return 0xE9; - case "ret": - return 0xC9; - case "rc": - return 0xD8; - case "rnc": - return 0xD0; - case "rz": - return 0xC8; - case "rnz": - return 0xC0; - case "rm": - return 0xF8; - case "rp": - return 0xF0; - case "rpe": - return 0xE8; - case "rpo": - return 0xE0; - case "ei": - return 0xFB; - case "di": - return 0xF3; - case "hlt": - return 0x76; - case "inr": - return 4; - case "dcr": - return 5; - case "add": - return 0x80; - case "adc": - return 0x88; - case "sub": - return 0x90; - case "sbb": - return 0x98; - case "ana": - return 0xA0; - case "xra": - return 0xA8; - case "ora": - return 0xB0; - case "cmp": - return 0xB8; - case "mov": - return 0x40; - case "stax": - return 2; - case "ldax": - return 0xA; - case "push": - return 0xC5; - case "pop": - return 0xC1; - case "dad": - return 9; - case "inx": - return 3; - case "dcx": - return 0xB; case "rst": return 0xC7; } throw new CompileException(token.getCharPositionInLine(), token.getLine(), "Unknown instruction opcode: " + token.getText()); } - public static int parseReg(Token token) { - switch (token.getText().toLowerCase(Locale.ENGLISH)) { - case "a": - return 7; - case "b": - return 0; - case "c": - return 1; - case "d": - return 2; - case "e": - return 3; - case "h": - return 4; - case "l": - return 5; - case "m": - return 6; - } - throw new CompileException(token.getCharPositionInLine(), token.getLine(), "Unknown register: " + token.getText()); - } - public static int parseRegPair(Token token) { - switch (token.getText().toLowerCase(Locale.ENGLISH)) { - case "b": - return 0; - case "d": - return 1; - case "h": - return 2; - case "psw": - case "sp": - return 3; - } - throw new CompileException(token.getCharPositionInLine(), token.getLine(), "Unknown register pair: " + token.getText()); - } + public static String parseLabel(Token token) { String rawText = token.getText(); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index 84bbe9208..5b7960716 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -1,10 +1,13 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; @@ -12,6 +15,7 @@ public class InstrExpr extends Node { public final int opcode; private final static Set twoBytes = new HashSet<>(); + private final static Map opcodes = new HashMap<>(); static { twoBytes.add(OPCODE_ADI); @@ -24,6 +28,39 @@ public class InstrExpr extends Node { twoBytes.add(OPCODE_CPI); twoBytes.add(OPCODE_IN); twoBytes.add(OPCODE_OUT); + + opcodes.put(OPCODE_LDA, 0x3A); + opcodes.put(OPCODE_STA, 0x32); + opcodes.put(OPCODE_LHLD, 0x2A); + opcodes.put(OPCODE_SHLD, 0x22); + opcodes.put(OPCODE_ADI, 0xC6); + opcodes.put(OPCODE_ACI, 0xCE); + opcodes.put(OPCODE_SUI, 0xD6); + opcodes.put(OPCODE_SBI, 0xDE); + opcodes.put(OPCODE_ANI, 0xE6); + opcodes.put(OPCODE_ORI, 0xF6); + opcodes.put(OPCODE_XRI, 0xEE); + opcodes.put(OPCODE_CPI, 0xFE); + opcodes.put(OPCODE_JMP, 0xC3); + opcodes.put(OPCODE_JC, 0xDA); + opcodes.put(OPCODE_JNC, 0xD2); + opcodes.put(OPCODE_JZ, 0xCA); + opcodes.put(OPCODE_JNZ, 0xC2); + opcodes.put(OPCODE_JM, 0xFA); + opcodes.put(OPCODE_JP, 0xF2); + opcodes.put(OPCODE_JPE, 0xEA); + opcodes.put(OPCODE_JPO, 0xE2); + opcodes.put(OPCODE_CALL, 0xCD); + opcodes.put(OPCODE_CC, 0xDC); + opcodes.put(OPCODE_CNC, 0xD4); + opcodes.put(OPCODE_CNZ, 0xC4); + opcodes.put(OPCODE_CM, 0xFC); + opcodes.put(OPCODE_CP, 0xF4); + opcodes.put(OPCODE_CPE, 0xEC); + opcodes.put(OPCODE_CPO, 0xE4); + opcodes.put(OPCODE_IN, 0xDB); + opcodes.put(OPCODE_OUT, 0xD3); + opcodes.put(OPCODE_RST, 0xC7); } public InstrExpr(int line, int column, int opcode) { @@ -45,6 +82,25 @@ public int getExprSizeBytes() { return 2; // address } + public int getExprMaxValue() { + if (opcode == OPCODE_RST) { + return 7; + } else if (twoBytes.contains(opcode)) { + return 0xFFFF; + } + return 0xFF; + } + + public byte eval() { + byte result = (byte) (opcodes.get(opcode) & 0xFF); + if (opcode == OPCODE_RST) { + int value = collectChild(Evaluated.class).get().value; + result = (byte) (result | (value << 3)); + } + + return result; + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java index fcf8feeaa..02f207f8f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java @@ -4,9 +4,43 @@ import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; + public class InstrNoArgs extends Node { + private final static Map opcodes = new HashMap<>(); public final int opcode; + static { + opcodes.put(OPCODE_STC, 0x37); + opcodes.put(OPCODE_CMC, 0x3F); + opcodes.put(OPCODE_CMA, 0x2F); + opcodes.put(OPCODE_DAA, 0x27); + opcodes.put(OPCODE_NOP, 0); + opcodes.put(OPCODE_RLC, 7); + opcodes.put(OPCODE_RRC, 0xF); + opcodes.put(OPCODE_RAL, 0x17); + opcodes.put(OPCODE_RAR, 0x1F); + opcodes.put(OPCODE_XCHG, 0xEB); + opcodes.put(OPCODE_XTHL, 0xE3); + opcodes.put(OPCODE_SPHL, 0xF9); + opcodes.put(OPCODE_PCHL, 0xE9); + opcodes.put(OPCODE_RET, 0xC9); + opcodes.put(OPCODE_RC, 0xD8); + opcodes.put(OPCODE_RNC, 0xD0); + opcodes.put(OPCODE_RZ, 0xC8); + opcodes.put(OPCODE_RNZ, 0xC0); + opcodes.put(OPCODE_RM, 0xF8); + opcodes.put(OPCODE_RP, 0xF0); + opcodes.put(OPCODE_RPE, 0xE8); + opcodes.put(OPCODE_RPO, 0xE0); + opcodes.put(OPCODE_EI, 0xFB); + opcodes.put(OPCODE_DI, 0xF3); + opcodes.put(OPCODE_HLT, 0x76); + } + public InstrNoArgs(int line, int column, int opcode) { super(line, column); this.opcode = opcode; @@ -16,6 +50,10 @@ public InstrNoArgs(Token opcode) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); } + public byte eval() { + return (byte) (opcodes.get(opcode) & 0xFF); + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java index 7d8637f93..b6b8586ea 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java @@ -4,10 +4,39 @@ import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; + public class InstrReg extends Node { + private final static Map opcodes = new HashMap<>(); + public final static Map registers = new HashMap<>(); public final int opcode; public final int reg; + static { + opcodes.put(OPCODE_INR, 4); + opcodes.put(OPCODE_DCR, 5); + opcodes.put(OPCODE_ADD, 0x80); + opcodes.put(OPCODE_ADC, 0x88); + opcodes.put(OPCODE_SUB, 0x90); + opcodes.put(OPCODE_SBB, 0x98); + opcodes.put(OPCODE_ANA, 0xA0); + opcodes.put(OPCODE_XRA, 0xA8); + opcodes.put(OPCODE_ORA, 0xB0); + opcodes.put(OPCODE_CMP, 0xB8); + + registers.put(REG_A, 7); + registers.put(REG_B, 0); + registers.put(REG_C, 1); + registers.put(REG_D, 2); + registers.put(REG_E, 3); + registers.put(REG_H, 4); + registers.put(REG_L, 5); + registers.put(REG_M, 6); + } + public InstrReg(int line, int column, int opcode, int reg) { super(line, column); this.opcode = opcode; @@ -18,6 +47,15 @@ public InstrReg(Token opcode, Token reg) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); } + public byte eval() { + int result = opcodes.get(opcode); + int register = registers.get(reg); + if (opcode == OPCODE_INR || opcode == OPCODE_DCR) { + return (byte) ((result | (register << 3)) & 0xFF); + } + return (byte) ((result | register) & 0xFF); + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); @@ -25,7 +63,7 @@ public void accept(NodeVisitor visitor) { @Override protected String toStringShallow() { - return "InstrReg(" + opcode + "," + reg +")"; + return "InstrReg(" + opcode + "," + reg + ")"; } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java index d841ab869..723ee3bb3 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java @@ -5,7 +5,7 @@ import org.antlr.v4.runtime.Token; public class InstrRegExpr extends Node { - public final int opcode; + public final int opcode; // MVI only public final int reg; public InstrRegExpr(int line, int column, int opcode, int reg) { @@ -19,6 +19,11 @@ public InstrRegExpr(Token opcode, Token reg) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); } + public byte eval() { + int register = InstrReg.registers.get(reg); + return (byte) ((6 | (register << 3)) & 0xFF); + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); @@ -26,7 +31,7 @@ public void accept(NodeVisitor visitor) { @Override protected String toStringShallow() { - return "InstrRegExpr(" + opcode + "," + reg +")"; + return "InstrRegExpr(" + opcode + "," + reg + ")"; } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java index 72ed0211c..90ed3a11d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java @@ -4,10 +4,34 @@ import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import org.antlr.v4.runtime.Token; +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; + public class InstrRegPair extends Node { + private final static Map opcodes = new HashMap<>(); + public final static Map regpairs = new HashMap<>(); + public final int opcode; public final int regPair; + static { + opcodes.put(OPCODE_STAX, 2); + opcodes.put(OPCODE_LDAX, 0xA); + opcodes.put(OPCODE_PUSH, 0xC5); + opcodes.put(OPCODE_POP, 0xC1); + opcodes.put(OPCODE_DAD, 9); + opcodes.put(OPCODE_INX, 3); + opcodes.put(OPCODE_DCX, 0xB); + + regpairs.put(REG_B, 0); + regpairs.put(REG_D, 1); + regpairs.put(REG_H, 2); + regpairs.put(REG_PSW, 3); + regpairs.put(REG_SP, 3); + } + public InstrRegPair(int line, int column, int opcode, int regPair) { super(line, column); this.opcode = opcode; @@ -18,6 +42,12 @@ public InstrRegPair(Token opcode, Token regPair) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); } + public byte eval() { + int result = opcodes.get(opcode); + int rp = regpairs.get(regPair); + return (byte) ((result | (rp << 4)) & 0xFF); + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); @@ -25,7 +55,7 @@ public void accept(NodeVisitor visitor) { @Override protected String toStringShallow() { - return "InstrRegPair(" + opcode + "," + regPair +")"; + return "InstrRegPair(" + opcode + "," + regPair + ")"; } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java index 6211be8a5..823e9099a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java @@ -19,6 +19,11 @@ public InstrRegPairExpr(Token opcode, Token regPair) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); } + public byte eval() { + int rp = InstrRegPair.regpairs.get(regPair); + return (byte) ((1 | (rp << 4)) & 0xFF); + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); @@ -26,7 +31,7 @@ public void accept(NodeVisitor visitor) { @Override protected String toStringShallow() { - return "InstrRegPairExpr(" + opcode + "," + regPair +")"; + return "InstrRegPairExpr(" + opcode + "," + regPair + ")"; } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java index 8ee1887ba..7dc6d3e3f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java @@ -5,7 +5,7 @@ import org.antlr.v4.runtime.Token; public class InstrRegReg extends Node { - public final int opcode; + public final int opcode; // MOV only public final int srcReg; public final int dstReg; @@ -20,6 +20,12 @@ public InstrRegReg(Token opcode, Token dst, Token src) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), dst.getType(), src.getType()); } + public byte eval() { + int srcRegister = InstrReg.registers.get(srcReg); + int dstRegister = InstrReg.registers.get(dstReg); + return (byte)((0x40 | (dstRegister << 3) | (srcRegister)) & 0xFF); // TODO: mov M, M == HLT + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java index 22582549d..bb8d667ed 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java @@ -5,8 +5,10 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegPairExpr; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroArgument; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoOrg; import static net.emustudio.plugins.compiler.as8080.CompileError.expressionIsBiggerThanExpected; @@ -35,6 +37,12 @@ public void visit(DataDS node) { visitChildren(node); } + @Override + public void visit(InstrExpr node) { + expectedBytes = node.getExprSizeBytes(); + visitChildren(node); + } + @Override public void visit(InstrRegExpr node) { expectedBytes = 1; @@ -53,6 +61,11 @@ public void visit(PseudoOrg node) { visitChildren(node); } + @Override + public void visit(PseudoMacroArgument node) { + node.remove(); + } + @Override public void visit(Evaluated node) { long maxNumber = Long.MAX_VALUE >>> (63 - expectedBytes * 8); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java index 1fa188b3d..2386cfb44 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java @@ -11,11 +11,11 @@ import java.util.Objects; +import static net.emustudio.plugins.compiler.as8080.CompileError.valueMustBePositive; + public class GenerateCodeVisitor extends NodeVisitor { private final IntelHEX hex; - - private int currentAddress; - private Evaluated lastEval; + private int expectedBytes; public GenerateCodeVisitor(IntelHEX hex) { this.hex = Objects.requireNonNull(hex); @@ -23,56 +23,93 @@ public GenerateCodeVisitor(IntelHEX hex) { @Override public void visit(DataDB node) { - super.visit(node); + expectedBytes = 1; + visitChildren(node); } @Override public void visit(DataDW node) { - super.visit(node); + expectedBytes = 2; + visitChildren(node); } @Override public void visit(DataDS node) { - super.visit(node); + node.collectChild(Evaluated.class) + .ifPresent(e -> { + if (e.value < 0) { + error(valueMustBePositive(e)); + } else { + for (int i = 0; i < e.value; i++) { + hex.add((byte) 0); + } + } + }); } @Override public void visit(InstrExpr node) { - super.visit(node); + hex.add(node.eval()); + expectedBytes = node.getExprSizeBytes(); + visitChildren(node); } @Override public void visit(InstrNoArgs node) { - super.visit(node); + hex.add(node.eval()); } @Override public void visit(InstrReg node) { - super.visit(node); + hex.add(node.eval()); } @Override public void visit(InstrRegExpr node) { - super.visit(node); + hex.add(node.eval()); + expectedBytes = 1; + visitChildren(node); } @Override public void visit(InstrRegPair node) { - super.visit(node); + hex.add(node.eval()); } @Override public void visit(InstrRegPairExpr node) { - super.visit(node); + hex.add(node.eval()); + expectedBytes = 2; + visitChildren(node); } @Override public void visit(InstrRegReg node) { - super.visit(node); + hex.add(node.eval()); } @Override public void visit(PseudoOrg node) { - super.visit(node); + node.collectChild(Evaluated.class) + .ifPresent(e -> { + if (e.value < 0) { + error(valueMustBePositive(node)); + } else { + hex.setNextAddress(e.value); + } + }); + } + + @Override + public void visit(Evaluated node) { + if (expectedBytes == 1) { + hex.add((byte) (node.value & 0xFF)); + } else if (expectedBytes == 2) { + byte byte0 = (byte) (node.value & 0xFF); + byte byte1 = (byte) (node.value >>> 8); + + hex.add(byte0); + hex.add(byte1); + } } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java index b5da5f19f..4ace19e11 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java @@ -5,13 +5,17 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegPairExpr; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroArgument; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroCall; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoOrg; import org.junit.Test; import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; import static net.emustudio.plugins.compiler.as8080.CompileError.ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED; +import static net.emustudio.plugins.compiler.as8080.Utils.assertTrees; import static org.junit.Assert.assertTrue; public class CheckExprSizesVisitorTest { @@ -173,4 +177,40 @@ public void testPseudoOrgThreeBytes() { assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); } + + @Test + public void testMacroArgumentsAreRemoved() { + Program program = new Program(); + program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))), + program + ); + } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java new file mode 100644 index 000000000..8ce7c851b --- /dev/null +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java @@ -0,0 +1,399 @@ +package net.emustudio.plugins.compiler.as8080.visitors; + +import net.emustudio.emulib.runtime.io.IntelHEX; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.Program; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; +import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; +import net.emustudio.plugins.compiler.as8080.ast.instr.*; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroCall; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoOrg; +import org.junit.Test; + +import java.util.Map; + +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; +import static org.junit.Assert.assertEquals; + +public class GenerateCodeVisitorTest { + + @Test + public void testCodeGeneration() { + Program program = new Program(); + program + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 255)) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 4)))) + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 5))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0xFEAB))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_D) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_H) + .addChild(new Evaluated(0, 0, 0x1234)))); + + IntelHEX hex = new IntelHEX(); + GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); + visitor.visit(program); + Map code = hex.getCode(); + + assertEquals((byte) 255, code.get(0).byteValue()); + assertEquals((byte) 0xe7, code.get(1).byteValue()); + assertEquals(1, code.get(2).byteValue()); // dw - lower byte + assertEquals(0, code.get(3).byteValue()); // dw - upper byte + assertEquals(0, code.get(4).byteValue()); + assertEquals(0, code.get(5).byteValue()); + assertEquals(0, code.get(6).byteValue()); + assertEquals(0, code.get(7).byteValue()); + assertEquals(0, code.get(8).byteValue()); + assertEquals(1, code.get(9).byteValue()); // lxi b + assertEquals((byte) 0xAB, code.get(10).byteValue()); + assertEquals((byte) 0xFE, code.get(11).byteValue()); + assertEquals(0x11, code.get(12).byteValue()); // lxi d + assertEquals(1, code.get(13).byteValue()); + assertEquals(0, code.get(14).byteValue()); + assertEquals(0x21, code.get(15).byteValue()); // lxi h + assertEquals(0x34, code.get(16).byteValue()); + assertEquals(0x12, code.get(17).byteValue()); + } + + @Test + public void testPseudoOrg() { + Program program = new Program(); + program + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0, 0, 5))) + .addChild(new InstrExpr(0, 0, OPCODE_CNZ) + .addChild(new Evaluated(0, 0, 0x400))) + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrNoArgs(0, 0, OPCODE_XCHG)); + + IntelHEX hex = new IntelHEX(); + GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); + visitor.visit(program); + Map code = hex.getCode(); + + assertEquals((byte) 0xeb, code.get(0).byteValue()); + assertEquals((byte) 0xc4, code.get(5).byteValue()); + assertEquals(0, code.get(6).byteValue()); + assertEquals(4, code.get(7).byteValue()); + } + + @Test + public void testGenerateInstructions() { + Program program = new Program(); + program + .addChild(new InstrNoArgs(0, 0, OPCODE_NOP)) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrRegPair(0, 0, OPCODE_STAX, REG_B)) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_B)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) + .addChild(new Evaluated(0, 0, 7))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RLC)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_B)) + .addChild(new InstrRegPair(0, 0, OPCODE_LDAX, REG_B)) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_C)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_C) + .addChild(new Evaluated(0, 0, 8))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_D) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_STAX, REG_D)) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_D)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_D) + .addChild(new Evaluated(0, 0, 9))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RAL)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_D)) + .addChild(new InstrRegPair(0, 0, OPCODE_LDAX, REG_D)) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_E)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_E) + .addChild(new Evaluated(0, 0, 10))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RAR)) + ; + + IntelHEX hex = new IntelHEX(); + GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); + visitor.visit(program); + Map code = hex.getCode(); + + assertEquals(0, code.get(0).byteValue()); // NOP + assertEquals(1, code.get(1).byteValue()); // LXI B,D16 + assertEquals(0x34, code.get(2).byteValue()); + assertEquals(0x12, code.get(3).byteValue()); + assertEquals(2, code.get(4).byteValue()); // STAX B + assertEquals(3, code.get(5).byteValue()); // INX B + assertEquals(4, code.get(6).byteValue()); // INR B + assertEquals(5, code.get(7).byteValue()); // DCR B + assertEquals(6, code.get(8).byteValue()); // MVI B + assertEquals(7, code.get(9).byteValue()); + assertEquals(7, code.get(10).byteValue()); // RLC + assertEquals(9, code.get(11).byteValue()); // DAD B + assertEquals(0x0A, code.get(12).byteValue()); // LDAX B + assertEquals(0x0B, code.get(13).byteValue()); // DCX B + assertEquals(0x0C, code.get(14).byteValue()); // INR C + assertEquals(0x0D, code.get(15).byteValue()); // DCR C + assertEquals(0x0E, code.get(16).byteValue()); // MVI C + assertEquals(8, code.get(17).byteValue()); + assertEquals(0x0F, code.get(18).byteValue()); // RRC + assertEquals(0x11, code.get(19).byteValue()); // LXI D + assertEquals(0x45, code.get(20).byteValue()); + assertEquals(0x23, code.get(21).byteValue()); + assertEquals(0x12, code.get(22).byteValue()); // STAX D + assertEquals(0x13, code.get(23).byteValue()); // INX D + assertEquals(0x14, code.get(24).byteValue()); // INR D + assertEquals(0x15, code.get(25).byteValue()); // DCR D + assertEquals(0x16, code.get(26).byteValue()); // MVI D + assertEquals(9, code.get(27).byteValue()); + assertEquals(0x17, code.get(28).byteValue()); // RAL + assertEquals(0x19, code.get(29).byteValue()); // DAD D + assertEquals(0x1A, code.get(30).byteValue()); // LDAX D + assertEquals(0x1B, code.get(31).byteValue()); // DCX D + assertEquals(0x1C, code.get(32).byteValue()); // INR E + assertEquals(0x1D, code.get(33).byteValue()); // DCR E + assertEquals(0x1E, code.get(34).byteValue()); // MVI E + assertEquals(10, code.get(35).byteValue()); + assertEquals(0x1F, code.get(36).byteValue()); // RAR + + //0x21 LXI H,D16 3 H <- byte 3, L <- byte 2 + //0x22 SHLD adr 3 (adr) <-L; (adr+1)<-H + //0x23 INX H 1 HL <- HL + 1 + //0x24 INR H 1 Z, S, P, AC H <- H+1 + //0x25 DCR H 1 Z, S, P, AC H <- H-1 + //0x26 MVI H,D8 2 H <- byte 2 + //0x27 DAA 1 special + //0x28 - + //0x29 DAD H 1 CY HL = HL + HI + //0x2a LHLD adr 3 L <- (adr); H<-(adr+1) + //0x2b DCX H 1 HL = HL-1 + //0x2c INR L 1 Z, S, P, AC L <- L+1 + //0x2d DCR L 1 Z, S, P, AC L <- L-1 + //0x2e MVI L, D8 2 L <- byte 2 + //0x2f CMA 1 A <- !A + //0x30 - + //0x31 LXI SP, D16 3 SP.hi <- byte 3, SP.lo <- byte 2 + //0x32 STA adr 3 (adr) <- A + //0x33 INX SP 1 SP = SP + 1 + //0x34 INR M 1 Z, S, P, AC (HL) <- (HL)+1 + //0x35 DCR M 1 Z, S, P, AC (HL) <- (HL)-1 + //0x36 MVI M,D8 2 (HL) <- byte 2 + //0x37 STC 1 CY CY = 1 + //0x38 - + //0x39 DAD SP 1 CY HL = HL + SP + //0x3a LDA adr 3 A <- (adr) + //0x3b DCX SP 1 SP = SP-1 + //0x3c INR A 1 Z, S, P, AC A <- A+1 + //0x3d DCR A 1 Z, S, P, AC A <- A-1 + //0x3e MVI A,D8 2 A <- byte 2 + //0x3f CMC 1 CY CY=!CY + //0x40 MOV B,B 1 B <- B + //0x41 MOV B,C 1 B <- C + //0x42 MOV B,D 1 B <- D + //0x43 MOV B,E 1 B <- E + //0x44 MOV B,H 1 B <- H + //0x45 MOV B,L 1 B <- L + //0x46 MOV B,M 1 B <- (HL) + //0x47 MOV B,A 1 B <- A + //0x48 MOV C,B 1 C <- B + //0x49 MOV C,C 1 C <- C + //0x4a MOV C,D 1 C <- D + //0x4b MOV C,E 1 C <- E + //0x4c MOV C,H 1 C <- H + //0x4d MOV C,L 1 C <- L + //0x4e MOV C,M 1 C <- (HL) + //0x4f MOV C,A 1 C <- A + //0x50 MOV D,B 1 D <- B + //0x51 MOV D,C 1 D <- C + //0x52 MOV D,D 1 D <- D + //0x53 MOV D,E 1 D <- E + //0x54 MOV D,H 1 D <- H + //0x55 MOV D,L 1 D <- L + //0x56 MOV D,M 1 D <- (HL) + //0x57 MOV D,A 1 D <- A + //0x58 MOV E,B 1 E <- B + //0x59 MOV E,C 1 E <- C + //0x5a MOV E,D 1 E <- D + //0x5b MOV E,E 1 E <- E + //0x5c MOV E,H 1 E <- H + //0x5d MOV E,L 1 E <- L + //0x5e MOV E,M 1 E <- (HL) + //0x5f MOV E,A 1 E <- A + //0x60 MOV H,B 1 H <- B + //0x61 MOV H,C 1 H <- C + //0x62 MOV H,D 1 H <- D + //0x63 MOV H,E 1 H <- E + //0x64 MOV H,H 1 H <- H + //0x65 MOV H,L 1 H <- L + //0x66 MOV H,M 1 H <- (HL) + //0x67 MOV H,A 1 H <- A + //0x68 MOV L,B 1 L <- B + //0x69 MOV L,C 1 L <- C + //0x6a MOV L,D 1 L <- D + //0x6b MOV L,E 1 L <- E + //0x6c MOV L,H 1 L <- H + //0x6d MOV L,L 1 L <- L + //0x6e MOV L,M 1 L <- (HL) + //0x6f MOV L,A 1 L <- A + //0x70 MOV M,B 1 (HL) <- B + //0x71 MOV M,C 1 (HL) <- C + //0x72 MOV M,D 1 (HL) <- D + //0x73 MOV M,E 1 (HL) <- E + //0x74 MOV M,H 1 (HL) <- H + //0x75 MOV M,L 1 (HL) <- L + //0x76 HLT 1 special + //0x77 MOV M,A 1 (HL) <- A + //0x78 MOV A,B 1 A <- B + //0x79 MOV A,C 1 A <- C + //0x7a MOV A,D 1 A <- D + //0x7b MOV A,E 1 A <- E + //0x7c MOV A,H 1 A <- H + //0x7d MOV A,L 1 A <- L + //0x7e MOV A,M 1 A <- (HL) + //0x7f MOV A,A 1 A <- A + //0x80 ADD B 1 Z, S, P, CY, AC A <- A + B + //0x81 ADD C 1 Z, S, P, CY, AC A <- A + C + //0x82 ADD D 1 Z, S, P, CY, AC A <- A + D + //0x83 ADD E 1 Z, S, P, CY, AC A <- A + E + //0x84 ADD H 1 Z, S, P, CY, AC A <- A + H + //0x85 ADD L 1 Z, S, P, CY, AC A <- A + L + //0x86 ADD M 1 Z, S, P, CY, AC A <- A + (HL) + //0x87 ADD A 1 Z, S, P, CY, AC A <- A + A + //0x88 ADC B 1 Z, S, P, CY, AC A <- A + B + CY + //0x89 ADC C 1 Z, S, P, CY, AC A <- A + C + CY + //0x8a ADC D 1 Z, S, P, CY, AC A <- A + D + CY + //0x8b ADC E 1 Z, S, P, CY, AC A <- A + E + CY + //0x8c ADC H 1 Z, S, P, CY, AC A <- A + H + CY + //0x8d ADC L 1 Z, S, P, CY, AC A <- A + L + CY + //0x8e ADC M 1 Z, S, P, CY, AC A <- A + (HL) + CY + //0x8f ADC A 1 Z, S, P, CY, AC A <- A + A + CY + //0x90 SUB B 1 Z, S, P, CY, AC A <- A - B + //0x91 SUB C 1 Z, S, P, CY, AC A <- A - C + //0x92 SUB D 1 Z, S, P, CY, AC A <- A + D + //0x93 SUB E 1 Z, S, P, CY, AC A <- A - E + //0x94 SUB H 1 Z, S, P, CY, AC A <- A + H + //0x95 SUB L 1 Z, S, P, CY, AC A <- A - L + //0x96 SUB M 1 Z, S, P, CY, AC A <- A + (HL) + //0x97 SUB A 1 Z, S, P, CY, AC A <- A - A + //0x98 SBB B 1 Z, S, P, CY, AC A <- A - B - CY + //0x99 SBB C 1 Z, S, P, CY, AC A <- A - C - CY + //0x9a SBB D 1 Z, S, P, CY, AC A <- A - D - CY + //0x9b SBB E 1 Z, S, P, CY, AC A <- A - E - CY + //0x9c SBB H 1 Z, S, P, CY, AC A <- A - H - CY + //0x9d SBB L 1 Z, S, P, CY, AC A <- A - L - CY + //0x9e SBB M 1 Z, S, P, CY, AC A <- A - (HL) - CY + //0x9f SBB A 1 Z, S, P, CY, AC A <- A - A - CY + //0xa0 ANA B 1 Z, S, P, CY, AC A <- A & B + //0xa1 ANA C 1 Z, S, P, CY, AC A <- A & C + //0xa2 ANA D 1 Z, S, P, CY, AC A <- A & D + //0xa3 ANA E 1 Z, S, P, CY, AC A <- A & E + //0xa4 ANA H 1 Z, S, P, CY, AC A <- A & H + //0xa5 ANA L 1 Z, S, P, CY, AC A <- A & L + //0xa6 ANA M 1 Z, S, P, CY, AC A <- A & (HL) + //0xa7 ANA A 1 Z, S, P, CY, AC A <- A & A + //0xa8 XRA B 1 Z, S, P, CY, AC A <- A ^ B + //0xa9 XRA C 1 Z, S, P, CY, AC A <- A ^ C + //0xaa XRA D 1 Z, S, P, CY, AC A <- A ^ D + //0xab XRA E 1 Z, S, P, CY, AC A <- A ^ E + //0xac XRA H 1 Z, S, P, CY, AC A <- A ^ H + //0xad XRA L 1 Z, S, P, CY, AC A <- A ^ L + //0xae XRA M 1 Z, S, P, CY, AC A <- A ^ (HL) + //0xaf XRA A 1 Z, S, P, CY, AC A <- A ^ A + //0xb0 ORA B 1 Z, S, P, CY, AC A <- A | B + //0xb1 ORA C 1 Z, S, P, CY, AC A <- A | C + //0xb2 ORA D 1 Z, S, P, CY, AC A <- A | D + //0xb3 ORA E 1 Z, S, P, CY, AC A <- A | E + //0xb4 ORA H 1 Z, S, P, CY, AC A <- A | H + //0xb5 ORA L 1 Z, S, P, CY, AC A <- A | L + //0xb6 ORA M 1 Z, S, P, CY, AC A <- A | (HL) + //0xb7 ORA A 1 Z, S, P, CY, AC A <- A | A + //0xb8 CMP B 1 Z, S, P, CY, AC A - B + //0xb9 CMP C 1 Z, S, P, CY, AC A - C + //0xba CMP D 1 Z, S, P, CY, AC A - D + //0xbb CMP E 1 Z, S, P, CY, AC A - E + //0xbc CMP H 1 Z, S, P, CY, AC A - H + //0xbd CMP L 1 Z, S, P, CY, AC A - L + //0xbe CMP M 1 Z, S, P, CY, AC A - (HL) + //0xbf CMP A 1 Z, S, P, CY, AC A - A + //0xc0 RNZ 1 if NZ, RET + //0xc1 POP B 1 C <- (sp); B <- (sp+1); sp <- sp+2 + //0xc2 JNZ adr 3 if NZ, PC <- adr + //0xc3 JMP adr 3 PC <= adr + //0xc4 CNZ adr 3 if NZ, CALL adr + //0xc5 PUSH B 1 (sp-2)<-C; (sp-1)<-B; sp <- sp - 2 + //0xc6 ADI D8 2 Z, S, P, CY, AC A <- A + byte + //0xc7 RST 0 1 CALL $0 + //0xc8 RZ 1 if Z, RET + //0xc9 RET 1 PC.lo <- (sp); PC.hi<-(sp+1); SP <- SP+2 + //0xca JZ adr 3 if Z, PC <- adr + //0xcb - + //0xcc CZ adr 3 if Z, CALL adr + //0xcd CALL adr 3 (SP-1)<-PC.hi;(SP-2)<-PC.lo;SP<-SP-2;PC=adr + //0xce ACI D8 2 Z, S, P, CY, AC A <- A + data + CY + //0xcf RST 1 1 CALL $8 + //0xd0 RNC 1 if NCY, RET + //0xd1 POP D 1 E <- (sp); D <- (sp+1); sp <- sp+2 + //0xd2 JNC adr 3 if NCY, PC<-adr + //0xd3 OUT D8 2 special + //0xd4 CNC adr 3 if NCY, CALL adr + //0xd5 PUSH D 1 (sp-2)<-E; (sp-1)<-D; sp <- sp - 2 + //0xd6 SUI D8 2 Z, S, P, CY, AC A <- A - data + //0xd7 RST 2 1 CALL $10 + //0xd8 RC 1 if CY, RET + //0xd9 - + //0xda JC adr 3 if CY, PC<-adr + //0xdb IN D8 2 special + //0xdc CC adr 3 if CY, CALL adr + //0xdd - + //0xde SBI D8 2 Z, S, P, CY, AC A <- A - data - CY + //0xdf RST 3 1 CALL $18 + //0xe0 RPO 1 if PO, RET + //0xe1 POP H 1 L <- (sp); H <- (sp+1); sp <- sp+2 + //0xe2 JPO adr 3 if PO, PC <- adr + //0xe3 XTHL 1 L <-> (SP); H <-> (SP+1) + //0xe4 CPO adr 3 if PO, CALL adr + //0xe5 PUSH H 1 (sp-2)<-L; (sp-1)<-H; sp <- sp - 2 + //0xe6 ANI D8 2 Z, S, P, CY, AC A <- A & data + //0xe7 RST 4 1 CALL $20 + //0xe8 RPE 1 if PE, RET + //0xe9 PCHL 1 PC.hi <- H; PC.lo <- L + //0xea JPE adr 3 if PE, PC <- adr + //0xeb XCHG 1 H <-> D; L <-> E + //0xec CPE adr 3 if PE, CALL adr + //0xed - + //0xee XRI D8 2 Z, S, P, CY, AC A <- A ^ data + //0xef RST 5 1 CALL $28 + //0xf0 RP 1 if P, RET + //0xf1 POP PSW 1 flags <- (sp); A <- (sp+1); sp <- sp+2 + //0xf2 JP adr 3 if P=1 PC <- adr + //0xf3 DI 1 special + //0xf4 CP adr 3 if P, PC <- adr + //0xf5 PUSH PSW 1 (sp-2)<-flags; (sp-1)<-A; sp <- sp - 2 + //0xf6 ORI D8 2 Z, S, P, CY, AC A <- A | data + //0xf7 RST 6 1 CALL $30 + //0xf8 RM 1 if M, RET + //0xf9 SPHL 1 SP=HL + //0xfa JM adr 3 if M, PC <- adr + //0xfb EI 1 special + //0xfc CM adr 3 if M, CALL adr + //0xfd - + //0xfe CPI D8 2 Z, S, P, CY, AC A - data + //0xff RST 7 1 CALL $38 + } + +} From 7bfdb45853f3b086028921b1174de55867059c6f Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 15 Jan 2022 09:39:05 +0100 Subject: [PATCH 075/314] [#201] as-8080: enable other tests --- .../compiler/as8080/Assembler8080.java | 9 +- .../plugins/compiler/as8080/Lexer.java | 194 ----------------- .../compiler/as8080/LexicalAnalyzerImpl.java | 2 +- .../plugins/compiler/as8080/Namespace.java | 132 ------------ .../compiler/as8080/ParserErrorListener.java | 2 +- .../plugins/compiler/as8080/ParsingUtils.java | 12 -- .../compiler/as8080/ast/Evaluated.java | 2 + .../plugins/compiler/as8080/ast/Node.java | 5 +- .../plugins/compiler/as8080/ast/Program.java | 2 + .../compiler/as8080/ast/data/DataDB.java | 2 +- .../compiler/as8080/ast/data/DataDS.java | 2 +- .../compiler/as8080/ast/data/DataDW.java | 2 +- .../as8080/ast/expr/ExprCurrentAddress.java | 2 +- .../compiler/as8080/ast/expr/ExprId.java | 2 +- .../compiler/as8080/ast/expr/ExprInfix.java | 2 +- .../compiler/as8080/ast/expr/ExprNumber.java | 2 +- .../compiler/as8080/ast/expr/ExprUnary.java | 2 +- .../compiler/as8080/ast/instr/InstrExpr.java | 18 +- .../as8080/ast/instr/InstrNoArgs.java | 2 +- .../compiler/as8080/ast/instr/InstrReg.java | 2 +- .../as8080/ast/instr/InstrRegExpr.java | 2 +- .../as8080/ast/instr/InstrRegPair.java | 2 +- .../as8080/ast/instr/InstrRegPairExpr.java | 2 +- .../as8080/ast/instr/InstrRegReg.java | 2 +- .../compiler/as8080/ast/pseudo/PseudoEqu.java | 2 +- .../compiler/as8080/ast/pseudo/PseudoIf.java | 2 +- .../as8080/ast/pseudo/PseudoIfExpression.java | 2 +- .../as8080/ast/pseudo/PseudoInclude.java | 2 +- .../as8080/ast/pseudo/PseudoLabel.java | 2 +- .../ast/pseudo/PseudoMacroArgument.java | 2 +- .../as8080/ast/pseudo/PseudoMacroCall.java | 2 +- .../as8080/ast/pseudo/PseudoMacroDef.java | 2 +- .../ast/pseudo/PseudoMacroParameter.java | 2 +- .../compiler/as8080/ast/pseudo/PseudoOrg.java | 2 +- .../compiler/as8080/ast/pseudo/PseudoSet.java | 2 +- .../exceptions/AlreadyDefinedException.java | 26 --- .../as8080/exceptions/AmbiguousException.java | 26 --- .../exceptions/{used => }/FatalError.java | 3 +- .../InvalidMacroParamsCountException.java | 26 --- .../exceptions/NeedMorePassException.java | 33 --- .../exceptions/NegativeValueException.java | 26 --- .../{used => }/SyntaxErrorException.java | 4 +- .../exceptions/UndefinedMacroException.java | 26 --- .../exceptions/UnexpectedEOFException.java | 26 --- .../UnknownMacroParametersException.java | 25 --- .../exceptions/ValueTooBigException.java | 26 --- .../used/AlreadyDeclaredException.java | 11 - .../used/CouldNotReadFileException.java | 11 - .../as8080/tree/AddressValueNode.java | 36 ---- .../compiler/as8080/tree/ArithNode.java | 94 -------- .../compiler/as8080/tree/DBDataNode.java | 100 --------- .../compiler/as8080/tree/DSDataNode.java | 74 ------- .../compiler/as8080/tree/DWDataNode.java | 64 ------ .../compiler/as8080/tree/DataNode.java | 70 ------ .../as8080/tree/DecimalValueNode.java | 46 ---- .../compiler/as8080/tree/EquPseudoNode.java | 63 ------ .../plugins/compiler/as8080/tree/IdExpr.java | 68 ------ .../compiler/as8080/tree/IfPseudoNode.java | 91 -------- .../as8080/tree/IncludePseudoNode.java | 135 ------------ .../compiler/as8080/tree/InstructionNode.java | 113 ---------- .../compiler/as8080/tree/LabelNode.java | 64 ------ .../compiler/as8080/tree/MacroCallPseudo.java | 95 -------- .../compiler/as8080/tree/MacroPseudoNode.java | 113 ---------- .../plugins/compiler/as8080/tree/OC_Expr.java | 203 ------------------ .../compiler/as8080/tree/OC_NoParams.java | 128 ----------- .../plugins/compiler/as8080/tree/OC_Reg.java | 89 -------- .../compiler/as8080/tree/OC_RegExpr.java | 73 ------- .../compiler/as8080/tree/OC_RegReg.java | 66 ------ .../compiler/as8080/tree/OC_Regpair.java | 80 ------- .../compiler/as8080/tree/OC_RegpairExpr.java | 62 ------ .../compiler/as8080/tree/OrgPseudoNode.java | 73 ------- .../compiler/as8080/tree/SetPseudoNode.java | 71 ------ .../compiler/as8080/tree/Statement.java | 151 ------------- .../as8080/treeAbstract/CodeNode.java | 27 --- .../as8080/treeAbstract/CodePseudoNode.java | 43 ---- .../as8080/treeAbstract/DataValueNode.java | 50 ----- .../as8080/treeAbstract/ExprNode.java | 55 ----- .../as8080/treeAbstract/OpCodeNode.java | 28 --- .../as8080/treeAbstract/PseudoBlock.java | 28 --- .../as8080/treeAbstract/PseudoNode.java | 32 --- .../visitors/CheckDeclarationsVisitor.java | 1 - .../visitors/CheckExprSizesVisitor.java | 1 - .../as8080/visitors/EvaluateExprVisitor.java | 1 - .../visitors/ExpandIncludesVisitor.java | 1 - .../as8080/visitors/ExpandMacrosVisitor.java | 1 - .../as8080/visitors/GenerateCodeVisitor.java | 1 - .../as8080/{ast => visitors}/NodeVisitor.java | 8 +- .../visitors/SortMacroArgumentsVisitor.java | 1 - .../plugins/compiler/as8080/RunnerTest.java | 2 - .../plugins/compiler/as8080/Utils.java | 2 - .../{ => e2e}/AbstractCompilerTest.java | 3 +- .../as8080/{ => e2e}/Assembler8080Test.java | 4 +- .../{ => e2e}/ConstantsAndVariablesTest.java | 4 +- .../compiler/as8080/{ => e2e}/DataTest.java | 4 +- .../compiler/as8080/{ => e2e}/IfNodeTest.java | 4 +- .../as8080/{ => e2e}/IncludeTest.java | 4 +- .../InstrExprTest.java} | 6 +- .../InstrRegTest.java} | 15 +- .../compiler/as8080/{ => e2e}/MacroTest.java | 4 +- .../{ORGTest.java => e2e/PseudoOrgTest.java} | 23 +- .../LexicalAnalyzerImplTest.java} | 4 +- .../as8080/{ => parser}/ParseDataTest.java | 2 +- .../as8080/{ => parser}/ParseExprTest.java | 2 +- .../as8080/{ => parser}/ParseInstrTest.java | 2 +- .../as8080/{ => parser}/ParsePseudoTest.java | 4 +- .../as8080/{ => parser}/ParsingUtilsTest.java | 10 +- .../visitors/ExpandIncludesVisitorTest.java | 2 +- .../as8080/visitors/ExpandMacrosTest.java | 2 +- 108 files changed, 85 insertions(+), 3215 deletions(-) delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Namespace.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDefinedException.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AmbiguousException.java rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/{used => }/FatalError.java (77%) delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InvalidMacroParamsCountException.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NeedMorePassException.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NegativeValueException.java rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/{used => }/SyntaxErrorException.java (69%) delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UndefinedMacroException.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnexpectedEOFException.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownMacroParametersException.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/ValueTooBigException.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/AlreadyDeclaredException.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/CouldNotReadFileException.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/AddressValueNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/ArithNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DecimalValueNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/LabelNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/Statement.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodeNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodePseudoNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/DataValueNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/ExprNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/OpCodeNode.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/PseudoBlock.java delete mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/PseudoNode.java rename plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/{ast => visitors}/NodeVisitor.java (90%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => e2e}/AbstractCompilerTest.java (97%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => e2e}/Assembler8080Test.java (97%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => e2e}/ConstantsAndVariablesTest.java (97%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => e2e}/DataTest.java (98%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => e2e}/IfNodeTest.java (96%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => e2e}/IncludeTest.java (97%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{OC_ExprTest.java => e2e/InstrExprTest.java} (70%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{OC_RegTest.java => e2e/InstrRegTest.java} (92%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => e2e}/MacroTest.java (97%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ORGTest.java => e2e/PseudoOrgTest.java} (86%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{LexerTest.java => parser/LexicalAnalyzerImplTest.java} (99%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => parser}/ParseDataTest.java (98%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => parser}/ParseExprTest.java (99%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => parser}/ParseInstrTest.java (99%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => parser}/ParsePseudoTest.java (97%) rename plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/{ => parser}/ParsingUtilsTest.java (86%) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index cce9023ce..f8896521e 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -30,7 +30,7 @@ import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; import net.emustudio.plugins.compiler.as8080.visitors.*; @@ -99,8 +99,13 @@ public String getDescription() { @Override public LexicalAnalyzer createLexer(String s) { + // @Override + // public LexicalAnalyzer createLexer(String s) { + // SSEMLexer lexer = createLexer(CharStreams.fromString(s)); + // return new LexicalAnalyzerImpl(lexer); + // } As8080Lexer lexer = createLexer(CharStreams.fromString(s)); - return new Lexer(lexer); + return new LexicalAnalyzerImpl(lexer); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java deleted file mode 100644 index feb62d0dd..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Lexer.java +++ /dev/null @@ -1,194 +0,0 @@ -package net.emustudio.plugins.compiler.as8080; - -import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; -import net.emustudio.emulib.plugins.compiler.Token; -import org.antlr.v4.runtime.CharStreams; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Objects; - -import static net.emustudio.plugins.compiler.as8080.As8080Lexer.*; - -public class Lexer implements LexicalAnalyzer { - private final As8080Lexer lexer; - private static final int[] tokenMap = new int[As8080Lexer.EOL + 1]; // As8080Lexer.ERROR is the highest number - - static { - tokenMap[COMMENT] = Token.COMMENT; - tokenMap[EOL] = Token.WHITESPACE; - tokenMap[WS] = Token.WHITESPACE; - tokenMap[OPCODE_STC] = Token.RESERVED; - tokenMap[OPCODE_CMC] = Token.RESERVED; - tokenMap[OPCODE_INR] = Token.RESERVED; - tokenMap[OPCODE_DCR] = Token.RESERVED; - tokenMap[OPCODE_CMA] = Token.RESERVED; - tokenMap[OPCODE_DAA] = Token.RESERVED; - tokenMap[OPCODE_NOP] = Token.RESERVED; - tokenMap[OPCODE_MOV] = Token.RESERVED; - tokenMap[OPCODE_STAX] = Token.RESERVED; - tokenMap[OPCODE_LDAX] = Token.RESERVED; - tokenMap[OPCODE_ADD] = Token.RESERVED; - tokenMap[OPCODE_ADC] = Token.RESERVED; - tokenMap[OPCODE_SUB] = Token.RESERVED; - tokenMap[OPCODE_SBB] = Token.RESERVED; - tokenMap[OPCODE_ANA] = Token.RESERVED; - tokenMap[OPCODE_XRA] = Token.RESERVED; - tokenMap[OPCODE_ORA] = Token.RESERVED; - tokenMap[OPCODE_CMP] = Token.RESERVED; - tokenMap[OPCODE_RLC] = Token.RESERVED; - tokenMap[OPCODE_RRC] = Token.RESERVED; - tokenMap[OPCODE_RAL] = Token.RESERVED; - tokenMap[OPCODE_RAR] = Token.RESERVED; - tokenMap[OPCODE_PUSH] = Token.RESERVED; - tokenMap[OPCODE_POP] = Token.RESERVED; - tokenMap[OPCODE_DAD] = Token.RESERVED; - tokenMap[OPCODE_INX] = Token.RESERVED; - tokenMap[OPCODE_DCX] = Token.RESERVED; - tokenMap[OPCODE_XCHG] = Token.RESERVED; - tokenMap[OPCODE_XTHL] = Token.RESERVED; - tokenMap[OPCODE_SPHL] = Token.RESERVED; - tokenMap[OPCODE_LXI] = Token.RESERVED; - tokenMap[OPCODE_MVI] = Token.RESERVED; - tokenMap[OPCODE_ADI] = Token.RESERVED; - tokenMap[OPCODE_ACI] = Token.RESERVED; - tokenMap[OPCODE_SUI] = Token.RESERVED; - tokenMap[OPCODE_SBI] = Token.RESERVED; - tokenMap[OPCODE_ANI] = Token.RESERVED; - tokenMap[OPCODE_XRI] = Token.RESERVED; - tokenMap[OPCODE_ORI] = Token.RESERVED; - tokenMap[OPCODE_CPI] = Token.RESERVED; - tokenMap[OPCODE_STA] = Token.RESERVED; - tokenMap[OPCODE_LDA] = Token.RESERVED; - tokenMap[OPCODE_SHLD] = Token.RESERVED; - tokenMap[OPCODE_LHLD] = Token.RESERVED; - tokenMap[OPCODE_PCHL] = Token.RESERVED; - tokenMap[OPCODE_JMP] = Token.RESERVED; - tokenMap[OPCODE_JC] = Token.RESERVED; - tokenMap[OPCODE_JNC] = Token.RESERVED; - tokenMap[OPCODE_JZ] = Token.RESERVED; - tokenMap[OPCODE_JNZ] = Token.RESERVED; - tokenMap[OPCODE_JP] = Token.RESERVED; - tokenMap[OPCODE_JM] = Token.RESERVED; - tokenMap[OPCODE_JPE] = Token.RESERVED; - tokenMap[OPCODE_JPO] = Token.RESERVED; - tokenMap[OPCODE_CALL] = Token.RESERVED; - tokenMap[OPCODE_CC] = Token.RESERVED; - tokenMap[OPCODE_CNC] = Token.RESERVED; - tokenMap[OPCODE_CZ] = Token.RESERVED; - tokenMap[OPCODE_CNZ] = Token.RESERVED; - tokenMap[OPCODE_CP] = Token.RESERVED; - tokenMap[OPCODE_CM] = Token.RESERVED; - tokenMap[OPCODE_CPE] = Token.RESERVED; - tokenMap[OPCODE_CPO] = Token.RESERVED; - tokenMap[OPCODE_RET] = Token.RESERVED; - tokenMap[OPCODE_RC] = Token.RESERVED; - tokenMap[OPCODE_RNC] = Token.RESERVED; - tokenMap[OPCODE_RZ] = Token.RESERVED; - tokenMap[OPCODE_RNZ] = Token.RESERVED; - tokenMap[OPCODE_RM] = Token.RESERVED; - tokenMap[OPCODE_RP] = Token.RESERVED; - tokenMap[OPCODE_RPE] = Token.RESERVED; - tokenMap[OPCODE_RPO] = Token.RESERVED; - tokenMap[OPCODE_RST] = Token.RESERVED; - tokenMap[OPCODE_EI] = Token.RESERVED; - tokenMap[OPCODE_DI] = Token.RESERVED; - tokenMap[OPCODE_IN] = Token.RESERVED; - tokenMap[OPCODE_OUT] = Token.RESERVED; - tokenMap[OPCODE_HLT] = Token.RESERVED; - - tokenMap[PREP_ORG] = Token.PREPROCESSOR; - tokenMap[PREP_EQU] = Token.PREPROCESSOR; - tokenMap[PREP_SET] = Token.PREPROCESSOR; - tokenMap[PREP_INCLUDE] = Token.PREPROCESSOR; - tokenMap[PREP_IF] = Token.PREPROCESSOR; - tokenMap[PREP_ENDIF] = Token.PREPROCESSOR; - tokenMap[PREP_MACRO] = Token.PREPROCESSOR; - tokenMap[PREP_ENDM] = Token.PREPROCESSOR; - tokenMap[PREP_DB] = Token.PREPROCESSOR; - tokenMap[PREP_DW] = Token.PREPROCESSOR; - tokenMap[PREP_DS] = Token.PREPROCESSOR; - tokenMap[PREP_ADDR] = Token.PREPROCESSOR; - - tokenMap[REG_A] = Token.REGISTER; - tokenMap[REG_B] = Token.REGISTER; - tokenMap[REG_C] = Token.REGISTER; - tokenMap[REG_D] = Token.REGISTER; - tokenMap[REG_E] = Token.REGISTER; - tokenMap[REG_H] = Token.REGISTER; - tokenMap[REG_L] = Token.REGISTER; - tokenMap[REG_M] = Token.REGISTER; - tokenMap[REG_PSW] = Token.REGISTER; - tokenMap[REG_SP] = Token.REGISTER; - - tokenMap[SEP_LPAR] = Token.SEPARATOR; - tokenMap[SEP_RPAR] = Token.SEPARATOR; - tokenMap[SEP_COMMA] = Token.SEPARATOR; - - tokenMap[OP_ADD] = Token.OPERATOR; - tokenMap[OP_SUBTRACT] = Token.OPERATOR; - tokenMap[OP_MULTIPLY] = Token.OPERATOR; - tokenMap[OP_DIVIDE] = Token.OPERATOR; - tokenMap[OP_EQUAL] = Token.OPERATOR; - tokenMap[OP_MOD] = Token.OPERATOR; - tokenMap[OP_SHR] = Token.OPERATOR; - tokenMap[OP_SHL] = Token.OPERATOR; - tokenMap[OP_NOT] = Token.OPERATOR; - tokenMap[OP_AND] = Token.OPERATOR; - tokenMap[OP_OR] = Token.OPERATOR; - tokenMap[OP_XOR] = Token.OPERATOR; - - tokenMap[LIT_NUMBER] =Token.LITERAL; - tokenMap[LIT_HEXNUMBER_1] =Token.LITERAL; - tokenMap[LIT_HEXNUMBER_2] =Token.LITERAL; - tokenMap[LIT_OCTNUMBER] =Token.LITERAL; - tokenMap[LIT_BINNUMBER] =Token.LITERAL; - tokenMap[LIT_STRING_1] =Token.LITERAL; - tokenMap[LIT_STRING_2] =Token.LITERAL; - - tokenMap[ID_IDENTIFIER] = Token.IDENTIFIER; - tokenMap[ID_LABEL] = Token.IDENTIFIER; - - tokenMap[ERROR] = Token.ERROR; - } - - - public Lexer(As8080Lexer lexer) { - this.lexer = Objects.requireNonNull(lexer); - } - - @Override - public Token nextToken() { - org.antlr.v4.runtime.Token token = lexer.nextToken(); - return new Token() { - @Override - public int getType() { - return convertLexerTokenType(token.getType()); - } - - @Override - public int getOffset() { - return token.getStartIndex(); - } - - @Override - public String getText() { - return token.getText(); - } - }; - } - - @Override - public boolean isAtEOF() { - return lexer._hitEOF; - } - - @Override - public void reset(InputStream inputStream) throws IOException { - lexer.setInputStream(CharStreams.fromStream(inputStream)); - } - - private int convertLexerTokenType(int tokenType) { - return tokenMap[tokenType]; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java index 2d5283439..2280f4069 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java @@ -12,7 +12,7 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { private final As8080Lexer lexer; - private static final int[] tokenMap = new int[As8080Lexer.EOL + 1]; // As8080Lexer.ERROR is the highest number + private static final int[] tokenMap = new int[As8080Lexer.EOL + 1]; static { tokenMap[COMMENT] = Token.COMMENT; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Namespace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Namespace.java deleted file mode 100644 index e2ba31970..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Namespace.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080; - -import net.emustudio.plugins.compiler.as8080.tree.*; - -import java.io.File; -import java.util.*; - -public class Namespace { - private final Map labels = new HashMap<>(); - private final Map macros = new HashMap<>(); - private final Map constants = new HashMap<>(); - private final Map variables = new HashMap<>(); - private final List passNeed = new ArrayList<>(); - private final File inputFile; - - public Namespace(String inputFileName) { - this.inputFile = new File(inputFileName); - } - - public File getInputFile() { - return inputFile; - } - - private boolean identifierExists(String name) { - Objects.requireNonNull(name); - - return labels.containsKey(name) - || macros.containsKey(name) - || constants.containsKey(name) - || variables.containsKey(name); - } - - private boolean addIdentifier(Map identifiers, T identifier, String name) { - if (identifiers.get(name) == identifier) { - return true; - } else if (identifierExists(name)) { - return false; - } - identifiers.put(name, identifier); - return true; - } - - public boolean addLabel(LabelNode label) { - return addIdentifier(labels, label, label.getName()); - } - - public LabelNode getLabel(String name) { - return labels.get(name); - } - - public boolean addMacro(MacroPseudoNode macro) { - return addIdentifier(macros, macro, macro.getName()); - } - - public MacroPseudoNode getMacro(String name) { - return macros.get(name); - } - - public boolean addConstant(EquPseudoNode constant) { - return addIdentifier(constants, constant, constant.getName()); - } - - public EquPseudoNode getConstant(String name) { - return constants.get(name); - } - - public boolean setVariable(SetPseudoNode variable) { - if (identifierExists(variable.getName()) && !variables.containsKey(variable.getName())) { - return false; - } - variables.put(variable.getName(), variable); - return true; - } - - public SetPseudoNode getVariable(String name) { - return variables.get(name); - } - - // used in macro block - public void removeAllDefinitions(String name) { - labels.remove(name); - macros.remove(name); - constants.remove(name); - variables.remove(name); - } - - public void copyTo(Namespace env) { - labels.values().forEach(env::addLabel); - macros.values().forEach(env::addMacro); - constants.values().forEach(env::addConstant); - variables.values().forEach(env::setVariable); - } - - public void addPassNeed(InstructionNode n) { - passNeed.add(n); - } - - public int getPassNeedCount() { - return passNeed.size(); - } - - public InstructionNode getPassNeed(int index) { - return passNeed.get(index); - } - - public List getPassNeedView() { - return Collections.unmodifiableList(passNeed); - } - - public void removePassNeed(int index) { - passNeed.remove(index); - } - -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java index aea84ab0c..f6803eeb1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java @@ -1,6 +1,6 @@ package net.emustudio.plugins.compiler.as8080; -import net.emustudio.plugins.compiler.as8080.exceptions.used.SyntaxErrorException; +import net.emustudio.plugins.compiler.as8080.exceptions.SyntaxErrorException; import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Recognizer; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParsingUtils.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParsingUtils.java index c39bcaf5d..55d9395a8 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParsingUtils.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParsingUtils.java @@ -1,6 +1,5 @@ package net.emustudio.plugins.compiler.as8080; -import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; import org.antlr.v4.runtime.Token; import java.util.Locale; @@ -47,17 +46,6 @@ public static int parseLitBin(Token token) { return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 2); } - public static int parseOpcode(Token token) { - switch (token.getText().toLowerCase(Locale.ENGLISH)) { - case "rst": - return 0xC7; - } - throw new CompileException(token.getCharPositionInLine(), token.getLine(), "Unknown instruction opcode: " + token.getText()); - } - - - - public static String parseLabel(Token token) { String rawText = token.getText(); return rawText.substring(0, rawText.length() - 1); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java index 62eba053d..4c48563b4 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Evaluated.java @@ -1,5 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; + public class Evaluated extends Node { public final int value; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 7b3e5b8a7..3163d890d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -1,5 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; + import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -17,10 +19,9 @@ public Node(int line, int column) { this.column = column; } - public Node addChildFirst(Node node) { + public void addChildFirst(Node node) { node.parent = this; children.add(0, node); - return this; } public Node addChild(Node node) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java index 427187cc8..48da39e93 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java @@ -1,5 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; + import java.util.Objects; import java.util.Optional; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java index a90117ac0..79827d6a2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDB.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.data; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; public class DataDB extends Node { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java index 6a0f87726..93e8f7a52 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDS.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.data; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; /** * "Data Store" node. Inserts some space. diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java index 64b6b292f..dd31e9774 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/data/DataDW.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.data; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; public class DataDW extends Node { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java index 27c7f7df7..9d44c10c2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprCurrentAddress.java @@ -3,7 +3,7 @@ import net.emustudio.plugins.compiler.as8080.ast.Evaluated; import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import java.util.Optional; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java index 6c81d8540..0225579de 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprId.java @@ -3,7 +3,7 @@ import net.emustudio.plugins.compiler.as8080.ast.Evaluated; import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.Objects; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index 4dddd2281..af60a892f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -3,7 +3,7 @@ import net.emustudio.plugins.compiler.as8080.ast.Evaluated; import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.HashMap; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java index 4a99fbdb7..dc144fb74 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprNumber.java @@ -3,7 +3,7 @@ import net.emustudio.plugins.compiler.as8080.ast.Evaluated; import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.Optional; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index a9d9daaa9..07070ab81 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -3,7 +3,7 @@ import net.emustudio.plugins.compiler.as8080.ast.Evaluated; import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.Map; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index 5b7960716..02c4f5951 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -2,7 +2,7 @@ import net.emustudio.plugins.compiler.as8080.ast.Evaluated; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.HashMap; @@ -82,20 +82,14 @@ public int getExprSizeBytes() { return 2; // address } - public int getExprMaxValue() { - if (opcode == OPCODE_RST) { - return 7; - } else if (twoBytes.contains(opcode)) { - return 0xFFFF; - } - return 0xFF; - } - public byte eval() { byte result = (byte) (opcodes.get(opcode) & 0xFF); if (opcode == OPCODE_RST) { - int value = collectChild(Evaluated.class).get().value; - result = (byte) (result | (value << 3)); + result = (byte) (result | collectChild(Evaluated.class) + .map(e -> { + int value = e.value; + return (byte) (value << 3); + }).orElse((byte) 0)); } return result; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java index 02f207f8f..7df5d0d64 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.HashMap; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java index b6b8586ea..1f6c618e7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.HashMap; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java index 723ee3bb3..efc0f38db 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegExpr.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; public class InstrRegExpr extends Node { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java index 90ed3a11d..0e3f2e934 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.HashMap; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java index 823e9099a..11396e4bb 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPairExpr.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; public class InstrRegPairExpr extends Node { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java index 7dc6d3e3f..d37755d7a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.instr; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; public class InstrRegReg extends Node { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java index 02b7bc265..b8c4ee6ce 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoEqu.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.Objects; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java index adcc257ad..5914b02b4 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIf.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; public class PseudoIf extends Node { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIfExpression.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIfExpression.java index e0fa02978..d339ee74c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIfExpression.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoIfExpression.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; public class PseudoIfExpression extends Node { public PseudoIfExpression(int line, int column) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java index 7509d3f33..f2031c45b 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoInclude.java @@ -2,7 +2,7 @@ import net.emustudio.plugins.compiler.as8080.ParsingUtils; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.Objects; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java index 23946089d..a961cbbd8 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java @@ -3,7 +3,7 @@ import net.emustudio.plugins.compiler.as8080.ast.Evaluated; import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.Objects; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java index 34becfcdf..7105a4f9a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroArgument.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; /** * Macro call arguments are passed when macro is called. diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java index f709ddc14..2dd153395 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroCall.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.Objects; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java index c520a87ae..30b066d01 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroDef.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.Objects; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java index 8199802d1..d5a026d50 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoMacroParameter.java @@ -2,7 +2,7 @@ import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; /** * Macro definition parameter diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java index d11bc6c40..df425738e 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoOrg.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; public class PseudoOrg extends Node { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java index 9a2055a62..3e7b19f9d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoSet.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.as8080.ast.pseudo; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; import java.util.Objects; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDefinedException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDefinedException.java deleted file mode 100644 index d5c610de9..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AlreadyDefinedException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.exceptions; - -public class AlreadyDefinedException extends CompileException { - - public AlreadyDefinedException(int line, int column, String what) { - super(line, column, what + " is already defined!"); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AmbiguousException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AmbiguousException.java deleted file mode 100644 index 34b4610c5..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/AmbiguousException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.exceptions; - -public class AmbiguousException extends CompileException { - - public AmbiguousException(int line, int column, String whatIsAmbiguous) { - super(line, column, whatIsAmbiguous + " is ambiguous!"); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/FatalError.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/FatalError.java similarity index 77% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/FatalError.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/FatalError.java index a7c3244c1..f415486c4 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/FatalError.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/FatalError.java @@ -1,7 +1,6 @@ -package net.emustudio.plugins.compiler.as8080.exceptions.used; +package net.emustudio.plugins.compiler.as8080.exceptions; import net.emustudio.plugins.compiler.as8080.CompileError; -import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; public class FatalError extends CompileException { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InvalidMacroParamsCountException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InvalidMacroParamsCountException.java deleted file mode 100644 index 80ccc0efd..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/InvalidMacroParamsCountException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.exceptions; - -public class InvalidMacroParamsCountException extends CompileException { - - public InvalidMacroParamsCountException(int column, int line, String name, int expected, int was) { - super(column, line, "Invalid macro(" + name + ") parameters count, expected " + expected + ", but was " + was); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NeedMorePassException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NeedMorePassException.java deleted file mode 100644 index a9f4138c2..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NeedMorePassException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.exceptions; - -/** - * This exception can be thrown during compiling forward references that are in expressions. - *

- * Expression with forward reference for label can't be evaulated without knowing a value of the label (its address that - * label is pointing at). - */ -public class NeedMorePassException extends CompileException { - - public NeedMorePassException(int line, int column) { - super(line, column, ""); - } - -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NegativeValueException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NegativeValueException.java deleted file mode 100644 index 3f2134e5b..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/NegativeValueException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.exceptions; - -public class NegativeValueException extends CompileException { - - public NegativeValueException(int line, int column, int value) { - super(line, column, "Value(" + value + ") cannot be negative!"); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/SyntaxErrorException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/SyntaxErrorException.java similarity index 69% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/SyntaxErrorException.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/SyntaxErrorException.java index e4dd732bf..8d663b282 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/SyntaxErrorException.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/SyntaxErrorException.java @@ -1,6 +1,4 @@ -package net.emustudio.plugins.compiler.as8080.exceptions.used; - -import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; +package net.emustudio.plugins.compiler.as8080.exceptions; public class SyntaxErrorException extends CompileException { public SyntaxErrorException(int line, int column, String message) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UndefinedMacroException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UndefinedMacroException.java deleted file mode 100644 index 1d2f1e6ff..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UndefinedMacroException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.exceptions; - -public class UndefinedMacroException extends CompileException { - - public UndefinedMacroException(int column, int line, String macroName) { - super(column, line, "Undefined macro: " + macroName); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnexpectedEOFException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnexpectedEOFException.java deleted file mode 100644 index a2257db2d..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnexpectedEOFException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.exceptions; - -public class UnexpectedEOFException extends CompileException { - - public UnexpectedEOFException(int line, int column, String filename) { - super(line, column, "Unexpected end of file (" + filename + ")"); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownMacroParametersException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownMacroParametersException.java deleted file mode 100644 index ed6198008..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/UnknownMacroParametersException.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.exceptions; - -public class UnknownMacroParametersException extends CompileException { - public UnknownMacroParametersException(int column, int line, String name) { - super(column, line, "Unknown macro(" + name + ") parameters"); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/ValueTooBigException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/ValueTooBigException.java deleted file mode 100644 index 9abb96405..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/ValueTooBigException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.exceptions; - -public class ValueTooBigException extends CompileException { - - public ValueTooBigException(int line, int column, int currentValue, int maximumValue) { - super(column, line, "Value (" + currentValue + ") too large (maximum is " + maximumValue + ")"); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/AlreadyDeclaredException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/AlreadyDeclaredException.java deleted file mode 100644 index c4c035c4d..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/AlreadyDeclaredException.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.exceptions.used; - -import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; - -public class AlreadyDeclaredException extends CompileException { - private final static String MSG = " was already declared"; - - public AlreadyDeclaredException(int line, int column, String message) { - super(line, column, message + MSG); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/CouldNotReadFileException.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/CouldNotReadFileException.java deleted file mode 100644 index 3d0183456..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/exceptions/used/CouldNotReadFileException.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.emustudio.plugins.compiler.as8080.exceptions.used; - -import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; - -public class CouldNotReadFileException extends CompileException { - private final static String MSG = "Could not read file: "; - - public CouldNotReadFileException(int line, int column, String filename, Throwable cause) { - super(line, column, MSG + filename, cause); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/AddressValueNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/AddressValueNode.java deleted file mode 100644 index 15f8b5d61..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/AddressValueNode.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; - -public class AddressValueNode extends ExprNode { - - @Override - public int eval(Namespace env, int curr_addr) { - this.value = curr_addr; - return curr_addr; - } - - @Override - public String toString() { - return "AddressValueNode{value="+ value +"}"; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/ArithNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/ArithNode.java deleted file mode 100644 index 2760f4e08..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/ArithNode.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; - -public class ArithNode extends ExprNode { - private final ExprNode left; - private final ExprNode right; - private final String operator; - - public ArithNode(ExprNode left, ExprNode right, String operator) { - this.left = left; - this.right = right; - this.operator = operator; - } - - @Override - public int eval(Namespace env, int curr_addr) throws Exception { - int lv = left.eval(env, curr_addr); - int rv = 0; - if (right != null) { - rv = right.eval(env, curr_addr); - } - - this.value = 0; - switch (operator) { - case "or": - this.value = lv | rv; - break; - case "xor": - this.value = lv ^ rv; - break; - case "and": - this.value = lv & rv; - break; - case "not": - this.value = ~lv; - break; - case "+": - this.value = lv + rv; - break; - case "-": - this.value = lv - rv; - break; - case "*": - this.value = lv * rv; - break; - case "/": - this.value = lv / rv; - break; - case "mod": - this.value = lv % rv; - break; - case "shr": - this.value = lv >>> rv; - break; - case "shl": - this.value = lv << rv; - break; - case "=": - this.value = (lv == rv) ? 1 : 0; - break; - } - - return this.value; - } - - @Override - public String toString() { - return "ArithNode{" + - "left=" + left + - ", right=" + right + - ", operator='" + operator + '\'' + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java deleted file mode 100644 index ce5567a10..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DBDataNode.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.ValueTooBigException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.DataValueNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; - -public class DBDataNode extends DataValueNode { - - private ExprNode expression = null; - private String literalString = null; - private OpCodeNode opcode = null; - - public DBDataNode(ExprNode expression, int line, int column) { - super(line, column); - this.expression = expression; - } - - public DBDataNode(String literalString, int line, int column) { - super(line, column); - this.literalString = literalString; - } - - public DBDataNode(OpCodeNode opcode, int line, int column) { - super(line, column); - this.opcode = opcode; - } - - /// compile time /// - @Override - public int getSize() { - if (expression != null) { - return 1; - } else if (literalString != null) { - return literalString.length(); - } else if (opcode != null) { - return opcode.getSize(); - } - return 0; - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - if (expression != null) { - expression.eval(env, addr_start); - return addr_start + 1; - } else if (literalString != null) { - return addr_start + literalString.length(); - } else if (opcode != null) { - return opcode.pass2(env, addr_start); - } - return addr_start; - } - - @Override - public void pass4(IntelHEX hex) throws Exception { - if (expression != null) { - if (expression.getValue() > 0xFF) { - throw new ValueTooBigException(line, column, expression.getValue(), 0xFF); - } - if (expression.getValue() < -128) { - throw new ValueTooBigException(line, column, expression.getValue(), -128); - } - hex.add(expression.getEncValue(true)); - } else if (literalString != null) { - hex.add(this.getEncString(literalString)); - } else if (opcode != null) { - opcode.pass4(hex); - } - } - - @Override - public String toString() { - return "DBDataNode{" + - "expression=" + expression + - ", literalString='" + literalString + '\'' + - ", opcode=" + opcode + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java deleted file mode 100644 index cc15e7b46..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DSDataNode.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.AmbiguousException; -import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.as8080.exceptions.NegativeValueException; -import net.emustudio.plugins.compiler.as8080.exceptions.ValueTooBigException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.DataValueNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; - -public class DSDataNode extends DataValueNode { - - private final ExprNode expression; - - public DSDataNode(ExprNode expr, int line, int column) { - super(line, column); - this.expression = expr; - } - - @Override - public int getSize() { - return expression.getValue(); - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - try { - int val = expression.eval(env, addr_start); - return addr_start + val; - } catch (NeedMorePassException e) { - throw new AmbiguousException(line, column, "DS expression"); - } - } - - @Override - public void pass4(IntelHEX hex) throws Exception { - StringBuilder str = new StringBuilder(); - - if (expression.getValue() > 0xFF) { - throw new ValueTooBigException(line, column, expression.getValue(), 0xFF); - } else if (expression.getValue() < 0) { - throw new NegativeValueException(line, column, expression.getValue()); - } - - str.append("00".repeat(Math.max(0, expression.getValue()))); - hex.add(str.toString()); - } - - @Override - public String toString() { - return "DSDataNode{" + - "expression=" + expression + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java deleted file mode 100644 index bc739b157..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DWDataNode.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.ValueTooBigException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.DataValueNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; - -public class DWDataNode extends DataValueNode { - private final ExprNode expression; - - public DWDataNode(ExprNode expr, int line, int column) { - super(line, column); - this.expression = expr; - } - - @Override - public int getSize() { - return 2; - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - expression.eval(env, addr_start); - return addr_start + 2; - } - - @Override - public void pass4(IntelHEX hex) throws Exception { - if (expression.getValue() > 0xFFFF) { - throw new ValueTooBigException(line, column, expression.getValue(), 0xFFFF); - } - if (expression.getValue() < -32768) { - throw new ValueTooBigException(line, column, expression.getValue(), -32768); - } - - hex.add(expression.getEncValue(false)); - } - - @Override - public String toString() { - return "DWDataNode{" + - "expression=" + expression + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java deleted file mode 100644 index 60aeb5bbb..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DataNode.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.treeAbstract.CodeNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.DataValueNode; - -import java.util.ArrayList; -import java.util.List; - -public class DataNode extends CodeNode { - private final List dataValues = new ArrayList<>(); - - public void addElement(DataValueNode node) { - dataValues.add(node); - } - - public DataNode(int line, int column) { - super(line, column); - } - - @Override - public int getSize() { - int size = 0; - for (DataValueNode dataValue : dataValues) { - size += dataValue.getSize(); - } - return size; - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - for (DataValueNode dataValue : dataValues) { - addr_start = dataValue.pass2(env, addr_start); - } - return addr_start; - } - - @Override - public void pass4(IntelHEX hex) throws Exception { - for (DataValueNode dataValue : dataValues) { - dataValue.pass4(hex); - } - } - - @Override - public String toString() { - return "DataNode{" + - "dataValues=" + dataValues + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DecimalValueNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DecimalValueNode.java deleted file mode 100644 index 1962b91e5..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/DecimalValueNode.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; - -public class DecimalValueNode extends ExprNode { - - public DecimalValueNode(int value) { - this.value = value; - } - - public int getSize() { - if ((value & 0xFF) == value) { - return 1; - } - return 2; - } - - @Override - public int eval(Namespace env, int curr_addr) throws Exception { - return value; - } - - @Override - public String toString() { - return "DecimalValueNode{value="+ value +"}"; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java deleted file mode 100644 index d40221ebb..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/EquPseudoNode.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.AlreadyDefinedException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoNode; - -public class EquPseudoNode extends PseudoNode { - private final ExprNode expr; - private final String mnemo; - - public EquPseudoNode(String id, ExprNode expr, int line, int column) { - super(line, column); - this.mnemo = id; - this.expr = expr; - } - - @Override - public String getName() { - return mnemo; - } - - public int getValue() { - return expr.getValue(); - } - - @Override - public int getSize() { - return 0; - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - if (!env.addConstant(this)) { - throw new AlreadyDefinedException(line, column, "identifier (" + mnemo + ")"); - } - expr.eval(env, addr_start); - return addr_start; - } - - @Override - public void pass4(IntelHEX hex) { - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java deleted file mode 100644 index 17c2d5ed2..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IdExpr.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; - -public class IdExpr extends ExprNode { - private final String name; - - public IdExpr(String name) { - this.name = name; - } - - public int getSize() { - return 0; - } - - @Override - public int eval(Namespace env, int curr_addr) throws Exception { - // identifier in expression can be only label, equ, or set statement. macro does NOT search in env for labels - LabelNode lab = env.getLabel(this.name); - if ((lab != null) && (lab.getAddress() == null)) { - throw new NeedMorePassException(lab.getLine(), lab.getColumn()); - } else if (lab != null) { - this.value = lab.getAddress(); - return this.value; - } - - EquPseudoNode equ = env.getConstant(this.name); - if (equ != null) { - this.value = equ.getValue(); - return this.value; - } - - SetPseudoNode set = env.getVariable(this.name); - if (set != null) { - this.value = set.getValue(); - return this.value; - } else { - throw new NeedMorePassException(0,0); - } - } - - @Override - public String toString() { - return "IdExpr{" + - "name='" + name + '\'' + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java deleted file mode 100644 index 705d0e1c7..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IfPseudoNode.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.AmbiguousException; -import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoBlock; - -public class IfPseudoNode extends PseudoBlock { - private ExprNode expr; - private Statement stat; - private boolean condTrue; // for pass4 - - public IfPseudoNode(ExprNode expr, Statement stat, int line, int column) { - super(line, column); - this.expr = expr; - this.stat = stat; - this.condTrue = false; - } - - // if doesnt have and id - @Override - public String getName() { - return ""; - } - - @Override - public int getSize() { - if (expr.getValue() != 0) { - return stat.getSize(); - } else { - return 0; - } - } - - @Override - public void pass1() { - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - stat.pass1(env); - - // now evaluate expression and then decide if block can be passed - try { - if (expr.eval(env, addr_start) != 0) { - condTrue = true; - return stat.pass2(env, addr_start); - } else { - return addr_start; - } - } catch (NeedMorePassException e) { - throw new AmbiguousException(line, column, "IF expression"); - } - } - - @Override - public void pass4(IntelHEX hex) throws Exception { - if (condTrue) { - stat.pass4(hex); - } - } - - @Override - public String toString() { - return "IfPseudoNode{" + - "expr=" + expr + - ", stat=" + stat + - ", condTrue=" + condTrue + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java deleted file mode 100644 index 933ade454..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/IncludePseudoNode.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Assembler8080; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; -import net.emustudio.plugins.compiler.as8080.exceptions.UnexpectedEOFException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoNode; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.List; - -public class IncludePseudoNode extends PseudoNode { - private final String fileName; - private final Assembler8080 compiler; - private Statement program; - private Namespace namespace; - - public IncludePseudoNode(String filename, int line, int column, Assembler8080 compiler) { - super(line, column); - this.fileName = filename.replace("\\", File.separator); - this.compiler = compiler; - } - - @Override - public int getSize() { - return program.getSize(); - } - - private File findIncludeFile(String tmpFileName) { - File tmpFile = new File(tmpFileName); - if (tmpFile.isAbsolute()) { - return tmpFile; - } else { - return new File(namespace.getInputFile().getParent() + File.separator + tmpFileName); - } - } - - /** - * Method will compare filename (in the include statement) - * with filename given by the parameter. - * - * @param tmpFileName provided file name - * @return true if filenames equal, false if not - */ - boolean isEqualName(String tmpFileName) { - return findIncludeFile(fileName).equals(findIncludeFile(tmpFileName)); - } - - void pass1(List includefiles, Namespace parentEnv) throws Exception { -// try { -// namespace = new Namespace(parentEnv.getInputFile().getAbsolutePath()); -// -// File file = findIncludeFile(fileName); -// FileReader f = new FileReader(file); -// LexerImpl lexer = new LexerImpl(f); -// ParserImpl parser = new ParserImpl(lexer, compiler); -// -// parser.setReportPrefixString(file.getName() + ": "); -// Object s = parser.parse().value; -// parser.setReportPrefixString(null); -// -// if (s == null) { -// throw new UnexpectedEOFException(line, column, file.getAbsolutePath()); -// } -// -// program = (Statement) s; -// program.addIncludeFiles(includefiles); -// namespace = parentEnv; -// -// if (program.getIncludeLoops(file.getAbsolutePath())) { -// throw new CompileException(line, column, "Infinite INCLUDE loop (" + file.getAbsolutePath() + ")"); -// } -// program.pass1(namespace); // create symbol table -// } catch (CompileException e) { -// throw e; -// } catch (IOException e) { -// throw new CompileException(line, column, fileName + ": " + e.getMessage(), e); -// } catch (Exception e) { -// throw new CompileException(line, column, e.getMessage(), e); -// } - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - // try to evaluate all expressions + compute relative addresses - return program.pass2(addr_start); - } - - @Override - public void pass4(IntelHEX hex) throws Exception { - while (program.pass3(namespace)) { - // ignore - } - if (namespace.getPassNeedCount() != 0) { - throw new Exception("Error: can't evaluate all expressions"); - } - program.pass4(hex); - } - - @Override - public String getName() { - return fileName; - } - - @Override - public String toString() { - return "IncludePseudoNode{" + - "fileName='" + fileName + '\'' + - ", compiler=" + compiler + - ", program=" + program + - ", namespace=" + namespace + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java deleted file mode 100644 index ce938e65a..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/InstructionNode.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.CodePseudoNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoBlock; - -import java.util.List; - -public class InstructionNode { - protected LabelNode label; - final CodePseudoNode codePseudo; - private int current_address; // its computed in pass2 - - public InstructionNode(LabelNode label, CodePseudoNode codePseudo) { - this.label = label; - this.codePseudo = codePseudo; - } - - public InstructionNode(CodePseudoNode codePseudo) { - this.label = null; - this.codePseudo = codePseudo; - } - - public int getSize() { - if (codePseudo != null) { - return codePseudo.getSize(); - } - return 0; - } - - void pass1(List inclfiles, Namespace parentEnv) throws Exception { - ((IncludePseudoNode) codePseudo).pass1(inclfiles, parentEnv); - } - - void pass1() throws Exception { - if (codePseudo instanceof PseudoBlock) { - ((PseudoBlock) codePseudo).pass1(); - } - } - - public int pass2(Namespace prev_env, int addr_start) throws Exception { - this.current_address = addr_start; - if (label != null) { - label.setAddress(addr_start); - } - // pass2 pre definiciu makra nemozem volat. ide totiz o samotnu expanziu - // makra. preto pass2 mozem volat az pri samotnom volani makra (pass2 triedy - // MacroCallPseudo) - if (codePseudo != null) { - if (!(codePseudo instanceof MacroPseudoNode)) { - addr_start = codePseudo.pass2(prev_env, addr_start); - } - } - return addr_start; - } - - boolean pass3(Namespace env) throws Exception { - try { - if (codePseudo != null) { - codePseudo.pass2(env, this.current_address); - } - } catch (NeedMorePassException e) { - return false; - } - return true; - } - - // code generation - public void pass4(IntelHEX hex) throws Exception { - if (codePseudo != null) { - if (!(codePseudo instanceof MacroPseudoNode)) { - codePseudo.pass4(hex); - } - } - } - - boolean getIncludeLoops(String filename) { - if (codePseudo != null && codePseudo instanceof IncludePseudoNode) { - IncludePseudoNode i = (IncludePseudoNode) codePseudo; - return i.isEqualName(filename); - } - return false; - } - - @Override - public String toString() { - return "InstructionNode{" + - "label=" + label + - ", codePseudo=" + codePseudo + - ", current_address=" + current_address + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/LabelNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/LabelNode.java deleted file mode 100644 index 9904a87dc..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/LabelNode.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -public class LabelNode { - private final String name; - private Integer address; - private final int line; - private final int column; - - public LabelNode(String name, int line, int column) { - this.name = name; - this.address = null; - - this.line = line; - this.column = column; - } - - void setAddress(Integer address) { - this.address = address; - } - - Integer getAddress() { - return this.address; - } - - public int getLine() { - return line; - } - - public int getColumn() { - return column; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return "LabelNode{" + - "name='" + name + '\'' + - ", address=" + address + - ", line=" + line + - ", column=" + column + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java deleted file mode 100644 index 045481dd1..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroCallPseudo.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.AmbiguousException; -import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.as8080.exceptions.UndefinedMacroException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoNode; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class MacroCallPseudo extends PseudoNode { - - private List params; // vector of expressions - private MacroPseudoNode macro; // only pointer... - private IntelHEX statHex; // hex file for concrete macro - private String mnemo; - - public MacroCallPseudo(String name, List params, int line, int column) { - super(line, column); - this.mnemo = name; - this.params = Objects.requireNonNullElseGet(params, ArrayList::new); - statHex = new IntelHEX(); - } - - @Override - public int getSize() { - return macro.getStatSize(); - } - - // this is a call for expanding a macro - // also generate code for pass4 - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - // first find a macro - this.macro = env.getMacro(this.mnemo); - if (macro == null) { - throw new UndefinedMacroException(line, column, this.mnemo); - } - // do pass2 for expressions (real macro parameters) - try { - for (ExprNode param : params) { - param.eval(env, addr_start); - } - macro.setCallParams(params); - int a = macro.pass2(env, addr_start); - statHex.setNextAddress(addr_start); - macro.pass4(statHex); // generate code for concrete macro - return a; - } catch (NeedMorePassException e) { - throw new AmbiguousException(line, column, "MACRO expression"); - } - } - - @Override - public String getName() { - return this.mnemo; - } - - @Override - public void pass4(IntelHEX hex) { - //hex.add(statHex.getTable()); - } - - @Override - public String toString() { - return "MacroCallPseudo{" + - "params=" + params + - ", macro=" + macro + - ", statHex=" + statHex + - ", mnemo='" + mnemo + '\'' + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java deleted file mode 100644 index 2237032b4..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/MacroPseudoNode.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.InvalidMacroParamsCountException; -import net.emustudio.plugins.compiler.as8080.exceptions.UnknownMacroParametersException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoBlock; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class MacroPseudoNode extends PseudoBlock { - private Namespace newEnv; - private final List params; // macro parameters - private List call_params; // concrete parameters, they can change - private final Statement stat; - private final String mnemo; - - public MacroPseudoNode(String name, List params, Statement s, int line, int column) { - super(line, column); - this.mnemo = name; - this.params = Objects.requireNonNullElseGet(params, ArrayList::new); - this.stat = s; - } - - @Override - public String getName() { - return mnemo; - } - - void setCallParams(List params) { - this.call_params = params; - } - - @Override - public int getSize() { - return 0; - } - - int getStatSize() { - return stat.getSize(); - } - - @Override - public void pass1() { - } - - // this is macro expansion ! can be called only in MacroCallPseudo class - // call parameters have to be set - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - createNewEnvForMacro(env); - stat.pass1(newEnv); - - // check of call_params - if (call_params == null) { - throw new UnknownMacroParametersException(line, column, mnemo); - } - if (call_params.size() != params.size()) { - throw new InvalidMacroParamsCountException(line, column, mnemo, params.size(), call_params.size()); - } - // create/rewrite symbols => parameters as equ pseudo instructions - for (int i = 0; i < params.size(); i++) { - newEnv.addConstant(new EquPseudoNode(params.get(i), call_params.get(i), - line, column)); - } - return stat.pass2(newEnv, addr_start); - } - - private void createNewEnvForMacro(Namespace env) { - newEnv = new Namespace(env.getInputFile().getAbsolutePath()); - env.copyTo(newEnv); - for (String param : params) { - newEnv.removeAllDefinitions(param); - } - } - - @Override - public void pass4(IntelHEX hex) throws Exception { - stat.pass4(hex, newEnv); - } - - @Override - public String toString() { - return "MacroPseudoNode{" + - "newEnv=" + newEnv + - ", params=" + params + - ", call_params=" + call_params + - ", stat=" + stat + - ", mnemo='" + mnemo + '\'' + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java deleted file mode 100644 index 4768be422..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Expr.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.ValueTooBigException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; - -import java.util.HashMap; -import java.util.Map; - -public class OC_Expr extends OpCodeNode { - private final static Map OPCODES_BASE_198 = new HashMap<>(); - private final static Map OPCODES_BASE_34 = new HashMap<>(); - private final static Map OPCODES_BASE_194 = new HashMap<>(); - private final static Map OPCODES_BASE_196 = new HashMap<>(); - - private final static Map INSTRUCTION_SIZE = new HashMap<>(); - - static { - INSTRUCTION_SIZE.put("sta", 3); - INSTRUCTION_SIZE.put("lda", 3); - INSTRUCTION_SIZE.put("shld", 3); - INSTRUCTION_SIZE.put("lhld", 3); - INSTRUCTION_SIZE.put("jmp", 3); - INSTRUCTION_SIZE.put("jc", 3); - INSTRUCTION_SIZE.put("jnc", 3); - INSTRUCTION_SIZE.put("jz", 3); - INSTRUCTION_SIZE.put("jnz", 3); - INSTRUCTION_SIZE.put("jm", 3); - INSTRUCTION_SIZE.put("jp", 3); - INSTRUCTION_SIZE.put("jpe", 3); - INSTRUCTION_SIZE.put("jpo", 3); - INSTRUCTION_SIZE.put("call", 3); - INSTRUCTION_SIZE.put("cc", 3); - INSTRUCTION_SIZE.put("cnc", 3); - INSTRUCTION_SIZE.put("cz", 3); - INSTRUCTION_SIZE.put("cnz", 3); - INSTRUCTION_SIZE.put("cm", 3); - INSTRUCTION_SIZE.put("cp", 3); - INSTRUCTION_SIZE.put("cpe", 3); - INSTRUCTION_SIZE.put("cpo", 3); - INSTRUCTION_SIZE.put("rst", 1); - INSTRUCTION_SIZE.put("adi", 2); - INSTRUCTION_SIZE.put("aci", 2); - INSTRUCTION_SIZE.put("sui", 2); - INSTRUCTION_SIZE.put("sbi", 2); - INSTRUCTION_SIZE.put("ani", 2); - INSTRUCTION_SIZE.put("xri", 2); - INSTRUCTION_SIZE.put("ori", 2); - INSTRUCTION_SIZE.put("cpi", 2); - INSTRUCTION_SIZE.put("in", 2); - INSTRUCTION_SIZE.put("out", 2); - - OPCODES_BASE_198.put("adi", 0); - OPCODES_BASE_198.put("aci", 8); - OPCODES_BASE_198.put("sui", 16); - OPCODES_BASE_198.put("sbi", 24); - OPCODES_BASE_198.put("ani", 32); - OPCODES_BASE_198.put("xri", 40); - OPCODES_BASE_198.put("ori", 48); - OPCODES_BASE_198.put("cpi", 0x38); - - OPCODES_BASE_34.put("shld", 0); - OPCODES_BASE_34.put("lhld", 8); - OPCODES_BASE_34.put("sta", 16); - OPCODES_BASE_34.put("lda", 24); - - OPCODES_BASE_194.put("jmp", 1); - OPCODES_BASE_194.put("jnz", 0); - OPCODES_BASE_194.put("jz", 8); - OPCODES_BASE_194.put("jnc", 16); - OPCODES_BASE_194.put("jc", 24); - OPCODES_BASE_194.put("jpo", 32); - OPCODES_BASE_194.put("jpe", 40); - OPCODES_BASE_194.put("jp", 48); - OPCODES_BASE_194.put("jm", 56); - - OPCODES_BASE_196.put("call", 9); - OPCODES_BASE_196.put("cnz", 0); - OPCODES_BASE_196.put("cz", 8); - OPCODES_BASE_196.put("cnc", 16); - OPCODES_BASE_196.put("cc", 24); - OPCODES_BASE_196.put("cpo", 32); - OPCODES_BASE_196.put("cpe", 40); - OPCODES_BASE_196.put("cp", 48); - OPCODES_BASE_196.put("cm", 56); - - } - - private final ExprNode expr; - - public OC_Expr(String mnemo, ExprNode expr, int line, int column) { - super(mnemo, line, column); - this.expr = expr; - } - - @Override - public int getSize() { - return INSTRUCTION_SIZE.get(mnemo); - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - expr.eval(parentEnv, addr_start); - return (addr_start + this.getSize()); - } - - @Override - public void pass4(IntelHEX hex) throws Exception { - short opCode = 0xC6; // opcode for adi: 11 (000adi) 110 - boolean oneDataByte = true; // how many data bytes - boolean insertAfter = true; // if expression have to be written after opcode - boolean found = false; - String code; - - if (OPCODES_BASE_198.containsKey(mnemo)) { - opCode |= OPCODES_BASE_198.get(mnemo); - found = true; - } else { - opCode = 34; - oneDataByte = false; - } - - if (!found && OPCODES_BASE_34.containsKey(mnemo)) { - opCode |= OPCODES_BASE_34.get(mnemo); - found = true; - } else if (!found) { - opCode = 194; - } - - if (!found && OPCODES_BASE_194.containsKey(mnemo)) { - opCode |= OPCODES_BASE_194.get(mnemo); - found = true; - } else if (!found) { - opCode = 196; - } - - if (!found && OPCODES_BASE_196.containsKey(mnemo)) { - opCode |= OPCODES_BASE_196.get(mnemo); - found = true; - } else if (!found) { - opCode = 199; - } - - if (!found && mnemo.equals("rst")) { - int v = expr.getValue(); - if (v > 7) { - throw new ValueTooBigException(line, column, v, 7); - } - opCode |= (expr.getValue() << 3); - insertAfter = false; - found = true; - } - if (!found && mnemo.equals("in")) { - opCode = 219; - oneDataByte = true; - found = true; - } - if (!found && mnemo.equals("out")) { - opCode = 211; - oneDataByte = true; - } - - code = String.format("%02X", opCode); - if (insertAfter) { - if (oneDataByte) { - if (expr.getValue() > 0xFF) { - throw new ValueTooBigException(line, column, expr.getValue(), 0xFF); - } - code += expr.getEncValue(true); - } else { - code += expr.getEncValue(false); - } - } - hex.add(code); - } - - @Override - public String toString() { - return "OC_Expr{" + - "expr=" + expr + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java deleted file mode 100644 index 8832aa39e..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_NoParams.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; - -public class OC_NoParams extends OpCodeNode { - - public OC_NoParams(String mnemo, int line, int column) { - super(mnemo, line, column); - } - - @Override - public int getSize() { - return 1; - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - return addr_start + 1; - } - - @Override - public void pass4(IntelHEX hex) { - short opCode = 0; // nop - - switch (mnemo) { - case "stc": - opCode = 55; - break; - case "cmc": - opCode = 63; - break; - case "cma": - opCode = 47; - break; - case "daa": - opCode = 39; - break; - case "nop": - break; - case "rlc": - opCode = 7; - break; - case "rrc": - opCode = 15; - break; - case "ral": - opCode = 23; - break; - case "rar": - opCode = 31; - break; - case "xchg": - opCode = 235; - break; - case "xthl": - opCode = 227; - break; - case "sphl": - opCode = 249; - break; - case "pchl": - opCode = 233; - break; - case "ret": - opCode = 201; - break; - case "rc": - opCode = 216; - break; - case "rnc": - opCode = 208; - break; - case "rz": - opCode = 200; - break; - case "rnz": - opCode = 192; - break; - case "rm": - opCode = 248; - break; - case "rp": - opCode = 240; - break; - case "rpe": - opCode = 232; - break; - case "rpo": - opCode = 224; - break; - case "ei": - opCode = 251; - break; - case "di": - opCode = 243; - break; - case "hlt": - opCode = 118; - break; - } - hex.add(String.format("%1$02X", opCode)); - } - - @Override - public String toString() { - return "OC_NoParams{mnemo="+mnemo+"}"; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java deleted file mode 100644 index 7e31d34ae..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Reg.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; - -public class OC_Reg extends OpCodeNode { - private final byte reg; - - public OC_Reg(String mnemo, byte reg, int line, int column) { - super(mnemo, line, column); - this.reg = reg; - } - - @Override - public int getSize() { - return 1; - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - return addr_start + 1; - } - - @Override - public void pass4(IntelHEX hex) { - int opCode = 0; - - switch (mnemo) { - case "inr": - opCode = 4 | (reg << 3); - break; - case "dcr": - opCode = 5 | (reg << 3); - break; - case "add": - opCode = 128 | reg; - break; - case "adc": - opCode = 136 | reg; - break; - case "sub": - opCode = 144 | reg; - break; - case "sbb": - opCode = 152 | reg; - break; - case "ana": - opCode = 160 | reg; - break; - case "xra": - opCode = 168 | reg; - break; - case "ora": - opCode = 176 | reg; - break; - case "cmp": - opCode = 184 | reg; - break; - } - - hex.add(String.format("%1$02X", opCode)); - } - - @Override - public String toString() { - return "OC_Reg{" + - "reg=" + reg + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java deleted file mode 100644 index 554485c07..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegExpr.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.ValueTooBigException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; - -// this class uses only mvi instruction -public class OC_RegExpr extends OpCodeNode { - private final byte reg; - private final ExprNode expr; - - public OC_RegExpr(String mnemo, byte reg, ExprNode expr, int line, int column) { - super(mnemo, line, column); - this.reg = reg; - this.expr = expr; - } - - @Override - public int getSize() { - return 2; - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - expr.eval(parentEnv, addr_start); - - if (expr.getValue() > 0xff) { - throw new ValueTooBigException(line, column, expr.getValue(), 0xFF); - } - return addr_start + 2; - } - - // this can be only mvi instr - @Override - public void pass4(IntelHEX hex) throws Exception { - int opCode = 6; - - if (expr.getEncValue(true).length() > 2) { - throw new ValueTooBigException(line, column, expr.getValue(), 0xFF); - } - opCode |= (reg << 3); - hex.add(String.format("%1$02X", opCode)); - hex.add(expr.getEncValue(true)); - } - - @Override - public String toString() { - return "OC_RegExpr{" + - "reg=" + reg + - ", expr=" + expr + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java deleted file mode 100644 index eaea9039f..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegReg.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; - -// only for mov instruction -public class OC_RegReg extends OpCodeNode { - private final byte reg_src; - private final byte reg_dst; - - public OC_RegReg(String mnemo, byte reg_dst, byte reg_src, int line, - int column) { - super(mnemo, line, column); - this.reg_dst = reg_dst; - this.reg_src = reg_src; - } - - @Override - public int getSize() { - return 1; - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - if ((reg_src == reg_dst) && (reg_src == 6)) { - throw new CompileException(line, column, "Can't use M register on both src and dst"); - } - return addr_start + 1; - } - - @Override - public void pass4(IntelHEX hex) { - int opCode = 64; - opCode |= (reg_dst << 3); - opCode |= reg_src; - hex.add(String.format("%1$02X", opCode)); - } - - @Override - public String toString() { - return "OC_RegReg{" + - "reg_src=" + reg_src + - ", reg_dst=" + reg_dst + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java deleted file mode 100644 index f69fa7b62..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_Regpair.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; - -public class OC_Regpair extends OpCodeNode { - private final byte regpair; - - public OC_Regpair(String mnemo, byte regpair, boolean psw, int line, int column) { - super(mnemo, line, column); - this.regpair = regpair; - } - - @Override - public int getSize() { - return 1; - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - return addr_start + 1; - } - - @Override - public void pass4(IntelHEX hex) { - int opCode = 0; - - switch (mnemo) { - case "stax": - opCode = 2 | (regpair << 4); - break; - case "ldax": - opCode = 10 | (regpair << 4); - break; - case "push": - opCode = 197 | (regpair << 4); - break; - case "pop": - opCode = 193 | (regpair << 4); - break; - case "dad": - opCode = 9 | (regpair << 4); - break; - case "inx": - opCode = 3 | (regpair << 4); - break; - case "dcx": - opCode = 11 | (regpair << 4); - break; - } - - hex.add(String.format("%1$02X", opCode)); - } - - @Override - public String toString() { - return "OC_Regpair{" + - "regpair=" + regpair + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java deleted file mode 100644 index dc45ed710..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OC_RegpairExpr.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.OpCodeNode; - -// this class uses only lxi instruction -public class OC_RegpairExpr extends OpCodeNode { - private final byte regpair; - private final ExprNode expr; - - public OC_RegpairExpr(String mnemo, byte regpair, ExprNode expr, int line, int column) { - super(mnemo, line, column); - this.regpair = regpair; - this.expr = expr; - } - - @Override - public int getSize() { - return 3; - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - expr.eval(parentEnv, addr_start); - return addr_start + 3; - } - - @Override - public void pass4(IntelHEX hex) { - int opCode = 1 | (regpair << 4); - hex.add(String.format("%1$02X", opCode)); - hex.add(expr.getEncValue(false)); - } - - @Override - public String toString() { - return "OC_RegpairExpr{" + - "regpair=" + regpair + - ", expr=" + expr + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java deleted file mode 100644 index b60ce9000..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/OrgPseudoNode.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.AmbiguousException; -import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoNode; - -public class OrgPseudoNode extends PseudoNode { - private final ExprNode expr; - - public OrgPseudoNode(ExprNode expr, int line, int column) { - super(line, column); - this.expr = expr; - } - - @Override - public int getSize() { - return 0; - } - - @Override - public String getName() { - return ""; - } - - // org only changes current address - // if expr isnt valuable, then error exception is thrown - // it cant help even more passes, because its recursive: - // org label - // mvi a,50 - // label: hlt - // label address cant be evaluated - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - try { - return expr.eval(parentEnv, addr_start); - } catch (NeedMorePassException e) { - throw new AmbiguousException(line, column, "ORG expression"); - } - } - - @Override - public void pass4(IntelHEX hex) { - hex.setNextAddress(expr.getValue()); - } - - @Override - public String toString() { - return "OrgPseudoNode{" + - "expr=" + expr + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java deleted file mode 100644 index 78e6f6163..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/SetPseudoNode.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.AlreadyDefinedException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoNode; - -public class SetPseudoNode extends PseudoNode { - private final ExprNode expr; - private final String mnemo; - - public SetPseudoNode(String id, ExprNode expr, int line, int column) { - super(line, column); - this.mnemo = id; - this.expr = expr; - } - - @Override - public String getName() { - return mnemo; - } - - public int getValue() { - return expr.getValue(); - } - - @Override - public int getSize() { - return 0; - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - if (!env.setVariable(this)) { - throw new AlreadyDefinedException(line, column, "identifier(" + mnemo + ")"); - } - expr.eval(env, addr_start); - return addr_start; - } - - @Override - public void pass4(IntelHEX hex) { - } - - @Override - public String toString() { - return "SetPseudoNode{" + - "expr=" + expr + - ", mnemo='" + mnemo + '\'' + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/Statement.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/Statement.java deleted file mode 100644 index f5ac361b6..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/tree/Statement.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.tree; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; -import net.emustudio.plugins.compiler.as8080.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.as8080.treeAbstract.PseudoBlock; - -import java.util.ArrayList; -import java.util.List; - -public class Statement { - /* PASS1 = symbol table - * 1. get all label definitions - * 2. get all macro definitions - */ - private Namespace env; - private final List list = new ArrayList<>(); - private final List includefiles = new ArrayList<>(); - // were checked for include-loops - // in short: list of included files - - public void addElement(InstructionNode node) { - list.add(node); - } - - public int getSize() { - int size = 0; - for (InstructionNode in : list) { - size += in.getSize(); - } - return size; - } - - public void pass1(Namespace env) throws Exception { - this.env = env; - pass1(); - } - - // creates symbol table - // return next current address - void pass1() throws Exception { - // only labels and macros have right to be all added to symbol table at once - for (InstructionNode in : list) { - if (in.label != null) { - if (!env.addLabel(in.label)) { - throw new Exception("Label already defined: " + in.label.getName()); - } - } - if ((in.codePseudo instanceof MacroPseudoNode)) { - if (!env.addMacro((MacroPseudoNode) in.codePseudo)) { - throw new Exception("Macro already defined: " + ((MacroPseudoNode) in.codePseudo).getName()); - } - } - if ((in.codePseudo instanceof IncludePseudoNode)) { - in.pass1(includefiles, env); - } else if (in.codePseudo instanceof PseudoBlock) { - in.pass1(); - } - } - } - - // pass2 tries to evaulate all expressions and compute relative addresses - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - int curr_addr; - for (InstructionNode in : list) { - try { - curr_addr = in.pass2(parentEnv, addr_start); - addr_start = curr_addr; - } catch (NeedMorePassException e) { - parentEnv.addPassNeed(in); - addr_start += in.getSize(); - } - } - return addr_start; - } - - public int pass2(int addr_start) throws Exception { - return this.pass2(env, addr_start); - } - - public boolean pass3(Namespace parentEnv) throws Exception { - int pnCount = parentEnv.getPassNeedCount(); - for (int i = parentEnv.getPassNeedCount() - 1; i >= 0; i--) { - if (parentEnv.getPassNeed(i).pass3(parentEnv)) { - pnCount--; - parentEnv.removePassNeed(i); - } - } - return pnCount < parentEnv.getPassNeedCount(); - } - - public void pass4(IntelHEX hex) throws Exception { - for (InstructionNode in : list) { - in.pass4(hex); - } - } - - public void pass4(IntelHEX hex, Namespace env) throws Exception { - this.env = env; - pass4(hex); - } - - /** - * Method check whether this "subprogram" contains include - * pseudocode(s) and if yes, whether the statement calls for - * filename given by parameter. - * - * @param filename name of the file that "include" pseudocode should contain - * @return true if subprogram contains "include filename" pseudocode - */ - boolean getIncludeLoops(String filename) { - int i; - for (i = 0; i < includefiles.size(); i++) { - String s = includefiles.get(i); - if (s.equals(filename)) { - return true; - } - } - includefiles.add(filename); - InstructionNode in; - for (i = 0; i < list.size(); i++) { - in = list.get(i); - if (in.getIncludeLoops(filename)) { - return true; - } - } - return false; - } - - void addIncludeFiles(List inclfiles) { - includefiles.addAll(inclfiles); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodeNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodeNode.java deleted file mode 100644 index 46180898b..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodeNode.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.treeAbstract; - -public abstract class CodeNode extends CodePseudoNode { - - public CodeNode(int line, int column) { - super(line, column); - } - -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodePseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodePseudoNode.java deleted file mode 100644 index fbf7aeadd..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/CodePseudoNode.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.treeAbstract; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; - -public abstract class CodePseudoNode { - protected int line; - protected int column; - - public CodePseudoNode(int line, int column) { - this.line = line; - this.column = column; - } - - /** - * Get size of compiled code. - * - * @return size in bytes - */ - public abstract int getSize(); - - public abstract int pass2(Namespace parentEnv, int addr_start) throws Exception; - - public abstract void pass4(IntelHEX hex) throws Exception; -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/DataValueNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/DataValueNode.java deleted file mode 100644 index 468ee65df..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/DataValueNode.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.treeAbstract; - -import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.as8080.Namespace; - -public abstract class DataValueNode { - protected int line; - protected int column; - - public DataValueNode(int line, int column) { - this.line = line; - this.column = column; - } - - /// compile time /// - public abstract int getSize(); - - public abstract int pass2(Namespace env, int addr_start) throws Exception; - - public abstract void pass4(IntelHEX hex) throws Exception; - - // encode string to hex codes - protected String getEncString(String literal) { - byte[] byts = literal.getBytes(); - StringBuilder enc = new StringBuilder(); - - for (byte byt : byts) { - enc.append(ExprNode.getEncValue(byt, true)); - } - return enc.toString(); - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/ExprNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/ExprNode.java deleted file mode 100644 index 96f087617..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/ExprNode.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.treeAbstract; - -import net.emustudio.emulib.runtime.helpers.RadixUtils; -import net.emustudio.plugins.compiler.as8080.Namespace; - -public abstract class ExprNode { - protected int value; - - public int getValue() { - return value; - } - - public abstract int eval(Namespace env, int curr_addr) throws Exception; - - public static String getEncValue(int val, boolean oneByte) { - if (oneByte) { - return RadixUtils.formatByteHexString(val & 0xFF); - } else { - return String.format("%02X%02X", (val & 0xFF), ((val >> 8) & 0xFF)); - } - } - - public String getEncValue(boolean oneByte) { - if (oneByte) { - return RadixUtils.formatByteHexString(value & 0xFF); - } else { - return String.format("%02X%02X", (value & 0xFF), ((value >> 8) & 0xFF)); - } - } - - @Override - public String toString() { - return "ExprNode{" + - "value=" + value + - '}'; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/OpCodeNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/OpCodeNode.java deleted file mode 100644 index c98b382a2..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/OpCodeNode.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.treeAbstract; - -public abstract class OpCodeNode extends CodeNode { - protected final String mnemo; - - public OpCodeNode(String mnemo, int line, int column) { - super(line, column); - this.mnemo = mnemo; - } -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/PseudoBlock.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/PseudoBlock.java deleted file mode 100644 index 6081e30ba..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/PseudoBlock.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.treeAbstract; - -public abstract class PseudoBlock extends PseudoNode { - - public PseudoBlock(int line, int column) { - super(line, column); - } - - public abstract void pass1() throws Exception; -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/PseudoNode.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/PseudoNode.java deleted file mode 100644 index a11e6a848..000000000 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/treeAbstract/PseudoNode.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080.treeAbstract; - -/* - * pseudocodes like: set,equ - * are treated as local if theyre set in a macro. (see LabelNode class) - */ -public abstract class PseudoNode extends CodePseudoNode { - - public PseudoNode(int line, int column) { - super(line, column); - } - - public abstract String getName(); -} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java index 1754c76db..d2f06f4b6 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java @@ -2,7 +2,6 @@ import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; import java.util.*; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java index bb8d667ed..0c9fbea5c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java @@ -1,7 +1,6 @@ package net.emustudio.plugins.compiler.as8080.visitors; import net.emustudio.plugins.compiler.as8080.ast.Evaluated; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 4fc25c7f4..a81f146bf 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -2,7 +2,6 @@ import net.emustudio.plugins.compiler.as8080.ast.Evaluated; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java index 39ae78641..e414a3433 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java @@ -2,7 +2,6 @@ import net.emustudio.plugins.compiler.as8080.As8080Lexer; import net.emustudio.plugins.compiler.as8080.As8080Parser; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoInclude; import org.antlr.v4.runtime.CharStreams; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java index aac918c97..81515f5aa 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java @@ -1,7 +1,6 @@ package net.emustudio.plugins.compiler.as8080.visitors; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroCall; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java index 2386cfb44..47fd0606c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java @@ -2,7 +2,6 @@ import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.as8080.ast.Evaluated; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/NodeVisitor.java similarity index 90% rename from plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java rename to plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/NodeVisitor.java index 14fb04698..00a8d92e9 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/NodeVisitor.java @@ -1,13 +1,17 @@ -package net.emustudio.plugins.compiler.as8080.ast; +package net.emustudio.plugins.compiler.as8080.visitors; import net.emustudio.plugins.compiler.as8080.CompileError; +import net.emustudio.plugins.compiler.as8080.ast.Evaluated; +import net.emustudio.plugins.compiler.as8080.ast.NameSpace; +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; import net.emustudio.plugins.compiler.as8080.ast.expr.*; import net.emustudio.plugins.compiler.as8080.ast.instr.*; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; -import net.emustudio.plugins.compiler.as8080.exceptions.used.FatalError; +import net.emustudio.plugins.compiler.as8080.exceptions.FatalError; import java.util.List; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java index ae1ab4262..4193a7cb6 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java @@ -1,7 +1,6 @@ package net.emustudio.plugins.compiler.as8080.visitors; import net.emustudio.plugins.compiler.as8080.ast.Node; -import net.emustudio.plugins.compiler.as8080.ast.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroArgument; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroCall; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java index f652c9aef..0f14a134c 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/RunnerTest.java @@ -18,7 +18,6 @@ */ package net.emustudio.plugins.compiler.as8080; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -30,7 +29,6 @@ import static org.junit.Assert.assertEquals; -@Ignore public class RunnerTest { @Rule diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java index 90be070fa..a001e7475 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -1,6 +1,5 @@ package net.emustudio.plugins.compiler.as8080; -import net.emustudio.plugins.compiler.as8080.ast.NameSpace; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.visitors.CreateProgramVisitor; @@ -20,7 +19,6 @@ import java.util.function.Consumer; import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; -import static net.emustudio.plugins.compiler.as8080.As8080Parser.REG_M; import static org.junit.Assert.assertEquals; public class Utils { diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/AbstractCompilerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java similarity index 97% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/AbstractCompilerTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java index 098233aa5..bb54983c9 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/AbstractCompilerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.e2e; import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.cpu.testsuite.memory.MemoryStub; @@ -28,6 +28,7 @@ import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; +import net.emustudio.plugins.compiler.as8080.Assembler8080; import org.junit.Before; import org.junit.Rule; import org.junit.rules.TemporaryFolder; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Assembler8080Test.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/Assembler8080Test.java similarity index 97% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Assembler8080Test.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/Assembler8080Test.java index b8a96e636..56c714ead 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Assembler8080Test.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/Assembler8080Test.java @@ -16,14 +16,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.e2e; -import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.assertNotEquals; -@Ignore public class Assembler8080Test extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/ConstantsAndVariablesTest.java similarity index 97% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/ConstantsAndVariablesTest.java index 8ef617d2d..83a55a930 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ConstantsAndVariablesTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/ConstantsAndVariablesTest.java @@ -16,12 +16,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.e2e; -import org.junit.Ignore; import org.junit.Test; -@Ignore public class ConstantsAndVariablesTest extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/DataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java similarity index 98% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/DataTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java index 081c8fe59..4906ccee1 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/DataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java @@ -16,12 +16,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.e2e; -import org.junit.Ignore; import org.junit.Test; -@Ignore public class DataTest extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IfNodeTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IfNodeTest.java similarity index 96% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IfNodeTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IfNodeTest.java index 4e9a5d60f..68b6bb84e 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IfNodeTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IfNodeTest.java @@ -16,12 +16,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.e2e; -import org.junit.Ignore; import org.junit.Test; -@Ignore public class IfNodeTest extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IncludeTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IncludeTest.java similarity index 97% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IncludeTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IncludeTest.java index 4e8755a60..b8183f67f 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/IncludeTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IncludeTest.java @@ -16,14 +16,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.e2e; -import org.junit.Ignore; import org.junit.Test; import java.io.File; -@Ignore public class IncludeTest extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_ExprTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrExprTest.java similarity index 70% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_ExprTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrExprTest.java index 520b22086..1516af4ab 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_ExprTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrExprTest.java @@ -1,10 +1,8 @@ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.e2e; -import org.junit.Ignore; import org.junit.Test; -@Ignore -public class OC_ExprTest extends AbstractCompilerTest { +public class InstrExprTest extends AbstractCompilerTest { @Test public void testRST() throws Exception { diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_RegTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrRegTest.java similarity index 92% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_RegTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrRegTest.java index d6624215f..c836cb49d 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/OC_RegTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrRegTest.java @@ -16,17 +16,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.e2e; -import net.emustudio.plugins.compiler.as8080.tree.OC_Reg; -import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; -import static org.junit.Assert.assertEquals; - -@Ignore -public class OC_RegTest extends AbstractCompilerTest { +public class InstrRegTest extends AbstractCompilerTest { @Test public void testINR() throws Exception { @@ -207,9 +201,4 @@ public void testCMP() throws Exception { 0xBF, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE ); } - - @Test - public void testOCRegSizeReturns1() { - Assert.assertEquals(1, new OC_Reg("doesnotmatter", (byte) 0, 0, 0).getSize()); - } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/MacroTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/MacroTest.java similarity index 97% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/MacroTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/MacroTest.java index cea2522ff..c5c9fb6f0 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/MacroTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/MacroTest.java @@ -16,12 +16,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.e2e; -import org.junit.Ignore; import org.junit.Test; -@Ignore public class MacroTest extends AbstractCompilerTest { @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ORGTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/PseudoOrgTest.java similarity index 86% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ORGTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/PseudoOrgTest.java index ea5fe6b24..af841a2bd 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ORGTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/PseudoOrgTest.java @@ -16,19 +16,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.e2e; -import net.emustudio.plugins.compiler.as8080.tree.OrgPseudoNode; -import net.emustudio.plugins.compiler.as8080.treeAbstract.ExprNode; -import org.junit.Ignore; import org.junit.Test; import java.io.File; -import static org.junit.Assert.assertEquals; - -@Ignore -public class ORGTest extends AbstractCompilerTest { +public class PseudoOrgTest extends AbstractCompilerTest { @Test public void testORGwithInclude() throws Exception { @@ -165,17 +159,4 @@ public void testORGisAmbiguous() throws Exception { "org text\nmvi a, 4\ntext: db 4\n" ); } - - @Test - public void testORGhasSizeZero() { - OrgPseudoNode node = new OrgPseudoNode(new ExprNode() { - @Override - public int eval(Namespace env, int curr_addr) { - return 0; - } - }, 0, 0); - - assertEquals(0, node.getSize()); - assertEquals("", node.getName()); - } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java similarity index 99% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java index feb9d179f..b138fa5aa 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/LexerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.parser; import org.junit.Test; @@ -6,7 +6,7 @@ import static net.emustudio.plugins.compiler.as8080.Utils.assertTokenTypes; import static net.emustudio.plugins.compiler.as8080.Utils.assertTokenTypesIgnoreCase; -public class LexerTest { +public class LexicalAnalyzerImplTest { @Test public void testParseEols() { diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseDataTest.java similarity index 98% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseDataTest.java index 635fcda1c..aa3347817 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseDataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseDataTest.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.parser; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseExprTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java similarity index 99% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseExprTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java index 87f59df20..50eaca344 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseExprTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.parser; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseInstrTest.java similarity index 99% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseInstrTest.java index 54d79f155..80bd3c96f 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParseInstrTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseInstrTest.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.parser; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsePseudoTest.java similarity index 97% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsePseudoTest.java index 04170c785..ee617a536 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsePseudoTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsePseudoTest.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.parser; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; @@ -8,7 +8,7 @@ import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; -import net.emustudio.plugins.compiler.as8080.exceptions.used.SyntaxErrorException; +import net.emustudio.plugins.compiler.as8080.exceptions.SyntaxErrorException; import org.junit.Test; import java.util.List; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsingUtilsTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsingUtilsTest.java similarity index 86% rename from plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsingUtilsTest.java rename to plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsingUtilsTest.java index fa3509956..88c9f4b07 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/ParsingUtilsTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsingUtilsTest.java @@ -1,6 +1,10 @@ -package net.emustudio.plugins.compiler.as8080; +package net.emustudio.plugins.compiler.as8080.parser; +import net.emustudio.plugins.compiler.as8080.As8080Parser; +import net.emustudio.plugins.compiler.as8080.ParsingUtils; +import net.emustudio.plugins.compiler.as8080.Utils; import org.antlr.v4.runtime.Token; +import org.junit.Assert; import org.junit.Test; import java.util.List; @@ -14,8 +18,8 @@ public class ParsingUtilsTest { @Test public void testParseLitString() { List tokens = getTokens("'te\"x\"t1' \"te'x't2\""); - assertTokenTypes(tokens, As8080Parser.LIT_STRING_1, As8080Parser.LIT_STRING_2, As8080Parser.EOF); - assertEquals("te\"x\"t1", ParsingUtils.parseLitString(tokens.get(0))); + Utils.assertTokenTypes(tokens, As8080Parser.LIT_STRING_1, As8080Parser.LIT_STRING_2, As8080Parser.EOF); + Assert.assertEquals("te\"x\"t1", ParsingUtils.parseLitString(tokens.get(0))); assertEquals("te'x't2", ParsingUtils.parseLitString(tokens.get(1))); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java index 44e1de53f..89f68b525 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java @@ -6,7 +6,7 @@ import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; -import net.emustudio.plugins.compiler.as8080.exceptions.used.FatalError; +import net.emustudio.plugins.compiler.as8080.exceptions.FatalError; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java index 080a3cb7b..19dbdd9f8 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java @@ -7,7 +7,7 @@ import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroCall; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroDef; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroParameter; -import net.emustudio.plugins.compiler.as8080.exceptions.used.FatalError; +import net.emustudio.plugins.compiler.as8080.exceptions.FatalError; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; From a2ba3600ec79f5028e65c5ef99e1166b9cdcc88b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 16 Jan 2022 09:14:08 +0100 Subject: [PATCH 076/314] [#201] as-8080: fixes --- .../compiler/as8080/Assembler8080.java | 2 +- .../plugins/compiler/as8080/ast/Node.java | 18 +++++++++- .../visitors/CheckDeclarationsVisitor.java | 2 ++ .../as8080/visitors/EvaluateExprVisitor.java | 36 ++++++++++++++++--- .../visitors/ExpandIncludesVisitor.java | 3 +- .../visitors/SortMacroArgumentsVisitor.java | 2 +- .../as8080/e2e/AbstractCompilerTest.java | 9 +++-- .../compiler/as8080/e2e/IfNodeTest.java | 10 ------ .../compiler/as8080/e2e/PseudoOrgTest.java | 28 +++++++++------ .../CheckDeclarationsVisitorTest.java | 7 ++-- .../visitors/EvaluateExprVisitorTest.java | 17 +++++++++ 11 files changed, 95 insertions(+), 39 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index f8896521e..ae86b17cf 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -126,7 +126,7 @@ public boolean compile(String inputFileName, String outputFileName) { new CreateProgramVisitor(program).visit(parser.rStart()); IntelHEX hex = new IntelHEX(); - NodeVisitor[] visitors = new NodeVisitor[] { + NodeVisitor[] visitors = new NodeVisitor[]{ new ExpandIncludesVisitor(), new CheckDeclarationsVisitor(), new ExpandMacrosVisitor(), diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 3163d890d..5e213025c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -30,6 +30,11 @@ public Node addChild(Node node) { return this; } + public void addChildAt(int index, Node node) { + node.parent = this; + children.add(index, node); + } + public void addChildren(List nodes) { for (Node node : nodes) { node.parent = this; @@ -69,6 +74,17 @@ public Optional remove() { return parent; } + public void exclude() { + Optional parent = getParent(); + parent.ifPresent(p -> { + int index = p.getChildren().indexOf(this); + p.removeChild(this); + for (Node child : getChildren()) { + p.addChildAt(index++, child); + } + }); + } + public int getAddress() { return address; } @@ -93,7 +109,7 @@ public String toString() { private String toString(int indent) { String spaces = new String(new char[indent]).replace("\0", " "); StringBuilder builder = new StringBuilder(spaces); - builder.append(toStringShallow()); + builder.append(address).append("> ").append(toStringShallow()); for (Node child : children) { builder.append("\n").append(child.toString(indent + 2)); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java index d2f06f4b6..82fa7c394 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java @@ -49,6 +49,7 @@ public void visit(PseudoEqu node) { addDeclaration(node.id, node); currentDeclarationId = normalizeId(node.id); visitChildren(node); + currentDeclarationId = null; } @Override @@ -65,6 +66,7 @@ public void visit(PseudoSet node) { currentDeclarationId = normalizeId(node.id); visitChildren(node); addVariable(node.id, node); + currentDeclarationId = null; } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index a81f146bf..e9d8a69ba 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -7,9 +7,7 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; import net.emustudio.plugins.compiler.as8080.ast.expr.*; -import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; -import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; -import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegPairExpr; +import net.emustudio.plugins.compiler.as8080.ast.instr.*; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; import java.util.*; @@ -144,9 +142,13 @@ public void visit(PseudoLabel node) { Optional eval = node.eval(getCurrentAddress(), env); env.put(normalizeId(node.label), eval); eval.ifPresentOrElse( - e -> node.remove(), // we don't need to re-evaluate label + e -> { + // we don't need to re-evaluate label + node.exclude(); + }, () -> needMorePassThings.add(node) ); + visitChildren(node); } @Override @@ -166,7 +168,7 @@ public void visit(PseudoIf node) { Optional expr = node .collectChild(PseudoIfExpression.class) .flatMap(p -> { - visit(p); + visitChildren(p); return p.collectChild(Evaluated.class); }); @@ -210,6 +212,30 @@ public void visit(InstrRegPairExpr node) { currentAddress++; // opcode } + @Override + public void visit(InstrNoArgs node) { + node.setAddress(currentAddress); + currentAddress++; + } + + @Override + public void visit(InstrRegReg node) { + node.setAddress(currentAddress); + currentAddress++; + } + + @Override + public void visit(InstrReg node) { + node.setAddress(currentAddress); + currentAddress++; + } + + @Override + public void visit(InstrRegPair node) { + node.setAddress(currentAddress); + currentAddress++; + } + @Override public void visit(PseudoMacroCall node) { // save old current macro, including its params diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java index e414a3433..35f07c401 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java @@ -52,7 +52,8 @@ public void visit(PseudoInclude node) { alreadyIncludedFiles.add(node.filename); new ExpandIncludesVisitor(alreadyIncludedFiles).visit(program); - node.remove().ifPresent(parent -> parent.addChildren(program.getChildren())); // TODO: custom error space? + node.addChildren(program.getChildren()); + node.exclude(); } catch (IOException e) { error(couldNotReadFile(node, node.filename, e)); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java index 4193a7cb6..55888da60 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java @@ -87,7 +87,7 @@ public void visit(PseudoMacroDef node) { .collectChild(ExprId.class) .ifPresentOrElse(macroArgument::addChildFirst, () -> error(macroArgumentsDoNotMatch(node))); } - node.remove().ifPresent(p -> p.addChildren(node.getChildren())); + node.exclude(); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java index bb54983c9..b7d92339b 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java @@ -20,7 +20,6 @@ import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.cpu.testsuite.memory.MemoryStub; -import net.emustudio.cpu.testsuite.memory.ShortMemoryStub; import net.emustudio.emulib.plugins.compiler.CompilerListener; import net.emustudio.emulib.plugins.compiler.CompilerMessage; import net.emustudio.emulib.plugins.memory.MemoryContext; @@ -91,14 +90,14 @@ protected void compile(String content) throws Exception { protected void assertProgram(int... bytes) { for (int i = 0; i < bytes.length; i++) { assertEquals( - String.format("%d. expected=%x, but was=%x", i, bytes[i], memoryStub.read(i)), - bytes[i], (int) memoryStub.read(i) + String.format("[addr=%x] expected=%x, but was=%x", i, bytes[i], memoryStub.read(i)), + (byte)bytes[i], memoryStub.read(i).byteValue() ); } for (int i = bytes.length; i < memoryStub.getSize(); i++) { assertEquals( - String.format("%d. expected=%x, but was=%x", i, 0, memoryStub.read(i)), - 0, (int) memoryStub.read(i) + String.format("[addr=%x] expected=%x, but was=%x", i, 0, memoryStub.read(i)), + 0, memoryStub.read(i).byteValue() ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IfNodeTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IfNodeTest.java index 68b6bb84e..a7ec6346e 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IfNodeTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IfNodeTest.java @@ -73,16 +73,6 @@ public void testIfCanEvaluateBackwardReferenceInExpression() throws Exception { ); } - @Test(expected = Exception.class) - public void testIfCannotEvaluateForwardReferenceInExpression() throws Exception { - compile( - "if present\n" - + " rrc\n" - + "endif\n" - + "present equ 1\n" - ); - } - @Test(expected = Exception.class) public void testIfCannotRedefineIdentifierInside() throws Exception { compile( diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/PseudoOrgTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/PseudoOrgTest.java index af841a2bd..fbadebe22 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/PseudoOrgTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/PseudoOrgTest.java @@ -18,19 +18,29 @@ */ package net.emustudio.plugins.compiler.as8080.e2e; +import org.junit.Before; import org.junit.Test; -import java.io.File; +import java.util.Objects; + public class PseudoOrgTest extends AbstractCompilerTest { + private String sampleFile; + private String sample2File; + + @Before + public void setup() { + sampleFile = Objects.requireNonNull(getClass().getResource("/sample.asm")).getFile(); + sample2File = Objects.requireNonNull(getClass().getResource("/sample2.asm")).getFile(); + } + @Test public void testORGwithInclude() throws Exception { - File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( "org 3\n" + "call sample\n" - + "include '" + includeFile.getAbsolutePath() + "'\n" + + "include '" + sampleFile + "'\n" ); assertProgram( @@ -40,13 +50,11 @@ public void testORGwithInclude() throws Exception { @Test public void testORGwithDoubleInclude() throws Exception { - File first = new File(getClass().getResource("/sample.asm").toURI()); - File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( "org 3\n" + "call sample\n" - + "include '" + second.getAbsolutePath() + "'\n" - + "include '" + first.getAbsolutePath() + "'\n" + + "include '" + sample2File + "'\n" + + "include '" + sampleFile + "'\n" ); assertProgram( @@ -56,13 +64,11 @@ public void testORGwithDoubleInclude() throws Exception { @Test public void testORGwithDoubleIncludeAndJMPafter() throws Exception { - File first = new File(getClass().getResource("/sample.asm").toURI()); - File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( "org 3\n" + "jmp next\n" - + "include '" + first.getAbsolutePath() + "'\n" - + "include '" + second.getAbsolutePath() + "'\n" + + "include '" + sampleFile + "'\n" + + "include '" + sample2File + "'\n" + "next:\n" + "mov a, b\n" ); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java index 7d6b6b5a9..60ba763a4 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java @@ -167,11 +167,10 @@ public void testSelfReferencingExistingVariableIsFine() { } @Test - public void testDeclarationsReferencingInCycle() { - Program program = parseProgram("one equ two\ntwo equ three\nthree equ one"); + public void testConstantIfReference() { + Program program = parseProgram("const equ 1\nif const\nrrc\nendif"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); - System.out.println(program); - System.out.println(program.env()); + assertTrue(program.env().hasNoErrors()); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index 5f05d7130..402ee756b 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -10,6 +10,7 @@ import net.emustudio.plugins.compiler.as8080.ast.expr.ExprInfix; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegPairExpr; import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; @@ -451,4 +452,20 @@ public void testEvaluateMacroScopedArguments() { program ); } + + @Test + public void testLabelKeepsChildren() { + Program program = new Program(); + program + .addChild(new PseudoLabel(0, 0, "label") + .addChild(new InstrNoArgs(0, 0, OPCODE_RET))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program().addChild(new InstrNoArgs(0, 0, OPCODE_RET)), + program + ); + } } From ed3f2ee08481b09b2acd428b85525d217f8c146d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 16 Jan 2022 10:11:42 +0100 Subject: [PATCH 077/314] [#201] as-8080: fixes --- .../as-8080/src/main/antlr/As8080Parser.g4 | 2 +- .../plugins/compiler/as8080/CompileError.java | 7 --- .../plugins/compiler/as8080/ast/Node.java | 4 ++ .../compiler/as8080/ast/expr/ExprString.java | 46 +++++++++++++++++++ .../visitors/CheckExprSizesVisitor.java | 10 +++- .../as8080/visitors/CreateDataVisitor.java | 9 ---- .../as8080/visitors/CreateExprVisitor.java | 5 ++ .../as8080/visitors/EvaluateExprVisitor.java | 25 +++++++++- .../compiler/as8080/visitors/NodeVisitor.java | 4 ++ .../as8080/e2e/ConstantsAndVariablesTest.java | 6 +-- .../compiler/as8080/parser/ParseDataTest.java | 20 ++------ 11 files changed, 98 insertions(+), 40 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprString.java diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index 3109ffcce..989475483 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -140,7 +140,6 @@ rData: rDBdata: expr=rExpression - | str=(LIT_STRING_1|LIT_STRING_2) | instr=r8bitInstruction ; @@ -165,4 +164,5 @@ rExpression: | num=LIT_BINNUMBER # exprBin | PREP_ADDR # exprCurrentAddress | id=ID_IDENTIFIER # exprId + | str=(LIT_STRING_1|LIT_STRING_2) # exprString ; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java index e6128be54..2354112a2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java @@ -16,7 +16,6 @@ public class CompileError { public static final int ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH = 8; public static final int ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED = 9; public static final int ERROR_VALUE_MUST_BE_POSITIVE = 10; - public static final int ERROR_VALUE_IS_BIGGER_THAN_EXPECTED = 11; public final int line; public final int column; @@ -85,12 +84,6 @@ public static CompileError valueMustBePositive(Node node) { return new CompileError(node, ERROR_VALUE_MUST_BE_POSITIVE, "Value must be positive"); } - public static CompileError valueIsBiggerThanExpected(Node node, int expectedValue) { - return new CompileError( - node, ERROR_VALUE_IS_BIGGER_THAN_EXPECTED, "Value is bigger than expected (" + expectedValue + ")" - ); - } - @Override public String toString() { return "CompileError{" + diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index 5e213025c..82b7d22e1 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -46,6 +46,10 @@ public List getChildren() { return List.copyOf(children); } + public int getChildrenCount() { + return children.size(); + } + public Optional collectChild(Class cl) { for (Node child : children) { if (cl.isInstance(child)) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprString.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprString.java new file mode 100644 index 000000000..c7b70ac6f --- /dev/null +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprString.java @@ -0,0 +1,46 @@ +package net.emustudio.plugins.compiler.as8080.ast.expr; + +import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +import static net.emustudio.plugins.compiler.as8080.ParsingUtils.parseLitString; + +public class ExprString extends Node { + public final String string; + + public ExprString(int line, int column, String string) { + super(line, column); + this.string = Objects.requireNonNull(string); + } + + public ExprString(Token str) { + this(str.getLine(), str.getCharPositionInLine(), parseLitString(str)); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new ExprString(line, column, string); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + ExprString that = (ExprString) o; + return Objects.equals(string, that.string); + } + + @Override + protected String toStringShallow() { + return "ExprString(" + string + ")"; + } +} diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java index 0c9fbea5c..a2b5d23d0 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java @@ -39,12 +39,18 @@ public void visit(DataDS node) { @Override public void visit(InstrExpr node) { expectedBytes = node.getExprSizeBytes(); + if (expectedBytes == 1 && node.getChildrenCount() > 1) { + error(expressionIsBiggerThanExpected(node, expectedBytes, node.getChildrenCount())); + } visitChildren(node); } @Override public void visit(InstrRegExpr node) { expectedBytes = 1; + if (node.getChildrenCount() > 1) { + error(expressionIsBiggerThanExpected(node, expectedBytes, node.getChildrenCount())); + } visitChildren(node); } @@ -68,8 +74,8 @@ public void visit(PseudoMacroArgument node) { @Override public void visit(Evaluated node) { long maxNumber = Long.MAX_VALUE >>> (63 - expectedBytes * 8); - if (node.value != (node.value & maxNumber)) { - int wasBits = (int)Math.ceil(Math.log10(node.value) / Math.log10(2)) + 1; + if (expectedBytes > 0 && node.value != (node.value & maxNumber)) { + int wasBits = (int) Math.ceil(Math.log10(node.value) / Math.log10(2)) + 1; int wasBytes = wasBits / 8 + wasBits % 8; error(expressionIsBiggerThanExpected(node, expectedBytes, wasBytes)); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java index c715210c6..7a32ea594 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateDataVisitor.java @@ -6,11 +6,8 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDB; import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; -import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import org.antlr.v4.runtime.Token; -import static net.emustudio.plugins.compiler.as8080.ParsingUtils.parseLitString; - public class CreateDataVisitor extends As8080ParserBaseVisitor { @Override @@ -23,12 +20,6 @@ public Node visitDataDB(DataDBContext ctx) { db.addChild(CreateVisitors.expr.visit(next.expr)); } else if (next.instr != null) { db.addChild(CreateVisitors.instr.visit(next.instr)); - } else { - Token token = next.str; - String text = parseLitString(next.str); - for (byte c : text.getBytes()) { - db.addChild(new ExprNumber(token.getLine(), token.getCharPositionInLine(), c)); - } } } return db; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java index ceca1f124..5b713865e 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateExprVisitor.java @@ -39,6 +39,11 @@ public Node visitExprId(As8080Parser.ExprIdContext ctx) { return new ExprId(ctx.id); } + @Override + public Node visitExprString(As8080Parser.ExprStringContext ctx) { + return new ExprString(ctx.str); + } + @Override public Node visitExprUnary(As8080Parser.ExprUnaryContext ctx) { ExprUnary unary = new ExprUnary(ctx.unaryop); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index e9d8a69ba..7af88b2c7 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -13,7 +13,7 @@ import java.util.*; import java.util.stream.Collectors; -import static net.emustudio.plugins.compiler.as8080.CompileError.ambiguousExpression; +import static net.emustudio.plugins.compiler.as8080.CompileError.*; import static net.emustudio.plugins.compiler.as8080.ParsingUtils.normalizeId; /** @@ -309,6 +309,29 @@ public void visit(ExprId node) { } } + @Override + public void visit(ExprString node) { + // 2-byte sized strings are merged, for simplicity. 1-bytes will be added byte per byte. + // hopefully this covers all cases. + + int strLen = node.string.length(); + if (sizeBytes == 2) { + if (strLen > sizeBytes) { + error(expressionIsBiggerThanExpected(node, sizeBytes, strLen)); + } + int result = node.string.charAt(0); + if (strLen > 1) { + result |= (node.string.charAt(1) << 8); + } + node.addChild(new Evaluated(node.line, node.column, result)); + } else { + for (int i = 0; i < strLen; i++) { + node.addChild(new Evaluated(node.line, node.column, node.string.charAt(i))); + } + } + node.exclude(); + } + private Optional getCurrentAddress() { return doNotEvaluateCurrentAddress ? Optional.empty() : Optional.of(currentAddress); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/NodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/NodeVisitor.java index 00a8d92e9..20e173f6c 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/NodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/NodeVisitor.java @@ -61,6 +61,10 @@ public void visit(ExprId node) { visitChildren(node); } + public void visit(ExprString node) { + visitChildren(node); + } + public void visit(ExprNumber node) { visitChildren(node); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/ConstantsAndVariablesTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/ConstantsAndVariablesTest.java index 83a55a930..94170a4d8 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/ConstantsAndVariablesTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/ConstantsAndVariablesTest.java @@ -48,15 +48,13 @@ public void testConstantAsLabelWorks() throws Exception { ); } - @Test - public void testRecursiveConstantDefinitionsWorks() throws Exception { + @Test(expected = Exception.class) + public void testRecursiveConstantDefinitionsDoesNotWork() throws Exception { compile( "here equ there\n" + "there equ here\n" + "jz here" ); - - assertProgram(0xCA, 0, 0); } @Test(expected = Exception.class) diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseDataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseDataTest.java index aa3347817..9a7fdefba 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseDataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseDataTest.java @@ -5,6 +5,7 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.as8080.ast.expr.ExprString; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprUnary; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import org.junit.Test; @@ -21,11 +22,7 @@ public void testDBstring1() { Program program = parseProgram("db 'hello'"); assertTrees(new Program() .addChild(new DataDB(0, 0) - .addChild(new ExprNumber(0, 0, 'h')) - .addChild(new ExprNumber(0, 0, 'e')) - .addChild(new ExprNumber(0, 0, 'l')) - .addChild(new ExprNumber(0, 0, 'l')) - .addChild(new ExprNumber(0, 0, 'o'))), + .addChild(new ExprString(0, 0, "hello"))), program ); } @@ -35,11 +32,7 @@ public void testDBstring2() { Program program = parseProgram("db \"hello\""); assertTrees(new Program() .addChild(new DataDB(0, 0) - .addChild(new ExprNumber(0, 0, 'h')) - .addChild(new ExprNumber(0, 0, 'e')) - .addChild(new ExprNumber(0, 0, 'l')) - .addChild(new ExprNumber(0, 0, 'l')) - .addChild(new ExprNumber(0, 0, 'o'))), + .addChild(new ExprString(0, 0, "hello"))), program ); } @@ -47,7 +40,6 @@ public void testDBstring2() { @Test public void testDBinstruction() { Program program = parseProgram("db stc"); - System.out.println(program); assertTrees( new Program() .addChild(new DataDB(0, 0) @@ -87,11 +79,7 @@ public void testMultipleDBstringNumberString() { .addChild(new DataDB(0, 0) .addChild(new ExprUnary(0, 0, OP_SUBTRACT) .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 'h')) - .addChild(new ExprNumber(0, 0, 'e')) - .addChild(new ExprNumber(0, 0, 'l')) - .addChild(new ExprNumber(0, 0, 'l')) - .addChild(new ExprNumber(0, 0, 'o')) + .addChild(new ExprString(0, 0, "hello")) .addChild(new ExprNumber(0, 0, 3))), program ); From 02186ff746c959cf01993684f633072e668c1ff0 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 17 Jan 2022 07:25:31 +0100 Subject: [PATCH 078/314] [#201] as-8080: fixes --- .../plugins/compiler/as8080/CompileError.java | 7 ++ .../compiler/as8080/ast/instr/InstrExpr.java | 17 +-- .../visitors/CheckExprSizesVisitor.java | 14 ++- .../as8080/visitors/EvaluateExprVisitor.java | 1 + .../as8080/visitors/GenerateCodeVisitor.java | 7 +- .../plugins/compiler/as8080/e2e/DataTest.java | 10 -- .../compiler/as8080/e2e/MacroTest.java | 14 ++- .../visitors/GenerateCodeVisitorTest.java | 109 +++++++++++++----- 8 files changed, 118 insertions(+), 61 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java index 2354112a2..1c32cfaef 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java @@ -16,6 +16,7 @@ public class CompileError { public static final int ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH = 8; public static final int ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED = 9; public static final int ERROR_VALUE_MUST_BE_POSITIVE = 10; + public static final int ERROR_VALUE_OUT_OF_BOUNDS = 11; public final int line; public final int column; @@ -84,6 +85,12 @@ public static CompileError valueMustBePositive(Node node) { return new CompileError(node, ERROR_VALUE_MUST_BE_POSITIVE, "Value must be positive"); } + public static CompileError valueOutOfBounds(Node node, int min, int max) { + return new CompileError( + node, ERROR_VALUE_OUT_OF_BOUNDS, "Value is out of bounds (min=" + min + ", max=" + max + ")" + ); + } + @Override public String toString() { return "CompileError{" + diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index 02c4f5951..d6c5cda45 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -5,10 +5,7 @@ import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; @@ -82,17 +79,15 @@ public int getExprSizeBytes() { return 2; // address } - public byte eval() { + public Optional eval() { byte result = (byte) (opcodes.get(opcode) & 0xFF); if (opcode == OPCODE_RST) { - result = (byte) (result | collectChild(Evaluated.class) - .map(e -> { - int value = e.value; - return (byte) (value << 3); - }).orElse((byte) 0)); + return collectChild(Evaluated.class) + .filter(e -> e.value >= 0 && e.value <= 7) + .map(e -> (byte) (result | (e.value << 3))); } - return result; + return Optional.of(result); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java index a2b5d23d0..b5717393a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitor.java @@ -73,11 +73,15 @@ public void visit(PseudoMacroArgument node) { @Override public void visit(Evaluated node) { - long maxNumber = Long.MAX_VALUE >>> (63 - expectedBytes * 8); - if (expectedBytes > 0 && node.value != (node.value & maxNumber)) { - int wasBits = (int) Math.ceil(Math.log10(node.value) / Math.log10(2)) + 1; - int wasBytes = wasBits / 8 + wasBits % 8; - error(expressionIsBiggerThanExpected(node, expectedBytes, wasBytes)); + if (expectedBytes > 0) { + int value = node.value < 0 ? ((~node.value) * 2) : node.value; + + int wasBits = (int) Math.floor(Math.log10(Math.abs(value)) / Math.log10(2)) + 1; + int wasBytes = (int) Math.ceil(wasBits / 8.0); + + if (wasBytes > expectedBytes) { + error(expressionIsBiggerThanExpected(node, expectedBytes, wasBytes)); + } } } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 7af88b2c7..76e3d07ab 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -330,6 +330,7 @@ public void visit(ExprString node) { } } node.exclude(); + currentAddress += sizeBytes; } private Optional getCurrentAddress() { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java index 47fd0606c..9340a2ec3 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java @@ -11,6 +11,7 @@ import java.util.Objects; import static net.emustudio.plugins.compiler.as8080.CompileError.valueMustBePositive; +import static net.emustudio.plugins.compiler.as8080.CompileError.valueOutOfBounds; public class GenerateCodeVisitor extends NodeVisitor { private final IntelHEX hex; @@ -48,7 +49,11 @@ public void visit(DataDS node) { @Override public void visit(InstrExpr node) { - hex.add(node.eval()); + node.eval() + .ifPresentOrElse( + hex::add, + () -> error(valueOutOfBounds(node, 0, 7)) + ); expectedBytes = node.getExprSizeBytes(); visitChildren(node); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java index 4906ccee1..2673db537 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java @@ -189,14 +189,4 @@ public void testJumpBackwardWithDSamong() throws Exception { 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 ); } - - @Test(expected = Exception.class) - public void testDS_ValueTooBig() throws Exception { - compile( - "org 0FFh\n" - + "rrc\n" - + "test:\n" - + "ds test" - ); - } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/MacroTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/MacroTest.java index c5c9fb6f0..3dd50e4c4 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/MacroTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/MacroTest.java @@ -64,8 +64,8 @@ public void testMacroWithParams() throws Exception { ); } - @Test(expected = Exception.class) - public void testDBinMacroIsNotVisibleFromOutside() throws Exception { + @Test + public void testDBinMacroIsVisibleFromOutside() throws Exception { compile( "shrt macro\n" + " text: db 0Fh\n" @@ -74,6 +74,9 @@ public void testDBinMacroIsNotVisibleFromOutside() throws Exception { + "shrt\n" + "lxi h, text\n" ); + assertProgram( + 0x0F, 0xE6, 0x7F, 0x21, 0, 0 + ); } @Test(expected = Exception.class) @@ -95,8 +98,8 @@ public void testMacroAlreadyDefined() throws Exception { ); } - @Test(expected = Exception.class) - public void testMacroCannotGetForwardLabelReferences() throws Exception { + @Test + public void testMacroCanGetForwardLabelReferences() throws Exception { compile( "shrt macro param\n" + " lxi h, param\n" @@ -104,6 +107,9 @@ public void testMacroCannotGetForwardLabelReferences() throws Exception { + "shrt text\n" + "text: db 1\n" ); + assertProgram( + 0x21, 3, 0, 1 + ); } @Test(expected = Exception.class) diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java index 8ce7c851b..4a5d74478 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java @@ -126,7 +126,43 @@ public void testGenerateInstructions() { .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_E) .addChild(new Evaluated(0, 0, 10))) .addChild(new InstrNoArgs(0, 0, OPCODE_RAR)) - ; + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_H) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrExpr(0, 0, OPCODE_SHLD) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_H)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_H) + .addChild(new Evaluated(0, 0, 0x28))) + .addChild(new InstrNoArgs(0, 0, OPCODE_DAA)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_H)) + .addChild(new InstrExpr(0, 0, OPCODE_LHLD) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_L)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_L) + .addChild(new Evaluated(0, 0, 10))) + .addChild(new InstrNoArgs(0, 0, OPCODE_CMA)) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_SP) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrExpr(0, 0, OPCODE_STA) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_SP)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_M)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_M) + .addChild(new Evaluated(0, 0, 7))) + .addChild(new InstrNoArgs(0, 0, OPCODE_STC)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_SP)) + .addChild(new InstrExpr(0, 0, OPCODE_LDA) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_SP)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_A)) + + ; IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); @@ -170,36 +206,49 @@ public void testGenerateInstructions() { assertEquals(0x1E, code.get(34).byteValue()); // MVI E assertEquals(10, code.get(35).byteValue()); assertEquals(0x1F, code.get(36).byteValue()); // RAR + assertEquals(0x21, code.get(37).byteValue()); // LXI H + assertEquals(0x45, code.get(38).byteValue()); + assertEquals(0x23, code.get(39).byteValue()); + assertEquals(0x22, code.get(40).byteValue()); // SHLD + assertEquals(0x45, code.get(41).byteValue()); + assertEquals(0x23, code.get(42).byteValue()); + assertEquals(0x23, code.get(43).byteValue()); // INX H + assertEquals(0x24, code.get(44).byteValue()); // INR H + assertEquals(0x25, code.get(45).byteValue()); // DCR H + assertEquals(0x26, code.get(46).byteValue()); // MVI H + assertEquals(0x28, code.get(47).byteValue()); + assertEquals(0x27, code.get(48).byteValue()); // DAA + assertEquals(0x29, code.get(49).byteValue()); // DAD H + assertEquals(0x2A, code.get(50).byteValue()); // LHLD + assertEquals(0x45, code.get(51).byteValue()); + assertEquals(0x23, code.get(52).byteValue()); + assertEquals(0x2B, code.get(53).byteValue()); // DCX H + assertEquals(0x2C, code.get(54).byteValue()); // INR L + assertEquals(0x2D, code.get(55).byteValue()); // DCR L + assertEquals(0x2E, code.get(56).byteValue()); // MVI L + assertEquals(10, code.get(57).byteValue()); + assertEquals(0x2F, code.get(58).byteValue()); // CMA + assertEquals(0x31, code.get(59).byteValue()); // LXI SP + assertEquals(0x45, code.get(60).byteValue()); + assertEquals(0x23, code.get(61).byteValue()); + assertEquals(0x32, code.get(62).byteValue()); // STA + assertEquals(0x45, code.get(63).byteValue()); + assertEquals(0x23, code.get(64).byteValue()); + assertEquals(0x33, code.get(65).byteValue()); // INX SP + assertEquals(0x34, code.get(66).byteValue()); // INR M + assertEquals(0x35, code.get(67).byteValue()); // DCR M + assertEquals(0x36, code.get(68).byteValue()); // MVI M + assertEquals(7, code.get(69).byteValue()); + assertEquals(0x37, code.get(70).byteValue()); // STC + assertEquals(0x39, code.get(71).byteValue()); // DAD SP + assertEquals(0x3A, code.get(72).byteValue()); // LDA + assertEquals(0x45, code.get(73).byteValue()); + assertEquals(0x23, code.get(74).byteValue()); + assertEquals(0x3B, code.get(75).byteValue()); // DCX SP + assertEquals(0x3C, code.get(76).byteValue()); // INR A + assertEquals(0x3D, code.get(77).byteValue()); // DCR A + - //0x21 LXI H,D16 3 H <- byte 3, L <- byte 2 - //0x22 SHLD adr 3 (adr) <-L; (adr+1)<-H - //0x23 INX H 1 HL <- HL + 1 - //0x24 INR H 1 Z, S, P, AC H <- H+1 - //0x25 DCR H 1 Z, S, P, AC H <- H-1 - //0x26 MVI H,D8 2 H <- byte 2 - //0x27 DAA 1 special - //0x28 - - //0x29 DAD H 1 CY HL = HL + HI - //0x2a LHLD adr 3 L <- (adr); H<-(adr+1) - //0x2b DCX H 1 HL = HL-1 - //0x2c INR L 1 Z, S, P, AC L <- L+1 - //0x2d DCR L 1 Z, S, P, AC L <- L-1 - //0x2e MVI L, D8 2 L <- byte 2 - //0x2f CMA 1 A <- !A - //0x30 - - //0x31 LXI SP, D16 3 SP.hi <- byte 3, SP.lo <- byte 2 - //0x32 STA adr 3 (adr) <- A - //0x33 INX SP 1 SP = SP + 1 - //0x34 INR M 1 Z, S, P, AC (HL) <- (HL)+1 - //0x35 DCR M 1 Z, S, P, AC (HL) <- (HL)-1 - //0x36 MVI M,D8 2 (HL) <- byte 2 - //0x37 STC 1 CY CY = 1 - //0x38 - - //0x39 DAD SP 1 CY HL = HL + SP - //0x3a LDA adr 3 A <- (adr) - //0x3b DCX SP 1 SP = SP-1 - //0x3c INR A 1 Z, S, P, AC A <- A+1 - //0x3d DCR A 1 Z, S, P, AC A <- A-1 //0x3e MVI A,D8 2 A <- byte 2 //0x3f CMC 1 CY CY=!CY //0x40 MOV B,B 1 B <- B From 32338f964dc130e91738546fbd6ddb12c82ab2bc Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 17 Jan 2022 11:50:58 +0100 Subject: [PATCH 079/314] [#201] as-8080: tests --- .../visitors/GenerateCodeVisitorTest.java | 202 ++++++++++++------ 1 file changed, 135 insertions(+), 67 deletions(-) diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java index 4a5d74478..22f235016 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java @@ -161,7 +161,73 @@ public void testGenerateInstructions() { .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_SP)) .addChild(new InstrReg(0, 0, OPCODE_INR, REG_A)) .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_A)) - + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0, 0, -128))) + .addChild(new InstrNoArgs(0, 0, OPCODE_CMC)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_M)) // HLT + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_A)) ; IntelHEX hex = new IntelHEX(); @@ -247,74 +313,76 @@ public void testGenerateInstructions() { assertEquals(0x3B, code.get(75).byteValue()); // DCX SP assertEquals(0x3C, code.get(76).byteValue()); // INR A assertEquals(0x3D, code.get(77).byteValue()); // DCR A + assertEquals(0x3E, code.get(78).byteValue()); // MVI A + assertEquals(-128, code.get(79).byteValue()); + assertEquals(0x3F, code.get(80).byteValue()); // CMC + assertEquals(0x40, code.get(81).byteValue()); // MOV B,B + assertEquals(0x41, code.get(82).byteValue()); // MOV B,C + assertEquals(0x42, code.get(83).byteValue()); // MOV B,D + assertEquals(0x43, code.get(84).byteValue()); // MOV B,E + assertEquals(0x44, code.get(85).byteValue()); // MOV B,H + assertEquals(0x45, code.get(86).byteValue()); // MOV B,L + assertEquals(0x46, code.get(87).byteValue()); // MOV B,M + assertEquals(0x47, code.get(88).byteValue()); // MOV B,A + assertEquals(0x48, code.get(89).byteValue()); // MOV C,B + assertEquals(0x49, code.get(90).byteValue()); // MOV C,C + assertEquals(0x4A, code.get(91).byteValue()); // MOV C,D + assertEquals(0x4B, code.get(92).byteValue()); // MOV C,E + assertEquals(0x4C, code.get(93).byteValue()); // MOV C,H + assertEquals(0x4D, code.get(94).byteValue()); // MOV C,L + assertEquals(0x4E, code.get(95).byteValue()); // MOV C,M + assertEquals(0x4F, code.get(96).byteValue()); // MOV C,A + assertEquals(0x50, code.get(97).byteValue()); // MOV D,B + assertEquals(0x51, code.get(98).byteValue()); // MOV D,C + assertEquals(0x52, code.get(99).byteValue()); // MOV D,D + assertEquals(0x53, code.get(100).byteValue()); // MOV D,E + assertEquals(0x54, code.get(101).byteValue()); // MOV D,H + assertEquals(0x55, code.get(102).byteValue()); // MOV D,L + assertEquals(0x56, code.get(103).byteValue()); // MOV D,M + assertEquals(0x57, code.get(104).byteValue()); // MOV D,A + assertEquals(0x58, code.get(105).byteValue()); // MOV E,B + assertEquals(0x59, code.get(106).byteValue()); // MOV E,C + assertEquals(0x5A, code.get(107).byteValue()); // MOV E,D + assertEquals(0x5B, code.get(108).byteValue()); // MOV E,E + assertEquals(0x5C, code.get(109).byteValue()); // MOV E,H + assertEquals(0x5D, code.get(110).byteValue()); // MOV E,L + assertEquals(0x5E, code.get(111).byteValue()); // MOV E,M + assertEquals(0x5F, code.get(112).byteValue()); // MOV E,A + assertEquals(0x60, code.get(113).byteValue()); // MOV H,B + assertEquals(0x61, code.get(114).byteValue()); // MOV H,C + assertEquals(0x62, code.get(115).byteValue()); // MOV H,D + assertEquals(0x63, code.get(116).byteValue()); // MOV H,E + assertEquals(0x64, code.get(117).byteValue()); // MOV H,H + assertEquals(0x65, code.get(118).byteValue()); // MOV H,L + assertEquals(0x66, code.get(119).byteValue()); // MOV H,M + assertEquals(0x67, code.get(120).byteValue()); // MOV H,A + assertEquals(0x68, code.get(121).byteValue()); // MOV L,B + assertEquals(0x69, code.get(122).byteValue()); // MOV L,C + assertEquals(0x6A, code.get(123).byteValue()); // MOV L,D + assertEquals(0x6B, code.get(124).byteValue()); // MOV L,E + assertEquals(0x6C, code.get(125).byteValue()); // MOV L,H + assertEquals(0x6D, code.get(126).byteValue()); // MOV L,L + assertEquals(0x6E, code.get(127).byteValue()); // MOV L,M + assertEquals(0x6F, code.get(128).byteValue()); // MOV L,A + assertEquals(0x70, code.get(129).byteValue()); // MOV M,B + assertEquals(0x71, code.get(130).byteValue()); // MOV M,C + assertEquals(0x72, code.get(131).byteValue()); // MOV M,D + assertEquals(0x73, code.get(132).byteValue()); // MOV M,E + assertEquals(0x74, code.get(133).byteValue()); // MOV M,H + assertEquals(0x75, code.get(134).byteValue()); // MOV M,L + assertEquals(0x76, code.get(135).byteValue()); // MOV M,M / HLT + assertEquals(0x77, code.get(136).byteValue()); // MOV M,A + assertEquals(0x78, code.get(137).byteValue()); // MOV A,B + assertEquals(0x79, code.get(138).byteValue()); // MOV A,C + assertEquals(0x7A, code.get(139).byteValue()); // MOV A,D + assertEquals(0x7B, code.get(140).byteValue()); // MOV A,E + assertEquals(0x7C, code.get(141).byteValue()); // MOV A,H + assertEquals(0x7D, code.get(142).byteValue()); // MOV A,L + assertEquals(0x7E, code.get(143).byteValue()); // MOV A,M + assertEquals(0x7F, code.get(144).byteValue()); // MOV A,A + - //0x3e MVI A,D8 2 A <- byte 2 - //0x3f CMC 1 CY CY=!CY - //0x40 MOV B,B 1 B <- B - //0x41 MOV B,C 1 B <- C - //0x42 MOV B,D 1 B <- D - //0x43 MOV B,E 1 B <- E - //0x44 MOV B,H 1 B <- H - //0x45 MOV B,L 1 B <- L - //0x46 MOV B,M 1 B <- (HL) - //0x47 MOV B,A 1 B <- A - //0x48 MOV C,B 1 C <- B - //0x49 MOV C,C 1 C <- C - //0x4a MOV C,D 1 C <- D - //0x4b MOV C,E 1 C <- E - //0x4c MOV C,H 1 C <- H - //0x4d MOV C,L 1 C <- L - //0x4e MOV C,M 1 C <- (HL) - //0x4f MOV C,A 1 C <- A - //0x50 MOV D,B 1 D <- B - //0x51 MOV D,C 1 D <- C - //0x52 MOV D,D 1 D <- D - //0x53 MOV D,E 1 D <- E - //0x54 MOV D,H 1 D <- H - //0x55 MOV D,L 1 D <- L - //0x56 MOV D,M 1 D <- (HL) - //0x57 MOV D,A 1 D <- A - //0x58 MOV E,B 1 E <- B - //0x59 MOV E,C 1 E <- C - //0x5a MOV E,D 1 E <- D - //0x5b MOV E,E 1 E <- E - //0x5c MOV E,H 1 E <- H - //0x5d MOV E,L 1 E <- L - //0x5e MOV E,M 1 E <- (HL) - //0x5f MOV E,A 1 E <- A - //0x60 MOV H,B 1 H <- B - //0x61 MOV H,C 1 H <- C - //0x62 MOV H,D 1 H <- D - //0x63 MOV H,E 1 H <- E - //0x64 MOV H,H 1 H <- H - //0x65 MOV H,L 1 H <- L - //0x66 MOV H,M 1 H <- (HL) - //0x67 MOV H,A 1 H <- A - //0x68 MOV L,B 1 L <- B - //0x69 MOV L,C 1 L <- C - //0x6a MOV L,D 1 L <- D - //0x6b MOV L,E 1 L <- E - //0x6c MOV L,H 1 L <- H - //0x6d MOV L,L 1 L <- L - //0x6e MOV L,M 1 L <- (HL) - //0x6f MOV L,A 1 L <- A - //0x70 MOV M,B 1 (HL) <- B - //0x71 MOV M,C 1 (HL) <- C - //0x72 MOV M,D 1 (HL) <- D - //0x73 MOV M,E 1 (HL) <- E - //0x74 MOV M,H 1 (HL) <- H - //0x75 MOV M,L 1 (HL) <- L - //0x76 HLT 1 special - //0x77 MOV M,A 1 (HL) <- A - //0x78 MOV A,B 1 A <- B - //0x79 MOV A,C 1 A <- C - //0x7a MOV A,D 1 A <- D - //0x7b MOV A,E 1 A <- E - //0x7c MOV A,H 1 A <- H - //0x7d MOV A,L 1 A <- L - //0x7e MOV A,M 1 A <- (HL) - //0x7f MOV A,A 1 A <- A //0x80 ADD B 1 Z, S, P, CY, AC A <- A + B //0x81 ADD C 1 Z, S, P, CY, AC A <- A + C //0x82 ADD D 1 Z, S, P, CY, AC A <- A + D From b89f096647ded636275c7d7f9594c2f8bb1e7a18 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 19 Jan 2022 10:56:08 +0100 Subject: [PATCH 080/314] [#201] as-8080: test --- .../compiler/as-8080/src/main/cup/parser.cup | 348 ------------------ .../visitors/GenerateCodeVisitorTest.java | 220 +++++++---- 2 files changed, 150 insertions(+), 418 deletions(-) delete mode 100644 plugins/compiler/as-8080/src/main/cup/parser.cup diff --git a/plugins/compiler/as-8080/src/main/cup/parser.cup b/plugins/compiler/as-8080/src/main/cup/parser.cup deleted file mode 100644 index 65fdd58be..000000000 --- a/plugins/compiler/as-8080/src/main/cup/parser.cup +++ /dev/null @@ -1,348 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080; - -import java_cup.runtime.ComplexSymbolFactory; -import java_cup.runtime.Symbol; -import net.emustudio.emulib.plugins.compiler.CompilerMessage; -import net.emustudio.emulib.plugins.compiler.Token; -import net.emustudio.plugins.compiler.as8080.tree.*; -import net.emustudio.plugins.compiler.as8080.treeAbstract.*; - -import java.util.List; -import java.util.Objects; -import java.util.Vector; -import java.util.stream.Collectors; - - -init with {: lastLine = 0; lastColumn = 0; :} -scan with {: - Token t = (Token)this.getScanner().next_token(); - this.lastLine = t.getLine()+1; - this.lastColumn = t.getColumn()+1; - return (Symbol)t; - :} -parser code {: - private CompilerImpl compiler; // cannot be final because cup generates garbage constructors - private boolean syntaxErrors; - private int lastLine; - private int lastColumn; - private String reportPrefixString; - - public ParserImpl(LexerImpl lexer, CompilerImpl compiler) { - super(lexer, new ComplexSymbolFactory()); - this.compiler = Objects.requireNonNull(compiler); - } - - public void reset() { - syntaxErrors = false; - } - - @Override - public void report_fatal_error(String message, Object info) throws Exception { - done_parsing(); - report_error(message, info); - throw new Exception("Can't recover from previous error(s)"); - } - - @Override - public void report_error(String messageText, Object current) { - syntaxErrors = true; - - Token token = (Token)current; - - if (reportPrefixString != null) { - messageText = reportPrefixString + messageText + ":" + token.getErrorString() + " ('" + token.getText() + "')"; - } else { - messageText += ":" + token.getErrorString() + " ('" + token.getText() + "')"; - } - - List expectedTokenIds = expected_token_ids() - .stream() - .map(this::symbl_name_from_id) - .collect(Collectors.toList()); - - if (!expectedTokenIds.isEmpty()) { - messageText += "\nExpected tokens: " + expectedTokenIds; - } - - CompilerMessage message = new CompilerMessage( - CompilerMessage.MessageType.TYPE_ERROR, messageText, token.getLine()+1, token.getColumn() - ); - - compiler.notifyOnMessage(message); - } - - public boolean hasSyntaxErrors() { - return syntaxErrors; - } - - public void setReportPrefixString(String str) { - this.reportPrefixString = str; - } -:} - -terminal RESERVED_STC,RESERVED_CMC,RESERVED_INR,RESERVED_DCR,RESERVED_CMA, - RESERVED_DAA,RESERVED_NOP,RESERVED_MOV,RESERVED_STAX,RESERVED_LDAX, - RESERVED_ADD,RESERVED_ADC,RESERVED_SUB,RESERVED_SBB,RESERVED_ANA, - RESERVED_XRA,RESERVED_ORA,RESERVED_CMP,RESERVED_RLC,RESERVED_RRC, - RESERVED_RAL,RESERVED_RAR,RESERVED_PUSH,RESERVED_POP,RESERVED_DAD, - RESERVED_INX,RESERVED_DCX,RESERVED_XCHG,RESERVED_XTHL,RESERVED_SPHL, - RESERVED_LXI,RESERVED_MVI,RESERVED_ADI,RESERVED_ACI,RESERVED_SUI, - RESERVED_SBI,RESERVED_ANI,RESERVED_XRI,RESERVED_ORI,RESERVED_CPI, - RESERVED_STA,RESERVED_LDA,RESERVED_SHLD,RESERVED_LHLD,RESERVED_PCHL, - RESERVED_JMP,RESERVED_JC,RESERVED_JNC,RESERVED_JZ,RESERVED_JNZ, - RESERVED_JP,RESERVED_JM,RESERVED_JPE,RESERVED_JPO,RESERVED_CALL, - RESERVED_CC,RESERVED_CNC,RESERVED_CZ,RESERVED_CNZ,RESERVED_CP, - RESERVED_CM,RESERVED_CPE,RESERVED_CPO,RESERVED_RET,RESERVED_RC, - RESERVED_RNC,RESERVED_RZ,RESERVED_RNZ,RESERVED_RM,RESERVED_RP, - RESERVED_RPE,RESERVED_RPO,RESERVED_RST,RESERVED_EI,RESERVED_DI, - RESERVED_IN,RESERVED_OUT,RESERVED_HLT; -terminal PREPROCESSOR_ORG,PREPROCESSOR_EQU,PREPROCESSOR_SET,PREPROCESSOR_INCLUDE, - PREPROCESSOR_IF,PREPROCESSOR_ENDIF,PREPROCESSOR_MACRO,PREPROCESSOR_ENDM, - PREPROCESSOR_DB,PREPROCESSOR_DW,PREPROCESSOR_DS,PREPROCESSOR_ADDR; -terminal REGISTERS_A,REGISTERS_B,REGISTERS_C,REGISTERS_D,REGISTERS_E, - REGISTERS_H,REGISTERS_L,REGISTERS_M,REGISTERS_PSW,REGISTERS_SP; -terminal SEPARATOR_LPAR,SEPARATOR_RPAR,SEPARATOR_COMMA,SEPARATOR_EOL; -terminal OPERATOR_ADD,OPERATOR_SUBTRACT,OPERATOR_MULTIPLY,OPERATOR_DIVIDE, - OPERATOR_EQUAL,OPERATOR_MOD,OPERATOR_SHR,OPERATOR_SHL,OPERATOR_NOT, - OPERATOR_AND,OPERATOR_OR,OPERATOR_XOR; -terminal Integer LITERAL_DECIMAL_8BIT,LITERAL_DECIMAL_16BIT; -terminal String LITERAL_STRING,TLABEL,TIDENTIFIER; -terminal TCOMMENT; - -non terminal Statement Statement; -non terminal InstructionNode Instruction; -non terminal LabelNode LabelOptional; -non terminal CodePseudoNode CodePseudocode; -non terminal CodeNode Code; -non terminal PseudoNode Pseudocode; -non terminal DataNode Data,DBDataList,DWDataList; -non terminal DBDataNode DB_Data; -non terminal DWDataNode DW_Data; -non terminal OpCodeNode Opcode; -non terminal ExprNode Expression; -non terminal Vector MacroOperOptional,MOperList,MacroExprOptional,MExprList; -non terminal Byte Reg,RegPairBD,RegPairBDHP,RegPairBDHS; -non terminal CommentOptional; - -precedence left OPERATOR_OR,OPERATOR_XOR; -precedence left OPERATOR_AND; -precedence left OPERATOR_NOT; -precedence nonassoc OPERATOR_EQUAL; -precedence left OPERATOR_ADD,OPERATOR_SUBTRACT; -precedence left OPERATOR_MULTIPLY,OPERATOR_DIVIDE,OPERATOR_MOD,OPERATOR_SHL, - OPERATOR_SHR; - -start with Statement; - -Statement ::= Instruction:instr - {: - Statement stmt = new Statement(); - if (instr != null) stmt.addElement(instr); - RESULT = stmt; - :} - | Statement:stmt SEPARATOR_EOL Instruction:instr - {: if (instr != null) stmt.addElement(instr); RESULT = stmt; :} - | Statement:stmt error {: parser.syntaxErrors = true; RESULT = stmt; :}; - -Instruction ::= LabelOptional:label CodePseudocode:codepseudo CommentOptional - {: if (label == null && codepseudo == null) RESULT = null; - else RESULT = new InstructionNode(label,codepseudo); :}; - -LabelOptional ::= TLABEL:name {: RESULT = new LabelNode(name,parser.lastLine,parser.lastColumn); :} - | {: RESULT = null; :}; -CommentOptional ::= TCOMMENT | ; -CodePseudocode ::= Code:code {: RESULT = code; :} - | Pseudocode:pseudo {: RESULT = pseudo; :} - | {: RESULT = null; :}; - -Code ::= Data:data {: RESULT = data; :} | Opcode:code {: RESULT = code; :}; - -Data ::= PREPROCESSOR_DB DBDataList:db {: RESULT = db; :} - | PREPROCESSOR_DW DWDataList:dw {: RESULT = dw; :} - | PREPROCESSOR_DS Expression:expr - {: DataNode dn = new DataNode(parser.lastLine,parser.lastColumn); - dn.addElement(new DSDataNode(expr,parser.lastLine,parser.lastColumn)); - RESULT= dn; :}; - -DBDataList ::= DB_Data:dbdata - {: DataNode dn = new DataNode(parser.lastLine,parser.lastColumn); - dn.addElement(dbdata); - RESULT = dn; :} - | DBDataList:dn SEPARATOR_COMMA DB_Data:dbdata - {: dn.addElement(dbdata); RESULT = dn; :}; - -DWDataList ::= DW_Data:dwdata - {: DataNode dn = new DataNode(parser.lastLine,parser.lastColumn); - dn.addElement(dwdata); - RESULT = dn; :} - | DWDataList:dn SEPARATOR_COMMA DW_Data:dwdata - {: dn.addElement(dwdata); RESULT = dn; :}; - -DB_Data ::= Expression:expr {: RESULT = new DBDataNode(expr,parser.lastLine,parser.lastColumn);:} - | LITERAL_STRING:str {: RESULT = new DBDataNode(str,parser.lastLine,parser.lastColumn); :} - | Opcode:opcode {: RESULT = new DBDataNode(opcode,parser.lastLine,parser.lastColumn);:}; -DW_Data ::= Expression:expr {: RESULT = new DWDataNode(expr,parser.lastLine,parser.lastColumn);:}; - -Expression ::= SEPARATOR_LPAR Expression:e SEPARATOR_RPAR {: RESULT = e; :} - | LITERAL_DECIMAL_8BIT:num8 {: RESULT = new DecimalValueNode(num8); :} - | LITERAL_DECIMAL_16BIT:num16 {:RESULT = new DecimalValueNode(num16); :} - | PREPROCESSOR_ADDR {: RESULT = new AddressValueNode(); :} - | TIDENTIFIER:name {: RESULT = new IdExpr(name); :} - | Expression:e1 OPERATOR_OR Expression:e2 {: RESULT = new ArithNode(e1,e2,"or"); :} - | Expression:e1 OPERATOR_XOR Expression:e2 {: RESULT = new ArithNode(e1,e2,"xor"); :} - | Expression:e1 OPERATOR_AND Expression:e2 {: RESULT = new ArithNode(e1,e2,"and"); :} - | OPERATOR_NOT Expression:e {: RESULT = new ArithNode(e,null,"not"); :} - | Expression:e1 OPERATOR_EQUAL Expression:e2 {: RESULT = new ArithNode(e1,e2,"="); :} - | Expression:e1 OPERATOR_ADD Expression:e2 {: RESULT = new ArithNode(e1,e2,"+"); :} - | OPERATOR_ADD Expression:e1 {: RESULT = new ArithNode(new DecimalValueNode(0),e1,"+"); :} - | Expression:e1 OPERATOR_SUBTRACT Expression:e2 {: RESULT = new ArithNode(e1,e2,"-"); :} - | OPERATOR_SUBTRACT Expression:e1 {: RESULT = new ArithNode(new DecimalValueNode(0),e1,"-"); :} - | Expression:e1 OPERATOR_MULTIPLY Expression:e2 {: RESULT = new ArithNode(e1,e2,"*"); :} - | Expression:e1 OPERATOR_DIVIDE Expression:e2 {: RESULT = new ArithNode(e1,e2,"/"); :} - | Expression:e1 OPERATOR_MOD Expression:e2 {: RESULT = new ArithNode(e1,e2,"mod"); :} - | Expression:e1 OPERATOR_SHR Expression:e2 {: RESULT = new ArithNode(e1,e2,"shr"); :} - | Expression:e1 OPERATOR_SHL Expression:e2 {: RESULT = new ArithNode(e1,e2,"shl"); :}; - -Pseudocode ::= PREPROCESSOR_ORG Expression:e - {: RESULT = new OrgPseudoNode(e,parser.lastLine, parser.lastColumn); :} - | TIDENTIFIER:name PREPROCESSOR_EQU Expression:e - {: RESULT = new EquPseudoNode(name,e,parser.lastLine, parser.lastColumn); :} - | TIDENTIFIER:name PREPROCESSOR_SET Expression:e - {: RESULT = new SetPseudoNode(name,e,parser.lastLine, parser.lastColumn); :} - | PREPROCESSOR_IF Expression:e CommentOptional SEPARATOR_EOL Statement:s - SEPARATOR_EOL PREPROCESSOR_ENDIF - {: RESULT = new IfPseudoNode(e,s,parser.lastLine, parser.lastColumn); :} - | TIDENTIFIER:name PREPROCESSOR_MACRO MacroOperOptional:vec CommentOptional SEPARATOR_EOL - Statement:s PREPROCESSOR_ENDM - {: RESULT = new MacroPseudoNode(name,vec,s,parser.lastLine, parser.lastColumn); :} - | TIDENTIFIER:name MacroExprOptional:vec - {: RESULT = new MacroCallPseudo(name, vec,parser.lastLine, parser.lastColumn); :} - | PREPROCESSOR_INCLUDE LITERAL_STRING:filename - {: RESULT = new IncludePseudoNode(filename,parser.lastLine,parser.lastColumn,parser.compiler); :}; - -MacroOperOptional ::= MOperList:vec {: RESULT = vec; :} | {: RESULT = null; :}; -MOperList ::= TIDENTIFIER:name - {: Vector vec = new Vector(); - vec.addElement(name); - RESULT = vec; :} - | MOperList:vec SEPARATOR_COMMA TIDENTIFIER:name - {: vec.addElement(name); RESULT = vec; :}; - -MacroExprOptional ::= MExprList:vec {: RESULT = vec; :} | {: RESULT = null; :}; -MExprList ::= Expression:expr - {: Vector vec = new Vector(); - vec.addElement(expr); - RESULT = vec; :} - | MExprList:vec SEPARATOR_COMMA Expression:expr - {: vec.addElement(expr); RESULT = vec; :}; - -Opcode ::= RESERVED_STC {: RESULT = new OC_NoParams("stc",parser.lastLine, parser.lastColumn); :} - | RESERVED_CMC {: RESULT = new OC_NoParams("cmc",parser.lastLine, parser.lastColumn); :} - | RESERVED_CMA {: RESULT = new OC_NoParams("cma",parser.lastLine, parser.lastColumn); :} - | RESERVED_DAA {: RESULT = new OC_NoParams("daa",parser.lastLine, parser.lastColumn); :} - | RESERVED_NOP {: RESULT = new OC_NoParams("nop",parser.lastLine, parser.lastColumn); :} - | RESERVED_RLC {: RESULT = new OC_NoParams("rlc",parser.lastLine, parser.lastColumn); :} - | RESERVED_RRC {: RESULT = new OC_NoParams("rrc",parser.lastLine, parser.lastColumn); :} - | RESERVED_RAL {: RESULT = new OC_NoParams("ral",parser.lastLine, parser.lastColumn); :} - | RESERVED_RAR {: RESULT = new OC_NoParams("rar",parser.lastLine, parser.lastColumn); :} - | RESERVED_XCHG {: RESULT = new OC_NoParams("xchg",parser.lastLine, parser.lastColumn); :} - | RESERVED_XTHL {: RESULT = new OC_NoParams("xthl",parser.lastLine, parser.lastColumn); :} - | RESERVED_SPHL {: RESULT = new OC_NoParams("sphl",parser.lastLine, parser.lastColumn); :} - | RESERVED_PCHL {: RESULT = new OC_NoParams("pchl",parser.lastLine, parser.lastColumn); :} - | RESERVED_RET {: RESULT = new OC_NoParams("ret",parser.lastLine, parser.lastColumn); :} - | RESERVED_RC {: RESULT = new OC_NoParams("rc",parser.lastLine, parser.lastColumn); :} - | RESERVED_RNC {: RESULT = new OC_NoParams("rnc",parser.lastLine, parser.lastColumn); :} - | RESERVED_RZ {: RESULT = new OC_NoParams("rz",parser.lastLine, parser.lastColumn); :} - | RESERVED_RNZ {: RESULT = new OC_NoParams("rnz",parser.lastLine, parser.lastColumn); :} - | RESERVED_RM {: RESULT = new OC_NoParams("rm",parser.lastLine, parser.lastColumn); :} - | RESERVED_RP {: RESULT = new OC_NoParams("rp",parser.lastLine, parser.lastColumn); :} - | RESERVED_RPE {: RESULT = new OC_NoParams("rpe",parser.lastLine, parser.lastColumn); :} - | RESERVED_RPO {: RESULT = new OC_NoParams("rpo",parser.lastLine, parser.lastColumn); :} - | RESERVED_EI {: RESULT = new OC_NoParams("ei",parser.lastLine, parser.lastColumn); :} - | RESERVED_DI {: RESULT = new OC_NoParams("di",parser.lastLine, parser.lastColumn); :} - | RESERVED_HLT {: RESULT = new OC_NoParams("hlt",parser.lastLine, parser.lastColumn); :} - | RESERVED_INR Reg:r {: RESULT = new OC_Reg("inr",r,parser.lastLine, parser.lastColumn); :} - | RESERVED_DCR Reg:r {: RESULT = new OC_Reg("dcr",r,parser.lastLine, parser.lastColumn); :} - | RESERVED_ADD Reg:r {: RESULT = new OC_Reg("add",r,parser.lastLine, parser.lastColumn); :} - | RESERVED_ADC Reg:r {: RESULT = new OC_Reg("adc",r,parser.lastLine, parser.lastColumn); :} - | RESERVED_SUB Reg:r {: RESULT = new OC_Reg("sub",r,parser.lastLine, parser.lastColumn); :} - | RESERVED_SBB Reg:r {: RESULT = new OC_Reg("sbb",r,parser.lastLine, parser.lastColumn); :} - | RESERVED_ANA Reg:r {: RESULT = new OC_Reg("ana",r,parser.lastLine, parser.lastColumn); :} - | RESERVED_XRA Reg:r {: RESULT = new OC_Reg("xra",r,parser.lastLine, parser.lastColumn); :} - | RESERVED_ORA Reg:r {: RESULT = new OC_Reg("ora",r,parser.lastLine, parser.lastColumn); :} - | RESERVED_CMP Reg:r {: RESULT = new OC_Reg("cmp",r,parser.lastLine, parser.lastColumn); :} - | RESERVED_MOV Reg:dst SEPARATOR_COMMA Reg:src - {: RESULT = new OC_RegReg("mov",dst,src,parser.lastLine, parser.lastColumn); :} - | RESERVED_STAX RegPairBD:r {: RESULT = new OC_Regpair("stax",r,false,parser.lastLine, parser.lastColumn); :} - | RESERVED_LDAX RegPairBD:r {: RESULT = new OC_Regpair("ldax",r,false,parser.lastLine, parser.lastColumn); :} - | RESERVED_PUSH RegPairBDHP:r {: RESULT = new OC_Regpair("push",r,true,parser.lastLine, parser.lastColumn); :} - | RESERVED_POP RegPairBDHP:r {: RESULT = new OC_Regpair("pop",r,true,parser.lastLine, parser.lastColumn); :} - | RESERVED_DAD RegPairBDHS:r {: RESULT = new OC_Regpair("dad",r,false,parser.lastLine, parser.lastColumn); :} - | RESERVED_INX RegPairBDHS:r {: RESULT = new OC_Regpair("inx",r,false,parser.lastLine, parser.lastColumn); :} - | RESERVED_DCX RegPairBDHS:r {: RESULT = new OC_Regpair("dcx",r,false,parser.lastLine, parser.lastColumn); :} - | RESERVED_LXI RegPairBDHS:r SEPARATOR_COMMA Expression:e - {: RESULT = new OC_RegpairExpr("lxi",r,e,parser.lastLine, parser.lastColumn); :} - | RESERVED_MVI Reg:r SEPARATOR_COMMA Expression:e - {: RESULT = new OC_RegExpr("mvi",r,e,parser.lastLine, parser.lastColumn); :} - | RESERVED_ADI Expression:e {: RESULT = new OC_Expr("adi",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_ACI Expression:e {: RESULT = new OC_Expr("aci",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_SUI Expression:e {: RESULT = new OC_Expr("sui",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_SBI Expression:e {: RESULT = new OC_Expr("sbi",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_ANI Expression:e {: RESULT = new OC_Expr("ani",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_XRI Expression:e {: RESULT = new OC_Expr("xri",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_ORI Expression:e {: RESULT = new OC_Expr("ori",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_CPI Expression:e {: RESULT = new OC_Expr("cpi",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_STA Expression:e {: RESULT = new OC_Expr("sta",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_LDA Expression:e {: RESULT = new OC_Expr("lda",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_SHLD Expression:e {: RESULT = new OC_Expr("shld",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_LHLD Expression:e {: RESULT = new OC_Expr("lhld",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_JMP Expression:e {: RESULT = new OC_Expr("jmp",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_JC Expression:e {: RESULT = new OC_Expr("jc",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_JNC Expression:e {: RESULT = new OC_Expr("jnc",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_JZ Expression:e {: RESULT = new OC_Expr("jz",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_JNZ Expression:e {: RESULT = new OC_Expr("jnz",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_JM Expression:e {: RESULT = new OC_Expr("jm",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_JP Expression:e {: RESULT = new OC_Expr("jp",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_JPE Expression:e {: RESULT = new OC_Expr("jpe",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_JPO Expression:e {: RESULT = new OC_Expr("jpo",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_CALL Expression:e {: RESULT = new OC_Expr("call",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_CC Expression:e {: RESULT = new OC_Expr("cc",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_CNC Expression:e {: RESULT = new OC_Expr("cnc",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_CZ Expression:e {: RESULT = new OC_Expr("cz",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_CNZ Expression:e {: RESULT = new OC_Expr("cnz",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_CM Expression:e {: RESULT = new OC_Expr("cm",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_CP Expression:e {: RESULT = new OC_Expr("cp",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_CPE Expression:e {: RESULT = new OC_Expr("cpe",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_CPO Expression:e {: RESULT = new OC_Expr("cpo",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_RST Expression:e {: RESULT = new OC_Expr("rst",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_IN Expression:e {: RESULT = new OC_Expr("in",e,parser.lastLine, parser.lastColumn); :} - | RESERVED_OUT Expression:e {: RESULT = new OC_Expr("out",e,parser.lastLine, parser.lastColumn); :}; -RegPairBD ::= REGISTERS_B {: RESULT = 0; :} | REGISTERS_D {: RESULT = 1; :}; -RegPairBDHP ::= REGISTERS_B {: RESULT = 0; :} | REGISTERS_D {: RESULT = 1; :} - | REGISTERS_H {: RESULT = 2; :} | REGISTERS_PSW {: RESULT = 3; :}; -RegPairBDHS ::= REGISTERS_B {: RESULT = 0; :} | REGISTERS_D {: RESULT = 1; :} - | REGISTERS_H {: RESULT = 2; :} | REGISTERS_SP {: RESULT = 3; :}; - -Reg ::= REGISTERS_A {: RESULT = 7; :} | REGISTERS_B {: RESULT = 0; :} - | REGISTERS_C {: RESULT = 1; :} | REGISTERS_D {: RESULT = 2; :} - | REGISTERS_E {: RESULT = 3; :} | REGISTERS_H {: RESULT = 4; :} - | REGISTERS_L {: RESULT = 5; :} | REGISTERS_M {: RESULT = 6; :}; - diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java index 22f235016..94676f0db 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java @@ -228,8 +228,82 @@ public void testGenerateInstructions() { .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_L)) .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_M)) .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_A)) + .addChild(new InstrNoArgs(0, 0, OPCODE_RNZ)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_B)) + .addChild(new InstrExpr(0, 0, OPCODE_JNZ) + .addChild(new Evaluated(0, 0, 2))) + .addChild(new InstrExpr(0, 0, OPCODE_JMP) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrExpr(0, 0, OPCODE_CNZ) + .addChild(new Evaluated(0, 0, 0xF0A0))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_B)) ; + IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); visitor.visit(program); @@ -380,79 +454,85 @@ public void testGenerateInstructions() { assertEquals(0x7D, code.get(142).byteValue()); // MOV A,L assertEquals(0x7E, code.get(143).byteValue()); // MOV A,M assertEquals(0x7F, code.get(144).byteValue()); // MOV A,A + assertEquals(0x80, code.get(145) & 0xFF); // ADD B + assertEquals(0x81, code.get(146) & 0xFF); // ADD C + assertEquals(0x82, code.get(147) & 0xFF); // ADD D + assertEquals(0x83, code.get(148) & 0xFF); // ADD E + assertEquals(0x84, code.get(149) & 0xFF); // ADD H + assertEquals(0x85, code.get(150) & 0xFF); // ADD L + assertEquals(0x86, code.get(151) & 0xFF); // ADD M + assertEquals(0x87, code.get(152) & 0xFF); // ADD A + assertEquals(0x88, code.get(153) & 0xFF); // ADC B + assertEquals(0x89, code.get(154) & 0xFF); // ADC C + assertEquals(0x8A, code.get(155) & 0xFF); // ADC D + assertEquals(0x8B, code.get(156) & 0xFF); // ADC E + assertEquals(0x8C, code.get(157) & 0xFF); // ADC H + assertEquals(0x8D, code.get(158) & 0xFF); // ADC L + assertEquals(0x8E, code.get(159) & 0xFF); // ADC M + assertEquals(0x8F, code.get(160) & 0xFF); // ADC A + assertEquals(0x90, code.get(161) & 0xFF); // SUB B + assertEquals(0x91, code.get(162) & 0xFF); // SUB C + assertEquals(0x92, code.get(163) & 0xFF); // SUB D + assertEquals(0x93, code.get(164) & 0xFF); // SUB E + assertEquals(0x94, code.get(165) & 0xFF); // SUB H + assertEquals(0x95, code.get(166) & 0xFF); // SUB L + assertEquals(0x96, code.get(167) & 0xFF); // SUB M + assertEquals(0x97, code.get(168) & 0xFF); // SUB A + assertEquals(0x98, code.get(169) & 0xFF); // SBB B + assertEquals(0x99, code.get(170) & 0xFF); // SBB C + assertEquals(0x9A, code.get(171) & 0xFF); // SBB D + assertEquals(0x9B, code.get(172) & 0xFF); // SBB E + assertEquals(0x9C, code.get(173) & 0xFF); // SBB H + assertEquals(0x9D, code.get(174) & 0xFF); // SBB L + assertEquals(0x9E, code.get(175) & 0xFF); // SBB M + assertEquals(0x9F, code.get(176) & 0xFF); // SBB A + assertEquals(0xA0, code.get(177) & 0xFF); // ANA B + assertEquals(0xA1, code.get(178) & 0xFF); // ANA C + assertEquals(0xA2, code.get(179) & 0xFF); // ANA D + assertEquals(0xA3, code.get(180) & 0xFF); // ANA E + assertEquals(0xA4, code.get(181) & 0xFF); // ANA H + assertEquals(0xA5, code.get(182) & 0xFF); // ANA L + assertEquals(0xA6, code.get(183) & 0xFF); // ANA M + assertEquals(0xA7, code.get(184) & 0xFF); // ANA A + assertEquals(0xA8, code.get(185) & 0xFF); // XRA B + assertEquals(0xA9, code.get(186) & 0xFF); // XRA C + assertEquals(0xAA, code.get(187) & 0xFF); // XRA D + assertEquals(0xAB, code.get(188) & 0xFF); // XRA E + assertEquals(0xAC, code.get(189) & 0xFF); // XRA H + assertEquals(0xAD, code.get(190) & 0xFF); // XRA L + assertEquals(0xAE, code.get(191) & 0xFF); // XRA M + assertEquals(0xAF, code.get(192) & 0xFF); // XRA A + assertEquals(0xB0, code.get(193) & 0xFF); // ORA B + assertEquals(0xB1, code.get(194) & 0xFF); // ORA C + assertEquals(0xB2, code.get(195) & 0xFF); // ORA D + assertEquals(0xB3, code.get(196) & 0xFF); // ORA E + assertEquals(0xB4, code.get(197) & 0xFF); // ORA H + assertEquals(0xB5, code.get(198) & 0xFF); // ORA L + assertEquals(0xB6, code.get(199) & 0xFF); // ORA M + assertEquals(0xB7, code.get(200) & 0xFF); // ORA A + assertEquals(0xB8, code.get(201) & 0xFF); // CMP B + assertEquals(0xB9, code.get(202) & 0xFF); // CMP C + assertEquals(0xBA, code.get(203) & 0xFF); // CMP D + assertEquals(0xBB, code.get(204) & 0xFF); // CMP E + assertEquals(0xBC, code.get(205) & 0xFF); // CMP H + assertEquals(0xBD, code.get(206) & 0xFF); // CMP L + assertEquals(0xBE, code.get(207) & 0xFF); // CMP M + assertEquals(0xBF, code.get(208) & 0xFF); // CMP A + assertEquals(0xC0, code.get(209) & 0xFF); // RNZ + assertEquals(0xC1, code.get(210) & 0xFF); // POP B + assertEquals(0xC2, code.get(211) & 0xFF); // JNZ + assertEquals(2, code.get(212).byteValue()); + assertEquals(0, code.get(213).byteValue()); + assertEquals(0xC3, code.get(214) & 0xFF); // JMP + assertEquals(0, code.get(215).byteValue()); + assertEquals(2, code.get(216).byteValue()); + assertEquals(0xC4, code.get(217) & 0xFF); // CNZ + assertEquals(0xA0, code.get(218) & 0xFF); + assertEquals(0xF0, code.get(219) & 0xFF); + assertEquals(0xC5, code.get(220) & 0xFF); // PUSH B - //0x80 ADD B 1 Z, S, P, CY, AC A <- A + B - //0x81 ADD C 1 Z, S, P, CY, AC A <- A + C - //0x82 ADD D 1 Z, S, P, CY, AC A <- A + D - //0x83 ADD E 1 Z, S, P, CY, AC A <- A + E - //0x84 ADD H 1 Z, S, P, CY, AC A <- A + H - //0x85 ADD L 1 Z, S, P, CY, AC A <- A + L - //0x86 ADD M 1 Z, S, P, CY, AC A <- A + (HL) - //0x87 ADD A 1 Z, S, P, CY, AC A <- A + A - //0x88 ADC B 1 Z, S, P, CY, AC A <- A + B + CY - //0x89 ADC C 1 Z, S, P, CY, AC A <- A + C + CY - //0x8a ADC D 1 Z, S, P, CY, AC A <- A + D + CY - //0x8b ADC E 1 Z, S, P, CY, AC A <- A + E + CY - //0x8c ADC H 1 Z, S, P, CY, AC A <- A + H + CY - //0x8d ADC L 1 Z, S, P, CY, AC A <- A + L + CY - //0x8e ADC M 1 Z, S, P, CY, AC A <- A + (HL) + CY - //0x8f ADC A 1 Z, S, P, CY, AC A <- A + A + CY - //0x90 SUB B 1 Z, S, P, CY, AC A <- A - B - //0x91 SUB C 1 Z, S, P, CY, AC A <- A - C - //0x92 SUB D 1 Z, S, P, CY, AC A <- A + D - //0x93 SUB E 1 Z, S, P, CY, AC A <- A - E - //0x94 SUB H 1 Z, S, P, CY, AC A <- A + H - //0x95 SUB L 1 Z, S, P, CY, AC A <- A - L - //0x96 SUB M 1 Z, S, P, CY, AC A <- A + (HL) - //0x97 SUB A 1 Z, S, P, CY, AC A <- A - A - //0x98 SBB B 1 Z, S, P, CY, AC A <- A - B - CY - //0x99 SBB C 1 Z, S, P, CY, AC A <- A - C - CY - //0x9a SBB D 1 Z, S, P, CY, AC A <- A - D - CY - //0x9b SBB E 1 Z, S, P, CY, AC A <- A - E - CY - //0x9c SBB H 1 Z, S, P, CY, AC A <- A - H - CY - //0x9d SBB L 1 Z, S, P, CY, AC A <- A - L - CY - //0x9e SBB M 1 Z, S, P, CY, AC A <- A - (HL) - CY - //0x9f SBB A 1 Z, S, P, CY, AC A <- A - A - CY - //0xa0 ANA B 1 Z, S, P, CY, AC A <- A & B - //0xa1 ANA C 1 Z, S, P, CY, AC A <- A & C - //0xa2 ANA D 1 Z, S, P, CY, AC A <- A & D - //0xa3 ANA E 1 Z, S, P, CY, AC A <- A & E - //0xa4 ANA H 1 Z, S, P, CY, AC A <- A & H - //0xa5 ANA L 1 Z, S, P, CY, AC A <- A & L - //0xa6 ANA M 1 Z, S, P, CY, AC A <- A & (HL) - //0xa7 ANA A 1 Z, S, P, CY, AC A <- A & A - //0xa8 XRA B 1 Z, S, P, CY, AC A <- A ^ B - //0xa9 XRA C 1 Z, S, P, CY, AC A <- A ^ C - //0xaa XRA D 1 Z, S, P, CY, AC A <- A ^ D - //0xab XRA E 1 Z, S, P, CY, AC A <- A ^ E - //0xac XRA H 1 Z, S, P, CY, AC A <- A ^ H - //0xad XRA L 1 Z, S, P, CY, AC A <- A ^ L - //0xae XRA M 1 Z, S, P, CY, AC A <- A ^ (HL) - //0xaf XRA A 1 Z, S, P, CY, AC A <- A ^ A - //0xb0 ORA B 1 Z, S, P, CY, AC A <- A | B - //0xb1 ORA C 1 Z, S, P, CY, AC A <- A | C - //0xb2 ORA D 1 Z, S, P, CY, AC A <- A | D - //0xb3 ORA E 1 Z, S, P, CY, AC A <- A | E - //0xb4 ORA H 1 Z, S, P, CY, AC A <- A | H - //0xb5 ORA L 1 Z, S, P, CY, AC A <- A | L - //0xb6 ORA M 1 Z, S, P, CY, AC A <- A | (HL) - //0xb7 ORA A 1 Z, S, P, CY, AC A <- A | A - //0xb8 CMP B 1 Z, S, P, CY, AC A - B - //0xb9 CMP C 1 Z, S, P, CY, AC A - C - //0xba CMP D 1 Z, S, P, CY, AC A - D - //0xbb CMP E 1 Z, S, P, CY, AC A - E - //0xbc CMP H 1 Z, S, P, CY, AC A - H - //0xbd CMP L 1 Z, S, P, CY, AC A - L - //0xbe CMP M 1 Z, S, P, CY, AC A - (HL) - //0xbf CMP A 1 Z, S, P, CY, AC A - A - //0xc0 RNZ 1 if NZ, RET - //0xc1 POP B 1 C <- (sp); B <- (sp+1); sp <- sp+2 - //0xc2 JNZ adr 3 if NZ, PC <- adr - //0xc3 JMP adr 3 PC <= adr - //0xc4 CNZ adr 3 if NZ, CALL adr - //0xc5 PUSH B 1 (sp-2)<-C; (sp-1)<-B; sp <- sp - 2 //0xc6 ADI D8 2 Z, S, P, CY, AC A <- A + byte //0xc7 RST 0 1 CALL $0 //0xc8 RZ 1 if Z, RET From 678a63370ca5a89b3004a7066f45f018a6fca050 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 24 Jan 2022 10:28:26 +0100 Subject: [PATCH 081/314] [#201] as-8080: tests --- .../compiler/as8080/ast/instr/InstrExpr.java | 1 + .../visitors/CheckExprSizesVisitorTest.java | 27 ++ .../visitors/GenerateCodeVisitorTest.java | 243 +++++++++++++----- 3 files changed, 207 insertions(+), 64 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index d6c5cda45..d30df3712 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -49,6 +49,7 @@ public class InstrExpr extends Node { opcodes.put(OPCODE_JPO, 0xE2); opcodes.put(OPCODE_CALL, 0xCD); opcodes.put(OPCODE_CC, 0xDC); + opcodes.put(OPCODE_CZ, 0xCC); opcodes.put(OPCODE_CNC, 0xD4); opcodes.put(OPCODE_CNZ, 0xC4); opcodes.put(OPCODE_CM, 0xFC); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java index 4ace19e11..b228eb49d 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java @@ -6,6 +6,7 @@ import net.emustudio.plugins.compiler.as8080.ast.data.DataDS; import net.emustudio.plugins.compiler.as8080.ast.data.DataDW; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; +import net.emustudio.plugins.compiler.as8080.ast.instr.InstrExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegPairExpr; import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoMacroArgument; @@ -100,6 +101,32 @@ public void testDSthreeBytes() { assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); } + @Test + public void testInstrExprTwoBytes() { + Program program = new Program(); + program + .addChild(new InstrExpr(0, 0, OPCODE_ADI) + .addChild(new Evaluated(0,0, 0xFF00))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testInstrExprThreeBytes() { + Program program = new Program(); + program + .addChild(new InstrExpr(0, 0, OPCODE_JMP) + .addChild(new Evaluated(0,0, 0xFF000))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + @Test public void testInstrRegExprOneByte() { Program program = new Program(); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java index 94676f0db..728e14dc2 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java @@ -301,8 +301,92 @@ public void testGenerateInstructions() { .addChild(new InstrExpr(0, 0, OPCODE_CNZ) .addChild(new Evaluated(0, 0, 0xF0A0))) .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_B)) - ; - + .addChild(new InstrExpr(0, 0, OPCODE_ADI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RZ)) + .addChild(new InstrNoArgs(0, 0, OPCODE_RET)) + .addChild(new InstrExpr(0, 0, OPCODE_JZ) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_CZ) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_CALL) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_ACI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RNC)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_D)) + .addChild(new InstrExpr(0, 0, OPCODE_JNC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_OUT) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_CNC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_D)) + .addChild(new InstrExpr(0, 0, OPCODE_SUI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 2))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RC)) + .addChild(new InstrExpr(0, 0, OPCODE_JC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_IN) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_CC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_SBI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 3))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RPO)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_H)) + .addChild(new InstrExpr(0, 0, OPCODE_JPO) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrNoArgs(0, 0, OPCODE_XTHL)) + .addChild(new InstrExpr(0, 0, OPCODE_CPO) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_H)) + .addChild(new InstrExpr(0, 0, OPCODE_ANI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 4))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RPE)) + .addChild(new InstrNoArgs(0, 0, OPCODE_PCHL)) + .addChild(new InstrExpr(0, 0, OPCODE_JPE) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrNoArgs(0, 0, OPCODE_XCHG)) + .addChild(new InstrExpr(0, 0, OPCODE_CPE) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_XRI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 5))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RP)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_PSW)) + .addChild(new InstrExpr(0, 0, OPCODE_JP) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrNoArgs(0, 0, OPCODE_DI)) + .addChild(new InstrExpr(0, 0, OPCODE_CP) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_PSW)) + .addChild(new InstrExpr(0, 0, OPCODE_ORI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 6))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RM)) + .addChild(new InstrNoArgs(0, 0, OPCODE_SPHL)) + .addChild(new InstrExpr(0, 0, OPCODE_JM) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrNoArgs(0, 0, OPCODE_EI)) + .addChild(new InstrExpr(0, 0, OPCODE_CM) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrExpr(0, 0, OPCODE_CPI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 7))); IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); @@ -530,67 +614,98 @@ public void testGenerateInstructions() { assertEquals(0xA0, code.get(218) & 0xFF); assertEquals(0xF0, code.get(219) & 0xFF); assertEquals(0xC5, code.get(220) & 0xFF); // PUSH B - - - - //0xc6 ADI D8 2 Z, S, P, CY, AC A <- A + byte - //0xc7 RST 0 1 CALL $0 - //0xc8 RZ 1 if Z, RET - //0xc9 RET 1 PC.lo <- (sp); PC.hi<-(sp+1); SP <- SP+2 - //0xca JZ adr 3 if Z, PC <- adr - //0xcb - - //0xcc CZ adr 3 if Z, CALL adr - //0xcd CALL adr 3 (SP-1)<-PC.hi;(SP-2)<-PC.lo;SP<-SP-2;PC=adr - //0xce ACI D8 2 Z, S, P, CY, AC A <- A + data + CY - //0xcf RST 1 1 CALL $8 - //0xd0 RNC 1 if NCY, RET - //0xd1 POP D 1 E <- (sp); D <- (sp+1); sp <- sp+2 - //0xd2 JNC adr 3 if NCY, PC<-adr - //0xd3 OUT D8 2 special - //0xd4 CNC adr 3 if NCY, CALL adr - //0xd5 PUSH D 1 (sp-2)<-E; (sp-1)<-D; sp <- sp - 2 - //0xd6 SUI D8 2 Z, S, P, CY, AC A <- A - data - //0xd7 RST 2 1 CALL $10 - //0xd8 RC 1 if CY, RET - //0xd9 - - //0xda JC adr 3 if CY, PC<-adr - //0xdb IN D8 2 special - //0xdc CC adr 3 if CY, CALL adr - //0xdd - - //0xde SBI D8 2 Z, S, P, CY, AC A <- A - data - CY - //0xdf RST 3 1 CALL $18 - //0xe0 RPO 1 if PO, RET - //0xe1 POP H 1 L <- (sp); H <- (sp+1); sp <- sp+2 - //0xe2 JPO adr 3 if PO, PC <- adr - //0xe3 XTHL 1 L <-> (SP); H <-> (SP+1) - //0xe4 CPO adr 3 if PO, CALL adr - //0xe5 PUSH H 1 (sp-2)<-L; (sp-1)<-H; sp <- sp - 2 - //0xe6 ANI D8 2 Z, S, P, CY, AC A <- A & data - //0xe7 RST 4 1 CALL $20 - //0xe8 RPE 1 if PE, RET - //0xe9 PCHL 1 PC.hi <- H; PC.lo <- L - //0xea JPE adr 3 if PE, PC <- adr - //0xeb XCHG 1 H <-> D; L <-> E - //0xec CPE adr 3 if PE, CALL adr - //0xed - - //0xee XRI D8 2 Z, S, P, CY, AC A <- A ^ data - //0xef RST 5 1 CALL $28 - //0xf0 RP 1 if P, RET - //0xf1 POP PSW 1 flags <- (sp); A <- (sp+1); sp <- sp+2 - //0xf2 JP adr 3 if P=1 PC <- adr - //0xf3 DI 1 special - //0xf4 CP adr 3 if P, PC <- adr - //0xf5 PUSH PSW 1 (sp-2)<-flags; (sp-1)<-A; sp <- sp - 2 - //0xf6 ORI D8 2 Z, S, P, CY, AC A <- A | data - //0xf7 RST 6 1 CALL $30 - //0xf8 RM 1 if M, RET - //0xf9 SPHL 1 SP=HL - //0xfa JM adr 3 if M, PC <- adr - //0xfb EI 1 special - //0xfc CM adr 3 if M, CALL adr - //0xfd - - //0xfe CPI D8 2 Z, S, P, CY, AC A - data - //0xff RST 7 1 CALL $38 + assertEquals(0xC6, code.get(221) & 0xFF); // ADI + assertEquals(0xF0, code.get(222) & 0xFF); + assertEquals(0xC7, code.get(223) & 0xFF); // RST 0 + assertEquals(0xC8, code.get(224) & 0xFF); // RZ + assertEquals(0xC9, code.get(225) & 0xFF); // RET + assertEquals(0xCA, code.get(226) & 0xFF); // JZ + assertEquals(0x34, code.get(227) & 0xFF); + assertEquals(0x12, code.get(228) & 0xFF); + assertEquals(0xCC, code.get(229) & 0xFF); // CZ + assertEquals(0x34, code.get(230) & 0xFF); + assertEquals(0x12, code.get(231) & 0xFF); + assertEquals(0xCD, code.get(232) & 0xFF); // CALL + assertEquals(0x34, code.get(233) & 0xFF); + assertEquals(0x12, code.get(234) & 0xFF); + assertEquals(0xCE, code.get(235) & 0xFF); // ACI + assertEquals(0xF0, code.get(236) & 0xFF); + assertEquals(0xCF, code.get(237) & 0xFF); // RST 1 + assertEquals(0xD0, code.get(238) & 0xFF); // RNC + assertEquals(0xD1, code.get(239) & 0xFF); // POP D + assertEquals(0xD2, code.get(240) & 0xFF); // JNC + assertEquals(0x34, code.get(241) & 0xFF); + assertEquals(0x12, code.get(242) & 0xFF); + assertEquals(0xD3, code.get(243) & 0xFF); // OUT + assertEquals(0xF0, code.get(244) & 0xFF); + assertEquals(0xD4, code.get(245) & 0xFF); // CNC + assertEquals(0x34, code.get(246) & 0xFF); + assertEquals(0x12, code.get(247) & 0xFF); + assertEquals(0xD5, code.get(248) & 0xFF); // PUSH D + assertEquals(0xD6, code.get(249) & 0xFF); // SUI + assertEquals(0xF0, code.get(250) & 0xFF); + assertEquals(0xD7, code.get(251) & 0xFF); // RST 2 + assertEquals(0xD8, code.get(252) & 0xFF); // RC + assertEquals(0xDA, code.get(253) & 0xFF); // JC + assertEquals(0x34, code.get(254) & 0xFF); + assertEquals(0x12, code.get(255) & 0xFF); + assertEquals(0xDB, code.get(256) & 0xFF); // IN + assertEquals(0xF0, code.get(257) & 0xFF); + assertEquals(0xDC, code.get(258) & 0xFF); // CC + assertEquals(0x34, code.get(259) & 0xFF); + assertEquals(0x12, code.get(260) & 0xFF); + assertEquals(0xDE, code.get(261) & 0xFF); // SBI + assertEquals(0xF0, code.get(262) & 0xFF); + assertEquals(0xDF, code.get(263) & 0xFF); // RST 3 + assertEquals(0xE0, code.get(264) & 0xFF); // RPO + assertEquals(0xE1, code.get(265) & 0xFF); // POP H + assertEquals(0xE2, code.get(266) & 0xFF); // JPO + assertEquals(0x34, code.get(267) & 0xFF); + assertEquals(0x12, code.get(268) & 0xFF); + assertEquals(0xE3, code.get(269) & 0xFF); // XTHL + assertEquals(0xE4, code.get(270) & 0xFF); // CPO + assertEquals(0x34, code.get(271) & 0xFF); + assertEquals(0x12, code.get(272) & 0xFF); + assertEquals(0xE5, code.get(273) & 0xFF); // PUSH H + assertEquals(0xE6, code.get(274) & 0xFF); // ANI + assertEquals(0xF0, code.get(275) & 0xFF); + assertEquals(0xE7, code.get(276) & 0xFF); // RST + assertEquals(0xE8, code.get(277) & 0xFF); // RPE + assertEquals(0xE9, code.get(278) & 0xFF); // PCHL + assertEquals(0xEA, code.get(279) & 0xFF); // JPE + assertEquals(0x34, code.get(280) & 0xFF); + assertEquals(0x12, code.get(281) & 0xFF); + assertEquals(0xEB, code.get(282) & 0xFF); // XCHG + assertEquals(0xEC, code.get(283) & 0xFF); // CPE + assertEquals(0x34, code.get(284) & 0xFF); + assertEquals(0x12, code.get(285) & 0xFF); + assertEquals(0xEE, code.get(286) & 0xFF); // XRI + assertEquals(0xF0, code.get(287) & 0xFF); + assertEquals(0xEF, code.get(288) & 0xFF); // RST + assertEquals(0xF0, code.get(289) & 0xFF); // RP + assertEquals(0xF1, code.get(290) & 0xFF); // POP PSW + assertEquals(0xF2, code.get(291) & 0xFF); // JP + assertEquals(0x00, code.get(292) & 0xFF); + assertEquals(0x02, code.get(293) & 0xFF); + assertEquals(0xF3, code.get(294) & 0xFF); // DI + assertEquals(0xF4, code.get(295) & 0xFF); // CP + assertEquals(0x00, code.get(296) & 0xFF); + assertEquals(0x02, code.get(297) & 0xFF); + assertEquals(0xF5, code.get(298) & 0xFF); // PUSH PSW + assertEquals(0xF6, code.get(299) & 0xFF); // ORI + assertEquals(0xF0, code.get(300) & 0xFF); + assertEquals(0xF7, code.get(301) & 0xFF); // RST 6 + assertEquals(0xF8, code.get(302) & 0xFF); // RM + assertEquals(0xF9, code.get(303) & 0xFF); // SPHL + assertEquals(0xFA, code.get(304) & 0xFF); // JM + assertEquals(0x00, code.get(305) & 0xFF); + assertEquals(0x02, code.get(306) & 0xFF); + assertEquals(0xFB, code.get(307) & 0xFF); // EI + assertEquals(0xFC, code.get(308) & 0xFF); // CM + assertEquals(0x00, code.get(309) & 0xFF); + assertEquals(0x02, code.get(310) & 0xFF); + assertEquals(0xFE, code.get(311) & 0xFF); // CPI + assertEquals(0xF0, code.get(312) & 0xFF); + assertEquals(0xFF, code.get(313) & 0xFF); // RST 7 } - } From b7c0bd6d214c8a83fdc23c449488a4c166c3a37e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 25 Jan 2022 14:32:42 +0100 Subject: [PATCH 082/314] [#201] 8080-cpu + z80-cpu: byte memory --- .../plugins/cpu/intel8080/ContextImpl.java | 8 +- .../plugins/cpu/intel8080/EmulatorEngine.java | 671 ++++++++++-------- .../cpu/intel8080/InitializerFor8080.java | 4 +- .../cpu/intel8080/api/DefaultInitializer.java | 10 +- .../cpu/intel8080/api/ExtendedContext.java | 2 +- .../cpu/intel8080/InstructionsTest.java | 4 +- .../plugins/cpu/intel8080/TransferTest.java | 151 ++-- .../cpu/intel8080/suite/CpuRunnerImpl.java | 6 +- .../cpu/intel8080/suite/CpuVerifierImpl.java | 27 +- plugins/cpu/brainduck-cpu/build.gradle | 4 +- .../cpu/brainduck-cpu/src/main/edigen/cpu.eds | 2 + .../cpu/brainduck/BrainCPUContext.java | 2 +- .../cpu/brainduck/BrainCPUContextImpl.java | 14 +- .../plugins/cpu/brainduck/EmulatorEngine.java | 32 +- .../plugins/cpu/brainduck/Profiler.java | 2 +- .../cpu/brainduck/gui/MemoryTableModel.java | 2 +- .../cpu/brainduck/gui/StatusPanel.java | 5 +- .../plugins/cpu/brainduck/CpuImplTest.java | 10 +- .../plugins/cpu/brainduck/DeviceStub.java | 18 +- .../cpu/brainduck/EmulatorEngineTest.java | 24 +- .../plugins/cpu/brainduck/MemoryStub.java | 6 +- plugins/cpu/z80-cpu/build.gradle | 4 +- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 2 + .../plugins/cpu/zilogZ80/ContextImpl.java | 16 +- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 130 ++-- .../cpu/zilogZ80/InitializerForZ80.java | 4 +- .../plugins/cpu/zilogZ80/FakeDevice.java | 14 +- .../plugins/cpu/zilogZ80/IOTest.java | 10 +- .../plugins/device/mits88dcdd/DeviceImpl.java | 2 +- .../device/mits88dcdd/drive/Drive.java | 40 +- .../device/mits88dcdd/ports/ControlPort.java | 10 +- .../device/mits88dcdd/ports/DataPort.java | 12 +- .../device/mits88dcdd/ports/StatusPort.java | 10 +- .../plugins/device/mits88sio/DeviceImpl.java | 6 +- .../plugins/device/mits88sio/Transmitter.java | 26 +- .../device/mits88sio/ports/CpuDataPort.java | 10 +- .../device/mits88sio/ports/CpuStatusPort.java | 10 +- .../mits88sio/ports/CpuDataPortTest.java | 6 +- .../mits88sio/ports/CpuStatusPortTest.java | 4 +- .../memory/brainduck/MemoryContextImpl.java | 35 +- .../brainduck/api/RawMemoryContext.java | 4 +- .../memory/brainduck/gui/MemoryGui.java | 4 +- .../brainduck/gui/MemoryTableModel.java | 6 +- .../memory/bytemem/MemoryContextImpl.java | 64 +- .../plugins/memory/bytemem/RangeTree.java | 9 + .../memory/bytemem/api/ByteMemoryContext.java | 3 +- .../bytemem/gui/model/MemoryTableModel.java | 6 +- settings.gradle | 10 +- 48 files changed, 774 insertions(+), 687 deletions(-) diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/ContextImpl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/ContextImpl.java index 354afe2b0..975673249 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/ContextImpl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/ContextImpl.java @@ -32,7 +32,7 @@ public class ContextImpl implements ExtendedContext { private final static Logger LOGGER = LoggerFactory.getLogger(ContextImpl.class); - private final ConcurrentMap> devices = new ConcurrentHashMap<>(); + private final ConcurrentMap> devices = new ConcurrentHashMap<>(); private volatile EmulatorEngine cpu; private volatile int clockFrequency = 2000; // kHz @@ -43,7 +43,7 @@ public void setCpu(EmulatorEngine cpu) { // device mapping = only one device can be attached to one port @Override - public boolean attachDevice(DeviceContext device, int port) { + public boolean attachDevice(DeviceContext device, int port) { if (devices.containsKey(port)) { LOGGER.debug("[port={}, device={}] Could not attach device to given port. The port is already taken by: {}", port, device, devices.get(port)); return false; @@ -74,8 +74,8 @@ public void clearDevices() { * @param data data to be written to the port. if parameter read is set to true, then data are ignored. * @return value from the port if read is true, otherwise 0 */ - public short fireIO(int port, boolean read, short data) throws IOException { - DeviceContext device = devices.get(port); + public byte fireIO(int port, boolean read, byte data) throws IOException { + DeviceContext device = devices.get(port); if (device != null) { if (read) { return device.readData(); diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java index 28c1c5792..8f760f6d1 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java @@ -57,8 +57,9 @@ public class EmulatorEngine implements CpuEngine { public int[] regs = new int[8]; public short flags = 2; // registers public volatile CPU.RunState currentRunState = CPU.RunState.STATE_STOPPED_NORMAL; + private byte lastOpcode; - private final MemoryContext memory; + private final MemoryContext memory; private final ContextImpl context; private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); @@ -66,7 +67,7 @@ public class EmulatorEngine implements CpuEngine { private volatile DispatchListener dispatchListener; - public EmulatorEngine(MemoryContext memory, ContextImpl context) { + public EmulatorEngine(MemoryContext memory, ContextImpl context) { this.memory = memory; this.context = context; } @@ -165,7 +166,7 @@ public void interrupt(short b1, short b2, short b3) { /* Get an 8080 register and return it */ private int getreg(int reg) { if (reg == 6) { - return memory.read((regs[REG_H] << 8) | regs[REG_L]); + return readByte((regs[REG_H] << 8) | regs[REG_L]); } return regs[reg]; } @@ -173,7 +174,7 @@ private int getreg(int reg) { /* Put a value into an 8080 register from memory */ private void putreg(int reg, int val) { if (reg == 6) { - memory.write((regs[REG_H] << 8) | regs[REG_L], (short) (val & 0xFF)); + memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) (val & 0xFF)); } else { regs[reg] = val & 0xFF; } @@ -194,6 +195,11 @@ private int getpair(int reg) { return SP; } int index = reg * 2; + + System.out.println("REG: " + index); + System.out.println("REG: " + regs[index]); + System.out.println("REG: " + regs[index + 1]); + return regs[index] << 8 | regs[index + 1]; } @@ -257,133 +263,277 @@ private void auxCarry(int before, int sumWith) { } } + private int readByte(int address) { + return memory.read(address) & 0xFF; + } + private int readWord(int address) { - Short[] read = memory.read(address, 2); - return (read[1] << 8) | read[0]; + Byte[] read = memory.read(address, 2); + return ((read[1] << 8) | (read[0] & 0xFF)) & 0xFFFF; } private void writeWord(int address, int value) { - memory.write(address, new Short[]{(short) (value & 0xFF), (short) ((value >>> 8) & 0xFF)}, 2); + memory.write(address, new Byte[]{(byte) (value & 0xFF), (byte) ((value >>> 8) & 0xFF)}, 2); } private static final Method[] DISPATCH_TABLE = new Method[256]; static { try { - DISPATCH_TABLE[0] = EmulatorEngine.class.getDeclaredMethod("O0_NOP", short.class); - DISPATCH_TABLE[6] = EmulatorEngine.class.getDeclaredMethod("MC7_O6_MVI", short.class); - DISPATCH_TABLE[7] = EmulatorEngine.class.getDeclaredMethod("O7_RLC", short.class); - DISPATCH_TABLE[14] = EmulatorEngine.class.getDeclaredMethod("MC7_O6_MVI", short.class); - DISPATCH_TABLE[15] = EmulatorEngine.class.getDeclaredMethod("O15_RRC", short.class); - DISPATCH_TABLE[22] = EmulatorEngine.class.getDeclaredMethod("MC7_O6_MVI", short.class); - DISPATCH_TABLE[23] = EmulatorEngine.class.getDeclaredMethod("O23_RAL", short.class); - DISPATCH_TABLE[30] = EmulatorEngine.class.getDeclaredMethod("MC7_O6_MVI", short.class); - DISPATCH_TABLE[31] = EmulatorEngine.class.getDeclaredMethod("O31_RAR", short.class); - DISPATCH_TABLE[34] = EmulatorEngine.class.getDeclaredMethod("O34_SHLD", short.class); - DISPATCH_TABLE[38] = EmulatorEngine.class.getDeclaredMethod("MC7_O6_MVI", short.class); - DISPATCH_TABLE[39] = EmulatorEngine.class.getDeclaredMethod("O39_DAA", short.class); - DISPATCH_TABLE[42] = EmulatorEngine.class.getDeclaredMethod("O42_LHLD", short.class); - DISPATCH_TABLE[46] = EmulatorEngine.class.getDeclaredMethod("MC7_O6_MVI", short.class); - DISPATCH_TABLE[47] = EmulatorEngine.class.getDeclaredMethod("O47_CMA", short.class); - DISPATCH_TABLE[50] = EmulatorEngine.class.getDeclaredMethod("O50_STA", short.class); - DISPATCH_TABLE[54] = EmulatorEngine.class.getDeclaredMethod("MC7_O6_MVI", short.class); - DISPATCH_TABLE[55] = EmulatorEngine.class.getDeclaredMethod("O55_STC", short.class); - DISPATCH_TABLE[58] = EmulatorEngine.class.getDeclaredMethod("O58_LDA", short.class); - DISPATCH_TABLE[62] = EmulatorEngine.class.getDeclaredMethod("MC7_O6_MVI", short.class); - DISPATCH_TABLE[63] = EmulatorEngine.class.getDeclaredMethod("O63_CMC", short.class); - DISPATCH_TABLE[64] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[65] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[66] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[67] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[68] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[69] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[70] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[71] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[72] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[73] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[74] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[75] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[76] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[77] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[78] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[79] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[80] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[81] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[82] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[83] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[84] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[85] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[86] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[87] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[88] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[89] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[90] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[91] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[92] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[93] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[94] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[95] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[96] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[97] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[98] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[99] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[100] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[101] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[102] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[103] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[104] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[105] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[106] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[107] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[108] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[109] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[110] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[111] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[112] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[113] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[114] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[115] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[116] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[117] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[118] = EmulatorEngine.class.getDeclaredMethod("O118_HLT", short.class); - DISPATCH_TABLE[119] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[120] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[121] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[122] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[123] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[124] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[125] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[126] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[127] = EmulatorEngine.class.getDeclaredMethod("MC0_O40_MOV", short.class); - DISPATCH_TABLE[195] = EmulatorEngine.class.getDeclaredMethod("O195_JMP", short.class); - DISPATCH_TABLE[198] = EmulatorEngine.class.getDeclaredMethod("O198_ADI", short.class); - DISPATCH_TABLE[201] = EmulatorEngine.class.getDeclaredMethod("O201_RET", short.class); - DISPATCH_TABLE[205] = EmulatorEngine.class.getDeclaredMethod("O205_CALL", short.class); - DISPATCH_TABLE[206] = EmulatorEngine.class.getDeclaredMethod("O206_ACI", short.class); - DISPATCH_TABLE[211] = EmulatorEngine.class.getDeclaredMethod("O211_OUT", short.class); - DISPATCH_TABLE[214] = EmulatorEngine.class.getDeclaredMethod("O214_SUI", short.class); - DISPATCH_TABLE[219] = EmulatorEngine.class.getDeclaredMethod("O219_IN", short.class); - DISPATCH_TABLE[222] = EmulatorEngine.class.getDeclaredMethod("O222_SBI", short.class); - DISPATCH_TABLE[227] = EmulatorEngine.class.getDeclaredMethod("O227_XTHL", short.class); - DISPATCH_TABLE[230] = EmulatorEngine.class.getDeclaredMethod("O230_ANI", short.class); - DISPATCH_TABLE[233] = EmulatorEngine.class.getDeclaredMethod("O233_PCHL", short.class); - DISPATCH_TABLE[235] = EmulatorEngine.class.getDeclaredMethod("O235_XCHG", short.class); - DISPATCH_TABLE[238] = EmulatorEngine.class.getDeclaredMethod("O238_XRI", short.class); - DISPATCH_TABLE[243] = EmulatorEngine.class.getDeclaredMethod("O243_DI", short.class); - DISPATCH_TABLE[246] = EmulatorEngine.class.getDeclaredMethod("O246_ORI", short.class); - DISPATCH_TABLE[249] = EmulatorEngine.class.getDeclaredMethod("O249_SPHL", short.class); - DISPATCH_TABLE[251] = EmulatorEngine.class.getDeclaredMethod("O251_EI", short.class); - DISPATCH_TABLE[254] = EmulatorEngine.class.getDeclaredMethod("O254_CPI", short.class); + DISPATCH_TABLE[0x00] = EmulatorEngine.class.getDeclaredMethod("I_NOP"); + DISPATCH_TABLE[0x01] = EmulatorEngine.class.getDeclaredMethod("I_LXI"); + DISPATCH_TABLE[0x02] = EmulatorEngine.class.getDeclaredMethod("I_STAX"); + DISPATCH_TABLE[0x03] = EmulatorEngine.class.getDeclaredMethod("I_INX"); + DISPATCH_TABLE[0x04] = EmulatorEngine.class.getDeclaredMethod("I_INR"); + DISPATCH_TABLE[0x05] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); + DISPATCH_TABLE[0x06] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); + DISPATCH_TABLE[0x07] = EmulatorEngine.class.getDeclaredMethod("I_RLC"); + DISPATCH_TABLE[0x09] = EmulatorEngine.class.getDeclaredMethod("I_DAD"); + DISPATCH_TABLE[0x0A] = EmulatorEngine.class.getDeclaredMethod("I_LDAX"); + DISPATCH_TABLE[0x0B] = EmulatorEngine.class.getDeclaredMethod("I_DCX"); + DISPATCH_TABLE[0x0C] = EmulatorEngine.class.getDeclaredMethod("I_INR"); + DISPATCH_TABLE[0x0D] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); + DISPATCH_TABLE[0x0E] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); + DISPATCH_TABLE[0x0F] = EmulatorEngine.class.getDeclaredMethod("I_RRC"); + DISPATCH_TABLE[0x11] = EmulatorEngine.class.getDeclaredMethod("I_LXI"); + DISPATCH_TABLE[0x12] = EmulatorEngine.class.getDeclaredMethod("I_STAX"); + DISPATCH_TABLE[0x13] = EmulatorEngine.class.getDeclaredMethod("I_INX"); + DISPATCH_TABLE[0x14] = EmulatorEngine.class.getDeclaredMethod("I_INR"); + DISPATCH_TABLE[0x15] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); + DISPATCH_TABLE[0x16] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); + DISPATCH_TABLE[0x17] = EmulatorEngine.class.getDeclaredMethod("I_RAL"); + DISPATCH_TABLE[0x19] = EmulatorEngine.class.getDeclaredMethod("I_DAD"); + DISPATCH_TABLE[0x1A] = EmulatorEngine.class.getDeclaredMethod("I_LDAX"); + DISPATCH_TABLE[0x1B] = EmulatorEngine.class.getDeclaredMethod("I_DCX"); + DISPATCH_TABLE[0x1C] = EmulatorEngine.class.getDeclaredMethod("I_INR"); + DISPATCH_TABLE[0x1D] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); + DISPATCH_TABLE[0x1E] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); + DISPATCH_TABLE[0x1F] = EmulatorEngine.class.getDeclaredMethod("I_RAR"); + DISPATCH_TABLE[0x21] = EmulatorEngine.class.getDeclaredMethod("I_LXI"); + DISPATCH_TABLE[0x22] = EmulatorEngine.class.getDeclaredMethod("I_SHLD"); + DISPATCH_TABLE[0x23] = EmulatorEngine.class.getDeclaredMethod("I_INX"); + DISPATCH_TABLE[0x24] = EmulatorEngine.class.getDeclaredMethod("I_INR"); + DISPATCH_TABLE[0x25] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); + DISPATCH_TABLE[0x26] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); + DISPATCH_TABLE[0x27] = EmulatorEngine.class.getDeclaredMethod("I_DAA"); + DISPATCH_TABLE[0x29] = EmulatorEngine.class.getDeclaredMethod("I_DAD"); + DISPATCH_TABLE[0x2A] = EmulatorEngine.class.getDeclaredMethod("I_LHLD"); + DISPATCH_TABLE[0x2B] = EmulatorEngine.class.getDeclaredMethod("I_DCX"); + DISPATCH_TABLE[0x2C] = EmulatorEngine.class.getDeclaredMethod("I_INR"); + DISPATCH_TABLE[0x2D] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); + DISPATCH_TABLE[0x2E] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); + DISPATCH_TABLE[0x2F] = EmulatorEngine.class.getDeclaredMethod("I_CMA"); + DISPATCH_TABLE[0x31] = EmulatorEngine.class.getDeclaredMethod("I_LXI"); + DISPATCH_TABLE[0x32] = EmulatorEngine.class.getDeclaredMethod("I_STA"); + DISPATCH_TABLE[0x33] = EmulatorEngine.class.getDeclaredMethod("I_INX"); + DISPATCH_TABLE[0x34] = EmulatorEngine.class.getDeclaredMethod("I_INR"); + DISPATCH_TABLE[0x35] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); + DISPATCH_TABLE[0x36] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); + DISPATCH_TABLE[0x37] = EmulatorEngine.class.getDeclaredMethod("I_STC"); + DISPATCH_TABLE[0x39] = EmulatorEngine.class.getDeclaredMethod("I_DAD"); + DISPATCH_TABLE[0x3A] = EmulatorEngine.class.getDeclaredMethod("I_LDA"); + DISPATCH_TABLE[0x3B] = EmulatorEngine.class.getDeclaredMethod("I_DCX"); + DISPATCH_TABLE[0x3C] = EmulatorEngine.class.getDeclaredMethod("I_INR"); + DISPATCH_TABLE[0x3D] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); + DISPATCH_TABLE[0x3E] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); + DISPATCH_TABLE[0x3F] = EmulatorEngine.class.getDeclaredMethod("I_CMC"); + DISPATCH_TABLE[0x40] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x41] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x42] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x43] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x44] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x45] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x46] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x47] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x48] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x49] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x4A] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x4B] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x4C] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x4D] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x4E] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x4F] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x50] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x51] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x52] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x53] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x54] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x55] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x56] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x57] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x58] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x59] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x5A] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x5B] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x5C] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x5D] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x5E] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x5F] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x60] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x61] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x62] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x63] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x64] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x65] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x66] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x67] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x68] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x69] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x6A] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x6B] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x6C] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x6D] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x6E] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x6F] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x70] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x71] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x72] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x73] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x74] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x75] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x76] = EmulatorEngine.class.getDeclaredMethod("I_HLT"); + DISPATCH_TABLE[0x77] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x78] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x79] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x7A] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x7B] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x7C] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x7D] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x7E] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x7F] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); + DISPATCH_TABLE[0x80] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); + DISPATCH_TABLE[0x81] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); + DISPATCH_TABLE[0x82] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); + DISPATCH_TABLE[0x83] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); + DISPATCH_TABLE[0x84] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); + DISPATCH_TABLE[0x85] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); + DISPATCH_TABLE[0x86] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); + DISPATCH_TABLE[0x87] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); + DISPATCH_TABLE[0x88] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); + DISPATCH_TABLE[0x89] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); + DISPATCH_TABLE[0x8A] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); + DISPATCH_TABLE[0x8B] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); + DISPATCH_TABLE[0x8C] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); + DISPATCH_TABLE[0x8D] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); + DISPATCH_TABLE[0x8E] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); + DISPATCH_TABLE[0x8F] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); + DISPATCH_TABLE[0x90] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); + DISPATCH_TABLE[0x91] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); + DISPATCH_TABLE[0x92] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); + DISPATCH_TABLE[0x93] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); + DISPATCH_TABLE[0x94] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); + DISPATCH_TABLE[0x95] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); + DISPATCH_TABLE[0x96] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); + DISPATCH_TABLE[0x97] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); + DISPATCH_TABLE[0x98] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); + DISPATCH_TABLE[0x99] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); + DISPATCH_TABLE[0x9A] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); + DISPATCH_TABLE[0x9B] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); + DISPATCH_TABLE[0x9C] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); + DISPATCH_TABLE[0x9D] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); + DISPATCH_TABLE[0x9E] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); + DISPATCH_TABLE[0x9F] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); + DISPATCH_TABLE[0xA0] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); + DISPATCH_TABLE[0xA1] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); + DISPATCH_TABLE[0xA2] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); + DISPATCH_TABLE[0xA3] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); + DISPATCH_TABLE[0xA4] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); + DISPATCH_TABLE[0xA5] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); + DISPATCH_TABLE[0xA6] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); + DISPATCH_TABLE[0xA7] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); + DISPATCH_TABLE[0xA8] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); + DISPATCH_TABLE[0xA9] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); + DISPATCH_TABLE[0xAA] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); + DISPATCH_TABLE[0xAB] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); + DISPATCH_TABLE[0xAC] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); + DISPATCH_TABLE[0xAD] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); + DISPATCH_TABLE[0xAE] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); + DISPATCH_TABLE[0xAF] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); + DISPATCH_TABLE[0xB0] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); + DISPATCH_TABLE[0xB1] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); + DISPATCH_TABLE[0xB2] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); + DISPATCH_TABLE[0xB3] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); + DISPATCH_TABLE[0xB4] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); + DISPATCH_TABLE[0xB5] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); + DISPATCH_TABLE[0xB6] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); + DISPATCH_TABLE[0xB7] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); + DISPATCH_TABLE[0xB8] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); + DISPATCH_TABLE[0xB9] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); + DISPATCH_TABLE[0xBA] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); + DISPATCH_TABLE[0xBB] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); + DISPATCH_TABLE[0xBC] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); + DISPATCH_TABLE[0xBD] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); + DISPATCH_TABLE[0xBE] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); + DISPATCH_TABLE[0xBF] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); + DISPATCH_TABLE[0xC0] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RNZ + DISPATCH_TABLE[0xC1] = EmulatorEngine.class.getDeclaredMethod("I_POP"); + DISPATCH_TABLE[0xC2] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JNZ + DISPATCH_TABLE[0xC3] = EmulatorEngine.class.getDeclaredMethod("I_JMP"); + DISPATCH_TABLE[0xC4] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CNZ + DISPATCH_TABLE[0xC5] = EmulatorEngine.class.getDeclaredMethod("I_PUSH"); + DISPATCH_TABLE[0xC6] = EmulatorEngine.class.getDeclaredMethod("I_ADI"); + DISPATCH_TABLE[0xC7] = EmulatorEngine.class.getDeclaredMethod("I_RST"); + DISPATCH_TABLE[0xC8] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RZ + DISPATCH_TABLE[0xC9] = EmulatorEngine.class.getDeclaredMethod("I_RET"); + DISPATCH_TABLE[0xCA] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JZ + DISPATCH_TABLE[0xCC] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CZ + DISPATCH_TABLE[0xCD] = EmulatorEngine.class.getDeclaredMethod("I_CALL"); + DISPATCH_TABLE[0xCE] = EmulatorEngine.class.getDeclaredMethod("I_ACI"); + DISPATCH_TABLE[0xCF] = EmulatorEngine.class.getDeclaredMethod("I_RST"); + DISPATCH_TABLE[0xD0] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RNC + DISPATCH_TABLE[0xD1] = EmulatorEngine.class.getDeclaredMethod("I_POP"); + DISPATCH_TABLE[0xD2] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JNC + DISPATCH_TABLE[0xD3] = EmulatorEngine.class.getDeclaredMethod("I_OUT"); + DISPATCH_TABLE[0xD4] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CNC + DISPATCH_TABLE[0xD5] = EmulatorEngine.class.getDeclaredMethod("I_PUSH"); + DISPATCH_TABLE[0xD6] = EmulatorEngine.class.getDeclaredMethod("I_SUI"); + DISPATCH_TABLE[0xD7] = EmulatorEngine.class.getDeclaredMethod("I_RST"); + DISPATCH_TABLE[0xD8] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RC + DISPATCH_TABLE[0xDA] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JC + DISPATCH_TABLE[0xDB] = EmulatorEngine.class.getDeclaredMethod("I_IN"); + DISPATCH_TABLE[0xDC] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CC + DISPATCH_TABLE[0xDE] = EmulatorEngine.class.getDeclaredMethod("I_SBI"); + DISPATCH_TABLE[0xDF] = EmulatorEngine.class.getDeclaredMethod("I_RST"); + DISPATCH_TABLE[0xE0] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RPO + DISPATCH_TABLE[0xE1] = EmulatorEngine.class.getDeclaredMethod("I_POP"); + DISPATCH_TABLE[0xE2] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JPO + DISPATCH_TABLE[0xE3] = EmulatorEngine.class.getDeclaredMethod("I_XTHL"); + DISPATCH_TABLE[0xE4] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CPO + DISPATCH_TABLE[0xE5] = EmulatorEngine.class.getDeclaredMethod("I_PUSH"); + DISPATCH_TABLE[0xE6] = EmulatorEngine.class.getDeclaredMethod("I_ANI"); + DISPATCH_TABLE[0xE7] = EmulatorEngine.class.getDeclaredMethod("I_RST"); + DISPATCH_TABLE[0xE8] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RPE + DISPATCH_TABLE[0xE9] = EmulatorEngine.class.getDeclaredMethod("I_PCHL"); + DISPATCH_TABLE[0xEA] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JPE + DISPATCH_TABLE[0xEB] = EmulatorEngine.class.getDeclaredMethod("I_XCHG"); + DISPATCH_TABLE[0xEC] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CPE + DISPATCH_TABLE[0xEE] = EmulatorEngine.class.getDeclaredMethod("I_XRI"); + DISPATCH_TABLE[0xEF] = EmulatorEngine.class.getDeclaredMethod("I_RST"); + DISPATCH_TABLE[0xF0] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RP + DISPATCH_TABLE[0xF1] = EmulatorEngine.class.getDeclaredMethod("I_POP"); + DISPATCH_TABLE[0xF2] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JP + DISPATCH_TABLE[0xF3] = EmulatorEngine.class.getDeclaredMethod("I_DI"); + DISPATCH_TABLE[0xF4] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CP + DISPATCH_TABLE[0xF5] = EmulatorEngine.class.getDeclaredMethod("I_PUSH"); + DISPATCH_TABLE[0xF6] = EmulatorEngine.class.getDeclaredMethod("I_ORI"); + DISPATCH_TABLE[0xF7] = EmulatorEngine.class.getDeclaredMethod("I_RST"); + DISPATCH_TABLE[0xF8] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RM + DISPATCH_TABLE[0xF9] = EmulatorEngine.class.getDeclaredMethod("I_SPHL"); + DISPATCH_TABLE[0xFA] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JM + DISPATCH_TABLE[0xFB] = EmulatorEngine.class.getDeclaredMethod("I_EI"); + DISPATCH_TABLE[0xFC] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CM + DISPATCH_TABLE[0xFE] = EmulatorEngine.class.getDeclaredMethod("I_CPI"); + DISPATCH_TABLE[0xFF] = EmulatorEngine.class.getDeclaredMethod("I_RST"); } catch (NoSuchMethodException e) { LOGGER.error("Could not set up dispatch table. The emulator won't work correctly", e); } } - private int O0_NOP(short OP) { + private int I_NOP() { return 4; } - private int O7_RLC(short OP) { + private int I_RLC() { int temp = (regs[REG_A] & 0x80) >>> 7; flags &= (~FLAG_C); @@ -393,17 +543,17 @@ private int O7_RLC(short OP) { return 4; } - private int O15_RRC(short OP) { + private int I_RRC() { int temp = regs[REG_A] & 0x01; flags &= (~FLAG_C); flags |= temp; - regs[REG_A] = (regs[REG_A] >>> 1) | (temp << 7); + regs[REG_A] = ((regs[REG_A] >>> 1) | (temp << 7)) & 0xFF; return 4; } - private int O23_RAL(short OP) { + private int I_RAL() { int temp = regs[REG_A] << 1; regs[REG_A] = temp & 0xFF; regs[REG_A] |= (flags & FLAG_C); @@ -413,7 +563,7 @@ private int O23_RAL(short OP) { return 4; } - private int O31_RAR(short OP) { + private int I_RAR() { int newCarry = regs[REG_A] & 1; regs[REG_A] = regs[REG_A] >>> 1; if ((flags & FLAG_C) == FLAG_C) { @@ -425,14 +575,14 @@ private int O31_RAR(short OP) { return 4; } - private int O34_SHLD(short OP) { + private int I_SHLD() { int DAR = readWord(PC); PC = (PC + 2) & 0xFFFF; - memory.write(DAR, new Short[]{(short) regs[REG_L], (short) regs[REG_H]}, 2); + memory.write(DAR, new Byte[]{(byte) regs[REG_L], (byte) regs[REG_H]}, 2); return 16; } - private int O39_DAA(short OP) { + private int I_DAA() { int temp = regs[REG_A]; boolean acFlag = (flags & FLAG_AC) == FLAG_AC; @@ -460,40 +610,40 @@ private int O39_DAA(short OP) { return 4; } - private int O42_LHLD(short OP) { + private int I_LHLD() { int DAR = readWord(PC); PC = (PC + 2) & 0xFFFF; - regs[REG_L] = memory.read(DAR); - regs[REG_H] = memory.read(DAR + 1); + regs[REG_L] = readByte(DAR); + regs[REG_H] = readByte(DAR + 1); return 16; } - private int O47_CMA(short OP) { + private int I_CMA() { regs[REG_A] = ~regs[REG_A]; regs[REG_A] &= 0xFF; return 4; } - private int O50_STA(short OP) { + private int I_STA() { int DAR = readWord(PC); PC = (PC + 2) & 0xFFFF; - memory.write(DAR, (short) regs[REG_A]); + memory.write(DAR, (byte) regs[REG_A]); return 13; } - private int O55_STC(short OP) { + private int I_STC() { flags |= FLAG_C; return 4; } - private int O58_LDA(short OP) { + private int I_LDA() { int DAR = readWord(PC); PC = (PC + 2) & 0xFFFF; - regs[REG_A] = memory.read(DAR); + regs[REG_A] = readByte(DAR); return 13; } - private int O63_CMC(short OP) { + private int I_CMC() { if ((flags & FLAG_C) != 0) { flags &= (~FLAG_C); } else { @@ -502,45 +652,45 @@ private int O63_CMC(short OP) { return 4; } - private int O118_HLT(short OP) { + private int I_HLT() { currentRunState = CPU.RunState.STATE_STOPPED_NORMAL; return 7; } - private int O195_JMP(short OP) { + private int I_JMP() { PC = readWord(PC); return 10; } - private int O198_ADI(short OP) { + private int I_ADI() { int DAR = regs[REG_A]; - int diff = memory.read(PC); + int diff = readByte(PC); PC = (PC + 1) & 0xFFFF; regs[REG_A] += diff; flags = EmulatorTables.SIGN_ZERO_PARITY_CARRY_TABLE[regs[REG_A] & 0x1FF]; auxCarry(DAR, diff); - regs[REG_A] = regs[REG_A] & 0xFF; + regs[REG_A] &= 0xFF; return 7; } - private int O201_RET(short OP) { + private int I_RET() { PC = readWord(SP); SP = (SP + 2) & 0xFFFF; return 10; } - private int O205_CALL(short OP) { + private int I_CALL() { SP = (SP - 2) & 0xFFFF; writeWord(SP, (PC + 2) & 0xFFFF); PC = readWord(PC); return 17; } - private int O206_ACI(short OP) { + private int I_ACI() { int X = regs[REG_A]; - int diff = memory.read(PC); + int diff = readByte(PC); PC = (PC + 1) & 0xFFFF; if ((flags & FLAG_C) == FLAG_C) { diff++; @@ -550,40 +700,40 @@ private int O206_ACI(short OP) { flags = EmulatorTables.SIGN_ZERO_PARITY_CARRY_TABLE[regs[REG_A] & 0x1FF]; auxCarry(X, diff); - regs[REG_A] = regs[REG_A] & 0xFF; + regs[REG_A] &= 0xFF; return 7; } - private int O211_OUT(short OP) throws IOException { - int DAR = memory.read(PC); + private int I_OUT() throws IOException { + int DAR = readByte(PC); PC = (PC + 1) & 0xFFFF; - context.fireIO(DAR, false, (short) regs[REG_A]); + context.fireIO(DAR, false, (byte) regs[REG_A]); return 10; } - private int O214_SUI(short OP) { + private int I_SUI() { int DAR = regs[REG_A]; - int diff = memory.read(PC); + int diff = readByte(PC); PC = (PC + 1) & 0xFFFF; regs[REG_A] -= diff; flags = EmulatorTables.SIGN_ZERO_PARITY_CARRY_TABLE[regs[REG_A] & 0x1FF]; auxCarry(DAR, (-diff) & 0xFF); - regs[REG_A] = regs[REG_A] & 0xFF; + regs[REG_A] &= 0xFF; return 7; } - private int O219_IN(short OP) throws IOException { - int DAR = memory.read(PC); + private int I_IN() throws IOException { + int DAR = readByte(PC); PC = (PC + 1) & 0xFFFF; - regs[REG_A] = context.fireIO(DAR, true, (short) 0); + regs[REG_A] = context.fireIO(DAR, true, (byte) 0) & 0xFF; return 10; } - private int O222_SBI(short OP) { + private int I_SBI() { int DAR = regs[REG_A]; - int diff = memory.read(PC); + int diff = readByte(PC); PC = (PC + 1) & 0xFFFF; if ((flags & FLAG_C) != 0) { diff++; @@ -593,11 +743,11 @@ private int O222_SBI(short OP) { flags = EmulatorTables.SIGN_ZERO_PARITY_CARRY_TABLE[regs[REG_A] & 0x1FF]; auxCarry(DAR, (-diff) & 0xFF); - regs[REG_A] = regs[REG_A] & 0xFF; + regs[REG_A] &= 0xFF; return 7; } - private int O227_XTHL(short OP) { + private int I_XTHL() { int DAR = readWord(SP); writeWord(SP, (regs[REG_H] << 8) | regs[REG_L]); regs[REG_H] = (DAR >>> 8) & 0xFF; @@ -605,19 +755,19 @@ private int O227_XTHL(short OP) { return 18; } - private int O230_ANI(short OP) { - regs[REG_A] &= (memory.read(PC) & 0xFF); + private int I_ANI() { + regs[REG_A] &= readByte(PC); PC = (PC + 1) & 0xFFFF; flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 7; } - private int O233_PCHL(short OP) { + private int I_PCHL() { PC = (regs[REG_H] << 8) | regs[REG_L]; return 5; } - private int O235_XCHG(short OP) { + private int I_XCHG() { int x = regs[REG_H]; int y = regs[REG_L]; regs[REG_H] = regs[REG_D]; @@ -627,39 +777,39 @@ private int O235_XCHG(short OP) { return 4; } - private int O238_XRI(short OP) { - regs[REG_A] ^= (memory.read(PC) & 0xFF); + private int I_XRI() { + regs[REG_A] ^= readByte(PC); PC = (PC + 1) & 0xFFFF; flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 7; } - private int O243_DI(short OP) { + private int I_DI() { INTE = false; return 4; } - private int O246_ORI(short OP) { - regs[REG_A] |= (memory.read(PC) & 0xFF); + private int I_ORI() { + regs[REG_A] |= readByte(PC); PC = (PC + 1) & 0xFFFF; flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 7; } - private int O249_SPHL(short OP) { + private int I_SPHL() { SP = ((regs[REG_H] << 8) | regs[REG_L]) & 0xFFFF; return 5; } - private int O251_EI(short OP) { + private int I_EI() { INTE = true; return 4; } - private int O254_CPI(short OP) { + private int I_CPI() { int X = regs[REG_A]; int DAR = regs[REG_A] & 0xFF; - int diff = memory.read(PC); + int diff = readByte(PC); PC = (PC + 1) & 0xFFFF; DAR -= diff; @@ -669,55 +819,57 @@ private int O254_CPI(short OP) { return 7; } - private int MC0_O40_MOV(short OP) { - putreg((OP >>> 3) & 0x07, getreg(OP & 0x07)); - if (((OP & 0x07) == 6) || (((OP >>> 3) & 0x07) == 6)) { + private int I_MOV() { + putreg((lastOpcode >>> 3) & 0x07, getreg(lastOpcode & 0x07)); + if (((lastOpcode & 0x07) == 6) || (((lastOpcode >>> 3) & 0x07) == 6)) { return 7; } else { return 5; } } - private int MC7_O6_MVI(short OP) { - putreg((OP >>> 3) & 0x07, memory.read(PC)); + private int I_MVI() { + putreg((lastOpcode >>> 3) & 0x07, readByte(PC)); PC = (PC + 1) & 0xFFFF; - if (((OP >>> 3) & 0x07) == 6) { + if (((lastOpcode >>> 3) & 0x07) == 6) { return 10; } else { return 7; } } - private int MCF_01_LXI(short OP) { - putpair((OP >>> 4) & 0x03, readWord(PC)); + private int I_LXI() { + putpair((lastOpcode >>> 4) & 0x03, readWord(PC)); PC = (PC + 2) & 0xFFFF; return 10; } - private int MEF_0A_LDAX(short OP) { - putreg(7, memory.read(getpair((OP >>> 4) & 0x03))); + private int I_LDAX() { + int address = getpair((lastOpcode >>> 4) & 0x03); + System.out.println(address); + putreg(7, readByte(address)); return 7; } - private int MEF_02_STAX(short OP) { - memory.write(getpair((OP >>> 4) & 0x03), (short) getreg(7)); + private int I_STAX() { + memory.write(getpair((lastOpcode >>> 4) & 0x03), (byte) getreg(7)); return 7; } - private int MF8_B8_CMP(short OP) { + private int I_CMP() { int X = regs[REG_A]; int DAR = X & 0xFF; - int diff = getreg(OP & 0x07); + int diff = getreg(lastOpcode & 0x07); DAR -= diff; flags = EmulatorTables.SIGN_ZERO_PARITY_CARRY_TABLE[DAR & 0x1FF]; auxCarry(X, (-diff) & 0xFF); - return ((OP & 0x07) == 6) ? 7 : 4; + return ((lastOpcode & 0x07) == 6) ? 7 : 4; } - private int MC7_C2_JMP(short OP) { - int index = (OP >>> 3) & 0x07; + private int I_JMP_COND() { + int index = (lastOpcode >>> 3) & 0x07; if ((flags & CONDITION[index]) == CONDITION_VALUES[index]) { PC = readWord(PC); } else { @@ -726,8 +878,8 @@ private int MC7_C2_JMP(short OP) { return 10; } - private int MC7_C4_CALL(short OP) { - int index = (OP >>> 3) & 0x07; + private int I_CALL_COND() { + int index = (lastOpcode >>> 3) & 0x07; if ((flags & CONDITION[index]) == CONDITION_VALUES[index]) { int DAR = readWord(PC); SP = (SP - 2) & 0xFFFF; @@ -740,8 +892,8 @@ private int MC7_C4_CALL(short OP) { } } - private int MC7_C0_RET(short OP) { - int index = (OP >>> 3) & 0x07; + private int I_RET_COND() { + int index = (lastOpcode >>> 3) & 0x07; if ((flags & CONDITION[index]) == CONDITION_VALUES[index]) { PC = readWord(SP); SP = (SP + 2) & 0xFFFF; @@ -749,42 +901,42 @@ private int MC7_C0_RET(short OP) { return 10; } - private int MC7_C7_RST(short OP) { + private int I_RST() { SP = (SP - 2) & 0xFFFF; writeWord(SP, PC); - PC = OP & 0x38; + PC = lastOpcode & 0x38; return 11; } - private int MCF_C5_PUSH(short OP) { - int DAR = getpush((OP >>> 4) & 0x03); + private int I_PUSH() { + int DAR = getpush((lastOpcode >>> 4) & 0x03); SP = (SP - 2) & 0xFFFF; writeWord(SP, DAR); return 11; } - private int MCF_C1_POP(short OP) { + private int I_POP() { int DAR = readWord(SP); SP = (SP + 2) & 0xFFFF; - putpush((OP >>> 4) & 0x03, DAR); + putpush((lastOpcode >>> 4) & 0x03, DAR); return 10; } - private int MF8_80_ADD(short OP) { + private int I_ADD() { int X = regs[REG_A]; - int diff = getreg(OP & 0x07); + int diff = getreg(lastOpcode & 0x07); regs[REG_A] += diff; flags = EmulatorTables.SIGN_ZERO_PARITY_CARRY_TABLE[regs[REG_A] & 0x1FF]; auxCarry(X, diff); - regs[REG_A] = regs[REG_A] & 0xFF; - return ((OP & 0x07) == 6) ? 7 : 4; + regs[REG_A] &= 0xFF; + return ((lastOpcode & 0x07) == 6) ? 7 : 4; } - private int MF8_88_ADC(short OP) { + private int I_ADC() { int X = regs[REG_A]; - int diff = getreg(OP & 0x07); + int diff = getreg(lastOpcode & 0x07); if ((flags & FLAG_C) == FLAG_C) { diff++; } @@ -793,25 +945,25 @@ private int MF8_88_ADC(short OP) { flags = EmulatorTables.SIGN_ZERO_PARITY_CARRY_TABLE[regs[REG_A] & 0x1FF]; auxCarry(X, diff); - regs[REG_A] = regs[REG_A] & 0xFF; - return ((OP & 0x07) == 6) ? 7 : 4; + regs[REG_A] &= 0xFF; + return ((lastOpcode & 0x07) == 6) ? 7 : 4; } - private int MF8_90_SUB(short OP) { + private int I_SUB() { int X = regs[REG_A]; - int diff = getreg(OP & 0x07); + int diff = getreg(lastOpcode & 0x07); regs[REG_A] -= diff; flags = EmulatorTables.SIGN_ZERO_PARITY_CARRY_TABLE[regs[REG_A] & 0x1FF]; auxCarry(X, (-diff) & 0xFF); - regs[REG_A] = regs[REG_A] & 0xFF; - return ((OP & 0x07) == 6) ? 7 : 4; + regs[REG_A] &= 0xFF; + return ((lastOpcode & 0x07) == 6) ? 7 : 4; } - private int MF8_98_SBB(short OP) { + private int I_SBB() { int X = regs[REG_A]; - int diff = getreg(OP & 0x07); + int diff = getreg(lastOpcode & 0x07); if ((flags & FLAG_C) != 0) { diff++; } @@ -820,38 +972,38 @@ private int MF8_98_SBB(short OP) { flags = EmulatorTables.SIGN_ZERO_PARITY_CARRY_TABLE[regs[REG_A] & 0x1FF]; auxCarry(X, (-diff) & 0xFF); - regs[REG_A] = regs[REG_A] & 0xFF; - return ((OP & 0x07) == 6) ? 7 : 4; + regs[REG_A] &= 0xFF; + return ((lastOpcode & 0x07) == 6) ? 7 : 4; } - private int MC7_04_INR(short OP) { - int DAR = (getreg((OP >>> 3) & 0x07) + 1) & 0xFF; + private int I_INR() { + int DAR = (getreg((lastOpcode >>> 3) & 0x07) + 1) & 0xFF; flags = (short) (EmulatorTables.INC_TABLE[DAR] | (flags & FLAG_C)); - putreg((OP >>> 3) & 0x07, DAR); + putreg((lastOpcode >>> 3) & 0x07, DAR); return 5; } - private int MC7_05_DCR(short OP) { - int DAR = (getreg((OP >>> 3) & 0x07) - 1) & 0xFF; + private int I_DCR() { + int DAR = (getreg((lastOpcode >>> 3) & 0x07) - 1) & 0xFF; flags = (short) (EmulatorTables.DEC_TABLE[DAR] | (flags & FLAG_C)); - putreg((OP >>> 3) & 0x07, DAR); + putreg((lastOpcode >>> 3) & 0x07, DAR); return 5; } - private int MCF_03_INX(short OP) { - int DAR = (getpair((OP >>> 4) & 0x03) + 1) & 0xFFFF; - putpair((OP >>> 4) & 0x03, DAR); + private int I_INX() { + int DAR = (getpair((lastOpcode >>> 4) & 0x03) + 1) & 0xFFFF; + putpair((lastOpcode >>> 4) & 0x03, DAR); return 5; } - private int MCF_0B_DCX(short OP) { - int DAR = (getpair((OP >>> 4) & 0x03) - 1) & 0xFFFF; - putpair((OP >>> 4) & 0x03, DAR); + private int I_DCX() { + int DAR = (getpair((lastOpcode >>> 4) & 0x03) - 1) & 0xFFFF; + putpair((lastOpcode >>> 4) & 0x03, DAR); return 5; } - private int MCF_09_DAD(short OP) { - int DAR = getpair((OP >>> 4) & 0x03); + private int I_DAD() { + int DAR = getpair((lastOpcode >>> 4) & 0x03); DAR += getpair(2); if ((DAR & 0x10000) != 0) { flags |= FLAG_C; @@ -863,27 +1015,25 @@ private int MCF_09_DAD(short OP) { return 10; } - private int MF8_A0_ANA(short OP) { - regs[REG_A] &= getreg(OP & 0x07); + private int I_ANA() { + regs[REG_A] &= getreg(lastOpcode & 0x07); flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 4; } - private int MF8_A8_XRA(short OP) { - regs[REG_A] ^= getreg(OP & 0x07); + private int I_XRA() { + regs[REG_A] ^= getreg(lastOpcode & 0x07); flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 4; } - private int MF8_B0_ORA(short OP) { - regs[REG_A] |= getreg(OP & 0x07); + private int I_ORA() { + regs[REG_A] |= getreg(lastOpcode & 0x07); flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 4; } private int dispatch() throws InvocationTargetException, IllegalAccessException { - short OP; - DispatchListener tmpListener = dispatchListener; if (tmpListener != null) { tmpListener.beforeDispatch(); @@ -900,7 +1050,7 @@ private int dispatch() throws InvocationTargetException, IllegalAccessException writeWord(SP, PC); PC = b1 & 0x38; return 11; - } else if (b1 == 0315) { /* CALL */ + } else if (b1 == 0xCD) { /* CALL */ SP = (SP - 2) & 0xFFFF; writeWord(SP, (PC + 2) & 0xFFFF); PC = ((b3 & 0xFF) << 8) | (b2 & 0xFF); @@ -910,9 +1060,9 @@ private int dispatch() throws InvocationTargetException, IllegalAccessException isINT = false; } - OP = 0; + lastOpcode = 0; try { - OP = memory.read(PC); + lastOpcode = (byte)readByte(PC); } catch (NullPointerException e) { LOGGER.error("NPE; PC=" + Integer.toHexString(PC), e); currentRunState = CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; @@ -921,65 +1071,16 @@ private int dispatch() throws InvocationTargetException, IllegalAccessException PC = (PC + 1) & 0xFFFF; try { - /* Handle below all operations which refer to registers or register pairs. - After that, a large switch statement takes care of all other opcodes */ - if ((OP & 0xCF) == 0x01) { /* LXI */ - return MCF_01_LXI(OP); - } else if ((OP & 0xEF) == 0x0A) { /* LDAX */ - return MEF_0A_LDAX(OP); - } else if ((OP & 0xEF) == 0x02) { /* STAX */ - return MEF_02_STAX(OP); - } else if ((OP & 0xF8) == 0xB8) { /* CMP */ - return MF8_B8_CMP(OP); - } else if ((OP & 0xC7) == 0xC2) { /* JMP */ - return MC7_C2_JMP(OP); - } else if ((OP & 0xC7) == 0xC4) { /* CALL */ - return MC7_C4_CALL(OP); - } else if ((OP & 0xC7) == 0xC0) { /* RET */ - return MC7_C0_RET(OP); - } else if ((OP & 0xC7) == 0xC7) { /* RST */ - return MC7_C7_RST(OP); - } else if ((OP & 0xCF) == 0xC5) { /* PUSH */ - return MCF_C5_PUSH(OP); - } else if ((OP & 0xCF) == 0xC1) { /*POP */ - return MCF_C1_POP(OP); - } else if ((OP & 0xF8) == 0x80) { /* ADD */ - return MF8_80_ADD(OP); - } else if ((OP & 0xF8) == 0x88) { /* ADC */ - return MF8_88_ADC(OP); - } else if ((OP & 0xF8) == 0x90) { /* SUB */ - return MF8_90_SUB(OP); - } else if ((OP & 0xF8) == 0x98) { /* SBB */ - return MF8_98_SBB(OP); - } else if ((OP & 0xC7) == 0x04) { /* INR */ - return MC7_04_INR(OP); - } else if ((OP & 0xC7) == 0x05) { /* DCR */ - return MC7_05_DCR(OP); - } else if ((OP & 0xCF) == 0x03) { /* INX */ - return MCF_03_INX(OP); - } else if ((OP & 0xCF) == 0x0B) { /* DCX */ - return MCF_0B_DCX(OP); - } else if ((OP & 0xCF) == 0x09) { /* DAD */ - return MCF_09_DAD(OP); - } else if ((OP & 0xF8) == 0xA0) { /* ANA */ - return MF8_A0_ANA(OP); - } else if ((OP & 0xF8) == 0xA8) { /* XRA */ - return MF8_A8_XRA(OP); - } else if ((OP & 0xF8) == 0xB0) { /* ORA */ - return MF8_B0_ORA(OP); - } - /* Dispatch Instruction */ - Method instr = DISPATCH_TABLE[OP]; + Method instr = DISPATCH_TABLE[lastOpcode & 0xFF]; if (instr == null) { currentRunState = CPU.RunState.STATE_STOPPED_BAD_INSTR; return 0; } - return (Integer) instr.invoke(this, OP); + return (Integer) instr.invoke(this); } finally { if (tmpListener != null) { tmpListener.afterDispatch(); } } } - } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InitializerFor8080.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InitializerFor8080.java index 030c28f9d..986b48444 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InitializerFor8080.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InitializerFor8080.java @@ -43,7 +43,7 @@ public InitializerFor8080(Plugin plugin, long pluginId, ContextPool contextPool, } @Override - protected EmulatorEngine createEmulatorEngine(MemoryContext memory) { + protected EmulatorEngine createEmulatorEngine(MemoryContext memory) { return new EmulatorEngine(memory, context); } @@ -54,7 +54,7 @@ protected DispatchListener createInstructionPrinter(Disassembler disassembler, E } @Override - protected Disassembler createDisassembler(MemoryContext memory) { + protected Disassembler createDisassembler(MemoryContext memory) { return new DisassemblerImpl(memory, new DecoderImpl(memory)); } } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/DefaultInitializer.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/DefaultInitializer.java index 2144cb2ac..34e53d33a 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/DefaultInitializer.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/DefaultInitializer.java @@ -57,10 +57,10 @@ public DefaultInitializer(Plugin plugin, long pluginId, ContextPool contextPool, @SuppressWarnings("unchecked") public final void initialize() throws PluginInitializationException { try { - MemoryContext memory = contextPool.getMemoryContext(pluginId, MemoryContext.class); - if (memory.getDataType() != Short.class) { + MemoryContext memory = contextPool.getMemoryContext(pluginId, MemoryContext.class); + if (memory.getDataType() != Byte.class) { throw new InvalidContextException( - "Unexpected memory cell type. Expected Short but was: " + memory.getDataType() + "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() ); } @@ -98,10 +98,10 @@ public boolean shouldDumpInstructions() { return dumpInstructions; } - protected abstract Engine createEmulatorEngine(MemoryContext memory); + protected abstract Engine createEmulatorEngine(MemoryContext memory); protected abstract DispatchListener createInstructionPrinter(Disassembler disassembler, Engine engine, boolean useCache, PrintStream writer); - protected abstract Disassembler createDisassembler(MemoryContext memory); + protected abstract Disassembler createDisassembler(MemoryContext memory); } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/ExtendedContext.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/ExtendedContext.java index b5b530349..ce5a1d556 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/ExtendedContext.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/ExtendedContext.java @@ -35,7 +35,7 @@ public interface ExtendedContext extends CPUContext { * @param port CPU port where the device should be attached * @return true on success, false otherwise */ - boolean attachDevice(DeviceContext device, int port); + boolean attachDevice(DeviceContext device, int port); /** * Detach a device from the CPU. diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/InstructionsTest.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/InstructionsTest.java index fe6dbb79f..f1418c7d3 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/InstructionsTest.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/InstructionsTest.java @@ -19,7 +19,7 @@ package net.emustudio.plugins.cpu.intel8080; import net.emustudio.cpu.testsuite.Generator; -import net.emustudio.cpu.testsuite.memory.ShortMemoryStub; +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.emulib.plugins.PluginInitializationException; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; @@ -49,7 +49,7 @@ public class InstructionsTest { @SuppressWarnings("unchecked") @Before public void setUp() throws PluginInitializationException { - ShortMemoryStub memoryStub = new ShortMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); + ByteMemoryStub memoryStub = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); ContextPool contextPool = createNiceMock(ContextPool.class); expect(contextPool.getMemoryContext(0, MemoryContext.class)) diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/TransferTest.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/TransferTest.java index 14b3888d2..d3412bd22 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/TransferTest.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/TransferTest.java @@ -24,6 +24,8 @@ import net.emustudio.plugins.cpu.intel8080.suite.IntegerTestBuilder; import org.junit.Test; +import static net.emustudio.plugins.cpu.intel8080.EmulatorEngine.*; + public class TransferTest extends InstructionsTest { @Test @@ -32,13 +34,14 @@ public void testMVI() { .clearOtherVerifiersAfterRun(); Generator.forSome8bitUnary( - test.verifyRegister(EmulatorEngine.REG_A, context -> context.first & 0xFF).runWithFirstOperand(0x3E), - test.verifyRegister(EmulatorEngine.REG_B).runWithFirstOperand(0x06), - test.verifyRegister(EmulatorEngine.REG_C).runWithFirstOperand(0x0E), - test.verifyRegister(EmulatorEngine.REG_D).runWithFirstOperand(0x16), - test.verifyRegister(EmulatorEngine.REG_E).runWithFirstOperand(0x1E), - test.verifyRegister(EmulatorEngine.REG_H).runWithFirstOperand(0x26), - test.verifyRegister(EmulatorEngine.REG_L).runWithFirstOperand(0x2E), + test.verifyRegister(REG_A, context -> context.first & 0xFF) + .runWithFirstOperand(0x3E), + test.verifyRegister(REG_B).runWithFirstOperand(0x06), + test.verifyRegister(REG_C).runWithFirstOperand(0x0E), + test.verifyRegister(REG_D).runWithFirstOperand(0x16), + test.verifyRegister(REG_E).runWithFirstOperand(0x1E), + test.verifyRegister(REG_H).runWithFirstOperand(0x26), + test.verifyRegister(REG_L).runWithFirstOperand(0x2E), test.setPair(REG_PAIR_HL, 0x20) .verifyByte(0x20, context -> context.first & 0xFF) .runWithFirstOperand(0x36) @@ -48,17 +51,17 @@ public void testMVI() { @Test public void testMOV_A() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(EmulatorEngine.REG_A, context -> context.first & 0xFF) + .verifyRegister(REG_A, context -> context.first & 0xFF) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(EmulatorEngine.REG_A).run(0x7F), - test.firstIsRegister(EmulatorEngine.REG_B).run(0x78), - test.firstIsRegister(EmulatorEngine.REG_C).run(0x79), - test.firstIsRegister(EmulatorEngine.REG_D).run(0x7A), - test.firstIsRegister(EmulatorEngine.REG_E).run(0x7B), - test.firstIsRegister(EmulatorEngine.REG_H).run(0x7C), - test.firstIsRegister(EmulatorEngine.REG_L).run(0x7D), + test.firstIsRegister(REG_A).run(0x7F), + test.firstIsRegister(REG_B).run(0x78), + test.firstIsRegister(REG_C).run(0x79), + test.firstIsRegister(REG_D).run(0x7A), + test.firstIsRegister(REG_E).run(0x7B), + test.firstIsRegister(REG_H).run(0x7C), + test.firstIsRegister(REG_L).run(0x7D), test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x7E) ); } @@ -66,17 +69,17 @@ public void testMOV_A() { @Test public void testMOV_B() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(EmulatorEngine.REG_B, context -> context.first & 0xFF) + .verifyRegister(REG_B, context -> context.first & 0xFF) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(EmulatorEngine.REG_A).run(0x47), - test.firstIsRegister(EmulatorEngine.REG_B).run(0x40), - test.firstIsRegister(EmulatorEngine.REG_C).run(0x41), - test.firstIsRegister(EmulatorEngine.REG_D).run(0x42), - test.firstIsRegister(EmulatorEngine.REG_E).run(0x43), - test.firstIsRegister(EmulatorEngine.REG_H).run(0x44), - test.firstIsRegister(EmulatorEngine.REG_L).run(0x45), + test.firstIsRegister(REG_A).run(0x47), + test.firstIsRegister(REG_B).run(0x40), + test.firstIsRegister(REG_C).run(0x41), + test.firstIsRegister(REG_D).run(0x42), + test.firstIsRegister(REG_E).run(0x43), + test.firstIsRegister(REG_H).run(0x44), + test.firstIsRegister(REG_L).run(0x45), test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x46) ); } @@ -84,17 +87,17 @@ public void testMOV_B() { @Test public void testMOV_C() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(EmulatorEngine.REG_C, context -> context.first & 0xFF) + .verifyRegister(REG_C, context -> context.first & 0xFF) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(EmulatorEngine.REG_A).run(0x4F), - test.firstIsRegister(EmulatorEngine.REG_B).run(0x48), - test.firstIsRegister(EmulatorEngine.REG_C).run(0x49), - test.firstIsRegister(EmulatorEngine.REG_D).run(0x4A), - test.firstIsRegister(EmulatorEngine.REG_E).run(0x4B), - test.firstIsRegister(EmulatorEngine.REG_H).run(0x4C), - test.firstIsRegister(EmulatorEngine.REG_L).run(0x4D), + test.firstIsRegister(REG_A).run(0x4F), + test.firstIsRegister(REG_B).run(0x48), + test.firstIsRegister(REG_C).run(0x49), + test.firstIsRegister(REG_D).run(0x4A), + test.firstIsRegister(REG_E).run(0x4B), + test.firstIsRegister(REG_H).run(0x4C), + test.firstIsRegister(REG_L).run(0x4D), test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x4E) ); } @@ -102,17 +105,17 @@ public void testMOV_C() { @Test public void testMOV_D() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(EmulatorEngine.REG_D, context -> context.first & 0xFF) + .verifyRegister(REG_D, context -> context.first & 0xFF) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(EmulatorEngine.REG_A).run(0x57), - test.firstIsRegister(EmulatorEngine.REG_B).run(0x50), - test.firstIsRegister(EmulatorEngine.REG_C).run(0x51), - test.firstIsRegister(EmulatorEngine.REG_D).run(0x52), - test.firstIsRegister(EmulatorEngine.REG_E).run(0x53), - test.firstIsRegister(EmulatorEngine.REG_H).run(0x54), - test.firstIsRegister(EmulatorEngine.REG_L).run(0x55), + test.firstIsRegister(REG_A).run(0x57), + test.firstIsRegister(REG_B).run(0x50), + test.firstIsRegister(REG_C).run(0x51), + test.firstIsRegister(REG_D).run(0x52), + test.firstIsRegister(REG_E).run(0x53), + test.firstIsRegister(REG_H).run(0x54), + test.firstIsRegister(REG_L).run(0x55), test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x56) ); } @@ -120,17 +123,17 @@ public void testMOV_D() { @Test public void testMOV_E() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(EmulatorEngine.REG_E, context -> context.first & 0xFF) + .verifyRegister(REG_E, context -> context.first & 0xFF) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(EmulatorEngine.REG_A).run(0x5F), - test.firstIsRegister(EmulatorEngine.REG_B).run(0x58), - test.firstIsRegister(EmulatorEngine.REG_C).run(0x59), - test.firstIsRegister(EmulatorEngine.REG_D).run(0x5A), - test.firstIsRegister(EmulatorEngine.REG_E).run(0x5B), - test.firstIsRegister(EmulatorEngine.REG_H).run(0x5C), - test.firstIsRegister(EmulatorEngine.REG_L).run(0x5D), + test.firstIsRegister(REG_A).run(0x5F), + test.firstIsRegister(REG_B).run(0x58), + test.firstIsRegister(REG_C).run(0x59), + test.firstIsRegister(REG_D).run(0x5A), + test.firstIsRegister(REG_E).run(0x5B), + test.firstIsRegister(REG_H).run(0x5C), + test.firstIsRegister(REG_L).run(0x5D), test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x5E) ); } @@ -138,17 +141,17 @@ public void testMOV_E() { @Test public void testMOV_H() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(EmulatorEngine.REG_H, context -> context.first & 0xFF) + .verifyRegister(REG_H, context -> context.first & 0xFF) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(EmulatorEngine.REG_A).run(0x67), - test.firstIsRegister(EmulatorEngine.REG_B).run(0x60), - test.firstIsRegister(EmulatorEngine.REG_C).run(0x61), - test.firstIsRegister(EmulatorEngine.REG_D).run(0x62), - test.firstIsRegister(EmulatorEngine.REG_E).run(0x63), - test.firstIsRegister(EmulatorEngine.REG_H).run(0x64), - test.firstIsRegister(EmulatorEngine.REG_L).run(0x65), + test.firstIsRegister(REG_A).run(0x67), + test.firstIsRegister(REG_B).run(0x60), + test.firstIsRegister(REG_C).run(0x61), + test.firstIsRegister(REG_D).run(0x62), + test.firstIsRegister(REG_E).run(0x63), + test.firstIsRegister(REG_H).run(0x64), + test.firstIsRegister(REG_L).run(0x65), test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x66) ); } @@ -156,17 +159,17 @@ public void testMOV_H() { @Test public void testMOV_L() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(EmulatorEngine.REG_L, context -> context.first & 0xFF) + .verifyRegister(REG_L, context -> context.first & 0xFF) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(EmulatorEngine.REG_A).run(0x6F), - test.firstIsRegister(EmulatorEngine.REG_B).run(0x68), - test.firstIsRegister(EmulatorEngine.REG_C).run(0x69), - test.firstIsRegister(EmulatorEngine.REG_D).run(0x6A), - test.firstIsRegister(EmulatorEngine.REG_E).run(0x6B), - test.firstIsRegister(EmulatorEngine.REG_H).run(0x6C), - test.firstIsRegister(EmulatorEngine.REG_L).run(0x6D), + test.firstIsRegister(REG_A).run(0x6F), + test.firstIsRegister(REG_B).run(0x68), + test.firstIsRegister(REG_C).run(0x69), + test.firstIsRegister(REG_D).run(0x6A), + test.firstIsRegister(REG_E).run(0x6B), + test.firstIsRegister(REG_H).run(0x6C), + test.firstIsRegister(REG_L).run(0x6D), test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x6E) ); } @@ -180,14 +183,14 @@ public void testMOV_M_r() { .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.setPair(REG_PAIR_HL, address).firstIsRegister(EmulatorEngine.REG_A).run(0x77), - test.setPair(REG_PAIR_HL, address).firstIsRegister(EmulatorEngine.REG_B).run(0x70), - test.setPair(REG_PAIR_HL, address).firstIsRegister(EmulatorEngine.REG_C).run(0x71), - test.setPair(REG_PAIR_HL, address).firstIsRegister(EmulatorEngine.REG_D).run(0x72), - test.setPair(REG_PAIR_HL, address).firstIsRegister(EmulatorEngine.REG_E).run(0x73) + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_A).run(0x77), + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_B).run(0x70), + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_C).run(0x71), + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_D).run(0x72), + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_E).run(0x73) ); - test.setPair(REG_PAIR_HL, address).firstIsRegister(EmulatorEngine.REG_H).run(0x74).accept((byte) 0, (byte) 0); - test.setPair(REG_PAIR_HL, address).firstIsRegister(EmulatorEngine.REG_L).run(0x75).accept((byte) address, (byte) 0); + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_H).run(0x74).accept((byte) 0, (byte) 0); + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_L).run(0x75).accept((byte) address, (byte) 0); } @Test @@ -195,7 +198,7 @@ public void testLDAX() { final int value = 0x25; IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(EmulatorEngine.REG_A, context -> value) + .verifyRegister(REG_A, context -> value) .firstIsMemoryAddressByte(value) .keepCurrentInjectorsAfterRun(); @@ -211,7 +214,7 @@ public void testSTAX() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .verifyByte(context -> context.first, context -> value) - .setRegister(EmulatorEngine.REG_A, value) + .setRegister(REG_A, value) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitUnary(3, @@ -225,7 +228,7 @@ public void testLDA() { byte value = -120; IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(EmulatorEngine.REG_A, context -> value & 0xFF) + .verifyRegister(REG_A, context -> value & 0xFF) .firstIsMemoryAddressByte(value); Generator.forSome16bitUnary(3, @@ -239,7 +242,7 @@ public void testSTA() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .verifyByte(context -> context.first, context -> value & 0xFF) - .setRegister(EmulatorEngine.REG_A, value); + .setRegister(REG_A, value); Generator.forSome16bitUnary(3, test.runWithFirstOperand(0x32) diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuRunnerImpl.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuRunnerImpl.java index 9631b22b4..eca282276 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuRunnerImpl.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuRunnerImpl.java @@ -19,7 +19,7 @@ package net.emustudio.plugins.cpu.intel8080.suite; import net.emustudio.cpu.testsuite.CpuRunner; -import net.emustudio.cpu.testsuite.memory.ShortMemoryStub; +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.plugins.cpu.intel8080.CpuImpl; import java.util.ArrayList; @@ -29,7 +29,7 @@ public class CpuRunnerImpl extends CpuRunner { - public CpuRunnerImpl(CpuImpl cpu, ShortMemoryStub memoryStub) { + public CpuRunnerImpl(CpuImpl cpu, ByteMemoryStub memoryStub) { super(cpu, memoryStub); } @@ -68,7 +68,7 @@ public void setRegisterPairPSW(int registerPair, int value) { if (registerPair < 3) { setRegisterPair(registerPair, value); } else if (registerPair == 3) { - cpu.getEngine().regs[REG_A] = (value >>> 8) & 0xFF; + cpu.getEngine().regs[REG_A] = (byte)((value >>> 8) & 0xFF); cpu.getEngine().flags = (short) (value & 0xD7 | 2); } else { throw new IllegalArgumentException("Expected value between <0,3> !"); diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuVerifierImpl.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuVerifierImpl.java index 689229ae2..d9fbb6c63 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuVerifierImpl.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuVerifierImpl.java @@ -19,7 +19,7 @@ package net.emustudio.plugins.cpu.intel8080.suite; import net.emustudio.cpu.testsuite.CpuVerifier; -import net.emustudio.cpu.testsuite.memory.ShortMemoryStub; +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.plugins.cpu.intel8080.CpuImpl; import net.emustudio.plugins.cpu.intel8080.EmulatorEngine; @@ -30,16 +30,17 @@ public class CpuVerifierImpl extends CpuVerifier { private final CpuImpl cpu; - public CpuVerifierImpl(CpuImpl cpu, ShortMemoryStub memoryStub) { + public CpuVerifierImpl(CpuImpl cpu, ByteMemoryStub memoryStub) { super(memoryStub); this.cpu = Objects.requireNonNull(cpu); } - public void checkRegister(int register, int value) { - value &= 0xFF; + public void checkRegister(int register, int expected) { + expected &= 0xFF; + int actual = cpu.getEngine().regs[register] & 0xFF; assertEquals( - String.format("Expected reg[%02x]=%02x, but was %02x", register, value, cpu.getEngine().regs[register]), - value, cpu.getEngine().regs[register] + String.format("Expected reg[%02x]=%02x, but was %02x", register, expected, actual), + expected, actual ); } @@ -121,19 +122,13 @@ public String intToFlags(int flags) { @Override public void checkFlags(int mask) { - assertTrue( - String.format("Expected flags=%s, but was %s", - intToFlags(mask), intToFlags(cpu.getEngine().flags)), - (cpu.getEngine().flags & mask) == mask - ); + assertEquals(String.format("Expected flags=%s, but was %s", + intToFlags(mask), intToFlags(cpu.getEngine().flags)), (cpu.getEngine().flags & mask), mask); } @Override public void checkNotFlags(int mask) { - assertTrue( - String.format("Expected NOT flags=%s, but was %s", - intToFlags(mask), intToFlags(cpu.getEngine().flags)), - (cpu.getEngine().flags & mask) == 0 - ); + assertEquals(String.format("Expected NOT flags=%s, but was %s", + intToFlags(mask), intToFlags(cpu.getEngine().flags)), 0, (cpu.getEngine().flags & mask)); } } diff --git a/plugins/cpu/brainduck-cpu/build.gradle b/plugins/cpu/brainduck-cpu/build.gradle index 2c960693f..a56d2ab9c 100644 --- a/plugins/cpu/brainduck-cpu/build.gradle +++ b/plugins/cpu/brainduck-cpu/build.gradle @@ -21,12 +21,12 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.2.0' + id 'net.emustudio.edigen-plugin' version '1.4.0' } repositories { + mavenLocal() mavenCentral() - jcenter() } dependencies { diff --git a/plugins/cpu/brainduck-cpu/src/main/edigen/cpu.eds b/plugins/cpu/brainduck-cpu/src/main/edigen/cpu.eds index 7fdd7c602..f2888c82b 100644 --- a/plugins/cpu/brainduck-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/brainduck-cpu/src/main/edigen/cpu.eds @@ -1,3 +1,5 @@ +root instruction; + instruction = "halt": 00000000 | "> (P++)": 00000001 | "< (P--)": 00000010 | diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContext.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContext.java index 5d422fba0..a0efa3aa1 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContext.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContext.java @@ -24,7 +24,7 @@ @PluginContext public interface BrainCPUContext extends CPUContext { - void attachDevice(DeviceContext device); + void attachDevice(DeviceContext device); void detachDevice(); } diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContextImpl.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContextImpl.java index 13a1a9731..d8edd5cd2 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContextImpl.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContextImpl.java @@ -25,14 +25,14 @@ class BrainCPUContextImpl implements BrainCPUContext { - private DeviceContext device; + private DeviceContext device; BrainCPUContextImpl() { device = null; } @Override - public void attachDevice(DeviceContext device) { + public void attachDevice(DeviceContext device) { this.device = Objects.requireNonNull(device); } @@ -46,8 +46,8 @@ public void detachDevice() { * * @param data value that will be written into the device */ - public void writeToDevice(short data) throws IOException { - DeviceContext tmp = device; + public void writeToDevice(byte data) throws IOException { + DeviceContext tmp = device; if (tmp == null) { return; } @@ -62,12 +62,12 @@ public void writeToDevice(short data) throws IOException { * * @return value from the device, or 0 if the device is null or there's anything */ - public short readFromDevice() throws IOException { - DeviceContext tmp = device; + public byte readFromDevice() throws IOException { + DeviceContext tmp = device; if (tmp == null) { return 0; } - Short value = tmp.readData(); + Byte value = tmp.readData(); return (value == null) ? 0 : value; } diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java index 16733040d..35b1f4b98 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java @@ -28,19 +28,19 @@ import java.util.Objects; public class EmulatorEngine { - final static short I_STOP = 0; // ; - final static short I_INC = 1; // > - final static short I_DEC = 2; // < - final static short I_INCV = 3; // + - final static short I_DECV = 4; // - - final static short I_PRINT = 5; // . - final static short I_READ = 6; // , - final static short I_LOOP_START = 7; // [ - final static short I_LOOP_END = 8; // ] - final static short I_COPY_AND_CLEAR = 0xA1; // any copyloop, including clear - final static short I_SCANLOOP = 0xA2; // [<] or [>] - - private final short[] rawMemory; + final static byte I_STOP = 0; // ; + final static byte I_INC = 1; // > + final static byte I_DEC = 2; // < + final static byte I_INCV = 3; // + + final static byte I_DECV = 4; // - + final static byte I_PRINT = 5; // . + final static byte I_READ = 6; // , + final static byte I_LOOP_START = 7; // [ + final static byte I_LOOP_END = 8; // ] + final static byte I_COPY_AND_CLEAR = (byte)0xA1; // any copyloop, including clear + final static byte I_SCANLOOP = (byte)0xA2; // [<] or [>] + + private final Byte[] rawMemory; private final BrainCPUContextImpl context; private final Deque loopPointers = new ArrayDeque<>(); private final Profiler profiler; @@ -106,10 +106,10 @@ CPU.RunState step(boolean optimize) throws IOException { } break; case I_INCV: /* + */ - rawMemory[P] = (short) ((rawMemory[P] + argument) & 0xFF); + rawMemory[P] = (byte) ((rawMemory[P] + argument) & 0xFF); break; case I_DECV: /* - */ - rawMemory[P] = (short) ((rawMemory[P] - argument) & 0xFF); + rawMemory[P] = (byte) ((rawMemory[P] - argument) & 0xFF); break; case I_PRINT: /* . */ while (argument > 0) { @@ -144,7 +144,7 @@ CPU.RunState step(boolean optimize) throws IOException { } else if (copyLoop.specialOP == I_READ) { rawMemory[P] = context.readFromDevice(); } else { - rawMemory[P + copyLoop.relativePosition] = (short) + rawMemory[P + copyLoop.relativePosition] = (byte) ((rawMemory[P] * copyLoop.factor + rawMemory[P + copyLoop.relativePosition]) & 0xFF); } } diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java index 362d5f79d..8bb80a0a9 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java @@ -33,7 +33,7 @@ public class Profiler { private final static Logger LOGGER = LoggerFactory.getLogger(Profiler.class); - private final short[] memory; + private final Byte[] memory; private final CachedOperation[] operationsCache; private final Integer[] loopEndsCache; diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/MemoryTableModel.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/MemoryTableModel.java index c63b4e689..ed75fac54 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/MemoryTableModel.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/MemoryTableModel.java @@ -23,7 +23,7 @@ import javax.swing.table.AbstractTableModel; public class MemoryTableModel extends AbstractTableModel { - private final short[] memory; + private final Byte[] memory; private volatile int P; MemoryTableModel(RawMemoryContext memory) { diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java index 24d9a5aec..4d1a84013 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java @@ -25,14 +25,13 @@ import javax.swing.*; import javax.swing.table.DefaultTableModel; -import java.awt.*; import static net.emustudio.plugins.cpu.brainduck.gui.Constants.MONOSPACED_PLAIN; public class StatusPanel extends JPanel { private final ColumnsRepainter columnsRepainter = new ColumnsRepainter(); private final MemoryTableModel tableModel; - private final short[] memory; + private final Byte[] memory; private final EmulatorEngine cpu; private class CPUStatusListener implements CPU.CPUListener { @@ -263,7 +262,7 @@ private void initComponents() { } ) { Class[] types = new Class[]{ - java.lang.Short.class, java.lang.Short.class, java.lang.Short.class, java.lang.Short.class, java.lang.Short.class + java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class }; public Class getColumnClass(int columnIndex) { diff --git a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java index bf63f339e..6068df620 100644 --- a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java +++ b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java @@ -146,7 +146,7 @@ public void testSimpleOutput() { assertTrue(ioDevice.wasInputRead()); - List output = ioDevice.getOutput(); + List output = ioDevice.getOutput(); assertEquals(3, output.size()); assertEquals(4, output.get(0).byteValue()); @@ -216,7 +216,7 @@ public void testAddition() { assertTrue(ioDevice.wasInputRead()); - List output = ioDevice.getOutput(); + List output = ioDevice.getOutput(); assertEquals(2, output.size()); assertEquals('8', output.get(0).byteValue()); assertEquals('\n', output.get(1).byteValue()); @@ -239,7 +239,7 @@ public void testMoreAddition() { assertTrue(ioDevice.wasInputRead()); - List output = ioDevice.getOutput(); + List output = ioDevice.getOutput(); assertEquals(2, output.size()); assertEquals(64, output.get(0).byteValue()); assertEquals('a', output.get(1).byteValue()); @@ -286,7 +286,7 @@ public void testDecrementZeroGives255() { emulate(program, null, null); assertEquals(memory.getDataStart(), cpu.getEngine().P); - assertEquals(255, memory.read(memory.getDataStart()).shortValue()); + assertEquals(255, memory.read(memory.getDataStart()) & 0xFF); } @Test(timeout = 3000) @@ -356,7 +356,7 @@ public void testSelfPrint() { assertTrue(ioDevice.wasInputRead()); - List output = ioDevice.getOutput(); + List output = ioDevice.getOutput(); assertEquals(3, output.size()); } diff --git a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/DeviceStub.java b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/DeviceStub.java index ec456cb8e..fe81fffd3 100644 --- a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/DeviceStub.java +++ b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/DeviceStub.java @@ -27,36 +27,36 @@ import java.util.concurrent.CopyOnWriteArrayList; @PluginContext -public class DeviceStub implements DeviceContext { - private final List output = new CopyOnWriteArrayList<>(); - private final Queue input = new ConcurrentLinkedQueue<>(); +public class DeviceStub implements DeviceContext { + private final List output = new CopyOnWriteArrayList<>(); + private final Queue input = new ConcurrentLinkedQueue<>(); public void setInput(byte[] input) { for (byte value : input) { - this.input.add((short) value); + this.input.add(value); } } @Override - public Short readData() { + public Byte readData() { return input.poll(); } @Override - public void writeData(Short data) { + public void writeData(Byte data) { output.add(data); } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } public boolean wasInputRead() { return input.isEmpty(); } - public List getOutput() { + public List getOutput() { return output; } } diff --git a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngineTest.java b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngineTest.java index 2f4c8a02b..dfaf7fb13 100644 --- a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngineTest.java +++ b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngineTest.java @@ -41,14 +41,14 @@ public void setUp() throws Exception { profiler = new Profiler(memory); context = createNiceMock(BrainCPUContextImpl.class); - context.writeToDevice(anyShort()); + context.writeToDevice(anyByte()); expectLastCall().anyTimes(); - expect(context.readFromDevice()).andReturn((short) 0).anyTimes(); + expect(context.readFromDevice()).andReturn((byte) 0).anyTimes(); } - private void resetProgram(short... operations) { + private void resetProgram(byte... operations) { int i = 0; - for (short op : operations) { + for (byte op : operations) { memory.write(i++, op); } engine = new EmulatorEngine(memory, context, profiler); @@ -79,7 +79,7 @@ public void testCopyLoop() throws Exception { } @Test - public void testCopyLoopWeird() throws Exception { + public void testCopyLoopWeird() { resetProgram( I_LOOP_START, I_DECV, @@ -125,10 +125,10 @@ public void testScanloop() throws Exception { assertNotNull(operation); assertEquals(I_SCANLOOP, operation.operation); - memory.write(6, (short) 5); - memory.write(7, (short) 5); - memory.write(8, (short) 5); - memory.write(9, (short) 5); + memory.write(6, (byte) 5); + memory.write(7, (byte) 5); + memory.write(8, (byte) 5); + memory.write(9, (byte) 5); engine.P = 6; engine.step(true); @@ -154,14 +154,14 @@ private void checkProfilerCopyLoop(int nextIP, int[] factors, int[] relPositions private void runAndCheckCopyLoop(int start, int valueP, int[] resultValues, int[] relPositions) throws IOException { engine.P = start; - memory.write(engine.P, (short) valueP); + memory.write(engine.P, (byte) valueP); engine.step(true); for (int i = 0; i < resultValues.length; i++) { assertEquals("Expected res[" + i + "]=" + resultValues[i] + " at " + (start + relPositions[i]), - resultValues[i], (int) memory.read(start + relPositions[i])); + resultValues[i], memory.read(start + relPositions[i]) & 0xFF); } - assertEquals(0, (int) memory.read(engine.P)); + assertEquals(0, memory.read(engine.P) & 0xFF); } } diff --git a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java index c366c5448..446d511e4 100644 --- a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java +++ b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java @@ -18,13 +18,13 @@ */ package net.emustudio.plugins.cpu.brainduck; -import net.emustudio.cpu.testsuite.memory.ShortMemoryStub; +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.runtime.helpers.NumberUtils; import net.emustudio.plugins.memory.brainduck.api.RawMemoryContext; @PluginContext -public class MemoryStub extends ShortMemoryStub implements RawMemoryContext { +public class MemoryStub extends ByteMemoryStub implements RawMemoryContext { private int afterProgram; MemoryStub() { @@ -49,7 +49,7 @@ void setData(byte[] data) { } @Override - public short[] getRawMemory() { + public Byte[] getRawMemory() { return memory; } diff --git a/plugins/cpu/z80-cpu/build.gradle b/plugins/cpu/z80-cpu/build.gradle index 53928c98d..9e9e9775e 100644 --- a/plugins/cpu/z80-cpu/build.gradle +++ b/plugins/cpu/z80-cpu/build.gradle @@ -21,12 +21,12 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.2.0' + id 'net.emustudio.edigen-plugin' version '1.4.0' } repositories { + mavenLocal() mavenCentral() - jcenter() } dependencies { diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index 47e15e6c7..50787702d 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -1,3 +1,5 @@ +root instruction; + instruction = "nop": 00000000 | "ex (SP),HL": 0xE3 | "ex DE,HL": 0xEB | "ld SP,HL": 0xF9 | "ei": 0xFB | "di": 0xF3 | "halt": 0x76 | "daa": 0x27 | "cpl": 0x2F | "scf": 0x37 | "ccf": 0x3F | "ret": 0xC9 | "rlca": 0x07 | "rrca": 0x0F | "rla": 0x17 | "rra": 0x1F | "jp (HL)": 0xE9 | "ret NZ": 0xC0 | "ret Z": 0xC8 | diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java index 456dc4f72..7c0cd74a1 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java @@ -28,11 +28,11 @@ import java.util.concurrent.ConcurrentMap; public final class ContextImpl implements ExtendedContext { - private final static int NO_DATA = 0xFF; + private final static byte NO_DATA = (byte)0xFF; public final static int DEFAULT_FREQUENCY_KHZ = 20000; private final static Logger LOGGER = LoggerFactory.getLogger(ContextImpl.class); - private final ConcurrentMap> devices = new ConcurrentHashMap<>(); + private final ConcurrentMap> devices = new ConcurrentHashMap<>(); private volatile EmulatorEngine cpu; private volatile int clockFrequency = DEFAULT_FREQUENCY_KHZ; @@ -43,7 +43,7 @@ public void setCpu(EmulatorEngine cpu) { // device mapping = only one device can be attached to one port @Override - public boolean attachDevice(DeviceContext device, int port) { + public boolean attachDevice(DeviceContext device, int port) { if (devices.containsKey(port)) { LOGGER.debug("[port={}, device={}] Could not attach device to given port. The port is already taken by: {}", port, device, devices.get(port)); return false; @@ -65,15 +65,15 @@ void clearDevices() { devices.clear(); } - void writeIO(int port, int val) throws IOException { - DeviceContext device = devices.get(port); + void writeIO(int port, byte val) throws IOException { + DeviceContext device = devices.get(port); if (device != null) { - device.writeData((short) val); + device.writeData(val); } } - short readIO(int port) throws IOException { - DeviceContext device = devices.get(port); + byte readIO(int port) throws IOException { + DeviceContext device = devices.get(port); if (device != null) { return device.readData(); } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 49fd5b723..b267f6f8f 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -56,7 +56,7 @@ public class EmulatorEngine implements CpuEngine { }; private final ContextImpl context; - private final MemoryContext memory; + private final MemoryContext memory; private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); public final int[] regs = new int[8]; @@ -87,7 +87,7 @@ public class EmulatorEngine implements CpuEngine { private volatile DispatchListener dispatchListener; - public EmulatorEngine(MemoryContext memory, ContextImpl context) { + public EmulatorEngine(MemoryContext memory, ContextImpl context) { this.memory = Objects.requireNonNull(memory); this.context = Objects.requireNonNull(context); } @@ -230,15 +230,15 @@ private int getreg2(int reg) { private void putreg(int reg, int val) { if (reg == 6) { - memory.write((regs[REG_H] << 8) | regs[REG_L], (short) val); + memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) (val & 0xFF)); } else { - regs[reg] = val; + regs[reg] = val & 0xFF; } } private void putreg2(int reg, int val) { if (reg != 6) { - regs[reg] = val; + regs[reg] = val & 0xFF; } } @@ -318,13 +318,17 @@ private int getspecial(short spec) { return 0; } + private int readByte(int address) { + return memory.read(address) & 0xFF; + } + private int readWord(int address) { - Short[] read = memory.readWord(address); - return (read[1] << 8) | read[0]; + Byte[] read = memory.read(address, 2); + return ((read[1] << 8) | (read[0] & 0xFF)) & 0xFFFF; } private void writeWord(int address, int value) { - memory.writeWord(address, new Short[]{(short) (value & 0xFF), (short) ((value >>> 8) & 0xFF)}); + memory.write(address, new Byte[]{(byte) (value & 0xFF), (byte) ((value >>> 8) & 0xFF)}, 2); } private int doInterrupt() throws IOException, InvocationTargetException, IllegalAccessException { @@ -349,13 +353,13 @@ private int doInterrupt() throws IOException, InvocationTargetException, Illegal break; case 1: // rst 0xFF cycles += 12; - writeWord(SP - 2, PC); + writeWord((SP - 2) & 0xFFFF, PC); SP = (SP - 2) & 0xffff; PC = 0xFF & 0x38; break; case 2: cycles += 13; - writeWord(SP - 2, PC); + writeWord((SP - 2) & 0xFFFF, PC); PC = readWord((I << 8) | interruptVector); break; } @@ -808,7 +812,7 @@ private int O0_NOP(short OP) { } private int O2_LD_LPAR_BC_RPAR__A(short OP) { - memory.write(getpair(0, false), (short) regs[REG_A]); + memory.write(getpair(0, false), (byte) regs[REG_A]); return 7; } @@ -904,7 +908,7 @@ private int ADD_A_R(short OP) { regs[REG_A] += diff; flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF]; - regs[REG_A] = regs[REG_A] & 0xFF; + regs[REG_A] &= 0xFF; auxCarry(X, diff); overflow(X, diff, regs[REG_A]); @@ -954,7 +958,7 @@ private int SBC_A_R(short OP) { diff &= 0xFF; flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF] | FLAG_N; - regs[REG_A] = regs[REG_A] & 0xFF; + regs[REG_A] &= 0xFF; auxCarry(X, diff); overflow(X, diff, regs[REG_A]); @@ -1034,7 +1038,7 @@ private int O10_DJNZ(short OP) { } private int O12_LD_LPAR_DE_RPAR_A(short OP) { - memory.write(getpair(1, false), (short) regs[REG_A]); + memory.write(getpair(1, false), (byte) regs[REG_A]); return 7; } @@ -1046,8 +1050,7 @@ private int O17_RLA(short OP) { } private int O1A_LD_A_LPAR_DE_RPAR(short OP) { - int tmp = memory.read(getpair(1, false)); - regs[REG_A] = (tmp & 0xff); + regs[REG_A] = memory.read(getpair(1, false)) & 0xFF; return 7; } @@ -1156,8 +1159,8 @@ private int E3_EX_LPAR_SP_RPAR_HL(short OP) { int tmp = memory.read(SP); int x = (SP + 1) & 0xFFFF; int tmp1 = memory.read(x); - memory.write(SP, (short) regs[REG_L]); - memory.write(x, (short) regs[REG_H]); + memory.write(SP, (byte) regs[REG_L]); + memory.write(x, (byte) regs[REG_H]); regs[REG_L] = tmp & 0xFF; regs[REG_H] = tmp1 & 0xFF; return 19; @@ -1202,7 +1205,7 @@ private int IN_r_LPAR_C_RPAR(short OP) throws IOException { private int OUT_LPAR_C_RPAR_r(short OP) throws IOException { int tmp = (OP >>> 3) & 0x7; - context.writeIO(regs[REG_C], (short) getreg(tmp)); + context.writeIO(regs[REG_C], (byte) getreg(tmp)); return 12; } @@ -1327,7 +1330,7 @@ private int O67_RRD(short OP) { int tmp1 = memory.read((regs[REG_H] << 8) | regs[REG_L]); regs[REG_A] = ((regs[REG_A] & 0xF0) | (tmp1 & 0x0F)); tmp1 = ((tmp1 >>> 4) & 0x0F) | (tmp << 4); - memory.write(((regs[REG_H] << 8) | regs[REG_L]), (short) (tmp1 & 0xff)); + memory.write(((regs[REG_H] << 8) | regs[REG_L]), (byte) (tmp1 & 0xff)); flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_A]] | EmulatorTables.PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); return 18; } @@ -1337,7 +1340,7 @@ private int O6F_RLD(short OP) { int tmp1 = (tmp >>> 4) & 0x0F; tmp = ((tmp << 4) & 0xF0) | (regs[REG_A] & 0x0F); regs[REG_A] = ((regs[REG_A] & 0xF0) | tmp1); - memory.write((regs[REG_H] << 8) | regs[REG_L], (short) (tmp & 0xff)); + memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) (tmp & 0xff)); flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_A]] | EmulatorTables.PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); return 18; } @@ -1349,7 +1352,7 @@ private int O70_IN_LPAR_C_RPAR(short OP) throws IOException { } private int O71_OUT_LPAR_C_RPAR_0(short OP) throws IOException { - context.writeIO(regs[REG_C], 0); + context.writeIO(regs[REG_C], (byte)0); return 12; } @@ -1404,7 +1407,7 @@ private int A2_INI(short OP) throws IOException { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = tmp + (regs[REG_C] + 1) & 0xFF; - memory.write(tmp1, (short) tmp); + memory.write(tmp1, (byte) tmp); tmp1 = (tmp1 + 1) & 0xFFFF; regs[REG_H] = ((tmp1 >>> 8) & 0xff); regs[REG_L] = (tmp1 & 0xFF); @@ -1424,7 +1427,7 @@ private int A3_OUTI(short OP) throws IOException { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = memory.read(tmp1) & 0xFF; - context.writeIO(regs[REG_C], tmp2); + context.writeIO(regs[REG_C], (byte)tmp2); tmp1 = (tmp1 + 1) & 0xFFFF; regs[REG_H] = ((tmp1 >>> 8) & 0xff); regs[REG_L] = (tmp1 & 0xFF); @@ -1490,7 +1493,7 @@ private int AA_IND(short OP) throws IOException { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = tmp + ((regs[REG_C] - 1) & 0xFF); - memory.write(tmp1, (short) tmp); + memory.write(tmp1, (byte) tmp); tmp1 = (tmp1 - 1) & 0xFFFF; regs[REG_H] = ((tmp1 >>> 8) & 0xff); regs[REG_L] = (tmp1 & 0xFF); @@ -1511,7 +1514,7 @@ private int AB_OUTD(short OP) throws IOException { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = memory.read(tmp1) & 0xFF; - context.writeIO(regs[REG_C], tmp2); + context.writeIO(regs[REG_C], (byte)tmp2); tmp1 = (tmp1 - 1) & 0xFFFF; regs[REG_H] = ((tmp1 >>> 8) & 0xff); regs[REG_L] = (tmp1 & 0xFF); @@ -1586,7 +1589,7 @@ private int B2_INIR(short OP) throws IOException { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = tmp + (regs[REG_C] + 1) & 0xFF; - memory.write(tmp1, (short) tmp); + memory.write(tmp1, (byte) tmp); tmp1 = (tmp1 + 1) & 0xFFFF; regs[REG_H] = ((tmp1 >>> 8) & 0xff); regs[REG_L] = (tmp1 & 0xFF); @@ -1611,7 +1614,7 @@ private int B3_OTIR(short OP) throws IOException { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = memory.read(tmp1) & 0xFF; - context.writeIO(regs[REG_C], tmp2); + context.writeIO(regs[REG_C], (byte)tmp2); tmp1 = (tmp1 + 1) & 0xFFFF; regs[REG_H] = ((tmp1 >>> 8) & 0xff); regs[REG_L] = (tmp1 & 0xFF); @@ -1687,7 +1690,7 @@ private int BA_INDR(short OP) throws IOException { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = tmp + ((regs[REG_C] - 1) & 0xFF); - memory.write(tmp1, (short) tmp); + memory.write(tmp1, (byte) tmp); tmp1 = (tmp1 - 1) & 0xFFFF; regs[REG_H] = ((tmp1 >>> 8) & 0xff); regs[REG_L] = (tmp1 & 0xFF); @@ -1712,7 +1715,7 @@ private int BB_OTDR(short OP) throws IOException { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = memory.read(tmp1) & 0xFF; - context.writeIO(regs[REG_C], tmp2); + context.writeIO(regs[REG_C], (byte)tmp2); tmp1 = (tmp1 - 1) & 0xFFFF; regs[REG_H] = (tmp1 >>> 8); regs[REG_L] = (tmp1 & 0xFF); @@ -1812,7 +1815,7 @@ private int D3_OUT_LPAR_D_RPAR_A(short OP) throws IOException { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - context.writeIO(tmp, (short) regs[REG_A]); + context.writeIO(tmp, (byte) regs[REG_A]); return 11; } @@ -1906,8 +1909,7 @@ private int FE_CP_d(short OP) { } private int LD_SS_NN(short OP) { - Short[] word = memory.readWord(PC); - int tmp = word[0] | (word[1] << 8); + int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; putpair((OP >>> 4) & 3, tmp, true); @@ -1915,8 +1917,7 @@ private int LD_SS_NN(short OP) { } private int JP_CC_NN(short OP) { - Short[] word = memory.readWord(PC); - int tmp = word[0] | (word[1] << 8); + int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; int tmp1 = (OP >>> 3) & 7; @@ -1927,8 +1928,7 @@ private int JP_CC_NN(short OP) { } private int CALL_CC_NN(short OP) { - Short[] word = memory.readWord(PC); - int tmp = word[0] | (word[1] << 8); + int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; int tmp1 = (OP >>> 3) & 7; @@ -1942,8 +1942,7 @@ private int CALL_CC_NN(short OP) { } private int O22_LD_LPAR_NN_RPAR_HL(short OP) { - Short[] word = memory.readWord(PC); - int tmp = word[0] | (word[1] << 8); + int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; int tmp1 = getpair(2, false); @@ -1952,8 +1951,7 @@ private int O22_LD_LPAR_NN_RPAR_HL(short OP) { } private int O2A_LD_HL_LPAR_NN_RPAR(short OP) { - Short[] word = memory.readWord(PC); - int tmp = word[0] | (word[1] << 8); + int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; int tmp1 = readWord(tmp); @@ -1962,17 +1960,15 @@ private int O2A_LD_HL_LPAR_NN_RPAR(short OP) { } private int O32_LD_LPAR_NN_RPAR_A(short OP) { - Short[] word = memory.readWord(PC); - int tmp = word[0] | (word[1] << 8); + int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; - memory.write(tmp, (short) regs[REG_A]); + memory.write(tmp, (byte) regs[REG_A]); return 13; } private int O3A_LD_A_LPAR_NN_RPAR(short OP) { - Short[] word = memory.readWord(PC); - int tmp = word[0] | (word[1] << 8); + int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; regs[REG_A] = (memory.read(tmp) & 0xff); @@ -1980,19 +1976,13 @@ private int O3A_LD_A_LPAR_NN_RPAR(short OP) { } private int C3_JP_NN(short OP) { - Short[] word = memory.readWord(PC); - int tmp = word[0] | (word[1] << 8); - PC = (PC + 2) & 0xFFFF; - - PC = tmp; + PC = readWord(PC); return 10; } private int CD_CALL_NN(short OP) { - Short[] word = memory.readWord(PC); - int tmp = word[0] | (word[1] << 8); + int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; - SP = (SP - 2) & 0xffff; writeWord(SP, PC); PC = tmp; @@ -2150,19 +2140,19 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il case 0x77: tmp1 = (OP & 7); tmp2 = (getspecial(special) + (byte) tmp) & 0xFFFF; - memory.write(tmp2, (short) getreg2(tmp1)); + memory.write(tmp2, (byte) getreg2(tmp1)); return 19; case 0x34: /* INC (ii+d) */ tmp1 = (getspecial(special) + (byte) tmp) & 0xFFFF; tmp2 = (memory.read(tmp1) + 1) & 0xFF; - memory.write(tmp1, (short) tmp2); + memory.write(tmp1, (byte) tmp2); flags = EmulatorTables.INC_TABLE[tmp2] | (flags & FLAG_C); return 23; case 0x35: /* DEC (ii+d) */ tmp1 = (getspecial(special) + (byte) tmp) & 0xFFFF; tmp2 = (memory.read(tmp1) - 1) & 0xFF; - memory.write(tmp1, (short) tmp2); + memory.write(tmp1, (byte) tmp2); flags = EmulatorTables.DEC_TABLE[tmp2] | (flags & FLAG_C); return 23; case 0x86: /* ADD A,(ii+d) */ @@ -2261,7 +2251,7 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il putspecial(special, tmp1); return 20; case 0x36: /* LD (ii+d),n */ - memory.write((getspecial(special) + (byte) (tmp & 0xFF)) & 0xFFFF, (short) ((tmp >>> 8))); + memory.write((getspecial(special) + (byte) (tmp & 0xFF)) & 0xFFFF, (byte) ((tmp >>> 8))); return 19; case 0xCB: OP = (short) ((tmp >>> 8) & 0xff); @@ -2307,7 +2297,7 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il tmp3 = (getspecial(special) + (byte) tmp) & 0xffff; tmp1 = memory.read(tmp3); tmp1 = (tmp1 & (~(1 << tmp2))); - memory.write(tmp3, (short) (tmp1 & 0xff)); + memory.write(tmp3, (byte) (tmp1 & 0xff)); return 23; /* SET b,(ii+d) */ case 0xC6: @@ -2322,7 +2312,7 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il tmp3 = (getspecial(special) + (byte) tmp) & 0xffff; tmp1 = memory.read(tmp3); tmp1 = (tmp1 | (1 << tmp2)); - memory.write(tmp3, (short) (tmp1 & 0xff)); + memory.write(tmp3, (byte) (tmp1 & 0xff)); return 23; /* SET 0,(ii+d),reg (undocumented) */ case 0xC0: @@ -2336,7 +2326,7 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il tmp3 = (getspecial(special) + (byte) tmp) & 0xffff; tmp1 = memory.read(tmp3); tmp1 = (tmp1 | (1 << tmp2)); - memory.write(tmp3, (short) (tmp1 & 0xff)); + memory.write(tmp3, (byte) (tmp1 & 0xff)); regs[OP & 7] = tmp1 & 0xFF; return 23; case 0x06: /* RLC (ii+d) */ @@ -2347,11 +2337,11 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il tmp2 = (tmp1 >>> 7) & 1; tmp1 = ((((tmp1 << 1) & 0xFF) | tmp2) & 0xFF); - memory.write(tmp, (short) (tmp1 & 0xFF)); + memory.write(tmp, (byte) (tmp1 & 0xFF)); flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; if (OP == 0) { - regs[REG_B] = (short) (tmp1 & 0xFF); + regs[REG_B] = tmp1 & 0xFF; } return 23; case 0x0E: /* RRC (ii+d) */ @@ -2361,7 +2351,7 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il tmp2 = tmp1 & 1; tmp1 = (((tmp1 >>> 1) & 0x7F) | (tmp2 << 7)) & 0xFF; - memory.write(tmp, (short) (tmp1 & 0xFF)); + memory.write(tmp, (byte) (tmp1 & 0xFF)); flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; return 23; @@ -2371,7 +2361,7 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il tmp2 = (tmp1 >>> 7) & 1; tmp1 = ((((tmp1 << 1) & 0xFF) | flags & FLAG_C) & 0xFF); - memory.write(tmp, (short) (tmp1 & 0xFF)); + memory.write(tmp, (byte) (tmp1 & 0xFF)); flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; @@ -2382,7 +2372,7 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il tmp2 = tmp1 & 1; tmp1 = ((((tmp1 >> 1) & 0xFF) | (flags & FLAG_C) << 7) & 0xFF); - memory.write(tmp, (short) (tmp1 & 0xFF)); + memory.write(tmp, (byte) (tmp1 & 0xFF)); flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; @@ -2393,7 +2383,7 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il tmp2 = (tmp1 >>> 7) & 1; tmp1 = (tmp1 << 1) & 0xFE; - memory.write(tmp, (short) tmp1); + memory.write(tmp, (byte) tmp1); flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; @@ -2404,7 +2394,7 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il tmp2 = tmp1 & 1; tmp1 = (tmp1 >> 1) & 0xFF | (tmp1 & 0x80); - memory.write(tmp, (short) tmp1); + memory.write(tmp, (byte) tmp1); flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; @@ -2415,7 +2405,7 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il tmp2 = (tmp1 >>> 7) & 1; tmp1 = (tmp1 << 1) & 0xFF | tmp1 & 1; - memory.write(tmp, (short) tmp1); + memory.write(tmp, (byte) tmp1); flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; @@ -2426,7 +2416,7 @@ private int dispatch(short OP) throws IOException, InvocationTargetException, Il tmp2 = tmp1 & 1; tmp1 = (tmp1 >>> 1) & 0x7F; - memory.write(tmp, (short) tmp1); + memory.write(tmp, (byte) tmp1); flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InitializerForZ80.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InitializerForZ80.java index af0bd8605..ebc30b635 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InitializerForZ80.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InitializerForZ80.java @@ -42,7 +42,7 @@ public InitializerForZ80(Plugin plugin, long pluginId, ContextPool contextPool, } @Override - protected EmulatorEngine createEmulatorEngine(MemoryContext memory) { + protected EmulatorEngine createEmulatorEngine(MemoryContext memory) { return new EmulatorEngine(memory, context); } @@ -53,7 +53,7 @@ protected DispatchListener createInstructionPrinter(Disassembler disassembler, E } @Override - protected Disassembler createDisassembler(MemoryContext memory) { + protected Disassembler createDisassembler(MemoryContext memory) { return new DisassemblerImpl(memory, new DecoderImpl(memory)); } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeDevice.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeDevice.java index 9e22d2bcb..59b1a3114 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeDevice.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeDevice.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.plugins.device.DeviceContext; -public class FakeDevice implements DeviceContext { +public class FakeDevice implements DeviceContext { private byte value; public void setValue(byte value) { @@ -32,17 +32,17 @@ public byte getValue() { } @Override - public Short readData() { - return (short) (value & 0xFF); + public Byte readData() { + return (byte) (value & 0xFF); } @Override - public void writeData(Short value) { - this.value = value.byteValue(); + public void writeData(Byte value) { + this.value = value; } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java index 81551c38a..a5b7a1358 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java @@ -86,8 +86,7 @@ public void testIN__C() { @Test public void testINI() { - BiFunction, Number, Boolean> flagHCtest = (context, result) -> - (((context.first >>> 8) & 0xFF) + ((context.first & 0xFF + 1) & 0xFF)) > 0xFF; + BiFunction, Number, Boolean> flagHCtest = (context, result) -> false; BiFunction, Number, Boolean> flagPVtest = (context, result) -> FlagsCheckImpl.isParity( ((((context.first >>> 8) & 0xFF) + (((context.first & 0xFF) + 1) & 0xFF)) & 7) ^ result.byteValue() @@ -118,8 +117,7 @@ public void testINI() { @Test public void testINIR() { - BiFunction, Number, Boolean> flagHCtest = (context, result) -> - (((context.first >>> 8) & 0xFF) + ((context.first & 0xFF + 1) & 0xFF)) > 0xFF; + BiFunction, Number, Boolean> flagHCtest = (context, result) -> false; BiFunction, Number, Boolean> flagPVtest = (context, result) -> FlagsCheckImpl.isParity( ((((context.first >>> 8) & 0xFF) + (((context.first & 0xFF) + 1) & 0xFF)) & 7) ^ result.byteValue() @@ -135,9 +133,7 @@ public void testINIR() { .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero() - .expectFlagOnlyWhen(FLAG_N, - (context, result) -> (((context.first >>> 8) & 0x80) == 0x80) - ) + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) .expectFlagOnlyWhen(FLAG_H, flagHCtest) .expectFlagOnlyWhen(FLAG_C, flagHCtest) .expectFlagOnlyWhen(FLAG_PV, flagPVtest) diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java index 46ea414b5..b08319219 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java @@ -177,7 +177,7 @@ private void readSettings() { }); } - private int attachPort(int diskPortNumber, DeviceContext diskPort, int cpuPort) throws PluginInitializationException { + private int attachPort(int diskPortNumber, DeviceContext diskPort, int cpuPort) throws PluginInitializationException { if (cpuContext.attachDevice(diskPort, cpuPort)) { return cpuPort; } else { diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java index 58966d446..bba09a21d 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java @@ -45,17 +45,17 @@ public class Drive { private static final Logger LOGGER = LoggerFactory.getLogger(Drive.class); - public final static short DEFAULT_SECTORS_COUNT = 32; - public final static short DEFAULT_SECTOR_LENGTH = 137; + public final static byte DEFAULT_SECTORS_COUNT = 32; + public final static byte DEFAULT_SECTOR_LENGTH = (byte)137; - public static final short DEAD_DRIVE = 0b11100111; - private static final short ALIVE_DRIVE = 0b11100101; - private static final short MASK_TRACK0 = 0b10111111; + public static final byte DEAD_DRIVE = (byte)0b11100111; + private static final byte ALIVE_DRIVE = (byte)0b11100101; + private static final byte MASK_TRACK0 = (byte)0b10111111; - public static final short SECTOR0 = 0b11000001; + public static final byte SECTOR0 = (byte)0b11000001; - private static final short MASK_HEAD_LOAD = 0b11111011; - private static final short MASK_DATA_AVAILABLE = 0b01111111; + private static final byte MASK_HEAD_LOAD = (byte)0b11111011; + private static final byte MASK_DATA_AVAILABLE = 0b01111111; private final int driveIndex; @@ -88,8 +88,8 @@ public class Drive { Z - When 0, indicates head is on track 0 R - When 0, indicates that read circuit has new byte to read */ - private short port1status = DEAD_DRIVE; - private short port2status = SECTOR0; + private byte port1status = DEAD_DRIVE; + private byte port2status = SECTOR0; public Drive(int driveIndex) { this.driveIndex = driveIndex; @@ -202,16 +202,16 @@ public Path getImagePath() { return mountedFloppy; } - public short getPort1status() { + public byte getPort1status() { return inReadLock(() -> port1status); } - public short getPort2status() { + public byte getPort2status() { return inReadLock(() -> { if (((~port1status) & (~MASK_HEAD_LOAD)) != 0) { return port2status; } else { - return (short) 0; + return (byte)0; } }); } @@ -238,7 +238,7 @@ public void writeToPort2(short val) { if ((val & 0x04) != 0) { /* Head load */ port1status &= MASK_HEAD_LOAD; port1status &= MASK_DATA_AVAILABLE; - port2status = (short) ((sector << 1) & 0x3E | 0xC0); + port2status = (byte) ((sector << 1) & 0x3E | 0xC0); if (sectorOffset != 0) { port2status |= 1; // SR0 = false } @@ -263,9 +263,9 @@ public void writeToPort2(short val) { public void nextSectorIfHeadIsLoaded() { inWriteLock(() -> { if (((~port1status) & (~MASK_HEAD_LOAD)) != 0) { /* head loaded? */ - sector = (short) ((sector + 1) % sectorsCount); + sector = (byte) ((sector + 1) % sectorsCount); sectorOffset = sectorLength; - port2status = (short) ((sector << 1) & 0x3E | 0xC0); + port2status = (byte) ((sector << 1) & 0x3E | 0xC0); } }); notifyParamsChanged(); @@ -297,21 +297,21 @@ public void writeData(int data) { notifyParamsChanged(); } - public short readData() { + public byte readData() { if (mountedFloppy == null) { return 0; } - short result = inWriteLock(() -> { + byte result = inWriteLock(() -> { try { int offset = (sectorOffset == sectorLength) ? 0 : sectorOffset; - imageChannel.position(sectorsCount * sectorLength * track + sectorLength * sector + offset); + imageChannel.position((long) sectorsCount * sectorLength * track + (long) sectorLength * sector + offset); byteBuffer.clear(); int bytesRead = imageChannel.read(byteBuffer); if (bytesRead != byteBuffer.capacity()) { throw new IOException("[drive=" + driveIndex + "] Could not read data from disk image"); } byteBuffer.flip(); - return (short) (byteBuffer.get() & 0xFF); + return (byte) (byteBuffer.get() & 0xFF); } catch (IOException ex) { throw new RuntimeException(ex); } finally { diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/ControlPort.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/ControlPort.java index 0ba7b24b6..48addbf35 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/ControlPort.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/ControlPort.java @@ -32,7 +32,7 @@ * IN: sector pos * OUT: set flags */ -public class ControlPort implements DeviceContext { +public class ControlPort implements DeviceContext { private final DriveCollection disk; public ControlPort(DriveCollection disk) { @@ -40,7 +40,7 @@ public ControlPort(DriveCollection disk) { } @Override - public Short readData() { + public Byte readData() { return disk.getCurrentDrive().map(drive -> { drive.nextSectorIfHeadIsLoaded(); return drive.getPort2status(); @@ -48,13 +48,13 @@ public Short readData() { } @Override - public void writeData(Short val) { + public void writeData(Byte val) { disk.getCurrentDrive().ifPresent(drive -> drive.writeToPort2(val)); } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } @Override diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/DataPort.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/DataPort.java index f93bd0d60..ad3f6c0e1 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/DataPort.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/DataPort.java @@ -32,7 +32,7 @@ * IN: read data * OUT: write data */ -public class DataPort implements DeviceContext { +public class DataPort implements DeviceContext { private final DriveCollection disk; public DataPort(DriveCollection disk) { @@ -40,18 +40,18 @@ public DataPort(DriveCollection disk) { } @Override - public Short readData() { - return disk.getCurrentDrive().map(Drive::readData).orElse((short)0); + public Byte readData() { + return disk.getCurrentDrive().map(Drive::readData).orElse((byte)0); } @Override - public void writeData(Short data) { + public void writeData(Byte data) { disk.getCurrentDrive().ifPresent(drive -> drive.writeData(data)); } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } @Override diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/StatusPort.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/StatusPort.java index cd583d6ac..3d6b1097f 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/StatusPort.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/StatusPort.java @@ -32,7 +32,7 @@ * IN: disk flags * OUT: select/unselect drive */ -public class StatusPort implements DeviceContext { +public class StatusPort implements DeviceContext { private final DriveCollection disk; public StatusPort(DriveCollection disk) { @@ -40,12 +40,12 @@ public StatusPort(DriveCollection disk) { } @Override - public Short readData() { + public Byte readData() { return disk.getCurrentDrive().map(Drive::getPort1status).orElse(Drive.DEAD_DRIVE); } @Override - public void writeData(Short value) { + public void writeData(Byte value) { if ((value & 0x80) != 0) { disk.getCurrentDrive().ifPresent(Drive::deselect); disk.unsetCurrentDrive(); @@ -56,8 +56,8 @@ public void writeData(Short value) { } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } @Override diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java index 12ee51a4b..4b55af818 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java @@ -98,10 +98,10 @@ public void initialize() throws PluginInitializationException { // get a device attached to this board try { - DeviceContext device = applicationApi.getContextPool().getDeviceContext(pluginID, DeviceContext.class); - if (device.getDataType() != Short.class) { + DeviceContext device = applicationApi.getContextPool().getDeviceContext(pluginID, DeviceContext.class); + if (device.getDataType() != Byte.class) { throw new PluginInitializationException( - "Unexpected device data type. Expected Short but was: " + device.getDataType() + "Unexpected device data type. Expected Byte but was: " + device.getDataType() ); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/Transmitter.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/Transmitter.java index a465950c8..2fff5ebf4 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/Transmitter.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/Transmitter.java @@ -48,23 +48,23 @@ public class Transmitter { private final static Logger LOGGER = LoggerFactory.getLogger(Transmitter.class); - private final Queue buffer = new ConcurrentLinkedQueue<>(); + private final Queue buffer = new ConcurrentLinkedQueue<>(); private final Lock bufferAndStatusLock = new ReentrantLock(); - private volatile DeviceContext device; - private volatile short status = 0x2; + private volatile DeviceContext device; + private volatile byte status = 0x2; private volatile boolean inputInterruptEnabled; private volatile boolean outputInterruptEnabled; private final List observers = new ArrayList<>(); - void setDevice(DeviceContext device) { + void setDevice(DeviceContext device) { this.device = device; LOGGER.info("[device={}] Device was attached to 88-SIO", getDeviceId()); } String getDeviceId() { - DeviceContext tmpDevice = device; + DeviceContext tmpDevice = device; if (tmpDevice == null) { return "unknown"; } @@ -99,7 +99,7 @@ public void writeToStatus(short value) { } } - public void writeFromDevice(short data) { + public void writeFromDevice(byte data) { boolean wasEmpty = false; int newStatus = status; @@ -109,7 +109,7 @@ public void writeFromDevice(short data) { wasEmpty = true; } buffer.add(data); - status = (short) (status | 1); + status = (byte) (status | 1); newStatus = status; } finally { bufferAndStatusLock.unlock(); @@ -121,24 +121,24 @@ public void writeFromDevice(short data) { } } - public void writeToDevice(short data) throws IOException { - DeviceContext tmpDevice = device; + public void writeToDevice(byte data) throws IOException { + DeviceContext tmpDevice = device; if (tmpDevice != null) { tmpDevice.writeData(data); } } - public short readBuffer() { + public byte readBuffer() { int newData = 0; boolean isNotEmpty = false; int newStatus = status; // what to do.. bufferAndStatusLock.lock(); try { - Short result = buffer.poll(); + Byte result = buffer.poll(); isNotEmpty = !buffer.isEmpty(); - status = isNotEmpty ? (short) (status | 1) : (short) (status & 0xFE); + status = (byte) (isNotEmpty ? (status | 1) : (status & 0xFE)); newStatus = status; if (isNotEmpty) { @@ -158,7 +158,7 @@ public short readBuffer() { } } - public short readStatus() { + public byte readStatus() { return status; } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPort.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPort.java index 916581077..99065f33c 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPort.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPort.java @@ -32,7 +32,7 @@ * A read to the data port gets the buffered character, a write to the data port * writes the character to the device. */ -public class CpuDataPort implements DeviceContext { +public class CpuDataPort implements DeviceContext { private final Transmitter transmitter; public CpuDataPort(Transmitter transmitter) { @@ -40,17 +40,17 @@ public CpuDataPort(Transmitter transmitter) { } @Override - public void writeData(Short data) throws IOException { + public void writeData(Byte data) throws IOException { transmitter.writeToDevice(data); } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } @Override - public Short readData() { + public Byte readData() { return transmitter.readBuffer(); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPort.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPort.java index 513f3b2b5..e59cf9d5a 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPort.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPort.java @@ -28,7 +28,7 @@ * This is the status port of 88-SIO card. */ @PluginContext(id = "Status port") -public class CpuStatusPort implements DeviceContext { +public class CpuStatusPort implements DeviceContext { private final Transmitter transmitter; public CpuStatusPort(Transmitter transmitter) { @@ -36,18 +36,18 @@ public CpuStatusPort(Transmitter transmitter) { } @Override - public Short readData() { + public Byte readData() { return transmitter.readStatus(); } @Override - public void writeData(Short data) { + public void writeData(Byte data) { transmitter.writeToStatus(data); } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } @Override diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPortTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPortTest.java index 8769c96f6..c83555bf9 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPortTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPortTest.java @@ -35,7 +35,7 @@ public void testNullTransmitterInConstructorThrows() { @Test public void testReadCallsReadBufferOnTransmitter() { Transmitter transmitter = EasyMock.createMock(Transmitter.class); - expect(transmitter.readBuffer()).andReturn((short) 5).once(); + expect(transmitter.readBuffer()).andReturn((byte) 5).once(); replay(transmitter); CpuDataPort cpuDataPort = new CpuDataPort(transmitter); @@ -47,12 +47,12 @@ public void testReadCallsReadBufferOnTransmitter() { @Test public void testWriteCallsWriteToDeviceOnTransmitter() throws Exception { Transmitter transmitter = EasyMock.createMock(Transmitter.class); - transmitter.writeToDevice(eq((short) 5)); + transmitter.writeToDevice(eq((byte) 5)); expectLastCall().once(); replay(transmitter); CpuDataPort cpuDataPort = new CpuDataPort(transmitter); - cpuDataPort.writeData((short) 5); + cpuDataPort.writeData((byte) 5); verify(transmitter); } diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPortTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPortTest.java index 616f077f4..ebcaa1a73 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPortTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPortTest.java @@ -35,7 +35,7 @@ public void testNullTransmitterInConstructorThrows() { @Test public void testReadCallsReadStatusOnTransmitter() { Transmitter transmitter = EasyMock.createMock(Transmitter.class); - expect(transmitter.readStatus()).andReturn((short) 5).once(); + expect(transmitter.readStatus()).andReturn((byte) 5).once(); replay(transmitter); CpuStatusPort cpuStatusPort = new CpuStatusPort(transmitter); @@ -52,7 +52,7 @@ public void testWriteCallsWriteToStatusOnTransmitter() { replay(transmitter); CpuStatusPort cpuStatusPort = new CpuStatusPort(transmitter); - cpuStatusPort.writeData((short) 5); + cpuStatusPort.writeData((byte) 5); verify(transmitter); } diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java index 5ef56c011..d057572c9 100644 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java +++ b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java @@ -23,47 +23,42 @@ import java.util.Arrays; -public class MemoryContextImpl extends AbstractMemoryContext implements RawMemoryContext { - private final short[] memory = new short[65536]; +public class MemoryContextImpl extends AbstractMemoryContext implements RawMemoryContext { + private final Byte[] memory = new Byte[65536]; @Override public void clear() { - Arrays.fill(memory, (short) 0); + Arrays.fill(memory, (byte) 0); notifyMemoryChanged(-1); // notify that all memory has changed } @Override - public Short read(int from) { + public Byte read(int from) { return memory[from]; } @Override - public Short[] readWord(int from) { - if (from == memory.length - 1) { - return new Short[]{memory[from], 0}; - } - return new Short[]{memory[from], memory[from + 1]}; + public Byte[] read(int from, int count) { + return Arrays.copyOfRange(memory, from, from + count); // from+count can be >= memory.length } @Override - public void write(int to, Short val) { - memory[to] = val; + public void write(int to, Byte value) { + memory[to] = value; notifyMemoryChanged(to); } @Override - public void writeWord(int to, Short[] cells) { - memory[to] = cells[0]; - notifyMemoryChanged(to); - if (to < memory.length - 1) { - memory[to + 1] = cells[1]; - notifyMemoryChanged(to + 1); + public void write(int to, Byte[] values, int count) { + System.arraycopy(values, 0, memory, to, count); + for (int i = 0; i < values.length; i++) { + notifyMemoryChanged(to + i); } } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } @Override @@ -72,7 +67,7 @@ public int getSize() { } @Override - public short[] getRawMemory() { + public Byte[] getRawMemory() { return memory; } } diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/api/RawMemoryContext.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/api/RawMemoryContext.java index acb3133c1..a480921b6 100644 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/api/RawMemoryContext.java +++ b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/api/RawMemoryContext.java @@ -23,7 +23,7 @@ import net.emustudio.emulib.plugins.memory.MemoryContext; @PluginContext(id = "BrainDuck Raw Memory") -public interface RawMemoryContext extends MemoryContext { +public interface RawMemoryContext extends MemoryContext { /** * Returns raw memory represented by Java array. @@ -32,5 +32,5 @@ public interface RawMemoryContext extends MemoryContext { * * @return raw memory */ - short[] getRawMemory(); + Byte[] getRawMemory(); } diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryGui.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryGui.java index bc47dd57e..070403a27 100644 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryGui.java +++ b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryGui.java @@ -27,7 +27,7 @@ public class MemoryGui extends JDialog { private final MemoryTableModel tableModel; - private final MemoryContext memory; + private final MemoryContext memory; private class MemoryListenerImpl implements Memory.MemoryListener { @@ -42,7 +42,7 @@ public void memorySizeChanged() { } } - public MemoryGui(JFrame parent, MemoryContext memory) { + public MemoryGui(JFrame parent, MemoryContext memory) { super(parent, false); setLocationRelativeTo(parent); initComponents(); diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTableModel.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTableModel.java index 76fe8389c..251a2b538 100644 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTableModel.java +++ b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTableModel.java @@ -24,12 +24,12 @@ import java.util.Objects; public class MemoryTableModel extends AbstractTableModel { - private final MemoryContext mem; + private final MemoryContext mem; private int currentPage = 0; private final int ROW_COUNT = 16; private final int COLUMN_COUNT = 16; - MemoryTableModel(MemoryContext memory) { + MemoryTableModel(MemoryContext memory) { this.mem = Objects.requireNonNull(memory); } @@ -62,7 +62,7 @@ public Object getValueAt(int rowIndex, int columnIndex) { public void setValueAt(Object aValue, int rowIndex, int columnIndex) { int pos = ROW_COUNT * COLUMN_COUNT * currentPage + rowIndex * COLUMN_COUNT + columnIndex; try { - mem.write(pos, Short.decode(String.valueOf(aValue))); + mem.write(pos, Byte.decode(String.valueOf(aValue))); fireTableCellUpdated(rowIndex, columnIndex); } catch (NumberFormatException ignored) { } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java index a47dfe744..f44e3a344 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java @@ -20,8 +20,8 @@ import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.memory.AbstractMemoryContext; -import net.emustudio.emulib.runtime.helpers.IntelHEX; import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import java.io.EOFException; @@ -33,7 +33,7 @@ import java.util.Objects; @PluginContext(id = "Byte Memory") -public class MemoryContextImpl extends AbstractMemoryContext implements ByteMemoryContext { +public class MemoryContextImpl extends AbstractMemoryContext implements ByteMemoryContext { final static int DEFAULT_MEM_SIZE = 65536; private final RangeTree romRanges = new RangeTree(); @@ -44,7 +44,7 @@ public MemoryContextImpl(Dialogs dialogs) { } int lastImageStart = 0; - private short[][] mem = new short[1][0]; + private Byte[][] mem = new Byte[1][0]; private int banksCount; private short bankSelect = 0; private int bankCommon = 0; @@ -56,13 +56,13 @@ void init(int size, int banks, int bankCommon) { this.bankCommon = bankCommon; this.banksCount = banks; - mem = new short[banks][size]; + mem = new Byte[banks][size]; } @Override public void clear() { - for (short[] mem1 : mem) { - Arrays.fill(mem1, (short) 0); + for (Byte[] bank : mem) { + Arrays.fill(bank, (byte) 0); } lastImageStart = 0; notifyMemoryChanged(-1); @@ -99,8 +99,8 @@ public int getCommonBoundary() { public void loadHex(Path hexFile, int bank) { short currentBank = bankSelect; try { - bankSelect = (short)bank; - lastImageStart = IntelHEX.loadIntoMemory(hexFile.toFile(), this); + bankSelect = (short) bank; + lastImageStart = IntelHEX.loadIntoMemory(hexFile.toFile(), this, p -> p); } catch (FileNotFoundException ex) { dialogs.showError("File not found: " + hexFile); } catch (Exception e) { @@ -116,7 +116,7 @@ public void loadBin(Path binFile, int address, int bank) { try (RandomAccessFile binaryFile = new RandomAccessFile(binFile.toFile(), "r")) { long position = 0, length = binaryFile.length(); while (position < length) { - mem[bank][address++] = (short) (binaryFile.readUnsignedByte() & 0xFF); + mem[bank][address++] = (byte) (binaryFile.readUnsignedByte() & 0xFF); position++; } } catch (EOFException ignored) { @@ -131,12 +131,12 @@ public void loadBin(Path binFile, int address, int bank) { } @Override - public Short read(int from) { + public Byte read(int from) { int activeBank = (from < bankCommon) ? bankSelect : 0; return mem[activeBank][from]; } - public Short read(int from, int bank) { + public Byte readBank(int from, int bank) { if (from < bankCommon) { return mem[bank][from]; } else { @@ -145,48 +145,38 @@ public Short read(int from, int bank) { } @Override - public Short[] readWord(int from) { - int activeBank = (from < bankCommon) ? bankSelect : 0; - return new Short[]{mem[activeBank][from], mem[activeBank][(from + 1) & 0xFFFF]}; + public Byte[] read(int from, int count) { + return Arrays.copyOfRange(mem[bank(from)], from, from + count); // from+count can be >= memory.length } @Override - public void write(int to, Short val) { + public void write(int to, Byte value) { if (!isReadOnly(to)) { - int activeBank = (to < bankCommon) ? bankSelect : 0; - mem[activeBank][to] = (short) (val & 0xFF); + mem[bank(to)][to] = value; notifyMemoryChanged(to); } } - public void write(int to, short val, int bank) { + public void writeBank(int to, byte val, int bank) { if (!isReadOnly(to)) { int activeBank = (to < bankCommon) ? bank : 0; - mem[activeBank][to] = (short) (val & 0xFF); + mem[activeBank][to] = val; notifyMemoryChanged(to); } } - @Override - public void writeWord(int to, Short[] cells) { - if (isReadOnly(to)) { - return; - } - int activeBank = (to < bankCommon) ? bankSelect : 0; - mem[activeBank][to] = (short) (cells[0] & 0xFF); - - if (isReadOnly(to + 1)) { - return; + public void write(int to, Byte[] values, int count) { + if (!romRanges.intersects(to, to + count)) { + System.arraycopy(values, 0, mem[bank(to)], to, count); + for (int i = 0; i < values.length; i++) { + notifyMemoryChanged(to + i); + } } - - mem[activeBank][to + 1] = (short) (cells[1] & 0xFF); - notifyMemoryChanged(to); - notifyMemoryChanged(to + 1); } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } @Override @@ -227,4 +217,8 @@ private void removeROMRange(AddressRange rangeToRemove) { private void addRomRange(AddressRange range) { romRanges.add(range.getStartAddress(), range.getStopAddress()); } + + private int bank(int address) { + return (address < bankCommon) ? bankSelect : 0; + } } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/RangeTree.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/RangeTree.java index 43c7f78a0..44177bfed 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/RangeTree.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/RangeTree.java @@ -69,6 +69,15 @@ public boolean isIn(int value) { return values.contains(value); } + public boolean intersects(int from, int to) { + for (int i = from; i <= to; i++) { + if (values.contains(i)) { + return true; + } + } + return false; + } + public final static class Range implements ByteMemoryContext.AddressRange { public final int from; public final int to; diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java index 3d5e76947..529eb97ad 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java @@ -28,8 +28,9 @@ *

* Supports bank switching, ROM ranges, and loading HEX/BIN files. */ +@SuppressWarnings("unused") @PluginContext(id = "Byte memory") -public interface ByteMemoryContext extends MemoryContext { +public interface ByteMemoryContext extends MemoryContext { /** * This interface represents a range of addresses in the memory. diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java index 7fc28fe80..4f9984d13 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java @@ -67,14 +67,14 @@ public Object getValueAt(int rowIndex, int columnIndex) { if (pos >= memory.getSize()) { return "."; } - return String.format("%1$02X", memory.read(pos, currentBank)); + return String.format("%1$02X", memory.readBank(pos, currentBank)); } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { int pos = ROW_COUNT * COLUMN_COUNT * currentPage + rowIndex * COLUMN_COUNT + columnIndex; try { - memory.write(pos, Short.decode(String.valueOf(aValue)), currentBank); + memory.writeBank(pos, Byte.decode(String.valueOf(aValue)), currentBank); fireTableCellUpdated(rowIndex, columnIndex); } catch (NumberFormatException e) { // ignored @@ -99,7 +99,7 @@ public Optional findSequence(byte[] sequence, int from) { int offset = 0; int foundAddress = -1; for (int currentAddr = from; currentAddr < size && offset < sequence.length; currentAddr++) { - if ((memory.read(currentAddr, currentBank)).byteValue() == sequence[offset]) { + if (memory.readBank(currentAddr, currentBank) == sequence[offset]) { if (offset == 0) { foundAddress = currentAddr; } diff --git a/settings.gradle b/settings.gradle index e2fb0be6d..5506ec622 100644 --- a/settings.gradle +++ b/settings.gradle @@ -29,23 +29,23 @@ include ':plugins:compiler:as-ssem' //include ':plugins:compiler:raspc-rasp' include ':plugins:cpu:8080-cpu' -//include ':plugins:cpu:brainduck-cpu' +include ':plugins:cpu:brainduck-cpu' //include ':plugins:cpu:ram-cpu' //include ':plugins:cpu:rasp-cpu' include ':plugins:cpu:ssem-cpu' -//include ':plugins:cpu:z80-cpu' +include ':plugins:cpu:z80-cpu' include ':plugins:device:88-dcdd' include ':plugins:device:88-sio' include ':plugins:device:abstract-tape' include ':plugins:device:adm3A-terminal' //include ':plugins:device:brainduck-terminal' -//include ':plugins:device:simhPseudo-z80' +include ':plugins:device:simhPseudo-z80' include ':plugins:device:ssem-display' -//include ':plugins:memory:brainduck-mem' +include ':plugins:memory:brainduck-mem' //include ':plugins:memory:ram-mem' //include ':plugins:memory:rasp-mem' include ':plugins:memory:ssem-mem' -//include ':plugins:memory:byte-mem' +include ':plugins:memory:byte-mem' From 6b5efd1026de0e1e7f69c71cebac7f5d0afd7f37 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 30 Jan 2022 17:29:22 +0100 Subject: [PATCH 083/314] [#201] Rewrite Z80 emulator --- .../plugins/cpu/zilogZ80/DispatchTables.java | 1311 ++++++++ .../plugins/cpu/zilogZ80/EmulatorEngine.java | 2748 ++++++++--------- .../plugins/cpu/zilogZ80/EmulatorTables.java | 80 +- .../plugins/cpu/zilogZ80/ArithmeticTest.java | 90 +- .../{FakeDevice.java => FakeByteDevice.java} | 2 +- .../cpu/zilogZ80/FlagsTableGeneratorTest.java | 1 + .../plugins/cpu/zilogZ80/IOTest.java | 146 +- .../cpu/zilogZ80/InstructionsTest.java | 8 +- .../plugins/cpu/zilogZ80/LogicTest.java | 181 +- .../plugins/cpu/zilogZ80/TablesGenerator.java | 71 + .../plugins/cpu/zilogZ80/TransferTest.java | 191 +- .../cpu/zilogZ80/suite/CpuRunnerImpl.java | 10 +- .../cpu/zilogZ80/suite/CpuVerifierImpl.java | 15 +- .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 52 + 14 files changed, 3036 insertions(+), 1870 deletions(-) create mode 100644 plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java rename plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/{FakeDevice.java => FakeByteDevice.java} (95%) create mode 100644 plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TablesGenerator.java diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java new file mode 100644 index 000000000..5329e1768 --- /dev/null +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java @@ -0,0 +1,1311 @@ +package net.emustudio.plugins.cpu.zilogZ80; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class DispatchTables { + private final static Logger LOGGER = LoggerFactory.getLogger(DispatchTables.class); + + public final static MethodHandle[] DISPATCH_TABLE = new MethodHandle[256]; + public final static MethodHandle[] DISPATCH_TABLE_ED = new MethodHandle[256]; + public final static MethodHandle[] DISPATCH_TABLE_CB = new MethodHandle[256]; + public final static MethodHandle[] DISPATCH_TABLE_DD = new MethodHandle[256]; + public final static MethodHandle[] DISPATCH_TABLE_DD_CB = new MethodHandle[256]; + public final static MethodHandle[] DISPATCH_TABLE_FD = new MethodHandle[256]; + public final static MethodHandle[] DISPATCH_TABLE_FD_CB = new MethodHandle[256]; + + static { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType intShort = MethodType.methodType(int.class, short.class); + MethodType intShortByte = MethodType.methodType(int.class, short.class, byte.class); + + try { + DISPATCH_TABLE[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); + DISPATCH_TABLE[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); + DISPATCH_TABLE[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_BC_A", intShort); // TODO: unify + DISPATCH_TABLE[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); + DISPATCH_TABLE[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); + DISPATCH_TABLE[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); + DISPATCH_TABLE[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); + DISPATCH_TABLE[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLCA", intShort); + DISPATCH_TABLE[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_EX_AF_AFF", intShort); + DISPATCH_TABLE[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); + DISPATCH_TABLE[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_BC", intShort); // TODO: unify + DISPATCH_TABLE[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); + DISPATCH_TABLE[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); + DISPATCH_TABLE[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); + DISPATCH_TABLE[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); + DISPATCH_TABLE[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRCA", intShort); + DISPATCH_TABLE[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_DJNZ", intShort); + DISPATCH_TABLE[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); + DISPATCH_TABLE[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_DE_A", intShort); // TODO: unify + DISPATCH_TABLE[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); + DISPATCH_TABLE[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); + DISPATCH_TABLE[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); + DISPATCH_TABLE[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); + DISPATCH_TABLE[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RLA", intShort); + DISPATCH_TABLE[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_JR_N", intShort); + DISPATCH_TABLE[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); + DISPATCH_TABLE[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_DE", intShort); // TODO: unify + DISPATCH_TABLE[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); + DISPATCH_TABLE[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); + DISPATCH_TABLE[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); + DISPATCH_TABLE[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); + DISPATCH_TABLE[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RRA", intShort); + DISPATCH_TABLE[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); + DISPATCH_TABLE[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); + DISPATCH_TABLE[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_HL", intShort); // TODO: unify??? + DISPATCH_TABLE[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); + DISPATCH_TABLE[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); + DISPATCH_TABLE[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); + DISPATCH_TABLE[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); + DISPATCH_TABLE[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_DAA", intShort); + DISPATCH_TABLE[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); + DISPATCH_TABLE[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); + DISPATCH_TABLE[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_HL_REF_NN", intShort); // TODO: unify ??? + DISPATCH_TABLE[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); + DISPATCH_TABLE[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); + DISPATCH_TABLE[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); + DISPATCH_TABLE[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); + DISPATCH_TABLE[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_CPL", intShort); + DISPATCH_TABLE[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); + DISPATCH_TABLE[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); + DISPATCH_TABLE[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_A", intShort); // TODO: unify + DISPATCH_TABLE[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); + DISPATCH_TABLE[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); + DISPATCH_TABLE[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); + DISPATCH_TABLE[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); + DISPATCH_TABLE[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SCF", intShort); + DISPATCH_TABLE[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); + DISPATCH_TABLE[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); + DISPATCH_TABLE[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_NN", intShort); // TODO: unify + DISPATCH_TABLE[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); + DISPATCH_TABLE[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); + DISPATCH_TABLE[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); + DISPATCH_TABLE[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); + DISPATCH_TABLE[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_CCF", intShort); + DISPATCH_TABLE[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_HALT", intShort); + DISPATCH_TABLE[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); + DISPATCH_TABLE[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); // TODO: ADD R, R + DISPATCH_TABLE[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); + DISPATCH_TABLE[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); + DISPATCH_TABLE[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); + DISPATCH_TABLE[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); + DISPATCH_TABLE[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); + DISPATCH_TABLE[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); + DISPATCH_TABLE[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); + DISPATCH_TABLE[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); + DISPATCH_TABLE[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); + DISPATCH_TABLE[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); + DISPATCH_TABLE[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); + DISPATCH_TABLE[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); + DISPATCH_TABLE[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); + DISPATCH_TABLE[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); + DISPATCH_TABLE[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); + DISPATCH_TABLE[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); + DISPATCH_TABLE[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); + DISPATCH_TABLE[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); + DISPATCH_TABLE[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); + DISPATCH_TABLE[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); + DISPATCH_TABLE[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); + DISPATCH_TABLE[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); + DISPATCH_TABLE[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); + DISPATCH_TABLE[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); + DISPATCH_TABLE[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); + DISPATCH_TABLE[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); + DISPATCH_TABLE[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); + DISPATCH_TABLE[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); + DISPATCH_TABLE[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); + DISPATCH_TABLE[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); + DISPATCH_TABLE[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); + DISPATCH_TABLE[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); + DISPATCH_TABLE[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); + DISPATCH_TABLE[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); + DISPATCH_TABLE[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); + DISPATCH_TABLE[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); + DISPATCH_TABLE[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); + DISPATCH_TABLE[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); + DISPATCH_TABLE[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); + DISPATCH_TABLE[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); + DISPATCH_TABLE[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); + DISPATCH_TABLE[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); + DISPATCH_TABLE[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); + DISPATCH_TABLE[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); + DISPATCH_TABLE[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); + DISPATCH_TABLE[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); + DISPATCH_TABLE[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); + DISPATCH_TABLE[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); + DISPATCH_TABLE[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); + DISPATCH_TABLE[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); + DISPATCH_TABLE[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); + DISPATCH_TABLE[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); + DISPATCH_TABLE[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); + DISPATCH_TABLE[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); + DISPATCH_TABLE[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); + DISPATCH_TABLE[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); + DISPATCH_TABLE[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); + DISPATCH_TABLE[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); + DISPATCH_TABLE[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); + DISPATCH_TABLE[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); + DISPATCH_TABLE[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); + DISPATCH_TABLE[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); + DISPATCH_TABLE[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); + DISPATCH_TABLE[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); + DISPATCH_TABLE[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", intShort); + DISPATCH_TABLE[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); + DISPATCH_TABLE[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_JP_NN", intShort); + DISPATCH_TABLE[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); + DISPATCH_TABLE[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", intShort); + DISPATCH_TABLE[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_N", intShort); + DISPATCH_TABLE[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); + DISPATCH_TABLE[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); + DISPATCH_TABLE[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_RET", intShort); + DISPATCH_TABLE[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); + DISPATCH_TABLE[0xCB] = lookup.findVirtual(EmulatorEngine.class, "CB_DISPATCH", intShort); + DISPATCH_TABLE[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); + DISPATCH_TABLE[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_NN", intShort); + DISPATCH_TABLE[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_N", intShort); + DISPATCH_TABLE[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); + DISPATCH_TABLE[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); + DISPATCH_TABLE[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", intShort); + DISPATCH_TABLE[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); + DISPATCH_TABLE[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_N_A", intShort); + DISPATCH_TABLE[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); + DISPATCH_TABLE[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", intShort); + DISPATCH_TABLE[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_N", intShort); + DISPATCH_TABLE[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); + DISPATCH_TABLE[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); + DISPATCH_TABLE[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_EXX", intShort); + DISPATCH_TABLE[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); + DISPATCH_TABLE[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_IN_A_REF_N", intShort); + DISPATCH_TABLE[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); + DISPATCH_TABLE[0xDD] = lookup.findVirtual(EmulatorEngine.class, "DD_DISPATCH", intShort); + DISPATCH_TABLE[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_N", intShort); + DISPATCH_TABLE[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); + DISPATCH_TABLE[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); + DISPATCH_TABLE[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", intShort); + DISPATCH_TABLE[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); + DISPATCH_TABLE[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_HL", intShort); // TODO: unify ??? + DISPATCH_TABLE[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); + DISPATCH_TABLE[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", intShort); + DISPATCH_TABLE[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_N", intShort); + DISPATCH_TABLE[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); + DISPATCH_TABLE[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); + DISPATCH_TABLE[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_HL", intShort); + DISPATCH_TABLE[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); + DISPATCH_TABLE[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_EX_DE_HL", intShort); // TODO: union??? + DISPATCH_TABLE[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); + DISPATCH_TABLE[0xED] = lookup.findVirtual(EmulatorEngine.class, "ED_DISPATCH", intShort); + DISPATCH_TABLE[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_N", intShort); + DISPATCH_TABLE[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); + DISPATCH_TABLE[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); + DISPATCH_TABLE[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", intShort); + DISPATCH_TABLE[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); + DISPATCH_TABLE[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_DI", intShort); + DISPATCH_TABLE[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); + DISPATCH_TABLE[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", intShort); + DISPATCH_TABLE[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_N", intShort); + DISPATCH_TABLE[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); + DISPATCH_TABLE[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); + DISPATCH_TABLE[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_HL", intShort); + DISPATCH_TABLE[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); + DISPATCH_TABLE[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_EI", intShort); + DISPATCH_TABLE[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); + DISPATCH_TABLE[0xFD] = lookup.findVirtual(EmulatorEngine.class, "FD_DISPATCH", intShort); + DISPATCH_TABLE[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_N", intShort); + DISPATCH_TABLE[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); + + DISPATCH_TABLE_ED[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); + DISPATCH_TABLE_ED[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); + DISPATCH_TABLE_ED[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", intShort); + DISPATCH_TABLE_ED[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", intShort); + DISPATCH_TABLE_ED[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); + DISPATCH_TABLE_ED[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); + DISPATCH_TABLE_ED[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", intShort); + DISPATCH_TABLE_ED[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_I_A", intShort); + DISPATCH_TABLE_ED[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); + DISPATCH_TABLE_ED[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); + DISPATCH_TABLE_ED[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", intShort); + DISPATCH_TABLE_ED[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", intShort); + DISPATCH_TABLE_ED[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); + DISPATCH_TABLE_ED[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_RETI", intShort); + DISPATCH_TABLE_ED[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", intShort); // im 0/1 + DISPATCH_TABLE_ED[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_A", intShort); + DISPATCH_TABLE_ED[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); + DISPATCH_TABLE_ED[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); + DISPATCH_TABLE_ED[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", intShort); + DISPATCH_TABLE_ED[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", intShort); + DISPATCH_TABLE_ED[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); + DISPATCH_TABLE_ED[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); + DISPATCH_TABLE_ED[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_IM_1", intShort); + DISPATCH_TABLE_ED[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_I", intShort); + DISPATCH_TABLE_ED[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); + DISPATCH_TABLE_ED[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); + DISPATCH_TABLE_ED[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", intShort); + DISPATCH_TABLE_ED[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", intShort); + DISPATCH_TABLE_ED[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); + DISPATCH_TABLE_ED[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); + DISPATCH_TABLE_ED[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_2", intShort); + DISPATCH_TABLE_ED[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_R", intShort); + DISPATCH_TABLE_ED[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); + DISPATCH_TABLE_ED[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); + DISPATCH_TABLE_ED[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", intShort); + DISPATCH_TABLE_ED[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", intShort); + DISPATCH_TABLE_ED[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); + DISPATCH_TABLE_ED[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); + DISPATCH_TABLE_ED[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", intShort); + DISPATCH_TABLE_ED[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_RRD", intShort); + DISPATCH_TABLE_ED[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); + DISPATCH_TABLE_ED[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); + DISPATCH_TABLE_ED[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", intShort); + DISPATCH_TABLE_ED[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", intShort); + DISPATCH_TABLE_ED[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); + DISPATCH_TABLE_ED[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); + DISPATCH_TABLE_ED[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", intShort); // im 0/1 + DISPATCH_TABLE_ED[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_RLD", intShort); + DISPATCH_TABLE_ED[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_IN_REF_C", intShort); + DISPATCH_TABLE_ED[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_0", intShort); + DISPATCH_TABLE_ED[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", intShort); + DISPATCH_TABLE_ED[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", intShort); + DISPATCH_TABLE_ED[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); + DISPATCH_TABLE_ED[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); + DISPATCH_TABLE_ED[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_IM_1", intShort); + DISPATCH_TABLE_ED[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); + DISPATCH_TABLE_ED[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); + DISPATCH_TABLE_ED[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", intShort); + DISPATCH_TABLE_ED[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", intShort); + DISPATCH_TABLE_ED[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); + DISPATCH_TABLE_ED[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); + DISPATCH_TABLE_ED[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_2", intShort); + DISPATCH_TABLE_ED[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_LDI", intShort); + DISPATCH_TABLE_ED[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_CPI", intShort); + DISPATCH_TABLE_ED[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_INI", intShort); + DISPATCH_TABLE_ED[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_OUTI", intShort); + DISPATCH_TABLE_ED[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_LDD", intShort); + DISPATCH_TABLE_ED[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_CPD", intShort); + DISPATCH_TABLE_ED[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_IND", intShort); + DISPATCH_TABLE_ED[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_OUTD", intShort); + DISPATCH_TABLE_ED[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_LDIR", intShort); + DISPATCH_TABLE_ED[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_CPIR", intShort); + DISPATCH_TABLE_ED[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_INIR", intShort); + DISPATCH_TABLE_ED[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OTIR", intShort); + DISPATCH_TABLE_ED[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_LDDR", intShort); + DISPATCH_TABLE_ED[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CPDR", intShort); + DISPATCH_TABLE_ED[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_INDR", intShort); + DISPATCH_TABLE_ED[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_OTDR", intShort); + + DISPATCH_TABLE_CB[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); + DISPATCH_TABLE_CB[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); + DISPATCH_TABLE_CB[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); + DISPATCH_TABLE_CB[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); + DISPATCH_TABLE_CB[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); + DISPATCH_TABLE_CB[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); + DISPATCH_TABLE_CB[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); + DISPATCH_TABLE_CB[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); + DISPATCH_TABLE_CB[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); + DISPATCH_TABLE_CB[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); + DISPATCH_TABLE_CB[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); + DISPATCH_TABLE_CB[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); + DISPATCH_TABLE_CB[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); + DISPATCH_TABLE_CB[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); + DISPATCH_TABLE_CB[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); + DISPATCH_TABLE_CB[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); + DISPATCH_TABLE_CB[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); + DISPATCH_TABLE_CB[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); + DISPATCH_TABLE_CB[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); + DISPATCH_TABLE_CB[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); + DISPATCH_TABLE_CB[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); + DISPATCH_TABLE_CB[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); + DISPATCH_TABLE_CB[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); + DISPATCH_TABLE_CB[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); + DISPATCH_TABLE_CB[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); + DISPATCH_TABLE_CB[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); + DISPATCH_TABLE_CB[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); + DISPATCH_TABLE_CB[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); + DISPATCH_TABLE_CB[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); + DISPATCH_TABLE_CB[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); + DISPATCH_TABLE_CB[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); + DISPATCH_TABLE_CB[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); + DISPATCH_TABLE_CB[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); + DISPATCH_TABLE_CB[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); + DISPATCH_TABLE_CB[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); + DISPATCH_TABLE_CB[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); + DISPATCH_TABLE_CB[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); + DISPATCH_TABLE_CB[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); + DISPATCH_TABLE_CB[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); + DISPATCH_TABLE_CB[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); + DISPATCH_TABLE_CB[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); + DISPATCH_TABLE_CB[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); + DISPATCH_TABLE_CB[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); + DISPATCH_TABLE_CB[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); + DISPATCH_TABLE_CB[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); + DISPATCH_TABLE_CB[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); + DISPATCH_TABLE_CB[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); + DISPATCH_TABLE_CB[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); + DISPATCH_TABLE_CB[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); + DISPATCH_TABLE_CB[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); + DISPATCH_TABLE_CB[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); + DISPATCH_TABLE_CB[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); + DISPATCH_TABLE_CB[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); + DISPATCH_TABLE_CB[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); + DISPATCH_TABLE_CB[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); + DISPATCH_TABLE_CB[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); + DISPATCH_TABLE_CB[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); + DISPATCH_TABLE_CB[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); + DISPATCH_TABLE_CB[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); + DISPATCH_TABLE_CB[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); + DISPATCH_TABLE_CB[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); + DISPATCH_TABLE_CB[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); + DISPATCH_TABLE_CB[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); + DISPATCH_TABLE_CB[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); + DISPATCH_TABLE_CB[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); + DISPATCH_TABLE_CB[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); + DISPATCH_TABLE_CB[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xCB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xDD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xED] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xFD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + + DISPATCH_TABLE_DD[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", intShort); + DISPATCH_TABLE_DD[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", intShort); + DISPATCH_TABLE_DD[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IX_NN", intShort); + DISPATCH_TABLE_DD[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_IX", intShort); + DISPATCH_TABLE_DD[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IX", intShort); + DISPATCH_TABLE_DD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: inc ixh + DISPATCH_TABLE_DD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: dec ixh + DISPATCH_TABLE_DD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,* + DISPATCH_TABLE_DD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", intShort); + DISPATCH_TABLE_DD[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IX_REF_NN", intShort); + DISPATCH_TABLE_DD[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IX", intShort); + DISPATCH_TABLE_DD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: inc ixl + DISPATCH_TABLE_DD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: dec ixl + DISPATCH_TABLE_DD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,* + DISPATCH_TABLE_DD[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_N", intShort); + DISPATCH_TABLE_DD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", intShort); + DISPATCH_TABLE_DD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld b,ixh + DISPATCH_TABLE_DD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld b,ixl + DISPATCH_TABLE_DD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld c,ixh + DISPATCH_TABLE_DD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld c,ixl + DISPATCH_TABLE_DD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld d,ixh + DISPATCH_TABLE_DD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld d,ixl + DISPATCH_TABLE_DD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld e,ixh + DISPATCH_TABLE_DD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld e,ixl + DISPATCH_TABLE_DD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,b + DISPATCH_TABLE_DD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,c + DISPATCH_TABLE_DD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,d + DISPATCH_TABLE_DD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,e + DISPATCH_TABLE_DD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,ixh + DISPATCH_TABLE_DD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,ixl + DISPATCH_TABLE_DD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,a + DISPATCH_TABLE_DD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,b + DISPATCH_TABLE_DD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,c + DISPATCH_TABLE_DD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,d + DISPATCH_TABLE_DD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,e + DISPATCH_TABLE_DD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,ixh + DISPATCH_TABLE_DD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,ixl + DISPATCH_TABLE_DD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,a + DISPATCH_TABLE_DD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); + DISPATCH_TABLE_DD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); + DISPATCH_TABLE_DD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); + DISPATCH_TABLE_DD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); + DISPATCH_TABLE_DD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); + DISPATCH_TABLE_DD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); + DISPATCH_TABLE_DD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); + DISPATCH_TABLE_DD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld a,ixh + DISPATCH_TABLE_DD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld a,ixl + DISPATCH_TABLE_DD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: add a,ixh + DISPATCH_TABLE_DD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: add a,ixl + DISPATCH_TABLE_DD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: adc a,ixh + DISPATCH_TABLE_DD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: adc a,ixl + DISPATCH_TABLE_DD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sub ixh + DISPATCH_TABLE_DD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sub ixl + DISPATCH_TABLE_DD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sbc a,ixh + DISPATCH_TABLE_DD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sbc a,ixl + DISPATCH_TABLE_DD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: and ixh + DISPATCH_TABLE_DD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: and ixl + DISPATCH_TABLE_DD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: xor ixh + DISPATCH_TABLE_DD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: xor ixl + DISPATCH_TABLE_DD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: or ixh + DISPATCH_TABLE_DD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: or ixl + DISPATCH_TABLE_DD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: cp ixh + DISPATCH_TABLE_DD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: cp ixl + DISPATCH_TABLE_DD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IX_N", intShort); + DISPATCH_TABLE_DD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "DD_CB_DISPATCH", intShort); + DISPATCH_TABLE_DD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IX", intShort); + DISPATCH_TABLE_DD[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_IX", intShort); + DISPATCH_TABLE_DD[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_IX", intShort); + DISPATCH_TABLE_DD[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_IX", intShort); + DISPATCH_TABLE_DD[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_IX", intShort); + + DISPATCH_TABLE_FD[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", intShort); + DISPATCH_TABLE_FD[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", intShort); + DISPATCH_TABLE_FD[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IY_NN", intShort); + DISPATCH_TABLE_FD[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_IY", intShort); + DISPATCH_TABLE_FD[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IY", intShort); + DISPATCH_TABLE_FD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: inc iyh + DISPATCH_TABLE_FD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: dec iyh + DISPATCH_TABLE_FD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,* + DISPATCH_TABLE_FD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", intShort); + DISPATCH_TABLE_FD[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IY_REF_NN", intShort); + DISPATCH_TABLE_FD[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IY", intShort); + DISPATCH_TABLE_FD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: inc iyl + DISPATCH_TABLE_FD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: dec iyl + DISPATCH_TABLE_FD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,* + DISPATCH_TABLE_FD[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_N", intShort); + DISPATCH_TABLE_FD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", intShort); + DISPATCH_TABLE_FD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld b,iyh + DISPATCH_TABLE_FD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld b,iyl + DISPATCH_TABLE_FD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld c,iyh + DISPATCH_TABLE_FD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld c,iyl + DISPATCH_TABLE_FD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld d,iyh + DISPATCH_TABLE_FD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld d,iyl + DISPATCH_TABLE_FD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld e,iyh + DISPATCH_TABLE_FD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld e,iyl + DISPATCH_TABLE_FD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,b + DISPATCH_TABLE_FD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,c + DISPATCH_TABLE_FD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,d + DISPATCH_TABLE_FD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,e + DISPATCH_TABLE_FD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,iyh + DISPATCH_TABLE_FD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,iyl + DISPATCH_TABLE_FD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,a + DISPATCH_TABLE_FD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,b + DISPATCH_TABLE_FD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,c + DISPATCH_TABLE_FD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,d + DISPATCH_TABLE_FD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,e + DISPATCH_TABLE_FD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,iyh + DISPATCH_TABLE_FD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,iyl + DISPATCH_TABLE_FD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,a + DISPATCH_TABLE_FD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); + DISPATCH_TABLE_FD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); + DISPATCH_TABLE_FD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); + DISPATCH_TABLE_FD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); + DISPATCH_TABLE_FD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); + DISPATCH_TABLE_FD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); + DISPATCH_TABLE_FD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); + DISPATCH_TABLE_FD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld a,iyh + DISPATCH_TABLE_FD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld a,iyl + DISPATCH_TABLE_FD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: add a,iyh + DISPATCH_TABLE_FD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: add a,iyl + DISPATCH_TABLE_FD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: adc a,iyh + DISPATCH_TABLE_FD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: adc a,iyl + DISPATCH_TABLE_FD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sub iyh + DISPATCH_TABLE_FD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sub iyl + DISPATCH_TABLE_FD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sbc a,iyh + DISPATCH_TABLE_FD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sbc a,iyl + DISPATCH_TABLE_FD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: and iyh + DISPATCH_TABLE_FD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: and iyl + DISPATCH_TABLE_FD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: xor iyh + DISPATCH_TABLE_FD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: xor iyl + DISPATCH_TABLE_FD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: or iyh + DISPATCH_TABLE_FD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: or iyl + DISPATCH_TABLE_FD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: cp iyh + DISPATCH_TABLE_FD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: cp iyl + DISPATCH_TABLE_FD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IY_N", intShort); + DISPATCH_TABLE_FD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "FD_CB_DISPATCH", intShort); + DISPATCH_TABLE_FD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IY", intShort); + DISPATCH_TABLE_FD[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_IY", intShort); + DISPATCH_TABLE_FD[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_IY", intShort); + DISPATCH_TABLE_FD[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_IY", intShort); + DISPATCH_TABLE_FD[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_IY", intShort); + + DISPATCH_TABLE_DD_CB[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); + DISPATCH_TABLE_DD_CB[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xCB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xDD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xED] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xFD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + + DISPATCH_TABLE_FD_CB[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); + DISPATCH_TABLE_FD_CB[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xCB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xDD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xED] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xFD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + } catch (IllegalAccessException | NoSuchMethodException e) { + LOGGER.error("Could not set up dispatch table. The emulator won't work correctly", e); + } + } +} diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index b267f6f8f..002fd07d4 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -29,14 +29,15 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; +import java.lang.invoke.MethodHandle; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.LockSupport; +import static net.emustudio.plugins.cpu.zilogZ80.DispatchTables.*; + /** * Main implementation class for CPU emulation CPU works in a separate thread * (parallel with other hardware) @@ -138,9 +139,13 @@ CPU.RunState step() throws Exception { boolean oldIFF = IFF[0]; noWait = false; currentRunState = CPU.RunState.STATE_STOPPED_BREAK; - short opcode = memory.read(PC); + short opcode = (short)(memory.read(PC) & 0xFF); PC = (PC + 1) & 0xFFFF; - dispatch(opcode); + try { + dispatch(opcode); + } catch (Throwable e) { + throw new Exception(e); + } isINT = (interruptPending != 0) && oldIFF && IFF[0]; if (PC > 0xffff) { PC = 0xffff; @@ -171,20 +176,17 @@ public CPU.RunState run(CPU cpu) { if (cpu.isBreakpointSet(PC)) { throw new Breakpoint(); } - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - LOGGER.debug("Unexpected error", e); - if (e.getCause() != null && e.getCause() instanceof IndexOutOfBoundsException) { - return CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; - } - return CPU.RunState.STATE_STOPPED_BAD_INSTR; + } catch (Breakpoint e) { + return CPU.RunState.STATE_STOPPED_BREAK; } catch (IndexOutOfBoundsException e) { LOGGER.debug("Unexpected error", e); return CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; } catch (IOException e) { LOGGER.error("Unexpected error", e); return RunState.STATE_STOPPED_BAD_INSTR; - } catch (Breakpoint e) { - return CPU.RunState.STATE_STOPPED_BREAK; + } catch (Throwable e) { + LOGGER.debug("Unexpected error", e); + return CPU.RunState.STATE_STOPPED_BAD_INSTR; } } endTime = System.nanoTime() - startTime; @@ -196,6 +198,92 @@ public CPU.RunState run(CPU cpu) { return currentRunState; } + private int dispatch(short OP) throws Throwable { + int tmp, tmp1, tmp2, tmp3; + short special = 0; // prefix if available = 0xDD or 0xFD + + DispatchListener tmpListener = dispatchListener; + if (tmpListener != null) { + tmpListener.beforeDispatch(); + } + + try { + /* if interrupt is waiting, instruction won't be read from memory + * but from one or all of 3 bytes (b1,b2,b3) which represents either + * rst or call instruction incomed from external peripheral device + */ + if (isINT) { + return doInterrupt(); + } + incrementR(); + + /* Dispatch Instruction */ + MethodHandle instr = DISPATCH_TABLE[OP]; + if (instr != null) { + return (int) instr.invokeExact(this, OP); + } + currentRunState = CPU.RunState.STATE_STOPPED_BAD_INSTR; + } finally { + if (tmpListener != null) { + tmpListener.afterDispatch(); + } + } + return 0; + } + + int CB_DISPATCH(short OP) throws Throwable { + return DISPATCH(DISPATCH_TABLE_CB); + } + + int DD_DISPATCH(short OP) throws Throwable { + return DISPATCH(DISPATCH_TABLE_DD); + } + + int DD_CB_DISPATCH(short OP) throws Throwable { + return SPECIAL_CB_DISPATCH(DISPATCH_TABLE_DD_CB); + } + + int ED_DISPATCH(short OP) throws Throwable { + return DISPATCH(DISPATCH_TABLE_ED); + } + + int FD_DISPATCH(short OP) throws Throwable { + return DISPATCH(DISPATCH_TABLE_FD); + } + + int FD_CB_DISPATCH(short OP) throws Throwable { + return SPECIAL_CB_DISPATCH(DISPATCH_TABLE_FD_CB); + } + + private int DISPATCH(MethodHandle[] table) throws Throwable { + short OP = (short)(memory.read(PC) & 0xFF); + incrementR(); + PC = (PC + 1) & 0xFFFF; + + MethodHandle instr = table[OP]; + if (instr != null) { + return (int) instr.invokeExact(this, OP); + } + currentRunState = RunState.STATE_STOPPED_BAD_INSTR; + return 0; + } + + int SPECIAL_CB_DISPATCH(MethodHandle[] table) throws Throwable { + byte operand = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + + short OP = (short)(memory.read(PC) & 0xFF); + PC = (PC + 1) & 0xFFFF; + incrementR(); + + MethodHandle instr = table[OP]; + if (instr != null) { + return (int) instr.invokeExact(this, OP, operand); + } + currentRunState = RunState.STATE_STOPPED_BAD_INSTR; + return 0; + } + void setInterrupt(DeviceContext device, int mask) { this.interruptDevice = device; this.interruptPending |= mask; @@ -214,18 +302,54 @@ void setInterruptVector(byte[] vector) { this.interruptVector = vector[0]; } + private int doInterrupt() throws Throwable { + isINT = false; + int cycles = 0; + + if (!noWait) { + cycles += 14; + } +// if (interruptDevice != null) { + // interruptDevice.setInterrupt(1); + // } + IFF[0] = IFF[1] = false; + switch (intMode) { + case 0: // rst p (interruptVector) + cycles += 11; + RunState old_runstate = currentRunState; + dispatch((short) interruptVector); // must ignore halt + if (currentRunState == RunState.STATE_STOPPED_NORMAL) { + currentRunState = old_runstate; + } + break; + case 1: // rst 0xFF + cycles += 12; + writeWord((SP - 2) & 0xFFFF, PC); + SP = (SP - 2) & 0xffff; + PC = 0xFF & 0x38; + break; + case 2: + cycles += 13; + writeWord((SP - 2) & 0xFFFF, PC); + PC = readWord((I << 8) | interruptVector); + break; + } + return cycles; + } + + private int getreg(int reg) { if (reg == 6) { - return memory.read((regs[REG_H] << 8) | regs[REG_L]); + return readByte((regs[REG_H] << 8) | regs[REG_L]); } return regs[reg]; } - private int getreg2(int reg) { + private byte getreg2(int reg) { if (reg == 6) { return 0; } - return regs[reg]; + return (byte)regs[reg]; } private void putreg(int reg, int val) { @@ -293,9 +417,6 @@ private boolean getCC1(int cc) { return false; } - /** - * Put a value into IX/IY register - */ private void putspecial(short spec, int val) { val &= 0xFFFF; switch (spec) { @@ -331,49 +452,13 @@ private void writeWord(int address, int value) { memory.write(address, new Byte[]{(byte) (value & 0xFF), (byte) ((value >>> 8) & 0xFF)}, 2); } - private int doInterrupt() throws IOException, InvocationTargetException, IllegalAccessException { - isINT = false; - int cycles = 0; - - if (!noWait) { - cycles += 14; - } -// if (interruptDevice != null) { - // interruptDevice.setInterrupt(1); - // } - IFF[0] = IFF[1] = false; - switch (intMode) { - case 0: // rst p (interruptVector) - cycles += 11; - RunState old_runstate = currentRunState; - dispatch((short) interruptVector); // must ignore halt - if (currentRunState == RunState.STATE_STOPPED_NORMAL) { - currentRunState = old_runstate; - } - break; - case 1: // rst 0xFF - cycles += 12; - writeWord((SP - 2) & 0xFFFF, PC); - SP = (SP - 2) & 0xffff; - PC = 0xFF & 0x38; - break; - case 2: - cycles += 13; - writeWord((SP - 2) & 0xFFFF, PC); - PC = readWord((I << 8) | interruptVector); - break; - } - return cycles; - } + private int flagSZHPC(int a, int b, int sum) { + int carryOut = (a > 0xFF - b) ? FLAG_C : 0; + int carryIns = sum ^ a ^ b; + int halfCarryOut = (carryIns >> 4) & 1; + int overflowOut = (((carryIns >> 7) ^ carryOut) != 0) ? FLAG_PV : 0; - private void overflow(int i, int j, int result) { - int signFirst = i & 0x80; - int signSecond = j & 0x80; - if (signFirst != signSecond) { - flags &= (~FLAG_PV); - } else if ((result & 0x80) != signFirst) { - flags |= FLAG_PV; - } + return carryOut | (halfCarryOut << 4) | (overflowOut) | (sum == 0 ? FLAG_Z : 0) | (sum & 0x80); } private void bigOverflow(int i, int j, int result) { @@ -385,16 +470,10 @@ private void bigOverflow(int i, int j, int result) { } } - private void auxCarry(int before, int sumWith) { - int mask = sumWith & before; - int xormask = sumWith ^ before; - - int C0 = mask & 1; - int C1 = ((mask >>> 1) ^ (C0 & (xormask >>> 1))) & 1; - int C2 = ((mask >>> 2) ^ (C1 & (xormask >>> 2))) & 1; - int C3 = ((mask >>> 3) ^ (C2 & (xormask >>> 3))) & 1; - - if (C3 != 0) { + private void auxCarry(int a, int b) { + int carryIns = ((a + b) & 0xFF) ^ a ^ b; + int halfCarryOut = (carryIns >> 4) & 1; + if (halfCarryOut != 0) { flags |= FLAG_H; } else { flags &= (~FLAG_H); @@ -458,371 +537,22 @@ private void incrementR() { } - private final static Method[] DISPATCH_TABLE = new Method[256]; - private final static Method[] DISPATCH_TABLE_ED = new Method[256]; - private final static Method[] DISPATCH_TABLE_DD_FD = new Method[256]; - - static { - try { - DISPATCH_TABLE[0x00] = EmulatorEngine.class.getDeclaredMethod("O0_NOP", short.class); - DISPATCH_TABLE[0x02] = EmulatorEngine.class.getDeclaredMethod("O2_LD_LPAR_BC_RPAR__A", short.class); - DISPATCH_TABLE[0x03] = EmulatorEngine.class.getDeclaredMethod("INC_SS", short.class); - DISPATCH_TABLE[0x13] = EmulatorEngine.class.getDeclaredMethod("INC_SS", short.class); - DISPATCH_TABLE[0x23] = EmulatorEngine.class.getDeclaredMethod("INC_SS", short.class); - DISPATCH_TABLE[0x33] = EmulatorEngine.class.getDeclaredMethod("INC_SS", short.class); - - DISPATCH_TABLE[0x09] = EmulatorEngine.class.getDeclaredMethod("ADD_HL_SS", short.class); - DISPATCH_TABLE[0x19] = EmulatorEngine.class.getDeclaredMethod("ADD_HL_SS", short.class); - DISPATCH_TABLE[0x29] = EmulatorEngine.class.getDeclaredMethod("ADD_HL_SS", short.class); - DISPATCH_TABLE[0x39] = EmulatorEngine.class.getDeclaredMethod("ADD_HL_SS", short.class); - - DISPATCH_TABLE[0x01] = EmulatorEngine.class.getDeclaredMethod("LD_SS_NN", short.class); - DISPATCH_TABLE[0x11] = EmulatorEngine.class.getDeclaredMethod("LD_SS_NN", short.class); - DISPATCH_TABLE[0x21] = EmulatorEngine.class.getDeclaredMethod("LD_SS_NN", short.class); - DISPATCH_TABLE[0x31] = EmulatorEngine.class.getDeclaredMethod("LD_SS_NN", short.class); - - DISPATCH_TABLE[0x0B] = EmulatorEngine.class.getDeclaredMethod("DEC_SS", short.class); - DISPATCH_TABLE[0x1B] = EmulatorEngine.class.getDeclaredMethod("DEC_SS", short.class); - DISPATCH_TABLE[0x2B] = EmulatorEngine.class.getDeclaredMethod("DEC_SS", short.class); - DISPATCH_TABLE[0x3B] = EmulatorEngine.class.getDeclaredMethod("DEC_SS", short.class); - - DISPATCH_TABLE[0xC1] = EmulatorEngine.class.getDeclaredMethod("POP_QQ", short.class); - DISPATCH_TABLE[0xD1] = EmulatorEngine.class.getDeclaredMethod("POP_QQ", short.class); - DISPATCH_TABLE[0xE1] = EmulatorEngine.class.getDeclaredMethod("POP_QQ", short.class); - DISPATCH_TABLE[0xF1] = EmulatorEngine.class.getDeclaredMethod("POP_QQ", short.class); - - DISPATCH_TABLE[0xC5] = EmulatorEngine.class.getDeclaredMethod("PUSH_QQ", short.class); - DISPATCH_TABLE[0xD5] = EmulatorEngine.class.getDeclaredMethod("PUSH_QQ", short.class); - DISPATCH_TABLE[0xE5] = EmulatorEngine.class.getDeclaredMethod("PUSH_QQ", short.class); - DISPATCH_TABLE[0xF5] = EmulatorEngine.class.getDeclaredMethod("PUSH_QQ", short.class); - - DISPATCH_TABLE[0x06] = EmulatorEngine.class.getDeclaredMethod("LD_R_N", short.class); - DISPATCH_TABLE[0x0E] = EmulatorEngine.class.getDeclaredMethod("LD_R_N", short.class); - DISPATCH_TABLE[0x16] = EmulatorEngine.class.getDeclaredMethod("LD_R_N", short.class); - DISPATCH_TABLE[0x1E] = EmulatorEngine.class.getDeclaredMethod("LD_R_N", short.class); - DISPATCH_TABLE[0x26] = EmulatorEngine.class.getDeclaredMethod("LD_R_N", short.class); - DISPATCH_TABLE[0x2E] = EmulatorEngine.class.getDeclaredMethod("LD_R_N", short.class); - DISPATCH_TABLE[0x36] = EmulatorEngine.class.getDeclaredMethod("LD_R_N", short.class); - DISPATCH_TABLE[0x3E] = EmulatorEngine.class.getDeclaredMethod("LD_R_N", short.class); - - DISPATCH_TABLE[0x04] = EmulatorEngine.class.getDeclaredMethod("INC_R", short.class); - DISPATCH_TABLE[0x0C] = EmulatorEngine.class.getDeclaredMethod("INC_R", short.class); - DISPATCH_TABLE[0x14] = EmulatorEngine.class.getDeclaredMethod("INC_R", short.class); - DISPATCH_TABLE[0x1C] = EmulatorEngine.class.getDeclaredMethod("INC_R", short.class); - DISPATCH_TABLE[0x24] = EmulatorEngine.class.getDeclaredMethod("INC_R", short.class); - DISPATCH_TABLE[0x2C] = EmulatorEngine.class.getDeclaredMethod("INC_R", short.class); - DISPATCH_TABLE[0x34] = EmulatorEngine.class.getDeclaredMethod("INC_R", short.class); - DISPATCH_TABLE[0x3C] = EmulatorEngine.class.getDeclaredMethod("INC_R", short.class); - - DISPATCH_TABLE[0x05] = EmulatorEngine.class.getDeclaredMethod("DEC_R", short.class); - DISPATCH_TABLE[0x0D] = EmulatorEngine.class.getDeclaredMethod("DEC_R", short.class); - DISPATCH_TABLE[0x15] = EmulatorEngine.class.getDeclaredMethod("DEC_R", short.class); - DISPATCH_TABLE[0x1D] = EmulatorEngine.class.getDeclaredMethod("DEC_R", short.class); - DISPATCH_TABLE[0x25] = EmulatorEngine.class.getDeclaredMethod("DEC_R", short.class); - DISPATCH_TABLE[0x2D] = EmulatorEngine.class.getDeclaredMethod("DEC_R", short.class); - DISPATCH_TABLE[0x35] = EmulatorEngine.class.getDeclaredMethod("DEC_R", short.class); - DISPATCH_TABLE[0x3D] = EmulatorEngine.class.getDeclaredMethod("DEC_R", short.class); - - DISPATCH_TABLE[0xC0] = EmulatorEngine.class.getDeclaredMethod("RET_CC", short.class); - DISPATCH_TABLE[0xC8] = EmulatorEngine.class.getDeclaredMethod("RET_CC", short.class); - DISPATCH_TABLE[0xD0] = EmulatorEngine.class.getDeclaredMethod("RET_CC", short.class); - DISPATCH_TABLE[0xD8] = EmulatorEngine.class.getDeclaredMethod("RET_CC", short.class); - DISPATCH_TABLE[0xE0] = EmulatorEngine.class.getDeclaredMethod("RET_CC", short.class); - DISPATCH_TABLE[0xE8] = EmulatorEngine.class.getDeclaredMethod("RET_CC", short.class); - DISPATCH_TABLE[0xF0] = EmulatorEngine.class.getDeclaredMethod("RET_CC", short.class); - DISPATCH_TABLE[0xF8] = EmulatorEngine.class.getDeclaredMethod("RET_CC", short.class); - - DISPATCH_TABLE[0xC2] = EmulatorEngine.class.getDeclaredMethod("JP_CC_NN", short.class); - DISPATCH_TABLE[0xCA] = EmulatorEngine.class.getDeclaredMethod("JP_CC_NN", short.class); - DISPATCH_TABLE[0xD2] = EmulatorEngine.class.getDeclaredMethod("JP_CC_NN", short.class); - DISPATCH_TABLE[0xDA] = EmulatorEngine.class.getDeclaredMethod("JP_CC_NN", short.class); - DISPATCH_TABLE[0xE2] = EmulatorEngine.class.getDeclaredMethod("JP_CC_NN", short.class); - DISPATCH_TABLE[0xEA] = EmulatorEngine.class.getDeclaredMethod("JP_CC_NN", short.class); - DISPATCH_TABLE[0xF2] = EmulatorEngine.class.getDeclaredMethod("JP_CC_NN", short.class); - DISPATCH_TABLE[0xFA] = EmulatorEngine.class.getDeclaredMethod("JP_CC_NN", short.class); - - DISPATCH_TABLE[0xC4] = EmulatorEngine.class.getDeclaredMethod("CALL_CC_NN", short.class); - DISPATCH_TABLE[0xCC] = EmulatorEngine.class.getDeclaredMethod("CALL_CC_NN", short.class); - DISPATCH_TABLE[0xD4] = EmulatorEngine.class.getDeclaredMethod("CALL_CC_NN", short.class); - DISPATCH_TABLE[0xDC] = EmulatorEngine.class.getDeclaredMethod("CALL_CC_NN", short.class); - DISPATCH_TABLE[0xE4] = EmulatorEngine.class.getDeclaredMethod("CALL_CC_NN", short.class); - DISPATCH_TABLE[0xEC] = EmulatorEngine.class.getDeclaredMethod("CALL_CC_NN", short.class); - DISPATCH_TABLE[0xF4] = EmulatorEngine.class.getDeclaredMethod("CALL_CC_NN", short.class); - DISPATCH_TABLE[0xFC] = EmulatorEngine.class.getDeclaredMethod("CALL_CC_NN", short.class); - - DISPATCH_TABLE[0xC7] = EmulatorEngine.class.getDeclaredMethod("RST_P", short.class); - DISPATCH_TABLE[0xCF] = EmulatorEngine.class.getDeclaredMethod("RST_P", short.class); - DISPATCH_TABLE[0xD7] = EmulatorEngine.class.getDeclaredMethod("RST_P", short.class); - DISPATCH_TABLE[0xDF] = EmulatorEngine.class.getDeclaredMethod("RST_P", short.class); - DISPATCH_TABLE[0xE7] = EmulatorEngine.class.getDeclaredMethod("RST_P", short.class); - DISPATCH_TABLE[0xEF] = EmulatorEngine.class.getDeclaredMethod("RST_P", short.class); - DISPATCH_TABLE[0xF7] = EmulatorEngine.class.getDeclaredMethod("RST_P", short.class); - DISPATCH_TABLE[0xFF] = EmulatorEngine.class.getDeclaredMethod("RST_P", short.class); - - DISPATCH_TABLE[0x80] = EmulatorEngine.class.getDeclaredMethod("ADD_A_R", short.class); - DISPATCH_TABLE[0x81] = EmulatorEngine.class.getDeclaredMethod("ADD_A_R", short.class); - DISPATCH_TABLE[0x82] = EmulatorEngine.class.getDeclaredMethod("ADD_A_R", short.class); - DISPATCH_TABLE[0x83] = EmulatorEngine.class.getDeclaredMethod("ADD_A_R", short.class); - DISPATCH_TABLE[0x84] = EmulatorEngine.class.getDeclaredMethod("ADD_A_R", short.class); - DISPATCH_TABLE[0x85] = EmulatorEngine.class.getDeclaredMethod("ADD_A_R", short.class); - DISPATCH_TABLE[0x86] = EmulatorEngine.class.getDeclaredMethod("ADD_A_R", short.class); - DISPATCH_TABLE[0x87] = EmulatorEngine.class.getDeclaredMethod("ADD_A_R", short.class); - - DISPATCH_TABLE[0x88] = EmulatorEngine.class.getDeclaredMethod("ADC_A_R", short.class); - DISPATCH_TABLE[0x89] = EmulatorEngine.class.getDeclaredMethod("ADC_A_R", short.class); - DISPATCH_TABLE[0x8A] = EmulatorEngine.class.getDeclaredMethod("ADC_A_R", short.class); - DISPATCH_TABLE[0x8B] = EmulatorEngine.class.getDeclaredMethod("ADC_A_R", short.class); - DISPATCH_TABLE[0x8C] = EmulatorEngine.class.getDeclaredMethod("ADC_A_R", short.class); - DISPATCH_TABLE[0x8D] = EmulatorEngine.class.getDeclaredMethod("ADC_A_R", short.class); - DISPATCH_TABLE[0x8E] = EmulatorEngine.class.getDeclaredMethod("ADC_A_R", short.class); - DISPATCH_TABLE[0x8F] = EmulatorEngine.class.getDeclaredMethod("ADC_A_R", short.class); - - DISPATCH_TABLE[0x90] = EmulatorEngine.class.getDeclaredMethod("SUB_R", short.class); - DISPATCH_TABLE[0x91] = EmulatorEngine.class.getDeclaredMethod("SUB_R", short.class); - DISPATCH_TABLE[0x92] = EmulatorEngine.class.getDeclaredMethod("SUB_R", short.class); - DISPATCH_TABLE[0x93] = EmulatorEngine.class.getDeclaredMethod("SUB_R", short.class); - DISPATCH_TABLE[0x94] = EmulatorEngine.class.getDeclaredMethod("SUB_R", short.class); - DISPATCH_TABLE[0x95] = EmulatorEngine.class.getDeclaredMethod("SUB_R", short.class); - DISPATCH_TABLE[0x96] = EmulatorEngine.class.getDeclaredMethod("SUB_R", short.class); - DISPATCH_TABLE[0x97] = EmulatorEngine.class.getDeclaredMethod("SUB_R", short.class); - - DISPATCH_TABLE[0x98] = EmulatorEngine.class.getDeclaredMethod("SBC_A_R", short.class); - DISPATCH_TABLE[0x99] = EmulatorEngine.class.getDeclaredMethod("SBC_A_R", short.class); - DISPATCH_TABLE[0x9A] = EmulatorEngine.class.getDeclaredMethod("SBC_A_R", short.class); - DISPATCH_TABLE[0x9B] = EmulatorEngine.class.getDeclaredMethod("SBC_A_R", short.class); - DISPATCH_TABLE[0x9C] = EmulatorEngine.class.getDeclaredMethod("SBC_A_R", short.class); - DISPATCH_TABLE[0x9D] = EmulatorEngine.class.getDeclaredMethod("SBC_A_R", short.class); - DISPATCH_TABLE[0x9E] = EmulatorEngine.class.getDeclaredMethod("SBC_A_R", short.class); - DISPATCH_TABLE[0x9F] = EmulatorEngine.class.getDeclaredMethod("SBC_A_R", short.class); - - DISPATCH_TABLE[0xA0] = EmulatorEngine.class.getDeclaredMethod("AND_R", short.class); - DISPATCH_TABLE[0xA1] = EmulatorEngine.class.getDeclaredMethod("AND_R", short.class); - DISPATCH_TABLE[0xA2] = EmulatorEngine.class.getDeclaredMethod("AND_R", short.class); - DISPATCH_TABLE[0xA3] = EmulatorEngine.class.getDeclaredMethod("AND_R", short.class); - DISPATCH_TABLE[0xA4] = EmulatorEngine.class.getDeclaredMethod("AND_R", short.class); - DISPATCH_TABLE[0xA5] = EmulatorEngine.class.getDeclaredMethod("AND_R", short.class); - DISPATCH_TABLE[0xA6] = EmulatorEngine.class.getDeclaredMethod("AND_R", short.class); - DISPATCH_TABLE[0xA7] = EmulatorEngine.class.getDeclaredMethod("AND_R", short.class); - - DISPATCH_TABLE[0xA8] = EmulatorEngine.class.getDeclaredMethod("XOR_R", short.class); - DISPATCH_TABLE[0xA9] = EmulatorEngine.class.getDeclaredMethod("XOR_R", short.class); - DISPATCH_TABLE[0xAA] = EmulatorEngine.class.getDeclaredMethod("XOR_R", short.class); - DISPATCH_TABLE[0xAB] = EmulatorEngine.class.getDeclaredMethod("XOR_R", short.class); - DISPATCH_TABLE[0xAC] = EmulatorEngine.class.getDeclaredMethod("XOR_R", short.class); - DISPATCH_TABLE[0xAD] = EmulatorEngine.class.getDeclaredMethod("XOR_R", short.class); - DISPATCH_TABLE[0xAE] = EmulatorEngine.class.getDeclaredMethod("XOR_R", short.class); - DISPATCH_TABLE[0xAF] = EmulatorEngine.class.getDeclaredMethod("XOR_R", short.class); - - DISPATCH_TABLE[0xB0] = EmulatorEngine.class.getDeclaredMethod("OR_R", short.class); - DISPATCH_TABLE[0xB1] = EmulatorEngine.class.getDeclaredMethod("OR_R", short.class); - DISPATCH_TABLE[0xB2] = EmulatorEngine.class.getDeclaredMethod("OR_R", short.class); - DISPATCH_TABLE[0xB3] = EmulatorEngine.class.getDeclaredMethod("OR_R", short.class); - DISPATCH_TABLE[0xB4] = EmulatorEngine.class.getDeclaredMethod("OR_R", short.class); - DISPATCH_TABLE[0xB5] = EmulatorEngine.class.getDeclaredMethod("OR_R", short.class); - DISPATCH_TABLE[0xB6] = EmulatorEngine.class.getDeclaredMethod("OR_R", short.class); - DISPATCH_TABLE[0xB7] = EmulatorEngine.class.getDeclaredMethod("OR_R", short.class); - - DISPATCH_TABLE[0xB8] = EmulatorEngine.class.getDeclaredMethod("CP_R", short.class); - DISPATCH_TABLE[0xB9] = EmulatorEngine.class.getDeclaredMethod("CP_R", short.class); - DISPATCH_TABLE[0xBA] = EmulatorEngine.class.getDeclaredMethod("CP_R", short.class); - DISPATCH_TABLE[0xBB] = EmulatorEngine.class.getDeclaredMethod("CP_R", short.class); - DISPATCH_TABLE[0xBC] = EmulatorEngine.class.getDeclaredMethod("CP_R", short.class); - DISPATCH_TABLE[0xBD] = EmulatorEngine.class.getDeclaredMethod("CP_R", short.class); - DISPATCH_TABLE[0xBE] = EmulatorEngine.class.getDeclaredMethod("CP_R", short.class); - DISPATCH_TABLE[0xBF] = EmulatorEngine.class.getDeclaredMethod("CP_R", short.class); - - DISPATCH_TABLE[0x07] = EmulatorEngine.class.getDeclaredMethod("O7_RLCA", short.class); - DISPATCH_TABLE[0x08] = EmulatorEngine.class.getDeclaredMethod("O8_EX_AF_AFF", short.class); - DISPATCH_TABLE[0x0A] = EmulatorEngine.class.getDeclaredMethod("OA_LD_A_LPAR_BC_RPAR", short.class); - DISPATCH_TABLE[0x0F] = EmulatorEngine.class.getDeclaredMethod("OF_RRCA", short.class); - DISPATCH_TABLE[0x10] = EmulatorEngine.class.getDeclaredMethod("O10_DJNZ", short.class); - DISPATCH_TABLE[0x12] = EmulatorEngine.class.getDeclaredMethod("O12_LD_LPAR_DE_RPAR_A", short.class); - DISPATCH_TABLE[0x17] = EmulatorEngine.class.getDeclaredMethod("O17_RLA", short.class); - DISPATCH_TABLE[0x18] = EmulatorEngine.class.getDeclaredMethod("O18_JR_E", short.class); - DISPATCH_TABLE[0x1A] = EmulatorEngine.class.getDeclaredMethod("O1A_LD_A_LPAR_DE_RPAR", short.class); - DISPATCH_TABLE[0x1F] = EmulatorEngine.class.getDeclaredMethod("O1F_RRA", short.class); - DISPATCH_TABLE[0x22] = EmulatorEngine.class.getDeclaredMethod("O22_LD_LPAR_NN_RPAR_HL", short.class); - DISPATCH_TABLE[0x2A] = EmulatorEngine.class.getDeclaredMethod("O2A_LD_HL_LPAR_NN_RPAR", short.class); - DISPATCH_TABLE[0x32] = EmulatorEngine.class.getDeclaredMethod("O32_LD_LPAR_NN_RPAR_A", short.class); - DISPATCH_TABLE[0x3A] = EmulatorEngine.class.getDeclaredMethod("O3A_LD_A_LPAR_NN_RPAR", short.class); - DISPATCH_TABLE[0xC3] = EmulatorEngine.class.getDeclaredMethod("C3_JP_NN", short.class); - DISPATCH_TABLE[0xC6] = EmulatorEngine.class.getDeclaredMethod("C6_ADD_A_d", short.class); - DISPATCH_TABLE[0xCD] = EmulatorEngine.class.getDeclaredMethod("CD_CALL_NN", short.class); - DISPATCH_TABLE[0xD3] = EmulatorEngine.class.getDeclaredMethod("D3_OUT_LPAR_D_RPAR_A", short.class); - DISPATCH_TABLE[0xD6] = EmulatorEngine.class.getDeclaredMethod("D6_SUB_d", short.class); - DISPATCH_TABLE[0xDB] = EmulatorEngine.class.getDeclaredMethod("DB_IN_A_LPAR_d_RPAR", short.class); - DISPATCH_TABLE[0xDE] = EmulatorEngine.class.getDeclaredMethod("DE_SBC_A_d", short.class); - DISPATCH_TABLE[0xE6] = EmulatorEngine.class.getDeclaredMethod("E6_AND_d", short.class); - DISPATCH_TABLE[0xEE] = EmulatorEngine.class.getDeclaredMethod("EE_XOR_d", short.class); - DISPATCH_TABLE[0xF6] = EmulatorEngine.class.getDeclaredMethod("F6_OR_d", short.class); - DISPATCH_TABLE[0xFE] = EmulatorEngine.class.getDeclaredMethod("FE_CP_d", short.class); - - DISPATCH_TABLE[0x20] = EmulatorEngine.class.getDeclaredMethod("JR_CC_D", short.class); - DISPATCH_TABLE[0x28] = EmulatorEngine.class.getDeclaredMethod("JR_CC_D", short.class); - DISPATCH_TABLE[0x30] = EmulatorEngine.class.getDeclaredMethod("JR_CC_D", short.class); - DISPATCH_TABLE[0x38] = EmulatorEngine.class.getDeclaredMethod("JR_CC_D", short.class); - - DISPATCH_TABLE[0x27] = EmulatorEngine.class.getDeclaredMethod("O27_DAA", short.class); - DISPATCH_TABLE[0x2F] = EmulatorEngine.class.getDeclaredMethod("O2F_CPL", short.class); - DISPATCH_TABLE[0x37] = EmulatorEngine.class.getDeclaredMethod("O37_SCF", short.class); - DISPATCH_TABLE[0x3F] = EmulatorEngine.class.getDeclaredMethod("O3F_CCF", short.class); - DISPATCH_TABLE[0xC9] = EmulatorEngine.class.getDeclaredMethod("C9_RET", short.class); - DISPATCH_TABLE[0xCE] = EmulatorEngine.class.getDeclaredMethod("CE_ADC_A_d", short.class); - DISPATCH_TABLE[0xD9] = EmulatorEngine.class.getDeclaredMethod("D9_EXX", short.class); - DISPATCH_TABLE[0xE3] = EmulatorEngine.class.getDeclaredMethod("E3_EX_LPAR_SP_RPAR_HL", short.class); - DISPATCH_TABLE[0xE9] = EmulatorEngine.class.getDeclaredMethod("E9_JP_LPAR_HL_RPAR", short.class); - DISPATCH_TABLE[0xEB] = EmulatorEngine.class.getDeclaredMethod("EB_EX_DE_HL", short.class); - DISPATCH_TABLE[0xF3] = EmulatorEngine.class.getDeclaredMethod("F3_DI", short.class); - DISPATCH_TABLE[0xF9] = EmulatorEngine.class.getDeclaredMethod("F9_LD_SP_HL", short.class); - DISPATCH_TABLE[0xFB] = EmulatorEngine.class.getDeclaredMethod("FB_EI", short.class); - DISPATCH_TABLE[0xED] = EmulatorEngine.class.getDeclaredMethod("ED_DISPATCH", short.class); - - DISPATCH_TABLE_ED[0x77] = EmulatorEngine.class.getDeclaredMethod("O0_NOP", short.class); - DISPATCH_TABLE_ED[0x7F] = EmulatorEngine.class.getDeclaredMethod("O0_NOP", short.class); - - DISPATCH_TABLE_ED[0x40] = EmulatorEngine.class.getDeclaredMethod("IN_r_LPAR_C_RPAR", short.class); - DISPATCH_TABLE_ED[0x48] = EmulatorEngine.class.getDeclaredMethod("IN_r_LPAR_C_RPAR", short.class); - DISPATCH_TABLE_ED[0x50] = EmulatorEngine.class.getDeclaredMethod("IN_r_LPAR_C_RPAR", short.class); - DISPATCH_TABLE_ED[0x58] = EmulatorEngine.class.getDeclaredMethod("IN_r_LPAR_C_RPAR", short.class); - DISPATCH_TABLE_ED[0x60] = EmulatorEngine.class.getDeclaredMethod("IN_r_LPAR_C_RPAR", short.class); - DISPATCH_TABLE_ED[0x68] = EmulatorEngine.class.getDeclaredMethod("IN_r_LPAR_C_RPAR", short.class); - DISPATCH_TABLE_ED[0x78] = EmulatorEngine.class.getDeclaredMethod("IN_r_LPAR_C_RPAR", short.class); - - DISPATCH_TABLE_ED[0x41] = EmulatorEngine.class.getDeclaredMethod("OUT_LPAR_C_RPAR_r", short.class); - DISPATCH_TABLE_ED[0x49] = EmulatorEngine.class.getDeclaredMethod("OUT_LPAR_C_RPAR_r", short.class); - DISPATCH_TABLE_ED[0x51] = EmulatorEngine.class.getDeclaredMethod("OUT_LPAR_C_RPAR_r", short.class); - DISPATCH_TABLE_ED[0x59] = EmulatorEngine.class.getDeclaredMethod("OUT_LPAR_C_RPAR_r", short.class); - DISPATCH_TABLE_ED[0x61] = EmulatorEngine.class.getDeclaredMethod("OUT_LPAR_C_RPAR_r", short.class); - DISPATCH_TABLE_ED[0x69] = EmulatorEngine.class.getDeclaredMethod("OUT_LPAR_C_RPAR_r", short.class); - DISPATCH_TABLE_ED[0x79] = EmulatorEngine.class.getDeclaredMethod("OUT_LPAR_C_RPAR_r", short.class); - - DISPATCH_TABLE_ED[0x42] = EmulatorEngine.class.getDeclaredMethod("SBC_HL_SS", short.class); - DISPATCH_TABLE_ED[0x52] = EmulatorEngine.class.getDeclaredMethod("SBC_HL_SS", short.class); - DISPATCH_TABLE_ED[0x62] = EmulatorEngine.class.getDeclaredMethod("SBC_HL_SS", short.class); - DISPATCH_TABLE_ED[0x72] = EmulatorEngine.class.getDeclaredMethod("SBC_HL_SS", short.class); - - DISPATCH_TABLE_ED[0x4A] = EmulatorEngine.class.getDeclaredMethod("ADC_HL_SS", short.class); - DISPATCH_TABLE_ED[0x5A] = EmulatorEngine.class.getDeclaredMethod("ADC_HL_SS", short.class); - DISPATCH_TABLE_ED[0x6A] = EmulatorEngine.class.getDeclaredMethod("ADC_HL_SS", short.class); - DISPATCH_TABLE_ED[0x7A] = EmulatorEngine.class.getDeclaredMethod("ADC_HL_SS", short.class); - - DISPATCH_TABLE_ED[0x44] = EmulatorEngine.class.getDeclaredMethod("NEG", short.class); - DISPATCH_TABLE_ED[0x4C] = EmulatorEngine.class.getDeclaredMethod("NEG", short.class); - DISPATCH_TABLE_ED[0x54] = EmulatorEngine.class.getDeclaredMethod("NEG", short.class); - DISPATCH_TABLE_ED[0x5C] = EmulatorEngine.class.getDeclaredMethod("NEG", short.class); - DISPATCH_TABLE_ED[0x64] = EmulatorEngine.class.getDeclaredMethod("NEG", short.class); - DISPATCH_TABLE_ED[0x6C] = EmulatorEngine.class.getDeclaredMethod("NEG", short.class); - DISPATCH_TABLE_ED[0x74] = EmulatorEngine.class.getDeclaredMethod("NEG", short.class); - DISPATCH_TABLE_ED[0x7C] = EmulatorEngine.class.getDeclaredMethod("NEG", short.class); - - DISPATCH_TABLE_ED[0x45] = EmulatorEngine.class.getDeclaredMethod("RETN", short.class); - DISPATCH_TABLE_ED[0x55] = EmulatorEngine.class.getDeclaredMethod("RETN", short.class); - DISPATCH_TABLE_ED[0x5D] = EmulatorEngine.class.getDeclaredMethod("RETN", short.class); - DISPATCH_TABLE_ED[0x65] = EmulatorEngine.class.getDeclaredMethod("RETN", short.class); - DISPATCH_TABLE_ED[0x6D] = EmulatorEngine.class.getDeclaredMethod("RETN", short.class); - DISPATCH_TABLE_ED[0x75] = EmulatorEngine.class.getDeclaredMethod("RETN", short.class); - DISPATCH_TABLE_ED[0x7D] = EmulatorEngine.class.getDeclaredMethod("RETN", short.class); - - DISPATCH_TABLE_ED[0x46] = EmulatorEngine.class.getDeclaredMethod("IM_0", short.class); - DISPATCH_TABLE_ED[0x4E] = EmulatorEngine.class.getDeclaredMethod("IM_0", short.class); - DISPATCH_TABLE_ED[0x66] = EmulatorEngine.class.getDeclaredMethod("IM_0", short.class); - DISPATCH_TABLE_ED[0x6E] = EmulatorEngine.class.getDeclaredMethod("IM_0", short.class); - - DISPATCH_TABLE_ED[0x47] = EmulatorEngine.class.getDeclaredMethod("O47_LD_I_A", short.class); - DISPATCH_TABLE_ED[0x4D] = EmulatorEngine.class.getDeclaredMethod("O4D_RETI", short.class); - DISPATCH_TABLE_ED[0x4F] = EmulatorEngine.class.getDeclaredMethod("O4F_LD_R_A", short.class); - - DISPATCH_TABLE_ED[0x56] = EmulatorEngine.class.getDeclaredMethod("IM_1", short.class); - DISPATCH_TABLE_ED[0x76] = EmulatorEngine.class.getDeclaredMethod("IM_1", short.class); - - DISPATCH_TABLE_ED[0x57] = EmulatorEngine.class.getDeclaredMethod("O57_LD_A_I", short.class); - - DISPATCH_TABLE_ED[0x5E] = EmulatorEngine.class.getDeclaredMethod("IM_2", short.class); - DISPATCH_TABLE_ED[0x7E] = EmulatorEngine.class.getDeclaredMethod("IM_2", short.class); - - DISPATCH_TABLE_ED[0x5F] = EmulatorEngine.class.getDeclaredMethod("O5F_LD_A_R", short.class); - DISPATCH_TABLE_ED[0x67] = EmulatorEngine.class.getDeclaredMethod("O67_RRD", short.class); - DISPATCH_TABLE_ED[0x6F] = EmulatorEngine.class.getDeclaredMethod("O6F_RLD", short.class); - DISPATCH_TABLE_ED[0x70] = EmulatorEngine.class.getDeclaredMethod("O70_IN_LPAR_C_RPAR", short.class); - DISPATCH_TABLE_ED[0x71] = EmulatorEngine.class.getDeclaredMethod("O71_OUT_LPAR_C_RPAR_0", short.class); - DISPATCH_TABLE_ED[0xA0] = EmulatorEngine.class.getDeclaredMethod("A0_LDI", short.class); - DISPATCH_TABLE_ED[0xA1] = EmulatorEngine.class.getDeclaredMethod("A1_CPI", short.class); - DISPATCH_TABLE_ED[0xA2] = EmulatorEngine.class.getDeclaredMethod("A2_INI", short.class); - DISPATCH_TABLE_ED[0xA3] = EmulatorEngine.class.getDeclaredMethod("A3_OUTI", short.class); - DISPATCH_TABLE_ED[0xA8] = EmulatorEngine.class.getDeclaredMethod("A8_LDD", short.class); - DISPATCH_TABLE_ED[0xA9] = EmulatorEngine.class.getDeclaredMethod("A9_CPD", short.class); - DISPATCH_TABLE_ED[0xAA] = EmulatorEngine.class.getDeclaredMethod("AA_IND", short.class); - DISPATCH_TABLE_ED[0xAB] = EmulatorEngine.class.getDeclaredMethod("AB_OUTD", short.class); - DISPATCH_TABLE_ED[0xB0] = EmulatorEngine.class.getDeclaredMethod("B0_LDIR", short.class); - DISPATCH_TABLE_ED[0xB1] = EmulatorEngine.class.getDeclaredMethod("B1_CPIR", short.class); - DISPATCH_TABLE_ED[0xB2] = EmulatorEngine.class.getDeclaredMethod("B2_INIR", short.class); - DISPATCH_TABLE_ED[0xB3] = EmulatorEngine.class.getDeclaredMethod("B3_OTIR", short.class); - DISPATCH_TABLE_ED[0xB8] = EmulatorEngine.class.getDeclaredMethod("B8_LDDR", short.class); - DISPATCH_TABLE_ED[0xB9] = EmulatorEngine.class.getDeclaredMethod("B9_CPDR", short.class); - DISPATCH_TABLE_ED[0xBA] = EmulatorEngine.class.getDeclaredMethod("BA_INDR", short.class); - DISPATCH_TABLE_ED[0xBB] = EmulatorEngine.class.getDeclaredMethod("BB_OTDR", short.class); - - DISPATCH_TABLE_ED[0x43] = EmulatorEngine.class.getDeclaredMethod("LD_LPAR_N_RPAR_SS", short.class); - DISPATCH_TABLE_ED[0x53] = EmulatorEngine.class.getDeclaredMethod("LD_LPAR_N_RPAR_SS", short.class); - DISPATCH_TABLE_ED[0x63] = EmulatorEngine.class.getDeclaredMethod("LD_LPAR_N_RPAR_SS", short.class); - DISPATCH_TABLE_ED[0x73] = EmulatorEngine.class.getDeclaredMethod("LD_LPAR_N_RPAR_SS", short.class); - - DISPATCH_TABLE_ED[0x4B] = EmulatorEngine.class.getDeclaredMethod("LD_SS_LPAR_N_RPAR", short.class); - DISPATCH_TABLE_ED[0x5B] = EmulatorEngine.class.getDeclaredMethod("LD_SS_LPAR_N_RPAR", short.class); - DISPATCH_TABLE_ED[0x6B] = EmulatorEngine.class.getDeclaredMethod("LD_SS_LPAR_N_RPAR", short.class); - DISPATCH_TABLE_ED[0x7B] = EmulatorEngine.class.getDeclaredMethod("LD_SS_LPAR_N_RPAR", short.class); - - - } catch (NoSuchMethodException | SecurityException e) { - LOGGER.error("Could not set up dispatch table. The emulator won't work correctly", e); - } - } - - - private int ED_DISPATCH(short OP) throws InvocationTargetException, IllegalAccessException { - OP = memory.read(PC); - incrementR(); - PC = (PC + 1) & 0xFFFF; - - Method instr = DISPATCH_TABLE_ED[OP]; - if (instr != null) { - return (Integer) instr.invoke(this, OP); - } - currentRunState = RunState.STATE_STOPPED_BAD_INSTR; - return 0; - } - - private int DD_FD_DISPATCH(short OP) throws InvocationTargetException, IllegalAccessException { - int special = OP; - OP = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - incrementR(); - - Method instr = DISPATCH_TABLE_DD_FD[OP]; - if (instr != null) { - return (Integer) instr.invoke(this, OP, special); - } - currentRunState = RunState.STATE_STOPPED_BAD_INSTR; - return 0; - } - - - private int O0_NOP(short OP) { + int I_NOP(short OP) { return 4; } - private int O2_LD_LPAR_BC_RPAR__A(short OP) { + int I_LD_REF_BC_A(short OP) { memory.write(getpair(0, false), (byte) regs[REG_A]); return 7; } - private int INC_SS(short OP) { + int I_INC_RP(short OP) { int tmp = (OP >>> 4) & 0x03; putpair(tmp, (getpair(tmp, true) + 1) & 0xFFFF, true); return 6; } - private int ADD_HL_SS(short OP) { + int I_ADD_HL_RP(short OP) { int tmp = getpair((OP >>> 4) & 0x03, true); int tmp1 = getpair(2, true); carry15(tmp, tmp1); @@ -836,58 +566,58 @@ private int ADD_HL_SS(short OP) { return 11; } - private int DEC_SS(short OP) { - int tmp = (OP >>> 4) & 0x03; - putpair(tmp, (getpair(tmp, true) - 1) & 0xFFFF, true); + int I_DEC_RP(short OP) { + int regPair = (OP >>> 4) & 0x03; + putpair(regPair, (getpair(regPair, true) - 1) & 0xFFFF, true); return 6; } - private int POP_QQ(short OP) { - int tmp = (OP >>> 4) & 0x03; - int tmp1 = readWord(SP); + int I_POP_RP(short OP) { + int regPair = (OP >>> 4) & 0x03; + int value = readWord(SP); SP = (SP + 2) & 0xffff; - putpair(tmp, tmp1, false); + putpair(regPair, value, false); return 10; } - private int PUSH_QQ(short OP) { - int tmp = (OP >>> 4) & 0x03; - int tmp1 = getpair(tmp, false); + int I_PUSH_RP(short OP) { + int regPair = (OP >>> 4) & 0x03; + int value = getpair(regPair, false); SP = (SP - 2) & 0xffff; - writeWord(SP, tmp1); + writeWord(SP, value); return 11; } - private int LD_R_N(short OP) { - int tmp = (OP >>> 3) & 0x07; - putreg(tmp, memory.read(PC)); + int I_LD_R_N(short OP) { + int reg = (OP >>> 3) & 0x07; + putreg(reg, memory.read(PC)); PC = (PC + 1) & 0xFFFF; - if (tmp == 6) { + if (reg == 6) { return 10; } else { return 7; } } - private int INC_R(short OP) { - int tmp = (OP >>> 3) & 0x07; - int tmp1 = (getreg(tmp) + 1) & 0xFF; - flags = EmulatorTables.INC_TABLE[tmp1] | (flags & FLAG_C); - putreg(tmp, tmp1); - return (tmp == 6) ? 11 : 4; + int I_INC_R(short OP) { + int reg = (OP >>> 3) & 0x07; + int value = (getreg(reg) + 1) & 0xFF; + flags = EmulatorTables.INC_TABLE[value] | (flags & FLAG_C); + putreg(reg, value); + return (reg == 6) ? 11 : 4; } - private int DEC_R(short OP) { - int tmp = (OP >>> 3) & 0x07; - int tmp1 = (getreg(tmp) - 1) & 0xFF; - flags = EmulatorTables.DEC_TABLE[tmp1] | (flags & FLAG_C); - putreg(tmp, tmp1); - return (tmp == 6) ? 11 : 4; + int I_DEC_R(short OP) { + int reg = (OP >>> 3) & 0x07; + int value = (getreg(reg) - 1) & 0xFF; + flags = EmulatorTables.DEC_TABLE[value] | (flags & FLAG_C); + putreg(reg, value); + return (reg == 6) ? 11 : 4; } - private int RET_CC(short OP) { - int tmp = (OP >>> 3) & 7; - if ((flags & CONDITION[tmp]) == CONDITION_VALUES[tmp]) { + int I_RET_CC(short OP) { + int cc = (OP >>> 3) & 7; + if ((flags & CONDITION[cc]) == CONDITION_VALUES[cc]) { PC = readWord(SP); SP = (SP + 2) & 0xffff; return 11; @@ -895,115 +625,78 @@ private int RET_CC(short OP) { return 5; } - private int RST_P(short OP) { + int I_RST(short OP) { SP = (SP - 2) & 0xffff; writeWord(SP, PC); PC = OP & 0x38; return 11; } - private int ADD_A_R(short OP) { - int X = regs[REG_A]; - int diff = getreg(OP & 0x07); - regs[REG_A] += diff; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF]; - regs[REG_A] &= 0xFF; - - auxCarry(X, diff); - overflow(X, diff, regs[REG_A]); - - return ((OP & 0x07) == 6) ? 7 : 4; + int I_ADD_A_R(short OP) { + int value = getreg(OP & 0x07); + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value) & 0xFF; + flags = flagSZHPC(oldA, value, regs[REG_A]); + return (OP == 0x86) ? 7 : 4; } - private int ADC_A_R(short OP) { - int X = regs[REG_A]; - int diff = getreg(OP & 0x07); - if ((flags & FLAG_C) != 0) { - diff++; - } - regs[REG_A] += diff; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF]; - regs[REG_A] = regs[REG_A] & 0xFF; - - auxCarry(X, diff); - overflow(X, diff, regs[REG_A]); - - return ((OP & 0x07) == 6) ? 7 : 4; + int I_ADC_A_R(short OP) { + int value = getreg(OP & 0x07); + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; + flags = flagSZHPC(oldA, (value + (flags & FLAG_C)) & 0xFF, regs[REG_A]); + return (OP == 0x8E) ? 7 : 4; } - private int SUB_R(short OP) { - int X = regs[REG_A]; - int diff = -getreg(OP & 0x07); - regs[REG_A] += diff; - diff &= 0xFF; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF] | FLAG_N; - regs[REG_A] = regs[REG_A] & 0xFF; - - auxCarry(X, diff); - overflow(X, diff, regs[REG_A]); - - return ((OP & 0x07) == 6) ? 7 : 4; + int I_SUB_R(short OP) { + int value = ((~getreg(OP & 0x07)) + 1) & 0xFF; + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value) & 0xFF; + flags = flagSZHPC(oldA, value, regs[REG_A]) | FLAG_N; + return (OP == 0x96) ? 7 : 4; } - private int SBC_A_R(short OP) { - int X = regs[REG_A]; - int diff = -getreg(OP & 0x07); - if ((flags & FLAG_C) != 0) { - diff--; - } - regs[REG_A] += diff; - diff &= 0xFF; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF] | FLAG_N; - regs[REG_A] &= 0xFF; - - auxCarry(X, diff); - overflow(X, diff, regs[REG_A]); - - return ((OP & 0x07) == 6) ? 7 : 4; + int I_SBC_A_R(short OP) { + int value = ((~getreg(OP & 0x07)) + 1) & 0xFF; + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value - (flags & FLAG_C)) & 0xFF; + flags = flagSZHPC(oldA, (value - (flags & FLAG_C)) & 0xFF, regs[REG_A]) | FLAG_N; + return (OP == 0x9E) ? 7 : 4; } - private int AND_R(short OP) { + int I_AND_R(short OP) { regs[REG_A] = (regs[REG_A] & getreg(OP & 7)) & 0xFF; flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; return (OP == 0xA6) ? 7 : 4; } - private int XOR_R(short OP) { + int I_XOR_R(short OP) { regs[REG_A] = ((regs[REG_A] ^ getreg(OP & 7)) & 0xff); flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; return (OP == 0xAE) ? 7 : 4; } - private int OR_R(short OP) { + int I_OR_R(short OP) { regs[REG_A] = (regs[REG_A] | getreg(OP & 7)) & 0xFF; flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; return (OP == 0xB6) ? 7 : 4; } - private int CP_R(short OP) { - int diff = -getreg(OP & 7); - int tmp2 = regs[REG_A] + diff; - diff &= 0xFF; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[tmp2 & 0x1FF] | FLAG_N; - auxCarry(regs[REG_A], diff); - overflow(regs[REG_A], diff, tmp2 & 0xFF); - + int I_CP_R(short OP) { + int value = ((~getreg(OP & 7)) + 1) & 0xFF; + int result = (regs[REG_A] + value) & 0xFF; + flags = flagSZHPC(regs[REG_A], value, result) | FLAG_N; return (OP == 0xBE) ? 7 : 4; } - private int O7_RLCA(short OP) { + int I_RLCA(short OP) { int tmp = regs[REG_A] >>> 7; regs[REG_A] = ((((regs[REG_A] << 1) & 0xFF) | tmp) & 0xff); flags = ((flags & 0xEC) | tmp); return 4; } - private int O8_EX_AF_AFF(short OP) { + int I_EX_AF_AFF(short OP) { int tmp = regs[REG_A]; regs[REG_A] = regs2[REG_A]; regs2[REG_A] = tmp; @@ -1013,55 +706,54 @@ private int O8_EX_AF_AFF(short OP) { return 4; } - private int OA_LD_A_LPAR_BC_RPAR(short OP) { - regs[REG_A] = memory.read(getpair(0, false)); + int I_LD_A_REF_BC(short OP) { + regs[REG_A] = readByte(getpair(0, false)); return 7; } - private int OF_RRCA(short OP) { + int I_RRCA(short OP) { flags = ((flags & 0xEC) | (regs[REG_A] & 1)); regs[REG_A] = EmulatorTables.RRCA_TABLE[regs[REG_A]]; return 4; } - private int O10_DJNZ(short OP) { - int tmp = memory.read(PC); + int I_DJNZ(short OP) { + byte tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; regs[REG_B]--; regs[REG_B] &= 0xFF; if (regs[REG_B] != 0) { - PC += (byte) tmp; - PC &= 0xFFFF; + PC = (PC + tmp) & 0xFFFF; return 13; } return 8; } - private int O12_LD_LPAR_DE_RPAR_A(short OP) { + int I_LD_REF_DE_A(short OP) { memory.write(getpair(1, false), (byte) regs[REG_A]); return 7; } - private int O17_RLA(short OP) { + int I_RLA(short OP) { int tmp = regs[REG_A] >>> 7; regs[REG_A] = (((regs[REG_A] << 1) | (flags & FLAG_C)) & 0xff); flags = ((flags & 0xEC) | tmp); return 4; } - private int O1A_LD_A_LPAR_DE_RPAR(short OP) { - regs[REG_A] = memory.read(getpair(1, false)) & 0xFF; + int I_LD_A_REF_DE(short OP) { + regs[REG_A] = readByte(getpair(1, false)); return 7; } - private int O1F_RRA(short OP) { + int I_RRA(short OP) { int tmp = (flags & FLAG_C) << 7; flags = ((flags & 0xEC) | (regs[REG_A] & 1)); regs[REG_A] = ((regs[REG_A] >>> 1 | tmp) & 0xff); return 4; } - private int O27_DAA(short OP) { + int I_DAA(short OP) { int temp = regs[REG_A]; boolean acFlag = (flags & FLAG_H) == FLAG_H; boolean cFlag = (flags & FLAG_C) == FLAG_C; @@ -1083,7 +775,7 @@ private int O27_DAA(short OP) { } else { flags |= EmulatorTables.DAA_NOT_N_H_FOR_H_TABLE[temp]; } - } else if (!acFlag && cFlag) { + } else if (!acFlag) { // cFlag = true regs[REG_A] = EmulatorTables.DAA_C_NOT_H_TABLE[temp] & 0xFF; flags = (EmulatorTables.DAA_C_NOT_H_TABLE[temp] >> 8) & 0xFF | (flags & FLAG_N); if (nFlag) { @@ -1091,7 +783,7 @@ private int O27_DAA(short OP) { } else { flags |= EmulatorTables.DAA_NOT_N_NOT_H_FOR_H_TABLE[temp]; } - } else { + } else { // acFlag = cFlag = true regs[REG_A] = EmulatorTables.DAA_C_H_TABLE[temp] & 0xFF; flags = (EmulatorTables.DAA_C_H_TABLE[temp] >> 8) & 0xFF | (flags & FLAG_N); if (nFlag) { @@ -1104,19 +796,19 @@ private int O27_DAA(short OP) { return 4; } - private int O2F_CPL(short OP) { + int I_CPL(short OP) { regs[REG_A] = ((~regs[REG_A]) & 0xFF); flags |= FLAG_N | FLAG_H; return 4; } - private int O37_SCF(short OP) { + int I_SCF(short OP) { flags |= FLAG_N | FLAG_C; flags &= ~FLAG_H; return 4; } - private int O3F_CCF(short OP) { + int I_CCF(short OP) { int tmp = flags & FLAG_C; if (tmp == 0) { flags |= FLAG_C; @@ -1127,13 +819,13 @@ private int O3F_CCF(short OP) { return 4; } - private int C9_RET(short OP) { + int I_RET(short OP) { PC = readWord(SP); SP = (SP + 2) & 0xFFFF; return 10; } - private int D9_EXX(short OP) { + int I_EXX(short OP) { int tmp = regs[REG_B]; regs[REG_B] = regs2[REG_B]; regs2[REG_B] = tmp; @@ -1155,10 +847,10 @@ private int D9_EXX(short OP) { return 4; } - private int E3_EX_LPAR_SP_RPAR_HL(short OP) { - int tmp = memory.read(SP); + int I_EX_REF_SP_HL(short OP) { + byte tmp = memory.read(SP); int x = (SP + 1) & 0xFFFF; - int tmp1 = memory.read(x); + byte tmp1 = memory.read(x); memory.write(SP, (byte) regs[REG_L]); memory.write(x, (byte) regs[REG_H]); regs[REG_L] = tmp & 0xFF; @@ -1166,12 +858,12 @@ private int E3_EX_LPAR_SP_RPAR_HL(short OP) { return 19; } - private int E9_JP_LPAR_HL_RPAR(short OP) { + int I_JP_REF_HL(short OP) { PC = ((regs[REG_H] << 8) | regs[REG_L]); return 4; } - private int EB_EX_DE_HL(short OP) { + int I_EX_DE_HL(short OP) { int tmp = regs[REG_D]; regs[REG_D] = regs[REG_H]; regs[REG_H] = tmp; @@ -1181,35 +873,35 @@ private int EB_EX_DE_HL(short OP) { return 4; } - private int F3_DI(short OP) { + int I_DI(short OP) { IFF[0] = IFF[1] = false; return 4; } - private int F9_LD_SP_HL(short OP) { + int I_LD_SP_HL(short OP) { SP = ((regs[REG_H] << 8) | regs[REG_L]); return 6; } - private int FB_EI(short OP) { + int I_EI(short OP) { IFF[0] = IFF[1] = true; return 4; } - private int IN_r_LPAR_C_RPAR(short OP) throws IOException { + int I_IN_R_REF_C(short OP) throws IOException { int tmp = (OP >>> 3) & 0x7; putreg(tmp, context.readIO(regs[REG_C])); flags = (flags & FLAG_C) | EmulatorTables.SIGN_ZERO_TABLE[regs[tmp]] | EmulatorTables.PARITY_TABLE[regs[tmp]]; return 12; } - private int OUT_LPAR_C_RPAR_r(short OP) throws IOException { + int I_OUT_REF_C_R(short OP) throws IOException { int tmp = (OP >>> 3) & 0x7; - context.writeIO(regs[REG_C], (byte) getreg(tmp)); + context.writeIO(regs[REG_C], (byte)getreg(tmp)); return 12; } - private int SBC_HL_SS(short OP) { + int I_SBC_HL_RP(short OP) { int tmp = -getpair((OP >>> 4) & 0x03, true); int tmp1 = getpair(2, true); if ((flags & FLAG_C) == FLAG_C) { @@ -1239,7 +931,7 @@ private int SBC_HL_SS(short OP) { return 15; } - private int ADC_HL_SS(short OP) { + int I_ADC_HL_RP(short OP) { int tmp = getpair((OP >>> 4) & 0x03, true); int tmp1 = getpair(2, true); if ((flags & FLAG_C) == FLAG_C) { @@ -1268,64 +960,64 @@ private int ADC_HL_SS(short OP) { return 11; } - private int NEG(short OP) { + int I_NEG(short OP) { flags = EmulatorTables.NEG_TABLE[regs[REG_A]] & 0xFF; regs[REG_A] = (EmulatorTables.NEG_TABLE[regs[REG_A]] >>> 8) & 0xFF; return 8; } - private int RETN(short OP) { + int I_RETN(short OP) { IFF[0] = IFF[1]; PC = readWord(SP); SP = (SP + 2) & 0xffff; return 14; } - private int IM_0(short OP) { + int I_IM_0(short OP) { intMode = 0; return 8; } - private int O47_LD_I_A(short OP) { + int I_LD_I_A(short OP) { I = regs[REG_A]; return 9; } - private int O4D_RETI(short OP) { + int I_RETI(short OP) { IFF[0] = IFF[1]; PC = readWord(SP); SP = (SP + 2) & 0xffff; return 14; } - private int O4F_LD_R_A(short OP) { + int I_LD_R_A(short OP) { R = regs[REG_A]; return 9; } - private int IM_1(short OP) { + int I_IM_1(short OP) { intMode = 1; return 8; } - private int O57_LD_A_I(short OP) { + int I_LD_A_I(short OP) { regs[REG_A] = I & 0xFF; flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C); return 9; } - private int IM_2(short OP) { + int I_IM_2(short OP) { intMode = 2; return 8; } - private int O5F_LD_A_R(short OP) { + int I_LD_A_R(short OP) { regs[REG_A] = R & 0xFF; flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C); return 9; } - private int O67_RRD(short OP) { + int I_RRD(short OP) { int tmp = regs[REG_A] & 0x0F; int tmp1 = memory.read((regs[REG_H] << 8) | regs[REG_L]); regs[REG_A] = ((regs[REG_A] & 0xF0) | (tmp1 & 0x0F)); @@ -1335,7 +1027,7 @@ private int O67_RRD(short OP) { return 18; } - private int O6F_RLD(short OP) { + int I_RLD(short OP) { int tmp = memory.read((regs[REG_H] << 8) | regs[REG_L]); int tmp1 = (tmp >>> 4) & 0x0F; tmp = ((tmp << 4) & 0xF0) | (regs[REG_A] & 0x0F); @@ -1345,18 +1037,18 @@ private int O6F_RLD(short OP) { return 18; } - private int O70_IN_LPAR_C_RPAR(short OP) throws IOException { + int I_IN_REF_C(short OP) throws IOException { int tmp = (context.readIO(regs[REG_C]) & 0xFF); flags = EmulatorTables.SIGN_ZERO_TABLE[tmp] | EmulatorTables.PARITY_TABLE[tmp] | (flags & FLAG_C); return 12; } - private int O71_OUT_LPAR_C_RPAR_0(short OP) throws IOException { - context.writeIO(regs[REG_C], (byte)0); + int I_OUT_REF_C_0(short OP) throws IOException { + context.writeIO(regs[REG_C], (byte) 0); return 12; } - private int A0_LDI(short OP) { + int I_LDI(short OP) { int tmp1 = getpair(2, false); int tmp2 = getpair(1, false); int tmp = getpair(0, false); @@ -1380,7 +1072,7 @@ private int A0_LDI(short OP) { return 16; } - private int A1_CPI(short OP) { + int I_CPI(short OP) { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_B] << 8) | regs[REG_C]; @@ -1402,47 +1094,7 @@ private int A1_CPI(short OP) { return 16; } - private int A2_INI(short OP) throws IOException { - int tmp = context.readIO(regs[REG_C]) & 0xFF; - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = tmp + (regs[REG_C] + 1) & 0xFF; - - memory.write(tmp1, (byte) tmp); - tmp1 = (tmp1 + 1) & 0xFFFF; - regs[REG_H] = ((tmp1 >>> 8) & 0xff); - regs[REG_L] = (tmp1 & 0xFF); - regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_B]] | EmulatorTables.PARITY_TABLE[(tmp2 & 7) ^ regs[REG_B]]; - if ((tmp & 0x80) == 0x80) { - flags |= FLAG_N; - } - if (tmp2 > 0xFF) { - flags |= (FLAG_H | FLAG_C); - } - return 16; - } - - private int A3_OUTI(short OP) throws IOException { - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = memory.read(tmp1) & 0xFF; - - context.writeIO(regs[REG_C], (byte)tmp2); - tmp1 = (tmp1 + 1) & 0xFFFF; - regs[REG_H] = ((tmp1 >>> 8) & 0xff); - regs[REG_L] = (tmp1 & 0xFF); - regs[REG_B] = (regs[REG_B] - 1) & 0xFF; - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_B]] | EmulatorTables.PARITY_TABLE[((tmp2 + regs[REG_L]) & 7) ^ regs[REG_B]]; - if ((tmp2 & 0x80) == 0x80) { - flags |= FLAG_N; - } - if ((tmp2 + regs[REG_L]) > 0xFF) { - flags |= FLAG_C | FLAG_H; - } - return 16; - } - - private int A8_LDD(short OP) { + int I_LDD(short OP) { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_D] << 8) | regs[REG_E]; int tmp = (regs[REG_B] << 8) | regs[REG_C]; @@ -1466,7 +1118,7 @@ private int A8_LDD(short OP) { return 16; } - private int A9_CPD(short OP) { + int I_CPD(short OP) { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_B] << 8) | regs[REG_C]; @@ -1488,49 +1140,7 @@ private int A9_CPD(short OP) { return 16; } - private int AA_IND(short OP) throws IOException { - int tmp = context.readIO(regs[REG_C]) & 0xFF; - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = tmp + ((regs[REG_C] - 1) & 0xFF); - - memory.write(tmp1, (byte) tmp); - tmp1 = (tmp1 - 1) & 0xFFFF; - regs[REG_H] = ((tmp1 >>> 8) & 0xff); - regs[REG_L] = (tmp1 & 0xFF); - regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_B]] | EmulatorTables.PARITY_TABLE[(tmp2 & 7) ^ regs[REG_B]]; - if ((tmp & 0x80) == 0x80) { - flags |= FLAG_N; - } - if (tmp2 > 0xFF) { - flags |= (FLAG_H | FLAG_C); - } - - return 16; - } - - private int AB_OUTD(short OP) throws IOException { - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = memory.read(tmp1) & 0xFF; - - context.writeIO(regs[REG_C], (byte)tmp2); - tmp1 = (tmp1 - 1) & 0xFFFF; - regs[REG_H] = ((tmp1 >>> 8) & 0xff); - regs[REG_L] = (tmp1 & 0xFF); - regs[REG_B] = (regs[REG_B] - 1) & 0xFF; - - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_B]] | EmulatorTables.PARITY_TABLE[((tmp2 + regs[REG_L]) & 7) ^ regs[REG_B]]; - if ((tmp2 & 0x80) == 0x80) { - flags |= FLAG_N; - } - if ((tmp2 + regs[REG_L]) > 0xFF) { - flags |= FLAG_C | FLAG_H; - } - return 16; - } - - private int B0_LDIR(short OP) { + int I_LDIR(short OP) { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_D] << 8) | regs[REG_E]; int tmp = (regs[REG_B] << 8) | regs[REG_C]; @@ -1557,7 +1167,7 @@ private int B0_LDIR(short OP) { return 21; } - private int B1_CPIR(short OP) { + int I_CPIR(short OP) { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_B] << 8) | regs[REG_C]; @@ -1584,24 +1194,33 @@ private int B1_CPIR(short OP) { return 21; } - private int B2_INIR(short OP) throws IOException { - int tmp = context.readIO(regs[REG_C]) & 0xFF; - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = tmp + (regs[REG_C] + 1) & 0xFF; + int I_INI(short OP) throws IOException { + byte value = context.readIO(regs[REG_C]); + int address = (regs[REG_H] << 8) | regs[REG_L]; + memory.write(address, value); - memory.write(tmp1, (byte) tmp); - tmp1 = (tmp1 + 1) & 0xFFFF; - regs[REG_H] = ((tmp1 >>> 8) & 0xff); - regs[REG_L] = (tmp1 & 0xFF); regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + address++; - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_B]] | EmulatorTables.PARITY_TABLE[(tmp2 & 7) ^ regs[REG_B]]; - if ((tmp & 0x80) == 0x80) { - flags |= FLAG_N; - } - if (tmp2 > 0xFF) { - flags |= (FLAG_H | FLAG_C); - } + regs[REG_H] = (address >>> 8) & 0xFF; + regs[REG_L] = address & 0xFF; + + flags |= FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0); + return 16; + } + + int I_INIR(short OP) throws IOException { + byte value = context.readIO(regs[REG_C]); + int address = (regs[REG_H] << 8) | regs[REG_L]; + memory.write(address, value); + + regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + address++; + + regs[REG_H] = (address >>> 8) & 0xFF; + regs[REG_L] = address & 0xFF; + + flags |= FLAG_Z | FLAG_N; // FLAG_Z is set b/c it is expected that INIR will be repeated until B=0 if (regs[REG_B] == 0) { return 16; @@ -1610,23 +1229,99 @@ private int B2_INIR(short OP) throws IOException { return 21; } - private int B3_OTIR(short OP) throws IOException { - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = memory.read(tmp1) & 0xFF; + int I_IND(short OP) throws IOException { + byte value = context.readIO(regs[REG_C]); + int address = (regs[REG_H] << 8) | regs[REG_L]; + memory.write(address, value); + + regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + address--; + + regs[REG_H] = (address >>> 8) & 0xFF; + regs[REG_L] = address & 0xFF; + + flags |= FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0); + return 16; + } + + int I_INDR(short OP) throws IOException { + byte value = context.readIO(regs[REG_C]); + int address = (regs[REG_H] << 8) | regs[REG_L]; + memory.write(address, value); - context.writeIO(regs[REG_C], (byte)tmp2); - tmp1 = (tmp1 + 1) & 0xFFFF; - regs[REG_H] = ((tmp1 >>> 8) & 0xff); - regs[REG_L] = (tmp1 & 0xFF); regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + address--; + + regs[REG_H] = (address >>> 8) & 0xFF; + regs[REG_L] = address & 0xFF; + + flags |= FLAG_Z | FLAG_N; // FLAG_Z is set b/c it is expected that INIR will be repeated until B=0 - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_B]] | EmulatorTables.PARITY_TABLE[((tmp2 + regs[REG_L]) & 7) ^ regs[REG_B]]; - if ((tmp2 & 0x80) == 0x80) { - flags |= FLAG_N; + if (regs[REG_B] == 0) { + return 16; } - if ((tmp2 + regs[REG_L]) > 0xFF) { - flags |= FLAG_C | FLAG_H; + PC = (PC - 2) & 0xFFFF; + return 21; + } + + int I_OUTI(short OP) throws IOException { + int address = (regs[REG_H] << 8) | regs[REG_L]; + byte value = memory.read(address); + context.writeIO(regs[REG_C], value); + + address++; + regs[REG_H] = (address >>> 8) & 0xFF; + regs[REG_L] = address & 0xFF; + regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + + flags |= FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0); + return 16; + } + + int I_OTIR(short OP) throws IOException { + int address = (regs[REG_H] << 8) | regs[REG_L]; + byte value = memory.read(address); + context.writeIO(regs[REG_C], value); + + address++; + regs[REG_H] = (address >>> 8) & 0xFF; + regs[REG_L] = address & 0xFF; + regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + + flags |= FLAG_Z | FLAG_N; // FLAG_Z is set b/c it is expected that OTIR will be repeated until B=0 + + if (regs[REG_B] == 0) { + return 16; } + PC = (PC - 2) & 0xFFFF; + return 21; + } + + int I_OUTD(short OP) throws IOException { + int address = (regs[REG_H] << 8) | regs[REG_L]; + byte value = memory.read(address); + context.writeIO(regs[REG_C], value); + + address--; + regs[REG_H] = (address >>> 8) & 0xFF; + regs[REG_L] = address & 0xFF; + regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + + flags |= FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0); + return 16; + } + + int I_OTDR(short OP) throws IOException { + int address = (regs[REG_H] << 8) | regs[REG_L]; + byte value = memory.read(address); + context.writeIO(regs[REG_C], value); + + address--; + regs[REG_H] = (address >>> 8) & 0xFF; + regs[REG_L] = address & 0xFF; + regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + + flags |= FLAG_Z | FLAG_N; if (regs[REG_B] == 0) { return 16; @@ -1635,7 +1330,7 @@ private int B3_OTIR(short OP) throws IOException { return 21; } - private int B8_LDDR(short OP) { + int I_LDDR(short OP) { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_D] << 8) | regs[REG_E]; memory.write(tmp2, memory.read(tmp1)); @@ -1658,85 +1353,34 @@ private int B8_LDDR(short OP) { return 21; } - private int B9_CPDR(short OP) { - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = (regs[REG_B] << 8) | regs[REG_C]; + int I_CPDR(short OP) { + int hl = (regs[REG_H] << 8) | regs[REG_L]; + int bc = (regs[REG_B] << 8) | regs[REG_C]; - int tmp = memory.read(tmp1); - tmp1 = (tmp1 - 1) & 0xFFFF; - tmp2 = (tmp2 - 1) & 0xFFFF; + int tmp = readByte(hl); + hl = (hl - 1) & 0xFFFF; + bc = (bc - 1) & 0xFFFF; flags = EmulatorTables.SIGN_ZERO_TABLE[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); auxCarry(regs[REG_A], (-tmp) & 0xFF); - if (tmp2 != 0) { + if (bc != 0) { flags |= FLAG_PV; } - regs[REG_H] = (tmp1 >>> 8) & 0xFF; - regs[REG_L] = tmp1 & 0xFF; - regs[REG_B] = (tmp2 >>> 8) & 0xFF; - regs[REG_C] = tmp2 & 0xFF; - - if ((tmp2 == 0) || (regs[REG_A] == tmp)) { - return 16; - } - PC = (PC - 2) & 0xFFFF; - return 21; - } - - private int BA_INDR(short OP) throws IOException { - int tmp = context.readIO(regs[REG_C]) & 0xFF; - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = tmp + ((regs[REG_C] - 1) & 0xFF); - - memory.write(tmp1, (byte) tmp); - tmp1 = (tmp1 - 1) & 0xFFFF; - regs[REG_H] = ((tmp1 >>> 8) & 0xff); - regs[REG_L] = (tmp1 & 0xFF); - regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_B]] | EmulatorTables.PARITY_TABLE[(tmp2 & 7) ^ regs[REG_B]]; - if ((tmp & 0x80) == 0x80) { - flags |= FLAG_N; - } - if (tmp2 > 0xFF) { - flags |= (FLAG_H | FLAG_C); - } - - if (regs[REG_B] == 0) { - return 16; - } - PC = (PC - 2) & 0xFFFF; - return 21; - } - - private int BB_OTDR(short OP) throws IOException { - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = memory.read(tmp1) & 0xFF; - - context.writeIO(regs[REG_C], (byte)tmp2); - tmp1 = (tmp1 - 1) & 0xFFFF; - regs[REG_H] = (tmp1 >>> 8); - regs[REG_L] = (tmp1 & 0xFF); - regs[REG_B] = (regs[REG_B] - 1) & 0xFF; - - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_B]] | EmulatorTables.PARITY_TABLE[((tmp2 + regs[REG_L]) & 7) ^ regs[REG_B]]; - if ((tmp2 & 0x80) == 0x80) { - flags |= FLAG_N; - } - if ((tmp2 + regs[REG_L]) > 0xFF) { - flags |= FLAG_C | FLAG_H; - } + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; - if (regs[REG_B] == 0) { + if ((bc == 0) || (regs[REG_A] == tmp)) { return 16; } PC = (PC - 2) & 0xFFFF; return 21; } - private int LD_LPAR_N_RPAR_SS(short OP) { + int I_LD_REF_NN_RP(short OP) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1745,7 +1389,7 @@ private int LD_LPAR_N_RPAR_SS(short OP) { return 20; } - private int LD_SS_LPAR_N_RPAR(short OP) { + int I_LD_RP_REF_NN(short OP) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1754,7 +1398,7 @@ private int LD_SS_LPAR_N_RPAR(short OP) { return 20; } - private int JR_CC_D(short OP) { + int I_JR_CC_N(short OP) { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; @@ -1766,7 +1410,7 @@ private int JR_CC_D(short OP) { return 7; } - private int O18_JR_E(short OP) { + int I_JR_N(short OP) { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; @@ -1775,98 +1419,57 @@ private int O18_JR_E(short OP) { return 12; } - private int C6_ADD_A_d(short OP) { - int tmp = memory.read(PC); + int I_ADD_A_N(short OP) { + int value = readByte(PC); PC = (PC + 1) & 0xFFFF; - - int DAR = regs[REG_A]; - regs[REG_A] += tmp; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF]; - regs[REG_A] = regs[REG_A] & 0xFF; - - auxCarry(DAR, tmp); - overflow(DAR, tmp, regs[REG_A]); - + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value) & 0xFF; + flags = flagSZHPC(oldA, value, regs[REG_A]); return 7; } - private int CE_ADC_A_d(short OP) { - int tmp = memory.read(PC); + int I_ADC_A_N(short OP) { + int value = readByte(PC); PC = (PC + 1) & 0xFFFF; - - int DAR = regs[REG_A]; - int diff = tmp; - if ((flags & FLAG_C) != 0) { - diff++; - } - regs[REG_A] += diff; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF]; - regs[REG_A] = regs[REG_A] & 0xFF; - - auxCarry(DAR, diff); - overflow(DAR, diff, regs[REG_A]); - + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; + flags = flagSZHPC(oldA, (value + (flags & FLAG_C)) & 0xFF, regs[REG_A]); return 7; } - private int D3_OUT_LPAR_D_RPAR_A(short OP) throws IOException { - int tmp = memory.read(PC); + int I_OUT_REF_N_A(short OP) throws IOException { + int tmp = readByte(PC); PC = (PC + 1) & 0xFFFF; - context.writeIO(tmp, (byte) regs[REG_A]); return 11; } - private int D6_SUB_d(short OP) { - int tmp = memory.read(PC); + int I_SUB_N(short OP) { + int value = ((~memory.read(PC)) + 1) & 0xFF; PC = (PC + 1) & 0xFFFF; - - int tmp1 = regs[REG_A]; - tmp = -tmp; - regs[REG_A] += tmp; - tmp &= 0xFF; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF] | FLAG_N; - regs[REG_A] = regs[REG_A] & 0xFF; - - auxCarry(tmp1, tmp); - overflow(tmp1, tmp, regs[REG_A]); - + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value) & 0xFF; + flags = flagSZHPC(oldA, value, regs[REG_A]) | FLAG_N; return 7; } - private int DB_IN_A_LPAR_d_RPAR(short OP) throws IOException { - int tmp = memory.read(PC); + int I_IN_A_REF_N(short OP) throws IOException { + int tmp = readByte(PC); PC = (PC + 1) & 0xFFFF; - regs[REG_A] = (context.readIO(tmp) & 0xFF); return 11; } - private int DE_SBC_A_d(short OP) { - int tmp = memory.read(PC); + int I_SBC_A_N(short OP) { + int value = ((~readByte(PC)) + 1) & 0xFF; PC = (PC + 1) & 0xFFFF; - - int tmp2 = regs[REG_A]; - int diff = -tmp; - if ((flags & FLAG_C) != 0) { - diff--; - } - regs[REG_A] += diff; - diff &= 0xFF; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF] | FLAG_N; - regs[REG_A] = regs[REG_A] & 0xFF; - - auxCarry(tmp2, diff); - overflow(tmp2, diff, regs[REG_A]); - + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value - (flags & FLAG_C)) & 0xFF; + flags = flagSZHPC(oldA, (value - (flags & FLAG_C)) & 0xFF, regs[REG_A]) | FLAG_N; return 7; } - private int E6_AND_d(short OP) { + int I_AND_N(short OP) { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; @@ -1875,7 +1478,7 @@ private int E6_AND_d(short OP) { return 7; } - private int EE_XOR_d(short OP) { + int I_XOR_N(short OP) { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; @@ -1884,7 +1487,7 @@ private int EE_XOR_d(short OP) { return 7; } - private int F6_OR_d(short OP) { + int I_OR_N(short OP) { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; @@ -1893,22 +1496,15 @@ private int F6_OR_d(short OP) { return 7; } - private int FE_CP_d(short OP) { - int tmp = memory.read(PC); + int I_CP_N(short OP) { + int value = ((~readByte(PC)) + 1) & 0xFF; PC = (PC + 1) & 0xFFFF; - - tmp = -tmp; - int tmp2 = regs[REG_A] + tmp; - tmp &= 0xFF; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[tmp2 & 0x1FF] | FLAG_N; - auxCarry(regs[REG_A], tmp); - overflow(regs[REG_A], tmp, tmp2 & 0xFF); - + int diff = (regs[REG_A] + value) & 0xFF; + flags = flagSZHPC(regs[REG_A], value, diff) | FLAG_N; return 7; } - private int LD_SS_NN(short OP) { + int I_LD_RP_NN(short OP) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1916,7 +1512,7 @@ private int LD_SS_NN(short OP) { return 10; } - private int JP_CC_NN(short OP) { + int I_JP_CC_NN(short OP) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1927,7 +1523,7 @@ private int JP_CC_NN(short OP) { return 10; } - private int CALL_CC_NN(short OP) { + int I_CALL_CC_NN(short OP) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1941,7 +1537,7 @@ private int CALL_CC_NN(short OP) { return 10; } - private int O22_LD_LPAR_NN_RPAR_HL(short OP) { + int I_LD_REF_NN_HL(short OP) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1950,7 +1546,7 @@ private int O22_LD_LPAR_NN_RPAR_HL(short OP) { return 16; } - private int O2A_LD_HL_LPAR_NN_RPAR(short OP) { + int I_LD_HL_REF_NN(short OP) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1959,7 +1555,7 @@ private int O2A_LD_HL_LPAR_NN_RPAR(short OP) { return 16; } - private int O32_LD_LPAR_NN_RPAR_A(short OP) { + int I_LD_REF_NN_A(short OP) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1967,7 +1563,7 @@ private int O32_LD_LPAR_NN_RPAR_A(short OP) { return 13; } - private int O3A_LD_A_LPAR_NN_RPAR(short OP) { + int I_LD_A_REF_NN(short OP) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1975,12 +1571,12 @@ private int O3A_LD_A_LPAR_NN_RPAR(short OP) { return 13; } - private int C3_JP_NN(short OP) { + int I_JP_NN(short OP) { PC = readWord(PC); return 10; } - private int CD_CALL_NN(short OP) { + int I_CALL_NN(short OP) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; SP = (SP - 2) & 0xffff; @@ -1989,680 +1585,818 @@ private int CD_CALL_NN(short OP) { return 17; } + int I_LD_R_R(short OP) { + int tmp = (OP >>> 3) & 0x07; + int tmp1 = OP & 0x07; + putreg(tmp, getreg(tmp1)); + if ((tmp1 == 6) || (tmp == 6)) { + return 7; + } else { + return 4; + } + } - private int dispatch(short OP) throws IOException, InvocationTargetException, IllegalAccessException { - int tmp, tmp1, tmp2, tmp3; - short special = 0; // prefix if available = 0xDD or 0xFD + int I_HALT(short OP) { + currentRunState = RunState.STATE_STOPPED_NORMAL; + return 4; + } - DispatchListener tmpListener = dispatchListener; - if (tmpListener != null) { - tmpListener.beforeDispatch(); + int I_RLC_R(short OP) { + int tmp = OP & 7; + int tmp1 = getreg(tmp) & 0xFF; + + int tmp2 = (tmp1 >>> 7) & 1; + tmp1 = (((tmp1 << 1) & 0xFF) | tmp2) & 0xFF; + putreg(tmp, tmp1); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + + if (tmp == 6) { + return 15; + } else { + return 8; } + } - try { - /* if interrupt is waiting, instruction won't be read from memory - * but from one or all of 3 bytes (b1,b2,b3) which represents either - * rst or call instruction incomed from external peripheral device - */ - if (isINT) { - return doInterrupt(); - } - incrementR(); - if (OP == 0x76) { /* HALT */ - currentRunState = RunState.STATE_STOPPED_NORMAL; - return 4; - } + int I_RRC_R(short OP) { + int tmp = OP & 7; + int tmp1 = getreg(tmp) & 0xFF; - /* Handle below all operations which refer to registers or register pairs. - After that, a large switch statement takes care of all other opcodes */ - switch (OP & 0xC0) { - case 0x40: /* LD r,r' */ - tmp = (OP >>> 3) & 0x07; - tmp1 = OP & 0x07; - putreg(tmp, (short) getreg(tmp1)); - if ((tmp1 == 6) || (tmp == 6)) { - return 7; - } else { - return 4; - } - } + int tmp2 = tmp1 & 1; + tmp1 = (((tmp1 >>> 1) & 0x7F) | (tmp2 << 7)) & 0xFF; + putreg(tmp, tmp1); - /* Dispatch Instruction */ - Method instr = DISPATCH_TABLE[OP]; - if (instr != null) { - return (Integer) instr.invoke(this, OP); - } + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - switch (OP) { - case 0xDD: - special = 0xDD; - case 0xFD: - if (OP == 0xFD) { - special = 0xFD; - } - OP = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - incrementR(); - switch (OP) { - /* ADD ii,pp */ - case 0x09: - case 0x19: - case 0x29: - case 0x39: - tmp = getspecial(special); - tmp1 = getpair(special, (OP >>> 4) & 0x03); - - carry15(tmp, tmp1); - halfCarry11(tmp, tmp1); - flags &= (~(FLAG_N | FLAG_S | FLAG_Z)); - - tmp += tmp1; - flags |= ((tmp & 0x8000) == 0x8000) ? FLAG_S : 0; - flags |= (tmp == 0) ? FLAG_Z : 0; - putspecial(special, tmp); - return 15; - case 0x23: /* INC ii */ - if (special == 0xDD) { - IX = (IX + 1) & 0xFFFF; - } else { - IY = (IY + 1) & 0xFFFF; - } - return 10; - case 0x2B: /* DEC ii */ - if (special == 0xDD) { - IX = (IX - 1) & 0xFFFF; - } else { - IY = (IY - 1) & 0xFFFF; - } - return 10; - case 0xE1: /* POP ii */ - if (special == 0xDD) { - IX = readWord(SP); - } else { - IY = readWord(SP); - } - SP = (SP + 2) & 0xFFFF; - return 14; - case 0xE3: /* EX (SP),ii */ - tmp = readWord(SP); - if (special == 0xDD) { - tmp1 = IX; - IX = tmp; - } else { - tmp1 = IY; - IY = tmp; - } - writeWord(SP, tmp1); - return 23; - case 0xE5: /* PUSH ii */ - SP = (SP - 2) & 0xFFFF; - if (special == 0xDD) { - writeWord(SP, IX); - } else { - writeWord(SP, IY); - } - return 15; - case 0xE9: /* JP (ii) */ - if (special == 0xDD) { - PC = IX; - } else { - PC = IY; - } - return 8; - case 0xF9: /* LD SP,ii */ - SP = (special == 0xDD) ? IX : IY; - return 10; - } + if (tmp == 6) { + return 15; + } else { + return 8; + } + } - tmp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - switch (OP) { - case 0x76: - break; - /* LD r,(ii+d) */ - case 0x46: - case 0x4E: - case 0x56: - case 0x5E: - case 0x66: - case 0x6E: - case 0x7E: - tmp1 = (OP >>> 3) & 7; - putreg2(tmp1, memory.read((getspecial(special) + (byte) tmp) & 0xFFFF)); - return 19; - /* LD (ii+d),r */ - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x77: - tmp1 = (OP & 7); - tmp2 = (getspecial(special) + (byte) tmp) & 0xFFFF; - memory.write(tmp2, (byte) getreg2(tmp1)); - return 19; - case 0x34: /* INC (ii+d) */ - tmp1 = (getspecial(special) + (byte) tmp) & 0xFFFF; - tmp2 = (memory.read(tmp1) + 1) & 0xFF; - - memory.write(tmp1, (byte) tmp2); - flags = EmulatorTables.INC_TABLE[tmp2] | (flags & FLAG_C); - return 23; - case 0x35: /* DEC (ii+d) */ - tmp1 = (getspecial(special) + (byte) tmp) & 0xFFFF; - tmp2 = (memory.read(tmp1) - 1) & 0xFF; - memory.write(tmp1, (byte) tmp2); - flags = EmulatorTables.DEC_TABLE[tmp2] | (flags & FLAG_C); - return 23; - case 0x86: /* ADD A,(ii+d) */ - tmp1 = regs[REG_A]; - tmp2 = memory.read((getspecial(special) + (byte) tmp) & 0xFFFF) & 0xFF; - - regs[REG_A] += tmp2; - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF]; - regs[REG_A] = regs[REG_A] & 0xFF; - - auxCarry(tmp1, tmp2); - overflow(tmp1, tmp2, regs[REG_A]); - - return 19; - case 0x8E: /* ADC A,(ii+d) */ - tmp1 = regs[REG_A]; - tmp2 = memory.read((getspecial(special) + (byte) tmp) & 0xFFFF) & 0xFF; - if ((flags & FLAG_C) == FLAG_C) { - tmp2++; - } - regs[REG_A] += tmp2; - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF]; - regs[REG_A] = regs[REG_A] & 0xFF; - - auxCarry(tmp1, tmp2); - overflow(tmp1, tmp2, regs[REG_A]); - - return 19; - case 0x96: /* SUB (ii+d) */ - tmp1 = regs[REG_A]; - tmp2 = -(memory.read((getspecial(special) + (byte) tmp) & 0xFFFF) & 0xFF); - - regs[REG_A] += tmp2; - tmp2 &= 0xFF; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF] | FLAG_N; - regs[REG_A] = (short) (regs[REG_A] & 0xFF); - - auxCarry(tmp1, tmp2); - overflow(tmp1, tmp2, regs[REG_A]); - - return 19; - case 0x9E: /* SBC A,(ii+d) */ - tmp1 = regs[REG_A]; - tmp2 = -(memory.read((getspecial(special) + (byte) tmp) & 0xFFFF) & 0xFF); - if ((flags & FLAG_C) == FLAG_C) { - tmp2--; - } - regs[REG_A] += tmp2; - tmp2 &= 0xFF; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[regs[REG_A] & 0x1FF] | FLAG_N; - regs[REG_A] = regs[REG_A] & 0xFF; - - auxCarry(tmp1, tmp2); - overflow(tmp1, tmp2, regs[REG_A]); - - return 19; - case 0xA6: /* AND (ii+d) */ - tmp1 = memory.read((getspecial(special) + (byte) tmp) & 0xFFFF); - regs[REG_A] = (regs[REG_A] & tmp1) & 0xFF; - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; - return 19; - case 0xAE: /* XOR (ii+d) */ - tmp1 = memory.read((getspecial(special) + (byte) tmp) & 0xFFFF); - regs[REG_A] = ((regs[REG_A] ^ tmp1) & 0xff); - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; - return 19; - case 0xB6: /* OR (ii+d) */ - tmp1 = memory.read((getspecial(special) + (byte) tmp) & 0xFFFF); - regs[REG_A] = ((regs[REG_A] | tmp1) & 0xff); - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; - return 19; - case 0xBE: /* CP (ii+d) */ - int diff = -memory.read((getspecial(special) + (byte) tmp) & 0xFFFF); - tmp2 = regs[REG_A] + diff; - diff &= 0xFF; - - flags = EmulatorTables.SIGN_ZERO_CARRY_TABLE[tmp2 & 0x1FF] | FLAG_N; - auxCarry(regs[REG_A], diff); - overflow(regs[REG_A], diff, tmp2 & 0xFF); - - return 19; - } - tmp |= ((memory.read(PC)) << 8); - PC = (PC + 1) & 0xFFFF; - switch (OP) { - case 0x21: /* LD ii,nn */ - putspecial(special, tmp); - return 14; - case 0x22: /* LD (nn),ii */ - writeWord(tmp, getspecial(special)); - return 16; - case 0x2A: /* LD ii,(nn) */ - tmp1 = readWord(tmp); - putspecial(special, tmp1); - return 20; - case 0x36: /* LD (ii+d),n */ - memory.write((getspecial(special) + (byte) (tmp & 0xFF)) & 0xFFFF, (byte) ((tmp >>> 8))); - return 19; - case 0xCB: - OP = (short) ((tmp >>> 8) & 0xff); - tmp &= 0xff; - switch (OP) { - /* BIT b,(ii+d) */ - case 0x46: - case 0x4E: - case 0x56: - case 0x5E: - case 0x66: - case 0x6E: - case 0x76: - case 0x7E: - tmp2 = (OP >>> 3) & 7; - tmp1 = memory.read((getspecial(special) + (byte) tmp) & 0xffff); - flags = ((flags & FLAG_C) | FLAG_H | (((tmp1 & (1 << tmp2)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); - if (tmp2 == 7) { - flags |= (((tmp1 & (1 << 7)) == 0x80) ? FLAG_S : 0); - } - return 20; - case 0x78: // undocumented BIT 7,(ii+d) - case 0x79: - case 0x7A: - case 0x7B: - case 0x7C: - case 0x7D: - case 0x7F: - tmp1 = memory.read((getspecial(special) + (byte) tmp) & 0xffff); - flags = ((flags & FLAG_C) | FLAG_H | (((tmp1 & (1 << 7)) == 0) ? (FLAG_Z | FLAG_PV) : 0)) - | (((tmp1 & (1 << 7)) == 0x80) ? FLAG_S : 0); - return 20; - /* RES b,(ii+d) */ - case 0x86: - case 0x8E: - case 0x96: - case 0x9E: - case 0xA6: - case 0xAE: - case 0xB6: - case 0xBE: - tmp2 = (OP >>> 3) & 7; - tmp3 = (getspecial(special) + (byte) tmp) & 0xffff; - tmp1 = memory.read(tmp3); - tmp1 = (tmp1 & (~(1 << tmp2))); - memory.write(tmp3, (byte) (tmp1 & 0xff)); - return 23; - /* SET b,(ii+d) */ - case 0xC6: - case 0xCE: - case 0xD6: - case 0xDE: - case 0xE6: - case 0xEE: - case 0xF6: - case 0xFE: - tmp2 = (OP >>> 3) & 7; - tmp3 = (getspecial(special) + (byte) tmp) & 0xffff; - tmp1 = memory.read(tmp3); - tmp1 = (tmp1 | (1 << tmp2)); - memory.write(tmp3, (byte) (tmp1 & 0xff)); - return 23; - /* SET 0,(ii+d),reg (undocumented) */ - case 0xC0: - case 0xC1: - case 0xC2: - case 0xC3: - case 0xC4: - case 0xC5: - case 0xC7: - tmp2 = (OP >>> 3) & 7; - tmp3 = (getspecial(special) + (byte) tmp) & 0xffff; - tmp1 = memory.read(tmp3); - tmp1 = (tmp1 | (1 << tmp2)); - memory.write(tmp3, (byte) (tmp1 & 0xff)); - regs[OP & 7] = tmp1 & 0xFF; - return 23; - case 0x06: /* RLC (ii+d) */ - case 0: // undocumented - tmp = (getspecial(special) + (byte) tmp) & 0xffff; - tmp1 = memory.read(tmp); - - tmp2 = (tmp1 >>> 7) & 1; - tmp1 = ((((tmp1 << 1) & 0xFF) | tmp2) & 0xFF); - - memory.write(tmp, (byte) (tmp1 & 0xFF)); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - if (OP == 0) { - regs[REG_B] = tmp1 & 0xFF; - } - return 23; - case 0x0E: /* RRC (ii+d) */ - tmp = (getspecial(special) + (byte) tmp) & 0xffff; - tmp1 = memory.read(tmp); - - tmp2 = tmp1 & 1; - tmp1 = (((tmp1 >>> 1) & 0x7F) | (tmp2 << 7)) & 0xFF; - - memory.write(tmp, (byte) (tmp1 & 0xFF)); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - return 23; - case 0x16: /* RL (ii+d) */ - tmp = (getspecial(special) + (byte) tmp) & 0xffff; - tmp1 = memory.read(tmp); - - tmp2 = (tmp1 >>> 7) & 1; - tmp1 = ((((tmp1 << 1) & 0xFF) | flags & FLAG_C) & 0xFF); - memory.write(tmp, (byte) (tmp1 & 0xFF)); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - return 23; - case 0x1E: /* RR (ii+d) */ - tmp = (getspecial(special) + (byte) tmp) & 0xffff; - tmp1 = memory.read(tmp); - - tmp2 = tmp1 & 1; - tmp1 = ((((tmp1 >> 1) & 0xFF) | (flags & FLAG_C) << 7) & 0xFF); - memory.write(tmp, (byte) (tmp1 & 0xFF)); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - return 23; - case 0x26: /* SLA (ii+d) */ - tmp = (getspecial(special) + (byte) tmp) & 0xffff; - tmp1 = memory.read(tmp); - - tmp2 = (tmp1 >>> 7) & 1; - tmp1 = (tmp1 << 1) & 0xFE; - memory.write(tmp, (byte) tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - return 23; - case 0x2E: /* SRA (ii+d) */ - tmp = (getspecial(special) + (byte) tmp) & 0xffff; - tmp1 = memory.read(tmp); - - tmp2 = tmp1 & 1; - tmp1 = (tmp1 >> 1) & 0xFF | (tmp1 & 0x80); - memory.write(tmp, (byte) tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - return 23; - case 0x36: /* SLL (ii+d) unsupported */ - tmp = (getspecial(special) + (byte) tmp) & 0xffff; - tmp1 = memory.read(tmp); - - tmp2 = (tmp1 >>> 7) & 1; - tmp1 = (tmp1 << 1) & 0xFF | tmp1 & 1; - memory.write(tmp, (byte) tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - return 23; - case 0x3E: /* SRL (ii+d) */ - tmp = (getspecial(special) + (byte) tmp) & 0xffff; - tmp1 = memory.read(tmp); - - tmp2 = tmp1 & 1; - tmp1 = (tmp1 >>> 1) & 0x7F; - memory.write(tmp, (byte) tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - return 23; - } - currentRunState = RunState.STATE_STOPPED_BAD_INSTR; - return 0; - } - currentRunState = RunState.STATE_STOPPED_BAD_INSTR; - return 0; - case 0xCB: - OP = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - incrementR(); - switch (OP) { - /* RLC r */ - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - tmp = OP & 7; - tmp1 = getreg(tmp); - - tmp2 = (tmp1 >>> 7) & 1; - tmp1 = (((tmp1 << 1) & 0xFF) | tmp2) & 0xFF; - putreg(tmp, tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - if (tmp == 6) { - return 15; - } else { - return 8; - } - /* RRC r */ - case 0x08: - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - case 0x0E: - case 0x0F: - tmp = OP & 7; - tmp1 = getreg(tmp); - - tmp2 = tmp1 & 1; - tmp1 = (((tmp1 >>> 1) & 0x7F) | (tmp2 << 7)) & 0xFF; - putreg(tmp, tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - if (tmp == 6) { - return 15; - } else { - return 8; - } - /* RL r */ - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - tmp = OP & 7; - tmp1 = getreg(tmp); - - tmp2 = (tmp1 >>> 7) & 1; - tmp1 = ((((tmp1 << 1) & 0xFF) | flags & FLAG_C) & 0xFF); - putreg(tmp, tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - if (tmp == 6) { - return 15; - } else { - return 8; - } - /* RR r */ - case 0x18: - case 0x19: - case 0x1A: - case 0x1B: - case 0x1C: - case 0x1D: - case 0x1E: - case 0x1F: - tmp = OP & 7; - tmp1 = getreg(tmp); - - tmp2 = tmp1 & 1; - tmp1 = ((((tmp1 >> 1) & 0x7F) | (flags & FLAG_C) << 7) & 0xFF); - putreg(tmp, tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - if (tmp == 6) { - return 15; - } else { - return 8; - } - /* SLA r */ - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: - tmp = OP & 7; - tmp1 = getreg(tmp); - - tmp2 = (tmp1 >>> 7) & 1; - tmp1 = (tmp1 << 1) & 0xFE; - putreg(tmp, tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - if (tmp == 6) { - return 15; - } else { - return 8; - } - /* SRA r */ - case 0x28: - case 0x29: - case 0x2A: - case 0x2B: - case 0x2C: - case 0x2D: - case 0x2E: - case 0x2F: - tmp = OP & 7; - tmp1 = getreg(tmp); - - tmp2 = tmp1 & 1; - tmp1 = (tmp1 >> 1) & 0xFF | (tmp1 & 0x80); - putreg(tmp, tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - if (tmp == 6) { - return 15; - } else { - return 8; - } - /* SLL r - unsupported */ - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - tmp = OP & 7; - tmp1 = getreg(tmp); - - tmp2 = (tmp1 >>> 7) & 1; - tmp1 = (tmp1 << 1) & 0xFF | tmp1 & 1; - putreg(tmp, tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - if (tmp == 6) { - return 15; - } else { - return 8; - } - /* SRL r */ - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - case 0x3E: - case 0x3F: - tmp = OP & 7; - tmp1 = getreg(tmp); - - tmp2 = tmp1 & 1; - tmp1 = (tmp1 >>> 1) & 0x7F; - putreg(tmp, tmp1); - - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - if (tmp == 6) { - return 15; - } else { - return 8; - } - } - switch (OP & 0xC0) { - case 0x40: /* BIT b,r */ - tmp = (OP >>> 3) & 7; - tmp2 = OP & 7; - tmp1 = getreg(tmp2); - flags = ((flags & FLAG_C) | FLAG_H | (((tmp1 & (1 << tmp)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); - if (tmp == 7) { - flags |= (((tmp1 & (1 << tmp)) == 0x80) ? FLAG_S : 0); - } - if (tmp2 == 6) { - return 12; - } else { - return 8; - } - case 0x80: /* RES b,r */ - tmp = (OP >>> 3) & 7; - tmp2 = OP & 7; - tmp1 = getreg(tmp2); - tmp1 = (tmp1 & (~(1 << tmp))); - putreg(tmp2, tmp1); - if (tmp2 == 6) { - return 15; - } else { - return 8; - } - case 0xC0: /* SET b,r */ - tmp = (OP >>> 3) & 7; - tmp2 = OP & 7; - tmp1 = getreg(tmp2); - tmp1 = (tmp1 | (1 << tmp)); - putreg(tmp2, tmp1); - if (tmp2 == 6) { - return 15; - } else { - return 8; - } - } - } + int I_RL_R(short OP) { + int tmp = OP & 7; + int tmp1 = getreg(tmp)& 0xFF; - currentRunState = CPU.RunState.STATE_STOPPED_BAD_INSTR; - } finally { - if (tmpListener != null) { - tmpListener.afterDispatch(); - } + int tmp2 = (tmp1 >>> 7) & 1; + tmp1 = ((((tmp1 << 1) & 0xFF) | flags & FLAG_C) & 0xFF); + putreg(tmp, tmp1); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + + if (tmp == 6) { + return 15; + } else { + return 8; } - return 0; } + int I_RR_R(short OP) { + int tmp = OP & 7; + int tmp1 = getreg(tmp) & 0xFF; + + int tmp2 = tmp1 & 1; + tmp1 = ((((tmp1 >> 1) & 0x7F) | (flags & FLAG_C) << 7) & 0xFF); + putreg(tmp, tmp1); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + + if (tmp == 6) { + return 15; + } else { + return 8; + } + } + + int I_SLA_R(short OP) { + int tmp = OP & 7; + int tmp1 = getreg(tmp) & 0xFF; + + int tmp2 = (tmp1 >>> 7) & 1; + tmp1 = (tmp1 << 1) & 0xFE; + putreg(tmp, tmp1); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + + if (tmp == 6) { + return 15; + } else { + return 8; + } + } + + int I_SRA_R(short OP) { + int tmp = OP & 7; + int tmp1 = getreg(tmp) & 0xFF; + + int tmp2 = tmp1 & 1; + tmp1 = (tmp1 >> 1) & 0xFF | (tmp1 & 0x80); + putreg(tmp, tmp1); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + + if (tmp == 6) { + return 15; + } else { + return 8; + } + } + + int I_SLL_R(short OP) { + int tmp = OP & 7; + int tmp1 = getreg(tmp) & 0xFF; + + int tmp2 = (tmp1 >>> 7) & 1; + tmp1 = (tmp1 << 1) & 0xFF | tmp1 & 1; + putreg(tmp, tmp1); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + + if (tmp == 6) { + return 15; + } else { + return 8; + } + } + + int I_SRL_R(short OP) { + int tmp = OP & 7; + int tmp1 = getreg(tmp) & 0xFF; + + int tmp2 = tmp1 & 1; + tmp1 = (tmp1 >>> 1) & 0x7F; + putreg(tmp, tmp1); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + + if (tmp == 6) { + return 15; + } else { + return 8; + } + } + + + int I_BIT_N_R(short OP) { + int tmp = (OP >>> 3) & 7; + int tmp2 = OP & 7; + int tmp1 = getreg(tmp2) & 0xFF; + flags = ((flags & FLAG_C) | FLAG_H | (((tmp1 & (1 << tmp)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); + if (tmp == 7) { + flags |= (((tmp1 & (1 << tmp)) == 0x80) ? FLAG_S : 0); + } + if (tmp2 == 6) { + return 12; + } else { + return 8; + } + } + + int I_RES_N_R(short OP) { + int tmp = (OP >>> 3) & 7; + int tmp2 = OP & 7; + int tmp1 = getreg(tmp2) & 0xFF; + tmp1 = (tmp1 & (~(1 << tmp))); + putreg(tmp2, tmp1); + if (tmp2 == 6) { + return 15; + } else { + return 8; + } + } + + int I_SET_N_R(short OP) { + int tmp = (OP >>> 3) & 7; + int tmp2 = OP & 7; + int tmp1 = getreg(tmp2) & 0xFF; + tmp1 = (tmp1 | (1 << tmp)); + putreg(tmp2, tmp1); + if (tmp2 == 6) { + return 15; + } else { + return 8; + } + } + + int I_ADD_IX_RP(short OP) { + return I_ADD_II_RP(OP, (short) 0xDD); + } + + int I_ADD_IY_RP(short OP) { + return I_ADD_II_RP(OP, (short) 0xFD); + } + + int I_ADD_II_RP(short OP, short special) { + int tmp = getspecial(special); + int tmp1 = getpair(special, (OP >>> 4) & 0x03); + + carry15(tmp, tmp1); + halfCarry11(tmp, tmp1); + flags &= (~(FLAG_N | FLAG_S | FLAG_Z)); + + tmp += tmp1; + flags |= ((tmp & 0x8000) == 0x8000) ? FLAG_S : 0; + flags |= (tmp == 0) ? FLAG_Z : 0; + putspecial(special, tmp); + return 15; + } + + int I_LD_IX_NN(short OP) { + return I_LD_II_NN(OP, (short) 0xDD); + } + + int I_LD_IY_NN(short OP) { + return I_LD_II_NN(OP, (short) 0xFD); + } + + int I_LD_II_NN(short OP, short special) { + int tmp = readWord(PC); + PC = (PC + 2) & 0xFFFF; + putspecial(special, tmp); + return 14; + } + + int I_LD_REF_NN_IX(short OP) { + return I_LD_REF_NN_II(OP, (short) 0xDD); + } + + int I_LD_REF_NN_IY(short OP) { + return I_LD_REF_NN_II(OP, (short) 0xFD); + } + + int I_LD_REF_NN_II(short OP, short special) { + int tmp = readWord(PC); + PC = (PC + 2) & 0xFFFF; + writeWord(tmp, getspecial(special)); + return 16; + } + + int I_INC_IX(short OP) { + return I_INC_II(OP, (short) 0xDD); + } + + int I_INC_IY(short OP) { + return I_INC_II(OP, (short) 0xFD); + } + + int I_INC_II(short OP, short special) { + if (special == 0xDD) { + IX = (IX + 1) & 0xFFFF; + } else { + IY = (IY + 1) & 0xFFFF; + } + return 10; + } + + int I_LD_IX_REF_NN(short OP) { + return I_LD_II_REF_NN(OP, (short) 0xDD); + } + + int I_LD_IY_REF_NN(short OP) { + return I_LD_II_REF_NN(OP, (short) 0xFD); + } + + int I_LD_II_REF_NN(short OP, short special) { + int tmp = readWord(PC); + PC = (PC + 2) & 0xFFFF; + int tmp1 = readWord(tmp); + putspecial(special, tmp1); + return 20; + } + + int I_DEC_IX(short OP) { + return I_DEC_II(OP, (short) 0xDD); + } + + int I_DEC_IY(short OP) { + return I_DEC_II(OP, (short) 0xFD); + } + + int I_DEC_II(short OP, short special) { + putspecial(special, getspecial(special) - 1); + return 10; + } + + int I_INC_REF_IX_N(short OP) { + return I_INC_REF_II_N(OP, (short) 0xDD); + } + + int I_INC_REF_IY_N(short OP) { + return I_INC_REF_II_N(OP, (short) 0xFD); + } + + int I_INC_REF_II_N(short OP, short special) { + int tmp = readByte(PC); + PC = (PC + 1) & 0xFFFF; + int tmp1 = (getspecial(special) + (byte) tmp) & 0xFFFF; + int tmp2 = (memory.read(tmp1) + 1) & 0xFF; + + memory.write(tmp1, (byte) tmp2); + flags = EmulatorTables.INC_TABLE[tmp2] | (flags & FLAG_C); + return 23; + } + + int I_DEC_REF_IX_N(short OP) { + return I_DEC_REF_II_N(OP, (short) 0xDD); + } + + int I_DEC_REF_IY_N(short OP) { + return I_DEC_REF_II_N(OP, (short) 0xFD); + } + + int I_DEC_REF_II_N(short OP, short special) { + int tmp = readByte(PC); + PC = (PC + 1) & 0xFFFF; + int tmp1 = (getspecial(special) + (byte) tmp) & 0xFFFF; + int tmp2 = (memory.read(tmp1) - 1) & 0xFF; + memory.write(tmp1, (byte) tmp2); + flags = EmulatorTables.DEC_TABLE[tmp2] | (flags & FLAG_C); + return 23; + } + + int I_LD_REF_IX_N_N(short OP) { + return I_LD_REF_II_N_N(OP, (short) 0xDD); + } + + int I_LD_REF_IY_N_N(short OP) { + return I_LD_REF_II_N_N(OP, (short) 0xFD); + } + + int I_LD_REF_II_N_N(short OP, short special) { + byte offset = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + byte number = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + memory.write((getspecial(special) + offset) & 0xFFFF, number); + return 19; + } + + int I_LD_R_REF_IX_N(short OP) { + return I_LD_R_REF_II_N(OP, (short) 0xDD); + } + + int I_LD_R_REF_IY_N(short OP) { + return I_LD_R_REF_II_N(OP, (short) 0xFD); + } + + int I_LD_R_REF_II_N(short OP, short special) { + byte offset = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int tmp1 = (OP >>> 3) & 7; + putreg2(tmp1, memory.read((getspecial(special) + offset) & 0xFFFF)); + return 19; + } + + int I_LD_REF_IX_N_R(short OP) { + return I_LD_REF_II_N_R(OP, (short)0xDD); + } + + int I_LD_REF_IY_N_R(short OP) { + return I_LD_REF_II_N_R(OP, (short)0xFD); + } + + int I_LD_REF_II_N_R(short OP, short special) { + byte tmp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int tmp1 = (OP & 7); + memory.write((getspecial(special) + tmp) & 0xFFFF, getreg2(tmp1)); + return 19; + } + + int I_ADD_A_REF_IX_N(short OP) { + return I_ADD_A_REF_II_N(OP, (short)0xDD); + } + + int I_ADD_A_REF_IY_N(short OP) { + return I_ADD_A_REF_II_N(OP, (short)0xFD); + } + + int I_ADD_A_REF_II_N(short OP, short special) { + byte offset = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int value = readByte((getspecial(special) + offset) & 0xFFFF); + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value) & 0xFF; + flags = flagSZHPC(oldA, value, regs[REG_A]); + return 19; + } + + int I_ADC_A_REF_IX_N(short OP) { + return I_ADC_A_REF_II_N(OP, (short) 0xDD); + } + + int I_ADC_A_REF_IY_N(short OP) { + return I_ADC_A_REF_II_N(OP, (short) 0xFD); + } + + int I_ADC_A_REF_II_N(short OP, short special) { + byte offset = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int value = readByte((getspecial(special) + offset) & 0xFFFF); + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; + flags = flagSZHPC(oldA, (value + (flags & FLAG_C)) & 0xFF, regs[REG_A]); + return 19; + } + + int I_SUB_REF_IX_N(short OP) { + return I_SUB_REF_II_N(OP, (short) 0xDD); + } + + int I_SUB_REF_IY_N(short OP) { + return I_SUB_REF_II_N(OP, (short) 0xFD); + } + + int I_SUB_REF_II_N(short OP, short special) { + byte offset = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int value = ((~readByte((getspecial(special) + offset) & 0xFFFF)) + 1) & 0xFF; + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value) & 0xFF; + flags = flagSZHPC(oldA, value, regs[REG_A]) | FLAG_N; + return 19; + } + + int I_SBC_A_REF_IX_N(short OP) { + return I_SBC_A_REF_II_N(OP, (short) 0xDD); + } + + int I_SBC_A_REF_IY_N(short OP) { + return I_SBC_A_REF_II_N(OP, (short) 0xFD); + } + + int I_SBC_A_REF_II_N(short OP, short special) { + byte offset = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int value = ((~readByte((getspecial(special) + offset) & 0xFFFF)) + 1) & 0xFF; + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value - (flags & FLAG_C)) & 0xFF; + flags = flagSZHPC(oldA, (value - (flags & FLAG_C)) & 0xFF, regs[REG_A]) | FLAG_N; + return 19; + } + + int I_AND_REF_IX_N(short OP) { + return I_AND_REF_II_N(OP, (short) 0xDD); + } + + int I_AND_REF_IY_N(short OP) { + return I_AND_REF_II_N(OP, (short) 0xFD); + } + + int I_AND_REF_II_N(short OP, short special) { + byte tmp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + + int tmp1 = memory.read((getspecial(special) + tmp) & 0xFFFF); + regs[REG_A] = (regs[REG_A] & tmp1) & 0xFF; + flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + return 19; + } + + int I_XOR_REF_IX_N(short OP) { + return I_XOR_REF_II_N(OP, (short) 0xDD); + } + + int I_XOR_REF_IY_N(short OP) { + return I_XOR_REF_II_N(OP, (short) 0xFD); + } + + int I_XOR_REF_II_N(short OP, short special) { + byte tmp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + + int tmp1 = memory.read((getspecial(special) + tmp) & 0xFFFF); + regs[REG_A] = ((regs[REG_A] ^ tmp1) & 0xff); + flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + return 19; + } + + int I_OR_REF_IX_N(short OP) { + return I_OR_REF_II_N(OP, (short) 0xDD); + } + + int I_OR_REF_IY_N(short OP) { + return I_OR_REF_II_N(OP, (short) 0xFD); + } + + int I_OR_REF_II_N(short OP, short special) { + byte tmp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int tmp1 = memory.read((getspecial(special) + tmp) & 0xFFFF); + regs[REG_A] = ((regs[REG_A] | tmp1) & 0xff); + flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + return 19; + } + + int I_CP_REF_IX_N(short OP) { + return I_CP_REF_II_N(OP, (short) 0xDD); + } + + int I_CP_REF_IY_N(short OP) { + return I_CP_REF_II_N(OP, (short) 0xFD); + } + + int I_CP_REF_II_N(short OP, short special) { + byte offset = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int value = ((~readByte((getspecial(special) + offset) & 0xFFFF)) + 1) & 0xFF; + int diff = (regs[REG_A] + value) & 0xFF; + flags = flagSZHPC(regs[REG_A], value, diff) | FLAG_N; + return 19; + } + + int I_POP_IX(short OP) { + IX = readWord(SP); + SP = (SP + 2) & 0xFFFF; + return 14; + } + + int I_POP_IY(short OP) { + IY = readWord(SP); + SP = (SP + 2) & 0xFFFF; + return 14; + } + + int I_EX_REF_SP_IX(short OP) { + int tmp = readWord(SP); + int tmp1 = IX; + IX = tmp; + writeWord(SP, tmp1); + return 23; + } + + int I_EX_REF_SP_IY(short OP) { + int tmp = readWord(SP); + int tmp1 = IY; + IY = tmp; + writeWord(SP, tmp1); + return 23; + } + + int I_PUSH_IX(short OP) { + SP = (SP - 2) & 0xFFFF; + writeWord(SP, IX); + return 15; + } + + int I_PUSH_IY(short OP) { + SP = (SP - 2) & 0xFFFF; + writeWord(SP, IY); + return 15; + } + + int I_JP_REF_IX(short OP) { + PC = IX; + return 8; + } + + int I_JP_REF_IY(short OP) { + PC = IY; + return 8; + } + + int I_LD_SP_IX(short OP) { + SP = IX; + return 10; + } + + int I_LD_SP_IY(short OP) { + SP = IY; + return 10; + } + + int I_RLC_REF_IX_N_R(short OP, byte operand) { + return I_RLC_REF_II_N_R(OP, operand, (short) 0xDD); + } + + int I_RLC_REF_IY_N_R(short OP, byte operand) { + return I_RLC_REF_II_N_R(OP, operand, (short) 0xFD); + } + + int I_RLC_REF_II_N_R(short OP, byte operand, short special) { + int address = (getspecial(special) + operand) & 0xFFFF; + int value = readByte(address); + int bit7 = (value >>> 7) & 1; + + value = (((value << 1) | bit7) & 0xFF); + memory.write(address, (byte) value); + flags = EmulatorTables.SIGN_ZERO_TABLE[value] | EmulatorTables.PARITY_TABLE[value] | bit7; + + // regs[6] is unused, so it's ok + regs[OP & 7] = value & 0xFF; + return 23; + } + + int I_RRC_REF_IX_N_R(short OP, byte operand) { + return I_RRC_REF_II_N_R(OP, operand, (short) 0xDD); + } + + int I_RRC_REF_IY_N_R(short OP, byte operand) { + return I_RRC_REF_II_N_R(OP, operand, (short) 0xFD); + } + + int I_RRC_REF_II_N_R(short OP, byte operand, short special) { + int tmp = (getspecial(special) + operand) & 0xffff; + int tmp1 = memory.read(tmp); + + int tmp2 = tmp1 & 1; + tmp1 = (((tmp1 >>> 1) & 0x7F) | (tmp2 << 7)) & 0xFF; + + memory.write(tmp, (byte) (tmp1 & 0xFF)); + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + + // regs[6] is unused, so it's ok + regs[OP & 7] = tmp1 & 0xFF; + return 23; + } + + int I_RL_REF_IX_N_R(short OP, byte operand) { + return I_RL_REF_II_N_R(OP, operand, (short) 0xDD); + } + + int I_RL_REF_IY_N_R(short OP, byte operand) { + return I_RL_REF_II_N_R(OP, operand, (short) 0xFD); + } + + int I_RL_REF_II_N_R(short OP, byte operand, short special) { + int tmp = (getspecial(special) + operand) & 0xffff; + int tmp1 = memory.read(tmp); + + int tmp2 = (tmp1 >>> 7) & 1; + tmp1 = ((((tmp1 << 1) & 0xFF) | flags & FLAG_C) & 0xFF); + memory.write(tmp, (byte) (tmp1 & 0xFF)); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + // regs[6] is unused, so it's ok + regs[OP & 7] = tmp1 & 0xFF; + return 23; + } + + int I_RR_REF_IX_N_R(short OP, byte operand) { + return I_RR_REF_II_N_R(OP, operand, (short) 0xDD); + } + + int I_RR_REF_IY_N_R(short OP, byte operand) { + return I_RR_REF_II_N_R(OP, operand, (short) 0xFD); + } + + int I_RR_REF_II_N_R(short OP, byte operand, short special) { + int address = (getspecial(special) + operand) & 0xffff; + int value = readByte(address); + + int bit0 = value & 1; + value = ((((value >> 1) & 0xFF) | (flags & FLAG_C) << 7) & 0xFF); + memory.write(address, (byte) (value & 0xFF)); + + flags = EmulatorTables.SIGN_ZERO_TABLE[value] | EmulatorTables.PARITY_TABLE[value] | bit0; + // regs[6] is unused, so it's ok + regs[OP & 7] = value & 0xFF; + return 23; + } + + int I_SLA_REF_IX_N_R(short OP, byte operand) { + return I_SLA_REF_II_N_R(OP, operand, (short) 0xDD); + } + + int I_SLA_REF_IY_N_R(short OP, byte operand) { + return I_SLA_REF_II_N_R(OP, operand, (short) 0xFD); + } + + int I_SLA_REF_II_N_R(short OP, byte operand, short special) { + int tmp = (getspecial(special) + operand) & 0xffff; + int tmp1 = memory.read(tmp); + + int tmp2 = (tmp1 >>> 7) & 1; + tmp1 = (tmp1 << 1) & 0xFE; + memory.write(tmp, (byte) tmp1); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + // regs[6] is unused, so it's ok + regs[OP & 7] = tmp1 & 0xFF; + return 23; + } + + int I_SRA_REF_IX_N_R(short OP, byte operand) { + return I_SRA_REF_II_N_R(OP, operand, (short) 0xDD); + } + + int I_SRA_REF_IY_N_R(short OP, byte operand) { + return I_SRA_REF_II_N_R(OP, operand, (short) 0xFD); + } + + int I_SRA_REF_II_N_R(short OP, byte operand, short special) { + int tmp = (getspecial(special) + operand) & 0xffff; + int tmp1 = memory.read(tmp); + + int tmp2 = tmp1 & 1; + tmp1 = (tmp1 >> 1) & 0xFF | (tmp1 & 0x80); + memory.write(tmp, (byte) tmp1); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + // regs[6] is unused, so it's ok + regs[OP & 7] = tmp1 & 0xFF; + return 23; + } + + int I_SLL_REF_IX_N_R(short OP, byte operand) { + return I_SLL_REF_II_N_R(OP, operand, (short) 0xDD); + } + + int I_SLL_REF_IY_N_R(short OP, byte operand) { + return I_SLL_REF_II_N_R(OP, operand, (short) 0xFD); + } + + int I_SLL_REF_II_N_R(short OP, byte operand, short special) { + int tmp = (getspecial(special) + operand) & 0xffff; + int tmp1 = memory.read(tmp); + + int tmp2 = (tmp1 >>> 7) & 1; + tmp1 = (tmp1 << 1) & 0xFF | tmp1 & 1; + memory.write(tmp, (byte) tmp1); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + // regs[6] is unused, so it's ok + regs[OP & 7] = tmp1 & 0xFF; + return 23; + } + + int I_SRL_REF_IX_N_R(short OP, byte operand) { + return I_SRL_REF_II_N_R(OP, operand, (short)0xDD); + } + + int I_SRL_REF_IY_N_R(short OP, byte operand) { + return I_SRL_REF_II_N_R(OP, operand, (short)0xFD); + } + + int I_SRL_REF_II_N_R(short OP, byte operand, short special) { + int tmp = (getspecial(special) + operand) & 0xffff; + int tmp1 = memory.read(tmp); + + int tmp2 = tmp1 & 1; + tmp1 = (tmp1 >>> 1) & 0x7F; + memory.write(tmp, (byte) tmp1); + + flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + // regs[6] is unused, so it's ok + regs[OP & 7] = tmp1 & 0xFF; + return 23; + } + + int I_BIT_N_REF_IX_N(short OP, byte operand) { + return I_BIT_N_REF_II_N(OP, operand, (short) 0xDD); + } + + int I_BIT_N_REF_IY_N(short OP, byte operand) { + return I_BIT_N_REF_II_N(OP, operand, (short) 0xFD); + } + + int I_BIT_N_REF_II_N(short OP, byte operand, short special) { + int bitNumber = (OP >>> 3) & 7; + int tmp1 = memory.read((getspecial(special) + operand) & 0xFFFF); + flags = ((flags & FLAG_C) | FLAG_H | (((tmp1 & (1 << bitNumber)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); + if (bitNumber == 7) { + flags |= (((tmp1 & (1 << 7)) == 0x80) ? FLAG_S : 0); + } + return 20; + } + + int I_RES_N_REF_IX_N_R(short OP, byte operand) { + return I_RES_N_REF_II_N_R(OP, operand, (short) 0xDD); + } + + int I_RES_N_REF_IY_N_R(short OP, byte operand) { + return I_RES_N_REF_II_N_R(OP, operand, (short) 0xFD); + } + + int I_RES_N_REF_II_N_R(short OP, byte operand, short special) { + int tmp2 = (OP >>> 3) & 7; + int tmp3 = (getspecial(special) + operand) & 0xffff; + int tmp1 = memory.read(tmp3); + tmp1 = (tmp1 & (~(1 << tmp2))); + memory.write(tmp3, (byte) (tmp1 & 0xff)); + // regs[6] is unused, so it's ok + regs[OP & 7] = tmp1 & 0xFF; + return 23; + } + + int I_SET_N_REF_IX_N_R(short OP, byte operand) { + return I_SET_N_REF_II_N_R(OP, operand, (short) 0xDD); + } + + int I_SET_N_REF_IY_N_R(short OP, byte operand) { + return I_SET_N_REF_II_N_R(OP, operand, (short) 0xFD); + } + + int I_SET_N_REF_II_N_R(short OP, byte operand, short special) { + int tmp2 = (OP >>> 3) & 7; + int tmp3 = (getspecial(special) + operand) & 0xffff; + int tmp1 = memory.read(tmp3); + tmp1 = (tmp1 | (1 << tmp2)); + memory.write(tmp3, (byte) (tmp1 & 0xff)); + + // regs[6] is unused, so it's ok + regs[OP & 7] = tmp1 & 0xFF; + return 23; + } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java index e05ce75f7..77ccb407b 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java @@ -18,9 +18,82 @@ */ package net.emustudio.plugins.cpu.zilogZ80; +import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.*; + class EmulatorTables { + private final static int FLAG_S_SHIFT = 7; + private final static int FLAG_Z_SHIFT = 6; + private final static int FLAG_H_SHIFT = 4; + private final static int FLAG_PV_SHIFT = 2; + private final static int FLAG_N_SHIFT = 1; + private final static int FLAG_C_SHIFT = 0; + + // INDEX IS: + // - for ADD: A+B + // - for ADC: A+B+carry + // - for SUB: A+(~B + 1) + // - for SBC: A+(~B + 1)-carry + // + // carryIns = *acc ^ a ^ b; + // carryOut = 1 IFF (a + b > 0xFF) or, + // equivalently, but avoiding overflow in C: (a > 0xFF - b). + // overflowOut = (carryIns >> 7) ^ carryOut; + // halfCarryOut = (carryIns >> 4) & 1; + // zeroOut = sum == 0 + // signOut = sum & 0x80 +// final static byte[] SZHPC_TABLE = new byte[511]; +// +// public static String intToFlags(int flags) { +// String flagsString = ""; +// if ((flags & FLAG_S) == FLAG_S) { +// flagsString += "S"; +// } +// if ((flags & FLAG_Z) == FLAG_Z) { +// flagsString += "Z"; +// } +// if ((flags & FLAG_H) == FLAG_H) { +// flagsString += "H"; +// } +// if ((flags & FLAG_PV) == FLAG_PV) { +// flagsString += "P"; +// } +// if ((flags & FLAG_N) == FLAG_N) { +// flagsString += "N"; +// } +// if ((flags & FLAG_C) == FLAG_C) { +// flagsString += "C"; +// } +// return flagsString; +// } +// +// static { +// for (int a = 0; a < 256; a++) { +// for (int b = 0; b < 256; b++) { +// int sum = (a + b) & 0xFF; // index to the array +// +// int carryOut = (a > 0xFF - b) ? FLAG_C : 0; +// int carryIns = sum ^ a ^ b; +// int halfCarryOut = (carryIns >> 4) & 1; +// int overflowOut = (((carryIns >> 7) ^ carryOut) != 0) ? FLAG_PV : 0; +// +// int result = carryOut | (halfCarryOut << FLAG_H_SHIFT) | (overflowOut) | (sum == 0 ? FLAG_Z : 0) | (sum & 0x80); +// +// if (a == 0x65 && b == 0x1C) { +// System.out.println("TABLE = " + intToFlags(result)); +// } +// if (sum == (0x65 + 0x1C)) { +// System.out.println("TABLE(SUM) = " + intToFlags(result)); +// System.out.println(" a = " + Integer.toHexString(a)); +// System.out.println(" b = " + Integer.toHexString(b)); +// } +// +// SZHPC_TABLE[(a + b) & 0x1FF] = (byte)result; +// } +// } +// } - final static short[] SIGN_ZERO_CARRY_TABLE = new short[]{ + + final static short[] SIGN_ZERO_CARRY_TABLE = { 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -220,4 +293,9 @@ class EmulatorTables { 218, 91, 219, 92, 220, 93, 221, 94, 222, 95, 223, 96, 224, 97, 225, 98, 226, 99, 227, 100, 228, 101, 229, 102, 230, 103, 231, 104, 232, 105, 233, 106, 234, 107, 235, 108, 236, 109, 237, 110, 238, 111, 239, 112, 240, 113, 241, 114, 242, 115, 243, 116, 244, 117, 245, 118, 246, 119, 247, 120, 248, 121, 249, 122, 250, 123, 251, 124, 252, 125, 253, 126, 254, 127, 255 }; + + + + + } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java index 53a7112c5..828ce1640 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java @@ -33,24 +33,8 @@ public class ArithmeticTest extends InstructionsTest { - private ByteTestBuilder additionTestBuilder() { - return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) - .keepCurrentInjectorsAfterRun(); - } - - private ByteTestBuilder subtractionTestBuilder() { - return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsSet()) - .keepCurrentInjectorsAfterRun(); - } - @Test - public void testADD_A__r() { + public void testADD_A_R() { ByteTestBuilder test = additionTestBuilder(); Generator.forSome8bitBinaryWhichEqual( @@ -68,7 +52,7 @@ public void testADD_A__r() { } @Test - public void testADD_A__n() { + public void testADD_A_N() { ByteTestBuilder test = additionTestBuilder(); Generator.forSome8bitBinary( @@ -77,7 +61,7 @@ public void testADD_A__n() { } @Test - public void testADC_A__r() { + public void testADC_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) @@ -99,7 +83,7 @@ public void testADC_A__r() { } @Test - public void testADC_A__n() { + public void testADC_A_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) @@ -111,7 +95,7 @@ public void testADC_A__n() { } @Test - public void testSUB_A__r() { + public void testSUB_R() { ByteTestBuilder test = subtractionTestBuilder(); Generator.forSome8bitBinaryWhichEqual( @@ -129,7 +113,7 @@ public void testSUB_A__r() { } @Test - public void testSUB_A__n() { + public void testSUB_N() { ByteTestBuilder test = subtractionTestBuilder(); Generator.forSome8bitBinary( @@ -138,11 +122,11 @@ public void testSUB_A__n() { } @Test - public void testSBC_A__r() { + public void testSBC_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsSet()) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrowWithCarry().overflow().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( @@ -160,11 +144,11 @@ public void testSBC_A__r() { } @Test - public void testSBC_A__n() { + public void testSBC_A_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsSet()); + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrowWithCarry().overflow().subtractionIsSet()); Generator.forSome8bitBinary( test.runWithSecondOperand(0xDE) @@ -172,7 +156,7 @@ public void testSBC_A__n() { } @Test - public void testINC__r() { + public void testINC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .verifyFlags(new FlagsCheckImpl().sign().zero().overflow().halfCarry().subtractionIsReset(), context -> context.first + 1) @@ -192,7 +176,7 @@ public void testINC__r() { } @Test - public void testDEC__r() { + public void testDEC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .verifyFlags(new FlagsCheckImpl().sign().zero().overflow().halfCarry().subtractionIsSet(), context -> context.first - 1) @@ -212,7 +196,7 @@ public void testDEC__r() { } @Test - public void testINC__ss() { + public void testINC_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .clearOtherVerifiersAfterRun(); @@ -227,7 +211,7 @@ public void testINC__ss() { } @Test - public void testDEC__ss() { + public void testDEC_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .clearOtherVerifiersAfterRun(); @@ -242,7 +226,7 @@ public void testDEC__ss() { } @Test - public void testADD_HL__ss() { + public void testADD_HL_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsPair(REG_PAIR_HL) .verifyPair(REG_PAIR_HL, context -> context.first + context.second) @@ -264,7 +248,7 @@ public void testADD_HL__ss() { /* 8080-incompatible */ @Test - public void testADD_A__IX_IY_plus_d() { + public void testADD_A_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) @@ -279,7 +263,7 @@ public void testADD_A__IX_IY_plus_d() { } @Test - public void testADC_A__IX_IY_plus_d() { + public void testADC_A_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) @@ -294,12 +278,12 @@ public void testADC_A__IX_IY_plus_d() { } @Test - public void testSUB_A__IX_IY_plus_d() { + public void testSUB_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsSet()) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflow().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -309,12 +293,12 @@ public void testSUB_A__IX_IY_plus_d() { } @Test - public void testSBC_A__IX_IY_plus_d() { + public void testSBC_A_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsSet()) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrowWithCarry().overflow().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -324,7 +308,7 @@ public void testSBC_A__IX_IY_plus_d() { } @Test - public void testINC__IX_IY() { + public void testINC_II() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .clearOtherVerifiersAfterRun(); @@ -335,7 +319,7 @@ public void testINC__IX_IY() { } @Test - public void testDEC__IX_IY() { + public void testDEC_II() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .clearOtherVerifiersAfterRun(); @@ -346,7 +330,7 @@ public void testDEC__IX_IY() { } @Test - public void testINC__IX_IY_plus_d() { + public void testINC_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .verifyByte(context -> get8MSBplus8LSB(context.first), context -> (context.second + 1)) @@ -362,7 +346,7 @@ public void testINC__IX_IY_plus_d() { } @Test - public void testDEC__IX_IY_plus_d() { + public void testDEC_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .verifyByte(context -> get8MSBplus8LSB(context.first), context -> (context.second - 1)) @@ -378,7 +362,7 @@ public void testDEC__IX_IY_plus_d() { } @Test - public void testADD_IX__ss() { + public void testADD_IX_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIX() .verifyIX(context -> context.first + context.second) @@ -399,7 +383,7 @@ public void testADD_IX__ss() { } @Test - public void testADD_IY__ss() { + public void testADD_IY_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIY() .verifyIY(context -> context.first + context.second) @@ -420,7 +404,7 @@ public void testADD_IY__ss() { } @Test - public void testADC_HL__ss() { + public void testADC_HL_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsPair(REG_PAIR_HL) .verifyPair(REG_PAIR_HL, context -> context.first + context.second + (context.flags & FLAG_C)) @@ -440,7 +424,7 @@ public void testADC_HL__ss() { } @Test - public void testSBC_HL__ss() { + public void testSBC_HL_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsPair(REG_PAIR_HL) .verifyPair(REG_PAIR_HL, context -> @@ -459,4 +443,20 @@ public void testSBC_HL__ss() { test.secondIsPair(REG_SP).run(0xED, 0x72) ); } + + private ByteTestBuilder additionTestBuilder() { + return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) + .keepCurrentInjectorsAfterRun(); + } + + private ByteTestBuilder subtractionTestBuilder() { + return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflow().subtractionIsSet()) + .keepCurrentInjectorsAfterRun(); + } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeDevice.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeByteDevice.java similarity index 95% rename from plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeDevice.java rename to plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeByteDevice.java index 59b1a3114..5f51d6098 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeDevice.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeByteDevice.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.plugins.device.DeviceContext; -public class FakeDevice implements DeviceContext { +public class FakeByteDevice implements DeviceContext { private byte value; public void setValue(byte value) { diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FlagsTableGeneratorTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FlagsTableGeneratorTest.java index 2a63e8dcd..e097c5b58 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FlagsTableGeneratorTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FlagsTableGeneratorTest.java @@ -24,6 +24,7 @@ import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.FLAG_C; import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.FLAG_H; +@Ignore public class FlagsTableGeneratorTest { private final static int MAX_INDENT = 25; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java index a5b7a1358..58d8b7606 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java @@ -33,7 +33,7 @@ public class IOTest extends InstructionsTest { @Test - public void testIN_A__n() { + public void testIN_A_REF_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsDeviceAndSecondIsPort() .secondIsRegister(REG_A) @@ -45,7 +45,7 @@ public void testIN_A__n() { } @Test - public void testIN_r__C() { + public void testIN_R_REF_C() { Function, Integer> operation = context -> context.first & 0xFF; ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) @@ -68,7 +68,7 @@ public void testIN_r__C() { } @Test - public void testIN__C() { + public void testIN_REF_C() { Function, Integer> operation = context -> context.first & 0xFF; ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) @@ -86,12 +86,6 @@ public void testIN__C() { @Test public void testINI() { - BiFunction, Number, Boolean> flagHCtest = (context, result) -> false; - BiFunction, Number, Boolean> flagPVtest = (context, result) -> - FlagsCheckImpl.isParity( - ((((context.first >>> 8) & 0xFF) + (((context.first & 0xFF) + 1) & 0xFF)) & 7) ^ result.byteValue() - ); - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBisDeviceAndFirst8LSBIsPort() .first8LSBisRegister(REG_C) @@ -101,13 +95,9 @@ public void testINI() { .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero() - .expectFlagOnlyWhen(FLAG_N, - (context, result) -> (((context.first >>> 8) & 0x80) == 0x80) - ) - .expectFlagOnlyWhen(FLAG_H, flagHCtest) - .expectFlagOnlyWhen(FLAG_C, flagHCtest) - .expectFlagOnlyWhen(FLAG_PV, flagPVtest) + .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) ); Generator.forSome16bitBinary(2, @@ -117,12 +107,6 @@ public void testINI() { @Test public void testINIR() { - BiFunction, Number, Boolean> flagHCtest = (context, result) -> false; - BiFunction, Number, Boolean> flagPVtest = (context, result) -> - FlagsCheckImpl.isParity( - ((((context.first >>> 8) & 0xFF) + (((context.first & 0xFF) + 1) & 0xFF)) & 7) ^ result.byteValue() - ); - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBisDeviceAndFirst8LSBIsPort() .first8LSBisRegister(REG_C) @@ -132,11 +116,10 @@ public void testINIR() { .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero() + .verifyFlagsOfLastOp(new FlagsCheckImpl() .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_H, flagHCtest) - .expectFlagOnlyWhen(FLAG_C, flagHCtest) - .expectFlagOnlyWhen(FLAG_PV, flagPVtest) + .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) ) .verifyPC(context -> { if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { @@ -152,13 +135,6 @@ public void testINIR() { @Test public void testIND() { - BiFunction, Number, Boolean> flagHCtest = (context, result) -> - (((context.first >>> 8) & 0xFF) + (((context.first & 0xFF) - 1) & 0xFF)) > 0xFF; - BiFunction, Number, Boolean> flagPVtest = (context, result) -> - FlagsCheckImpl.isParity( - ((((context.first >>> 8) & 0xFF) + (((context.first & 0xFF) - 1) & 0xFF)) & 7) ^ result.byteValue() - ); - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBisDeviceAndFirst8LSBIsPort() .first8LSBisRegister(REG_C) @@ -168,13 +144,9 @@ public void testIND() { .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero() - .expectFlagOnlyWhen(FLAG_N, - (context, result) -> (((context.first >>> 8) & 0x80) == 0x80) - ) - .expectFlagOnlyWhen(FLAG_H, flagHCtest) - .expectFlagOnlyWhen(FLAG_C, flagHCtest) - .expectFlagOnlyWhen(FLAG_PV, flagPVtest) + .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) ); Generator.forSome16bitBinary(2, @@ -184,13 +156,6 @@ public void testIND() { @Test public void testINDR() { - BiFunction, Number, Boolean> flagHCtest = (context, result) -> - (((context.first >>> 8) & 0xFF) + (((context.first & 0xFF) - 1) & 0xFF)) > 0xFF; - BiFunction, Number, Boolean> flagPVtest = (context, result) -> - FlagsCheckImpl.isParity( - ((((context.first >>> 8) & 0xFF) + (((context.first & 0xFF) - 1) & 0xFF)) & 7) ^ result.byteValue() - ); - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBisDeviceAndFirst8LSBIsPort() .first8LSBisRegister(REG_C) @@ -200,13 +165,10 @@ public void testINDR() { .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero() - .expectFlagOnlyWhen(FLAG_N, - (context, result) -> (((context.first >>> 8) & 0x80) == 0x80) - ) - .expectFlagOnlyWhen(FLAG_H, flagHCtest) - .expectFlagOnlyWhen(FLAG_C, flagHCtest) - .expectFlagOnlyWhen(FLAG_PV, flagPVtest) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) ) .verifyPC(context -> { if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { @@ -221,7 +183,7 @@ public void testINDR() { } @Test - public void testOUT_n__A() { + public void testOUT_REF_N_A() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyDeviceWhenSecondIsPort(context -> context.first & 0xFF); @@ -232,7 +194,7 @@ public void testOUT_n__A() { } @Test - public void testOUT_C__r() { + public void testOUT_REF_C_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .secondIsRegister(REG_C) .verifyDeviceWhenSecondIsPort(context -> context.first & 0xFF) @@ -253,7 +215,7 @@ public void testOUT_C__r() { } @Test - public void testOUT_C_0() { + public void testOUT_REF_C_0() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .secondIsRegister(REG_C) .verifyDeviceWhenSecondIsPort(context -> 0) @@ -266,13 +228,6 @@ public void testOUT_C_0() { @Test public void testOUTI() { - BiFunction, Number, Boolean> flagHCtest = (context, result) -> - ((context.second & 0xFF) + ((context.first + 1) & 0xFF)) > 0xFF; - BiFunction, Number, Boolean> flagPVtest = (context, result) -> - FlagsCheckImpl.isParity( - (((context.second & 0xFF) + ((context.first + 1) & 0xFF)) & 7) ^ result.byteValue() - ); - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .firstIsPair(REG_PAIR_HL) @@ -281,13 +236,9 @@ public void testOUTI() { .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero() - .expectFlagOnlyWhen(FLAG_N, - (context, result) -> ((context.second & 0x80) == 0x80) - ) - .expectFlagOnlyWhen(FLAG_H, flagHCtest) - .expectFlagOnlyWhen(FLAG_C, flagHCtest) - .expectFlagOnlyWhen(FLAG_PV, flagPVtest) + .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) ); Generator.forSome16bitBinary(2, @@ -297,13 +248,6 @@ public void testOUTI() { @Test public void testOTIR() { - BiFunction, Number, Boolean> flagHCtest = (context, result) -> - ((context.second & 0xFF) + ((context.first + 1) & 0xFF)) > 0xFF; - BiFunction, Number, Boolean> flagPVtest = (context, result) -> - FlagsCheckImpl.isParity( - (((context.second & 0xFF) + (context.first + 1) & 0xFF) & 7) ^ result.byteValue() - ); - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .firstIsPair(REG_PAIR_HL) @@ -312,13 +256,10 @@ public void testOTIR() { .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero() - .expectFlagOnlyWhen(FLAG_N, - (context, result) -> ((context.second & 0x80) == 0x80) - ) - .expectFlagOnlyWhen(FLAG_H, flagHCtest) - .expectFlagOnlyWhen(FLAG_C, flagHCtest) - .expectFlagOnlyWhen(FLAG_PV, flagPVtest) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) ) .verifyPC(context -> { if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { @@ -334,13 +275,6 @@ public void testOTIR() { @Test public void testOUTD() { - BiFunction, Number, Boolean> flagHCtest = (context, result) -> - ((context.second & 0xFF) + ((context.first - 1) & 0xFF)) > 0xFF; - BiFunction, Number, Boolean> flagPVtest = (context, result) -> - FlagsCheckImpl.isParity( - (((context.second & 0xFF) + ((context.first - 1) & 0xFF)) & 7) ^ result.byteValue() - ); - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .firstIsPair(REG_PAIR_HL) @@ -349,13 +283,9 @@ public void testOUTD() { .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero() - .expectFlagOnlyWhen(FLAG_N, - (context, result) -> ((context.second & 0x80) == 0x80) - ) - .expectFlagOnlyWhen(FLAG_H, flagHCtest) - .expectFlagOnlyWhen(FLAG_C, flagHCtest) - .expectFlagOnlyWhen(FLAG_PV, flagPVtest) + .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) ); Generator.forSome16bitBinary(2, @@ -365,13 +295,6 @@ public void testOUTD() { @Test public void testOTDR() { - BiFunction, Number, Boolean> flagHCtest = (context, result) -> - ((context.second & 0xFF) + ((context.first - 1) & 0xFF)) > 0xFF; - BiFunction, Number, Boolean> flagPVtest = (context, result) -> - FlagsCheckImpl.isParity( - (((context.second & 0xFF) + ((context.first - 1) & 0xFF)) & 7) ^ result.byteValue() - ); - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .firstIsPair(REG_PAIR_HL) @@ -380,13 +303,10 @@ public void testOTDR() { .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero() - .expectFlagOnlyWhen(FLAG_N, - (context, result) -> ((context.second & 0x80) == 0x80) - ) - .expectFlagOnlyWhen(FLAG_H, flagHCtest) - .expectFlagOnlyWhen(FLAG_C, flagHCtest) - .expectFlagOnlyWhen(FLAG_PV, flagPVtest) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) ) .verifyPC(context -> { if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java index 87e97c63d..dadbb739c 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java @@ -19,7 +19,7 @@ package net.emustudio.plugins.cpu.zilogZ80; import net.emustudio.cpu.testsuite.Generator; -import net.emustudio.cpu.testsuite.memory.ShortMemoryStub; +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; @@ -50,12 +50,12 @@ public class InstructionsTest { private CpuImpl cpu; CpuRunnerImpl cpuRunnerImpl; CpuVerifierImpl cpuVerifierImpl; - private final List devices = new ArrayList<>(); + private final List devices = new ArrayList<>(); @SuppressWarnings("unchecked") @Before public void setUp() throws Exception { - ShortMemoryStub memoryStub = new ShortMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); + ByteMemoryStub memoryStub = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); Capture cpuContext = Capture.newInstance(); ContextPool contextPool = EasyMock.createNiceMock(ContextPool.class); @@ -73,7 +73,7 @@ public void setUp() throws Exception { assertTrue(cpuContext.hasCaptured()); for (int i = 0; i < 256; i++) { - FakeDevice device = new FakeDevice(); + FakeByteDevice device = new FakeByteDevice(); devices.add(device); cpuContext.getValue().attachDevice(device, i); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java index dd6d3524b..1e26333cf 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java @@ -43,7 +43,7 @@ private ByteTestBuilder getLogicTestBuilder(Function, Intege } @Test - public void testAND__r() { + public void testAND_R() { ByteTestBuilder test = getLogicTestBuilder(context -> context.first & context.second); Generator.forSome8bitBinaryWhichEqual( @@ -62,7 +62,7 @@ public void testAND__r() { } @Test - public void testAND__n() { + public void testAND_N() { ByteTestBuilder test = getLogicTestBuilder(context -> context.first & context.second); Generator.forSome8bitBinary( @@ -71,7 +71,7 @@ public void testAND__n() { } @Test - public void testOR__r() { + public void testOR_R() { ByteTestBuilder test = getLogicTestBuilder(context -> context.first | context.second); Generator.forSome8bitBinaryWhichEqual( @@ -90,7 +90,7 @@ public void testOR__r() { } @Test - public void testOR__n() { + public void testOR_N() { ByteTestBuilder test = getLogicTestBuilder(context -> context.first | context.second); Generator.forSome8bitBinary( @@ -99,7 +99,7 @@ public void testOR__n() { } @Test - public void testXOR__r() { + public void testXOR_R() { ByteTestBuilder test = getLogicTestBuilder(context -> context.first ^ context.second); Generator.forSome8bitBinaryWhichEqual( @@ -118,7 +118,7 @@ public void testXOR__r() { } @Test - public void testXOR__n() { + public void testXOR_N() { ByteTestBuilder test = getLogicTestBuilder(context -> context.first ^ context.second); Generator.forSome8bitBinary( @@ -127,12 +127,12 @@ public void testXOR__n() { } @Test - public void testCP__r() { + public void testCP_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsSet(), - context -> (context.first & 0xFF) - (context.second & 0xFF)) + .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflow().subtractionIsSet(), + context -> (context.first & 0xFF) - (byte)(context.second & 0xFF)) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( @@ -150,12 +150,12 @@ public void testCP__r() { } @Test - public void testCP__n() { + public void testCP_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsSet(), - context -> (context.first & 0xFF) - (context.second & 0xFF)); + .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflow().subtractionIsSet(), + context -> (context.first & 0xFF) - (byte)(context.second & 0xFF)); Generator.forSome8bitBinary( test.runWithSecondOperand(0xFE) @@ -279,24 +279,6 @@ public void testRRA() { ); } - private IntegerTestBuilder prepareCPxTest(Function, Integer> hlOperation) { - return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8LSBisRegister(REG_A) - .registerIsRandom(REG_B, 0xFF) - .registerIsRandom(REG_C, 0xFF) - .verifyPair(REG_PAIR_HL, hlOperation) - .verifyPair(REG_PAIR_BC, context -> - ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) - ) - .verifyFlags(new FlagsCheckImpl() - .sign().zero().subtractionIsSet().halfCarry() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> - ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) != 0 - ), context -> context.registers.get(REG_A) - (context.second & 0xFF)); - } - @Test public void testCPI() { IntegerTestBuilder test = prepareCPxTest(context -> @@ -353,18 +335,8 @@ public void testCPDR() { ); } - private IntegerTestBuilder prepareLogicIXYtest(Function, Integer> operation) { - return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8LSBisRegister(REG_A) - .verifyRegister(REG_A, operation) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().carryIsReset().halfCarryIsSet().parity().subtractionIsReset()); - } - - @Test - public void testAND__IX_IY_plus_d() { + public void testAND_REF_II_N() { IntegerTestBuilder test = prepareLogicIXYtest(context -> (context.first & 0xFF) & (context.second & 0xFF)) .keepCurrentInjectorsAfterRun(); @@ -375,7 +347,7 @@ public void testAND__IX_IY_plus_d() { } @Test - public void testOR__IX_IY_plus_d() { + public void testOR_REF_II_N() { IntegerTestBuilder test = prepareLogicIXYtest(context -> (context.first & 0xFF) | (context.second & 0xFF)) .keepCurrentInjectorsAfterRun(); @@ -386,7 +358,7 @@ public void testOR__IX_IY_plus_d() { } @Test - public void testXOR__IX_IY_plus_d() { + public void testXOR_REF_II_N() { IntegerTestBuilder test = prepareLogicIXYtest(context -> (context.first & 0xFF) ^ (context.second & 0xFF)) .keepCurrentInjectorsAfterRun(); @@ -397,12 +369,12 @@ public void testXOR__IX_IY_plus_d() { } @Test - public void testCP__IX_IY_plus_d() { + public void testCP_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsSet(), + .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflow().subtractionIsSet(), context -> (context.first & 0xFF) - (context.second & 0xFF) ) .keepCurrentInjectorsAfterRun(); @@ -438,7 +410,7 @@ public void testNEG() { } @Test - public void testRLC__r() { + public void testRLC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .setFlags(FLAG_H | FLAG_N) .keepCurrentInjectorsAfterRun() @@ -462,29 +434,9 @@ public void testRLC__r() { ); } - private IntegerTestBuilder prepareIXIYRotationMSBTest(Function, Integer> operator) { - return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .verifyByte(context -> get8MSBplus8LSB(context.first), operator) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().carryIsFirstOperandMSB().sign().zero().halfCarryIsReset().parity() - .subtractionIsReset()) - .setFlags(FLAG_H | FLAG_N); - } - - private IntegerTestBuilder prepareIXIYRotationLSBTest(Function, Integer> operator) { - return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .verifyByte(context -> get8MSBplus8LSB(context.first), operator) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().carryIsFirstOperandLSB().sign().zero().halfCarryIsReset().parity() - .subtractionIsReset()) - .setFlags(FLAG_H | FLAG_N); - } - @Test - public void testRLC__IX_IY_plus_d() { - IntegerTestBuilder test = prepareIXIYRotationMSBTest( + public void testRLC_REF_II_N() { + IntegerTestBuilder test = prepareIIRotationMSBTest( context -> ((context.second << 1) & 0xFF) | (context.second >>> 7) & 1 ).keepCurrentInjectorsAfterRun(); @@ -495,11 +447,11 @@ public void testRLC__IX_IY_plus_d() { } @Test - public void testRLC__IX_IY_plus_d_undocumented() { + public void testRLC_REF_II_N_R() { Function, Integer> operation = context -> ((context.second << 1) & 0xFF) | (context.second >>> 7) & 1; - IntegerTestBuilder test = prepareIXIYRotationMSBTest(operation) + IntegerTestBuilder test = prepareIIRotationMSBTest(operation) .verifyRegister(REG_B, operation) .keepCurrentInjectorsAfterRun(); @@ -511,7 +463,7 @@ public void testRLC__IX_IY_plus_d_undocumented() { @Test - public void testRL__r() { + public void testRL_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .setFlags(FLAG_H | FLAG_N) .keepCurrentInjectorsAfterRun() @@ -536,8 +488,8 @@ public void testRL__r() { } @Test - public void testRL__IX_IY_plus_d() { - IntegerTestBuilder test = prepareIXIYRotationMSBTest( + public void testRL_REF_II_N() { + IntegerTestBuilder test = prepareIIRotationMSBTest( context -> ((context.second << 1) & 0xFF) | (context.flags & FLAG_C) ).keepCurrentInjectorsAfterRun(); @@ -548,7 +500,7 @@ public void testRL__IX_IY_plus_d() { } @Test - public void testRRC__r() { + public void testRRC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .setFlags(FLAG_H | FLAG_N) .keepCurrentInjectorsAfterRun() @@ -573,8 +525,8 @@ public void testRRC__r() { } @Test - public void testRRC__IX_IY_plus_d() { - IntegerTestBuilder test = prepareIXIYRotationLSBTest( + public void testRRC_REF_II_N() { + IntegerTestBuilder test = prepareIIRotationLSBTest( context -> ((context.second >>> 1) & 0x7F) | (((context.second & 1) << 7)) ).keepCurrentInjectorsAfterRun(); @@ -585,7 +537,7 @@ public void testRRC__IX_IY_plus_d() { } @Test - public void testRR__r() { + public void testRR_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .setFlags(FLAG_H | FLAG_N) .keepCurrentInjectorsAfterRun() @@ -610,8 +562,8 @@ public void testRR__r() { } @Test - public void testRR__IX_IY_plus_d() { - IntegerTestBuilder test = prepareIXIYRotationLSBTest( + public void testRR_REF_II_N() { + IntegerTestBuilder test = prepareIIRotationLSBTest( context -> ((context.second >> 1) & 0x7F) | ((context.flags & FLAG_C) << 7) ).keepCurrentInjectorsAfterRun(); @@ -622,7 +574,7 @@ public void testRR__IX_IY_plus_d() { } @Test - public void testSLA__r() { + public void testSLA_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .setFlags(FLAG_H | FLAG_N) .keepCurrentInjectorsAfterRun() @@ -646,8 +598,8 @@ public void testSLA__r() { } @Test - public void testSLA__IX_IY_plus_d() { - IntegerTestBuilder test = prepareIXIYRotationMSBTest(context -> (context.second << 1) & 0xFE) + public void testSLA_REF_II_N() { + IntegerTestBuilder test = prepareIIRotationMSBTest(context -> (context.second << 1) & 0xFE) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), @@ -657,7 +609,7 @@ public void testSLA__IX_IY_plus_d() { } @Test - public void testSRA__r() { + public void testSRA_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .setFlags(FLAG_H | FLAG_N) .keepCurrentInjectorsAfterRun() @@ -681,8 +633,8 @@ public void testSRA__r() { } @Test - public void testSRA__IX_IY_plus_d() { - IntegerTestBuilder test = prepareIXIYRotationLSBTest( + public void testSRA_REF_II_N() { + IntegerTestBuilder test = prepareIIRotationLSBTest( context -> ((context.second & 0xFF) >>> 1) & 0xFF | (context.second & 0x80) ).keepCurrentInjectorsAfterRun(); @@ -693,7 +645,7 @@ public void testSRA__IX_IY_plus_d() { } @Test - public void testSRL__r() { + public void testSRL_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .setFlags(FLAG_H | FLAG_N) .keepCurrentInjectorsAfterRun() @@ -717,8 +669,8 @@ public void testSRL__r() { } @Test - public void testSRL__IX_IY_plus_d() { - IntegerTestBuilder test = prepareIXIYRotationLSBTest(context -> ((context.second & 0xFF) >>> 1) & 0x7F) + public void testSRL_REF_II_N() { + IntegerTestBuilder test = prepareIIRotationLSBTest(context -> ((context.second & 0xFF) >>> 1) & 0x7F) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), @@ -728,7 +680,7 @@ public void testSRL__IX_IY_plus_d() { } @Test - public void testSLL__r() { + public void testSLL_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .setFlags(FLAG_H | FLAG_N) .keepCurrentInjectorsAfterRun() @@ -752,8 +704,8 @@ public void testSLL__r() { } @Test - public void testSLL_IX_IY_plus_d() { - IntegerTestBuilder test = prepareIXIYRotationMSBTest(context -> ((context.second << 1) & 0xFF) | context.second & 1) + public void testSLL_REF_II_N() { + IntegerTestBuilder test = prepareIIRotationMSBTest(context -> ((context.second << 1) & 0xFF) | context.second & 1) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), @@ -791,4 +743,51 @@ public void testRRD() { test.run(0xED, 0x67) ); } + + private IntegerTestBuilder prepareCPxTest(Function, Integer> hlOperation) { + return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8LSBisRegister(REG_A) + .registerIsRandom(REG_B, 0xFF) + .registerIsRandom(REG_C, 0xFF) + .verifyPair(REG_PAIR_HL, hlOperation) + .verifyPair(REG_PAIR_BC, context -> + ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) + ) + .verifyFlags(new FlagsCheckImpl() + .sign().zero().subtractionIsSet().halfCarry() + .expectFlagOnlyWhen(FLAG_PV, (context, result) -> + ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) != 0 + ), context -> context.registers.get(REG_A) - (context.second & 0xFF)); + } + + private IntegerTestBuilder prepareLogicIXYtest(Function, Integer> operation) { + return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8LSBisRegister(REG_A) + .verifyRegister(REG_A, operation) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().carryIsReset().halfCarryIsSet().parity().subtractionIsReset()); + } + + private IntegerTestBuilder prepareIIRotationMSBTest(Function, Integer> operator) { + return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .verifyByte(context -> get8MSBplus8LSB(context.first), operator) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .switchFirstAndSecond().carryIsFirstOperandMSB().sign().zero().halfCarryIsReset().parity() + .subtractionIsReset()) + .setFlags(FLAG_H | FLAG_N); + } + + private IntegerTestBuilder prepareIIRotationLSBTest(Function, Integer> operator) { + return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .verifyByte(context -> get8MSBplus8LSB(context.first), operator) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .switchFirstAndSecond().carryIsFirstOperandLSB().sign().zero().halfCarryIsReset().parity() + .subtractionIsReset()) + .setFlags(FLAG_H | FLAG_N); + } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TablesGenerator.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TablesGenerator.java new file mode 100644 index 000000000..7b8bc76bd --- /dev/null +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TablesGenerator.java @@ -0,0 +1,71 @@ +package net.emustudio.plugins.cpu.zilogZ80; + +import org.junit.Test; + +import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.FLAG_C; +import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.FLAG_Z; + +public class TablesGenerator { + int FLAG_S_SHIFT = 7; + int FLAG_Z_SHIFT = 6; + int FLAG_H_SHIFT = 4; + int FLAG_PV_SHIFT = 2; + int FLAG_N_SHIFT = 1; + int FLAG_C_SHIFT = 0; + + @Test + public void generateOverFlow() { + // carryIns = *acc ^ a ^ b; + // carryOut = 1 IFF (a + b > 0xFF) or, + // equivalently, but avoiding overflow in C: (a > 0xFF - b). + // overflowOut = (carryIns >> 7) ^ carryOut; + // halfCarryOut = (carryIns >> 4) & 1; + // zeroOut = sum == 0 + // signOut = sum & 0x80 + + System.out.print(" final static byte[] SZHPC_TABLE = {\n "); + + for (int a = 0; a < 256; a++) { + for (int b = 0; b < 256; b++) { + int sum = (a + b) & 0xFF; // index to the array + + int carryOut = (a > 0xFF - b) ? FLAG_C : 0; + int carryIns = sum ^ a ^ b; + int halfCarryOut = (carryIns >> 4) & 1; + int overflowOut = (carryIns >> 7) ^ carryOut; + + int result = carryOut | (halfCarryOut << FLAG_H_SHIFT) | (overflowOut << FLAG_PV_SHIFT) | (sum == 0 ? FLAG_Z : 0) | (sum & 0x80); + System.out.print(result + ","); + } + if (((a + 1) & 0x03) == 0) { + System.out.print("\n "); + } + } + System.out.println("};"); + } + + + @Test + public void testFlags() { + int a = 0x65; + int b = ((~0xE4) + 1) & 0xFF; + + int sum = (a + b) ; //& 0xFF; // index to the array + + System.out.println(Integer.toBinaryString(a)); + System.out.println(Integer.toBinaryString(b)); + System.out.println(Integer.toBinaryString(sum)); + + int carryOut = (a > 0xFF - b) ? 1 : 0; + int carryIns = sum ^ a ^ b; + int halfCarryOut = (carryIns >> 4) & 1; + int overflowOut = (((carryIns >> 7) ^ carryOut) != 0) ? 1 : 0; + + System.out.println("C=" + carryOut); + System.out.println("H=" + halfCarryOut); + System.out.println("P=" + overflowOut); + System.out.println("S=" + (((sum & 0x80) != 0) ? 1 : 0)); + + //System.out.println(intToFlags(SZHPC_TABLE[sum & 0x1FF])); + } +} diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java index 5bebd6ea5..4134f4a27 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java @@ -30,61 +30,30 @@ public class TransferTest extends InstructionsTest { - private void runLD_r_r_test(int register, int... opcodes) { - ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(register) - .verifyRegister(register, context -> context.second & 0xFF) - .keepCurrentInjectorsAfterRun(); - - Generator.forSome8bitBinary( - test.secondIsRegister(REG_B).run(opcodes[0]), - test.secondIsRegister(REG_C).run(opcodes[1]), - test.secondIsRegister(REG_D).run(opcodes[2]), - test.secondIsRegister(REG_E).run(opcodes[3]), - test.secondIsRegister(REG_H).run(opcodes[4]), - test.secondIsRegister(REG_L).run(opcodes[5]), - test.secondIsMemoryByteAt(0x303).setPair(REG_PAIR_HL, 0x303).run(opcodes[6]), - test.secondIsRegister(REG_A).run(opcodes[7]) - ); - - } - @Test - public void testLD_r__r() { - runLD_r_r_test(REG_A, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F); - runLD_r_r_test(REG_B, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47); - runLD_r_r_test(REG_C, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F); - runLD_r_r_test(REG_D, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57); - runLD_r_r_test(REG_E, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F); - runLD_r_r_test(REG_H, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67); - runLD_r_r_test(REG_L, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F); - } - - - private void runLD_r_n_test(int register, int opcode) { - ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(register) - .verifyRegister(register, context -> context.second & 0xFF) - .keepCurrentInjectorsAfterRun(); - - Generator.forSome8bitBinary( - test.runWithSecondOperand(opcode) - ); + public void testLD_R_R() { + runLD_R_R_test(REG_A, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F); + runLD_R_R_test(REG_B, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47); + runLD_R_R_test(REG_C, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F); + runLD_R_R_test(REG_D, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57); + runLD_R_R_test(REG_E, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F); + runLD_R_R_test(REG_H, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67); + runLD_R_R_test(REG_L, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F); } @Test - public void testLD_r__n() { - runLD_r_n_test(REG_A, 0x3E); - runLD_r_n_test(REG_B, 0x06); - runLD_r_n_test(REG_C, 0x0E); - runLD_r_n_test(REG_D, 0x16); - runLD_r_n_test(REG_E, 0x1E); - runLD_r_n_test(REG_H, 0x26); - runLD_r_n_test(REG_L, 0x2E); + public void testLD_R_N() { + runLD_R_N_test(REG_A, 0x3E); + runLD_R_N_test(REG_B, 0x06); + runLD_R_N_test(REG_C, 0x0E); + runLD_R_N_test(REG_D, 0x16); + runLD_R_N_test(REG_E, 0x1E); + runLD_R_N_test(REG_H, 0x26); + runLD_R_N_test(REG_L, 0x2E); } @Test - public void testLD_mHL__n() { + public void testLD_REF_HL_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsMemoryByteAt(0x303) .setPair(REG_PAIR_HL, 0x303) @@ -97,7 +66,7 @@ public void testLD_mHL__n() { } @Test - public void testLD_mHL__r() { + public void testLD_REF_HL_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsMemoryByteAt(0x303) .setPair(REG_PAIR_HL, 0x303) @@ -114,7 +83,7 @@ public void testLD_mHL__r() { } @Test - public void testLD_mHL__H_L() { + public void testLD_REF_HL_HL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .firstIsPair(REG_PAIR_HL) @@ -127,33 +96,19 @@ public void testLD_mHL__H_L() { ); } - - private void runLD_r__IX_IY_plus_d(int register, int opcode) { - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8LSBisRegister(register) - .verifyRegister(register, context -> context.second & 0xFF) - .keepCurrentInjectorsAfterRun(); - - Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, opcode), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, opcode) - ); - } - @Test - public void testLD_r__IX_IY_plus_d() { - runLD_r__IX_IY_plus_d(REG_A, 0x7E); - runLD_r__IX_IY_plus_d(REG_B, 0x46); - runLD_r__IX_IY_plus_d(REG_C, 0x4E); - runLD_r__IX_IY_plus_d(REG_D, 0x56); - runLD_r__IX_IY_plus_d(REG_E, 0x5E); - runLD_r__IX_IY_plus_d(REG_H, 0x66); - runLD_r__IX_IY_plus_d(REG_L, 0x6E); + public void testLD_R_II_N() { + runLD_R_II_N(REG_A, 0x7E); + runLD_R_II_N(REG_B, 0x46); + runLD_R_II_N(REG_C, 0x4E); + runLD_R_II_N(REG_D, 0x56); + runLD_R_II_N(REG_E, 0x5E); + runLD_R_II_N(REG_H, 0x66); + runLD_R_II_N(REG_L, 0x6E); } @Test - public void testLD_IX_plus_d__r() { + public void testLD_IX_N_R() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8MSBisIX() @@ -172,7 +127,7 @@ public void testLD_IX_plus_d__r() { } @Test - public void testLD_IY_plus_d__r() { + public void testLD_IY_N_R() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8MSBisIY() @@ -191,7 +146,7 @@ public void testLD_IY_plus_d__r() { } @Test - public void testLD_IX_IY_plus_d__n() { + public void testLD_II_N_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .verifyByte(context -> Utils.get8MSBplus8LSB(context.first), context -> context.first & 0xFF) @@ -204,7 +159,7 @@ public void testLD_IX_IY_plus_d__n() { } @Test - public void testLD_A__dd() { + public void testLD_A_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .verifyRegister(REG_A, context -> context.second & 0xFF) @@ -217,7 +172,7 @@ public void testLD_A__dd() { } @Test - public void testLD_A__nn() { + public void testLD_A_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .verifyRegister(REG_A, context -> context.second & 0xFF); @@ -228,7 +183,7 @@ public void testLD_A__nn() { } @Test - public void testLD_dd__A() { + public void testLD_REF_RP_A() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) @@ -242,7 +197,7 @@ public void testLD_dd__A() { } @Test - public void testLD_nn__A() { + public void testLD_NN_A() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) @@ -254,7 +209,7 @@ public void testLD_nn__A() { } @Test - public void testLD_A__I() { + public void testLD_A_I() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .secondIsRegisterI() @@ -270,7 +225,7 @@ public void testLD_A__I() { } @Test - public void testLD_A__R() { + public void testLD_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .secondIsRegisterR() @@ -286,7 +241,7 @@ public void testLD_A__R() { } @Test - public void testLD_I__A() { + public void testLD_I_A() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegisterI() .secondIsRegister(REG_A) @@ -298,7 +253,7 @@ public void testLD_I__A() { } @Test - public void testLD_R__A() { + public void testLD_R_A() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegisterR() .secondIsRegister(REG_A) @@ -310,7 +265,7 @@ public void testLD_R__A() { } @Test - public void testLD_dd__nn() { + public void testLD_RP_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .clearOtherVerifiersAfterRun(); @@ -323,7 +278,7 @@ public void testLD_dd__nn() { } @Test - public void testLD_IX_IY__nn() { + public void testLD_II_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .clearOtherVerifiersAfterRun(); @@ -334,7 +289,7 @@ public void testLD_IX_IY__nn() { } @Test - public void testLD_HL__mNN() { + public void testLD_HL_REF_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryWord() .verifyPair(REG_PAIR_HL, context -> context.second); @@ -345,7 +300,7 @@ public void testLD_HL__mNN() { } @Test - public void testLD_dd__mNN() { + public void testLD_RP_REF_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryWord() .keepCurrentInjectorsAfterRun() @@ -360,7 +315,7 @@ public void testLD_dd__mNN() { } @Test - public void testLD_IX_IY__mNN() { + public void testLD_II_REF_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryWord() .keepCurrentInjectorsAfterRun() @@ -373,7 +328,7 @@ public void testLD_IX_IY__mNN() { } @Test - public void testLD_mNN__HL() { + public void testLD_REF_NN_HL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryWord() .firstIsPair(REG_PAIR_HL) @@ -385,7 +340,7 @@ public void testLD_mNN__HL() { } @Test - public void testLD_mNN__dd() { + public void testLD_REF_NN_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryWord() .verifyWord(context -> context.first, context -> context.first) @@ -400,7 +355,7 @@ public void testLD_mNN__dd() { } @Test - public void testLD_mNN__IX_IY() { + public void testLD_REF_NN_II() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryWord() .verifyWord(context -> context.first, context -> context.first) @@ -413,7 +368,7 @@ public void testLD_mNN__IX_IY() { } @Test - public void testLD_SP__HL() { + public void testLD_SP_HL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsPair(REG_PAIR_HL) .verifyPair(REG_SP, context -> context.first); @@ -424,7 +379,7 @@ public void testLD_SP__HL() { } @Test - public void testLD_SP__IX_IY() { + public void testLD_SP_II() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .verifyPair(REG_SP, context -> context.first) .clearOtherVerifiersAfterRun(); @@ -436,7 +391,7 @@ public void testLD_SP__IX_IY() { } @Test - public void testEX_DE__HL() { + public void testEX_DE_HL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsPair(REG_PAIR_DE) .secondIsPair(REG_PAIR_HL) @@ -449,7 +404,7 @@ public void testEX_DE__HL() { } @Test - public void testEX_AF__AF2() { + public void testEX_AF_AF2() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAF() .secondIsAF2() @@ -483,7 +438,7 @@ public void testEXX() { } @Test - public void testEX_mSP__HL() { + public void testEX_REF_SP_HL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryWord() .firstIsPair(REG_SP) @@ -497,7 +452,7 @@ public void testEX_mSP__HL() { } @Test - public void testEX_mSP__IX_IY() { + public void testEX_REF_SP_II() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryWord() .firstIsPair(REG_SP) @@ -610,4 +565,46 @@ public void testLDDR() { ); } + private void runLD_R_R_test(int register, int... opcodes) { + ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsRegister(register) + .verifyRegister(register, context -> context.second & 0xFF) + .keepCurrentInjectorsAfterRun(); + + Generator.forSome8bitBinary( + test.secondIsRegister(REG_B).run(opcodes[0]), + test.secondIsRegister(REG_C).run(opcodes[1]), + test.secondIsRegister(REG_D).run(opcodes[2]), + test.secondIsRegister(REG_E).run(opcodes[3]), + test.secondIsRegister(REG_H).run(opcodes[4]), + test.secondIsRegister(REG_L).run(opcodes[5]), + test.secondIsMemoryByteAt(0x303).setPair(REG_PAIR_HL, 0x303).run(opcodes[6]), + test.secondIsRegister(REG_A).run(opcodes[7]) + ); + + } + + private void runLD_R_N_test(int register, int opcode) { + ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsRegister(register) + .verifyRegister(register, context -> context.second & 0xFF) + .keepCurrentInjectorsAfterRun(); + + Generator.forSome8bitBinary( + test.runWithSecondOperand(opcode) + ); + } + + private void runLD_R_II_N(int register, int opcode) { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8LSBisRegister(register) + .verifyRegister(register, context -> context.second & 0xFF) + .keepCurrentInjectorsAfterRun(); + + Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, opcode), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, opcode) + ); + } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java index ec4033d2d..9cde01e62 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java @@ -19,9 +19,9 @@ package net.emustudio.plugins.cpu.zilogZ80.suite; import net.emustudio.cpu.testsuite.CpuRunner; -import net.emustudio.cpu.testsuite.memory.ShortMemoryStub; +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.plugins.cpu.zilogZ80.CpuImpl; -import net.emustudio.plugins.cpu.zilogZ80.FakeDevice; +import net.emustudio.plugins.cpu.zilogZ80.FakeByteDevice; import java.util.ArrayList; import java.util.List; @@ -30,9 +30,9 @@ import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.*; public class CpuRunnerImpl extends CpuRunner { - private final List devices; + private final List devices; - public CpuRunnerImpl(CpuImpl cpu, ShortMemoryStub memoryStub, List devices) { + public CpuRunnerImpl(CpuImpl cpu, ByteMemoryStub memoryStub, List devices) { super(cpu, memoryStub); this.devices = List.copyOf(Objects.requireNonNull(devices)); } @@ -110,7 +110,7 @@ public boolean getIFF(int index) { return cpu.getEngine().IFF[index]; } - public FakeDevice getDevice(int port) { + public FakeByteDevice getDevice(int port) { return devices.get(port); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java index 07f05ae1c..2db8fce5c 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java @@ -19,9 +19,9 @@ package net.emustudio.plugins.cpu.zilogZ80.suite; import net.emustudio.cpu.testsuite.CpuVerifier; -import net.emustudio.cpu.testsuite.memory.ShortMemoryStub; +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.plugins.cpu.zilogZ80.CpuImpl; -import net.emustudio.plugins.cpu.zilogZ80.FakeDevice; +import net.emustudio.plugins.cpu.zilogZ80.FakeByteDevice; import java.util.List; import java.util.Objects; @@ -31,9 +31,9 @@ public class CpuVerifierImpl extends CpuVerifier { private final CpuImpl cpu; - private final List devices; + private final List devices; - public CpuVerifierImpl(CpuImpl cpu, ShortMemoryStub memoryStub, List devices) { + public CpuVerifierImpl(CpuImpl cpu, ByteMemoryStub memoryStub, List devices) { super(memoryStub); this.cpu = Objects.requireNonNull(cpu); this.devices = List.copyOf(Objects.requireNonNull(devices)); @@ -160,7 +160,7 @@ public void checkIntMode(int mode) { assertEquals(mode, cpu.getEngine().intMode); } - public String intToFlags(int flags) { + public static String intToFlags(int flags) { String flagsString = ""; if ((flags & FLAG_S) == FLAG_S) { flagsString += "S"; @@ -174,6 +174,9 @@ public String intToFlags(int flags) { if ((flags & FLAG_PV) == FLAG_PV) { flagsString += "P"; } + if ((flags & FLAG_N) == FLAG_N) { + flagsString += "N"; + } if ((flags & FLAG_C) == FLAG_C) { flagsString += "C"; } @@ -183,7 +186,7 @@ public String intToFlags(int flags) { @Override public void checkFlags(int mask) { assertEquals(String.format("Expected flags=%s, but was %s", - intToFlags(mask), intToFlags(cpu.getEngine().flags)), (cpu.getEngine().flags & mask), mask); + intToFlags(mask), intToFlags(cpu.getEngine().flags)), mask, (cpu.getEngine().flags & mask)); } @Override diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java index a756e5811..326c0df16 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java @@ -151,6 +151,29 @@ public FlagsCheckImpl carry() { return this; } + public FlagsCheckImpl borrow() { + // doesn't work if sub is using carry=1 (SBC) + evaluators.add((context, result) -> { + if ((context.first.intValue() & 0xFF) > (0xFF - (((~context.second.intValue()) + 1) & 0xFF))) { + expectedFlags |= FLAG_C; + } else { + expectedNotFlags |= FLAG_C; + } + }); + return this; + } + + public FlagsCheckImpl borrowWithCarry() { + evaluators.add((context, result) -> { + if ((context.first.intValue() & 0xFF) > (0xFF - (((~context.second.intValue()) + 1 - (context.flags & FLAG_C)) & 0xFF))) { + expectedFlags |= FLAG_C; + } else { + expectedNotFlags |= FLAG_C; + } + }); + return this; + } + public FlagsCheckImpl carryIsFirstOperandMSB() { evaluators.add((context, result) -> { if ((context.first.intValue() & 0x80) == 0x80) { @@ -204,6 +227,35 @@ public FlagsCheckImpl halfCarry() { return this; } + public FlagsCheckImpl halfBorrow() { + evaluators.add((context, result) -> { + int carryIns = result ^ (context.first.intValue() & 0xFF) ^ (((~context.second.intValue()) + 1) & 0xFF); + int halfCarryOut = (carryIns >> 4) & 1; + + if (halfCarryOut == 1) { + expectedFlags |= FLAG_H; + } else { + expectedNotFlags |= FLAG_H; + } + }); + return this; + } + + public FlagsCheckImpl halfBorrowWithCarry() { + evaluators.add((context, result) -> { + int b = (((~context.second.intValue()) + 1 - (context.flags & FLAG_C)) & 0xFF); + int carryIns = result ^ (context.first.intValue() & 0xFF) ^ b; + int halfCarryOut = (carryIns >> 4) & 1; + + if (halfCarryOut == 1) { + expectedFlags |= FLAG_H; + } else { + expectedNotFlags |= FLAG_H; + } + }); + return this; + } + public FlagsCheckImpl halfCarry11() { evaluators.add((context, result) -> { int second = (result - context.first.intValue()) & 0xFFFF; From 7f4a563e7dcd4f20fabc294c1c1a4f35ce44b8e8 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 30 Jan 2022 18:33:11 +0100 Subject: [PATCH 084/314] [#201] z80: simplify --- .../plugins/cpu/zilogZ80/DispatchTables.java | 22 +- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 350 ++++++++---------- .../plugins/cpu/zilogZ80/EmulatorTables.java | 29 -- 3 files changed, 168 insertions(+), 233 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java index 5329e1768..b61a59a2b 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java @@ -26,7 +26,7 @@ public class DispatchTables { try { DISPATCH_TABLE[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); DISPATCH_TABLE[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); - DISPATCH_TABLE[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_BC_A", intShort); // TODO: unify + DISPATCH_TABLE[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_BC_A", intShort); DISPATCH_TABLE[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); DISPATCH_TABLE[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); DISPATCH_TABLE[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); @@ -34,7 +34,7 @@ public class DispatchTables { DISPATCH_TABLE[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLCA", intShort); DISPATCH_TABLE[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_EX_AF_AFF", intShort); DISPATCH_TABLE[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); - DISPATCH_TABLE[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_BC", intShort); // TODO: unify + DISPATCH_TABLE[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_BC", intShort); DISPATCH_TABLE[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); DISPATCH_TABLE[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); DISPATCH_TABLE[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); @@ -42,7 +42,7 @@ public class DispatchTables { DISPATCH_TABLE[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRCA", intShort); DISPATCH_TABLE[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_DJNZ", intShort); DISPATCH_TABLE[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); - DISPATCH_TABLE[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_DE_A", intShort); // TODO: unify + DISPATCH_TABLE[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_DE_A", intShort); DISPATCH_TABLE[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); DISPATCH_TABLE[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); DISPATCH_TABLE[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); @@ -50,7 +50,7 @@ public class DispatchTables { DISPATCH_TABLE[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RLA", intShort); DISPATCH_TABLE[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_JR_N", intShort); DISPATCH_TABLE[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); - DISPATCH_TABLE[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_DE", intShort); // TODO: unify + DISPATCH_TABLE[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_DE", intShort); DISPATCH_TABLE[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); DISPATCH_TABLE[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); DISPATCH_TABLE[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); @@ -58,7 +58,7 @@ public class DispatchTables { DISPATCH_TABLE[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RRA", intShort); DISPATCH_TABLE[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); DISPATCH_TABLE[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); - DISPATCH_TABLE[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_HL", intShort); // TODO: unify??? + DISPATCH_TABLE[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_HL", intShort); DISPATCH_TABLE[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); DISPATCH_TABLE[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); DISPATCH_TABLE[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); @@ -66,7 +66,7 @@ public class DispatchTables { DISPATCH_TABLE[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_DAA", intShort); DISPATCH_TABLE[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); DISPATCH_TABLE[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); - DISPATCH_TABLE[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_HL_REF_NN", intShort); // TODO: unify ??? + DISPATCH_TABLE[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_HL_REF_NN", intShort); DISPATCH_TABLE[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); DISPATCH_TABLE[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); DISPATCH_TABLE[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); @@ -74,7 +74,7 @@ public class DispatchTables { DISPATCH_TABLE[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_CPL", intShort); DISPATCH_TABLE[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); DISPATCH_TABLE[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); - DISPATCH_TABLE[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_A", intShort); // TODO: unify + DISPATCH_TABLE[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_A", intShort); DISPATCH_TABLE[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); DISPATCH_TABLE[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); DISPATCH_TABLE[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); @@ -82,7 +82,7 @@ public class DispatchTables { DISPATCH_TABLE[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SCF", intShort); DISPATCH_TABLE[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); DISPATCH_TABLE[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); - DISPATCH_TABLE[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_NN", intShort); // TODO: unify + DISPATCH_TABLE[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_NN", intShort); DISPATCH_TABLE[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); DISPATCH_TABLE[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); DISPATCH_TABLE[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); @@ -152,7 +152,7 @@ public class DispatchTables { DISPATCH_TABLE[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); DISPATCH_TABLE[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); DISPATCH_TABLE[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); // TODO: ADD R, R + DISPATCH_TABLE[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); DISPATCH_TABLE[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); DISPATCH_TABLE[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); DISPATCH_TABLE[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); @@ -251,7 +251,7 @@ public class DispatchTables { DISPATCH_TABLE[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); DISPATCH_TABLE[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", intShort); DISPATCH_TABLE[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); - DISPATCH_TABLE[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_HL", intShort); // TODO: unify ??? + DISPATCH_TABLE[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_HL", intShort); DISPATCH_TABLE[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); DISPATCH_TABLE[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", intShort); DISPATCH_TABLE[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_N", intShort); @@ -259,7 +259,7 @@ public class DispatchTables { DISPATCH_TABLE[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); DISPATCH_TABLE[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_HL", intShort); DISPATCH_TABLE[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); - DISPATCH_TABLE[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_EX_DE_HL", intShort); // TODO: union??? + DISPATCH_TABLE[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_EX_DE_HL", intShort); DISPATCH_TABLE[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); DISPATCH_TABLE[0xED] = lookup.findVirtual(EmulatorEngine.class, "ED_DISPATCH", intShort); DISPATCH_TABLE[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_N", intShort); diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 002fd07d4..638831e21 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -139,7 +139,7 @@ CPU.RunState step() throws Exception { boolean oldIFF = IFF[0]; noWait = false; currentRunState = CPU.RunState.STATE_STOPPED_BREAK; - short opcode = (short)(memory.read(PC) & 0xFF); + short opcode = (short) (memory.read(PC) & 0xFF); PC = (PC + 1) & 0xFFFF; try { dispatch(opcode); @@ -256,7 +256,7 @@ int FD_CB_DISPATCH(short OP) throws Throwable { } private int DISPATCH(MethodHandle[] table) throws Throwable { - short OP = (short)(memory.read(PC) & 0xFF); + short OP = (short) (memory.read(PC) & 0xFF); incrementR(); PC = (PC + 1) & 0xFFFF; @@ -272,7 +272,7 @@ int SPECIAL_CB_DISPATCH(MethodHandle[] table) throws Throwable { byte operand = memory.read(PC); PC = (PC + 1) & 0xFFFF; - short OP = (short)(memory.read(PC) & 0xFF); + short OP = (short) (memory.read(PC) & 0xFF); PC = (PC + 1) & 0xFFFF; incrementR(); @@ -337,7 +337,6 @@ private int doInterrupt() throws Throwable { return cycles; } - private int getreg(int reg) { if (reg == 6) { return readByte((regs[REG_H] << 8) | regs[REG_L]); @@ -345,13 +344,6 @@ private int getreg(int reg) { return regs[reg]; } - private byte getreg2(int reg) { - if (reg == 6) { - return 0; - } - return (byte)regs[reg]; - } - private void putreg(int reg, int val) { if (reg == 6) { memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) (val & 0xFF)); @@ -360,12 +352,6 @@ private void putreg(int reg, int val) { } } - private void putreg2(int reg, int val) { - if (reg != 6) { - regs[reg] = val & 0xFF; - } - } - private void putpair(int reg, int val, boolean reg3IsSP) { int high = (val >>> 8) & 0xFF; int low = val & 0xFF; @@ -393,16 +379,6 @@ private int getpair(int reg, boolean reg3IsSP) { } - private int getpair(short special, int reg) { - if (reg == 3) { - return SP; - } else if (reg == 2) { - return (special == 0xDD) ? IX : IY; - } - int index = reg * 2; - return regs[index] << 8 | regs[index + 1]; - } - private boolean getCC1(int cc) { switch (cc) { case 0: @@ -417,28 +393,6 @@ private boolean getCC1(int cc) { return false; } - private void putspecial(short spec, int val) { - val &= 0xFFFF; - switch (spec) { - case 0xDD: - IX = val; - break; - case 0xFD: - IY = val; - break; - } - } - - private int getspecial(short spec) { - switch (spec) { - case 0xDD: - return IX; - case 0xFD: - return IY; - } - return 0; - } - private int readByte(int address) { return memory.read(address) & 0xFF; } @@ -897,7 +851,7 @@ int I_IN_R_REF_C(short OP) throws IOException { int I_OUT_REF_C_R(short OP) throws IOException { int tmp = (OP >>> 3) & 0x7; - context.writeIO(regs[REG_C], (byte)getreg(tmp)); + context.writeIO(regs[REG_C], (byte) getreg(tmp)); return 12; } @@ -1637,7 +1591,7 @@ int I_RRC_R(short OP) { int I_RL_R(short OP) { int tmp = OP & 7; - int tmp1 = getreg(tmp)& 0xFF; + int tmp1 = getreg(tmp) & 0xFF; int tmp2 = (tmp1 >>> 7) & 1; tmp1 = ((((tmp1 << 1) & 0xFF) | flags & FLAG_C) & 0xFF); @@ -1780,116 +1734,116 @@ int I_SET_N_R(short OP) { } int I_ADD_IX_RP(short OP) { - return I_ADD_II_RP(OP, (short) 0xDD); + IX = I_ADD_II_RP(OP, IX); + return 15; } int I_ADD_IY_RP(short OP) { - return I_ADD_II_RP(OP, (short) 0xFD); + IY = I_ADD_II_RP(OP, IY); + return 15; } - int I_ADD_II_RP(short OP, short special) { - int tmp = getspecial(special); - int tmp1 = getpair(special, (OP >>> 4) & 0x03); + int I_ADD_II_RP(short OP, int special) { + int tmp = special; + int pair; + int reg = (OP >>> 4) & 0x03; + switch (reg) { + case 3: + pair = SP; + break; + case 2: + pair = special; + break; + default: + int index = reg * 2; + pair = regs[index] << 8 | regs[index + 1]; + } - carry15(tmp, tmp1); - halfCarry11(tmp, tmp1); + carry15(tmp, pair); + halfCarry11(tmp, pair); flags &= (~(FLAG_N | FLAG_S | FLAG_Z)); - tmp += tmp1; + tmp += pair; flags |= ((tmp & 0x8000) == 0x8000) ? FLAG_S : 0; flags |= (tmp == 0) ? FLAG_Z : 0; - putspecial(special, tmp); - return 15; + return tmp & 0xFFFF; } int I_LD_IX_NN(short OP) { - return I_LD_II_NN(OP, (short) 0xDD); + IX = readWord(PC); + PC = (PC + 2) & 0xFFFF; + return 14; } int I_LD_IY_NN(short OP) { - return I_LD_II_NN(OP, (short) 0xFD); - } - - int I_LD_II_NN(short OP, short special) { - int tmp = readWord(PC); + IY = readWord(PC); PC = (PC + 2) & 0xFFFF; - putspecial(special, tmp); return 14; } int I_LD_REF_NN_IX(short OP) { - return I_LD_REF_NN_II(OP, (short) 0xDD); + return I_LD_REF_NN_II(OP, IX); } int I_LD_REF_NN_IY(short OP) { - return I_LD_REF_NN_II(OP, (short) 0xFD); + return I_LD_REF_NN_II(OP, IY); } - int I_LD_REF_NN_II(short OP, short special) { + int I_LD_REF_NN_II(short OP, int special) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; - writeWord(tmp, getspecial(special)); + writeWord(tmp, special); return 16; } int I_INC_IX(short OP) { - return I_INC_II(OP, (short) 0xDD); + IX = (IX + 1) & 0xFFFF; + return 10; } int I_INC_IY(short OP) { - return I_INC_II(OP, (short) 0xFD); - } - - int I_INC_II(short OP, short special) { - if (special == 0xDD) { - IX = (IX + 1) & 0xFFFF; - } else { - IY = (IY + 1) & 0xFFFF; - } + IY = (IY + 1) & 0xFFFF; return 10; } int I_LD_IX_REF_NN(short OP) { - return I_LD_II_REF_NN(OP, (short) 0xDD); + IX = I_LD_II_REF_NN(); + return 20; } int I_LD_IY_REF_NN(short OP) { - return I_LD_II_REF_NN(OP, (short) 0xFD); + IY = I_LD_II_REF_NN(); + return 20; } - int I_LD_II_REF_NN(short OP, short special) { + int I_LD_II_REF_NN() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; - int tmp1 = readWord(tmp); - putspecial(special, tmp1); - return 20; + return readWord(tmp); } int I_DEC_IX(short OP) { - return I_DEC_II(OP, (short) 0xDD); + IX = (IX - 1) & 0xFFFF; + return 10; } int I_DEC_IY(short OP) { - return I_DEC_II(OP, (short) 0xFD); - } - - int I_DEC_II(short OP, short special) { - putspecial(special, getspecial(special) - 1); + IY = (IY - 1) & 0xFFFF; return 10; } int I_INC_REF_IX_N(short OP) { - return I_INC_REF_II_N(OP, (short) 0xDD); + return I_INC_REF_II_N(OP, IX); } int I_INC_REF_IY_N(short OP) { - return I_INC_REF_II_N(OP, (short) 0xFD); + return I_INC_REF_II_N(OP, IY); } - int I_INC_REF_II_N(short OP, short special) { - int tmp = readByte(PC); + int I_INC_REF_II_N(short OP, int special) { + byte tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = (getspecial(special) + (byte) tmp) & 0xFFFF; + int tmp1 = (special + tmp) & 0xFFFF; int tmp2 = (memory.read(tmp1) + 1) & 0xFF; memory.write(tmp1, (byte) tmp2); @@ -1898,17 +1852,17 @@ int I_INC_REF_II_N(short OP, short special) { } int I_DEC_REF_IX_N(short OP) { - return I_DEC_REF_II_N(OP, (short) 0xDD); + return I_DEC_REF_II_N(OP, IX); } int I_DEC_REF_IY_N(short OP) { - return I_DEC_REF_II_N(OP, (short) 0xFD); + return I_DEC_REF_II_N(OP, IY); } - int I_DEC_REF_II_N(short OP, short special) { + int I_DEC_REF_II_N(short OP, int special) { int tmp = readByte(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = (getspecial(special) + (byte) tmp) & 0xFFFF; + int tmp1 = (special + (byte) tmp) & 0xFFFF; int tmp2 = (memory.read(tmp1) - 1) & 0xFF; memory.write(tmp1, (byte) tmp2); flags = EmulatorTables.DEC_TABLE[tmp2] | (flags & FLAG_C); @@ -1916,66 +1870,65 @@ int I_DEC_REF_II_N(short OP, short special) { } int I_LD_REF_IX_N_N(short OP) { - return I_LD_REF_II_N_N(OP, (short) 0xDD); + return I_LD_REF_II_N_N(OP, IX); } int I_LD_REF_IY_N_N(short OP) { - return I_LD_REF_II_N_N(OP, (short) 0xFD); + return I_LD_REF_II_N_N(OP, IY); } - int I_LD_REF_II_N_N(short OP, short special) { + int I_LD_REF_II_N_N(short OP, int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; byte number = memory.read(PC); PC = (PC + 1) & 0xFFFF; - memory.write((getspecial(special) + offset) & 0xFFFF, number); + memory.write((special + offset) & 0xFFFF, number); return 19; } int I_LD_R_REF_IX_N(short OP) { - return I_LD_R_REF_II_N(OP, (short) 0xDD); + return I_LD_R_REF_II_N(OP, IX); } int I_LD_R_REF_IY_N(short OP) { - return I_LD_R_REF_II_N(OP, (short) 0xFD); + return I_LD_R_REF_II_N(OP, IY); } - int I_LD_R_REF_II_N(short OP, short special) { + int I_LD_R_REF_II_N(short OP, int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; int tmp1 = (OP >>> 3) & 7; - putreg2(tmp1, memory.read((getspecial(special) + offset) & 0xFFFF)); + putreg(tmp1, memory.read((special + offset) & 0xFFFF)); return 19; } int I_LD_REF_IX_N_R(short OP) { - return I_LD_REF_II_N_R(OP, (short)0xDD); + return I_LD_REF_II_N_R(OP, IX); } int I_LD_REF_IY_N_R(short OP) { - return I_LD_REF_II_N_R(OP, (short)0xFD); + return I_LD_REF_II_N_R(OP, IY); } - int I_LD_REF_II_N_R(short OP, short special) { - byte tmp = memory.read(PC); + int I_LD_REF_II_N_R(short OP, int special) { + byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = (OP & 7); - memory.write((getspecial(special) + tmp) & 0xFFFF, getreg2(tmp1)); + memory.write((special + offset) & 0xFFFF, (byte) getreg(OP & 7)); return 19; } int I_ADD_A_REF_IX_N(short OP) { - return I_ADD_A_REF_II_N(OP, (short)0xDD); + return I_ADD_A_REF_II_N(OP, IX); } int I_ADD_A_REF_IY_N(short OP) { - return I_ADD_A_REF_II_N(OP, (short)0xFD); + return I_ADD_A_REF_II_N(OP, IY); } - int I_ADD_A_REF_II_N(short OP, short special) { + int I_ADD_A_REF_II_N(short OP, int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = readByte((getspecial(special) + offset) & 0xFFFF); + int value = readByte((special + offset) & 0xFFFF); int oldA = regs[REG_A]; regs[REG_A] = (oldA + value) & 0xFF; flags = flagSZHPC(oldA, value, regs[REG_A]); @@ -1983,17 +1936,17 @@ int I_ADD_A_REF_II_N(short OP, short special) { } int I_ADC_A_REF_IX_N(short OP) { - return I_ADC_A_REF_II_N(OP, (short) 0xDD); + return I_ADC_A_REF_II_N(OP, IX); } int I_ADC_A_REF_IY_N(short OP) { - return I_ADC_A_REF_II_N(OP, (short) 0xFD); + return I_ADC_A_REF_II_N(OP, IY); } - int I_ADC_A_REF_II_N(short OP, short special) { + int I_ADC_A_REF_II_N(short OP, int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = readByte((getspecial(special) + offset) & 0xFFFF); + int value = readByte((special + offset) & 0xFFFF); int oldA = regs[REG_A]; regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; flags = flagSZHPC(oldA, (value + (flags & FLAG_C)) & 0xFF, regs[REG_A]); @@ -2001,17 +1954,17 @@ int I_ADC_A_REF_II_N(short OP, short special) { } int I_SUB_REF_IX_N(short OP) { - return I_SUB_REF_II_N(OP, (short) 0xDD); + return I_SUB_REF_II_N(OP, IX); } int I_SUB_REF_IY_N(short OP) { - return I_SUB_REF_II_N(OP, (short) 0xFD); + return I_SUB_REF_II_N(OP, IY); } - int I_SUB_REF_II_N(short OP, short special) { + int I_SUB_REF_II_N(short OP, int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = ((~readByte((getspecial(special) + offset) & 0xFFFF)) + 1) & 0xFF; + int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value) & 0xFF; flags = flagSZHPC(oldA, value, regs[REG_A]) | FLAG_N; @@ -2019,17 +1972,17 @@ int I_SUB_REF_II_N(short OP, short special) { } int I_SBC_A_REF_IX_N(short OP) { - return I_SBC_A_REF_II_N(OP, (short) 0xDD); + return I_SBC_A_REF_II_N(OP, IX); } int I_SBC_A_REF_IY_N(short OP) { - return I_SBC_A_REF_II_N(OP, (short) 0xFD); + return I_SBC_A_REF_II_N(OP, IY); } - int I_SBC_A_REF_II_N(short OP, short special) { + int I_SBC_A_REF_II_N(short OP, int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = ((~readByte((getspecial(special) + offset) & 0xFFFF)) + 1) & 0xFF; + int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value - (flags & FLAG_C)) & 0xFF; flags = flagSZHPC(oldA, (value - (flags & FLAG_C)) & 0xFF, regs[REG_A]) | FLAG_N; @@ -2037,70 +1990,70 @@ int I_SBC_A_REF_II_N(short OP, short special) { } int I_AND_REF_IX_N(short OP) { - return I_AND_REF_II_N(OP, (short) 0xDD); + return I_AND_REF_II_N(OP, IX); } int I_AND_REF_IY_N(short OP) { - return I_AND_REF_II_N(OP, (short) 0xFD); + return I_AND_REF_II_N(OP, IY); } - int I_AND_REF_II_N(short OP, short special) { + int I_AND_REF_II_N(short OP, int special) { byte tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = memory.read((getspecial(special) + tmp) & 0xFFFF); + int tmp1 = memory.read((special + tmp) & 0xFFFF); regs[REG_A] = (regs[REG_A] & tmp1) & 0xFF; flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; return 19; } int I_XOR_REF_IX_N(short OP) { - return I_XOR_REF_II_N(OP, (short) 0xDD); + return I_XOR_REF_II_N(OP, IX); } int I_XOR_REF_IY_N(short OP) { - return I_XOR_REF_II_N(OP, (short) 0xFD); + return I_XOR_REF_II_N(OP, IY); } - int I_XOR_REF_II_N(short OP, short special) { + int I_XOR_REF_II_N(short OP, int special) { byte tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = memory.read((getspecial(special) + tmp) & 0xFFFF); + int tmp1 = memory.read((special + tmp) & 0xFFFF); regs[REG_A] = ((regs[REG_A] ^ tmp1) & 0xff); flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; return 19; } int I_OR_REF_IX_N(short OP) { - return I_OR_REF_II_N(OP, (short) 0xDD); + return I_OR_REF_II_N(OP, IX); } int I_OR_REF_IY_N(short OP) { - return I_OR_REF_II_N(OP, (short) 0xFD); + return I_OR_REF_II_N(OP, IY); } - int I_OR_REF_II_N(short OP, short special) { + int I_OR_REF_II_N(short OP, int special) { byte tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = memory.read((getspecial(special) + tmp) & 0xFFFF); + int tmp1 = memory.read((special + tmp) & 0xFFFF); regs[REG_A] = ((regs[REG_A] | tmp1) & 0xff); flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; return 19; } int I_CP_REF_IX_N(short OP) { - return I_CP_REF_II_N(OP, (short) 0xDD); + return I_CP_REF_II_N(OP, IX); } int I_CP_REF_IY_N(short OP) { - return I_CP_REF_II_N(OP, (short) 0xFD); + return I_CP_REF_II_N(OP, IY); } - int I_CP_REF_II_N(short OP, short special) { + int I_CP_REF_II_N(short OP, int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = ((~readByte((getspecial(special) + offset) & 0xFFFF)) + 1) & 0xFF; + int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; int diff = (regs[REG_A] + value) & 0xFF; flags = flagSZHPC(regs[REG_A], value, diff) | FLAG_N; return 19; @@ -2167,15 +2120,15 @@ int I_LD_SP_IY(short OP) { } int I_RLC_REF_IX_N_R(short OP, byte operand) { - return I_RLC_REF_II_N_R(OP, operand, (short) 0xDD); + return I_RLC_REF_II_N_R(OP, operand, IX); } int I_RLC_REF_IY_N_R(short OP, byte operand) { - return I_RLC_REF_II_N_R(OP, operand, (short) 0xFD); + return I_RLC_REF_II_N_R(OP, operand, IY); } - int I_RLC_REF_II_N_R(short OP, byte operand, short special) { - int address = (getspecial(special) + operand) & 0xFFFF; + int I_RLC_REF_II_N_R(short OP, byte operand, int special) { + int address = (special + operand) & 0xFFFF; int value = readByte(address); int bit7 = (value >>> 7) & 1; @@ -2189,15 +2142,15 @@ int I_RLC_REF_II_N_R(short OP, byte operand, short special) { } int I_RRC_REF_IX_N_R(short OP, byte operand) { - return I_RRC_REF_II_N_R(OP, operand, (short) 0xDD); + return I_RRC_REF_II_N_R(OP, operand, IX); } int I_RRC_REF_IY_N_R(short OP, byte operand) { - return I_RRC_REF_II_N_R(OP, operand, (short) 0xFD); + return I_RRC_REF_II_N_R(OP, operand, IY); } - int I_RRC_REF_II_N_R(short OP, byte operand, short special) { - int tmp = (getspecial(special) + operand) & 0xffff; + int I_RRC_REF_II_N_R(short OP, byte operand, int special) { + int tmp = (special + operand) & 0xffff; int tmp1 = memory.read(tmp); int tmp2 = tmp1 & 1; @@ -2212,15 +2165,15 @@ int I_RRC_REF_II_N_R(short OP, byte operand, short special) { } int I_RL_REF_IX_N_R(short OP, byte operand) { - return I_RL_REF_II_N_R(OP, operand, (short) 0xDD); + return I_RL_REF_II_N_R(OP, operand, IX); } int I_RL_REF_IY_N_R(short OP, byte operand) { - return I_RL_REF_II_N_R(OP, operand, (short) 0xFD); + return I_RL_REF_II_N_R(OP, operand, IY); } - int I_RL_REF_II_N_R(short OP, byte operand, short special) { - int tmp = (getspecial(special) + operand) & 0xffff; + int I_RL_REF_II_N_R(short OP, byte operand, int special) { + int tmp = (special + operand) & 0xffff; int tmp1 = memory.read(tmp); int tmp2 = (tmp1 >>> 7) & 1; @@ -2234,15 +2187,15 @@ int I_RL_REF_II_N_R(short OP, byte operand, short special) { } int I_RR_REF_IX_N_R(short OP, byte operand) { - return I_RR_REF_II_N_R(OP, operand, (short) 0xDD); + return I_RR_REF_II_N_R(OP, operand, IX); } int I_RR_REF_IY_N_R(short OP, byte operand) { - return I_RR_REF_II_N_R(OP, operand, (short) 0xFD); + return I_RR_REF_II_N_R(OP, operand, IY); } - int I_RR_REF_II_N_R(short OP, byte operand, short special) { - int address = (getspecial(special) + operand) & 0xffff; + int I_RR_REF_II_N_R(short OP, byte operand, int special) { + int address = (special + operand) & 0xffff; int value = readByte(address); int bit0 = value & 1; @@ -2256,15 +2209,15 @@ int I_RR_REF_II_N_R(short OP, byte operand, short special) { } int I_SLA_REF_IX_N_R(short OP, byte operand) { - return I_SLA_REF_II_N_R(OP, operand, (short) 0xDD); + return I_SLA_REF_II_N_R(OP, operand, IX); } int I_SLA_REF_IY_N_R(short OP, byte operand) { - return I_SLA_REF_II_N_R(OP, operand, (short) 0xFD); + return I_SLA_REF_II_N_R(OP, operand, IY); } - int I_SLA_REF_II_N_R(short OP, byte operand, short special) { - int tmp = (getspecial(special) + operand) & 0xffff; + int I_SLA_REF_II_N_R(short OP, byte operand, int special) { + int tmp = (special + operand) & 0xFFFF; int tmp1 = memory.read(tmp); int tmp2 = (tmp1 >>> 7) & 1; @@ -2278,15 +2231,15 @@ int I_SLA_REF_II_N_R(short OP, byte operand, short special) { } int I_SRA_REF_IX_N_R(short OP, byte operand) { - return I_SRA_REF_II_N_R(OP, operand, (short) 0xDD); + return I_SRA_REF_II_N_R(OP, operand, IX); } int I_SRA_REF_IY_N_R(short OP, byte operand) { - return I_SRA_REF_II_N_R(OP, operand, (short) 0xFD); + return I_SRA_REF_II_N_R(OP, operand, IY); } - int I_SRA_REF_II_N_R(short OP, byte operand, short special) { - int tmp = (getspecial(special) + operand) & 0xffff; + int I_SRA_REF_II_N_R(short OP, byte operand, int special) { + int tmp = (special + operand) & 0xffff; int tmp1 = memory.read(tmp); int tmp2 = tmp1 & 1; @@ -2300,15 +2253,15 @@ int I_SRA_REF_II_N_R(short OP, byte operand, short special) { } int I_SLL_REF_IX_N_R(short OP, byte operand) { - return I_SLL_REF_II_N_R(OP, operand, (short) 0xDD); + return I_SLL_REF_II_N_R(OP, operand, IX); } int I_SLL_REF_IY_N_R(short OP, byte operand) { - return I_SLL_REF_II_N_R(OP, operand, (short) 0xFD); + return I_SLL_REF_II_N_R(OP, operand, IY); } - int I_SLL_REF_II_N_R(short OP, byte operand, short special) { - int tmp = (getspecial(special) + operand) & 0xffff; + int I_SLL_REF_II_N_R(short OP, byte operand, int special) { + int tmp = (special + operand) & 0xffff; int tmp1 = memory.read(tmp); int tmp2 = (tmp1 >>> 7) & 1; @@ -2322,15 +2275,15 @@ int I_SLL_REF_II_N_R(short OP, byte operand, short special) { } int I_SRL_REF_IX_N_R(short OP, byte operand) { - return I_SRL_REF_II_N_R(OP, operand, (short)0xDD); + return I_SRL_REF_II_N_R(OP, operand, IX); } int I_SRL_REF_IY_N_R(short OP, byte operand) { - return I_SRL_REF_II_N_R(OP, operand, (short)0xFD); + return I_SRL_REF_II_N_R(OP, operand, IY); } - int I_SRL_REF_II_N_R(short OP, byte operand, short special) { - int tmp = (getspecial(special) + operand) & 0xffff; + int I_SRL_REF_II_N_R(short OP, byte operand, int special) { + int tmp = (special + operand) & 0xffff; int tmp1 = memory.read(tmp); int tmp2 = tmp1 & 1; @@ -2344,16 +2297,16 @@ int I_SRL_REF_II_N_R(short OP, byte operand, short special) { } int I_BIT_N_REF_IX_N(short OP, byte operand) { - return I_BIT_N_REF_II_N(OP, operand, (short) 0xDD); + return I_BIT_N_REF_II_N(OP, operand, IX); } int I_BIT_N_REF_IY_N(short OP, byte operand) { - return I_BIT_N_REF_II_N(OP, operand, (short) 0xFD); + return I_BIT_N_REF_II_N(OP, operand, IY); } - int I_BIT_N_REF_II_N(short OP, byte operand, short special) { + int I_BIT_N_REF_II_N(short OP, byte operand, int special) { int bitNumber = (OP >>> 3) & 7; - int tmp1 = memory.read((getspecial(special) + operand) & 0xFFFF); + int tmp1 = memory.read((special + operand) & 0xFFFF); flags = ((flags & FLAG_C) | FLAG_H | (((tmp1 & (1 << bitNumber)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); if (bitNumber == 7) { flags |= (((tmp1 & (1 << 7)) == 0x80) ? FLAG_S : 0); @@ -2362,16 +2315,16 @@ int I_BIT_N_REF_II_N(short OP, byte operand, short special) { } int I_RES_N_REF_IX_N_R(short OP, byte operand) { - return I_RES_N_REF_II_N_R(OP, operand, (short) 0xDD); + return I_RES_N_REF_II_N_R(OP, operand, IX); } int I_RES_N_REF_IY_N_R(short OP, byte operand) { - return I_RES_N_REF_II_N_R(OP, operand, (short) 0xFD); + return I_RES_N_REF_II_N_R(OP, operand, IY); } - int I_RES_N_REF_II_N_R(short OP, byte operand, short special) { + int I_RES_N_REF_II_N_R(short OP, byte operand, int special) { int tmp2 = (OP >>> 3) & 7; - int tmp3 = (getspecial(special) + operand) & 0xffff; + int tmp3 = (special + operand) & 0xffff; int tmp1 = memory.read(tmp3); tmp1 = (tmp1 & (~(1 << tmp2))); memory.write(tmp3, (byte) (tmp1 & 0xff)); @@ -2381,16 +2334,16 @@ int I_RES_N_REF_II_N_R(short OP, byte operand, short special) { } int I_SET_N_REF_IX_N_R(short OP, byte operand) { - return I_SET_N_REF_II_N_R(OP, operand, (short) 0xDD); + return I_SET_N_REF_II_N_R(OP, operand, IX); } int I_SET_N_REF_IY_N_R(short OP, byte operand) { - return I_SET_N_REF_II_N_R(OP, operand, (short) 0xFD); + return I_SET_N_REF_II_N_R(OP, operand, IY); } - int I_SET_N_REF_II_N_R(short OP, byte operand, short special) { + int I_SET_N_REF_II_N_R(short OP, byte operand, int special) { int tmp2 = (OP >>> 3) & 7; - int tmp3 = (getspecial(special) + operand) & 0xffff; + int tmp3 = (special + operand) & 0xffff; int tmp1 = memory.read(tmp3); tmp1 = (tmp1 | (1 << tmp2)); memory.write(tmp3, (byte) (tmp1 & 0xff)); @@ -2399,4 +2352,15 @@ int I_SET_N_REF_II_N_R(short OP, byte operand, short special) { regs[OP & 7] = tmp1 & 0xFF; return 23; } + + //inc ixh +// int I_INC_IIH(short OP, short special) { +// int reg = (OP >>> 3) & 0x07; +// int value = (getreg(reg) + 1) & 0xFF; +// flags = EmulatorTables.INC_TABLE[value] | (flags & FLAG_C); +// putreg(reg, value); +// return (reg == 6) ? 11 : 4; +// } + + } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java index 77ccb407b..bcf8fac0a 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java @@ -18,8 +18,6 @@ */ package net.emustudio.plugins.cpu.zilogZ80; -import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.*; - class EmulatorTables { private final static int FLAG_S_SHIFT = 7; private final static int FLAG_Z_SHIFT = 6; @@ -92,28 +90,6 @@ class EmulatorTables { // } // } - - final static short[] SIGN_ZERO_CARRY_TABLE = { - 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129 - }; - final static short[] SIGN_ZERO_TABLE = new short[]{ 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -293,9 +269,4 @@ class EmulatorTables { 218, 91, 219, 92, 220, 93, 221, 94, 222, 95, 223, 96, 224, 97, 225, 98, 226, 99, 227, 100, 228, 101, 229, 102, 230, 103, 231, 104, 232, 105, 233, 106, 234, 107, 235, 108, 236, 109, 237, 110, 238, 111, 239, 112, 240, 113, 241, 114, 242, 115, 243, 116, 244, 117, 245, 118, 246, 119, 247, 120, 248, 121, 249, 122, 250, 123, 251, 124, 252, 125, 253, 126, 254, 127, 255 }; - - - - - } From b671b9597ee93ffb2597588e0b671177eb7bd899 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 30 Jan 2022 18:55:33 +0100 Subject: [PATCH 085/314] [#201] z80: implement some undocumented instructions --- .../plugins/cpu/zilogZ80/DispatchTables.java | 24 ++--- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 97 +++++++++++++++++-- .../plugins/cpu/zilogZ80/ArithmeticTest.java | 41 ++++++++ .../plugins/cpu/zilogZ80/TransferTest.java | 20 ++++ 4 files changed, 162 insertions(+), 20 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java index b61a59a2b..7f480fa88 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java @@ -622,15 +622,15 @@ public class DispatchTables { DISPATCH_TABLE_DD[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IX_NN", intShort); DISPATCH_TABLE_DD[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_IX", intShort); DISPATCH_TABLE_DD[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IX", intShort); - DISPATCH_TABLE_DD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: inc ixh - DISPATCH_TABLE_DD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: dec ixh - DISPATCH_TABLE_DD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,* + DISPATCH_TABLE_DD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IXH", intShort); + DISPATCH_TABLE_DD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IXH", intShort); + DISPATCH_TABLE_DD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_N", intShort); DISPATCH_TABLE_DD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", intShort); DISPATCH_TABLE_DD[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IX_REF_NN", intShort); DISPATCH_TABLE_DD[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IX", intShort); - DISPATCH_TABLE_DD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: inc ixl - DISPATCH_TABLE_DD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: dec ixl - DISPATCH_TABLE_DD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,* + DISPATCH_TABLE_DD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IXL", intShort); + DISPATCH_TABLE_DD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IXL", intShort); + DISPATCH_TABLE_DD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_N", intShort); DISPATCH_TABLE_DD[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_REF_IX_N", intShort); DISPATCH_TABLE_DD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IX_N", intShort); DISPATCH_TABLE_DD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_N", intShort); @@ -709,15 +709,15 @@ public class DispatchTables { DISPATCH_TABLE_FD[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IY_NN", intShort); DISPATCH_TABLE_FD[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_IY", intShort); DISPATCH_TABLE_FD[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IY", intShort); - DISPATCH_TABLE_FD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: inc iyh - DISPATCH_TABLE_FD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: dec iyh - DISPATCH_TABLE_FD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,* + DISPATCH_TABLE_FD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IYH", intShort); + DISPATCH_TABLE_FD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IYH", intShort); + DISPATCH_TABLE_FD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_N", intShort); DISPATCH_TABLE_FD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", intShort); DISPATCH_TABLE_FD[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IY_REF_NN", intShort); DISPATCH_TABLE_FD[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IY", intShort); - DISPATCH_TABLE_FD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: inc iyl - DISPATCH_TABLE_FD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: dec iyl - DISPATCH_TABLE_FD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,* + DISPATCH_TABLE_FD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IYL", intShort); + DISPATCH_TABLE_FD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IYL", intShort); + DISPATCH_TABLE_FD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_N", intShort); DISPATCH_TABLE_FD[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_REF_IY_N", intShort); DISPATCH_TABLE_FD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IY_N", intShort); DISPATCH_TABLE_FD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_N", intShort); diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 638831e21..88460cd28 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -2353,14 +2353,95 @@ int I_SET_N_REF_II_N_R(short OP, byte operand, int special) { return 23; } - //inc ixh -// int I_INC_IIH(short OP, short special) { -// int reg = (OP >>> 3) & 0x07; -// int value = (getreg(reg) + 1) & 0xFF; -// flags = EmulatorTables.INC_TABLE[value] | (flags & FLAG_C); -// putreg(reg, value); -// return (reg == 6) ? 11 : 4; -// } + int I_INC_IXH(short OP) { + IX = ((I_INC_IIH(IX) << 8) | (IX & 0xFF)) & 0xFFFF; + return 8; + } + int I_INC_IYH(short OP) { + IY = ((I_INC_IIH(IY) << 8) | (IY & 0xFF)) & 0xFFFF; + return 8; + } + + int I_INC_IIH(int special) { + int reg = special >>> 8; + int value = (reg + 1) & 0xFF; + flags = EmulatorTables.INC_TABLE[value] | (flags & FLAG_C); + return value; + } + + int I_INC_IXL(short OP) { + IX = ((IX & 0xFF00) | (I_INC_IIL(IX) & 0xFF)) & 0xFFFF; + return 8; + } + + int I_INC_IYL(short OP) { + IY = ((IY & 0xFF00) | (I_INC_IIL(IY) & 0xFF)) & 0xFFFF; + return 8; + } + + int I_INC_IIL(int special) { + int reg = special & 0xFF; + int value = (reg + 1) & 0xFF; + flags = EmulatorTables.INC_TABLE[value] | (flags & FLAG_C); + return value; + } + + int I_DEC_IXH(short OP) { + IX = ((I_DEC_IIH(IX) << 8) | (IX & 0xFF)) & 0xFFFF; + return 8; + } + + int I_DEC_IYH(short OP) { + IY = ((I_DEC_IIH(IY) << 8) | (IY & 0xFF)) & 0xFFFF; + return 8; + } + + int I_DEC_IIH(int special) { + int reg = special >>> 8; + int value = (reg - 1) & 0xFF; + flags = EmulatorTables.DEC_TABLE[value] | (flags & FLAG_C); + return value; + } + int I_DEC_IXL(short OP) { + IX = ((IX & 0xFF00) | (I_DEC_IIL(IX) & 0xFF)) & 0xFFFF; + return 8; + } + + int I_DEC_IYL(short OP) { + IY = ((IY & 0xFF00) | (I_DEC_IIL(IY) & 0xFF)) & 0xFFFF; + return 8; + } + + int I_DEC_IIL(int special) { + int reg = special & 0xFF; + int value = (reg - 1) & 0xFF; + flags = EmulatorTables.DEC_TABLE[value] | (flags & FLAG_C); + return value; + } + + int I_LD_IXH_N(short OP) { + IX = ((readByte(PC) << 8) | (IX & 0xFF)) & 0xFFFF; + PC = (PC + 1) & 0xFFFF; + return 11; + } + + int I_LD_IYH_N(short OP) { + IY = ((readByte(PC) << 8) | (IY & 0xFF)) & 0xFFFF; + PC = (PC + 1) & 0xFFFF; + return 11; + } + + int I_LD_IXL_N(short OP) { + IX = ((IX & 0xFF00) | (readByte(PC) & 0xFF)) & 0xFFFF; + PC = (PC + 1) & 0xFFFF; + return 11; + } + + int I_LD_IYL_N(short OP) { + IY = ((IY & 0xFF00) | (readByte(PC) & 0xFF)) & 0xFFFF; + PC = (PC + 1) & 0xFFFF; + return 11; + } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java index 828ce1640..dd03ed0cd 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java @@ -444,6 +444,47 @@ public void testSBC_HL_RP() { ); } + @Test + public void testINC_IXH() { + + } + + @Test + public void testINC_IYH() { + + } + + @Test + public void testDEC_IXH() { + + } + + @Test + public void testDEC_IYH() { + + } + + @Test + public void testINC_IXL() { + + } + + @Test + public void testINC_IYL() { + + } + + @Test + public void testDEC_IXL() { + + } + + @Test + public void testDEC_IYL() { + + } + + private ByteTestBuilder additionTestBuilder() { return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java index 4134f4a27..6673a62cb 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java @@ -565,6 +565,26 @@ public void testLDDR() { ); } + @Test + public void testLD_IXH_N() { + + } + + @Test + public void testLD_IYH_N() { + + } + + @Test + public void testLD_IXL_N() { + + } + + @Test + public void testLD_IYL_N() { + + } + private void runLD_R_R_test(int register, int... opcodes) { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(register) From d3b343e864a24cc0d527bd7dcea20b4283ea8b6b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 1 Feb 2022 12:35:31 +0100 Subject: [PATCH 086/314] [#201] z80: Implement rest of instructions --- .../plugins/cpu/zilogZ80/DispatchTables.java | 160 +++++----- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 287 ++++++++++++++++- .../plugins/cpu/zilogZ80/ArithmeticTest.java | 296 ++++++++++++++++++ .../plugins/cpu/zilogZ80/LogicTest.java | 82 +++++ .../plugins/cpu/zilogZ80/TransferTest.java | 226 ++++++++++++- .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 58 +++- 6 files changed, 991 insertions(+), 118 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java index 7f480fa88..bf4e89632 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java @@ -635,34 +635,34 @@ public class DispatchTables { DISPATCH_TABLE_DD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IX_N", intShort); DISPATCH_TABLE_DD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_N", intShort); DISPATCH_TABLE_DD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", intShort); - DISPATCH_TABLE_DD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld b,ixh - DISPATCH_TABLE_DD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld b,ixl + DISPATCH_TABLE_DD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", intShort); + DISPATCH_TABLE_DD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", intShort); DISPATCH_TABLE_DD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld c,ixh - DISPATCH_TABLE_DD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld c,ixl + DISPATCH_TABLE_DD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", intShort); + DISPATCH_TABLE_DD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", intShort); DISPATCH_TABLE_DD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld d,ixh - DISPATCH_TABLE_DD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld d,ixl + DISPATCH_TABLE_DD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", intShort); + DISPATCH_TABLE_DD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", intShort); DISPATCH_TABLE_DD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld e,ixh - DISPATCH_TABLE_DD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld e,ixl + DISPATCH_TABLE_DD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", intShort); + DISPATCH_TABLE_DD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", intShort); DISPATCH_TABLE_DD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,b - DISPATCH_TABLE_DD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,c - DISPATCH_TABLE_DD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,d - DISPATCH_TABLE_DD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,e - DISPATCH_TABLE_DD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,ixh - DISPATCH_TABLE_DD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,ixl + DISPATCH_TABLE_DD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", intShort); + DISPATCH_TABLE_DD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", intShort); + DISPATCH_TABLE_DD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", intShort); + DISPATCH_TABLE_DD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", intShort); + DISPATCH_TABLE_DD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIH_IIH", intShort); + DISPATCH_TABLE_DD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_IXL", intShort); DISPATCH_TABLE_DD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixh,a - DISPATCH_TABLE_DD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,b - DISPATCH_TABLE_DD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,c - DISPATCH_TABLE_DD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,d - DISPATCH_TABLE_DD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,e - DISPATCH_TABLE_DD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,ixh - DISPATCH_TABLE_DD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,ixl + DISPATCH_TABLE_DD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", intShort); + DISPATCH_TABLE_DD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", intShort); + DISPATCH_TABLE_DD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", intShort); + DISPATCH_TABLE_DD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", intShort); + DISPATCH_TABLE_DD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", intShort); + DISPATCH_TABLE_DD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_IXH", intShort); + DISPATCH_TABLE_DD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIL_IIL", intShort); DISPATCH_TABLE_DD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld ixl,a + DISPATCH_TABLE_DD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", intShort); DISPATCH_TABLE_DD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); DISPATCH_TABLE_DD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); DISPATCH_TABLE_DD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); @@ -670,32 +670,32 @@ public class DispatchTables { DISPATCH_TABLE_DD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); DISPATCH_TABLE_DD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); DISPATCH_TABLE_DD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); - DISPATCH_TABLE_DD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld a,ixh - DISPATCH_TABLE_DD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld a,ixl + DISPATCH_TABLE_DD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", intShort); + DISPATCH_TABLE_DD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", intShort); DISPATCH_TABLE_DD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: add a,ixh - DISPATCH_TABLE_DD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: add a,ixl + DISPATCH_TABLE_DD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IXH", intShort); + DISPATCH_TABLE_DD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IXL", intShort); DISPATCH_TABLE_DD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: adc a,ixh - DISPATCH_TABLE_DD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: adc a,ixl + DISPATCH_TABLE_DD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IXH", intShort); + DISPATCH_TABLE_DD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IXL", intShort); DISPATCH_TABLE_DD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sub ixh - DISPATCH_TABLE_DD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sub ixl + DISPATCH_TABLE_DD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IXH", intShort); + DISPATCH_TABLE_DD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IXL", intShort); DISPATCH_TABLE_DD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sbc a,ixh - DISPATCH_TABLE_DD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sbc a,ixl + DISPATCH_TABLE_DD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IXH", intShort); + DISPATCH_TABLE_DD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IXL", intShort); DISPATCH_TABLE_DD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: and ixh - DISPATCH_TABLE_DD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: and ixl + DISPATCH_TABLE_DD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IXH", intShort); + DISPATCH_TABLE_DD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IXL", intShort); DISPATCH_TABLE_DD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: xor ixh - DISPATCH_TABLE_DD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: xor ixl + DISPATCH_TABLE_DD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IXH", intShort); + DISPATCH_TABLE_DD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IXL", intShort); DISPATCH_TABLE_DD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: or ixh - DISPATCH_TABLE_DD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: or ixl + DISPATCH_TABLE_DD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IXH", intShort); + DISPATCH_TABLE_DD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IXL", intShort); DISPATCH_TABLE_DD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: cp ixh - DISPATCH_TABLE_DD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: cp ixl + DISPATCH_TABLE_DD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IXH", intShort); + DISPATCH_TABLE_DD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IXL", intShort); DISPATCH_TABLE_DD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IX_N", intShort); DISPATCH_TABLE_DD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "DD_CB_DISPATCH", intShort); DISPATCH_TABLE_DD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IX", intShort); @@ -722,34 +722,34 @@ public class DispatchTables { DISPATCH_TABLE_FD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IY_N", intShort); DISPATCH_TABLE_FD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_N", intShort); DISPATCH_TABLE_FD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", intShort); - DISPATCH_TABLE_FD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld b,iyh - DISPATCH_TABLE_FD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld b,iyl + DISPATCH_TABLE_FD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", intShort); + DISPATCH_TABLE_FD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", intShort); DISPATCH_TABLE_FD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld c,iyh - DISPATCH_TABLE_FD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld c,iyl + DISPATCH_TABLE_FD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", intShort); + DISPATCH_TABLE_FD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", intShort); DISPATCH_TABLE_FD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld d,iyh - DISPATCH_TABLE_FD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld d,iyl + DISPATCH_TABLE_FD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", intShort); + DISPATCH_TABLE_FD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", intShort); DISPATCH_TABLE_FD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld e,iyh - DISPATCH_TABLE_FD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld e,iyl + DISPATCH_TABLE_FD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", intShort); + DISPATCH_TABLE_FD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", intShort); DISPATCH_TABLE_FD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,b - DISPATCH_TABLE_FD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,c - DISPATCH_TABLE_FD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,d - DISPATCH_TABLE_FD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,e - DISPATCH_TABLE_FD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,iyh - DISPATCH_TABLE_FD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,iyl + DISPATCH_TABLE_FD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", intShort); + DISPATCH_TABLE_FD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", intShort); + DISPATCH_TABLE_FD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", intShort); + DISPATCH_TABLE_FD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", intShort); + DISPATCH_TABLE_FD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIH_IIH", intShort); + DISPATCH_TABLE_FD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_IYL", intShort); DISPATCH_TABLE_FD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyh,a - DISPATCH_TABLE_FD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,b - DISPATCH_TABLE_FD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,c - DISPATCH_TABLE_FD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,d - DISPATCH_TABLE_FD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,e - DISPATCH_TABLE_FD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,iyh - DISPATCH_TABLE_FD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,iyl + DISPATCH_TABLE_FD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", intShort); + DISPATCH_TABLE_FD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", intShort); + DISPATCH_TABLE_FD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", intShort); + DISPATCH_TABLE_FD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", intShort); + DISPATCH_TABLE_FD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", intShort); + DISPATCH_TABLE_FD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_IYH", intShort); + DISPATCH_TABLE_FD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIL_IIL", intShort); DISPATCH_TABLE_FD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld iyl,a + DISPATCH_TABLE_FD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", intShort); DISPATCH_TABLE_FD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); DISPATCH_TABLE_FD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); DISPATCH_TABLE_FD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); @@ -757,32 +757,32 @@ public class DispatchTables { DISPATCH_TABLE_FD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); DISPATCH_TABLE_FD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); DISPATCH_TABLE_FD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); - DISPATCH_TABLE_FD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld a,iyh - DISPATCH_TABLE_FD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: ld a,iyl + DISPATCH_TABLE_FD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", intShort); + DISPATCH_TABLE_FD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", intShort); DISPATCH_TABLE_FD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: add a,iyh - DISPATCH_TABLE_FD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: add a,iyl + DISPATCH_TABLE_FD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IYH", intShort); + DISPATCH_TABLE_FD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IYL", intShort); DISPATCH_TABLE_FD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: adc a,iyh - DISPATCH_TABLE_FD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: adc a,iyl + DISPATCH_TABLE_FD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IYH", intShort); + DISPATCH_TABLE_FD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IYL", intShort); DISPATCH_TABLE_FD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sub iyh - DISPATCH_TABLE_FD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sub iyl + DISPATCH_TABLE_FD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IYH", intShort); + DISPATCH_TABLE_FD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IYL", intShort); DISPATCH_TABLE_FD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sbc a,iyh - DISPATCH_TABLE_FD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: sbc a,iyl + DISPATCH_TABLE_FD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IYH", intShort); + DISPATCH_TABLE_FD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IYL", intShort); DISPATCH_TABLE_FD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: and iyh - DISPATCH_TABLE_FD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: and iyl + DISPATCH_TABLE_FD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IYH", intShort); + DISPATCH_TABLE_FD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IYL", intShort); DISPATCH_TABLE_FD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: xor iyh - DISPATCH_TABLE_FD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: xor iyl + DISPATCH_TABLE_FD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IYH", intShort); + DISPATCH_TABLE_FD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IYL", intShort); DISPATCH_TABLE_FD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: or iyh - DISPATCH_TABLE_FD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: or iyl + DISPATCH_TABLE_FD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IYH", intShort); + DISPATCH_TABLE_FD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IYL", intShort); DISPATCH_TABLE_FD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: cp iyh - DISPATCH_TABLE_FD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); // TODO: cp iyl + DISPATCH_TABLE_FD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IYH", intShort); + DISPATCH_TABLE_FD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IYL", intShort); DISPATCH_TABLE_FD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IY_N", intShort); DISPATCH_TABLE_FD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "FD_CB_DISPATCH", intShort); DISPATCH_TABLE_FD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IY", intShort); diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 88460cd28..d26c5209a 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -2354,37 +2354,29 @@ int I_SET_N_REF_II_N_R(short OP, byte operand, int special) { } int I_INC_IXH(short OP) { - IX = ((I_INC_IIH(IX) << 8) | (IX & 0xFF)) & 0xFFFF; + IX = ((I_INC(IX >>> 8) << 8) | (IX & 0xFF)) & 0xFFFF; return 8; } int I_INC_IYH(short OP) { - IY = ((I_INC_IIH(IY) << 8) | (IY & 0xFF)) & 0xFFFF; + IY = ((I_INC(IY >>> 8) << 8) | (IY & 0xFF)) & 0xFFFF; return 8; } - int I_INC_IIH(int special) { - int reg = special >>> 8; - int value = (reg + 1) & 0xFF; - flags = EmulatorTables.INC_TABLE[value] | (flags & FLAG_C); - return value; - } - int I_INC_IXL(short OP) { - IX = ((IX & 0xFF00) | (I_INC_IIL(IX) & 0xFF)) & 0xFFFF; + IX = ((IX & 0xFF00) | I_INC(IX & 0xFF)) & 0xFFFF; return 8; } int I_INC_IYL(short OP) { - IY = ((IY & 0xFF00) | (I_INC_IIL(IY) & 0xFF)) & 0xFFFF; + IY = ((IY & 0xFF00) | I_INC(IY & 0xFF)) & 0xFFFF; return 8; } - int I_INC_IIL(int special) { - int reg = special & 0xFF; - int value = (reg + 1) & 0xFF; - flags = EmulatorTables.INC_TABLE[value] | (flags & FLAG_C); - return value; + int I_INC(int value) { + int valueInc = (value + 1) & 0xFF; + flags = EmulatorTables.INC_TABLE[valueInc] | (flags & FLAG_C); + return valueInc; } int I_DEC_IXH(short OP) { @@ -2444,4 +2436,267 @@ int I_LD_IYL_N(short OP) { PC = (PC + 1) & 0xFFFF; return 11; } + + int I_LD_R_IXH(short OP) { + return I_LD_R_IIH(OP, IX); + } + + int I_LD_R_IYH(short OP) { + return I_LD_R_IIH(OP, IY); + } + + int I_LD_R_IIH(short OP, int special) { + int reg = ((OP >>> 2) & 0x0F) / 2; // 4,5,6 not supported + regs[reg] = special >>> 8; + return 8; + } + + int I_LD_R_IXL(short OP) { + return I_LD_R_IIL(OP, IX); + } + + int I_LD_R_IYL(short OP) { + return I_LD_R_IIL(OP, IY); + } + + int I_LD_R_IIL(short OP, int special) { + int reg = ((OP >>> 2) & 0x0F) / 2; // 4,5,6 not supported + regs[reg] = special & 0xFF; + return 8; + } + + int I_LD_IXH_R(short OP) { + int reg = OP & 7; // 4,5,6 not supported + IX = (IX & 0xFF) | ((regs[reg] << 8) & 0xFF00); + return 8; + } + + int I_LD_IYH_R(short OP) { + int reg = OP & 7; // 4,5,6 not supported + IY = (IY & 0xFF) | ((regs[reg] << 8) & 0xFF00); + return 8; + } + + int I_LD_IIH_IIH(short OP) { + return 8; + } + + int I_LD_IXH_IXL(short OP) { + IX = (IX & 0xFF) | ((IX << 8) & 0xFF00); + return 8; + } + + int I_LD_IYH_IYL(short OP) { + IY = (IY & 0xFF) | ((IY << 8) & 0xFF00); + return 8; + } + + int I_LD_IXL_R(short OP) { + int reg = OP & 7; // 4,5,6 not supported + IX = (IX & 0xFF00) | (regs[reg] & 0xFF); + return 8; + } + + int I_LD_IYL_R(short OP) { + int reg = OP & 7; // 4,5,6 not supported + IY = (IY & 0xFF00) | (regs[reg] & 0xFF); + return 8; + } + + int I_LD_IXL_IXH(short OP) { + IX = (IX & 0xFF00) | (IX >>> 8); + return 8; + } + + int I_LD_IYL_IYH(short OP) { + IY = (IY & 0xFF00) | (IY >>> 8); + return 8; + } + + int I_LD_IIL_IIL(short OP) { + return 8; + } + + int I_ADD_A_IXH(short OP) { + return I_ADD_A(IX >>> 8); + } + + int I_ADD_A_IYH(short OP) { + return I_ADD_A(IY >>> 8); + } + + int I_ADD_A_IXL(short OP) { + return I_ADD_A(IX & 0xFF); + } + + int I_ADD_A_IYL(short OP) { + return I_ADD_A(IY & 0xFF); + } + + int I_ADD_A(int value) { + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value) & 0xFF; + flags = flagSZHPC(oldA, value, regs[REG_A]); + return 8; + } + + int I_ADC_A_IXH(short OP) { + return I_ADC_A(IX >>> 8); + } + + int I_ADC_A_IYH(short OP) { + return I_ADC_A(IY >>> 8); + } + + int I_ADC_A_IXL(short OP) { + return I_ADC_A(IX & 0xFF); + } + + int I_ADC_A_IYL(short OP) { + return I_ADC_A(IY & 0xFF); + } + + int I_ADC_A(int value) { + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; + flags = flagSZHPC(oldA, (value + (flags & FLAG_C)) & 0xFF, regs[REG_A]); + return 8; + } + + int I_SUB_IXH(short OP) { + return I_SUB(IX >>> 8); + } + + int I_SUB_IYH(short OP) { + return I_SUB(IY >>> 8); + } + + int I_SUB_IXL(short OP) { + return I_SUB(IX & 0xFF); + } + + int I_SUB_IYL(short OP) { + return I_SUB(IY & 0xFF); + } + + int I_SUB(int value) { + int valueNeg = ((~value) + 1) & 0xFF; + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + valueNeg) & 0xFF; + flags = flagSZHPC(oldA, valueNeg, regs[REG_A]) | FLAG_N; + return 8; + } + + int I_SBC_A_IXH(short OP) { + return I_SBC_A(IX >>> 8); + } + + int I_SBC_A_IYH(short OP) { + return I_SBC_A(IY >>> 8); + } + + int I_SBC_A_IXL(short OP) { + return I_SBC_A(IX & 0xFF); + } + + int I_SBC_A_IYL(short OP) { + return I_SBC_A(IY & 0xFF); + } + + int I_SBC_A(int value) { + int valueNeg = ((~value) + 1) & 0xFF; + int oldA = regs[REG_A]; + regs[REG_A] = (oldA + valueNeg - (flags & FLAG_C)) & 0xFF; + flags = flagSZHPC(oldA, (valueNeg - (flags & FLAG_C)) & 0xFF, regs[REG_A]) | FLAG_N; + return 8; + } + + int I_AND_IXH(short OP) { + return I_AND(IX >>> 8); + } + + int I_AND_IYH(short OP) { + return I_AND(IY >>> 8); + } + + int I_AND_IXL(short OP) { + return I_AND(IX & 0xFF); + } + + int I_AND_IYL(short OP) { + return I_AND(IY & 0xFF); + } + + int I_AND(int value) { + regs[REG_A] = (regs[REG_A] & value) & 0xFF; + flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + return 8; + } + + int I_XOR_IXH(short OP) { + return I_XOR(IX >>> 8); + } + + int I_XOR_IYH(short OP) { + return I_XOR(IY >>> 8); + } + + int I_XOR_IXL(short OP) { + return I_XOR(IX & 0xFF); + } + + int I_XOR_IYL(short OP) { + return I_XOR(IY & 0xFF); + } + + int I_XOR(int value) { + regs[REG_A] = ((regs[REG_A] ^ value) & 0xFF); + flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + return 8; + } + + int I_OR_IXH(short OP) { + return I_OR(IX >>> 8); + } + + int I_OR_IXL(short OP) { + return I_OR(IX & 0xFF); + } + + int I_OR_IYH(short OP) { + return I_OR(IY >>> 8); + } + + int I_OR_IYL(short OP) { + return I_OR(IY & 0xFF); + } + + int I_OR(int value) { + regs[REG_A] = (regs[REG_A] | value) & 0xFF; + flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + return 8; + } + + int I_CP_IXH(short OP) { + return I_CP(IX >>> 8); + } + + int I_CP_IXL(short OP) { + return I_CP(IX & 0xFF); + } + + int I_CP_IYH(short OP) { + return I_CP(IY >>> 8); + } + + int I_CP_IYL(short OP) { + return I_CP(IY & 0xFF); + } + + int I_CP(int value) { + int valueNeg = ((~value) + 1) & 0xFF; + int result = (regs[REG_A] + valueNeg) & 0xFF; + flags = flagSZHPC(regs[REG_A], valueNeg, result) | FLAG_N; + return 8; + } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java index dd03ed0cd..c296f3a4a 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java @@ -446,42 +446,338 @@ public void testSBC_HL_RP() { @Test public void testINC_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIX() + .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8MSB().halfCarryOfFirst8MSB().subtractionIsReset(), + context -> ((context.first >>> 8) + 1) & 0xFF) + .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); + Generator.forSome16bitUnary( + test.run(0xDD, 0x24) + ); } @Test public void testINC_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIY() + .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8MSB().halfCarryOfFirst8MSB().subtractionIsReset(), + context -> ((context.first >>> 8) + 1) & 0xFF) + .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); + Generator.forSome16bitUnary( + test.run(0xFD, 0x24) + ); } @Test public void testDEC_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIX() + .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8MSB().halfCarryOfFirst8MSB().subtractionIsSet(), + context -> ((context.first >>> 8) - 1) & 0xFF) + .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); + Generator.forSome16bitUnary( + test.run(0xDD, 0x25) + ); } @Test public void testDEC_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIY() + .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8MSB().halfCarryOfFirst8MSB().subtractionIsSet(), + context -> ((context.first >>> 8) - 1) & 0xFF) + .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); + Generator.forSome16bitUnary( + test.run(0xFD, 0x25) + ); } @Test public void testINC_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIX() + .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8LSB().halfCarryOfFirst8LSB().subtractionIsReset(), + context -> ((context.first & 0xFF) + 1) & 0xFF) + .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) + 1) & 0xFF)); + Generator.forSome16bitUnary( + test.run(0xDD, 0x2C) + ); } @Test public void testINC_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIY() + .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8LSB().halfCarryOfFirst8LSB().subtractionIsReset(), + context -> ((context.first & 0xFF) + 1) & 0xFF) + .verifyIY(context -> (context.first & 0xFF00) | (((context.first & 0xFF) + 1) & 0xFF)); + Generator.forSome16bitUnary( + test.run(0xFD, 0x2C) + ); } @Test public void testDEC_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIX() + .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8LSB().halfCarryOfFirst8LSB().subtractionIsSet(), + context -> ((context.first & 0xFF) - 1) & 0xFF) + .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); + Generator.forSome16bitUnary( + test.run(0xDD, 0x2D) + ); } @Test public void testDEC_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIY() + .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8LSB().halfCarryOfFirst8LSB().subtractionIsSet(), + context -> ((context.first & 0xFF) - 1) & 0xFF) + .verifyIY(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); + + Generator.forSome16bitUnary( + test.run(0xFD, 0x2D) + ); + } + + @Test + public void testADD_A_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + + Generator.forSome16bitBinary( + test.run(0xDD, 0x84) + ); + } + + @Test + public void testADD_A_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + + Generator.forSome16bitBinary( + test.run(0xFD, 0x84) + ); + } + + @Test + public void testADD_A_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + + Generator.forSome16bitBinary( + test.run(0xDD, 0x85) + ); + } + + @Test + public void testADD_A_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + + Generator.forSome16bitBinary( + test.run(0xFD, 0x85) + ); + } + + @Test + public void testADC_A_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + + Generator.forSome16bitBinary( + test.run(0xDD, 0x8C) + ); + } + + @Test + public void testADC_A_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + + Generator.forSome16bitBinary( + test.run(0xFD, 0x8C) + ); + } + + @Test + public void testADC_A_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + + Generator.forSome16bitBinary( + test.run(0xDD, 0x8D) + ); + } + + @Test + public void testADC_A_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + + Generator.forSome16bitBinary( + test.run(0xFD, 0x8D) + ); + } + + @Test + public void testSUB_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero() + .borrow(context -> context.second >>> 8) + .halfBorrow(context -> context.second >>> 8) + .overflow().subtractionIsSet()); + Generator.forSome16bitBinary( + test.run(0xDD, 0x94) + ); + } + + @Test + public void testSUB_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero() + .borrow(context -> context.second >>> 8) + .halfBorrow(context -> context.second >>> 8) + .overflow().subtractionIsSet()); + + Generator.forSome16bitBinary( + test.run(0xFD, 0x94) + ); + } + + @Test + public void testSUB_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero() + .borrow() + .halfBorrow() + .overflow().subtractionIsSet()); + + Generator.forSome16bitBinary( + test.run(0xDD, 0x95) + ); + } + + @Test + public void testSUB_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero() + .borrow() + .halfBorrow() + .overflow().subtractionIsSet()); + + Generator.forSome16bitBinary( + test.run(0xFD, 0x95) + ); + } + + @Test + public void testSBC_A_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero() + .borrowWithCarry(context -> context.second >>> 8) + .halfBorrowWithCarry(context -> context.second >>> 8) + .overflow().subtractionIsSet()); + + Generator.forSome16bitBinary( + test.run(0xDD, 0x9C) + ); + } + + @Test + public void testSBC_A_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero() + .borrowWithCarry(context -> context.second >>> 8) + .halfBorrowWithCarry(context -> context.second >>> 8) + .overflow().subtractionIsSet()); + + Generator.forSome16bitBinary( + test.run(0xFD, 0x9C) + ); + } + + @Test + public void testSBC_A_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrowWithCarry().overflow().subtractionIsSet()); + + Generator.forSome16bitBinary( + test.run(0xDD, 0x9D) + ); + } + + @Test + public void testSBC_A_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrowWithCarry().overflow().subtractionIsSet()); + + Generator.forSome16bitBinary( + test.run(0xFD, 0x9D) + ); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java index 1e26333cf..31a587d61 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java @@ -744,6 +744,88 @@ public void testRRD() { ); } + @Test + public void testAND_IXH() { + + } + + @Test + public void testAND_IXL() { + + } + + @Test + public void testAND_IYH() { + + } + + @Test + public void testAND_IYL() { + + } + + @Test + public void testXOR_IXH() { + + } + + @Test + public void testXOR_IXL() { + + } + + @Test + public void testXOR_IYH() { + + } + + @Test + public void testXOR_IYL() { + + } + + @Test + public void testOR_IXH() { + + } + + @Test + public void testOR_IXL() { + + } + + @Test + public void testOR_IYH() { + + } + + @Test + public void testOR_IYL() { + + } + + @Test + public void testCP_IXH() { + + } + + @Test + public void testCP_IYH() { + + } + + @Test + public void testCP_IXL() { + + } + + @Test + public void testCP_IYL() { + + } + + + private IntegerTestBuilder prepareCPxTest(Function, Integer> hlOperation) { return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java index 6673a62cb..3719c881b 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java @@ -97,18 +97,18 @@ public void testLD_REF_HL_HL() { } @Test - public void testLD_R_II_N() { - runLD_R_II_N(REG_A, 0x7E); - runLD_R_II_N(REG_B, 0x46); - runLD_R_II_N(REG_C, 0x4E); - runLD_R_II_N(REG_D, 0x56); - runLD_R_II_N(REG_E, 0x5E); - runLD_R_II_N(REG_H, 0x66); - runLD_R_II_N(REG_L, 0x6E); + public void testLD_R_REF_II_N() { + runLD_R_REF_II_N(REG_A, 0x7E); + runLD_R_REF_II_N(REG_B, 0x46); + runLD_R_REF_II_N(REG_C, 0x4E); + runLD_R_REF_II_N(REG_D, 0x56); + runLD_R_REF_II_N(REG_E, 0x5E); + runLD_R_REF_II_N(REG_H, 0x66); + runLD_R_REF_II_N(REG_L, 0x6E); } @Test - public void testLD_IX_N_R() { + public void testLD_REF_IX_N_R() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8MSBisIX() @@ -127,7 +127,7 @@ public void testLD_IX_N_R() { } @Test - public void testLD_IY_N_R() { + public void testLD_REF_IY_N_R() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8MSBisIY() @@ -146,7 +146,7 @@ public void testLD_IY_N_R() { } @Test - public void testLD_II_N_N() { + public void testLD_REF_II_N_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .verifyByte(context -> Utils.get8MSBplus8LSB(context.first), context -> context.first & 0xFF) @@ -159,7 +159,7 @@ public void testLD_II_N_N() { } @Test - public void testLD_A_RP() { + public void testLD_A_REF_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .verifyRegister(REG_A, context -> context.second & 0xFF) @@ -172,7 +172,7 @@ public void testLD_A_RP() { } @Test - public void testLD_A_NN() { + public void testLD_A_REF_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .verifyRegister(REG_A, context -> context.second & 0xFF); @@ -197,7 +197,7 @@ public void testLD_REF_RP_A() { } @Test - public void testLD_NN_A() { + public void testLD_REF_NN_A() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) @@ -567,22 +567,218 @@ public void testLDDR() { @Test public void testLD_IXH_N() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .secondIsIX() + .verifyIX(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); + Generator.forSome16bitBinary( + test.runWithFirst8bitOperand(0xDD, 0x26) + ); } @Test public void testLD_IYH_N() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .secondIsIY() + .verifyIY(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); + Generator.forSome16bitBinary( + test.runWithFirst8bitOperand(0xFD, 0x26) + ); } @Test public void testLD_IXL_N() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .secondIsIX() + .verifyIX(context -> (context.second & 0xFF00) | (context.first & 0xFF)); + Generator.forSome16bitBinary( + test.runWithFirst8bitOperand(0xDD, 0x2E) + ); } @Test public void testLD_IYL_N() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .secondIsIY() + .verifyIY(context -> (context.second & 0xFF00) | (context.first & 0xFF)); + + Generator.forSome16bitBinary( + test.runWithFirst8bitOperand(0xFD, 0x2E) + ); + } + + @Test + public void testLD_R_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); + int[][] regOpcodes = { {REG_B, 0x44}, {REG_C, 0x4C}, {REG_D, 0x54}, {REG_E, 0x5C}, {REG_A, 0x7C} }; + + for (int[] regOpcode : regOpcodes) { + test.secondIsIX() + .first8LSBisRegister(regOpcode[0]) + .verifyRegister(regOpcode[0], context -> (context.second >>> 8) & 0xFF); + + Generator.forSome16bitBinary( + test.run(0xDD, regOpcode[1]) + ); + } + } + + @Test + public void testLD_R_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); + int[][] regOpcodes = { {REG_B, 0x45}, {REG_C, 0x4D}, {REG_D, 0x55}, {REG_E, 0x5D}, {REG_A, 0x7D} }; + + for (int[] regOpcode : regOpcodes) { + test.secondIsIX() + .first8LSBisRegister(regOpcode[0]) + .verifyRegister(regOpcode[0], context -> context.second & 0xFF); + + Generator.forSome16bitBinary( + test.run(0xDD, regOpcode[1]) + ); + } + } + + @Test + public void testLD_R_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); + int[][] regOpcodes = { {REG_B, 0x44}, {REG_C, 0x4C}, {REG_D, 0x54}, {REG_E, 0x5C}, {REG_A, 0x7C} }; + + for (int[] regOpcode : regOpcodes) { + test.secondIsIY() + .first8LSBisRegister(regOpcode[0]) + .verifyRegister(regOpcode[0], context -> (context.second >>> 8) & 0xFF); + + Generator.forSome16bitBinary( + test.run(0xFD, regOpcode[1]) + ); + } + } + + @Test + public void testLD_R_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); + int[][] regOpcodes = { {REG_B, 0x45}, {REG_C, 0x4D}, {REG_D, 0x55}, {REG_E, 0x5D}, {REG_A, 0x7D} }; + + for (int[] regOpcode : regOpcodes) { + test.secondIsIY() + .first8LSBisRegister(regOpcode[0]) + .verifyRegister(regOpcode[0], context -> context.second & 0xFF); + + Generator.forSome16bitBinary( + test.run(0xFD, regOpcode[1]) + ); + } + } + + @Test + public void testLD_IXH_R() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); + int[][] regOpcodes = { {REG_B, 0x60}, {REG_C, 0x61}, {REG_D, 0x62}, {REG_E, 0x63}, {REG_A, 0x67} }; + + for (int[] regOpcode : regOpcodes) { + test.secondIsIX() + .first8LSBisRegister(regOpcode[0]) + .verifyIX(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); + + Generator.forSome16bitBinary( + test.run(0xDD, regOpcode[1]) + ); + } + } + @Test + public void testLD_IYH_R() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); + int[][] regOpcodes = { {REG_B, 0x60}, {REG_C, 0x61}, {REG_D, 0x62}, {REG_E, 0x63}, {REG_A, 0x67} }; + + for (int[] regOpcode : regOpcodes) { + test.secondIsIY() + .first8LSBisRegister(regOpcode[0]) + .verifyIY(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); + + Generator.forSome16bitBinary( + test.run(0xFD, regOpcode[1]) + ); + } + } + + @Test + public void testLD_IXH_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIX() + .verifyIX(context -> ((context.first << 8) & 0xFF00) | (context.first & 0xFF)); + + Generator.forSome16bitBinary( + test.run(0xDD, 0x65) + ); + } + + @Test + public void testLD_IYH_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIY() + .verifyIY(context -> ((context.first << 8) & 0xFF00) | (context.first & 0xFF)); + + Generator.forSome16bitBinary( + test.run(0xFD, 0x65) + ); + } + + @Test + public void testLD_IXL_R() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); + int[][] regOpcodes = { {REG_B, 0x68}, {REG_C, 0x69}, {REG_D, 0x6A}, {REG_E, 0x6B}, {REG_A, 0x6F} }; + + for (int[] regOpcode : regOpcodes) { + test.secondIsIX() + .first8LSBisRegister(regOpcode[0]) + .verifyIX(context -> (context.second & 0xFF00) | (context.first & 0xFF)); + + Generator.forSome16bitBinary( + test.run(0xDD, regOpcode[1]) + ); + } + } + + @Test + public void testLD_IYL_R() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); + int[][] regOpcodes = { {REG_B, 0x68}, {REG_C, 0x69}, {REG_D, 0x6A}, {REG_E, 0x6B}, {REG_A, 0x6F} }; + + for (int[] regOpcode : regOpcodes) { + test.secondIsIY() + .first8LSBisRegister(regOpcode[0]) + .verifyIY(context -> (context.second & 0xFF00) | (context.first & 0xFF)); + + Generator.forSome16bitBinary( + test.run(0xFD, regOpcode[1]) + ); + } + } + + @Test + public void testLD_IXL_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIX() + .verifyIX(context -> (context.first >>> 8) | (context.first & 0xFF00)); + + Generator.forSome16bitBinary( + test.run(0xDD, 0x6C) + ); + } + + @Test + public void testLD_IYL_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsIY() + .verifyIY(context -> (context.first >>> 8) | (context.first & 0xFF00)); + + Generator.forSome16bitBinary( + test.run(0xFD, 0x6C) + ); } private void runLD_R_R_test(int register, int... opcodes) { @@ -615,7 +811,7 @@ private void runLD_R_N_test(int register, int opcode) { ); } - private void runLD_R_II_N(int register, int opcode) { + private void runLD_R_REF_II_N(int register, int opcode) { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(register) diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java index 326c0df16..fb6ce208f 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java @@ -19,6 +19,9 @@ package net.emustudio.plugins.cpu.zilogZ80.suite; import net.emustudio.cpu.testsuite.FlagsCheck; +import net.emustudio.cpu.testsuite.RunnerContext; + +import java.util.function.Function; import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.*; @@ -79,9 +82,22 @@ public FlagsCheckImpl subtractionIsSet() { } public FlagsCheckImpl overflow() { + return overflow(context -> context.first.intValue()); + } + + public FlagsCheckImpl overflowOfFirst8MSB() { + return overflow(context -> context.first.intValue() >>> 8); + } + + public FlagsCheckImpl overflowOfFirst8LSB() { + return overflow(context -> context.first.intValue() & 0xFF); + } + + public FlagsCheckImpl overflow(Function, Integer> first) { evaluators.add((context, result) -> { - int sign = context.first.intValue() & 0x80; - int trueSecond = result - context.first.intValue(); + int firstInt = first.apply(context); + int sign = firstInt & 0x80; + int trueSecond = result - firstInt; if (sign != (trueSecond & 0x80)) { expectedNotFlags |= FLAG_PV; @@ -152,9 +168,13 @@ public FlagsCheckImpl carry() { } public FlagsCheckImpl borrow() { + return borrow(context -> context.second.intValue()); + } + + public FlagsCheckImpl borrow(Function, Integer> second) { // doesn't work if sub is using carry=1 (SBC) evaluators.add((context, result) -> { - if ((context.first.intValue() & 0xFF) > (0xFF - (((~context.second.intValue()) + 1) & 0xFF))) { + if ((context.first.intValue() & 0xFF) > (0xFF - (((~second.apply(context)) + 1) & 0xFF))) { expectedFlags |= FLAG_C; } else { expectedNotFlags |= FLAG_C; @@ -164,8 +184,12 @@ public FlagsCheckImpl borrow() { } public FlagsCheckImpl borrowWithCarry() { + return borrowWithCarry(context -> context.second.intValue()); + } + + public FlagsCheckImpl borrowWithCarry(Function, Integer> second) { evaluators.add((context, result) -> { - if ((context.first.intValue() & 0xFF) > (0xFF - (((~context.second.intValue()) + 1 - (context.flags & FLAG_C)) & 0xFF))) { + if ((context.first.intValue() & 0xFF) > (0xFF - (((~second.apply(context)) + 1 - (context.flags & FLAG_C)) & 0xFF))) { expectedFlags |= FLAG_C; } else { expectedNotFlags |= FLAG_C; @@ -213,9 +237,21 @@ public static boolean isAuxCarry(int first, int sumWith) { return (C3 != 0); } + public FlagsCheckImpl halfCarryOfFirst8MSB() { + return halfCarry(context -> context.first.intValue() >>> 8); + } + + public FlagsCheckImpl halfCarryOfFirst8LSB() { + return halfCarry(context -> context.first.intValue() & 0xFF); + } + public FlagsCheckImpl halfCarry() { + return halfCarry(context -> context.first.intValue()); + } + + public FlagsCheckImpl halfCarry(Function, Integer> first) { evaluators.add((context, result) -> { - int firstInt = context.first.intValue(); + int firstInt = first.apply(context); byte diff = (byte) ((result - firstInt) & 0xFF); if (isAuxCarry(firstInt & 0xFF, diff)) { @@ -228,8 +264,12 @@ public FlagsCheckImpl halfCarry() { } public FlagsCheckImpl halfBorrow() { + return halfBorrow(context -> context.second.intValue()); + } + + public FlagsCheckImpl halfBorrow(Function, Integer> second) { evaluators.add((context, result) -> { - int carryIns = result ^ (context.first.intValue() & 0xFF) ^ (((~context.second.intValue()) + 1) & 0xFF); + int carryIns = result ^ (context.first.intValue() & 0xFF) ^ (((~second.apply(context)) + 1) & 0xFF); int halfCarryOut = (carryIns >> 4) & 1; if (halfCarryOut == 1) { @@ -242,8 +282,12 @@ public FlagsCheckImpl halfBorrow() { } public FlagsCheckImpl halfBorrowWithCarry() { + return halfBorrowWithCarry(context -> context.second.intValue()); + } + + public FlagsCheckImpl halfBorrowWithCarry(Function, Integer> second) { evaluators.add((context, result) -> { - int b = (((~context.second.intValue()) + 1 - (context.flags & FLAG_C)) & 0xFF); + int b = (((~second.apply(context)) + 1 - (context.flags & FLAG_C)) & 0xFF); int carryIns = result ^ (context.first.intValue() & 0xFF) ^ b; int halfCarryOut = (carryIns >> 4) & 1; From e4628dff5edc415edf75435ce9cea6f976d55e25 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 2 Feb 2022 08:20:19 +0100 Subject: [PATCH 087/314] [#201] z80: tests --- .../plugins/cpu/zilogZ80/LogicTest.java | 168 ++++++++++++++++-- 1 file changed, 157 insertions(+), 11 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java index 31a587d61..f971beecc 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java @@ -33,15 +33,6 @@ public class LogicTest extends InstructionsTest { - private ByteTestBuilder getLogicTestBuilder(Function, Integer> operator) { - return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, operator) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()) - .keepCurrentInjectorsAfterRun(); - } - @Test public void testAND_R() { ByteTestBuilder test = getLogicTestBuilder(context -> context.first & context.second); @@ -132,7 +123,7 @@ public void testCP_R() { .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> context.first & 0xFF) .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflow().subtractionIsSet(), - context -> (context.first & 0xFF) - (byte)(context.second & 0xFF)) + context -> (context.first & 0xFF) + (((~context.second) + 1) & 0xFF)) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( @@ -746,85 +737,240 @@ public void testRRD() { @Test public void testAND_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xDD, 0xA4) + ); } @Test public void testAND_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xDD, 0xA5) + ); } @Test public void testAND_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xFD, 0xA4) + ); } @Test public void testAND_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xFD, 0xA5) + ); } @Test public void testXOR_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xDD, 0xAC) + ); } @Test public void testXOR_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xDD, 0xAD) + ); } @Test public void testXOR_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xFD, 0xAC) + ); } @Test public void testXOR_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xFD, 0xAD) + ); } @Test public void testOR_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xDD, 0xB4) + ); } @Test public void testOR_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xDD, 0xB5) + ); } @Test public void testOR_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xFD, 0xB4) + ); } @Test public void testOR_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + Generator.forSome16bitUnary( + test.run(0xFD, 0xB5) + ); } @Test public void testCP_IXH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> context.first & 0xFF) + .verifyFlags(new FlagsCheckImpl().sign().zero() + .borrow(context -> context.first >>> 8) + .halfBorrow(context -> context.first >>> 8) + .overflow() + .subtractionIsSet(), + context -> (context.first & 0xFF) + (((~(context.first >>> 8)) + 1) & 0xFF)); + Generator.forSome16bitUnary( + test.run(0xDD, 0xBC) + ); } @Test public void testCP_IYH() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> context.first & 0xFF) + .verifyFlags(new FlagsCheckImpl().sign().zero() + .borrow(context -> context.first >>> 8) + .halfBorrow(context -> context.first >>> 8) + .overflow() + .subtractionIsSet(), + context -> (context.first & 0xFF) + (((~(context.first >>> 8)) + 1) & 0xFF)); + Generator.forSome16bitUnary( + test.run(0xFD, 0xBC) + ); } @Test public void testCP_IXL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> context.first & 0xFF) + .verifyFlags(new FlagsCheckImpl().sign().zero() + .borrow() + .halfBorrow() + .overflow() + .subtractionIsSet(), + context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); + Generator.forSome16bitBinary( + test.run(0xDD, 0xBD) + ); } @Test public void testCP_IYL() { + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> context.first & 0xFF) + .verifyFlags(new FlagsCheckImpl().sign().zero() + .borrow() + .halfBorrow() + .overflow() + .subtractionIsSet(), + context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); + Generator.forSome16bitBinary( + test.run(0xFD, 0xBD) + ); } - + private ByteTestBuilder getLogicTestBuilder(Function, Integer> operator) { + return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsRegister(REG_A) + .verifyRegister(REG_A, operator) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()) + .keepCurrentInjectorsAfterRun(); + } private IntegerTestBuilder prepareCPxTest(Function, Integer> hlOperation) { return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) From 7b10074b50e83616ed70cc675c43c92ae447335e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 2 Feb 2022 08:38:22 +0100 Subject: [PATCH 088/314] [#201] z80: optimize --- .../plugins/cpu/zilogZ80/DispatchTables.java | 2552 ++++++++--------- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 852 +++--- .../plugins/cpu/zilogZ80/ArithmeticTest.java | 6 +- 3 files changed, 1704 insertions(+), 1706 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java index bf4e89632..c4cef65ac 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java @@ -20,1290 +20,1290 @@ public class DispatchTables { static { MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodType intShort = MethodType.methodType(int.class, short.class); - MethodType intShortByte = MethodType.methodType(int.class, short.class, byte.class); + MethodType retInt = MethodType.methodType(int.class); + MethodType retIntByte = MethodType.methodType(int.class, byte.class); try { - DISPATCH_TABLE[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", intShort); - DISPATCH_TABLE[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); - DISPATCH_TABLE[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_BC_A", intShort); - DISPATCH_TABLE[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); - DISPATCH_TABLE[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); - DISPATCH_TABLE[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); - DISPATCH_TABLE[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); - DISPATCH_TABLE[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLCA", intShort); - DISPATCH_TABLE[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_EX_AF_AFF", intShort); - DISPATCH_TABLE[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); - DISPATCH_TABLE[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_BC", intShort); - DISPATCH_TABLE[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); - DISPATCH_TABLE[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); - DISPATCH_TABLE[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); - DISPATCH_TABLE[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); - DISPATCH_TABLE[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRCA", intShort); - DISPATCH_TABLE[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_DJNZ", intShort); - DISPATCH_TABLE[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); - DISPATCH_TABLE[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_DE_A", intShort); - DISPATCH_TABLE[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); - DISPATCH_TABLE[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); - DISPATCH_TABLE[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); - DISPATCH_TABLE[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); - DISPATCH_TABLE[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RLA", intShort); - DISPATCH_TABLE[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_JR_N", intShort); - DISPATCH_TABLE[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); - DISPATCH_TABLE[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_DE", intShort); - DISPATCH_TABLE[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); - DISPATCH_TABLE[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); - DISPATCH_TABLE[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); - DISPATCH_TABLE[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); - DISPATCH_TABLE[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RRA", intShort); - DISPATCH_TABLE[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); - DISPATCH_TABLE[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); - DISPATCH_TABLE[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_HL", intShort); - DISPATCH_TABLE[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); - DISPATCH_TABLE[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); - DISPATCH_TABLE[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); - DISPATCH_TABLE[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); - DISPATCH_TABLE[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_DAA", intShort); - DISPATCH_TABLE[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); - DISPATCH_TABLE[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); - DISPATCH_TABLE[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_HL_REF_NN", intShort); - DISPATCH_TABLE[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); - DISPATCH_TABLE[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); - DISPATCH_TABLE[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); - DISPATCH_TABLE[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); - DISPATCH_TABLE[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_CPL", intShort); - DISPATCH_TABLE[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); - DISPATCH_TABLE[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", intShort); - DISPATCH_TABLE[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_A", intShort); - DISPATCH_TABLE[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", intShort); - DISPATCH_TABLE[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); - DISPATCH_TABLE[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); - DISPATCH_TABLE[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); - DISPATCH_TABLE[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SCF", intShort); - DISPATCH_TABLE[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", intShort); - DISPATCH_TABLE[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", intShort); - DISPATCH_TABLE[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_NN", intShort); - DISPATCH_TABLE[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", intShort); - DISPATCH_TABLE[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", intShort); - DISPATCH_TABLE[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", intShort); - DISPATCH_TABLE[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", intShort); - DISPATCH_TABLE[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_CCF", intShort); - DISPATCH_TABLE[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_HALT", intShort); - DISPATCH_TABLE[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", intShort); - DISPATCH_TABLE[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); - DISPATCH_TABLE[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); - DISPATCH_TABLE[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); - DISPATCH_TABLE[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); - DISPATCH_TABLE[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); - DISPATCH_TABLE[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); - DISPATCH_TABLE[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); - DISPATCH_TABLE[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", intShort); - DISPATCH_TABLE[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); - DISPATCH_TABLE[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); - DISPATCH_TABLE[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); - DISPATCH_TABLE[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); - DISPATCH_TABLE[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); - DISPATCH_TABLE[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); - DISPATCH_TABLE[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); - DISPATCH_TABLE[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", intShort); - DISPATCH_TABLE[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); - DISPATCH_TABLE[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); - DISPATCH_TABLE[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); - DISPATCH_TABLE[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); - DISPATCH_TABLE[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); - DISPATCH_TABLE[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); - DISPATCH_TABLE[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); - DISPATCH_TABLE[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", intShort); - DISPATCH_TABLE[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); - DISPATCH_TABLE[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); - DISPATCH_TABLE[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); - DISPATCH_TABLE[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); - DISPATCH_TABLE[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); - DISPATCH_TABLE[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); - DISPATCH_TABLE[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); - DISPATCH_TABLE[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", intShort); - DISPATCH_TABLE[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); - DISPATCH_TABLE[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); - DISPATCH_TABLE[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); - DISPATCH_TABLE[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); - DISPATCH_TABLE[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); - DISPATCH_TABLE[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); - DISPATCH_TABLE[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); - DISPATCH_TABLE[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", intShort); - DISPATCH_TABLE[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); - DISPATCH_TABLE[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); - DISPATCH_TABLE[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); - DISPATCH_TABLE[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); - DISPATCH_TABLE[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); - DISPATCH_TABLE[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); - DISPATCH_TABLE[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); - DISPATCH_TABLE[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", intShort); - DISPATCH_TABLE[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); - DISPATCH_TABLE[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); - DISPATCH_TABLE[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); - DISPATCH_TABLE[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); - DISPATCH_TABLE[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); - DISPATCH_TABLE[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); - DISPATCH_TABLE[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); - DISPATCH_TABLE[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", intShort); - DISPATCH_TABLE[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); - DISPATCH_TABLE[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); - DISPATCH_TABLE[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); - DISPATCH_TABLE[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); - DISPATCH_TABLE[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); - DISPATCH_TABLE[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); - DISPATCH_TABLE[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); - DISPATCH_TABLE[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", intShort); - DISPATCH_TABLE[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); - DISPATCH_TABLE[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", intShort); - DISPATCH_TABLE[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); - DISPATCH_TABLE[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_JP_NN", intShort); - DISPATCH_TABLE[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); - DISPATCH_TABLE[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", intShort); - DISPATCH_TABLE[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_N", intShort); - DISPATCH_TABLE[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); - DISPATCH_TABLE[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); - DISPATCH_TABLE[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_RET", intShort); - DISPATCH_TABLE[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); - DISPATCH_TABLE[0xCB] = lookup.findVirtual(EmulatorEngine.class, "CB_DISPATCH", intShort); - DISPATCH_TABLE[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); - DISPATCH_TABLE[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_NN", intShort); - DISPATCH_TABLE[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_N", intShort); - DISPATCH_TABLE[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); - DISPATCH_TABLE[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); - DISPATCH_TABLE[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", intShort); - DISPATCH_TABLE[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); - DISPATCH_TABLE[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_N_A", intShort); - DISPATCH_TABLE[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); - DISPATCH_TABLE[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", intShort); - DISPATCH_TABLE[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_N", intShort); - DISPATCH_TABLE[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); - DISPATCH_TABLE[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); - DISPATCH_TABLE[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_EXX", intShort); - DISPATCH_TABLE[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); - DISPATCH_TABLE[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_IN_A_REF_N", intShort); - DISPATCH_TABLE[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); - DISPATCH_TABLE[0xDD] = lookup.findVirtual(EmulatorEngine.class, "DD_DISPATCH", intShort); - DISPATCH_TABLE[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_N", intShort); - DISPATCH_TABLE[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); - DISPATCH_TABLE[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); - DISPATCH_TABLE[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", intShort); - DISPATCH_TABLE[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); - DISPATCH_TABLE[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_HL", intShort); - DISPATCH_TABLE[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); - DISPATCH_TABLE[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", intShort); - DISPATCH_TABLE[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_N", intShort); - DISPATCH_TABLE[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); - DISPATCH_TABLE[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); - DISPATCH_TABLE[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_HL", intShort); - DISPATCH_TABLE[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); - DISPATCH_TABLE[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_EX_DE_HL", intShort); - DISPATCH_TABLE[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); - DISPATCH_TABLE[0xED] = lookup.findVirtual(EmulatorEngine.class, "ED_DISPATCH", intShort); - DISPATCH_TABLE[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_N", intShort); - DISPATCH_TABLE[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); - DISPATCH_TABLE[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); - DISPATCH_TABLE[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", intShort); - DISPATCH_TABLE[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); - DISPATCH_TABLE[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_DI", intShort); - DISPATCH_TABLE[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); - DISPATCH_TABLE[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", intShort); - DISPATCH_TABLE[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_N", intShort); - DISPATCH_TABLE[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); - DISPATCH_TABLE[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", intShort); - DISPATCH_TABLE[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_HL", intShort); - DISPATCH_TABLE[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", intShort); - DISPATCH_TABLE[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_EI", intShort); - DISPATCH_TABLE[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", intShort); - DISPATCH_TABLE[0xFD] = lookup.findVirtual(EmulatorEngine.class, "FD_DISPATCH", intShort); - DISPATCH_TABLE[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_N", intShort); - DISPATCH_TABLE[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", intShort); + DISPATCH_TABLE[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", retInt); + DISPATCH_TABLE[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", retInt); + DISPATCH_TABLE[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_BC_A", retInt); + DISPATCH_TABLE[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", retInt); + DISPATCH_TABLE[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); + DISPATCH_TABLE[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); + DISPATCH_TABLE[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLCA", retInt); + DISPATCH_TABLE[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_EX_AF_AFF", retInt); + DISPATCH_TABLE[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", retInt); + DISPATCH_TABLE[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_BC", retInt); + DISPATCH_TABLE[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", retInt); + DISPATCH_TABLE[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); + DISPATCH_TABLE[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); + DISPATCH_TABLE[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRCA", retInt); + DISPATCH_TABLE[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_DJNZ", retInt); + DISPATCH_TABLE[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", retInt); + DISPATCH_TABLE[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_DE_A", retInt); + DISPATCH_TABLE[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", retInt); + DISPATCH_TABLE[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); + DISPATCH_TABLE[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); + DISPATCH_TABLE[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RLA", retInt); + DISPATCH_TABLE[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_JR_N", retInt); + DISPATCH_TABLE[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", retInt); + DISPATCH_TABLE[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_DE", retInt); + DISPATCH_TABLE[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", retInt); + DISPATCH_TABLE[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); + DISPATCH_TABLE[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); + DISPATCH_TABLE[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RRA", retInt); + DISPATCH_TABLE[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); + DISPATCH_TABLE[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", retInt); + DISPATCH_TABLE[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_HL", retInt); + DISPATCH_TABLE[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", retInt); + DISPATCH_TABLE[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); + DISPATCH_TABLE[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); + DISPATCH_TABLE[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_DAA", retInt); + DISPATCH_TABLE[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); + DISPATCH_TABLE[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", retInt); + DISPATCH_TABLE[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_HL_REF_NN", retInt); + DISPATCH_TABLE[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", retInt); + DISPATCH_TABLE[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); + DISPATCH_TABLE[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); + DISPATCH_TABLE[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_CPL", retInt); + DISPATCH_TABLE[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); + DISPATCH_TABLE[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", retInt); + DISPATCH_TABLE[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_A", retInt); + DISPATCH_TABLE[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", retInt); + DISPATCH_TABLE[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); + DISPATCH_TABLE[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); + DISPATCH_TABLE[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SCF", retInt); + DISPATCH_TABLE[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); + DISPATCH_TABLE[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", retInt); + DISPATCH_TABLE[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_NN", retInt); + DISPATCH_TABLE[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", retInt); + DISPATCH_TABLE[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); + DISPATCH_TABLE[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); + DISPATCH_TABLE[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_CCF", retInt); + DISPATCH_TABLE[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_HALT", retInt); + DISPATCH_TABLE[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", retInt); + DISPATCH_TABLE[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_JP_NN", retInt); + DISPATCH_TABLE[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", retInt); + DISPATCH_TABLE[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_N", retInt); + DISPATCH_TABLE[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_RET", retInt); + DISPATCH_TABLE[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE[0xCB] = lookup.findVirtual(EmulatorEngine.class, "CB_DISPATCH", retInt); + DISPATCH_TABLE[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_NN", retInt); + DISPATCH_TABLE[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_N", retInt); + DISPATCH_TABLE[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", retInt); + DISPATCH_TABLE[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_N_A", retInt); + DISPATCH_TABLE[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", retInt); + DISPATCH_TABLE[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_N", retInt); + DISPATCH_TABLE[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_EXX", retInt); + DISPATCH_TABLE[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_IN_A_REF_N", retInt); + DISPATCH_TABLE[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE[0xDD] = lookup.findVirtual(EmulatorEngine.class, "DD_DISPATCH", retInt); + DISPATCH_TABLE[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_N", retInt); + DISPATCH_TABLE[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", retInt); + DISPATCH_TABLE[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_HL", retInt); + DISPATCH_TABLE[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", retInt); + DISPATCH_TABLE[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_N", retInt); + DISPATCH_TABLE[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_HL", retInt); + DISPATCH_TABLE[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_EX_DE_HL", retInt); + DISPATCH_TABLE[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE[0xED] = lookup.findVirtual(EmulatorEngine.class, "ED_DISPATCH", retInt); + DISPATCH_TABLE[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_N", retInt); + DISPATCH_TABLE[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", retInt); + DISPATCH_TABLE[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_DI", retInt); + DISPATCH_TABLE[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", retInt); + DISPATCH_TABLE[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_N", retInt); + DISPATCH_TABLE[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_HL", retInt); + DISPATCH_TABLE[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_EI", retInt); + DISPATCH_TABLE[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE[0xFD] = lookup.findVirtual(EmulatorEngine.class, "FD_DISPATCH", retInt); + DISPATCH_TABLE[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_N", retInt); + DISPATCH_TABLE[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); - DISPATCH_TABLE_ED[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); - DISPATCH_TABLE_ED[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); - DISPATCH_TABLE_ED[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", intShort); - DISPATCH_TABLE_ED[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", intShort); - DISPATCH_TABLE_ED[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); - DISPATCH_TABLE_ED[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); - DISPATCH_TABLE_ED[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", intShort); - DISPATCH_TABLE_ED[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_I_A", intShort); - DISPATCH_TABLE_ED[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); - DISPATCH_TABLE_ED[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); - DISPATCH_TABLE_ED[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", intShort); - DISPATCH_TABLE_ED[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", intShort); - DISPATCH_TABLE_ED[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); - DISPATCH_TABLE_ED[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_RETI", intShort); - DISPATCH_TABLE_ED[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", intShort); // im 0/1 - DISPATCH_TABLE_ED[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_A", intShort); - DISPATCH_TABLE_ED[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); - DISPATCH_TABLE_ED[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); - DISPATCH_TABLE_ED[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", intShort); - DISPATCH_TABLE_ED[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", intShort); - DISPATCH_TABLE_ED[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); - DISPATCH_TABLE_ED[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); - DISPATCH_TABLE_ED[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_IM_1", intShort); - DISPATCH_TABLE_ED[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_I", intShort); - DISPATCH_TABLE_ED[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); - DISPATCH_TABLE_ED[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); - DISPATCH_TABLE_ED[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", intShort); - DISPATCH_TABLE_ED[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", intShort); - DISPATCH_TABLE_ED[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); - DISPATCH_TABLE_ED[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); - DISPATCH_TABLE_ED[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_2", intShort); - DISPATCH_TABLE_ED[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_R", intShort); - DISPATCH_TABLE_ED[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); - DISPATCH_TABLE_ED[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); - DISPATCH_TABLE_ED[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", intShort); - DISPATCH_TABLE_ED[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", intShort); - DISPATCH_TABLE_ED[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); - DISPATCH_TABLE_ED[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); - DISPATCH_TABLE_ED[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", intShort); - DISPATCH_TABLE_ED[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_RRD", intShort); - DISPATCH_TABLE_ED[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); - DISPATCH_TABLE_ED[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); - DISPATCH_TABLE_ED[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", intShort); - DISPATCH_TABLE_ED[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", intShort); - DISPATCH_TABLE_ED[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); - DISPATCH_TABLE_ED[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); - DISPATCH_TABLE_ED[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", intShort); // im 0/1 - DISPATCH_TABLE_ED[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_RLD", intShort); - DISPATCH_TABLE_ED[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_IN_REF_C", intShort); - DISPATCH_TABLE_ED[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_0", intShort); - DISPATCH_TABLE_ED[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", intShort); - DISPATCH_TABLE_ED[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", intShort); - DISPATCH_TABLE_ED[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); - DISPATCH_TABLE_ED[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); - DISPATCH_TABLE_ED[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_IM_1", intShort); - DISPATCH_TABLE_ED[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", intShort); - DISPATCH_TABLE_ED[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", intShort); - DISPATCH_TABLE_ED[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", intShort); - DISPATCH_TABLE_ED[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", intShort); - DISPATCH_TABLE_ED[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", intShort); - DISPATCH_TABLE_ED[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", intShort); - DISPATCH_TABLE_ED[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_2", intShort); - DISPATCH_TABLE_ED[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_LDI", intShort); - DISPATCH_TABLE_ED[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_CPI", intShort); - DISPATCH_TABLE_ED[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_INI", intShort); - DISPATCH_TABLE_ED[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_OUTI", intShort); - DISPATCH_TABLE_ED[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_LDD", intShort); - DISPATCH_TABLE_ED[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_CPD", intShort); - DISPATCH_TABLE_ED[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_IND", intShort); - DISPATCH_TABLE_ED[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_OUTD", intShort); - DISPATCH_TABLE_ED[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_LDIR", intShort); - DISPATCH_TABLE_ED[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_CPIR", intShort); - DISPATCH_TABLE_ED[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_INIR", intShort); - DISPATCH_TABLE_ED[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OTIR", intShort); - DISPATCH_TABLE_ED[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_LDDR", intShort); - DISPATCH_TABLE_ED[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CPDR", intShort); - DISPATCH_TABLE_ED[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_INDR", intShort); - DISPATCH_TABLE_ED[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_OTDR", intShort); + DISPATCH_TABLE_ED[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); + DISPATCH_TABLE_ED[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", retInt); + DISPATCH_TABLE_ED[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", retInt); + DISPATCH_TABLE_ED[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); + DISPATCH_TABLE_ED[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); + DISPATCH_TABLE_ED[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); + DISPATCH_TABLE_ED[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_I_A", retInt); + DISPATCH_TABLE_ED[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); + DISPATCH_TABLE_ED[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", retInt); + DISPATCH_TABLE_ED[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", retInt); + DISPATCH_TABLE_ED[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); + DISPATCH_TABLE_ED[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_RETI", retInt); + DISPATCH_TABLE_ED[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); // im 0/1 + DISPATCH_TABLE_ED[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_A", retInt); + DISPATCH_TABLE_ED[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); + DISPATCH_TABLE_ED[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", retInt); + DISPATCH_TABLE_ED[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", retInt); + DISPATCH_TABLE_ED[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); + DISPATCH_TABLE_ED[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); + DISPATCH_TABLE_ED[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_IM_1", retInt); + DISPATCH_TABLE_ED[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_I", retInt); + DISPATCH_TABLE_ED[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); + DISPATCH_TABLE_ED[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", retInt); + DISPATCH_TABLE_ED[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", retInt); + DISPATCH_TABLE_ED[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); + DISPATCH_TABLE_ED[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); + DISPATCH_TABLE_ED[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_2", retInt); + DISPATCH_TABLE_ED[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_R", retInt); + DISPATCH_TABLE_ED[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); + DISPATCH_TABLE_ED[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", retInt); + DISPATCH_TABLE_ED[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", retInt); + DISPATCH_TABLE_ED[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); + DISPATCH_TABLE_ED[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); + DISPATCH_TABLE_ED[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); + DISPATCH_TABLE_ED[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_RRD", retInt); + DISPATCH_TABLE_ED[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); + DISPATCH_TABLE_ED[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", retInt); + DISPATCH_TABLE_ED[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", retInt); + DISPATCH_TABLE_ED[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); + DISPATCH_TABLE_ED[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); + DISPATCH_TABLE_ED[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); // im 0/1 + DISPATCH_TABLE_ED[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_RLD", retInt); + DISPATCH_TABLE_ED[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_IN_REF_C", retInt); + DISPATCH_TABLE_ED[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_0", retInt); + DISPATCH_TABLE_ED[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", retInt); + DISPATCH_TABLE_ED[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", retInt); + DISPATCH_TABLE_ED[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); + DISPATCH_TABLE_ED[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); + DISPATCH_TABLE_ED[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_IM_1", retInt); + DISPATCH_TABLE_ED[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); + DISPATCH_TABLE_ED[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", retInt); + DISPATCH_TABLE_ED[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", retInt); + DISPATCH_TABLE_ED[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); + DISPATCH_TABLE_ED[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); + DISPATCH_TABLE_ED[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_2", retInt); + DISPATCH_TABLE_ED[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_LDI", retInt); + DISPATCH_TABLE_ED[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_CPI", retInt); + DISPATCH_TABLE_ED[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_INI", retInt); + DISPATCH_TABLE_ED[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_OUTI", retInt); + DISPATCH_TABLE_ED[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_LDD", retInt); + DISPATCH_TABLE_ED[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_CPD", retInt); + DISPATCH_TABLE_ED[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_IND", retInt); + DISPATCH_TABLE_ED[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_OUTD", retInt); + DISPATCH_TABLE_ED[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_LDIR", retInt); + DISPATCH_TABLE_ED[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_CPIR", retInt); + DISPATCH_TABLE_ED[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_INIR", retInt); + DISPATCH_TABLE_ED[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OTIR", retInt); + DISPATCH_TABLE_ED[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_LDDR", retInt); + DISPATCH_TABLE_ED[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CPDR", retInt); + DISPATCH_TABLE_ED[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_INDR", retInt); + DISPATCH_TABLE_ED[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_OTDR", retInt); - DISPATCH_TABLE_CB[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); - DISPATCH_TABLE_CB[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); - DISPATCH_TABLE_CB[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); - DISPATCH_TABLE_CB[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); - DISPATCH_TABLE_CB[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); - DISPATCH_TABLE_CB[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); - DISPATCH_TABLE_CB[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); - DISPATCH_TABLE_CB[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", intShort); - DISPATCH_TABLE_CB[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); - DISPATCH_TABLE_CB[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); - DISPATCH_TABLE_CB[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); - DISPATCH_TABLE_CB[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); - DISPATCH_TABLE_CB[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); - DISPATCH_TABLE_CB[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); - DISPATCH_TABLE_CB[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); - DISPATCH_TABLE_CB[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", intShort); - DISPATCH_TABLE_CB[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); - DISPATCH_TABLE_CB[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); - DISPATCH_TABLE_CB[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); - DISPATCH_TABLE_CB[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); - DISPATCH_TABLE_CB[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); - DISPATCH_TABLE_CB[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); - DISPATCH_TABLE_CB[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); - DISPATCH_TABLE_CB[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", intShort); - DISPATCH_TABLE_CB[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); - DISPATCH_TABLE_CB[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); - DISPATCH_TABLE_CB[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); - DISPATCH_TABLE_CB[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); - DISPATCH_TABLE_CB[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); - DISPATCH_TABLE_CB[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); - DISPATCH_TABLE_CB[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); - DISPATCH_TABLE_CB[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", intShort); - DISPATCH_TABLE_CB[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); - DISPATCH_TABLE_CB[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); - DISPATCH_TABLE_CB[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); - DISPATCH_TABLE_CB[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); - DISPATCH_TABLE_CB[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); - DISPATCH_TABLE_CB[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); - DISPATCH_TABLE_CB[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); - DISPATCH_TABLE_CB[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", intShort); - DISPATCH_TABLE_CB[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); - DISPATCH_TABLE_CB[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); - DISPATCH_TABLE_CB[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); - DISPATCH_TABLE_CB[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); - DISPATCH_TABLE_CB[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); - DISPATCH_TABLE_CB[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); - DISPATCH_TABLE_CB[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); - DISPATCH_TABLE_CB[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", intShort); - DISPATCH_TABLE_CB[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); - DISPATCH_TABLE_CB[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); - DISPATCH_TABLE_CB[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); - DISPATCH_TABLE_CB[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); - DISPATCH_TABLE_CB[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); - DISPATCH_TABLE_CB[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); - DISPATCH_TABLE_CB[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); - DISPATCH_TABLE_CB[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", intShort); - DISPATCH_TABLE_CB[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); - DISPATCH_TABLE_CB[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); - DISPATCH_TABLE_CB[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); - DISPATCH_TABLE_CB[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); - DISPATCH_TABLE_CB[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); - DISPATCH_TABLE_CB[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); - DISPATCH_TABLE_CB[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); - DISPATCH_TABLE_CB[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", intShort); - DISPATCH_TABLE_CB[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", intShort); - DISPATCH_TABLE_CB[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", intShort); - DISPATCH_TABLE_CB[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xCB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xDD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xED] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xFD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); - DISPATCH_TABLE_CB[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", intShort); + DISPATCH_TABLE_CB[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", retInt); + DISPATCH_TABLE_CB[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", retInt); + DISPATCH_TABLE_CB[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", retInt); + DISPATCH_TABLE_CB[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", retInt); + DISPATCH_TABLE_CB[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", retInt); + DISPATCH_TABLE_CB[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", retInt); + DISPATCH_TABLE_CB[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", retInt); + DISPATCH_TABLE_CB[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_R", retInt); + DISPATCH_TABLE_CB[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", retInt); + DISPATCH_TABLE_CB[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", retInt); + DISPATCH_TABLE_CB[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", retInt); + DISPATCH_TABLE_CB[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", retInt); + DISPATCH_TABLE_CB[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", retInt); + DISPATCH_TABLE_CB[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", retInt); + DISPATCH_TABLE_CB[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", retInt); + DISPATCH_TABLE_CB[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_R", retInt); + DISPATCH_TABLE_CB[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", retInt); + DISPATCH_TABLE_CB[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", retInt); + DISPATCH_TABLE_CB[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", retInt); + DISPATCH_TABLE_CB[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", retInt); + DISPATCH_TABLE_CB[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", retInt); + DISPATCH_TABLE_CB[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", retInt); + DISPATCH_TABLE_CB[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", retInt); + DISPATCH_TABLE_CB[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RL_R", retInt); + DISPATCH_TABLE_CB[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", retInt); + DISPATCH_TABLE_CB[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", retInt); + DISPATCH_TABLE_CB[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", retInt); + DISPATCH_TABLE_CB[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", retInt); + DISPATCH_TABLE_CB[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", retInt); + DISPATCH_TABLE_CB[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", retInt); + DISPATCH_TABLE_CB[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", retInt); + DISPATCH_TABLE_CB[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RR_R", retInt); + DISPATCH_TABLE_CB[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", retInt); + DISPATCH_TABLE_CB[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", retInt); + DISPATCH_TABLE_CB[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", retInt); + DISPATCH_TABLE_CB[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", retInt); + DISPATCH_TABLE_CB[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", retInt); + DISPATCH_TABLE_CB[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", retInt); + DISPATCH_TABLE_CB[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", retInt); + DISPATCH_TABLE_CB[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_R", retInt); + DISPATCH_TABLE_CB[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", retInt); + DISPATCH_TABLE_CB[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", retInt); + DISPATCH_TABLE_CB[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", retInt); + DISPATCH_TABLE_CB[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", retInt); + DISPATCH_TABLE_CB[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", retInt); + DISPATCH_TABLE_CB[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", retInt); + DISPATCH_TABLE_CB[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", retInt); + DISPATCH_TABLE_CB[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_R", retInt); + DISPATCH_TABLE_CB[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", retInt); + DISPATCH_TABLE_CB[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", retInt); + DISPATCH_TABLE_CB[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", retInt); + DISPATCH_TABLE_CB[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", retInt); + DISPATCH_TABLE_CB[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", retInt); + DISPATCH_TABLE_CB[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", retInt); + DISPATCH_TABLE_CB[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", retInt); + DISPATCH_TABLE_CB[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_R", retInt); + DISPATCH_TABLE_CB[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", retInt); + DISPATCH_TABLE_CB[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", retInt); + DISPATCH_TABLE_CB[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", retInt); + DISPATCH_TABLE_CB[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", retInt); + DISPATCH_TABLE_CB[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", retInt); + DISPATCH_TABLE_CB[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", retInt); + DISPATCH_TABLE_CB[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", retInt); + DISPATCH_TABLE_CB[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_R", retInt); + DISPATCH_TABLE_CB[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_R", retInt); + DISPATCH_TABLE_CB[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_R", retInt); + DISPATCH_TABLE_CB[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xCB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xDD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xED] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xFD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); + DISPATCH_TABLE_CB[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); - DISPATCH_TABLE_DD[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", intShort); - DISPATCH_TABLE_DD[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", intShort); - DISPATCH_TABLE_DD[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IX_NN", intShort); - DISPATCH_TABLE_DD[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_IX", intShort); - DISPATCH_TABLE_DD[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IX", intShort); - DISPATCH_TABLE_DD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IXH", intShort); - DISPATCH_TABLE_DD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IXH", intShort); - DISPATCH_TABLE_DD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_N", intShort); - DISPATCH_TABLE_DD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", intShort); - DISPATCH_TABLE_DD[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IX_REF_NN", intShort); - DISPATCH_TABLE_DD[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IX", intShort); - DISPATCH_TABLE_DD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IXL", intShort); - DISPATCH_TABLE_DD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IXL", intShort); - DISPATCH_TABLE_DD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_N", intShort); - DISPATCH_TABLE_DD[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_N", intShort); - DISPATCH_TABLE_DD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", intShort); - DISPATCH_TABLE_DD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", intShort); - DISPATCH_TABLE_DD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", intShort); - DISPATCH_TABLE_DD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", intShort); - DISPATCH_TABLE_DD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", intShort); - DISPATCH_TABLE_DD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", intShort); - DISPATCH_TABLE_DD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", intShort); - DISPATCH_TABLE_DD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", intShort); - DISPATCH_TABLE_DD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", intShort); - DISPATCH_TABLE_DD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", intShort); - DISPATCH_TABLE_DD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", intShort); - DISPATCH_TABLE_DD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", intShort); - DISPATCH_TABLE_DD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", intShort); - DISPATCH_TABLE_DD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIH_IIH", intShort); - DISPATCH_TABLE_DD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_IXL", intShort); - DISPATCH_TABLE_DD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", intShort); - DISPATCH_TABLE_DD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", intShort); - DISPATCH_TABLE_DD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", intShort); - DISPATCH_TABLE_DD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", intShort); - DISPATCH_TABLE_DD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", intShort); - DISPATCH_TABLE_DD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_IXH", intShort); - DISPATCH_TABLE_DD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIL_IIL", intShort); - DISPATCH_TABLE_DD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", intShort); - DISPATCH_TABLE_DD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); - DISPATCH_TABLE_DD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); - DISPATCH_TABLE_DD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); - DISPATCH_TABLE_DD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); - DISPATCH_TABLE_DD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); - DISPATCH_TABLE_DD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); - DISPATCH_TABLE_DD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", intShort); - DISPATCH_TABLE_DD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", intShort); - DISPATCH_TABLE_DD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", intShort); - DISPATCH_TABLE_DD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IXH", intShort); - DISPATCH_TABLE_DD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IXL", intShort); - DISPATCH_TABLE_DD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IXH", intShort); - DISPATCH_TABLE_DD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IXL", intShort); - DISPATCH_TABLE_DD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IXH", intShort); - DISPATCH_TABLE_DD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IXL", intShort); - DISPATCH_TABLE_DD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IXH", intShort); - DISPATCH_TABLE_DD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IXL", intShort); - DISPATCH_TABLE_DD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IXH", intShort); - DISPATCH_TABLE_DD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IXL", intShort); - DISPATCH_TABLE_DD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IXH", intShort); - DISPATCH_TABLE_DD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IXL", intShort); - DISPATCH_TABLE_DD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IXH", intShort); - DISPATCH_TABLE_DD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IXL", intShort); - DISPATCH_TABLE_DD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IXH", intShort); - DISPATCH_TABLE_DD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IXL", intShort); - DISPATCH_TABLE_DD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IX_N", intShort); - DISPATCH_TABLE_DD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "DD_CB_DISPATCH", intShort); - DISPATCH_TABLE_DD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IX", intShort); - DISPATCH_TABLE_DD[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_IX", intShort); - DISPATCH_TABLE_DD[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_IX", intShort); - DISPATCH_TABLE_DD[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_IX", intShort); - DISPATCH_TABLE_DD[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_IX", intShort); + DISPATCH_TABLE_DD[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", retInt); + DISPATCH_TABLE_DD[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", retInt); + DISPATCH_TABLE_DD[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IX_NN", retInt); + DISPATCH_TABLE_DD[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_IX", retInt); + DISPATCH_TABLE_DD[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IX", retInt); + DISPATCH_TABLE_DD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IXH", retInt); + DISPATCH_TABLE_DD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IXH", retInt); + DISPATCH_TABLE_DD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_N", retInt); + DISPATCH_TABLE_DD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", retInt); + DISPATCH_TABLE_DD[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IX_REF_NN", retInt); + DISPATCH_TABLE_DD[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IX", retInt); + DISPATCH_TABLE_DD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IXL", retInt); + DISPATCH_TABLE_DD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IXL", retInt); + DISPATCH_TABLE_DD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_N", retInt); + DISPATCH_TABLE_DD[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_N", retInt); + DISPATCH_TABLE_DD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", retInt); + DISPATCH_TABLE_DD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); + DISPATCH_TABLE_DD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); + DISPATCH_TABLE_DD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); + DISPATCH_TABLE_DD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); + DISPATCH_TABLE_DD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); + DISPATCH_TABLE_DD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); + DISPATCH_TABLE_DD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); + DISPATCH_TABLE_DD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); + DISPATCH_TABLE_DD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); + DISPATCH_TABLE_DD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); + DISPATCH_TABLE_DD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); + DISPATCH_TABLE_DD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); + DISPATCH_TABLE_DD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIH_IIH", retInt); + DISPATCH_TABLE_DD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_IXL", retInt); + DISPATCH_TABLE_DD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); + DISPATCH_TABLE_DD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", retInt); + DISPATCH_TABLE_DD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", retInt); + DISPATCH_TABLE_DD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", retInt); + DISPATCH_TABLE_DD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", retInt); + DISPATCH_TABLE_DD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_IXH", retInt); + DISPATCH_TABLE_DD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIL_IIL", retInt); + DISPATCH_TABLE_DD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", retInt); + DISPATCH_TABLE_DD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); + DISPATCH_TABLE_DD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); + DISPATCH_TABLE_DD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); + DISPATCH_TABLE_DD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); + DISPATCH_TABLE_DD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); + DISPATCH_TABLE_DD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); + DISPATCH_TABLE_DD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); + DISPATCH_TABLE_DD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); + DISPATCH_TABLE_DD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); + DISPATCH_TABLE_DD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IXH", retInt); + DISPATCH_TABLE_DD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IXL", retInt); + DISPATCH_TABLE_DD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IXH", retInt); + DISPATCH_TABLE_DD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IXL", retInt); + DISPATCH_TABLE_DD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IXH", retInt); + DISPATCH_TABLE_DD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IXL", retInt); + DISPATCH_TABLE_DD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IXH", retInt); + DISPATCH_TABLE_DD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IXL", retInt); + DISPATCH_TABLE_DD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IXH", retInt); + DISPATCH_TABLE_DD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IXL", retInt); + DISPATCH_TABLE_DD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IXH", retInt); + DISPATCH_TABLE_DD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IXL", retInt); + DISPATCH_TABLE_DD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IXH", retInt); + DISPATCH_TABLE_DD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IXL", retInt); + DISPATCH_TABLE_DD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IXH", retInt); + DISPATCH_TABLE_DD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IXL", retInt); + DISPATCH_TABLE_DD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "DD_CB_DISPATCH", retInt); + DISPATCH_TABLE_DD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IX", retInt); + DISPATCH_TABLE_DD[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_IX", retInt); + DISPATCH_TABLE_DD[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_IX", retInt); + DISPATCH_TABLE_DD[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_IX", retInt); + DISPATCH_TABLE_DD[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_IX", retInt); - DISPATCH_TABLE_FD[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", intShort); - DISPATCH_TABLE_FD[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", intShort); - DISPATCH_TABLE_FD[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IY_NN", intShort); - DISPATCH_TABLE_FD[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_IY", intShort); - DISPATCH_TABLE_FD[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IY", intShort); - DISPATCH_TABLE_FD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IYH", intShort); - DISPATCH_TABLE_FD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IYH", intShort); - DISPATCH_TABLE_FD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_N", intShort); - DISPATCH_TABLE_FD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", intShort); - DISPATCH_TABLE_FD[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IY_REF_NN", intShort); - DISPATCH_TABLE_FD[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IY", intShort); - DISPATCH_TABLE_FD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IYL", intShort); - DISPATCH_TABLE_FD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IYL", intShort); - DISPATCH_TABLE_FD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_N", intShort); - DISPATCH_TABLE_FD[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_N", intShort); - DISPATCH_TABLE_FD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", intShort); - DISPATCH_TABLE_FD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", intShort); - DISPATCH_TABLE_FD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", intShort); - DISPATCH_TABLE_FD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", intShort); - DISPATCH_TABLE_FD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", intShort); - DISPATCH_TABLE_FD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", intShort); - DISPATCH_TABLE_FD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", intShort); - DISPATCH_TABLE_FD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", intShort); - DISPATCH_TABLE_FD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", intShort); - DISPATCH_TABLE_FD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", intShort); - DISPATCH_TABLE_FD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", intShort); - DISPATCH_TABLE_FD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", intShort); - DISPATCH_TABLE_FD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", intShort); - DISPATCH_TABLE_FD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIH_IIH", intShort); - DISPATCH_TABLE_FD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_IYL", intShort); - DISPATCH_TABLE_FD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", intShort); - DISPATCH_TABLE_FD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", intShort); - DISPATCH_TABLE_FD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", intShort); - DISPATCH_TABLE_FD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", intShort); - DISPATCH_TABLE_FD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", intShort); - DISPATCH_TABLE_FD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_IYH", intShort); - DISPATCH_TABLE_FD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIL_IIL", intShort); - DISPATCH_TABLE_FD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", intShort); - DISPATCH_TABLE_FD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); - DISPATCH_TABLE_FD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); - DISPATCH_TABLE_FD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); - DISPATCH_TABLE_FD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); - DISPATCH_TABLE_FD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); - DISPATCH_TABLE_FD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); - DISPATCH_TABLE_FD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", intShort); - DISPATCH_TABLE_FD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", intShort); - DISPATCH_TABLE_FD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", intShort); - DISPATCH_TABLE_FD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IYH", intShort); - DISPATCH_TABLE_FD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IYL", intShort); - DISPATCH_TABLE_FD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IYH", intShort); - DISPATCH_TABLE_FD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IYL", intShort); - DISPATCH_TABLE_FD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IYH", intShort); - DISPATCH_TABLE_FD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IYL", intShort); - DISPATCH_TABLE_FD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IYH", intShort); - DISPATCH_TABLE_FD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IYL", intShort); - DISPATCH_TABLE_FD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IYH", intShort); - DISPATCH_TABLE_FD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IYL", intShort); - DISPATCH_TABLE_FD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IYH", intShort); - DISPATCH_TABLE_FD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IYL", intShort); - DISPATCH_TABLE_FD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IYH", intShort); - DISPATCH_TABLE_FD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IYL", intShort); - DISPATCH_TABLE_FD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IYH", intShort); - DISPATCH_TABLE_FD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IYL", intShort); - DISPATCH_TABLE_FD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IY_N", intShort); - DISPATCH_TABLE_FD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "FD_CB_DISPATCH", intShort); - DISPATCH_TABLE_FD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IY", intShort); - DISPATCH_TABLE_FD[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_IY", intShort); - DISPATCH_TABLE_FD[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_IY", intShort); - DISPATCH_TABLE_FD[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_IY", intShort); - DISPATCH_TABLE_FD[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_IY", intShort); + DISPATCH_TABLE_FD[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", retInt); + DISPATCH_TABLE_FD[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", retInt); + DISPATCH_TABLE_FD[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IY_NN", retInt); + DISPATCH_TABLE_FD[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_IY", retInt); + DISPATCH_TABLE_FD[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IY", retInt); + DISPATCH_TABLE_FD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IYH", retInt); + DISPATCH_TABLE_FD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IYH", retInt); + DISPATCH_TABLE_FD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_N", retInt); + DISPATCH_TABLE_FD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", retInt); + DISPATCH_TABLE_FD[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IY_REF_NN", retInt); + DISPATCH_TABLE_FD[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IY", retInt); + DISPATCH_TABLE_FD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IYL", retInt); + DISPATCH_TABLE_FD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IYL", retInt); + DISPATCH_TABLE_FD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_N", retInt); + DISPATCH_TABLE_FD[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_N", retInt); + DISPATCH_TABLE_FD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", retInt); + DISPATCH_TABLE_FD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); + DISPATCH_TABLE_FD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); + DISPATCH_TABLE_FD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); + DISPATCH_TABLE_FD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); + DISPATCH_TABLE_FD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); + DISPATCH_TABLE_FD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); + DISPATCH_TABLE_FD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); + DISPATCH_TABLE_FD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); + DISPATCH_TABLE_FD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); + DISPATCH_TABLE_FD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); + DISPATCH_TABLE_FD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); + DISPATCH_TABLE_FD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); + DISPATCH_TABLE_FD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIH_IIH", retInt); + DISPATCH_TABLE_FD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_IYL", retInt); + DISPATCH_TABLE_FD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); + DISPATCH_TABLE_FD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", retInt); + DISPATCH_TABLE_FD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", retInt); + DISPATCH_TABLE_FD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", retInt); + DISPATCH_TABLE_FD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", retInt); + DISPATCH_TABLE_FD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_IYH", retInt); + DISPATCH_TABLE_FD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIL_IIL", retInt); + DISPATCH_TABLE_FD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", retInt); + DISPATCH_TABLE_FD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); + DISPATCH_TABLE_FD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); + DISPATCH_TABLE_FD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); + DISPATCH_TABLE_FD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); + DISPATCH_TABLE_FD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); + DISPATCH_TABLE_FD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); + DISPATCH_TABLE_FD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); + DISPATCH_TABLE_FD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); + DISPATCH_TABLE_FD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); + DISPATCH_TABLE_FD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IYH", retInt); + DISPATCH_TABLE_FD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IYL", retInt); + DISPATCH_TABLE_FD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IYH", retInt); + DISPATCH_TABLE_FD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IYL", retInt); + DISPATCH_TABLE_FD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IYH", retInt); + DISPATCH_TABLE_FD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IYL", retInt); + DISPATCH_TABLE_FD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IYH", retInt); + DISPATCH_TABLE_FD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IYL", retInt); + DISPATCH_TABLE_FD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IYH", retInt); + DISPATCH_TABLE_FD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IYL", retInt); + DISPATCH_TABLE_FD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IYH", retInt); + DISPATCH_TABLE_FD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IYL", retInt); + DISPATCH_TABLE_FD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IYH", retInt); + DISPATCH_TABLE_FD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IYL", retInt); + DISPATCH_TABLE_FD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IYH", retInt); + DISPATCH_TABLE_FD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IYL", retInt); + DISPATCH_TABLE_FD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "FD_CB_DISPATCH", retInt); + DISPATCH_TABLE_FD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IY", retInt); + DISPATCH_TABLE_FD[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_IY", retInt); + DISPATCH_TABLE_FD[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_IY", retInt); + DISPATCH_TABLE_FD[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_IY", retInt); + DISPATCH_TABLE_FD[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_IY", retInt); - DISPATCH_TABLE_DD_CB[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", intShortByte); - DISPATCH_TABLE_DD_CB[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xCB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xDD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xED] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xFD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); - DISPATCH_TABLE_DD_CB[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", intShortByte); + DISPATCH_TABLE_DD_CB[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IX_N", retIntByte); + DISPATCH_TABLE_DD_CB[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xCB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xDD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xED] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xFD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); + DISPATCH_TABLE_DD_CB[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IX_N_R", retIntByte); - DISPATCH_TABLE_FD_CB[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", intShortByte); - DISPATCH_TABLE_FD_CB[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xCB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xDD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xED] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xFD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); - DISPATCH_TABLE_FD_CB[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", intShortByte); + DISPATCH_TABLE_FD_CB[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRC_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RR_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_SLA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_SRA_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SLL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_SRL_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_BIT_N_REF_IY_N", retIntByte); + DISPATCH_TABLE_FD_CB[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_RES_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xCB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xDD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xED] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xFD] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); + DISPATCH_TABLE_FD_CB[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_REF_IY_N_R", retIntByte); } catch (IllegalAccessException | NoSuchMethodException e) { LOGGER.error("Could not set up dispatch table. The emulator won't work correctly", e); } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index d26c5209a..5524d5bcf 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -22,6 +22,7 @@ import net.emustudio.emulib.plugins.cpu.CPU.RunState; import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.emulib.plugins.memory.MemoryContext; +import net.emustudio.emulib.runtime.helpers.SleepUtils; import net.emustudio.plugins.cpu.intel8080.api.CpuEngine; import net.emustudio.plugins.cpu.intel8080.api.DispatchListener; import net.emustudio.plugins.cpu.intel8080.api.FrequencyChangedListener; @@ -34,7 +35,6 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.locks.LockSupport; import static net.emustudio.plugins.cpu.zilogZ80.DispatchTables.*; @@ -60,6 +60,8 @@ public class EmulatorEngine implements CpuEngine { private final MemoryContext memory; private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); + private int lastOpcode; + public final int[] regs = new int[8]; public final int[] regs2 = new int[8]; public int flags = 2; @@ -139,18 +141,16 @@ CPU.RunState step() throws Exception { boolean oldIFF = IFF[0]; noWait = false; currentRunState = CPU.RunState.STATE_STOPPED_BREAK; - short opcode = (short) (memory.read(PC) & 0xFF); + lastOpcode = readByte (PC); PC = (PC + 1) & 0xFFFF; try { - dispatch(opcode); + dispatch(); + } catch (Exception e) { + throw e; } catch (Throwable e) { throw new Exception(e); } isINT = (interruptPending != 0) && oldIFF && IFF[0]; - if (PC > 0xffff) { - PC = 0xffff; - return RunState.STATE_STOPPED_ADDR_FALLOUT; - } return currentRunState; } @@ -168,9 +168,9 @@ public CPU.RunState run(CPU cpu) { cycles_executed = 0; while ((cycles_executed < cycles_to_execute) && !Thread.currentThread().isInterrupted() && (currentRunState == CPU.RunState.STATE_RUNNING)) { try { - short opcode = memory.read(PC); + lastOpcode = readByte(PC); PC = (PC + 1) & 0xFFFF; - cycles = dispatch(opcode); + cycles = dispatch(); cycles_executed += cycles; executedCycles += cycles; if (cpu.isBreakpointSet(PC)) { @@ -192,16 +192,13 @@ public CPU.RunState run(CPU cpu) { endTime = System.nanoTime() - startTime; if (endTime < slice) { // time correction - LockSupport.parkNanos(slice - endTime); + SleepUtils.preciseSleepNanos(slice - endTime); } } return currentRunState; } - private int dispatch(short OP) throws Throwable { - int tmp, tmp1, tmp2, tmp3; - short special = 0; // prefix if available = 0xDD or 0xFD - + private int dispatch() throws Throwable { DispatchListener tmpListener = dispatchListener; if (tmpListener != null) { tmpListener.beforeDispatch(); @@ -218,9 +215,9 @@ private int dispatch(short OP) throws Throwable { incrementR(); /* Dispatch Instruction */ - MethodHandle instr = DISPATCH_TABLE[OP]; + MethodHandle instr = DISPATCH_TABLE[lastOpcode]; if (instr != null) { - return (int) instr.invokeExact(this, OP); + return (int) instr.invokeExact(this); } currentRunState = CPU.RunState.STATE_STOPPED_BAD_INSTR; } finally { @@ -231,38 +228,38 @@ private int dispatch(short OP) throws Throwable { return 0; } - int CB_DISPATCH(short OP) throws Throwable { + int CB_DISPATCH() throws Throwable { return DISPATCH(DISPATCH_TABLE_CB); } - int DD_DISPATCH(short OP) throws Throwable { + int DD_DISPATCH() throws Throwable { return DISPATCH(DISPATCH_TABLE_DD); } - int DD_CB_DISPATCH(short OP) throws Throwable { + int DD_CB_DISPATCH() throws Throwable { return SPECIAL_CB_DISPATCH(DISPATCH_TABLE_DD_CB); } - int ED_DISPATCH(short OP) throws Throwable { + int ED_DISPATCH() throws Throwable { return DISPATCH(DISPATCH_TABLE_ED); } - int FD_DISPATCH(short OP) throws Throwable { + int FD_DISPATCH() throws Throwable { return DISPATCH(DISPATCH_TABLE_FD); } - int FD_CB_DISPATCH(short OP) throws Throwable { + int FD_CB_DISPATCH() throws Throwable { return SPECIAL_CB_DISPATCH(DISPATCH_TABLE_FD_CB); } private int DISPATCH(MethodHandle[] table) throws Throwable { - short OP = (short) (memory.read(PC) & 0xFF); - incrementR(); + lastOpcode = readByte(PC); PC = (PC + 1) & 0xFFFF; + incrementR(); - MethodHandle instr = table[OP]; + MethodHandle instr = table[lastOpcode]; if (instr != null) { - return (int) instr.invokeExact(this, OP); + return (int) instr.invokeExact(this); } currentRunState = RunState.STATE_STOPPED_BAD_INSTR; return 0; @@ -272,13 +269,13 @@ int SPECIAL_CB_DISPATCH(MethodHandle[] table) throws Throwable { byte operand = memory.read(PC); PC = (PC + 1) & 0xFFFF; - short OP = (short) (memory.read(PC) & 0xFF); + lastOpcode = readByte(PC); PC = (PC + 1) & 0xFFFF; incrementR(); - MethodHandle instr = table[OP]; + MethodHandle instr = table[lastOpcode]; if (instr != null) { - return (int) instr.invokeExact(this, OP, operand); + return (int) instr.invokeExact(this, operand); } currentRunState = RunState.STATE_STOPPED_BAD_INSTR; return 0; @@ -317,7 +314,8 @@ private int doInterrupt() throws Throwable { case 0: // rst p (interruptVector) cycles += 11; RunState old_runstate = currentRunState; - dispatch((short) interruptVector); // must ignore halt + lastOpcode = interruptVector & 0xFF; + dispatch(); // must ignore halt if (currentRunState == RunState.STATE_STOPPED_NORMAL) { currentRunState = old_runstate; } @@ -491,23 +489,23 @@ private void incrementR() { } - int I_NOP(short OP) { + int I_NOP() { return 4; } - int I_LD_REF_BC_A(short OP) { + int I_LD_REF_BC_A() { memory.write(getpair(0, false), (byte) regs[REG_A]); return 7; } - int I_INC_RP(short OP) { - int tmp = (OP >>> 4) & 0x03; + int I_INC_RP() { + int tmp = (lastOpcode >>> 4) & 0x03; putpair(tmp, (getpair(tmp, true) + 1) & 0xFFFF, true); return 6; } - int I_ADD_HL_RP(short OP) { - int tmp = getpair((OP >>> 4) & 0x03, true); + int I_ADD_HL_RP() { + int tmp = getpair((lastOpcode >>> 4) & 0x03, true); int tmp1 = getpair(2, true); carry15(tmp, tmp1); halfCarry11(tmp, tmp1); @@ -520,30 +518,30 @@ int I_ADD_HL_RP(short OP) { return 11; } - int I_DEC_RP(short OP) { - int regPair = (OP >>> 4) & 0x03; + int I_DEC_RP() { + int regPair = (lastOpcode >>> 4) & 0x03; putpair(regPair, (getpair(regPair, true) - 1) & 0xFFFF, true); return 6; } - int I_POP_RP(short OP) { - int regPair = (OP >>> 4) & 0x03; + int I_POP_RP() { + int regPair = (lastOpcode >>> 4) & 0x03; int value = readWord(SP); SP = (SP + 2) & 0xffff; putpair(regPair, value, false); return 10; } - int I_PUSH_RP(short OP) { - int regPair = (OP >>> 4) & 0x03; + int I_PUSH_RP() { + int regPair = (lastOpcode >>> 4) & 0x03; int value = getpair(regPair, false); SP = (SP - 2) & 0xffff; writeWord(SP, value); return 11; } - int I_LD_R_N(short OP) { - int reg = (OP >>> 3) & 0x07; + int I_LD_R_N() { + int reg = (lastOpcode >>> 3) & 0x07; putreg(reg, memory.read(PC)); PC = (PC + 1) & 0xFFFF; if (reg == 6) { @@ -553,24 +551,24 @@ int I_LD_R_N(short OP) { } } - int I_INC_R(short OP) { - int reg = (OP >>> 3) & 0x07; + int I_INC_R() { + int reg = (lastOpcode >>> 3) & 0x07; int value = (getreg(reg) + 1) & 0xFF; flags = EmulatorTables.INC_TABLE[value] | (flags & FLAG_C); putreg(reg, value); return (reg == 6) ? 11 : 4; } - int I_DEC_R(short OP) { - int reg = (OP >>> 3) & 0x07; + int I_DEC_R() { + int reg = (lastOpcode >>> 3) & 0x07; int value = (getreg(reg) - 1) & 0xFF; flags = EmulatorTables.DEC_TABLE[value] | (flags & FLAG_C); putreg(reg, value); return (reg == 6) ? 11 : 4; } - int I_RET_CC(short OP) { - int cc = (OP >>> 3) & 7; + int I_RET_CC() { + int cc = (lastOpcode >>> 3) & 7; if ((flags & CONDITION[cc]) == CONDITION_VALUES[cc]) { PC = readWord(SP); SP = (SP + 2) & 0xffff; @@ -579,78 +577,78 @@ int I_RET_CC(short OP) { return 5; } - int I_RST(short OP) { + int I_RST() { SP = (SP - 2) & 0xffff; writeWord(SP, PC); - PC = OP & 0x38; + PC = lastOpcode & 0x38; return 11; } - int I_ADD_A_R(short OP) { - int value = getreg(OP & 0x07); + int I_ADD_A_R() { + int value = getreg(lastOpcode & 0x07); int oldA = regs[REG_A]; regs[REG_A] = (oldA + value) & 0xFF; flags = flagSZHPC(oldA, value, regs[REG_A]); - return (OP == 0x86) ? 7 : 4; + return (lastOpcode == 0x86) ? 7 : 4; } - int I_ADC_A_R(short OP) { - int value = getreg(OP & 0x07); + int I_ADC_A_R() { + int value = getreg(lastOpcode & 0x07); int oldA = regs[REG_A]; regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; flags = flagSZHPC(oldA, (value + (flags & FLAG_C)) & 0xFF, regs[REG_A]); - return (OP == 0x8E) ? 7 : 4; + return (lastOpcode == 0x8E) ? 7 : 4; } - int I_SUB_R(short OP) { - int value = ((~getreg(OP & 0x07)) + 1) & 0xFF; + int I_SUB_R() { + int value = ((~getreg(lastOpcode & 0x07)) + 1) & 0xFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value) & 0xFF; flags = flagSZHPC(oldA, value, regs[REG_A]) | FLAG_N; - return (OP == 0x96) ? 7 : 4; + return (lastOpcode == 0x96) ? 7 : 4; } - int I_SBC_A_R(short OP) { - int value = ((~getreg(OP & 0x07)) + 1) & 0xFF; + int I_SBC_A_R() { + int value = ((~getreg(lastOpcode & 0x07)) + 1) & 0xFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value - (flags & FLAG_C)) & 0xFF; flags = flagSZHPC(oldA, (value - (flags & FLAG_C)) & 0xFF, regs[REG_A]) | FLAG_N; - return (OP == 0x9E) ? 7 : 4; + return (lastOpcode == 0x9E) ? 7 : 4; } - int I_AND_R(short OP) { - regs[REG_A] = (regs[REG_A] & getreg(OP & 7)) & 0xFF; + int I_AND_R() { + regs[REG_A] = (regs[REG_A] & getreg(lastOpcode & 7)) & 0xFF; flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; - return (OP == 0xA6) ? 7 : 4; + return (lastOpcode == 0xA6) ? 7 : 4; } - int I_XOR_R(short OP) { - regs[REG_A] = ((regs[REG_A] ^ getreg(OP & 7)) & 0xff); + int I_XOR_R() { + regs[REG_A] = ((regs[REG_A] ^ getreg(lastOpcode & 7)) & 0xff); flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; - return (OP == 0xAE) ? 7 : 4; + return (lastOpcode == 0xAE) ? 7 : 4; } - int I_OR_R(short OP) { - regs[REG_A] = (regs[REG_A] | getreg(OP & 7)) & 0xFF; + int I_OR_R() { + regs[REG_A] = (regs[REG_A] | getreg(lastOpcode & 7)) & 0xFF; flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; - return (OP == 0xB6) ? 7 : 4; + return (lastOpcode == 0xB6) ? 7 : 4; } - int I_CP_R(short OP) { - int value = ((~getreg(OP & 7)) + 1) & 0xFF; + int I_CP_R() { + int value = ((~getreg(lastOpcode & 7)) + 1) & 0xFF; int result = (regs[REG_A] + value) & 0xFF; flags = flagSZHPC(regs[REG_A], value, result) | FLAG_N; - return (OP == 0xBE) ? 7 : 4; + return (lastOpcode == 0xBE) ? 7 : 4; } - int I_RLCA(short OP) { + int I_RLCA() { int tmp = regs[REG_A] >>> 7; regs[REG_A] = ((((regs[REG_A] << 1) & 0xFF) | tmp) & 0xff); flags = ((flags & 0xEC) | tmp); return 4; } - int I_EX_AF_AFF(short OP) { + int I_EX_AF_AFF() { int tmp = regs[REG_A]; regs[REG_A] = regs2[REG_A]; regs2[REG_A] = tmp; @@ -660,18 +658,18 @@ int I_EX_AF_AFF(short OP) { return 4; } - int I_LD_A_REF_BC(short OP) { + int I_LD_A_REF_BC() { regs[REG_A] = readByte(getpair(0, false)); return 7; } - int I_RRCA(short OP) { + int I_RRCA() { flags = ((flags & 0xEC) | (regs[REG_A] & 1)); regs[REG_A] = EmulatorTables.RRCA_TABLE[regs[REG_A]]; return 4; } - int I_DJNZ(short OP) { + int I_DJNZ() { byte tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; regs[REG_B]--; @@ -683,31 +681,31 @@ int I_DJNZ(short OP) { return 8; } - int I_LD_REF_DE_A(short OP) { + int I_LD_REF_DE_A() { memory.write(getpair(1, false), (byte) regs[REG_A]); return 7; } - int I_RLA(short OP) { + int I_RLA() { int tmp = regs[REG_A] >>> 7; regs[REG_A] = (((regs[REG_A] << 1) | (flags & FLAG_C)) & 0xff); flags = ((flags & 0xEC) | tmp); return 4; } - int I_LD_A_REF_DE(short OP) { + int I_LD_A_REF_DE() { regs[REG_A] = readByte(getpair(1, false)); return 7; } - int I_RRA(short OP) { + int I_RRA() { int tmp = (flags & FLAG_C) << 7; flags = ((flags & 0xEC) | (regs[REG_A] & 1)); regs[REG_A] = ((regs[REG_A] >>> 1 | tmp) & 0xff); return 4; } - int I_DAA(short OP) { + int I_DAA() { int temp = regs[REG_A]; boolean acFlag = (flags & FLAG_H) == FLAG_H; boolean cFlag = (flags & FLAG_C) == FLAG_C; @@ -750,19 +748,19 @@ int I_DAA(short OP) { return 4; } - int I_CPL(short OP) { + int I_CPL() { regs[REG_A] = ((~regs[REG_A]) & 0xFF); flags |= FLAG_N | FLAG_H; return 4; } - int I_SCF(short OP) { + int I_SCF() { flags |= FLAG_N | FLAG_C; flags &= ~FLAG_H; return 4; } - int I_CCF(short OP) { + int I_CCF() { int tmp = flags & FLAG_C; if (tmp == 0) { flags |= FLAG_C; @@ -773,13 +771,13 @@ int I_CCF(short OP) { return 4; } - int I_RET(short OP) { + int I_RET() { PC = readWord(SP); SP = (SP + 2) & 0xFFFF; return 10; } - int I_EXX(short OP) { + int I_EXX() { int tmp = regs[REG_B]; regs[REG_B] = regs2[REG_B]; regs2[REG_B] = tmp; @@ -801,7 +799,7 @@ int I_EXX(short OP) { return 4; } - int I_EX_REF_SP_HL(short OP) { + int I_EX_REF_SP_HL() { byte tmp = memory.read(SP); int x = (SP + 1) & 0xFFFF; byte tmp1 = memory.read(x); @@ -812,12 +810,12 @@ int I_EX_REF_SP_HL(short OP) { return 19; } - int I_JP_REF_HL(short OP) { + int I_JP_REF_HL() { PC = ((regs[REG_H] << 8) | regs[REG_L]); return 4; } - int I_EX_DE_HL(short OP) { + int I_EX_DE_HL() { int tmp = regs[REG_D]; regs[REG_D] = regs[REG_H]; regs[REG_H] = tmp; @@ -827,36 +825,36 @@ int I_EX_DE_HL(short OP) { return 4; } - int I_DI(short OP) { + int I_DI() { IFF[0] = IFF[1] = false; return 4; } - int I_LD_SP_HL(short OP) { + int I_LD_SP_HL() { SP = ((regs[REG_H] << 8) | regs[REG_L]); return 6; } - int I_EI(short OP) { + int I_EI() { IFF[0] = IFF[1] = true; return 4; } - int I_IN_R_REF_C(short OP) throws IOException { - int tmp = (OP >>> 3) & 0x7; + int I_IN_R_REF_C() throws IOException { + int tmp = (lastOpcode >>> 3) & 0x7; putreg(tmp, context.readIO(regs[REG_C])); flags = (flags & FLAG_C) | EmulatorTables.SIGN_ZERO_TABLE[regs[tmp]] | EmulatorTables.PARITY_TABLE[regs[tmp]]; return 12; } - int I_OUT_REF_C_R(short OP) throws IOException { - int tmp = (OP >>> 3) & 0x7; + int I_OUT_REF_C_R() throws IOException { + int tmp = (lastOpcode >>> 3) & 0x7; context.writeIO(regs[REG_C], (byte) getreg(tmp)); return 12; } - int I_SBC_HL_RP(short OP) { - int tmp = -getpair((OP >>> 4) & 0x03, true); + int I_SBC_HL_RP() { + int tmp = -getpair((lastOpcode >>> 4) & 0x03, true); int tmp1 = getpair(2, true); if ((flags & FLAG_C) == FLAG_C) { tmp--; @@ -885,8 +883,8 @@ int I_SBC_HL_RP(short OP) { return 15; } - int I_ADC_HL_RP(short OP) { - int tmp = getpair((OP >>> 4) & 0x03, true); + int I_ADC_HL_RP() { + int tmp = getpair((lastOpcode >>> 4) & 0x03, true); int tmp1 = getpair(2, true); if ((flags & FLAG_C) == FLAG_C) { tmp++; @@ -914,64 +912,64 @@ int I_ADC_HL_RP(short OP) { return 11; } - int I_NEG(short OP) { + int I_NEG() { flags = EmulatorTables.NEG_TABLE[regs[REG_A]] & 0xFF; regs[REG_A] = (EmulatorTables.NEG_TABLE[regs[REG_A]] >>> 8) & 0xFF; return 8; } - int I_RETN(short OP) { + int I_RETN() { IFF[0] = IFF[1]; PC = readWord(SP); SP = (SP + 2) & 0xffff; return 14; } - int I_IM_0(short OP) { + int I_IM_0() { intMode = 0; return 8; } - int I_LD_I_A(short OP) { + int I_LD_I_A() { I = regs[REG_A]; return 9; } - int I_RETI(short OP) { + int I_RETI() { IFF[0] = IFF[1]; PC = readWord(SP); SP = (SP + 2) & 0xffff; return 14; } - int I_LD_R_A(short OP) { + int I_LD_R_A() { R = regs[REG_A]; return 9; } - int I_IM_1(short OP) { + int I_IM_1() { intMode = 1; return 8; } - int I_LD_A_I(short OP) { + int I_LD_A_I() { regs[REG_A] = I & 0xFF; flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C); return 9; } - int I_IM_2(short OP) { + int I_IM_2() { intMode = 2; return 8; } - int I_LD_A_R(short OP) { + int I_LD_A_R() { regs[REG_A] = R & 0xFF; flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C); return 9; } - int I_RRD(short OP) { + int I_RRD() { int tmp = regs[REG_A] & 0x0F; int tmp1 = memory.read((regs[REG_H] << 8) | regs[REG_L]); regs[REG_A] = ((regs[REG_A] & 0xF0) | (tmp1 & 0x0F)); @@ -981,7 +979,7 @@ int I_RRD(short OP) { return 18; } - int I_RLD(short OP) { + int I_RLD() { int tmp = memory.read((regs[REG_H] << 8) | regs[REG_L]); int tmp1 = (tmp >>> 4) & 0x0F; tmp = ((tmp << 4) & 0xF0) | (regs[REG_A] & 0x0F); @@ -991,18 +989,18 @@ int I_RLD(short OP) { return 18; } - int I_IN_REF_C(short OP) throws IOException { + int I_IN_REF_C() throws IOException { int tmp = (context.readIO(regs[REG_C]) & 0xFF); flags = EmulatorTables.SIGN_ZERO_TABLE[tmp] | EmulatorTables.PARITY_TABLE[tmp] | (flags & FLAG_C); return 12; } - int I_OUT_REF_C_0(short OP) throws IOException { + int I_OUT_REF_C_0() throws IOException { context.writeIO(regs[REG_C], (byte) 0); return 12; } - int I_LDI(short OP) { + int I_LDI() { int tmp1 = getpair(2, false); int tmp2 = getpair(1, false); int tmp = getpair(0, false); @@ -1026,7 +1024,7 @@ int I_LDI(short OP) { return 16; } - int I_CPI(short OP) { + int I_CPI() { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_B] << 8) | regs[REG_C]; @@ -1048,7 +1046,7 @@ int I_CPI(short OP) { return 16; } - int I_LDD(short OP) { + int I_LDD() { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_D] << 8) | regs[REG_E]; int tmp = (regs[REG_B] << 8) | regs[REG_C]; @@ -1072,7 +1070,7 @@ int I_LDD(short OP) { return 16; } - int I_CPD(short OP) { + int I_CPD() { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_B] << 8) | regs[REG_C]; @@ -1094,7 +1092,7 @@ int I_CPD(short OP) { return 16; } - int I_LDIR(short OP) { + int I_LDIR() { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_D] << 8) | regs[REG_E]; int tmp = (regs[REG_B] << 8) | regs[REG_C]; @@ -1121,7 +1119,7 @@ int I_LDIR(short OP) { return 21; } - int I_CPIR(short OP) { + int I_CPIR() { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_B] << 8) | regs[REG_C]; @@ -1148,7 +1146,7 @@ int I_CPIR(short OP) { return 21; } - int I_INI(short OP) throws IOException { + int I_INI() throws IOException { byte value = context.readIO(regs[REG_C]); int address = (regs[REG_H] << 8) | regs[REG_L]; memory.write(address, value); @@ -1163,7 +1161,7 @@ int I_INI(short OP) throws IOException { return 16; } - int I_INIR(short OP) throws IOException { + int I_INIR() throws IOException { byte value = context.readIO(regs[REG_C]); int address = (regs[REG_H] << 8) | regs[REG_L]; memory.write(address, value); @@ -1183,7 +1181,7 @@ int I_INIR(short OP) throws IOException { return 21; } - int I_IND(short OP) throws IOException { + int I_IND() throws IOException { byte value = context.readIO(regs[REG_C]); int address = (regs[REG_H] << 8) | regs[REG_L]; memory.write(address, value); @@ -1198,7 +1196,7 @@ int I_IND(short OP) throws IOException { return 16; } - int I_INDR(short OP) throws IOException { + int I_INDR() throws IOException { byte value = context.readIO(regs[REG_C]); int address = (regs[REG_H] << 8) | regs[REG_L]; memory.write(address, value); @@ -1218,7 +1216,7 @@ int I_INDR(short OP) throws IOException { return 21; } - int I_OUTI(short OP) throws IOException { + int I_OUTI() throws IOException { int address = (regs[REG_H] << 8) | regs[REG_L]; byte value = memory.read(address); context.writeIO(regs[REG_C], value); @@ -1232,7 +1230,7 @@ int I_OUTI(short OP) throws IOException { return 16; } - int I_OTIR(short OP) throws IOException { + int I_OTIR() throws IOException { int address = (regs[REG_H] << 8) | regs[REG_L]; byte value = memory.read(address); context.writeIO(regs[REG_C], value); @@ -1251,7 +1249,7 @@ int I_OTIR(short OP) throws IOException { return 21; } - int I_OUTD(short OP) throws IOException { + int I_OUTD() throws IOException { int address = (regs[REG_H] << 8) | regs[REG_L]; byte value = memory.read(address); context.writeIO(regs[REG_C], value); @@ -1265,7 +1263,7 @@ int I_OUTD(short OP) throws IOException { return 16; } - int I_OTDR(short OP) throws IOException { + int I_OTDR() throws IOException { int address = (regs[REG_H] << 8) | regs[REG_L]; byte value = memory.read(address); context.writeIO(regs[REG_C], value); @@ -1284,7 +1282,7 @@ int I_OTDR(short OP) throws IOException { return 21; } - int I_LDDR(short OP) { + int I_LDDR() { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_D] << 8) | regs[REG_E]; memory.write(tmp2, memory.read(tmp1)); @@ -1307,7 +1305,7 @@ int I_LDDR(short OP) { return 21; } - int I_CPDR(short OP) { + int I_CPDR() { int hl = (regs[REG_H] << 8) | regs[REG_L]; int bc = (regs[REG_B] << 8) | regs[REG_C]; @@ -1334,29 +1332,29 @@ int I_CPDR(short OP) { return 21; } - int I_LD_REF_NN_RP(short OP) { + int I_LD_REF_NN_RP() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; - int tmp1 = getpair((OP >>> 4) & 3, true); + int tmp1 = getpair((lastOpcode >>> 4) & 3, true); writeWord(tmp, tmp1); return 20; } - int I_LD_RP_REF_NN(short OP) { + int I_LD_RP_REF_NN() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; int tmp1 = readWord(tmp); - putpair((OP >>> 4) & 3, tmp1, true); + putpair((lastOpcode >>> 4) & 3, tmp1, true); return 20; } - int I_JR_CC_N(short OP) { + int I_JR_CC_N() { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - if (getCC1((OP >>> 3) & 3)) { + if (getCC1((lastOpcode >>> 3) & 3)) { PC += (byte) tmp; PC &= 0xFFFF; return 12; @@ -1364,7 +1362,7 @@ int I_JR_CC_N(short OP) { return 7; } - int I_JR_N(short OP) { + int I_JR_N() { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; @@ -1373,7 +1371,7 @@ int I_JR_N(short OP) { return 12; } - int I_ADD_A_N(short OP) { + int I_ADD_A_N() { int value = readByte(PC); PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; @@ -1382,7 +1380,7 @@ int I_ADD_A_N(short OP) { return 7; } - int I_ADC_A_N(short OP) { + int I_ADC_A_N() { int value = readByte(PC); PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; @@ -1391,14 +1389,14 @@ int I_ADC_A_N(short OP) { return 7; } - int I_OUT_REF_N_A(short OP) throws IOException { + int I_OUT_REF_N_A() throws IOException { int tmp = readByte(PC); PC = (PC + 1) & 0xFFFF; context.writeIO(tmp, (byte) regs[REG_A]); return 11; } - int I_SUB_N(short OP) { + int I_SUB_N() { int value = ((~memory.read(PC)) + 1) & 0xFF; PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; @@ -1407,14 +1405,14 @@ int I_SUB_N(short OP) { return 7; } - int I_IN_A_REF_N(short OP) throws IOException { + int I_IN_A_REF_N() throws IOException { int tmp = readByte(PC); PC = (PC + 1) & 0xFFFF; regs[REG_A] = (context.readIO(tmp) & 0xFF); return 11; } - int I_SBC_A_N(short OP) { + int I_SBC_A_N() { int value = ((~readByte(PC)) + 1) & 0xFF; PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; @@ -1423,7 +1421,7 @@ int I_SBC_A_N(short OP) { return 7; } - int I_AND_N(short OP) { + int I_AND_N() { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; @@ -1432,7 +1430,7 @@ int I_AND_N(short OP) { return 7; } - int I_XOR_N(short OP) { + int I_XOR_N() { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; @@ -1441,7 +1439,7 @@ int I_XOR_N(short OP) { return 7; } - int I_OR_N(short OP) { + int I_OR_N() { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; @@ -1450,7 +1448,7 @@ int I_OR_N(short OP) { return 7; } - int I_CP_N(short OP) { + int I_CP_N() { int value = ((~readByte(PC)) + 1) & 0xFF; PC = (PC + 1) & 0xFFFF; int diff = (regs[REG_A] + value) & 0xFF; @@ -1458,30 +1456,30 @@ int I_CP_N(short OP) { return 7; } - int I_LD_RP_NN(short OP) { + int I_LD_RP_NN() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; - putpair((OP >>> 4) & 3, tmp, true); + putpair((lastOpcode >>> 4) & 3, tmp, true); return 10; } - int I_JP_CC_NN(short OP) { + int I_JP_CC_NN() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; - int tmp1 = (OP >>> 3) & 7; + int tmp1 = (lastOpcode >>> 3) & 7; if ((flags & CONDITION[tmp1]) == CONDITION_VALUES[tmp1]) { PC = tmp; } return 10; } - int I_CALL_CC_NN(short OP) { + int I_CALL_CC_NN() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; - int tmp1 = (OP >>> 3) & 7; + int tmp1 = (lastOpcode >>> 3) & 7; if ((flags & CONDITION[tmp1]) == CONDITION_VALUES[tmp1]) { SP = (SP - 2) & 0xffff; writeWord(SP, PC); @@ -1491,7 +1489,7 @@ int I_CALL_CC_NN(short OP) { return 10; } - int I_LD_REF_NN_HL(short OP) { + int I_LD_REF_NN_HL() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1500,7 +1498,7 @@ int I_LD_REF_NN_HL(short OP) { return 16; } - int I_LD_HL_REF_NN(short OP) { + int I_LD_HL_REF_NN() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1509,7 +1507,7 @@ int I_LD_HL_REF_NN(short OP) { return 16; } - int I_LD_REF_NN_A(short OP) { + int I_LD_REF_NN_A() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1517,7 +1515,7 @@ int I_LD_REF_NN_A(short OP) { return 13; } - int I_LD_A_REF_NN(short OP) { + int I_LD_A_REF_NN() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1525,12 +1523,12 @@ int I_LD_A_REF_NN(short OP) { return 13; } - int I_JP_NN(short OP) { + int I_JP_NN() { PC = readWord(PC); return 10; } - int I_CALL_NN(short OP) { + int I_CALL_NN() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; SP = (SP - 2) & 0xffff; @@ -1539,9 +1537,9 @@ int I_CALL_NN(short OP) { return 17; } - int I_LD_R_R(short OP) { - int tmp = (OP >>> 3) & 0x07; - int tmp1 = OP & 0x07; + int I_LD_R_R() { + int tmp = (lastOpcode >>> 3) & 0x07; + int tmp1 = lastOpcode & 0x07; putreg(tmp, getreg(tmp1)); if ((tmp1 == 6) || (tmp == 6)) { return 7; @@ -1550,13 +1548,13 @@ int I_LD_R_R(short OP) { } } - int I_HALT(short OP) { + int I_HALT() { currentRunState = RunState.STATE_STOPPED_NORMAL; return 4; } - int I_RLC_R(short OP) { - int tmp = OP & 7; + int I_RLC_R() { + int tmp = lastOpcode & 7; int tmp1 = getreg(tmp) & 0xFF; int tmp2 = (tmp1 >>> 7) & 1; @@ -1572,8 +1570,8 @@ int I_RLC_R(short OP) { } } - int I_RRC_R(short OP) { - int tmp = OP & 7; + int I_RRC_R() { + int tmp = lastOpcode & 7; int tmp1 = getreg(tmp) & 0xFF; int tmp2 = tmp1 & 1; @@ -1589,8 +1587,8 @@ int I_RRC_R(short OP) { } } - int I_RL_R(short OP) { - int tmp = OP & 7; + int I_RL_R() { + int tmp = lastOpcode & 7; int tmp1 = getreg(tmp) & 0xFF; int tmp2 = (tmp1 >>> 7) & 1; @@ -1606,8 +1604,8 @@ int I_RL_R(short OP) { } } - int I_RR_R(short OP) { - int tmp = OP & 7; + int I_RR_R() { + int tmp = lastOpcode & 7; int tmp1 = getreg(tmp) & 0xFF; int tmp2 = tmp1 & 1; @@ -1623,8 +1621,8 @@ int I_RR_R(short OP) { } } - int I_SLA_R(short OP) { - int tmp = OP & 7; + int I_SLA_R() { + int tmp = lastOpcode & 7; int tmp1 = getreg(tmp) & 0xFF; int tmp2 = (tmp1 >>> 7) & 1; @@ -1640,8 +1638,8 @@ int I_SLA_R(short OP) { } } - int I_SRA_R(short OP) { - int tmp = OP & 7; + int I_SRA_R() { + int tmp = lastOpcode & 7; int tmp1 = getreg(tmp) & 0xFF; int tmp2 = tmp1 & 1; @@ -1657,8 +1655,8 @@ int I_SRA_R(short OP) { } } - int I_SLL_R(short OP) { - int tmp = OP & 7; + int I_SLL_R() { + int tmp = lastOpcode & 7; int tmp1 = getreg(tmp) & 0xFF; int tmp2 = (tmp1 >>> 7) & 1; @@ -1674,8 +1672,8 @@ int I_SLL_R(short OP) { } } - int I_SRL_R(short OP) { - int tmp = OP & 7; + int I_SRL_R() { + int tmp = lastOpcode & 7; int tmp1 = getreg(tmp) & 0xFF; int tmp2 = tmp1 & 1; @@ -1692,9 +1690,9 @@ int I_SRL_R(short OP) { } - int I_BIT_N_R(short OP) { - int tmp = (OP >>> 3) & 7; - int tmp2 = OP & 7; + int I_BIT_N_R() { + int tmp = (lastOpcode >>> 3) & 7; + int tmp2 = lastOpcode & 7; int tmp1 = getreg(tmp2) & 0xFF; flags = ((flags & FLAG_C) | FLAG_H | (((tmp1 & (1 << tmp)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); if (tmp == 7) { @@ -1707,9 +1705,9 @@ int I_BIT_N_R(short OP) { } } - int I_RES_N_R(short OP) { - int tmp = (OP >>> 3) & 7; - int tmp2 = OP & 7; + int I_RES_N_R() { + int tmp = (lastOpcode >>> 3) & 7; + int tmp2 = lastOpcode & 7; int tmp1 = getreg(tmp2) & 0xFF; tmp1 = (tmp1 & (~(1 << tmp))); putreg(tmp2, tmp1); @@ -1720,9 +1718,9 @@ int I_RES_N_R(short OP) { } } - int I_SET_N_R(short OP) { - int tmp = (OP >>> 3) & 7; - int tmp2 = OP & 7; + int I_SET_N_R() { + int tmp = (lastOpcode >>> 3) & 7; + int tmp2 = lastOpcode & 7; int tmp1 = getreg(tmp2) & 0xFF; tmp1 = (tmp1 | (1 << tmp)); putreg(tmp2, tmp1); @@ -1733,20 +1731,20 @@ int I_SET_N_R(short OP) { } } - int I_ADD_IX_RP(short OP) { - IX = I_ADD_II_RP(OP, IX); + int I_ADD_IX_RP() { + IX = I_ADD_II_RP(IX); return 15; } - int I_ADD_IY_RP(short OP) { - IY = I_ADD_II_RP(OP, IY); + int I_ADD_IY_RP() { + IY = I_ADD_II_RP(IY); return 15; } - int I_ADD_II_RP(short OP, int special) { + int I_ADD_II_RP(int special) { int tmp = special; int pair; - int reg = (OP >>> 4) & 0x03; + int reg = (lastOpcode >>> 4) & 0x03; switch (reg) { case 3: pair = SP; @@ -1769,49 +1767,49 @@ int I_ADD_II_RP(short OP, int special) { return tmp & 0xFFFF; } - int I_LD_IX_NN(short OP) { + int I_LD_IX_NN() { IX = readWord(PC); PC = (PC + 2) & 0xFFFF; return 14; } - int I_LD_IY_NN(short OP) { + int I_LD_IY_NN() { IY = readWord(PC); PC = (PC + 2) & 0xFFFF; return 14; } - int I_LD_REF_NN_IX(short OP) { - return I_LD_REF_NN_II(OP, IX); + int I_LD_REF_NN_IX() { + return I_LD_REF_NN_II(IX); } - int I_LD_REF_NN_IY(short OP) { - return I_LD_REF_NN_II(OP, IY); + int I_LD_REF_NN_IY() { + return I_LD_REF_NN_II(IY); } - int I_LD_REF_NN_II(short OP, int special) { + int I_LD_REF_NN_II(int special) { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; writeWord(tmp, special); return 16; } - int I_INC_IX(short OP) { + int I_INC_IX() { IX = (IX + 1) & 0xFFFF; return 10; } - int I_INC_IY(short OP) { + int I_INC_IY() { IY = (IY + 1) & 0xFFFF; return 10; } - int I_LD_IX_REF_NN(short OP) { + int I_LD_IX_REF_NN() { IX = I_LD_II_REF_NN(); return 20; } - int I_LD_IY_REF_NN(short OP) { + int I_LD_IY_REF_NN() { IY = I_LD_II_REF_NN(); return 20; } @@ -1822,25 +1820,25 @@ int I_LD_II_REF_NN() { return readWord(tmp); } - int I_DEC_IX(short OP) { + int I_DEC_IX() { IX = (IX - 1) & 0xFFFF; return 10; } - int I_DEC_IY(short OP) { + int I_DEC_IY() { IY = (IY - 1) & 0xFFFF; return 10; } - int I_INC_REF_IX_N(short OP) { - return I_INC_REF_II_N(OP, IX); + int I_INC_REF_IX_N() { + return I_INC_REF_II_N(IX); } - int I_INC_REF_IY_N(short OP) { - return I_INC_REF_II_N(OP, IY); + int I_INC_REF_IY_N() { + return I_INC_REF_II_N(IY); } - int I_INC_REF_II_N(short OP, int special) { + int I_INC_REF_II_N(int special) { byte tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; int tmp1 = (special + tmp) & 0xFFFF; @@ -1851,15 +1849,15 @@ int I_INC_REF_II_N(short OP, int special) { return 23; } - int I_DEC_REF_IX_N(short OP) { - return I_DEC_REF_II_N(OP, IX); + int I_DEC_REF_IX_N() { + return I_DEC_REF_II_N(IX); } - int I_DEC_REF_IY_N(short OP) { - return I_DEC_REF_II_N(OP, IY); + int I_DEC_REF_IY_N() { + return I_DEC_REF_II_N(IY); } - int I_DEC_REF_II_N(short OP, int special) { + int I_DEC_REF_II_N(int special) { int tmp = readByte(PC); PC = (PC + 1) & 0xFFFF; int tmp1 = (special + (byte) tmp) & 0xFFFF; @@ -1869,15 +1867,15 @@ int I_DEC_REF_II_N(short OP, int special) { return 23; } - int I_LD_REF_IX_N_N(short OP) { - return I_LD_REF_II_N_N(OP, IX); + int I_LD_REF_IX_N_N() { + return I_LD_REF_II_N_N(IX); } - int I_LD_REF_IY_N_N(short OP) { - return I_LD_REF_II_N_N(OP, IY); + int I_LD_REF_IY_N_N() { + return I_LD_REF_II_N_N(IY); } - int I_LD_REF_II_N_N(short OP, int special) { + int I_LD_REF_II_N_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; byte number = memory.read(PC); @@ -1886,46 +1884,46 @@ int I_LD_REF_II_N_N(short OP, int special) { return 19; } - int I_LD_R_REF_IX_N(short OP) { - return I_LD_R_REF_II_N(OP, IX); + int I_LD_R_REF_IX_N() { + return I_LD_R_REF_II_N(IX); } - int I_LD_R_REF_IY_N(short OP) { - return I_LD_R_REF_II_N(OP, IY); + int I_LD_R_REF_IY_N() { + return I_LD_R_REF_II_N(IY); } - int I_LD_R_REF_II_N(short OP, int special) { + int I_LD_R_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = (OP >>> 3) & 7; + int tmp1 = (lastOpcode >>> 3) & 7; putreg(tmp1, memory.read((special + offset) & 0xFFFF)); return 19; } - int I_LD_REF_IX_N_R(short OP) { - return I_LD_REF_II_N_R(OP, IX); + int I_LD_REF_IX_N_R() { + return I_LD_REF_II_N_R(IX); } - int I_LD_REF_IY_N_R(short OP) { - return I_LD_REF_II_N_R(OP, IY); + int I_LD_REF_IY_N_R() { + return I_LD_REF_II_N_R(IY); } - int I_LD_REF_II_N_R(short OP, int special) { + int I_LD_REF_II_N_R(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - memory.write((special + offset) & 0xFFFF, (byte) getreg(OP & 7)); + memory.write((special + offset) & 0xFFFF, (byte) getreg(lastOpcode & 7)); return 19; } - int I_ADD_A_REF_IX_N(short OP) { - return I_ADD_A_REF_II_N(OP, IX); + int I_ADD_A_REF_IX_N() { + return I_ADD_A_REF_II_N(IX); } - int I_ADD_A_REF_IY_N(short OP) { - return I_ADD_A_REF_II_N(OP, IY); + int I_ADD_A_REF_IY_N() { + return I_ADD_A_REF_II_N(IY); } - int I_ADD_A_REF_II_N(short OP, int special) { + int I_ADD_A_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; int value = readByte((special + offset) & 0xFFFF); @@ -1935,15 +1933,15 @@ int I_ADD_A_REF_II_N(short OP, int special) { return 19; } - int I_ADC_A_REF_IX_N(short OP) { - return I_ADC_A_REF_II_N(OP, IX); + int I_ADC_A_REF_IX_N() { + return I_ADC_A_REF_II_N(IX); } - int I_ADC_A_REF_IY_N(short OP) { - return I_ADC_A_REF_II_N(OP, IY); + int I_ADC_A_REF_IY_N() { + return I_ADC_A_REF_II_N(IY); } - int I_ADC_A_REF_II_N(short OP, int special) { + int I_ADC_A_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; int value = readByte((special + offset) & 0xFFFF); @@ -1953,15 +1951,15 @@ int I_ADC_A_REF_II_N(short OP, int special) { return 19; } - int I_SUB_REF_IX_N(short OP) { - return I_SUB_REF_II_N(OP, IX); + int I_SUB_REF_IX_N() { + return I_SUB_REF_II_N(IX); } - int I_SUB_REF_IY_N(short OP) { - return I_SUB_REF_II_N(OP, IY); + int I_SUB_REF_IY_N() { + return I_SUB_REF_II_N(IY); } - int I_SUB_REF_II_N(short OP, int special) { + int I_SUB_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; @@ -1971,15 +1969,15 @@ int I_SUB_REF_II_N(short OP, int special) { return 19; } - int I_SBC_A_REF_IX_N(short OP) { - return I_SBC_A_REF_II_N(OP, IX); + int I_SBC_A_REF_IX_N() { + return I_SBC_A_REF_II_N(IX); } - int I_SBC_A_REF_IY_N(short OP) { - return I_SBC_A_REF_II_N(OP, IY); + int I_SBC_A_REF_IY_N() { + return I_SBC_A_REF_II_N(IY); } - int I_SBC_A_REF_II_N(short OP, int special) { + int I_SBC_A_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; @@ -1989,15 +1987,15 @@ int I_SBC_A_REF_II_N(short OP, int special) { return 19; } - int I_AND_REF_IX_N(short OP) { - return I_AND_REF_II_N(OP, IX); + int I_AND_REF_IX_N() { + return I_AND_REF_II_N(IX); } - int I_AND_REF_IY_N(short OP) { - return I_AND_REF_II_N(OP, IY); + int I_AND_REF_IY_N() { + return I_AND_REF_II_N(IY); } - int I_AND_REF_II_N(short OP, int special) { + int I_AND_REF_II_N(int special) { byte tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; @@ -2007,15 +2005,15 @@ int I_AND_REF_II_N(short OP, int special) { return 19; } - int I_XOR_REF_IX_N(short OP) { - return I_XOR_REF_II_N(OP, IX); + int I_XOR_REF_IX_N() { + return I_XOR_REF_II_N(IX); } - int I_XOR_REF_IY_N(short OP) { - return I_XOR_REF_II_N(OP, IY); + int I_XOR_REF_IY_N() { + return I_XOR_REF_II_N(IY); } - int I_XOR_REF_II_N(short OP, int special) { + int I_XOR_REF_II_N(int special) { byte tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; @@ -2025,15 +2023,15 @@ int I_XOR_REF_II_N(short OP, int special) { return 19; } - int I_OR_REF_IX_N(short OP) { - return I_OR_REF_II_N(OP, IX); + int I_OR_REF_IX_N() { + return I_OR_REF_II_N(IX); } - int I_OR_REF_IY_N(short OP) { - return I_OR_REF_II_N(OP, IY); + int I_OR_REF_IY_N() { + return I_OR_REF_II_N(IY); } - int I_OR_REF_II_N(short OP, int special) { + int I_OR_REF_II_N(int special) { byte tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; int tmp1 = memory.read((special + tmp) & 0xFFFF); @@ -2042,15 +2040,15 @@ int I_OR_REF_II_N(short OP, int special) { return 19; } - int I_CP_REF_IX_N(short OP) { - return I_CP_REF_II_N(OP, IX); + int I_CP_REF_IX_N() { + return I_CP_REF_II_N(IX); } - int I_CP_REF_IY_N(short OP) { - return I_CP_REF_II_N(OP, IY); + int I_CP_REF_IY_N() { + return I_CP_REF_II_N(IY); } - int I_CP_REF_II_N(short OP, int special) { + int I_CP_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; @@ -2059,19 +2057,19 @@ int I_CP_REF_II_N(short OP, int special) { return 19; } - int I_POP_IX(short OP) { + int I_POP_IX() { IX = readWord(SP); SP = (SP + 2) & 0xFFFF; return 14; } - int I_POP_IY(short OP) { + int I_POP_IY() { IY = readWord(SP); SP = (SP + 2) & 0xFFFF; return 14; } - int I_EX_REF_SP_IX(short OP) { + int I_EX_REF_SP_IX() { int tmp = readWord(SP); int tmp1 = IX; IX = tmp; @@ -2079,7 +2077,7 @@ int I_EX_REF_SP_IX(short OP) { return 23; } - int I_EX_REF_SP_IY(short OP) { + int I_EX_REF_SP_IY() { int tmp = readWord(SP); int tmp1 = IY; IY = tmp; @@ -2087,47 +2085,47 @@ int I_EX_REF_SP_IY(short OP) { return 23; } - int I_PUSH_IX(short OP) { + int I_PUSH_IX() { SP = (SP - 2) & 0xFFFF; writeWord(SP, IX); return 15; } - int I_PUSH_IY(short OP) { + int I_PUSH_IY() { SP = (SP - 2) & 0xFFFF; writeWord(SP, IY); return 15; } - int I_JP_REF_IX(short OP) { + int I_JP_REF_IX() { PC = IX; return 8; } - int I_JP_REF_IY(short OP) { + int I_JP_REF_IY() { PC = IY; return 8; } - int I_LD_SP_IX(short OP) { + int I_LD_SP_IX() { SP = IX; return 10; } - int I_LD_SP_IY(short OP) { + int I_LD_SP_IY() { SP = IY; return 10; } - int I_RLC_REF_IX_N_R(short OP, byte operand) { - return I_RLC_REF_II_N_R(OP, operand, IX); + int I_RLC_REF_IX_N_R(byte operand) { + return I_RLC_REF_II_N_R(operand, IX); } - int I_RLC_REF_IY_N_R(short OP, byte operand) { - return I_RLC_REF_II_N_R(OP, operand, IY); + int I_RLC_REF_IY_N_R(byte operand) { + return I_RLC_REF_II_N_R(operand, IY); } - int I_RLC_REF_II_N_R(short OP, byte operand, int special) { + int I_RLC_REF_II_N_R(byte operand, int special) { int address = (special + operand) & 0xFFFF; int value = readByte(address); int bit7 = (value >>> 7) & 1; @@ -2137,19 +2135,19 @@ int I_RLC_REF_II_N_R(short OP, byte operand, int special) { flags = EmulatorTables.SIGN_ZERO_TABLE[value] | EmulatorTables.PARITY_TABLE[value] | bit7; // regs[6] is unused, so it's ok - regs[OP & 7] = value & 0xFF; + regs[lastOpcode & 7] = value & 0xFF; return 23; } - int I_RRC_REF_IX_N_R(short OP, byte operand) { - return I_RRC_REF_II_N_R(OP, operand, IX); + int I_RRC_REF_IX_N_R(byte operand) { + return I_RRC_REF_II_N_R(operand, IX); } - int I_RRC_REF_IY_N_R(short OP, byte operand) { - return I_RRC_REF_II_N_R(OP, operand, IY); + int I_RRC_REF_IY_N_R(byte operand) { + return I_RRC_REF_II_N_R(operand, IY); } - int I_RRC_REF_II_N_R(short OP, byte operand, int special) { + int I_RRC_REF_II_N_R(byte operand, int special) { int tmp = (special + operand) & 0xffff; int tmp1 = memory.read(tmp); @@ -2160,19 +2158,19 @@ int I_RRC_REF_II_N_R(short OP, byte operand, int special) { flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok - regs[OP & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; } - int I_RL_REF_IX_N_R(short OP, byte operand) { - return I_RL_REF_II_N_R(OP, operand, IX); + int I_RL_REF_IX_N_R(byte operand) { + return I_RL_REF_II_N_R(operand, IX); } - int I_RL_REF_IY_N_R(short OP, byte operand) { - return I_RL_REF_II_N_R(OP, operand, IY); + int I_RL_REF_IY_N_R(byte operand) { + return I_RL_REF_II_N_R(operand, IY); } - int I_RL_REF_II_N_R(short OP, byte operand, int special) { + int I_RL_REF_II_N_R(byte operand, int special) { int tmp = (special + operand) & 0xffff; int tmp1 = memory.read(tmp); @@ -2182,19 +2180,19 @@ int I_RL_REF_II_N_R(short OP, byte operand, int special) { flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok - regs[OP & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; } - int I_RR_REF_IX_N_R(short OP, byte operand) { - return I_RR_REF_II_N_R(OP, operand, IX); + int I_RR_REF_IX_N_R(byte operand) { + return I_RR_REF_II_N_R(operand, IX); } - int I_RR_REF_IY_N_R(short OP, byte operand) { - return I_RR_REF_II_N_R(OP, operand, IY); + int I_RR_REF_IY_N_R(byte operand) { + return I_RR_REF_II_N_R(operand, IY); } - int I_RR_REF_II_N_R(short OP, byte operand, int special) { + int I_RR_REF_II_N_R(byte operand, int special) { int address = (special + operand) & 0xffff; int value = readByte(address); @@ -2204,19 +2202,19 @@ int I_RR_REF_II_N_R(short OP, byte operand, int special) { flags = EmulatorTables.SIGN_ZERO_TABLE[value] | EmulatorTables.PARITY_TABLE[value] | bit0; // regs[6] is unused, so it's ok - regs[OP & 7] = value & 0xFF; + regs[lastOpcode & 7] = value & 0xFF; return 23; } - int I_SLA_REF_IX_N_R(short OP, byte operand) { - return I_SLA_REF_II_N_R(OP, operand, IX); + int I_SLA_REF_IX_N_R(byte operand) { + return I_SLA_REF_II_N_R(operand, IX); } - int I_SLA_REF_IY_N_R(short OP, byte operand) { - return I_SLA_REF_II_N_R(OP, operand, IY); + int I_SLA_REF_IY_N_R(byte operand) { + return I_SLA_REF_II_N_R(operand, IY); } - int I_SLA_REF_II_N_R(short OP, byte operand, int special) { + int I_SLA_REF_II_N_R(byte operand, int special) { int tmp = (special + operand) & 0xFFFF; int tmp1 = memory.read(tmp); @@ -2226,19 +2224,19 @@ int I_SLA_REF_II_N_R(short OP, byte operand, int special) { flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok - regs[OP & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; } - int I_SRA_REF_IX_N_R(short OP, byte operand) { - return I_SRA_REF_II_N_R(OP, operand, IX); + int I_SRA_REF_IX_N_R(byte operand) { + return I_SRA_REF_II_N_R(operand, IX); } - int I_SRA_REF_IY_N_R(short OP, byte operand) { - return I_SRA_REF_II_N_R(OP, operand, IY); + int I_SRA_REF_IY_N_R(byte operand) { + return I_SRA_REF_II_N_R(operand, IY); } - int I_SRA_REF_II_N_R(short OP, byte operand, int special) { + int I_SRA_REF_II_N_R(byte operand, int special) { int tmp = (special + operand) & 0xffff; int tmp1 = memory.read(tmp); @@ -2248,19 +2246,19 @@ int I_SRA_REF_II_N_R(short OP, byte operand, int special) { flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok - regs[OP & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; } - int I_SLL_REF_IX_N_R(short OP, byte operand) { - return I_SLL_REF_II_N_R(OP, operand, IX); + int I_SLL_REF_IX_N_R(byte operand) { + return I_SLL_REF_II_N_R(operand, IX); } - int I_SLL_REF_IY_N_R(short OP, byte operand) { - return I_SLL_REF_II_N_R(OP, operand, IY); + int I_SLL_REF_IY_N_R(byte operand) { + return I_SLL_REF_II_N_R(operand, IY); } - int I_SLL_REF_II_N_R(short OP, byte operand, int special) { + int I_SLL_REF_II_N_R(byte operand, int special) { int tmp = (special + operand) & 0xffff; int tmp1 = memory.read(tmp); @@ -2270,19 +2268,19 @@ int I_SLL_REF_II_N_R(short OP, byte operand, int special) { flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok - regs[OP & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; } - int I_SRL_REF_IX_N_R(short OP, byte operand) { - return I_SRL_REF_II_N_R(OP, operand, IX); + int I_SRL_REF_IX_N_R(byte operand) { + return I_SRL_REF_II_N_R(operand, IX); } - int I_SRL_REF_IY_N_R(short OP, byte operand) { - return I_SRL_REF_II_N_R(OP, operand, IY); + int I_SRL_REF_IY_N_R(byte operand) { + return I_SRL_REF_II_N_R(operand, IY); } - int I_SRL_REF_II_N_R(short OP, byte operand, int special) { + int I_SRL_REF_II_N_R(byte operand, int special) { int tmp = (special + operand) & 0xffff; int tmp1 = memory.read(tmp); @@ -2292,20 +2290,20 @@ int I_SRL_REF_II_N_R(short OP, byte operand, int special) { flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok - regs[OP & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; } - int I_BIT_N_REF_IX_N(short OP, byte operand) { - return I_BIT_N_REF_II_N(OP, operand, IX); + int I_BIT_N_REF_IX_N(byte operand) { + return I_BIT_N_REF_II_N(operand, IX); } - int I_BIT_N_REF_IY_N(short OP, byte operand) { - return I_BIT_N_REF_II_N(OP, operand, IY); + int I_BIT_N_REF_IY_N(byte operand) { + return I_BIT_N_REF_II_N(operand, IY); } - int I_BIT_N_REF_II_N(short OP, byte operand, int special) { - int bitNumber = (OP >>> 3) & 7; + int I_BIT_N_REF_II_N(byte operand, int special) { + int bitNumber = (lastOpcode >>> 3) & 7; int tmp1 = memory.read((special + operand) & 0xFFFF); flags = ((flags & FLAG_C) | FLAG_H | (((tmp1 & (1 << bitNumber)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); if (bitNumber == 7) { @@ -2314,61 +2312,61 @@ int I_BIT_N_REF_II_N(short OP, byte operand, int special) { return 20; } - int I_RES_N_REF_IX_N_R(short OP, byte operand) { - return I_RES_N_REF_II_N_R(OP, operand, IX); + int I_RES_N_REF_IX_N_R(byte operand) { + return I_RES_N_REF_II_N_R(operand, IX); } - int I_RES_N_REF_IY_N_R(short OP, byte operand) { - return I_RES_N_REF_II_N_R(OP, operand, IY); + int I_RES_N_REF_IY_N_R(byte operand) { + return I_RES_N_REF_II_N_R(operand, IY); } - int I_RES_N_REF_II_N_R(short OP, byte operand, int special) { - int tmp2 = (OP >>> 3) & 7; + int I_RES_N_REF_II_N_R(byte operand, int special) { + int tmp2 = (lastOpcode >>> 3) & 7; int tmp3 = (special + operand) & 0xffff; int tmp1 = memory.read(tmp3); tmp1 = (tmp1 & (~(1 << tmp2))); memory.write(tmp3, (byte) (tmp1 & 0xff)); // regs[6] is unused, so it's ok - regs[OP & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; } - int I_SET_N_REF_IX_N_R(short OP, byte operand) { - return I_SET_N_REF_II_N_R(OP, operand, IX); + int I_SET_N_REF_IX_N_R(byte operand) { + return I_SET_N_REF_II_N_R(operand, IX); } - int I_SET_N_REF_IY_N_R(short OP, byte operand) { - return I_SET_N_REF_II_N_R(OP, operand, IY); + int I_SET_N_REF_IY_N_R(byte operand) { + return I_SET_N_REF_II_N_R(operand, IY); } - int I_SET_N_REF_II_N_R(short OP, byte operand, int special) { - int tmp2 = (OP >>> 3) & 7; + int I_SET_N_REF_II_N_R(byte operand, int special) { + int tmp2 = (lastOpcode >>> 3) & 7; int tmp3 = (special + operand) & 0xffff; int tmp1 = memory.read(tmp3); tmp1 = (tmp1 | (1 << tmp2)); memory.write(tmp3, (byte) (tmp1 & 0xff)); // regs[6] is unused, so it's ok - regs[OP & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; } - int I_INC_IXH(short OP) { + int I_INC_IXH() { IX = ((I_INC(IX >>> 8) << 8) | (IX & 0xFF)) & 0xFFFF; return 8; } - int I_INC_IYH(short OP) { + int I_INC_IYH() { IY = ((I_INC(IY >>> 8) << 8) | (IY & 0xFF)) & 0xFFFF; return 8; } - int I_INC_IXL(short OP) { + int I_INC_IXL() { IX = ((IX & 0xFF00) | I_INC(IX & 0xFF)) & 0xFFFF; return 8; } - int I_INC_IYL(short OP) { + int I_INC_IYL() { IY = ((IY & 0xFF00) | I_INC(IY & 0xFF)) & 0xFFFF; return 8; } @@ -2379,12 +2377,12 @@ int I_INC(int value) { return valueInc; } - int I_DEC_IXH(short OP) { + int I_DEC_IXH() { IX = ((I_DEC_IIH(IX) << 8) | (IX & 0xFF)) & 0xFFFF; return 8; } - int I_DEC_IYH(short OP) { + int I_DEC_IYH() { IY = ((I_DEC_IIH(IY) << 8) | (IY & 0xFF)) & 0xFFFF; return 8; } @@ -2396,12 +2394,12 @@ int I_DEC_IIH(int special) { return value; } - int I_DEC_IXL(short OP) { + int I_DEC_IXL() { IX = ((IX & 0xFF00) | (I_DEC_IIL(IX) & 0xFF)) & 0xFFFF; return 8; } - int I_DEC_IYL(short OP) { + int I_DEC_IYL() { IY = ((IY & 0xFF00) | (I_DEC_IIL(IY) & 0xFF)) & 0xFFFF; return 8; } @@ -2413,123 +2411,123 @@ int I_DEC_IIL(int special) { return value; } - int I_LD_IXH_N(short OP) { + int I_LD_IXH_N() { IX = ((readByte(PC) << 8) | (IX & 0xFF)) & 0xFFFF; PC = (PC + 1) & 0xFFFF; return 11; } - int I_LD_IYH_N(short OP) { + int I_LD_IYH_N() { IY = ((readByte(PC) << 8) | (IY & 0xFF)) & 0xFFFF; PC = (PC + 1) & 0xFFFF; return 11; } - int I_LD_IXL_N(short OP) { + int I_LD_IXL_N() { IX = ((IX & 0xFF00) | (readByte(PC) & 0xFF)) & 0xFFFF; PC = (PC + 1) & 0xFFFF; return 11; } - int I_LD_IYL_N(short OP) { + int I_LD_IYL_N() { IY = ((IY & 0xFF00) | (readByte(PC) & 0xFF)) & 0xFFFF; PC = (PC + 1) & 0xFFFF; return 11; } - int I_LD_R_IXH(short OP) { - return I_LD_R_IIH(OP, IX); + int I_LD_R_IXH() { + return I_LD_R_IIH(IX); } - int I_LD_R_IYH(short OP) { - return I_LD_R_IIH(OP, IY); + int I_LD_R_IYH() { + return I_LD_R_IIH(IY); } - int I_LD_R_IIH(short OP, int special) { - int reg = ((OP >>> 2) & 0x0F) / 2; // 4,5,6 not supported + int I_LD_R_IIH(int special) { + int reg = ((lastOpcode >>> 2) & 0x0F) / 2; // 4,5,6 not supported regs[reg] = special >>> 8; return 8; } - int I_LD_R_IXL(short OP) { - return I_LD_R_IIL(OP, IX); + int I_LD_R_IXL() { + return I_LD_R_IIL(IX); } - int I_LD_R_IYL(short OP) { - return I_LD_R_IIL(OP, IY); + int I_LD_R_IYL() { + return I_LD_R_IIL(IY); } - int I_LD_R_IIL(short OP, int special) { - int reg = ((OP >>> 2) & 0x0F) / 2; // 4,5,6 not supported + int I_LD_R_IIL(int special) { + int reg = ((lastOpcode >>> 2) & 0x0F) / 2; // 4,5,6 not supported regs[reg] = special & 0xFF; return 8; } - int I_LD_IXH_R(short OP) { - int reg = OP & 7; // 4,5,6 not supported + int I_LD_IXH_R() { + int reg = lastOpcode & 7; // 4,5,6 not supported IX = (IX & 0xFF) | ((regs[reg] << 8) & 0xFF00); return 8; } - int I_LD_IYH_R(short OP) { - int reg = OP & 7; // 4,5,6 not supported + int I_LD_IYH_R() { + int reg = lastOpcode & 7; // 4,5,6 not supported IY = (IY & 0xFF) | ((regs[reg] << 8) & 0xFF00); return 8; } - int I_LD_IIH_IIH(short OP) { + int I_LD_IIH_IIH() { return 8; } - int I_LD_IXH_IXL(short OP) { + int I_LD_IXH_IXL() { IX = (IX & 0xFF) | ((IX << 8) & 0xFF00); return 8; } - int I_LD_IYH_IYL(short OP) { + int I_LD_IYH_IYL() { IY = (IY & 0xFF) | ((IY << 8) & 0xFF00); return 8; } - int I_LD_IXL_R(short OP) { - int reg = OP & 7; // 4,5,6 not supported + int I_LD_IXL_R() { + int reg = lastOpcode & 7; // 4,5,6 not supported IX = (IX & 0xFF00) | (regs[reg] & 0xFF); return 8; } - int I_LD_IYL_R(short OP) { - int reg = OP & 7; // 4,5,6 not supported + int I_LD_IYL_R() { + int reg = lastOpcode & 7; // 4,5,6 not supported IY = (IY & 0xFF00) | (regs[reg] & 0xFF); return 8; } - int I_LD_IXL_IXH(short OP) { + int I_LD_IXL_IXH() { IX = (IX & 0xFF00) | (IX >>> 8); return 8; } - int I_LD_IYL_IYH(short OP) { + int I_LD_IYL_IYH() { IY = (IY & 0xFF00) | (IY >>> 8); return 8; } - int I_LD_IIL_IIL(short OP) { + int I_LD_IIL_IIL() { return 8; } - int I_ADD_A_IXH(short OP) { + int I_ADD_A_IXH() { return I_ADD_A(IX >>> 8); } - int I_ADD_A_IYH(short OP) { + int I_ADD_A_IYH() { return I_ADD_A(IY >>> 8); } - int I_ADD_A_IXL(short OP) { + int I_ADD_A_IXL() { return I_ADD_A(IX & 0xFF); } - int I_ADD_A_IYL(short OP) { + int I_ADD_A_IYL() { return I_ADD_A(IY & 0xFF); } @@ -2540,19 +2538,19 @@ int I_ADD_A(int value) { return 8; } - int I_ADC_A_IXH(short OP) { + int I_ADC_A_IXH() { return I_ADC_A(IX >>> 8); } - int I_ADC_A_IYH(short OP) { + int I_ADC_A_IYH() { return I_ADC_A(IY >>> 8); } - int I_ADC_A_IXL(short OP) { + int I_ADC_A_IXL() { return I_ADC_A(IX & 0xFF); } - int I_ADC_A_IYL(short OP) { + int I_ADC_A_IYL() { return I_ADC_A(IY & 0xFF); } @@ -2563,19 +2561,19 @@ int I_ADC_A(int value) { return 8; } - int I_SUB_IXH(short OP) { + int I_SUB_IXH() { return I_SUB(IX >>> 8); } - int I_SUB_IYH(short OP) { + int I_SUB_IYH() { return I_SUB(IY >>> 8); } - int I_SUB_IXL(short OP) { + int I_SUB_IXL() { return I_SUB(IX & 0xFF); } - int I_SUB_IYL(short OP) { + int I_SUB_IYL() { return I_SUB(IY & 0xFF); } @@ -2587,19 +2585,19 @@ int I_SUB(int value) { return 8; } - int I_SBC_A_IXH(short OP) { + int I_SBC_A_IXH() { return I_SBC_A(IX >>> 8); } - int I_SBC_A_IYH(short OP) { + int I_SBC_A_IYH() { return I_SBC_A(IY >>> 8); } - int I_SBC_A_IXL(short OP) { + int I_SBC_A_IXL() { return I_SBC_A(IX & 0xFF); } - int I_SBC_A_IYL(short OP) { + int I_SBC_A_IYL() { return I_SBC_A(IY & 0xFF); } @@ -2611,19 +2609,19 @@ int I_SBC_A(int value) { return 8; } - int I_AND_IXH(short OP) { + int I_AND_IXH() { return I_AND(IX >>> 8); } - int I_AND_IYH(short OP) { + int I_AND_IYH() { return I_AND(IY >>> 8); } - int I_AND_IXL(short OP) { + int I_AND_IXL() { return I_AND(IX & 0xFF); } - int I_AND_IYL(short OP) { + int I_AND_IYL() { return I_AND(IY & 0xFF); } @@ -2633,19 +2631,19 @@ int I_AND(int value) { return 8; } - int I_XOR_IXH(short OP) { + int I_XOR_IXH() { return I_XOR(IX >>> 8); } - int I_XOR_IYH(short OP) { + int I_XOR_IYH() { return I_XOR(IY >>> 8); } - int I_XOR_IXL(short OP) { + int I_XOR_IXL() { return I_XOR(IX & 0xFF); } - int I_XOR_IYL(short OP) { + int I_XOR_IYL() { return I_XOR(IY & 0xFF); } @@ -2655,19 +2653,19 @@ int I_XOR(int value) { return 8; } - int I_OR_IXH(short OP) { + int I_OR_IXH() { return I_OR(IX >>> 8); } - int I_OR_IXL(short OP) { + int I_OR_IXL() { return I_OR(IX & 0xFF); } - int I_OR_IYH(short OP) { + int I_OR_IYH() { return I_OR(IY >>> 8); } - int I_OR_IYL(short OP) { + int I_OR_IYL() { return I_OR(IY & 0xFF); } @@ -2677,19 +2675,19 @@ int I_OR(int value) { return 8; } - int I_CP_IXH(short OP) { + int I_CP_IXH() { return I_CP(IX >>> 8); } - int I_CP_IXL(short OP) { + int I_CP_IXL() { return I_CP(IX & 0xFF); } - int I_CP_IYH(short OP) { + int I_CP_IYH() { return I_CP(IY >>> 8); } - int I_CP_IYL(short OP) { + int I_CP_IYL() { return I_CP(IY & 0xFF); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java index c296f3a4a..5337da1c4 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java @@ -64,7 +64,7 @@ public void testADD_A_N() { public void testADC_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) + .verifyRegister(REG_A, context -> ((context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); @@ -86,7 +86,7 @@ public void testADC_A_R() { public void testADC_A_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) + .verifyRegister(REG_A, context -> ((context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); Generator.forSome8bitBinary( @@ -125,7 +125,7 @@ public void testSUB_N() { public void testSBC_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) + .verifyRegister(REG_A, context -> ((context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrowWithCarry().overflow().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); From 516b2961fa96d5ccb5466be14443a61194bb5c71 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 2 Feb 2022 08:39:30 +0100 Subject: [PATCH 089/314] [#201] z80: fix --- .../net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java index 5337da1c4..a1498edb6 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java @@ -64,7 +64,7 @@ public void testADD_A_N() { public void testADC_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> ((context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) & 0xFF) + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); @@ -86,7 +86,7 @@ public void testADC_A_R() { public void testADC_A_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> ((context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) & 0xFF) + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); Generator.forSome8bitBinary( From 54215838af2ded38ab362b23d2f70bc69739c443 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 2 Feb 2022 09:04:01 +0100 Subject: [PATCH 090/314] [#201] 8080-cpu: optimize --- application/build.gradle | 22 +- plugins/cpu/8080-cpu/build.gradle | 1 + .../plugins/cpu/intel8080/DispatchTables.java | 267 ++++++++++ .../plugins/cpu/intel8080/EmulatorEngine.java | 504 +++++------------- plugins/cpu/z80-cpu/build.gradle | 1 + .../plugins/cpu/zilogZ80/TablesGenerator.java | 71 --- 6 files changed, 406 insertions(+), 460 deletions(-) create mode 100644 plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/DispatchTables.java delete mode 100644 plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TablesGenerator.java diff --git a/application/build.gradle b/application/build.gradle index e69da5fac..11c13312e 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -49,7 +49,7 @@ dependencies { extraLibs libs.slf4JApi extraLibsRuntime libs.javaCupRuntime -// providedRuntime project(":plugins:compiler:as-8080") + providedRuntime project(":plugins:compiler:as-8080") providedRuntime project(":plugins:compiler:as-ssem") // providedRuntime project(":plugins:compiler:as-z80") // providedRuntime project(":plugins:compiler:brainc-brainduck") @@ -58,23 +58,23 @@ dependencies { // providedRuntime project(":plugins:memory:ram-mem") // providedRuntime project(":plugins:memory:rasp-mem") - // providedRuntime project(":plugins:memory:brainduck-mem") + providedRuntime project(":plugins:memory:brainduck-mem") providedRuntime project(":plugins:memory:ssem-mem") - // providedRuntime project(":plugins:memory:byte-mem") + providedRuntime project(":plugins:memory:byte-mem") - // providedRuntime project(":plugins:cpu:8080-cpu") - // providedRuntime project(":plugins:cpu:brainduck-cpu") + providedRuntime project(":plugins:cpu:8080-cpu") + providedRuntime project(":plugins:cpu:brainduck-cpu") // providedRuntime project(":plugins:cpu:ram-cpu") // providedRuntime project(":plugins:cpu:rasp-cpu") - // providedRuntime project(":plugins:cpu:z80-cpu") + providedRuntime project(":plugins:cpu:z80-cpu") providedRuntime project(":plugins:cpu:ssem-cpu") -// providedRuntime project(":plugins:device:abstract-tape") -// providedRuntime project(":plugins:device:88-dcdd") -// providedRuntime project(":plugins:device:88-sio") -// providedRuntime project(":plugins:device:adm3A-terminal") + providedRuntime project(":plugins:device:abstract-tape") + providedRuntime project(":plugins:device:88-dcdd") + providedRuntime project(":plugins:device:88-sio") + providedRuntime project(":plugins:device:adm3A-terminal") // providedRuntime project(":plugins:device:brainduck-terminal") -// providedRuntime project(":plugins:device:simhPseudo-z80") + providedRuntime project(":plugins:device:simhPseudo-z80") providedRuntime project(":plugins:device:ssem-display") testImplementation libs.junit diff --git a/plugins/cpu/8080-cpu/build.gradle b/plugins/cpu/8080-cpu/build.gradle index f984bacd8..dc3c22a3e 100644 --- a/plugins/cpu/8080-cpu/build.gradle +++ b/plugins/cpu/8080-cpu/build.gradle @@ -29,6 +29,7 @@ buildscript { plugins { id 'java' id 'net.emustudio.edigen-plugin' version '1.4.0' + id 'com.adarshr.test-logger' version '3.1.0' } repositories { diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/DispatchTables.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/DispatchTables.java new file mode 100644 index 000000000..a8354dfcc --- /dev/null +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/DispatchTables.java @@ -0,0 +1,267 @@ +package net.emustudio.plugins.cpu.intel8080; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class DispatchTables { + private final static Logger LOGGER = LoggerFactory.getLogger(DispatchTables.class); + public final static MethodHandle[] DISPATCH_TABLE = new MethodHandle[256]; + + static { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType retInt = MethodType.methodType(int.class); + + try { + DISPATCH_TABLE[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", retInt); + DISPATCH_TABLE[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_LXI", retInt); + DISPATCH_TABLE[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_STAX", retInt); + DISPATCH_TABLE[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_INX", retInt); + DISPATCH_TABLE[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_INR", retInt); + DISPATCH_TABLE[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_DCR", retInt); + DISPATCH_TABLE[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_MVI", retInt); + DISPATCH_TABLE[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLC", retInt); + DISPATCH_TABLE[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_DAD", retInt); + DISPATCH_TABLE[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_LDAX", retInt); + DISPATCH_TABLE[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_DCX", retInt); + DISPATCH_TABLE[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_INR", retInt); + DISPATCH_TABLE[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_DCR", retInt); + DISPATCH_TABLE[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_MVI", retInt); + DISPATCH_TABLE[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRC", retInt); + DISPATCH_TABLE[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_LXI", retInt); + DISPATCH_TABLE[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_STAX", retInt); + DISPATCH_TABLE[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_INX", retInt); + DISPATCH_TABLE[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_INR", retInt); + DISPATCH_TABLE[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_DCR", retInt); + DISPATCH_TABLE[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_MVI", retInt); + DISPATCH_TABLE[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RAL", retInt); + DISPATCH_TABLE[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_DAD", retInt); + DISPATCH_TABLE[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_LDAX", retInt); + DISPATCH_TABLE[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_DCX", retInt); + DISPATCH_TABLE[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_INR", retInt); + DISPATCH_TABLE[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_DCR", retInt); + DISPATCH_TABLE[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_MVI", retInt); + DISPATCH_TABLE[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RAR", retInt); + DISPATCH_TABLE[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LXI", retInt); + DISPATCH_TABLE[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_SHLD", retInt); + DISPATCH_TABLE[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INX", retInt); + DISPATCH_TABLE[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INR", retInt); + DISPATCH_TABLE[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DCR", retInt); + DISPATCH_TABLE[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_MVI", retInt); + DISPATCH_TABLE[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_DAA", retInt); + DISPATCH_TABLE[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_DAD", retInt); + DISPATCH_TABLE[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LHLD", retInt); + DISPATCH_TABLE[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DCX", retInt); + DISPATCH_TABLE[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INR", retInt); + DISPATCH_TABLE[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DCR", retInt); + DISPATCH_TABLE[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_MVI", retInt); + DISPATCH_TABLE[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_CMA", retInt); + DISPATCH_TABLE[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_LXI", retInt); + DISPATCH_TABLE[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_STA", retInt); + DISPATCH_TABLE[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_INX", retInt); + DISPATCH_TABLE[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INR", retInt); + DISPATCH_TABLE[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DCR", retInt); + DISPATCH_TABLE[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_MVI", retInt); + DISPATCH_TABLE[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_STC", retInt); + DISPATCH_TABLE[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_DAD", retInt); + DISPATCH_TABLE[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_LDA", retInt); + DISPATCH_TABLE[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_DCX", retInt); + DISPATCH_TABLE[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_INR", retInt); + DISPATCH_TABLE[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_DCR", retInt); + DISPATCH_TABLE[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_MVI", retInt); + DISPATCH_TABLE[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_CMC", retInt); + DISPATCH_TABLE[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_HLT", retInt); + DISPATCH_TABLE[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_MOV", retInt); + DISPATCH_TABLE[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD", retInt); + DISPATCH_TABLE[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD", retInt); + DISPATCH_TABLE[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD", retInt); + DISPATCH_TABLE[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD", retInt); + DISPATCH_TABLE[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD", retInt); + DISPATCH_TABLE[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD", retInt); + DISPATCH_TABLE[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD", retInt); + DISPATCH_TABLE[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD", retInt); + DISPATCH_TABLE[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC", retInt); + DISPATCH_TABLE[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC", retInt); + DISPATCH_TABLE[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC", retInt); + DISPATCH_TABLE[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC", retInt); + DISPATCH_TABLE[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC", retInt); + DISPATCH_TABLE[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC", retInt); + DISPATCH_TABLE[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC", retInt); + DISPATCH_TABLE[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC", retInt); + DISPATCH_TABLE[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB", retInt); + DISPATCH_TABLE[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB", retInt); + DISPATCH_TABLE[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB", retInt); + DISPATCH_TABLE[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB", retInt); + DISPATCH_TABLE[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB", retInt); + DISPATCH_TABLE[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB", retInt); + DISPATCH_TABLE[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB", retInt); + DISPATCH_TABLE[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB", retInt); + DISPATCH_TABLE[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBB", retInt); + DISPATCH_TABLE[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBB", retInt); + DISPATCH_TABLE[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBB", retInt); + DISPATCH_TABLE[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBB", retInt); + DISPATCH_TABLE[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBB", retInt); + DISPATCH_TABLE[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBB", retInt); + DISPATCH_TABLE[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBB", retInt); + DISPATCH_TABLE[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBB", retInt); + DISPATCH_TABLE[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_ANA", retInt); + DISPATCH_TABLE[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_ANA", retInt); + DISPATCH_TABLE[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_ANA", retInt); + DISPATCH_TABLE[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_ANA", retInt); + DISPATCH_TABLE[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_ANA", retInt); + DISPATCH_TABLE[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_ANA", retInt); + DISPATCH_TABLE[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_ANA", retInt); + DISPATCH_TABLE[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_ANA", retInt); + DISPATCH_TABLE[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XRA", retInt); + DISPATCH_TABLE[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XRA", retInt); + DISPATCH_TABLE[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XRA", retInt); + DISPATCH_TABLE[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XRA", retInt); + DISPATCH_TABLE[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XRA", retInt); + DISPATCH_TABLE[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XRA", retInt); + DISPATCH_TABLE[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XRA", retInt); + DISPATCH_TABLE[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XRA", retInt); + DISPATCH_TABLE[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_ORA", retInt); + DISPATCH_TABLE[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_ORA", retInt); + DISPATCH_TABLE[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_ORA", retInt); + DISPATCH_TABLE[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_ORA", retInt); + DISPATCH_TABLE[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_ORA", retInt); + DISPATCH_TABLE[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_ORA", retInt); + DISPATCH_TABLE[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_ORA", retInt); + DISPATCH_TABLE[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_ORA", retInt); + DISPATCH_TABLE[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CMP", retInt); + DISPATCH_TABLE[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CMP", retInt); + DISPATCH_TABLE[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CMP", retInt); + DISPATCH_TABLE[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CMP", retInt); + DISPATCH_TABLE[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CMP", retInt); + DISPATCH_TABLE[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CMP", retInt); + DISPATCH_TABLE[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CMP", retInt); + DISPATCH_TABLE[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CMP", retInt); + DISPATCH_TABLE[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_COND", retInt); // RNZ + DISPATCH_TABLE[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_POP", retInt); + DISPATCH_TABLE[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_JMP_COND", retInt); // JNZ + DISPATCH_TABLE[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_JMP", retInt); + DISPATCH_TABLE[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_COND", retInt); // CNZ + DISPATCH_TABLE[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH", retInt); + DISPATCH_TABLE[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_ADI", retInt); + DISPATCH_TABLE[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_COND", retInt); // RZ + DISPATCH_TABLE[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_RET", retInt); + DISPATCH_TABLE[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_JMP_COND", retInt); // JZ + DISPATCH_TABLE[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_COND", retInt); // CZ + DISPATCH_TABLE[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_CALL", retInt); + DISPATCH_TABLE[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_ACI", retInt); + DISPATCH_TABLE[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_COND", retInt); // RNC + DISPATCH_TABLE[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_POP", retInt); + DISPATCH_TABLE[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_JMP_COND", retInt); // JNC + DISPATCH_TABLE[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_OUT", retInt); + DISPATCH_TABLE[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_COND", retInt); // CNC + DISPATCH_TABLE[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH", retInt); + DISPATCH_TABLE[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SUI", retInt); + DISPATCH_TABLE[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_COND", retInt); // RC + DISPATCH_TABLE[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_JMP_COND", retInt); // JC + DISPATCH_TABLE[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_IN", retInt); + DISPATCH_TABLE[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_COND", retInt); // CC + DISPATCH_TABLE[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SBI", retInt); + DISPATCH_TABLE[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_COND", retInt); // RPO + DISPATCH_TABLE[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP", retInt); + DISPATCH_TABLE[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_JMP_COND", retInt); // JPO + DISPATCH_TABLE[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_XTHL", retInt); + DISPATCH_TABLE[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_COND", retInt); // CPO + DISPATCH_TABLE[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH", retInt); + DISPATCH_TABLE[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_ANI", retInt); + DISPATCH_TABLE[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_COND", retInt); // RPE + DISPATCH_TABLE[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_PCHL", retInt); + DISPATCH_TABLE[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_JMP_COND", retInt); // JPE + DISPATCH_TABLE[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_XCHG", retInt); + DISPATCH_TABLE[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_COND", retInt); // CPE + DISPATCH_TABLE[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_XRI", retInt); + DISPATCH_TABLE[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_COND", retInt); // RP + DISPATCH_TABLE[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_POP", retInt); + DISPATCH_TABLE[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_JMP_COND", retInt); // JP + DISPATCH_TABLE[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_DI", retInt); + DISPATCH_TABLE[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_COND", retInt); // CP + DISPATCH_TABLE[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH", retInt); + DISPATCH_TABLE[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_ORI", retInt); + DISPATCH_TABLE[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_COND", retInt); // RM + DISPATCH_TABLE[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_SPHL", retInt); + DISPATCH_TABLE[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_JMP_COND", retInt); // JM + DISPATCH_TABLE[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_EI", retInt); + DISPATCH_TABLE[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_COND", retInt); // CM + DISPATCH_TABLE[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_CPI", retInt); + DISPATCH_TABLE[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + } catch (IllegalAccessException | NoSuchMethodException e) { + LOGGER.error("Could not set up dispatch table. The emulator won't work correctly", e); + } + } +} diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java index 8f760f6d1..c20fb060e 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java @@ -28,12 +28,13 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; +import java.lang.invoke.MethodHandle; import java.util.Arrays; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import static net.emustudio.plugins.cpu.intel8080.DispatchTables.DISPATCH_TABLE; + public class EmulatorEngine implements CpuEngine { private static final Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); @@ -57,7 +58,7 @@ public class EmulatorEngine implements CpuEngine { public int[] regs = new int[8]; public short flags = 2; // registers public volatile CPU.RunState currentRunState = CPU.RunState.STATE_STOPPED_NORMAL; - private byte lastOpcode; + private int lastOpcode; private final MemoryContext memory; private final ContextImpl context; @@ -106,7 +107,13 @@ public void reset(int startPos) { public CPU.RunState step() throws Exception { currentRunState = CPU.RunState.STATE_STOPPED_BREAK; - dispatch(); + try { + dispatch(); + } catch (Exception e) { + throw e; + } catch (Throwable e) { + throw new Exception(e); + } return currentRunState; } @@ -130,17 +137,17 @@ public CPU.RunState run(CPU cpu) { if (cpu.isBreakpointSet(PC)) { throw new Breakpoint(); } - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - LOGGER.debug("Unexpected error", e); - if (e.getCause() != null && e.getCause() instanceof IndexOutOfBoundsException) { - return CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; - } - return CPU.RunState.STATE_STOPPED_BAD_INSTR; + } catch (Breakpoint e) { + return CPU.RunState.STATE_STOPPED_BREAK; } catch (IndexOutOfBoundsException e) { LOGGER.debug("Unexpected error", e); return CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; - } catch (Breakpoint e) { - return CPU.RunState.STATE_STOPPED_BREAK; + } catch (IOException e) { + LOGGER.error("Unexpected error", e); + return CPU.RunState.STATE_STOPPED_BAD_INSTR; + } catch (Throwable e) { + LOGGER.debug("Unexpected error", e); + return CPU.RunState.STATE_STOPPED_BAD_INSTR; } } endTime = System.nanoTime() - startTime; @@ -152,6 +159,56 @@ public CPU.RunState run(CPU cpu) { return currentRunState; } + private int dispatch() throws Throwable { + DispatchListener tmpListener = dispatchListener; + if (tmpListener != null) { + tmpListener.beforeDispatch(); + } + + /* if interrupt is waiting, instruction won't be read from memory + * but from one or all of 3 bytes (b1,b2,b3) which represents either + * rst or call instruction incomed from external peripheral device + */ + if (isINT) { + if (INTE) { + if ((b1 & 0xC7) == 0xC7) { /* RST */ + SP = (SP - 2) & 0xFFFF; + writeWord(SP, PC); + PC = b1 & 0x38; + return 11; + } else if (b1 == 0xCD) { /* CALL */ + SP = (SP - 2) & 0xFFFF; + writeWord(SP, (PC + 2) & 0xFFFF); + PC = ((b3 & 0xFF) << 8) | (b2 & 0xFF); + return 17; + } + } + isINT = false; + } + + try { + lastOpcode = readByte(PC); + } catch (NullPointerException e) { + LOGGER.error("NPE; PC=" + Integer.toHexString(PC), e); + currentRunState = CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; + return 0; + } + PC = (PC + 1) & 0xFFFF; + + try { + MethodHandle instr = DISPATCH_TABLE[lastOpcode]; + if (instr != null) { + return (int) instr.invokeExact(this); + } + currentRunState = CPU.RunState.STATE_STOPPED_BAD_INSTR; + return 0; + } finally { + if (tmpListener != null) { + tmpListener.afterDispatch(); + } + } + } + public void interrupt(short b1, short b2, short b3) { if (!INTE) { @@ -195,11 +252,6 @@ private int getpair(int reg) { return SP; } int index = reg * 2; - - System.out.println("REG: " + index); - System.out.println("REG: " + regs[index]); - System.out.println("REG: " + regs[index + 1]); - return regs[index] << 8 | regs[index + 1]; } @@ -276,264 +328,11 @@ private void writeWord(int address, int value) { memory.write(address, new Byte[]{(byte) (value & 0xFF), (byte) ((value >>> 8) & 0xFF)}, 2); } - private static final Method[] DISPATCH_TABLE = new Method[256]; - - static { - try { - DISPATCH_TABLE[0x00] = EmulatorEngine.class.getDeclaredMethod("I_NOP"); - DISPATCH_TABLE[0x01] = EmulatorEngine.class.getDeclaredMethod("I_LXI"); - DISPATCH_TABLE[0x02] = EmulatorEngine.class.getDeclaredMethod("I_STAX"); - DISPATCH_TABLE[0x03] = EmulatorEngine.class.getDeclaredMethod("I_INX"); - DISPATCH_TABLE[0x04] = EmulatorEngine.class.getDeclaredMethod("I_INR"); - DISPATCH_TABLE[0x05] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); - DISPATCH_TABLE[0x06] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); - DISPATCH_TABLE[0x07] = EmulatorEngine.class.getDeclaredMethod("I_RLC"); - DISPATCH_TABLE[0x09] = EmulatorEngine.class.getDeclaredMethod("I_DAD"); - DISPATCH_TABLE[0x0A] = EmulatorEngine.class.getDeclaredMethod("I_LDAX"); - DISPATCH_TABLE[0x0B] = EmulatorEngine.class.getDeclaredMethod("I_DCX"); - DISPATCH_TABLE[0x0C] = EmulatorEngine.class.getDeclaredMethod("I_INR"); - DISPATCH_TABLE[0x0D] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); - DISPATCH_TABLE[0x0E] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); - DISPATCH_TABLE[0x0F] = EmulatorEngine.class.getDeclaredMethod("I_RRC"); - DISPATCH_TABLE[0x11] = EmulatorEngine.class.getDeclaredMethod("I_LXI"); - DISPATCH_TABLE[0x12] = EmulatorEngine.class.getDeclaredMethod("I_STAX"); - DISPATCH_TABLE[0x13] = EmulatorEngine.class.getDeclaredMethod("I_INX"); - DISPATCH_TABLE[0x14] = EmulatorEngine.class.getDeclaredMethod("I_INR"); - DISPATCH_TABLE[0x15] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); - DISPATCH_TABLE[0x16] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); - DISPATCH_TABLE[0x17] = EmulatorEngine.class.getDeclaredMethod("I_RAL"); - DISPATCH_TABLE[0x19] = EmulatorEngine.class.getDeclaredMethod("I_DAD"); - DISPATCH_TABLE[0x1A] = EmulatorEngine.class.getDeclaredMethod("I_LDAX"); - DISPATCH_TABLE[0x1B] = EmulatorEngine.class.getDeclaredMethod("I_DCX"); - DISPATCH_TABLE[0x1C] = EmulatorEngine.class.getDeclaredMethod("I_INR"); - DISPATCH_TABLE[0x1D] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); - DISPATCH_TABLE[0x1E] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); - DISPATCH_TABLE[0x1F] = EmulatorEngine.class.getDeclaredMethod("I_RAR"); - DISPATCH_TABLE[0x21] = EmulatorEngine.class.getDeclaredMethod("I_LXI"); - DISPATCH_TABLE[0x22] = EmulatorEngine.class.getDeclaredMethod("I_SHLD"); - DISPATCH_TABLE[0x23] = EmulatorEngine.class.getDeclaredMethod("I_INX"); - DISPATCH_TABLE[0x24] = EmulatorEngine.class.getDeclaredMethod("I_INR"); - DISPATCH_TABLE[0x25] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); - DISPATCH_TABLE[0x26] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); - DISPATCH_TABLE[0x27] = EmulatorEngine.class.getDeclaredMethod("I_DAA"); - DISPATCH_TABLE[0x29] = EmulatorEngine.class.getDeclaredMethod("I_DAD"); - DISPATCH_TABLE[0x2A] = EmulatorEngine.class.getDeclaredMethod("I_LHLD"); - DISPATCH_TABLE[0x2B] = EmulatorEngine.class.getDeclaredMethod("I_DCX"); - DISPATCH_TABLE[0x2C] = EmulatorEngine.class.getDeclaredMethod("I_INR"); - DISPATCH_TABLE[0x2D] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); - DISPATCH_TABLE[0x2E] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); - DISPATCH_TABLE[0x2F] = EmulatorEngine.class.getDeclaredMethod("I_CMA"); - DISPATCH_TABLE[0x31] = EmulatorEngine.class.getDeclaredMethod("I_LXI"); - DISPATCH_TABLE[0x32] = EmulatorEngine.class.getDeclaredMethod("I_STA"); - DISPATCH_TABLE[0x33] = EmulatorEngine.class.getDeclaredMethod("I_INX"); - DISPATCH_TABLE[0x34] = EmulatorEngine.class.getDeclaredMethod("I_INR"); - DISPATCH_TABLE[0x35] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); - DISPATCH_TABLE[0x36] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); - DISPATCH_TABLE[0x37] = EmulatorEngine.class.getDeclaredMethod("I_STC"); - DISPATCH_TABLE[0x39] = EmulatorEngine.class.getDeclaredMethod("I_DAD"); - DISPATCH_TABLE[0x3A] = EmulatorEngine.class.getDeclaredMethod("I_LDA"); - DISPATCH_TABLE[0x3B] = EmulatorEngine.class.getDeclaredMethod("I_DCX"); - DISPATCH_TABLE[0x3C] = EmulatorEngine.class.getDeclaredMethod("I_INR"); - DISPATCH_TABLE[0x3D] = EmulatorEngine.class.getDeclaredMethod("I_DCR"); - DISPATCH_TABLE[0x3E] = EmulatorEngine.class.getDeclaredMethod("I_MVI"); - DISPATCH_TABLE[0x3F] = EmulatorEngine.class.getDeclaredMethod("I_CMC"); - DISPATCH_TABLE[0x40] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x41] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x42] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x43] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x44] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x45] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x46] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x47] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x48] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x49] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x4A] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x4B] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x4C] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x4D] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x4E] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x4F] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x50] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x51] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x52] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x53] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x54] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x55] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x56] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x57] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x58] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x59] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x5A] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x5B] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x5C] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x5D] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x5E] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x5F] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x60] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x61] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x62] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x63] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x64] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x65] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x66] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x67] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x68] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x69] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x6A] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x6B] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x6C] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x6D] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x6E] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x6F] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x70] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x71] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x72] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x73] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x74] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x75] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x76] = EmulatorEngine.class.getDeclaredMethod("I_HLT"); - DISPATCH_TABLE[0x77] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x78] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x79] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x7A] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x7B] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x7C] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x7D] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x7E] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x7F] = EmulatorEngine.class.getDeclaredMethod("I_MOV"); - DISPATCH_TABLE[0x80] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); - DISPATCH_TABLE[0x81] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); - DISPATCH_TABLE[0x82] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); - DISPATCH_TABLE[0x83] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); - DISPATCH_TABLE[0x84] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); - DISPATCH_TABLE[0x85] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); - DISPATCH_TABLE[0x86] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); - DISPATCH_TABLE[0x87] = EmulatorEngine.class.getDeclaredMethod("I_ADD"); - DISPATCH_TABLE[0x88] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); - DISPATCH_TABLE[0x89] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); - DISPATCH_TABLE[0x8A] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); - DISPATCH_TABLE[0x8B] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); - DISPATCH_TABLE[0x8C] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); - DISPATCH_TABLE[0x8D] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); - DISPATCH_TABLE[0x8E] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); - DISPATCH_TABLE[0x8F] = EmulatorEngine.class.getDeclaredMethod("I_ADC"); - DISPATCH_TABLE[0x90] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); - DISPATCH_TABLE[0x91] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); - DISPATCH_TABLE[0x92] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); - DISPATCH_TABLE[0x93] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); - DISPATCH_TABLE[0x94] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); - DISPATCH_TABLE[0x95] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); - DISPATCH_TABLE[0x96] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); - DISPATCH_TABLE[0x97] = EmulatorEngine.class.getDeclaredMethod("I_SUB"); - DISPATCH_TABLE[0x98] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); - DISPATCH_TABLE[0x99] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); - DISPATCH_TABLE[0x9A] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); - DISPATCH_TABLE[0x9B] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); - DISPATCH_TABLE[0x9C] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); - DISPATCH_TABLE[0x9D] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); - DISPATCH_TABLE[0x9E] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); - DISPATCH_TABLE[0x9F] = EmulatorEngine.class.getDeclaredMethod("I_SBB"); - DISPATCH_TABLE[0xA0] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); - DISPATCH_TABLE[0xA1] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); - DISPATCH_TABLE[0xA2] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); - DISPATCH_TABLE[0xA3] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); - DISPATCH_TABLE[0xA4] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); - DISPATCH_TABLE[0xA5] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); - DISPATCH_TABLE[0xA6] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); - DISPATCH_TABLE[0xA7] = EmulatorEngine.class.getDeclaredMethod("I_ANA"); - DISPATCH_TABLE[0xA8] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); - DISPATCH_TABLE[0xA9] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); - DISPATCH_TABLE[0xAA] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); - DISPATCH_TABLE[0xAB] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); - DISPATCH_TABLE[0xAC] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); - DISPATCH_TABLE[0xAD] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); - DISPATCH_TABLE[0xAE] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); - DISPATCH_TABLE[0xAF] = EmulatorEngine.class.getDeclaredMethod("I_XRA"); - DISPATCH_TABLE[0xB0] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); - DISPATCH_TABLE[0xB1] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); - DISPATCH_TABLE[0xB2] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); - DISPATCH_TABLE[0xB3] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); - DISPATCH_TABLE[0xB4] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); - DISPATCH_TABLE[0xB5] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); - DISPATCH_TABLE[0xB6] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); - DISPATCH_TABLE[0xB7] = EmulatorEngine.class.getDeclaredMethod("I_ORA"); - DISPATCH_TABLE[0xB8] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); - DISPATCH_TABLE[0xB9] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); - DISPATCH_TABLE[0xBA] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); - DISPATCH_TABLE[0xBB] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); - DISPATCH_TABLE[0xBC] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); - DISPATCH_TABLE[0xBD] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); - DISPATCH_TABLE[0xBE] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); - DISPATCH_TABLE[0xBF] = EmulatorEngine.class.getDeclaredMethod("I_CMP"); - DISPATCH_TABLE[0xC0] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RNZ - DISPATCH_TABLE[0xC1] = EmulatorEngine.class.getDeclaredMethod("I_POP"); - DISPATCH_TABLE[0xC2] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JNZ - DISPATCH_TABLE[0xC3] = EmulatorEngine.class.getDeclaredMethod("I_JMP"); - DISPATCH_TABLE[0xC4] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CNZ - DISPATCH_TABLE[0xC5] = EmulatorEngine.class.getDeclaredMethod("I_PUSH"); - DISPATCH_TABLE[0xC6] = EmulatorEngine.class.getDeclaredMethod("I_ADI"); - DISPATCH_TABLE[0xC7] = EmulatorEngine.class.getDeclaredMethod("I_RST"); - DISPATCH_TABLE[0xC8] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RZ - DISPATCH_TABLE[0xC9] = EmulatorEngine.class.getDeclaredMethod("I_RET"); - DISPATCH_TABLE[0xCA] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JZ - DISPATCH_TABLE[0xCC] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CZ - DISPATCH_TABLE[0xCD] = EmulatorEngine.class.getDeclaredMethod("I_CALL"); - DISPATCH_TABLE[0xCE] = EmulatorEngine.class.getDeclaredMethod("I_ACI"); - DISPATCH_TABLE[0xCF] = EmulatorEngine.class.getDeclaredMethod("I_RST"); - DISPATCH_TABLE[0xD0] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RNC - DISPATCH_TABLE[0xD1] = EmulatorEngine.class.getDeclaredMethod("I_POP"); - DISPATCH_TABLE[0xD2] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JNC - DISPATCH_TABLE[0xD3] = EmulatorEngine.class.getDeclaredMethod("I_OUT"); - DISPATCH_TABLE[0xD4] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CNC - DISPATCH_TABLE[0xD5] = EmulatorEngine.class.getDeclaredMethod("I_PUSH"); - DISPATCH_TABLE[0xD6] = EmulatorEngine.class.getDeclaredMethod("I_SUI"); - DISPATCH_TABLE[0xD7] = EmulatorEngine.class.getDeclaredMethod("I_RST"); - DISPATCH_TABLE[0xD8] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RC - DISPATCH_TABLE[0xDA] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JC - DISPATCH_TABLE[0xDB] = EmulatorEngine.class.getDeclaredMethod("I_IN"); - DISPATCH_TABLE[0xDC] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CC - DISPATCH_TABLE[0xDE] = EmulatorEngine.class.getDeclaredMethod("I_SBI"); - DISPATCH_TABLE[0xDF] = EmulatorEngine.class.getDeclaredMethod("I_RST"); - DISPATCH_TABLE[0xE0] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RPO - DISPATCH_TABLE[0xE1] = EmulatorEngine.class.getDeclaredMethod("I_POP"); - DISPATCH_TABLE[0xE2] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JPO - DISPATCH_TABLE[0xE3] = EmulatorEngine.class.getDeclaredMethod("I_XTHL"); - DISPATCH_TABLE[0xE4] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CPO - DISPATCH_TABLE[0xE5] = EmulatorEngine.class.getDeclaredMethod("I_PUSH"); - DISPATCH_TABLE[0xE6] = EmulatorEngine.class.getDeclaredMethod("I_ANI"); - DISPATCH_TABLE[0xE7] = EmulatorEngine.class.getDeclaredMethod("I_RST"); - DISPATCH_TABLE[0xE8] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RPE - DISPATCH_TABLE[0xE9] = EmulatorEngine.class.getDeclaredMethod("I_PCHL"); - DISPATCH_TABLE[0xEA] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JPE - DISPATCH_TABLE[0xEB] = EmulatorEngine.class.getDeclaredMethod("I_XCHG"); - DISPATCH_TABLE[0xEC] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CPE - DISPATCH_TABLE[0xEE] = EmulatorEngine.class.getDeclaredMethod("I_XRI"); - DISPATCH_TABLE[0xEF] = EmulatorEngine.class.getDeclaredMethod("I_RST"); - DISPATCH_TABLE[0xF0] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RP - DISPATCH_TABLE[0xF1] = EmulatorEngine.class.getDeclaredMethod("I_POP"); - DISPATCH_TABLE[0xF2] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JP - DISPATCH_TABLE[0xF3] = EmulatorEngine.class.getDeclaredMethod("I_DI"); - DISPATCH_TABLE[0xF4] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CP - DISPATCH_TABLE[0xF5] = EmulatorEngine.class.getDeclaredMethod("I_PUSH"); - DISPATCH_TABLE[0xF6] = EmulatorEngine.class.getDeclaredMethod("I_ORI"); - DISPATCH_TABLE[0xF7] = EmulatorEngine.class.getDeclaredMethod("I_RST"); - DISPATCH_TABLE[0xF8] = EmulatorEngine.class.getDeclaredMethod("I_RET_COND"); // RM - DISPATCH_TABLE[0xF9] = EmulatorEngine.class.getDeclaredMethod("I_SPHL"); - DISPATCH_TABLE[0xFA] = EmulatorEngine.class.getDeclaredMethod("I_JMP_COND"); // JM - DISPATCH_TABLE[0xFB] = EmulatorEngine.class.getDeclaredMethod("I_EI"); - DISPATCH_TABLE[0xFC] = EmulatorEngine.class.getDeclaredMethod("I_CALL_COND"); // CM - DISPATCH_TABLE[0xFE] = EmulatorEngine.class.getDeclaredMethod("I_CPI"); - DISPATCH_TABLE[0xFF] = EmulatorEngine.class.getDeclaredMethod("I_RST"); - } catch (NoSuchMethodException e) { - LOGGER.error("Could not set up dispatch table. The emulator won't work correctly", e); - } - } - - private int I_NOP() { + public int I_NOP() { return 4; } - private int I_RLC() { + public int I_RLC() { int temp = (regs[REG_A] & 0x80) >>> 7; flags &= (~FLAG_C); @@ -543,7 +342,7 @@ private int I_RLC() { return 4; } - private int I_RRC() { + public int I_RRC() { int temp = regs[REG_A] & 0x01; flags &= (~FLAG_C); @@ -553,7 +352,7 @@ private int I_RRC() { return 4; } - private int I_RAL() { + public int I_RAL() { int temp = regs[REG_A] << 1; regs[REG_A] = temp & 0xFF; regs[REG_A] |= (flags & FLAG_C); @@ -563,7 +362,7 @@ private int I_RAL() { return 4; } - private int I_RAR() { + public int I_RAR() { int newCarry = regs[REG_A] & 1; regs[REG_A] = regs[REG_A] >>> 1; if ((flags & FLAG_C) == FLAG_C) { @@ -575,14 +374,14 @@ private int I_RAR() { return 4; } - private int I_SHLD() { + public int I_SHLD() { int DAR = readWord(PC); PC = (PC + 2) & 0xFFFF; memory.write(DAR, new Byte[]{(byte) regs[REG_L], (byte) regs[REG_H]}, 2); return 16; } - private int I_DAA() { + public int I_DAA() { int temp = regs[REG_A]; boolean acFlag = (flags & FLAG_AC) == FLAG_AC; @@ -610,7 +409,7 @@ private int I_DAA() { return 4; } - private int I_LHLD() { + public int I_LHLD() { int DAR = readWord(PC); PC = (PC + 2) & 0xFFFF; regs[REG_L] = readByte(DAR); @@ -618,32 +417,32 @@ private int I_LHLD() { return 16; } - private int I_CMA() { + public int I_CMA() { regs[REG_A] = ~regs[REG_A]; regs[REG_A] &= 0xFF; return 4; } - private int I_STA() { + public int I_STA() { int DAR = readWord(PC); PC = (PC + 2) & 0xFFFF; memory.write(DAR, (byte) regs[REG_A]); return 13; } - private int I_STC() { + public int I_STC() { flags |= FLAG_C; return 4; } - private int I_LDA() { + public int I_LDA() { int DAR = readWord(PC); PC = (PC + 2) & 0xFFFF; regs[REG_A] = readByte(DAR); return 13; } - private int I_CMC() { + public int I_CMC() { if ((flags & FLAG_C) != 0) { flags &= (~FLAG_C); } else { @@ -652,17 +451,17 @@ private int I_CMC() { return 4; } - private int I_HLT() { + public int I_HLT() { currentRunState = CPU.RunState.STATE_STOPPED_NORMAL; return 7; } - private int I_JMP() { + public int I_JMP() { PC = readWord(PC); return 10; } - private int I_ADI() { + public int I_ADI() { int DAR = regs[REG_A]; int diff = readByte(PC); PC = (PC + 1) & 0xFFFF; @@ -675,20 +474,20 @@ private int I_ADI() { return 7; } - private int I_RET() { + public int I_RET() { PC = readWord(SP); SP = (SP + 2) & 0xFFFF; return 10; } - private int I_CALL() { + public int I_CALL() { SP = (SP - 2) & 0xFFFF; writeWord(SP, (PC + 2) & 0xFFFF); PC = readWord(PC); return 17; } - private int I_ACI() { + public int I_ACI() { int X = regs[REG_A]; int diff = readByte(PC); PC = (PC + 1) & 0xFFFF; @@ -704,14 +503,14 @@ private int I_ACI() { return 7; } - private int I_OUT() throws IOException { + public int I_OUT() throws IOException { int DAR = readByte(PC); PC = (PC + 1) & 0xFFFF; context.fireIO(DAR, false, (byte) regs[REG_A]); return 10; } - private int I_SUI() { + public int I_SUI() { int DAR = regs[REG_A]; int diff = readByte(PC); PC = (PC + 1) & 0xFFFF; @@ -724,14 +523,14 @@ private int I_SUI() { return 7; } - private int I_IN() throws IOException { + public int I_IN() throws IOException { int DAR = readByte(PC); PC = (PC + 1) & 0xFFFF; regs[REG_A] = context.fireIO(DAR, true, (byte) 0) & 0xFF; return 10; } - private int I_SBI() { + public int I_SBI() { int DAR = regs[REG_A]; int diff = readByte(PC); PC = (PC + 1) & 0xFFFF; @@ -747,7 +546,7 @@ private int I_SBI() { return 7; } - private int I_XTHL() { + public int I_XTHL() { int DAR = readWord(SP); writeWord(SP, (regs[REG_H] << 8) | regs[REG_L]); regs[REG_H] = (DAR >>> 8) & 0xFF; @@ -755,19 +554,19 @@ private int I_XTHL() { return 18; } - private int I_ANI() { + public int I_ANI() { regs[REG_A] &= readByte(PC); PC = (PC + 1) & 0xFFFF; flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 7; } - private int I_PCHL() { + public int I_PCHL() { PC = (regs[REG_H] << 8) | regs[REG_L]; return 5; } - private int I_XCHG() { + public int I_XCHG() { int x = regs[REG_H]; int y = regs[REG_L]; regs[REG_H] = regs[REG_D]; @@ -777,36 +576,36 @@ private int I_XCHG() { return 4; } - private int I_XRI() { + public int I_XRI() { regs[REG_A] ^= readByte(PC); PC = (PC + 1) & 0xFFFF; flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 7; } - private int I_DI() { + public int I_DI() { INTE = false; return 4; } - private int I_ORI() { + public int I_ORI() { regs[REG_A] |= readByte(PC); PC = (PC + 1) & 0xFFFF; flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 7; } - private int I_SPHL() { + public int I_SPHL() { SP = ((regs[REG_H] << 8) | regs[REG_L]) & 0xFFFF; return 5; } - private int I_EI() { + public int I_EI() { INTE = true; return 4; } - private int I_CPI() { + public int I_CPI() { int X = regs[REG_A]; int DAR = regs[REG_A] & 0xFF; int diff = readByte(PC); @@ -819,7 +618,7 @@ private int I_CPI() { return 7; } - private int I_MOV() { + public int I_MOV() { putreg((lastOpcode >>> 3) & 0x07, getreg(lastOpcode & 0x07)); if (((lastOpcode & 0x07) == 6) || (((lastOpcode >>> 3) & 0x07) == 6)) { return 7; @@ -828,7 +627,7 @@ private int I_MOV() { } } - private int I_MVI() { + public int I_MVI() { putreg((lastOpcode >>> 3) & 0x07, readByte(PC)); PC = (PC + 1) & 0xFFFF; if (((lastOpcode >>> 3) & 0x07) == 6) { @@ -838,25 +637,25 @@ private int I_MVI() { } } - private int I_LXI() { + public int I_LXI() { putpair((lastOpcode >>> 4) & 0x03, readWord(PC)); PC = (PC + 2) & 0xFFFF; return 10; } - private int I_LDAX() { + public int I_LDAX() { int address = getpair((lastOpcode >>> 4) & 0x03); System.out.println(address); putreg(7, readByte(address)); return 7; } - private int I_STAX() { + public int I_STAX() { memory.write(getpair((lastOpcode >>> 4) & 0x03), (byte) getreg(7)); return 7; } - private int I_CMP() { + public int I_CMP() { int X = regs[REG_A]; int DAR = X & 0xFF; int diff = getreg(lastOpcode & 0x07); @@ -868,7 +667,7 @@ private int I_CMP() { return ((lastOpcode & 0x07) == 6) ? 7 : 4; } - private int I_JMP_COND() { + public int I_JMP_COND() { int index = (lastOpcode >>> 3) & 0x07; if ((flags & CONDITION[index]) == CONDITION_VALUES[index]) { PC = readWord(PC); @@ -878,7 +677,7 @@ private int I_JMP_COND() { return 10; } - private int I_CALL_COND() { + public int I_CALL_COND() { int index = (lastOpcode >>> 3) & 0x07; if ((flags & CONDITION[index]) == CONDITION_VALUES[index]) { int DAR = readWord(PC); @@ -892,7 +691,7 @@ private int I_CALL_COND() { } } - private int I_RET_COND() { + public int I_RET_COND() { int index = (lastOpcode >>> 3) & 0x07; if ((flags & CONDITION[index]) == CONDITION_VALUES[index]) { PC = readWord(SP); @@ -901,28 +700,28 @@ private int I_RET_COND() { return 10; } - private int I_RST() { + public int I_RST() { SP = (SP - 2) & 0xFFFF; writeWord(SP, PC); PC = lastOpcode & 0x38; return 11; } - private int I_PUSH() { + public int I_PUSH() { int DAR = getpush((lastOpcode >>> 4) & 0x03); SP = (SP - 2) & 0xFFFF; writeWord(SP, DAR); return 11; } - private int I_POP() { + public int I_POP() { int DAR = readWord(SP); SP = (SP + 2) & 0xFFFF; putpush((lastOpcode >>> 4) & 0x03, DAR); return 10; } - private int I_ADD() { + public int I_ADD() { int X = regs[REG_A]; int diff = getreg(lastOpcode & 0x07); regs[REG_A] += diff; @@ -934,7 +733,7 @@ private int I_ADD() { return ((lastOpcode & 0x07) == 6) ? 7 : 4; } - private int I_ADC() { + public int I_ADC() { int X = regs[REG_A]; int diff = getreg(lastOpcode & 0x07); if ((flags & FLAG_C) == FLAG_C) { @@ -949,7 +748,7 @@ private int I_ADC() { return ((lastOpcode & 0x07) == 6) ? 7 : 4; } - private int I_SUB() { + public int I_SUB() { int X = regs[REG_A]; int diff = getreg(lastOpcode & 0x07); regs[REG_A] -= diff; @@ -961,7 +760,7 @@ private int I_SUB() { return ((lastOpcode & 0x07) == 6) ? 7 : 4; } - private int I_SBB() { + public int I_SBB() { int X = regs[REG_A]; int diff = getreg(lastOpcode & 0x07); if ((flags & FLAG_C) != 0) { @@ -976,33 +775,33 @@ private int I_SBB() { return ((lastOpcode & 0x07) == 6) ? 7 : 4; } - private int I_INR() { + public int I_INR() { int DAR = (getreg((lastOpcode >>> 3) & 0x07) + 1) & 0xFF; flags = (short) (EmulatorTables.INC_TABLE[DAR] | (flags & FLAG_C)); putreg((lastOpcode >>> 3) & 0x07, DAR); return 5; } - private int I_DCR() { + public int I_DCR() { int DAR = (getreg((lastOpcode >>> 3) & 0x07) - 1) & 0xFF; flags = (short) (EmulatorTables.DEC_TABLE[DAR] | (flags & FLAG_C)); putreg((lastOpcode >>> 3) & 0x07, DAR); return 5; } - private int I_INX() { + public int I_INX() { int DAR = (getpair((lastOpcode >>> 4) & 0x03) + 1) & 0xFFFF; putpair((lastOpcode >>> 4) & 0x03, DAR); return 5; } - private int I_DCX() { + public int I_DCX() { int DAR = (getpair((lastOpcode >>> 4) & 0x03) - 1) & 0xFFFF; putpair((lastOpcode >>> 4) & 0x03, DAR); return 5; } - private int I_DAD() { + public int I_DAD() { int DAR = getpair((lastOpcode >>> 4) & 0x03); DAR += getpair(2); if ((DAR & 0x10000) != 0) { @@ -1015,72 +814,21 @@ private int I_DAD() { return 10; } - private int I_ANA() { + public int I_ANA() { regs[REG_A] &= getreg(lastOpcode & 0x07); flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 4; } - private int I_XRA() { + public int I_XRA() { regs[REG_A] ^= getreg(lastOpcode & 0x07); flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 4; } - private int I_ORA() { + public int I_ORA() { regs[REG_A] |= getreg(lastOpcode & 0x07); flags = EmulatorTables.SIGN_ZERO_PARITY_TABLE[regs[REG_A]]; return 4; } - - private int dispatch() throws InvocationTargetException, IllegalAccessException { - DispatchListener tmpListener = dispatchListener; - if (tmpListener != null) { - tmpListener.beforeDispatch(); - } - - /* if interrupt is waiting, instruction won't be read from memory - * but from one or all of 3 bytes (b1,b2,b3) which represents either - * rst or call instruction incomed from external peripheral device - */ - if (isINT) { - if (INTE) { - if ((b1 & 0xC7) == 0xC7) { /* RST */ - SP = (SP - 2) & 0xFFFF; - writeWord(SP, PC); - PC = b1 & 0x38; - return 11; - } else if (b1 == 0xCD) { /* CALL */ - SP = (SP - 2) & 0xFFFF; - writeWord(SP, (PC + 2) & 0xFFFF); - PC = ((b3 & 0xFF) << 8) | (b2 & 0xFF); - return 17; - } - } - isINT = false; - } - - lastOpcode = 0; - try { - lastOpcode = (byte)readByte(PC); - } catch (NullPointerException e) { - LOGGER.error("NPE; PC=" + Integer.toHexString(PC), e); - currentRunState = CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; - return 0; - } - PC = (PC + 1) & 0xFFFF; - - try { - Method instr = DISPATCH_TABLE[lastOpcode & 0xFF]; - if (instr == null) { - currentRunState = CPU.RunState.STATE_STOPPED_BAD_INSTR; - return 0; - } - return (Integer) instr.invoke(this); - } finally { - if (tmpListener != null) { - tmpListener.afterDispatch(); - } - } - } } diff --git a/plugins/cpu/z80-cpu/build.gradle b/plugins/cpu/z80-cpu/build.gradle index 9e9e9775e..a6ebd0cd9 100644 --- a/plugins/cpu/z80-cpu/build.gradle +++ b/plugins/cpu/z80-cpu/build.gradle @@ -22,6 +22,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' id 'net.emustudio.edigen-plugin' version '1.4.0' + id 'com.adarshr.test-logger' version '3.1.0' } repositories { diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TablesGenerator.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TablesGenerator.java deleted file mode 100644 index 7b8bc76bd..000000000 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TablesGenerator.java +++ /dev/null @@ -1,71 +0,0 @@ -package net.emustudio.plugins.cpu.zilogZ80; - -import org.junit.Test; - -import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.FLAG_C; -import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.FLAG_Z; - -public class TablesGenerator { - int FLAG_S_SHIFT = 7; - int FLAG_Z_SHIFT = 6; - int FLAG_H_SHIFT = 4; - int FLAG_PV_SHIFT = 2; - int FLAG_N_SHIFT = 1; - int FLAG_C_SHIFT = 0; - - @Test - public void generateOverFlow() { - // carryIns = *acc ^ a ^ b; - // carryOut = 1 IFF (a + b > 0xFF) or, - // equivalently, but avoiding overflow in C: (a > 0xFF - b). - // overflowOut = (carryIns >> 7) ^ carryOut; - // halfCarryOut = (carryIns >> 4) & 1; - // zeroOut = sum == 0 - // signOut = sum & 0x80 - - System.out.print(" final static byte[] SZHPC_TABLE = {\n "); - - for (int a = 0; a < 256; a++) { - for (int b = 0; b < 256; b++) { - int sum = (a + b) & 0xFF; // index to the array - - int carryOut = (a > 0xFF - b) ? FLAG_C : 0; - int carryIns = sum ^ a ^ b; - int halfCarryOut = (carryIns >> 4) & 1; - int overflowOut = (carryIns >> 7) ^ carryOut; - - int result = carryOut | (halfCarryOut << FLAG_H_SHIFT) | (overflowOut << FLAG_PV_SHIFT) | (sum == 0 ? FLAG_Z : 0) | (sum & 0x80); - System.out.print(result + ","); - } - if (((a + 1) & 0x03) == 0) { - System.out.print("\n "); - } - } - System.out.println("};"); - } - - - @Test - public void testFlags() { - int a = 0x65; - int b = ((~0xE4) + 1) & 0xFF; - - int sum = (a + b) ; //& 0xFF; // index to the array - - System.out.println(Integer.toBinaryString(a)); - System.out.println(Integer.toBinaryString(b)); - System.out.println(Integer.toBinaryString(sum)); - - int carryOut = (a > 0xFF - b) ? 1 : 0; - int carryIns = sum ^ a ^ b; - int halfCarryOut = (carryIns >> 4) & 1; - int overflowOut = (((carryIns >> 7) ^ carryOut) != 0) ? 1 : 0; - - System.out.println("C=" + carryOut); - System.out.println("H=" + halfCarryOut); - System.out.println("P=" + overflowOut); - System.out.println("S=" + (((sum & 0x80) != 0) ? 1 : 0)); - - //System.out.println(intToFlags(SZHPC_TABLE[sum & 0x1FF])); - } -} From 98af8511fad855718f311953c88c1075f10905a7 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 2 Feb 2022 18:14:34 +0100 Subject: [PATCH 091/314] [#201] z80: disassembler --- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 482 ++++++++++++-------- 1 file changed, 298 insertions(+), 184 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index 50787702d..7a6113671 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -1,118 +1,198 @@ root instruction; -instruction = "nop": 00000000 | "ex (SP),HL": 0xE3 | "ex DE,HL": 0xEB | "ld SP,HL": 0xF9 | "ei": 0xFB | "di": 0xF3 | - "halt": 0x76 | "daa": 0x27 | "cpl": 0x2F | "scf": 0x37 | "ccf": 0x3F | "ret": 0xC9 | "rlca": 0x07 | - "rrca": 0x0F | "rla": 0x17 | "rra": 0x1F | "jp (HL)": 0xE9 | "ret NZ": 0xC0 | "ret Z": 0xC8 | - "ret NC": 0xD0 | "ret C": 0xD8 | "ret PO": 0xE0 | "ret PE": 0xE8 | "ret P": 0xF0 | "ret M": 0xF8 | - "ex AF,AF'": 00001000 | "exx": 0xD9 | - - "inc": 000 BCDE(1) 0011 | "dec": 000 BCDE(1) 1011 | "add HL,": 000 BCDE(1) 1001 | - "pop": 110 BCDE(1) 0001 | "push": 110 BCDE(1) 0101 | - - "inc": 001 HLSP(1) 0011 | "dec": 001 HLSP(1) 1011 | "add HL,": 001 HLSP(1) 1001 | - - "pop": 111 HLPSW(1) 0001 | "push": 111 HLPSW(1) 0101 | - - "inc": 00 REG(3) 100 | "dec": 00 REG(3) 101 | "add": 0x8 0 REG | "adc": 0x8 1 REG | "sub": 0x9 0 REG | - "sbc": 0x9 1 REG | "and": 0xA 0 REG | "xor": 0xA 1 REG | "or": 0xB 0 REG | "cp": 0xB 1 REG | - - "sbc": 0xDE imm8 | "add A,": 0xC6 imm8 | "adc A,": 0xCE imm8 | "sub": 0xD6 imm8 | "and": 0xE6 imm8 | - "or": 0xF6 imm8 | "xor": 0xEE imm8 | "cp": 0xFE imm8 | "in A,": 0xDB imm8 | "jr": 0x18 imm8 | - "djnz": 0x10 imm8 | "jr NZ,": 0x20 imm8 | "jr Z,": 0x28 imm8 | "jr NC,": 0x30 imm8 | "jr C,": 0x38 imm8 | - - "jp": 0xC3 address | "jp NZ,": 0xC2 address | "jp Z,": 0xCA address | "jp NC,": 0xD2 address | - "jp C,": 0xDA address | "jp PO,": 0xE2 address | "jp PE,": 0xEA address | "jp P,": 0xF2 address | - "jp M,": 0xFA address | "call": 0xCD address | "call NZ,": 0xC4 address | "call Z,": 0xCC address | - "call NC,": 0xD4 address | "call C,": 0xDC address | "call PO,": 0xE4 address | "call PE,": 0xEC address | - "call P,": 0xF4 address | "call M,": 0xFC address | - - "rst": 11 NUMBER(3) 111 | - - "out": 0xD3 imm8_OUT | - - "ld": 00101010 imm16_LHLD | - - "ld": 00100010 imm16_SHLD | - - "ld": 000 BCDE(1) 0001 imm16 | - - "ld": 001 HLSP(1) 0001 imm16 | - - "ld": 00 REG(3) 110 imm8 | - - "ld": 000 BCDE_LDAX(1) 1010 | - - "ld": 000 BCDE_STAX(1) 0010 | - - "ld": 00111010 imm16_LDA | - - "ld": 00110010 imm16_STA | - - "ld": 010 REG_BCDE(2) REG | - - "ld": 0110 REG_HL(1) REG | - - "ld": 01 REG_A[111](3) REG | - - "ld": 011100 REG_BCDE | - - "ld": 0111010 REG_HL | - - "ld": 01110 REG_A[111](3) | - - 0xDD ddINSTR | 0xFD fdINSTR | 0xCB cbINSTR | 0xED edINSTR; - -cbINSTR = "rlc": 00000 REG | "rl": 00010 REG | "rrc": 00001 REG | "rr": 00011 REG | "bit": 01 BIT(3) REG | - "res": 10 BIT(3) REG | "set": 11 BIT(3) REG | "sla": 00100 REG | "sra": 00101 REG | "srl": 00111 REG | - "sll": 00110 REG - ; - -ddINSTR = "ld": 010 REG_BCDE(2) 110 index | - - "ld": 0110 REG_HL(1) 110 index | - - "ld": 01 REG_A[111](3) 110 index | - - "ld": 01 M[110](3) 0 REG_BCDE(2) index | - - "ld": 01 M[110](3) 10 REG_HL(1) index | - - "ld": 01 M[110](3) REG_A[111](3) index | - - "ld": 0x36 index(8) imm8 | - - "ld": 00100001 imm16 | - - "ld": 00101010 address | - - "ld": 00100010 address_LDIX | - - "ld SP,IX": 0xF9 | "ex (SP),IX": 0xE3 | "inc IX" : 0x23 | "dec IX": 0x2B | "jp (IX)": 0xE9 | "push IX": 0xE5 | - "pop IX": 0xE1 | - - "add": 0x86 index | "adc": 0x8E index | "sub": 0x96 index | "sbc": 0x9E index | "inc": 0x34 index | - "dec": 0x35 index | "and": 0xA6 index | "xor": 0xAE index | "or": 0xB6 index | "cp": 0xBE index | - - "add": 00 BCDEIXSP(2) 1001 | - - "ld": 0x76 index(8) imm8 | - - 0xCB index(8) ddcbINSTR; - - -fdINSTR = "ld": 010 REG_BCDE(2) 110 index | - - "ld": 0110 REG_HL(1) 110 index | - - "ld": 01 REG_A[111](3) 110 index | - - "ld": 01 M[110](3) 0 REG_BCDE(2) index | - - "ld": 01 M[110](3) 10 REG_HL(1) index | - - "ld": 01 M[110](3) REG_A[111](3) index | - - "ld": 0x36 index(8) imm8 | +instruction = + "nop": 0x00 | # 0x00 + "ld": 00 BC_DE_HL_SP(2) 0001 imm16 | # 0x01, 0x11, 0x21, 0x31 + "ld": 000 REF_BC_DE_A(1) 0010 | # 0x02, 0x12 + "inc": 00 BC_DE_HL_SP(2) 0011 | # 0x03, 0x13, 0x23, 0x33 + "inc": 00 REG(3) 100 | # 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34, 0x3C + "dec": 00 REG(3) 101 | # 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, 0x35, 0x3D + "ld": 00 REG(3) 110 imm8 | # 0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, 0x36, 0x3E + "rlca": 0x07 | # 0x07 + "ex AF,AF'": 0x08 | # 0x08 + "add HL,": 00 BC_DE_HL_SP(2) 1001 | # 0x09, 0x19, 0x29, 0x39 + "ld": 000 A_REF_BC_DE(1) 1010 | # 0x0A, 0x1A + "dec": 00 BC_DE_HL_SP(2) 1011 | # 0x0B, 0x1B, 0x2B, 0x3B + "rrca": 0x0F | # 0x0F + "djnz": 0x10 imm8 | # 0x10 + "rla": 0x17 | # 0x17 + "jr": 0x18 imm8 | # 0x18 + "rra": 0x1F | # 0x1F + "jr": 001 FLAGS_JR(2) 000 imm8 | # 0x20, 0x28, 0x30, 0x38 + "ld": 0x22 REF_imm16_HL | # 0x22 + "daa": 0x27 | # 0x27 + "ld": 0x2A HL_REF_imm16 | # 0x2A + "cpl": 0x2F | # 0x2F + "ld": 0x32 REF_imm16_A | # 0x32 + "scf": 0x37 | # 0x37 + "ld": 0x3A A_REF_imm16 | # 0x3A + "ccf": 0x3F | # 0x3F + "ld": 01 0 REG_B_C_D_E(2) REG | # 0x40 - 0x5F + "ld": 01 10 REG_H_L(1) REG | # 0x60 - 0x6F + "ld (HL),": 01 1100 REG_B_C_D_E(2) | # 0x70 - 0x73 + "ld (HL),": 01 11010 REG_H_L(1) | # 0x74, 0x75 + "halt": 0x76 | # 0x76 + "ld (HL), A": 0x77 | # 0x77 + "ld A,": 01 111 REG | # 0x78 - 0x7F + "add A,": 0x8 0 REG | # 0x80 - 0x87 + "adc A,": 0x8 1 REG | # 0x88 - 0x8F + "sub": 0x9 0 REG | # 0x90 - 0x97 + "sbc A,": 0x9 1 REG | # 0x98 - 0x9F + "and": 0xA 0 REG | # 0xA0 - 0xA7 + "xor": 0xA 1 REG | # 0xA8 - 0xAF + "or": 0xB 0 REG | # 0xB0 - 0xB7 + "cp": 0xB 1 REG | # 0xB8 - 0xBF + "ret NZ": 0xC0 | # 0xC0 + "pop": 110 BC_DE(1) 0001 | # 0xC1, 0xD1, 0xE1 + "pop": 111 HL_AF(1) 0001 | # 0xF1 + "jp": 11 FLAGS(3) 010 imm16 | # 0xC2, 0xCA, 0xD2, 0xDA, 0xE2, 0xEA, 0xF2, 0xFA + "jp": 0xC3 imm16 | # 0xC3 + "call": 11 FLAGS(3) 100 imm16 | # 0xC4, 0xCC, 0xD4, 0xDC, 0xE4, 0xEC, 0xF4, 0xFC + "push": 110 BC_DE(1) 0101 | # 0xC5, 0xD5 + "push": 111 HL_AF(1) 0101 | # 0xE5, 0xF5 + "add A,": 0xC6 imm8 | # 0xC6 + "rst": 11 NUMBER(3) 111 | # 0xC7, 0xCF, 0xD7, 0xDF, 0xE7, 0xEF, 0xF7, 0xFF + "ret Z": 0xC8 | # 0xC8 + "ret": 0xC9 | # 0xC9 + + 0xCB cbInstruction | # 0xCB + + "call": 0xCD imm16 | # 0xCD + "adc A,": 0xCE imm8 | # 0xCE + "ret NC": 0xD0 | # 0xD0 + "out": 0xD3 REF_imm8_A | # 0xD3 + "sub": 0xD6 imm8 | # 0xD6 + "ret C": 0xD8 | # 0xD8 + "exx": 0xD9 | # 0xD9 + "in A,": 0xDB REF_imm8 | # 0xDB + + 0xDD ddInstruction | # 0xDD + + "sbc": 0xDE imm8 | # 0xDE + "ret PO": 0xE0 | # 0xE0 + "ex (SP), HL": 0xE3 | # 0xE3 + "and": 0xE6 imm8 | # 0xE6 + "ret PE": 0xE8 | # 0xE8 + "jp (HL)": 0xE9 | # 0xE9 + "ex DE, HL": 0xEB | # 0xEB + + 0xED edINSTR | # 0xED + + "xor": 0xEE imm8 | # 0xEE + "ret P": 0xF0 | # 0xF0 + "di": 0xF3 | # 0xF3 + "or": 0xF6 imm8 | # 0xF6 + "ret M": 0xF8 | # 0xF8 + "ld SP,HL": 0xF9 | # 0xF9 + "ei": 0xFB | # 0xFB + + 0xFD fdINSTR | # 0xFD + + "cp": 0xFE imm8 ; # 0xFE + + +cbInstruction = + "rlc": 00000 REG | # 0x00 - 0x07 + "rrc": 00001 REG | # 0x08 - 0x0F + "rl": 00010 REG | # 0x10 - 0x17 + "rr": 00011 REG | # 0x18 - 0x1F + "sla": 00100 REG | # 0x20 - 0x27 + "sra": 00101 REG | # 0x28 - 0x2F + "sll": 00110 REG | # 0x30 - 0x37 + "srl": 00111 REG | # 0x38 - 0x3F + "bit": 01 BIT(3) REG | # 0x40 - 0x7F + "res": 10 BIT(3) REG | # 0x80 - 0xBF + "set": 11 BIT(3) REG ; # 0xC0 - 0xFF + + + + + +# DISPATCH_TABLE_DD[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_IX", retInt); +# DISPATCH_TABLE_DD[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_IX", retInt); + + +ddInstruction = + "add IX,": 00 BC_DE_IX_SP(2) 1001 | # 0x09, 0x19, 0x29, 0x39 + "ld IX,": 0x21 imm16 | # 0x21 + "ld": 0x22 REF_imm16_IX | # 0x22 + "inc IX": 0x23 | # 0x23 + "inc IXH": 0x24 | # 0x24 + "dec IXH": 0x25 | # 0x25 + "ld IXH,": 0x26 imm8 | # 0x26 + "ld IX,": 0x2A REF_imm16 | # 0x2A + "dec IX": 0x2B | # 0x2B + "inc IXL": 0x2C | # 0x2C + "dec IXL": 0x2D | # 0x2D + "ld IXL,": 0x2E imm8 | # 0x2E + "inc": 0x34 REF_II_N | # 0x34 + "dec": 0x35 REF_II_N | # 0x35 + "ld": 0x36 REF_II_N(8) imm8 | # 0x36 + "ld": 010 REG_B_C_D_E_IXH(2) 100 | # 0x44, 0x4C, 0x54, 0x5C + "ld A, IXH": 0x7C | # 0x7C + "ld": 010 REG_B_C_D_E_IXL(2) 101 | # 0x45, 0x4D, 0x55, 0x5D + "ld A, IXL": 0x7D | # 0x7D + "ld": 010 REG_B_C_D_E(2) 110 REF_II_N | # 0x46, 0x4E, 0x56, 0x5E + "ld": 0110 REG_H_L(1) 110 REF_II_N | # 0x66, 0x6E + "ld A,": 0x7E REF_II_N | # 0x7E + "ld IXH,": 0110 00 REG_B_C_D_E(2) | # 0x60 - 063 + "ld IXH, IXH": 0x64 | # 0x64 + "ld IXH, IXL": 0x65 | # 0x65 + "ld IXH, A": 0x67 | # 0x67 + "ld IXL,": 0110 10 REG_B_C_D_E(2) | # 0x68 - 0x6B + "ld IXL, IXH": 0x6C | # 0x6C + "ld IXL, IXL": 0x6D | # 0x6D + "ld IXL, A": 0x6F | # 0x6F + "ld": 01110 0 REG_B_C_D_E(2) REF_II_N_2 | # 0x70 - 0x73 + "ld": 01110 10 REG_H_L(1) REF_II_N_2 | # 0x74, 0x75 + "ld": 01110 REG_A[111](3) REF_II_N_2 | # 0x77 + "add A, IXH": 0x84 | # 0x84 + "add A, IXL": 0x85 | # 0x85 + "add A,": 0x86 REF_II_N | # 0x86 + "adc A, IXH": 0x8C | # 0x8C + "adc A, IXL": 0x8D | # 0x8D + "adc A,": 0x8E REF_II_N | # 0x8E + "sub IXH": 0x94 | # 0x94 + "sub IXL": 0x95 | # 0x95 + "sub": 0x96 REF_II_N | # 0x96 + "sbc A, IXH": 0x9C | # 0x9C + "sbc A, IXL": 0x9D | # 0x9D + "sbc A,": 0x9E REF_II_N | # 0x9E + "and IXH": 0xA4 | # 0xA4 + "and IXL": 0xA5 | # 0xA5 + "and": 0xA6 REF_II_N | # 0xA6 + "xor IXH": 0xAC | # 0xAC + "xor IXL": 0xAD | # 0xAD + "xor": 0xAE REF_II_N | # 0xAE + "or IXH": 0xB4 | # 0xB4 + "or IXL": 0xB5 | # 0xB5 + "or": 0xB6 REF_II_N | # 0xB6 + "cp IXH": 0xBC | # 0xBC + "cp IXL": 0xBD | # 0xBD + "cp": 0xBE REF_II_N | # 0xBE + + 0xCB REF_II_N(8) ddcbInstruction | # 0xCB + + "pop IX": 0xE1 | # 0xE1 + "ex (SP), IX": 0xE3 | # 0xE3 + "push IX": 0xE5 | # 0xE5 + "jp (IX)": 0xE9 | # 0xE9 + "ld SP,IX": 0xF9 ; # 0xF9 + + +fdINSTR = "ld": 010 REG_B_C_D_E(2) 110 REF_II_N | + + "ld": 0110 REG_H_L(1) 110 REF_II_N | + + "ld": 01 REG_A[111](3) 110 REF_II_N | + + "ld": 01 M[110](3) 0 REG_B_C_D_E(2) REF_II_N | + + "ld": 01 M[110](3) 10 REG_H_L(1) REF_II_N | + + "ld": 01 M[110](3) REG_A[111](3) REF_II_N | + + "ld": 0x36 REF_II_N(8) imm8 | "ld": 00100001 imm16 | @@ -123,27 +203,27 @@ fdINSTR = "ld": 010 REG_BCDE(2) 110 index | "ld SP,IY": 0xF9 | "ex (SP),IY": 0xE3 | "inc IY" : 0x23 | "dec IY": 0x2B | "jp (IY)": 0xE9 | "push IY": 0xE5 | "pop IY": 0xE1 | - "add": 0x86 index | "adc": 0x8E index | "sub": 0x96 index | "sbc": 0x9E index | "inc": 0x34 index | - "dec": 0x35 index | "and": 0xA6 index | "xor": 0xAE index | "or": 0xB6 index | "cp": 0xBE index | + "add": 0x86 REF_II_N | "adc": 0x8E REF_II_N | "sub": 0x96 REF_II_N | "sbc": 0x9E REF_II_N | "inc": 0x34 REF_II_N | + "dec": 0x35 REF_II_N | "and": 0xA6 REF_II_N | "xor": 0xAE REF_II_N | "or": 0xB6 REF_II_N | "cp": 0xBE REF_II_N | "add": 00 BCDEIYSP(2) 1001 | - "ld": 0x76 index(8) imm8 | + "ld": 0x76 REF_II_N(8) imm8 | - 0xCB index(8) fdcbINSTR; + 0xCB REF_II_N(8) fdcbINSTR; -ddcbINSTR = "rlc": 00000110 | "rl": 00010110 | "rrc": 00001110 | "rr": 00011110 | "sla": 0x26 | "sra": 0x2E | +ddcbInstruction = "rlc": 00000110 | "rl": 00010110 | "rrc": 00001110 | "rr": 00011110 | "sla": 0x26 | "sra": 0x2E | "srl": 0x3E | "sll": 0x36 | "bit": 01 BIT(3) 110 | "res": 10 BIT(3) 110 | "set": 11 BIT(3) 110; fdcbINSTR = "rlc": 00000110 | "rl": 00010110 | "rrc": 00001110 | "rr": 00011110 | "sla": 0x26 | "sra": 0x2E | "srl": 0x3E | "sll": 0x36 | "bit": 01 BIT(3) 110 | "res": 10 BIT(3) 110 | "set": 11 BIT(3) 110; -edINSTR = "ld": 010 BCDE(1) 1011 imm16 | "ld": 011 HLSP(1) 1011 imm16 | +edINSTR = "ld": 010 BC_DE(1) 1011 imm16 | "ld": 011 HLSP(1) 1011 imm16 | - "ld": 010 BCDE(1) 0011 address | "ld": 011 HLSP(1) 0011 address | + "ld": 010 BC_DE(1) 0011 address | "ld": 011 HLSP(1) 0011 address | - "adc HL,": 010 BCDE(1) 1010 | "sbc HL,": 010 BCDE(1) 0010 | + "adc HL,": 010 BC_DE(1) 1010 | "sbc HL,": 010 BC_DE(1) 0010 | "adc HL,": 011 HLSP(1) 1010 | "sbc HL,": 011 HLSP(1) 0010 | @@ -155,96 +235,130 @@ edINSTR = "ld": 010 BCDE(1) 1011 imm16 | "ld": 011 HLSP(1) 1011 imm16 | "in": 01 REG(3) 000 | "out": 01 REG_OUT(3) 001; -BCDEIXSP = "BC": 00 | "DE": 01 | "IX": 10 | "SP": 11; +BC_DE_HL_SP = "BC": 00 | "DE": 01 | "HL": 10 | "SP": 11; +FLAGS_JR = "NZ": 00 | "Z": 01 | "NC": 10 | "C": 11; +FLAGS = "NZ": 000 | "Z": 001 | "NC": 010 | "C": 011 | "PO": 100 | "PE": 101 | "P": 110 | "M": 111; + +REG_B_C_D_E,REG_B_C_D_E_IXH,REG_B_C_D_E_IXL = "B": 00 | "C": 01 | "D": 10 | "E": 11; +REG_H_L = "H": 0 | "L": 1; +REG_A = "A": 111; + + + + +BC_DE_IX_SP = "BC": 00 | "DE": 01 | "IX": 10 | "SP": 11; BCDEIYSP = "BC": 00 | "DE": 01 | "IY": 10 | "SP": 11; -BCDE = "BC" : 0 | "DE" : 1; + HLSP = "HL": 0 | "SP" : 1; -BCDE_STAX,BCDE_LDAX = "BC" : 0 | "DE" : 1; -HLPSW = "HL" : 0 | "AF" : 1; +BC_DE, REF_BC_DE_A, A_REF_BC_DE = "BC" : 0 | "DE" : 1; +HL_AF = "HL" : 0 | "AF" : 1; REG,REG_OUT = "B": 000 | "C": 001 | "D": 010 | "E": 011 | "H": 100 | "L": 101 | "(HL)": 110 | "A": 111; -REG_BCDE = "B": 00 | "C": 01 | "D": 10 | "E": 11; -REG_HL = "H": 0 | "L": 1; -REG_A = "A": 111; - M = "(HL)": 110; NUMBER = "00": 000 | "08": 001 | "10": 010 | "18": 011 | "20": 100 | "28": 101 | "30": 110 | "38": 111; -imm8,index,imm8_OUT = imm8: imm8(8); +imm8,REF_II_N,REF_II_N_2,REF_imm8_A,REF_imm8 = imm8: imm8(8); BIT = bit: bit(3); -imm16,address,address_LDIX,imm16_SHLD,imm16_LHLD,imm16_LDA,imm16_STA = imm16: imm16(16); +REF_imm16_HL, HL_REF_imm16, imm16, REF_imm16, REF_imm16_IX, address, address_LDIX, A_REF_imm16, REF_imm16_A = imm16: imm16(16); %% - -"%s %s, %s" = instruction REG_BCDE REG; -"%s %s, %s" = instruction REG_HL REG; -"%s %s, %s" = instruction REG_A REG; -"%s (HL), %s" = instruction REG_BCDE; -"%s (HL), %s" = instruction REG_HL; -"%s (HL), %s" = instruction REG_A; -"%s A,(%X)" = instruction imm16_LDA; -"%s (%X),A" = instruction imm16_STA; -"%s A, (%s)" = instruction BCDE_LDAX; -"%s (%s), A" = instruction BCDE_STAX; -"%s %s, %X" = instruction BCDE imm16; -"%s %s, %X" = instruction HLSP imm16; -"%s (%X),HL" = instruction imm16_SHLD; -"%s HL,(%X)" = instruction imm16_LHLD; +"%s %d, %s" = cbInstruction BIT REG; + +"%s (IX + %X), %X" = ddInstruction REF_II_N imm8; +"%s %s, (IX + %X)" = ddInstruction REG_B_C_D_E REF_II_N; +"%s (IX + %X), %s" = ddInstruction REF_II_N_2 REG_B_C_D_E; +"%s %s, (IX + %X)" = ddInstruction REG_H_L REF_II_N; +"%s (IX + %X), %s" = ddInstruction REF_II_N_2 REG_H_L; +"%s (IX + %X), %s" = ddInstruction REF_II_N_2 REG_A; + +"%s %s, %X" = instruction BC_DE_HL_SP imm16; +"%s %s, %s" = instruction REG_B_C_D_E REG; +"%s %s, %s" = instruction REG_H_L REG; "%s %s, %X" = instruction REG imm8; -"%s (%X),A" = instruction imm8_OUT; -"%s %s" = instruction NUMBER; -"%s %X" = instruction address; +"%s %s, %X" = instruction FLAGS_JR imm8; +"%s %s, %X" = instruction FLAGS imm16; + +"%s %s" = cbInstruction REG; + +"%s %s" = ddInstruction BC_DE_IX_SP; +"%s %X" = ddInstruction imm8; +"%s %X" = ddInstruction imm16; +"%s (%X)" = ddInstruction REF_imm16; +"%s (%X), IX" = ddInstruction REF_imm16_IX; +"%s (IX + %X)" = ddInstruction REF_II_N; +"%s %s" = ddInstruction REG_B_C_D_E; +"%s %s, IXH" = ddInstruction REG_B_C_D_E_IXH; +"%s %s, IXL" = ddInstruction REG_B_C_D_E_IXL; + + +"%s (%s), A" = instruction REF_BC_DE_A; +"%s A, (%s)" = instruction A_REF_BC_DE; +"%s %s" = instruction BC_DE_HL_SP; "%s %s" = instruction REG; -"%s %s" = instruction HLPSW; -"%s %s" = instruction HLSP; -"%s %s" = instruction BCDE; "%s %X" = instruction imm8; +"%s A, (%X)" = instruction A_REF_imm16; +"%s (%X), A" = instruction REF_imm16_A; +"%s %s" = instruction BC_DE; +"%s %s" = instruction HL_AF; +"%s %s" = instruction REG_H_L; +"%s %X" = instruction imm16; +"%s %s" = instruction NUMBER; +"%s (%X), A" = instruction REF_imm8_A; +"%s (%X)" = instruction REF_imm8; + +"%s" = ddInstruction; +"%s" = instruction; + + + +############################### + -"%s %s,(IX+%X)" = ddINSTR REG_BCDE index; -"%s %s,(IX+%X)" = ddINSTR REG_HL index; -"%s A,(IX+%X)" = ddINSTR REG_A index; -"%s (IX+%X),%s" = ddINSTR index REG_BCDE M; -"%s (IX+%X),%s" = ddINSTR index REG_HL M; -"%s (IX+%X),A" = ddINSTR index REG_A M; -"%s (IX+%X),%X" = ddINSTR index imm8; -"%s (IX+%X)" = ddcbINSTR index; -"%s (IX+%X)" = ddINSTR index; -"%s IX,%s" = ddINSTR BCDEIXSP; -"%s IX,%X" = ddINSTR imm16; -"%s IX,(%X)" = ddINSTR address; -"%s (%X),IX" = ddINSTR address_LDIX; -"%s %d,(IX+%X)" = ddcbINSTR BIT index; -"%s" = ddINSTR; - -"%s %s,(IY+%X)" = fdINSTR REG_BCDE index; -"%s %s,(IY+%X)" = fdINSTR REG_HL index; -"%s A,(IY+%X)" = fdINSTR REG_A index; -"%s (IY+%X),%s" = fdINSTR index REG_BCDE M; -"%s (IY+%X),%s" = fdINSTR index REG_HL M; -"%s (IY+%X),A" = fdINSTR index REG_A M; -"%s (IY+%X),%X" = fdINSTR index imm8; -"%s (IY+%X)" = fdcbINSTR index; -"%s (IY+%X)" = fdINSTR index; +"%s (%X), HL" = instruction REF_imm16_HL; +"%s HL, (%X)" = instruction HL_REF_imm16; + +"%s %X" = instruction address; +"%s %s" = instruction HLSP; # TODO: get rid + +"%s %s" = instruction REG_B_C_D_E; + + +"%s A,(IX+%X)" = ddInstruction REG_A REF_II_N; +"%s (IX+%X),%s" = ddInstruction REF_II_N REG_B_C_D_E M; +"%s (IX+%X),%s" = ddInstruction REF_II_N REG_H_L M; +"%s (IX+%X),A" = ddInstruction REF_II_N REG_A M; + +"%s (IX+%X)" = ddcbInstruction REF_II_N; +"%s %d,(IX+%X)" = ddcbInstruction BIT REF_II_N; + +"%s %s,(IY+%X)" = fdINSTR REG_B_C_D_E REF_II_N; +"%s %s,(IY+%X)" = fdINSTR REG_H_L REF_II_N; +"%s A,(IY+%X)" = fdINSTR REG_A REF_II_N; +"%s (IY+%X),%s" = fdINSTR REF_II_N REG_B_C_D_E M; +"%s (IY+%X),%s" = fdINSTR REF_II_N REG_H_L M; +"%s (IY+%X),A" = fdINSTR REF_II_N REG_A M; +"%s (IY+%X),%X" = fdINSTR REF_II_N imm8; +"%s (IY+%X)" = fdcbINSTR REF_II_N; +"%s (IY+%X)" = fdINSTR REF_II_N; "%s IY,%s" = fdINSTR BCDEIYSP; "%s IY,%X" = fdINSTR imm16; "%s IY,(%X)" = fdINSTR address; "%s (%X),IY" = fdINSTR address_LDIX; -"%s %d,(IY+%X)" = fdcbINSTR BIT index; +"%s %d,(IY+%X)" = fdcbINSTR BIT REF_II_N; "%s" = fdINSTR; -"%s %s" = cbINSTR REG; -"%s %d, %s" = cbINSTR BIT REG; -"%s %s,%X" = edINSTR BCDE imm16; + +"%s %s,%X" = edINSTR BC_DE imm16; "%s %s,%X" = edINSTR HLSP imm16; -"%s (%X),%s" = edINSTR address BCDE; +"%s (%X),%s" = edINSTR address BC_DE; "%s (%X),%s" = edINSTR address HLSP; -"%s%s" = edINSTR BCDE; +"%s%s" = edINSTR BC_DE; "%s%s" = edINSTR HLSP; "%s %s,(C)" = edINSTR REG; "%s (C),%s" = edINSTR REG_OUT; "%s" = edINSTR; -"%s" = instruction; + From 089f7e830adf3aa49e1b9cf1ae1d6dd067e8dda4 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 3 Feb 2022 17:54:23 +0100 Subject: [PATCH 092/314] [#201] z80: disassembler finished --- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 433 +++++++++++++------- 1 file changed, 293 insertions(+), 140 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index 7a6113671..62c8c11dc 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -76,7 +76,7 @@ instruction = "jp (HL)": 0xE9 | # 0xE9 "ex DE, HL": 0xEB | # 0xEB - 0xED edINSTR | # 0xED + 0xED edInstruction | # 0xED "xor": 0xEE imm8 | # 0xEE "ret P": 0xF0 | # 0xF0 @@ -86,7 +86,7 @@ instruction = "ld SP,HL": 0xF9 | # 0xF9 "ei": 0xFB | # 0xFB - 0xFD fdINSTR | # 0xFD + 0xFD fdInstruction | # 0xFD "cp": 0xFE imm8 ; # 0xFE @@ -104,18 +104,10 @@ cbInstruction = "res": 10 BIT(3) REG | # 0x80 - 0xBF "set": 11 BIT(3) REG ; # 0xC0 - 0xFF - - - - -# DISPATCH_TABLE_DD[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_IX", retInt); -# DISPATCH_TABLE_DD[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_IX", retInt); - - ddInstruction = "add IX,": 00 BC_DE_IX_SP(2) 1001 | # 0x09, 0x19, 0x29, 0x39 "ld IX,": 0x21 imm16 | # 0x21 - "ld": 0x22 REF_imm16_IX | # 0x22 + "ld": 0x22 REF_imm16_II | # 0x22 "inc IX": 0x23 | # 0x23 "inc IXH": 0x24 | # 0x24 "dec IXH": 0x25 | # 0x25 @@ -128,9 +120,9 @@ ddInstruction = "inc": 0x34 REF_II_N | # 0x34 "dec": 0x35 REF_II_N | # 0x35 "ld": 0x36 REF_II_N(8) imm8 | # 0x36 - "ld": 010 REG_B_C_D_E_IXH(2) 100 | # 0x44, 0x4C, 0x54, 0x5C + "ld": 010 REG_B_C_D_E_IIH(2) 100 | # 0x44, 0x4C, 0x54, 0x5C "ld A, IXH": 0x7C | # 0x7C - "ld": 010 REG_B_C_D_E_IXL(2) 101 | # 0x45, 0x4D, 0x55, 0x5D + "ld": 010 REG_B_C_D_E_IIL(2) 101 | # 0x45, 0x4D, 0x55, 0x5D "ld A, IXL": 0x7D | # 0x7D "ld": 010 REG_B_C_D_E(2) 110 REF_II_N | # 0x46, 0x4E, 0x56, 0x5E "ld": 0110 REG_H_L(1) 110 REF_II_N | # 0x66, 0x6E @@ -177,93 +169,268 @@ ddInstruction = "ex (SP), IX": 0xE3 | # 0xE3 "push IX": 0xE5 | # 0xE5 "jp (IX)": 0xE9 | # 0xE9 - "ld SP,IX": 0xF9 ; # 0xF9 - - -fdINSTR = "ld": 010 REG_B_C_D_E(2) 110 REF_II_N | - - "ld": 0110 REG_H_L(1) 110 REF_II_N | - - "ld": 01 REG_A[111](3) 110 REF_II_N | - - "ld": 01 M[110](3) 0 REG_B_C_D_E(2) REF_II_N | - - "ld": 01 M[110](3) 10 REG_H_L(1) REF_II_N | - - "ld": 01 M[110](3) REG_A[111](3) REF_II_N | - - "ld": 0x36 REF_II_N(8) imm8 | - - "ld": 00100001 imm16 | - - "ld": 00101010 address | - - "ld": 00100010 address_LDIX | - - "ld SP,IY": 0xF9 | "ex (SP),IY": 0xE3 | "inc IY" : 0x23 | "dec IY": 0x2B | "jp (IY)": 0xE9 | "push IY": 0xE5 | - "pop IY": 0xE1 | - - "add": 0x86 REF_II_N | "adc": 0x8E REF_II_N | "sub": 0x96 REF_II_N | "sbc": 0x9E REF_II_N | "inc": 0x34 REF_II_N | - "dec": 0x35 REF_II_N | "and": 0xA6 REF_II_N | "xor": 0xAE REF_II_N | "or": 0xB6 REF_II_N | "cp": 0xBE REF_II_N | - - "add": 00 BCDEIYSP(2) 1001 | - - "ld": 0x76 REF_II_N(8) imm8 | - - 0xCB REF_II_N(8) fdcbINSTR; - - -ddcbInstruction = "rlc": 00000110 | "rl": 00010110 | "rrc": 00001110 | "rr": 00011110 | "sla": 0x26 | "sra": 0x2E | - "srl": 0x3E | "sll": 0x36 | "bit": 01 BIT(3) 110 | "res": 10 BIT(3) 110 | "set": 11 BIT(3) 110; - -fdcbINSTR = "rlc": 00000110 | "rl": 00010110 | "rrc": 00001110 | "rr": 00011110 | "sla": 0x26 | "sra": 0x2E | - "srl": 0x3E | "sll": 0x36 | "bit": 01 BIT(3) 110 | "res": 10 BIT(3) 110 | "set": 11 BIT(3) 110; - -edINSTR = "ld": 010 BC_DE(1) 1011 imm16 | "ld": 011 HLSP(1) 1011 imm16 | - - "ld": 010 BC_DE(1) 0011 address | "ld": 011 HLSP(1) 0011 address | + "ld SP, IX": 0xF9 ; # 0xF9 + +fdInstruction = + "add IY,": 00 BC_DE_IY_SP(2) 1001 | # 0x09, 0x19, 0x29, 0x39 + "ld IY,": 0x21 imm16 | # 0x21 + "ld": 0x22 REF_imm16_II | # 0x22 + "inc IY": 0x23 | # 0x23 + "inc IYH": 0x24 | # 0x24 + "dec IYH": 0x25 | # 0x25 + "ld IYH,": 0x26 imm8 | # 0x26 + "ld IY,": 0x2A REF_imm16 | # 0x2A + "dec IY": 0x2B | # 0x2B + "inc IYL": 0x2C | # 0x2C + "dec IYL": 0x2D | # 0x2D + "ld IYL,": 0x2E imm8 | # 0x2E + "inc": 0x34 REF_II_N | # 0x34 + "dec": 0x35 REF_II_N | # 0x35 + "ld": 0x36 REF_II_N(8) imm8 | # 0x36 + "ld": 010 REG_B_C_D_E_IIH(2) 100 | # 0x44, 0x4C, 0x54, 0x5C + "ld A, IYH": 0x7C | # 0x7C + "ld": 010 REG_B_C_D_E_IIL(2) 101 | # 0x45, 0x4D, 0x55, 0x5D + "ld A, IYL": 0x7D | # 0x7D + "ld": 010 REG_B_C_D_E(2) 110 REF_II_N | # 0x46, 0x4E, 0x56, 0x5E + "ld": 0110 REG_H_L(1) 110 REF_II_N | # 0x66, 0x6E + "ld A,": 0x7E REF_II_N | # 0x7E + "ld IYH,": 0110 00 REG_B_C_D_E(2) | # 0x60 - 063 + "ld IYH, IYH": 0x64 | # 0x64 + "ld IYH, IYL": 0x65 | # 0x65 + "ld IYH, A": 0x67 | # 0x67 + "ld IYL,": 0110 10 REG_B_C_D_E(2) | # 0x68 - 0x6B + "ld IYL, IYH": 0x6C | # 0x6C + "ld IYL, IYL": 0x6D | # 0x6D + "ld IYL, A": 0x6F | # 0x6F + "ld": 01110 0 REG_B_C_D_E(2) REF_II_N_2 | # 0x70 - 0x73 + "ld": 01110 10 REG_H_L(1) REF_II_N_2 | # 0x74, 0x75 + "ld": 01110 REG_A[111](3) REF_II_N_2 | # 0x77 + "add A, IYH": 0x84 | # 0x84 + "add A, IYL": 0x85 | # 0x85 + "add A,": 0x86 REF_II_N | # 0x86 + "adc A, IYH": 0x8C | # 0x8C + "adc A, IYL": 0x8D | # 0x8D + "adc A,": 0x8E REF_II_N | # 0x8E + "sub IYH": 0x94 | # 0x94 + "sub IYL": 0x95 | # 0x95 + "sub": 0x96 REF_II_N | # 0x96 + "sbc A, IYH": 0x9C | # 0x9C + "sbc A, IYL": 0x9D | # 0x9D + "sbc A,": 0x9E REF_II_N | # 0x9E + "and IYH": 0xA4 | # 0xA4 + "and IYL": 0xA5 | # 0xA5 + "and": 0xA6 REF_II_N | # 0xA6 + "xor IYH": 0xAC | # 0xAC + "xor IYL": 0xAD | # 0xAD + "xor": 0xAE REF_II_N | # 0xAE + "or IYH": 0xB4 | # 0xB4 + "or IYL": 0xB5 | # 0xB5 + "or": 0xB6 REF_II_N | # 0xB6 + "cp IYH": 0xBC | # 0xBC + "cp IYL": 0xBD | # 0xBD + "cp": 0xBE REF_II_N | # 0xBE - "adc HL,": 010 BC_DE(1) 1010 | "sbc HL,": 010 BC_DE(1) 0010 | + 0xCB REF_II_N(8) fdcbInstruction | # 0xCB + + "pop IY": 0xE1 | # 0xE1 + "ex (SP), IY": 0xE3 | # 0xE3 + "push IY": 0xE5 | # 0xE5 + "jp (IY)": 0xE9 | # 0xE9 + "ld SP, IY": 0xF9 ; # 0xF9 + +ddcbInstruction = + "rlc": 0000 00 REG_B_C_D_E(2) | # 0x00 - 0x03 + "rlc": 0000 01 0 REG_H_L(1) | # 0x04, 0x05 + "rlc": 0000 0110 | # 0x06 + "rlc": 0000 0 REG_A[111](3) | # 0x07 + "rrc": 0000 10 REG_B_C_D_E(2) | # 0x08 - 0x0B + "rrc": 0000 110 REG_H_L(1) | # 0x0C, 0x0D + "rrc": 0x0E | # 0x0E + "rrc": 0000 1 REG_A[111](3) | # 0x0F + "rl": 0001 00 REG_B_C_D_E | # 0x10 - 0x13 + "rl": 0001 010 REG_H_L | # 0x14, 0x15 + "rl": 0x16 | # 0x16 + "rl": 0001 0 REG_A[111](3) | # 0x17 + "rr": 0001 10 REG_B_C_D_E | # 0x18 - 0x1B + "rr": 0001 110 REG_H_L | # 0x1C, 0x1D + "rr": 0x1E | # 0x1E + "rr": 0001 1 REG_A[111](3) | # 0x1F + "sla": 0010 00 REG_B_C_D_E | # 0x20 - 0x23 + "sla": 0010 010 REG_H_L | # 0x24, 0x25 + "sla": 0x26 | # 0x26 + "sla": 0010 0 REG_A[111](3) | # 0x27 + "sra": 0010 10 REG_B_C_D_E | # 0x28 - 0x2B + "sra": 0010 110 REG_H_L | # 0x2C, 0x2D + "sra": 0x2E | # 0x2E + "sra": 0010 1 REG_A[111](3) | # 0x2F + "sll": 0011 00 REG_B_C_D_E | # 0x30 - 0x33 + "sll": 0011 010 REG_H_L | # 0x34, 0x35 + "sll": 0x36 | # 0x36 + "sll": 0011 0 REG_A[111](3) | # 0x37 + "srl": 0011 10 REG_B_C_D_E | # 0x38 - 0x3B + "srl": 0011 110 REG_H_L | # 0x3C, 0x3D + "srl": 0x3E | # 0x3E + "srl": 0011 1 REG_A[111](3) | # 0x3F + "bit": 01 BIT(3) IGNORE(3) | # 0x40 - 0x7F + "res": 10 BIT(3) 0 REG_B_C_D_E | # 0x80-0x83, 0x88-0x8B, 0x90-0x93, 0x98-0x9B, 0xA0-0xA3, 0xA8-0xAB, 0xB0-0xB3, 0xB8-0xBB + "res": 10 BIT(3) 10 REG_H_L | # 0x84, 0x85, 0x8C, 0x8D, 0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD, 0xB4, 0xB5, 0xBC, 0xBD + "res": 10 BIT(3) 110 | # 0x86, 0x8E, 0x96, 0x9E, 0xA6, 0xAE, 0xB6, 0xBE + "res": 10 BIT(3) REG_A[111](3) | # 0x87, 0x8F, 0x97, 0x9F, 0xA7, 0xAF, 0xB7, 0xBF + "set": 11 BIT(3) 0 REG_B_C_D_E | # 0xC0-0xC3, 0xC8-0xCB, 0xD0-0xD3, 0xD8-0xDB, 0xE0-0xE3, 0xE8-0xEB, 0xF0-0xF3, 0xF8-0xFB + "set": 11 BIT(3) 10 REG_H_L | # 0xC4, 0xC5, 0xCC, 0xCD, 0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED, 0xF4, 0xF5, 0xFC, 0xFD + "set": 11 BIT(3) 110 | # 0xC6, 0xCE, 0xD6, 0xDE, 0xE6, 0xEE, 0xF6, 0xFE + "set": 11 BIT(3) REG_A[111](3) ; # 0xC7, 0xCF, 0xD7, 0xDF, 0xE7, 0xEF, 0xF7, 0xFF + +fdcbInstruction = + "rlc": 0000 00 REG_B_C_D_E | # 0x00 - 0x03 + "rlc": 0000 010 REG_H_L | # 0x04, 0x05 + "rlc": 0x06 | # 0x06 + "rlc": 0000 0 REG_A[111](3) | # 0x07 + "rrc": 0000 10 REG_B_C_D_E | # 0x08 - 0x0B + "rrc": 0000 110 REG_H_L | # 0x0C, 0x0D + "rrc": 0x0E | # 0x0E + "rrc": 0000 1 REG_A[111](3) | # 0x0F + "rl": 0001 00 REG_B_C_D_E | # 0x10 - 0x13 + "rl": 0001 010 REG_H_L | # 0x14, 0x15 + "rl": 0x16 | # 0x16 + "rl": 0001 0 REG_A[111](3) | # 0x17 + "rr": 0001 10 REG_B_C_D_E | # 0x18 - 0x1B + "rr": 0001 110 REG_H_L | # 0x1C, 0x1D + "rr": 0x1E | # 0x1E + "rr": 0001 1 REG_A[111](3) | # 0x1F + "sla": 0010 00 REG_B_C_D_E | # 0x20 - 0x23 + "sla": 0010 010 REG_H_L | # 0x24, 0x25 + "sla": 0x26 | # 0x26 + "sla": 0010 0 REG_A[111](3) | # 0x27 + "sra": 0010 10 REG_B_C_D_E | # 0x28 - 0x2B + "sra": 0010 110 REG_H_L | # 0x2C, 0x2D + "sra": 0x2E | # 0x2E + "sra": 0010 1 REG_A[111](3) | # 0x2F + "sll": 0011 00 REG_B_C_D_E | # 0x30 - 0x33 + "sll": 0011 010 REG_H_L | # 0x34, 0x35 + "sll": 0x36 | # 0x36 + "sll": 0011 0 REG_A[111](3) | # 0x37 + "srl": 0011 10 REG_B_C_D_E | # 0x38 - 0x3B + "srl": 0011 110 REG_H_L | # 0x3C, 0x3D + "srl": 0x3E | # 0x3E + "srl": 0011 1 REG_A[111](3) | # 0x3F + "bit": 01 BIT(3) IGNORE(3) | # 0x40 - 0x7F + "res": 10 BIT(3) 0 REG_B_C_D_E | # 0x80-0x83, 0x88-0x8B, 0x90-0x93, 0x98-0x9B, 0xA0-0xA3, 0xA8-0xAB, 0xB0-0xB3, 0xB8-0xBB + "res": 10 BIT(3) 10 REG_H_L | # 0x84, 0x85, 0x8C, 0x8D, 0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD, 0xB4, 0xB5, 0xBC, 0xBD + "res": 10 BIT(3) 110 | # 0x86, 0x8E, 0x96, 0x9E, 0xA6, 0xAE, 0xB6, 0xBE + "res": 10 BIT(3) REG_A[111](3) | # 0x87, 0x8F, 0x97, 0x9F, 0xA7, 0xAF, 0xB7, 0xBF + "set": 11 BIT(3) 0 REG_B_C_D_E | # 0xC0-0xC3, 0xC8-0xCB, 0xD0-0xD3, 0xD8-0xDB, 0xE0-0xE3, 0xE8-0xEB, 0xF0-0xF3, 0xF8-0xFB + "set": 11 BIT(3) 10 REG_H_L | # 0xC4, 0xC5, 0xCC, 0xCD, 0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED, 0xF4, 0xF5, 0xFC, 0xFD + "set": 11 BIT(3) 110 | # 0xC6, 0xCE, 0xD6, 0xDE, 0xE6, 0xEE, 0xF6, 0xFE + "set": 11 BIT(3) REG_A[111](3) ; # 0xC7, 0xCF, 0xD7, 0xDF, 0xE7, 0xEF, 0xF7, 0xFF + +edInstruction = + "in": 01 0 REG_B_C_D_E(2) 000 | # 0x40, 0x48, 0x50, 0x58 + "out": 01 0 REG_B_C_D_E_OUT(2) 001 | # 0x41, 0x49, 0x51, 0x59 + "sbc HL,": 010 BC_DE(1) 0010 | # 0x42, 0x52 + "ld": 010 BC_DE(1) 0011 REF_imm16 | # 0x43, 0x53 + "neg": 0x44 | # 0x44 + "retn": 0x45 | # 0x45 + "im 0": 0x46 | # 0x46 + "ld I, A": 0x47 | # 0x47 + "adc HL,": 010 BC_DE(1) 1010 | # 0x4A, 0x5A + "ld": 010 BC_DE(1) 1011 imm16 | # 0x4B, 0x5B + "neg": 0x4C | # 0x4C + "reti": 0x4D | # 0x4D + "im 0": 0x4E | # 0x4E + "ld R, A": 0x4F | # 0x4F + "neg": 0x54 | # 0x54 + "retn": 0x55 | # 0x55 + "im 1": 0x56 | # 0x56 + "ld A, I": 0x57 | # 0x57 + "neg": 0x5C | # 0x5C + "retn": 0x5D | # 0x5D + "im 2": 0x5E | # 0x5E + "ld A, R": 0x5F | # 0x5F + "in": 01 10 REG_H_L(1) 000 | # 0x60, 0x68 + "out": 01 10 REG_H_L_OUT(1) 001 | # 0x61, 0x69 + "sbc HL,": 011 HL_SP(1) 0010 | # 0x62, 0x72 + "ld": 011 HL_SP(1) 0011 REF_imm16 | # 0x63, 0x73 + "neg": 0x64 | # 0x64 + "retn": 0x65 | # 0x65 + "im 0": 0x66 | # 0x66 + "rrd": 0x67 | # 0x67 + "adc HL,": 011 HL_SP(1) 1010 | # 0x6A, 0x7A + "ld": 011 HL_SP(1) 1011 imm16 | # 0x6B, 0x7B + "neg": 0x6C | # 0x6C + "retn": 0x6D | # 0x6D + "im 0": 0x6E | # 0x6E + "rld": 0x6F | # 0x6F + "in (C)": 0x70 | # 0x70 + "out (C), 0": 0x71 | # 0x71 + "neg": 0x74 | # 0x74 + "retn": 0x75 | # 0x75 + "im 1": 0x76 | # 0x76 + "in": 01 REG_A[111](3) 000 | # 0x78 + "out": 01 REG_A_OUT[111](3) 001 | # 0x79 + "neg": 0x7C | # 0x7C + "retn": 0x7D | # 0x7D + "im 2": 0x7E | # 0x7E + "ldi": 0xA0 | # 0xA0 + "cpi": 0xA1 | # 0xA1 + "ini": 0xA2 | # 0xA2 + "outi": 0xA3 | # 0xA3 + "ldd": 0xA8 | # 0xA8 + "cpd": 0xA9 | # 0xA9 + "ind": 0xAA | # 0xAA + "outd": 0xAB | # 0xAB + "ldir": 0xB0 | # 0xB0 + "cpir": 0xB1 | # 0xB1 + "inir": 0xB2 | # 0xB2 + "otir": 0xB3 | # 0xB3 + "lddr": 0xB8 | # 0xB8 + "cpdr": 0xB9 | # 0xB9 + "indr": 0xBA | # 0xBA + "otdr": 0xBB ; # 0xBB - "adc HL,": 011 HLSP(1) 1010 | "sbc HL,": 011 HLSP(1) 0010 | +BC_DE_HL_SP = "BC": 00 | "DE": 01 | "HL": 10 | "SP": 11; +BC_DE_IX_SP = "BC": 00 | "DE": 01 | "IX": 10 | "SP": 11; +BC_DE_IY_SP = "BC": 00 | "DE": 01 | "IY": 10 | "SP": 11; - "im 0": 0x46 | "im 1": 0x56 | "im 2": 0x5E | "ld A,I": 0x57 | "ld I,A": 0x47 | "ld A,R": 0x5F | - "ld R,A": 0x4F | "neg": 0x44 | "rld": 0x6F | "rrd": 0x67 | "cpi": 0xA1 | "cpir": 0xB1 | "cpd": 0xA9 | - "cpdr": 0xB9 | "reti": 0x4D | "retn": 0x45 | "ini": 0xA2 | "inir": 0xB2 | "ind": 0xAA | "indr": 0xBA | - "outi": 0xA3 | "otir": 0xB3 | "outd": 0xAB | "otdr": 0xBB | "ldi": 0xA0 | "ldir": 0xB0 | "ldd": 0xA8 | - "lddr": 0xB8 | +BC_DE, REF_BC_DE_A, A_REF_BC_DE = "BC" : 0 | "DE" : 1; +HL_SP = "HL": 0 | "SP": 1; - "in": 01 REG(3) 000 | "out": 01 REG_OUT(3) 001; +REG_B_C_D_E, REG_B_C_D_E_IIH, REG_B_C_D_E_IIL, REG_B_C_D_E_OUT = "B": 00 | "C": 01 | "D": 10 | "E": 11; +REG_H_L, REG_H_L_OUT = "H": 0 | "L": 1; +REG_A, REG_A_OUT = "A": 111; -BC_DE_HL_SP = "BC": 00 | "DE": 01 | "HL": 10 | "SP": 11; FLAGS_JR = "NZ": 00 | "Z": 01 | "NC": 10 | "C": 11; FLAGS = "NZ": 000 | "Z": 001 | "NC": 010 | "C": 011 | "PO": 100 | "PE": 101 | "P": 110 | "M": 111; -REG_B_C_D_E,REG_B_C_D_E_IXH,REG_B_C_D_E_IXL = "B": 00 | "C": 01 | "D": 10 | "E": 11; -REG_H_L = "H": 0 | "L": 1; -REG_A = "A": 111; - - +HL_AF = "HL" : 0 | "AF" : 1; +REG = "B": 000 | "C": 001 | "D": 010 | "E": 011 | "H": 100 | "L": 101 | "(HL)": 110 | "A": 111; +NUMBER = "00": 000 | "08": 001 | "10": 010 | "18": 011 | "20": 100 | "28": 101 | "30": 110 | "38": 111; +imm8,REF_II_N,REF_II_N_2,REF_imm8_A,REF_imm8 = imm8: imm8(8); +BIT = bit: bit(3); +REF_imm16_HL, HL_REF_imm16, imm16, REF_imm16, REF_imm16_II, A_REF_imm16, REF_imm16_A = imm16: imm16(16); -BC_DE_IX_SP = "BC": 00 | "DE": 01 | "IX": 10 | "SP": 11; -BCDEIYSP = "BC": 00 | "DE": 01 | "IY": 10 | "SP": 11; +%% -HLSP = "HL": 0 | "SP" : 1; +"%s %d, (IX + %X), %s" = ddcbInstruction BIT REF_II_N REG_B_C_D_E; +"%s %d, (IX + %X), %s" = ddcbInstruction BIT REF_II_N REG_H_L; +"%s %d, (IX + %X), %s" = ddcbInstruction BIT REF_II_N REG_A; -BC_DE, REF_BC_DE_A, A_REF_BC_DE = "BC" : 0 | "DE" : 1; -HL_AF = "HL" : 0 | "AF" : 1; -REG,REG_OUT = "B": 000 | "C": 001 | "D": 010 | "E": 011 | "H": 100 | "L": 101 | "(HL)": 110 | "A": 111; +"%s %d, (IY + %X), %s" = fdcbInstruction BIT REF_II_N REG_B_C_D_E; +"%s %d, (IY + %X), %s" = fdcbInstruction BIT REF_II_N REG_H_L; +"%s %d, (IY + %X), %s" = fdcbInstruction BIT REF_II_N REG_A; -M = "(HL)": 110; +"%s (IX + %X), %s" = ddcbInstruction REF_II_N REG_B_C_D_E; +"%s (IX + %X), %s" = ddcbInstruction REF_II_N REG_H_L; +"%s (IX + %X), %s" = ddcbInstruction REF_II_N REG_A; +"%s %d, (IX + %X)" = ddcbInstruction BIT REF_II_N; -NUMBER = "00": 000 | "08": 001 | "10": 010 | "18": 011 | "20": 100 | "28": 101 | "30": 110 | "38": 111; -imm8,REF_II_N,REF_II_N_2,REF_imm8_A,REF_imm8 = imm8: imm8(8); -BIT = bit: bit(3); -REF_imm16_HL, HL_REF_imm16, imm16, REF_imm16, REF_imm16_IX, address, address_LDIX, A_REF_imm16, REF_imm16_A = imm16: imm16(16); +"%s (IY + %X), %s" = fdcbInstruction REF_II_N REG_B_C_D_E; +"%s (IY + %X), %s" = fdcbInstruction REF_II_N REG_H_L; +"%s (IY + %X), %s" = fdcbInstruction REF_II_N REG_A; +"%s %d, (IY + %X)" = fdcbInstruction BIT REF_II_N; -%% "%s %d, %s" = cbInstruction BIT REG; "%s (IX + %X), %X" = ddInstruction REF_II_N imm8; @@ -273,6 +440,18 @@ REF_imm16_HL, HL_REF_imm16, imm16, REF_imm16, REF_imm16_IX, address, address_LDI "%s (IX + %X), %s" = ddInstruction REF_II_N_2 REG_H_L; "%s (IX + %X), %s" = ddInstruction REF_II_N_2 REG_A; +"%s (IY + %X), %X" = fdInstruction REF_II_N imm8; +"%s %s, (IY + %X)" = fdInstruction REG_B_C_D_E REF_II_N; +"%s (IY + %X), %s" = fdInstruction REF_II_N_2 REG_B_C_D_E; +"%s %s, (IY + %X)" = fdInstruction REG_H_L REF_II_N; +"%s (IY + %X), %s" = fdInstruction REF_II_N_2 REG_H_L; +"%s (IY + %X), %s" = fdInstruction REF_II_N_2 REG_A; + +"%s (%X), %s" = edInstruction REF_imm16 BC_DE; +"%s (%X), %s" = edInstruction REF_imm16 HL_SP; +"%s %s, (%X)" = edInstruction BC_DE imm16; +"%s %s, (%X)" = edInstruction HL_SP imm16; + "%s %s, %X" = instruction BC_DE_HL_SP imm16; "%s %s, %s" = instruction REG_B_C_D_E REG; "%s %s, %s" = instruction REG_H_L REG; @@ -280,22 +459,44 @@ REF_imm16_HL, HL_REF_imm16, imm16, REF_imm16, REF_imm16_IX, address, address_LDI "%s %s, %X" = instruction FLAGS_JR imm8; "%s %s, %X" = instruction FLAGS imm16; +"%s (IX + %X)" = ddcbInstruction REF_II_N; +"%s (IY + %X)" = fdcbInstruction REF_II_N; + "%s %s" = cbInstruction REG; "%s %s" = ddInstruction BC_DE_IX_SP; "%s %X" = ddInstruction imm8; "%s %X" = ddInstruction imm16; "%s (%X)" = ddInstruction REF_imm16; -"%s (%X), IX" = ddInstruction REF_imm16_IX; +"%s (%X), IX" = ddInstruction REF_imm16_II; "%s (IX + %X)" = ddInstruction REF_II_N; "%s %s" = ddInstruction REG_B_C_D_E; -"%s %s, IXH" = ddInstruction REG_B_C_D_E_IXH; -"%s %s, IXL" = ddInstruction REG_B_C_D_E_IXL; - +"%s %s, IXH" = ddInstruction REG_B_C_D_E_IIH; +"%s %s, IXL" = ddInstruction REG_B_C_D_E_IIL; + +"%s %s" = fdInstruction BC_DE_IY_SP; +"%s %X" = fdInstruction imm8; +"%s %X" = fdInstruction imm16; +"%s (%X)" = fdInstruction REF_imm16; +"%s (%X), IY" = fdInstruction REF_imm16_II; +"%s (IY + %X)" = fdInstruction REF_II_N; +"%s %s" = fdInstruction REG_B_C_D_E; +"%s %s, IYH" = fdInstruction REG_B_C_D_E_IIH; +"%s %s, IYL" = fdInstruction REG_B_C_D_E_IIL; + +"%s %s, (C)" = edInstruction REG_B_C_D_E; +"%s %s, (C)" = edInstruction REG_H_L; +"%s %s, (C)" = edInstruction REG_A; +"%s (C), %s" = edInstruction REG_B_C_D_E_OUT; +"%s (C), %s" = edInstruction REG_H_L_OUT; +"%s (C), %s" = edInstruction REG_A_OUT; +"%s %s" = edInstruction BC_DE; +"%s %s" = edInstruction HL_SP; "%s (%s), A" = instruction REF_BC_DE_A; "%s A, (%s)" = instruction A_REF_BC_DE; "%s %s" = instruction BC_DE_HL_SP; +"%s %s" = instruction REG_B_C_D_E; "%s %s" = instruction REG; "%s %X" = instruction imm8; "%s A, (%X)" = instruction A_REF_imm16; @@ -307,58 +508,10 @@ REF_imm16_HL, HL_REF_imm16, imm16, REF_imm16, REF_imm16_IX, address, address_LDI "%s %s" = instruction NUMBER; "%s (%X), A" = instruction REF_imm8_A; "%s (%X)" = instruction REF_imm8; - -"%s" = ddInstruction; -"%s" = instruction; - - - -############################### - - "%s (%X), HL" = instruction REF_imm16_HL; "%s HL, (%X)" = instruction HL_REF_imm16; -"%s %X" = instruction address; -"%s %s" = instruction HLSP; # TODO: get rid - -"%s %s" = instruction REG_B_C_D_E; - - -"%s A,(IX+%X)" = ddInstruction REG_A REF_II_N; -"%s (IX+%X),%s" = ddInstruction REF_II_N REG_B_C_D_E M; -"%s (IX+%X),%s" = ddInstruction REF_II_N REG_H_L M; -"%s (IX+%X),A" = ddInstruction REF_II_N REG_A M; - -"%s (IX+%X)" = ddcbInstruction REF_II_N; -"%s %d,(IX+%X)" = ddcbInstruction BIT REF_II_N; - -"%s %s,(IY+%X)" = fdINSTR REG_B_C_D_E REF_II_N; -"%s %s,(IY+%X)" = fdINSTR REG_H_L REF_II_N; -"%s A,(IY+%X)" = fdINSTR REG_A REF_II_N; -"%s (IY+%X),%s" = fdINSTR REF_II_N REG_B_C_D_E M; -"%s (IY+%X),%s" = fdINSTR REF_II_N REG_H_L M; -"%s (IY+%X),A" = fdINSTR REF_II_N REG_A M; -"%s (IY+%X),%X" = fdINSTR REF_II_N imm8; -"%s (IY+%X)" = fdcbINSTR REF_II_N; -"%s (IY+%X)" = fdINSTR REF_II_N; -"%s IY,%s" = fdINSTR BCDEIYSP; -"%s IY,%X" = fdINSTR imm16; -"%s IY,(%X)" = fdINSTR address; -"%s (%X),IY" = fdINSTR address_LDIX; -"%s %d,(IY+%X)" = fdcbINSTR BIT REF_II_N; -"%s" = fdINSTR; - - - -"%s %s,%X" = edINSTR BC_DE imm16; -"%s %s,%X" = edINSTR HLSP imm16; -"%s (%X),%s" = edINSTR address BC_DE; -"%s (%X),%s" = edINSTR address HLSP; -"%s%s" = edINSTR BC_DE; -"%s%s" = edINSTR HLSP; -"%s %s,(C)" = edINSTR REG; -"%s (C),%s" = edINSTR REG_OUT; -"%s" = edINSTR; - - +"%s" = edInstruction; +"%s" = fdInstruction; +"%s" = ddInstruction; +"%s" = instruction; From 3714f458323ad99a844481f29f29c818182607cc Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 4 Feb 2022 13:29:55 +0100 Subject: [PATCH 093/314] [#201] as-z80: grammar draft, unfinished --- application/build.gradle | 40 +- plugins/compiler/as-8080/build.gradle | 1 - .../as-8080/src/main/jflex/lexer.jflex | 348 ---------- plugins/compiler/as-z80/build.gradle | 47 +- .../as-z80/src/main/antlr/AsZ80Lexer.g4 | 206 ++++++ .../as-z80/src/main/antlr/AsZ80Parser.g4 | 166 +++++ .../as-z80/src/main/jflex/lexer.jflex | 652 ------------------ settings.gradle | 2 +- 8 files changed, 425 insertions(+), 1037 deletions(-) delete mode 100644 plugins/compiler/as-8080/src/main/jflex/lexer.jflex create mode 100644 plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 create mode 100644 plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 delete mode 100644 plugins/compiler/as-z80/src/main/jflex/lexer.jflex diff --git a/application/build.gradle b/application/build.gradle index 11c13312e..077ac3219 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -51,7 +51,7 @@ dependencies { extraLibsRuntime libs.javaCupRuntime providedRuntime project(":plugins:compiler:as-8080") providedRuntime project(":plugins:compiler:as-ssem") -// providedRuntime project(":plugins:compiler:as-z80") + providedRuntime project(":plugins:compiler:as-z80") // providedRuntime project(":plugins:compiler:brainc-brainduck") // providedRuntime project(":plugins:compiler:ramc-ram") // providedRuntime project(":plugins:compiler:raspc-rasp") @@ -176,8 +176,8 @@ distributions { into('compiler') { include '*.jar' -// from(output(":plugins:compiler:as-8080")) - // from(output(":plugins:compiler:as-z80")) + from(output(":plugins:compiler:as-8080")) + from(output(":plugins:compiler:as-z80")) from(output(":plugins:compiler:as-ssem")) // from(output(":plugins:compiler:brainc-brainduck")) // from(output(":plugins:compiler:ramc-ram")) @@ -188,35 +188,35 @@ distributions { include '*.jar' // from(output(":plugins:memory:ram-mem")) // from(output(":plugins:memory:rasp-mem")) - // from(output(":plugins:memory:brainduck-mem")) + from(output(":plugins:memory:brainduck-mem")) from(output(":plugins:memory:ssem-mem")) - // from(output(":plugins:memory:byte-mem")) + from(output(":plugins:memory:byte-mem")) } into('cpu') { include '*.jar' -// from(output(":plugins:cpu:8080-cpu")) - // from(output(":plugins:cpu:brainduck-cpu")) + from(output(":plugins:cpu:8080-cpu")) + from(output(":plugins:cpu:brainduck-cpu")) // from(output(":plugins:cpu:ram-cpu")) // from(output(":plugins:cpu:rasp-cpu")) - // from(output(":plugins:cpu:z80-cpu")) + from(output(":plugins:cpu:z80-cpu")) from(output(":plugins:cpu:ssem-cpu")) } into('device') { include '*.jar' -// from(output(":plugins:device:abstract-tape")) - // from(output(":plugins:device:88-dcdd")) - // from(output(":plugins:device:88-sio")) - // from(output(":plugins:device:adm3A-terminal")) + from(output(":plugins:device:abstract-tape")) + from(output(":plugins:device:88-dcdd")) + from(output(":plugins:device:88-sio")) + from(output(":plugins:device:adm3A-terminal")) //from(output(":plugins:device:brainduck-terminal")) - // from(output(":plugins:device:simhPseudo-z80")) + from(output(":plugins:device:simhPseudo-z80")) from(output(":plugins:device:ssem-display")) } // Examples //["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"] - ["as-ssem"].collect { compiler -> + ["as-8080", "as-z80", "as-ssem"].collect { compiler -> from(examples(":plugins:compiler:$compiler")) { into "examples/$compiler" } @@ -224,16 +224,16 @@ distributions { // Scripts // ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"] - ["as-ssem"].collect { compiler -> + ["as-8080", "as-z80", "as-ssem"].collect { compiler -> from(scripts(":plugins:compiler:$compiler")) { into "bin" } } -// ["88-dcdd"].collect { device -> -// from(scripts(":plugins:device:$device")) { -// into "bin" -// } -// } + ["88-dcdd"].collect { device -> + from(scripts(":plugins:device:$device")) { + into "bin" + } + } } } } diff --git a/plugins/compiler/as-8080/build.gradle b/plugins/compiler/as-8080/build.gradle index 0746ce51a..271eaa783 100644 --- a/plugins/compiler/as-8080/build.gradle +++ b/plugins/compiler/as-8080/build.gradle @@ -32,7 +32,6 @@ dependencies { implementation libs.emuLib implementation libs.slf4JApi implementation libs.jcipAnnotations - implementation libs.javaCupRuntime // TODO: remove testImplementation libs.cpuTestSuite testImplementation libs.junit diff --git a/plugins/compiler/as-8080/src/main/jflex/lexer.jflex b/plugins/compiler/as-8080/src/main/jflex/lexer.jflex deleted file mode 100644 index 7e45a29e4..000000000 --- a/plugins/compiler/as-8080/src/main/jflex/lexer.jflex +++ /dev/null @@ -1,348 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.as8080; - -import java_cup.runtime.ComplexSymbolFactory.Location; -import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; -import net.emustudio.emulib.plugins.compiler.Token; - -import java.io.IOException; -import java.io.Reader; - -%% - -/* options */ -%class LexerImpl -%cup -%public -%implements LexicalAnalyzer -%line -%column -%char -%caseless -%unicode -%type TokenImpl - -%{ - @Override - public Token getToken() throws IOException { - return next_token(); - } - - @Override - public void reset(Reader in, int yyline, int yychar, int yycolumn) { - yyreset(in); - this.yyline = yyline; - this.yychar = yychar; - this.yycolumn = yycolumn; - } - - @Override - public void reset(Reader in, int line, int offset, int column, int lexerState) { - yyreset(in); - this.yyline = line; - this.yychar = offset; - this.yycolumn = column; - this.zzLexicalState = lexerState; - } - - private TokenImpl token(int id, int category) { - Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); - return new TokenImpl(id, category, zzLexicalState, yytext(), left, right); - } - - private TokenImpl token(int id, int category, Object value) { - Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); - return new TokenImpl(id, category, zzLexicalState, yytext(), left, right, value); - } -%} -%eofval{ - return token(TokenImpl.EOF, Token.TEOF); -%eofval} - -Comment =(";"[^\r\n]*) - -Eol =[\n]|[\r]|[\n][\r] -WhiteSpace =([ ]|[\t]|[\f]) - -DecimalNum =[0-9]+[dD]? -OctalNum =[0-7]+[oOqQ] -HexaPostfix =([0-9a-fA-F]*[hH]) -HexaNum =[0-9]{HexaPostfix} -BinaryNum =[0-1]+[bB] - -AnyChar =([^\'\n\r]) -UnclosedString =('{AnyChar}+) -String ={UnclosedString}' - -Identifier =([a-zA-Z_\?@])[a-zA-Z_\?@0-9]* -Label ={Identifier}[\:] - -%% - -/* reserved words */ -"stc" { return token(TokenImpl.RESERVED_STC, Token.RESERVED); } -"cmc" { return token(TokenImpl.RESERVED_CMC, Token.RESERVED); } -"inr" { return token(TokenImpl.RESERVED_INR, Token.RESERVED); } -"dcr" { return token(TokenImpl.RESERVED_DCR, Token.RESERVED); } -"cma" { return token(TokenImpl.RESERVED_CMA, Token.RESERVED); } -"daa" { return token(TokenImpl.RESERVED_DAA, Token.RESERVED); } -"nop" { return token(TokenImpl.RESERVED_NOP, Token.RESERVED); } -"mov" { return token(TokenImpl.RESERVED_MOV, Token.RESERVED); } -"stax" { return token(TokenImpl.RESERVED_STAX, Token.RESERVED); } -"ldax" { return token(TokenImpl.RESERVED_LDAX, Token.RESERVED); } -"add" { return token(TokenImpl.RESERVED_ADD, Token.RESERVED); } -"adc" { return token(TokenImpl.RESERVED_ADC, Token.RESERVED); } -"sub" { return token(TokenImpl.RESERVED_SUB, Token.RESERVED); } -"sbb" { return token(TokenImpl.RESERVED_SBB, Token.RESERVED); } -"ana" { return token(TokenImpl.RESERVED_ANA, Token.RESERVED); } -"xra" { return token(TokenImpl.RESERVED_XRA, Token.RESERVED); } -"ora" { return token(TokenImpl.RESERVED_ORA, Token.RESERVED); } -"cmp" { return token(TokenImpl.RESERVED_CMP, Token.RESERVED); } -"rlc" { return token(TokenImpl.RESERVED_RLC, Token.RESERVED); } -"rrc" { return token(TokenImpl.RESERVED_RRC, Token.RESERVED); } -"ral" { return token(TokenImpl.RESERVED_RAL, Token.RESERVED); } -"rar" { return token(TokenImpl.RESERVED_RAR, Token.RESERVED); } -"push" { return token(TokenImpl.RESERVED_PUSH, Token.RESERVED); } -"pop" { return token(TokenImpl.RESERVED_POP, Token.RESERVED); } -"dad" { return token(TokenImpl.RESERVED_DAD, Token.RESERVED); } -"inx" { return token(TokenImpl.RESERVED_INX, Token.RESERVED); } -"dcx" { return token(TokenImpl.RESERVED_DCX, Token.RESERVED); } -"xchg" { return token(TokenImpl.RESERVED_XCHG, Token.RESERVED); } -"xthl" { return token(TokenImpl.RESERVED_XTHL, Token.RESERVED); } -"sphl" { return token(TokenImpl.RESERVED_SPHL, Token.RESERVED); } -"lxi" { return token(TokenImpl.RESERVED_LXI, Token.RESERVED); } -"mvi" { return token(TokenImpl.RESERVED_MVI, Token.RESERVED); } -"adi" { return token(TokenImpl.RESERVED_ADI, Token.RESERVED); } -"aci" { return token(TokenImpl.RESERVED_ACI, Token.RESERVED); } -"sui" { return token(TokenImpl.RESERVED_SUI, Token.RESERVED); } -"sbi" { return token(TokenImpl.RESERVED_SBI, Token.RESERVED); } -"ani" { return token(TokenImpl.RESERVED_ANI, Token.RESERVED); } -"xri" { return token(TokenImpl.RESERVED_XRI, Token.RESERVED); } -"ori" { return token(TokenImpl.RESERVED_ORI, Token.RESERVED); } -"cpi" { return token(TokenImpl.RESERVED_CPI, Token.RESERVED); } -"sta" { return token(TokenImpl.RESERVED_STA, Token.RESERVED); } -"lda" { return token(TokenImpl.RESERVED_LDA, Token.RESERVED); } -"shld" { return token(TokenImpl.RESERVED_SHLD, Token.RESERVED); } -"lhld" { return token(TokenImpl.RESERVED_LHLD, Token.RESERVED); } -"pchl" { return token(TokenImpl.RESERVED_PCHL, Token.RESERVED); } -"jmp" { return token(TokenImpl.RESERVED_JMP, Token.RESERVED); } -"jc" { return token(TokenImpl.RESERVED_JC, Token.RESERVED); } -"jnc" { return token(TokenImpl.RESERVED_JNC, Token.RESERVED); } -"jz" { return token(TokenImpl.RESERVED_JZ, Token.RESERVED); } -"jnz" { return token(TokenImpl.RESERVED_JNZ, Token.RESERVED); } -"jp" { return token(TokenImpl.RESERVED_JP, Token.RESERVED); } -"jm" { return token(TokenImpl.RESERVED_JM, Token.RESERVED); } -"jpe" { return token(TokenImpl.RESERVED_JPE, Token.RESERVED); } -"jpo" { return token(TokenImpl.RESERVED_JPO, Token.RESERVED); } -"call" { return token(TokenImpl.RESERVED_CALL, Token.RESERVED); } -"cc" { return token(TokenImpl.RESERVED_CC, Token.RESERVED); } -"cnc" { return token(TokenImpl.RESERVED_CNC, Token.RESERVED); } -"cz" { return token(TokenImpl.RESERVED_CZ, Token.RESERVED); } -"cnz" { return token(TokenImpl.RESERVED_CNZ, Token.RESERVED); } -"cp" { return token(TokenImpl.RESERVED_CP, Token.RESERVED); } -"cm" { return token(TokenImpl.RESERVED_CM, Token.RESERVED); } -"cpe" { return token(TokenImpl.RESERVED_CPE, Token.RESERVED); } -"cpo" { return token(TokenImpl.RESERVED_CPO, Token.RESERVED); } -"ret" { return token(TokenImpl.RESERVED_RET, Token.RESERVED); } -"rc" { return token(TokenImpl.RESERVED_RC, Token.RESERVED); } -"rnc" { return token(TokenImpl.RESERVED_RNC, Token.RESERVED); } -"rz" { return token(TokenImpl.RESERVED_RZ, Token.RESERVED); } -"rnz" { return token(TokenImpl.RESERVED_RNZ, Token.RESERVED); } -"rm" { return token(TokenImpl.RESERVED_RM, Token.RESERVED); } -"rp" { return token(TokenImpl.RESERVED_RP, Token.RESERVED); } -"rpe" { return token(TokenImpl.RESERVED_RPE, Token.RESERVED); } -"rpo" { return token(TokenImpl.RESERVED_RPO, Token.RESERVED); } -"rst" { return token(TokenImpl.RESERVED_RST, Token.RESERVED); } -"ei" { return token(TokenImpl.RESERVED_EI, Token.RESERVED); } -"di" { return token(TokenImpl.RESERVED_DI, Token.RESERVED); } -"in" { return token(TokenImpl.RESERVED_IN, Token.RESERVED); } -"out" { return token(TokenImpl.RESERVED_OUT, Token.RESERVED); } -"hlt" { return token(TokenImpl.RESERVED_HLT, Token.RESERVED); } - -/* preprocessor words */ -"org" { return token(TokenImpl.PREPROCESSOR_ORG, Token.PREPROCESSOR); } -"equ" { return token(TokenImpl.PREPROCESSOR_EQU, Token.PREPROCESSOR); } -"set" { return token(TokenImpl.PREPROCESSOR_SET, Token.PREPROCESSOR); } -"include" { return token(TokenImpl.PREPROCESSOR_INCLUDE, Token.PREPROCESSOR); } -"if" { return token(TokenImpl.PREPROCESSOR_IF, Token.PREPROCESSOR); } -"endif" { return token(TokenImpl.PREPROCESSOR_ENDIF, Token.PREPROCESSOR); } -"macro" { return token(TokenImpl.PREPROCESSOR_MACRO, Token.PREPROCESSOR); } -"endm" { return token(TokenImpl.PREPROCESSOR_ENDM, Token.PREPROCESSOR); } -"db" { return token(TokenImpl.PREPROCESSOR_DB, Token.PREPROCESSOR); } -"dw" { return token(TokenImpl.PREPROCESSOR_DW, Token.PREPROCESSOR); } -"ds" { return token(TokenImpl.PREPROCESSOR_DS, Token.PREPROCESSOR); } -"$" { return token(TokenImpl.PREPROCESSOR_ADDR, Token.PREPROCESSOR); } - -/* registers */ -"a" { return token(TokenImpl.REGISTERS_A, Token.REGISTER); } -"b" { return token(TokenImpl.REGISTERS_B, Token.REGISTER); } -"c" { return token(TokenImpl.REGISTERS_C, Token.REGISTER); } -"d" { return token(TokenImpl.REGISTERS_D, Token.REGISTER); } -"e" { return token(TokenImpl.REGISTERS_E, Token.REGISTER); } -"h" { return token(TokenImpl.REGISTERS_H, Token.REGISTER); } -"l" { return token(TokenImpl.REGISTERS_L, Token.REGISTER); } -"m" { return token(TokenImpl.REGISTERS_M, Token.REGISTER); } -"psw" { return token(TokenImpl.REGISTERS_PSW, Token.REGISTER); } -"sp" { return token(TokenImpl.REGISTERS_SP, Token.REGISTER); } - -/* separators */ -"(" { return token(TokenImpl.SEPARATOR_LPAR, Token.SEPARATOR); } -")" { return token(TokenImpl.SEPARATOR_RPAR, Token.SEPARATOR); } -"," { return token(TokenImpl.SEPARATOR_COMMA, Token.SEPARATOR); } -{Eol} { return token(TokenImpl.SEPARATOR_EOL, Token.SEPARATOR); } -{WhiteSpace}+ { /* ignore white spaces */ } - -/* operators */ -"+" { return token(TokenImpl.OPERATOR_ADD, Token.OPERATOR); } -"-" { return token(TokenImpl.OPERATOR_SUBTRACT, Token.OPERATOR); } -"*" { return token(TokenImpl.OPERATOR_MULTIPLY, Token.OPERATOR); } -"/" { return token(TokenImpl.OPERATOR_DIVIDE, Token.OPERATOR); } -"=" { return token(TokenImpl.OPERATOR_EQUAL, Token.OPERATOR); } -"mod" { return token(TokenImpl.OPERATOR_MOD, Token.OPERATOR); } -"shr" { return token(TokenImpl.OPERATOR_SHR, Token.OPERATOR); } -"shl" { return token(TokenImpl.OPERATOR_SHL, Token.OPERATOR); } -"not" { return token(TokenImpl.OPERATOR_NOT, Token.OPERATOR); } -"and" { return token(TokenImpl.OPERATOR_AND, Token.OPERATOR); } -"or" { return token(TokenImpl.OPERATOR_OR, Token.OPERATOR); } -"xor" { return token(TokenImpl.OPERATOR_XOR, Token.OPERATOR); } - -/* comment */ -{Comment} { return token(TokenImpl.TCOMMENT, Token.COMMENT); } - -/* literals */ -{DecimalNum} { - String text = yytext().replaceFirst("[dD]",""); - int num = 0; - int tokenId; - int tokenType = Token.LITERAL; - - try { - num = Integer.parseInt(text,10); - if (num > 65535) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } else if (num > 255) { - tokenId = TokenImpl.LITERAL_DECIMAL_16BIT; - } else { - tokenId = TokenImpl.LITERAL_DECIMAL_8BIT; - } - } catch (NumberFormatException e) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } - return token(tokenId, tokenType, (Object)num); -} -{OctalNum} { - String text = yytext().replaceFirst("[oOqQ]",""); - int num = 0; - int tokenId; - int tokenType = Token.LITERAL; - - try { - num = Integer.parseInt(text,8); - if (num > 65535) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } else if (num > 255) { - tokenId = TokenImpl.LITERAL_DECIMAL_16BIT; - } else { - tokenId = TokenImpl.LITERAL_DECIMAL_8BIT; - } - } catch (NumberFormatException e) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } - return token(tokenId, tokenType, (Object)num); -} -{HexaNum} { - String text = yytext().replaceFirst("[hH]",""); - int num = 0; - int tokenId; - int tokenType = Token.LITERAL; - - try { - num = Integer.parseInt(text,16); - if (num > 65535) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } else if (num > 255) { - tokenId = TokenImpl.LITERAL_DECIMAL_16BIT; - } else { - tokenId = TokenImpl.LITERAL_DECIMAL_8BIT; - } - } catch (NumberFormatException e) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } - return token(tokenId, tokenType, (Object)num); -} -{BinaryNum} { - String text = yytext().replaceFirst("[bB]",""); - int num = 0; - int tokenId; - int tokenType = Token.LITERAL; - - try { - num = Integer.parseInt(text,2); - if (num > 65535) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } else if (num > 255) { - tokenId = TokenImpl.LITERAL_DECIMAL_16BIT; - } else { - tokenId = TokenImpl.LITERAL_DECIMAL_8BIT; - } - } catch (NumberFormatException e) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } - return token(tokenId, tokenType, (Object)num); -} -{UnclosedString} { - return token(TokenImpl.ERROR_UNCLOSED_STRING, Token.ERROR); -} -{String} { - String text = yytext(); - String val = text.substring(1,text.length()-1); - if (val.length() > 1) { - return token(TokenImpl.LITERAL_STRING, Token.LITERAL, val); - } else { - byte[] b = val.getBytes(); - int numval = b[0]; - for (int i = 1; i < b.length; i++) - numval = (numval <<8) + b[i]; - - int tokenId = (numval > 255) ? TokenImpl.LITERAL_DECIMAL_16BIT : TokenImpl.LITERAL_DECIMAL_8BIT; - return token(tokenId, Token.LITERAL, numval); - } -} -{Identifier} { - return token(TokenImpl.TIDENTIFIER, Token.IDENTIFIER, yytext().toUpperCase()); -} -{Label} { - String text = yytext(); - Object val = text.substring(0,text.length()-1).toUpperCase(); - return token(TokenImpl.TLABEL, Token.LABEL, val); -} -. { - return token(TokenImpl.error, Token.ERROR); -} diff --git a/plugins/compiler/as-z80/build.gradle b/plugins/compiler/as-z80/build.gradle index afe44a6a3..af699c704 100644 --- a/plugins/compiler/as-z80/build.gradle +++ b/plugins/compiler/as-z80/build.gradle @@ -1,7 +1,7 @@ /* * This file is part of emuStudio. * - * Copyright (C) 2006-2020 Peter Jakubčo + * Copyright (C) 2006-2022 Peter Jakubčo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,14 +21,16 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'org.xbib.gradle.plugin.jflex' version "1.5.0" - id "com.github.andrescv.jcup" version "1.0" + id 'idea' + id 'antlr' } dependencies { + antlr "org.antlr:antlr4:4.9.2" + implementation "org.antlr:antlr4-runtime:4.9.2" + implementation libs.emuLib implementation libs.slf4JApi - implementation libs.javaCupRuntime testImplementation libs.cpuTestSuite testImplementation libs.junit @@ -36,20 +38,29 @@ dependencies { testImplementation libs.slf4JSimple } -sourceSets.main.java.srcDirs = [ - "${buildDir}/generated-sources/jflex", "${buildDir}/generated-sources/cup", 'src/main/java' -] +generateGrammarSource { + maxHeapSize = "128m" + arguments += ['-package', 'net.emustudio.plugins.compiler.asZ80', '-visitor', '-no-listener'] + outputDirectory = file("${buildDir}/generated-src/antlr/main/net/emustudio/plugins/compiler/asZ80") +} +compileJava.dependsOn generateGrammarSource -jflex { - no_backup = true +sourceSets { + generated { + java.srcDir "${buildDir}/generated-src/antlr/main" + } + main { + java.srcDirs = [ + 'src/main/java', "${buildDir}/generated-src/antlr/main" + ] + } } +compileJava.source sourceSets.generated.java, sourceSets.main.java -jcup { - input = file('src/main/cup/parser.cup') - destdir = file("${buildDir}/generated-sources/cup/net/emustudio/plugins/compiler/asZ80") - parser = 'ParserImpl' - symbols = 'Symbols' - iface = true +idea { + module { + sourceDirs += file("build/generated-src/antlr") + } } jar { @@ -81,3 +92,9 @@ copy { from('src/main/scripts') into "$buildDir/libs/scripts" } + +test { + testLogging { + events "passed", "skipped", "failed" + } +} diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 new file mode 100644 index 000000000..2605ffaa7 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 @@ -0,0 +1,206 @@ +lexer grammar AsZ80Lexer; + +COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]* -> skip; +COMMENT2: '/*' .*? '*/' -> skip; + +fragment A: [aA]; +fragment B: [bB]; +fragment C: [cC]; +fragment D: [dD]; +fragment E: [eE]; +fragment F: [fF]; +fragment G: [gG]; +fragment H: [hH]; +fragment I: [iI]; +fragment J: [jJ]; +fragment L: [lL]; +fragment M: [mM]; +fragment N: [nN]; +fragment O: [oO]; +fragment P: [pP]; +fragment Q: [qQ]; +fragment R: [rR]; +fragment S: [sS]; +fragment T: [tT]; +fragment U: [uU]; +fragment V: [vV]; +fragment W: [wW]; +fragment X: [xX]; +fragment Y: [yY]; +fragment Z: [zZ]; + + +// reserved +OPCODE_ADC: A D C; +OPCODE_ADD: A D D; +OPCODE_AND: A N D; +OPCODE_BIT: B I T; +OPCODE_CALL: C A L L -> pushMode(CONDITION); +OPCODE_CCF: C C F; +OPCODE_CP: C P; +OPCODE_CPD: C P D; +OPCODE_CPDR: C P D R; +OPCODE_CPI: C P I; +OPCODE_CPIR: C P I R; +OPCODE_CPL: C P L; +OPCODE_DAA: D A A; +OPCODE_DEC: D E C; +OPCODE_DI: D I; +OPCODE_DJNZ: D J N Z; +OPCODE_EI: E I; +OPCODE_EX: E X; +OPCODE_EXX: E X X; +OPCODE_HALT: H A L T; +OPCODE_IM: I M; +OPCODE_IN: I N; +OPCODE_INC: I N C; +OPCODE_IND: I N D; +OPCODE_INDR: I N D R; +OPCODE_INI: I N I; +OPCODE_INIR: I N I R; +OPCODE_JP: J P -> pushMode(CONDITION); +OPCODE_JR: J R -> pushMode(CONDITION); +OPCODE_LD: L D; +OPCODE_LDD: L D D; +OPCODE_LDDR: L D D R; +OPCODE_LDI: L D I; +OPCODE_LDIR: L D I R; +OPCODE_NEG: N E G; +OPCODE_NOP: N O P; +OPCODE_OR: O R; +OPCODE_OTDR: O T D R; +OPCODE_OTIR: O T I R; +OPCODE_OUT: O U T; +OPCODE_OUTD: O U T D; +OPCODE_OUTI: O U T I; +OPCODE_POP: P O P; +OPCODE_PUSH: P U S H; +OPCODE_RES: R E S; +OPCODE_RET: R E T -> pushMode(CONDITION); +OPCODE_RETI: R E T I; +OPCODE_RETN: R E T N; +OPCODE_RL: R L; +OPCODE_RLA: R L A; +OPCODE_RLC: R L C; +OPCODE_RLCA: R L C A; +OPCODE_RLD: R L D; +OPCODE_RR: R R; +OPCODE_RRA: R R A; +OPCODE_RRC: R R C; +OPCODE_RRCA: R R C A; +OPCODE_RRD: R R D; +OPCODE_RST: R S T; +OPCODE_SBC: S B C; +OPCODE_SCF: S C F; +OPCODE_SET: S E T; +OPCODE_SLA: S L A; +OPCODE_SRA: S R A; +OPCODE_SLL: S L L; +OPCODE_SRL: S R L; +OPCODE_SUB: S U B; +OPCODE_XOR: X O R; + +mode CONDITION; +COND_C: C -> popMode; +COND_NC: N C -> popMode; +COND_Z: Z -> popMode; +COND_NZ: N Z -> popMode; +COND_M: M -> popMode; +COND_P: P -> popMode; +COND_PE: P E -> popMode; +COND_PO: P O -> popMode; +COND_WS : [ \t\f]+ -> skip; +COND_UNRECOGNIZED: {true}? -> popMode, channel(HIDDEN); // TODO + + +mode DEFAULT_MODE; + +// preprocessor +PREP_ORG: O R G; +PREP_EQU: E Q U; +PREP_SET: S E T; +PREP_VAR: V A R; +PREP_IF: I F; +PREP_ENDIF: E N D I F; +PREP_INCLUDE: I N C L U D E; +PREP_MACRO: M A C R O; +PREP_ENDM: E N D M; +PREP_DB: D B; +PREP_DW: D W; +PREP_DS: D S; +PREP_ADDR: '$'; + +// registers +REG_A: A; +REG_B: B; +REG_C: C; +REG_D: D; +REG_E: E; +REG_H: H; +REG_L: L; +REG_IX: I X; +REG_IXH: I X H; +REG_IXL: I X L; +REG_IY: I Y; +REG_IYH: I Y H; +REG_IYL: I Y L; +REG_BC: B C; +REG_DE: D E; +REG_HL: H L; +REG_SP: S P; +REG_AF: A F; +REG_AFF: A F '\''; +REG_I: I; +REG_R: R; + +// operators +OP_MOD: M O D; +OP_SHR: S H R; +OP_SHL: S H L; +OP_NOT: N O T; +OP_AND: A N D; +OP_OR: O R; +OP_XOR: X O R; + +// literals +LIT_HEXNUMBER_1: '0' X [0-9a-fA-F]+; +LIT_NUMBER: [0-9]+ D?; +LIT_HEXNUMBER_2: [0-9a-fA-F]+ H; +LIT_OCTNUMBER: [0-7]+ [oOqQ]; +LIT_BINNUMBER: [01]+ B; +LIT_STRING_1: '\'' ~[']* '\''; +LIT_STRING_2: '"' ~["]* '"'; + +// other + +ID_IDENTIFIER: [a-zA-Z_?@] [a-zA-Z_?@0-9]*; +ID_LABEL: ID_IDENTIFIER ':'; + +ERROR : ~[+* \t\f\r\n(),=/-]+; // below: everything which does not require space + +//\+\* +// separators - not requiring space inbetween +SEP_LPAR: '('; +SEP_RPAR: ')'; +SEP_COMMA: ','; + +// operators not requiring space inbetween +OP_ADD: '+'; +OP_SUBTRACT: '-'; +OP_MULTIPLY: '*'; +OP_DIVIDE: '/'; +OP_EQUAL: '='; +OP_GT: '>'; +OP_GTE: '>='; +OP_LT: '<'; +OP_LTE: '<='; +OP_MOD_2: '%'; +OP_SHR_2: '>>'; +OP_SHL_2: '<<'; +OP_NOT_2: '!'; +OP_AND_2: '&'; +OP_OR_2: '|'; +OP_XOR_2: '~'; + +WS : [ \t\f]+ -> skip; +EOL: '\r'? '\n'; diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 new file mode 100644 index 000000000..99ee23565 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 @@ -0,0 +1,166 @@ +parser grammar AsZ80Parser; + +options { + tokenVocab = AsZ80Lexer; +} + +rStart: + EOL* rLine? (EOL+ rLine)* EOL* EOF + ; + +rLine: + label=ID_LABEL? EOL* statement=rStatement + | label=ID_LABEL; + +rStatement: + instr=rInstruction + | pseudo=rPseudoCode + | data=rData + ; + +rInstruction: + r8bitInstruction # instr8bit + | opcode=OPCODE_MVI reg=rRegister SEP_COMMA expr=rExpression # instrRegExpr + | opcode=OPCODE_LXI regpair=(REG_B|REG_D|REG_H|REG_SP) SEP_COMMA expr=rExpression # instrRegPairExpr + | opcode=OPCODE_LDA expr=rExpression # instrExpr + | opcode=OPCODE_STA expr=rExpression # instrExpr + | opcode=OPCODE_LHLD expr=rExpression # instrExpr + | opcode=OPCODE_SHLD expr=rExpression # instrExpr + | opcode=OPCODE_ADI expr=rExpression # instrExpr + | opcode=OPCODE_ACI expr=rExpression # instrExpr + | opcode=OPCODE_SUI expr=rExpression # instrExpr + | opcode=OPCODE_SBI expr=rExpression # instrExpr + | opcode=OPCODE_ANI expr=rExpression # instrExpr + | opcode=OPCODE_ORI expr=rExpression # instrExpr + | opcode=OPCODE_XRI expr=rExpression # instrExpr + | opcode=OPCODE_CPI expr=rExpression # instrExpr + | opcode=OPCODE_JMP expr=rExpression # instrExpr + | opcode=OPCODE_JC expr=rExpression # instrExpr + | opcode=OPCODE_JNC expr=rExpression # instrExpr + | opcode=OPCODE_JZ expr=rExpression # instrExpr + | opcode=OPCODE_JNZ expr=rExpression # instrExpr + | opcode=OPCODE_JM expr=rExpression # instrExpr + | opcode=OPCODE_JP expr=rExpression # instrExpr + | opcode=OPCODE_JPE expr=rExpression # instrExpr + | opcode=OPCODE_JPO expr=rExpression # instrExpr + | opcode=OPCODE_CALL expr=rExpression # instrExpr + | opcode=OPCODE_CC expr=rExpression # instrExpr + | opcode=OPCODE_CNC expr=rExpression # instrExpr + | opcode=OPCODE_CZ expr=rExpression # instrExpr + | opcode=OPCODE_CNZ expr=rExpression # instrExpr + | opcode=OPCODE_CM expr=rExpression # instrExpr + | opcode=OPCODE_CP expr=rExpression # instrExpr + | opcode=OPCODE_CPE expr=rExpression # instrExpr + | opcode=OPCODE_CPO expr=rExpression # instrExpr + | opcode=OPCODE_IN expr=rExpression # instrExpr + | opcode=OPCODE_OUT expr=rExpression # instrExpr + ; + +r8bitInstruction: + opcode=OPCODE_NOP # instrNoArgs + | opcode=OPCODE_INC regpair=(REG_BC|REG_DE|REG_HL|REG_SP) # instrRegPair + | opcode=OPCODE_INC reg=rRegister # instrReg + | opcode=OPCODE_DEC reg=rRegister # instrReg + | opcode=OPCODE_RLCA # instrNoArgs + | opcode=OPCODE_EX src=REG_AF SEP_COMMA dst=REG_AFF # instrRegPairRegPair + | opcode=OPCODE_EX src=REG_DE SEP_COMMA dst=REG_HL # instrRegPairRegPair + | opcode=OPCODE_EX SEP_LPAR src=REG_SP SEP_RPAR SEP_COMMA dst=REG_HL # instrRegPairRegPair + | opcode=OPCODE_ADD REG_HL SEP_COMMA regpair=(REG_BC|REG_DE|REG_HL|REG_SP) # instrRegPair + | opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR regpair=(REG_BC|REG_DE) SEP_RPAR # instrRegPair + | opcode=OPCODE_DEC regpair=(REG_BC|REG_DE|REG_HL|REG_SP) # instrRegPair + | opcode=OPCODE_RRCA # instrNoArgs + | opcode=OPCODE_RLA # instrNoArgs + | opcode=OPCODE_RRA # instrNoArgs + | opcode=OPCODE_DAA # instrNoArgs + | opcode=OPCODE_CPL # instrNoArgs + | opcode=OPCODE_INC SEP_LPAR regpairM=REG_HL SEP_RPAR # instrRegPair + | opcode=OPCODE_DEC SEP_LPAR regpairM=REG_HL SEP_RPAR # instrRegPair + | opcode=OPCODE_SCF # instrNoArgs + | opcode=OPCODE_CCF # instrNoArgs + | opcode=OPCODE_LD dst=rRegister SEP_COMMA src=rRegister # instrRegReg + | opcode=OPCODE_HALT # instrNoArgs + | opcode=OPCODE_ADD REG_A SEP_COMMA reg=rRegister # instrReg + | opcode=OPCODE_ADC REG_A SEP_COMMA reg=rRegister # instrReg + | opcode=OPCODE_SUB reg=rRegister # instrReg + | opcode=OPCODE_SBC REG_A SEP_COMMA reg=rRegister # instrReg + | opcode=OPCODE_AND reg=rRegister # instrReg + | opcode=OPCODE_XOR reg=rRegister # instrReg + | opcode=OPCODE_OR reg=rRegister # instrReg + | opcode=OPCODE_CP reg=rRegister # instrReg + | opcode=OPCODE_RET cond=(COND_C|COND_NC|COND_Z|COND_NZ|COND_M|COND_P|COND_PE|COND_PO)? # instrCond + | opcode=OPCODE_POP regpair=(REG_BC|REG_DE|REG_HL|REG_AF) # instrRegPair + | opcode=OPCODE_PUSH regpair=(REG_BC|REG_DE|REG_HL|REG_AF) # instrRegPair + | opcode=OPCODE_RST expr=rExpression # instr8bitExpr + | opcode=OPCODE_EXX # instrNoArgs + | opcode=OPCODE_JP SEP_LPAR regpairM=REG_HL SEP_RPAR # instrRegPair + | opcode=OPCODE_DI # instrNoArgs + | opcode=OPCODE_LD dst=REG_SP SEP_COMMA src=REG_HL # instrRegPairRegPair + | opcode=OPCODE_EI # instrNoArgs + ; + +rRegister: + r=REG_A + | r=REG_B + | r=REG_C + | r=REG_D + | r=REG_E + | r=REG_H + | r=REG_L + | SEP_LPAR r=REG_HL SEP_RPAR + ; + + + + +rPseudoCode: + PREP_ORG expr=rExpression # pseudoOrg + | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu + | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoSet + | PREP_IF expr=rExpression EOL (rLine EOL)* EOL* PREP_ENDIF # pseudoIf + | id=ID_IDENTIFIER PREP_MACRO params=rMacroParameters? EOL (rLine EOL)* EOL* PREP_ENDM # pseudoMacroDef + | id=ID_IDENTIFIER args=rMacroArguments? # pseudoMacroCall + | PREP_INCLUDE filename=(LIT_STRING_1|LIT_STRING_2) # pseudoInclude + ; + +rMacroParameters: + ID_IDENTIFIER (SEP_COMMA ID_IDENTIFIER)* + ; + +rMacroArguments: + rExpression (SEP_COMMA rExpression)* + ; + +rData: + PREP_DB rDBdata (SEP_COMMA rDBdata)* # dataDB + | PREP_DW rDWdata (SEP_COMMA rDWdata)* # dataDW + | PREP_DS data=rExpression # dataDS + ; + +rDBdata: + expr=rExpression + | instr=r8bitInstruction + ; + +rDWdata: + expr=rExpression + ; + +rExpression: + unaryop=(OP_ADD|OP_SUBTRACT|OP_NOT) expr=rExpression # exprUnary + | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_SHL|OP_SHR) expr2=rExpression # exprInfix + | expr1=rExpression op=OP_AND expr2=rExpression # exprInfix + | expr1=rExpression op=OP_XOR expr2=rExpression # exprInfix + | expr1=rExpression op=OP_OR expr2=rExpression # exprInfix + | expr1=rExpression op=OP_EQUAL expr2=rExpression # exprInfix + | SEP_LPAR expr=rExpression SEP_RPAR # exprParens + | num=LIT_NUMBER # exprDec + | num=LIT_HEXNUMBER_1 # exprHex1 + | num=LIT_HEXNUMBER_2 # exprHex2 + | num=LIT_OCTNUMBER # exprOct + | num=LIT_BINNUMBER # exprBin + | PREP_ADDR # exprCurrentAddress + | id=ID_IDENTIFIER # exprId + | str=(LIT_STRING_1|LIT_STRING_2) # exprString + ; diff --git a/plugins/compiler/as-z80/src/main/jflex/lexer.jflex b/plugins/compiler/as-z80/src/main/jflex/lexer.jflex deleted file mode 100644 index 1921e59c4..000000000 --- a/plugins/compiler/as-z80/src/main/jflex/lexer.jflex +++ /dev/null @@ -1,652 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80; - -import java_cup.runtime.ComplexSymbolFactory.Location; -import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; -import net.emustudio.emulib.plugins.compiler.Token; - -import java.io.*; - -%% - -/* options */ -%class LexerImpl -%cup -%public -%implements LexicalAnalyzer -%line -%column -%char -%caseless -%unicode -%type TokenImpl -%states CONDITION,LD,LD_A,LD_RR,LD_II,LD_X_COMMA - -%{ - @Override - public Token getToken() throws IOException { - return next_token(); - } - - @Override - public void reset(Reader in, int yyline, int yychar, int yycolumn) { - yyreset(in); - this.yyline = yyline; - this.yychar = yychar; - this.yycolumn = yycolumn; - } - - @Override - public void reset(Reader in, int line, int offset, int column, int lexerState) { - yyreset(in); - this.yyline = line; - this.yychar = offset; - this.yycolumn = column; - this.zzLexicalState = lexerState; - } - - private TokenImpl token(int id, int category) { - Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); - return new TokenImpl(id, category, zzLexicalState, yytext(), left, right); - } - - private TokenImpl token(int id, int category, Object value) { - Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); - return new TokenImpl(id, category, zzLexicalState, yytext(), left, right, value); - } -%} -%eofval{ - return token(TokenImpl.EOF, Token.TEOF); -%eofval} - -Comment =(";"[^\r\n]*) - -Eol =[\n]|[\r]|[\n][\r] -WhiteSpace =([ ]|[\t]|[\f]) - -DecimalNum =[0-9]+[dD]? -OctalNum =[0-7]+[oOqQ] -HexaPostfix =([0-9a-fA-F]*[hH]) -HexaNum =[0-9]{HexaPostfix} -BinaryNum =[0-1]+[bB] - -AnyChar =([^\"\n\r]) -UnclosedString =(\"{AnyChar}+) -String ={UnclosedString}\" - -Identifier =([a-zA-Z_\?@])[a-zA-Z_\?@0-9]* -Label ={Identifier}[\:] - -%% - -/* reserved words */ -"adc" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_ADC, Token.RESERVED); - } -"add" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_ADD, Token.RESERVED); -} -"and" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_AND, Token.RESERVED); -} -"bit" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_BIT, Token.RESERVED); -} -"call" { yybegin(CONDITION); - return token(TokenImpl.RESERVED_CALL, Token.RESERVED); -} -"ccf" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_CCF, Token.RESERVED); -} -"cp" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_CP, Token.RESERVED); -} -"cpd" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_CPD, Token.RESERVED); -} -"cpdr" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_CPDR, Token.RESERVED); -} -"cpi" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_CPI, Token.RESERVED); -} -"cpir" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_CPIR, Token.RESERVED); -} -"cpl" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_CPL, Token.RESERVED); -} -"daa" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_DAA, Token.RESERVED); -} -"dec" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_DEC, Token.RESERVED); -} -"di" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_DI, Token.RESERVED); -} -"djnz" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_DJNZ, Token.RESERVED); -} -"ei" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_EI, Token.RESERVED); -} -"ex" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_EX, Token.RESERVED); -} -"exx" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_EXX, Token.RESERVED); -} -"halt" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_HALT, Token.RESERVED); -} -"im" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_IM, Token.RESERVED); -} -"in" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_IN, Token.RESERVED); -} -"inc" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_INC, Token.RESERVED); -} -"ind" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_IND, Token.RESERVED); -} -"indr" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_INDR, Token.RESERVED); -} -"ini" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_INI, Token.RESERVED); -} -"inir" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_INIR, Token.RESERVED); -} -"jp" { yybegin(CONDITION); - return token(TokenImpl.RESERVED_JP, Token.RESERVED); -} -"jr" { yybegin(CONDITION); - return token(TokenImpl.RESERVED_JR, Token.RESERVED); -} -"ld" { yybegin(LD); - return token(TokenImpl.RESERVED_LD, Token.RESERVED); -} -"ldd" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_LDD, Token.RESERVED); -} -"lddr" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_LDDR, Token.RESERVED); -} -"ldi" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_LDI, Token.RESERVED); -} -"ldir" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_LDIR, Token.RESERVED); -} -"neg" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_NEG, Token.RESERVED); -} -"nop" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_NOP, Token.RESERVED); -} -"or" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_OR, Token.RESERVED); -} -"otdr" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_OTDR, Token.RESERVED); -} -"otir" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_OTIR, Token.RESERVED); -} -"out" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_OUT, Token.RESERVED); -} -"outd" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_OUTD, Token.RESERVED); -} -"outi" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_OUTI, Token.RESERVED); -} -"pop" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_POP, Token.RESERVED); -} -"push" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_PUSH, Token.RESERVED); -} -"res" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RES, Token.RESERVED); -} -"ret" { yybegin(CONDITION); - return token(TokenImpl.RESERVED_RET, Token.RESERVED); -} -"reti" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RETI, Token.RESERVED); -} -"retn" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RETN, Token.RESERVED); -} -"rl" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RL, Token.RESERVED); -} -"rla" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RLA, Token.RESERVED); -} -"rlc" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RLC, Token.RESERVED); -} -"rlca" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RLCA, Token.RESERVED); -} -"rld" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RLD, Token.RESERVED); -} -"rr" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RR, Token.RESERVED); -} -"rra" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RRA, Token.RESERVED); -} -"rrc" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RRC, Token.RESERVED); -} -"rrca" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RRCA, Token.RESERVED); -} -"rrd" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RRD, Token.RESERVED); -} -"rst" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_RST, Token.RESERVED); -} -"sbc" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_SBC, Token.RESERVED); -} -"scf" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_SCF, Token.RESERVED); -} -"set" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_SET, Token.RESERVED); -} -"sla" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_SLA, Token.RESERVED); -} -"sra" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_SRA, Token.RESERVED); -} -"sll" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_SLL, Token.RESERVED); -} -"srl" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_SRL, Token.RESERVED); -} -"sub" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_SUB, Token.RESERVED); -} -"xor" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_XOR, Token.RESERVED); -} -/* CALL,JP,JR,RET */ - "c" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_C, Token.RESERVED); -} - "nc" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_NC, Token.RESERVED); -} - "z" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_Z, Token.RESERVED); -} - "nz" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_NZ, Token.RESERVED); -} - "m" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_M, Token.RESERVED); -} - "p" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_P, Token.RESERVED); -} - "pe" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_PE, Token.RESERVED); -} - "po" { yybegin(YYINITIAL); - return token(TokenImpl.RESERVED_PO, Token.RESERVED); -} - -/* preprocessor words */ -"org" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_ORG, Token.PREPROCESSOR); -} -"equ" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_EQU, Token.PREPROCESSOR); -} -"var" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_VAR, Token.PREPROCESSOR); -} -"if" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_IF, Token.PREPROCESSOR); -} -"endif" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_ENDIF, Token.PREPROCESSOR); -} -"macro" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_MACRO, Token.PREPROCESSOR); -} -"endm" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_ENDM, Token.PREPROCESSOR); -} -"db" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_DB, Token.PREPROCESSOR); -} -"dw" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_DW, Token.PREPROCESSOR); -} -"ds" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_DS, Token.PREPROCESSOR); -} -"$" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_ADDR, Token.PREPROCESSOR); -} -"include" { yybegin(YYINITIAL); - return token(TokenImpl.PREPROCESSOR_INCLUDE, Token.PREPROCESSOR); -} - -/* registers */ - "a" { yybegin(LD_A); - return token(TokenImpl.REGISTERS_A, Token.REGISTER); -} -"a" { - return token(TokenImpl.REGISTERS_A, Token.REGISTER); -} -"b" { yybegin(YYINITIAL); - return token(TokenImpl.REGISTERS_B, Token.REGISTER); -} -"c" { yybegin(YYINITIAL); - return token(TokenImpl.REGISTERS_C, Token.REGISTER); -} -"d" { yybegin(YYINITIAL); - return token(TokenImpl.REGISTERS_D, Token.REGISTER); -} -"e" { yybegin(YYINITIAL); - return token(TokenImpl.REGISTERS_E, Token.REGISTER); -} -"h" { yybegin(YYINITIAL); - return token(TokenImpl.REGISTERS_H, Token.REGISTER); -} -"l" { yybegin(YYINITIAL); - return token(TokenImpl.REGISTERS_L, Token.REGISTER); -} - "ix" { yybegin(LD_II); - return token(TokenImpl.REGISTERS_IX, Token.REGISTER); -} -"ix" { - return token(TokenImpl.REGISTERS_IX, Token.REGISTER); -} - "iy" { yybegin(LD_II); - return token(TokenImpl.REGISTERS_IY, Token.REGISTER); -} -"iy" { - return token(TokenImpl.REGISTERS_IY, Token.REGISTER); -} - "sp" { yybegin(LD_RR); - return token(TokenImpl.REGISTERS_SP, Token.REGISTER); -} -"sp" { - return token(TokenImpl.REGISTERS_SP, Token.REGISTER); -} - "bc" { yybegin(LD_RR); - return token(TokenImpl.REGISTERS_BC, Token.REGISTER); -} -"bc" { - return token(TokenImpl.REGISTERS_BC, Token.REGISTER); -} - "de" { yybegin(LD_RR); - return token(TokenImpl.REGISTERS_DE, Token.REGISTER); -} -"de" { - return token(TokenImpl.REGISTERS_DE, Token.REGISTER); -} - "hl" { yybegin(LD_RR); - return token(TokenImpl.REGISTERS_HL, Token.REGISTER); -} -"hl" { - return token(TokenImpl.REGISTERS_HL, Token.REGISTER); -} -"af" { yybegin(YYINITIAL); - return token(TokenImpl.REGISTERS_AF, Token.REGISTER); -} -"af'" { yybegin(YYINITIAL); - return token(TokenImpl.REGISTERS_AFF, Token.REGISTER); -} -"i" { yybegin(YYINITIAL); - return token(TokenImpl.REGISTERS_I, Token.REGISTER); -} -"r" { yybegin(YYINITIAL); - return token(TokenImpl.REGISTERS_R, Token.REGISTER); -} - -/* separators */ - "(" { yybegin(YYINITIAL); - return token(TokenImpl.SEPARATOR_INDEXLPAR, Token.SEPARATOR); -} -"(" { - return token(TokenImpl.SEPARATOR_LPAR, Token.SEPARATOR); -} -")" { yybegin(YYINITIAL); - return token(TokenImpl.SEPARATOR_RPAR, Token.SEPARATOR); -} - "," { yybegin(LD_X_COMMA); - return token(TokenImpl.SEPARATOR_COMMA, Token.SEPARATOR); -} - "," { - return token(TokenImpl.SEPARATOR_COMMA, Token.SEPARATOR); -} -{Eol} { yybegin(YYINITIAL); - return token(TokenImpl.SEPARATOR_EOL, Token.SEPARATOR); -} -{WhiteSpace}+ { /* ignore white spaces */ } - -/* operators */ -"+" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_ADD, Token.OPERATOR); -} -"-" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_SUBTRACT, Token.OPERATOR); -} -"*" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_MULTIPLY, Token.OPERATOR); -} -"/" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_DIVIDE, Token.OPERATOR); -} -"=" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_EQUAL, Token.OPERATOR); -} -">" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_GREATER, Token.OPERATOR); -} -"<" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_LESS, Token.OPERATOR); -} -">=" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_GE, Token.OPERATOR); -} -"<=" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_LE, Token.OPERATOR); -} -"%" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_MOD, Token.OPERATOR); -} -">>" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_SHR, Token.OPERATOR); -} -"<<" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_SHL, Token.OPERATOR); -} -"!" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_NOT, Token.OPERATOR); -} -"&" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_AND, Token.OPERATOR); -} -"|" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_OR, Token.OPERATOR); -} -"~" { yybegin(YYINITIAL); - return token(TokenImpl.OPERATOR_XOR, Token.OPERATOR); -} - -/* comment */ -{Comment} { - yybegin(YYINITIAL); - return token(TokenImpl.TCOMMENT, Token.COMMENT); -} - -/* literals */ -{DecimalNum} { - yybegin(YYINITIAL); - - String text = yytext().replaceFirst("[dD]",""); - int num = 0; - int tokenId; - int tokenType = Token.LITERAL; - - try { - num = Integer.parseInt(text,10); - if (num > 65535) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } else if (num > 255) { - tokenId = TokenImpl.LITERAL_DECIMAL_16BIT; - } else { - tokenId = TokenImpl.LITERAL_DECIMAL_8BIT; - } - } catch (NumberFormatException e) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } - return token(tokenId, tokenType, (Object)num); -} -{OctalNum} { - yybegin(YYINITIAL); - - String text = yytext().replaceFirst("[oOqQ]",""); - int num = 0; - int tokenId; - int tokenType = Token.LITERAL; - - try { - num = Integer.parseInt(text,8); - if (num > 65535) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } else if (num > 255) { - tokenId = TokenImpl.LITERAL_DECIMAL_16BIT; - } else { - tokenId = TokenImpl.LITERAL_DECIMAL_8BIT; - } - } catch (NumberFormatException e) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } - return token(tokenId, tokenType, (Object)num); -} -{HexaNum} { - yybegin(YYINITIAL); - - String text = yytext().replaceFirst("[hH]",""); - int num = 0; - int tokenId; - int tokenType = Token.LITERAL; - - try { - num = Integer.parseInt(text,16); - if (num > 65535) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } else if (num > 255) { - tokenId = TokenImpl.LITERAL_DECIMAL_16BIT; - } else { - tokenId = TokenImpl.LITERAL_DECIMAL_8BIT; - } - } catch (NumberFormatException e) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } - return token(tokenId, tokenType, (Object)num); -} -{BinaryNum} { - yybegin(YYINITIAL); - - String text = yytext().replaceFirst("[bB]",""); - int num = 0; - int tokenId; - int tokenType = Token.LITERAL; - - try { - num = Integer.parseInt(text,2); - if (num > 65535) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } else if (num > 255) { - tokenId = TokenImpl.LITERAL_DECIMAL_16BIT; - } else { - tokenId = TokenImpl.LITERAL_DECIMAL_8BIT; - } - } catch (NumberFormatException e) { - tokenId = TokenImpl.ERROR_DECIMAL_SIZE; - tokenType = Token.ERROR; - } - return token(tokenId, tokenType, (Object)num); -} -{UnclosedString} { - yybegin(YYINITIAL); - return token(TokenImpl.ERROR_UNCLOSED_STRING, Token.ERROR); -} -{String} { - yybegin(YYINITIAL); - - String text = yytext(); - String val = text.substring(1,text.length()-1); - if (val.length() > 1) { - return token(TokenImpl.LITERAL_STRING, Token.LITERAL, val); - } else { - byte[] b = val.getBytes(); - int numval = b[0]; - for (int i = 1; i < b.length; i++) - numval = (numval <<8) + b[i]; - - int tokenId = (numval > 255) ? TokenImpl.LITERAL_DECIMAL_16BIT : TokenImpl.LITERAL_DECIMAL_8BIT; - return token(tokenId, Token.LITERAL, numval); - } -} -{Identifier} { - yybegin(YYINITIAL); - return token(TokenImpl.TIDENTIFIER, Token.IDENTIFIER, yytext().toUpperCase()); -} -{Label} { - yybegin(YYINITIAL); - String text = yytext(); - Object val = text.substring(0,text.length()-1).toUpperCase(); - return token(TokenImpl.TLABEL, Token.LABEL, val); -} -. { - yybegin(YYINITIAL); - return token(TokenImpl.error, Token.ERROR); -} diff --git a/settings.gradle b/settings.gradle index 5506ec622..7619871f2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -23,7 +23,7 @@ include ':application' include ':plugins:compiler:as-8080' include ':plugins:compiler:as-ssem' -//include ':plugins:compiler:as-z80' +include ':plugins:compiler:as-z80' //include ':plugins:compiler:brainc-brainduck' //include ':plugins:compiler:ramc-ram' //include ':plugins:compiler:raspc-rasp' From 8da84d407f8f7cccfd28be264718dd5cc809e839 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 5 Feb 2022 11:46:38 +0100 Subject: [PATCH 094/314] [#201] as-z80: draft --- .../as-8080/src/main/antlr/As8080Lexer.g4 | 13 +- .../as-8080/src/main/antlr/As8080Lexer.tokens | 26 +- .../as-8080/src/main/antlr/As8080Parser.g4 | 35 +- .../compiler/as8080/Assembler8080.java | 7 +- .../compiler/as8080/LexicalAnalyzerImpl.java | 11 + .../compiler/as8080/ast/expr/ExprInfix.java | 32 +- .../compiler/as8080/ast/expr/ExprUnary.java | 3 +- .../compiler/as8080/parser/ParseExprTest.java | 29 + .../as-z80/src/main/antlr/AsZ80Lexer.g4 | 7 +- .../as-z80/src/main/antlr/AsZ80Lexer.tokens | 172 + .../as-z80/src/main/antlr/AsZ80Parser.g4 | 114 +- .../src/main/antlr/gen/AsZ80Lexer.interp | 499 +++ .../as-z80/src/main/antlr/gen/AsZ80Lexer.java | 597 +++ .../src/main/antlr/gen/AsZ80Lexer.tokens | 172 + .../as-z80/src/main/gen/AsZ80Lexer.interp | 496 +++ .../as-z80/src/main/gen/AsZ80Lexer.java | 593 +++ .../as-z80/src/main/gen/AsZ80Lexer.tokens | 171 + .../as-z80/src/main/gen/AsZ80Parser.interp | 329 ++ .../as-z80/src/main/gen/AsZ80Parser.java | 3658 +++++++++++++++++ .../as-z80/src/main/gen/AsZ80Parser.tokens | 172 + .../src/main/gen/AsZ80ParserBaseListener.java | 578 +++ .../src/main/gen/AsZ80ParserBaseVisitor.java | 328 ++ .../src/main/gen/AsZ80ParserListener.java | 531 +++ .../src/main/gen/AsZ80ParserVisitor.java | 318 ++ .../plugins/compiler/asZ80/AssemblerZ80.java | 216 + .../plugins/compiler/asZ80/CompileError.java | 103 + .../plugins/compiler/asZ80/CompilerImpl.java | 193 - .../compiler/asZ80/LexicalAnalyzerImpl.java | 214 + .../plugins/compiler/asZ80/Namespace.java | 139 - .../compiler/asZ80/ParserErrorListener.java | 25 + .../plugins/compiler/asZ80/ParsingUtils.java | 57 + .../plugins/compiler/asZ80/Runner.java | 5 +- .../plugins/compiler/asZ80/TokenImpl.java | 100 - .../plugins/compiler/asZ80/ast/Evaluated.java | 37 + .../plugins/compiler/asZ80/ast/NameSpace.java | 45 + .../plugins/compiler/asZ80/ast/Node.java | 142 + .../plugins/compiler/asZ80/ast/Program.java | 49 + .../compiler/asZ80/ast/data/DataDB.java | 22 + .../compiler/asZ80/ast/data/DataDS.java | 24 + .../compiler/asZ80/ast/data/DataDW.java | 22 + .../asZ80/ast/expr/ExprCurrentAddress.java | 30 + .../compiler/asZ80/ast/expr/ExprId.java | 54 + .../compiler/asZ80/ast/expr/ExprInfix.java | 97 + .../compiler/asZ80/ast/expr/ExprNumber.java | 52 + .../compiler/asZ80/ast/expr/ExprString.java | 46 + .../compiler/asZ80/ast/expr/ExprUnary.java | 67 + .../compiler/asZ80/ast/instr/InstrExpr.java | 117 + .../compiler/asZ80/ast/instr/InstrNoArgs.java | 80 + .../compiler/asZ80/ast/instr/InstrReg.java | 84 + .../asZ80/ast/instr/InstrRegExpr.java | 52 + .../asZ80/ast/instr/InstrRegPair.java | 76 + .../asZ80/ast/instr/InstrRegPairExpr.java | 52 + .../compiler/asZ80/ast/instr/InstrRegReg.java | 55 + .../compiler/asZ80/ast/pseudo/PseudoEqu.java | 45 + .../compiler/asZ80/ast/pseudo/PseudoIf.java | 23 + .../asZ80/ast/pseudo/PseudoIfExpression.java | 20 + .../asZ80/ast/pseudo/PseudoInclude.java | 45 + .../asZ80/ast/pseudo/PseudoLabel.java | 54 + .../asZ80/ast/pseudo/PseudoMacroArgument.java | 25 + .../asZ80/ast/pseudo/PseudoMacroCall.java | 45 + .../asZ80/ast/pseudo/PseudoMacroDef.java | 45 + .../ast/pseudo/PseudoMacroParameter.java | 26 + .../compiler/asZ80/ast/pseudo/PseudoOrg.java | 22 + .../compiler/asZ80/ast/pseudo/PseudoSet.java | 45 + .../exceptions/AlreadyDefinedException.java | 26 - .../asZ80/exceptions/AmbiguousException.java | 26 - ...erException.java => CompileException.java} | 18 +- .../compiler/asZ80/exceptions/FatalError.java | 18 + .../InvalidMacroParamsCountException.java | 26 - .../exceptions/NeedMorePassException.java | 33 - .../exceptions/NegativeValueException.java | 26 - .../exceptions/SyntaxErrorException.java | 11 + .../exceptions/UndefinedMacroException.java | 26 - .../exceptions/UnexpectedEOFException.java | 26 - .../UnknownMacroParametersException.java | 25 - .../exceptions/ValueOutOfBoundsException.java | 27 - .../exceptions/ValueTooBigException.java | 26 - .../plugins/compiler/asZ80/tree/Address.java | 40 - .../compiler/asZ80/tree/Arithmetic.java | 117 - .../plugins/compiler/asZ80/tree/DataDB.java | 101 - .../plugins/compiler/asZ80/tree/DataDS.java | 68 - .../plugins/compiler/asZ80/tree/DataDW.java | 62 - .../plugins/compiler/asZ80/tree/DataNode.java | 71 - .../compiler/asZ80/tree/DecimalExpr.java | 43 - .../compiler/asZ80/tree/Identifier.java | 66 - .../plugins/compiler/asZ80/tree/Label.java | 57 - .../plugins/compiler/asZ80/tree/Program.java | 153 - .../compiler/asZ80/tree/PseudoEQU.java | 67 - .../plugins/compiler/asZ80/tree/PseudoIF.java | 77 - .../compiler/asZ80/tree/PseudoINCLUDE.java | 126 - .../compiler/asZ80/tree/PseudoMACRO.java | 104 - .../compiler/asZ80/tree/PseudoMACROCall.java | 84 - .../compiler/asZ80/tree/PseudoORG.java | 67 - .../compiler/asZ80/tree/PseudoVAR.java | 66 - .../plugins/compiler/asZ80/tree/Row.java | 110 - .../asZ80/treeAbstract/DataValue.java | 54 - .../asZ80/treeAbstract/Expression.java | 84 - .../asZ80/treeAbstract/InstrData.java | 31 - .../asZ80/treeAbstract/Instruction.java | 44 - .../compiler/asZ80/treeAbstract/Pseudo.java | 35 - .../asZ80/treeAbstract/Statement.java | 43 - .../visitors/CheckDeclarationsVisitor.java | 173 + .../asZ80/visitors/CheckExprSizesVisitor.java | 87 + .../asZ80/visitors/CreateDataVisitor.java | 49 + .../asZ80/visitors/CreateExprVisitor.java | 72 + .../asZ80/visitors/CreateInstrVisitor.java | 57 + .../asZ80/visitors/CreateLineVisitor.java | 40 + .../asZ80/visitors/CreateProgramVisitor.java | 28 + .../asZ80/visitors/CreatePseudoVisitor.java | 86 + .../asZ80/visitors/CreateVisitors.java | 11 + .../asZ80/visitors/EvaluateExprVisitor.java | 348 ++ .../asZ80/visitors/ExpandIncludesVisitor.java | 61 + .../asZ80/visitors/ExpandMacrosVisitor.java | 81 + .../asZ80/visitors/GenerateCodeVisitor.java | 119 + .../compiler/asZ80/visitors/NodeVisitor.java | 164 + .../visitors/SortMacroArgumentsVisitor.java | 98 + .../compiler/asZ80/CompilerImplTest.java | 173 - .../plugins/compiler/asZ80/Utils.java | 134 + .../asZ80/{ => e2e}/AbstractCompilerTest.java | 49 +- .../compiler/asZ80/e2e/AssemblerZ80Test.java | 148 + .../{ => e2e}/ConstantsAndVariablesTest.java | 14 +- .../compiler/asZ80/{ => e2e}/DataTest.java | 29 +- .../compiler/asZ80/{ => e2e}/IfNodeTest.java | 12 +- .../compiler/asZ80/{ => e2e}/IncludeTest.java | 22 +- .../compiler/asZ80/e2e/InstrExprTest.java | 20 + .../compiler/asZ80/e2e/InstrRegTest.java | 204 + .../compiler/asZ80/{ => e2e}/MacroTest.java | 24 +- .../{ORGTest.java => e2e/PseudoOrgTest.java} | 54 +- .../asZ80/parser/LexicalAnalyzerImplTest.java | 246 ++ .../compiler/asZ80/parser/ParseDataTest.java | 121 + .../compiler/asZ80/parser/ParseExprTest.java | 199 + .../compiler/asZ80/parser/ParseInstrTest.java | 223 + .../asZ80/parser/ParsePseudoTest.java | 181 + .../asZ80/parser/ParsingUtilsTest.java | 79 + .../CheckDeclarationsVisitorTest.java | 176 + .../visitors/CheckExprSizesVisitorTest.java | 243 ++ .../visitors/EvaluateExprVisitorTest.java | 471 +++ .../visitors/ExpandIncludesVisitorTest.java | 82 + .../asZ80/visitors/ExpandMacrosTest.java | 121 + .../visitors/GenerateCodeVisitorTest.java | 711 ++++ .../SortMacroArgumentsVisitorTest.java | 169 + 141 files changed, 16141 insertions(+), 2863 deletions(-) create mode 100644 plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens create mode 100644 plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.interp create mode 100644 plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.java create mode 100644 plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.tokens create mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp create mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java create mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.tokens create mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Parser.interp create mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Parser.java create mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Parser.tokens create mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseListener.java create mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80ParserListener.java create mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80ParserVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerImpl.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Namespace.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParserErrorListener.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParsingUtils.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/TokenImpl.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Evaluated.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Program.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDB.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDS.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDW.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprCurrentAddress.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprId.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprNumber.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprString.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprUnary.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrExpr.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNoArgs.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrReg.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegExpr.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPair.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPairExpr.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegReg.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoEqu.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoIf.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoIfExpression.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoInclude.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroArgument.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroCall.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroDef.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroParameter.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoOrg.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoSet.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/AlreadyDefinedException.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/AmbiguousException.java rename plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/{CompilerException.java => CompileException.java} (73%) create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/FatalError.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/InvalidMacroParamsCountException.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/NeedMorePassException.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/NegativeValueException.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/SyntaxErrorException.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UndefinedMacroException.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnexpectedEOFException.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnknownMacroParametersException.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/ValueOutOfBoundsException.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/ValueTooBigException.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Address.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Arithmetic.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDB.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDS.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDW.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataNode.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DecimalExpr.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Identifier.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Label.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Program.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoEQU.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoIF.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoINCLUDE.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoMACRO.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoMACROCall.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoORG.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoVAR.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Row.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/DataValue.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Expression.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/InstrData.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Instruction.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Pseudo.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Statement.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateDataVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateExprVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateLineVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateProgramVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateVisitors.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitor.java delete mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/CompilerImplTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java rename plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/{ => e2e}/AbstractCompilerTest.java (60%) create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java rename plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/{ => e2e}/ConstantsAndVariablesTest.java (92%) rename plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/{ => e2e}/DataTest.java (88%) rename plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/{ => e2e}/IfNodeTest.java (86%) rename plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/{ => e2e}/IncludeTest.java (81%) create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java rename plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/{ => e2e}/MacroTest.java (86%) rename plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/{ORGTest.java => e2e/PseudoOrgTest.java} (72%) create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitorTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java create mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 index 0c8836725..ea9de972e 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 @@ -158,7 +158,7 @@ LIT_STRING_2: '"' ~["]* '"'; ID_IDENTIFIER: [a-zA-Z_?@] [a-zA-Z_?@0-9]*; ID_LABEL: ID_IDENTIFIER ':'; -ERROR : ~[+* \t\f\r\n(),=/-]+; // below: everything which does not require space +ERROR : ~([+* \t\f\r\n(),=/-]|'~'|'>'|'<'|'&'|'|'|'%'|'^')+; // below: everything which does not require space //\+\* // separators - not requiring space inbetween @@ -172,6 +172,17 @@ OP_SUBTRACT: '-'; OP_MULTIPLY: '*'; OP_DIVIDE: '/'; OP_EQUAL: '='; +OP_GT: '>'; +OP_GTE: '>='; +OP_LT: '<'; +OP_LTE: '<='; +OP_MOD_2: '%'; +OP_SHR_2: '>>'; +OP_SHL_2: '<<'; +OP_NOT_2: '~'; +OP_AND_2: '&'; +OP_OR_2: '|'; +OP_XOR_2: '^'; WS : [ \t\f]+ -> skip; EOL: '\r'? '\n'; diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens index cf48b0b9d..add624e00 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens @@ -125,8 +125,19 @@ OP_SUBTRACT=124 OP_MULTIPLY=125 OP_DIVIDE=126 OP_EQUAL=127 -WS=128 -EOL=129 +OP_GT=128 +OP_GTE=129 +OP_LT=130 +OP_LTE=131 +OP_MOD_2=132 +OP_SHR_2=133 +OP_SHL_2=134 +OP_NOT_2=135 +OP_AND_2=136 +OP_OR_2=137 +OP_XOR_2=138 +WS=139 +EOL=140 '$'=92 '('=120 ')'=121 @@ -136,3 +147,14 @@ EOL=129 '*'=125 '/'=126 '='=127 +'>'=128 +'>='=129 +'<'=130 +'<='=131 +'%'=132 +'>>'=133 +'<<'=134 +'~'=135 +'&'=136 +'|'=137 +'^'=138 diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index 989475483..6c6cdfc18 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -148,21 +148,22 @@ rDWdata: ; rExpression: - unaryop=(OP_ADD|OP_SUBTRACT|OP_NOT) expr=rExpression # exprUnary - | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD) expr2=rExpression # exprInfix - | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression # exprInfix - | expr1=rExpression op=(OP_SHL|OP_SHR) expr2=rExpression # exprInfix - | expr1=rExpression op=OP_AND expr2=rExpression # exprInfix - | expr1=rExpression op=OP_XOR expr2=rExpression # exprInfix - | expr1=rExpression op=OP_OR expr2=rExpression # exprInfix - | expr1=rExpression op=OP_EQUAL expr2=rExpression # exprInfix - | SEP_LPAR expr=rExpression SEP_RPAR # exprParens - | num=LIT_NUMBER # exprDec - | num=LIT_HEXNUMBER_1 # exprHex1 - | num=LIT_HEXNUMBER_2 # exprHex2 - | num=LIT_OCTNUMBER # exprOct - | num=LIT_BINNUMBER # exprBin - | PREP_ADDR # exprCurrentAddress - | id=ID_IDENTIFIER # exprId - | str=(LIT_STRING_1|LIT_STRING_2) # exprString + unaryop=(OP_ADD|OP_SUBTRACT|OP_NOT|OP_NOT_2) expr=rExpression # exprUnary + | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD|OP_MOD_2) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_SHL|OP_SHR|OP_SHR_2|OP_SHL_2) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_GT|OP_GTE|OP_LT|OP_LTE) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_AND|OP_AND_2) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_XOR|OP_XOR_2) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_OR|OP_OR_2) expr2=rExpression # exprInfix + | expr1=rExpression op=OP_EQUAL expr2=rExpression # exprInfix + | SEP_LPAR expr=rExpression SEP_RPAR # exprParens + | num=LIT_NUMBER # exprDec + | num=LIT_HEXNUMBER_1 # exprHex1 + | num=LIT_HEXNUMBER_2 # exprHex2 + | num=LIT_OCTNUMBER # exprOct + | num=LIT_BINNUMBER # exprBin + | PREP_ADDR # exprCurrentAddress + | id=ID_IDENTIFIER # exprId + | str=(LIT_STRING_1|LIT_STRING_2) # exprString ; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index ae86b17cf..00a3b83e5 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -94,16 +94,11 @@ public String getCopyright() { @Override public String getDescription() { - return "Lightly modified/extended clone of original Intel's 8080 assembler."; + return "Modified and extended clone of original Intel's 8080 assembler."; } @Override public LexicalAnalyzer createLexer(String s) { - // @Override - // public LexicalAnalyzer createLexer(String s) { - // SSEMLexer lexer = createLexer(CharStreams.fromString(s)); - // return new LexicalAnalyzerImpl(lexer); - // } As8080Lexer lexer = createLexer(CharStreams.fromString(s)); return new LexicalAnalyzerImpl(lexer); } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java index 2280f4069..e6b697386 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java @@ -131,12 +131,23 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[OP_DIVIDE] = Token.OPERATOR; tokenMap[OP_EQUAL] = Token.OPERATOR; tokenMap[OP_MOD] = Token.OPERATOR; + tokenMap[OP_MOD_2] = Token.OPERATOR; tokenMap[OP_SHR] = Token.OPERATOR; + tokenMap[OP_SHR_2] = Token.OPERATOR; tokenMap[OP_SHL] = Token.OPERATOR; + tokenMap[OP_SHL_2] = Token.OPERATOR; tokenMap[OP_NOT] = Token.OPERATOR; + tokenMap[OP_NOT_2] = Token.OPERATOR; tokenMap[OP_AND] = Token.OPERATOR; + tokenMap[OP_AND_2] = Token.OPERATOR; tokenMap[OP_OR] = Token.OPERATOR; + tokenMap[OP_OR_2] = Token.OPERATOR; tokenMap[OP_XOR] = Token.OPERATOR; + tokenMap[OP_XOR_2] = Token.OPERATOR; + tokenMap[OP_LT] = Token.OPERATOR; + tokenMap[OP_LTE] = Token.OPERATOR; + tokenMap[OP_GT] = Token.OPERATOR; + tokenMap[OP_GTE] = Token.OPERATOR; tokenMap[LIT_NUMBER] =Token.LITERAL; tokenMap[LIT_HEXNUMBER_1] =Token.LITERAL; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index af60a892f..c4873f990 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -20,19 +20,27 @@ public class ExprInfix extends Node { public final int operationCode; static { - infixOps.putAll(Map.of( - OP_ADD, Integer::sum, - OP_SUBTRACT, (x, y) -> x - y, - OP_DIVIDE, (x, y) -> x / y, // can throw! - OP_MULTIPLY, (x, y) -> x * y, - OP_MOD, (x, y) -> x % y, - OP_AND, (x, y) -> x & y, - OP_OR, (x, y) -> x | y, - OP_XOR, (x, y) -> x ^ y, - OP_SHL, (x, y) -> x << y, - OP_SHR, (x, y) -> x >>> y - )); + infixOps.put(OP_ADD, Integer::sum); + infixOps.put(OP_SUBTRACT, (x, y) -> x - y); + infixOps.put(OP_DIVIDE, (x, y) -> x / y); // can throw! + infixOps.put(OP_MULTIPLY, (x, y) -> x * y); + infixOps.put(OP_MOD, (x, y) -> x % y); + infixOps.put(OP_MOD_2, (x, y) -> x % y); + infixOps.put(OP_AND, (x, y) -> x & y); + infixOps.put(OP_AND_2, (x, y) -> x & y); + infixOps.put(OP_OR, (x, y) -> x | y); + infixOps.put(OP_OR_2, (x, y) -> x | y); + infixOps.put(OP_XOR, (x, y) -> x ^ y); + infixOps.put(OP_XOR_2, (x, y) -> x ^ y); + infixOps.put(OP_SHL, (x, y) -> x << y); + infixOps.put(OP_SHL_2, (x, y) -> x << y); + infixOps.put(OP_SHR, (x, y) -> x >>> y); + infixOps.put(OP_SHR_2, (x, y) -> x >>> y); infixOps.put(OP_EQUAL, (x, y) -> ((x.equals(y)) ? 1 : 0)); + infixOps.put(OP_LT, (x, y) -> (x < y) ? 1 : 0); + infixOps.put(OP_LTE, (x, y) -> (x <= y) ? 1 : 0); + infixOps.put(OP_GT, (x, y) -> (x > y) ? 1 : 0); + infixOps.put(OP_GTE, (x, y) -> (x >= y) ? 1 : 0); } public ExprInfix(int line, int column, int op) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index 07070ab81..69dcdebc0 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -17,7 +17,8 @@ public class ExprUnary extends Node { private final static Map> unaryOps = Map.of( OP_ADD, x -> x, OP_SUBTRACT, x -> -x, - OP_NOT, x -> ~x + OP_NOT, x -> ~x, + OP_NOT_2, x -> ~x ); private final Function operation; public final int operationCode; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java index 50eaca344..1535de4e4 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java @@ -151,6 +151,35 @@ public void testAndMulXorDivNotPlusMinus() { ); } + @Test + public void testAndMulXorDivNotPlusMinusWithOperators() { + Program program = parseProgram("db ~1 & 2 | 2 ^ 5 = -5 * 6 << 4 - 1 >> 2"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprInfix(0, 0, OP_OR_2) + .addChild(new ExprInfix(0, 0, OP_AND_2) + .addChild(new ExprUnary(0, 0, OP_NOT_2) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR_2) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 5)))) + .addChild(new ExprInfix(0, 0, OP_SHR_2) // shl/shr associates to the right + .addChild(new ExprInfix(0, 0, OP_SHL_2) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))), + program + ); + } + @Test public void testParenthesis() { Program program = parseProgram("db (2 + 3) * (4 - 2)"); diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 index 2605ffaa7..c2afb4b58 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 @@ -119,7 +119,6 @@ mode DEFAULT_MODE; PREP_ORG: O R G; PREP_EQU: E Q U; PREP_SET: S E T; -PREP_VAR: V A R; PREP_IF: I F; PREP_ENDIF: E N D I F; PREP_INCLUDE: I N C L U D E; @@ -176,7 +175,7 @@ LIT_STRING_2: '"' ~["]* '"'; ID_IDENTIFIER: [a-zA-Z_?@] [a-zA-Z_?@0-9]*; ID_LABEL: ID_IDENTIFIER ':'; -ERROR : ~[+* \t\f\r\n(),=/-]+; // below: everything which does not require space +ERROR : ~([+* \t\f\r\n(),=/-]|'~'|'>'|'<'|'&'|'|'|'%'|'^')+; // below: everything which does not require space //\+\* // separators - not requiring space inbetween @@ -197,10 +196,10 @@ OP_LTE: '<='; OP_MOD_2: '%'; OP_SHR_2: '>>'; OP_SHL_2: '<<'; -OP_NOT_2: '!'; +OP_NOT_2: '~'; OP_AND_2: '&'; OP_OR_2: '|'; -OP_XOR_2: '~'; +OP_XOR_2: '^'; WS : [ \t\f]+ -> skip; EOL: '\r'? '\n'; diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens new file mode 100644 index 000000000..64c701cbd --- /dev/null +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens @@ -0,0 +1,172 @@ +COMMENT=1 +COMMENT2=2 +OPCODE_ADC=3 +OPCODE_ADD=4 +OPCODE_AND=5 +OPCODE_BIT=6 +OPCODE_CALL=7 +OPCODE_CCF=8 +OPCODE_CP=9 +OPCODE_CPD=10 +OPCODE_CPDR=11 +OPCODE_CPI=12 +OPCODE_CPIR=13 +OPCODE_CPL=14 +OPCODE_DAA=15 +OPCODE_DEC=16 +OPCODE_DI=17 +OPCODE_DJNZ=18 +OPCODE_EI=19 +OPCODE_EX=20 +OPCODE_EXX=21 +OPCODE_HALT=22 +OPCODE_IM=23 +OPCODE_IN=24 +OPCODE_INC=25 +OPCODE_IND=26 +OPCODE_INDR=27 +OPCODE_INI=28 +OPCODE_INIR=29 +OPCODE_JP=30 +OPCODE_JR=31 +OPCODE_LD=32 +OPCODE_LDD=33 +OPCODE_LDDR=34 +OPCODE_LDI=35 +OPCODE_LDIR=36 +OPCODE_NEG=37 +OPCODE_NOP=38 +OPCODE_OR=39 +OPCODE_OTDR=40 +OPCODE_OTIR=41 +OPCODE_OUT=42 +OPCODE_OUTD=43 +OPCODE_OUTI=44 +OPCODE_POP=45 +OPCODE_PUSH=46 +OPCODE_RES=47 +OPCODE_RET=48 +OPCODE_RETI=49 +OPCODE_RETN=50 +OPCODE_RL=51 +OPCODE_RLA=52 +OPCODE_RLC=53 +OPCODE_RLCA=54 +OPCODE_RLD=55 +OPCODE_RR=56 +OPCODE_RRA=57 +OPCODE_RRC=58 +OPCODE_RRCA=59 +OPCODE_RRD=60 +OPCODE_RST=61 +OPCODE_SBC=62 +OPCODE_SCF=63 +OPCODE_SET=64 +OPCODE_SLA=65 +OPCODE_SRA=66 +OPCODE_SLL=67 +OPCODE_SRL=68 +OPCODE_SUB=69 +OPCODE_XOR=70 +COND_C=71 +COND_NC=72 +COND_Z=73 +COND_NZ=74 +COND_M=75 +COND_P=76 +COND_PE=77 +COND_PO=78 +COND_WS=79 +COND_UNRECOGNIZED=80 +PREP_ORG=81 +PREP_EQU=82 +PREP_SET=83 +PREP_VAR=84 +PREP_IF=85 +PREP_ENDIF=86 +PREP_INCLUDE=87 +PREP_MACRO=88 +PREP_ENDM=89 +PREP_DB=90 +PREP_DW=91 +PREP_DS=92 +PREP_ADDR=93 +REG_A=94 +REG_B=95 +REG_C=96 +REG_D=97 +REG_E=98 +REG_H=99 +REG_L=100 +REG_IX=101 +REG_IXH=102 +REG_IXL=103 +REG_IY=104 +REG_IYH=105 +REG_IYL=106 +REG_BC=107 +REG_DE=108 +REG_HL=109 +REG_SP=110 +REG_AF=111 +REG_AFF=112 +REG_I=113 +REG_R=114 +OP_MOD=115 +OP_SHR=116 +OP_SHL=117 +OP_NOT=118 +OP_AND=119 +OP_OR=120 +OP_XOR=121 +LIT_HEXNUMBER_1=122 +LIT_NUMBER=123 +LIT_HEXNUMBER_2=124 +LIT_OCTNUMBER=125 +LIT_BINNUMBER=126 +LIT_STRING_1=127 +LIT_STRING_2=128 +ID_IDENTIFIER=129 +ID_LABEL=130 +ERROR=131 +SEP_LPAR=132 +SEP_RPAR=133 +SEP_COMMA=134 +OP_ADD=135 +OP_SUBTRACT=136 +OP_MULTIPLY=137 +OP_DIVIDE=138 +OP_EQUAL=139 +OP_GT=140 +OP_GTE=141 +OP_LT=142 +OP_LTE=143 +OP_MOD_2=144 +OP_SHR_2=145 +OP_SHL_2=146 +OP_NOT_2=147 +OP_AND_2=148 +OP_OR_2=149 +OP_XOR_2=150 +WS=151 +EOL=152 +'$'=93 +'('=132 +')'=133 +','=134 +'+'=135 +'-'=136 +'*'=137 +'/'=138 +'='=139 +'>'=140 +'>='=141 +'<'=142 +'<='=143 +'%'=144 +'>>'=145 +'<<'=146 +'~'=147 +'&'=148 +'|'=149 +'^'=150 diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 index 99ee23565..d1d79912b 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 @@ -20,61 +20,51 @@ rStatement: rInstruction: r8bitInstruction # instr8bit - | opcode=OPCODE_MVI reg=rRegister SEP_COMMA expr=rExpression # instrRegExpr - | opcode=OPCODE_LXI regpair=(REG_B|REG_D|REG_H|REG_SP) SEP_COMMA expr=rExpression # instrRegPairExpr - | opcode=OPCODE_LDA expr=rExpression # instrExpr - | opcode=OPCODE_STA expr=rExpression # instrExpr - | opcode=OPCODE_LHLD expr=rExpression # instrExpr - | opcode=OPCODE_SHLD expr=rExpression # instrExpr - | opcode=OPCODE_ADI expr=rExpression # instrExpr - | opcode=OPCODE_ACI expr=rExpression # instrExpr - | opcode=OPCODE_SUI expr=rExpression # instrExpr - | opcode=OPCODE_SBI expr=rExpression # instrExpr - | opcode=OPCODE_ANI expr=rExpression # instrExpr - | opcode=OPCODE_ORI expr=rExpression # instrExpr - | opcode=OPCODE_XRI expr=rExpression # instrExpr - | opcode=OPCODE_CPI expr=rExpression # instrExpr - | opcode=OPCODE_JMP expr=rExpression # instrExpr - | opcode=OPCODE_JC expr=rExpression # instrExpr - | opcode=OPCODE_JNC expr=rExpression # instrExpr - | opcode=OPCODE_JZ expr=rExpression # instrExpr - | opcode=OPCODE_JNZ expr=rExpression # instrExpr - | opcode=OPCODE_JM expr=rExpression # instrExpr + | opcode=OPCODE_LD regpair=(REG_BC|REG_DE|REG_HL|REG_SP) SEP_COMMA expr=rExpression # instrRegPairExpr + | opcode=OPCODE_LD reg=rRegister SEP_COMMA expr=rExpression # instrRegExpr + | opcode=OPCODE_JR expr=rExpression # instrExpr + | opcode=OPCODE_JR cond=(COND_NZ|COND_Z|COND_NC|COND_C) SEP_COMMA expr=rExpression # instrCondExpr + | opcode=OPCODE_LD SEP_LPAR expr=rExpression SEP_RPAR SEP_COMMA regpair=REG_HL # instrRefExprRegPair + | opcode=OPCODE_LD regpair=REG_HL SEP_COMMA SEP_LPAR expr=rExpression SEP_RPAR # instrRegPairRefExpr + | opcode=OPCODE_LD SEP_LPAR expr=rExpression SEP_RPAR SEP_COMMA reg=REG_A # instrRefExprReg + | opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR expr=rExpression SEP_RPAR # instrRegRefExpr | opcode=OPCODE_JP expr=rExpression # instrExpr - | opcode=OPCODE_JPE expr=rExpression # instrExpr - | opcode=OPCODE_JPO expr=rExpression # instrExpr + | opcode=OPCODE_JP cond=cCondition SEP_COMMA expr=rExpression # instrCondExpr | opcode=OPCODE_CALL expr=rExpression # instrExpr - | opcode=OPCODE_CC expr=rExpression # instrExpr - | opcode=OPCODE_CNC expr=rExpression # instrExpr - | opcode=OPCODE_CZ expr=rExpression # instrExpr - | opcode=OPCODE_CNZ expr=rExpression # instrExpr - | opcode=OPCODE_CM expr=rExpression # instrExpr + | opcode=OPCODE_CALL cond=cCondition SEP_COMMA expr=rExpression # instrCondExpr + | opcode=OPCODE_ADD REG_A SEP_COMMA expr=rExpression # instrExpr + | opcode=OPCODE_ADC REG_A SEP_COMMA expr=rExpression # instrExpr + | opcode=OPCODE_OUT SEP_LPAR expr=rExpression SEP_RPAR SEP_COMMA REG_A # instrRefExprReg + | opcode=OPCODE_SUB expr=rExpression # instrExpr + | opcode=OPCODE_IN REG_A SEP_COMMA SEP_LPAR expr=rExpression SEP_RPAR # instrRegRefExpr + | opcode=OPCODE_SBC REG_A SEP_COMMA expr=rExpression # instrExpr + | opcode=OPCODE_AND expr=rExpression # instrExpr + | opcode=OPCODE_XOR expr=rExpression # instrExpr + | opcode=OPCODE_OR expr=rExpression # instrExpr | opcode=OPCODE_CP expr=rExpression # instrExpr - | opcode=OPCODE_CPE expr=rExpression # instrExpr - | opcode=OPCODE_CPO expr=rExpression # instrExpr - | opcode=OPCODE_IN expr=rExpression # instrExpr - | opcode=OPCODE_OUT expr=rExpression # instrExpr ; r8bitInstruction: opcode=OPCODE_NOP # instrNoArgs + | opcode=OPCODE_LD SEP_LPAR regpair=(REG_BC|REG_DE) SEP_RPAR SEP_COMMA REG_A # instrRefRegPairReg + | opcode=OPCODE_LD SEP_LPAR regpair=REG_HL SEP_RPAR SEP_COMMA reg=rRegister # instrRefRegPairReg | opcode=OPCODE_INC regpair=(REG_BC|REG_DE|REG_HL|REG_SP) # instrRegPair | opcode=OPCODE_INC reg=rRegister # instrReg | opcode=OPCODE_DEC reg=rRegister # instrReg | opcode=OPCODE_RLCA # instrNoArgs | opcode=OPCODE_EX src=REG_AF SEP_COMMA dst=REG_AFF # instrRegPairRegPair | opcode=OPCODE_EX src=REG_DE SEP_COMMA dst=REG_HL # instrRegPairRegPair - | opcode=OPCODE_EX SEP_LPAR src=REG_SP SEP_RPAR SEP_COMMA dst=REG_HL # instrRegPairRegPair - | opcode=OPCODE_ADD REG_HL SEP_COMMA regpair=(REG_BC|REG_DE|REG_HL|REG_SP) # instrRegPair - | opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR regpair=(REG_BC|REG_DE) SEP_RPAR # instrRegPair + | opcode=OPCODE_EX SEP_LPAR src=REG_SP SEP_RPAR SEP_COMMA dst=REG_HL # instrRefRegPairRegPair + | opcode=OPCODE_ADD REG_HL SEP_COMMA regpair=(REG_BC|REG_DE|REG_HL|REG_SP) # instrRegPairRegPair + | opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR regpair=(REG_BC|REG_DE) SEP_RPAR # instrRegRefRegPair | opcode=OPCODE_DEC regpair=(REG_BC|REG_DE|REG_HL|REG_SP) # instrRegPair | opcode=OPCODE_RRCA # instrNoArgs | opcode=OPCODE_RLA # instrNoArgs | opcode=OPCODE_RRA # instrNoArgs | opcode=OPCODE_DAA # instrNoArgs | opcode=OPCODE_CPL # instrNoArgs - | opcode=OPCODE_INC SEP_LPAR regpairM=REG_HL SEP_RPAR # instrRegPair - | opcode=OPCODE_DEC SEP_LPAR regpairM=REG_HL SEP_RPAR # instrRegPair + | opcode=OPCODE_INC SEP_LPAR regpair=REG_HL SEP_RPAR # instrRefRegPair + | opcode=OPCODE_DEC SEP_LPAR regpair=REG_HL SEP_RPAR # instrRefRegPair | opcode=OPCODE_SCF # instrNoArgs | opcode=OPCODE_CCF # instrNoArgs | opcode=OPCODE_LD dst=rRegister SEP_COMMA src=rRegister # instrRegReg @@ -87,12 +77,13 @@ r8bitInstruction: | opcode=OPCODE_XOR reg=rRegister # instrReg | opcode=OPCODE_OR reg=rRegister # instrReg | opcode=OPCODE_CP reg=rRegister # instrReg - | opcode=OPCODE_RET cond=(COND_C|COND_NC|COND_Z|COND_NZ|COND_M|COND_P|COND_PE|COND_PO)? # instrCond + | opcode=OPCODE_RET cond=cCondition # instrCond + | opcode=OPCODE_RET # instrNoArgs | opcode=OPCODE_POP regpair=(REG_BC|REG_DE|REG_HL|REG_AF) # instrRegPair | opcode=OPCODE_PUSH regpair=(REG_BC|REG_DE|REG_HL|REG_AF) # instrRegPair | opcode=OPCODE_RST expr=rExpression # instr8bitExpr | opcode=OPCODE_EXX # instrNoArgs - | opcode=OPCODE_JP SEP_LPAR regpairM=REG_HL SEP_RPAR # instrRegPair + | opcode=OPCODE_JP SEP_LPAR regpair=REG_HL SEP_RPAR # instrRefRegPair | opcode=OPCODE_DI # instrNoArgs | opcode=OPCODE_LD dst=REG_SP SEP_COMMA src=REG_HL # instrRegPairRegPair | opcode=OPCODE_EI # instrNoArgs @@ -109,8 +100,16 @@ rRegister: | SEP_LPAR r=REG_HL SEP_RPAR ; - - +cCondition: + COND_C + | COND_NC + | COND_Z + | COND_NZ + | COND_M + | COND_P + | COND_PE + | COND_PO + ; rPseudoCode: PREP_ORG expr=rExpression # pseudoOrg @@ -146,21 +145,22 @@ rDWdata: ; rExpression: - unaryop=(OP_ADD|OP_SUBTRACT|OP_NOT) expr=rExpression # exprUnary - | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD) expr2=rExpression # exprInfix - | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression # exprInfix - | expr1=rExpression op=(OP_SHL|OP_SHR) expr2=rExpression # exprInfix - | expr1=rExpression op=OP_AND expr2=rExpression # exprInfix - | expr1=rExpression op=OP_XOR expr2=rExpression # exprInfix - | expr1=rExpression op=OP_OR expr2=rExpression # exprInfix - | expr1=rExpression op=OP_EQUAL expr2=rExpression # exprInfix - | SEP_LPAR expr=rExpression SEP_RPAR # exprParens - | num=LIT_NUMBER # exprDec - | num=LIT_HEXNUMBER_1 # exprHex1 - | num=LIT_HEXNUMBER_2 # exprHex2 - | num=LIT_OCTNUMBER # exprOct - | num=LIT_BINNUMBER # exprBin - | PREP_ADDR # exprCurrentAddress - | id=ID_IDENTIFIER # exprId - | str=(LIT_STRING_1|LIT_STRING_2) # exprString + unaryop=(OP_ADD|OP_SUBTRACT|OP_NOT|OP_NOT_2) expr=rExpression # exprUnary + | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD|OP_MOD_2) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_SHL|OP_SHR|OP_SHR_2|OP_SHL_2) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_GT|OP_GTE|OP_LT|OP_LTE) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_AND|OP_AND_2) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_XOR|OP_XOR_2) expr2=rExpression # exprInfix + | expr1=rExpression op=(OP_OR|OP_OR_2) expr2=rExpression # exprInfix + | expr1=rExpression op=OP_EQUAL expr2=rExpression # exprInfix + | SEP_LPAR expr=rExpression SEP_RPAR # exprParens + | num=LIT_NUMBER # exprDec + | num=LIT_HEXNUMBER_1 # exprHex1 + | num=LIT_HEXNUMBER_2 # exprHex2 + | num=LIT_OCTNUMBER # exprOct + | num=LIT_BINNUMBER # exprBin + | PREP_ADDR # exprCurrentAddress + | id=ID_IDENTIFIER # exprId + | str=(LIT_STRING_1|LIT_STRING_2) # exprString ; diff --git a/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.interp b/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.interp new file mode 100644 index 000000000..1fa749f22 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.interp @@ -0,0 +1,499 @@ +token literal names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'$' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'(' +')' +',' +'+' +'-' +'*' +'/' +'=' +'>' +'>=' +'<' +'<=' +'%' +'>>' +'<<' +'!' +'&' +'|' +'~' +null +null + +token symbolic names: +null +COMMENT +COMMENT2 +OPCODE_ADC +OPCODE_ADD +OPCODE_AND +OPCODE_BIT +OPCODE_CALL +OPCODE_CCF +OPCODE_CP +OPCODE_CPD +OPCODE_CPDR +OPCODE_CPI +OPCODE_CPIR +OPCODE_CPL +OPCODE_DAA +OPCODE_DEC +OPCODE_DI +OPCODE_DJNZ +OPCODE_EI +OPCODE_EX +OPCODE_EXX +OPCODE_HALT +OPCODE_IM +OPCODE_IN +OPCODE_INC +OPCODE_IND +OPCODE_INDR +OPCODE_INI +OPCODE_INIR +OPCODE_JP +OPCODE_JR +OPCODE_LD +OPCODE_LDD +OPCODE_LDDR +OPCODE_LDI +OPCODE_LDIR +OPCODE_NEG +OPCODE_NOP +OPCODE_OR +OPCODE_OTDR +OPCODE_OTIR +OPCODE_OUT +OPCODE_OUTD +OPCODE_OUTI +OPCODE_POP +OPCODE_PUSH +OPCODE_RES +OPCODE_RET +OPCODE_RETI +OPCODE_RETN +OPCODE_RL +OPCODE_RLA +OPCODE_RLC +OPCODE_RLCA +OPCODE_RLD +OPCODE_RR +OPCODE_RRA +OPCODE_RRC +OPCODE_RRCA +OPCODE_RRD +OPCODE_RST +OPCODE_SBC +OPCODE_SCF +OPCODE_SET +OPCODE_SLA +OPCODE_SRA +OPCODE_SLL +OPCODE_SRL +OPCODE_SUB +OPCODE_XOR +COND_C +COND_NC +COND_Z +COND_NZ +COND_M +COND_P +COND_PE +COND_PO +COND_WS +COND_UNRECOGNIZED +PREP_ORG +PREP_EQU +PREP_SET +PREP_VAR +PREP_IF +PREP_ENDIF +PREP_INCLUDE +PREP_MACRO +PREP_ENDM +PREP_DB +PREP_DW +PREP_DS +PREP_ADDR +REG_A +REG_B +REG_C +REG_D +REG_E +REG_H +REG_L +REG_IX +REG_IXH +REG_IXL +REG_IY +REG_IYH +REG_IYL +REG_BC +REG_DE +REG_HL +REG_SP +REG_AF +REG_AFF +REG_I +REG_R +OP_MOD +OP_SHR +OP_SHL +OP_NOT +OP_AND +OP_OR +OP_XOR +LIT_HEXNUMBER_1 +LIT_NUMBER +LIT_HEXNUMBER_2 +LIT_OCTNUMBER +LIT_BINNUMBER +LIT_STRING_1 +LIT_STRING_2 +ID_IDENTIFIER +ID_LABEL +ERROR +SEP_LPAR +SEP_RPAR +SEP_COMMA +OP_ADD +OP_SUBTRACT +OP_MULTIPLY +OP_DIVIDE +OP_EQUAL +OP_GT +OP_GTE +OP_LT +OP_LTE +OP_MOD_2 +OP_SHR_2 +OP_SHL_2 +OP_NOT_2 +OP_AND_2 +OP_OR_2 +OP_XOR_2 +WS +EOL + +rule names: +COMMENT +COMMENT2 +A +B +C +D +E +F +G +H +I +J +L +M +N +O +P +Q +R +S +T +U +V +W +X +Y +Z +OPCODE_ADC +OPCODE_ADD +OPCODE_AND +OPCODE_BIT +OPCODE_CALL +OPCODE_CCF +OPCODE_CP +OPCODE_CPD +OPCODE_CPDR +OPCODE_CPI +OPCODE_CPIR +OPCODE_CPL +OPCODE_DAA +OPCODE_DEC +OPCODE_DI +OPCODE_DJNZ +OPCODE_EI +OPCODE_EX +OPCODE_EXX +OPCODE_HALT +OPCODE_IM +OPCODE_IN +OPCODE_INC +OPCODE_IND +OPCODE_INDR +OPCODE_INI +OPCODE_INIR +OPCODE_JP +OPCODE_JR +OPCODE_LD +OPCODE_LDD +OPCODE_LDDR +OPCODE_LDI +OPCODE_LDIR +OPCODE_NEG +OPCODE_NOP +OPCODE_OR +OPCODE_OTDR +OPCODE_OTIR +OPCODE_OUT +OPCODE_OUTD +OPCODE_OUTI +OPCODE_POP +OPCODE_PUSH +OPCODE_RES +OPCODE_RET +OPCODE_RETI +OPCODE_RETN +OPCODE_RL +OPCODE_RLA +OPCODE_RLC +OPCODE_RLCA +OPCODE_RLD +OPCODE_RR +OPCODE_RRA +OPCODE_RRC +OPCODE_RRCA +OPCODE_RRD +OPCODE_RST +OPCODE_SBC +OPCODE_SCF +OPCODE_SET +OPCODE_SLA +OPCODE_SRA +OPCODE_SLL +OPCODE_SRL +OPCODE_SUB +OPCODE_XOR +COND_C +COND_NC +COND_Z +COND_NZ +COND_M +COND_P +COND_PE +COND_PO +COND_WS +COND_UNRECOGNIZED +PREP_ORG +PREP_EQU +PREP_SET +PREP_VAR +PREP_IF +PREP_ENDIF +PREP_INCLUDE +PREP_MACRO +PREP_ENDM +PREP_DB +PREP_DW +PREP_DS +PREP_ADDR +REG_A +REG_B +REG_C +REG_D +REG_E +REG_H +REG_L +REG_IX +REG_IXH +REG_IXL +REG_IY +REG_IYH +REG_IYL +REG_BC +REG_DE +REG_HL +REG_SP +REG_AF +REG_AFF +REG_I +REG_R +OP_MOD +OP_SHR +OP_SHL +OP_NOT +OP_AND +OP_OR +OP_XOR +LIT_HEXNUMBER_1 +LIT_NUMBER +LIT_HEXNUMBER_2 +LIT_OCTNUMBER +LIT_BINNUMBER +LIT_STRING_1 +LIT_STRING_2 +ID_IDENTIFIER +ID_LABEL +ERROR +SEP_LPAR +SEP_RPAR +SEP_COMMA +OP_ADD +OP_SUBTRACT +OP_MULTIPLY +OP_DIVIDE +OP_EQUAL +OP_GT +OP_GTE +OP_LT +OP_LTE +OP_MOD_2 +OP_SHR_2 +OP_SHL_2 +OP_NOT_2 +OP_AND_2 +OP_OR_2 +OP_XOR_2 +WS +EOL + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE +CONDITION + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 154, 1035, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 4, 154, 9, 154, 4, 155, 9, 155, 4, 156, 9, 156, 4, 157, 9, 157, 4, 158, 9, 158, 4, 159, 9, 159, 4, 160, 9, 160, 4, 161, 9, 161, 4, 162, 9, 162, 4, 163, 9, 163, 4, 164, 9, 164, 4, 165, 9, 165, 4, 166, 9, 166, 4, 167, 9, 167, 4, 168, 9, 168, 4, 169, 9, 169, 4, 170, 9, 170, 4, 171, 9, 171, 4, 172, 9, 172, 4, 173, 9, 173, 4, 174, 9, 174, 4, 175, 9, 175, 4, 176, 9, 176, 4, 177, 9, 177, 4, 178, 9, 178, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 364, 10, 2, 3, 2, 7, 2, 367, 10, 2, 12, 2, 14, 2, 370, 11, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 378, 10, 3, 12, 3, 14, 3, 381, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 104, 3, 105, 6, 105, 761, 10, 105, 13, 105, 14, 105, 762, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 129, 3, 129, 3, 130, 3, 130, 3, 130, 3, 131, 3, 131, 3, 131, 3, 131, 3, 132, 3, 132, 3, 132, 3, 132, 3, 133, 3, 133, 3, 133, 3, 134, 3, 134, 3, 134, 3, 135, 3, 135, 3, 135, 3, 136, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 138, 3, 138, 3, 139, 3, 139, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 3, 144, 3, 144, 3, 144, 3, 145, 3, 145, 3, 145, 3, 145, 3, 146, 3, 146, 3, 146, 3, 147, 3, 147, 3, 147, 3, 147, 3, 148, 3, 148, 3, 148, 6, 148, 916, 10, 148, 13, 148, 14, 148, 917, 3, 149, 6, 149, 921, 10, 149, 13, 149, 14, 149, 922, 3, 149, 5, 149, 926, 10, 149, 3, 150, 6, 150, 929, 10, 150, 13, 150, 14, 150, 930, 3, 150, 3, 150, 3, 151, 6, 151, 936, 10, 151, 13, 151, 14, 151, 937, 3, 151, 3, 151, 3, 152, 6, 152, 943, 10, 152, 13, 152, 14, 152, 944, 3, 152, 3, 152, 3, 153, 3, 153, 7, 153, 951, 10, 153, 12, 153, 14, 153, 954, 11, 153, 3, 153, 3, 153, 3, 154, 3, 154, 7, 154, 960, 10, 154, 12, 154, 14, 154, 963, 11, 154, 3, 154, 3, 154, 3, 155, 3, 155, 7, 155, 969, 10, 155, 12, 155, 14, 155, 972, 11, 155, 3, 156, 3, 156, 3, 156, 3, 157, 6, 157, 978, 10, 157, 13, 157, 14, 157, 979, 3, 158, 3, 158, 3, 159, 3, 159, 3, 160, 3, 160, 3, 161, 3, 161, 3, 162, 3, 162, 3, 163, 3, 163, 3, 164, 3, 164, 3, 165, 3, 165, 3, 166, 3, 166, 3, 167, 3, 167, 3, 167, 3, 168, 3, 168, 3, 169, 3, 169, 3, 169, 3, 170, 3, 170, 3, 171, 3, 171, 3, 171, 3, 172, 3, 172, 3, 172, 3, 173, 3, 173, 3, 174, 3, 174, 3, 175, 3, 175, 3, 176, 3, 176, 3, 177, 6, 177, 1025, 10, 177, 13, 177, 14, 177, 1026, 3, 177, 3, 177, 3, 178, 5, 178, 1032, 10, 178, 3, 178, 3, 178, 3, 379, 2, 179, 4, 3, 6, 4, 8, 2, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54, 2, 56, 2, 58, 5, 60, 6, 62, 7, 64, 8, 66, 9, 68, 10, 70, 11, 72, 12, 74, 13, 76, 14, 78, 15, 80, 16, 82, 17, 84, 18, 86, 19, 88, 20, 90, 21, 92, 22, 94, 23, 96, 24, 98, 25, 100, 26, 102, 27, 104, 28, 106, 29, 108, 30, 110, 31, 112, 32, 114, 33, 116, 34, 118, 35, 120, 36, 122, 37, 124, 38, 126, 39, 128, 40, 130, 41, 132, 42, 134, 43, 136, 44, 138, 45, 140, 46, 142, 47, 144, 48, 146, 49, 148, 50, 150, 51, 152, 52, 154, 53, 156, 54, 158, 55, 160, 56, 162, 57, 164, 58, 166, 59, 168, 60, 170, 61, 172, 62, 174, 63, 176, 64, 178, 65, 180, 66, 182, 67, 184, 68, 186, 69, 188, 70, 190, 71, 192, 72, 194, 73, 196, 74, 198, 75, 200, 76, 202, 77, 204, 78, 206, 79, 208, 80, 210, 81, 212, 82, 214, 83, 216, 84, 218, 85, 220, 86, 222, 87, 224, 88, 226, 89, 228, 90, 230, 91, 232, 92, 234, 93, 236, 94, 238, 95, 240, 96, 242, 97, 244, 98, 246, 99, 248, 100, 250, 101, 252, 102, 254, 103, 256, 104, 258, 105, 260, 106, 262, 107, 264, 108, 266, 109, 268, 110, 270, 111, 272, 112, 274, 113, 276, 114, 278, 115, 280, 116, 282, 117, 284, 118, 286, 119, 288, 120, 290, 121, 292, 122, 294, 123, 296, 124, 298, 125, 300, 126, 302, 127, 304, 128, 306, 129, 308, 130, 310, 131, 312, 132, 314, 133, 316, 134, 318, 135, 320, 136, 322, 137, 324, 138, 326, 139, 328, 140, 330, 141, 332, 142, 334, 143, 336, 144, 338, 145, 340, 146, 342, 147, 344, 148, 346, 149, 348, 150, 350, 151, 352, 152, 354, 153, 356, 154, 4, 2, 3, 40, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 5, 2, 11, 11, 14, 14, 34, 34, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 59, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 3, 2, 36, 36, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 8, 2, 11, 12, 14, 15, 34, 34, 42, 47, 49, 49, 63, 63, 2, 1025, 2, 4, 3, 2, 2, 2, 2, 6, 3, 2, 2, 2, 2, 58, 3, 2, 2, 2, 2, 60, 3, 2, 2, 2, 2, 62, 3, 2, 2, 2, 2, 64, 3, 2, 2, 2, 2, 66, 3, 2, 2, 2, 2, 68, 3, 2, 2, 2, 2, 70, 3, 2, 2, 2, 2, 72, 3, 2, 2, 2, 2, 74, 3, 2, 2, 2, 2, 76, 3, 2, 2, 2, 2, 78, 3, 2, 2, 2, 2, 80, 3, 2, 2, 2, 2, 82, 3, 2, 2, 2, 2, 84, 3, 2, 2, 2, 2, 86, 3, 2, 2, 2, 2, 88, 3, 2, 2, 2, 2, 90, 3, 2, 2, 2, 2, 92, 3, 2, 2, 2, 2, 94, 3, 2, 2, 2, 2, 96, 3, 2, 2, 2, 2, 98, 3, 2, 2, 2, 2, 100, 3, 2, 2, 2, 2, 102, 3, 2, 2, 2, 2, 104, 3, 2, 2, 2, 2, 106, 3, 2, 2, 2, 2, 108, 3, 2, 2, 2, 2, 110, 3, 2, 2, 2, 2, 112, 3, 2, 2, 2, 2, 114, 3, 2, 2, 2, 2, 116, 3, 2, 2, 2, 2, 118, 3, 2, 2, 2, 2, 120, 3, 2, 2, 2, 2, 122, 3, 2, 2, 2, 2, 124, 3, 2, 2, 2, 2, 126, 3, 2, 2, 2, 2, 128, 3, 2, 2, 2, 2, 130, 3, 2, 2, 2, 2, 132, 3, 2, 2, 2, 2, 134, 3, 2, 2, 2, 2, 136, 3, 2, 2, 2, 2, 138, 3, 2, 2, 2, 2, 140, 3, 2, 2, 2, 2, 142, 3, 2, 2, 2, 2, 144, 3, 2, 2, 2, 2, 146, 3, 2, 2, 2, 2, 148, 3, 2, 2, 2, 2, 150, 3, 2, 2, 2, 2, 152, 3, 2, 2, 2, 2, 154, 3, 2, 2, 2, 2, 156, 3, 2, 2, 2, 2, 158, 3, 2, 2, 2, 2, 160, 3, 2, 2, 2, 2, 162, 3, 2, 2, 2, 2, 164, 3, 2, 2, 2, 2, 166, 3, 2, 2, 2, 2, 168, 3, 2, 2, 2, 2, 170, 3, 2, 2, 2, 2, 172, 3, 2, 2, 2, 2, 174, 3, 2, 2, 2, 2, 176, 3, 2, 2, 2, 2, 178, 3, 2, 2, 2, 2, 180, 3, 2, 2, 2, 2, 182, 3, 2, 2, 2, 2, 184, 3, 2, 2, 2, 2, 186, 3, 2, 2, 2, 2, 188, 3, 2, 2, 2, 2, 190, 3, 2, 2, 2, 2, 192, 3, 2, 2, 2, 2, 214, 3, 2, 2, 2, 2, 216, 3, 2, 2, 2, 2, 218, 3, 2, 2, 2, 2, 220, 3, 2, 2, 2, 2, 222, 3, 2, 2, 2, 2, 224, 3, 2, 2, 2, 2, 226, 3, 2, 2, 2, 2, 228, 3, 2, 2, 2, 2, 230, 3, 2, 2, 2, 2, 232, 3, 2, 2, 2, 2, 234, 3, 2, 2, 2, 2, 236, 3, 2, 2, 2, 2, 238, 3, 2, 2, 2, 2, 240, 3, 2, 2, 2, 2, 242, 3, 2, 2, 2, 2, 244, 3, 2, 2, 2, 2, 246, 3, 2, 2, 2, 2, 248, 3, 2, 2, 2, 2, 250, 3, 2, 2, 2, 2, 252, 3, 2, 2, 2, 2, 254, 3, 2, 2, 2, 2, 256, 3, 2, 2, 2, 2, 258, 3, 2, 2, 2, 2, 260, 3, 2, 2, 2, 2, 262, 3, 2, 2, 2, 2, 264, 3, 2, 2, 2, 2, 266, 3, 2, 2, 2, 2, 268, 3, 2, 2, 2, 2, 270, 3, 2, 2, 2, 2, 272, 3, 2, 2, 2, 2, 274, 3, 2, 2, 2, 2, 276, 3, 2, 2, 2, 2, 278, 3, 2, 2, 2, 2, 280, 3, 2, 2, 2, 2, 282, 3, 2, 2, 2, 2, 284, 3, 2, 2, 2, 2, 286, 3, 2, 2, 2, 2, 288, 3, 2, 2, 2, 2, 290, 3, 2, 2, 2, 2, 292, 3, 2, 2, 2, 2, 294, 3, 2, 2, 2, 2, 296, 3, 2, 2, 2, 2, 298, 3, 2, 2, 2, 2, 300, 3, 2, 2, 2, 2, 302, 3, 2, 2, 2, 2, 304, 3, 2, 2, 2, 2, 306, 3, 2, 2, 2, 2, 308, 3, 2, 2, 2, 2, 310, 3, 2, 2, 2, 2, 312, 3, 2, 2, 2, 2, 314, 3, 2, 2, 2, 2, 316, 3, 2, 2, 2, 2, 318, 3, 2, 2, 2, 2, 320, 3, 2, 2, 2, 2, 322, 3, 2, 2, 2, 2, 324, 3, 2, 2, 2, 2, 326, 3, 2, 2, 2, 2, 328, 3, 2, 2, 2, 2, 330, 3, 2, 2, 2, 2, 332, 3, 2, 2, 2, 2, 334, 3, 2, 2, 2, 2, 336, 3, 2, 2, 2, 2, 338, 3, 2, 2, 2, 2, 340, 3, 2, 2, 2, 2, 342, 3, 2, 2, 2, 2, 344, 3, 2, 2, 2, 2, 346, 3, 2, 2, 2, 2, 348, 3, 2, 2, 2, 2, 350, 3, 2, 2, 2, 2, 352, 3, 2, 2, 2, 2, 354, 3, 2, 2, 2, 2, 356, 3, 2, 2, 2, 3, 194, 3, 2, 2, 2, 3, 196, 3, 2, 2, 2, 3, 198, 3, 2, 2, 2, 3, 200, 3, 2, 2, 2, 3, 202, 3, 2, 2, 2, 3, 204, 3, 2, 2, 2, 3, 206, 3, 2, 2, 2, 3, 208, 3, 2, 2, 2, 3, 210, 3, 2, 2, 2, 3, 212, 3, 2, 2, 2, 4, 363, 3, 2, 2, 2, 6, 373, 3, 2, 2, 2, 8, 387, 3, 2, 2, 2, 10, 389, 3, 2, 2, 2, 12, 391, 3, 2, 2, 2, 14, 393, 3, 2, 2, 2, 16, 395, 3, 2, 2, 2, 18, 397, 3, 2, 2, 2, 20, 399, 3, 2, 2, 2, 22, 401, 3, 2, 2, 2, 24, 403, 3, 2, 2, 2, 26, 405, 3, 2, 2, 2, 28, 407, 3, 2, 2, 2, 30, 409, 3, 2, 2, 2, 32, 411, 3, 2, 2, 2, 34, 413, 3, 2, 2, 2, 36, 415, 3, 2, 2, 2, 38, 417, 3, 2, 2, 2, 40, 419, 3, 2, 2, 2, 42, 421, 3, 2, 2, 2, 44, 423, 3, 2, 2, 2, 46, 425, 3, 2, 2, 2, 48, 427, 3, 2, 2, 2, 50, 429, 3, 2, 2, 2, 52, 431, 3, 2, 2, 2, 54, 433, 3, 2, 2, 2, 56, 435, 3, 2, 2, 2, 58, 437, 3, 2, 2, 2, 60, 441, 3, 2, 2, 2, 62, 445, 3, 2, 2, 2, 64, 449, 3, 2, 2, 2, 66, 453, 3, 2, 2, 2, 68, 460, 3, 2, 2, 2, 70, 464, 3, 2, 2, 2, 72, 467, 3, 2, 2, 2, 74, 471, 3, 2, 2, 2, 76, 476, 3, 2, 2, 2, 78, 480, 3, 2, 2, 2, 80, 485, 3, 2, 2, 2, 82, 489, 3, 2, 2, 2, 84, 493, 3, 2, 2, 2, 86, 497, 3, 2, 2, 2, 88, 500, 3, 2, 2, 2, 90, 505, 3, 2, 2, 2, 92, 508, 3, 2, 2, 2, 94, 511, 3, 2, 2, 2, 96, 515, 3, 2, 2, 2, 98, 520, 3, 2, 2, 2, 100, 523, 3, 2, 2, 2, 102, 526, 3, 2, 2, 2, 104, 530, 3, 2, 2, 2, 106, 534, 3, 2, 2, 2, 108, 539, 3, 2, 2, 2, 110, 543, 3, 2, 2, 2, 112, 548, 3, 2, 2, 2, 114, 553, 3, 2, 2, 2, 116, 558, 3, 2, 2, 2, 118, 561, 3, 2, 2, 2, 120, 565, 3, 2, 2, 2, 122, 570, 3, 2, 2, 2, 124, 574, 3, 2, 2, 2, 126, 579, 3, 2, 2, 2, 128, 583, 3, 2, 2, 2, 130, 587, 3, 2, 2, 2, 132, 590, 3, 2, 2, 2, 134, 595, 3, 2, 2, 2, 136, 600, 3, 2, 2, 2, 138, 604, 3, 2, 2, 2, 140, 609, 3, 2, 2, 2, 142, 614, 3, 2, 2, 2, 144, 618, 3, 2, 2, 2, 146, 623, 3, 2, 2, 2, 148, 627, 3, 2, 2, 2, 150, 633, 3, 2, 2, 2, 152, 638, 3, 2, 2, 2, 154, 643, 3, 2, 2, 2, 156, 646, 3, 2, 2, 2, 158, 650, 3, 2, 2, 2, 160, 654, 3, 2, 2, 2, 162, 659, 3, 2, 2, 2, 164, 663, 3, 2, 2, 2, 166, 666, 3, 2, 2, 2, 168, 670, 3, 2, 2, 2, 170, 674, 3, 2, 2, 2, 172, 679, 3, 2, 2, 2, 174, 683, 3, 2, 2, 2, 176, 687, 3, 2, 2, 2, 178, 691, 3, 2, 2, 2, 180, 695, 3, 2, 2, 2, 182, 699, 3, 2, 2, 2, 184, 703, 3, 2, 2, 2, 186, 707, 3, 2, 2, 2, 188, 711, 3, 2, 2, 2, 190, 715, 3, 2, 2, 2, 192, 719, 3, 2, 2, 2, 194, 723, 3, 2, 2, 2, 196, 727, 3, 2, 2, 2, 198, 732, 3, 2, 2, 2, 200, 736, 3, 2, 2, 2, 202, 741, 3, 2, 2, 2, 204, 745, 3, 2, 2, 2, 206, 749, 3, 2, 2, 2, 208, 754, 3, 2, 2, 2, 210, 760, 3, 2, 2, 2, 212, 766, 3, 2, 2, 2, 214, 771, 3, 2, 2, 2, 216, 775, 3, 2, 2, 2, 218, 779, 3, 2, 2, 2, 220, 783, 3, 2, 2, 2, 222, 787, 3, 2, 2, 2, 224, 790, 3, 2, 2, 2, 226, 796, 3, 2, 2, 2, 228, 804, 3, 2, 2, 2, 230, 810, 3, 2, 2, 2, 232, 815, 3, 2, 2, 2, 234, 818, 3, 2, 2, 2, 236, 821, 3, 2, 2, 2, 238, 824, 3, 2, 2, 2, 240, 826, 3, 2, 2, 2, 242, 828, 3, 2, 2, 2, 244, 830, 3, 2, 2, 2, 246, 832, 3, 2, 2, 2, 248, 834, 3, 2, 2, 2, 250, 836, 3, 2, 2, 2, 252, 838, 3, 2, 2, 2, 254, 840, 3, 2, 2, 2, 256, 843, 3, 2, 2, 2, 258, 847, 3, 2, 2, 2, 260, 851, 3, 2, 2, 2, 262, 854, 3, 2, 2, 2, 264, 858, 3, 2, 2, 2, 266, 862, 3, 2, 2, 2, 268, 865, 3, 2, 2, 2, 270, 868, 3, 2, 2, 2, 272, 871, 3, 2, 2, 2, 274, 874, 3, 2, 2, 2, 276, 877, 3, 2, 2, 2, 278, 881, 3, 2, 2, 2, 280, 883, 3, 2, 2, 2, 282, 885, 3, 2, 2, 2, 284, 889, 3, 2, 2, 2, 286, 893, 3, 2, 2, 2, 288, 897, 3, 2, 2, 2, 290, 901, 3, 2, 2, 2, 292, 905, 3, 2, 2, 2, 294, 908, 3, 2, 2, 2, 296, 912, 3, 2, 2, 2, 298, 920, 3, 2, 2, 2, 300, 928, 3, 2, 2, 2, 302, 935, 3, 2, 2, 2, 304, 942, 3, 2, 2, 2, 306, 948, 3, 2, 2, 2, 308, 957, 3, 2, 2, 2, 310, 966, 3, 2, 2, 2, 312, 973, 3, 2, 2, 2, 314, 977, 3, 2, 2, 2, 316, 981, 3, 2, 2, 2, 318, 983, 3, 2, 2, 2, 320, 985, 3, 2, 2, 2, 322, 987, 3, 2, 2, 2, 324, 989, 3, 2, 2, 2, 326, 991, 3, 2, 2, 2, 328, 993, 3, 2, 2, 2, 330, 995, 3, 2, 2, 2, 332, 997, 3, 2, 2, 2, 334, 999, 3, 2, 2, 2, 336, 1002, 3, 2, 2, 2, 338, 1004, 3, 2, 2, 2, 340, 1007, 3, 2, 2, 2, 342, 1009, 3, 2, 2, 2, 344, 1012, 3, 2, 2, 2, 346, 1015, 3, 2, 2, 2, 348, 1017, 3, 2, 2, 2, 350, 1019, 3, 2, 2, 2, 352, 1021, 3, 2, 2, 2, 354, 1024, 3, 2, 2, 2, 356, 1031, 3, 2, 2, 2, 358, 359, 7, 49, 2, 2, 359, 364, 7, 49, 2, 2, 360, 361, 7, 47, 2, 2, 361, 364, 7, 47, 2, 2, 362, 364, 9, 2, 2, 2, 363, 358, 3, 2, 2, 2, 363, 360, 3, 2, 2, 2, 363, 362, 3, 2, 2, 2, 364, 368, 3, 2, 2, 2, 365, 367, 10, 3, 2, 2, 366, 365, 3, 2, 2, 2, 367, 370, 3, 2, 2, 2, 368, 366, 3, 2, 2, 2, 368, 369, 3, 2, 2, 2, 369, 371, 3, 2, 2, 2, 370, 368, 3, 2, 2, 2, 371, 372, 8, 2, 2, 2, 372, 5, 3, 2, 2, 2, 373, 374, 7, 49, 2, 2, 374, 375, 7, 44, 2, 2, 375, 379, 3, 2, 2, 2, 376, 378, 11, 2, 2, 2, 377, 376, 3, 2, 2, 2, 378, 381, 3, 2, 2, 2, 379, 380, 3, 2, 2, 2, 379, 377, 3, 2, 2, 2, 380, 382, 3, 2, 2, 2, 381, 379, 3, 2, 2, 2, 382, 383, 7, 44, 2, 2, 383, 384, 7, 49, 2, 2, 384, 385, 3, 2, 2, 2, 385, 386, 8, 3, 2, 2, 386, 7, 3, 2, 2, 2, 387, 388, 9, 4, 2, 2, 388, 9, 3, 2, 2, 2, 389, 390, 9, 5, 2, 2, 390, 11, 3, 2, 2, 2, 391, 392, 9, 6, 2, 2, 392, 13, 3, 2, 2, 2, 393, 394, 9, 7, 2, 2, 394, 15, 3, 2, 2, 2, 395, 396, 9, 8, 2, 2, 396, 17, 3, 2, 2, 2, 397, 398, 9, 9, 2, 2, 398, 19, 3, 2, 2, 2, 399, 400, 9, 10, 2, 2, 400, 21, 3, 2, 2, 2, 401, 402, 9, 11, 2, 2, 402, 23, 3, 2, 2, 2, 403, 404, 9, 12, 2, 2, 404, 25, 3, 2, 2, 2, 405, 406, 9, 13, 2, 2, 406, 27, 3, 2, 2, 2, 407, 408, 9, 14, 2, 2, 408, 29, 3, 2, 2, 2, 409, 410, 9, 15, 2, 2, 410, 31, 3, 2, 2, 2, 411, 412, 9, 16, 2, 2, 412, 33, 3, 2, 2, 2, 413, 414, 9, 17, 2, 2, 414, 35, 3, 2, 2, 2, 415, 416, 9, 18, 2, 2, 416, 37, 3, 2, 2, 2, 417, 418, 9, 19, 2, 2, 418, 39, 3, 2, 2, 2, 419, 420, 9, 20, 2, 2, 420, 41, 3, 2, 2, 2, 421, 422, 9, 21, 2, 2, 422, 43, 3, 2, 2, 2, 423, 424, 9, 22, 2, 2, 424, 45, 3, 2, 2, 2, 425, 426, 9, 23, 2, 2, 426, 47, 3, 2, 2, 2, 427, 428, 9, 24, 2, 2, 428, 49, 3, 2, 2, 2, 429, 430, 9, 25, 2, 2, 430, 51, 3, 2, 2, 2, 431, 432, 9, 26, 2, 2, 432, 53, 3, 2, 2, 2, 433, 434, 9, 27, 2, 2, 434, 55, 3, 2, 2, 2, 435, 436, 9, 28, 2, 2, 436, 57, 3, 2, 2, 2, 437, 438, 5, 8, 4, 2, 438, 439, 5, 14, 7, 2, 439, 440, 5, 12, 6, 2, 440, 59, 3, 2, 2, 2, 441, 442, 5, 8, 4, 2, 442, 443, 5, 14, 7, 2, 443, 444, 5, 14, 7, 2, 444, 61, 3, 2, 2, 2, 445, 446, 5, 8, 4, 2, 446, 447, 5, 32, 16, 2, 447, 448, 5, 14, 7, 2, 448, 63, 3, 2, 2, 2, 449, 450, 5, 10, 5, 2, 450, 451, 5, 24, 12, 2, 451, 452, 5, 44, 22, 2, 452, 65, 3, 2, 2, 2, 453, 454, 5, 12, 6, 2, 454, 455, 5, 8, 4, 2, 455, 456, 5, 28, 14, 2, 456, 457, 5, 28, 14, 2, 457, 458, 3, 2, 2, 2, 458, 459, 8, 33, 3, 2, 459, 67, 3, 2, 2, 2, 460, 461, 5, 12, 6, 2, 461, 462, 5, 12, 6, 2, 462, 463, 5, 18, 9, 2, 463, 69, 3, 2, 2, 2, 464, 465, 5, 12, 6, 2, 465, 466, 5, 36, 18, 2, 466, 71, 3, 2, 2, 2, 467, 468, 5, 12, 6, 2, 468, 469, 5, 36, 18, 2, 469, 470, 5, 14, 7, 2, 470, 73, 3, 2, 2, 2, 471, 472, 5, 12, 6, 2, 472, 473, 5, 36, 18, 2, 473, 474, 5, 14, 7, 2, 474, 475, 5, 40, 20, 2, 475, 75, 3, 2, 2, 2, 476, 477, 5, 12, 6, 2, 477, 478, 5, 36, 18, 2, 478, 479, 5, 24, 12, 2, 479, 77, 3, 2, 2, 2, 480, 481, 5, 12, 6, 2, 481, 482, 5, 36, 18, 2, 482, 483, 5, 24, 12, 2, 483, 484, 5, 40, 20, 2, 484, 79, 3, 2, 2, 2, 485, 486, 5, 12, 6, 2, 486, 487, 5, 36, 18, 2, 487, 488, 5, 28, 14, 2, 488, 81, 3, 2, 2, 2, 489, 490, 5, 14, 7, 2, 490, 491, 5, 8, 4, 2, 491, 492, 5, 8, 4, 2, 492, 83, 3, 2, 2, 2, 493, 494, 5, 14, 7, 2, 494, 495, 5, 16, 8, 2, 495, 496, 5, 12, 6, 2, 496, 85, 3, 2, 2, 2, 497, 498, 5, 14, 7, 2, 498, 499, 5, 24, 12, 2, 499, 87, 3, 2, 2, 2, 500, 501, 5, 14, 7, 2, 501, 502, 5, 26, 13, 2, 502, 503, 5, 32, 16, 2, 503, 504, 5, 56, 28, 2, 504, 89, 3, 2, 2, 2, 505, 506, 5, 16, 8, 2, 506, 507, 5, 24, 12, 2, 507, 91, 3, 2, 2, 2, 508, 509, 5, 16, 8, 2, 509, 510, 5, 52, 26, 2, 510, 93, 3, 2, 2, 2, 511, 512, 5, 16, 8, 2, 512, 513, 5, 52, 26, 2, 513, 514, 5, 52, 26, 2, 514, 95, 3, 2, 2, 2, 515, 516, 5, 22, 11, 2, 516, 517, 5, 8, 4, 2, 517, 518, 5, 28, 14, 2, 518, 519, 5, 44, 22, 2, 519, 97, 3, 2, 2, 2, 520, 521, 5, 24, 12, 2, 521, 522, 5, 30, 15, 2, 522, 99, 3, 2, 2, 2, 523, 524, 5, 24, 12, 2, 524, 525, 5, 32, 16, 2, 525, 101, 3, 2, 2, 2, 526, 527, 5, 24, 12, 2, 527, 528, 5, 32, 16, 2, 528, 529, 5, 12, 6, 2, 529, 103, 3, 2, 2, 2, 530, 531, 5, 24, 12, 2, 531, 532, 5, 32, 16, 2, 532, 533, 5, 14, 7, 2, 533, 105, 3, 2, 2, 2, 534, 535, 5, 24, 12, 2, 535, 536, 5, 32, 16, 2, 536, 537, 5, 14, 7, 2, 537, 538, 5, 40, 20, 2, 538, 107, 3, 2, 2, 2, 539, 540, 5, 24, 12, 2, 540, 541, 5, 32, 16, 2, 541, 542, 5, 24, 12, 2, 542, 109, 3, 2, 2, 2, 543, 544, 5, 24, 12, 2, 544, 545, 5, 32, 16, 2, 545, 546, 5, 24, 12, 2, 546, 547, 5, 40, 20, 2, 547, 111, 3, 2, 2, 2, 548, 549, 5, 26, 13, 2, 549, 550, 5, 36, 18, 2, 550, 551, 3, 2, 2, 2, 551, 552, 8, 56, 3, 2, 552, 113, 3, 2, 2, 2, 553, 554, 5, 26, 13, 2, 554, 555, 5, 40, 20, 2, 555, 556, 3, 2, 2, 2, 556, 557, 8, 57, 3, 2, 557, 115, 3, 2, 2, 2, 558, 559, 5, 28, 14, 2, 559, 560, 5, 14, 7, 2, 560, 117, 3, 2, 2, 2, 561, 562, 5, 28, 14, 2, 562, 563, 5, 14, 7, 2, 563, 564, 5, 14, 7, 2, 564, 119, 3, 2, 2, 2, 565, 566, 5, 28, 14, 2, 566, 567, 5, 14, 7, 2, 567, 568, 5, 14, 7, 2, 568, 569, 5, 40, 20, 2, 569, 121, 3, 2, 2, 2, 570, 571, 5, 28, 14, 2, 571, 572, 5, 14, 7, 2, 572, 573, 5, 24, 12, 2, 573, 123, 3, 2, 2, 2, 574, 575, 5, 28, 14, 2, 575, 576, 5, 14, 7, 2, 576, 577, 5, 24, 12, 2, 577, 578, 5, 40, 20, 2, 578, 125, 3, 2, 2, 2, 579, 580, 5, 32, 16, 2, 580, 581, 5, 16, 8, 2, 581, 582, 5, 20, 10, 2, 582, 127, 3, 2, 2, 2, 583, 584, 5, 32, 16, 2, 584, 585, 5, 34, 17, 2, 585, 586, 5, 36, 18, 2, 586, 129, 3, 2, 2, 2, 587, 588, 5, 34, 17, 2, 588, 589, 5, 40, 20, 2, 589, 131, 3, 2, 2, 2, 590, 591, 5, 34, 17, 2, 591, 592, 5, 44, 22, 2, 592, 593, 5, 14, 7, 2, 593, 594, 5, 40, 20, 2, 594, 133, 3, 2, 2, 2, 595, 596, 5, 34, 17, 2, 596, 597, 5, 44, 22, 2, 597, 598, 5, 24, 12, 2, 598, 599, 5, 40, 20, 2, 599, 135, 3, 2, 2, 2, 600, 601, 5, 34, 17, 2, 601, 602, 5, 46, 23, 2, 602, 603, 5, 44, 22, 2, 603, 137, 3, 2, 2, 2, 604, 605, 5, 34, 17, 2, 605, 606, 5, 46, 23, 2, 606, 607, 5, 44, 22, 2, 607, 608, 5, 14, 7, 2, 608, 139, 3, 2, 2, 2, 609, 610, 5, 34, 17, 2, 610, 611, 5, 46, 23, 2, 611, 612, 5, 44, 22, 2, 612, 613, 5, 24, 12, 2, 613, 141, 3, 2, 2, 2, 614, 615, 5, 36, 18, 2, 615, 616, 5, 34, 17, 2, 616, 617, 5, 36, 18, 2, 617, 143, 3, 2, 2, 2, 618, 619, 5, 36, 18, 2, 619, 620, 5, 46, 23, 2, 620, 621, 5, 42, 21, 2, 621, 622, 5, 22, 11, 2, 622, 145, 3, 2, 2, 2, 623, 624, 5, 40, 20, 2, 624, 625, 5, 16, 8, 2, 625, 626, 5, 42, 21, 2, 626, 147, 3, 2, 2, 2, 627, 628, 5, 40, 20, 2, 628, 629, 5, 16, 8, 2, 629, 630, 5, 44, 22, 2, 630, 631, 3, 2, 2, 2, 631, 632, 8, 74, 3, 2, 632, 149, 3, 2, 2, 2, 633, 634, 5, 40, 20, 2, 634, 635, 5, 16, 8, 2, 635, 636, 5, 44, 22, 2, 636, 637, 5, 24, 12, 2, 637, 151, 3, 2, 2, 2, 638, 639, 5, 40, 20, 2, 639, 640, 5, 16, 8, 2, 640, 641, 5, 44, 22, 2, 641, 642, 5, 32, 16, 2, 642, 153, 3, 2, 2, 2, 643, 644, 5, 40, 20, 2, 644, 645, 5, 28, 14, 2, 645, 155, 3, 2, 2, 2, 646, 647, 5, 40, 20, 2, 647, 648, 5, 28, 14, 2, 648, 649, 5, 8, 4, 2, 649, 157, 3, 2, 2, 2, 650, 651, 5, 40, 20, 2, 651, 652, 5, 28, 14, 2, 652, 653, 5, 12, 6, 2, 653, 159, 3, 2, 2, 2, 654, 655, 5, 40, 20, 2, 655, 656, 5, 28, 14, 2, 656, 657, 5, 12, 6, 2, 657, 658, 5, 8, 4, 2, 658, 161, 3, 2, 2, 2, 659, 660, 5, 40, 20, 2, 660, 661, 5, 28, 14, 2, 661, 662, 5, 14, 7, 2, 662, 163, 3, 2, 2, 2, 663, 664, 5, 40, 20, 2, 664, 665, 5, 40, 20, 2, 665, 165, 3, 2, 2, 2, 666, 667, 5, 40, 20, 2, 667, 668, 5, 40, 20, 2, 668, 669, 5, 8, 4, 2, 669, 167, 3, 2, 2, 2, 670, 671, 5, 40, 20, 2, 671, 672, 5, 40, 20, 2, 672, 673, 5, 12, 6, 2, 673, 169, 3, 2, 2, 2, 674, 675, 5, 40, 20, 2, 675, 676, 5, 40, 20, 2, 676, 677, 5, 12, 6, 2, 677, 678, 5, 8, 4, 2, 678, 171, 3, 2, 2, 2, 679, 680, 5, 40, 20, 2, 680, 681, 5, 40, 20, 2, 681, 682, 5, 14, 7, 2, 682, 173, 3, 2, 2, 2, 683, 684, 5, 40, 20, 2, 684, 685, 5, 42, 21, 2, 685, 686, 5, 44, 22, 2, 686, 175, 3, 2, 2, 2, 687, 688, 5, 42, 21, 2, 688, 689, 5, 10, 5, 2, 689, 690, 5, 12, 6, 2, 690, 177, 3, 2, 2, 2, 691, 692, 5, 42, 21, 2, 692, 693, 5, 12, 6, 2, 693, 694, 5, 18, 9, 2, 694, 179, 3, 2, 2, 2, 695, 696, 5, 42, 21, 2, 696, 697, 5, 16, 8, 2, 697, 698, 5, 44, 22, 2, 698, 181, 3, 2, 2, 2, 699, 700, 5, 42, 21, 2, 700, 701, 5, 28, 14, 2, 701, 702, 5, 8, 4, 2, 702, 183, 3, 2, 2, 2, 703, 704, 5, 42, 21, 2, 704, 705, 5, 40, 20, 2, 705, 706, 5, 8, 4, 2, 706, 185, 3, 2, 2, 2, 707, 708, 5, 42, 21, 2, 708, 709, 5, 28, 14, 2, 709, 710, 5, 28, 14, 2, 710, 187, 3, 2, 2, 2, 711, 712, 5, 42, 21, 2, 712, 713, 5, 40, 20, 2, 713, 714, 5, 28, 14, 2, 714, 189, 3, 2, 2, 2, 715, 716, 5, 42, 21, 2, 716, 717, 5, 46, 23, 2, 717, 718, 5, 10, 5, 2, 718, 191, 3, 2, 2, 2, 719, 720, 5, 52, 26, 2, 720, 721, 5, 34, 17, 2, 721, 722, 5, 40, 20, 2, 722, 193, 3, 2, 2, 2, 723, 724, 5, 12, 6, 2, 724, 725, 3, 2, 2, 2, 725, 726, 8, 97, 4, 2, 726, 195, 3, 2, 2, 2, 727, 728, 5, 32, 16, 2, 728, 729, 5, 12, 6, 2, 729, 730, 3, 2, 2, 2, 730, 731, 8, 98, 4, 2, 731, 197, 3, 2, 2, 2, 732, 733, 5, 56, 28, 2, 733, 734, 3, 2, 2, 2, 734, 735, 8, 99, 4, 2, 735, 199, 3, 2, 2, 2, 736, 737, 5, 32, 16, 2, 737, 738, 5, 56, 28, 2, 738, 739, 3, 2, 2, 2, 739, 740, 8, 100, 4, 2, 740, 201, 3, 2, 2, 2, 741, 742, 5, 30, 15, 2, 742, 743, 3, 2, 2, 2, 743, 744, 8, 101, 4, 2, 744, 203, 3, 2, 2, 2, 745, 746, 5, 36, 18, 2, 746, 747, 3, 2, 2, 2, 747, 748, 8, 102, 4, 2, 748, 205, 3, 2, 2, 2, 749, 750, 5, 36, 18, 2, 750, 751, 5, 16, 8, 2, 751, 752, 3, 2, 2, 2, 752, 753, 8, 103, 4, 2, 753, 207, 3, 2, 2, 2, 754, 755, 5, 36, 18, 2, 755, 756, 5, 34, 17, 2, 756, 757, 3, 2, 2, 2, 757, 758, 8, 104, 4, 2, 758, 209, 3, 2, 2, 2, 759, 761, 9, 29, 2, 2, 760, 759, 3, 2, 2, 2, 761, 762, 3, 2, 2, 2, 762, 760, 3, 2, 2, 2, 762, 763, 3, 2, 2, 2, 763, 764, 3, 2, 2, 2, 764, 765, 8, 105, 2, 2, 765, 211, 3, 2, 2, 2, 766, 767, 6, 106, 2, 2, 767, 768, 3, 2, 2, 2, 768, 769, 8, 106, 4, 2, 769, 770, 8, 106, 5, 2, 770, 213, 3, 2, 2, 2, 771, 772, 5, 34, 17, 2, 772, 773, 5, 40, 20, 2, 773, 774, 5, 20, 10, 2, 774, 215, 3, 2, 2, 2, 775, 776, 5, 16, 8, 2, 776, 777, 5, 38, 19, 2, 777, 778, 5, 46, 23, 2, 778, 217, 3, 2, 2, 2, 779, 780, 5, 42, 21, 2, 780, 781, 5, 16, 8, 2, 781, 782, 5, 44, 22, 2, 782, 219, 3, 2, 2, 2, 783, 784, 5, 48, 24, 2, 784, 785, 5, 8, 4, 2, 785, 786, 5, 40, 20, 2, 786, 221, 3, 2, 2, 2, 787, 788, 5, 24, 12, 2, 788, 789, 5, 18, 9, 2, 789, 223, 3, 2, 2, 2, 790, 791, 5, 16, 8, 2, 791, 792, 5, 32, 16, 2, 792, 793, 5, 14, 7, 2, 793, 794, 5, 24, 12, 2, 794, 795, 5, 18, 9, 2, 795, 225, 3, 2, 2, 2, 796, 797, 5, 24, 12, 2, 797, 798, 5, 32, 16, 2, 798, 799, 5, 12, 6, 2, 799, 800, 5, 28, 14, 2, 800, 801, 5, 46, 23, 2, 801, 802, 5, 14, 7, 2, 802, 803, 5, 16, 8, 2, 803, 227, 3, 2, 2, 2, 804, 805, 5, 30, 15, 2, 805, 806, 5, 8, 4, 2, 806, 807, 5, 12, 6, 2, 807, 808, 5, 40, 20, 2, 808, 809, 5, 34, 17, 2, 809, 229, 3, 2, 2, 2, 810, 811, 5, 16, 8, 2, 811, 812, 5, 32, 16, 2, 812, 813, 5, 14, 7, 2, 813, 814, 5, 30, 15, 2, 814, 231, 3, 2, 2, 2, 815, 816, 5, 14, 7, 2, 816, 817, 5, 10, 5, 2, 817, 233, 3, 2, 2, 2, 818, 819, 5, 14, 7, 2, 819, 820, 5, 50, 25, 2, 820, 235, 3, 2, 2, 2, 821, 822, 5, 14, 7, 2, 822, 823, 5, 42, 21, 2, 823, 237, 3, 2, 2, 2, 824, 825, 7, 38, 2, 2, 825, 239, 3, 2, 2, 2, 826, 827, 5, 8, 4, 2, 827, 241, 3, 2, 2, 2, 828, 829, 5, 10, 5, 2, 829, 243, 3, 2, 2, 2, 830, 831, 5, 12, 6, 2, 831, 245, 3, 2, 2, 2, 832, 833, 5, 14, 7, 2, 833, 247, 3, 2, 2, 2, 834, 835, 5, 16, 8, 2, 835, 249, 3, 2, 2, 2, 836, 837, 5, 22, 11, 2, 837, 251, 3, 2, 2, 2, 838, 839, 5, 28, 14, 2, 839, 253, 3, 2, 2, 2, 840, 841, 5, 24, 12, 2, 841, 842, 5, 52, 26, 2, 842, 255, 3, 2, 2, 2, 843, 844, 5, 24, 12, 2, 844, 845, 5, 52, 26, 2, 845, 846, 5, 22, 11, 2, 846, 257, 3, 2, 2, 2, 847, 848, 5, 24, 12, 2, 848, 849, 5, 52, 26, 2, 849, 850, 5, 28, 14, 2, 850, 259, 3, 2, 2, 2, 851, 852, 5, 24, 12, 2, 852, 853, 5, 54, 27, 2, 853, 261, 3, 2, 2, 2, 854, 855, 5, 24, 12, 2, 855, 856, 5, 54, 27, 2, 856, 857, 5, 22, 11, 2, 857, 263, 3, 2, 2, 2, 858, 859, 5, 24, 12, 2, 859, 860, 5, 54, 27, 2, 860, 861, 5, 28, 14, 2, 861, 265, 3, 2, 2, 2, 862, 863, 5, 10, 5, 2, 863, 864, 5, 12, 6, 2, 864, 267, 3, 2, 2, 2, 865, 866, 5, 14, 7, 2, 866, 867, 5, 16, 8, 2, 867, 269, 3, 2, 2, 2, 868, 869, 5, 22, 11, 2, 869, 870, 5, 28, 14, 2, 870, 271, 3, 2, 2, 2, 871, 872, 5, 42, 21, 2, 872, 873, 5, 36, 18, 2, 873, 273, 3, 2, 2, 2, 874, 875, 5, 8, 4, 2, 875, 876, 5, 18, 9, 2, 876, 275, 3, 2, 2, 2, 877, 878, 5, 8, 4, 2, 878, 879, 5, 18, 9, 2, 879, 880, 7, 41, 2, 2, 880, 277, 3, 2, 2, 2, 881, 882, 5, 24, 12, 2, 882, 279, 3, 2, 2, 2, 883, 884, 5, 40, 20, 2, 884, 281, 3, 2, 2, 2, 885, 886, 5, 30, 15, 2, 886, 887, 5, 34, 17, 2, 887, 888, 5, 14, 7, 2, 888, 283, 3, 2, 2, 2, 889, 890, 5, 42, 21, 2, 890, 891, 5, 22, 11, 2, 891, 892, 5, 40, 20, 2, 892, 285, 3, 2, 2, 2, 893, 894, 5, 42, 21, 2, 894, 895, 5, 22, 11, 2, 895, 896, 5, 28, 14, 2, 896, 287, 3, 2, 2, 2, 897, 898, 5, 32, 16, 2, 898, 899, 5, 34, 17, 2, 899, 900, 5, 44, 22, 2, 900, 289, 3, 2, 2, 2, 901, 902, 5, 8, 4, 2, 902, 903, 5, 32, 16, 2, 903, 904, 5, 14, 7, 2, 904, 291, 3, 2, 2, 2, 905, 906, 5, 34, 17, 2, 906, 907, 5, 40, 20, 2, 907, 293, 3, 2, 2, 2, 908, 909, 5, 52, 26, 2, 909, 910, 5, 34, 17, 2, 910, 911, 5, 40, 20, 2, 911, 295, 3, 2, 2, 2, 912, 913, 7, 50, 2, 2, 913, 915, 5, 52, 26, 2, 914, 916, 9, 30, 2, 2, 915, 914, 3, 2, 2, 2, 916, 917, 3, 2, 2, 2, 917, 915, 3, 2, 2, 2, 917, 918, 3, 2, 2, 2, 918, 297, 3, 2, 2, 2, 919, 921, 9, 31, 2, 2, 920, 919, 3, 2, 2, 2, 921, 922, 3, 2, 2, 2, 922, 920, 3, 2, 2, 2, 922, 923, 3, 2, 2, 2, 923, 925, 3, 2, 2, 2, 924, 926, 5, 14, 7, 2, 925, 924, 3, 2, 2, 2, 925, 926, 3, 2, 2, 2, 926, 299, 3, 2, 2, 2, 927, 929, 9, 30, 2, 2, 928, 927, 3, 2, 2, 2, 929, 930, 3, 2, 2, 2, 930, 928, 3, 2, 2, 2, 930, 931, 3, 2, 2, 2, 931, 932, 3, 2, 2, 2, 932, 933, 5, 22, 11, 2, 933, 301, 3, 2, 2, 2, 934, 936, 9, 32, 2, 2, 935, 934, 3, 2, 2, 2, 936, 937, 3, 2, 2, 2, 937, 935, 3, 2, 2, 2, 937, 938, 3, 2, 2, 2, 938, 939, 3, 2, 2, 2, 939, 940, 9, 33, 2, 2, 940, 303, 3, 2, 2, 2, 941, 943, 9, 34, 2, 2, 942, 941, 3, 2, 2, 2, 943, 944, 3, 2, 2, 2, 944, 942, 3, 2, 2, 2, 944, 945, 3, 2, 2, 2, 945, 946, 3, 2, 2, 2, 946, 947, 5, 10, 5, 2, 947, 305, 3, 2, 2, 2, 948, 952, 7, 41, 2, 2, 949, 951, 10, 35, 2, 2, 950, 949, 3, 2, 2, 2, 951, 954, 3, 2, 2, 2, 952, 950, 3, 2, 2, 2, 952, 953, 3, 2, 2, 2, 953, 955, 3, 2, 2, 2, 954, 952, 3, 2, 2, 2, 955, 956, 7, 41, 2, 2, 956, 307, 3, 2, 2, 2, 957, 961, 7, 36, 2, 2, 958, 960, 10, 36, 2, 2, 959, 958, 3, 2, 2, 2, 960, 963, 3, 2, 2, 2, 961, 959, 3, 2, 2, 2, 961, 962, 3, 2, 2, 2, 962, 964, 3, 2, 2, 2, 963, 961, 3, 2, 2, 2, 964, 965, 7, 36, 2, 2, 965, 309, 3, 2, 2, 2, 966, 970, 9, 37, 2, 2, 967, 969, 9, 38, 2, 2, 968, 967, 3, 2, 2, 2, 969, 972, 3, 2, 2, 2, 970, 968, 3, 2, 2, 2, 970, 971, 3, 2, 2, 2, 971, 311, 3, 2, 2, 2, 972, 970, 3, 2, 2, 2, 973, 974, 5, 310, 155, 2, 974, 975, 7, 60, 2, 2, 975, 313, 3, 2, 2, 2, 976, 978, 10, 39, 2, 2, 977, 976, 3, 2, 2, 2, 978, 979, 3, 2, 2, 2, 979, 977, 3, 2, 2, 2, 979, 980, 3, 2, 2, 2, 980, 315, 3, 2, 2, 2, 981, 982, 7, 42, 2, 2, 982, 317, 3, 2, 2, 2, 983, 984, 7, 43, 2, 2, 984, 319, 3, 2, 2, 2, 985, 986, 7, 46, 2, 2, 986, 321, 3, 2, 2, 2, 987, 988, 7, 45, 2, 2, 988, 323, 3, 2, 2, 2, 989, 990, 7, 47, 2, 2, 990, 325, 3, 2, 2, 2, 991, 992, 7, 44, 2, 2, 992, 327, 3, 2, 2, 2, 993, 994, 7, 49, 2, 2, 994, 329, 3, 2, 2, 2, 995, 996, 7, 63, 2, 2, 996, 331, 3, 2, 2, 2, 997, 998, 7, 64, 2, 2, 998, 333, 3, 2, 2, 2, 999, 1000, 7, 64, 2, 2, 1000, 1001, 7, 63, 2, 2, 1001, 335, 3, 2, 2, 2, 1002, 1003, 7, 62, 2, 2, 1003, 337, 3, 2, 2, 2, 1004, 1005, 7, 62, 2, 2, 1005, 1006, 7, 63, 2, 2, 1006, 339, 3, 2, 2, 2, 1007, 1008, 7, 39, 2, 2, 1008, 341, 3, 2, 2, 2, 1009, 1010, 7, 64, 2, 2, 1010, 1011, 7, 64, 2, 2, 1011, 343, 3, 2, 2, 2, 1012, 1013, 7, 62, 2, 2, 1013, 1014, 7, 62, 2, 2, 1014, 345, 3, 2, 2, 2, 1015, 1016, 7, 35, 2, 2, 1016, 347, 3, 2, 2, 2, 1017, 1018, 7, 40, 2, 2, 1018, 349, 3, 2, 2, 2, 1019, 1020, 7, 126, 2, 2, 1020, 351, 3, 2, 2, 2, 1021, 1022, 7, 128, 2, 2, 1022, 353, 3, 2, 2, 2, 1023, 1025, 9, 29, 2, 2, 1024, 1023, 3, 2, 2, 2, 1025, 1026, 3, 2, 2, 2, 1026, 1024, 3, 2, 2, 2, 1026, 1027, 3, 2, 2, 2, 1027, 1028, 3, 2, 2, 2, 1028, 1029, 8, 177, 2, 2, 1029, 355, 3, 2, 2, 2, 1030, 1032, 7, 15, 2, 2, 1031, 1030, 3, 2, 2, 2, 1031, 1032, 3, 2, 2, 2, 1032, 1033, 3, 2, 2, 2, 1033, 1034, 7, 12, 2, 2, 1034, 357, 3, 2, 2, 2, 20, 2, 3, 363, 368, 379, 762, 917, 922, 925, 930, 937, 944, 952, 961, 970, 979, 1026, 1031, 6, 8, 2, 2, 7, 3, 2, 6, 2, 2, 2, 3, 2] \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.java b/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.java new file mode 100644 index 000000000..a118ca5bf --- /dev/null +++ b/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.java @@ -0,0 +1,597 @@ +// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 by ANTLR 4.9.2 +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class AsZ80Lexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.9.2", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + COMMENT=1, COMMENT2=2, OPCODE_ADC=3, OPCODE_ADD=4, OPCODE_AND=5, OPCODE_BIT=6, + OPCODE_CALL=7, OPCODE_CCF=8, OPCODE_CP=9, OPCODE_CPD=10, OPCODE_CPDR=11, + OPCODE_CPI=12, OPCODE_CPIR=13, OPCODE_CPL=14, OPCODE_DAA=15, OPCODE_DEC=16, + OPCODE_DI=17, OPCODE_DJNZ=18, OPCODE_EI=19, OPCODE_EX=20, OPCODE_EXX=21, + OPCODE_HALT=22, OPCODE_IM=23, OPCODE_IN=24, OPCODE_INC=25, OPCODE_IND=26, + OPCODE_INDR=27, OPCODE_INI=28, OPCODE_INIR=29, OPCODE_JP=30, OPCODE_JR=31, + OPCODE_LD=32, OPCODE_LDD=33, OPCODE_LDDR=34, OPCODE_LDI=35, OPCODE_LDIR=36, + OPCODE_NEG=37, OPCODE_NOP=38, OPCODE_OR=39, OPCODE_OTDR=40, OPCODE_OTIR=41, + OPCODE_OUT=42, OPCODE_OUTD=43, OPCODE_OUTI=44, OPCODE_POP=45, OPCODE_PUSH=46, + OPCODE_RES=47, OPCODE_RET=48, OPCODE_RETI=49, OPCODE_RETN=50, OPCODE_RL=51, + OPCODE_RLA=52, OPCODE_RLC=53, OPCODE_RLCA=54, OPCODE_RLD=55, OPCODE_RR=56, + OPCODE_RRA=57, OPCODE_RRC=58, OPCODE_RRCA=59, OPCODE_RRD=60, OPCODE_RST=61, + OPCODE_SBC=62, OPCODE_SCF=63, OPCODE_SET=64, OPCODE_SLA=65, OPCODE_SRA=66, + OPCODE_SLL=67, OPCODE_SRL=68, OPCODE_SUB=69, OPCODE_XOR=70, COND_C=71, + COND_NC=72, COND_Z=73, COND_NZ=74, COND_M=75, COND_P=76, COND_PE=77, COND_PO=78, + COND_WS=79, COND_UNRECOGNIZED=80, PREP_ORG=81, PREP_EQU=82, PREP_SET=83, + PREP_VAR=84, PREP_IF=85, PREP_ENDIF=86, PREP_INCLUDE=87, PREP_MACRO=88, + PREP_ENDM=89, PREP_DB=90, PREP_DW=91, PREP_DS=92, PREP_ADDR=93, REG_A=94, + REG_B=95, REG_C=96, REG_D=97, REG_E=98, REG_H=99, REG_L=100, REG_IX=101, + REG_IXH=102, REG_IXL=103, REG_IY=104, REG_IYH=105, REG_IYL=106, REG_BC=107, + REG_DE=108, REG_HL=109, REG_SP=110, REG_AF=111, REG_AFF=112, REG_I=113, + REG_R=114, OP_MOD=115, OP_SHR=116, OP_SHL=117, OP_NOT=118, OP_AND=119, + OP_OR=120, OP_XOR=121, LIT_HEXNUMBER_1=122, LIT_NUMBER=123, LIT_HEXNUMBER_2=124, + LIT_OCTNUMBER=125, LIT_BINNUMBER=126, LIT_STRING_1=127, LIT_STRING_2=128, + ID_IDENTIFIER=129, ID_LABEL=130, ERROR=131, SEP_LPAR=132, SEP_RPAR=133, + SEP_COMMA=134, OP_ADD=135, OP_SUBTRACT=136, OP_MULTIPLY=137, OP_DIVIDE=138, + OP_EQUAL=139, OP_GT=140, OP_GTE=141, OP_LT=142, OP_LTE=143, OP_MOD_2=144, + OP_SHR_2=145, OP_SHL_2=146, OP_NOT_2=147, OP_AND_2=148, OP_OR_2=149, OP_XOR_2=150, + WS=151, EOL=152; + public static final int + CONDITION=1; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE", "CONDITION" + }; + + private static String[] makeRuleNames() { + return new String[] { + "COMMENT", "COMMENT2", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", + "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", + "Z", "OPCODE_ADC", "OPCODE_ADD", "OPCODE_AND", "OPCODE_BIT", "OPCODE_CALL", + "OPCODE_CCF", "OPCODE_CP", "OPCODE_CPD", "OPCODE_CPDR", "OPCODE_CPI", + "OPCODE_CPIR", "OPCODE_CPL", "OPCODE_DAA", "OPCODE_DEC", "OPCODE_DI", + "OPCODE_DJNZ", "OPCODE_EI", "OPCODE_EX", "OPCODE_EXX", "OPCODE_HALT", + "OPCODE_IM", "OPCODE_IN", "OPCODE_INC", "OPCODE_IND", "OPCODE_INDR", + "OPCODE_INI", "OPCODE_INIR", "OPCODE_JP", "OPCODE_JR", "OPCODE_LD", "OPCODE_LDD", + "OPCODE_LDDR", "OPCODE_LDI", "OPCODE_LDIR", "OPCODE_NEG", "OPCODE_NOP", + "OPCODE_OR", "OPCODE_OTDR", "OPCODE_OTIR", "OPCODE_OUT", "OPCODE_OUTD", + "OPCODE_OUTI", "OPCODE_POP", "OPCODE_PUSH", "OPCODE_RES", "OPCODE_RET", + "OPCODE_RETI", "OPCODE_RETN", "OPCODE_RL", "OPCODE_RLA", "OPCODE_RLC", + "OPCODE_RLCA", "OPCODE_RLD", "OPCODE_RR", "OPCODE_RRA", "OPCODE_RRC", + "OPCODE_RRCA", "OPCODE_RRD", "OPCODE_RST", "OPCODE_SBC", "OPCODE_SCF", + "OPCODE_SET", "OPCODE_SLA", "OPCODE_SRA", "OPCODE_SLL", "OPCODE_SRL", + "OPCODE_SUB", "OPCODE_XOR", "COND_C", "COND_NC", "COND_Z", "COND_NZ", + "COND_M", "COND_P", "COND_PE", "COND_PO", "COND_WS", "COND_UNRECOGNIZED", + "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_VAR", "PREP_IF", "PREP_ENDIF", + "PREP_INCLUDE", "PREP_MACRO", "PREP_ENDM", "PREP_DB", "PREP_DW", "PREP_DS", + "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", "REG_E", "REG_H", "REG_L", + "REG_IX", "REG_IXH", "REG_IXL", "REG_IY", "REG_IYH", "REG_IYL", "REG_BC", + "REG_DE", "REG_HL", "REG_SP", "REG_AF", "REG_AFF", "REG_I", "REG_R", + "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", "OP_XOR", + "LIT_HEXNUMBER_1", "LIT_NUMBER", "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", + "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", + "ERROR", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", + "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_GT", "OP_GTE", "OP_LT", "OP_LTE", + "OP_MOD_2", "OP_SHR_2", "OP_SHL_2", "OP_NOT_2", "OP_AND_2", "OP_OR_2", + "OP_XOR_2", "WS", "EOL" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, "'$'", null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + "'('", "')'", "','", "'+'", "'-'", "'*'", "'/'", "'='", "'>'", "'>='", + "'<'", "'<='", "'%'", "'>>'", "'<<'", "'!'", "'&'", "'|'", "'~'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "COMMENT", "COMMENT2", "OPCODE_ADC", "OPCODE_ADD", "OPCODE_AND", + "OPCODE_BIT", "OPCODE_CALL", "OPCODE_CCF", "OPCODE_CP", "OPCODE_CPD", + "OPCODE_CPDR", "OPCODE_CPI", "OPCODE_CPIR", "OPCODE_CPL", "OPCODE_DAA", + "OPCODE_DEC", "OPCODE_DI", "OPCODE_DJNZ", "OPCODE_EI", "OPCODE_EX", "OPCODE_EXX", + "OPCODE_HALT", "OPCODE_IM", "OPCODE_IN", "OPCODE_INC", "OPCODE_IND", + "OPCODE_INDR", "OPCODE_INI", "OPCODE_INIR", "OPCODE_JP", "OPCODE_JR", + "OPCODE_LD", "OPCODE_LDD", "OPCODE_LDDR", "OPCODE_LDI", "OPCODE_LDIR", + "OPCODE_NEG", "OPCODE_NOP", "OPCODE_OR", "OPCODE_OTDR", "OPCODE_OTIR", + "OPCODE_OUT", "OPCODE_OUTD", "OPCODE_OUTI", "OPCODE_POP", "OPCODE_PUSH", + "OPCODE_RES", "OPCODE_RET", "OPCODE_RETI", "OPCODE_RETN", "OPCODE_RL", + "OPCODE_RLA", "OPCODE_RLC", "OPCODE_RLCA", "OPCODE_RLD", "OPCODE_RR", + "OPCODE_RRA", "OPCODE_RRC", "OPCODE_RRCA", "OPCODE_RRD", "OPCODE_RST", + "OPCODE_SBC", "OPCODE_SCF", "OPCODE_SET", "OPCODE_SLA", "OPCODE_SRA", + "OPCODE_SLL", "OPCODE_SRL", "OPCODE_SUB", "OPCODE_XOR", "COND_C", "COND_NC", + "COND_Z", "COND_NZ", "COND_M", "COND_P", "COND_PE", "COND_PO", "COND_WS", + "COND_UNRECOGNIZED", "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_VAR", + "PREP_IF", "PREP_ENDIF", "PREP_INCLUDE", "PREP_MACRO", "PREP_ENDM", "PREP_DB", + "PREP_DW", "PREP_DS", "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", + "REG_E", "REG_H", "REG_L", "REG_IX", "REG_IXH", "REG_IXL", "REG_IY", + "REG_IYH", "REG_IYL", "REG_BC", "REG_DE", "REG_HL", "REG_SP", "REG_AF", + "REG_AFF", "REG_I", "REG_R", "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", + "OP_AND", "OP_OR", "OP_XOR", "LIT_HEXNUMBER_1", "LIT_NUMBER", "LIT_HEXNUMBER_2", + "LIT_OCTNUMBER", "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", + "ID_LABEL", "ERROR", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", + "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_GT", "OP_GTE", "OP_LT", "OP_LTE", + "OP_MOD_2", "OP_SHR_2", "OP_SHL_2", "OP_NOT_2", "OP_AND_2", "OP_OR_2", + "OP_XOR_2", "WS", "EOL" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public AsZ80Lexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "AsZ80Lexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + @Override + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 104: + return COND_UNRECOGNIZED_sempred((RuleContext)_localctx, predIndex); + } + return true; + } + private boolean COND_UNRECOGNIZED_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return true; + } + return true; + } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u009a\u040b\b\1\b"+ + "\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n"+ + "\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21"+ + "\4\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30"+ + "\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37"+ + "\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t"+ + "*\4+\t+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63"+ + "\4\64\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t"+ + "<\4=\t=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4"+ + "H\tH\4I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\t"+ + "S\4T\tT\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^"+ + "\4_\t_\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j"+ + "\tj\4k\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu"+ + "\4v\tv\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080"+ + "\t\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084"+ + "\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089"+ + "\t\u0089\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c\t\u008c\4\u008d\t\u008d"+ + "\4\u008e\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090\4\u0091\t\u0091\4\u0092"+ + "\t\u0092\4\u0093\t\u0093\4\u0094\t\u0094\4\u0095\t\u0095\4\u0096\t\u0096"+ + "\4\u0097\t\u0097\4\u0098\t\u0098\4\u0099\t\u0099\4\u009a\t\u009a\4\u009b"+ + "\t\u009b\4\u009c\t\u009c\4\u009d\t\u009d\4\u009e\t\u009e\4\u009f\t\u009f"+ + "\4\u00a0\t\u00a0\4\u00a1\t\u00a1\4\u00a2\t\u00a2\4\u00a3\t\u00a3\4\u00a4"+ + "\t\u00a4\4\u00a5\t\u00a5\4\u00a6\t\u00a6\4\u00a7\t\u00a7\4\u00a8\t\u00a8"+ + "\4\u00a9\t\u00a9\4\u00aa\t\u00aa\4\u00ab\t\u00ab\4\u00ac\t\u00ac\4\u00ad"+ + "\t\u00ad\4\u00ae\t\u00ae\4\u00af\t\u00af\4\u00b0\t\u00b0\4\u00b1\t\u00b1"+ + "\4\u00b2\t\u00b2\3\2\3\2\3\2\3\2\3\2\5\2\u016c\n\2\3\2\7\2\u016f\n\2\f"+ + "\2\16\2\u0172\13\2\3\2\3\2\3\3\3\3\3\3\3\3\7\3\u017a\n\3\f\3\16\3\u017d"+ + "\13\3\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t"+ + "\3\t\3\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3"+ + "\21\3\21\3\22\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3"+ + "\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\35\3\35\3"+ + "\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3!\3!\3!\3"+ + "!\3\"\3\"\3\"\3\"\3#\3#\3#\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3\'"+ + "\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3+\3,\3,\3"+ + ",\3,\3,\3-\3-\3-\3.\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\3\61\3"+ + "\61\3\61\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\65\3"+ + "\65\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\3\67\38\38"+ + "\38\38\38\39\39\39\39\39\3:\3:\3:\3;\3;\3;\3;\3<\3<\3<\3<\3<\3=\3=\3="+ + "\3=\3>\3>\3>\3>\3>\3?\3?\3?\3?\3@\3@\3@\3@\3A\3A\3A\3B\3B\3B\3B\3B\3C"+ + "\3C\3C\3C\3C\3D\3D\3D\3D\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3G\3G\3G\3G\3H"+ + "\3H\3H\3H\3H\3I\3I\3I\3I\3J\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3L\3L\3L\3L"+ + "\3L\3M\3M\3M\3N\3N\3N\3N\3O\3O\3O\3O\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3R\3R"+ + "\3R\3S\3S\3S\3S\3T\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3V\3V\3W\3W\3W\3W\3X"+ + "\3X\3X\3X\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3]\3]\3"+ + "]\3]\3^\3^\3^\3^\3_\3_\3_\3_\3`\3`\3`\3`\3a\3a\3a\3a\3b\3b\3b\3b\3b\3"+ + "c\3c\3c\3c\3d\3d\3d\3d\3d\3e\3e\3e\3e\3f\3f\3f\3f\3g\3g\3g\3g\3g\3h\3"+ + "h\3h\3h\3h\3i\6i\u02f9\ni\ri\16i\u02fa\3i\3i\3j\3j\3j\3j\3j\3k\3k\3k\3"+ + "k\3l\3l\3l\3l\3m\3m\3m\3m\3n\3n\3n\3n\3o\3o\3o\3p\3p\3p\3p\3p\3p\3q\3"+ + "q\3q\3q\3q\3q\3q\3q\3r\3r\3r\3r\3r\3r\3s\3s\3s\3s\3s\3t\3t\3t\3u\3u\3"+ + "u\3v\3v\3v\3w\3w\3x\3x\3y\3y\3z\3z\3{\3{\3|\3|\3}\3}\3~\3~\3\177\3\177"+ + "\3\177\3\u0080\3\u0080\3\u0080\3\u0080\3\u0081\3\u0081\3\u0081\3\u0081"+ + "\3\u0082\3\u0082\3\u0082\3\u0083\3\u0083\3\u0083\3\u0083\3\u0084\3\u0084"+ + "\3\u0084\3\u0084\3\u0085\3\u0085\3\u0085\3\u0086\3\u0086\3\u0086\3\u0087"+ + "\3\u0087\3\u0087\3\u0088\3\u0088\3\u0088\3\u0089\3\u0089\3\u0089\3\u008a"+ + "\3\u008a\3\u008a\3\u008a\3\u008b\3\u008b\3\u008c\3\u008c\3\u008d\3\u008d"+ + "\3\u008d\3\u008d\3\u008e\3\u008e\3\u008e\3\u008e\3\u008f\3\u008f\3\u008f"+ + "\3\u008f\3\u0090\3\u0090\3\u0090\3\u0090\3\u0091\3\u0091\3\u0091\3\u0091"+ + "\3\u0092\3\u0092\3\u0092\3\u0093\3\u0093\3\u0093\3\u0093\3\u0094\3\u0094"+ + "\3\u0094\6\u0094\u0394\n\u0094\r\u0094\16\u0094\u0395\3\u0095\6\u0095"+ + "\u0399\n\u0095\r\u0095\16\u0095\u039a\3\u0095\5\u0095\u039e\n\u0095\3"+ + "\u0096\6\u0096\u03a1\n\u0096\r\u0096\16\u0096\u03a2\3\u0096\3\u0096\3"+ + "\u0097\6\u0097\u03a8\n\u0097\r\u0097\16\u0097\u03a9\3\u0097\3\u0097\3"+ + "\u0098\6\u0098\u03af\n\u0098\r\u0098\16\u0098\u03b0\3\u0098\3\u0098\3"+ + "\u0099\3\u0099\7\u0099\u03b7\n\u0099\f\u0099\16\u0099\u03ba\13\u0099\3"+ + "\u0099\3\u0099\3\u009a\3\u009a\7\u009a\u03c0\n\u009a\f\u009a\16\u009a"+ + "\u03c3\13\u009a\3\u009a\3\u009a\3\u009b\3\u009b\7\u009b\u03c9\n\u009b"+ + "\f\u009b\16\u009b\u03cc\13\u009b\3\u009c\3\u009c\3\u009c\3\u009d\6\u009d"+ + "\u03d2\n\u009d\r\u009d\16\u009d\u03d3\3\u009e\3\u009e\3\u009f\3\u009f"+ + "\3\u00a0\3\u00a0\3\u00a1\3\u00a1\3\u00a2\3\u00a2\3\u00a3\3\u00a3\3\u00a4"+ + "\3\u00a4\3\u00a5\3\u00a5\3\u00a6\3\u00a6\3\u00a7\3\u00a7\3\u00a7\3\u00a8"+ + "\3\u00a8\3\u00a9\3\u00a9\3\u00a9\3\u00aa\3\u00aa\3\u00ab\3\u00ab\3\u00ab"+ + "\3\u00ac\3\u00ac\3\u00ac\3\u00ad\3\u00ad\3\u00ae\3\u00ae\3\u00af\3\u00af"+ + "\3\u00b0\3\u00b0\3\u00b1\6\u00b1\u0401\n\u00b1\r\u00b1\16\u00b1\u0402"+ + "\3\u00b1\3\u00b1\3\u00b2\5\u00b2\u0408\n\u00b2\3\u00b2\3\u00b2\3\u017b"+ + "\2\u00b3\4\3\6\4\b\2\n\2\f\2\16\2\20\2\22\2\24\2\26\2\30\2\32\2\34\2\36"+ + "\2 \2\"\2$\2&\2(\2*\2,\2.\2\60\2\62\2\64\2\66\28\2:\5<\6>\7@\bB\tD\nF"+ + "\13H\fJ\rL\16N\17P\20R\21T\22V\23X\24Z\25\\\26^\27`\30b\31d\32f\33h\34"+ + "j\35l\36n\37p r!t\"v#x$z%|&~\'\u0080(\u0082)\u0084*\u0086+\u0088,\u008a"+ + "-\u008c.\u008e/\u0090\60\u0092\61\u0094\62\u0096\63\u0098\64\u009a\65"+ + "\u009c\66\u009e\67\u00a08\u00a29\u00a4:\u00a6;\u00a8<\u00aa=\u00ac>\u00ae"+ + "?\u00b0@\u00b2A\u00b4B\u00b6C\u00b8D\u00baE\u00bcF\u00beG\u00c0H\u00c2"+ + "I\u00c4J\u00c6K\u00c8L\u00caM\u00ccN\u00ceO\u00d0P\u00d2Q\u00d4R\u00d6"+ + "S\u00d8T\u00daU\u00dcV\u00deW\u00e0X\u00e2Y\u00e4Z\u00e6[\u00e8\\\u00ea"+ + "]\u00ec^\u00ee_\u00f0`\u00f2a\u00f4b\u00f6c\u00f8d\u00fae\u00fcf\u00fe"+ + "g\u0100h\u0102i\u0104j\u0106k\u0108l\u010am\u010cn\u010eo\u0110p\u0112"+ + "q\u0114r\u0116s\u0118t\u011au\u011cv\u011ew\u0120x\u0122y\u0124z\u0126"+ + "{\u0128|\u012a}\u012c~\u012e\177\u0130\u0080\u0132\u0081\u0134\u0082\u0136"+ + "\u0083\u0138\u0084\u013a\u0085\u013c\u0086\u013e\u0087\u0140\u0088\u0142"+ + "\u0089\u0144\u008a\u0146\u008b\u0148\u008c\u014a\u008d\u014c\u008e\u014e"+ + "\u008f\u0150\u0090\u0152\u0091\u0154\u0092\u0156\u0093\u0158\u0094\u015a"+ + "\u0095\u015c\u0096\u015e\u0097\u0160\u0098\u0162\u0099\u0164\u009a\4\2"+ + "\3(\4\2%%==\4\2\f\f\17\17\4\2CCcc\4\2DDdd\4\2EEee\4\2FFff\4\2GGgg\4\2"+ + "HHhh\4\2IIii\4\2JJjj\4\2KKkk\4\2LLll\4\2NNnn\4\2OOoo\4\2PPpp\4\2QQqq\4"+ + "\2RRrr\4\2SSss\4\2TTtt\4\2UUuu\4\2VVvv\4\2WWww\4\2XXxx\4\2YYyy\4\2ZZz"+ + "z\4\2[[{{\4\2\\\\||\5\2\13\13\16\16\"\"\5\2\62;CHch\3\2\62;\3\2\629\6"+ + "\2QQSSqqss\3\2\62\63\3\2))\3\2$$\5\2A\\aac|\6\2\62;A\\aac|\b\2\13\f\16"+ + "\17\"\"*/\61\61??\2\u0401\2\4\3\2\2\2\2\6\3\2\2\2\2:\3\2\2\2\2<\3\2\2"+ + "\2\2>\3\2\2\2\2@\3\2\2\2\2B\3\2\2\2\2D\3\2\2\2\2F\3\2\2\2\2H\3\2\2\2\2"+ + "J\3\2\2\2\2L\3\2\2\2\2N\3\2\2\2\2P\3\2\2\2\2R\3\2\2\2\2T\3\2\2\2\2V\3"+ + "\2\2\2\2X\3\2\2\2\2Z\3\2\2\2\2\\\3\2\2\2\2^\3\2\2\2\2`\3\2\2\2\2b\3\2"+ + "\2\2\2d\3\2\2\2\2f\3\2\2\2\2h\3\2\2\2\2j\3\2\2\2\2l\3\2\2\2\2n\3\2\2\2"+ + "\2p\3\2\2\2\2r\3\2\2\2\2t\3\2\2\2\2v\3\2\2\2\2x\3\2\2\2\2z\3\2\2\2\2|"+ + "\3\2\2\2\2~\3\2\2\2\2\u0080\3\2\2\2\2\u0082\3\2\2\2\2\u0084\3\2\2\2\2"+ + "\u0086\3\2\2\2\2\u0088\3\2\2\2\2\u008a\3\2\2\2\2\u008c\3\2\2\2\2\u008e"+ + "\3\2\2\2\2\u0090\3\2\2\2\2\u0092\3\2\2\2\2\u0094\3\2\2\2\2\u0096\3\2\2"+ + "\2\2\u0098\3\2\2\2\2\u009a\3\2\2\2\2\u009c\3\2\2\2\2\u009e\3\2\2\2\2\u00a0"+ + "\3\2\2\2\2\u00a2\3\2\2\2\2\u00a4\3\2\2\2\2\u00a6\3\2\2\2\2\u00a8\3\2\2"+ + "\2\2\u00aa\3\2\2\2\2\u00ac\3\2\2\2\2\u00ae\3\2\2\2\2\u00b0\3\2\2\2\2\u00b2"+ + "\3\2\2\2\2\u00b4\3\2\2\2\2\u00b6\3\2\2\2\2\u00b8\3\2\2\2\2\u00ba\3\2\2"+ + "\2\2\u00bc\3\2\2\2\2\u00be\3\2\2\2\2\u00c0\3\2\2\2\2\u00d6\3\2\2\2\2\u00d8"+ + "\3\2\2\2\2\u00da\3\2\2\2\2\u00dc\3\2\2\2\2\u00de\3\2\2\2\2\u00e0\3\2\2"+ + "\2\2\u00e2\3\2\2\2\2\u00e4\3\2\2\2\2\u00e6\3\2\2\2\2\u00e8\3\2\2\2\2\u00ea"+ + "\3\2\2\2\2\u00ec\3\2\2\2\2\u00ee\3\2\2\2\2\u00f0\3\2\2\2\2\u00f2\3\2\2"+ + "\2\2\u00f4\3\2\2\2\2\u00f6\3\2\2\2\2\u00f8\3\2\2\2\2\u00fa\3\2\2\2\2\u00fc"+ + "\3\2\2\2\2\u00fe\3\2\2\2\2\u0100\3\2\2\2\2\u0102\3\2\2\2\2\u0104\3\2\2"+ + "\2\2\u0106\3\2\2\2\2\u0108\3\2\2\2\2\u010a\3\2\2\2\2\u010c\3\2\2\2\2\u010e"+ + "\3\2\2\2\2\u0110\3\2\2\2\2\u0112\3\2\2\2\2\u0114\3\2\2\2\2\u0116\3\2\2"+ + "\2\2\u0118\3\2\2\2\2\u011a\3\2\2\2\2\u011c\3\2\2\2\2\u011e\3\2\2\2\2\u0120"+ + "\3\2\2\2\2\u0122\3\2\2\2\2\u0124\3\2\2\2\2\u0126\3\2\2\2\2\u0128\3\2\2"+ + "\2\2\u012a\3\2\2\2\2\u012c\3\2\2\2\2\u012e\3\2\2\2\2\u0130\3\2\2\2\2\u0132"+ + "\3\2\2\2\2\u0134\3\2\2\2\2\u0136\3\2\2\2\2\u0138\3\2\2\2\2\u013a\3\2\2"+ + "\2\2\u013c\3\2\2\2\2\u013e\3\2\2\2\2\u0140\3\2\2\2\2\u0142\3\2\2\2\2\u0144"+ + "\3\2\2\2\2\u0146\3\2\2\2\2\u0148\3\2\2\2\2\u014a\3\2\2\2\2\u014c\3\2\2"+ + "\2\2\u014e\3\2\2\2\2\u0150\3\2\2\2\2\u0152\3\2\2\2\2\u0154\3\2\2\2\2\u0156"+ + "\3\2\2\2\2\u0158\3\2\2\2\2\u015a\3\2\2\2\2\u015c\3\2\2\2\2\u015e\3\2\2"+ + "\2\2\u0160\3\2\2\2\2\u0162\3\2\2\2\2\u0164\3\2\2\2\3\u00c2\3\2\2\2\3\u00c4"+ + "\3\2\2\2\3\u00c6\3\2\2\2\3\u00c8\3\2\2\2\3\u00ca\3\2\2\2\3\u00cc\3\2\2"+ + "\2\3\u00ce\3\2\2\2\3\u00d0\3\2\2\2\3\u00d2\3\2\2\2\3\u00d4\3\2\2\2\4\u016b"+ + "\3\2\2\2\6\u0175\3\2\2\2\b\u0183\3\2\2\2\n\u0185\3\2\2\2\f\u0187\3\2\2"+ + "\2\16\u0189\3\2\2\2\20\u018b\3\2\2\2\22\u018d\3\2\2\2\24\u018f\3\2\2\2"+ + "\26\u0191\3\2\2\2\30\u0193\3\2\2\2\32\u0195\3\2\2\2\34\u0197\3\2\2\2\36"+ + "\u0199\3\2\2\2 \u019b\3\2\2\2\"\u019d\3\2\2\2$\u019f\3\2\2\2&\u01a1\3"+ + "\2\2\2(\u01a3\3\2\2\2*\u01a5\3\2\2\2,\u01a7\3\2\2\2.\u01a9\3\2\2\2\60"+ + "\u01ab\3\2\2\2\62\u01ad\3\2\2\2\64\u01af\3\2\2\2\66\u01b1\3\2\2\28\u01b3"+ + "\3\2\2\2:\u01b5\3\2\2\2<\u01b9\3\2\2\2>\u01bd\3\2\2\2@\u01c1\3\2\2\2B"+ + "\u01c5\3\2\2\2D\u01cc\3\2\2\2F\u01d0\3\2\2\2H\u01d3\3\2\2\2J\u01d7\3\2"+ + "\2\2L\u01dc\3\2\2\2N\u01e0\3\2\2\2P\u01e5\3\2\2\2R\u01e9\3\2\2\2T\u01ed"+ + "\3\2\2\2V\u01f1\3\2\2\2X\u01f4\3\2\2\2Z\u01f9\3\2\2\2\\\u01fc\3\2\2\2"+ + "^\u01ff\3\2\2\2`\u0203\3\2\2\2b\u0208\3\2\2\2d\u020b\3\2\2\2f\u020e\3"+ + "\2\2\2h\u0212\3\2\2\2j\u0216\3\2\2\2l\u021b\3\2\2\2n\u021f\3\2\2\2p\u0224"+ + "\3\2\2\2r\u0229\3\2\2\2t\u022e\3\2\2\2v\u0231\3\2\2\2x\u0235\3\2\2\2z"+ + "\u023a\3\2\2\2|\u023e\3\2\2\2~\u0243\3\2\2\2\u0080\u0247\3\2\2\2\u0082"+ + "\u024b\3\2\2\2\u0084\u024e\3\2\2\2\u0086\u0253\3\2\2\2\u0088\u0258\3\2"+ + "\2\2\u008a\u025c\3\2\2\2\u008c\u0261\3\2\2\2\u008e\u0266\3\2\2\2\u0090"+ + "\u026a\3\2\2\2\u0092\u026f\3\2\2\2\u0094\u0273\3\2\2\2\u0096\u0279\3\2"+ + "\2\2\u0098\u027e\3\2\2\2\u009a\u0283\3\2\2\2\u009c\u0286\3\2\2\2\u009e"+ + "\u028a\3\2\2\2\u00a0\u028e\3\2\2\2\u00a2\u0293\3\2\2\2\u00a4\u0297\3\2"+ + "\2\2\u00a6\u029a\3\2\2\2\u00a8\u029e\3\2\2\2\u00aa\u02a2\3\2\2\2\u00ac"+ + "\u02a7\3\2\2\2\u00ae\u02ab\3\2\2\2\u00b0\u02af\3\2\2\2\u00b2\u02b3\3\2"+ + "\2\2\u00b4\u02b7\3\2\2\2\u00b6\u02bb\3\2\2\2\u00b8\u02bf\3\2\2\2\u00ba"+ + "\u02c3\3\2\2\2\u00bc\u02c7\3\2\2\2\u00be\u02cb\3\2\2\2\u00c0\u02cf\3\2"+ + "\2\2\u00c2\u02d3\3\2\2\2\u00c4\u02d7\3\2\2\2\u00c6\u02dc\3\2\2\2\u00c8"+ + "\u02e0\3\2\2\2\u00ca\u02e5\3\2\2\2\u00cc\u02e9\3\2\2\2\u00ce\u02ed\3\2"+ + "\2\2\u00d0\u02f2\3\2\2\2\u00d2\u02f8\3\2\2\2\u00d4\u02fe\3\2\2\2\u00d6"+ + "\u0303\3\2\2\2\u00d8\u0307\3\2\2\2\u00da\u030b\3\2\2\2\u00dc\u030f\3\2"+ + "\2\2\u00de\u0313\3\2\2\2\u00e0\u0316\3\2\2\2\u00e2\u031c\3\2\2\2\u00e4"+ + "\u0324\3\2\2\2\u00e6\u032a\3\2\2\2\u00e8\u032f\3\2\2\2\u00ea\u0332\3\2"+ + "\2\2\u00ec\u0335\3\2\2\2\u00ee\u0338\3\2\2\2\u00f0\u033a\3\2\2\2\u00f2"+ + "\u033c\3\2\2\2\u00f4\u033e\3\2\2\2\u00f6\u0340\3\2\2\2\u00f8\u0342\3\2"+ + "\2\2\u00fa\u0344\3\2\2\2\u00fc\u0346\3\2\2\2\u00fe\u0348\3\2\2\2\u0100"+ + "\u034b\3\2\2\2\u0102\u034f\3\2\2\2\u0104\u0353\3\2\2\2\u0106\u0356\3\2"+ + "\2\2\u0108\u035a\3\2\2\2\u010a\u035e\3\2\2\2\u010c\u0361\3\2\2\2\u010e"+ + "\u0364\3\2\2\2\u0110\u0367\3\2\2\2\u0112\u036a\3\2\2\2\u0114\u036d\3\2"+ + "\2\2\u0116\u0371\3\2\2\2\u0118\u0373\3\2\2\2\u011a\u0375\3\2\2\2\u011c"+ + "\u0379\3\2\2\2\u011e\u037d\3\2\2\2\u0120\u0381\3\2\2\2\u0122\u0385\3\2"+ + "\2\2\u0124\u0389\3\2\2\2\u0126\u038c\3\2\2\2\u0128\u0390\3\2\2\2\u012a"+ + "\u0398\3\2\2\2\u012c\u03a0\3\2\2\2\u012e\u03a7\3\2\2\2\u0130\u03ae\3\2"+ + "\2\2\u0132\u03b4\3\2\2\2\u0134\u03bd\3\2\2\2\u0136\u03c6\3\2\2\2\u0138"+ + "\u03cd\3\2\2\2\u013a\u03d1\3\2\2\2\u013c\u03d5\3\2\2\2\u013e\u03d7\3\2"+ + "\2\2\u0140\u03d9\3\2\2\2\u0142\u03db\3\2\2\2\u0144\u03dd\3\2\2\2\u0146"+ + "\u03df\3\2\2\2\u0148\u03e1\3\2\2\2\u014a\u03e3\3\2\2\2\u014c\u03e5\3\2"+ + "\2\2\u014e\u03e7\3\2\2\2\u0150\u03ea\3\2\2\2\u0152\u03ec\3\2\2\2\u0154"+ + "\u03ef\3\2\2\2\u0156\u03f1\3\2\2\2\u0158\u03f4\3\2\2\2\u015a\u03f7\3\2"+ + "\2\2\u015c\u03f9\3\2\2\2\u015e\u03fb\3\2\2\2\u0160\u03fd\3\2\2\2\u0162"+ + "\u0400\3\2\2\2\u0164\u0407\3\2\2\2\u0166\u0167\7\61\2\2\u0167\u016c\7"+ + "\61\2\2\u0168\u0169\7/\2\2\u0169\u016c\7/\2\2\u016a\u016c\t\2\2\2\u016b"+ + "\u0166\3\2\2\2\u016b\u0168\3\2\2\2\u016b\u016a\3\2\2\2\u016c\u0170\3\2"+ + "\2\2\u016d\u016f\n\3\2\2\u016e\u016d\3\2\2\2\u016f\u0172\3\2\2\2\u0170"+ + "\u016e\3\2\2\2\u0170\u0171\3\2\2\2\u0171\u0173\3\2\2\2\u0172\u0170\3\2"+ + "\2\2\u0173\u0174\b\2\2\2\u0174\5\3\2\2\2\u0175\u0176\7\61\2\2\u0176\u0177"+ + "\7,\2\2\u0177\u017b\3\2\2\2\u0178\u017a\13\2\2\2\u0179\u0178\3\2\2\2\u017a"+ + "\u017d\3\2\2\2\u017b\u017c\3\2\2\2\u017b\u0179\3\2\2\2\u017c\u017e\3\2"+ + "\2\2\u017d\u017b\3\2\2\2\u017e\u017f\7,\2\2\u017f\u0180\7\61\2\2\u0180"+ + "\u0181\3\2\2\2\u0181\u0182\b\3\2\2\u0182\7\3\2\2\2\u0183\u0184\t\4\2\2"+ + "\u0184\t\3\2\2\2\u0185\u0186\t\5\2\2\u0186\13\3\2\2\2\u0187\u0188\t\6"+ + "\2\2\u0188\r\3\2\2\2\u0189\u018a\t\7\2\2\u018a\17\3\2\2\2\u018b\u018c"+ + "\t\b\2\2\u018c\21\3\2\2\2\u018d\u018e\t\t\2\2\u018e\23\3\2\2\2\u018f\u0190"+ + "\t\n\2\2\u0190\25\3\2\2\2\u0191\u0192\t\13\2\2\u0192\27\3\2\2\2\u0193"+ + "\u0194\t\f\2\2\u0194\31\3\2\2\2\u0195\u0196\t\r\2\2\u0196\33\3\2\2\2\u0197"+ + "\u0198\t\16\2\2\u0198\35\3\2\2\2\u0199\u019a\t\17\2\2\u019a\37\3\2\2\2"+ + "\u019b\u019c\t\20\2\2\u019c!\3\2\2\2\u019d\u019e\t\21\2\2\u019e#\3\2\2"+ + "\2\u019f\u01a0\t\22\2\2\u01a0%\3\2\2\2\u01a1\u01a2\t\23\2\2\u01a2\'\3"+ + "\2\2\2\u01a3\u01a4\t\24\2\2\u01a4)\3\2\2\2\u01a5\u01a6\t\25\2\2\u01a6"+ + "+\3\2\2\2\u01a7\u01a8\t\26\2\2\u01a8-\3\2\2\2\u01a9\u01aa\t\27\2\2\u01aa"+ + "/\3\2\2\2\u01ab\u01ac\t\30\2\2\u01ac\61\3\2\2\2\u01ad\u01ae\t\31\2\2\u01ae"+ + "\63\3\2\2\2\u01af\u01b0\t\32\2\2\u01b0\65\3\2\2\2\u01b1\u01b2\t\33\2\2"+ + "\u01b2\67\3\2\2\2\u01b3\u01b4\t\34\2\2\u01b49\3\2\2\2\u01b5\u01b6\5\b"+ + "\4\2\u01b6\u01b7\5\16\7\2\u01b7\u01b8\5\f\6\2\u01b8;\3\2\2\2\u01b9\u01ba"+ + "\5\b\4\2\u01ba\u01bb\5\16\7\2\u01bb\u01bc\5\16\7\2\u01bc=\3\2\2\2\u01bd"+ + "\u01be\5\b\4\2\u01be\u01bf\5 \20\2\u01bf\u01c0\5\16\7\2\u01c0?\3\2\2\2"+ + "\u01c1\u01c2\5\n\5\2\u01c2\u01c3\5\30\f\2\u01c3\u01c4\5,\26\2\u01c4A\3"+ + "\2\2\2\u01c5\u01c6\5\f\6\2\u01c6\u01c7\5\b\4\2\u01c7\u01c8\5\34\16\2\u01c8"+ + "\u01c9\5\34\16\2\u01c9\u01ca\3\2\2\2\u01ca\u01cb\b!\3\2\u01cbC\3\2\2\2"+ + "\u01cc\u01cd\5\f\6\2\u01cd\u01ce\5\f\6\2\u01ce\u01cf\5\22\t\2\u01cfE\3"+ + "\2\2\2\u01d0\u01d1\5\f\6\2\u01d1\u01d2\5$\22\2\u01d2G\3\2\2\2\u01d3\u01d4"+ + "\5\f\6\2\u01d4\u01d5\5$\22\2\u01d5\u01d6\5\16\7\2\u01d6I\3\2\2\2\u01d7"+ + "\u01d8\5\f\6\2\u01d8\u01d9\5$\22\2\u01d9\u01da\5\16\7\2\u01da\u01db\5"+ + "(\24\2\u01dbK\3\2\2\2\u01dc\u01dd\5\f\6\2\u01dd\u01de\5$\22\2\u01de\u01df"+ + "\5\30\f\2\u01dfM\3\2\2\2\u01e0\u01e1\5\f\6\2\u01e1\u01e2\5$\22\2\u01e2"+ + "\u01e3\5\30\f\2\u01e3\u01e4\5(\24\2\u01e4O\3\2\2\2\u01e5\u01e6\5\f\6\2"+ + "\u01e6\u01e7\5$\22\2\u01e7\u01e8\5\34\16\2\u01e8Q\3\2\2\2\u01e9\u01ea"+ + "\5\16\7\2\u01ea\u01eb\5\b\4\2\u01eb\u01ec\5\b\4\2\u01ecS\3\2\2\2\u01ed"+ + "\u01ee\5\16\7\2\u01ee\u01ef\5\20\b\2\u01ef\u01f0\5\f\6\2\u01f0U\3\2\2"+ + "\2\u01f1\u01f2\5\16\7\2\u01f2\u01f3\5\30\f\2\u01f3W\3\2\2\2\u01f4\u01f5"+ + "\5\16\7\2\u01f5\u01f6\5\32\r\2\u01f6\u01f7\5 \20\2\u01f7\u01f8\58\34\2"+ + "\u01f8Y\3\2\2\2\u01f9\u01fa\5\20\b\2\u01fa\u01fb\5\30\f\2\u01fb[\3\2\2"+ + "\2\u01fc\u01fd\5\20\b\2\u01fd\u01fe\5\64\32\2\u01fe]\3\2\2\2\u01ff\u0200"+ + "\5\20\b\2\u0200\u0201\5\64\32\2\u0201\u0202\5\64\32\2\u0202_\3\2\2\2\u0203"+ + "\u0204\5\26\13\2\u0204\u0205\5\b\4\2\u0205\u0206\5\34\16\2\u0206\u0207"+ + "\5,\26\2\u0207a\3\2\2\2\u0208\u0209\5\30\f\2\u0209\u020a\5\36\17\2\u020a"+ + "c\3\2\2\2\u020b\u020c\5\30\f\2\u020c\u020d\5 \20\2\u020de\3\2\2\2\u020e"+ + "\u020f\5\30\f\2\u020f\u0210\5 \20\2\u0210\u0211\5\f\6\2\u0211g\3\2\2\2"+ + "\u0212\u0213\5\30\f\2\u0213\u0214\5 \20\2\u0214\u0215\5\16\7\2\u0215i"+ + "\3\2\2\2\u0216\u0217\5\30\f\2\u0217\u0218\5 \20\2\u0218\u0219\5\16\7\2"+ + "\u0219\u021a\5(\24\2\u021ak\3\2\2\2\u021b\u021c\5\30\f\2\u021c\u021d\5"+ + " \20\2\u021d\u021e\5\30\f\2\u021em\3\2\2\2\u021f\u0220\5\30\f\2\u0220"+ + "\u0221\5 \20\2\u0221\u0222\5\30\f\2\u0222\u0223\5(\24\2\u0223o\3\2\2\2"+ + "\u0224\u0225\5\32\r\2\u0225\u0226\5$\22\2\u0226\u0227\3\2\2\2\u0227\u0228"+ + "\b8\3\2\u0228q\3\2\2\2\u0229\u022a\5\32\r\2\u022a\u022b\5(\24\2\u022b"+ + "\u022c\3\2\2\2\u022c\u022d\b9\3\2\u022ds\3\2\2\2\u022e\u022f\5\34\16\2"+ + "\u022f\u0230\5\16\7\2\u0230u\3\2\2\2\u0231\u0232\5\34\16\2\u0232\u0233"+ + "\5\16\7\2\u0233\u0234\5\16\7\2\u0234w\3\2\2\2\u0235\u0236\5\34\16\2\u0236"+ + "\u0237\5\16\7\2\u0237\u0238\5\16\7\2\u0238\u0239\5(\24\2\u0239y\3\2\2"+ + "\2\u023a\u023b\5\34\16\2\u023b\u023c\5\16\7\2\u023c\u023d\5\30\f\2\u023d"+ + "{\3\2\2\2\u023e\u023f\5\34\16\2\u023f\u0240\5\16\7\2\u0240\u0241\5\30"+ + "\f\2\u0241\u0242\5(\24\2\u0242}\3\2\2\2\u0243\u0244\5 \20\2\u0244\u0245"+ + "\5\20\b\2\u0245\u0246\5\24\n\2\u0246\177\3\2\2\2\u0247\u0248\5 \20\2\u0248"+ + "\u0249\5\"\21\2\u0249\u024a\5$\22\2\u024a\u0081\3\2\2\2\u024b\u024c\5"+ + "\"\21\2\u024c\u024d\5(\24\2\u024d\u0083\3\2\2\2\u024e\u024f\5\"\21\2\u024f"+ + "\u0250\5,\26\2\u0250\u0251\5\16\7\2\u0251\u0252\5(\24\2\u0252\u0085\3"+ + "\2\2\2\u0253\u0254\5\"\21\2\u0254\u0255\5,\26\2\u0255\u0256\5\30\f\2\u0256"+ + "\u0257\5(\24\2\u0257\u0087\3\2\2\2\u0258\u0259\5\"\21\2\u0259\u025a\5"+ + ".\27\2\u025a\u025b\5,\26\2\u025b\u0089\3\2\2\2\u025c\u025d\5\"\21\2\u025d"+ + "\u025e\5.\27\2\u025e\u025f\5,\26\2\u025f\u0260\5\16\7\2\u0260\u008b\3"+ + "\2\2\2\u0261\u0262\5\"\21\2\u0262\u0263\5.\27\2\u0263\u0264\5,\26\2\u0264"+ + "\u0265\5\30\f\2\u0265\u008d\3\2\2\2\u0266\u0267\5$\22\2\u0267\u0268\5"+ + "\"\21\2\u0268\u0269\5$\22\2\u0269\u008f\3\2\2\2\u026a\u026b\5$\22\2\u026b"+ + "\u026c\5.\27\2\u026c\u026d\5*\25\2\u026d\u026e\5\26\13\2\u026e\u0091\3"+ + "\2\2\2\u026f\u0270\5(\24\2\u0270\u0271\5\20\b\2\u0271\u0272\5*\25\2\u0272"+ + "\u0093\3\2\2\2\u0273\u0274\5(\24\2\u0274\u0275\5\20\b\2\u0275\u0276\5"+ + ",\26\2\u0276\u0277\3\2\2\2\u0277\u0278\bJ\3\2\u0278\u0095\3\2\2\2\u0279"+ + "\u027a\5(\24\2\u027a\u027b\5\20\b\2\u027b\u027c\5,\26\2\u027c\u027d\5"+ + "\30\f\2\u027d\u0097\3\2\2\2\u027e\u027f\5(\24\2\u027f\u0280\5\20\b\2\u0280"+ + "\u0281\5,\26\2\u0281\u0282\5 \20\2\u0282\u0099\3\2\2\2\u0283\u0284\5("+ + "\24\2\u0284\u0285\5\34\16\2\u0285\u009b\3\2\2\2\u0286\u0287\5(\24\2\u0287"+ + "\u0288\5\34\16\2\u0288\u0289\5\b\4\2\u0289\u009d\3\2\2\2\u028a\u028b\5"+ + "(\24\2\u028b\u028c\5\34\16\2\u028c\u028d\5\f\6\2\u028d\u009f\3\2\2\2\u028e"+ + "\u028f\5(\24\2\u028f\u0290\5\34\16\2\u0290\u0291\5\f\6\2\u0291\u0292\5"+ + "\b\4\2\u0292\u00a1\3\2\2\2\u0293\u0294\5(\24\2\u0294\u0295\5\34\16\2\u0295"+ + "\u0296\5\16\7\2\u0296\u00a3\3\2\2\2\u0297\u0298\5(\24\2\u0298\u0299\5"+ + "(\24\2\u0299\u00a5\3\2\2\2\u029a\u029b\5(\24\2\u029b\u029c\5(\24\2\u029c"+ + "\u029d\5\b\4\2\u029d\u00a7\3\2\2\2\u029e\u029f\5(\24\2\u029f\u02a0\5("+ + "\24\2\u02a0\u02a1\5\f\6\2\u02a1\u00a9\3\2\2\2\u02a2\u02a3\5(\24\2\u02a3"+ + "\u02a4\5(\24\2\u02a4\u02a5\5\f\6\2\u02a5\u02a6\5\b\4\2\u02a6\u00ab\3\2"+ + "\2\2\u02a7\u02a8\5(\24\2\u02a8\u02a9\5(\24\2\u02a9\u02aa\5\16\7\2\u02aa"+ + "\u00ad\3\2\2\2\u02ab\u02ac\5(\24\2\u02ac\u02ad\5*\25\2\u02ad\u02ae\5,"+ + "\26\2\u02ae\u00af\3\2\2\2\u02af\u02b0\5*\25\2\u02b0\u02b1\5\n\5\2\u02b1"+ + "\u02b2\5\f\6\2\u02b2\u00b1\3\2\2\2\u02b3\u02b4\5*\25\2\u02b4\u02b5\5\f"+ + "\6\2\u02b5\u02b6\5\22\t\2\u02b6\u00b3\3\2\2\2\u02b7\u02b8\5*\25\2\u02b8"+ + "\u02b9\5\20\b\2\u02b9\u02ba\5,\26\2\u02ba\u00b5\3\2\2\2\u02bb\u02bc\5"+ + "*\25\2\u02bc\u02bd\5\34\16\2\u02bd\u02be\5\b\4\2\u02be\u00b7\3\2\2\2\u02bf"+ + "\u02c0\5*\25\2\u02c0\u02c1\5(\24\2\u02c1\u02c2\5\b\4\2\u02c2\u00b9\3\2"+ + "\2\2\u02c3\u02c4\5*\25\2\u02c4\u02c5\5\34\16\2\u02c5\u02c6\5\34\16\2\u02c6"+ + "\u00bb\3\2\2\2\u02c7\u02c8\5*\25\2\u02c8\u02c9\5(\24\2\u02c9\u02ca\5\34"+ + "\16\2\u02ca\u00bd\3\2\2\2\u02cb\u02cc\5*\25\2\u02cc\u02cd\5.\27\2\u02cd"+ + "\u02ce\5\n\5\2\u02ce\u00bf\3\2\2\2\u02cf\u02d0\5\64\32\2\u02d0\u02d1\5"+ + "\"\21\2\u02d1\u02d2\5(\24\2\u02d2\u00c1\3\2\2\2\u02d3\u02d4\5\f\6\2\u02d4"+ + "\u02d5\3\2\2\2\u02d5\u02d6\ba\4\2\u02d6\u00c3\3\2\2\2\u02d7\u02d8\5 \20"+ + "\2\u02d8\u02d9\5\f\6\2\u02d9\u02da\3\2\2\2\u02da\u02db\bb\4\2\u02db\u00c5"+ + "\3\2\2\2\u02dc\u02dd\58\34\2\u02dd\u02de\3\2\2\2\u02de\u02df\bc\4\2\u02df"+ + "\u00c7\3\2\2\2\u02e0\u02e1\5 \20\2\u02e1\u02e2\58\34\2\u02e2\u02e3\3\2"+ + "\2\2\u02e3\u02e4\bd\4\2\u02e4\u00c9\3\2\2\2\u02e5\u02e6\5\36\17\2\u02e6"+ + "\u02e7\3\2\2\2\u02e7\u02e8\be\4\2\u02e8\u00cb\3\2\2\2\u02e9\u02ea\5$\22"+ + "\2\u02ea\u02eb\3\2\2\2\u02eb\u02ec\bf\4\2\u02ec\u00cd\3\2\2\2\u02ed\u02ee"+ + "\5$\22\2\u02ee\u02ef\5\20\b\2\u02ef\u02f0\3\2\2\2\u02f0\u02f1\bg\4\2\u02f1"+ + "\u00cf\3\2\2\2\u02f2\u02f3\5$\22\2\u02f3\u02f4\5\"\21\2\u02f4\u02f5\3"+ + "\2\2\2\u02f5\u02f6\bh\4\2\u02f6\u00d1\3\2\2\2\u02f7\u02f9\t\35\2\2\u02f8"+ + "\u02f7\3\2\2\2\u02f9\u02fa\3\2\2\2\u02fa\u02f8\3\2\2\2\u02fa\u02fb\3\2"+ + "\2\2\u02fb\u02fc\3\2\2\2\u02fc\u02fd\bi\2\2\u02fd\u00d3\3\2\2\2\u02fe"+ + "\u02ff\6j\2\2\u02ff\u0300\3\2\2\2\u0300\u0301\bj\4\2\u0301\u0302\bj\5"+ + "\2\u0302\u00d5\3\2\2\2\u0303\u0304\5\"\21\2\u0304\u0305\5(\24\2\u0305"+ + "\u0306\5\24\n\2\u0306\u00d7\3\2\2\2\u0307\u0308\5\20\b\2\u0308\u0309\5"+ + "&\23\2\u0309\u030a\5.\27\2\u030a\u00d9\3\2\2\2\u030b\u030c\5*\25\2\u030c"+ + "\u030d\5\20\b\2\u030d\u030e\5,\26\2\u030e\u00db\3\2\2\2\u030f\u0310\5"+ + "\60\30\2\u0310\u0311\5\b\4\2\u0311\u0312\5(\24\2\u0312\u00dd\3\2\2\2\u0313"+ + "\u0314\5\30\f\2\u0314\u0315\5\22\t\2\u0315\u00df\3\2\2\2\u0316\u0317\5"+ + "\20\b\2\u0317\u0318\5 \20\2\u0318\u0319\5\16\7\2\u0319\u031a\5\30\f\2"+ + "\u031a\u031b\5\22\t\2\u031b\u00e1\3\2\2\2\u031c\u031d\5\30\f\2\u031d\u031e"+ + "\5 \20\2\u031e\u031f\5\f\6\2\u031f\u0320\5\34\16\2\u0320\u0321\5.\27\2"+ + "\u0321\u0322\5\16\7\2\u0322\u0323\5\20\b\2\u0323\u00e3\3\2\2\2\u0324\u0325"+ + "\5\36\17\2\u0325\u0326\5\b\4\2\u0326\u0327\5\f\6\2\u0327\u0328\5(\24\2"+ + "\u0328\u0329\5\"\21\2\u0329\u00e5\3\2\2\2\u032a\u032b\5\20\b\2\u032b\u032c"+ + "\5 \20\2\u032c\u032d\5\16\7\2\u032d\u032e\5\36\17\2\u032e\u00e7\3\2\2"+ + "\2\u032f\u0330\5\16\7\2\u0330\u0331\5\n\5\2\u0331\u00e9\3\2\2\2\u0332"+ + "\u0333\5\16\7\2\u0333\u0334\5\62\31\2\u0334\u00eb\3\2\2\2\u0335\u0336"+ + "\5\16\7\2\u0336\u0337\5*\25\2\u0337\u00ed\3\2\2\2\u0338\u0339\7&\2\2\u0339"+ + "\u00ef\3\2\2\2\u033a\u033b\5\b\4\2\u033b\u00f1\3\2\2\2\u033c\u033d\5\n"+ + "\5\2\u033d\u00f3\3\2\2\2\u033e\u033f\5\f\6\2\u033f\u00f5\3\2\2\2\u0340"+ + "\u0341\5\16\7\2\u0341\u00f7\3\2\2\2\u0342\u0343\5\20\b\2\u0343\u00f9\3"+ + "\2\2\2\u0344\u0345\5\26\13\2\u0345\u00fb\3\2\2\2\u0346\u0347\5\34\16\2"+ + "\u0347\u00fd\3\2\2\2\u0348\u0349\5\30\f\2\u0349\u034a\5\64\32\2\u034a"+ + "\u00ff\3\2\2\2\u034b\u034c\5\30\f\2\u034c\u034d\5\64\32\2\u034d\u034e"+ + "\5\26\13\2\u034e\u0101\3\2\2\2\u034f\u0350\5\30\f\2\u0350\u0351\5\64\32"+ + "\2\u0351\u0352\5\34\16\2\u0352\u0103\3\2\2\2\u0353\u0354\5\30\f\2\u0354"+ + "\u0355\5\66\33\2\u0355\u0105\3\2\2\2\u0356\u0357\5\30\f\2\u0357\u0358"+ + "\5\66\33\2\u0358\u0359\5\26\13\2\u0359\u0107\3\2\2\2\u035a\u035b\5\30"+ + "\f\2\u035b\u035c\5\66\33\2\u035c\u035d\5\34\16\2\u035d\u0109\3\2\2\2\u035e"+ + "\u035f\5\n\5\2\u035f\u0360\5\f\6\2\u0360\u010b\3\2\2\2\u0361\u0362\5\16"+ + "\7\2\u0362\u0363\5\20\b\2\u0363\u010d\3\2\2\2\u0364\u0365\5\26\13\2\u0365"+ + "\u0366\5\34\16\2\u0366\u010f\3\2\2\2\u0367\u0368\5*\25\2\u0368\u0369\5"+ + "$\22\2\u0369\u0111\3\2\2\2\u036a\u036b\5\b\4\2\u036b\u036c\5\22\t\2\u036c"+ + "\u0113\3\2\2\2\u036d\u036e\5\b\4\2\u036e\u036f\5\22\t\2\u036f\u0370\7"+ + ")\2\2\u0370\u0115\3\2\2\2\u0371\u0372\5\30\f\2\u0372\u0117\3\2\2\2\u0373"+ + "\u0374\5(\24\2\u0374\u0119\3\2\2\2\u0375\u0376\5\36\17\2\u0376\u0377\5"+ + "\"\21\2\u0377\u0378\5\16\7\2\u0378\u011b\3\2\2\2\u0379\u037a\5*\25\2\u037a"+ + "\u037b\5\26\13\2\u037b\u037c\5(\24\2\u037c\u011d\3\2\2\2\u037d\u037e\5"+ + "*\25\2\u037e\u037f\5\26\13\2\u037f\u0380\5\34\16\2\u0380\u011f\3\2\2\2"+ + "\u0381\u0382\5 \20\2\u0382\u0383\5\"\21\2\u0383\u0384\5,\26\2\u0384\u0121"+ + "\3\2\2\2\u0385\u0386\5\b\4\2\u0386\u0387\5 \20\2\u0387\u0388\5\16\7\2"+ + "\u0388\u0123\3\2\2\2\u0389\u038a\5\"\21\2\u038a\u038b\5(\24\2\u038b\u0125"+ + "\3\2\2\2\u038c\u038d\5\64\32\2\u038d\u038e\5\"\21\2\u038e\u038f\5(\24"+ + "\2\u038f\u0127\3\2\2\2\u0390\u0391\7\62\2\2\u0391\u0393\5\64\32\2\u0392"+ + "\u0394\t\36\2\2\u0393\u0392\3\2\2\2\u0394\u0395\3\2\2\2\u0395\u0393\3"+ + "\2\2\2\u0395\u0396\3\2\2\2\u0396\u0129\3\2\2\2\u0397\u0399\t\37\2\2\u0398"+ + "\u0397\3\2\2\2\u0399\u039a\3\2\2\2\u039a\u0398\3\2\2\2\u039a\u039b\3\2"+ + "\2\2\u039b\u039d\3\2\2\2\u039c\u039e\5\16\7\2\u039d\u039c\3\2\2\2\u039d"+ + "\u039e\3\2\2\2\u039e\u012b\3\2\2\2\u039f\u03a1\t\36\2\2\u03a0\u039f\3"+ + "\2\2\2\u03a1\u03a2\3\2\2\2\u03a2\u03a0\3\2\2\2\u03a2\u03a3\3\2\2\2\u03a3"+ + "\u03a4\3\2\2\2\u03a4\u03a5\5\26\13\2\u03a5\u012d\3\2\2\2\u03a6\u03a8\t"+ + " \2\2\u03a7\u03a6\3\2\2\2\u03a8\u03a9\3\2\2\2\u03a9\u03a7\3\2\2\2\u03a9"+ + "\u03aa\3\2\2\2\u03aa\u03ab\3\2\2\2\u03ab\u03ac\t!\2\2\u03ac\u012f\3\2"+ + "\2\2\u03ad\u03af\t\"\2\2\u03ae\u03ad\3\2\2\2\u03af\u03b0\3\2\2\2\u03b0"+ + "\u03ae\3\2\2\2\u03b0\u03b1\3\2\2\2\u03b1\u03b2\3\2\2\2\u03b2\u03b3\5\n"+ + "\5\2\u03b3\u0131\3\2\2\2\u03b4\u03b8\7)\2\2\u03b5\u03b7\n#\2\2\u03b6\u03b5"+ + "\3\2\2\2\u03b7\u03ba\3\2\2\2\u03b8\u03b6\3\2\2\2\u03b8\u03b9\3\2\2\2\u03b9"+ + "\u03bb\3\2\2\2\u03ba\u03b8\3\2\2\2\u03bb\u03bc\7)\2\2\u03bc\u0133\3\2"+ + "\2\2\u03bd\u03c1\7$\2\2\u03be\u03c0\n$\2\2\u03bf\u03be\3\2\2\2\u03c0\u03c3"+ + "\3\2\2\2\u03c1\u03bf\3\2\2\2\u03c1\u03c2\3\2\2\2\u03c2\u03c4\3\2\2\2\u03c3"+ + "\u03c1\3\2\2\2\u03c4\u03c5\7$\2\2\u03c5\u0135\3\2\2\2\u03c6\u03ca\t%\2"+ + "\2\u03c7\u03c9\t&\2\2\u03c8\u03c7\3\2\2\2\u03c9\u03cc\3\2\2\2\u03ca\u03c8"+ + "\3\2\2\2\u03ca\u03cb\3\2\2\2\u03cb\u0137\3\2\2\2\u03cc\u03ca\3\2\2\2\u03cd"+ + "\u03ce\5\u0136\u009b\2\u03ce\u03cf\7<\2\2\u03cf\u0139\3\2\2\2\u03d0\u03d2"+ + "\n\'\2\2\u03d1\u03d0\3\2\2\2\u03d2\u03d3\3\2\2\2\u03d3\u03d1\3\2\2\2\u03d3"+ + "\u03d4\3\2\2\2\u03d4\u013b\3\2\2\2\u03d5\u03d6\7*\2\2\u03d6\u013d\3\2"+ + "\2\2\u03d7\u03d8\7+\2\2\u03d8\u013f\3\2\2\2\u03d9\u03da\7.\2\2\u03da\u0141"+ + "\3\2\2\2\u03db\u03dc\7-\2\2\u03dc\u0143\3\2\2\2\u03dd\u03de\7/\2\2\u03de"+ + "\u0145\3\2\2\2\u03df\u03e0\7,\2\2\u03e0\u0147\3\2\2\2\u03e1\u03e2\7\61"+ + "\2\2\u03e2\u0149\3\2\2\2\u03e3\u03e4\7?\2\2\u03e4\u014b\3\2\2\2\u03e5"+ + "\u03e6\7@\2\2\u03e6\u014d\3\2\2\2\u03e7\u03e8\7@\2\2\u03e8\u03e9\7?\2"+ + "\2\u03e9\u014f\3\2\2\2\u03ea\u03eb\7>\2\2\u03eb\u0151\3\2\2\2\u03ec\u03ed"+ + "\7>\2\2\u03ed\u03ee\7?\2\2\u03ee\u0153\3\2\2\2\u03ef\u03f0\7\'\2\2\u03f0"+ + "\u0155\3\2\2\2\u03f1\u03f2\7@\2\2\u03f2\u03f3\7@\2\2\u03f3\u0157\3\2\2"+ + "\2\u03f4\u03f5\7>\2\2\u03f5\u03f6\7>\2\2\u03f6\u0159\3\2\2\2\u03f7\u03f8"+ + "\7#\2\2\u03f8\u015b\3\2\2\2\u03f9\u03fa\7(\2\2\u03fa\u015d\3\2\2\2\u03fb"+ + "\u03fc\7~\2\2\u03fc\u015f\3\2\2\2\u03fd\u03fe\7\u0080\2\2\u03fe\u0161"+ + "\3\2\2\2\u03ff\u0401\t\35\2\2\u0400\u03ff\3\2\2\2\u0401\u0402\3\2\2\2"+ + "\u0402\u0400\3\2\2\2\u0402\u0403\3\2\2\2\u0403\u0404\3\2\2\2\u0404\u0405"+ + "\b\u00b1\2\2\u0405\u0163\3\2\2\2\u0406\u0408\7\17\2\2\u0407\u0406\3\2"+ + "\2\2\u0407\u0408\3\2\2\2\u0408\u0409\3\2\2\2\u0409\u040a\7\f\2\2\u040a"+ + "\u0165\3\2\2\2\24\2\3\u016b\u0170\u017b\u02fa\u0395\u039a\u039d\u03a2"+ + "\u03a9\u03b0\u03b8\u03c1\u03ca\u03d3\u0402\u0407\6\b\2\2\7\3\2\6\2\2\2"+ + "\3\2"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.tokens new file mode 100644 index 000000000..e398feb30 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.tokens @@ -0,0 +1,172 @@ +COMMENT=1 +COMMENT2=2 +OPCODE_ADC=3 +OPCODE_ADD=4 +OPCODE_AND=5 +OPCODE_BIT=6 +OPCODE_CALL=7 +OPCODE_CCF=8 +OPCODE_CP=9 +OPCODE_CPD=10 +OPCODE_CPDR=11 +OPCODE_CPI=12 +OPCODE_CPIR=13 +OPCODE_CPL=14 +OPCODE_DAA=15 +OPCODE_DEC=16 +OPCODE_DI=17 +OPCODE_DJNZ=18 +OPCODE_EI=19 +OPCODE_EX=20 +OPCODE_EXX=21 +OPCODE_HALT=22 +OPCODE_IM=23 +OPCODE_IN=24 +OPCODE_INC=25 +OPCODE_IND=26 +OPCODE_INDR=27 +OPCODE_INI=28 +OPCODE_INIR=29 +OPCODE_JP=30 +OPCODE_JR=31 +OPCODE_LD=32 +OPCODE_LDD=33 +OPCODE_LDDR=34 +OPCODE_LDI=35 +OPCODE_LDIR=36 +OPCODE_NEG=37 +OPCODE_NOP=38 +OPCODE_OR=39 +OPCODE_OTDR=40 +OPCODE_OTIR=41 +OPCODE_OUT=42 +OPCODE_OUTD=43 +OPCODE_OUTI=44 +OPCODE_POP=45 +OPCODE_PUSH=46 +OPCODE_RES=47 +OPCODE_RET=48 +OPCODE_RETI=49 +OPCODE_RETN=50 +OPCODE_RL=51 +OPCODE_RLA=52 +OPCODE_RLC=53 +OPCODE_RLCA=54 +OPCODE_RLD=55 +OPCODE_RR=56 +OPCODE_RRA=57 +OPCODE_RRC=58 +OPCODE_RRCA=59 +OPCODE_RRD=60 +OPCODE_RST=61 +OPCODE_SBC=62 +OPCODE_SCF=63 +OPCODE_SET=64 +OPCODE_SLA=65 +OPCODE_SRA=66 +OPCODE_SLL=67 +OPCODE_SRL=68 +OPCODE_SUB=69 +OPCODE_XOR=70 +COND_C=71 +COND_NC=72 +COND_Z=73 +COND_NZ=74 +COND_M=75 +COND_P=76 +COND_PE=77 +COND_PO=78 +COND_WS=79 +COND_UNRECOGNIZED=80 +PREP_ORG=81 +PREP_EQU=82 +PREP_SET=83 +PREP_VAR=84 +PREP_IF=85 +PREP_ENDIF=86 +PREP_INCLUDE=87 +PREP_MACRO=88 +PREP_ENDM=89 +PREP_DB=90 +PREP_DW=91 +PREP_DS=92 +PREP_ADDR=93 +REG_A=94 +REG_B=95 +REG_C=96 +REG_D=97 +REG_E=98 +REG_H=99 +REG_L=100 +REG_IX=101 +REG_IXH=102 +REG_IXL=103 +REG_IY=104 +REG_IYH=105 +REG_IYL=106 +REG_BC=107 +REG_DE=108 +REG_HL=109 +REG_SP=110 +REG_AF=111 +REG_AFF=112 +REG_I=113 +REG_R=114 +OP_MOD=115 +OP_SHR=116 +OP_SHL=117 +OP_NOT=118 +OP_AND=119 +OP_OR=120 +OP_XOR=121 +LIT_HEXNUMBER_1=122 +LIT_NUMBER=123 +LIT_HEXNUMBER_2=124 +LIT_OCTNUMBER=125 +LIT_BINNUMBER=126 +LIT_STRING_1=127 +LIT_STRING_2=128 +ID_IDENTIFIER=129 +ID_LABEL=130 +ERROR=131 +SEP_LPAR=132 +SEP_RPAR=133 +SEP_COMMA=134 +OP_ADD=135 +OP_SUBTRACT=136 +OP_MULTIPLY=137 +OP_DIVIDE=138 +OP_EQUAL=139 +OP_GT=140 +OP_GTE=141 +OP_LT=142 +OP_LTE=143 +OP_MOD_2=144 +OP_SHR_2=145 +OP_SHL_2=146 +OP_NOT_2=147 +OP_AND_2=148 +OP_OR_2=149 +OP_XOR_2=150 +WS=151 +EOL=152 +'$'=93 +'('=132 +')'=133 +','=134 +'+'=135 +'-'=136 +'*'=137 +'/'=138 +'='=139 +'>'=140 +'>='=141 +'<'=142 +'<='=143 +'%'=144 +'>>'=145 +'<<'=146 +'!'=147 +'&'=148 +'|'=149 +'~'=150 diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp new file mode 100644 index 000000000..742e9dbcc --- /dev/null +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp @@ -0,0 +1,496 @@ +token literal names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'$' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'(' +')' +',' +'+' +'-' +'*' +'/' +'=' +'>' +'>=' +'<' +'<=' +'%' +'>>' +'<<' +'~' +'&' +'|' +'^' +null +null + +token symbolic names: +null +COMMENT +COMMENT2 +OPCODE_ADC +OPCODE_ADD +OPCODE_AND +OPCODE_BIT +OPCODE_CALL +OPCODE_CCF +OPCODE_CP +OPCODE_CPD +OPCODE_CPDR +OPCODE_CPI +OPCODE_CPIR +OPCODE_CPL +OPCODE_DAA +OPCODE_DEC +OPCODE_DI +OPCODE_DJNZ +OPCODE_EI +OPCODE_EX +OPCODE_EXX +OPCODE_HALT +OPCODE_IM +OPCODE_IN +OPCODE_INC +OPCODE_IND +OPCODE_INDR +OPCODE_INI +OPCODE_INIR +OPCODE_JP +OPCODE_JR +OPCODE_LD +OPCODE_LDD +OPCODE_LDDR +OPCODE_LDI +OPCODE_LDIR +OPCODE_NEG +OPCODE_NOP +OPCODE_OR +OPCODE_OTDR +OPCODE_OTIR +OPCODE_OUT +OPCODE_OUTD +OPCODE_OUTI +OPCODE_POP +OPCODE_PUSH +OPCODE_RES +OPCODE_RET +OPCODE_RETI +OPCODE_RETN +OPCODE_RL +OPCODE_RLA +OPCODE_RLC +OPCODE_RLCA +OPCODE_RLD +OPCODE_RR +OPCODE_RRA +OPCODE_RRC +OPCODE_RRCA +OPCODE_RRD +OPCODE_RST +OPCODE_SBC +OPCODE_SCF +OPCODE_SET +OPCODE_SLA +OPCODE_SRA +OPCODE_SLL +OPCODE_SRL +OPCODE_SUB +OPCODE_XOR +COND_C +COND_NC +COND_Z +COND_NZ +COND_M +COND_P +COND_PE +COND_PO +COND_WS +COND_UNRECOGNIZED +PREP_ORG +PREP_EQU +PREP_SET +PREP_IF +PREP_ENDIF +PREP_INCLUDE +PREP_MACRO +PREP_ENDM +PREP_DB +PREP_DW +PREP_DS +PREP_ADDR +REG_A +REG_B +REG_C +REG_D +REG_E +REG_H +REG_L +REG_IX +REG_IXH +REG_IXL +REG_IY +REG_IYH +REG_IYL +REG_BC +REG_DE +REG_HL +REG_SP +REG_AF +REG_AFF +REG_I +REG_R +OP_MOD +OP_SHR +OP_SHL +OP_NOT +OP_AND +OP_OR +OP_XOR +LIT_HEXNUMBER_1 +LIT_NUMBER +LIT_HEXNUMBER_2 +LIT_OCTNUMBER +LIT_BINNUMBER +LIT_STRING_1 +LIT_STRING_2 +ID_IDENTIFIER +ID_LABEL +ERROR +SEP_LPAR +SEP_RPAR +SEP_COMMA +OP_ADD +OP_SUBTRACT +OP_MULTIPLY +OP_DIVIDE +OP_EQUAL +OP_GT +OP_GTE +OP_LT +OP_LTE +OP_MOD_2 +OP_SHR_2 +OP_SHL_2 +OP_NOT_2 +OP_AND_2 +OP_OR_2 +OP_XOR_2 +WS +EOL + +rule names: +COMMENT +COMMENT2 +A +B +C +D +E +F +G +H +I +J +L +M +N +O +P +Q +R +S +T +U +V +W +X +Y +Z +OPCODE_ADC +OPCODE_ADD +OPCODE_AND +OPCODE_BIT +OPCODE_CALL +OPCODE_CCF +OPCODE_CP +OPCODE_CPD +OPCODE_CPDR +OPCODE_CPI +OPCODE_CPIR +OPCODE_CPL +OPCODE_DAA +OPCODE_DEC +OPCODE_DI +OPCODE_DJNZ +OPCODE_EI +OPCODE_EX +OPCODE_EXX +OPCODE_HALT +OPCODE_IM +OPCODE_IN +OPCODE_INC +OPCODE_IND +OPCODE_INDR +OPCODE_INI +OPCODE_INIR +OPCODE_JP +OPCODE_JR +OPCODE_LD +OPCODE_LDD +OPCODE_LDDR +OPCODE_LDI +OPCODE_LDIR +OPCODE_NEG +OPCODE_NOP +OPCODE_OR +OPCODE_OTDR +OPCODE_OTIR +OPCODE_OUT +OPCODE_OUTD +OPCODE_OUTI +OPCODE_POP +OPCODE_PUSH +OPCODE_RES +OPCODE_RET +OPCODE_RETI +OPCODE_RETN +OPCODE_RL +OPCODE_RLA +OPCODE_RLC +OPCODE_RLCA +OPCODE_RLD +OPCODE_RR +OPCODE_RRA +OPCODE_RRC +OPCODE_RRCA +OPCODE_RRD +OPCODE_RST +OPCODE_SBC +OPCODE_SCF +OPCODE_SET +OPCODE_SLA +OPCODE_SRA +OPCODE_SLL +OPCODE_SRL +OPCODE_SUB +OPCODE_XOR +COND_C +COND_NC +COND_Z +COND_NZ +COND_M +COND_P +COND_PE +COND_PO +COND_WS +COND_UNRECOGNIZED +PREP_ORG +PREP_EQU +PREP_SET +PREP_IF +PREP_ENDIF +PREP_INCLUDE +PREP_MACRO +PREP_ENDM +PREP_DB +PREP_DW +PREP_DS +PREP_ADDR +REG_A +REG_B +REG_C +REG_D +REG_E +REG_H +REG_L +REG_IX +REG_IXH +REG_IXL +REG_IY +REG_IYH +REG_IYL +REG_BC +REG_DE +REG_HL +REG_SP +REG_AF +REG_AFF +REG_I +REG_R +OP_MOD +OP_SHR +OP_SHL +OP_NOT +OP_AND +OP_OR +OP_XOR +LIT_HEXNUMBER_1 +LIT_NUMBER +LIT_HEXNUMBER_2 +LIT_OCTNUMBER +LIT_BINNUMBER +LIT_STRING_1 +LIT_STRING_2 +ID_IDENTIFIER +ID_LABEL +ERROR +SEP_LPAR +SEP_RPAR +SEP_COMMA +OP_ADD +OP_SUBTRACT +OP_MULTIPLY +OP_DIVIDE +OP_EQUAL +OP_GT +OP_GTE +OP_LT +OP_LTE +OP_MOD_2 +OP_SHR_2 +OP_SHL_2 +OP_NOT_2 +OP_AND_2 +OP_OR_2 +OP_XOR_2 +WS +EOL + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE +CONDITION + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 153, 1029, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 4, 154, 9, 154, 4, 155, 9, 155, 4, 156, 9, 156, 4, 157, 9, 157, 4, 158, 9, 158, 4, 159, 9, 159, 4, 160, 9, 160, 4, 161, 9, 161, 4, 162, 9, 162, 4, 163, 9, 163, 4, 164, 9, 164, 4, 165, 9, 165, 4, 166, 9, 166, 4, 167, 9, 167, 4, 168, 9, 168, 4, 169, 9, 169, 4, 170, 9, 170, 4, 171, 9, 171, 4, 172, 9, 172, 4, 173, 9, 173, 4, 174, 9, 174, 4, 175, 9, 175, 4, 176, 9, 176, 4, 177, 9, 177, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 362, 10, 2, 3, 2, 7, 2, 365, 10, 2, 12, 2, 14, 2, 368, 11, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 376, 10, 3, 12, 3, 14, 3, 379, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 104, 3, 105, 6, 105, 759, 10, 105, 13, 105, 14, 105, 760, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 129, 3, 130, 3, 130, 3, 130, 3, 130, 3, 131, 3, 131, 3, 131, 3, 131, 3, 132, 3, 132, 3, 132, 3, 133, 3, 133, 3, 133, 3, 134, 3, 134, 3, 134, 3, 135, 3, 135, 3, 135, 3, 136, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 3, 144, 3, 144, 3, 144, 3, 145, 3, 145, 3, 145, 3, 146, 3, 146, 3, 146, 3, 146, 3, 147, 3, 147, 3, 147, 6, 147, 910, 10, 147, 13, 147, 14, 147, 911, 3, 148, 6, 148, 915, 10, 148, 13, 148, 14, 148, 916, 3, 148, 5, 148, 920, 10, 148, 3, 149, 6, 149, 923, 10, 149, 13, 149, 14, 149, 924, 3, 149, 3, 149, 3, 150, 6, 150, 930, 10, 150, 13, 150, 14, 150, 931, 3, 150, 3, 150, 3, 151, 6, 151, 937, 10, 151, 13, 151, 14, 151, 938, 3, 151, 3, 151, 3, 152, 3, 152, 7, 152, 945, 10, 152, 12, 152, 14, 152, 948, 11, 152, 3, 152, 3, 152, 3, 153, 3, 153, 7, 153, 954, 10, 153, 12, 153, 14, 153, 957, 11, 153, 3, 153, 3, 153, 3, 154, 3, 154, 7, 154, 963, 10, 154, 12, 154, 14, 154, 966, 11, 154, 3, 155, 3, 155, 3, 155, 3, 156, 6, 156, 972, 10, 156, 13, 156, 14, 156, 973, 3, 157, 3, 157, 3, 158, 3, 158, 3, 159, 3, 159, 3, 160, 3, 160, 3, 161, 3, 161, 3, 162, 3, 162, 3, 163, 3, 163, 3, 164, 3, 164, 3, 165, 3, 165, 3, 166, 3, 166, 3, 166, 3, 167, 3, 167, 3, 168, 3, 168, 3, 168, 3, 169, 3, 169, 3, 170, 3, 170, 3, 170, 3, 171, 3, 171, 3, 171, 3, 172, 3, 172, 3, 173, 3, 173, 3, 174, 3, 174, 3, 175, 3, 175, 3, 176, 6, 176, 1019, 10, 176, 13, 176, 14, 176, 1020, 3, 176, 3, 176, 3, 177, 5, 177, 1026, 10, 177, 3, 177, 3, 177, 3, 377, 2, 178, 4, 3, 6, 4, 8, 2, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54, 2, 56, 2, 58, 5, 60, 6, 62, 7, 64, 8, 66, 9, 68, 10, 70, 11, 72, 12, 74, 13, 76, 14, 78, 15, 80, 16, 82, 17, 84, 18, 86, 19, 88, 20, 90, 21, 92, 22, 94, 23, 96, 24, 98, 25, 100, 26, 102, 27, 104, 28, 106, 29, 108, 30, 110, 31, 112, 32, 114, 33, 116, 34, 118, 35, 120, 36, 122, 37, 124, 38, 126, 39, 128, 40, 130, 41, 132, 42, 134, 43, 136, 44, 138, 45, 140, 46, 142, 47, 144, 48, 146, 49, 148, 50, 150, 51, 152, 52, 154, 53, 156, 54, 158, 55, 160, 56, 162, 57, 164, 58, 166, 59, 168, 60, 170, 61, 172, 62, 174, 63, 176, 64, 178, 65, 180, 66, 182, 67, 184, 68, 186, 69, 188, 70, 190, 71, 192, 72, 194, 73, 196, 74, 198, 75, 200, 76, 202, 77, 204, 78, 206, 79, 208, 80, 210, 81, 212, 82, 214, 83, 216, 84, 218, 85, 220, 86, 222, 87, 224, 88, 226, 89, 228, 90, 230, 91, 232, 92, 234, 93, 236, 94, 238, 95, 240, 96, 242, 97, 244, 98, 246, 99, 248, 100, 250, 101, 252, 102, 254, 103, 256, 104, 258, 105, 260, 106, 262, 107, 264, 108, 266, 109, 268, 110, 270, 111, 272, 112, 274, 113, 276, 114, 278, 115, 280, 116, 282, 117, 284, 118, 286, 119, 288, 120, 290, 121, 292, 122, 294, 123, 296, 124, 298, 125, 300, 126, 302, 127, 304, 128, 306, 129, 308, 130, 310, 131, 312, 132, 314, 133, 316, 134, 318, 135, 320, 136, 322, 137, 324, 138, 326, 139, 328, 140, 330, 141, 332, 142, 334, 143, 336, 144, 338, 145, 340, 146, 342, 147, 344, 148, 346, 149, 348, 150, 350, 151, 352, 152, 354, 153, 4, 2, 3, 40, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 5, 2, 11, 11, 14, 14, 34, 34, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 59, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 3, 2, 36, 36, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 12, 2, 11, 12, 14, 15, 34, 34, 39, 40, 42, 47, 49, 49, 62, 64, 96, 96, 126, 126, 128, 128, 2, 1019, 2, 4, 3, 2, 2, 2, 2, 6, 3, 2, 2, 2, 2, 58, 3, 2, 2, 2, 2, 60, 3, 2, 2, 2, 2, 62, 3, 2, 2, 2, 2, 64, 3, 2, 2, 2, 2, 66, 3, 2, 2, 2, 2, 68, 3, 2, 2, 2, 2, 70, 3, 2, 2, 2, 2, 72, 3, 2, 2, 2, 2, 74, 3, 2, 2, 2, 2, 76, 3, 2, 2, 2, 2, 78, 3, 2, 2, 2, 2, 80, 3, 2, 2, 2, 2, 82, 3, 2, 2, 2, 2, 84, 3, 2, 2, 2, 2, 86, 3, 2, 2, 2, 2, 88, 3, 2, 2, 2, 2, 90, 3, 2, 2, 2, 2, 92, 3, 2, 2, 2, 2, 94, 3, 2, 2, 2, 2, 96, 3, 2, 2, 2, 2, 98, 3, 2, 2, 2, 2, 100, 3, 2, 2, 2, 2, 102, 3, 2, 2, 2, 2, 104, 3, 2, 2, 2, 2, 106, 3, 2, 2, 2, 2, 108, 3, 2, 2, 2, 2, 110, 3, 2, 2, 2, 2, 112, 3, 2, 2, 2, 2, 114, 3, 2, 2, 2, 2, 116, 3, 2, 2, 2, 2, 118, 3, 2, 2, 2, 2, 120, 3, 2, 2, 2, 2, 122, 3, 2, 2, 2, 2, 124, 3, 2, 2, 2, 2, 126, 3, 2, 2, 2, 2, 128, 3, 2, 2, 2, 2, 130, 3, 2, 2, 2, 2, 132, 3, 2, 2, 2, 2, 134, 3, 2, 2, 2, 2, 136, 3, 2, 2, 2, 2, 138, 3, 2, 2, 2, 2, 140, 3, 2, 2, 2, 2, 142, 3, 2, 2, 2, 2, 144, 3, 2, 2, 2, 2, 146, 3, 2, 2, 2, 2, 148, 3, 2, 2, 2, 2, 150, 3, 2, 2, 2, 2, 152, 3, 2, 2, 2, 2, 154, 3, 2, 2, 2, 2, 156, 3, 2, 2, 2, 2, 158, 3, 2, 2, 2, 2, 160, 3, 2, 2, 2, 2, 162, 3, 2, 2, 2, 2, 164, 3, 2, 2, 2, 2, 166, 3, 2, 2, 2, 2, 168, 3, 2, 2, 2, 2, 170, 3, 2, 2, 2, 2, 172, 3, 2, 2, 2, 2, 174, 3, 2, 2, 2, 2, 176, 3, 2, 2, 2, 2, 178, 3, 2, 2, 2, 2, 180, 3, 2, 2, 2, 2, 182, 3, 2, 2, 2, 2, 184, 3, 2, 2, 2, 2, 186, 3, 2, 2, 2, 2, 188, 3, 2, 2, 2, 2, 190, 3, 2, 2, 2, 2, 192, 3, 2, 2, 2, 2, 214, 3, 2, 2, 2, 2, 216, 3, 2, 2, 2, 2, 218, 3, 2, 2, 2, 2, 220, 3, 2, 2, 2, 2, 222, 3, 2, 2, 2, 2, 224, 3, 2, 2, 2, 2, 226, 3, 2, 2, 2, 2, 228, 3, 2, 2, 2, 2, 230, 3, 2, 2, 2, 2, 232, 3, 2, 2, 2, 2, 234, 3, 2, 2, 2, 2, 236, 3, 2, 2, 2, 2, 238, 3, 2, 2, 2, 2, 240, 3, 2, 2, 2, 2, 242, 3, 2, 2, 2, 2, 244, 3, 2, 2, 2, 2, 246, 3, 2, 2, 2, 2, 248, 3, 2, 2, 2, 2, 250, 3, 2, 2, 2, 2, 252, 3, 2, 2, 2, 2, 254, 3, 2, 2, 2, 2, 256, 3, 2, 2, 2, 2, 258, 3, 2, 2, 2, 2, 260, 3, 2, 2, 2, 2, 262, 3, 2, 2, 2, 2, 264, 3, 2, 2, 2, 2, 266, 3, 2, 2, 2, 2, 268, 3, 2, 2, 2, 2, 270, 3, 2, 2, 2, 2, 272, 3, 2, 2, 2, 2, 274, 3, 2, 2, 2, 2, 276, 3, 2, 2, 2, 2, 278, 3, 2, 2, 2, 2, 280, 3, 2, 2, 2, 2, 282, 3, 2, 2, 2, 2, 284, 3, 2, 2, 2, 2, 286, 3, 2, 2, 2, 2, 288, 3, 2, 2, 2, 2, 290, 3, 2, 2, 2, 2, 292, 3, 2, 2, 2, 2, 294, 3, 2, 2, 2, 2, 296, 3, 2, 2, 2, 2, 298, 3, 2, 2, 2, 2, 300, 3, 2, 2, 2, 2, 302, 3, 2, 2, 2, 2, 304, 3, 2, 2, 2, 2, 306, 3, 2, 2, 2, 2, 308, 3, 2, 2, 2, 2, 310, 3, 2, 2, 2, 2, 312, 3, 2, 2, 2, 2, 314, 3, 2, 2, 2, 2, 316, 3, 2, 2, 2, 2, 318, 3, 2, 2, 2, 2, 320, 3, 2, 2, 2, 2, 322, 3, 2, 2, 2, 2, 324, 3, 2, 2, 2, 2, 326, 3, 2, 2, 2, 2, 328, 3, 2, 2, 2, 2, 330, 3, 2, 2, 2, 2, 332, 3, 2, 2, 2, 2, 334, 3, 2, 2, 2, 2, 336, 3, 2, 2, 2, 2, 338, 3, 2, 2, 2, 2, 340, 3, 2, 2, 2, 2, 342, 3, 2, 2, 2, 2, 344, 3, 2, 2, 2, 2, 346, 3, 2, 2, 2, 2, 348, 3, 2, 2, 2, 2, 350, 3, 2, 2, 2, 2, 352, 3, 2, 2, 2, 2, 354, 3, 2, 2, 2, 3, 194, 3, 2, 2, 2, 3, 196, 3, 2, 2, 2, 3, 198, 3, 2, 2, 2, 3, 200, 3, 2, 2, 2, 3, 202, 3, 2, 2, 2, 3, 204, 3, 2, 2, 2, 3, 206, 3, 2, 2, 2, 3, 208, 3, 2, 2, 2, 3, 210, 3, 2, 2, 2, 3, 212, 3, 2, 2, 2, 4, 361, 3, 2, 2, 2, 6, 371, 3, 2, 2, 2, 8, 385, 3, 2, 2, 2, 10, 387, 3, 2, 2, 2, 12, 389, 3, 2, 2, 2, 14, 391, 3, 2, 2, 2, 16, 393, 3, 2, 2, 2, 18, 395, 3, 2, 2, 2, 20, 397, 3, 2, 2, 2, 22, 399, 3, 2, 2, 2, 24, 401, 3, 2, 2, 2, 26, 403, 3, 2, 2, 2, 28, 405, 3, 2, 2, 2, 30, 407, 3, 2, 2, 2, 32, 409, 3, 2, 2, 2, 34, 411, 3, 2, 2, 2, 36, 413, 3, 2, 2, 2, 38, 415, 3, 2, 2, 2, 40, 417, 3, 2, 2, 2, 42, 419, 3, 2, 2, 2, 44, 421, 3, 2, 2, 2, 46, 423, 3, 2, 2, 2, 48, 425, 3, 2, 2, 2, 50, 427, 3, 2, 2, 2, 52, 429, 3, 2, 2, 2, 54, 431, 3, 2, 2, 2, 56, 433, 3, 2, 2, 2, 58, 435, 3, 2, 2, 2, 60, 439, 3, 2, 2, 2, 62, 443, 3, 2, 2, 2, 64, 447, 3, 2, 2, 2, 66, 451, 3, 2, 2, 2, 68, 458, 3, 2, 2, 2, 70, 462, 3, 2, 2, 2, 72, 465, 3, 2, 2, 2, 74, 469, 3, 2, 2, 2, 76, 474, 3, 2, 2, 2, 78, 478, 3, 2, 2, 2, 80, 483, 3, 2, 2, 2, 82, 487, 3, 2, 2, 2, 84, 491, 3, 2, 2, 2, 86, 495, 3, 2, 2, 2, 88, 498, 3, 2, 2, 2, 90, 503, 3, 2, 2, 2, 92, 506, 3, 2, 2, 2, 94, 509, 3, 2, 2, 2, 96, 513, 3, 2, 2, 2, 98, 518, 3, 2, 2, 2, 100, 521, 3, 2, 2, 2, 102, 524, 3, 2, 2, 2, 104, 528, 3, 2, 2, 2, 106, 532, 3, 2, 2, 2, 108, 537, 3, 2, 2, 2, 110, 541, 3, 2, 2, 2, 112, 546, 3, 2, 2, 2, 114, 551, 3, 2, 2, 2, 116, 556, 3, 2, 2, 2, 118, 559, 3, 2, 2, 2, 120, 563, 3, 2, 2, 2, 122, 568, 3, 2, 2, 2, 124, 572, 3, 2, 2, 2, 126, 577, 3, 2, 2, 2, 128, 581, 3, 2, 2, 2, 130, 585, 3, 2, 2, 2, 132, 588, 3, 2, 2, 2, 134, 593, 3, 2, 2, 2, 136, 598, 3, 2, 2, 2, 138, 602, 3, 2, 2, 2, 140, 607, 3, 2, 2, 2, 142, 612, 3, 2, 2, 2, 144, 616, 3, 2, 2, 2, 146, 621, 3, 2, 2, 2, 148, 625, 3, 2, 2, 2, 150, 631, 3, 2, 2, 2, 152, 636, 3, 2, 2, 2, 154, 641, 3, 2, 2, 2, 156, 644, 3, 2, 2, 2, 158, 648, 3, 2, 2, 2, 160, 652, 3, 2, 2, 2, 162, 657, 3, 2, 2, 2, 164, 661, 3, 2, 2, 2, 166, 664, 3, 2, 2, 2, 168, 668, 3, 2, 2, 2, 170, 672, 3, 2, 2, 2, 172, 677, 3, 2, 2, 2, 174, 681, 3, 2, 2, 2, 176, 685, 3, 2, 2, 2, 178, 689, 3, 2, 2, 2, 180, 693, 3, 2, 2, 2, 182, 697, 3, 2, 2, 2, 184, 701, 3, 2, 2, 2, 186, 705, 3, 2, 2, 2, 188, 709, 3, 2, 2, 2, 190, 713, 3, 2, 2, 2, 192, 717, 3, 2, 2, 2, 194, 721, 3, 2, 2, 2, 196, 725, 3, 2, 2, 2, 198, 730, 3, 2, 2, 2, 200, 734, 3, 2, 2, 2, 202, 739, 3, 2, 2, 2, 204, 743, 3, 2, 2, 2, 206, 747, 3, 2, 2, 2, 208, 752, 3, 2, 2, 2, 210, 758, 3, 2, 2, 2, 212, 764, 3, 2, 2, 2, 214, 769, 3, 2, 2, 2, 216, 773, 3, 2, 2, 2, 218, 777, 3, 2, 2, 2, 220, 781, 3, 2, 2, 2, 222, 784, 3, 2, 2, 2, 224, 790, 3, 2, 2, 2, 226, 798, 3, 2, 2, 2, 228, 804, 3, 2, 2, 2, 230, 809, 3, 2, 2, 2, 232, 812, 3, 2, 2, 2, 234, 815, 3, 2, 2, 2, 236, 818, 3, 2, 2, 2, 238, 820, 3, 2, 2, 2, 240, 822, 3, 2, 2, 2, 242, 824, 3, 2, 2, 2, 244, 826, 3, 2, 2, 2, 246, 828, 3, 2, 2, 2, 248, 830, 3, 2, 2, 2, 250, 832, 3, 2, 2, 2, 252, 834, 3, 2, 2, 2, 254, 837, 3, 2, 2, 2, 256, 841, 3, 2, 2, 2, 258, 845, 3, 2, 2, 2, 260, 848, 3, 2, 2, 2, 262, 852, 3, 2, 2, 2, 264, 856, 3, 2, 2, 2, 266, 859, 3, 2, 2, 2, 268, 862, 3, 2, 2, 2, 270, 865, 3, 2, 2, 2, 272, 868, 3, 2, 2, 2, 274, 871, 3, 2, 2, 2, 276, 875, 3, 2, 2, 2, 278, 877, 3, 2, 2, 2, 280, 879, 3, 2, 2, 2, 282, 883, 3, 2, 2, 2, 284, 887, 3, 2, 2, 2, 286, 891, 3, 2, 2, 2, 288, 895, 3, 2, 2, 2, 290, 899, 3, 2, 2, 2, 292, 902, 3, 2, 2, 2, 294, 906, 3, 2, 2, 2, 296, 914, 3, 2, 2, 2, 298, 922, 3, 2, 2, 2, 300, 929, 3, 2, 2, 2, 302, 936, 3, 2, 2, 2, 304, 942, 3, 2, 2, 2, 306, 951, 3, 2, 2, 2, 308, 960, 3, 2, 2, 2, 310, 967, 3, 2, 2, 2, 312, 971, 3, 2, 2, 2, 314, 975, 3, 2, 2, 2, 316, 977, 3, 2, 2, 2, 318, 979, 3, 2, 2, 2, 320, 981, 3, 2, 2, 2, 322, 983, 3, 2, 2, 2, 324, 985, 3, 2, 2, 2, 326, 987, 3, 2, 2, 2, 328, 989, 3, 2, 2, 2, 330, 991, 3, 2, 2, 2, 332, 993, 3, 2, 2, 2, 334, 996, 3, 2, 2, 2, 336, 998, 3, 2, 2, 2, 338, 1001, 3, 2, 2, 2, 340, 1003, 3, 2, 2, 2, 342, 1006, 3, 2, 2, 2, 344, 1009, 3, 2, 2, 2, 346, 1011, 3, 2, 2, 2, 348, 1013, 3, 2, 2, 2, 350, 1015, 3, 2, 2, 2, 352, 1018, 3, 2, 2, 2, 354, 1025, 3, 2, 2, 2, 356, 357, 7, 49, 2, 2, 357, 362, 7, 49, 2, 2, 358, 359, 7, 47, 2, 2, 359, 362, 7, 47, 2, 2, 360, 362, 9, 2, 2, 2, 361, 356, 3, 2, 2, 2, 361, 358, 3, 2, 2, 2, 361, 360, 3, 2, 2, 2, 362, 366, 3, 2, 2, 2, 363, 365, 10, 3, 2, 2, 364, 363, 3, 2, 2, 2, 365, 368, 3, 2, 2, 2, 366, 364, 3, 2, 2, 2, 366, 367, 3, 2, 2, 2, 367, 369, 3, 2, 2, 2, 368, 366, 3, 2, 2, 2, 369, 370, 8, 2, 2, 2, 370, 5, 3, 2, 2, 2, 371, 372, 7, 49, 2, 2, 372, 373, 7, 44, 2, 2, 373, 377, 3, 2, 2, 2, 374, 376, 11, 2, 2, 2, 375, 374, 3, 2, 2, 2, 376, 379, 3, 2, 2, 2, 377, 378, 3, 2, 2, 2, 377, 375, 3, 2, 2, 2, 378, 380, 3, 2, 2, 2, 379, 377, 3, 2, 2, 2, 380, 381, 7, 44, 2, 2, 381, 382, 7, 49, 2, 2, 382, 383, 3, 2, 2, 2, 383, 384, 8, 3, 2, 2, 384, 7, 3, 2, 2, 2, 385, 386, 9, 4, 2, 2, 386, 9, 3, 2, 2, 2, 387, 388, 9, 5, 2, 2, 388, 11, 3, 2, 2, 2, 389, 390, 9, 6, 2, 2, 390, 13, 3, 2, 2, 2, 391, 392, 9, 7, 2, 2, 392, 15, 3, 2, 2, 2, 393, 394, 9, 8, 2, 2, 394, 17, 3, 2, 2, 2, 395, 396, 9, 9, 2, 2, 396, 19, 3, 2, 2, 2, 397, 398, 9, 10, 2, 2, 398, 21, 3, 2, 2, 2, 399, 400, 9, 11, 2, 2, 400, 23, 3, 2, 2, 2, 401, 402, 9, 12, 2, 2, 402, 25, 3, 2, 2, 2, 403, 404, 9, 13, 2, 2, 404, 27, 3, 2, 2, 2, 405, 406, 9, 14, 2, 2, 406, 29, 3, 2, 2, 2, 407, 408, 9, 15, 2, 2, 408, 31, 3, 2, 2, 2, 409, 410, 9, 16, 2, 2, 410, 33, 3, 2, 2, 2, 411, 412, 9, 17, 2, 2, 412, 35, 3, 2, 2, 2, 413, 414, 9, 18, 2, 2, 414, 37, 3, 2, 2, 2, 415, 416, 9, 19, 2, 2, 416, 39, 3, 2, 2, 2, 417, 418, 9, 20, 2, 2, 418, 41, 3, 2, 2, 2, 419, 420, 9, 21, 2, 2, 420, 43, 3, 2, 2, 2, 421, 422, 9, 22, 2, 2, 422, 45, 3, 2, 2, 2, 423, 424, 9, 23, 2, 2, 424, 47, 3, 2, 2, 2, 425, 426, 9, 24, 2, 2, 426, 49, 3, 2, 2, 2, 427, 428, 9, 25, 2, 2, 428, 51, 3, 2, 2, 2, 429, 430, 9, 26, 2, 2, 430, 53, 3, 2, 2, 2, 431, 432, 9, 27, 2, 2, 432, 55, 3, 2, 2, 2, 433, 434, 9, 28, 2, 2, 434, 57, 3, 2, 2, 2, 435, 436, 5, 8, 4, 2, 436, 437, 5, 14, 7, 2, 437, 438, 5, 12, 6, 2, 438, 59, 3, 2, 2, 2, 439, 440, 5, 8, 4, 2, 440, 441, 5, 14, 7, 2, 441, 442, 5, 14, 7, 2, 442, 61, 3, 2, 2, 2, 443, 444, 5, 8, 4, 2, 444, 445, 5, 32, 16, 2, 445, 446, 5, 14, 7, 2, 446, 63, 3, 2, 2, 2, 447, 448, 5, 10, 5, 2, 448, 449, 5, 24, 12, 2, 449, 450, 5, 44, 22, 2, 450, 65, 3, 2, 2, 2, 451, 452, 5, 12, 6, 2, 452, 453, 5, 8, 4, 2, 453, 454, 5, 28, 14, 2, 454, 455, 5, 28, 14, 2, 455, 456, 3, 2, 2, 2, 456, 457, 8, 33, 3, 2, 457, 67, 3, 2, 2, 2, 458, 459, 5, 12, 6, 2, 459, 460, 5, 12, 6, 2, 460, 461, 5, 18, 9, 2, 461, 69, 3, 2, 2, 2, 462, 463, 5, 12, 6, 2, 463, 464, 5, 36, 18, 2, 464, 71, 3, 2, 2, 2, 465, 466, 5, 12, 6, 2, 466, 467, 5, 36, 18, 2, 467, 468, 5, 14, 7, 2, 468, 73, 3, 2, 2, 2, 469, 470, 5, 12, 6, 2, 470, 471, 5, 36, 18, 2, 471, 472, 5, 14, 7, 2, 472, 473, 5, 40, 20, 2, 473, 75, 3, 2, 2, 2, 474, 475, 5, 12, 6, 2, 475, 476, 5, 36, 18, 2, 476, 477, 5, 24, 12, 2, 477, 77, 3, 2, 2, 2, 478, 479, 5, 12, 6, 2, 479, 480, 5, 36, 18, 2, 480, 481, 5, 24, 12, 2, 481, 482, 5, 40, 20, 2, 482, 79, 3, 2, 2, 2, 483, 484, 5, 12, 6, 2, 484, 485, 5, 36, 18, 2, 485, 486, 5, 28, 14, 2, 486, 81, 3, 2, 2, 2, 487, 488, 5, 14, 7, 2, 488, 489, 5, 8, 4, 2, 489, 490, 5, 8, 4, 2, 490, 83, 3, 2, 2, 2, 491, 492, 5, 14, 7, 2, 492, 493, 5, 16, 8, 2, 493, 494, 5, 12, 6, 2, 494, 85, 3, 2, 2, 2, 495, 496, 5, 14, 7, 2, 496, 497, 5, 24, 12, 2, 497, 87, 3, 2, 2, 2, 498, 499, 5, 14, 7, 2, 499, 500, 5, 26, 13, 2, 500, 501, 5, 32, 16, 2, 501, 502, 5, 56, 28, 2, 502, 89, 3, 2, 2, 2, 503, 504, 5, 16, 8, 2, 504, 505, 5, 24, 12, 2, 505, 91, 3, 2, 2, 2, 506, 507, 5, 16, 8, 2, 507, 508, 5, 52, 26, 2, 508, 93, 3, 2, 2, 2, 509, 510, 5, 16, 8, 2, 510, 511, 5, 52, 26, 2, 511, 512, 5, 52, 26, 2, 512, 95, 3, 2, 2, 2, 513, 514, 5, 22, 11, 2, 514, 515, 5, 8, 4, 2, 515, 516, 5, 28, 14, 2, 516, 517, 5, 44, 22, 2, 517, 97, 3, 2, 2, 2, 518, 519, 5, 24, 12, 2, 519, 520, 5, 30, 15, 2, 520, 99, 3, 2, 2, 2, 521, 522, 5, 24, 12, 2, 522, 523, 5, 32, 16, 2, 523, 101, 3, 2, 2, 2, 524, 525, 5, 24, 12, 2, 525, 526, 5, 32, 16, 2, 526, 527, 5, 12, 6, 2, 527, 103, 3, 2, 2, 2, 528, 529, 5, 24, 12, 2, 529, 530, 5, 32, 16, 2, 530, 531, 5, 14, 7, 2, 531, 105, 3, 2, 2, 2, 532, 533, 5, 24, 12, 2, 533, 534, 5, 32, 16, 2, 534, 535, 5, 14, 7, 2, 535, 536, 5, 40, 20, 2, 536, 107, 3, 2, 2, 2, 537, 538, 5, 24, 12, 2, 538, 539, 5, 32, 16, 2, 539, 540, 5, 24, 12, 2, 540, 109, 3, 2, 2, 2, 541, 542, 5, 24, 12, 2, 542, 543, 5, 32, 16, 2, 543, 544, 5, 24, 12, 2, 544, 545, 5, 40, 20, 2, 545, 111, 3, 2, 2, 2, 546, 547, 5, 26, 13, 2, 547, 548, 5, 36, 18, 2, 548, 549, 3, 2, 2, 2, 549, 550, 8, 56, 3, 2, 550, 113, 3, 2, 2, 2, 551, 552, 5, 26, 13, 2, 552, 553, 5, 40, 20, 2, 553, 554, 3, 2, 2, 2, 554, 555, 8, 57, 3, 2, 555, 115, 3, 2, 2, 2, 556, 557, 5, 28, 14, 2, 557, 558, 5, 14, 7, 2, 558, 117, 3, 2, 2, 2, 559, 560, 5, 28, 14, 2, 560, 561, 5, 14, 7, 2, 561, 562, 5, 14, 7, 2, 562, 119, 3, 2, 2, 2, 563, 564, 5, 28, 14, 2, 564, 565, 5, 14, 7, 2, 565, 566, 5, 14, 7, 2, 566, 567, 5, 40, 20, 2, 567, 121, 3, 2, 2, 2, 568, 569, 5, 28, 14, 2, 569, 570, 5, 14, 7, 2, 570, 571, 5, 24, 12, 2, 571, 123, 3, 2, 2, 2, 572, 573, 5, 28, 14, 2, 573, 574, 5, 14, 7, 2, 574, 575, 5, 24, 12, 2, 575, 576, 5, 40, 20, 2, 576, 125, 3, 2, 2, 2, 577, 578, 5, 32, 16, 2, 578, 579, 5, 16, 8, 2, 579, 580, 5, 20, 10, 2, 580, 127, 3, 2, 2, 2, 581, 582, 5, 32, 16, 2, 582, 583, 5, 34, 17, 2, 583, 584, 5, 36, 18, 2, 584, 129, 3, 2, 2, 2, 585, 586, 5, 34, 17, 2, 586, 587, 5, 40, 20, 2, 587, 131, 3, 2, 2, 2, 588, 589, 5, 34, 17, 2, 589, 590, 5, 44, 22, 2, 590, 591, 5, 14, 7, 2, 591, 592, 5, 40, 20, 2, 592, 133, 3, 2, 2, 2, 593, 594, 5, 34, 17, 2, 594, 595, 5, 44, 22, 2, 595, 596, 5, 24, 12, 2, 596, 597, 5, 40, 20, 2, 597, 135, 3, 2, 2, 2, 598, 599, 5, 34, 17, 2, 599, 600, 5, 46, 23, 2, 600, 601, 5, 44, 22, 2, 601, 137, 3, 2, 2, 2, 602, 603, 5, 34, 17, 2, 603, 604, 5, 46, 23, 2, 604, 605, 5, 44, 22, 2, 605, 606, 5, 14, 7, 2, 606, 139, 3, 2, 2, 2, 607, 608, 5, 34, 17, 2, 608, 609, 5, 46, 23, 2, 609, 610, 5, 44, 22, 2, 610, 611, 5, 24, 12, 2, 611, 141, 3, 2, 2, 2, 612, 613, 5, 36, 18, 2, 613, 614, 5, 34, 17, 2, 614, 615, 5, 36, 18, 2, 615, 143, 3, 2, 2, 2, 616, 617, 5, 36, 18, 2, 617, 618, 5, 46, 23, 2, 618, 619, 5, 42, 21, 2, 619, 620, 5, 22, 11, 2, 620, 145, 3, 2, 2, 2, 621, 622, 5, 40, 20, 2, 622, 623, 5, 16, 8, 2, 623, 624, 5, 42, 21, 2, 624, 147, 3, 2, 2, 2, 625, 626, 5, 40, 20, 2, 626, 627, 5, 16, 8, 2, 627, 628, 5, 44, 22, 2, 628, 629, 3, 2, 2, 2, 629, 630, 8, 74, 3, 2, 630, 149, 3, 2, 2, 2, 631, 632, 5, 40, 20, 2, 632, 633, 5, 16, 8, 2, 633, 634, 5, 44, 22, 2, 634, 635, 5, 24, 12, 2, 635, 151, 3, 2, 2, 2, 636, 637, 5, 40, 20, 2, 637, 638, 5, 16, 8, 2, 638, 639, 5, 44, 22, 2, 639, 640, 5, 32, 16, 2, 640, 153, 3, 2, 2, 2, 641, 642, 5, 40, 20, 2, 642, 643, 5, 28, 14, 2, 643, 155, 3, 2, 2, 2, 644, 645, 5, 40, 20, 2, 645, 646, 5, 28, 14, 2, 646, 647, 5, 8, 4, 2, 647, 157, 3, 2, 2, 2, 648, 649, 5, 40, 20, 2, 649, 650, 5, 28, 14, 2, 650, 651, 5, 12, 6, 2, 651, 159, 3, 2, 2, 2, 652, 653, 5, 40, 20, 2, 653, 654, 5, 28, 14, 2, 654, 655, 5, 12, 6, 2, 655, 656, 5, 8, 4, 2, 656, 161, 3, 2, 2, 2, 657, 658, 5, 40, 20, 2, 658, 659, 5, 28, 14, 2, 659, 660, 5, 14, 7, 2, 660, 163, 3, 2, 2, 2, 661, 662, 5, 40, 20, 2, 662, 663, 5, 40, 20, 2, 663, 165, 3, 2, 2, 2, 664, 665, 5, 40, 20, 2, 665, 666, 5, 40, 20, 2, 666, 667, 5, 8, 4, 2, 667, 167, 3, 2, 2, 2, 668, 669, 5, 40, 20, 2, 669, 670, 5, 40, 20, 2, 670, 671, 5, 12, 6, 2, 671, 169, 3, 2, 2, 2, 672, 673, 5, 40, 20, 2, 673, 674, 5, 40, 20, 2, 674, 675, 5, 12, 6, 2, 675, 676, 5, 8, 4, 2, 676, 171, 3, 2, 2, 2, 677, 678, 5, 40, 20, 2, 678, 679, 5, 40, 20, 2, 679, 680, 5, 14, 7, 2, 680, 173, 3, 2, 2, 2, 681, 682, 5, 40, 20, 2, 682, 683, 5, 42, 21, 2, 683, 684, 5, 44, 22, 2, 684, 175, 3, 2, 2, 2, 685, 686, 5, 42, 21, 2, 686, 687, 5, 10, 5, 2, 687, 688, 5, 12, 6, 2, 688, 177, 3, 2, 2, 2, 689, 690, 5, 42, 21, 2, 690, 691, 5, 12, 6, 2, 691, 692, 5, 18, 9, 2, 692, 179, 3, 2, 2, 2, 693, 694, 5, 42, 21, 2, 694, 695, 5, 16, 8, 2, 695, 696, 5, 44, 22, 2, 696, 181, 3, 2, 2, 2, 697, 698, 5, 42, 21, 2, 698, 699, 5, 28, 14, 2, 699, 700, 5, 8, 4, 2, 700, 183, 3, 2, 2, 2, 701, 702, 5, 42, 21, 2, 702, 703, 5, 40, 20, 2, 703, 704, 5, 8, 4, 2, 704, 185, 3, 2, 2, 2, 705, 706, 5, 42, 21, 2, 706, 707, 5, 28, 14, 2, 707, 708, 5, 28, 14, 2, 708, 187, 3, 2, 2, 2, 709, 710, 5, 42, 21, 2, 710, 711, 5, 40, 20, 2, 711, 712, 5, 28, 14, 2, 712, 189, 3, 2, 2, 2, 713, 714, 5, 42, 21, 2, 714, 715, 5, 46, 23, 2, 715, 716, 5, 10, 5, 2, 716, 191, 3, 2, 2, 2, 717, 718, 5, 52, 26, 2, 718, 719, 5, 34, 17, 2, 719, 720, 5, 40, 20, 2, 720, 193, 3, 2, 2, 2, 721, 722, 5, 12, 6, 2, 722, 723, 3, 2, 2, 2, 723, 724, 8, 97, 4, 2, 724, 195, 3, 2, 2, 2, 725, 726, 5, 32, 16, 2, 726, 727, 5, 12, 6, 2, 727, 728, 3, 2, 2, 2, 728, 729, 8, 98, 4, 2, 729, 197, 3, 2, 2, 2, 730, 731, 5, 56, 28, 2, 731, 732, 3, 2, 2, 2, 732, 733, 8, 99, 4, 2, 733, 199, 3, 2, 2, 2, 734, 735, 5, 32, 16, 2, 735, 736, 5, 56, 28, 2, 736, 737, 3, 2, 2, 2, 737, 738, 8, 100, 4, 2, 738, 201, 3, 2, 2, 2, 739, 740, 5, 30, 15, 2, 740, 741, 3, 2, 2, 2, 741, 742, 8, 101, 4, 2, 742, 203, 3, 2, 2, 2, 743, 744, 5, 36, 18, 2, 744, 745, 3, 2, 2, 2, 745, 746, 8, 102, 4, 2, 746, 205, 3, 2, 2, 2, 747, 748, 5, 36, 18, 2, 748, 749, 5, 16, 8, 2, 749, 750, 3, 2, 2, 2, 750, 751, 8, 103, 4, 2, 751, 207, 3, 2, 2, 2, 752, 753, 5, 36, 18, 2, 753, 754, 5, 34, 17, 2, 754, 755, 3, 2, 2, 2, 755, 756, 8, 104, 4, 2, 756, 209, 3, 2, 2, 2, 757, 759, 9, 29, 2, 2, 758, 757, 3, 2, 2, 2, 759, 760, 3, 2, 2, 2, 760, 758, 3, 2, 2, 2, 760, 761, 3, 2, 2, 2, 761, 762, 3, 2, 2, 2, 762, 763, 8, 105, 2, 2, 763, 211, 3, 2, 2, 2, 764, 765, 6, 106, 2, 2, 765, 766, 3, 2, 2, 2, 766, 767, 8, 106, 4, 2, 767, 768, 8, 106, 5, 2, 768, 213, 3, 2, 2, 2, 769, 770, 5, 34, 17, 2, 770, 771, 5, 40, 20, 2, 771, 772, 5, 20, 10, 2, 772, 215, 3, 2, 2, 2, 773, 774, 5, 16, 8, 2, 774, 775, 5, 38, 19, 2, 775, 776, 5, 46, 23, 2, 776, 217, 3, 2, 2, 2, 777, 778, 5, 42, 21, 2, 778, 779, 5, 16, 8, 2, 779, 780, 5, 44, 22, 2, 780, 219, 3, 2, 2, 2, 781, 782, 5, 24, 12, 2, 782, 783, 5, 18, 9, 2, 783, 221, 3, 2, 2, 2, 784, 785, 5, 16, 8, 2, 785, 786, 5, 32, 16, 2, 786, 787, 5, 14, 7, 2, 787, 788, 5, 24, 12, 2, 788, 789, 5, 18, 9, 2, 789, 223, 3, 2, 2, 2, 790, 791, 5, 24, 12, 2, 791, 792, 5, 32, 16, 2, 792, 793, 5, 12, 6, 2, 793, 794, 5, 28, 14, 2, 794, 795, 5, 46, 23, 2, 795, 796, 5, 14, 7, 2, 796, 797, 5, 16, 8, 2, 797, 225, 3, 2, 2, 2, 798, 799, 5, 30, 15, 2, 799, 800, 5, 8, 4, 2, 800, 801, 5, 12, 6, 2, 801, 802, 5, 40, 20, 2, 802, 803, 5, 34, 17, 2, 803, 227, 3, 2, 2, 2, 804, 805, 5, 16, 8, 2, 805, 806, 5, 32, 16, 2, 806, 807, 5, 14, 7, 2, 807, 808, 5, 30, 15, 2, 808, 229, 3, 2, 2, 2, 809, 810, 5, 14, 7, 2, 810, 811, 5, 10, 5, 2, 811, 231, 3, 2, 2, 2, 812, 813, 5, 14, 7, 2, 813, 814, 5, 50, 25, 2, 814, 233, 3, 2, 2, 2, 815, 816, 5, 14, 7, 2, 816, 817, 5, 42, 21, 2, 817, 235, 3, 2, 2, 2, 818, 819, 7, 38, 2, 2, 819, 237, 3, 2, 2, 2, 820, 821, 5, 8, 4, 2, 821, 239, 3, 2, 2, 2, 822, 823, 5, 10, 5, 2, 823, 241, 3, 2, 2, 2, 824, 825, 5, 12, 6, 2, 825, 243, 3, 2, 2, 2, 826, 827, 5, 14, 7, 2, 827, 245, 3, 2, 2, 2, 828, 829, 5, 16, 8, 2, 829, 247, 3, 2, 2, 2, 830, 831, 5, 22, 11, 2, 831, 249, 3, 2, 2, 2, 832, 833, 5, 28, 14, 2, 833, 251, 3, 2, 2, 2, 834, 835, 5, 24, 12, 2, 835, 836, 5, 52, 26, 2, 836, 253, 3, 2, 2, 2, 837, 838, 5, 24, 12, 2, 838, 839, 5, 52, 26, 2, 839, 840, 5, 22, 11, 2, 840, 255, 3, 2, 2, 2, 841, 842, 5, 24, 12, 2, 842, 843, 5, 52, 26, 2, 843, 844, 5, 28, 14, 2, 844, 257, 3, 2, 2, 2, 845, 846, 5, 24, 12, 2, 846, 847, 5, 54, 27, 2, 847, 259, 3, 2, 2, 2, 848, 849, 5, 24, 12, 2, 849, 850, 5, 54, 27, 2, 850, 851, 5, 22, 11, 2, 851, 261, 3, 2, 2, 2, 852, 853, 5, 24, 12, 2, 853, 854, 5, 54, 27, 2, 854, 855, 5, 28, 14, 2, 855, 263, 3, 2, 2, 2, 856, 857, 5, 10, 5, 2, 857, 858, 5, 12, 6, 2, 858, 265, 3, 2, 2, 2, 859, 860, 5, 14, 7, 2, 860, 861, 5, 16, 8, 2, 861, 267, 3, 2, 2, 2, 862, 863, 5, 22, 11, 2, 863, 864, 5, 28, 14, 2, 864, 269, 3, 2, 2, 2, 865, 866, 5, 42, 21, 2, 866, 867, 5, 36, 18, 2, 867, 271, 3, 2, 2, 2, 868, 869, 5, 8, 4, 2, 869, 870, 5, 18, 9, 2, 870, 273, 3, 2, 2, 2, 871, 872, 5, 8, 4, 2, 872, 873, 5, 18, 9, 2, 873, 874, 7, 41, 2, 2, 874, 275, 3, 2, 2, 2, 875, 876, 5, 24, 12, 2, 876, 277, 3, 2, 2, 2, 877, 878, 5, 40, 20, 2, 878, 279, 3, 2, 2, 2, 879, 880, 5, 30, 15, 2, 880, 881, 5, 34, 17, 2, 881, 882, 5, 14, 7, 2, 882, 281, 3, 2, 2, 2, 883, 884, 5, 42, 21, 2, 884, 885, 5, 22, 11, 2, 885, 886, 5, 40, 20, 2, 886, 283, 3, 2, 2, 2, 887, 888, 5, 42, 21, 2, 888, 889, 5, 22, 11, 2, 889, 890, 5, 28, 14, 2, 890, 285, 3, 2, 2, 2, 891, 892, 5, 32, 16, 2, 892, 893, 5, 34, 17, 2, 893, 894, 5, 44, 22, 2, 894, 287, 3, 2, 2, 2, 895, 896, 5, 8, 4, 2, 896, 897, 5, 32, 16, 2, 897, 898, 5, 14, 7, 2, 898, 289, 3, 2, 2, 2, 899, 900, 5, 34, 17, 2, 900, 901, 5, 40, 20, 2, 901, 291, 3, 2, 2, 2, 902, 903, 5, 52, 26, 2, 903, 904, 5, 34, 17, 2, 904, 905, 5, 40, 20, 2, 905, 293, 3, 2, 2, 2, 906, 907, 7, 50, 2, 2, 907, 909, 5, 52, 26, 2, 908, 910, 9, 30, 2, 2, 909, 908, 3, 2, 2, 2, 910, 911, 3, 2, 2, 2, 911, 909, 3, 2, 2, 2, 911, 912, 3, 2, 2, 2, 912, 295, 3, 2, 2, 2, 913, 915, 9, 31, 2, 2, 914, 913, 3, 2, 2, 2, 915, 916, 3, 2, 2, 2, 916, 914, 3, 2, 2, 2, 916, 917, 3, 2, 2, 2, 917, 919, 3, 2, 2, 2, 918, 920, 5, 14, 7, 2, 919, 918, 3, 2, 2, 2, 919, 920, 3, 2, 2, 2, 920, 297, 3, 2, 2, 2, 921, 923, 9, 30, 2, 2, 922, 921, 3, 2, 2, 2, 923, 924, 3, 2, 2, 2, 924, 922, 3, 2, 2, 2, 924, 925, 3, 2, 2, 2, 925, 926, 3, 2, 2, 2, 926, 927, 5, 22, 11, 2, 927, 299, 3, 2, 2, 2, 928, 930, 9, 32, 2, 2, 929, 928, 3, 2, 2, 2, 930, 931, 3, 2, 2, 2, 931, 929, 3, 2, 2, 2, 931, 932, 3, 2, 2, 2, 932, 933, 3, 2, 2, 2, 933, 934, 9, 33, 2, 2, 934, 301, 3, 2, 2, 2, 935, 937, 9, 34, 2, 2, 936, 935, 3, 2, 2, 2, 937, 938, 3, 2, 2, 2, 938, 936, 3, 2, 2, 2, 938, 939, 3, 2, 2, 2, 939, 940, 3, 2, 2, 2, 940, 941, 5, 10, 5, 2, 941, 303, 3, 2, 2, 2, 942, 946, 7, 41, 2, 2, 943, 945, 10, 35, 2, 2, 944, 943, 3, 2, 2, 2, 945, 948, 3, 2, 2, 2, 946, 944, 3, 2, 2, 2, 946, 947, 3, 2, 2, 2, 947, 949, 3, 2, 2, 2, 948, 946, 3, 2, 2, 2, 949, 950, 7, 41, 2, 2, 950, 305, 3, 2, 2, 2, 951, 955, 7, 36, 2, 2, 952, 954, 10, 36, 2, 2, 953, 952, 3, 2, 2, 2, 954, 957, 3, 2, 2, 2, 955, 953, 3, 2, 2, 2, 955, 956, 3, 2, 2, 2, 956, 958, 3, 2, 2, 2, 957, 955, 3, 2, 2, 2, 958, 959, 7, 36, 2, 2, 959, 307, 3, 2, 2, 2, 960, 964, 9, 37, 2, 2, 961, 963, 9, 38, 2, 2, 962, 961, 3, 2, 2, 2, 963, 966, 3, 2, 2, 2, 964, 962, 3, 2, 2, 2, 964, 965, 3, 2, 2, 2, 965, 309, 3, 2, 2, 2, 966, 964, 3, 2, 2, 2, 967, 968, 5, 308, 154, 2, 968, 969, 7, 60, 2, 2, 969, 311, 3, 2, 2, 2, 970, 972, 10, 39, 2, 2, 971, 970, 3, 2, 2, 2, 972, 973, 3, 2, 2, 2, 973, 971, 3, 2, 2, 2, 973, 974, 3, 2, 2, 2, 974, 313, 3, 2, 2, 2, 975, 976, 7, 42, 2, 2, 976, 315, 3, 2, 2, 2, 977, 978, 7, 43, 2, 2, 978, 317, 3, 2, 2, 2, 979, 980, 7, 46, 2, 2, 980, 319, 3, 2, 2, 2, 981, 982, 7, 45, 2, 2, 982, 321, 3, 2, 2, 2, 983, 984, 7, 47, 2, 2, 984, 323, 3, 2, 2, 2, 985, 986, 7, 44, 2, 2, 986, 325, 3, 2, 2, 2, 987, 988, 7, 49, 2, 2, 988, 327, 3, 2, 2, 2, 989, 990, 7, 63, 2, 2, 990, 329, 3, 2, 2, 2, 991, 992, 7, 64, 2, 2, 992, 331, 3, 2, 2, 2, 993, 994, 7, 64, 2, 2, 994, 995, 7, 63, 2, 2, 995, 333, 3, 2, 2, 2, 996, 997, 7, 62, 2, 2, 997, 335, 3, 2, 2, 2, 998, 999, 7, 62, 2, 2, 999, 1000, 7, 63, 2, 2, 1000, 337, 3, 2, 2, 2, 1001, 1002, 7, 39, 2, 2, 1002, 339, 3, 2, 2, 2, 1003, 1004, 7, 64, 2, 2, 1004, 1005, 7, 64, 2, 2, 1005, 341, 3, 2, 2, 2, 1006, 1007, 7, 62, 2, 2, 1007, 1008, 7, 62, 2, 2, 1008, 343, 3, 2, 2, 2, 1009, 1010, 7, 128, 2, 2, 1010, 345, 3, 2, 2, 2, 1011, 1012, 7, 40, 2, 2, 1012, 347, 3, 2, 2, 2, 1013, 1014, 7, 126, 2, 2, 1014, 349, 3, 2, 2, 2, 1015, 1016, 7, 96, 2, 2, 1016, 351, 3, 2, 2, 2, 1017, 1019, 9, 29, 2, 2, 1018, 1017, 3, 2, 2, 2, 1019, 1020, 3, 2, 2, 2, 1020, 1018, 3, 2, 2, 2, 1020, 1021, 3, 2, 2, 2, 1021, 1022, 3, 2, 2, 2, 1022, 1023, 8, 176, 2, 2, 1023, 353, 3, 2, 2, 2, 1024, 1026, 7, 15, 2, 2, 1025, 1024, 3, 2, 2, 2, 1025, 1026, 3, 2, 2, 2, 1026, 1027, 3, 2, 2, 2, 1027, 1028, 7, 12, 2, 2, 1028, 355, 3, 2, 2, 2, 20, 2, 3, 361, 366, 377, 760, 911, 916, 919, 924, 931, 938, 946, 955, 964, 973, 1020, 1025, 6, 8, 2, 2, 7, 3, 2, 6, 2, 2, 2, 3, 2] \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java new file mode 100644 index 000000000..e06dd4877 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java @@ -0,0 +1,593 @@ +// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 by ANTLR 4.9.2 +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class AsZ80Lexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.9.2", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + COMMENT=1, COMMENT2=2, OPCODE_ADC=3, OPCODE_ADD=4, OPCODE_AND=5, OPCODE_BIT=6, + OPCODE_CALL=7, OPCODE_CCF=8, OPCODE_CP=9, OPCODE_CPD=10, OPCODE_CPDR=11, + OPCODE_CPI=12, OPCODE_CPIR=13, OPCODE_CPL=14, OPCODE_DAA=15, OPCODE_DEC=16, + OPCODE_DI=17, OPCODE_DJNZ=18, OPCODE_EI=19, OPCODE_EX=20, OPCODE_EXX=21, + OPCODE_HALT=22, OPCODE_IM=23, OPCODE_IN=24, OPCODE_INC=25, OPCODE_IND=26, + OPCODE_INDR=27, OPCODE_INI=28, OPCODE_INIR=29, OPCODE_JP=30, OPCODE_JR=31, + OPCODE_LD=32, OPCODE_LDD=33, OPCODE_LDDR=34, OPCODE_LDI=35, OPCODE_LDIR=36, + OPCODE_NEG=37, OPCODE_NOP=38, OPCODE_OR=39, OPCODE_OTDR=40, OPCODE_OTIR=41, + OPCODE_OUT=42, OPCODE_OUTD=43, OPCODE_OUTI=44, OPCODE_POP=45, OPCODE_PUSH=46, + OPCODE_RES=47, OPCODE_RET=48, OPCODE_RETI=49, OPCODE_RETN=50, OPCODE_RL=51, + OPCODE_RLA=52, OPCODE_RLC=53, OPCODE_RLCA=54, OPCODE_RLD=55, OPCODE_RR=56, + OPCODE_RRA=57, OPCODE_RRC=58, OPCODE_RRCA=59, OPCODE_RRD=60, OPCODE_RST=61, + OPCODE_SBC=62, OPCODE_SCF=63, OPCODE_SET=64, OPCODE_SLA=65, OPCODE_SRA=66, + OPCODE_SLL=67, OPCODE_SRL=68, OPCODE_SUB=69, OPCODE_XOR=70, COND_C=71, + COND_NC=72, COND_Z=73, COND_NZ=74, COND_M=75, COND_P=76, COND_PE=77, COND_PO=78, + COND_WS=79, COND_UNRECOGNIZED=80, PREP_ORG=81, PREP_EQU=82, PREP_SET=83, + PREP_IF=84, PREP_ENDIF=85, PREP_INCLUDE=86, PREP_MACRO=87, PREP_ENDM=88, + PREP_DB=89, PREP_DW=90, PREP_DS=91, PREP_ADDR=92, REG_A=93, REG_B=94, + REG_C=95, REG_D=96, REG_E=97, REG_H=98, REG_L=99, REG_IX=100, REG_IXH=101, + REG_IXL=102, REG_IY=103, REG_IYH=104, REG_IYL=105, REG_BC=106, REG_DE=107, + REG_HL=108, REG_SP=109, REG_AF=110, REG_AFF=111, REG_I=112, REG_R=113, + OP_MOD=114, OP_SHR=115, OP_SHL=116, OP_NOT=117, OP_AND=118, OP_OR=119, + OP_XOR=120, LIT_HEXNUMBER_1=121, LIT_NUMBER=122, LIT_HEXNUMBER_2=123, + LIT_OCTNUMBER=124, LIT_BINNUMBER=125, LIT_STRING_1=126, LIT_STRING_2=127, + ID_IDENTIFIER=128, ID_LABEL=129, ERROR=130, SEP_LPAR=131, SEP_RPAR=132, + SEP_COMMA=133, OP_ADD=134, OP_SUBTRACT=135, OP_MULTIPLY=136, OP_DIVIDE=137, + OP_EQUAL=138, OP_GT=139, OP_GTE=140, OP_LT=141, OP_LTE=142, OP_MOD_2=143, + OP_SHR_2=144, OP_SHL_2=145, OP_NOT_2=146, OP_AND_2=147, OP_OR_2=148, OP_XOR_2=149, + WS=150, EOL=151; + public static final int + CONDITION=1; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE", "CONDITION" + }; + + private static String[] makeRuleNames() { + return new String[] { + "COMMENT", "COMMENT2", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", + "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", + "Z", "OPCODE_ADC", "OPCODE_ADD", "OPCODE_AND", "OPCODE_BIT", "OPCODE_CALL", + "OPCODE_CCF", "OPCODE_CP", "OPCODE_CPD", "OPCODE_CPDR", "OPCODE_CPI", + "OPCODE_CPIR", "OPCODE_CPL", "OPCODE_DAA", "OPCODE_DEC", "OPCODE_DI", + "OPCODE_DJNZ", "OPCODE_EI", "OPCODE_EX", "OPCODE_EXX", "OPCODE_HALT", + "OPCODE_IM", "OPCODE_IN", "OPCODE_INC", "OPCODE_IND", "OPCODE_INDR", + "OPCODE_INI", "OPCODE_INIR", "OPCODE_JP", "OPCODE_JR", "OPCODE_LD", "OPCODE_LDD", + "OPCODE_LDDR", "OPCODE_LDI", "OPCODE_LDIR", "OPCODE_NEG", "OPCODE_NOP", + "OPCODE_OR", "OPCODE_OTDR", "OPCODE_OTIR", "OPCODE_OUT", "OPCODE_OUTD", + "OPCODE_OUTI", "OPCODE_POP", "OPCODE_PUSH", "OPCODE_RES", "OPCODE_RET", + "OPCODE_RETI", "OPCODE_RETN", "OPCODE_RL", "OPCODE_RLA", "OPCODE_RLC", + "OPCODE_RLCA", "OPCODE_RLD", "OPCODE_RR", "OPCODE_RRA", "OPCODE_RRC", + "OPCODE_RRCA", "OPCODE_RRD", "OPCODE_RST", "OPCODE_SBC", "OPCODE_SCF", + "OPCODE_SET", "OPCODE_SLA", "OPCODE_SRA", "OPCODE_SLL", "OPCODE_SRL", + "OPCODE_SUB", "OPCODE_XOR", "COND_C", "COND_NC", "COND_Z", "COND_NZ", + "COND_M", "COND_P", "COND_PE", "COND_PO", "COND_WS", "COND_UNRECOGNIZED", + "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_IF", "PREP_ENDIF", "PREP_INCLUDE", + "PREP_MACRO", "PREP_ENDM", "PREP_DB", "PREP_DW", "PREP_DS", "PREP_ADDR", + "REG_A", "REG_B", "REG_C", "REG_D", "REG_E", "REG_H", "REG_L", "REG_IX", + "REG_IXH", "REG_IXL", "REG_IY", "REG_IYH", "REG_IYL", "REG_BC", "REG_DE", + "REG_HL", "REG_SP", "REG_AF", "REG_AFF", "REG_I", "REG_R", "OP_MOD", + "OP_SHR", "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", "OP_XOR", "LIT_HEXNUMBER_1", + "LIT_NUMBER", "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", "LIT_BINNUMBER", "LIT_STRING_1", + "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", "ERROR", "SEP_LPAR", "SEP_RPAR", + "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", + "OP_GT", "OP_GTE", "OP_LT", "OP_LTE", "OP_MOD_2", "OP_SHR_2", "OP_SHL_2", + "OP_NOT_2", "OP_AND_2", "OP_OR_2", "OP_XOR_2", "WS", "EOL" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, "'$'", null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, "'('", + "')'", "','", "'+'", "'-'", "'*'", "'/'", "'='", "'>'", "'>='", "'<'", + "'<='", "'%'", "'>>'", "'<<'", "'~'", "'&'", "'|'", "'^'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "COMMENT", "COMMENT2", "OPCODE_ADC", "OPCODE_ADD", "OPCODE_AND", + "OPCODE_BIT", "OPCODE_CALL", "OPCODE_CCF", "OPCODE_CP", "OPCODE_CPD", + "OPCODE_CPDR", "OPCODE_CPI", "OPCODE_CPIR", "OPCODE_CPL", "OPCODE_DAA", + "OPCODE_DEC", "OPCODE_DI", "OPCODE_DJNZ", "OPCODE_EI", "OPCODE_EX", "OPCODE_EXX", + "OPCODE_HALT", "OPCODE_IM", "OPCODE_IN", "OPCODE_INC", "OPCODE_IND", + "OPCODE_INDR", "OPCODE_INI", "OPCODE_INIR", "OPCODE_JP", "OPCODE_JR", + "OPCODE_LD", "OPCODE_LDD", "OPCODE_LDDR", "OPCODE_LDI", "OPCODE_LDIR", + "OPCODE_NEG", "OPCODE_NOP", "OPCODE_OR", "OPCODE_OTDR", "OPCODE_OTIR", + "OPCODE_OUT", "OPCODE_OUTD", "OPCODE_OUTI", "OPCODE_POP", "OPCODE_PUSH", + "OPCODE_RES", "OPCODE_RET", "OPCODE_RETI", "OPCODE_RETN", "OPCODE_RL", + "OPCODE_RLA", "OPCODE_RLC", "OPCODE_RLCA", "OPCODE_RLD", "OPCODE_RR", + "OPCODE_RRA", "OPCODE_RRC", "OPCODE_RRCA", "OPCODE_RRD", "OPCODE_RST", + "OPCODE_SBC", "OPCODE_SCF", "OPCODE_SET", "OPCODE_SLA", "OPCODE_SRA", + "OPCODE_SLL", "OPCODE_SRL", "OPCODE_SUB", "OPCODE_XOR", "COND_C", "COND_NC", + "COND_Z", "COND_NZ", "COND_M", "COND_P", "COND_PE", "COND_PO", "COND_WS", + "COND_UNRECOGNIZED", "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_IF", "PREP_ENDIF", + "PREP_INCLUDE", "PREP_MACRO", "PREP_ENDM", "PREP_DB", "PREP_DW", "PREP_DS", + "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", "REG_E", "REG_H", "REG_L", + "REG_IX", "REG_IXH", "REG_IXL", "REG_IY", "REG_IYH", "REG_IYL", "REG_BC", + "REG_DE", "REG_HL", "REG_SP", "REG_AF", "REG_AFF", "REG_I", "REG_R", + "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", "OP_XOR", + "LIT_HEXNUMBER_1", "LIT_NUMBER", "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", + "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", + "ERROR", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", + "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_GT", "OP_GTE", "OP_LT", "OP_LTE", + "OP_MOD_2", "OP_SHR_2", "OP_SHL_2", "OP_NOT_2", "OP_AND_2", "OP_OR_2", + "OP_XOR_2", "WS", "EOL" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public AsZ80Lexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "AsZ80Lexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + @Override + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 104: + return COND_UNRECOGNIZED_sempred((RuleContext)_localctx, predIndex); + } + return true; + } + private boolean COND_UNRECOGNIZED_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return true; + } + return true; + } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u0099\u0405\b\1\b"+ + "\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n"+ + "\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21"+ + "\4\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30"+ + "\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37"+ + "\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t"+ + "*\4+\t+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63"+ + "\4\64\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t"+ + "<\4=\t=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4"+ + "H\tH\4I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\t"+ + "S\4T\tT\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^"+ + "\4_\t_\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j"+ + "\tj\4k\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu"+ + "\4v\tv\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080"+ + "\t\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084"+ + "\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089"+ + "\t\u0089\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c\t\u008c\4\u008d\t\u008d"+ + "\4\u008e\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090\4\u0091\t\u0091\4\u0092"+ + "\t\u0092\4\u0093\t\u0093\4\u0094\t\u0094\4\u0095\t\u0095\4\u0096\t\u0096"+ + "\4\u0097\t\u0097\4\u0098\t\u0098\4\u0099\t\u0099\4\u009a\t\u009a\4\u009b"+ + "\t\u009b\4\u009c\t\u009c\4\u009d\t\u009d\4\u009e\t\u009e\4\u009f\t\u009f"+ + "\4\u00a0\t\u00a0\4\u00a1\t\u00a1\4\u00a2\t\u00a2\4\u00a3\t\u00a3\4\u00a4"+ + "\t\u00a4\4\u00a5\t\u00a5\4\u00a6\t\u00a6\4\u00a7\t\u00a7\4\u00a8\t\u00a8"+ + "\4\u00a9\t\u00a9\4\u00aa\t\u00aa\4\u00ab\t\u00ab\4\u00ac\t\u00ac\4\u00ad"+ + "\t\u00ad\4\u00ae\t\u00ae\4\u00af\t\u00af\4\u00b0\t\u00b0\4\u00b1\t\u00b1"+ + "\3\2\3\2\3\2\3\2\3\2\5\2\u016a\n\2\3\2\7\2\u016d\n\2\f\2\16\2\u0170\13"+ + "\2\3\2\3\2\3\3\3\3\3\3\3\3\7\3\u0178\n\3\f\3\16\3\u017b\13\3\3\3\3\3\3"+ + "\3\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13"+ + "\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3\22\3\22"+ + "\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\31\3\31"+ + "\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36"+ + "\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\""+ + "\3#\3#\3#\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3"+ + "(\3(\3(\3(\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3+\3,\3,\3,\3,\3,\3-\3-\3-\3"+ + ".\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\3\61\3\61\3\61\3\62\3\62"+ + "\3\62\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\65\3\65\3\65\3\65\3\65"+ + "\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\3\67\38\38\38\38\38\39\39\39"+ + "\39\39\3:\3:\3:\3;\3;\3;\3;\3<\3<\3<\3<\3<\3=\3=\3=\3=\3>\3>\3>\3>\3>"+ + "\3?\3?\3?\3?\3@\3@\3@\3@\3A\3A\3A\3B\3B\3B\3B\3B\3C\3C\3C\3C\3C\3D\3D"+ + "\3D\3D\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I"+ + "\3I\3I\3J\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3M\3M\3M\3N\3N"+ + "\3N\3N\3O\3O\3O\3O\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3R\3R\3R\3S\3S\3S\3S\3T"+ + "\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3V\3V\3W\3W\3W\3W\3X\3X\3X\3X\3Y\3Y\3Y"+ + "\3Y\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3]\3]\3]\3]\3^\3^\3^\3^\3"+ + "_\3_\3_\3_\3`\3`\3`\3`\3a\3a\3a\3a\3b\3b\3b\3b\3b\3c\3c\3c\3c\3d\3d\3"+ + "d\3d\3d\3e\3e\3e\3e\3f\3f\3f\3f\3g\3g\3g\3g\3g\3h\3h\3h\3h\3h\3i\6i\u02f7"+ + "\ni\ri\16i\u02f8\3i\3i\3j\3j\3j\3j\3j\3k\3k\3k\3k\3l\3l\3l\3l\3m\3m\3"+ + "m\3m\3n\3n\3n\3o\3o\3o\3o\3o\3o\3p\3p\3p\3p\3p\3p\3p\3p\3q\3q\3q\3q\3"+ + "q\3q\3r\3r\3r\3r\3r\3s\3s\3s\3t\3t\3t\3u\3u\3u\3v\3v\3w\3w\3x\3x\3y\3"+ + "y\3z\3z\3{\3{\3|\3|\3}\3}\3~\3~\3~\3\177\3\177\3\177\3\177\3\u0080\3\u0080"+ + "\3\u0080\3\u0080\3\u0081\3\u0081\3\u0081\3\u0082\3\u0082\3\u0082\3\u0082"+ + "\3\u0083\3\u0083\3\u0083\3\u0083\3\u0084\3\u0084\3\u0084\3\u0085\3\u0085"+ + "\3\u0085\3\u0086\3\u0086\3\u0086\3\u0087\3\u0087\3\u0087\3\u0088\3\u0088"+ + "\3\u0088\3\u0089\3\u0089\3\u0089\3\u0089\3\u008a\3\u008a\3\u008b\3\u008b"+ + "\3\u008c\3\u008c\3\u008c\3\u008c\3\u008d\3\u008d\3\u008d\3\u008d\3\u008e"+ + "\3\u008e\3\u008e\3\u008e\3\u008f\3\u008f\3\u008f\3\u008f\3\u0090\3\u0090"+ + "\3\u0090\3\u0090\3\u0091\3\u0091\3\u0091\3\u0092\3\u0092\3\u0092\3\u0092"+ + "\3\u0093\3\u0093\3\u0093\6\u0093\u038e\n\u0093\r\u0093\16\u0093\u038f"+ + "\3\u0094\6\u0094\u0393\n\u0094\r\u0094\16\u0094\u0394\3\u0094\5\u0094"+ + "\u0398\n\u0094\3\u0095\6\u0095\u039b\n\u0095\r\u0095\16\u0095\u039c\3"+ + "\u0095\3\u0095\3\u0096\6\u0096\u03a2\n\u0096\r\u0096\16\u0096\u03a3\3"+ + "\u0096\3\u0096\3\u0097\6\u0097\u03a9\n\u0097\r\u0097\16\u0097\u03aa\3"+ + "\u0097\3\u0097\3\u0098\3\u0098\7\u0098\u03b1\n\u0098\f\u0098\16\u0098"+ + "\u03b4\13\u0098\3\u0098\3\u0098\3\u0099\3\u0099\7\u0099\u03ba\n\u0099"+ + "\f\u0099\16\u0099\u03bd\13\u0099\3\u0099\3\u0099\3\u009a\3\u009a\7\u009a"+ + "\u03c3\n\u009a\f\u009a\16\u009a\u03c6\13\u009a\3\u009b\3\u009b\3\u009b"+ + "\3\u009c\6\u009c\u03cc\n\u009c\r\u009c\16\u009c\u03cd\3\u009d\3\u009d"+ + "\3\u009e\3\u009e\3\u009f\3\u009f\3\u00a0\3\u00a0\3\u00a1\3\u00a1\3\u00a2"+ + "\3\u00a2\3\u00a3\3\u00a3\3\u00a4\3\u00a4\3\u00a5\3\u00a5\3\u00a6\3\u00a6"+ + "\3\u00a6\3\u00a7\3\u00a7\3\u00a8\3\u00a8\3\u00a8\3\u00a9\3\u00a9\3\u00aa"+ + "\3\u00aa\3\u00aa\3\u00ab\3\u00ab\3\u00ab\3\u00ac\3\u00ac\3\u00ad\3\u00ad"+ + "\3\u00ae\3\u00ae\3\u00af\3\u00af\3\u00b0\6\u00b0\u03fb\n\u00b0\r\u00b0"+ + "\16\u00b0\u03fc\3\u00b0\3\u00b0\3\u00b1\5\u00b1\u0402\n\u00b1\3\u00b1"+ + "\3\u00b1\3\u0179\2\u00b2\4\3\6\4\b\2\n\2\f\2\16\2\20\2\22\2\24\2\26\2"+ + "\30\2\32\2\34\2\36\2 \2\"\2$\2&\2(\2*\2,\2.\2\60\2\62\2\64\2\66\28\2:"+ + "\5<\6>\7@\bB\tD\nF\13H\fJ\rL\16N\17P\20R\21T\22V\23X\24Z\25\\\26^\27`"+ + "\30b\31d\32f\33h\34j\35l\36n\37p r!t\"v#x$z%|&~\'\u0080(\u0082)\u0084"+ + "*\u0086+\u0088,\u008a-\u008c.\u008e/\u0090\60\u0092\61\u0094\62\u0096"+ + "\63\u0098\64\u009a\65\u009c\66\u009e\67\u00a08\u00a29\u00a4:\u00a6;\u00a8"+ + "<\u00aa=\u00ac>\u00ae?\u00b0@\u00b2A\u00b4B\u00b6C\u00b8D\u00baE\u00bc"+ + "F\u00beG\u00c0H\u00c2I\u00c4J\u00c6K\u00c8L\u00caM\u00ccN\u00ceO\u00d0"+ + "P\u00d2Q\u00d4R\u00d6S\u00d8T\u00daU\u00dcV\u00deW\u00e0X\u00e2Y\u00e4"+ + "Z\u00e6[\u00e8\\\u00ea]\u00ec^\u00ee_\u00f0`\u00f2a\u00f4b\u00f6c\u00f8"+ + "d\u00fae\u00fcf\u00feg\u0100h\u0102i\u0104j\u0106k\u0108l\u010am\u010c"+ + "n\u010eo\u0110p\u0112q\u0114r\u0116s\u0118t\u011au\u011cv\u011ew\u0120"+ + "x\u0122y\u0124z\u0126{\u0128|\u012a}\u012c~\u012e\177\u0130\u0080\u0132"+ + "\u0081\u0134\u0082\u0136\u0083\u0138\u0084\u013a\u0085\u013c\u0086\u013e"+ + "\u0087\u0140\u0088\u0142\u0089\u0144\u008a\u0146\u008b\u0148\u008c\u014a"+ + "\u008d\u014c\u008e\u014e\u008f\u0150\u0090\u0152\u0091\u0154\u0092\u0156"+ + "\u0093\u0158\u0094\u015a\u0095\u015c\u0096\u015e\u0097\u0160\u0098\u0162"+ + "\u0099\4\2\3(\4\2%%==\4\2\f\f\17\17\4\2CCcc\4\2DDdd\4\2EEee\4\2FFff\4"+ + "\2GGgg\4\2HHhh\4\2IIii\4\2JJjj\4\2KKkk\4\2LLll\4\2NNnn\4\2OOoo\4\2PPp"+ + "p\4\2QQqq\4\2RRrr\4\2SSss\4\2TTtt\4\2UUuu\4\2VVvv\4\2WWww\4\2XXxx\4\2"+ + "YYyy\4\2ZZzz\4\2[[{{\4\2\\\\||\5\2\13\13\16\16\"\"\5\2\62;CHch\3\2\62"+ + ";\3\2\629\6\2QQSSqqss\3\2\62\63\3\2))\3\2$$\5\2A\\aac|\6\2\62;A\\aac|"+ + "\f\2\13\f\16\17\"\"\'(*/\61\61>@``~~\u0080\u0080\2\u03fb\2\4\3\2\2\2\2"+ + "\6\3\2\2\2\2:\3\2\2\2\2<\3\2\2\2\2>\3\2\2\2\2@\3\2\2\2\2B\3\2\2\2\2D\3"+ + "\2\2\2\2F\3\2\2\2\2H\3\2\2\2\2J\3\2\2\2\2L\3\2\2\2\2N\3\2\2\2\2P\3\2\2"+ + "\2\2R\3\2\2\2\2T\3\2\2\2\2V\3\2\2\2\2X\3\2\2\2\2Z\3\2\2\2\2\\\3\2\2\2"+ + "\2^\3\2\2\2\2`\3\2\2\2\2b\3\2\2\2\2d\3\2\2\2\2f\3\2\2\2\2h\3\2\2\2\2j"+ + "\3\2\2\2\2l\3\2\2\2\2n\3\2\2\2\2p\3\2\2\2\2r\3\2\2\2\2t\3\2\2\2\2v\3\2"+ + "\2\2\2x\3\2\2\2\2z\3\2\2\2\2|\3\2\2\2\2~\3\2\2\2\2\u0080\3\2\2\2\2\u0082"+ + "\3\2\2\2\2\u0084\3\2\2\2\2\u0086\3\2\2\2\2\u0088\3\2\2\2\2\u008a\3\2\2"+ + "\2\2\u008c\3\2\2\2\2\u008e\3\2\2\2\2\u0090\3\2\2\2\2\u0092\3\2\2\2\2\u0094"+ + "\3\2\2\2\2\u0096\3\2\2\2\2\u0098\3\2\2\2\2\u009a\3\2\2\2\2\u009c\3\2\2"+ + "\2\2\u009e\3\2\2\2\2\u00a0\3\2\2\2\2\u00a2\3\2\2\2\2\u00a4\3\2\2\2\2\u00a6"+ + "\3\2\2\2\2\u00a8\3\2\2\2\2\u00aa\3\2\2\2\2\u00ac\3\2\2\2\2\u00ae\3\2\2"+ + "\2\2\u00b0\3\2\2\2\2\u00b2\3\2\2\2\2\u00b4\3\2\2\2\2\u00b6\3\2\2\2\2\u00b8"+ + "\3\2\2\2\2\u00ba\3\2\2\2\2\u00bc\3\2\2\2\2\u00be\3\2\2\2\2\u00c0\3\2\2"+ + "\2\2\u00d6\3\2\2\2\2\u00d8\3\2\2\2\2\u00da\3\2\2\2\2\u00dc\3\2\2\2\2\u00de"+ + "\3\2\2\2\2\u00e0\3\2\2\2\2\u00e2\3\2\2\2\2\u00e4\3\2\2\2\2\u00e6\3\2\2"+ + "\2\2\u00e8\3\2\2\2\2\u00ea\3\2\2\2\2\u00ec\3\2\2\2\2\u00ee\3\2\2\2\2\u00f0"+ + "\3\2\2\2\2\u00f2\3\2\2\2\2\u00f4\3\2\2\2\2\u00f6\3\2\2\2\2\u00f8\3\2\2"+ + "\2\2\u00fa\3\2\2\2\2\u00fc\3\2\2\2\2\u00fe\3\2\2\2\2\u0100\3\2\2\2\2\u0102"+ + "\3\2\2\2\2\u0104\3\2\2\2\2\u0106\3\2\2\2\2\u0108\3\2\2\2\2\u010a\3\2\2"+ + "\2\2\u010c\3\2\2\2\2\u010e\3\2\2\2\2\u0110\3\2\2\2\2\u0112\3\2\2\2\2\u0114"+ + "\3\2\2\2\2\u0116\3\2\2\2\2\u0118\3\2\2\2\2\u011a\3\2\2\2\2\u011c\3\2\2"+ + "\2\2\u011e\3\2\2\2\2\u0120\3\2\2\2\2\u0122\3\2\2\2\2\u0124\3\2\2\2\2\u0126"+ + "\3\2\2\2\2\u0128\3\2\2\2\2\u012a\3\2\2\2\2\u012c\3\2\2\2\2\u012e\3\2\2"+ + "\2\2\u0130\3\2\2\2\2\u0132\3\2\2\2\2\u0134\3\2\2\2\2\u0136\3\2\2\2\2\u0138"+ + "\3\2\2\2\2\u013a\3\2\2\2\2\u013c\3\2\2\2\2\u013e\3\2\2\2\2\u0140\3\2\2"+ + "\2\2\u0142\3\2\2\2\2\u0144\3\2\2\2\2\u0146\3\2\2\2\2\u0148\3\2\2\2\2\u014a"+ + "\3\2\2\2\2\u014c\3\2\2\2\2\u014e\3\2\2\2\2\u0150\3\2\2\2\2\u0152\3\2\2"+ + "\2\2\u0154\3\2\2\2\2\u0156\3\2\2\2\2\u0158\3\2\2\2\2\u015a\3\2\2\2\2\u015c"+ + "\3\2\2\2\2\u015e\3\2\2\2\2\u0160\3\2\2\2\2\u0162\3\2\2\2\3\u00c2\3\2\2"+ + "\2\3\u00c4\3\2\2\2\3\u00c6\3\2\2\2\3\u00c8\3\2\2\2\3\u00ca\3\2\2\2\3\u00cc"+ + "\3\2\2\2\3\u00ce\3\2\2\2\3\u00d0\3\2\2\2\3\u00d2\3\2\2\2\3\u00d4\3\2\2"+ + "\2\4\u0169\3\2\2\2\6\u0173\3\2\2\2\b\u0181\3\2\2\2\n\u0183\3\2\2\2\f\u0185"+ + "\3\2\2\2\16\u0187\3\2\2\2\20\u0189\3\2\2\2\22\u018b\3\2\2\2\24\u018d\3"+ + "\2\2\2\26\u018f\3\2\2\2\30\u0191\3\2\2\2\32\u0193\3\2\2\2\34\u0195\3\2"+ + "\2\2\36\u0197\3\2\2\2 \u0199\3\2\2\2\"\u019b\3\2\2\2$\u019d\3\2\2\2&\u019f"+ + "\3\2\2\2(\u01a1\3\2\2\2*\u01a3\3\2\2\2,\u01a5\3\2\2\2.\u01a7\3\2\2\2\60"+ + "\u01a9\3\2\2\2\62\u01ab\3\2\2\2\64\u01ad\3\2\2\2\66\u01af\3\2\2\28\u01b1"+ + "\3\2\2\2:\u01b3\3\2\2\2<\u01b7\3\2\2\2>\u01bb\3\2\2\2@\u01bf\3\2\2\2B"+ + "\u01c3\3\2\2\2D\u01ca\3\2\2\2F\u01ce\3\2\2\2H\u01d1\3\2\2\2J\u01d5\3\2"+ + "\2\2L\u01da\3\2\2\2N\u01de\3\2\2\2P\u01e3\3\2\2\2R\u01e7\3\2\2\2T\u01eb"+ + "\3\2\2\2V\u01ef\3\2\2\2X\u01f2\3\2\2\2Z\u01f7\3\2\2\2\\\u01fa\3\2\2\2"+ + "^\u01fd\3\2\2\2`\u0201\3\2\2\2b\u0206\3\2\2\2d\u0209\3\2\2\2f\u020c\3"+ + "\2\2\2h\u0210\3\2\2\2j\u0214\3\2\2\2l\u0219\3\2\2\2n\u021d\3\2\2\2p\u0222"+ + "\3\2\2\2r\u0227\3\2\2\2t\u022c\3\2\2\2v\u022f\3\2\2\2x\u0233\3\2\2\2z"+ + "\u0238\3\2\2\2|\u023c\3\2\2\2~\u0241\3\2\2\2\u0080\u0245\3\2\2\2\u0082"+ + "\u0249\3\2\2\2\u0084\u024c\3\2\2\2\u0086\u0251\3\2\2\2\u0088\u0256\3\2"+ + "\2\2\u008a\u025a\3\2\2\2\u008c\u025f\3\2\2\2\u008e\u0264\3\2\2\2\u0090"+ + "\u0268\3\2\2\2\u0092\u026d\3\2\2\2\u0094\u0271\3\2\2\2\u0096\u0277\3\2"+ + "\2\2\u0098\u027c\3\2\2\2\u009a\u0281\3\2\2\2\u009c\u0284\3\2\2\2\u009e"+ + "\u0288\3\2\2\2\u00a0\u028c\3\2\2\2\u00a2\u0291\3\2\2\2\u00a4\u0295\3\2"+ + "\2\2\u00a6\u0298\3\2\2\2\u00a8\u029c\3\2\2\2\u00aa\u02a0\3\2\2\2\u00ac"+ + "\u02a5\3\2\2\2\u00ae\u02a9\3\2\2\2\u00b0\u02ad\3\2\2\2\u00b2\u02b1\3\2"+ + "\2\2\u00b4\u02b5\3\2\2\2\u00b6\u02b9\3\2\2\2\u00b8\u02bd\3\2\2\2\u00ba"+ + "\u02c1\3\2\2\2\u00bc\u02c5\3\2\2\2\u00be\u02c9\3\2\2\2\u00c0\u02cd\3\2"+ + "\2\2\u00c2\u02d1\3\2\2\2\u00c4\u02d5\3\2\2\2\u00c6\u02da\3\2\2\2\u00c8"+ + "\u02de\3\2\2\2\u00ca\u02e3\3\2\2\2\u00cc\u02e7\3\2\2\2\u00ce\u02eb\3\2"+ + "\2\2\u00d0\u02f0\3\2\2\2\u00d2\u02f6\3\2\2\2\u00d4\u02fc\3\2\2\2\u00d6"+ + "\u0301\3\2\2\2\u00d8\u0305\3\2\2\2\u00da\u0309\3\2\2\2\u00dc\u030d\3\2"+ + "\2\2\u00de\u0310\3\2\2\2\u00e0\u0316\3\2\2\2\u00e2\u031e\3\2\2\2\u00e4"+ + "\u0324\3\2\2\2\u00e6\u0329\3\2\2\2\u00e8\u032c\3\2\2\2\u00ea\u032f\3\2"+ + "\2\2\u00ec\u0332\3\2\2\2\u00ee\u0334\3\2\2\2\u00f0\u0336\3\2\2\2\u00f2"+ + "\u0338\3\2\2\2\u00f4\u033a\3\2\2\2\u00f6\u033c\3\2\2\2\u00f8\u033e\3\2"+ + "\2\2\u00fa\u0340\3\2\2\2\u00fc\u0342\3\2\2\2\u00fe\u0345\3\2\2\2\u0100"+ + "\u0349\3\2\2\2\u0102\u034d\3\2\2\2\u0104\u0350\3\2\2\2\u0106\u0354\3\2"+ + "\2\2\u0108\u0358\3\2\2\2\u010a\u035b\3\2\2\2\u010c\u035e\3\2\2\2\u010e"+ + "\u0361\3\2\2\2\u0110\u0364\3\2\2\2\u0112\u0367\3\2\2\2\u0114\u036b\3\2"+ + "\2\2\u0116\u036d\3\2\2\2\u0118\u036f\3\2\2\2\u011a\u0373\3\2\2\2\u011c"+ + "\u0377\3\2\2\2\u011e\u037b\3\2\2\2\u0120\u037f\3\2\2\2\u0122\u0383\3\2"+ + "\2\2\u0124\u0386\3\2\2\2\u0126\u038a\3\2\2\2\u0128\u0392\3\2\2\2\u012a"+ + "\u039a\3\2\2\2\u012c\u03a1\3\2\2\2\u012e\u03a8\3\2\2\2\u0130\u03ae\3\2"+ + "\2\2\u0132\u03b7\3\2\2\2\u0134\u03c0\3\2\2\2\u0136\u03c7\3\2\2\2\u0138"+ + "\u03cb\3\2\2\2\u013a\u03cf\3\2\2\2\u013c\u03d1\3\2\2\2\u013e\u03d3\3\2"+ + "\2\2\u0140\u03d5\3\2\2\2\u0142\u03d7\3\2\2\2\u0144\u03d9\3\2\2\2\u0146"+ + "\u03db\3\2\2\2\u0148\u03dd\3\2\2\2\u014a\u03df\3\2\2\2\u014c\u03e1\3\2"+ + "\2\2\u014e\u03e4\3\2\2\2\u0150\u03e6\3\2\2\2\u0152\u03e9\3\2\2\2\u0154"+ + "\u03eb\3\2\2\2\u0156\u03ee\3\2\2\2\u0158\u03f1\3\2\2\2\u015a\u03f3\3\2"+ + "\2\2\u015c\u03f5\3\2\2\2\u015e\u03f7\3\2\2\2\u0160\u03fa\3\2\2\2\u0162"+ + "\u0401\3\2\2\2\u0164\u0165\7\61\2\2\u0165\u016a\7\61\2\2\u0166\u0167\7"+ + "/\2\2\u0167\u016a\7/\2\2\u0168\u016a\t\2\2\2\u0169\u0164\3\2\2\2\u0169"+ + "\u0166\3\2\2\2\u0169\u0168\3\2\2\2\u016a\u016e\3\2\2\2\u016b\u016d\n\3"+ + "\2\2\u016c\u016b\3\2\2\2\u016d\u0170\3\2\2\2\u016e\u016c\3\2\2\2\u016e"+ + "\u016f\3\2\2\2\u016f\u0171\3\2\2\2\u0170\u016e\3\2\2\2\u0171\u0172\b\2"+ + "\2\2\u0172\5\3\2\2\2\u0173\u0174\7\61\2\2\u0174\u0175\7,\2\2\u0175\u0179"+ + "\3\2\2\2\u0176\u0178\13\2\2\2\u0177\u0176\3\2\2\2\u0178\u017b\3\2\2\2"+ + "\u0179\u017a\3\2\2\2\u0179\u0177\3\2\2\2\u017a\u017c\3\2\2\2\u017b\u0179"+ + "\3\2\2\2\u017c\u017d\7,\2\2\u017d\u017e\7\61\2\2\u017e\u017f\3\2\2\2\u017f"+ + "\u0180\b\3\2\2\u0180\7\3\2\2\2\u0181\u0182\t\4\2\2\u0182\t\3\2\2\2\u0183"+ + "\u0184\t\5\2\2\u0184\13\3\2\2\2\u0185\u0186\t\6\2\2\u0186\r\3\2\2\2\u0187"+ + "\u0188\t\7\2\2\u0188\17\3\2\2\2\u0189\u018a\t\b\2\2\u018a\21\3\2\2\2\u018b"+ + "\u018c\t\t\2\2\u018c\23\3\2\2\2\u018d\u018e\t\n\2\2\u018e\25\3\2\2\2\u018f"+ + "\u0190\t\13\2\2\u0190\27\3\2\2\2\u0191\u0192\t\f\2\2\u0192\31\3\2\2\2"+ + "\u0193\u0194\t\r\2\2\u0194\33\3\2\2\2\u0195\u0196\t\16\2\2\u0196\35\3"+ + "\2\2\2\u0197\u0198\t\17\2\2\u0198\37\3\2\2\2\u0199\u019a\t\20\2\2\u019a"+ + "!\3\2\2\2\u019b\u019c\t\21\2\2\u019c#\3\2\2\2\u019d\u019e\t\22\2\2\u019e"+ + "%\3\2\2\2\u019f\u01a0\t\23\2\2\u01a0\'\3\2\2\2\u01a1\u01a2\t\24\2\2\u01a2"+ + ")\3\2\2\2\u01a3\u01a4\t\25\2\2\u01a4+\3\2\2\2\u01a5\u01a6\t\26\2\2\u01a6"+ + "-\3\2\2\2\u01a7\u01a8\t\27\2\2\u01a8/\3\2\2\2\u01a9\u01aa\t\30\2\2\u01aa"+ + "\61\3\2\2\2\u01ab\u01ac\t\31\2\2\u01ac\63\3\2\2\2\u01ad\u01ae\t\32\2\2"+ + "\u01ae\65\3\2\2\2\u01af\u01b0\t\33\2\2\u01b0\67\3\2\2\2\u01b1\u01b2\t"+ + "\34\2\2\u01b29\3\2\2\2\u01b3\u01b4\5\b\4\2\u01b4\u01b5\5\16\7\2\u01b5"+ + "\u01b6\5\f\6\2\u01b6;\3\2\2\2\u01b7\u01b8\5\b\4\2\u01b8\u01b9\5\16\7\2"+ + "\u01b9\u01ba\5\16\7\2\u01ba=\3\2\2\2\u01bb\u01bc\5\b\4\2\u01bc\u01bd\5"+ + " \20\2\u01bd\u01be\5\16\7\2\u01be?\3\2\2\2\u01bf\u01c0\5\n\5\2\u01c0\u01c1"+ + "\5\30\f\2\u01c1\u01c2\5,\26\2\u01c2A\3\2\2\2\u01c3\u01c4\5\f\6\2\u01c4"+ + "\u01c5\5\b\4\2\u01c5\u01c6\5\34\16\2\u01c6\u01c7\5\34\16\2\u01c7\u01c8"+ + "\3\2\2\2\u01c8\u01c9\b!\3\2\u01c9C\3\2\2\2\u01ca\u01cb\5\f\6\2\u01cb\u01cc"+ + "\5\f\6\2\u01cc\u01cd\5\22\t\2\u01cdE\3\2\2\2\u01ce\u01cf\5\f\6\2\u01cf"+ + "\u01d0\5$\22\2\u01d0G\3\2\2\2\u01d1\u01d2\5\f\6\2\u01d2\u01d3\5$\22\2"+ + "\u01d3\u01d4\5\16\7\2\u01d4I\3\2\2\2\u01d5\u01d6\5\f\6\2\u01d6\u01d7\5"+ + "$\22\2\u01d7\u01d8\5\16\7\2\u01d8\u01d9\5(\24\2\u01d9K\3\2\2\2\u01da\u01db"+ + "\5\f\6\2\u01db\u01dc\5$\22\2\u01dc\u01dd\5\30\f\2\u01ddM\3\2\2\2\u01de"+ + "\u01df\5\f\6\2\u01df\u01e0\5$\22\2\u01e0\u01e1\5\30\f\2\u01e1\u01e2\5"+ + "(\24\2\u01e2O\3\2\2\2\u01e3\u01e4\5\f\6\2\u01e4\u01e5\5$\22\2\u01e5\u01e6"+ + "\5\34\16\2\u01e6Q\3\2\2\2\u01e7\u01e8\5\16\7\2\u01e8\u01e9\5\b\4\2\u01e9"+ + "\u01ea\5\b\4\2\u01eaS\3\2\2\2\u01eb\u01ec\5\16\7\2\u01ec\u01ed\5\20\b"+ + "\2\u01ed\u01ee\5\f\6\2\u01eeU\3\2\2\2\u01ef\u01f0\5\16\7\2\u01f0\u01f1"+ + "\5\30\f\2\u01f1W\3\2\2\2\u01f2\u01f3\5\16\7\2\u01f3\u01f4\5\32\r\2\u01f4"+ + "\u01f5\5 \20\2\u01f5\u01f6\58\34\2\u01f6Y\3\2\2\2\u01f7\u01f8\5\20\b\2"+ + "\u01f8\u01f9\5\30\f\2\u01f9[\3\2\2\2\u01fa\u01fb\5\20\b\2\u01fb\u01fc"+ + "\5\64\32\2\u01fc]\3\2\2\2\u01fd\u01fe\5\20\b\2\u01fe\u01ff\5\64\32\2\u01ff"+ + "\u0200\5\64\32\2\u0200_\3\2\2\2\u0201\u0202\5\26\13\2\u0202\u0203\5\b"+ + "\4\2\u0203\u0204\5\34\16\2\u0204\u0205\5,\26\2\u0205a\3\2\2\2\u0206\u0207"+ + "\5\30\f\2\u0207\u0208\5\36\17\2\u0208c\3\2\2\2\u0209\u020a\5\30\f\2\u020a"+ + "\u020b\5 \20\2\u020be\3\2\2\2\u020c\u020d\5\30\f\2\u020d\u020e\5 \20\2"+ + "\u020e\u020f\5\f\6\2\u020fg\3\2\2\2\u0210\u0211\5\30\f\2\u0211\u0212\5"+ + " \20\2\u0212\u0213\5\16\7\2\u0213i\3\2\2\2\u0214\u0215\5\30\f\2\u0215"+ + "\u0216\5 \20\2\u0216\u0217\5\16\7\2\u0217\u0218\5(\24\2\u0218k\3\2\2\2"+ + "\u0219\u021a\5\30\f\2\u021a\u021b\5 \20\2\u021b\u021c\5\30\f\2\u021cm"+ + "\3\2\2\2\u021d\u021e\5\30\f\2\u021e\u021f\5 \20\2\u021f\u0220\5\30\f\2"+ + "\u0220\u0221\5(\24\2\u0221o\3\2\2\2\u0222\u0223\5\32\r\2\u0223\u0224\5"+ + "$\22\2\u0224\u0225\3\2\2\2\u0225\u0226\b8\3\2\u0226q\3\2\2\2\u0227\u0228"+ + "\5\32\r\2\u0228\u0229\5(\24\2\u0229\u022a\3\2\2\2\u022a\u022b\b9\3\2\u022b"+ + "s\3\2\2\2\u022c\u022d\5\34\16\2\u022d\u022e\5\16\7\2\u022eu\3\2\2\2\u022f"+ + "\u0230\5\34\16\2\u0230\u0231\5\16\7\2\u0231\u0232\5\16\7\2\u0232w\3\2"+ + "\2\2\u0233\u0234\5\34\16\2\u0234\u0235\5\16\7\2\u0235\u0236\5\16\7\2\u0236"+ + "\u0237\5(\24\2\u0237y\3\2\2\2\u0238\u0239\5\34\16\2\u0239\u023a\5\16\7"+ + "\2\u023a\u023b\5\30\f\2\u023b{\3\2\2\2\u023c\u023d\5\34\16\2\u023d\u023e"+ + "\5\16\7\2\u023e\u023f\5\30\f\2\u023f\u0240\5(\24\2\u0240}\3\2\2\2\u0241"+ + "\u0242\5 \20\2\u0242\u0243\5\20\b\2\u0243\u0244\5\24\n\2\u0244\177\3\2"+ + "\2\2\u0245\u0246\5 \20\2\u0246\u0247\5\"\21\2\u0247\u0248\5$\22\2\u0248"+ + "\u0081\3\2\2\2\u0249\u024a\5\"\21\2\u024a\u024b\5(\24\2\u024b\u0083\3"+ + "\2\2\2\u024c\u024d\5\"\21\2\u024d\u024e\5,\26\2\u024e\u024f\5\16\7\2\u024f"+ + "\u0250\5(\24\2\u0250\u0085\3\2\2\2\u0251\u0252\5\"\21\2\u0252\u0253\5"+ + ",\26\2\u0253\u0254\5\30\f\2\u0254\u0255\5(\24\2\u0255\u0087\3\2\2\2\u0256"+ + "\u0257\5\"\21\2\u0257\u0258\5.\27\2\u0258\u0259\5,\26\2\u0259\u0089\3"+ + "\2\2\2\u025a\u025b\5\"\21\2\u025b\u025c\5.\27\2\u025c\u025d\5,\26\2\u025d"+ + "\u025e\5\16\7\2\u025e\u008b\3\2\2\2\u025f\u0260\5\"\21\2\u0260\u0261\5"+ + ".\27\2\u0261\u0262\5,\26\2\u0262\u0263\5\30\f\2\u0263\u008d\3\2\2\2\u0264"+ + "\u0265\5$\22\2\u0265\u0266\5\"\21\2\u0266\u0267\5$\22\2\u0267\u008f\3"+ + "\2\2\2\u0268\u0269\5$\22\2\u0269\u026a\5.\27\2\u026a\u026b\5*\25\2\u026b"+ + "\u026c\5\26\13\2\u026c\u0091\3\2\2\2\u026d\u026e\5(\24\2\u026e\u026f\5"+ + "\20\b\2\u026f\u0270\5*\25\2\u0270\u0093\3\2\2\2\u0271\u0272\5(\24\2\u0272"+ + "\u0273\5\20\b\2\u0273\u0274\5,\26\2\u0274\u0275\3\2\2\2\u0275\u0276\b"+ + "J\3\2\u0276\u0095\3\2\2\2\u0277\u0278\5(\24\2\u0278\u0279\5\20\b\2\u0279"+ + "\u027a\5,\26\2\u027a\u027b\5\30\f\2\u027b\u0097\3\2\2\2\u027c\u027d\5"+ + "(\24\2\u027d\u027e\5\20\b\2\u027e\u027f\5,\26\2\u027f\u0280\5 \20\2\u0280"+ + "\u0099\3\2\2\2\u0281\u0282\5(\24\2\u0282\u0283\5\34\16\2\u0283\u009b\3"+ + "\2\2\2\u0284\u0285\5(\24\2\u0285\u0286\5\34\16\2\u0286\u0287\5\b\4\2\u0287"+ + "\u009d\3\2\2\2\u0288\u0289\5(\24\2\u0289\u028a\5\34\16\2\u028a\u028b\5"+ + "\f\6\2\u028b\u009f\3\2\2\2\u028c\u028d\5(\24\2\u028d\u028e\5\34\16\2\u028e"+ + "\u028f\5\f\6\2\u028f\u0290\5\b\4\2\u0290\u00a1\3\2\2\2\u0291\u0292\5("+ + "\24\2\u0292\u0293\5\34\16\2\u0293\u0294\5\16\7\2\u0294\u00a3\3\2\2\2\u0295"+ + "\u0296\5(\24\2\u0296\u0297\5(\24\2\u0297\u00a5\3\2\2\2\u0298\u0299\5("+ + "\24\2\u0299\u029a\5(\24\2\u029a\u029b\5\b\4\2\u029b\u00a7\3\2\2\2\u029c"+ + "\u029d\5(\24\2\u029d\u029e\5(\24\2\u029e\u029f\5\f\6\2\u029f\u00a9\3\2"+ + "\2\2\u02a0\u02a1\5(\24\2\u02a1\u02a2\5(\24\2\u02a2\u02a3\5\f\6\2\u02a3"+ + "\u02a4\5\b\4\2\u02a4\u00ab\3\2\2\2\u02a5\u02a6\5(\24\2\u02a6\u02a7\5("+ + "\24\2\u02a7\u02a8\5\16\7\2\u02a8\u00ad\3\2\2\2\u02a9\u02aa\5(\24\2\u02aa"+ + "\u02ab\5*\25\2\u02ab\u02ac\5,\26\2\u02ac\u00af\3\2\2\2\u02ad\u02ae\5*"+ + "\25\2\u02ae\u02af\5\n\5\2\u02af\u02b0\5\f\6\2\u02b0\u00b1\3\2\2\2\u02b1"+ + "\u02b2\5*\25\2\u02b2\u02b3\5\f\6\2\u02b3\u02b4\5\22\t\2\u02b4\u00b3\3"+ + "\2\2\2\u02b5\u02b6\5*\25\2\u02b6\u02b7\5\20\b\2\u02b7\u02b8\5,\26\2\u02b8"+ + "\u00b5\3\2\2\2\u02b9\u02ba\5*\25\2\u02ba\u02bb\5\34\16\2\u02bb\u02bc\5"+ + "\b\4\2\u02bc\u00b7\3\2\2\2\u02bd\u02be\5*\25\2\u02be\u02bf\5(\24\2\u02bf"+ + "\u02c0\5\b\4\2\u02c0\u00b9\3\2\2\2\u02c1\u02c2\5*\25\2\u02c2\u02c3\5\34"+ + "\16\2\u02c3\u02c4\5\34\16\2\u02c4\u00bb\3\2\2\2\u02c5\u02c6\5*\25\2\u02c6"+ + "\u02c7\5(\24\2\u02c7\u02c8\5\34\16\2\u02c8\u00bd\3\2\2\2\u02c9\u02ca\5"+ + "*\25\2\u02ca\u02cb\5.\27\2\u02cb\u02cc\5\n\5\2\u02cc\u00bf\3\2\2\2\u02cd"+ + "\u02ce\5\64\32\2\u02ce\u02cf\5\"\21\2\u02cf\u02d0\5(\24\2\u02d0\u00c1"+ + "\3\2\2\2\u02d1\u02d2\5\f\6\2\u02d2\u02d3\3\2\2\2\u02d3\u02d4\ba\4\2\u02d4"+ + "\u00c3\3\2\2\2\u02d5\u02d6\5 \20\2\u02d6\u02d7\5\f\6\2\u02d7\u02d8\3\2"+ + "\2\2\u02d8\u02d9\bb\4\2\u02d9\u00c5\3\2\2\2\u02da\u02db\58\34\2\u02db"+ + "\u02dc\3\2\2\2\u02dc\u02dd\bc\4\2\u02dd\u00c7\3\2\2\2\u02de\u02df\5 \20"+ + "\2\u02df\u02e0\58\34\2\u02e0\u02e1\3\2\2\2\u02e1\u02e2\bd\4\2\u02e2\u00c9"+ + "\3\2\2\2\u02e3\u02e4\5\36\17\2\u02e4\u02e5\3\2\2\2\u02e5\u02e6\be\4\2"+ + "\u02e6\u00cb\3\2\2\2\u02e7\u02e8\5$\22\2\u02e8\u02e9\3\2\2\2\u02e9\u02ea"+ + "\bf\4\2\u02ea\u00cd\3\2\2\2\u02eb\u02ec\5$\22\2\u02ec\u02ed\5\20\b\2\u02ed"+ + "\u02ee\3\2\2\2\u02ee\u02ef\bg\4\2\u02ef\u00cf\3\2\2\2\u02f0\u02f1\5$\22"+ + "\2\u02f1\u02f2\5\"\21\2\u02f2\u02f3\3\2\2\2\u02f3\u02f4\bh\4\2\u02f4\u00d1"+ + "\3\2\2\2\u02f5\u02f7\t\35\2\2\u02f6\u02f5\3\2\2\2\u02f7\u02f8\3\2\2\2"+ + "\u02f8\u02f6\3\2\2\2\u02f8\u02f9\3\2\2\2\u02f9\u02fa\3\2\2\2\u02fa\u02fb"+ + "\bi\2\2\u02fb\u00d3\3\2\2\2\u02fc\u02fd\6j\2\2\u02fd\u02fe\3\2\2\2\u02fe"+ + "\u02ff\bj\4\2\u02ff\u0300\bj\5\2\u0300\u00d5\3\2\2\2\u0301\u0302\5\"\21"+ + "\2\u0302\u0303\5(\24\2\u0303\u0304\5\24\n\2\u0304\u00d7\3\2\2\2\u0305"+ + "\u0306\5\20\b\2\u0306\u0307\5&\23\2\u0307\u0308\5.\27\2\u0308\u00d9\3"+ + "\2\2\2\u0309\u030a\5*\25\2\u030a\u030b\5\20\b\2\u030b\u030c\5,\26\2\u030c"+ + "\u00db\3\2\2\2\u030d\u030e\5\30\f\2\u030e\u030f\5\22\t\2\u030f\u00dd\3"+ + "\2\2\2\u0310\u0311\5\20\b\2\u0311\u0312\5 \20\2\u0312\u0313\5\16\7\2\u0313"+ + "\u0314\5\30\f\2\u0314\u0315\5\22\t\2\u0315\u00df\3\2\2\2\u0316\u0317\5"+ + "\30\f\2\u0317\u0318\5 \20\2\u0318\u0319\5\f\6\2\u0319\u031a\5\34\16\2"+ + "\u031a\u031b\5.\27\2\u031b\u031c\5\16\7\2\u031c\u031d\5\20\b\2\u031d\u00e1"+ + "\3\2\2\2\u031e\u031f\5\36\17\2\u031f\u0320\5\b\4\2\u0320\u0321\5\f\6\2"+ + "\u0321\u0322\5(\24\2\u0322\u0323\5\"\21\2\u0323\u00e3\3\2\2\2\u0324\u0325"+ + "\5\20\b\2\u0325\u0326\5 \20\2\u0326\u0327\5\16\7\2\u0327\u0328\5\36\17"+ + "\2\u0328\u00e5\3\2\2\2\u0329\u032a\5\16\7\2\u032a\u032b\5\n\5\2\u032b"+ + "\u00e7\3\2\2\2\u032c\u032d\5\16\7\2\u032d\u032e\5\62\31\2\u032e\u00e9"+ + "\3\2\2\2\u032f\u0330\5\16\7\2\u0330\u0331\5*\25\2\u0331\u00eb\3\2\2\2"+ + "\u0332\u0333\7&\2\2\u0333\u00ed\3\2\2\2\u0334\u0335\5\b\4\2\u0335\u00ef"+ + "\3\2\2\2\u0336\u0337\5\n\5\2\u0337\u00f1\3\2\2\2\u0338\u0339\5\f\6\2\u0339"+ + "\u00f3\3\2\2\2\u033a\u033b\5\16\7\2\u033b\u00f5\3\2\2\2\u033c\u033d\5"+ + "\20\b\2\u033d\u00f7\3\2\2\2\u033e\u033f\5\26\13\2\u033f\u00f9\3\2\2\2"+ + "\u0340\u0341\5\34\16\2\u0341\u00fb\3\2\2\2\u0342\u0343\5\30\f\2\u0343"+ + "\u0344\5\64\32\2\u0344\u00fd\3\2\2\2\u0345\u0346\5\30\f\2\u0346\u0347"+ + "\5\64\32\2\u0347\u0348\5\26\13\2\u0348\u00ff\3\2\2\2\u0349\u034a\5\30"+ + "\f\2\u034a\u034b\5\64\32\2\u034b\u034c\5\34\16\2\u034c\u0101\3\2\2\2\u034d"+ + "\u034e\5\30\f\2\u034e\u034f\5\66\33\2\u034f\u0103\3\2\2\2\u0350\u0351"+ + "\5\30\f\2\u0351\u0352\5\66\33\2\u0352\u0353\5\26\13\2\u0353\u0105\3\2"+ + "\2\2\u0354\u0355\5\30\f\2\u0355\u0356\5\66\33\2\u0356\u0357\5\34\16\2"+ + "\u0357\u0107\3\2\2\2\u0358\u0359\5\n\5\2\u0359\u035a\5\f\6\2\u035a\u0109"+ + "\3\2\2\2\u035b\u035c\5\16\7\2\u035c\u035d\5\20\b\2\u035d\u010b\3\2\2\2"+ + "\u035e\u035f\5\26\13\2\u035f\u0360\5\34\16\2\u0360\u010d\3\2\2\2\u0361"+ + "\u0362\5*\25\2\u0362\u0363\5$\22\2\u0363\u010f\3\2\2\2\u0364\u0365\5\b"+ + "\4\2\u0365\u0366\5\22\t\2\u0366\u0111\3\2\2\2\u0367\u0368\5\b\4\2\u0368"+ + "\u0369\5\22\t\2\u0369\u036a\7)\2\2\u036a\u0113\3\2\2\2\u036b\u036c\5\30"+ + "\f\2\u036c\u0115\3\2\2\2\u036d\u036e\5(\24\2\u036e\u0117\3\2\2\2\u036f"+ + "\u0370\5\36\17\2\u0370\u0371\5\"\21\2\u0371\u0372\5\16\7\2\u0372\u0119"+ + "\3\2\2\2\u0373\u0374\5*\25\2\u0374\u0375\5\26\13\2\u0375\u0376\5(\24\2"+ + "\u0376\u011b\3\2\2\2\u0377\u0378\5*\25\2\u0378\u0379\5\26\13\2\u0379\u037a"+ + "\5\34\16\2\u037a\u011d\3\2\2\2\u037b\u037c\5 \20\2\u037c\u037d\5\"\21"+ + "\2\u037d\u037e\5,\26\2\u037e\u011f\3\2\2\2\u037f\u0380\5\b\4\2\u0380\u0381"+ + "\5 \20\2\u0381\u0382\5\16\7\2\u0382\u0121\3\2\2\2\u0383\u0384\5\"\21\2"+ + "\u0384\u0385\5(\24\2\u0385\u0123\3\2\2\2\u0386\u0387\5\64\32\2\u0387\u0388"+ + "\5\"\21\2\u0388\u0389\5(\24\2\u0389\u0125\3\2\2\2\u038a\u038b\7\62\2\2"+ + "\u038b\u038d\5\64\32\2\u038c\u038e\t\36\2\2\u038d\u038c\3\2\2\2\u038e"+ + "\u038f\3\2\2\2\u038f\u038d\3\2\2\2\u038f\u0390\3\2\2\2\u0390\u0127\3\2"+ + "\2\2\u0391\u0393\t\37\2\2\u0392\u0391\3\2\2\2\u0393\u0394\3\2\2\2\u0394"+ + "\u0392\3\2\2\2\u0394\u0395\3\2\2\2\u0395\u0397\3\2\2\2\u0396\u0398\5\16"+ + "\7\2\u0397\u0396\3\2\2\2\u0397\u0398\3\2\2\2\u0398\u0129\3\2\2\2\u0399"+ + "\u039b\t\36\2\2\u039a\u0399\3\2\2\2\u039b\u039c\3\2\2\2\u039c\u039a\3"+ + "\2\2\2\u039c\u039d\3\2\2\2\u039d\u039e\3\2\2\2\u039e\u039f\5\26\13\2\u039f"+ + "\u012b\3\2\2\2\u03a0\u03a2\t \2\2\u03a1\u03a0\3\2\2\2\u03a2\u03a3\3\2"+ + "\2\2\u03a3\u03a1\3\2\2\2\u03a3\u03a4\3\2\2\2\u03a4\u03a5\3\2\2\2\u03a5"+ + "\u03a6\t!\2\2\u03a6\u012d\3\2\2\2\u03a7\u03a9\t\"\2\2\u03a8\u03a7\3\2"+ + "\2\2\u03a9\u03aa\3\2\2\2\u03aa\u03a8\3\2\2\2\u03aa\u03ab\3\2\2\2\u03ab"+ + "\u03ac\3\2\2\2\u03ac\u03ad\5\n\5\2\u03ad\u012f\3\2\2\2\u03ae\u03b2\7)"+ + "\2\2\u03af\u03b1\n#\2\2\u03b0\u03af\3\2\2\2\u03b1\u03b4\3\2\2\2\u03b2"+ + "\u03b0\3\2\2\2\u03b2\u03b3\3\2\2\2\u03b3\u03b5\3\2\2\2\u03b4\u03b2\3\2"+ + "\2\2\u03b5\u03b6\7)\2\2\u03b6\u0131\3\2\2\2\u03b7\u03bb\7$\2\2\u03b8\u03ba"+ + "\n$\2\2\u03b9\u03b8\3\2\2\2\u03ba\u03bd\3\2\2\2\u03bb\u03b9\3\2\2\2\u03bb"+ + "\u03bc\3\2\2\2\u03bc\u03be\3\2\2\2\u03bd\u03bb\3\2\2\2\u03be\u03bf\7$"+ + "\2\2\u03bf\u0133\3\2\2\2\u03c0\u03c4\t%\2\2\u03c1\u03c3\t&\2\2\u03c2\u03c1"+ + "\3\2\2\2\u03c3\u03c6\3\2\2\2\u03c4\u03c2\3\2\2\2\u03c4\u03c5\3\2\2\2\u03c5"+ + "\u0135\3\2\2\2\u03c6\u03c4\3\2\2\2\u03c7\u03c8\5\u0134\u009a\2\u03c8\u03c9"+ + "\7<\2\2\u03c9\u0137\3\2\2\2\u03ca\u03cc\n\'\2\2\u03cb\u03ca\3\2\2\2\u03cc"+ + "\u03cd\3\2\2\2\u03cd\u03cb\3\2\2\2\u03cd\u03ce\3\2\2\2\u03ce\u0139\3\2"+ + "\2\2\u03cf\u03d0\7*\2\2\u03d0\u013b\3\2\2\2\u03d1\u03d2\7+\2\2\u03d2\u013d"+ + "\3\2\2\2\u03d3\u03d4\7.\2\2\u03d4\u013f\3\2\2\2\u03d5\u03d6\7-\2\2\u03d6"+ + "\u0141\3\2\2\2\u03d7\u03d8\7/\2\2\u03d8\u0143\3\2\2\2\u03d9\u03da\7,\2"+ + "\2\u03da\u0145\3\2\2\2\u03db\u03dc\7\61\2\2\u03dc\u0147\3\2\2\2\u03dd"+ + "\u03de\7?\2\2\u03de\u0149\3\2\2\2\u03df\u03e0\7@\2\2\u03e0\u014b\3\2\2"+ + "\2\u03e1\u03e2\7@\2\2\u03e2\u03e3\7?\2\2\u03e3\u014d\3\2\2\2\u03e4\u03e5"+ + "\7>\2\2\u03e5\u014f\3\2\2\2\u03e6\u03e7\7>\2\2\u03e7\u03e8\7?\2\2\u03e8"+ + "\u0151\3\2\2\2\u03e9\u03ea\7\'\2\2\u03ea\u0153\3\2\2\2\u03eb\u03ec\7@"+ + "\2\2\u03ec\u03ed\7@\2\2\u03ed\u0155\3\2\2\2\u03ee\u03ef\7>\2\2\u03ef\u03f0"+ + "\7>\2\2\u03f0\u0157\3\2\2\2\u03f1\u03f2\7\u0080\2\2\u03f2\u0159\3\2\2"+ + "\2\u03f3\u03f4\7(\2\2\u03f4\u015b\3\2\2\2\u03f5\u03f6\7~\2\2\u03f6\u015d"+ + "\3\2\2\2\u03f7\u03f8\7`\2\2\u03f8\u015f\3\2\2\2\u03f9\u03fb\t\35\2\2\u03fa"+ + "\u03f9\3\2\2\2\u03fb\u03fc\3\2\2\2\u03fc\u03fa\3\2\2\2\u03fc\u03fd\3\2"+ + "\2\2\u03fd\u03fe\3\2\2\2\u03fe\u03ff\b\u00b0\2\2\u03ff\u0161\3\2\2\2\u0400"+ + "\u0402\7\17\2\2\u0401\u0400\3\2\2\2\u0401\u0402\3\2\2\2\u0402\u0403\3"+ + "\2\2\2\u0403\u0404\7\f\2\2\u0404\u0163\3\2\2\2\24\2\3\u0169\u016e\u0179"+ + "\u02f8\u038f\u0394\u0397\u039c\u03a3\u03aa\u03b2\u03bb\u03c4\u03cd\u03fc"+ + "\u0401\6\b\2\2\7\3\2\6\2\2\2\3\2"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.tokens new file mode 100644 index 000000000..a4d6ab04f --- /dev/null +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.tokens @@ -0,0 +1,171 @@ +COMMENT=1 +COMMENT2=2 +OPCODE_ADC=3 +OPCODE_ADD=4 +OPCODE_AND=5 +OPCODE_BIT=6 +OPCODE_CALL=7 +OPCODE_CCF=8 +OPCODE_CP=9 +OPCODE_CPD=10 +OPCODE_CPDR=11 +OPCODE_CPI=12 +OPCODE_CPIR=13 +OPCODE_CPL=14 +OPCODE_DAA=15 +OPCODE_DEC=16 +OPCODE_DI=17 +OPCODE_DJNZ=18 +OPCODE_EI=19 +OPCODE_EX=20 +OPCODE_EXX=21 +OPCODE_HALT=22 +OPCODE_IM=23 +OPCODE_IN=24 +OPCODE_INC=25 +OPCODE_IND=26 +OPCODE_INDR=27 +OPCODE_INI=28 +OPCODE_INIR=29 +OPCODE_JP=30 +OPCODE_JR=31 +OPCODE_LD=32 +OPCODE_LDD=33 +OPCODE_LDDR=34 +OPCODE_LDI=35 +OPCODE_LDIR=36 +OPCODE_NEG=37 +OPCODE_NOP=38 +OPCODE_OR=39 +OPCODE_OTDR=40 +OPCODE_OTIR=41 +OPCODE_OUT=42 +OPCODE_OUTD=43 +OPCODE_OUTI=44 +OPCODE_POP=45 +OPCODE_PUSH=46 +OPCODE_RES=47 +OPCODE_RET=48 +OPCODE_RETI=49 +OPCODE_RETN=50 +OPCODE_RL=51 +OPCODE_RLA=52 +OPCODE_RLC=53 +OPCODE_RLCA=54 +OPCODE_RLD=55 +OPCODE_RR=56 +OPCODE_RRA=57 +OPCODE_RRC=58 +OPCODE_RRCA=59 +OPCODE_RRD=60 +OPCODE_RST=61 +OPCODE_SBC=62 +OPCODE_SCF=63 +OPCODE_SET=64 +OPCODE_SLA=65 +OPCODE_SRA=66 +OPCODE_SLL=67 +OPCODE_SRL=68 +OPCODE_SUB=69 +OPCODE_XOR=70 +COND_C=71 +COND_NC=72 +COND_Z=73 +COND_NZ=74 +COND_M=75 +COND_P=76 +COND_PE=77 +COND_PO=78 +COND_WS=79 +COND_UNRECOGNIZED=80 +PREP_ORG=81 +PREP_EQU=82 +PREP_SET=83 +PREP_IF=84 +PREP_ENDIF=85 +PREP_INCLUDE=86 +PREP_MACRO=87 +PREP_ENDM=88 +PREP_DB=89 +PREP_DW=90 +PREP_DS=91 +PREP_ADDR=92 +REG_A=93 +REG_B=94 +REG_C=95 +REG_D=96 +REG_E=97 +REG_H=98 +REG_L=99 +REG_IX=100 +REG_IXH=101 +REG_IXL=102 +REG_IY=103 +REG_IYH=104 +REG_IYL=105 +REG_BC=106 +REG_DE=107 +REG_HL=108 +REG_SP=109 +REG_AF=110 +REG_AFF=111 +REG_I=112 +REG_R=113 +OP_MOD=114 +OP_SHR=115 +OP_SHL=116 +OP_NOT=117 +OP_AND=118 +OP_OR=119 +OP_XOR=120 +LIT_HEXNUMBER_1=121 +LIT_NUMBER=122 +LIT_HEXNUMBER_2=123 +LIT_OCTNUMBER=124 +LIT_BINNUMBER=125 +LIT_STRING_1=126 +LIT_STRING_2=127 +ID_IDENTIFIER=128 +ID_LABEL=129 +ERROR=130 +SEP_LPAR=131 +SEP_RPAR=132 +SEP_COMMA=133 +OP_ADD=134 +OP_SUBTRACT=135 +OP_MULTIPLY=136 +OP_DIVIDE=137 +OP_EQUAL=138 +OP_GT=139 +OP_GTE=140 +OP_LT=141 +OP_LTE=142 +OP_MOD_2=143 +OP_SHR_2=144 +OP_SHL_2=145 +OP_NOT_2=146 +OP_AND_2=147 +OP_OR_2=148 +OP_XOR_2=149 +WS=150 +EOL=151 +'$'=92 +'('=131 +')'=132 +','=133 +'+'=134 +'-'=135 +'*'=136 +'/'=137 +'='=138 +'>'=139 +'>='=140 +'<'=141 +'<='=142 +'%'=143 +'>>'=144 +'<<'=145 +'~'=146 +'&'=147 +'|'=148 +'^'=149 diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.interp b/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.interp new file mode 100644 index 000000000..057aa659f --- /dev/null +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.interp @@ -0,0 +1,329 @@ +token literal names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'$' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +'(' +')' +',' +'+' +'-' +'*' +'/' +'=' +'>' +'>=' +'<' +'<=' +'%' +'>>' +'<<' +'!' +'&' +'|' +'~' +null +null + +token symbolic names: +null +COMMENT +COMMENT2 +OPCODE_ADC +OPCODE_ADD +OPCODE_AND +OPCODE_BIT +OPCODE_CALL +OPCODE_CCF +OPCODE_CP +OPCODE_CPD +OPCODE_CPDR +OPCODE_CPI +OPCODE_CPIR +OPCODE_CPL +OPCODE_DAA +OPCODE_DEC +OPCODE_DI +OPCODE_DJNZ +OPCODE_EI +OPCODE_EX +OPCODE_EXX +OPCODE_HALT +OPCODE_IM +OPCODE_IN +OPCODE_INC +OPCODE_IND +OPCODE_INDR +OPCODE_INI +OPCODE_INIR +OPCODE_JP +OPCODE_JR +OPCODE_LD +OPCODE_LDD +OPCODE_LDDR +OPCODE_LDI +OPCODE_LDIR +OPCODE_NEG +OPCODE_NOP +OPCODE_OR +OPCODE_OTDR +OPCODE_OTIR +OPCODE_OUT +OPCODE_OUTD +OPCODE_OUTI +OPCODE_POP +OPCODE_PUSH +OPCODE_RES +OPCODE_RET +OPCODE_RETI +OPCODE_RETN +OPCODE_RL +OPCODE_RLA +OPCODE_RLC +OPCODE_RLCA +OPCODE_RLD +OPCODE_RR +OPCODE_RRA +OPCODE_RRC +OPCODE_RRCA +OPCODE_RRD +OPCODE_RST +OPCODE_SBC +OPCODE_SCF +OPCODE_SET +OPCODE_SLA +OPCODE_SRA +OPCODE_SLL +OPCODE_SRL +OPCODE_SUB +OPCODE_XOR +COND_C +COND_NC +COND_Z +COND_NZ +COND_M +COND_P +COND_PE +COND_PO +COND_WS +COND_UNRECOGNIZED +PREP_ORG +PREP_EQU +PREP_SET +PREP_VAR +PREP_IF +PREP_ENDIF +PREP_INCLUDE +PREP_MACRO +PREP_ENDM +PREP_DB +PREP_DW +PREP_DS +PREP_ADDR +REG_A +REG_B +REG_C +REG_D +REG_E +REG_H +REG_L +REG_IX +REG_IXH +REG_IXL +REG_IY +REG_IYH +REG_IYL +REG_BC +REG_DE +REG_HL +REG_SP +REG_AF +REG_AFF +REG_I +REG_R +OP_MOD +OP_SHR +OP_SHL +OP_NOT +OP_AND +OP_OR +OP_XOR +LIT_HEXNUMBER_1 +LIT_NUMBER +LIT_HEXNUMBER_2 +LIT_OCTNUMBER +LIT_BINNUMBER +LIT_STRING_1 +LIT_STRING_2 +ID_IDENTIFIER +ID_LABEL +ERROR +SEP_LPAR +SEP_RPAR +SEP_COMMA +OP_ADD +OP_SUBTRACT +OP_MULTIPLY +OP_DIVIDE +OP_EQUAL +OP_GT +OP_GTE +OP_LT +OP_LTE +OP_MOD_2 +OP_SHR_2 +OP_SHL_2 +OP_NOT_2 +OP_AND_2 +OP_OR_2 +OP_XOR_2 +WS +EOL + +rule names: +rStart +rLine +rStatement +rInstruction +r8bitInstruction +rRegister +cCondition +rPseudoCode +rMacroParameters +rMacroArguments +rData +rDBdata +rDWdata +rExpression + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 154, 445, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 3, 2, 7, 2, 32, 10, 2, 12, 2, 14, 2, 35, 11, 2, 3, 2, 5, 2, 38, 10, 2, 3, 2, 6, 2, 41, 10, 2, 13, 2, 14, 2, 42, 3, 2, 7, 2, 46, 10, 2, 12, 2, 14, 2, 49, 11, 2, 3, 2, 7, 2, 52, 10, 2, 12, 2, 14, 2, 55, 11, 2, 3, 2, 3, 2, 3, 3, 5, 3, 60, 10, 3, 3, 3, 7, 3, 63, 10, 3, 12, 3, 14, 3, 66, 11, 3, 3, 3, 3, 3, 5, 3, 70, 10, 3, 3, 4, 3, 4, 3, 4, 5, 4, 75, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 90, 10, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 125, 10, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 171, 10, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 264, 10, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 283, 10, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 295, 10, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 7, 9, 313, 10, 9, 12, 9, 14, 9, 316, 11, 9, 3, 9, 7, 9, 319, 10, 9, 12, 9, 14, 9, 322, 11, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 329, 10, 9, 3, 9, 3, 9, 3, 9, 3, 9, 7, 9, 335, 10, 9, 12, 9, 14, 9, 338, 11, 9, 3, 9, 7, 9, 341, 10, 9, 12, 9, 14, 9, 344, 11, 9, 3, 9, 3, 9, 3, 9, 5, 9, 349, 10, 9, 3, 9, 3, 9, 5, 9, 353, 10, 9, 3, 10, 3, 10, 3, 10, 7, 10, 358, 10, 10, 12, 10, 14, 10, 361, 11, 10, 3, 11, 3, 11, 3, 11, 7, 11, 366, 10, 11, 12, 11, 14, 11, 369, 11, 11, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 375, 10, 12, 12, 12, 14, 12, 378, 11, 12, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 384, 10, 12, 12, 12, 14, 12, 387, 11, 12, 3, 12, 3, 12, 5, 12, 391, 10, 12, 3, 13, 3, 13, 5, 13, 395, 10, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 5, 15, 414, 10, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 7, 15, 440, 10, 15, 12, 15, 14, 15, 443, 11, 15, 3, 15, 2, 3, 28, 16, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 2, 16, 3, 2, 109, 112, 3, 2, 73, 76, 3, 2, 109, 110, 4, 2, 109, 111, 113, 113, 3, 2, 73, 80, 3, 2, 129, 130, 5, 2, 120, 120, 137, 138, 149, 149, 5, 2, 117, 117, 139, 140, 146, 146, 3, 2, 137, 138, 4, 2, 118, 119, 147, 148, 3, 2, 142, 145, 4, 2, 121, 121, 150, 150, 4, 2, 123, 123, 152, 152, 4, 2, 122, 122, 151, 151, 2, 546, 2, 33, 3, 2, 2, 2, 4, 69, 3, 2, 2, 2, 6, 74, 3, 2, 2, 2, 8, 170, 3, 2, 2, 2, 10, 282, 3, 2, 2, 2, 12, 294, 3, 2, 2, 2, 14, 296, 3, 2, 2, 2, 16, 352, 3, 2, 2, 2, 18, 354, 3, 2, 2, 2, 20, 362, 3, 2, 2, 2, 22, 390, 3, 2, 2, 2, 24, 394, 3, 2, 2, 2, 26, 396, 3, 2, 2, 2, 28, 413, 3, 2, 2, 2, 30, 32, 7, 154, 2, 2, 31, 30, 3, 2, 2, 2, 32, 35, 3, 2, 2, 2, 33, 31, 3, 2, 2, 2, 33, 34, 3, 2, 2, 2, 34, 37, 3, 2, 2, 2, 35, 33, 3, 2, 2, 2, 36, 38, 5, 4, 3, 2, 37, 36, 3, 2, 2, 2, 37, 38, 3, 2, 2, 2, 38, 47, 3, 2, 2, 2, 39, 41, 7, 154, 2, 2, 40, 39, 3, 2, 2, 2, 41, 42, 3, 2, 2, 2, 42, 40, 3, 2, 2, 2, 42, 43, 3, 2, 2, 2, 43, 44, 3, 2, 2, 2, 44, 46, 5, 4, 3, 2, 45, 40, 3, 2, 2, 2, 46, 49, 3, 2, 2, 2, 47, 45, 3, 2, 2, 2, 47, 48, 3, 2, 2, 2, 48, 53, 3, 2, 2, 2, 49, 47, 3, 2, 2, 2, 50, 52, 7, 154, 2, 2, 51, 50, 3, 2, 2, 2, 52, 55, 3, 2, 2, 2, 53, 51, 3, 2, 2, 2, 53, 54, 3, 2, 2, 2, 54, 56, 3, 2, 2, 2, 55, 53, 3, 2, 2, 2, 56, 57, 7, 2, 2, 3, 57, 3, 3, 2, 2, 2, 58, 60, 7, 132, 2, 2, 59, 58, 3, 2, 2, 2, 59, 60, 3, 2, 2, 2, 60, 64, 3, 2, 2, 2, 61, 63, 7, 154, 2, 2, 62, 61, 3, 2, 2, 2, 63, 66, 3, 2, 2, 2, 64, 62, 3, 2, 2, 2, 64, 65, 3, 2, 2, 2, 65, 67, 3, 2, 2, 2, 66, 64, 3, 2, 2, 2, 67, 70, 5, 6, 4, 2, 68, 70, 7, 132, 2, 2, 69, 59, 3, 2, 2, 2, 69, 68, 3, 2, 2, 2, 70, 5, 3, 2, 2, 2, 71, 75, 5, 8, 5, 2, 72, 75, 5, 16, 9, 2, 73, 75, 5, 22, 12, 2, 74, 71, 3, 2, 2, 2, 74, 72, 3, 2, 2, 2, 74, 73, 3, 2, 2, 2, 75, 7, 3, 2, 2, 2, 76, 171, 5, 10, 6, 2, 77, 78, 7, 34, 2, 2, 78, 79, 9, 2, 2, 2, 79, 80, 7, 136, 2, 2, 80, 171, 5, 28, 15, 2, 81, 82, 7, 34, 2, 2, 82, 83, 5, 12, 7, 2, 83, 84, 7, 136, 2, 2, 84, 85, 5, 28, 15, 2, 85, 171, 3, 2, 2, 2, 86, 89, 7, 33, 2, 2, 87, 88, 9, 3, 2, 2, 88, 90, 7, 136, 2, 2, 89, 87, 3, 2, 2, 2, 89, 90, 3, 2, 2, 2, 90, 91, 3, 2, 2, 2, 91, 171, 5, 28, 15, 2, 92, 93, 7, 34, 2, 2, 93, 94, 7, 134, 2, 2, 94, 95, 5, 28, 15, 2, 95, 96, 7, 135, 2, 2, 96, 97, 7, 136, 2, 2, 97, 98, 7, 111, 2, 2, 98, 171, 3, 2, 2, 2, 99, 100, 7, 34, 2, 2, 100, 101, 7, 111, 2, 2, 101, 102, 7, 136, 2, 2, 102, 103, 7, 134, 2, 2, 103, 104, 5, 28, 15, 2, 104, 105, 7, 135, 2, 2, 105, 171, 3, 2, 2, 2, 106, 107, 7, 34, 2, 2, 107, 108, 7, 134, 2, 2, 108, 109, 5, 28, 15, 2, 109, 110, 7, 135, 2, 2, 110, 111, 7, 136, 2, 2, 111, 112, 7, 96, 2, 2, 112, 171, 3, 2, 2, 2, 113, 114, 7, 34, 2, 2, 114, 115, 7, 96, 2, 2, 115, 116, 7, 136, 2, 2, 116, 117, 7, 134, 2, 2, 117, 118, 5, 28, 15, 2, 118, 119, 7, 135, 2, 2, 119, 171, 3, 2, 2, 2, 120, 124, 7, 32, 2, 2, 121, 122, 5, 14, 8, 2, 122, 123, 7, 136, 2, 2, 123, 125, 3, 2, 2, 2, 124, 121, 3, 2, 2, 2, 124, 125, 3, 2, 2, 2, 125, 126, 3, 2, 2, 2, 126, 171, 5, 28, 15, 2, 127, 128, 7, 9, 2, 2, 128, 171, 5, 28, 15, 2, 129, 130, 7, 9, 2, 2, 130, 131, 5, 14, 8, 2, 131, 132, 7, 136, 2, 2, 132, 133, 5, 28, 15, 2, 133, 171, 3, 2, 2, 2, 134, 135, 7, 6, 2, 2, 135, 136, 7, 96, 2, 2, 136, 137, 7, 136, 2, 2, 137, 171, 5, 28, 15, 2, 138, 139, 7, 5, 2, 2, 139, 140, 7, 96, 2, 2, 140, 141, 7, 136, 2, 2, 141, 171, 5, 28, 15, 2, 142, 143, 7, 44, 2, 2, 143, 144, 7, 134, 2, 2, 144, 145, 5, 28, 15, 2, 145, 146, 7, 135, 2, 2, 146, 147, 7, 136, 2, 2, 147, 148, 7, 96, 2, 2, 148, 171, 3, 2, 2, 2, 149, 150, 7, 71, 2, 2, 150, 171, 5, 28, 15, 2, 151, 152, 7, 26, 2, 2, 152, 153, 7, 96, 2, 2, 153, 154, 7, 136, 2, 2, 154, 155, 7, 134, 2, 2, 155, 156, 5, 28, 15, 2, 156, 157, 7, 135, 2, 2, 157, 171, 3, 2, 2, 2, 158, 159, 7, 64, 2, 2, 159, 160, 7, 96, 2, 2, 160, 161, 7, 136, 2, 2, 161, 171, 5, 28, 15, 2, 162, 163, 7, 7, 2, 2, 163, 171, 5, 28, 15, 2, 164, 165, 7, 72, 2, 2, 165, 171, 5, 28, 15, 2, 166, 167, 7, 41, 2, 2, 167, 171, 5, 28, 15, 2, 168, 169, 7, 11, 2, 2, 169, 171, 5, 28, 15, 2, 170, 76, 3, 2, 2, 2, 170, 77, 3, 2, 2, 2, 170, 81, 3, 2, 2, 2, 170, 86, 3, 2, 2, 2, 170, 92, 3, 2, 2, 2, 170, 99, 3, 2, 2, 2, 170, 106, 3, 2, 2, 2, 170, 113, 3, 2, 2, 2, 170, 120, 3, 2, 2, 2, 170, 127, 3, 2, 2, 2, 170, 129, 3, 2, 2, 2, 170, 134, 3, 2, 2, 2, 170, 138, 3, 2, 2, 2, 170, 142, 3, 2, 2, 2, 170, 149, 3, 2, 2, 2, 170, 151, 3, 2, 2, 2, 170, 158, 3, 2, 2, 2, 170, 162, 3, 2, 2, 2, 170, 164, 3, 2, 2, 2, 170, 166, 3, 2, 2, 2, 170, 168, 3, 2, 2, 2, 171, 9, 3, 2, 2, 2, 172, 283, 7, 40, 2, 2, 173, 174, 7, 34, 2, 2, 174, 175, 7, 134, 2, 2, 175, 176, 9, 4, 2, 2, 176, 177, 7, 135, 2, 2, 177, 178, 7, 136, 2, 2, 178, 283, 7, 96, 2, 2, 179, 180, 7, 34, 2, 2, 180, 181, 7, 134, 2, 2, 181, 182, 7, 111, 2, 2, 182, 183, 7, 135, 2, 2, 183, 184, 7, 136, 2, 2, 184, 283, 5, 12, 7, 2, 185, 186, 7, 27, 2, 2, 186, 283, 9, 2, 2, 2, 187, 188, 7, 27, 2, 2, 188, 283, 5, 12, 7, 2, 189, 190, 7, 18, 2, 2, 190, 283, 5, 12, 7, 2, 191, 283, 7, 56, 2, 2, 192, 193, 7, 22, 2, 2, 193, 194, 7, 113, 2, 2, 194, 195, 7, 136, 2, 2, 195, 283, 7, 114, 2, 2, 196, 197, 7, 22, 2, 2, 197, 198, 7, 110, 2, 2, 198, 199, 7, 136, 2, 2, 199, 283, 7, 111, 2, 2, 200, 201, 7, 22, 2, 2, 201, 202, 7, 134, 2, 2, 202, 203, 7, 112, 2, 2, 203, 204, 7, 135, 2, 2, 204, 205, 7, 136, 2, 2, 205, 283, 7, 111, 2, 2, 206, 207, 7, 6, 2, 2, 207, 208, 7, 111, 2, 2, 208, 209, 7, 136, 2, 2, 209, 283, 9, 2, 2, 2, 210, 211, 7, 34, 2, 2, 211, 212, 7, 96, 2, 2, 212, 213, 7, 136, 2, 2, 213, 214, 7, 134, 2, 2, 214, 215, 9, 4, 2, 2, 215, 283, 7, 135, 2, 2, 216, 217, 7, 18, 2, 2, 217, 283, 9, 2, 2, 2, 218, 283, 7, 61, 2, 2, 219, 283, 7, 54, 2, 2, 220, 283, 7, 59, 2, 2, 221, 283, 7, 17, 2, 2, 222, 283, 7, 16, 2, 2, 223, 224, 7, 27, 2, 2, 224, 225, 7, 134, 2, 2, 225, 226, 7, 111, 2, 2, 226, 283, 7, 135, 2, 2, 227, 228, 7, 18, 2, 2, 228, 229, 7, 134, 2, 2, 229, 230, 7, 111, 2, 2, 230, 283, 7, 135, 2, 2, 231, 283, 7, 65, 2, 2, 232, 283, 7, 10, 2, 2, 233, 234, 7, 34, 2, 2, 234, 235, 5, 12, 7, 2, 235, 236, 7, 136, 2, 2, 236, 237, 5, 12, 7, 2, 237, 283, 3, 2, 2, 2, 238, 283, 7, 24, 2, 2, 239, 240, 7, 6, 2, 2, 240, 241, 7, 96, 2, 2, 241, 242, 7, 136, 2, 2, 242, 283, 5, 12, 7, 2, 243, 244, 7, 5, 2, 2, 244, 245, 7, 96, 2, 2, 245, 246, 7, 136, 2, 2, 246, 283, 5, 12, 7, 2, 247, 248, 7, 71, 2, 2, 248, 283, 5, 12, 7, 2, 249, 250, 7, 64, 2, 2, 250, 251, 7, 96, 2, 2, 251, 252, 7, 136, 2, 2, 252, 283, 5, 12, 7, 2, 253, 254, 7, 7, 2, 2, 254, 283, 5, 12, 7, 2, 255, 256, 7, 72, 2, 2, 256, 283, 5, 12, 7, 2, 257, 258, 7, 41, 2, 2, 258, 283, 5, 12, 7, 2, 259, 260, 7, 11, 2, 2, 260, 283, 5, 12, 7, 2, 261, 263, 7, 50, 2, 2, 262, 264, 5, 14, 8, 2, 263, 262, 3, 2, 2, 2, 263, 264, 3, 2, 2, 2, 264, 283, 3, 2, 2, 2, 265, 266, 7, 47, 2, 2, 266, 283, 9, 5, 2, 2, 267, 268, 7, 48, 2, 2, 268, 283, 9, 5, 2, 2, 269, 270, 7, 63, 2, 2, 270, 283, 5, 28, 15, 2, 271, 283, 7, 23, 2, 2, 272, 273, 7, 32, 2, 2, 273, 274, 7, 134, 2, 2, 274, 275, 7, 111, 2, 2, 275, 283, 7, 135, 2, 2, 276, 283, 7, 19, 2, 2, 277, 278, 7, 34, 2, 2, 278, 279, 7, 112, 2, 2, 279, 280, 7, 136, 2, 2, 280, 283, 7, 111, 2, 2, 281, 283, 7, 21, 2, 2, 282, 172, 3, 2, 2, 2, 282, 173, 3, 2, 2, 2, 282, 179, 3, 2, 2, 2, 282, 185, 3, 2, 2, 2, 282, 187, 3, 2, 2, 2, 282, 189, 3, 2, 2, 2, 282, 191, 3, 2, 2, 2, 282, 192, 3, 2, 2, 2, 282, 196, 3, 2, 2, 2, 282, 200, 3, 2, 2, 2, 282, 206, 3, 2, 2, 2, 282, 210, 3, 2, 2, 2, 282, 216, 3, 2, 2, 2, 282, 218, 3, 2, 2, 2, 282, 219, 3, 2, 2, 2, 282, 220, 3, 2, 2, 2, 282, 221, 3, 2, 2, 2, 282, 222, 3, 2, 2, 2, 282, 223, 3, 2, 2, 2, 282, 227, 3, 2, 2, 2, 282, 231, 3, 2, 2, 2, 282, 232, 3, 2, 2, 2, 282, 233, 3, 2, 2, 2, 282, 238, 3, 2, 2, 2, 282, 239, 3, 2, 2, 2, 282, 243, 3, 2, 2, 2, 282, 247, 3, 2, 2, 2, 282, 249, 3, 2, 2, 2, 282, 253, 3, 2, 2, 2, 282, 255, 3, 2, 2, 2, 282, 257, 3, 2, 2, 2, 282, 259, 3, 2, 2, 2, 282, 261, 3, 2, 2, 2, 282, 265, 3, 2, 2, 2, 282, 267, 3, 2, 2, 2, 282, 269, 3, 2, 2, 2, 282, 271, 3, 2, 2, 2, 282, 272, 3, 2, 2, 2, 282, 276, 3, 2, 2, 2, 282, 277, 3, 2, 2, 2, 282, 281, 3, 2, 2, 2, 283, 11, 3, 2, 2, 2, 284, 295, 7, 96, 2, 2, 285, 295, 7, 97, 2, 2, 286, 295, 7, 98, 2, 2, 287, 295, 7, 99, 2, 2, 288, 295, 7, 100, 2, 2, 289, 295, 7, 101, 2, 2, 290, 295, 7, 102, 2, 2, 291, 292, 7, 134, 2, 2, 292, 293, 7, 111, 2, 2, 293, 295, 7, 135, 2, 2, 294, 284, 3, 2, 2, 2, 294, 285, 3, 2, 2, 2, 294, 286, 3, 2, 2, 2, 294, 287, 3, 2, 2, 2, 294, 288, 3, 2, 2, 2, 294, 289, 3, 2, 2, 2, 294, 290, 3, 2, 2, 2, 294, 291, 3, 2, 2, 2, 295, 13, 3, 2, 2, 2, 296, 297, 9, 6, 2, 2, 297, 15, 3, 2, 2, 2, 298, 299, 7, 83, 2, 2, 299, 353, 5, 28, 15, 2, 300, 301, 7, 131, 2, 2, 301, 302, 7, 84, 2, 2, 302, 353, 5, 28, 15, 2, 303, 304, 7, 131, 2, 2, 304, 305, 7, 85, 2, 2, 305, 353, 5, 28, 15, 2, 306, 307, 7, 87, 2, 2, 307, 308, 5, 28, 15, 2, 308, 314, 7, 154, 2, 2, 309, 310, 5, 4, 3, 2, 310, 311, 7, 154, 2, 2, 311, 313, 3, 2, 2, 2, 312, 309, 3, 2, 2, 2, 313, 316, 3, 2, 2, 2, 314, 312, 3, 2, 2, 2, 314, 315, 3, 2, 2, 2, 315, 320, 3, 2, 2, 2, 316, 314, 3, 2, 2, 2, 317, 319, 7, 154, 2, 2, 318, 317, 3, 2, 2, 2, 319, 322, 3, 2, 2, 2, 320, 318, 3, 2, 2, 2, 320, 321, 3, 2, 2, 2, 321, 323, 3, 2, 2, 2, 322, 320, 3, 2, 2, 2, 323, 324, 7, 88, 2, 2, 324, 353, 3, 2, 2, 2, 325, 326, 7, 131, 2, 2, 326, 328, 7, 90, 2, 2, 327, 329, 5, 18, 10, 2, 328, 327, 3, 2, 2, 2, 328, 329, 3, 2, 2, 2, 329, 330, 3, 2, 2, 2, 330, 336, 7, 154, 2, 2, 331, 332, 5, 4, 3, 2, 332, 333, 7, 154, 2, 2, 333, 335, 3, 2, 2, 2, 334, 331, 3, 2, 2, 2, 335, 338, 3, 2, 2, 2, 336, 334, 3, 2, 2, 2, 336, 337, 3, 2, 2, 2, 337, 342, 3, 2, 2, 2, 338, 336, 3, 2, 2, 2, 339, 341, 7, 154, 2, 2, 340, 339, 3, 2, 2, 2, 341, 344, 3, 2, 2, 2, 342, 340, 3, 2, 2, 2, 342, 343, 3, 2, 2, 2, 343, 345, 3, 2, 2, 2, 344, 342, 3, 2, 2, 2, 345, 353, 7, 91, 2, 2, 346, 348, 7, 131, 2, 2, 347, 349, 5, 20, 11, 2, 348, 347, 3, 2, 2, 2, 348, 349, 3, 2, 2, 2, 349, 353, 3, 2, 2, 2, 350, 351, 7, 89, 2, 2, 351, 353, 9, 7, 2, 2, 352, 298, 3, 2, 2, 2, 352, 300, 3, 2, 2, 2, 352, 303, 3, 2, 2, 2, 352, 306, 3, 2, 2, 2, 352, 325, 3, 2, 2, 2, 352, 346, 3, 2, 2, 2, 352, 350, 3, 2, 2, 2, 353, 17, 3, 2, 2, 2, 354, 359, 7, 131, 2, 2, 355, 356, 7, 136, 2, 2, 356, 358, 7, 131, 2, 2, 357, 355, 3, 2, 2, 2, 358, 361, 3, 2, 2, 2, 359, 357, 3, 2, 2, 2, 359, 360, 3, 2, 2, 2, 360, 19, 3, 2, 2, 2, 361, 359, 3, 2, 2, 2, 362, 367, 5, 28, 15, 2, 363, 364, 7, 136, 2, 2, 364, 366, 5, 28, 15, 2, 365, 363, 3, 2, 2, 2, 366, 369, 3, 2, 2, 2, 367, 365, 3, 2, 2, 2, 367, 368, 3, 2, 2, 2, 368, 21, 3, 2, 2, 2, 369, 367, 3, 2, 2, 2, 370, 371, 7, 92, 2, 2, 371, 376, 5, 24, 13, 2, 372, 373, 7, 136, 2, 2, 373, 375, 5, 24, 13, 2, 374, 372, 3, 2, 2, 2, 375, 378, 3, 2, 2, 2, 376, 374, 3, 2, 2, 2, 376, 377, 3, 2, 2, 2, 377, 391, 3, 2, 2, 2, 378, 376, 3, 2, 2, 2, 379, 380, 7, 93, 2, 2, 380, 385, 5, 26, 14, 2, 381, 382, 7, 136, 2, 2, 382, 384, 5, 26, 14, 2, 383, 381, 3, 2, 2, 2, 384, 387, 3, 2, 2, 2, 385, 383, 3, 2, 2, 2, 385, 386, 3, 2, 2, 2, 386, 391, 3, 2, 2, 2, 387, 385, 3, 2, 2, 2, 388, 389, 7, 94, 2, 2, 389, 391, 5, 28, 15, 2, 390, 370, 3, 2, 2, 2, 390, 379, 3, 2, 2, 2, 390, 388, 3, 2, 2, 2, 391, 23, 3, 2, 2, 2, 392, 395, 5, 28, 15, 2, 393, 395, 5, 10, 6, 2, 394, 392, 3, 2, 2, 2, 394, 393, 3, 2, 2, 2, 395, 25, 3, 2, 2, 2, 396, 397, 5, 28, 15, 2, 397, 27, 3, 2, 2, 2, 398, 399, 8, 15, 1, 2, 399, 400, 9, 8, 2, 2, 400, 414, 5, 28, 15, 20, 401, 402, 7, 134, 2, 2, 402, 403, 5, 28, 15, 2, 403, 404, 7, 135, 2, 2, 404, 414, 3, 2, 2, 2, 405, 414, 7, 125, 2, 2, 406, 414, 7, 124, 2, 2, 407, 414, 7, 126, 2, 2, 408, 414, 7, 127, 2, 2, 409, 414, 7, 128, 2, 2, 410, 414, 7, 95, 2, 2, 411, 414, 7, 131, 2, 2, 412, 414, 9, 7, 2, 2, 413, 398, 3, 2, 2, 2, 413, 401, 3, 2, 2, 2, 413, 405, 3, 2, 2, 2, 413, 406, 3, 2, 2, 2, 413, 407, 3, 2, 2, 2, 413, 408, 3, 2, 2, 2, 413, 409, 3, 2, 2, 2, 413, 410, 3, 2, 2, 2, 413, 411, 3, 2, 2, 2, 413, 412, 3, 2, 2, 2, 414, 441, 3, 2, 2, 2, 415, 416, 12, 19, 2, 2, 416, 417, 9, 9, 2, 2, 417, 440, 5, 28, 15, 20, 418, 419, 12, 18, 2, 2, 419, 420, 9, 10, 2, 2, 420, 440, 5, 28, 15, 19, 421, 422, 12, 17, 2, 2, 422, 423, 9, 11, 2, 2, 423, 440, 5, 28, 15, 18, 424, 425, 12, 16, 2, 2, 425, 426, 9, 12, 2, 2, 426, 440, 5, 28, 15, 16, 427, 428, 12, 15, 2, 2, 428, 429, 7, 141, 2, 2, 429, 440, 5, 28, 15, 15, 430, 431, 12, 14, 2, 2, 431, 432, 9, 13, 2, 2, 432, 440, 5, 28, 15, 15, 433, 434, 12, 13, 2, 2, 434, 435, 9, 14, 2, 2, 435, 440, 5, 28, 15, 14, 436, 437, 12, 12, 2, 2, 437, 438, 9, 15, 2, 2, 438, 440, 5, 28, 15, 13, 439, 415, 3, 2, 2, 2, 439, 418, 3, 2, 2, 2, 439, 421, 3, 2, 2, 2, 439, 424, 3, 2, 2, 2, 439, 427, 3, 2, 2, 2, 439, 430, 3, 2, 2, 2, 439, 433, 3, 2, 2, 2, 439, 436, 3, 2, 2, 2, 440, 443, 3, 2, 2, 2, 441, 439, 3, 2, 2, 2, 441, 442, 3, 2, 2, 2, 442, 29, 3, 2, 2, 2, 443, 441, 3, 2, 2, 2, 33, 33, 37, 42, 47, 53, 59, 64, 69, 74, 89, 124, 170, 263, 282, 294, 314, 320, 328, 336, 342, 348, 352, 359, 367, 376, 385, 390, 394, 413, 439, 441] \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.java b/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.java new file mode 100644 index 000000000..8f387fbca --- /dev/null +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.java @@ -0,0 +1,3658 @@ +// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 by ANTLR 4.9.2 +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class AsZ80Parser extends Parser { + static { RuntimeMetaData.checkVersion("4.9.2", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + COMMENT=1, COMMENT2=2, OPCODE_ADC=3, OPCODE_ADD=4, OPCODE_AND=5, OPCODE_BIT=6, + OPCODE_CALL=7, OPCODE_CCF=8, OPCODE_CP=9, OPCODE_CPD=10, OPCODE_CPDR=11, + OPCODE_CPI=12, OPCODE_CPIR=13, OPCODE_CPL=14, OPCODE_DAA=15, OPCODE_DEC=16, + OPCODE_DI=17, OPCODE_DJNZ=18, OPCODE_EI=19, OPCODE_EX=20, OPCODE_EXX=21, + OPCODE_HALT=22, OPCODE_IM=23, OPCODE_IN=24, OPCODE_INC=25, OPCODE_IND=26, + OPCODE_INDR=27, OPCODE_INI=28, OPCODE_INIR=29, OPCODE_JP=30, OPCODE_JR=31, + OPCODE_LD=32, OPCODE_LDD=33, OPCODE_LDDR=34, OPCODE_LDI=35, OPCODE_LDIR=36, + OPCODE_NEG=37, OPCODE_NOP=38, OPCODE_OR=39, OPCODE_OTDR=40, OPCODE_OTIR=41, + OPCODE_OUT=42, OPCODE_OUTD=43, OPCODE_OUTI=44, OPCODE_POP=45, OPCODE_PUSH=46, + OPCODE_RES=47, OPCODE_RET=48, OPCODE_RETI=49, OPCODE_RETN=50, OPCODE_RL=51, + OPCODE_RLA=52, OPCODE_RLC=53, OPCODE_RLCA=54, OPCODE_RLD=55, OPCODE_RR=56, + OPCODE_RRA=57, OPCODE_RRC=58, OPCODE_RRCA=59, OPCODE_RRD=60, OPCODE_RST=61, + OPCODE_SBC=62, OPCODE_SCF=63, OPCODE_SET=64, OPCODE_SLA=65, OPCODE_SRA=66, + OPCODE_SLL=67, OPCODE_SRL=68, OPCODE_SUB=69, OPCODE_XOR=70, COND_C=71, + COND_NC=72, COND_Z=73, COND_NZ=74, COND_M=75, COND_P=76, COND_PE=77, COND_PO=78, + COND_WS=79, COND_UNRECOGNIZED=80, PREP_ORG=81, PREP_EQU=82, PREP_SET=83, + PREP_VAR=84, PREP_IF=85, PREP_ENDIF=86, PREP_INCLUDE=87, PREP_MACRO=88, + PREP_ENDM=89, PREP_DB=90, PREP_DW=91, PREP_DS=92, PREP_ADDR=93, REG_A=94, + REG_B=95, REG_C=96, REG_D=97, REG_E=98, REG_H=99, REG_L=100, REG_IX=101, + REG_IXH=102, REG_IXL=103, REG_IY=104, REG_IYH=105, REG_IYL=106, REG_BC=107, + REG_DE=108, REG_HL=109, REG_SP=110, REG_AF=111, REG_AFF=112, REG_I=113, + REG_R=114, OP_MOD=115, OP_SHR=116, OP_SHL=117, OP_NOT=118, OP_AND=119, + OP_OR=120, OP_XOR=121, LIT_HEXNUMBER_1=122, LIT_NUMBER=123, LIT_HEXNUMBER_2=124, + LIT_OCTNUMBER=125, LIT_BINNUMBER=126, LIT_STRING_1=127, LIT_STRING_2=128, + ID_IDENTIFIER=129, ID_LABEL=130, ERROR=131, SEP_LPAR=132, SEP_RPAR=133, + SEP_COMMA=134, OP_ADD=135, OP_SUBTRACT=136, OP_MULTIPLY=137, OP_DIVIDE=138, + OP_EQUAL=139, OP_GT=140, OP_GTE=141, OP_LT=142, OP_LTE=143, OP_MOD_2=144, + OP_SHR_2=145, OP_SHL_2=146, OP_NOT_2=147, OP_AND_2=148, OP_OR_2=149, OP_XOR_2=150, + WS=151, EOL=152; + public static final int + RULE_rStart = 0, RULE_rLine = 1, RULE_rStatement = 2, RULE_rInstruction = 3, + RULE_r8bitInstruction = 4, RULE_rRegister = 5, RULE_cCondition = 6, RULE_rPseudoCode = 7, + RULE_rMacroParameters = 8, RULE_rMacroArguments = 9, RULE_rData = 10, + RULE_rDBdata = 11, RULE_rDWdata = 12, RULE_rExpression = 13; + private static String[] makeRuleNames() { + return new String[] { + "rStart", "rLine", "rStatement", "rInstruction", "r8bitInstruction", + "rRegister", "cCondition", "rPseudoCode", "rMacroParameters", "rMacroArguments", + "rData", "rDBdata", "rDWdata", "rExpression" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, "'$'", null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + "'('", "')'", "','", "'+'", "'-'", "'*'", "'/'", "'='", "'>'", "'>='", + "'<'", "'<='", "'%'", "'>>'", "'<<'", "'!'", "'&'", "'|'", "'~'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "COMMENT", "COMMENT2", "OPCODE_ADC", "OPCODE_ADD", "OPCODE_AND", + "OPCODE_BIT", "OPCODE_CALL", "OPCODE_CCF", "OPCODE_CP", "OPCODE_CPD", + "OPCODE_CPDR", "OPCODE_CPI", "OPCODE_CPIR", "OPCODE_CPL", "OPCODE_DAA", + "OPCODE_DEC", "OPCODE_DI", "OPCODE_DJNZ", "OPCODE_EI", "OPCODE_EX", "OPCODE_EXX", + "OPCODE_HALT", "OPCODE_IM", "OPCODE_IN", "OPCODE_INC", "OPCODE_IND", + "OPCODE_INDR", "OPCODE_INI", "OPCODE_INIR", "OPCODE_JP", "OPCODE_JR", + "OPCODE_LD", "OPCODE_LDD", "OPCODE_LDDR", "OPCODE_LDI", "OPCODE_LDIR", + "OPCODE_NEG", "OPCODE_NOP", "OPCODE_OR", "OPCODE_OTDR", "OPCODE_OTIR", + "OPCODE_OUT", "OPCODE_OUTD", "OPCODE_OUTI", "OPCODE_POP", "OPCODE_PUSH", + "OPCODE_RES", "OPCODE_RET", "OPCODE_RETI", "OPCODE_RETN", "OPCODE_RL", + "OPCODE_RLA", "OPCODE_RLC", "OPCODE_RLCA", "OPCODE_RLD", "OPCODE_RR", + "OPCODE_RRA", "OPCODE_RRC", "OPCODE_RRCA", "OPCODE_RRD", "OPCODE_RST", + "OPCODE_SBC", "OPCODE_SCF", "OPCODE_SET", "OPCODE_SLA", "OPCODE_SRA", + "OPCODE_SLL", "OPCODE_SRL", "OPCODE_SUB", "OPCODE_XOR", "COND_C", "COND_NC", + "COND_Z", "COND_NZ", "COND_M", "COND_P", "COND_PE", "COND_PO", "COND_WS", + "COND_UNRECOGNIZED", "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_VAR", + "PREP_IF", "PREP_ENDIF", "PREP_INCLUDE", "PREP_MACRO", "PREP_ENDM", "PREP_DB", + "PREP_DW", "PREP_DS", "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", + "REG_E", "REG_H", "REG_L", "REG_IX", "REG_IXH", "REG_IXL", "REG_IY", + "REG_IYH", "REG_IYL", "REG_BC", "REG_DE", "REG_HL", "REG_SP", "REG_AF", + "REG_AFF", "REG_I", "REG_R", "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", + "OP_AND", "OP_OR", "OP_XOR", "LIT_HEXNUMBER_1", "LIT_NUMBER", "LIT_HEXNUMBER_2", + "LIT_OCTNUMBER", "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", + "ID_LABEL", "ERROR", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", + "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_GT", "OP_GTE", "OP_LT", "OP_LTE", + "OP_MOD_2", "OP_SHR_2", "OP_SHL_2", "OP_NOT_2", "OP_AND_2", "OP_OR_2", + "OP_XOR_2", "WS", "EOL" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "AsZ80Parser.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public AsZ80Parser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + public static class RStartContext extends ParserRuleContext { + public TerminalNode EOF() { return getToken(AsZ80Parser.EOF, 0); } + public List EOL() { return getTokens(AsZ80Parser.EOL); } + public TerminalNode EOL(int i) { + return getToken(AsZ80Parser.EOL, i); + } + public List rLine() { + return getRuleContexts(RLineContext.class); + } + public RLineContext rLine(int i) { + return getRuleContext(RLineContext.class,i); + } + public RStartContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rStart; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRStart(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRStart(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRStart(this); + else return visitor.visitChildren(this); + } + } + + public final RStartContext rStart() throws RecognitionException { + RStartContext _localctx = new RStartContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_rStart); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(31); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,0,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(28); + match(EOL); + } + } + } + setState(33); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,0,_ctx); + } + setState(35); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) { + case 1: + { + setState(34); + rLine(); + } + break; + } + setState(45); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,3,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(38); + _errHandler.sync(this); + _alt = 1; + do { + switch (_alt) { + case 1: + { + { + setState(37); + match(EOL); + } + } + break; + default: + throw new NoViableAltException(this); + } + setState(40); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,2,_ctx); + } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); + setState(42); + rLine(); + } + } + } + setState(47); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,3,_ctx); + } + setState(51); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==EOL) { + { + { + setState(48); + match(EOL); + } + } + setState(53); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(54); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RLineContext extends ParserRuleContext { + public Token label; + public RStatementContext statement; + public RStatementContext rStatement() { + return getRuleContext(RStatementContext.class,0); + } + public List EOL() { return getTokens(AsZ80Parser.EOL); } + public TerminalNode EOL(int i) { + return getToken(AsZ80Parser.EOL, i); + } + public TerminalNode ID_LABEL() { return getToken(AsZ80Parser.ID_LABEL, 0); } + public RLineContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rLine; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRLine(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRLine(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRLine(this); + else return visitor.visitChildren(this); + } + } + + public final RLineContext rLine() throws RecognitionException { + RLineContext _localctx = new RLineContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_rLine); + int _la; + try { + setState(67); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(57); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==ID_LABEL) { + { + setState(56); + ((RLineContext)_localctx).label = match(ID_LABEL); + } + } + + setState(62); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==EOL) { + { + { + setState(59); + match(EOL); + } + } + setState(64); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(65); + ((RLineContext)_localctx).statement = rStatement(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(66); + ((RLineContext)_localctx).label = match(ID_LABEL); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RStatementContext extends ParserRuleContext { + public RInstructionContext instr; + public RPseudoCodeContext pseudo; + public RDataContext data; + public RInstructionContext rInstruction() { + return getRuleContext(RInstructionContext.class,0); + } + public RPseudoCodeContext rPseudoCode() { + return getRuleContext(RPseudoCodeContext.class,0); + } + public RDataContext rData() { + return getRuleContext(RDataContext.class,0); + } + public RStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRStatement(this); + else return visitor.visitChildren(this); + } + } + + public final RStatementContext rStatement() throws RecognitionException { + RStatementContext _localctx = new RStatementContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_rStatement); + try { + setState(72); + _errHandler.sync(this); + switch (_input.LA(1)) { + case OPCODE_ADC: + case OPCODE_ADD: + case OPCODE_AND: + case OPCODE_CALL: + case OPCODE_CCF: + case OPCODE_CP: + case OPCODE_CPL: + case OPCODE_DAA: + case OPCODE_DEC: + case OPCODE_DI: + case OPCODE_EI: + case OPCODE_EX: + case OPCODE_EXX: + case OPCODE_HALT: + case OPCODE_IN: + case OPCODE_INC: + case OPCODE_JP: + case OPCODE_JR: + case OPCODE_LD: + case OPCODE_NOP: + case OPCODE_OR: + case OPCODE_OUT: + case OPCODE_POP: + case OPCODE_PUSH: + case OPCODE_RET: + case OPCODE_RLA: + case OPCODE_RLCA: + case OPCODE_RRA: + case OPCODE_RRCA: + case OPCODE_RST: + case OPCODE_SBC: + case OPCODE_SCF: + case OPCODE_SUB: + case OPCODE_XOR: + enterOuterAlt(_localctx, 1); + { + setState(69); + ((RStatementContext)_localctx).instr = rInstruction(); + } + break; + case PREP_ORG: + case PREP_IF: + case PREP_INCLUDE: + case ID_IDENTIFIER: + enterOuterAlt(_localctx, 2); + { + setState(70); + ((RStatementContext)_localctx).pseudo = rPseudoCode(); + } + break; + case PREP_DB: + case PREP_DW: + case PREP_DS: + enterOuterAlt(_localctx, 3); + { + setState(71); + ((RStatementContext)_localctx).data = rData(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RInstructionContext extends ParserRuleContext { + public RInstructionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rInstruction; } + + public RInstructionContext() { } + public void copyFrom(RInstructionContext ctx) { + super.copyFrom(ctx); + } + } + public static class InstrRegExprContext extends RInstructionContext { + public Token opcode; + public RRegisterContext reg; + public RExpressionContext expr; + public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } + public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } + public RRegisterContext rRegister() { + return getRuleContext(RRegisterContext.class,0); + } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public InstrRegExprContext(RInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegExpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegExpr(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegExpr(this); + else return visitor.visitChildren(this); + } + } + public static class Instr8bitContext extends RInstructionContext { + public R8bitInstructionContext r8bitInstruction() { + return getRuleContext(R8bitInstructionContext.class,0); + } + public Instr8bitContext(RInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstr8bit(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstr8bit(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstr8bit(this); + else return visitor.visitChildren(this); + } + } + public static class InstrExprRegPairContext extends RInstructionContext { + public Token opcode; + public RExpressionContext expr; + public Token regpair; + public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } + public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } + public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } + public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public TerminalNode REG_HL() { return getToken(AsZ80Parser.REG_HL, 0); } + public InstrExprRegPairContext(RInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrExprRegPair(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrExprRegPair(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrExprRegPair(this); + else return visitor.visitChildren(this); + } + } + public static class InstrExprContext extends RInstructionContext { + public Token opcode; + public RExpressionContext expr; + public TerminalNode REG_A() { return getToken(AsZ80Parser.REG_A, 0); } + public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } + public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } + public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } + public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public TerminalNode OPCODE_CALL() { return getToken(AsZ80Parser.OPCODE_CALL, 0); } + public TerminalNode OPCODE_ADD() { return getToken(AsZ80Parser.OPCODE_ADD, 0); } + public TerminalNode OPCODE_ADC() { return getToken(AsZ80Parser.OPCODE_ADC, 0); } + public TerminalNode OPCODE_OUT() { return getToken(AsZ80Parser.OPCODE_OUT, 0); } + public TerminalNode OPCODE_SUB() { return getToken(AsZ80Parser.OPCODE_SUB, 0); } + public TerminalNode OPCODE_IN() { return getToken(AsZ80Parser.OPCODE_IN, 0); } + public TerminalNode OPCODE_SBC() { return getToken(AsZ80Parser.OPCODE_SBC, 0); } + public TerminalNode OPCODE_AND() { return getToken(AsZ80Parser.OPCODE_AND, 0); } + public TerminalNode OPCODE_XOR() { return getToken(AsZ80Parser.OPCODE_XOR, 0); } + public TerminalNode OPCODE_OR() { return getToken(AsZ80Parser.OPCODE_OR, 0); } + public TerminalNode OPCODE_CP() { return getToken(AsZ80Parser.OPCODE_CP, 0); } + public InstrExprContext(RInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrExpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrExpr(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrExpr(this); + else return visitor.visitChildren(this); + } + } + public static class InstrExprRegContext extends RInstructionContext { + public Token opcode; + public RExpressionContext expr; + public Token reg; + public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } + public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } + public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } + public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public TerminalNode REG_A() { return getToken(AsZ80Parser.REG_A, 0); } + public InstrExprRegContext(RInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrExprReg(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrExprReg(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrExprReg(this); + else return visitor.visitChildren(this); + } + } + public static class InstrCondExprContext extends RInstructionContext { + public Token opcode; + public Token cond; + public RExpressionContext expr; + public TerminalNode OPCODE_JR() { return getToken(AsZ80Parser.OPCODE_JR, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } + public TerminalNode COND_NZ() { return getToken(AsZ80Parser.COND_NZ, 0); } + public TerminalNode COND_Z() { return getToken(AsZ80Parser.COND_Z, 0); } + public TerminalNode COND_NC() { return getToken(AsZ80Parser.COND_NC, 0); } + public TerminalNode COND_C() { return getToken(AsZ80Parser.COND_C, 0); } + public TerminalNode OPCODE_JP() { return getToken(AsZ80Parser.OPCODE_JP, 0); } + public CConditionContext cCondition() { + return getRuleContext(CConditionContext.class,0); + } + public TerminalNode OPCODE_CALL() { return getToken(AsZ80Parser.OPCODE_CALL, 0); } + public InstrCondExprContext(RInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrCondExpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrCondExpr(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrCondExpr(this); + else return visitor.visitChildren(this); + } + } + public static class InstrRegPairExprContext extends RInstructionContext { + public Token opcode; + public Token regpair; + public RExpressionContext expr; + public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } + public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public TerminalNode REG_BC() { return getToken(AsZ80Parser.REG_BC, 0); } + public TerminalNode REG_DE() { return getToken(AsZ80Parser.REG_DE, 0); } + public TerminalNode REG_HL() { return getToken(AsZ80Parser.REG_HL, 0); } + public TerminalNode REG_SP() { return getToken(AsZ80Parser.REG_SP, 0); } + public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } + public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } + public InstrRegPairExprContext(RInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegPairExpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegPairExpr(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegPairExpr(this); + else return visitor.visitChildren(this); + } + } + + public final RInstructionContext rInstruction() throws RecognitionException { + RInstructionContext _localctx = new RInstructionContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_rInstruction); + int _la; + try { + setState(168); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) { + case 1: + _localctx = new Instr8bitContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(74); + r8bitInstruction(); + } + break; + case 2: + _localctx = new InstrRegPairExprContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(75); + ((InstrRegPairExprContext)_localctx).opcode = match(OPCODE_LD); + setState(76); + ((InstrRegPairExprContext)_localctx).regpair = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_SP - 107)))) != 0)) ) { + ((InstrRegPairExprContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(77); + match(SEP_COMMA); + setState(78); + ((InstrRegPairExprContext)_localctx).expr = rExpression(0); + } + break; + case 3: + _localctx = new InstrRegExprContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(79); + ((InstrRegExprContext)_localctx).opcode = match(OPCODE_LD); + setState(80); + ((InstrRegExprContext)_localctx).reg = rRegister(); + setState(81); + match(SEP_COMMA); + setState(82); + ((InstrRegExprContext)_localctx).expr = rExpression(0); + } + break; + case 4: + _localctx = new InstrCondExprContext(_localctx); + enterOuterAlt(_localctx, 4); + { + setState(84); + ((InstrCondExprContext)_localctx).opcode = match(OPCODE_JR); + setState(87); + _errHandler.sync(this); + _la = _input.LA(1); + if (((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (COND_C - 71)) | (1L << (COND_NC - 71)) | (1L << (COND_Z - 71)) | (1L << (COND_NZ - 71)))) != 0)) { + { + setState(85); + ((InstrCondExprContext)_localctx).cond = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (COND_C - 71)) | (1L << (COND_NC - 71)) | (1L << (COND_Z - 71)) | (1L << (COND_NZ - 71)))) != 0)) ) { + ((InstrCondExprContext)_localctx).cond = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(86); + match(SEP_COMMA); + } + } + + setState(89); + ((InstrCondExprContext)_localctx).expr = rExpression(0); + } + break; + case 5: + _localctx = new InstrExprRegPairContext(_localctx); + enterOuterAlt(_localctx, 5); + { + setState(90); + ((InstrExprRegPairContext)_localctx).opcode = match(OPCODE_LD); + setState(91); + match(SEP_LPAR); + setState(92); + ((InstrExprRegPairContext)_localctx).expr = rExpression(0); + setState(93); + match(SEP_RPAR); + setState(94); + match(SEP_COMMA); + setState(95); + ((InstrExprRegPairContext)_localctx).regpair = match(REG_HL); + } + break; + case 6: + _localctx = new InstrRegPairExprContext(_localctx); + enterOuterAlt(_localctx, 6); + { + setState(97); + ((InstrRegPairExprContext)_localctx).opcode = match(OPCODE_LD); + setState(98); + ((InstrRegPairExprContext)_localctx).regpair = match(REG_HL); + setState(99); + match(SEP_COMMA); + setState(100); + match(SEP_LPAR); + setState(101); + ((InstrRegPairExprContext)_localctx).expr = rExpression(0); + setState(102); + match(SEP_RPAR); + } + break; + case 7: + _localctx = new InstrExprRegContext(_localctx); + enterOuterAlt(_localctx, 7); + { + setState(104); + ((InstrExprRegContext)_localctx).opcode = match(OPCODE_LD); + setState(105); + match(SEP_LPAR); + setState(106); + ((InstrExprRegContext)_localctx).expr = rExpression(0); + setState(107); + match(SEP_RPAR); + setState(108); + match(SEP_COMMA); + setState(109); + ((InstrExprRegContext)_localctx).reg = match(REG_A); + } + break; + case 8: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 8); + { + setState(111); + ((InstrExprContext)_localctx).opcode = match(OPCODE_LD); + setState(112); + match(REG_A); + setState(113); + match(SEP_COMMA); + setState(114); + match(SEP_LPAR); + setState(115); + ((InstrExprContext)_localctx).expr = rExpression(0); + setState(116); + match(SEP_RPAR); + } + break; + case 9: + _localctx = new InstrCondExprContext(_localctx); + enterOuterAlt(_localctx, 9); + { + setState(118); + ((InstrCondExprContext)_localctx).opcode = match(OPCODE_JP); + setState(122); + _errHandler.sync(this); + _la = _input.LA(1); + if (((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (COND_C - 71)) | (1L << (COND_NC - 71)) | (1L << (COND_Z - 71)) | (1L << (COND_NZ - 71)) | (1L << (COND_M - 71)) | (1L << (COND_P - 71)) | (1L << (COND_PE - 71)) | (1L << (COND_PO - 71)))) != 0)) { + { + setState(119); + ((InstrCondExprContext)_localctx).cond = cCondition(); + setState(120); + match(SEP_COMMA); + } + } + + setState(124); + ((InstrCondExprContext)_localctx).expr = rExpression(0); + } + break; + case 10: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 10); + { + setState(125); + ((InstrExprContext)_localctx).opcode = match(OPCODE_CALL); + setState(126); + ((InstrExprContext)_localctx).expr = rExpression(0); + } + break; + case 11: + _localctx = new InstrCondExprContext(_localctx); + enterOuterAlt(_localctx, 11); + { + setState(127); + ((InstrCondExprContext)_localctx).opcode = match(OPCODE_CALL); + setState(128); + ((InstrCondExprContext)_localctx).cond = cCondition(); + setState(129); + match(SEP_COMMA); + setState(130); + ((InstrCondExprContext)_localctx).expr = rExpression(0); + } + break; + case 12: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 12); + { + setState(132); + ((InstrExprContext)_localctx).opcode = match(OPCODE_ADD); + setState(133); + match(REG_A); + setState(134); + match(SEP_COMMA); + setState(135); + ((InstrExprContext)_localctx).expr = rExpression(0); + } + break; + case 13: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 13); + { + setState(136); + ((InstrExprContext)_localctx).opcode = match(OPCODE_ADC); + setState(137); + match(REG_A); + setState(138); + match(SEP_COMMA); + setState(139); + ((InstrExprContext)_localctx).expr = rExpression(0); + } + break; + case 14: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 14); + { + setState(140); + ((InstrExprContext)_localctx).opcode = match(OPCODE_OUT); + setState(141); + match(SEP_LPAR); + setState(142); + ((InstrExprContext)_localctx).expr = rExpression(0); + setState(143); + match(SEP_RPAR); + setState(144); + match(SEP_COMMA); + setState(145); + match(REG_A); + } + break; + case 15: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 15); + { + setState(147); + ((InstrExprContext)_localctx).opcode = match(OPCODE_SUB); + setState(148); + ((InstrExprContext)_localctx).expr = rExpression(0); + } + break; + case 16: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 16); + { + setState(149); + ((InstrExprContext)_localctx).opcode = match(OPCODE_IN); + setState(150); + match(REG_A); + setState(151); + match(SEP_COMMA); + setState(152); + match(SEP_LPAR); + setState(153); + ((InstrExprContext)_localctx).expr = rExpression(0); + setState(154); + match(SEP_RPAR); + } + break; + case 17: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 17); + { + setState(156); + ((InstrExprContext)_localctx).opcode = match(OPCODE_SBC); + setState(157); + match(REG_A); + setState(158); + match(SEP_COMMA); + setState(159); + ((InstrExprContext)_localctx).expr = rExpression(0); + } + break; + case 18: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 18); + { + setState(160); + ((InstrExprContext)_localctx).opcode = match(OPCODE_AND); + setState(161); + ((InstrExprContext)_localctx).expr = rExpression(0); + } + break; + case 19: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 19); + { + setState(162); + ((InstrExprContext)_localctx).opcode = match(OPCODE_XOR); + setState(163); + ((InstrExprContext)_localctx).expr = rExpression(0); + } + break; + case 20: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 20); + { + setState(164); + ((InstrExprContext)_localctx).opcode = match(OPCODE_OR); + setState(165); + ((InstrExprContext)_localctx).expr = rExpression(0); + } + break; + case 21: + _localctx = new InstrExprContext(_localctx); + enterOuterAlt(_localctx, 21); + { + setState(166); + ((InstrExprContext)_localctx).opcode = match(OPCODE_CP); + setState(167); + ((InstrExprContext)_localctx).expr = rExpression(0); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class R8bitInstructionContext extends ParserRuleContext { + public R8bitInstructionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_r8bitInstruction; } + + public R8bitInstructionContext() { } + public void copyFrom(R8bitInstructionContext ctx) { + super.copyFrom(ctx); + } + } + public static class InstrRegPairRegContext extends R8bitInstructionContext { + public Token opcode; + public Token regpair; + public RRegisterContext reg; + public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } + public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } + public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } + public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } + public TerminalNode REG_HL() { return getToken(AsZ80Parser.REG_HL, 0); } + public RRegisterContext rRegister() { + return getRuleContext(RRegisterContext.class,0); + } + public InstrRegPairRegContext(R8bitInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegPairReg(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegPairReg(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegPairReg(this); + else return visitor.visitChildren(this); + } + } + public static class Instr8bitExprContext extends R8bitInstructionContext { + public Token opcode; + public RExpressionContext expr; + public TerminalNode OPCODE_RST() { return getToken(AsZ80Parser.OPCODE_RST, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public Instr8bitExprContext(R8bitInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstr8bitExpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstr8bitExpr(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstr8bitExpr(this); + else return visitor.visitChildren(this); + } + } + public static class InstrRegPairContext extends R8bitInstructionContext { + public Token opcode; + public Token regpair; + public Token regpairM; + public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } + public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } + public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } + public TerminalNode REG_A() { return getToken(AsZ80Parser.REG_A, 0); } + public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } + public TerminalNode REG_BC() { return getToken(AsZ80Parser.REG_BC, 0); } + public TerminalNode REG_DE() { return getToken(AsZ80Parser.REG_DE, 0); } + public TerminalNode OPCODE_INC() { return getToken(AsZ80Parser.OPCODE_INC, 0); } + public List REG_HL() { return getTokens(AsZ80Parser.REG_HL); } + public TerminalNode REG_HL(int i) { + return getToken(AsZ80Parser.REG_HL, i); + } + public TerminalNode REG_SP() { return getToken(AsZ80Parser.REG_SP, 0); } + public TerminalNode OPCODE_ADD() { return getToken(AsZ80Parser.OPCODE_ADD, 0); } + public TerminalNode OPCODE_DEC() { return getToken(AsZ80Parser.OPCODE_DEC, 0); } + public TerminalNode OPCODE_POP() { return getToken(AsZ80Parser.OPCODE_POP, 0); } + public TerminalNode REG_AF() { return getToken(AsZ80Parser.REG_AF, 0); } + public TerminalNode OPCODE_PUSH() { return getToken(AsZ80Parser.OPCODE_PUSH, 0); } + public TerminalNode OPCODE_JP() { return getToken(AsZ80Parser.OPCODE_JP, 0); } + public InstrRegPairContext(R8bitInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegPair(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegPair(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegPair(this); + else return visitor.visitChildren(this); + } + } + public static class InstrRegContext extends R8bitInstructionContext { + public Token opcode; + public RRegisterContext reg; + public TerminalNode OPCODE_INC() { return getToken(AsZ80Parser.OPCODE_INC, 0); } + public RRegisterContext rRegister() { + return getRuleContext(RRegisterContext.class,0); + } + public TerminalNode OPCODE_DEC() { return getToken(AsZ80Parser.OPCODE_DEC, 0); } + public TerminalNode REG_A() { return getToken(AsZ80Parser.REG_A, 0); } + public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } + public TerminalNode OPCODE_ADD() { return getToken(AsZ80Parser.OPCODE_ADD, 0); } + public TerminalNode OPCODE_ADC() { return getToken(AsZ80Parser.OPCODE_ADC, 0); } + public TerminalNode OPCODE_SUB() { return getToken(AsZ80Parser.OPCODE_SUB, 0); } + public TerminalNode OPCODE_SBC() { return getToken(AsZ80Parser.OPCODE_SBC, 0); } + public TerminalNode OPCODE_AND() { return getToken(AsZ80Parser.OPCODE_AND, 0); } + public TerminalNode OPCODE_XOR() { return getToken(AsZ80Parser.OPCODE_XOR, 0); } + public TerminalNode OPCODE_OR() { return getToken(AsZ80Parser.OPCODE_OR, 0); } + public TerminalNode OPCODE_CP() { return getToken(AsZ80Parser.OPCODE_CP, 0); } + public InstrRegContext(R8bitInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrReg(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrReg(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrReg(this); + else return visitor.visitChildren(this); + } + } + public static class InstrCondContext extends R8bitInstructionContext { + public Token opcode; + public CConditionContext cond; + public TerminalNode OPCODE_RET() { return getToken(AsZ80Parser.OPCODE_RET, 0); } + public CConditionContext cCondition() { + return getRuleContext(CConditionContext.class,0); + } + public InstrCondContext(R8bitInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrCond(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrCond(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrCond(this); + else return visitor.visitChildren(this); + } + } + public static class InstrNoArgsContext extends R8bitInstructionContext { + public Token opcode; + public TerminalNode OPCODE_NOP() { return getToken(AsZ80Parser.OPCODE_NOP, 0); } + public TerminalNode OPCODE_RLCA() { return getToken(AsZ80Parser.OPCODE_RLCA, 0); } + public TerminalNode OPCODE_RRCA() { return getToken(AsZ80Parser.OPCODE_RRCA, 0); } + public TerminalNode OPCODE_RLA() { return getToken(AsZ80Parser.OPCODE_RLA, 0); } + public TerminalNode OPCODE_RRA() { return getToken(AsZ80Parser.OPCODE_RRA, 0); } + public TerminalNode OPCODE_DAA() { return getToken(AsZ80Parser.OPCODE_DAA, 0); } + public TerminalNode OPCODE_CPL() { return getToken(AsZ80Parser.OPCODE_CPL, 0); } + public TerminalNode OPCODE_SCF() { return getToken(AsZ80Parser.OPCODE_SCF, 0); } + public TerminalNode OPCODE_CCF() { return getToken(AsZ80Parser.OPCODE_CCF, 0); } + public TerminalNode OPCODE_HALT() { return getToken(AsZ80Parser.OPCODE_HALT, 0); } + public TerminalNode OPCODE_EXX() { return getToken(AsZ80Parser.OPCODE_EXX, 0); } + public TerminalNode OPCODE_DI() { return getToken(AsZ80Parser.OPCODE_DI, 0); } + public TerminalNode OPCODE_EI() { return getToken(AsZ80Parser.OPCODE_EI, 0); } + public InstrNoArgsContext(R8bitInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrNoArgs(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrNoArgs(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrNoArgs(this); + else return visitor.visitChildren(this); + } + } + public static class InstrRegRegContext extends R8bitInstructionContext { + public Token opcode; + public RRegisterContext dst; + public RRegisterContext src; + public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } + public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } + public List rRegister() { + return getRuleContexts(RRegisterContext.class); + } + public RRegisterContext rRegister(int i) { + return getRuleContext(RRegisterContext.class,i); + } + public InstrRegRegContext(R8bitInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegReg(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegReg(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegReg(this); + else return visitor.visitChildren(this); + } + } + public static class InstrRegPairRegPairContext extends R8bitInstructionContext { + public Token opcode; + public Token src; + public Token dst; + public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } + public TerminalNode OPCODE_EX() { return getToken(AsZ80Parser.OPCODE_EX, 0); } + public TerminalNode REG_AF() { return getToken(AsZ80Parser.REG_AF, 0); } + public TerminalNode REG_AFF() { return getToken(AsZ80Parser.REG_AFF, 0); } + public TerminalNode REG_DE() { return getToken(AsZ80Parser.REG_DE, 0); } + public TerminalNode REG_HL() { return getToken(AsZ80Parser.REG_HL, 0); } + public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } + public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } + public TerminalNode REG_SP() { return getToken(AsZ80Parser.REG_SP, 0); } + public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } + public InstrRegPairRegPairContext(R8bitInstructionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegPairRegPair(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegPairRegPair(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegPairRegPair(this); + else return visitor.visitChildren(this); + } + } + + public final R8bitInstructionContext r8bitInstruction() throws RecognitionException { + R8bitInstructionContext _localctx = new R8bitInstructionContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_r8bitInstruction); + int _la; + try { + setState(280); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) { + case 1: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(170); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_NOP); + } + break; + case 2: + _localctx = new InstrRegPairContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(171); + ((InstrRegPairContext)_localctx).opcode = match(OPCODE_LD); + setState(172); + match(SEP_LPAR); + setState(173); + ((InstrRegPairContext)_localctx).regpair = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==REG_BC || _la==REG_DE) ) { + ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(174); + match(SEP_RPAR); + setState(175); + match(SEP_COMMA); + setState(176); + match(REG_A); + } + break; + case 3: + _localctx = new InstrRegPairRegContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(177); + ((InstrRegPairRegContext)_localctx).opcode = match(OPCODE_LD); + setState(178); + match(SEP_LPAR); + setState(179); + ((InstrRegPairRegContext)_localctx).regpair = match(REG_HL); + setState(180); + match(SEP_RPAR); + setState(181); + match(SEP_COMMA); + setState(182); + ((InstrRegPairRegContext)_localctx).reg = rRegister(); + } + break; + case 4: + _localctx = new InstrRegPairContext(_localctx); + enterOuterAlt(_localctx, 4); + { + setState(183); + ((InstrRegPairContext)_localctx).opcode = match(OPCODE_INC); + setState(184); + ((InstrRegPairContext)_localctx).regpair = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_SP - 107)))) != 0)) ) { + ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + break; + case 5: + _localctx = new InstrRegContext(_localctx); + enterOuterAlt(_localctx, 5); + { + setState(185); + ((InstrRegContext)_localctx).opcode = match(OPCODE_INC); + setState(186); + ((InstrRegContext)_localctx).reg = rRegister(); + } + break; + case 6: + _localctx = new InstrRegContext(_localctx); + enterOuterAlt(_localctx, 6); + { + setState(187); + ((InstrRegContext)_localctx).opcode = match(OPCODE_DEC); + setState(188); + ((InstrRegContext)_localctx).reg = rRegister(); + } + break; + case 7: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 7); + { + setState(189); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_RLCA); + } + break; + case 8: + _localctx = new InstrRegPairRegPairContext(_localctx); + enterOuterAlt(_localctx, 8); + { + setState(190); + ((InstrRegPairRegPairContext)_localctx).opcode = match(OPCODE_EX); + setState(191); + ((InstrRegPairRegPairContext)_localctx).src = match(REG_AF); + setState(192); + match(SEP_COMMA); + setState(193); + ((InstrRegPairRegPairContext)_localctx).dst = match(REG_AFF); + } + break; + case 9: + _localctx = new InstrRegPairRegPairContext(_localctx); + enterOuterAlt(_localctx, 9); + { + setState(194); + ((InstrRegPairRegPairContext)_localctx).opcode = match(OPCODE_EX); + setState(195); + ((InstrRegPairRegPairContext)_localctx).src = match(REG_DE); + setState(196); + match(SEP_COMMA); + setState(197); + ((InstrRegPairRegPairContext)_localctx).dst = match(REG_HL); + } + break; + case 10: + _localctx = new InstrRegPairRegPairContext(_localctx); + enterOuterAlt(_localctx, 10); + { + setState(198); + ((InstrRegPairRegPairContext)_localctx).opcode = match(OPCODE_EX); + setState(199); + match(SEP_LPAR); + setState(200); + ((InstrRegPairRegPairContext)_localctx).src = match(REG_SP); + setState(201); + match(SEP_RPAR); + setState(202); + match(SEP_COMMA); + setState(203); + ((InstrRegPairRegPairContext)_localctx).dst = match(REG_HL); + } + break; + case 11: + _localctx = new InstrRegPairContext(_localctx); + enterOuterAlt(_localctx, 11); + { + setState(204); + ((InstrRegPairContext)_localctx).opcode = match(OPCODE_ADD); + setState(205); + match(REG_HL); + setState(206); + match(SEP_COMMA); + setState(207); + ((InstrRegPairContext)_localctx).regpair = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_SP - 107)))) != 0)) ) { + ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + break; + case 12: + _localctx = new InstrRegPairContext(_localctx); + enterOuterAlt(_localctx, 12); + { + setState(208); + ((InstrRegPairContext)_localctx).opcode = match(OPCODE_LD); + setState(209); + match(REG_A); + setState(210); + match(SEP_COMMA); + setState(211); + match(SEP_LPAR); + setState(212); + ((InstrRegPairContext)_localctx).regpair = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==REG_BC || _la==REG_DE) ) { + ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(213); + match(SEP_RPAR); + } + break; + case 13: + _localctx = new InstrRegPairContext(_localctx); + enterOuterAlt(_localctx, 13); + { + setState(214); + ((InstrRegPairContext)_localctx).opcode = match(OPCODE_DEC); + setState(215); + ((InstrRegPairContext)_localctx).regpair = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_SP - 107)))) != 0)) ) { + ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + break; + case 14: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 14); + { + setState(216); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_RRCA); + } + break; + case 15: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 15); + { + setState(217); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_RLA); + } + break; + case 16: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 16); + { + setState(218); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_RRA); + } + break; + case 17: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 17); + { + setState(219); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_DAA); + } + break; + case 18: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 18); + { + setState(220); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_CPL); + } + break; + case 19: + _localctx = new InstrRegPairContext(_localctx); + enterOuterAlt(_localctx, 19); + { + setState(221); + ((InstrRegPairContext)_localctx).opcode = match(OPCODE_INC); + setState(222); + match(SEP_LPAR); + setState(223); + ((InstrRegPairContext)_localctx).regpairM = match(REG_HL); + setState(224); + match(SEP_RPAR); + } + break; + case 20: + _localctx = new InstrRegPairContext(_localctx); + enterOuterAlt(_localctx, 20); + { + setState(225); + ((InstrRegPairContext)_localctx).opcode = match(OPCODE_DEC); + setState(226); + match(SEP_LPAR); + setState(227); + ((InstrRegPairContext)_localctx).regpairM = match(REG_HL); + setState(228); + match(SEP_RPAR); + } + break; + case 21: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 21); + { + setState(229); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_SCF); + } + break; + case 22: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 22); + { + setState(230); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_CCF); + } + break; + case 23: + _localctx = new InstrRegRegContext(_localctx); + enterOuterAlt(_localctx, 23); + { + setState(231); + ((InstrRegRegContext)_localctx).opcode = match(OPCODE_LD); + setState(232); + ((InstrRegRegContext)_localctx).dst = rRegister(); + setState(233); + match(SEP_COMMA); + setState(234); + ((InstrRegRegContext)_localctx).src = rRegister(); + } + break; + case 24: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 24); + { + setState(236); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_HALT); + } + break; + case 25: + _localctx = new InstrRegContext(_localctx); + enterOuterAlt(_localctx, 25); + { + setState(237); + ((InstrRegContext)_localctx).opcode = match(OPCODE_ADD); + setState(238); + match(REG_A); + setState(239); + match(SEP_COMMA); + setState(240); + ((InstrRegContext)_localctx).reg = rRegister(); + } + break; + case 26: + _localctx = new InstrRegContext(_localctx); + enterOuterAlt(_localctx, 26); + { + setState(241); + ((InstrRegContext)_localctx).opcode = match(OPCODE_ADC); + setState(242); + match(REG_A); + setState(243); + match(SEP_COMMA); + setState(244); + ((InstrRegContext)_localctx).reg = rRegister(); + } + break; + case 27: + _localctx = new InstrRegContext(_localctx); + enterOuterAlt(_localctx, 27); + { + setState(245); + ((InstrRegContext)_localctx).opcode = match(OPCODE_SUB); + setState(246); + ((InstrRegContext)_localctx).reg = rRegister(); + } + break; + case 28: + _localctx = new InstrRegContext(_localctx); + enterOuterAlt(_localctx, 28); + { + setState(247); + ((InstrRegContext)_localctx).opcode = match(OPCODE_SBC); + setState(248); + match(REG_A); + setState(249); + match(SEP_COMMA); + setState(250); + ((InstrRegContext)_localctx).reg = rRegister(); + } + break; + case 29: + _localctx = new InstrRegContext(_localctx); + enterOuterAlt(_localctx, 29); + { + setState(251); + ((InstrRegContext)_localctx).opcode = match(OPCODE_AND); + setState(252); + ((InstrRegContext)_localctx).reg = rRegister(); + } + break; + case 30: + _localctx = new InstrRegContext(_localctx); + enterOuterAlt(_localctx, 30); + { + setState(253); + ((InstrRegContext)_localctx).opcode = match(OPCODE_XOR); + setState(254); + ((InstrRegContext)_localctx).reg = rRegister(); + } + break; + case 31: + _localctx = new InstrRegContext(_localctx); + enterOuterAlt(_localctx, 31); + { + setState(255); + ((InstrRegContext)_localctx).opcode = match(OPCODE_OR); + setState(256); + ((InstrRegContext)_localctx).reg = rRegister(); + } + break; + case 32: + _localctx = new InstrRegContext(_localctx); + enterOuterAlt(_localctx, 32); + { + setState(257); + ((InstrRegContext)_localctx).opcode = match(OPCODE_CP); + setState(258); + ((InstrRegContext)_localctx).reg = rRegister(); + } + break; + case 33: + _localctx = new InstrCondContext(_localctx); + enterOuterAlt(_localctx, 33); + { + setState(259); + ((InstrCondContext)_localctx).opcode = match(OPCODE_RET); + setState(261); + _errHandler.sync(this); + _la = _input.LA(1); + if (((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (COND_C - 71)) | (1L << (COND_NC - 71)) | (1L << (COND_Z - 71)) | (1L << (COND_NZ - 71)) | (1L << (COND_M - 71)) | (1L << (COND_P - 71)) | (1L << (COND_PE - 71)) | (1L << (COND_PO - 71)))) != 0)) { + { + setState(260); + ((InstrCondContext)_localctx).cond = cCondition(); + } + } + + } + break; + case 34: + _localctx = new InstrRegPairContext(_localctx); + enterOuterAlt(_localctx, 34); + { + setState(263); + ((InstrRegPairContext)_localctx).opcode = match(OPCODE_POP); + setState(264); + ((InstrRegPairContext)_localctx).regpair = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_AF - 107)))) != 0)) ) { + ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + break; + case 35: + _localctx = new InstrRegPairContext(_localctx); + enterOuterAlt(_localctx, 35); + { + setState(265); + ((InstrRegPairContext)_localctx).opcode = match(OPCODE_PUSH); + setState(266); + ((InstrRegPairContext)_localctx).regpair = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_AF - 107)))) != 0)) ) { + ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + break; + case 36: + _localctx = new Instr8bitExprContext(_localctx); + enterOuterAlt(_localctx, 36); + { + setState(267); + ((Instr8bitExprContext)_localctx).opcode = match(OPCODE_RST); + setState(268); + ((Instr8bitExprContext)_localctx).expr = rExpression(0); + } + break; + case 37: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 37); + { + setState(269); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_EXX); + } + break; + case 38: + _localctx = new InstrRegPairContext(_localctx); + enterOuterAlt(_localctx, 38); + { + setState(270); + ((InstrRegPairContext)_localctx).opcode = match(OPCODE_JP); + setState(271); + match(SEP_LPAR); + setState(272); + ((InstrRegPairContext)_localctx).regpairM = match(REG_HL); + setState(273); + match(SEP_RPAR); + } + break; + case 39: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 39); + { + setState(274); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_DI); + } + break; + case 40: + _localctx = new InstrRegPairRegPairContext(_localctx); + enterOuterAlt(_localctx, 40); + { + setState(275); + ((InstrRegPairRegPairContext)_localctx).opcode = match(OPCODE_LD); + setState(276); + ((InstrRegPairRegPairContext)_localctx).dst = match(REG_SP); + setState(277); + match(SEP_COMMA); + setState(278); + ((InstrRegPairRegPairContext)_localctx).src = match(REG_HL); + } + break; + case 41: + _localctx = new InstrNoArgsContext(_localctx); + enterOuterAlt(_localctx, 41); + { + setState(279); + ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_EI); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RRegisterContext extends ParserRuleContext { + public Token r; + public TerminalNode REG_A() { return getToken(AsZ80Parser.REG_A, 0); } + public TerminalNode REG_B() { return getToken(AsZ80Parser.REG_B, 0); } + public TerminalNode REG_C() { return getToken(AsZ80Parser.REG_C, 0); } + public TerminalNode REG_D() { return getToken(AsZ80Parser.REG_D, 0); } + public TerminalNode REG_E() { return getToken(AsZ80Parser.REG_E, 0); } + public TerminalNode REG_H() { return getToken(AsZ80Parser.REG_H, 0); } + public TerminalNode REG_L() { return getToken(AsZ80Parser.REG_L, 0); } + public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } + public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } + public TerminalNode REG_HL() { return getToken(AsZ80Parser.REG_HL, 0); } + public RRegisterContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rRegister; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRRegister(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRRegister(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRRegister(this); + else return visitor.visitChildren(this); + } + } + + public final RRegisterContext rRegister() throws RecognitionException { + RRegisterContext _localctx = new RRegisterContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_rRegister); + try { + setState(292); + _errHandler.sync(this); + switch (_input.LA(1)) { + case REG_A: + enterOuterAlt(_localctx, 1); + { + setState(282); + ((RRegisterContext)_localctx).r = match(REG_A); + } + break; + case REG_B: + enterOuterAlt(_localctx, 2); + { + setState(283); + ((RRegisterContext)_localctx).r = match(REG_B); + } + break; + case REG_C: + enterOuterAlt(_localctx, 3); + { + setState(284); + ((RRegisterContext)_localctx).r = match(REG_C); + } + break; + case REG_D: + enterOuterAlt(_localctx, 4); + { + setState(285); + ((RRegisterContext)_localctx).r = match(REG_D); + } + break; + case REG_E: + enterOuterAlt(_localctx, 5); + { + setState(286); + ((RRegisterContext)_localctx).r = match(REG_E); + } + break; + case REG_H: + enterOuterAlt(_localctx, 6); + { + setState(287); + ((RRegisterContext)_localctx).r = match(REG_H); + } + break; + case REG_L: + enterOuterAlt(_localctx, 7); + { + setState(288); + ((RRegisterContext)_localctx).r = match(REG_L); + } + break; + case SEP_LPAR: + enterOuterAlt(_localctx, 8); + { + setState(289); + match(SEP_LPAR); + setState(290); + ((RRegisterContext)_localctx).r = match(REG_HL); + setState(291); + match(SEP_RPAR); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class CConditionContext extends ParserRuleContext { + public TerminalNode COND_C() { return getToken(AsZ80Parser.COND_C, 0); } + public TerminalNode COND_NC() { return getToken(AsZ80Parser.COND_NC, 0); } + public TerminalNode COND_Z() { return getToken(AsZ80Parser.COND_Z, 0); } + public TerminalNode COND_NZ() { return getToken(AsZ80Parser.COND_NZ, 0); } + public TerminalNode COND_M() { return getToken(AsZ80Parser.COND_M, 0); } + public TerminalNode COND_P() { return getToken(AsZ80Parser.COND_P, 0); } + public TerminalNode COND_PE() { return getToken(AsZ80Parser.COND_PE, 0); } + public TerminalNode COND_PO() { return getToken(AsZ80Parser.COND_PO, 0); } + public CConditionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_cCondition; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterCCondition(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitCCondition(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitCCondition(this); + else return visitor.visitChildren(this); + } + } + + public final CConditionContext cCondition() throws RecognitionException { + CConditionContext _localctx = new CConditionContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_cCondition); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(294); + _la = _input.LA(1); + if ( !(((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (COND_C - 71)) | (1L << (COND_NC - 71)) | (1L << (COND_Z - 71)) | (1L << (COND_NZ - 71)) | (1L << (COND_M - 71)) | (1L << (COND_P - 71)) | (1L << (COND_PE - 71)) | (1L << (COND_PO - 71)))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RPseudoCodeContext extends ParserRuleContext { + public RPseudoCodeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rPseudoCode; } + + public RPseudoCodeContext() { } + public void copyFrom(RPseudoCodeContext ctx) { + super.copyFrom(ctx); + } + } + public static class PseudoIncludeContext extends RPseudoCodeContext { + public Token filename; + public TerminalNode PREP_INCLUDE() { return getToken(AsZ80Parser.PREP_INCLUDE, 0); } + public TerminalNode LIT_STRING_1() { return getToken(AsZ80Parser.LIT_STRING_1, 0); } + public TerminalNode LIT_STRING_2() { return getToken(AsZ80Parser.LIT_STRING_2, 0); } + public PseudoIncludeContext(RPseudoCodeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoInclude(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoInclude(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoInclude(this); + else return visitor.visitChildren(this); + } + } + public static class PseudoIfContext extends RPseudoCodeContext { + public RExpressionContext expr; + public TerminalNode PREP_IF() { return getToken(AsZ80Parser.PREP_IF, 0); } + public List EOL() { return getTokens(AsZ80Parser.EOL); } + public TerminalNode EOL(int i) { + return getToken(AsZ80Parser.EOL, i); + } + public TerminalNode PREP_ENDIF() { return getToken(AsZ80Parser.PREP_ENDIF, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public List rLine() { + return getRuleContexts(RLineContext.class); + } + public RLineContext rLine(int i) { + return getRuleContext(RLineContext.class,i); + } + public PseudoIfContext(RPseudoCodeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoIf(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoIf(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoIf(this); + else return visitor.visitChildren(this); + } + } + public static class PseudoEquContext extends RPseudoCodeContext { + public Token id; + public RExpressionContext expr; + public TerminalNode PREP_EQU() { return getToken(AsZ80Parser.PREP_EQU, 0); } + public TerminalNode ID_IDENTIFIER() { return getToken(AsZ80Parser.ID_IDENTIFIER, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public PseudoEquContext(RPseudoCodeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoEqu(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoEqu(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoEqu(this); + else return visitor.visitChildren(this); + } + } + public static class PseudoMacroCallContext extends RPseudoCodeContext { + public Token id; + public RMacroArgumentsContext args; + public TerminalNode ID_IDENTIFIER() { return getToken(AsZ80Parser.ID_IDENTIFIER, 0); } + public RMacroArgumentsContext rMacroArguments() { + return getRuleContext(RMacroArgumentsContext.class,0); + } + public PseudoMacroCallContext(RPseudoCodeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoMacroCall(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoMacroCall(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoMacroCall(this); + else return visitor.visitChildren(this); + } + } + public static class PseudoMacroDefContext extends RPseudoCodeContext { + public Token id; + public RMacroParametersContext params; + public TerminalNode PREP_MACRO() { return getToken(AsZ80Parser.PREP_MACRO, 0); } + public List EOL() { return getTokens(AsZ80Parser.EOL); } + public TerminalNode EOL(int i) { + return getToken(AsZ80Parser.EOL, i); + } + public TerminalNode PREP_ENDM() { return getToken(AsZ80Parser.PREP_ENDM, 0); } + public TerminalNode ID_IDENTIFIER() { return getToken(AsZ80Parser.ID_IDENTIFIER, 0); } + public List rLine() { + return getRuleContexts(RLineContext.class); + } + public RLineContext rLine(int i) { + return getRuleContext(RLineContext.class,i); + } + public RMacroParametersContext rMacroParameters() { + return getRuleContext(RMacroParametersContext.class,0); + } + public PseudoMacroDefContext(RPseudoCodeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoMacroDef(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoMacroDef(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoMacroDef(this); + else return visitor.visitChildren(this); + } + } + public static class PseudoSetContext extends RPseudoCodeContext { + public Token id; + public RExpressionContext expr; + public TerminalNode PREP_SET() { return getToken(AsZ80Parser.PREP_SET, 0); } + public TerminalNode ID_IDENTIFIER() { return getToken(AsZ80Parser.ID_IDENTIFIER, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public PseudoSetContext(RPseudoCodeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoSet(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoSet(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoSet(this); + else return visitor.visitChildren(this); + } + } + public static class PseudoOrgContext extends RPseudoCodeContext { + public RExpressionContext expr; + public TerminalNode PREP_ORG() { return getToken(AsZ80Parser.PREP_ORG, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public PseudoOrgContext(RPseudoCodeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoOrg(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoOrg(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoOrg(this); + else return visitor.visitChildren(this); + } + } + + public final RPseudoCodeContext rPseudoCode() throws RecognitionException { + RPseudoCodeContext _localctx = new RPseudoCodeContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_rPseudoCode); + int _la; + try { + int _alt; + setState(350); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,21,_ctx) ) { + case 1: + _localctx = new PseudoOrgContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(296); + match(PREP_ORG); + setState(297); + ((PseudoOrgContext)_localctx).expr = rExpression(0); + } + break; + case 2: + _localctx = new PseudoEquContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(298); + ((PseudoEquContext)_localctx).id = match(ID_IDENTIFIER); + setState(299); + match(PREP_EQU); + setState(300); + ((PseudoEquContext)_localctx).expr = rExpression(0); + } + break; + case 3: + _localctx = new PseudoSetContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(301); + ((PseudoSetContext)_localctx).id = match(ID_IDENTIFIER); + setState(302); + match(PREP_SET); + setState(303); + ((PseudoSetContext)_localctx).expr = rExpression(0); + } + break; + case 4: + _localctx = new PseudoIfContext(_localctx); + enterOuterAlt(_localctx, 4); + { + setState(304); + match(PREP_IF); + setState(305); + ((PseudoIfContext)_localctx).expr = rExpression(0); + setState(306); + match(EOL); + setState(312); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,15,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(307); + rLine(); + setState(308); + match(EOL); + } + } + } + setState(314); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,15,_ctx); + } + setState(318); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==EOL) { + { + { + setState(315); + match(EOL); + } + } + setState(320); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(321); + match(PREP_ENDIF); + } + break; + case 5: + _localctx = new PseudoMacroDefContext(_localctx); + enterOuterAlt(_localctx, 5); + { + setState(323); + ((PseudoMacroDefContext)_localctx).id = match(ID_IDENTIFIER); + setState(324); + match(PREP_MACRO); + setState(326); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==ID_IDENTIFIER) { + { + setState(325); + ((PseudoMacroDefContext)_localctx).params = rMacroParameters(); + } + } + + setState(328); + match(EOL); + setState(334); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,18,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(329); + rLine(); + setState(330); + match(EOL); + } + } + } + setState(336); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,18,_ctx); + } + setState(340); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==EOL) { + { + { + setState(337); + match(EOL); + } + } + setState(342); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(343); + match(PREP_ENDM); + } + break; + case 6: + _localctx = new PseudoMacroCallContext(_localctx); + enterOuterAlt(_localctx, 6); + { + setState(344); + ((PseudoMacroCallContext)_localctx).id = match(ID_IDENTIFIER); + setState(346); + _errHandler.sync(this); + _la = _input.LA(1); + if (((((_la - 93)) & ~0x3f) == 0 && ((1L << (_la - 93)) & ((1L << (PREP_ADDR - 93)) | (1L << (OP_NOT - 93)) | (1L << (LIT_HEXNUMBER_1 - 93)) | (1L << (LIT_NUMBER - 93)) | (1L << (LIT_HEXNUMBER_2 - 93)) | (1L << (LIT_OCTNUMBER - 93)) | (1L << (LIT_BINNUMBER - 93)) | (1L << (LIT_STRING_1 - 93)) | (1L << (LIT_STRING_2 - 93)) | (1L << (ID_IDENTIFIER - 93)) | (1L << (SEP_LPAR - 93)) | (1L << (OP_ADD - 93)) | (1L << (OP_SUBTRACT - 93)) | (1L << (OP_NOT_2 - 93)))) != 0)) { + { + setState(345); + ((PseudoMacroCallContext)_localctx).args = rMacroArguments(); + } + } + + } + break; + case 7: + _localctx = new PseudoIncludeContext(_localctx); + enterOuterAlt(_localctx, 7); + { + setState(348); + match(PREP_INCLUDE); + setState(349); + ((PseudoIncludeContext)_localctx).filename = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==LIT_STRING_1 || _la==LIT_STRING_2) ) { + ((PseudoIncludeContext)_localctx).filename = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RMacroParametersContext extends ParserRuleContext { + public List ID_IDENTIFIER() { return getTokens(AsZ80Parser.ID_IDENTIFIER); } + public TerminalNode ID_IDENTIFIER(int i) { + return getToken(AsZ80Parser.ID_IDENTIFIER, i); + } + public List SEP_COMMA() { return getTokens(AsZ80Parser.SEP_COMMA); } + public TerminalNode SEP_COMMA(int i) { + return getToken(AsZ80Parser.SEP_COMMA, i); + } + public RMacroParametersContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rMacroParameters; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRMacroParameters(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRMacroParameters(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRMacroParameters(this); + else return visitor.visitChildren(this); + } + } + + public final RMacroParametersContext rMacroParameters() throws RecognitionException { + RMacroParametersContext _localctx = new RMacroParametersContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_rMacroParameters); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(352); + match(ID_IDENTIFIER); + setState(357); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==SEP_COMMA) { + { + { + setState(353); + match(SEP_COMMA); + setState(354); + match(ID_IDENTIFIER); + } + } + setState(359); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RMacroArgumentsContext extends ParserRuleContext { + public List rExpression() { + return getRuleContexts(RExpressionContext.class); + } + public RExpressionContext rExpression(int i) { + return getRuleContext(RExpressionContext.class,i); + } + public List SEP_COMMA() { return getTokens(AsZ80Parser.SEP_COMMA); } + public TerminalNode SEP_COMMA(int i) { + return getToken(AsZ80Parser.SEP_COMMA, i); + } + public RMacroArgumentsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rMacroArguments; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRMacroArguments(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRMacroArguments(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRMacroArguments(this); + else return visitor.visitChildren(this); + } + } + + public final RMacroArgumentsContext rMacroArguments() throws RecognitionException { + RMacroArgumentsContext _localctx = new RMacroArgumentsContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_rMacroArguments); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(360); + rExpression(0); + setState(365); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==SEP_COMMA) { + { + { + setState(361); + match(SEP_COMMA); + setState(362); + rExpression(0); + } + } + setState(367); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RDataContext extends ParserRuleContext { + public RDataContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rData; } + + public RDataContext() { } + public void copyFrom(RDataContext ctx) { + super.copyFrom(ctx); + } + } + public static class DataDSContext extends RDataContext { + public RExpressionContext data; + public TerminalNode PREP_DS() { return getToken(AsZ80Parser.PREP_DS, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public DataDSContext(RDataContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterDataDS(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitDataDS(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitDataDS(this); + else return visitor.visitChildren(this); + } + } + public static class DataDBContext extends RDataContext { + public TerminalNode PREP_DB() { return getToken(AsZ80Parser.PREP_DB, 0); } + public List rDBdata() { + return getRuleContexts(RDBdataContext.class); + } + public RDBdataContext rDBdata(int i) { + return getRuleContext(RDBdataContext.class,i); + } + public List SEP_COMMA() { return getTokens(AsZ80Parser.SEP_COMMA); } + public TerminalNode SEP_COMMA(int i) { + return getToken(AsZ80Parser.SEP_COMMA, i); + } + public DataDBContext(RDataContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterDataDB(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitDataDB(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitDataDB(this); + else return visitor.visitChildren(this); + } + } + public static class DataDWContext extends RDataContext { + public TerminalNode PREP_DW() { return getToken(AsZ80Parser.PREP_DW, 0); } + public List rDWdata() { + return getRuleContexts(RDWdataContext.class); + } + public RDWdataContext rDWdata(int i) { + return getRuleContext(RDWdataContext.class,i); + } + public List SEP_COMMA() { return getTokens(AsZ80Parser.SEP_COMMA); } + public TerminalNode SEP_COMMA(int i) { + return getToken(AsZ80Parser.SEP_COMMA, i); + } + public DataDWContext(RDataContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterDataDW(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitDataDW(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitDataDW(this); + else return visitor.visitChildren(this); + } + } + + public final RDataContext rData() throws RecognitionException { + RDataContext _localctx = new RDataContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_rData); + int _la; + try { + setState(388); + _errHandler.sync(this); + switch (_input.LA(1)) { + case PREP_DB: + _localctx = new DataDBContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(368); + match(PREP_DB); + setState(369); + rDBdata(); + setState(374); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==SEP_COMMA) { + { + { + setState(370); + match(SEP_COMMA); + setState(371); + rDBdata(); + } + } + setState(376); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + break; + case PREP_DW: + _localctx = new DataDWContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(377); + match(PREP_DW); + setState(378); + rDWdata(); + setState(383); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==SEP_COMMA) { + { + { + setState(379); + match(SEP_COMMA); + setState(380); + rDWdata(); + } + } + setState(385); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + break; + case PREP_DS: + _localctx = new DataDSContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(386); + match(PREP_DS); + setState(387); + ((DataDSContext)_localctx).data = rExpression(0); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RDBdataContext extends ParserRuleContext { + public RExpressionContext expr; + public R8bitInstructionContext instr; + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public R8bitInstructionContext r8bitInstruction() { + return getRuleContext(R8bitInstructionContext.class,0); + } + public RDBdataContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rDBdata; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRDBdata(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRDBdata(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRDBdata(this); + else return visitor.visitChildren(this); + } + } + + public final RDBdataContext rDBdata() throws RecognitionException { + RDBdataContext _localctx = new RDBdataContext(_ctx, getState()); + enterRule(_localctx, 22, RULE_rDBdata); + try { + setState(392); + _errHandler.sync(this); + switch (_input.LA(1)) { + case PREP_ADDR: + case OP_NOT: + case LIT_HEXNUMBER_1: + case LIT_NUMBER: + case LIT_HEXNUMBER_2: + case LIT_OCTNUMBER: + case LIT_BINNUMBER: + case LIT_STRING_1: + case LIT_STRING_2: + case ID_IDENTIFIER: + case SEP_LPAR: + case OP_ADD: + case OP_SUBTRACT: + case OP_NOT_2: + enterOuterAlt(_localctx, 1); + { + setState(390); + ((RDBdataContext)_localctx).expr = rExpression(0); + } + break; + case OPCODE_ADC: + case OPCODE_ADD: + case OPCODE_AND: + case OPCODE_CCF: + case OPCODE_CP: + case OPCODE_CPL: + case OPCODE_DAA: + case OPCODE_DEC: + case OPCODE_DI: + case OPCODE_EI: + case OPCODE_EX: + case OPCODE_EXX: + case OPCODE_HALT: + case OPCODE_INC: + case OPCODE_JP: + case OPCODE_LD: + case OPCODE_NOP: + case OPCODE_OR: + case OPCODE_POP: + case OPCODE_PUSH: + case OPCODE_RET: + case OPCODE_RLA: + case OPCODE_RLCA: + case OPCODE_RRA: + case OPCODE_RRCA: + case OPCODE_RST: + case OPCODE_SBC: + case OPCODE_SCF: + case OPCODE_SUB: + case OPCODE_XOR: + enterOuterAlt(_localctx, 2); + { + setState(391); + ((RDBdataContext)_localctx).instr = r8bitInstruction(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RDWdataContext extends ParserRuleContext { + public RExpressionContext expr; + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public RDWdataContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rDWdata; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRDWdata(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRDWdata(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRDWdata(this); + else return visitor.visitChildren(this); + } + } + + public final RDWdataContext rDWdata() throws RecognitionException { + RDWdataContext _localctx = new RDWdataContext(_ctx, getState()); + enterRule(_localctx, 24, RULE_rDWdata); + try { + enterOuterAlt(_localctx, 1); + { + setState(394); + ((RDWdataContext)_localctx).expr = rExpression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RExpressionContext extends ParserRuleContext { + public RExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rExpression; } + + public RExpressionContext() { } + public void copyFrom(RExpressionContext ctx) { + super.copyFrom(ctx); + } + } + public static class ExprOctContext extends RExpressionContext { + public Token num; + public TerminalNode LIT_OCTNUMBER() { return getToken(AsZ80Parser.LIT_OCTNUMBER, 0); } + public ExprOctContext(RExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprOct(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprOct(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprOct(this); + else return visitor.visitChildren(this); + } + } + public static class ExprHex1Context extends RExpressionContext { + public Token num; + public TerminalNode LIT_HEXNUMBER_1() { return getToken(AsZ80Parser.LIT_HEXNUMBER_1, 0); } + public ExprHex1Context(RExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprHex1(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprHex1(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprHex1(this); + else return visitor.visitChildren(this); + } + } + public static class ExprHex2Context extends RExpressionContext { + public Token num; + public TerminalNode LIT_HEXNUMBER_2() { return getToken(AsZ80Parser.LIT_HEXNUMBER_2, 0); } + public ExprHex2Context(RExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprHex2(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprHex2(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprHex2(this); + else return visitor.visitChildren(this); + } + } + public static class ExprDecContext extends RExpressionContext { + public Token num; + public TerminalNode LIT_NUMBER() { return getToken(AsZ80Parser.LIT_NUMBER, 0); } + public ExprDecContext(RExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprDec(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprDec(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprDec(this); + else return visitor.visitChildren(this); + } + } + public static class ExprStringContext extends RExpressionContext { + public Token str; + public TerminalNode LIT_STRING_1() { return getToken(AsZ80Parser.LIT_STRING_1, 0); } + public TerminalNode LIT_STRING_2() { return getToken(AsZ80Parser.LIT_STRING_2, 0); } + public ExprStringContext(RExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprString(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprString(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprString(this); + else return visitor.visitChildren(this); + } + } + public static class ExprBinContext extends RExpressionContext { + public Token num; + public TerminalNode LIT_BINNUMBER() { return getToken(AsZ80Parser.LIT_BINNUMBER, 0); } + public ExprBinContext(RExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprBin(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprBin(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprBin(this); + else return visitor.visitChildren(this); + } + } + public static class ExprParensContext extends RExpressionContext { + public RExpressionContext expr; + public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } + public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public ExprParensContext(RExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprParens(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprParens(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprParens(this); + else return visitor.visitChildren(this); + } + } + public static class ExprIdContext extends RExpressionContext { + public Token id; + public TerminalNode ID_IDENTIFIER() { return getToken(AsZ80Parser.ID_IDENTIFIER, 0); } + public ExprIdContext(RExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprId(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprId(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprId(this); + else return visitor.visitChildren(this); + } + } + public static class ExprUnaryContext extends RExpressionContext { + public Token unaryop; + public RExpressionContext expr; + public RExpressionContext rExpression() { + return getRuleContext(RExpressionContext.class,0); + } + public TerminalNode OP_ADD() { return getToken(AsZ80Parser.OP_ADD, 0); } + public TerminalNode OP_SUBTRACT() { return getToken(AsZ80Parser.OP_SUBTRACT, 0); } + public TerminalNode OP_NOT() { return getToken(AsZ80Parser.OP_NOT, 0); } + public TerminalNode OP_NOT_2() { return getToken(AsZ80Parser.OP_NOT_2, 0); } + public ExprUnaryContext(RExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprUnary(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprUnary(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprUnary(this); + else return visitor.visitChildren(this); + } + } + public static class ExprInfixContext extends RExpressionContext { + public RExpressionContext expr1; + public Token op; + public RExpressionContext expr2; + public List rExpression() { + return getRuleContexts(RExpressionContext.class); + } + public RExpressionContext rExpression(int i) { + return getRuleContext(RExpressionContext.class,i); + } + public TerminalNode OP_MULTIPLY() { return getToken(AsZ80Parser.OP_MULTIPLY, 0); } + public TerminalNode OP_DIVIDE() { return getToken(AsZ80Parser.OP_DIVIDE, 0); } + public TerminalNode OP_MOD() { return getToken(AsZ80Parser.OP_MOD, 0); } + public TerminalNode OP_MOD_2() { return getToken(AsZ80Parser.OP_MOD_2, 0); } + public TerminalNode OP_ADD() { return getToken(AsZ80Parser.OP_ADD, 0); } + public TerminalNode OP_SUBTRACT() { return getToken(AsZ80Parser.OP_SUBTRACT, 0); } + public TerminalNode OP_SHL() { return getToken(AsZ80Parser.OP_SHL, 0); } + public TerminalNode OP_SHR() { return getToken(AsZ80Parser.OP_SHR, 0); } + public TerminalNode OP_SHR_2() { return getToken(AsZ80Parser.OP_SHR_2, 0); } + public TerminalNode OP_SHL_2() { return getToken(AsZ80Parser.OP_SHL_2, 0); } + public TerminalNode OP_GT() { return getToken(AsZ80Parser.OP_GT, 0); } + public TerminalNode OP_GTE() { return getToken(AsZ80Parser.OP_GTE, 0); } + public TerminalNode OP_LT() { return getToken(AsZ80Parser.OP_LT, 0); } + public TerminalNode OP_LTE() { return getToken(AsZ80Parser.OP_LTE, 0); } + public TerminalNode OP_EQUAL() { return getToken(AsZ80Parser.OP_EQUAL, 0); } + public TerminalNode OP_AND() { return getToken(AsZ80Parser.OP_AND, 0); } + public TerminalNode OP_AND_2() { return getToken(AsZ80Parser.OP_AND_2, 0); } + public TerminalNode OP_XOR() { return getToken(AsZ80Parser.OP_XOR, 0); } + public TerminalNode OP_XOR_2() { return getToken(AsZ80Parser.OP_XOR_2, 0); } + public TerminalNode OP_OR() { return getToken(AsZ80Parser.OP_OR, 0); } + public TerminalNode OP_OR_2() { return getToken(AsZ80Parser.OP_OR_2, 0); } + public ExprInfixContext(RExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprInfix(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprInfix(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprInfix(this); + else return visitor.visitChildren(this); + } + } + public static class ExprCurrentAddressContext extends RExpressionContext { + public TerminalNode PREP_ADDR() { return getToken(AsZ80Parser.PREP_ADDR, 0); } + public ExprCurrentAddressContext(RExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprCurrentAddress(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprCurrentAddress(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprCurrentAddress(this); + else return visitor.visitChildren(this); + } + } + + public final RExpressionContext rExpression() throws RecognitionException { + return rExpression(0); + } + + private RExpressionContext rExpression(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + RExpressionContext _localctx = new RExpressionContext(_ctx, _parentState); + RExpressionContext _prevctx = _localctx; + int _startState = 26; + enterRecursionRule(_localctx, 26, RULE_rExpression, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(411); + _errHandler.sync(this); + switch (_input.LA(1)) { + case OP_NOT: + case OP_ADD: + case OP_SUBTRACT: + case OP_NOT_2: + { + _localctx = new ExprUnaryContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + + setState(397); + ((ExprUnaryContext)_localctx).unaryop = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 118)) & ~0x3f) == 0 && ((1L << (_la - 118)) & ((1L << (OP_NOT - 118)) | (1L << (OP_ADD - 118)) | (1L << (OP_SUBTRACT - 118)) | (1L << (OP_NOT_2 - 118)))) != 0)) ) { + ((ExprUnaryContext)_localctx).unaryop = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(398); + ((ExprUnaryContext)_localctx).expr = rExpression(18); + } + break; + case SEP_LPAR: + { + _localctx = new ExprParensContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(399); + match(SEP_LPAR); + setState(400); + ((ExprParensContext)_localctx).expr = rExpression(0); + setState(401); + match(SEP_RPAR); + } + break; + case LIT_NUMBER: + { + _localctx = new ExprDecContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(403); + ((ExprDecContext)_localctx).num = match(LIT_NUMBER); + } + break; + case LIT_HEXNUMBER_1: + { + _localctx = new ExprHex1Context(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(404); + ((ExprHex1Context)_localctx).num = match(LIT_HEXNUMBER_1); + } + break; + case LIT_HEXNUMBER_2: + { + _localctx = new ExprHex2Context(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(405); + ((ExprHex2Context)_localctx).num = match(LIT_HEXNUMBER_2); + } + break; + case LIT_OCTNUMBER: + { + _localctx = new ExprOctContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(406); + ((ExprOctContext)_localctx).num = match(LIT_OCTNUMBER); + } + break; + case LIT_BINNUMBER: + { + _localctx = new ExprBinContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(407); + ((ExprBinContext)_localctx).num = match(LIT_BINNUMBER); + } + break; + case PREP_ADDR: + { + _localctx = new ExprCurrentAddressContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(408); + match(PREP_ADDR); + } + break; + case ID_IDENTIFIER: + { + _localctx = new ExprIdContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(409); + ((ExprIdContext)_localctx).id = match(ID_IDENTIFIER); + } + break; + case LIT_STRING_1: + case LIT_STRING_2: + { + _localctx = new ExprStringContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(410); + ((ExprStringContext)_localctx).str = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==LIT_STRING_1 || _la==LIT_STRING_2) ) { + ((ExprStringContext)_localctx).str = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + break; + default: + throw new NoViableAltException(this); + } + _ctx.stop = _input.LT(-1); + setState(439); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,30,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(437); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,29,_ctx) ) { + case 1: + { + _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); + ((ExprInfixContext)_localctx).expr1 = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_rExpression); + setState(413); + if (!(precpred(_ctx, 17))) throw new FailedPredicateException(this, "precpred(_ctx, 17)"); + setState(414); + ((ExprInfixContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 115)) & ~0x3f) == 0 && ((1L << (_la - 115)) & ((1L << (OP_MOD - 115)) | (1L << (OP_MULTIPLY - 115)) | (1L << (OP_DIVIDE - 115)) | (1L << (OP_MOD_2 - 115)))) != 0)) ) { + ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(415); + ((ExprInfixContext)_localctx).expr2 = rExpression(18); + } + break; + case 2: + { + _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); + ((ExprInfixContext)_localctx).expr1 = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_rExpression); + setState(416); + if (!(precpred(_ctx, 16))) throw new FailedPredicateException(this, "precpred(_ctx, 16)"); + setState(417); + ((ExprInfixContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==OP_ADD || _la==OP_SUBTRACT) ) { + ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(418); + ((ExprInfixContext)_localctx).expr2 = rExpression(17); + } + break; + case 3: + { + _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); + ((ExprInfixContext)_localctx).expr1 = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_rExpression); + setState(419); + if (!(precpred(_ctx, 15))) throw new FailedPredicateException(this, "precpred(_ctx, 15)"); + setState(420); + ((ExprInfixContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 116)) & ~0x3f) == 0 && ((1L << (_la - 116)) & ((1L << (OP_SHR - 116)) | (1L << (OP_SHL - 116)) | (1L << (OP_SHR_2 - 116)) | (1L << (OP_SHL_2 - 116)))) != 0)) ) { + ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(421); + ((ExprInfixContext)_localctx).expr2 = rExpression(16); + } + break; + case 4: + { + _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); + ((ExprInfixContext)_localctx).expr1 = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_rExpression); + setState(422); + if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)"); + setState(423); + ((ExprInfixContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 140)) & ~0x3f) == 0 && ((1L << (_la - 140)) & ((1L << (OP_GT - 140)) | (1L << (OP_GTE - 140)) | (1L << (OP_LT - 140)) | (1L << (OP_LTE - 140)))) != 0)) ) { + ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(424); + ((ExprInfixContext)_localctx).expr2 = rExpression(14); + } + break; + case 5: + { + _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); + ((ExprInfixContext)_localctx).expr1 = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_rExpression); + setState(425); + if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); + setState(426); + ((ExprInfixContext)_localctx).op = match(OP_EQUAL); + setState(427); + ((ExprInfixContext)_localctx).expr2 = rExpression(13); + } + break; + case 6: + { + _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); + ((ExprInfixContext)_localctx).expr1 = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_rExpression); + setState(428); + if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); + setState(429); + ((ExprInfixContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==OP_AND || _la==OP_AND_2) ) { + ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(430); + ((ExprInfixContext)_localctx).expr2 = rExpression(13); + } + break; + case 7: + { + _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); + ((ExprInfixContext)_localctx).expr1 = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_rExpression); + setState(431); + if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); + setState(432); + ((ExprInfixContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==OP_XOR || _la==OP_XOR_2) ) { + ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(433); + ((ExprInfixContext)_localctx).expr2 = rExpression(12); + } + break; + case 8: + { + _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); + ((ExprInfixContext)_localctx).expr1 = _prevctx; + pushNewRecursionContext(_localctx, _startState, RULE_rExpression); + setState(434); + if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); + setState(435); + ((ExprInfixContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==OP_OR || _la==OP_OR_2) ) { + ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(436); + ((ExprInfixContext)_localctx).expr2 = rExpression(11); + } + break; + } + } + } + setState(441); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,30,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 13: + return rExpression_sempred((RExpressionContext)_localctx, predIndex); + } + return true; + } + private boolean rExpression_sempred(RExpressionContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return precpred(_ctx, 17); + case 1: + return precpred(_ctx, 16); + case 2: + return precpred(_ctx, 15); + case 3: + return precpred(_ctx, 14); + case 4: + return precpred(_ctx, 13); + case 5: + return precpred(_ctx, 12); + case 6: + return precpred(_ctx, 11); + case 7: + return precpred(_ctx, 10); + } + return true; + } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\u009a\u01bd\4\2\t"+ + "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ + "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\3\2\7\2 \n\2\f\2\16\2#\13\2"+ + "\3\2\5\2&\n\2\3\2\6\2)\n\2\r\2\16\2*\3\2\7\2.\n\2\f\2\16\2\61\13\2\3\2"+ + "\7\2\64\n\2\f\2\16\2\67\13\2\3\2\3\2\3\3\5\3<\n\3\3\3\7\3?\n\3\f\3\16"+ + "\3B\13\3\3\3\3\3\5\3F\n\3\3\4\3\4\3\4\5\4K\n\4\3\5\3\5\3\5\3\5\3\5\3\5"+ + "\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5Z\n\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5"+ + "\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3"+ + "\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5}\n\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3"+ + "\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5"+ + "\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3"+ + "\5\3\5\5\5\u00ab\n\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3"+ + "\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6"+ + "\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3"+ + "\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6"+ + "\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3"+ + "\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6\u0108\n\6\3\6\3\6\3\6\3\6\3\6\3"+ + "\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6\u011b\n\6\3\7\3\7\3"+ + "\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\5\7\u0127\n\7\3\b\3\b\3\t\3\t\3\t\3\t\3"+ + "\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\7\t\u0139\n\t\f\t\16\t\u013c\13"+ + "\t\3\t\7\t\u013f\n\t\f\t\16\t\u0142\13\t\3\t\3\t\3\t\3\t\3\t\5\t\u0149"+ + "\n\t\3\t\3\t\3\t\3\t\7\t\u014f\n\t\f\t\16\t\u0152\13\t\3\t\7\t\u0155\n"+ + "\t\f\t\16\t\u0158\13\t\3\t\3\t\3\t\5\t\u015d\n\t\3\t\3\t\5\t\u0161\n\t"+ + "\3\n\3\n\3\n\7\n\u0166\n\n\f\n\16\n\u0169\13\n\3\13\3\13\3\13\7\13\u016e"+ + "\n\13\f\13\16\13\u0171\13\13\3\f\3\f\3\f\3\f\7\f\u0177\n\f\f\f\16\f\u017a"+ + "\13\f\3\f\3\f\3\f\3\f\7\f\u0180\n\f\f\f\16\f\u0183\13\f\3\f\3\f\5\f\u0187"+ + "\n\f\3\r\3\r\5\r\u018b\n\r\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17"+ + "\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\5\17\u019e\n\17\3\17\3\17\3\17"+ + "\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17"+ + "\3\17\3\17\3\17\3\17\3\17\3\17\3\17\7\17\u01b8\n\17\f\17\16\17\u01bb\13"+ + "\17\3\17\2\3\34\20\2\4\6\b\n\f\16\20\22\24\26\30\32\34\2\20\3\2mp\3\2"+ + "IL\3\2mn\4\2moqq\3\2IP\3\2\u0081\u0082\5\2xx\u0089\u008a\u0095\u0095\5"+ + "\2uu\u008b\u008c\u0092\u0092\3\2\u0089\u008a\4\2vw\u0093\u0094\3\2\u008e"+ + "\u0091\4\2yy\u0096\u0096\4\2{{\u0098\u0098\4\2zz\u0097\u0097\2\u0222\2"+ + "!\3\2\2\2\4E\3\2\2\2\6J\3\2\2\2\b\u00aa\3\2\2\2\n\u011a\3\2\2\2\f\u0126"+ + "\3\2\2\2\16\u0128\3\2\2\2\20\u0160\3\2\2\2\22\u0162\3\2\2\2\24\u016a\3"+ + "\2\2\2\26\u0186\3\2\2\2\30\u018a\3\2\2\2\32\u018c\3\2\2\2\34\u019d\3\2"+ + "\2\2\36 \7\u009a\2\2\37\36\3\2\2\2 #\3\2\2\2!\37\3\2\2\2!\"\3\2\2\2\""+ + "%\3\2\2\2#!\3\2\2\2$&\5\4\3\2%$\3\2\2\2%&\3\2\2\2&/\3\2\2\2\')\7\u009a"+ + "\2\2(\'\3\2\2\2)*\3\2\2\2*(\3\2\2\2*+\3\2\2\2+,\3\2\2\2,.\5\4\3\2-(\3"+ + "\2\2\2.\61\3\2\2\2/-\3\2\2\2/\60\3\2\2\2\60\65\3\2\2\2\61/\3\2\2\2\62"+ + "\64\7\u009a\2\2\63\62\3\2\2\2\64\67\3\2\2\2\65\63\3\2\2\2\65\66\3\2\2"+ + "\2\668\3\2\2\2\67\65\3\2\2\289\7\2\2\39\3\3\2\2\2:<\7\u0084\2\2;:\3\2"+ + "\2\2;<\3\2\2\2<@\3\2\2\2=?\7\u009a\2\2>=\3\2\2\2?B\3\2\2\2@>\3\2\2\2@"+ + "A\3\2\2\2AC\3\2\2\2B@\3\2\2\2CF\5\6\4\2DF\7\u0084\2\2E;\3\2\2\2ED\3\2"+ + "\2\2F\5\3\2\2\2GK\5\b\5\2HK\5\20\t\2IK\5\26\f\2JG\3\2\2\2JH\3\2\2\2JI"+ + "\3\2\2\2K\7\3\2\2\2L\u00ab\5\n\6\2MN\7\"\2\2NO\t\2\2\2OP\7\u0088\2\2P"+ + "\u00ab\5\34\17\2QR\7\"\2\2RS\5\f\7\2ST\7\u0088\2\2TU\5\34\17\2U\u00ab"+ + "\3\2\2\2VY\7!\2\2WX\t\3\2\2XZ\7\u0088\2\2YW\3\2\2\2YZ\3\2\2\2Z[\3\2\2"+ + "\2[\u00ab\5\34\17\2\\]\7\"\2\2]^\7\u0086\2\2^_\5\34\17\2_`\7\u0087\2\2"+ + "`a\7\u0088\2\2ab\7o\2\2b\u00ab\3\2\2\2cd\7\"\2\2de\7o\2\2ef\7\u0088\2"+ + "\2fg\7\u0086\2\2gh\5\34\17\2hi\7\u0087\2\2i\u00ab\3\2\2\2jk\7\"\2\2kl"+ + "\7\u0086\2\2lm\5\34\17\2mn\7\u0087\2\2no\7\u0088\2\2op\7`\2\2p\u00ab\3"+ + "\2\2\2qr\7\"\2\2rs\7`\2\2st\7\u0088\2\2tu\7\u0086\2\2uv\5\34\17\2vw\7"+ + "\u0087\2\2w\u00ab\3\2\2\2x|\7 \2\2yz\5\16\b\2z{\7\u0088\2\2{}\3\2\2\2"+ + "|y\3\2\2\2|}\3\2\2\2}~\3\2\2\2~\u00ab\5\34\17\2\177\u0080\7\t\2\2\u0080"+ + "\u00ab\5\34\17\2\u0081\u0082\7\t\2\2\u0082\u0083\5\16\b\2\u0083\u0084"+ + "\7\u0088\2\2\u0084\u0085\5\34\17\2\u0085\u00ab\3\2\2\2\u0086\u0087\7\6"+ + "\2\2\u0087\u0088\7`\2\2\u0088\u0089\7\u0088\2\2\u0089\u00ab\5\34\17\2"+ + "\u008a\u008b\7\5\2\2\u008b\u008c\7`\2\2\u008c\u008d\7\u0088\2\2\u008d"+ + "\u00ab\5\34\17\2\u008e\u008f\7,\2\2\u008f\u0090\7\u0086\2\2\u0090\u0091"+ + "\5\34\17\2\u0091\u0092\7\u0087\2\2\u0092\u0093\7\u0088\2\2\u0093\u0094"+ + "\7`\2\2\u0094\u00ab\3\2\2\2\u0095\u0096\7G\2\2\u0096\u00ab\5\34\17\2\u0097"+ + "\u0098\7\32\2\2\u0098\u0099\7`\2\2\u0099\u009a\7\u0088\2\2\u009a\u009b"+ + "\7\u0086\2\2\u009b\u009c\5\34\17\2\u009c\u009d\7\u0087\2\2\u009d\u00ab"+ + "\3\2\2\2\u009e\u009f\7@\2\2\u009f\u00a0\7`\2\2\u00a0\u00a1\7\u0088\2\2"+ + "\u00a1\u00ab\5\34\17\2\u00a2\u00a3\7\7\2\2\u00a3\u00ab\5\34\17\2\u00a4"+ + "\u00a5\7H\2\2\u00a5\u00ab\5\34\17\2\u00a6\u00a7\7)\2\2\u00a7\u00ab\5\34"+ + "\17\2\u00a8\u00a9\7\13\2\2\u00a9\u00ab\5\34\17\2\u00aaL\3\2\2\2\u00aa"+ + "M\3\2\2\2\u00aaQ\3\2\2\2\u00aaV\3\2\2\2\u00aa\\\3\2\2\2\u00aac\3\2\2\2"+ + "\u00aaj\3\2\2\2\u00aaq\3\2\2\2\u00aax\3\2\2\2\u00aa\177\3\2\2\2\u00aa"+ + "\u0081\3\2\2\2\u00aa\u0086\3\2\2\2\u00aa\u008a\3\2\2\2\u00aa\u008e\3\2"+ + "\2\2\u00aa\u0095\3\2\2\2\u00aa\u0097\3\2\2\2\u00aa\u009e\3\2\2\2\u00aa"+ + "\u00a2\3\2\2\2\u00aa\u00a4\3\2\2\2\u00aa\u00a6\3\2\2\2\u00aa\u00a8\3\2"+ + "\2\2\u00ab\t\3\2\2\2\u00ac\u011b\7(\2\2\u00ad\u00ae\7\"\2\2\u00ae\u00af"+ + "\7\u0086\2\2\u00af\u00b0\t\4\2\2\u00b0\u00b1\7\u0087\2\2\u00b1\u00b2\7"+ + "\u0088\2\2\u00b2\u011b\7`\2\2\u00b3\u00b4\7\"\2\2\u00b4\u00b5\7\u0086"+ + "\2\2\u00b5\u00b6\7o\2\2\u00b6\u00b7\7\u0087\2\2\u00b7\u00b8\7\u0088\2"+ + "\2\u00b8\u011b\5\f\7\2\u00b9\u00ba\7\33\2\2\u00ba\u011b\t\2\2\2\u00bb"+ + "\u00bc\7\33\2\2\u00bc\u011b\5\f\7\2\u00bd\u00be\7\22\2\2\u00be\u011b\5"+ + "\f\7\2\u00bf\u011b\78\2\2\u00c0\u00c1\7\26\2\2\u00c1\u00c2\7q\2\2\u00c2"+ + "\u00c3\7\u0088\2\2\u00c3\u011b\7r\2\2\u00c4\u00c5\7\26\2\2\u00c5\u00c6"+ + "\7n\2\2\u00c6\u00c7\7\u0088\2\2\u00c7\u011b\7o\2\2\u00c8\u00c9\7\26\2"+ + "\2\u00c9\u00ca\7\u0086\2\2\u00ca\u00cb\7p\2\2\u00cb\u00cc\7\u0087\2\2"+ + "\u00cc\u00cd\7\u0088\2\2\u00cd\u011b\7o\2\2\u00ce\u00cf\7\6\2\2\u00cf"+ + "\u00d0\7o\2\2\u00d0\u00d1\7\u0088\2\2\u00d1\u011b\t\2\2\2\u00d2\u00d3"+ + "\7\"\2\2\u00d3\u00d4\7`\2\2\u00d4\u00d5\7\u0088\2\2\u00d5\u00d6\7\u0086"+ + "\2\2\u00d6\u00d7\t\4\2\2\u00d7\u011b\7\u0087\2\2\u00d8\u00d9\7\22\2\2"+ + "\u00d9\u011b\t\2\2\2\u00da\u011b\7=\2\2\u00db\u011b\7\66\2\2\u00dc\u011b"+ + "\7;\2\2\u00dd\u011b\7\21\2\2\u00de\u011b\7\20\2\2\u00df\u00e0\7\33\2\2"+ + "\u00e0\u00e1\7\u0086\2\2\u00e1\u00e2\7o\2\2\u00e2\u011b\7\u0087\2\2\u00e3"+ + "\u00e4\7\22\2\2\u00e4\u00e5\7\u0086\2\2\u00e5\u00e6\7o\2\2\u00e6\u011b"+ + "\7\u0087\2\2\u00e7\u011b\7A\2\2\u00e8\u011b\7\n\2\2\u00e9\u00ea\7\"\2"+ + "\2\u00ea\u00eb\5\f\7\2\u00eb\u00ec\7\u0088\2\2\u00ec\u00ed\5\f\7\2\u00ed"+ + "\u011b\3\2\2\2\u00ee\u011b\7\30\2\2\u00ef\u00f0\7\6\2\2\u00f0\u00f1\7"+ + "`\2\2\u00f1\u00f2\7\u0088\2\2\u00f2\u011b\5\f\7\2\u00f3\u00f4\7\5\2\2"+ + "\u00f4\u00f5\7`\2\2\u00f5\u00f6\7\u0088\2\2\u00f6\u011b\5\f\7\2\u00f7"+ + "\u00f8\7G\2\2\u00f8\u011b\5\f\7\2\u00f9\u00fa\7@\2\2\u00fa\u00fb\7`\2"+ + "\2\u00fb\u00fc\7\u0088\2\2\u00fc\u011b\5\f\7\2\u00fd\u00fe\7\7\2\2\u00fe"+ + "\u011b\5\f\7\2\u00ff\u0100\7H\2\2\u0100\u011b\5\f\7\2\u0101\u0102\7)\2"+ + "\2\u0102\u011b\5\f\7\2\u0103\u0104\7\13\2\2\u0104\u011b\5\f\7\2\u0105"+ + "\u0107\7\62\2\2\u0106\u0108\5\16\b\2\u0107\u0106\3\2\2\2\u0107\u0108\3"+ + "\2\2\2\u0108\u011b\3\2\2\2\u0109\u010a\7/\2\2\u010a\u011b\t\5\2\2\u010b"+ + "\u010c\7\60\2\2\u010c\u011b\t\5\2\2\u010d\u010e\7?\2\2\u010e\u011b\5\34"+ + "\17\2\u010f\u011b\7\27\2\2\u0110\u0111\7 \2\2\u0111\u0112\7\u0086\2\2"+ + "\u0112\u0113\7o\2\2\u0113\u011b\7\u0087\2\2\u0114\u011b\7\23\2\2\u0115"+ + "\u0116\7\"\2\2\u0116\u0117\7p\2\2\u0117\u0118\7\u0088\2\2\u0118\u011b"+ + "\7o\2\2\u0119\u011b\7\25\2\2\u011a\u00ac\3\2\2\2\u011a\u00ad\3\2\2\2\u011a"+ + "\u00b3\3\2\2\2\u011a\u00b9\3\2\2\2\u011a\u00bb\3\2\2\2\u011a\u00bd\3\2"+ + "\2\2\u011a\u00bf\3\2\2\2\u011a\u00c0\3\2\2\2\u011a\u00c4\3\2\2\2\u011a"+ + "\u00c8\3\2\2\2\u011a\u00ce\3\2\2\2\u011a\u00d2\3\2\2\2\u011a\u00d8\3\2"+ + "\2\2\u011a\u00da\3\2\2\2\u011a\u00db\3\2\2\2\u011a\u00dc\3\2\2\2\u011a"+ + "\u00dd\3\2\2\2\u011a\u00de\3\2\2\2\u011a\u00df\3\2\2\2\u011a\u00e3\3\2"+ + "\2\2\u011a\u00e7\3\2\2\2\u011a\u00e8\3\2\2\2\u011a\u00e9\3\2\2\2\u011a"+ + "\u00ee\3\2\2\2\u011a\u00ef\3\2\2\2\u011a\u00f3\3\2\2\2\u011a\u00f7\3\2"+ + "\2\2\u011a\u00f9\3\2\2\2\u011a\u00fd\3\2\2\2\u011a\u00ff\3\2\2\2\u011a"+ + "\u0101\3\2\2\2\u011a\u0103\3\2\2\2\u011a\u0105\3\2\2\2\u011a\u0109\3\2"+ + "\2\2\u011a\u010b\3\2\2\2\u011a\u010d\3\2\2\2\u011a\u010f\3\2\2\2\u011a"+ + "\u0110\3\2\2\2\u011a\u0114\3\2\2\2\u011a\u0115\3\2\2\2\u011a\u0119\3\2"+ + "\2\2\u011b\13\3\2\2\2\u011c\u0127\7`\2\2\u011d\u0127\7a\2\2\u011e\u0127"+ + "\7b\2\2\u011f\u0127\7c\2\2\u0120\u0127\7d\2\2\u0121\u0127\7e\2\2\u0122"+ + "\u0127\7f\2\2\u0123\u0124\7\u0086\2\2\u0124\u0125\7o\2\2\u0125\u0127\7"+ + "\u0087\2\2\u0126\u011c\3\2\2\2\u0126\u011d\3\2\2\2\u0126\u011e\3\2\2\2"+ + "\u0126\u011f\3\2\2\2\u0126\u0120\3\2\2\2\u0126\u0121\3\2\2\2\u0126\u0122"+ + "\3\2\2\2\u0126\u0123\3\2\2\2\u0127\r\3\2\2\2\u0128\u0129\t\6\2\2\u0129"+ + "\17\3\2\2\2\u012a\u012b\7S\2\2\u012b\u0161\5\34\17\2\u012c\u012d\7\u0083"+ + "\2\2\u012d\u012e\7T\2\2\u012e\u0161\5\34\17\2\u012f\u0130\7\u0083\2\2"+ + "\u0130\u0131\7U\2\2\u0131\u0161\5\34\17\2\u0132\u0133\7W\2\2\u0133\u0134"+ + "\5\34\17\2\u0134\u013a\7\u009a\2\2\u0135\u0136\5\4\3\2\u0136\u0137\7\u009a"+ + "\2\2\u0137\u0139\3\2\2\2\u0138\u0135\3\2\2\2\u0139\u013c\3\2\2\2\u013a"+ + "\u0138\3\2\2\2\u013a\u013b\3\2\2\2\u013b\u0140\3\2\2\2\u013c\u013a\3\2"+ + "\2\2\u013d\u013f\7\u009a\2\2\u013e\u013d\3\2\2\2\u013f\u0142\3\2\2\2\u0140"+ + "\u013e\3\2\2\2\u0140\u0141\3\2\2\2\u0141\u0143\3\2\2\2\u0142\u0140\3\2"+ + "\2\2\u0143\u0144\7X\2\2\u0144\u0161\3\2\2\2\u0145\u0146\7\u0083\2\2\u0146"+ + "\u0148\7Z\2\2\u0147\u0149\5\22\n\2\u0148\u0147\3\2\2\2\u0148\u0149\3\2"+ + "\2\2\u0149\u014a\3\2\2\2\u014a\u0150\7\u009a\2\2\u014b\u014c\5\4\3\2\u014c"+ + "\u014d\7\u009a\2\2\u014d\u014f\3\2\2\2\u014e\u014b\3\2\2\2\u014f\u0152"+ + "\3\2\2\2\u0150\u014e\3\2\2\2\u0150\u0151\3\2\2\2\u0151\u0156\3\2\2\2\u0152"+ + "\u0150\3\2\2\2\u0153\u0155\7\u009a\2\2\u0154\u0153\3\2\2\2\u0155\u0158"+ + "\3\2\2\2\u0156\u0154\3\2\2\2\u0156\u0157\3\2\2\2\u0157\u0159\3\2\2\2\u0158"+ + "\u0156\3\2\2\2\u0159\u0161\7[\2\2\u015a\u015c\7\u0083\2\2\u015b\u015d"+ + "\5\24\13\2\u015c\u015b\3\2\2\2\u015c\u015d\3\2\2\2\u015d\u0161\3\2\2\2"+ + "\u015e\u015f\7Y\2\2\u015f\u0161\t\7\2\2\u0160\u012a\3\2\2\2\u0160\u012c"+ + "\3\2\2\2\u0160\u012f\3\2\2\2\u0160\u0132\3\2\2\2\u0160\u0145\3\2\2\2\u0160"+ + "\u015a\3\2\2\2\u0160\u015e\3\2\2\2\u0161\21\3\2\2\2\u0162\u0167\7\u0083"+ + "\2\2\u0163\u0164\7\u0088\2\2\u0164\u0166\7\u0083\2\2\u0165\u0163\3\2\2"+ + "\2\u0166\u0169\3\2\2\2\u0167\u0165\3\2\2\2\u0167\u0168\3\2\2\2\u0168\23"+ + "\3\2\2\2\u0169\u0167\3\2\2\2\u016a\u016f\5\34\17\2\u016b\u016c\7\u0088"+ + "\2\2\u016c\u016e\5\34\17\2\u016d\u016b\3\2\2\2\u016e\u0171\3\2\2\2\u016f"+ + "\u016d\3\2\2\2\u016f\u0170\3\2\2\2\u0170\25\3\2\2\2\u0171\u016f\3\2\2"+ + "\2\u0172\u0173\7\\\2\2\u0173\u0178\5\30\r\2\u0174\u0175\7\u0088\2\2\u0175"+ + "\u0177\5\30\r\2\u0176\u0174\3\2\2\2\u0177\u017a\3\2\2\2\u0178\u0176\3"+ + "\2\2\2\u0178\u0179\3\2\2\2\u0179\u0187\3\2\2\2\u017a\u0178\3\2\2\2\u017b"+ + "\u017c\7]\2\2\u017c\u0181\5\32\16\2\u017d\u017e\7\u0088\2\2\u017e\u0180"+ + "\5\32\16\2\u017f\u017d\3\2\2\2\u0180\u0183\3\2\2\2\u0181\u017f\3\2\2\2"+ + "\u0181\u0182\3\2\2\2\u0182\u0187\3\2\2\2\u0183\u0181\3\2\2\2\u0184\u0185"+ + "\7^\2\2\u0185\u0187\5\34\17\2\u0186\u0172\3\2\2\2\u0186\u017b\3\2\2\2"+ + "\u0186\u0184\3\2\2\2\u0187\27\3\2\2\2\u0188\u018b\5\34\17\2\u0189\u018b"+ + "\5\n\6\2\u018a\u0188\3\2\2\2\u018a\u0189\3\2\2\2\u018b\31\3\2\2\2\u018c"+ + "\u018d\5\34\17\2\u018d\33\3\2\2\2\u018e\u018f\b\17\1\2\u018f\u0190\t\b"+ + "\2\2\u0190\u019e\5\34\17\24\u0191\u0192\7\u0086\2\2\u0192\u0193\5\34\17"+ + "\2\u0193\u0194\7\u0087\2\2\u0194\u019e\3\2\2\2\u0195\u019e\7}\2\2\u0196"+ + "\u019e\7|\2\2\u0197\u019e\7~\2\2\u0198\u019e\7\177\2\2\u0199\u019e\7\u0080"+ + "\2\2\u019a\u019e\7_\2\2\u019b\u019e\7\u0083\2\2\u019c\u019e\t\7\2\2\u019d"+ + "\u018e\3\2\2\2\u019d\u0191\3\2\2\2\u019d\u0195\3\2\2\2\u019d\u0196\3\2"+ + "\2\2\u019d\u0197\3\2\2\2\u019d\u0198\3\2\2\2\u019d\u0199\3\2\2\2\u019d"+ + "\u019a\3\2\2\2\u019d\u019b\3\2\2\2\u019d\u019c\3\2\2\2\u019e\u01b9\3\2"+ + "\2\2\u019f\u01a0\f\23\2\2\u01a0\u01a1\t\t\2\2\u01a1\u01b8\5\34\17\24\u01a2"+ + "\u01a3\f\22\2\2\u01a3\u01a4\t\n\2\2\u01a4\u01b8\5\34\17\23\u01a5\u01a6"+ + "\f\21\2\2\u01a6\u01a7\t\13\2\2\u01a7\u01b8\5\34\17\22\u01a8\u01a9\f\20"+ + "\2\2\u01a9\u01aa\t\f\2\2\u01aa\u01b8\5\34\17\20\u01ab\u01ac\f\17\2\2\u01ac"+ + "\u01ad\7\u008d\2\2\u01ad\u01b8\5\34\17\17\u01ae\u01af\f\16\2\2\u01af\u01b0"+ + "\t\r\2\2\u01b0\u01b8\5\34\17\17\u01b1\u01b2\f\r\2\2\u01b2\u01b3\t\16\2"+ + "\2\u01b3\u01b8\5\34\17\16\u01b4\u01b5\f\f\2\2\u01b5\u01b6\t\17\2\2\u01b6"+ + "\u01b8\5\34\17\r\u01b7\u019f\3\2\2\2\u01b7\u01a2\3\2\2\2\u01b7\u01a5\3"+ + "\2\2\2\u01b7\u01a8\3\2\2\2\u01b7\u01ab\3\2\2\2\u01b7\u01ae\3\2\2\2\u01b7"+ + "\u01b1\3\2\2\2\u01b7\u01b4\3\2\2\2\u01b8\u01bb\3\2\2\2\u01b9\u01b7\3\2"+ + "\2\2\u01b9\u01ba\3\2\2\2\u01ba\35\3\2\2\2\u01bb\u01b9\3\2\2\2!!%*/\65"+ + ";@EJY|\u00aa\u0107\u011a\u0126\u013a\u0140\u0148\u0150\u0156\u015c\u0160"+ + "\u0167\u016f\u0178\u0181\u0186\u018a\u019d\u01b7\u01b9"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.tokens b/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.tokens new file mode 100644 index 000000000..e398feb30 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.tokens @@ -0,0 +1,172 @@ +COMMENT=1 +COMMENT2=2 +OPCODE_ADC=3 +OPCODE_ADD=4 +OPCODE_AND=5 +OPCODE_BIT=6 +OPCODE_CALL=7 +OPCODE_CCF=8 +OPCODE_CP=9 +OPCODE_CPD=10 +OPCODE_CPDR=11 +OPCODE_CPI=12 +OPCODE_CPIR=13 +OPCODE_CPL=14 +OPCODE_DAA=15 +OPCODE_DEC=16 +OPCODE_DI=17 +OPCODE_DJNZ=18 +OPCODE_EI=19 +OPCODE_EX=20 +OPCODE_EXX=21 +OPCODE_HALT=22 +OPCODE_IM=23 +OPCODE_IN=24 +OPCODE_INC=25 +OPCODE_IND=26 +OPCODE_INDR=27 +OPCODE_INI=28 +OPCODE_INIR=29 +OPCODE_JP=30 +OPCODE_JR=31 +OPCODE_LD=32 +OPCODE_LDD=33 +OPCODE_LDDR=34 +OPCODE_LDI=35 +OPCODE_LDIR=36 +OPCODE_NEG=37 +OPCODE_NOP=38 +OPCODE_OR=39 +OPCODE_OTDR=40 +OPCODE_OTIR=41 +OPCODE_OUT=42 +OPCODE_OUTD=43 +OPCODE_OUTI=44 +OPCODE_POP=45 +OPCODE_PUSH=46 +OPCODE_RES=47 +OPCODE_RET=48 +OPCODE_RETI=49 +OPCODE_RETN=50 +OPCODE_RL=51 +OPCODE_RLA=52 +OPCODE_RLC=53 +OPCODE_RLCA=54 +OPCODE_RLD=55 +OPCODE_RR=56 +OPCODE_RRA=57 +OPCODE_RRC=58 +OPCODE_RRCA=59 +OPCODE_RRD=60 +OPCODE_RST=61 +OPCODE_SBC=62 +OPCODE_SCF=63 +OPCODE_SET=64 +OPCODE_SLA=65 +OPCODE_SRA=66 +OPCODE_SLL=67 +OPCODE_SRL=68 +OPCODE_SUB=69 +OPCODE_XOR=70 +COND_C=71 +COND_NC=72 +COND_Z=73 +COND_NZ=74 +COND_M=75 +COND_P=76 +COND_PE=77 +COND_PO=78 +COND_WS=79 +COND_UNRECOGNIZED=80 +PREP_ORG=81 +PREP_EQU=82 +PREP_SET=83 +PREP_VAR=84 +PREP_IF=85 +PREP_ENDIF=86 +PREP_INCLUDE=87 +PREP_MACRO=88 +PREP_ENDM=89 +PREP_DB=90 +PREP_DW=91 +PREP_DS=92 +PREP_ADDR=93 +REG_A=94 +REG_B=95 +REG_C=96 +REG_D=97 +REG_E=98 +REG_H=99 +REG_L=100 +REG_IX=101 +REG_IXH=102 +REG_IXL=103 +REG_IY=104 +REG_IYH=105 +REG_IYL=106 +REG_BC=107 +REG_DE=108 +REG_HL=109 +REG_SP=110 +REG_AF=111 +REG_AFF=112 +REG_I=113 +REG_R=114 +OP_MOD=115 +OP_SHR=116 +OP_SHL=117 +OP_NOT=118 +OP_AND=119 +OP_OR=120 +OP_XOR=121 +LIT_HEXNUMBER_1=122 +LIT_NUMBER=123 +LIT_HEXNUMBER_2=124 +LIT_OCTNUMBER=125 +LIT_BINNUMBER=126 +LIT_STRING_1=127 +LIT_STRING_2=128 +ID_IDENTIFIER=129 +ID_LABEL=130 +ERROR=131 +SEP_LPAR=132 +SEP_RPAR=133 +SEP_COMMA=134 +OP_ADD=135 +OP_SUBTRACT=136 +OP_MULTIPLY=137 +OP_DIVIDE=138 +OP_EQUAL=139 +OP_GT=140 +OP_GTE=141 +OP_LT=142 +OP_LTE=143 +OP_MOD_2=144 +OP_SHR_2=145 +OP_SHL_2=146 +OP_NOT_2=147 +OP_AND_2=148 +OP_OR_2=149 +OP_XOR_2=150 +WS=151 +EOL=152 +'$'=93 +'('=132 +')'=133 +','=134 +'+'=135 +'-'=136 +'*'=137 +'/'=138 +'='=139 +'>'=140 +'>='=141 +'<'=142 +'<='=143 +'%'=144 +'>>'=145 +'<<'=146 +'!'=147 +'&'=148 +'|'=149 +'~'=150 diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseListener.java b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseListener.java new file mode 100644 index 000000000..368ba9d8d --- /dev/null +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseListener.java @@ -0,0 +1,578 @@ +// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 by ANTLR 4.9.2 + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link AsZ80ParserListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +public class AsZ80ParserBaseListener implements AsZ80ParserListener { + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterRStart(AsZ80Parser.RStartContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitRStart(AsZ80Parser.RStartContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterRLine(AsZ80Parser.RLineContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitRLine(AsZ80Parser.RLineContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterRStatement(AsZ80Parser.RStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitRStatement(AsZ80Parser.RStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstr8bit(AsZ80Parser.Instr8bitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstr8bit(AsZ80Parser.Instr8bitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrExprReg(AsZ80Parser.InstrExprRegContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrExprReg(AsZ80Parser.InstrExprRegContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrExpr(AsZ80Parser.InstrExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrExpr(AsZ80Parser.InstrExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrRegPair(AsZ80Parser.InstrRegPairContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrRegPair(AsZ80Parser.InstrRegPairContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrReg(AsZ80Parser.InstrRegContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrReg(AsZ80Parser.InstrRegContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrRegReg(AsZ80Parser.InstrRegRegContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrRegReg(AsZ80Parser.InstrRegRegContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstrCond(AsZ80Parser.InstrCondContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstrCond(AsZ80Parser.InstrCondContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterRRegister(AsZ80Parser.RRegisterContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitRRegister(AsZ80Parser.RRegisterContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterCCondition(AsZ80Parser.CConditionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitCCondition(AsZ80Parser.CConditionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPseudoOrg(AsZ80Parser.PseudoOrgContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPseudoOrg(AsZ80Parser.PseudoOrgContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPseudoEqu(AsZ80Parser.PseudoEquContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPseudoEqu(AsZ80Parser.PseudoEquContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPseudoSet(AsZ80Parser.PseudoSetContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPseudoSet(AsZ80Parser.PseudoSetContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPseudoIf(AsZ80Parser.PseudoIfContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPseudoIf(AsZ80Parser.PseudoIfContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterRMacroParameters(AsZ80Parser.RMacroParametersContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitRMacroParameters(AsZ80Parser.RMacroParametersContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterDataDB(AsZ80Parser.DataDBContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitDataDB(AsZ80Parser.DataDBContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterDataDW(AsZ80Parser.DataDWContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitDataDW(AsZ80Parser.DataDWContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterDataDS(AsZ80Parser.DataDSContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitDataDS(AsZ80Parser.DataDSContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterRDBdata(AsZ80Parser.RDBdataContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitRDBdata(AsZ80Parser.RDBdataContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterRDWdata(AsZ80Parser.RDWdataContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitRDWdata(AsZ80Parser.RDWdataContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprOct(AsZ80Parser.ExprOctContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprOct(AsZ80Parser.ExprOctContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprHex1(AsZ80Parser.ExprHex1Context ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprHex1(AsZ80Parser.ExprHex1Context ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprHex2(AsZ80Parser.ExprHex2Context ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprHex2(AsZ80Parser.ExprHex2Context ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprDec(AsZ80Parser.ExprDecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprDec(AsZ80Parser.ExprDecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprString(AsZ80Parser.ExprStringContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprString(AsZ80Parser.ExprStringContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprBin(AsZ80Parser.ExprBinContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprBin(AsZ80Parser.ExprBinContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprParens(AsZ80Parser.ExprParensContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprParens(AsZ80Parser.ExprParensContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprId(AsZ80Parser.ExprIdContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprId(AsZ80Parser.ExprIdContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprUnary(AsZ80Parser.ExprUnaryContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprUnary(AsZ80Parser.ExprUnaryContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprInfix(AsZ80Parser.ExprInfixContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprInfix(AsZ80Parser.ExprInfixContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitErrorNode(ErrorNode node) { } +} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseVisitor.java b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseVisitor.java new file mode 100644 index 000000000..3e16f7c77 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseVisitor.java @@ -0,0 +1,328 @@ +// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 by ANTLR 4.9.2 +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + +/** + * This class provides an empty implementation of {@link AsZ80ParserVisitor}, + * which can be extended to create a visitor which only needs to handle a subset + * of the available methods. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public class AsZ80ParserBaseVisitor extends AbstractParseTreeVisitor implements AsZ80ParserVisitor { + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitRStart(AsZ80Parser.RStartContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitRLine(AsZ80Parser.RLineContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitRStatement(AsZ80Parser.RStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstr8bit(AsZ80Parser.Instr8bitContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrExprReg(AsZ80Parser.InstrExprRegContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrExpr(AsZ80Parser.InstrExprContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrRegPair(AsZ80Parser.InstrRegPairContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrReg(AsZ80Parser.InstrRegContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrRegReg(AsZ80Parser.InstrRegRegContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstrCond(AsZ80Parser.InstrCondContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitRRegister(AsZ80Parser.RRegisterContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitCCondition(AsZ80Parser.CConditionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPseudoOrg(AsZ80Parser.PseudoOrgContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPseudoEqu(AsZ80Parser.PseudoEquContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPseudoSet(AsZ80Parser.PseudoSetContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPseudoIf(AsZ80Parser.PseudoIfContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitRMacroParameters(AsZ80Parser.RMacroParametersContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitDataDB(AsZ80Parser.DataDBContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitDataDW(AsZ80Parser.DataDWContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitDataDS(AsZ80Parser.DataDSContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitRDBdata(AsZ80Parser.RDBdataContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitRDWdata(AsZ80Parser.RDWdataContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprOct(AsZ80Parser.ExprOctContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprHex1(AsZ80Parser.ExprHex1Context ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprHex2(AsZ80Parser.ExprHex2Context ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprDec(AsZ80Parser.ExprDecContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprString(AsZ80Parser.ExprStringContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprBin(AsZ80Parser.ExprBinContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprParens(AsZ80Parser.ExprParensContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprId(AsZ80Parser.ExprIdContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprUnary(AsZ80Parser.ExprUnaryContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprInfix(AsZ80Parser.ExprInfixContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx) { return visitChildren(ctx); } +} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserListener.java b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserListener.java new file mode 100644 index 000000000..149359e3b --- /dev/null +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserListener.java @@ -0,0 +1,531 @@ +// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 by ANTLR 4.9.2 +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link AsZ80Parser}. + */ +public interface AsZ80ParserListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link AsZ80Parser#rStart}. + * @param ctx the parse tree + */ + void enterRStart(AsZ80Parser.RStartContext ctx); + /** + * Exit a parse tree produced by {@link AsZ80Parser#rStart}. + * @param ctx the parse tree + */ + void exitRStart(AsZ80Parser.RStartContext ctx); + /** + * Enter a parse tree produced by {@link AsZ80Parser#rLine}. + * @param ctx the parse tree + */ + void enterRLine(AsZ80Parser.RLineContext ctx); + /** + * Exit a parse tree produced by {@link AsZ80Parser#rLine}. + * @param ctx the parse tree + */ + void exitRLine(AsZ80Parser.RLineContext ctx); + /** + * Enter a parse tree produced by {@link AsZ80Parser#rStatement}. + * @param ctx the parse tree + */ + void enterRStatement(AsZ80Parser.RStatementContext ctx); + /** + * Exit a parse tree produced by {@link AsZ80Parser#rStatement}. + * @param ctx the parse tree + */ + void exitRStatement(AsZ80Parser.RStatementContext ctx); + /** + * Enter a parse tree produced by the {@code instr8bit} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void enterInstr8bit(AsZ80Parser.Instr8bitContext ctx); + /** + * Exit a parse tree produced by the {@code instr8bit} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void exitInstr8bit(AsZ80Parser.Instr8bitContext ctx); + /** + * Enter a parse tree produced by the {@code instrRegPairExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void enterInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx); + /** + * Exit a parse tree produced by the {@code instrRegPairExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void exitInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx); + /** + * Enter a parse tree produced by the {@code instrRegExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void enterInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx); + /** + * Exit a parse tree produced by the {@code instrRegExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void exitInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx); + /** + * Enter a parse tree produced by the {@code instrCondExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void enterInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx); + /** + * Exit a parse tree produced by the {@code instrCondExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void exitInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx); + /** + * Enter a parse tree produced by the {@code instrExprRegPair} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void enterInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx); + /** + * Exit a parse tree produced by the {@code instrExprRegPair} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void exitInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx); + /** + * Enter a parse tree produced by the {@code instrExprReg} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void enterInstrExprReg(AsZ80Parser.InstrExprRegContext ctx); + /** + * Exit a parse tree produced by the {@code instrExprReg} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void exitInstrExprReg(AsZ80Parser.InstrExprRegContext ctx); + /** + * Enter a parse tree produced by the {@code instrExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void enterInstrExpr(AsZ80Parser.InstrExprContext ctx); + /** + * Exit a parse tree produced by the {@code instrExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + */ + void exitInstrExpr(AsZ80Parser.InstrExprContext ctx); + /** + * Enter a parse tree produced by the {@code instrNoArgs} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void enterInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx); + /** + * Exit a parse tree produced by the {@code instrNoArgs} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void exitInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx); + /** + * Enter a parse tree produced by the {@code instrRegPair} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void enterInstrRegPair(AsZ80Parser.InstrRegPairContext ctx); + /** + * Exit a parse tree produced by the {@code instrRegPair} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void exitInstrRegPair(AsZ80Parser.InstrRegPairContext ctx); + /** + * Enter a parse tree produced by the {@code instrRegPairReg} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void enterInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx); + /** + * Exit a parse tree produced by the {@code instrRegPairReg} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void exitInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx); + /** + * Enter a parse tree produced by the {@code instrReg} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void enterInstrReg(AsZ80Parser.InstrRegContext ctx); + /** + * Exit a parse tree produced by the {@code instrReg} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void exitInstrReg(AsZ80Parser.InstrRegContext ctx); + /** + * Enter a parse tree produced by the {@code instrRegPairRegPair} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void enterInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx); + /** + * Exit a parse tree produced by the {@code instrRegPairRegPair} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void exitInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx); + /** + * Enter a parse tree produced by the {@code instrRegReg} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void enterInstrRegReg(AsZ80Parser.InstrRegRegContext ctx); + /** + * Exit a parse tree produced by the {@code instrRegReg} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void exitInstrRegReg(AsZ80Parser.InstrRegRegContext ctx); + /** + * Enter a parse tree produced by the {@code instrCond} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void enterInstrCond(AsZ80Parser.InstrCondContext ctx); + /** + * Exit a parse tree produced by the {@code instrCond} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void exitInstrCond(AsZ80Parser.InstrCondContext ctx); + /** + * Enter a parse tree produced by the {@code instr8bitExpr} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void enterInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx); + /** + * Exit a parse tree produced by the {@code instr8bitExpr} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + */ + void exitInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx); + /** + * Enter a parse tree produced by {@link AsZ80Parser#rRegister}. + * @param ctx the parse tree + */ + void enterRRegister(AsZ80Parser.RRegisterContext ctx); + /** + * Exit a parse tree produced by {@link AsZ80Parser#rRegister}. + * @param ctx the parse tree + */ + void exitRRegister(AsZ80Parser.RRegisterContext ctx); + /** + * Enter a parse tree produced by {@link AsZ80Parser#cCondition}. + * @param ctx the parse tree + */ + void enterCCondition(AsZ80Parser.CConditionContext ctx); + /** + * Exit a parse tree produced by {@link AsZ80Parser#cCondition}. + * @param ctx the parse tree + */ + void exitCCondition(AsZ80Parser.CConditionContext ctx); + /** + * Enter a parse tree produced by the {@code pseudoOrg} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void enterPseudoOrg(AsZ80Parser.PseudoOrgContext ctx); + /** + * Exit a parse tree produced by the {@code pseudoOrg} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void exitPseudoOrg(AsZ80Parser.PseudoOrgContext ctx); + /** + * Enter a parse tree produced by the {@code pseudoEqu} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void enterPseudoEqu(AsZ80Parser.PseudoEquContext ctx); + /** + * Exit a parse tree produced by the {@code pseudoEqu} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void exitPseudoEqu(AsZ80Parser.PseudoEquContext ctx); + /** + * Enter a parse tree produced by the {@code pseudoSet} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void enterPseudoSet(AsZ80Parser.PseudoSetContext ctx); + /** + * Exit a parse tree produced by the {@code pseudoSet} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void exitPseudoSet(AsZ80Parser.PseudoSetContext ctx); + /** + * Enter a parse tree produced by the {@code pseudoIf} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void enterPseudoIf(AsZ80Parser.PseudoIfContext ctx); + /** + * Exit a parse tree produced by the {@code pseudoIf} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void exitPseudoIf(AsZ80Parser.PseudoIfContext ctx); + /** + * Enter a parse tree produced by the {@code pseudoMacroDef} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void enterPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx); + /** + * Exit a parse tree produced by the {@code pseudoMacroDef} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void exitPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx); + /** + * Enter a parse tree produced by the {@code pseudoMacroCall} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void enterPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx); + /** + * Exit a parse tree produced by the {@code pseudoMacroCall} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void exitPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx); + /** + * Enter a parse tree produced by the {@code pseudoInclude} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void enterPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx); + /** + * Exit a parse tree produced by the {@code pseudoInclude} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + */ + void exitPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx); + /** + * Enter a parse tree produced by {@link AsZ80Parser#rMacroParameters}. + * @param ctx the parse tree + */ + void enterRMacroParameters(AsZ80Parser.RMacroParametersContext ctx); + /** + * Exit a parse tree produced by {@link AsZ80Parser#rMacroParameters}. + * @param ctx the parse tree + */ + void exitRMacroParameters(AsZ80Parser.RMacroParametersContext ctx); + /** + * Enter a parse tree produced by {@link AsZ80Parser#rMacroArguments}. + * @param ctx the parse tree + */ + void enterRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx); + /** + * Exit a parse tree produced by {@link AsZ80Parser#rMacroArguments}. + * @param ctx the parse tree + */ + void exitRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx); + /** + * Enter a parse tree produced by the {@code dataDB} + * labeled alternative in {@link AsZ80Parser#rData}. + * @param ctx the parse tree + */ + void enterDataDB(AsZ80Parser.DataDBContext ctx); + /** + * Exit a parse tree produced by the {@code dataDB} + * labeled alternative in {@link AsZ80Parser#rData}. + * @param ctx the parse tree + */ + void exitDataDB(AsZ80Parser.DataDBContext ctx); + /** + * Enter a parse tree produced by the {@code dataDW} + * labeled alternative in {@link AsZ80Parser#rData}. + * @param ctx the parse tree + */ + void enterDataDW(AsZ80Parser.DataDWContext ctx); + /** + * Exit a parse tree produced by the {@code dataDW} + * labeled alternative in {@link AsZ80Parser#rData}. + * @param ctx the parse tree + */ + void exitDataDW(AsZ80Parser.DataDWContext ctx); + /** + * Enter a parse tree produced by the {@code dataDS} + * labeled alternative in {@link AsZ80Parser#rData}. + * @param ctx the parse tree + */ + void enterDataDS(AsZ80Parser.DataDSContext ctx); + /** + * Exit a parse tree produced by the {@code dataDS} + * labeled alternative in {@link AsZ80Parser#rData}. + * @param ctx the parse tree + */ + void exitDataDS(AsZ80Parser.DataDSContext ctx); + /** + * Enter a parse tree produced by {@link AsZ80Parser#rDBdata}. + * @param ctx the parse tree + */ + void enterRDBdata(AsZ80Parser.RDBdataContext ctx); + /** + * Exit a parse tree produced by {@link AsZ80Parser#rDBdata}. + * @param ctx the parse tree + */ + void exitRDBdata(AsZ80Parser.RDBdataContext ctx); + /** + * Enter a parse tree produced by {@link AsZ80Parser#rDWdata}. + * @param ctx the parse tree + */ + void enterRDWdata(AsZ80Parser.RDWdataContext ctx); + /** + * Exit a parse tree produced by {@link AsZ80Parser#rDWdata}. + * @param ctx the parse tree + */ + void exitRDWdata(AsZ80Parser.RDWdataContext ctx); + /** + * Enter a parse tree produced by the {@code exprOct} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void enterExprOct(AsZ80Parser.ExprOctContext ctx); + /** + * Exit a parse tree produced by the {@code exprOct} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void exitExprOct(AsZ80Parser.ExprOctContext ctx); + /** + * Enter a parse tree produced by the {@code exprHex1} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void enterExprHex1(AsZ80Parser.ExprHex1Context ctx); + /** + * Exit a parse tree produced by the {@code exprHex1} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void exitExprHex1(AsZ80Parser.ExprHex1Context ctx); + /** + * Enter a parse tree produced by the {@code exprHex2} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void enterExprHex2(AsZ80Parser.ExprHex2Context ctx); + /** + * Exit a parse tree produced by the {@code exprHex2} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void exitExprHex2(AsZ80Parser.ExprHex2Context ctx); + /** + * Enter a parse tree produced by the {@code exprDec} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void enterExprDec(AsZ80Parser.ExprDecContext ctx); + /** + * Exit a parse tree produced by the {@code exprDec} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void exitExprDec(AsZ80Parser.ExprDecContext ctx); + /** + * Enter a parse tree produced by the {@code exprString} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void enterExprString(AsZ80Parser.ExprStringContext ctx); + /** + * Exit a parse tree produced by the {@code exprString} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void exitExprString(AsZ80Parser.ExprStringContext ctx); + /** + * Enter a parse tree produced by the {@code exprBin} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void enterExprBin(AsZ80Parser.ExprBinContext ctx); + /** + * Exit a parse tree produced by the {@code exprBin} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void exitExprBin(AsZ80Parser.ExprBinContext ctx); + /** + * Enter a parse tree produced by the {@code exprParens} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void enterExprParens(AsZ80Parser.ExprParensContext ctx); + /** + * Exit a parse tree produced by the {@code exprParens} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void exitExprParens(AsZ80Parser.ExprParensContext ctx); + /** + * Enter a parse tree produced by the {@code exprId} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void enterExprId(AsZ80Parser.ExprIdContext ctx); + /** + * Exit a parse tree produced by the {@code exprId} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void exitExprId(AsZ80Parser.ExprIdContext ctx); + /** + * Enter a parse tree produced by the {@code exprUnary} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void enterExprUnary(AsZ80Parser.ExprUnaryContext ctx); + /** + * Exit a parse tree produced by the {@code exprUnary} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void exitExprUnary(AsZ80Parser.ExprUnaryContext ctx); + /** + * Enter a parse tree produced by the {@code exprInfix} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void enterExprInfix(AsZ80Parser.ExprInfixContext ctx); + /** + * Exit a parse tree produced by the {@code exprInfix} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void exitExprInfix(AsZ80Parser.ExprInfixContext ctx); + /** + * Enter a parse tree produced by the {@code exprCurrentAddress} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void enterExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx); + /** + * Exit a parse tree produced by the {@code exprCurrentAddress} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + */ + void exitExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx); +} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserVisitor.java b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserVisitor.java new file mode 100644 index 000000000..be8c7e54e --- /dev/null +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserVisitor.java @@ -0,0 +1,318 @@ +// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 by ANTLR 4.9.2 +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link AsZ80Parser}. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public interface AsZ80ParserVisitor extends ParseTreeVisitor { + /** + * Visit a parse tree produced by {@link AsZ80Parser#rStart}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitRStart(AsZ80Parser.RStartContext ctx); + /** + * Visit a parse tree produced by {@link AsZ80Parser#rLine}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitRLine(AsZ80Parser.RLineContext ctx); + /** + * Visit a parse tree produced by {@link AsZ80Parser#rStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitRStatement(AsZ80Parser.RStatementContext ctx); + /** + * Visit a parse tree produced by the {@code instr8bit} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstr8bit(AsZ80Parser.Instr8bitContext ctx); + /** + * Visit a parse tree produced by the {@code instrRegPairExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx); + /** + * Visit a parse tree produced by the {@code instrRegExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx); + /** + * Visit a parse tree produced by the {@code instrCondExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx); + /** + * Visit a parse tree produced by the {@code instrExprRegPair} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx); + /** + * Visit a parse tree produced by the {@code instrExprReg} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrExprReg(AsZ80Parser.InstrExprRegContext ctx); + /** + * Visit a parse tree produced by the {@code instrExpr} + * labeled alternative in {@link AsZ80Parser#rInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrExpr(AsZ80Parser.InstrExprContext ctx); + /** + * Visit a parse tree produced by the {@code instrNoArgs} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx); + /** + * Visit a parse tree produced by the {@code instrRegPair} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrRegPair(AsZ80Parser.InstrRegPairContext ctx); + /** + * Visit a parse tree produced by the {@code instrRegPairReg} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx); + /** + * Visit a parse tree produced by the {@code instrReg} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrReg(AsZ80Parser.InstrRegContext ctx); + /** + * Visit a parse tree produced by the {@code instrRegPairRegPair} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx); + /** + * Visit a parse tree produced by the {@code instrRegReg} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrRegReg(AsZ80Parser.InstrRegRegContext ctx); + /** + * Visit a parse tree produced by the {@code instrCond} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstrCond(AsZ80Parser.InstrCondContext ctx); + /** + * Visit a parse tree produced by the {@code instr8bitExpr} + * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx); + /** + * Visit a parse tree produced by {@link AsZ80Parser#rRegister}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitRRegister(AsZ80Parser.RRegisterContext ctx); + /** + * Visit a parse tree produced by {@link AsZ80Parser#cCondition}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitCCondition(AsZ80Parser.CConditionContext ctx); + /** + * Visit a parse tree produced by the {@code pseudoOrg} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPseudoOrg(AsZ80Parser.PseudoOrgContext ctx); + /** + * Visit a parse tree produced by the {@code pseudoEqu} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPseudoEqu(AsZ80Parser.PseudoEquContext ctx); + /** + * Visit a parse tree produced by the {@code pseudoSet} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPseudoSet(AsZ80Parser.PseudoSetContext ctx); + /** + * Visit a parse tree produced by the {@code pseudoIf} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPseudoIf(AsZ80Parser.PseudoIfContext ctx); + /** + * Visit a parse tree produced by the {@code pseudoMacroDef} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx); + /** + * Visit a parse tree produced by the {@code pseudoMacroCall} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx); + /** + * Visit a parse tree produced by the {@code pseudoInclude} + * labeled alternative in {@link AsZ80Parser#rPseudoCode}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx); + /** + * Visit a parse tree produced by {@link AsZ80Parser#rMacroParameters}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitRMacroParameters(AsZ80Parser.RMacroParametersContext ctx); + /** + * Visit a parse tree produced by {@link AsZ80Parser#rMacroArguments}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx); + /** + * Visit a parse tree produced by the {@code dataDB} + * labeled alternative in {@link AsZ80Parser#rData}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDataDB(AsZ80Parser.DataDBContext ctx); + /** + * Visit a parse tree produced by the {@code dataDW} + * labeled alternative in {@link AsZ80Parser#rData}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDataDW(AsZ80Parser.DataDWContext ctx); + /** + * Visit a parse tree produced by the {@code dataDS} + * labeled alternative in {@link AsZ80Parser#rData}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDataDS(AsZ80Parser.DataDSContext ctx); + /** + * Visit a parse tree produced by {@link AsZ80Parser#rDBdata}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitRDBdata(AsZ80Parser.RDBdataContext ctx); + /** + * Visit a parse tree produced by {@link AsZ80Parser#rDWdata}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitRDWdata(AsZ80Parser.RDWdataContext ctx); + /** + * Visit a parse tree produced by the {@code exprOct} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprOct(AsZ80Parser.ExprOctContext ctx); + /** + * Visit a parse tree produced by the {@code exprHex1} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprHex1(AsZ80Parser.ExprHex1Context ctx); + /** + * Visit a parse tree produced by the {@code exprHex2} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprHex2(AsZ80Parser.ExprHex2Context ctx); + /** + * Visit a parse tree produced by the {@code exprDec} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprDec(AsZ80Parser.ExprDecContext ctx); + /** + * Visit a parse tree produced by the {@code exprString} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprString(AsZ80Parser.ExprStringContext ctx); + /** + * Visit a parse tree produced by the {@code exprBin} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprBin(AsZ80Parser.ExprBinContext ctx); + /** + * Visit a parse tree produced by the {@code exprParens} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprParens(AsZ80Parser.ExprParensContext ctx); + /** + * Visit a parse tree produced by the {@code exprId} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprId(AsZ80Parser.ExprIdContext ctx); + /** + * Visit a parse tree produced by the {@code exprUnary} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprUnary(AsZ80Parser.ExprUnaryContext ctx); + /** + * Visit a parse tree produced by the {@code exprInfix} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprInfix(AsZ80Parser.ExprInfixContext ctx); + /** + * Visit a parse tree produced by the {@code exprCurrentAddress} + * labeled alternative in {@link AsZ80Parser#rExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx); +} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java new file mode 100644 index 000000000..595332b5e --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java @@ -0,0 +1,216 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2020 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.compiler.asZ80; + +import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; +import net.emustudio.emulib.plugins.annotations.PluginRoot; +import net.emustudio.emulib.plugins.compiler.AbstractCompiler; +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; +import net.emustudio.emulib.plugins.compiler.SourceFileExtension; +import net.emustudio.emulib.plugins.memory.MemoryContext; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.ContextNotFoundException; +import net.emustudio.emulib.runtime.InvalidContextException; +import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.helpers.RadixUtils; +import net.emustudio.emulib.runtime.io.IntelHEX; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.exceptions.CompileException; +import net.emustudio.plugins.compiler.asZ80.visitors.*; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.TokenStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.*; + +@PluginRoot( + type = PLUGIN_TYPE.COMPILER, + title = "Zilog Z80 Assembler" +) +@SuppressWarnings("unused") +public class AssemblerZ80 extends AbstractCompiler { + private final static Logger LOGGER = LoggerFactory.getLogger(AssemblerZ80.class); + private final static List SOURCE_FILE_EXTENSIONS = List.of( + new SourceFileExtension("asm", "Assembler source file"), + new SourceFileExtension("inc", "Include file") + ); + + private MemoryContext memory; + private int programLocation; + + public AssemblerZ80(long pluginID, ApplicationApi applicationApi, PluginSettings pluginSettings) { + super(pluginID, applicationApi, pluginSettings); + } + + @SuppressWarnings("unchecked") + @Override + public void initialize() { + Optional.ofNullable(applicationApi.getContextPool()).ifPresent(pool -> { + try { + memory = pool.getMemoryContext(pluginID, MemoryContext.class); + if (memory.getDataType() != Byte.class) { + throw new InvalidContextException( + "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() + ); + } + } catch (InvalidContextException | ContextNotFoundException e) { + LOGGER.warn("Memory is not available", e); + } + }); + } + + @Override + public String getVersion() { + return getResourceBundle().map(b -> b.getString("version")).orElse("(unknown)"); + } + + @Override + public String getCopyright() { + return getResourceBundle().map(b -> b.getString("copyright")).orElse("(unknown)"); + } + + @Override + public String getDescription() { + return "Assembler targetting Z80 microprocessor"; + } + + @Override + public LexicalAnalyzer createLexer(String s) { + AsZ80Lexer lexer = createLexer(CharStreams.fromString(s)); + return new LexicalAnalyzerImpl(lexer); + } + + @Override + public boolean compile(String inputFileName, String outputFileName) { + notifyCompileStart(); + notifyInfo(getTitle() + ", version " + getVersion()); + + try (Reader reader = new FileReader(inputFileName)) { + org.antlr.v4.runtime.Lexer lexer = createLexer(CharStreams.fromReader(reader)); + lexer.addErrorListener(new ParserErrorListener()); + CommonTokenStream tokens = new CommonTokenStream(lexer); + + AsZ80Parser parser = createParser(tokens); + parser.removeErrorListeners(); + parser.addErrorListener(new ParserErrorListener()); + + Program program = new Program(); + new CreateProgramVisitor(program).visit(parser.rStart()); + + IntelHEX hex = new IntelHEX(); + NodeVisitor[] visitors = new NodeVisitor[]{ + new ExpandIncludesVisitor(), + new CheckDeclarationsVisitor(), + new ExpandMacrosVisitor(), + new SortMacroArgumentsVisitor(), + // macro expansion could bring re-definition of declarations, but we cannot check declarations again + // until the macro is properly integrated (b/c we could see multiple macro defs on multiple calls) + new CheckDeclarationsVisitor(), + new EvaluateExprVisitor(), + new CheckExprSizesVisitor(), + new GenerateCodeVisitor(hex) + }; + + for (NodeVisitor visitor : visitors) { + visitor.visit(program); + } + + programLocation = 0; + if (program.env().hasNoErrors()) { + hex.generate(outputFileName); + programLocation = hex.findProgramLocation(); + + notifyInfo(String.format( + "Compile was successful.\n\tOutput: %s\n\tProgram starts at 0x%s", + outputFileName, RadixUtils.formatWordHexString(programLocation) + )); + + if (memory != null) { + hex.loadIntoMemory(memory, b -> b); + notifyInfo("Compiled file was loaded into memory."); + } else { + notifyWarning("Memory is not available."); + } + return true; + } else { + for (CompileError error : program.env().getErrors()) { + notifyError(error.line, error.column, error.msg); + } + return false; + } + } catch (CompileException e) { + notifyError(e.line, e.column, e.getMessage()); + return false; + } catch (IOException e) { + notifyError("Compilation error: " + e); + return false; + } finally { + notifyCompileFinish(); + } + } + + @Override + public boolean compile(String inputFileName) { + String outputFileName = Objects.requireNonNull(inputFileName); + SourceFileExtension srcExtension = SOURCE_FILE_EXTENSIONS.get(0); + + int i = inputFileName.lastIndexOf("." + srcExtension.getExtension()); + if (i >= 0) { + outputFileName = outputFileName.substring(0, i); + } + return compile(inputFileName, outputFileName + ".hex"); + } + + @Override + public int getProgramLocation() { + return programLocation; + } + + @Override + public List getSourceFileExtensions() { + return SOURCE_FILE_EXTENSIONS; + } + + private Optional getResourceBundle() { + try { + return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.compiler.asZ80.version")); + } catch (MissingResourceException e) { + return Optional.empty(); + } + } + + private AsZ80Lexer createLexer(CharStream input) { + AsZ80Lexer lexer = new AsZ80Lexer(input); + lexer.removeErrorListeners(); + return lexer; + } + + private AsZ80Parser createParser(TokenStream tokenStream) { + AsZ80Parser parser = new AsZ80Parser(tokenStream); + parser.removeErrorListeners(); + return parser; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java new file mode 100644 index 000000000..0cc5c5bca --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java @@ -0,0 +1,103 @@ +package net.emustudio.plugins.compiler.asZ80; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; + +import java.io.IOException; +import java.util.Objects; + +public class CompileError { + public static final int ERROR_ALREADY_DECLARED = 1; + public static final int ERROR_INFINITE_LOOP_DETECTED = 2; + public static final int ERROR_CANNOT_READ_FILE = 3; + public static final int ERROR_NOT_DEFINED = 4; + public static final int ERROR_AMBIGUOUS_EXPRESSION = 5; + public static final int ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK = 6; + public static final int ERROR_DECLARATION_REFERENCES_ITSELF = 7; + public static final int ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH = 8; + public static final int ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED = 9; + public static final int ERROR_VALUE_MUST_BE_POSITIVE = 10; + public static final int ERROR_VALUE_OUT_OF_BOUNDS = 11; + + public final int line; + public final int column; + public final String msg; + public final int errorCode; + + private CompileError(int line, int column, int errorCode, String msg) { + this.line = line; + this.column = column; + this.errorCode = errorCode; + this.msg = Objects.requireNonNull(msg); + } + + private CompileError(Node node, int errorCode, String msg) { + this(node.line, node.column, errorCode, msg); + } + + + public static CompileError alreadyDeclared(Node node, String what) { + return new CompileError(node, ERROR_ALREADY_DECLARED, what + " was already declared"); + } + + public static CompileError infiniteLoopDetected(Node node, String what) { + return new CompileError(node, ERROR_INFINITE_LOOP_DETECTED, "Infinite " + what + " loop detected"); + } + + public static CompileError couldNotReadFile(Node node, String filename, IOException e) { + return new CompileError( + node, ERROR_CANNOT_READ_FILE, "Could not read file: " + filename + " (" + e.getMessage() + ")" + ); + } + + public static CompileError notDefined(Node node, String what) { + return new CompileError(node, ERROR_NOT_DEFINED, "Not defined: " + what); + } + + public static CompileError ambiguousExpression(Node node) { + return new CompileError(node, ERROR_AMBIGUOUS_EXPRESSION, "Ambiguous expression"); + } + + public static CompileError ifExpressionReferencesOwnBlock(Node node) { + return new CompileError( + node, ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK, "If expression references declaration in its own block" + ); + } + + public static CompileError declarationReferencesItself(Node node) { + return new CompileError(node, ERROR_DECLARATION_REFERENCES_ITSELF, "Declaration references itself"); + } + + public static CompileError macroArgumentsDoNotMatch(Node node) { + return new CompileError( + node, ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH, "Macro call arguments do not match with defined parameters" + ); + } + + public static CompileError expressionIsBiggerThanExpected(Node node, int expectedBytes, int wasBytes) { + return new CompileError( + node, + ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED, + "Expression (" + wasBytes + " bytes) is bigger than expected (" + expectedBytes + " byte(s))" + ); + } + + public static CompileError valueMustBePositive(Node node) { + return new CompileError(node, ERROR_VALUE_MUST_BE_POSITIVE, "Value must be positive"); + } + + public static CompileError valueOutOfBounds(Node node, int min, int max) { + return new CompileError( + node, ERROR_VALUE_OUT_OF_BOUNDS, "Value is out of bounds (min=" + min + ", max=" + max + ")" + ); + } + + @Override + public String toString() { + return "CompileError{" + + "line=" + line + + ", column=" + column + + ", msg='" + msg + '\'' + + ", errorCode=" + errorCode + + '}'; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerImpl.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerImpl.java deleted file mode 100644 index 1125acd6c..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerImpl.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80; - -import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; -import net.emustudio.emulib.plugins.annotations.PluginRoot; -import net.emustudio.emulib.plugins.compiler.AbstractCompiler; -import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; -import net.emustudio.emulib.plugins.compiler.SourceFileExtension; -import net.emustudio.emulib.plugins.memory.MemoryContext; -import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.ContextNotFoundException; -import net.emustudio.emulib.runtime.InvalidContextException; -import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.tree.Program; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.FileReader; -import java.io.Reader; -import java.util.*; - -@PluginRoot( - type = PLUGIN_TYPE.COMPILER, - title = "Zilog Z80 Assembler" -) -@SuppressWarnings("unused") -public class CompilerImpl extends AbstractCompiler { - private final static Logger LOGGER = LoggerFactory.getLogger(CompilerImpl.class); - - private final static List SOURCE_FILE_EXTENSIONS = List.of( - new SourceFileExtension("asm", "Z80 assembler source") - ); - - private final LexerImpl lexer; - private final ParserImpl parser; - private MemoryContext memory; - int programLocation; - - public CompilerImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { - super(pluginID, applicationApi, settings); - - lexer = new LexerImpl(null); - parser = new ParserImpl(lexer, this); - } - - @SuppressWarnings("unchecked") - @Override - public void initialize() { - Optional.ofNullable(applicationApi.getContextPool()).ifPresent(pool -> { - try { - memory = pool.getMemoryContext(pluginID, MemoryContext.class); - if (memory.getDataType() != Short.class) { - throw new InvalidContextException( - "Unexpected memory cell type. Expected Short but was: " + memory.getDataType() - ); - } - } catch (ContextNotFoundException | InvalidContextException e) { - LOGGER.warn("Memory is not available", e); - } - }); - } - - @Override - public boolean compile(String inputFileName, String outputFileName) { - try { - notifyCompileStart(); - IntelHEX hex = compileToHex(inputFileName); - - hex.generate(outputFileName); - programLocation = hex.getProgramLocation(); - notifyInfo("Compile was successful.\nOutput: " + outputFileName); - - if (memory != null) { - hex.loadIntoMemory(memory); - notifyInfo("Compiled file was loaded into operating memory."); - } else { - notifyWarning("Memory is not available."); - } - - notifyCompileFinish(); - return true; - } catch (Exception e) { - LOGGER.trace("Compilation error", e); - notifyError("Compilation error: " + e.getMessage()); - notifyCompileFinish(); - return false; - } - } - - @Override - public boolean compile(String inputFileName) { - int i = inputFileName.lastIndexOf(".asm"); - - String outputFileName = inputFileName; - if (i >= 0) { - outputFileName = outputFileName.substring(0, i); - } - outputFileName += ".hex"; - return compile(inputFileName, outputFileName); - } - - @Override - public String getVersion() { - return getResourceBundle().map(b -> b.getString("version")).orElse("(unknown)"); - } - - @Override - public String getCopyright() { - return getResourceBundle().map(b -> b.getString("copyright")).orElse("(unknown)"); - } - - @Override - public String getDescription() { - return "Assembler targeting Z80 processor."; - } - - @Override - public LexicalAnalyzer getLexer(Reader in) { - return new LexerImpl(in); - } - - @Override - public List getSourceFileExtensions() { - return SOURCE_FILE_EXTENSIONS; - } - - @Override - public int getProgramLocation() { - return programLocation; - } - - - private IntelHEX compileToHex(String inputFileName) throws Exception { - Objects.requireNonNull(inputFileName); - - notifyInfo(getTitle() + ", version " + getVersion()); - - Object parsedProgram; - IntelHEX hex = new IntelHEX(); - - try (Reader reader = new FileReader(inputFileName)) { - lexer.reset(reader, 0, 0, 0); - parser.reset(); - parsedProgram = parser.parse().value; - - if (parsedProgram == null) { - throw new Exception("Unexpected end of file"); - } - if (parser.hasSyntaxErrors()) { - throw new Exception("One or more errors has been found, cannot continue."); - } - - Program stat = (Program) parsedProgram; - Namespace env = new Namespace(inputFileName); - stat.pass1(env); // create symbol table - stat.pass2(0); // try to evaluate all expressions + compute relative addresses - while (stat.pass3(env)) { - // don't worry about deadlock - } - if (env.getPassNeedCount() != 0) { - throw new Exception("Could not evaluate: " + env.getPassNeedView()); - } - stat.pass4(hex, env); - return hex; - } - } - - private Optional getResourceBundle() { - try { - return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.compiler.asZ80.version")); - } catch (MissingResourceException e) { - return Optional.empty(); - } - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java new file mode 100644 index 000000000..e4bdf7f57 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java @@ -0,0 +1,214 @@ +package net.emustudio.plugins.compiler.asZ80; + +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; +import net.emustudio.emulib.plugins.compiler.Token; +import org.antlr.v4.runtime.CharStreams; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Objects; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Lexer.*; + +public class LexicalAnalyzerImpl implements LexicalAnalyzer { + private final AsZ80Lexer lexer; + private static final int[] tokenMap = new int[AsZ80Lexer.EOL + 1]; + + static { + tokenMap[COMMENT] = Token.COMMENT; + tokenMap[EOL] = Token.WHITESPACE; + tokenMap[WS] = Token.WHITESPACE; + tokenMap[OPCODE_ADC] = Token.RESERVED; + tokenMap[OPCODE_ADD] = Token.RESERVED; + tokenMap[OPCODE_BIT] = Token.RESERVED; + tokenMap[OPCODE_CALL] = Token.RESERVED; + tokenMap[OPCODE_CCF] = Token.RESERVED; + tokenMap[OPCODE_CP] = Token.RESERVED; + tokenMap[OPCODE_CPD] = Token.RESERVED; + tokenMap[OPCODE_CPDR] = Token.RESERVED; + tokenMap[OPCODE_CPI] = Token.RESERVED; + tokenMap[OPCODE_CPIR] = Token.RESERVED; + tokenMap[OPCODE_CPL] = Token.RESERVED; + tokenMap[OPCODE_DAA] = Token.RESERVED; + tokenMap[OPCODE_DEC] = Token.RESERVED; + tokenMap[OPCODE_DI] = Token.RESERVED; + tokenMap[OPCODE_DJNZ] = Token.RESERVED; + tokenMap[OPCODE_EI] = Token.RESERVED; + tokenMap[OPCODE_EX] = Token.RESERVED; + tokenMap[OPCODE_EXX] = Token.RESERVED; + tokenMap[OPCODE_HALT] = Token.RESERVED; + tokenMap[OPCODE_IM] = Token.RESERVED; + tokenMap[OPCODE_IN] = Token.RESERVED; + tokenMap[OPCODE_INC] = Token.RESERVED; + tokenMap[OPCODE_IND] = Token.RESERVED; + tokenMap[OPCODE_INDR] = Token.RESERVED; + tokenMap[OPCODE_INI] = Token.RESERVED; + tokenMap[OPCODE_INIR] = Token.RESERVED; + tokenMap[OPCODE_JP] = Token.RESERVED; + tokenMap[OPCODE_JR] = Token.RESERVED; + tokenMap[OPCODE_LD] = Token.RESERVED; + tokenMap[OPCODE_LDD] = Token.RESERVED; + tokenMap[OPCODE_LDDR] = Token.RESERVED; + tokenMap[OPCODE_LDI] = Token.RESERVED; + tokenMap[OPCODE_LDIR] = Token.RESERVED; + tokenMap[OPCODE_NEG] = Token.RESERVED; + tokenMap[OPCODE_NOP] = Token.RESERVED; + tokenMap[OPCODE_OR] = Token.RESERVED; + tokenMap[OPCODE_OTDR] = Token.RESERVED; + tokenMap[OPCODE_OTIR] = Token.RESERVED; + tokenMap[OPCODE_OUT] = Token.RESERVED; + tokenMap[OPCODE_OUTD] = Token.RESERVED; + tokenMap[OPCODE_OUTI] = Token.RESERVED; + tokenMap[OPCODE_POP] = Token.RESERVED; + tokenMap[OPCODE_PUSH] = Token.RESERVED; + tokenMap[OPCODE_RES] = Token.RESERVED; + tokenMap[OPCODE_RET] = Token.RESERVED; + tokenMap[OPCODE_RETI] = Token.RESERVED; + tokenMap[OPCODE_RETN] = Token.RESERVED; + tokenMap[OPCODE_RL] = Token.RESERVED; + tokenMap[OPCODE_RLA] = Token.RESERVED; + tokenMap[OPCODE_RLC] = Token.RESERVED; + tokenMap[OPCODE_RLCA] = Token.RESERVED; + tokenMap[OPCODE_RLD] = Token.RESERVED; + tokenMap[OPCODE_RR] = Token.RESERVED; + tokenMap[OPCODE_RRA] = Token.RESERVED; + tokenMap[OPCODE_RRC] = Token.RESERVED; + tokenMap[OPCODE_RRCA] = Token.RESERVED; + tokenMap[OPCODE_RRD] = Token.RESERVED; + tokenMap[OPCODE_RST] = Token.RESERVED; + tokenMap[OPCODE_SBC] = Token.RESERVED; + tokenMap[OPCODE_SCF] = Token.RESERVED; + tokenMap[OPCODE_SET] = Token.RESERVED; + tokenMap[OPCODE_SLA] = Token.RESERVED; + tokenMap[OPCODE_SRA] = Token.RESERVED; + tokenMap[OPCODE_SLL] = Token.RESERVED; + tokenMap[OPCODE_SRL] = Token.RESERVED; + tokenMap[OPCODE_SUB] = Token.RESERVED; + tokenMap[OPCODE_XOR] = Token.RESERVED; + tokenMap[COND_C] = Token.RESERVED; + tokenMap[COND_NC] = Token.RESERVED; + tokenMap[COND_Z] = Token.RESERVED; + tokenMap[COND_NZ] = Token.RESERVED; + tokenMap[COND_M] = Token.RESERVED; + tokenMap[COND_P] = Token.RESERVED; + tokenMap[COND_PE] = Token.RESERVED; + tokenMap[COND_PO] = Token.RESERVED; + tokenMap[COND_WS] = Token.RESERVED; + + tokenMap[PREP_ORG] = Token.PREPROCESSOR; + tokenMap[PREP_EQU] = Token.PREPROCESSOR; + tokenMap[PREP_SET] = Token.PREPROCESSOR; + tokenMap[PREP_INCLUDE] = Token.PREPROCESSOR; + tokenMap[PREP_IF] = Token.PREPROCESSOR; + tokenMap[PREP_ENDIF] = Token.PREPROCESSOR; + tokenMap[PREP_MACRO] = Token.PREPROCESSOR; + tokenMap[PREP_ENDM] = Token.PREPROCESSOR; + tokenMap[PREP_DB] = Token.PREPROCESSOR; + tokenMap[PREP_DW] = Token.PREPROCESSOR; + tokenMap[PREP_DS] = Token.PREPROCESSOR; + tokenMap[PREP_ADDR] = Token.PREPROCESSOR; + + tokenMap[REG_A] = Token.REGISTER; + tokenMap[REG_B] = Token.REGISTER; + tokenMap[REG_C] = Token.REGISTER; + tokenMap[REG_D] = Token.REGISTER; + tokenMap[REG_E] = Token.REGISTER; + tokenMap[REG_H] = Token.REGISTER; + tokenMap[REG_L] = Token.REGISTER; + tokenMap[REG_IX] = Token.REGISTER; + tokenMap[REG_IY] = Token.REGISTER; + tokenMap[REG_SP] = Token.REGISTER; + tokenMap[REG_HL] = Token.REGISTER; + tokenMap[REG_DE] = Token.REGISTER; + tokenMap[REG_BC] = Token.REGISTER; + tokenMap[REG_IXH] = Token.REGISTER; + tokenMap[REG_IXL] = Token.REGISTER; + tokenMap[REG_IYH] = Token.REGISTER; + tokenMap[REG_IYL] = Token.REGISTER; + tokenMap[REG_AF] = Token.REGISTER; + tokenMap[REG_AFF] = Token.REGISTER; + tokenMap[REG_I] = Token.REGISTER; + tokenMap[REG_R] = Token.REGISTER; + + tokenMap[SEP_LPAR] = Token.SEPARATOR; + tokenMap[SEP_RPAR] = Token.SEPARATOR; + tokenMap[SEP_COMMA] = Token.SEPARATOR; + + tokenMap[OP_ADD] = Token.OPERATOR; + tokenMap[OP_SUBTRACT] = Token.OPERATOR; + tokenMap[OP_MULTIPLY] = Token.OPERATOR; + tokenMap[OP_DIVIDE] = Token.OPERATOR; + tokenMap[OP_EQUAL] = Token.OPERATOR; + tokenMap[OP_MOD] = Token.OPERATOR; + tokenMap[OP_MOD_2] = Token.OPERATOR; + tokenMap[OP_SHR] = Token.OPERATOR; + tokenMap[OP_SHR_2] = Token.OPERATOR; + tokenMap[OP_SHL] = Token.OPERATOR; + tokenMap[OP_SHL_2] = Token.OPERATOR; + tokenMap[OP_NOT] = Token.OPERATOR; + tokenMap[OP_NOT_2] = Token.OPERATOR; + tokenMap[OP_AND] = Token.OPERATOR; + tokenMap[OP_AND_2] = Token.OPERATOR; + tokenMap[OP_OR] = Token.OPERATOR; + tokenMap[OP_OR_2] = Token.OPERATOR; + tokenMap[OP_XOR] = Token.OPERATOR; + tokenMap[OP_XOR_2] = Token.OPERATOR; + tokenMap[OP_LT] = Token.OPERATOR; + tokenMap[OP_LTE] = Token.OPERATOR; + tokenMap[OP_GT] = Token.OPERATOR; + tokenMap[OP_GTE] = Token.OPERATOR; + + tokenMap[LIT_NUMBER] =Token.LITERAL; + tokenMap[LIT_HEXNUMBER_1] =Token.LITERAL; + tokenMap[LIT_HEXNUMBER_2] =Token.LITERAL; + tokenMap[LIT_OCTNUMBER] =Token.LITERAL; + tokenMap[LIT_BINNUMBER] =Token.LITERAL; + tokenMap[LIT_STRING_1] =Token.LITERAL; + tokenMap[LIT_STRING_2] =Token.LITERAL; + + tokenMap[ID_IDENTIFIER] = Token.IDENTIFIER; + tokenMap[ID_LABEL] = Token.IDENTIFIER; + + tokenMap[ERROR] = Token.ERROR; + } + + + public LexicalAnalyzerImpl(AsZ80Lexer lexer) { + this.lexer = Objects.requireNonNull(lexer); + } + + @Override + public Token nextToken() { + org.antlr.v4.runtime.Token token = lexer.nextToken(); + return new Token() { + @Override + public int getType() { + return convertLexerTokenType(token.getType()); + } + + @Override + public int getOffset() { + return token.getStartIndex(); + } + + @Override + public String getText() { + return token.getText(); + } + }; + } + + @Override + public boolean isAtEOF() { + return lexer._hitEOF; + } + + @Override + public void reset(InputStream inputStream) throws IOException { + lexer.setInputStream(CharStreams.fromStream(inputStream)); + } + + private int convertLexerTokenType(int tokenType) { + return tokenMap[tokenType]; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Namespace.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Namespace.java deleted file mode 100644 index fdbc220eb..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Namespace.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80; - -import net.emustudio.plugins.compiler.asZ80.tree.*; - -import java.io.File; -import java.util.*; - -/** - * Namespace is used in compile time. - *

- * It is a compile environment. It stores needed values for all compiler passes. - * sets, macros and equs are pseudo-instructions that aren't added to symbol table - * in pass1. This means that if eg. equ wasn't defined before first use error - * comes. - */ -public class Namespace { - private final Map labels = new HashMap<>(); - private final Map macros = new HashMap<>(); - private final Map constants = new HashMap<>(); - private final Map variables = new HashMap<>(); - private final List passNeed = new ArrayList<>(); - private final File inputFile; - - public Namespace(String inputFileName) { - this.inputFile = new File(inputFileName); - } - - public File getInputFile() { - return inputFile; - } - - private boolean identifierExists(String name) { - Objects.requireNonNull(name); - - return labels.containsKey(name) - || macros.containsKey(name) - || constants.containsKey(name) - || variables.containsKey(name); - } - - private boolean addIdentifier(Map identifiers, T identifier, String name) { - if (identifiers.get(name) == identifier) { - return true; - } else if (identifierExists(name)) { - return false; - } - identifiers.put(name, identifier); - return true; - } - - public boolean addLabel(Label label) { - return addIdentifier(labels, label, label.getName()); - } - - public Label getLabel(String name) { - return labels.get(name); - } - - public boolean addMacro(PseudoMACRO macro) { - return addIdentifier(macros, macro, macro.getName()); - } - - public PseudoMACRO getMacro(String name) { - return macros.get(name); - } - - public boolean addConstant(PseudoEQU constant) { - return addIdentifier(constants, constant, constant.getName()); - } - - public PseudoEQU getConstant(String name) { - return constants.get(name); - } - - public boolean setVariable(PseudoVAR variable) { - if (identifierExists(variable.getName()) && !variables.containsKey(variable.getName())) { - return false; - } - variables.put(variable.getName(), variable); - return true; - } - - public PseudoVAR getVariable(String name) { - return variables.get(name); - } - - // it is used in a macro block - public void removeAllDefinitions(String name) { - labels.remove(name); - macros.remove(name); - constants.remove(name); - variables.remove(name); - } - - public void copyTo(Namespace env) { - labels.values().forEach(env::addLabel); - macros.values().forEach(env::addMacro); - constants.values().forEach(env::addConstant); - variables.values().forEach(env::setVariable); - } - - public void addPassNeed(Row n) { - passNeed.add(n); - } - - public int getPassNeedCount() { - return passNeed.size(); - } - - public List getPassNeedView() { - return Collections.unmodifiableList(passNeed); - } - - public Row getPassNeed(int index) { - return passNeed.get(index); - } - - public void removePassNeed(int index) { - passNeed.remove(index); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParserErrorListener.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParserErrorListener.java new file mode 100644 index 000000000..8d4b1d65c --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParserErrorListener.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.compiler.asZ80; + +import net.emustudio.plugins.compiler.asZ80.exceptions.SyntaxErrorException; +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; + +class ParserErrorListener extends BaseErrorListener { + // TODO: parse message expected tokens to token categories + @Override + public void syntaxError( + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { + + if (e == null) { + throw new SyntaxErrorException(line, charPositionInLine, msg); + } else { + throw new SyntaxErrorException(line, charPositionInLine, msg, e); + } + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParsingUtils.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParsingUtils.java new file mode 100644 index 000000000..5f81beddb --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParsingUtils.java @@ -0,0 +1,57 @@ +package net.emustudio.plugins.compiler.asZ80; + +import org.antlr.v4.runtime.Token; + +import java.util.Locale; + +public class ParsingUtils { + + public static String parseLitString(Token token) { + // LIT_STRING_1: '\'' ~[']* '\''; + // LIT_STRING_2: '"' ~["]* '"'; + String text = token.getText(); + return text.substring(1, text.length() - 1); + } + + public static int parseLitHex1(Token token) { + // LIT_HEXNUMBER_1: [\-]? '0' X [0-9a-fA-F]+; + return Integer.decode(token.getText()); + } + + public static int parseLitHex2(Token token) { + // LIT_HEXNUMBER_2: [\-]? [0-9a-fA-F]+ H; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 16); + } + + public static int parseLitOct(Token token) { + // LIT_OCTNUMBER: [\-]? [0-7]+ [oOqQ]; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 8); + } + + public static int parseLitDec(Token token) { + // LIT_NUMBER: [\-]? [0-9]+ D? + String rawText = token.getText(); + if (rawText.endsWith("d") || rawText.endsWith("D")) { + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 10); + } else { + return Integer.parseInt(rawText, 10); + } + } + + public static int parseLitBin(Token token) { + // LIT_BINNUMBER: [01]+ B; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 2); + } + + public static String parseLabel(Token token) { + String rawText = token.getText(); + return rawText.substring(0, rawText.length() - 1); + } + + public static String normalizeId(String id) { + return id.toLowerCase(Locale.ENGLISH); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Runner.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Runner.java index 0653f90dc..b3d70f084 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Runner.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Runner.java @@ -38,7 +38,7 @@ public static void main(String... args) { printHelp(); return; } else if (arg.equals("--version") || arg.equals("-v")) { - System.out.println(new CompilerImpl(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE).getVersion()); + System.out.println(new AssemblerZ80(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE).getVersion()); return; } else { break; @@ -59,7 +59,7 @@ public static void main(String... args) { outputFile += ".hex"; } - CompilerImpl compiler = new CompilerImpl(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE); + AssemblerZ80 compiler = new AssemblerZ80(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE); compiler.addCompilerListener(new CompilerListener() { @Override public void onStart() { @@ -73,7 +73,6 @@ public void onMessage(CompilerMessage message) { @Override public void onFinish() { System.err.println("Compilation finished"); - } }); try { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/TokenImpl.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/TokenImpl.java deleted file mode 100644 index 2629408e0..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/TokenImpl.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80; - -import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol; -import java_cup.runtime.ComplexSymbolFactory.Location; -import net.emustudio.emulib.plugins.compiler.Token; - -public class TokenImpl extends ComplexSymbol implements Token, Symbols { - public final static int ERROR_DECIMAL_SIZE = 0xA01; - public final static int ERROR_UNCLOSED_CHAR = 0xA02; - public final static int ERROR_UNCLOSED_STRING = 0xA03; - - private final int category; - private final int lexerState; - - public TokenImpl(int id, int category, int lexerState, String text, Location left, Location right) { - super(text, id, left, right); - this.category = category; - this.lexerState = lexerState; - } - - public TokenImpl(int id, int category, int lexerState, String text, Location left, Location right, Object value) { - super(text, id, left, right, value); - this.category = category; - this.lexerState = lexerState; - } - - - @Override - public int getID() { - return super.sym; - } - - @Override - public int getType() { - return this.category; - } - - @Override - public String getText() { - return getName(); - } - - @Override - public String getErrorString() { - switch (super.sym) { - case ERROR_DECIMAL_SIZE: - return "Literal has too big size (max. is 65535)"; - case ERROR_UNCLOSED_CHAR: - return "Char is not closed with single quote (')"; - case ERROR_UNCLOSED_STRING: - return "String is not closed with single quote (')"; - case ERROR: - return "Unknown token"; - } - return ""; - } - - @Override - public int getLine() { - return getLeft().getLine(); - } - - @Override - public int getColumn() { - return getLeft().getColumn(); - } - - @Override - public int getOffset() { - return getLeft().getOffset(); - } - - @Override - public int getLength() { - return getRight().getOffset() - getLeft().getOffset(); - } - - @Override - public int getLexerState() { - return lexerState; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Evaluated.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Evaluated.java new file mode 100644 index 000000000..43b20df07 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Evaluated.java @@ -0,0 +1,37 @@ +package net.emustudio.plugins.compiler.asZ80.ast; + +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +public class Evaluated extends Node { + public final int value; + + public Evaluated(int line, int column, int value) { + super(line, column); + this.value = value; + } + + @Override + protected Node mkCopy() { + return new Evaluated(line, column, value); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + Evaluated evaluated = (Evaluated) o; + return value == evaluated.value; + } + + @Override + protected String toStringShallow() { + return "Evaluated(" + value + ")"; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java new file mode 100644 index 000000000..216d84faa --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java @@ -0,0 +1,45 @@ +package net.emustudio.plugins.compiler.asZ80.ast; + +import net.emustudio.plugins.compiler.asZ80.CompileError; + +import java.util.*; + +public class NameSpace { + private final List errors = new ArrayList<>(); + private final Map> definitions = new HashMap<>(); + + public void error(CompileError error) { + errors.add(Objects.requireNonNull(error)); + } + + public boolean hasError(int errorCode) { + return errors.stream().anyMatch(e -> e.errorCode == errorCode); + } + + public boolean hasNoErrors() { + return errors.isEmpty(); + } + + public void put(String id, Optional value) { + definitions.put(id, value); + } + + public void remove(String id) { + definitions.remove(id); + } + + public Optional get(String id) { + return Optional.ofNullable(definitions.get(id)).flatMap(e -> e); + } + + public List getErrors() { + return Collections.unmodifiableList(errors); + } + + @Override + public String toString() { + return "NameSpace{" + + "errors=" + errors + + '}'; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java new file mode 100644 index 000000000..b17662309 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java @@ -0,0 +1,142 @@ +package net.emustudio.plugins.compiler.asZ80.ast; + +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public abstract class Node { + protected Node parent; + protected final List children = new ArrayList<>(); + public final int line; + public final int column; + + private int address; + + public Node(int line, int column) { + this.line = line; + this.column = column; + } + + public void addChildFirst(Node node) { + node.parent = this; + children.add(0, node); + } + + public Node addChild(Node node) { + node.parent = this; + children.add(node); + return this; + } + + public void addChildAt(int index, Node node) { + node.parent = this; + children.add(index, node); + } + + public void addChildren(List nodes) { + for (Node node : nodes) { + node.parent = this; + } + children.addAll(nodes); + } + + public List getChildren() { + return List.copyOf(children); + } + + public int getChildrenCount() { + return children.size(); + } + + public Optional collectChild(Class cl) { + for (Node child : children) { + if (cl.isInstance(child)) { + return Optional.of((T) child); + } + } + return Optional.empty(); + } + + public Optional getParent() { + return Optional.ofNullable(parent); + } + + public Node getChild(int index) { + return children.get(index); + } + + public void removeChild(Node node) { + node.parent = null; + children.remove(node); + } + + public Optional remove() { + Optional parent = getParent(); + parent.ifPresent(p -> p.removeChild(this)); + return parent; + } + + public void exclude() { + Optional parent = getParent(); + parent.ifPresent(p -> { + int index = p.getChildren().indexOf(this); + p.removeChild(this); + for (Node child : getChildren()) { + p.addChildAt(index++, child); + } + }); + } + + public int getAddress() { + return address; + } + + public void setAddress(int address) { + this.address = address; + } + + public Optional eval(Optional currentAddress, NameSpace env) { + return Optional.empty(); + } + + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public String toString() { + return toString(0); + } + + private String toString(int indent) { + String spaces = new String(new char[indent]).replace("\0", " "); + StringBuilder builder = new StringBuilder(spaces); + builder.append(address).append("> ").append(toStringShallow()); + for (Node child : children) { + builder.append("\n").append(child.toString(indent + 2)); + } + return builder.toString(); + } + + protected String toStringShallow() { + return getClass().getSimpleName(); + } + + protected abstract Node mkCopy(); + + public Node copy() { + Node copied = mkCopy(); + for (Node child : children) { + copied.addChild(child.copy()); + } + return copied; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + return !(o == null || getClass() != o.getClass()); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Program.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Program.java new file mode 100644 index 000000000..bc3e42b1c --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Program.java @@ -0,0 +1,49 @@ +package net.emustudio.plugins.compiler.asZ80.ast; + +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +import java.util.Objects; +import java.util.Optional; + +public class Program extends Node { + private final NameSpace env; + private String filename; + + public Program(int line, int column, NameSpace env) { + super(line, column); + this.env = Objects.requireNonNull(env); + } + + public Program(NameSpace env) { + this(0, 0, env); + } + + public Program() { + this(new NameSpace()); + } + + public void setFileName(String filename) { + this.filename = filename; + } + + public Optional getFileName() { + return Optional.ofNullable(filename); + } + + + public NameSpace env() { + return env; + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + Program program = new Program(line, column, env); + program.setFileName(filename); + return program; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDB.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDB.java new file mode 100644 index 000000000..513686710 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDB.java @@ -0,0 +1,22 @@ +package net.emustudio.plugins.compiler.asZ80.ast.data; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +public class DataDB extends Node { + + public DataDB(int line, int column) { + super(line, column); + // child is string, expr or 8-bit instruction + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new DataDB(line, column); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDS.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDS.java new file mode 100644 index 000000000..f7f2f8040 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDS.java @@ -0,0 +1,24 @@ +package net.emustudio.plugins.compiler.asZ80.ast.data; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +/** + * "Data Store" node. Inserts some space. + * Child is an expression which must not use forward references and must not be negative. + */ +public class DataDS extends Node { + public DataDS(int line, int column) { + super(line, column); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new DataDS(line, column); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDW.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDW.java new file mode 100644 index 000000000..a9bb69dd9 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/data/DataDW.java @@ -0,0 +1,22 @@ +package net.emustudio.plugins.compiler.asZ80.ast.data; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +public class DataDW extends Node { + + public DataDW(int line, int column) { + super(line, column); + // child is expr 2 byte + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new DataDW(line, column); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprCurrentAddress.java new file mode 100644 index 000000000..a856afa81 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprCurrentAddress.java @@ -0,0 +1,30 @@ +package net.emustudio.plugins.compiler.asZ80.ast.expr; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.NameSpace; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +import java.util.Optional; + +public class ExprCurrentAddress extends Node { + + public ExprCurrentAddress(int line, int column) { + super(line, column); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new ExprCurrentAddress(line, column); + } + + @Override + public Optional eval(Optional currentAddress, NameSpace env) { + return currentAddress.map(addr -> new Evaluated(line, column, addr)); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprId.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprId.java new file mode 100644 index 000000000..f3bfd1762 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprId.java @@ -0,0 +1,54 @@ +package net.emustudio.plugins.compiler.asZ80.ast.expr; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.NameSpace; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; +import java.util.Optional; + +import static net.emustudio.plugins.compiler.asZ80.ParsingUtils.normalizeId; + +public class ExprId extends Node { + public final String id; + + public ExprId(int line, int column, String id) { + super(line, column); + this.id = Objects.requireNonNull(id); + } + + public ExprId(Token id) { + this(id.getLine(), id.getCharPositionInLine(), id.getText()); + } + + @Override + public Optional eval(Optional currentAddress, NameSpace env) { + return env.get(normalizeId(id)); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "ExprId(" + id + ")"; + } + + @Override + protected Node mkCopy() { + return new ExprId(line, column, id); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ExprId exprId = (ExprId) o; + return Objects.equals(id, exprId.id); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java new file mode 100644 index 000000000..a16d23061 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java @@ -0,0 +1,97 @@ +package net.emustudio.plugins.compiler.asZ80.ast.expr; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.NameSpace; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.BiFunction; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +public class ExprInfix extends Node { + private final static Map> infixOps = new HashMap<>(); + private final BiFunction operation; + public final int operationCode; + + static { + infixOps.put(OP_ADD, Integer::sum); + infixOps.put(OP_SUBTRACT, (x, y) -> x - y); + infixOps.put(OP_DIVIDE, (x, y) -> x / y); // can throw! + infixOps.put(OP_MULTIPLY, (x, y) -> x * y); + infixOps.put(OP_MOD, (x, y) -> x % y); + infixOps.put(OP_MOD_2, (x, y) -> x % y); + infixOps.put(OP_AND, (x, y) -> x & y); + infixOps.put(OP_AND_2, (x, y) -> x & y); + infixOps.put(OP_OR, (x, y) -> x | y); + infixOps.put(OP_OR_2, (x, y) -> x | y); + infixOps.put(OP_XOR, (x, y) -> x ^ y); + infixOps.put(OP_XOR_2, (x, y) -> x ^ y); + infixOps.put(OP_SHL, (x, y) -> x << y); + infixOps.put(OP_SHL_2, (x, y) -> x << y); + infixOps.put(OP_SHR, (x, y) -> x >>> y); + infixOps.put(OP_SHR_2, (x, y) -> x >>> y); + infixOps.put(OP_EQUAL, (x, y) -> ((x.equals(y)) ? 1 : 0)); + infixOps.put(OP_LT, (x, y) -> (x < y) ? 1 : 0); + infixOps.put(OP_LTE, (x, y) -> (x <= y) ? 1 : 0); + infixOps.put(OP_GT, (x, y) -> (x > y) ? 1 : 0); + infixOps.put(OP_GTE, (x, y) -> (x >= y) ? 1 : 0); + } + + public ExprInfix(int line, int column, int op) { + super(line, column); + this.operationCode = op; + this.operation = Objects.requireNonNull(infixOps.get(op), "Unknown infix operation"); + // children are: left, right + } + + public ExprInfix(Token op) { + this(op.getLine(), op.getCharPositionInLine(), op.getType()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public Optional eval(Optional currentAddress, NameSpace env) { + Node leftChild = getChild(0); + Node rightChild = getChild(1); + + Optional left = leftChild.eval(currentAddress, env); + Optional right = rightChild.eval(currentAddress, env); + + if (left.isPresent() && right.isPresent()) { + int l = left.get().value; + int r = right.get().value; + return Optional.of(new Evaluated(line, column, operation.apply(l, r))); + } + + return Optional.empty(); + } + + @Override + protected String toStringShallow() { + return "ExprInfix(" + operationCode + ")"; + } + + @Override + protected Node mkCopy() { + return new ExprInfix(line, column, operationCode); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + ExprInfix exprInfix = (ExprInfix) o; + return operationCode == exprInfix.operationCode; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprNumber.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprNumber.java new file mode 100644 index 000000000..1e504117d --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprNumber.java @@ -0,0 +1,52 @@ +package net.emustudio.plugins.compiler.asZ80.ast.expr; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.NameSpace; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Optional; +import java.util.function.Function; + +public class ExprNumber extends Node { + public final int number; + + public ExprNumber(int line, int column, int number) { + super(line, column); + this.number = number; + } + + public ExprNumber(Token number, Function parser) { + this(number.getLine(), number.getCharPositionInLine(), parser.apply(number)); + } + + @Override + public Optional eval(Optional currentAddress, NameSpace env) { + return Optional.of(new Evaluated(line, column, number)); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "ExprNumber(" + number + ")"; + } + + @Override + protected Node mkCopy() { + return new ExprNumber(line, column, number); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ExprNumber that = (ExprNumber) o; + return number == that.number; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprString.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprString.java new file mode 100644 index 000000000..40f39d9e0 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprString.java @@ -0,0 +1,46 @@ +package net.emustudio.plugins.compiler.asZ80.ast.expr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +import static net.emustudio.plugins.compiler.asZ80.ParsingUtils.parseLitString; + +public class ExprString extends Node { + public final String string; + + public ExprString(int line, int column, String string) { + super(line, column); + this.string = Objects.requireNonNull(string); + } + + public ExprString(Token str) { + this(str.getLine(), str.getCharPositionInLine(), parseLitString(str)); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new ExprString(line, column, string); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + ExprString that = (ExprString) o; + return Objects.equals(string, that.string); + } + + @Override + protected String toStringShallow() { + return "ExprString(" + string + ")"; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprUnary.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprUnary.java new file mode 100644 index 000000000..b44b47d0d --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprUnary.java @@ -0,0 +1,67 @@ +package net.emustudio.plugins.compiler.asZ80.ast.expr; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.NameSpace; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +public class ExprUnary extends Node { + private final static Map> unaryOps = Map.of( + OP_ADD, x -> x, + OP_SUBTRACT, x -> -x, + OP_NOT, x -> ~x, + OP_NOT_2, x -> ~x + ); + private final Function operation; + public final int operationCode; + + public ExprUnary(int line, int column, int op) { + super(line, column); + this.operationCode = op; + this.operation = Objects.requireNonNull(unaryOps.get(op), "Unknown unary operation"); + // child is expr + } + + public ExprUnary(Token op) { + this(op.getLine(), op.getCharPositionInLine(), op.getType()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public Optional eval(Optional currentAddress, NameSpace env) { + return getChild(0) + .eval(currentAddress, env) + .map(childEval -> new Evaluated(line, column, operation.apply(childEval.value))); + } + + @Override + protected String toStringShallow() { + return "ExprUnary(" + operationCode + ")"; + } + + @Override + protected Node mkCopy() { + return new ExprUnary(line, column, operationCode); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + ExprUnary exprUnary = (ExprUnary) o; + return operationCode == exprUnary.operationCode; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrExpr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrExpr.java new file mode 100644 index 000000000..7cde73c23 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrExpr.java @@ -0,0 +1,117 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.*; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +public class InstrExpr extends Node { + public final int opcode; + private final static Set twoBytes = new HashSet<>(); + private final static Map opcodes = new HashMap<>(); + + static { + twoBytes.add(OPCODE_ADI); + twoBytes.add(OPCODE_ACI); + twoBytes.add(OPCODE_SUI); + twoBytes.add(OPCODE_SBI); + twoBytes.add(OPCODE_ANI); + twoBytes.add(OPCODE_ORI); + twoBytes.add(OPCODE_XRI); + twoBytes.add(OPCODE_CPI); + twoBytes.add(OPCODE_IN); + twoBytes.add(OPCODE_OUT); + + opcodes.put(OPCODE_LDA, 0x3A); + opcodes.put(OPCODE_STA, 0x32); + opcodes.put(OPCODE_LHLD, 0x2A); + opcodes.put(OPCODE_SHLD, 0x22); + opcodes.put(OPCODE_ADI, 0xC6); + opcodes.put(OPCODE_ACI, 0xCE); + opcodes.put(OPCODE_SUI, 0xD6); + opcodes.put(OPCODE_SBI, 0xDE); + opcodes.put(OPCODE_ANI, 0xE6); + opcodes.put(OPCODE_ORI, 0xF6); + opcodes.put(OPCODE_XRI, 0xEE); + opcodes.put(OPCODE_CPI, 0xFE); + opcodes.put(OPCODE_JMP, 0xC3); + opcodes.put(OPCODE_JC, 0xDA); + opcodes.put(OPCODE_JNC, 0xD2); + opcodes.put(OPCODE_JZ, 0xCA); + opcodes.put(OPCODE_JNZ, 0xC2); + opcodes.put(OPCODE_JM, 0xFA); + opcodes.put(OPCODE_JP, 0xF2); + opcodes.put(OPCODE_JPE, 0xEA); + opcodes.put(OPCODE_JPO, 0xE2); + opcodes.put(OPCODE_CALL, 0xCD); + opcodes.put(OPCODE_CC, 0xDC); + opcodes.put(OPCODE_CZ, 0xCC); + opcodes.put(OPCODE_CNC, 0xD4); + opcodes.put(OPCODE_CNZ, 0xC4); + opcodes.put(OPCODE_CM, 0xFC); + opcodes.put(OPCODE_CP, 0xF4); + opcodes.put(OPCODE_CPE, 0xEC); + opcodes.put(OPCODE_CPO, 0xE4); + opcodes.put(OPCODE_IN, 0xDB); + opcodes.put(OPCODE_OUT, 0xD3); + opcodes.put(OPCODE_RST, 0xC7); + } + + public InstrExpr(int line, int column, int opcode) { + super(line, column); + this.opcode = opcode; + // child is expr + } + + public InstrExpr(Token opcode) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); + } + + public int getExprSizeBytes() { + if (opcode == OPCODE_RST) { + return 0; + } else if (twoBytes.contains(opcode)) { + return 1; + } + return 2; // address + } + + public Optional eval() { + byte result = (byte) (opcodes.get(opcode) & 0xFF); + if (opcode == OPCODE_RST) { + return collectChild(Evaluated.class) + .filter(e -> e.value >= 0 && e.value <= 7) + .map(e -> (byte) (result | (e.value << 3))); + } + + return Optional.of(result); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "InstrExpr(" + opcode + ")"; + } + + @Override + protected Node mkCopy() { + return new InstrExpr(line, column, opcode); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrExpr instrExpr = (InstrExpr) o; + return opcode == instrExpr.opcode; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNoArgs.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNoArgs.java new file mode 100644 index 000000000..704db9ac6 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNoArgs.java @@ -0,0 +1,80 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +public class InstrNoArgs extends Node { + private final static Map opcodes = new HashMap<>(); + public final int opcode; + + static { + opcodes.put(OPCODE_STC, 0x37); + opcodes.put(OPCODE_CMC, 0x3F); + opcodes.put(OPCODE_CMA, 0x2F); + opcodes.put(OPCODE_DAA, 0x27); + opcodes.put(OPCODE_NOP, 0); + opcodes.put(OPCODE_RLC, 7); + opcodes.put(OPCODE_RRC, 0xF); + opcodes.put(OPCODE_RAL, 0x17); + opcodes.put(OPCODE_RAR, 0x1F); + opcodes.put(OPCODE_XCHG, 0xEB); + opcodes.put(OPCODE_XTHL, 0xE3); + opcodes.put(OPCODE_SPHL, 0xF9); + opcodes.put(OPCODE_PCHL, 0xE9); + opcodes.put(OPCODE_RET, 0xC9); + opcodes.put(OPCODE_RC, 0xD8); + opcodes.put(OPCODE_RNC, 0xD0); + opcodes.put(OPCODE_RZ, 0xC8); + opcodes.put(OPCODE_RNZ, 0xC0); + opcodes.put(OPCODE_RM, 0xF8); + opcodes.put(OPCODE_RP, 0xF0); + opcodes.put(OPCODE_RPE, 0xE8); + opcodes.put(OPCODE_RPO, 0xE0); + opcodes.put(OPCODE_EI, 0xFB); + opcodes.put(OPCODE_DI, 0xF3); + opcodes.put(OPCODE_HLT, 0x76); + } + + public InstrNoArgs(int line, int column, int opcode) { + super(line, column); + this.opcode = opcode; + } + + public InstrNoArgs(Token opcode) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); + } + + public byte eval() { + return (byte) (opcodes.get(opcode) & 0xFF); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "InstrNoArgs(" + opcode + ")"; + } + + @Override + protected Node mkCopy() { + return new InstrNoArgs(line, column, opcode); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrNoArgs that = (InstrNoArgs) o; + return opcode == that.opcode; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrReg.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrReg.java new file mode 100644 index 000000000..770372b0a --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrReg.java @@ -0,0 +1,84 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +public class InstrReg extends Node { + private final static Map opcodes = new HashMap<>(); + public final static Map registers = new HashMap<>(); + public final int opcode; + public final int reg; + + static { + opcodes.put(OPCODE_INR, 4); + opcodes.put(OPCODE_DCR, 5); + opcodes.put(OPCODE_ADD, 0x80); + opcodes.put(OPCODE_ADC, 0x88); + opcodes.put(OPCODE_SUB, 0x90); + opcodes.put(OPCODE_SBB, 0x98); + opcodes.put(OPCODE_ANA, 0xA0); + opcodes.put(OPCODE_XRA, 0xA8); + opcodes.put(OPCODE_ORA, 0xB0); + opcodes.put(OPCODE_CMP, 0xB8); + + registers.put(REG_A, 7); + registers.put(REG_B, 0); + registers.put(REG_C, 1); + registers.put(REG_D, 2); + registers.put(REG_E, 3); + registers.put(REG_H, 4); + registers.put(REG_L, 5); + registers.put(REG_M, 6); + } + + public InstrReg(int line, int column, int opcode, int reg) { + super(line, column); + this.opcode = opcode; + this.reg = reg; + } + + public InstrReg(Token opcode, Token reg) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); + } + + public byte eval() { + int result = opcodes.get(opcode); + int register = registers.get(reg); + if (opcode == OPCODE_INR || opcode == OPCODE_DCR) { + return (byte) ((result | (register << 3)) & 0xFF); + } + return (byte) ((result | register) & 0xFF); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "InstrReg(" + opcode + "," + reg + ")"; + } + + @Override + protected Node mkCopy() { + return new InstrReg(line, column, opcode, reg); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrReg instrReg = (InstrReg) o; + + if (opcode != instrReg.opcode) return false; + return reg == instrReg.reg; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegExpr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegExpr.java new file mode 100644 index 000000000..8d2de6990 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegExpr.java @@ -0,0 +1,52 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +public class InstrRegExpr extends Node { + public final int opcode; // MVI only + public final int reg; + + public InstrRegExpr(int line, int column, int opcode, int reg) { + super(line, column); + this.opcode = opcode; + this.reg = reg; + // child is expr + } + + public InstrRegExpr(Token opcode, Token reg) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); + } + + public byte eval() { + int register = InstrReg.registers.get(reg); + return (byte) ((6 | (register << 3)) & 0xFF); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "InstrRegExpr(" + opcode + "," + reg + ")"; + } + + @Override + protected Node mkCopy() { + return new InstrRegExpr(line, column, opcode, reg); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrRegExpr that = (InstrRegExpr) o; + + if (opcode != that.opcode) return false; + return reg == that.reg; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPair.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPair.java new file mode 100644 index 000000000..b08f4f336 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPair.java @@ -0,0 +1,76 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +public class InstrRegPair extends Node { + private final static Map opcodes = new HashMap<>(); + public final static Map regpairs = new HashMap<>(); + + public final int opcode; + public final int regPair; + + static { + opcodes.put(OPCODE_STAX, 2); + opcodes.put(OPCODE_LDAX, 0xA); + opcodes.put(OPCODE_PUSH, 0xC5); + opcodes.put(OPCODE_POP, 0xC1); + opcodes.put(OPCODE_DAD, 9); + opcodes.put(OPCODE_INX, 3); + opcodes.put(OPCODE_DCX, 0xB); + + regpairs.put(REG_B, 0); + regpairs.put(REG_D, 1); + regpairs.put(REG_H, 2); + regpairs.put(REG_PSW, 3); + regpairs.put(REG_SP, 3); + } + + public InstrRegPair(int line, int column, int opcode, int regPair) { + super(line, column); + this.opcode = opcode; + this.regPair = regPair; + } + + public InstrRegPair(Token opcode, Token regPair) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); + } + + public byte eval() { + int result = opcodes.get(opcode); + int rp = regpairs.get(regPair); + return (byte) ((result | (rp << 4)) & 0xFF); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "InstrRegPair(" + opcode + "," + regPair + ")"; + } + + @Override + protected Node mkCopy() { + return new InstrRegPair(line, column, opcode, regPair); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrRegPair that = (InstrRegPair) o; + + if (opcode != that.opcode) return false; + return regPair == that.regPair; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPairExpr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPairExpr.java new file mode 100644 index 000000000..074b3b75e --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPairExpr.java @@ -0,0 +1,52 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +public class InstrRegPairExpr extends Node { + public final int opcode; + public final int regPair; + + public InstrRegPairExpr(int line, int column, int opcode, int regPair) { + super(line, column); + this.opcode = opcode; + this.regPair = regPair; + // child is expr + } + + public InstrRegPairExpr(Token opcode, Token regPair) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); + } + + public byte eval() { + int rp = InstrRegPair.regpairs.get(regPair); + return (byte) ((1 | (rp << 4)) & 0xFF); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "InstrRegPairExpr(" + opcode + "," + regPair + ")"; + } + + @Override + protected Node mkCopy() { + return new InstrRegPairExpr(line, column, opcode, regPair); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrRegPairExpr that = (InstrRegPairExpr) o; + + if (opcode != that.opcode) return false; + return regPair == that.regPair; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegReg.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegReg.java new file mode 100644 index 000000000..820103c62 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegReg.java @@ -0,0 +1,55 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +public class InstrRegReg extends Node { + public final int opcode; // MOV only + public final int srcReg; + public final int dstReg; + + public InstrRegReg(int line, int column, int opcode, int dst, int src) { + super(line, column); + this.opcode = opcode; + this.srcReg = src; + this.dstReg = dst; + } + + public InstrRegReg(Token opcode, Token dst, Token src) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), dst.getType(), src.getType()); + } + + public byte eval() { + int srcRegister = InstrReg.registers.get(srcReg); + int dstRegister = InstrReg.registers.get(dstReg); + return (byte)((0x40 | (dstRegister << 3) | (srcRegister)) & 0xFF); // TODO: mov M, M == HLT + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "InstrRegReg(" + opcode + ","+ dstReg +","+ srcReg +")"; + } + + @Override + protected Node mkCopy() { + return new InstrRegReg(line, column, opcode, dstReg, srcReg); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrRegReg that = (InstrRegReg) o; + + if (opcode != that.opcode) return false; + if (srcReg != that.srcReg) return false; + return dstReg == that.dstReg; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoEqu.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoEqu.java new file mode 100644 index 000000000..07409f22b --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoEqu.java @@ -0,0 +1,45 @@ +package net.emustudio.plugins.compiler.asZ80.ast.pseudo; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +public class PseudoEqu extends Node { + public final String id; + + public PseudoEqu(int line, int column, String id) { + super(line, column); + this.id = Objects.requireNonNull(id); + // expr is the only child + } + + public PseudoEqu(Token id) { + this(id.getLine(), id.getCharPositionInLine(), id.getText()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "PseudoEqu(" + id + ")"; + } + + @Override + protected Node mkCopy() { + return new PseudoEqu(line, column, id); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoEqu pseudoEqu = (PseudoEqu) o; + return Objects.equals(id, pseudoEqu.id); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoIf.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoIf.java new file mode 100644 index 000000000..9f84bcca1 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoIf.java @@ -0,0 +1,23 @@ +package net.emustudio.plugins.compiler.asZ80.ast.pseudo; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +public class PseudoIf extends Node { + + public PseudoIf(int line, int column) { + super(line, column); + // expr is the first child + // statement is the second child + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new PseudoIf(line, column); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoIfExpression.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoIfExpression.java new file mode 100644 index 000000000..1ae9c2cbe --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoIfExpression.java @@ -0,0 +1,20 @@ +package net.emustudio.plugins.compiler.asZ80.ast.pseudo; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +public class PseudoIfExpression extends Node { + public PseudoIfExpression(int line, int column) { + super(line, column); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new PseudoIfExpression(line, column); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoInclude.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoInclude.java new file mode 100644 index 000000000..e463fd1a7 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoInclude.java @@ -0,0 +1,45 @@ +package net.emustudio.plugins.compiler.asZ80.ast.pseudo; + +import net.emustudio.plugins.compiler.asZ80.ParsingUtils; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +public class PseudoInclude extends Node { + public final String filename; + + public PseudoInclude(int line, int column, String fileName) { + super(line, column); + this.filename = Objects.requireNonNull(fileName); + } + + public PseudoInclude(Token fileName) { + this(fileName.getLine(), fileName.getCharPositionInLine(), ParsingUtils.parseLitString(fileName)); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "PseudoInclude('" + filename + "')"; + } + + @Override + protected Node mkCopy() { + return new PseudoInclude(line, column, filename); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoInclude that = (PseudoInclude) o; + return Objects.equals(filename, that.filename); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java new file mode 100644 index 000000000..73eee631d --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java @@ -0,0 +1,54 @@ +package net.emustudio.plugins.compiler.asZ80.ast.pseudo; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.NameSpace; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; +import java.util.Optional; + +import static net.emustudio.plugins.compiler.asZ80.ParsingUtils.parseLabel; + +public class PseudoLabel extends Node { + public final String label; + + public PseudoLabel(int line, int column, String label) { + super(line, column); + this.label = Objects.requireNonNull(label); + } + + public PseudoLabel(Token label) { + this(label.getLine(), label.getCharPositionInLine(), parseLabel(label)); + } + + @Override + public Optional eval(Optional currentAddress, NameSpace env) { + return currentAddress.map(addr -> new Evaluated(line, column, addr)); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "Label(" + label +")"; + } + + @Override + protected Node mkCopy() { + return new PseudoLabel(line, column, label); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoLabel pseudoLabel1 = (PseudoLabel) o; + return Objects.equals(label, pseudoLabel1.label); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroArgument.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroArgument.java new file mode 100644 index 000000000..0344703ff --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroArgument.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.compiler.asZ80.ast.pseudo; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +/** + * Macro call arguments are passed when macro is called. + */ +public class PseudoMacroArgument extends Node { + + public PseudoMacroArgument(int line, int column) { + super(line, column); + // the only child is expr + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new PseudoMacroArgument(line, column); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroCall.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroCall.java new file mode 100644 index 000000000..f252b641f --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroCall.java @@ -0,0 +1,45 @@ +package net.emustudio.plugins.compiler.asZ80.ast.pseudo; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +public class PseudoMacroCall extends Node { + public final String id; + + public PseudoMacroCall(int line, int column, String id) { + super(line, column); + this.id = Objects.requireNonNull(id); + // children are exprs (arguments) + } + + public PseudoMacroCall(Token id) { + this(id.getLine(), id.getCharPositionInLine(), id.getText()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "PseudoMacroCall(" + id + ")"; + } + + @Override + protected Node mkCopy() { + return new PseudoMacroCall(line, column, id); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoMacroCall that = (PseudoMacroCall) o; + return Objects.equals(id, that.id); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroDef.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroDef.java new file mode 100644 index 000000000..c5d8e443c --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroDef.java @@ -0,0 +1,45 @@ +package net.emustudio.plugins.compiler.asZ80.ast.pseudo; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +public class PseudoMacroDef extends Node { + public final String id; + + public PseudoMacroDef(int line, int column, String id) { + super(line, column); + this.id = Objects.requireNonNull(id); + // parameters are the first children + // statements are followed + } + + public PseudoMacroDef(Token id) { + this(id.getLine(), id.getCharPositionInLine(), id.getText()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "PseudoMacroDef(" + id + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoMacroDef that = (PseudoMacroDef) o; + return Objects.equals(id, that.id); + } + + public PseudoMacroDef mkCopy() { + return new PseudoMacroDef(line, column, id); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroParameter.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroParameter.java new file mode 100644 index 000000000..d0a2f5ad6 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoMacroParameter.java @@ -0,0 +1,26 @@ +package net.emustudio.plugins.compiler.asZ80.ast.pseudo; + + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +/** + * Macro definition parameter + */ +public class PseudoMacroParameter extends Node { + + public PseudoMacroParameter(int line, int column) { + super(line, column); + // the only child is ExprId + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new PseudoMacroParameter(line, column); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoOrg.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoOrg.java new file mode 100644 index 000000000..985446a8d --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoOrg.java @@ -0,0 +1,22 @@ +package net.emustudio.plugins.compiler.asZ80.ast.pseudo; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; + +public class PseudoOrg extends Node { + + public PseudoOrg(int line, int column) { + super(line, column); + // expr is the only child + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new PseudoOrg(line, column); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoSet.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoSet.java new file mode 100644 index 000000000..a82d771d4 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoSet.java @@ -0,0 +1,45 @@ +package net.emustudio.plugins.compiler.asZ80.ast.pseudo; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.Objects; + +public class PseudoSet extends Node { + public final String id; + + public PseudoSet(int line, int column, String id) { + super(line, column); + this.id = Objects.requireNonNull(id); + // expr is the only child + } + + public PseudoSet(Token id) { + this(id.getLine(), id.getCharPositionInLine(), id.getText()); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "PseudoSet(" + id + ")"; + } + + @Override + protected Node mkCopy() { + return new PseudoSet(line, column, id); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PseudoSet pseudoSet = (PseudoSet) o; + return Objects.equals(id, pseudoSet.id); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/AlreadyDefinedException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/AlreadyDefinedException.java deleted file mode 100644 index 614e3ea63..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/AlreadyDefinedException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.exceptions; - -public class AlreadyDefinedException extends CompilerException { - - public AlreadyDefinedException(int line, int column, String what) { - super(line, column, what + " is already defined!"); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/AmbiguousException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/AmbiguousException.java deleted file mode 100644 index 5caca71e7..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/AmbiguousException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.exceptions; - -public class AmbiguousException extends CompilerException { - - public AmbiguousException(int line, int column, String whatIsAmbiguous) { - super(line, column, whatIsAmbiguous + " is ambiguous!"); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/CompilerException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/CompileException.java similarity index 73% rename from plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/CompilerException.java rename to plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/CompileException.java index 36a83e798..47d856a26 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/CompilerException.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/CompileException.java @@ -18,29 +18,21 @@ */ package net.emustudio.plugins.compiler.asZ80.exceptions; -public class CompilerException extends Exception { - private final int line; - private final int column; +public class CompileException extends RuntimeException { + public final int line; + public final int column; - public CompilerException(int column, int line, String message) { + public CompileException(int line, int column, String message) { super("[" + line + "," + column + "] " + message); this.column = column; this.line = line; } - public CompilerException(int column, int line, String message, Throwable cause) { + public CompileException(int line, int column, String message, Throwable cause) { super("[" + line + "," + column + "] " + message, cause); this.column = column; this.line = line; } - - public int getColumn() { - return column; - } - - public int getLine() { - return line; - } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/FatalError.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/FatalError.java new file mode 100644 index 000000000..fc4acda48 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/FatalError.java @@ -0,0 +1,18 @@ +package net.emustudio.plugins.compiler.asZ80.exceptions; + +import net.emustudio.plugins.compiler.asZ80.CompileError; + +public class FatalError extends CompileException { + + public FatalError(int line, int column, String why) { + super(line, column, "Fatal error (cannot continue): " + why); + } + + public static void now(int line, int column, String why) { + throw new FatalError(line, column, why); + } + + public static void now(CompileError error) { + now(error.line, error.column, error.msg); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/InvalidMacroParamsCountException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/InvalidMacroParamsCountException.java deleted file mode 100644 index 45791cffe..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/InvalidMacroParamsCountException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.exceptions; - -public class InvalidMacroParamsCountException extends CompilerException { - - public InvalidMacroParamsCountException(int column, int line, String name, int expected, int was) { - super(column, line, "Invalid macro(" + name + ") parameters count, expected " + expected + ", but was " + was); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/NeedMorePassException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/NeedMorePassException.java deleted file mode 100644 index d922131e0..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/NeedMorePassException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.exceptions; - -/** - * This exception can be thrown during compiling forward references that are in expressions. - *

- * Expression with forward reference for label can't be evaulated without knowing a value of the label (its address that - * label is pointing at). - */ -public class NeedMorePassException extends CompilerException { - - public NeedMorePassException(int line, int column) { - super(line, column, ""); - } - -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/NegativeValueException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/NegativeValueException.java deleted file mode 100644 index b9b8b031a..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/NegativeValueException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.exceptions; - -public class NegativeValueException extends CompilerException { - - public NegativeValueException(int line, int column, int value) { - super(line, column, "Value(" + value + ") cannot be negative!"); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/SyntaxErrorException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/SyntaxErrorException.java new file mode 100644 index 000000000..7b9e085c9 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/SyntaxErrorException.java @@ -0,0 +1,11 @@ +package net.emustudio.plugins.compiler.asZ80.exceptions; + +public class SyntaxErrorException extends CompileException { + public SyntaxErrorException(int line, int column, String message) { + super(line, column, message); + } + + public SyntaxErrorException(int line, int column, String message, Throwable cause) { + super(line, column, message, cause); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UndefinedMacroException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UndefinedMacroException.java deleted file mode 100644 index c4b6e1b44..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UndefinedMacroException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.exceptions; - -public class UndefinedMacroException extends CompilerException { - - public UndefinedMacroException(int column, int line, String macroName) { - super(column, line, "Undefined macro: " + macroName); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnexpectedEOFException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnexpectedEOFException.java deleted file mode 100644 index ceef1fc56..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnexpectedEOFException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.exceptions; - -public class UnexpectedEOFException extends CompilerException { - - public UnexpectedEOFException(int line, int column, String filename) { - super(line, column, "Unexpected end of file (" + filename + ")"); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnknownMacroParametersException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnknownMacroParametersException.java deleted file mode 100644 index 13339eec1..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/UnknownMacroParametersException.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.exceptions; - -public class UnknownMacroParametersException extends CompilerException { - public UnknownMacroParametersException(int column, int line, String name) { - super(column, line, "Unknown macro(" + name + ") parameters"); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/ValueOutOfBoundsException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/ValueOutOfBoundsException.java deleted file mode 100644 index f38307bf7..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/ValueOutOfBoundsException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.exceptions; - -public class ValueOutOfBoundsException extends CompilerException { - - public ValueOutOfBoundsException(int column, int line, int minValue, int maxValue, int currentValue) { - super(column, line, "Value (" + currentValue + ") is out of bounds (minimum is " - + minValue + ", maximum is " + maxValue + ")"); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/ValueTooBigException.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/ValueTooBigException.java deleted file mode 100644 index 709104b80..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/exceptions/ValueTooBigException.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.exceptions; - -public class ValueTooBigException extends CompilerException { - - public ValueTooBigException(int line, int column, int currentValue, int maximumValue) { - super(column, line, "Value (" + currentValue + ") too large (maximum is " + maximumValue + ")"); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Address.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Address.java deleted file mode 100644 index b44802c78..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Address.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; - -public class Address extends Expression { - - public void setAddress(int address) { - this.value = address; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - @Override - public int eval(Namespace env, int curr_addr) { - this.setAddress(curr_addr); - return curr_addr; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Arithmetic.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Arithmetic.java deleted file mode 100644 index d8163757c..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Arithmetic.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; - -public class Arithmetic extends Expression { - - public static final int ADD = 0; - public static final int MINUS = 1; - public static final int MUL = 2; - public static final int DIV = 3; - public static final int MOD = 4; - public static final int SHL = 5; - public static final int SHR = 6; - public static final int AND = 7; - public static final int OR = 8; - public static final int XOR = 9; - public static final int EQ = 10; - public static final int LE = 11; - public static final int GE = 12; - public static final int LESS = 13; - public static final int GREATER = 14; - public static final int NOT = 15; - private Expression left; - private Expression right; - private int operator; - - /** - * Creates a new instance of Arithmetic - */ - public Arithmetic(Expression left, Expression right, final int operator) { - this.left = left; - this.right = right; - this.operator = operator; - } - - /// compile time /// - @Override - public int eval(Namespace env, int curr_addr) throws Exception { - int lv = left.eval(env, curr_addr); - int rv = 0; - if (right != null) { - rv = right.eval(env, curr_addr); - } - - this.value = 0; - switch (operator) { - case OR: - this.value = lv | rv; - break; - case XOR: - this.value = lv ^ rv; - break; - case AND: - this.value = lv & rv; - break; - case NOT: - this.value = ~lv; - break; - case ADD: - this.value = lv + rv; - break; - case MINUS: - this.value = (right == null) ? -lv : (lv - rv); - break; - case MUL: - this.value = lv * rv; - break; - case DIV: - this.value = lv / rv; - break; - case MOD: - this.value = lv % rv; - break; - case SHL: - this.value = lv << rv; - break; - case SHR: - this.value = lv >>> rv; - break; - case EQ: - this.value = (lv == rv) ? 1 : 0; - break; - case LE: - this.value = (lv <= rv) ? 1 : 0; - break; - case GE: - this.value = (lv >= rv) ? 1 : 0; - break; - case LESS: - this.value = (lv < rv) ? 1 : 0; - break; - case GREATER: - this.value = (lv > rv) ? 1 : 0; - break; - } - return this.value; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDB.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDB.java deleted file mode 100644 index a5184ab88..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDB.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.ValueTooBigException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.DataValue; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Instruction; - -public class DataDB extends DataValue { - - private Expression expression = null; - private String literalString = null; - private Instruction opcode = null; - - public DataDB(Expression expression, int line, int column) { - super(line, column); - this.expression = expression; - } - - public DataDB(String literalString, int line, int column) { - super(line, column); - this.literalString = literalString; - } - - public DataDB(Instruction opcode, int line, int column) { - super(line, column); - this.opcode = opcode; - } - - /// compile time /// - @Override - public int getSize() { - if (expression != null) { - return 1; - } else if (literalString != null) { - return literalString.length(); - } else if (opcode != null) { - return opcode.getSize(); - } - return 0; - } - - @Override - public void pass1() throws Exception { - if (opcode != null) { - opcode.pass1(); - } - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - int next; - if (expression != null) { - expression.eval(env, addr_start); - next = addr_start + 1; - } else if (literalString != null) { - next = addr_start + literalString.length(); - } else if (opcode != null) { - next = opcode.pass2(env, addr_start); - } else { - next = addr_start; - } - return next; - } - - @Override - public void pass4(IntelHEX hex) throws Exception { - if (expression != null) { - if (expression.getValue() > 0xFF) { - throw new ValueTooBigException(line, column, expression.getValue(), 0xFF); - } - if (expression.getValue() < -128) { - throw new ValueTooBigException(line, column, expression.getValue(), -128); - } - hex.putCode(expression.encodeValue(1)); - } else if (literalString != null) { - hex.putCode(this.encodeValue(literalString)); - } else if (opcode != null) { - opcode.generateCode(hex); - } - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDS.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDS.java deleted file mode 100644 index 0778dbdc5..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDS.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.AmbiguousException; -import net.emustudio.plugins.compiler.asZ80.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.asZ80.exceptions.NegativeValueException; -import net.emustudio.plugins.compiler.asZ80.exceptions.ValueTooBigException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.DataValue; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; - -public class DataDS extends DataValue { - private Expression expression; - - public DataDS(Expression expr, int line, int column) { - super(line, column); - this.expression = expr; - } - - @Override - public int getSize() { - return expression.getValue(); - } - - @Override - public void pass1() { - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - try { - int val = expression.eval(env, addr_start); - return addr_start + val; - } catch (NeedMorePassException e) { - throw new AmbiguousException(line, column, "DS expression"); - } - } - - @Override - public void pass4(IntelHEX hex) throws Exception { - StringBuilder str = new StringBuilder(); - if (expression.getValue() > 0xFF) { - throw new ValueTooBigException(line, column, expression.getValue(), 0xFF); - } else if (expression.getValue() < 0) { - throw new NegativeValueException(line, column, expression.getValue()); - } - str.append("00".repeat(Math.max(0, expression.getValue()))); - hex.putCode(str.toString()); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDW.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDW.java deleted file mode 100644 index afc719f1c..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataDW.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.ValueTooBigException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.DataValue; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; - -public class DataDW extends DataValue { - - private Expression expression; - - public DataDW(Expression expr, int line, int column) { - super(line, column); - this.expression = expr; - } - - @Override - public int getSize() { - return 2; - } - - @Override - public void pass1() { - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - expression.eval(env, addr_start); - return addr_start + 2; - } - - @Override - public void pass4(IntelHEX hex) throws Exception { - if (expression.getValue() > 0xFFFF) { - throw new ValueTooBigException(line, column, expression.getValue(), 0xFFFF); - } - if (expression.getValue() < -32768) { - throw new ValueTooBigException(line, column, expression.getValue(), -32768); - } - - hex.putCode(expression.encodeValue(2)); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataNode.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataNode.java deleted file mode 100644 index c2b21bba7..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DataNode.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.DataValue; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.InstrData; - -import java.util.ArrayList; -import java.util.List; - -public class DataNode extends InstrData { - private final List dataValues = new ArrayList<>(); - - public void addElement(DataValue node) { - dataValues.add(node); - } - - public DataNode(int line, int column) { - super(line, column); - } - - @Override - public int getSize() { - int size = 0; - for (DataValue dataValue : dataValues) { - size += dataValue.getSize(); - } - return size; - } - - @Override - public void pass1() throws Exception { - for (DataValue dataValue : dataValues) { - dataValue.pass1(); - } - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - for (DataValue dataValue : dataValues) { - addr_start = dataValue.pass2(env, addr_start); - } - return addr_start; - } - - @Override - public void generateCode(IntelHEX hex) throws Exception { - for (DataValue dataValue : dataValues) { - dataValue.pass4(hex); - } - } - -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DecimalExpr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DecimalExpr.java deleted file mode 100644 index de2250b53..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/DecimalExpr.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; - -public class DecimalExpr extends Expression { - - public DecimalExpr(int value) { - this.value = value; - } - - public int getSize() { - if ((value & 0xFF) == value) { - return 1; - } else { - return 2; - } - } - - @Override - public int eval(Namespace env, int curr_addr) throws Exception { - return value; - } - -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Identifier.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Identifier.java deleted file mode 100644 index 2a8dbfbb1..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Identifier.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; - -public class Identifier extends Expression { - private final String name; - private final int line; - private final int col; - - public Identifier(String name, int line, int col) { - this.name = name; - this.line = line; - this.col = col; - } - - public int getSize() { - return 0; - } - - @Override - public int eval(Namespace env, int curr_addr) throws Exception { - // identifier in expression can be only label, equ, or set statement. macro NOT - // search in env for labels - Label lab = env.getLabel(this.name); - if ((lab != null) && (lab.getAddress() == null)) { - throw new NeedMorePassException(lab.getLine(), lab.getColumn()); - } else if (lab != null) { - this.value = lab.getAddress(); - return this.value; - } - - PseudoEQU equ = env.getConstant(this.name); - if (equ != null) { - this.value = equ.getValue(); - return this.value; - } - - PseudoVAR set = env.getVariable(this.name); - if (set != null) { - this.value = set.getValue(); - return this.value; - } else { - throw new NeedMorePassException(line, col); - } - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Label.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Label.java deleted file mode 100644 index 29d79e404..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Label.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import java.util.Objects; - -public class Label { - private final String name; - private final int line; - private final int column; - - private Integer address; - - public Label(String name, int line, int column) { - this.name = Objects.requireNonNull(name); - this.address = null; - - this.line = line; - this.column = column; - } - - public void setAddress(Integer address) { - this.address = address; - } - - public Integer getAddress() { - return this.address; - } - - public int getLine() { - return line; - } - - public int getColumn() { - return column; - } - - public String getName() { - return name; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Program.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Program.java deleted file mode 100644 index 279182da9..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Program.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.NeedMorePassException; - -import java.util.ArrayList; -import java.util.List; - -public class Program { - private final List list = new ArrayList<>(); - private Namespace namespace; - private final List includefiles = new ArrayList<>(); - - void addIncludeFiles(List inclfiles) { - includefiles.addAll(inclfiles); - } - - public void addRow(Row node) { - list.add(node); - } - - public int getSize() { - int size = 0; - for (Row row : list) { - size += row.getSize(); - } - return size; - } - - /* PASS1 = symbol table - * 1. get all label definitions - * 2. get all macro definitions - */ - public Namespace getNamespace() { - return namespace; - } - - /** - * Method check whether this "subprogram" contains include - * pseudocode(s) and if yes, whether the statement calls for - * filename given by parameter. - * - * @param filename name of the file that "include" pseudocode should contain - * @return true if subprogram contains "include filename" pseudocode - */ - boolean getIncludeLoops(String filename) { - int i; - for (i = 0; i < includefiles.size(); i++) { - String s = includefiles.get(i); - if (s.equals(filename)) { - return true; - } - } - includefiles.add(filename); - Row in; - for (i = 0; i < list.size(); i++) { - in = list.get(i); - if (in.getIncludeLoops(filename)) { - return true; - } - } - return false; - } - - public void pass1(Namespace namespace) throws Exception { - this.namespace = namespace; - pass1(); - } - - // creates symbol table - // return next current address - public void pass1() throws Exception { - // only labels and macros have right to be all added to symbol table at once - for (Row row : list) { - if (row.label != null) { - if (!namespace.addLabel(row.label)) { - throw new Exception("Error: Label already defined: " + row.label.getName()); - } - } - if ((row.statement instanceof PseudoMACRO)) { - if (!namespace.addMacro((PseudoMACRO) row.statement)) { - throw new Exception("Error: Macro already defined: " - + ((PseudoMACRO) row.statement).getName()); - } - } - if ((row.statement instanceof PseudoINCLUDE)) { - row.pass1(includefiles, namespace); - } else { - row.pass1(); - } - } - } - - // pass2 tries to evaulate all expressions and compute relative addresses - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - int curr_addr; - for (Row row : list) { - try { - curr_addr = row.pass2(parentEnv, addr_start); - addr_start = curr_addr; - } catch (NeedMorePassException e) { - parentEnv.addPassNeed(row); - addr_start += row.getSize(); - } - } - return addr_start; - } - - public int pass2(int addr_start) throws Exception { - return this.pass2(namespace, addr_start); - } - - public boolean pass3(Namespace parentEnv) throws Exception { - int pnCount = parentEnv.getPassNeedCount(); - for (int i = parentEnv.getPassNeedCount() - 1; i >= 0; i--) { - if (parentEnv.getPassNeed(i).pass3(parentEnv)) { - pnCount--; - parentEnv.removePassNeed(i); - } - } - return pnCount < parentEnv.getPassNeedCount(); - } - - public void pass4(IntelHEX hex) throws Exception { - for (Row row : list) { - row.pass4(hex); - } - } - - public void pass4(IntelHEX hex, Namespace env) throws Exception { - this.namespace = env; - pass4(hex); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoEQU.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoEQU.java deleted file mode 100644 index c211e36d9..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoEQU.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.AlreadyDefinedException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Pseudo; - -public class PseudoEQU extends Pseudo { - - private Expression expr; - private String mnemo; - - public PseudoEQU(String id, Expression expr, int line, int column) { - super(line, column); - this.mnemo = id; - this.expr = expr; - } - - public String getName() { - return mnemo; - } - - public int getValue() { - return expr.getValue(); - } - - @Override - public int getSize() { - return 0; - } - - @Override - public void pass1() { - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - if (!env.addConstant(this)) { - throw new AlreadyDefinedException(line, column, "constant(" + mnemo + ")"); - } - expr.eval(env, addr_start); - return addr_start; - } - - @Override - public void generateCode(IntelHEX hex) { - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoIF.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoIF.java deleted file mode 100644 index ba966696d..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoIF.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.AmbiguousException; -import net.emustudio.plugins.compiler.asZ80.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Pseudo; - -public class PseudoIF extends Pseudo { - - private Expression expr; - private Program subprogram; - private boolean condTrue; // => for generateCode; if this is true, - // then generate code, otherwise not. - - public PseudoIF(Expression expr, Program stat, int line, int column) { - super(line, column); - this.expr = expr; - this.subprogram = stat; - this.condTrue = false; - } - - @Override - public int getSize() { - if (condTrue) { - return subprogram.getSize(); - } else { - return 0; - } - } - - @Override - public void pass1() { - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - subprogram.pass1(env); - // now evaluate expression and then decide if block can be passed - try { - if (expr.eval(env, addr_start) != 0) { - condTrue = true; - return subprogram.pass2(env, addr_start); - } else { - return addr_start; - } - } catch (NeedMorePassException e) { - throw new AmbiguousException(line, column, "IF expression"); - } - } - - @Override - public void generateCode(IntelHEX hex) throws Exception { - if (condTrue) { - subprogram.pass4(hex); - } - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoINCLUDE.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoINCLUDE.java deleted file mode 100644 index 7135dcd04..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoINCLUDE.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.CompilerImpl; -import net.emustudio.plugins.compiler.asZ80.LexerImpl; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.ParserImpl; -import net.emustudio.plugins.compiler.asZ80.exceptions.CompilerException; -import net.emustudio.plugins.compiler.asZ80.exceptions.UnexpectedEOFException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Pseudo; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.List; - -public class PseudoINCLUDE extends Pseudo { - private final String fileName; - private Program program; - private Namespace namespace; - private final CompilerImpl compiler; - - public PseudoINCLUDE(String filename, int line, int column, CompilerImpl compiler) { - super(line, column); - this.fileName = filename.replace("\\", File.separator); - this.compiler = compiler; - } - - @Override - public int getSize() { - return program.getSize(); - } - - private File findIncludeFile(String tmpFileName) { - File tmpFile = new File(tmpFileName); - if (tmpFile.isAbsolute()) { - return tmpFile; - } else { - return new File(namespace.getInputFile().getParent() - + File.separator + tmpFileName); - } - } - - - /** - * Method compare filename (in the include statement) - * with filename given by the parameter - * - * @return true if filenames equal, false if not - */ - public boolean isEqualName(String tmpFileName) { - return findIncludeFile(fileName).equals(findIncludeFile(tmpFileName)); - } - - @Override - public void pass1() { - } - - public void pass1(List includefiles, Namespace parent) throws Exception { - try { - namespace = new Namespace(parent.getInputFile().getAbsolutePath()); - - File file = findIncludeFile(fileName); - - FileReader f = new FileReader(file); - LexerImpl lexer = new LexerImpl(f); - ParserImpl parser = new ParserImpl(lexer, compiler); - - parser.setReportPrefixString(file.getName() + ": "); - Object s = parser.parse().value; - parser.setReportPrefixString(null); - if (s == null) { - throw new UnexpectedEOFException(line, column, file.getAbsolutePath()); - } - program = (Program) s; - program.addIncludeFiles(includefiles); - namespace = parent; - - if (program.getIncludeLoops(fileName)) { - throw new CompilerException(line, column, "Error: Infinite INCLUDE loop (" + file.getAbsolutePath() + ")"); - } - program.pass1(namespace); // create symbol table - } catch (CompilerException e) { - throw e; - } catch (IOException e) { - throw new CompilerException(line, column, fileName + ": " + e.getMessage(), e); - } catch (Exception e) { - throw new CompilerException(line, column, e.getMessage(), e); - } - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - // try to evaluate all expressions + compute relative addresses - return program.pass2(addr_start); - } - - @Override - public void generateCode(IntelHEX hex) throws Exception { - while (program.pass3(namespace)) { - // :-) - } - if (namespace.getPassNeedCount() != 0) { - throw new Exception("Error: can't evaulate all expressions"); - } - program.pass4(hex); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoMACRO.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoMACRO.java deleted file mode 100644 index dbde69848..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoMACRO.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.InvalidMacroParamsCountException; -import net.emustudio.plugins.compiler.asZ80.exceptions.UnknownMacroParametersException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Pseudo; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class PseudoMACRO extends Pseudo { - private final List params; // macro parameters - private List call_params; // concrete parameters, they can change - private final Program subprogram; - private final String mnemo; - // for generateCode - private Namespace newEnv; - - public PseudoMACRO(String name, List params, Program s, int line, - int column) { - super(line, column); - this.mnemo = name; - this.params = Objects.requireNonNullElseGet(params, ArrayList::new); - this.subprogram = s; - } - - public String getName() { - return mnemo; - } - - public void setCallParams(List params) { - this.call_params = params; - } - - @Override - public int getSize() { - return 0; - } - - public int getStatSize() { - return subprogram.getSize(); - } - - @Override - public void pass1() { - } - - // this is macro expansion ! can be called only in MacroCallPseudo class - // call parameters have to be set - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - createNewEnvironment(env); - - subprogram.pass1(newEnv); - - // check of call_params - if (call_params == null) { - throw new UnknownMacroParametersException(line, column, mnemo); - } - if (call_params.size() != params.size()) { - throw new InvalidMacroParamsCountException(line, column, mnemo, params.size(), call_params.size()); - } - // create/rewrite symbols => parameters as equ pseudo instructions - for (int i = 0; i < params.size(); i++) { - newEnv.addConstant(new PseudoEQU(params.get(i), - call_params.get(i), line, column)); - } - return subprogram.pass2(newEnv, addr_start); - } - - private void createNewEnvironment(Namespace env) { - newEnv = new Namespace(env.getInputFile().getAbsolutePath()); - env.copyTo(newEnv); - for (String param : params) { - newEnv.removeAllDefinitions(param); - } - } - - @Override - public void generateCode(IntelHEX hex) throws Exception { - subprogram.pass4(hex, newEnv); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoMACROCall.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoMACROCall.java deleted file mode 100644 index a266d54ac..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoMACROCall.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.AmbiguousException; -import net.emustudio.plugins.compiler.asZ80.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.asZ80.exceptions.UndefinedMacroException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Pseudo; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class PseudoMACROCall extends Pseudo { - - private List params; // ArrayList of expressions - private PseudoMACRO macro; // only pointer... - private IntelHEX statHex; // hex file for concrete macro - private String mnemo; - - public PseudoMACROCall(String name, List params, int line, int column) { - super(line, column); - this.mnemo = name; - this.params = Objects.requireNonNullElseGet(params, ArrayList::new); - statHex = new IntelHEX(); - } - - @Override - public int getSize() { - return macro.getStatSize(); - } - - @Override - public void pass1() { - } - - // this is a call for expanding a macro - // also generate code for generateCode - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - // first find a macro - this.macro = env.getMacro(this.mnemo); - if (macro == null) { - throw new UndefinedMacroException(line, column, mnemo); - } - // do pass2 for expressions (real macro parameters) - try { - for (Expression param : params) { - param.eval(env, addr_start); - } - macro.setCallParams(params); - int a = macro.pass2(env, addr_start); - statHex.setNextAddress(addr_start); - macro.generateCode(statHex); // generate code for concrete macro - return a; - } catch (NeedMorePassException e) { - throw new AmbiguousException(line, column, "MACRO expression"); - } - } - - @Override - public void generateCode(IntelHEX hex) { - hex.addTable(statHex.getTable()); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoORG.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoORG.java deleted file mode 100644 index 70575d521..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoORG.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.AmbiguousException; -import net.emustudio.plugins.compiler.asZ80.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Pseudo; - -import java.util.Objects; - -public class PseudoORG extends Pseudo { - private Expression expr; - - public PseudoORG(Expression expr, int line, int column) { - super(line, column); - this.expr = Objects.requireNonNull(expr); - } - - @Override - public int getSize() { - return 0; - } - - @Override - public void pass1() { - } - - // org only changes current address - // if expr isnt valuable, then error exception is thrown - // it cant help even more passes, because its recursive: - // org label - // mvi a,50 - // label: hlt - // label address cant be evaluated - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - try { - return expr.eval(parentEnv, addr_start); - } catch (NeedMorePassException e) { - throw new AmbiguousException(line, column, "ORG expression"); - } - } - - @Override - public void generateCode(IntelHEX hex) { - hex.setNextAddress(expr.getValue()); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoVAR.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoVAR.java deleted file mode 100644 index 8a93acaed..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/PseudoVAR.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.exceptions.AlreadyDefinedException; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Pseudo; - -public class PseudoVAR extends Pseudo { - private Expression expr; - private String mnemo; - - public PseudoVAR(String id, Expression expr, int line, int column) { - super(line, column); - this.mnemo = id; - this.expr = expr; - } - - public String getName() { - return mnemo; - } - - public int getValue() { - return expr.getValue(); - } - - @Override - public int getSize() { - return 0; - } - - @Override - public void pass1() { - } - - @Override - public int pass2(Namespace env, int addr_start) throws Exception { - if (!env.setVariable(this)) { - throw new AlreadyDefinedException(line, column, "Cannot set variable, the identifier(" + mnemo + ")"); - } - expr.eval(env, addr_start); - return addr_start; - } - - @Override - public void generateCode(IntelHEX hex) { - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Row.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Row.java deleted file mode 100644 index 26da1ba8c..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/Row.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.NeedMorePassException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Statement; - -import java.util.List; - -public class Row { - - protected Label label; - protected Statement statement; - private int current_address; // its computed in pass2 - - public Row(Label label, Statement statement) { - this.label = label; - this.statement = statement; - } - - public Row(Statement statement) { - this.label = null; - this.statement = statement; - } - - public boolean getIncludeLoops(String filename) { - if (statement == null) { - return false; - } - if (statement instanceof PseudoINCLUDE) { - PseudoINCLUDE i = (PseudoINCLUDE) statement; - return i.isEqualName(filename); - } - return false; - } - - public int getSize() { - if (statement != null) { - return statement.getSize(); - } else { - return 0; - } - } - - // do pass1 for all elements - public void pass1() - throws Exception { - if (statement != null) { - statement.pass1(); - } - } - - public void pass1(List inclfiles, Namespace parent) throws Exception { - ((PseudoINCLUDE) statement).pass1(inclfiles, parent); - } - - public int pass2(Namespace prev_env, int addr_start) throws Exception { - this.current_address = addr_start; - if (label != null) { - label.setAddress(addr_start); - } - // pass2 pre definiciu makra nemozem volat. ide totiz o samotnu expanziu - // makra. preto pass2 mozem volat az pri samotnom volani makra (pass2 triedy - // MacroCallPseudo) - if (statement != null) { - if (!(statement instanceof PseudoMACRO)) { - addr_start = statement.pass2(prev_env, addr_start); - } - } - return addr_start; - } - - public boolean pass3(Namespace env) throws Exception { - try { - if (statement != null) { - statement.pass2(env, this.current_address); - } - } catch (NeedMorePassException e) { - return false; - } - return true; - } - - // code generation - public void pass4(IntelHEX hex) throws Exception { - if (statement != null) { - if (!(statement instanceof PseudoMACRO)) { - statement.generateCode(hex); - } - } - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/DataValue.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/DataValue.java deleted file mode 100644 index aeb73884f..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/DataValue.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.treeAbstract; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; - -public abstract class DataValue { - - protected int line; - protected int column; - - public DataValue(int line, int column) { - this.line = line; - this.column = column; - } - - public abstract int getSize(); - - public abstract void pass1() throws Exception; - - public abstract int pass2(Namespace env, int addr_start) throws Exception; - - public abstract void pass4(IntelHEX hex) throws Exception; - - /** - * encode string into hex codes - */ - protected String encodeValue(String literal) { - byte[] byts = literal.getBytes(); - StringBuilder enc = new StringBuilder(); - - for (byte byt : byts) { - enc.append(Expression.encodeValue(byt, 1)); - } - return enc.toString(); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Expression.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Expression.java deleted file mode 100644 index 146b24b2d..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Expression.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.treeAbstract; - -import net.emustudio.plugins.compiler.asZ80.Namespace; - -public abstract class Expression { - - protected int value; - - public int getValue() { - return value; - } - - public static int getSize(int val) { - if (val <= 255 && val >= -128) { - return 1; - } else if (val <= 65535 && val >= -32768) { - return 2; - } else if (val <= 16777215 && val >= -8388608) { - return 3; - } - return 4; - } - - public abstract int eval(Namespace env, int curr_addr) throws Exception; - - static String encodeValue(int val, int neededSize) { - - int size = getSize(val); - if (size < neededSize) { - size = neededSize; - } - String s; - - if (size == 1) { - s = String.format("%02X", (val & 0xFF)); - } else if (size == 2) { - s = String.format("%02X%02X", (val & 0xFF), ((val >> 8) & 0xFF)); - } else if (size == 3) { - s = String.format("%02X%02X%02X", - (val & 0xFF), ((val >> 8) & 0xFF), ((val >> 16) & 0xFF)); - } else { - s = String.format("%02X%02X%02X%02X", - (val & 0xFF), ((val >> 8) & 0xFF), ((val >> 16) & 0xFF), - ((val >> 24) & 0xFF)); - } - return s; - } - - public static int reverseBytes(int val, int neededSize) { - int i = 0; - int size = getSize(val); - for (int j = 0; j < size; j++) { - i += (val & 0xFF); - val >>= 8; - i <<= 8; - } - for (int j = size; j < neededSize; j++) { - i <<= 8; - } - return i >>> 8; - } - - public String encodeValue(int neededSize) { - return encodeValue(value, neededSize); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/InstrData.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/InstrData.java deleted file mode 100644 index 730de1ca4..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/InstrData.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.treeAbstract; - -public abstract class InstrData extends Statement { - - public InstrData(int line, int column) { - super(line, column); - } - - @Override - public boolean isPseudo() { - return false; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Instruction.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Instruction.java deleted file mode 100644 index 5147aa3eb..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Instruction.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.treeAbstract; - -import net.emustudio.plugins.compiler.asZ80.exceptions.ValueOutOfBoundsException; - -public abstract class Instruction extends InstrData { - protected int opcode; - - public Instruction(int opcode, int line, int column) { - super(line, column); - this.opcode = opcode; - } - - protected static int computeRelativeAddress(int line, int column, int addressStart, int val) throws ValueOutOfBoundsException { - int relativeAddress = (val - addressStart - 2); - if (relativeAddress > 129 || relativeAddress < -126) { - throw new ValueOutOfBoundsException(line, column, -126, 129, val); - } - return relativeAddress & 0xFF; - } - - - @Override - public int getSize() { - return Expression.getSize(opcode); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Pseudo.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Pseudo.java deleted file mode 100644 index a4ea07501..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Pseudo.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.treeAbstract; - -/** - * pseudocodes var,equ are treated as local if theyre set in a macro. (see Label - * class) - */ -public abstract class Pseudo extends Statement { - - public Pseudo(int line, int column) { - super(line, column); - } - - @Override - public boolean isPseudo() { - return true; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Statement.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Statement.java deleted file mode 100644 index 3968b9787..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/treeAbstract/Statement.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.treeAbstract; - -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; - -public abstract class Statement { - protected int line; - protected int column; - - public abstract boolean isPseudo(); - - public Statement(int line, int column) { - this.line = line; - this.column = column; - } - - // return size of compiled code in bytes - public abstract int getSize(); - - public abstract void pass1() throws Exception; - - public abstract int pass2(Namespace parentEnv, int addr_start) throws Exception; - - public abstract void generateCode(IntelHEX hex) throws Exception; -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java new file mode 100644 index 000000000..0e9e31a82 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java @@ -0,0 +1,173 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; + +import java.util.*; + +import static net.emustudio.plugins.compiler.asZ80.CompileError.*; +import static net.emustudio.plugins.compiler.asZ80.ParsingUtils.normalizeId; + +/** + * Checks if all declarations are valid: + * - ID of constant,variable and macro can be used just once in the whole program. + * - ID of constant and macro cannot reference itself in the declaration + * - ID of variable cannot reference itself in the declaration only if it wasn't already declared + * - macro parameters should not conflict with: + * - declarations in and out of the macro scope + * - previously declared parameters in current or parent macros if the current one is nested + * - if expressions should not reference declarations inside that if (including all nested ifs) + * + * - cyclic references will be checked in evaluator since it requires > 1 passes + */ +public class CheckDeclarationsVisitor extends NodeVisitor { + private final Set allDeclarations = new HashSet<>(); + private final Set macros = new HashSet<>(); + private final Set variables = new HashSet<>(); + + // for checking collisions with other declarations (e.g. forward referenced labels) + private final Set allMacroParams = new HashSet<>(); + + // for checking marco param names in nested macros + private final List> macroParamsInScope = new ArrayList<>(); + + // for easier removal of current macro params from macroParamsInScope when the macro definition ends + private Set currentMacroParams; + + // if expr references + private final Set currentIfReferences = new HashSet<>(); + + private boolean insideMacroParameter = false; + private int insideIfLevel = 0; // if nesting level, to know how long to keep currentIfReferences + private boolean insideIfExpr = false; + + private String currentDeclarationId; + + @Override + public void visit(PseudoEqu node) { + addDeclaration(node.id, node); + currentDeclarationId = normalizeId(node.id); + visitChildren(node); + currentDeclarationId = null; + } + + @Override + public void visit(PseudoMacroDef node) { + addMacro(node.id, node); + currentMacroParams = new HashSet<>(); + macroParamsInScope.add(currentMacroParams); + visitChildren(node); + macroParamsInScope.remove(macroParamsInScope.size() - 1); + } + + @Override + public void visit(PseudoSet node) { + currentDeclarationId = normalizeId(node.id); + visitChildren(node); + addVariable(node.id, node); + currentDeclarationId = null; + } + + @Override + public void visit(PseudoLabel node) { + addDeclaration(node.label, node); + visitChildren(node); + } + + @Override + public void visit(PseudoMacroParameter node) { + insideMacroParameter = true; + visitChildren(node); + insideMacroParameter = false; + } + + @Override + public void visit(ExprId node) { + if (insideMacroParameter) { + addMacroParameter(node.id, node); + } + if (insideIfExpr) { + addIfReference(node); + } + String idLower = normalizeId(node.id); + if (!variables.contains(idLower) && idLower.equals(currentDeclarationId)) { + error(declarationReferencesItself(node)); + } + } + + @Override + public void visit(PseudoIf node) { + insideIfLevel++; + insideIfExpr = true; + visit(node.getChild(0)); // visiting only expr + insideIfExpr = false; + visitChildren(node, 1); + insideIfLevel--; + + if (insideIfLevel == 0) { + currentIfReferences.clear(); + } + } + + private void addVariable(String id, Node node) { + addDeclaration(id, true, node); + } + + private void addDeclaration(String id, Node node) { + addDeclaration(id, false, node); + } + + private void addDeclaration(String id, boolean isVariable, Node node) { + String normId = normalizeId(id); + + if (currentIfReferences.contains(normId)) { + error(ifExpressionReferencesOwnBlock(node)); + } + + // if we're in macro (arbitrary nesting level) and it has param named the same way -> error + // if there exist any declaration with that name, but either this declaration is not a variable or the name was taken by not a variable + if (allMacroParams.contains(normId) || buildDeclarations().contains(normId) && (!isVariable || !variables.contains(id))) { + error(alreadyDeclared(node, id)); + } + allDeclarations.add(normId); + if (isVariable) { + variables.add(normId); + } + } + + private void addMacro(String id, Node node) { + String idLower = id.toLowerCase(Locale.ENGLISH); + if (macros.contains(idLower)) { + error(alreadyDeclared(node, id)); + } + macros.add(idLower); + } + + private void addMacroParameter(String id, Node node) { + String idLower = id.toLowerCase(Locale.ENGLISH); + if (buildDeclarations().contains(idLower) || macros.contains(idLower)) { + error(alreadyDeclared(node, id)); + } + currentMacroParams.add(idLower); + allMacroParams.add(idLower); + } + + private void addIfReference(ExprId node) { + String idLower = node.id.toLowerCase(Locale.ENGLISH); + if (currentIfReferences.contains(idLower)) { + error(ifExpressionReferencesOwnBlock(node)); + } else { + currentIfReferences.add(idLower); + } + } + + private Set buildDeclarations() { + Set allDeclarations = new HashSet<>(); + for (Set parameters : macroParamsInScope) { + allDeclarations.addAll(parameters); + } + allDeclarations.addAll(this.allDeclarations); + return allDeclarations; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java new file mode 100644 index 000000000..ee2ef10a8 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java @@ -0,0 +1,87 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrExpr; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRegPairExpr; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroArgument; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoOrg; + +import static net.emustudio.plugins.compiler.asZ80.CompileError.expressionIsBiggerThanExpected; + +/** + * Checks proper sizes of evaluated nodes + */ +public class CheckExprSizesVisitor extends NodeVisitor { + private int expectedBytes; + + @Override + public void visit(DataDB node) { + expectedBytes = 1; + visitChildren(node); + } + + @Override + public void visit(DataDW node) { + expectedBytes = 2; + visitChildren(node); + } + + @Override + public void visit(DataDS node) { + expectedBytes = 2; + visitChildren(node); + } + + @Override + public void visit(InstrExpr node) { + expectedBytes = node.getExprSizeBytes(); + if (expectedBytes == 1 && node.getChildrenCount() > 1) { + error(expressionIsBiggerThanExpected(node, expectedBytes, node.getChildrenCount())); + } + visitChildren(node); + } + + @Override + public void visit(InstrRegExpr node) { + expectedBytes = 1; + if (node.getChildrenCount() > 1) { + error(expressionIsBiggerThanExpected(node, expectedBytes, node.getChildrenCount())); + } + visitChildren(node); + } + + @Override + public void visit(InstrRegPairExpr node) { + expectedBytes = 2; + visitChildren(node); + } + + @Override + public void visit(PseudoOrg node) { + expectedBytes = 2; + visitChildren(node); + } + + @Override + public void visit(PseudoMacroArgument node) { + node.remove(); + } + + @Override + public void visit(Evaluated node) { + if (expectedBytes > 0) { + int value = node.value < 0 ? ((~node.value) * 2) : node.value; + + int wasBits = (int) Math.floor(Math.log10(Math.abs(value)) / Math.log10(2)) + 1; + int wasBytes = (int) Math.ceil(wasBits / 8.0); + + if (wasBytes > expectedBytes) { + error(expressionIsBiggerThanExpected(node, expectedBytes, wasBytes)); + } + } + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateDataVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateDataVisitor.java new file mode 100644 index 000000000..da7f2ddb1 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateDataVisitor.java @@ -0,0 +1,49 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import net.emustudio.plugins.compiler.asZ80.AsZ80ParserBaseVisitor; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; +import org.antlr.v4.runtime.Token; + +public class CreateDataVisitor extends AsZ80ParserBaseVisitor { + + @Override + public Node visitDataDB(DataDBContext ctx) { + Token start = ctx.getStart(); + DataDB db = new DataDB(start.getLine(), start.getCharPositionInLine()); + + for (RDBdataContext next : ctx.rDBdata()) { + if (next.expr != null) { + db.addChild(CreateVisitors.expr.visit(next.expr)); + } else if (next.instr != null) { + db.addChild(CreateVisitors.instr.visit(next.instr)); + } + } + return db; + } + + @Override + public Node visitDataDW(DataDWContext ctx) { + Token start = ctx.getStart(); + DataDW dw = new DataDW(start.getLine(), start.getCharPositionInLine()); + + for (RDWdataContext next : ctx.rDWdata()) { + if (next.expr != null) { + dw.addChild(CreateVisitors.expr.visit(next.expr)); + } + } + + return dw; + } + + @Override + public Node visitDataDS(DataDSContext ctx) { + Token start = ctx.getStart(); + DataDS ds = new DataDS(start.getLine(), start.getCharPositionInLine()); + ds.addChild(CreateVisitors.expr.visit(ctx.data)); + return ds; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateExprVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateExprVisitor.java new file mode 100644 index 000000000..9d29745f3 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateExprVisitor.java @@ -0,0 +1,72 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import net.emustudio.plugins.compiler.asZ80.AsZ80ParserBaseVisitor; +import net.emustudio.plugins.compiler.asZ80.ParsingUtils; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.expr.*; +import org.antlr.v4.runtime.Token; + +public class CreateExprVisitor extends AsZ80ParserBaseVisitor { + + @Override + public Node visitExprOct(ExprOctContext ctx) { + return new ExprNumber(ctx.num, ParsingUtils::parseLitOct); + } + + @Override + public Node visitExprHex1(ExprHex1Context ctx) { + return new ExprNumber(ctx.num, ParsingUtils::parseLitHex1); + } + + @Override + public Node visitExprHex2(ExprHex2Context ctx) { + return new ExprNumber(ctx.num, ParsingUtils::parseLitHex2); + } + + @Override + public Node visitExprDec(ExprDecContext ctx) { + return new ExprNumber(ctx.num, ParsingUtils::parseLitDec); + } + + @Override + public Node visitExprBin(ExprBinContext ctx) { + return new ExprNumber(ctx.num, ParsingUtils::parseLitBin); + } + + @Override + public Node visitExprId(ExprIdContext ctx) { + return new ExprId(ctx.id); + } + + @Override + public Node visitExprString(ExprStringContext ctx) { + return new ExprString(ctx.str); + } + + @Override + public Node visitExprUnary(ExprUnaryContext ctx) { + ExprUnary unary = new ExprUnary(ctx.unaryop); + unary.addChild(visit(ctx.expr)); + return unary; + } + + @Override + public Node visitExprInfix(ExprInfixContext ctx) { + ExprInfix infix = new ExprInfix(ctx.op); + infix.addChild(visit(ctx.expr1)); + infix.addChild(visit(ctx.expr2)); + return infix; + } + + @Override + public Node visitExprParens(ExprParensContext ctx) { + return visit(ctx.expr); + } + + @Override + public Node visitExprCurrentAddress(ExprCurrentAddressContext ctx) { + Token start = ctx.getStart(); + return new ExprCurrentAddress(start.getLine(), start.getCharPositionInLine()); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java new file mode 100644 index 000000000..cfc60248e --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java @@ -0,0 +1,57 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import net.emustudio.plugins.compiler.asZ80.AsZ80ParserBaseVisitor; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.instr.*; + +public class CreateInstrVisitor extends AsZ80ParserBaseVisitor { + + @Override + public Node visitInstrNoArgs(InstrNoArgsContext ctx) { + return new InstrNoArgs(ctx.opcode); + } + + @Override + public Node visitInstrReg(InstrRegContext ctx) { + return new InstrReg(ctx.opcode, ctx.reg.getStart()); + } + + @Override + public Node visitInstrRegReg(InstrRegRegContext ctx) { + return new InstrRegReg(ctx.opcode, ctx.dst.getStart(), ctx.src.getStart()); + } + + @Override + public Node visitInstrRegPair(InstrRegPairContext ctx) { + return new InstrRegPair(ctx.opcode, ctx.regpair); + } + + @Override + public Node visitInstrRegPairExpr(InstrRegPairExprContext ctx) { + InstrRegPairExpr instr = new InstrRegPairExpr(ctx.opcode, ctx.regpair); + instr.addChild(CreateVisitors.expr.visit(ctx.expr)); + return instr; + } + + @Override + public Node visitInstrRegExpr(InstrRegExprContext ctx) { + InstrRegExpr instr = new InstrRegExpr(ctx.opcode, ctx.reg.getStart()); + instr.addChild(CreateVisitors.expr.visit(ctx.expr)); + return instr; + } + + @Override + public Node visitInstrExpr(InstrExprContext ctx) { + InstrExpr instr = new InstrExpr(ctx.opcode); + instr.addChild(CreateVisitors.expr.visit(ctx.expr)); + return instr; + } + + @Override + public Node visitInstr8bitExpr(Instr8bitExprContext ctx) { + InstrExpr instr = new InstrExpr(ctx.opcode); + instr.addChild(CreateVisitors.expr.visit(ctx.expr)); + return instr; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateLineVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateLineVisitor.java new file mode 100644 index 000000000..69a631f89 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateLineVisitor.java @@ -0,0 +1,40 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import net.emustudio.plugins.compiler.asZ80.AsZ80ParserBaseVisitor; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoLabel; +import net.emustudio.plugins.compiler.asZ80.ast.Node; + +public class CreateLineVisitor extends AsZ80ParserBaseVisitor { + + @Override + public Node visitRLine(RLineContext ctx) { + Node label = null; + if (ctx.label != null) { + label = new PseudoLabel(ctx.label); + } + Node statement = null; + if (ctx.statement != null) { + statement = visit(ctx.statement); + } + if (label != null) { + if (statement != null) { + label.addChild(statement); + } + return label; + } + return statement; + } + + @Override + public Node visitRStatement(RStatementContext ctx) { + if (ctx.instr != null) { + return CreateVisitors.instr.visit(ctx.instr); + } else if (ctx.data != null) { + return CreateVisitors.data.visit(ctx.data); + } else if (ctx.pseudo != null) { + return CreateVisitors.pseudo.visit(ctx.pseudo); + } + throw new IllegalStateException("No statement defined!"); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateProgramVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateProgramVisitor.java new file mode 100644 index 000000000..cd7b9c8e9 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateProgramVisitor.java @@ -0,0 +1,28 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import net.emustudio.plugins.compiler.asZ80.AsZ80ParserBaseVisitor; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.Program; + +import java.util.Objects; + +/** + * The visitor creates internal AST (= "Program") of the parse tree. + */ +public class CreateProgramVisitor extends AsZ80ParserBaseVisitor { + private final Program program; + + public CreateProgramVisitor(Program program) { + this.program = Objects.requireNonNull(program); + } + + @Override + public Program visitRLine(RLineContext ctx) { + Node statement = CreateVisitors.line.visitRLine(ctx); + if (statement != null) { + program.addChild(statement); + } + return program; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java new file mode 100644 index 000000000..dbd22e777 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java @@ -0,0 +1,86 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.As8080Parser.*; +import net.emustudio.plugins.compiler.asZ80.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.TerminalNode; + +public class CreatePseudoVisitor extends AsZ80ParserBaseVisitor { + + @Override + public Node visitPseudoOrg(PseudoOrgContext ctx) { + Token start = ctx.getStart(); + PseudoOrg pseudo = new PseudoOrg(start.getLine(), start.getCharPositionInLine()); + pseudo.addChild(CreateVisitors.expr.visit(ctx.expr)); + return pseudo; + } + + @Override + public Node visitPseudoEqu(PseudoEquContext ctx) { + PseudoEqu pseudo = new PseudoEqu(ctx.id); + pseudo.addChild(CreateVisitors.expr.visit(ctx.expr)); + return pseudo; + } + + @Override + public Node visitPseudoSet(PseudoSetContext ctx) { + PseudoSet pseudo = new PseudoSet(ctx.id); + pseudo.addChild(CreateVisitors.expr.visit(ctx.expr)); + return pseudo; + } + + @Override + public Node visitPseudoIf(PseudoIfContext ctx) { + Token start = ctx.getStart(); + + PseudoIf pseudo = new PseudoIf(start.getLine(), start.getCharPositionInLine()); + Node expr = CreateVisitors.expr.visit(ctx.expr); + PseudoIfExpression ifExpr = new PseudoIfExpression(expr.line, expr.column); + ifExpr.addChild(expr); + pseudo.addChild(ifExpr); + for (RLineContext line : ctx.rLine()) { + pseudo.addChild(CreateVisitors.line.visitRLine(line)); + } + return pseudo; + } + + @Override + public Node visitPseudoMacroDef(PseudoMacroDefContext ctx) { + PseudoMacroDef pseudo = new PseudoMacroDef(ctx.id); + + if (ctx.params != null) { + for (TerminalNode next : ctx.params.ID_IDENTIFIER()) { + Token symbol = next.getSymbol(); + PseudoMacroParameter parameter = new PseudoMacroParameter(symbol.getLine(), symbol.getCharPositionInLine()); + parameter.addChild(new ExprId(next.getSymbol())); + pseudo.addChild(parameter); + } + } + for (RLineContext line : ctx.rLine()) { + pseudo.addChild(CreateVisitors.line.visitRLine(line)); + } + return pseudo; + } + + @Override + public Node visitPseudoMacroCall(PseudoMacroCallContext ctx) { + PseudoMacroCall pseudo = new PseudoMacroCall(ctx.id); + + if (ctx.args != null) { + for (RExpressionContext next : ctx.args.rExpression()) { + Token start = next.getStart(); + PseudoMacroArgument argument = new PseudoMacroArgument(start.getLine(), start.getCharPositionInLine()); + pseudo.addChild(argument.addChild(CreateVisitors.expr.visit(next))); + } + } + return pseudo; + } + + @Override + public Node visitPseudoInclude(PseudoIncludeContext ctx) { + return new PseudoInclude(ctx.filename); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateVisitors.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateVisitors.java new file mode 100644 index 000000000..ec036bb7a --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateVisitors.java @@ -0,0 +1,11 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +public class CreateVisitors { + + static CreatePseudoVisitor pseudo = new CreatePseudoVisitor(); + static CreateExprVisitor expr = new CreateExprVisitor(); + static CreateInstrVisitor instr = new CreateInstrVisitor(); + static CreateDataVisitor data = new CreateDataVisitor(); + static CreateLineVisitor line = new CreateLineVisitor(); + +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java new file mode 100644 index 000000000..bbb0538b4 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java @@ -0,0 +1,348 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; +import net.emustudio.plugins.compiler.asZ80.ast.expr.*; +import net.emustudio.plugins.compiler.asZ80.ast.instr.*; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; + +import java.util.*; +import java.util.stream.Collectors; + +import static net.emustudio.plugins.compiler.asZ80.CompileError.*; +import static net.emustudio.plugins.compiler.asZ80.ParsingUtils.normalizeId; + +/** + * The goal is to replace all Expr* with Evaluated + *

+ * - replace ExprId (referencing PseudoEqu, PseudoSet, PseudoLabel or PseudoMacroArgument) with value + * - replace ExprCurrentAddress with the current address + * - address changes after processing Expr*, DataDS, PseudoOrg + * - eliminate or include code block of PseudoIf if expr evaluates to 1 + *

+ * After finishing this visitor, there should be: + * - no PseudoEqu + * - no ExprId + * - no PseudoIf + * - no PseudoLabel + */ +public class EvaluateExprVisitor extends NodeVisitor { + private int currentAddress = 0; + private int sizeBytes = 0; + private boolean doNotEvaluateCurrentAddress = false; + private final Set doNotEvaluateVariables = new HashSet<>(); + private final Set forwardReferences = new HashSet<>(); + + private Optional latestEval; + private Set needMorePassThings = new HashSet<>(); + + private final Map> macroArguments = new HashMap<>(); + private String currentMacroId; + + @Override + public void visit(Program node) { + if (env == null) { + this.env = node.env(); + } + + currentAddress = 0; + visitChildren(node); + + Set oldNeedMorePass; + while (!needMorePassThings.isEmpty()) { + oldNeedMorePass = needMorePassThings; + needMorePassThings = new HashSet<>(); + + currentAddress = 0; + doNotEvaluateCurrentAddress = false; + doNotEvaluateVariables.clear(); + forwardReferences.clear(); + + visitChildren(node); + + // at least one thing must disappear from "oldNeedMorePass"; + // doesn't matter if something is added - since the source code is final, also additions must be final. + boolean atLeastOneResolved = false; + for (Node oldNode : oldNeedMorePass) { + if (!needMorePassThings.contains(oldNode)) { + atLeastOneResolved = true; + break; + } + } + if (!atLeastOneResolved) { + // there is a cycle + for (Node unresolved : needMorePassThings) { + error(ambiguousExpression(unresolved)); + } + break; + } + } + } + + @Override + public void visit(DataDB node) { + node.setAddress(currentAddress); + sizeBytes = 1; + visitChildren(node); + } + + @Override + public void visit(DataDW node) { + node.setAddress(currentAddress); + sizeBytes = 2; + visitChildren(node); + } + + @Override + public void visit(DataDS node) { + node.setAddress(currentAddress); + sizeBytes = 0; + visitChildren(node); + latestEval.ifPresentOrElse( + e -> currentAddress += e.value, + () -> doNotEvaluateCurrentAddress = true + ); + } + + @Override + public void visit(PseudoEqu node) { + sizeBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) + visitChildren(node); + env.put(normalizeId(node.id), latestEval); + + // we don't need to re-evaluate the constant + latestEval.ifPresent(e -> node.remove()); + } + + @Override + public void visit(PseudoSet node) { + sizeBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) + String normalizedId = normalizeId(node.id); + if (!doNotEvaluateVariables.contains(normalizedId)) { + visitChildren(node); + env.put(normalizedId, latestEval); + + if (forwardReferences.contains(normalizedId)) { + // if there are forward references for this ID and the variable is redefined (defined more than once), + // the second pass would evaluate the reference with the latest variable redefinition instead of the + // first definition which appears after the reference. The reason is that references are evaluated by + // looking at env - and env contains previously defined values which are "inherited" in upcoming passes. + // So in the second pass env would contain the latest definition from the previous pass. + doNotEvaluateVariables.add(normalizedId); + } + } + } + + @Override + public void visit(PseudoLabel node) { + Optional eval = node.eval(getCurrentAddress(), env); + env.put(normalizeId(node.label), eval); + eval.ifPresentOrElse( + e -> { + // we don't need to re-evaluate label + node.exclude(); + }, + () -> needMorePassThings.add(node) + ); + visitChildren(node); + } + + @Override + public void visit(PseudoOrg node) { + node.setAddress(currentAddress); + sizeBytes = 0; + visitChildren(node); + latestEval.ifPresentOrElse( + e -> currentAddress = e.value, + () -> doNotEvaluateCurrentAddress = true + ); + } + + @Override + public void visit(PseudoIf node) { + sizeBytes = 0; + Optional expr = node + .collectChild(PseudoIfExpression.class) + .flatMap(p -> { + visitChildren(p); + return p.collectChild(Evaluated.class); + }); + + boolean includeBlock = expr.filter(p -> p.value != 0).isPresent(); + boolean excludeBlock = expr.filter(p -> p.value == 0).isPresent(); + + if (includeBlock) { + List codeChildren = node.getChildren().stream().skip(1).collect(Collectors.toList()); + node.remove().ifPresent(p -> p.addChildren(codeChildren)); + visitChildren(node, 1); + } else if (excludeBlock) { + node.remove(); + } else { + // expr needs more pass - it means all exprCurrentAddress and pseudoLabel evaluations below must be ignored + // until this expr is evaluated + doNotEvaluateCurrentAddress = true; + } + } + + @Override + public void visit(InstrExpr node) { + node.setAddress(currentAddress); + sizeBytes = node.getExprSizeBytes(); + visitChildren(node); + currentAddress++; // opcode + } + + @Override + public void visit(InstrRegExpr node) { + node.setAddress(currentAddress); + sizeBytes = 1; + visitChildren(node); + currentAddress++; // opcode + } + + @Override + public void visit(InstrRegPairExpr node) { + node.setAddress(currentAddress); + sizeBytes = 2; + visitChildren(node); + currentAddress++; // opcode + } + + @Override + public void visit(InstrNoArgs node) { + node.setAddress(currentAddress); + currentAddress++; + } + + @Override + public void visit(InstrRegReg node) { + node.setAddress(currentAddress); + currentAddress++; + } + + @Override + public void visit(InstrReg node) { + node.setAddress(currentAddress); + currentAddress++; + } + + @Override + public void visit(InstrRegPair node) { + node.setAddress(currentAddress); + currentAddress++; + } + + @Override + public void visit(PseudoMacroCall node) { + // save old current macro, including its params + String oldCurrentMacroId = currentMacroId; + Map> oldMacroParams = new HashMap<>(); + if (oldCurrentMacroId != null) { + for (String macroParameter : macroArguments.get(oldCurrentMacroId)) { + oldMacroParams.put(macroParameter, env.get(macroParameter)); + } + } + + currentMacroId = normalizeId(node.id); + macroArguments.put(currentMacroId, new ArrayList<>()); + visitChildren(node); + + // on macro exit, remove current macro arguments from env + for (String macroParameter : macroArguments.get(currentMacroId)) { + env.remove(macroParameter); + } + // and put back old current macro arguments to env + oldMacroParams.forEach((macroParam, expr) -> env.put(macroParam, expr)); + + macroArguments.remove(currentMacroId); + currentMacroId = oldCurrentMacroId; + } + + @Override + public void visit(PseudoMacroArgument node) { + sizeBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) + visitChildren(node, 1); // expected two children: ExprId and Expr* + + node.collectChild(ExprId.class) + .ifPresent(exprId -> { + String macroParameter = normalizeId(exprId.id); + macroArguments.get(currentMacroId).add(macroParameter); + env.put(macroParameter, latestEval); + }); + } + + @Override + public void visit(Evaluated node) { + latestEval = Optional.of(node); + currentAddress += sizeBytes; + } + + @Override + public void visit(ExprInfix node) { + evalExpr(node); + } + + @Override + public void visit(ExprNumber node) { + evalExpr(node); + } + + @Override + public void visit(ExprUnary node) { + evalExpr(node); + } + + @Override + public void visit(ExprCurrentAddress node) { + evalExpr(node); + } + + @Override + public void visit(ExprId node) { + evalExpr(node); + if (latestEval.isEmpty()) { + forwardReferences.add(normalizeId(node.id)); + } + } + + @Override + public void visit(ExprString node) { + // 2-byte sized strings are merged, for simplicity. 1-bytes will be added byte per byte. + // hopefully this covers all cases. + + int strLen = node.string.length(); + if (sizeBytes == 2) { + if (strLen > sizeBytes) { + error(expressionIsBiggerThanExpected(node, sizeBytes, strLen)); + } + int result = node.string.charAt(0); + if (strLen > 1) { + result |= (node.string.charAt(1) << 8); + } + node.addChild(new Evaluated(node.line, node.column, result)); + } else { + for (int i = 0; i < strLen; i++) { + node.addChild(new Evaluated(node.line, node.column, node.string.charAt(i))); + } + } + node.exclude(); + currentAddress += sizeBytes; + } + + private Optional getCurrentAddress() { + return doNotEvaluateCurrentAddress ? Optional.empty() : Optional.of(currentAddress); + } + + private void evalExpr(Node node) { + latestEval = node.eval(getCurrentAddress(), env); + latestEval.ifPresentOrElse( + e -> node.remove().ifPresent(p -> p.addChild(e)), + () -> needMorePassThings.add(node) + ); + currentAddress += sizeBytes; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java new file mode 100644 index 000000000..e4d23a16c --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java @@ -0,0 +1,61 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.AsZ80Lexer; +import net.emustudio.plugins.compiler.asZ80.AsZ80Parser; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoInclude; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTree; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import static net.emustudio.plugins.compiler.asZ80.CompileError.couldNotReadFile; +import static net.emustudio.plugins.compiler.asZ80.CompileError.infiniteLoopDetected; + +/** + * Integrate "include" files and remove PseudoInclude + */ +public class ExpandIncludesVisitor extends NodeVisitor { + private final Set includedFiles; // TODO: windows platform case-insensitive! + + public ExpandIncludesVisitor() { + this.includedFiles = Collections.emptySet(); + } + + public ExpandIncludesVisitor(Set includedFiles) { + this.includedFiles = Objects.requireNonNull(includedFiles); + } + + @Override + public void visit(PseudoInclude node) { + if (includedFiles.contains(node.filename)) { + fatalError(infiniteLoopDetected(node, "include")); + } + + try { + As8080Lexer lexer = new As8080Lexer(CharStreams.fromFileName(node.filename)); + CommonTokenStream stream = new CommonTokenStream(lexer); + As8080Parser parser = new As8080Parser(stream); + stream.fill(); + ParseTree tree = parser.rStart(); + Program program = new Program(node.line, node.column, env); + program.setFileName(node.filename); + + new CreateProgramVisitor(program).visit(tree); + + Set alreadyIncludedFiles = new HashSet<>(includedFiles); + alreadyIncludedFiles.add(node.filename); + new ExpandIncludesVisitor(alreadyIncludedFiles).visit(program); + + node.addChildren(program.getChildren()); + node.exclude(); + } catch (IOException e) { + error(couldNotReadFile(node, node.filename, e)); + } + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java new file mode 100644 index 000000000..28e3dc7a9 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java @@ -0,0 +1,81 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroCall; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroDef; + +import java.util.*; + +import static net.emustudio.plugins.compiler.asZ80.CompileError.infiniteLoopDetected; +import static net.emustudio.plugins.compiler.asZ80.CompileError.notDefined; +import static net.emustudio.plugins.compiler.asZ80.ParsingUtils.normalizeId; + +/** + * Expands macros. It means - find macro definitions, remove them from the parent node and put them as a child under + * each macro call. It supports forward references too. + * + * It doesn't mean the macro expansion will be used in code yet. + */ +public class ExpandMacrosVisitor extends NodeVisitor { + private final Map macros = new HashMap<>(); + private final Map> forwardMacroCalls = new HashMap<>(); + + @Override + public void visit(Program node) { + visitChildren(node); + for (Map.Entry> entry : forwardMacroCalls.entrySet()) { + error(notDefined(entry.getValue().get(0), "Macro '" + entry.getKey() + "'")); + } + } + + @Override + public void visit(PseudoMacroDef node) { + String id = normalizeId(node.id); + + // save macro + macros.put(id, node); + node.remove(); + + // expand macro if we had earlier calls (as a forward reference) + if (forwardMacroCalls.containsKey(id)) { + for (PseudoMacroCall macroCall : forwardMacroCalls.remove(id)) { + Node def = node.copy(); + macroCall.addChild(def); + visitChildren(def); // b/c original node does not have a parent + } + } else { + visitChildren(node); + } + } + + @Override + public void visit(PseudoMacroCall node) { + String id = normalizeId(node.id); + if (macros.containsKey(id)) { + node.addChild(macros.get(id).copy()); + checkInfiniteLoop(node); + } else { + // maybe the macro is defined later + forwardMacroCalls.putIfAbsent(id, new ArrayList<>()); + List macroCalls = forwardMacroCalls.get(id); + macroCalls.add(node); + } + } + + private void checkInfiniteLoop(PseudoMacroCall node) { + String id = normalizeId(node.id); + Optional parent = node.getParent(); + while (parent.isPresent()) { + // search all parents to the top for PseudoMacroDef + Node parentValue = parent.get(); + if (parentValue instanceof PseudoMacroDef) { + String parentId = normalizeId(((PseudoMacroDef) parentValue).id); + if (parentId.equals(id)) { + fatalError(infiniteLoopDetected(node, "macro call '" + id + "'")); + } + } + parent = parentValue.getParent(); + } + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java new file mode 100644 index 000000000..a5cfcb403 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java @@ -0,0 +1,119 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.emulib.runtime.io.IntelHEX; +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; +import net.emustudio.plugins.compiler.asZ80.ast.instr.*; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoOrg; + +import java.util.Objects; + +import static net.emustudio.plugins.compiler.asZ80.CompileError.valueMustBePositive; +import static net.emustudio.plugins.compiler.asZ80.CompileError.valueOutOfBounds; + +public class GenerateCodeVisitor extends NodeVisitor { + private final IntelHEX hex; + private int expectedBytes; + + public GenerateCodeVisitor(IntelHEX hex) { + this.hex = Objects.requireNonNull(hex); + } + + @Override + public void visit(DataDB node) { + expectedBytes = 1; + visitChildren(node); + } + + @Override + public void visit(DataDW node) { + expectedBytes = 2; + visitChildren(node); + } + + @Override + public void visit(DataDS node) { + node.collectChild(Evaluated.class) + .ifPresent(e -> { + if (e.value < 0) { + error(valueMustBePositive(e)); + } else { + for (int i = 0; i < e.value; i++) { + hex.add((byte) 0); + } + } + }); + } + + @Override + public void visit(InstrExpr node) { + node.eval() + .ifPresentOrElse( + hex::add, + () -> error(valueOutOfBounds(node, 0, 7)) + ); + expectedBytes = node.getExprSizeBytes(); + visitChildren(node); + } + + @Override + public void visit(InstrNoArgs node) { + hex.add(node.eval()); + } + + @Override + public void visit(InstrReg node) { + hex.add(node.eval()); + } + + @Override + public void visit(InstrRegExpr node) { + hex.add(node.eval()); + expectedBytes = 1; + visitChildren(node); + } + + @Override + public void visit(InstrRegPair node) { + hex.add(node.eval()); + } + + @Override + public void visit(InstrRegPairExpr node) { + hex.add(node.eval()); + expectedBytes = 2; + visitChildren(node); + } + + @Override + public void visit(InstrRegReg node) { + hex.add(node.eval()); + } + + @Override + public void visit(PseudoOrg node) { + node.collectChild(Evaluated.class) + .ifPresent(e -> { + if (e.value < 0) { + error(valueMustBePositive(node)); + } else { + hex.setNextAddress(e.value); + } + }); + } + + @Override + public void visit(Evaluated node) { + if (expectedBytes == 1) { + hex.add((byte) (node.value & 0xFF)); + } else if (expectedBytes == 2) { + byte byte0 = (byte) (node.value & 0xFF); + byte byte1 = (byte) (node.value >>> 8); + + hex.add(byte0); + hex.add(byte1); + } + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java new file mode 100644 index 000000000..72bce216c --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java @@ -0,0 +1,164 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.CompileError; +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.NameSpace; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; +import net.emustudio.plugins.compiler.asZ80.ast.expr.*; +import net.emustudio.plugins.compiler.asZ80.ast.instr.*; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; +import net.emustudio.plugins.compiler.asZ80.exceptions.FatalError; + +import java.util.List; + +public class NodeVisitor { + protected NameSpace env; + + protected void error(CompileError error) { + env.error(error); + } + + protected void fatalError(CompileError error) { + FatalError.now(error); + } + + public void visit(Node node) { + visitChildren(node); + } + + public void visit(Program node) { + if (env == null) { + this.env = node.env(); + } + visitChildren(node); + } + + public void visit(DataDB node) { + visitChildren(node); + } + + public void visit(DataDW node) { + visitChildren(node); + } + + public void visit(DataDS node) { + visitChildren(node); + } + + public void visit(ExprCurrentAddress node) { + visitChildren(node); + } + + public void visit(ExprInfix node) { + visitChildren(node); + } + + public void visit(ExprId node) { + visitChildren(node); + } + + public void visit(ExprString node) { + visitChildren(node); + } + + public void visit(ExprNumber node) { + visitChildren(node); + } + + public void visit(ExprUnary node) { + visitChildren(node); + } + + public void visit(InstrExpr node) { + visitChildren(node); + } + + public void visit(InstrNoArgs node) { + visitChildren(node); + } + + public void visit(InstrReg node) { + visitChildren(node); + } + + public void visit(InstrRegExpr node) { + visitChildren(node); + } + + public void visit(InstrRegPair node) { + visitChildren(node); + } + + public void visit(InstrRegPairExpr node) { + visitChildren(node); + } + + public void visit(InstrRegReg node) { + visitChildren(node); + } + + public void visit(PseudoEqu node) { + visitChildren(node); + } + + public void visit(PseudoIf node) { + visitChildren(node); + } + + public void visit(PseudoIfExpression node) { + visitChildren(node); + } + + public void visit(PseudoInclude node) { + visitChildren(node); + } + + public void visit(PseudoMacroCall node) { + visitChildren(node); + } + + public void visit(PseudoMacroArgument node) { + visitChildren(node); + } + + public void visit(PseudoMacroParameter node) { + visitChildren(node); + } + + public void visit(PseudoMacroDef node) { + visitChildren(node); + } + + public void visit(PseudoOrg node) { + visitChildren(node); + } + + public void visit(PseudoSet node) { + visitChildren(node); + } + + public void visit(PseudoLabel node) { + visitChildren(node); + } + + public void visit(Evaluated node) { + visitChildren(node); + } + + protected void visitChildren(Node node) { + for (Node child : node.getChildren()) { + child.accept(this); + } + } + + protected void visitChildren(Node node, int skipFirstN) { + List children = node.getChildren(); + for (int i = skipFirstN; i < children.size(); i++) { + children.get(i).accept(this); + } + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitor.java new file mode 100644 index 000000000..21b4348d7 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitor.java @@ -0,0 +1,98 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroArgument; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroCall; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroDef; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroParameter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.CompileError.macroArgumentsDoNotMatch; +import static net.emustudio.plugins.compiler.asZ80.ParsingUtils.normalizeId; + +/** + * Connects macro parameters with arguments. + * Example input: + *

+ * PseudoMacroCall
+ *   PseudoMacroArgument
+ *     ExprNumber(1)
+ *   PseudoMacroArgument
+ *     ExprNumber(2)
+ *   PseudoMacroDef
+ *     PseudoMacroParameter
+ *       ExprId(q)
+ *     PseudoMacroParameter
+ *       ExprId(r)
+ *     ...
+ * 
+ *

+ * Example output: + *

+ * PseudoMacroCall
+ *   PseudoMacroArgument
+ *     ExprId(q)
+ *     ExprNumber(1)
+ *   PseudoMacroArgument
+ *     ExprId(r)
+ *     ExprNumber(2)
+ *   ...
+ * 
+ */ +public class SortMacroArgumentsVisitor extends NodeVisitor { + + private final Map> macroArguments = new HashMap<>(); + private final Map> macroParameters = new HashMap<>(); + private String currentMacroCall; + private String currentMacroDef; + + @Override + public void visit(PseudoMacroCall node) { + currentMacroCall = normalizeId(node.id); + macroArguments.put(currentMacroCall, new ArrayList<>()); + visitChildren(node); + } + + @Override + public void visit(PseudoMacroArgument node) { + macroArguments.get(currentMacroCall).add(node); + } + + @Override + public void visit(PseudoMacroDef node) { + currentMacroDef = normalizeId(node.id); + macroParameters.put(currentMacroDef, new ArrayList<>()); + + String origMacroDef = currentMacroDef; // we can have macro calls inside this macro + visitChildren(node); + + // there should not be recursive macro calls (assured by ExpandMacrosVisitor) + List origMacroParams = macroParameters.get(origMacroDef); + List origMacroArguments = macroArguments.get(origMacroDef); + + if (origMacroArguments.size() != origMacroParams.size()) { + error(macroArgumentsDoNotMatch(node)); // better would be to have macro call instead of macro def + } else { + for (int i = 0; i < origMacroArguments.size(); i++) { + Node macroParam = origMacroParams.get(i); + macroParam.remove(); + + Node macroArgument = origMacroArguments.get(i); + macroParam + .collectChild(ExprId.class) + .ifPresentOrElse(macroArgument::addChildFirst, () -> error(macroArgumentsDoNotMatch(node))); + } + node.exclude(); + } + } + + @Override + public void visit(PseudoMacroParameter node) { + macroParameters.get(currentMacroDef).add(node); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/CompilerImplTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/CompilerImplTest.java deleted file mode 100644 index e4f661b66..000000000 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/CompilerImplTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80; - -import org.junit.Test; - -import static org.junit.Assert.assertNotEquals; - -public class CompilerImplTest extends AbstractCompilerTest { - - @Test - public void testVersionIsKnown() { - assertNotEquals("(unknown)", compiler.getVersion()); - } - - @Test - public void testCopyrightIsKnown() { - assertNotEquals("(unknown)", compiler.getCopyright()); - } - - @Test - public void testForwardAbsoluteJump() throws Exception { - compile( - "now: ld a, b\n" + - "cp \"C\"\n" + - "jp z, ler\n" + - "ler: ld (hl), a" - ); - - assertProgram( - 0x78, 0xFE, 0x43, 0xCA, 0x06, 0x00, 0x77 - ); - } - - @Test - public void testBackwardAbsoluteJump() throws Exception { - compile( - "now: ld a,b\n" + - "cp \"C\"\n" + - "jp z, now\n" + - "ler: ld (hl), a" - ); - - assertProgram( - 0x78, 0xFE, 0x43, 0xCA, 0x00, 0x00, 0x77 - ); - } - - @Test - public void testForwardRelativeJump() throws Exception { - compile( - "now: ld a, b\n" + - "cp \"C\"\n" + - "jp z, ler\n" + - "ler: ld (hl), a" - ); - - assertProgram( - 0x78, 0xFE, 0x43, 0xCA, 0x06, 0x00, 0x77 - ); - } - - @Test(expected = Exception.class) - public void testRSTtooBigArgument() throws Exception { - compile("rst 40h"); - } - - @Test - public void testRelativeJumpForward() throws Exception { - compile( - "loop: ld A, 0\n" + - "cp 0\n" + - "jr Z, end\n" + - "jp loop\n" + - "\n" + - "end:\n" + - "halt\n" - ); - - assertProgram( - 0x3E, 0, 0xFE, 0, 0x28, 3, 0xC3, 0, 0, 0x76 - ); - } - - @Test - public void testRelativeJumpBackward() throws Exception { - compile( - "loop: ld A, 0\n" + - "cp 0\n" + - "jr Z, loop\n" + - "jp loop\n" + - "\n" + - "end:\n" + - "halt\n" - ); - - assertProgram( - 0x3E, 0, 0xFE, 0, 0x28, (-6) & 0xFF, 0xC3, 0, 0, 0x76 - ); - } - - @Test(expected = Exception.class) - public void testRelativeJumpTooFarBackwards() throws Exception { - compile( - "loop: ld A,0\n" + - "org 130h\n" + - "cp 0\n" + - "jr loop\n" + - "halt" - ); - } - - @Test(expected = Exception.class) - public void testRelativeJumpTooFarForwards() throws Exception { - compile( - "loop: ld A,0\n" + - "cp 0\n" + - "jr end\n" + - "org 130h\n" + - "end:\n" + - "halt" - ); - } - - @Test - public void testDJNZ() throws Exception { - compile( - "loop: ld B,1\n" + - "djnz loop\n" + - "halt" - ); - - assertProgram( - 0x06, 1, 0x10, (-4) & 0xFF, 0x76 - ); - } - - @Test(expected = Exception.class) - public void testDJNZtooFarBackwards() throws Exception { - compile( - "loop: ld B,1\n" + - "org 130h\n" + - "djnz loop\n" + - "halt" - ); - } - - @Test(expected = Exception.class) - public void testDJNZtooFarForwards() throws Exception { - compile( - "djnz end\n" + - "org 130h\n" + - "end:\n" + - "halt" - ); - } -} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java new file mode 100644 index 000000000..06c5bc71c --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java @@ -0,0 +1,134 @@ +package net.emustudio.plugins.compiler.asZ80; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.visitors.CreateProgramVisitor; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTree; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.function.Consumer; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import static org.junit.Assert.assertEquals; + +public class Utils { + public static Map registers = Map.of( + "a", REG_A, + "b", REG_B, + "c", REG_C, + "d", REG_D, + "e", REG_E, + "h", REG_H, + "l", REG_L, + "m", REG_M + ); + + public static Map regPairsBD = Map.of( + "b", REG_B, + "d", REG_D + ); + public static Map regPairsBDHSP = Map.of( + "b", REG_B, + "d", REG_D, + "h", REG_H, + "sp", REG_SP + ); + public static Map regPairsBDHPSW = Map.of( + "b", REG_B, + "d", REG_D, + "h", REG_H, + "psw", REG_PSW + ); + + + public static List getTokens(String variation) { + AsZ80Lexer lexer = new AsZ80Lexer(CharStreams.fromString(variation)); + CommonTokenStream stream = new CommonTokenStream(lexer); + stream.fill(); + return stream.getTokens(); + } + + public static ParseTree parse(String program) { + AsZ80Lexer lexer = new AsZ80Lexer(CharStreams.fromString(program)); + CommonTokenStream stream = new CommonTokenStream(lexer); + AsZ80Parser parser = new AsZ80Parser(stream); + parser.removeErrorListeners(); + parser.addErrorListener(new ParserErrorListener()); + stream.fill(); + return parser.rStart(); + } + + public static Program parseProgram(String programString) { + ParseTree tree = parse(programString); + Program program = new Program(); + CreateProgramVisitor visitor = new CreateProgramVisitor(program); + visitor.visit(tree); + return program; + } + + public static void assertTokenTypes(String variation, int... expectedTypes) { + List tokens = getTokens(variation); + assertTokenTypes(tokens, expectedTypes); + } + + public static void assertTokenTypes(List tokens, int... expectedTypes) { + assertEquals("Tokens: " + tokens, expectedTypes.length, tokens.size()); + for (int i = 0; i < expectedTypes.length; i++) { + Token token = tokens.get(i); + assertEquals(token.toString(), expectedTypes[i], token.getType()); + } + } + + public static void assertTokenTypesIgnoreCase(String base, int... expectedTypes) { + forStringCaseVariations(base, variation -> assertTokenTypes(variation, expectedTypes)); + } + + public static void forStringCaseVariations(String base, Consumer f) { + Random r = new Random(); + List variations = new ArrayList<>(); + variations.add(base); + variations.add(base.toLowerCase()); + variations.add(base.toUpperCase()); + for (int i = 0; i < 5; i++) { + byte[] chars = base.getBytes(); + for (int j = 0; j < base.length(); j++) { + if (r.nextBoolean()) { + chars[j] = Character.valueOf((char) chars[j]).toString().toUpperCase().getBytes()[0]; + } else { + chars[j] = Character.valueOf((char) chars[j]).toString().toLowerCase().getBytes()[0]; + } + } + variations.add(new String(chars)); + } + for (String variation: variations) { + f.accept(variation); + } + } + + public static void assertTrees(Node expected, Node result) { + assertEquals("Children size does not match", expected.getChildren().size(), result.getChildren().size()); + assertEquals("Nodes are different", expected.getClass(), result.getClass()); + for (int i = 0; i < expected.getChildren().size(); i++) { + Node expectedChild = expected.getChild(i); + Node resultChild = result.getChild(i); + assertEquals(expectedChild, resultChild); + assertTrees(expectedChild, resultChild); + } + } + + public static void write(File file, String content) throws IOException { + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + writer.write(content); + writer.close(); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/AbstractCompilerTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java similarity index 60% rename from plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/AbstractCompilerTest.java rename to plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java index 58fc4a2cc..8ba04aa6b 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/AbstractCompilerTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java @@ -16,17 +16,18 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.asZ80; - +package net.emustudio.plugins.compiler.asZ80.e2e; +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.cpu.testsuite.memory.MemoryStub; -import net.emustudio.cpu.testsuite.memory.ShortMemoryStub; +import net.emustudio.emulib.plugins.compiler.CompilerListener; +import net.emustudio.emulib.plugins.compiler.CompilerMessage; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; -import net.emustudio.plugins.compiler.asZ80.CompilerImpl; +import net.emustudio.plugins.compiler.asZ80.AssemblerZ80; import org.junit.Before; import org.junit.Rule; import org.junit.rules.TemporaryFolder; @@ -39,8 +40,8 @@ import static org.junit.Assert.assertEquals; public abstract class AbstractCompilerTest { - protected CompilerImpl compiler; - protected MemoryStub memoryStub; + protected AssemblerZ80 compiler; + protected MemoryStub memoryStub; @Rule public TemporaryFolder folder = new TemporaryFolder(); @@ -48,17 +49,31 @@ public abstract class AbstractCompilerTest { @SuppressWarnings("unchecked") @Before public void setUp() throws Exception { - memoryStub = new ShortMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); + memoryStub = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); - ContextPool pool = createNiceMock(ContextPool.class); - expect(pool.getMemoryContext(0, MemoryContext.class)).andReturn(memoryStub).anyTimes(); - replay(pool); + ContextPool contextPool = createNiceMock(ContextPool.class); + expect(contextPool.getMemoryContext(0, MemoryContext.class)).andReturn(memoryStub).anyTimes(); + replay(contextPool); ApplicationApi applicationApi = createNiceMock(ApplicationApi.class); - expect(applicationApi.getContextPool()).andReturn(pool).anyTimes(); + expect(applicationApi.getContextPool()).andReturn(contextPool); replay(applicationApi); - compiler = new CompilerImpl(0L, applicationApi, PluginSettings.UNAVAILABLE); + compiler = new AssemblerZ80(0L, applicationApi, PluginSettings.UNAVAILABLE); + compiler.addCompilerListener(new CompilerListener() { + @Override + public void onStart() { + } + + @Override + public void onMessage(CompilerMessage message) { + System.out.println(message); + } + + @Override + public void onFinish() { + } + }); compiler.initialize(); } @@ -68,21 +83,21 @@ protected void compile(String content) throws Exception { File outputFile = folder.newFile(); if (!compiler.compile(sourceFile.getAbsolutePath(), outputFile.getAbsolutePath())) { - throw new Exception("Compilation error"); + throw new Exception("Compilation failed"); } } protected void assertProgram(int... bytes) { for (int i = 0; i < bytes.length; i++) { assertEquals( - String.format("%d. expected=%x, but was=%x", i, bytes[i], memoryStub.read(i)), - bytes[i], (int) memoryStub.read(i) + String.format("[addr=%x] expected=%x, but was=%x", i, bytes[i], memoryStub.read(i)), + (byte)bytes[i], memoryStub.read(i).byteValue() ); } for (int i = bytes.length; i < memoryStub.getSize(); i++) { assertEquals( - String.format("%d. expected=%x, but was=%x", i, 0, memoryStub.read(i)), - 0, (int) memoryStub.read(i) + String.format("[addr=%x] expected=%x, but was=%x", i, 0, memoryStub.read(i)), + 0, memoryStub.read(i).byteValue() ); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java new file mode 100644 index 000000000..10d216987 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java @@ -0,0 +1,148 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2020 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.compiler.asZ80.e2e; + +import org.junit.Test; + +import static org.junit.Assert.assertNotEquals; + +public class AssemblerZ80Test extends AbstractCompilerTest { + + @Test + public void testVersionIsKnown() { + assertNotEquals("(unknown)", compiler.getVersion()); + } + + @Test + public void testCopyrightIsKnown() { + assertNotEquals("(unknown)", compiler.getCopyright()); + } + + @Test + public void testForwardAbsoluteJump() throws Exception { + compile( + "now: ld a,b\n" + + "cp 'C'\n" + + "jp z, ler\n" + + "ler: ld (HL), a" + ); + + assertProgram( + 0x78, 0xFE, 0x43, 0xCA, 0x06, 0x00, 0x77 + ); + } + + @Test + public void testBackwardAbsoluteJump() throws Exception { + compile( + "now: ld a,b\n" + + "cp 'C'\n" + + "jp z, now\n" + + "ler: ld (HL), a" + ); + + assertProgram( + 0x78, 0xFE, 0x43, 0xCA, 0x00, 0x00, 0x77 + ); + } + + @Test + public void testCallBackward() throws Exception { + compile( + "dec sp\n" + + "now: ld a,b\n" + + "cp 'C'\n" + + "call now\n" + + "ler: ld (HL), a" + ); + + assertProgram( + 0x3B, 0x78, 0xFE, 0x43, 0xCD, 0x01, 0x00, 0x77 + ); + } + + @Test + public void testCallForward() throws Exception { + compile( + "dec sp\n" + + "now: ld a,b\n" + + "cp 'C'\n" + + "call ler\n" + + "ler: ld (HL), a" + ); + + assertProgram( + 0x3B, 0x78, 0xFE, 0x43, 0xCD, 0x07, 0x00, 0x77 + ); + } + + @Test(expected = Exception.class) + public void testRSTtooBigArgument() throws Exception { + compile("rst 10"); + } + + + @Test + public void testDECwithLD() throws Exception { + compile( + "dec sp\n" + + "ld hl, text\n" + + "text:\n" + + "db 'ahoj'" + ); + + assertProgram( + 0x3B, 0x21, 0x04, 0, 'a', 'h', 'o', 'j' + ); + } + + @Test + public void testINthenJMP() throws Exception { + compile( + "jp sample\n" + + "in a, (10h)\n" + + "sample:\n" + + "ld a, b\n" + ); + + assertProgram( + 0xC3, 0x5, 0, 0xDB, 0x10, 0x78 + ); + } + + @Test + public void testGetChar() throws Exception { + compile( + "jp sample\n" + + "getchar:\n" + + "in a, (10h)\n" + + "and 1\n" + + "jp z, getchar\n" + + "in a, (11h)\n" + + "out (11h), a\n" + + "ret\n" + + "sample:\n" + + "ld a, b" + ); + + assertProgram( + 0xC3, 0x0F, 0, 0xDB, 0x10, 0xE6, 1, 0xCA, 0x03, 0, 0xDB, 0x11, 0xD3, 0x11, 0xC9, 0x78 + ); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/ConstantsAndVariablesTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/ConstantsAndVariablesTest.java similarity index 92% rename from plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/ConstantsAndVariablesTest.java rename to plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/ConstantsAndVariablesTest.java index a81c5f8fb..071b92d16 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/ConstantsAndVariablesTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/ConstantsAndVariablesTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.asZ80; +package net.emustudio.plugins.compiler.asZ80.e2e; import org.junit.Test; @@ -48,14 +48,13 @@ public void testConstantAsLabelWorks() throws Exception { ); } - @Test + @Test(expected = Exception.class) public void testRecursiveConstantDefinitionsDoesNotWork() throws Exception { compile( "here equ there\n" + "there equ here\n" + "jp z, here" ); - assertProgram(0xCA, 0, 0); } @Test(expected = Exception.class) @@ -75,9 +74,8 @@ public void testTwoSameConstantsDoNotWork() throws Exception { @Test public void testVariableCanBeOverwritten() throws Exception { compile( - "here var 0\nhere var 1\ncp here" + "here set 0\nhere set 1\ncp here" ); - assertProgram( 0xFE, 1 ); @@ -99,18 +97,18 @@ public void testCannotDefineConstantBecauseIdentifierIsAlreadyDefined() throws E @Test public void testForwardReferenceOfConstantShouldWork() throws Exception { - compile("LD SP,STACK\n" + + compile("ld SP,STACK\n" + "TEMPP: DW TEMP0\n" + "TEMP0: DS 1\n" + "STACK EQU TEMPP+256"); assertProgram( - 0x31, 0x03, 0x01, 0x05, 0, 0 + 0x31, 0x03, 0x01, 5, 0, 0 ); } @Test(expected = Exception.class) public void testUnknownIdentifier() throws Exception { - compile("LD SP,STACK"); + compile("ld SP,STACK"); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/DataTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java similarity index 88% rename from plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/DataTest.java rename to plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java index 8d86b4888..7b372b958 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/DataTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.asZ80; +package net.emustudio.plugins.compiler.asZ80.e2e; import org.junit.Test; @@ -69,7 +69,7 @@ public void testDBseveralBytesWork() throws Exception { @Test public void testDBWithInstruction() throws Exception { compile( - "db inc A\n" + "db inr A\n" ); assertProgram( @@ -80,7 +80,7 @@ public void testDBWithInstruction() throws Exception { @Test public void testDBliteral() throws Exception { compile( - "db \"if\"\n" + "db 'if'\n" ); assertProgram( @@ -91,7 +91,7 @@ public void testDBliteral() throws Exception { @Test public void testDBshortLiteral() throws Exception { compile( - "db \"i\"\n" + "db 'i'\n" ); assertProgram( @@ -99,7 +99,6 @@ public void testDBshortLiteral() throws Exception { ); } - @Test public void testDWwithNegativeValueWorks() throws Exception { compile( @@ -148,7 +147,7 @@ public void testDWmoreThanFFFFdoesNotWork() throws Exception { public void testDW_ValueTooBig() throws Exception { compile( "org 0FFFFh\n" - + "rrc\n" + + "rrca\n" + "test:\n" + "dw test" ); @@ -163,8 +162,8 @@ public void testDSwithNegativeValueDoesNotWork() throws Exception { @Test public void testDSbreaksPreviousMemoryContent() throws Exception { - memoryStub.write(0, (short) 0x10); - memoryStub.write(1, (short) 0x11); + memoryStub.write(0, (byte) 0x10); + memoryStub.write(1, (byte) 0x11); compile( "ds 2\n" + "now: ld a,b\n" @@ -181,23 +180,13 @@ public void testJumpBackwardWithDSamong() throws Exception { "ds 2\n" + "now: ld a,b\n" + "ds 2\n" + - "cp \"C\"\n" + + "cp 'C'\n" + "jp z, now\n" + - "ler: ld (hl), a" + "ler: ld (HL), a" ); assertProgram( 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 ); } - - @Test(expected = Exception.class) - public void testDS_ValueTooBig() throws Exception { - compile( - "org 0FFh\n" - + "rrca\n" - + "test:\n" - + "ds test" - ); - } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/IfNodeTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IfNodeTest.java similarity index 86% rename from plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/IfNodeTest.java rename to plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IfNodeTest.java index f78f9ec9e..2ed698acb 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/IfNodeTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IfNodeTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.asZ80; +package net.emustudio.plugins.compiler.asZ80.e2e; import org.junit.Test; @@ -73,16 +73,6 @@ public void testIfCanEvaluateBackwardReferenceInExpression() throws Exception { ); } - @Test(expected = Exception.class) - public void testIfCannotEvaluateForwardReferenceInExpression() throws Exception { - compile( - "if present\n" - + " rrca\n" - + "endif\n" - + "present equ 1\n" - ); - } - @Test(expected = Exception.class) public void testIfCannotRedefineIdentifierInside() throws Exception { compile( diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/IncludeTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IncludeTest.java similarity index 81% rename from plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/IncludeTest.java rename to plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IncludeTest.java index b188b22f2..0bd0ff793 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/IncludeTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IncludeTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.asZ80; +package net.emustudio.plugins.compiler.asZ80.e2e; import org.junit.Test; @@ -29,11 +29,11 @@ public void testIncludeAndForwardCall() throws Exception { File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( "call sample\n" - + "include \"" + includeFile.getAbsolutePath() + "\"\n" + + "include '" + includeFile.getAbsolutePath() + "'\n" ); assertProgram( - 0xCD, 03, 00, 0x3E, 0, 0xC9 + 0xCD, 0x03, 0x00, 0x3E, 0, 0xC9 ); } @@ -43,8 +43,8 @@ public void testDoubleIncludeAndForwardCall() throws Exception { File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( "call sample2\n" - + "include \"" + first.getAbsolutePath() + "\"\n" - + "include \"" + second.getAbsolutePath() + "\"\n" + + "include '" + first.getAbsolutePath() + "'\n" + + "include '" + second.getAbsolutePath() + "'\n" ); assertProgram( @@ -56,7 +56,7 @@ public void testDoubleIncludeAndForwardCall() throws Exception { public void testIncludeAndBackwardCall() throws Exception { File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( - "include \"" + includeFile.getAbsolutePath() + "\"\n" + "include '" + includeFile.getAbsolutePath() + "'\n" + "call sample\n" ); @@ -70,8 +70,8 @@ public void testDoubleIncludeAndBackwardCall() throws Exception { File first = new File(getClass().getResource("/sample.asm").toURI()); File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( - "include \"" + first.getAbsolutePath() + "\"\n" - + "include \"" + second.getAbsolutePath() + "\"\n" + "include '" + first.getAbsolutePath() + "'\n" + + "include '" + second.getAbsolutePath() + "'\n" + "call sample\n" ); @@ -85,7 +85,7 @@ public void testIncludeAndJMPafter() throws Exception { File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( "jp next\n" - + "include \"" + includeFile.getAbsolutePath() + "\"\n" + + "include '" + includeFile.getAbsolutePath() + "'\n" + "next:\n" + "ld a, b\n" ); @@ -101,8 +101,8 @@ public void testDoubleIncludeAndJMPafter() throws Exception { File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( "jp next\n" - + "include \"" + first.getAbsolutePath() + "\"\n" - + "include \"" + second.getAbsolutePath() + "\"\n" + + "include '" + first.getAbsolutePath() + "'\n" + + "include '" + second.getAbsolutePath() + "'\n" + "next:\n" + "ld a, b\n" ); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java new file mode 100644 index 000000000..a352acfc8 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java @@ -0,0 +1,20 @@ +package net.emustudio.plugins.compiler.asZ80.e2e; + +import org.junit.Test; + +public class InstrExprTest extends AbstractCompilerTest { + + @Test + public void testRST() throws Exception { + compile( + "JP EXAMPLE\n" + + "RST 00H\n" + + "EXAMPLE:\n" + + "ld A,01H" + ); + + assertProgram( + 0xC3, 0x04, 0x00, 0xC7, 0x3E, 0x01 + ); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java new file mode 100644 index 000000000..bf2bc0721 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java @@ -0,0 +1,204 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2020 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.compiler.asZ80.e2e; + +import org.junit.Test; + +public class InstrRegTest extends AbstractCompilerTest { + + @Test + public void testINR() throws Exception { + compile( + "inr A\n" + + "inc B\n" + + "inc C\n" + + "inc D\n" + + "inc E\n" + + "inc H\n" + + "inc L\n" + + "inc (HL)\n" + ); + + assertProgram( + 0x3C, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34 + ); + } + + @Test + public void testDCR() throws Exception { + compile( + "dcr A\n" + + "dec B\n" + + "dec C\n" + + "dec D\n" + + "dec E\n" + + "dec H\n" + + "dec L\n" + + "dec (HL)\n" + ); + + assertProgram( + 0x3D, 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, 0x35 + ); + } + + @Test + public void testADD() throws Exception { + compile( + "add A\n" + + "add A,B\n" + + "add A,C\n" + + "add A,D\n" + + "add A,E\n" + + "add A,H\n" + + "add A,L\n" + + "add A,(HL)\n" + ); + + assertProgram( + 0x87, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86 + ); + } + + @Test + public void testADC() throws Exception { + compile( + "adc A\n" + + "adc A,B\n" + + "adc A,C\n" + + "adc A,D\n" + + "adc A,E\n" + + "adc A,H\n" + + "adc A,L\n" + + "adc A,(HL)\n" + ); + + assertProgram( + 0x8F, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E + ); + } + + @Test + public void testSUB() throws Exception { + compile( + "sub A\n" + + "sub B\n" + + "sub C\n" + + "sub D\n" + + "sub E\n" + + "sub H\n" + + "sub L\n" + + "sub (HL)\n" + ); + + assertProgram( + 0x97, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96 + ); + } + + @Test + public void testSBC() throws Exception { + compile( + "sbc A,A\n" + + "sbc A,B\n" + + "sbc A,C\n" + + "sbc A,D\n" + + "sbc A,E\n" + + "sbc A,H\n" + + "sbc A,L\n" + + "sbc A,(HL)\n" + ); + + assertProgram( + 0x9F, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E + ); + } + + @Test + public void testAND() throws Exception { + compile( + "and A\n" + + "and B\n" + + "and C\n" + + "and D\n" + + "and E\n" + + "and H\n" + + "and L\n" + + "and (HL)\n" + ); + + assertProgram( + 0xA7, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6 + ); + } + + @Test + public void testXOR() throws Exception { + compile( + "xor A\n" + + "xor B\n" + + "xor C\n" + + "xor D\n" + + "xor E\n" + + "xor H\n" + + "xor L\n" + + "xor (HL)\n" + ); + + assertProgram( + 0xAF, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE + ); + } + + @Test + public void testOR() throws Exception { + compile( + "or A\n" + + "or B\n" + + "or C\n" + + "or D\n" + + "or E\n" + + "or H\n" + + "or L\n" + + "or (HL)\n" + ); + + assertProgram( + 0xB7, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6 + ); + } + + @Test + public void testCP() throws Exception { + compile( + "cp A\n" + + "cp B\n" + + "cp C\n" + + "cp D\n" + + "cp E\n" + + "cp H\n" + + "cp L\n" + + "cp (HL)\n" + ); + + assertProgram( + 0xBF, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE + ); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/MacroTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/MacroTest.java similarity index 86% rename from plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/MacroTest.java rename to plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/MacroTest.java index 3042aadcd..f4baa53b2 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/MacroTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/MacroTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.asZ80; +package net.emustudio.plugins.compiler.asZ80.e2e; import org.junit.Test; @@ -64,15 +64,18 @@ public void testMacroWithParams() throws Exception { ); } - @Test(expected = Exception.class) - public void testDBinMacroIsNotVisibleFromOutside() throws Exception { + @Test + public void testDBinMacroIsVisibleFromOutside() throws Exception { compile( "shrt macro\n" + " text: db 0Fh\n" + " and 7Fh\n" + "endm\n\n" + "shrt\n" - + "ld hl, text\n" + + "ld HL, text\n" + ); + assertProgram( + 0x0F, 0xE6, 0x7F, 0x21, 0, 0 ); } @@ -95,22 +98,25 @@ public void testMacroAlreadyDefined() throws Exception { ); } - @Test(expected = Exception.class) - public void testMacroCannotGetForwardLabelReferences() throws Exception { + @Test + public void testMacroCanGetForwardLabelReferences() throws Exception { compile( "shrt macro param\n" - + " ld hl, param\n" + + " ld HL, param\n" + "endm\n" + "shrt text\n" + "text: db 1\n" ); + assertProgram( + 0x21, 3, 0, 1 + ); } @Test(expected = Exception.class) public void testLessMacroParametersThanExpected() throws Exception { compile( "shrt macro param\n" - + " ld hl, param\n" + + " lD HL, param\n" + "endm\n" + "shrt\n" ); @@ -120,7 +126,7 @@ public void testLessMacroParametersThanExpected() throws Exception { public void testMoreMacroParametersThanExpected() throws Exception { compile( "shrt macro param\n" - + " ld hl, param\n" + + " ld HL, param\n" + "endm\n" + "shrt 1, 2\n" ); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/ORGTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/PseudoOrgTest.java similarity index 72% rename from plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/ORGTest.java rename to plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/PseudoOrgTest.java index fb276b7a4..51c3c23a2 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/ORGTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/PseudoOrgTest.java @@ -16,21 +16,31 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.asZ80; +package net.emustudio.plugins.compiler.asZ80.e2e; +import org.junit.Before; import org.junit.Test; -import java.io.File; +import java.util.Objects; + + +public class PseudoOrgTest extends AbstractCompilerTest { + private String sampleFile; + private String sample2File; + + @Before + public void setup() { + sampleFile = Objects.requireNonNull(getClass().getResource("/sample.asm")).getFile(); + sample2File = Objects.requireNonNull(getClass().getResource("/sample2.asm")).getFile(); + } -public class ORGTest extends AbstractCompilerTest { @Test public void testORGwithInclude() throws Exception { - File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( "org 3\n" + "call sample\n" - + "include \"" + includeFile.getAbsolutePath() + "\"\n" + + "include '" + sampleFile + "'\n" ); assertProgram( @@ -40,13 +50,11 @@ public void testORGwithInclude() throws Exception { @Test public void testORGwithDoubleInclude() throws Exception { - File first = new File(getClass().getResource("/sample.asm").toURI()); - File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( "org 3\n" + "call sample\n" - + "include \"" + second.getAbsolutePath() + "\"\n" - + "include \"" + first.getAbsolutePath() + "\"\n" + + "include '" + sample2File + "'\n" + + "include '" + sampleFile + "'\n" ); assertProgram( @@ -56,13 +64,11 @@ public void testORGwithDoubleInclude() throws Exception { @Test public void testORGwithDoubleIncludeAndJMPafter() throws Exception { - File first = new File(getClass().getResource("/sample.asm").toURI()); - File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( "org 3\n" + "jp next\n" - + "include \"" + first.getAbsolutePath() + "\"\n" - + "include \"" + second.getAbsolutePath() + "\"\n" + + "include '" + sampleFile + "'\n" + + "include '" + sample2File + "'\n" + "next:\n" + "ld a, b\n" ); @@ -76,9 +82,9 @@ public void testORGwithDoubleIncludeAndJMPafter() throws Exception { public void testORGwithDB() throws Exception { compile( "org 3\n" - + "ld hl, text\n" + + "ld HL, text\n" + "text:\n" - + "db \"ahoj\"" + + "db 'ahoj'" ); assertProgram( @@ -92,9 +98,9 @@ public void testORG() throws Exception { "org 2\n" + "now: ld a,b\n" + "ds 2\n" + - "cp \"C\"\n" + + "cp 'C'\n" + "jp z, now\n" + - "ler: ld (hl), a" + "ler: ld (HL), a" ); assertProgram( @@ -131,8 +137,8 @@ public void testORGwithJumpForwards() throws Exception { @Test public void testORGdoesNotBreakPreviousMemoryContent() throws Exception { - memoryStub.write(0, (short) 0x10); - memoryStub.write(1, (short) 0x11); + memoryStub.write(0, (byte) 0x10); + memoryStub.write(1, (byte) 0x11); compile( "org 2\n" + "now: ld a,b\n" @@ -159,14 +165,4 @@ public void testORGisAmbiguous() throws Exception { "org text\nld a, 4\ntext: db 4\n" ); } - - @Test - public void testTwoSuccessiveORG() throws Exception { - compile( - "org 2\norg 3\nhalt" - ); - assertProgram( - 0, 0, 0, 0x76 - ); - } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java new file mode 100644 index 000000000..4b61ca484 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java @@ -0,0 +1,246 @@ +package net.emustudio.plugins.compiler.asZ80.parser; + +import org.junit.Test; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Lexer.*; +import static net.emustudio.plugins.compiler.asZ80.Utils.assertTokenTypes; +import static net.emustudio.plugins.compiler.asZ80.Utils.assertTokenTypesIgnoreCase; + +public class LexicalAnalyzerImplTest { + + @Test + public void testParseEols() { + assertTokenTypes("\n\n\n\n\n", EOL, EOL, EOL, EOL, EOL, EOF); + } + + @Test + public void testParseError1() { + assertTokenTypes("B &", REG_B, ERROR, EOF); + } + + @Test + public void testParseError2() { + assertTokenTypes("0x 9o 22b", ERROR, ERROR, ERROR, EOF); + } + + @Test + public void testParseHex1() { + assertTokenTypes( + "0x1 0x0 -0x5f -0xFffF 0x1BC", + LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, OP_SUBTRACT, LIT_HEXNUMBER_1, OP_SUBTRACT, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, EOF + ); + } + + @Test + public void testParseHex2() { + assertTokenTypes( + "1h 0h -5Fh -FFFFh 1BCh 5h -5h", + LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, + LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, EOF + ); + } + + @Test + public void testParseDecimal() { + assertTokenTypes( + "0 1 -2 3 -4 5 66 999", + LIT_NUMBER, LIT_NUMBER, OP_SUBTRACT, LIT_NUMBER, LIT_NUMBER, OP_SUBTRACT, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, + LIT_NUMBER, EOF + ); + } + + @Test + public void testParseOctal() { + assertTokenTypes("-6o 7q 11q -345O", OP_SUBTRACT, LIT_OCTNUMBER, LIT_OCTNUMBER, LIT_OCTNUMBER, OP_SUBTRACT, LIT_OCTNUMBER, EOF); + } + + @Test + public void testParseBinary() { + assertTokenTypes("10101010101010101010110b", LIT_BINNUMBER, EOF); + } + + @Test + public void testParseString1() { + assertTokenTypes("'' 'sss'", LIT_STRING_1, LIT_STRING_1, EOF); + assertTokenTypes("'\nsss'", LIT_STRING_1, EOF); + } + + @Test + public void testParseString2() { + assertTokenTypes("\"\" \"sss\"", LIT_STRING_2, LIT_STRING_2, EOF); + assertTokenTypes("\"\nsss\"", LIT_STRING_2, EOF); + } + + @Test + public void testParseString1Error() { + assertTokenTypes("'open", ERROR, EOF); + } + + @Test + public void testParseString2Error() { + assertTokenTypes("\"open", ERROR, EOF); + } + + @Test + public void testParseComment1() { + assertTokenTypes("// comment fun1", EOF); + assertTokenTypes("# comment fun1", EOF); + assertTokenTypes("; comment fun1", EOF); + } + + @Test + public void testParseComment2() { + assertTokenTypes("/*\n*\n* comment fun1\n\n*/", EOF); + } + + @Test + public void testParseOpcodes() { + assertTokenTypesIgnoreCase("STC", OPCODE_STC, EOF); + assertTokenTypesIgnoreCase("CMC", OPCODE_CMC, EOF); + assertTokenTypesIgnoreCase("CMA", OPCODE_CMA, EOF); + assertTokenTypesIgnoreCase("DAA", OPCODE_DAA, EOF); + assertTokenTypesIgnoreCase("NOP", OPCODE_NOP, EOF); + assertTokenTypesIgnoreCase("RLC", OPCODE_RLC, EOF); + assertTokenTypesIgnoreCase("RRC", OPCODE_RRC, EOF); + assertTokenTypesIgnoreCase("RAL", OPCODE_RAL, EOF); + assertTokenTypesIgnoreCase("RAR", OPCODE_RAR, EOF); + assertTokenTypesIgnoreCase("XCHG", OPCODE_XCHG, EOF); + assertTokenTypesIgnoreCase("XTHL", OPCODE_XTHL, EOF); + assertTokenTypesIgnoreCase("SPHL", OPCODE_SPHL, EOF); + assertTokenTypesIgnoreCase("PCHL", OPCODE_PCHL, EOF); + assertTokenTypesIgnoreCase("RET", OPCODE_RET, EOF); + assertTokenTypesIgnoreCase("RC", OPCODE_RC, EOF); + assertTokenTypesIgnoreCase("RNC", OPCODE_RNC, EOF); + assertTokenTypesIgnoreCase("RZ", OPCODE_RZ, EOF); + assertTokenTypesIgnoreCase("RNZ", OPCODE_RNZ, EOF); + assertTokenTypesIgnoreCase("RM", OPCODE_RM, EOF); + assertTokenTypesIgnoreCase("RP", OPCODE_RP, EOF); + assertTokenTypesIgnoreCase("RPE", OPCODE_RPE, EOF); + assertTokenTypesIgnoreCase("RPO", OPCODE_RPO, EOF); + assertTokenTypesIgnoreCase("EI", OPCODE_EI, EOF); + assertTokenTypesIgnoreCase("DI", OPCODE_DI, EOF); + assertTokenTypesIgnoreCase("HLT", OPCODE_HLT, EOF); + assertTokenTypesIgnoreCase("INR", OPCODE_INR, EOF); + assertTokenTypesIgnoreCase("DCR", OPCODE_DCR, EOF); + assertTokenTypesIgnoreCase("ADD", OPCODE_ADD, EOF); + assertTokenTypesIgnoreCase("ADC", OPCODE_ADC, EOF); + assertTokenTypesIgnoreCase("SUB", OPCODE_SUB, EOF); + assertTokenTypesIgnoreCase("SBB", OPCODE_SBB, EOF); + assertTokenTypesIgnoreCase("ANA", OPCODE_ANA, EOF); + assertTokenTypesIgnoreCase("XRA", OPCODE_XRA, EOF); + assertTokenTypesIgnoreCase("ORA", OPCODE_ORA, EOF); + assertTokenTypesIgnoreCase("CMP", OPCODE_CMP, EOF); + assertTokenTypesIgnoreCase("MOV", OPCODE_MOV, EOF); + assertTokenTypesIgnoreCase("STAX", OPCODE_STAX, EOF); + assertTokenTypesIgnoreCase("LDAX", OPCODE_LDAX, EOF); + assertTokenTypesIgnoreCase("PUSH", OPCODE_PUSH, EOF); + assertTokenTypesIgnoreCase("POP", OPCODE_POP, EOF); + assertTokenTypesIgnoreCase("DAD", OPCODE_DAD, EOF); + assertTokenTypesIgnoreCase("INX", OPCODE_INX, EOF); + assertTokenTypesIgnoreCase("DCX", OPCODE_DCX, EOF); + assertTokenTypesIgnoreCase("LXI", OPCODE_LXI, EOF); + assertTokenTypesIgnoreCase("MVI", OPCODE_MVI, EOF); + assertTokenTypesIgnoreCase("ADI", OPCODE_ADI, EOF); + assertTokenTypesIgnoreCase("ACI", OPCODE_ACI, EOF); + assertTokenTypesIgnoreCase("SUI", OPCODE_SUI, EOF); + assertTokenTypesIgnoreCase("SBI", OPCODE_SBI, EOF); + assertTokenTypesIgnoreCase("ANI", OPCODE_ANI, EOF); + assertTokenTypesIgnoreCase("XRI", OPCODE_XRI, EOF); + assertTokenTypesIgnoreCase("ORI", OPCODE_ORI, EOF); + assertTokenTypesIgnoreCase("CPI", OPCODE_CPI, EOF); + assertTokenTypesIgnoreCase("STA", OPCODE_STA, EOF); + assertTokenTypesIgnoreCase("LDA", OPCODE_LDA, EOF); + assertTokenTypesIgnoreCase("SHLD", OPCODE_SHLD, EOF); + assertTokenTypesIgnoreCase("LHLD", OPCODE_LHLD, EOF); + assertTokenTypesIgnoreCase("JMP", OPCODE_JMP, EOF); + assertTokenTypesIgnoreCase("JC", OPCODE_JC, EOF); + assertTokenTypesIgnoreCase("JNC", OPCODE_JNC, EOF); + assertTokenTypesIgnoreCase("JZ", OPCODE_JZ, EOF); + assertTokenTypesIgnoreCase("JNZ", OPCODE_JNZ, EOF); + assertTokenTypesIgnoreCase("JM", OPCODE_JM, EOF); + assertTokenTypesIgnoreCase("JP", OPCODE_JP, EOF); + assertTokenTypesIgnoreCase("JPE", OPCODE_JPE, EOF); + assertTokenTypesIgnoreCase("JPO", OPCODE_JPO, EOF); + assertTokenTypesIgnoreCase("CALL", OPCODE_CALL, EOF); + assertTokenTypesIgnoreCase("CC", OPCODE_CC, EOF); + assertTokenTypesIgnoreCase("CNC", OPCODE_CNC, EOF); + assertTokenTypesIgnoreCase("CZ", OPCODE_CZ, EOF); + assertTokenTypesIgnoreCase("CNZ", OPCODE_CNZ, EOF); + assertTokenTypesIgnoreCase("CM", OPCODE_CM, EOF); + assertTokenTypesIgnoreCase("CP", OPCODE_CP, EOF); + assertTokenTypesIgnoreCase("CPE", OPCODE_CPE, EOF); + assertTokenTypesIgnoreCase("CPO", OPCODE_CPO, EOF); + assertTokenTypesIgnoreCase("RST", OPCODE_RST, EOF); + assertTokenTypesIgnoreCase("IN", OPCODE_IN, EOF); + assertTokenTypesIgnoreCase("OUT", OPCODE_OUT, EOF); + } + + @Test + public void testParsePreprocessor() { + assertTokenTypesIgnoreCase("ORG", PREP_ORG, EOF); + assertTokenTypesIgnoreCase("EQU", PREP_EQU, EOF); + assertTokenTypesIgnoreCase("SET", PREP_SET, EOF); + assertTokenTypesIgnoreCase("INCLUDE", PREP_INCLUDE, EOF); + assertTokenTypesIgnoreCase("IF", PREP_IF, EOF); + assertTokenTypesIgnoreCase("ENDIF", PREP_ENDIF, EOF); + assertTokenTypesIgnoreCase("MACRO", PREP_MACRO, EOF); + assertTokenTypesIgnoreCase("ENDM", PREP_ENDM, EOF); + assertTokenTypesIgnoreCase("DB", PREP_DB, EOF); + assertTokenTypesIgnoreCase("DW", PREP_DW, EOF); + assertTokenTypesIgnoreCase("DS", PREP_DS, EOF); + assertTokenTypesIgnoreCase("$", PREP_ADDR, EOF); + } + + @Test + public void testRegisters() { + assertTokenTypesIgnoreCase("A", REG_A, EOF); + assertTokenTypesIgnoreCase("B", REG_B, EOF); + assertTokenTypesIgnoreCase("C", REG_C, EOF); + assertTokenTypesIgnoreCase("D", REG_D, EOF); + assertTokenTypesIgnoreCase("E", REG_E, EOF); + assertTokenTypesIgnoreCase("H", REG_H, EOF); + assertTokenTypesIgnoreCase("L", REG_L, EOF); + assertTokenTypesIgnoreCase("M", REG_M, EOF); + assertTokenTypesIgnoreCase("PSW", REG_PSW, EOF); + assertTokenTypesIgnoreCase("SP", REG_SP, EOF); + } + + @Test + public void testSeparators() { + assertTokenTypes("(),", SEP_LPAR, SEP_RPAR, SEP_COMMA, EOF); + } + + @Test + public void testOperators1() { + assertTokenTypes("+-*/=", OP_ADD, OP_SUBTRACT, OP_MULTIPLY, OP_DIVIDE, OP_EQUAL, EOF); + } + + @Test + public void testOperators2() { + assertTokenTypesIgnoreCase("MOD", OP_MOD, EOF); + assertTokenTypesIgnoreCase("SHR", OP_SHR, EOF); + assertTokenTypesIgnoreCase("SHL", OP_SHL, EOF); + assertTokenTypesIgnoreCase("NOT", OP_NOT, EOF); + assertTokenTypesIgnoreCase("AND", OP_AND, EOF); + assertTokenTypesIgnoreCase("OR", OP_OR, EOF); + assertTokenTypesIgnoreCase("XOR", OP_XOR, EOF); + } + + @Test + public void testIdentifier() { + assertTokenTypes("u @ ? _", ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, EOF); + assertTokenTypes("a@ abc ZZ_ H005", ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, EOF); + } + + @Test + public void testLabel() { + assertTokenTypes("u: @: ?: _:", ID_LABEL, ID_LABEL, ID_LABEL, ID_LABEL, EOF); + assertTokenTypes("a@: abc: ZZ_: H005:", ID_LABEL, ID_LABEL, ID_LABEL, ID_LABEL, EOF); + assertTokenTypes("a:", ID_LABEL, EOF); + } + + @Test + public void testCombineSpaceWithNoSpaceTokens() { + assertTokenTypes("abc=(XOR,MOD)", ID_IDENTIFIER, OP_EQUAL, SEP_LPAR, OP_XOR, SEP_COMMA, OP_MOD, SEP_RPAR, EOF); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java new file mode 100644 index 000000000..dc8eb2f50 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java @@ -0,0 +1,121 @@ +package net.emustudio.plugins.compiler.asZ80.parser; + +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprString; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprUnary; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrNoArgs; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.OPCODE_STC; +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.OP_SUBTRACT; +import static net.emustudio.plugins.compiler.asZ80.Utils.assertTrees; +import static net.emustudio.plugins.compiler.asZ80.Utils.parseProgram; + +public class ParseDataTest { + + @Test + public void testDBstring1() { + Program program = parseProgram("db 'hello'"); + assertTrees(new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprString(0, 0, "hello"))), + program + ); + } + + @Test + public void testDBstring2() { + Program program = parseProgram("db \"hello\""); + assertTrees(new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprString(0, 0, "hello"))), + program + ); + } + + @Test + public void testDBinstruction() { + Program program = parseProgram("db stc"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new InstrNoArgs(0, 0, OPCODE_STC))), + program + ); + } + + @Test + public void testMultipleDB() { + Program program = parseProgram("db -1,2,3"); + assertTrees(new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))), + program + ); + } + + @Test + public void testDBwithNegativeValue() { + Program program = parseProgram("db -1"); + assertTrees(new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1)))), + program + ); + } + + @Test + public void testMultipleDBstringNumberString() { + Program program = parseProgram("db -1,'hello',3"); + assertTrees(new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprString(0, 0, "hello")) + .addChild(new ExprNumber(0, 0, 3))), + program + ); + } + + @Test + public void testMultipleDW() { + Program program = parseProgram("dw -1,2,3"); + assertTrees(new Program() + .addChild(new DataDW(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))), + program + ); + } + + @Test + public void testDWwithNegativeValue() { + Program program = parseProgram("dw -1"); + assertTrees(new Program() + .addChild(new DataDW(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1)))), + program + ); + } + + @Test + public void testDS() { + Program program = parseProgram("ds 0x55"); + assertTrees(new Program() + .addChild(new DataDS(0, 0) + .addChild(new ExprNumber(0, 0, 0x55))), + program + ); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java new file mode 100644 index 000000000..d848045ae --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java @@ -0,0 +1,199 @@ +package net.emustudio.plugins.compiler.asZ80.parser; + +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprUnary; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import static net.emustudio.plugins.compiler.asZ80.Utils.assertTrees; +import static net.emustudio.plugins.compiler.asZ80.Utils.parseProgram; + +public class ParseExprTest { + + @Test + public void testPrioritiesAddMul() { + Program program = parseProgram("db 2+3*4"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 3)) + .addChild(new ExprNumber(0, 0, 4))))), + program + ); + } + + @Test + public void testPrioritiesMulAdd() { + Program program = parseProgram("db 2*3+4"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4)))), + program + ); + } + + @Test + public void testAssociativityPlusMinus() { + Program program = parseProgram("db 2-3+4-9"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4))) + .addChild(new ExprNumber(0, 0, 9)))), + program + ); + } + + @Test + public void testAssociativitMulDiv() { + Program program = parseProgram("db 2/3*4/9"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4))) + .addChild(new ExprNumber(0, 0, 9)))), + program + ); + } + + @Test + public void testPrecedencePlusMinusMulDivMod() { + Program program = parseProgram("db 2+3*4-9/2 mod 3"); + System.out.println(program); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 3)) + .addChild(new ExprNumber(0, 0, 4)))) + .addChild(new ExprInfix(0, 0, OP_MOD) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprNumber(0, 0, 9)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 3))))), + program + ); + } + + @Test + public void testAssociativityEqual() { + Program program = parseProgram("db 1 + 2 + 2 = 5 = 5 = 6 - 1"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprInfix(0, 0, OP_ADD) // 1 + 2 + 2 associates to left + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) // ... = 5 associates to right + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) // minus has > precedence than = + .addChild(new ExprNumber(0, 0, 6)) + .addChild(new ExprNumber(0, 0, 1))))))), + program + ); + } + + @Test + public void testAndMulXorDivNotPlusMinus() { + Program program = parseProgram("db not 1 and 2 or 2 xor 5 = - 5 * 6 shl 4 - 1 shr 2"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprInfix(0, 0, OP_OR) + .addChild(new ExprInfix(0, 0, OP_AND) + .addChild(new ExprUnary(0, 0, OP_NOT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 5)))) + .addChild(new ExprInfix(0, 0, OP_SHR) // shl/shr associates to the right + .addChild(new ExprInfix(0, 0, OP_SHL) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))), + program + ); + } + + @Test + public void testAndMulXorDivNotPlusMinusWithOperators() { + Program program = parseProgram("db ~1 & 2 | 2 ^ 5 = -5 * 6 << 4 - 1 >> 2"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprInfix(0, 0, OP_OR_2) + .addChild(new ExprInfix(0, 0, OP_AND_2) + .addChild(new ExprUnary(0, 0, OP_NOT_2) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR_2) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 5)))) + .addChild(new ExprInfix(0, 0, OP_SHR_2) // shl/shr associates to the right + .addChild(new ExprInfix(0, 0, OP_SHL_2) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))), + program + ); + } + + @Test + public void testParenthesis() { + Program program = parseProgram("db (2 + 3) * (4 - 2)"); + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 2))))), + program + ); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java new file mode 100644 index 000000000..fa82f4242 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java @@ -0,0 +1,223 @@ +package net.emustudio.plugins.compiler.asZ80.parser; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprCurrentAddress; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.asZ80.ast.instr.*; +import org.junit.Test; + +import java.util.Locale; +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import static net.emustudio.plugins.compiler.asZ80.Utils.*; + +public class ParseInstrTest { + + @Test + public void testInstrNoArgs() { + assertInstrNoArgs("stc", OPCODE_STC); + assertInstrNoArgs("cmc", OPCODE_CMC); + assertInstrNoArgs("daa", OPCODE_DAA); + assertInstrNoArgs("nop", OPCODE_NOP); + assertInstrNoArgs("rlc", OPCODE_RLC); + assertInstrNoArgs("rrc", OPCODE_RRC); + assertInstrNoArgs("ral", OPCODE_RAL); + assertInstrNoArgs("rar", OPCODE_RAR); + assertInstrNoArgs("xchg", OPCODE_XCHG); + assertInstrNoArgs("xthl", OPCODE_XTHL); + assertInstrNoArgs("sphl", OPCODE_SPHL); + assertInstrNoArgs("pchl", OPCODE_PCHL); + assertInstrNoArgs("ret", OPCODE_RET); + assertInstrNoArgs("rc", OPCODE_RC); + assertInstrNoArgs("rnc", OPCODE_RNC); + assertInstrNoArgs("rz", OPCODE_RZ); + assertInstrNoArgs("rnz", OPCODE_RNZ); + assertInstrNoArgs("rm", OPCODE_RM); + assertInstrNoArgs("rp", OPCODE_RP); + assertInstrNoArgs("rpe", OPCODE_RPE); + assertInstrNoArgs("rpo", OPCODE_RPO); + assertInstrNoArgs("ei", OPCODE_EI); + assertInstrNoArgs("di", OPCODE_DI); + assertInstrNoArgs("hlt", OPCODE_HLT); + } + + @Test + public void testInstrReg() { + assertInstrReg("inr", OPCODE_INR); + assertInstrReg("dcr", OPCODE_DCR); + assertInstrReg("add", OPCODE_ADD); + assertInstrReg("adc", OPCODE_ADC); + assertInstrReg("sub", OPCODE_SUB); + assertInstrReg("sbb", OPCODE_SBB); + assertInstrReg("ana", OPCODE_ANA); + assertInstrReg("xra", OPCODE_XRA); + assertInstrReg("ora", OPCODE_ORA); + assertInstrReg("cmp", OPCODE_CMP); + } + + @Test + public void testInstrExpr() { + assertInstrExpr("lda", OPCODE_LDA); + assertInstrExpr("sta", OPCODE_STA); + assertInstrExpr("lhld", OPCODE_LHLD); + assertInstrExpr("shld", OPCODE_SHLD); + assertInstrExpr("adi", OPCODE_ADI); + assertInstrExpr("aci", OPCODE_ACI); + assertInstrExpr("sui", OPCODE_SUI); + assertInstrExpr("sbi", OPCODE_SBI); + assertInstrExpr("ani", OPCODE_ANI); + assertInstrExpr("ori", OPCODE_ORI); + assertInstrExpr("xri", OPCODE_XRI); + assertInstrExpr("cpi", OPCODE_CPI); + assertInstrExpr("jmp", OPCODE_JMP); + assertInstrExpr("jc", OPCODE_JC); + assertInstrExpr("jnc", OPCODE_JNC); + assertInstrExpr("jz", OPCODE_JZ); + assertInstrExpr("jnz", OPCODE_JNZ); + assertInstrExpr("jm", OPCODE_JM); + assertInstrExpr("jp", OPCODE_JP); + assertInstrExpr("jpe", OPCODE_JPE); + assertInstrExpr("jpo", OPCODE_JPO); + assertInstrExpr("call", OPCODE_CALL); + assertInstrExpr("cc", OPCODE_CC); + assertInstrExpr("cnc", OPCODE_CNC); + assertInstrExpr("cz", OPCODE_CZ); + assertInstrExpr("cnz", OPCODE_CNZ); + assertInstrExpr("cm", OPCODE_CM); + assertInstrExpr("cp", OPCODE_CP); + assertInstrExpr("cpe", OPCODE_CPE); + assertInstrExpr("cpo", OPCODE_CPO); + assertInstrExpr("in", OPCODE_IN); + assertInstrExpr("out", OPCODE_OUT); + assertInstrExpr("rst", OPCODE_RST); + } + + @Test + public void testRegPair() { + assertInstrRegPair("stax", OPCODE_STAX, regPairsBD); + assertInstrRegPair("ldax", OPCODE_LDAX, regPairsBD); + assertInstrRegPair("dad", OPCODE_DAD, regPairsBDHSP); + assertInstrRegPair("inx", OPCODE_INX, regPairsBDHSP); + assertInstrRegPair("dcx", OPCODE_DCX, regPairsBDHSP); + assertInstrRegPair("push", OPCODE_PUSH, regPairsBDHPSW); + assertInstrRegPair("pop", OPCODE_POP, regPairsBDHPSW); + } + + @Test + public void testMVI() { + Node expr = new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); + + forStringCaseVariations("mvi", instrVariation -> { + for (Map.Entry register : registers.entrySet()) { + forStringCaseVariations(register.getKey(), registerVariation -> { + String row = instrVariation + " " + registerVariation + ", $ + 5"; + Program program = parseProgram(row); + assertTrees( + new Program() + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, register.getValue()) + .addChild(expr)), + program + ); + }); + } + }); + } + + @Test + public void testLXI() { + Node expr = new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); + + forStringCaseVariations("lxi", instrVariation -> { + for (Map.Entry regPair : regPairsBDHSP.entrySet()) { + forStringCaseVariations(regPair.getKey(), registerVariation -> { + String row = instrVariation + " " + registerVariation + ", $ + 5"; + Program program = parseProgram(row); + assertTrees( + new Program() + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, regPair.getValue()) + .addChild(expr)), + program + ); + }); + } + }); + } + + @Test + public void testMOV() { + forStringCaseVariations("mov", instrVariation -> { + for (Map.Entry register1 : registers.entrySet()) { + forStringCaseVariations(register1.getKey(), registerVariation1 -> { + for (Map.Entry register2 : registers.entrySet()) { + forStringCaseVariations(register2.getKey(), registerVariation2 -> { + if (!registerVariation1.toLowerCase(Locale.ENGLISH).equals("m") || !registerVariation1.equals(registerVariation2)) { + String row = instrVariation + " " + registerVariation1 + ", " + registerVariation2; + Program program = parseProgram(row); + assertTrees( + new Program() + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, register1.getValue(), register2.getValue())), + program + ); + } + }); + } + }); + } + }); + } + + private void assertInstrNoArgs(String instr, int instrType) { + forStringCaseVariations(instr, variation -> { + Program program = parseProgram(variation); + assertTrees(new Program().addChild(new InstrNoArgs(0, 0, instrType)), program); + }); + } + + private void assertInstrReg(String instr, int instrType) { + forStringCaseVariations(instr, instrVariation -> { + for (Map.Entry register : registers.entrySet()) { + forStringCaseVariations(register.getKey(), registerVariation -> { + String row = instrVariation + " " + registerVariation; + Program program = parseProgram(row); + assertTrees( + new Program().addChild(new InstrReg(0, 0, instrType, register.getValue())), + program + ); + }); + } + }); + } + + private void assertInstrExpr(String instr, int instrType) { + Node expr = new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); + + forStringCaseVariations(instr, variation -> { + Program program = parseProgram(variation + " $ + 5"); + assertTrees(new Program().addChild(new InstrExpr(0, 0, instrType).addChild(expr)), program); + }); + } + + private void assertInstrRegPair(String instr, int instrType, Map regPairs) { + forStringCaseVariations(instr, instrVariation -> { + for (Map.Entry regPair : regPairs.entrySet()) { + forStringCaseVariations(regPair.getKey(), registerVariation -> { + String row = instrVariation + " " + registerVariation; + Program program = parseProgram(row); + assertTrees( + new Program().addChild(new InstrRegPair(0, 0, instrType, regPair.getValue())), + program + ); + }); + } + }); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java new file mode 100644 index 000000000..e65d9e6b7 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java @@ -0,0 +1,181 @@ +package net.emustudio.plugins.compiler.asZ80.parser; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrExpr; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrNoArgs; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; +import net.emustudio.plugins.compiler.asZ80.exceptions.SyntaxErrorException; +import org.junit.Test; + +import java.util.List; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Lexer.*; +import static net.emustudio.plugins.compiler.asZ80.Utils.assertTrees; +import static net.emustudio.plugins.compiler.asZ80.Utils.parseProgram; + +public class ParsePseudoTest { + + @Test + public void testConstant() { + Program program = parseProgram("here equ 0x55"); + assertTrees(new Program() + .addChild(new PseudoEqu(0, 0, "here") + .addChild(new ExprNumber(0, 0, 0x55))), + program + ); + } + + @Test + public void testVariable() { + Program program = parseProgram("here set 0x55"); + assertTrees(new Program() + .addChild(new PseudoSet(0, 0, "here") + .addChild(new ExprNumber(0, 0, 0x55))), + program + ); + } + + @Test + public void testOrg() { + Program program = parseProgram("org 55+88"); + assertTrees(new Program() + .addChild(new PseudoOrg(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 55)) + .addChild(new ExprNumber(0, 0, 88)))), + program + ); + } + + @Test + public void testIf() { + Program program = parseProgram("if 1\n" + + " rrca\n" + + " rrca\n" + + "endif"); + + assertTrees(new Program() + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC))), + program + ); + } + + @Test + public void testIfEmpty() { + List programs = List.of( + "if 1\n\n\nendif", + "if 1\n\nendif", + "if 1\nendif" + ); + + for (String src : programs) { + Program program = parseProgram(src); + Node expected = new Program() + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 1)))); + assertTrees(expected, program); + } + } + + @Test(expected = SyntaxErrorException.class) + public void testIfEndifMustBeOnNewLine() { + parseProgram("if 1\nrrca\nrrca endif"); + } + + @Test + public void testTwoLabelsInsideIf() { + Program program = parseProgram("if 1\n" + + " label1:\n" + + " label2:\n" + + "endif"); + + assertTrees(new Program() + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoLabel(0, 0, "label1")) + .addChild(new PseudoLabel(0, 0, "label2"))), + program + ); + } + + @Test + public void testInclude() { + Program program = parseProgram("include 'filename.asm'"); + assertTrees( + new Program().addChild(new PseudoInclude(0, 0, "filename.asm")), + program + ); + } + + @Test + public void testMacroDef() { + Program program = parseProgram("shrt macro param1, param2\n" + + " rrca\n" + + " heylabel: and 7Fh\n" + + "endm\n\n"); + + Node expected = new Program() + .addChild(new PseudoMacroDef(0, 0, "shrt") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "param1"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "param2"))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) + .addChild(new PseudoLabel(0, 0, "heylabel") + .addChild(new InstrExpr(0, 0, OPCODE_ANI) + .addChild(new ExprNumber(0, 0, 0x7F))))); + + assertTrees(expected, program); + } + + @Test + public void testMacroDefEmpty() { + List programs = List.of( + "shrt macro\n\n\nendm", + "shrt macro\n\nendm", + "shrt macro\nendm" + ); + + for (String src : programs) { + Program program = parseProgram(src); + Node expected = new Program().addChild(new PseudoMacroDef(0, 0, "shrt")); + assertTrees(expected, program); + } + } + + @Test(expected = SyntaxErrorException.class) + public void testMacroDefEndmMustBeOnNewLine() { + parseProgram("shrt macro\nrrca\nrrca endm"); + } + + @Test + public void testMacroCallNoParams() { + Program program = parseProgram("shrt"); + Node expected = new Program().addChild(new PseudoMacroCall(0, 0, "shrt")); + assertTrees(expected, program); + } + + @Test + public void testMacroCallWithParams() { + Program program = parseProgram("shrt param1, 45"); + + Node expected = new Program() + .addChild(new PseudoMacroCall(0, 0, "shrt") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "param1"))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 45)))); + + assertTrees(expected, program); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java new file mode 100644 index 000000000..84036435b --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java @@ -0,0 +1,79 @@ +package net.emustudio.plugins.compiler.asZ80.parser; + +import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import net.emustudio.plugins.compiler.asZ80.ParsingUtils; +import net.emustudio.plugins.compiler.asZ80.Utils; +import org.antlr.v4.runtime.Token; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +import static net.emustudio.plugins.compiler.asZ80.Utils.assertTokenTypes; +import static net.emustudio.plugins.compiler.asZ80.Utils.getTokens; +import static org.junit.Assert.assertEquals; + +public class ParsingUtilsTest { + + @Test + public void testParseLitString() { + List tokens = getTokens("'te\"x\"t1' \"te'x't2\""); + Utils.assertTokenTypes(tokens, LIT_STRING_1, LIT_STRING_2, EOF); + Assert.assertEquals("te\"x\"t1", ParsingUtils.parseLitString(tokens.get(0))); + assertEquals("te'x't2", ParsingUtils.parseLitString(tokens.get(1))); + } + + @Test + public void testParseLitHex1() { + List tokens = getTokens("0x22F 0XAA55"); + assertTokenTypes(tokens, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, EOF); + assertEquals(0x22F, ParsingUtils.parseLitHex1(tokens.get(0))); + assertEquals(0xAA55, ParsingUtils.parseLitHex1(tokens.get(1))); + } + + @Test + public void testParseLitHex2() { + List tokens = getTokens("022Fh AA55H"); + assertTokenTypes(tokens, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, EOF); + assertEquals(0x22F, ParsingUtils.parseLitHex2(tokens.get(0))); + assertEquals(0xAA55, ParsingUtils.parseLitHex2(tokens.get(1))); + } + + @Test + public void testParseLitOct() { + List tokens = getTokens("22q 55O 77Q 001o"); + assertTokenTypes( + tokens, + LIT_OCTNUMBER, LIT_OCTNUMBER, LIT_OCTNUMBER, + LIT_OCTNUMBER, EOF + ); + assertEquals(18, ParsingUtils.parseLitOct(tokens.get(0))); + assertEquals(45, ParsingUtils.parseLitOct(tokens.get(1))); + assertEquals(63, ParsingUtils.parseLitOct(tokens.get(2))); + assertEquals(1, ParsingUtils.parseLitOct(tokens.get(3))); + } + + @Test + public void testParseLitDec() { + List tokens = getTokens("22 55 00"); + assertTokenTypes( + tokens, + LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, EOF + ); + assertEquals(22, ParsingUtils.parseLitDec(tokens.get(0))); + assertEquals(55, ParsingUtils.parseLitDec(tokens.get(1))); + assertEquals(0, ParsingUtils.parseLitDec(tokens.get(2))); + } + + @Test + public void testParseLitBin() { + List tokens = getTokens("000b 0101101b 111b"); + assertTokenTypes( + tokens, + LIT_BINNUMBER, LIT_BINNUMBER, LIT_BINNUMBER, EOF + ); + assertEquals(0, ParsingUtils.parseLitBin(tokens.get(0))); + assertEquals(45, ParsingUtils.parseLitBin(tokens.get(1))); + assertEquals(7, ParsingUtils.parseLitBin(tokens.get(2))); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitorTest.java new file mode 100644 index 000000000..944560576 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitorTest.java @@ -0,0 +1,176 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.asZ80.CompileError.*; +import static net.emustudio.plugins.compiler.asZ80.Utils.parseProgram; +import static org.junit.Assert.assertTrue; + +public class CheckDeclarationsVisitorTest { + + @Test + public void testDeclarationsAreFound() { + Program program = parseProgram("label:\nconstant equ 1\nvariable set 1\nxxx macro\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + } + + @Test + public void testVariableTwoTimesPass() { + Program program = parseProgram("var set 1\nvar set 2"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + } + + @Test + public void testConstantTwoTimesCannotBeDefined() { + Program program = parseProgram("var equ 1\nvar equ 2"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testVarCannotBeDefinedIfAnotherDeclarationExists() { + Program program = parseProgram("var equ 1\nvar set 2"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacrosAndDeclarationsAreIndependent() { + Program program = parseProgram("label:\nlabel macro\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + } + + @Test + public void testLabelThenConstantAlreadyDeclared() { + Program program = parseProgram("label:\nlabel equ 1"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroAlreadyDeclared() { + Program program = parseProgram("label macro\nendm\nlabel macro\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroParametersCollideWithLabel() { + Program program = parseProgram("label: x macro label\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroParametersCollideWithConstant() { + Program program = parseProgram("const equ 1\nx macro const\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroParametersCollideWithVariable() { + Program program = parseProgram("variable set 1\nx macro variable\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroParametersCollideParentMacroParameters() { + Program program = parseProgram("x macro f,g,n\ny macro p,g,o\nendm\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroParametersAfterMacroEndStillCollideWithLabel() { + Program program = parseProgram("x macro tt\nendm\ntt:"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroParametersCollideWithConstantInsideMacro() { + Program program = parseProgram("x macro tt\ntt equ 1\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroNameCollidesWithParameterName() { + Program program = parseProgram("x macro x\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); + } + + @Test + public void testMacroReuseParameterNamesIsPossible() { + Program program = parseProgram("x macro t\nendm\ny macro t\nendm"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testIfExpressionReferencesOwnBlockDeclarations() { + Program program = parseProgram("if var + 1\nvar set -1\nendif"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK)); + } + + @Test + public void testNestedIfExpressionReferencesOwnBlockDeclarations() { + Program program = parseProgram("if var + 1\nif 0\nvar:\nendif\nendif"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK)); + } + + @Test + public void testSelfReferencingConstant() { + Program program = parseProgram("self equ self + 1"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_DECLARATION_REFERENCES_ITSELF)); + } + + @Test + public void testSelfReferencingNoneExistingVariableIsNotFine() { + Program program = parseProgram("self set self + 1"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_DECLARATION_REFERENCES_ITSELF)); + } + + @Test + public void testSelfReferencingExistingVariableIsFine() { + Program program = parseProgram("self set 1\n self set self + 1"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testConstantIfReference() { + Program program = parseProgram("const equ 1\nif const\nrrca\nendif"); + CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); + visitor.visit(program); + assertTrue(program.env().hasNoErrors()); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java new file mode 100644 index 000000000..63471ec34 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java @@ -0,0 +1,243 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrExpr; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRegPairExpr; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroArgument; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroCall; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoOrg; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import static net.emustudio.plugins.compiler.asZ80.CompileError.ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED; +import static net.emustudio.plugins.compiler.asZ80.Utils.assertTrees; +import static org.junit.Assert.assertTrue; + +public class CheckExprSizesVisitorTest { + + @Test + public void testDBoneByte() { + Program program = new Program(); + program + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0,0, 0xFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testDBtwoBytes() { + Program program = new Program(); + program + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0,0, 0xFF)) + .addChild(new Evaluated(0,0, 0x100))); // bad size + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testDWtwoBytes() { + Program program = new Program(); + program + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0,0, 0xFFFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testDWthreeBytes() { + Program program = new Program(); + program + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0,0, 0xFFFF)) + .addChild(new Evaluated(0,0, 0x10000))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testDStwoBytes() { + Program program = new Program(); + program + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0,0, 0xFFFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testDSthreeBytes() { + Program program = new Program(); + program + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0,0, 0x10000))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testInstrExprTwoBytes() { + Program program = new Program(); + program + .addChild(new InstrExpr(0, 0, OPCODE_ADI) + .addChild(new Evaluated(0,0, 0xFF00))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testInstrExprThreeBytes() { + Program program = new Program(); + program + .addChild(new InstrExpr(0, 0, OPCODE_JMP) + .addChild(new Evaluated(0,0, 0xFF000))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testInstrRegExprOneByte() { + Program program = new Program(); + program + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0,0, 0xFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testInstrRegExprTwoBytes() { + Program program = new Program(); + program + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0,0, 0x100))); // bad size + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testInstrRegPairExprTwoBytes() { + Program program = new Program(); + program + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0,0, 0xFFFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testInstrRegPairExprThreeBytes() { + Program program = new Program(); + program + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0,0, 0x10000))); // bad size + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testPseudoOrgTwoBytes() { + Program program = new Program(); + program + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0,0, 0xFFFF))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + } + + @Test + public void testPseudoOrgThreeBytes() { + Program program = new Program(); + program + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0,0, 0x10000))); // bad size + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + } + + @Test + public void testMacroArgumentsAreRemoved() { + Program program = new Program(); + program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))); + + CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))), + program + ); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java new file mode 100644 index 000000000..abb03432a --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java @@ -0,0 +1,471 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprCurrentAddress; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrExpr; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrNoArgs; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRegPairExpr; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; +import org.junit.Test; + +import java.util.List; +import java.util.Optional; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import static net.emustudio.plugins.compiler.asZ80.CompileError.ERROR_AMBIGUOUS_EXPRESSION; +import static net.emustudio.plugins.compiler.asZ80.Utils.assertTrees; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class EvaluateExprVisitorTest { + + @Test + public void testEvaluateDB() { + Program program = new Program(); + program + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 'h')) + .addChild(new ExprNumber(0, 0, 'e')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'o')) + ); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 3)) + .addChild(new Evaluated(0, 0, 'h')) + .addChild(new Evaluated(0, 0, 'e')) + .addChild(new Evaluated(0, 0, 'l')) + .addChild(new Evaluated(0, 0, 'l')) + .addChild(new Evaluated(0, 0, 'o'))), + program + ); + } + + @Test + public void testEvaluateDW() { + Program program = new Program(); + program + .addChild(new DataDW(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new DataDW(0, 0) + .addChild(new ExprNumber(0, 0, 0))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 3))) + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 0))), + program + ); + assertEquals(0, program.getChild(0).getAddress()); + assertEquals(2, program.getChild(1).getAddress()); + } + + @Test + public void testEvaluateDS() { + Program program = new Program(); + program + .addChild(new DataDS(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new DataDB(0, 0) + .addChild(new ExprNumber(0, 0, 0))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 3))) + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 0))), + program + ); + assertEquals(0, program.getChild(0).getAddress()); + assertEquals(3, program.getChild(1).getAddress()); + } + + @Test + public void testEvaluateDSambiguous() { + Program program = new Program(); + program + .addChild(new DataDS(0, 0) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new PseudoLabel(0, 0, "label")); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_AMBIGUOUS_EXPRESSION)); + } + + @Test + public void testEvaluateDSconstReference() { + Program program = new Program(); + program + .addChild(new DataDS(0, 0) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new PseudoEqu(0, 0, "label") + .addChild(new ExprNumber(0, 0, 5))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + + Optional label = program.env().get("label"); + assertTrue(label.isPresent()); + assertEquals(0, label.get().getAddress()); + + assertTrees( + new Program() + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 5))), + program + ); + } + + @Test + public void testEvaluateEQUfivePasses() { + Program program = new Program(); + program + .addChild(new PseudoEqu(0, 0, "one") + .addChild(new ExprId(0, 0, "two"))) + .addChild(new PseudoEqu(0, 0, "two") + .addChild(new ExprId(0, 0, "three"))) + .addChild(new PseudoEqu(0, 0, "three") + .addChild(new ExprId(0, 0, "four"))) + .addChild(new PseudoEqu(0, 0, "four") + .addChild(new ExprId(0, 0, "five"))) + .addChild(new PseudoEqu(0, 0, "five") + .addChild(new ExprCurrentAddress(0, 0))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasNoErrors()); + assertTrees(new Program(), program); + + List constants = List.of("one", "two", "three", "four", "five"); + for (String c : constants) { + Optional constant = program.env().get(c); + assertTrue(constant.isPresent()); + assertEquals(0, constant.get().getAddress()); + assertEquals(0, constant.get().value); + } + } + + @Test + public void testEvaluateIFwithForwardConst() { + Program program = new Program(); + program + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprCurrentAddress(0, 0)))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0, 0, 6))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 0))), + program + ); + assertEquals(0, program.getChild(0).getAddress()); + assertEquals(2, program.getChild(1).getAddress()); + } + + @Test + public void testEvaluateIFwithForwardAddressReference() { + Program program = new Program(); + program + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "const")))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprCurrentAddress(0, 0)))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_AMBIGUOUS_EXPRESSION)); + } + + @Test + public void testEvaluateIFexcludeBlock() { + Program program = new Program(); + program + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new ExprNumber(0, 0, 0)))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees(new Program(), program); + } + + @Test + public void testEvaluateSETforwardTwoTimes() { + Program program = new Program(); + program + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new ExprNumber(0, 0, 2))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new Evaluated(0, 0, 1))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new Evaluated(0, 0, 2))), + program + ); + } + + @Test + public void testEvaluateSETforwardMoreTimes() { + Program program = new Program(); + program + .addChild(new DataDB(0, 0) + .addChild(new ExprId(0, 0, "id"))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0, 2))), + program + ); + } + + @Test + public void testTwoSETthenReference() { + Program program = new Program(); + program + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new DataDB(0, 0) + .addChild(new ExprId(0, 0, "id"))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0, 2))) + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 2))), + program + ); + } + + @Test + public void testEvaluateLABEL() { + Program program = new Program(); + program + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label")))) + .addChild(new PseudoLabel(0, 0, "label")); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 3)) + .addChild(new Evaluated(0, 0, 4)) + .addChild(new Evaluated(0, 0, 5))), + program + ); + } + + @Test + public void testEvaluateMacroCalls() { + Program program = new Program(); + program + .addChild(new PseudoLabel(0, 0, "label")) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "addr")) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "addr")))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "addr")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))), + program + ); + } + + @Test + public void testEvaluateMacroCallAmbiguous() { + Program program = new Program(); + program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "label")) + .addChild(new ExprId(0, 0, "addr"))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "addr")))) + .addChild(new PseudoLabel(0, 0, "label")); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_AMBIGUOUS_EXPRESSION)); + } + + @Test + public void testEvaluateMacroScopedArguments() { + Program program = new Program(); + program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new ExprNumber(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "arg"))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "arg")))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "arg")))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))), + program + ); + } + + @Test + public void testLabelKeepsChildren() { + Program program = new Program(); + program + .addChild(new PseudoLabel(0, 0, "label") + .addChild(new InstrNoArgs(0, 0, OPCODE_RET))); + + EvaluateExprVisitor visitor = new EvaluateExprVisitor(); + visitor.visit(program); + + assertTrees( + new Program().addChild(new InstrNoArgs(0, 0, OPCODE_RET)), + program + ); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java new file mode 100644 index 000000000..3744c6c22 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java @@ -0,0 +1,82 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoLabel; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrNoArgs; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.asZ80.exceptions.FatalError; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import static net.emustudio.plugins.compiler.asZ80.CompileError.ERROR_CANNOT_READ_FILE; +import static net.emustudio.plugins.compiler.asZ80.Utils.*; +import static org.junit.Assert.assertTrue; + +public class ExpandIncludesVisitorTest { + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void testExpandInclude() { + String filename = ExpandIncludesVisitorTest.class.getResource("/sample.asm").getFile(); + Program program = parseProgram("cmc\ninclude '" + filename + "'"); + ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); + visitor.visit(program); + + Node expected = new Program() + .addChild(new InstrNoArgs(0, 0, OPCODE_CMC)) + .addChild(new PseudoLabel(0, 0, "sample") + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RET)); + + assertTrees(expected, program); + } + + @Test + public void testExpandIncludeTwoTimes() throws IOException { + File file = folder.newFile("file-a.asm"); + write(file, "rrc"); + + Program program = parseProgram( + "include '" + file.getPath() + "'\n" + + "include '" + file.getPath() + "'" + ); + ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); + visitor.visit(program); + + Node expected = new Program() + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)); + + assertTrees(expected, program); + } + + @Test + public void testNonExistingFileThrows() { + Program program = parseProgram("cmc\ninclude 'non-existant.asm'"); + ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); + visitor.visit(program); + assertTrue(program.env().hasError(ERROR_CANNOT_READ_FILE)); + } + + @Test(expected = FatalError.class) + public void testIndefiniteLoopDetected() throws IOException { + File fileA = folder.newFile("file-a.asm"); + File fileB = folder.newFile("file-b.asm"); + + write(fileA, "include '" + fileB.getPath() + "'"); + write(fileB, "include '" + fileA.getPath() + "'"); + + Program program = parseProgram("include '" + fileA.getPath() + "'"); + ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); + visitor.visit(program); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java new file mode 100644 index 000000000..aefbdfec9 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java @@ -0,0 +1,121 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroArgument; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroCall; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroDef; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroParameter; +import net.emustudio.plugins.compiler.asZ80.exceptions.FatalError; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; + +import static net.emustudio.plugins.compiler.asZ80.Utils.*; + +public class ExpandMacrosTest { + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void testMacroDefinitionThenMacroCall() { + Program program = parseProgram("x macro\nendm\nx"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program + ); + } + + @Test + public void testMacroCallThenMacroDefinition() { + Program program = parseProgram("x\nx macro\nendm"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program + ); + } + + @Test + public void testMacroCallThenMacroDefinitionThenMacroCall() { + Program program = parseProgram("x\nx macro\nendm\nx"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program + ); + } + + @Test + public void testMacroCallThenMacroDefinitionInsideInclude() throws IOException { + File file = folder.newFile("file.asm"); + write(file, "x macro\nendm"); + + Program program = parseProgram("x\ninclude '" + file.getPath() + "'"); + ExpandIncludesVisitor includesVisitor = new ExpandIncludesVisitor(); + includesVisitor.visit(program); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program + ); + } + + @Test(expected = FatalError.class) + public void testTheSameMacroCallInsideMacroDefinition() { + Program program = parseProgram("x macro\nx\nendm"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + } + + @Test(expected = FatalError.class) + public void testMacroCallComplexInfiniteLoop() { + Program program = parseProgram("x macro\ny\nendm\ny macro\nx\nendm"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + } + + @Test + public void testMacroCallWithArguments() { + Program program = parseProgram("x 1,2,3\nx macro q,r,t\nendm"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "r"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "t"))))), + program + ); + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java new file mode 100644 index 000000000..394a263a9 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java @@ -0,0 +1,711 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.emulib.runtime.io.IntelHEX; +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; +import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; +import net.emustudio.plugins.compiler.asZ80.ast.instr.*; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroCall; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoOrg; +import org.junit.Test; + +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import static org.junit.Assert.assertEquals; + +public class GenerateCodeVisitorTest { + + @Test + public void testCodeGeneration() { + Program program = new Program(); + program + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 255)) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 4)))) + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 5))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0xFEAB))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_D) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_H) + .addChild(new Evaluated(0, 0, 0x1234)))); + + IntelHEX hex = new IntelHEX(); + GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); + visitor.visit(program); + Map code = hex.getCode(); + + assertEquals((byte) 255, code.get(0).byteValue()); + assertEquals((byte) 0xe7, code.get(1).byteValue()); + assertEquals(1, code.get(2).byteValue()); // dw - lower byte + assertEquals(0, code.get(3).byteValue()); // dw - upper byte + assertEquals(0, code.get(4).byteValue()); + assertEquals(0, code.get(5).byteValue()); + assertEquals(0, code.get(6).byteValue()); + assertEquals(0, code.get(7).byteValue()); + assertEquals(0, code.get(8).byteValue()); + assertEquals(1, code.get(9).byteValue()); // lxi b + assertEquals((byte) 0xAB, code.get(10).byteValue()); + assertEquals((byte) 0xFE, code.get(11).byteValue()); + assertEquals(0x11, code.get(12).byteValue()); // lxi d + assertEquals(1, code.get(13).byteValue()); + assertEquals(0, code.get(14).byteValue()); + assertEquals(0x21, code.get(15).byteValue()); // lxi h + assertEquals(0x34, code.get(16).byteValue()); + assertEquals(0x12, code.get(17).byteValue()); + } + + @Test + public void testPseudoOrg() { + Program program = new Program(); + program + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0, 0, 5))) + .addChild(new InstrExpr(0, 0, OPCODE_CNZ) + .addChild(new Evaluated(0, 0, 0x400))) + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrNoArgs(0, 0, OPCODE_XCHG)); + + IntelHEX hex = new IntelHEX(); + GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); + visitor.visit(program); + Map code = hex.getCode(); + + assertEquals((byte) 0xeb, code.get(0).byteValue()); + assertEquals((byte) 0xc4, code.get(5).byteValue()); + assertEquals(0, code.get(6).byteValue()); + assertEquals(4, code.get(7).byteValue()); + } + + @Test + public void testGenerateInstructions() { + Program program = new Program(); + program + .addChild(new InstrNoArgs(0, 0, OPCODE_NOP)) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrRegPair(0, 0, OPCODE_STAX, REG_B)) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_B)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) + .addChild(new Evaluated(0, 0, 7))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RLC)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_B)) + .addChild(new InstrRegPair(0, 0, OPCODE_LDAX, REG_B)) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_C)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_C) + .addChild(new Evaluated(0, 0, 8))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_D) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_STAX, REG_D)) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_D)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_D) + .addChild(new Evaluated(0, 0, 9))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RAL)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_D)) + .addChild(new InstrRegPair(0, 0, OPCODE_LDAX, REG_D)) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_E)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_E) + .addChild(new Evaluated(0, 0, 10))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RAR)) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_H) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrExpr(0, 0, OPCODE_SHLD) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_H)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_H) + .addChild(new Evaluated(0, 0, 0x28))) + .addChild(new InstrNoArgs(0, 0, OPCODE_DAA)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_H)) + .addChild(new InstrExpr(0, 0, OPCODE_LHLD) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_L)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_L) + .addChild(new Evaluated(0, 0, 10))) + .addChild(new InstrNoArgs(0, 0, OPCODE_CMA)) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_SP) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrExpr(0, 0, OPCODE_STA) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_SP)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_M)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_M) + .addChild(new Evaluated(0, 0, 7))) + .addChild(new InstrNoArgs(0, 0, OPCODE_STC)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_SP)) + .addChild(new InstrExpr(0, 0, OPCODE_LDA) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_SP)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_A)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0, 0, -128))) + .addChild(new InstrNoArgs(0, 0, OPCODE_CMC)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_M)) // HLT + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_A)) + .addChild(new InstrNoArgs(0, 0, OPCODE_RNZ)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_B)) + .addChild(new InstrExpr(0, 0, OPCODE_JNZ) + .addChild(new Evaluated(0, 0, 2))) + .addChild(new InstrExpr(0, 0, OPCODE_JMP) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrExpr(0, 0, OPCODE_CNZ) + .addChild(new Evaluated(0, 0, 0xF0A0))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_B)) + .addChild(new InstrExpr(0, 0, OPCODE_ADI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RZ)) + .addChild(new InstrNoArgs(0, 0, OPCODE_RET)) + .addChild(new InstrExpr(0, 0, OPCODE_JZ) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_CZ) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_CALL) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_ACI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RNC)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_D)) + .addChild(new InstrExpr(0, 0, OPCODE_JNC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_OUT) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_CNC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_D)) + .addChild(new InstrExpr(0, 0, OPCODE_SUI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 2))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RC)) + .addChild(new InstrExpr(0, 0, OPCODE_JC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_IN) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_CC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_SBI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 3))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RPO)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_H)) + .addChild(new InstrExpr(0, 0, OPCODE_JPO) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrNoArgs(0, 0, OPCODE_XTHL)) + .addChild(new InstrExpr(0, 0, OPCODE_CPO) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_H)) + .addChild(new InstrExpr(0, 0, OPCODE_ANI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 4))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RPE)) + .addChild(new InstrNoArgs(0, 0, OPCODE_PCHL)) + .addChild(new InstrExpr(0, 0, OPCODE_JPE) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrNoArgs(0, 0, OPCODE_XCHG)) + .addChild(new InstrExpr(0, 0, OPCODE_CPE) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_XRI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 5))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RP)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_PSW)) + .addChild(new InstrExpr(0, 0, OPCODE_JP) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrNoArgs(0, 0, OPCODE_DI)) + .addChild(new InstrExpr(0, 0, OPCODE_CP) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_PSW)) + .addChild(new InstrExpr(0, 0, OPCODE_ORI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 6))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RM)) + .addChild(new InstrNoArgs(0, 0, OPCODE_SPHL)) + .addChild(new InstrExpr(0, 0, OPCODE_JM) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrNoArgs(0, 0, OPCODE_EI)) + .addChild(new InstrExpr(0, 0, OPCODE_CM) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrExpr(0, 0, OPCODE_CPI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 7))); + + IntelHEX hex = new IntelHEX(); + GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); + visitor.visit(program); + Map code = hex.getCode(); + + assertEquals(0, code.get(0).byteValue()); // NOP + assertEquals(1, code.get(1).byteValue()); // LXI B,D16 + assertEquals(0x34, code.get(2).byteValue()); + assertEquals(0x12, code.get(3).byteValue()); + assertEquals(2, code.get(4).byteValue()); // STAX B + assertEquals(3, code.get(5).byteValue()); // INX B + assertEquals(4, code.get(6).byteValue()); // INR B + assertEquals(5, code.get(7).byteValue()); // DCR B + assertEquals(6, code.get(8).byteValue()); // MVI B + assertEquals(7, code.get(9).byteValue()); + assertEquals(7, code.get(10).byteValue()); // RLC + assertEquals(9, code.get(11).byteValue()); // DAD B + assertEquals(0x0A, code.get(12).byteValue()); // LDAX B + assertEquals(0x0B, code.get(13).byteValue()); // DCX B + assertEquals(0x0C, code.get(14).byteValue()); // INR C + assertEquals(0x0D, code.get(15).byteValue()); // DCR C + assertEquals(0x0E, code.get(16).byteValue()); // MVI C + assertEquals(8, code.get(17).byteValue()); + assertEquals(0x0F, code.get(18).byteValue()); // RRC + assertEquals(0x11, code.get(19).byteValue()); // LXI D + assertEquals(0x45, code.get(20).byteValue()); + assertEquals(0x23, code.get(21).byteValue()); + assertEquals(0x12, code.get(22).byteValue()); // STAX D + assertEquals(0x13, code.get(23).byteValue()); // INX D + assertEquals(0x14, code.get(24).byteValue()); // INR D + assertEquals(0x15, code.get(25).byteValue()); // DCR D + assertEquals(0x16, code.get(26).byteValue()); // MVI D + assertEquals(9, code.get(27).byteValue()); + assertEquals(0x17, code.get(28).byteValue()); // RAL + assertEquals(0x19, code.get(29).byteValue()); // DAD D + assertEquals(0x1A, code.get(30).byteValue()); // LDAX D + assertEquals(0x1B, code.get(31).byteValue()); // DCX D + assertEquals(0x1C, code.get(32).byteValue()); // INR E + assertEquals(0x1D, code.get(33).byteValue()); // DCR E + assertEquals(0x1E, code.get(34).byteValue()); // MVI E + assertEquals(10, code.get(35).byteValue()); + assertEquals(0x1F, code.get(36).byteValue()); // RAR + assertEquals(0x21, code.get(37).byteValue()); // LXI H + assertEquals(0x45, code.get(38).byteValue()); + assertEquals(0x23, code.get(39).byteValue()); + assertEquals(0x22, code.get(40).byteValue()); // SHLD + assertEquals(0x45, code.get(41).byteValue()); + assertEquals(0x23, code.get(42).byteValue()); + assertEquals(0x23, code.get(43).byteValue()); // INX H + assertEquals(0x24, code.get(44).byteValue()); // INR H + assertEquals(0x25, code.get(45).byteValue()); // DCR H + assertEquals(0x26, code.get(46).byteValue()); // MVI H + assertEquals(0x28, code.get(47).byteValue()); + assertEquals(0x27, code.get(48).byteValue()); // DAA + assertEquals(0x29, code.get(49).byteValue()); // DAD H + assertEquals(0x2A, code.get(50).byteValue()); // LHLD + assertEquals(0x45, code.get(51).byteValue()); + assertEquals(0x23, code.get(52).byteValue()); + assertEquals(0x2B, code.get(53).byteValue()); // DCX H + assertEquals(0x2C, code.get(54).byteValue()); // INR L + assertEquals(0x2D, code.get(55).byteValue()); // DCR L + assertEquals(0x2E, code.get(56).byteValue()); // MVI L + assertEquals(10, code.get(57).byteValue()); + assertEquals(0x2F, code.get(58).byteValue()); // CMA + assertEquals(0x31, code.get(59).byteValue()); // LXI SP + assertEquals(0x45, code.get(60).byteValue()); + assertEquals(0x23, code.get(61).byteValue()); + assertEquals(0x32, code.get(62).byteValue()); // STA + assertEquals(0x45, code.get(63).byteValue()); + assertEquals(0x23, code.get(64).byteValue()); + assertEquals(0x33, code.get(65).byteValue()); // INX SP + assertEquals(0x34, code.get(66).byteValue()); // INR M + assertEquals(0x35, code.get(67).byteValue()); // DCR M + assertEquals(0x36, code.get(68).byteValue()); // MVI M + assertEquals(7, code.get(69).byteValue()); + assertEquals(0x37, code.get(70).byteValue()); // STC + assertEquals(0x39, code.get(71).byteValue()); // DAD SP + assertEquals(0x3A, code.get(72).byteValue()); // LDA + assertEquals(0x45, code.get(73).byteValue()); + assertEquals(0x23, code.get(74).byteValue()); + assertEquals(0x3B, code.get(75).byteValue()); // DCX SP + assertEquals(0x3C, code.get(76).byteValue()); // INR A + assertEquals(0x3D, code.get(77).byteValue()); // DCR A + assertEquals(0x3E, code.get(78).byteValue()); // MVI A + assertEquals(-128, code.get(79).byteValue()); + assertEquals(0x3F, code.get(80).byteValue()); // CMC + assertEquals(0x40, code.get(81).byteValue()); // MOV B,B + assertEquals(0x41, code.get(82).byteValue()); // MOV B,C + assertEquals(0x42, code.get(83).byteValue()); // MOV B,D + assertEquals(0x43, code.get(84).byteValue()); // MOV B,E + assertEquals(0x44, code.get(85).byteValue()); // MOV B,H + assertEquals(0x45, code.get(86).byteValue()); // MOV B,L + assertEquals(0x46, code.get(87).byteValue()); // MOV B,M + assertEquals(0x47, code.get(88).byteValue()); // MOV B,A + assertEquals(0x48, code.get(89).byteValue()); // MOV C,B + assertEquals(0x49, code.get(90).byteValue()); // MOV C,C + assertEquals(0x4A, code.get(91).byteValue()); // MOV C,D + assertEquals(0x4B, code.get(92).byteValue()); // MOV C,E + assertEquals(0x4C, code.get(93).byteValue()); // MOV C,H + assertEquals(0x4D, code.get(94).byteValue()); // MOV C,L + assertEquals(0x4E, code.get(95).byteValue()); // MOV C,M + assertEquals(0x4F, code.get(96).byteValue()); // MOV C,A + assertEquals(0x50, code.get(97).byteValue()); // MOV D,B + assertEquals(0x51, code.get(98).byteValue()); // MOV D,C + assertEquals(0x52, code.get(99).byteValue()); // MOV D,D + assertEquals(0x53, code.get(100).byteValue()); // MOV D,E + assertEquals(0x54, code.get(101).byteValue()); // MOV D,H + assertEquals(0x55, code.get(102).byteValue()); // MOV D,L + assertEquals(0x56, code.get(103).byteValue()); // MOV D,M + assertEquals(0x57, code.get(104).byteValue()); // MOV D,A + assertEquals(0x58, code.get(105).byteValue()); // MOV E,B + assertEquals(0x59, code.get(106).byteValue()); // MOV E,C + assertEquals(0x5A, code.get(107).byteValue()); // MOV E,D + assertEquals(0x5B, code.get(108).byteValue()); // MOV E,E + assertEquals(0x5C, code.get(109).byteValue()); // MOV E,H + assertEquals(0x5D, code.get(110).byteValue()); // MOV E,L + assertEquals(0x5E, code.get(111).byteValue()); // MOV E,M + assertEquals(0x5F, code.get(112).byteValue()); // MOV E,A + assertEquals(0x60, code.get(113).byteValue()); // MOV H,B + assertEquals(0x61, code.get(114).byteValue()); // MOV H,C + assertEquals(0x62, code.get(115).byteValue()); // MOV H,D + assertEquals(0x63, code.get(116).byteValue()); // MOV H,E + assertEquals(0x64, code.get(117).byteValue()); // MOV H,H + assertEquals(0x65, code.get(118).byteValue()); // MOV H,L + assertEquals(0x66, code.get(119).byteValue()); // MOV H,M + assertEquals(0x67, code.get(120).byteValue()); // MOV H,A + assertEquals(0x68, code.get(121).byteValue()); // MOV L,B + assertEquals(0x69, code.get(122).byteValue()); // MOV L,C + assertEquals(0x6A, code.get(123).byteValue()); // MOV L,D + assertEquals(0x6B, code.get(124).byteValue()); // MOV L,E + assertEquals(0x6C, code.get(125).byteValue()); // MOV L,H + assertEquals(0x6D, code.get(126).byteValue()); // MOV L,L + assertEquals(0x6E, code.get(127).byteValue()); // MOV L,M + assertEquals(0x6F, code.get(128).byteValue()); // MOV L,A + assertEquals(0x70, code.get(129).byteValue()); // MOV M,B + assertEquals(0x71, code.get(130).byteValue()); // MOV M,C + assertEquals(0x72, code.get(131).byteValue()); // MOV M,D + assertEquals(0x73, code.get(132).byteValue()); // MOV M,E + assertEquals(0x74, code.get(133).byteValue()); // MOV M,H + assertEquals(0x75, code.get(134).byteValue()); // MOV M,L + assertEquals(0x76, code.get(135).byteValue()); // MOV M,M / HLT + assertEquals(0x77, code.get(136).byteValue()); // MOV M,A + assertEquals(0x78, code.get(137).byteValue()); // MOV A,B + assertEquals(0x79, code.get(138).byteValue()); // MOV A,C + assertEquals(0x7A, code.get(139).byteValue()); // MOV A,D + assertEquals(0x7B, code.get(140).byteValue()); // MOV A,E + assertEquals(0x7C, code.get(141).byteValue()); // MOV A,H + assertEquals(0x7D, code.get(142).byteValue()); // MOV A,L + assertEquals(0x7E, code.get(143).byteValue()); // MOV A,M + assertEquals(0x7F, code.get(144).byteValue()); // MOV A,A + assertEquals(0x80, code.get(145) & 0xFF); // ADD B + assertEquals(0x81, code.get(146) & 0xFF); // ADD C + assertEquals(0x82, code.get(147) & 0xFF); // ADD D + assertEquals(0x83, code.get(148) & 0xFF); // ADD E + assertEquals(0x84, code.get(149) & 0xFF); // ADD H + assertEquals(0x85, code.get(150) & 0xFF); // ADD L + assertEquals(0x86, code.get(151) & 0xFF); // ADD M + assertEquals(0x87, code.get(152) & 0xFF); // ADD A + assertEquals(0x88, code.get(153) & 0xFF); // ADC B + assertEquals(0x89, code.get(154) & 0xFF); // ADC C + assertEquals(0x8A, code.get(155) & 0xFF); // ADC D + assertEquals(0x8B, code.get(156) & 0xFF); // ADC E + assertEquals(0x8C, code.get(157) & 0xFF); // ADC H + assertEquals(0x8D, code.get(158) & 0xFF); // ADC L + assertEquals(0x8E, code.get(159) & 0xFF); // ADC M + assertEquals(0x8F, code.get(160) & 0xFF); // ADC A + assertEquals(0x90, code.get(161) & 0xFF); // SUB B + assertEquals(0x91, code.get(162) & 0xFF); // SUB C + assertEquals(0x92, code.get(163) & 0xFF); // SUB D + assertEquals(0x93, code.get(164) & 0xFF); // SUB E + assertEquals(0x94, code.get(165) & 0xFF); // SUB H + assertEquals(0x95, code.get(166) & 0xFF); // SUB L + assertEquals(0x96, code.get(167) & 0xFF); // SUB M + assertEquals(0x97, code.get(168) & 0xFF); // SUB A + assertEquals(0x98, code.get(169) & 0xFF); // SBB B + assertEquals(0x99, code.get(170) & 0xFF); // SBB C + assertEquals(0x9A, code.get(171) & 0xFF); // SBB D + assertEquals(0x9B, code.get(172) & 0xFF); // SBB E + assertEquals(0x9C, code.get(173) & 0xFF); // SBB H + assertEquals(0x9D, code.get(174) & 0xFF); // SBB L + assertEquals(0x9E, code.get(175) & 0xFF); // SBB M + assertEquals(0x9F, code.get(176) & 0xFF); // SBB A + assertEquals(0xA0, code.get(177) & 0xFF); // ANA B + assertEquals(0xA1, code.get(178) & 0xFF); // ANA C + assertEquals(0xA2, code.get(179) & 0xFF); // ANA D + assertEquals(0xA3, code.get(180) & 0xFF); // ANA E + assertEquals(0xA4, code.get(181) & 0xFF); // ANA H + assertEquals(0xA5, code.get(182) & 0xFF); // ANA L + assertEquals(0xA6, code.get(183) & 0xFF); // ANA M + assertEquals(0xA7, code.get(184) & 0xFF); // ANA A + assertEquals(0xA8, code.get(185) & 0xFF); // XRA B + assertEquals(0xA9, code.get(186) & 0xFF); // XRA C + assertEquals(0xAA, code.get(187) & 0xFF); // XRA D + assertEquals(0xAB, code.get(188) & 0xFF); // XRA E + assertEquals(0xAC, code.get(189) & 0xFF); // XRA H + assertEquals(0xAD, code.get(190) & 0xFF); // XRA L + assertEquals(0xAE, code.get(191) & 0xFF); // XRA M + assertEquals(0xAF, code.get(192) & 0xFF); // XRA A + assertEquals(0xB0, code.get(193) & 0xFF); // ORA B + assertEquals(0xB1, code.get(194) & 0xFF); // ORA C + assertEquals(0xB2, code.get(195) & 0xFF); // ORA D + assertEquals(0xB3, code.get(196) & 0xFF); // ORA E + assertEquals(0xB4, code.get(197) & 0xFF); // ORA H + assertEquals(0xB5, code.get(198) & 0xFF); // ORA L + assertEquals(0xB6, code.get(199) & 0xFF); // ORA M + assertEquals(0xB7, code.get(200) & 0xFF); // ORA A + assertEquals(0xB8, code.get(201) & 0xFF); // CMP B + assertEquals(0xB9, code.get(202) & 0xFF); // CMP C + assertEquals(0xBA, code.get(203) & 0xFF); // CMP D + assertEquals(0xBB, code.get(204) & 0xFF); // CMP E + assertEquals(0xBC, code.get(205) & 0xFF); // CMP H + assertEquals(0xBD, code.get(206) & 0xFF); // CMP L + assertEquals(0xBE, code.get(207) & 0xFF); // CMP M + assertEquals(0xBF, code.get(208) & 0xFF); // CMP A + assertEquals(0xC0, code.get(209) & 0xFF); // RNZ + assertEquals(0xC1, code.get(210) & 0xFF); // POP B + assertEquals(0xC2, code.get(211) & 0xFF); // JNZ + assertEquals(2, code.get(212).byteValue()); + assertEquals(0, code.get(213).byteValue()); + assertEquals(0xC3, code.get(214) & 0xFF); // JMP + assertEquals(0, code.get(215).byteValue()); + assertEquals(2, code.get(216).byteValue()); + assertEquals(0xC4, code.get(217) & 0xFF); // CNZ + assertEquals(0xA0, code.get(218) & 0xFF); + assertEquals(0xF0, code.get(219) & 0xFF); + assertEquals(0xC5, code.get(220) & 0xFF); // PUSH B + assertEquals(0xC6, code.get(221) & 0xFF); // ADI + assertEquals(0xF0, code.get(222) & 0xFF); + assertEquals(0xC7, code.get(223) & 0xFF); // RST 0 + assertEquals(0xC8, code.get(224) & 0xFF); // RZ + assertEquals(0xC9, code.get(225) & 0xFF); // RET + assertEquals(0xCA, code.get(226) & 0xFF); // JZ + assertEquals(0x34, code.get(227) & 0xFF); + assertEquals(0x12, code.get(228) & 0xFF); + assertEquals(0xCC, code.get(229) & 0xFF); // CZ + assertEquals(0x34, code.get(230) & 0xFF); + assertEquals(0x12, code.get(231) & 0xFF); + assertEquals(0xCD, code.get(232) & 0xFF); // CALL + assertEquals(0x34, code.get(233) & 0xFF); + assertEquals(0x12, code.get(234) & 0xFF); + assertEquals(0xCE, code.get(235) & 0xFF); // ACI + assertEquals(0xF0, code.get(236) & 0xFF); + assertEquals(0xCF, code.get(237) & 0xFF); // RST 1 + assertEquals(0xD0, code.get(238) & 0xFF); // RNC + assertEquals(0xD1, code.get(239) & 0xFF); // POP D + assertEquals(0xD2, code.get(240) & 0xFF); // JNC + assertEquals(0x34, code.get(241) & 0xFF); + assertEquals(0x12, code.get(242) & 0xFF); + assertEquals(0xD3, code.get(243) & 0xFF); // OUT + assertEquals(0xF0, code.get(244) & 0xFF); + assertEquals(0xD4, code.get(245) & 0xFF); // CNC + assertEquals(0x34, code.get(246) & 0xFF); + assertEquals(0x12, code.get(247) & 0xFF); + assertEquals(0xD5, code.get(248) & 0xFF); // PUSH D + assertEquals(0xD6, code.get(249) & 0xFF); // SUI + assertEquals(0xF0, code.get(250) & 0xFF); + assertEquals(0xD7, code.get(251) & 0xFF); // RST 2 + assertEquals(0xD8, code.get(252) & 0xFF); // RC + assertEquals(0xDA, code.get(253) & 0xFF); // JC + assertEquals(0x34, code.get(254) & 0xFF); + assertEquals(0x12, code.get(255) & 0xFF); + assertEquals(0xDB, code.get(256) & 0xFF); // IN + assertEquals(0xF0, code.get(257) & 0xFF); + assertEquals(0xDC, code.get(258) & 0xFF); // CC + assertEquals(0x34, code.get(259) & 0xFF); + assertEquals(0x12, code.get(260) & 0xFF); + assertEquals(0xDE, code.get(261) & 0xFF); // SBI + assertEquals(0xF0, code.get(262) & 0xFF); + assertEquals(0xDF, code.get(263) & 0xFF); // RST 3 + assertEquals(0xE0, code.get(264) & 0xFF); // RPO + assertEquals(0xE1, code.get(265) & 0xFF); // POP H + assertEquals(0xE2, code.get(266) & 0xFF); // JPO + assertEquals(0x34, code.get(267) & 0xFF); + assertEquals(0x12, code.get(268) & 0xFF); + assertEquals(0xE3, code.get(269) & 0xFF); // XTHL + assertEquals(0xE4, code.get(270) & 0xFF); // CPO + assertEquals(0x34, code.get(271) & 0xFF); + assertEquals(0x12, code.get(272) & 0xFF); + assertEquals(0xE5, code.get(273) & 0xFF); // PUSH H + assertEquals(0xE6, code.get(274) & 0xFF); // ANI + assertEquals(0xF0, code.get(275) & 0xFF); + assertEquals(0xE7, code.get(276) & 0xFF); // RST + assertEquals(0xE8, code.get(277) & 0xFF); // RPE + assertEquals(0xE9, code.get(278) & 0xFF); // PCHL + assertEquals(0xEA, code.get(279) & 0xFF); // JPE + assertEquals(0x34, code.get(280) & 0xFF); + assertEquals(0x12, code.get(281) & 0xFF); + assertEquals(0xEB, code.get(282) & 0xFF); // XCHG + assertEquals(0xEC, code.get(283) & 0xFF); // CPE + assertEquals(0x34, code.get(284) & 0xFF); + assertEquals(0x12, code.get(285) & 0xFF); + assertEquals(0xEE, code.get(286) & 0xFF); // XRI + assertEquals(0xF0, code.get(287) & 0xFF); + assertEquals(0xEF, code.get(288) & 0xFF); // RST + assertEquals(0xF0, code.get(289) & 0xFF); // RP + assertEquals(0xF1, code.get(290) & 0xFF); // POP PSW + assertEquals(0xF2, code.get(291) & 0xFF); // JP + assertEquals(0x00, code.get(292) & 0xFF); + assertEquals(0x02, code.get(293) & 0xFF); + assertEquals(0xF3, code.get(294) & 0xFF); // DI + assertEquals(0xF4, code.get(295) & 0xFF); // CP + assertEquals(0x00, code.get(296) & 0xFF); + assertEquals(0x02, code.get(297) & 0xFF); + assertEquals(0xF5, code.get(298) & 0xFF); // PUSH PSW + assertEquals(0xF6, code.get(299) & 0xFF); // ORI + assertEquals(0xF0, code.get(300) & 0xFF); + assertEquals(0xF7, code.get(301) & 0xFF); // RST 6 + assertEquals(0xF8, code.get(302) & 0xFF); // RM + assertEquals(0xF9, code.get(303) & 0xFF); // SPHL + assertEquals(0xFA, code.get(304) & 0xFF); // JM + assertEquals(0x00, code.get(305) & 0xFF); + assertEquals(0x02, code.get(306) & 0xFF); + assertEquals(0xFB, code.get(307) & 0xFF); // EI + assertEquals(0xFC, code.get(308) & 0xFF); // CM + assertEquals(0x00, code.get(309) & 0xFF); + assertEquals(0x02, code.get(310) & 0xFF); + assertEquals(0xFE, code.get(311) & 0xFF); // CPI + assertEquals(0xF0, code.get(312) & 0xFF); + assertEquals(0xFF, code.get(313) & 0xFF); // RST 7 + } +} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java new file mode 100644 index 000000000..38a68689b --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java @@ -0,0 +1,169 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.Program; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; +import org.junit.Test; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import static net.emustudio.plugins.compiler.asZ80.CompileError.ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH; +import static net.emustudio.plugins.compiler.asZ80.Utils.assertTrees; +import static org.junit.Assert.assertTrue; + +public class SortMacroArgumentsVisitorTest { + + @Test + public void testMacroArgumentsAreConnectedWithIds() { + Node program = new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "r"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "t"))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoEqu(0, 0, "uu") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprId(0, 0, "t")))))); + + SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); + visitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "t")) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoEqu(0, 0, "uu") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprId(0, 0, "t"))))), + program + ); + } + + @Test + public void testMultipleMacroCalls() { + Node program = new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))); + + SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); + visitor.visit(program); + + assertTrees(new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 2)))), + program + ); + } + + @Test + public void testNestedMacroCallWithSameNamedArgs() { + Node program = new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "y") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))))); + + SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); + visitor.visit(program); + + assertTrees( + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 3))))), + program + ); + } + + @Test + public void testMoreMacroArgumentsThanParameters() { + Program program = new Program(); + program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))); + + SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH)); + } + + @Test + public void testMoreMacroParametersThanArguments() { + Program program = new Program(); + program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "r"))))); + + SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); + visitor.visit(program); + + assertTrue(program.env().hasError(ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH)); + } +} From e751e6a44c740e7ead6df2c02ff3b16e9c1d87b8 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 9 Feb 2022 07:51:24 +0100 Subject: [PATCH 095/314] [#201] as-z80: wip --- .../as-z80/src/main/antlr/AsZ80Lexer.g4 | 4 +- .../as-z80/src/main/antlr/AsZ80Lexer.tokens | 177 +++---- .../as-z80/src/main/antlr/AsZ80Parser.g4 | 154 +++--- .../as-z80/src/main/gen/AsZ80Lexer.interp | 2 +- .../as-z80/src/main/gen/AsZ80Lexer.java | 241 +++++---- .../compiler/asZ80/CompilerTables.java | 91 ++++ .../plugins/compiler/asZ80/Pair.java | 15 + .../compiler/asZ80/ast/instr/Instr.java | 99 ++++ .../asZ80/ast/instr/InstrA_Ref_RP.java | 26 + .../compiler/asZ80/ast/instr/InstrC.java | 26 + .../compiler/asZ80/ast/instr/InstrC_N.java | 29 + .../compiler/asZ80/ast/instr/InstrC_NN.java | 28 + .../compiler/asZ80/ast/instr/InstrExpr.java | 117 ---- .../compiler/asZ80/ast/instr/InstrN.java | 134 +++++ .../compiler/asZ80/ast/instr/InstrNN.java | 25 + .../compiler/asZ80/ast/instr/InstrNoArgs.java | 80 --- .../ast/instr/{InstrReg.java => InstrR.java} | 39 +- .../instr/{InstrRegPair.java => InstrRP.java} | 29 +- ...{InstrRegPairExpr.java => InstrRP_NN.java} | 14 +- .../compiler/asZ80/ast/instr/InstrRP_RP.java | 30 ++ .../asZ80/ast/instr/InstrRP_Ref_NN.java | 27 + .../{InstrRegExpr.java => InstrR_N.java} | 16 +- .../instr/{InstrRegReg.java => InstrR_R.java} | 18 +- .../asZ80/ast/instr/InstrR_Ref_NN.java | 27 + .../asZ80/ast/instr/InstrRef_NN_R.java | 28 + .../compiler/asZ80/ast/instr/InstrRef_RP.java | 28 + .../asZ80/ast/instr/InstrRef_RP_RP.java | 28 + .../plugins/compiler/asZ80/tree/OC_Expr.java | 449 ++++++++-------- .../compiler/asZ80/tree/OC_ExprExpr.java | 136 +++-- .../compiler/asZ80/tree/OC_NoParams.java | 275 +++++----- .../plugins/compiler/asZ80/tree/OC_Reg.java | 111 ++-- .../compiler/asZ80/tree/OC_RegExpr.java | 180 +++---- .../asZ80/visitors/CheckExprSizesVisitor.java | 12 +- .../asZ80/visitors/CreateInstrVisitor.java | 112 +++- .../asZ80/visitors/CreatePseudoVisitor.java | 4 +- .../asZ80/visitors/EvaluateExprVisitor.java | 14 +- .../asZ80/visitors/ExpandIncludesVisitor.java | 4 +- .../asZ80/visitors/GenerateCodeVisitor.java | 14 +- .../compiler/asZ80/visitors/NodeVisitor.java | 58 +- .../plugins/compiler/asZ80/OC_ExprTest.java | 20 - .../compiler/asZ80/OC_RegExprTest.java | 35 -- .../plugins/compiler/asZ80/OC_RegTest.java | 372 ++++++------- .../plugins/compiler/asZ80/Utils.java | 6 +- .../asZ80/parser/LexicalAnalyzerImplTest.java | 144 +++-- .../compiler/asZ80/parser/ParseDataTest.java | 8 +- .../compiler/asZ80/parser/ParseInstrTest.java | 18 +- .../asZ80/parser/ParsePseudoTest.java | 12 +- .../visitors/CheckExprSizesVisitorTest.java | 30 +- .../visitors/EvaluateExprVisitorTest.java | 50 +- .../visitors/ExpandIncludesVisitorTest.java | 14 +- .../visitors/GenerateCodeVisitorTest.java | 500 +++++++++--------- .../SortMacroArgumentsVisitorTest.java | 6 +- 52 files changed, 2317 insertions(+), 1799 deletions(-) create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Pair.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrA_Ref_RP.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_N.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_NN.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrExpr.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrN.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNN.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNoArgs.java rename plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/{InstrReg.java => InstrR.java} (64%) rename plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/{InstrRegPair.java => InstrRP.java} (69%) rename plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/{InstrRegPairExpr.java => InstrRP_NN.java} (74%) create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_RP.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_Ref_NN.java rename plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/{InstrRegExpr.java => InstrR_N.java} (73%) rename plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/{InstrRegReg.java => InstrR_R.java} (71%) create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_Ref_NN.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_NN_R.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP_RP.java delete mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_ExprTest.java delete mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegExprTest.java diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 index c2afb4b58..0e7b791e6 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 @@ -109,8 +109,8 @@ COND_M: M -> popMode; COND_P: P -> popMode; COND_PE: P E -> popMode; COND_PO: P O -> popMode; -COND_WS : [ \t\f]+ -> skip; -COND_UNRECOGNIZED: {true}? -> popMode, channel(HIDDEN); // TODO +COND_WS: [ \t\f]+ -> skip; +COND_UNRECOGNIZED: ({"cCnNzZmMpP".indexOf((char) _input.LA(1)) == -1}?) -> popMode; mode DEFAULT_MODE; diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens index 64c701cbd..a4d6ab04f 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens @@ -81,92 +81,91 @@ COND_UNRECOGNIZED=80 PREP_ORG=81 PREP_EQU=82 PREP_SET=83 -PREP_VAR=84 -PREP_IF=85 -PREP_ENDIF=86 -PREP_INCLUDE=87 -PREP_MACRO=88 -PREP_ENDM=89 -PREP_DB=90 -PREP_DW=91 -PREP_DS=92 -PREP_ADDR=93 -REG_A=94 -REG_B=95 -REG_C=96 -REG_D=97 -REG_E=98 -REG_H=99 -REG_L=100 -REG_IX=101 -REG_IXH=102 -REG_IXL=103 -REG_IY=104 -REG_IYH=105 -REG_IYL=106 -REG_BC=107 -REG_DE=108 -REG_HL=109 -REG_SP=110 -REG_AF=111 -REG_AFF=112 -REG_I=113 -REG_R=114 -OP_MOD=115 -OP_SHR=116 -OP_SHL=117 -OP_NOT=118 -OP_AND=119 -OP_OR=120 -OP_XOR=121 -LIT_HEXNUMBER_1=122 -LIT_NUMBER=123 -LIT_HEXNUMBER_2=124 -LIT_OCTNUMBER=125 -LIT_BINNUMBER=126 -LIT_STRING_1=127 -LIT_STRING_2=128 -ID_IDENTIFIER=129 -ID_LABEL=130 -ERROR=131 -SEP_LPAR=132 -SEP_RPAR=133 -SEP_COMMA=134 -OP_ADD=135 -OP_SUBTRACT=136 -OP_MULTIPLY=137 -OP_DIVIDE=138 -OP_EQUAL=139 -OP_GT=140 -OP_GTE=141 -OP_LT=142 -OP_LTE=143 -OP_MOD_2=144 -OP_SHR_2=145 -OP_SHL_2=146 -OP_NOT_2=147 -OP_AND_2=148 -OP_OR_2=149 -OP_XOR_2=150 -WS=151 -EOL=152 -'$'=93 -'('=132 -')'=133 -','=134 -'+'=135 -'-'=136 -'*'=137 -'/'=138 -'='=139 -'>'=140 -'>='=141 -'<'=142 -'<='=143 -'%'=144 -'>>'=145 -'<<'=146 -'~'=147 -'&'=148 -'|'=149 -'^'=150 +PREP_IF=84 +PREP_ENDIF=85 +PREP_INCLUDE=86 +PREP_MACRO=87 +PREP_ENDM=88 +PREP_DB=89 +PREP_DW=90 +PREP_DS=91 +PREP_ADDR=92 +REG_A=93 +REG_B=94 +REG_C=95 +REG_D=96 +REG_E=97 +REG_H=98 +REG_L=99 +REG_IX=100 +REG_IXH=101 +REG_IXL=102 +REG_IY=103 +REG_IYH=104 +REG_IYL=105 +REG_BC=106 +REG_DE=107 +REG_HL=108 +REG_SP=109 +REG_AF=110 +REG_AFF=111 +REG_I=112 +REG_R=113 +OP_MOD=114 +OP_SHR=115 +OP_SHL=116 +OP_NOT=117 +OP_AND=118 +OP_OR=119 +OP_XOR=120 +LIT_HEXNUMBER_1=121 +LIT_NUMBER=122 +LIT_HEXNUMBER_2=123 +LIT_OCTNUMBER=124 +LIT_BINNUMBER=125 +LIT_STRING_1=126 +LIT_STRING_2=127 +ID_IDENTIFIER=128 +ID_LABEL=129 +ERROR=130 +SEP_LPAR=131 +SEP_RPAR=132 +SEP_COMMA=133 +OP_ADD=134 +OP_SUBTRACT=135 +OP_MULTIPLY=136 +OP_DIVIDE=137 +OP_EQUAL=138 +OP_GT=139 +OP_GTE=140 +OP_LT=141 +OP_LTE=142 +OP_MOD_2=143 +OP_SHR_2=144 +OP_SHL_2=145 +OP_NOT_2=146 +OP_AND_2=147 +OP_OR_2=148 +OP_XOR_2=149 +WS=150 +EOL=151 +'$'=92 +'('=131 +')'=132 +','=133 +'+'=134 +'-'=135 +'*'=136 +'/'=137 +'='=138 +'>'=139 +'>='=140 +'<'=141 +'<='=142 +'%'=143 +'>>'=144 +'<<'=145 +'~'=146 +'&'=147 +'|'=148 +'^'=149 diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 index d1d79912b..0fbc0431a 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 @@ -19,74 +19,83 @@ rStatement: ; rInstruction: - r8bitInstruction # instr8bit - | opcode=OPCODE_LD regpair=(REG_BC|REG_DE|REG_HL|REG_SP) SEP_COMMA expr=rExpression # instrRegPairExpr - | opcode=OPCODE_LD reg=rRegister SEP_COMMA expr=rExpression # instrRegExpr - | opcode=OPCODE_JR expr=rExpression # instrExpr - | opcode=OPCODE_JR cond=(COND_NZ|COND_Z|COND_NC|COND_C) SEP_COMMA expr=rExpression # instrCondExpr - | opcode=OPCODE_LD SEP_LPAR expr=rExpression SEP_RPAR SEP_COMMA regpair=REG_HL # instrRefExprRegPair - | opcode=OPCODE_LD regpair=REG_HL SEP_COMMA SEP_LPAR expr=rExpression SEP_RPAR # instrRegPairRefExpr - | opcode=OPCODE_LD SEP_LPAR expr=rExpression SEP_RPAR SEP_COMMA reg=REG_A # instrRefExprReg - | opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR expr=rExpression SEP_RPAR # instrRegRefExpr - | opcode=OPCODE_JP expr=rExpression # instrExpr - | opcode=OPCODE_JP cond=cCondition SEP_COMMA expr=rExpression # instrCondExpr - | opcode=OPCODE_CALL expr=rExpression # instrExpr - | opcode=OPCODE_CALL cond=cCondition SEP_COMMA expr=rExpression # instrCondExpr - | opcode=OPCODE_ADD REG_A SEP_COMMA expr=rExpression # instrExpr - | opcode=OPCODE_ADC REG_A SEP_COMMA expr=rExpression # instrExpr - | opcode=OPCODE_OUT SEP_LPAR expr=rExpression SEP_RPAR SEP_COMMA REG_A # instrRefExprReg - | opcode=OPCODE_SUB expr=rExpression # instrExpr - | opcode=OPCODE_IN REG_A SEP_COMMA SEP_LPAR expr=rExpression SEP_RPAR # instrRegRefExpr - | opcode=OPCODE_SBC REG_A SEP_COMMA expr=rExpression # instrExpr - | opcode=OPCODE_AND expr=rExpression # instrExpr - | opcode=OPCODE_XOR expr=rExpression # instrExpr - | opcode=OPCODE_OR expr=rExpression # instrExpr - | opcode=OPCODE_CP expr=rExpression # instrExpr + r8bitInstruction # instr8bit + | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_A # instrRef_NN_R + | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_HL # instrRef_NN_R + | opcode=OPCODE_LD r=rRegister SEP_COMMA n=rExpression # instrR_N + | opcode=OPCODE_LD r=REG_A SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrR_Ref_NN + | opcode=OPCODE_LD rp=rRegPair SEP_COMMA nn=rExpression # instrRP_NN + | opcode=OPCODE_LD rp=REG_HL SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrRP_Ref_NN + | opcode=OPCODE_JR c=(COND_NZ|COND_Z|COND_NC|COND_C) SEP_COMMA n=rExpression # instrC_N + | opcode=OPCODE_JP c=cCondition SEP_COMMA nn=rExpression # instrC_NN + | opcode=OPCODE_CALL c=cCondition SEP_COMMA nn=rExpression # instrC_NN + | opcode=OPCODE_JR n=rExpression # instrN + | opcode=OPCODE_JP nn=rExpression # instrNN + | opcode=OPCODE_CALL nn=rExpression # instrNN + | opcode=OPCODE_ADD REG_A SEP_COMMA n=rExpression # instrN + | opcode=OPCODE_ADC REG_A SEP_COMMA n=rExpression # instrN + | opcode=OPCODE_OUT SEP_LPAR n=rExpression SEP_RPAR SEP_COMMA REG_A # instrN + | opcode=OPCODE_SUB n=rExpression # instrN + | opcode=OPCODE_IN REG_A SEP_COMMA SEP_LPAR n=rExpression SEP_RPAR # instrN + | opcode=OPCODE_SBC REG_A SEP_COMMA n=rExpression # instrN + | opcode=OPCODE_AND n=rExpression # instrN + | opcode=OPCODE_XOR n=rExpression # instrN + | opcode=OPCODE_OR n=rExpression # instrN + | opcode=OPCODE_CP n=rExpression # instrN + + +//# | opcode=OPCODE_RLC +//# | opcode=OPCODE_RRC +//# | opcode=OPCODE_RL +//# | opcode=OPCODE_RR +//# | opcode=OPCODE_SLA +//# | opcode=OPCODE_SRA +//# | opcode=OPCODE_SLL +//# | opcode=OPCODE_SRL + ; r8bitInstruction: - opcode=OPCODE_NOP # instrNoArgs - | opcode=OPCODE_LD SEP_LPAR regpair=(REG_BC|REG_DE) SEP_RPAR SEP_COMMA REG_A # instrRefRegPairReg - | opcode=OPCODE_LD SEP_LPAR regpair=REG_HL SEP_RPAR SEP_COMMA reg=rRegister # instrRefRegPairReg - | opcode=OPCODE_INC regpair=(REG_BC|REG_DE|REG_HL|REG_SP) # instrRegPair - | opcode=OPCODE_INC reg=rRegister # instrReg - | opcode=OPCODE_DEC reg=rRegister # instrReg - | opcode=OPCODE_RLCA # instrNoArgs - | opcode=OPCODE_EX src=REG_AF SEP_COMMA dst=REG_AFF # instrRegPairRegPair - | opcode=OPCODE_EX src=REG_DE SEP_COMMA dst=REG_HL # instrRegPairRegPair - | opcode=OPCODE_EX SEP_LPAR src=REG_SP SEP_RPAR SEP_COMMA dst=REG_HL # instrRefRegPairRegPair - | opcode=OPCODE_ADD REG_HL SEP_COMMA regpair=(REG_BC|REG_DE|REG_HL|REG_SP) # instrRegPairRegPair - | opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR regpair=(REG_BC|REG_DE) SEP_RPAR # instrRegRefRegPair - | opcode=OPCODE_DEC regpair=(REG_BC|REG_DE|REG_HL|REG_SP) # instrRegPair - | opcode=OPCODE_RRCA # instrNoArgs - | opcode=OPCODE_RLA # instrNoArgs - | opcode=OPCODE_RRA # instrNoArgs - | opcode=OPCODE_DAA # instrNoArgs - | opcode=OPCODE_CPL # instrNoArgs - | opcode=OPCODE_INC SEP_LPAR regpair=REG_HL SEP_RPAR # instrRefRegPair - | opcode=OPCODE_DEC SEP_LPAR regpair=REG_HL SEP_RPAR # instrRefRegPair - | opcode=OPCODE_SCF # instrNoArgs - | opcode=OPCODE_CCF # instrNoArgs - | opcode=OPCODE_LD dst=rRegister SEP_COMMA src=rRegister # instrRegReg - | opcode=OPCODE_HALT # instrNoArgs - | opcode=OPCODE_ADD REG_A SEP_COMMA reg=rRegister # instrReg - | opcode=OPCODE_ADC REG_A SEP_COMMA reg=rRegister # instrReg - | opcode=OPCODE_SUB reg=rRegister # instrReg - | opcode=OPCODE_SBC REG_A SEP_COMMA reg=rRegister # instrReg - | opcode=OPCODE_AND reg=rRegister # instrReg - | opcode=OPCODE_XOR reg=rRegister # instrReg - | opcode=OPCODE_OR reg=rRegister # instrReg - | opcode=OPCODE_CP reg=rRegister # instrReg - | opcode=OPCODE_RET cond=cCondition # instrCond - | opcode=OPCODE_RET # instrNoArgs - | opcode=OPCODE_POP regpair=(REG_BC|REG_DE|REG_HL|REG_AF) # instrRegPair - | opcode=OPCODE_PUSH regpair=(REG_BC|REG_DE|REG_HL|REG_AF) # instrRegPair - | opcode=OPCODE_RST expr=rExpression # instr8bitExpr - | opcode=OPCODE_EXX # instrNoArgs - | opcode=OPCODE_JP SEP_LPAR regpair=REG_HL SEP_RPAR # instrRefRegPair - | opcode=OPCODE_DI # instrNoArgs - | opcode=OPCODE_LD dst=REG_SP SEP_COMMA src=REG_HL # instrRegPairRegPair - | opcode=OPCODE_EI # instrNoArgs + opcode=OPCODE_LD SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR SEP_COMMA REG_A # instrRef_RP + | opcode=OPCODE_JP SEP_LPAR REG_HL SEP_RPAR # instrRef_RP + | opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR # instrA_Ref_RP + | opcode=OPCODE_EX SEP_LPAR src=REG_SP SEP_RPAR SEP_COMMA dst=REG_HL # instrRef_RP_RP + | opcode=OPCODE_LD dst=rRegister SEP_COMMA src=rRegister # instrR_R + | opcode=OPCODE_LD dst=REG_SP SEP_COMMA src=REG_HL # instrRP_RP + | opcode=OPCODE_EX dst=REG_AF SEP_COMMA src=REG_AFF # instrRP_RP + | opcode=OPCODE_EX dst=REG_DE SEP_COMMA src=REG_HL # instrRP_RP + | opcode=OPCODE_INC rp=rRegPair # instrRP + | opcode=OPCODE_DEC rp=rRegPair # instrRP + | opcode=OPCODE_ADD REG_HL SEP_COMMA rp=rRegPair # instrRP + | opcode=OPCODE_POP rp2=rRegPair2 # instrRP2 + | opcode=OPCODE_PUSH rp2=rRegPair2 # instrRP2 + | opcode=OPCODE_INC r=rRegister # instrR + | opcode=OPCODE_DEC r=rRegister # instrR + | opcode=OPCODE_ADD REG_A SEP_COMMA r=rRegister # instrR + | opcode=OPCODE_ADC REG_A SEP_COMMA r=rRegister # instrR + | opcode=OPCODE_SUB r=rRegister # instrR + | opcode=OPCODE_SBC REG_A SEP_COMMA r=rRegister # instrR + | opcode=OPCODE_AND r=rRegister # instrR + | opcode=OPCODE_XOR r=rRegister # instrR + | opcode=OPCODE_OR r=rRegister # instrR + | opcode=OPCODE_CP r=rRegister # instrR + | opcode=OPCODE_RET c=cCondition # instrC + | opcode=OPCODE_RST n=rExpression # instr8bitN + | opcode=OPCODE_NOP # instr + | opcode=OPCODE_RLCA # instr + | opcode=OPCODE_RRCA # instr + | opcode=OPCODE_RLA # instr + | opcode=OPCODE_RRA # instr + | opcode=OPCODE_DJNZ # instr + | opcode=OPCODE_DAA # instr + | opcode=OPCODE_CPL # instr + | opcode=OPCODE_SCF # instr + | opcode=OPCODE_CCF # instr + | opcode=OPCODE_HALT # instr + | opcode=OPCODE_RET # instr + | opcode=OPCODE_EXX # instr + | opcode=OPCODE_DI # instr + | opcode=OPCODE_EI # instr ; rRegister: @@ -100,6 +109,21 @@ rRegister: | SEP_LPAR r=REG_HL SEP_RPAR ; +rRegPair: + REG_BC + | REG_DE + | REG_HL + | REG_SP + ; + +rRegPair2: + REG_BC + | REG_DE + | REG_HL + | REG_AF + ; + + cCondition: COND_C | COND_NC diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp index 742e9dbcc..d876ac554 100644 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp @@ -493,4 +493,4 @@ DEFAULT_MODE CONDITION atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 153, 1029, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 4, 154, 9, 154, 4, 155, 9, 155, 4, 156, 9, 156, 4, 157, 9, 157, 4, 158, 9, 158, 4, 159, 9, 159, 4, 160, 9, 160, 4, 161, 9, 161, 4, 162, 9, 162, 4, 163, 9, 163, 4, 164, 9, 164, 4, 165, 9, 165, 4, 166, 9, 166, 4, 167, 9, 167, 4, 168, 9, 168, 4, 169, 9, 169, 4, 170, 9, 170, 4, 171, 9, 171, 4, 172, 9, 172, 4, 173, 9, 173, 4, 174, 9, 174, 4, 175, 9, 175, 4, 176, 9, 176, 4, 177, 9, 177, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 362, 10, 2, 3, 2, 7, 2, 365, 10, 2, 12, 2, 14, 2, 368, 11, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 376, 10, 3, 12, 3, 14, 3, 379, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 104, 3, 105, 6, 105, 759, 10, 105, 13, 105, 14, 105, 760, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 129, 3, 130, 3, 130, 3, 130, 3, 130, 3, 131, 3, 131, 3, 131, 3, 131, 3, 132, 3, 132, 3, 132, 3, 133, 3, 133, 3, 133, 3, 134, 3, 134, 3, 134, 3, 135, 3, 135, 3, 135, 3, 136, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 3, 144, 3, 144, 3, 144, 3, 145, 3, 145, 3, 145, 3, 146, 3, 146, 3, 146, 3, 146, 3, 147, 3, 147, 3, 147, 6, 147, 910, 10, 147, 13, 147, 14, 147, 911, 3, 148, 6, 148, 915, 10, 148, 13, 148, 14, 148, 916, 3, 148, 5, 148, 920, 10, 148, 3, 149, 6, 149, 923, 10, 149, 13, 149, 14, 149, 924, 3, 149, 3, 149, 3, 150, 6, 150, 930, 10, 150, 13, 150, 14, 150, 931, 3, 150, 3, 150, 3, 151, 6, 151, 937, 10, 151, 13, 151, 14, 151, 938, 3, 151, 3, 151, 3, 152, 3, 152, 7, 152, 945, 10, 152, 12, 152, 14, 152, 948, 11, 152, 3, 152, 3, 152, 3, 153, 3, 153, 7, 153, 954, 10, 153, 12, 153, 14, 153, 957, 11, 153, 3, 153, 3, 153, 3, 154, 3, 154, 7, 154, 963, 10, 154, 12, 154, 14, 154, 966, 11, 154, 3, 155, 3, 155, 3, 155, 3, 156, 6, 156, 972, 10, 156, 13, 156, 14, 156, 973, 3, 157, 3, 157, 3, 158, 3, 158, 3, 159, 3, 159, 3, 160, 3, 160, 3, 161, 3, 161, 3, 162, 3, 162, 3, 163, 3, 163, 3, 164, 3, 164, 3, 165, 3, 165, 3, 166, 3, 166, 3, 166, 3, 167, 3, 167, 3, 168, 3, 168, 3, 168, 3, 169, 3, 169, 3, 170, 3, 170, 3, 170, 3, 171, 3, 171, 3, 171, 3, 172, 3, 172, 3, 173, 3, 173, 3, 174, 3, 174, 3, 175, 3, 175, 3, 176, 6, 176, 1019, 10, 176, 13, 176, 14, 176, 1020, 3, 176, 3, 176, 3, 177, 5, 177, 1026, 10, 177, 3, 177, 3, 177, 3, 377, 2, 178, 4, 3, 6, 4, 8, 2, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54, 2, 56, 2, 58, 5, 60, 6, 62, 7, 64, 8, 66, 9, 68, 10, 70, 11, 72, 12, 74, 13, 76, 14, 78, 15, 80, 16, 82, 17, 84, 18, 86, 19, 88, 20, 90, 21, 92, 22, 94, 23, 96, 24, 98, 25, 100, 26, 102, 27, 104, 28, 106, 29, 108, 30, 110, 31, 112, 32, 114, 33, 116, 34, 118, 35, 120, 36, 122, 37, 124, 38, 126, 39, 128, 40, 130, 41, 132, 42, 134, 43, 136, 44, 138, 45, 140, 46, 142, 47, 144, 48, 146, 49, 148, 50, 150, 51, 152, 52, 154, 53, 156, 54, 158, 55, 160, 56, 162, 57, 164, 58, 166, 59, 168, 60, 170, 61, 172, 62, 174, 63, 176, 64, 178, 65, 180, 66, 182, 67, 184, 68, 186, 69, 188, 70, 190, 71, 192, 72, 194, 73, 196, 74, 198, 75, 200, 76, 202, 77, 204, 78, 206, 79, 208, 80, 210, 81, 212, 82, 214, 83, 216, 84, 218, 85, 220, 86, 222, 87, 224, 88, 226, 89, 228, 90, 230, 91, 232, 92, 234, 93, 236, 94, 238, 95, 240, 96, 242, 97, 244, 98, 246, 99, 248, 100, 250, 101, 252, 102, 254, 103, 256, 104, 258, 105, 260, 106, 262, 107, 264, 108, 266, 109, 268, 110, 270, 111, 272, 112, 274, 113, 276, 114, 278, 115, 280, 116, 282, 117, 284, 118, 286, 119, 288, 120, 290, 121, 292, 122, 294, 123, 296, 124, 298, 125, 300, 126, 302, 127, 304, 128, 306, 129, 308, 130, 310, 131, 312, 132, 314, 133, 316, 134, 318, 135, 320, 136, 322, 137, 324, 138, 326, 139, 328, 140, 330, 141, 332, 142, 334, 143, 336, 144, 338, 145, 340, 146, 342, 147, 344, 148, 346, 149, 348, 150, 350, 151, 352, 152, 354, 153, 4, 2, 3, 40, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 5, 2, 11, 11, 14, 14, 34, 34, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 59, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 3, 2, 36, 36, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 12, 2, 11, 12, 14, 15, 34, 34, 39, 40, 42, 47, 49, 49, 62, 64, 96, 96, 126, 126, 128, 128, 2, 1019, 2, 4, 3, 2, 2, 2, 2, 6, 3, 2, 2, 2, 2, 58, 3, 2, 2, 2, 2, 60, 3, 2, 2, 2, 2, 62, 3, 2, 2, 2, 2, 64, 3, 2, 2, 2, 2, 66, 3, 2, 2, 2, 2, 68, 3, 2, 2, 2, 2, 70, 3, 2, 2, 2, 2, 72, 3, 2, 2, 2, 2, 74, 3, 2, 2, 2, 2, 76, 3, 2, 2, 2, 2, 78, 3, 2, 2, 2, 2, 80, 3, 2, 2, 2, 2, 82, 3, 2, 2, 2, 2, 84, 3, 2, 2, 2, 2, 86, 3, 2, 2, 2, 2, 88, 3, 2, 2, 2, 2, 90, 3, 2, 2, 2, 2, 92, 3, 2, 2, 2, 2, 94, 3, 2, 2, 2, 2, 96, 3, 2, 2, 2, 2, 98, 3, 2, 2, 2, 2, 100, 3, 2, 2, 2, 2, 102, 3, 2, 2, 2, 2, 104, 3, 2, 2, 2, 2, 106, 3, 2, 2, 2, 2, 108, 3, 2, 2, 2, 2, 110, 3, 2, 2, 2, 2, 112, 3, 2, 2, 2, 2, 114, 3, 2, 2, 2, 2, 116, 3, 2, 2, 2, 2, 118, 3, 2, 2, 2, 2, 120, 3, 2, 2, 2, 2, 122, 3, 2, 2, 2, 2, 124, 3, 2, 2, 2, 2, 126, 3, 2, 2, 2, 2, 128, 3, 2, 2, 2, 2, 130, 3, 2, 2, 2, 2, 132, 3, 2, 2, 2, 2, 134, 3, 2, 2, 2, 2, 136, 3, 2, 2, 2, 2, 138, 3, 2, 2, 2, 2, 140, 3, 2, 2, 2, 2, 142, 3, 2, 2, 2, 2, 144, 3, 2, 2, 2, 2, 146, 3, 2, 2, 2, 2, 148, 3, 2, 2, 2, 2, 150, 3, 2, 2, 2, 2, 152, 3, 2, 2, 2, 2, 154, 3, 2, 2, 2, 2, 156, 3, 2, 2, 2, 2, 158, 3, 2, 2, 2, 2, 160, 3, 2, 2, 2, 2, 162, 3, 2, 2, 2, 2, 164, 3, 2, 2, 2, 2, 166, 3, 2, 2, 2, 2, 168, 3, 2, 2, 2, 2, 170, 3, 2, 2, 2, 2, 172, 3, 2, 2, 2, 2, 174, 3, 2, 2, 2, 2, 176, 3, 2, 2, 2, 2, 178, 3, 2, 2, 2, 2, 180, 3, 2, 2, 2, 2, 182, 3, 2, 2, 2, 2, 184, 3, 2, 2, 2, 2, 186, 3, 2, 2, 2, 2, 188, 3, 2, 2, 2, 2, 190, 3, 2, 2, 2, 2, 192, 3, 2, 2, 2, 2, 214, 3, 2, 2, 2, 2, 216, 3, 2, 2, 2, 2, 218, 3, 2, 2, 2, 2, 220, 3, 2, 2, 2, 2, 222, 3, 2, 2, 2, 2, 224, 3, 2, 2, 2, 2, 226, 3, 2, 2, 2, 2, 228, 3, 2, 2, 2, 2, 230, 3, 2, 2, 2, 2, 232, 3, 2, 2, 2, 2, 234, 3, 2, 2, 2, 2, 236, 3, 2, 2, 2, 2, 238, 3, 2, 2, 2, 2, 240, 3, 2, 2, 2, 2, 242, 3, 2, 2, 2, 2, 244, 3, 2, 2, 2, 2, 246, 3, 2, 2, 2, 2, 248, 3, 2, 2, 2, 2, 250, 3, 2, 2, 2, 2, 252, 3, 2, 2, 2, 2, 254, 3, 2, 2, 2, 2, 256, 3, 2, 2, 2, 2, 258, 3, 2, 2, 2, 2, 260, 3, 2, 2, 2, 2, 262, 3, 2, 2, 2, 2, 264, 3, 2, 2, 2, 2, 266, 3, 2, 2, 2, 2, 268, 3, 2, 2, 2, 2, 270, 3, 2, 2, 2, 2, 272, 3, 2, 2, 2, 2, 274, 3, 2, 2, 2, 2, 276, 3, 2, 2, 2, 2, 278, 3, 2, 2, 2, 2, 280, 3, 2, 2, 2, 2, 282, 3, 2, 2, 2, 2, 284, 3, 2, 2, 2, 2, 286, 3, 2, 2, 2, 2, 288, 3, 2, 2, 2, 2, 290, 3, 2, 2, 2, 2, 292, 3, 2, 2, 2, 2, 294, 3, 2, 2, 2, 2, 296, 3, 2, 2, 2, 2, 298, 3, 2, 2, 2, 2, 300, 3, 2, 2, 2, 2, 302, 3, 2, 2, 2, 2, 304, 3, 2, 2, 2, 2, 306, 3, 2, 2, 2, 2, 308, 3, 2, 2, 2, 2, 310, 3, 2, 2, 2, 2, 312, 3, 2, 2, 2, 2, 314, 3, 2, 2, 2, 2, 316, 3, 2, 2, 2, 2, 318, 3, 2, 2, 2, 2, 320, 3, 2, 2, 2, 2, 322, 3, 2, 2, 2, 2, 324, 3, 2, 2, 2, 2, 326, 3, 2, 2, 2, 2, 328, 3, 2, 2, 2, 2, 330, 3, 2, 2, 2, 2, 332, 3, 2, 2, 2, 2, 334, 3, 2, 2, 2, 2, 336, 3, 2, 2, 2, 2, 338, 3, 2, 2, 2, 2, 340, 3, 2, 2, 2, 2, 342, 3, 2, 2, 2, 2, 344, 3, 2, 2, 2, 2, 346, 3, 2, 2, 2, 2, 348, 3, 2, 2, 2, 2, 350, 3, 2, 2, 2, 2, 352, 3, 2, 2, 2, 2, 354, 3, 2, 2, 2, 3, 194, 3, 2, 2, 2, 3, 196, 3, 2, 2, 2, 3, 198, 3, 2, 2, 2, 3, 200, 3, 2, 2, 2, 3, 202, 3, 2, 2, 2, 3, 204, 3, 2, 2, 2, 3, 206, 3, 2, 2, 2, 3, 208, 3, 2, 2, 2, 3, 210, 3, 2, 2, 2, 3, 212, 3, 2, 2, 2, 4, 361, 3, 2, 2, 2, 6, 371, 3, 2, 2, 2, 8, 385, 3, 2, 2, 2, 10, 387, 3, 2, 2, 2, 12, 389, 3, 2, 2, 2, 14, 391, 3, 2, 2, 2, 16, 393, 3, 2, 2, 2, 18, 395, 3, 2, 2, 2, 20, 397, 3, 2, 2, 2, 22, 399, 3, 2, 2, 2, 24, 401, 3, 2, 2, 2, 26, 403, 3, 2, 2, 2, 28, 405, 3, 2, 2, 2, 30, 407, 3, 2, 2, 2, 32, 409, 3, 2, 2, 2, 34, 411, 3, 2, 2, 2, 36, 413, 3, 2, 2, 2, 38, 415, 3, 2, 2, 2, 40, 417, 3, 2, 2, 2, 42, 419, 3, 2, 2, 2, 44, 421, 3, 2, 2, 2, 46, 423, 3, 2, 2, 2, 48, 425, 3, 2, 2, 2, 50, 427, 3, 2, 2, 2, 52, 429, 3, 2, 2, 2, 54, 431, 3, 2, 2, 2, 56, 433, 3, 2, 2, 2, 58, 435, 3, 2, 2, 2, 60, 439, 3, 2, 2, 2, 62, 443, 3, 2, 2, 2, 64, 447, 3, 2, 2, 2, 66, 451, 3, 2, 2, 2, 68, 458, 3, 2, 2, 2, 70, 462, 3, 2, 2, 2, 72, 465, 3, 2, 2, 2, 74, 469, 3, 2, 2, 2, 76, 474, 3, 2, 2, 2, 78, 478, 3, 2, 2, 2, 80, 483, 3, 2, 2, 2, 82, 487, 3, 2, 2, 2, 84, 491, 3, 2, 2, 2, 86, 495, 3, 2, 2, 2, 88, 498, 3, 2, 2, 2, 90, 503, 3, 2, 2, 2, 92, 506, 3, 2, 2, 2, 94, 509, 3, 2, 2, 2, 96, 513, 3, 2, 2, 2, 98, 518, 3, 2, 2, 2, 100, 521, 3, 2, 2, 2, 102, 524, 3, 2, 2, 2, 104, 528, 3, 2, 2, 2, 106, 532, 3, 2, 2, 2, 108, 537, 3, 2, 2, 2, 110, 541, 3, 2, 2, 2, 112, 546, 3, 2, 2, 2, 114, 551, 3, 2, 2, 2, 116, 556, 3, 2, 2, 2, 118, 559, 3, 2, 2, 2, 120, 563, 3, 2, 2, 2, 122, 568, 3, 2, 2, 2, 124, 572, 3, 2, 2, 2, 126, 577, 3, 2, 2, 2, 128, 581, 3, 2, 2, 2, 130, 585, 3, 2, 2, 2, 132, 588, 3, 2, 2, 2, 134, 593, 3, 2, 2, 2, 136, 598, 3, 2, 2, 2, 138, 602, 3, 2, 2, 2, 140, 607, 3, 2, 2, 2, 142, 612, 3, 2, 2, 2, 144, 616, 3, 2, 2, 2, 146, 621, 3, 2, 2, 2, 148, 625, 3, 2, 2, 2, 150, 631, 3, 2, 2, 2, 152, 636, 3, 2, 2, 2, 154, 641, 3, 2, 2, 2, 156, 644, 3, 2, 2, 2, 158, 648, 3, 2, 2, 2, 160, 652, 3, 2, 2, 2, 162, 657, 3, 2, 2, 2, 164, 661, 3, 2, 2, 2, 166, 664, 3, 2, 2, 2, 168, 668, 3, 2, 2, 2, 170, 672, 3, 2, 2, 2, 172, 677, 3, 2, 2, 2, 174, 681, 3, 2, 2, 2, 176, 685, 3, 2, 2, 2, 178, 689, 3, 2, 2, 2, 180, 693, 3, 2, 2, 2, 182, 697, 3, 2, 2, 2, 184, 701, 3, 2, 2, 2, 186, 705, 3, 2, 2, 2, 188, 709, 3, 2, 2, 2, 190, 713, 3, 2, 2, 2, 192, 717, 3, 2, 2, 2, 194, 721, 3, 2, 2, 2, 196, 725, 3, 2, 2, 2, 198, 730, 3, 2, 2, 2, 200, 734, 3, 2, 2, 2, 202, 739, 3, 2, 2, 2, 204, 743, 3, 2, 2, 2, 206, 747, 3, 2, 2, 2, 208, 752, 3, 2, 2, 2, 210, 758, 3, 2, 2, 2, 212, 764, 3, 2, 2, 2, 214, 769, 3, 2, 2, 2, 216, 773, 3, 2, 2, 2, 218, 777, 3, 2, 2, 2, 220, 781, 3, 2, 2, 2, 222, 784, 3, 2, 2, 2, 224, 790, 3, 2, 2, 2, 226, 798, 3, 2, 2, 2, 228, 804, 3, 2, 2, 2, 230, 809, 3, 2, 2, 2, 232, 812, 3, 2, 2, 2, 234, 815, 3, 2, 2, 2, 236, 818, 3, 2, 2, 2, 238, 820, 3, 2, 2, 2, 240, 822, 3, 2, 2, 2, 242, 824, 3, 2, 2, 2, 244, 826, 3, 2, 2, 2, 246, 828, 3, 2, 2, 2, 248, 830, 3, 2, 2, 2, 250, 832, 3, 2, 2, 2, 252, 834, 3, 2, 2, 2, 254, 837, 3, 2, 2, 2, 256, 841, 3, 2, 2, 2, 258, 845, 3, 2, 2, 2, 260, 848, 3, 2, 2, 2, 262, 852, 3, 2, 2, 2, 264, 856, 3, 2, 2, 2, 266, 859, 3, 2, 2, 2, 268, 862, 3, 2, 2, 2, 270, 865, 3, 2, 2, 2, 272, 868, 3, 2, 2, 2, 274, 871, 3, 2, 2, 2, 276, 875, 3, 2, 2, 2, 278, 877, 3, 2, 2, 2, 280, 879, 3, 2, 2, 2, 282, 883, 3, 2, 2, 2, 284, 887, 3, 2, 2, 2, 286, 891, 3, 2, 2, 2, 288, 895, 3, 2, 2, 2, 290, 899, 3, 2, 2, 2, 292, 902, 3, 2, 2, 2, 294, 906, 3, 2, 2, 2, 296, 914, 3, 2, 2, 2, 298, 922, 3, 2, 2, 2, 300, 929, 3, 2, 2, 2, 302, 936, 3, 2, 2, 2, 304, 942, 3, 2, 2, 2, 306, 951, 3, 2, 2, 2, 308, 960, 3, 2, 2, 2, 310, 967, 3, 2, 2, 2, 312, 971, 3, 2, 2, 2, 314, 975, 3, 2, 2, 2, 316, 977, 3, 2, 2, 2, 318, 979, 3, 2, 2, 2, 320, 981, 3, 2, 2, 2, 322, 983, 3, 2, 2, 2, 324, 985, 3, 2, 2, 2, 326, 987, 3, 2, 2, 2, 328, 989, 3, 2, 2, 2, 330, 991, 3, 2, 2, 2, 332, 993, 3, 2, 2, 2, 334, 996, 3, 2, 2, 2, 336, 998, 3, 2, 2, 2, 338, 1001, 3, 2, 2, 2, 340, 1003, 3, 2, 2, 2, 342, 1006, 3, 2, 2, 2, 344, 1009, 3, 2, 2, 2, 346, 1011, 3, 2, 2, 2, 348, 1013, 3, 2, 2, 2, 350, 1015, 3, 2, 2, 2, 352, 1018, 3, 2, 2, 2, 354, 1025, 3, 2, 2, 2, 356, 357, 7, 49, 2, 2, 357, 362, 7, 49, 2, 2, 358, 359, 7, 47, 2, 2, 359, 362, 7, 47, 2, 2, 360, 362, 9, 2, 2, 2, 361, 356, 3, 2, 2, 2, 361, 358, 3, 2, 2, 2, 361, 360, 3, 2, 2, 2, 362, 366, 3, 2, 2, 2, 363, 365, 10, 3, 2, 2, 364, 363, 3, 2, 2, 2, 365, 368, 3, 2, 2, 2, 366, 364, 3, 2, 2, 2, 366, 367, 3, 2, 2, 2, 367, 369, 3, 2, 2, 2, 368, 366, 3, 2, 2, 2, 369, 370, 8, 2, 2, 2, 370, 5, 3, 2, 2, 2, 371, 372, 7, 49, 2, 2, 372, 373, 7, 44, 2, 2, 373, 377, 3, 2, 2, 2, 374, 376, 11, 2, 2, 2, 375, 374, 3, 2, 2, 2, 376, 379, 3, 2, 2, 2, 377, 378, 3, 2, 2, 2, 377, 375, 3, 2, 2, 2, 378, 380, 3, 2, 2, 2, 379, 377, 3, 2, 2, 2, 380, 381, 7, 44, 2, 2, 381, 382, 7, 49, 2, 2, 382, 383, 3, 2, 2, 2, 383, 384, 8, 3, 2, 2, 384, 7, 3, 2, 2, 2, 385, 386, 9, 4, 2, 2, 386, 9, 3, 2, 2, 2, 387, 388, 9, 5, 2, 2, 388, 11, 3, 2, 2, 2, 389, 390, 9, 6, 2, 2, 390, 13, 3, 2, 2, 2, 391, 392, 9, 7, 2, 2, 392, 15, 3, 2, 2, 2, 393, 394, 9, 8, 2, 2, 394, 17, 3, 2, 2, 2, 395, 396, 9, 9, 2, 2, 396, 19, 3, 2, 2, 2, 397, 398, 9, 10, 2, 2, 398, 21, 3, 2, 2, 2, 399, 400, 9, 11, 2, 2, 400, 23, 3, 2, 2, 2, 401, 402, 9, 12, 2, 2, 402, 25, 3, 2, 2, 2, 403, 404, 9, 13, 2, 2, 404, 27, 3, 2, 2, 2, 405, 406, 9, 14, 2, 2, 406, 29, 3, 2, 2, 2, 407, 408, 9, 15, 2, 2, 408, 31, 3, 2, 2, 2, 409, 410, 9, 16, 2, 2, 410, 33, 3, 2, 2, 2, 411, 412, 9, 17, 2, 2, 412, 35, 3, 2, 2, 2, 413, 414, 9, 18, 2, 2, 414, 37, 3, 2, 2, 2, 415, 416, 9, 19, 2, 2, 416, 39, 3, 2, 2, 2, 417, 418, 9, 20, 2, 2, 418, 41, 3, 2, 2, 2, 419, 420, 9, 21, 2, 2, 420, 43, 3, 2, 2, 2, 421, 422, 9, 22, 2, 2, 422, 45, 3, 2, 2, 2, 423, 424, 9, 23, 2, 2, 424, 47, 3, 2, 2, 2, 425, 426, 9, 24, 2, 2, 426, 49, 3, 2, 2, 2, 427, 428, 9, 25, 2, 2, 428, 51, 3, 2, 2, 2, 429, 430, 9, 26, 2, 2, 430, 53, 3, 2, 2, 2, 431, 432, 9, 27, 2, 2, 432, 55, 3, 2, 2, 2, 433, 434, 9, 28, 2, 2, 434, 57, 3, 2, 2, 2, 435, 436, 5, 8, 4, 2, 436, 437, 5, 14, 7, 2, 437, 438, 5, 12, 6, 2, 438, 59, 3, 2, 2, 2, 439, 440, 5, 8, 4, 2, 440, 441, 5, 14, 7, 2, 441, 442, 5, 14, 7, 2, 442, 61, 3, 2, 2, 2, 443, 444, 5, 8, 4, 2, 444, 445, 5, 32, 16, 2, 445, 446, 5, 14, 7, 2, 446, 63, 3, 2, 2, 2, 447, 448, 5, 10, 5, 2, 448, 449, 5, 24, 12, 2, 449, 450, 5, 44, 22, 2, 450, 65, 3, 2, 2, 2, 451, 452, 5, 12, 6, 2, 452, 453, 5, 8, 4, 2, 453, 454, 5, 28, 14, 2, 454, 455, 5, 28, 14, 2, 455, 456, 3, 2, 2, 2, 456, 457, 8, 33, 3, 2, 457, 67, 3, 2, 2, 2, 458, 459, 5, 12, 6, 2, 459, 460, 5, 12, 6, 2, 460, 461, 5, 18, 9, 2, 461, 69, 3, 2, 2, 2, 462, 463, 5, 12, 6, 2, 463, 464, 5, 36, 18, 2, 464, 71, 3, 2, 2, 2, 465, 466, 5, 12, 6, 2, 466, 467, 5, 36, 18, 2, 467, 468, 5, 14, 7, 2, 468, 73, 3, 2, 2, 2, 469, 470, 5, 12, 6, 2, 470, 471, 5, 36, 18, 2, 471, 472, 5, 14, 7, 2, 472, 473, 5, 40, 20, 2, 473, 75, 3, 2, 2, 2, 474, 475, 5, 12, 6, 2, 475, 476, 5, 36, 18, 2, 476, 477, 5, 24, 12, 2, 477, 77, 3, 2, 2, 2, 478, 479, 5, 12, 6, 2, 479, 480, 5, 36, 18, 2, 480, 481, 5, 24, 12, 2, 481, 482, 5, 40, 20, 2, 482, 79, 3, 2, 2, 2, 483, 484, 5, 12, 6, 2, 484, 485, 5, 36, 18, 2, 485, 486, 5, 28, 14, 2, 486, 81, 3, 2, 2, 2, 487, 488, 5, 14, 7, 2, 488, 489, 5, 8, 4, 2, 489, 490, 5, 8, 4, 2, 490, 83, 3, 2, 2, 2, 491, 492, 5, 14, 7, 2, 492, 493, 5, 16, 8, 2, 493, 494, 5, 12, 6, 2, 494, 85, 3, 2, 2, 2, 495, 496, 5, 14, 7, 2, 496, 497, 5, 24, 12, 2, 497, 87, 3, 2, 2, 2, 498, 499, 5, 14, 7, 2, 499, 500, 5, 26, 13, 2, 500, 501, 5, 32, 16, 2, 501, 502, 5, 56, 28, 2, 502, 89, 3, 2, 2, 2, 503, 504, 5, 16, 8, 2, 504, 505, 5, 24, 12, 2, 505, 91, 3, 2, 2, 2, 506, 507, 5, 16, 8, 2, 507, 508, 5, 52, 26, 2, 508, 93, 3, 2, 2, 2, 509, 510, 5, 16, 8, 2, 510, 511, 5, 52, 26, 2, 511, 512, 5, 52, 26, 2, 512, 95, 3, 2, 2, 2, 513, 514, 5, 22, 11, 2, 514, 515, 5, 8, 4, 2, 515, 516, 5, 28, 14, 2, 516, 517, 5, 44, 22, 2, 517, 97, 3, 2, 2, 2, 518, 519, 5, 24, 12, 2, 519, 520, 5, 30, 15, 2, 520, 99, 3, 2, 2, 2, 521, 522, 5, 24, 12, 2, 522, 523, 5, 32, 16, 2, 523, 101, 3, 2, 2, 2, 524, 525, 5, 24, 12, 2, 525, 526, 5, 32, 16, 2, 526, 527, 5, 12, 6, 2, 527, 103, 3, 2, 2, 2, 528, 529, 5, 24, 12, 2, 529, 530, 5, 32, 16, 2, 530, 531, 5, 14, 7, 2, 531, 105, 3, 2, 2, 2, 532, 533, 5, 24, 12, 2, 533, 534, 5, 32, 16, 2, 534, 535, 5, 14, 7, 2, 535, 536, 5, 40, 20, 2, 536, 107, 3, 2, 2, 2, 537, 538, 5, 24, 12, 2, 538, 539, 5, 32, 16, 2, 539, 540, 5, 24, 12, 2, 540, 109, 3, 2, 2, 2, 541, 542, 5, 24, 12, 2, 542, 543, 5, 32, 16, 2, 543, 544, 5, 24, 12, 2, 544, 545, 5, 40, 20, 2, 545, 111, 3, 2, 2, 2, 546, 547, 5, 26, 13, 2, 547, 548, 5, 36, 18, 2, 548, 549, 3, 2, 2, 2, 549, 550, 8, 56, 3, 2, 550, 113, 3, 2, 2, 2, 551, 552, 5, 26, 13, 2, 552, 553, 5, 40, 20, 2, 553, 554, 3, 2, 2, 2, 554, 555, 8, 57, 3, 2, 555, 115, 3, 2, 2, 2, 556, 557, 5, 28, 14, 2, 557, 558, 5, 14, 7, 2, 558, 117, 3, 2, 2, 2, 559, 560, 5, 28, 14, 2, 560, 561, 5, 14, 7, 2, 561, 562, 5, 14, 7, 2, 562, 119, 3, 2, 2, 2, 563, 564, 5, 28, 14, 2, 564, 565, 5, 14, 7, 2, 565, 566, 5, 14, 7, 2, 566, 567, 5, 40, 20, 2, 567, 121, 3, 2, 2, 2, 568, 569, 5, 28, 14, 2, 569, 570, 5, 14, 7, 2, 570, 571, 5, 24, 12, 2, 571, 123, 3, 2, 2, 2, 572, 573, 5, 28, 14, 2, 573, 574, 5, 14, 7, 2, 574, 575, 5, 24, 12, 2, 575, 576, 5, 40, 20, 2, 576, 125, 3, 2, 2, 2, 577, 578, 5, 32, 16, 2, 578, 579, 5, 16, 8, 2, 579, 580, 5, 20, 10, 2, 580, 127, 3, 2, 2, 2, 581, 582, 5, 32, 16, 2, 582, 583, 5, 34, 17, 2, 583, 584, 5, 36, 18, 2, 584, 129, 3, 2, 2, 2, 585, 586, 5, 34, 17, 2, 586, 587, 5, 40, 20, 2, 587, 131, 3, 2, 2, 2, 588, 589, 5, 34, 17, 2, 589, 590, 5, 44, 22, 2, 590, 591, 5, 14, 7, 2, 591, 592, 5, 40, 20, 2, 592, 133, 3, 2, 2, 2, 593, 594, 5, 34, 17, 2, 594, 595, 5, 44, 22, 2, 595, 596, 5, 24, 12, 2, 596, 597, 5, 40, 20, 2, 597, 135, 3, 2, 2, 2, 598, 599, 5, 34, 17, 2, 599, 600, 5, 46, 23, 2, 600, 601, 5, 44, 22, 2, 601, 137, 3, 2, 2, 2, 602, 603, 5, 34, 17, 2, 603, 604, 5, 46, 23, 2, 604, 605, 5, 44, 22, 2, 605, 606, 5, 14, 7, 2, 606, 139, 3, 2, 2, 2, 607, 608, 5, 34, 17, 2, 608, 609, 5, 46, 23, 2, 609, 610, 5, 44, 22, 2, 610, 611, 5, 24, 12, 2, 611, 141, 3, 2, 2, 2, 612, 613, 5, 36, 18, 2, 613, 614, 5, 34, 17, 2, 614, 615, 5, 36, 18, 2, 615, 143, 3, 2, 2, 2, 616, 617, 5, 36, 18, 2, 617, 618, 5, 46, 23, 2, 618, 619, 5, 42, 21, 2, 619, 620, 5, 22, 11, 2, 620, 145, 3, 2, 2, 2, 621, 622, 5, 40, 20, 2, 622, 623, 5, 16, 8, 2, 623, 624, 5, 42, 21, 2, 624, 147, 3, 2, 2, 2, 625, 626, 5, 40, 20, 2, 626, 627, 5, 16, 8, 2, 627, 628, 5, 44, 22, 2, 628, 629, 3, 2, 2, 2, 629, 630, 8, 74, 3, 2, 630, 149, 3, 2, 2, 2, 631, 632, 5, 40, 20, 2, 632, 633, 5, 16, 8, 2, 633, 634, 5, 44, 22, 2, 634, 635, 5, 24, 12, 2, 635, 151, 3, 2, 2, 2, 636, 637, 5, 40, 20, 2, 637, 638, 5, 16, 8, 2, 638, 639, 5, 44, 22, 2, 639, 640, 5, 32, 16, 2, 640, 153, 3, 2, 2, 2, 641, 642, 5, 40, 20, 2, 642, 643, 5, 28, 14, 2, 643, 155, 3, 2, 2, 2, 644, 645, 5, 40, 20, 2, 645, 646, 5, 28, 14, 2, 646, 647, 5, 8, 4, 2, 647, 157, 3, 2, 2, 2, 648, 649, 5, 40, 20, 2, 649, 650, 5, 28, 14, 2, 650, 651, 5, 12, 6, 2, 651, 159, 3, 2, 2, 2, 652, 653, 5, 40, 20, 2, 653, 654, 5, 28, 14, 2, 654, 655, 5, 12, 6, 2, 655, 656, 5, 8, 4, 2, 656, 161, 3, 2, 2, 2, 657, 658, 5, 40, 20, 2, 658, 659, 5, 28, 14, 2, 659, 660, 5, 14, 7, 2, 660, 163, 3, 2, 2, 2, 661, 662, 5, 40, 20, 2, 662, 663, 5, 40, 20, 2, 663, 165, 3, 2, 2, 2, 664, 665, 5, 40, 20, 2, 665, 666, 5, 40, 20, 2, 666, 667, 5, 8, 4, 2, 667, 167, 3, 2, 2, 2, 668, 669, 5, 40, 20, 2, 669, 670, 5, 40, 20, 2, 670, 671, 5, 12, 6, 2, 671, 169, 3, 2, 2, 2, 672, 673, 5, 40, 20, 2, 673, 674, 5, 40, 20, 2, 674, 675, 5, 12, 6, 2, 675, 676, 5, 8, 4, 2, 676, 171, 3, 2, 2, 2, 677, 678, 5, 40, 20, 2, 678, 679, 5, 40, 20, 2, 679, 680, 5, 14, 7, 2, 680, 173, 3, 2, 2, 2, 681, 682, 5, 40, 20, 2, 682, 683, 5, 42, 21, 2, 683, 684, 5, 44, 22, 2, 684, 175, 3, 2, 2, 2, 685, 686, 5, 42, 21, 2, 686, 687, 5, 10, 5, 2, 687, 688, 5, 12, 6, 2, 688, 177, 3, 2, 2, 2, 689, 690, 5, 42, 21, 2, 690, 691, 5, 12, 6, 2, 691, 692, 5, 18, 9, 2, 692, 179, 3, 2, 2, 2, 693, 694, 5, 42, 21, 2, 694, 695, 5, 16, 8, 2, 695, 696, 5, 44, 22, 2, 696, 181, 3, 2, 2, 2, 697, 698, 5, 42, 21, 2, 698, 699, 5, 28, 14, 2, 699, 700, 5, 8, 4, 2, 700, 183, 3, 2, 2, 2, 701, 702, 5, 42, 21, 2, 702, 703, 5, 40, 20, 2, 703, 704, 5, 8, 4, 2, 704, 185, 3, 2, 2, 2, 705, 706, 5, 42, 21, 2, 706, 707, 5, 28, 14, 2, 707, 708, 5, 28, 14, 2, 708, 187, 3, 2, 2, 2, 709, 710, 5, 42, 21, 2, 710, 711, 5, 40, 20, 2, 711, 712, 5, 28, 14, 2, 712, 189, 3, 2, 2, 2, 713, 714, 5, 42, 21, 2, 714, 715, 5, 46, 23, 2, 715, 716, 5, 10, 5, 2, 716, 191, 3, 2, 2, 2, 717, 718, 5, 52, 26, 2, 718, 719, 5, 34, 17, 2, 719, 720, 5, 40, 20, 2, 720, 193, 3, 2, 2, 2, 721, 722, 5, 12, 6, 2, 722, 723, 3, 2, 2, 2, 723, 724, 8, 97, 4, 2, 724, 195, 3, 2, 2, 2, 725, 726, 5, 32, 16, 2, 726, 727, 5, 12, 6, 2, 727, 728, 3, 2, 2, 2, 728, 729, 8, 98, 4, 2, 729, 197, 3, 2, 2, 2, 730, 731, 5, 56, 28, 2, 731, 732, 3, 2, 2, 2, 732, 733, 8, 99, 4, 2, 733, 199, 3, 2, 2, 2, 734, 735, 5, 32, 16, 2, 735, 736, 5, 56, 28, 2, 736, 737, 3, 2, 2, 2, 737, 738, 8, 100, 4, 2, 738, 201, 3, 2, 2, 2, 739, 740, 5, 30, 15, 2, 740, 741, 3, 2, 2, 2, 741, 742, 8, 101, 4, 2, 742, 203, 3, 2, 2, 2, 743, 744, 5, 36, 18, 2, 744, 745, 3, 2, 2, 2, 745, 746, 8, 102, 4, 2, 746, 205, 3, 2, 2, 2, 747, 748, 5, 36, 18, 2, 748, 749, 5, 16, 8, 2, 749, 750, 3, 2, 2, 2, 750, 751, 8, 103, 4, 2, 751, 207, 3, 2, 2, 2, 752, 753, 5, 36, 18, 2, 753, 754, 5, 34, 17, 2, 754, 755, 3, 2, 2, 2, 755, 756, 8, 104, 4, 2, 756, 209, 3, 2, 2, 2, 757, 759, 9, 29, 2, 2, 758, 757, 3, 2, 2, 2, 759, 760, 3, 2, 2, 2, 760, 758, 3, 2, 2, 2, 760, 761, 3, 2, 2, 2, 761, 762, 3, 2, 2, 2, 762, 763, 8, 105, 2, 2, 763, 211, 3, 2, 2, 2, 764, 765, 6, 106, 2, 2, 765, 766, 3, 2, 2, 2, 766, 767, 8, 106, 4, 2, 767, 768, 8, 106, 5, 2, 768, 213, 3, 2, 2, 2, 769, 770, 5, 34, 17, 2, 770, 771, 5, 40, 20, 2, 771, 772, 5, 20, 10, 2, 772, 215, 3, 2, 2, 2, 773, 774, 5, 16, 8, 2, 774, 775, 5, 38, 19, 2, 775, 776, 5, 46, 23, 2, 776, 217, 3, 2, 2, 2, 777, 778, 5, 42, 21, 2, 778, 779, 5, 16, 8, 2, 779, 780, 5, 44, 22, 2, 780, 219, 3, 2, 2, 2, 781, 782, 5, 24, 12, 2, 782, 783, 5, 18, 9, 2, 783, 221, 3, 2, 2, 2, 784, 785, 5, 16, 8, 2, 785, 786, 5, 32, 16, 2, 786, 787, 5, 14, 7, 2, 787, 788, 5, 24, 12, 2, 788, 789, 5, 18, 9, 2, 789, 223, 3, 2, 2, 2, 790, 791, 5, 24, 12, 2, 791, 792, 5, 32, 16, 2, 792, 793, 5, 12, 6, 2, 793, 794, 5, 28, 14, 2, 794, 795, 5, 46, 23, 2, 795, 796, 5, 14, 7, 2, 796, 797, 5, 16, 8, 2, 797, 225, 3, 2, 2, 2, 798, 799, 5, 30, 15, 2, 799, 800, 5, 8, 4, 2, 800, 801, 5, 12, 6, 2, 801, 802, 5, 40, 20, 2, 802, 803, 5, 34, 17, 2, 803, 227, 3, 2, 2, 2, 804, 805, 5, 16, 8, 2, 805, 806, 5, 32, 16, 2, 806, 807, 5, 14, 7, 2, 807, 808, 5, 30, 15, 2, 808, 229, 3, 2, 2, 2, 809, 810, 5, 14, 7, 2, 810, 811, 5, 10, 5, 2, 811, 231, 3, 2, 2, 2, 812, 813, 5, 14, 7, 2, 813, 814, 5, 50, 25, 2, 814, 233, 3, 2, 2, 2, 815, 816, 5, 14, 7, 2, 816, 817, 5, 42, 21, 2, 817, 235, 3, 2, 2, 2, 818, 819, 7, 38, 2, 2, 819, 237, 3, 2, 2, 2, 820, 821, 5, 8, 4, 2, 821, 239, 3, 2, 2, 2, 822, 823, 5, 10, 5, 2, 823, 241, 3, 2, 2, 2, 824, 825, 5, 12, 6, 2, 825, 243, 3, 2, 2, 2, 826, 827, 5, 14, 7, 2, 827, 245, 3, 2, 2, 2, 828, 829, 5, 16, 8, 2, 829, 247, 3, 2, 2, 2, 830, 831, 5, 22, 11, 2, 831, 249, 3, 2, 2, 2, 832, 833, 5, 28, 14, 2, 833, 251, 3, 2, 2, 2, 834, 835, 5, 24, 12, 2, 835, 836, 5, 52, 26, 2, 836, 253, 3, 2, 2, 2, 837, 838, 5, 24, 12, 2, 838, 839, 5, 52, 26, 2, 839, 840, 5, 22, 11, 2, 840, 255, 3, 2, 2, 2, 841, 842, 5, 24, 12, 2, 842, 843, 5, 52, 26, 2, 843, 844, 5, 28, 14, 2, 844, 257, 3, 2, 2, 2, 845, 846, 5, 24, 12, 2, 846, 847, 5, 54, 27, 2, 847, 259, 3, 2, 2, 2, 848, 849, 5, 24, 12, 2, 849, 850, 5, 54, 27, 2, 850, 851, 5, 22, 11, 2, 851, 261, 3, 2, 2, 2, 852, 853, 5, 24, 12, 2, 853, 854, 5, 54, 27, 2, 854, 855, 5, 28, 14, 2, 855, 263, 3, 2, 2, 2, 856, 857, 5, 10, 5, 2, 857, 858, 5, 12, 6, 2, 858, 265, 3, 2, 2, 2, 859, 860, 5, 14, 7, 2, 860, 861, 5, 16, 8, 2, 861, 267, 3, 2, 2, 2, 862, 863, 5, 22, 11, 2, 863, 864, 5, 28, 14, 2, 864, 269, 3, 2, 2, 2, 865, 866, 5, 42, 21, 2, 866, 867, 5, 36, 18, 2, 867, 271, 3, 2, 2, 2, 868, 869, 5, 8, 4, 2, 869, 870, 5, 18, 9, 2, 870, 273, 3, 2, 2, 2, 871, 872, 5, 8, 4, 2, 872, 873, 5, 18, 9, 2, 873, 874, 7, 41, 2, 2, 874, 275, 3, 2, 2, 2, 875, 876, 5, 24, 12, 2, 876, 277, 3, 2, 2, 2, 877, 878, 5, 40, 20, 2, 878, 279, 3, 2, 2, 2, 879, 880, 5, 30, 15, 2, 880, 881, 5, 34, 17, 2, 881, 882, 5, 14, 7, 2, 882, 281, 3, 2, 2, 2, 883, 884, 5, 42, 21, 2, 884, 885, 5, 22, 11, 2, 885, 886, 5, 40, 20, 2, 886, 283, 3, 2, 2, 2, 887, 888, 5, 42, 21, 2, 888, 889, 5, 22, 11, 2, 889, 890, 5, 28, 14, 2, 890, 285, 3, 2, 2, 2, 891, 892, 5, 32, 16, 2, 892, 893, 5, 34, 17, 2, 893, 894, 5, 44, 22, 2, 894, 287, 3, 2, 2, 2, 895, 896, 5, 8, 4, 2, 896, 897, 5, 32, 16, 2, 897, 898, 5, 14, 7, 2, 898, 289, 3, 2, 2, 2, 899, 900, 5, 34, 17, 2, 900, 901, 5, 40, 20, 2, 901, 291, 3, 2, 2, 2, 902, 903, 5, 52, 26, 2, 903, 904, 5, 34, 17, 2, 904, 905, 5, 40, 20, 2, 905, 293, 3, 2, 2, 2, 906, 907, 7, 50, 2, 2, 907, 909, 5, 52, 26, 2, 908, 910, 9, 30, 2, 2, 909, 908, 3, 2, 2, 2, 910, 911, 3, 2, 2, 2, 911, 909, 3, 2, 2, 2, 911, 912, 3, 2, 2, 2, 912, 295, 3, 2, 2, 2, 913, 915, 9, 31, 2, 2, 914, 913, 3, 2, 2, 2, 915, 916, 3, 2, 2, 2, 916, 914, 3, 2, 2, 2, 916, 917, 3, 2, 2, 2, 917, 919, 3, 2, 2, 2, 918, 920, 5, 14, 7, 2, 919, 918, 3, 2, 2, 2, 919, 920, 3, 2, 2, 2, 920, 297, 3, 2, 2, 2, 921, 923, 9, 30, 2, 2, 922, 921, 3, 2, 2, 2, 923, 924, 3, 2, 2, 2, 924, 922, 3, 2, 2, 2, 924, 925, 3, 2, 2, 2, 925, 926, 3, 2, 2, 2, 926, 927, 5, 22, 11, 2, 927, 299, 3, 2, 2, 2, 928, 930, 9, 32, 2, 2, 929, 928, 3, 2, 2, 2, 930, 931, 3, 2, 2, 2, 931, 929, 3, 2, 2, 2, 931, 932, 3, 2, 2, 2, 932, 933, 3, 2, 2, 2, 933, 934, 9, 33, 2, 2, 934, 301, 3, 2, 2, 2, 935, 937, 9, 34, 2, 2, 936, 935, 3, 2, 2, 2, 937, 938, 3, 2, 2, 2, 938, 936, 3, 2, 2, 2, 938, 939, 3, 2, 2, 2, 939, 940, 3, 2, 2, 2, 940, 941, 5, 10, 5, 2, 941, 303, 3, 2, 2, 2, 942, 946, 7, 41, 2, 2, 943, 945, 10, 35, 2, 2, 944, 943, 3, 2, 2, 2, 945, 948, 3, 2, 2, 2, 946, 944, 3, 2, 2, 2, 946, 947, 3, 2, 2, 2, 947, 949, 3, 2, 2, 2, 948, 946, 3, 2, 2, 2, 949, 950, 7, 41, 2, 2, 950, 305, 3, 2, 2, 2, 951, 955, 7, 36, 2, 2, 952, 954, 10, 36, 2, 2, 953, 952, 3, 2, 2, 2, 954, 957, 3, 2, 2, 2, 955, 953, 3, 2, 2, 2, 955, 956, 3, 2, 2, 2, 956, 958, 3, 2, 2, 2, 957, 955, 3, 2, 2, 2, 958, 959, 7, 36, 2, 2, 959, 307, 3, 2, 2, 2, 960, 964, 9, 37, 2, 2, 961, 963, 9, 38, 2, 2, 962, 961, 3, 2, 2, 2, 963, 966, 3, 2, 2, 2, 964, 962, 3, 2, 2, 2, 964, 965, 3, 2, 2, 2, 965, 309, 3, 2, 2, 2, 966, 964, 3, 2, 2, 2, 967, 968, 5, 308, 154, 2, 968, 969, 7, 60, 2, 2, 969, 311, 3, 2, 2, 2, 970, 972, 10, 39, 2, 2, 971, 970, 3, 2, 2, 2, 972, 973, 3, 2, 2, 2, 973, 971, 3, 2, 2, 2, 973, 974, 3, 2, 2, 2, 974, 313, 3, 2, 2, 2, 975, 976, 7, 42, 2, 2, 976, 315, 3, 2, 2, 2, 977, 978, 7, 43, 2, 2, 978, 317, 3, 2, 2, 2, 979, 980, 7, 46, 2, 2, 980, 319, 3, 2, 2, 2, 981, 982, 7, 45, 2, 2, 982, 321, 3, 2, 2, 2, 983, 984, 7, 47, 2, 2, 984, 323, 3, 2, 2, 2, 985, 986, 7, 44, 2, 2, 986, 325, 3, 2, 2, 2, 987, 988, 7, 49, 2, 2, 988, 327, 3, 2, 2, 2, 989, 990, 7, 63, 2, 2, 990, 329, 3, 2, 2, 2, 991, 992, 7, 64, 2, 2, 992, 331, 3, 2, 2, 2, 993, 994, 7, 64, 2, 2, 994, 995, 7, 63, 2, 2, 995, 333, 3, 2, 2, 2, 996, 997, 7, 62, 2, 2, 997, 335, 3, 2, 2, 2, 998, 999, 7, 62, 2, 2, 999, 1000, 7, 63, 2, 2, 1000, 337, 3, 2, 2, 2, 1001, 1002, 7, 39, 2, 2, 1002, 339, 3, 2, 2, 2, 1003, 1004, 7, 64, 2, 2, 1004, 1005, 7, 64, 2, 2, 1005, 341, 3, 2, 2, 2, 1006, 1007, 7, 62, 2, 2, 1007, 1008, 7, 62, 2, 2, 1008, 343, 3, 2, 2, 2, 1009, 1010, 7, 128, 2, 2, 1010, 345, 3, 2, 2, 2, 1011, 1012, 7, 40, 2, 2, 1012, 347, 3, 2, 2, 2, 1013, 1014, 7, 126, 2, 2, 1014, 349, 3, 2, 2, 2, 1015, 1016, 7, 96, 2, 2, 1016, 351, 3, 2, 2, 2, 1017, 1019, 9, 29, 2, 2, 1018, 1017, 3, 2, 2, 2, 1019, 1020, 3, 2, 2, 2, 1020, 1018, 3, 2, 2, 2, 1020, 1021, 3, 2, 2, 2, 1021, 1022, 3, 2, 2, 2, 1022, 1023, 8, 176, 2, 2, 1023, 353, 3, 2, 2, 2, 1024, 1026, 7, 15, 2, 2, 1025, 1024, 3, 2, 2, 2, 1025, 1026, 3, 2, 2, 2, 1026, 1027, 3, 2, 2, 2, 1027, 1028, 7, 12, 2, 2, 1028, 355, 3, 2, 2, 2, 20, 2, 3, 361, 366, 377, 760, 911, 916, 919, 924, 931, 938, 946, 955, 964, 973, 1020, 1025, 6, 8, 2, 2, 7, 3, 2, 6, 2, 2, 2, 3, 2] \ No newline at end of file +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 153, 1028, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 4, 154, 9, 154, 4, 155, 9, 155, 4, 156, 9, 156, 4, 157, 9, 157, 4, 158, 9, 158, 4, 159, 9, 159, 4, 160, 9, 160, 4, 161, 9, 161, 4, 162, 9, 162, 4, 163, 9, 163, 4, 164, 9, 164, 4, 165, 9, 165, 4, 166, 9, 166, 4, 167, 9, 167, 4, 168, 9, 168, 4, 169, 9, 169, 4, 170, 9, 170, 4, 171, 9, 171, 4, 172, 9, 172, 4, 173, 9, 173, 4, 174, 9, 174, 4, 175, 9, 175, 4, 176, 9, 176, 4, 177, 9, 177, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 362, 10, 2, 3, 2, 7, 2, 365, 10, 2, 12, 2, 14, 2, 368, 11, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 376, 10, 3, 12, 3, 14, 3, 379, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 104, 3, 105, 6, 105, 759, 10, 105, 13, 105, 14, 105, 760, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 129, 3, 130, 3, 130, 3, 130, 3, 130, 3, 131, 3, 131, 3, 131, 3, 131, 3, 132, 3, 132, 3, 132, 3, 133, 3, 133, 3, 133, 3, 134, 3, 134, 3, 134, 3, 135, 3, 135, 3, 135, 3, 136, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 3, 144, 3, 144, 3, 144, 3, 145, 3, 145, 3, 145, 3, 146, 3, 146, 3, 146, 3, 146, 3, 147, 3, 147, 3, 147, 6, 147, 909, 10, 147, 13, 147, 14, 147, 910, 3, 148, 6, 148, 914, 10, 148, 13, 148, 14, 148, 915, 3, 148, 5, 148, 919, 10, 148, 3, 149, 6, 149, 922, 10, 149, 13, 149, 14, 149, 923, 3, 149, 3, 149, 3, 150, 6, 150, 929, 10, 150, 13, 150, 14, 150, 930, 3, 150, 3, 150, 3, 151, 6, 151, 936, 10, 151, 13, 151, 14, 151, 937, 3, 151, 3, 151, 3, 152, 3, 152, 7, 152, 944, 10, 152, 12, 152, 14, 152, 947, 11, 152, 3, 152, 3, 152, 3, 153, 3, 153, 7, 153, 953, 10, 153, 12, 153, 14, 153, 956, 11, 153, 3, 153, 3, 153, 3, 154, 3, 154, 7, 154, 962, 10, 154, 12, 154, 14, 154, 965, 11, 154, 3, 155, 3, 155, 3, 155, 3, 156, 6, 156, 971, 10, 156, 13, 156, 14, 156, 972, 3, 157, 3, 157, 3, 158, 3, 158, 3, 159, 3, 159, 3, 160, 3, 160, 3, 161, 3, 161, 3, 162, 3, 162, 3, 163, 3, 163, 3, 164, 3, 164, 3, 165, 3, 165, 3, 166, 3, 166, 3, 166, 3, 167, 3, 167, 3, 168, 3, 168, 3, 168, 3, 169, 3, 169, 3, 170, 3, 170, 3, 170, 3, 171, 3, 171, 3, 171, 3, 172, 3, 172, 3, 173, 3, 173, 3, 174, 3, 174, 3, 175, 3, 175, 3, 176, 6, 176, 1018, 10, 176, 13, 176, 14, 176, 1019, 3, 176, 3, 176, 3, 177, 5, 177, 1025, 10, 177, 3, 177, 3, 177, 3, 377, 2, 178, 4, 3, 6, 4, 8, 2, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54, 2, 56, 2, 58, 5, 60, 6, 62, 7, 64, 8, 66, 9, 68, 10, 70, 11, 72, 12, 74, 13, 76, 14, 78, 15, 80, 16, 82, 17, 84, 18, 86, 19, 88, 20, 90, 21, 92, 22, 94, 23, 96, 24, 98, 25, 100, 26, 102, 27, 104, 28, 106, 29, 108, 30, 110, 31, 112, 32, 114, 33, 116, 34, 118, 35, 120, 36, 122, 37, 124, 38, 126, 39, 128, 40, 130, 41, 132, 42, 134, 43, 136, 44, 138, 45, 140, 46, 142, 47, 144, 48, 146, 49, 148, 50, 150, 51, 152, 52, 154, 53, 156, 54, 158, 55, 160, 56, 162, 57, 164, 58, 166, 59, 168, 60, 170, 61, 172, 62, 174, 63, 176, 64, 178, 65, 180, 66, 182, 67, 184, 68, 186, 69, 188, 70, 190, 71, 192, 72, 194, 73, 196, 74, 198, 75, 200, 76, 202, 77, 204, 78, 206, 79, 208, 80, 210, 81, 212, 82, 214, 83, 216, 84, 218, 85, 220, 86, 222, 87, 224, 88, 226, 89, 228, 90, 230, 91, 232, 92, 234, 93, 236, 94, 238, 95, 240, 96, 242, 97, 244, 98, 246, 99, 248, 100, 250, 101, 252, 102, 254, 103, 256, 104, 258, 105, 260, 106, 262, 107, 264, 108, 266, 109, 268, 110, 270, 111, 272, 112, 274, 113, 276, 114, 278, 115, 280, 116, 282, 117, 284, 118, 286, 119, 288, 120, 290, 121, 292, 122, 294, 123, 296, 124, 298, 125, 300, 126, 302, 127, 304, 128, 306, 129, 308, 130, 310, 131, 312, 132, 314, 133, 316, 134, 318, 135, 320, 136, 322, 137, 324, 138, 326, 139, 328, 140, 330, 141, 332, 142, 334, 143, 336, 144, 338, 145, 340, 146, 342, 147, 344, 148, 346, 149, 348, 150, 350, 151, 352, 152, 354, 153, 4, 2, 3, 40, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 5, 2, 11, 11, 14, 14, 34, 34, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 59, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 3, 2, 36, 36, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 12, 2, 11, 12, 14, 15, 34, 34, 39, 40, 42, 47, 49, 49, 62, 64, 96, 96, 126, 126, 128, 128, 2, 1018, 2, 4, 3, 2, 2, 2, 2, 6, 3, 2, 2, 2, 2, 58, 3, 2, 2, 2, 2, 60, 3, 2, 2, 2, 2, 62, 3, 2, 2, 2, 2, 64, 3, 2, 2, 2, 2, 66, 3, 2, 2, 2, 2, 68, 3, 2, 2, 2, 2, 70, 3, 2, 2, 2, 2, 72, 3, 2, 2, 2, 2, 74, 3, 2, 2, 2, 2, 76, 3, 2, 2, 2, 2, 78, 3, 2, 2, 2, 2, 80, 3, 2, 2, 2, 2, 82, 3, 2, 2, 2, 2, 84, 3, 2, 2, 2, 2, 86, 3, 2, 2, 2, 2, 88, 3, 2, 2, 2, 2, 90, 3, 2, 2, 2, 2, 92, 3, 2, 2, 2, 2, 94, 3, 2, 2, 2, 2, 96, 3, 2, 2, 2, 2, 98, 3, 2, 2, 2, 2, 100, 3, 2, 2, 2, 2, 102, 3, 2, 2, 2, 2, 104, 3, 2, 2, 2, 2, 106, 3, 2, 2, 2, 2, 108, 3, 2, 2, 2, 2, 110, 3, 2, 2, 2, 2, 112, 3, 2, 2, 2, 2, 114, 3, 2, 2, 2, 2, 116, 3, 2, 2, 2, 2, 118, 3, 2, 2, 2, 2, 120, 3, 2, 2, 2, 2, 122, 3, 2, 2, 2, 2, 124, 3, 2, 2, 2, 2, 126, 3, 2, 2, 2, 2, 128, 3, 2, 2, 2, 2, 130, 3, 2, 2, 2, 2, 132, 3, 2, 2, 2, 2, 134, 3, 2, 2, 2, 2, 136, 3, 2, 2, 2, 2, 138, 3, 2, 2, 2, 2, 140, 3, 2, 2, 2, 2, 142, 3, 2, 2, 2, 2, 144, 3, 2, 2, 2, 2, 146, 3, 2, 2, 2, 2, 148, 3, 2, 2, 2, 2, 150, 3, 2, 2, 2, 2, 152, 3, 2, 2, 2, 2, 154, 3, 2, 2, 2, 2, 156, 3, 2, 2, 2, 2, 158, 3, 2, 2, 2, 2, 160, 3, 2, 2, 2, 2, 162, 3, 2, 2, 2, 2, 164, 3, 2, 2, 2, 2, 166, 3, 2, 2, 2, 2, 168, 3, 2, 2, 2, 2, 170, 3, 2, 2, 2, 2, 172, 3, 2, 2, 2, 2, 174, 3, 2, 2, 2, 2, 176, 3, 2, 2, 2, 2, 178, 3, 2, 2, 2, 2, 180, 3, 2, 2, 2, 2, 182, 3, 2, 2, 2, 2, 184, 3, 2, 2, 2, 2, 186, 3, 2, 2, 2, 2, 188, 3, 2, 2, 2, 2, 190, 3, 2, 2, 2, 2, 192, 3, 2, 2, 2, 2, 214, 3, 2, 2, 2, 2, 216, 3, 2, 2, 2, 2, 218, 3, 2, 2, 2, 2, 220, 3, 2, 2, 2, 2, 222, 3, 2, 2, 2, 2, 224, 3, 2, 2, 2, 2, 226, 3, 2, 2, 2, 2, 228, 3, 2, 2, 2, 2, 230, 3, 2, 2, 2, 2, 232, 3, 2, 2, 2, 2, 234, 3, 2, 2, 2, 2, 236, 3, 2, 2, 2, 2, 238, 3, 2, 2, 2, 2, 240, 3, 2, 2, 2, 2, 242, 3, 2, 2, 2, 2, 244, 3, 2, 2, 2, 2, 246, 3, 2, 2, 2, 2, 248, 3, 2, 2, 2, 2, 250, 3, 2, 2, 2, 2, 252, 3, 2, 2, 2, 2, 254, 3, 2, 2, 2, 2, 256, 3, 2, 2, 2, 2, 258, 3, 2, 2, 2, 2, 260, 3, 2, 2, 2, 2, 262, 3, 2, 2, 2, 2, 264, 3, 2, 2, 2, 2, 266, 3, 2, 2, 2, 2, 268, 3, 2, 2, 2, 2, 270, 3, 2, 2, 2, 2, 272, 3, 2, 2, 2, 2, 274, 3, 2, 2, 2, 2, 276, 3, 2, 2, 2, 2, 278, 3, 2, 2, 2, 2, 280, 3, 2, 2, 2, 2, 282, 3, 2, 2, 2, 2, 284, 3, 2, 2, 2, 2, 286, 3, 2, 2, 2, 2, 288, 3, 2, 2, 2, 2, 290, 3, 2, 2, 2, 2, 292, 3, 2, 2, 2, 2, 294, 3, 2, 2, 2, 2, 296, 3, 2, 2, 2, 2, 298, 3, 2, 2, 2, 2, 300, 3, 2, 2, 2, 2, 302, 3, 2, 2, 2, 2, 304, 3, 2, 2, 2, 2, 306, 3, 2, 2, 2, 2, 308, 3, 2, 2, 2, 2, 310, 3, 2, 2, 2, 2, 312, 3, 2, 2, 2, 2, 314, 3, 2, 2, 2, 2, 316, 3, 2, 2, 2, 2, 318, 3, 2, 2, 2, 2, 320, 3, 2, 2, 2, 2, 322, 3, 2, 2, 2, 2, 324, 3, 2, 2, 2, 2, 326, 3, 2, 2, 2, 2, 328, 3, 2, 2, 2, 2, 330, 3, 2, 2, 2, 2, 332, 3, 2, 2, 2, 2, 334, 3, 2, 2, 2, 2, 336, 3, 2, 2, 2, 2, 338, 3, 2, 2, 2, 2, 340, 3, 2, 2, 2, 2, 342, 3, 2, 2, 2, 2, 344, 3, 2, 2, 2, 2, 346, 3, 2, 2, 2, 2, 348, 3, 2, 2, 2, 2, 350, 3, 2, 2, 2, 2, 352, 3, 2, 2, 2, 2, 354, 3, 2, 2, 2, 3, 194, 3, 2, 2, 2, 3, 196, 3, 2, 2, 2, 3, 198, 3, 2, 2, 2, 3, 200, 3, 2, 2, 2, 3, 202, 3, 2, 2, 2, 3, 204, 3, 2, 2, 2, 3, 206, 3, 2, 2, 2, 3, 208, 3, 2, 2, 2, 3, 210, 3, 2, 2, 2, 3, 212, 3, 2, 2, 2, 4, 361, 3, 2, 2, 2, 6, 371, 3, 2, 2, 2, 8, 385, 3, 2, 2, 2, 10, 387, 3, 2, 2, 2, 12, 389, 3, 2, 2, 2, 14, 391, 3, 2, 2, 2, 16, 393, 3, 2, 2, 2, 18, 395, 3, 2, 2, 2, 20, 397, 3, 2, 2, 2, 22, 399, 3, 2, 2, 2, 24, 401, 3, 2, 2, 2, 26, 403, 3, 2, 2, 2, 28, 405, 3, 2, 2, 2, 30, 407, 3, 2, 2, 2, 32, 409, 3, 2, 2, 2, 34, 411, 3, 2, 2, 2, 36, 413, 3, 2, 2, 2, 38, 415, 3, 2, 2, 2, 40, 417, 3, 2, 2, 2, 42, 419, 3, 2, 2, 2, 44, 421, 3, 2, 2, 2, 46, 423, 3, 2, 2, 2, 48, 425, 3, 2, 2, 2, 50, 427, 3, 2, 2, 2, 52, 429, 3, 2, 2, 2, 54, 431, 3, 2, 2, 2, 56, 433, 3, 2, 2, 2, 58, 435, 3, 2, 2, 2, 60, 439, 3, 2, 2, 2, 62, 443, 3, 2, 2, 2, 64, 447, 3, 2, 2, 2, 66, 451, 3, 2, 2, 2, 68, 458, 3, 2, 2, 2, 70, 462, 3, 2, 2, 2, 72, 465, 3, 2, 2, 2, 74, 469, 3, 2, 2, 2, 76, 474, 3, 2, 2, 2, 78, 478, 3, 2, 2, 2, 80, 483, 3, 2, 2, 2, 82, 487, 3, 2, 2, 2, 84, 491, 3, 2, 2, 2, 86, 495, 3, 2, 2, 2, 88, 498, 3, 2, 2, 2, 90, 503, 3, 2, 2, 2, 92, 506, 3, 2, 2, 2, 94, 509, 3, 2, 2, 2, 96, 513, 3, 2, 2, 2, 98, 518, 3, 2, 2, 2, 100, 521, 3, 2, 2, 2, 102, 524, 3, 2, 2, 2, 104, 528, 3, 2, 2, 2, 106, 532, 3, 2, 2, 2, 108, 537, 3, 2, 2, 2, 110, 541, 3, 2, 2, 2, 112, 546, 3, 2, 2, 2, 114, 551, 3, 2, 2, 2, 116, 556, 3, 2, 2, 2, 118, 559, 3, 2, 2, 2, 120, 563, 3, 2, 2, 2, 122, 568, 3, 2, 2, 2, 124, 572, 3, 2, 2, 2, 126, 577, 3, 2, 2, 2, 128, 581, 3, 2, 2, 2, 130, 585, 3, 2, 2, 2, 132, 588, 3, 2, 2, 2, 134, 593, 3, 2, 2, 2, 136, 598, 3, 2, 2, 2, 138, 602, 3, 2, 2, 2, 140, 607, 3, 2, 2, 2, 142, 612, 3, 2, 2, 2, 144, 616, 3, 2, 2, 2, 146, 621, 3, 2, 2, 2, 148, 625, 3, 2, 2, 2, 150, 631, 3, 2, 2, 2, 152, 636, 3, 2, 2, 2, 154, 641, 3, 2, 2, 2, 156, 644, 3, 2, 2, 2, 158, 648, 3, 2, 2, 2, 160, 652, 3, 2, 2, 2, 162, 657, 3, 2, 2, 2, 164, 661, 3, 2, 2, 2, 166, 664, 3, 2, 2, 2, 168, 668, 3, 2, 2, 2, 170, 672, 3, 2, 2, 2, 172, 677, 3, 2, 2, 2, 174, 681, 3, 2, 2, 2, 176, 685, 3, 2, 2, 2, 178, 689, 3, 2, 2, 2, 180, 693, 3, 2, 2, 2, 182, 697, 3, 2, 2, 2, 184, 701, 3, 2, 2, 2, 186, 705, 3, 2, 2, 2, 188, 709, 3, 2, 2, 2, 190, 713, 3, 2, 2, 2, 192, 717, 3, 2, 2, 2, 194, 721, 3, 2, 2, 2, 196, 725, 3, 2, 2, 2, 198, 730, 3, 2, 2, 2, 200, 734, 3, 2, 2, 2, 202, 739, 3, 2, 2, 2, 204, 743, 3, 2, 2, 2, 206, 747, 3, 2, 2, 2, 208, 752, 3, 2, 2, 2, 210, 758, 3, 2, 2, 2, 212, 764, 3, 2, 2, 2, 214, 768, 3, 2, 2, 2, 216, 772, 3, 2, 2, 2, 218, 776, 3, 2, 2, 2, 220, 780, 3, 2, 2, 2, 222, 783, 3, 2, 2, 2, 224, 789, 3, 2, 2, 2, 226, 797, 3, 2, 2, 2, 228, 803, 3, 2, 2, 2, 230, 808, 3, 2, 2, 2, 232, 811, 3, 2, 2, 2, 234, 814, 3, 2, 2, 2, 236, 817, 3, 2, 2, 2, 238, 819, 3, 2, 2, 2, 240, 821, 3, 2, 2, 2, 242, 823, 3, 2, 2, 2, 244, 825, 3, 2, 2, 2, 246, 827, 3, 2, 2, 2, 248, 829, 3, 2, 2, 2, 250, 831, 3, 2, 2, 2, 252, 833, 3, 2, 2, 2, 254, 836, 3, 2, 2, 2, 256, 840, 3, 2, 2, 2, 258, 844, 3, 2, 2, 2, 260, 847, 3, 2, 2, 2, 262, 851, 3, 2, 2, 2, 264, 855, 3, 2, 2, 2, 266, 858, 3, 2, 2, 2, 268, 861, 3, 2, 2, 2, 270, 864, 3, 2, 2, 2, 272, 867, 3, 2, 2, 2, 274, 870, 3, 2, 2, 2, 276, 874, 3, 2, 2, 2, 278, 876, 3, 2, 2, 2, 280, 878, 3, 2, 2, 2, 282, 882, 3, 2, 2, 2, 284, 886, 3, 2, 2, 2, 286, 890, 3, 2, 2, 2, 288, 894, 3, 2, 2, 2, 290, 898, 3, 2, 2, 2, 292, 901, 3, 2, 2, 2, 294, 905, 3, 2, 2, 2, 296, 913, 3, 2, 2, 2, 298, 921, 3, 2, 2, 2, 300, 928, 3, 2, 2, 2, 302, 935, 3, 2, 2, 2, 304, 941, 3, 2, 2, 2, 306, 950, 3, 2, 2, 2, 308, 959, 3, 2, 2, 2, 310, 966, 3, 2, 2, 2, 312, 970, 3, 2, 2, 2, 314, 974, 3, 2, 2, 2, 316, 976, 3, 2, 2, 2, 318, 978, 3, 2, 2, 2, 320, 980, 3, 2, 2, 2, 322, 982, 3, 2, 2, 2, 324, 984, 3, 2, 2, 2, 326, 986, 3, 2, 2, 2, 328, 988, 3, 2, 2, 2, 330, 990, 3, 2, 2, 2, 332, 992, 3, 2, 2, 2, 334, 995, 3, 2, 2, 2, 336, 997, 3, 2, 2, 2, 338, 1000, 3, 2, 2, 2, 340, 1002, 3, 2, 2, 2, 342, 1005, 3, 2, 2, 2, 344, 1008, 3, 2, 2, 2, 346, 1010, 3, 2, 2, 2, 348, 1012, 3, 2, 2, 2, 350, 1014, 3, 2, 2, 2, 352, 1017, 3, 2, 2, 2, 354, 1024, 3, 2, 2, 2, 356, 357, 7, 49, 2, 2, 357, 362, 7, 49, 2, 2, 358, 359, 7, 47, 2, 2, 359, 362, 7, 47, 2, 2, 360, 362, 9, 2, 2, 2, 361, 356, 3, 2, 2, 2, 361, 358, 3, 2, 2, 2, 361, 360, 3, 2, 2, 2, 362, 366, 3, 2, 2, 2, 363, 365, 10, 3, 2, 2, 364, 363, 3, 2, 2, 2, 365, 368, 3, 2, 2, 2, 366, 364, 3, 2, 2, 2, 366, 367, 3, 2, 2, 2, 367, 369, 3, 2, 2, 2, 368, 366, 3, 2, 2, 2, 369, 370, 8, 2, 2, 2, 370, 5, 3, 2, 2, 2, 371, 372, 7, 49, 2, 2, 372, 373, 7, 44, 2, 2, 373, 377, 3, 2, 2, 2, 374, 376, 11, 2, 2, 2, 375, 374, 3, 2, 2, 2, 376, 379, 3, 2, 2, 2, 377, 378, 3, 2, 2, 2, 377, 375, 3, 2, 2, 2, 378, 380, 3, 2, 2, 2, 379, 377, 3, 2, 2, 2, 380, 381, 7, 44, 2, 2, 381, 382, 7, 49, 2, 2, 382, 383, 3, 2, 2, 2, 383, 384, 8, 3, 2, 2, 384, 7, 3, 2, 2, 2, 385, 386, 9, 4, 2, 2, 386, 9, 3, 2, 2, 2, 387, 388, 9, 5, 2, 2, 388, 11, 3, 2, 2, 2, 389, 390, 9, 6, 2, 2, 390, 13, 3, 2, 2, 2, 391, 392, 9, 7, 2, 2, 392, 15, 3, 2, 2, 2, 393, 394, 9, 8, 2, 2, 394, 17, 3, 2, 2, 2, 395, 396, 9, 9, 2, 2, 396, 19, 3, 2, 2, 2, 397, 398, 9, 10, 2, 2, 398, 21, 3, 2, 2, 2, 399, 400, 9, 11, 2, 2, 400, 23, 3, 2, 2, 2, 401, 402, 9, 12, 2, 2, 402, 25, 3, 2, 2, 2, 403, 404, 9, 13, 2, 2, 404, 27, 3, 2, 2, 2, 405, 406, 9, 14, 2, 2, 406, 29, 3, 2, 2, 2, 407, 408, 9, 15, 2, 2, 408, 31, 3, 2, 2, 2, 409, 410, 9, 16, 2, 2, 410, 33, 3, 2, 2, 2, 411, 412, 9, 17, 2, 2, 412, 35, 3, 2, 2, 2, 413, 414, 9, 18, 2, 2, 414, 37, 3, 2, 2, 2, 415, 416, 9, 19, 2, 2, 416, 39, 3, 2, 2, 2, 417, 418, 9, 20, 2, 2, 418, 41, 3, 2, 2, 2, 419, 420, 9, 21, 2, 2, 420, 43, 3, 2, 2, 2, 421, 422, 9, 22, 2, 2, 422, 45, 3, 2, 2, 2, 423, 424, 9, 23, 2, 2, 424, 47, 3, 2, 2, 2, 425, 426, 9, 24, 2, 2, 426, 49, 3, 2, 2, 2, 427, 428, 9, 25, 2, 2, 428, 51, 3, 2, 2, 2, 429, 430, 9, 26, 2, 2, 430, 53, 3, 2, 2, 2, 431, 432, 9, 27, 2, 2, 432, 55, 3, 2, 2, 2, 433, 434, 9, 28, 2, 2, 434, 57, 3, 2, 2, 2, 435, 436, 5, 8, 4, 2, 436, 437, 5, 14, 7, 2, 437, 438, 5, 12, 6, 2, 438, 59, 3, 2, 2, 2, 439, 440, 5, 8, 4, 2, 440, 441, 5, 14, 7, 2, 441, 442, 5, 14, 7, 2, 442, 61, 3, 2, 2, 2, 443, 444, 5, 8, 4, 2, 444, 445, 5, 32, 16, 2, 445, 446, 5, 14, 7, 2, 446, 63, 3, 2, 2, 2, 447, 448, 5, 10, 5, 2, 448, 449, 5, 24, 12, 2, 449, 450, 5, 44, 22, 2, 450, 65, 3, 2, 2, 2, 451, 452, 5, 12, 6, 2, 452, 453, 5, 8, 4, 2, 453, 454, 5, 28, 14, 2, 454, 455, 5, 28, 14, 2, 455, 456, 3, 2, 2, 2, 456, 457, 8, 33, 3, 2, 457, 67, 3, 2, 2, 2, 458, 459, 5, 12, 6, 2, 459, 460, 5, 12, 6, 2, 460, 461, 5, 18, 9, 2, 461, 69, 3, 2, 2, 2, 462, 463, 5, 12, 6, 2, 463, 464, 5, 36, 18, 2, 464, 71, 3, 2, 2, 2, 465, 466, 5, 12, 6, 2, 466, 467, 5, 36, 18, 2, 467, 468, 5, 14, 7, 2, 468, 73, 3, 2, 2, 2, 469, 470, 5, 12, 6, 2, 470, 471, 5, 36, 18, 2, 471, 472, 5, 14, 7, 2, 472, 473, 5, 40, 20, 2, 473, 75, 3, 2, 2, 2, 474, 475, 5, 12, 6, 2, 475, 476, 5, 36, 18, 2, 476, 477, 5, 24, 12, 2, 477, 77, 3, 2, 2, 2, 478, 479, 5, 12, 6, 2, 479, 480, 5, 36, 18, 2, 480, 481, 5, 24, 12, 2, 481, 482, 5, 40, 20, 2, 482, 79, 3, 2, 2, 2, 483, 484, 5, 12, 6, 2, 484, 485, 5, 36, 18, 2, 485, 486, 5, 28, 14, 2, 486, 81, 3, 2, 2, 2, 487, 488, 5, 14, 7, 2, 488, 489, 5, 8, 4, 2, 489, 490, 5, 8, 4, 2, 490, 83, 3, 2, 2, 2, 491, 492, 5, 14, 7, 2, 492, 493, 5, 16, 8, 2, 493, 494, 5, 12, 6, 2, 494, 85, 3, 2, 2, 2, 495, 496, 5, 14, 7, 2, 496, 497, 5, 24, 12, 2, 497, 87, 3, 2, 2, 2, 498, 499, 5, 14, 7, 2, 499, 500, 5, 26, 13, 2, 500, 501, 5, 32, 16, 2, 501, 502, 5, 56, 28, 2, 502, 89, 3, 2, 2, 2, 503, 504, 5, 16, 8, 2, 504, 505, 5, 24, 12, 2, 505, 91, 3, 2, 2, 2, 506, 507, 5, 16, 8, 2, 507, 508, 5, 52, 26, 2, 508, 93, 3, 2, 2, 2, 509, 510, 5, 16, 8, 2, 510, 511, 5, 52, 26, 2, 511, 512, 5, 52, 26, 2, 512, 95, 3, 2, 2, 2, 513, 514, 5, 22, 11, 2, 514, 515, 5, 8, 4, 2, 515, 516, 5, 28, 14, 2, 516, 517, 5, 44, 22, 2, 517, 97, 3, 2, 2, 2, 518, 519, 5, 24, 12, 2, 519, 520, 5, 30, 15, 2, 520, 99, 3, 2, 2, 2, 521, 522, 5, 24, 12, 2, 522, 523, 5, 32, 16, 2, 523, 101, 3, 2, 2, 2, 524, 525, 5, 24, 12, 2, 525, 526, 5, 32, 16, 2, 526, 527, 5, 12, 6, 2, 527, 103, 3, 2, 2, 2, 528, 529, 5, 24, 12, 2, 529, 530, 5, 32, 16, 2, 530, 531, 5, 14, 7, 2, 531, 105, 3, 2, 2, 2, 532, 533, 5, 24, 12, 2, 533, 534, 5, 32, 16, 2, 534, 535, 5, 14, 7, 2, 535, 536, 5, 40, 20, 2, 536, 107, 3, 2, 2, 2, 537, 538, 5, 24, 12, 2, 538, 539, 5, 32, 16, 2, 539, 540, 5, 24, 12, 2, 540, 109, 3, 2, 2, 2, 541, 542, 5, 24, 12, 2, 542, 543, 5, 32, 16, 2, 543, 544, 5, 24, 12, 2, 544, 545, 5, 40, 20, 2, 545, 111, 3, 2, 2, 2, 546, 547, 5, 26, 13, 2, 547, 548, 5, 36, 18, 2, 548, 549, 3, 2, 2, 2, 549, 550, 8, 56, 3, 2, 550, 113, 3, 2, 2, 2, 551, 552, 5, 26, 13, 2, 552, 553, 5, 40, 20, 2, 553, 554, 3, 2, 2, 2, 554, 555, 8, 57, 3, 2, 555, 115, 3, 2, 2, 2, 556, 557, 5, 28, 14, 2, 557, 558, 5, 14, 7, 2, 558, 117, 3, 2, 2, 2, 559, 560, 5, 28, 14, 2, 560, 561, 5, 14, 7, 2, 561, 562, 5, 14, 7, 2, 562, 119, 3, 2, 2, 2, 563, 564, 5, 28, 14, 2, 564, 565, 5, 14, 7, 2, 565, 566, 5, 14, 7, 2, 566, 567, 5, 40, 20, 2, 567, 121, 3, 2, 2, 2, 568, 569, 5, 28, 14, 2, 569, 570, 5, 14, 7, 2, 570, 571, 5, 24, 12, 2, 571, 123, 3, 2, 2, 2, 572, 573, 5, 28, 14, 2, 573, 574, 5, 14, 7, 2, 574, 575, 5, 24, 12, 2, 575, 576, 5, 40, 20, 2, 576, 125, 3, 2, 2, 2, 577, 578, 5, 32, 16, 2, 578, 579, 5, 16, 8, 2, 579, 580, 5, 20, 10, 2, 580, 127, 3, 2, 2, 2, 581, 582, 5, 32, 16, 2, 582, 583, 5, 34, 17, 2, 583, 584, 5, 36, 18, 2, 584, 129, 3, 2, 2, 2, 585, 586, 5, 34, 17, 2, 586, 587, 5, 40, 20, 2, 587, 131, 3, 2, 2, 2, 588, 589, 5, 34, 17, 2, 589, 590, 5, 44, 22, 2, 590, 591, 5, 14, 7, 2, 591, 592, 5, 40, 20, 2, 592, 133, 3, 2, 2, 2, 593, 594, 5, 34, 17, 2, 594, 595, 5, 44, 22, 2, 595, 596, 5, 24, 12, 2, 596, 597, 5, 40, 20, 2, 597, 135, 3, 2, 2, 2, 598, 599, 5, 34, 17, 2, 599, 600, 5, 46, 23, 2, 600, 601, 5, 44, 22, 2, 601, 137, 3, 2, 2, 2, 602, 603, 5, 34, 17, 2, 603, 604, 5, 46, 23, 2, 604, 605, 5, 44, 22, 2, 605, 606, 5, 14, 7, 2, 606, 139, 3, 2, 2, 2, 607, 608, 5, 34, 17, 2, 608, 609, 5, 46, 23, 2, 609, 610, 5, 44, 22, 2, 610, 611, 5, 24, 12, 2, 611, 141, 3, 2, 2, 2, 612, 613, 5, 36, 18, 2, 613, 614, 5, 34, 17, 2, 614, 615, 5, 36, 18, 2, 615, 143, 3, 2, 2, 2, 616, 617, 5, 36, 18, 2, 617, 618, 5, 46, 23, 2, 618, 619, 5, 42, 21, 2, 619, 620, 5, 22, 11, 2, 620, 145, 3, 2, 2, 2, 621, 622, 5, 40, 20, 2, 622, 623, 5, 16, 8, 2, 623, 624, 5, 42, 21, 2, 624, 147, 3, 2, 2, 2, 625, 626, 5, 40, 20, 2, 626, 627, 5, 16, 8, 2, 627, 628, 5, 44, 22, 2, 628, 629, 3, 2, 2, 2, 629, 630, 8, 74, 3, 2, 630, 149, 3, 2, 2, 2, 631, 632, 5, 40, 20, 2, 632, 633, 5, 16, 8, 2, 633, 634, 5, 44, 22, 2, 634, 635, 5, 24, 12, 2, 635, 151, 3, 2, 2, 2, 636, 637, 5, 40, 20, 2, 637, 638, 5, 16, 8, 2, 638, 639, 5, 44, 22, 2, 639, 640, 5, 32, 16, 2, 640, 153, 3, 2, 2, 2, 641, 642, 5, 40, 20, 2, 642, 643, 5, 28, 14, 2, 643, 155, 3, 2, 2, 2, 644, 645, 5, 40, 20, 2, 645, 646, 5, 28, 14, 2, 646, 647, 5, 8, 4, 2, 647, 157, 3, 2, 2, 2, 648, 649, 5, 40, 20, 2, 649, 650, 5, 28, 14, 2, 650, 651, 5, 12, 6, 2, 651, 159, 3, 2, 2, 2, 652, 653, 5, 40, 20, 2, 653, 654, 5, 28, 14, 2, 654, 655, 5, 12, 6, 2, 655, 656, 5, 8, 4, 2, 656, 161, 3, 2, 2, 2, 657, 658, 5, 40, 20, 2, 658, 659, 5, 28, 14, 2, 659, 660, 5, 14, 7, 2, 660, 163, 3, 2, 2, 2, 661, 662, 5, 40, 20, 2, 662, 663, 5, 40, 20, 2, 663, 165, 3, 2, 2, 2, 664, 665, 5, 40, 20, 2, 665, 666, 5, 40, 20, 2, 666, 667, 5, 8, 4, 2, 667, 167, 3, 2, 2, 2, 668, 669, 5, 40, 20, 2, 669, 670, 5, 40, 20, 2, 670, 671, 5, 12, 6, 2, 671, 169, 3, 2, 2, 2, 672, 673, 5, 40, 20, 2, 673, 674, 5, 40, 20, 2, 674, 675, 5, 12, 6, 2, 675, 676, 5, 8, 4, 2, 676, 171, 3, 2, 2, 2, 677, 678, 5, 40, 20, 2, 678, 679, 5, 40, 20, 2, 679, 680, 5, 14, 7, 2, 680, 173, 3, 2, 2, 2, 681, 682, 5, 40, 20, 2, 682, 683, 5, 42, 21, 2, 683, 684, 5, 44, 22, 2, 684, 175, 3, 2, 2, 2, 685, 686, 5, 42, 21, 2, 686, 687, 5, 10, 5, 2, 687, 688, 5, 12, 6, 2, 688, 177, 3, 2, 2, 2, 689, 690, 5, 42, 21, 2, 690, 691, 5, 12, 6, 2, 691, 692, 5, 18, 9, 2, 692, 179, 3, 2, 2, 2, 693, 694, 5, 42, 21, 2, 694, 695, 5, 16, 8, 2, 695, 696, 5, 44, 22, 2, 696, 181, 3, 2, 2, 2, 697, 698, 5, 42, 21, 2, 698, 699, 5, 28, 14, 2, 699, 700, 5, 8, 4, 2, 700, 183, 3, 2, 2, 2, 701, 702, 5, 42, 21, 2, 702, 703, 5, 40, 20, 2, 703, 704, 5, 8, 4, 2, 704, 185, 3, 2, 2, 2, 705, 706, 5, 42, 21, 2, 706, 707, 5, 28, 14, 2, 707, 708, 5, 28, 14, 2, 708, 187, 3, 2, 2, 2, 709, 710, 5, 42, 21, 2, 710, 711, 5, 40, 20, 2, 711, 712, 5, 28, 14, 2, 712, 189, 3, 2, 2, 2, 713, 714, 5, 42, 21, 2, 714, 715, 5, 46, 23, 2, 715, 716, 5, 10, 5, 2, 716, 191, 3, 2, 2, 2, 717, 718, 5, 52, 26, 2, 718, 719, 5, 34, 17, 2, 719, 720, 5, 40, 20, 2, 720, 193, 3, 2, 2, 2, 721, 722, 5, 12, 6, 2, 722, 723, 3, 2, 2, 2, 723, 724, 8, 97, 4, 2, 724, 195, 3, 2, 2, 2, 725, 726, 5, 32, 16, 2, 726, 727, 5, 12, 6, 2, 727, 728, 3, 2, 2, 2, 728, 729, 8, 98, 4, 2, 729, 197, 3, 2, 2, 2, 730, 731, 5, 56, 28, 2, 731, 732, 3, 2, 2, 2, 732, 733, 8, 99, 4, 2, 733, 199, 3, 2, 2, 2, 734, 735, 5, 32, 16, 2, 735, 736, 5, 56, 28, 2, 736, 737, 3, 2, 2, 2, 737, 738, 8, 100, 4, 2, 738, 201, 3, 2, 2, 2, 739, 740, 5, 30, 15, 2, 740, 741, 3, 2, 2, 2, 741, 742, 8, 101, 4, 2, 742, 203, 3, 2, 2, 2, 743, 744, 5, 36, 18, 2, 744, 745, 3, 2, 2, 2, 745, 746, 8, 102, 4, 2, 746, 205, 3, 2, 2, 2, 747, 748, 5, 36, 18, 2, 748, 749, 5, 16, 8, 2, 749, 750, 3, 2, 2, 2, 750, 751, 8, 103, 4, 2, 751, 207, 3, 2, 2, 2, 752, 753, 5, 36, 18, 2, 753, 754, 5, 34, 17, 2, 754, 755, 3, 2, 2, 2, 755, 756, 8, 104, 4, 2, 756, 209, 3, 2, 2, 2, 757, 759, 9, 29, 2, 2, 758, 757, 3, 2, 2, 2, 759, 760, 3, 2, 2, 2, 760, 758, 3, 2, 2, 2, 760, 761, 3, 2, 2, 2, 761, 762, 3, 2, 2, 2, 762, 763, 8, 105, 2, 2, 763, 211, 3, 2, 2, 2, 764, 765, 6, 106, 2, 2, 765, 766, 3, 2, 2, 2, 766, 767, 8, 106, 4, 2, 767, 213, 3, 2, 2, 2, 768, 769, 5, 34, 17, 2, 769, 770, 5, 40, 20, 2, 770, 771, 5, 20, 10, 2, 771, 215, 3, 2, 2, 2, 772, 773, 5, 16, 8, 2, 773, 774, 5, 38, 19, 2, 774, 775, 5, 46, 23, 2, 775, 217, 3, 2, 2, 2, 776, 777, 5, 42, 21, 2, 777, 778, 5, 16, 8, 2, 778, 779, 5, 44, 22, 2, 779, 219, 3, 2, 2, 2, 780, 781, 5, 24, 12, 2, 781, 782, 5, 18, 9, 2, 782, 221, 3, 2, 2, 2, 783, 784, 5, 16, 8, 2, 784, 785, 5, 32, 16, 2, 785, 786, 5, 14, 7, 2, 786, 787, 5, 24, 12, 2, 787, 788, 5, 18, 9, 2, 788, 223, 3, 2, 2, 2, 789, 790, 5, 24, 12, 2, 790, 791, 5, 32, 16, 2, 791, 792, 5, 12, 6, 2, 792, 793, 5, 28, 14, 2, 793, 794, 5, 46, 23, 2, 794, 795, 5, 14, 7, 2, 795, 796, 5, 16, 8, 2, 796, 225, 3, 2, 2, 2, 797, 798, 5, 30, 15, 2, 798, 799, 5, 8, 4, 2, 799, 800, 5, 12, 6, 2, 800, 801, 5, 40, 20, 2, 801, 802, 5, 34, 17, 2, 802, 227, 3, 2, 2, 2, 803, 804, 5, 16, 8, 2, 804, 805, 5, 32, 16, 2, 805, 806, 5, 14, 7, 2, 806, 807, 5, 30, 15, 2, 807, 229, 3, 2, 2, 2, 808, 809, 5, 14, 7, 2, 809, 810, 5, 10, 5, 2, 810, 231, 3, 2, 2, 2, 811, 812, 5, 14, 7, 2, 812, 813, 5, 50, 25, 2, 813, 233, 3, 2, 2, 2, 814, 815, 5, 14, 7, 2, 815, 816, 5, 42, 21, 2, 816, 235, 3, 2, 2, 2, 817, 818, 7, 38, 2, 2, 818, 237, 3, 2, 2, 2, 819, 820, 5, 8, 4, 2, 820, 239, 3, 2, 2, 2, 821, 822, 5, 10, 5, 2, 822, 241, 3, 2, 2, 2, 823, 824, 5, 12, 6, 2, 824, 243, 3, 2, 2, 2, 825, 826, 5, 14, 7, 2, 826, 245, 3, 2, 2, 2, 827, 828, 5, 16, 8, 2, 828, 247, 3, 2, 2, 2, 829, 830, 5, 22, 11, 2, 830, 249, 3, 2, 2, 2, 831, 832, 5, 28, 14, 2, 832, 251, 3, 2, 2, 2, 833, 834, 5, 24, 12, 2, 834, 835, 5, 52, 26, 2, 835, 253, 3, 2, 2, 2, 836, 837, 5, 24, 12, 2, 837, 838, 5, 52, 26, 2, 838, 839, 5, 22, 11, 2, 839, 255, 3, 2, 2, 2, 840, 841, 5, 24, 12, 2, 841, 842, 5, 52, 26, 2, 842, 843, 5, 28, 14, 2, 843, 257, 3, 2, 2, 2, 844, 845, 5, 24, 12, 2, 845, 846, 5, 54, 27, 2, 846, 259, 3, 2, 2, 2, 847, 848, 5, 24, 12, 2, 848, 849, 5, 54, 27, 2, 849, 850, 5, 22, 11, 2, 850, 261, 3, 2, 2, 2, 851, 852, 5, 24, 12, 2, 852, 853, 5, 54, 27, 2, 853, 854, 5, 28, 14, 2, 854, 263, 3, 2, 2, 2, 855, 856, 5, 10, 5, 2, 856, 857, 5, 12, 6, 2, 857, 265, 3, 2, 2, 2, 858, 859, 5, 14, 7, 2, 859, 860, 5, 16, 8, 2, 860, 267, 3, 2, 2, 2, 861, 862, 5, 22, 11, 2, 862, 863, 5, 28, 14, 2, 863, 269, 3, 2, 2, 2, 864, 865, 5, 42, 21, 2, 865, 866, 5, 36, 18, 2, 866, 271, 3, 2, 2, 2, 867, 868, 5, 8, 4, 2, 868, 869, 5, 18, 9, 2, 869, 273, 3, 2, 2, 2, 870, 871, 5, 8, 4, 2, 871, 872, 5, 18, 9, 2, 872, 873, 7, 41, 2, 2, 873, 275, 3, 2, 2, 2, 874, 875, 5, 24, 12, 2, 875, 277, 3, 2, 2, 2, 876, 877, 5, 40, 20, 2, 877, 279, 3, 2, 2, 2, 878, 879, 5, 30, 15, 2, 879, 880, 5, 34, 17, 2, 880, 881, 5, 14, 7, 2, 881, 281, 3, 2, 2, 2, 882, 883, 5, 42, 21, 2, 883, 884, 5, 22, 11, 2, 884, 885, 5, 40, 20, 2, 885, 283, 3, 2, 2, 2, 886, 887, 5, 42, 21, 2, 887, 888, 5, 22, 11, 2, 888, 889, 5, 28, 14, 2, 889, 285, 3, 2, 2, 2, 890, 891, 5, 32, 16, 2, 891, 892, 5, 34, 17, 2, 892, 893, 5, 44, 22, 2, 893, 287, 3, 2, 2, 2, 894, 895, 5, 8, 4, 2, 895, 896, 5, 32, 16, 2, 896, 897, 5, 14, 7, 2, 897, 289, 3, 2, 2, 2, 898, 899, 5, 34, 17, 2, 899, 900, 5, 40, 20, 2, 900, 291, 3, 2, 2, 2, 901, 902, 5, 52, 26, 2, 902, 903, 5, 34, 17, 2, 903, 904, 5, 40, 20, 2, 904, 293, 3, 2, 2, 2, 905, 906, 7, 50, 2, 2, 906, 908, 5, 52, 26, 2, 907, 909, 9, 30, 2, 2, 908, 907, 3, 2, 2, 2, 909, 910, 3, 2, 2, 2, 910, 908, 3, 2, 2, 2, 910, 911, 3, 2, 2, 2, 911, 295, 3, 2, 2, 2, 912, 914, 9, 31, 2, 2, 913, 912, 3, 2, 2, 2, 914, 915, 3, 2, 2, 2, 915, 913, 3, 2, 2, 2, 915, 916, 3, 2, 2, 2, 916, 918, 3, 2, 2, 2, 917, 919, 5, 14, 7, 2, 918, 917, 3, 2, 2, 2, 918, 919, 3, 2, 2, 2, 919, 297, 3, 2, 2, 2, 920, 922, 9, 30, 2, 2, 921, 920, 3, 2, 2, 2, 922, 923, 3, 2, 2, 2, 923, 921, 3, 2, 2, 2, 923, 924, 3, 2, 2, 2, 924, 925, 3, 2, 2, 2, 925, 926, 5, 22, 11, 2, 926, 299, 3, 2, 2, 2, 927, 929, 9, 32, 2, 2, 928, 927, 3, 2, 2, 2, 929, 930, 3, 2, 2, 2, 930, 928, 3, 2, 2, 2, 930, 931, 3, 2, 2, 2, 931, 932, 3, 2, 2, 2, 932, 933, 9, 33, 2, 2, 933, 301, 3, 2, 2, 2, 934, 936, 9, 34, 2, 2, 935, 934, 3, 2, 2, 2, 936, 937, 3, 2, 2, 2, 937, 935, 3, 2, 2, 2, 937, 938, 3, 2, 2, 2, 938, 939, 3, 2, 2, 2, 939, 940, 5, 10, 5, 2, 940, 303, 3, 2, 2, 2, 941, 945, 7, 41, 2, 2, 942, 944, 10, 35, 2, 2, 943, 942, 3, 2, 2, 2, 944, 947, 3, 2, 2, 2, 945, 943, 3, 2, 2, 2, 945, 946, 3, 2, 2, 2, 946, 948, 3, 2, 2, 2, 947, 945, 3, 2, 2, 2, 948, 949, 7, 41, 2, 2, 949, 305, 3, 2, 2, 2, 950, 954, 7, 36, 2, 2, 951, 953, 10, 36, 2, 2, 952, 951, 3, 2, 2, 2, 953, 956, 3, 2, 2, 2, 954, 952, 3, 2, 2, 2, 954, 955, 3, 2, 2, 2, 955, 957, 3, 2, 2, 2, 956, 954, 3, 2, 2, 2, 957, 958, 7, 36, 2, 2, 958, 307, 3, 2, 2, 2, 959, 963, 9, 37, 2, 2, 960, 962, 9, 38, 2, 2, 961, 960, 3, 2, 2, 2, 962, 965, 3, 2, 2, 2, 963, 961, 3, 2, 2, 2, 963, 964, 3, 2, 2, 2, 964, 309, 3, 2, 2, 2, 965, 963, 3, 2, 2, 2, 966, 967, 5, 308, 154, 2, 967, 968, 7, 60, 2, 2, 968, 311, 3, 2, 2, 2, 969, 971, 10, 39, 2, 2, 970, 969, 3, 2, 2, 2, 971, 972, 3, 2, 2, 2, 972, 970, 3, 2, 2, 2, 972, 973, 3, 2, 2, 2, 973, 313, 3, 2, 2, 2, 974, 975, 7, 42, 2, 2, 975, 315, 3, 2, 2, 2, 976, 977, 7, 43, 2, 2, 977, 317, 3, 2, 2, 2, 978, 979, 7, 46, 2, 2, 979, 319, 3, 2, 2, 2, 980, 981, 7, 45, 2, 2, 981, 321, 3, 2, 2, 2, 982, 983, 7, 47, 2, 2, 983, 323, 3, 2, 2, 2, 984, 985, 7, 44, 2, 2, 985, 325, 3, 2, 2, 2, 986, 987, 7, 49, 2, 2, 987, 327, 3, 2, 2, 2, 988, 989, 7, 63, 2, 2, 989, 329, 3, 2, 2, 2, 990, 991, 7, 64, 2, 2, 991, 331, 3, 2, 2, 2, 992, 993, 7, 64, 2, 2, 993, 994, 7, 63, 2, 2, 994, 333, 3, 2, 2, 2, 995, 996, 7, 62, 2, 2, 996, 335, 3, 2, 2, 2, 997, 998, 7, 62, 2, 2, 998, 999, 7, 63, 2, 2, 999, 337, 3, 2, 2, 2, 1000, 1001, 7, 39, 2, 2, 1001, 339, 3, 2, 2, 2, 1002, 1003, 7, 64, 2, 2, 1003, 1004, 7, 64, 2, 2, 1004, 341, 3, 2, 2, 2, 1005, 1006, 7, 62, 2, 2, 1006, 1007, 7, 62, 2, 2, 1007, 343, 3, 2, 2, 2, 1008, 1009, 7, 128, 2, 2, 1009, 345, 3, 2, 2, 2, 1010, 1011, 7, 40, 2, 2, 1011, 347, 3, 2, 2, 2, 1012, 1013, 7, 126, 2, 2, 1013, 349, 3, 2, 2, 2, 1014, 1015, 7, 96, 2, 2, 1015, 351, 3, 2, 2, 2, 1016, 1018, 9, 29, 2, 2, 1017, 1016, 3, 2, 2, 2, 1018, 1019, 3, 2, 2, 2, 1019, 1017, 3, 2, 2, 2, 1019, 1020, 3, 2, 2, 2, 1020, 1021, 3, 2, 2, 2, 1021, 1022, 8, 176, 2, 2, 1022, 353, 3, 2, 2, 2, 1023, 1025, 7, 15, 2, 2, 1024, 1023, 3, 2, 2, 2, 1024, 1025, 3, 2, 2, 2, 1025, 1026, 3, 2, 2, 2, 1026, 1027, 7, 12, 2, 2, 1027, 355, 3, 2, 2, 2, 20, 2, 3, 361, 366, 377, 760, 910, 915, 918, 923, 930, 937, 945, 954, 963, 972, 1019, 1024, 5, 8, 2, 2, 7, 3, 2, 6, 2, 2] \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java index e06dd4877..d2bbdbb43 100644 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java +++ b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java @@ -207,13 +207,13 @@ public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { private boolean COND_UNRECOGNIZED_sempred(RuleContext _localctx, int predIndex) { switch (predIndex) { case 0: - return true; + return "cCnNzZmMpP".indexOf((char) _input.LA(1)) == -1; } return true; } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u0099\u0405\b\1\b"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u0099\u0404\b\1\b"+ "\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n"+ "\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21"+ "\4\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30"+ @@ -259,10 +259,10 @@ private boolean COND_UNRECOGNIZED_sempred(RuleContext _localctx, int predIndex) "\3Y\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3]\3]\3]\3]\3^\3^\3^\3^\3"+ "_\3_\3_\3_\3`\3`\3`\3`\3a\3a\3a\3a\3b\3b\3b\3b\3b\3c\3c\3c\3c\3d\3d\3"+ "d\3d\3d\3e\3e\3e\3e\3f\3f\3f\3f\3g\3g\3g\3g\3g\3h\3h\3h\3h\3h\3i\6i\u02f7"+ - "\ni\ri\16i\u02f8\3i\3i\3j\3j\3j\3j\3j\3k\3k\3k\3k\3l\3l\3l\3l\3m\3m\3"+ - "m\3m\3n\3n\3n\3o\3o\3o\3o\3o\3o\3p\3p\3p\3p\3p\3p\3p\3p\3q\3q\3q\3q\3"+ - "q\3q\3r\3r\3r\3r\3r\3s\3s\3s\3t\3t\3t\3u\3u\3u\3v\3v\3w\3w\3x\3x\3y\3"+ - "y\3z\3z\3{\3{\3|\3|\3}\3}\3~\3~\3~\3\177\3\177\3\177\3\177\3\u0080\3\u0080"+ + "\ni\ri\16i\u02f8\3i\3i\3j\3j\3j\3j\3k\3k\3k\3k\3l\3l\3l\3l\3m\3m\3m\3"+ + "m\3n\3n\3n\3o\3o\3o\3o\3o\3o\3p\3p\3p\3p\3p\3p\3p\3p\3q\3q\3q\3q\3q\3"+ + "q\3r\3r\3r\3r\3r\3s\3s\3s\3t\3t\3t\3u\3u\3u\3v\3v\3w\3w\3x\3x\3y\3y\3"+ + "z\3z\3{\3{\3|\3|\3}\3}\3~\3~\3~\3\177\3\177\3\177\3\177\3\u0080\3\u0080"+ "\3\u0080\3\u0080\3\u0081\3\u0081\3\u0081\3\u0082\3\u0082\3\u0082\3\u0082"+ "\3\u0083\3\u0083\3\u0083\3\u0083\3\u0084\3\u0084\3\u0084\3\u0085\3\u0085"+ "\3\u0085\3\u0086\3\u0086\3\u0086\3\u0087\3\u0087\3\u0087\3\u0088\3\u0088"+ @@ -270,22 +270,22 @@ private boolean COND_UNRECOGNIZED_sempred(RuleContext _localctx, int predIndex) "\3\u008c\3\u008c\3\u008c\3\u008c\3\u008d\3\u008d\3\u008d\3\u008d\3\u008e"+ "\3\u008e\3\u008e\3\u008e\3\u008f\3\u008f\3\u008f\3\u008f\3\u0090\3\u0090"+ "\3\u0090\3\u0090\3\u0091\3\u0091\3\u0091\3\u0092\3\u0092\3\u0092\3\u0092"+ - "\3\u0093\3\u0093\3\u0093\6\u0093\u038e\n\u0093\r\u0093\16\u0093\u038f"+ - "\3\u0094\6\u0094\u0393\n\u0094\r\u0094\16\u0094\u0394\3\u0094\5\u0094"+ - "\u0398\n\u0094\3\u0095\6\u0095\u039b\n\u0095\r\u0095\16\u0095\u039c\3"+ - "\u0095\3\u0095\3\u0096\6\u0096\u03a2\n\u0096\r\u0096\16\u0096\u03a3\3"+ - "\u0096\3\u0096\3\u0097\6\u0097\u03a9\n\u0097\r\u0097\16\u0097\u03aa\3"+ - "\u0097\3\u0097\3\u0098\3\u0098\7\u0098\u03b1\n\u0098\f\u0098\16\u0098"+ - "\u03b4\13\u0098\3\u0098\3\u0098\3\u0099\3\u0099\7\u0099\u03ba\n\u0099"+ - "\f\u0099\16\u0099\u03bd\13\u0099\3\u0099\3\u0099\3\u009a\3\u009a\7\u009a"+ - "\u03c3\n\u009a\f\u009a\16\u009a\u03c6\13\u009a\3\u009b\3\u009b\3\u009b"+ - "\3\u009c\6\u009c\u03cc\n\u009c\r\u009c\16\u009c\u03cd\3\u009d\3\u009d"+ + "\3\u0093\3\u0093\3\u0093\6\u0093\u038d\n\u0093\r\u0093\16\u0093\u038e"+ + "\3\u0094\6\u0094\u0392\n\u0094\r\u0094\16\u0094\u0393\3\u0094\5\u0094"+ + "\u0397\n\u0094\3\u0095\6\u0095\u039a\n\u0095\r\u0095\16\u0095\u039b\3"+ + "\u0095\3\u0095\3\u0096\6\u0096\u03a1\n\u0096\r\u0096\16\u0096\u03a2\3"+ + "\u0096\3\u0096\3\u0097\6\u0097\u03a8\n\u0097\r\u0097\16\u0097\u03a9\3"+ + "\u0097\3\u0097\3\u0098\3\u0098\7\u0098\u03b0\n\u0098\f\u0098\16\u0098"+ + "\u03b3\13\u0098\3\u0098\3\u0098\3\u0099\3\u0099\7\u0099\u03b9\n\u0099"+ + "\f\u0099\16\u0099\u03bc\13\u0099\3\u0099\3\u0099\3\u009a\3\u009a\7\u009a"+ + "\u03c2\n\u009a\f\u009a\16\u009a\u03c5\13\u009a\3\u009b\3\u009b\3\u009b"+ + "\3\u009c\6\u009c\u03cb\n\u009c\r\u009c\16\u009c\u03cc\3\u009d\3\u009d"+ "\3\u009e\3\u009e\3\u009f\3\u009f\3\u00a0\3\u00a0\3\u00a1\3\u00a1\3\u00a2"+ "\3\u00a2\3\u00a3\3\u00a3\3\u00a4\3\u00a4\3\u00a5\3\u00a5\3\u00a6\3\u00a6"+ "\3\u00a6\3\u00a7\3\u00a7\3\u00a8\3\u00a8\3\u00a8\3\u00a9\3\u00a9\3\u00aa"+ "\3\u00aa\3\u00aa\3\u00ab\3\u00ab\3\u00ab\3\u00ac\3\u00ac\3\u00ad\3\u00ad"+ - "\3\u00ae\3\u00ae\3\u00af\3\u00af\3\u00b0\6\u00b0\u03fb\n\u00b0\r\u00b0"+ - "\16\u00b0\u03fc\3\u00b0\3\u00b0\3\u00b1\5\u00b1\u0402\n\u00b1\3\u00b1"+ + "\3\u00ae\3\u00ae\3\u00af\3\u00af\3\u00b0\6\u00b0\u03fa\n\u00b0\r\u00b0"+ + "\16\u00b0\u03fb\3\u00b0\3\u00b0\3\u00b1\5\u00b1\u0401\n\u00b1\3\u00b1"+ "\3\u00b1\3\u0179\2\u00b2\4\3\6\4\b\2\n\2\f\2\16\2\20\2\22\2\24\2\26\2"+ "\30\2\32\2\34\2\36\2 \2\"\2$\2&\2(\2*\2,\2.\2\60\2\62\2\64\2\66\28\2:"+ "\5<\6>\7@\bB\tD\nF\13H\fJ\rL\16N\17P\20R\21T\22V\23X\24Z\25\\\26^\27`"+ @@ -308,7 +308,7 @@ private boolean COND_UNRECOGNIZED_sempred(RuleContext _localctx, int predIndex) "p\4\2QQqq\4\2RRrr\4\2SSss\4\2TTtt\4\2UUuu\4\2VVvv\4\2WWww\4\2XXxx\4\2"+ "YYyy\4\2ZZzz\4\2[[{{\4\2\\\\||\5\2\13\13\16\16\"\"\5\2\62;CHch\3\2\62"+ ";\3\2\629\6\2QQSSqqss\3\2\62\63\3\2))\3\2$$\5\2A\\aac|\6\2\62;A\\aac|"+ - "\f\2\13\f\16\17\"\"\'(*/\61\61>@``~~\u0080\u0080\2\u03fb\2\4\3\2\2\2\2"+ + "\f\2\13\f\16\17\"\"\'(*/\61\61>@``~~\u0080\u0080\2\u03fa\2\4\3\2\2\2\2"+ "\6\3\2\2\2\2:\3\2\2\2\2<\3\2\2\2\2>\3\2\2\2\2@\3\2\2\2\2B\3\2\2\2\2D\3"+ "\2\2\2\2F\3\2\2\2\2H\3\2\2\2\2J\3\2\2\2\2L\3\2\2\2\2N\3\2\2\2\2P\3\2\2"+ "\2\2R\3\2\2\2\2T\3\2\2\2\2V\3\2\2\2\2X\3\2\2\2\2Z\3\2\2\2\2\\\3\2\2\2"+ @@ -366,27 +366,27 @@ private boolean COND_UNRECOGNIZED_sempred(RuleContext _localctx, int predIndex) "\2\2\u00c2\u02d1\3\2\2\2\u00c4\u02d5\3\2\2\2\u00c6\u02da\3\2\2\2\u00c8"+ "\u02de\3\2\2\2\u00ca\u02e3\3\2\2\2\u00cc\u02e7\3\2\2\2\u00ce\u02eb\3\2"+ "\2\2\u00d0\u02f0\3\2\2\2\u00d2\u02f6\3\2\2\2\u00d4\u02fc\3\2\2\2\u00d6"+ - "\u0301\3\2\2\2\u00d8\u0305\3\2\2\2\u00da\u0309\3\2\2\2\u00dc\u030d\3\2"+ - "\2\2\u00de\u0310\3\2\2\2\u00e0\u0316\3\2\2\2\u00e2\u031e\3\2\2\2\u00e4"+ - "\u0324\3\2\2\2\u00e6\u0329\3\2\2\2\u00e8\u032c\3\2\2\2\u00ea\u032f\3\2"+ - "\2\2\u00ec\u0332\3\2\2\2\u00ee\u0334\3\2\2\2\u00f0\u0336\3\2\2\2\u00f2"+ - "\u0338\3\2\2\2\u00f4\u033a\3\2\2\2\u00f6\u033c\3\2\2\2\u00f8\u033e\3\2"+ - "\2\2\u00fa\u0340\3\2\2\2\u00fc\u0342\3\2\2\2\u00fe\u0345\3\2\2\2\u0100"+ - "\u0349\3\2\2\2\u0102\u034d\3\2\2\2\u0104\u0350\3\2\2\2\u0106\u0354\3\2"+ - "\2\2\u0108\u0358\3\2\2\2\u010a\u035b\3\2\2\2\u010c\u035e\3\2\2\2\u010e"+ - "\u0361\3\2\2\2\u0110\u0364\3\2\2\2\u0112\u0367\3\2\2\2\u0114\u036b\3\2"+ - "\2\2\u0116\u036d\3\2\2\2\u0118\u036f\3\2\2\2\u011a\u0373\3\2\2\2\u011c"+ - "\u0377\3\2\2\2\u011e\u037b\3\2\2\2\u0120\u037f\3\2\2\2\u0122\u0383\3\2"+ - "\2\2\u0124\u0386\3\2\2\2\u0126\u038a\3\2\2\2\u0128\u0392\3\2\2\2\u012a"+ - "\u039a\3\2\2\2\u012c\u03a1\3\2\2\2\u012e\u03a8\3\2\2\2\u0130\u03ae\3\2"+ - "\2\2\u0132\u03b7\3\2\2\2\u0134\u03c0\3\2\2\2\u0136\u03c7\3\2\2\2\u0138"+ - "\u03cb\3\2\2\2\u013a\u03cf\3\2\2\2\u013c\u03d1\3\2\2\2\u013e\u03d3\3\2"+ - "\2\2\u0140\u03d5\3\2\2\2\u0142\u03d7\3\2\2\2\u0144\u03d9\3\2\2\2\u0146"+ - "\u03db\3\2\2\2\u0148\u03dd\3\2\2\2\u014a\u03df\3\2\2\2\u014c\u03e1\3\2"+ - "\2\2\u014e\u03e4\3\2\2\2\u0150\u03e6\3\2\2\2\u0152\u03e9\3\2\2\2\u0154"+ - "\u03eb\3\2\2\2\u0156\u03ee\3\2\2\2\u0158\u03f1\3\2\2\2\u015a\u03f3\3\2"+ - "\2\2\u015c\u03f5\3\2\2\2\u015e\u03f7\3\2\2\2\u0160\u03fa\3\2\2\2\u0162"+ - "\u0401\3\2\2\2\u0164\u0165\7\61\2\2\u0165\u016a\7\61\2\2\u0166\u0167\7"+ + "\u0300\3\2\2\2\u00d8\u0304\3\2\2\2\u00da\u0308\3\2\2\2\u00dc\u030c\3\2"+ + "\2\2\u00de\u030f\3\2\2\2\u00e0\u0315\3\2\2\2\u00e2\u031d\3\2\2\2\u00e4"+ + "\u0323\3\2\2\2\u00e6\u0328\3\2\2\2\u00e8\u032b\3\2\2\2\u00ea\u032e\3\2"+ + "\2\2\u00ec\u0331\3\2\2\2\u00ee\u0333\3\2\2\2\u00f0\u0335\3\2\2\2\u00f2"+ + "\u0337\3\2\2\2\u00f4\u0339\3\2\2\2\u00f6\u033b\3\2\2\2\u00f8\u033d\3\2"+ + "\2\2\u00fa\u033f\3\2\2\2\u00fc\u0341\3\2\2\2\u00fe\u0344\3\2\2\2\u0100"+ + "\u0348\3\2\2\2\u0102\u034c\3\2\2\2\u0104\u034f\3\2\2\2\u0106\u0353\3\2"+ + "\2\2\u0108\u0357\3\2\2\2\u010a\u035a\3\2\2\2\u010c\u035d\3\2\2\2\u010e"+ + "\u0360\3\2\2\2\u0110\u0363\3\2\2\2\u0112\u0366\3\2\2\2\u0114\u036a\3\2"+ + "\2\2\u0116\u036c\3\2\2\2\u0118\u036e\3\2\2\2\u011a\u0372\3\2\2\2\u011c"+ + "\u0376\3\2\2\2\u011e\u037a\3\2\2\2\u0120\u037e\3\2\2\2\u0122\u0382\3\2"+ + "\2\2\u0124\u0385\3\2\2\2\u0126\u0389\3\2\2\2\u0128\u0391\3\2\2\2\u012a"+ + "\u0399\3\2\2\2\u012c\u03a0\3\2\2\2\u012e\u03a7\3\2\2\2\u0130\u03ad\3\2"+ + "\2\2\u0132\u03b6\3\2\2\2\u0134\u03bf\3\2\2\2\u0136\u03c6\3\2\2\2\u0138"+ + "\u03ca\3\2\2\2\u013a\u03ce\3\2\2\2\u013c\u03d0\3\2\2\2\u013e\u03d2\3\2"+ + "\2\2\u0140\u03d4\3\2\2\2\u0142\u03d6\3\2\2\2\u0144\u03d8\3\2\2\2\u0146"+ + "\u03da\3\2\2\2\u0148\u03dc\3\2\2\2\u014a\u03de\3\2\2\2\u014c\u03e0\3\2"+ + "\2\2\u014e\u03e3\3\2\2\2\u0150\u03e5\3\2\2\2\u0152\u03e8\3\2\2\2\u0154"+ + "\u03ea\3\2\2\2\u0156\u03ed\3\2\2\2\u0158\u03f0\3\2\2\2\u015a\u03f2\3\2"+ + "\2\2\u015c\u03f4\3\2\2\2\u015e\u03f6\3\2\2\2\u0160\u03f9\3\2\2\2\u0162"+ + "\u0400\3\2\2\2\u0164\u0165\7\61\2\2\u0165\u016a\7\61\2\2\u0166\u0167\7"+ "/\2\2\u0167\u016a\7/\2\2\u0168\u016a\t\2\2\2\u0169\u0164\3\2\2\2\u0169"+ "\u0166\3\2\2\2\u0169\u0168\3\2\2\2\u016a\u016e\3\2\2\2\u016b\u016d\n\3"+ "\2\2\u016c\u016b\3\2\2\2\u016d\u0170\3\2\2\2\u016e\u016c\3\2\2\2\u016e"+ @@ -501,87 +501,86 @@ private boolean COND_UNRECOGNIZED_sempred(RuleContext _localctx, int predIndex) "\3\2\2\2\u02f5\u02f7\t\35\2\2\u02f6\u02f5\3\2\2\2\u02f7\u02f8\3\2\2\2"+ "\u02f8\u02f6\3\2\2\2\u02f8\u02f9\3\2\2\2\u02f9\u02fa\3\2\2\2\u02fa\u02fb"+ "\bi\2\2\u02fb\u00d3\3\2\2\2\u02fc\u02fd\6j\2\2\u02fd\u02fe\3\2\2\2\u02fe"+ - "\u02ff\bj\4\2\u02ff\u0300\bj\5\2\u0300\u00d5\3\2\2\2\u0301\u0302\5\"\21"+ - "\2\u0302\u0303\5(\24\2\u0303\u0304\5\24\n\2\u0304\u00d7\3\2\2\2\u0305"+ - "\u0306\5\20\b\2\u0306\u0307\5&\23\2\u0307\u0308\5.\27\2\u0308\u00d9\3"+ - "\2\2\2\u0309\u030a\5*\25\2\u030a\u030b\5\20\b\2\u030b\u030c\5,\26\2\u030c"+ - "\u00db\3\2\2\2\u030d\u030e\5\30\f\2\u030e\u030f\5\22\t\2\u030f\u00dd\3"+ - "\2\2\2\u0310\u0311\5\20\b\2\u0311\u0312\5 \20\2\u0312\u0313\5\16\7\2\u0313"+ - "\u0314\5\30\f\2\u0314\u0315\5\22\t\2\u0315\u00df\3\2\2\2\u0316\u0317\5"+ - "\30\f\2\u0317\u0318\5 \20\2\u0318\u0319\5\f\6\2\u0319\u031a\5\34\16\2"+ - "\u031a\u031b\5.\27\2\u031b\u031c\5\16\7\2\u031c\u031d\5\20\b\2\u031d\u00e1"+ - "\3\2\2\2\u031e\u031f\5\36\17\2\u031f\u0320\5\b\4\2\u0320\u0321\5\f\6\2"+ - "\u0321\u0322\5(\24\2\u0322\u0323\5\"\21\2\u0323\u00e3\3\2\2\2\u0324\u0325"+ - "\5\20\b\2\u0325\u0326\5 \20\2\u0326\u0327\5\16\7\2\u0327\u0328\5\36\17"+ - "\2\u0328\u00e5\3\2\2\2\u0329\u032a\5\16\7\2\u032a\u032b\5\n\5\2\u032b"+ - "\u00e7\3\2\2\2\u032c\u032d\5\16\7\2\u032d\u032e\5\62\31\2\u032e\u00e9"+ - "\3\2\2\2\u032f\u0330\5\16\7\2\u0330\u0331\5*\25\2\u0331\u00eb\3\2\2\2"+ - "\u0332\u0333\7&\2\2\u0333\u00ed\3\2\2\2\u0334\u0335\5\b\4\2\u0335\u00ef"+ - "\3\2\2\2\u0336\u0337\5\n\5\2\u0337\u00f1\3\2\2\2\u0338\u0339\5\f\6\2\u0339"+ - "\u00f3\3\2\2\2\u033a\u033b\5\16\7\2\u033b\u00f5\3\2\2\2\u033c\u033d\5"+ - "\20\b\2\u033d\u00f7\3\2\2\2\u033e\u033f\5\26\13\2\u033f\u00f9\3\2\2\2"+ - "\u0340\u0341\5\34\16\2\u0341\u00fb\3\2\2\2\u0342\u0343\5\30\f\2\u0343"+ - "\u0344\5\64\32\2\u0344\u00fd\3\2\2\2\u0345\u0346\5\30\f\2\u0346\u0347"+ - "\5\64\32\2\u0347\u0348\5\26\13\2\u0348\u00ff\3\2\2\2\u0349\u034a\5\30"+ - "\f\2\u034a\u034b\5\64\32\2\u034b\u034c\5\34\16\2\u034c\u0101\3\2\2\2\u034d"+ - "\u034e\5\30\f\2\u034e\u034f\5\66\33\2\u034f\u0103\3\2\2\2\u0350\u0351"+ - "\5\30\f\2\u0351\u0352\5\66\33\2\u0352\u0353\5\26\13\2\u0353\u0105\3\2"+ - "\2\2\u0354\u0355\5\30\f\2\u0355\u0356\5\66\33\2\u0356\u0357\5\34\16\2"+ - "\u0357\u0107\3\2\2\2\u0358\u0359\5\n\5\2\u0359\u035a\5\f\6\2\u035a\u0109"+ - "\3\2\2\2\u035b\u035c\5\16\7\2\u035c\u035d\5\20\b\2\u035d\u010b\3\2\2\2"+ - "\u035e\u035f\5\26\13\2\u035f\u0360\5\34\16\2\u0360\u010d\3\2\2\2\u0361"+ - "\u0362\5*\25\2\u0362\u0363\5$\22\2\u0363\u010f\3\2\2\2\u0364\u0365\5\b"+ - "\4\2\u0365\u0366\5\22\t\2\u0366\u0111\3\2\2\2\u0367\u0368\5\b\4\2\u0368"+ - "\u0369\5\22\t\2\u0369\u036a\7)\2\2\u036a\u0113\3\2\2\2\u036b\u036c\5\30"+ - "\f\2\u036c\u0115\3\2\2\2\u036d\u036e\5(\24\2\u036e\u0117\3\2\2\2\u036f"+ - "\u0370\5\36\17\2\u0370\u0371\5\"\21\2\u0371\u0372\5\16\7\2\u0372\u0119"+ - "\3\2\2\2\u0373\u0374\5*\25\2\u0374\u0375\5\26\13\2\u0375\u0376\5(\24\2"+ - "\u0376\u011b\3\2\2\2\u0377\u0378\5*\25\2\u0378\u0379\5\26\13\2\u0379\u037a"+ - "\5\34\16\2\u037a\u011d\3\2\2\2\u037b\u037c\5 \20\2\u037c\u037d\5\"\21"+ - "\2\u037d\u037e\5,\26\2\u037e\u011f\3\2\2\2\u037f\u0380\5\b\4\2\u0380\u0381"+ - "\5 \20\2\u0381\u0382\5\16\7\2\u0382\u0121\3\2\2\2\u0383\u0384\5\"\21\2"+ - "\u0384\u0385\5(\24\2\u0385\u0123\3\2\2\2\u0386\u0387\5\64\32\2\u0387\u0388"+ - "\5\"\21\2\u0388\u0389\5(\24\2\u0389\u0125\3\2\2\2\u038a\u038b\7\62\2\2"+ - "\u038b\u038d\5\64\32\2\u038c\u038e\t\36\2\2\u038d\u038c\3\2\2\2\u038e"+ - "\u038f\3\2\2\2\u038f\u038d\3\2\2\2\u038f\u0390\3\2\2\2\u0390\u0127\3\2"+ - "\2\2\u0391\u0393\t\37\2\2\u0392\u0391\3\2\2\2\u0393\u0394\3\2\2\2\u0394"+ - "\u0392\3\2\2\2\u0394\u0395\3\2\2\2\u0395\u0397\3\2\2\2\u0396\u0398\5\16"+ - "\7\2\u0397\u0396\3\2\2\2\u0397\u0398\3\2\2\2\u0398\u0129\3\2\2\2\u0399"+ - "\u039b\t\36\2\2\u039a\u0399\3\2\2\2\u039b\u039c\3\2\2\2\u039c\u039a\3"+ - "\2\2\2\u039c\u039d\3\2\2\2\u039d\u039e\3\2\2\2\u039e\u039f\5\26\13\2\u039f"+ - "\u012b\3\2\2\2\u03a0\u03a2\t \2\2\u03a1\u03a0\3\2\2\2\u03a2\u03a3\3\2"+ - "\2\2\u03a3\u03a1\3\2\2\2\u03a3\u03a4\3\2\2\2\u03a4\u03a5\3\2\2\2\u03a5"+ - "\u03a6\t!\2\2\u03a6\u012d\3\2\2\2\u03a7\u03a9\t\"\2\2\u03a8\u03a7\3\2"+ - "\2\2\u03a9\u03aa\3\2\2\2\u03aa\u03a8\3\2\2\2\u03aa\u03ab\3\2\2\2\u03ab"+ - "\u03ac\3\2\2\2\u03ac\u03ad\5\n\5\2\u03ad\u012f\3\2\2\2\u03ae\u03b2\7)"+ - "\2\2\u03af\u03b1\n#\2\2\u03b0\u03af\3\2\2\2\u03b1\u03b4\3\2\2\2\u03b2"+ - "\u03b0\3\2\2\2\u03b2\u03b3\3\2\2\2\u03b3\u03b5\3\2\2\2\u03b4\u03b2\3\2"+ - "\2\2\u03b5\u03b6\7)\2\2\u03b6\u0131\3\2\2\2\u03b7\u03bb\7$\2\2\u03b8\u03ba"+ - "\n$\2\2\u03b9\u03b8\3\2\2\2\u03ba\u03bd\3\2\2\2\u03bb\u03b9\3\2\2\2\u03bb"+ - "\u03bc\3\2\2\2\u03bc\u03be\3\2\2\2\u03bd\u03bb\3\2\2\2\u03be\u03bf\7$"+ - "\2\2\u03bf\u0133\3\2\2\2\u03c0\u03c4\t%\2\2\u03c1\u03c3\t&\2\2\u03c2\u03c1"+ - "\3\2\2\2\u03c3\u03c6\3\2\2\2\u03c4\u03c2\3\2\2\2\u03c4\u03c5\3\2\2\2\u03c5"+ - "\u0135\3\2\2\2\u03c6\u03c4\3\2\2\2\u03c7\u03c8\5\u0134\u009a\2\u03c8\u03c9"+ - "\7<\2\2\u03c9\u0137\3\2\2\2\u03ca\u03cc\n\'\2\2\u03cb\u03ca\3\2\2\2\u03cc"+ - "\u03cd\3\2\2\2\u03cd\u03cb\3\2\2\2\u03cd\u03ce\3\2\2\2\u03ce\u0139\3\2"+ - "\2\2\u03cf\u03d0\7*\2\2\u03d0\u013b\3\2\2\2\u03d1\u03d2\7+\2\2\u03d2\u013d"+ - "\3\2\2\2\u03d3\u03d4\7.\2\2\u03d4\u013f\3\2\2\2\u03d5\u03d6\7-\2\2\u03d6"+ - "\u0141\3\2\2\2\u03d7\u03d8\7/\2\2\u03d8\u0143\3\2\2\2\u03d9\u03da\7,\2"+ - "\2\u03da\u0145\3\2\2\2\u03db\u03dc\7\61\2\2\u03dc\u0147\3\2\2\2\u03dd"+ - "\u03de\7?\2\2\u03de\u0149\3\2\2\2\u03df\u03e0\7@\2\2\u03e0\u014b\3\2\2"+ - "\2\u03e1\u03e2\7@\2\2\u03e2\u03e3\7?\2\2\u03e3\u014d\3\2\2\2\u03e4\u03e5"+ - "\7>\2\2\u03e5\u014f\3\2\2\2\u03e6\u03e7\7>\2\2\u03e7\u03e8\7?\2\2\u03e8"+ - "\u0151\3\2\2\2\u03e9\u03ea\7\'\2\2\u03ea\u0153\3\2\2\2\u03eb\u03ec\7@"+ - "\2\2\u03ec\u03ed\7@\2\2\u03ed\u0155\3\2\2\2\u03ee\u03ef\7>\2\2\u03ef\u03f0"+ - "\7>\2\2\u03f0\u0157\3\2\2\2\u03f1\u03f2\7\u0080\2\2\u03f2\u0159\3\2\2"+ - "\2\u03f3\u03f4\7(\2\2\u03f4\u015b\3\2\2\2\u03f5\u03f6\7~\2\2\u03f6\u015d"+ - "\3\2\2\2\u03f7\u03f8\7`\2\2\u03f8\u015f\3\2\2\2\u03f9\u03fb\t\35\2\2\u03fa"+ - "\u03f9\3\2\2\2\u03fb\u03fc\3\2\2\2\u03fc\u03fa\3\2\2\2\u03fc\u03fd\3\2"+ - "\2\2\u03fd\u03fe\3\2\2\2\u03fe\u03ff\b\u00b0\2\2\u03ff\u0161\3\2\2\2\u0400"+ - "\u0402\7\17\2\2\u0401\u0400\3\2\2\2\u0401\u0402\3\2\2\2\u0402\u0403\3"+ - "\2\2\2\u0403\u0404\7\f\2\2\u0404\u0163\3\2\2\2\24\2\3\u0169\u016e\u0179"+ - "\u02f8\u038f\u0394\u0397\u039c\u03a3\u03aa\u03b2\u03bb\u03c4\u03cd\u03fc"+ - "\u0401\6\b\2\2\7\3\2\6\2\2\2\3\2"; + "\u02ff\bj\4\2\u02ff\u00d5\3\2\2\2\u0300\u0301\5\"\21\2\u0301\u0302\5("+ + "\24\2\u0302\u0303\5\24\n\2\u0303\u00d7\3\2\2\2\u0304\u0305\5\20\b\2\u0305"+ + "\u0306\5&\23\2\u0306\u0307\5.\27\2\u0307\u00d9\3\2\2\2\u0308\u0309\5*"+ + "\25\2\u0309\u030a\5\20\b\2\u030a\u030b\5,\26\2\u030b\u00db\3\2\2\2\u030c"+ + "\u030d\5\30\f\2\u030d\u030e\5\22\t\2\u030e\u00dd\3\2\2\2\u030f\u0310\5"+ + "\20\b\2\u0310\u0311\5 \20\2\u0311\u0312\5\16\7\2\u0312\u0313\5\30\f\2"+ + "\u0313\u0314\5\22\t\2\u0314\u00df\3\2\2\2\u0315\u0316\5\30\f\2\u0316\u0317"+ + "\5 \20\2\u0317\u0318\5\f\6\2\u0318\u0319\5\34\16\2\u0319\u031a\5.\27\2"+ + "\u031a\u031b\5\16\7\2\u031b\u031c\5\20\b\2\u031c\u00e1\3\2\2\2\u031d\u031e"+ + "\5\36\17\2\u031e\u031f\5\b\4\2\u031f\u0320\5\f\6\2\u0320\u0321\5(\24\2"+ + "\u0321\u0322\5\"\21\2\u0322\u00e3\3\2\2\2\u0323\u0324\5\20\b\2\u0324\u0325"+ + "\5 \20\2\u0325\u0326\5\16\7\2\u0326\u0327\5\36\17\2\u0327\u00e5\3\2\2"+ + "\2\u0328\u0329\5\16\7\2\u0329\u032a\5\n\5\2\u032a\u00e7\3\2\2\2\u032b"+ + "\u032c\5\16\7\2\u032c\u032d\5\62\31\2\u032d\u00e9\3\2\2\2\u032e\u032f"+ + "\5\16\7\2\u032f\u0330\5*\25\2\u0330\u00eb\3\2\2\2\u0331\u0332\7&\2\2\u0332"+ + "\u00ed\3\2\2\2\u0333\u0334\5\b\4\2\u0334\u00ef\3\2\2\2\u0335\u0336\5\n"+ + "\5\2\u0336\u00f1\3\2\2\2\u0337\u0338\5\f\6\2\u0338\u00f3\3\2\2\2\u0339"+ + "\u033a\5\16\7\2\u033a\u00f5\3\2\2\2\u033b\u033c\5\20\b\2\u033c\u00f7\3"+ + "\2\2\2\u033d\u033e\5\26\13\2\u033e\u00f9\3\2\2\2\u033f\u0340\5\34\16\2"+ + "\u0340\u00fb\3\2\2\2\u0341\u0342\5\30\f\2\u0342\u0343\5\64\32\2\u0343"+ + "\u00fd\3\2\2\2\u0344\u0345\5\30\f\2\u0345\u0346\5\64\32\2\u0346\u0347"+ + "\5\26\13\2\u0347\u00ff\3\2\2\2\u0348\u0349\5\30\f\2\u0349\u034a\5\64\32"+ + "\2\u034a\u034b\5\34\16\2\u034b\u0101\3\2\2\2\u034c\u034d\5\30\f\2\u034d"+ + "\u034e\5\66\33\2\u034e\u0103\3\2\2\2\u034f\u0350\5\30\f\2\u0350\u0351"+ + "\5\66\33\2\u0351\u0352\5\26\13\2\u0352\u0105\3\2\2\2\u0353\u0354\5\30"+ + "\f\2\u0354\u0355\5\66\33\2\u0355\u0356\5\34\16\2\u0356\u0107\3\2\2\2\u0357"+ + "\u0358\5\n\5\2\u0358\u0359\5\f\6\2\u0359\u0109\3\2\2\2\u035a\u035b\5\16"+ + "\7\2\u035b\u035c\5\20\b\2\u035c\u010b\3\2\2\2\u035d\u035e\5\26\13\2\u035e"+ + "\u035f\5\34\16\2\u035f\u010d\3\2\2\2\u0360\u0361\5*\25\2\u0361\u0362\5"+ + "$\22\2\u0362\u010f\3\2\2\2\u0363\u0364\5\b\4\2\u0364\u0365\5\22\t\2\u0365"+ + "\u0111\3\2\2\2\u0366\u0367\5\b\4\2\u0367\u0368\5\22\t\2\u0368\u0369\7"+ + ")\2\2\u0369\u0113\3\2\2\2\u036a\u036b\5\30\f\2\u036b\u0115\3\2\2\2\u036c"+ + "\u036d\5(\24\2\u036d\u0117\3\2\2\2\u036e\u036f\5\36\17\2\u036f\u0370\5"+ + "\"\21\2\u0370\u0371\5\16\7\2\u0371\u0119\3\2\2\2\u0372\u0373\5*\25\2\u0373"+ + "\u0374\5\26\13\2\u0374\u0375\5(\24\2\u0375\u011b\3\2\2\2\u0376\u0377\5"+ + "*\25\2\u0377\u0378\5\26\13\2\u0378\u0379\5\34\16\2\u0379\u011d\3\2\2\2"+ + "\u037a\u037b\5 \20\2\u037b\u037c\5\"\21\2\u037c\u037d\5,\26\2\u037d\u011f"+ + "\3\2\2\2\u037e\u037f\5\b\4\2\u037f\u0380\5 \20\2\u0380\u0381\5\16\7\2"+ + "\u0381\u0121\3\2\2\2\u0382\u0383\5\"\21\2\u0383\u0384\5(\24\2\u0384\u0123"+ + "\3\2\2\2\u0385\u0386\5\64\32\2\u0386\u0387\5\"\21\2\u0387\u0388\5(\24"+ + "\2\u0388\u0125\3\2\2\2\u0389\u038a\7\62\2\2\u038a\u038c\5\64\32\2\u038b"+ + "\u038d\t\36\2\2\u038c\u038b\3\2\2\2\u038d\u038e\3\2\2\2\u038e\u038c\3"+ + "\2\2\2\u038e\u038f\3\2\2\2\u038f\u0127\3\2\2\2\u0390\u0392\t\37\2\2\u0391"+ + "\u0390\3\2\2\2\u0392\u0393\3\2\2\2\u0393\u0391\3\2\2\2\u0393\u0394\3\2"+ + "\2\2\u0394\u0396\3\2\2\2\u0395\u0397\5\16\7\2\u0396\u0395\3\2\2\2\u0396"+ + "\u0397\3\2\2\2\u0397\u0129\3\2\2\2\u0398\u039a\t\36\2\2\u0399\u0398\3"+ + "\2\2\2\u039a\u039b\3\2\2\2\u039b\u0399\3\2\2\2\u039b\u039c\3\2\2\2\u039c"+ + "\u039d\3\2\2\2\u039d\u039e\5\26\13\2\u039e\u012b\3\2\2\2\u039f\u03a1\t"+ + " \2\2\u03a0\u039f\3\2\2\2\u03a1\u03a2\3\2\2\2\u03a2\u03a0\3\2\2\2\u03a2"+ + "\u03a3\3\2\2\2\u03a3\u03a4\3\2\2\2\u03a4\u03a5\t!\2\2\u03a5\u012d\3\2"+ + "\2\2\u03a6\u03a8\t\"\2\2\u03a7\u03a6\3\2\2\2\u03a8\u03a9\3\2\2\2\u03a9"+ + "\u03a7\3\2\2\2\u03a9\u03aa\3\2\2\2\u03aa\u03ab\3\2\2\2\u03ab\u03ac\5\n"+ + "\5\2\u03ac\u012f\3\2\2\2\u03ad\u03b1\7)\2\2\u03ae\u03b0\n#\2\2\u03af\u03ae"+ + "\3\2\2\2\u03b0\u03b3\3\2\2\2\u03b1\u03af\3\2\2\2\u03b1\u03b2\3\2\2\2\u03b2"+ + "\u03b4\3\2\2\2\u03b3\u03b1\3\2\2\2\u03b4\u03b5\7)\2\2\u03b5\u0131\3\2"+ + "\2\2\u03b6\u03ba\7$\2\2\u03b7\u03b9\n$\2\2\u03b8\u03b7\3\2\2\2\u03b9\u03bc"+ + "\3\2\2\2\u03ba\u03b8\3\2\2\2\u03ba\u03bb\3\2\2\2\u03bb\u03bd\3\2\2\2\u03bc"+ + "\u03ba\3\2\2\2\u03bd\u03be\7$\2\2\u03be\u0133\3\2\2\2\u03bf\u03c3\t%\2"+ + "\2\u03c0\u03c2\t&\2\2\u03c1\u03c0\3\2\2\2\u03c2\u03c5\3\2\2\2\u03c3\u03c1"+ + "\3\2\2\2\u03c3\u03c4\3\2\2\2\u03c4\u0135\3\2\2\2\u03c5\u03c3\3\2\2\2\u03c6"+ + "\u03c7\5\u0134\u009a\2\u03c7\u03c8\7<\2\2\u03c8\u0137\3\2\2\2\u03c9\u03cb"+ + "\n\'\2\2\u03ca\u03c9\3\2\2\2\u03cb\u03cc\3\2\2\2\u03cc\u03ca\3\2\2\2\u03cc"+ + "\u03cd\3\2\2\2\u03cd\u0139\3\2\2\2\u03ce\u03cf\7*\2\2\u03cf\u013b\3\2"+ + "\2\2\u03d0\u03d1\7+\2\2\u03d1\u013d\3\2\2\2\u03d2\u03d3\7.\2\2\u03d3\u013f"+ + "\3\2\2\2\u03d4\u03d5\7-\2\2\u03d5\u0141\3\2\2\2\u03d6\u03d7\7/\2\2\u03d7"+ + "\u0143\3\2\2\2\u03d8\u03d9\7,\2\2\u03d9\u0145\3\2\2\2\u03da\u03db\7\61"+ + "\2\2\u03db\u0147\3\2\2\2\u03dc\u03dd\7?\2\2\u03dd\u0149\3\2\2\2\u03de"+ + "\u03df\7@\2\2\u03df\u014b\3\2\2\2\u03e0\u03e1\7@\2\2\u03e1\u03e2\7?\2"+ + "\2\u03e2\u014d\3\2\2\2\u03e3\u03e4\7>\2\2\u03e4\u014f\3\2\2\2\u03e5\u03e6"+ + "\7>\2\2\u03e6\u03e7\7?\2\2\u03e7\u0151\3\2\2\2\u03e8\u03e9\7\'\2\2\u03e9"+ + "\u0153\3\2\2\2\u03ea\u03eb\7@\2\2\u03eb\u03ec\7@\2\2\u03ec\u0155\3\2\2"+ + "\2\u03ed\u03ee\7>\2\2\u03ee\u03ef\7>\2\2\u03ef\u0157\3\2\2\2\u03f0\u03f1"+ + "\7\u0080\2\2\u03f1\u0159\3\2\2\2\u03f2\u03f3\7(\2\2\u03f3\u015b\3\2\2"+ + "\2\u03f4\u03f5\7~\2\2\u03f5\u015d\3\2\2\2\u03f6\u03f7\7`\2\2\u03f7\u015f"+ + "\3\2\2\2\u03f8\u03fa\t\35\2\2\u03f9\u03f8\3\2\2\2\u03fa\u03fb\3\2\2\2"+ + "\u03fb\u03f9\3\2\2\2\u03fb\u03fc\3\2\2\2\u03fc\u03fd\3\2\2\2\u03fd\u03fe"+ + "\b\u00b0\2\2\u03fe\u0161\3\2\2\2\u03ff\u0401\7\17\2\2\u0400\u03ff\3\2"+ + "\2\2\u0400\u0401\3\2\2\2\u0401\u0402\3\2\2\2\u0402\u0403\7\f\2\2\u0403"+ + "\u0163\3\2\2\2\24\2\3\u0169\u016e\u0179\u02f8\u038e\u0393\u0396\u039b"+ + "\u03a2\u03a9\u03b1\u03ba\u03c3\u03cc\u03fb\u0400\5\b\2\2\7\3\2\6\2\2"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java new file mode 100644 index 000000000..a4ca44e91 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java @@ -0,0 +1,91 @@ +package net.emustudio.plugins.compiler.asZ80; + +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +//http://www.z80.info/decoding.htm +public class CompilerTables { + + public final static Map registers = new HashMap<>(); + public final static Map regPairs = new HashMap<>(); + public final static Map regPairs2 = new HashMap<>(); + public final static Map conditions = new HashMap<>(); + public final static Map alu = new HashMap<>(); + public final static Map rot = new HashMap<>(); + public final static Map im = new HashMap<>(); + public final static Map> block = new HashMap<>(); + + static { + registers.put(REG_B, 0); + registers.put(REG_C, 1); + registers.put(REG_D, 2); + registers.put(REG_E, 3); + registers.put(REG_H, 4); + registers.put(REG_L, 5); + registers.put(REG_HL, 6); + registers.put(REG_A, 7); + + regPairs.put(REG_BC, 0); + regPairs.put(REG_DE, 1); + regPairs.put(REG_HL, 2); + regPairs.put(REG_SP, 3); + + regPairs2.put(REG_BC, 0); + regPairs2.put(REG_DE, 1); + regPairs2.put(REG_HL, 2); + regPairs2.put(REG_AF, 3); + + conditions.put(COND_NZ, 0); + conditions.put(COND_Z, 1); + conditions.put(COND_NC, 2); + conditions.put(COND_C, 3); + conditions.put(COND_PO, 4); + conditions.put(COND_PE, 5); + conditions.put(COND_P, 6); + conditions.put(COND_M, 7); + + alu.put(OPCODE_ADD, 0); + alu.put(OPCODE_ADC, 1); + alu.put(OPCODE_SUB, 2); + alu.put(OPCODE_SBC, 3); + alu.put(OPCODE_AND, 4); + alu.put(OPCODE_XOR, 5); + alu.put(OPCODE_OR, 6); + alu.put(OPCODE_CP, 7); + + rot.put(OPCODE_RLC, 0); + rot.put(OPCODE_RRC, 1); + rot.put(OPCODE_RL, 2); + rot.put(OPCODE_RR, 3); + rot.put(OPCODE_SLA, 4); + rot.put(OPCODE_SRA, 5); + rot.put(OPCODE_SLL, 6); + rot.put(OPCODE_SRL, 7); + + im.put("0", 0); + im.put("0/1", 1); + im.put("1", 2); + im.put("2", 3); + + block.put(OPCODE_LDI, Pair.of(4, 0)); + block.put(OPCODE_LDD, Pair.of(5, 0)); + block.put(OPCODE_LDIR, Pair.of(6, 0)); + block.put(OPCODE_LDDR, Pair.of(7, 0)); + block.put(OPCODE_CPI, Pair.of(4, 1)); + block.put(OPCODE_CPD, Pair.of(5, 1)); + block.put(OPCODE_CPIR, Pair.of(6, 1)); + block.put(OPCODE_CPDR, Pair.of(7, 1)); + block.put(OPCODE_INI, Pair.of(4, 2)); + block.put(OPCODE_IND, Pair.of(5, 2)); + block.put(OPCODE_INIR, Pair.of(6, 2)); + block.put(OPCODE_INDR, Pair.of(7, 2)); + block.put(OPCODE_OUTI, Pair.of(4, 3)); + block.put(OPCODE_OUTD, Pair.of(5, 3)); + block.put(OPCODE_OTIR, Pair.of(6, 3)); + block.put(OPCODE_OTDR, Pair.of(7, 3)); + } + + +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Pair.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Pair.java new file mode 100644 index 000000000..c8a98ebca --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Pair.java @@ -0,0 +1,15 @@ +package net.emustudio.plugins.compiler.asZ80; + +public class Pair { + public final L l; + public final R r; + + public Pair(L l, R r) { + this.l = l; + this.r = r; + } + + public static Pair of(L l, R r) { + return new Pair<>(l, r); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java new file mode 100644 index 000000000..60ab51381 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java @@ -0,0 +1,99 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +public class Instr extends Node { + // opcode=OPCODE_NOP + // opcode=OPCODE_RLCA + // opcode=OPCODE_RRCA + // opcode=OPCODE_RLA + // opcode=OPCODE_RRA + // opcode=OPCODE_DJNZ + // opcode=OPCODE_DAA + // opcode=OPCODE_CPL + // opcode=OPCODE_SCF + // opcode=OPCODE_CCF + // opcode=OPCODE_HALT + // opcode=OPCODE_RET + // opcode=OPCODE_EXX + // opcode=OPCODE_DI + // opcode=OPCODE_EI + + private final static Map opcodes = new HashMap<>(); + public final int opcode; + + static { + opcodes.put(OPCODE_NOP, 0); + opcodes.put(OPCODE_RLCA, 7); + opcodes.put(OPCODE_RRCA, 0x0F); + opcodes.put(OPCODE_RLA, 0x17); + opcodes.put(OPCODE_RRA, 0x1F); + opcodes.put(OPCODE_DAA, 0x27); + opcodes.put(OPCODE_CPL, 0x2F); + opcodes.put(OPCODE_SCF, 0x37); + opcodes.put(OPCODE_CCF, 0x3F); + opcodes.put(OPCODE_HALT, 0x76); + opcodes.put(OPCODE_RET, 0xC9); + opcodes.put(OPCODE_EXX, 0xD9); + opcodes.put(OPCODE_DI, 0xF3); + opcodes.put(OPCODE_EI, 0xFB); + + +// opcodes.put(OPCODE_XCHG, 0xEB); +// opcodes.put(OPCODE_XTHL, 0xE3); +// opcodes.put(OPCODE_SPHL, 0xF9); +// opcodes.put(OPCODE_PCHL, 0xE9); +// opcodes.put(OPCODE_RC, 0xD8); +// opcodes.put(OPCODE_RNC, 0xD0); +// opcodes.put(OPCODE_RZ, 0xC8); +// opcodes.put(OPCODE_RNZ, 0xC0); +// opcodes.put(OPCODE_RM, 0xF8); +// opcodes.put(OPCODE_RP, 0xF0); +// opcodes.put(OPCODE_RPE, 0xE8); +// opcodes.put(OPCODE_RPO, 0xE0); + } + + public Instr(int line, int column, int opcode) { + super(line, column); + this.opcode = opcode; + } + + public Instr(Token opcode) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); + } + + public byte eval() { + return (byte) (opcodes.get(opcode) & 0xFF); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "InstrNoArgs(" + opcode + ")"; + } + + @Override + protected Node mkCopy() { + return new Instr(line, column, opcode); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Instr that = (Instr) o; + return opcode == that.opcode; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrA_Ref_RP.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrA_Ref_RP.java new file mode 100644 index 000000000..74a42a969 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrA_Ref_RP.java @@ -0,0 +1,26 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import org.antlr.v4.runtime.Token; + +public class InstrA_Ref_RP extends Node { + // opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR + + public final int opcode; + public final int regPair; + + public InstrA_Ref_RP(int line, int column, int opcode, int regPair) { + super(line, column); + this.opcode = opcode; + this.regPair = regPair; + } + + public InstrA_Ref_RP(Token opcode, Token regPair) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); + } + + @Override + protected Node mkCopy() { + return new InstrA_Ref_RP(line, column, opcode, regPair); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC.java new file mode 100644 index 000000000..69f11ed63 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC.java @@ -0,0 +1,26 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import org.antlr.v4.runtime.Token; + +public class InstrC extends Node { + // opcode=OPCODE_RET c=cCondition + + public final int opcode; + public final int cond; + + public InstrC(int line, int column, int opcode, int cond) { + super(line, column); + this.opcode = opcode; + this.cond = cond; + } + + public InstrC(Token opcode, Token cond) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), cond.getType()); + } + + @Override + protected Node mkCopy() { + return new InstrC(line, column, opcode, cond); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_N.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_N.java new file mode 100644 index 000000000..5b85ccb47 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_N.java @@ -0,0 +1,29 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import org.antlr.v4.runtime.Token; + +public class InstrC_N extends Node { + // opcode=OPCODE_JR c=(COND_NZ|COND_Z|COND_NC|COND_C) SEP_COMMA n=rExpression + + public final int opcode; + public final int cond; + + public InstrC_N(int line, int column, int opcode, int cond) { + super(line, column); + this.opcode = opcode; + this.cond = cond; + // child is expr + } + + public InstrC_N(Token opcode, Token cond) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), cond.getType()); + } + + + + @Override + protected Node mkCopy() { + return new InstrC_N(line, column, opcode, cond); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_NN.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_NN.java new file mode 100644 index 000000000..3cd120861 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_NN.java @@ -0,0 +1,28 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import org.antlr.v4.runtime.Token; + +public class InstrC_NN extends Node { + // opcode=OPCODE_JP c=cCondition SEP_COMMA nn=rExpression + // opcode=OPCODE_CALL c=cCondition SEP_COMMA nn=rExpression + + public final int opcode; + public final int cond; + + public InstrC_NN(int line, int column, int opcode, int cond) { + super(line, column); + this.opcode = opcode; + this.cond = cond; + // child is expr + } + + public InstrC_NN(Token opcode, Token cond) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), cond.getType()); + } + + @Override + protected Node mkCopy() { + return new InstrC_NN(line, column, opcode, cond); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrExpr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrExpr.java deleted file mode 100644 index 7cde73c23..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrExpr.java +++ /dev/null @@ -1,117 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; -import org.antlr.v4.runtime.Token; - -import java.util.*; - -import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; - -public class InstrExpr extends Node { - public final int opcode; - private final static Set twoBytes = new HashSet<>(); - private final static Map opcodes = new HashMap<>(); - - static { - twoBytes.add(OPCODE_ADI); - twoBytes.add(OPCODE_ACI); - twoBytes.add(OPCODE_SUI); - twoBytes.add(OPCODE_SBI); - twoBytes.add(OPCODE_ANI); - twoBytes.add(OPCODE_ORI); - twoBytes.add(OPCODE_XRI); - twoBytes.add(OPCODE_CPI); - twoBytes.add(OPCODE_IN); - twoBytes.add(OPCODE_OUT); - - opcodes.put(OPCODE_LDA, 0x3A); - opcodes.put(OPCODE_STA, 0x32); - opcodes.put(OPCODE_LHLD, 0x2A); - opcodes.put(OPCODE_SHLD, 0x22); - opcodes.put(OPCODE_ADI, 0xC6); - opcodes.put(OPCODE_ACI, 0xCE); - opcodes.put(OPCODE_SUI, 0xD6); - opcodes.put(OPCODE_SBI, 0xDE); - opcodes.put(OPCODE_ANI, 0xE6); - opcodes.put(OPCODE_ORI, 0xF6); - opcodes.put(OPCODE_XRI, 0xEE); - opcodes.put(OPCODE_CPI, 0xFE); - opcodes.put(OPCODE_JMP, 0xC3); - opcodes.put(OPCODE_JC, 0xDA); - opcodes.put(OPCODE_JNC, 0xD2); - opcodes.put(OPCODE_JZ, 0xCA); - opcodes.put(OPCODE_JNZ, 0xC2); - opcodes.put(OPCODE_JM, 0xFA); - opcodes.put(OPCODE_JP, 0xF2); - opcodes.put(OPCODE_JPE, 0xEA); - opcodes.put(OPCODE_JPO, 0xE2); - opcodes.put(OPCODE_CALL, 0xCD); - opcodes.put(OPCODE_CC, 0xDC); - opcodes.put(OPCODE_CZ, 0xCC); - opcodes.put(OPCODE_CNC, 0xD4); - opcodes.put(OPCODE_CNZ, 0xC4); - opcodes.put(OPCODE_CM, 0xFC); - opcodes.put(OPCODE_CP, 0xF4); - opcodes.put(OPCODE_CPE, 0xEC); - opcodes.put(OPCODE_CPO, 0xE4); - opcodes.put(OPCODE_IN, 0xDB); - opcodes.put(OPCODE_OUT, 0xD3); - opcodes.put(OPCODE_RST, 0xC7); - } - - public InstrExpr(int line, int column, int opcode) { - super(line, column); - this.opcode = opcode; - // child is expr - } - - public InstrExpr(Token opcode) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); - } - - public int getExprSizeBytes() { - if (opcode == OPCODE_RST) { - return 0; - } else if (twoBytes.contains(opcode)) { - return 1; - } - return 2; // address - } - - public Optional eval() { - byte result = (byte) (opcodes.get(opcode) & 0xFF); - if (opcode == OPCODE_RST) { - return collectChild(Evaluated.class) - .filter(e -> e.value >= 0 && e.value <= 7) - .map(e -> (byte) (result | (e.value << 3))); - } - - return Optional.of(result); - } - - @Override - public void accept(NodeVisitor visitor) { - visitor.visit(this); - } - - @Override - protected String toStringShallow() { - return "InstrExpr(" + opcode + ")"; - } - - @Override - protected Node mkCopy() { - return new InstrExpr(line, column, opcode); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - InstrExpr instrExpr = (InstrExpr) o; - return opcode == instrExpr.opcode; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrN.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrN.java new file mode 100644 index 000000000..b5551f7bd --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrN.java @@ -0,0 +1,134 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.*; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +public class InstrN extends Node { + // opcode=OPCODE_JR n=rExpression + // opcode=OPCODE_ADD REG_A SEP_COMMA n=rExpression + // opcode=OPCODE_ADC REG_A SEP_COMMA n=rExpression + // opcode=OPCODE_OUT SEP_LPAR n=rExpression SEP_RPAR SEP_COMMA REG_A + // opcode=OPCODE_SUB n=rExpression + // opcode=OPCODE_IN REG_A SEP_COMMA SEP_LPAR n=rExpression SEP_RPAR + // opcode=OPCODE_SBC REG_A SEP_COMMA n=rExpression + // opcode=OPCODE_AND n=rExpression + // opcode=OPCODE_XOR n=rExpression + // opcode=OPCODE_OR n=rExpression + // opcode=OPCODE_CP n=rExpression + // opcode=OPCODE_RST n=rExpression + + public final int opcode; + private final static Set twoBytes = new HashSet<>(); + private final static Map opcodes = new HashMap<>(); + + static { + twoBytes.add(OPCODE_JR); + twoBytes.add(OPCODE_ADD); + twoBytes.add(OPCODE_ADC); + twoBytes.add(OPCODE_SUB); + twoBytes.add(OPCODE_SBC); + twoBytes.add(OPCODE_AND); + twoBytes.add(OPCODE_XOR); + twoBytes.add(OPCODE_OR); + twoBytes.add(OPCODE_CP); + twoBytes.add(OPCODE_IN); + twoBytes.add(OPCODE_OUT); + + opcodes.put(OPCODE_JR, 0x18); + opcodes.put(OPCODE_JP, 0xC3); + opcodes.put(OPCODE_CALL, 0xCD); + opcodes.put(OPCODE_ADD, 0xC6); + opcodes.put(OPCODE_ADC, 0xCE); + opcodes.put(OPCODE_SUB, 0xD6); + opcodes.put(OPCODE_SBC, 0xDE); + opcodes.put(OPCODE_AND, 0xE6); + opcodes.put(OPCODE_XOR, 0xEE); + opcodes.put(OPCODE_OR, 0xF6); + opcodes.put(OPCODE_CP, 0xFE); + opcodes.put(OPCODE_RST, 0xC7); + opcodes.put(OPCODE_IN, 0xDB); + opcodes.put(OPCODE_OUT, 0xD3); + + + +// opcodes.put(OPCODE_STA, 0x32); +// opcodes.put(OPCODE_LHLD, 0x2A); +// opcodes.put(OPCODE_SHLD, 0x22); +// opcodes.put(OPCODE_JC, 0xDA); +// opcodes.put(OPCODE_JNC, 0xD2); +// opcodes.put(OPCODE_JZ, 0xCA); +// opcodes.put(OPCODE_JNZ, 0xC2); +// opcodes.put(OPCODE_JM, 0xFA); +// opcodes.put(OPCODE_JP, 0xF2); +// opcodes.put(OPCODE_JPE, 0xEA); +// opcodes.put(OPCODE_JPO, 0xE2); +// opcodes.put(OPCODE_CC, 0xDC); +// opcodes.put(OPCODE_CZ, 0xCC); +// opcodes.put(OPCODE_CNC, 0xD4); +// opcodes.put(OPCODE_CNZ, 0xC4); +// opcodes.put(OPCODE_CM, 0xFC); +// opcodes.put(OPCODE_CP, 0xF4); +// opcodes.put(OPCODE_CPE, 0xEC); +// opcodes.put(OPCODE_CPO, 0xE4); + } + + public InstrN(int line, int column, int opcode) { + super(line, column); + this.opcode = opcode; + // child is expr + } + + public InstrN(Token opcode) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); + } + + public int getExprSizeBytes() { + if (opcode == OPCODE_RST) { + return 0; + } else if (twoBytes.contains(opcode)) { + return 1; + } + return 2; // address + } + + public Optional eval() { + byte result = (byte) (opcodes.get(opcode) & 0xFF); + if (opcode == OPCODE_RST) { + return collectChild(Evaluated.class) + .filter(e -> e.value >= 0 && e.value <= 7) + .map(e -> (byte) (result | (e.value << 3))); + } + + return Optional.of(result); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected String toStringShallow() { + return "InstrExpr(" + opcode + ")"; + } + + @Override + protected Node mkCopy() { + return new InstrN(line, column, opcode); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstrN instrExpr = (InstrN) o; + return opcode == instrExpr.opcode; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNN.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNN.java new file mode 100644 index 000000000..4ba1246e3 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNN.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import org.antlr.v4.runtime.Token; + +public class InstrNN extends Node { + // opcode=OPCODE_JP nn=rExpression + // opcode=OPCODE_CALL nn=rExpression + public final int opcode; + + public InstrNN(int line, int column, int opcode) { + super(line, column); + this.opcode = opcode; + // child is expr + } + + public InstrNN(Token opcode) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); + } + + @Override + protected Node mkCopy() { + return new InstrNN(line, column, opcode); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNoArgs.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNoArgs.java deleted file mode 100644 index 704db9ac6..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNoArgs.java +++ /dev/null @@ -1,80 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; -import org.antlr.v4.runtime.Token; - -import java.util.HashMap; -import java.util.Map; - -import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; - -public class InstrNoArgs extends Node { - private final static Map opcodes = new HashMap<>(); - public final int opcode; - - static { - opcodes.put(OPCODE_STC, 0x37); - opcodes.put(OPCODE_CMC, 0x3F); - opcodes.put(OPCODE_CMA, 0x2F); - opcodes.put(OPCODE_DAA, 0x27); - opcodes.put(OPCODE_NOP, 0); - opcodes.put(OPCODE_RLC, 7); - opcodes.put(OPCODE_RRC, 0xF); - opcodes.put(OPCODE_RAL, 0x17); - opcodes.put(OPCODE_RAR, 0x1F); - opcodes.put(OPCODE_XCHG, 0xEB); - opcodes.put(OPCODE_XTHL, 0xE3); - opcodes.put(OPCODE_SPHL, 0xF9); - opcodes.put(OPCODE_PCHL, 0xE9); - opcodes.put(OPCODE_RET, 0xC9); - opcodes.put(OPCODE_RC, 0xD8); - opcodes.put(OPCODE_RNC, 0xD0); - opcodes.put(OPCODE_RZ, 0xC8); - opcodes.put(OPCODE_RNZ, 0xC0); - opcodes.put(OPCODE_RM, 0xF8); - opcodes.put(OPCODE_RP, 0xF0); - opcodes.put(OPCODE_RPE, 0xE8); - opcodes.put(OPCODE_RPO, 0xE0); - opcodes.put(OPCODE_EI, 0xFB); - opcodes.put(OPCODE_DI, 0xF3); - opcodes.put(OPCODE_HLT, 0x76); - } - - public InstrNoArgs(int line, int column, int opcode) { - super(line, column); - this.opcode = opcode; - } - - public InstrNoArgs(Token opcode) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); - } - - public byte eval() { - return (byte) (opcodes.get(opcode) & 0xFF); - } - - @Override - public void accept(NodeVisitor visitor) { - visitor.visit(this); - } - - @Override - protected String toStringShallow() { - return "InstrNoArgs(" + opcode + ")"; - } - - @Override - protected Node mkCopy() { - return new InstrNoArgs(line, column, opcode); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - InstrNoArgs that = (InstrNoArgs) o; - return opcode == that.opcode; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrReg.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR.java similarity index 64% rename from plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrReg.java rename to plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR.java index 770372b0a..d66f935da 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrReg.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR.java @@ -9,23 +9,34 @@ import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; -public class InstrReg extends Node { +public class InstrR extends Node { + // opcode=OPCODE_INC r=rRegister + // opcode=OPCODE_DEC r=rRegister + // opcode=OPCODE_ADD REG_A SEP_COMMA r=rRegister + // opcode=OPCODE_ADC REG_A SEP_COMMA r=rRegister + // opcode=OPCODE_SUB r=rRegister + // opcode=OPCODE_SBC REG_A SEP_COMMA r=rRegister + // opcode=OPCODE_AND r=rRegister + // opcode=OPCODE_XOR r=rRegister + // opcode=OPCODE_OR r=rRegister + // opcode=OPCODE_CP r=rRegister + private final static Map opcodes = new HashMap<>(); public final static Map registers = new HashMap<>(); public final int opcode; public final int reg; static { - opcodes.put(OPCODE_INR, 4); - opcodes.put(OPCODE_DCR, 5); + opcodes.put(OPCODE_INC, 4); + opcodes.put(OPCODE_DEC, 5); opcodes.put(OPCODE_ADD, 0x80); opcodes.put(OPCODE_ADC, 0x88); opcodes.put(OPCODE_SUB, 0x90); - opcodes.put(OPCODE_SBB, 0x98); - opcodes.put(OPCODE_ANA, 0xA0); - opcodes.put(OPCODE_XRA, 0xA8); - opcodes.put(OPCODE_ORA, 0xB0); - opcodes.put(OPCODE_CMP, 0xB8); + opcodes.put(OPCODE_SBC, 0x98); + opcodes.put(OPCODE_AND, 0xA0); + opcodes.put(OPCODE_XOR, 0xA8); + opcodes.put(OPCODE_OR, 0xB0); + opcodes.put(OPCODE_CP, 0xB8); registers.put(REG_A, 7); registers.put(REG_B, 0); @@ -34,23 +45,23 @@ public class InstrReg extends Node { registers.put(REG_E, 3); registers.put(REG_H, 4); registers.put(REG_L, 5); - registers.put(REG_M, 6); + registers.put(REG_HL, 6); } - public InstrReg(int line, int column, int opcode, int reg) { + public InstrR(int line, int column, int opcode, int reg) { super(line, column); this.opcode = opcode; this.reg = reg; } - public InstrReg(Token opcode, Token reg) { + public InstrR(Token opcode, Token reg) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); } public byte eval() { int result = opcodes.get(opcode); int register = registers.get(reg); - if (opcode == OPCODE_INR || opcode == OPCODE_DCR) { + if (opcode == OPCODE_INC || opcode == OPCODE_DEC) { return (byte) ((result | (register << 3)) & 0xFF); } return (byte) ((result | register) & 0xFF); @@ -68,7 +79,7 @@ protected String toStringShallow() { @Override protected Node mkCopy() { - return new InstrReg(line, column, opcode, reg); + return new InstrR(line, column, opcode, reg); } @Override @@ -76,7 +87,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - InstrReg instrReg = (InstrReg) o; + InstrR instrReg = (InstrR) o; if (opcode != instrReg.opcode) return false; return reg == instrReg.reg; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPair.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP.java similarity index 69% rename from plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPair.java rename to plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP.java index b08f4f336..b0d7a11d8 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPair.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP.java @@ -9,7 +9,13 @@ import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; -public class InstrRegPair extends Node { +public class InstrRP extends Node { + // opcode=OPCODE_INC rp=rRegPair + // opcode=OPCODE_DEC rp=rRegPair + // opcode=OPCODE_ADD REG_HL SEP_COMMA rp=rRegPair + // opcode=OPCODE_POP rp=(REG_BC|REG_DE|REG_HL|REG_AF) + // opcode=OPCODE_PUSH rp=(REG_BC|REG_DE|REG_HL|REG_AF) + private final static Map opcodes = new HashMap<>(); public final static Map regpairs = new HashMap<>(); @@ -17,28 +23,29 @@ public class InstrRegPair extends Node { public final int regPair; static { - opcodes.put(OPCODE_STAX, 2); - opcodes.put(OPCODE_LDAX, 0xA); + opcodes.put(OPCODE_INC, 3); + opcodes.put(OPCODE_DEC, 0xB); opcodes.put(OPCODE_PUSH, 0xC5); opcodes.put(OPCODE_POP, 0xC1); - opcodes.put(OPCODE_DAD, 9); - opcodes.put(OPCODE_INX, 3); - opcodes.put(OPCODE_DCX, 0xB); + +// opcodes.put(OPCODE_STAX, 2); +// opcodes.put(OPCODE_LDAX, 0xA); +// opcodes.put(OPCODE_DAD, 9); regpairs.put(REG_B, 0); regpairs.put(REG_D, 1); regpairs.put(REG_H, 2); - regpairs.put(REG_PSW, 3); + regpairs.put(REG_AF, 3); regpairs.put(REG_SP, 3); } - public InstrRegPair(int line, int column, int opcode, int regPair) { + public InstrRP(int line, int column, int opcode, int regPair) { super(line, column); this.opcode = opcode; this.regPair = regPair; } - public InstrRegPair(Token opcode, Token regPair) { + public InstrRP(Token opcode, Token regPair) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); } @@ -60,7 +67,7 @@ protected String toStringShallow() { @Override protected Node mkCopy() { - return new InstrRegPair(line, column, opcode, regPair); + return new InstrRP(line, column, opcode, regPair); } @Override @@ -68,7 +75,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - InstrRegPair that = (InstrRegPair) o; + InstrRP that = (InstrRP) o; if (opcode != that.opcode) return false; return regPair == that.regPair; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPairExpr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_NN.java similarity index 74% rename from plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPairExpr.java rename to plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_NN.java index 074b3b75e..0630f94ee 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegPairExpr.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_NN.java @@ -4,23 +4,25 @@ import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; -public class InstrRegPairExpr extends Node { +public class InstrRP_NN extends Node { + // opcode=OPCODE_LD rp=rRegPair SEP_COMMA nn=rExpression + public final int opcode; public final int regPair; - public InstrRegPairExpr(int line, int column, int opcode, int regPair) { + public InstrRP_NN(int line, int column, int opcode, int regPair) { super(line, column); this.opcode = opcode; this.regPair = regPair; // child is expr } - public InstrRegPairExpr(Token opcode, Token regPair) { + public InstrRP_NN(Token opcode, Token regPair) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); } public byte eval() { - int rp = InstrRegPair.regpairs.get(regPair); + int rp = InstrRP.regpairs.get(regPair); return (byte) ((1 | (rp << 4)) & 0xFF); } @@ -36,7 +38,7 @@ protected String toStringShallow() { @Override protected Node mkCopy() { - return new InstrRegPairExpr(line, column, opcode, regPair); + return new InstrRP_NN(line, column, opcode, regPair); } @Override @@ -44,7 +46,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - InstrRegPairExpr that = (InstrRegPairExpr) o; + InstrRP_NN that = (InstrRP_NN) o; if (opcode != that.opcode) return false; return regPair == that.regPair; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_RP.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_RP.java new file mode 100644 index 000000000..7b99fb148 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_RP.java @@ -0,0 +1,30 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import org.antlr.v4.runtime.Token; + +public class InstrRP_RP extends Node { + // opcode=OPCODE_LD dst=REG_SP SEP_COMMA src=REG_HL + // opcode=OPCODE_EX dst=REG_AF SEP_COMMA src=REG_AFF + // opcode=OPCODE_EX dst=REG_DE SEP_COMMA src=REG_HL + + public final int opcode; + public final int srcRegPair; + public final int dstRegPair; + + public InstrRP_RP(int line, int column, int opcode, int srcRegPair, int dstRegPair) { + super(line, column); + this.opcode = opcode; + this.srcRegPair = srcRegPair; + this.dstRegPair = dstRegPair; + } + + public InstrRP_RP(Token opcode, Token srcRegPair, Token dstRegPair) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), srcRegPair.getType(), dstRegPair.getType()); + } + + @Override + protected Node mkCopy() { + return new InstrRP_RP(line, column, opcode, srcRegPair, dstRegPair); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_Ref_NN.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_Ref_NN.java new file mode 100644 index 000000000..26905db1a --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_Ref_NN.java @@ -0,0 +1,27 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import org.antlr.v4.runtime.Token; + +public class InstrRP_Ref_NN extends Node { + // opcode=OPCODE_LD rp=REG_HL SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR + + public final int opcode; + public final int regPair; + + public InstrRP_Ref_NN(int line, int column, int opcode, int regPair) { + super(line, column); + this.opcode = opcode; + this.regPair = regPair; + // child is expr + } + + public InstrRP_Ref_NN(Token opcode, Token regPair) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); + } + + @Override + protected Node mkCopy() { + return new InstrRP_Ref_NN(line, column, opcode, regPair); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegExpr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_N.java similarity index 73% rename from plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegExpr.java rename to plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_N.java index 8d2de6990..8b0200054 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegExpr.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_N.java @@ -4,23 +4,25 @@ import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; -public class InstrRegExpr extends Node { - public final int opcode; // MVI only +public class InstrR_N extends Node { + // opcode=OPCODE_LD r=rRegister SEP_COMMA n=rExpression + + public final int opcode; public final int reg; - public InstrRegExpr(int line, int column, int opcode, int reg) { + public InstrR_N(int line, int column, int opcode, int reg) { super(line, column); this.opcode = opcode; this.reg = reg; // child is expr } - public InstrRegExpr(Token opcode, Token reg) { + public InstrR_N(Token opcode, Token reg) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); } public byte eval() { - int register = InstrReg.registers.get(reg); + int register = InstrR.registers.get(reg); return (byte) ((6 | (register << 3)) & 0xFF); } @@ -36,7 +38,7 @@ protected String toStringShallow() { @Override protected Node mkCopy() { - return new InstrRegExpr(line, column, opcode, reg); + return new InstrR_N(line, column, opcode, reg); } @Override @@ -44,7 +46,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - InstrRegExpr that = (InstrRegExpr) o; + InstrR_N that = (InstrR_N) o; if (opcode != that.opcode) return false; return reg == that.reg; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegReg.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_R.java similarity index 71% rename from plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegReg.java rename to plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_R.java index 820103c62..9c3bc1750 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRegReg.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_R.java @@ -4,25 +4,27 @@ import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; -public class InstrRegReg extends Node { - public final int opcode; // MOV only +public class InstrR_R extends Node { + // opcode=OPCODE_LD dst=rRegister SEP_COMMA src=rRegister + + public final int opcode; public final int srcReg; public final int dstReg; - public InstrRegReg(int line, int column, int opcode, int dst, int src) { + public InstrR_R(int line, int column, int opcode, int dst, int src) { super(line, column); this.opcode = opcode; this.srcReg = src; this.dstReg = dst; } - public InstrRegReg(Token opcode, Token dst, Token src) { + public InstrR_R(Token opcode, Token dst, Token src) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), dst.getType(), src.getType()); } public byte eval() { - int srcRegister = InstrReg.registers.get(srcReg); - int dstRegister = InstrReg.registers.get(dstReg); + int srcRegister = InstrR.registers.get(srcReg); + int dstRegister = InstrR.registers.get(dstReg); return (byte)((0x40 | (dstRegister << 3) | (srcRegister)) & 0xFF); // TODO: mov M, M == HLT } @@ -38,7 +40,7 @@ protected String toStringShallow() { @Override protected Node mkCopy() { - return new InstrRegReg(line, column, opcode, dstReg, srcReg); + return new InstrR_R(line, column, opcode, dstReg, srcReg); } @Override @@ -46,7 +48,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - InstrRegReg that = (InstrRegReg) o; + InstrR_R that = (InstrR_R) o; if (opcode != that.opcode) return false; if (srcReg != that.srcReg) return false; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_Ref_NN.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_Ref_NN.java new file mode 100644 index 000000000..23a242115 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_Ref_NN.java @@ -0,0 +1,27 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import org.antlr.v4.runtime.Token; + +public class InstrR_Ref_NN extends Node { + // opcode=OPCODE_LD r=REG_A SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR + + public final int opcode; + public final int reg; + + public InstrR_Ref_NN(int line, int column, int opcode, int reg) { + super(line, column); + this.opcode = opcode; + this.reg = reg; + // child is expr + } + + public InstrR_Ref_NN(Token opcode, Token reg) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); + } + + @Override + protected Node mkCopy() { + return new InstrR_Ref_NN(line, column, opcode, reg); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_NN_R.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_NN_R.java new file mode 100644 index 000000000..fd21bcf02 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_NN_R.java @@ -0,0 +1,28 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import org.antlr.v4.runtime.Token; + +public class InstrRef_NN_R extends Node { + // opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_A + // opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_HL + + public final int opcode; + public final int reg; + + public InstrRef_NN_R(int line, int column, int opcode, int reg) { + super(line, column); + this.opcode = opcode; + this.reg = reg; + // child is expr + } + + public InstrRef_NN_R(Token opcode, Token reg) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); + } + + @Override + protected Node mkCopy() { + return new InstrRef_NN_R(line, column, opcode, reg); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP.java new file mode 100644 index 000000000..9a1abddb4 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP.java @@ -0,0 +1,28 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import org.antlr.v4.runtime.Token; + +public class InstrRef_RP extends Node { + // opcode=OPCODE_LD SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR SEP_COMMA REG_A + // opcode=OPCODE_JP SEP_LPAR REG_HL SEP_RPAR + + + public final int opcode; + public final int regPair; + + public InstrRef_RP(int line, int column, int opcode, int regPair) { + super(line, column); + this.opcode = opcode; + this.regPair = regPair; + } + + public InstrRef_RP(Token opcode, Token regPair) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); + } + + @Override + protected Node mkCopy() { + return new InstrRef_RP(line, column, opcode, regPair); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP_RP.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP_RP.java new file mode 100644 index 000000000..d06952187 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP_RP.java @@ -0,0 +1,28 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import org.antlr.v4.runtime.Token; + +public class InstrRef_RP_RP extends Node { + // opcode=OPCODE_EX SEP_LPAR src=REG_SP SEP_RPAR SEP_COMMA dst=REG_HL + + public final int opcode; + public final int srcRegPair; + public final int dstRegPair; + + public InstrRef_RP_RP(int line, int column, int opcode, int srcRegPair, int dstRegPair) { + super(line, column); + this.opcode = opcode; + this.srcRegPair = srcRegPair; + this.dstRegPair = dstRegPair; + } + + public InstrRef_RP_RP(Token opcode, Token srcRegPair, Token dstRegPair) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), srcRegPair.getType(), dstRegPair.getType()); + } + + @Override + protected Node mkCopy() { + return new InstrRef_RP_RP(line, column, opcode, srcRegPair, dstRegPair); + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Expr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Expr.java index ea83f0a5f..2f3a0196f 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Expr.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Expr.java @@ -18,233 +18,226 @@ */ package net.emustudio.plugins.compiler.asZ80.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.CompilerException; -import net.emustudio.plugins.compiler.asZ80.exceptions.ValueOutOfBoundsException; -import net.emustudio.plugins.compiler.asZ80.exceptions.ValueTooBigException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Instruction; -public class OC_Expr extends Instruction { - public static final int ADC = 0xCE00; // ADC A,N - public static final int ADC_A_IIX_NN = 0xDD8E00; // ADC A, (IX+N) - public static final int ADC_A_IIY_NN = 0xFD8E00; // ADC A, (IY+N) - public static final int ADD = 0xC600; // ADD A,N - public static final int ADD_A_IIX_NN = 0xDD8600; // ADD A, (IX+N) - public static final int ADD_A_IIY_NN = 0xFD8600; // ADD A, (IY+N) - public static final int AND = 0xE600; // AND N - public static final int AND_IIX_NN = 0xDDA600; // AND (IX+N) - public static final int AND_IIY_NN = 0xFDA600; // AND (IY+N) - public static final int BIT = 0xCB46; // BIT b,(HL) - public static final int CALL = 0xCD0000; // CALL NN - public static final int CP = 0xFE00; // CP N - public static final int CP_IIX_NN = 0xDDBE00; // CP (IX+N) - public static final int CP_IIY_NN = 0xFDBE00; // CP (IY+N) - public static final int DEC_IIX_NN = 0xDD3500; // DEC (IX+N) - public static final int DEC_IIY_NN = 0xFD3500; // DEC (IY+N) - public static final int DJNZ = 0x1000; // DJNZ N - public static final int IM = 0xED00; // IM N - public static final int IN = 0xDB00; // IN A, (N) - public static final int INC_IIX_NN = 0xDD3400; // INC (IX+N) - public static final int INC_IIY_NN = 0xFD3400; // INC (IY+N) - public static final int JP = 0xC30000; // JP NN - public static final int JR = 0x1800; // JR N - public static final int LD_A = 0x3E00; // LD A,N - public static final int LD_A_IIX_NN = 0xDD7E00; // LD A,(IX+N) - public static final int LD_A_IIY_NN = 0xFD7E00; // LD A,(IY+N) - public static final int LD_A_NN = 0x3A0000; // LD A,(NN) - public static final int LD_B = 0x0600; // LD B,N - public static final int LD_C = 0x0E00; // LD C,N - public static final int LD_D = 0x1600; // LD D,N - public static final int LD_E = 0x1E00; // LD E,N - public static final int LD_H = 0x2600; // LD H,N - public static final int LD_L = 0x2E00; // LD L,N - public static final int LD_B_IIX_NN = 0xDD4600; // LD B,(IX+N) - public static final int LD_B_IIY_NN = 0xFD4600; // LD B,(IY+N) - public static final int LD_C_IIX_NN = 0xDD4E00; // LD C,(IX+N) - public static final int LD_C_IIY_NN = 0xFD4E00; // LD C,(IY+N) - public static final int LD_D_IIX_NN = 0xDD5600; // LD D,(IX+N) - public static final int LD_D_IIY_NN = 0xFD5600; // LD D,(IY+N) - public static final int LD_E_IIX_NN = 0xDD5E00; // LD E,(IX+N) - public static final int LD_E_IIY_NN = 0xFD5E00; // LD E,(IY+N) - public static final int LD_H_IIX_NN = 0xDD6600; // LD H,(IX+N) - public static final int LD_H_IIY_NN = 0xFD6600; // LD H,(IY+N) - public static final int LD_L_IIX_NN = 0xDD6E00; // LD L,(IX+N) - public static final int LD_L_IIY_NN = 0xFD6E00; // LD L,(IY+N) - public static final int LD_BC_NN = 0xED4B0000; // LD BC,(NN) - public static final int LD_DE_NN = 0xED5B0000; // LD DE,(NN) - public static final int LD_HL_NN = 0x2A0000; // LD HL,(NN) - public static final int LD_SP_NN = 0xED7B0000; // LD SP,(NN) - public static final int LD_IX_NN = 0xDD2A0000; // LD IX,(NN) - public static final int LD_IY_NN = 0xFD2A0000; // LD IY,(NN) - public static final int LD_IX = 0xDD210000; // LD IX,NN - public static final int LD_IY = 0xFD210000; // LD IY,NN - public static final int LD_HHLL = 0x3600; // LD (HL),N - public static final int LD_NN_A = 0x320000; // LD (NN),A - public static final int LD_NN_BC = 0xED430000; // LD (NN),BC - public static final int LD_NN_DE = 0xED530000; // LD (NN),DE - public static final int LD_NN_HL = 0x220000; // LD (NN),HL - public static final int LD_NN_SP = 0xED730000; // LD (NN),SP - public static final int LD_NN_IX = 0xDD220000; // LD (NN),IX - public static final int LD_NN_IY = 0xFD220000; // LD (NN),IY - public static final int OR = 0xF600; // OR N - public static final int OR_IIX_NN = 0xDDB600; // OR (IX+N) - public static final int OR_IIY_NN = 0xFDB600; // OR (IY+N) - public static final int OUT = 0xD300; // OUT (N),A - public static final int RES = 0xCB86; // RES b,(HL) - public static final int RL_IIX_NN = 0xDDCB0016; // RL (IX+N) - public static final int RL_IIY_NN = 0xFDCB0016; // RL (IY+N) - public static final int RLC_IIX_NN = 0xDDCB0006; // RLC (IX+N) - public static final int RLC_IIY_NN = 0xFDCB0006; // RLC (IY+N) - public static final int RR_IIX_NN = 0xDDCB001E; // RR (IX+N) - public static final int RR_IIY_NN = 0xFDCB001E; // RR (IY+N) - public static final int RRC_IIX_NN = 0xDDCB000E; // RRC (IX+N) - public static final int RRC_IIY_NN = 0xFDCB000E; // RRC (IY+N) - public static final int RST = 0xC7; - public static final int SBC = 0xDE00; // SBC A,N - public static final int SBC_A_IIX_NN = 0xDD9E00; // SBC A,(IX+N) - public static final int SBC_A_IIY_NN = 0xFD9E00; // SBC A,(IY+N) - public static final int SET = 0xCBC6; // SET b,(HL) - public static final int SLA_IIX_NN = 0xDDCB0026; // SLA (IX+N) - public static final int SLA_IIY_NN = 0xFDCB0026; // SLA (IY+N) - public static final int SRA_IIX_NN = 0xDDCB002E; // SRA (IX+N) - public static final int SRA_IIY_NN = 0xFDCB002E; // SRA (IY+N) - public static final int SLL_IIX_NN = 0xDDCB0036; // SLL (IX+N) - public static final int SLL_IIY_NN = 0xFDCB0036; // SLL (IY+N) - public static final int SRL_IIX_NN = 0xDDCB003E; // SRL (IX+N) - public static final int SRL_IIY_NN = 0xFDCB003E; // SRL (IY+N) - public static final int SUB = 0xD600; // SUB N - public static final int SUB_IIX_NN = 0xDD9600; // SUB (IX+N) - public static final int SUB_IIY_NN = 0xFD9600; // SUB (IY+N) - public static final int XOR = 0xEE00; // XOR N - public static final int XOR_IIX_NN = 0xDDAE00; // XOR (IX+N) - public static final int XOR_IIY_NN = 0xFDAE00; // XOR (IY+N) - - private final Expression expr; - private final boolean oneByte; - private final int old_opcode; - - public OC_Expr(int opcode, Expression expr, boolean oneByte, int line, int column) { - super(opcode, line, column); - this.old_opcode = opcode; - this.expr = expr; - this.oneByte = oneByte; - } - - @Override - public void pass1() { - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - expr.eval(parentEnv, addr_start); - int val = expr.getValue(); - - opcode = old_opcode; - switch (opcode) { - case DJNZ: - case JR: - opcode += computeRelativeAddress(line, column, addr_start, val); - break; - case BIT: - case RES: - case SET: - if ((val > 7) || (val < 0)) { - throw new ValueOutOfBoundsException(line, column, 0, 7, val); - } - opcode += (8 * val); - break; - case IM: - switch (val) { - case 0: - opcode += 0x46; - break; - case 1: - opcode += 0x56; - break; - case 2: - opcode += 0x5E; - break; - default: - throw new CompilerException(line, column, "Error: value can be only 0,1 or 2"); - } - break; - case RL_IIX_NN: - case RL_IIY_NN: - case RLC_IIX_NN: - case RLC_IIY_NN: - case RR_IIX_NN: - case RR_IIY_NN: - case RRC_IIX_NN: - case RRC_IIY_NN: - case SLA_IIX_NN: - case SLA_IIY_NN: - case SRA_IIX_NN: - case SRA_IIY_NN: - case SLL_IIX_NN: - case SLL_IIY_NN: - case SRL_IIX_NN: - case SRL_IIY_NN: - if (oneByte && (val & 0xFFF) > 0xFF) { - throw new ValueTooBigException(line, column, val, 0xFF); - } - opcode += ((val << 8) & 0xFF00); - break; - case RST: - switch (val) { - case 0: - break; - case 8: - opcode = 0xCF; - break; - case 0x10: - opcode = 0xD7; - break; - case 0x18: - opcode = 0xDF; - break; - case 0x20: - opcode = 0xE7; - break; - case 0x28: - opcode = 0xEF; - break; - case 0x30: - opcode = 0xF7; - break; - case 0x38: - opcode = 0xFF; - break; - default: - throw new CompilerException(line, column, " Error: value can be only 0,8h,10h,18h,20h,28h,30h or 38h"); - } - break; - default: - if (oneByte) { - if ((val & 0xFFF) > 0xFF) { - throw new ValueTooBigException(line, column, val, 0xFF); - } - opcode += Expression.reverseBytes(val, 1); - } else { - opcode += Expression.reverseBytes(val, 2); - } - } - return (addr_start + getSize()); - } - - @Override - public void generateCode(IntelHEX hex) { - String s; - if (getSize() == 1) { - s = "%1$02X"; - } else if (getSize() == 2) { - s = "%1$04X"; - } else if (getSize() == 3) { - s = "%1$06X"; - } else { - s = "%1$08X"; - } - hex.putCode(String.format(s, opcode)); - } +public class OC_Expr { +// public static final int ADC = 0xCE00; // ADC A,N +// public static final int ADC_A_IIX_NN = 0xDD8E00; // ADC A, (IX+N) +// public static final int ADC_A_IIY_NN = 0xFD8E00; // ADC A, (IY+N) +// public static final int ADD = 0xC600; // ADD A,N +// public static final int ADD_A_IIX_NN = 0xDD8600; // ADD A, (IX+N) +// public static final int ADD_A_IIY_NN = 0xFD8600; // ADD A, (IY+N) +// public static final int AND = 0xE600; // AND N +// public static final int AND_IIX_NN = 0xDDA600; // AND (IX+N) +// public static final int AND_IIY_NN = 0xFDA600; // AND (IY+N) +// public static final int BIT = 0xCB46; // BIT b,(HL) +// public static final int CALL = 0xCD0000; // CALL NN +// public static final int CP = 0xFE00; // CP N +// public static final int CP_IIX_NN = 0xDDBE00; // CP (IX+N) +// public static final int CP_IIY_NN = 0xFDBE00; // CP (IY+N) +// public static final int DEC_IIX_NN = 0xDD3500; // DEC (IX+N) +// public static final int DEC_IIY_NN = 0xFD3500; // DEC (IY+N) +// public static final int DJNZ = 0x1000; // DJNZ N +// public static final int IM = 0xED00; // IM N +// public static final int IN = 0xDB00; // IN A, (N) +// public static final int INC_IIX_NN = 0xDD3400; // INC (IX+N) +// public static final int INC_IIY_NN = 0xFD3400; // INC (IY+N) +// public static final int JP = 0xC30000; // JP NN +// public static final int JR = 0x1800; // JR N +// public static final int LD_A = 0x3E00; // LD A,N +// public static final int LD_A_IIX_NN = 0xDD7E00; // LD A,(IX+N) +// public static final int LD_A_IIY_NN = 0xFD7E00; // LD A,(IY+N) +// public static final int LD_A_NN = 0x3A0000; // LD A,(NN) +// public static final int LD_B = 0x0600; // LD B,N +// public static final int LD_C = 0x0E00; // LD C,N +// public static final int LD_D = 0x1600; // LD D,N +// public static final int LD_E = 0x1E00; // LD E,N +// public static final int LD_H = 0x2600; // LD H,N +// public static final int LD_L = 0x2E00; // LD L,N +// public static final int LD_B_IIX_NN = 0xDD4600; // LD B,(IX+N) +// public static final int LD_B_IIY_NN = 0xFD4600; // LD B,(IY+N) +// public static final int LD_C_IIX_NN = 0xDD4E00; // LD C,(IX+N) +// public static final int LD_C_IIY_NN = 0xFD4E00; // LD C,(IY+N) +// public static final int LD_D_IIX_NN = 0xDD5600; // LD D,(IX+N) +// public static final int LD_D_IIY_NN = 0xFD5600; // LD D,(IY+N) +// public static final int LD_E_IIX_NN = 0xDD5E00; // LD E,(IX+N) +// public static final int LD_E_IIY_NN = 0xFD5E00; // LD E,(IY+N) +// public static final int LD_H_IIX_NN = 0xDD6600; // LD H,(IX+N) +// public static final int LD_H_IIY_NN = 0xFD6600; // LD H,(IY+N) +// public static final int LD_L_IIX_NN = 0xDD6E00; // LD L,(IX+N) +// public static final int LD_L_IIY_NN = 0xFD6E00; // LD L,(IY+N) +// public static final int LD_BC_NN = 0xED4B0000; // LD BC,(NN) +// public static final int LD_DE_NN = 0xED5B0000; // LD DE,(NN) +// public static final int LD_HL_NN = 0x2A0000; // LD HL,(NN) +// public static final int LD_SP_NN = 0xED7B0000; // LD SP,(NN) +// public static final int LD_IX_NN = 0xDD2A0000; // LD IX,(NN) +// public static final int LD_IY_NN = 0xFD2A0000; // LD IY,(NN) +// public static final int LD_IX = 0xDD210000; // LD IX,NN +// public static final int LD_IY = 0xFD210000; // LD IY,NN +// public static final int LD_HHLL = 0x3600; // LD (HL),N +// public static final int LD_NN_A = 0x320000; // LD (NN),A +// public static final int LD_NN_BC = 0xED430000; // LD (NN),BC +// public static final int LD_NN_DE = 0xED530000; // LD (NN),DE +// public static final int LD_NN_HL = 0x220000; // LD (NN),HL +// public static final int LD_NN_SP = 0xED730000; // LD (NN),SP +// public static final int LD_NN_IX = 0xDD220000; // LD (NN),IX +// public static final int LD_NN_IY = 0xFD220000; // LD (NN),IY +// public static final int OR = 0xF600; // OR N +// public static final int OR_IIX_NN = 0xDDB600; // OR (IX+N) +// public static final int OR_IIY_NN = 0xFDB600; // OR (IY+N) +// public static final int OUT = 0xD300; // OUT (N),A +// public static final int RES = 0xCB86; // RES b,(HL) +// public static final int RL_IIX_NN = 0xDDCB0016; // RL (IX+N) +// public static final int RL_IIY_NN = 0xFDCB0016; // RL (IY+N) +// public static final int RLC_IIX_NN = 0xDDCB0006; // RLC (IX+N) +// public static final int RLC_IIY_NN = 0xFDCB0006; // RLC (IY+N) +// public static final int RR_IIX_NN = 0xDDCB001E; // RR (IX+N) +// public static final int RR_IIY_NN = 0xFDCB001E; // RR (IY+N) +// public static final int RRC_IIX_NN = 0xDDCB000E; // RRC (IX+N) +// public static final int RRC_IIY_NN = 0xFDCB000E; // RRC (IY+N) +// public static final int RST = 0xC7; +// public static final int SBC = 0xDE00; // SBC A,N +// public static final int SBC_A_IIX_NN = 0xDD9E00; // SBC A,(IX+N) +// public static final int SBC_A_IIY_NN = 0xFD9E00; // SBC A,(IY+N) +// public static final int SET = 0xCBC6; // SET b,(HL) +// public static final int SLA_IIX_NN = 0xDDCB0026; // SLA (IX+N) +// public static final int SLA_IIY_NN = 0xFDCB0026; // SLA (IY+N) +// public static final int SRA_IIX_NN = 0xDDCB002E; // SRA (IX+N) +// public static final int SRA_IIY_NN = 0xFDCB002E; // SRA (IY+N) +// public static final int SLL_IIX_NN = 0xDDCB0036; // SLL (IX+N) +// public static final int SLL_IIY_NN = 0xFDCB0036; // SLL (IY+N) +// public static final int SRL_IIX_NN = 0xDDCB003E; // SRL (IX+N) +// public static final int SRL_IIY_NN = 0xFDCB003E; // SRL (IY+N) +// public static final int SUB = 0xD600; // SUB N +// public static final int SUB_IIX_NN = 0xDD9600; // SUB (IX+N) +// public static final int SUB_IIY_NN = 0xFD9600; // SUB (IY+N) +// public static final int XOR = 0xEE00; // XOR N +// public static final int XOR_IIX_NN = 0xDDAE00; // XOR (IX+N) +// public static final int XOR_IIY_NN = 0xFDAE00; // XOR (IY+N) +// +// private final Expression expr; +// private final boolean oneByte; +// private final int old_opcode; +// +// public OC_Expr(int opcode, Expression expr, boolean oneByte, int line, int column) { +// super(opcode, line, column); +// this.old_opcode = opcode; +// this.expr = expr; +// this.oneByte = oneByte; +// } +// +// @Override +// public void pass1() { +// } +// +// @Override +// public int pass2(Namespace parentEnv, int addr_start) throws Exception { +// expr.eval(parentEnv, addr_start); +// int val = expr.getValue(); +// +// opcode = old_opcode; +// switch (opcode) { +// case DJNZ: +// case JR: +// opcode += computeRelativeAddress(line, column, addr_start, val); +// break; +// case BIT: +// case RES: +// case SET: +// if ((val > 7) || (val < 0)) { +// throw new ValueOutOfBoundsException(line, column, 0, 7, val); +// } +// opcode += (8 * val); +// break; +// case IM: +// switch (val) { +// case 0: +// opcode += 0x46; +// break; +// case 1: +// opcode += 0x56; +// break; +// case 2: +// opcode += 0x5E; +// break; +// default: +// throw new CompilerException(line, column, "Error: value can be only 0,1 or 2"); +// } +// break; +// case RL_IIX_NN: +// case RL_IIY_NN: +// case RLC_IIX_NN: +// case RLC_IIY_NN: +// case RR_IIX_NN: +// case RR_IIY_NN: +// case RRC_IIX_NN: +// case RRC_IIY_NN: +// case SLA_IIX_NN: +// case SLA_IIY_NN: +// case SRA_IIX_NN: +// case SRA_IIY_NN: +// case SLL_IIX_NN: +// case SLL_IIY_NN: +// case SRL_IIX_NN: +// case SRL_IIY_NN: +// if (oneByte && (val & 0xFFF) > 0xFF) { +// throw new ValueTooBigException(line, column, val, 0xFF); +// } +// opcode += ((val << 8) & 0xFF00); +// break; +// case RST: +// switch (val) { +// case 0: +// break; +// case 8: +// opcode = 0xCF; +// break; +// case 0x10: +// opcode = 0xD7; +// break; +// case 0x18: +// opcode = 0xDF; +// break; +// case 0x20: +// opcode = 0xE7; +// break; +// case 0x28: +// opcode = 0xEF; +// break; +// case 0x30: +// opcode = 0xF7; +// break; +// case 0x38: +// opcode = 0xFF; +// break; +// default: +// throw new CompilerException(line, column, " Error: value can be only 0,8h,10h,18h,20h,28h,30h or 38h"); +// } +// break; +// default: +// if (oneByte) { +// if ((val & 0xFFF) > 0xFF) { +// throw new ValueTooBigException(line, column, val, 0xFF); +// } +// opcode += Expression.reverseBytes(val, 1); +// } else { +// opcode += Expression.reverseBytes(val, 2); +// } +// } +// return (addr_start + getSize()); +// } +// +// @Override +// public void generateCode(IntelHEX hex) { +// String s; +// if (getSize() == 1) { +// s = "%1$02X"; +// } else if (getSize() == 2) { +// s = "%1$04X"; +// } else if (getSize() == 3) { +// s = "%1$06X"; +// } else { +// s = "%1$08X"; +// } +// hex.putCode(String.format(s, opcode)); +// } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_ExprExpr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_ExprExpr.java index 9900aed9d..9a66104ba 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_ExprExpr.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_ExprExpr.java @@ -18,76 +18,70 @@ */ package net.emustudio.plugins.compiler.asZ80.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.CompilerException; -import net.emustudio.plugins.compiler.asZ80.exceptions.ValueTooBigException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Instruction; -public class OC_ExprExpr extends Instruction { - public static final int LD_IIX_NN = 0xDD360000; // LD (IX+N),N - public static final int LD_IIY_NN = 0xFD360000; // LD (IY+N),N - public static final int BIT_IIX_NN = 0xDDCB0046; // BIT b,(IIX+N) - public static final int BIT_IIY_NN = 0xFDCB0046; // BIT b,(IIY+N) - public static final int RES_IIX_NN = 0xDDCB0086; // RES b,(IIX+N) - public static final int RES_IIY_NN = 0xFDCB0086; // RES b,(IIY+N) - public static final int SET_IIX_NN = 0xDDCB00C6; // SET b,(IIX+N) - public static final int SET_IIY_NN = 0xFDCB00C6; // SET b,(IIY+N) - private Expression e1; - private Expression e2; - private boolean bitInstr; - private int old_opcode; - - public OC_ExprExpr(int opcode, Expression e1, Expression e2, boolean bitInstr, int line, int column) { - super(opcode, line, column); - this.e1 = e1; - this.e2 = e2; - this.bitInstr = bitInstr; - this.old_opcode = opcode; - } - - @Override - public void pass1() { - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - e1.eval(parentEnv, addr_start); - e2.eval(parentEnv, addr_start); - - int val1 = e1.getValue(); - int val2 = e2.getValue(); - if (Expression.getSize(val1) > 1) { - throw new ValueTooBigException(line, column, val1, 0xFF); - } - if (Expression.getSize(val2) > 1) { - throw new ValueTooBigException(line, column, val2, 0xFF); - } - opcode = old_opcode; - if (bitInstr) { - if ((val1 > 7) || (val1 < 0)) { - throw new CompilerException(line, column, "Error: value(1) can be only in range 0-7"); - } - opcode += (val2 << 8) + (8 * val1); - } else { - opcode += ((val1 << 8) + val2); - } - return (addr_start + getSize()); - } - - @Override - public void generateCode(IntelHEX hex) { - String s; - if (getSize() == 1) { - s = "%1$02X"; - } else if (getSize() == 2) { - s = "%1$04X"; - } else if (getSize() == 3) { - s = "%1$06X"; - } else { - s = "%1$08X"; - } - hex.putCode(String.format(s, opcode)); - } +public class OC_ExprExpr { +// public static final int LD_IIX_NN = 0xDD360000; // LD (IX+N),N +// public static final int LD_IIY_NN = 0xFD360000; // LD (IY+N),N +// public static final int BIT_IIX_NN = 0xDDCB0046; // BIT b,(IIX+N) +// public static final int BIT_IIY_NN = 0xFDCB0046; // BIT b,(IIY+N) +// public static final int RES_IIX_NN = 0xDDCB0086; // RES b,(IIX+N) +// public static final int RES_IIY_NN = 0xFDCB0086; // RES b,(IIY+N) +// public static final int SET_IIX_NN = 0xDDCB00C6; // SET b,(IIX+N) +// public static final int SET_IIY_NN = 0xFDCB00C6; // SET b,(IIY+N) +// private Expression e1; +// private Expression e2; +// private boolean bitInstr; +// private int old_opcode; +// +// public OC_ExprExpr(int opcode, Expression e1, Expression e2, boolean bitInstr, int line, int column) { +// super(opcode, line, column); +// this.e1 = e1; +// this.e2 = e2; +// this.bitInstr = bitInstr; +// this.old_opcode = opcode; +// } +// +// @Override +// public void pass1() { +// } +// +// @Override +// public int pass2(Namespace parentEnv, int addr_start) throws Exception { +// e1.eval(parentEnv, addr_start); +// e2.eval(parentEnv, addr_start); +// +// int val1 = e1.getValue(); +// int val2 = e2.getValue(); +// if (Expression.getSize(val1) > 1) { +// throw new ValueTooBigException(line, column, val1, 0xFF); +// } +// if (Expression.getSize(val2) > 1) { +// throw new ValueTooBigException(line, column, val2, 0xFF); +// } +// opcode = old_opcode; +// if (bitInstr) { +// if ((val1 > 7) || (val1 < 0)) { +// throw new CompilerException(line, column, "Error: value(1) can be only in range 0-7"); +// } +// opcode += (val2 << 8) + (8 * val1); +// } else { +// opcode += ((val1 << 8) + val2); +// } +// return (addr_start + getSize()); +// } +// +// @Override +// public void generateCode(IntelHEX hex) { +// String s; +// if (getSize() == 1) { +// s = "%1$02X"; +// } else if (getSize() == 2) { +// s = "%1$04X"; +// } else if (getSize() == 3) { +// s = "%1$06X"; +// } else { +// s = "%1$08X"; +// } +// hex.putCode(String.format(s, opcode)); +// } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_NoParams.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_NoParams.java index be4614a17..8a7d643c2 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_NoParams.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_NoParams.java @@ -18,144 +18,141 @@ */ package net.emustudio.plugins.compiler.asZ80.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Instruction; -public class OC_NoParams extends Instruction { - public static final int ADC_A_HHLL = 0x8E; - public static final int ADD_A_HHLL = 0x86; - public static final int AND_HHLL = 0xA6; - public static final int CCF = 0x3F; - public static final int CP_HHLL = 0xBE; - public static final int CPD = 0xEDA9; - public static final int CPDR = 0xEDB9; - public static final int CPI = 0xEDA1; - public static final int CPIR = 0xEDB1; - public static final int CPL = 0x2F; - public static final int DAA = 0x27; - public static final int DEC = 0x0B; - public static final int DEC_A = 0x3D; - public static final int DEC_B = 0x05; - public static final int DEC_C = 0x0D; - public static final int DEC_D = 0x15; - public static final int DEC_E = 0x1D; - public static final int DEC_H = 0x25; - public static final int DEC_L = 0x2D; - public static final int DEC_HHLL = 0x35; - public static final int DEC_IX = 0xDD2B; - public static final int DEC_IY = 0xFD2B; - public static final int DI = 0xF3; - public static final int EI = 0xFB; - public static final int EX_SSPP_HL = 0xE3; - public static final int EX_SSPP_IX = 0xDDE3; - public static final int EX_SSPP_IY = 0xFDE3; - public static final int EX_AF_AFF = 0x08; - public static final int EX_DDEE_HL = 0xEB; - public static final int EXX = 0xD9; - public static final int HALT = 0x76; - public static final int IN_A = 0xED78; - public static final int IN_B = 0xED40; - public static final int IN_C = 0xED48; - public static final int IN_D = 0xED50; - public static final int IN_E = 0xED58; - public static final int IN_H = 0xED60; - public static final int IN_L = 0xED68; - public static final int INC_A = 0x3C; - public static final int INC_B = 0x04; - public static final int INC_C = 0x0C; - public static final int INC_D = 0x14; - public static final int INC_E = 0x1C; - public static final int INC_H = 0x24; - public static final int INC_L = 0x2C; - public static final int INC_IX = 0xDD23; - public static final int INC_IY = 0xFD23; - public static final int INC_HHLL = 0x34; - public static final int IND = 0xEDAA; - public static final int INDR = 0xEDBA; - public static final int INI = 0xEDA2; - public static final int INIR = 0xEDB2; - public static final int JP_HHLL = 0xE9; - public static final int JP_IIXX = 0xDDE9; - public static final int JP_IIYY = 0xFDE9; - public static final int LD_I = 0xED47; // LD I,A - public static final int LD_R = 0xED4F; // LD R,A - public static final int LD_A_I = 0xED57; // LD A,I - public static final int LD_A_R = 0xED5F; // LD A,R - public static final int LD_A_BBCC = 0x0A; - public static final int LD_A_DDEE = 0x1A; - public static final int LD_A_HHLL = 0x7E; - public static final int LD_B_HHLL = 0x46; - public static final int LD_C_HHLL = 0x4E; - public static final int LD_D_HHLL = 0x56; - public static final int LD_E_HHLL = 0x5E; - public static final int LD_H_HHLL = 0x66; - public static final int LD_L_HHLL = 0x6E; - public static final int LD_SP_HL = 0xF9; - public static final int LD_SP_IX = 0xDDF9; - public static final int LD_SP_IY = 0xFDF9; - public static final int LD_BBCC_A = 0x02; - public static final int LD_DDEE_A = 0x12; - public static final int LDD = 0xEDA8; - public static final int LDDR = 0xEDB8; - public static final int LDI = 0xA0; - public static final int LDIR = 0xB0; - public static final int NEG = 0xED44; - public static final int NOP = 0; - public static final int OR_HHLL = 0xB6; - public static final int OTDR = 0xEDBB; - public static final int OTIR = 0xEDB3; - public static final int OUT_A = 0xED79; - public static final int OUT_B = 0xED41; - public static final int OUT_C = 0xED49; - public static final int OUT_D = 0xED51; - public static final int OUT_E = 0xED59; - public static final int OUT_H = 0xED61; - public static final int OUT_L = 0xED69; - public static final int OUTD = 0xEDAB; - public static final int OUTI = 0xEDA3; - public static final int POP_IX = 0xDDE1; - public static final int POP_IY = 0xFDE1; - public static final int PUSH_IX = 0xDDE5; - public static final int PUSH_IY = 0xFDE5; - public static final int RET = 0xC9; - public static final int RETI = 0xED4D; - public static final int RETN = 0xED45; - public static final int RL_HHLL = 0xCB16; - public static final int RLA = 0x17; - public static final int RLC_HHLL = 0xCB06; - public static final int RLCA = 0x7; - public static final int RLD = 0xED6F; - public static final int RR_HHLL = 0xCB1E; - public static final int RRA = 0x1F; - public static final int RRC_HHLL = 0xCB0E; - public static final int RRCA = 0x0F; - public static final int RRD = 0xED67; - public static final int SBC_A_HHLL = 0x9E; - public static final int SCF = 0x37; - public static final int SLA_HHLL = 0xCB26; - public static final int SRA_HHLL = 0xCB2E; - public static final int SLL_HHLL = 0xCB36; - public static final int SRL_HHLL = 0xCB3E; - public static final int SUB_HHLL = 0x96; - public static final int XOR_HHLL = 0xAE; - - public OC_NoParams(int opcode, int line, int column) { - super(opcode, line, column); - } - - @Override - public void pass1() { - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) { - return addr_start + getSize(); - } - - @Override - public void generateCode(IntelHEX hex) { - String s = (getSize() == 1) ? "%1$02X" : "%1$04X"; - hex.putCode(String.format(s, opcode)); - } +public class OC_NoParams { +// public static final int ADC_A_HHLL = 0x8E; +// public static final int ADD_A_HHLL = 0x86; +// public static final int AND_HHLL = 0xA6; +// public static final int CCF = 0x3F; +// public static final int CP_HHLL = 0xBE; +// public static final int CPD = 0xEDA9; +// public static final int CPDR = 0xEDB9; +// public static final int CPI = 0xEDA1; +// public static final int CPIR = 0xEDB1; +// public static final int CPL = 0x2F; +// public static final int DAA = 0x27; +// public static final int DEC = 0x0B; +// public static final int DEC_A = 0x3D; +// public static final int DEC_B = 0x05; +// public static final int DEC_C = 0x0D; +// public static final int DEC_D = 0x15; +// public static final int DEC_E = 0x1D; +// public static final int DEC_H = 0x25; +// public static final int DEC_L = 0x2D; +// public static final int DEC_HHLL = 0x35; +// public static final int DEC_IX = 0xDD2B; +// public static final int DEC_IY = 0xFD2B; +// public static final int DI = 0xF3; +// public static final int EI = 0xFB; +// public static final int EX_SSPP_HL = 0xE3; +// public static final int EX_SSPP_IX = 0xDDE3; +// public static final int EX_SSPP_IY = 0xFDE3; +// public static final int EX_AF_AFF = 0x08; +// public static final int EX_DDEE_HL = 0xEB; +// public static final int EXX = 0xD9; +// public static final int HALT = 0x76; +// public static final int IN_A = 0xED78; +// public static final int IN_B = 0xED40; +// public static final int IN_C = 0xED48; +// public static final int IN_D = 0xED50; +// public static final int IN_E = 0xED58; +// public static final int IN_H = 0xED60; +// public static final int IN_L = 0xED68; +// public static final int INC_A = 0x3C; +// public static final int INC_B = 0x04; +// public static final int INC_C = 0x0C; +// public static final int INC_D = 0x14; +// public static final int INC_E = 0x1C; +// public static final int INC_H = 0x24; +// public static final int INC_L = 0x2C; +// public static final int INC_IX = 0xDD23; +// public static final int INC_IY = 0xFD23; +// public static final int INC_HHLL = 0x34; +// public static final int IND = 0xEDAA; +// public static final int INDR = 0xEDBA; +// public static final int INI = 0xEDA2; +// public static final int INIR = 0xEDB2; +// public static final int JP_HHLL = 0xE9; +// public static final int JP_IIXX = 0xDDE9; +// public static final int JP_IIYY = 0xFDE9; +// public static final int LD_I = 0xED47; // LD I,A +// public static final int LD_R = 0xED4F; // LD R,A +// public static final int LD_A_I = 0xED57; // LD A,I +// public static final int LD_A_R = 0xED5F; // LD A,R +// public static final int LD_A_BBCC = 0x0A; +// public static final int LD_A_DDEE = 0x1A; +// public static final int LD_A_HHLL = 0x7E; +// public static final int LD_B_HHLL = 0x46; +// public static final int LD_C_HHLL = 0x4E; +// public static final int LD_D_HHLL = 0x56; +// public static final int LD_E_HHLL = 0x5E; +// public static final int LD_H_HHLL = 0x66; +// public static final int LD_L_HHLL = 0x6E; +// public static final int LD_SP_HL = 0xF9; +// public static final int LD_SP_IX = 0xDDF9; +// public static final int LD_SP_IY = 0xFDF9; +// public static final int LD_BBCC_A = 0x02; +// public static final int LD_DDEE_A = 0x12; +// public static final int LDD = 0xEDA8; +// public static final int LDDR = 0xEDB8; +// public static final int LDI = 0xA0; +// public static final int LDIR = 0xB0; +// public static final int NEG = 0xED44; +// public static final int NOP = 0; +// public static final int OR_HHLL = 0xB6; +// public static final int OTDR = 0xEDBB; +// public static final int OTIR = 0xEDB3; +// public static final int OUT_A = 0xED79; +// public static final int OUT_B = 0xED41; +// public static final int OUT_C = 0xED49; +// public static final int OUT_D = 0xED51; +// public static final int OUT_E = 0xED59; +// public static final int OUT_H = 0xED61; +// public static final int OUT_L = 0xED69; +// public static final int OUTD = 0xEDAB; +// public static final int OUTI = 0xEDA3; +// public static final int POP_IX = 0xDDE1; +// public static final int POP_IY = 0xFDE1; +// public static final int PUSH_IX = 0xDDE5; +// public static final int PUSH_IY = 0xFDE5; +// public static final int RET = 0xC9; +// public static final int RETI = 0xED4D; +// public static final int RETN = 0xED45; +// public static final int RL_HHLL = 0xCB16; +// public static final int RLA = 0x17; +// public static final int RLC_HHLL = 0xCB06; +// public static final int RLCA = 0x7; +// public static final int RLD = 0xED6F; +// public static final int RR_HHLL = 0xCB1E; +// public static final int RRA = 0x1F; +// public static final int RRC_HHLL = 0xCB0E; +// public static final int RRCA = 0x0F; +// public static final int RRD = 0xED67; +// public static final int SBC_A_HHLL = 0x9E; +// public static final int SCF = 0x37; +// public static final int SLA_HHLL = 0xCB26; +// public static final int SRA_HHLL = 0xCB2E; +// public static final int SLL_HHLL = 0xCB36; +// public static final int SRL_HHLL = 0xCB3E; +// public static final int SUB_HHLL = 0x96; +// public static final int XOR_HHLL = 0xAE; +// +// public OC_NoParams(int opcode, int line, int column) { +// super(opcode, line, column); +// } +// +// @Override +// public void pass1() { +// } +// +// @Override +// public int pass2(Namespace parentEnv, int addr_start) { +// return addr_start + getSize(); +// } +// +// @Override +// public void generateCode(IntelHEX hex) { +// String s = (getSize() == 1) ? "%1$02X" : "%1$04X"; +// hex.putCode(String.format(s, opcode)); +// } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Reg.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Reg.java index 95612d3ad..f622ab46c 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Reg.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Reg.java @@ -18,62 +18,59 @@ */ package net.emustudio.plugins.compiler.asZ80.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Instruction; -public class OC_Reg extends Instruction { - public static final int ADC = 0x88; //ADC A,r - public static final int ADC_HL = 0xED4A; //ADC HL,rr - public static final int ADD = 0x80; //ADD A,r - public static final int ADD_HL = 0x09; //ADD HL,rr - public static final int ADD_IX = 0xDD09; //ADD IX,rx - public static final int ADD_IY = 0xFD09; //ADD IY,ry - public static final int AND = 0xA0; //AND r - public static final int CP = 0xB8; //CP r - public static final int DEC = 0x0B; // DEC rr - public static final int INC = 0x03; // INC rr - public static final int LD_A = 0x78; //LD A,r - public static final int LD_B = 0x40; //LD B,r - public static final int LD_C = 0x48; //LD C,r - public static final int LD_D = 0x50; //LD D,r - public static final int LD_E = 0x58; //LD E,r - public static final int LD_H = 0x60; //LD H,r - public static final int LD_L = 0x68; //LD L,r - public static final int LD_HHLL_r = 0x70; //LD (HL),r - public static final int OR = 0xB0; // OR r - public static final int POP = 0xC1; // POP qq - public static final int PUSH = 0xC5; // PUSH qq - public static final int RET = 0xC0; // RET cc - public static final int RL = 0xCB10; // RL r - public static final int RLC = 0xCB00; // RLC r - public static final int RR = 0xCB18; // RR r - public static final int RRC = 0xCB08; // RRC r - public static final int SBC = 0x98; // SBC r - public static final int SBC_HL = 0xED42; // SBC HL, rr - public static final int SLA = 0xCB20; // SLA r - public static final int SRA = 0xCB28; // SRA r - public static final int SLL = 0xCB30; // SLL r - public static final int SRL = 0xCB38; // SRL r - public static final int SUB = 0x90; // SUB r - public static final int XOR = 0xA8; // XOR r - - public OC_Reg(int opcode, int reg, int line, int column) { - super(opcode + reg, line, column); - } - - @Override - public void pass1() { - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) { - return addr_start + getSize(); - } - - @Override - public void generateCode(IntelHEX hex) { - String s = (getSize() == 1) ? "%1$02X" : "%1$04X"; - hex.putCode(String.format(s, opcode)); - } +public class OC_Reg { +// public static final int ADC = 0x88; //ADC A,r +// public static final int ADC_HL = 0xED4A; //ADC HL,rr +// public static final int ADD = 0x80; //ADD A,r +// public static final int ADD_HL = 0x09; //ADD HL,rr +// public static final int ADD_IX = 0xDD09; //ADD IX,rx +// public static final int ADD_IY = 0xFD09; //ADD IY,ry +// public static final int AND = 0xA0; //AND r +// public static final int CP = 0xB8; //CP r +// public static final int DEC = 0x0B; // DEC rr +// public static final int INC = 0x03; // INC rr +// public static final int LD_A = 0x78; //LD A,r +// public static final int LD_B = 0x40; //LD B,r +// public static final int LD_C = 0x48; //LD C,r +// public static final int LD_D = 0x50; //LD D,r +// public static final int LD_E = 0x58; //LD E,r +// public static final int LD_H = 0x60; //LD H,r +// public static final int LD_L = 0x68; //LD L,r +// public static final int LD_HHLL_r = 0x70; //LD (HL),r +// public static final int OR = 0xB0; // OR r +// public static final int POP = 0xC1; // POP qq +// public static final int PUSH = 0xC5; // PUSH qq +// public static final int RET = 0xC0; // RET cc +// public static final int RL = 0xCB10; // RL r +// public static final int RLC = 0xCB00; // RLC r +// public static final int RR = 0xCB18; // RR r +// public static final int RRC = 0xCB08; // RRC r +// public static final int SBC = 0x98; // SBC r +// public static final int SBC_HL = 0xED42; // SBC HL, rr +// public static final int SLA = 0xCB20; // SLA r +// public static final int SRA = 0xCB28; // SRA r +// public static final int SLL = 0xCB30; // SLL r +// public static final int SRL = 0xCB38; // SRL r +// public static final int SUB = 0x90; // SUB r +// public static final int XOR = 0xA8; // XOR r +// +// public OC_Reg(int opcode, int reg, int line, int column) { +// super(opcode + reg, line, column); +// } +// +// @Override +// public void pass1() { +// } +// +// @Override +// public int pass2(Namespace parentEnv, int addr_start) { +// return addr_start + getSize(); +// } +// +// @Override +// public void generateCode(IntelHEX hex) { +// String s = (getSize() == 1) ? "%1$02X" : "%1$04X"; +// hex.putCode(String.format(s, opcode)); +// } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_RegExpr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_RegExpr.java index 5dad18ae3..9563453a3 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_RegExpr.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_RegExpr.java @@ -18,101 +18,95 @@ */ package net.emustudio.plugins.compiler.asZ80.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.Namespace; -import net.emustudio.plugins.compiler.asZ80.exceptions.ValueOutOfBoundsException; -import net.emustudio.plugins.compiler.asZ80.exceptions.ValueTooBigException; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Expression; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.Instruction; /** * opcode = (first_byte+reg) expr */ -public class OC_RegExpr extends Instruction { - public static final int CALL = 0xC40000; // CALL cc,NN - public static final int JP = 0xC20000; // JP cc,NN - public static final int JR = 0x2000; // JR cc,N - public static final int LD_IIX_NN = 0xDD7000; // LD (IX+N),r - public static final int LD_IIY_NN = 0xFD7000; // LD (IY+N),r - public static final int LD_RR = 0x010000; // LD rr,NN - public static final int BIT = 0xCB40; // BIT b,r - public static final int RES = 0xCB80; // RES b,r - public static final int SET = 0xCBC0; // SET b,r - - private final Expression expr; - private final boolean oneByte; - private final boolean bitInstr; // bit instruction? (BIT,SET,RES) - private final boolean relativeAddress; - - /** - * Creates a new instance of OC_RegExpr - * - * @param pos index of byte where add register value; e.g. DD 70+reg XX XX - * => pos = 1; C4+reg 00 00 => pos = 0; - */ - - public OC_RegExpr(int opcode, int reg, int pos, Expression expr, boolean oneByte, int line, int column) { - super(opcode, line, column); - relativeAddress = opcode == JR; - this.opcode += (reg << ((getSize() - 1 - pos) * 8)); - this.oneByte = oneByte; - this.expr = expr; - this.bitInstr = false; - } - - /** - * Special constructor for BIT,RES and SET instructions - */ - public OC_RegExpr(int opcode, Expression bit, int reg, int line, int column) { - super(opcode, line, column); - relativeAddress = false; - oneByte = true; - this.expr = bit; - this.opcode += reg; - bitInstr = true; - } - - @Override - public void pass1() { - } - - @Override - public int pass2(Namespace parentEnv, int addr_start) throws Exception { - expr.eval(parentEnv, addr_start); - int val = expr.getValue(); - if (bitInstr) { - if ((val > 7) || (val < 0)) { - throw new ValueOutOfBoundsException(line, column, 0, 7, val); - } - opcode += (8 * val); - } else { - if (oneByte) { - if (relativeAddress) { - val = computeRelativeAddress(line, column, addr_start, val); - } else if (Expression.getSize(val) > 1) { - throw new ValueTooBigException(line, column, val, 0xFF); - } - opcode += Expression.reverseBytes(val, 1); - } else { - opcode += Expression.reverseBytes(val, 2); - } - } - return addr_start + getSize(); - } - - // this can be only mvi instr - @Override - public void generateCode(IntelHEX hex) { - String s; - if (getSize() == 1) { - s = "%1$02X"; - } else if (getSize() == 2) { - s = "%1$04X"; - } else if (getSize() == 3) { - s = "%1$06X"; - } else { - s = "%1$08X"; - } - hex.putCode(String.format(s, opcode)); - } +public class OC_RegExpr { +// public static final int CALL = 0xC40000; // CALL cc,NN +// public static final int JP = 0xC20000; // JP cc,NN +// public static final int JR = 0x2000; // JR cc,N +// public static final int LD_IIX_NN = 0xDD7000; // LD (IX+N),r +// public static final int LD_IIY_NN = 0xFD7000; // LD (IY+N),r +// public static final int LD_RR = 0x010000; // LD rr,NN +// public static final int BIT = 0xCB40; // BIT b,r +// public static final int RES = 0xCB80; // RES b,r +// public static final int SET = 0xCBC0; // SET b,r +// +// private final Expression expr; +// private final boolean oneByte; +// private final boolean bitInstr; // bit instruction? (BIT,SET,RES) +// private final boolean relativeAddress; +// +// /** +// * Creates a new instance of OC_RegExpr +// * +// * @param pos index of byte where add register value; e.g. DD 70+reg XX XX +// * => pos = 1; C4+reg 00 00 => pos = 0; +// */ +// +// public OC_RegExpr(int opcode, int reg, int pos, Expression expr, boolean oneByte, int line, int column) { +// super(opcode, line, column); +// relativeAddress = opcode == JR; +// this.opcode += (reg << ((getSize() - 1 - pos) * 8)); +// this.oneByte = oneByte; +// this.expr = expr; +// this.bitInstr = false; +// } +// +// /** +// * Special constructor for BIT,RES and SET instructions +// */ +// public OC_RegExpr(int opcode, Expression bit, int reg, int line, int column) { +// super(opcode, line, column); +// relativeAddress = false; +// oneByte = true; +// this.expr = bit; +// this.opcode += reg; +// bitInstr = true; +// } +// +// @Override +// public void pass1() { +// } +// +// @Override +// public int pass2(Namespace parentEnv, int addr_start) throws Exception { +// expr.eval(parentEnv, addr_start); +// int val = expr.getValue(); +// if (bitInstr) { +// if ((val > 7) || (val < 0)) { +// throw new ValueOutOfBoundsException(line, column, 0, 7, val); +// } +// opcode += (8 * val); +// } else { +// if (oneByte) { +// if (relativeAddress) { +// val = computeRelativeAddress(line, column, addr_start, val); +// } else if (Expression.getSize(val) > 1) { +// throw new ValueTooBigException(line, column, val, 0xFF); +// } +// opcode += Expression.reverseBytes(val, 1); +// } else { +// opcode += Expression.reverseBytes(val, 2); +// } +// } +// return addr_start + getSize(); +// } +// +// // this can be only mvi instr +// @Override +// public void generateCode(IntelHEX hex) { +// String s; +// if (getSize() == 1) { +// s = "%1$02X"; +// } else if (getSize() == 2) { +// s = "%1$04X"; +// } else if (getSize() == 3) { +// s = "%1$06X"; +// } else { +// s = "%1$08X"; +// } +// hex.putCode(String.format(s, opcode)); +// } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java index ee2ef10a8..f0a49f33b 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java @@ -4,9 +4,9 @@ import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrExpr; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRegExpr; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRegPairExpr; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrN; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrR_N; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRP_NN; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroArgument; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoOrg; @@ -37,7 +37,7 @@ public void visit(DataDS node) { } @Override - public void visit(InstrExpr node) { + public void visit(InstrN node) { expectedBytes = node.getExprSizeBytes(); if (expectedBytes == 1 && node.getChildrenCount() > 1) { error(expressionIsBiggerThanExpected(node, expectedBytes, node.getChildrenCount())); @@ -46,7 +46,7 @@ public void visit(InstrExpr node) { } @Override - public void visit(InstrRegExpr node) { + public void visit(InstrR_N node) { expectedBytes = 1; if (node.getChildrenCount() > 1) { error(expressionIsBiggerThanExpected(node, expectedBytes, node.getChildrenCount())); @@ -55,7 +55,7 @@ public void visit(InstrRegExpr node) { } @Override - public void visit(InstrRegPairExpr node) { + public void visit(InstrRP_NN node) { expectedBytes = 2; visitChildren(node); } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java index cfc60248e..d41486491 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java @@ -8,50 +8,122 @@ public class CreateInstrVisitor extends AsZ80ParserBaseVisitor { @Override - public Node visitInstrNoArgs(InstrNoArgsContext ctx) { - return new InstrNoArgs(ctx.opcode); + public Node visitInstrRP_NN(InstrRP_NNContext ctx) { + InstrRP_NN instr = new InstrRP_NN(ctx.opcode, ctx.rp.start); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + return instr; } @Override - public Node visitInstrReg(InstrRegContext ctx) { - return new InstrReg(ctx.opcode, ctx.reg.getStart()); + public Node visitInstrR_N(InstrR_NContext ctx) { + InstrR_N instr = new InstrR_N(ctx.opcode, ctx.r.r); + instr.addChild(CreateVisitors.expr.visit(ctx.n)); + return instr; } @Override - public Node visitInstrRegReg(InstrRegRegContext ctx) { - return new InstrRegReg(ctx.opcode, ctx.dst.getStart(), ctx.src.getStart()); + public Node visitInstr8bitN(Instr8bitNContext ctx) { + InstrN instr = new InstrN(ctx.opcode); + instr.addChild(CreateVisitors.expr.visit(ctx.n)); + return instr; } @Override - public Node visitInstrRegPair(InstrRegPairContext ctx) { - return new InstrRegPair(ctx.opcode, ctx.regpair); + public Node visitInstrRef_NN_R(InstrRef_NN_RContext ctx) { + InstrRef_NN_R instr = new InstrRef_NN_R(ctx.opcode, ctx.r); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + return instr; } @Override - public Node visitInstrRegPairExpr(InstrRegPairExprContext ctx) { - InstrRegPairExpr instr = new InstrRegPairExpr(ctx.opcode, ctx.regpair); - instr.addChild(CreateVisitors.expr.visit(ctx.expr)); + public Node visitInstrRP_Ref_NN(InstrRP_Ref_NNContext ctx) { + InstrRP_Ref_NN instr = new InstrRP_Ref_NN(ctx.opcode, ctx.rp); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); return instr; } @Override - public Node visitInstrRegExpr(InstrRegExprContext ctx) { - InstrRegExpr instr = new InstrRegExpr(ctx.opcode, ctx.reg.getStart()); - instr.addChild(CreateVisitors.expr.visit(ctx.expr)); + public Node visitInstrR_Ref_NN(InstrR_Ref_NNContext ctx) { + InstrR_Ref_NN instr = new InstrR_Ref_NN(ctx.opcode, ctx.r); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); return instr; } @Override - public Node visitInstrExpr(InstrExprContext ctx) { - InstrExpr instr = new InstrExpr(ctx.opcode); - instr.addChild(CreateVisitors.expr.visit(ctx.expr)); + public Node visitInstrN(InstrNContext ctx) { + InstrN instr = new InstrN(ctx.opcode); + instr.addChild(CreateVisitors.expr.visit(ctx.n)); return instr; } @Override - public Node visitInstr8bitExpr(Instr8bitExprContext ctx) { - InstrExpr instr = new InstrExpr(ctx.opcode); - instr.addChild(CreateVisitors.expr.visit(ctx.expr)); + public Node visitInstrNN(InstrNNContext ctx) { + InstrNN instr = new InstrNN(ctx.opcode); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + return instr; + } + + @Override + public Node visitInstrC_N(InstrC_NContext ctx) { + InstrC_N instr = new InstrC_N(ctx.opcode, ctx.c); + instr.addChild(CreateVisitors.expr.visit(ctx.n)); + return instr; + } + + @Override + public Node visitInstr(InstrContext ctx) { + return new Instr(ctx.opcode); + } + + @Override + public Node visitInstrRef_RP(InstrRef_RPContext ctx) { + return new InstrRef_RP(ctx.opcode, ctx.rp); + } + + @Override + public Node visitInstrA_Ref_RP(InstrA_Ref_RPContext ctx) { + return new InstrA_Ref_RP(ctx.opcode, ctx.rp); + } + + @Override + public Node visitInstrR_R(InstrR_RContext ctx) { + return new InstrR_R(ctx.opcode, ctx.dst.r, ctx.src.r); + } + + @Override + public Node visitInstrRP_RP(InstrRP_RPContext ctx) { + return new InstrRP_RP(ctx.opcode, ctx.src, ctx.dst); + } + + @Override + public Node visitInstrRP(InstrRPContext ctx) { + return new InstrRP(ctx.opcode, ctx.rp.start); + } + + @Override + public Node visitInstrRP2(InstrRP2Context ctx) { + return new InstrRP(ctx.opcode, ctx.rp2.start); + } + + @Override + public Node visitInstrR(InstrRContext ctx) { + return new InstrR(ctx.opcode, ctx.r.r); + } + + @Override + public Node visitInstrRef_RP_RP(InstrRef_RP_RPContext ctx) { + return new InstrRef_RP_RP(ctx.opcode, ctx.src, ctx.dst); + } + + @Override + public Node visitInstrC(InstrCContext ctx) { + return new InstrC(ctx.opcode, ctx.c.start); + } + + @Override + public Node visitInstrC_NN(InstrC_NNContext ctx) { + InstrC_NN instr = new InstrC_NN(ctx.opcode, ctx.c.start); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); return instr; } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java index dbd22e777..c2cca16b8 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java @@ -1,7 +1,7 @@ package net.emustudio.plugins.compiler.asZ80.visitors; -import net.emustudio.plugins.compiler.asZ80.As8080Parser.*; -import net.emustudio.plugins.compiler.asZ80.As8080ParserBaseVisitor; +import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import net.emustudio.plugins.compiler.asZ80.AsZ80ParserBaseVisitor; import net.emustudio.plugins.compiler.asZ80.ast.Node; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java index bbb0538b4..55e218d6f 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java @@ -189,7 +189,7 @@ public void visit(PseudoIf node) { } @Override - public void visit(InstrExpr node) { + public void visit(InstrN node) { node.setAddress(currentAddress); sizeBytes = node.getExprSizeBytes(); visitChildren(node); @@ -197,7 +197,7 @@ public void visit(InstrExpr node) { } @Override - public void visit(InstrRegExpr node) { + public void visit(InstrR_N node) { node.setAddress(currentAddress); sizeBytes = 1; visitChildren(node); @@ -205,7 +205,7 @@ public void visit(InstrRegExpr node) { } @Override - public void visit(InstrRegPairExpr node) { + public void visit(InstrRP_NN node) { node.setAddress(currentAddress); sizeBytes = 2; visitChildren(node); @@ -213,25 +213,25 @@ public void visit(InstrRegPairExpr node) { } @Override - public void visit(InstrNoArgs node) { + public void visit(Instr node) { node.setAddress(currentAddress); currentAddress++; } @Override - public void visit(InstrRegReg node) { + public void visit(InstrR_R node) { node.setAddress(currentAddress); currentAddress++; } @Override - public void visit(InstrReg node) { + public void visit(InstrR node) { node.setAddress(currentAddress); currentAddress++; } @Override - public void visit(InstrRegPair node) { + public void visit(InstrRP node) { node.setAddress(currentAddress); currentAddress++; } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java index e4d23a16c..e65fcbcae 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java @@ -38,9 +38,9 @@ public void visit(PseudoInclude node) { } try { - As8080Lexer lexer = new As8080Lexer(CharStreams.fromFileName(node.filename)); + AsZ80Lexer lexer = new AsZ80Lexer(CharStreams.fromFileName(node.filename)); CommonTokenStream stream = new CommonTokenStream(lexer); - As8080Parser parser = new As8080Parser(stream); + AsZ80Parser parser = new AsZ80Parser(stream); stream.fill(); ParseTree tree = parser.rStart(); Program program = new Program(node.line, node.column, env); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java index a5cfcb403..967b9e547 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java @@ -48,7 +48,7 @@ public void visit(DataDS node) { } @Override - public void visit(InstrExpr node) { + public void visit(InstrN node) { node.eval() .ifPresentOrElse( hex::add, @@ -59,36 +59,36 @@ public void visit(InstrExpr node) { } @Override - public void visit(InstrNoArgs node) { + public void visit(Instr node) { hex.add(node.eval()); } @Override - public void visit(InstrReg node) { + public void visit(InstrR node) { hex.add(node.eval()); } @Override - public void visit(InstrRegExpr node) { + public void visit(InstrR_N node) { hex.add(node.eval()); expectedBytes = 1; visitChildren(node); } @Override - public void visit(InstrRegPair node) { + public void visit(InstrRP node) { hex.add(node.eval()); } @Override - public void visit(InstrRegPairExpr node) { + public void visit(InstrRP_NN node) { hex.add(node.eval()); expectedBytes = 2; visitChildren(node); } @Override - public void visit(InstrRegReg node) { + public void visit(InstrR_R node) { hex.add(node.eval()); } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java index 72bce216c..ee2a35476 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java @@ -73,31 +73,75 @@ public void visit(ExprUnary node) { visitChildren(node); } - public void visit(InstrExpr node) { + public void visit(Instr node) { visitChildren(node); } - public void visit(InstrNoArgs node) { + public void visit(InstrA_Ref_RP node) { visitChildren(node); } - public void visit(InstrReg node) { + public void visit(InstrC node) { visitChildren(node); } - public void visit(InstrRegExpr node) { + public void visit(InstrC_N node) { visitChildren(node); } - public void visit(InstrRegPair node) { + public void visit(InstrC_NN node) { visitChildren(node); } - public void visit(InstrRegPairExpr node) { + public void visit(InstrN node) { visitChildren(node); } - public void visit(InstrRegReg node) { + public void visit(InstrNN node) { + visitChildren(node); + } + + public void visit(InstrR node) { + visitChildren(node); + } + + public void visit(InstrR_N node) { + visitChildren(node); + } + + public void visit(InstrR_R node) { + visitChildren(node); + } + + public void visit(InstrR_Ref_NN node) { + visitChildren(node); + } + + public void visit(InstrRef_NN_R node) { + visitChildren(node); + } + + public void visit(InstrRef_RP node) { + visitChildren(node); + } + + public void visit(InstrRef_RP_RP node) { + visitChildren(node); + } + + public void visit(InstrRP node) { + visitChildren(node); + } + + public void visit(InstrRP_NN node) { + visitChildren(node); + } + + public void visit(InstrRP_Ref_NN node) { + visitChildren(node); + } + + public void visit(InstrRP_RP node) { visitChildren(node); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_ExprTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_ExprTest.java deleted file mode 100644 index 7a8cad776..000000000 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_ExprTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80; - -import org.junit.Test; - -public class OC_ExprTest extends AbstractCompilerTest { - - @Test - public void testRST() throws Exception { - compile( - "JP EXAMPLE\n" + - "RST 0\n" + - "EXAMPLE:\n" + - "LD A, 1\n" - ); - - assertProgram( - 0xC3, 0x04, 0x00, 0xC7, 0x3E, 0x01 - ); - } -} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegExprTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegExprTest.java deleted file mode 100644 index dcc58b12f..000000000 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegExprTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80; - -import org.junit.Test; - -public class OC_RegExprTest extends AbstractCompilerTest { - - @Test - public void testJR_CC_N() throws Exception { - compile( - "jr c, 3\n" - ); - - assertProgram( - 0x38, 01 - ); - } -} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java index 796477898..e6dcba70c 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java @@ -24,190 +24,190 @@ import static org.junit.Assert.assertEquals; -public class OC_RegTest extends AbstractCompilerTest { - - @Test - public void testINR() throws Exception { - compile( - "inc A\n" - + "inc B\n" - + "inc C\n" - + "inc D\n" - + "inc E\n" - + "inc H\n" - + "inc L\n" - + "inc (HL)\n" - ); - - assertProgram( - 0x3C, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34 - ); - } - - @Test - public void testDCR() throws Exception { - compile( - "dec A\n" - + "dec B\n" - + "dec C\n" - + "dec D\n" - + "dec E\n" - + "dec H\n" - + "dec L\n" - + "dec (HL)\n" - ); - - assertProgram( - 0x3D, 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, 0x35 - ); - } - - @Test - public void testADD() throws Exception { - compile( - "add A,A\n" - + "add A,B\n" - + "add A,C\n" - + "add A,D\n" - + "add A,E\n" - + "add A,H\n" - + "add A,L\n" - + "add A,(HL)\n" - ); - - assertProgram( - 0x87, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86 - ); - } - - @Test - public void testADC() throws Exception { - compile( - "adc A,A\n" - + "adc A,B\n" - + "adc A,C\n" - + "adc A,D\n" - + "adc A,E\n" - + "adc A,H\n" - + "adc A,L\n" - + "adc A,(HL)\n" - ); - - assertProgram( - 0x8F, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E - ); - } - - @Test - public void testSUB() throws Exception { - compile( - "sub A\n" - + "sub B\n" - + "sub C\n" - + "sub D\n" - + "sub E\n" - + "sub H\n" - + "sub L\n" - + "sub (HL)\n" - ); - - assertProgram( - 0x97, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96 - ); - } - - @Test - public void testSBB() throws Exception { - compile( - "sbc A\n" - + "sbc B\n" - + "sbc C\n" - + "sbc D\n" - + "sbc E\n" - + "sbc H\n" - + "sbc L\n" - + "sbc (HL)\n" - ); - - assertProgram( - 0x9F, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E - ); - } - - @Test - public void testANA() throws Exception { - compile( - "and A\n" - + "and B\n" - + "and C\n" - + "and D\n" - + "and E\n" - + "and H\n" - + "and L\n" - + "and (HL)\n" - ); - - assertProgram( - 0xA7, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6 - ); - } - - @Test - public void testXRA() throws Exception { - compile( - "xor A\n" - + "xor B\n" - + "xor C\n" - + "xor D\n" - + "xor E\n" - + "xor H\n" - + "xor L\n" - + "xor (HL)\n" - ); - - assertProgram( - 0xAF, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE - ); - } - - @Test - public void testORA() throws Exception { - compile( - "or A\n" - + "or B\n" - + "or C\n" - + "or D\n" - + "or E\n" - + "or H\n" - + "or L\n" - + "or (HL)\n" - ); - - assertProgram( - 0xB7, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6 - ); - } - - @Test - public void testCMP() throws Exception { - compile( - "cp A\n" - + "cp B\n" - + "cp C\n" - + "cp D\n" - + "cp E\n" - + "cp H\n" - + "cp L\n" - + "cp (HL)\n" - ); - - assertProgram( - 0xBF, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE - ); - } - - @Test - public void testOCRegSizeReturns1() throws Exception { - Assert.assertEquals(1, new OC_Reg(55, 0, 0, 0).getSize()); - } +public class OC_RegTest { +// +// @Test +// public void testINR() throws Exception { +// compile( +// "inc A\n" +// + "inc B\n" +// + "inc C\n" +// + "inc D\n" +// + "inc E\n" +// + "inc H\n" +// + "inc L\n" +// + "inc (HL)\n" +// ); +// +// assertProgram( +// 0x3C, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34 +// ); +// } +// +// @Test +// public void testDCR() throws Exception { +// compile( +// "dec A\n" +// + "dec B\n" +// + "dec C\n" +// + "dec D\n" +// + "dec E\n" +// + "dec H\n" +// + "dec L\n" +// + "dec (HL)\n" +// ); +// +// assertProgram( +// 0x3D, 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, 0x35 +// ); +// } +// +// @Test +// public void testADD() throws Exception { +// compile( +// "add A,A\n" +// + "add A,B\n" +// + "add A,C\n" +// + "add A,D\n" +// + "add A,E\n" +// + "add A,H\n" +// + "add A,L\n" +// + "add A,(HL)\n" +// ); +// +// assertProgram( +// 0x87, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86 +// ); +// } +// +// @Test +// public void testADC() throws Exception { +// compile( +// "adc A,A\n" +// + "adc A,B\n" +// + "adc A,C\n" +// + "adc A,D\n" +// + "adc A,E\n" +// + "adc A,H\n" +// + "adc A,L\n" +// + "adc A,(HL)\n" +// ); +// +// assertProgram( +// 0x8F, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E +// ); +// } +// +// @Test +// public void testSUB() throws Exception { +// compile( +// "sub A\n" +// + "sub B\n" +// + "sub C\n" +// + "sub D\n" +// + "sub E\n" +// + "sub H\n" +// + "sub L\n" +// + "sub (HL)\n" +// ); +// +// assertProgram( +// 0x97, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96 +// ); +// } +// +// @Test +// public void testSBB() throws Exception { +// compile( +// "sbc A\n" +// + "sbc B\n" +// + "sbc C\n" +// + "sbc D\n" +// + "sbc E\n" +// + "sbc H\n" +// + "sbc L\n" +// + "sbc (HL)\n" +// ); +// +// assertProgram( +// 0x9F, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E +// ); +// } +// +// @Test +// public void testANA() throws Exception { +// compile( +// "and A\n" +// + "and B\n" +// + "and C\n" +// + "and D\n" +// + "and E\n" +// + "and H\n" +// + "and L\n" +// + "and (HL)\n" +// ); +// +// assertProgram( +// 0xA7, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6 +// ); +// } +// +// @Test +// public void testXRA() throws Exception { +// compile( +// "xor A\n" +// + "xor B\n" +// + "xor C\n" +// + "xor D\n" +// + "xor E\n" +// + "xor H\n" +// + "xor L\n" +// + "xor (HL)\n" +// ); +// +// assertProgram( +// 0xAF, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE +// ); +// } +// +// @Test +// public void testORA() throws Exception { +// compile( +// "or A\n" +// + "or B\n" +// + "or C\n" +// + "or D\n" +// + "or E\n" +// + "or H\n" +// + "or L\n" +// + "or (HL)\n" +// ); +// +// assertProgram( +// 0xB7, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6 +// ); +// } +// +// @Test +// public void testCMP() throws Exception { +// compile( +// "cp A\n" +// + "cp B\n" +// + "cp C\n" +// + "cp D\n" +// + "cp E\n" +// + "cp H\n" +// + "cp L\n" +// + "cp (HL)\n" +// ); +// +// assertProgram( +// 0xBF, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE +// ); +// } +// +// @Test +// public void testOCRegSizeReturns1() throws Exception { +// Assert.assertEquals(1, new OC_Reg(55, 0, 0, 0).getSize()); +// } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java index 06c5bc71c..285641478 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java @@ -30,7 +30,7 @@ public class Utils { "e", REG_E, "h", REG_H, "l", REG_L, - "m", REG_M + "(HL)", REG_HL ); public static Map regPairsBD = Map.of( @@ -43,11 +43,11 @@ public class Utils { "h", REG_H, "sp", REG_SP ); - public static Map regPairsBDHPSW = Map.of( + public static Map regPairsBDHAF = Map.of( "b", REG_B, "d", REG_D, "h", REG_H, - "psw", REG_PSW + "af", REG_AF ); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java index 4b61ca484..373809a7f 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java @@ -95,84 +95,74 @@ public void testParseComment2() { @Test public void testParseOpcodes() { - assertTokenTypesIgnoreCase("STC", OPCODE_STC, EOF); - assertTokenTypesIgnoreCase("CMC", OPCODE_CMC, EOF); - assertTokenTypesIgnoreCase("CMA", OPCODE_CMA, EOF); - assertTokenTypesIgnoreCase("DAA", OPCODE_DAA, EOF); - assertTokenTypesIgnoreCase("NOP", OPCODE_NOP, EOF); - assertTokenTypesIgnoreCase("RLC", OPCODE_RLC, EOF); - assertTokenTypesIgnoreCase("RRC", OPCODE_RRC, EOF); - assertTokenTypesIgnoreCase("RAL", OPCODE_RAL, EOF); - assertTokenTypesIgnoreCase("RAR", OPCODE_RAR, EOF); - assertTokenTypesIgnoreCase("XCHG", OPCODE_XCHG, EOF); - assertTokenTypesIgnoreCase("XTHL", OPCODE_XTHL, EOF); - assertTokenTypesIgnoreCase("SPHL", OPCODE_SPHL, EOF); - assertTokenTypesIgnoreCase("PCHL", OPCODE_PCHL, EOF); - assertTokenTypesIgnoreCase("RET", OPCODE_RET, EOF); - assertTokenTypesIgnoreCase("RC", OPCODE_RC, EOF); - assertTokenTypesIgnoreCase("RNC", OPCODE_RNC, EOF); - assertTokenTypesIgnoreCase("RZ", OPCODE_RZ, EOF); - assertTokenTypesIgnoreCase("RNZ", OPCODE_RNZ, EOF); - assertTokenTypesIgnoreCase("RM", OPCODE_RM, EOF); - assertTokenTypesIgnoreCase("RP", OPCODE_RP, EOF); - assertTokenTypesIgnoreCase("RPE", OPCODE_RPE, EOF); - assertTokenTypesIgnoreCase("RPO", OPCODE_RPO, EOF); - assertTokenTypesIgnoreCase("EI", OPCODE_EI, EOF); - assertTokenTypesIgnoreCase("DI", OPCODE_DI, EOF); - assertTokenTypesIgnoreCase("HLT", OPCODE_HLT, EOF); - assertTokenTypesIgnoreCase("INR", OPCODE_INR, EOF); - assertTokenTypesIgnoreCase("DCR", OPCODE_DCR, EOF); - assertTokenTypesIgnoreCase("ADD", OPCODE_ADD, EOF); assertTokenTypesIgnoreCase("ADC", OPCODE_ADC, EOF); - assertTokenTypesIgnoreCase("SUB", OPCODE_SUB, EOF); - assertTokenTypesIgnoreCase("SBB", OPCODE_SBB, EOF); - assertTokenTypesIgnoreCase("ANA", OPCODE_ANA, EOF); - assertTokenTypesIgnoreCase("XRA", OPCODE_XRA, EOF); - assertTokenTypesIgnoreCase("ORA", OPCODE_ORA, EOF); - assertTokenTypesIgnoreCase("CMP", OPCODE_CMP, EOF); - assertTokenTypesIgnoreCase("MOV", OPCODE_MOV, EOF); - assertTokenTypesIgnoreCase("STAX", OPCODE_STAX, EOF); - assertTokenTypesIgnoreCase("LDAX", OPCODE_LDAX, EOF); - assertTokenTypesIgnoreCase("PUSH", OPCODE_PUSH, EOF); - assertTokenTypesIgnoreCase("POP", OPCODE_POP, EOF); - assertTokenTypesIgnoreCase("DAD", OPCODE_DAD, EOF); - assertTokenTypesIgnoreCase("INX", OPCODE_INX, EOF); - assertTokenTypesIgnoreCase("DCX", OPCODE_DCX, EOF); - assertTokenTypesIgnoreCase("LXI", OPCODE_LXI, EOF); - assertTokenTypesIgnoreCase("MVI", OPCODE_MVI, EOF); - assertTokenTypesIgnoreCase("ADI", OPCODE_ADI, EOF); - assertTokenTypesIgnoreCase("ACI", OPCODE_ACI, EOF); - assertTokenTypesIgnoreCase("SUI", OPCODE_SUI, EOF); - assertTokenTypesIgnoreCase("SBI", OPCODE_SBI, EOF); - assertTokenTypesIgnoreCase("ANI", OPCODE_ANI, EOF); - assertTokenTypesIgnoreCase("XRI", OPCODE_XRI, EOF); - assertTokenTypesIgnoreCase("ORI", OPCODE_ORI, EOF); - assertTokenTypesIgnoreCase("CPI", OPCODE_CPI, EOF); - assertTokenTypesIgnoreCase("STA", OPCODE_STA, EOF); - assertTokenTypesIgnoreCase("LDA", OPCODE_LDA, EOF); - assertTokenTypesIgnoreCase("SHLD", OPCODE_SHLD, EOF); - assertTokenTypesIgnoreCase("LHLD", OPCODE_LHLD, EOF); - assertTokenTypesIgnoreCase("JMP", OPCODE_JMP, EOF); - assertTokenTypesIgnoreCase("JC", OPCODE_JC, EOF); - assertTokenTypesIgnoreCase("JNC", OPCODE_JNC, EOF); - assertTokenTypesIgnoreCase("JZ", OPCODE_JZ, EOF); - assertTokenTypesIgnoreCase("JNZ", OPCODE_JNZ, EOF); - assertTokenTypesIgnoreCase("JM", OPCODE_JM, EOF); - assertTokenTypesIgnoreCase("JP", OPCODE_JP, EOF); - assertTokenTypesIgnoreCase("JPE", OPCODE_JPE, EOF); - assertTokenTypesIgnoreCase("JPO", OPCODE_JPO, EOF); + assertTokenTypesIgnoreCase("ADD", OPCODE_ADD, EOF); + assertTokenTypesIgnoreCase("AND", OPCODE_AND, EOF); + assertTokenTypesIgnoreCase("BIT", OPCODE_BIT, EOF); assertTokenTypesIgnoreCase("CALL", OPCODE_CALL, EOF); - assertTokenTypesIgnoreCase("CC", OPCODE_CC, EOF); - assertTokenTypesIgnoreCase("CNC", OPCODE_CNC, EOF); - assertTokenTypesIgnoreCase("CZ", OPCODE_CZ, EOF); - assertTokenTypesIgnoreCase("CNZ", OPCODE_CNZ, EOF); - assertTokenTypesIgnoreCase("CM", OPCODE_CM, EOF); + assertTokenTypesIgnoreCase("CCF", OPCODE_CCF, EOF); assertTokenTypesIgnoreCase("CP", OPCODE_CP, EOF); - assertTokenTypesIgnoreCase("CPE", OPCODE_CPE, EOF); - assertTokenTypesIgnoreCase("CPO", OPCODE_CPO, EOF); - assertTokenTypesIgnoreCase("RST", OPCODE_RST, EOF); + assertTokenTypesIgnoreCase("CPD", OPCODE_CPD, EOF); + assertTokenTypesIgnoreCase("CPDR", OPCODE_CPDR, EOF); + assertTokenTypesIgnoreCase("CPI", OPCODE_CPI, EOF); + assertTokenTypesIgnoreCase("CPIR", OPCODE_CPIR, EOF); + assertTokenTypesIgnoreCase("CPL", OPCODE_CPL, EOF); + assertTokenTypesIgnoreCase("DAA", OPCODE_DAA, EOF); + assertTokenTypesIgnoreCase("DEC", OPCODE_DEC, EOF); + assertTokenTypesIgnoreCase("DI", OPCODE_DI, EOF); + assertTokenTypesIgnoreCase("DJNZ", OPCODE_DJNZ, EOF); + assertTokenTypesIgnoreCase("EI", OPCODE_EI, EOF); + assertTokenTypesIgnoreCase("EX", OPCODE_EX, EOF); + assertTokenTypesIgnoreCase("EXX", OPCODE_EXX, EOF); + assertTokenTypesIgnoreCase("HALT", OPCODE_HALT, EOF); + assertTokenTypesIgnoreCase("IM", OPCODE_IM, EOF); assertTokenTypesIgnoreCase("IN", OPCODE_IN, EOF); + assertTokenTypesIgnoreCase("INC", OPCODE_INC, EOF); + assertTokenTypesIgnoreCase("IND", OPCODE_IND, EOF); + assertTokenTypesIgnoreCase("INDR", OPCODE_INDR, EOF); + assertTokenTypesIgnoreCase("INI", OPCODE_INI, EOF); + assertTokenTypesIgnoreCase("INIR", OPCODE_INIR, EOF); + assertTokenTypesIgnoreCase("JP", OPCODE_JP, EOF); // condition + assertTokenTypesIgnoreCase("JR", OPCODE_JR, EOF); // condition + assertTokenTypesIgnoreCase("LD", OPCODE_LD, EOF); + assertTokenTypesIgnoreCase("LDD", OPCODE_LDD, EOF); + assertTokenTypesIgnoreCase("LDDR", OPCODE_LDDR, EOF); + assertTokenTypesIgnoreCase("LDI", OPCODE_LDI, EOF); + assertTokenTypesIgnoreCase("LDIR", OPCODE_LDIR, EOF); + assertTokenTypesIgnoreCase("NEG", OPCODE_NEG, EOF); + assertTokenTypesIgnoreCase("NOP", OPCODE_NOP, EOF); + assertTokenTypesIgnoreCase("OR", OPCODE_OR, EOF); + assertTokenTypesIgnoreCase("OTDR", OPCODE_OTDR, EOF); + assertTokenTypesIgnoreCase("OTIR", OPCODE_OTIR, EOF); assertTokenTypesIgnoreCase("OUT", OPCODE_OUT, EOF); + assertTokenTypesIgnoreCase("OUTD", OPCODE_OUTD, EOF); + assertTokenTypesIgnoreCase("OUTI", OPCODE_OUTI, EOF); + assertTokenTypesIgnoreCase("POP", OPCODE_POP, EOF); + assertTokenTypesIgnoreCase("PUSH", OPCODE_PUSH, EOF); + assertTokenTypesIgnoreCase("RES", OPCODE_RES, EOF); + assertTokenTypesIgnoreCase("RET", OPCODE_RET, EOF); // condition + assertTokenTypesIgnoreCase("RETI", OPCODE_RETI, EOF); + assertTokenTypesIgnoreCase("RETN", OPCODE_RETN, EOF); + assertTokenTypesIgnoreCase("RL", OPCODE_RL, EOF); + assertTokenTypesIgnoreCase("RLA", OPCODE_RLA, EOF); + assertTokenTypesIgnoreCase("RLC", OPCODE_RLC, EOF); + assertTokenTypesIgnoreCase("RLCA", OPCODE_RLCA, EOF); + assertTokenTypesIgnoreCase("RLD", OPCODE_RLD, EOF); + assertTokenTypesIgnoreCase("RR", OPCODE_RR, EOF); + assertTokenTypesIgnoreCase("RRA", OPCODE_RRA, EOF); + assertTokenTypesIgnoreCase("RRC", OPCODE_RRC, EOF); + assertTokenTypesIgnoreCase("RRCA", OPCODE_RRCA, EOF); + assertTokenTypesIgnoreCase("RRD", OPCODE_RRD, EOF); + assertTokenTypesIgnoreCase("RST", OPCODE_RST, EOF); + assertTokenTypesIgnoreCase("SBC", OPCODE_SBC, EOF); + assertTokenTypesIgnoreCase("SCF", OPCODE_SCF, EOF); + assertTokenTypesIgnoreCase("SET", OPCODE_SET, EOF); + assertTokenTypesIgnoreCase("SLA", OPCODE_SLA, EOF); + assertTokenTypesIgnoreCase("SRA", OPCODE_SRA, EOF); + assertTokenTypesIgnoreCase("SLL", OPCODE_SLL, EOF); + assertTokenTypesIgnoreCase("SRL", OPCODE_SRL, EOF); + assertTokenTypesIgnoreCase("SUB", OPCODE_SUB, EOF); + assertTokenTypesIgnoreCase("XOR", OPCODE_XOR, EOF); } @Test @@ -200,8 +190,8 @@ public void testRegisters() { assertTokenTypesIgnoreCase("E", REG_E, EOF); assertTokenTypesIgnoreCase("H", REG_H, EOF); assertTokenTypesIgnoreCase("L", REG_L, EOF); - assertTokenTypesIgnoreCase("M", REG_M, EOF); - assertTokenTypesIgnoreCase("PSW", REG_PSW, EOF); + assertTokenTypesIgnoreCase("AF", REG_AF, EOF); + assertTokenTypesIgnoreCase("AFF", REG_AFF, EOF); assertTokenTypesIgnoreCase("SP", REG_SP, EOF); } @@ -212,7 +202,9 @@ public void testSeparators() { @Test public void testOperators1() { - assertTokenTypes("+-*/=", OP_ADD, OP_SUBTRACT, OP_MULTIPLY, OP_DIVIDE, OP_EQUAL, EOF); + assertTokenTypes("+-*/=<<>><><=>=^%|&", + OP_ADD, OP_SUBTRACT, OP_MULTIPLY, OP_DIVIDE, OP_EQUAL, OP_SHL_2, OP_SHR_2, OP_LT, OP_GT, OP_LTE, OP_GTE, + OP_XOR_2, OP_MOD_2, OP_OR_2, OP_AND_2, EOF); } @Test diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java index dc8eb2f50..8f857e965 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java @@ -7,10 +7,10 @@ import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprString; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprUnary; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrNoArgs; +import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; import org.junit.Test; -import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.OPCODE_STC; +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.OPCODE_RET; import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.OP_SUBTRACT; import static net.emustudio.plugins.compiler.asZ80.Utils.assertTrees; import static net.emustudio.plugins.compiler.asZ80.Utils.parseProgram; @@ -39,11 +39,11 @@ public void testDBstring2() { @Test public void testDBinstruction() { - Program program = parseProgram("db stc"); + Program program = parseProgram("db ret"); assertTrees( new Program() .addChild(new DataDB(0, 0) - .addChild(new InstrNoArgs(0, 0, OPCODE_STC))), + .addChild(new Instr(0, 0, OPCODE_RET))), program ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java index fa82f4242..218bdb1c9 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java @@ -102,8 +102,8 @@ public void testRegPair() { assertInstrRegPair("dad", OPCODE_DAD, regPairsBDHSP); assertInstrRegPair("inx", OPCODE_INX, regPairsBDHSP); assertInstrRegPair("dcx", OPCODE_DCX, regPairsBDHSP); - assertInstrRegPair("push", OPCODE_PUSH, regPairsBDHPSW); - assertInstrRegPair("pop", OPCODE_POP, regPairsBDHPSW); + assertInstrRegPair("push", OPCODE_PUSH, regPairsBDHAF); + assertInstrRegPair("pop", OPCODE_POP, regPairsBDHAF); } @Test @@ -119,7 +119,7 @@ public void testMVI() { Program program = parseProgram(row); assertTrees( new Program() - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, register.getValue()) + .addChild(new InstrR_N(0, 0, OPCODE_MVI, register.getValue()) .addChild(expr)), program ); @@ -141,7 +141,7 @@ public void testLXI() { Program program = parseProgram(row); assertTrees( new Program() - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, regPair.getValue()) + .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, regPair.getValue()) .addChild(expr)), program ); @@ -162,7 +162,7 @@ public void testMOV() { Program program = parseProgram(row); assertTrees( new Program() - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, register1.getValue(), register2.getValue())), + .addChild(new InstrR_R(0, 0, OPCODE_MOV, register1.getValue(), register2.getValue())), program ); } @@ -176,7 +176,7 @@ public void testMOV() { private void assertInstrNoArgs(String instr, int instrType) { forStringCaseVariations(instr, variation -> { Program program = parseProgram(variation); - assertTrees(new Program().addChild(new InstrNoArgs(0, 0, instrType)), program); + assertTrees(new Program().addChild(new Instr(0, 0, instrType)), program); }); } @@ -187,7 +187,7 @@ private void assertInstrReg(String instr, int instrType) { String row = instrVariation + " " + registerVariation; Program program = parseProgram(row); assertTrees( - new Program().addChild(new InstrReg(0, 0, instrType, register.getValue())), + new Program().addChild(new InstrR(0, 0, instrType, register.getValue())), program ); }); @@ -202,7 +202,7 @@ private void assertInstrExpr(String instr, int instrType) { forStringCaseVariations(instr, variation -> { Program program = parseProgram(variation + " $ + 5"); - assertTrees(new Program().addChild(new InstrExpr(0, 0, instrType).addChild(expr)), program); + assertTrees(new Program().addChild(new InstrN(0, 0, instrType).addChild(expr)), program); }); } @@ -213,7 +213,7 @@ private void assertInstrRegPair(String instr, int instrType, Map Date: Wed, 9 Feb 2022 07:52:26 +0100 Subject: [PATCH 096/314] [#201] as-z80: wip --- plugins/compiler/as-z80/.gitignore | 3 +- .../src/main/antlr/gen/AsZ80Lexer.interp | 499 --- .../as-z80/src/main/antlr/gen/AsZ80Lexer.java | 597 --- .../src/main/antlr/gen/AsZ80Lexer.tokens | 172 - .../as-z80/src/main/gen/AsZ80Lexer.interp | 496 --- .../as-z80/src/main/gen/AsZ80Lexer.java | 592 --- .../as-z80/src/main/gen/AsZ80Lexer.tokens | 171 - .../as-z80/src/main/gen/AsZ80Parser.interp | 329 -- .../as-z80/src/main/gen/AsZ80Parser.java | 3658 ----------------- .../as-z80/src/main/gen/AsZ80Parser.tokens | 172 - .../src/main/gen/AsZ80ParserBaseListener.java | 578 --- .../src/main/gen/AsZ80ParserBaseVisitor.java | 328 -- .../src/main/gen/AsZ80ParserListener.java | 531 --- .../src/main/gen/AsZ80ParserVisitor.java | 318 -- 14 files changed, 2 insertions(+), 8442 deletions(-) delete mode 100644 plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.interp delete mode 100644 plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.java delete mode 100644 plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.tokens delete mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp delete mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java delete mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.tokens delete mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Parser.interp delete mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Parser.java delete mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80Parser.tokens delete mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseListener.java delete mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseVisitor.java delete mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80ParserListener.java delete mode 100644 plugins/compiler/as-z80/src/main/gen/AsZ80ParserVisitor.java diff --git a/plugins/compiler/as-z80/.gitignore b/plugins/compiler/as-z80/.gitignore index 4c20bab5e..a37c70406 100644 --- a/plugins/compiler/as-z80/.gitignore +++ b/plugins/compiler/as-z80/.gitignore @@ -1 +1,2 @@ -src/main/java/net/emustudio/plugins/compiler/asZ80/LexerImpl.java +/src/main/antlr/gen/ +/src/main/gen/ diff --git a/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.interp b/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.interp deleted file mode 100644 index 1fa749f22..000000000 --- a/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.interp +++ /dev/null @@ -1,499 +0,0 @@ -token literal names: -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -'$' -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -'(' -')' -',' -'+' -'-' -'*' -'/' -'=' -'>' -'>=' -'<' -'<=' -'%' -'>>' -'<<' -'!' -'&' -'|' -'~' -null -null - -token symbolic names: -null -COMMENT -COMMENT2 -OPCODE_ADC -OPCODE_ADD -OPCODE_AND -OPCODE_BIT -OPCODE_CALL -OPCODE_CCF -OPCODE_CP -OPCODE_CPD -OPCODE_CPDR -OPCODE_CPI -OPCODE_CPIR -OPCODE_CPL -OPCODE_DAA -OPCODE_DEC -OPCODE_DI -OPCODE_DJNZ -OPCODE_EI -OPCODE_EX -OPCODE_EXX -OPCODE_HALT -OPCODE_IM -OPCODE_IN -OPCODE_INC -OPCODE_IND -OPCODE_INDR -OPCODE_INI -OPCODE_INIR -OPCODE_JP -OPCODE_JR -OPCODE_LD -OPCODE_LDD -OPCODE_LDDR -OPCODE_LDI -OPCODE_LDIR -OPCODE_NEG -OPCODE_NOP -OPCODE_OR -OPCODE_OTDR -OPCODE_OTIR -OPCODE_OUT -OPCODE_OUTD -OPCODE_OUTI -OPCODE_POP -OPCODE_PUSH -OPCODE_RES -OPCODE_RET -OPCODE_RETI -OPCODE_RETN -OPCODE_RL -OPCODE_RLA -OPCODE_RLC -OPCODE_RLCA -OPCODE_RLD -OPCODE_RR -OPCODE_RRA -OPCODE_RRC -OPCODE_RRCA -OPCODE_RRD -OPCODE_RST -OPCODE_SBC -OPCODE_SCF -OPCODE_SET -OPCODE_SLA -OPCODE_SRA -OPCODE_SLL -OPCODE_SRL -OPCODE_SUB -OPCODE_XOR -COND_C -COND_NC -COND_Z -COND_NZ -COND_M -COND_P -COND_PE -COND_PO -COND_WS -COND_UNRECOGNIZED -PREP_ORG -PREP_EQU -PREP_SET -PREP_VAR -PREP_IF -PREP_ENDIF -PREP_INCLUDE -PREP_MACRO -PREP_ENDM -PREP_DB -PREP_DW -PREP_DS -PREP_ADDR -REG_A -REG_B -REG_C -REG_D -REG_E -REG_H -REG_L -REG_IX -REG_IXH -REG_IXL -REG_IY -REG_IYH -REG_IYL -REG_BC -REG_DE -REG_HL -REG_SP -REG_AF -REG_AFF -REG_I -REG_R -OP_MOD -OP_SHR -OP_SHL -OP_NOT -OP_AND -OP_OR -OP_XOR -LIT_HEXNUMBER_1 -LIT_NUMBER -LIT_HEXNUMBER_2 -LIT_OCTNUMBER -LIT_BINNUMBER -LIT_STRING_1 -LIT_STRING_2 -ID_IDENTIFIER -ID_LABEL -ERROR -SEP_LPAR -SEP_RPAR -SEP_COMMA -OP_ADD -OP_SUBTRACT -OP_MULTIPLY -OP_DIVIDE -OP_EQUAL -OP_GT -OP_GTE -OP_LT -OP_LTE -OP_MOD_2 -OP_SHR_2 -OP_SHL_2 -OP_NOT_2 -OP_AND_2 -OP_OR_2 -OP_XOR_2 -WS -EOL - -rule names: -COMMENT -COMMENT2 -A -B -C -D -E -F -G -H -I -J -L -M -N -O -P -Q -R -S -T -U -V -W -X -Y -Z -OPCODE_ADC -OPCODE_ADD -OPCODE_AND -OPCODE_BIT -OPCODE_CALL -OPCODE_CCF -OPCODE_CP -OPCODE_CPD -OPCODE_CPDR -OPCODE_CPI -OPCODE_CPIR -OPCODE_CPL -OPCODE_DAA -OPCODE_DEC -OPCODE_DI -OPCODE_DJNZ -OPCODE_EI -OPCODE_EX -OPCODE_EXX -OPCODE_HALT -OPCODE_IM -OPCODE_IN -OPCODE_INC -OPCODE_IND -OPCODE_INDR -OPCODE_INI -OPCODE_INIR -OPCODE_JP -OPCODE_JR -OPCODE_LD -OPCODE_LDD -OPCODE_LDDR -OPCODE_LDI -OPCODE_LDIR -OPCODE_NEG -OPCODE_NOP -OPCODE_OR -OPCODE_OTDR -OPCODE_OTIR -OPCODE_OUT -OPCODE_OUTD -OPCODE_OUTI -OPCODE_POP -OPCODE_PUSH -OPCODE_RES -OPCODE_RET -OPCODE_RETI -OPCODE_RETN -OPCODE_RL -OPCODE_RLA -OPCODE_RLC -OPCODE_RLCA -OPCODE_RLD -OPCODE_RR -OPCODE_RRA -OPCODE_RRC -OPCODE_RRCA -OPCODE_RRD -OPCODE_RST -OPCODE_SBC -OPCODE_SCF -OPCODE_SET -OPCODE_SLA -OPCODE_SRA -OPCODE_SLL -OPCODE_SRL -OPCODE_SUB -OPCODE_XOR -COND_C -COND_NC -COND_Z -COND_NZ -COND_M -COND_P -COND_PE -COND_PO -COND_WS -COND_UNRECOGNIZED -PREP_ORG -PREP_EQU -PREP_SET -PREP_VAR -PREP_IF -PREP_ENDIF -PREP_INCLUDE -PREP_MACRO -PREP_ENDM -PREP_DB -PREP_DW -PREP_DS -PREP_ADDR -REG_A -REG_B -REG_C -REG_D -REG_E -REG_H -REG_L -REG_IX -REG_IXH -REG_IXL -REG_IY -REG_IYH -REG_IYL -REG_BC -REG_DE -REG_HL -REG_SP -REG_AF -REG_AFF -REG_I -REG_R -OP_MOD -OP_SHR -OP_SHL -OP_NOT -OP_AND -OP_OR -OP_XOR -LIT_HEXNUMBER_1 -LIT_NUMBER -LIT_HEXNUMBER_2 -LIT_OCTNUMBER -LIT_BINNUMBER -LIT_STRING_1 -LIT_STRING_2 -ID_IDENTIFIER -ID_LABEL -ERROR -SEP_LPAR -SEP_RPAR -SEP_COMMA -OP_ADD -OP_SUBTRACT -OP_MULTIPLY -OP_DIVIDE -OP_EQUAL -OP_GT -OP_GTE -OP_LT -OP_LTE -OP_MOD_2 -OP_SHR_2 -OP_SHL_2 -OP_NOT_2 -OP_AND_2 -OP_OR_2 -OP_XOR_2 -WS -EOL - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE -CONDITION - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 154, 1035, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 4, 154, 9, 154, 4, 155, 9, 155, 4, 156, 9, 156, 4, 157, 9, 157, 4, 158, 9, 158, 4, 159, 9, 159, 4, 160, 9, 160, 4, 161, 9, 161, 4, 162, 9, 162, 4, 163, 9, 163, 4, 164, 9, 164, 4, 165, 9, 165, 4, 166, 9, 166, 4, 167, 9, 167, 4, 168, 9, 168, 4, 169, 9, 169, 4, 170, 9, 170, 4, 171, 9, 171, 4, 172, 9, 172, 4, 173, 9, 173, 4, 174, 9, 174, 4, 175, 9, 175, 4, 176, 9, 176, 4, 177, 9, 177, 4, 178, 9, 178, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 364, 10, 2, 3, 2, 7, 2, 367, 10, 2, 12, 2, 14, 2, 370, 11, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 378, 10, 3, 12, 3, 14, 3, 381, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 104, 3, 105, 6, 105, 761, 10, 105, 13, 105, 14, 105, 762, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 129, 3, 129, 3, 130, 3, 130, 3, 130, 3, 131, 3, 131, 3, 131, 3, 131, 3, 132, 3, 132, 3, 132, 3, 132, 3, 133, 3, 133, 3, 133, 3, 134, 3, 134, 3, 134, 3, 135, 3, 135, 3, 135, 3, 136, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 138, 3, 138, 3, 139, 3, 139, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 3, 144, 3, 144, 3, 144, 3, 145, 3, 145, 3, 145, 3, 145, 3, 146, 3, 146, 3, 146, 3, 147, 3, 147, 3, 147, 3, 147, 3, 148, 3, 148, 3, 148, 6, 148, 916, 10, 148, 13, 148, 14, 148, 917, 3, 149, 6, 149, 921, 10, 149, 13, 149, 14, 149, 922, 3, 149, 5, 149, 926, 10, 149, 3, 150, 6, 150, 929, 10, 150, 13, 150, 14, 150, 930, 3, 150, 3, 150, 3, 151, 6, 151, 936, 10, 151, 13, 151, 14, 151, 937, 3, 151, 3, 151, 3, 152, 6, 152, 943, 10, 152, 13, 152, 14, 152, 944, 3, 152, 3, 152, 3, 153, 3, 153, 7, 153, 951, 10, 153, 12, 153, 14, 153, 954, 11, 153, 3, 153, 3, 153, 3, 154, 3, 154, 7, 154, 960, 10, 154, 12, 154, 14, 154, 963, 11, 154, 3, 154, 3, 154, 3, 155, 3, 155, 7, 155, 969, 10, 155, 12, 155, 14, 155, 972, 11, 155, 3, 156, 3, 156, 3, 156, 3, 157, 6, 157, 978, 10, 157, 13, 157, 14, 157, 979, 3, 158, 3, 158, 3, 159, 3, 159, 3, 160, 3, 160, 3, 161, 3, 161, 3, 162, 3, 162, 3, 163, 3, 163, 3, 164, 3, 164, 3, 165, 3, 165, 3, 166, 3, 166, 3, 167, 3, 167, 3, 167, 3, 168, 3, 168, 3, 169, 3, 169, 3, 169, 3, 170, 3, 170, 3, 171, 3, 171, 3, 171, 3, 172, 3, 172, 3, 172, 3, 173, 3, 173, 3, 174, 3, 174, 3, 175, 3, 175, 3, 176, 3, 176, 3, 177, 6, 177, 1025, 10, 177, 13, 177, 14, 177, 1026, 3, 177, 3, 177, 3, 178, 5, 178, 1032, 10, 178, 3, 178, 3, 178, 3, 379, 2, 179, 4, 3, 6, 4, 8, 2, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54, 2, 56, 2, 58, 5, 60, 6, 62, 7, 64, 8, 66, 9, 68, 10, 70, 11, 72, 12, 74, 13, 76, 14, 78, 15, 80, 16, 82, 17, 84, 18, 86, 19, 88, 20, 90, 21, 92, 22, 94, 23, 96, 24, 98, 25, 100, 26, 102, 27, 104, 28, 106, 29, 108, 30, 110, 31, 112, 32, 114, 33, 116, 34, 118, 35, 120, 36, 122, 37, 124, 38, 126, 39, 128, 40, 130, 41, 132, 42, 134, 43, 136, 44, 138, 45, 140, 46, 142, 47, 144, 48, 146, 49, 148, 50, 150, 51, 152, 52, 154, 53, 156, 54, 158, 55, 160, 56, 162, 57, 164, 58, 166, 59, 168, 60, 170, 61, 172, 62, 174, 63, 176, 64, 178, 65, 180, 66, 182, 67, 184, 68, 186, 69, 188, 70, 190, 71, 192, 72, 194, 73, 196, 74, 198, 75, 200, 76, 202, 77, 204, 78, 206, 79, 208, 80, 210, 81, 212, 82, 214, 83, 216, 84, 218, 85, 220, 86, 222, 87, 224, 88, 226, 89, 228, 90, 230, 91, 232, 92, 234, 93, 236, 94, 238, 95, 240, 96, 242, 97, 244, 98, 246, 99, 248, 100, 250, 101, 252, 102, 254, 103, 256, 104, 258, 105, 260, 106, 262, 107, 264, 108, 266, 109, 268, 110, 270, 111, 272, 112, 274, 113, 276, 114, 278, 115, 280, 116, 282, 117, 284, 118, 286, 119, 288, 120, 290, 121, 292, 122, 294, 123, 296, 124, 298, 125, 300, 126, 302, 127, 304, 128, 306, 129, 308, 130, 310, 131, 312, 132, 314, 133, 316, 134, 318, 135, 320, 136, 322, 137, 324, 138, 326, 139, 328, 140, 330, 141, 332, 142, 334, 143, 336, 144, 338, 145, 340, 146, 342, 147, 344, 148, 346, 149, 348, 150, 350, 151, 352, 152, 354, 153, 356, 154, 4, 2, 3, 40, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 5, 2, 11, 11, 14, 14, 34, 34, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 59, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 3, 2, 36, 36, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 8, 2, 11, 12, 14, 15, 34, 34, 42, 47, 49, 49, 63, 63, 2, 1025, 2, 4, 3, 2, 2, 2, 2, 6, 3, 2, 2, 2, 2, 58, 3, 2, 2, 2, 2, 60, 3, 2, 2, 2, 2, 62, 3, 2, 2, 2, 2, 64, 3, 2, 2, 2, 2, 66, 3, 2, 2, 2, 2, 68, 3, 2, 2, 2, 2, 70, 3, 2, 2, 2, 2, 72, 3, 2, 2, 2, 2, 74, 3, 2, 2, 2, 2, 76, 3, 2, 2, 2, 2, 78, 3, 2, 2, 2, 2, 80, 3, 2, 2, 2, 2, 82, 3, 2, 2, 2, 2, 84, 3, 2, 2, 2, 2, 86, 3, 2, 2, 2, 2, 88, 3, 2, 2, 2, 2, 90, 3, 2, 2, 2, 2, 92, 3, 2, 2, 2, 2, 94, 3, 2, 2, 2, 2, 96, 3, 2, 2, 2, 2, 98, 3, 2, 2, 2, 2, 100, 3, 2, 2, 2, 2, 102, 3, 2, 2, 2, 2, 104, 3, 2, 2, 2, 2, 106, 3, 2, 2, 2, 2, 108, 3, 2, 2, 2, 2, 110, 3, 2, 2, 2, 2, 112, 3, 2, 2, 2, 2, 114, 3, 2, 2, 2, 2, 116, 3, 2, 2, 2, 2, 118, 3, 2, 2, 2, 2, 120, 3, 2, 2, 2, 2, 122, 3, 2, 2, 2, 2, 124, 3, 2, 2, 2, 2, 126, 3, 2, 2, 2, 2, 128, 3, 2, 2, 2, 2, 130, 3, 2, 2, 2, 2, 132, 3, 2, 2, 2, 2, 134, 3, 2, 2, 2, 2, 136, 3, 2, 2, 2, 2, 138, 3, 2, 2, 2, 2, 140, 3, 2, 2, 2, 2, 142, 3, 2, 2, 2, 2, 144, 3, 2, 2, 2, 2, 146, 3, 2, 2, 2, 2, 148, 3, 2, 2, 2, 2, 150, 3, 2, 2, 2, 2, 152, 3, 2, 2, 2, 2, 154, 3, 2, 2, 2, 2, 156, 3, 2, 2, 2, 2, 158, 3, 2, 2, 2, 2, 160, 3, 2, 2, 2, 2, 162, 3, 2, 2, 2, 2, 164, 3, 2, 2, 2, 2, 166, 3, 2, 2, 2, 2, 168, 3, 2, 2, 2, 2, 170, 3, 2, 2, 2, 2, 172, 3, 2, 2, 2, 2, 174, 3, 2, 2, 2, 2, 176, 3, 2, 2, 2, 2, 178, 3, 2, 2, 2, 2, 180, 3, 2, 2, 2, 2, 182, 3, 2, 2, 2, 2, 184, 3, 2, 2, 2, 2, 186, 3, 2, 2, 2, 2, 188, 3, 2, 2, 2, 2, 190, 3, 2, 2, 2, 2, 192, 3, 2, 2, 2, 2, 214, 3, 2, 2, 2, 2, 216, 3, 2, 2, 2, 2, 218, 3, 2, 2, 2, 2, 220, 3, 2, 2, 2, 2, 222, 3, 2, 2, 2, 2, 224, 3, 2, 2, 2, 2, 226, 3, 2, 2, 2, 2, 228, 3, 2, 2, 2, 2, 230, 3, 2, 2, 2, 2, 232, 3, 2, 2, 2, 2, 234, 3, 2, 2, 2, 2, 236, 3, 2, 2, 2, 2, 238, 3, 2, 2, 2, 2, 240, 3, 2, 2, 2, 2, 242, 3, 2, 2, 2, 2, 244, 3, 2, 2, 2, 2, 246, 3, 2, 2, 2, 2, 248, 3, 2, 2, 2, 2, 250, 3, 2, 2, 2, 2, 252, 3, 2, 2, 2, 2, 254, 3, 2, 2, 2, 2, 256, 3, 2, 2, 2, 2, 258, 3, 2, 2, 2, 2, 260, 3, 2, 2, 2, 2, 262, 3, 2, 2, 2, 2, 264, 3, 2, 2, 2, 2, 266, 3, 2, 2, 2, 2, 268, 3, 2, 2, 2, 2, 270, 3, 2, 2, 2, 2, 272, 3, 2, 2, 2, 2, 274, 3, 2, 2, 2, 2, 276, 3, 2, 2, 2, 2, 278, 3, 2, 2, 2, 2, 280, 3, 2, 2, 2, 2, 282, 3, 2, 2, 2, 2, 284, 3, 2, 2, 2, 2, 286, 3, 2, 2, 2, 2, 288, 3, 2, 2, 2, 2, 290, 3, 2, 2, 2, 2, 292, 3, 2, 2, 2, 2, 294, 3, 2, 2, 2, 2, 296, 3, 2, 2, 2, 2, 298, 3, 2, 2, 2, 2, 300, 3, 2, 2, 2, 2, 302, 3, 2, 2, 2, 2, 304, 3, 2, 2, 2, 2, 306, 3, 2, 2, 2, 2, 308, 3, 2, 2, 2, 2, 310, 3, 2, 2, 2, 2, 312, 3, 2, 2, 2, 2, 314, 3, 2, 2, 2, 2, 316, 3, 2, 2, 2, 2, 318, 3, 2, 2, 2, 2, 320, 3, 2, 2, 2, 2, 322, 3, 2, 2, 2, 2, 324, 3, 2, 2, 2, 2, 326, 3, 2, 2, 2, 2, 328, 3, 2, 2, 2, 2, 330, 3, 2, 2, 2, 2, 332, 3, 2, 2, 2, 2, 334, 3, 2, 2, 2, 2, 336, 3, 2, 2, 2, 2, 338, 3, 2, 2, 2, 2, 340, 3, 2, 2, 2, 2, 342, 3, 2, 2, 2, 2, 344, 3, 2, 2, 2, 2, 346, 3, 2, 2, 2, 2, 348, 3, 2, 2, 2, 2, 350, 3, 2, 2, 2, 2, 352, 3, 2, 2, 2, 2, 354, 3, 2, 2, 2, 2, 356, 3, 2, 2, 2, 3, 194, 3, 2, 2, 2, 3, 196, 3, 2, 2, 2, 3, 198, 3, 2, 2, 2, 3, 200, 3, 2, 2, 2, 3, 202, 3, 2, 2, 2, 3, 204, 3, 2, 2, 2, 3, 206, 3, 2, 2, 2, 3, 208, 3, 2, 2, 2, 3, 210, 3, 2, 2, 2, 3, 212, 3, 2, 2, 2, 4, 363, 3, 2, 2, 2, 6, 373, 3, 2, 2, 2, 8, 387, 3, 2, 2, 2, 10, 389, 3, 2, 2, 2, 12, 391, 3, 2, 2, 2, 14, 393, 3, 2, 2, 2, 16, 395, 3, 2, 2, 2, 18, 397, 3, 2, 2, 2, 20, 399, 3, 2, 2, 2, 22, 401, 3, 2, 2, 2, 24, 403, 3, 2, 2, 2, 26, 405, 3, 2, 2, 2, 28, 407, 3, 2, 2, 2, 30, 409, 3, 2, 2, 2, 32, 411, 3, 2, 2, 2, 34, 413, 3, 2, 2, 2, 36, 415, 3, 2, 2, 2, 38, 417, 3, 2, 2, 2, 40, 419, 3, 2, 2, 2, 42, 421, 3, 2, 2, 2, 44, 423, 3, 2, 2, 2, 46, 425, 3, 2, 2, 2, 48, 427, 3, 2, 2, 2, 50, 429, 3, 2, 2, 2, 52, 431, 3, 2, 2, 2, 54, 433, 3, 2, 2, 2, 56, 435, 3, 2, 2, 2, 58, 437, 3, 2, 2, 2, 60, 441, 3, 2, 2, 2, 62, 445, 3, 2, 2, 2, 64, 449, 3, 2, 2, 2, 66, 453, 3, 2, 2, 2, 68, 460, 3, 2, 2, 2, 70, 464, 3, 2, 2, 2, 72, 467, 3, 2, 2, 2, 74, 471, 3, 2, 2, 2, 76, 476, 3, 2, 2, 2, 78, 480, 3, 2, 2, 2, 80, 485, 3, 2, 2, 2, 82, 489, 3, 2, 2, 2, 84, 493, 3, 2, 2, 2, 86, 497, 3, 2, 2, 2, 88, 500, 3, 2, 2, 2, 90, 505, 3, 2, 2, 2, 92, 508, 3, 2, 2, 2, 94, 511, 3, 2, 2, 2, 96, 515, 3, 2, 2, 2, 98, 520, 3, 2, 2, 2, 100, 523, 3, 2, 2, 2, 102, 526, 3, 2, 2, 2, 104, 530, 3, 2, 2, 2, 106, 534, 3, 2, 2, 2, 108, 539, 3, 2, 2, 2, 110, 543, 3, 2, 2, 2, 112, 548, 3, 2, 2, 2, 114, 553, 3, 2, 2, 2, 116, 558, 3, 2, 2, 2, 118, 561, 3, 2, 2, 2, 120, 565, 3, 2, 2, 2, 122, 570, 3, 2, 2, 2, 124, 574, 3, 2, 2, 2, 126, 579, 3, 2, 2, 2, 128, 583, 3, 2, 2, 2, 130, 587, 3, 2, 2, 2, 132, 590, 3, 2, 2, 2, 134, 595, 3, 2, 2, 2, 136, 600, 3, 2, 2, 2, 138, 604, 3, 2, 2, 2, 140, 609, 3, 2, 2, 2, 142, 614, 3, 2, 2, 2, 144, 618, 3, 2, 2, 2, 146, 623, 3, 2, 2, 2, 148, 627, 3, 2, 2, 2, 150, 633, 3, 2, 2, 2, 152, 638, 3, 2, 2, 2, 154, 643, 3, 2, 2, 2, 156, 646, 3, 2, 2, 2, 158, 650, 3, 2, 2, 2, 160, 654, 3, 2, 2, 2, 162, 659, 3, 2, 2, 2, 164, 663, 3, 2, 2, 2, 166, 666, 3, 2, 2, 2, 168, 670, 3, 2, 2, 2, 170, 674, 3, 2, 2, 2, 172, 679, 3, 2, 2, 2, 174, 683, 3, 2, 2, 2, 176, 687, 3, 2, 2, 2, 178, 691, 3, 2, 2, 2, 180, 695, 3, 2, 2, 2, 182, 699, 3, 2, 2, 2, 184, 703, 3, 2, 2, 2, 186, 707, 3, 2, 2, 2, 188, 711, 3, 2, 2, 2, 190, 715, 3, 2, 2, 2, 192, 719, 3, 2, 2, 2, 194, 723, 3, 2, 2, 2, 196, 727, 3, 2, 2, 2, 198, 732, 3, 2, 2, 2, 200, 736, 3, 2, 2, 2, 202, 741, 3, 2, 2, 2, 204, 745, 3, 2, 2, 2, 206, 749, 3, 2, 2, 2, 208, 754, 3, 2, 2, 2, 210, 760, 3, 2, 2, 2, 212, 766, 3, 2, 2, 2, 214, 771, 3, 2, 2, 2, 216, 775, 3, 2, 2, 2, 218, 779, 3, 2, 2, 2, 220, 783, 3, 2, 2, 2, 222, 787, 3, 2, 2, 2, 224, 790, 3, 2, 2, 2, 226, 796, 3, 2, 2, 2, 228, 804, 3, 2, 2, 2, 230, 810, 3, 2, 2, 2, 232, 815, 3, 2, 2, 2, 234, 818, 3, 2, 2, 2, 236, 821, 3, 2, 2, 2, 238, 824, 3, 2, 2, 2, 240, 826, 3, 2, 2, 2, 242, 828, 3, 2, 2, 2, 244, 830, 3, 2, 2, 2, 246, 832, 3, 2, 2, 2, 248, 834, 3, 2, 2, 2, 250, 836, 3, 2, 2, 2, 252, 838, 3, 2, 2, 2, 254, 840, 3, 2, 2, 2, 256, 843, 3, 2, 2, 2, 258, 847, 3, 2, 2, 2, 260, 851, 3, 2, 2, 2, 262, 854, 3, 2, 2, 2, 264, 858, 3, 2, 2, 2, 266, 862, 3, 2, 2, 2, 268, 865, 3, 2, 2, 2, 270, 868, 3, 2, 2, 2, 272, 871, 3, 2, 2, 2, 274, 874, 3, 2, 2, 2, 276, 877, 3, 2, 2, 2, 278, 881, 3, 2, 2, 2, 280, 883, 3, 2, 2, 2, 282, 885, 3, 2, 2, 2, 284, 889, 3, 2, 2, 2, 286, 893, 3, 2, 2, 2, 288, 897, 3, 2, 2, 2, 290, 901, 3, 2, 2, 2, 292, 905, 3, 2, 2, 2, 294, 908, 3, 2, 2, 2, 296, 912, 3, 2, 2, 2, 298, 920, 3, 2, 2, 2, 300, 928, 3, 2, 2, 2, 302, 935, 3, 2, 2, 2, 304, 942, 3, 2, 2, 2, 306, 948, 3, 2, 2, 2, 308, 957, 3, 2, 2, 2, 310, 966, 3, 2, 2, 2, 312, 973, 3, 2, 2, 2, 314, 977, 3, 2, 2, 2, 316, 981, 3, 2, 2, 2, 318, 983, 3, 2, 2, 2, 320, 985, 3, 2, 2, 2, 322, 987, 3, 2, 2, 2, 324, 989, 3, 2, 2, 2, 326, 991, 3, 2, 2, 2, 328, 993, 3, 2, 2, 2, 330, 995, 3, 2, 2, 2, 332, 997, 3, 2, 2, 2, 334, 999, 3, 2, 2, 2, 336, 1002, 3, 2, 2, 2, 338, 1004, 3, 2, 2, 2, 340, 1007, 3, 2, 2, 2, 342, 1009, 3, 2, 2, 2, 344, 1012, 3, 2, 2, 2, 346, 1015, 3, 2, 2, 2, 348, 1017, 3, 2, 2, 2, 350, 1019, 3, 2, 2, 2, 352, 1021, 3, 2, 2, 2, 354, 1024, 3, 2, 2, 2, 356, 1031, 3, 2, 2, 2, 358, 359, 7, 49, 2, 2, 359, 364, 7, 49, 2, 2, 360, 361, 7, 47, 2, 2, 361, 364, 7, 47, 2, 2, 362, 364, 9, 2, 2, 2, 363, 358, 3, 2, 2, 2, 363, 360, 3, 2, 2, 2, 363, 362, 3, 2, 2, 2, 364, 368, 3, 2, 2, 2, 365, 367, 10, 3, 2, 2, 366, 365, 3, 2, 2, 2, 367, 370, 3, 2, 2, 2, 368, 366, 3, 2, 2, 2, 368, 369, 3, 2, 2, 2, 369, 371, 3, 2, 2, 2, 370, 368, 3, 2, 2, 2, 371, 372, 8, 2, 2, 2, 372, 5, 3, 2, 2, 2, 373, 374, 7, 49, 2, 2, 374, 375, 7, 44, 2, 2, 375, 379, 3, 2, 2, 2, 376, 378, 11, 2, 2, 2, 377, 376, 3, 2, 2, 2, 378, 381, 3, 2, 2, 2, 379, 380, 3, 2, 2, 2, 379, 377, 3, 2, 2, 2, 380, 382, 3, 2, 2, 2, 381, 379, 3, 2, 2, 2, 382, 383, 7, 44, 2, 2, 383, 384, 7, 49, 2, 2, 384, 385, 3, 2, 2, 2, 385, 386, 8, 3, 2, 2, 386, 7, 3, 2, 2, 2, 387, 388, 9, 4, 2, 2, 388, 9, 3, 2, 2, 2, 389, 390, 9, 5, 2, 2, 390, 11, 3, 2, 2, 2, 391, 392, 9, 6, 2, 2, 392, 13, 3, 2, 2, 2, 393, 394, 9, 7, 2, 2, 394, 15, 3, 2, 2, 2, 395, 396, 9, 8, 2, 2, 396, 17, 3, 2, 2, 2, 397, 398, 9, 9, 2, 2, 398, 19, 3, 2, 2, 2, 399, 400, 9, 10, 2, 2, 400, 21, 3, 2, 2, 2, 401, 402, 9, 11, 2, 2, 402, 23, 3, 2, 2, 2, 403, 404, 9, 12, 2, 2, 404, 25, 3, 2, 2, 2, 405, 406, 9, 13, 2, 2, 406, 27, 3, 2, 2, 2, 407, 408, 9, 14, 2, 2, 408, 29, 3, 2, 2, 2, 409, 410, 9, 15, 2, 2, 410, 31, 3, 2, 2, 2, 411, 412, 9, 16, 2, 2, 412, 33, 3, 2, 2, 2, 413, 414, 9, 17, 2, 2, 414, 35, 3, 2, 2, 2, 415, 416, 9, 18, 2, 2, 416, 37, 3, 2, 2, 2, 417, 418, 9, 19, 2, 2, 418, 39, 3, 2, 2, 2, 419, 420, 9, 20, 2, 2, 420, 41, 3, 2, 2, 2, 421, 422, 9, 21, 2, 2, 422, 43, 3, 2, 2, 2, 423, 424, 9, 22, 2, 2, 424, 45, 3, 2, 2, 2, 425, 426, 9, 23, 2, 2, 426, 47, 3, 2, 2, 2, 427, 428, 9, 24, 2, 2, 428, 49, 3, 2, 2, 2, 429, 430, 9, 25, 2, 2, 430, 51, 3, 2, 2, 2, 431, 432, 9, 26, 2, 2, 432, 53, 3, 2, 2, 2, 433, 434, 9, 27, 2, 2, 434, 55, 3, 2, 2, 2, 435, 436, 9, 28, 2, 2, 436, 57, 3, 2, 2, 2, 437, 438, 5, 8, 4, 2, 438, 439, 5, 14, 7, 2, 439, 440, 5, 12, 6, 2, 440, 59, 3, 2, 2, 2, 441, 442, 5, 8, 4, 2, 442, 443, 5, 14, 7, 2, 443, 444, 5, 14, 7, 2, 444, 61, 3, 2, 2, 2, 445, 446, 5, 8, 4, 2, 446, 447, 5, 32, 16, 2, 447, 448, 5, 14, 7, 2, 448, 63, 3, 2, 2, 2, 449, 450, 5, 10, 5, 2, 450, 451, 5, 24, 12, 2, 451, 452, 5, 44, 22, 2, 452, 65, 3, 2, 2, 2, 453, 454, 5, 12, 6, 2, 454, 455, 5, 8, 4, 2, 455, 456, 5, 28, 14, 2, 456, 457, 5, 28, 14, 2, 457, 458, 3, 2, 2, 2, 458, 459, 8, 33, 3, 2, 459, 67, 3, 2, 2, 2, 460, 461, 5, 12, 6, 2, 461, 462, 5, 12, 6, 2, 462, 463, 5, 18, 9, 2, 463, 69, 3, 2, 2, 2, 464, 465, 5, 12, 6, 2, 465, 466, 5, 36, 18, 2, 466, 71, 3, 2, 2, 2, 467, 468, 5, 12, 6, 2, 468, 469, 5, 36, 18, 2, 469, 470, 5, 14, 7, 2, 470, 73, 3, 2, 2, 2, 471, 472, 5, 12, 6, 2, 472, 473, 5, 36, 18, 2, 473, 474, 5, 14, 7, 2, 474, 475, 5, 40, 20, 2, 475, 75, 3, 2, 2, 2, 476, 477, 5, 12, 6, 2, 477, 478, 5, 36, 18, 2, 478, 479, 5, 24, 12, 2, 479, 77, 3, 2, 2, 2, 480, 481, 5, 12, 6, 2, 481, 482, 5, 36, 18, 2, 482, 483, 5, 24, 12, 2, 483, 484, 5, 40, 20, 2, 484, 79, 3, 2, 2, 2, 485, 486, 5, 12, 6, 2, 486, 487, 5, 36, 18, 2, 487, 488, 5, 28, 14, 2, 488, 81, 3, 2, 2, 2, 489, 490, 5, 14, 7, 2, 490, 491, 5, 8, 4, 2, 491, 492, 5, 8, 4, 2, 492, 83, 3, 2, 2, 2, 493, 494, 5, 14, 7, 2, 494, 495, 5, 16, 8, 2, 495, 496, 5, 12, 6, 2, 496, 85, 3, 2, 2, 2, 497, 498, 5, 14, 7, 2, 498, 499, 5, 24, 12, 2, 499, 87, 3, 2, 2, 2, 500, 501, 5, 14, 7, 2, 501, 502, 5, 26, 13, 2, 502, 503, 5, 32, 16, 2, 503, 504, 5, 56, 28, 2, 504, 89, 3, 2, 2, 2, 505, 506, 5, 16, 8, 2, 506, 507, 5, 24, 12, 2, 507, 91, 3, 2, 2, 2, 508, 509, 5, 16, 8, 2, 509, 510, 5, 52, 26, 2, 510, 93, 3, 2, 2, 2, 511, 512, 5, 16, 8, 2, 512, 513, 5, 52, 26, 2, 513, 514, 5, 52, 26, 2, 514, 95, 3, 2, 2, 2, 515, 516, 5, 22, 11, 2, 516, 517, 5, 8, 4, 2, 517, 518, 5, 28, 14, 2, 518, 519, 5, 44, 22, 2, 519, 97, 3, 2, 2, 2, 520, 521, 5, 24, 12, 2, 521, 522, 5, 30, 15, 2, 522, 99, 3, 2, 2, 2, 523, 524, 5, 24, 12, 2, 524, 525, 5, 32, 16, 2, 525, 101, 3, 2, 2, 2, 526, 527, 5, 24, 12, 2, 527, 528, 5, 32, 16, 2, 528, 529, 5, 12, 6, 2, 529, 103, 3, 2, 2, 2, 530, 531, 5, 24, 12, 2, 531, 532, 5, 32, 16, 2, 532, 533, 5, 14, 7, 2, 533, 105, 3, 2, 2, 2, 534, 535, 5, 24, 12, 2, 535, 536, 5, 32, 16, 2, 536, 537, 5, 14, 7, 2, 537, 538, 5, 40, 20, 2, 538, 107, 3, 2, 2, 2, 539, 540, 5, 24, 12, 2, 540, 541, 5, 32, 16, 2, 541, 542, 5, 24, 12, 2, 542, 109, 3, 2, 2, 2, 543, 544, 5, 24, 12, 2, 544, 545, 5, 32, 16, 2, 545, 546, 5, 24, 12, 2, 546, 547, 5, 40, 20, 2, 547, 111, 3, 2, 2, 2, 548, 549, 5, 26, 13, 2, 549, 550, 5, 36, 18, 2, 550, 551, 3, 2, 2, 2, 551, 552, 8, 56, 3, 2, 552, 113, 3, 2, 2, 2, 553, 554, 5, 26, 13, 2, 554, 555, 5, 40, 20, 2, 555, 556, 3, 2, 2, 2, 556, 557, 8, 57, 3, 2, 557, 115, 3, 2, 2, 2, 558, 559, 5, 28, 14, 2, 559, 560, 5, 14, 7, 2, 560, 117, 3, 2, 2, 2, 561, 562, 5, 28, 14, 2, 562, 563, 5, 14, 7, 2, 563, 564, 5, 14, 7, 2, 564, 119, 3, 2, 2, 2, 565, 566, 5, 28, 14, 2, 566, 567, 5, 14, 7, 2, 567, 568, 5, 14, 7, 2, 568, 569, 5, 40, 20, 2, 569, 121, 3, 2, 2, 2, 570, 571, 5, 28, 14, 2, 571, 572, 5, 14, 7, 2, 572, 573, 5, 24, 12, 2, 573, 123, 3, 2, 2, 2, 574, 575, 5, 28, 14, 2, 575, 576, 5, 14, 7, 2, 576, 577, 5, 24, 12, 2, 577, 578, 5, 40, 20, 2, 578, 125, 3, 2, 2, 2, 579, 580, 5, 32, 16, 2, 580, 581, 5, 16, 8, 2, 581, 582, 5, 20, 10, 2, 582, 127, 3, 2, 2, 2, 583, 584, 5, 32, 16, 2, 584, 585, 5, 34, 17, 2, 585, 586, 5, 36, 18, 2, 586, 129, 3, 2, 2, 2, 587, 588, 5, 34, 17, 2, 588, 589, 5, 40, 20, 2, 589, 131, 3, 2, 2, 2, 590, 591, 5, 34, 17, 2, 591, 592, 5, 44, 22, 2, 592, 593, 5, 14, 7, 2, 593, 594, 5, 40, 20, 2, 594, 133, 3, 2, 2, 2, 595, 596, 5, 34, 17, 2, 596, 597, 5, 44, 22, 2, 597, 598, 5, 24, 12, 2, 598, 599, 5, 40, 20, 2, 599, 135, 3, 2, 2, 2, 600, 601, 5, 34, 17, 2, 601, 602, 5, 46, 23, 2, 602, 603, 5, 44, 22, 2, 603, 137, 3, 2, 2, 2, 604, 605, 5, 34, 17, 2, 605, 606, 5, 46, 23, 2, 606, 607, 5, 44, 22, 2, 607, 608, 5, 14, 7, 2, 608, 139, 3, 2, 2, 2, 609, 610, 5, 34, 17, 2, 610, 611, 5, 46, 23, 2, 611, 612, 5, 44, 22, 2, 612, 613, 5, 24, 12, 2, 613, 141, 3, 2, 2, 2, 614, 615, 5, 36, 18, 2, 615, 616, 5, 34, 17, 2, 616, 617, 5, 36, 18, 2, 617, 143, 3, 2, 2, 2, 618, 619, 5, 36, 18, 2, 619, 620, 5, 46, 23, 2, 620, 621, 5, 42, 21, 2, 621, 622, 5, 22, 11, 2, 622, 145, 3, 2, 2, 2, 623, 624, 5, 40, 20, 2, 624, 625, 5, 16, 8, 2, 625, 626, 5, 42, 21, 2, 626, 147, 3, 2, 2, 2, 627, 628, 5, 40, 20, 2, 628, 629, 5, 16, 8, 2, 629, 630, 5, 44, 22, 2, 630, 631, 3, 2, 2, 2, 631, 632, 8, 74, 3, 2, 632, 149, 3, 2, 2, 2, 633, 634, 5, 40, 20, 2, 634, 635, 5, 16, 8, 2, 635, 636, 5, 44, 22, 2, 636, 637, 5, 24, 12, 2, 637, 151, 3, 2, 2, 2, 638, 639, 5, 40, 20, 2, 639, 640, 5, 16, 8, 2, 640, 641, 5, 44, 22, 2, 641, 642, 5, 32, 16, 2, 642, 153, 3, 2, 2, 2, 643, 644, 5, 40, 20, 2, 644, 645, 5, 28, 14, 2, 645, 155, 3, 2, 2, 2, 646, 647, 5, 40, 20, 2, 647, 648, 5, 28, 14, 2, 648, 649, 5, 8, 4, 2, 649, 157, 3, 2, 2, 2, 650, 651, 5, 40, 20, 2, 651, 652, 5, 28, 14, 2, 652, 653, 5, 12, 6, 2, 653, 159, 3, 2, 2, 2, 654, 655, 5, 40, 20, 2, 655, 656, 5, 28, 14, 2, 656, 657, 5, 12, 6, 2, 657, 658, 5, 8, 4, 2, 658, 161, 3, 2, 2, 2, 659, 660, 5, 40, 20, 2, 660, 661, 5, 28, 14, 2, 661, 662, 5, 14, 7, 2, 662, 163, 3, 2, 2, 2, 663, 664, 5, 40, 20, 2, 664, 665, 5, 40, 20, 2, 665, 165, 3, 2, 2, 2, 666, 667, 5, 40, 20, 2, 667, 668, 5, 40, 20, 2, 668, 669, 5, 8, 4, 2, 669, 167, 3, 2, 2, 2, 670, 671, 5, 40, 20, 2, 671, 672, 5, 40, 20, 2, 672, 673, 5, 12, 6, 2, 673, 169, 3, 2, 2, 2, 674, 675, 5, 40, 20, 2, 675, 676, 5, 40, 20, 2, 676, 677, 5, 12, 6, 2, 677, 678, 5, 8, 4, 2, 678, 171, 3, 2, 2, 2, 679, 680, 5, 40, 20, 2, 680, 681, 5, 40, 20, 2, 681, 682, 5, 14, 7, 2, 682, 173, 3, 2, 2, 2, 683, 684, 5, 40, 20, 2, 684, 685, 5, 42, 21, 2, 685, 686, 5, 44, 22, 2, 686, 175, 3, 2, 2, 2, 687, 688, 5, 42, 21, 2, 688, 689, 5, 10, 5, 2, 689, 690, 5, 12, 6, 2, 690, 177, 3, 2, 2, 2, 691, 692, 5, 42, 21, 2, 692, 693, 5, 12, 6, 2, 693, 694, 5, 18, 9, 2, 694, 179, 3, 2, 2, 2, 695, 696, 5, 42, 21, 2, 696, 697, 5, 16, 8, 2, 697, 698, 5, 44, 22, 2, 698, 181, 3, 2, 2, 2, 699, 700, 5, 42, 21, 2, 700, 701, 5, 28, 14, 2, 701, 702, 5, 8, 4, 2, 702, 183, 3, 2, 2, 2, 703, 704, 5, 42, 21, 2, 704, 705, 5, 40, 20, 2, 705, 706, 5, 8, 4, 2, 706, 185, 3, 2, 2, 2, 707, 708, 5, 42, 21, 2, 708, 709, 5, 28, 14, 2, 709, 710, 5, 28, 14, 2, 710, 187, 3, 2, 2, 2, 711, 712, 5, 42, 21, 2, 712, 713, 5, 40, 20, 2, 713, 714, 5, 28, 14, 2, 714, 189, 3, 2, 2, 2, 715, 716, 5, 42, 21, 2, 716, 717, 5, 46, 23, 2, 717, 718, 5, 10, 5, 2, 718, 191, 3, 2, 2, 2, 719, 720, 5, 52, 26, 2, 720, 721, 5, 34, 17, 2, 721, 722, 5, 40, 20, 2, 722, 193, 3, 2, 2, 2, 723, 724, 5, 12, 6, 2, 724, 725, 3, 2, 2, 2, 725, 726, 8, 97, 4, 2, 726, 195, 3, 2, 2, 2, 727, 728, 5, 32, 16, 2, 728, 729, 5, 12, 6, 2, 729, 730, 3, 2, 2, 2, 730, 731, 8, 98, 4, 2, 731, 197, 3, 2, 2, 2, 732, 733, 5, 56, 28, 2, 733, 734, 3, 2, 2, 2, 734, 735, 8, 99, 4, 2, 735, 199, 3, 2, 2, 2, 736, 737, 5, 32, 16, 2, 737, 738, 5, 56, 28, 2, 738, 739, 3, 2, 2, 2, 739, 740, 8, 100, 4, 2, 740, 201, 3, 2, 2, 2, 741, 742, 5, 30, 15, 2, 742, 743, 3, 2, 2, 2, 743, 744, 8, 101, 4, 2, 744, 203, 3, 2, 2, 2, 745, 746, 5, 36, 18, 2, 746, 747, 3, 2, 2, 2, 747, 748, 8, 102, 4, 2, 748, 205, 3, 2, 2, 2, 749, 750, 5, 36, 18, 2, 750, 751, 5, 16, 8, 2, 751, 752, 3, 2, 2, 2, 752, 753, 8, 103, 4, 2, 753, 207, 3, 2, 2, 2, 754, 755, 5, 36, 18, 2, 755, 756, 5, 34, 17, 2, 756, 757, 3, 2, 2, 2, 757, 758, 8, 104, 4, 2, 758, 209, 3, 2, 2, 2, 759, 761, 9, 29, 2, 2, 760, 759, 3, 2, 2, 2, 761, 762, 3, 2, 2, 2, 762, 760, 3, 2, 2, 2, 762, 763, 3, 2, 2, 2, 763, 764, 3, 2, 2, 2, 764, 765, 8, 105, 2, 2, 765, 211, 3, 2, 2, 2, 766, 767, 6, 106, 2, 2, 767, 768, 3, 2, 2, 2, 768, 769, 8, 106, 4, 2, 769, 770, 8, 106, 5, 2, 770, 213, 3, 2, 2, 2, 771, 772, 5, 34, 17, 2, 772, 773, 5, 40, 20, 2, 773, 774, 5, 20, 10, 2, 774, 215, 3, 2, 2, 2, 775, 776, 5, 16, 8, 2, 776, 777, 5, 38, 19, 2, 777, 778, 5, 46, 23, 2, 778, 217, 3, 2, 2, 2, 779, 780, 5, 42, 21, 2, 780, 781, 5, 16, 8, 2, 781, 782, 5, 44, 22, 2, 782, 219, 3, 2, 2, 2, 783, 784, 5, 48, 24, 2, 784, 785, 5, 8, 4, 2, 785, 786, 5, 40, 20, 2, 786, 221, 3, 2, 2, 2, 787, 788, 5, 24, 12, 2, 788, 789, 5, 18, 9, 2, 789, 223, 3, 2, 2, 2, 790, 791, 5, 16, 8, 2, 791, 792, 5, 32, 16, 2, 792, 793, 5, 14, 7, 2, 793, 794, 5, 24, 12, 2, 794, 795, 5, 18, 9, 2, 795, 225, 3, 2, 2, 2, 796, 797, 5, 24, 12, 2, 797, 798, 5, 32, 16, 2, 798, 799, 5, 12, 6, 2, 799, 800, 5, 28, 14, 2, 800, 801, 5, 46, 23, 2, 801, 802, 5, 14, 7, 2, 802, 803, 5, 16, 8, 2, 803, 227, 3, 2, 2, 2, 804, 805, 5, 30, 15, 2, 805, 806, 5, 8, 4, 2, 806, 807, 5, 12, 6, 2, 807, 808, 5, 40, 20, 2, 808, 809, 5, 34, 17, 2, 809, 229, 3, 2, 2, 2, 810, 811, 5, 16, 8, 2, 811, 812, 5, 32, 16, 2, 812, 813, 5, 14, 7, 2, 813, 814, 5, 30, 15, 2, 814, 231, 3, 2, 2, 2, 815, 816, 5, 14, 7, 2, 816, 817, 5, 10, 5, 2, 817, 233, 3, 2, 2, 2, 818, 819, 5, 14, 7, 2, 819, 820, 5, 50, 25, 2, 820, 235, 3, 2, 2, 2, 821, 822, 5, 14, 7, 2, 822, 823, 5, 42, 21, 2, 823, 237, 3, 2, 2, 2, 824, 825, 7, 38, 2, 2, 825, 239, 3, 2, 2, 2, 826, 827, 5, 8, 4, 2, 827, 241, 3, 2, 2, 2, 828, 829, 5, 10, 5, 2, 829, 243, 3, 2, 2, 2, 830, 831, 5, 12, 6, 2, 831, 245, 3, 2, 2, 2, 832, 833, 5, 14, 7, 2, 833, 247, 3, 2, 2, 2, 834, 835, 5, 16, 8, 2, 835, 249, 3, 2, 2, 2, 836, 837, 5, 22, 11, 2, 837, 251, 3, 2, 2, 2, 838, 839, 5, 28, 14, 2, 839, 253, 3, 2, 2, 2, 840, 841, 5, 24, 12, 2, 841, 842, 5, 52, 26, 2, 842, 255, 3, 2, 2, 2, 843, 844, 5, 24, 12, 2, 844, 845, 5, 52, 26, 2, 845, 846, 5, 22, 11, 2, 846, 257, 3, 2, 2, 2, 847, 848, 5, 24, 12, 2, 848, 849, 5, 52, 26, 2, 849, 850, 5, 28, 14, 2, 850, 259, 3, 2, 2, 2, 851, 852, 5, 24, 12, 2, 852, 853, 5, 54, 27, 2, 853, 261, 3, 2, 2, 2, 854, 855, 5, 24, 12, 2, 855, 856, 5, 54, 27, 2, 856, 857, 5, 22, 11, 2, 857, 263, 3, 2, 2, 2, 858, 859, 5, 24, 12, 2, 859, 860, 5, 54, 27, 2, 860, 861, 5, 28, 14, 2, 861, 265, 3, 2, 2, 2, 862, 863, 5, 10, 5, 2, 863, 864, 5, 12, 6, 2, 864, 267, 3, 2, 2, 2, 865, 866, 5, 14, 7, 2, 866, 867, 5, 16, 8, 2, 867, 269, 3, 2, 2, 2, 868, 869, 5, 22, 11, 2, 869, 870, 5, 28, 14, 2, 870, 271, 3, 2, 2, 2, 871, 872, 5, 42, 21, 2, 872, 873, 5, 36, 18, 2, 873, 273, 3, 2, 2, 2, 874, 875, 5, 8, 4, 2, 875, 876, 5, 18, 9, 2, 876, 275, 3, 2, 2, 2, 877, 878, 5, 8, 4, 2, 878, 879, 5, 18, 9, 2, 879, 880, 7, 41, 2, 2, 880, 277, 3, 2, 2, 2, 881, 882, 5, 24, 12, 2, 882, 279, 3, 2, 2, 2, 883, 884, 5, 40, 20, 2, 884, 281, 3, 2, 2, 2, 885, 886, 5, 30, 15, 2, 886, 887, 5, 34, 17, 2, 887, 888, 5, 14, 7, 2, 888, 283, 3, 2, 2, 2, 889, 890, 5, 42, 21, 2, 890, 891, 5, 22, 11, 2, 891, 892, 5, 40, 20, 2, 892, 285, 3, 2, 2, 2, 893, 894, 5, 42, 21, 2, 894, 895, 5, 22, 11, 2, 895, 896, 5, 28, 14, 2, 896, 287, 3, 2, 2, 2, 897, 898, 5, 32, 16, 2, 898, 899, 5, 34, 17, 2, 899, 900, 5, 44, 22, 2, 900, 289, 3, 2, 2, 2, 901, 902, 5, 8, 4, 2, 902, 903, 5, 32, 16, 2, 903, 904, 5, 14, 7, 2, 904, 291, 3, 2, 2, 2, 905, 906, 5, 34, 17, 2, 906, 907, 5, 40, 20, 2, 907, 293, 3, 2, 2, 2, 908, 909, 5, 52, 26, 2, 909, 910, 5, 34, 17, 2, 910, 911, 5, 40, 20, 2, 911, 295, 3, 2, 2, 2, 912, 913, 7, 50, 2, 2, 913, 915, 5, 52, 26, 2, 914, 916, 9, 30, 2, 2, 915, 914, 3, 2, 2, 2, 916, 917, 3, 2, 2, 2, 917, 915, 3, 2, 2, 2, 917, 918, 3, 2, 2, 2, 918, 297, 3, 2, 2, 2, 919, 921, 9, 31, 2, 2, 920, 919, 3, 2, 2, 2, 921, 922, 3, 2, 2, 2, 922, 920, 3, 2, 2, 2, 922, 923, 3, 2, 2, 2, 923, 925, 3, 2, 2, 2, 924, 926, 5, 14, 7, 2, 925, 924, 3, 2, 2, 2, 925, 926, 3, 2, 2, 2, 926, 299, 3, 2, 2, 2, 927, 929, 9, 30, 2, 2, 928, 927, 3, 2, 2, 2, 929, 930, 3, 2, 2, 2, 930, 928, 3, 2, 2, 2, 930, 931, 3, 2, 2, 2, 931, 932, 3, 2, 2, 2, 932, 933, 5, 22, 11, 2, 933, 301, 3, 2, 2, 2, 934, 936, 9, 32, 2, 2, 935, 934, 3, 2, 2, 2, 936, 937, 3, 2, 2, 2, 937, 935, 3, 2, 2, 2, 937, 938, 3, 2, 2, 2, 938, 939, 3, 2, 2, 2, 939, 940, 9, 33, 2, 2, 940, 303, 3, 2, 2, 2, 941, 943, 9, 34, 2, 2, 942, 941, 3, 2, 2, 2, 943, 944, 3, 2, 2, 2, 944, 942, 3, 2, 2, 2, 944, 945, 3, 2, 2, 2, 945, 946, 3, 2, 2, 2, 946, 947, 5, 10, 5, 2, 947, 305, 3, 2, 2, 2, 948, 952, 7, 41, 2, 2, 949, 951, 10, 35, 2, 2, 950, 949, 3, 2, 2, 2, 951, 954, 3, 2, 2, 2, 952, 950, 3, 2, 2, 2, 952, 953, 3, 2, 2, 2, 953, 955, 3, 2, 2, 2, 954, 952, 3, 2, 2, 2, 955, 956, 7, 41, 2, 2, 956, 307, 3, 2, 2, 2, 957, 961, 7, 36, 2, 2, 958, 960, 10, 36, 2, 2, 959, 958, 3, 2, 2, 2, 960, 963, 3, 2, 2, 2, 961, 959, 3, 2, 2, 2, 961, 962, 3, 2, 2, 2, 962, 964, 3, 2, 2, 2, 963, 961, 3, 2, 2, 2, 964, 965, 7, 36, 2, 2, 965, 309, 3, 2, 2, 2, 966, 970, 9, 37, 2, 2, 967, 969, 9, 38, 2, 2, 968, 967, 3, 2, 2, 2, 969, 972, 3, 2, 2, 2, 970, 968, 3, 2, 2, 2, 970, 971, 3, 2, 2, 2, 971, 311, 3, 2, 2, 2, 972, 970, 3, 2, 2, 2, 973, 974, 5, 310, 155, 2, 974, 975, 7, 60, 2, 2, 975, 313, 3, 2, 2, 2, 976, 978, 10, 39, 2, 2, 977, 976, 3, 2, 2, 2, 978, 979, 3, 2, 2, 2, 979, 977, 3, 2, 2, 2, 979, 980, 3, 2, 2, 2, 980, 315, 3, 2, 2, 2, 981, 982, 7, 42, 2, 2, 982, 317, 3, 2, 2, 2, 983, 984, 7, 43, 2, 2, 984, 319, 3, 2, 2, 2, 985, 986, 7, 46, 2, 2, 986, 321, 3, 2, 2, 2, 987, 988, 7, 45, 2, 2, 988, 323, 3, 2, 2, 2, 989, 990, 7, 47, 2, 2, 990, 325, 3, 2, 2, 2, 991, 992, 7, 44, 2, 2, 992, 327, 3, 2, 2, 2, 993, 994, 7, 49, 2, 2, 994, 329, 3, 2, 2, 2, 995, 996, 7, 63, 2, 2, 996, 331, 3, 2, 2, 2, 997, 998, 7, 64, 2, 2, 998, 333, 3, 2, 2, 2, 999, 1000, 7, 64, 2, 2, 1000, 1001, 7, 63, 2, 2, 1001, 335, 3, 2, 2, 2, 1002, 1003, 7, 62, 2, 2, 1003, 337, 3, 2, 2, 2, 1004, 1005, 7, 62, 2, 2, 1005, 1006, 7, 63, 2, 2, 1006, 339, 3, 2, 2, 2, 1007, 1008, 7, 39, 2, 2, 1008, 341, 3, 2, 2, 2, 1009, 1010, 7, 64, 2, 2, 1010, 1011, 7, 64, 2, 2, 1011, 343, 3, 2, 2, 2, 1012, 1013, 7, 62, 2, 2, 1013, 1014, 7, 62, 2, 2, 1014, 345, 3, 2, 2, 2, 1015, 1016, 7, 35, 2, 2, 1016, 347, 3, 2, 2, 2, 1017, 1018, 7, 40, 2, 2, 1018, 349, 3, 2, 2, 2, 1019, 1020, 7, 126, 2, 2, 1020, 351, 3, 2, 2, 2, 1021, 1022, 7, 128, 2, 2, 1022, 353, 3, 2, 2, 2, 1023, 1025, 9, 29, 2, 2, 1024, 1023, 3, 2, 2, 2, 1025, 1026, 3, 2, 2, 2, 1026, 1024, 3, 2, 2, 2, 1026, 1027, 3, 2, 2, 2, 1027, 1028, 3, 2, 2, 2, 1028, 1029, 8, 177, 2, 2, 1029, 355, 3, 2, 2, 2, 1030, 1032, 7, 15, 2, 2, 1031, 1030, 3, 2, 2, 2, 1031, 1032, 3, 2, 2, 2, 1032, 1033, 3, 2, 2, 2, 1033, 1034, 7, 12, 2, 2, 1034, 357, 3, 2, 2, 2, 20, 2, 3, 363, 368, 379, 762, 917, 922, 925, 930, 937, 944, 952, 961, 970, 979, 1026, 1031, 6, 8, 2, 2, 7, 3, 2, 6, 2, 2, 2, 3, 2] \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.java b/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.java deleted file mode 100644 index a118ca5bf..000000000 --- a/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.java +++ /dev/null @@ -1,597 +0,0 @@ -// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 by ANTLR 4.9.2 -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class AsZ80Lexer extends Lexer { - static { RuntimeMetaData.checkVersion("4.9.2", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - COMMENT=1, COMMENT2=2, OPCODE_ADC=3, OPCODE_ADD=4, OPCODE_AND=5, OPCODE_BIT=6, - OPCODE_CALL=7, OPCODE_CCF=8, OPCODE_CP=9, OPCODE_CPD=10, OPCODE_CPDR=11, - OPCODE_CPI=12, OPCODE_CPIR=13, OPCODE_CPL=14, OPCODE_DAA=15, OPCODE_DEC=16, - OPCODE_DI=17, OPCODE_DJNZ=18, OPCODE_EI=19, OPCODE_EX=20, OPCODE_EXX=21, - OPCODE_HALT=22, OPCODE_IM=23, OPCODE_IN=24, OPCODE_INC=25, OPCODE_IND=26, - OPCODE_INDR=27, OPCODE_INI=28, OPCODE_INIR=29, OPCODE_JP=30, OPCODE_JR=31, - OPCODE_LD=32, OPCODE_LDD=33, OPCODE_LDDR=34, OPCODE_LDI=35, OPCODE_LDIR=36, - OPCODE_NEG=37, OPCODE_NOP=38, OPCODE_OR=39, OPCODE_OTDR=40, OPCODE_OTIR=41, - OPCODE_OUT=42, OPCODE_OUTD=43, OPCODE_OUTI=44, OPCODE_POP=45, OPCODE_PUSH=46, - OPCODE_RES=47, OPCODE_RET=48, OPCODE_RETI=49, OPCODE_RETN=50, OPCODE_RL=51, - OPCODE_RLA=52, OPCODE_RLC=53, OPCODE_RLCA=54, OPCODE_RLD=55, OPCODE_RR=56, - OPCODE_RRA=57, OPCODE_RRC=58, OPCODE_RRCA=59, OPCODE_RRD=60, OPCODE_RST=61, - OPCODE_SBC=62, OPCODE_SCF=63, OPCODE_SET=64, OPCODE_SLA=65, OPCODE_SRA=66, - OPCODE_SLL=67, OPCODE_SRL=68, OPCODE_SUB=69, OPCODE_XOR=70, COND_C=71, - COND_NC=72, COND_Z=73, COND_NZ=74, COND_M=75, COND_P=76, COND_PE=77, COND_PO=78, - COND_WS=79, COND_UNRECOGNIZED=80, PREP_ORG=81, PREP_EQU=82, PREP_SET=83, - PREP_VAR=84, PREP_IF=85, PREP_ENDIF=86, PREP_INCLUDE=87, PREP_MACRO=88, - PREP_ENDM=89, PREP_DB=90, PREP_DW=91, PREP_DS=92, PREP_ADDR=93, REG_A=94, - REG_B=95, REG_C=96, REG_D=97, REG_E=98, REG_H=99, REG_L=100, REG_IX=101, - REG_IXH=102, REG_IXL=103, REG_IY=104, REG_IYH=105, REG_IYL=106, REG_BC=107, - REG_DE=108, REG_HL=109, REG_SP=110, REG_AF=111, REG_AFF=112, REG_I=113, - REG_R=114, OP_MOD=115, OP_SHR=116, OP_SHL=117, OP_NOT=118, OP_AND=119, - OP_OR=120, OP_XOR=121, LIT_HEXNUMBER_1=122, LIT_NUMBER=123, LIT_HEXNUMBER_2=124, - LIT_OCTNUMBER=125, LIT_BINNUMBER=126, LIT_STRING_1=127, LIT_STRING_2=128, - ID_IDENTIFIER=129, ID_LABEL=130, ERROR=131, SEP_LPAR=132, SEP_RPAR=133, - SEP_COMMA=134, OP_ADD=135, OP_SUBTRACT=136, OP_MULTIPLY=137, OP_DIVIDE=138, - OP_EQUAL=139, OP_GT=140, OP_GTE=141, OP_LT=142, OP_LTE=143, OP_MOD_2=144, - OP_SHR_2=145, OP_SHL_2=146, OP_NOT_2=147, OP_AND_2=148, OP_OR_2=149, OP_XOR_2=150, - WS=151, EOL=152; - public static final int - CONDITION=1; - public static String[] channelNames = { - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }; - - public static String[] modeNames = { - "DEFAULT_MODE", "CONDITION" - }; - - private static String[] makeRuleNames() { - return new String[] { - "COMMENT", "COMMENT2", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", - "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", - "Z", "OPCODE_ADC", "OPCODE_ADD", "OPCODE_AND", "OPCODE_BIT", "OPCODE_CALL", - "OPCODE_CCF", "OPCODE_CP", "OPCODE_CPD", "OPCODE_CPDR", "OPCODE_CPI", - "OPCODE_CPIR", "OPCODE_CPL", "OPCODE_DAA", "OPCODE_DEC", "OPCODE_DI", - "OPCODE_DJNZ", "OPCODE_EI", "OPCODE_EX", "OPCODE_EXX", "OPCODE_HALT", - "OPCODE_IM", "OPCODE_IN", "OPCODE_INC", "OPCODE_IND", "OPCODE_INDR", - "OPCODE_INI", "OPCODE_INIR", "OPCODE_JP", "OPCODE_JR", "OPCODE_LD", "OPCODE_LDD", - "OPCODE_LDDR", "OPCODE_LDI", "OPCODE_LDIR", "OPCODE_NEG", "OPCODE_NOP", - "OPCODE_OR", "OPCODE_OTDR", "OPCODE_OTIR", "OPCODE_OUT", "OPCODE_OUTD", - "OPCODE_OUTI", "OPCODE_POP", "OPCODE_PUSH", "OPCODE_RES", "OPCODE_RET", - "OPCODE_RETI", "OPCODE_RETN", "OPCODE_RL", "OPCODE_RLA", "OPCODE_RLC", - "OPCODE_RLCA", "OPCODE_RLD", "OPCODE_RR", "OPCODE_RRA", "OPCODE_RRC", - "OPCODE_RRCA", "OPCODE_RRD", "OPCODE_RST", "OPCODE_SBC", "OPCODE_SCF", - "OPCODE_SET", "OPCODE_SLA", "OPCODE_SRA", "OPCODE_SLL", "OPCODE_SRL", - "OPCODE_SUB", "OPCODE_XOR", "COND_C", "COND_NC", "COND_Z", "COND_NZ", - "COND_M", "COND_P", "COND_PE", "COND_PO", "COND_WS", "COND_UNRECOGNIZED", - "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_VAR", "PREP_IF", "PREP_ENDIF", - "PREP_INCLUDE", "PREP_MACRO", "PREP_ENDM", "PREP_DB", "PREP_DW", "PREP_DS", - "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", "REG_E", "REG_H", "REG_L", - "REG_IX", "REG_IXH", "REG_IXL", "REG_IY", "REG_IYH", "REG_IYL", "REG_BC", - "REG_DE", "REG_HL", "REG_SP", "REG_AF", "REG_AFF", "REG_I", "REG_R", - "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", "OP_XOR", - "LIT_HEXNUMBER_1", "LIT_NUMBER", "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", - "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", - "ERROR", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", - "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_GT", "OP_GTE", "OP_LT", "OP_LTE", - "OP_MOD_2", "OP_SHR_2", "OP_SHL_2", "OP_NOT_2", "OP_AND_2", "OP_OR_2", - "OP_XOR_2", "WS", "EOL" - }; - } - public static final String[] ruleNames = makeRuleNames(); - - private static String[] makeLiteralNames() { - return new String[] { - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, "'$'", null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - "'('", "')'", "','", "'+'", "'-'", "'*'", "'/'", "'='", "'>'", "'>='", - "'<'", "'<='", "'%'", "'>>'", "'<<'", "'!'", "'&'", "'|'", "'~'" - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - null, "COMMENT", "COMMENT2", "OPCODE_ADC", "OPCODE_ADD", "OPCODE_AND", - "OPCODE_BIT", "OPCODE_CALL", "OPCODE_CCF", "OPCODE_CP", "OPCODE_CPD", - "OPCODE_CPDR", "OPCODE_CPI", "OPCODE_CPIR", "OPCODE_CPL", "OPCODE_DAA", - "OPCODE_DEC", "OPCODE_DI", "OPCODE_DJNZ", "OPCODE_EI", "OPCODE_EX", "OPCODE_EXX", - "OPCODE_HALT", "OPCODE_IM", "OPCODE_IN", "OPCODE_INC", "OPCODE_IND", - "OPCODE_INDR", "OPCODE_INI", "OPCODE_INIR", "OPCODE_JP", "OPCODE_JR", - "OPCODE_LD", "OPCODE_LDD", "OPCODE_LDDR", "OPCODE_LDI", "OPCODE_LDIR", - "OPCODE_NEG", "OPCODE_NOP", "OPCODE_OR", "OPCODE_OTDR", "OPCODE_OTIR", - "OPCODE_OUT", "OPCODE_OUTD", "OPCODE_OUTI", "OPCODE_POP", "OPCODE_PUSH", - "OPCODE_RES", "OPCODE_RET", "OPCODE_RETI", "OPCODE_RETN", "OPCODE_RL", - "OPCODE_RLA", "OPCODE_RLC", "OPCODE_RLCA", "OPCODE_RLD", "OPCODE_RR", - "OPCODE_RRA", "OPCODE_RRC", "OPCODE_RRCA", "OPCODE_RRD", "OPCODE_RST", - "OPCODE_SBC", "OPCODE_SCF", "OPCODE_SET", "OPCODE_SLA", "OPCODE_SRA", - "OPCODE_SLL", "OPCODE_SRL", "OPCODE_SUB", "OPCODE_XOR", "COND_C", "COND_NC", - "COND_Z", "COND_NZ", "COND_M", "COND_P", "COND_PE", "COND_PO", "COND_WS", - "COND_UNRECOGNIZED", "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_VAR", - "PREP_IF", "PREP_ENDIF", "PREP_INCLUDE", "PREP_MACRO", "PREP_ENDM", "PREP_DB", - "PREP_DW", "PREP_DS", "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", - "REG_E", "REG_H", "REG_L", "REG_IX", "REG_IXH", "REG_IXL", "REG_IY", - "REG_IYH", "REG_IYL", "REG_BC", "REG_DE", "REG_HL", "REG_SP", "REG_AF", - "REG_AFF", "REG_I", "REG_R", "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", - "OP_AND", "OP_OR", "OP_XOR", "LIT_HEXNUMBER_1", "LIT_NUMBER", "LIT_HEXNUMBER_2", - "LIT_OCTNUMBER", "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", - "ID_LABEL", "ERROR", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", - "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_GT", "OP_GTE", "OP_LT", "OP_LTE", - "OP_MOD_2", "OP_SHR_2", "OP_SHL_2", "OP_NOT_2", "OP_AND_2", "OP_OR_2", - "OP_XOR_2", "WS", "EOL" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - - public AsZ80Lexer(CharStream input) { - super(input); - _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - @Override - public String getGrammarFileName() { return "AsZ80Lexer.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public String[] getChannelNames() { return channelNames; } - - @Override - public String[] getModeNames() { return modeNames; } - - @Override - public ATN getATN() { return _ATN; } - - @Override - public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { - switch (ruleIndex) { - case 104: - return COND_UNRECOGNIZED_sempred((RuleContext)_localctx, predIndex); - } - return true; - } - private boolean COND_UNRECOGNIZED_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 0: - return true; - } - return true; - } - - public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u009a\u040b\b\1\b"+ - "\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n"+ - "\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21"+ - "\4\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30"+ - "\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37"+ - "\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t"+ - "*\4+\t+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63"+ - "\4\64\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t"+ - "<\4=\t=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4"+ - "H\tH\4I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\t"+ - "S\4T\tT\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^"+ - "\4_\t_\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j"+ - "\tj\4k\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu"+ - "\4v\tv\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080"+ - "\t\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084"+ - "\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089"+ - "\t\u0089\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c\t\u008c\4\u008d\t\u008d"+ - "\4\u008e\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090\4\u0091\t\u0091\4\u0092"+ - "\t\u0092\4\u0093\t\u0093\4\u0094\t\u0094\4\u0095\t\u0095\4\u0096\t\u0096"+ - "\4\u0097\t\u0097\4\u0098\t\u0098\4\u0099\t\u0099\4\u009a\t\u009a\4\u009b"+ - "\t\u009b\4\u009c\t\u009c\4\u009d\t\u009d\4\u009e\t\u009e\4\u009f\t\u009f"+ - "\4\u00a0\t\u00a0\4\u00a1\t\u00a1\4\u00a2\t\u00a2\4\u00a3\t\u00a3\4\u00a4"+ - "\t\u00a4\4\u00a5\t\u00a5\4\u00a6\t\u00a6\4\u00a7\t\u00a7\4\u00a8\t\u00a8"+ - "\4\u00a9\t\u00a9\4\u00aa\t\u00aa\4\u00ab\t\u00ab\4\u00ac\t\u00ac\4\u00ad"+ - "\t\u00ad\4\u00ae\t\u00ae\4\u00af\t\u00af\4\u00b0\t\u00b0\4\u00b1\t\u00b1"+ - "\4\u00b2\t\u00b2\3\2\3\2\3\2\3\2\3\2\5\2\u016c\n\2\3\2\7\2\u016f\n\2\f"+ - "\2\16\2\u0172\13\2\3\2\3\2\3\3\3\3\3\3\3\3\7\3\u017a\n\3\f\3\16\3\u017d"+ - "\13\3\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t"+ - "\3\t\3\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3"+ - "\21\3\21\3\22\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3"+ - "\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\35\3\35\3"+ - "\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3!\3!\3!\3"+ - "!\3\"\3\"\3\"\3\"\3#\3#\3#\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3\'"+ - "\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3+\3,\3,\3"+ - ",\3,\3,\3-\3-\3-\3.\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\3\61\3"+ - "\61\3\61\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\65\3"+ - "\65\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\3\67\38\38"+ - "\38\38\38\39\39\39\39\39\3:\3:\3:\3;\3;\3;\3;\3<\3<\3<\3<\3<\3=\3=\3="+ - "\3=\3>\3>\3>\3>\3>\3?\3?\3?\3?\3@\3@\3@\3@\3A\3A\3A\3B\3B\3B\3B\3B\3C"+ - "\3C\3C\3C\3C\3D\3D\3D\3D\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3G\3G\3G\3G\3H"+ - "\3H\3H\3H\3H\3I\3I\3I\3I\3J\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3L\3L\3L\3L"+ - "\3L\3M\3M\3M\3N\3N\3N\3N\3O\3O\3O\3O\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3R\3R"+ - "\3R\3S\3S\3S\3S\3T\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3V\3V\3W\3W\3W\3W\3X"+ - "\3X\3X\3X\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3]\3]\3"+ - "]\3]\3^\3^\3^\3^\3_\3_\3_\3_\3`\3`\3`\3`\3a\3a\3a\3a\3b\3b\3b\3b\3b\3"+ - "c\3c\3c\3c\3d\3d\3d\3d\3d\3e\3e\3e\3e\3f\3f\3f\3f\3g\3g\3g\3g\3g\3h\3"+ - "h\3h\3h\3h\3i\6i\u02f9\ni\ri\16i\u02fa\3i\3i\3j\3j\3j\3j\3j\3k\3k\3k\3"+ - "k\3l\3l\3l\3l\3m\3m\3m\3m\3n\3n\3n\3n\3o\3o\3o\3p\3p\3p\3p\3p\3p\3q\3"+ - "q\3q\3q\3q\3q\3q\3q\3r\3r\3r\3r\3r\3r\3s\3s\3s\3s\3s\3t\3t\3t\3u\3u\3"+ - "u\3v\3v\3v\3w\3w\3x\3x\3y\3y\3z\3z\3{\3{\3|\3|\3}\3}\3~\3~\3\177\3\177"+ - "\3\177\3\u0080\3\u0080\3\u0080\3\u0080\3\u0081\3\u0081\3\u0081\3\u0081"+ - "\3\u0082\3\u0082\3\u0082\3\u0083\3\u0083\3\u0083\3\u0083\3\u0084\3\u0084"+ - "\3\u0084\3\u0084\3\u0085\3\u0085\3\u0085\3\u0086\3\u0086\3\u0086\3\u0087"+ - "\3\u0087\3\u0087\3\u0088\3\u0088\3\u0088\3\u0089\3\u0089\3\u0089\3\u008a"+ - "\3\u008a\3\u008a\3\u008a\3\u008b\3\u008b\3\u008c\3\u008c\3\u008d\3\u008d"+ - "\3\u008d\3\u008d\3\u008e\3\u008e\3\u008e\3\u008e\3\u008f\3\u008f\3\u008f"+ - "\3\u008f\3\u0090\3\u0090\3\u0090\3\u0090\3\u0091\3\u0091\3\u0091\3\u0091"+ - "\3\u0092\3\u0092\3\u0092\3\u0093\3\u0093\3\u0093\3\u0093\3\u0094\3\u0094"+ - "\3\u0094\6\u0094\u0394\n\u0094\r\u0094\16\u0094\u0395\3\u0095\6\u0095"+ - "\u0399\n\u0095\r\u0095\16\u0095\u039a\3\u0095\5\u0095\u039e\n\u0095\3"+ - "\u0096\6\u0096\u03a1\n\u0096\r\u0096\16\u0096\u03a2\3\u0096\3\u0096\3"+ - "\u0097\6\u0097\u03a8\n\u0097\r\u0097\16\u0097\u03a9\3\u0097\3\u0097\3"+ - "\u0098\6\u0098\u03af\n\u0098\r\u0098\16\u0098\u03b0\3\u0098\3\u0098\3"+ - "\u0099\3\u0099\7\u0099\u03b7\n\u0099\f\u0099\16\u0099\u03ba\13\u0099\3"+ - "\u0099\3\u0099\3\u009a\3\u009a\7\u009a\u03c0\n\u009a\f\u009a\16\u009a"+ - "\u03c3\13\u009a\3\u009a\3\u009a\3\u009b\3\u009b\7\u009b\u03c9\n\u009b"+ - "\f\u009b\16\u009b\u03cc\13\u009b\3\u009c\3\u009c\3\u009c\3\u009d\6\u009d"+ - "\u03d2\n\u009d\r\u009d\16\u009d\u03d3\3\u009e\3\u009e\3\u009f\3\u009f"+ - "\3\u00a0\3\u00a0\3\u00a1\3\u00a1\3\u00a2\3\u00a2\3\u00a3\3\u00a3\3\u00a4"+ - "\3\u00a4\3\u00a5\3\u00a5\3\u00a6\3\u00a6\3\u00a7\3\u00a7\3\u00a7\3\u00a8"+ - "\3\u00a8\3\u00a9\3\u00a9\3\u00a9\3\u00aa\3\u00aa\3\u00ab\3\u00ab\3\u00ab"+ - "\3\u00ac\3\u00ac\3\u00ac\3\u00ad\3\u00ad\3\u00ae\3\u00ae\3\u00af\3\u00af"+ - "\3\u00b0\3\u00b0\3\u00b1\6\u00b1\u0401\n\u00b1\r\u00b1\16\u00b1\u0402"+ - "\3\u00b1\3\u00b1\3\u00b2\5\u00b2\u0408\n\u00b2\3\u00b2\3\u00b2\3\u017b"+ - "\2\u00b3\4\3\6\4\b\2\n\2\f\2\16\2\20\2\22\2\24\2\26\2\30\2\32\2\34\2\36"+ - "\2 \2\"\2$\2&\2(\2*\2,\2.\2\60\2\62\2\64\2\66\28\2:\5<\6>\7@\bB\tD\nF"+ - "\13H\fJ\rL\16N\17P\20R\21T\22V\23X\24Z\25\\\26^\27`\30b\31d\32f\33h\34"+ - "j\35l\36n\37p r!t\"v#x$z%|&~\'\u0080(\u0082)\u0084*\u0086+\u0088,\u008a"+ - "-\u008c.\u008e/\u0090\60\u0092\61\u0094\62\u0096\63\u0098\64\u009a\65"+ - "\u009c\66\u009e\67\u00a08\u00a29\u00a4:\u00a6;\u00a8<\u00aa=\u00ac>\u00ae"+ - "?\u00b0@\u00b2A\u00b4B\u00b6C\u00b8D\u00baE\u00bcF\u00beG\u00c0H\u00c2"+ - "I\u00c4J\u00c6K\u00c8L\u00caM\u00ccN\u00ceO\u00d0P\u00d2Q\u00d4R\u00d6"+ - "S\u00d8T\u00daU\u00dcV\u00deW\u00e0X\u00e2Y\u00e4Z\u00e6[\u00e8\\\u00ea"+ - "]\u00ec^\u00ee_\u00f0`\u00f2a\u00f4b\u00f6c\u00f8d\u00fae\u00fcf\u00fe"+ - "g\u0100h\u0102i\u0104j\u0106k\u0108l\u010am\u010cn\u010eo\u0110p\u0112"+ - "q\u0114r\u0116s\u0118t\u011au\u011cv\u011ew\u0120x\u0122y\u0124z\u0126"+ - "{\u0128|\u012a}\u012c~\u012e\177\u0130\u0080\u0132\u0081\u0134\u0082\u0136"+ - "\u0083\u0138\u0084\u013a\u0085\u013c\u0086\u013e\u0087\u0140\u0088\u0142"+ - "\u0089\u0144\u008a\u0146\u008b\u0148\u008c\u014a\u008d\u014c\u008e\u014e"+ - "\u008f\u0150\u0090\u0152\u0091\u0154\u0092\u0156\u0093\u0158\u0094\u015a"+ - "\u0095\u015c\u0096\u015e\u0097\u0160\u0098\u0162\u0099\u0164\u009a\4\2"+ - "\3(\4\2%%==\4\2\f\f\17\17\4\2CCcc\4\2DDdd\4\2EEee\4\2FFff\4\2GGgg\4\2"+ - "HHhh\4\2IIii\4\2JJjj\4\2KKkk\4\2LLll\4\2NNnn\4\2OOoo\4\2PPpp\4\2QQqq\4"+ - "\2RRrr\4\2SSss\4\2TTtt\4\2UUuu\4\2VVvv\4\2WWww\4\2XXxx\4\2YYyy\4\2ZZz"+ - "z\4\2[[{{\4\2\\\\||\5\2\13\13\16\16\"\"\5\2\62;CHch\3\2\62;\3\2\629\6"+ - "\2QQSSqqss\3\2\62\63\3\2))\3\2$$\5\2A\\aac|\6\2\62;A\\aac|\b\2\13\f\16"+ - "\17\"\"*/\61\61??\2\u0401\2\4\3\2\2\2\2\6\3\2\2\2\2:\3\2\2\2\2<\3\2\2"+ - "\2\2>\3\2\2\2\2@\3\2\2\2\2B\3\2\2\2\2D\3\2\2\2\2F\3\2\2\2\2H\3\2\2\2\2"+ - "J\3\2\2\2\2L\3\2\2\2\2N\3\2\2\2\2P\3\2\2\2\2R\3\2\2\2\2T\3\2\2\2\2V\3"+ - "\2\2\2\2X\3\2\2\2\2Z\3\2\2\2\2\\\3\2\2\2\2^\3\2\2\2\2`\3\2\2\2\2b\3\2"+ - "\2\2\2d\3\2\2\2\2f\3\2\2\2\2h\3\2\2\2\2j\3\2\2\2\2l\3\2\2\2\2n\3\2\2\2"+ - "\2p\3\2\2\2\2r\3\2\2\2\2t\3\2\2\2\2v\3\2\2\2\2x\3\2\2\2\2z\3\2\2\2\2|"+ - "\3\2\2\2\2~\3\2\2\2\2\u0080\3\2\2\2\2\u0082\3\2\2\2\2\u0084\3\2\2\2\2"+ - "\u0086\3\2\2\2\2\u0088\3\2\2\2\2\u008a\3\2\2\2\2\u008c\3\2\2\2\2\u008e"+ - "\3\2\2\2\2\u0090\3\2\2\2\2\u0092\3\2\2\2\2\u0094\3\2\2\2\2\u0096\3\2\2"+ - "\2\2\u0098\3\2\2\2\2\u009a\3\2\2\2\2\u009c\3\2\2\2\2\u009e\3\2\2\2\2\u00a0"+ - "\3\2\2\2\2\u00a2\3\2\2\2\2\u00a4\3\2\2\2\2\u00a6\3\2\2\2\2\u00a8\3\2\2"+ - "\2\2\u00aa\3\2\2\2\2\u00ac\3\2\2\2\2\u00ae\3\2\2\2\2\u00b0\3\2\2\2\2\u00b2"+ - "\3\2\2\2\2\u00b4\3\2\2\2\2\u00b6\3\2\2\2\2\u00b8\3\2\2\2\2\u00ba\3\2\2"+ - "\2\2\u00bc\3\2\2\2\2\u00be\3\2\2\2\2\u00c0\3\2\2\2\2\u00d6\3\2\2\2\2\u00d8"+ - "\3\2\2\2\2\u00da\3\2\2\2\2\u00dc\3\2\2\2\2\u00de\3\2\2\2\2\u00e0\3\2\2"+ - "\2\2\u00e2\3\2\2\2\2\u00e4\3\2\2\2\2\u00e6\3\2\2\2\2\u00e8\3\2\2\2\2\u00ea"+ - "\3\2\2\2\2\u00ec\3\2\2\2\2\u00ee\3\2\2\2\2\u00f0\3\2\2\2\2\u00f2\3\2\2"+ - "\2\2\u00f4\3\2\2\2\2\u00f6\3\2\2\2\2\u00f8\3\2\2\2\2\u00fa\3\2\2\2\2\u00fc"+ - "\3\2\2\2\2\u00fe\3\2\2\2\2\u0100\3\2\2\2\2\u0102\3\2\2\2\2\u0104\3\2\2"+ - "\2\2\u0106\3\2\2\2\2\u0108\3\2\2\2\2\u010a\3\2\2\2\2\u010c\3\2\2\2\2\u010e"+ - "\3\2\2\2\2\u0110\3\2\2\2\2\u0112\3\2\2\2\2\u0114\3\2\2\2\2\u0116\3\2\2"+ - "\2\2\u0118\3\2\2\2\2\u011a\3\2\2\2\2\u011c\3\2\2\2\2\u011e\3\2\2\2\2\u0120"+ - "\3\2\2\2\2\u0122\3\2\2\2\2\u0124\3\2\2\2\2\u0126\3\2\2\2\2\u0128\3\2\2"+ - "\2\2\u012a\3\2\2\2\2\u012c\3\2\2\2\2\u012e\3\2\2\2\2\u0130\3\2\2\2\2\u0132"+ - "\3\2\2\2\2\u0134\3\2\2\2\2\u0136\3\2\2\2\2\u0138\3\2\2\2\2\u013a\3\2\2"+ - "\2\2\u013c\3\2\2\2\2\u013e\3\2\2\2\2\u0140\3\2\2\2\2\u0142\3\2\2\2\2\u0144"+ - "\3\2\2\2\2\u0146\3\2\2\2\2\u0148\3\2\2\2\2\u014a\3\2\2\2\2\u014c\3\2\2"+ - "\2\2\u014e\3\2\2\2\2\u0150\3\2\2\2\2\u0152\3\2\2\2\2\u0154\3\2\2\2\2\u0156"+ - "\3\2\2\2\2\u0158\3\2\2\2\2\u015a\3\2\2\2\2\u015c\3\2\2\2\2\u015e\3\2\2"+ - "\2\2\u0160\3\2\2\2\2\u0162\3\2\2\2\2\u0164\3\2\2\2\3\u00c2\3\2\2\2\3\u00c4"+ - "\3\2\2\2\3\u00c6\3\2\2\2\3\u00c8\3\2\2\2\3\u00ca\3\2\2\2\3\u00cc\3\2\2"+ - "\2\3\u00ce\3\2\2\2\3\u00d0\3\2\2\2\3\u00d2\3\2\2\2\3\u00d4\3\2\2\2\4\u016b"+ - "\3\2\2\2\6\u0175\3\2\2\2\b\u0183\3\2\2\2\n\u0185\3\2\2\2\f\u0187\3\2\2"+ - "\2\16\u0189\3\2\2\2\20\u018b\3\2\2\2\22\u018d\3\2\2\2\24\u018f\3\2\2\2"+ - "\26\u0191\3\2\2\2\30\u0193\3\2\2\2\32\u0195\3\2\2\2\34\u0197\3\2\2\2\36"+ - "\u0199\3\2\2\2 \u019b\3\2\2\2\"\u019d\3\2\2\2$\u019f\3\2\2\2&\u01a1\3"+ - "\2\2\2(\u01a3\3\2\2\2*\u01a5\3\2\2\2,\u01a7\3\2\2\2.\u01a9\3\2\2\2\60"+ - "\u01ab\3\2\2\2\62\u01ad\3\2\2\2\64\u01af\3\2\2\2\66\u01b1\3\2\2\28\u01b3"+ - "\3\2\2\2:\u01b5\3\2\2\2<\u01b9\3\2\2\2>\u01bd\3\2\2\2@\u01c1\3\2\2\2B"+ - "\u01c5\3\2\2\2D\u01cc\3\2\2\2F\u01d0\3\2\2\2H\u01d3\3\2\2\2J\u01d7\3\2"+ - "\2\2L\u01dc\3\2\2\2N\u01e0\3\2\2\2P\u01e5\3\2\2\2R\u01e9\3\2\2\2T\u01ed"+ - "\3\2\2\2V\u01f1\3\2\2\2X\u01f4\3\2\2\2Z\u01f9\3\2\2\2\\\u01fc\3\2\2\2"+ - "^\u01ff\3\2\2\2`\u0203\3\2\2\2b\u0208\3\2\2\2d\u020b\3\2\2\2f\u020e\3"+ - "\2\2\2h\u0212\3\2\2\2j\u0216\3\2\2\2l\u021b\3\2\2\2n\u021f\3\2\2\2p\u0224"+ - "\3\2\2\2r\u0229\3\2\2\2t\u022e\3\2\2\2v\u0231\3\2\2\2x\u0235\3\2\2\2z"+ - "\u023a\3\2\2\2|\u023e\3\2\2\2~\u0243\3\2\2\2\u0080\u0247\3\2\2\2\u0082"+ - "\u024b\3\2\2\2\u0084\u024e\3\2\2\2\u0086\u0253\3\2\2\2\u0088\u0258\3\2"+ - "\2\2\u008a\u025c\3\2\2\2\u008c\u0261\3\2\2\2\u008e\u0266\3\2\2\2\u0090"+ - "\u026a\3\2\2\2\u0092\u026f\3\2\2\2\u0094\u0273\3\2\2\2\u0096\u0279\3\2"+ - "\2\2\u0098\u027e\3\2\2\2\u009a\u0283\3\2\2\2\u009c\u0286\3\2\2\2\u009e"+ - "\u028a\3\2\2\2\u00a0\u028e\3\2\2\2\u00a2\u0293\3\2\2\2\u00a4\u0297\3\2"+ - "\2\2\u00a6\u029a\3\2\2\2\u00a8\u029e\3\2\2\2\u00aa\u02a2\3\2\2\2\u00ac"+ - "\u02a7\3\2\2\2\u00ae\u02ab\3\2\2\2\u00b0\u02af\3\2\2\2\u00b2\u02b3\3\2"+ - "\2\2\u00b4\u02b7\3\2\2\2\u00b6\u02bb\3\2\2\2\u00b8\u02bf\3\2\2\2\u00ba"+ - "\u02c3\3\2\2\2\u00bc\u02c7\3\2\2\2\u00be\u02cb\3\2\2\2\u00c0\u02cf\3\2"+ - "\2\2\u00c2\u02d3\3\2\2\2\u00c4\u02d7\3\2\2\2\u00c6\u02dc\3\2\2\2\u00c8"+ - "\u02e0\3\2\2\2\u00ca\u02e5\3\2\2\2\u00cc\u02e9\3\2\2\2\u00ce\u02ed\3\2"+ - "\2\2\u00d0\u02f2\3\2\2\2\u00d2\u02f8\3\2\2\2\u00d4\u02fe\3\2\2\2\u00d6"+ - "\u0303\3\2\2\2\u00d8\u0307\3\2\2\2\u00da\u030b\3\2\2\2\u00dc\u030f\3\2"+ - "\2\2\u00de\u0313\3\2\2\2\u00e0\u0316\3\2\2\2\u00e2\u031c\3\2\2\2\u00e4"+ - "\u0324\3\2\2\2\u00e6\u032a\3\2\2\2\u00e8\u032f\3\2\2\2\u00ea\u0332\3\2"+ - "\2\2\u00ec\u0335\3\2\2\2\u00ee\u0338\3\2\2\2\u00f0\u033a\3\2\2\2\u00f2"+ - "\u033c\3\2\2\2\u00f4\u033e\3\2\2\2\u00f6\u0340\3\2\2\2\u00f8\u0342\3\2"+ - "\2\2\u00fa\u0344\3\2\2\2\u00fc\u0346\3\2\2\2\u00fe\u0348\3\2\2\2\u0100"+ - "\u034b\3\2\2\2\u0102\u034f\3\2\2\2\u0104\u0353\3\2\2\2\u0106\u0356\3\2"+ - "\2\2\u0108\u035a\3\2\2\2\u010a\u035e\3\2\2\2\u010c\u0361\3\2\2\2\u010e"+ - "\u0364\3\2\2\2\u0110\u0367\3\2\2\2\u0112\u036a\3\2\2\2\u0114\u036d\3\2"+ - "\2\2\u0116\u0371\3\2\2\2\u0118\u0373\3\2\2\2\u011a\u0375\3\2\2\2\u011c"+ - "\u0379\3\2\2\2\u011e\u037d\3\2\2\2\u0120\u0381\3\2\2\2\u0122\u0385\3\2"+ - "\2\2\u0124\u0389\3\2\2\2\u0126\u038c\3\2\2\2\u0128\u0390\3\2\2\2\u012a"+ - "\u0398\3\2\2\2\u012c\u03a0\3\2\2\2\u012e\u03a7\3\2\2\2\u0130\u03ae\3\2"+ - "\2\2\u0132\u03b4\3\2\2\2\u0134\u03bd\3\2\2\2\u0136\u03c6\3\2\2\2\u0138"+ - "\u03cd\3\2\2\2\u013a\u03d1\3\2\2\2\u013c\u03d5\3\2\2\2\u013e\u03d7\3\2"+ - "\2\2\u0140\u03d9\3\2\2\2\u0142\u03db\3\2\2\2\u0144\u03dd\3\2\2\2\u0146"+ - "\u03df\3\2\2\2\u0148\u03e1\3\2\2\2\u014a\u03e3\3\2\2\2\u014c\u03e5\3\2"+ - "\2\2\u014e\u03e7\3\2\2\2\u0150\u03ea\3\2\2\2\u0152\u03ec\3\2\2\2\u0154"+ - "\u03ef\3\2\2\2\u0156\u03f1\3\2\2\2\u0158\u03f4\3\2\2\2\u015a\u03f7\3\2"+ - "\2\2\u015c\u03f9\3\2\2\2\u015e\u03fb\3\2\2\2\u0160\u03fd\3\2\2\2\u0162"+ - "\u0400\3\2\2\2\u0164\u0407\3\2\2\2\u0166\u0167\7\61\2\2\u0167\u016c\7"+ - "\61\2\2\u0168\u0169\7/\2\2\u0169\u016c\7/\2\2\u016a\u016c\t\2\2\2\u016b"+ - "\u0166\3\2\2\2\u016b\u0168\3\2\2\2\u016b\u016a\3\2\2\2\u016c\u0170\3\2"+ - "\2\2\u016d\u016f\n\3\2\2\u016e\u016d\3\2\2\2\u016f\u0172\3\2\2\2\u0170"+ - "\u016e\3\2\2\2\u0170\u0171\3\2\2\2\u0171\u0173\3\2\2\2\u0172\u0170\3\2"+ - "\2\2\u0173\u0174\b\2\2\2\u0174\5\3\2\2\2\u0175\u0176\7\61\2\2\u0176\u0177"+ - "\7,\2\2\u0177\u017b\3\2\2\2\u0178\u017a\13\2\2\2\u0179\u0178\3\2\2\2\u017a"+ - "\u017d\3\2\2\2\u017b\u017c\3\2\2\2\u017b\u0179\3\2\2\2\u017c\u017e\3\2"+ - "\2\2\u017d\u017b\3\2\2\2\u017e\u017f\7,\2\2\u017f\u0180\7\61\2\2\u0180"+ - "\u0181\3\2\2\2\u0181\u0182\b\3\2\2\u0182\7\3\2\2\2\u0183\u0184\t\4\2\2"+ - "\u0184\t\3\2\2\2\u0185\u0186\t\5\2\2\u0186\13\3\2\2\2\u0187\u0188\t\6"+ - "\2\2\u0188\r\3\2\2\2\u0189\u018a\t\7\2\2\u018a\17\3\2\2\2\u018b\u018c"+ - "\t\b\2\2\u018c\21\3\2\2\2\u018d\u018e\t\t\2\2\u018e\23\3\2\2\2\u018f\u0190"+ - "\t\n\2\2\u0190\25\3\2\2\2\u0191\u0192\t\13\2\2\u0192\27\3\2\2\2\u0193"+ - "\u0194\t\f\2\2\u0194\31\3\2\2\2\u0195\u0196\t\r\2\2\u0196\33\3\2\2\2\u0197"+ - "\u0198\t\16\2\2\u0198\35\3\2\2\2\u0199\u019a\t\17\2\2\u019a\37\3\2\2\2"+ - "\u019b\u019c\t\20\2\2\u019c!\3\2\2\2\u019d\u019e\t\21\2\2\u019e#\3\2\2"+ - "\2\u019f\u01a0\t\22\2\2\u01a0%\3\2\2\2\u01a1\u01a2\t\23\2\2\u01a2\'\3"+ - "\2\2\2\u01a3\u01a4\t\24\2\2\u01a4)\3\2\2\2\u01a5\u01a6\t\25\2\2\u01a6"+ - "+\3\2\2\2\u01a7\u01a8\t\26\2\2\u01a8-\3\2\2\2\u01a9\u01aa\t\27\2\2\u01aa"+ - "/\3\2\2\2\u01ab\u01ac\t\30\2\2\u01ac\61\3\2\2\2\u01ad\u01ae\t\31\2\2\u01ae"+ - "\63\3\2\2\2\u01af\u01b0\t\32\2\2\u01b0\65\3\2\2\2\u01b1\u01b2\t\33\2\2"+ - "\u01b2\67\3\2\2\2\u01b3\u01b4\t\34\2\2\u01b49\3\2\2\2\u01b5\u01b6\5\b"+ - "\4\2\u01b6\u01b7\5\16\7\2\u01b7\u01b8\5\f\6\2\u01b8;\3\2\2\2\u01b9\u01ba"+ - "\5\b\4\2\u01ba\u01bb\5\16\7\2\u01bb\u01bc\5\16\7\2\u01bc=\3\2\2\2\u01bd"+ - "\u01be\5\b\4\2\u01be\u01bf\5 \20\2\u01bf\u01c0\5\16\7\2\u01c0?\3\2\2\2"+ - "\u01c1\u01c2\5\n\5\2\u01c2\u01c3\5\30\f\2\u01c3\u01c4\5,\26\2\u01c4A\3"+ - "\2\2\2\u01c5\u01c6\5\f\6\2\u01c6\u01c7\5\b\4\2\u01c7\u01c8\5\34\16\2\u01c8"+ - "\u01c9\5\34\16\2\u01c9\u01ca\3\2\2\2\u01ca\u01cb\b!\3\2\u01cbC\3\2\2\2"+ - "\u01cc\u01cd\5\f\6\2\u01cd\u01ce\5\f\6\2\u01ce\u01cf\5\22\t\2\u01cfE\3"+ - "\2\2\2\u01d0\u01d1\5\f\6\2\u01d1\u01d2\5$\22\2\u01d2G\3\2\2\2\u01d3\u01d4"+ - "\5\f\6\2\u01d4\u01d5\5$\22\2\u01d5\u01d6\5\16\7\2\u01d6I\3\2\2\2\u01d7"+ - "\u01d8\5\f\6\2\u01d8\u01d9\5$\22\2\u01d9\u01da\5\16\7\2\u01da\u01db\5"+ - "(\24\2\u01dbK\3\2\2\2\u01dc\u01dd\5\f\6\2\u01dd\u01de\5$\22\2\u01de\u01df"+ - "\5\30\f\2\u01dfM\3\2\2\2\u01e0\u01e1\5\f\6\2\u01e1\u01e2\5$\22\2\u01e2"+ - "\u01e3\5\30\f\2\u01e3\u01e4\5(\24\2\u01e4O\3\2\2\2\u01e5\u01e6\5\f\6\2"+ - "\u01e6\u01e7\5$\22\2\u01e7\u01e8\5\34\16\2\u01e8Q\3\2\2\2\u01e9\u01ea"+ - "\5\16\7\2\u01ea\u01eb\5\b\4\2\u01eb\u01ec\5\b\4\2\u01ecS\3\2\2\2\u01ed"+ - "\u01ee\5\16\7\2\u01ee\u01ef\5\20\b\2\u01ef\u01f0\5\f\6\2\u01f0U\3\2\2"+ - "\2\u01f1\u01f2\5\16\7\2\u01f2\u01f3\5\30\f\2\u01f3W\3\2\2\2\u01f4\u01f5"+ - "\5\16\7\2\u01f5\u01f6\5\32\r\2\u01f6\u01f7\5 \20\2\u01f7\u01f8\58\34\2"+ - "\u01f8Y\3\2\2\2\u01f9\u01fa\5\20\b\2\u01fa\u01fb\5\30\f\2\u01fb[\3\2\2"+ - "\2\u01fc\u01fd\5\20\b\2\u01fd\u01fe\5\64\32\2\u01fe]\3\2\2\2\u01ff\u0200"+ - "\5\20\b\2\u0200\u0201\5\64\32\2\u0201\u0202\5\64\32\2\u0202_\3\2\2\2\u0203"+ - "\u0204\5\26\13\2\u0204\u0205\5\b\4\2\u0205\u0206\5\34\16\2\u0206\u0207"+ - "\5,\26\2\u0207a\3\2\2\2\u0208\u0209\5\30\f\2\u0209\u020a\5\36\17\2\u020a"+ - "c\3\2\2\2\u020b\u020c\5\30\f\2\u020c\u020d\5 \20\2\u020de\3\2\2\2\u020e"+ - "\u020f\5\30\f\2\u020f\u0210\5 \20\2\u0210\u0211\5\f\6\2\u0211g\3\2\2\2"+ - "\u0212\u0213\5\30\f\2\u0213\u0214\5 \20\2\u0214\u0215\5\16\7\2\u0215i"+ - "\3\2\2\2\u0216\u0217\5\30\f\2\u0217\u0218\5 \20\2\u0218\u0219\5\16\7\2"+ - "\u0219\u021a\5(\24\2\u021ak\3\2\2\2\u021b\u021c\5\30\f\2\u021c\u021d\5"+ - " \20\2\u021d\u021e\5\30\f\2\u021em\3\2\2\2\u021f\u0220\5\30\f\2\u0220"+ - "\u0221\5 \20\2\u0221\u0222\5\30\f\2\u0222\u0223\5(\24\2\u0223o\3\2\2\2"+ - "\u0224\u0225\5\32\r\2\u0225\u0226\5$\22\2\u0226\u0227\3\2\2\2\u0227\u0228"+ - "\b8\3\2\u0228q\3\2\2\2\u0229\u022a\5\32\r\2\u022a\u022b\5(\24\2\u022b"+ - "\u022c\3\2\2\2\u022c\u022d\b9\3\2\u022ds\3\2\2\2\u022e\u022f\5\34\16\2"+ - "\u022f\u0230\5\16\7\2\u0230u\3\2\2\2\u0231\u0232\5\34\16\2\u0232\u0233"+ - "\5\16\7\2\u0233\u0234\5\16\7\2\u0234w\3\2\2\2\u0235\u0236\5\34\16\2\u0236"+ - "\u0237\5\16\7\2\u0237\u0238\5\16\7\2\u0238\u0239\5(\24\2\u0239y\3\2\2"+ - "\2\u023a\u023b\5\34\16\2\u023b\u023c\5\16\7\2\u023c\u023d\5\30\f\2\u023d"+ - "{\3\2\2\2\u023e\u023f\5\34\16\2\u023f\u0240\5\16\7\2\u0240\u0241\5\30"+ - "\f\2\u0241\u0242\5(\24\2\u0242}\3\2\2\2\u0243\u0244\5 \20\2\u0244\u0245"+ - "\5\20\b\2\u0245\u0246\5\24\n\2\u0246\177\3\2\2\2\u0247\u0248\5 \20\2\u0248"+ - "\u0249\5\"\21\2\u0249\u024a\5$\22\2\u024a\u0081\3\2\2\2\u024b\u024c\5"+ - "\"\21\2\u024c\u024d\5(\24\2\u024d\u0083\3\2\2\2\u024e\u024f\5\"\21\2\u024f"+ - "\u0250\5,\26\2\u0250\u0251\5\16\7\2\u0251\u0252\5(\24\2\u0252\u0085\3"+ - "\2\2\2\u0253\u0254\5\"\21\2\u0254\u0255\5,\26\2\u0255\u0256\5\30\f\2\u0256"+ - "\u0257\5(\24\2\u0257\u0087\3\2\2\2\u0258\u0259\5\"\21\2\u0259\u025a\5"+ - ".\27\2\u025a\u025b\5,\26\2\u025b\u0089\3\2\2\2\u025c\u025d\5\"\21\2\u025d"+ - "\u025e\5.\27\2\u025e\u025f\5,\26\2\u025f\u0260\5\16\7\2\u0260\u008b\3"+ - "\2\2\2\u0261\u0262\5\"\21\2\u0262\u0263\5.\27\2\u0263\u0264\5,\26\2\u0264"+ - "\u0265\5\30\f\2\u0265\u008d\3\2\2\2\u0266\u0267\5$\22\2\u0267\u0268\5"+ - "\"\21\2\u0268\u0269\5$\22\2\u0269\u008f\3\2\2\2\u026a\u026b\5$\22\2\u026b"+ - "\u026c\5.\27\2\u026c\u026d\5*\25\2\u026d\u026e\5\26\13\2\u026e\u0091\3"+ - "\2\2\2\u026f\u0270\5(\24\2\u0270\u0271\5\20\b\2\u0271\u0272\5*\25\2\u0272"+ - "\u0093\3\2\2\2\u0273\u0274\5(\24\2\u0274\u0275\5\20\b\2\u0275\u0276\5"+ - ",\26\2\u0276\u0277\3\2\2\2\u0277\u0278\bJ\3\2\u0278\u0095\3\2\2\2\u0279"+ - "\u027a\5(\24\2\u027a\u027b\5\20\b\2\u027b\u027c\5,\26\2\u027c\u027d\5"+ - "\30\f\2\u027d\u0097\3\2\2\2\u027e\u027f\5(\24\2\u027f\u0280\5\20\b\2\u0280"+ - "\u0281\5,\26\2\u0281\u0282\5 \20\2\u0282\u0099\3\2\2\2\u0283\u0284\5("+ - "\24\2\u0284\u0285\5\34\16\2\u0285\u009b\3\2\2\2\u0286\u0287\5(\24\2\u0287"+ - "\u0288\5\34\16\2\u0288\u0289\5\b\4\2\u0289\u009d\3\2\2\2\u028a\u028b\5"+ - "(\24\2\u028b\u028c\5\34\16\2\u028c\u028d\5\f\6\2\u028d\u009f\3\2\2\2\u028e"+ - "\u028f\5(\24\2\u028f\u0290\5\34\16\2\u0290\u0291\5\f\6\2\u0291\u0292\5"+ - "\b\4\2\u0292\u00a1\3\2\2\2\u0293\u0294\5(\24\2\u0294\u0295\5\34\16\2\u0295"+ - "\u0296\5\16\7\2\u0296\u00a3\3\2\2\2\u0297\u0298\5(\24\2\u0298\u0299\5"+ - "(\24\2\u0299\u00a5\3\2\2\2\u029a\u029b\5(\24\2\u029b\u029c\5(\24\2\u029c"+ - "\u029d\5\b\4\2\u029d\u00a7\3\2\2\2\u029e\u029f\5(\24\2\u029f\u02a0\5("+ - "\24\2\u02a0\u02a1\5\f\6\2\u02a1\u00a9\3\2\2\2\u02a2\u02a3\5(\24\2\u02a3"+ - "\u02a4\5(\24\2\u02a4\u02a5\5\f\6\2\u02a5\u02a6\5\b\4\2\u02a6\u00ab\3\2"+ - "\2\2\u02a7\u02a8\5(\24\2\u02a8\u02a9\5(\24\2\u02a9\u02aa\5\16\7\2\u02aa"+ - "\u00ad\3\2\2\2\u02ab\u02ac\5(\24\2\u02ac\u02ad\5*\25\2\u02ad\u02ae\5,"+ - "\26\2\u02ae\u00af\3\2\2\2\u02af\u02b0\5*\25\2\u02b0\u02b1\5\n\5\2\u02b1"+ - "\u02b2\5\f\6\2\u02b2\u00b1\3\2\2\2\u02b3\u02b4\5*\25\2\u02b4\u02b5\5\f"+ - "\6\2\u02b5\u02b6\5\22\t\2\u02b6\u00b3\3\2\2\2\u02b7\u02b8\5*\25\2\u02b8"+ - "\u02b9\5\20\b\2\u02b9\u02ba\5,\26\2\u02ba\u00b5\3\2\2\2\u02bb\u02bc\5"+ - "*\25\2\u02bc\u02bd\5\34\16\2\u02bd\u02be\5\b\4\2\u02be\u00b7\3\2\2\2\u02bf"+ - "\u02c0\5*\25\2\u02c0\u02c1\5(\24\2\u02c1\u02c2\5\b\4\2\u02c2\u00b9\3\2"+ - "\2\2\u02c3\u02c4\5*\25\2\u02c4\u02c5\5\34\16\2\u02c5\u02c6\5\34\16\2\u02c6"+ - "\u00bb\3\2\2\2\u02c7\u02c8\5*\25\2\u02c8\u02c9\5(\24\2\u02c9\u02ca\5\34"+ - "\16\2\u02ca\u00bd\3\2\2\2\u02cb\u02cc\5*\25\2\u02cc\u02cd\5.\27\2\u02cd"+ - "\u02ce\5\n\5\2\u02ce\u00bf\3\2\2\2\u02cf\u02d0\5\64\32\2\u02d0\u02d1\5"+ - "\"\21\2\u02d1\u02d2\5(\24\2\u02d2\u00c1\3\2\2\2\u02d3\u02d4\5\f\6\2\u02d4"+ - "\u02d5\3\2\2\2\u02d5\u02d6\ba\4\2\u02d6\u00c3\3\2\2\2\u02d7\u02d8\5 \20"+ - "\2\u02d8\u02d9\5\f\6\2\u02d9\u02da\3\2\2\2\u02da\u02db\bb\4\2\u02db\u00c5"+ - "\3\2\2\2\u02dc\u02dd\58\34\2\u02dd\u02de\3\2\2\2\u02de\u02df\bc\4\2\u02df"+ - "\u00c7\3\2\2\2\u02e0\u02e1\5 \20\2\u02e1\u02e2\58\34\2\u02e2\u02e3\3\2"+ - "\2\2\u02e3\u02e4\bd\4\2\u02e4\u00c9\3\2\2\2\u02e5\u02e6\5\36\17\2\u02e6"+ - "\u02e7\3\2\2\2\u02e7\u02e8\be\4\2\u02e8\u00cb\3\2\2\2\u02e9\u02ea\5$\22"+ - "\2\u02ea\u02eb\3\2\2\2\u02eb\u02ec\bf\4\2\u02ec\u00cd\3\2\2\2\u02ed\u02ee"+ - "\5$\22\2\u02ee\u02ef\5\20\b\2\u02ef\u02f0\3\2\2\2\u02f0\u02f1\bg\4\2\u02f1"+ - "\u00cf\3\2\2\2\u02f2\u02f3\5$\22\2\u02f3\u02f4\5\"\21\2\u02f4\u02f5\3"+ - "\2\2\2\u02f5\u02f6\bh\4\2\u02f6\u00d1\3\2\2\2\u02f7\u02f9\t\35\2\2\u02f8"+ - "\u02f7\3\2\2\2\u02f9\u02fa\3\2\2\2\u02fa\u02f8\3\2\2\2\u02fa\u02fb\3\2"+ - "\2\2\u02fb\u02fc\3\2\2\2\u02fc\u02fd\bi\2\2\u02fd\u00d3\3\2\2\2\u02fe"+ - "\u02ff\6j\2\2\u02ff\u0300\3\2\2\2\u0300\u0301\bj\4\2\u0301\u0302\bj\5"+ - "\2\u0302\u00d5\3\2\2\2\u0303\u0304\5\"\21\2\u0304\u0305\5(\24\2\u0305"+ - "\u0306\5\24\n\2\u0306\u00d7\3\2\2\2\u0307\u0308\5\20\b\2\u0308\u0309\5"+ - "&\23\2\u0309\u030a\5.\27\2\u030a\u00d9\3\2\2\2\u030b\u030c\5*\25\2\u030c"+ - "\u030d\5\20\b\2\u030d\u030e\5,\26\2\u030e\u00db\3\2\2\2\u030f\u0310\5"+ - "\60\30\2\u0310\u0311\5\b\4\2\u0311\u0312\5(\24\2\u0312\u00dd\3\2\2\2\u0313"+ - "\u0314\5\30\f\2\u0314\u0315\5\22\t\2\u0315\u00df\3\2\2\2\u0316\u0317\5"+ - "\20\b\2\u0317\u0318\5 \20\2\u0318\u0319\5\16\7\2\u0319\u031a\5\30\f\2"+ - "\u031a\u031b\5\22\t\2\u031b\u00e1\3\2\2\2\u031c\u031d\5\30\f\2\u031d\u031e"+ - "\5 \20\2\u031e\u031f\5\f\6\2\u031f\u0320\5\34\16\2\u0320\u0321\5.\27\2"+ - "\u0321\u0322\5\16\7\2\u0322\u0323\5\20\b\2\u0323\u00e3\3\2\2\2\u0324\u0325"+ - "\5\36\17\2\u0325\u0326\5\b\4\2\u0326\u0327\5\f\6\2\u0327\u0328\5(\24\2"+ - "\u0328\u0329\5\"\21\2\u0329\u00e5\3\2\2\2\u032a\u032b\5\20\b\2\u032b\u032c"+ - "\5 \20\2\u032c\u032d\5\16\7\2\u032d\u032e\5\36\17\2\u032e\u00e7\3\2\2"+ - "\2\u032f\u0330\5\16\7\2\u0330\u0331\5\n\5\2\u0331\u00e9\3\2\2\2\u0332"+ - "\u0333\5\16\7\2\u0333\u0334\5\62\31\2\u0334\u00eb\3\2\2\2\u0335\u0336"+ - "\5\16\7\2\u0336\u0337\5*\25\2\u0337\u00ed\3\2\2\2\u0338\u0339\7&\2\2\u0339"+ - "\u00ef\3\2\2\2\u033a\u033b\5\b\4\2\u033b\u00f1\3\2\2\2\u033c\u033d\5\n"+ - "\5\2\u033d\u00f3\3\2\2\2\u033e\u033f\5\f\6\2\u033f\u00f5\3\2\2\2\u0340"+ - "\u0341\5\16\7\2\u0341\u00f7\3\2\2\2\u0342\u0343\5\20\b\2\u0343\u00f9\3"+ - "\2\2\2\u0344\u0345\5\26\13\2\u0345\u00fb\3\2\2\2\u0346\u0347\5\34\16\2"+ - "\u0347\u00fd\3\2\2\2\u0348\u0349\5\30\f\2\u0349\u034a\5\64\32\2\u034a"+ - "\u00ff\3\2\2\2\u034b\u034c\5\30\f\2\u034c\u034d\5\64\32\2\u034d\u034e"+ - "\5\26\13\2\u034e\u0101\3\2\2\2\u034f\u0350\5\30\f\2\u0350\u0351\5\64\32"+ - "\2\u0351\u0352\5\34\16\2\u0352\u0103\3\2\2\2\u0353\u0354\5\30\f\2\u0354"+ - "\u0355\5\66\33\2\u0355\u0105\3\2\2\2\u0356\u0357\5\30\f\2\u0357\u0358"+ - "\5\66\33\2\u0358\u0359\5\26\13\2\u0359\u0107\3\2\2\2\u035a\u035b\5\30"+ - "\f\2\u035b\u035c\5\66\33\2\u035c\u035d\5\34\16\2\u035d\u0109\3\2\2\2\u035e"+ - "\u035f\5\n\5\2\u035f\u0360\5\f\6\2\u0360\u010b\3\2\2\2\u0361\u0362\5\16"+ - "\7\2\u0362\u0363\5\20\b\2\u0363\u010d\3\2\2\2\u0364\u0365\5\26\13\2\u0365"+ - "\u0366\5\34\16\2\u0366\u010f\3\2\2\2\u0367\u0368\5*\25\2\u0368\u0369\5"+ - "$\22\2\u0369\u0111\3\2\2\2\u036a\u036b\5\b\4\2\u036b\u036c\5\22\t\2\u036c"+ - "\u0113\3\2\2\2\u036d\u036e\5\b\4\2\u036e\u036f\5\22\t\2\u036f\u0370\7"+ - ")\2\2\u0370\u0115\3\2\2\2\u0371\u0372\5\30\f\2\u0372\u0117\3\2\2\2\u0373"+ - "\u0374\5(\24\2\u0374\u0119\3\2\2\2\u0375\u0376\5\36\17\2\u0376\u0377\5"+ - "\"\21\2\u0377\u0378\5\16\7\2\u0378\u011b\3\2\2\2\u0379\u037a\5*\25\2\u037a"+ - "\u037b\5\26\13\2\u037b\u037c\5(\24\2\u037c\u011d\3\2\2\2\u037d\u037e\5"+ - "*\25\2\u037e\u037f\5\26\13\2\u037f\u0380\5\34\16\2\u0380\u011f\3\2\2\2"+ - "\u0381\u0382\5 \20\2\u0382\u0383\5\"\21\2\u0383\u0384\5,\26\2\u0384\u0121"+ - "\3\2\2\2\u0385\u0386\5\b\4\2\u0386\u0387\5 \20\2\u0387\u0388\5\16\7\2"+ - "\u0388\u0123\3\2\2\2\u0389\u038a\5\"\21\2\u038a\u038b\5(\24\2\u038b\u0125"+ - "\3\2\2\2\u038c\u038d\5\64\32\2\u038d\u038e\5\"\21\2\u038e\u038f\5(\24"+ - "\2\u038f\u0127\3\2\2\2\u0390\u0391\7\62\2\2\u0391\u0393\5\64\32\2\u0392"+ - "\u0394\t\36\2\2\u0393\u0392\3\2\2\2\u0394\u0395\3\2\2\2\u0395\u0393\3"+ - "\2\2\2\u0395\u0396\3\2\2\2\u0396\u0129\3\2\2\2\u0397\u0399\t\37\2\2\u0398"+ - "\u0397\3\2\2\2\u0399\u039a\3\2\2\2\u039a\u0398\3\2\2\2\u039a\u039b\3\2"+ - "\2\2\u039b\u039d\3\2\2\2\u039c\u039e\5\16\7\2\u039d\u039c\3\2\2\2\u039d"+ - "\u039e\3\2\2\2\u039e\u012b\3\2\2\2\u039f\u03a1\t\36\2\2\u03a0\u039f\3"+ - "\2\2\2\u03a1\u03a2\3\2\2\2\u03a2\u03a0\3\2\2\2\u03a2\u03a3\3\2\2\2\u03a3"+ - "\u03a4\3\2\2\2\u03a4\u03a5\5\26\13\2\u03a5\u012d\3\2\2\2\u03a6\u03a8\t"+ - " \2\2\u03a7\u03a6\3\2\2\2\u03a8\u03a9\3\2\2\2\u03a9\u03a7\3\2\2\2\u03a9"+ - "\u03aa\3\2\2\2\u03aa\u03ab\3\2\2\2\u03ab\u03ac\t!\2\2\u03ac\u012f\3\2"+ - "\2\2\u03ad\u03af\t\"\2\2\u03ae\u03ad\3\2\2\2\u03af\u03b0\3\2\2\2\u03b0"+ - "\u03ae\3\2\2\2\u03b0\u03b1\3\2\2\2\u03b1\u03b2\3\2\2\2\u03b2\u03b3\5\n"+ - "\5\2\u03b3\u0131\3\2\2\2\u03b4\u03b8\7)\2\2\u03b5\u03b7\n#\2\2\u03b6\u03b5"+ - "\3\2\2\2\u03b7\u03ba\3\2\2\2\u03b8\u03b6\3\2\2\2\u03b8\u03b9\3\2\2\2\u03b9"+ - "\u03bb\3\2\2\2\u03ba\u03b8\3\2\2\2\u03bb\u03bc\7)\2\2\u03bc\u0133\3\2"+ - "\2\2\u03bd\u03c1\7$\2\2\u03be\u03c0\n$\2\2\u03bf\u03be\3\2\2\2\u03c0\u03c3"+ - "\3\2\2\2\u03c1\u03bf\3\2\2\2\u03c1\u03c2\3\2\2\2\u03c2\u03c4\3\2\2\2\u03c3"+ - "\u03c1\3\2\2\2\u03c4\u03c5\7$\2\2\u03c5\u0135\3\2\2\2\u03c6\u03ca\t%\2"+ - "\2\u03c7\u03c9\t&\2\2\u03c8\u03c7\3\2\2\2\u03c9\u03cc\3\2\2\2\u03ca\u03c8"+ - "\3\2\2\2\u03ca\u03cb\3\2\2\2\u03cb\u0137\3\2\2\2\u03cc\u03ca\3\2\2\2\u03cd"+ - "\u03ce\5\u0136\u009b\2\u03ce\u03cf\7<\2\2\u03cf\u0139\3\2\2\2\u03d0\u03d2"+ - "\n\'\2\2\u03d1\u03d0\3\2\2\2\u03d2\u03d3\3\2\2\2\u03d3\u03d1\3\2\2\2\u03d3"+ - "\u03d4\3\2\2\2\u03d4\u013b\3\2\2\2\u03d5\u03d6\7*\2\2\u03d6\u013d\3\2"+ - "\2\2\u03d7\u03d8\7+\2\2\u03d8\u013f\3\2\2\2\u03d9\u03da\7.\2\2\u03da\u0141"+ - "\3\2\2\2\u03db\u03dc\7-\2\2\u03dc\u0143\3\2\2\2\u03dd\u03de\7/\2\2\u03de"+ - "\u0145\3\2\2\2\u03df\u03e0\7,\2\2\u03e0\u0147\3\2\2\2\u03e1\u03e2\7\61"+ - "\2\2\u03e2\u0149\3\2\2\2\u03e3\u03e4\7?\2\2\u03e4\u014b\3\2\2\2\u03e5"+ - "\u03e6\7@\2\2\u03e6\u014d\3\2\2\2\u03e7\u03e8\7@\2\2\u03e8\u03e9\7?\2"+ - "\2\u03e9\u014f\3\2\2\2\u03ea\u03eb\7>\2\2\u03eb\u0151\3\2\2\2\u03ec\u03ed"+ - "\7>\2\2\u03ed\u03ee\7?\2\2\u03ee\u0153\3\2\2\2\u03ef\u03f0\7\'\2\2\u03f0"+ - "\u0155\3\2\2\2\u03f1\u03f2\7@\2\2\u03f2\u03f3\7@\2\2\u03f3\u0157\3\2\2"+ - "\2\u03f4\u03f5\7>\2\2\u03f5\u03f6\7>\2\2\u03f6\u0159\3\2\2\2\u03f7\u03f8"+ - "\7#\2\2\u03f8\u015b\3\2\2\2\u03f9\u03fa\7(\2\2\u03fa\u015d\3\2\2\2\u03fb"+ - "\u03fc\7~\2\2\u03fc\u015f\3\2\2\2\u03fd\u03fe\7\u0080\2\2\u03fe\u0161"+ - "\3\2\2\2\u03ff\u0401\t\35\2\2\u0400\u03ff\3\2\2\2\u0401\u0402\3\2\2\2"+ - "\u0402\u0400\3\2\2\2\u0402\u0403\3\2\2\2\u0403\u0404\3\2\2\2\u0404\u0405"+ - "\b\u00b1\2\2\u0405\u0163\3\2\2\2\u0406\u0408\7\17\2\2\u0407\u0406\3\2"+ - "\2\2\u0407\u0408\3\2\2\2\u0408\u0409\3\2\2\2\u0409\u040a\7\f\2\2\u040a"+ - "\u0165\3\2\2\2\24\2\3\u016b\u0170\u017b\u02fa\u0395\u039a\u039d\u03a2"+ - "\u03a9\u03b0\u03b8\u03c1\u03ca\u03d3\u0402\u0407\6\b\2\2\7\3\2\6\2\2\2"+ - "\3\2"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.tokens deleted file mode 100644 index e398feb30..000000000 --- a/plugins/compiler/as-z80/src/main/antlr/gen/AsZ80Lexer.tokens +++ /dev/null @@ -1,172 +0,0 @@ -COMMENT=1 -COMMENT2=2 -OPCODE_ADC=3 -OPCODE_ADD=4 -OPCODE_AND=5 -OPCODE_BIT=6 -OPCODE_CALL=7 -OPCODE_CCF=8 -OPCODE_CP=9 -OPCODE_CPD=10 -OPCODE_CPDR=11 -OPCODE_CPI=12 -OPCODE_CPIR=13 -OPCODE_CPL=14 -OPCODE_DAA=15 -OPCODE_DEC=16 -OPCODE_DI=17 -OPCODE_DJNZ=18 -OPCODE_EI=19 -OPCODE_EX=20 -OPCODE_EXX=21 -OPCODE_HALT=22 -OPCODE_IM=23 -OPCODE_IN=24 -OPCODE_INC=25 -OPCODE_IND=26 -OPCODE_INDR=27 -OPCODE_INI=28 -OPCODE_INIR=29 -OPCODE_JP=30 -OPCODE_JR=31 -OPCODE_LD=32 -OPCODE_LDD=33 -OPCODE_LDDR=34 -OPCODE_LDI=35 -OPCODE_LDIR=36 -OPCODE_NEG=37 -OPCODE_NOP=38 -OPCODE_OR=39 -OPCODE_OTDR=40 -OPCODE_OTIR=41 -OPCODE_OUT=42 -OPCODE_OUTD=43 -OPCODE_OUTI=44 -OPCODE_POP=45 -OPCODE_PUSH=46 -OPCODE_RES=47 -OPCODE_RET=48 -OPCODE_RETI=49 -OPCODE_RETN=50 -OPCODE_RL=51 -OPCODE_RLA=52 -OPCODE_RLC=53 -OPCODE_RLCA=54 -OPCODE_RLD=55 -OPCODE_RR=56 -OPCODE_RRA=57 -OPCODE_RRC=58 -OPCODE_RRCA=59 -OPCODE_RRD=60 -OPCODE_RST=61 -OPCODE_SBC=62 -OPCODE_SCF=63 -OPCODE_SET=64 -OPCODE_SLA=65 -OPCODE_SRA=66 -OPCODE_SLL=67 -OPCODE_SRL=68 -OPCODE_SUB=69 -OPCODE_XOR=70 -COND_C=71 -COND_NC=72 -COND_Z=73 -COND_NZ=74 -COND_M=75 -COND_P=76 -COND_PE=77 -COND_PO=78 -COND_WS=79 -COND_UNRECOGNIZED=80 -PREP_ORG=81 -PREP_EQU=82 -PREP_SET=83 -PREP_VAR=84 -PREP_IF=85 -PREP_ENDIF=86 -PREP_INCLUDE=87 -PREP_MACRO=88 -PREP_ENDM=89 -PREP_DB=90 -PREP_DW=91 -PREP_DS=92 -PREP_ADDR=93 -REG_A=94 -REG_B=95 -REG_C=96 -REG_D=97 -REG_E=98 -REG_H=99 -REG_L=100 -REG_IX=101 -REG_IXH=102 -REG_IXL=103 -REG_IY=104 -REG_IYH=105 -REG_IYL=106 -REG_BC=107 -REG_DE=108 -REG_HL=109 -REG_SP=110 -REG_AF=111 -REG_AFF=112 -REG_I=113 -REG_R=114 -OP_MOD=115 -OP_SHR=116 -OP_SHL=117 -OP_NOT=118 -OP_AND=119 -OP_OR=120 -OP_XOR=121 -LIT_HEXNUMBER_1=122 -LIT_NUMBER=123 -LIT_HEXNUMBER_2=124 -LIT_OCTNUMBER=125 -LIT_BINNUMBER=126 -LIT_STRING_1=127 -LIT_STRING_2=128 -ID_IDENTIFIER=129 -ID_LABEL=130 -ERROR=131 -SEP_LPAR=132 -SEP_RPAR=133 -SEP_COMMA=134 -OP_ADD=135 -OP_SUBTRACT=136 -OP_MULTIPLY=137 -OP_DIVIDE=138 -OP_EQUAL=139 -OP_GT=140 -OP_GTE=141 -OP_LT=142 -OP_LTE=143 -OP_MOD_2=144 -OP_SHR_2=145 -OP_SHL_2=146 -OP_NOT_2=147 -OP_AND_2=148 -OP_OR_2=149 -OP_XOR_2=150 -WS=151 -EOL=152 -'$'=93 -'('=132 -')'=133 -','=134 -'+'=135 -'-'=136 -'*'=137 -'/'=138 -'='=139 -'>'=140 -'>='=141 -'<'=142 -'<='=143 -'%'=144 -'>>'=145 -'<<'=146 -'!'=147 -'&'=148 -'|'=149 -'~'=150 diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp deleted file mode 100644 index d876ac554..000000000 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.interp +++ /dev/null @@ -1,496 +0,0 @@ -token literal names: -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -'$' -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -'(' -')' -',' -'+' -'-' -'*' -'/' -'=' -'>' -'>=' -'<' -'<=' -'%' -'>>' -'<<' -'~' -'&' -'|' -'^' -null -null - -token symbolic names: -null -COMMENT -COMMENT2 -OPCODE_ADC -OPCODE_ADD -OPCODE_AND -OPCODE_BIT -OPCODE_CALL -OPCODE_CCF -OPCODE_CP -OPCODE_CPD -OPCODE_CPDR -OPCODE_CPI -OPCODE_CPIR -OPCODE_CPL -OPCODE_DAA -OPCODE_DEC -OPCODE_DI -OPCODE_DJNZ -OPCODE_EI -OPCODE_EX -OPCODE_EXX -OPCODE_HALT -OPCODE_IM -OPCODE_IN -OPCODE_INC -OPCODE_IND -OPCODE_INDR -OPCODE_INI -OPCODE_INIR -OPCODE_JP -OPCODE_JR -OPCODE_LD -OPCODE_LDD -OPCODE_LDDR -OPCODE_LDI -OPCODE_LDIR -OPCODE_NEG -OPCODE_NOP -OPCODE_OR -OPCODE_OTDR -OPCODE_OTIR -OPCODE_OUT -OPCODE_OUTD -OPCODE_OUTI -OPCODE_POP -OPCODE_PUSH -OPCODE_RES -OPCODE_RET -OPCODE_RETI -OPCODE_RETN -OPCODE_RL -OPCODE_RLA -OPCODE_RLC -OPCODE_RLCA -OPCODE_RLD -OPCODE_RR -OPCODE_RRA -OPCODE_RRC -OPCODE_RRCA -OPCODE_RRD -OPCODE_RST -OPCODE_SBC -OPCODE_SCF -OPCODE_SET -OPCODE_SLA -OPCODE_SRA -OPCODE_SLL -OPCODE_SRL -OPCODE_SUB -OPCODE_XOR -COND_C -COND_NC -COND_Z -COND_NZ -COND_M -COND_P -COND_PE -COND_PO -COND_WS -COND_UNRECOGNIZED -PREP_ORG -PREP_EQU -PREP_SET -PREP_IF -PREP_ENDIF -PREP_INCLUDE -PREP_MACRO -PREP_ENDM -PREP_DB -PREP_DW -PREP_DS -PREP_ADDR -REG_A -REG_B -REG_C -REG_D -REG_E -REG_H -REG_L -REG_IX -REG_IXH -REG_IXL -REG_IY -REG_IYH -REG_IYL -REG_BC -REG_DE -REG_HL -REG_SP -REG_AF -REG_AFF -REG_I -REG_R -OP_MOD -OP_SHR -OP_SHL -OP_NOT -OP_AND -OP_OR -OP_XOR -LIT_HEXNUMBER_1 -LIT_NUMBER -LIT_HEXNUMBER_2 -LIT_OCTNUMBER -LIT_BINNUMBER -LIT_STRING_1 -LIT_STRING_2 -ID_IDENTIFIER -ID_LABEL -ERROR -SEP_LPAR -SEP_RPAR -SEP_COMMA -OP_ADD -OP_SUBTRACT -OP_MULTIPLY -OP_DIVIDE -OP_EQUAL -OP_GT -OP_GTE -OP_LT -OP_LTE -OP_MOD_2 -OP_SHR_2 -OP_SHL_2 -OP_NOT_2 -OP_AND_2 -OP_OR_2 -OP_XOR_2 -WS -EOL - -rule names: -COMMENT -COMMENT2 -A -B -C -D -E -F -G -H -I -J -L -M -N -O -P -Q -R -S -T -U -V -W -X -Y -Z -OPCODE_ADC -OPCODE_ADD -OPCODE_AND -OPCODE_BIT -OPCODE_CALL -OPCODE_CCF -OPCODE_CP -OPCODE_CPD -OPCODE_CPDR -OPCODE_CPI -OPCODE_CPIR -OPCODE_CPL -OPCODE_DAA -OPCODE_DEC -OPCODE_DI -OPCODE_DJNZ -OPCODE_EI -OPCODE_EX -OPCODE_EXX -OPCODE_HALT -OPCODE_IM -OPCODE_IN -OPCODE_INC -OPCODE_IND -OPCODE_INDR -OPCODE_INI -OPCODE_INIR -OPCODE_JP -OPCODE_JR -OPCODE_LD -OPCODE_LDD -OPCODE_LDDR -OPCODE_LDI -OPCODE_LDIR -OPCODE_NEG -OPCODE_NOP -OPCODE_OR -OPCODE_OTDR -OPCODE_OTIR -OPCODE_OUT -OPCODE_OUTD -OPCODE_OUTI -OPCODE_POP -OPCODE_PUSH -OPCODE_RES -OPCODE_RET -OPCODE_RETI -OPCODE_RETN -OPCODE_RL -OPCODE_RLA -OPCODE_RLC -OPCODE_RLCA -OPCODE_RLD -OPCODE_RR -OPCODE_RRA -OPCODE_RRC -OPCODE_RRCA -OPCODE_RRD -OPCODE_RST -OPCODE_SBC -OPCODE_SCF -OPCODE_SET -OPCODE_SLA -OPCODE_SRA -OPCODE_SLL -OPCODE_SRL -OPCODE_SUB -OPCODE_XOR -COND_C -COND_NC -COND_Z -COND_NZ -COND_M -COND_P -COND_PE -COND_PO -COND_WS -COND_UNRECOGNIZED -PREP_ORG -PREP_EQU -PREP_SET -PREP_IF -PREP_ENDIF -PREP_INCLUDE -PREP_MACRO -PREP_ENDM -PREP_DB -PREP_DW -PREP_DS -PREP_ADDR -REG_A -REG_B -REG_C -REG_D -REG_E -REG_H -REG_L -REG_IX -REG_IXH -REG_IXL -REG_IY -REG_IYH -REG_IYL -REG_BC -REG_DE -REG_HL -REG_SP -REG_AF -REG_AFF -REG_I -REG_R -OP_MOD -OP_SHR -OP_SHL -OP_NOT -OP_AND -OP_OR -OP_XOR -LIT_HEXNUMBER_1 -LIT_NUMBER -LIT_HEXNUMBER_2 -LIT_OCTNUMBER -LIT_BINNUMBER -LIT_STRING_1 -LIT_STRING_2 -ID_IDENTIFIER -ID_LABEL -ERROR -SEP_LPAR -SEP_RPAR -SEP_COMMA -OP_ADD -OP_SUBTRACT -OP_MULTIPLY -OP_DIVIDE -OP_EQUAL -OP_GT -OP_GTE -OP_LT -OP_LTE -OP_MOD_2 -OP_SHR_2 -OP_SHL_2 -OP_NOT_2 -OP_AND_2 -OP_OR_2 -OP_XOR_2 -WS -EOL - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE -CONDITION - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 153, 1028, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, 9, 119, 4, 120, 9, 120, 4, 121, 9, 121, 4, 122, 9, 122, 4, 123, 9, 123, 4, 124, 9, 124, 4, 125, 9, 125, 4, 126, 9, 126, 4, 127, 9, 127, 4, 128, 9, 128, 4, 129, 9, 129, 4, 130, 9, 130, 4, 131, 9, 131, 4, 132, 9, 132, 4, 133, 9, 133, 4, 134, 9, 134, 4, 135, 9, 135, 4, 136, 9, 136, 4, 137, 9, 137, 4, 138, 9, 138, 4, 139, 9, 139, 4, 140, 9, 140, 4, 141, 9, 141, 4, 142, 9, 142, 4, 143, 9, 143, 4, 144, 9, 144, 4, 145, 9, 145, 4, 146, 9, 146, 4, 147, 9, 147, 4, 148, 9, 148, 4, 149, 9, 149, 4, 150, 9, 150, 4, 151, 9, 151, 4, 152, 9, 152, 4, 153, 9, 153, 4, 154, 9, 154, 4, 155, 9, 155, 4, 156, 9, 156, 4, 157, 9, 157, 4, 158, 9, 158, 4, 159, 9, 159, 4, 160, 9, 160, 4, 161, 9, 161, 4, 162, 9, 162, 4, 163, 9, 163, 4, 164, 9, 164, 4, 165, 9, 165, 4, 166, 9, 166, 4, 167, 9, 167, 4, 168, 9, 168, 4, 169, 9, 169, 4, 170, 9, 170, 4, 171, 9, 171, 4, 172, 9, 172, 4, 173, 9, 173, 4, 174, 9, 174, 4, 175, 9, 175, 4, 176, 9, 176, 4, 177, 9, 177, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 362, 10, 2, 3, 2, 7, 2, 365, 10, 2, 12, 2, 14, 2, 368, 11, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 376, 10, 3, 12, 3, 14, 3, 379, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 3, 84, 3, 85, 3, 85, 3, 85, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 94, 3, 94, 3, 94, 3, 94, 3, 95, 3, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 98, 3, 98, 3, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 104, 3, 105, 6, 105, 759, 10, 105, 13, 105, 14, 105, 760, 3, 105, 3, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, 110, 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, 116, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 118, 3, 118, 3, 119, 3, 119, 3, 120, 3, 120, 3, 121, 3, 121, 3, 122, 3, 122, 3, 123, 3, 123, 3, 124, 3, 124, 3, 125, 3, 125, 3, 126, 3, 126, 3, 126, 3, 127, 3, 127, 3, 127, 3, 127, 3, 128, 3, 128, 3, 128, 3, 128, 3, 129, 3, 129, 3, 129, 3, 130, 3, 130, 3, 130, 3, 130, 3, 131, 3, 131, 3, 131, 3, 131, 3, 132, 3, 132, 3, 132, 3, 133, 3, 133, 3, 133, 3, 134, 3, 134, 3, 134, 3, 135, 3, 135, 3, 135, 3, 136, 3, 136, 3, 136, 3, 137, 3, 137, 3, 137, 3, 137, 3, 138, 3, 138, 3, 139, 3, 139, 3, 140, 3, 140, 3, 140, 3, 140, 3, 141, 3, 141, 3, 141, 3, 141, 3, 142, 3, 142, 3, 142, 3, 142, 3, 143, 3, 143, 3, 143, 3, 143, 3, 144, 3, 144, 3, 144, 3, 144, 3, 145, 3, 145, 3, 145, 3, 146, 3, 146, 3, 146, 3, 146, 3, 147, 3, 147, 3, 147, 6, 147, 909, 10, 147, 13, 147, 14, 147, 910, 3, 148, 6, 148, 914, 10, 148, 13, 148, 14, 148, 915, 3, 148, 5, 148, 919, 10, 148, 3, 149, 6, 149, 922, 10, 149, 13, 149, 14, 149, 923, 3, 149, 3, 149, 3, 150, 6, 150, 929, 10, 150, 13, 150, 14, 150, 930, 3, 150, 3, 150, 3, 151, 6, 151, 936, 10, 151, 13, 151, 14, 151, 937, 3, 151, 3, 151, 3, 152, 3, 152, 7, 152, 944, 10, 152, 12, 152, 14, 152, 947, 11, 152, 3, 152, 3, 152, 3, 153, 3, 153, 7, 153, 953, 10, 153, 12, 153, 14, 153, 956, 11, 153, 3, 153, 3, 153, 3, 154, 3, 154, 7, 154, 962, 10, 154, 12, 154, 14, 154, 965, 11, 154, 3, 155, 3, 155, 3, 155, 3, 156, 6, 156, 971, 10, 156, 13, 156, 14, 156, 972, 3, 157, 3, 157, 3, 158, 3, 158, 3, 159, 3, 159, 3, 160, 3, 160, 3, 161, 3, 161, 3, 162, 3, 162, 3, 163, 3, 163, 3, 164, 3, 164, 3, 165, 3, 165, 3, 166, 3, 166, 3, 166, 3, 167, 3, 167, 3, 168, 3, 168, 3, 168, 3, 169, 3, 169, 3, 170, 3, 170, 3, 170, 3, 171, 3, 171, 3, 171, 3, 172, 3, 172, 3, 173, 3, 173, 3, 174, 3, 174, 3, 175, 3, 175, 3, 176, 6, 176, 1018, 10, 176, 13, 176, 14, 176, 1019, 3, 176, 3, 176, 3, 177, 5, 177, 1025, 10, 177, 3, 177, 3, 177, 3, 377, 2, 178, 4, 3, 6, 4, 8, 2, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54, 2, 56, 2, 58, 5, 60, 6, 62, 7, 64, 8, 66, 9, 68, 10, 70, 11, 72, 12, 74, 13, 76, 14, 78, 15, 80, 16, 82, 17, 84, 18, 86, 19, 88, 20, 90, 21, 92, 22, 94, 23, 96, 24, 98, 25, 100, 26, 102, 27, 104, 28, 106, 29, 108, 30, 110, 31, 112, 32, 114, 33, 116, 34, 118, 35, 120, 36, 122, 37, 124, 38, 126, 39, 128, 40, 130, 41, 132, 42, 134, 43, 136, 44, 138, 45, 140, 46, 142, 47, 144, 48, 146, 49, 148, 50, 150, 51, 152, 52, 154, 53, 156, 54, 158, 55, 160, 56, 162, 57, 164, 58, 166, 59, 168, 60, 170, 61, 172, 62, 174, 63, 176, 64, 178, 65, 180, 66, 182, 67, 184, 68, 186, 69, 188, 70, 190, 71, 192, 72, 194, 73, 196, 74, 198, 75, 200, 76, 202, 77, 204, 78, 206, 79, 208, 80, 210, 81, 212, 82, 214, 83, 216, 84, 218, 85, 220, 86, 222, 87, 224, 88, 226, 89, 228, 90, 230, 91, 232, 92, 234, 93, 236, 94, 238, 95, 240, 96, 242, 97, 244, 98, 246, 99, 248, 100, 250, 101, 252, 102, 254, 103, 256, 104, 258, 105, 260, 106, 262, 107, 264, 108, 266, 109, 268, 110, 270, 111, 272, 112, 274, 113, 276, 114, 278, 115, 280, 116, 282, 117, 284, 118, 286, 119, 288, 120, 290, 121, 292, 122, 294, 123, 296, 124, 298, 125, 300, 126, 302, 127, 304, 128, 306, 129, 308, 130, 310, 131, 312, 132, 314, 133, 316, 134, 318, 135, 320, 136, 322, 137, 324, 138, 326, 139, 328, 140, 330, 141, 332, 142, 334, 143, 336, 144, 338, 145, 340, 146, 342, 147, 344, 148, 346, 149, 348, 150, 350, 151, 352, 152, 354, 153, 4, 2, 3, 40, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 5, 2, 11, 11, 14, 14, 34, 34, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 59, 3, 2, 50, 57, 6, 2, 81, 81, 83, 83, 113, 113, 115, 115, 3, 2, 50, 51, 3, 2, 41, 41, 3, 2, 36, 36, 5, 2, 65, 92, 97, 97, 99, 124, 6, 2, 50, 59, 65, 92, 97, 97, 99, 124, 12, 2, 11, 12, 14, 15, 34, 34, 39, 40, 42, 47, 49, 49, 62, 64, 96, 96, 126, 126, 128, 128, 2, 1018, 2, 4, 3, 2, 2, 2, 2, 6, 3, 2, 2, 2, 2, 58, 3, 2, 2, 2, 2, 60, 3, 2, 2, 2, 2, 62, 3, 2, 2, 2, 2, 64, 3, 2, 2, 2, 2, 66, 3, 2, 2, 2, 2, 68, 3, 2, 2, 2, 2, 70, 3, 2, 2, 2, 2, 72, 3, 2, 2, 2, 2, 74, 3, 2, 2, 2, 2, 76, 3, 2, 2, 2, 2, 78, 3, 2, 2, 2, 2, 80, 3, 2, 2, 2, 2, 82, 3, 2, 2, 2, 2, 84, 3, 2, 2, 2, 2, 86, 3, 2, 2, 2, 2, 88, 3, 2, 2, 2, 2, 90, 3, 2, 2, 2, 2, 92, 3, 2, 2, 2, 2, 94, 3, 2, 2, 2, 2, 96, 3, 2, 2, 2, 2, 98, 3, 2, 2, 2, 2, 100, 3, 2, 2, 2, 2, 102, 3, 2, 2, 2, 2, 104, 3, 2, 2, 2, 2, 106, 3, 2, 2, 2, 2, 108, 3, 2, 2, 2, 2, 110, 3, 2, 2, 2, 2, 112, 3, 2, 2, 2, 2, 114, 3, 2, 2, 2, 2, 116, 3, 2, 2, 2, 2, 118, 3, 2, 2, 2, 2, 120, 3, 2, 2, 2, 2, 122, 3, 2, 2, 2, 2, 124, 3, 2, 2, 2, 2, 126, 3, 2, 2, 2, 2, 128, 3, 2, 2, 2, 2, 130, 3, 2, 2, 2, 2, 132, 3, 2, 2, 2, 2, 134, 3, 2, 2, 2, 2, 136, 3, 2, 2, 2, 2, 138, 3, 2, 2, 2, 2, 140, 3, 2, 2, 2, 2, 142, 3, 2, 2, 2, 2, 144, 3, 2, 2, 2, 2, 146, 3, 2, 2, 2, 2, 148, 3, 2, 2, 2, 2, 150, 3, 2, 2, 2, 2, 152, 3, 2, 2, 2, 2, 154, 3, 2, 2, 2, 2, 156, 3, 2, 2, 2, 2, 158, 3, 2, 2, 2, 2, 160, 3, 2, 2, 2, 2, 162, 3, 2, 2, 2, 2, 164, 3, 2, 2, 2, 2, 166, 3, 2, 2, 2, 2, 168, 3, 2, 2, 2, 2, 170, 3, 2, 2, 2, 2, 172, 3, 2, 2, 2, 2, 174, 3, 2, 2, 2, 2, 176, 3, 2, 2, 2, 2, 178, 3, 2, 2, 2, 2, 180, 3, 2, 2, 2, 2, 182, 3, 2, 2, 2, 2, 184, 3, 2, 2, 2, 2, 186, 3, 2, 2, 2, 2, 188, 3, 2, 2, 2, 2, 190, 3, 2, 2, 2, 2, 192, 3, 2, 2, 2, 2, 214, 3, 2, 2, 2, 2, 216, 3, 2, 2, 2, 2, 218, 3, 2, 2, 2, 2, 220, 3, 2, 2, 2, 2, 222, 3, 2, 2, 2, 2, 224, 3, 2, 2, 2, 2, 226, 3, 2, 2, 2, 2, 228, 3, 2, 2, 2, 2, 230, 3, 2, 2, 2, 2, 232, 3, 2, 2, 2, 2, 234, 3, 2, 2, 2, 2, 236, 3, 2, 2, 2, 2, 238, 3, 2, 2, 2, 2, 240, 3, 2, 2, 2, 2, 242, 3, 2, 2, 2, 2, 244, 3, 2, 2, 2, 2, 246, 3, 2, 2, 2, 2, 248, 3, 2, 2, 2, 2, 250, 3, 2, 2, 2, 2, 252, 3, 2, 2, 2, 2, 254, 3, 2, 2, 2, 2, 256, 3, 2, 2, 2, 2, 258, 3, 2, 2, 2, 2, 260, 3, 2, 2, 2, 2, 262, 3, 2, 2, 2, 2, 264, 3, 2, 2, 2, 2, 266, 3, 2, 2, 2, 2, 268, 3, 2, 2, 2, 2, 270, 3, 2, 2, 2, 2, 272, 3, 2, 2, 2, 2, 274, 3, 2, 2, 2, 2, 276, 3, 2, 2, 2, 2, 278, 3, 2, 2, 2, 2, 280, 3, 2, 2, 2, 2, 282, 3, 2, 2, 2, 2, 284, 3, 2, 2, 2, 2, 286, 3, 2, 2, 2, 2, 288, 3, 2, 2, 2, 2, 290, 3, 2, 2, 2, 2, 292, 3, 2, 2, 2, 2, 294, 3, 2, 2, 2, 2, 296, 3, 2, 2, 2, 2, 298, 3, 2, 2, 2, 2, 300, 3, 2, 2, 2, 2, 302, 3, 2, 2, 2, 2, 304, 3, 2, 2, 2, 2, 306, 3, 2, 2, 2, 2, 308, 3, 2, 2, 2, 2, 310, 3, 2, 2, 2, 2, 312, 3, 2, 2, 2, 2, 314, 3, 2, 2, 2, 2, 316, 3, 2, 2, 2, 2, 318, 3, 2, 2, 2, 2, 320, 3, 2, 2, 2, 2, 322, 3, 2, 2, 2, 2, 324, 3, 2, 2, 2, 2, 326, 3, 2, 2, 2, 2, 328, 3, 2, 2, 2, 2, 330, 3, 2, 2, 2, 2, 332, 3, 2, 2, 2, 2, 334, 3, 2, 2, 2, 2, 336, 3, 2, 2, 2, 2, 338, 3, 2, 2, 2, 2, 340, 3, 2, 2, 2, 2, 342, 3, 2, 2, 2, 2, 344, 3, 2, 2, 2, 2, 346, 3, 2, 2, 2, 2, 348, 3, 2, 2, 2, 2, 350, 3, 2, 2, 2, 2, 352, 3, 2, 2, 2, 2, 354, 3, 2, 2, 2, 3, 194, 3, 2, 2, 2, 3, 196, 3, 2, 2, 2, 3, 198, 3, 2, 2, 2, 3, 200, 3, 2, 2, 2, 3, 202, 3, 2, 2, 2, 3, 204, 3, 2, 2, 2, 3, 206, 3, 2, 2, 2, 3, 208, 3, 2, 2, 2, 3, 210, 3, 2, 2, 2, 3, 212, 3, 2, 2, 2, 4, 361, 3, 2, 2, 2, 6, 371, 3, 2, 2, 2, 8, 385, 3, 2, 2, 2, 10, 387, 3, 2, 2, 2, 12, 389, 3, 2, 2, 2, 14, 391, 3, 2, 2, 2, 16, 393, 3, 2, 2, 2, 18, 395, 3, 2, 2, 2, 20, 397, 3, 2, 2, 2, 22, 399, 3, 2, 2, 2, 24, 401, 3, 2, 2, 2, 26, 403, 3, 2, 2, 2, 28, 405, 3, 2, 2, 2, 30, 407, 3, 2, 2, 2, 32, 409, 3, 2, 2, 2, 34, 411, 3, 2, 2, 2, 36, 413, 3, 2, 2, 2, 38, 415, 3, 2, 2, 2, 40, 417, 3, 2, 2, 2, 42, 419, 3, 2, 2, 2, 44, 421, 3, 2, 2, 2, 46, 423, 3, 2, 2, 2, 48, 425, 3, 2, 2, 2, 50, 427, 3, 2, 2, 2, 52, 429, 3, 2, 2, 2, 54, 431, 3, 2, 2, 2, 56, 433, 3, 2, 2, 2, 58, 435, 3, 2, 2, 2, 60, 439, 3, 2, 2, 2, 62, 443, 3, 2, 2, 2, 64, 447, 3, 2, 2, 2, 66, 451, 3, 2, 2, 2, 68, 458, 3, 2, 2, 2, 70, 462, 3, 2, 2, 2, 72, 465, 3, 2, 2, 2, 74, 469, 3, 2, 2, 2, 76, 474, 3, 2, 2, 2, 78, 478, 3, 2, 2, 2, 80, 483, 3, 2, 2, 2, 82, 487, 3, 2, 2, 2, 84, 491, 3, 2, 2, 2, 86, 495, 3, 2, 2, 2, 88, 498, 3, 2, 2, 2, 90, 503, 3, 2, 2, 2, 92, 506, 3, 2, 2, 2, 94, 509, 3, 2, 2, 2, 96, 513, 3, 2, 2, 2, 98, 518, 3, 2, 2, 2, 100, 521, 3, 2, 2, 2, 102, 524, 3, 2, 2, 2, 104, 528, 3, 2, 2, 2, 106, 532, 3, 2, 2, 2, 108, 537, 3, 2, 2, 2, 110, 541, 3, 2, 2, 2, 112, 546, 3, 2, 2, 2, 114, 551, 3, 2, 2, 2, 116, 556, 3, 2, 2, 2, 118, 559, 3, 2, 2, 2, 120, 563, 3, 2, 2, 2, 122, 568, 3, 2, 2, 2, 124, 572, 3, 2, 2, 2, 126, 577, 3, 2, 2, 2, 128, 581, 3, 2, 2, 2, 130, 585, 3, 2, 2, 2, 132, 588, 3, 2, 2, 2, 134, 593, 3, 2, 2, 2, 136, 598, 3, 2, 2, 2, 138, 602, 3, 2, 2, 2, 140, 607, 3, 2, 2, 2, 142, 612, 3, 2, 2, 2, 144, 616, 3, 2, 2, 2, 146, 621, 3, 2, 2, 2, 148, 625, 3, 2, 2, 2, 150, 631, 3, 2, 2, 2, 152, 636, 3, 2, 2, 2, 154, 641, 3, 2, 2, 2, 156, 644, 3, 2, 2, 2, 158, 648, 3, 2, 2, 2, 160, 652, 3, 2, 2, 2, 162, 657, 3, 2, 2, 2, 164, 661, 3, 2, 2, 2, 166, 664, 3, 2, 2, 2, 168, 668, 3, 2, 2, 2, 170, 672, 3, 2, 2, 2, 172, 677, 3, 2, 2, 2, 174, 681, 3, 2, 2, 2, 176, 685, 3, 2, 2, 2, 178, 689, 3, 2, 2, 2, 180, 693, 3, 2, 2, 2, 182, 697, 3, 2, 2, 2, 184, 701, 3, 2, 2, 2, 186, 705, 3, 2, 2, 2, 188, 709, 3, 2, 2, 2, 190, 713, 3, 2, 2, 2, 192, 717, 3, 2, 2, 2, 194, 721, 3, 2, 2, 2, 196, 725, 3, 2, 2, 2, 198, 730, 3, 2, 2, 2, 200, 734, 3, 2, 2, 2, 202, 739, 3, 2, 2, 2, 204, 743, 3, 2, 2, 2, 206, 747, 3, 2, 2, 2, 208, 752, 3, 2, 2, 2, 210, 758, 3, 2, 2, 2, 212, 764, 3, 2, 2, 2, 214, 768, 3, 2, 2, 2, 216, 772, 3, 2, 2, 2, 218, 776, 3, 2, 2, 2, 220, 780, 3, 2, 2, 2, 222, 783, 3, 2, 2, 2, 224, 789, 3, 2, 2, 2, 226, 797, 3, 2, 2, 2, 228, 803, 3, 2, 2, 2, 230, 808, 3, 2, 2, 2, 232, 811, 3, 2, 2, 2, 234, 814, 3, 2, 2, 2, 236, 817, 3, 2, 2, 2, 238, 819, 3, 2, 2, 2, 240, 821, 3, 2, 2, 2, 242, 823, 3, 2, 2, 2, 244, 825, 3, 2, 2, 2, 246, 827, 3, 2, 2, 2, 248, 829, 3, 2, 2, 2, 250, 831, 3, 2, 2, 2, 252, 833, 3, 2, 2, 2, 254, 836, 3, 2, 2, 2, 256, 840, 3, 2, 2, 2, 258, 844, 3, 2, 2, 2, 260, 847, 3, 2, 2, 2, 262, 851, 3, 2, 2, 2, 264, 855, 3, 2, 2, 2, 266, 858, 3, 2, 2, 2, 268, 861, 3, 2, 2, 2, 270, 864, 3, 2, 2, 2, 272, 867, 3, 2, 2, 2, 274, 870, 3, 2, 2, 2, 276, 874, 3, 2, 2, 2, 278, 876, 3, 2, 2, 2, 280, 878, 3, 2, 2, 2, 282, 882, 3, 2, 2, 2, 284, 886, 3, 2, 2, 2, 286, 890, 3, 2, 2, 2, 288, 894, 3, 2, 2, 2, 290, 898, 3, 2, 2, 2, 292, 901, 3, 2, 2, 2, 294, 905, 3, 2, 2, 2, 296, 913, 3, 2, 2, 2, 298, 921, 3, 2, 2, 2, 300, 928, 3, 2, 2, 2, 302, 935, 3, 2, 2, 2, 304, 941, 3, 2, 2, 2, 306, 950, 3, 2, 2, 2, 308, 959, 3, 2, 2, 2, 310, 966, 3, 2, 2, 2, 312, 970, 3, 2, 2, 2, 314, 974, 3, 2, 2, 2, 316, 976, 3, 2, 2, 2, 318, 978, 3, 2, 2, 2, 320, 980, 3, 2, 2, 2, 322, 982, 3, 2, 2, 2, 324, 984, 3, 2, 2, 2, 326, 986, 3, 2, 2, 2, 328, 988, 3, 2, 2, 2, 330, 990, 3, 2, 2, 2, 332, 992, 3, 2, 2, 2, 334, 995, 3, 2, 2, 2, 336, 997, 3, 2, 2, 2, 338, 1000, 3, 2, 2, 2, 340, 1002, 3, 2, 2, 2, 342, 1005, 3, 2, 2, 2, 344, 1008, 3, 2, 2, 2, 346, 1010, 3, 2, 2, 2, 348, 1012, 3, 2, 2, 2, 350, 1014, 3, 2, 2, 2, 352, 1017, 3, 2, 2, 2, 354, 1024, 3, 2, 2, 2, 356, 357, 7, 49, 2, 2, 357, 362, 7, 49, 2, 2, 358, 359, 7, 47, 2, 2, 359, 362, 7, 47, 2, 2, 360, 362, 9, 2, 2, 2, 361, 356, 3, 2, 2, 2, 361, 358, 3, 2, 2, 2, 361, 360, 3, 2, 2, 2, 362, 366, 3, 2, 2, 2, 363, 365, 10, 3, 2, 2, 364, 363, 3, 2, 2, 2, 365, 368, 3, 2, 2, 2, 366, 364, 3, 2, 2, 2, 366, 367, 3, 2, 2, 2, 367, 369, 3, 2, 2, 2, 368, 366, 3, 2, 2, 2, 369, 370, 8, 2, 2, 2, 370, 5, 3, 2, 2, 2, 371, 372, 7, 49, 2, 2, 372, 373, 7, 44, 2, 2, 373, 377, 3, 2, 2, 2, 374, 376, 11, 2, 2, 2, 375, 374, 3, 2, 2, 2, 376, 379, 3, 2, 2, 2, 377, 378, 3, 2, 2, 2, 377, 375, 3, 2, 2, 2, 378, 380, 3, 2, 2, 2, 379, 377, 3, 2, 2, 2, 380, 381, 7, 44, 2, 2, 381, 382, 7, 49, 2, 2, 382, 383, 3, 2, 2, 2, 383, 384, 8, 3, 2, 2, 384, 7, 3, 2, 2, 2, 385, 386, 9, 4, 2, 2, 386, 9, 3, 2, 2, 2, 387, 388, 9, 5, 2, 2, 388, 11, 3, 2, 2, 2, 389, 390, 9, 6, 2, 2, 390, 13, 3, 2, 2, 2, 391, 392, 9, 7, 2, 2, 392, 15, 3, 2, 2, 2, 393, 394, 9, 8, 2, 2, 394, 17, 3, 2, 2, 2, 395, 396, 9, 9, 2, 2, 396, 19, 3, 2, 2, 2, 397, 398, 9, 10, 2, 2, 398, 21, 3, 2, 2, 2, 399, 400, 9, 11, 2, 2, 400, 23, 3, 2, 2, 2, 401, 402, 9, 12, 2, 2, 402, 25, 3, 2, 2, 2, 403, 404, 9, 13, 2, 2, 404, 27, 3, 2, 2, 2, 405, 406, 9, 14, 2, 2, 406, 29, 3, 2, 2, 2, 407, 408, 9, 15, 2, 2, 408, 31, 3, 2, 2, 2, 409, 410, 9, 16, 2, 2, 410, 33, 3, 2, 2, 2, 411, 412, 9, 17, 2, 2, 412, 35, 3, 2, 2, 2, 413, 414, 9, 18, 2, 2, 414, 37, 3, 2, 2, 2, 415, 416, 9, 19, 2, 2, 416, 39, 3, 2, 2, 2, 417, 418, 9, 20, 2, 2, 418, 41, 3, 2, 2, 2, 419, 420, 9, 21, 2, 2, 420, 43, 3, 2, 2, 2, 421, 422, 9, 22, 2, 2, 422, 45, 3, 2, 2, 2, 423, 424, 9, 23, 2, 2, 424, 47, 3, 2, 2, 2, 425, 426, 9, 24, 2, 2, 426, 49, 3, 2, 2, 2, 427, 428, 9, 25, 2, 2, 428, 51, 3, 2, 2, 2, 429, 430, 9, 26, 2, 2, 430, 53, 3, 2, 2, 2, 431, 432, 9, 27, 2, 2, 432, 55, 3, 2, 2, 2, 433, 434, 9, 28, 2, 2, 434, 57, 3, 2, 2, 2, 435, 436, 5, 8, 4, 2, 436, 437, 5, 14, 7, 2, 437, 438, 5, 12, 6, 2, 438, 59, 3, 2, 2, 2, 439, 440, 5, 8, 4, 2, 440, 441, 5, 14, 7, 2, 441, 442, 5, 14, 7, 2, 442, 61, 3, 2, 2, 2, 443, 444, 5, 8, 4, 2, 444, 445, 5, 32, 16, 2, 445, 446, 5, 14, 7, 2, 446, 63, 3, 2, 2, 2, 447, 448, 5, 10, 5, 2, 448, 449, 5, 24, 12, 2, 449, 450, 5, 44, 22, 2, 450, 65, 3, 2, 2, 2, 451, 452, 5, 12, 6, 2, 452, 453, 5, 8, 4, 2, 453, 454, 5, 28, 14, 2, 454, 455, 5, 28, 14, 2, 455, 456, 3, 2, 2, 2, 456, 457, 8, 33, 3, 2, 457, 67, 3, 2, 2, 2, 458, 459, 5, 12, 6, 2, 459, 460, 5, 12, 6, 2, 460, 461, 5, 18, 9, 2, 461, 69, 3, 2, 2, 2, 462, 463, 5, 12, 6, 2, 463, 464, 5, 36, 18, 2, 464, 71, 3, 2, 2, 2, 465, 466, 5, 12, 6, 2, 466, 467, 5, 36, 18, 2, 467, 468, 5, 14, 7, 2, 468, 73, 3, 2, 2, 2, 469, 470, 5, 12, 6, 2, 470, 471, 5, 36, 18, 2, 471, 472, 5, 14, 7, 2, 472, 473, 5, 40, 20, 2, 473, 75, 3, 2, 2, 2, 474, 475, 5, 12, 6, 2, 475, 476, 5, 36, 18, 2, 476, 477, 5, 24, 12, 2, 477, 77, 3, 2, 2, 2, 478, 479, 5, 12, 6, 2, 479, 480, 5, 36, 18, 2, 480, 481, 5, 24, 12, 2, 481, 482, 5, 40, 20, 2, 482, 79, 3, 2, 2, 2, 483, 484, 5, 12, 6, 2, 484, 485, 5, 36, 18, 2, 485, 486, 5, 28, 14, 2, 486, 81, 3, 2, 2, 2, 487, 488, 5, 14, 7, 2, 488, 489, 5, 8, 4, 2, 489, 490, 5, 8, 4, 2, 490, 83, 3, 2, 2, 2, 491, 492, 5, 14, 7, 2, 492, 493, 5, 16, 8, 2, 493, 494, 5, 12, 6, 2, 494, 85, 3, 2, 2, 2, 495, 496, 5, 14, 7, 2, 496, 497, 5, 24, 12, 2, 497, 87, 3, 2, 2, 2, 498, 499, 5, 14, 7, 2, 499, 500, 5, 26, 13, 2, 500, 501, 5, 32, 16, 2, 501, 502, 5, 56, 28, 2, 502, 89, 3, 2, 2, 2, 503, 504, 5, 16, 8, 2, 504, 505, 5, 24, 12, 2, 505, 91, 3, 2, 2, 2, 506, 507, 5, 16, 8, 2, 507, 508, 5, 52, 26, 2, 508, 93, 3, 2, 2, 2, 509, 510, 5, 16, 8, 2, 510, 511, 5, 52, 26, 2, 511, 512, 5, 52, 26, 2, 512, 95, 3, 2, 2, 2, 513, 514, 5, 22, 11, 2, 514, 515, 5, 8, 4, 2, 515, 516, 5, 28, 14, 2, 516, 517, 5, 44, 22, 2, 517, 97, 3, 2, 2, 2, 518, 519, 5, 24, 12, 2, 519, 520, 5, 30, 15, 2, 520, 99, 3, 2, 2, 2, 521, 522, 5, 24, 12, 2, 522, 523, 5, 32, 16, 2, 523, 101, 3, 2, 2, 2, 524, 525, 5, 24, 12, 2, 525, 526, 5, 32, 16, 2, 526, 527, 5, 12, 6, 2, 527, 103, 3, 2, 2, 2, 528, 529, 5, 24, 12, 2, 529, 530, 5, 32, 16, 2, 530, 531, 5, 14, 7, 2, 531, 105, 3, 2, 2, 2, 532, 533, 5, 24, 12, 2, 533, 534, 5, 32, 16, 2, 534, 535, 5, 14, 7, 2, 535, 536, 5, 40, 20, 2, 536, 107, 3, 2, 2, 2, 537, 538, 5, 24, 12, 2, 538, 539, 5, 32, 16, 2, 539, 540, 5, 24, 12, 2, 540, 109, 3, 2, 2, 2, 541, 542, 5, 24, 12, 2, 542, 543, 5, 32, 16, 2, 543, 544, 5, 24, 12, 2, 544, 545, 5, 40, 20, 2, 545, 111, 3, 2, 2, 2, 546, 547, 5, 26, 13, 2, 547, 548, 5, 36, 18, 2, 548, 549, 3, 2, 2, 2, 549, 550, 8, 56, 3, 2, 550, 113, 3, 2, 2, 2, 551, 552, 5, 26, 13, 2, 552, 553, 5, 40, 20, 2, 553, 554, 3, 2, 2, 2, 554, 555, 8, 57, 3, 2, 555, 115, 3, 2, 2, 2, 556, 557, 5, 28, 14, 2, 557, 558, 5, 14, 7, 2, 558, 117, 3, 2, 2, 2, 559, 560, 5, 28, 14, 2, 560, 561, 5, 14, 7, 2, 561, 562, 5, 14, 7, 2, 562, 119, 3, 2, 2, 2, 563, 564, 5, 28, 14, 2, 564, 565, 5, 14, 7, 2, 565, 566, 5, 14, 7, 2, 566, 567, 5, 40, 20, 2, 567, 121, 3, 2, 2, 2, 568, 569, 5, 28, 14, 2, 569, 570, 5, 14, 7, 2, 570, 571, 5, 24, 12, 2, 571, 123, 3, 2, 2, 2, 572, 573, 5, 28, 14, 2, 573, 574, 5, 14, 7, 2, 574, 575, 5, 24, 12, 2, 575, 576, 5, 40, 20, 2, 576, 125, 3, 2, 2, 2, 577, 578, 5, 32, 16, 2, 578, 579, 5, 16, 8, 2, 579, 580, 5, 20, 10, 2, 580, 127, 3, 2, 2, 2, 581, 582, 5, 32, 16, 2, 582, 583, 5, 34, 17, 2, 583, 584, 5, 36, 18, 2, 584, 129, 3, 2, 2, 2, 585, 586, 5, 34, 17, 2, 586, 587, 5, 40, 20, 2, 587, 131, 3, 2, 2, 2, 588, 589, 5, 34, 17, 2, 589, 590, 5, 44, 22, 2, 590, 591, 5, 14, 7, 2, 591, 592, 5, 40, 20, 2, 592, 133, 3, 2, 2, 2, 593, 594, 5, 34, 17, 2, 594, 595, 5, 44, 22, 2, 595, 596, 5, 24, 12, 2, 596, 597, 5, 40, 20, 2, 597, 135, 3, 2, 2, 2, 598, 599, 5, 34, 17, 2, 599, 600, 5, 46, 23, 2, 600, 601, 5, 44, 22, 2, 601, 137, 3, 2, 2, 2, 602, 603, 5, 34, 17, 2, 603, 604, 5, 46, 23, 2, 604, 605, 5, 44, 22, 2, 605, 606, 5, 14, 7, 2, 606, 139, 3, 2, 2, 2, 607, 608, 5, 34, 17, 2, 608, 609, 5, 46, 23, 2, 609, 610, 5, 44, 22, 2, 610, 611, 5, 24, 12, 2, 611, 141, 3, 2, 2, 2, 612, 613, 5, 36, 18, 2, 613, 614, 5, 34, 17, 2, 614, 615, 5, 36, 18, 2, 615, 143, 3, 2, 2, 2, 616, 617, 5, 36, 18, 2, 617, 618, 5, 46, 23, 2, 618, 619, 5, 42, 21, 2, 619, 620, 5, 22, 11, 2, 620, 145, 3, 2, 2, 2, 621, 622, 5, 40, 20, 2, 622, 623, 5, 16, 8, 2, 623, 624, 5, 42, 21, 2, 624, 147, 3, 2, 2, 2, 625, 626, 5, 40, 20, 2, 626, 627, 5, 16, 8, 2, 627, 628, 5, 44, 22, 2, 628, 629, 3, 2, 2, 2, 629, 630, 8, 74, 3, 2, 630, 149, 3, 2, 2, 2, 631, 632, 5, 40, 20, 2, 632, 633, 5, 16, 8, 2, 633, 634, 5, 44, 22, 2, 634, 635, 5, 24, 12, 2, 635, 151, 3, 2, 2, 2, 636, 637, 5, 40, 20, 2, 637, 638, 5, 16, 8, 2, 638, 639, 5, 44, 22, 2, 639, 640, 5, 32, 16, 2, 640, 153, 3, 2, 2, 2, 641, 642, 5, 40, 20, 2, 642, 643, 5, 28, 14, 2, 643, 155, 3, 2, 2, 2, 644, 645, 5, 40, 20, 2, 645, 646, 5, 28, 14, 2, 646, 647, 5, 8, 4, 2, 647, 157, 3, 2, 2, 2, 648, 649, 5, 40, 20, 2, 649, 650, 5, 28, 14, 2, 650, 651, 5, 12, 6, 2, 651, 159, 3, 2, 2, 2, 652, 653, 5, 40, 20, 2, 653, 654, 5, 28, 14, 2, 654, 655, 5, 12, 6, 2, 655, 656, 5, 8, 4, 2, 656, 161, 3, 2, 2, 2, 657, 658, 5, 40, 20, 2, 658, 659, 5, 28, 14, 2, 659, 660, 5, 14, 7, 2, 660, 163, 3, 2, 2, 2, 661, 662, 5, 40, 20, 2, 662, 663, 5, 40, 20, 2, 663, 165, 3, 2, 2, 2, 664, 665, 5, 40, 20, 2, 665, 666, 5, 40, 20, 2, 666, 667, 5, 8, 4, 2, 667, 167, 3, 2, 2, 2, 668, 669, 5, 40, 20, 2, 669, 670, 5, 40, 20, 2, 670, 671, 5, 12, 6, 2, 671, 169, 3, 2, 2, 2, 672, 673, 5, 40, 20, 2, 673, 674, 5, 40, 20, 2, 674, 675, 5, 12, 6, 2, 675, 676, 5, 8, 4, 2, 676, 171, 3, 2, 2, 2, 677, 678, 5, 40, 20, 2, 678, 679, 5, 40, 20, 2, 679, 680, 5, 14, 7, 2, 680, 173, 3, 2, 2, 2, 681, 682, 5, 40, 20, 2, 682, 683, 5, 42, 21, 2, 683, 684, 5, 44, 22, 2, 684, 175, 3, 2, 2, 2, 685, 686, 5, 42, 21, 2, 686, 687, 5, 10, 5, 2, 687, 688, 5, 12, 6, 2, 688, 177, 3, 2, 2, 2, 689, 690, 5, 42, 21, 2, 690, 691, 5, 12, 6, 2, 691, 692, 5, 18, 9, 2, 692, 179, 3, 2, 2, 2, 693, 694, 5, 42, 21, 2, 694, 695, 5, 16, 8, 2, 695, 696, 5, 44, 22, 2, 696, 181, 3, 2, 2, 2, 697, 698, 5, 42, 21, 2, 698, 699, 5, 28, 14, 2, 699, 700, 5, 8, 4, 2, 700, 183, 3, 2, 2, 2, 701, 702, 5, 42, 21, 2, 702, 703, 5, 40, 20, 2, 703, 704, 5, 8, 4, 2, 704, 185, 3, 2, 2, 2, 705, 706, 5, 42, 21, 2, 706, 707, 5, 28, 14, 2, 707, 708, 5, 28, 14, 2, 708, 187, 3, 2, 2, 2, 709, 710, 5, 42, 21, 2, 710, 711, 5, 40, 20, 2, 711, 712, 5, 28, 14, 2, 712, 189, 3, 2, 2, 2, 713, 714, 5, 42, 21, 2, 714, 715, 5, 46, 23, 2, 715, 716, 5, 10, 5, 2, 716, 191, 3, 2, 2, 2, 717, 718, 5, 52, 26, 2, 718, 719, 5, 34, 17, 2, 719, 720, 5, 40, 20, 2, 720, 193, 3, 2, 2, 2, 721, 722, 5, 12, 6, 2, 722, 723, 3, 2, 2, 2, 723, 724, 8, 97, 4, 2, 724, 195, 3, 2, 2, 2, 725, 726, 5, 32, 16, 2, 726, 727, 5, 12, 6, 2, 727, 728, 3, 2, 2, 2, 728, 729, 8, 98, 4, 2, 729, 197, 3, 2, 2, 2, 730, 731, 5, 56, 28, 2, 731, 732, 3, 2, 2, 2, 732, 733, 8, 99, 4, 2, 733, 199, 3, 2, 2, 2, 734, 735, 5, 32, 16, 2, 735, 736, 5, 56, 28, 2, 736, 737, 3, 2, 2, 2, 737, 738, 8, 100, 4, 2, 738, 201, 3, 2, 2, 2, 739, 740, 5, 30, 15, 2, 740, 741, 3, 2, 2, 2, 741, 742, 8, 101, 4, 2, 742, 203, 3, 2, 2, 2, 743, 744, 5, 36, 18, 2, 744, 745, 3, 2, 2, 2, 745, 746, 8, 102, 4, 2, 746, 205, 3, 2, 2, 2, 747, 748, 5, 36, 18, 2, 748, 749, 5, 16, 8, 2, 749, 750, 3, 2, 2, 2, 750, 751, 8, 103, 4, 2, 751, 207, 3, 2, 2, 2, 752, 753, 5, 36, 18, 2, 753, 754, 5, 34, 17, 2, 754, 755, 3, 2, 2, 2, 755, 756, 8, 104, 4, 2, 756, 209, 3, 2, 2, 2, 757, 759, 9, 29, 2, 2, 758, 757, 3, 2, 2, 2, 759, 760, 3, 2, 2, 2, 760, 758, 3, 2, 2, 2, 760, 761, 3, 2, 2, 2, 761, 762, 3, 2, 2, 2, 762, 763, 8, 105, 2, 2, 763, 211, 3, 2, 2, 2, 764, 765, 6, 106, 2, 2, 765, 766, 3, 2, 2, 2, 766, 767, 8, 106, 4, 2, 767, 213, 3, 2, 2, 2, 768, 769, 5, 34, 17, 2, 769, 770, 5, 40, 20, 2, 770, 771, 5, 20, 10, 2, 771, 215, 3, 2, 2, 2, 772, 773, 5, 16, 8, 2, 773, 774, 5, 38, 19, 2, 774, 775, 5, 46, 23, 2, 775, 217, 3, 2, 2, 2, 776, 777, 5, 42, 21, 2, 777, 778, 5, 16, 8, 2, 778, 779, 5, 44, 22, 2, 779, 219, 3, 2, 2, 2, 780, 781, 5, 24, 12, 2, 781, 782, 5, 18, 9, 2, 782, 221, 3, 2, 2, 2, 783, 784, 5, 16, 8, 2, 784, 785, 5, 32, 16, 2, 785, 786, 5, 14, 7, 2, 786, 787, 5, 24, 12, 2, 787, 788, 5, 18, 9, 2, 788, 223, 3, 2, 2, 2, 789, 790, 5, 24, 12, 2, 790, 791, 5, 32, 16, 2, 791, 792, 5, 12, 6, 2, 792, 793, 5, 28, 14, 2, 793, 794, 5, 46, 23, 2, 794, 795, 5, 14, 7, 2, 795, 796, 5, 16, 8, 2, 796, 225, 3, 2, 2, 2, 797, 798, 5, 30, 15, 2, 798, 799, 5, 8, 4, 2, 799, 800, 5, 12, 6, 2, 800, 801, 5, 40, 20, 2, 801, 802, 5, 34, 17, 2, 802, 227, 3, 2, 2, 2, 803, 804, 5, 16, 8, 2, 804, 805, 5, 32, 16, 2, 805, 806, 5, 14, 7, 2, 806, 807, 5, 30, 15, 2, 807, 229, 3, 2, 2, 2, 808, 809, 5, 14, 7, 2, 809, 810, 5, 10, 5, 2, 810, 231, 3, 2, 2, 2, 811, 812, 5, 14, 7, 2, 812, 813, 5, 50, 25, 2, 813, 233, 3, 2, 2, 2, 814, 815, 5, 14, 7, 2, 815, 816, 5, 42, 21, 2, 816, 235, 3, 2, 2, 2, 817, 818, 7, 38, 2, 2, 818, 237, 3, 2, 2, 2, 819, 820, 5, 8, 4, 2, 820, 239, 3, 2, 2, 2, 821, 822, 5, 10, 5, 2, 822, 241, 3, 2, 2, 2, 823, 824, 5, 12, 6, 2, 824, 243, 3, 2, 2, 2, 825, 826, 5, 14, 7, 2, 826, 245, 3, 2, 2, 2, 827, 828, 5, 16, 8, 2, 828, 247, 3, 2, 2, 2, 829, 830, 5, 22, 11, 2, 830, 249, 3, 2, 2, 2, 831, 832, 5, 28, 14, 2, 832, 251, 3, 2, 2, 2, 833, 834, 5, 24, 12, 2, 834, 835, 5, 52, 26, 2, 835, 253, 3, 2, 2, 2, 836, 837, 5, 24, 12, 2, 837, 838, 5, 52, 26, 2, 838, 839, 5, 22, 11, 2, 839, 255, 3, 2, 2, 2, 840, 841, 5, 24, 12, 2, 841, 842, 5, 52, 26, 2, 842, 843, 5, 28, 14, 2, 843, 257, 3, 2, 2, 2, 844, 845, 5, 24, 12, 2, 845, 846, 5, 54, 27, 2, 846, 259, 3, 2, 2, 2, 847, 848, 5, 24, 12, 2, 848, 849, 5, 54, 27, 2, 849, 850, 5, 22, 11, 2, 850, 261, 3, 2, 2, 2, 851, 852, 5, 24, 12, 2, 852, 853, 5, 54, 27, 2, 853, 854, 5, 28, 14, 2, 854, 263, 3, 2, 2, 2, 855, 856, 5, 10, 5, 2, 856, 857, 5, 12, 6, 2, 857, 265, 3, 2, 2, 2, 858, 859, 5, 14, 7, 2, 859, 860, 5, 16, 8, 2, 860, 267, 3, 2, 2, 2, 861, 862, 5, 22, 11, 2, 862, 863, 5, 28, 14, 2, 863, 269, 3, 2, 2, 2, 864, 865, 5, 42, 21, 2, 865, 866, 5, 36, 18, 2, 866, 271, 3, 2, 2, 2, 867, 868, 5, 8, 4, 2, 868, 869, 5, 18, 9, 2, 869, 273, 3, 2, 2, 2, 870, 871, 5, 8, 4, 2, 871, 872, 5, 18, 9, 2, 872, 873, 7, 41, 2, 2, 873, 275, 3, 2, 2, 2, 874, 875, 5, 24, 12, 2, 875, 277, 3, 2, 2, 2, 876, 877, 5, 40, 20, 2, 877, 279, 3, 2, 2, 2, 878, 879, 5, 30, 15, 2, 879, 880, 5, 34, 17, 2, 880, 881, 5, 14, 7, 2, 881, 281, 3, 2, 2, 2, 882, 883, 5, 42, 21, 2, 883, 884, 5, 22, 11, 2, 884, 885, 5, 40, 20, 2, 885, 283, 3, 2, 2, 2, 886, 887, 5, 42, 21, 2, 887, 888, 5, 22, 11, 2, 888, 889, 5, 28, 14, 2, 889, 285, 3, 2, 2, 2, 890, 891, 5, 32, 16, 2, 891, 892, 5, 34, 17, 2, 892, 893, 5, 44, 22, 2, 893, 287, 3, 2, 2, 2, 894, 895, 5, 8, 4, 2, 895, 896, 5, 32, 16, 2, 896, 897, 5, 14, 7, 2, 897, 289, 3, 2, 2, 2, 898, 899, 5, 34, 17, 2, 899, 900, 5, 40, 20, 2, 900, 291, 3, 2, 2, 2, 901, 902, 5, 52, 26, 2, 902, 903, 5, 34, 17, 2, 903, 904, 5, 40, 20, 2, 904, 293, 3, 2, 2, 2, 905, 906, 7, 50, 2, 2, 906, 908, 5, 52, 26, 2, 907, 909, 9, 30, 2, 2, 908, 907, 3, 2, 2, 2, 909, 910, 3, 2, 2, 2, 910, 908, 3, 2, 2, 2, 910, 911, 3, 2, 2, 2, 911, 295, 3, 2, 2, 2, 912, 914, 9, 31, 2, 2, 913, 912, 3, 2, 2, 2, 914, 915, 3, 2, 2, 2, 915, 913, 3, 2, 2, 2, 915, 916, 3, 2, 2, 2, 916, 918, 3, 2, 2, 2, 917, 919, 5, 14, 7, 2, 918, 917, 3, 2, 2, 2, 918, 919, 3, 2, 2, 2, 919, 297, 3, 2, 2, 2, 920, 922, 9, 30, 2, 2, 921, 920, 3, 2, 2, 2, 922, 923, 3, 2, 2, 2, 923, 921, 3, 2, 2, 2, 923, 924, 3, 2, 2, 2, 924, 925, 3, 2, 2, 2, 925, 926, 5, 22, 11, 2, 926, 299, 3, 2, 2, 2, 927, 929, 9, 32, 2, 2, 928, 927, 3, 2, 2, 2, 929, 930, 3, 2, 2, 2, 930, 928, 3, 2, 2, 2, 930, 931, 3, 2, 2, 2, 931, 932, 3, 2, 2, 2, 932, 933, 9, 33, 2, 2, 933, 301, 3, 2, 2, 2, 934, 936, 9, 34, 2, 2, 935, 934, 3, 2, 2, 2, 936, 937, 3, 2, 2, 2, 937, 935, 3, 2, 2, 2, 937, 938, 3, 2, 2, 2, 938, 939, 3, 2, 2, 2, 939, 940, 5, 10, 5, 2, 940, 303, 3, 2, 2, 2, 941, 945, 7, 41, 2, 2, 942, 944, 10, 35, 2, 2, 943, 942, 3, 2, 2, 2, 944, 947, 3, 2, 2, 2, 945, 943, 3, 2, 2, 2, 945, 946, 3, 2, 2, 2, 946, 948, 3, 2, 2, 2, 947, 945, 3, 2, 2, 2, 948, 949, 7, 41, 2, 2, 949, 305, 3, 2, 2, 2, 950, 954, 7, 36, 2, 2, 951, 953, 10, 36, 2, 2, 952, 951, 3, 2, 2, 2, 953, 956, 3, 2, 2, 2, 954, 952, 3, 2, 2, 2, 954, 955, 3, 2, 2, 2, 955, 957, 3, 2, 2, 2, 956, 954, 3, 2, 2, 2, 957, 958, 7, 36, 2, 2, 958, 307, 3, 2, 2, 2, 959, 963, 9, 37, 2, 2, 960, 962, 9, 38, 2, 2, 961, 960, 3, 2, 2, 2, 962, 965, 3, 2, 2, 2, 963, 961, 3, 2, 2, 2, 963, 964, 3, 2, 2, 2, 964, 309, 3, 2, 2, 2, 965, 963, 3, 2, 2, 2, 966, 967, 5, 308, 154, 2, 967, 968, 7, 60, 2, 2, 968, 311, 3, 2, 2, 2, 969, 971, 10, 39, 2, 2, 970, 969, 3, 2, 2, 2, 971, 972, 3, 2, 2, 2, 972, 970, 3, 2, 2, 2, 972, 973, 3, 2, 2, 2, 973, 313, 3, 2, 2, 2, 974, 975, 7, 42, 2, 2, 975, 315, 3, 2, 2, 2, 976, 977, 7, 43, 2, 2, 977, 317, 3, 2, 2, 2, 978, 979, 7, 46, 2, 2, 979, 319, 3, 2, 2, 2, 980, 981, 7, 45, 2, 2, 981, 321, 3, 2, 2, 2, 982, 983, 7, 47, 2, 2, 983, 323, 3, 2, 2, 2, 984, 985, 7, 44, 2, 2, 985, 325, 3, 2, 2, 2, 986, 987, 7, 49, 2, 2, 987, 327, 3, 2, 2, 2, 988, 989, 7, 63, 2, 2, 989, 329, 3, 2, 2, 2, 990, 991, 7, 64, 2, 2, 991, 331, 3, 2, 2, 2, 992, 993, 7, 64, 2, 2, 993, 994, 7, 63, 2, 2, 994, 333, 3, 2, 2, 2, 995, 996, 7, 62, 2, 2, 996, 335, 3, 2, 2, 2, 997, 998, 7, 62, 2, 2, 998, 999, 7, 63, 2, 2, 999, 337, 3, 2, 2, 2, 1000, 1001, 7, 39, 2, 2, 1001, 339, 3, 2, 2, 2, 1002, 1003, 7, 64, 2, 2, 1003, 1004, 7, 64, 2, 2, 1004, 341, 3, 2, 2, 2, 1005, 1006, 7, 62, 2, 2, 1006, 1007, 7, 62, 2, 2, 1007, 343, 3, 2, 2, 2, 1008, 1009, 7, 128, 2, 2, 1009, 345, 3, 2, 2, 2, 1010, 1011, 7, 40, 2, 2, 1011, 347, 3, 2, 2, 2, 1012, 1013, 7, 126, 2, 2, 1013, 349, 3, 2, 2, 2, 1014, 1015, 7, 96, 2, 2, 1015, 351, 3, 2, 2, 2, 1016, 1018, 9, 29, 2, 2, 1017, 1016, 3, 2, 2, 2, 1018, 1019, 3, 2, 2, 2, 1019, 1017, 3, 2, 2, 2, 1019, 1020, 3, 2, 2, 2, 1020, 1021, 3, 2, 2, 2, 1021, 1022, 8, 176, 2, 2, 1022, 353, 3, 2, 2, 2, 1023, 1025, 7, 15, 2, 2, 1024, 1023, 3, 2, 2, 2, 1024, 1025, 3, 2, 2, 2, 1025, 1026, 3, 2, 2, 2, 1026, 1027, 7, 12, 2, 2, 1027, 355, 3, 2, 2, 2, 20, 2, 3, 361, 366, 377, 760, 910, 915, 918, 923, 930, 937, 945, 954, 963, 972, 1019, 1024, 5, 8, 2, 2, 7, 3, 2, 6, 2, 2] \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java deleted file mode 100644 index d2bbdbb43..000000000 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.java +++ /dev/null @@ -1,592 +0,0 @@ -// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 by ANTLR 4.9.2 -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class AsZ80Lexer extends Lexer { - static { RuntimeMetaData.checkVersion("4.9.2", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - COMMENT=1, COMMENT2=2, OPCODE_ADC=3, OPCODE_ADD=4, OPCODE_AND=5, OPCODE_BIT=6, - OPCODE_CALL=7, OPCODE_CCF=8, OPCODE_CP=9, OPCODE_CPD=10, OPCODE_CPDR=11, - OPCODE_CPI=12, OPCODE_CPIR=13, OPCODE_CPL=14, OPCODE_DAA=15, OPCODE_DEC=16, - OPCODE_DI=17, OPCODE_DJNZ=18, OPCODE_EI=19, OPCODE_EX=20, OPCODE_EXX=21, - OPCODE_HALT=22, OPCODE_IM=23, OPCODE_IN=24, OPCODE_INC=25, OPCODE_IND=26, - OPCODE_INDR=27, OPCODE_INI=28, OPCODE_INIR=29, OPCODE_JP=30, OPCODE_JR=31, - OPCODE_LD=32, OPCODE_LDD=33, OPCODE_LDDR=34, OPCODE_LDI=35, OPCODE_LDIR=36, - OPCODE_NEG=37, OPCODE_NOP=38, OPCODE_OR=39, OPCODE_OTDR=40, OPCODE_OTIR=41, - OPCODE_OUT=42, OPCODE_OUTD=43, OPCODE_OUTI=44, OPCODE_POP=45, OPCODE_PUSH=46, - OPCODE_RES=47, OPCODE_RET=48, OPCODE_RETI=49, OPCODE_RETN=50, OPCODE_RL=51, - OPCODE_RLA=52, OPCODE_RLC=53, OPCODE_RLCA=54, OPCODE_RLD=55, OPCODE_RR=56, - OPCODE_RRA=57, OPCODE_RRC=58, OPCODE_RRCA=59, OPCODE_RRD=60, OPCODE_RST=61, - OPCODE_SBC=62, OPCODE_SCF=63, OPCODE_SET=64, OPCODE_SLA=65, OPCODE_SRA=66, - OPCODE_SLL=67, OPCODE_SRL=68, OPCODE_SUB=69, OPCODE_XOR=70, COND_C=71, - COND_NC=72, COND_Z=73, COND_NZ=74, COND_M=75, COND_P=76, COND_PE=77, COND_PO=78, - COND_WS=79, COND_UNRECOGNIZED=80, PREP_ORG=81, PREP_EQU=82, PREP_SET=83, - PREP_IF=84, PREP_ENDIF=85, PREP_INCLUDE=86, PREP_MACRO=87, PREP_ENDM=88, - PREP_DB=89, PREP_DW=90, PREP_DS=91, PREP_ADDR=92, REG_A=93, REG_B=94, - REG_C=95, REG_D=96, REG_E=97, REG_H=98, REG_L=99, REG_IX=100, REG_IXH=101, - REG_IXL=102, REG_IY=103, REG_IYH=104, REG_IYL=105, REG_BC=106, REG_DE=107, - REG_HL=108, REG_SP=109, REG_AF=110, REG_AFF=111, REG_I=112, REG_R=113, - OP_MOD=114, OP_SHR=115, OP_SHL=116, OP_NOT=117, OP_AND=118, OP_OR=119, - OP_XOR=120, LIT_HEXNUMBER_1=121, LIT_NUMBER=122, LIT_HEXNUMBER_2=123, - LIT_OCTNUMBER=124, LIT_BINNUMBER=125, LIT_STRING_1=126, LIT_STRING_2=127, - ID_IDENTIFIER=128, ID_LABEL=129, ERROR=130, SEP_LPAR=131, SEP_RPAR=132, - SEP_COMMA=133, OP_ADD=134, OP_SUBTRACT=135, OP_MULTIPLY=136, OP_DIVIDE=137, - OP_EQUAL=138, OP_GT=139, OP_GTE=140, OP_LT=141, OP_LTE=142, OP_MOD_2=143, - OP_SHR_2=144, OP_SHL_2=145, OP_NOT_2=146, OP_AND_2=147, OP_OR_2=148, OP_XOR_2=149, - WS=150, EOL=151; - public static final int - CONDITION=1; - public static String[] channelNames = { - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }; - - public static String[] modeNames = { - "DEFAULT_MODE", "CONDITION" - }; - - private static String[] makeRuleNames() { - return new String[] { - "COMMENT", "COMMENT2", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", - "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", - "Z", "OPCODE_ADC", "OPCODE_ADD", "OPCODE_AND", "OPCODE_BIT", "OPCODE_CALL", - "OPCODE_CCF", "OPCODE_CP", "OPCODE_CPD", "OPCODE_CPDR", "OPCODE_CPI", - "OPCODE_CPIR", "OPCODE_CPL", "OPCODE_DAA", "OPCODE_DEC", "OPCODE_DI", - "OPCODE_DJNZ", "OPCODE_EI", "OPCODE_EX", "OPCODE_EXX", "OPCODE_HALT", - "OPCODE_IM", "OPCODE_IN", "OPCODE_INC", "OPCODE_IND", "OPCODE_INDR", - "OPCODE_INI", "OPCODE_INIR", "OPCODE_JP", "OPCODE_JR", "OPCODE_LD", "OPCODE_LDD", - "OPCODE_LDDR", "OPCODE_LDI", "OPCODE_LDIR", "OPCODE_NEG", "OPCODE_NOP", - "OPCODE_OR", "OPCODE_OTDR", "OPCODE_OTIR", "OPCODE_OUT", "OPCODE_OUTD", - "OPCODE_OUTI", "OPCODE_POP", "OPCODE_PUSH", "OPCODE_RES", "OPCODE_RET", - "OPCODE_RETI", "OPCODE_RETN", "OPCODE_RL", "OPCODE_RLA", "OPCODE_RLC", - "OPCODE_RLCA", "OPCODE_RLD", "OPCODE_RR", "OPCODE_RRA", "OPCODE_RRC", - "OPCODE_RRCA", "OPCODE_RRD", "OPCODE_RST", "OPCODE_SBC", "OPCODE_SCF", - "OPCODE_SET", "OPCODE_SLA", "OPCODE_SRA", "OPCODE_SLL", "OPCODE_SRL", - "OPCODE_SUB", "OPCODE_XOR", "COND_C", "COND_NC", "COND_Z", "COND_NZ", - "COND_M", "COND_P", "COND_PE", "COND_PO", "COND_WS", "COND_UNRECOGNIZED", - "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_IF", "PREP_ENDIF", "PREP_INCLUDE", - "PREP_MACRO", "PREP_ENDM", "PREP_DB", "PREP_DW", "PREP_DS", "PREP_ADDR", - "REG_A", "REG_B", "REG_C", "REG_D", "REG_E", "REG_H", "REG_L", "REG_IX", - "REG_IXH", "REG_IXL", "REG_IY", "REG_IYH", "REG_IYL", "REG_BC", "REG_DE", - "REG_HL", "REG_SP", "REG_AF", "REG_AFF", "REG_I", "REG_R", "OP_MOD", - "OP_SHR", "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", "OP_XOR", "LIT_HEXNUMBER_1", - "LIT_NUMBER", "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", "LIT_BINNUMBER", "LIT_STRING_1", - "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", "ERROR", "SEP_LPAR", "SEP_RPAR", - "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", - "OP_GT", "OP_GTE", "OP_LT", "OP_LTE", "OP_MOD_2", "OP_SHR_2", "OP_SHL_2", - "OP_NOT_2", "OP_AND_2", "OP_OR_2", "OP_XOR_2", "WS", "EOL" - }; - } - public static final String[] ruleNames = makeRuleNames(); - - private static String[] makeLiteralNames() { - return new String[] { - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, "'$'", null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, "'('", - "')'", "','", "'+'", "'-'", "'*'", "'/'", "'='", "'>'", "'>='", "'<'", - "'<='", "'%'", "'>>'", "'<<'", "'~'", "'&'", "'|'", "'^'" - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - null, "COMMENT", "COMMENT2", "OPCODE_ADC", "OPCODE_ADD", "OPCODE_AND", - "OPCODE_BIT", "OPCODE_CALL", "OPCODE_CCF", "OPCODE_CP", "OPCODE_CPD", - "OPCODE_CPDR", "OPCODE_CPI", "OPCODE_CPIR", "OPCODE_CPL", "OPCODE_DAA", - "OPCODE_DEC", "OPCODE_DI", "OPCODE_DJNZ", "OPCODE_EI", "OPCODE_EX", "OPCODE_EXX", - "OPCODE_HALT", "OPCODE_IM", "OPCODE_IN", "OPCODE_INC", "OPCODE_IND", - "OPCODE_INDR", "OPCODE_INI", "OPCODE_INIR", "OPCODE_JP", "OPCODE_JR", - "OPCODE_LD", "OPCODE_LDD", "OPCODE_LDDR", "OPCODE_LDI", "OPCODE_LDIR", - "OPCODE_NEG", "OPCODE_NOP", "OPCODE_OR", "OPCODE_OTDR", "OPCODE_OTIR", - "OPCODE_OUT", "OPCODE_OUTD", "OPCODE_OUTI", "OPCODE_POP", "OPCODE_PUSH", - "OPCODE_RES", "OPCODE_RET", "OPCODE_RETI", "OPCODE_RETN", "OPCODE_RL", - "OPCODE_RLA", "OPCODE_RLC", "OPCODE_RLCA", "OPCODE_RLD", "OPCODE_RR", - "OPCODE_RRA", "OPCODE_RRC", "OPCODE_RRCA", "OPCODE_RRD", "OPCODE_RST", - "OPCODE_SBC", "OPCODE_SCF", "OPCODE_SET", "OPCODE_SLA", "OPCODE_SRA", - "OPCODE_SLL", "OPCODE_SRL", "OPCODE_SUB", "OPCODE_XOR", "COND_C", "COND_NC", - "COND_Z", "COND_NZ", "COND_M", "COND_P", "COND_PE", "COND_PO", "COND_WS", - "COND_UNRECOGNIZED", "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_IF", "PREP_ENDIF", - "PREP_INCLUDE", "PREP_MACRO", "PREP_ENDM", "PREP_DB", "PREP_DW", "PREP_DS", - "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", "REG_E", "REG_H", "REG_L", - "REG_IX", "REG_IXH", "REG_IXL", "REG_IY", "REG_IYH", "REG_IYL", "REG_BC", - "REG_DE", "REG_HL", "REG_SP", "REG_AF", "REG_AFF", "REG_I", "REG_R", - "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", "OP_AND", "OP_OR", "OP_XOR", - "LIT_HEXNUMBER_1", "LIT_NUMBER", "LIT_HEXNUMBER_2", "LIT_OCTNUMBER", - "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", "ID_LABEL", - "ERROR", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", - "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_GT", "OP_GTE", "OP_LT", "OP_LTE", - "OP_MOD_2", "OP_SHR_2", "OP_SHL_2", "OP_NOT_2", "OP_AND_2", "OP_OR_2", - "OP_XOR_2", "WS", "EOL" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - - public AsZ80Lexer(CharStream input) { - super(input); - _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - @Override - public String getGrammarFileName() { return "AsZ80Lexer.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public String[] getChannelNames() { return channelNames; } - - @Override - public String[] getModeNames() { return modeNames; } - - @Override - public ATN getATN() { return _ATN; } - - @Override - public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { - switch (ruleIndex) { - case 104: - return COND_UNRECOGNIZED_sempred((RuleContext)_localctx, predIndex); - } - return true; - } - private boolean COND_UNRECOGNIZED_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 0: - return "cCnNzZmMpP".indexOf((char) _input.LA(1)) == -1; - } - return true; - } - - public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u0099\u0404\b\1\b"+ - "\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n"+ - "\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21"+ - "\4\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30"+ - "\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37"+ - "\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t"+ - "*\4+\t+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63"+ - "\4\64\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t"+ - "<\4=\t=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4"+ - "H\tH\4I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\t"+ - "S\4T\tT\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^"+ - "\4_\t_\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j"+ - "\tj\4k\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu"+ - "\4v\tv\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080"+ - "\t\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084"+ - "\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089"+ - "\t\u0089\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c\t\u008c\4\u008d\t\u008d"+ - "\4\u008e\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090\4\u0091\t\u0091\4\u0092"+ - "\t\u0092\4\u0093\t\u0093\4\u0094\t\u0094\4\u0095\t\u0095\4\u0096\t\u0096"+ - "\4\u0097\t\u0097\4\u0098\t\u0098\4\u0099\t\u0099\4\u009a\t\u009a\4\u009b"+ - "\t\u009b\4\u009c\t\u009c\4\u009d\t\u009d\4\u009e\t\u009e\4\u009f\t\u009f"+ - "\4\u00a0\t\u00a0\4\u00a1\t\u00a1\4\u00a2\t\u00a2\4\u00a3\t\u00a3\4\u00a4"+ - "\t\u00a4\4\u00a5\t\u00a5\4\u00a6\t\u00a6\4\u00a7\t\u00a7\4\u00a8\t\u00a8"+ - "\4\u00a9\t\u00a9\4\u00aa\t\u00aa\4\u00ab\t\u00ab\4\u00ac\t\u00ac\4\u00ad"+ - "\t\u00ad\4\u00ae\t\u00ae\4\u00af\t\u00af\4\u00b0\t\u00b0\4\u00b1\t\u00b1"+ - "\3\2\3\2\3\2\3\2\3\2\5\2\u016a\n\2\3\2\7\2\u016d\n\2\f\2\16\2\u0170\13"+ - "\2\3\2\3\2\3\3\3\3\3\3\3\3\7\3\u0178\n\3\f\3\16\3\u017b\13\3\3\3\3\3\3"+ - "\3\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13"+ - "\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3\22\3\22"+ - "\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\31\3\31"+ - "\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36"+ - "\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\""+ - "\3#\3#\3#\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3"+ - "(\3(\3(\3(\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3+\3,\3,\3,\3,\3,\3-\3-\3-\3"+ - ".\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\3\61\3\61\3\61\3\62\3\62"+ - "\3\62\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\65\3\65\3\65\3\65\3\65"+ - "\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\3\67\38\38\38\38\38\39\39\39"+ - "\39\39\3:\3:\3:\3;\3;\3;\3;\3<\3<\3<\3<\3<\3=\3=\3=\3=\3>\3>\3>\3>\3>"+ - "\3?\3?\3?\3?\3@\3@\3@\3@\3A\3A\3A\3B\3B\3B\3B\3B\3C\3C\3C\3C\3C\3D\3D"+ - "\3D\3D\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3G\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I"+ - "\3I\3I\3J\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3M\3M\3M\3N\3N"+ - "\3N\3N\3O\3O\3O\3O\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3R\3R\3R\3S\3S\3S\3S\3T"+ - "\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3V\3V\3W\3W\3W\3W\3X\3X\3X\3X\3Y\3Y\3Y"+ - "\3Y\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3]\3]\3]\3]\3^\3^\3^\3^\3"+ - "_\3_\3_\3_\3`\3`\3`\3`\3a\3a\3a\3a\3b\3b\3b\3b\3b\3c\3c\3c\3c\3d\3d\3"+ - "d\3d\3d\3e\3e\3e\3e\3f\3f\3f\3f\3g\3g\3g\3g\3g\3h\3h\3h\3h\3h\3i\6i\u02f7"+ - "\ni\ri\16i\u02f8\3i\3i\3j\3j\3j\3j\3k\3k\3k\3k\3l\3l\3l\3l\3m\3m\3m\3"+ - "m\3n\3n\3n\3o\3o\3o\3o\3o\3o\3p\3p\3p\3p\3p\3p\3p\3p\3q\3q\3q\3q\3q\3"+ - "q\3r\3r\3r\3r\3r\3s\3s\3s\3t\3t\3t\3u\3u\3u\3v\3v\3w\3w\3x\3x\3y\3y\3"+ - "z\3z\3{\3{\3|\3|\3}\3}\3~\3~\3~\3\177\3\177\3\177\3\177\3\u0080\3\u0080"+ - "\3\u0080\3\u0080\3\u0081\3\u0081\3\u0081\3\u0082\3\u0082\3\u0082\3\u0082"+ - "\3\u0083\3\u0083\3\u0083\3\u0083\3\u0084\3\u0084\3\u0084\3\u0085\3\u0085"+ - "\3\u0085\3\u0086\3\u0086\3\u0086\3\u0087\3\u0087\3\u0087\3\u0088\3\u0088"+ - "\3\u0088\3\u0089\3\u0089\3\u0089\3\u0089\3\u008a\3\u008a\3\u008b\3\u008b"+ - "\3\u008c\3\u008c\3\u008c\3\u008c\3\u008d\3\u008d\3\u008d\3\u008d\3\u008e"+ - "\3\u008e\3\u008e\3\u008e\3\u008f\3\u008f\3\u008f\3\u008f\3\u0090\3\u0090"+ - "\3\u0090\3\u0090\3\u0091\3\u0091\3\u0091\3\u0092\3\u0092\3\u0092\3\u0092"+ - "\3\u0093\3\u0093\3\u0093\6\u0093\u038d\n\u0093\r\u0093\16\u0093\u038e"+ - "\3\u0094\6\u0094\u0392\n\u0094\r\u0094\16\u0094\u0393\3\u0094\5\u0094"+ - "\u0397\n\u0094\3\u0095\6\u0095\u039a\n\u0095\r\u0095\16\u0095\u039b\3"+ - "\u0095\3\u0095\3\u0096\6\u0096\u03a1\n\u0096\r\u0096\16\u0096\u03a2\3"+ - "\u0096\3\u0096\3\u0097\6\u0097\u03a8\n\u0097\r\u0097\16\u0097\u03a9\3"+ - "\u0097\3\u0097\3\u0098\3\u0098\7\u0098\u03b0\n\u0098\f\u0098\16\u0098"+ - "\u03b3\13\u0098\3\u0098\3\u0098\3\u0099\3\u0099\7\u0099\u03b9\n\u0099"+ - "\f\u0099\16\u0099\u03bc\13\u0099\3\u0099\3\u0099\3\u009a\3\u009a\7\u009a"+ - "\u03c2\n\u009a\f\u009a\16\u009a\u03c5\13\u009a\3\u009b\3\u009b\3\u009b"+ - "\3\u009c\6\u009c\u03cb\n\u009c\r\u009c\16\u009c\u03cc\3\u009d\3\u009d"+ - "\3\u009e\3\u009e\3\u009f\3\u009f\3\u00a0\3\u00a0\3\u00a1\3\u00a1\3\u00a2"+ - "\3\u00a2\3\u00a3\3\u00a3\3\u00a4\3\u00a4\3\u00a5\3\u00a5\3\u00a6\3\u00a6"+ - "\3\u00a6\3\u00a7\3\u00a7\3\u00a8\3\u00a8\3\u00a8\3\u00a9\3\u00a9\3\u00aa"+ - "\3\u00aa\3\u00aa\3\u00ab\3\u00ab\3\u00ab\3\u00ac\3\u00ac\3\u00ad\3\u00ad"+ - "\3\u00ae\3\u00ae\3\u00af\3\u00af\3\u00b0\6\u00b0\u03fa\n\u00b0\r\u00b0"+ - "\16\u00b0\u03fb\3\u00b0\3\u00b0\3\u00b1\5\u00b1\u0401\n\u00b1\3\u00b1"+ - "\3\u00b1\3\u0179\2\u00b2\4\3\6\4\b\2\n\2\f\2\16\2\20\2\22\2\24\2\26\2"+ - "\30\2\32\2\34\2\36\2 \2\"\2$\2&\2(\2*\2,\2.\2\60\2\62\2\64\2\66\28\2:"+ - "\5<\6>\7@\bB\tD\nF\13H\fJ\rL\16N\17P\20R\21T\22V\23X\24Z\25\\\26^\27`"+ - "\30b\31d\32f\33h\34j\35l\36n\37p r!t\"v#x$z%|&~\'\u0080(\u0082)\u0084"+ - "*\u0086+\u0088,\u008a-\u008c.\u008e/\u0090\60\u0092\61\u0094\62\u0096"+ - "\63\u0098\64\u009a\65\u009c\66\u009e\67\u00a08\u00a29\u00a4:\u00a6;\u00a8"+ - "<\u00aa=\u00ac>\u00ae?\u00b0@\u00b2A\u00b4B\u00b6C\u00b8D\u00baE\u00bc"+ - "F\u00beG\u00c0H\u00c2I\u00c4J\u00c6K\u00c8L\u00caM\u00ccN\u00ceO\u00d0"+ - "P\u00d2Q\u00d4R\u00d6S\u00d8T\u00daU\u00dcV\u00deW\u00e0X\u00e2Y\u00e4"+ - "Z\u00e6[\u00e8\\\u00ea]\u00ec^\u00ee_\u00f0`\u00f2a\u00f4b\u00f6c\u00f8"+ - "d\u00fae\u00fcf\u00feg\u0100h\u0102i\u0104j\u0106k\u0108l\u010am\u010c"+ - "n\u010eo\u0110p\u0112q\u0114r\u0116s\u0118t\u011au\u011cv\u011ew\u0120"+ - "x\u0122y\u0124z\u0126{\u0128|\u012a}\u012c~\u012e\177\u0130\u0080\u0132"+ - "\u0081\u0134\u0082\u0136\u0083\u0138\u0084\u013a\u0085\u013c\u0086\u013e"+ - "\u0087\u0140\u0088\u0142\u0089\u0144\u008a\u0146\u008b\u0148\u008c\u014a"+ - "\u008d\u014c\u008e\u014e\u008f\u0150\u0090\u0152\u0091\u0154\u0092\u0156"+ - "\u0093\u0158\u0094\u015a\u0095\u015c\u0096\u015e\u0097\u0160\u0098\u0162"+ - "\u0099\4\2\3(\4\2%%==\4\2\f\f\17\17\4\2CCcc\4\2DDdd\4\2EEee\4\2FFff\4"+ - "\2GGgg\4\2HHhh\4\2IIii\4\2JJjj\4\2KKkk\4\2LLll\4\2NNnn\4\2OOoo\4\2PPp"+ - "p\4\2QQqq\4\2RRrr\4\2SSss\4\2TTtt\4\2UUuu\4\2VVvv\4\2WWww\4\2XXxx\4\2"+ - "YYyy\4\2ZZzz\4\2[[{{\4\2\\\\||\5\2\13\13\16\16\"\"\5\2\62;CHch\3\2\62"+ - ";\3\2\629\6\2QQSSqqss\3\2\62\63\3\2))\3\2$$\5\2A\\aac|\6\2\62;A\\aac|"+ - "\f\2\13\f\16\17\"\"\'(*/\61\61>@``~~\u0080\u0080\2\u03fa\2\4\3\2\2\2\2"+ - "\6\3\2\2\2\2:\3\2\2\2\2<\3\2\2\2\2>\3\2\2\2\2@\3\2\2\2\2B\3\2\2\2\2D\3"+ - "\2\2\2\2F\3\2\2\2\2H\3\2\2\2\2J\3\2\2\2\2L\3\2\2\2\2N\3\2\2\2\2P\3\2\2"+ - "\2\2R\3\2\2\2\2T\3\2\2\2\2V\3\2\2\2\2X\3\2\2\2\2Z\3\2\2\2\2\\\3\2\2\2"+ - "\2^\3\2\2\2\2`\3\2\2\2\2b\3\2\2\2\2d\3\2\2\2\2f\3\2\2\2\2h\3\2\2\2\2j"+ - "\3\2\2\2\2l\3\2\2\2\2n\3\2\2\2\2p\3\2\2\2\2r\3\2\2\2\2t\3\2\2\2\2v\3\2"+ - "\2\2\2x\3\2\2\2\2z\3\2\2\2\2|\3\2\2\2\2~\3\2\2\2\2\u0080\3\2\2\2\2\u0082"+ - "\3\2\2\2\2\u0084\3\2\2\2\2\u0086\3\2\2\2\2\u0088\3\2\2\2\2\u008a\3\2\2"+ - "\2\2\u008c\3\2\2\2\2\u008e\3\2\2\2\2\u0090\3\2\2\2\2\u0092\3\2\2\2\2\u0094"+ - "\3\2\2\2\2\u0096\3\2\2\2\2\u0098\3\2\2\2\2\u009a\3\2\2\2\2\u009c\3\2\2"+ - "\2\2\u009e\3\2\2\2\2\u00a0\3\2\2\2\2\u00a2\3\2\2\2\2\u00a4\3\2\2\2\2\u00a6"+ - "\3\2\2\2\2\u00a8\3\2\2\2\2\u00aa\3\2\2\2\2\u00ac\3\2\2\2\2\u00ae\3\2\2"+ - "\2\2\u00b0\3\2\2\2\2\u00b2\3\2\2\2\2\u00b4\3\2\2\2\2\u00b6\3\2\2\2\2\u00b8"+ - "\3\2\2\2\2\u00ba\3\2\2\2\2\u00bc\3\2\2\2\2\u00be\3\2\2\2\2\u00c0\3\2\2"+ - "\2\2\u00d6\3\2\2\2\2\u00d8\3\2\2\2\2\u00da\3\2\2\2\2\u00dc\3\2\2\2\2\u00de"+ - "\3\2\2\2\2\u00e0\3\2\2\2\2\u00e2\3\2\2\2\2\u00e4\3\2\2\2\2\u00e6\3\2\2"+ - "\2\2\u00e8\3\2\2\2\2\u00ea\3\2\2\2\2\u00ec\3\2\2\2\2\u00ee\3\2\2\2\2\u00f0"+ - "\3\2\2\2\2\u00f2\3\2\2\2\2\u00f4\3\2\2\2\2\u00f6\3\2\2\2\2\u00f8\3\2\2"+ - "\2\2\u00fa\3\2\2\2\2\u00fc\3\2\2\2\2\u00fe\3\2\2\2\2\u0100\3\2\2\2\2\u0102"+ - "\3\2\2\2\2\u0104\3\2\2\2\2\u0106\3\2\2\2\2\u0108\3\2\2\2\2\u010a\3\2\2"+ - "\2\2\u010c\3\2\2\2\2\u010e\3\2\2\2\2\u0110\3\2\2\2\2\u0112\3\2\2\2\2\u0114"+ - "\3\2\2\2\2\u0116\3\2\2\2\2\u0118\3\2\2\2\2\u011a\3\2\2\2\2\u011c\3\2\2"+ - "\2\2\u011e\3\2\2\2\2\u0120\3\2\2\2\2\u0122\3\2\2\2\2\u0124\3\2\2\2\2\u0126"+ - "\3\2\2\2\2\u0128\3\2\2\2\2\u012a\3\2\2\2\2\u012c\3\2\2\2\2\u012e\3\2\2"+ - "\2\2\u0130\3\2\2\2\2\u0132\3\2\2\2\2\u0134\3\2\2\2\2\u0136\3\2\2\2\2\u0138"+ - "\3\2\2\2\2\u013a\3\2\2\2\2\u013c\3\2\2\2\2\u013e\3\2\2\2\2\u0140\3\2\2"+ - "\2\2\u0142\3\2\2\2\2\u0144\3\2\2\2\2\u0146\3\2\2\2\2\u0148\3\2\2\2\2\u014a"+ - "\3\2\2\2\2\u014c\3\2\2\2\2\u014e\3\2\2\2\2\u0150\3\2\2\2\2\u0152\3\2\2"+ - "\2\2\u0154\3\2\2\2\2\u0156\3\2\2\2\2\u0158\3\2\2\2\2\u015a\3\2\2\2\2\u015c"+ - "\3\2\2\2\2\u015e\3\2\2\2\2\u0160\3\2\2\2\2\u0162\3\2\2\2\3\u00c2\3\2\2"+ - "\2\3\u00c4\3\2\2\2\3\u00c6\3\2\2\2\3\u00c8\3\2\2\2\3\u00ca\3\2\2\2\3\u00cc"+ - "\3\2\2\2\3\u00ce\3\2\2\2\3\u00d0\3\2\2\2\3\u00d2\3\2\2\2\3\u00d4\3\2\2"+ - "\2\4\u0169\3\2\2\2\6\u0173\3\2\2\2\b\u0181\3\2\2\2\n\u0183\3\2\2\2\f\u0185"+ - "\3\2\2\2\16\u0187\3\2\2\2\20\u0189\3\2\2\2\22\u018b\3\2\2\2\24\u018d\3"+ - "\2\2\2\26\u018f\3\2\2\2\30\u0191\3\2\2\2\32\u0193\3\2\2\2\34\u0195\3\2"+ - "\2\2\36\u0197\3\2\2\2 \u0199\3\2\2\2\"\u019b\3\2\2\2$\u019d\3\2\2\2&\u019f"+ - "\3\2\2\2(\u01a1\3\2\2\2*\u01a3\3\2\2\2,\u01a5\3\2\2\2.\u01a7\3\2\2\2\60"+ - "\u01a9\3\2\2\2\62\u01ab\3\2\2\2\64\u01ad\3\2\2\2\66\u01af\3\2\2\28\u01b1"+ - "\3\2\2\2:\u01b3\3\2\2\2<\u01b7\3\2\2\2>\u01bb\3\2\2\2@\u01bf\3\2\2\2B"+ - "\u01c3\3\2\2\2D\u01ca\3\2\2\2F\u01ce\3\2\2\2H\u01d1\3\2\2\2J\u01d5\3\2"+ - "\2\2L\u01da\3\2\2\2N\u01de\3\2\2\2P\u01e3\3\2\2\2R\u01e7\3\2\2\2T\u01eb"+ - "\3\2\2\2V\u01ef\3\2\2\2X\u01f2\3\2\2\2Z\u01f7\3\2\2\2\\\u01fa\3\2\2\2"+ - "^\u01fd\3\2\2\2`\u0201\3\2\2\2b\u0206\3\2\2\2d\u0209\3\2\2\2f\u020c\3"+ - "\2\2\2h\u0210\3\2\2\2j\u0214\3\2\2\2l\u0219\3\2\2\2n\u021d\3\2\2\2p\u0222"+ - "\3\2\2\2r\u0227\3\2\2\2t\u022c\3\2\2\2v\u022f\3\2\2\2x\u0233\3\2\2\2z"+ - "\u0238\3\2\2\2|\u023c\3\2\2\2~\u0241\3\2\2\2\u0080\u0245\3\2\2\2\u0082"+ - "\u0249\3\2\2\2\u0084\u024c\3\2\2\2\u0086\u0251\3\2\2\2\u0088\u0256\3\2"+ - "\2\2\u008a\u025a\3\2\2\2\u008c\u025f\3\2\2\2\u008e\u0264\3\2\2\2\u0090"+ - "\u0268\3\2\2\2\u0092\u026d\3\2\2\2\u0094\u0271\3\2\2\2\u0096\u0277\3\2"+ - "\2\2\u0098\u027c\3\2\2\2\u009a\u0281\3\2\2\2\u009c\u0284\3\2\2\2\u009e"+ - "\u0288\3\2\2\2\u00a0\u028c\3\2\2\2\u00a2\u0291\3\2\2\2\u00a4\u0295\3\2"+ - "\2\2\u00a6\u0298\3\2\2\2\u00a8\u029c\3\2\2\2\u00aa\u02a0\3\2\2\2\u00ac"+ - "\u02a5\3\2\2\2\u00ae\u02a9\3\2\2\2\u00b0\u02ad\3\2\2\2\u00b2\u02b1\3\2"+ - "\2\2\u00b4\u02b5\3\2\2\2\u00b6\u02b9\3\2\2\2\u00b8\u02bd\3\2\2\2\u00ba"+ - "\u02c1\3\2\2\2\u00bc\u02c5\3\2\2\2\u00be\u02c9\3\2\2\2\u00c0\u02cd\3\2"+ - "\2\2\u00c2\u02d1\3\2\2\2\u00c4\u02d5\3\2\2\2\u00c6\u02da\3\2\2\2\u00c8"+ - "\u02de\3\2\2\2\u00ca\u02e3\3\2\2\2\u00cc\u02e7\3\2\2\2\u00ce\u02eb\3\2"+ - "\2\2\u00d0\u02f0\3\2\2\2\u00d2\u02f6\3\2\2\2\u00d4\u02fc\3\2\2\2\u00d6"+ - "\u0300\3\2\2\2\u00d8\u0304\3\2\2\2\u00da\u0308\3\2\2\2\u00dc\u030c\3\2"+ - "\2\2\u00de\u030f\3\2\2\2\u00e0\u0315\3\2\2\2\u00e2\u031d\3\2\2\2\u00e4"+ - "\u0323\3\2\2\2\u00e6\u0328\3\2\2\2\u00e8\u032b\3\2\2\2\u00ea\u032e\3\2"+ - "\2\2\u00ec\u0331\3\2\2\2\u00ee\u0333\3\2\2\2\u00f0\u0335\3\2\2\2\u00f2"+ - "\u0337\3\2\2\2\u00f4\u0339\3\2\2\2\u00f6\u033b\3\2\2\2\u00f8\u033d\3\2"+ - "\2\2\u00fa\u033f\3\2\2\2\u00fc\u0341\3\2\2\2\u00fe\u0344\3\2\2\2\u0100"+ - "\u0348\3\2\2\2\u0102\u034c\3\2\2\2\u0104\u034f\3\2\2\2\u0106\u0353\3\2"+ - "\2\2\u0108\u0357\3\2\2\2\u010a\u035a\3\2\2\2\u010c\u035d\3\2\2\2\u010e"+ - "\u0360\3\2\2\2\u0110\u0363\3\2\2\2\u0112\u0366\3\2\2\2\u0114\u036a\3\2"+ - "\2\2\u0116\u036c\3\2\2\2\u0118\u036e\3\2\2\2\u011a\u0372\3\2\2\2\u011c"+ - "\u0376\3\2\2\2\u011e\u037a\3\2\2\2\u0120\u037e\3\2\2\2\u0122\u0382\3\2"+ - "\2\2\u0124\u0385\3\2\2\2\u0126\u0389\3\2\2\2\u0128\u0391\3\2\2\2\u012a"+ - "\u0399\3\2\2\2\u012c\u03a0\3\2\2\2\u012e\u03a7\3\2\2\2\u0130\u03ad\3\2"+ - "\2\2\u0132\u03b6\3\2\2\2\u0134\u03bf\3\2\2\2\u0136\u03c6\3\2\2\2\u0138"+ - "\u03ca\3\2\2\2\u013a\u03ce\3\2\2\2\u013c\u03d0\3\2\2\2\u013e\u03d2\3\2"+ - "\2\2\u0140\u03d4\3\2\2\2\u0142\u03d6\3\2\2\2\u0144\u03d8\3\2\2\2\u0146"+ - "\u03da\3\2\2\2\u0148\u03dc\3\2\2\2\u014a\u03de\3\2\2\2\u014c\u03e0\3\2"+ - "\2\2\u014e\u03e3\3\2\2\2\u0150\u03e5\3\2\2\2\u0152\u03e8\3\2\2\2\u0154"+ - "\u03ea\3\2\2\2\u0156\u03ed\3\2\2\2\u0158\u03f0\3\2\2\2\u015a\u03f2\3\2"+ - "\2\2\u015c\u03f4\3\2\2\2\u015e\u03f6\3\2\2\2\u0160\u03f9\3\2\2\2\u0162"+ - "\u0400\3\2\2\2\u0164\u0165\7\61\2\2\u0165\u016a\7\61\2\2\u0166\u0167\7"+ - "/\2\2\u0167\u016a\7/\2\2\u0168\u016a\t\2\2\2\u0169\u0164\3\2\2\2\u0169"+ - "\u0166\3\2\2\2\u0169\u0168\3\2\2\2\u016a\u016e\3\2\2\2\u016b\u016d\n\3"+ - "\2\2\u016c\u016b\3\2\2\2\u016d\u0170\3\2\2\2\u016e\u016c\3\2\2\2\u016e"+ - "\u016f\3\2\2\2\u016f\u0171\3\2\2\2\u0170\u016e\3\2\2\2\u0171\u0172\b\2"+ - "\2\2\u0172\5\3\2\2\2\u0173\u0174\7\61\2\2\u0174\u0175\7,\2\2\u0175\u0179"+ - "\3\2\2\2\u0176\u0178\13\2\2\2\u0177\u0176\3\2\2\2\u0178\u017b\3\2\2\2"+ - "\u0179\u017a\3\2\2\2\u0179\u0177\3\2\2\2\u017a\u017c\3\2\2\2\u017b\u0179"+ - "\3\2\2\2\u017c\u017d\7,\2\2\u017d\u017e\7\61\2\2\u017e\u017f\3\2\2\2\u017f"+ - "\u0180\b\3\2\2\u0180\7\3\2\2\2\u0181\u0182\t\4\2\2\u0182\t\3\2\2\2\u0183"+ - "\u0184\t\5\2\2\u0184\13\3\2\2\2\u0185\u0186\t\6\2\2\u0186\r\3\2\2\2\u0187"+ - "\u0188\t\7\2\2\u0188\17\3\2\2\2\u0189\u018a\t\b\2\2\u018a\21\3\2\2\2\u018b"+ - "\u018c\t\t\2\2\u018c\23\3\2\2\2\u018d\u018e\t\n\2\2\u018e\25\3\2\2\2\u018f"+ - "\u0190\t\13\2\2\u0190\27\3\2\2\2\u0191\u0192\t\f\2\2\u0192\31\3\2\2\2"+ - "\u0193\u0194\t\r\2\2\u0194\33\3\2\2\2\u0195\u0196\t\16\2\2\u0196\35\3"+ - "\2\2\2\u0197\u0198\t\17\2\2\u0198\37\3\2\2\2\u0199\u019a\t\20\2\2\u019a"+ - "!\3\2\2\2\u019b\u019c\t\21\2\2\u019c#\3\2\2\2\u019d\u019e\t\22\2\2\u019e"+ - "%\3\2\2\2\u019f\u01a0\t\23\2\2\u01a0\'\3\2\2\2\u01a1\u01a2\t\24\2\2\u01a2"+ - ")\3\2\2\2\u01a3\u01a4\t\25\2\2\u01a4+\3\2\2\2\u01a5\u01a6\t\26\2\2\u01a6"+ - "-\3\2\2\2\u01a7\u01a8\t\27\2\2\u01a8/\3\2\2\2\u01a9\u01aa\t\30\2\2\u01aa"+ - "\61\3\2\2\2\u01ab\u01ac\t\31\2\2\u01ac\63\3\2\2\2\u01ad\u01ae\t\32\2\2"+ - "\u01ae\65\3\2\2\2\u01af\u01b0\t\33\2\2\u01b0\67\3\2\2\2\u01b1\u01b2\t"+ - "\34\2\2\u01b29\3\2\2\2\u01b3\u01b4\5\b\4\2\u01b4\u01b5\5\16\7\2\u01b5"+ - "\u01b6\5\f\6\2\u01b6;\3\2\2\2\u01b7\u01b8\5\b\4\2\u01b8\u01b9\5\16\7\2"+ - "\u01b9\u01ba\5\16\7\2\u01ba=\3\2\2\2\u01bb\u01bc\5\b\4\2\u01bc\u01bd\5"+ - " \20\2\u01bd\u01be\5\16\7\2\u01be?\3\2\2\2\u01bf\u01c0\5\n\5\2\u01c0\u01c1"+ - "\5\30\f\2\u01c1\u01c2\5,\26\2\u01c2A\3\2\2\2\u01c3\u01c4\5\f\6\2\u01c4"+ - "\u01c5\5\b\4\2\u01c5\u01c6\5\34\16\2\u01c6\u01c7\5\34\16\2\u01c7\u01c8"+ - "\3\2\2\2\u01c8\u01c9\b!\3\2\u01c9C\3\2\2\2\u01ca\u01cb\5\f\6\2\u01cb\u01cc"+ - "\5\f\6\2\u01cc\u01cd\5\22\t\2\u01cdE\3\2\2\2\u01ce\u01cf\5\f\6\2\u01cf"+ - "\u01d0\5$\22\2\u01d0G\3\2\2\2\u01d1\u01d2\5\f\6\2\u01d2\u01d3\5$\22\2"+ - "\u01d3\u01d4\5\16\7\2\u01d4I\3\2\2\2\u01d5\u01d6\5\f\6\2\u01d6\u01d7\5"+ - "$\22\2\u01d7\u01d8\5\16\7\2\u01d8\u01d9\5(\24\2\u01d9K\3\2\2\2\u01da\u01db"+ - "\5\f\6\2\u01db\u01dc\5$\22\2\u01dc\u01dd\5\30\f\2\u01ddM\3\2\2\2\u01de"+ - "\u01df\5\f\6\2\u01df\u01e0\5$\22\2\u01e0\u01e1\5\30\f\2\u01e1\u01e2\5"+ - "(\24\2\u01e2O\3\2\2\2\u01e3\u01e4\5\f\6\2\u01e4\u01e5\5$\22\2\u01e5\u01e6"+ - "\5\34\16\2\u01e6Q\3\2\2\2\u01e7\u01e8\5\16\7\2\u01e8\u01e9\5\b\4\2\u01e9"+ - "\u01ea\5\b\4\2\u01eaS\3\2\2\2\u01eb\u01ec\5\16\7\2\u01ec\u01ed\5\20\b"+ - "\2\u01ed\u01ee\5\f\6\2\u01eeU\3\2\2\2\u01ef\u01f0\5\16\7\2\u01f0\u01f1"+ - "\5\30\f\2\u01f1W\3\2\2\2\u01f2\u01f3\5\16\7\2\u01f3\u01f4\5\32\r\2\u01f4"+ - "\u01f5\5 \20\2\u01f5\u01f6\58\34\2\u01f6Y\3\2\2\2\u01f7\u01f8\5\20\b\2"+ - "\u01f8\u01f9\5\30\f\2\u01f9[\3\2\2\2\u01fa\u01fb\5\20\b\2\u01fb\u01fc"+ - "\5\64\32\2\u01fc]\3\2\2\2\u01fd\u01fe\5\20\b\2\u01fe\u01ff\5\64\32\2\u01ff"+ - "\u0200\5\64\32\2\u0200_\3\2\2\2\u0201\u0202\5\26\13\2\u0202\u0203\5\b"+ - "\4\2\u0203\u0204\5\34\16\2\u0204\u0205\5,\26\2\u0205a\3\2\2\2\u0206\u0207"+ - "\5\30\f\2\u0207\u0208\5\36\17\2\u0208c\3\2\2\2\u0209\u020a\5\30\f\2\u020a"+ - "\u020b\5 \20\2\u020be\3\2\2\2\u020c\u020d\5\30\f\2\u020d\u020e\5 \20\2"+ - "\u020e\u020f\5\f\6\2\u020fg\3\2\2\2\u0210\u0211\5\30\f\2\u0211\u0212\5"+ - " \20\2\u0212\u0213\5\16\7\2\u0213i\3\2\2\2\u0214\u0215\5\30\f\2\u0215"+ - "\u0216\5 \20\2\u0216\u0217\5\16\7\2\u0217\u0218\5(\24\2\u0218k\3\2\2\2"+ - "\u0219\u021a\5\30\f\2\u021a\u021b\5 \20\2\u021b\u021c\5\30\f\2\u021cm"+ - "\3\2\2\2\u021d\u021e\5\30\f\2\u021e\u021f\5 \20\2\u021f\u0220\5\30\f\2"+ - "\u0220\u0221\5(\24\2\u0221o\3\2\2\2\u0222\u0223\5\32\r\2\u0223\u0224\5"+ - "$\22\2\u0224\u0225\3\2\2\2\u0225\u0226\b8\3\2\u0226q\3\2\2\2\u0227\u0228"+ - "\5\32\r\2\u0228\u0229\5(\24\2\u0229\u022a\3\2\2\2\u022a\u022b\b9\3\2\u022b"+ - "s\3\2\2\2\u022c\u022d\5\34\16\2\u022d\u022e\5\16\7\2\u022eu\3\2\2\2\u022f"+ - "\u0230\5\34\16\2\u0230\u0231\5\16\7\2\u0231\u0232\5\16\7\2\u0232w\3\2"+ - "\2\2\u0233\u0234\5\34\16\2\u0234\u0235\5\16\7\2\u0235\u0236\5\16\7\2\u0236"+ - "\u0237\5(\24\2\u0237y\3\2\2\2\u0238\u0239\5\34\16\2\u0239\u023a\5\16\7"+ - "\2\u023a\u023b\5\30\f\2\u023b{\3\2\2\2\u023c\u023d\5\34\16\2\u023d\u023e"+ - "\5\16\7\2\u023e\u023f\5\30\f\2\u023f\u0240\5(\24\2\u0240}\3\2\2\2\u0241"+ - "\u0242\5 \20\2\u0242\u0243\5\20\b\2\u0243\u0244\5\24\n\2\u0244\177\3\2"+ - "\2\2\u0245\u0246\5 \20\2\u0246\u0247\5\"\21\2\u0247\u0248\5$\22\2\u0248"+ - "\u0081\3\2\2\2\u0249\u024a\5\"\21\2\u024a\u024b\5(\24\2\u024b\u0083\3"+ - "\2\2\2\u024c\u024d\5\"\21\2\u024d\u024e\5,\26\2\u024e\u024f\5\16\7\2\u024f"+ - "\u0250\5(\24\2\u0250\u0085\3\2\2\2\u0251\u0252\5\"\21\2\u0252\u0253\5"+ - ",\26\2\u0253\u0254\5\30\f\2\u0254\u0255\5(\24\2\u0255\u0087\3\2\2\2\u0256"+ - "\u0257\5\"\21\2\u0257\u0258\5.\27\2\u0258\u0259\5,\26\2\u0259\u0089\3"+ - "\2\2\2\u025a\u025b\5\"\21\2\u025b\u025c\5.\27\2\u025c\u025d\5,\26\2\u025d"+ - "\u025e\5\16\7\2\u025e\u008b\3\2\2\2\u025f\u0260\5\"\21\2\u0260\u0261\5"+ - ".\27\2\u0261\u0262\5,\26\2\u0262\u0263\5\30\f\2\u0263\u008d\3\2\2\2\u0264"+ - "\u0265\5$\22\2\u0265\u0266\5\"\21\2\u0266\u0267\5$\22\2\u0267\u008f\3"+ - "\2\2\2\u0268\u0269\5$\22\2\u0269\u026a\5.\27\2\u026a\u026b\5*\25\2\u026b"+ - "\u026c\5\26\13\2\u026c\u0091\3\2\2\2\u026d\u026e\5(\24\2\u026e\u026f\5"+ - "\20\b\2\u026f\u0270\5*\25\2\u0270\u0093\3\2\2\2\u0271\u0272\5(\24\2\u0272"+ - "\u0273\5\20\b\2\u0273\u0274\5,\26\2\u0274\u0275\3\2\2\2\u0275\u0276\b"+ - "J\3\2\u0276\u0095\3\2\2\2\u0277\u0278\5(\24\2\u0278\u0279\5\20\b\2\u0279"+ - "\u027a\5,\26\2\u027a\u027b\5\30\f\2\u027b\u0097\3\2\2\2\u027c\u027d\5"+ - "(\24\2\u027d\u027e\5\20\b\2\u027e\u027f\5,\26\2\u027f\u0280\5 \20\2\u0280"+ - "\u0099\3\2\2\2\u0281\u0282\5(\24\2\u0282\u0283\5\34\16\2\u0283\u009b\3"+ - "\2\2\2\u0284\u0285\5(\24\2\u0285\u0286\5\34\16\2\u0286\u0287\5\b\4\2\u0287"+ - "\u009d\3\2\2\2\u0288\u0289\5(\24\2\u0289\u028a\5\34\16\2\u028a\u028b\5"+ - "\f\6\2\u028b\u009f\3\2\2\2\u028c\u028d\5(\24\2\u028d\u028e\5\34\16\2\u028e"+ - "\u028f\5\f\6\2\u028f\u0290\5\b\4\2\u0290\u00a1\3\2\2\2\u0291\u0292\5("+ - "\24\2\u0292\u0293\5\34\16\2\u0293\u0294\5\16\7\2\u0294\u00a3\3\2\2\2\u0295"+ - "\u0296\5(\24\2\u0296\u0297\5(\24\2\u0297\u00a5\3\2\2\2\u0298\u0299\5("+ - "\24\2\u0299\u029a\5(\24\2\u029a\u029b\5\b\4\2\u029b\u00a7\3\2\2\2\u029c"+ - "\u029d\5(\24\2\u029d\u029e\5(\24\2\u029e\u029f\5\f\6\2\u029f\u00a9\3\2"+ - "\2\2\u02a0\u02a1\5(\24\2\u02a1\u02a2\5(\24\2\u02a2\u02a3\5\f\6\2\u02a3"+ - "\u02a4\5\b\4\2\u02a4\u00ab\3\2\2\2\u02a5\u02a6\5(\24\2\u02a6\u02a7\5("+ - "\24\2\u02a7\u02a8\5\16\7\2\u02a8\u00ad\3\2\2\2\u02a9\u02aa\5(\24\2\u02aa"+ - "\u02ab\5*\25\2\u02ab\u02ac\5,\26\2\u02ac\u00af\3\2\2\2\u02ad\u02ae\5*"+ - "\25\2\u02ae\u02af\5\n\5\2\u02af\u02b0\5\f\6\2\u02b0\u00b1\3\2\2\2\u02b1"+ - "\u02b2\5*\25\2\u02b2\u02b3\5\f\6\2\u02b3\u02b4\5\22\t\2\u02b4\u00b3\3"+ - "\2\2\2\u02b5\u02b6\5*\25\2\u02b6\u02b7\5\20\b\2\u02b7\u02b8\5,\26\2\u02b8"+ - "\u00b5\3\2\2\2\u02b9\u02ba\5*\25\2\u02ba\u02bb\5\34\16\2\u02bb\u02bc\5"+ - "\b\4\2\u02bc\u00b7\3\2\2\2\u02bd\u02be\5*\25\2\u02be\u02bf\5(\24\2\u02bf"+ - "\u02c0\5\b\4\2\u02c0\u00b9\3\2\2\2\u02c1\u02c2\5*\25\2\u02c2\u02c3\5\34"+ - "\16\2\u02c3\u02c4\5\34\16\2\u02c4\u00bb\3\2\2\2\u02c5\u02c6\5*\25\2\u02c6"+ - "\u02c7\5(\24\2\u02c7\u02c8\5\34\16\2\u02c8\u00bd\3\2\2\2\u02c9\u02ca\5"+ - "*\25\2\u02ca\u02cb\5.\27\2\u02cb\u02cc\5\n\5\2\u02cc\u00bf\3\2\2\2\u02cd"+ - "\u02ce\5\64\32\2\u02ce\u02cf\5\"\21\2\u02cf\u02d0\5(\24\2\u02d0\u00c1"+ - "\3\2\2\2\u02d1\u02d2\5\f\6\2\u02d2\u02d3\3\2\2\2\u02d3\u02d4\ba\4\2\u02d4"+ - "\u00c3\3\2\2\2\u02d5\u02d6\5 \20\2\u02d6\u02d7\5\f\6\2\u02d7\u02d8\3\2"+ - "\2\2\u02d8\u02d9\bb\4\2\u02d9\u00c5\3\2\2\2\u02da\u02db\58\34\2\u02db"+ - "\u02dc\3\2\2\2\u02dc\u02dd\bc\4\2\u02dd\u00c7\3\2\2\2\u02de\u02df\5 \20"+ - "\2\u02df\u02e0\58\34\2\u02e0\u02e1\3\2\2\2\u02e1\u02e2\bd\4\2\u02e2\u00c9"+ - "\3\2\2\2\u02e3\u02e4\5\36\17\2\u02e4\u02e5\3\2\2\2\u02e5\u02e6\be\4\2"+ - "\u02e6\u00cb\3\2\2\2\u02e7\u02e8\5$\22\2\u02e8\u02e9\3\2\2\2\u02e9\u02ea"+ - "\bf\4\2\u02ea\u00cd\3\2\2\2\u02eb\u02ec\5$\22\2\u02ec\u02ed\5\20\b\2\u02ed"+ - "\u02ee\3\2\2\2\u02ee\u02ef\bg\4\2\u02ef\u00cf\3\2\2\2\u02f0\u02f1\5$\22"+ - "\2\u02f1\u02f2\5\"\21\2\u02f2\u02f3\3\2\2\2\u02f3\u02f4\bh\4\2\u02f4\u00d1"+ - "\3\2\2\2\u02f5\u02f7\t\35\2\2\u02f6\u02f5\3\2\2\2\u02f7\u02f8\3\2\2\2"+ - "\u02f8\u02f6\3\2\2\2\u02f8\u02f9\3\2\2\2\u02f9\u02fa\3\2\2\2\u02fa\u02fb"+ - "\bi\2\2\u02fb\u00d3\3\2\2\2\u02fc\u02fd\6j\2\2\u02fd\u02fe\3\2\2\2\u02fe"+ - "\u02ff\bj\4\2\u02ff\u00d5\3\2\2\2\u0300\u0301\5\"\21\2\u0301\u0302\5("+ - "\24\2\u0302\u0303\5\24\n\2\u0303\u00d7\3\2\2\2\u0304\u0305\5\20\b\2\u0305"+ - "\u0306\5&\23\2\u0306\u0307\5.\27\2\u0307\u00d9\3\2\2\2\u0308\u0309\5*"+ - "\25\2\u0309\u030a\5\20\b\2\u030a\u030b\5,\26\2\u030b\u00db\3\2\2\2\u030c"+ - "\u030d\5\30\f\2\u030d\u030e\5\22\t\2\u030e\u00dd\3\2\2\2\u030f\u0310\5"+ - "\20\b\2\u0310\u0311\5 \20\2\u0311\u0312\5\16\7\2\u0312\u0313\5\30\f\2"+ - "\u0313\u0314\5\22\t\2\u0314\u00df\3\2\2\2\u0315\u0316\5\30\f\2\u0316\u0317"+ - "\5 \20\2\u0317\u0318\5\f\6\2\u0318\u0319\5\34\16\2\u0319\u031a\5.\27\2"+ - "\u031a\u031b\5\16\7\2\u031b\u031c\5\20\b\2\u031c\u00e1\3\2\2\2\u031d\u031e"+ - "\5\36\17\2\u031e\u031f\5\b\4\2\u031f\u0320\5\f\6\2\u0320\u0321\5(\24\2"+ - "\u0321\u0322\5\"\21\2\u0322\u00e3\3\2\2\2\u0323\u0324\5\20\b\2\u0324\u0325"+ - "\5 \20\2\u0325\u0326\5\16\7\2\u0326\u0327\5\36\17\2\u0327\u00e5\3\2\2"+ - "\2\u0328\u0329\5\16\7\2\u0329\u032a\5\n\5\2\u032a\u00e7\3\2\2\2\u032b"+ - "\u032c\5\16\7\2\u032c\u032d\5\62\31\2\u032d\u00e9\3\2\2\2\u032e\u032f"+ - "\5\16\7\2\u032f\u0330\5*\25\2\u0330\u00eb\3\2\2\2\u0331\u0332\7&\2\2\u0332"+ - "\u00ed\3\2\2\2\u0333\u0334\5\b\4\2\u0334\u00ef\3\2\2\2\u0335\u0336\5\n"+ - "\5\2\u0336\u00f1\3\2\2\2\u0337\u0338\5\f\6\2\u0338\u00f3\3\2\2\2\u0339"+ - "\u033a\5\16\7\2\u033a\u00f5\3\2\2\2\u033b\u033c\5\20\b\2\u033c\u00f7\3"+ - "\2\2\2\u033d\u033e\5\26\13\2\u033e\u00f9\3\2\2\2\u033f\u0340\5\34\16\2"+ - "\u0340\u00fb\3\2\2\2\u0341\u0342\5\30\f\2\u0342\u0343\5\64\32\2\u0343"+ - "\u00fd\3\2\2\2\u0344\u0345\5\30\f\2\u0345\u0346\5\64\32\2\u0346\u0347"+ - "\5\26\13\2\u0347\u00ff\3\2\2\2\u0348\u0349\5\30\f\2\u0349\u034a\5\64\32"+ - "\2\u034a\u034b\5\34\16\2\u034b\u0101\3\2\2\2\u034c\u034d\5\30\f\2\u034d"+ - "\u034e\5\66\33\2\u034e\u0103\3\2\2\2\u034f\u0350\5\30\f\2\u0350\u0351"+ - "\5\66\33\2\u0351\u0352\5\26\13\2\u0352\u0105\3\2\2\2\u0353\u0354\5\30"+ - "\f\2\u0354\u0355\5\66\33\2\u0355\u0356\5\34\16\2\u0356\u0107\3\2\2\2\u0357"+ - "\u0358\5\n\5\2\u0358\u0359\5\f\6\2\u0359\u0109\3\2\2\2\u035a\u035b\5\16"+ - "\7\2\u035b\u035c\5\20\b\2\u035c\u010b\3\2\2\2\u035d\u035e\5\26\13\2\u035e"+ - "\u035f\5\34\16\2\u035f\u010d\3\2\2\2\u0360\u0361\5*\25\2\u0361\u0362\5"+ - "$\22\2\u0362\u010f\3\2\2\2\u0363\u0364\5\b\4\2\u0364\u0365\5\22\t\2\u0365"+ - "\u0111\3\2\2\2\u0366\u0367\5\b\4\2\u0367\u0368\5\22\t\2\u0368\u0369\7"+ - ")\2\2\u0369\u0113\3\2\2\2\u036a\u036b\5\30\f\2\u036b\u0115\3\2\2\2\u036c"+ - "\u036d\5(\24\2\u036d\u0117\3\2\2\2\u036e\u036f\5\36\17\2\u036f\u0370\5"+ - "\"\21\2\u0370\u0371\5\16\7\2\u0371\u0119\3\2\2\2\u0372\u0373\5*\25\2\u0373"+ - "\u0374\5\26\13\2\u0374\u0375\5(\24\2\u0375\u011b\3\2\2\2\u0376\u0377\5"+ - "*\25\2\u0377\u0378\5\26\13\2\u0378\u0379\5\34\16\2\u0379\u011d\3\2\2\2"+ - "\u037a\u037b\5 \20\2\u037b\u037c\5\"\21\2\u037c\u037d\5,\26\2\u037d\u011f"+ - "\3\2\2\2\u037e\u037f\5\b\4\2\u037f\u0380\5 \20\2\u0380\u0381\5\16\7\2"+ - "\u0381\u0121\3\2\2\2\u0382\u0383\5\"\21\2\u0383\u0384\5(\24\2\u0384\u0123"+ - "\3\2\2\2\u0385\u0386\5\64\32\2\u0386\u0387\5\"\21\2\u0387\u0388\5(\24"+ - "\2\u0388\u0125\3\2\2\2\u0389\u038a\7\62\2\2\u038a\u038c\5\64\32\2\u038b"+ - "\u038d\t\36\2\2\u038c\u038b\3\2\2\2\u038d\u038e\3\2\2\2\u038e\u038c\3"+ - "\2\2\2\u038e\u038f\3\2\2\2\u038f\u0127\3\2\2\2\u0390\u0392\t\37\2\2\u0391"+ - "\u0390\3\2\2\2\u0392\u0393\3\2\2\2\u0393\u0391\3\2\2\2\u0393\u0394\3\2"+ - "\2\2\u0394\u0396\3\2\2\2\u0395\u0397\5\16\7\2\u0396\u0395\3\2\2\2\u0396"+ - "\u0397\3\2\2\2\u0397\u0129\3\2\2\2\u0398\u039a\t\36\2\2\u0399\u0398\3"+ - "\2\2\2\u039a\u039b\3\2\2\2\u039b\u0399\3\2\2\2\u039b\u039c\3\2\2\2\u039c"+ - "\u039d\3\2\2\2\u039d\u039e\5\26\13\2\u039e\u012b\3\2\2\2\u039f\u03a1\t"+ - " \2\2\u03a0\u039f\3\2\2\2\u03a1\u03a2\3\2\2\2\u03a2\u03a0\3\2\2\2\u03a2"+ - "\u03a3\3\2\2\2\u03a3\u03a4\3\2\2\2\u03a4\u03a5\t!\2\2\u03a5\u012d\3\2"+ - "\2\2\u03a6\u03a8\t\"\2\2\u03a7\u03a6\3\2\2\2\u03a8\u03a9\3\2\2\2\u03a9"+ - "\u03a7\3\2\2\2\u03a9\u03aa\3\2\2\2\u03aa\u03ab\3\2\2\2\u03ab\u03ac\5\n"+ - "\5\2\u03ac\u012f\3\2\2\2\u03ad\u03b1\7)\2\2\u03ae\u03b0\n#\2\2\u03af\u03ae"+ - "\3\2\2\2\u03b0\u03b3\3\2\2\2\u03b1\u03af\3\2\2\2\u03b1\u03b2\3\2\2\2\u03b2"+ - "\u03b4\3\2\2\2\u03b3\u03b1\3\2\2\2\u03b4\u03b5\7)\2\2\u03b5\u0131\3\2"+ - "\2\2\u03b6\u03ba\7$\2\2\u03b7\u03b9\n$\2\2\u03b8\u03b7\3\2\2\2\u03b9\u03bc"+ - "\3\2\2\2\u03ba\u03b8\3\2\2\2\u03ba\u03bb\3\2\2\2\u03bb\u03bd\3\2\2\2\u03bc"+ - "\u03ba\3\2\2\2\u03bd\u03be\7$\2\2\u03be\u0133\3\2\2\2\u03bf\u03c3\t%\2"+ - "\2\u03c0\u03c2\t&\2\2\u03c1\u03c0\3\2\2\2\u03c2\u03c5\3\2\2\2\u03c3\u03c1"+ - "\3\2\2\2\u03c3\u03c4\3\2\2\2\u03c4\u0135\3\2\2\2\u03c5\u03c3\3\2\2\2\u03c6"+ - "\u03c7\5\u0134\u009a\2\u03c7\u03c8\7<\2\2\u03c8\u0137\3\2\2\2\u03c9\u03cb"+ - "\n\'\2\2\u03ca\u03c9\3\2\2\2\u03cb\u03cc\3\2\2\2\u03cc\u03ca\3\2\2\2\u03cc"+ - "\u03cd\3\2\2\2\u03cd\u0139\3\2\2\2\u03ce\u03cf\7*\2\2\u03cf\u013b\3\2"+ - "\2\2\u03d0\u03d1\7+\2\2\u03d1\u013d\3\2\2\2\u03d2\u03d3\7.\2\2\u03d3\u013f"+ - "\3\2\2\2\u03d4\u03d5\7-\2\2\u03d5\u0141\3\2\2\2\u03d6\u03d7\7/\2\2\u03d7"+ - "\u0143\3\2\2\2\u03d8\u03d9\7,\2\2\u03d9\u0145\3\2\2\2\u03da\u03db\7\61"+ - "\2\2\u03db\u0147\3\2\2\2\u03dc\u03dd\7?\2\2\u03dd\u0149\3\2\2\2\u03de"+ - "\u03df\7@\2\2\u03df\u014b\3\2\2\2\u03e0\u03e1\7@\2\2\u03e1\u03e2\7?\2"+ - "\2\u03e2\u014d\3\2\2\2\u03e3\u03e4\7>\2\2\u03e4\u014f\3\2\2\2\u03e5\u03e6"+ - "\7>\2\2\u03e6\u03e7\7?\2\2\u03e7\u0151\3\2\2\2\u03e8\u03e9\7\'\2\2\u03e9"+ - "\u0153\3\2\2\2\u03ea\u03eb\7@\2\2\u03eb\u03ec\7@\2\2\u03ec\u0155\3\2\2"+ - "\2\u03ed\u03ee\7>\2\2\u03ee\u03ef\7>\2\2\u03ef\u0157\3\2\2\2\u03f0\u03f1"+ - "\7\u0080\2\2\u03f1\u0159\3\2\2\2\u03f2\u03f3\7(\2\2\u03f3\u015b\3\2\2"+ - "\2\u03f4\u03f5\7~\2\2\u03f5\u015d\3\2\2\2\u03f6\u03f7\7`\2\2\u03f7\u015f"+ - "\3\2\2\2\u03f8\u03fa\t\35\2\2\u03f9\u03f8\3\2\2\2\u03fa\u03fb\3\2\2\2"+ - "\u03fb\u03f9\3\2\2\2\u03fb\u03fc\3\2\2\2\u03fc\u03fd\3\2\2\2\u03fd\u03fe"+ - "\b\u00b0\2\2\u03fe\u0161\3\2\2\2\u03ff\u0401\7\17\2\2\u0400\u03ff\3\2"+ - "\2\2\u0400\u0401\3\2\2\2\u0401\u0402\3\2\2\2\u0402\u0403\7\f\2\2\u0403"+ - "\u0163\3\2\2\2\24\2\3\u0169\u016e\u0179\u02f8\u038e\u0393\u0396\u039b"+ - "\u03a2\u03a9\u03b1\u03ba\u03c3\u03cc\u03fb\u0400\5\b\2\2\7\3\2\6\2\2"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.tokens deleted file mode 100644 index a4d6ab04f..000000000 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80Lexer.tokens +++ /dev/null @@ -1,171 +0,0 @@ -COMMENT=1 -COMMENT2=2 -OPCODE_ADC=3 -OPCODE_ADD=4 -OPCODE_AND=5 -OPCODE_BIT=6 -OPCODE_CALL=7 -OPCODE_CCF=8 -OPCODE_CP=9 -OPCODE_CPD=10 -OPCODE_CPDR=11 -OPCODE_CPI=12 -OPCODE_CPIR=13 -OPCODE_CPL=14 -OPCODE_DAA=15 -OPCODE_DEC=16 -OPCODE_DI=17 -OPCODE_DJNZ=18 -OPCODE_EI=19 -OPCODE_EX=20 -OPCODE_EXX=21 -OPCODE_HALT=22 -OPCODE_IM=23 -OPCODE_IN=24 -OPCODE_INC=25 -OPCODE_IND=26 -OPCODE_INDR=27 -OPCODE_INI=28 -OPCODE_INIR=29 -OPCODE_JP=30 -OPCODE_JR=31 -OPCODE_LD=32 -OPCODE_LDD=33 -OPCODE_LDDR=34 -OPCODE_LDI=35 -OPCODE_LDIR=36 -OPCODE_NEG=37 -OPCODE_NOP=38 -OPCODE_OR=39 -OPCODE_OTDR=40 -OPCODE_OTIR=41 -OPCODE_OUT=42 -OPCODE_OUTD=43 -OPCODE_OUTI=44 -OPCODE_POP=45 -OPCODE_PUSH=46 -OPCODE_RES=47 -OPCODE_RET=48 -OPCODE_RETI=49 -OPCODE_RETN=50 -OPCODE_RL=51 -OPCODE_RLA=52 -OPCODE_RLC=53 -OPCODE_RLCA=54 -OPCODE_RLD=55 -OPCODE_RR=56 -OPCODE_RRA=57 -OPCODE_RRC=58 -OPCODE_RRCA=59 -OPCODE_RRD=60 -OPCODE_RST=61 -OPCODE_SBC=62 -OPCODE_SCF=63 -OPCODE_SET=64 -OPCODE_SLA=65 -OPCODE_SRA=66 -OPCODE_SLL=67 -OPCODE_SRL=68 -OPCODE_SUB=69 -OPCODE_XOR=70 -COND_C=71 -COND_NC=72 -COND_Z=73 -COND_NZ=74 -COND_M=75 -COND_P=76 -COND_PE=77 -COND_PO=78 -COND_WS=79 -COND_UNRECOGNIZED=80 -PREP_ORG=81 -PREP_EQU=82 -PREP_SET=83 -PREP_IF=84 -PREP_ENDIF=85 -PREP_INCLUDE=86 -PREP_MACRO=87 -PREP_ENDM=88 -PREP_DB=89 -PREP_DW=90 -PREP_DS=91 -PREP_ADDR=92 -REG_A=93 -REG_B=94 -REG_C=95 -REG_D=96 -REG_E=97 -REG_H=98 -REG_L=99 -REG_IX=100 -REG_IXH=101 -REG_IXL=102 -REG_IY=103 -REG_IYH=104 -REG_IYL=105 -REG_BC=106 -REG_DE=107 -REG_HL=108 -REG_SP=109 -REG_AF=110 -REG_AFF=111 -REG_I=112 -REG_R=113 -OP_MOD=114 -OP_SHR=115 -OP_SHL=116 -OP_NOT=117 -OP_AND=118 -OP_OR=119 -OP_XOR=120 -LIT_HEXNUMBER_1=121 -LIT_NUMBER=122 -LIT_HEXNUMBER_2=123 -LIT_OCTNUMBER=124 -LIT_BINNUMBER=125 -LIT_STRING_1=126 -LIT_STRING_2=127 -ID_IDENTIFIER=128 -ID_LABEL=129 -ERROR=130 -SEP_LPAR=131 -SEP_RPAR=132 -SEP_COMMA=133 -OP_ADD=134 -OP_SUBTRACT=135 -OP_MULTIPLY=136 -OP_DIVIDE=137 -OP_EQUAL=138 -OP_GT=139 -OP_GTE=140 -OP_LT=141 -OP_LTE=142 -OP_MOD_2=143 -OP_SHR_2=144 -OP_SHL_2=145 -OP_NOT_2=146 -OP_AND_2=147 -OP_OR_2=148 -OP_XOR_2=149 -WS=150 -EOL=151 -'$'=92 -'('=131 -')'=132 -','=133 -'+'=134 -'-'=135 -'*'=136 -'/'=137 -'='=138 -'>'=139 -'>='=140 -'<'=141 -'<='=142 -'%'=143 -'>>'=144 -'<<'=145 -'~'=146 -'&'=147 -'|'=148 -'^'=149 diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.interp b/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.interp deleted file mode 100644 index 057aa659f..000000000 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.interp +++ /dev/null @@ -1,329 +0,0 @@ -token literal names: -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -'$' -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -'(' -')' -',' -'+' -'-' -'*' -'/' -'=' -'>' -'>=' -'<' -'<=' -'%' -'>>' -'<<' -'!' -'&' -'|' -'~' -null -null - -token symbolic names: -null -COMMENT -COMMENT2 -OPCODE_ADC -OPCODE_ADD -OPCODE_AND -OPCODE_BIT -OPCODE_CALL -OPCODE_CCF -OPCODE_CP -OPCODE_CPD -OPCODE_CPDR -OPCODE_CPI -OPCODE_CPIR -OPCODE_CPL -OPCODE_DAA -OPCODE_DEC -OPCODE_DI -OPCODE_DJNZ -OPCODE_EI -OPCODE_EX -OPCODE_EXX -OPCODE_HALT -OPCODE_IM -OPCODE_IN -OPCODE_INC -OPCODE_IND -OPCODE_INDR -OPCODE_INI -OPCODE_INIR -OPCODE_JP -OPCODE_JR -OPCODE_LD -OPCODE_LDD -OPCODE_LDDR -OPCODE_LDI -OPCODE_LDIR -OPCODE_NEG -OPCODE_NOP -OPCODE_OR -OPCODE_OTDR -OPCODE_OTIR -OPCODE_OUT -OPCODE_OUTD -OPCODE_OUTI -OPCODE_POP -OPCODE_PUSH -OPCODE_RES -OPCODE_RET -OPCODE_RETI -OPCODE_RETN -OPCODE_RL -OPCODE_RLA -OPCODE_RLC -OPCODE_RLCA -OPCODE_RLD -OPCODE_RR -OPCODE_RRA -OPCODE_RRC -OPCODE_RRCA -OPCODE_RRD -OPCODE_RST -OPCODE_SBC -OPCODE_SCF -OPCODE_SET -OPCODE_SLA -OPCODE_SRA -OPCODE_SLL -OPCODE_SRL -OPCODE_SUB -OPCODE_XOR -COND_C -COND_NC -COND_Z -COND_NZ -COND_M -COND_P -COND_PE -COND_PO -COND_WS -COND_UNRECOGNIZED -PREP_ORG -PREP_EQU -PREP_SET -PREP_VAR -PREP_IF -PREP_ENDIF -PREP_INCLUDE -PREP_MACRO -PREP_ENDM -PREP_DB -PREP_DW -PREP_DS -PREP_ADDR -REG_A -REG_B -REG_C -REG_D -REG_E -REG_H -REG_L -REG_IX -REG_IXH -REG_IXL -REG_IY -REG_IYH -REG_IYL -REG_BC -REG_DE -REG_HL -REG_SP -REG_AF -REG_AFF -REG_I -REG_R -OP_MOD -OP_SHR -OP_SHL -OP_NOT -OP_AND -OP_OR -OP_XOR -LIT_HEXNUMBER_1 -LIT_NUMBER -LIT_HEXNUMBER_2 -LIT_OCTNUMBER -LIT_BINNUMBER -LIT_STRING_1 -LIT_STRING_2 -ID_IDENTIFIER -ID_LABEL -ERROR -SEP_LPAR -SEP_RPAR -SEP_COMMA -OP_ADD -OP_SUBTRACT -OP_MULTIPLY -OP_DIVIDE -OP_EQUAL -OP_GT -OP_GTE -OP_LT -OP_LTE -OP_MOD_2 -OP_SHR_2 -OP_SHL_2 -OP_NOT_2 -OP_AND_2 -OP_OR_2 -OP_XOR_2 -WS -EOL - -rule names: -rStart -rLine -rStatement -rInstruction -r8bitInstruction -rRegister -cCondition -rPseudoCode -rMacroParameters -rMacroArguments -rData -rDBdata -rDWdata -rExpression - - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 154, 445, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 3, 2, 7, 2, 32, 10, 2, 12, 2, 14, 2, 35, 11, 2, 3, 2, 5, 2, 38, 10, 2, 3, 2, 6, 2, 41, 10, 2, 13, 2, 14, 2, 42, 3, 2, 7, 2, 46, 10, 2, 12, 2, 14, 2, 49, 11, 2, 3, 2, 7, 2, 52, 10, 2, 12, 2, 14, 2, 55, 11, 2, 3, 2, 3, 2, 3, 3, 5, 3, 60, 10, 3, 3, 3, 7, 3, 63, 10, 3, 12, 3, 14, 3, 66, 11, 3, 3, 3, 3, 3, 5, 3, 70, 10, 3, 3, 4, 3, 4, 3, 4, 5, 4, 75, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 90, 10, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 125, 10, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 171, 10, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 264, 10, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 283, 10, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 295, 10, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 7, 9, 313, 10, 9, 12, 9, 14, 9, 316, 11, 9, 3, 9, 7, 9, 319, 10, 9, 12, 9, 14, 9, 322, 11, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 329, 10, 9, 3, 9, 3, 9, 3, 9, 3, 9, 7, 9, 335, 10, 9, 12, 9, 14, 9, 338, 11, 9, 3, 9, 7, 9, 341, 10, 9, 12, 9, 14, 9, 344, 11, 9, 3, 9, 3, 9, 3, 9, 5, 9, 349, 10, 9, 3, 9, 3, 9, 5, 9, 353, 10, 9, 3, 10, 3, 10, 3, 10, 7, 10, 358, 10, 10, 12, 10, 14, 10, 361, 11, 10, 3, 11, 3, 11, 3, 11, 7, 11, 366, 10, 11, 12, 11, 14, 11, 369, 11, 11, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 375, 10, 12, 12, 12, 14, 12, 378, 11, 12, 3, 12, 3, 12, 3, 12, 3, 12, 7, 12, 384, 10, 12, 12, 12, 14, 12, 387, 11, 12, 3, 12, 3, 12, 5, 12, 391, 10, 12, 3, 13, 3, 13, 5, 13, 395, 10, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 5, 15, 414, 10, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 7, 15, 440, 10, 15, 12, 15, 14, 15, 443, 11, 15, 3, 15, 2, 3, 28, 16, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 2, 16, 3, 2, 109, 112, 3, 2, 73, 76, 3, 2, 109, 110, 4, 2, 109, 111, 113, 113, 3, 2, 73, 80, 3, 2, 129, 130, 5, 2, 120, 120, 137, 138, 149, 149, 5, 2, 117, 117, 139, 140, 146, 146, 3, 2, 137, 138, 4, 2, 118, 119, 147, 148, 3, 2, 142, 145, 4, 2, 121, 121, 150, 150, 4, 2, 123, 123, 152, 152, 4, 2, 122, 122, 151, 151, 2, 546, 2, 33, 3, 2, 2, 2, 4, 69, 3, 2, 2, 2, 6, 74, 3, 2, 2, 2, 8, 170, 3, 2, 2, 2, 10, 282, 3, 2, 2, 2, 12, 294, 3, 2, 2, 2, 14, 296, 3, 2, 2, 2, 16, 352, 3, 2, 2, 2, 18, 354, 3, 2, 2, 2, 20, 362, 3, 2, 2, 2, 22, 390, 3, 2, 2, 2, 24, 394, 3, 2, 2, 2, 26, 396, 3, 2, 2, 2, 28, 413, 3, 2, 2, 2, 30, 32, 7, 154, 2, 2, 31, 30, 3, 2, 2, 2, 32, 35, 3, 2, 2, 2, 33, 31, 3, 2, 2, 2, 33, 34, 3, 2, 2, 2, 34, 37, 3, 2, 2, 2, 35, 33, 3, 2, 2, 2, 36, 38, 5, 4, 3, 2, 37, 36, 3, 2, 2, 2, 37, 38, 3, 2, 2, 2, 38, 47, 3, 2, 2, 2, 39, 41, 7, 154, 2, 2, 40, 39, 3, 2, 2, 2, 41, 42, 3, 2, 2, 2, 42, 40, 3, 2, 2, 2, 42, 43, 3, 2, 2, 2, 43, 44, 3, 2, 2, 2, 44, 46, 5, 4, 3, 2, 45, 40, 3, 2, 2, 2, 46, 49, 3, 2, 2, 2, 47, 45, 3, 2, 2, 2, 47, 48, 3, 2, 2, 2, 48, 53, 3, 2, 2, 2, 49, 47, 3, 2, 2, 2, 50, 52, 7, 154, 2, 2, 51, 50, 3, 2, 2, 2, 52, 55, 3, 2, 2, 2, 53, 51, 3, 2, 2, 2, 53, 54, 3, 2, 2, 2, 54, 56, 3, 2, 2, 2, 55, 53, 3, 2, 2, 2, 56, 57, 7, 2, 2, 3, 57, 3, 3, 2, 2, 2, 58, 60, 7, 132, 2, 2, 59, 58, 3, 2, 2, 2, 59, 60, 3, 2, 2, 2, 60, 64, 3, 2, 2, 2, 61, 63, 7, 154, 2, 2, 62, 61, 3, 2, 2, 2, 63, 66, 3, 2, 2, 2, 64, 62, 3, 2, 2, 2, 64, 65, 3, 2, 2, 2, 65, 67, 3, 2, 2, 2, 66, 64, 3, 2, 2, 2, 67, 70, 5, 6, 4, 2, 68, 70, 7, 132, 2, 2, 69, 59, 3, 2, 2, 2, 69, 68, 3, 2, 2, 2, 70, 5, 3, 2, 2, 2, 71, 75, 5, 8, 5, 2, 72, 75, 5, 16, 9, 2, 73, 75, 5, 22, 12, 2, 74, 71, 3, 2, 2, 2, 74, 72, 3, 2, 2, 2, 74, 73, 3, 2, 2, 2, 75, 7, 3, 2, 2, 2, 76, 171, 5, 10, 6, 2, 77, 78, 7, 34, 2, 2, 78, 79, 9, 2, 2, 2, 79, 80, 7, 136, 2, 2, 80, 171, 5, 28, 15, 2, 81, 82, 7, 34, 2, 2, 82, 83, 5, 12, 7, 2, 83, 84, 7, 136, 2, 2, 84, 85, 5, 28, 15, 2, 85, 171, 3, 2, 2, 2, 86, 89, 7, 33, 2, 2, 87, 88, 9, 3, 2, 2, 88, 90, 7, 136, 2, 2, 89, 87, 3, 2, 2, 2, 89, 90, 3, 2, 2, 2, 90, 91, 3, 2, 2, 2, 91, 171, 5, 28, 15, 2, 92, 93, 7, 34, 2, 2, 93, 94, 7, 134, 2, 2, 94, 95, 5, 28, 15, 2, 95, 96, 7, 135, 2, 2, 96, 97, 7, 136, 2, 2, 97, 98, 7, 111, 2, 2, 98, 171, 3, 2, 2, 2, 99, 100, 7, 34, 2, 2, 100, 101, 7, 111, 2, 2, 101, 102, 7, 136, 2, 2, 102, 103, 7, 134, 2, 2, 103, 104, 5, 28, 15, 2, 104, 105, 7, 135, 2, 2, 105, 171, 3, 2, 2, 2, 106, 107, 7, 34, 2, 2, 107, 108, 7, 134, 2, 2, 108, 109, 5, 28, 15, 2, 109, 110, 7, 135, 2, 2, 110, 111, 7, 136, 2, 2, 111, 112, 7, 96, 2, 2, 112, 171, 3, 2, 2, 2, 113, 114, 7, 34, 2, 2, 114, 115, 7, 96, 2, 2, 115, 116, 7, 136, 2, 2, 116, 117, 7, 134, 2, 2, 117, 118, 5, 28, 15, 2, 118, 119, 7, 135, 2, 2, 119, 171, 3, 2, 2, 2, 120, 124, 7, 32, 2, 2, 121, 122, 5, 14, 8, 2, 122, 123, 7, 136, 2, 2, 123, 125, 3, 2, 2, 2, 124, 121, 3, 2, 2, 2, 124, 125, 3, 2, 2, 2, 125, 126, 3, 2, 2, 2, 126, 171, 5, 28, 15, 2, 127, 128, 7, 9, 2, 2, 128, 171, 5, 28, 15, 2, 129, 130, 7, 9, 2, 2, 130, 131, 5, 14, 8, 2, 131, 132, 7, 136, 2, 2, 132, 133, 5, 28, 15, 2, 133, 171, 3, 2, 2, 2, 134, 135, 7, 6, 2, 2, 135, 136, 7, 96, 2, 2, 136, 137, 7, 136, 2, 2, 137, 171, 5, 28, 15, 2, 138, 139, 7, 5, 2, 2, 139, 140, 7, 96, 2, 2, 140, 141, 7, 136, 2, 2, 141, 171, 5, 28, 15, 2, 142, 143, 7, 44, 2, 2, 143, 144, 7, 134, 2, 2, 144, 145, 5, 28, 15, 2, 145, 146, 7, 135, 2, 2, 146, 147, 7, 136, 2, 2, 147, 148, 7, 96, 2, 2, 148, 171, 3, 2, 2, 2, 149, 150, 7, 71, 2, 2, 150, 171, 5, 28, 15, 2, 151, 152, 7, 26, 2, 2, 152, 153, 7, 96, 2, 2, 153, 154, 7, 136, 2, 2, 154, 155, 7, 134, 2, 2, 155, 156, 5, 28, 15, 2, 156, 157, 7, 135, 2, 2, 157, 171, 3, 2, 2, 2, 158, 159, 7, 64, 2, 2, 159, 160, 7, 96, 2, 2, 160, 161, 7, 136, 2, 2, 161, 171, 5, 28, 15, 2, 162, 163, 7, 7, 2, 2, 163, 171, 5, 28, 15, 2, 164, 165, 7, 72, 2, 2, 165, 171, 5, 28, 15, 2, 166, 167, 7, 41, 2, 2, 167, 171, 5, 28, 15, 2, 168, 169, 7, 11, 2, 2, 169, 171, 5, 28, 15, 2, 170, 76, 3, 2, 2, 2, 170, 77, 3, 2, 2, 2, 170, 81, 3, 2, 2, 2, 170, 86, 3, 2, 2, 2, 170, 92, 3, 2, 2, 2, 170, 99, 3, 2, 2, 2, 170, 106, 3, 2, 2, 2, 170, 113, 3, 2, 2, 2, 170, 120, 3, 2, 2, 2, 170, 127, 3, 2, 2, 2, 170, 129, 3, 2, 2, 2, 170, 134, 3, 2, 2, 2, 170, 138, 3, 2, 2, 2, 170, 142, 3, 2, 2, 2, 170, 149, 3, 2, 2, 2, 170, 151, 3, 2, 2, 2, 170, 158, 3, 2, 2, 2, 170, 162, 3, 2, 2, 2, 170, 164, 3, 2, 2, 2, 170, 166, 3, 2, 2, 2, 170, 168, 3, 2, 2, 2, 171, 9, 3, 2, 2, 2, 172, 283, 7, 40, 2, 2, 173, 174, 7, 34, 2, 2, 174, 175, 7, 134, 2, 2, 175, 176, 9, 4, 2, 2, 176, 177, 7, 135, 2, 2, 177, 178, 7, 136, 2, 2, 178, 283, 7, 96, 2, 2, 179, 180, 7, 34, 2, 2, 180, 181, 7, 134, 2, 2, 181, 182, 7, 111, 2, 2, 182, 183, 7, 135, 2, 2, 183, 184, 7, 136, 2, 2, 184, 283, 5, 12, 7, 2, 185, 186, 7, 27, 2, 2, 186, 283, 9, 2, 2, 2, 187, 188, 7, 27, 2, 2, 188, 283, 5, 12, 7, 2, 189, 190, 7, 18, 2, 2, 190, 283, 5, 12, 7, 2, 191, 283, 7, 56, 2, 2, 192, 193, 7, 22, 2, 2, 193, 194, 7, 113, 2, 2, 194, 195, 7, 136, 2, 2, 195, 283, 7, 114, 2, 2, 196, 197, 7, 22, 2, 2, 197, 198, 7, 110, 2, 2, 198, 199, 7, 136, 2, 2, 199, 283, 7, 111, 2, 2, 200, 201, 7, 22, 2, 2, 201, 202, 7, 134, 2, 2, 202, 203, 7, 112, 2, 2, 203, 204, 7, 135, 2, 2, 204, 205, 7, 136, 2, 2, 205, 283, 7, 111, 2, 2, 206, 207, 7, 6, 2, 2, 207, 208, 7, 111, 2, 2, 208, 209, 7, 136, 2, 2, 209, 283, 9, 2, 2, 2, 210, 211, 7, 34, 2, 2, 211, 212, 7, 96, 2, 2, 212, 213, 7, 136, 2, 2, 213, 214, 7, 134, 2, 2, 214, 215, 9, 4, 2, 2, 215, 283, 7, 135, 2, 2, 216, 217, 7, 18, 2, 2, 217, 283, 9, 2, 2, 2, 218, 283, 7, 61, 2, 2, 219, 283, 7, 54, 2, 2, 220, 283, 7, 59, 2, 2, 221, 283, 7, 17, 2, 2, 222, 283, 7, 16, 2, 2, 223, 224, 7, 27, 2, 2, 224, 225, 7, 134, 2, 2, 225, 226, 7, 111, 2, 2, 226, 283, 7, 135, 2, 2, 227, 228, 7, 18, 2, 2, 228, 229, 7, 134, 2, 2, 229, 230, 7, 111, 2, 2, 230, 283, 7, 135, 2, 2, 231, 283, 7, 65, 2, 2, 232, 283, 7, 10, 2, 2, 233, 234, 7, 34, 2, 2, 234, 235, 5, 12, 7, 2, 235, 236, 7, 136, 2, 2, 236, 237, 5, 12, 7, 2, 237, 283, 3, 2, 2, 2, 238, 283, 7, 24, 2, 2, 239, 240, 7, 6, 2, 2, 240, 241, 7, 96, 2, 2, 241, 242, 7, 136, 2, 2, 242, 283, 5, 12, 7, 2, 243, 244, 7, 5, 2, 2, 244, 245, 7, 96, 2, 2, 245, 246, 7, 136, 2, 2, 246, 283, 5, 12, 7, 2, 247, 248, 7, 71, 2, 2, 248, 283, 5, 12, 7, 2, 249, 250, 7, 64, 2, 2, 250, 251, 7, 96, 2, 2, 251, 252, 7, 136, 2, 2, 252, 283, 5, 12, 7, 2, 253, 254, 7, 7, 2, 2, 254, 283, 5, 12, 7, 2, 255, 256, 7, 72, 2, 2, 256, 283, 5, 12, 7, 2, 257, 258, 7, 41, 2, 2, 258, 283, 5, 12, 7, 2, 259, 260, 7, 11, 2, 2, 260, 283, 5, 12, 7, 2, 261, 263, 7, 50, 2, 2, 262, 264, 5, 14, 8, 2, 263, 262, 3, 2, 2, 2, 263, 264, 3, 2, 2, 2, 264, 283, 3, 2, 2, 2, 265, 266, 7, 47, 2, 2, 266, 283, 9, 5, 2, 2, 267, 268, 7, 48, 2, 2, 268, 283, 9, 5, 2, 2, 269, 270, 7, 63, 2, 2, 270, 283, 5, 28, 15, 2, 271, 283, 7, 23, 2, 2, 272, 273, 7, 32, 2, 2, 273, 274, 7, 134, 2, 2, 274, 275, 7, 111, 2, 2, 275, 283, 7, 135, 2, 2, 276, 283, 7, 19, 2, 2, 277, 278, 7, 34, 2, 2, 278, 279, 7, 112, 2, 2, 279, 280, 7, 136, 2, 2, 280, 283, 7, 111, 2, 2, 281, 283, 7, 21, 2, 2, 282, 172, 3, 2, 2, 2, 282, 173, 3, 2, 2, 2, 282, 179, 3, 2, 2, 2, 282, 185, 3, 2, 2, 2, 282, 187, 3, 2, 2, 2, 282, 189, 3, 2, 2, 2, 282, 191, 3, 2, 2, 2, 282, 192, 3, 2, 2, 2, 282, 196, 3, 2, 2, 2, 282, 200, 3, 2, 2, 2, 282, 206, 3, 2, 2, 2, 282, 210, 3, 2, 2, 2, 282, 216, 3, 2, 2, 2, 282, 218, 3, 2, 2, 2, 282, 219, 3, 2, 2, 2, 282, 220, 3, 2, 2, 2, 282, 221, 3, 2, 2, 2, 282, 222, 3, 2, 2, 2, 282, 223, 3, 2, 2, 2, 282, 227, 3, 2, 2, 2, 282, 231, 3, 2, 2, 2, 282, 232, 3, 2, 2, 2, 282, 233, 3, 2, 2, 2, 282, 238, 3, 2, 2, 2, 282, 239, 3, 2, 2, 2, 282, 243, 3, 2, 2, 2, 282, 247, 3, 2, 2, 2, 282, 249, 3, 2, 2, 2, 282, 253, 3, 2, 2, 2, 282, 255, 3, 2, 2, 2, 282, 257, 3, 2, 2, 2, 282, 259, 3, 2, 2, 2, 282, 261, 3, 2, 2, 2, 282, 265, 3, 2, 2, 2, 282, 267, 3, 2, 2, 2, 282, 269, 3, 2, 2, 2, 282, 271, 3, 2, 2, 2, 282, 272, 3, 2, 2, 2, 282, 276, 3, 2, 2, 2, 282, 277, 3, 2, 2, 2, 282, 281, 3, 2, 2, 2, 283, 11, 3, 2, 2, 2, 284, 295, 7, 96, 2, 2, 285, 295, 7, 97, 2, 2, 286, 295, 7, 98, 2, 2, 287, 295, 7, 99, 2, 2, 288, 295, 7, 100, 2, 2, 289, 295, 7, 101, 2, 2, 290, 295, 7, 102, 2, 2, 291, 292, 7, 134, 2, 2, 292, 293, 7, 111, 2, 2, 293, 295, 7, 135, 2, 2, 294, 284, 3, 2, 2, 2, 294, 285, 3, 2, 2, 2, 294, 286, 3, 2, 2, 2, 294, 287, 3, 2, 2, 2, 294, 288, 3, 2, 2, 2, 294, 289, 3, 2, 2, 2, 294, 290, 3, 2, 2, 2, 294, 291, 3, 2, 2, 2, 295, 13, 3, 2, 2, 2, 296, 297, 9, 6, 2, 2, 297, 15, 3, 2, 2, 2, 298, 299, 7, 83, 2, 2, 299, 353, 5, 28, 15, 2, 300, 301, 7, 131, 2, 2, 301, 302, 7, 84, 2, 2, 302, 353, 5, 28, 15, 2, 303, 304, 7, 131, 2, 2, 304, 305, 7, 85, 2, 2, 305, 353, 5, 28, 15, 2, 306, 307, 7, 87, 2, 2, 307, 308, 5, 28, 15, 2, 308, 314, 7, 154, 2, 2, 309, 310, 5, 4, 3, 2, 310, 311, 7, 154, 2, 2, 311, 313, 3, 2, 2, 2, 312, 309, 3, 2, 2, 2, 313, 316, 3, 2, 2, 2, 314, 312, 3, 2, 2, 2, 314, 315, 3, 2, 2, 2, 315, 320, 3, 2, 2, 2, 316, 314, 3, 2, 2, 2, 317, 319, 7, 154, 2, 2, 318, 317, 3, 2, 2, 2, 319, 322, 3, 2, 2, 2, 320, 318, 3, 2, 2, 2, 320, 321, 3, 2, 2, 2, 321, 323, 3, 2, 2, 2, 322, 320, 3, 2, 2, 2, 323, 324, 7, 88, 2, 2, 324, 353, 3, 2, 2, 2, 325, 326, 7, 131, 2, 2, 326, 328, 7, 90, 2, 2, 327, 329, 5, 18, 10, 2, 328, 327, 3, 2, 2, 2, 328, 329, 3, 2, 2, 2, 329, 330, 3, 2, 2, 2, 330, 336, 7, 154, 2, 2, 331, 332, 5, 4, 3, 2, 332, 333, 7, 154, 2, 2, 333, 335, 3, 2, 2, 2, 334, 331, 3, 2, 2, 2, 335, 338, 3, 2, 2, 2, 336, 334, 3, 2, 2, 2, 336, 337, 3, 2, 2, 2, 337, 342, 3, 2, 2, 2, 338, 336, 3, 2, 2, 2, 339, 341, 7, 154, 2, 2, 340, 339, 3, 2, 2, 2, 341, 344, 3, 2, 2, 2, 342, 340, 3, 2, 2, 2, 342, 343, 3, 2, 2, 2, 343, 345, 3, 2, 2, 2, 344, 342, 3, 2, 2, 2, 345, 353, 7, 91, 2, 2, 346, 348, 7, 131, 2, 2, 347, 349, 5, 20, 11, 2, 348, 347, 3, 2, 2, 2, 348, 349, 3, 2, 2, 2, 349, 353, 3, 2, 2, 2, 350, 351, 7, 89, 2, 2, 351, 353, 9, 7, 2, 2, 352, 298, 3, 2, 2, 2, 352, 300, 3, 2, 2, 2, 352, 303, 3, 2, 2, 2, 352, 306, 3, 2, 2, 2, 352, 325, 3, 2, 2, 2, 352, 346, 3, 2, 2, 2, 352, 350, 3, 2, 2, 2, 353, 17, 3, 2, 2, 2, 354, 359, 7, 131, 2, 2, 355, 356, 7, 136, 2, 2, 356, 358, 7, 131, 2, 2, 357, 355, 3, 2, 2, 2, 358, 361, 3, 2, 2, 2, 359, 357, 3, 2, 2, 2, 359, 360, 3, 2, 2, 2, 360, 19, 3, 2, 2, 2, 361, 359, 3, 2, 2, 2, 362, 367, 5, 28, 15, 2, 363, 364, 7, 136, 2, 2, 364, 366, 5, 28, 15, 2, 365, 363, 3, 2, 2, 2, 366, 369, 3, 2, 2, 2, 367, 365, 3, 2, 2, 2, 367, 368, 3, 2, 2, 2, 368, 21, 3, 2, 2, 2, 369, 367, 3, 2, 2, 2, 370, 371, 7, 92, 2, 2, 371, 376, 5, 24, 13, 2, 372, 373, 7, 136, 2, 2, 373, 375, 5, 24, 13, 2, 374, 372, 3, 2, 2, 2, 375, 378, 3, 2, 2, 2, 376, 374, 3, 2, 2, 2, 376, 377, 3, 2, 2, 2, 377, 391, 3, 2, 2, 2, 378, 376, 3, 2, 2, 2, 379, 380, 7, 93, 2, 2, 380, 385, 5, 26, 14, 2, 381, 382, 7, 136, 2, 2, 382, 384, 5, 26, 14, 2, 383, 381, 3, 2, 2, 2, 384, 387, 3, 2, 2, 2, 385, 383, 3, 2, 2, 2, 385, 386, 3, 2, 2, 2, 386, 391, 3, 2, 2, 2, 387, 385, 3, 2, 2, 2, 388, 389, 7, 94, 2, 2, 389, 391, 5, 28, 15, 2, 390, 370, 3, 2, 2, 2, 390, 379, 3, 2, 2, 2, 390, 388, 3, 2, 2, 2, 391, 23, 3, 2, 2, 2, 392, 395, 5, 28, 15, 2, 393, 395, 5, 10, 6, 2, 394, 392, 3, 2, 2, 2, 394, 393, 3, 2, 2, 2, 395, 25, 3, 2, 2, 2, 396, 397, 5, 28, 15, 2, 397, 27, 3, 2, 2, 2, 398, 399, 8, 15, 1, 2, 399, 400, 9, 8, 2, 2, 400, 414, 5, 28, 15, 20, 401, 402, 7, 134, 2, 2, 402, 403, 5, 28, 15, 2, 403, 404, 7, 135, 2, 2, 404, 414, 3, 2, 2, 2, 405, 414, 7, 125, 2, 2, 406, 414, 7, 124, 2, 2, 407, 414, 7, 126, 2, 2, 408, 414, 7, 127, 2, 2, 409, 414, 7, 128, 2, 2, 410, 414, 7, 95, 2, 2, 411, 414, 7, 131, 2, 2, 412, 414, 9, 7, 2, 2, 413, 398, 3, 2, 2, 2, 413, 401, 3, 2, 2, 2, 413, 405, 3, 2, 2, 2, 413, 406, 3, 2, 2, 2, 413, 407, 3, 2, 2, 2, 413, 408, 3, 2, 2, 2, 413, 409, 3, 2, 2, 2, 413, 410, 3, 2, 2, 2, 413, 411, 3, 2, 2, 2, 413, 412, 3, 2, 2, 2, 414, 441, 3, 2, 2, 2, 415, 416, 12, 19, 2, 2, 416, 417, 9, 9, 2, 2, 417, 440, 5, 28, 15, 20, 418, 419, 12, 18, 2, 2, 419, 420, 9, 10, 2, 2, 420, 440, 5, 28, 15, 19, 421, 422, 12, 17, 2, 2, 422, 423, 9, 11, 2, 2, 423, 440, 5, 28, 15, 18, 424, 425, 12, 16, 2, 2, 425, 426, 9, 12, 2, 2, 426, 440, 5, 28, 15, 16, 427, 428, 12, 15, 2, 2, 428, 429, 7, 141, 2, 2, 429, 440, 5, 28, 15, 15, 430, 431, 12, 14, 2, 2, 431, 432, 9, 13, 2, 2, 432, 440, 5, 28, 15, 15, 433, 434, 12, 13, 2, 2, 434, 435, 9, 14, 2, 2, 435, 440, 5, 28, 15, 14, 436, 437, 12, 12, 2, 2, 437, 438, 9, 15, 2, 2, 438, 440, 5, 28, 15, 13, 439, 415, 3, 2, 2, 2, 439, 418, 3, 2, 2, 2, 439, 421, 3, 2, 2, 2, 439, 424, 3, 2, 2, 2, 439, 427, 3, 2, 2, 2, 439, 430, 3, 2, 2, 2, 439, 433, 3, 2, 2, 2, 439, 436, 3, 2, 2, 2, 440, 443, 3, 2, 2, 2, 441, 439, 3, 2, 2, 2, 441, 442, 3, 2, 2, 2, 442, 29, 3, 2, 2, 2, 443, 441, 3, 2, 2, 2, 33, 33, 37, 42, 47, 53, 59, 64, 69, 74, 89, 124, 170, 263, 282, 294, 314, 320, 328, 336, 342, 348, 352, 359, 367, 376, 385, 390, 394, 413, 439, 441] \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.java b/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.java deleted file mode 100644 index 8f387fbca..000000000 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.java +++ /dev/null @@ -1,3658 +0,0 @@ -// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 by ANTLR 4.9.2 -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.misc.*; -import org.antlr.v4.runtime.tree.*; -import java.util.List; -import java.util.Iterator; -import java.util.ArrayList; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class AsZ80Parser extends Parser { - static { RuntimeMetaData.checkVersion("4.9.2", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - COMMENT=1, COMMENT2=2, OPCODE_ADC=3, OPCODE_ADD=4, OPCODE_AND=5, OPCODE_BIT=6, - OPCODE_CALL=7, OPCODE_CCF=8, OPCODE_CP=9, OPCODE_CPD=10, OPCODE_CPDR=11, - OPCODE_CPI=12, OPCODE_CPIR=13, OPCODE_CPL=14, OPCODE_DAA=15, OPCODE_DEC=16, - OPCODE_DI=17, OPCODE_DJNZ=18, OPCODE_EI=19, OPCODE_EX=20, OPCODE_EXX=21, - OPCODE_HALT=22, OPCODE_IM=23, OPCODE_IN=24, OPCODE_INC=25, OPCODE_IND=26, - OPCODE_INDR=27, OPCODE_INI=28, OPCODE_INIR=29, OPCODE_JP=30, OPCODE_JR=31, - OPCODE_LD=32, OPCODE_LDD=33, OPCODE_LDDR=34, OPCODE_LDI=35, OPCODE_LDIR=36, - OPCODE_NEG=37, OPCODE_NOP=38, OPCODE_OR=39, OPCODE_OTDR=40, OPCODE_OTIR=41, - OPCODE_OUT=42, OPCODE_OUTD=43, OPCODE_OUTI=44, OPCODE_POP=45, OPCODE_PUSH=46, - OPCODE_RES=47, OPCODE_RET=48, OPCODE_RETI=49, OPCODE_RETN=50, OPCODE_RL=51, - OPCODE_RLA=52, OPCODE_RLC=53, OPCODE_RLCA=54, OPCODE_RLD=55, OPCODE_RR=56, - OPCODE_RRA=57, OPCODE_RRC=58, OPCODE_RRCA=59, OPCODE_RRD=60, OPCODE_RST=61, - OPCODE_SBC=62, OPCODE_SCF=63, OPCODE_SET=64, OPCODE_SLA=65, OPCODE_SRA=66, - OPCODE_SLL=67, OPCODE_SRL=68, OPCODE_SUB=69, OPCODE_XOR=70, COND_C=71, - COND_NC=72, COND_Z=73, COND_NZ=74, COND_M=75, COND_P=76, COND_PE=77, COND_PO=78, - COND_WS=79, COND_UNRECOGNIZED=80, PREP_ORG=81, PREP_EQU=82, PREP_SET=83, - PREP_VAR=84, PREP_IF=85, PREP_ENDIF=86, PREP_INCLUDE=87, PREP_MACRO=88, - PREP_ENDM=89, PREP_DB=90, PREP_DW=91, PREP_DS=92, PREP_ADDR=93, REG_A=94, - REG_B=95, REG_C=96, REG_D=97, REG_E=98, REG_H=99, REG_L=100, REG_IX=101, - REG_IXH=102, REG_IXL=103, REG_IY=104, REG_IYH=105, REG_IYL=106, REG_BC=107, - REG_DE=108, REG_HL=109, REG_SP=110, REG_AF=111, REG_AFF=112, REG_I=113, - REG_R=114, OP_MOD=115, OP_SHR=116, OP_SHL=117, OP_NOT=118, OP_AND=119, - OP_OR=120, OP_XOR=121, LIT_HEXNUMBER_1=122, LIT_NUMBER=123, LIT_HEXNUMBER_2=124, - LIT_OCTNUMBER=125, LIT_BINNUMBER=126, LIT_STRING_1=127, LIT_STRING_2=128, - ID_IDENTIFIER=129, ID_LABEL=130, ERROR=131, SEP_LPAR=132, SEP_RPAR=133, - SEP_COMMA=134, OP_ADD=135, OP_SUBTRACT=136, OP_MULTIPLY=137, OP_DIVIDE=138, - OP_EQUAL=139, OP_GT=140, OP_GTE=141, OP_LT=142, OP_LTE=143, OP_MOD_2=144, - OP_SHR_2=145, OP_SHL_2=146, OP_NOT_2=147, OP_AND_2=148, OP_OR_2=149, OP_XOR_2=150, - WS=151, EOL=152; - public static final int - RULE_rStart = 0, RULE_rLine = 1, RULE_rStatement = 2, RULE_rInstruction = 3, - RULE_r8bitInstruction = 4, RULE_rRegister = 5, RULE_cCondition = 6, RULE_rPseudoCode = 7, - RULE_rMacroParameters = 8, RULE_rMacroArguments = 9, RULE_rData = 10, - RULE_rDBdata = 11, RULE_rDWdata = 12, RULE_rExpression = 13; - private static String[] makeRuleNames() { - return new String[] { - "rStart", "rLine", "rStatement", "rInstruction", "r8bitInstruction", - "rRegister", "cCondition", "rPseudoCode", "rMacroParameters", "rMacroArguments", - "rData", "rDBdata", "rDWdata", "rExpression" - }; - } - public static final String[] ruleNames = makeRuleNames(); - - private static String[] makeLiteralNames() { - return new String[] { - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, "'$'", null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - "'('", "')'", "','", "'+'", "'-'", "'*'", "'/'", "'='", "'>'", "'>='", - "'<'", "'<='", "'%'", "'>>'", "'<<'", "'!'", "'&'", "'|'", "'~'" - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - null, "COMMENT", "COMMENT2", "OPCODE_ADC", "OPCODE_ADD", "OPCODE_AND", - "OPCODE_BIT", "OPCODE_CALL", "OPCODE_CCF", "OPCODE_CP", "OPCODE_CPD", - "OPCODE_CPDR", "OPCODE_CPI", "OPCODE_CPIR", "OPCODE_CPL", "OPCODE_DAA", - "OPCODE_DEC", "OPCODE_DI", "OPCODE_DJNZ", "OPCODE_EI", "OPCODE_EX", "OPCODE_EXX", - "OPCODE_HALT", "OPCODE_IM", "OPCODE_IN", "OPCODE_INC", "OPCODE_IND", - "OPCODE_INDR", "OPCODE_INI", "OPCODE_INIR", "OPCODE_JP", "OPCODE_JR", - "OPCODE_LD", "OPCODE_LDD", "OPCODE_LDDR", "OPCODE_LDI", "OPCODE_LDIR", - "OPCODE_NEG", "OPCODE_NOP", "OPCODE_OR", "OPCODE_OTDR", "OPCODE_OTIR", - "OPCODE_OUT", "OPCODE_OUTD", "OPCODE_OUTI", "OPCODE_POP", "OPCODE_PUSH", - "OPCODE_RES", "OPCODE_RET", "OPCODE_RETI", "OPCODE_RETN", "OPCODE_RL", - "OPCODE_RLA", "OPCODE_RLC", "OPCODE_RLCA", "OPCODE_RLD", "OPCODE_RR", - "OPCODE_RRA", "OPCODE_RRC", "OPCODE_RRCA", "OPCODE_RRD", "OPCODE_RST", - "OPCODE_SBC", "OPCODE_SCF", "OPCODE_SET", "OPCODE_SLA", "OPCODE_SRA", - "OPCODE_SLL", "OPCODE_SRL", "OPCODE_SUB", "OPCODE_XOR", "COND_C", "COND_NC", - "COND_Z", "COND_NZ", "COND_M", "COND_P", "COND_PE", "COND_PO", "COND_WS", - "COND_UNRECOGNIZED", "PREP_ORG", "PREP_EQU", "PREP_SET", "PREP_VAR", - "PREP_IF", "PREP_ENDIF", "PREP_INCLUDE", "PREP_MACRO", "PREP_ENDM", "PREP_DB", - "PREP_DW", "PREP_DS", "PREP_ADDR", "REG_A", "REG_B", "REG_C", "REG_D", - "REG_E", "REG_H", "REG_L", "REG_IX", "REG_IXH", "REG_IXL", "REG_IY", - "REG_IYH", "REG_IYL", "REG_BC", "REG_DE", "REG_HL", "REG_SP", "REG_AF", - "REG_AFF", "REG_I", "REG_R", "OP_MOD", "OP_SHR", "OP_SHL", "OP_NOT", - "OP_AND", "OP_OR", "OP_XOR", "LIT_HEXNUMBER_1", "LIT_NUMBER", "LIT_HEXNUMBER_2", - "LIT_OCTNUMBER", "LIT_BINNUMBER", "LIT_STRING_1", "LIT_STRING_2", "ID_IDENTIFIER", - "ID_LABEL", "ERROR", "SEP_LPAR", "SEP_RPAR", "SEP_COMMA", "OP_ADD", "OP_SUBTRACT", - "OP_MULTIPLY", "OP_DIVIDE", "OP_EQUAL", "OP_GT", "OP_GTE", "OP_LT", "OP_LTE", - "OP_MOD_2", "OP_SHR_2", "OP_SHL_2", "OP_NOT_2", "OP_AND_2", "OP_OR_2", - "OP_XOR_2", "WS", "EOL" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - @Override - public String getGrammarFileName() { return "AsZ80Parser.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public ATN getATN() { return _ATN; } - - public AsZ80Parser(TokenStream input) { - super(input); - _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - public static class RStartContext extends ParserRuleContext { - public TerminalNode EOF() { return getToken(AsZ80Parser.EOF, 0); } - public List EOL() { return getTokens(AsZ80Parser.EOL); } - public TerminalNode EOL(int i) { - return getToken(AsZ80Parser.EOL, i); - } - public List rLine() { - return getRuleContexts(RLineContext.class); - } - public RLineContext rLine(int i) { - return getRuleContext(RLineContext.class,i); - } - public RStartContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rStart; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRStart(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRStart(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRStart(this); - else return visitor.visitChildren(this); - } - } - - public final RStartContext rStart() throws RecognitionException { - RStartContext _localctx = new RStartContext(_ctx, getState()); - enterRule(_localctx, 0, RULE_rStart); - int _la; - try { - int _alt; - enterOuterAlt(_localctx, 1); - { - setState(31); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,0,_ctx); - while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { - if ( _alt==1 ) { - { - { - setState(28); - match(EOL); - } - } - } - setState(33); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,0,_ctx); - } - setState(35); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) { - case 1: - { - setState(34); - rLine(); - } - break; - } - setState(45); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,3,_ctx); - while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { - if ( _alt==1 ) { - { - { - setState(38); - _errHandler.sync(this); - _alt = 1; - do { - switch (_alt) { - case 1: - { - { - setState(37); - match(EOL); - } - } - break; - default: - throw new NoViableAltException(this); - } - setState(40); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,2,_ctx); - } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); - setState(42); - rLine(); - } - } - } - setState(47); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,3,_ctx); - } - setState(51); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==EOL) { - { - { - setState(48); - match(EOL); - } - } - setState(53); - _errHandler.sync(this); - _la = _input.LA(1); - } - setState(54); - match(EOF); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class RLineContext extends ParserRuleContext { - public Token label; - public RStatementContext statement; - public RStatementContext rStatement() { - return getRuleContext(RStatementContext.class,0); - } - public List EOL() { return getTokens(AsZ80Parser.EOL); } - public TerminalNode EOL(int i) { - return getToken(AsZ80Parser.EOL, i); - } - public TerminalNode ID_LABEL() { return getToken(AsZ80Parser.ID_LABEL, 0); } - public RLineContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rLine; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRLine(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRLine(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRLine(this); - else return visitor.visitChildren(this); - } - } - - public final RLineContext rLine() throws RecognitionException { - RLineContext _localctx = new RLineContext(_ctx, getState()); - enterRule(_localctx, 2, RULE_rLine); - int _la; - try { - setState(67); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) { - case 1: - enterOuterAlt(_localctx, 1); - { - setState(57); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==ID_LABEL) { - { - setState(56); - ((RLineContext)_localctx).label = match(ID_LABEL); - } - } - - setState(62); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==EOL) { - { - { - setState(59); - match(EOL); - } - } - setState(64); - _errHandler.sync(this); - _la = _input.LA(1); - } - setState(65); - ((RLineContext)_localctx).statement = rStatement(); - } - break; - case 2: - enterOuterAlt(_localctx, 2); - { - setState(66); - ((RLineContext)_localctx).label = match(ID_LABEL); - } - break; - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class RStatementContext extends ParserRuleContext { - public RInstructionContext instr; - public RPseudoCodeContext pseudo; - public RDataContext data; - public RInstructionContext rInstruction() { - return getRuleContext(RInstructionContext.class,0); - } - public RPseudoCodeContext rPseudoCode() { - return getRuleContext(RPseudoCodeContext.class,0); - } - public RDataContext rData() { - return getRuleContext(RDataContext.class,0); - } - public RStatementContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rStatement; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRStatement(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRStatement(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRStatement(this); - else return visitor.visitChildren(this); - } - } - - public final RStatementContext rStatement() throws RecognitionException { - RStatementContext _localctx = new RStatementContext(_ctx, getState()); - enterRule(_localctx, 4, RULE_rStatement); - try { - setState(72); - _errHandler.sync(this); - switch (_input.LA(1)) { - case OPCODE_ADC: - case OPCODE_ADD: - case OPCODE_AND: - case OPCODE_CALL: - case OPCODE_CCF: - case OPCODE_CP: - case OPCODE_CPL: - case OPCODE_DAA: - case OPCODE_DEC: - case OPCODE_DI: - case OPCODE_EI: - case OPCODE_EX: - case OPCODE_EXX: - case OPCODE_HALT: - case OPCODE_IN: - case OPCODE_INC: - case OPCODE_JP: - case OPCODE_JR: - case OPCODE_LD: - case OPCODE_NOP: - case OPCODE_OR: - case OPCODE_OUT: - case OPCODE_POP: - case OPCODE_PUSH: - case OPCODE_RET: - case OPCODE_RLA: - case OPCODE_RLCA: - case OPCODE_RRA: - case OPCODE_RRCA: - case OPCODE_RST: - case OPCODE_SBC: - case OPCODE_SCF: - case OPCODE_SUB: - case OPCODE_XOR: - enterOuterAlt(_localctx, 1); - { - setState(69); - ((RStatementContext)_localctx).instr = rInstruction(); - } - break; - case PREP_ORG: - case PREP_IF: - case PREP_INCLUDE: - case ID_IDENTIFIER: - enterOuterAlt(_localctx, 2); - { - setState(70); - ((RStatementContext)_localctx).pseudo = rPseudoCode(); - } - break; - case PREP_DB: - case PREP_DW: - case PREP_DS: - enterOuterAlt(_localctx, 3); - { - setState(71); - ((RStatementContext)_localctx).data = rData(); - } - break; - default: - throw new NoViableAltException(this); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class RInstructionContext extends ParserRuleContext { - public RInstructionContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rInstruction; } - - public RInstructionContext() { } - public void copyFrom(RInstructionContext ctx) { - super.copyFrom(ctx); - } - } - public static class InstrRegExprContext extends RInstructionContext { - public Token opcode; - public RRegisterContext reg; - public RExpressionContext expr; - public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } - public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } - public RRegisterContext rRegister() { - return getRuleContext(RRegisterContext.class,0); - } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public InstrRegExprContext(RInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegExpr(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegExpr(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegExpr(this); - else return visitor.visitChildren(this); - } - } - public static class Instr8bitContext extends RInstructionContext { - public R8bitInstructionContext r8bitInstruction() { - return getRuleContext(R8bitInstructionContext.class,0); - } - public Instr8bitContext(RInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstr8bit(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstr8bit(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstr8bit(this); - else return visitor.visitChildren(this); - } - } - public static class InstrExprRegPairContext extends RInstructionContext { - public Token opcode; - public RExpressionContext expr; - public Token regpair; - public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } - public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } - public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } - public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public TerminalNode REG_HL() { return getToken(AsZ80Parser.REG_HL, 0); } - public InstrExprRegPairContext(RInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrExprRegPair(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrExprRegPair(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrExprRegPair(this); - else return visitor.visitChildren(this); - } - } - public static class InstrExprContext extends RInstructionContext { - public Token opcode; - public RExpressionContext expr; - public TerminalNode REG_A() { return getToken(AsZ80Parser.REG_A, 0); } - public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } - public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } - public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } - public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public TerminalNode OPCODE_CALL() { return getToken(AsZ80Parser.OPCODE_CALL, 0); } - public TerminalNode OPCODE_ADD() { return getToken(AsZ80Parser.OPCODE_ADD, 0); } - public TerminalNode OPCODE_ADC() { return getToken(AsZ80Parser.OPCODE_ADC, 0); } - public TerminalNode OPCODE_OUT() { return getToken(AsZ80Parser.OPCODE_OUT, 0); } - public TerminalNode OPCODE_SUB() { return getToken(AsZ80Parser.OPCODE_SUB, 0); } - public TerminalNode OPCODE_IN() { return getToken(AsZ80Parser.OPCODE_IN, 0); } - public TerminalNode OPCODE_SBC() { return getToken(AsZ80Parser.OPCODE_SBC, 0); } - public TerminalNode OPCODE_AND() { return getToken(AsZ80Parser.OPCODE_AND, 0); } - public TerminalNode OPCODE_XOR() { return getToken(AsZ80Parser.OPCODE_XOR, 0); } - public TerminalNode OPCODE_OR() { return getToken(AsZ80Parser.OPCODE_OR, 0); } - public TerminalNode OPCODE_CP() { return getToken(AsZ80Parser.OPCODE_CP, 0); } - public InstrExprContext(RInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrExpr(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrExpr(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrExpr(this); - else return visitor.visitChildren(this); - } - } - public static class InstrExprRegContext extends RInstructionContext { - public Token opcode; - public RExpressionContext expr; - public Token reg; - public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } - public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } - public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } - public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public TerminalNode REG_A() { return getToken(AsZ80Parser.REG_A, 0); } - public InstrExprRegContext(RInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrExprReg(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrExprReg(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrExprReg(this); - else return visitor.visitChildren(this); - } - } - public static class InstrCondExprContext extends RInstructionContext { - public Token opcode; - public Token cond; - public RExpressionContext expr; - public TerminalNode OPCODE_JR() { return getToken(AsZ80Parser.OPCODE_JR, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } - public TerminalNode COND_NZ() { return getToken(AsZ80Parser.COND_NZ, 0); } - public TerminalNode COND_Z() { return getToken(AsZ80Parser.COND_Z, 0); } - public TerminalNode COND_NC() { return getToken(AsZ80Parser.COND_NC, 0); } - public TerminalNode COND_C() { return getToken(AsZ80Parser.COND_C, 0); } - public TerminalNode OPCODE_JP() { return getToken(AsZ80Parser.OPCODE_JP, 0); } - public CConditionContext cCondition() { - return getRuleContext(CConditionContext.class,0); - } - public TerminalNode OPCODE_CALL() { return getToken(AsZ80Parser.OPCODE_CALL, 0); } - public InstrCondExprContext(RInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrCondExpr(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrCondExpr(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrCondExpr(this); - else return visitor.visitChildren(this); - } - } - public static class InstrRegPairExprContext extends RInstructionContext { - public Token opcode; - public Token regpair; - public RExpressionContext expr; - public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } - public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public TerminalNode REG_BC() { return getToken(AsZ80Parser.REG_BC, 0); } - public TerminalNode REG_DE() { return getToken(AsZ80Parser.REG_DE, 0); } - public TerminalNode REG_HL() { return getToken(AsZ80Parser.REG_HL, 0); } - public TerminalNode REG_SP() { return getToken(AsZ80Parser.REG_SP, 0); } - public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } - public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } - public InstrRegPairExprContext(RInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegPairExpr(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegPairExpr(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegPairExpr(this); - else return visitor.visitChildren(this); - } - } - - public final RInstructionContext rInstruction() throws RecognitionException { - RInstructionContext _localctx = new RInstructionContext(_ctx, getState()); - enterRule(_localctx, 6, RULE_rInstruction); - int _la; - try { - setState(168); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) { - case 1: - _localctx = new Instr8bitContext(_localctx); - enterOuterAlt(_localctx, 1); - { - setState(74); - r8bitInstruction(); - } - break; - case 2: - _localctx = new InstrRegPairExprContext(_localctx); - enterOuterAlt(_localctx, 2); - { - setState(75); - ((InstrRegPairExprContext)_localctx).opcode = match(OPCODE_LD); - setState(76); - ((InstrRegPairExprContext)_localctx).regpair = _input.LT(1); - _la = _input.LA(1); - if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_SP - 107)))) != 0)) ) { - ((InstrRegPairExprContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(77); - match(SEP_COMMA); - setState(78); - ((InstrRegPairExprContext)_localctx).expr = rExpression(0); - } - break; - case 3: - _localctx = new InstrRegExprContext(_localctx); - enterOuterAlt(_localctx, 3); - { - setState(79); - ((InstrRegExprContext)_localctx).opcode = match(OPCODE_LD); - setState(80); - ((InstrRegExprContext)_localctx).reg = rRegister(); - setState(81); - match(SEP_COMMA); - setState(82); - ((InstrRegExprContext)_localctx).expr = rExpression(0); - } - break; - case 4: - _localctx = new InstrCondExprContext(_localctx); - enterOuterAlt(_localctx, 4); - { - setState(84); - ((InstrCondExprContext)_localctx).opcode = match(OPCODE_JR); - setState(87); - _errHandler.sync(this); - _la = _input.LA(1); - if (((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (COND_C - 71)) | (1L << (COND_NC - 71)) | (1L << (COND_Z - 71)) | (1L << (COND_NZ - 71)))) != 0)) { - { - setState(85); - ((InstrCondExprContext)_localctx).cond = _input.LT(1); - _la = _input.LA(1); - if ( !(((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (COND_C - 71)) | (1L << (COND_NC - 71)) | (1L << (COND_Z - 71)) | (1L << (COND_NZ - 71)))) != 0)) ) { - ((InstrCondExprContext)_localctx).cond = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(86); - match(SEP_COMMA); - } - } - - setState(89); - ((InstrCondExprContext)_localctx).expr = rExpression(0); - } - break; - case 5: - _localctx = new InstrExprRegPairContext(_localctx); - enterOuterAlt(_localctx, 5); - { - setState(90); - ((InstrExprRegPairContext)_localctx).opcode = match(OPCODE_LD); - setState(91); - match(SEP_LPAR); - setState(92); - ((InstrExprRegPairContext)_localctx).expr = rExpression(0); - setState(93); - match(SEP_RPAR); - setState(94); - match(SEP_COMMA); - setState(95); - ((InstrExprRegPairContext)_localctx).regpair = match(REG_HL); - } - break; - case 6: - _localctx = new InstrRegPairExprContext(_localctx); - enterOuterAlt(_localctx, 6); - { - setState(97); - ((InstrRegPairExprContext)_localctx).opcode = match(OPCODE_LD); - setState(98); - ((InstrRegPairExprContext)_localctx).regpair = match(REG_HL); - setState(99); - match(SEP_COMMA); - setState(100); - match(SEP_LPAR); - setState(101); - ((InstrRegPairExprContext)_localctx).expr = rExpression(0); - setState(102); - match(SEP_RPAR); - } - break; - case 7: - _localctx = new InstrExprRegContext(_localctx); - enterOuterAlt(_localctx, 7); - { - setState(104); - ((InstrExprRegContext)_localctx).opcode = match(OPCODE_LD); - setState(105); - match(SEP_LPAR); - setState(106); - ((InstrExprRegContext)_localctx).expr = rExpression(0); - setState(107); - match(SEP_RPAR); - setState(108); - match(SEP_COMMA); - setState(109); - ((InstrExprRegContext)_localctx).reg = match(REG_A); - } - break; - case 8: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 8); - { - setState(111); - ((InstrExprContext)_localctx).opcode = match(OPCODE_LD); - setState(112); - match(REG_A); - setState(113); - match(SEP_COMMA); - setState(114); - match(SEP_LPAR); - setState(115); - ((InstrExprContext)_localctx).expr = rExpression(0); - setState(116); - match(SEP_RPAR); - } - break; - case 9: - _localctx = new InstrCondExprContext(_localctx); - enterOuterAlt(_localctx, 9); - { - setState(118); - ((InstrCondExprContext)_localctx).opcode = match(OPCODE_JP); - setState(122); - _errHandler.sync(this); - _la = _input.LA(1); - if (((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (COND_C - 71)) | (1L << (COND_NC - 71)) | (1L << (COND_Z - 71)) | (1L << (COND_NZ - 71)) | (1L << (COND_M - 71)) | (1L << (COND_P - 71)) | (1L << (COND_PE - 71)) | (1L << (COND_PO - 71)))) != 0)) { - { - setState(119); - ((InstrCondExprContext)_localctx).cond = cCondition(); - setState(120); - match(SEP_COMMA); - } - } - - setState(124); - ((InstrCondExprContext)_localctx).expr = rExpression(0); - } - break; - case 10: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 10); - { - setState(125); - ((InstrExprContext)_localctx).opcode = match(OPCODE_CALL); - setState(126); - ((InstrExprContext)_localctx).expr = rExpression(0); - } - break; - case 11: - _localctx = new InstrCondExprContext(_localctx); - enterOuterAlt(_localctx, 11); - { - setState(127); - ((InstrCondExprContext)_localctx).opcode = match(OPCODE_CALL); - setState(128); - ((InstrCondExprContext)_localctx).cond = cCondition(); - setState(129); - match(SEP_COMMA); - setState(130); - ((InstrCondExprContext)_localctx).expr = rExpression(0); - } - break; - case 12: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 12); - { - setState(132); - ((InstrExprContext)_localctx).opcode = match(OPCODE_ADD); - setState(133); - match(REG_A); - setState(134); - match(SEP_COMMA); - setState(135); - ((InstrExprContext)_localctx).expr = rExpression(0); - } - break; - case 13: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 13); - { - setState(136); - ((InstrExprContext)_localctx).opcode = match(OPCODE_ADC); - setState(137); - match(REG_A); - setState(138); - match(SEP_COMMA); - setState(139); - ((InstrExprContext)_localctx).expr = rExpression(0); - } - break; - case 14: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 14); - { - setState(140); - ((InstrExprContext)_localctx).opcode = match(OPCODE_OUT); - setState(141); - match(SEP_LPAR); - setState(142); - ((InstrExprContext)_localctx).expr = rExpression(0); - setState(143); - match(SEP_RPAR); - setState(144); - match(SEP_COMMA); - setState(145); - match(REG_A); - } - break; - case 15: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 15); - { - setState(147); - ((InstrExprContext)_localctx).opcode = match(OPCODE_SUB); - setState(148); - ((InstrExprContext)_localctx).expr = rExpression(0); - } - break; - case 16: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 16); - { - setState(149); - ((InstrExprContext)_localctx).opcode = match(OPCODE_IN); - setState(150); - match(REG_A); - setState(151); - match(SEP_COMMA); - setState(152); - match(SEP_LPAR); - setState(153); - ((InstrExprContext)_localctx).expr = rExpression(0); - setState(154); - match(SEP_RPAR); - } - break; - case 17: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 17); - { - setState(156); - ((InstrExprContext)_localctx).opcode = match(OPCODE_SBC); - setState(157); - match(REG_A); - setState(158); - match(SEP_COMMA); - setState(159); - ((InstrExprContext)_localctx).expr = rExpression(0); - } - break; - case 18: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 18); - { - setState(160); - ((InstrExprContext)_localctx).opcode = match(OPCODE_AND); - setState(161); - ((InstrExprContext)_localctx).expr = rExpression(0); - } - break; - case 19: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 19); - { - setState(162); - ((InstrExprContext)_localctx).opcode = match(OPCODE_XOR); - setState(163); - ((InstrExprContext)_localctx).expr = rExpression(0); - } - break; - case 20: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 20); - { - setState(164); - ((InstrExprContext)_localctx).opcode = match(OPCODE_OR); - setState(165); - ((InstrExprContext)_localctx).expr = rExpression(0); - } - break; - case 21: - _localctx = new InstrExprContext(_localctx); - enterOuterAlt(_localctx, 21); - { - setState(166); - ((InstrExprContext)_localctx).opcode = match(OPCODE_CP); - setState(167); - ((InstrExprContext)_localctx).expr = rExpression(0); - } - break; - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class R8bitInstructionContext extends ParserRuleContext { - public R8bitInstructionContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_r8bitInstruction; } - - public R8bitInstructionContext() { } - public void copyFrom(R8bitInstructionContext ctx) { - super.copyFrom(ctx); - } - } - public static class InstrRegPairRegContext extends R8bitInstructionContext { - public Token opcode; - public Token regpair; - public RRegisterContext reg; - public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } - public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } - public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } - public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } - public TerminalNode REG_HL() { return getToken(AsZ80Parser.REG_HL, 0); } - public RRegisterContext rRegister() { - return getRuleContext(RRegisterContext.class,0); - } - public InstrRegPairRegContext(R8bitInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegPairReg(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegPairReg(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegPairReg(this); - else return visitor.visitChildren(this); - } - } - public static class Instr8bitExprContext extends R8bitInstructionContext { - public Token opcode; - public RExpressionContext expr; - public TerminalNode OPCODE_RST() { return getToken(AsZ80Parser.OPCODE_RST, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public Instr8bitExprContext(R8bitInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstr8bitExpr(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstr8bitExpr(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstr8bitExpr(this); - else return visitor.visitChildren(this); - } - } - public static class InstrRegPairContext extends R8bitInstructionContext { - public Token opcode; - public Token regpair; - public Token regpairM; - public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } - public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } - public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } - public TerminalNode REG_A() { return getToken(AsZ80Parser.REG_A, 0); } - public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } - public TerminalNode REG_BC() { return getToken(AsZ80Parser.REG_BC, 0); } - public TerminalNode REG_DE() { return getToken(AsZ80Parser.REG_DE, 0); } - public TerminalNode OPCODE_INC() { return getToken(AsZ80Parser.OPCODE_INC, 0); } - public List REG_HL() { return getTokens(AsZ80Parser.REG_HL); } - public TerminalNode REG_HL(int i) { - return getToken(AsZ80Parser.REG_HL, i); - } - public TerminalNode REG_SP() { return getToken(AsZ80Parser.REG_SP, 0); } - public TerminalNode OPCODE_ADD() { return getToken(AsZ80Parser.OPCODE_ADD, 0); } - public TerminalNode OPCODE_DEC() { return getToken(AsZ80Parser.OPCODE_DEC, 0); } - public TerminalNode OPCODE_POP() { return getToken(AsZ80Parser.OPCODE_POP, 0); } - public TerminalNode REG_AF() { return getToken(AsZ80Parser.REG_AF, 0); } - public TerminalNode OPCODE_PUSH() { return getToken(AsZ80Parser.OPCODE_PUSH, 0); } - public TerminalNode OPCODE_JP() { return getToken(AsZ80Parser.OPCODE_JP, 0); } - public InstrRegPairContext(R8bitInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegPair(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegPair(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegPair(this); - else return visitor.visitChildren(this); - } - } - public static class InstrRegContext extends R8bitInstructionContext { - public Token opcode; - public RRegisterContext reg; - public TerminalNode OPCODE_INC() { return getToken(AsZ80Parser.OPCODE_INC, 0); } - public RRegisterContext rRegister() { - return getRuleContext(RRegisterContext.class,0); - } - public TerminalNode OPCODE_DEC() { return getToken(AsZ80Parser.OPCODE_DEC, 0); } - public TerminalNode REG_A() { return getToken(AsZ80Parser.REG_A, 0); } - public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } - public TerminalNode OPCODE_ADD() { return getToken(AsZ80Parser.OPCODE_ADD, 0); } - public TerminalNode OPCODE_ADC() { return getToken(AsZ80Parser.OPCODE_ADC, 0); } - public TerminalNode OPCODE_SUB() { return getToken(AsZ80Parser.OPCODE_SUB, 0); } - public TerminalNode OPCODE_SBC() { return getToken(AsZ80Parser.OPCODE_SBC, 0); } - public TerminalNode OPCODE_AND() { return getToken(AsZ80Parser.OPCODE_AND, 0); } - public TerminalNode OPCODE_XOR() { return getToken(AsZ80Parser.OPCODE_XOR, 0); } - public TerminalNode OPCODE_OR() { return getToken(AsZ80Parser.OPCODE_OR, 0); } - public TerminalNode OPCODE_CP() { return getToken(AsZ80Parser.OPCODE_CP, 0); } - public InstrRegContext(R8bitInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrReg(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrReg(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrReg(this); - else return visitor.visitChildren(this); - } - } - public static class InstrCondContext extends R8bitInstructionContext { - public Token opcode; - public CConditionContext cond; - public TerminalNode OPCODE_RET() { return getToken(AsZ80Parser.OPCODE_RET, 0); } - public CConditionContext cCondition() { - return getRuleContext(CConditionContext.class,0); - } - public InstrCondContext(R8bitInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrCond(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrCond(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrCond(this); - else return visitor.visitChildren(this); - } - } - public static class InstrNoArgsContext extends R8bitInstructionContext { - public Token opcode; - public TerminalNode OPCODE_NOP() { return getToken(AsZ80Parser.OPCODE_NOP, 0); } - public TerminalNode OPCODE_RLCA() { return getToken(AsZ80Parser.OPCODE_RLCA, 0); } - public TerminalNode OPCODE_RRCA() { return getToken(AsZ80Parser.OPCODE_RRCA, 0); } - public TerminalNode OPCODE_RLA() { return getToken(AsZ80Parser.OPCODE_RLA, 0); } - public TerminalNode OPCODE_RRA() { return getToken(AsZ80Parser.OPCODE_RRA, 0); } - public TerminalNode OPCODE_DAA() { return getToken(AsZ80Parser.OPCODE_DAA, 0); } - public TerminalNode OPCODE_CPL() { return getToken(AsZ80Parser.OPCODE_CPL, 0); } - public TerminalNode OPCODE_SCF() { return getToken(AsZ80Parser.OPCODE_SCF, 0); } - public TerminalNode OPCODE_CCF() { return getToken(AsZ80Parser.OPCODE_CCF, 0); } - public TerminalNode OPCODE_HALT() { return getToken(AsZ80Parser.OPCODE_HALT, 0); } - public TerminalNode OPCODE_EXX() { return getToken(AsZ80Parser.OPCODE_EXX, 0); } - public TerminalNode OPCODE_DI() { return getToken(AsZ80Parser.OPCODE_DI, 0); } - public TerminalNode OPCODE_EI() { return getToken(AsZ80Parser.OPCODE_EI, 0); } - public InstrNoArgsContext(R8bitInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrNoArgs(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrNoArgs(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrNoArgs(this); - else return visitor.visitChildren(this); - } - } - public static class InstrRegRegContext extends R8bitInstructionContext { - public Token opcode; - public RRegisterContext dst; - public RRegisterContext src; - public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } - public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } - public List rRegister() { - return getRuleContexts(RRegisterContext.class); - } - public RRegisterContext rRegister(int i) { - return getRuleContext(RRegisterContext.class,i); - } - public InstrRegRegContext(R8bitInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegReg(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegReg(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegReg(this); - else return visitor.visitChildren(this); - } - } - public static class InstrRegPairRegPairContext extends R8bitInstructionContext { - public Token opcode; - public Token src; - public Token dst; - public TerminalNode SEP_COMMA() { return getToken(AsZ80Parser.SEP_COMMA, 0); } - public TerminalNode OPCODE_EX() { return getToken(AsZ80Parser.OPCODE_EX, 0); } - public TerminalNode REG_AF() { return getToken(AsZ80Parser.REG_AF, 0); } - public TerminalNode REG_AFF() { return getToken(AsZ80Parser.REG_AFF, 0); } - public TerminalNode REG_DE() { return getToken(AsZ80Parser.REG_DE, 0); } - public TerminalNode REG_HL() { return getToken(AsZ80Parser.REG_HL, 0); } - public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } - public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } - public TerminalNode REG_SP() { return getToken(AsZ80Parser.REG_SP, 0); } - public TerminalNode OPCODE_LD() { return getToken(AsZ80Parser.OPCODE_LD, 0); } - public InstrRegPairRegPairContext(R8bitInstructionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterInstrRegPairRegPair(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitInstrRegPairRegPair(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitInstrRegPairRegPair(this); - else return visitor.visitChildren(this); - } - } - - public final R8bitInstructionContext r8bitInstruction() throws RecognitionException { - R8bitInstructionContext _localctx = new R8bitInstructionContext(_ctx, getState()); - enterRule(_localctx, 8, RULE_r8bitInstruction); - int _la; - try { - setState(280); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) { - case 1: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 1); - { - setState(170); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_NOP); - } - break; - case 2: - _localctx = new InstrRegPairContext(_localctx); - enterOuterAlt(_localctx, 2); - { - setState(171); - ((InstrRegPairContext)_localctx).opcode = match(OPCODE_LD); - setState(172); - match(SEP_LPAR); - setState(173); - ((InstrRegPairContext)_localctx).regpair = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==REG_BC || _la==REG_DE) ) { - ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(174); - match(SEP_RPAR); - setState(175); - match(SEP_COMMA); - setState(176); - match(REG_A); - } - break; - case 3: - _localctx = new InstrRegPairRegContext(_localctx); - enterOuterAlt(_localctx, 3); - { - setState(177); - ((InstrRegPairRegContext)_localctx).opcode = match(OPCODE_LD); - setState(178); - match(SEP_LPAR); - setState(179); - ((InstrRegPairRegContext)_localctx).regpair = match(REG_HL); - setState(180); - match(SEP_RPAR); - setState(181); - match(SEP_COMMA); - setState(182); - ((InstrRegPairRegContext)_localctx).reg = rRegister(); - } - break; - case 4: - _localctx = new InstrRegPairContext(_localctx); - enterOuterAlt(_localctx, 4); - { - setState(183); - ((InstrRegPairContext)_localctx).opcode = match(OPCODE_INC); - setState(184); - ((InstrRegPairContext)_localctx).regpair = _input.LT(1); - _la = _input.LA(1); - if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_SP - 107)))) != 0)) ) { - ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - break; - case 5: - _localctx = new InstrRegContext(_localctx); - enterOuterAlt(_localctx, 5); - { - setState(185); - ((InstrRegContext)_localctx).opcode = match(OPCODE_INC); - setState(186); - ((InstrRegContext)_localctx).reg = rRegister(); - } - break; - case 6: - _localctx = new InstrRegContext(_localctx); - enterOuterAlt(_localctx, 6); - { - setState(187); - ((InstrRegContext)_localctx).opcode = match(OPCODE_DEC); - setState(188); - ((InstrRegContext)_localctx).reg = rRegister(); - } - break; - case 7: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 7); - { - setState(189); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_RLCA); - } - break; - case 8: - _localctx = new InstrRegPairRegPairContext(_localctx); - enterOuterAlt(_localctx, 8); - { - setState(190); - ((InstrRegPairRegPairContext)_localctx).opcode = match(OPCODE_EX); - setState(191); - ((InstrRegPairRegPairContext)_localctx).src = match(REG_AF); - setState(192); - match(SEP_COMMA); - setState(193); - ((InstrRegPairRegPairContext)_localctx).dst = match(REG_AFF); - } - break; - case 9: - _localctx = new InstrRegPairRegPairContext(_localctx); - enterOuterAlt(_localctx, 9); - { - setState(194); - ((InstrRegPairRegPairContext)_localctx).opcode = match(OPCODE_EX); - setState(195); - ((InstrRegPairRegPairContext)_localctx).src = match(REG_DE); - setState(196); - match(SEP_COMMA); - setState(197); - ((InstrRegPairRegPairContext)_localctx).dst = match(REG_HL); - } - break; - case 10: - _localctx = new InstrRegPairRegPairContext(_localctx); - enterOuterAlt(_localctx, 10); - { - setState(198); - ((InstrRegPairRegPairContext)_localctx).opcode = match(OPCODE_EX); - setState(199); - match(SEP_LPAR); - setState(200); - ((InstrRegPairRegPairContext)_localctx).src = match(REG_SP); - setState(201); - match(SEP_RPAR); - setState(202); - match(SEP_COMMA); - setState(203); - ((InstrRegPairRegPairContext)_localctx).dst = match(REG_HL); - } - break; - case 11: - _localctx = new InstrRegPairContext(_localctx); - enterOuterAlt(_localctx, 11); - { - setState(204); - ((InstrRegPairContext)_localctx).opcode = match(OPCODE_ADD); - setState(205); - match(REG_HL); - setState(206); - match(SEP_COMMA); - setState(207); - ((InstrRegPairContext)_localctx).regpair = _input.LT(1); - _la = _input.LA(1); - if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_SP - 107)))) != 0)) ) { - ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - break; - case 12: - _localctx = new InstrRegPairContext(_localctx); - enterOuterAlt(_localctx, 12); - { - setState(208); - ((InstrRegPairContext)_localctx).opcode = match(OPCODE_LD); - setState(209); - match(REG_A); - setState(210); - match(SEP_COMMA); - setState(211); - match(SEP_LPAR); - setState(212); - ((InstrRegPairContext)_localctx).regpair = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==REG_BC || _la==REG_DE) ) { - ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(213); - match(SEP_RPAR); - } - break; - case 13: - _localctx = new InstrRegPairContext(_localctx); - enterOuterAlt(_localctx, 13); - { - setState(214); - ((InstrRegPairContext)_localctx).opcode = match(OPCODE_DEC); - setState(215); - ((InstrRegPairContext)_localctx).regpair = _input.LT(1); - _la = _input.LA(1); - if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_SP - 107)))) != 0)) ) { - ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - break; - case 14: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 14); - { - setState(216); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_RRCA); - } - break; - case 15: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 15); - { - setState(217); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_RLA); - } - break; - case 16: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 16); - { - setState(218); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_RRA); - } - break; - case 17: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 17); - { - setState(219); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_DAA); - } - break; - case 18: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 18); - { - setState(220); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_CPL); - } - break; - case 19: - _localctx = new InstrRegPairContext(_localctx); - enterOuterAlt(_localctx, 19); - { - setState(221); - ((InstrRegPairContext)_localctx).opcode = match(OPCODE_INC); - setState(222); - match(SEP_LPAR); - setState(223); - ((InstrRegPairContext)_localctx).regpairM = match(REG_HL); - setState(224); - match(SEP_RPAR); - } - break; - case 20: - _localctx = new InstrRegPairContext(_localctx); - enterOuterAlt(_localctx, 20); - { - setState(225); - ((InstrRegPairContext)_localctx).opcode = match(OPCODE_DEC); - setState(226); - match(SEP_LPAR); - setState(227); - ((InstrRegPairContext)_localctx).regpairM = match(REG_HL); - setState(228); - match(SEP_RPAR); - } - break; - case 21: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 21); - { - setState(229); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_SCF); - } - break; - case 22: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 22); - { - setState(230); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_CCF); - } - break; - case 23: - _localctx = new InstrRegRegContext(_localctx); - enterOuterAlt(_localctx, 23); - { - setState(231); - ((InstrRegRegContext)_localctx).opcode = match(OPCODE_LD); - setState(232); - ((InstrRegRegContext)_localctx).dst = rRegister(); - setState(233); - match(SEP_COMMA); - setState(234); - ((InstrRegRegContext)_localctx).src = rRegister(); - } - break; - case 24: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 24); - { - setState(236); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_HALT); - } - break; - case 25: - _localctx = new InstrRegContext(_localctx); - enterOuterAlt(_localctx, 25); - { - setState(237); - ((InstrRegContext)_localctx).opcode = match(OPCODE_ADD); - setState(238); - match(REG_A); - setState(239); - match(SEP_COMMA); - setState(240); - ((InstrRegContext)_localctx).reg = rRegister(); - } - break; - case 26: - _localctx = new InstrRegContext(_localctx); - enterOuterAlt(_localctx, 26); - { - setState(241); - ((InstrRegContext)_localctx).opcode = match(OPCODE_ADC); - setState(242); - match(REG_A); - setState(243); - match(SEP_COMMA); - setState(244); - ((InstrRegContext)_localctx).reg = rRegister(); - } - break; - case 27: - _localctx = new InstrRegContext(_localctx); - enterOuterAlt(_localctx, 27); - { - setState(245); - ((InstrRegContext)_localctx).opcode = match(OPCODE_SUB); - setState(246); - ((InstrRegContext)_localctx).reg = rRegister(); - } - break; - case 28: - _localctx = new InstrRegContext(_localctx); - enterOuterAlt(_localctx, 28); - { - setState(247); - ((InstrRegContext)_localctx).opcode = match(OPCODE_SBC); - setState(248); - match(REG_A); - setState(249); - match(SEP_COMMA); - setState(250); - ((InstrRegContext)_localctx).reg = rRegister(); - } - break; - case 29: - _localctx = new InstrRegContext(_localctx); - enterOuterAlt(_localctx, 29); - { - setState(251); - ((InstrRegContext)_localctx).opcode = match(OPCODE_AND); - setState(252); - ((InstrRegContext)_localctx).reg = rRegister(); - } - break; - case 30: - _localctx = new InstrRegContext(_localctx); - enterOuterAlt(_localctx, 30); - { - setState(253); - ((InstrRegContext)_localctx).opcode = match(OPCODE_XOR); - setState(254); - ((InstrRegContext)_localctx).reg = rRegister(); - } - break; - case 31: - _localctx = new InstrRegContext(_localctx); - enterOuterAlt(_localctx, 31); - { - setState(255); - ((InstrRegContext)_localctx).opcode = match(OPCODE_OR); - setState(256); - ((InstrRegContext)_localctx).reg = rRegister(); - } - break; - case 32: - _localctx = new InstrRegContext(_localctx); - enterOuterAlt(_localctx, 32); - { - setState(257); - ((InstrRegContext)_localctx).opcode = match(OPCODE_CP); - setState(258); - ((InstrRegContext)_localctx).reg = rRegister(); - } - break; - case 33: - _localctx = new InstrCondContext(_localctx); - enterOuterAlt(_localctx, 33); - { - setState(259); - ((InstrCondContext)_localctx).opcode = match(OPCODE_RET); - setState(261); - _errHandler.sync(this); - _la = _input.LA(1); - if (((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (COND_C - 71)) | (1L << (COND_NC - 71)) | (1L << (COND_Z - 71)) | (1L << (COND_NZ - 71)) | (1L << (COND_M - 71)) | (1L << (COND_P - 71)) | (1L << (COND_PE - 71)) | (1L << (COND_PO - 71)))) != 0)) { - { - setState(260); - ((InstrCondContext)_localctx).cond = cCondition(); - } - } - - } - break; - case 34: - _localctx = new InstrRegPairContext(_localctx); - enterOuterAlt(_localctx, 34); - { - setState(263); - ((InstrRegPairContext)_localctx).opcode = match(OPCODE_POP); - setState(264); - ((InstrRegPairContext)_localctx).regpair = _input.LT(1); - _la = _input.LA(1); - if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_AF - 107)))) != 0)) ) { - ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - break; - case 35: - _localctx = new InstrRegPairContext(_localctx); - enterOuterAlt(_localctx, 35); - { - setState(265); - ((InstrRegPairContext)_localctx).opcode = match(OPCODE_PUSH); - setState(266); - ((InstrRegPairContext)_localctx).regpair = _input.LT(1); - _la = _input.LA(1); - if ( !(((((_la - 107)) & ~0x3f) == 0 && ((1L << (_la - 107)) & ((1L << (REG_BC - 107)) | (1L << (REG_DE - 107)) | (1L << (REG_HL - 107)) | (1L << (REG_AF - 107)))) != 0)) ) { - ((InstrRegPairContext)_localctx).regpair = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - break; - case 36: - _localctx = new Instr8bitExprContext(_localctx); - enterOuterAlt(_localctx, 36); - { - setState(267); - ((Instr8bitExprContext)_localctx).opcode = match(OPCODE_RST); - setState(268); - ((Instr8bitExprContext)_localctx).expr = rExpression(0); - } - break; - case 37: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 37); - { - setState(269); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_EXX); - } - break; - case 38: - _localctx = new InstrRegPairContext(_localctx); - enterOuterAlt(_localctx, 38); - { - setState(270); - ((InstrRegPairContext)_localctx).opcode = match(OPCODE_JP); - setState(271); - match(SEP_LPAR); - setState(272); - ((InstrRegPairContext)_localctx).regpairM = match(REG_HL); - setState(273); - match(SEP_RPAR); - } - break; - case 39: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 39); - { - setState(274); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_DI); - } - break; - case 40: - _localctx = new InstrRegPairRegPairContext(_localctx); - enterOuterAlt(_localctx, 40); - { - setState(275); - ((InstrRegPairRegPairContext)_localctx).opcode = match(OPCODE_LD); - setState(276); - ((InstrRegPairRegPairContext)_localctx).dst = match(REG_SP); - setState(277); - match(SEP_COMMA); - setState(278); - ((InstrRegPairRegPairContext)_localctx).src = match(REG_HL); - } - break; - case 41: - _localctx = new InstrNoArgsContext(_localctx); - enterOuterAlt(_localctx, 41); - { - setState(279); - ((InstrNoArgsContext)_localctx).opcode = match(OPCODE_EI); - } - break; - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class RRegisterContext extends ParserRuleContext { - public Token r; - public TerminalNode REG_A() { return getToken(AsZ80Parser.REG_A, 0); } - public TerminalNode REG_B() { return getToken(AsZ80Parser.REG_B, 0); } - public TerminalNode REG_C() { return getToken(AsZ80Parser.REG_C, 0); } - public TerminalNode REG_D() { return getToken(AsZ80Parser.REG_D, 0); } - public TerminalNode REG_E() { return getToken(AsZ80Parser.REG_E, 0); } - public TerminalNode REG_H() { return getToken(AsZ80Parser.REG_H, 0); } - public TerminalNode REG_L() { return getToken(AsZ80Parser.REG_L, 0); } - public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } - public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } - public TerminalNode REG_HL() { return getToken(AsZ80Parser.REG_HL, 0); } - public RRegisterContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rRegister; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRRegister(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRRegister(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRRegister(this); - else return visitor.visitChildren(this); - } - } - - public final RRegisterContext rRegister() throws RecognitionException { - RRegisterContext _localctx = new RRegisterContext(_ctx, getState()); - enterRule(_localctx, 10, RULE_rRegister); - try { - setState(292); - _errHandler.sync(this); - switch (_input.LA(1)) { - case REG_A: - enterOuterAlt(_localctx, 1); - { - setState(282); - ((RRegisterContext)_localctx).r = match(REG_A); - } - break; - case REG_B: - enterOuterAlt(_localctx, 2); - { - setState(283); - ((RRegisterContext)_localctx).r = match(REG_B); - } - break; - case REG_C: - enterOuterAlt(_localctx, 3); - { - setState(284); - ((RRegisterContext)_localctx).r = match(REG_C); - } - break; - case REG_D: - enterOuterAlt(_localctx, 4); - { - setState(285); - ((RRegisterContext)_localctx).r = match(REG_D); - } - break; - case REG_E: - enterOuterAlt(_localctx, 5); - { - setState(286); - ((RRegisterContext)_localctx).r = match(REG_E); - } - break; - case REG_H: - enterOuterAlt(_localctx, 6); - { - setState(287); - ((RRegisterContext)_localctx).r = match(REG_H); - } - break; - case REG_L: - enterOuterAlt(_localctx, 7); - { - setState(288); - ((RRegisterContext)_localctx).r = match(REG_L); - } - break; - case SEP_LPAR: - enterOuterAlt(_localctx, 8); - { - setState(289); - match(SEP_LPAR); - setState(290); - ((RRegisterContext)_localctx).r = match(REG_HL); - setState(291); - match(SEP_RPAR); - } - break; - default: - throw new NoViableAltException(this); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class CConditionContext extends ParserRuleContext { - public TerminalNode COND_C() { return getToken(AsZ80Parser.COND_C, 0); } - public TerminalNode COND_NC() { return getToken(AsZ80Parser.COND_NC, 0); } - public TerminalNode COND_Z() { return getToken(AsZ80Parser.COND_Z, 0); } - public TerminalNode COND_NZ() { return getToken(AsZ80Parser.COND_NZ, 0); } - public TerminalNode COND_M() { return getToken(AsZ80Parser.COND_M, 0); } - public TerminalNode COND_P() { return getToken(AsZ80Parser.COND_P, 0); } - public TerminalNode COND_PE() { return getToken(AsZ80Parser.COND_PE, 0); } - public TerminalNode COND_PO() { return getToken(AsZ80Parser.COND_PO, 0); } - public CConditionContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_cCondition; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterCCondition(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitCCondition(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitCCondition(this); - else return visitor.visitChildren(this); - } - } - - public final CConditionContext cCondition() throws RecognitionException { - CConditionContext _localctx = new CConditionContext(_ctx, getState()); - enterRule(_localctx, 12, RULE_cCondition); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(294); - _la = _input.LA(1); - if ( !(((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (COND_C - 71)) | (1L << (COND_NC - 71)) | (1L << (COND_Z - 71)) | (1L << (COND_NZ - 71)) | (1L << (COND_M - 71)) | (1L << (COND_P - 71)) | (1L << (COND_PE - 71)) | (1L << (COND_PO - 71)))) != 0)) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class RPseudoCodeContext extends ParserRuleContext { - public RPseudoCodeContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rPseudoCode; } - - public RPseudoCodeContext() { } - public void copyFrom(RPseudoCodeContext ctx) { - super.copyFrom(ctx); - } - } - public static class PseudoIncludeContext extends RPseudoCodeContext { - public Token filename; - public TerminalNode PREP_INCLUDE() { return getToken(AsZ80Parser.PREP_INCLUDE, 0); } - public TerminalNode LIT_STRING_1() { return getToken(AsZ80Parser.LIT_STRING_1, 0); } - public TerminalNode LIT_STRING_2() { return getToken(AsZ80Parser.LIT_STRING_2, 0); } - public PseudoIncludeContext(RPseudoCodeContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoInclude(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoInclude(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoInclude(this); - else return visitor.visitChildren(this); - } - } - public static class PseudoIfContext extends RPseudoCodeContext { - public RExpressionContext expr; - public TerminalNode PREP_IF() { return getToken(AsZ80Parser.PREP_IF, 0); } - public List EOL() { return getTokens(AsZ80Parser.EOL); } - public TerminalNode EOL(int i) { - return getToken(AsZ80Parser.EOL, i); - } - public TerminalNode PREP_ENDIF() { return getToken(AsZ80Parser.PREP_ENDIF, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public List rLine() { - return getRuleContexts(RLineContext.class); - } - public RLineContext rLine(int i) { - return getRuleContext(RLineContext.class,i); - } - public PseudoIfContext(RPseudoCodeContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoIf(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoIf(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoIf(this); - else return visitor.visitChildren(this); - } - } - public static class PseudoEquContext extends RPseudoCodeContext { - public Token id; - public RExpressionContext expr; - public TerminalNode PREP_EQU() { return getToken(AsZ80Parser.PREP_EQU, 0); } - public TerminalNode ID_IDENTIFIER() { return getToken(AsZ80Parser.ID_IDENTIFIER, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public PseudoEquContext(RPseudoCodeContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoEqu(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoEqu(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoEqu(this); - else return visitor.visitChildren(this); - } - } - public static class PseudoMacroCallContext extends RPseudoCodeContext { - public Token id; - public RMacroArgumentsContext args; - public TerminalNode ID_IDENTIFIER() { return getToken(AsZ80Parser.ID_IDENTIFIER, 0); } - public RMacroArgumentsContext rMacroArguments() { - return getRuleContext(RMacroArgumentsContext.class,0); - } - public PseudoMacroCallContext(RPseudoCodeContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoMacroCall(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoMacroCall(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoMacroCall(this); - else return visitor.visitChildren(this); - } - } - public static class PseudoMacroDefContext extends RPseudoCodeContext { - public Token id; - public RMacroParametersContext params; - public TerminalNode PREP_MACRO() { return getToken(AsZ80Parser.PREP_MACRO, 0); } - public List EOL() { return getTokens(AsZ80Parser.EOL); } - public TerminalNode EOL(int i) { - return getToken(AsZ80Parser.EOL, i); - } - public TerminalNode PREP_ENDM() { return getToken(AsZ80Parser.PREP_ENDM, 0); } - public TerminalNode ID_IDENTIFIER() { return getToken(AsZ80Parser.ID_IDENTIFIER, 0); } - public List rLine() { - return getRuleContexts(RLineContext.class); - } - public RLineContext rLine(int i) { - return getRuleContext(RLineContext.class,i); - } - public RMacroParametersContext rMacroParameters() { - return getRuleContext(RMacroParametersContext.class,0); - } - public PseudoMacroDefContext(RPseudoCodeContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoMacroDef(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoMacroDef(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoMacroDef(this); - else return visitor.visitChildren(this); - } - } - public static class PseudoSetContext extends RPseudoCodeContext { - public Token id; - public RExpressionContext expr; - public TerminalNode PREP_SET() { return getToken(AsZ80Parser.PREP_SET, 0); } - public TerminalNode ID_IDENTIFIER() { return getToken(AsZ80Parser.ID_IDENTIFIER, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public PseudoSetContext(RPseudoCodeContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoSet(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoSet(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoSet(this); - else return visitor.visitChildren(this); - } - } - public static class PseudoOrgContext extends RPseudoCodeContext { - public RExpressionContext expr; - public TerminalNode PREP_ORG() { return getToken(AsZ80Parser.PREP_ORG, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public PseudoOrgContext(RPseudoCodeContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterPseudoOrg(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitPseudoOrg(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitPseudoOrg(this); - else return visitor.visitChildren(this); - } - } - - public final RPseudoCodeContext rPseudoCode() throws RecognitionException { - RPseudoCodeContext _localctx = new RPseudoCodeContext(_ctx, getState()); - enterRule(_localctx, 14, RULE_rPseudoCode); - int _la; - try { - int _alt; - setState(350); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,21,_ctx) ) { - case 1: - _localctx = new PseudoOrgContext(_localctx); - enterOuterAlt(_localctx, 1); - { - setState(296); - match(PREP_ORG); - setState(297); - ((PseudoOrgContext)_localctx).expr = rExpression(0); - } - break; - case 2: - _localctx = new PseudoEquContext(_localctx); - enterOuterAlt(_localctx, 2); - { - setState(298); - ((PseudoEquContext)_localctx).id = match(ID_IDENTIFIER); - setState(299); - match(PREP_EQU); - setState(300); - ((PseudoEquContext)_localctx).expr = rExpression(0); - } - break; - case 3: - _localctx = new PseudoSetContext(_localctx); - enterOuterAlt(_localctx, 3); - { - setState(301); - ((PseudoSetContext)_localctx).id = match(ID_IDENTIFIER); - setState(302); - match(PREP_SET); - setState(303); - ((PseudoSetContext)_localctx).expr = rExpression(0); - } - break; - case 4: - _localctx = new PseudoIfContext(_localctx); - enterOuterAlt(_localctx, 4); - { - setState(304); - match(PREP_IF); - setState(305); - ((PseudoIfContext)_localctx).expr = rExpression(0); - setState(306); - match(EOL); - setState(312); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,15,_ctx); - while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { - if ( _alt==1 ) { - { - { - setState(307); - rLine(); - setState(308); - match(EOL); - } - } - } - setState(314); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,15,_ctx); - } - setState(318); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==EOL) { - { - { - setState(315); - match(EOL); - } - } - setState(320); - _errHandler.sync(this); - _la = _input.LA(1); - } - setState(321); - match(PREP_ENDIF); - } - break; - case 5: - _localctx = new PseudoMacroDefContext(_localctx); - enterOuterAlt(_localctx, 5); - { - setState(323); - ((PseudoMacroDefContext)_localctx).id = match(ID_IDENTIFIER); - setState(324); - match(PREP_MACRO); - setState(326); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==ID_IDENTIFIER) { - { - setState(325); - ((PseudoMacroDefContext)_localctx).params = rMacroParameters(); - } - } - - setState(328); - match(EOL); - setState(334); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,18,_ctx); - while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { - if ( _alt==1 ) { - { - { - setState(329); - rLine(); - setState(330); - match(EOL); - } - } - } - setState(336); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,18,_ctx); - } - setState(340); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==EOL) { - { - { - setState(337); - match(EOL); - } - } - setState(342); - _errHandler.sync(this); - _la = _input.LA(1); - } - setState(343); - match(PREP_ENDM); - } - break; - case 6: - _localctx = new PseudoMacroCallContext(_localctx); - enterOuterAlt(_localctx, 6); - { - setState(344); - ((PseudoMacroCallContext)_localctx).id = match(ID_IDENTIFIER); - setState(346); - _errHandler.sync(this); - _la = _input.LA(1); - if (((((_la - 93)) & ~0x3f) == 0 && ((1L << (_la - 93)) & ((1L << (PREP_ADDR - 93)) | (1L << (OP_NOT - 93)) | (1L << (LIT_HEXNUMBER_1 - 93)) | (1L << (LIT_NUMBER - 93)) | (1L << (LIT_HEXNUMBER_2 - 93)) | (1L << (LIT_OCTNUMBER - 93)) | (1L << (LIT_BINNUMBER - 93)) | (1L << (LIT_STRING_1 - 93)) | (1L << (LIT_STRING_2 - 93)) | (1L << (ID_IDENTIFIER - 93)) | (1L << (SEP_LPAR - 93)) | (1L << (OP_ADD - 93)) | (1L << (OP_SUBTRACT - 93)) | (1L << (OP_NOT_2 - 93)))) != 0)) { - { - setState(345); - ((PseudoMacroCallContext)_localctx).args = rMacroArguments(); - } - } - - } - break; - case 7: - _localctx = new PseudoIncludeContext(_localctx); - enterOuterAlt(_localctx, 7); - { - setState(348); - match(PREP_INCLUDE); - setState(349); - ((PseudoIncludeContext)_localctx).filename = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==LIT_STRING_1 || _la==LIT_STRING_2) ) { - ((PseudoIncludeContext)_localctx).filename = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - break; - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class RMacroParametersContext extends ParserRuleContext { - public List ID_IDENTIFIER() { return getTokens(AsZ80Parser.ID_IDENTIFIER); } - public TerminalNode ID_IDENTIFIER(int i) { - return getToken(AsZ80Parser.ID_IDENTIFIER, i); - } - public List SEP_COMMA() { return getTokens(AsZ80Parser.SEP_COMMA); } - public TerminalNode SEP_COMMA(int i) { - return getToken(AsZ80Parser.SEP_COMMA, i); - } - public RMacroParametersContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rMacroParameters; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRMacroParameters(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRMacroParameters(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRMacroParameters(this); - else return visitor.visitChildren(this); - } - } - - public final RMacroParametersContext rMacroParameters() throws RecognitionException { - RMacroParametersContext _localctx = new RMacroParametersContext(_ctx, getState()); - enterRule(_localctx, 16, RULE_rMacroParameters); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(352); - match(ID_IDENTIFIER); - setState(357); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==SEP_COMMA) { - { - { - setState(353); - match(SEP_COMMA); - setState(354); - match(ID_IDENTIFIER); - } - } - setState(359); - _errHandler.sync(this); - _la = _input.LA(1); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class RMacroArgumentsContext extends ParserRuleContext { - public List rExpression() { - return getRuleContexts(RExpressionContext.class); - } - public RExpressionContext rExpression(int i) { - return getRuleContext(RExpressionContext.class,i); - } - public List SEP_COMMA() { return getTokens(AsZ80Parser.SEP_COMMA); } - public TerminalNode SEP_COMMA(int i) { - return getToken(AsZ80Parser.SEP_COMMA, i); - } - public RMacroArgumentsContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rMacroArguments; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRMacroArguments(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRMacroArguments(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRMacroArguments(this); - else return visitor.visitChildren(this); - } - } - - public final RMacroArgumentsContext rMacroArguments() throws RecognitionException { - RMacroArgumentsContext _localctx = new RMacroArgumentsContext(_ctx, getState()); - enterRule(_localctx, 18, RULE_rMacroArguments); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(360); - rExpression(0); - setState(365); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==SEP_COMMA) { - { - { - setState(361); - match(SEP_COMMA); - setState(362); - rExpression(0); - } - } - setState(367); - _errHandler.sync(this); - _la = _input.LA(1); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class RDataContext extends ParserRuleContext { - public RDataContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rData; } - - public RDataContext() { } - public void copyFrom(RDataContext ctx) { - super.copyFrom(ctx); - } - } - public static class DataDSContext extends RDataContext { - public RExpressionContext data; - public TerminalNode PREP_DS() { return getToken(AsZ80Parser.PREP_DS, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public DataDSContext(RDataContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterDataDS(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitDataDS(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitDataDS(this); - else return visitor.visitChildren(this); - } - } - public static class DataDBContext extends RDataContext { - public TerminalNode PREP_DB() { return getToken(AsZ80Parser.PREP_DB, 0); } - public List rDBdata() { - return getRuleContexts(RDBdataContext.class); - } - public RDBdataContext rDBdata(int i) { - return getRuleContext(RDBdataContext.class,i); - } - public List SEP_COMMA() { return getTokens(AsZ80Parser.SEP_COMMA); } - public TerminalNode SEP_COMMA(int i) { - return getToken(AsZ80Parser.SEP_COMMA, i); - } - public DataDBContext(RDataContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterDataDB(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitDataDB(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitDataDB(this); - else return visitor.visitChildren(this); - } - } - public static class DataDWContext extends RDataContext { - public TerminalNode PREP_DW() { return getToken(AsZ80Parser.PREP_DW, 0); } - public List rDWdata() { - return getRuleContexts(RDWdataContext.class); - } - public RDWdataContext rDWdata(int i) { - return getRuleContext(RDWdataContext.class,i); - } - public List SEP_COMMA() { return getTokens(AsZ80Parser.SEP_COMMA); } - public TerminalNode SEP_COMMA(int i) { - return getToken(AsZ80Parser.SEP_COMMA, i); - } - public DataDWContext(RDataContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterDataDW(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitDataDW(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitDataDW(this); - else return visitor.visitChildren(this); - } - } - - public final RDataContext rData() throws RecognitionException { - RDataContext _localctx = new RDataContext(_ctx, getState()); - enterRule(_localctx, 20, RULE_rData); - int _la; - try { - setState(388); - _errHandler.sync(this); - switch (_input.LA(1)) { - case PREP_DB: - _localctx = new DataDBContext(_localctx); - enterOuterAlt(_localctx, 1); - { - setState(368); - match(PREP_DB); - setState(369); - rDBdata(); - setState(374); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==SEP_COMMA) { - { - { - setState(370); - match(SEP_COMMA); - setState(371); - rDBdata(); - } - } - setState(376); - _errHandler.sync(this); - _la = _input.LA(1); - } - } - break; - case PREP_DW: - _localctx = new DataDWContext(_localctx); - enterOuterAlt(_localctx, 2); - { - setState(377); - match(PREP_DW); - setState(378); - rDWdata(); - setState(383); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==SEP_COMMA) { - { - { - setState(379); - match(SEP_COMMA); - setState(380); - rDWdata(); - } - } - setState(385); - _errHandler.sync(this); - _la = _input.LA(1); - } - } - break; - case PREP_DS: - _localctx = new DataDSContext(_localctx); - enterOuterAlt(_localctx, 3); - { - setState(386); - match(PREP_DS); - setState(387); - ((DataDSContext)_localctx).data = rExpression(0); - } - break; - default: - throw new NoViableAltException(this); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class RDBdataContext extends ParserRuleContext { - public RExpressionContext expr; - public R8bitInstructionContext instr; - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public R8bitInstructionContext r8bitInstruction() { - return getRuleContext(R8bitInstructionContext.class,0); - } - public RDBdataContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rDBdata; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRDBdata(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRDBdata(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRDBdata(this); - else return visitor.visitChildren(this); - } - } - - public final RDBdataContext rDBdata() throws RecognitionException { - RDBdataContext _localctx = new RDBdataContext(_ctx, getState()); - enterRule(_localctx, 22, RULE_rDBdata); - try { - setState(392); - _errHandler.sync(this); - switch (_input.LA(1)) { - case PREP_ADDR: - case OP_NOT: - case LIT_HEXNUMBER_1: - case LIT_NUMBER: - case LIT_HEXNUMBER_2: - case LIT_OCTNUMBER: - case LIT_BINNUMBER: - case LIT_STRING_1: - case LIT_STRING_2: - case ID_IDENTIFIER: - case SEP_LPAR: - case OP_ADD: - case OP_SUBTRACT: - case OP_NOT_2: - enterOuterAlt(_localctx, 1); - { - setState(390); - ((RDBdataContext)_localctx).expr = rExpression(0); - } - break; - case OPCODE_ADC: - case OPCODE_ADD: - case OPCODE_AND: - case OPCODE_CCF: - case OPCODE_CP: - case OPCODE_CPL: - case OPCODE_DAA: - case OPCODE_DEC: - case OPCODE_DI: - case OPCODE_EI: - case OPCODE_EX: - case OPCODE_EXX: - case OPCODE_HALT: - case OPCODE_INC: - case OPCODE_JP: - case OPCODE_LD: - case OPCODE_NOP: - case OPCODE_OR: - case OPCODE_POP: - case OPCODE_PUSH: - case OPCODE_RET: - case OPCODE_RLA: - case OPCODE_RLCA: - case OPCODE_RRA: - case OPCODE_RRCA: - case OPCODE_RST: - case OPCODE_SBC: - case OPCODE_SCF: - case OPCODE_SUB: - case OPCODE_XOR: - enterOuterAlt(_localctx, 2); - { - setState(391); - ((RDBdataContext)_localctx).instr = r8bitInstruction(); - } - break; - default: - throw new NoViableAltException(this); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class RDWdataContext extends ParserRuleContext { - public RExpressionContext expr; - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public RDWdataContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rDWdata; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterRDWdata(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitRDWdata(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitRDWdata(this); - else return visitor.visitChildren(this); - } - } - - public final RDWdataContext rDWdata() throws RecognitionException { - RDWdataContext _localctx = new RDWdataContext(_ctx, getState()); - enterRule(_localctx, 24, RULE_rDWdata); - try { - enterOuterAlt(_localctx, 1); - { - setState(394); - ((RDWdataContext)_localctx).expr = rExpression(0); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public static class RExpressionContext extends ParserRuleContext { - public RExpressionContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_rExpression; } - - public RExpressionContext() { } - public void copyFrom(RExpressionContext ctx) { - super.copyFrom(ctx); - } - } - public static class ExprOctContext extends RExpressionContext { - public Token num; - public TerminalNode LIT_OCTNUMBER() { return getToken(AsZ80Parser.LIT_OCTNUMBER, 0); } - public ExprOctContext(RExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprOct(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprOct(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprOct(this); - else return visitor.visitChildren(this); - } - } - public static class ExprHex1Context extends RExpressionContext { - public Token num; - public TerminalNode LIT_HEXNUMBER_1() { return getToken(AsZ80Parser.LIT_HEXNUMBER_1, 0); } - public ExprHex1Context(RExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprHex1(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprHex1(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprHex1(this); - else return visitor.visitChildren(this); - } - } - public static class ExprHex2Context extends RExpressionContext { - public Token num; - public TerminalNode LIT_HEXNUMBER_2() { return getToken(AsZ80Parser.LIT_HEXNUMBER_2, 0); } - public ExprHex2Context(RExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprHex2(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprHex2(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprHex2(this); - else return visitor.visitChildren(this); - } - } - public static class ExprDecContext extends RExpressionContext { - public Token num; - public TerminalNode LIT_NUMBER() { return getToken(AsZ80Parser.LIT_NUMBER, 0); } - public ExprDecContext(RExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprDec(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprDec(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprDec(this); - else return visitor.visitChildren(this); - } - } - public static class ExprStringContext extends RExpressionContext { - public Token str; - public TerminalNode LIT_STRING_1() { return getToken(AsZ80Parser.LIT_STRING_1, 0); } - public TerminalNode LIT_STRING_2() { return getToken(AsZ80Parser.LIT_STRING_2, 0); } - public ExprStringContext(RExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprString(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprString(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprString(this); - else return visitor.visitChildren(this); - } - } - public static class ExprBinContext extends RExpressionContext { - public Token num; - public TerminalNode LIT_BINNUMBER() { return getToken(AsZ80Parser.LIT_BINNUMBER, 0); } - public ExprBinContext(RExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprBin(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprBin(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprBin(this); - else return visitor.visitChildren(this); - } - } - public static class ExprParensContext extends RExpressionContext { - public RExpressionContext expr; - public TerminalNode SEP_LPAR() { return getToken(AsZ80Parser.SEP_LPAR, 0); } - public TerminalNode SEP_RPAR() { return getToken(AsZ80Parser.SEP_RPAR, 0); } - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public ExprParensContext(RExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprParens(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprParens(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprParens(this); - else return visitor.visitChildren(this); - } - } - public static class ExprIdContext extends RExpressionContext { - public Token id; - public TerminalNode ID_IDENTIFIER() { return getToken(AsZ80Parser.ID_IDENTIFIER, 0); } - public ExprIdContext(RExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprId(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprId(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprId(this); - else return visitor.visitChildren(this); - } - } - public static class ExprUnaryContext extends RExpressionContext { - public Token unaryop; - public RExpressionContext expr; - public RExpressionContext rExpression() { - return getRuleContext(RExpressionContext.class,0); - } - public TerminalNode OP_ADD() { return getToken(AsZ80Parser.OP_ADD, 0); } - public TerminalNode OP_SUBTRACT() { return getToken(AsZ80Parser.OP_SUBTRACT, 0); } - public TerminalNode OP_NOT() { return getToken(AsZ80Parser.OP_NOT, 0); } - public TerminalNode OP_NOT_2() { return getToken(AsZ80Parser.OP_NOT_2, 0); } - public ExprUnaryContext(RExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprUnary(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprUnary(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprUnary(this); - else return visitor.visitChildren(this); - } - } - public static class ExprInfixContext extends RExpressionContext { - public RExpressionContext expr1; - public Token op; - public RExpressionContext expr2; - public List rExpression() { - return getRuleContexts(RExpressionContext.class); - } - public RExpressionContext rExpression(int i) { - return getRuleContext(RExpressionContext.class,i); - } - public TerminalNode OP_MULTIPLY() { return getToken(AsZ80Parser.OP_MULTIPLY, 0); } - public TerminalNode OP_DIVIDE() { return getToken(AsZ80Parser.OP_DIVIDE, 0); } - public TerminalNode OP_MOD() { return getToken(AsZ80Parser.OP_MOD, 0); } - public TerminalNode OP_MOD_2() { return getToken(AsZ80Parser.OP_MOD_2, 0); } - public TerminalNode OP_ADD() { return getToken(AsZ80Parser.OP_ADD, 0); } - public TerminalNode OP_SUBTRACT() { return getToken(AsZ80Parser.OP_SUBTRACT, 0); } - public TerminalNode OP_SHL() { return getToken(AsZ80Parser.OP_SHL, 0); } - public TerminalNode OP_SHR() { return getToken(AsZ80Parser.OP_SHR, 0); } - public TerminalNode OP_SHR_2() { return getToken(AsZ80Parser.OP_SHR_2, 0); } - public TerminalNode OP_SHL_2() { return getToken(AsZ80Parser.OP_SHL_2, 0); } - public TerminalNode OP_GT() { return getToken(AsZ80Parser.OP_GT, 0); } - public TerminalNode OP_GTE() { return getToken(AsZ80Parser.OP_GTE, 0); } - public TerminalNode OP_LT() { return getToken(AsZ80Parser.OP_LT, 0); } - public TerminalNode OP_LTE() { return getToken(AsZ80Parser.OP_LTE, 0); } - public TerminalNode OP_EQUAL() { return getToken(AsZ80Parser.OP_EQUAL, 0); } - public TerminalNode OP_AND() { return getToken(AsZ80Parser.OP_AND, 0); } - public TerminalNode OP_AND_2() { return getToken(AsZ80Parser.OP_AND_2, 0); } - public TerminalNode OP_XOR() { return getToken(AsZ80Parser.OP_XOR, 0); } - public TerminalNode OP_XOR_2() { return getToken(AsZ80Parser.OP_XOR_2, 0); } - public TerminalNode OP_OR() { return getToken(AsZ80Parser.OP_OR, 0); } - public TerminalNode OP_OR_2() { return getToken(AsZ80Parser.OP_OR_2, 0); } - public ExprInfixContext(RExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprInfix(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprInfix(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprInfix(this); - else return visitor.visitChildren(this); - } - } - public static class ExprCurrentAddressContext extends RExpressionContext { - public TerminalNode PREP_ADDR() { return getToken(AsZ80Parser.PREP_ADDR, 0); } - public ExprCurrentAddressContext(RExpressionContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).enterExprCurrentAddress(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof AsZ80ParserListener ) ((AsZ80ParserListener)listener).exitExprCurrentAddress(this); - } - @Override - public T accept(ParseTreeVisitor visitor) { - if ( visitor instanceof AsZ80ParserVisitor ) return ((AsZ80ParserVisitor)visitor).visitExprCurrentAddress(this); - else return visitor.visitChildren(this); - } - } - - public final RExpressionContext rExpression() throws RecognitionException { - return rExpression(0); - } - - private RExpressionContext rExpression(int _p) throws RecognitionException { - ParserRuleContext _parentctx = _ctx; - int _parentState = getState(); - RExpressionContext _localctx = new RExpressionContext(_ctx, _parentState); - RExpressionContext _prevctx = _localctx; - int _startState = 26; - enterRecursionRule(_localctx, 26, RULE_rExpression, _p); - int _la; - try { - int _alt; - enterOuterAlt(_localctx, 1); - { - setState(411); - _errHandler.sync(this); - switch (_input.LA(1)) { - case OP_NOT: - case OP_ADD: - case OP_SUBTRACT: - case OP_NOT_2: - { - _localctx = new ExprUnaryContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - - setState(397); - ((ExprUnaryContext)_localctx).unaryop = _input.LT(1); - _la = _input.LA(1); - if ( !(((((_la - 118)) & ~0x3f) == 0 && ((1L << (_la - 118)) & ((1L << (OP_NOT - 118)) | (1L << (OP_ADD - 118)) | (1L << (OP_SUBTRACT - 118)) | (1L << (OP_NOT_2 - 118)))) != 0)) ) { - ((ExprUnaryContext)_localctx).unaryop = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(398); - ((ExprUnaryContext)_localctx).expr = rExpression(18); - } - break; - case SEP_LPAR: - { - _localctx = new ExprParensContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(399); - match(SEP_LPAR); - setState(400); - ((ExprParensContext)_localctx).expr = rExpression(0); - setState(401); - match(SEP_RPAR); - } - break; - case LIT_NUMBER: - { - _localctx = new ExprDecContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(403); - ((ExprDecContext)_localctx).num = match(LIT_NUMBER); - } - break; - case LIT_HEXNUMBER_1: - { - _localctx = new ExprHex1Context(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(404); - ((ExprHex1Context)_localctx).num = match(LIT_HEXNUMBER_1); - } - break; - case LIT_HEXNUMBER_2: - { - _localctx = new ExprHex2Context(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(405); - ((ExprHex2Context)_localctx).num = match(LIT_HEXNUMBER_2); - } - break; - case LIT_OCTNUMBER: - { - _localctx = new ExprOctContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(406); - ((ExprOctContext)_localctx).num = match(LIT_OCTNUMBER); - } - break; - case LIT_BINNUMBER: - { - _localctx = new ExprBinContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(407); - ((ExprBinContext)_localctx).num = match(LIT_BINNUMBER); - } - break; - case PREP_ADDR: - { - _localctx = new ExprCurrentAddressContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(408); - match(PREP_ADDR); - } - break; - case ID_IDENTIFIER: - { - _localctx = new ExprIdContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(409); - ((ExprIdContext)_localctx).id = match(ID_IDENTIFIER); - } - break; - case LIT_STRING_1: - case LIT_STRING_2: - { - _localctx = new ExprStringContext(_localctx); - _ctx = _localctx; - _prevctx = _localctx; - setState(410); - ((ExprStringContext)_localctx).str = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==LIT_STRING_1 || _la==LIT_STRING_2) ) { - ((ExprStringContext)_localctx).str = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - break; - default: - throw new NoViableAltException(this); - } - _ctx.stop = _input.LT(-1); - setState(439); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,30,_ctx); - while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { - if ( _alt==1 ) { - if ( _parseListeners!=null ) triggerExitRuleEvent(); - _prevctx = _localctx; - { - setState(437); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,29,_ctx) ) { - case 1: - { - _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); - ((ExprInfixContext)_localctx).expr1 = _prevctx; - pushNewRecursionContext(_localctx, _startState, RULE_rExpression); - setState(413); - if (!(precpred(_ctx, 17))) throw new FailedPredicateException(this, "precpred(_ctx, 17)"); - setState(414); - ((ExprInfixContext)_localctx).op = _input.LT(1); - _la = _input.LA(1); - if ( !(((((_la - 115)) & ~0x3f) == 0 && ((1L << (_la - 115)) & ((1L << (OP_MOD - 115)) | (1L << (OP_MULTIPLY - 115)) | (1L << (OP_DIVIDE - 115)) | (1L << (OP_MOD_2 - 115)))) != 0)) ) { - ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(415); - ((ExprInfixContext)_localctx).expr2 = rExpression(18); - } - break; - case 2: - { - _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); - ((ExprInfixContext)_localctx).expr1 = _prevctx; - pushNewRecursionContext(_localctx, _startState, RULE_rExpression); - setState(416); - if (!(precpred(_ctx, 16))) throw new FailedPredicateException(this, "precpred(_ctx, 16)"); - setState(417); - ((ExprInfixContext)_localctx).op = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==OP_ADD || _la==OP_SUBTRACT) ) { - ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(418); - ((ExprInfixContext)_localctx).expr2 = rExpression(17); - } - break; - case 3: - { - _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); - ((ExprInfixContext)_localctx).expr1 = _prevctx; - pushNewRecursionContext(_localctx, _startState, RULE_rExpression); - setState(419); - if (!(precpred(_ctx, 15))) throw new FailedPredicateException(this, "precpred(_ctx, 15)"); - setState(420); - ((ExprInfixContext)_localctx).op = _input.LT(1); - _la = _input.LA(1); - if ( !(((((_la - 116)) & ~0x3f) == 0 && ((1L << (_la - 116)) & ((1L << (OP_SHR - 116)) | (1L << (OP_SHL - 116)) | (1L << (OP_SHR_2 - 116)) | (1L << (OP_SHL_2 - 116)))) != 0)) ) { - ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(421); - ((ExprInfixContext)_localctx).expr2 = rExpression(16); - } - break; - case 4: - { - _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); - ((ExprInfixContext)_localctx).expr1 = _prevctx; - pushNewRecursionContext(_localctx, _startState, RULE_rExpression); - setState(422); - if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)"); - setState(423); - ((ExprInfixContext)_localctx).op = _input.LT(1); - _la = _input.LA(1); - if ( !(((((_la - 140)) & ~0x3f) == 0 && ((1L << (_la - 140)) & ((1L << (OP_GT - 140)) | (1L << (OP_GTE - 140)) | (1L << (OP_LT - 140)) | (1L << (OP_LTE - 140)))) != 0)) ) { - ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(424); - ((ExprInfixContext)_localctx).expr2 = rExpression(14); - } - break; - case 5: - { - _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); - ((ExprInfixContext)_localctx).expr1 = _prevctx; - pushNewRecursionContext(_localctx, _startState, RULE_rExpression); - setState(425); - if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); - setState(426); - ((ExprInfixContext)_localctx).op = match(OP_EQUAL); - setState(427); - ((ExprInfixContext)_localctx).expr2 = rExpression(13); - } - break; - case 6: - { - _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); - ((ExprInfixContext)_localctx).expr1 = _prevctx; - pushNewRecursionContext(_localctx, _startState, RULE_rExpression); - setState(428); - if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); - setState(429); - ((ExprInfixContext)_localctx).op = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==OP_AND || _la==OP_AND_2) ) { - ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(430); - ((ExprInfixContext)_localctx).expr2 = rExpression(13); - } - break; - case 7: - { - _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); - ((ExprInfixContext)_localctx).expr1 = _prevctx; - pushNewRecursionContext(_localctx, _startState, RULE_rExpression); - setState(431); - if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); - setState(432); - ((ExprInfixContext)_localctx).op = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==OP_XOR || _la==OP_XOR_2) ) { - ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(433); - ((ExprInfixContext)_localctx).expr2 = rExpression(12); - } - break; - case 8: - { - _localctx = new ExprInfixContext(new RExpressionContext(_parentctx, _parentState)); - ((ExprInfixContext)_localctx).expr1 = _prevctx; - pushNewRecursionContext(_localctx, _startState, RULE_rExpression); - setState(434); - if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); - setState(435); - ((ExprInfixContext)_localctx).op = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==OP_OR || _la==OP_OR_2) ) { - ((ExprInfixContext)_localctx).op = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(436); - ((ExprInfixContext)_localctx).expr2 = rExpression(11); - } - break; - } - } - } - setState(441); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,30,_ctx); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - unrollRecursionContexts(_parentctx); - } - return _localctx; - } - - public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { - switch (ruleIndex) { - case 13: - return rExpression_sempred((RExpressionContext)_localctx, predIndex); - } - return true; - } - private boolean rExpression_sempred(RExpressionContext _localctx, int predIndex) { - switch (predIndex) { - case 0: - return precpred(_ctx, 17); - case 1: - return precpred(_ctx, 16); - case 2: - return precpred(_ctx, 15); - case 3: - return precpred(_ctx, 14); - case 4: - return precpred(_ctx, 13); - case 5: - return precpred(_ctx, 12); - case 6: - return precpred(_ctx, 11); - case 7: - return precpred(_ctx, 10); - } - return true; - } - - public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\u009a\u01bd\4\2\t"+ - "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ - "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\3\2\7\2 \n\2\f\2\16\2#\13\2"+ - "\3\2\5\2&\n\2\3\2\6\2)\n\2\r\2\16\2*\3\2\7\2.\n\2\f\2\16\2\61\13\2\3\2"+ - "\7\2\64\n\2\f\2\16\2\67\13\2\3\2\3\2\3\3\5\3<\n\3\3\3\7\3?\n\3\f\3\16"+ - "\3B\13\3\3\3\3\3\5\3F\n\3\3\4\3\4\3\4\5\4K\n\4\3\5\3\5\3\5\3\5\3\5\3\5"+ - "\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5Z\n\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5"+ - "\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3"+ - "\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\5\5}\n\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3"+ - "\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5"+ - "\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3"+ - "\5\3\5\5\5\u00ab\n\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3"+ - "\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6"+ - "\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3"+ - "\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6"+ - "\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3"+ - "\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6\u0108\n\6\3\6\3\6\3\6\3\6\3\6\3"+ - "\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\5\6\u011b\n\6\3\7\3\7\3"+ - "\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\5\7\u0127\n\7\3\b\3\b\3\t\3\t\3\t\3\t\3"+ - "\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\7\t\u0139\n\t\f\t\16\t\u013c\13"+ - "\t\3\t\7\t\u013f\n\t\f\t\16\t\u0142\13\t\3\t\3\t\3\t\3\t\3\t\5\t\u0149"+ - "\n\t\3\t\3\t\3\t\3\t\7\t\u014f\n\t\f\t\16\t\u0152\13\t\3\t\7\t\u0155\n"+ - "\t\f\t\16\t\u0158\13\t\3\t\3\t\3\t\5\t\u015d\n\t\3\t\3\t\5\t\u0161\n\t"+ - "\3\n\3\n\3\n\7\n\u0166\n\n\f\n\16\n\u0169\13\n\3\13\3\13\3\13\7\13\u016e"+ - "\n\13\f\13\16\13\u0171\13\13\3\f\3\f\3\f\3\f\7\f\u0177\n\f\f\f\16\f\u017a"+ - "\13\f\3\f\3\f\3\f\3\f\7\f\u0180\n\f\f\f\16\f\u0183\13\f\3\f\3\f\5\f\u0187"+ - "\n\f\3\r\3\r\5\r\u018b\n\r\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17"+ - "\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\5\17\u019e\n\17\3\17\3\17\3\17"+ - "\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17"+ - "\3\17\3\17\3\17\3\17\3\17\3\17\3\17\7\17\u01b8\n\17\f\17\16\17\u01bb\13"+ - "\17\3\17\2\3\34\20\2\4\6\b\n\f\16\20\22\24\26\30\32\34\2\20\3\2mp\3\2"+ - "IL\3\2mn\4\2moqq\3\2IP\3\2\u0081\u0082\5\2xx\u0089\u008a\u0095\u0095\5"+ - "\2uu\u008b\u008c\u0092\u0092\3\2\u0089\u008a\4\2vw\u0093\u0094\3\2\u008e"+ - "\u0091\4\2yy\u0096\u0096\4\2{{\u0098\u0098\4\2zz\u0097\u0097\2\u0222\2"+ - "!\3\2\2\2\4E\3\2\2\2\6J\3\2\2\2\b\u00aa\3\2\2\2\n\u011a\3\2\2\2\f\u0126"+ - "\3\2\2\2\16\u0128\3\2\2\2\20\u0160\3\2\2\2\22\u0162\3\2\2\2\24\u016a\3"+ - "\2\2\2\26\u0186\3\2\2\2\30\u018a\3\2\2\2\32\u018c\3\2\2\2\34\u019d\3\2"+ - "\2\2\36 \7\u009a\2\2\37\36\3\2\2\2 #\3\2\2\2!\37\3\2\2\2!\"\3\2\2\2\""+ - "%\3\2\2\2#!\3\2\2\2$&\5\4\3\2%$\3\2\2\2%&\3\2\2\2&/\3\2\2\2\')\7\u009a"+ - "\2\2(\'\3\2\2\2)*\3\2\2\2*(\3\2\2\2*+\3\2\2\2+,\3\2\2\2,.\5\4\3\2-(\3"+ - "\2\2\2.\61\3\2\2\2/-\3\2\2\2/\60\3\2\2\2\60\65\3\2\2\2\61/\3\2\2\2\62"+ - "\64\7\u009a\2\2\63\62\3\2\2\2\64\67\3\2\2\2\65\63\3\2\2\2\65\66\3\2\2"+ - "\2\668\3\2\2\2\67\65\3\2\2\289\7\2\2\39\3\3\2\2\2:<\7\u0084\2\2;:\3\2"+ - "\2\2;<\3\2\2\2<@\3\2\2\2=?\7\u009a\2\2>=\3\2\2\2?B\3\2\2\2@>\3\2\2\2@"+ - "A\3\2\2\2AC\3\2\2\2B@\3\2\2\2CF\5\6\4\2DF\7\u0084\2\2E;\3\2\2\2ED\3\2"+ - "\2\2F\5\3\2\2\2GK\5\b\5\2HK\5\20\t\2IK\5\26\f\2JG\3\2\2\2JH\3\2\2\2JI"+ - "\3\2\2\2K\7\3\2\2\2L\u00ab\5\n\6\2MN\7\"\2\2NO\t\2\2\2OP\7\u0088\2\2P"+ - "\u00ab\5\34\17\2QR\7\"\2\2RS\5\f\7\2ST\7\u0088\2\2TU\5\34\17\2U\u00ab"+ - "\3\2\2\2VY\7!\2\2WX\t\3\2\2XZ\7\u0088\2\2YW\3\2\2\2YZ\3\2\2\2Z[\3\2\2"+ - "\2[\u00ab\5\34\17\2\\]\7\"\2\2]^\7\u0086\2\2^_\5\34\17\2_`\7\u0087\2\2"+ - "`a\7\u0088\2\2ab\7o\2\2b\u00ab\3\2\2\2cd\7\"\2\2de\7o\2\2ef\7\u0088\2"+ - "\2fg\7\u0086\2\2gh\5\34\17\2hi\7\u0087\2\2i\u00ab\3\2\2\2jk\7\"\2\2kl"+ - "\7\u0086\2\2lm\5\34\17\2mn\7\u0087\2\2no\7\u0088\2\2op\7`\2\2p\u00ab\3"+ - "\2\2\2qr\7\"\2\2rs\7`\2\2st\7\u0088\2\2tu\7\u0086\2\2uv\5\34\17\2vw\7"+ - "\u0087\2\2w\u00ab\3\2\2\2x|\7 \2\2yz\5\16\b\2z{\7\u0088\2\2{}\3\2\2\2"+ - "|y\3\2\2\2|}\3\2\2\2}~\3\2\2\2~\u00ab\5\34\17\2\177\u0080\7\t\2\2\u0080"+ - "\u00ab\5\34\17\2\u0081\u0082\7\t\2\2\u0082\u0083\5\16\b\2\u0083\u0084"+ - "\7\u0088\2\2\u0084\u0085\5\34\17\2\u0085\u00ab\3\2\2\2\u0086\u0087\7\6"+ - "\2\2\u0087\u0088\7`\2\2\u0088\u0089\7\u0088\2\2\u0089\u00ab\5\34\17\2"+ - "\u008a\u008b\7\5\2\2\u008b\u008c\7`\2\2\u008c\u008d\7\u0088\2\2\u008d"+ - "\u00ab\5\34\17\2\u008e\u008f\7,\2\2\u008f\u0090\7\u0086\2\2\u0090\u0091"+ - "\5\34\17\2\u0091\u0092\7\u0087\2\2\u0092\u0093\7\u0088\2\2\u0093\u0094"+ - "\7`\2\2\u0094\u00ab\3\2\2\2\u0095\u0096\7G\2\2\u0096\u00ab\5\34\17\2\u0097"+ - "\u0098\7\32\2\2\u0098\u0099\7`\2\2\u0099\u009a\7\u0088\2\2\u009a\u009b"+ - "\7\u0086\2\2\u009b\u009c\5\34\17\2\u009c\u009d\7\u0087\2\2\u009d\u00ab"+ - "\3\2\2\2\u009e\u009f\7@\2\2\u009f\u00a0\7`\2\2\u00a0\u00a1\7\u0088\2\2"+ - "\u00a1\u00ab\5\34\17\2\u00a2\u00a3\7\7\2\2\u00a3\u00ab\5\34\17\2\u00a4"+ - "\u00a5\7H\2\2\u00a5\u00ab\5\34\17\2\u00a6\u00a7\7)\2\2\u00a7\u00ab\5\34"+ - "\17\2\u00a8\u00a9\7\13\2\2\u00a9\u00ab\5\34\17\2\u00aaL\3\2\2\2\u00aa"+ - "M\3\2\2\2\u00aaQ\3\2\2\2\u00aaV\3\2\2\2\u00aa\\\3\2\2\2\u00aac\3\2\2\2"+ - "\u00aaj\3\2\2\2\u00aaq\3\2\2\2\u00aax\3\2\2\2\u00aa\177\3\2\2\2\u00aa"+ - "\u0081\3\2\2\2\u00aa\u0086\3\2\2\2\u00aa\u008a\3\2\2\2\u00aa\u008e\3\2"+ - "\2\2\u00aa\u0095\3\2\2\2\u00aa\u0097\3\2\2\2\u00aa\u009e\3\2\2\2\u00aa"+ - "\u00a2\3\2\2\2\u00aa\u00a4\3\2\2\2\u00aa\u00a6\3\2\2\2\u00aa\u00a8\3\2"+ - "\2\2\u00ab\t\3\2\2\2\u00ac\u011b\7(\2\2\u00ad\u00ae\7\"\2\2\u00ae\u00af"+ - "\7\u0086\2\2\u00af\u00b0\t\4\2\2\u00b0\u00b1\7\u0087\2\2\u00b1\u00b2\7"+ - "\u0088\2\2\u00b2\u011b\7`\2\2\u00b3\u00b4\7\"\2\2\u00b4\u00b5\7\u0086"+ - "\2\2\u00b5\u00b6\7o\2\2\u00b6\u00b7\7\u0087\2\2\u00b7\u00b8\7\u0088\2"+ - "\2\u00b8\u011b\5\f\7\2\u00b9\u00ba\7\33\2\2\u00ba\u011b\t\2\2\2\u00bb"+ - "\u00bc\7\33\2\2\u00bc\u011b\5\f\7\2\u00bd\u00be\7\22\2\2\u00be\u011b\5"+ - "\f\7\2\u00bf\u011b\78\2\2\u00c0\u00c1\7\26\2\2\u00c1\u00c2\7q\2\2\u00c2"+ - "\u00c3\7\u0088\2\2\u00c3\u011b\7r\2\2\u00c4\u00c5\7\26\2\2\u00c5\u00c6"+ - "\7n\2\2\u00c6\u00c7\7\u0088\2\2\u00c7\u011b\7o\2\2\u00c8\u00c9\7\26\2"+ - "\2\u00c9\u00ca\7\u0086\2\2\u00ca\u00cb\7p\2\2\u00cb\u00cc\7\u0087\2\2"+ - "\u00cc\u00cd\7\u0088\2\2\u00cd\u011b\7o\2\2\u00ce\u00cf\7\6\2\2\u00cf"+ - "\u00d0\7o\2\2\u00d0\u00d1\7\u0088\2\2\u00d1\u011b\t\2\2\2\u00d2\u00d3"+ - "\7\"\2\2\u00d3\u00d4\7`\2\2\u00d4\u00d5\7\u0088\2\2\u00d5\u00d6\7\u0086"+ - "\2\2\u00d6\u00d7\t\4\2\2\u00d7\u011b\7\u0087\2\2\u00d8\u00d9\7\22\2\2"+ - "\u00d9\u011b\t\2\2\2\u00da\u011b\7=\2\2\u00db\u011b\7\66\2\2\u00dc\u011b"+ - "\7;\2\2\u00dd\u011b\7\21\2\2\u00de\u011b\7\20\2\2\u00df\u00e0\7\33\2\2"+ - "\u00e0\u00e1\7\u0086\2\2\u00e1\u00e2\7o\2\2\u00e2\u011b\7\u0087\2\2\u00e3"+ - "\u00e4\7\22\2\2\u00e4\u00e5\7\u0086\2\2\u00e5\u00e6\7o\2\2\u00e6\u011b"+ - "\7\u0087\2\2\u00e7\u011b\7A\2\2\u00e8\u011b\7\n\2\2\u00e9\u00ea\7\"\2"+ - "\2\u00ea\u00eb\5\f\7\2\u00eb\u00ec\7\u0088\2\2\u00ec\u00ed\5\f\7\2\u00ed"+ - "\u011b\3\2\2\2\u00ee\u011b\7\30\2\2\u00ef\u00f0\7\6\2\2\u00f0\u00f1\7"+ - "`\2\2\u00f1\u00f2\7\u0088\2\2\u00f2\u011b\5\f\7\2\u00f3\u00f4\7\5\2\2"+ - "\u00f4\u00f5\7`\2\2\u00f5\u00f6\7\u0088\2\2\u00f6\u011b\5\f\7\2\u00f7"+ - "\u00f8\7G\2\2\u00f8\u011b\5\f\7\2\u00f9\u00fa\7@\2\2\u00fa\u00fb\7`\2"+ - "\2\u00fb\u00fc\7\u0088\2\2\u00fc\u011b\5\f\7\2\u00fd\u00fe\7\7\2\2\u00fe"+ - "\u011b\5\f\7\2\u00ff\u0100\7H\2\2\u0100\u011b\5\f\7\2\u0101\u0102\7)\2"+ - "\2\u0102\u011b\5\f\7\2\u0103\u0104\7\13\2\2\u0104\u011b\5\f\7\2\u0105"+ - "\u0107\7\62\2\2\u0106\u0108\5\16\b\2\u0107\u0106\3\2\2\2\u0107\u0108\3"+ - "\2\2\2\u0108\u011b\3\2\2\2\u0109\u010a\7/\2\2\u010a\u011b\t\5\2\2\u010b"+ - "\u010c\7\60\2\2\u010c\u011b\t\5\2\2\u010d\u010e\7?\2\2\u010e\u011b\5\34"+ - "\17\2\u010f\u011b\7\27\2\2\u0110\u0111\7 \2\2\u0111\u0112\7\u0086\2\2"+ - "\u0112\u0113\7o\2\2\u0113\u011b\7\u0087\2\2\u0114\u011b\7\23\2\2\u0115"+ - "\u0116\7\"\2\2\u0116\u0117\7p\2\2\u0117\u0118\7\u0088\2\2\u0118\u011b"+ - "\7o\2\2\u0119\u011b\7\25\2\2\u011a\u00ac\3\2\2\2\u011a\u00ad\3\2\2\2\u011a"+ - "\u00b3\3\2\2\2\u011a\u00b9\3\2\2\2\u011a\u00bb\3\2\2\2\u011a\u00bd\3\2"+ - "\2\2\u011a\u00bf\3\2\2\2\u011a\u00c0\3\2\2\2\u011a\u00c4\3\2\2\2\u011a"+ - "\u00c8\3\2\2\2\u011a\u00ce\3\2\2\2\u011a\u00d2\3\2\2\2\u011a\u00d8\3\2"+ - "\2\2\u011a\u00da\3\2\2\2\u011a\u00db\3\2\2\2\u011a\u00dc\3\2\2\2\u011a"+ - "\u00dd\3\2\2\2\u011a\u00de\3\2\2\2\u011a\u00df\3\2\2\2\u011a\u00e3\3\2"+ - "\2\2\u011a\u00e7\3\2\2\2\u011a\u00e8\3\2\2\2\u011a\u00e9\3\2\2\2\u011a"+ - "\u00ee\3\2\2\2\u011a\u00ef\3\2\2\2\u011a\u00f3\3\2\2\2\u011a\u00f7\3\2"+ - "\2\2\u011a\u00f9\3\2\2\2\u011a\u00fd\3\2\2\2\u011a\u00ff\3\2\2\2\u011a"+ - "\u0101\3\2\2\2\u011a\u0103\3\2\2\2\u011a\u0105\3\2\2\2\u011a\u0109\3\2"+ - "\2\2\u011a\u010b\3\2\2\2\u011a\u010d\3\2\2\2\u011a\u010f\3\2\2\2\u011a"+ - "\u0110\3\2\2\2\u011a\u0114\3\2\2\2\u011a\u0115\3\2\2\2\u011a\u0119\3\2"+ - "\2\2\u011b\13\3\2\2\2\u011c\u0127\7`\2\2\u011d\u0127\7a\2\2\u011e\u0127"+ - "\7b\2\2\u011f\u0127\7c\2\2\u0120\u0127\7d\2\2\u0121\u0127\7e\2\2\u0122"+ - "\u0127\7f\2\2\u0123\u0124\7\u0086\2\2\u0124\u0125\7o\2\2\u0125\u0127\7"+ - "\u0087\2\2\u0126\u011c\3\2\2\2\u0126\u011d\3\2\2\2\u0126\u011e\3\2\2\2"+ - "\u0126\u011f\3\2\2\2\u0126\u0120\3\2\2\2\u0126\u0121\3\2\2\2\u0126\u0122"+ - "\3\2\2\2\u0126\u0123\3\2\2\2\u0127\r\3\2\2\2\u0128\u0129\t\6\2\2\u0129"+ - "\17\3\2\2\2\u012a\u012b\7S\2\2\u012b\u0161\5\34\17\2\u012c\u012d\7\u0083"+ - "\2\2\u012d\u012e\7T\2\2\u012e\u0161\5\34\17\2\u012f\u0130\7\u0083\2\2"+ - "\u0130\u0131\7U\2\2\u0131\u0161\5\34\17\2\u0132\u0133\7W\2\2\u0133\u0134"+ - "\5\34\17\2\u0134\u013a\7\u009a\2\2\u0135\u0136\5\4\3\2\u0136\u0137\7\u009a"+ - "\2\2\u0137\u0139\3\2\2\2\u0138\u0135\3\2\2\2\u0139\u013c\3\2\2\2\u013a"+ - "\u0138\3\2\2\2\u013a\u013b\3\2\2\2\u013b\u0140\3\2\2\2\u013c\u013a\3\2"+ - "\2\2\u013d\u013f\7\u009a\2\2\u013e\u013d\3\2\2\2\u013f\u0142\3\2\2\2\u0140"+ - "\u013e\3\2\2\2\u0140\u0141\3\2\2\2\u0141\u0143\3\2\2\2\u0142\u0140\3\2"+ - "\2\2\u0143\u0144\7X\2\2\u0144\u0161\3\2\2\2\u0145\u0146\7\u0083\2\2\u0146"+ - "\u0148\7Z\2\2\u0147\u0149\5\22\n\2\u0148\u0147\3\2\2\2\u0148\u0149\3\2"+ - "\2\2\u0149\u014a\3\2\2\2\u014a\u0150\7\u009a\2\2\u014b\u014c\5\4\3\2\u014c"+ - "\u014d\7\u009a\2\2\u014d\u014f\3\2\2\2\u014e\u014b\3\2\2\2\u014f\u0152"+ - "\3\2\2\2\u0150\u014e\3\2\2\2\u0150\u0151\3\2\2\2\u0151\u0156\3\2\2\2\u0152"+ - "\u0150\3\2\2\2\u0153\u0155\7\u009a\2\2\u0154\u0153\3\2\2\2\u0155\u0158"+ - "\3\2\2\2\u0156\u0154\3\2\2\2\u0156\u0157\3\2\2\2\u0157\u0159\3\2\2\2\u0158"+ - "\u0156\3\2\2\2\u0159\u0161\7[\2\2\u015a\u015c\7\u0083\2\2\u015b\u015d"+ - "\5\24\13\2\u015c\u015b\3\2\2\2\u015c\u015d\3\2\2\2\u015d\u0161\3\2\2\2"+ - "\u015e\u015f\7Y\2\2\u015f\u0161\t\7\2\2\u0160\u012a\3\2\2\2\u0160\u012c"+ - "\3\2\2\2\u0160\u012f\3\2\2\2\u0160\u0132\3\2\2\2\u0160\u0145\3\2\2\2\u0160"+ - "\u015a\3\2\2\2\u0160\u015e\3\2\2\2\u0161\21\3\2\2\2\u0162\u0167\7\u0083"+ - "\2\2\u0163\u0164\7\u0088\2\2\u0164\u0166\7\u0083\2\2\u0165\u0163\3\2\2"+ - "\2\u0166\u0169\3\2\2\2\u0167\u0165\3\2\2\2\u0167\u0168\3\2\2\2\u0168\23"+ - "\3\2\2\2\u0169\u0167\3\2\2\2\u016a\u016f\5\34\17\2\u016b\u016c\7\u0088"+ - "\2\2\u016c\u016e\5\34\17\2\u016d\u016b\3\2\2\2\u016e\u0171\3\2\2\2\u016f"+ - "\u016d\3\2\2\2\u016f\u0170\3\2\2\2\u0170\25\3\2\2\2\u0171\u016f\3\2\2"+ - "\2\u0172\u0173\7\\\2\2\u0173\u0178\5\30\r\2\u0174\u0175\7\u0088\2\2\u0175"+ - "\u0177\5\30\r\2\u0176\u0174\3\2\2\2\u0177\u017a\3\2\2\2\u0178\u0176\3"+ - "\2\2\2\u0178\u0179\3\2\2\2\u0179\u0187\3\2\2\2\u017a\u0178\3\2\2\2\u017b"+ - "\u017c\7]\2\2\u017c\u0181\5\32\16\2\u017d\u017e\7\u0088\2\2\u017e\u0180"+ - "\5\32\16\2\u017f\u017d\3\2\2\2\u0180\u0183\3\2\2\2\u0181\u017f\3\2\2\2"+ - "\u0181\u0182\3\2\2\2\u0182\u0187\3\2\2\2\u0183\u0181\3\2\2\2\u0184\u0185"+ - "\7^\2\2\u0185\u0187\5\34\17\2\u0186\u0172\3\2\2\2\u0186\u017b\3\2\2\2"+ - "\u0186\u0184\3\2\2\2\u0187\27\3\2\2\2\u0188\u018b\5\34\17\2\u0189\u018b"+ - "\5\n\6\2\u018a\u0188\3\2\2\2\u018a\u0189\3\2\2\2\u018b\31\3\2\2\2\u018c"+ - "\u018d\5\34\17\2\u018d\33\3\2\2\2\u018e\u018f\b\17\1\2\u018f\u0190\t\b"+ - "\2\2\u0190\u019e\5\34\17\24\u0191\u0192\7\u0086\2\2\u0192\u0193\5\34\17"+ - "\2\u0193\u0194\7\u0087\2\2\u0194\u019e\3\2\2\2\u0195\u019e\7}\2\2\u0196"+ - "\u019e\7|\2\2\u0197\u019e\7~\2\2\u0198\u019e\7\177\2\2\u0199\u019e\7\u0080"+ - "\2\2\u019a\u019e\7_\2\2\u019b\u019e\7\u0083\2\2\u019c\u019e\t\7\2\2\u019d"+ - "\u018e\3\2\2\2\u019d\u0191\3\2\2\2\u019d\u0195\3\2\2\2\u019d\u0196\3\2"+ - "\2\2\u019d\u0197\3\2\2\2\u019d\u0198\3\2\2\2\u019d\u0199\3\2\2\2\u019d"+ - "\u019a\3\2\2\2\u019d\u019b\3\2\2\2\u019d\u019c\3\2\2\2\u019e\u01b9\3\2"+ - "\2\2\u019f\u01a0\f\23\2\2\u01a0\u01a1\t\t\2\2\u01a1\u01b8\5\34\17\24\u01a2"+ - "\u01a3\f\22\2\2\u01a3\u01a4\t\n\2\2\u01a4\u01b8\5\34\17\23\u01a5\u01a6"+ - "\f\21\2\2\u01a6\u01a7\t\13\2\2\u01a7\u01b8\5\34\17\22\u01a8\u01a9\f\20"+ - "\2\2\u01a9\u01aa\t\f\2\2\u01aa\u01b8\5\34\17\20\u01ab\u01ac\f\17\2\2\u01ac"+ - "\u01ad\7\u008d\2\2\u01ad\u01b8\5\34\17\17\u01ae\u01af\f\16\2\2\u01af\u01b0"+ - "\t\r\2\2\u01b0\u01b8\5\34\17\17\u01b1\u01b2\f\r\2\2\u01b2\u01b3\t\16\2"+ - "\2\u01b3\u01b8\5\34\17\16\u01b4\u01b5\f\f\2\2\u01b5\u01b6\t\17\2\2\u01b6"+ - "\u01b8\5\34\17\r\u01b7\u019f\3\2\2\2\u01b7\u01a2\3\2\2\2\u01b7\u01a5\3"+ - "\2\2\2\u01b7\u01a8\3\2\2\2\u01b7\u01ab\3\2\2\2\u01b7\u01ae\3\2\2\2\u01b7"+ - "\u01b1\3\2\2\2\u01b7\u01b4\3\2\2\2\u01b8\u01bb\3\2\2\2\u01b9\u01b7\3\2"+ - "\2\2\u01b9\u01ba\3\2\2\2\u01ba\35\3\2\2\2\u01bb\u01b9\3\2\2\2!!%*/\65"+ - ";@EJY|\u00aa\u0107\u011a\u0126\u013a\u0140\u0148\u0150\u0156\u015c\u0160"+ - "\u0167\u016f\u0178\u0181\u0186\u018a\u019d\u01b7\u01b9"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.tokens b/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.tokens deleted file mode 100644 index e398feb30..000000000 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80Parser.tokens +++ /dev/null @@ -1,172 +0,0 @@ -COMMENT=1 -COMMENT2=2 -OPCODE_ADC=3 -OPCODE_ADD=4 -OPCODE_AND=5 -OPCODE_BIT=6 -OPCODE_CALL=7 -OPCODE_CCF=8 -OPCODE_CP=9 -OPCODE_CPD=10 -OPCODE_CPDR=11 -OPCODE_CPI=12 -OPCODE_CPIR=13 -OPCODE_CPL=14 -OPCODE_DAA=15 -OPCODE_DEC=16 -OPCODE_DI=17 -OPCODE_DJNZ=18 -OPCODE_EI=19 -OPCODE_EX=20 -OPCODE_EXX=21 -OPCODE_HALT=22 -OPCODE_IM=23 -OPCODE_IN=24 -OPCODE_INC=25 -OPCODE_IND=26 -OPCODE_INDR=27 -OPCODE_INI=28 -OPCODE_INIR=29 -OPCODE_JP=30 -OPCODE_JR=31 -OPCODE_LD=32 -OPCODE_LDD=33 -OPCODE_LDDR=34 -OPCODE_LDI=35 -OPCODE_LDIR=36 -OPCODE_NEG=37 -OPCODE_NOP=38 -OPCODE_OR=39 -OPCODE_OTDR=40 -OPCODE_OTIR=41 -OPCODE_OUT=42 -OPCODE_OUTD=43 -OPCODE_OUTI=44 -OPCODE_POP=45 -OPCODE_PUSH=46 -OPCODE_RES=47 -OPCODE_RET=48 -OPCODE_RETI=49 -OPCODE_RETN=50 -OPCODE_RL=51 -OPCODE_RLA=52 -OPCODE_RLC=53 -OPCODE_RLCA=54 -OPCODE_RLD=55 -OPCODE_RR=56 -OPCODE_RRA=57 -OPCODE_RRC=58 -OPCODE_RRCA=59 -OPCODE_RRD=60 -OPCODE_RST=61 -OPCODE_SBC=62 -OPCODE_SCF=63 -OPCODE_SET=64 -OPCODE_SLA=65 -OPCODE_SRA=66 -OPCODE_SLL=67 -OPCODE_SRL=68 -OPCODE_SUB=69 -OPCODE_XOR=70 -COND_C=71 -COND_NC=72 -COND_Z=73 -COND_NZ=74 -COND_M=75 -COND_P=76 -COND_PE=77 -COND_PO=78 -COND_WS=79 -COND_UNRECOGNIZED=80 -PREP_ORG=81 -PREP_EQU=82 -PREP_SET=83 -PREP_VAR=84 -PREP_IF=85 -PREP_ENDIF=86 -PREP_INCLUDE=87 -PREP_MACRO=88 -PREP_ENDM=89 -PREP_DB=90 -PREP_DW=91 -PREP_DS=92 -PREP_ADDR=93 -REG_A=94 -REG_B=95 -REG_C=96 -REG_D=97 -REG_E=98 -REG_H=99 -REG_L=100 -REG_IX=101 -REG_IXH=102 -REG_IXL=103 -REG_IY=104 -REG_IYH=105 -REG_IYL=106 -REG_BC=107 -REG_DE=108 -REG_HL=109 -REG_SP=110 -REG_AF=111 -REG_AFF=112 -REG_I=113 -REG_R=114 -OP_MOD=115 -OP_SHR=116 -OP_SHL=117 -OP_NOT=118 -OP_AND=119 -OP_OR=120 -OP_XOR=121 -LIT_HEXNUMBER_1=122 -LIT_NUMBER=123 -LIT_HEXNUMBER_2=124 -LIT_OCTNUMBER=125 -LIT_BINNUMBER=126 -LIT_STRING_1=127 -LIT_STRING_2=128 -ID_IDENTIFIER=129 -ID_LABEL=130 -ERROR=131 -SEP_LPAR=132 -SEP_RPAR=133 -SEP_COMMA=134 -OP_ADD=135 -OP_SUBTRACT=136 -OP_MULTIPLY=137 -OP_DIVIDE=138 -OP_EQUAL=139 -OP_GT=140 -OP_GTE=141 -OP_LT=142 -OP_LTE=143 -OP_MOD_2=144 -OP_SHR_2=145 -OP_SHL_2=146 -OP_NOT_2=147 -OP_AND_2=148 -OP_OR_2=149 -OP_XOR_2=150 -WS=151 -EOL=152 -'$'=93 -'('=132 -')'=133 -','=134 -'+'=135 -'-'=136 -'*'=137 -'/'=138 -'='=139 -'>'=140 -'>='=141 -'<'=142 -'<='=143 -'%'=144 -'>>'=145 -'<<'=146 -'!'=147 -'&'=148 -'|'=149 -'~'=150 diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseListener.java b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseListener.java deleted file mode 100644 index 368ba9d8d..000000000 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseListener.java +++ /dev/null @@ -1,578 +0,0 @@ -// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 by ANTLR 4.9.2 - -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.tree.ErrorNode; -import org.antlr.v4.runtime.tree.TerminalNode; - -/** - * This class provides an empty implementation of {@link AsZ80ParserListener}, - * which can be extended to create a listener which only needs to handle a subset - * of the available methods. - */ -public class AsZ80ParserBaseListener implements AsZ80ParserListener { - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterRStart(AsZ80Parser.RStartContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitRStart(AsZ80Parser.RStartContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterRLine(AsZ80Parser.RLineContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitRLine(AsZ80Parser.RLineContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterRStatement(AsZ80Parser.RStatementContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitRStatement(AsZ80Parser.RStatementContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstr8bit(AsZ80Parser.Instr8bitContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstr8bit(AsZ80Parser.Instr8bitContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrExprReg(AsZ80Parser.InstrExprRegContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrExprReg(AsZ80Parser.InstrExprRegContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrExpr(AsZ80Parser.InstrExprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrExpr(AsZ80Parser.InstrExprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrRegPair(AsZ80Parser.InstrRegPairContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrRegPair(AsZ80Parser.InstrRegPairContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrReg(AsZ80Parser.InstrRegContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrReg(AsZ80Parser.InstrRegContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrRegReg(AsZ80Parser.InstrRegRegContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrRegReg(AsZ80Parser.InstrRegRegContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstrCond(AsZ80Parser.InstrCondContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstrCond(AsZ80Parser.InstrCondContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterRRegister(AsZ80Parser.RRegisterContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitRRegister(AsZ80Parser.RRegisterContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterCCondition(AsZ80Parser.CConditionContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitCCondition(AsZ80Parser.CConditionContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterPseudoOrg(AsZ80Parser.PseudoOrgContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitPseudoOrg(AsZ80Parser.PseudoOrgContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterPseudoEqu(AsZ80Parser.PseudoEquContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitPseudoEqu(AsZ80Parser.PseudoEquContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterPseudoSet(AsZ80Parser.PseudoSetContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitPseudoSet(AsZ80Parser.PseudoSetContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterPseudoIf(AsZ80Parser.PseudoIfContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitPseudoIf(AsZ80Parser.PseudoIfContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterRMacroParameters(AsZ80Parser.RMacroParametersContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitRMacroParameters(AsZ80Parser.RMacroParametersContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterDataDB(AsZ80Parser.DataDBContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitDataDB(AsZ80Parser.DataDBContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterDataDW(AsZ80Parser.DataDWContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitDataDW(AsZ80Parser.DataDWContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterDataDS(AsZ80Parser.DataDSContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitDataDS(AsZ80Parser.DataDSContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterRDBdata(AsZ80Parser.RDBdataContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitRDBdata(AsZ80Parser.RDBdataContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterRDWdata(AsZ80Parser.RDWdataContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitRDWdata(AsZ80Parser.RDWdataContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterExprOct(AsZ80Parser.ExprOctContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitExprOct(AsZ80Parser.ExprOctContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterExprHex1(AsZ80Parser.ExprHex1Context ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitExprHex1(AsZ80Parser.ExprHex1Context ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterExprHex2(AsZ80Parser.ExprHex2Context ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitExprHex2(AsZ80Parser.ExprHex2Context ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterExprDec(AsZ80Parser.ExprDecContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitExprDec(AsZ80Parser.ExprDecContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterExprString(AsZ80Parser.ExprStringContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitExprString(AsZ80Parser.ExprStringContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterExprBin(AsZ80Parser.ExprBinContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitExprBin(AsZ80Parser.ExprBinContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterExprParens(AsZ80Parser.ExprParensContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitExprParens(AsZ80Parser.ExprParensContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterExprId(AsZ80Parser.ExprIdContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitExprId(AsZ80Parser.ExprIdContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterExprUnary(AsZ80Parser.ExprUnaryContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitExprUnary(AsZ80Parser.ExprUnaryContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterExprInfix(AsZ80Parser.ExprInfixContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitExprInfix(AsZ80Parser.ExprInfixContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx) { } - - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterEveryRule(ParserRuleContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitEveryRule(ParserRuleContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void visitTerminal(TerminalNode node) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void visitErrorNode(ErrorNode node) { } -} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseVisitor.java b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseVisitor.java deleted file mode 100644 index 3e16f7c77..000000000 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserBaseVisitor.java +++ /dev/null @@ -1,328 +0,0 @@ -// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 by ANTLR 4.9.2 -import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; - -/** - * This class provides an empty implementation of {@link AsZ80ParserVisitor}, - * which can be extended to create a visitor which only needs to handle a subset - * of the available methods. - * - * @param The return type of the visit operation. Use {@link Void} for - * operations with no return type. - */ -public class AsZ80ParserBaseVisitor extends AbstractParseTreeVisitor implements AsZ80ParserVisitor { - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitRStart(AsZ80Parser.RStartContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitRLine(AsZ80Parser.RLineContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitRStatement(AsZ80Parser.RStatementContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstr8bit(AsZ80Parser.Instr8bitContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrExprReg(AsZ80Parser.InstrExprRegContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrExpr(AsZ80Parser.InstrExprContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrRegPair(AsZ80Parser.InstrRegPairContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrReg(AsZ80Parser.InstrRegContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrRegReg(AsZ80Parser.InstrRegRegContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstrCond(AsZ80Parser.InstrCondContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitRRegister(AsZ80Parser.RRegisterContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitCCondition(AsZ80Parser.CConditionContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitPseudoOrg(AsZ80Parser.PseudoOrgContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitPseudoEqu(AsZ80Parser.PseudoEquContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitPseudoSet(AsZ80Parser.PseudoSetContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitPseudoIf(AsZ80Parser.PseudoIfContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitRMacroParameters(AsZ80Parser.RMacroParametersContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitDataDB(AsZ80Parser.DataDBContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitDataDW(AsZ80Parser.DataDWContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitDataDS(AsZ80Parser.DataDSContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitRDBdata(AsZ80Parser.RDBdataContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitRDWdata(AsZ80Parser.RDWdataContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitExprOct(AsZ80Parser.ExprOctContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitExprHex1(AsZ80Parser.ExprHex1Context ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitExprHex2(AsZ80Parser.ExprHex2Context ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitExprDec(AsZ80Parser.ExprDecContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitExprString(AsZ80Parser.ExprStringContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitExprBin(AsZ80Parser.ExprBinContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitExprParens(AsZ80Parser.ExprParensContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitExprId(AsZ80Parser.ExprIdContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitExprUnary(AsZ80Parser.ExprUnaryContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitExprInfix(AsZ80Parser.ExprInfixContext ctx) { return visitChildren(ctx); } - /** - * {@inheritDoc} - * - *

The default implementation returns the result of calling - * {@link #visitChildren} on {@code ctx}.

- */ - @Override public T visitExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx) { return visitChildren(ctx); } -} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserListener.java b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserListener.java deleted file mode 100644 index 149359e3b..000000000 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserListener.java +++ /dev/null @@ -1,531 +0,0 @@ -// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 by ANTLR 4.9.2 -import org.antlr.v4.runtime.tree.ParseTreeListener; - -/** - * This interface defines a complete listener for a parse tree produced by - * {@link AsZ80Parser}. - */ -public interface AsZ80ParserListener extends ParseTreeListener { - /** - * Enter a parse tree produced by {@link AsZ80Parser#rStart}. - * @param ctx the parse tree - */ - void enterRStart(AsZ80Parser.RStartContext ctx); - /** - * Exit a parse tree produced by {@link AsZ80Parser#rStart}. - * @param ctx the parse tree - */ - void exitRStart(AsZ80Parser.RStartContext ctx); - /** - * Enter a parse tree produced by {@link AsZ80Parser#rLine}. - * @param ctx the parse tree - */ - void enterRLine(AsZ80Parser.RLineContext ctx); - /** - * Exit a parse tree produced by {@link AsZ80Parser#rLine}. - * @param ctx the parse tree - */ - void exitRLine(AsZ80Parser.RLineContext ctx); - /** - * Enter a parse tree produced by {@link AsZ80Parser#rStatement}. - * @param ctx the parse tree - */ - void enterRStatement(AsZ80Parser.RStatementContext ctx); - /** - * Exit a parse tree produced by {@link AsZ80Parser#rStatement}. - * @param ctx the parse tree - */ - void exitRStatement(AsZ80Parser.RStatementContext ctx); - /** - * Enter a parse tree produced by the {@code instr8bit} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void enterInstr8bit(AsZ80Parser.Instr8bitContext ctx); - /** - * Exit a parse tree produced by the {@code instr8bit} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void exitInstr8bit(AsZ80Parser.Instr8bitContext ctx); - /** - * Enter a parse tree produced by the {@code instrRegPairExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void enterInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx); - /** - * Exit a parse tree produced by the {@code instrRegPairExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void exitInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx); - /** - * Enter a parse tree produced by the {@code instrRegExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void enterInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx); - /** - * Exit a parse tree produced by the {@code instrRegExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void exitInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx); - /** - * Enter a parse tree produced by the {@code instrCondExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void enterInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx); - /** - * Exit a parse tree produced by the {@code instrCondExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void exitInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx); - /** - * Enter a parse tree produced by the {@code instrExprRegPair} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void enterInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx); - /** - * Exit a parse tree produced by the {@code instrExprRegPair} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void exitInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx); - /** - * Enter a parse tree produced by the {@code instrExprReg} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void enterInstrExprReg(AsZ80Parser.InstrExprRegContext ctx); - /** - * Exit a parse tree produced by the {@code instrExprReg} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void exitInstrExprReg(AsZ80Parser.InstrExprRegContext ctx); - /** - * Enter a parse tree produced by the {@code instrExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void enterInstrExpr(AsZ80Parser.InstrExprContext ctx); - /** - * Exit a parse tree produced by the {@code instrExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - */ - void exitInstrExpr(AsZ80Parser.InstrExprContext ctx); - /** - * Enter a parse tree produced by the {@code instrNoArgs} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void enterInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx); - /** - * Exit a parse tree produced by the {@code instrNoArgs} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void exitInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx); - /** - * Enter a parse tree produced by the {@code instrRegPair} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void enterInstrRegPair(AsZ80Parser.InstrRegPairContext ctx); - /** - * Exit a parse tree produced by the {@code instrRegPair} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void exitInstrRegPair(AsZ80Parser.InstrRegPairContext ctx); - /** - * Enter a parse tree produced by the {@code instrRegPairReg} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void enterInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx); - /** - * Exit a parse tree produced by the {@code instrRegPairReg} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void exitInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx); - /** - * Enter a parse tree produced by the {@code instrReg} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void enterInstrReg(AsZ80Parser.InstrRegContext ctx); - /** - * Exit a parse tree produced by the {@code instrReg} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void exitInstrReg(AsZ80Parser.InstrRegContext ctx); - /** - * Enter a parse tree produced by the {@code instrRegPairRegPair} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void enterInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx); - /** - * Exit a parse tree produced by the {@code instrRegPairRegPair} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void exitInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx); - /** - * Enter a parse tree produced by the {@code instrRegReg} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void enterInstrRegReg(AsZ80Parser.InstrRegRegContext ctx); - /** - * Exit a parse tree produced by the {@code instrRegReg} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void exitInstrRegReg(AsZ80Parser.InstrRegRegContext ctx); - /** - * Enter a parse tree produced by the {@code instrCond} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void enterInstrCond(AsZ80Parser.InstrCondContext ctx); - /** - * Exit a parse tree produced by the {@code instrCond} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void exitInstrCond(AsZ80Parser.InstrCondContext ctx); - /** - * Enter a parse tree produced by the {@code instr8bitExpr} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void enterInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx); - /** - * Exit a parse tree produced by the {@code instr8bitExpr} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - */ - void exitInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx); - /** - * Enter a parse tree produced by {@link AsZ80Parser#rRegister}. - * @param ctx the parse tree - */ - void enterRRegister(AsZ80Parser.RRegisterContext ctx); - /** - * Exit a parse tree produced by {@link AsZ80Parser#rRegister}. - * @param ctx the parse tree - */ - void exitRRegister(AsZ80Parser.RRegisterContext ctx); - /** - * Enter a parse tree produced by {@link AsZ80Parser#cCondition}. - * @param ctx the parse tree - */ - void enterCCondition(AsZ80Parser.CConditionContext ctx); - /** - * Exit a parse tree produced by {@link AsZ80Parser#cCondition}. - * @param ctx the parse tree - */ - void exitCCondition(AsZ80Parser.CConditionContext ctx); - /** - * Enter a parse tree produced by the {@code pseudoOrg} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void enterPseudoOrg(AsZ80Parser.PseudoOrgContext ctx); - /** - * Exit a parse tree produced by the {@code pseudoOrg} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void exitPseudoOrg(AsZ80Parser.PseudoOrgContext ctx); - /** - * Enter a parse tree produced by the {@code pseudoEqu} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void enterPseudoEqu(AsZ80Parser.PseudoEquContext ctx); - /** - * Exit a parse tree produced by the {@code pseudoEqu} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void exitPseudoEqu(AsZ80Parser.PseudoEquContext ctx); - /** - * Enter a parse tree produced by the {@code pseudoSet} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void enterPseudoSet(AsZ80Parser.PseudoSetContext ctx); - /** - * Exit a parse tree produced by the {@code pseudoSet} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void exitPseudoSet(AsZ80Parser.PseudoSetContext ctx); - /** - * Enter a parse tree produced by the {@code pseudoIf} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void enterPseudoIf(AsZ80Parser.PseudoIfContext ctx); - /** - * Exit a parse tree produced by the {@code pseudoIf} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void exitPseudoIf(AsZ80Parser.PseudoIfContext ctx); - /** - * Enter a parse tree produced by the {@code pseudoMacroDef} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void enterPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx); - /** - * Exit a parse tree produced by the {@code pseudoMacroDef} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void exitPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx); - /** - * Enter a parse tree produced by the {@code pseudoMacroCall} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void enterPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx); - /** - * Exit a parse tree produced by the {@code pseudoMacroCall} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void exitPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx); - /** - * Enter a parse tree produced by the {@code pseudoInclude} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void enterPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx); - /** - * Exit a parse tree produced by the {@code pseudoInclude} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - */ - void exitPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx); - /** - * Enter a parse tree produced by {@link AsZ80Parser#rMacroParameters}. - * @param ctx the parse tree - */ - void enterRMacroParameters(AsZ80Parser.RMacroParametersContext ctx); - /** - * Exit a parse tree produced by {@link AsZ80Parser#rMacroParameters}. - * @param ctx the parse tree - */ - void exitRMacroParameters(AsZ80Parser.RMacroParametersContext ctx); - /** - * Enter a parse tree produced by {@link AsZ80Parser#rMacroArguments}. - * @param ctx the parse tree - */ - void enterRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx); - /** - * Exit a parse tree produced by {@link AsZ80Parser#rMacroArguments}. - * @param ctx the parse tree - */ - void exitRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx); - /** - * Enter a parse tree produced by the {@code dataDB} - * labeled alternative in {@link AsZ80Parser#rData}. - * @param ctx the parse tree - */ - void enterDataDB(AsZ80Parser.DataDBContext ctx); - /** - * Exit a parse tree produced by the {@code dataDB} - * labeled alternative in {@link AsZ80Parser#rData}. - * @param ctx the parse tree - */ - void exitDataDB(AsZ80Parser.DataDBContext ctx); - /** - * Enter a parse tree produced by the {@code dataDW} - * labeled alternative in {@link AsZ80Parser#rData}. - * @param ctx the parse tree - */ - void enterDataDW(AsZ80Parser.DataDWContext ctx); - /** - * Exit a parse tree produced by the {@code dataDW} - * labeled alternative in {@link AsZ80Parser#rData}. - * @param ctx the parse tree - */ - void exitDataDW(AsZ80Parser.DataDWContext ctx); - /** - * Enter a parse tree produced by the {@code dataDS} - * labeled alternative in {@link AsZ80Parser#rData}. - * @param ctx the parse tree - */ - void enterDataDS(AsZ80Parser.DataDSContext ctx); - /** - * Exit a parse tree produced by the {@code dataDS} - * labeled alternative in {@link AsZ80Parser#rData}. - * @param ctx the parse tree - */ - void exitDataDS(AsZ80Parser.DataDSContext ctx); - /** - * Enter a parse tree produced by {@link AsZ80Parser#rDBdata}. - * @param ctx the parse tree - */ - void enterRDBdata(AsZ80Parser.RDBdataContext ctx); - /** - * Exit a parse tree produced by {@link AsZ80Parser#rDBdata}. - * @param ctx the parse tree - */ - void exitRDBdata(AsZ80Parser.RDBdataContext ctx); - /** - * Enter a parse tree produced by {@link AsZ80Parser#rDWdata}. - * @param ctx the parse tree - */ - void enterRDWdata(AsZ80Parser.RDWdataContext ctx); - /** - * Exit a parse tree produced by {@link AsZ80Parser#rDWdata}. - * @param ctx the parse tree - */ - void exitRDWdata(AsZ80Parser.RDWdataContext ctx); - /** - * Enter a parse tree produced by the {@code exprOct} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void enterExprOct(AsZ80Parser.ExprOctContext ctx); - /** - * Exit a parse tree produced by the {@code exprOct} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void exitExprOct(AsZ80Parser.ExprOctContext ctx); - /** - * Enter a parse tree produced by the {@code exprHex1} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void enterExprHex1(AsZ80Parser.ExprHex1Context ctx); - /** - * Exit a parse tree produced by the {@code exprHex1} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void exitExprHex1(AsZ80Parser.ExprHex1Context ctx); - /** - * Enter a parse tree produced by the {@code exprHex2} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void enterExprHex2(AsZ80Parser.ExprHex2Context ctx); - /** - * Exit a parse tree produced by the {@code exprHex2} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void exitExprHex2(AsZ80Parser.ExprHex2Context ctx); - /** - * Enter a parse tree produced by the {@code exprDec} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void enterExprDec(AsZ80Parser.ExprDecContext ctx); - /** - * Exit a parse tree produced by the {@code exprDec} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void exitExprDec(AsZ80Parser.ExprDecContext ctx); - /** - * Enter a parse tree produced by the {@code exprString} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void enterExprString(AsZ80Parser.ExprStringContext ctx); - /** - * Exit a parse tree produced by the {@code exprString} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void exitExprString(AsZ80Parser.ExprStringContext ctx); - /** - * Enter a parse tree produced by the {@code exprBin} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void enterExprBin(AsZ80Parser.ExprBinContext ctx); - /** - * Exit a parse tree produced by the {@code exprBin} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void exitExprBin(AsZ80Parser.ExprBinContext ctx); - /** - * Enter a parse tree produced by the {@code exprParens} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void enterExprParens(AsZ80Parser.ExprParensContext ctx); - /** - * Exit a parse tree produced by the {@code exprParens} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void exitExprParens(AsZ80Parser.ExprParensContext ctx); - /** - * Enter a parse tree produced by the {@code exprId} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void enterExprId(AsZ80Parser.ExprIdContext ctx); - /** - * Exit a parse tree produced by the {@code exprId} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void exitExprId(AsZ80Parser.ExprIdContext ctx); - /** - * Enter a parse tree produced by the {@code exprUnary} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void enterExprUnary(AsZ80Parser.ExprUnaryContext ctx); - /** - * Exit a parse tree produced by the {@code exprUnary} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void exitExprUnary(AsZ80Parser.ExprUnaryContext ctx); - /** - * Enter a parse tree produced by the {@code exprInfix} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void enterExprInfix(AsZ80Parser.ExprInfixContext ctx); - /** - * Exit a parse tree produced by the {@code exprInfix} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void exitExprInfix(AsZ80Parser.ExprInfixContext ctx); - /** - * Enter a parse tree produced by the {@code exprCurrentAddress} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void enterExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx); - /** - * Exit a parse tree produced by the {@code exprCurrentAddress} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - */ - void exitExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx); -} \ No newline at end of file diff --git a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserVisitor.java b/plugins/compiler/as-z80/src/main/gen/AsZ80ParserVisitor.java deleted file mode 100644 index be8c7e54e..000000000 --- a/plugins/compiler/as-z80/src/main/gen/AsZ80ParserVisitor.java +++ /dev/null @@ -1,318 +0,0 @@ -// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 by ANTLR 4.9.2 -import org.antlr.v4.runtime.tree.ParseTreeVisitor; - -/** - * This interface defines a complete generic visitor for a parse tree produced - * by {@link AsZ80Parser}. - * - * @param The return type of the visit operation. Use {@link Void} for - * operations with no return type. - */ -public interface AsZ80ParserVisitor extends ParseTreeVisitor { - /** - * Visit a parse tree produced by {@link AsZ80Parser#rStart}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitRStart(AsZ80Parser.RStartContext ctx); - /** - * Visit a parse tree produced by {@link AsZ80Parser#rLine}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitRLine(AsZ80Parser.RLineContext ctx); - /** - * Visit a parse tree produced by {@link AsZ80Parser#rStatement}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitRStatement(AsZ80Parser.RStatementContext ctx); - /** - * Visit a parse tree produced by the {@code instr8bit} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstr8bit(AsZ80Parser.Instr8bitContext ctx); - /** - * Visit a parse tree produced by the {@code instrRegPairExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrRegPairExpr(AsZ80Parser.InstrRegPairExprContext ctx); - /** - * Visit a parse tree produced by the {@code instrRegExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrRegExpr(AsZ80Parser.InstrRegExprContext ctx); - /** - * Visit a parse tree produced by the {@code instrCondExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrCondExpr(AsZ80Parser.InstrCondExprContext ctx); - /** - * Visit a parse tree produced by the {@code instrExprRegPair} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrExprRegPair(AsZ80Parser.InstrExprRegPairContext ctx); - /** - * Visit a parse tree produced by the {@code instrExprReg} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrExprReg(AsZ80Parser.InstrExprRegContext ctx); - /** - * Visit a parse tree produced by the {@code instrExpr} - * labeled alternative in {@link AsZ80Parser#rInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrExpr(AsZ80Parser.InstrExprContext ctx); - /** - * Visit a parse tree produced by the {@code instrNoArgs} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrNoArgs(AsZ80Parser.InstrNoArgsContext ctx); - /** - * Visit a parse tree produced by the {@code instrRegPair} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrRegPair(AsZ80Parser.InstrRegPairContext ctx); - /** - * Visit a parse tree produced by the {@code instrRegPairReg} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrRegPairReg(AsZ80Parser.InstrRegPairRegContext ctx); - /** - * Visit a parse tree produced by the {@code instrReg} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrReg(AsZ80Parser.InstrRegContext ctx); - /** - * Visit a parse tree produced by the {@code instrRegPairRegPair} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrRegPairRegPair(AsZ80Parser.InstrRegPairRegPairContext ctx); - /** - * Visit a parse tree produced by the {@code instrRegReg} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrRegReg(AsZ80Parser.InstrRegRegContext ctx); - /** - * Visit a parse tree produced by the {@code instrCond} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstrCond(AsZ80Parser.InstrCondContext ctx); - /** - * Visit a parse tree produced by the {@code instr8bitExpr} - * labeled alternative in {@link AsZ80Parser#r8bitInstruction}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitInstr8bitExpr(AsZ80Parser.Instr8bitExprContext ctx); - /** - * Visit a parse tree produced by {@link AsZ80Parser#rRegister}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitRRegister(AsZ80Parser.RRegisterContext ctx); - /** - * Visit a parse tree produced by {@link AsZ80Parser#cCondition}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitCCondition(AsZ80Parser.CConditionContext ctx); - /** - * Visit a parse tree produced by the {@code pseudoOrg} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitPseudoOrg(AsZ80Parser.PseudoOrgContext ctx); - /** - * Visit a parse tree produced by the {@code pseudoEqu} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitPseudoEqu(AsZ80Parser.PseudoEquContext ctx); - /** - * Visit a parse tree produced by the {@code pseudoSet} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitPseudoSet(AsZ80Parser.PseudoSetContext ctx); - /** - * Visit a parse tree produced by the {@code pseudoIf} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitPseudoIf(AsZ80Parser.PseudoIfContext ctx); - /** - * Visit a parse tree produced by the {@code pseudoMacroDef} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitPseudoMacroDef(AsZ80Parser.PseudoMacroDefContext ctx); - /** - * Visit a parse tree produced by the {@code pseudoMacroCall} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitPseudoMacroCall(AsZ80Parser.PseudoMacroCallContext ctx); - /** - * Visit a parse tree produced by the {@code pseudoInclude} - * labeled alternative in {@link AsZ80Parser#rPseudoCode}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitPseudoInclude(AsZ80Parser.PseudoIncludeContext ctx); - /** - * Visit a parse tree produced by {@link AsZ80Parser#rMacroParameters}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitRMacroParameters(AsZ80Parser.RMacroParametersContext ctx); - /** - * Visit a parse tree produced by {@link AsZ80Parser#rMacroArguments}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitRMacroArguments(AsZ80Parser.RMacroArgumentsContext ctx); - /** - * Visit a parse tree produced by the {@code dataDB} - * labeled alternative in {@link AsZ80Parser#rData}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitDataDB(AsZ80Parser.DataDBContext ctx); - /** - * Visit a parse tree produced by the {@code dataDW} - * labeled alternative in {@link AsZ80Parser#rData}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitDataDW(AsZ80Parser.DataDWContext ctx); - /** - * Visit a parse tree produced by the {@code dataDS} - * labeled alternative in {@link AsZ80Parser#rData}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitDataDS(AsZ80Parser.DataDSContext ctx); - /** - * Visit a parse tree produced by {@link AsZ80Parser#rDBdata}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitRDBdata(AsZ80Parser.RDBdataContext ctx); - /** - * Visit a parse tree produced by {@link AsZ80Parser#rDWdata}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitRDWdata(AsZ80Parser.RDWdataContext ctx); - /** - * Visit a parse tree produced by the {@code exprOct} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExprOct(AsZ80Parser.ExprOctContext ctx); - /** - * Visit a parse tree produced by the {@code exprHex1} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExprHex1(AsZ80Parser.ExprHex1Context ctx); - /** - * Visit a parse tree produced by the {@code exprHex2} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExprHex2(AsZ80Parser.ExprHex2Context ctx); - /** - * Visit a parse tree produced by the {@code exprDec} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExprDec(AsZ80Parser.ExprDecContext ctx); - /** - * Visit a parse tree produced by the {@code exprString} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExprString(AsZ80Parser.ExprStringContext ctx); - /** - * Visit a parse tree produced by the {@code exprBin} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExprBin(AsZ80Parser.ExprBinContext ctx); - /** - * Visit a parse tree produced by the {@code exprParens} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExprParens(AsZ80Parser.ExprParensContext ctx); - /** - * Visit a parse tree produced by the {@code exprId} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExprId(AsZ80Parser.ExprIdContext ctx); - /** - * Visit a parse tree produced by the {@code exprUnary} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExprUnary(AsZ80Parser.ExprUnaryContext ctx); - /** - * Visit a parse tree produced by the {@code exprInfix} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExprInfix(AsZ80Parser.ExprInfixContext ctx); - /** - * Visit a parse tree produced by the {@code exprCurrentAddress} - * labeled alternative in {@link AsZ80Parser#rExpression}. - * @param ctx the parse tree - * @return the visitor result - */ - T visitExprCurrentAddress(AsZ80Parser.ExprCurrentAddressContext ctx); -} \ No newline at end of file From b89daf433ff834b126017cef87ae28a8cec1039b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 14 Feb 2022 12:25:56 +0100 Subject: [PATCH 097/314] [#201] as-z80: wip --- .../as-z80/src/main/antlr/AsZ80Lexer.g4 | 9 +- .../as-z80/src/main/antlr/AsZ80Lexer.tokens | 192 +++--- .../as-z80/src/main/antlr/AsZ80Parser.g4 | 291 ++++++--- .../compiler/asZ80/CompilerTables.java | 29 +- .../compiler/asZ80/ast/instr/Instr.java | 87 +-- .../asZ80/ast/instr/InstrA_Ref_RP.java | 26 - .../compiler/asZ80/ast/instr/InstrC.java | 26 - .../compiler/asZ80/ast/instr/InstrCB.java | 71 +++ .../compiler/asZ80/ast/instr/InstrC_N.java | 29 - .../compiler/asZ80/ast/instr/InstrC_NN.java | 28 - .../compiler/asZ80/ast/instr/InstrED.java | 89 +++ .../compiler/asZ80/ast/instr/InstrN.java | 134 ---- .../compiler/asZ80/ast/instr/InstrNN.java | 25 - .../compiler/asZ80/ast/instr/InstrR.java | 95 --- .../compiler/asZ80/ast/instr/InstrRP.java | 83 --- .../compiler/asZ80/ast/instr/InstrRP_NN.java | 54 -- .../compiler/asZ80/ast/instr/InstrRP_RP.java | 30 - .../asZ80/ast/instr/InstrRP_Ref_NN.java | 27 - .../compiler/asZ80/ast/instr/InstrR_N.java | 54 -- .../compiler/asZ80/ast/instr/InstrR_R.java | 57 -- .../asZ80/ast/instr/InstrR_Ref_NN.java | 27 - .../asZ80/ast/instr/InstrRef_NN_R.java | 28 - .../compiler/asZ80/ast/instr/InstrRef_RP.java | 28 - .../asZ80/ast/instr/InstrRef_RP_RP.java | 28 - .../compiler/asZ80/ast/instr/InstrXD.java | 58 ++ .../compiler/asZ80/ast/instr/InstrXDCB.java | 77 +++ .../asZ80/visitors/CheckExprSizesVisitor.java | 3 - .../asZ80/visitors/CreateInstrVisitor.java | 570 ++++++++++++++++-- .../compiler/asZ80/visitors/NodeVisitor.java | 60 +- .../compiler/asZ80/parser/ParseDataTest.java | 2 +- .../compiler/asZ80/parser/ParseInstrTest.java | 2 +- .../asZ80/parser/ParsePseudoTest.java | 7 +- .../visitors/CheckExprSizesVisitorTest.java | 3 - .../visitors/EvaluateExprVisitorTest.java | 7 +- .../visitors/ExpandIncludesVisitorTest.java | 9 +- .../visitors/GenerateCodeVisitorTest.java | 50 +- .../SortMacroArgumentsVisitorTest.java | 1 - 37 files changed, 1234 insertions(+), 1162 deletions(-) delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrA_Ref_RP.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_N.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_NN.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrN.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNN.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_NN.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_RP.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_Ref_NN.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_N.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_R.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_Ref_NN.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_NN_R.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP_RP.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 index 0e7b791e6..e6b2d1f11 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 @@ -51,7 +51,7 @@ OPCODE_EI: E I; OPCODE_EX: E X; OPCODE_EXX: E X X; OPCODE_HALT: H A L T; -OPCODE_IM: I M; +OPCODE_IM: I M -> pushMode(IM_NUMBER); OPCODE_IN: I N; OPCODE_INC: I N C; OPCODE_IND: I N D; @@ -112,6 +112,13 @@ COND_PO: P O -> popMode; COND_WS: [ \t\f]+ -> skip; COND_UNRECOGNIZED: ({"cCnNzZmMpP".indexOf((char) _input.LA(1)) == -1}?) -> popMode; +mode IM_NUMBER; +IM_01: '0/1' -> popMode; +IM_0: '0' -> popMode; +IM_1: '1' -> popMode; +IM_2: '2' -> popMode; +IM_WS: [ \t\f]+ -> skip; +IM_UNRECOGNIZED: ({"012".indexOf((char) _input.LA(1)) == -1}?) -> popMode; mode DEFAULT_MODE; diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens index a4d6ab04f..807c43e71 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens @@ -78,94 +78,104 @@ COND_PE=77 COND_PO=78 COND_WS=79 COND_UNRECOGNIZED=80 -PREP_ORG=81 -PREP_EQU=82 -PREP_SET=83 -PREP_IF=84 -PREP_ENDIF=85 -PREP_INCLUDE=86 -PREP_MACRO=87 -PREP_ENDM=88 -PREP_DB=89 -PREP_DW=90 -PREP_DS=91 -PREP_ADDR=92 -REG_A=93 -REG_B=94 -REG_C=95 -REG_D=96 -REG_E=97 -REG_H=98 -REG_L=99 -REG_IX=100 -REG_IXH=101 -REG_IXL=102 -REG_IY=103 -REG_IYH=104 -REG_IYL=105 -REG_BC=106 -REG_DE=107 -REG_HL=108 -REG_SP=109 -REG_AF=110 -REG_AFF=111 -REG_I=112 -REG_R=113 -OP_MOD=114 -OP_SHR=115 -OP_SHL=116 -OP_NOT=117 -OP_AND=118 -OP_OR=119 -OP_XOR=120 -LIT_HEXNUMBER_1=121 -LIT_NUMBER=122 -LIT_HEXNUMBER_2=123 -LIT_OCTNUMBER=124 -LIT_BINNUMBER=125 -LIT_STRING_1=126 -LIT_STRING_2=127 -ID_IDENTIFIER=128 -ID_LABEL=129 -ERROR=130 -SEP_LPAR=131 -SEP_RPAR=132 -SEP_COMMA=133 -OP_ADD=134 -OP_SUBTRACT=135 -OP_MULTIPLY=136 -OP_DIVIDE=137 -OP_EQUAL=138 -OP_GT=139 -OP_GTE=140 -OP_LT=141 -OP_LTE=142 -OP_MOD_2=143 -OP_SHR_2=144 -OP_SHL_2=145 -OP_NOT_2=146 -OP_AND_2=147 -OP_OR_2=148 -OP_XOR_2=149 -WS=150 -EOL=151 -'$'=92 -'('=131 -')'=132 -','=133 -'+'=134 -'-'=135 -'*'=136 -'/'=137 -'='=138 -'>'=139 -'>='=140 -'<'=141 -'<='=142 -'%'=143 -'>>'=144 -'<<'=145 -'~'=146 -'&'=147 -'|'=148 -'^'=149 +IM_01=81 +IM_0=82 +IM_1=83 +IM_2=84 +IM_WS=85 +IM_UNRECOGNIZED=86 +PREP_ORG=87 +PREP_EQU=88 +PREP_SET=89 +PREP_IF=90 +PREP_ENDIF=91 +PREP_INCLUDE=92 +PREP_MACRO=93 +PREP_ENDM=94 +PREP_DB=95 +PREP_DW=96 +PREP_DS=97 +PREP_ADDR=98 +REG_A=99 +REG_B=100 +REG_C=101 +REG_D=102 +REG_E=103 +REG_H=104 +REG_L=105 +REG_IX=106 +REG_IXH=107 +REG_IXL=108 +REG_IY=109 +REG_IYH=110 +REG_IYL=111 +REG_BC=112 +REG_DE=113 +REG_HL=114 +REG_SP=115 +REG_AF=116 +REG_AFF=117 +REG_I=118 +REG_R=119 +OP_MOD=120 +OP_SHR=121 +OP_SHL=122 +OP_NOT=123 +OP_AND=124 +OP_OR=125 +OP_XOR=126 +LIT_HEXNUMBER_1=127 +LIT_NUMBER=128 +LIT_HEXNUMBER_2=129 +LIT_OCTNUMBER=130 +LIT_BINNUMBER=131 +LIT_STRING_1=132 +LIT_STRING_2=133 +ID_IDENTIFIER=134 +ID_LABEL=135 +ERROR=136 +SEP_LPAR=137 +SEP_RPAR=138 +SEP_COMMA=139 +OP_ADD=140 +OP_SUBTRACT=141 +OP_MULTIPLY=142 +OP_DIVIDE=143 +OP_EQUAL=144 +OP_GT=145 +OP_GTE=146 +OP_LT=147 +OP_LTE=148 +OP_MOD_2=149 +OP_SHR_2=150 +OP_SHL_2=151 +OP_NOT_2=152 +OP_AND_2=153 +OP_OR_2=154 +OP_XOR_2=155 +WS=156 +EOL=157 +'0/1'=81 +'0'=82 +'1'=83 +'2'=84 +'$'=98 +'('=137 +')'=138 +','=139 +'+'=140 +'-'=141 +'*'=142 +'/'=143 +'='=144 +'>'=145 +'>='=146 +'<'=147 +'<='=148 +'%'=149 +'>>'=150 +'<<'=151 +'~'=152 +'&'=153 +'|'=154 +'^'=155 diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 index 0fbc0431a..863c6aed7 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 @@ -19,83 +19,196 @@ rStatement: ; rInstruction: - r8bitInstruction # instr8bit - | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_A # instrRef_NN_R + opcode=OPCODE_RLC d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + | opcode=OPCODE_RRC d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + | opcode=OPCODE_RL d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + | opcode=OPCODE_RR d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + | opcode=OPCODE_SLA d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + | opcode=OPCODE_SRA d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + | opcode=OPCODE_SLL d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + | opcode=OPCODE_SRL d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + | opcode=OPCODE_SRL d=rDisplacement # instrXDCB + | opcode=OPCODE_RLC d=rDisplacement # instrXDCB + | opcode=OPCODE_RRC d=rDisplacement # instrXDCB + | opcode=OPCODE_RL d=rDisplacement # instrXDCB + | opcode=OPCODE_RR d=rDisplacement # instrXDCB + | opcode=OPCODE_SLA d=rDisplacement # instrXDCB + | opcode=OPCODE_SRA d=rDisplacement # instrXDCB + | opcode=OPCODE_SLL d=rDisplacement # instrXDCB + | opcode=OPCODE_BIT n=rExpression SEP_COMMA d=rDisplacement # instrXDCB_N + | opcode=OPCODE_RES n=rExpression SEP_COMMA d=rDisplacement # instrXDCB_N + | opcode=OPCODE_SET n=rExpression SEP_COMMA d=rDisplacement # instrXDCB_N + | opcode=OPCODE_RES n=rExpression SEP_COMMA d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_N_R + | opcode=OPCODE_SET n=rExpression SEP_COMMA d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_N_R + + | opcode=OPCODE_IN r=rRegister2 SEP_COMMA SEP_LPAR REG_C SEP_RPAR # instrED_R2 + | opcode=OPCODE_OUT SEP_LPAR REG_C SEP_RPAR SEP_COMMA r=rRegister2 # instrED_R2 + | opcode=OPCODE_IN SEP_LPAR REG_C SEP_RPAR # instrED_C + | opcode=OPCODE_OUT SEP_LPAR REG_C SEP_RPAR SEP_COMMA n=LIT_NUMBER # instrED_C + | opcode=OPCODE_SBC REG_HL SEP_COMMA rp=rRegPair # instrED_RP + | opcode=OPCODE_ADC REG_HL SEP_COMMA rp=rRegPair # instrED_RP + | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA rp=rRegPair # instrED_NN_RP + | opcode=OPCODE_LD rp=rRegPair SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrED_RP_NN + | opcode=OPCODE_IM im=(IM_0|IM_1|IM_2|IM_01) # instrED_IM + | opcode=OPCODE_LD dst=REG_I src=REG_A # instrED_RIA_RIA + | opcode=OPCODE_LD dst=REG_A src=REG_I # instrED_RIA_RIA + | opcode=OPCODE_LD dst=REG_R src=REG_A # instrED_RIA_RIA + | opcode=OPCODE_LD dst=REG_A src=REG_R # instrED_RIA_RIA + | opcode=OPCODE_NEG # instrED + | opcode=OPCODE_RETN # instrED + | opcode=OPCODE_RETI # instrED + | opcode=OPCODE_LDI # instrED + | opcode=OPCODE_LDIR # instrED + | opcode=OPCODE_CPI # instrED + | opcode=OPCODE_CPIR # instrED + | opcode=OPCODE_INI # instrED + | opcode=OPCODE_INIR # instrED + | opcode=OPCODE_OUTI # instrED + | opcode=OPCODE_OTIR # instrED + | opcode=OPCODE_LDD # instrED + | opcode=OPCODE_LDDR # instrED + | opcode=OPCODE_CPD # instrED + | opcode=OPCODE_CPDR # instrED + | opcode=OPCODE_IND # instrED + | opcode=OPCODE_INDR # instrED + | opcode=OPCODE_OUTD # instrED + | opcode=OPCODE_OTDR # instrED + | opcode=OPCODE_RLD # instrED + | opcode=OPCODE_RRD # instrED + + | opcode=OPCODE_RLC r=rRegister # instrCB + | opcode=OPCODE_RRC r=rRegister # instrCB + | opcode=OPCODE_RL r=rRegister # instrCB + | opcode=OPCODE_RR r=rRegister # instrCB + | opcode=OPCODE_SLA r=rRegister # instrCB + | opcode=OPCODE_SRA r=rRegister # instrCB + | opcode=OPCODE_SLL r=rRegister # instrCB + | opcode=OPCODE_SRL r=rRegister # instrCB + | opcode=OPCODE_BIT n=rExpression SEP_COMMA r=rRegister # instrCB_N_R + | opcode=OPCODE_RES n=rExpression SEP_COMMA r=rRegister # instrCB_N_R + | opcode=OPCODE_SET n=rExpression SEP_COMMA r=rRegister # instrCB_N_R + + | opcode=OPCODE_LD ii=rII SEP_COMMA nn=rExpression # instrXD_II_NN + | opcode=OPCODE_ADD ii=rII SEP_COMMA rp=(REG_BC|REG_DE|REG_IX|REG_IY|REG_SP) # instrXD_II_RP + | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA ii=rII # instrXD_Ref_NN_II + | opcode=OPCODE_LD ii=rII SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrXD_II_Ref_NN + | opcode=OPCODE_LD ii=rII_HL SEP_COMMA n=rExpression # instrXD_IIHL_N + | opcode=OPCODE_LD d=rDisplacement SEP_COMMA n=rExpression # instrXD_Ref_II_N_N + + | opcode=OPCODE_LD ii=rII_HL SEP_COMMA r=rRegisterII # instrXD_IIHL_R + | opcode=OPCODE_LD r=rRegisterII SEP_COMMA ii=rII_HL # instrXD_R_IIHL + | opcode=OPCODE_LD d=rDisplacement SEP_COMMA r=rRegister2 # instrXD_Ref_II_N_R + | opcode=OPCODE_LD r=rRegister2 SEP_COMMA d=rDisplacement # instrXD_R_Ref_II_N + + | opcode=OPCODE_INC d=rDisplacement # instrXD_Ref_II_N + | opcode=OPCODE_DEC d=rDisplacement # instrXD_Ref_II_N + | opcode=OPCODE_ADD REG_A SEP_COMMA d=rDisplacement # instrXD_Ref_II_N + | opcode=OPCODE_ADC REG_A SEP_COMMA d=rDisplacement # instrXD_Ref_II_N + | opcode=OPCODE_SBC REG_A SEP_COMMA d=rDisplacement # instrXD_Ref_II_N + | opcode=OPCODE_SUB d=rDisplacement # instrXD_Ref_II_N + | opcode=OPCODE_AND d=rDisplacement # instrXD_Ref_II_N + | opcode=OPCODE_XOR d=rDisplacement # instrXD_Ref_II_N + | opcode=OPCODE_OR d=rDisplacement # instrXD_Ref_II_N + | opcode=OPCODE_CP d=rDisplacement # instrXD_Ref_II_N + + | opcode=OPCODE_INC ii=rII_HL # instrXD_IIHL + | opcode=OPCODE_DEC ii=rII_HL # instrXD_IIHL + | opcode=OPCODE_ADD REG_A SEP_COMMA ii=rII_HL # instrXD_IIHL + | opcode=OPCODE_ADC REG_A SEP_COMMA ii=rII_HL # instrXD_IIHL + | opcode=OPCODE_SBC REG_A SEP_COMMA ii=rII_HL # instrXD_IIHL + | opcode=OPCODE_SUB ii=rII_HL # instrXD_IIHL + | opcode=OPCODE_AND ii=rII_HL # instrXD_IIHL + | opcode=OPCODE_XOR ii=rII_HL # instrXD_IIHL + | opcode=OPCODE_OR ii=rII_HL # instrXD_IIHL + | opcode=OPCODE_CP ii=rII_HL # instrXD_IIHL + + | opcode=OPCODE_INC ii=rII # instrXD_II + | opcode=OPCODE_DEC ii=rII # instrXD_II + | opcode=OPCODE_POP ii=rII # instrXD_II + | opcode=OPCODE_JP SEP_LPAR ii=rII SEP_RPAR # instrXD_II + | opcode=OPCODE_LD REG_SP SEP_COMMA ii=rII # instrXD_II + | opcode=OPCODE_EX SEP_LPAR REG_SP SEP_RPAR SEP_COMMA ii=rII # instrXD_II + | opcode=OPCODE_PUSH ii=rII # instrXD_II + | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_HL # instrRef_NN_R - | opcode=OPCODE_LD r=rRegister SEP_COMMA n=rExpression # instrR_N - | opcode=OPCODE_LD r=REG_A SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrR_Ref_NN - | opcode=OPCODE_LD rp=rRegPair SEP_COMMA nn=rExpression # instrRP_NN - | opcode=OPCODE_LD rp=REG_HL SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrRP_Ref_NN - | opcode=OPCODE_JR c=(COND_NZ|COND_Z|COND_NC|COND_C) SEP_COMMA n=rExpression # instrC_N - | opcode=OPCODE_JP c=cCondition SEP_COMMA nn=rExpression # instrC_NN - | opcode=OPCODE_CALL c=cCondition SEP_COMMA nn=rExpression # instrC_NN - | opcode=OPCODE_JR n=rExpression # instrN - | opcode=OPCODE_JP nn=rExpression # instrNN - | opcode=OPCODE_CALL nn=rExpression # instrNN - | opcode=OPCODE_ADD REG_A SEP_COMMA n=rExpression # instrN - | opcode=OPCODE_ADC REG_A SEP_COMMA n=rExpression # instrN - | opcode=OPCODE_OUT SEP_LPAR n=rExpression SEP_RPAR SEP_COMMA REG_A # instrN - | opcode=OPCODE_SUB n=rExpression # instrN - | opcode=OPCODE_IN REG_A SEP_COMMA SEP_LPAR n=rExpression SEP_RPAR # instrN - | opcode=OPCODE_SBC REG_A SEP_COMMA n=rExpression # instrN - | opcode=OPCODE_AND n=rExpression # instrN - | opcode=OPCODE_XOR n=rExpression # instrN - | opcode=OPCODE_OR n=rExpression # instrN - | opcode=OPCODE_CP n=rExpression # instrN - - -//# | opcode=OPCODE_RLC -//# | opcode=OPCODE_RRC -//# | opcode=OPCODE_RL -//# | opcode=OPCODE_RR -//# | opcode=OPCODE_SLA -//# | opcode=OPCODE_SRA -//# | opcode=OPCODE_SLL -//# | opcode=OPCODE_SRL + | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_A # instrRef_NN_R - ; + | opcode=OPCODE_LD rp=REG_HL SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrRP_Ref_NN // x=0, z=2, q=1, p=2 + + | opcode=OPCODE_LD r=REG_A SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrR_Ref_NN // x=0, z=2, q=1, p=3 + + | opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR # instrA_Ref_RP // x=0, z=2, q=1, p=rp + + | opcode=OPCODE_LD SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR SEP_COMMA REG_A # instrRef_RP // x=0, z=2, q=0, p=rp + | opcode=OPCODE_JP SEP_LPAR rp=REG_HL SEP_RPAR # instrRef_RP // x=3, z=1, q=1, p=2 + + | opcode=OPCODE_EX SEP_LPAR dst=REG_SP SEP_RPAR SEP_COMMA src=REG_HL # instrRef_RP_RP // x=3, z=3, y=4 + + | opcode=OPCODE_LD dst=rRegister SEP_COMMA src=rRegister # instrR_R // x=1, y=dst, z=src + | opcode=OPCODE_LD r=rRegister SEP_COMMA n=rExpression # instrR_N // x=0, z=6, y=r + + | opcode=OPCODE_JR c=(COND_NZ|COND_Z|COND_NC|COND_C) SEP_COMMA n=rExpression # instrC_N // x=0, z=0, y=4..7 -r8bitInstruction: - opcode=OPCODE_LD SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR SEP_COMMA REG_A # instrRef_RP - | opcode=OPCODE_JP SEP_LPAR REG_HL SEP_RPAR # instrRef_RP - | opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR # instrA_Ref_RP - | opcode=OPCODE_EX SEP_LPAR src=REG_SP SEP_RPAR SEP_COMMA dst=REG_HL # instrRef_RP_RP - | opcode=OPCODE_LD dst=rRegister SEP_COMMA src=rRegister # instrR_R - | opcode=OPCODE_LD dst=REG_SP SEP_COMMA src=REG_HL # instrRP_RP - | opcode=OPCODE_EX dst=REG_AF SEP_COMMA src=REG_AFF # instrRP_RP - | opcode=OPCODE_EX dst=REG_DE SEP_COMMA src=REG_HL # instrRP_RP - | opcode=OPCODE_INC rp=rRegPair # instrRP - | opcode=OPCODE_DEC rp=rRegPair # instrRP - | opcode=OPCODE_ADD REG_HL SEP_COMMA rp=rRegPair # instrRP - | opcode=OPCODE_POP rp2=rRegPair2 # instrRP2 - | opcode=OPCODE_PUSH rp2=rRegPair2 # instrRP2 - | opcode=OPCODE_INC r=rRegister # instrR - | opcode=OPCODE_DEC r=rRegister # instrR - | opcode=OPCODE_ADD REG_A SEP_COMMA r=rRegister # instrR - | opcode=OPCODE_ADC REG_A SEP_COMMA r=rRegister # instrR - | opcode=OPCODE_SUB r=rRegister # instrR - | opcode=OPCODE_SBC REG_A SEP_COMMA r=rRegister # instrR - | opcode=OPCODE_AND r=rRegister # instrR - | opcode=OPCODE_XOR r=rRegister # instrR - | opcode=OPCODE_OR r=rRegister # instrR - | opcode=OPCODE_CP r=rRegister # instrR - | opcode=OPCODE_RET c=cCondition # instrC - | opcode=OPCODE_RST n=rExpression # instr8bitN - | opcode=OPCODE_NOP # instr - | opcode=OPCODE_RLCA # instr - | opcode=OPCODE_RRCA # instr - | opcode=OPCODE_RLA # instr - | opcode=OPCODE_RRA # instr - | opcode=OPCODE_DJNZ # instr - | opcode=OPCODE_DAA # instr - | opcode=OPCODE_CPL # instr - | opcode=OPCODE_SCF # instr - | opcode=OPCODE_CCF # instr - | opcode=OPCODE_HALT # instr - | opcode=OPCODE_RET # instr - | opcode=OPCODE_EXX # instr - | opcode=OPCODE_DI # instr - | opcode=OPCODE_EI # instr + | opcode=OPCODE_RET c=cCondition # instrC // x=3, z=0, y=cc + + | opcode=OPCODE_JP c=cCondition SEP_COMMA nn=rExpression # instrC_NN // x=3, z=2, y=cc + | opcode=OPCODE_CALL c=cCondition SEP_COMMA nn=rExpression # instrC_NN // x=3, z=4, y=cc + + | opcode=OPCODE_LD rp=rRegPair SEP_COMMA nn=rExpression # instrRP_NN // x=0, z=1, q=0, p=rp + + | opcode=OPCODE_EX dst=REG_AF SEP_COMMA src=REG_AFF # instrRP_RP // x=0, z=0, y=1 + | opcode=OPCODE_LD dst=REG_SP SEP_COMMA src=REG_HL # instrRP_RP // x=3, z=1, q=1, p=3 + | opcode=OPCODE_EX dst=REG_DE SEP_COMMA src=REG_HL # instrRP_RP // x=3, z=3, y=5 + + | opcode=OPCODE_JP nn=rExpression # instrNN // x=3, z=3, y=0 + | opcode=OPCODE_CALL nn=rExpression # instrNN // x=3, z=5, q=1, p=0 + + | opcode=OPCODE_DJNZ n=rExpression # instrN // x=0, z=0, y=2 + | opcode=OPCODE_JR n=rExpression # instrN // x=0, z=0, y=3 + | opcode=OPCODE_OUT SEP_LPAR n=rExpression SEP_RPAR SEP_COMMA REG_A # instrN // x=3, z=3, y=2 + | opcode=OPCODE_IN REG_A SEP_COMMA SEP_LPAR n=rExpression SEP_RPAR # instrN // x=3, z=3, y=3 + | opcode=OPCODE_ADD REG_A SEP_COMMA n=rExpression # instrN // x=3, z=6, y=alu + | opcode=OPCODE_ADC REG_A SEP_COMMA n=rExpression # instrN // x=3, z=6, y=alu + | opcode=OPCODE_SUB n=rExpression # instrN // x=3, z=6, y=alu + | opcode=OPCODE_SBC REG_A SEP_COMMA n=rExpression # instrN // x=3, z=6, y=alu + | opcode=OPCODE_AND n=rExpression # instrN // x=3, z=6, y=alu + | opcode=OPCODE_XOR n=rExpression # instrN // x=3, z=6, y=alu + | opcode=OPCODE_OR n=rExpression # instrN // x=3, z=6, y=alu + | opcode=OPCODE_CP n=rExpression # instrN // x=3, z=6, y=alu + | opcode=OPCODE_RST n=rExpression # instrN // x=3, z=7, y=N/8 + + | opcode=OPCODE_ADD REG_HL SEP_COMMA rp=rRegPair # instrRP // x=0, z=1, q=1, p=rp + | opcode=OPCODE_INC rp=rRegPair # instrRP // x=0, z=3, q=0, p=rp + | opcode=OPCODE_DEC rp=rRegPair # instrRP // x=0, z=3, q=1, p=rp + + | opcode=OPCODE_POP rp2=rRegPair2 # instrRP2 // x=3, z=1, q=0, p=rp2 + | opcode=OPCODE_PUSH rp2=rRegPair2 # instrRP2 // x=3, z=5, q=0, p=rp2 + + | opcode=OPCODE_ADD REG_A SEP_COMMA r=rRegister # instrR // x=2, y=alu, z=r + | opcode=OPCODE_ADC REG_A SEP_COMMA r=rRegister # instrR // x=2, y=alu, z=r + | opcode=OPCODE_SUB r=rRegister # instrR // x=2, y=alu, z=r + | opcode=OPCODE_SBC REG_A SEP_COMMA r=rRegister # instrR // x=2, y=alu, z=r + | opcode=OPCODE_AND r=rRegister # instrR // x=2, y=alu, z=r + | opcode=OPCODE_XOR r=rRegister # instrR // x=2, y=alu, z=r + | opcode=OPCODE_OR r=rRegister # instrR // x=2, y=alu, z=r + | opcode=OPCODE_CP r=rRegister # instrR // x=2, y=alu, z=r + | opcode=OPCODE_INC r=rRegister # instrR // x=0, z=4, y=r + | opcode=OPCODE_DEC r=rRegister # instrR // x=0, z=5, y=r + + | opcode=OPCODE_NOP # instr // x=0, z=0, y=0 + | opcode=OPCODE_RLCA # instr // x=0, z=7, y=0 + | opcode=OPCODE_RRCA # instr // x=0, z=7, y=1 + | opcode=OPCODE_RLA # instr // x=0, z=7, y=2 + | opcode=OPCODE_RRA # instr // x=0, z=7, y=3 + | opcode=OPCODE_DAA # instr // x=0, z=7, y=4 + | opcode=OPCODE_CPL # instr // x=0, z=7, y=5 + | opcode=OPCODE_SCF # instr // x=0, z=7, y=6 + | opcode=OPCODE_CCF # instr // x=0, z=7, y=7 + | opcode=OPCODE_HALT # instr // x=1, z=6, y=6 + | opcode=OPCODE_RET # instr // x=3, z=1, q=1, p=0 + | opcode=OPCODE_EXX # instr // x=3, z=1, q=1, p=1 + | opcode=OPCODE_DI # instr // x=3, z=3, y=6 + | opcode=OPCODE_EI # instr // x=3, z=3, y=7 ; rRegister: @@ -109,6 +222,28 @@ rRegister: | SEP_LPAR r=REG_HL SEP_RPAR ; +rRegister2: + REG_B + | REG_C + | REG_D + | REG_E + | REG_H + | REG_L + | REG_A + ; + +rRegisterII: + REG_B + | REG_C + | REG_D + | REG_E + | REG_IXH + | REG_IXL + | REG_IYH + | REG_IYL + | REG_A + ; + rRegPair: REG_BC | REG_DE @@ -123,7 +258,6 @@ rRegPair2: | REG_AF ; - cCondition: COND_C | COND_NC @@ -135,6 +269,11 @@ cCondition: | COND_PO ; +rII: REG_IX | REG_IY; +rII_HL: REG_IXH | REG_IYH | REG_IXL | REG_IYL; + +rDisplacement: SEP_LPAR ii=rII '+' n=rExpression SEP_RPAR; + rPseudoCode: PREP_ORG expr=rExpression # pseudoOrg | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu @@ -161,7 +300,7 @@ rData: rDBdata: expr=rExpression - | instr=r8bitInstruction + | instr=rInstruction ; rDWdata: diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java index a4ca44e91..0ff4f9d96 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java @@ -10,12 +10,21 @@ public class CompilerTables { public final static Map registers = new HashMap<>(); public final static Map regPairs = new HashMap<>(); + public final static Map regPairsII = new HashMap<>(); public final static Map regPairs2 = new HashMap<>(); public final static Map conditions = new HashMap<>(); public final static Map alu = new HashMap<>(); public final static Map rot = new HashMap<>(); - public final static Map im = new HashMap<>(); + public final static Map im = new HashMap<>(); public final static Map> block = new HashMap<>(); + public final static Map prefix = Map.of( + REG_IX, 0xDD, + REG_IXH, 0xDD, + REG_IXL, 0xDD, + REG_IY, 0xFD, + REG_IYH, 0xFD, + REG_IYL, 0xFD + ); static { registers.put(REG_B, 0); @@ -23,7 +32,11 @@ public class CompilerTables { registers.put(REG_D, 2); registers.put(REG_E, 3); registers.put(REG_H, 4); + registers.put(REG_IXH, 4); + registers.put(REG_IYH, 4); registers.put(REG_L, 5); + registers.put(REG_IXL, 5); + registers.put(REG_IYL, 5); registers.put(REG_HL, 6); registers.put(REG_A, 7); @@ -32,6 +45,12 @@ public class CompilerTables { regPairs.put(REG_HL, 2); regPairs.put(REG_SP, 3); + regPairsII.put(REG_BC, 0); + regPairsII.put(REG_DE, 1); + regPairsII.put(REG_IX, 2); + regPairsII.put(REG_IY, 2); + regPairsII.put(REG_SP, 3); + regPairs2.put(REG_BC, 0); regPairs2.put(REG_DE, 1); regPairs2.put(REG_HL, 2); @@ -64,10 +83,10 @@ public class CompilerTables { rot.put(OPCODE_SLL, 6); rot.put(OPCODE_SRL, 7); - im.put("0", 0); - im.put("0/1", 1); - im.put("1", 2); - im.put("2", 3); + im.put(IM_0, 0); + im.put(IM_01, 1); + im.put(IM_1, 2); + im.put(IM_2, 3); block.put(OPCODE_LDI, Pair.of(4, 0)); block.put(OPCODE_LDD, Pair.of(5, 0)); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java index 60ab51381..9aa35858b 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java @@ -4,73 +4,30 @@ import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; -import java.util.HashMap; -import java.util.Map; - -import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import java.util.Objects; public class Instr extends Node { - // opcode=OPCODE_NOP - // opcode=OPCODE_RLCA - // opcode=OPCODE_RRCA - // opcode=OPCODE_RLA - // opcode=OPCODE_RRA - // opcode=OPCODE_DJNZ - // opcode=OPCODE_DAA - // opcode=OPCODE_CPL - // opcode=OPCODE_SCF - // opcode=OPCODE_CCF - // opcode=OPCODE_HALT - // opcode=OPCODE_RET - // opcode=OPCODE_EXX - // opcode=OPCODE_DI - // opcode=OPCODE_EI - - private final static Map opcodes = new HashMap<>(); public final int opcode; + public final int x; + public final int y; + public final int z; - static { - opcodes.put(OPCODE_NOP, 0); - opcodes.put(OPCODE_RLCA, 7); - opcodes.put(OPCODE_RRCA, 0x0F); - opcodes.put(OPCODE_RLA, 0x17); - opcodes.put(OPCODE_RRA, 0x1F); - opcodes.put(OPCODE_DAA, 0x27); - opcodes.put(OPCODE_CPL, 0x2F); - opcodes.put(OPCODE_SCF, 0x37); - opcodes.put(OPCODE_CCF, 0x3F); - opcodes.put(OPCODE_HALT, 0x76); - opcodes.put(OPCODE_RET, 0xC9); - opcodes.put(OPCODE_EXX, 0xD9); - opcodes.put(OPCODE_DI, 0xF3); - opcodes.put(OPCODE_EI, 0xFB); - - -// opcodes.put(OPCODE_XCHG, 0xEB); -// opcodes.put(OPCODE_XTHL, 0xE3); -// opcodes.put(OPCODE_SPHL, 0xF9); -// opcodes.put(OPCODE_PCHL, 0xE9); -// opcodes.put(OPCODE_RC, 0xD8); -// opcodes.put(OPCODE_RNC, 0xD0); -// opcodes.put(OPCODE_RZ, 0xC8); -// opcodes.put(OPCODE_RNZ, 0xC0); -// opcodes.put(OPCODE_RM, 0xF8); -// opcodes.put(OPCODE_RP, 0xF0); -// opcodes.put(OPCODE_RPE, 0xE8); -// opcodes.put(OPCODE_RPO, 0xE0); - } - - public Instr(int line, int column, int opcode) { + public Instr(int line, int column, int opcode, int x, int y, int z) { super(line, column); this.opcode = opcode; + this.x = x; + this.y = y; + this.z = z; + + // children might be expr in the same order as when compiled } - public Instr(Token opcode) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); + public Instr(Token opcode, int x, int y, int z) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), x, y, z); } - public byte eval() { - return (byte) (opcodes.get(opcode) & 0xFF); + public Instr(Token opcode, int x, int q, int p, int z) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), x, (p << 1) | q, z); } @Override @@ -78,22 +35,22 @@ public void accept(NodeVisitor visitor) { visitor.visit(this); } - @Override - protected String toStringShallow() { - return "InstrNoArgs(" + opcode + ")"; - } - @Override protected Node mkCopy() { - return new Instr(line, column, opcode); + return new Instr(line, column, opcode, x, y, z); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + Instr instr = (Instr) o; + return opcode == instr.opcode && x == instr.x && y == instr.y && z == instr.z; + } - Instr that = (Instr) o; - return opcode == that.opcode; + @Override + protected String toStringShallow() { + return "Instr(" + opcode + ", x=" + x + ", y=" + y + ", z=" + z + ")"; } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrA_Ref_RP.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrA_Ref_RP.java deleted file mode 100644 index 74a42a969..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrA_Ref_RP.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import org.antlr.v4.runtime.Token; - -public class InstrA_Ref_RP extends Node { - // opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR - - public final int opcode; - public final int regPair; - - public InstrA_Ref_RP(int line, int column, int opcode, int regPair) { - super(line, column); - this.opcode = opcode; - this.regPair = regPair; - } - - public InstrA_Ref_RP(Token opcode, Token regPair) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); - } - - @Override - protected Node mkCopy() { - return new InstrA_Ref_RP(line, column, opcode, regPair); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC.java deleted file mode 100644 index 69f11ed63..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import org.antlr.v4.runtime.Token; - -public class InstrC extends Node { - // opcode=OPCODE_RET c=cCondition - - public final int opcode; - public final int cond; - - public InstrC(int line, int column, int opcode, int cond) { - super(line, column); - this.opcode = opcode; - this.cond = cond; - } - - public InstrC(Token opcode, Token cond) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), cond.getType()); - } - - @Override - protected Node mkCopy() { - return new InstrC(line, column, opcode, cond); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java new file mode 100644 index 000000000..01398b261 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java @@ -0,0 +1,71 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +public class InstrCB extends Node { + public final int opcode; + public final int x; + public final int y; + public final int z; + + private static final Map xmap = new HashMap<>(); + static { + xmap.put(OPCODE_RLC, 0); + xmap.put(OPCODE_RRC, 0); + xmap.put(OPCODE_RL, 0); + xmap.put(OPCODE_RR, 0); + xmap.put(OPCODE_SLA, 0); + xmap.put(OPCODE_SRA, 0); + xmap.put(OPCODE_SLL, 0); + xmap.put(OPCODE_SRL, 0); + xmap.put(OPCODE_BIT, 1); + xmap.put(OPCODE_RES, 2); + xmap.put(OPCODE_SET, 3); + } + + public InstrCB(int line, int column, int opcode, int y, int z) { + super(line, column); + this.opcode = opcode; + this.x = xmap.get(opcode); + this.y = y; + this.z = z; + + // possibly a child is expr: if so, then it's new y + } + + public InstrCB(Token opcode, int y, int z) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), y, z); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new InstrCB(line, column, opcode, y, z); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + InstrCB instr = (InstrCB) o; + return opcode == instr.opcode && x == instr.x && y == instr.y && z == instr.z; + } + + @Override + protected String toStringShallow() { + return "InstrCB(" + opcode + ", x=" + x + ", y=" + y + ", z=" + z + ")"; + } + +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_N.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_N.java deleted file mode 100644 index 5b85ccb47..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_N.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import org.antlr.v4.runtime.Token; - -public class InstrC_N extends Node { - // opcode=OPCODE_JR c=(COND_NZ|COND_Z|COND_NC|COND_C) SEP_COMMA n=rExpression - - public final int opcode; - public final int cond; - - public InstrC_N(int line, int column, int opcode, int cond) { - super(line, column); - this.opcode = opcode; - this.cond = cond; - // child is expr - } - - public InstrC_N(Token opcode, Token cond) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), cond.getType()); - } - - - - @Override - protected Node mkCopy() { - return new InstrC_N(line, column, opcode, cond); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_NN.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_NN.java deleted file mode 100644 index 3cd120861..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrC_NN.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import org.antlr.v4.runtime.Token; - -public class InstrC_NN extends Node { - // opcode=OPCODE_JP c=cCondition SEP_COMMA nn=rExpression - // opcode=OPCODE_CALL c=cCondition SEP_COMMA nn=rExpression - - public final int opcode; - public final int cond; - - public InstrC_NN(int line, int column, int opcode, int cond) { - super(line, column); - this.opcode = opcode; - this.cond = cond; - // child is expr - } - - public InstrC_NN(Token opcode, Token cond) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), cond.getType()); - } - - @Override - protected Node mkCopy() { - return new InstrC_NN(line, column, opcode, cond); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java new file mode 100644 index 000000000..cdc91f9d2 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java @@ -0,0 +1,89 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +public class InstrED extends Node { + public final int opcode; + public final int x; + public final int y; + public final int z; + + private static final Map xmap = new HashMap<>(); + static { + xmap.put(OPCODE_IN, 1); + xmap.put(OPCODE_OUT, 1); + xmap.put(OPCODE_SBC, 1); + xmap.put(OPCODE_ADC, 1); + xmap.put(OPCODE_LD, 1); + xmap.put(OPCODE_NEG, 1); + xmap.put(OPCODE_RETN, 1); + xmap.put(OPCODE_RETI, 1); + xmap.put(OPCODE_IM, 1); + xmap.put(OPCODE_LDI, 2); + xmap.put(OPCODE_LDD, 2); + xmap.put(OPCODE_LDIR, 2); + xmap.put(OPCODE_LDDR, 2); + xmap.put(OPCODE_CPI, 2); + xmap.put(OPCODE_CPD, 2); + xmap.put(OPCODE_CPIR, 2); + xmap.put(OPCODE_CPDR, 2); + xmap.put(OPCODE_INI, 2); + xmap.put(OPCODE_IND, 2); + xmap.put(OPCODE_INIR, 2); + xmap.put(OPCODE_INDR, 2); + xmap.put(OPCODE_OUTI, 2); + xmap.put(OPCODE_OUTD, 2); + xmap.put(OPCODE_OTIR, 2); + xmap.put(OPCODE_OTDR, 2); + } + + public InstrED(int line, int column, int opcode, int y, int z) { + super(line, column); + this.opcode = opcode; + this.x = xmap.get(opcode); + this.y = y; + this.z = z; + + // possibly child is expr + } + + public InstrED(Token opcode, int y, int z) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), y, z); + } + + public InstrED(Token opcode, int q, int p, int z) { + this(opcode, (p << 1) | q, z); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new InstrED(line, column, opcode, y, z); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + InstrED instr = (InstrED) o; + return opcode == instr.opcode && x == instr.x && y == instr.y && z == instr.z; + } + + @Override + protected String toStringShallow() { + return "InstrED(" + opcode + ", x=" + x + ", y=" + y + ", z=" + z + ")"; + } + +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrN.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrN.java deleted file mode 100644 index b5551f7bd..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrN.java +++ /dev/null @@ -1,134 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; -import org.antlr.v4.runtime.Token; - -import java.util.*; - -import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; - -public class InstrN extends Node { - // opcode=OPCODE_JR n=rExpression - // opcode=OPCODE_ADD REG_A SEP_COMMA n=rExpression - // opcode=OPCODE_ADC REG_A SEP_COMMA n=rExpression - // opcode=OPCODE_OUT SEP_LPAR n=rExpression SEP_RPAR SEP_COMMA REG_A - // opcode=OPCODE_SUB n=rExpression - // opcode=OPCODE_IN REG_A SEP_COMMA SEP_LPAR n=rExpression SEP_RPAR - // opcode=OPCODE_SBC REG_A SEP_COMMA n=rExpression - // opcode=OPCODE_AND n=rExpression - // opcode=OPCODE_XOR n=rExpression - // opcode=OPCODE_OR n=rExpression - // opcode=OPCODE_CP n=rExpression - // opcode=OPCODE_RST n=rExpression - - public final int opcode; - private final static Set twoBytes = new HashSet<>(); - private final static Map opcodes = new HashMap<>(); - - static { - twoBytes.add(OPCODE_JR); - twoBytes.add(OPCODE_ADD); - twoBytes.add(OPCODE_ADC); - twoBytes.add(OPCODE_SUB); - twoBytes.add(OPCODE_SBC); - twoBytes.add(OPCODE_AND); - twoBytes.add(OPCODE_XOR); - twoBytes.add(OPCODE_OR); - twoBytes.add(OPCODE_CP); - twoBytes.add(OPCODE_IN); - twoBytes.add(OPCODE_OUT); - - opcodes.put(OPCODE_JR, 0x18); - opcodes.put(OPCODE_JP, 0xC3); - opcodes.put(OPCODE_CALL, 0xCD); - opcodes.put(OPCODE_ADD, 0xC6); - opcodes.put(OPCODE_ADC, 0xCE); - opcodes.put(OPCODE_SUB, 0xD6); - opcodes.put(OPCODE_SBC, 0xDE); - opcodes.put(OPCODE_AND, 0xE6); - opcodes.put(OPCODE_XOR, 0xEE); - opcodes.put(OPCODE_OR, 0xF6); - opcodes.put(OPCODE_CP, 0xFE); - opcodes.put(OPCODE_RST, 0xC7); - opcodes.put(OPCODE_IN, 0xDB); - opcodes.put(OPCODE_OUT, 0xD3); - - - -// opcodes.put(OPCODE_STA, 0x32); -// opcodes.put(OPCODE_LHLD, 0x2A); -// opcodes.put(OPCODE_SHLD, 0x22); -// opcodes.put(OPCODE_JC, 0xDA); -// opcodes.put(OPCODE_JNC, 0xD2); -// opcodes.put(OPCODE_JZ, 0xCA); -// opcodes.put(OPCODE_JNZ, 0xC2); -// opcodes.put(OPCODE_JM, 0xFA); -// opcodes.put(OPCODE_JP, 0xF2); -// opcodes.put(OPCODE_JPE, 0xEA); -// opcodes.put(OPCODE_JPO, 0xE2); -// opcodes.put(OPCODE_CC, 0xDC); -// opcodes.put(OPCODE_CZ, 0xCC); -// opcodes.put(OPCODE_CNC, 0xD4); -// opcodes.put(OPCODE_CNZ, 0xC4); -// opcodes.put(OPCODE_CM, 0xFC); -// opcodes.put(OPCODE_CP, 0xF4); -// opcodes.put(OPCODE_CPE, 0xEC); -// opcodes.put(OPCODE_CPO, 0xE4); - } - - public InstrN(int line, int column, int opcode) { - super(line, column); - this.opcode = opcode; - // child is expr - } - - public InstrN(Token opcode) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); - } - - public int getExprSizeBytes() { - if (opcode == OPCODE_RST) { - return 0; - } else if (twoBytes.contains(opcode)) { - return 1; - } - return 2; // address - } - - public Optional eval() { - byte result = (byte) (opcodes.get(opcode) & 0xFF); - if (opcode == OPCODE_RST) { - return collectChild(Evaluated.class) - .filter(e -> e.value >= 0 && e.value <= 7) - .map(e -> (byte) (result | (e.value << 3))); - } - - return Optional.of(result); - } - - @Override - public void accept(NodeVisitor visitor) { - visitor.visit(this); - } - - @Override - protected String toStringShallow() { - return "InstrExpr(" + opcode + ")"; - } - - @Override - protected Node mkCopy() { - return new InstrN(line, column, opcode); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - InstrN instrExpr = (InstrN) o; - return opcode == instrExpr.opcode; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNN.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNN.java deleted file mode 100644 index 4ba1246e3..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrNN.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import org.antlr.v4.runtime.Token; - -public class InstrNN extends Node { - // opcode=OPCODE_JP nn=rExpression - // opcode=OPCODE_CALL nn=rExpression - public final int opcode; - - public InstrNN(int line, int column, int opcode) { - super(line, column); - this.opcode = opcode; - // child is expr - } - - public InstrNN(Token opcode) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType()); - } - - @Override - protected Node mkCopy() { - return new InstrNN(line, column, opcode); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR.java deleted file mode 100644 index d66f935da..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR.java +++ /dev/null @@ -1,95 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; -import org.antlr.v4.runtime.Token; - -import java.util.HashMap; -import java.util.Map; - -import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; - -public class InstrR extends Node { - // opcode=OPCODE_INC r=rRegister - // opcode=OPCODE_DEC r=rRegister - // opcode=OPCODE_ADD REG_A SEP_COMMA r=rRegister - // opcode=OPCODE_ADC REG_A SEP_COMMA r=rRegister - // opcode=OPCODE_SUB r=rRegister - // opcode=OPCODE_SBC REG_A SEP_COMMA r=rRegister - // opcode=OPCODE_AND r=rRegister - // opcode=OPCODE_XOR r=rRegister - // opcode=OPCODE_OR r=rRegister - // opcode=OPCODE_CP r=rRegister - - private final static Map opcodes = new HashMap<>(); - public final static Map registers = new HashMap<>(); - public final int opcode; - public final int reg; - - static { - opcodes.put(OPCODE_INC, 4); - opcodes.put(OPCODE_DEC, 5); - opcodes.put(OPCODE_ADD, 0x80); - opcodes.put(OPCODE_ADC, 0x88); - opcodes.put(OPCODE_SUB, 0x90); - opcodes.put(OPCODE_SBC, 0x98); - opcodes.put(OPCODE_AND, 0xA0); - opcodes.put(OPCODE_XOR, 0xA8); - opcodes.put(OPCODE_OR, 0xB0); - opcodes.put(OPCODE_CP, 0xB8); - - registers.put(REG_A, 7); - registers.put(REG_B, 0); - registers.put(REG_C, 1); - registers.put(REG_D, 2); - registers.put(REG_E, 3); - registers.put(REG_H, 4); - registers.put(REG_L, 5); - registers.put(REG_HL, 6); - } - - public InstrR(int line, int column, int opcode, int reg) { - super(line, column); - this.opcode = opcode; - this.reg = reg; - } - - public InstrR(Token opcode, Token reg) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); - } - - public byte eval() { - int result = opcodes.get(opcode); - int register = registers.get(reg); - if (opcode == OPCODE_INC || opcode == OPCODE_DEC) { - return (byte) ((result | (register << 3)) & 0xFF); - } - return (byte) ((result | register) & 0xFF); - } - - @Override - public void accept(NodeVisitor visitor) { - visitor.visit(this); - } - - @Override - protected String toStringShallow() { - return "InstrReg(" + opcode + "," + reg + ")"; - } - - @Override - protected Node mkCopy() { - return new InstrR(line, column, opcode, reg); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - InstrR instrReg = (InstrR) o; - - if (opcode != instrReg.opcode) return false; - return reg == instrReg.reg; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP.java deleted file mode 100644 index b0d7a11d8..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP.java +++ /dev/null @@ -1,83 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; -import org.antlr.v4.runtime.Token; - -import java.util.HashMap; -import java.util.Map; - -import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; - -public class InstrRP extends Node { - // opcode=OPCODE_INC rp=rRegPair - // opcode=OPCODE_DEC rp=rRegPair - // opcode=OPCODE_ADD REG_HL SEP_COMMA rp=rRegPair - // opcode=OPCODE_POP rp=(REG_BC|REG_DE|REG_HL|REG_AF) - // opcode=OPCODE_PUSH rp=(REG_BC|REG_DE|REG_HL|REG_AF) - - private final static Map opcodes = new HashMap<>(); - public final static Map regpairs = new HashMap<>(); - - public final int opcode; - public final int regPair; - - static { - opcodes.put(OPCODE_INC, 3); - opcodes.put(OPCODE_DEC, 0xB); - opcodes.put(OPCODE_PUSH, 0xC5); - opcodes.put(OPCODE_POP, 0xC1); - -// opcodes.put(OPCODE_STAX, 2); -// opcodes.put(OPCODE_LDAX, 0xA); -// opcodes.put(OPCODE_DAD, 9); - - regpairs.put(REG_B, 0); - regpairs.put(REG_D, 1); - regpairs.put(REG_H, 2); - regpairs.put(REG_AF, 3); - regpairs.put(REG_SP, 3); - } - - public InstrRP(int line, int column, int opcode, int regPair) { - super(line, column); - this.opcode = opcode; - this.regPair = regPair; - } - - public InstrRP(Token opcode, Token regPair) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); - } - - public byte eval() { - int result = opcodes.get(opcode); - int rp = regpairs.get(regPair); - return (byte) ((result | (rp << 4)) & 0xFF); - } - - @Override - public void accept(NodeVisitor visitor) { - visitor.visit(this); - } - - @Override - protected String toStringShallow() { - return "InstrRegPair(" + opcode + "," + regPair + ")"; - } - - @Override - protected Node mkCopy() { - return new InstrRP(line, column, opcode, regPair); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - InstrRP that = (InstrRP) o; - - if (opcode != that.opcode) return false; - return regPair == that.regPair; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_NN.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_NN.java deleted file mode 100644 index 0630f94ee..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_NN.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; -import org.antlr.v4.runtime.Token; - -public class InstrRP_NN extends Node { - // opcode=OPCODE_LD rp=rRegPair SEP_COMMA nn=rExpression - - public final int opcode; - public final int regPair; - - public InstrRP_NN(int line, int column, int opcode, int regPair) { - super(line, column); - this.opcode = opcode; - this.regPair = regPair; - // child is expr - } - - public InstrRP_NN(Token opcode, Token regPair) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); - } - - public byte eval() { - int rp = InstrRP.regpairs.get(regPair); - return (byte) ((1 | (rp << 4)) & 0xFF); - } - - @Override - public void accept(NodeVisitor visitor) { - visitor.visit(this); - } - - @Override - protected String toStringShallow() { - return "InstrRegPairExpr(" + opcode + "," + regPair + ")"; - } - - @Override - protected Node mkCopy() { - return new InstrRP_NN(line, column, opcode, regPair); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - InstrRP_NN that = (InstrRP_NN) o; - - if (opcode != that.opcode) return false; - return regPair == that.regPair; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_RP.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_RP.java deleted file mode 100644 index 7b99fb148..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_RP.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import org.antlr.v4.runtime.Token; - -public class InstrRP_RP extends Node { - // opcode=OPCODE_LD dst=REG_SP SEP_COMMA src=REG_HL - // opcode=OPCODE_EX dst=REG_AF SEP_COMMA src=REG_AFF - // opcode=OPCODE_EX dst=REG_DE SEP_COMMA src=REG_HL - - public final int opcode; - public final int srcRegPair; - public final int dstRegPair; - - public InstrRP_RP(int line, int column, int opcode, int srcRegPair, int dstRegPair) { - super(line, column); - this.opcode = opcode; - this.srcRegPair = srcRegPair; - this.dstRegPair = dstRegPair; - } - - public InstrRP_RP(Token opcode, Token srcRegPair, Token dstRegPair) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), srcRegPair.getType(), dstRegPair.getType()); - } - - @Override - protected Node mkCopy() { - return new InstrRP_RP(line, column, opcode, srcRegPair, dstRegPair); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_Ref_NN.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_Ref_NN.java deleted file mode 100644 index 26905db1a..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRP_Ref_NN.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import org.antlr.v4.runtime.Token; - -public class InstrRP_Ref_NN extends Node { - // opcode=OPCODE_LD rp=REG_HL SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR - - public final int opcode; - public final int regPair; - - public InstrRP_Ref_NN(int line, int column, int opcode, int regPair) { - super(line, column); - this.opcode = opcode; - this.regPair = regPair; - // child is expr - } - - public InstrRP_Ref_NN(Token opcode, Token regPair) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); - } - - @Override - protected Node mkCopy() { - return new InstrRP_Ref_NN(line, column, opcode, regPair); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_N.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_N.java deleted file mode 100644 index 8b0200054..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_N.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; -import org.antlr.v4.runtime.Token; - -public class InstrR_N extends Node { - // opcode=OPCODE_LD r=rRegister SEP_COMMA n=rExpression - - public final int opcode; - public final int reg; - - public InstrR_N(int line, int column, int opcode, int reg) { - super(line, column); - this.opcode = opcode; - this.reg = reg; - // child is expr - } - - public InstrR_N(Token opcode, Token reg) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); - } - - public byte eval() { - int register = InstrR.registers.get(reg); - return (byte) ((6 | (register << 3)) & 0xFF); - } - - @Override - public void accept(NodeVisitor visitor) { - visitor.visit(this); - } - - @Override - protected String toStringShallow() { - return "InstrRegExpr(" + opcode + "," + reg + ")"; - } - - @Override - protected Node mkCopy() { - return new InstrR_N(line, column, opcode, reg); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - InstrR_N that = (InstrR_N) o; - - if (opcode != that.opcode) return false; - return reg == that.reg; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_R.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_R.java deleted file mode 100644 index 9c3bc1750..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_R.java +++ /dev/null @@ -1,57 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; -import org.antlr.v4.runtime.Token; - -public class InstrR_R extends Node { - // opcode=OPCODE_LD dst=rRegister SEP_COMMA src=rRegister - - public final int opcode; - public final int srcReg; - public final int dstReg; - - public InstrR_R(int line, int column, int opcode, int dst, int src) { - super(line, column); - this.opcode = opcode; - this.srcReg = src; - this.dstReg = dst; - } - - public InstrR_R(Token opcode, Token dst, Token src) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), dst.getType(), src.getType()); - } - - public byte eval() { - int srcRegister = InstrR.registers.get(srcReg); - int dstRegister = InstrR.registers.get(dstReg); - return (byte)((0x40 | (dstRegister << 3) | (srcRegister)) & 0xFF); // TODO: mov M, M == HLT - } - - @Override - public void accept(NodeVisitor visitor) { - visitor.visit(this); - } - - @Override - protected String toStringShallow() { - return "InstrRegReg(" + opcode + ","+ dstReg +","+ srcReg +")"; - } - - @Override - protected Node mkCopy() { - return new InstrR_R(line, column, opcode, dstReg, srcReg); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - InstrR_R that = (InstrR_R) o; - - if (opcode != that.opcode) return false; - if (srcReg != that.srcReg) return false; - return dstReg == that.dstReg; - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_Ref_NN.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_Ref_NN.java deleted file mode 100644 index 23a242115..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrR_Ref_NN.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import org.antlr.v4.runtime.Token; - -public class InstrR_Ref_NN extends Node { - // opcode=OPCODE_LD r=REG_A SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR - - public final int opcode; - public final int reg; - - public InstrR_Ref_NN(int line, int column, int opcode, int reg) { - super(line, column); - this.opcode = opcode; - this.reg = reg; - // child is expr - } - - public InstrR_Ref_NN(Token opcode, Token reg) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); - } - - @Override - protected Node mkCopy() { - return new InstrR_Ref_NN(line, column, opcode, reg); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_NN_R.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_NN_R.java deleted file mode 100644 index fd21bcf02..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_NN_R.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import org.antlr.v4.runtime.Token; - -public class InstrRef_NN_R extends Node { - // opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_A - // opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_HL - - public final int opcode; - public final int reg; - - public InstrRef_NN_R(int line, int column, int opcode, int reg) { - super(line, column); - this.opcode = opcode; - this.reg = reg; - // child is expr - } - - public InstrRef_NN_R(Token opcode, Token reg) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), reg.getType()); - } - - @Override - protected Node mkCopy() { - return new InstrRef_NN_R(line, column, opcode, reg); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP.java deleted file mode 100644 index 9a1abddb4..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import org.antlr.v4.runtime.Token; - -public class InstrRef_RP extends Node { - // opcode=OPCODE_LD SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR SEP_COMMA REG_A - // opcode=OPCODE_JP SEP_LPAR REG_HL SEP_RPAR - - - public final int opcode; - public final int regPair; - - public InstrRef_RP(int line, int column, int opcode, int regPair) { - super(line, column); - this.opcode = opcode; - this.regPair = regPair; - } - - public InstrRef_RP(Token opcode, Token regPair) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), regPair.getType()); - } - - @Override - protected Node mkCopy() { - return new InstrRef_RP(line, column, opcode, regPair); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP_RP.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP_RP.java deleted file mode 100644 index d06952187..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrRef_RP_RP.java +++ /dev/null @@ -1,28 +0,0 @@ -package net.emustudio.plugins.compiler.asZ80.ast.instr; - -import net.emustudio.plugins.compiler.asZ80.ast.Node; -import org.antlr.v4.runtime.Token; - -public class InstrRef_RP_RP extends Node { - // opcode=OPCODE_EX SEP_LPAR src=REG_SP SEP_RPAR SEP_COMMA dst=REG_HL - - public final int opcode; - public final int srcRegPair; - public final int dstRegPair; - - public InstrRef_RP_RP(int line, int column, int opcode, int srcRegPair, int dstRegPair) { - super(line, column); - this.opcode = opcode; - this.srcRegPair = srcRegPair; - this.dstRegPair = dstRegPair; - } - - public InstrRef_RP_RP(Token opcode, Token srcRegPair, Token dstRegPair) { - this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), srcRegPair.getType(), dstRegPair.getType()); - } - - @Override - protected Node mkCopy() { - return new InstrRef_RP_RP(line, column, opcode, srcRegPair, dstRegPair); - } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java new file mode 100644 index 000000000..f2f53a424 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java @@ -0,0 +1,58 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +public class InstrXD extends Node { + public final int opcode; + public final int prefix; + public final int x; + public final int y; + public final int z; + + public InstrXD(int line, int column, int opcode, int prefix, int x, int y, int z) { + super(line, column); + this.opcode = opcode; + this.prefix = prefix; + this.x = x; + this.y = y; + this.z = z; + + // 1. child is maybe expr (II+d) or N + // 2. child is maybe N if (II+d) is defined + } + + public InstrXD(Token opcode, int prefix, int x, int y, int z) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), prefix, x, y, z); + } + + public InstrXD(Token opcode, int prefix, int x, int q, int p, int z) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), prefix, x, (p << 1) | q, z); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new InstrXD(line, column, opcode, prefix, x, y, z); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + InstrXD instr = (InstrXD) o; + return opcode == instr.opcode && prefix == instr.prefix && x == instr.x && y == instr.y && z == instr.z; + } + + @Override + protected String toStringShallow() { + return "InstrXD(" + opcode + ", prefix=" + prefix + ", x=" + x + ", y=" + y + ", z=" + z + ")"; + } + +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java new file mode 100644 index 000000000..75bea0d8b --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java @@ -0,0 +1,77 @@ +package net.emustudio.plugins.compiler.asZ80.ast.instr; + +import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import org.antlr.v4.runtime.Token; + +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +/** + * DD or FD prefix, CB, displacement byte, opcode + */ +public class InstrXDCB extends Node { + public final int opcode; + public final int x; + public final int y; + public final int z; + public final int prefix; + + private static final Map xmap = new HashMap<>(); + static { + xmap.put(OPCODE_RLC, 0); + xmap.put(OPCODE_RRC, 0); + xmap.put(OPCODE_RL, 0); + xmap.put(OPCODE_RR, 0); + xmap.put(OPCODE_SLA, 0); + xmap.put(OPCODE_SRA, 0); + xmap.put(OPCODE_SLL, 0); + xmap.put(OPCODE_SRL, 0); + xmap.put(OPCODE_BIT, 1); + xmap.put(OPCODE_RES, 2); + xmap.put(OPCODE_SET, 3); + } + + public InstrXDCB(int line, int column, int opcode, int prefix, int y, int z) { + super(line, column); + + this.opcode = opcode; + this.prefix = prefix; + this.x = xmap.get(opcode); + this.y = y; + this.z = z; + + // 1. child is expr (II + d) + // 2. possibly another expr child + } + + public InstrXDCB(Token opcode, int prefix, int y, int z) { + this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), prefix, y, z); + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + protected Node mkCopy() { + return new InstrXDCB(line, column, opcode, prefix, y, z); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + InstrXDCB instr = (InstrXDCB) o; + return opcode == instr.opcode && prefix == instr.prefix && x == instr.x && y == instr.y && z == instr.z; + } + + @Override + protected String toStringShallow() { + return "InstrXDCB(" + opcode + ", prefix=" + prefix + ", x=" + x + ", y=" + y + ", z=" + z + ")"; + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java index f0a49f33b..4bb42ec58 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java @@ -4,9 +4,6 @@ import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrN; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrR_N; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRP_NN; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroArgument; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoOrg; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java index d41486491..f6a1eb89c 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java @@ -1,129 +1,617 @@ package net.emustudio.plugins.compiler.asZ80.visitors; -import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; import net.emustudio.plugins.compiler.asZ80.AsZ80ParserBaseVisitor; +import net.emustudio.plugins.compiler.asZ80.CompilerTables; +import net.emustudio.plugins.compiler.asZ80.Pair; import net.emustudio.plugins.compiler.asZ80.ast.Node; import net.emustudio.plugins.compiler.asZ80.ast.instr.*; +import java.util.HashMap; +import java.util.Map; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + public class CreateInstrVisitor extends AsZ80ParserBaseVisitor { @Override - public Node visitInstrRP_NN(InstrRP_NNContext ctx) { - InstrRP_NN instr = new InstrRP_NN(ctx.opcode, ctx.rp.start); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + public Node visitInstrXDCB_R(InstrXDCB_RContext ctx) { + // opcode=OPCODE_RLC d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + // | opcode=OPCODE_RRC d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + // | opcode=OPCODE_RL d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + // | opcode=OPCODE_RR d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + // | opcode=OPCODE_SLA d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + // | opcode=OPCODE_SRA d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + // | opcode=OPCODE_SLL d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + // | opcode=OPCODE_SRL d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_R + int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); + int y = CompilerTables.rot.get(ctx.opcode.getType()); + int z = CompilerTables.registers.get(ctx.r.start.getType()); + InstrXDCB instr = new InstrXDCB(ctx.opcode, prefix, y, z); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); return instr; } @Override - public Node visitInstrR_N(InstrR_NContext ctx) { - InstrR_N instr = new InstrR_N(ctx.opcode, ctx.r.r); - instr.addChild(CreateVisitors.expr.visit(ctx.n)); + public Node visitInstrXDCB(InstrXDCBContext ctx) { + // | opcode=OPCODE_SRL d=rDisplacement # instrXDCB + // | opcode=OPCODE_RLC d=rDisplacement # instrXDCB + // | opcode=OPCODE_RRC d=rDisplacement # instrXDCB + // | opcode=OPCODE_RL d=rDisplacement # instrXDCB + // | opcode=OPCODE_RR d=rDisplacement # instrXDCB + // | opcode=OPCODE_SLA d=rDisplacement # instrXDCB + // | opcode=OPCODE_SRA d=rDisplacement # instrXDCB + // | opcode=OPCODE_SLL d=rDisplacement # instrXDCB + int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); + int y = CompilerTables.rot.get(ctx.opcode.getType()); + InstrXDCB instr = new InstrXDCB(ctx.opcode, prefix, y, 6); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); return instr; } @Override - public Node visitInstr8bitN(Instr8bitNContext ctx) { - InstrN instr = new InstrN(ctx.opcode); + public Node visitInstrXDCB_N(InstrXDCB_NContext ctx) { + // | opcode=OPCODE_BIT n=rExpression SEP_COMMA d=rDisplacement # instrXDCB_N + // | opcode=OPCODE_RES n=rExpression SEP_COMMA d=rDisplacement # instrXDCB_N + // | opcode=OPCODE_SET n=rExpression SEP_COMMA d=rDisplacement # instrXDCB_N + int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); + InstrXDCB instr = new InstrXDCB(ctx.opcode, prefix, 0, 6); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + instr.addChild(CreateVisitors.expr.visit(ctx.n)); + return super.visitInstrXDCB_N(ctx); + } + + @Override + public Node visitInstrXDCB_N_R(InstrXDCB_N_RContext ctx) { + // | opcode=OPCODE_RES n=rExpression SEP_COMMA d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_N_R + // | opcode=OPCODE_SET n=rExpression SEP_COMMA d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_N_R + int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); + int z = CompilerTables.registers.get(ctx.r.start.getType()); + InstrXDCB instr = new InstrXDCB(ctx.opcode, prefix, 0, z); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); instr.addChild(CreateVisitors.expr.visit(ctx.n)); return instr; } @Override - public Node visitInstrRef_NN_R(InstrRef_NN_RContext ctx) { - InstrRef_NN_R instr = new InstrRef_NN_R(ctx.opcode, ctx.r); + public Node visitInstrED_R2(InstrED_R2Context ctx) { + // | opcode=OPCODE_IN r=rRegister2 SEP_COMMA SEP_LPAR REG_C SEP_RPAR # instrED_R2 + // | opcode=OPCODE_OUT SEP_LPAR REG_C SEP_RPAR SEP_COMMA r=rRegister2 # instrED_R2 + int y = CompilerTables.registers.get(ctx.r.start.getType()); + int z = (ctx.opcode.getType() == OPCODE_IN) ? 0 : 1; + return new InstrED(ctx.opcode, y, z); + } + + @Override + public Node visitInstrED_C(InstrED_CContext ctx) { + // | opcode=OPCODE_IN SEP_LPAR REG_C SEP_RPAR # instrED_C + // | opcode=OPCODE_OUT SEP_LPAR REG_C SEP_RPAR SEP_COMMA n=LIT_NUMBER # instrED_C + int z = (ctx.opcode.getType() == OPCODE_IN) ? 0 : 1; + return new InstrED(ctx.opcode, 6, z); + } + + @Override + public Node visitInstrED_RP(InstrED_RPContext ctx) { + // | opcode=OPCODE_SBC REG_HL SEP_COMMA rp=rRegPair # instrED_RP + // | opcode=OPCODE_ADC REG_HL SEP_COMMA rp=rRegPair # instrED_RP + int q = (ctx.opcode.getType() == OPCODE_SBC) ? 0 : 1; + int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); + return new InstrED(ctx.opcode, p, q, 2); + } + + @Override + public Node visitInstrED_NN_RP(InstrED_NN_RPContext ctx) { + // | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA rp=rRegPair # instrED_NN_RP + int q = 0; + int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); + InstrED instr = new InstrED(ctx.opcode, p, q, 3); instr.addChild(CreateVisitors.expr.visit(ctx.nn)); return instr; } @Override - public Node visitInstrRP_Ref_NN(InstrRP_Ref_NNContext ctx) { - InstrRP_Ref_NN instr = new InstrRP_Ref_NN(ctx.opcode, ctx.rp); + public Node visitInstrED_RP_NN(InstrED_RP_NNContext ctx) { + // | opcode=OPCODE_LD rp=rRegPair SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrED_RP_NN + int q = 1; + int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); + InstrED instr = new InstrED(ctx.opcode, p, q, 3); instr.addChild(CreateVisitors.expr.visit(ctx.nn)); return instr; } @Override - public Node visitInstrR_Ref_NN(InstrR_Ref_NNContext ctx) { - InstrR_Ref_NN instr = new InstrR_Ref_NN(ctx.opcode, ctx.r); + public Node visitInstrED_IM(InstrED_IMContext ctx) { + // | opcode=OPCODE_IM im=(IM_0|IM_1|IM_2|IM_01) # instrED_IM + int y = CompilerTables.im.get(ctx.im.getType()); + return new InstrED(ctx.opcode, y, 6); + } + + @Override + public Node visitInstrED_RIA_RIA(InstrED_RIA_RIAContext ctx) { + // | opcode=OPCODE_LD dst=REG_I src=REG_A # instrED_RIA_RIA + // | opcode=OPCODE_LD dst=REG_R src=REG_A # instrED_RIA_RIA + // | opcode=OPCODE_LD dst=REG_A src=REG_I # instrED_RIA_RIA + // | opcode=OPCODE_LD dst=REG_A src=REG_R # instrED_RIA_RIA + int y = 0; // ctx.dst.getType() == REG_I + if (ctx.dst.getType() == REG_R) { + y = 1; + } else if (ctx.src.getType() == REG_I) { + y = 2; + } else if (ctx.src.getType() == REG_R) { + y = 3; + } + return new InstrED(ctx.opcode, y, 7); + } + + @Override + public Node visitInstrED(InstrEDContext ctx) { + // | opcode=OPCODE_NEG # instrED + // | opcode=OPCODE_RETN # instrED + // | opcode=OPCODE_RETI # instrED + // | opcode=OPCODE_RLD # instrED + // | opcode=OPCODE_RRD # instrED + // | opcode=OPCODE_LDI # instrED + // | opcode=OPCODE_LDIR # instrED + // | opcode=OPCODE_CPI # instrED + // | opcode=OPCODE_CPIR # instrED + // | opcode=OPCODE_INI # instrED + // | opcode=OPCODE_INIR # instrED + // | opcode=OPCODE_OUTI # instrED + // | opcode=OPCODE_OTIR # instrED + // | opcode=OPCODE_LDD # instrED + // | opcode=OPCODE_LDDR # instrED + // | opcode=OPCODE_CPD # instrED + // | opcode=OPCODE_CPDR # instrED + // | opcode=OPCODE_IND # instrED + // | opcode=OPCODE_INDR # instrED + // | opcode=OPCODE_OUTD # instrED + // | opcode=OPCODE_OTDR # instrED + switch (ctx.opcode.getType()) { + case OPCODE_NEG: + return new InstrED(ctx.opcode, 0, 4); + case OPCODE_RETN: + return new InstrED(ctx.opcode, 0, 5); + case OPCODE_RETI: + return new InstrED(ctx.opcode, 1, 5); + case OPCODE_RRD: + return new InstrED(ctx.opcode, 4, 7); + case OPCODE_RLD: + return new InstrED(ctx.opcode, 5, 7); + } + + Pair yz = CompilerTables.block.get(ctx.opcode.getType()); + return new InstrED(ctx.opcode, yz.l, yz.r); + } + + @Override + public Node visitInstrCB(InstrCBContext ctx) { + // | opcode=OPCODE_RLC r=rRegister # instrCB + // | opcode=OPCODE_RRC r=rRegister # instrCB + // | opcode=OPCODE_RL r=rRegister # instrCB + // | opcode=OPCODE_RR r=rRegister # instrCB + // | opcode=OPCODE_SLA r=rRegister # instrCB + // | opcode=OPCODE_SRA r=rRegister # instrCB + // | opcode=OPCODE_SLL r=rRegister # instrCB + // | opcode=OPCODE_SRL r=rRegister # instrCB + int y = CompilerTables.rot.get(ctx.opcode.getType()); + int z = CompilerTables.registers.get(ctx.r.r.getType()); + return new InstrCB(ctx.opcode, y, z); + } + + @Override + public Node visitInstrCB_N_R(InstrCB_N_RContext ctx) { + // | opcode=OPCODE_BIT n=rExpression SEP_COMMA r=rRegister # instrCB_N_R + // | opcode=OPCODE_RES n=rExpression SEP_COMMA r=rRegister # instrCB_N_R + // | opcode=OPCODE_SET n=rExpression SEP_COMMA r=rRegister # instrCB_N_R + int z = CompilerTables.registers.get(ctx.r.r.getType()); + // y needs to be computed from expr + InstrCB instr = new InstrCB(ctx.opcode, 0, z); + instr.addChild(CreateVisitors.expr.visit(ctx.n)); + return instr; + } + + @Override + public Node visitInstrXD_II_NN(InstrXD_II_NNContext ctx) { + // | opcode=OPCODE_LD ii=rII SEP_COMMA nn=rExpression # instrXD_II_NN + int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); + InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 0, 2, 1); instr.addChild(CreateVisitors.expr.visit(ctx.nn)); return instr; } @Override - public Node visitInstrN(InstrNContext ctx) { - InstrN instr = new InstrN(ctx.opcode); - instr.addChild(CreateVisitors.expr.visit(ctx.n)); + public Node visitInstrXD_II_RP(InstrXD_II_RPContext ctx) { + // | opcode=OPCODE_ADD ii=rII SEP_COMMA rp=(REG_BC|REG_DE|REG_IX|REG_IY|REG_SP) # instrXD_II_RP + int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); + int p = CompilerTables.regPairsII.get(ctx.rp.getType()); + return new InstrXD(ctx.opcode, prefix, 0, 1, p, 1); + } + + @Override + public Node visitInstrXD_Ref_NN_II(InstrXD_Ref_NN_IIContext ctx) { + // | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA ii=rII # instrXD_Ref_NN_II + int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); + InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 0, 2, 2); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); return instr; } @Override - public Node visitInstrNN(InstrNNContext ctx) { - InstrNN instr = new InstrNN(ctx.opcode); + public Node visitInstrXD_II_Ref_NN(InstrXD_II_Ref_NNContext ctx) { + // | opcode=OPCODE_LD ii=rII SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrXD_II_Ref_NN + int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); + InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 1, 2, 2); instr.addChild(CreateVisitors.expr.visit(ctx.nn)); return instr; } @Override - public Node visitInstrC_N(InstrC_NContext ctx) { - InstrC_N instr = new InstrC_N(ctx.opcode, ctx.c); + public Node visitInstrXD_IIHL_N(InstrXD_IIHL_NContext ctx) { + // | opcode=OPCODE_LD ii=rII_HL SEP_COMMA n=rExpression # instrXD_IIHL_N + int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); + int y = CompilerTables.registers.get(ctx.ii.start.getType()); + InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, y, 6); instr.addChild(CreateVisitors.expr.visit(ctx.n)); return instr; } @Override - public Node visitInstr(InstrContext ctx) { - return new Instr(ctx.opcode); + public Node visitInstrXD_Ref_II_N_N(InstrXD_Ref_II_N_NContext ctx) { + // | opcode=OPCODE_LD d=rDisplacement SEP_COMMA n=rExpression # instrXD_Ref_II_N_N + int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); + InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 6, 6); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + instr.addChild(CreateVisitors.expr.visit(ctx.n)); + return instr; } @Override - public Node visitInstrRef_RP(InstrRef_RPContext ctx) { - return new InstrRef_RP(ctx.opcode, ctx.rp); + public Node visitInstrXD_IIHL_R(InstrXD_IIHL_RContext ctx) { + // | opcode=OPCODE_LD ii=rII_HL SEP_COMMA r=rRegisterII # instrXD_IIHL_R + int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); + int y = CompilerTables.registers.get(ctx.ii.start.getType()); + int z = CompilerTables.registers.get(ctx.r.start.getType()); + return new InstrXD(ctx.opcode, prefix, 1, y, z); } @Override - public Node visitInstrA_Ref_RP(InstrA_Ref_RPContext ctx) { - return new InstrA_Ref_RP(ctx.opcode, ctx.rp); + public Node visitInstrXD_R_IIHL(InstrXD_R_IIHLContext ctx) { + // | opcode=OPCODE_LD r=rRegisterII SEP_COMMA ii=rII_HL # instrXD_R_IIHL + int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); + int y = CompilerTables.registers.get(ctx.r.start.getType()); + int z = CompilerTables.registers.get(ctx.ii.start.getType()); + return new InstrXD(ctx.opcode, prefix, 1, y, z); } @Override - public Node visitInstrR_R(InstrR_RContext ctx) { - return new InstrR_R(ctx.opcode, ctx.dst.r, ctx.src.r); + public Node visitInstrXD_Ref_II_N_R(InstrXD_Ref_II_N_RContext ctx) { + // | opcode=OPCODE_LD d=rDisplacement SEP_COMMA r=rRegister2 # instrXD_Ref_II_N_R + int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); + int z = CompilerTables.registers.get(ctx.r.start.getType()); + InstrXD instr = new InstrXD(ctx.opcode, prefix, 1, 6, z); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + return instr; } @Override - public Node visitInstrRP_RP(InstrRP_RPContext ctx) { - return new InstrRP_RP(ctx.opcode, ctx.src, ctx.dst); + public Node visitInstrXD_R_Ref_II_N(InstrXD_R_Ref_II_NContext ctx) { + // | opcode=OPCODE_LD r=rRegister2 SEP_COMMA d=rDisplacement # instrXD_R_Ref_II_N + int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); + int y = CompilerTables.registers.get(ctx.r.start.getType()); + InstrXD instr = new InstrXD(ctx.opcode, prefix, 1, y, 6); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + return instr; } @Override - public Node visitInstrRP(InstrRPContext ctx) { - return new InstrRP(ctx.opcode, ctx.rp.start); + public Node visitInstrXD_Ref_II_N(InstrXD_Ref_II_NContext ctx) { + // | opcode=OPCODE_INC d=rDisplacement # instrXD_Ref_II_N + // | opcode=OPCODE_DEC d=rDisplacement # instrXD_Ref_II_N + // | opcode=OPCODE_ADD REG_A SEP_COMMA d=rDisplacement # instrXD_Ref_II_N + // | opcode=OPCODE_ADC REG_A SEP_COMMA d=rDisplacement # instrXD_Ref_II_N + // | opcode=OPCODE_SBC REG_A SEP_COMMA d=rDisplacement # instrXD_Ref_II_N + // | opcode=OPCODE_SUB d=rDisplacement # instrXD_Ref_II_N + // | opcode=OPCODE_AND d=rDisplacement # instrXD_Ref_II_N + // | opcode=OPCODE_XOR d=rDisplacement # instrXD_Ref_II_N + // | opcode=OPCODE_OR d=rDisplacement # instrXD_Ref_II_N + // | opcode=OPCODE_CP d=rDisplacement # instrXD_Ref_II_N + int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); + if (ctx.opcode.getType() == OPCODE_INC) { + InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 6, 4); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + return instr; + } else if (ctx.opcode.getType() == OPCODE_DEC) { + InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 6, 5); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + return instr; + } + + int y = CompilerTables.alu.get(ctx.opcode.getType()); + InstrXD instr = new InstrXD(ctx.opcode, prefix, 2, y, 6); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + return instr; } @Override - public Node visitInstrRP2(InstrRP2Context ctx) { - return new InstrRP(ctx.opcode, ctx.rp2.start); + public Node visitInstrXD_IIHL(InstrXD_IIHLContext ctx) { + // | opcode=OPCODE_INC ii=rII_HL # instrXD_IIHL + // | opcode=OPCODE_DEC ii=rII_HL # instrXD_IIHL + // | opcode=OPCODE_ADD REG_A SEP_COMMA ii=rII_HL # instrXD_IIHL + // | opcode=OPCODE_ADC REG_A SEP_COMMA ii=rII_HL # instrXD_IIHL + // | opcode=OPCODE_SBC REG_A SEP_COMMA ii=rII_HL # instrXD_IIHL + // | opcode=OPCODE_SUB ii=rII_HL # instrXD_IIHL + // | opcode=OPCODE_AND ii=rII_HL # instrXD_IIHL + // | opcode=OPCODE_XOR ii=rII_HL # instrXD_IIHL + // | opcode=OPCODE_OR ii=rII_HL # instrXD_IIHL + // | opcode=OPCODE_CP ii=rII_HL # instrXD_IIHL + int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); + int r = CompilerTables.registers.get(ctx.ii.start.getType()); + + if (ctx.opcode.getType() == OPCODE_INC) { + return new InstrXD(ctx.opcode, prefix, 0, r, 4); + } else if (ctx.opcode.getType() == OPCODE_DEC) { + return new InstrXD(ctx.opcode, prefix, 0, r, 5); + } + int y = CompilerTables.alu.get(ctx.opcode.getType()); + return new InstrXD(ctx.opcode, prefix, 2, y, r); } @Override - public Node visitInstrR(InstrRContext ctx) { - return new InstrR(ctx.opcode, ctx.r.r); + public Node visitInstrXD_II(InstrXD_IIContext ctx) { + // | opcode=OPCODE_INC ii=rII # instrXD_II + // | opcode=OPCODE_DEC ii=rII # instrXD_II + // | opcode=OPCODE_POP ii=rII # instrXD_II + // | opcode=OPCODE_JP SEP_LPAR ii=rII SEP_RPAR # instrXD_II + // | opcode=OPCODE_LD REG_SP SEP_COMMA ii=rII # instrXD_II + // | opcode=OPCODE_EX SEP_LPAR REG_SP SEP_RPAR SEP_COMMA ii=rII # instrXD_II + // | opcode=OPCODE_PUSH ii=rII # instrXD_II + int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); + int opcode = ctx.opcode.getType(); + int x = (opcode == OPCODE_INC || opcode == OPCODE_DEC) ? 0 : 3; + int z = (opcode == OPCODE_PUSH) ? 5 : ((opcode == OPCODE_POP || opcode == OPCODE_JP || opcode == OPCODE_LD) ? 1 : 3); + int q = 0; + int p = (opcode == OPCODE_LD) ? 3 : 2; + + switch (opcode) { + case OPCODE_DEC: + case OPCODE_JP: + case OPCODE_LD: + q = 1; + break; + } + + return new InstrXD(ctx.opcode, prefix, x, q, p, z); + } + + @Override + public Node visitInstrRef_NN_R(InstrRef_NN_RContext ctx) { + // | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_HL # instrRef_NN_R // x=0, z=2, q=0, p=2 + // | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_A # instrRef_NN_R // x=0, z=2, q=0, p=3 + int p = (ctx.r.getType() == REG_HL) ? 2 : 3; + Instr instr = new Instr(ctx.opcode, 0, 0, p, 2); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + return instr; + } + + @Override + public Node visitInstrRP_Ref_NN(InstrRP_Ref_NNContext ctx) { + // | opcode=OPCODE_LD rp=REG_HL SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrRP_Ref_NN // x=0, z=2, q=1, p=2 + Instr instr = new Instr(ctx.opcode, 0, 1, 2, 2); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + return instr; + } + + @Override + public Node visitInstrR_Ref_NN(InstrR_Ref_NNContext ctx) { + // | opcode=OPCODE_LD r=REG_A SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrR_Ref_NN // x=0, z=2, q=1, p=3 + Instr instr = new Instr(ctx.opcode, 0, 1, 3, 2); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + return instr; + } + + @Override + public Node visitInstrA_Ref_RP(InstrA_Ref_RPContext ctx) { + // | opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR # instrA_Ref_RP // x=0, z=2, q=1, p=rp + int p = CompilerTables.regPairs.get(ctx.rp.getType()); + return new Instr(ctx.opcode, 0, 1, p, 2); + } + + @Override + public Node visitInstrRef_RP(InstrRef_RPContext ctx) { + // | opcode=OPCODE_LD SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR SEP_COMMA REG_A # instrRef_RP // x=0, z=2, q=0, p=rp + // | opcode=OPCODE_JP SEP_LPAR rp=REG_HL SEP_RPAR # instrRef_RP // x=3, z=1, q=1, p=2 + int p = CompilerTables.regPairs.get(ctx.rp.getType()); + int x = (ctx.opcode.getType() == OPCODE_LD) ? 0 : 3; + int z = (ctx.opcode.getType() == OPCODE_LD) ? 2 : 1; + int q = (ctx.opcode.getType() == OPCODE_LD) ? 0 : 1; + return new Instr(ctx.opcode, x, q, p, z); } @Override public Node visitInstrRef_RP_RP(InstrRef_RP_RPContext ctx) { - return new InstrRef_RP_RP(ctx.opcode, ctx.src, ctx.dst); + // | opcode=OPCODE_EX SEP_LPAR dst=REG_SP SEP_RPAR SEP_COMMA src=REG_HL # instrRef_RP_RP // x=3, z=3, y=4 + return new Instr(ctx.opcode, 3, 4, 3); + } + + @Override + public Node visitInstrR_R(InstrR_RContext ctx) { + // | opcode=OPCODE_LD dst=rRegister SEP_COMMA src=rRegister # instrR_R // x=1, y=dst, z=src + int y = CompilerTables.registers.get(ctx.dst.r.getType()); + int z = CompilerTables.registers.get(ctx.src.r.getType()); + return new Instr(ctx.opcode, 1, y, z); + } + + @Override + public Node visitInstrR_N(InstrR_NContext ctx) { + // | opcode=OPCODE_LD r=rRegister SEP_COMMA n=rExpression # instrR_N // x=0, z=6, y=r + int y = CompilerTables.registers.get(ctx.r.r.getType()); + Instr instr = new Instr(ctx.opcode, 0, y, 6); + instr.addChild(CreateVisitors.expr.visit(ctx.n)); + return instr; + } + + @Override + public Node visitInstrC_N(InstrC_NContext ctx) { + // | opcode=OPCODE_JR c=(COND_NZ|COND_Z|COND_NC|COND_C) SEP_COMMA n=rExpression # instrC_N // x=0, z=0, y=4..7 + int y = CompilerTables.conditions.get(ctx.c.getType()); + Instr instr = new Instr(ctx.opcode, 0, y, 0); + instr.addChild(CreateVisitors.expr.visit(ctx.n)); + return instr; } @Override public Node visitInstrC(InstrCContext ctx) { - return new InstrC(ctx.opcode, ctx.c.start); + // | opcode=OPCODE_RET c=cCondition # instrC // x=3, z=0, y=cc + int y = CompilerTables.conditions.get(ctx.c.start.getType()); + return new Instr(ctx.opcode, 3, y, 0); } @Override public Node visitInstrC_NN(InstrC_NNContext ctx) { - InstrC_NN instr = new InstrC_NN(ctx.opcode, ctx.c.start); + // | opcode=OPCODE_JP c=cCondition SEP_COMMA nn=rExpression # instrC_NN // x=3, z=2, y=cc + // | opcode=OPCODE_CALL c=cCondition SEP_COMMA nn=rExpression # instrC_NN // x=3, z=4, y=cc + int y = CompilerTables.conditions.get(ctx.c.start.getType()); + int z = (ctx.opcode.getType() == OPCODE_JP) ? 2 : 4; + Instr instr = new Instr(ctx.opcode, 3, y, z); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + return instr; + } + + @Override + public Node visitInstrRP_NN(InstrRP_NNContext ctx) { + // | opcode=OPCODE_LD rp=rRegPair SEP_COMMA nn=rExpression # instrRP_NN // x=0, z=1, q=0, p=rp + int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); + Instr instr = new Instr(ctx.opcode, 0, 0, p, 1); instr.addChild(CreateVisitors.expr.visit(ctx.nn)); return instr; } + + @Override + public Node visitInstrRP_RP(InstrRP_RPContext ctx) { + // | opcode=OPCODE_EX dst=REG_AF SEP_COMMA src=REG_AFF # instrRP_RP // x=0, z=0, q=1, p=0 + // | opcode=OPCODE_LD dst=REG_SP SEP_COMMA src=REG_HL # instrRP_RP // x=3, z=1, q=1, p=3 + // | opcode=OPCODE_EX dst=REG_DE SEP_COMMA src=REG_HL # instrRP_RP // x=3, z=3, q=1, p=2 + int x = (ctx.opcode.getType() == OPCODE_EX && ctx.dst.getType() == REG_AF) ? 0 : 3; + int z = (ctx.opcode.getType() == OPCODE_LD) ? 1 : ((ctx.dst.getType() == REG_AF) ? 0 : 3); + int p = (ctx.opcode.getType() == OPCODE_LD) ? 3 : ((ctx.dst.getType() == REG_AF) ? 0 : 2); + return new Instr(ctx.opcode, x, 1, p, z); + } + + @Override + public Node visitInstrNN(InstrNNContext ctx) { + // | opcode=OPCODE_JP nn=rExpression # instrNN // x=3, z=3, y=0 + // | opcode=OPCODE_CALL nn=rExpression # instrNN // x=3, z=5, y=1 + int z = (ctx.opcode.getType() == OPCODE_JP) ? 3 : 5; + int y = (ctx.opcode.getType() == OPCODE_JP) ? 0 : 1; + Instr instr = new Instr(ctx.opcode, 3, y, z); + instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + return instr; + } + + @Override + public Node visitInstrN(InstrNContext ctx) { + // | opcode=OPCODE_DJNZ n=rExpression # instrN // x=0, z=0, y=2 + // | opcode=OPCODE_JR n=rExpression # instrN // x=0, z=0, y=3 + // | opcode=OPCODE_OUT SEP_LPAR n=rExpression SEP_RPAR SEP_COMMA REG_A # instrN // x=3, z=3, y=2 + // | opcode=OPCODE_IN REG_A SEP_COMMA SEP_LPAR n=rExpression SEP_RPAR # instrN // x=3, z=3, y=3 + // | opcode=OPCODE_ADD REG_A SEP_COMMA n=rExpression # instrN // x=3, z=6, y=alu + // | opcode=OPCODE_ADC REG_A SEP_COMMA n=rExpression # instrN // x=3, z=6, y=alu + // | opcode=OPCODE_SUB n=rExpression # instrN // x=3, z=6, y=alu + // | opcode=OPCODE_SBC REG_A SEP_COMMA n=rExpression # instrN // x=3, z=6, y=alu + // | opcode=OPCODE_AND n=rExpression # instrN // x=3, z=6, y=alu + // | opcode=OPCODE_XOR n=rExpression # instrN // x=3, z=6, y=alu + // | opcode=OPCODE_OR n=rExpression # instrN // x=3, z=6, y=alu + // | opcode=OPCODE_CP n=rExpression # instrN // x=3, z=6, y=alu + // | opcode=OPCODE_RST n=rExpression # instrN // x=3, z=7, y=N/8 + int opcode = ctx.opcode.getType(); + + boolean djnzOrJr = opcode == OPCODE_DJNZ || opcode == OPCODE_JR; + boolean djnzOrOut = opcode == OPCODE_DJNZ || opcode == OPCODE_OUT; + boolean rst = opcode == OPCODE_RST; + + int x = (djnzOrJr) ? 0 : 3; + int z = (djnzOrJr) ? 0 : ((opcode == OPCODE_OUT || opcode == OPCODE_IN) ? 3 : (rst ? 7 : 6)); + int y = djnzOrOut ? 2 : ((opcode == OPCODE_JR || opcode == OPCODE_IN) ? 3 : (rst ? 0 : CompilerTables.alu.get(opcode))); + Instr instr = new Instr(ctx.opcode, x, y, z); + instr.addChild(CreateVisitors.expr.visit(ctx.n)); + return instr; + } + + @Override + public Node visitInstrRP(InstrRPContext ctx) { + // | opcode=OPCODE_ADD REG_HL SEP_COMMA rp=rRegPair # instrRP // x=0, z=1, q=1, p=rp + // | opcode=OPCODE_INC rp=rRegPair # instrRP // x=0, z=3, q=0, p=rp + // | opcode=OPCODE_DEC rp=rRegPair # instrRP // x=0, z=3, q=1, p=rp + int q = (ctx.opcode.getType() == OPCODE_INC) ? 0 : 1; + int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); + int z = (ctx.opcode.getType() == OPCODE_ADD) ? 1 : 3; + return new Instr(ctx.opcode, 0, q, p, z); + } + + @Override + public Node visitInstrRP2(InstrRP2Context ctx) { + // | opcode=OPCODE_POP rp2=rRegPair2 # instrRP2 // x=3, z=1, q=0, p=rp2 + // | opcode=OPCODE_PUSH rp2=rRegPair2 # instrRP2 // x=3, z=5, q=0, p=rp2 + int p = CompilerTables.regPairs2.get(ctx.rp2.start.getType()); + int z = (ctx.opcode.getType() == OPCODE_POP) ? 1 : 5; + return new Instr(ctx.opcode, 3, 0, p, z); + } + + @Override + public Node visitInstrR(InstrRContext ctx) { + // | opcode=OPCODE_ADD REG_A SEP_COMMA r=rRegister # instrR // x=2, y=alu, z=r + // | opcode=OPCODE_ADC REG_A SEP_COMMA r=rRegister # instrR // x=2, y=alu, z=r + // | opcode=OPCODE_SUB r=rRegister # instrR // x=2, y=alu, z=r + // | opcode=OPCODE_SBC REG_A SEP_COMMA r=rRegister # instrR // x=2, y=alu, z=r + // | opcode=OPCODE_AND r=rRegister # instrR // x=2, y=alu, z=r + // | opcode=OPCODE_XOR r=rRegister # instrR // x=2, y=alu, z=r + // | opcode=OPCODE_OR r=rRegister # instrR // x=2, y=alu, z=r + // | opcode=OPCODE_CP r=rRegister # instrR // x=2, y=alu, z=r + // | opcode=OPCODE_INC r=rRegister # instrR // x=0, z=4, y=r + // | opcode=OPCODE_DEC r=rRegister # instrR // x=0, z=5, y=r + int opcode = ctx.opcode.getType(); + boolean incDec = (opcode == OPCODE_INC || opcode == OPCODE_DEC); + int reg = CompilerTables.registers.get(ctx.r.r.getType()); + + int x = incDec ? 0 : 2; + int y = incDec ? reg : CompilerTables.alu.get(ctx.opcode.getType()); + int z = (opcode == OPCODE_INC) ? 4 : ((opcode == OPCODE_DEC) ? 5 : reg); + return new Instr(ctx.opcode, x, y, z); + } + + @Override + public Node visitInstr(InstrContext ctx) { + // | opcode=OPCODE_NOP # instr // x=0, z=0, y=0 + // | opcode=OPCODE_RLCA # instr // x=0, z=7, y=0 + // | opcode=OPCODE_RRCA # instr // x=0, z=7, y=1 + // | opcode=OPCODE_RLA # instr // x=0, z=7, y=2 + // | opcode=OPCODE_RRA # instr // x=0, z=7, y=3 + // | opcode=OPCODE_DAA # instr // x=0, z=7, y=4 + // | opcode=OPCODE_CPL # instr // x=0, z=7, y=5 + // | opcode=OPCODE_SCF # instr // x=0, z=7, y=6 + // | opcode=OPCODE_CCF # instr // x=0, z=7, y=7 + // | opcode=OPCODE_HALT # instr // x=1, z=6, y=6 + // | opcode=OPCODE_RET # instr // x=3, z=1, q=1, p=0 + // | opcode=OPCODE_EXX # instr // x=3, z=1, q=1, p=1 + // | opcode=OPCODE_DI # instr // x=3, z=3, y=6 + // | opcode=OPCODE_EI # instr // x=3, z=3, y=7 + + Map xyz = new HashMap<>(); + xyz.put(OPCODE_NOP, new int[] {0, 0, 0}); + xyz.put(OPCODE_RLCA, new int[] {0, 0, 7}); + xyz.put(OPCODE_RRCA, new int[] {0, 1, 7}); + xyz.put(OPCODE_RLA, new int[] {0, 2, 7}); + xyz.put(OPCODE_RRA, new int[] {0, 3, 7}); + xyz.put(OPCODE_DAA, new int[] {0, 4, 7}); + xyz.put(OPCODE_CPL, new int[] {0, 5, 7}); + xyz.put(OPCODE_SCF, new int[] {0, 6, 7}); + xyz.put(OPCODE_CCF, new int[] {0, 7, 7}); + xyz.put(OPCODE_HALT, new int[] {1, 6, 6}); + xyz.put(OPCODE_RET, new int[] {3, 1, 1}); + xyz.put(OPCODE_EXX, new int[] {3, 3, 1}); + xyz.put(OPCODE_DI, new int[] {3, 6, 3}); + xyz.put(OPCODE_EI, new int[] {3, 7, 3}); + + int[] xyzValues = xyz.get(ctx.opcode.getType()); + return new Instr(ctx.opcode, xyzValues[0], xyzValues[1], xyzValues[2]); + } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java index ee2a35476..6b3784c34 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java @@ -77,71 +77,19 @@ public void visit(Instr node) { visitChildren(node); } - public void visit(InstrA_Ref_RP node) { + public void visit(InstrCB node) { visitChildren(node); } - public void visit(InstrC node) { + public void visit(InstrED node) { visitChildren(node); } - public void visit(InstrC_N node) { + public void visit(InstrXD node) { visitChildren(node); } - public void visit(InstrC_NN node) { - visitChildren(node); - } - - public void visit(InstrN node) { - visitChildren(node); - } - - public void visit(InstrNN node) { - visitChildren(node); - } - - public void visit(InstrR node) { - visitChildren(node); - } - - public void visit(InstrR_N node) { - visitChildren(node); - } - - public void visit(InstrR_R node) { - visitChildren(node); - } - - public void visit(InstrR_Ref_NN node) { - visitChildren(node); - } - - public void visit(InstrRef_NN_R node) { - visitChildren(node); - } - - public void visit(InstrRef_RP node) { - visitChildren(node); - } - - public void visit(InstrRef_RP_RP node) { - visitChildren(node); - } - - public void visit(InstrRP node) { - visitChildren(node); - } - - public void visit(InstrRP_NN node) { - visitChildren(node); - } - - public void visit(InstrRP_Ref_NN node) { - visitChildren(node); - } - - public void visit(InstrRP_RP node) { + public void visit(InstrXDCB node) { visitChildren(node); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java index 8f857e965..4260566e7 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java @@ -43,7 +43,7 @@ public void testDBinstruction() { assertTrees( new Program() .addChild(new DataDB(0, 0) - .addChild(new Instr(0, 0, OPCODE_RET))), + .addChild(new Instr(0, 0, OPCODE_RET, x, y, z))), program ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java index 218bdb1c9..7de884cfc 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java @@ -176,7 +176,7 @@ public void testMOV() { private void assertInstrNoArgs(String instr, int instrType) { forStringCaseVariations(instr, variation -> { Program program = parseProgram(variation); - assertTrees(new Program().addChild(new Instr(0, 0, instrType)), program); + assertTrees(new Program().addChild(new Instr(0, 0, instrType, x, y, z)), program); }); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java index 7367cc097..5d0131a19 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java @@ -5,7 +5,6 @@ import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrN; import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; import net.emustudio.plugins.compiler.asZ80.exceptions.SyntaxErrorException; @@ -62,8 +61,8 @@ public void testIf() { .addChild(new PseudoIf(0, 0) .addChild(new PseudoIfExpression(0, 0) .addChild(new ExprNumber(0, 0, 1))) - .addChild(new Instr(0, 0, OPCODE_RRC)) - .addChild(new Instr(0, 0, OPCODE_RRC))), + .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)) + .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z))), program ); } @@ -130,7 +129,7 @@ public void testMacroDef() { .addChild(new ExprId(0, 0, "param1"))) .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "param2"))) - .addChild(new Instr(0, 0, OPCODE_RRC)) + .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)) .addChild(new PseudoLabel(0, 0, "heylabel") .addChild(new InstrN(0, 0, OPCODE_ANI) .addChild(new ExprNumber(0, 0, 0x7F))))); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java index 754039dec..10ecd0e6f 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java @@ -6,9 +6,6 @@ import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrN; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrR_N; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRP_NN; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroArgument; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroCall; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoOrg; diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java index f0c8f422f..a323a911a 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java @@ -9,10 +9,7 @@ import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrN; import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrR_N; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrRP_NN; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; import org.junit.Test; @@ -458,13 +455,13 @@ public void testLabelKeepsChildren() { Program program = new Program(); program .addChild(new PseudoLabel(0, 0, "label") - .addChild(new Instr(0, 0, OPCODE_RET))); + .addChild(new Instr(0, 0, OPCODE_RET, x, y, z))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program().addChild(new Instr(0, 0, OPCODE_RET)), + new Program().addChild(new Instr(0, 0, OPCODE_RET, x, y, z)), program ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java index 60713c15e..939b35ebe 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java @@ -5,7 +5,6 @@ import net.emustudio.plugins.compiler.asZ80.ast.Program; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrR_N; import net.emustudio.plugins.compiler.asZ80.exceptions.FatalError; import org.junit.Rule; import org.junit.Test; @@ -31,11 +30,11 @@ public void testExpandInclude() { visitor.visit(program); Node expected = new Program() - .addChild(new Instr(0, 0, OPCODE_CMC)) + .addChild(new Instr(0, 0, OPCODE_CMC, x, y, z)) .addChild(new PseudoLabel(0, 0, "sample") .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) .addChild(new ExprNumber(0, 0, 0)))) - .addChild(new Instr(0, 0, OPCODE_RET)); + .addChild(new Instr(0, 0, OPCODE_RET, x, y, z)); assertTrees(expected, program); } @@ -53,8 +52,8 @@ public void testExpandIncludeTwoTimes() throws IOException { visitor.visit(program); Node expected = new Program() - .addChild(new Instr(0, 0, OPCODE_RRC)) - .addChild(new Instr(0, 0, OPCODE_RRC)); + .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)) + .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)); assertTrees(expected, program); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java index 7c6773b92..06f69eb7c 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java @@ -74,7 +74,7 @@ public void testPseudoOrg() { .addChild(new Evaluated(0, 0, 0x400))) .addChild(new PseudoOrg(0, 0) .addChild(new Evaluated(0, 0, 0))) - .addChild(new Instr(0, 0, OPCODE_XCHG)); + .addChild(new Instr(0, 0, OPCODE_XCHG, x, y, z)); IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); @@ -91,7 +91,7 @@ public void testPseudoOrg() { public void testGenerateInstructions() { Program program = new Program(); program - .addChild(new Instr(0, 0, OPCODE_NOP)) + .addChild(new Instr(0, 0, OPCODE_NOP, x, y, z)) .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) .addChild(new Evaluated(0, 0, 0x1234))) .addChild(new InstrRP(0, 0, OPCODE_STAX, REG_B)) @@ -100,7 +100,7 @@ public void testGenerateInstructions() { .addChild(new InstrR(0, 0, OPCODE_DCR, REG_B)) .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_B) .addChild(new Evaluated(0, 0, 7))) - .addChild(new Instr(0, 0, OPCODE_RLC)) + .addChild(new Instr(0, 0, OPCODE_RLC, x, y, z)) .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_B)) .addChild(new InstrRP(0, 0, OPCODE_LDAX, REG_B)) .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_B)) @@ -108,7 +108,7 @@ public void testGenerateInstructions() { .addChild(new InstrR(0, 0, OPCODE_DCR, REG_C)) .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_C) .addChild(new Evaluated(0, 0, 8))) - .addChild(new Instr(0, 0, OPCODE_RRC)) + .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)) .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_D) .addChild(new Evaluated(0, 0, 0x2345))) .addChild(new InstrRP(0, 0, OPCODE_STAX, REG_D)) @@ -117,7 +117,7 @@ public void testGenerateInstructions() { .addChild(new InstrR(0, 0, OPCODE_DCR, REG_D)) .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_D) .addChild(new Evaluated(0, 0, 9))) - .addChild(new Instr(0, 0, OPCODE_RAL)) + .addChild(new Instr(0, 0, OPCODE_RAL, x, y, z)) .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_D)) .addChild(new InstrRP(0, 0, OPCODE_LDAX, REG_D)) .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_D)) @@ -125,7 +125,7 @@ public void testGenerateInstructions() { .addChild(new InstrR(0, 0, OPCODE_DCR, REG_E)) .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_E) .addChild(new Evaluated(0, 0, 10))) - .addChild(new Instr(0, 0, OPCODE_RAR)) + .addChild(new Instr(0, 0, OPCODE_RAR, x, y, z)) .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_H) .addChild(new Evaluated(0, 0, 0x2345))) .addChild(new InstrN(0, 0, OPCODE_SHLD) @@ -135,7 +135,7 @@ public void testGenerateInstructions() { .addChild(new InstrR(0, 0, OPCODE_DCR, REG_H)) .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_H) .addChild(new Evaluated(0, 0, 0x28))) - .addChild(new Instr(0, 0, OPCODE_DAA)) + .addChild(new Instr(0, 0, OPCODE_DAA, x, y, z)) .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_H)) .addChild(new InstrN(0, 0, OPCODE_LHLD) .addChild(new Evaluated(0, 0, 0x2345))) @@ -144,7 +144,7 @@ public void testGenerateInstructions() { .addChild(new InstrR(0, 0, OPCODE_DCR, REG_L)) .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_L) .addChild(new Evaluated(0, 0, 10))) - .addChild(new Instr(0, 0, OPCODE_CMA)) + .addChild(new Instr(0, 0, OPCODE_CMA, x, y, z)) .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_SP) .addChild(new Evaluated(0, 0, 0x2345))) .addChild(new InstrN(0, 0, OPCODE_STA) @@ -154,7 +154,7 @@ public void testGenerateInstructions() { .addChild(new InstrR(0, 0, OPCODE_DCR, REG_M)) .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_M) .addChild(new Evaluated(0, 0, 7))) - .addChild(new Instr(0, 0, OPCODE_STC)) + .addChild(new Instr(0, 0, OPCODE_STC, x, y, z)) .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_SP)) .addChild(new InstrN(0, 0, OPCODE_LDA) .addChild(new Evaluated(0, 0, 0x2345))) @@ -163,7 +163,7 @@ public void testGenerateInstructions() { .addChild(new InstrR(0, 0, OPCODE_DCR, REG_A)) .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) .addChild(new Evaluated(0, 0, -128))) - .addChild(new Instr(0, 0, OPCODE_CMC)) + .addChild(new Instr(0, 0, OPCODE_CMC, x, y, z)) .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_B)) .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_C)) .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_D)) @@ -292,7 +292,7 @@ public void testGenerateInstructions() { .addChild(new InstrR(0, 0, OPCODE_CMP, REG_L)) .addChild(new InstrR(0, 0, OPCODE_CMP, REG_M)) .addChild(new InstrR(0, 0, OPCODE_CMP, REG_A)) - .addChild(new Instr(0, 0, OPCODE_RNZ)) + .addChild(new Instr(0, 0, OPCODE_RNZ, x, y, z)) .addChild(new InstrRP(0, 0, OPCODE_POP, REG_B)) .addChild(new InstrN(0, 0, OPCODE_JNZ) .addChild(new Evaluated(0, 0, 2))) @@ -305,8 +305,8 @@ public void testGenerateInstructions() { .addChild(new Evaluated(0, 0, 0xF0))) .addChild(new InstrN(0, 0, OPCODE_RST) .addChild(new Evaluated(0, 0, 0))) - .addChild(new Instr(0, 0, OPCODE_RZ)) - .addChild(new Instr(0, 0, OPCODE_RET)) + .addChild(new Instr(0, 0, OPCODE_RZ, x, y, z)) + .addChild(new Instr(0, 0, OPCODE_RET, x, y, z)) .addChild(new InstrN(0, 0, OPCODE_JZ) .addChild(new Evaluated(0, 0, 0x1234))) .addChild(new InstrN(0, 0, OPCODE_CZ) @@ -317,7 +317,7 @@ public void testGenerateInstructions() { .addChild(new Evaluated(0, 0, 0xF0))) .addChild(new InstrN(0, 0, OPCODE_RST) .addChild(new Evaluated(0, 0, 1))) - .addChild(new Instr(0, 0, OPCODE_RNC)) + .addChild(new Instr(0, 0, OPCODE_RNC, x, y, z)) .addChild(new InstrRP(0, 0, OPCODE_POP, REG_D)) .addChild(new InstrN(0, 0, OPCODE_JNC) .addChild(new Evaluated(0, 0, 0x1234))) @@ -330,7 +330,7 @@ public void testGenerateInstructions() { .addChild(new Evaluated(0, 0, 0xF0))) .addChild(new InstrN(0, 0, OPCODE_RST) .addChild(new Evaluated(0, 0, 2))) - .addChild(new Instr(0, 0, OPCODE_RC)) + .addChild(new Instr(0, 0, OPCODE_RC, x, y, z)) .addChild(new InstrN(0, 0, OPCODE_JC) .addChild(new Evaluated(0, 0, 0x1234))) .addChild(new InstrN(0, 0, OPCODE_IN) @@ -341,11 +341,11 @@ public void testGenerateInstructions() { .addChild(new Evaluated(0, 0, 0xF0))) .addChild(new InstrN(0, 0, OPCODE_RST) .addChild(new Evaluated(0, 0, 3))) - .addChild(new Instr(0, 0, OPCODE_RPO)) + .addChild(new Instr(0, 0, OPCODE_RPO, x, y, z)) .addChild(new InstrRP(0, 0, OPCODE_POP, REG_H)) .addChild(new InstrN(0, 0, OPCODE_JPO) .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new Instr(0, 0, OPCODE_XTHL)) + .addChild(new Instr(0, 0, OPCODE_XTHL, x, y, z)) .addChild(new InstrN(0, 0, OPCODE_CPO) .addChild(new Evaluated(0, 0, 0x1234))) .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_H)) @@ -353,22 +353,22 @@ public void testGenerateInstructions() { .addChild(new Evaluated(0, 0, 0xF0))) .addChild(new InstrN(0, 0, OPCODE_RST) .addChild(new Evaluated(0, 0, 4))) - .addChild(new Instr(0, 0, OPCODE_RPE)) - .addChild(new Instr(0, 0, OPCODE_PCHL)) + .addChild(new Instr(0, 0, OPCODE_RPE, x, y, z)) + .addChild(new Instr(0, 0, OPCODE_PCHL, x, y, z)) .addChild(new InstrN(0, 0, OPCODE_JPE) .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new Instr(0, 0, OPCODE_XCHG)) + .addChild(new Instr(0, 0, OPCODE_XCHG, x, y, z)) .addChild(new InstrN(0, 0, OPCODE_CPE) .addChild(new Evaluated(0, 0, 0x1234))) .addChild(new InstrN(0, 0, OPCODE_XRI) .addChild(new Evaluated(0, 0, 0xF0))) .addChild(new InstrN(0, 0, OPCODE_RST) .addChild(new Evaluated(0, 0, 5))) - .addChild(new Instr(0, 0, OPCODE_RP)) + .addChild(new Instr(0, 0, OPCODE_RP, x, y, z)) .addChild(new InstrRP(0, 0, OPCODE_POP, REG_PSW)) .addChild(new InstrN(0, 0, OPCODE_JP) .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new Instr(0, 0, OPCODE_DI)) + .addChild(new Instr(0, 0, OPCODE_DI, x, y, z)) .addChild(new InstrN(0, 0, OPCODE_CP) .addChild(new Evaluated(0, 0, 0x200))) .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_PSW)) @@ -376,11 +376,11 @@ public void testGenerateInstructions() { .addChild(new Evaluated(0, 0, 0xF0))) .addChild(new InstrN(0, 0, OPCODE_RST) .addChild(new Evaluated(0, 0, 6))) - .addChild(new Instr(0, 0, OPCODE_RM)) - .addChild(new Instr(0, 0, OPCODE_SPHL)) + .addChild(new Instr(0, 0, OPCODE_RM, x, y, z)) + .addChild(new Instr(0, 0, OPCODE_SPHL, x, y, z)) .addChild(new InstrN(0, 0, OPCODE_JM) .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new Instr(0, 0, OPCODE_EI)) + .addChild(new Instr(0, 0, OPCODE_EI, x, y, z)) .addChild(new InstrN(0, 0, OPCODE_CM) .addChild(new Evaluated(0, 0, 0x200))) .addChild(new InstrN(0, 0, OPCODE_CPI) diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java index 23df14a75..291d4ac5f 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java @@ -5,7 +5,6 @@ import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrR_N; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; import org.junit.Test; From 65b3737faffb940f315403309602afb2f0485bd5 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 17 Feb 2022 09:30:25 +0100 Subject: [PATCH 098/314] [#201] as-z80: finish compiler draft --- .../plugins/compiler/asZ80/ast/Node.java | 32 ++- .../compiler/asZ80/ast/instr/Instr.java | 20 +- .../compiler/asZ80/ast/instr/InstrCB.java | 7 + .../compiler/asZ80/ast/instr/InstrED.java | 7 + .../compiler/asZ80/ast/instr/InstrXD.java | 7 + .../compiler/asZ80/ast/instr/InstrXDCB.java | 8 + .../plugins/compiler/asZ80/tree/OC_Expr.java | 243 ------------------ .../compiler/asZ80/tree/OC_ExprExpr.java | 87 ------- .../compiler/asZ80/tree/OC_NoParams.java | 158 ------------ .../plugins/compiler/asZ80/tree/OC_Reg.java | 76 ------ .../compiler/asZ80/tree/OC_RegExpr.java | 112 -------- .../asZ80/visitors/CheckExprSizesVisitor.java | 41 ++- .../asZ80/visitors/CreateInstrVisitor.java | 159 ++++++------ .../asZ80/visitors/EvaluateExprVisitor.java | 48 ++-- .../asZ80/visitors/GenerateCodeVisitor.java | 85 +++--- .../plugins/compiler/asZ80/OC_RegTest.java | 1 - 16 files changed, 256 insertions(+), 835 deletions(-) delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Expr.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_ExprExpr.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_NoParams.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Reg.java delete mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_RegExpr.java diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java index b17662309..b46025afd 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java @@ -13,6 +13,8 @@ public abstract class Node { public final int column; private int address; + private Optional maxValue; + private Optional sizeBytes; public Node(int line, int column) { this.line = line; @@ -46,10 +48,6 @@ public List getChildren() { return List.copyOf(children); } - public int getChildrenCount() { - return children.size(); - } - public Optional collectChild(Class cl) { for (Node child : children) { if (cl.isInstance(child)) { @@ -139,4 +137,30 @@ public boolean equals(Object o) { if (this == o) return true; return !(o == null || getClass() != o.getClass()); } + + public Optional getMaxValue() { + return maxValue; + } + public Optional getSizeBytes() { + return sizeBytes; + } + + public Node setMaxValue(int maxValue) { + int wasBits = (int) Math.floor(Math.log10(Math.abs(maxValue)) / Math.log10(2)) + 1; + this.sizeBytes = Optional.of((int) Math.ceil(wasBits / 8.0)); + this.maxValue = Optional.of(maxValue); + return this; + } + + public Node setSizeBytes(int bytes) { + int value = 0; + for (int i = 0; i < bytes; i++) { + value <<= 8; + value |= 0xFF; + } + + this.sizeBytes = Optional.of(bytes); + this.maxValue = Optional.of(value); + return this; + } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java index 9aa35858b..f392e0b04 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java @@ -1,16 +1,23 @@ package net.emustudio.plugins.compiler.asZ80.ast.instr; +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; import net.emustudio.plugins.compiler.asZ80.ast.Node; import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; -import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.OPCODE_RST; public class Instr extends Node { public final int opcode; public final int x; public final int y; public final int z; + private final static Set allowedRstValues = Set.of( + 0, 0x8, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38 + ); public Instr(int line, int column, int opcode, int x, int y, int z) { super(line, column); @@ -30,6 +37,17 @@ public Instr(Token opcode, int x, int q, int p, int z) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), x, (p << 1) | q, z); } + public Optional eval() { + Optional actualY = Optional.of(y); + if (opcode == OPCODE_RST) { + actualY = collectChild(Evaluated.class) + .map(e -> e.value) + .filter(allowedRstValues::contains) + .map(v -> v / 8); + } + return actualY.map(yy -> (byte)(((x << 6) | (yy << 3) | (z & 7)) & 0xFF)); + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java index 01398b261..b938b3990 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java @@ -44,6 +44,13 @@ public InstrCB(Token opcode, int y, int z) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), y, z); } + public byte[] eval() { + return new byte[] { + (byte)0xCB, + (byte)(((x << 6) | (y << 3) | (z & 7)) & 0xFF) + }; + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java index cdc91f9d2..d2b855813 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java @@ -62,6 +62,13 @@ public InstrED(Token opcode, int q, int p, int z) { this(opcode, (p << 1) | q, z); } + public byte[] eval() { + return new byte[] { + (byte)0xED, + (byte)(((x << 6) | (y << 3) | (z & 7)) & 0xFF) + }; + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java index f2f53a424..2a00b380b 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java @@ -31,6 +31,13 @@ public InstrXD(Token opcode, int prefix, int x, int q, int p, int z) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), prefix, x, (p << 1) | q, z); } + public byte[] eval() { + return new byte[] { + (byte)prefix, + (byte)(((x << 6) | (y << 3) | (z & 7)) & 0xFF) + }; + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java index 75bea0d8b..628dce54f 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java @@ -51,6 +51,14 @@ public InstrXDCB(Token opcode, int prefix, int y, int z) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), prefix, y, z); } + public byte[] eval() { + return new byte[] { + (byte)prefix, + (byte)0xCB, + (byte)(((x << 6) | (y << 3) | (z & 7)) & 0xFF) + }; + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Expr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Expr.java deleted file mode 100644 index 2f3a0196f..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Expr.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - - -public class OC_Expr { -// public static final int ADC = 0xCE00; // ADC A,N -// public static final int ADC_A_IIX_NN = 0xDD8E00; // ADC A, (IX+N) -// public static final int ADC_A_IIY_NN = 0xFD8E00; // ADC A, (IY+N) -// public static final int ADD = 0xC600; // ADD A,N -// public static final int ADD_A_IIX_NN = 0xDD8600; // ADD A, (IX+N) -// public static final int ADD_A_IIY_NN = 0xFD8600; // ADD A, (IY+N) -// public static final int AND = 0xE600; // AND N -// public static final int AND_IIX_NN = 0xDDA600; // AND (IX+N) -// public static final int AND_IIY_NN = 0xFDA600; // AND (IY+N) -// public static final int BIT = 0xCB46; // BIT b,(HL) -// public static final int CALL = 0xCD0000; // CALL NN -// public static final int CP = 0xFE00; // CP N -// public static final int CP_IIX_NN = 0xDDBE00; // CP (IX+N) -// public static final int CP_IIY_NN = 0xFDBE00; // CP (IY+N) -// public static final int DEC_IIX_NN = 0xDD3500; // DEC (IX+N) -// public static final int DEC_IIY_NN = 0xFD3500; // DEC (IY+N) -// public static final int DJNZ = 0x1000; // DJNZ N -// public static final int IM = 0xED00; // IM N -// public static final int IN = 0xDB00; // IN A, (N) -// public static final int INC_IIX_NN = 0xDD3400; // INC (IX+N) -// public static final int INC_IIY_NN = 0xFD3400; // INC (IY+N) -// public static final int JP = 0xC30000; // JP NN -// public static final int JR = 0x1800; // JR N -// public static final int LD_A = 0x3E00; // LD A,N -// public static final int LD_A_IIX_NN = 0xDD7E00; // LD A,(IX+N) -// public static final int LD_A_IIY_NN = 0xFD7E00; // LD A,(IY+N) -// public static final int LD_A_NN = 0x3A0000; // LD A,(NN) -// public static final int LD_B = 0x0600; // LD B,N -// public static final int LD_C = 0x0E00; // LD C,N -// public static final int LD_D = 0x1600; // LD D,N -// public static final int LD_E = 0x1E00; // LD E,N -// public static final int LD_H = 0x2600; // LD H,N -// public static final int LD_L = 0x2E00; // LD L,N -// public static final int LD_B_IIX_NN = 0xDD4600; // LD B,(IX+N) -// public static final int LD_B_IIY_NN = 0xFD4600; // LD B,(IY+N) -// public static final int LD_C_IIX_NN = 0xDD4E00; // LD C,(IX+N) -// public static final int LD_C_IIY_NN = 0xFD4E00; // LD C,(IY+N) -// public static final int LD_D_IIX_NN = 0xDD5600; // LD D,(IX+N) -// public static final int LD_D_IIY_NN = 0xFD5600; // LD D,(IY+N) -// public static final int LD_E_IIX_NN = 0xDD5E00; // LD E,(IX+N) -// public static final int LD_E_IIY_NN = 0xFD5E00; // LD E,(IY+N) -// public static final int LD_H_IIX_NN = 0xDD6600; // LD H,(IX+N) -// public static final int LD_H_IIY_NN = 0xFD6600; // LD H,(IY+N) -// public static final int LD_L_IIX_NN = 0xDD6E00; // LD L,(IX+N) -// public static final int LD_L_IIY_NN = 0xFD6E00; // LD L,(IY+N) -// public static final int LD_BC_NN = 0xED4B0000; // LD BC,(NN) -// public static final int LD_DE_NN = 0xED5B0000; // LD DE,(NN) -// public static final int LD_HL_NN = 0x2A0000; // LD HL,(NN) -// public static final int LD_SP_NN = 0xED7B0000; // LD SP,(NN) -// public static final int LD_IX_NN = 0xDD2A0000; // LD IX,(NN) -// public static final int LD_IY_NN = 0xFD2A0000; // LD IY,(NN) -// public static final int LD_IX = 0xDD210000; // LD IX,NN -// public static final int LD_IY = 0xFD210000; // LD IY,NN -// public static final int LD_HHLL = 0x3600; // LD (HL),N -// public static final int LD_NN_A = 0x320000; // LD (NN),A -// public static final int LD_NN_BC = 0xED430000; // LD (NN),BC -// public static final int LD_NN_DE = 0xED530000; // LD (NN),DE -// public static final int LD_NN_HL = 0x220000; // LD (NN),HL -// public static final int LD_NN_SP = 0xED730000; // LD (NN),SP -// public static final int LD_NN_IX = 0xDD220000; // LD (NN),IX -// public static final int LD_NN_IY = 0xFD220000; // LD (NN),IY -// public static final int OR = 0xF600; // OR N -// public static final int OR_IIX_NN = 0xDDB600; // OR (IX+N) -// public static final int OR_IIY_NN = 0xFDB600; // OR (IY+N) -// public static final int OUT = 0xD300; // OUT (N),A -// public static final int RES = 0xCB86; // RES b,(HL) -// public static final int RL_IIX_NN = 0xDDCB0016; // RL (IX+N) -// public static final int RL_IIY_NN = 0xFDCB0016; // RL (IY+N) -// public static final int RLC_IIX_NN = 0xDDCB0006; // RLC (IX+N) -// public static final int RLC_IIY_NN = 0xFDCB0006; // RLC (IY+N) -// public static final int RR_IIX_NN = 0xDDCB001E; // RR (IX+N) -// public static final int RR_IIY_NN = 0xFDCB001E; // RR (IY+N) -// public static final int RRC_IIX_NN = 0xDDCB000E; // RRC (IX+N) -// public static final int RRC_IIY_NN = 0xFDCB000E; // RRC (IY+N) -// public static final int RST = 0xC7; -// public static final int SBC = 0xDE00; // SBC A,N -// public static final int SBC_A_IIX_NN = 0xDD9E00; // SBC A,(IX+N) -// public static final int SBC_A_IIY_NN = 0xFD9E00; // SBC A,(IY+N) -// public static final int SET = 0xCBC6; // SET b,(HL) -// public static final int SLA_IIX_NN = 0xDDCB0026; // SLA (IX+N) -// public static final int SLA_IIY_NN = 0xFDCB0026; // SLA (IY+N) -// public static final int SRA_IIX_NN = 0xDDCB002E; // SRA (IX+N) -// public static final int SRA_IIY_NN = 0xFDCB002E; // SRA (IY+N) -// public static final int SLL_IIX_NN = 0xDDCB0036; // SLL (IX+N) -// public static final int SLL_IIY_NN = 0xFDCB0036; // SLL (IY+N) -// public static final int SRL_IIX_NN = 0xDDCB003E; // SRL (IX+N) -// public static final int SRL_IIY_NN = 0xFDCB003E; // SRL (IY+N) -// public static final int SUB = 0xD600; // SUB N -// public static final int SUB_IIX_NN = 0xDD9600; // SUB (IX+N) -// public static final int SUB_IIY_NN = 0xFD9600; // SUB (IY+N) -// public static final int XOR = 0xEE00; // XOR N -// public static final int XOR_IIX_NN = 0xDDAE00; // XOR (IX+N) -// public static final int XOR_IIY_NN = 0xFDAE00; // XOR (IY+N) -// -// private final Expression expr; -// private final boolean oneByte; -// private final int old_opcode; -// -// public OC_Expr(int opcode, Expression expr, boolean oneByte, int line, int column) { -// super(opcode, line, column); -// this.old_opcode = opcode; -// this.expr = expr; -// this.oneByte = oneByte; -// } -// -// @Override -// public void pass1() { -// } -// -// @Override -// public int pass2(Namespace parentEnv, int addr_start) throws Exception { -// expr.eval(parentEnv, addr_start); -// int val = expr.getValue(); -// -// opcode = old_opcode; -// switch (opcode) { -// case DJNZ: -// case JR: -// opcode += computeRelativeAddress(line, column, addr_start, val); -// break; -// case BIT: -// case RES: -// case SET: -// if ((val > 7) || (val < 0)) { -// throw new ValueOutOfBoundsException(line, column, 0, 7, val); -// } -// opcode += (8 * val); -// break; -// case IM: -// switch (val) { -// case 0: -// opcode += 0x46; -// break; -// case 1: -// opcode += 0x56; -// break; -// case 2: -// opcode += 0x5E; -// break; -// default: -// throw new CompilerException(line, column, "Error: value can be only 0,1 or 2"); -// } -// break; -// case RL_IIX_NN: -// case RL_IIY_NN: -// case RLC_IIX_NN: -// case RLC_IIY_NN: -// case RR_IIX_NN: -// case RR_IIY_NN: -// case RRC_IIX_NN: -// case RRC_IIY_NN: -// case SLA_IIX_NN: -// case SLA_IIY_NN: -// case SRA_IIX_NN: -// case SRA_IIY_NN: -// case SLL_IIX_NN: -// case SLL_IIY_NN: -// case SRL_IIX_NN: -// case SRL_IIY_NN: -// if (oneByte && (val & 0xFFF) > 0xFF) { -// throw new ValueTooBigException(line, column, val, 0xFF); -// } -// opcode += ((val << 8) & 0xFF00); -// break; -// case RST: -// switch (val) { -// case 0: -// break; -// case 8: -// opcode = 0xCF; -// break; -// case 0x10: -// opcode = 0xD7; -// break; -// case 0x18: -// opcode = 0xDF; -// break; -// case 0x20: -// opcode = 0xE7; -// break; -// case 0x28: -// opcode = 0xEF; -// break; -// case 0x30: -// opcode = 0xF7; -// break; -// case 0x38: -// opcode = 0xFF; -// break; -// default: -// throw new CompilerException(line, column, " Error: value can be only 0,8h,10h,18h,20h,28h,30h or 38h"); -// } -// break; -// default: -// if (oneByte) { -// if ((val & 0xFFF) > 0xFF) { -// throw new ValueTooBigException(line, column, val, 0xFF); -// } -// opcode += Expression.reverseBytes(val, 1); -// } else { -// opcode += Expression.reverseBytes(val, 2); -// } -// } -// return (addr_start + getSize()); -// } -// -// @Override -// public void generateCode(IntelHEX hex) { -// String s; -// if (getSize() == 1) { -// s = "%1$02X"; -// } else if (getSize() == 2) { -// s = "%1$04X"; -// } else if (getSize() == 3) { -// s = "%1$06X"; -// } else { -// s = "%1$08X"; -// } -// hex.putCode(String.format(s, opcode)); -// } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_ExprExpr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_ExprExpr.java deleted file mode 100644 index 9a66104ba..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_ExprExpr.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - - -public class OC_ExprExpr { -// public static final int LD_IIX_NN = 0xDD360000; // LD (IX+N),N -// public static final int LD_IIY_NN = 0xFD360000; // LD (IY+N),N -// public static final int BIT_IIX_NN = 0xDDCB0046; // BIT b,(IIX+N) -// public static final int BIT_IIY_NN = 0xFDCB0046; // BIT b,(IIY+N) -// public static final int RES_IIX_NN = 0xDDCB0086; // RES b,(IIX+N) -// public static final int RES_IIY_NN = 0xFDCB0086; // RES b,(IIY+N) -// public static final int SET_IIX_NN = 0xDDCB00C6; // SET b,(IIX+N) -// public static final int SET_IIY_NN = 0xFDCB00C6; // SET b,(IIY+N) -// private Expression e1; -// private Expression e2; -// private boolean bitInstr; -// private int old_opcode; -// -// public OC_ExprExpr(int opcode, Expression e1, Expression e2, boolean bitInstr, int line, int column) { -// super(opcode, line, column); -// this.e1 = e1; -// this.e2 = e2; -// this.bitInstr = bitInstr; -// this.old_opcode = opcode; -// } -// -// @Override -// public void pass1() { -// } -// -// @Override -// public int pass2(Namespace parentEnv, int addr_start) throws Exception { -// e1.eval(parentEnv, addr_start); -// e2.eval(parentEnv, addr_start); -// -// int val1 = e1.getValue(); -// int val2 = e2.getValue(); -// if (Expression.getSize(val1) > 1) { -// throw new ValueTooBigException(line, column, val1, 0xFF); -// } -// if (Expression.getSize(val2) > 1) { -// throw new ValueTooBigException(line, column, val2, 0xFF); -// } -// opcode = old_opcode; -// if (bitInstr) { -// if ((val1 > 7) || (val1 < 0)) { -// throw new CompilerException(line, column, "Error: value(1) can be only in range 0-7"); -// } -// opcode += (val2 << 8) + (8 * val1); -// } else { -// opcode += ((val1 << 8) + val2); -// } -// return (addr_start + getSize()); -// } -// -// @Override -// public void generateCode(IntelHEX hex) { -// String s; -// if (getSize() == 1) { -// s = "%1$02X"; -// } else if (getSize() == 2) { -// s = "%1$04X"; -// } else if (getSize() == 3) { -// s = "%1$06X"; -// } else { -// s = "%1$08X"; -// } -// hex.putCode(String.format(s, opcode)); -// } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_NoParams.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_NoParams.java deleted file mode 100644 index 8a7d643c2..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_NoParams.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - - -public class OC_NoParams { -// public static final int ADC_A_HHLL = 0x8E; -// public static final int ADD_A_HHLL = 0x86; -// public static final int AND_HHLL = 0xA6; -// public static final int CCF = 0x3F; -// public static final int CP_HHLL = 0xBE; -// public static final int CPD = 0xEDA9; -// public static final int CPDR = 0xEDB9; -// public static final int CPI = 0xEDA1; -// public static final int CPIR = 0xEDB1; -// public static final int CPL = 0x2F; -// public static final int DAA = 0x27; -// public static final int DEC = 0x0B; -// public static final int DEC_A = 0x3D; -// public static final int DEC_B = 0x05; -// public static final int DEC_C = 0x0D; -// public static final int DEC_D = 0x15; -// public static final int DEC_E = 0x1D; -// public static final int DEC_H = 0x25; -// public static final int DEC_L = 0x2D; -// public static final int DEC_HHLL = 0x35; -// public static final int DEC_IX = 0xDD2B; -// public static final int DEC_IY = 0xFD2B; -// public static final int DI = 0xF3; -// public static final int EI = 0xFB; -// public static final int EX_SSPP_HL = 0xE3; -// public static final int EX_SSPP_IX = 0xDDE3; -// public static final int EX_SSPP_IY = 0xFDE3; -// public static final int EX_AF_AFF = 0x08; -// public static final int EX_DDEE_HL = 0xEB; -// public static final int EXX = 0xD9; -// public static final int HALT = 0x76; -// public static final int IN_A = 0xED78; -// public static final int IN_B = 0xED40; -// public static final int IN_C = 0xED48; -// public static final int IN_D = 0xED50; -// public static final int IN_E = 0xED58; -// public static final int IN_H = 0xED60; -// public static final int IN_L = 0xED68; -// public static final int INC_A = 0x3C; -// public static final int INC_B = 0x04; -// public static final int INC_C = 0x0C; -// public static final int INC_D = 0x14; -// public static final int INC_E = 0x1C; -// public static final int INC_H = 0x24; -// public static final int INC_L = 0x2C; -// public static final int INC_IX = 0xDD23; -// public static final int INC_IY = 0xFD23; -// public static final int INC_HHLL = 0x34; -// public static final int IND = 0xEDAA; -// public static final int INDR = 0xEDBA; -// public static final int INI = 0xEDA2; -// public static final int INIR = 0xEDB2; -// public static final int JP_HHLL = 0xE9; -// public static final int JP_IIXX = 0xDDE9; -// public static final int JP_IIYY = 0xFDE9; -// public static final int LD_I = 0xED47; // LD I,A -// public static final int LD_R = 0xED4F; // LD R,A -// public static final int LD_A_I = 0xED57; // LD A,I -// public static final int LD_A_R = 0xED5F; // LD A,R -// public static final int LD_A_BBCC = 0x0A; -// public static final int LD_A_DDEE = 0x1A; -// public static final int LD_A_HHLL = 0x7E; -// public static final int LD_B_HHLL = 0x46; -// public static final int LD_C_HHLL = 0x4E; -// public static final int LD_D_HHLL = 0x56; -// public static final int LD_E_HHLL = 0x5E; -// public static final int LD_H_HHLL = 0x66; -// public static final int LD_L_HHLL = 0x6E; -// public static final int LD_SP_HL = 0xF9; -// public static final int LD_SP_IX = 0xDDF9; -// public static final int LD_SP_IY = 0xFDF9; -// public static final int LD_BBCC_A = 0x02; -// public static final int LD_DDEE_A = 0x12; -// public static final int LDD = 0xEDA8; -// public static final int LDDR = 0xEDB8; -// public static final int LDI = 0xA0; -// public static final int LDIR = 0xB0; -// public static final int NEG = 0xED44; -// public static final int NOP = 0; -// public static final int OR_HHLL = 0xB6; -// public static final int OTDR = 0xEDBB; -// public static final int OTIR = 0xEDB3; -// public static final int OUT_A = 0xED79; -// public static final int OUT_B = 0xED41; -// public static final int OUT_C = 0xED49; -// public static final int OUT_D = 0xED51; -// public static final int OUT_E = 0xED59; -// public static final int OUT_H = 0xED61; -// public static final int OUT_L = 0xED69; -// public static final int OUTD = 0xEDAB; -// public static final int OUTI = 0xEDA3; -// public static final int POP_IX = 0xDDE1; -// public static final int POP_IY = 0xFDE1; -// public static final int PUSH_IX = 0xDDE5; -// public static final int PUSH_IY = 0xFDE5; -// public static final int RET = 0xC9; -// public static final int RETI = 0xED4D; -// public static final int RETN = 0xED45; -// public static final int RL_HHLL = 0xCB16; -// public static final int RLA = 0x17; -// public static final int RLC_HHLL = 0xCB06; -// public static final int RLCA = 0x7; -// public static final int RLD = 0xED6F; -// public static final int RR_HHLL = 0xCB1E; -// public static final int RRA = 0x1F; -// public static final int RRC_HHLL = 0xCB0E; -// public static final int RRCA = 0x0F; -// public static final int RRD = 0xED67; -// public static final int SBC_A_HHLL = 0x9E; -// public static final int SCF = 0x37; -// public static final int SLA_HHLL = 0xCB26; -// public static final int SRA_HHLL = 0xCB2E; -// public static final int SLL_HHLL = 0xCB36; -// public static final int SRL_HHLL = 0xCB3E; -// public static final int SUB_HHLL = 0x96; -// public static final int XOR_HHLL = 0xAE; -// -// public OC_NoParams(int opcode, int line, int column) { -// super(opcode, line, column); -// } -// -// @Override -// public void pass1() { -// } -// -// @Override -// public int pass2(Namespace parentEnv, int addr_start) { -// return addr_start + getSize(); -// } -// -// @Override -// public void generateCode(IntelHEX hex) { -// String s = (getSize() == 1) ? "%1$02X" : "%1$04X"; -// hex.putCode(String.format(s, opcode)); -// } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Reg.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Reg.java deleted file mode 100644 index f622ab46c..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_Reg.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - - -public class OC_Reg { -// public static final int ADC = 0x88; //ADC A,r -// public static final int ADC_HL = 0xED4A; //ADC HL,rr -// public static final int ADD = 0x80; //ADD A,r -// public static final int ADD_HL = 0x09; //ADD HL,rr -// public static final int ADD_IX = 0xDD09; //ADD IX,rx -// public static final int ADD_IY = 0xFD09; //ADD IY,ry -// public static final int AND = 0xA0; //AND r -// public static final int CP = 0xB8; //CP r -// public static final int DEC = 0x0B; // DEC rr -// public static final int INC = 0x03; // INC rr -// public static final int LD_A = 0x78; //LD A,r -// public static final int LD_B = 0x40; //LD B,r -// public static final int LD_C = 0x48; //LD C,r -// public static final int LD_D = 0x50; //LD D,r -// public static final int LD_E = 0x58; //LD E,r -// public static final int LD_H = 0x60; //LD H,r -// public static final int LD_L = 0x68; //LD L,r -// public static final int LD_HHLL_r = 0x70; //LD (HL),r -// public static final int OR = 0xB0; // OR r -// public static final int POP = 0xC1; // POP qq -// public static final int PUSH = 0xC5; // PUSH qq -// public static final int RET = 0xC0; // RET cc -// public static final int RL = 0xCB10; // RL r -// public static final int RLC = 0xCB00; // RLC r -// public static final int RR = 0xCB18; // RR r -// public static final int RRC = 0xCB08; // RRC r -// public static final int SBC = 0x98; // SBC r -// public static final int SBC_HL = 0xED42; // SBC HL, rr -// public static final int SLA = 0xCB20; // SLA r -// public static final int SRA = 0xCB28; // SRA r -// public static final int SLL = 0xCB30; // SLL r -// public static final int SRL = 0xCB38; // SRL r -// public static final int SUB = 0x90; // SUB r -// public static final int XOR = 0xA8; // XOR r -// -// public OC_Reg(int opcode, int reg, int line, int column) { -// super(opcode + reg, line, column); -// } -// -// @Override -// public void pass1() { -// } -// -// @Override -// public int pass2(Namespace parentEnv, int addr_start) { -// return addr_start + getSize(); -// } -// -// @Override -// public void generateCode(IntelHEX hex) { -// String s = (getSize() == 1) ? "%1$02X" : "%1$04X"; -// hex.putCode(String.format(s, opcode)); -// } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_RegExpr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_RegExpr.java deleted file mode 100644 index 9563453a3..000000000 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/tree/OC_RegExpr.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80.tree; - - -/** - * opcode = (first_byte+reg) expr - */ -public class OC_RegExpr { -// public static final int CALL = 0xC40000; // CALL cc,NN -// public static final int JP = 0xC20000; // JP cc,NN -// public static final int JR = 0x2000; // JR cc,N -// public static final int LD_IIX_NN = 0xDD7000; // LD (IX+N),r -// public static final int LD_IIY_NN = 0xFD7000; // LD (IY+N),r -// public static final int LD_RR = 0x010000; // LD rr,NN -// public static final int BIT = 0xCB40; // BIT b,r -// public static final int RES = 0xCB80; // RES b,r -// public static final int SET = 0xCBC0; // SET b,r -// -// private final Expression expr; -// private final boolean oneByte; -// private final boolean bitInstr; // bit instruction? (BIT,SET,RES) -// private final boolean relativeAddress; -// -// /** -// * Creates a new instance of OC_RegExpr -// * -// * @param pos index of byte where add register value; e.g. DD 70+reg XX XX -// * => pos = 1; C4+reg 00 00 => pos = 0; -// */ -// -// public OC_RegExpr(int opcode, int reg, int pos, Expression expr, boolean oneByte, int line, int column) { -// super(opcode, line, column); -// relativeAddress = opcode == JR; -// this.opcode += (reg << ((getSize() - 1 - pos) * 8)); -// this.oneByte = oneByte; -// this.expr = expr; -// this.bitInstr = false; -// } -// -// /** -// * Special constructor for BIT,RES and SET instructions -// */ -// public OC_RegExpr(int opcode, Expression bit, int reg, int line, int column) { -// super(opcode, line, column); -// relativeAddress = false; -// oneByte = true; -// this.expr = bit; -// this.opcode += reg; -// bitInstr = true; -// } -// -// @Override -// public void pass1() { -// } -// -// @Override -// public int pass2(Namespace parentEnv, int addr_start) throws Exception { -// expr.eval(parentEnv, addr_start); -// int val = expr.getValue(); -// if (bitInstr) { -// if ((val > 7) || (val < 0)) { -// throw new ValueOutOfBoundsException(line, column, 0, 7, val); -// } -// opcode += (8 * val); -// } else { -// if (oneByte) { -// if (relativeAddress) { -// val = computeRelativeAddress(line, column, addr_start, val); -// } else if (Expression.getSize(val) > 1) { -// throw new ValueTooBigException(line, column, val, 0xFF); -// } -// opcode += Expression.reverseBytes(val, 1); -// } else { -// opcode += Expression.reverseBytes(val, 2); -// } -// } -// return addr_start + getSize(); -// } -// -// // this can be only mvi instr -// @Override -// public void generateCode(IntelHEX hex) { -// String s; -// if (getSize() == 1) { -// s = "%1$02X"; -// } else if (getSize() == 2) { -// s = "%1$04X"; -// } else if (getSize() == 3) { -// s = "%1$06X"; -// } else { -// s = "%1$08X"; -// } -// hex.putCode(String.format(s, opcode)); -// } -} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java index 4bb42ec58..7eccef8ac 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java @@ -4,10 +4,12 @@ import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; +import net.emustudio.plugins.compiler.asZ80.ast.instr.*; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroArgument; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoOrg; import static net.emustudio.plugins.compiler.asZ80.CompileError.expressionIsBiggerThanExpected; +import static net.emustudio.plugins.compiler.asZ80.CompileError.valueOutOfBounds; /** * Checks proper sizes of evaluated nodes @@ -34,26 +36,32 @@ public void visit(DataDS node) { } @Override - public void visit(InstrN node) { - expectedBytes = node.getExprSizeBytes(); - if (expectedBytes == 1 && node.getChildrenCount() > 1) { - error(expressionIsBiggerThanExpected(node, expectedBytes, node.getChildrenCount())); - } + public void visit(Instr node) { + expectedBytes = 0; visitChildren(node); } @Override - public void visit(InstrR_N node) { - expectedBytes = 1; - if (node.getChildrenCount() > 1) { - error(expressionIsBiggerThanExpected(node, expectedBytes, node.getChildrenCount())); - } + public void visit(InstrCB node) { + expectedBytes = 0; visitChildren(node); } @Override - public void visit(InstrRP_NN node) { - expectedBytes = 2; + public void visit(InstrED node) { + expectedBytes = 0; + visitChildren(node); + } + + @Override + public void visit(InstrXD node) { + expectedBytes = 0; + visitChildren(node); + } + + @Override + public void visit(InstrXDCB node) { + expectedBytes = 0; visitChildren(node); } @@ -70,15 +78,20 @@ public void visit(PseudoMacroArgument node) { @Override public void visit(Evaluated node) { + int value = node.value < 0 ? ((~node.value) * 2) : node.value; if (expectedBytes > 0) { - int value = node.value < 0 ? ((~node.value) * 2) : node.value; - int wasBits = (int) Math.floor(Math.log10(Math.abs(value)) / Math.log10(2)) + 1; int wasBytes = (int) Math.ceil(wasBits / 8.0); if (wasBytes > expectedBytes) { error(expressionIsBiggerThanExpected(node, expectedBytes, wasBytes)); } + } else { + node.getMaxValue().ifPresent(maxValue -> { + if (value > maxValue) { + error(valueOutOfBounds(node, 0, maxValue)); + } + }); } } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java index f6a1eb89c..68fd9cdb5 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java @@ -26,8 +26,8 @@ public Node visitInstrXDCB_R(InstrXDCB_RContext ctx) { int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); int y = CompilerTables.rot.get(ctx.opcode.getType()); int z = CompilerTables.registers.get(ctx.r.start.getType()); - InstrXDCB instr = new InstrXDCB(ctx.opcode, prefix, y, z); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + Node instr = new InstrXDCB(ctx.opcode, prefix, y, z).setSizeBytes(4); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); return instr; } @@ -43,8 +43,8 @@ public Node visitInstrXDCB(InstrXDCBContext ctx) { // | opcode=OPCODE_SLL d=rDisplacement # instrXDCB int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); int y = CompilerTables.rot.get(ctx.opcode.getType()); - InstrXDCB instr = new InstrXDCB(ctx.opcode, prefix, y, 6); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + Node instr = new InstrXDCB(ctx.opcode, prefix, y, 6).setSizeBytes(4); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); return instr; } @@ -54,9 +54,9 @@ public Node visitInstrXDCB_N(InstrXDCB_NContext ctx) { // | opcode=OPCODE_RES n=rExpression SEP_COMMA d=rDisplacement # instrXDCB_N // | opcode=OPCODE_SET n=rExpression SEP_COMMA d=rDisplacement # instrXDCB_N int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); - InstrXDCB instr = new InstrXDCB(ctx.opcode, prefix, 0, 6); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); - instr.addChild(CreateVisitors.expr.visit(ctx.n)); + Node instr = new InstrXDCB(ctx.opcode, prefix, 0, 6).setSizeBytes(4); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); + instr.addChild(CreateVisitors.expr.visit(ctx.n).setMaxValue(7)); return super.visitInstrXDCB_N(ctx); } @@ -66,9 +66,9 @@ public Node visitInstrXDCB_N_R(InstrXDCB_N_RContext ctx) { // | opcode=OPCODE_SET n=rExpression SEP_COMMA d=rDisplacement SEP_COMMA r=rRegister2 # instrXDCB_N_R int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); int z = CompilerTables.registers.get(ctx.r.start.getType()); - InstrXDCB instr = new InstrXDCB(ctx.opcode, prefix, 0, z); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); - instr.addChild(CreateVisitors.expr.visit(ctx.n)); + Node instr = new InstrXDCB(ctx.opcode, prefix, 0, z).setSizeBytes(4); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); + instr.addChild(CreateVisitors.expr.visit(ctx.n).setMaxValue(7)); return instr; } @@ -78,7 +78,7 @@ public Node visitInstrED_R2(InstrED_R2Context ctx) { // | opcode=OPCODE_OUT SEP_LPAR REG_C SEP_RPAR SEP_COMMA r=rRegister2 # instrED_R2 int y = CompilerTables.registers.get(ctx.r.start.getType()); int z = (ctx.opcode.getType() == OPCODE_IN) ? 0 : 1; - return new InstrED(ctx.opcode, y, z); + return new InstrED(ctx.opcode, y, z).setSizeBytes(2); } @Override @@ -86,7 +86,7 @@ public Node visitInstrED_C(InstrED_CContext ctx) { // | opcode=OPCODE_IN SEP_LPAR REG_C SEP_RPAR # instrED_C // | opcode=OPCODE_OUT SEP_LPAR REG_C SEP_RPAR SEP_COMMA n=LIT_NUMBER # instrED_C int z = (ctx.opcode.getType() == OPCODE_IN) ? 0 : 1; - return new InstrED(ctx.opcode, 6, z); + return new InstrED(ctx.opcode, 6, z).setSizeBytes(2); } @Override @@ -95,7 +95,7 @@ public Node visitInstrED_RP(InstrED_RPContext ctx) { // | opcode=OPCODE_ADC REG_HL SEP_COMMA rp=rRegPair # instrED_RP int q = (ctx.opcode.getType() == OPCODE_SBC) ? 0 : 1; int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); - return new InstrED(ctx.opcode, p, q, 2); + return new InstrED(ctx.opcode, p, q, 2).setSizeBytes(2); } @Override @@ -103,8 +103,8 @@ public Node visitInstrED_NN_RP(InstrED_NN_RPContext ctx) { // | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA rp=rRegPair # instrED_NN_RP int q = 0; int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); - InstrED instr = new InstrED(ctx.opcode, p, q, 3); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + Node instr = new InstrED(ctx.opcode, p, q, 3).setSizeBytes(4); + instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; } @@ -113,8 +113,8 @@ public Node visitInstrED_RP_NN(InstrED_RP_NNContext ctx) { // | opcode=OPCODE_LD rp=rRegPair SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrED_RP_NN int q = 1; int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); - InstrED instr = new InstrED(ctx.opcode, p, q, 3); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + Node instr = new InstrED(ctx.opcode, p, q, 3).setSizeBytes(4); + instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; } @@ -122,7 +122,7 @@ public Node visitInstrED_RP_NN(InstrED_RP_NNContext ctx) { public Node visitInstrED_IM(InstrED_IMContext ctx) { // | opcode=OPCODE_IM im=(IM_0|IM_1|IM_2|IM_01) # instrED_IM int y = CompilerTables.im.get(ctx.im.getType()); - return new InstrED(ctx.opcode, y, 6); + return new InstrED(ctx.opcode, y, 6).setSizeBytes(2); } @Override @@ -139,7 +139,7 @@ public Node visitInstrED_RIA_RIA(InstrED_RIA_RIAContext ctx) { } else if (ctx.src.getType() == REG_R) { y = 3; } - return new InstrED(ctx.opcode, y, 7); + return new InstrED(ctx.opcode, y, 7).setSizeBytes(2); } @Override @@ -179,7 +179,7 @@ public Node visitInstrED(InstrEDContext ctx) { } Pair yz = CompilerTables.block.get(ctx.opcode.getType()); - return new InstrED(ctx.opcode, yz.l, yz.r); + return new InstrED(ctx.opcode, yz.l, yz.r).setSizeBytes(2); } @Override @@ -194,7 +194,7 @@ public Node visitInstrCB(InstrCBContext ctx) { // | opcode=OPCODE_SRL r=rRegister # instrCB int y = CompilerTables.rot.get(ctx.opcode.getType()); int z = CompilerTables.registers.get(ctx.r.r.getType()); - return new InstrCB(ctx.opcode, y, z); + return new InstrCB(ctx.opcode, y, z).setSizeBytes(2); } @Override @@ -204,8 +204,8 @@ public Node visitInstrCB_N_R(InstrCB_N_RContext ctx) { // | opcode=OPCODE_SET n=rExpression SEP_COMMA r=rRegister # instrCB_N_R int z = CompilerTables.registers.get(ctx.r.r.getType()); // y needs to be computed from expr - InstrCB instr = new InstrCB(ctx.opcode, 0, z); - instr.addChild(CreateVisitors.expr.visit(ctx.n)); + Node instr = new InstrCB(ctx.opcode, 0, z).setSizeBytes(2); + instr.addChild(CreateVisitors.expr.visit(ctx.n).setMaxValue(7)); return instr; } @@ -213,8 +213,8 @@ public Node visitInstrCB_N_R(InstrCB_N_RContext ctx) { public Node visitInstrXD_II_NN(InstrXD_II_NNContext ctx) { // | opcode=OPCODE_LD ii=rII SEP_COMMA nn=rExpression # instrXD_II_NN int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); - InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 0, 2, 1); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + Node instr = new InstrXD(ctx.opcode, prefix, 0, 0, 2, 1).setSizeBytes(4); + instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; } @@ -223,15 +223,15 @@ public Node visitInstrXD_II_RP(InstrXD_II_RPContext ctx) { // | opcode=OPCODE_ADD ii=rII SEP_COMMA rp=(REG_BC|REG_DE|REG_IX|REG_IY|REG_SP) # instrXD_II_RP int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); int p = CompilerTables.regPairsII.get(ctx.rp.getType()); - return new InstrXD(ctx.opcode, prefix, 0, 1, p, 1); + return new InstrXD(ctx.opcode, prefix, 0, 1, p, 1).setSizeBytes(2); } @Override public Node visitInstrXD_Ref_NN_II(InstrXD_Ref_NN_IIContext ctx) { // | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA ii=rII # instrXD_Ref_NN_II int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); - InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 0, 2, 2); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + Node instr = new InstrXD(ctx.opcode, prefix, 0, 0, 2, 2).setSizeBytes(4); + instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; } @@ -239,8 +239,8 @@ public Node visitInstrXD_Ref_NN_II(InstrXD_Ref_NN_IIContext ctx) { public Node visitInstrXD_II_Ref_NN(InstrXD_II_Ref_NNContext ctx) { // | opcode=OPCODE_LD ii=rII SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrXD_II_Ref_NN int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); - InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 1, 2, 2); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + Node instr = new InstrXD(ctx.opcode, prefix, 0, 1, 2, 2).setSizeBytes(4); + instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; } @@ -249,8 +249,8 @@ public Node visitInstrXD_IIHL_N(InstrXD_IIHL_NContext ctx) { // | opcode=OPCODE_LD ii=rII_HL SEP_COMMA n=rExpression # instrXD_IIHL_N int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); int y = CompilerTables.registers.get(ctx.ii.start.getType()); - InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, y, 6); - instr.addChild(CreateVisitors.expr.visit(ctx.n)); + Node instr = new InstrXD(ctx.opcode, prefix, 0, y, 6).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.n).setSizeBytes(1)); return instr; } @@ -258,9 +258,9 @@ public Node visitInstrXD_IIHL_N(InstrXD_IIHL_NContext ctx) { public Node visitInstrXD_Ref_II_N_N(InstrXD_Ref_II_N_NContext ctx) { // | opcode=OPCODE_LD d=rDisplacement SEP_COMMA n=rExpression # instrXD_Ref_II_N_N int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); - InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 6, 6); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); - instr.addChild(CreateVisitors.expr.visit(ctx.n)); + Node instr = new InstrXD(ctx.opcode, prefix, 0, 6, 6).setSizeBytes(4); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); + instr.addChild(CreateVisitors.expr.visit(ctx.n).setSizeBytes(1)); return instr; } @@ -270,7 +270,7 @@ public Node visitInstrXD_IIHL_R(InstrXD_IIHL_RContext ctx) { int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); int y = CompilerTables.registers.get(ctx.ii.start.getType()); int z = CompilerTables.registers.get(ctx.r.start.getType()); - return new InstrXD(ctx.opcode, prefix, 1, y, z); + return new InstrXD(ctx.opcode, prefix, 1, y, z).setSizeBytes(2); } @Override @@ -279,7 +279,7 @@ public Node visitInstrXD_R_IIHL(InstrXD_R_IIHLContext ctx) { int prefix = CompilerTables.prefix.get(ctx.ii.start.getType()); int y = CompilerTables.registers.get(ctx.r.start.getType()); int z = CompilerTables.registers.get(ctx.ii.start.getType()); - return new InstrXD(ctx.opcode, prefix, 1, y, z); + return new InstrXD(ctx.opcode, prefix, 1, y, z).setSizeBytes(2); } @Override @@ -287,8 +287,8 @@ public Node visitInstrXD_Ref_II_N_R(InstrXD_Ref_II_N_RContext ctx) { // | opcode=OPCODE_LD d=rDisplacement SEP_COMMA r=rRegister2 # instrXD_Ref_II_N_R int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); int z = CompilerTables.registers.get(ctx.r.start.getType()); - InstrXD instr = new InstrXD(ctx.opcode, prefix, 1, 6, z); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + Node instr = new InstrXD(ctx.opcode, prefix, 1, 6, z).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); return instr; } @@ -297,8 +297,8 @@ public Node visitInstrXD_R_Ref_II_N(InstrXD_R_Ref_II_NContext ctx) { // | opcode=OPCODE_LD r=rRegister2 SEP_COMMA d=rDisplacement # instrXD_R_Ref_II_N int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); int y = CompilerTables.registers.get(ctx.r.start.getType()); - InstrXD instr = new InstrXD(ctx.opcode, prefix, 1, y, 6); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + Node instr = new InstrXD(ctx.opcode, prefix, 1, y, 6).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); return instr; } @@ -316,18 +316,18 @@ public Node visitInstrXD_Ref_II_N(InstrXD_Ref_II_NContext ctx) { // | opcode=OPCODE_CP d=rDisplacement # instrXD_Ref_II_N int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); if (ctx.opcode.getType() == OPCODE_INC) { - InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 6, 4); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + Node instr = new InstrXD(ctx.opcode, prefix, 0, 6, 4).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); return instr; } else if (ctx.opcode.getType() == OPCODE_DEC) { - InstrXD instr = new InstrXD(ctx.opcode, prefix, 0, 6, 5); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + Node instr = new InstrXD(ctx.opcode, prefix, 0, 6, 5).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); return instr; } int y = CompilerTables.alu.get(ctx.opcode.getType()); - InstrXD instr = new InstrXD(ctx.opcode, prefix, 2, y, 6); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n)); + Node instr = new InstrXD(ctx.opcode, prefix, 2, y, 6).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); return instr; } @@ -347,12 +347,12 @@ public Node visitInstrXD_IIHL(InstrXD_IIHLContext ctx) { int r = CompilerTables.registers.get(ctx.ii.start.getType()); if (ctx.opcode.getType() == OPCODE_INC) { - return new InstrXD(ctx.opcode, prefix, 0, r, 4); + return new InstrXD(ctx.opcode, prefix, 0, r, 4).setSizeBytes(2); } else if (ctx.opcode.getType() == OPCODE_DEC) { - return new InstrXD(ctx.opcode, prefix, 0, r, 5); + return new InstrXD(ctx.opcode, prefix, 0, r, 5).setSizeBytes(2); } int y = CompilerTables.alu.get(ctx.opcode.getType()); - return new InstrXD(ctx.opcode, prefix, 2, y, r); + return new InstrXD(ctx.opcode, prefix, 2, y, r).setSizeBytes(2); } @Override @@ -379,7 +379,7 @@ public Node visitInstrXD_II(InstrXD_IIContext ctx) { break; } - return new InstrXD(ctx.opcode, prefix, x, q, p, z); + return new InstrXD(ctx.opcode, prefix, x, q, p, z).setSizeBytes(2); } @Override @@ -387,24 +387,24 @@ public Node visitInstrRef_NN_R(InstrRef_NN_RContext ctx) { // | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_HL # instrRef_NN_R // x=0, z=2, q=0, p=2 // | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA r=REG_A # instrRef_NN_R // x=0, z=2, q=0, p=3 int p = (ctx.r.getType() == REG_HL) ? 2 : 3; - Instr instr = new Instr(ctx.opcode, 0, 0, p, 2); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + Node instr = new Instr(ctx.opcode, 0, 0, p, 2).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; } @Override public Node visitInstrRP_Ref_NN(InstrRP_Ref_NNContext ctx) { // | opcode=OPCODE_LD rp=REG_HL SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrRP_Ref_NN // x=0, z=2, q=1, p=2 - Instr instr = new Instr(ctx.opcode, 0, 1, 2, 2); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + Node instr = new Instr(ctx.opcode, 0, 1, 2, 2).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; } @Override public Node visitInstrR_Ref_NN(InstrR_Ref_NNContext ctx) { // | opcode=OPCODE_LD r=REG_A SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrR_Ref_NN // x=0, z=2, q=1, p=3 - Instr instr = new Instr(ctx.opcode, 0, 1, 3, 2); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + Node instr = new Instr(ctx.opcode, 0, 1, 3, 2).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; } @@ -412,7 +412,7 @@ public Node visitInstrR_Ref_NN(InstrR_Ref_NNContext ctx) { public Node visitInstrA_Ref_RP(InstrA_Ref_RPContext ctx) { // | opcode=OPCODE_LD REG_A SEP_COMMA SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR # instrA_Ref_RP // x=0, z=2, q=1, p=rp int p = CompilerTables.regPairs.get(ctx.rp.getType()); - return new Instr(ctx.opcode, 0, 1, p, 2); + return new Instr(ctx.opcode, 0, 1, p, 2).setSizeBytes(1); } @Override @@ -423,13 +423,13 @@ public Node visitInstrRef_RP(InstrRef_RPContext ctx) { int x = (ctx.opcode.getType() == OPCODE_LD) ? 0 : 3; int z = (ctx.opcode.getType() == OPCODE_LD) ? 2 : 1; int q = (ctx.opcode.getType() == OPCODE_LD) ? 0 : 1; - return new Instr(ctx.opcode, x, q, p, z); + return new Instr(ctx.opcode, x, q, p, z).setSizeBytes(1); } @Override public Node visitInstrRef_RP_RP(InstrRef_RP_RPContext ctx) { // | opcode=OPCODE_EX SEP_LPAR dst=REG_SP SEP_RPAR SEP_COMMA src=REG_HL # instrRef_RP_RP // x=3, z=3, y=4 - return new Instr(ctx.opcode, 3, 4, 3); + return new Instr(ctx.opcode, 3, 4, 3).setSizeBytes(1); } @Override @@ -437,15 +437,15 @@ public Node visitInstrR_R(InstrR_RContext ctx) { // | opcode=OPCODE_LD dst=rRegister SEP_COMMA src=rRegister # instrR_R // x=1, y=dst, z=src int y = CompilerTables.registers.get(ctx.dst.r.getType()); int z = CompilerTables.registers.get(ctx.src.r.getType()); - return new Instr(ctx.opcode, 1, y, z); + return new Instr(ctx.opcode, 1, y, z).setSizeBytes(1); } @Override public Node visitInstrR_N(InstrR_NContext ctx) { // | opcode=OPCODE_LD r=rRegister SEP_COMMA n=rExpression # instrR_N // x=0, z=6, y=r int y = CompilerTables.registers.get(ctx.r.r.getType()); - Instr instr = new Instr(ctx.opcode, 0, y, 6); - instr.addChild(CreateVisitors.expr.visit(ctx.n)); + Node instr = new Instr(ctx.opcode, 0, y, 6).setSizeBytes(2); + instr.addChild(CreateVisitors.expr.visit(ctx.n).setSizeBytes(1)); return instr; } @@ -453,8 +453,8 @@ public Node visitInstrR_N(InstrR_NContext ctx) { public Node visitInstrC_N(InstrC_NContext ctx) { // | opcode=OPCODE_JR c=(COND_NZ|COND_Z|COND_NC|COND_C) SEP_COMMA n=rExpression # instrC_N // x=0, z=0, y=4..7 int y = CompilerTables.conditions.get(ctx.c.getType()); - Instr instr = new Instr(ctx.opcode, 0, y, 0); - instr.addChild(CreateVisitors.expr.visit(ctx.n)); + Node instr = new Instr(ctx.opcode, 0, y, 0).setSizeBytes(2); + instr.addChild(CreateVisitors.expr.visit(ctx.n).setSizeBytes(1)); return instr; } @@ -462,7 +462,7 @@ public Node visitInstrC_N(InstrC_NContext ctx) { public Node visitInstrC(InstrCContext ctx) { // | opcode=OPCODE_RET c=cCondition # instrC // x=3, z=0, y=cc int y = CompilerTables.conditions.get(ctx.c.start.getType()); - return new Instr(ctx.opcode, 3, y, 0); + return new Instr(ctx.opcode, 3, y, 0).setSizeBytes(1); } @Override @@ -471,8 +471,8 @@ public Node visitInstrC_NN(InstrC_NNContext ctx) { // | opcode=OPCODE_CALL c=cCondition SEP_COMMA nn=rExpression # instrC_NN // x=3, z=4, y=cc int y = CompilerTables.conditions.get(ctx.c.start.getType()); int z = (ctx.opcode.getType() == OPCODE_JP) ? 2 : 4; - Instr instr = new Instr(ctx.opcode, 3, y, z); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + Node instr = new Instr(ctx.opcode, 3, y, z).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; } @@ -480,8 +480,8 @@ public Node visitInstrC_NN(InstrC_NNContext ctx) { public Node visitInstrRP_NN(InstrRP_NNContext ctx) { // | opcode=OPCODE_LD rp=rRegPair SEP_COMMA nn=rExpression # instrRP_NN // x=0, z=1, q=0, p=rp int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); - Instr instr = new Instr(ctx.opcode, 0, 0, p, 1); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + Node instr = new Instr(ctx.opcode, 0, 0, p, 1).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; } @@ -493,7 +493,7 @@ public Node visitInstrRP_RP(InstrRP_RPContext ctx) { int x = (ctx.opcode.getType() == OPCODE_EX && ctx.dst.getType() == REG_AF) ? 0 : 3; int z = (ctx.opcode.getType() == OPCODE_LD) ? 1 : ((ctx.dst.getType() == REG_AF) ? 0 : 3); int p = (ctx.opcode.getType() == OPCODE_LD) ? 3 : ((ctx.dst.getType() == REG_AF) ? 0 : 2); - return new Instr(ctx.opcode, x, 1, p, z); + return new Instr(ctx.opcode, x, 1, p, z).setSizeBytes(1); } @Override @@ -502,8 +502,8 @@ public Node visitInstrNN(InstrNNContext ctx) { // | opcode=OPCODE_CALL nn=rExpression # instrNN // x=3, z=5, y=1 int z = (ctx.opcode.getType() == OPCODE_JP) ? 3 : 5; int y = (ctx.opcode.getType() == OPCODE_JP) ? 0 : 1; - Instr instr = new Instr(ctx.opcode, 3, y, z); - instr.addChild(CreateVisitors.expr.visit(ctx.nn)); + Node instr = new Instr(ctx.opcode, 3, y, z).setSizeBytes(3); + instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; } @@ -531,8 +531,9 @@ public Node visitInstrN(InstrNContext ctx) { int x = (djnzOrJr) ? 0 : 3; int z = (djnzOrJr) ? 0 : ((opcode == OPCODE_OUT || opcode == OPCODE_IN) ? 3 : (rst ? 7 : 6)); int y = djnzOrOut ? 2 : ((opcode == OPCODE_JR || opcode == OPCODE_IN) ? 3 : (rst ? 0 : CompilerTables.alu.get(opcode))); - Instr instr = new Instr(ctx.opcode, x, y, z); - instr.addChild(CreateVisitors.expr.visit(ctx.n)); + + Node instr = new Instr(ctx.opcode, x, y, z).setSizeBytes(rst ? 1 : 2); + instr.addChild(CreateVisitors.expr.visit(ctx.n).setSizeBytes(1)); return instr; } @@ -544,7 +545,7 @@ public Node visitInstrRP(InstrRPContext ctx) { int q = (ctx.opcode.getType() == OPCODE_INC) ? 0 : 1; int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); int z = (ctx.opcode.getType() == OPCODE_ADD) ? 1 : 3; - return new Instr(ctx.opcode, 0, q, p, z); + return new Instr(ctx.opcode, 0, q, p, z).setSizeBytes(1); } @Override @@ -553,7 +554,7 @@ public Node visitInstrRP2(InstrRP2Context ctx) { // | opcode=OPCODE_PUSH rp2=rRegPair2 # instrRP2 // x=3, z=5, q=0, p=rp2 int p = CompilerTables.regPairs2.get(ctx.rp2.start.getType()); int z = (ctx.opcode.getType() == OPCODE_POP) ? 1 : 5; - return new Instr(ctx.opcode, 3, 0, p, z); + return new Instr(ctx.opcode, 3, 0, p, z).setSizeBytes(1); } @Override @@ -575,7 +576,7 @@ public Node visitInstrR(InstrRContext ctx) { int x = incDec ? 0 : 2; int y = incDec ? reg : CompilerTables.alu.get(ctx.opcode.getType()); int z = (opcode == OPCODE_INC) ? 4 : ((opcode == OPCODE_DEC) ? 5 : reg); - return new Instr(ctx.opcode, x, y, z); + return new Instr(ctx.opcode, x, y, z).setSizeBytes(1); } @Override @@ -612,6 +613,6 @@ public Node visitInstr(InstrContext ctx) { xyz.put(OPCODE_EI, new int[] {3, 7, 3}); int[] xyzValues = xyz.get(ctx.opcode.getType()); - return new Instr(ctx.opcode, xyzValues[0], xyzValues[1], xyzValues[2]); + return new Instr(ctx.opcode, xyzValues[0], xyzValues[1], xyzValues[2]).setSizeBytes(1); } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java index 55e218d6f..1026b73ee 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java @@ -189,51 +189,43 @@ public void visit(PseudoIf node) { } @Override - public void visit(InstrN node) { + public void visit(Instr node) { node.setAddress(currentAddress); - sizeBytes = node.getExprSizeBytes(); + sizeBytes = 0; visitChildren(node); - currentAddress++; // opcode + node.getSizeBytes().ifPresent(s -> currentAddress += s); } @Override - public void visit(InstrR_N node) { + public void visit(InstrCB node) { node.setAddress(currentAddress); - sizeBytes = 1; + sizeBytes = 0; visitChildren(node); - currentAddress++; // opcode + node.getSizeBytes().ifPresent(s -> currentAddress += s); } @Override - public void visit(InstrRP_NN node) { + public void visit(InstrED node) { node.setAddress(currentAddress); - sizeBytes = 2; + sizeBytes = 0; visitChildren(node); - currentAddress++; // opcode + node.getSizeBytes().ifPresent(s -> currentAddress += s); } @Override - public void visit(Instr node) { + public void visit(InstrXD node) { node.setAddress(currentAddress); - currentAddress++; - } - - @Override - public void visit(InstrR_R node) { - node.setAddress(currentAddress); - currentAddress++; - } - - @Override - public void visit(InstrR node) { - node.setAddress(currentAddress); - currentAddress++; + sizeBytes = 0; + visitChildren(node); + node.getSizeBytes().ifPresent(s -> currentAddress += s); } @Override - public void visit(InstrRP node) { + public void visit(InstrXDCB node) { node.setAddress(currentAddress); - currentAddress++; + sizeBytes = 0; + visitChildren(node); + node.getSizeBytes().ifPresent(s -> currentAddress += s); } @Override @@ -323,10 +315,11 @@ public void visit(ExprString node) { if (strLen > 1) { result |= (node.string.charAt(1) << 8); } - node.addChild(new Evaluated(node.line, node.column, result)); + node.addChild(new Evaluated(node.line, node.column, result).setSizeBytes(2)); } else { + int maxValue = node.getMaxValue().map(v -> Math.min(v, 0xFF)).orElse(0xFF); for (int i = 0; i < strLen; i++) { - node.addChild(new Evaluated(node.line, node.column, node.string.charAt(i))); + node.addChild(new Evaluated(node.line, node.column, node.string.charAt(i)).setMaxValue(maxValue)); } } node.exclude(); @@ -339,6 +332,7 @@ private Optional getCurrentAddress() { private void evalExpr(Node node) { latestEval = node.eval(getCurrentAddress(), env); + latestEval.ifPresent(e -> node.getMaxValue().ifPresent(e::setMaxValue)); latestEval.ifPresentOrElse( e -> node.remove().ifPresent(p -> p.addChild(e)), () -> needMorePassThings.add(node) diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java index 967b9e547..34ad4fb4b 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java @@ -47,49 +47,53 @@ public void visit(DataDS node) { }); } - @Override - public void visit(InstrN node) { - node.eval() - .ifPresentOrElse( - hex::add, - () -> error(valueOutOfBounds(node, 0, 7)) - ); - expectedBytes = node.getExprSizeBytes(); - visitChildren(node); - } - @Override public void visit(Instr node) { - hex.add(node.eval()); - } - - @Override - public void visit(InstrR node) { - hex.add(node.eval()); + node.eval().ifPresentOrElse( + hex::add, + () -> error(valueOutOfBounds(node, 0, 7)) + ); + int instrSize = node.getSizeBytes().orElse(1); + if (instrSize > 1) { + expectedBytes = 0; + visitChildren(node); + } } @Override - public void visit(InstrR_N node) { - hex.add(node.eval()); - expectedBytes = 1; + public void visit(InstrCB node) { + for (byte b : node.eval()) { + hex.add(b); + } + expectedBytes = 0; visitChildren(node); } @Override - public void visit(InstrRP node) { - hex.add(node.eval()); + public void visit(InstrED node) { + for (byte b : node.eval()) { + hex.add(b); + } + expectedBytes = 0; + visitChildren(node); } @Override - public void visit(InstrRP_NN node) { - hex.add(node.eval()); - expectedBytes = 2; + public void visit(InstrXD node) { + for (byte b : node.eval()) { + hex.add(b); + } + expectedBytes = 0; visitChildren(node); } @Override - public void visit(InstrR_R node) { - hex.add(node.eval()); + public void visit(InstrXDCB node) { + for (byte b : node.eval()) { + hex.add(b); + } + expectedBytes = 0; + visitChildren(node); } @Override @@ -107,13 +111,28 @@ public void visit(PseudoOrg node) { @Override public void visit(Evaluated node) { if (expectedBytes == 1) { - hex.add((byte) (node.value & 0xFF)); + addByte(node.value); } else if (expectedBytes == 2) { - byte byte0 = (byte) (node.value & 0xFF); - byte byte1 = (byte) (node.value >>> 8); - - hex.add(byte0); - hex.add(byte1); + addWord(node.value); + } else { + node.getSizeBytes().ifPresent(size -> { + if (size == 1) { + addByte(node.value); + } else if (size == 2) { + addWord(node.value); + } + }); } } + + private void addByte(int value) { + hex.add((byte) (value & 0xFF)); + } + + private void addWord(int value) { + byte byte0 = (byte) (value & 0xFF); + byte byte1 = (byte) (value >>> 8); + hex.add(byte0); + hex.add(byte1); + } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java index e6dcba70c..ce1bcba7f 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java @@ -18,7 +18,6 @@ */ package net.emustudio.plugins.compiler.asZ80; -import net.emustudio.plugins.compiler.asZ80.tree.OC_Reg; import org.junit.Assert; import org.junit.Test; From b76cf20f74136ed441fb4dc030159f07e1603511 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 18 Feb 2022 11:05:15 +0100 Subject: [PATCH 099/314] [#201] as-z80: tests wip --- .../plugins/compiler/asZ80/Utils.java | 12 + .../compiler/asZ80/parser/ParseDataTest.java | 2 +- .../compiler/asZ80/parser/ParseInstrTest.java | 333 +++++++++--------- 3 files changed, 178 insertions(+), 169 deletions(-) diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java index 285641478..e050e3a39 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java @@ -115,6 +115,18 @@ public static void forStringCaseVariations(String base, Consumer f) { } } + public static void forRegister(Consumer> f) { + for (Map.Entry register : registers.entrySet()) { + f.accept(Pair.of(register.getKey(), register.getValue())); + } + } + + public static void forRegPair(Consumer> f) { + for (Map.Entry regPair : regPairsBDHSP.entrySet()) { + f.accept(Pair.of(regPair.getKey(), regPair.getValue())); + } + } + public static void assertTrees(Node expected, Node result) { assertEquals("Children size does not match", expected.getChildren().size(), result.getChildren().size()); assertEquals("Nodes are different", expected.getClass(), result.getClass()); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java index 4260566e7..10856f024 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java @@ -43,7 +43,7 @@ public void testDBinstruction() { assertTrees( new Program() .addChild(new DataDB(0, 0) - .addChild(new Instr(0, 0, OPCODE_RET, x, y, z))), + .addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1))), program ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java index 7de884cfc..f6e61e651 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java @@ -5,11 +5,12 @@ import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprCurrentAddress; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; -import net.emustudio.plugins.compiler.asZ80.ast.instr.*; +import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrCB; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrED; import org.junit.Test; -import java.util.Locale; -import java.util.Map; +import java.util.Random; import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; import static net.emustudio.plugins.compiler.asZ80.Utils.*; @@ -18,206 +19,202 @@ public class ParseInstrTest { @Test public void testInstrNoArgs() { - assertInstrNoArgs("stc", OPCODE_STC); - assertInstrNoArgs("cmc", OPCODE_CMC); - assertInstrNoArgs("daa", OPCODE_DAA); - assertInstrNoArgs("nop", OPCODE_NOP); - assertInstrNoArgs("rlc", OPCODE_RLC); - assertInstrNoArgs("rrc", OPCODE_RRC); - assertInstrNoArgs("ral", OPCODE_RAL); - assertInstrNoArgs("rar", OPCODE_RAR); - assertInstrNoArgs("xchg", OPCODE_XCHG); - assertInstrNoArgs("xthl", OPCODE_XTHL); - assertInstrNoArgs("sphl", OPCODE_SPHL); - assertInstrNoArgs("pchl", OPCODE_PCHL); - assertInstrNoArgs("ret", OPCODE_RET); - assertInstrNoArgs("rc", OPCODE_RC); - assertInstrNoArgs("rnc", OPCODE_RNC); - assertInstrNoArgs("rz", OPCODE_RZ); - assertInstrNoArgs("rnz", OPCODE_RNZ); - assertInstrNoArgs("rm", OPCODE_RM); - assertInstrNoArgs("rp", OPCODE_RP); - assertInstrNoArgs("rpe", OPCODE_RPE); - assertInstrNoArgs("rpo", OPCODE_RPO); - assertInstrNoArgs("ei", OPCODE_EI); - assertInstrNoArgs("di", OPCODE_DI); - assertInstrNoArgs("hlt", OPCODE_HLT); + assertInstr("nop", OPCODE_NOP, 0, 0, 0); + assertInstr("ex af, af'", OPCODE_EX, 0, 1, 0); + assertInstr("ld (bc), a", OPCODE_LD, 0, 0, 2); + assertInstr("ld (de), a", OPCODE_LD, 0, 2, 2); + assertInstr("ld a, (bc)", OPCODE_LD, 0, 1, 2); + assertInstr("ld a, (de)", OPCODE_LD, 0, 3, 2); + assertInstr("rlca", OPCODE_RLCA, 0, 0, 7); + assertInstr("rrca", OPCODE_RRCA, 0, 1, 7); + assertInstr("rla", OPCODE_RLA, 0, 2, 7); + assertInstr("rra", OPCODE_RRA, 0, 3, 7); + assertInstr("daa", OPCODE_DAA, 0, 4, 7); + assertInstr("cpl", OPCODE_CPL, 0, 5, 7); + assertInstr("scf", OPCODE_SCF, 0, 6, 7); + assertInstr("ccf", OPCODE_CCF, 0, 7, 7); + assertInstr("halt", OPCODE_HALT, 1, 6, 6); + assertInstr("ret", OPCODE_RET, 3, 1, 1); + assertInstr("exx", OPCODE_EXX, 3, 3, 1); + assertInstr("jp hl", OPCODE_JP, 3, 5, 1); + assertInstr("ld sp, hl", OPCODE_LD, 3, 7, 1); + assertInstr("ex (sp), hl", OPCODE_EX, 3, 4, 3); + assertInstr("ex de, hl", OPCODE_EX, 3, 5, 3); + assertInstr("di", OPCODE_DI, 3, 6, 3); + assertInstr("ei", OPCODE_EI, 3, 7, 3); + assertInstrED("in (c)", OPCODE_IN, 6, 0); + assertInstrED("out (c), 0", OPCODE_OUT, 6, 1); + assertInstrED("neg", OPCODE_NEG, 0, 4); + assertInstrED("retn", OPCODE_RETN, 0, 5); + assertInstrED("reti", OPCODE_RETI, 1, 5); + assertInstrED("im 0", OPCODE_IM, 0, 6); + assertInstrED("im 0/1", OPCODE_IM, 1, 6); + assertInstrED("im 1", OPCODE_IM, 2, 6); + assertInstrED("im 2", OPCODE_IM, 3, 6); + assertInstrED("ld i, a", OPCODE_LD, 0, 7); + assertInstrED("ld r, a", OPCODE_LD, 1, 7); + assertInstrED("ld a, i", OPCODE_LD, 2, 7); + assertInstrED("ld a, r", OPCODE_LD, 3, 7); + assertInstrED("rrd", OPCODE_RRD, 4, 7); + assertInstrED("rld", OPCODE_RLD, 5, 7); + assertInstrED("ldi", OPCODE_LDI, 4, 0); + assertInstrED("ldd", OPCODE_LDD, 5, 0); + assertInstrED("ldir", OPCODE_LDIR, 6, 0); + assertInstrED("lddr", OPCODE_LDDR, 7, 0); + assertInstrED("cpi", OPCODE_CPI, 4, 1); + assertInstrED("cpd", OPCODE_CPD, 5, 1); + assertInstrED("cpir", OPCODE_CPIR, 6, 1); + assertInstrED("cpdr", OPCODE_CPDR, 7, 1); + assertInstrED("ini", OPCODE_INI, 4, 2); + assertInstrED("ind", OPCODE_IND, 5, 2); + assertInstrED("inir", OPCODE_INIR, 6, 2); + assertInstrED("indr", OPCODE_INDR, 7, 2); + assertInstrED("outi", OPCODE_OUTI, 4, 3); + assertInstrED("outd", OPCODE_OUTD, 5, 3); + assertInstrED("otir", OPCODE_OTIR, 6, 3); + assertInstrED("otdr", OPCODE_OTDR, 7, 3); } @Test public void testInstrReg() { - assertInstrReg("inr", OPCODE_INR); - assertInstrReg("dcr", OPCODE_DCR); - assertInstrReg("add", OPCODE_ADD); - assertInstrReg("adc", OPCODE_ADC); - assertInstrReg("sub", OPCODE_SUB); - assertInstrReg("sbb", OPCODE_SBB); - assertInstrReg("ana", OPCODE_ANA); - assertInstrReg("xra", OPCODE_XRA); - assertInstrReg("ora", OPCODE_ORA); - assertInstrReg("cmp", OPCODE_CMP); + Random random = new Random(); + forRegister(regValue -> { + assertInstr("inc " + regValue.l, OPCODE_INC, 0, regValue.r, 4); + assertInstr("dec " + regValue.l, OPCODE_DEC, 0, regValue.r, 5); + assertInstrExpr("ld " + regValue.l + ", ", OPCODE_LD, 0, regValue.r, 6); + assertInstr("add a, " + regValue.l, OPCODE_ADD, 2, 0, regValue.r); + assertInstr("adc a, " + regValue.l, OPCODE_ADC, 2, 1, regValue.r); + assertInstr("sub " + regValue.l, OPCODE_SUB, 2, 2, regValue.r); + assertInstr("sbc a, " + regValue.l, OPCODE_SBC, 2, 3, regValue.r); + assertInstr("and " + regValue.l, OPCODE_AND, 2, 4, regValue.r); + assertInstr("xor " + regValue.l, OPCODE_XOR, 2, 5, regValue.r); + assertInstr("or " + regValue.l, OPCODE_OR, 2, 6, regValue.r); + assertInstr("cp " + regValue.l, OPCODE_CP, 2, 7, regValue.r); + + assertInstrCBNoArgs("rlc " + regValue.l, OPCODE_RLC, 0, regValue.r); + assertInstrCBNoArgs("rrc " + regValue.l, OPCODE_RRC, 1, regValue.r); + assertInstrCBNoArgs("rl " + regValue.l, OPCODE_RL, 2, regValue.r); + assertInstrCBNoArgs("rr " + regValue.l, OPCODE_RR, 3, regValue.r); + assertInstrCBNoArgs("sla " + regValue.l, OPCODE_SLA, 4, regValue.r); + assertInstrCBNoArgs("sra " + regValue.l, OPCODE_SRA, 5, regValue.r); + assertInstrCBNoArgs("sll " + regValue.l, OPCODE_SLL, 6, regValue.r); + assertInstrCBNoArgs("srl " + regValue.l, OPCODE_SRL, 7, regValue.r); + + int bit = random.nextInt() % 8; + assertInstrCBExprBit("bit " + bit + ", " + regValue.l, OPCODE_BIT, bit, regValue.r); + assertInstrCBExprBit("res " + bit + ", " + regValue.l, OPCODE_RES, bit, regValue.r); + assertInstrCBExprBit("set " + bit + ", " + regValue.l, OPCODE_SET, bit, regValue.r); + + assertInstrED("in " + regValue.l + ", (c)", OPCODE_IN, regValue.r, 0); + assertInstrED("out (c), " + regValue.l, OPCODE_OUT, regValue.r, 1); + + forRegister(regValue2 -> { + assertInstr("ld " + regValue.l + ", " + regValue2.l, OPCODE_LD, 1, regValue.r, regValue2.r); + }); + }); } @Test - public void testInstrExpr() { - assertInstrExpr("lda", OPCODE_LDA); - assertInstrExpr("sta", OPCODE_STA); - assertInstrExpr("lhld", OPCODE_LHLD); - assertInstrExpr("shld", OPCODE_SHLD); - assertInstrExpr("adi", OPCODE_ADI); - assertInstrExpr("aci", OPCODE_ACI); - assertInstrExpr("sui", OPCODE_SUI); - assertInstrExpr("sbi", OPCODE_SBI); - assertInstrExpr("ani", OPCODE_ANI); - assertInstrExpr("ori", OPCODE_ORI); - assertInstrExpr("xri", OPCODE_XRI); - assertInstrExpr("cpi", OPCODE_CPI); - assertInstrExpr("jmp", OPCODE_JMP); - assertInstrExpr("jc", OPCODE_JC); - assertInstrExpr("jnc", OPCODE_JNC); - assertInstrExpr("jz", OPCODE_JZ); - assertInstrExpr("jnz", OPCODE_JNZ); - assertInstrExpr("jm", OPCODE_JM); - assertInstrExpr("jp", OPCODE_JP); - assertInstrExpr("jpe", OPCODE_JPE); - assertInstrExpr("jpo", OPCODE_JPO); - assertInstrExpr("call", OPCODE_CALL); - assertInstrExpr("cc", OPCODE_CC); - assertInstrExpr("cnc", OPCODE_CNC); - assertInstrExpr("cz", OPCODE_CZ); - assertInstrExpr("cnz", OPCODE_CNZ); - assertInstrExpr("cm", OPCODE_CM); - assertInstrExpr("cp", OPCODE_CP); - assertInstrExpr("cpe", OPCODE_CPE); - assertInstrExpr("cpo", OPCODE_CPO); - assertInstrExpr("in", OPCODE_IN); - assertInstrExpr("out", OPCODE_OUT); - assertInstrExpr("rst", OPCODE_RST); + public void testInstrRP() { + forRegPair(regPair -> { + assertInstrExpr("ld " + regPair.l + ", ", OPCODE_LD, 0, regPair.r, 0, 1); + assertInstr("add hl, " + regPair.l, OPCODE_ADD, 0, (regPair.r << 1) | 1, 1); + assertInstr("inc " + regPair.l, OPCODE_INC, 0, regPair.r, 0, 3); + assertInstr("dec " + regPair.l, OPCODE_DEC, 0, regPair.r, 1, 3); + assertInstrED("sbc hl, " + regPair.l, OPCODE_SBC, regPair.r << 1, 2); + assertInstrED("adc hl, " + regPair.l, OPCODE_ADC, (regPair.r << 1) | 1, 2); + assertInstrEDExpr("ld (", "), " + regPair.l, OPCODE_LD, regPair.r << 1, 3); + assertInstrEDExpr("ld " + regPair.l + ", (", ")" + regPair.l, OPCODE_LD, (regPair.r << 1) | 1, 3); + }); } @Test - public void testRegPair() { - assertInstrRegPair("stax", OPCODE_STAX, regPairsBD); - assertInstrRegPair("ldax", OPCODE_LDAX, regPairsBD); - assertInstrRegPair("dad", OPCODE_DAD, regPairsBDHSP); - assertInstrRegPair("inx", OPCODE_INX, regPairsBDHSP); - assertInstrRegPair("dcx", OPCODE_DCX, regPairsBDHSP); - assertInstrRegPair("push", OPCODE_PUSH, regPairsBDHAF); - assertInstrRegPair("pop", OPCODE_POP, regPairsBDHAF); + public void testInstrExpr() { + assertInstrExpr("ld (", "), hl", OPCODE_LD, 0, 4, 2); + assertInstrExpr("ld (", "), a", OPCODE_LD, 0, 6, 2); + assertInstrExpr("ld hl, (", ")", OPCODE_LD, 0, 5, 2); + assertInstrExpr("ld a, (", ")", OPCODE_LD, 0, 7, 2); + assertInstrExpr("jp ", OPCODE_JP, 3, 0, 3); + assertInstrExpr("out (", "), a", OPCODE_OUT, 3, 2, 3); + assertInstrExpr("in a, (", ")", OPCODE_IN, 3, 3, 3); + assertInstrExpr("call ", OPCODE_CALL, 3, 0, 1, 5); + assertInstrExpr("add a,", OPCODE_ADD, 3, 0, 6); + assertInstrExpr("adc a,", OPCODE_ADC, 3, 1, 6); + assertInstrExpr("sub", OPCODE_SUB, 3, 2, 6); + assertInstrExpr("sbc a,", OPCODE_SBC, 3, 3, 6); + assertInstrExpr("and", OPCODE_AND, 3, 4, 6); + assertInstrExpr("xor", OPCODE_XOR, 3, 5, 6); + assertInstrExpr("or", OPCODE_OR, 3, 6, 6); + assertInstrExpr("cp", OPCODE_CP, 3, 7, 6); + assertInstrExpr("rst", OPCODE_RST, 3, 0, 7); } - @Test - public void testMVI() { - Node expr = new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 5)); - forStringCaseVariations("mvi", instrVariation -> { - for (Map.Entry register : registers.entrySet()) { - forStringCaseVariations(register.getKey(), registerVariation -> { - String row = instrVariation + " " + registerVariation + ", $ + 5"; - Program program = parseProgram(row); - assertTrees( - new Program() - .addChild(new InstrR_N(0, 0, OPCODE_MVI, register.getValue()) - .addChild(expr)), - program - ); - }); - } + private void assertInstr(String instr, int instrType, int x, int y, int z) { + forStringCaseVariations(instr, variation -> { + Program program = parseProgram(variation); + assertTrees(new Program().addChild(new Instr(0, 0, instrType, x, y, z)), program); }); } - @Test - public void testLXI() { - Node expr = new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 5)); + private void assertInstr(String instr, int instrType, int x, int p, int q, int z) { + assertInstr(instr, instrType, x, (p << 1) | q, z); + } - forStringCaseVariations("lxi", instrVariation -> { - for (Map.Entry regPair : regPairsBDHSP.entrySet()) { - forStringCaseVariations(regPair.getKey(), registerVariation -> { - String row = instrVariation + " " + registerVariation + ", $ + 5"; - Program program = parseProgram(row); - assertTrees( - new Program() - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, regPair.getValue()) - .addChild(expr)), - program - ); - }); - } + private void assertInstrED(String instr, int instrType, int y, int z) { + forStringCaseVariations(instr, variation -> { + Program program = parseProgram(variation); + assertTrees(new Program().addChild(new InstrED(0, 0, instrType, y, z)), program); }); } - @Test - public void testMOV() { - forStringCaseVariations("mov", instrVariation -> { - for (Map.Entry register1 : registers.entrySet()) { - forStringCaseVariations(register1.getKey(), registerVariation1 -> { - for (Map.Entry register2 : registers.entrySet()) { - forStringCaseVariations(register2.getKey(), registerVariation2 -> { - if (!registerVariation1.toLowerCase(Locale.ENGLISH).equals("m") || !registerVariation1.equals(registerVariation2)) { - String row = instrVariation + " " + registerVariation1 + ", " + registerVariation2; - Program program = parseProgram(row); - assertTrees( - new Program() - .addChild(new InstrR_R(0, 0, OPCODE_MOV, register1.getValue(), register2.getValue())), - program - ); - } - }); - } - }); - } + private void assertInstrEDExpr(String instrPrefix, String instrPostfix, int instrType, int y, int z) { + Node expr = new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); + + forStringCaseVariations(instrPrefix, prefixVariation -> { + forStringCaseVariations(instrPostfix, postfixVariation -> { + Program program = parseProgram(prefixVariation + " $ + 5" + postfixVariation); + assertTrees(new Program().addChild(new InstrED(0, 0, instrType, y, z).addChild(expr)), program); + }); }); } - private void assertInstrNoArgs(String instr, int instrType) { + private void assertInstrCBNoArgs(String instr, int instrType, int y, int z) { forStringCaseVariations(instr, variation -> { Program program = parseProgram(variation); - assertTrees(new Program().addChild(new Instr(0, 0, instrType, x, y, z)), program); - }); - } - - private void assertInstrReg(String instr, int instrType) { - forStringCaseVariations(instr, instrVariation -> { - for (Map.Entry register : registers.entrySet()) { - forStringCaseVariations(register.getKey(), registerVariation -> { - String row = instrVariation + " " + registerVariation; - Program program = parseProgram(row); - assertTrees( - new Program().addChild(new InstrR(0, 0, instrType, register.getValue())), - program - ); - }); - } + assertTrees(new Program().addChild(new InstrCB(0, 0, instrType, y, z)), program); }); } - private void assertInstrExpr(String instr, int instrType) { + private void assertInstrExpr(String instrPrefix, String instrPostfix, int instrType, int x, int y, int z) { Node expr = new ExprInfix(0, 0, OP_ADD) .addChild(new ExprCurrentAddress(0, 0)) .addChild(new ExprNumber(0, 0, 5)); - forStringCaseVariations(instr, variation -> { - Program program = parseProgram(variation + " $ + 5"); - assertTrees(new Program().addChild(new InstrN(0, 0, instrType).addChild(expr)), program); + forStringCaseVariations(instrPrefix, prefixVariation -> { + forStringCaseVariations(instrPostfix, postfixVariation -> { + Program program = parseProgram(prefixVariation + " $ + 5" + postfixVariation); + assertTrees(new Program().addChild(new Instr(0, 0, instrType, x, y, z).addChild(expr)), program); + }); }); } - private void assertInstrRegPair(String instr, int instrType, Map regPairs) { - forStringCaseVariations(instr, instrVariation -> { - for (Map.Entry regPair : regPairs.entrySet()) { - forStringCaseVariations(regPair.getKey(), registerVariation -> { - String row = instrVariation + " " + registerVariation; - Program program = parseProgram(row); - assertTrees( - new Program().addChild(new InstrRP(0, 0, instrType, regPair.getValue())), - program - ); - }); - } + private void assertInstrExpr(String instr, int instrType, int x, int y, int z) { + assertInstrExpr(instr, "", instrType, x, y, z); + } + + private void assertInstrExpr(String instr, int instrType, int x, int p, int q, int z) { + assertInstrExpr(instr, instrType, x, (p << 1) | q, z); + } + + private void assertInstrCBExprBit(String instr, int instrType, int y, int z) { + Node expr = new ExprNumber(0, 0, y); + + forStringCaseVariations(instr, variation -> { + Program program = parseProgram(variation); + assertTrees(new Program().addChild(new InstrCB(0, 0, instrType, 0, z).addChild(expr)), program); }); } } From 0ff2c9d3f6a6c2a2f332ad33e1fb963d705a8985 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 19 Feb 2022 08:49:01 +0100 Subject: [PATCH 100/314] [#201] as-z80: small test fixes --- .../asZ80/visitors/CreatePseudoVisitor.java | 4 +- .../asZ80/parser/ParsePseudoTest.java | 8 +- .../asZ80/parser/ParsingUtilsTest.java | 2 +- .../visitors/CheckExprSizesVisitorTest.java | 73 +- .../visitors/EvaluateExprVisitorTest.java | 42 +- .../visitors/ExpandIncludesVisitorTest.java | 10 +- .../visitors/GenerateCodeVisitorTest.java | 1222 ++++++++--------- .../SortMacroArgumentsVisitorTest.java | 5 +- 8 files changed, 684 insertions(+), 682 deletions(-) diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java index c2cca16b8..69477ab9a 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java @@ -13,8 +13,8 @@ public class CreatePseudoVisitor extends AsZ80ParserBaseVisitor { @Override public Node visitPseudoOrg(PseudoOrgContext ctx) { Token start = ctx.getStart(); - PseudoOrg pseudo = new PseudoOrg(start.getLine(), start.getCharPositionInLine()); - pseudo.addChild(CreateVisitors.expr.visit(ctx.expr)); + Node pseudo = new PseudoOrg(start.getLine(), start.getCharPositionInLine()).setSizeBytes(2); + pseudo.addChild(CreateVisitors.expr.visit(ctx.expr).setSizeBytes(2)); return pseudo; } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java index 5d0131a19..ace1b00a3 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java @@ -61,8 +61,8 @@ public void testIf() { .addChild(new PseudoIf(0, 0) .addChild(new PseudoIfExpression(0, 0) .addChild(new ExprNumber(0, 0, 1))) - .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)) - .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z))), + .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)) + .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7))), program ); } @@ -129,9 +129,9 @@ public void testMacroDef() { .addChild(new ExprId(0, 0, "param1"))) .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "param2"))) - .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)) + .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)) .addChild(new PseudoLabel(0, 0, "heylabel") - .addChild(new InstrN(0, 0, OPCODE_ANI) + .addChild(new Instr(0, 0, OPCODE_AND, 3, 4, 6) .addChild(new ExprNumber(0, 0, 0x7F))))); assertTrees(expected, program); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java index 84036435b..7b2e4b86a 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java @@ -1,6 +1,5 @@ package net.emustudio.plugins.compiler.asZ80.parser; -import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; import net.emustudio.plugins.compiler.asZ80.ParsingUtils; import net.emustudio.plugins.compiler.asZ80.Utils; import org.antlr.v4.runtime.Token; @@ -9,6 +8,7 @@ import java.util.List; +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; import static net.emustudio.plugins.compiler.asZ80.Utils.assertTokenTypes; import static net.emustudio.plugins.compiler.asZ80.Utils.getTokens; import static org.junit.Assert.assertEquals; diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java index 10ecd0e6f..6eaaa5122 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java @@ -6,6 +6,7 @@ import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; +import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroArgument; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroCall; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoOrg; @@ -23,7 +24,7 @@ public void testDBoneByte() { Program program = new Program(); program .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0,0, 0xFF))); + .addChild(new Evaluated(0, 0, 0xFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -36,8 +37,8 @@ public void testDBtwoBytes() { Program program = new Program(); program .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0,0, 0xFF)) - .addChild(new Evaluated(0,0, 0x100))); // bad size + .addChild(new Evaluated(0, 0, 0xFF)) + .addChild(new Evaluated(0, 0, 0x100))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -50,7 +51,7 @@ public void testDWtwoBytes() { Program program = new Program(); program .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0,0, 0xFFFF))); + .addChild(new Evaluated(0, 0, 0xFFFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -63,8 +64,8 @@ public void testDWthreeBytes() { Program program = new Program(); program .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0,0, 0xFFFF)) - .addChild(new Evaluated(0,0, 0x10000))); + .addChild(new Evaluated(0, 0, 0xFFFF)) + .addChild(new Evaluated(0, 0, 0x10000))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -77,7 +78,7 @@ public void testDStwoBytes() { Program program = new Program(); program .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0,0, 0xFFFF))); + .addChild(new Evaluated(0, 0, 0xFFFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -90,7 +91,7 @@ public void testDSthreeBytes() { Program program = new Program(); program .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0,0, 0x10000))); + .addChild(new Evaluated(0, 0, 0x10000))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -102,8 +103,8 @@ public void testDSthreeBytes() { public void testInstrExprTwoBytes() { Program program = new Program(); program - .addChild(new InstrN(0, 0, OPCODE_ADI) - .addChild(new Evaluated(0,0, 0xFF00))); + .addChild(new Instr(0, 0, OPCODE_ADD, 3, 0, 6).setSizeBytes(2) + .addChild(new Evaluated(0, 0, 0xFF00).setSizeBytes(1))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -115,8 +116,8 @@ public void testInstrExprTwoBytes() { public void testInstrExprThreeBytes() { Program program = new Program(); program - .addChild(new InstrN(0, 0, OPCODE_JMP) - .addChild(new Evaluated(0,0, 0xFF000))); + .addChild(new Instr(0, 0, OPCODE_JP, 3, 0, 3).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0xFF000).setSizeBytes(2))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -128,8 +129,8 @@ public void testInstrExprThreeBytes() { public void testInstrRegExprOneByte() { Program program = new Program(); program - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0,0, 0xFF))); + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6).setSizeBytes(2) + .addChild(new Evaluated(0, 0, 0xFF).setSizeBytes(1))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -141,8 +142,8 @@ public void testInstrRegExprOneByte() { public void testInstrRegExprTwoBytes() { Program program = new Program(); program - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0,0, 0x100))); // bad size + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6).setSizeBytes(2) + .addChild(new Evaluated(0, 0, 0x100).setSizeBytes(1))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -154,8 +155,8 @@ public void testInstrRegExprTwoBytes() { public void testInstrRegPairExprTwoBytes() { Program program = new Program(); program - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0,0, 0xFFFF))); + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0xFFFF).setSizeBytes(2))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -167,8 +168,8 @@ public void testInstrRegPairExprTwoBytes() { public void testInstrRegPairExprThreeBytes() { Program program = new Program(); program - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0,0, 0x10000))); // bad size + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0x10000).setSizeBytes(2))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -180,8 +181,8 @@ public void testInstrRegPairExprThreeBytes() { public void testPseudoOrgTwoBytes() { Program program = new Program(); program - .addChild(new PseudoOrg(0, 0) - .addChild(new Evaluated(0,0, 0xFFFF))); + .addChild(new PseudoOrg(0, 0).setSizeBytes(2) + .addChild(new Evaluated(0, 0, 0xFFFF).setSizeBytes(2))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -193,8 +194,8 @@ public void testPseudoOrgTwoBytes() { public void testPseudoOrgThreeBytes() { Program program = new Program(); program - .addChild(new PseudoOrg(0, 0) - .addChild(new Evaluated(0,0, 0x10000))); // bad size + .addChild(new PseudoOrg(0, 0).setSizeBytes(2) + .addChild(new Evaluated(0, 0, 0x10000).setSizeBytes(2))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -210,16 +211,16 @@ public void testMacroArgumentsAreRemoved() { .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "arg")) .addChild(new Evaluated(0, 0, 0))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0).setSizeBytes(2))) .addChild(new PseudoMacroCall(0, 0, "y") .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "arg")) .addChild(new Evaluated(0, 0, 1))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 1)))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0)))); + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 1).setSizeBytes(2)))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0).setSizeBytes(2)))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -227,13 +228,13 @@ public void testMacroArgumentsAreRemoved() { assertTrees( new Program() .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0).setSizeBytes(2))) .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 1)))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0)))), + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 1).setSizeBytes(2)))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0).setSizeBytes(2)))), program ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java index a323a911a..b35805b98 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java @@ -181,14 +181,14 @@ public void testEvaluateEQUfivePasses() { public void testEvaluateIFwithForwardConst() { Program program = new Program(); program - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) .addChild(new ExprId(0, 0, "const"))) .addChild(new PseudoIf(0, 0) .addChild(new PseudoIfExpression(0, 0) .addChild(new ExprInfix(0, 0, OP_EQUAL) .addChild(new ExprCurrentAddress(0, 0)) .addChild(new ExprNumber(0, 0, 2)))) - .addChild(new InstrN(0, 0, OPCODE_RST) + .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) .addChild(new ExprNumber(0, 0, 0)))) .addChild(new PseudoEqu(0, 0, "const") .addChild(new ExprInfix(0, 0, OP_ADD) @@ -200,9 +200,9 @@ public void testEvaluateIFwithForwardConst() { assertTrees( new Program() - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) .addChild(new Evaluated(0, 0, 6))) - .addChild(new InstrN(0, 0, OPCODE_RST) + .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) .addChild(new Evaluated(0, 0, 0))), program ); @@ -219,7 +219,7 @@ public void testEvaluateIFwithForwardAddressReference() { .addChild(new ExprInfix(0, 0, OP_EQUAL) .addChild(new ExprCurrentAddress(0, 0)) .addChild(new ExprId(0, 0, "const")))) - .addChild(new InstrN(0, 0, OPCODE_RST) + .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) .addChild(new ExprNumber(0, 0, 0)))) .addChild(new PseudoEqu(0, 0, "const") .addChild(new ExprInfix(0, 0, OP_ADD) @@ -239,7 +239,7 @@ public void testEvaluateIFexcludeBlock() { .addChild(new PseudoIf(0, 0) .addChild(new PseudoIfExpression(0, 0) .addChild(new ExprNumber(0, 0, 0))) - .addChild(new InstrN(0, 0, OPCODE_RST) + .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) .addChild(new ExprNumber(0, 0, 0)))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); @@ -252,11 +252,11 @@ public void testEvaluateIFexcludeBlock() { public void testEvaluateSETforwardTwoTimes() { Program program = new Program(); program - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) .addChild(new ExprId(0, 0, "const"))) .addChild(new PseudoSet(0, 0, "const") .addChild(new ExprNumber(0, 0, 1))) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 6) .addChild(new ExprId(0, 0, "const"))) .addChild(new PseudoSet(0, 0, "const") .addChild(new ExprNumber(0, 0, 2))); @@ -266,11 +266,11 @@ public void testEvaluateSETforwardTwoTimes() { assertTrees( new Program() - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) .addChild(new Evaluated(0, 0, 1))) .addChild(new PseudoSet(0, 0, "const") .addChild(new Evaluated(0, 0, 1))) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 6) .addChild(new Evaluated(0, 0, 1))) .addChild(new PseudoSet(0, 0, "const") .addChild(new Evaluated(0, 0, 2))), @@ -372,7 +372,7 @@ public void testEvaluateMacroCalls() { .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "addr")) .addChild(new ExprId(0, 0, "label"))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) .addChild(new ExprId(0, 0, "addr")))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); @@ -384,7 +384,7 @@ public void testEvaluateMacroCalls() { .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "addr")) .addChild(new Evaluated(0, 0, 0))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) .addChild(new Evaluated(0, 0, 0)))), program ); @@ -398,7 +398,7 @@ public void testEvaluateMacroCallAmbiguous() { .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "label")) .addChild(new ExprId(0, 0, "addr"))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) .addChild(new ExprId(0, 0, "addr")))) .addChild(new PseudoLabel(0, 0, "label")); @@ -416,15 +416,15 @@ public void testEvaluateMacroScopedArguments() { .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "arg")) .addChild(new ExprNumber(0, 0, 0))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) .addChild(new ExprId(0, 0, "arg"))) .addChild(new PseudoMacroCall(0, 0, "y") .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "arg")) .addChild(new ExprNumber(0, 0, 1))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) .addChild(new ExprId(0, 0, "arg")))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) .addChild(new ExprId(0, 0, "arg")))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); @@ -436,15 +436,15 @@ public void testEvaluateMacroScopedArguments() { .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "arg")) .addChild(new Evaluated(0, 0, 0))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) .addChild(new Evaluated(0, 0, 0))) .addChild(new PseudoMacroCall(0, 0, "y") .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "arg")) .addChild(new Evaluated(0, 0, 1))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) .addChild(new Evaluated(0, 0, 1)))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) .addChild(new Evaluated(0, 0, 0)))), program ); @@ -455,13 +455,13 @@ public void testLabelKeepsChildren() { Program program = new Program(); program .addChild(new PseudoLabel(0, 0, "label") - .addChild(new Instr(0, 0, OPCODE_RET, x, y, z))); + .addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program().addChild(new Instr(0, 0, OPCODE_RET, x, y, z)), + new Program().addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1)), program ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java index 939b35ebe..140223109 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java @@ -30,11 +30,11 @@ public void testExpandInclude() { visitor.visit(program); Node expected = new Program() - .addChild(new Instr(0, 0, OPCODE_CMC, x, y, z)) + .addChild(new Instr(0, 0, OPCODE_CCF, 0, 7, 7)) .addChild(new PseudoLabel(0, 0, "sample") - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) .addChild(new ExprNumber(0, 0, 0)))) - .addChild(new Instr(0, 0, OPCODE_RET, x, y, z)); + .addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1)); assertTrees(expected, program); } @@ -52,8 +52,8 @@ public void testExpandIncludeTwoTimes() throws IOException { visitor.visit(program); Node expected = new Program() - .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)) - .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)); + .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)) + .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)); assertTrees(expected, program); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java index 06f69eb7c..4326eb559 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java @@ -24,19 +24,19 @@ public void testCodeGeneration() { program .addChild(new DataDB(0, 0) .addChild(new Evaluated(0, 0, 255)) - .addChild(new InstrN(0, 0, OPCODE_RST) + .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) .addChild(new Evaluated(0, 0, 4)))) .addChild(new DataDW(0, 0) .addChild(new Evaluated(0, 0, 1))) .addChild(new DataDS(0, 0) .addChild(new Evaluated(0, 0, 5))) .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) .addChild(new Evaluated(0, 0, 0xFEAB))) .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_D) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 2, 1) .addChild(new Evaluated(0, 0, 1)))) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_H) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 4, 1) .addChild(new Evaluated(0, 0, 0x1234)))); IntelHEX hex = new IntelHEX(); @@ -70,11 +70,11 @@ public void testPseudoOrg() { program .addChild(new PseudoOrg(0, 0) .addChild(new Evaluated(0, 0, 5))) - .addChild(new InstrN(0, 0, OPCODE_CNZ) - .addChild(new Evaluated(0, 0, 0x400))) + .addChild(new Instr(0, 0, OPCODE_CALL, 3, 0, 4)) + .addChild(new Evaluated(0, 0, 0x400)) .addChild(new PseudoOrg(0, 0) .addChild(new Evaluated(0, 0, 0))) - .addChild(new Instr(0, 0, OPCODE_XCHG, x, y, z)); + .addChild(new Instr(0, 0, OPCODE_EX, 3, 5, 3)); IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); @@ -91,302 +91,302 @@ public void testPseudoOrg() { public void testGenerateInstructions() { Program program = new Program(); program - .addChild(new Instr(0, 0, OPCODE_NOP, x, y, z)) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_B) + .addChild(new Instr(0, 0, OPCODE_NOP, 0, 0, 0)) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrRP(0, 0, OPCODE_STAX, REG_B)) - .addChild(new InstrRP(0, 0, OPCODE_INX, REG_B)) - .addChild(new InstrR(0, 0, OPCODE_INR, REG_B)) - .addChild(new InstrR(0, 0, OPCODE_DCR, REG_B)) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_B) - .addChild(new Evaluated(0, 0, 7))) - .addChild(new Instr(0, 0, OPCODE_RLC, x, y, z)) - .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_B)) - .addChild(new InstrRP(0, 0, OPCODE_LDAX, REG_B)) - .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_B)) - .addChild(new InstrR(0, 0, OPCODE_INR, REG_C)) - .addChild(new InstrR(0, 0, OPCODE_DCR, REG_C)) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_C) - .addChild(new Evaluated(0, 0, 8))) - .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_D) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrRP(0, 0, OPCODE_STAX, REG_D)) - .addChild(new InstrRP(0, 0, OPCODE_INX, REG_D)) - .addChild(new InstrR(0, 0, OPCODE_INR, REG_D)) - .addChild(new InstrR(0, 0, OPCODE_DCR, REG_D)) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_D) - .addChild(new Evaluated(0, 0, 9))) - .addChild(new Instr(0, 0, OPCODE_RAL, x, y, z)) - .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_D)) - .addChild(new InstrRP(0, 0, OPCODE_LDAX, REG_D)) - .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_D)) - .addChild(new InstrR(0, 0, OPCODE_INR, REG_E)) - .addChild(new InstrR(0, 0, OPCODE_DCR, REG_E)) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_E) - .addChild(new Evaluated(0, 0, 10))) - .addChild(new Instr(0, 0, OPCODE_RAR, x, y, z)) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_H) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrN(0, 0, OPCODE_SHLD) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrRP(0, 0, OPCODE_INX, REG_H)) - .addChild(new InstrR(0, 0, OPCODE_INR, REG_H)) - .addChild(new InstrR(0, 0, OPCODE_DCR, REG_H)) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_H) - .addChild(new Evaluated(0, 0, 0x28))) - .addChild(new Instr(0, 0, OPCODE_DAA, x, y, z)) - .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_H)) - .addChild(new InstrN(0, 0, OPCODE_LHLD) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_H)) - .addChild(new InstrR(0, 0, OPCODE_INR, REG_L)) - .addChild(new InstrR(0, 0, OPCODE_DCR, REG_L)) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_L) - .addChild(new Evaluated(0, 0, 10))) - .addChild(new Instr(0, 0, OPCODE_CMA, x, y, z)) - .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_SP) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrN(0, 0, OPCODE_STA) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrRP(0, 0, OPCODE_INX, REG_SP)) - .addChild(new InstrR(0, 0, OPCODE_INR, REG_M)) - .addChild(new InstrR(0, 0, OPCODE_DCR, REG_M)) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_M) - .addChild(new Evaluated(0, 0, 7))) - .addChild(new Instr(0, 0, OPCODE_STC, x, y, z)) - .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_SP)) - .addChild(new InstrN(0, 0, OPCODE_LDA) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_SP)) - .addChild(new InstrR(0, 0, OPCODE_INR, REG_A)) - .addChild(new InstrR(0, 0, OPCODE_DCR, REG_A)) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0, 0, -128))) - .addChild(new Instr(0, 0, OPCODE_CMC, x, y, z)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_B)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_C)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_D)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_E)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_H)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_L)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_M)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_A)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_B)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_C)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_D)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_E)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_H)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_L)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_M)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_A)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_B)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_C)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_D)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_E)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_H)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_L)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_M)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_A)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_B)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_C)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_D)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_E)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_H)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_L)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_M)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_A)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_B)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_C)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_D)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_E)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_H)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_L)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_M)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_A)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_B)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_C)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_D)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_E)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_H)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_L)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_M)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_A)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_B)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_C)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_D)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_E)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_H)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_L)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_M)) // HLT - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_A)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_B)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_C)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_D)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_E)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_H)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_L)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_M)) - .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_A)) - .addChild(new InstrR(0, 0, OPCODE_ADD, REG_B)) - .addChild(new InstrR(0, 0, OPCODE_ADD, REG_C)) - .addChild(new InstrR(0, 0, OPCODE_ADD, REG_D)) - .addChild(new InstrR(0, 0, OPCODE_ADD, REG_E)) - .addChild(new InstrR(0, 0, OPCODE_ADD, REG_H)) - .addChild(new InstrR(0, 0, OPCODE_ADD, REG_L)) - .addChild(new InstrR(0, 0, OPCODE_ADD, REG_M)) - .addChild(new InstrR(0, 0, OPCODE_ADD, REG_A)) - .addChild(new InstrR(0, 0, OPCODE_ADC, REG_B)) - .addChild(new InstrR(0, 0, OPCODE_ADC, REG_C)) - .addChild(new InstrR(0, 0, OPCODE_ADC, REG_D)) - .addChild(new InstrR(0, 0, OPCODE_ADC, REG_E)) - .addChild(new InstrR(0, 0, OPCODE_ADC, REG_H)) - .addChild(new InstrR(0, 0, OPCODE_ADC, REG_L)) - .addChild(new InstrR(0, 0, OPCODE_ADC, REG_M)) - .addChild(new InstrR(0, 0, OPCODE_ADC, REG_A)) - .addChild(new InstrR(0, 0, OPCODE_SUB, REG_B)) - .addChild(new InstrR(0, 0, OPCODE_SUB, REG_C)) - .addChild(new InstrR(0, 0, OPCODE_SUB, REG_D)) - .addChild(new InstrR(0, 0, OPCODE_SUB, REG_E)) - .addChild(new InstrR(0, 0, OPCODE_SUB, REG_H)) - .addChild(new InstrR(0, 0, OPCODE_SUB, REG_L)) - .addChild(new InstrR(0, 0, OPCODE_SUB, REG_M)) - .addChild(new InstrR(0, 0, OPCODE_SUB, REG_A)) - .addChild(new InstrR(0, 0, OPCODE_SBB, REG_B)) - .addChild(new InstrR(0, 0, OPCODE_SBB, REG_C)) - .addChild(new InstrR(0, 0, OPCODE_SBB, REG_D)) - .addChild(new InstrR(0, 0, OPCODE_SBB, REG_E)) - .addChild(new InstrR(0, 0, OPCODE_SBB, REG_H)) - .addChild(new InstrR(0, 0, OPCODE_SBB, REG_L)) - .addChild(new InstrR(0, 0, OPCODE_SBB, REG_M)) - .addChild(new InstrR(0, 0, OPCODE_SBB, REG_A)) - .addChild(new InstrR(0, 0, OPCODE_ANA, REG_B)) - .addChild(new InstrR(0, 0, OPCODE_ANA, REG_C)) - .addChild(new InstrR(0, 0, OPCODE_ANA, REG_D)) - .addChild(new InstrR(0, 0, OPCODE_ANA, REG_E)) - .addChild(new InstrR(0, 0, OPCODE_ANA, REG_H)) - .addChild(new InstrR(0, 0, OPCODE_ANA, REG_L)) - .addChild(new InstrR(0, 0, OPCODE_ANA, REG_M)) - .addChild(new InstrR(0, 0, OPCODE_ANA, REG_A)) - .addChild(new InstrR(0, 0, OPCODE_XRA, REG_B)) - .addChild(new InstrR(0, 0, OPCODE_XRA, REG_C)) - .addChild(new InstrR(0, 0, OPCODE_XRA, REG_D)) - .addChild(new InstrR(0, 0, OPCODE_XRA, REG_E)) - .addChild(new InstrR(0, 0, OPCODE_XRA, REG_H)) - .addChild(new InstrR(0, 0, OPCODE_XRA, REG_L)) - .addChild(new InstrR(0, 0, OPCODE_XRA, REG_M)) - .addChild(new InstrR(0, 0, OPCODE_XRA, REG_A)) - .addChild(new InstrR(0, 0, OPCODE_ORA, REG_B)) - .addChild(new InstrR(0, 0, OPCODE_ORA, REG_C)) - .addChild(new InstrR(0, 0, OPCODE_ORA, REG_D)) - .addChild(new InstrR(0, 0, OPCODE_ORA, REG_E)) - .addChild(new InstrR(0, 0, OPCODE_ORA, REG_H)) - .addChild(new InstrR(0, 0, OPCODE_ORA, REG_L)) - .addChild(new InstrR(0, 0, OPCODE_ORA, REG_M)) - .addChild(new InstrR(0, 0, OPCODE_ORA, REG_A)) - .addChild(new InstrR(0, 0, OPCODE_CMP, REG_B)) - .addChild(new InstrR(0, 0, OPCODE_CMP, REG_C)) - .addChild(new InstrR(0, 0, OPCODE_CMP, REG_D)) - .addChild(new InstrR(0, 0, OPCODE_CMP, REG_E)) - .addChild(new InstrR(0, 0, OPCODE_CMP, REG_H)) - .addChild(new InstrR(0, 0, OPCODE_CMP, REG_L)) - .addChild(new InstrR(0, 0, OPCODE_CMP, REG_M)) - .addChild(new InstrR(0, 0, OPCODE_CMP, REG_A)) - .addChild(new Instr(0, 0, OPCODE_RNZ, x, y, z)) - .addChild(new InstrRP(0, 0, OPCODE_POP, REG_B)) - .addChild(new InstrN(0, 0, OPCODE_JNZ) - .addChild(new Evaluated(0, 0, 2))) - .addChild(new InstrN(0, 0, OPCODE_JMP) - .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new InstrN(0, 0, OPCODE_CNZ) - .addChild(new Evaluated(0, 0, 0xF0A0))) - .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_B)) - .addChild(new InstrN(0, 0, OPCODE_ADI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrN(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new Instr(0, 0, OPCODE_RZ, x, y, z)) - .addChild(new Instr(0, 0, OPCODE_RET, x, y, z)) - .addChild(new InstrN(0, 0, OPCODE_JZ) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrN(0, 0, OPCODE_CZ) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrN(0, 0, OPCODE_CALL) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrN(0, 0, OPCODE_ACI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrN(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new Instr(0, 0, OPCODE_RNC, x, y, z)) - .addChild(new InstrRP(0, 0, OPCODE_POP, REG_D)) - .addChild(new InstrN(0, 0, OPCODE_JNC) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrN(0, 0, OPCODE_OUT) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrN(0, 0, OPCODE_CNC) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_D)) - .addChild(new InstrN(0, 0, OPCODE_SUI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrN(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 2))) - .addChild(new Instr(0, 0, OPCODE_RC, x, y, z)) - .addChild(new InstrN(0, 0, OPCODE_JC) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrN(0, 0, OPCODE_IN) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrN(0, 0, OPCODE_CC) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrN(0, 0, OPCODE_SBI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrN(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 3))) - .addChild(new Instr(0, 0, OPCODE_RPO, x, y, z)) - .addChild(new InstrRP(0, 0, OPCODE_POP, REG_H)) - .addChild(new InstrN(0, 0, OPCODE_JPO) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new Instr(0, 0, OPCODE_XTHL, x, y, z)) - .addChild(new InstrN(0, 0, OPCODE_CPO) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_H)) - .addChild(new InstrN(0, 0, OPCODE_ANI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrN(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 4))) - .addChild(new Instr(0, 0, OPCODE_RPE, x, y, z)) - .addChild(new Instr(0, 0, OPCODE_PCHL, x, y, z)) - .addChild(new InstrN(0, 0, OPCODE_JPE) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new Instr(0, 0, OPCODE_XCHG, x, y, z)) - .addChild(new InstrN(0, 0, OPCODE_CPE) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrN(0, 0, OPCODE_XRI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrN(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 5))) - .addChild(new Instr(0, 0, OPCODE_RP, x, y, z)) - .addChild(new InstrRP(0, 0, OPCODE_POP, REG_PSW)) - .addChild(new InstrN(0, 0, OPCODE_JP) - .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new Instr(0, 0, OPCODE_DI, x, y, z)) - .addChild(new InstrN(0, 0, OPCODE_CP) - .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_PSW)) - .addChild(new InstrN(0, 0, OPCODE_ORI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrN(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 6))) - .addChild(new Instr(0, 0, OPCODE_RM, x, y, z)) - .addChild(new Instr(0, 0, OPCODE_SPHL, x, y, z)) - .addChild(new InstrN(0, 0, OPCODE_JM) - .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new Instr(0, 0, OPCODE_EI, x, y, z)) - .addChild(new InstrN(0, 0, OPCODE_CM) - .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new InstrN(0, 0, OPCODE_CPI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrN(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 7))); + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 2)); +// .addChild(new InstrRP(0, 0, OPCODE_INX, REG_B)) +// .addChild(new InstrR(0, 0, OPCODE_INR, REG_B)) +// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_B)) +// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_B) +// .addChild(new Evaluated(0, 0, 7))) +// .addChild(new Instr(0, 0, OPCODE_RLC, x, y, z)) +// .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_B)) +// .addChild(new InstrRP(0, 0, OPCODE_LDAX, REG_B)) +// .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_B)) +// .addChild(new InstrR(0, 0, OPCODE_INR, REG_C)) +// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_C)) +// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_C) +// .addChild(new Evaluated(0, 0, 8))) +// .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)) +// .addChild(new Instr(0, 0, OPCODE_LD, 0, 2, 1) +// .addChild(new Evaluated(0, 0, 0x2345))) +// .addChild(new InstrRP(0, 0, OPCODE_STAX, REG_D)) +// .addChild(new InstrRP(0, 0, OPCODE_INX, REG_D)) +// .addChild(new InstrR(0, 0, OPCODE_INR, REG_D)) +// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_D)) +// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_D) +// .addChild(new Evaluated(0, 0, 9))) +// .addChild(new Instr(0, 0, OPCODE_RAL, x, y, z)) +// .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_D)) +// .addChild(new InstrRP(0, 0, OPCODE_LDAX, REG_D)) +// .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_D)) +// .addChild(new InstrR(0, 0, OPCODE_INR, REG_E)) +// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_E)) +// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_E) +// .addChild(new Evaluated(0, 0, 10))) +// .addChild(new Instr(0, 0, OPCODE_RAR, x, y, z)) +// .addChild(new Instr(0, 0, OPCODE_LD, 0, 4, 1) +// .addChild(new Evaluated(0, 0, 0x2345))) +// .addChild(new InstrN(0, 0, OPCODE_SHLD) +// .addChild(new Evaluated(0, 0, 0x2345))) +// .addChild(new InstrRP(0, 0, OPCODE_INX, REG_H)) +// .addChild(new InstrR(0, 0, OPCODE_INR, REG_H)) +// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_H)) +// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_H) +// .addChild(new Evaluated(0, 0, 0x28))) +// .addChild(new Instr(0, 0, OPCODE_DAA, x, y, z)) +// .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_H)) +// .addChild(new InstrN(0, 0, OPCODE_LHLD) +// .addChild(new Evaluated(0, 0, 0x2345))) +// .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_H)) +// .addChild(new InstrR(0, 0, OPCODE_INR, REG_L)) +// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_L)) +// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_L) +// .addChild(new Evaluated(0, 0, 10))) +// .addChild(new Instr(0, 0, OPCODE_CMA, x, y, z)) +// .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_SP) +// .addChild(new Evaluated(0, 0, 0x2345))) +// .addChild(new InstrN(0, 0, OPCODE_STA) +// .addChild(new Evaluated(0, 0, 0x2345))) +// .addChild(new InstrRP(0, 0, OPCODE_INX, REG_SP)) +// .addChild(new InstrR(0, 0, OPCODE_INR, REG_M)) +// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_M)) +// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_M) +// .addChild(new Evaluated(0, 0, 7))) +// .addChild(new Instr(0, 0, OPCODE_STC, x, y, z)) +// .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_SP)) +// .addChild(new InstrN(0, 0, OPCODE_LDA) +// .addChild(new Evaluated(0, 0, 0x2345))) +// .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_SP)) +// .addChild(new InstrR(0, 0, OPCODE_INR, REG_A)) +// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_A)) +// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) +// .addChild(new Evaluated(0, 0, -128))) +// .addChild(new Instr(0, 0, OPCODE_CMC, x, y, z)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_B)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_C)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_D)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_E)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_H)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_L)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_M)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_A)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_B)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_C)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_D)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_E)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_H)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_L)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_M)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_A)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_B)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_C)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_D)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_E)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_H)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_L)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_M)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_A)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_B)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_C)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_D)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_E)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_H)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_L)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_M)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_A)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_B)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_C)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_D)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_E)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_H)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_L)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_M)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_A)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_B)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_C)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_D)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_E)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_H)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_L)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_M)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_A)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_B)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_C)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_D)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_E)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_H)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_L)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_M)) // HLT +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_A)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_B)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_C)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_D)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_E)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_H)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_L)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_M)) +// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_A)) +// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_B)) +// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_C)) +// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_D)) +// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_E)) +// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_H)) +// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_L)) +// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_M)) +// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_A)) +// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_B)) +// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_C)) +// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_D)) +// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_E)) +// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_H)) +// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_L)) +// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_M)) +// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_A)) +// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_B)) +// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_C)) +// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_D)) +// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_E)) +// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_H)) +// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_L)) +// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_M)) +// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_A)) +// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_B)) +// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_C)) +// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_D)) +// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_E)) +// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_H)) +// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_L)) +// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_M)) +// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_A)) +// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_B)) +// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_C)) +// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_D)) +// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_E)) +// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_H)) +// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_L)) +// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_M)) +// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_A)) +// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_B)) +// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_C)) +// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_D)) +// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_E)) +// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_H)) +// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_L)) +// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_M)) +// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_A)) +// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_B)) +// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_C)) +// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_D)) +// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_E)) +// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_H)) +// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_L)) +// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_M)) +// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_A)) +// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_B)) +// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_C)) +// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_D)) +// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_E)) +// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_H)) +// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_L)) +// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_M)) +// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_A)) +// .addChild(new Instr(0, 0, OPCODE_RNZ, x, y, z)) +// .addChild(new InstrRP(0, 0, OPCODE_POP, REG_B)) +// .addChild(new InstrN(0, 0, OPCODE_JNZ) +// .addChild(new Evaluated(0, 0, 2))) +// .addChild(new InstrN(0, 0, OPCODE_JMP) +// .addChild(new Evaluated(0, 0, 0x200))) +// .addChild(new Instr(0, 0, OPCODE_CALL, 3, 0, 4) +// .addChild(new Evaluated(0, 0, 0xF0A0))) +// .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_B)) +// .addChild(new InstrN(0, 0, OPCODE_ADI) +// .addChild(new Evaluated(0, 0, 0xF0))) +// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) +// .addChild(new Evaluated(0, 0, 0))) +// .addChild(new Instr(0, 0, OPCODE_RZ, x, y, z)) +// .addChild(new Instr(0, 0, OPCODE_RET, x, y, z)) +// .addChild(new InstrN(0, 0, OPCODE_JZ) +// .addChild(new Evaluated(0, 0, 0x1234))) +// .addChild(new InstrN(0, 0, OPCODE_CZ) +// .addChild(new Evaluated(0, 0, 0x1234))) +// .addChild(new InstrN(0, 0, OPCODE_CALL) +// .addChild(new Evaluated(0, 0, 0x1234))) +// .addChild(new InstrN(0, 0, OPCODE_ACI) +// .addChild(new Evaluated(0, 0, 0xF0))) +// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) +// .addChild(new Evaluated(0, 0, 1))) +// .addChild(new Instr(0, 0, OPCODE_RNC, x, y, z)) +// .addChild(new InstrRP(0, 0, OPCODE_POP, REG_D)) +// .addChild(new InstrN(0, 0, OPCODE_JNC) +// .addChild(new Evaluated(0, 0, 0x1234))) +// .addChild(new InstrN(0, 0, OPCODE_OUT) +// .addChild(new Evaluated(0, 0, 0xF0))) +// .addChild(new InstrN(0, 0, OPCODE_CNC) +// .addChild(new Evaluated(0, 0, 0x1234))) +// .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_D)) +// .addChild(new InstrN(0, 0, OPCODE_SUI) +// .addChild(new Evaluated(0, 0, 0xF0))) +// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) +// .addChild(new Evaluated(0, 0, 2))) +// .addChild(new Instr(0, 0, OPCODE_RC, x, y, z)) +// .addChild(new InstrN(0, 0, OPCODE_JC) +// .addChild(new Evaluated(0, 0, 0x1234))) +// .addChild(new InstrN(0, 0, OPCODE_IN) +// .addChild(new Evaluated(0, 0, 0xF0))) +// .addChild(new InstrN(0, 0, OPCODE_CC) +// .addChild(new Evaluated(0, 0, 0x1234))) +// .addChild(new InstrN(0, 0, OPCODE_SBI) +// .addChild(new Evaluated(0, 0, 0xF0))) +// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) +// .addChild(new Evaluated(0, 0, 3))) +// .addChild(new Instr(0, 0, OPCODE_RPO, x, y, z)) +// .addChild(new InstrRP(0, 0, OPCODE_POP, REG_H)) +// .addChild(new InstrN(0, 0, OPCODE_JPO) +// .addChild(new Evaluated(0, 0, 0x1234))) +// .addChild(new Instr(0, 0, OPCODE_XTHL, x, y, z)) +// .addChild(new InstrN(0, 0, OPCODE_CPO) +// .addChild(new Evaluated(0, 0, 0x1234))) +// .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_H)) +// .addChild(new InstrN(0, 0, OPCODE_ANI) +// .addChild(new Evaluated(0, 0, 0xF0))) +// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) +// .addChild(new Evaluated(0, 0, 4))) +// .addChild(new Instr(0, 0, OPCODE_RPE, x, y, z)) +// .addChild(new Instr(0, 0, OPCODE_PCHL, x, y, z)) +// .addChild(new InstrN(0, 0, OPCODE_JPE) +// .addChild(new Evaluated(0, 0, 0x1234))) +// .addChild(new Instr(0, 0, OPCODE_EX, 3, 5, 3)) +// .addChild(new InstrN(0, 0, OPCODE_CPE) +// .addChild(new Evaluated(0, 0, 0x1234))) +// .addChild(new InstrN(0, 0, OPCODE_XRI) +// .addChild(new Evaluated(0, 0, 0xF0))) +// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) +// .addChild(new Evaluated(0, 0, 5))) +// .addChild(new Instr(0, 0, OPCODE_RP, x, y, z)) +// .addChild(new InstrRP(0, 0, OPCODE_POP, REG_PSW)) +// .addChild(new InstrN(0, 0, OPCODE_JP) +// .addChild(new Evaluated(0, 0, 0x200))) +// .addChild(new Instr(0, 0, OPCODE_DI, x, y, z)) +// .addChild(new InstrN(0, 0, OPCODE_CP) +// .addChild(new Evaluated(0, 0, 0x200))) +// .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_PSW)) +// .addChild(new InstrN(0, 0, OPCODE_ORI) +// .addChild(new Evaluated(0, 0, 0xF0))) +// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) +// .addChild(new Evaluated(0, 0, 6))) +// .addChild(new Instr(0, 0, OPCODE_RM, x, y, z)) +// .addChild(new Instr(0, 0, OPCODE_SPHL, x, y, z)) +// .addChild(new InstrN(0, 0, OPCODE_JM) +// .addChild(new Evaluated(0, 0, 0x200))) +// .addChild(new Instr(0, 0, OPCODE_EI, x, y, z)) +// .addChild(new InstrN(0, 0, OPCODE_CM) +// .addChild(new Evaluated(0, 0, 0x200))) +// .addChild(new InstrN(0, 0, OPCODE_CPI) +// .addChild(new Evaluated(0, 0, 0xF0))) +// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) +// .addChild(new Evaluated(0, 0, 7))); IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); @@ -398,314 +398,314 @@ public void testGenerateInstructions() { assertEquals(0x34, code.get(2).byteValue()); assertEquals(0x12, code.get(3).byteValue()); assertEquals(2, code.get(4).byteValue()); // STAX B - assertEquals(3, code.get(5).byteValue()); // INX B - assertEquals(4, code.get(6).byteValue()); // INR B - assertEquals(5, code.get(7).byteValue()); // DCR B - assertEquals(6, code.get(8).byteValue()); // MVI B - assertEquals(7, code.get(9).byteValue()); - assertEquals(7, code.get(10).byteValue()); // RLC - assertEquals(9, code.get(11).byteValue()); // DAD B - assertEquals(0x0A, code.get(12).byteValue()); // LDAX B - assertEquals(0x0B, code.get(13).byteValue()); // DCX B - assertEquals(0x0C, code.get(14).byteValue()); // INR C - assertEquals(0x0D, code.get(15).byteValue()); // DCR C - assertEquals(0x0E, code.get(16).byteValue()); // MVI C - assertEquals(8, code.get(17).byteValue()); - assertEquals(0x0F, code.get(18).byteValue()); // RRC - assertEquals(0x11, code.get(19).byteValue()); // LXI D - assertEquals(0x45, code.get(20).byteValue()); - assertEquals(0x23, code.get(21).byteValue()); - assertEquals(0x12, code.get(22).byteValue()); // STAX D - assertEquals(0x13, code.get(23).byteValue()); // INX D - assertEquals(0x14, code.get(24).byteValue()); // INR D - assertEquals(0x15, code.get(25).byteValue()); // DCR D - assertEquals(0x16, code.get(26).byteValue()); // MVI D - assertEquals(9, code.get(27).byteValue()); - assertEquals(0x17, code.get(28).byteValue()); // RAL - assertEquals(0x19, code.get(29).byteValue()); // DAD D - assertEquals(0x1A, code.get(30).byteValue()); // LDAX D - assertEquals(0x1B, code.get(31).byteValue()); // DCX D - assertEquals(0x1C, code.get(32).byteValue()); // INR E - assertEquals(0x1D, code.get(33).byteValue()); // DCR E - assertEquals(0x1E, code.get(34).byteValue()); // MVI E - assertEquals(10, code.get(35).byteValue()); - assertEquals(0x1F, code.get(36).byteValue()); // RAR - assertEquals(0x21, code.get(37).byteValue()); // LXI H - assertEquals(0x45, code.get(38).byteValue()); - assertEquals(0x23, code.get(39).byteValue()); - assertEquals(0x22, code.get(40).byteValue()); // SHLD - assertEquals(0x45, code.get(41).byteValue()); - assertEquals(0x23, code.get(42).byteValue()); - assertEquals(0x23, code.get(43).byteValue()); // INX H - assertEquals(0x24, code.get(44).byteValue()); // INR H - assertEquals(0x25, code.get(45).byteValue()); // DCR H - assertEquals(0x26, code.get(46).byteValue()); // MVI H - assertEquals(0x28, code.get(47).byteValue()); - assertEquals(0x27, code.get(48).byteValue()); // DAA - assertEquals(0x29, code.get(49).byteValue()); // DAD H - assertEquals(0x2A, code.get(50).byteValue()); // LHLD - assertEquals(0x45, code.get(51).byteValue()); - assertEquals(0x23, code.get(52).byteValue()); - assertEquals(0x2B, code.get(53).byteValue()); // DCX H - assertEquals(0x2C, code.get(54).byteValue()); // INR L - assertEquals(0x2D, code.get(55).byteValue()); // DCR L - assertEquals(0x2E, code.get(56).byteValue()); // MVI L - assertEquals(10, code.get(57).byteValue()); - assertEquals(0x2F, code.get(58).byteValue()); // CMA - assertEquals(0x31, code.get(59).byteValue()); // LXI SP - assertEquals(0x45, code.get(60).byteValue()); - assertEquals(0x23, code.get(61).byteValue()); - assertEquals(0x32, code.get(62).byteValue()); // STA - assertEquals(0x45, code.get(63).byteValue()); - assertEquals(0x23, code.get(64).byteValue()); - assertEquals(0x33, code.get(65).byteValue()); // INX SP - assertEquals(0x34, code.get(66).byteValue()); // INR M - assertEquals(0x35, code.get(67).byteValue()); // DCR M - assertEquals(0x36, code.get(68).byteValue()); // MVI M - assertEquals(7, code.get(69).byteValue()); - assertEquals(0x37, code.get(70).byteValue()); // STC - assertEquals(0x39, code.get(71).byteValue()); // DAD SP - assertEquals(0x3A, code.get(72).byteValue()); // LDA - assertEquals(0x45, code.get(73).byteValue()); - assertEquals(0x23, code.get(74).byteValue()); - assertEquals(0x3B, code.get(75).byteValue()); // DCX SP - assertEquals(0x3C, code.get(76).byteValue()); // INR A - assertEquals(0x3D, code.get(77).byteValue()); // DCR A - assertEquals(0x3E, code.get(78).byteValue()); // MVI A - assertEquals(-128, code.get(79).byteValue()); - assertEquals(0x3F, code.get(80).byteValue()); // CMC - assertEquals(0x40, code.get(81).byteValue()); // MOV B,B - assertEquals(0x41, code.get(82).byteValue()); // MOV B,C - assertEquals(0x42, code.get(83).byteValue()); // MOV B,D - assertEquals(0x43, code.get(84).byteValue()); // MOV B,E - assertEquals(0x44, code.get(85).byteValue()); // MOV B,H - assertEquals(0x45, code.get(86).byteValue()); // MOV B,L - assertEquals(0x46, code.get(87).byteValue()); // MOV B,M - assertEquals(0x47, code.get(88).byteValue()); // MOV B,A - assertEquals(0x48, code.get(89).byteValue()); // MOV C,B - assertEquals(0x49, code.get(90).byteValue()); // MOV C,C - assertEquals(0x4A, code.get(91).byteValue()); // MOV C,D - assertEquals(0x4B, code.get(92).byteValue()); // MOV C,E - assertEquals(0x4C, code.get(93).byteValue()); // MOV C,H - assertEquals(0x4D, code.get(94).byteValue()); // MOV C,L - assertEquals(0x4E, code.get(95).byteValue()); // MOV C,M - assertEquals(0x4F, code.get(96).byteValue()); // MOV C,A - assertEquals(0x50, code.get(97).byteValue()); // MOV D,B - assertEquals(0x51, code.get(98).byteValue()); // MOV D,C - assertEquals(0x52, code.get(99).byteValue()); // MOV D,D - assertEquals(0x53, code.get(100).byteValue()); // MOV D,E - assertEquals(0x54, code.get(101).byteValue()); // MOV D,H - assertEquals(0x55, code.get(102).byteValue()); // MOV D,L - assertEquals(0x56, code.get(103).byteValue()); // MOV D,M - assertEquals(0x57, code.get(104).byteValue()); // MOV D,A - assertEquals(0x58, code.get(105).byteValue()); // MOV E,B - assertEquals(0x59, code.get(106).byteValue()); // MOV E,C - assertEquals(0x5A, code.get(107).byteValue()); // MOV E,D - assertEquals(0x5B, code.get(108).byteValue()); // MOV E,E - assertEquals(0x5C, code.get(109).byteValue()); // MOV E,H - assertEquals(0x5D, code.get(110).byteValue()); // MOV E,L - assertEquals(0x5E, code.get(111).byteValue()); // MOV E,M - assertEquals(0x5F, code.get(112).byteValue()); // MOV E,A - assertEquals(0x60, code.get(113).byteValue()); // MOV H,B - assertEquals(0x61, code.get(114).byteValue()); // MOV H,C - assertEquals(0x62, code.get(115).byteValue()); // MOV H,D - assertEquals(0x63, code.get(116).byteValue()); // MOV H,E - assertEquals(0x64, code.get(117).byteValue()); // MOV H,H - assertEquals(0x65, code.get(118).byteValue()); // MOV H,L - assertEquals(0x66, code.get(119).byteValue()); // MOV H,M - assertEquals(0x67, code.get(120).byteValue()); // MOV H,A - assertEquals(0x68, code.get(121).byteValue()); // MOV L,B - assertEquals(0x69, code.get(122).byteValue()); // MOV L,C - assertEquals(0x6A, code.get(123).byteValue()); // MOV L,D - assertEquals(0x6B, code.get(124).byteValue()); // MOV L,E - assertEquals(0x6C, code.get(125).byteValue()); // MOV L,H - assertEquals(0x6D, code.get(126).byteValue()); // MOV L,L - assertEquals(0x6E, code.get(127).byteValue()); // MOV L,M - assertEquals(0x6F, code.get(128).byteValue()); // MOV L,A - assertEquals(0x70, code.get(129).byteValue()); // MOV M,B - assertEquals(0x71, code.get(130).byteValue()); // MOV M,C - assertEquals(0x72, code.get(131).byteValue()); // MOV M,D - assertEquals(0x73, code.get(132).byteValue()); // MOV M,E - assertEquals(0x74, code.get(133).byteValue()); // MOV M,H - assertEquals(0x75, code.get(134).byteValue()); // MOV M,L - assertEquals(0x76, code.get(135).byteValue()); // MOV M,M / HLT - assertEquals(0x77, code.get(136).byteValue()); // MOV M,A - assertEquals(0x78, code.get(137).byteValue()); // MOV A,B - assertEquals(0x79, code.get(138).byteValue()); // MOV A,C - assertEquals(0x7A, code.get(139).byteValue()); // MOV A,D - assertEquals(0x7B, code.get(140).byteValue()); // MOV A,E - assertEquals(0x7C, code.get(141).byteValue()); // MOV A,H - assertEquals(0x7D, code.get(142).byteValue()); // MOV A,L - assertEquals(0x7E, code.get(143).byteValue()); // MOV A,M - assertEquals(0x7F, code.get(144).byteValue()); // MOV A,A - assertEquals(0x80, code.get(145) & 0xFF); // ADD B - assertEquals(0x81, code.get(146) & 0xFF); // ADD C - assertEquals(0x82, code.get(147) & 0xFF); // ADD D - assertEquals(0x83, code.get(148) & 0xFF); // ADD E - assertEquals(0x84, code.get(149) & 0xFF); // ADD H - assertEquals(0x85, code.get(150) & 0xFF); // ADD L - assertEquals(0x86, code.get(151) & 0xFF); // ADD M - assertEquals(0x87, code.get(152) & 0xFF); // ADD A - assertEquals(0x88, code.get(153) & 0xFF); // ADC B - assertEquals(0x89, code.get(154) & 0xFF); // ADC C - assertEquals(0x8A, code.get(155) & 0xFF); // ADC D - assertEquals(0x8B, code.get(156) & 0xFF); // ADC E - assertEquals(0x8C, code.get(157) & 0xFF); // ADC H - assertEquals(0x8D, code.get(158) & 0xFF); // ADC L - assertEquals(0x8E, code.get(159) & 0xFF); // ADC M - assertEquals(0x8F, code.get(160) & 0xFF); // ADC A - assertEquals(0x90, code.get(161) & 0xFF); // SUB B - assertEquals(0x91, code.get(162) & 0xFF); // SUB C - assertEquals(0x92, code.get(163) & 0xFF); // SUB D - assertEquals(0x93, code.get(164) & 0xFF); // SUB E - assertEquals(0x94, code.get(165) & 0xFF); // SUB H - assertEquals(0x95, code.get(166) & 0xFF); // SUB L - assertEquals(0x96, code.get(167) & 0xFF); // SUB M - assertEquals(0x97, code.get(168) & 0xFF); // SUB A - assertEquals(0x98, code.get(169) & 0xFF); // SBB B - assertEquals(0x99, code.get(170) & 0xFF); // SBB C - assertEquals(0x9A, code.get(171) & 0xFF); // SBB D - assertEquals(0x9B, code.get(172) & 0xFF); // SBB E - assertEquals(0x9C, code.get(173) & 0xFF); // SBB H - assertEquals(0x9D, code.get(174) & 0xFF); // SBB L - assertEquals(0x9E, code.get(175) & 0xFF); // SBB M - assertEquals(0x9F, code.get(176) & 0xFF); // SBB A - assertEquals(0xA0, code.get(177) & 0xFF); // ANA B - assertEquals(0xA1, code.get(178) & 0xFF); // ANA C - assertEquals(0xA2, code.get(179) & 0xFF); // ANA D - assertEquals(0xA3, code.get(180) & 0xFF); // ANA E - assertEquals(0xA4, code.get(181) & 0xFF); // ANA H - assertEquals(0xA5, code.get(182) & 0xFF); // ANA L - assertEquals(0xA6, code.get(183) & 0xFF); // ANA M - assertEquals(0xA7, code.get(184) & 0xFF); // ANA A - assertEquals(0xA8, code.get(185) & 0xFF); // XRA B - assertEquals(0xA9, code.get(186) & 0xFF); // XRA C - assertEquals(0xAA, code.get(187) & 0xFF); // XRA D - assertEquals(0xAB, code.get(188) & 0xFF); // XRA E - assertEquals(0xAC, code.get(189) & 0xFF); // XRA H - assertEquals(0xAD, code.get(190) & 0xFF); // XRA L - assertEquals(0xAE, code.get(191) & 0xFF); // XRA M - assertEquals(0xAF, code.get(192) & 0xFF); // XRA A - assertEquals(0xB0, code.get(193) & 0xFF); // ORA B - assertEquals(0xB1, code.get(194) & 0xFF); // ORA C - assertEquals(0xB2, code.get(195) & 0xFF); // ORA D - assertEquals(0xB3, code.get(196) & 0xFF); // ORA E - assertEquals(0xB4, code.get(197) & 0xFF); // ORA H - assertEquals(0xB5, code.get(198) & 0xFF); // ORA L - assertEquals(0xB6, code.get(199) & 0xFF); // ORA M - assertEquals(0xB7, code.get(200) & 0xFF); // ORA A - assertEquals(0xB8, code.get(201) & 0xFF); // CMP B - assertEquals(0xB9, code.get(202) & 0xFF); // CMP C - assertEquals(0xBA, code.get(203) & 0xFF); // CMP D - assertEquals(0xBB, code.get(204) & 0xFF); // CMP E - assertEquals(0xBC, code.get(205) & 0xFF); // CMP H - assertEquals(0xBD, code.get(206) & 0xFF); // CMP L - assertEquals(0xBE, code.get(207) & 0xFF); // CMP M - assertEquals(0xBF, code.get(208) & 0xFF); // CMP A - assertEquals(0xC0, code.get(209) & 0xFF); // RNZ - assertEquals(0xC1, code.get(210) & 0xFF); // POP B - assertEquals(0xC2, code.get(211) & 0xFF); // JNZ - assertEquals(2, code.get(212).byteValue()); - assertEquals(0, code.get(213).byteValue()); - assertEquals(0xC3, code.get(214) & 0xFF); // JMP - assertEquals(0, code.get(215).byteValue()); - assertEquals(2, code.get(216).byteValue()); - assertEquals(0xC4, code.get(217) & 0xFF); // CNZ - assertEquals(0xA0, code.get(218) & 0xFF); - assertEquals(0xF0, code.get(219) & 0xFF); - assertEquals(0xC5, code.get(220) & 0xFF); // PUSH B - assertEquals(0xC6, code.get(221) & 0xFF); // ADI - assertEquals(0xF0, code.get(222) & 0xFF); - assertEquals(0xC7, code.get(223) & 0xFF); // RST 0 - assertEquals(0xC8, code.get(224) & 0xFF); // RZ - assertEquals(0xC9, code.get(225) & 0xFF); // RET - assertEquals(0xCA, code.get(226) & 0xFF); // JZ - assertEquals(0x34, code.get(227) & 0xFF); - assertEquals(0x12, code.get(228) & 0xFF); - assertEquals(0xCC, code.get(229) & 0xFF); // CZ - assertEquals(0x34, code.get(230) & 0xFF); - assertEquals(0x12, code.get(231) & 0xFF); - assertEquals(0xCD, code.get(232) & 0xFF); // CALL - assertEquals(0x34, code.get(233) & 0xFF); - assertEquals(0x12, code.get(234) & 0xFF); - assertEquals(0xCE, code.get(235) & 0xFF); // ACI - assertEquals(0xF0, code.get(236) & 0xFF); - assertEquals(0xCF, code.get(237) & 0xFF); // RST 1 - assertEquals(0xD0, code.get(238) & 0xFF); // RNC - assertEquals(0xD1, code.get(239) & 0xFF); // POP D - assertEquals(0xD2, code.get(240) & 0xFF); // JNC - assertEquals(0x34, code.get(241) & 0xFF); - assertEquals(0x12, code.get(242) & 0xFF); - assertEquals(0xD3, code.get(243) & 0xFF); // OUT - assertEquals(0xF0, code.get(244) & 0xFF); - assertEquals(0xD4, code.get(245) & 0xFF); // CNC - assertEquals(0x34, code.get(246) & 0xFF); - assertEquals(0x12, code.get(247) & 0xFF); - assertEquals(0xD5, code.get(248) & 0xFF); // PUSH D - assertEquals(0xD6, code.get(249) & 0xFF); // SUI - assertEquals(0xF0, code.get(250) & 0xFF); - assertEquals(0xD7, code.get(251) & 0xFF); // RST 2 - assertEquals(0xD8, code.get(252) & 0xFF); // RC - assertEquals(0xDA, code.get(253) & 0xFF); // JC - assertEquals(0x34, code.get(254) & 0xFF); - assertEquals(0x12, code.get(255) & 0xFF); - assertEquals(0xDB, code.get(256) & 0xFF); // IN - assertEquals(0xF0, code.get(257) & 0xFF); - assertEquals(0xDC, code.get(258) & 0xFF); // CC - assertEquals(0x34, code.get(259) & 0xFF); - assertEquals(0x12, code.get(260) & 0xFF); - assertEquals(0xDE, code.get(261) & 0xFF); // SBI - assertEquals(0xF0, code.get(262) & 0xFF); - assertEquals(0xDF, code.get(263) & 0xFF); // RST 3 - assertEquals(0xE0, code.get(264) & 0xFF); // RPO - assertEquals(0xE1, code.get(265) & 0xFF); // POP H - assertEquals(0xE2, code.get(266) & 0xFF); // JPO - assertEquals(0x34, code.get(267) & 0xFF); - assertEquals(0x12, code.get(268) & 0xFF); - assertEquals(0xE3, code.get(269) & 0xFF); // XTHL - assertEquals(0xE4, code.get(270) & 0xFF); // CPO - assertEquals(0x34, code.get(271) & 0xFF); - assertEquals(0x12, code.get(272) & 0xFF); - assertEquals(0xE5, code.get(273) & 0xFF); // PUSH H - assertEquals(0xE6, code.get(274) & 0xFF); // ANI - assertEquals(0xF0, code.get(275) & 0xFF); - assertEquals(0xE7, code.get(276) & 0xFF); // RST - assertEquals(0xE8, code.get(277) & 0xFF); // RPE - assertEquals(0xE9, code.get(278) & 0xFF); // PCHL - assertEquals(0xEA, code.get(279) & 0xFF); // JPE - assertEquals(0x34, code.get(280) & 0xFF); - assertEquals(0x12, code.get(281) & 0xFF); - assertEquals(0xEB, code.get(282) & 0xFF); // XCHG - assertEquals(0xEC, code.get(283) & 0xFF); // CPE - assertEquals(0x34, code.get(284) & 0xFF); - assertEquals(0x12, code.get(285) & 0xFF); - assertEquals(0xEE, code.get(286) & 0xFF); // XRI - assertEquals(0xF0, code.get(287) & 0xFF); - assertEquals(0xEF, code.get(288) & 0xFF); // RST - assertEquals(0xF0, code.get(289) & 0xFF); // RP - assertEquals(0xF1, code.get(290) & 0xFF); // POP PSW - assertEquals(0xF2, code.get(291) & 0xFF); // JP - assertEquals(0x00, code.get(292) & 0xFF); - assertEquals(0x02, code.get(293) & 0xFF); - assertEquals(0xF3, code.get(294) & 0xFF); // DI - assertEquals(0xF4, code.get(295) & 0xFF); // CP - assertEquals(0x00, code.get(296) & 0xFF); - assertEquals(0x02, code.get(297) & 0xFF); - assertEquals(0xF5, code.get(298) & 0xFF); // PUSH PSW - assertEquals(0xF6, code.get(299) & 0xFF); // ORI - assertEquals(0xF0, code.get(300) & 0xFF); - assertEquals(0xF7, code.get(301) & 0xFF); // RST 6 - assertEquals(0xF8, code.get(302) & 0xFF); // RM - assertEquals(0xF9, code.get(303) & 0xFF); // SPHL - assertEquals(0xFA, code.get(304) & 0xFF); // JM - assertEquals(0x00, code.get(305) & 0xFF); - assertEquals(0x02, code.get(306) & 0xFF); - assertEquals(0xFB, code.get(307) & 0xFF); // EI - assertEquals(0xFC, code.get(308) & 0xFF); // CM - assertEquals(0x00, code.get(309) & 0xFF); - assertEquals(0x02, code.get(310) & 0xFF); - assertEquals(0xFE, code.get(311) & 0xFF); // CPI - assertEquals(0xF0, code.get(312) & 0xFF); - assertEquals(0xFF, code.get(313) & 0xFF); // RST 7 +// assertEquals(3, code.get(5).byteValue()); // INX B +// assertEquals(4, code.get(6).byteValue()); // INR B +// assertEquals(5, code.get(7).byteValue()); // DCR B +// assertEquals(6, code.get(8).byteValue()); // MVI B +// assertEquals(7, code.get(9).byteValue()); +// assertEquals(7, code.get(10).byteValue()); // RLC +// assertEquals(9, code.get(11).byteValue()); // DAD B +// assertEquals(0x0A, code.get(12).byteValue()); // LDAX B +// assertEquals(0x0B, code.get(13).byteValue()); // DCX B +// assertEquals(0x0C, code.get(14).byteValue()); // INR C +// assertEquals(0x0D, code.get(15).byteValue()); // DCR C +// assertEquals(0x0E, code.get(16).byteValue()); // MVI C +// assertEquals(8, code.get(17).byteValue()); +// assertEquals(0x0F, code.get(18).byteValue()); // RRC +// assertEquals(0x11, code.get(19).byteValue()); // LXI D +// assertEquals(0x45, code.get(20).byteValue()); +// assertEquals(0x23, code.get(21).byteValue()); +// assertEquals(0x12, code.get(22).byteValue()); // STAX D +// assertEquals(0x13, code.get(23).byteValue()); // INX D +// assertEquals(0x14, code.get(24).byteValue()); // INR D +// assertEquals(0x15, code.get(25).byteValue()); // DCR D +// assertEquals(0x16, code.get(26).byteValue()); // MVI D +// assertEquals(9, code.get(27).byteValue()); +// assertEquals(0x17, code.get(28).byteValue()); // RAL +// assertEquals(0x19, code.get(29).byteValue()); // DAD D +// assertEquals(0x1A, code.get(30).byteValue()); // LDAX D +// assertEquals(0x1B, code.get(31).byteValue()); // DCX D +// assertEquals(0x1C, code.get(32).byteValue()); // INR E +// assertEquals(0x1D, code.get(33).byteValue()); // DCR E +// assertEquals(0x1E, code.get(34).byteValue()); // MVI E +// assertEquals(10, code.get(35).byteValue()); +// assertEquals(0x1F, code.get(36).byteValue()); // RAR +// assertEquals(0x21, code.get(37).byteValue()); // LXI H +// assertEquals(0x45, code.get(38).byteValue()); +// assertEquals(0x23, code.get(39).byteValue()); +// assertEquals(0x22, code.get(40).byteValue()); // SHLD +// assertEquals(0x45, code.get(41).byteValue()); +// assertEquals(0x23, code.get(42).byteValue()); +// assertEquals(0x23, code.get(43).byteValue()); // INX H +// assertEquals(0x24, code.get(44).byteValue()); // INR H +// assertEquals(0x25, code.get(45).byteValue()); // DCR H +// assertEquals(0x26, code.get(46).byteValue()); // MVI H +// assertEquals(0x28, code.get(47).byteValue()); +// assertEquals(0x27, code.get(48).byteValue()); // DAA +// assertEquals(0x29, code.get(49).byteValue()); // DAD H +// assertEquals(0x2A, code.get(50).byteValue()); // LHLD +// assertEquals(0x45, code.get(51).byteValue()); +// assertEquals(0x23, code.get(52).byteValue()); +// assertEquals(0x2B, code.get(53).byteValue()); // DCX H +// assertEquals(0x2C, code.get(54).byteValue()); // INR L +// assertEquals(0x2D, code.get(55).byteValue()); // DCR L +// assertEquals(0x2E, code.get(56).byteValue()); // MVI L +// assertEquals(10, code.get(57).byteValue()); +// assertEquals(0x2F, code.get(58).byteValue()); // CMA +// assertEquals(0x31, code.get(59).byteValue()); // LXI SP +// assertEquals(0x45, code.get(60).byteValue()); +// assertEquals(0x23, code.get(61).byteValue()); +// assertEquals(0x32, code.get(62).byteValue()); // STA +// assertEquals(0x45, code.get(63).byteValue()); +// assertEquals(0x23, code.get(64).byteValue()); +// assertEquals(0x33, code.get(65).byteValue()); // INX SP +// assertEquals(0x34, code.get(66).byteValue()); // INR M +// assertEquals(0x35, code.get(67).byteValue()); // DCR M +// assertEquals(0x36, code.get(68).byteValue()); // MVI M +// assertEquals(7, code.get(69).byteValue()); +// assertEquals(0x37, code.get(70).byteValue()); // STC +// assertEquals(0x39, code.get(71).byteValue()); // DAD SP +// assertEquals(0x3A, code.get(72).byteValue()); // LDA +// assertEquals(0x45, code.get(73).byteValue()); +// assertEquals(0x23, code.get(74).byteValue()); +// assertEquals(0x3B, code.get(75).byteValue()); // DCX SP +// assertEquals(0x3C, code.get(76).byteValue()); // INR A +// assertEquals(0x3D, code.get(77).byteValue()); // DCR A +// assertEquals(0x3E, code.get(78).byteValue()); // MVI A +// assertEquals(-128, code.get(79).byteValue()); +// assertEquals(0x3F, code.get(80).byteValue()); // CMC +// assertEquals(0x40, code.get(81).byteValue()); // MOV B,B +// assertEquals(0x41, code.get(82).byteValue()); // MOV B,C +// assertEquals(0x42, code.get(83).byteValue()); // MOV B,D +// assertEquals(0x43, code.get(84).byteValue()); // MOV B,E +// assertEquals(0x44, code.get(85).byteValue()); // MOV B,H +// assertEquals(0x45, code.get(86).byteValue()); // MOV B,L +// assertEquals(0x46, code.get(87).byteValue()); // MOV B,M +// assertEquals(0x47, code.get(88).byteValue()); // MOV B,A +// assertEquals(0x48, code.get(89).byteValue()); // MOV C,B +// assertEquals(0x49, code.get(90).byteValue()); // MOV C,C +// assertEquals(0x4A, code.get(91).byteValue()); // MOV C,D +// assertEquals(0x4B, code.get(92).byteValue()); // MOV C,E +// assertEquals(0x4C, code.get(93).byteValue()); // MOV C,H +// assertEquals(0x4D, code.get(94).byteValue()); // MOV C,L +// assertEquals(0x4E, code.get(95).byteValue()); // MOV C,M +// assertEquals(0x4F, code.get(96).byteValue()); // MOV C,A +// assertEquals(0x50, code.get(97).byteValue()); // MOV D,B +// assertEquals(0x51, code.get(98).byteValue()); // MOV D,C +// assertEquals(0x52, code.get(99).byteValue()); // MOV D,D +// assertEquals(0x53, code.get(100).byteValue()); // MOV D,E +// assertEquals(0x54, code.get(101).byteValue()); // MOV D,H +// assertEquals(0x55, code.get(102).byteValue()); // MOV D,L +// assertEquals(0x56, code.get(103).byteValue()); // MOV D,M +// assertEquals(0x57, code.get(104).byteValue()); // MOV D,A +// assertEquals(0x58, code.get(105).byteValue()); // MOV E,B +// assertEquals(0x59, code.get(106).byteValue()); // MOV E,C +// assertEquals(0x5A, code.get(107).byteValue()); // MOV E,D +// assertEquals(0x5B, code.get(108).byteValue()); // MOV E,E +// assertEquals(0x5C, code.get(109).byteValue()); // MOV E,H +// assertEquals(0x5D, code.get(110).byteValue()); // MOV E,L +// assertEquals(0x5E, code.get(111).byteValue()); // MOV E,M +// assertEquals(0x5F, code.get(112).byteValue()); // MOV E,A +// assertEquals(0x60, code.get(113).byteValue()); // MOV H,B +// assertEquals(0x61, code.get(114).byteValue()); // MOV H,C +// assertEquals(0x62, code.get(115).byteValue()); // MOV H,D +// assertEquals(0x63, code.get(116).byteValue()); // MOV H,E +// assertEquals(0x64, code.get(117).byteValue()); // MOV H,H +// assertEquals(0x65, code.get(118).byteValue()); // MOV H,L +// assertEquals(0x66, code.get(119).byteValue()); // MOV H,M +// assertEquals(0x67, code.get(120).byteValue()); // MOV H,A +// assertEquals(0x68, code.get(121).byteValue()); // MOV L,B +// assertEquals(0x69, code.get(122).byteValue()); // MOV L,C +// assertEquals(0x6A, code.get(123).byteValue()); // MOV L,D +// assertEquals(0x6B, code.get(124).byteValue()); // MOV L,E +// assertEquals(0x6C, code.get(125).byteValue()); // MOV L,H +// assertEquals(0x6D, code.get(126).byteValue()); // MOV L,L +// assertEquals(0x6E, code.get(127).byteValue()); // MOV L,M +// assertEquals(0x6F, code.get(128).byteValue()); // MOV L,A +// assertEquals(0x70, code.get(129).byteValue()); // MOV M,B +// assertEquals(0x71, code.get(130).byteValue()); // MOV M,C +// assertEquals(0x72, code.get(131).byteValue()); // MOV M,D +// assertEquals(0x73, code.get(132).byteValue()); // MOV M,E +// assertEquals(0x74, code.get(133).byteValue()); // MOV M,H +// assertEquals(0x75, code.get(134).byteValue()); // MOV M,L +// assertEquals(0x76, code.get(135).byteValue()); // MOV M,M / HLT +// assertEquals(0x77, code.get(136).byteValue()); // MOV M,A +// assertEquals(0x78, code.get(137).byteValue()); // MOV A,B +// assertEquals(0x79, code.get(138).byteValue()); // MOV A,C +// assertEquals(0x7A, code.get(139).byteValue()); // MOV A,D +// assertEquals(0x7B, code.get(140).byteValue()); // MOV A,E +// assertEquals(0x7C, code.get(141).byteValue()); // MOV A,H +// assertEquals(0x7D, code.get(142).byteValue()); // MOV A,L +// assertEquals(0x7E, code.get(143).byteValue()); // MOV A,M +// assertEquals(0x7F, code.get(144).byteValue()); // MOV A,A +// assertEquals(0x80, code.get(145) & 0xFF); // ADD B +// assertEquals(0x81, code.get(146) & 0xFF); // ADD C +// assertEquals(0x82, code.get(147) & 0xFF); // ADD D +// assertEquals(0x83, code.get(148) & 0xFF); // ADD E +// assertEquals(0x84, code.get(149) & 0xFF); // ADD H +// assertEquals(0x85, code.get(150) & 0xFF); // ADD L +// assertEquals(0x86, code.get(151) & 0xFF); // ADD M +// assertEquals(0x87, code.get(152) & 0xFF); // ADD A +// assertEquals(0x88, code.get(153) & 0xFF); // ADC B +// assertEquals(0x89, code.get(154) & 0xFF); // ADC C +// assertEquals(0x8A, code.get(155) & 0xFF); // ADC D +// assertEquals(0x8B, code.get(156) & 0xFF); // ADC E +// assertEquals(0x8C, code.get(157) & 0xFF); // ADC H +// assertEquals(0x8D, code.get(158) & 0xFF); // ADC L +// assertEquals(0x8E, code.get(159) & 0xFF); // ADC M +// assertEquals(0x8F, code.get(160) & 0xFF); // ADC A +// assertEquals(0x90, code.get(161) & 0xFF); // SUB B +// assertEquals(0x91, code.get(162) & 0xFF); // SUB C +// assertEquals(0x92, code.get(163) & 0xFF); // SUB D +// assertEquals(0x93, code.get(164) & 0xFF); // SUB E +// assertEquals(0x94, code.get(165) & 0xFF); // SUB H +// assertEquals(0x95, code.get(166) & 0xFF); // SUB L +// assertEquals(0x96, code.get(167) & 0xFF); // SUB M +// assertEquals(0x97, code.get(168) & 0xFF); // SUB A +// assertEquals(0x98, code.get(169) & 0xFF); // SBB B +// assertEquals(0x99, code.get(170) & 0xFF); // SBB C +// assertEquals(0x9A, code.get(171) & 0xFF); // SBB D +// assertEquals(0x9B, code.get(172) & 0xFF); // SBB E +// assertEquals(0x9C, code.get(173) & 0xFF); // SBB H +// assertEquals(0x9D, code.get(174) & 0xFF); // SBB L +// assertEquals(0x9E, code.get(175) & 0xFF); // SBB M +// assertEquals(0x9F, code.get(176) & 0xFF); // SBB A +// assertEquals(0xA0, code.get(177) & 0xFF); // ANA B +// assertEquals(0xA1, code.get(178) & 0xFF); // ANA C +// assertEquals(0xA2, code.get(179) & 0xFF); // ANA D +// assertEquals(0xA3, code.get(180) & 0xFF); // ANA E +// assertEquals(0xA4, code.get(181) & 0xFF); // ANA H +// assertEquals(0xA5, code.get(182) & 0xFF); // ANA L +// assertEquals(0xA6, code.get(183) & 0xFF); // ANA M +// assertEquals(0xA7, code.get(184) & 0xFF); // ANA A +// assertEquals(0xA8, code.get(185) & 0xFF); // XRA B +// assertEquals(0xA9, code.get(186) & 0xFF); // XRA C +// assertEquals(0xAA, code.get(187) & 0xFF); // XRA D +// assertEquals(0xAB, code.get(188) & 0xFF); // XRA E +// assertEquals(0xAC, code.get(189) & 0xFF); // XRA H +// assertEquals(0xAD, code.get(190) & 0xFF); // XRA L +// assertEquals(0xAE, code.get(191) & 0xFF); // XRA M +// assertEquals(0xAF, code.get(192) & 0xFF); // XRA A +// assertEquals(0xB0, code.get(193) & 0xFF); // ORA B +// assertEquals(0xB1, code.get(194) & 0xFF); // ORA C +// assertEquals(0xB2, code.get(195) & 0xFF); // ORA D +// assertEquals(0xB3, code.get(196) & 0xFF); // ORA E +// assertEquals(0xB4, code.get(197) & 0xFF); // ORA H +// assertEquals(0xB5, code.get(198) & 0xFF); // ORA L +// assertEquals(0xB6, code.get(199) & 0xFF); // ORA M +// assertEquals(0xB7, code.get(200) & 0xFF); // ORA A +// assertEquals(0xB8, code.get(201) & 0xFF); // CMP B +// assertEquals(0xB9, code.get(202) & 0xFF); // CMP C +// assertEquals(0xBA, code.get(203) & 0xFF); // CMP D +// assertEquals(0xBB, code.get(204) & 0xFF); // CMP E +// assertEquals(0xBC, code.get(205) & 0xFF); // CMP H +// assertEquals(0xBD, code.get(206) & 0xFF); // CMP L +// assertEquals(0xBE, code.get(207) & 0xFF); // CMP M +// assertEquals(0xBF, code.get(208) & 0xFF); // CMP A +// assertEquals(0xC0, code.get(209) & 0xFF); // RNZ +// assertEquals(0xC1, code.get(210) & 0xFF); // POP B +// assertEquals(0xC2, code.get(211) & 0xFF); // JNZ +// assertEquals(2, code.get(212).byteValue()); +// assertEquals(0, code.get(213).byteValue()); +// assertEquals(0xC3, code.get(214) & 0xFF); // JMP +// assertEquals(0, code.get(215).byteValue()); +// assertEquals(2, code.get(216).byteValue()); +// assertEquals(0xC4, code.get(217) & 0xFF); // CNZ +// assertEquals(0xA0, code.get(218) & 0xFF); +// assertEquals(0xF0, code.get(219) & 0xFF); +// assertEquals(0xC5, code.get(220) & 0xFF); // PUSH B +// assertEquals(0xC6, code.get(221) & 0xFF); // ADI +// assertEquals(0xF0, code.get(222) & 0xFF); +// assertEquals(0xC7, code.get(223) & 0xFF); // RST 0 +// assertEquals(0xC8, code.get(224) & 0xFF); // RZ +// assertEquals(0xC9, code.get(225) & 0xFF); // RET +// assertEquals(0xCA, code.get(226) & 0xFF); // JZ +// assertEquals(0x34, code.get(227) & 0xFF); +// assertEquals(0x12, code.get(228) & 0xFF); +// assertEquals(0xCC, code.get(229) & 0xFF); // CZ +// assertEquals(0x34, code.get(230) & 0xFF); +// assertEquals(0x12, code.get(231) & 0xFF); +// assertEquals(0xCD, code.get(232) & 0xFF); // CALL +// assertEquals(0x34, code.get(233) & 0xFF); +// assertEquals(0x12, code.get(234) & 0xFF); +// assertEquals(0xCE, code.get(235) & 0xFF); // ACI +// assertEquals(0xF0, code.get(236) & 0xFF); +// assertEquals(0xCF, code.get(237) & 0xFF); // RST 1 +// assertEquals(0xD0, code.get(238) & 0xFF); // RNC +// assertEquals(0xD1, code.get(239) & 0xFF); // POP D +// assertEquals(0xD2, code.get(240) & 0xFF); // JNC +// assertEquals(0x34, code.get(241) & 0xFF); +// assertEquals(0x12, code.get(242) & 0xFF); +// assertEquals(0xD3, code.get(243) & 0xFF); // OUT +// assertEquals(0xF0, code.get(244) & 0xFF); +// assertEquals(0xD4, code.get(245) & 0xFF); // CNC +// assertEquals(0x34, code.get(246) & 0xFF); +// assertEquals(0x12, code.get(247) & 0xFF); +// assertEquals(0xD5, code.get(248) & 0xFF); // PUSH D +// assertEquals(0xD6, code.get(249) & 0xFF); // SUI +// assertEquals(0xF0, code.get(250) & 0xFF); +// assertEquals(0xD7, code.get(251) & 0xFF); // RST 2 +// assertEquals(0xD8, code.get(252) & 0xFF); // RC +// assertEquals(0xDA, code.get(253) & 0xFF); // JC +// assertEquals(0x34, code.get(254) & 0xFF); +// assertEquals(0x12, code.get(255) & 0xFF); +// assertEquals(0xDB, code.get(256) & 0xFF); // IN +// assertEquals(0xF0, code.get(257) & 0xFF); +// assertEquals(0xDC, code.get(258) & 0xFF); // CC +// assertEquals(0x34, code.get(259) & 0xFF); +// assertEquals(0x12, code.get(260) & 0xFF); +// assertEquals(0xDE, code.get(261) & 0xFF); // SBI +// assertEquals(0xF0, code.get(262) & 0xFF); +// assertEquals(0xDF, code.get(263) & 0xFF); // RST 3 +// assertEquals(0xE0, code.get(264) & 0xFF); // RPO +// assertEquals(0xE1, code.get(265) & 0xFF); // POP H +// assertEquals(0xE2, code.get(266) & 0xFF); // JPO +// assertEquals(0x34, code.get(267) & 0xFF); +// assertEquals(0x12, code.get(268) & 0xFF); +// assertEquals(0xE3, code.get(269) & 0xFF); // XTHL +// assertEquals(0xE4, code.get(270) & 0xFF); // CPO +// assertEquals(0x34, code.get(271) & 0xFF); +// assertEquals(0x12, code.get(272) & 0xFF); +// assertEquals(0xE5, code.get(273) & 0xFF); // PUSH H +// assertEquals(0xE6, code.get(274) & 0xFF); // ANI +// assertEquals(0xF0, code.get(275) & 0xFF); +// assertEquals(0xE7, code.get(276) & 0xFF); // RST +// assertEquals(0xE8, code.get(277) & 0xFF); // RPE +// assertEquals(0xE9, code.get(278) & 0xFF); // PCHL +// assertEquals(0xEA, code.get(279) & 0xFF); // JPE +// assertEquals(0x34, code.get(280) & 0xFF); +// assertEquals(0x12, code.get(281) & 0xFF); +// assertEquals(0xEB, code.get(282) & 0xFF); // XCHG +// assertEquals(0xEC, code.get(283) & 0xFF); // CPE +// assertEquals(0x34, code.get(284) & 0xFF); +// assertEquals(0x12, code.get(285) & 0xFF); +// assertEquals(0xEE, code.get(286) & 0xFF); // XRI +// assertEquals(0xF0, code.get(287) & 0xFF); +// assertEquals(0xEF, code.get(288) & 0xFF); // RST +// assertEquals(0xF0, code.get(289) & 0xFF); // RP +// assertEquals(0xF1, code.get(290) & 0xFF); // POP PSW +// assertEquals(0xF2, code.get(291) & 0xFF); // JP +// assertEquals(0x00, code.get(292) & 0xFF); +// assertEquals(0x02, code.get(293) & 0xFF); +// assertEquals(0xF3, code.get(294) & 0xFF); // DI +// assertEquals(0xF4, code.get(295) & 0xFF); // CP +// assertEquals(0x00, code.get(296) & 0xFF); +// assertEquals(0x02, code.get(297) & 0xFF); +// assertEquals(0xF5, code.get(298) & 0xFF); // PUSH PSW +// assertEquals(0xF6, code.get(299) & 0xFF); // ORI +// assertEquals(0xF0, code.get(300) & 0xFF); +// assertEquals(0xF7, code.get(301) & 0xFF); // RST 6 +// assertEquals(0xF8, code.get(302) & 0xFF); // RM +// assertEquals(0xF9, code.get(303) & 0xFF); // SPHL +// assertEquals(0xFA, code.get(304) & 0xFF); // JM +// assertEquals(0x00, code.get(305) & 0xFF); +// assertEquals(0x02, code.get(306) & 0xFF); +// assertEquals(0xFB, code.get(307) & 0xFF); // EI +// assertEquals(0xFC, code.get(308) & 0xFF); // CM +// assertEquals(0x00, code.get(309) & 0xFF); +// assertEquals(0x02, code.get(310) & 0xFF); +// assertEquals(0xFE, code.get(311) & 0xFF); // CPI +// assertEquals(0xF0, code.get(312) & 0xFF); +// assertEquals(0xFF, code.get(313) & 0xFF); // RST 7 } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java index 291d4ac5f..20c5ecd70 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java @@ -5,6 +5,7 @@ import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; +import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; import org.junit.Test; @@ -32,7 +33,7 @@ public void testMacroArgumentsAreConnectedWithIds() { .addChild(new ExprId(0, 0, "r"))) .addChild(new PseudoMacroParameter(0, 0) .addChild(new ExprId(0, 0, "t"))) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) .addChild(new ExprId(0, 0, "q"))) .addChild(new PseudoEqu(0, 0, "uu") .addChild(new ExprInfix(0, 0, OP_ADD) @@ -53,7 +54,7 @@ public void testMacroArgumentsAreConnectedWithIds() { .addChild(new PseudoMacroArgument(0, 0) .addChild(new ExprId(0, 0, "t")) .addChild(new ExprNumber(0, 0, 3))) - .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) .addChild(new ExprId(0, 0, "q"))) .addChild(new PseudoEqu(0, 0, "uu") .addChild(new ExprInfix(0, 0, OP_ADD) From 062c1c41e32f58ea654ea0e7b7c75198618c8307 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 20 Feb 2022 08:28:47 +0100 Subject: [PATCH 101/314] [#201] as-z80: tests --- .../as-8080/src/main/antlr/As8080Parser.g4 | 2 +- .../as-z80/src/main/antlr/AsZ80Lexer.g4 | 15 +-- .../as-z80/src/main/antlr/AsZ80Lexer.tokens | 105 +++++++++--------- .../as-z80/src/main/antlr/AsZ80Parser.g4 | 25 +++-- .../compiler/asZ80/LexicalAnalyzerImpl.java | 5 +- .../compiler/asZ80/ast/expr/ExprInfix.java | 3 - .../compiler/asZ80/ast/instr/InstrED.java | 4 +- .../pseudo/{PseudoSet.java => PseudoVar.java} | 14 +-- .../visitors/CheckDeclarationsVisitor.java | 2 +- .../asZ80/visitors/CreateInstrVisitor.java | 6 +- .../asZ80/visitors/CreatePseudoVisitor.java | 4 +- .../asZ80/visitors/EvaluateExprVisitor.java | 2 +- .../compiler/asZ80/visitors/NodeVisitor.java | 2 +- .../plugins/compiler/asZ80/Utils.java | 23 ++-- .../asZ80/parser/LexicalAnalyzerImplTest.java | 41 +++++-- .../compiler/asZ80/parser/ParseExprTest.java | 80 ++++++------- .../compiler/asZ80/parser/ParseInstrTest.java | 85 ++++++++------ .../asZ80/parser/ParsePseudoTest.java | 2 +- .../visitors/EvaluateExprVisitorTest.java | 24 ++-- 19 files changed, 234 insertions(+), 210 deletions(-) rename plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/{PseudoSet.java => PseudoVar.java} (73%) diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index 6c6cdfc18..e324a0528 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -117,7 +117,7 @@ rRegister: rPseudoCode: PREP_ORG expr=rExpression # pseudoOrg | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu - | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoSet + | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoVar | PREP_IF expr=rExpression EOL (rLine EOL)* EOL* PREP_ENDIF # pseudoIf | id=ID_IDENTIFIER PREP_MACRO params=rMacroParameters? EOL (rLine EOL)* EOL* PREP_ENDM # pseudoMacroDef | id=ID_IDENTIFIER args=rMacroArguments? # pseudoMacroCall diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 index e6b2d1f11..d2089fa3d 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 @@ -110,7 +110,7 @@ COND_P: P -> popMode; COND_PE: P E -> popMode; COND_PO: P O -> popMode; COND_WS: [ \t\f]+ -> skip; -COND_UNRECOGNIZED: ({"cCnNzZmMpP".indexOf((char) _input.LA(1)) == -1}?) -> popMode; +ERROR_COND: ({"cCnNzZmMpP".indexOf((char) _input.LA(1)) == -1}?) -> popMode,skip; mode IM_NUMBER; IM_01: '0/1' -> popMode; @@ -118,14 +118,14 @@ IM_0: '0' -> popMode; IM_1: '1' -> popMode; IM_2: '2' -> popMode; IM_WS: [ \t\f]+ -> skip; -IM_UNRECOGNIZED: ({"012".indexOf((char) _input.LA(1)) == -1}?) -> popMode; +ERROR_IM: ({"012".indexOf((char) _input.LA(1)) == -1}?) -> popMode,skip; mode DEFAULT_MODE; // preprocessor PREP_ORG: O R G; PREP_EQU: E Q U; -PREP_SET: S E T; +PREP_VAR: V A R; PREP_IF: I F; PREP_ENDIF: E N D I F; PREP_INCLUDE: I N C L U D E; @@ -164,9 +164,6 @@ OP_MOD: M O D; OP_SHR: S H R; OP_SHL: S H L; OP_NOT: N O T; -OP_AND: A N D; -OP_OR: O R; -OP_XOR: X O R; // literals LIT_HEXNUMBER_1: '0' X [0-9a-fA-F]+; @@ -204,9 +201,9 @@ OP_MOD_2: '%'; OP_SHR_2: '>>'; OP_SHL_2: '<<'; OP_NOT_2: '~'; -OP_AND_2: '&'; -OP_OR_2: '|'; -OP_XOR_2: '^'; +OP_AND: '&'; +OP_OR: '|'; +OP_XOR: '^'; WS : [ \t\f]+ -> skip; EOL: '\r'? '\n'; diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens index 807c43e71..c13ba3a09 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens @@ -86,7 +86,7 @@ IM_WS=85 IM_UNRECOGNIZED=86 PREP_ORG=87 PREP_EQU=88 -PREP_SET=89 +PREP_VAR=89 PREP_IF=90 PREP_ENDIF=91 PREP_INCLUDE=92 @@ -121,61 +121,58 @@ OP_MOD=120 OP_SHR=121 OP_SHL=122 OP_NOT=123 -OP_AND=124 -OP_OR=125 -OP_XOR=126 -LIT_HEXNUMBER_1=127 -LIT_NUMBER=128 -LIT_HEXNUMBER_2=129 -LIT_OCTNUMBER=130 -LIT_BINNUMBER=131 -LIT_STRING_1=132 -LIT_STRING_2=133 -ID_IDENTIFIER=134 -ID_LABEL=135 -ERROR=136 -SEP_LPAR=137 -SEP_RPAR=138 -SEP_COMMA=139 -OP_ADD=140 -OP_SUBTRACT=141 -OP_MULTIPLY=142 -OP_DIVIDE=143 -OP_EQUAL=144 -OP_GT=145 -OP_GTE=146 -OP_LT=147 -OP_LTE=148 -OP_MOD_2=149 -OP_SHR_2=150 -OP_SHL_2=151 -OP_NOT_2=152 -OP_AND_2=153 -OP_OR_2=154 -OP_XOR_2=155 -WS=156 -EOL=157 +LIT_HEXNUMBER_1=124 +LIT_NUMBER=125 +LIT_HEXNUMBER_2=126 +LIT_OCTNUMBER=127 +LIT_BINNUMBER=128 +LIT_STRING_1=129 +LIT_STRING_2=130 +ID_IDENTIFIER=131 +ID_LABEL=132 +ERROR=133 +SEP_LPAR=134 +SEP_RPAR=135 +SEP_COMMA=136 +OP_ADD=137 +OP_SUBTRACT=138 +OP_MULTIPLY=139 +OP_DIVIDE=140 +OP_EQUAL=141 +OP_GT=142 +OP_GTE=143 +OP_LT=144 +OP_LTE=145 +OP_MOD_2=146 +OP_SHR_2=147 +OP_SHL_2=148 +OP_NOT_2=149 +OP_AND=150 +OP_OR=151 +OP_XOR=152 +WS=153 +EOL=154 '0/1'=81 '0'=82 '1'=83 '2'=84 '$'=98 -'('=137 -')'=138 -','=139 -'+'=140 -'-'=141 -'*'=142 -'/'=143 -'='=144 -'>'=145 -'>='=146 -'<'=147 -'<='=148 -'%'=149 -'>>'=150 -'<<'=151 -'~'=152 -'&'=153 -'|'=154 -'^'=155 +'('=134 +')'=135 +','=136 +'+'=137 +'-'=138 +'*'=139 +'/'=140 +'='=141 +'>'=142 +'>='=143 +'<'=144 +'<='=145 +'%'=146 +'>>'=147 +'<<'=148 +'~'=149 +'&'=150 +'|'=151 +'^'=152 diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 index 863c6aed7..dd6a2e721 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 @@ -47,13 +47,13 @@ rInstruction: | opcode=OPCODE_OUT SEP_LPAR REG_C SEP_RPAR SEP_COMMA n=LIT_NUMBER # instrED_C | opcode=OPCODE_SBC REG_HL SEP_COMMA rp=rRegPair # instrED_RP | opcode=OPCODE_ADC REG_HL SEP_COMMA rp=rRegPair # instrED_RP - | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA rp=rRegPair # instrED_NN_RP - | opcode=OPCODE_LD rp=rRegPair SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrED_RP_NN + | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA rp=(REG_BC|REG_DE|REG_SP) # instrED_NN_RP + | opcode=OPCODE_LD rp=(REG_BC|REG_DE|REG_SP) SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrED_RP_NN | opcode=OPCODE_IM im=(IM_0|IM_1|IM_2|IM_01) # instrED_IM - | opcode=OPCODE_LD dst=REG_I src=REG_A # instrED_RIA_RIA - | opcode=OPCODE_LD dst=REG_A src=REG_I # instrED_RIA_RIA - | opcode=OPCODE_LD dst=REG_R src=REG_A # instrED_RIA_RIA - | opcode=OPCODE_LD dst=REG_A src=REG_R # instrED_RIA_RIA + | opcode=OPCODE_LD dst=REG_I SEP_COMMA src=REG_A # instrED_RIA_RIA + | opcode=OPCODE_LD dst=REG_A SEP_COMMA src=REG_I # instrED_RIA_RIA + | opcode=OPCODE_LD dst=REG_R SEP_COMMA src=REG_A # instrED_RIA_RIA + | opcode=OPCODE_LD dst=REG_A SEP_COMMA src=REG_R # instrED_RIA_RIA | opcode=OPCODE_NEG # instrED | opcode=OPCODE_RETN # instrED | opcode=OPCODE_RETI # instrED @@ -141,6 +141,7 @@ rInstruction: | opcode=OPCODE_LD SEP_LPAR rp=(REG_BC|REG_DE) SEP_RPAR SEP_COMMA REG_A # instrRef_RP // x=0, z=2, q=0, p=rp | opcode=OPCODE_JP SEP_LPAR rp=REG_HL SEP_RPAR # instrRef_RP // x=3, z=1, q=1, p=2 + | opcode=OPCODE_JP rp=REG_HL # instrRef_RP // x=3, z=1, q=1, p=2 | opcode=OPCODE_EX SEP_LPAR dst=REG_SP SEP_RPAR SEP_COMMA src=REG_HL # instrRef_RP_RP // x=3, z=3, y=4 @@ -277,7 +278,7 @@ rDisplacement: SEP_LPAR ii=rII '+' n=rExpression SEP_RPAR; rPseudoCode: PREP_ORG expr=rExpression # pseudoOrg | id=ID_IDENTIFIER PREP_EQU expr=rExpression # pseudoEqu - | id=ID_IDENTIFIER PREP_SET expr=rExpression # pseudoSet + | id=ID_IDENTIFIER PREP_VAR expr=rExpression # pseudoVar | PREP_IF expr=rExpression EOL (rLine EOL)* EOL* PREP_ENDIF # pseudoIf | id=ID_IDENTIFIER PREP_MACRO params=rMacroParameters? EOL (rLine EOL)* EOL* PREP_ENDM # pseudoMacroDef | id=ID_IDENTIFIER args=rMacroArguments? # pseudoMacroCall @@ -308,16 +309,16 @@ rDWdata: ; rExpression: - unaryop=(OP_ADD|OP_SUBTRACT|OP_NOT|OP_NOT_2) expr=rExpression # exprUnary + SEP_LPAR expr=rExpression SEP_RPAR # exprParens + | unaryop=(OP_ADD|OP_SUBTRACT|OP_NOT|OP_NOT_2) expr=rExpression # exprUnary | expr1=rExpression op=(OP_MULTIPLY|OP_DIVIDE|OP_MOD|OP_MOD_2) expr2=rExpression # exprInfix | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression # exprInfix | expr1=rExpression op=(OP_SHL|OP_SHR|OP_SHR_2|OP_SHL_2) expr2=rExpression # exprInfix | expr1=rExpression op=(OP_GT|OP_GTE|OP_LT|OP_LTE) expr2=rExpression # exprInfix - | expr1=rExpression op=(OP_AND|OP_AND_2) expr2=rExpression # exprInfix - | expr1=rExpression op=(OP_XOR|OP_XOR_2) expr2=rExpression # exprInfix - | expr1=rExpression op=(OP_OR|OP_OR_2) expr2=rExpression # exprInfix | expr1=rExpression op=OP_EQUAL expr2=rExpression # exprInfix - | SEP_LPAR expr=rExpression SEP_RPAR # exprParens + | expr1=rExpression op=OP_AND expr2=rExpression # exprInfix + | expr1=rExpression op=OP_XOR expr2=rExpression # exprInfix + | expr1=rExpression op=OP_OR expr2=rExpression # exprInfix | num=LIT_NUMBER # exprDec | num=LIT_HEXNUMBER_1 # exprHex1 | num=LIT_HEXNUMBER_2 # exprHex2 diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java index e4bdf7f57..2979b965b 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java @@ -97,7 +97,7 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[PREP_ORG] = Token.PREPROCESSOR; tokenMap[PREP_EQU] = Token.PREPROCESSOR; - tokenMap[PREP_SET] = Token.PREPROCESSOR; + tokenMap[PREP_VAR] = Token.PREPROCESSOR; tokenMap[PREP_INCLUDE] = Token.PREPROCESSOR; tokenMap[PREP_IF] = Token.PREPROCESSOR; tokenMap[PREP_ENDIF] = Token.PREPROCESSOR; @@ -148,11 +148,8 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[OP_NOT] = Token.OPERATOR; tokenMap[OP_NOT_2] = Token.OPERATOR; tokenMap[OP_AND] = Token.OPERATOR; - tokenMap[OP_AND_2] = Token.OPERATOR; tokenMap[OP_OR] = Token.OPERATOR; - tokenMap[OP_OR_2] = Token.OPERATOR; tokenMap[OP_XOR] = Token.OPERATOR; - tokenMap[OP_XOR_2] = Token.OPERATOR; tokenMap[OP_LT] = Token.OPERATOR; tokenMap[OP_LTE] = Token.OPERATOR; tokenMap[OP_GT] = Token.OPERATOR; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java index a16d23061..4b0da8269 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java @@ -27,11 +27,8 @@ public class ExprInfix extends Node { infixOps.put(OP_MOD, (x, y) -> x % y); infixOps.put(OP_MOD_2, (x, y) -> x % y); infixOps.put(OP_AND, (x, y) -> x & y); - infixOps.put(OP_AND_2, (x, y) -> x & y); infixOps.put(OP_OR, (x, y) -> x | y); - infixOps.put(OP_OR_2, (x, y) -> x | y); infixOps.put(OP_XOR, (x, y) -> x ^ y); - infixOps.put(OP_XOR_2, (x, y) -> x ^ y); infixOps.put(OP_SHL, (x, y) -> x << y); infixOps.put(OP_SHL_2, (x, y) -> x << y); infixOps.put(OP_SHR, (x, y) -> x >>> y); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java index d2b855813..0d2e6c2f1 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java @@ -26,6 +26,8 @@ public class InstrED extends Node { xmap.put(OPCODE_RETN, 1); xmap.put(OPCODE_RETI, 1); xmap.put(OPCODE_IM, 1); + xmap.put(OPCODE_RRD, 1); + xmap.put(OPCODE_RLD, 1); xmap.put(OPCODE_LDI, 2); xmap.put(OPCODE_LDD, 2); xmap.put(OPCODE_LDIR, 2); @@ -58,7 +60,7 @@ public InstrED(Token opcode, int y, int z) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), y, z); } - public InstrED(Token opcode, int q, int p, int z) { + public InstrED(Token opcode, int p, int q, int z) { this(opcode, (p << 1) | q, z); } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoSet.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoVar.java similarity index 73% rename from plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoSet.java rename to plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoVar.java index a82d771d4..141cb46fa 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoSet.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoVar.java @@ -6,16 +6,16 @@ import java.util.Objects; -public class PseudoSet extends Node { +public class PseudoVar extends Node { public final String id; - public PseudoSet(int line, int column, String id) { + public PseudoVar(int line, int column, String id) { super(line, column); this.id = Objects.requireNonNull(id); // expr is the only child } - public PseudoSet(Token id) { + public PseudoVar(Token id) { this(id.getLine(), id.getCharPositionInLine(), id.getText()); } @@ -26,12 +26,12 @@ public void accept(NodeVisitor visitor) { @Override protected String toStringShallow() { - return "PseudoSet(" + id + ")"; + return "PseudoVar(" + id + ")"; } @Override protected Node mkCopy() { - return new PseudoSet(line, column, id); + return new PseudoVar(line, column, id); } @Override @@ -39,7 +39,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - PseudoSet pseudoSet = (PseudoSet) o; - return Objects.equals(id, pseudoSet.id); + PseudoVar pseudoVar = (PseudoVar) o; + return Objects.equals(id, pseudoVar.id); } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java index 0e9e31a82..3cb9101f9 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java @@ -62,7 +62,7 @@ public void visit(PseudoMacroDef node) { } @Override - public void visit(PseudoSet node) { + public void visit(PseudoVar node) { currentDeclarationId = normalizeId(node.id); visitChildren(node); addVariable(node.id, node); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java index 68fd9cdb5..622d55d52 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java @@ -95,14 +95,14 @@ public Node visitInstrED_RP(InstrED_RPContext ctx) { // | opcode=OPCODE_ADC REG_HL SEP_COMMA rp=rRegPair # instrED_RP int q = (ctx.opcode.getType() == OPCODE_SBC) ? 0 : 1; int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); - return new InstrED(ctx.opcode, p, q, 2).setSizeBytes(2); + return new InstrED(ctx.opcode, p,q, 2).setSizeBytes(2); } @Override public Node visitInstrED_NN_RP(InstrED_NN_RPContext ctx) { // | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA rp=rRegPair # instrED_NN_RP int q = 0; - int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); + int p = CompilerTables.regPairs.get(ctx.rp.getType()); Node instr = new InstrED(ctx.opcode, p, q, 3).setSizeBytes(4); instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; @@ -112,7 +112,7 @@ public Node visitInstrED_NN_RP(InstrED_NN_RPContext ctx) { public Node visitInstrED_RP_NN(InstrED_RP_NNContext ctx) { // | opcode=OPCODE_LD rp=rRegPair SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrED_RP_NN int q = 1; - int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); + int p = CompilerTables.regPairs.get(ctx.rp.getType()); Node instr = new InstrED(ctx.opcode, p, q, 3).setSizeBytes(4); instr.addChild(CreateVisitors.expr.visit(ctx.nn).setSizeBytes(2)); return instr; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java index 69477ab9a..fd7c741d8 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java @@ -26,8 +26,8 @@ public Node visitPseudoEqu(PseudoEquContext ctx) { } @Override - public Node visitPseudoSet(PseudoSetContext ctx) { - PseudoSet pseudo = new PseudoSet(ctx.id); + public Node visitPseudoVar(PseudoVarContext ctx) { + PseudoVar pseudo = new PseudoVar(ctx.id); pseudo.addChild(CreateVisitors.expr.visit(ctx.expr)); return pseudo; } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java index 1026b73ee..dd0723657 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java @@ -119,7 +119,7 @@ public void visit(PseudoEqu node) { } @Override - public void visit(PseudoSet node) { + public void visit(PseudoVar node) { sizeBytes = 0; // expected number of bytes will be known on usage (DB, DW, DS, instruction with expr, ORG) String normalizedId = normalizeId(node.id); if (!doNotEvaluateVariables.contains(normalizedId)) { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java index 6b3784c34..5accb6a83 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/NodeVisitor.java @@ -129,7 +129,7 @@ public void visit(PseudoOrg node) { visitChildren(node); } - public void visit(PseudoSet node) { + public void visit(PseudoVar node) { visitChildren(node); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java index e050e3a39..0fbc87a0d 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java @@ -33,20 +33,17 @@ public class Utils { "(HL)", REG_HL ); - public static Map regPairsBD = Map.of( - "b", REG_B, - "d", REG_D - ); - public static Map regPairsBDHSP = Map.of( - "b", REG_B, - "d", REG_D, - "h", REG_H, + public static Map regPairs = Map.of( + "bc", REG_BC, + "de", REG_DE, + "hl", REG_HL, "sp", REG_SP ); - public static Map regPairsBDHAF = Map.of( - "b", REG_B, - "d", REG_D, - "h", REG_H, + + public static Map regPairs2 = Map.of( + "bc", REG_BC, + "de", REG_DE, + "hl", REG_HL, "af", REG_AF ); @@ -122,7 +119,7 @@ public static void forRegister(Consumer> f) { } public static void forRegPair(Consumer> f) { - for (Map.Entry regPair : regPairsBDHSP.entrySet()) { + for (Map.Entry regPair : regPairs.entrySet()) { f.accept(Pair.of(regPair.getKey(), regPair.getValue())); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java index 373809a7f..0854a8b4d 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java @@ -15,7 +15,7 @@ public void testParseEols() { @Test public void testParseError1() { - assertTokenTypes("B &", REG_B, ERROR, EOF); + assertTokenTypes("B :", REG_B, ERROR, EOF); } @Test @@ -165,11 +165,31 @@ public void testParseOpcodes() { assertTokenTypesIgnoreCase("XOR", OPCODE_XOR, EOF); } + @Test + public void parseIm() { + assertTokenTypesIgnoreCase("IM 0 0", OPCODE_IM, IM_0, LIT_NUMBER, EOF); + assertTokenTypesIgnoreCase("IM 0/1", OPCODE_IM, IM_01, EOF); + assertTokenTypesIgnoreCase("IM 3 0", OPCODE_IM, LIT_NUMBER, LIT_NUMBER, EOF); + } + + @Test + public void parseRet() { + assertTokenTypesIgnoreCase("ret and", OPCODE_RET, OPCODE_AND, EOF); + assertTokenTypesIgnoreCase("ret nz", OPCODE_RET, COND_NZ, EOF); + assertTokenTypesIgnoreCase("ret c c", OPCODE_RET, COND_C, REG_C, EOF); + } + + @Test + public void parseJp() { + assertTokenTypesIgnoreCase("jp c c", OPCODE_JP, COND_C, REG_C, EOF); + assertTokenTypesIgnoreCase("jp hl", OPCODE_JP, REG_HL, EOF); + } + @Test public void testParsePreprocessor() { assertTokenTypesIgnoreCase("ORG", PREP_ORG, EOF); assertTokenTypesIgnoreCase("EQU", PREP_EQU, EOF); - assertTokenTypesIgnoreCase("SET", PREP_SET, EOF); + assertTokenTypesIgnoreCase("VAR", PREP_VAR, EOF); assertTokenTypesIgnoreCase("INCLUDE", PREP_INCLUDE, EOF); assertTokenTypesIgnoreCase("IF", PREP_IF, EOF); assertTokenTypesIgnoreCase("ENDIF", PREP_ENDIF, EOF); @@ -191,8 +211,16 @@ public void testRegisters() { assertTokenTypesIgnoreCase("H", REG_H, EOF); assertTokenTypesIgnoreCase("L", REG_L, EOF); assertTokenTypesIgnoreCase("AF", REG_AF, EOF); - assertTokenTypesIgnoreCase("AFF", REG_AFF, EOF); + assertTokenTypesIgnoreCase("AF'", REG_AFF, EOF); assertTokenTypesIgnoreCase("SP", REG_SP, EOF); + assertTokenTypesIgnoreCase("IX", REG_IX, EOF); + assertTokenTypesIgnoreCase("IY", REG_IY, EOF); + assertTokenTypesIgnoreCase("IXH", REG_IXH, EOF); + assertTokenTypesIgnoreCase("IXL", REG_IXL, EOF); + assertTokenTypesIgnoreCase("IYH", REG_IYH, EOF); + assertTokenTypesIgnoreCase("IYL", REG_IYL, EOF); + assertTokenTypesIgnoreCase("R", REG_R, EOF); + assertTokenTypesIgnoreCase("I", REG_I, EOF); } @Test @@ -204,7 +232,7 @@ public void testSeparators() { public void testOperators1() { assertTokenTypes("+-*/=<<>><><=>=^%|&", OP_ADD, OP_SUBTRACT, OP_MULTIPLY, OP_DIVIDE, OP_EQUAL, OP_SHL_2, OP_SHR_2, OP_LT, OP_GT, OP_LTE, OP_GTE, - OP_XOR_2, OP_MOD_2, OP_OR_2, OP_AND_2, EOF); + OP_XOR, OP_MOD_2, OP_OR, OP_AND, EOF); } @Test @@ -213,9 +241,6 @@ public void testOperators2() { assertTokenTypesIgnoreCase("SHR", OP_SHR, EOF); assertTokenTypesIgnoreCase("SHL", OP_SHL, EOF); assertTokenTypesIgnoreCase("NOT", OP_NOT, EOF); - assertTokenTypesIgnoreCase("AND", OP_AND, EOF); - assertTokenTypesIgnoreCase("OR", OP_OR, EOF); - assertTokenTypesIgnoreCase("XOR", OP_XOR, EOF); } @Test @@ -233,6 +258,6 @@ public void testLabel() { @Test public void testCombineSpaceWithNoSpaceTokens() { - assertTokenTypes("abc=(XOR,MOD)", ID_IDENTIFIER, OP_EQUAL, SEP_LPAR, OP_XOR, SEP_COMMA, OP_MOD, SEP_RPAR, EOF); + assertTokenTypes("abc=(^,MOD)", ID_IDENTIFIER, OP_EQUAL, SEP_LPAR, OP_XOR, SEP_COMMA, OP_MOD, SEP_RPAR, EOF); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java index d848045ae..61929a061 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java @@ -80,7 +80,6 @@ public void testAssociativitMulDiv() { @Test public void testPrecedencePlusMinusMulDivMod() { Program program = parseProgram("db 2+3*4-9/2 mod 3"); - System.out.println(program); assertTrees( new Program() .addChild(new DataDB(0, 0) @@ -124,58 +123,59 @@ public void testAssociativityEqual() { @Test public void testAndMulXorDivNotPlusMinus() { - Program program = parseProgram("db not 1 and 2 or 2 xor 5 = - 5 * 6 shl 4 - 1 shr 2"); + Program program = parseProgram("db not 1 & 2 | 2 ^ 5 = - 5 * 6 shl 4 - 1 shr 2"); assertTrees( new Program() .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprInfix(0, 0, OP_OR) - .addChild(new ExprInfix(0, 0, OP_AND) - .addChild(new ExprUnary(0, 0, OP_NOT) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprInfix(0, 0, OP_XOR) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 5)))) - .addChild(new ExprInfix(0, 0, OP_SHR) // shl/shr associates to the right - .addChild(new ExprInfix(0, 0, OP_SHL) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 5))) - .addChild(new ExprNumber(0, 0, 6))) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 4)) - .addChild(new ExprNumber(0, 0, 1)))) - .addChild(new ExprNumber(0, 0, 2))))), + .addChild(new ExprInfix(0, 0, OP_OR) + .addChild(new ExprInfix(0, 0, OP_AND) + .addChild(new ExprUnary(0, 0, OP_NOT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SHR) + .addChild(new ExprInfix(0, 0, OP_SHL) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))))), program ); } @Test public void testAndMulXorDivNotPlusMinusWithOperators() { + //Program program = parseProgram("db ((~1) & 2) | (2 ^ (5 = ((((-5) * 6) << (4 - 1)) >> 2)))"); Program program = parseProgram("db ~1 & 2 | 2 ^ 5 = -5 * 6 << 4 - 1 >> 2"); assertTrees( new Program() .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprInfix(0, 0, OP_OR_2) - .addChild(new ExprInfix(0, 0, OP_AND_2) - .addChild(new ExprUnary(0, 0, OP_NOT_2) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprInfix(0, 0, OP_XOR_2) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 5)))) - .addChild(new ExprInfix(0, 0, OP_SHR_2) // shl/shr associates to the right - .addChild(new ExprInfix(0, 0, OP_SHL_2) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 5))) - .addChild(new ExprNumber(0, 0, 6))) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 4)) - .addChild(new ExprNumber(0, 0, 1)))) - .addChild(new ExprNumber(0, 0, 2))))), + .addChild(new ExprInfix(0, 0, OP_OR) + .addChild(new ExprInfix(0, 0, OP_AND) + .addChild(new ExprUnary(0, 0, OP_NOT_2) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SHR_2) + .addChild(new ExprInfix(0, 0, OP_SHL_2) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))))), program ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java index f6e61e651..46e4c4510 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java @@ -1,5 +1,6 @@ package net.emustudio.plugins.compiler.asZ80.parser; +import net.emustudio.plugins.compiler.asZ80.CompilerTables; import net.emustudio.plugins.compiler.asZ80.ast.Node; import net.emustudio.plugins.compiler.asZ80.ast.Program; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprCurrentAddress; @@ -37,6 +38,7 @@ public void testInstrNoArgs() { assertInstr("ret", OPCODE_RET, 3, 1, 1); assertInstr("exx", OPCODE_EXX, 3, 3, 1); assertInstr("jp hl", OPCODE_JP, 3, 5, 1); + assertInstr("jp (hl)", OPCODE_JP, 3, 5, 1); assertInstr("ld sp, hl", OPCODE_LD, 3, 7, 1); assertInstr("ex (sp), hl", OPCODE_EX, 3, 4, 3); assertInstr("ex de, hl", OPCODE_EX, 3, 5, 3); @@ -79,37 +81,41 @@ public void testInstrNoArgs() { public void testInstrReg() { Random random = new Random(); forRegister(regValue -> { - assertInstr("inc " + regValue.l, OPCODE_INC, 0, regValue.r, 4); - assertInstr("dec " + regValue.l, OPCODE_DEC, 0, regValue.r, 5); - assertInstrExpr("ld " + regValue.l + ", ", OPCODE_LD, 0, regValue.r, 6); - assertInstr("add a, " + regValue.l, OPCODE_ADD, 2, 0, regValue.r); - assertInstr("adc a, " + regValue.l, OPCODE_ADC, 2, 1, regValue.r); - assertInstr("sub " + regValue.l, OPCODE_SUB, 2, 2, regValue.r); - assertInstr("sbc a, " + regValue.l, OPCODE_SBC, 2, 3, regValue.r); - assertInstr("and " + regValue.l, OPCODE_AND, 2, 4, regValue.r); - assertInstr("xor " + regValue.l, OPCODE_XOR, 2, 5, regValue.r); - assertInstr("or " + regValue.l, OPCODE_OR, 2, 6, regValue.r); - assertInstr("cp " + regValue.l, OPCODE_CP, 2, 7, regValue.r); - - assertInstrCBNoArgs("rlc " + regValue.l, OPCODE_RLC, 0, regValue.r); - assertInstrCBNoArgs("rrc " + regValue.l, OPCODE_RRC, 1, regValue.r); - assertInstrCBNoArgs("rl " + regValue.l, OPCODE_RL, 2, regValue.r); - assertInstrCBNoArgs("rr " + regValue.l, OPCODE_RR, 3, regValue.r); - assertInstrCBNoArgs("sla " + regValue.l, OPCODE_SLA, 4, regValue.r); - assertInstrCBNoArgs("sra " + regValue.l, OPCODE_SRA, 5, regValue.r); - assertInstrCBNoArgs("sll " + regValue.l, OPCODE_SLL, 6, regValue.r); - assertInstrCBNoArgs("srl " + regValue.l, OPCODE_SRL, 7, regValue.r); - - int bit = random.nextInt() % 8; - assertInstrCBExprBit("bit " + bit + ", " + regValue.l, OPCODE_BIT, bit, regValue.r); - assertInstrCBExprBit("res " + bit + ", " + regValue.l, OPCODE_RES, bit, regValue.r); - assertInstrCBExprBit("set " + bit + ", " + regValue.l, OPCODE_SET, bit, regValue.r); - - assertInstrED("in " + regValue.l + ", (c)", OPCODE_IN, regValue.r, 0); - assertInstrED("out (c), " + regValue.l, OPCODE_OUT, regValue.r, 1); + int r = CompilerTables.registers.get(regValue.r); + assertInstr("inc " + regValue.l, OPCODE_INC, 0, r, 4); + assertInstr("dec " + regValue.l, OPCODE_DEC, 0, r, 5); + assertInstrExpr("ld " + regValue.l + ", ", OPCODE_LD, 0, r, 6); + assertInstr("add a, " + regValue.l, OPCODE_ADD, 2, 0, r); + assertInstr("adc a, " + regValue.l, OPCODE_ADC, 2, 1, r); + assertInstr("sub " + regValue.l, OPCODE_SUB, 2, 2, r); + assertInstr("sbc a, " + regValue.l, OPCODE_SBC, 2, 3, r); + assertInstr("and " + regValue.l, OPCODE_AND, 2, 4, r); + assertInstr("xor " + regValue.l, OPCODE_XOR, 2, 5, r); + assertInstr("or " + regValue.l, OPCODE_OR, 2, 6, r); + assertInstr("cp " + regValue.l, OPCODE_CP, 2, 7, r); + + assertInstrCBNoArgs("rlc " + regValue.l, OPCODE_RLC, 0, r); + assertInstrCBNoArgs("rrc " + regValue.l, OPCODE_RRC, 1, r); + assertInstrCBNoArgs("rl " + regValue.l, OPCODE_RL, 2, r); + assertInstrCBNoArgs("rr " + regValue.l, OPCODE_RR, 3, r); + assertInstrCBNoArgs("sla " + regValue.l, OPCODE_SLA, 4, r); + assertInstrCBNoArgs("sra " + regValue.l, OPCODE_SRA, 5, r); + assertInstrCBNoArgs("sll " + regValue.l, OPCODE_SLL, 6, r); + assertInstrCBNoArgs("srl " + regValue.l, OPCODE_SRL, 7, r); + + int bit = Math.abs(random.nextInt() % 8); + assertInstrCBExprBit("bit " + bit + ", " + regValue.l, OPCODE_BIT, bit, r); + assertInstrCBExprBit("res " + bit + ", " + regValue.l, OPCODE_RES, bit, r); + assertInstrCBExprBit("set " + bit + ", " + regValue.l, OPCODE_SET, bit, r); + + if (r != 6) { + assertInstrED("in " + regValue.l + ", (c)", OPCODE_IN, r, 0); + assertInstrED("out (c), " + regValue.l, OPCODE_OUT, r, 1); + } forRegister(regValue2 -> { - assertInstr("ld " + regValue.l + ", " + regValue2.l, OPCODE_LD, 1, regValue.r, regValue2.r); + int r2 = CompilerTables.registers.get(regValue2.r); + assertInstr("ld " + regValue.l + ", " + regValue2.l, OPCODE_LD, 1, r, r2); }); }); } @@ -117,14 +123,19 @@ public void testInstrReg() { @Test public void testInstrRP() { forRegPair(regPair -> { - assertInstrExpr("ld " + regPair.l + ", ", OPCODE_LD, 0, regPair.r, 0, 1); - assertInstr("add hl, " + regPair.l, OPCODE_ADD, 0, (regPair.r << 1) | 1, 1); - assertInstr("inc " + regPair.l, OPCODE_INC, 0, regPair.r, 0, 3); - assertInstr("dec " + regPair.l, OPCODE_DEC, 0, regPair.r, 1, 3); - assertInstrED("sbc hl, " + regPair.l, OPCODE_SBC, regPair.r << 1, 2); - assertInstrED("adc hl, " + regPair.l, OPCODE_ADC, (regPair.r << 1) | 1, 2); - assertInstrEDExpr("ld (", "), " + regPair.l, OPCODE_LD, regPair.r << 1, 3); - assertInstrEDExpr("ld " + regPair.l + ", (", ")" + regPair.l, OPCODE_LD, (regPair.r << 1) | 1, 3); + int rp = CompilerTables.regPairs.get(regPair.r); + + assertInstrExpr("ld " + regPair.l + ", ", OPCODE_LD, 0, rp, 0, 1); + assertInstr("add hl, " + regPair.l, OPCODE_ADD, 0, (rp << 1) | 1, 1); + assertInstr("inc " + regPair.l, OPCODE_INC, 0, rp, 0, 3); + assertInstr("dec " + regPair.l, OPCODE_DEC, 0, rp, 1, 3); + assertInstrED("sbc hl, " + regPair.l, OPCODE_SBC, rp << 1, 2); + assertInstrED("adc hl, " + regPair.l, OPCODE_ADC, (rp << 1) | 1, 2); + if (rp != 2) { + // HL + assertInstrEDExpr("ld (", "), " + regPair.l, OPCODE_LD, rp << 1, 3); + assertInstrEDExpr("ld " + regPair.l + ", (", ")", OPCODE_LD, (rp << 1) | 1, 3); + } }); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java index ace1b00a3..e843ba550 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java @@ -32,7 +32,7 @@ public void testConstant() { public void testVariable() { Program program = parseProgram("here set 0x55"); assertTrees(new Program() - .addChild(new PseudoSet(0, 0, "here") + .addChild(new PseudoVar(0, 0, "here") .addChild(new ExprNumber(0, 0, 0x55))), program ); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java index b35805b98..aa8a41abc 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java @@ -254,11 +254,11 @@ public void testEvaluateSETforwardTwoTimes() { program .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoSet(0, 0, "const") + .addChild(new PseudoVar(0, 0, "const") .addChild(new ExprNumber(0, 0, 1))) .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 6) .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoSet(0, 0, "const") + .addChild(new PseudoVar(0, 0, "const") .addChild(new ExprNumber(0, 0, 2))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); @@ -268,11 +268,11 @@ public void testEvaluateSETforwardTwoTimes() { new Program() .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoSet(0, 0, "const") + .addChild(new PseudoVar(0, 0, "const") .addChild(new Evaluated(0, 0, 1))) .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 6) .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoSet(0, 0, "const") + .addChild(new PseudoVar(0, 0, "const") .addChild(new Evaluated(0, 0, 2))), program ); @@ -284,9 +284,9 @@ public void testEvaluateSETforwardMoreTimes() { program .addChild(new DataDB(0, 0) .addChild(new ExprId(0, 0, "id"))) - .addChild(new PseudoSet(0, 0, "id") + .addChild(new PseudoVar(0, 0, "id") .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoSet(0, 0, "id") + .addChild(new PseudoVar(0, 0, "id") .addChild(new ExprNumber(0, 0, 2))) .addChild(new PseudoEqu(0, 0, "const") .addChild(new ExprNumber(0, 0, 1))); @@ -298,9 +298,9 @@ public void testEvaluateSETforwardMoreTimes() { new Program() .addChild(new DataDB(0, 0) .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoSet(0, 0, "id") + .addChild(new PseudoVar(0, 0, "id") .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoSet(0, 0, "id") + .addChild(new PseudoVar(0, 0, "id") .addChild(new Evaluated(0, 0, 2))), program ); @@ -310,9 +310,9 @@ public void testEvaluateSETforwardMoreTimes() { public void testTwoSETthenReference() { Program program = new Program(); program - .addChild(new PseudoSet(0, 0, "id") + .addChild(new PseudoVar(0, 0, "id") .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoSet(0, 0, "id") + .addChild(new PseudoVar(0, 0, "id") .addChild(new ExprNumber(0, 0, 2))) .addChild(new PseudoEqu(0, 0, "const") .addChild(new ExprNumber(0, 0, 1))) @@ -324,9 +324,9 @@ public void testTwoSETthenReference() { assertTrees( new Program() - .addChild(new PseudoSet(0, 0, "id") + .addChild(new PseudoVar(0, 0, "id") .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoSet(0, 0, "id") + .addChild(new PseudoVar(0, 0, "id") .addChild(new Evaluated(0, 0, 2))) .addChild(new DataDB(0, 0) .addChild(new Evaluated(0, 0, 2))), From bde2302ecaed0e1ef01e89dead33544d17de086f Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 20 Feb 2022 08:37:10 +0100 Subject: [PATCH 102/314] [#201] as-z80: tests --- .../plugins/compiler/asZ80/OC_RegTest.java | 212 ------------------ .../asZ80/parser/ParsePseudoTest.java | 2 +- .../CheckDeclarationsVisitorTest.java | 18 +- .../asZ80/visitors/ExpandMacrosTest.java | 8 +- 4 files changed, 14 insertions(+), 226 deletions(-) delete mode 100644 plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java deleted file mode 100644 index ce1bcba7f..000000000 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/OC_RegTest.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80; - -import org.junit.Assert; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class OC_RegTest { -// -// @Test -// public void testINR() throws Exception { -// compile( -// "inc A\n" -// + "inc B\n" -// + "inc C\n" -// + "inc D\n" -// + "inc E\n" -// + "inc H\n" -// + "inc L\n" -// + "inc (HL)\n" -// ); -// -// assertProgram( -// 0x3C, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34 -// ); -// } -// -// @Test -// public void testDCR() throws Exception { -// compile( -// "dec A\n" -// + "dec B\n" -// + "dec C\n" -// + "dec D\n" -// + "dec E\n" -// + "dec H\n" -// + "dec L\n" -// + "dec (HL)\n" -// ); -// -// assertProgram( -// 0x3D, 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, 0x35 -// ); -// } -// -// @Test -// public void testADD() throws Exception { -// compile( -// "add A,A\n" -// + "add A,B\n" -// + "add A,C\n" -// + "add A,D\n" -// + "add A,E\n" -// + "add A,H\n" -// + "add A,L\n" -// + "add A,(HL)\n" -// ); -// -// assertProgram( -// 0x87, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86 -// ); -// } -// -// @Test -// public void testADC() throws Exception { -// compile( -// "adc A,A\n" -// + "adc A,B\n" -// + "adc A,C\n" -// + "adc A,D\n" -// + "adc A,E\n" -// + "adc A,H\n" -// + "adc A,L\n" -// + "adc A,(HL)\n" -// ); -// -// assertProgram( -// 0x8F, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E -// ); -// } -// -// @Test -// public void testSUB() throws Exception { -// compile( -// "sub A\n" -// + "sub B\n" -// + "sub C\n" -// + "sub D\n" -// + "sub E\n" -// + "sub H\n" -// + "sub L\n" -// + "sub (HL)\n" -// ); -// -// assertProgram( -// 0x97, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96 -// ); -// } -// -// @Test -// public void testSBB() throws Exception { -// compile( -// "sbc A\n" -// + "sbc B\n" -// + "sbc C\n" -// + "sbc D\n" -// + "sbc E\n" -// + "sbc H\n" -// + "sbc L\n" -// + "sbc (HL)\n" -// ); -// -// assertProgram( -// 0x9F, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E -// ); -// } -// -// @Test -// public void testANA() throws Exception { -// compile( -// "and A\n" -// + "and B\n" -// + "and C\n" -// + "and D\n" -// + "and E\n" -// + "and H\n" -// + "and L\n" -// + "and (HL)\n" -// ); -// -// assertProgram( -// 0xA7, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6 -// ); -// } -// -// @Test -// public void testXRA() throws Exception { -// compile( -// "xor A\n" -// + "xor B\n" -// + "xor C\n" -// + "xor D\n" -// + "xor E\n" -// + "xor H\n" -// + "xor L\n" -// + "xor (HL)\n" -// ); -// -// assertProgram( -// 0xAF, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE -// ); -// } -// -// @Test -// public void testORA() throws Exception { -// compile( -// "or A\n" -// + "or B\n" -// + "or C\n" -// + "or D\n" -// + "or E\n" -// + "or H\n" -// + "or L\n" -// + "or (HL)\n" -// ); -// -// assertProgram( -// 0xB7, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6 -// ); -// } -// -// @Test -// public void testCMP() throws Exception { -// compile( -// "cp A\n" -// + "cp B\n" -// + "cp C\n" -// + "cp D\n" -// + "cp E\n" -// + "cp H\n" -// + "cp L\n" -// + "cp (HL)\n" -// ); -// -// assertProgram( -// 0xBF, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE -// ); -// } -// -// @Test -// public void testOCRegSizeReturns1() throws Exception { -// Assert.assertEquals(1, new OC_Reg(55, 0, 0, 0).getSize()); -// } -} diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java index e843ba550..2a2b34df7 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java @@ -30,7 +30,7 @@ public void testConstant() { @Test public void testVariable() { - Program program = parseProgram("here set 0x55"); + Program program = parseProgram("here var 0x55"); assertTrees(new Program() .addChild(new PseudoVar(0, 0, "here") .addChild(new ExprNumber(0, 0, 0x55))), diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitorTest.java index 944560576..f037fc132 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitorTest.java @@ -11,21 +11,21 @@ public class CheckDeclarationsVisitorTest { @Test public void testDeclarationsAreFound() { - Program program = parseProgram("label:\nconstant equ 1\nvariable set 1\nxxx macro\nendm"); + Program program = parseProgram("label:\nconstant equ 1\nvariable var 1\nxxx macro\nendm"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); } @Test public void testVariableTwoTimesPass() { - Program program = parseProgram("var set 1\nvar set 2"); + Program program = parseProgram("variable var 1\nvariable var 2"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); } @Test public void testConstantTwoTimesCannotBeDefined() { - Program program = parseProgram("var equ 1\nvar equ 2"); + Program program = parseProgram("variable equ 1\nvariable equ 2"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); @@ -33,7 +33,7 @@ public void testConstantTwoTimesCannotBeDefined() { @Test public void testVarCannotBeDefinedIfAnotherDeclarationExists() { - Program program = parseProgram("var equ 1\nvar set 2"); + Program program = parseProgram("variable equ 1\nvariable var 2"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); @@ -80,7 +80,7 @@ public void testMacroParametersCollideWithConstant() { @Test public void testMacroParametersCollideWithVariable() { - Program program = parseProgram("variable set 1\nx macro variable\nendm"); + Program program = parseProgram("variable var 1\nx macro variable\nendm"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); @@ -128,7 +128,7 @@ public void testMacroReuseParameterNamesIsPossible() { @Test public void testIfExpressionReferencesOwnBlockDeclarations() { - Program program = parseProgram("if var + 1\nvar set -1\nendif"); + Program program = parseProgram("if variable + 1\nvariable var -1\nendif"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); assertTrue(program.env().hasError(ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK)); @@ -136,7 +136,7 @@ public void testIfExpressionReferencesOwnBlockDeclarations() { @Test public void testNestedIfExpressionReferencesOwnBlockDeclarations() { - Program program = parseProgram("if var + 1\nif 0\nvar:\nendif\nendif"); + Program program = parseProgram("if variable + 1\nif 0\nvariable:\nendif\nendif"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); assertTrue(program.env().hasError(ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK)); @@ -152,7 +152,7 @@ public void testSelfReferencingConstant() { @Test public void testSelfReferencingNoneExistingVariableIsNotFine() { - Program program = parseProgram("self set self + 1"); + Program program = parseProgram("self var self + 1"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); assertTrue(program.env().hasError(ERROR_DECLARATION_REFERENCES_ITSELF)); @@ -160,7 +160,7 @@ public void testSelfReferencingNoneExistingVariableIsNotFine() { @Test public void testSelfReferencingExistingVariableIsFine() { - Program program = parseProgram("self set 1\n self set self + 1"); + Program program = parseProgram("self var 1\n self var self + 1"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); assertTrue(program.env().hasNoErrors()); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java index aefbdfec9..6fd7a09db 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java @@ -96,7 +96,7 @@ public void testMacroCallComplexInfiniteLoop() { @Test public void testMacroCallWithArguments() { - Program program = parseProgram("x 1,2,3\nx macro q,r,t\nendm"); + Program program = parseProgram("x 1,2,3\nx macro u,v,w\nendm"); ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); macrosVisitor.visit(program); @@ -110,11 +110,11 @@ public void testMacroCallWithArguments() { .addChild(new ExprNumber(0, 0, 3))) .addChild(new PseudoMacroDef(0, 0, "x") .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))) + .addChild(new ExprId(0, 0, "u"))) .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "r"))) + .addChild(new ExprId(0, 0, "v"))) .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "t"))))), + .addChild(new ExprId(0, 0, "w"))))), program ); } From 2840a4f294888c328335701aa5ccab5e7cfc8b1c Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 20 Feb 2022 09:15:23 +0100 Subject: [PATCH 103/314] [#201] as-z80: tests --- .../asZ80/visitors/CreateInstrVisitor.java | 2 +- .../asZ80/visitors/GenerateCodeVisitor.java | 7 +- .../plugins/compiler/asZ80/Utils.java | 16 +++++ .../compiler/asZ80/parser/ParseInstrTest.java | 69 +++++++++++++++++++ 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java index 622d55d52..d104899ae 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java @@ -57,7 +57,7 @@ public Node visitInstrXDCB_N(InstrXDCB_NContext ctx) { Node instr = new InstrXDCB(ctx.opcode, prefix, 0, 6).setSizeBytes(4); instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); instr.addChild(CreateVisitors.expr.visit(ctx.n).setMaxValue(7)); - return super.visitInstrXDCB_N(ctx); + return instr; } @Override diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java index 34ad4fb4b..122abc4fd 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java @@ -89,11 +89,14 @@ public void visit(InstrXD node) { @Override public void visit(InstrXDCB node) { - for (byte b : node.eval()) { - hex.add(b); + byte[] eval = node.eval(); + for (int i = 0; i < eval.length - 1; i++) { + // opcode goes after displacement + hex.add(eval[i]); } expectedBytes = 0; visitChildren(node); + hex.add(eval[eval.length - 1]); // opcode } @Override diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java index 0fbc87a0d..82dce4fba 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java @@ -47,6 +47,16 @@ public class Utils { "af", REG_AF ); + public static Map rot = Map.of( + "rlc", OPCODE_RLC, + "rrc", OPCODE_RRC, + "rl", OPCODE_RL, + "rr", OPCODE_RR, + "sla", OPCODE_SLA, + "sra", OPCODE_SRA, + "sll", OPCODE_SLL, + "srl", OPCODE_SRL + ); public static List getTokens(String variation) { AsZ80Lexer lexer = new AsZ80Lexer(CharStreams.fromString(variation)); @@ -118,6 +128,12 @@ public static void forRegister(Consumer> f) { } } + public static void forRot(Consumer> f) { + for (Map.Entry rot : rot.entrySet()) { + f.accept(Pair.of(rot.getKey(), rot.getValue())); + } + } + public static void forRegPair(Consumer> f) { for (Map.Entry regPair : regPairs.entrySet()) { f.accept(Pair.of(regPair.getKey(), regPair.getValue())); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java index 46e4c4510..34dbb3d42 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java @@ -9,6 +9,7 @@ import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrCB; import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrED; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrXDCB; import org.junit.Test; import java.util.Random; @@ -160,6 +161,43 @@ public void testInstrExpr() { assertInstrExpr("rst", OPCODE_RST, 3, 0, 7); } + @Test + public void testInstrXDCB() { + Random random = new Random(); + forRegister(register -> { + int z = CompilerTables.registers.get(register.r); + forRot(rot -> { + int y = CompilerTables.rot.get(rot.r); + if (z != 6) { + assertInstrXDCBExpr(rot.l + " (ix + ", "), " + register.l, rot.r, 0xDD, y, z); + assertInstrXDCBExpr(rot.l + " (iy + ", "), " + register.l, rot.r, 0xFD, y, z); + } + }); + + int y = Math.abs(random.nextInt() % 8); + if (z != 6) { + assertInstrXDCBExprBit("res " + y + ", (ix + ", "), " + register.l, OPCODE_RES, 0xDD, y, z); + assertInstrXDCBExprBit("res " + y + ", (iy + ", "), " + register.l, OPCODE_RES, 0xFD, y, z); + assertInstrXDCBExprBit("set " + y + ", (ix + ", "), " + register.l, OPCODE_SET, 0xDD, y, z); + assertInstrXDCBExprBit("set " + y + ", (iy + ", "), " + register.l, OPCODE_SET, 0xFD, y, z); + } + }); + + forRot(rot -> { + int y = CompilerTables.rot.get(rot.r); + assertInstrXDCBExpr(rot.l + " (ix + ", ")", rot.r, 0xDD, y, 6); + assertInstrXDCBExpr(rot.l + " (iy + ", ")", rot.r, 0xFD, y, 6); + }); + + int y = Math.abs(random.nextInt() % 8); + assertInstrXDCBExprBit("bit " + y + ", (ix + ", ")", OPCODE_BIT, 0xDD, y, 6); + assertInstrXDCBExprBit("bit " + y + ", (iy + ", ")", OPCODE_BIT, 0xFD, y, 6); + assertInstrXDCBExprBit("res " + y + ", (ix + ", ")", OPCODE_RES, 0xDD, y, 6); + assertInstrXDCBExprBit("res " + y + ", (iy + ", ")", OPCODE_RES, 0xFD, y, 6); + assertInstrXDCBExprBit("set " + y + ", (ix + ", ")", OPCODE_SET, 0xDD, y, 6); + assertInstrXDCBExprBit("set " + y + ", (iy + ", ")", OPCODE_SET, 0xFD, y, 6); + } + private void assertInstr(String instr, int instrType, int x, int y, int z) { forStringCaseVariations(instr, variation -> { @@ -228,4 +266,35 @@ private void assertInstrCBExprBit(String instr, int instrType, int y, int z) { assertTrees(new Program().addChild(new InstrCB(0, 0, instrType, 0, z).addChild(expr)), program); }); } + + private void assertInstrXDCBExpr(String instrPrefix, String instrPostfix, int instrType, int prefix, int y, int z) { + Node expr = new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); + + forStringCaseVariations(instrPrefix, instrPrefixVariation -> { + forStringCaseVariations(instrPostfix, instrPostfixVariation -> { + Program program = parseProgram(instrPrefixVariation + " $ + 5" + instrPostfixVariation); + assertTrees(new Program().addChild(new InstrXDCB(0, 0, instrType, prefix, y, z).addChild(expr)), program); + }); + }); + } + + private void assertInstrXDCBExprBit(String instrPrefix, String instrPostfix, int instrType, int prefix, int y, int z) { + Node expr = new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); + + Node yExpr = new ExprNumber(0, 0, y); + + forStringCaseVariations(instrPrefix, instrPrefixVariation -> { + forStringCaseVariations(instrPostfix, instrPostfixVariation -> { + Program program = parseProgram(instrPrefixVariation + " $ + 5" + instrPostfixVariation); + assertTrees(new Program() + .addChild(new InstrXDCB(0, 0, instrType, prefix, 0, z) + .addChild(expr) + .addChild(yExpr)), program); + }); + }); + } } From 9108743bf10529bddd2c0beb5d69beccf1adf98b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 25 Feb 2022 06:15:16 +0100 Subject: [PATCH 104/314] [#201] as-z80: tests --- .../as-z80/src/main/antlr/AsZ80Lexer.tokens | 4 +- .../as-z80/src/main/antlr/AsZ80Parser.g4 | 2 +- .../plugins/compiler/asZ80/Utils.java | 38 +++- .../compiler/asZ80/parser/ParseInstrTest.java | 184 ++++++++++++++---- 4 files changed, 177 insertions(+), 51 deletions(-) diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens index c13ba3a09..874ad1b1b 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens @@ -77,13 +77,13 @@ COND_P=76 COND_PE=77 COND_PO=78 COND_WS=79 -COND_UNRECOGNIZED=80 +ERROR_COND=80 IM_01=81 IM_0=82 IM_1=83 IM_2=84 IM_WS=85 -IM_UNRECOGNIZED=86 +ERROR_IM=86 PREP_ORG=87 PREP_EQU=88 PREP_VAR=89 diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 index dd6a2e721..3ae64c890 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 @@ -88,10 +88,10 @@ rInstruction: | opcode=OPCODE_RES n=rExpression SEP_COMMA r=rRegister # instrCB_N_R | opcode=OPCODE_SET n=rExpression SEP_COMMA r=rRegister # instrCB_N_R + | opcode=OPCODE_LD ii=rII SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrXD_II_Ref_NN // must be above plain nn | opcode=OPCODE_LD ii=rII SEP_COMMA nn=rExpression # instrXD_II_NN | opcode=OPCODE_ADD ii=rII SEP_COMMA rp=(REG_BC|REG_DE|REG_IX|REG_IY|REG_SP) # instrXD_II_RP | opcode=OPCODE_LD SEP_LPAR nn=rExpression SEP_RPAR SEP_COMMA ii=rII # instrXD_Ref_NN_II - | opcode=OPCODE_LD ii=rII SEP_COMMA SEP_LPAR nn=rExpression SEP_RPAR # instrXD_II_Ref_NN | opcode=OPCODE_LD ii=rII_HL SEP_COMMA n=rExpression # instrXD_IIHL_N | opcode=OPCODE_LD d=rDisplacement SEP_COMMA n=rExpression # instrXD_Ref_II_N_N diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java index 82dce4fba..f7f09bb95 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java @@ -58,6 +58,18 @@ public class Utils { "srl", OPCODE_SRL ); + public static Map prefixReg = Map.of( + "IX", REG_IX, + "IY", REG_IY + ); + + public static Map prefixReg8 = Map.of( + "IXH", REG_IXH, + "IYH", REG_IYH, + "IXL", REG_IXL, + "IYL", REG_IYL + ); + public static List getTokens(String variation) { AsZ80Lexer lexer = new AsZ80Lexer(CharStreams.fromString(variation)); CommonTokenStream stream = new CommonTokenStream(lexer); @@ -123,19 +135,31 @@ public static void forStringCaseVariations(String base, Consumer f) { } public static void forRegister(Consumer> f) { - for (Map.Entry register : registers.entrySet()) { - f.accept(Pair.of(register.getKey(), register.getValue())); - } + forX(f, registers); } public static void forRot(Consumer> f) { - for (Map.Entry rot : rot.entrySet()) { - f.accept(Pair.of(rot.getKey(), rot.getValue())); - } + forX(f, rot); } public static void forRegPair(Consumer> f) { - for (Map.Entry regPair : regPairs.entrySet()) { + forX(f, regPairs); + } + + public static void forRegPair2(Consumer> f) { + forX(f, regPairs2); + } + + public static void forPrefixReg(Consumer> f) { + forX(f, prefixReg); + } + + public static void forPrefixReg8(Consumer> f) { + forX(f, prefixReg8); + } + + public static void forX(Consumer> f, Map x) { + for (Map.Entry regPair : x.entrySet()) { f.accept(Pair.of(regPair.getKey(), regPair.getValue())); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java index 34dbb3d42..c8a12d1f3 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java @@ -6,10 +6,7 @@ import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprCurrentAddress; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; -import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrCB; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrED; -import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrXDCB; +import net.emustudio.plugins.compiler.asZ80.ast.instr.*; import org.junit.Test; import java.util.Random; @@ -95,14 +92,14 @@ public void testInstrReg() { assertInstr("or " + regValue.l, OPCODE_OR, 2, 6, r); assertInstr("cp " + regValue.l, OPCODE_CP, 2, 7, r); - assertInstrCBNoArgs("rlc " + regValue.l, OPCODE_RLC, 0, r); - assertInstrCBNoArgs("rrc " + regValue.l, OPCODE_RRC, 1, r); - assertInstrCBNoArgs("rl " + regValue.l, OPCODE_RL, 2, r); - assertInstrCBNoArgs("rr " + regValue.l, OPCODE_RR, 3, r); - assertInstrCBNoArgs("sla " + regValue.l, OPCODE_SLA, 4, r); - assertInstrCBNoArgs("sra " + regValue.l, OPCODE_SRA, 5, r); - assertInstrCBNoArgs("sll " + regValue.l, OPCODE_SLL, 6, r); - assertInstrCBNoArgs("srl " + regValue.l, OPCODE_SRL, 7, r); + assertInstrCB("rlc " + regValue.l, OPCODE_RLC, 0, r); + assertInstrCB("rrc " + regValue.l, OPCODE_RRC, 1, r); + assertInstrCB("rl " + regValue.l, OPCODE_RL, 2, r); + assertInstrCB("rr " + regValue.l, OPCODE_RR, 3, r); + assertInstrCB("sla " + regValue.l, OPCODE_SLA, 4, r); + assertInstrCB("sra " + regValue.l, OPCODE_SRA, 5, r); + assertInstrCB("sll " + regValue.l, OPCODE_SLL, 6, r); + assertInstrCB("srl " + regValue.l, OPCODE_SRL, 7, r); int bit = Math.abs(random.nextInt() % 8); assertInstrCBExprBit("bit " + bit + ", " + regValue.l, OPCODE_BIT, bit, r); @@ -134,12 +131,21 @@ public void testInstrRP() { assertInstrED("adc hl, " + regPair.l, OPCODE_ADC, (rp << 1) | 1, 2); if (rp != 2) { // HL - assertInstrEDExpr("ld (", "), " + regPair.l, OPCODE_LD, rp << 1, 3); - assertInstrEDExpr("ld " + regPair.l + ", (", ")", OPCODE_LD, (rp << 1) | 1, 3); + assertInstrEDExpr("ld (", "), " + regPair.l, rp << 1); + assertInstrEDExpr("ld " + regPair.l + ", (", ")", (rp << 1) | 1); } }); } + @Test + public void testInstrRP2() { + forRegPair2(regPair2 -> { + int rp = CompilerTables.regPairs2.get(regPair2.r); + assertInstr("pop " + regPair2.l, OPCODE_POP, 3, rp, 0, 1); + assertInstr("push " + regPair2.l, OPCODE_PUSH, 3, rp, 0, 5); + }); + } + @Test public void testInstrExpr() { assertInstrExpr("ld (", "), hl", OPCODE_LD, 0, 4, 2); @@ -198,6 +204,70 @@ public void testInstrXDCB() { assertInstrXDCBExprBit("set " + y + ", (iy + ", ")", OPCODE_SET, 0xFD, y, 6); } + @Test + public void testInstrXD() { + forPrefixReg(ii -> { + int prefix = CompilerTables.prefix.get(ii.r); + forRegPair(regPair -> { + int rp = CompilerTables.regPairs.get(regPair.r); + if (regPair.r == 2) { + assertInstrXD("add " + ii.l + ", " + ii.l, OPCODE_ADD, prefix, 0, rp, 1, 1); + } + }); + + forRegister(register -> { + int r = CompilerTables.registers.get(register.r); + if (r != 6) { + assertInstrXDExpr("ld (" + ii.l + " +", "), " + register.l, OPCODE_LD, prefix, 1, 6, r); + assertInstrXDExpr("ld " + register.l + ", (" + ii.l + " +", ")", OPCODE_LD, prefix, 1, r, 6); + } + }); + + assertInstrXDExpr("ld " + ii.l + ", ", "", OPCODE_LD, prefix, 0, 4, 1); + assertInstrXDExpr("ld (", "), " + ii.l, OPCODE_LD, prefix, 0, 4, 2); + assertInstrXDExpr("inc (" + ii.l + "+", ")", OPCODE_INC, prefix, 0, 6, 4); + assertInstrXDExpr("dec (" + ii.l + "+", ")", OPCODE_DEC, prefix, 0, 6, 5); + assertInstrXD("inc " + ii.l, OPCODE_INC, prefix, 0, 4, 3); + assertInstrXDExpr("ld " + ii.l + ", (", ")", OPCODE_LD, prefix, 0, 5, 2); + assertInstrXD("dec " + ii.l, OPCODE_DEC, prefix, 0, 5, 3); + assertInstrXD("pop " + ii.l, OPCODE_POP, prefix, 3, 4, 1); + assertInstrXD("push " + ii.l, OPCODE_PUSH, prefix, 3, 4, 5); + assertInstrXD("ex (sp), " + ii.l, OPCODE_EX, prefix, 3, 4, 3); + assertInstrXD("jp (" + ii.l + ")", OPCODE_JP, prefix, 3, 5, 1); + assertInstrXD("ld sp, " + ii.l, OPCODE_LD, prefix, 3, 7, 1); + assertInstrXDExprExpr("ld (" + ii.l + "+", prefix); + }); + + forPrefixReg8(ii -> { + int prefix = CompilerTables.prefix.get(ii.r); + int r = CompilerTables.registers.get(ii.r); + + assertInstrXD("inc " + ii.l, OPCODE_INC, prefix, 0, r, 4); + assertInstrXD("dec " + ii.l, OPCODE_DEC, prefix, 0, r, 5); + assertInstrXDExpr("ld " + ii.l + ", ", "", OPCODE_LD, prefix, 0, r, 6); + + assertInstrXD("add a, " + ii.l, OPCODE_ADD, prefix, 2, 0, r); + assertInstrXD("adc a, " + ii.l, OPCODE_ADC, prefix, 2, 1, r); + assertInstrXD("sub " + ii.l, OPCODE_SUB, prefix, 2, 2, r); + assertInstrXD("sbc a, " + ii.l, OPCODE_SBC, prefix, 2, 3, r); + assertInstrXD("and " + ii.l, OPCODE_AND, prefix, 2, 4, r); + assertInstrXD("xor " + ii.l, OPCODE_XOR, prefix, 2, 5, r); + assertInstrXD("or " + ii.l, OPCODE_OR, prefix, 2, 6, r); + assertInstrXD("cp " + ii.l, OPCODE_CP, prefix, 2, 7, r); + + forRegister(register -> { + int r2 = CompilerTables.registers.get(register.r); + String r2s = (register.r == REG_H) ? (prefix == 0xDD ? "ixh" : "iyh") : ((register.r == REG_L) ? (prefix == 0xDD ? "ixl" : "iyl") : register.l); + + if (r2 != 6) { + assertInstrXD("ld " + ii.l + ", " + r2s, OPCODE_LD, prefix, 1, r, r2); + assertInstrXD("ld " + r2s + ", " + ii.l, OPCODE_LD, prefix, 1, r2, r); + } + }); + + }); + } + private void assertInstr(String instr, int instrType, int x, int y, int z) { forStringCaseVariations(instr, variation -> { @@ -217,20 +287,18 @@ private void assertInstrED(String instr, int instrType, int y, int z) { }); } - private void assertInstrEDExpr(String instrPrefix, String instrPostfix, int instrType, int y, int z) { + private void assertInstrEDExpr(String instrPrefix, String instrPostfix, int y) { Node expr = new ExprInfix(0, 0, OP_ADD) .addChild(new ExprCurrentAddress(0, 0)) .addChild(new ExprNumber(0, 0, 5)); - forStringCaseVariations(instrPrefix, prefixVariation -> { - forStringCaseVariations(instrPostfix, postfixVariation -> { - Program program = parseProgram(prefixVariation + " $ + 5" + postfixVariation); - assertTrees(new Program().addChild(new InstrED(0, 0, instrType, y, z).addChild(expr)), program); - }); - }); + forStringCaseVariations(instrPrefix, prefixVariation -> forStringCaseVariations(instrPostfix, postfixVariation -> { + Program program = parseProgram(prefixVariation + " $ + 5" + postfixVariation); + assertTrees(new Program().addChild(new InstrED(0, 0, OPCODE_LD, y, 3).addChild(expr)), program); + })); } - private void assertInstrCBNoArgs(String instr, int instrType, int y, int z) { + private void assertInstrCB(String instr, int instrType, int y, int z) { forStringCaseVariations(instr, variation -> { Program program = parseProgram(variation); assertTrees(new Program().addChild(new InstrCB(0, 0, instrType, y, z)), program); @@ -242,12 +310,10 @@ private void assertInstrExpr(String instrPrefix, String instrPostfix, int instrT .addChild(new ExprCurrentAddress(0, 0)) .addChild(new ExprNumber(0, 0, 5)); - forStringCaseVariations(instrPrefix, prefixVariation -> { - forStringCaseVariations(instrPostfix, postfixVariation -> { - Program program = parseProgram(prefixVariation + " $ + 5" + postfixVariation); - assertTrees(new Program().addChild(new Instr(0, 0, instrType, x, y, z).addChild(expr)), program); - }); - }); + forStringCaseVariations(instrPrefix, prefixVariation -> forStringCaseVariations(instrPostfix, postfixVariation -> { + Program program = parseProgram(prefixVariation + " $ + 5" + postfixVariation); + assertTrees(new Program().addChild(new Instr(0, 0, instrType, x, y, z).addChild(expr)), program); + })); } private void assertInstrExpr(String instr, int instrType, int x, int y, int z) { @@ -272,12 +338,10 @@ private void assertInstrXDCBExpr(String instrPrefix, String instrPostfix, int in .addChild(new ExprCurrentAddress(0, 0)) .addChild(new ExprNumber(0, 0, 5)); - forStringCaseVariations(instrPrefix, instrPrefixVariation -> { - forStringCaseVariations(instrPostfix, instrPostfixVariation -> { - Program program = parseProgram(instrPrefixVariation + " $ + 5" + instrPostfixVariation); - assertTrees(new Program().addChild(new InstrXDCB(0, 0, instrType, prefix, y, z).addChild(expr)), program); - }); - }); + forStringCaseVariations(instrPrefix, instrPrefixVariation -> forStringCaseVariations(instrPostfix, instrPostfixVariation -> { + Program program = parseProgram(instrPrefixVariation + " $ + 5" + instrPostfixVariation); + assertTrees(new Program().addChild(new InstrXDCB(0, 0, instrType, prefix, y, z).addChild(expr)), program); + })); } private void assertInstrXDCBExprBit(String instrPrefix, String instrPostfix, int instrType, int prefix, int y, int z) { @@ -287,14 +351,52 @@ private void assertInstrXDCBExprBit(String instrPrefix, String instrPostfix, int Node yExpr = new ExprNumber(0, 0, y); - forStringCaseVariations(instrPrefix, instrPrefixVariation -> { - forStringCaseVariations(instrPostfix, instrPostfixVariation -> { - Program program = parseProgram(instrPrefixVariation + " $ + 5" + instrPostfixVariation); - assertTrees(new Program() - .addChild(new InstrXDCB(0, 0, instrType, prefix, 0, z) - .addChild(expr) - .addChild(yExpr)), program); + forStringCaseVariations(instrPrefix, instrPrefixVariation -> forStringCaseVariations(instrPostfix, instrPostfixVariation -> { + Program program = parseProgram(instrPrefixVariation + " $ + 5" + instrPostfixVariation); + assertTrees(new Program() + .addChild(new InstrXDCB(0, 0, instrType, prefix, 0, z) + .addChild(expr) + .addChild(yExpr)), program); + })); + } + + private void assertInstrXD(String instr, int instrType, int prefix, int x, int y, int z) { + forStringCaseVariations(instr, variation -> { + Program program = parseProgram(variation); + assertTrees(new Program().addChild(new InstrXD(0, 0, instrType, prefix, x, y, z)), program); + }); + } + + private void assertInstrXD(String instr, int instrType, int prefix, int x, int p, int q, int z) { + assertInstrXD(instr, instrType, prefix, x, (p << 1) | q, z); + } + + private void assertInstrXDExpr(String instrPrefix, String instrPostfix, int instrType, int prefix, int x, int y, int z) { + Node expr = new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); + + forStringCaseVariations(instrPrefix, prefixVariation -> { + forStringCaseVariations(instrPostfix, postfixVariation -> { + Program program = parseProgram(prefixVariation + " $ + 5" + postfixVariation); + assertTrees(new Program().addChild(new InstrXD(0, 0, instrType, prefix, x, y, z).addChild(expr)), program); }); }); } + + private void assertInstrXDExprExpr(String instrPrefix, int prefix) { + Node disp = new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); + + Node expr = new ExprNumber(0, 0, 5); + + forStringCaseVariations(instrPrefix, prefixVariation -> { + Program program = parseProgram(prefixVariation + " $ + 5), 5"); + assertTrees(new Program() + .addChild(new InstrXD(0, 0, OPCODE_LD, prefix, 0, 6, 6) + .addChild(disp) + .addChild(expr)), program); + }); + } } From 3e357fb52fb59887291807ff4b94b2dbdf4f5485 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 25 Feb 2022 06:49:23 +0100 Subject: [PATCH 105/314] [#201] as-z80: tests --- .../plugins/compiler/asZ80/AssemblerZ80.java | 1 + .../plugins/compiler/asZ80/ast/Node.java | 4 +- .../compiler/asZ80/ast/instr/Instr.java | 27 +++----- .../compiler/asZ80/ast/instr/InstrCB.java | 6 +- .../compiler/asZ80/ast/instr/InstrXDCB.java | 9 ++- .../visitors/CollectExprsInOpcodeVisitor.java | 65 +++++++++++++++++++ .../asZ80/visitors/CreateInstrVisitor.java | 4 +- .../asZ80/visitors/GenerateCodeVisitor.java | 6 +- .../visitors/CheckExprSizesVisitorTest.java | 9 +-- .../visitors/EvaluateExprVisitorTest.java | 2 + .../visitors/ExpandIncludesVisitorTest.java | 4 +- 11 files changed, 100 insertions(+), 37 deletions(-) create mode 100644 plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java index 595332b5e..35c338e6c 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java @@ -131,6 +131,7 @@ public boolean compile(String inputFileName, String outputFileName) { new CheckDeclarationsVisitor(), new EvaluateExprVisitor(), new CheckExprSizesVisitor(), + new CollectExprsInOpcodeVisitor(), new GenerateCodeVisitor(hex) }; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java index b46025afd..c25d0bd53 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java @@ -13,8 +13,8 @@ public abstract class Node { public final int column; private int address; - private Optional maxValue; - private Optional sizeBytes; + private Optional maxValue = Optional.empty(); + private Optional sizeBytes = Optional.empty(); public Node(int line, int column) { this.line = line; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java index f392e0b04..033bf23e9 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java @@ -1,23 +1,14 @@ package net.emustudio.plugins.compiler.asZ80.ast.instr; -import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; import net.emustudio.plugins.compiler.asZ80.ast.Node; import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; import org.antlr.v4.runtime.Token; -import java.util.Optional; -import java.util.Set; - -import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.OPCODE_RST; - public class Instr extends Node { public final int opcode; public final int x; - public final int y; + private int y; public final int z; - private final static Set allowedRstValues = Set.of( - 0, 0x8, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38 - ); public Instr(int line, int column, int opcode, int x, int y, int z) { super(line, column); @@ -37,15 +28,13 @@ public Instr(Token opcode, int x, int q, int p, int z) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), x, (p << 1) | q, z); } - public Optional eval() { - Optional actualY = Optional.of(y); - if (opcode == OPCODE_RST) { - actualY = collectChild(Evaluated.class) - .map(e -> e.value) - .filter(allowedRstValues::contains) - .map(v -> v / 8); - } - return actualY.map(yy -> (byte)(((x << 6) | (yy << 3) | (z & 7)) & 0xFF)); + public void setY(int y) { + // for RST + this.y = y; + } + + public byte eval() { + return (byte)(((x << 6) | (y << 3) | (z & 7)) & 0xFF); } @Override diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java index b938b3990..0f1c0f238 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java @@ -12,7 +12,7 @@ public class InstrCB extends Node { public final int opcode; public final int x; - public final int y; + private int y; public final int z; private static final Map xmap = new HashMap<>(); @@ -44,6 +44,10 @@ public InstrCB(Token opcode, int y, int z) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), y, z); } + public void setY(int bit) { + this.y = bit; + } + public byte[] eval() { return new byte[] { (byte)0xCB, diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java index 628dce54f..5945667d4 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java @@ -15,7 +15,7 @@ public class InstrXDCB extends Node { public final int opcode; public final int x; - public final int y; + private int y; public final int z; public final int prefix; @@ -43,7 +43,8 @@ public InstrXDCB(int line, int column, int opcode, int prefix, int y, int z) { this.y = y; this.z = z; - // 1. child is expr (II + d) + // 1. child is BIT number in case of (BIT, SET, RES) + // otherwise it's (II + d) // 2. possibly another expr child } @@ -51,6 +52,10 @@ public InstrXDCB(Token opcode, int prefix, int y, int z) { this(opcode.getLine(), opcode.getCharPositionInLine(), opcode.getType(), prefix, y, z); } + public void setY(int y) { + this.y = y; + } + public byte[] eval() { return new byte[] { (byte)prefix, diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java new file mode 100644 index 000000000..b092cab6d --- /dev/null +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java @@ -0,0 +1,65 @@ +package net.emustudio.plugins.compiler.asZ80.visitors; + +import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; +import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrCB; +import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrXDCB; + +import java.util.Set; + +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; + +public class CollectExprsInOpcodeVisitor extends NodeVisitor { + private final static Set allowedRstValues = Set.of( + 0, 0x8, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38 + ); + + @Override + public void visit(Instr node) { + if (node.opcode == OPCODE_RST) { + node + .collectChild(Evaluated.class) + .map(e -> { + e.remove(); + return e.value; + }) + .filter(allowedRstValues::contains) + .map(v -> v / 8) + .ifPresent(node::setY); + } + } + + @Override + public void visit(InstrCB node) { + // SET, RES, BIT + switch (node.opcode) { + case OPCODE_SET: + case OPCODE_RES: + case OPCODE_BIT: + node + .collectChild(Evaluated.class) + .map(e -> { + e.remove(); + return e.value; + }) + .ifPresent(node::setY); + } + } + + @Override + public void visit(InstrXDCB node) { + // SET, RES, BIT + switch (node.opcode) { + case OPCODE_SET: + case OPCODE_RES: + case OPCODE_BIT: + node + .collectChild(Evaluated.class) + .map(e -> { + e.remove(); + return e.value; + }) + .ifPresent(node::setY); + } + } +} diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java index d104899ae..3f3775817 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java @@ -55,8 +55,8 @@ public Node visitInstrXDCB_N(InstrXDCB_NContext ctx) { // | opcode=OPCODE_SET n=rExpression SEP_COMMA d=rDisplacement # instrXDCB_N int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); Node instr = new InstrXDCB(ctx.opcode, prefix, 0, 6).setSizeBytes(4); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); instr.addChild(CreateVisitors.expr.visit(ctx.n).setMaxValue(7)); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); return instr; } @@ -67,8 +67,8 @@ public Node visitInstrXDCB_N_R(InstrXDCB_N_RContext ctx) { int prefix = CompilerTables.prefix.get(ctx.d.ii.start.getType()); int z = CompilerTables.registers.get(ctx.r.start.getType()); Node instr = new InstrXDCB(ctx.opcode, prefix, 0, z).setSizeBytes(4); - instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); instr.addChild(CreateVisitors.expr.visit(ctx.n).setMaxValue(7)); + instr.addChild(CreateVisitors.expr.visit(ctx.d.n).setSizeBytes(1)); return instr; } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java index 122abc4fd..eb94e5d31 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java @@ -11,7 +11,6 @@ import java.util.Objects; import static net.emustudio.plugins.compiler.asZ80.CompileError.valueMustBePositive; -import static net.emustudio.plugins.compiler.asZ80.CompileError.valueOutOfBounds; public class GenerateCodeVisitor extends NodeVisitor { private final IntelHEX hex; @@ -49,10 +48,7 @@ public void visit(DataDS node) { @Override public void visit(Instr node) { - node.eval().ifPresentOrElse( - hex::add, - () -> error(valueOutOfBounds(node, 0, 7)) - ); + hex.add(node.eval()); int instrSize = node.getSizeBytes().orElse(1); if (instrSize > 1) { expectedBytes = 0; diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java index 6eaaa5122..9463b926f 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java @@ -14,6 +14,7 @@ import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; import static net.emustudio.plugins.compiler.asZ80.CompileError.ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED; +import static net.emustudio.plugins.compiler.asZ80.CompileError.ERROR_VALUE_OUT_OF_BOUNDS; import static net.emustudio.plugins.compiler.asZ80.Utils.assertTrees; import static org.junit.Assert.assertTrue; @@ -109,7 +110,7 @@ public void testInstrExprTwoBytes() { CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); - assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + assertTrue(program.env().hasError(ERROR_VALUE_OUT_OF_BOUNDS)); } @Test @@ -122,7 +123,7 @@ public void testInstrExprThreeBytes() { CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); - assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + assertTrue(program.env().hasError(ERROR_VALUE_OUT_OF_BOUNDS)); } @Test @@ -148,7 +149,7 @@ public void testInstrRegExprTwoBytes() { CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); - assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + assertTrue(program.env().hasError(ERROR_VALUE_OUT_OF_BOUNDS)); } @Test @@ -174,7 +175,7 @@ public void testInstrRegPairExprThreeBytes() { CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); - assertTrue(program.env().hasError(ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED)); + assertTrue(program.env().hasError(ERROR_VALUE_OUT_OF_BOUNDS)); } @Test diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java index aa8a41abc..202acd094 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java @@ -182,6 +182,7 @@ public void testEvaluateIFwithForwardConst() { Program program = new Program(); program .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) + .setSizeBytes(2) .addChild(new ExprId(0, 0, "const"))) .addChild(new PseudoIf(0, 0) .addChild(new PseudoIfExpression(0, 0) @@ -189,6 +190,7 @@ public void testEvaluateIFwithForwardConst() { .addChild(new ExprCurrentAddress(0, 0)) .addChild(new ExprNumber(0, 0, 2)))) .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) + .setSizeBytes(1) .addChild(new ExprNumber(0, 0, 0)))) .addChild(new PseudoEqu(0, 0, "const") .addChild(new ExprInfix(0, 0, OP_ADD) diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java index 140223109..786f7d8ac 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java @@ -25,7 +25,7 @@ public class ExpandIncludesVisitorTest { @Test public void testExpandInclude() { String filename = ExpandIncludesVisitorTest.class.getResource("/sample.asm").getFile(); - Program program = parseProgram("cmc\ninclude '" + filename + "'"); + Program program = parseProgram("ccf\ninclude '" + filename + "'"); ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); visitor.visit(program); @@ -42,7 +42,7 @@ public void testExpandInclude() { @Test public void testExpandIncludeTwoTimes() throws IOException { File file = folder.newFile("file-a.asm"); - write(file, "rrc"); + write(file, "rrca"); Program program = parseProgram( "include '" + file.getPath() + "'\n" + From e64e9ce9ca9b53b636dfc21f62e1a870c3e96747 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 25 Feb 2022 09:25:00 +0100 Subject: [PATCH 106/314] [#201] as-z80: finish tests --- .../as-z80/src/main/antlr/AsZ80Lexer.g4 | 2 +- .../plugins/compiler/asZ80/CompileError.java | 17 ++++++++++++ .../plugins/compiler/asZ80/ast/Node.java | 9 ++++++- .../visitors/CollectExprsInOpcodeVisitor.java | 11 +++++++- .../compiler/asZ80/e2e/AssemblerZ80Test.java | 2 +- .../asZ80/e2e/ConstantsAndVariablesTest.java | 4 +-- .../plugins/compiler/asZ80/e2e/DataTest.java | 2 +- .../compiler/asZ80/e2e/InstrRegTest.java | 8 +++--- .../compiler/asZ80/parser/ParseInstrTest.java | 4 +-- .../visitors/GenerateCodeVisitorTest.java | 27 +++++++++++-------- 10 files changed, 62 insertions(+), 24 deletions(-) diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 index d2089fa3d..7958411bf 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 @@ -110,7 +110,7 @@ COND_P: P -> popMode; COND_PE: P E -> popMode; COND_PO: P O -> popMode; COND_WS: [ \t\f]+ -> skip; -ERROR_COND: ({"cCnNzZmMpP".indexOf((char) _input.LA(1)) == -1}?) -> popMode,skip; +ERROR_COND: () -> popMode,skip; mode IM_NUMBER; IM_01: '0/1' -> popMode; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java index 0cc5c5bca..29b84b8a6 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java @@ -3,7 +3,10 @@ import net.emustudio.plugins.compiler.asZ80.ast.Node; import java.io.IOException; +import java.util.List; import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; public class CompileError { public static final int ERROR_ALREADY_DECLARED = 1; @@ -91,6 +94,20 @@ public static CompileError valueOutOfBounds(Node node, int min, int max) { ); } + public static CompileError valueOutOfBounds(Node node, Set allowedValues) { + List hexaValues = allowedValues + .stream() + .sorted() + .map(Integer::toHexString) + .map(x -> "0x" + x) + .collect(Collectors.toList()); + + return new CompileError( + node, ERROR_VALUE_OUT_OF_BOUNDS, "Value is out of bounds (allowed values=" + hexaValues + ")" + ); + } + + @Override public String toString() { return "CompileError{" + diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java index c25d0bd53..be085a812 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java @@ -111,7 +111,12 @@ public String toString() { private String toString(int indent) { String spaces = new String(new char[indent]).replace("\0", " "); StringBuilder builder = new StringBuilder(spaces); - builder.append(address).append("> ").append(toStringShallow()); + builder + .append(address) + .append("> ") + .append(toStringShallow()) + .append(sizeBytes.map(s -> "(size=" + s + ")").orElse("")); + for (Node child : children) { builder.append("\n").append(child.toString(indent + 2)); } @@ -126,6 +131,7 @@ protected String toStringShallow() { public Node copy() { Node copied = mkCopy(); + maxValue.ifPresent(copied::setMaxValue); for (Node child : children) { copied.addChild(child.copy()); } @@ -141,6 +147,7 @@ public boolean equals(Object o) { public Optional getMaxValue() { return maxValue; } + public Optional getSizeBytes() { return sizeBytes; } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java index b092cab6d..ffe27c91d 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java @@ -1,13 +1,16 @@ package net.emustudio.plugins.compiler.asZ80.visitors; +import net.emustudio.plugins.compiler.asZ80.CompileError; import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrCB; import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrXDCB; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoVar; import java.util.Set; import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import static net.emustudio.plugins.compiler.asZ80.CompileError.valueOutOfBounds; public class CollectExprsInOpcodeVisitor extends NodeVisitor { private final static Set allowedRstValues = Set.of( @@ -25,7 +28,7 @@ public void visit(Instr node) { }) .filter(allowedRstValues::contains) .map(v -> v / 8) - .ifPresent(node::setY); + .ifPresentOrElse(node::setY, () -> error(valueOutOfBounds(node, allowedRstValues))); } } @@ -62,4 +65,10 @@ public void visit(InstrXDCB node) { .ifPresent(node::setY); } } + + @Override + public void visit(PseudoVar node) { + // remove useless VAR node before it gets evaluated in code generator... + node.remove(); + } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java index 10d216987..47e62a52d 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java @@ -94,7 +94,7 @@ public void testCallForward() throws Exception { @Test(expected = Exception.class) public void testRSTtooBigArgument() throws Exception { - compile("rst 10"); + compile("rst 14"); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/ConstantsAndVariablesTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/ConstantsAndVariablesTest.java index 071b92d16..c10700a36 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/ConstantsAndVariablesTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/ConstantsAndVariablesTest.java @@ -74,7 +74,7 @@ public void testTwoSameConstantsDoNotWork() throws Exception { @Test public void testVariableCanBeOverwritten() throws Exception { compile( - "here set 0\nhere set 1\ncp here" + "here var 0\nhere var 1\ncp here" ); assertProgram( 0xFE, 1 @@ -84,7 +84,7 @@ public void testVariableCanBeOverwritten() throws Exception { @Test(expected = Exception.class) public void testCannotSetVariableBecauseIdentifierIsAlreadyDefined() throws Exception { compile( - "here equ 0\nhere set 1\n" + "here equ 0\nhere var 1\n" ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java index 7b372b958..bfe096b17 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java @@ -69,7 +69,7 @@ public void testDBseveralBytesWork() throws Exception { @Test public void testDBWithInstruction() throws Exception { compile( - "db inr A\n" + "db inc A\n" ); assertProgram( diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java index bf2bc0721..75fc5de44 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java @@ -25,7 +25,7 @@ public class InstrRegTest extends AbstractCompilerTest { @Test public void testINR() throws Exception { compile( - "inr A\n" + "inc A\n" + "inc B\n" + "inc C\n" + "inc D\n" @@ -43,7 +43,7 @@ public void testINR() throws Exception { @Test public void testDCR() throws Exception { compile( - "dcr A\n" + "dec A\n" + "dec B\n" + "dec C\n" + "dec D\n" @@ -61,7 +61,7 @@ public void testDCR() throws Exception { @Test public void testADD() throws Exception { compile( - "add A\n" + "add A, A\n" + "add A,B\n" + "add A,C\n" + "add A,D\n" @@ -79,7 +79,7 @@ public void testADD() throws Exception { @Test public void testADC() throws Exception { compile( - "adc A\n" + "adc A, A\n" + "adc A,B\n" + "adc A,C\n" + "adc A,D\n" diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java index c8a12d1f3..45a1d3fec 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java @@ -355,8 +355,8 @@ private void assertInstrXDCBExprBit(String instrPrefix, String instrPostfix, int Program program = parseProgram(instrPrefixVariation + " $ + 5" + instrPostfixVariation); assertTrees(new Program() .addChild(new InstrXDCB(0, 0, instrType, prefix, 0, z) - .addChild(expr) - .addChild(yExpr)), program); + .addChild(yExpr) + .addChild(expr)), program); })); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java index 4326eb559..0b4282b08 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java @@ -32,12 +32,15 @@ public void testCodeGeneration() { .addChild(new Evaluated(0, 0, 5))) .addChild(new PseudoMacroCall(0, 0, "x") .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .addChild(new Evaluated(0, 0, 0xFEAB))) + .setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0xFEAB).setSizeBytes(2))) .addChild(new PseudoMacroCall(0, 0, "y") .addChild(new Instr(0, 0, OPCODE_LD, 0, 2, 1) - .addChild(new Evaluated(0, 0, 1)))) + .setSizeBytes(3) + .addChild(new Evaluated(0, 0, 1).setSizeBytes(2)))) .addChild(new Instr(0, 0, OPCODE_LD, 0, 4, 1) - .addChild(new Evaluated(0, 0, 0x1234)))); + .setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0x1234).setSizeBytes(2)))); IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); @@ -45,7 +48,7 @@ public void testCodeGeneration() { Map code = hex.getCode(); assertEquals((byte) 255, code.get(0).byteValue()); - assertEquals((byte) 0xe7, code.get(1).byteValue()); + assertEquals((byte) 0xc7, code.get(1).byteValue()); assertEquals(1, code.get(2).byteValue()); // dw - lower byte assertEquals(0, code.get(3).byteValue()); // dw - upper byte assertEquals(0, code.get(4).byteValue()); @@ -53,13 +56,13 @@ public void testCodeGeneration() { assertEquals(0, code.get(6).byteValue()); assertEquals(0, code.get(7).byteValue()); assertEquals(0, code.get(8).byteValue()); - assertEquals(1, code.get(9).byteValue()); // lxi b + assertEquals(1, code.get(9).byteValue()); // ld bc assertEquals((byte) 0xAB, code.get(10).byteValue()); assertEquals((byte) 0xFE, code.get(11).byteValue()); - assertEquals(0x11, code.get(12).byteValue()); // lxi d + assertEquals(0x11, code.get(12).byteValue()); // ld de assertEquals(1, code.get(13).byteValue()); assertEquals(0, code.get(14).byteValue()); - assertEquals(0x21, code.get(15).byteValue()); // lxi h + assertEquals(0x21, code.get(15).byteValue()); // ld hl assertEquals(0x34, code.get(16).byteValue()); assertEquals(0x12, code.get(17).byteValue()); } @@ -70,8 +73,9 @@ public void testPseudoOrg() { program .addChild(new PseudoOrg(0, 0) .addChild(new Evaluated(0, 0, 5))) - .addChild(new Instr(0, 0, OPCODE_CALL, 3, 0, 4)) - .addChild(new Evaluated(0, 0, 0x400)) + .addChild(new Instr(0, 0, OPCODE_CALL, 3, 0, 4) + .setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0x400).setSizeBytes(2))) .addChild(new PseudoOrg(0, 0) .addChild(new Evaluated(0, 0, 0))) .addChild(new Instr(0, 0, OPCODE_EX, 3, 5, 3)); @@ -93,7 +97,8 @@ public void testGenerateInstructions() { program .addChild(new Instr(0, 0, OPCODE_NOP, 0, 0, 0)) .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .addChild(new Evaluated(0, 0, 0x1234))) + .setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0x1234).setSizeBytes(2))) .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 2)); // .addChild(new InstrRP(0, 0, OPCODE_INX, REG_B)) // .addChild(new InstrR(0, 0, OPCODE_INR, REG_B)) @@ -394,7 +399,7 @@ public void testGenerateInstructions() { Map code = hex.getCode(); assertEquals(0, code.get(0).byteValue()); // NOP - assertEquals(1, code.get(1).byteValue()); // LXI B,D16 + assertEquals(1, code.get(1).byteValue()); // LD BC,D16 assertEquals(0x34, code.get(2).byteValue()); assertEquals(0x12, code.get(3).byteValue()); assertEquals(2, code.get(4).byteValue()); // STAX B From 7638963f3d70bc462f615bd8fd08d93834aca822 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 26 Feb 2022 10:32:45 +0100 Subject: [PATCH 107/314] [#201] improve gradle test reports + as-8080: fix tests --- build.gradle | 2 + plugins/compiler/as-8080/build.gradle | 8 +- .../as-8080/src/main/antlr/As8080Lexer.g4 | 2 +- .../as-8080/src/main/antlr/As8080Parser.g4 | 2 +- .../as8080/visitors/CreatePseudoVisitor.java | 2 +- .../parser/LexicalAnalyzerImplTest.java | 2 +- .../compiler/as8080/parser/ParseExprTest.java | 77 +++++++++---------- .../CheckDeclarationsVisitorTest.java | 10 +-- plugins/compiler/as-z80/build.gradle | 6 -- test_report.gradle | 72 +++++++++++++++++ 10 files changed, 122 insertions(+), 61 deletions(-) create mode 100644 test_report.gradle diff --git a/build.gradle b/build.gradle index 529c751a2..39c44e195 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,8 @@ import java.text.SimpleDateFormat +apply from: 'test_report.gradle' + ext.versions = [ slf4j: '1.7.30' ] diff --git a/plugins/compiler/as-8080/build.gradle b/plugins/compiler/as-8080/build.gradle index 271eaa783..1a40f32dc 100644 --- a/plugins/compiler/as-8080/build.gradle +++ b/plugins/compiler/as-8080/build.gradle @@ -1,7 +1,7 @@ /* * This file is part of emuStudio. * - * Copyright (C) 2006-2020 Peter Jakubčo + * Copyright (C) 2006-2022 Peter Jakubčo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -93,9 +93,3 @@ copy { from('src/main/scripts') into "$buildDir/libs/scripts" } - -test { - testLogging { - events "passed", "skipped", "failed" - } -} diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 index ea9de972e..87a785e59 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 @@ -112,7 +112,7 @@ OPCODE_HLT: H L T; // preprocessor PREP_ORG: O R G; PREP_EQU: E Q U; -PREP_SET: S E T; +PREP_SET: ((S E T) | (V A R)); PREP_INCLUDE: I N C L U D E; PREP_IF: I F; PREP_ENDIF: E N D I F; diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index e324a0528..6957fef3f 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -153,10 +153,10 @@ rExpression: | expr1=rExpression op=(OP_ADD|OP_SUBTRACT) expr2=rExpression # exprInfix | expr1=rExpression op=(OP_SHL|OP_SHR|OP_SHR_2|OP_SHL_2) expr2=rExpression # exprInfix | expr1=rExpression op=(OP_GT|OP_GTE|OP_LT|OP_LTE) expr2=rExpression # exprInfix + | expr1=rExpression op=OP_EQUAL expr2=rExpression # exprInfix | expr1=rExpression op=(OP_AND|OP_AND_2) expr2=rExpression # exprInfix | expr1=rExpression op=(OP_XOR|OP_XOR_2) expr2=rExpression # exprInfix | expr1=rExpression op=(OP_OR|OP_OR_2) expr2=rExpression # exprInfix - | expr1=rExpression op=OP_EQUAL expr2=rExpression # exprInfix | SEP_LPAR expr=rExpression SEP_RPAR # exprParens | num=LIT_NUMBER # exprDec | num=LIT_HEXNUMBER_1 # exprHex1 diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java index f3bc6a510..941777fb4 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java @@ -26,7 +26,7 @@ public Node visitPseudoEqu(PseudoEquContext ctx) { } @Override - public Node visitPseudoSet(PseudoSetContext ctx) { + public Node visitPseudoVar(PseudoVarContext ctx) { PseudoSet pseudo = new PseudoSet(ctx.id); pseudo.addChild(CreateVisitors.expr.visit(ctx.expr)); return pseudo; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java index b138fa5aa..a7a9d1af0 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java @@ -15,7 +15,7 @@ public void testParseEols() { @Test public void testParseError1() { - assertTokenTypes("B &", REG_B, ERROR, EOF); + assertTokenTypes("B !", REG_B, ERROR, EOF); } @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java index 1535de4e4..2f1b28e7c 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java @@ -80,7 +80,6 @@ public void testAssociativitMulDiv() { @Test public void testPrecedencePlusMinusMulDivMod() { Program program = parseProgram("db 2+3*4-9/2 mod 3"); - System.out.println(program); assertTrees( new Program() .addChild(new DataDB(0, 0) @@ -128,25 +127,25 @@ public void testAndMulXorDivNotPlusMinus() { assertTrees( new Program() .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprInfix(0, 0, OP_OR) - .addChild(new ExprInfix(0, 0, OP_AND) - .addChild(new ExprUnary(0, 0, OP_NOT) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprInfix(0, 0, OP_XOR) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 5)))) - .addChild(new ExprInfix(0, 0, OP_SHR) // shl/shr associates to the right - .addChild(new ExprInfix(0, 0, OP_SHL) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 5))) - .addChild(new ExprNumber(0, 0, 6))) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 4)) - .addChild(new ExprNumber(0, 0, 1)))) - .addChild(new ExprNumber(0, 0, 2))))), + .addChild(new ExprInfix(0, 0, OP_OR) + .addChild(new ExprInfix(0, 0, OP_AND) + .addChild(new ExprUnary(0, 0, OP_NOT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SHR) + .addChild(new ExprInfix(0, 0, OP_SHL) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))))), program ); } @@ -157,25 +156,25 @@ public void testAndMulXorDivNotPlusMinusWithOperators() { assertTrees( new Program() .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprInfix(0, 0, OP_OR_2) - .addChild(new ExprInfix(0, 0, OP_AND_2) - .addChild(new ExprUnary(0, 0, OP_NOT_2) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprInfix(0, 0, OP_XOR_2) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 5)))) - .addChild(new ExprInfix(0, 0, OP_SHR_2) // shl/shr associates to the right - .addChild(new ExprInfix(0, 0, OP_SHL_2) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 5))) - .addChild(new ExprNumber(0, 0, 6))) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 4)) - .addChild(new ExprNumber(0, 0, 1)))) - .addChild(new ExprNumber(0, 0, 2))))), + .addChild(new ExprInfix(0, 0, OP_OR_2) + .addChild(new ExprInfix(0, 0, OP_AND_2) + .addChild(new ExprUnary(0, 0, OP_NOT_2) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR_2) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SHR_2) + .addChild(new ExprInfix(0, 0, OP_SHL_2) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))))), program ); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java index 60ba763a4..3dd7895a9 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitorTest.java @@ -18,14 +18,14 @@ public void testDeclarationsAreFound() { @Test public void testVariableTwoTimesPass() { - Program program = parseProgram("var set 1\nvar set 2"); + Program program = parseProgram("variable set 1\nvariable set 2"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); } @Test public void testConstantTwoTimesCannotBeDefined() { - Program program = parseProgram("var equ 1\nvar equ 2"); + Program program = parseProgram("variable equ 1\nvariable equ 2"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); @@ -33,7 +33,7 @@ public void testConstantTwoTimesCannotBeDefined() { @Test public void testVarCannotBeDefinedIfAnotherDeclarationExists() { - Program program = parseProgram("var equ 1\nvar set 2"); + Program program = parseProgram("variable equ 1\nvariable set 2"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); assertTrue(program.env().hasError(ERROR_ALREADY_DECLARED)); @@ -128,7 +128,7 @@ public void testMacroReuseParameterNamesIsPossible() { @Test public void testIfExpressionReferencesOwnBlockDeclarations() { - Program program = parseProgram("if var + 1\nvar set -1\nendif"); + Program program = parseProgram("if variable + 1\nvariable set -1\nendif"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); assertTrue(program.env().hasError(ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK)); @@ -136,7 +136,7 @@ public void testIfExpressionReferencesOwnBlockDeclarations() { @Test public void testNestedIfExpressionReferencesOwnBlockDeclarations() { - Program program = parseProgram("if var + 1\nif 0\nvar:\nendif\nendif"); + Program program = parseProgram("if variable + 1\nif 0\nvariable:\nendif\nendif"); CheckDeclarationsVisitor visitor = new CheckDeclarationsVisitor(); visitor.visit(program); assertTrue(program.env().hasError(ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK)); diff --git a/plugins/compiler/as-z80/build.gradle b/plugins/compiler/as-z80/build.gradle index af699c704..b9f72a799 100644 --- a/plugins/compiler/as-z80/build.gradle +++ b/plugins/compiler/as-z80/build.gradle @@ -92,9 +92,3 @@ copy { from('src/main/scripts') into "$buildDir/libs/scripts" } - -test { - testLogging { - events "passed", "skipped", "failed" - } -} diff --git a/test_report.gradle b/test_report.gradle new file mode 100644 index 000000000..3ec8263af --- /dev/null +++ b/test_report.gradle @@ -0,0 +1,72 @@ +// Credits go to: https://gist.github.com/lwasyl/f5b2b4ebe9e348ebbd8ee4cb995f8362#file-gradle_tests_report-gradle +// https://medium.com/@wasyl/pretty-tests-summary-in-gradle-744804dd676c + +import groovy.time.TimeCategory +import org.gradle.api.tasks.testing.logging.TestExceptionFormat +import org.gradle.api.tasks.testing.logging.TestLogEvent + +ext.testsResults = [] // Container for tests summaries + +allprojects { project -> + tasks.withType(Test) { testTask -> + + testTask.testLogging { logging -> + events TestLogEvent.FAILED, + TestLogEvent.SKIPPED, + TestLogEvent.STANDARD_OUT, + TestLogEvent.STANDARD_ERROR + + exceptionFormat TestExceptionFormat.FULL + showExceptions true + showCauses true + showStackTraces true + } + + ignoreFailures = true // Always try to run all tests for all modules + + afterSuite { desc, result -> + + if (desc.parent) return // Only summarize results for whole modules + + String summary = "${testTask.project.name}:${testTask.name} results: ${result.resultType} " + + "(" + + "${result.testCount} tests, " + + "${result.successfulTestCount} successes, " + + "${result.failedTestCount} failures, " + + "${result.skippedTestCount} skipped" + + ") " + + "in ${TimeCategory.minus(new Date(result.endTime), new Date(result.startTime))}" + + "\n" + + "Report file: ${testTask.reports.html.entryPoint}" + + // Add reports in `testsResults`, keep failed suites at the end + if (result.resultType == TestResult.ResultType.SUCCESS) { + rootProject.testsResults.add(0, summary) + } else { + rootProject.testsResults += summary + } + } + } +} + +gradle.buildFinished { + def allResults = rootProject.ext.testsResults + + if (!allResults.isEmpty()) { + printResults allResults + } +} + +private static void printResults(allResults) { + def maxLength = allResults*.readLines().flatten().collect { it.length() }.max() + + println "┌${"${"─" * maxLength}"}┐" + + println allResults.collect { + it.readLines().collect { + "│" + it + " " * (maxLength - it.length()) + "│" + }.join("\n") + }.join("\n├${"${"─" * maxLength}"}┤\n") + + println "└${"${"─" * maxLength}"}┘" +} From 7f222d3a780ae00eb0e381f6c3aea1276c6e1bbf Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 26 Feb 2022 10:34:17 +0100 Subject: [PATCH 108/314] [#201] as-ssem: remove test{} in gradle --- plugins/compiler/as-ssem/build.gradle | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/compiler/as-ssem/build.gradle b/plugins/compiler/as-ssem/build.gradle index 5575363ce..7c8f622e2 100644 --- a/plugins/compiler/as-ssem/build.gradle +++ b/plugins/compiler/as-ssem/build.gradle @@ -93,9 +93,3 @@ copy { from('src/main/scripts') into "$buildDir/libs/scripts" } - -test { - testLogging { - events "passed", "skipped", "failed" - } -} From 6c820b5ddbb1f0b36363fb1dec464e3475592890 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 4 Mar 2022 23:10:53 +0000 Subject: [PATCH 109/314] [#201] as-z80: test all instructions --- .../as8080/visitors/ExpandMacrosVisitor.java | 2 +- .../plugins/compiler/asZ80/ast/Node.java | 2 +- .../asZ80/visitors/CreateInstrVisitor.java | 2 +- .../asZ80/visitors/ExpandMacrosVisitor.java | 2 +- .../asZ80/e2e/AbstractCompilerTest.java | 17 +- .../compiler/asZ80/e2e/AssemblerZ80Test.java | 799 +++++++++++++++++- .../visitors/GenerateCodeVisitorTest.java | 625 +------------- 7 files changed, 807 insertions(+), 642 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java index 81515f5aa..3caa19fbc 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java @@ -23,7 +23,7 @@ public class ExpandMacrosVisitor extends NodeVisitor { @Override public void visit(Program node) { - visitChildren(node); + super.visit(node); for (Map.Entry> entry : forwardMacroCalls.entrySet()) { error(notDefined(entry.getValue().get(0), "Macro '" + entry.getKey() + "'")); } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java index be085a812..8feed9653 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java @@ -112,7 +112,7 @@ private String toString(int indent) { String spaces = new String(new char[indent]).replace("\0", " "); StringBuilder builder = new StringBuilder(spaces); builder - .append(address) + .append(Integer.toHexString(address)) .append("> ") .append(toStringShallow()) .append(sizeBytes.map(s -> "(size=" + s + ")").orElse("")); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java index 3f3775817..5615c971e 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java @@ -452,7 +452,7 @@ public Node visitInstrR_N(InstrR_NContext ctx) { @Override public Node visitInstrC_N(InstrC_NContext ctx) { // | opcode=OPCODE_JR c=(COND_NZ|COND_Z|COND_NC|COND_C) SEP_COMMA n=rExpression # instrC_N // x=0, z=0, y=4..7 - int y = CompilerTables.conditions.get(ctx.c.getType()); + int y = CompilerTables.conditions.get(ctx.c.getType()) + 4; Node instr = new Instr(ctx.opcode, 0, y, 0).setSizeBytes(2); instr.addChild(CreateVisitors.expr.visit(ctx.n).setSizeBytes(1)); return instr; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java index 28e3dc7a9..311d8461c 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java @@ -23,7 +23,7 @@ public class ExpandMacrosVisitor extends NodeVisitor { @Override public void visit(Program node) { - visitChildren(node); + super.visit(node); for (Map.Entry> entry : forwardMacroCalls.entrySet()) { error(notDefined(entry.getValue().get(0), "Macro '" + entry.getKey() + "'")); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java index 8ba04aa6b..570e9c4c7 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java @@ -33,6 +33,7 @@ import org.junit.rules.TemporaryFolder; import java.io.File; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardOpenOption; @@ -77,13 +78,17 @@ public void onFinish() { compiler.initialize(); } - protected void compile(String content) throws Exception { - File sourceFile = folder.newFile(); - Files.write(sourceFile.toPath(), content.getBytes(), StandardOpenOption.WRITE); + protected void compile(String content) { + try { + File sourceFile = folder.newFile(); + Files.write(sourceFile.toPath(), content.getBytes(), StandardOpenOption.WRITE); - File outputFile = folder.newFile(); - if (!compiler.compile(sourceFile.getAbsolutePath(), outputFile.getAbsolutePath())) { - throw new Exception("Compilation failed"); + File outputFile = folder.newFile(); + if (!compiler.compile(sourceFile.getAbsolutePath(), outputFile.getAbsolutePath())) { + throw new RuntimeException("Compilation failed"); + } + } catch (IOException e) { + throw new RuntimeException(e); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java index 47e62a52d..26d4f930b 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java @@ -35,7 +35,7 @@ public void testCopyrightIsKnown() { } @Test - public void testForwardAbsoluteJump() throws Exception { + public void testForwardAbsoluteJump() { compile( "now: ld a,b\n" + "cp 'C'\n" + @@ -49,7 +49,7 @@ public void testForwardAbsoluteJump() throws Exception { } @Test - public void testBackwardAbsoluteJump() throws Exception { + public void testBackwardAbsoluteJump() { compile( "now: ld a,b\n" + "cp 'C'\n" + @@ -63,7 +63,7 @@ public void testBackwardAbsoluteJump() throws Exception { } @Test - public void testCallBackward() throws Exception { + public void testCallBackward() { compile( "dec sp\n" + "now: ld a,b\n" + @@ -78,7 +78,7 @@ public void testCallBackward() throws Exception { } @Test - public void testCallForward() throws Exception { + public void testCallForward() { compile( "dec sp\n" + "now: ld a,b\n" + @@ -93,13 +93,13 @@ public void testCallForward() throws Exception { } @Test(expected = Exception.class) - public void testRSTtooBigArgument() throws Exception { + public void testRSTtooBigArgument() { compile("rst 14"); } @Test - public void testDECwithLD() throws Exception { + public void testDECwithLD() { compile( "dec sp\n" + "ld hl, text\n" @@ -113,7 +113,7 @@ public void testDECwithLD() throws Exception { } @Test - public void testINthenJMP() throws Exception { + public void testINthenJMP() { compile( "jp sample\n" + "in a, (10h)\n" @@ -127,7 +127,7 @@ public void testINthenJMP() throws Exception { } @Test - public void testGetChar() throws Exception { + public void testGetChar() { compile( "jp sample\n" + "getchar:\n" @@ -145,4 +145,787 @@ public void testGetChar() throws Exception { 0xC3, 0x0F, 0, 0xDB, 0x10, 0xE6, 1, 0xCA, 0x03, 0, 0xDB, 0x11, 0xD3, 0x11, 0xC9, 0x78 ); } + + @Test + public void testAllInstructions() { + compile( + "nop\n" + + "ex af, af'\n" + + "djnz 20h\n" + + "jr 20h\n" + + "jr nz, 20h\n" // 6 + + "jr z, 20h\n" + + "jr nc, 20h\n" + + "jr c, 20h\n" + + "ld bc, 0x1234\n" + + "ld de, 0x1234\n" + + "ld hl, 0x1234\n" + + "ld sp, 0x1234\n" + + "add hl, bc\n" + + "add hl, de\n" + + "add hl, hl\n" + + "add hl, sp\n" + + "ld (bc), a\n" + + "ld (de), a\n" + + "ld a, (bc)\n" + + "ld a, (de)\n" + + "ld (0x1234), hl\n" // 0x22 + + "ld (0x1234), a\n" + + "ld hl, (0x1234)\n" + + "ld a, (0x1234)\n" + + "inc bc\n" + + "inc de\n" + + "inc hl\n" + + "inc sp\n" + + "dec bc\n" + + "dec de\n" + + "dec hl\n" + + "dec sp\n" + + "inc b\n" + + "inc c\n" + + "inc d\n" + + "inc e\n" + + "inc h\n" + + "inc l\n" + + "inc a\n" + + "dec b\n" + + "dec c\n" + + "dec d\n" + + "dec e\n" + + "dec h\n" + + "dec l\n" + + "dec a\n" + + "ld b, 0x20\n" + + "ld c, 0x20\n" + + "ld d, 0x20\n" + + "ld e, 0x20\n" + + "ld h, 0x20\n" + + "ld l, 0x20\n" + + "rlca\n" + + "rrca\n" + + "rla\n" + + "rra\n" + + "daa\n" + + "cpl\n" + + "scf\n" + + "ccf\n" + + "ld b, b\n" + + "ld b, c\n" + + "ld b, d\n" + + "ld b, e\n" + + "ld b, h\n" + + "ld b, l\n" + + "ld b, a\n" + + "ld (hl), b\n" + + "ld (hl), c\n" + + "ld (hl), d\n" + + "ld (hl), e\n" + + "ld (hl), h\n" + + "ld (hl), l\n" + + "ld (hl), a\n" + + "halt\n" + + "add a, b\n" + + "add a, (hl)\n" + + "adc a, c\n" + + "adc a, (hl)\n" + + "sub b\n" + + "sub (hl)\n" + + "sbc a, b\n" + + "sbc a, (hl)\n" + + "and b\n" + + "and (hl)\n" + + "xor b\n" + + "xor (hl)\n" + + "or b\n" + + "or (hl)\n" + + "cp b\n" + + "cp (hl)\n" + + "ret nz\n" + + "ret z\n" + + "ret nc\n" + + "ret c\n" + + "ret po\n" + + "ret pe\n" + + "ret p\n" + + "ret m\n" + + "pop bc\n" + + "pop de\n" + + "pop hl\n" + + "pop af\n" + + "ret\n" + + "exx\n" + + "jp hl\n" + + "jp (hl)\n" + + "ld sp, hl\n" + + "jp nz, 0x1234\n" + + "jp z, 0x1234\n" + + "jp nc, 0x1234\n" + + "jp c, 0x1234\n" + + "jp po, 0x1234\n" + + "jp pe, 0x1234\n" + + "jp p, 0x1234\n" + + "jp m, 0x1234\n" + + "jp 0x1234\n" + + "out (0x20), a\n" + + "in a, (0x20)\n" + + "ex (sp), hl\n" + + "ex de, hl\n" + + "di\n" + + "ei\n" + + "call nz, 0x1234\n" + + "call z, 0x1234\n" + + "call nc, 0x1234\n" + + "call c, 0x1234\n" + + "call po, 0x1234\n" + + "call pe, 0x1234\n" + + "call p, 0x1234\n" + + "call m, 0x1234\n" + + "push bc\n" + + "push de\n" + + "push hl\n" + + "push af\n" + + "call 0x1234\n" + + "add a, 0x20\n" + + "adc a, 0x20\n" + + "sub 0x20\n" + + "sbc a, 0x20\n" + + "and 0x20\n" + + "xor 0x20\n" + + "or 0x20\n" + + "cp 0x20\n" + + "rst 0\n" + + "rst 8\n" + + "rst 10h\n" + + "rst 18h\n" + + "rst 20h\n" + + "rst 28h\n" + + "rst 30h\n" + + "rst 38h\n" + + "rlc b\n" + + "rlc (HL)\n" + + "rrc c\n" + + "rrc (HL)\n" + + "rl d\n" + + "rl (HL)\n" + + "rr e\n" + + "rr (hl)\n" + + "sla h\n" + + "sla (hl)\n" + + "sra l\n" + + "sra (hl)\n" + + "sll b\n" + + "sll (hl)\n" + + "srl c\n" + + "srl (hl)\n" + + "bit 5, b\n" + + "bit 5, (hl)\n" + + "res 5, c\n" + + "res 6, (hl)\n" + + "set 7, d\n" + + "set 7, (hl)\n" + + "in e, (c)\n" + + "in (c)\n" + + "out (c), h\n" + + "out (c), 0\n" + + "sbc hl, bc\n" + + "sbc hl, de\n" + + "sbc hl, hl\n" + + "sbc hl, sp\n" + + "adc hl, bc\n" + + "adc hl, de\n" + + "adc hl, hl\n" + + "adc hl, sp\n" + + "ld (1234h), bc\n" + + "ld (1234h), de\n" + + "ld (1234h), hl\n" + + "ld (1234h), sp\n" + + "ld bc, (0x1234)\n" + + "ld de, (0x1234)\n" + + "ld hl, (0x1234)\n" + + "ld sp, (0x1234)\n" + + "neg\n" + + "retn\n" + + "reti\n" + + "im 0\n" + + "im 0/1\n" + + "im 1\n" + + "im 2\n" + + "ld i, a\n" + + "ld r, a\n" + + "ld a, i\n" + + "ld a, r\n" + + "rrd\n" + + "rld\n" + + "ldi\n" + + "ldd\n" + + "ldir\n" + + "lddr\n" + + "cpi\n" + + "cpd\n" + + "cpir\n" + + "cpdr\n" + + "ini\n" + + "ind\n" + + "inir\n" + + "indr\n" + + "outi\n" + + "outd\n" + + "otir\n" + + "otdr\n" + + "rlc (ix+0x20), b\n" + + "rlc (iy+0x20), b\n" + + "rlc (ix+0x20)\n" + + "rlc (iy+0x20)\n" + + "rrc (ix+0x20), c\n" + + "rrc (iy+0x20), c\n" + + "rrc (ix+0x20)\n" + + "rrc (iy+0x20)\n" + + "rl (ix+0x20), d\n" + + "rl (iy+0x20), d\n" + + "rl (ix+0x20)\n" + + "rl (iy+0x20)\n" + + "rr (ix+0x20), e\n" + + "rr (iy+0x20), e\n" + + "rr (ix+0x20)\n" + + "rr (iy+0x20)\n" + + "sla (ix+0x20), h\n" + + "sla (iy+0x20), h\n" + + "sla (ix+0x20)\n" + + "sla (iy+0x20)\n" + + "sra (ix+0x20), l\n" + + "sra (iy+0x20), l\n" + + "sra (ix+0x20)\n" + + "sra (iy+0x20)\n" + + "sll (ix+0x20), b\n" + + "sll (iy+0x20), b\n" + + "sll (ix+0x20)\n" + + "sll (iy+0x20)\n" + + "srl (ix+0x20), c\n" + + "srl (iy+0x20), c\n" + + "srl (ix+0x20)\n" + + "srl (iy+0x20)\n" + + "bit 3, (ix+0x20)\n" + + "bit 3, (iy+0x20)\n" + + "res 5, (ix+0x20), b\n" + + "res 5, (iy+0x20), b\n" + + "res 5, (ix+0x20)\n" + + "res 5, (iy+0x20)\n" + + "set 6, (ix+0x20), c\n" + + "set 6, (iy+0x20), c\n" + + "set 6, (ix+0x20)\n" + + "set 6, (iy+0x20)\n" + + "ld ix, 0x1234\n" + + "ld iy, 0x1234\n" + + "add ix, bc\n" + + "add iy, bc\n" + + "add ix, de\n" + + "add iy, de\n" + + "add ix, ix\n" + + "add iy, iy\n" + + "add ix, sp\n" + + "add iy, sp\n" + + "ld (0x1234), ix\n" + + "ld (0x1234), iy\n" + + "ld ix, (0x1234)\n" + + "ld iy, (0x1234)\n" + + "inc ix\n" + + "inc iy\n" + + "dec ix\n" + + "dec iy\n" + + "inc ixh\n" + + "inc iYh\n" + + "inc ixl\n" + + "inc iyl\n" + + "inc (ix+0x20)\n" + + "inc (iy+0x20)\n" + + "dec ixh\n" + + "dec iyh\n" + + "dec ixl\n" + + "dec iyl\n" + + "dec (ix+0x20)\n" + + "dec (iy+0x20)\n" + + "ld ixh, 0x20\n" + + "ld ixl, 0x20\n" + + "ld iyh, 0x20\n" + + "ld iyl, 0x20\n" + + "ld (ix+0x20), 0x20\n" + + "ld (iy+0x20), 0x20\n" + + "ld ixh, b\n" + + "ld ixh, ixh\n" + + "ld ixh, ixl\n" + + "ld iyh, c\n" + + "ld iyh, iyh\n" + + "ld iyh, iyl\n" + + "ld ixl, d\n" + + "ld ixl, ixh\n" + + "ld ixl, ixl\n" + + "ld iyl, e\n" + + "ld iyl, iyh\n" + + "ld iyl, iyl\n" + + "ld (ix+0x20), d\n" + + "ld (ix+0x20), h\n" + + "ld (ix+0x20), l\n" + + "ld (iy+0x20), e\n" + + "ld (iy+0x20), h\n" + + "ld (iy+0x20), l\n" + + "ld a, ixh\n" + + "ld a, iyh\n" + + "ld a, ixl\n" + + "ld a, iyl\n" + + "ld a, (ix+0x20)\n" + + "ld a, (iy+0x20)\n" + + "ld h, (ix+0x20)\n" + + "ld l, (ix+0x20)\n" + + "ld h, (iy+0x20)\n" + + "ld l, (iy+0x20)\n" + + "add a, ixh\n" + + "add a, ixl\n" + + "add a, (ix + 0x20)\n" + + "add a, iyh\n" + + "add a, iyl\n" + + "add a, (iy+0x20)\n" + + "adc a, ixh\n" + + "adc a, ixl\n" + + "adc a, (ix+0x20)\n" + + "adc a, iyh\n" + + "adc a, iyl\n" + + "adc a, (iy+0x20)\n" + + "sub ixh\n" + + "sub ixl\n" + + "sub (ix+0x20)\n" + + "sub iyh\n" + + "sub iyl\n" + + "sub (iy+0x20)\n" + + "sbc a, ixh\n" + + "sbc a, ixl\n" + + "sbc a, (ix+0x20)\n" + + "sbc a, iyh\n" + + "sbc a, iyl\n" + + "sbc a, (iy+0x20)\n" + + "and ixh\n" + + "and ixl\n" + + "and (ix+0x20)\n" + + "and iyh\n" + + "and iyl\n" + + "and (iy+0x20)\n" + + "xor ixh\n" + + "xor ixl\n" + + "xor (ix+0x20)\n" + + "xor iyh\n" + + "xor iyl\n" + + "xor (iy+0x20)\n" + + "or ixh\n" + + "or ixl\n" + + "or (ix+0x20)\n" + + "or iyh\n" + + "or iyl\n" + + "or (iy+0x20)\n" + + "cp ixh\n" + + "cp ixl\n" + + "cp (ix+0x20)\n" + + "cp iyh\n" + + "cp iyl\n" + + "cp (iy+0x20)\n" + + "pop ix\n" + + "pop iy\n" + + "jp (ix)\n" + + "jp (iy)\n" + + "ld sp, ix\n" + + "ld sp, iy\n" + + "ex (sp), ix\n" + + "ex (sp), iy\n" + + "push ix\n" + + "push iy\n" + ); + + assertProgram( + 0x00, + 0x08, + 0x10, 0x20, + 0x18, 0x20, + 0x20, 0x20, + 0x28, 0x20, + 0x30, 0x20, + 0x38, 0x20, + 0x01, 0x34, 0x12, + 0x11, 0x34, 0x12, + 0x21, 0x34, 0x12, + 0x31, 0x34, 0x12, + 0x09, + 0x19, + 0x29, + 0x39, + 0x02, + 0x12, + 0x0A, + 0x1A, + 0x22, 0x34, 0x12, + 0x32, 0x34, 0x12, + 0x2A, 0x34, 0x12, + 0x3A, 0x34, 0x12, + 0x03, + 0x13, + 0x23, + 0x33, + 0x0B, + 0x1B, + 0x2B, + 0x3B, + 0x04, + 0x0C, + 0x14, + 0x1C, + 0x24, + 0x2C, + 0x3C, + 0x05, + 0x0D, + 0x15, + 0x1D, + 0x25, + 0x2D, + 0x3D, + 0x06, 0x20, + 0x0E, 0x20, + 0x16, 0x20, + 0x1E, 0x20, + 0x26, 0x20, + 0x2E, 0x20, + 0x07, + 0x0F, + 0x17, + 0x1F, + 0x27, + 0x2F, + 0x37, + 0x3F, + 0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x47, + 0x70, + 0x71, + 0x72, + 0x73, + 0x74, + 0x75, + 0x77, + 0x76, + 0x80, + 0x86, + 0x89, + 0x8E, + 0x90, + 0x96, + 0x98, + 0x9E, + 0xA0, + 0xA6, + 0xA8, + 0xAE, + 0xB0, + 0xB6, + 0xB8, + 0xBE, + 0xC0, + 0xC8, + 0xD0, + 0xD8, + 0xE0, + 0xE8, + 0xF0, + 0xF8, + 0xC1, + 0xD1, + 0xE1, + 0xF1, + 0xC9, + 0xD9, + 0xE9, + 0xE9, + 0xF9, + 0xC2, 0x34, 0x12, + 0xCA, 0x34, 0x12, + 0xD2, 0x34, 0x12, + 0xDA, 0x34, 0x12, + 0xE2, 0x34, 0x12, + 0xEA, 0x34, 0x12, + 0xF2, 0x34, 0x12, + 0xFA, 0x34, 0x12, + 0xC3, 0x34, 0x12, + 0xD3, 0x20, + 0xDB, 0x20, + 0xE3, + 0xEB, + 0xF3, + 0xFB, + 0xC4, 0x34, 0x12, + 0xCC, 0x34, 0x12, + 0xD4, 0x34, 0x12, + 0xDC, 0x34, 0x12, + 0xE4, 0x34, 0x12, + 0xEC, 0x34, 0x12, + 0xF4, 0x34, 0x12, + 0xFC, 0x34, 0x12, + 0xC5, + 0xD5, + 0xE5, + 0xF5, + 0xCD, 0x34, 0x12, + 0xC6, 0x20, + 0xCE, 0x20, + 0xD6, 0x20, + 0xDE, 0x20, + 0xE6, 0x20, + 0xEE, 0x20, + 0xF6, 0x20, + 0xFE, 0x20, + 0xC7, + 0xCF, + 0xD7, + 0xDF, + 0xE7, + 0xEF, + 0xF7, + 0xFF, + 0xCB, 0x00, + 0xCB, 0x06, + 0xCB, 0x09, + 0xCB, 0x0E, + 0xCB, 0x12, + 0xCB, 0x16, + 0xCB, 0x1B, + 0xCB, 0x1E, + 0xCB, 0x24, + 0xCB, 0x26, + 0xCB, 0x2D, + 0xCB, 0x2E, + 0xCB, 0x30, + 0xCB, 0x36, + 0xCB, 0x39, + 0xCB, 0x3E, + 0xCB, 0x68, + 0xCB, 0x6E, + 0xCB, 0xA9, + 0xCB, 0xB6, + 0xCB, 0xFA, + 0xCB, 0xFE, + 0xED, 0x58, + 0xED, 0x70, + 0xED, 0x61, + 0xED, 0x71, + 0xED, 0x42, + 0xED, 0x52, + 0xED, 0x62, + 0xED, 0x72, + 0xED, 0x4A, + 0xED, 0x5A, + 0xED, 0x6A, + 0xED, 0x7A, + 0xED, 0x43, 0x34, 0x12, + 0xED, 0x53, 0x34, 0x12, + 0x22, 0x34, 0x12, // 0xED, 0x63, 0x34, 0x12 + 0xED, 0x73, 0x34, 0x12, + 0xED, 0x4B, 0x34, 0x12, + 0xED, 0x5B, 0x34, 0x12, + 0x2A, 0x34, 0x12, // 0xED, 0x6B, 0x34, 0x12 + 0xED, 0x7B, 0x34, 0x12, + 0xED, 0x44, + 0xED, 0x45, + 0xED, 0x4D, + 0xED, 0x46, + 0xED, 0x4E, + 0xED, 0x56, + 0xED, 0x5E, + 0xED, 0x47, + 0xED, 0x4F, + 0xED, 0x57, + 0xED, 0x5F, + 0xED, 0x67, + 0xED, 0x6F, + 0xED, 0xA0, + 0xED, 0xA8, + 0xED, 0xB0, + 0xED, 0xB8, + 0xED, 0xA1, + 0xED, 0xA9, + 0xED, 0xB1, + 0xED, 0xB9, + 0xED, 0xA2, + 0xED, 0xAA, + 0xED, 0xB2, + 0xED, 0xBA, + 0xED, 0xA3, + 0xED, 0xAB, + 0xED, 0xB3, + 0xED, 0xBB, + 0xDD, 0xCB, 0x20, 0x00, + 0xFD, 0xCB, 0x20, 0x00, + 0xDD, 0xCB, 0x20, 0x06, + 0xFD, 0xCB, 0x20, 0x06, + 0xDD, 0xCB, 0x20, 0x09, + 0xFD, 0xCB, 0x20, 0x09, + 0xDD, 0xCB, 0x20, 0x0E, + 0xFD, 0xCB, 0x20, 0x0E, + 0xDD, 0xCB, 0x20, 0x12, + 0xFD, 0xCB, 0x20, 0x12, + 0xDD, 0xCB, 0x20, 0x16, + 0xFD, 0xCB, 0x20, 0x16, + 0xDD, 0xCB, 0x20, 0x1B, + 0xFD, 0xCB, 0x20, 0x1B, + 0xDD, 0xCB, 0x20, 0x1E, + 0xFD, 0xCB, 0x20, 0x1E, + 0xDD, 0xCB, 0x20, 0x24, + 0xFD, 0xCB, 0x20, 0x24, + 0xDD, 0xCB, 0x20, 0x26, + 0xFD, 0xCB, 0x20, 0x26, + 0xDD, 0xCB, 0x20, 0x2D, + 0xFD, 0xCB, 0x20, 0x2D, + 0xDD, 0xCB, 0x20, 0x2E, + 0xFD, 0xCB, 0x20, 0x2E, + 0xDD, 0xCB, 0x20, 0x30, + 0xFD, 0xCB, 0x20, 0x30, + 0xDD, 0xCB, 0x20, 0x36, + 0xFD, 0xCB, 0x20, 0x36, + 0xDD, 0xCB, 0x20, 0x39, + 0xFD, 0xCB, 0x20, 0x39, + 0xDD, 0xCB, 0x20, 0x3E, + 0xFD, 0xCB, 0x20, 0x3E, + 0xDD, 0xCB, 0x20, 0x5E, + 0xFD, 0xCB, 0x20, 0x5E, + 0xDD, 0xCB, 0x20, 0xA8, + 0xFD, 0xCB, 0x20, 0xA8, + 0xDD, 0xCB, 0x20, 0xAE, + 0xFD, 0xCB, 0x20, 0xAE, + 0xDD, 0xCB, 0x20, 0xF1, + 0xFD, 0xCB, 0x20, 0xF1, + 0xDD, 0xCB, 0x20, 0xF6, + 0xFD, 0xCB, 0x20, 0xF6, + 0xDD, 0x21, 0x34, 0x12, + 0xFD, 0x21, 0x34, 0x12, + 0xDD, 0x09, + 0xFD, 0x09, + 0xDD, 0x19, + 0xFD, 0x19, + 0xDD, 0x29, + 0xFD, 0x29, + 0xDD, 0x39, + 0xFD, 0x39, + 0xDD, 0x22, 0x34, 0x12, + 0xFD, 0x22, 0x34, 0x12, + 0xDD, 0x2A, 0x34, 0x12, + 0xFD, 0x2A, 0x34, 0x12, + 0xDD, 0x23, + 0xFD, 0x23, + 0xDD, 0x2B, + 0xFD, 0x2B, + 0xDD, 0x24, + 0xFD, 0x24, + 0xDD, 0x2C, + 0xFD, 0x2C, + 0xDD, 0x34, 0x20, + 0xFD, 0x34, 0x20, + 0xDD, 0x25, + 0xFD, 0x25, + 0xDD, 0x2D, + 0xFD, 0x2D, + 0xDD, 0x35, 0x20, + 0xFD, 0x35, 0x20, + 0xDD, 0x26, 0x20, + 0xDD, 0x2E, 0x20, + 0xFD, 0x26, 0x20, + 0xFD, 0x2E, 0x20, + 0xDD, 0x36, 0x20, 0x20, + 0xFD, 0x36, 0x20, 0x20, + 0xDD, 0x60, + 0xDD, 0x64, + 0xDD, 0x65, + 0xFD, 0x61, + 0xFD, 0x64, + 0xFD, 0x65, + 0xDD, 0x6A, + 0xDD, 0x6C, + 0xDD, 0x6D, + 0xFD, 0x6B, + 0xFD, 0x6C, + 0xFD, 0x6D, + 0xDD, 0x72, 0x20, + 0xDD, 0x74, 0x20, + 0xDD, 0x75, 0x20, + 0xFD, 0x73, 0x20, + 0xFD, 0x74, 0x20, + 0xFD, 0x75, 0x20, + 0xDD, 0x7C, + 0xFD, 0x7C, + 0xDD, 0x7D, + 0xFD, 0x7D, + 0xDD, 0x7E, 0x20, + 0xFD, 0x7E, 0x20, + 0xDD, 0x66, 0x20, + 0xDD, 0x6E, 0x20, + 0xFD, 0x66, 0x20, + 0xFD, 0x6E, 0x20, + 0xDD, 0x84, + 0xDD, 0x85, + 0xDD, 0x86, 0x20, + 0xFD, 0x84, + 0xFD, 0x85, + 0xFD, 0x86, 0x20, + 0xDD, 0x8C, + 0xDD, 0x8D, + 0xDD, 0x8E, 0x20, + 0xFD, 0x8C, + 0xFD, 0x8D, + 0xFD, 0x8E, 0x20, + 0xDD, 0x94, + 0xDD, 0x95, + 0xDD, 0x96, 0x20, + 0xFD, 0x94, + 0xFD, 0x95, + 0xFD, 0x96, 0x20, + 0xDD, 0x9C, + 0xDD, 0x9D, + 0xDD, 0x9E, 0x20, + 0xFD, 0x9C, + 0xFD, 0x9D, + 0xFD, 0x9E, 0x20, + 0xDD, 0xA4, + 0xDD, 0xA5, + 0xDD, 0xA6, 0x20, + 0xFD, 0xA4, + 0xFD, 0xA5, + 0xFD, 0xA6, 0x20, + 0xDD, 0xAC, + 0xDD, 0xAD, + 0xDD, 0xAE, 0x20, + 0xFD, 0xAC, + 0xFD, 0xAD, + 0xFD, 0xAE, 0x20, + 0xDD, 0xB4, + 0xDD, 0xB5, + 0xDD, 0xB6, 0x20, + 0xFD, 0xB4, + 0xFD, 0xB5, + 0xFD, 0xB6, 0x20, + 0xDD, 0xBC, + 0xDD, 0xBD, + 0xDD, 0xBE, 0x20, + 0xFD, 0xBC, + 0xFD, 0xBD, + 0xFD, 0xBE, 0x20, + 0xDD, 0xE1, + 0xFD, 0xE1, + 0xDD, 0xE9, + 0xFD, 0xE9, + 0xDD, 0xF9, + 0xFD, 0xF9, + 0xDD, 0xE3, + 0xFD, 0xE3, + 0xDD, 0xE5, + 0xFD, 0xE5 + ); + } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java index 0b4282b08..d43b6a83b 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java @@ -6,7 +6,7 @@ import net.emustudio.plugins.compiler.asZ80.ast.data.DataDB; import net.emustudio.plugins.compiler.asZ80.ast.data.DataDS; import net.emustudio.plugins.compiler.asZ80.ast.data.DataDW; -import net.emustudio.plugins.compiler.asZ80.ast.instr.*; +import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoMacroCall; import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoOrg; import org.junit.Test; @@ -90,627 +90,4 @@ public void testPseudoOrg() { assertEquals(0, code.get(6).byteValue()); assertEquals(4, code.get(7).byteValue()); } - - @Test - public void testGenerateInstructions() { - Program program = new Program(); - program - .addChild(new Instr(0, 0, OPCODE_NOP, 0, 0, 0)) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .setSizeBytes(3) - .addChild(new Evaluated(0, 0, 0x1234).setSizeBytes(2))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 2)); -// .addChild(new InstrRP(0, 0, OPCODE_INX, REG_B)) -// .addChild(new InstrR(0, 0, OPCODE_INR, REG_B)) -// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_B)) -// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_B) -// .addChild(new Evaluated(0, 0, 7))) -// .addChild(new Instr(0, 0, OPCODE_RLC, x, y, z)) -// .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_B)) -// .addChild(new InstrRP(0, 0, OPCODE_LDAX, REG_B)) -// .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_B)) -// .addChild(new InstrR(0, 0, OPCODE_INR, REG_C)) -// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_C)) -// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_C) -// .addChild(new Evaluated(0, 0, 8))) -// .addChild(new Instr(0, 0, OPCODE_RRC, x, y, z)) -// .addChild(new Instr(0, 0, OPCODE_LD, 0, 2, 1) -// .addChild(new Evaluated(0, 0, 0x2345))) -// .addChild(new InstrRP(0, 0, OPCODE_STAX, REG_D)) -// .addChild(new InstrRP(0, 0, OPCODE_INX, REG_D)) -// .addChild(new InstrR(0, 0, OPCODE_INR, REG_D)) -// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_D)) -// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_D) -// .addChild(new Evaluated(0, 0, 9))) -// .addChild(new Instr(0, 0, OPCODE_RAL, x, y, z)) -// .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_D)) -// .addChild(new InstrRP(0, 0, OPCODE_LDAX, REG_D)) -// .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_D)) -// .addChild(new InstrR(0, 0, OPCODE_INR, REG_E)) -// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_E)) -// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_E) -// .addChild(new Evaluated(0, 0, 10))) -// .addChild(new Instr(0, 0, OPCODE_RAR, x, y, z)) -// .addChild(new Instr(0, 0, OPCODE_LD, 0, 4, 1) -// .addChild(new Evaluated(0, 0, 0x2345))) -// .addChild(new InstrN(0, 0, OPCODE_SHLD) -// .addChild(new Evaluated(0, 0, 0x2345))) -// .addChild(new InstrRP(0, 0, OPCODE_INX, REG_H)) -// .addChild(new InstrR(0, 0, OPCODE_INR, REG_H)) -// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_H)) -// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_H) -// .addChild(new Evaluated(0, 0, 0x28))) -// .addChild(new Instr(0, 0, OPCODE_DAA, x, y, z)) -// .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_H)) -// .addChild(new InstrN(0, 0, OPCODE_LHLD) -// .addChild(new Evaluated(0, 0, 0x2345))) -// .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_H)) -// .addChild(new InstrR(0, 0, OPCODE_INR, REG_L)) -// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_L)) -// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_L) -// .addChild(new Evaluated(0, 0, 10))) -// .addChild(new Instr(0, 0, OPCODE_CMA, x, y, z)) -// .addChild(new InstrRP_NN(0, 0, OPCODE_LXI, REG_SP) -// .addChild(new Evaluated(0, 0, 0x2345))) -// .addChild(new InstrN(0, 0, OPCODE_STA) -// .addChild(new Evaluated(0, 0, 0x2345))) -// .addChild(new InstrRP(0, 0, OPCODE_INX, REG_SP)) -// .addChild(new InstrR(0, 0, OPCODE_INR, REG_M)) -// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_M)) -// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_M) -// .addChild(new Evaluated(0, 0, 7))) -// .addChild(new Instr(0, 0, OPCODE_STC, x, y, z)) -// .addChild(new InstrRP(0, 0, OPCODE_DAD, REG_SP)) -// .addChild(new InstrN(0, 0, OPCODE_LDA) -// .addChild(new Evaluated(0, 0, 0x2345))) -// .addChild(new InstrRP(0, 0, OPCODE_DCX, REG_SP)) -// .addChild(new InstrR(0, 0, OPCODE_INR, REG_A)) -// .addChild(new InstrR(0, 0, OPCODE_DCR, REG_A)) -// .addChild(new InstrR_N(0, 0, OPCODE_MVI, REG_A) -// .addChild(new Evaluated(0, 0, -128))) -// .addChild(new Instr(0, 0, OPCODE_CMC, x, y, z)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_B)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_C)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_D)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_E)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_H)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_L)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_M)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_B, REG_A)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_B)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_C)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_D)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_E)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_H)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_L)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_M)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_C, REG_A)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_B)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_C)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_D)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_E)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_H)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_L)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_M)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_D, REG_A)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_B)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_C)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_D)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_E)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_H)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_L)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_M)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_E, REG_A)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_B)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_C)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_D)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_E)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_H)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_L)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_M)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_H, REG_A)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_B)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_C)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_D)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_E)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_H)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_L)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_M)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_L, REG_A)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_B)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_C)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_D)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_E)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_H)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_L)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_M)) // HLT -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_M, REG_A)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_B)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_C)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_D)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_E)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_H)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_L)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_M)) -// .addChild(new InstrR_R(0, 0, OPCODE_MOV, REG_A, REG_A)) -// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_B)) -// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_C)) -// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_D)) -// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_E)) -// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_H)) -// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_L)) -// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_M)) -// .addChild(new InstrR(0, 0, OPCODE_ADD, REG_A)) -// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_B)) -// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_C)) -// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_D)) -// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_E)) -// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_H)) -// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_L)) -// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_M)) -// .addChild(new InstrR(0, 0, OPCODE_ADC, REG_A)) -// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_B)) -// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_C)) -// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_D)) -// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_E)) -// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_H)) -// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_L)) -// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_M)) -// .addChild(new InstrR(0, 0, OPCODE_SUB, REG_A)) -// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_B)) -// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_C)) -// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_D)) -// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_E)) -// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_H)) -// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_L)) -// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_M)) -// .addChild(new InstrR(0, 0, OPCODE_SBB, REG_A)) -// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_B)) -// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_C)) -// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_D)) -// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_E)) -// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_H)) -// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_L)) -// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_M)) -// .addChild(new InstrR(0, 0, OPCODE_ANA, REG_A)) -// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_B)) -// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_C)) -// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_D)) -// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_E)) -// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_H)) -// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_L)) -// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_M)) -// .addChild(new InstrR(0, 0, OPCODE_XRA, REG_A)) -// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_B)) -// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_C)) -// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_D)) -// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_E)) -// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_H)) -// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_L)) -// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_M)) -// .addChild(new InstrR(0, 0, OPCODE_ORA, REG_A)) -// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_B)) -// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_C)) -// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_D)) -// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_E)) -// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_H)) -// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_L)) -// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_M)) -// .addChild(new InstrR(0, 0, OPCODE_CMP, REG_A)) -// .addChild(new Instr(0, 0, OPCODE_RNZ, x, y, z)) -// .addChild(new InstrRP(0, 0, OPCODE_POP, REG_B)) -// .addChild(new InstrN(0, 0, OPCODE_JNZ) -// .addChild(new Evaluated(0, 0, 2))) -// .addChild(new InstrN(0, 0, OPCODE_JMP) -// .addChild(new Evaluated(0, 0, 0x200))) -// .addChild(new Instr(0, 0, OPCODE_CALL, 3, 0, 4) -// .addChild(new Evaluated(0, 0, 0xF0A0))) -// .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_B)) -// .addChild(new InstrN(0, 0, OPCODE_ADI) -// .addChild(new Evaluated(0, 0, 0xF0))) -// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) -// .addChild(new Evaluated(0, 0, 0))) -// .addChild(new Instr(0, 0, OPCODE_RZ, x, y, z)) -// .addChild(new Instr(0, 0, OPCODE_RET, x, y, z)) -// .addChild(new InstrN(0, 0, OPCODE_JZ) -// .addChild(new Evaluated(0, 0, 0x1234))) -// .addChild(new InstrN(0, 0, OPCODE_CZ) -// .addChild(new Evaluated(0, 0, 0x1234))) -// .addChild(new InstrN(0, 0, OPCODE_CALL) -// .addChild(new Evaluated(0, 0, 0x1234))) -// .addChild(new InstrN(0, 0, OPCODE_ACI) -// .addChild(new Evaluated(0, 0, 0xF0))) -// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) -// .addChild(new Evaluated(0, 0, 1))) -// .addChild(new Instr(0, 0, OPCODE_RNC, x, y, z)) -// .addChild(new InstrRP(0, 0, OPCODE_POP, REG_D)) -// .addChild(new InstrN(0, 0, OPCODE_JNC) -// .addChild(new Evaluated(0, 0, 0x1234))) -// .addChild(new InstrN(0, 0, OPCODE_OUT) -// .addChild(new Evaluated(0, 0, 0xF0))) -// .addChild(new InstrN(0, 0, OPCODE_CNC) -// .addChild(new Evaluated(0, 0, 0x1234))) -// .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_D)) -// .addChild(new InstrN(0, 0, OPCODE_SUI) -// .addChild(new Evaluated(0, 0, 0xF0))) -// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) -// .addChild(new Evaluated(0, 0, 2))) -// .addChild(new Instr(0, 0, OPCODE_RC, x, y, z)) -// .addChild(new InstrN(0, 0, OPCODE_JC) -// .addChild(new Evaluated(0, 0, 0x1234))) -// .addChild(new InstrN(0, 0, OPCODE_IN) -// .addChild(new Evaluated(0, 0, 0xF0))) -// .addChild(new InstrN(0, 0, OPCODE_CC) -// .addChild(new Evaluated(0, 0, 0x1234))) -// .addChild(new InstrN(0, 0, OPCODE_SBI) -// .addChild(new Evaluated(0, 0, 0xF0))) -// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) -// .addChild(new Evaluated(0, 0, 3))) -// .addChild(new Instr(0, 0, OPCODE_RPO, x, y, z)) -// .addChild(new InstrRP(0, 0, OPCODE_POP, REG_H)) -// .addChild(new InstrN(0, 0, OPCODE_JPO) -// .addChild(new Evaluated(0, 0, 0x1234))) -// .addChild(new Instr(0, 0, OPCODE_XTHL, x, y, z)) -// .addChild(new InstrN(0, 0, OPCODE_CPO) -// .addChild(new Evaluated(0, 0, 0x1234))) -// .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_H)) -// .addChild(new InstrN(0, 0, OPCODE_ANI) -// .addChild(new Evaluated(0, 0, 0xF0))) -// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) -// .addChild(new Evaluated(0, 0, 4))) -// .addChild(new Instr(0, 0, OPCODE_RPE, x, y, z)) -// .addChild(new Instr(0, 0, OPCODE_PCHL, x, y, z)) -// .addChild(new InstrN(0, 0, OPCODE_JPE) -// .addChild(new Evaluated(0, 0, 0x1234))) -// .addChild(new Instr(0, 0, OPCODE_EX, 3, 5, 3)) -// .addChild(new InstrN(0, 0, OPCODE_CPE) -// .addChild(new Evaluated(0, 0, 0x1234))) -// .addChild(new InstrN(0, 0, OPCODE_XRI) -// .addChild(new Evaluated(0, 0, 0xF0))) -// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) -// .addChild(new Evaluated(0, 0, 5))) -// .addChild(new Instr(0, 0, OPCODE_RP, x, y, z)) -// .addChild(new InstrRP(0, 0, OPCODE_POP, REG_PSW)) -// .addChild(new InstrN(0, 0, OPCODE_JP) -// .addChild(new Evaluated(0, 0, 0x200))) -// .addChild(new Instr(0, 0, OPCODE_DI, x, y, z)) -// .addChild(new InstrN(0, 0, OPCODE_CP) -// .addChild(new Evaluated(0, 0, 0x200))) -// .addChild(new InstrRP(0, 0, OPCODE_PUSH, REG_PSW)) -// .addChild(new InstrN(0, 0, OPCODE_ORI) -// .addChild(new Evaluated(0, 0, 0xF0))) -// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) -// .addChild(new Evaluated(0, 0, 6))) -// .addChild(new Instr(0, 0, OPCODE_RM, x, y, z)) -// .addChild(new Instr(0, 0, OPCODE_SPHL, x, y, z)) -// .addChild(new InstrN(0, 0, OPCODE_JM) -// .addChild(new Evaluated(0, 0, 0x200))) -// .addChild(new Instr(0, 0, OPCODE_EI, x, y, z)) -// .addChild(new InstrN(0, 0, OPCODE_CM) -// .addChild(new Evaluated(0, 0, 0x200))) -// .addChild(new InstrN(0, 0, OPCODE_CPI) -// .addChild(new Evaluated(0, 0, 0xF0))) -// .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) -// .addChild(new Evaluated(0, 0, 7))); - - IntelHEX hex = new IntelHEX(); - GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); - visitor.visit(program); - Map code = hex.getCode(); - - assertEquals(0, code.get(0).byteValue()); // NOP - assertEquals(1, code.get(1).byteValue()); // LD BC,D16 - assertEquals(0x34, code.get(2).byteValue()); - assertEquals(0x12, code.get(3).byteValue()); - assertEquals(2, code.get(4).byteValue()); // STAX B -// assertEquals(3, code.get(5).byteValue()); // INX B -// assertEquals(4, code.get(6).byteValue()); // INR B -// assertEquals(5, code.get(7).byteValue()); // DCR B -// assertEquals(6, code.get(8).byteValue()); // MVI B -// assertEquals(7, code.get(9).byteValue()); -// assertEquals(7, code.get(10).byteValue()); // RLC -// assertEquals(9, code.get(11).byteValue()); // DAD B -// assertEquals(0x0A, code.get(12).byteValue()); // LDAX B -// assertEquals(0x0B, code.get(13).byteValue()); // DCX B -// assertEquals(0x0C, code.get(14).byteValue()); // INR C -// assertEquals(0x0D, code.get(15).byteValue()); // DCR C -// assertEquals(0x0E, code.get(16).byteValue()); // MVI C -// assertEquals(8, code.get(17).byteValue()); -// assertEquals(0x0F, code.get(18).byteValue()); // RRC -// assertEquals(0x11, code.get(19).byteValue()); // LXI D -// assertEquals(0x45, code.get(20).byteValue()); -// assertEquals(0x23, code.get(21).byteValue()); -// assertEquals(0x12, code.get(22).byteValue()); // STAX D -// assertEquals(0x13, code.get(23).byteValue()); // INX D -// assertEquals(0x14, code.get(24).byteValue()); // INR D -// assertEquals(0x15, code.get(25).byteValue()); // DCR D -// assertEquals(0x16, code.get(26).byteValue()); // MVI D -// assertEquals(9, code.get(27).byteValue()); -// assertEquals(0x17, code.get(28).byteValue()); // RAL -// assertEquals(0x19, code.get(29).byteValue()); // DAD D -// assertEquals(0x1A, code.get(30).byteValue()); // LDAX D -// assertEquals(0x1B, code.get(31).byteValue()); // DCX D -// assertEquals(0x1C, code.get(32).byteValue()); // INR E -// assertEquals(0x1D, code.get(33).byteValue()); // DCR E -// assertEquals(0x1E, code.get(34).byteValue()); // MVI E -// assertEquals(10, code.get(35).byteValue()); -// assertEquals(0x1F, code.get(36).byteValue()); // RAR -// assertEquals(0x21, code.get(37).byteValue()); // LXI H -// assertEquals(0x45, code.get(38).byteValue()); -// assertEquals(0x23, code.get(39).byteValue()); -// assertEquals(0x22, code.get(40).byteValue()); // SHLD -// assertEquals(0x45, code.get(41).byteValue()); -// assertEquals(0x23, code.get(42).byteValue()); -// assertEquals(0x23, code.get(43).byteValue()); // INX H -// assertEquals(0x24, code.get(44).byteValue()); // INR H -// assertEquals(0x25, code.get(45).byteValue()); // DCR H -// assertEquals(0x26, code.get(46).byteValue()); // MVI H -// assertEquals(0x28, code.get(47).byteValue()); -// assertEquals(0x27, code.get(48).byteValue()); // DAA -// assertEquals(0x29, code.get(49).byteValue()); // DAD H -// assertEquals(0x2A, code.get(50).byteValue()); // LHLD -// assertEquals(0x45, code.get(51).byteValue()); -// assertEquals(0x23, code.get(52).byteValue()); -// assertEquals(0x2B, code.get(53).byteValue()); // DCX H -// assertEquals(0x2C, code.get(54).byteValue()); // INR L -// assertEquals(0x2D, code.get(55).byteValue()); // DCR L -// assertEquals(0x2E, code.get(56).byteValue()); // MVI L -// assertEquals(10, code.get(57).byteValue()); -// assertEquals(0x2F, code.get(58).byteValue()); // CMA -// assertEquals(0x31, code.get(59).byteValue()); // LXI SP -// assertEquals(0x45, code.get(60).byteValue()); -// assertEquals(0x23, code.get(61).byteValue()); -// assertEquals(0x32, code.get(62).byteValue()); // STA -// assertEquals(0x45, code.get(63).byteValue()); -// assertEquals(0x23, code.get(64).byteValue()); -// assertEquals(0x33, code.get(65).byteValue()); // INX SP -// assertEquals(0x34, code.get(66).byteValue()); // INR M -// assertEquals(0x35, code.get(67).byteValue()); // DCR M -// assertEquals(0x36, code.get(68).byteValue()); // MVI M -// assertEquals(7, code.get(69).byteValue()); -// assertEquals(0x37, code.get(70).byteValue()); // STC -// assertEquals(0x39, code.get(71).byteValue()); // DAD SP -// assertEquals(0x3A, code.get(72).byteValue()); // LDA -// assertEquals(0x45, code.get(73).byteValue()); -// assertEquals(0x23, code.get(74).byteValue()); -// assertEquals(0x3B, code.get(75).byteValue()); // DCX SP -// assertEquals(0x3C, code.get(76).byteValue()); // INR A -// assertEquals(0x3D, code.get(77).byteValue()); // DCR A -// assertEquals(0x3E, code.get(78).byteValue()); // MVI A -// assertEquals(-128, code.get(79).byteValue()); -// assertEquals(0x3F, code.get(80).byteValue()); // CMC -// assertEquals(0x40, code.get(81).byteValue()); // MOV B,B -// assertEquals(0x41, code.get(82).byteValue()); // MOV B,C -// assertEquals(0x42, code.get(83).byteValue()); // MOV B,D -// assertEquals(0x43, code.get(84).byteValue()); // MOV B,E -// assertEquals(0x44, code.get(85).byteValue()); // MOV B,H -// assertEquals(0x45, code.get(86).byteValue()); // MOV B,L -// assertEquals(0x46, code.get(87).byteValue()); // MOV B,M -// assertEquals(0x47, code.get(88).byteValue()); // MOV B,A -// assertEquals(0x48, code.get(89).byteValue()); // MOV C,B -// assertEquals(0x49, code.get(90).byteValue()); // MOV C,C -// assertEquals(0x4A, code.get(91).byteValue()); // MOV C,D -// assertEquals(0x4B, code.get(92).byteValue()); // MOV C,E -// assertEquals(0x4C, code.get(93).byteValue()); // MOV C,H -// assertEquals(0x4D, code.get(94).byteValue()); // MOV C,L -// assertEquals(0x4E, code.get(95).byteValue()); // MOV C,M -// assertEquals(0x4F, code.get(96).byteValue()); // MOV C,A -// assertEquals(0x50, code.get(97).byteValue()); // MOV D,B -// assertEquals(0x51, code.get(98).byteValue()); // MOV D,C -// assertEquals(0x52, code.get(99).byteValue()); // MOV D,D -// assertEquals(0x53, code.get(100).byteValue()); // MOV D,E -// assertEquals(0x54, code.get(101).byteValue()); // MOV D,H -// assertEquals(0x55, code.get(102).byteValue()); // MOV D,L -// assertEquals(0x56, code.get(103).byteValue()); // MOV D,M -// assertEquals(0x57, code.get(104).byteValue()); // MOV D,A -// assertEquals(0x58, code.get(105).byteValue()); // MOV E,B -// assertEquals(0x59, code.get(106).byteValue()); // MOV E,C -// assertEquals(0x5A, code.get(107).byteValue()); // MOV E,D -// assertEquals(0x5B, code.get(108).byteValue()); // MOV E,E -// assertEquals(0x5C, code.get(109).byteValue()); // MOV E,H -// assertEquals(0x5D, code.get(110).byteValue()); // MOV E,L -// assertEquals(0x5E, code.get(111).byteValue()); // MOV E,M -// assertEquals(0x5F, code.get(112).byteValue()); // MOV E,A -// assertEquals(0x60, code.get(113).byteValue()); // MOV H,B -// assertEquals(0x61, code.get(114).byteValue()); // MOV H,C -// assertEquals(0x62, code.get(115).byteValue()); // MOV H,D -// assertEquals(0x63, code.get(116).byteValue()); // MOV H,E -// assertEquals(0x64, code.get(117).byteValue()); // MOV H,H -// assertEquals(0x65, code.get(118).byteValue()); // MOV H,L -// assertEquals(0x66, code.get(119).byteValue()); // MOV H,M -// assertEquals(0x67, code.get(120).byteValue()); // MOV H,A -// assertEquals(0x68, code.get(121).byteValue()); // MOV L,B -// assertEquals(0x69, code.get(122).byteValue()); // MOV L,C -// assertEquals(0x6A, code.get(123).byteValue()); // MOV L,D -// assertEquals(0x6B, code.get(124).byteValue()); // MOV L,E -// assertEquals(0x6C, code.get(125).byteValue()); // MOV L,H -// assertEquals(0x6D, code.get(126).byteValue()); // MOV L,L -// assertEquals(0x6E, code.get(127).byteValue()); // MOV L,M -// assertEquals(0x6F, code.get(128).byteValue()); // MOV L,A -// assertEquals(0x70, code.get(129).byteValue()); // MOV M,B -// assertEquals(0x71, code.get(130).byteValue()); // MOV M,C -// assertEquals(0x72, code.get(131).byteValue()); // MOV M,D -// assertEquals(0x73, code.get(132).byteValue()); // MOV M,E -// assertEquals(0x74, code.get(133).byteValue()); // MOV M,H -// assertEquals(0x75, code.get(134).byteValue()); // MOV M,L -// assertEquals(0x76, code.get(135).byteValue()); // MOV M,M / HLT -// assertEquals(0x77, code.get(136).byteValue()); // MOV M,A -// assertEquals(0x78, code.get(137).byteValue()); // MOV A,B -// assertEquals(0x79, code.get(138).byteValue()); // MOV A,C -// assertEquals(0x7A, code.get(139).byteValue()); // MOV A,D -// assertEquals(0x7B, code.get(140).byteValue()); // MOV A,E -// assertEquals(0x7C, code.get(141).byteValue()); // MOV A,H -// assertEquals(0x7D, code.get(142).byteValue()); // MOV A,L -// assertEquals(0x7E, code.get(143).byteValue()); // MOV A,M -// assertEquals(0x7F, code.get(144).byteValue()); // MOV A,A -// assertEquals(0x80, code.get(145) & 0xFF); // ADD B -// assertEquals(0x81, code.get(146) & 0xFF); // ADD C -// assertEquals(0x82, code.get(147) & 0xFF); // ADD D -// assertEquals(0x83, code.get(148) & 0xFF); // ADD E -// assertEquals(0x84, code.get(149) & 0xFF); // ADD H -// assertEquals(0x85, code.get(150) & 0xFF); // ADD L -// assertEquals(0x86, code.get(151) & 0xFF); // ADD M -// assertEquals(0x87, code.get(152) & 0xFF); // ADD A -// assertEquals(0x88, code.get(153) & 0xFF); // ADC B -// assertEquals(0x89, code.get(154) & 0xFF); // ADC C -// assertEquals(0x8A, code.get(155) & 0xFF); // ADC D -// assertEquals(0x8B, code.get(156) & 0xFF); // ADC E -// assertEquals(0x8C, code.get(157) & 0xFF); // ADC H -// assertEquals(0x8D, code.get(158) & 0xFF); // ADC L -// assertEquals(0x8E, code.get(159) & 0xFF); // ADC M -// assertEquals(0x8F, code.get(160) & 0xFF); // ADC A -// assertEquals(0x90, code.get(161) & 0xFF); // SUB B -// assertEquals(0x91, code.get(162) & 0xFF); // SUB C -// assertEquals(0x92, code.get(163) & 0xFF); // SUB D -// assertEquals(0x93, code.get(164) & 0xFF); // SUB E -// assertEquals(0x94, code.get(165) & 0xFF); // SUB H -// assertEquals(0x95, code.get(166) & 0xFF); // SUB L -// assertEquals(0x96, code.get(167) & 0xFF); // SUB M -// assertEquals(0x97, code.get(168) & 0xFF); // SUB A -// assertEquals(0x98, code.get(169) & 0xFF); // SBB B -// assertEquals(0x99, code.get(170) & 0xFF); // SBB C -// assertEquals(0x9A, code.get(171) & 0xFF); // SBB D -// assertEquals(0x9B, code.get(172) & 0xFF); // SBB E -// assertEquals(0x9C, code.get(173) & 0xFF); // SBB H -// assertEquals(0x9D, code.get(174) & 0xFF); // SBB L -// assertEquals(0x9E, code.get(175) & 0xFF); // SBB M -// assertEquals(0x9F, code.get(176) & 0xFF); // SBB A -// assertEquals(0xA0, code.get(177) & 0xFF); // ANA B -// assertEquals(0xA1, code.get(178) & 0xFF); // ANA C -// assertEquals(0xA2, code.get(179) & 0xFF); // ANA D -// assertEquals(0xA3, code.get(180) & 0xFF); // ANA E -// assertEquals(0xA4, code.get(181) & 0xFF); // ANA H -// assertEquals(0xA5, code.get(182) & 0xFF); // ANA L -// assertEquals(0xA6, code.get(183) & 0xFF); // ANA M -// assertEquals(0xA7, code.get(184) & 0xFF); // ANA A -// assertEquals(0xA8, code.get(185) & 0xFF); // XRA B -// assertEquals(0xA9, code.get(186) & 0xFF); // XRA C -// assertEquals(0xAA, code.get(187) & 0xFF); // XRA D -// assertEquals(0xAB, code.get(188) & 0xFF); // XRA E -// assertEquals(0xAC, code.get(189) & 0xFF); // XRA H -// assertEquals(0xAD, code.get(190) & 0xFF); // XRA L -// assertEquals(0xAE, code.get(191) & 0xFF); // XRA M -// assertEquals(0xAF, code.get(192) & 0xFF); // XRA A -// assertEquals(0xB0, code.get(193) & 0xFF); // ORA B -// assertEquals(0xB1, code.get(194) & 0xFF); // ORA C -// assertEquals(0xB2, code.get(195) & 0xFF); // ORA D -// assertEquals(0xB3, code.get(196) & 0xFF); // ORA E -// assertEquals(0xB4, code.get(197) & 0xFF); // ORA H -// assertEquals(0xB5, code.get(198) & 0xFF); // ORA L -// assertEquals(0xB6, code.get(199) & 0xFF); // ORA M -// assertEquals(0xB7, code.get(200) & 0xFF); // ORA A -// assertEquals(0xB8, code.get(201) & 0xFF); // CMP B -// assertEquals(0xB9, code.get(202) & 0xFF); // CMP C -// assertEquals(0xBA, code.get(203) & 0xFF); // CMP D -// assertEquals(0xBB, code.get(204) & 0xFF); // CMP E -// assertEquals(0xBC, code.get(205) & 0xFF); // CMP H -// assertEquals(0xBD, code.get(206) & 0xFF); // CMP L -// assertEquals(0xBE, code.get(207) & 0xFF); // CMP M -// assertEquals(0xBF, code.get(208) & 0xFF); // CMP A -// assertEquals(0xC0, code.get(209) & 0xFF); // RNZ -// assertEquals(0xC1, code.get(210) & 0xFF); // POP B -// assertEquals(0xC2, code.get(211) & 0xFF); // JNZ -// assertEquals(2, code.get(212).byteValue()); -// assertEquals(0, code.get(213).byteValue()); -// assertEquals(0xC3, code.get(214) & 0xFF); // JMP -// assertEquals(0, code.get(215).byteValue()); -// assertEquals(2, code.get(216).byteValue()); -// assertEquals(0xC4, code.get(217) & 0xFF); // CNZ -// assertEquals(0xA0, code.get(218) & 0xFF); -// assertEquals(0xF0, code.get(219) & 0xFF); -// assertEquals(0xC5, code.get(220) & 0xFF); // PUSH B -// assertEquals(0xC6, code.get(221) & 0xFF); // ADI -// assertEquals(0xF0, code.get(222) & 0xFF); -// assertEquals(0xC7, code.get(223) & 0xFF); // RST 0 -// assertEquals(0xC8, code.get(224) & 0xFF); // RZ -// assertEquals(0xC9, code.get(225) & 0xFF); // RET -// assertEquals(0xCA, code.get(226) & 0xFF); // JZ -// assertEquals(0x34, code.get(227) & 0xFF); -// assertEquals(0x12, code.get(228) & 0xFF); -// assertEquals(0xCC, code.get(229) & 0xFF); // CZ -// assertEquals(0x34, code.get(230) & 0xFF); -// assertEquals(0x12, code.get(231) & 0xFF); -// assertEquals(0xCD, code.get(232) & 0xFF); // CALL -// assertEquals(0x34, code.get(233) & 0xFF); -// assertEquals(0x12, code.get(234) & 0xFF); -// assertEquals(0xCE, code.get(235) & 0xFF); // ACI -// assertEquals(0xF0, code.get(236) & 0xFF); -// assertEquals(0xCF, code.get(237) & 0xFF); // RST 1 -// assertEquals(0xD0, code.get(238) & 0xFF); // RNC -// assertEquals(0xD1, code.get(239) & 0xFF); // POP D -// assertEquals(0xD2, code.get(240) & 0xFF); // JNC -// assertEquals(0x34, code.get(241) & 0xFF); -// assertEquals(0x12, code.get(242) & 0xFF); -// assertEquals(0xD3, code.get(243) & 0xFF); // OUT -// assertEquals(0xF0, code.get(244) & 0xFF); -// assertEquals(0xD4, code.get(245) & 0xFF); // CNC -// assertEquals(0x34, code.get(246) & 0xFF); -// assertEquals(0x12, code.get(247) & 0xFF); -// assertEquals(0xD5, code.get(248) & 0xFF); // PUSH D -// assertEquals(0xD6, code.get(249) & 0xFF); // SUI -// assertEquals(0xF0, code.get(250) & 0xFF); -// assertEquals(0xD7, code.get(251) & 0xFF); // RST 2 -// assertEquals(0xD8, code.get(252) & 0xFF); // RC -// assertEquals(0xDA, code.get(253) & 0xFF); // JC -// assertEquals(0x34, code.get(254) & 0xFF); -// assertEquals(0x12, code.get(255) & 0xFF); -// assertEquals(0xDB, code.get(256) & 0xFF); // IN -// assertEquals(0xF0, code.get(257) & 0xFF); -// assertEquals(0xDC, code.get(258) & 0xFF); // CC -// assertEquals(0x34, code.get(259) & 0xFF); -// assertEquals(0x12, code.get(260) & 0xFF); -// assertEquals(0xDE, code.get(261) & 0xFF); // SBI -// assertEquals(0xF0, code.get(262) & 0xFF); -// assertEquals(0xDF, code.get(263) & 0xFF); // RST 3 -// assertEquals(0xE0, code.get(264) & 0xFF); // RPO -// assertEquals(0xE1, code.get(265) & 0xFF); // POP H -// assertEquals(0xE2, code.get(266) & 0xFF); // JPO -// assertEquals(0x34, code.get(267) & 0xFF); -// assertEquals(0x12, code.get(268) & 0xFF); -// assertEquals(0xE3, code.get(269) & 0xFF); // XTHL -// assertEquals(0xE4, code.get(270) & 0xFF); // CPO -// assertEquals(0x34, code.get(271) & 0xFF); -// assertEquals(0x12, code.get(272) & 0xFF); -// assertEquals(0xE5, code.get(273) & 0xFF); // PUSH H -// assertEquals(0xE6, code.get(274) & 0xFF); // ANI -// assertEquals(0xF0, code.get(275) & 0xFF); -// assertEquals(0xE7, code.get(276) & 0xFF); // RST -// assertEquals(0xE8, code.get(277) & 0xFF); // RPE -// assertEquals(0xE9, code.get(278) & 0xFF); // PCHL -// assertEquals(0xEA, code.get(279) & 0xFF); // JPE -// assertEquals(0x34, code.get(280) & 0xFF); -// assertEquals(0x12, code.get(281) & 0xFF); -// assertEquals(0xEB, code.get(282) & 0xFF); // XCHG -// assertEquals(0xEC, code.get(283) & 0xFF); // CPE -// assertEquals(0x34, code.get(284) & 0xFF); -// assertEquals(0x12, code.get(285) & 0xFF); -// assertEquals(0xEE, code.get(286) & 0xFF); // XRI -// assertEquals(0xF0, code.get(287) & 0xFF); -// assertEquals(0xEF, code.get(288) & 0xFF); // RST -// assertEquals(0xF0, code.get(289) & 0xFF); // RP -// assertEquals(0xF1, code.get(290) & 0xFF); // POP PSW -// assertEquals(0xF2, code.get(291) & 0xFF); // JP -// assertEquals(0x00, code.get(292) & 0xFF); -// assertEquals(0x02, code.get(293) & 0xFF); -// assertEquals(0xF3, code.get(294) & 0xFF); // DI -// assertEquals(0xF4, code.get(295) & 0xFF); // CP -// assertEquals(0x00, code.get(296) & 0xFF); -// assertEquals(0x02, code.get(297) & 0xFF); -// assertEquals(0xF5, code.get(298) & 0xFF); // PUSH PSW -// assertEquals(0xF6, code.get(299) & 0xFF); // ORI -// assertEquals(0xF0, code.get(300) & 0xFF); -// assertEquals(0xF7, code.get(301) & 0xFF); // RST 6 -// assertEquals(0xF8, code.get(302) & 0xFF); // RM -// assertEquals(0xF9, code.get(303) & 0xFF); // SPHL -// assertEquals(0xFA, code.get(304) & 0xFF); // JM -// assertEquals(0x00, code.get(305) & 0xFF); -// assertEquals(0x02, code.get(306) & 0xFF); -// assertEquals(0xFB, code.get(307) & 0xFF); // EI -// assertEquals(0xFC, code.get(308) & 0xFF); // CM -// assertEquals(0x00, code.get(309) & 0xFF); -// assertEquals(0x02, code.get(310) & 0xFF); -// assertEquals(0xFE, code.get(311) & 0xFF); // CPI -// assertEquals(0xF0, code.get(312) & 0xFF); -// assertEquals(0xFF, code.get(313) & 0xFF); // RST 7 - } } From 1b9c33279e9e32abce03a677c10d4b296e705f0e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 5 Mar 2022 07:25:50 +0000 Subject: [PATCH 110/314] [#201] az-z80: tests + z80-cpu: do not halt on invalid instruction --- .../compiler/as8080/visitors/ExpandMacrosTest.java | 10 ++++++++++ .../compiler/asZ80/visitors/ExpandMacrosTest.java | 11 +++++++++++ .../plugins/cpu/zilogZ80/EmulatorEngine.java | 9 +++------ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java index 19dbdd9f8..0936e074f 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java @@ -15,7 +15,9 @@ import java.io.File; import java.io.IOException; +import static net.emustudio.plugins.compiler.as8080.CompileError.ERROR_NOT_DEFINED; import static net.emustudio.plugins.compiler.as8080.Utils.*; +import static org.junit.Assert.assertTrue; public class ExpandMacrosTest { @Rule @@ -118,4 +120,12 @@ public void testMacroCallWithArguments() { program ); } + + @Test + public void testUnknownMacro() { + Program program = parseProgram("x 1,2,3\n"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + assertTrue(program.env().hasError(ERROR_NOT_DEFINED)); + } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java index 6fd7a09db..ac62541f1 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java @@ -15,7 +15,9 @@ import java.io.File; import java.io.IOException; +import static net.emustudio.plugins.compiler.asZ80.CompileError.ERROR_NOT_DEFINED; import static net.emustudio.plugins.compiler.asZ80.Utils.*; +import static org.junit.Assert.assertTrue; public class ExpandMacrosTest { @Rule @@ -118,4 +120,13 @@ public void testMacroCallWithArguments() { program ); } + + + @Test + public void testUnknownMacro() { + Program program = parseProgram("x 1,2,3\n"); + ExpandMacrosVisitor macrosVisitor = new ExpandMacrosVisitor(); + macrosVisitor.visit(program); + assertTrue(program.env().hasError(ERROR_NOT_DEFINED)); + } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 5524d5bcf..360c49d1c 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -219,13 +219,12 @@ private int dispatch() throws Throwable { if (instr != null) { return (int) instr.invokeExact(this); } - currentRunState = CPU.RunState.STATE_STOPPED_BAD_INSTR; + return 4; } finally { if (tmpListener != null) { tmpListener.afterDispatch(); } } - return 0; } int CB_DISPATCH() throws Throwable { @@ -261,8 +260,7 @@ private int DISPATCH(MethodHandle[] table) throws Throwable { if (instr != null) { return (int) instr.invokeExact(this); } - currentRunState = RunState.STATE_STOPPED_BAD_INSTR; - return 0; + return 4; } int SPECIAL_CB_DISPATCH(MethodHandle[] table) throws Throwable { @@ -277,8 +275,7 @@ int SPECIAL_CB_DISPATCH(MethodHandle[] table) throws Throwable { if (instr != null) { return (int) instr.invokeExact(this, operand); } - currentRunState = RunState.STATE_STOPPED_BAD_INSTR; - return 0; + return 4; } void setInterrupt(DeviceContext device, int mask) { From c150fccd38cca5411b89cba179d8ba94b8234ba8 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 8 Mar 2022 07:56:02 +0000 Subject: [PATCH 111/314] [#201] z80-cpu: new edigen --- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 864 ++++++++---------- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 2 +- 2 files changed, 364 insertions(+), 502 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index 62c8c11dc..0318bb5c7 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -1,517 +1,379 @@ root instruction; +# http://www.z80.info/decoding.htm instruction = - "nop": 0x00 | # 0x00 - "ld": 00 BC_DE_HL_SP(2) 0001 imm16 | # 0x01, 0x11, 0x21, 0x31 - "ld": 000 REF_BC_DE_A(1) 0010 | # 0x02, 0x12 - "inc": 00 BC_DE_HL_SP(2) 0011 | # 0x03, 0x13, 0x23, 0x33 - "inc": 00 REG(3) 100 | # 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34, 0x3C - "dec": 00 REG(3) 101 | # 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, 0x35, 0x3D - "ld": 00 REG(3) 110 imm8 | # 0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, 0x36, 0x3E - "rlca": 0x07 | # 0x07 - "ex AF,AF'": 0x08 | # 0x08 - "add HL,": 00 BC_DE_HL_SP(2) 1001 | # 0x09, 0x19, 0x29, 0x39 - "ld": 000 A_REF_BC_DE(1) 1010 | # 0x0A, 0x1A - "dec": 00 BC_DE_HL_SP(2) 1011 | # 0x0B, 0x1B, 0x2B, 0x3B - "rrca": 0x0F | # 0x0F - "djnz": 0x10 imm8 | # 0x10 - "rla": 0x17 | # 0x17 - "jr": 0x18 imm8 | # 0x18 - "rra": 0x1F | # 0x1F - "jr": 001 FLAGS_JR(2) 000 imm8 | # 0x20, 0x28, 0x30, 0x38 - "ld": 0x22 REF_imm16_HL | # 0x22 - "daa": 0x27 | # 0x27 - "ld": 0x2A HL_REF_imm16 | # 0x2A - "cpl": 0x2F | # 0x2F - "ld": 0x32 REF_imm16_A | # 0x32 - "scf": 0x37 | # 0x37 - "ld": 0x3A A_REF_imm16 | # 0x3A - "ccf": 0x3F | # 0x3F - "ld": 01 0 REG_B_C_D_E(2) REG | # 0x40 - 0x5F - "ld": 01 10 REG_H_L(1) REG | # 0x60 - 0x6F - "ld (HL),": 01 1100 REG_B_C_D_E(2) | # 0x70 - 0x73 - "ld (HL),": 01 11010 REG_H_L(1) | # 0x74, 0x75 - "halt": 0x76 | # 0x76 - "ld (HL), A": 0x77 | # 0x77 - "ld A,": 01 111 REG | # 0x78 - 0x7F - "add A,": 0x8 0 REG | # 0x80 - 0x87 - "adc A,": 0x8 1 REG | # 0x88 - 0x8F - "sub": 0x9 0 REG | # 0x90 - 0x97 - "sbc A,": 0x9 1 REG | # 0x98 - 0x9F - "and": 0xA 0 REG | # 0xA0 - 0xA7 - "xor": 0xA 1 REG | # 0xA8 - 0xAF - "or": 0xB 0 REG | # 0xB0 - 0xB7 - "cp": 0xB 1 REG | # 0xB8 - 0xBF - "ret NZ": 0xC0 | # 0xC0 - "pop": 110 BC_DE(1) 0001 | # 0xC1, 0xD1, 0xE1 - "pop": 111 HL_AF(1) 0001 | # 0xF1 - "jp": 11 FLAGS(3) 010 imm16 | # 0xC2, 0xCA, 0xD2, 0xDA, 0xE2, 0xEA, 0xF2, 0xFA - "jp": 0xC3 imm16 | # 0xC3 - "call": 11 FLAGS(3) 100 imm16 | # 0xC4, 0xCC, 0xD4, 0xDC, 0xE4, 0xEC, 0xF4, 0xFC - "push": 110 BC_DE(1) 0101 | # 0xC5, 0xD5 - "push": 111 HL_AF(1) 0101 | # 0xE5, 0xF5 - "add A,": 0xC6 imm8 | # 0xC6 - "rst": 11 NUMBER(3) 111 | # 0xC7, 0xCF, 0xD7, 0xDF, 0xE7, 0xEF, 0xF7, 0xFF - "ret Z": 0xC8 | # 0xC8 - "ret": 0xC9 | # 0xC9 - - 0xCB cbInstruction | # 0xCB - - "call": 0xCD imm16 | # 0xCD - "adc A,": 0xCE imm8 | # 0xCE - "ret NC": 0xD0 | # 0xD0 - "out": 0xD3 REF_imm8_A | # 0xD3 - "sub": 0xD6 imm8 | # 0xD6 - "ret C": 0xD8 | # 0xD8 - "exx": 0xD9 | # 0xD9 - "in A,": 0xDB REF_imm8 | # 0xDB - - 0xDD ddInstruction | # 0xDD - - "sbc": 0xDE imm8 | # 0xDE - "ret PO": 0xE0 | # 0xE0 - "ex (SP), HL": 0xE3 | # 0xE3 - "and": 0xE6 imm8 | # 0xE6 - "ret PE": 0xE8 | # 0xE8 - "jp (HL)": 0xE9 | # 0xE9 - "ex DE, HL": 0xEB | # 0xEB - - 0xED edInstruction | # 0xED - - "xor": 0xEE imm8 | # 0xEE - "ret P": 0xF0 | # 0xF0 - "di": 0xF3 | # 0xF3 - "or": 0xF6 imm8 | # 0xF6 - "ret M": 0xF8 | # 0xF8 - "ld SP,HL": 0xF9 | # 0xF9 - "ei": 0xFB | # 0xFB - - 0xFD fdInstruction | # 0xFD - - "cp": 0xFE imm8 ; # 0xFE - - -cbInstruction = - "rlc": 00000 REG | # 0x00 - 0x07 - "rrc": 00001 REG | # 0x08 - 0x0F - "rl": 00010 REG | # 0x10 - 0x17 - "rr": 00011 REG | # 0x18 - 0x1F - "sla": 00100 REG | # 0x20 - 0x27 - "sra": 00101 REG | # 0x28 - 0x2F - "sll": 00110 REG | # 0x30 - 0x37 - "srl": 00111 REG | # 0x38 - 0x3F - "bit": 01 BIT(3) REG | # 0x40 - 0x7F - "res": 10 BIT(3) REG | # 0x80 - 0xBF - "set": 11 BIT(3) REG ; # 0xC0 - 0xFF + "nop": 00 000 000 | # x=0, y=0, z=0 + "ex af, af'": 00 001 000 | # x=0, y=1, z=0 + "djnz %X": 00 010 000 imm8 | # x=0, y=2, z=0 + "jr %X": 00 011 000 imm8 | # x=0, y=3, z=0 + "jr %s, %X": 00 1 cc_jr(2) 000 imm8 | # x=0, y=4..7, z=0 + "ld %s, %X": 00 rp(2) 0 001 imm16 | # x=0, p=rp, q=0, z=1 + "add hl, %s": 00 rp(2) 1 001 | # x=0, p=rp, q=1, z=1 + "ld (bc), a": 00 000 010 | # x=0, p=0, q=0, z=2 + "ld (de), a": 00 010 010 | # x=0, p=1, q=0, z=2 + "ld (%X), hl": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 + "ld (%X), a": 00 110 010 ref16 | # x=0, p=3, q=0, z=2 + "ld a, (bc)": 00 001 010 | # x=0, p=0, q=1, z=2 + "ld a, (de)": 00 011 010 | # x=0, p=1, q=1, z=2 + "ld hl, (%X)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 + "ld a, (%X)": 00 111 010 ref16 | # x=0, p=3, q=1, z=2 + "inc %s": 00 rp(2) 0 011 | # x=0, p=rp, q=0, z=3 + "dec %s": 00 rp(2) 1 011 | # x=0, p=rp, q=1, z=3 + "inc %s": 00 r(3) 100 | # x=0, y=r, z=4 + "dec %s": 00 r(3) 101 | # x=0, y=r, z=5 + "ld %s, %X": 00 r(3) 110 imm8 | # x=0, y=r, z=6 + "rlca": 00 000 111 | # x=0, y=0, z=7 + "rrca": 00 001 111 | # x=0, y=1, z=7 + "rla": 00 010 111 | # x=0, y=2, z=7 + "rra": 00 011 111 | # x=0, y=3, z=7 + "daa": 00 100 111 | # x=0, y=4, z=7 + "cpl": 00 101 111 | # x=0, y=5, z=7 + "scf": 00 110 111 | # x=0, y=6, z=7 + "ccf": 00 111 111 | # x=0, y=7, z=7 + + "halt": 01 110 110 | # x=1, y=6, z=6 + "ld %s, %s": 01 0 r_bcde(2) r(3) | # x=1, y=0 r_bcde, z=r + "ld %s, %s": 01 10 r_h_l(1) r(3) | # x=1, y=10 r_h_l, z=r + "ld a, %s": 01 111 r(3) | # x=1, y=7, z=r + "ld (hl), %s": 01 110 0 r_bcde(2) | # x=1, y=6, z=0 r_bcde + "ld (hl), %s": 01 110 10 r_h_l(1) | # x=1, y=6, z=10 r_h_l + "ld (hl), a": 01 110 111 | # x=1, y=6, z=7 + + "%s %s": 10 alu(3) r(3) | # x=2, y=alu, z=r + + "ret %s": 11 cc(3) 000 | # x=3, y=cc, z=0 + "pop %s": 11 rp2(2) 0 001 | # x=3, p=rp2, q=0, z=1 + "ret": 11 001 001 | # x=3, p=0, q=1, z=1 + "exx": 11 011 001 | # x=3, p=1, q=1, z=1 + "jp (hl)": 11 101 001 | # x=3, p=2, q=1, z=1 + "ld sp, hl": 11 111 001 | # x=3, p=3, q=1, z=1 + "jp %s, %X": 11 cc(3) 010 imm16 | # x=3, y=cc, z=2 + "jp %X": 11 000 011 imm16 | # x=3, y=0, z=3 + + "%s %s": 0xCB 00 rot(3) r(3) | # x=0, y=rot, z=r + "bit %X, %s": 0xCB 01 bit(3) r(3) | # x=1, y=bit, z=r + "res %X, %s": 0xCB 10 bit(3) r(3) | # x=2, y=bit, z=r + "set %X, %s": 0xCB 11 bit(3) r(3) | # x=3, y=bit, z=r + + "out (%X), a": 11 010 011 ref8 | # x=3, y=2, z=3 + "in a, (%X)": 11 011 011 ref8 | # x=3, y=3, z=3 + "ex (sp), hl": 11 100 011 | # x=3, y=4, z=3 + "ex de, hl": 11 101 011 | # x=3, y=5, z=3 + "di": 11 110 011 | # x=3, y=6, z=3 + "ei": 11 111 011 | # x=3, y=7, z=3 + "call %s, %X": 11 cc(3) 100 imm16 | # x=3, y=cc, z=4 + "push %s": 11 rp2(2) 0 101 | # x=3, p=rp2, q=0, z=5 + "call %X": 11 001 101 imm16 | # x=3, p=0, q=1, z=5 + + 0xDD ddInstruction | + + "in %s, (c)": 0xED 01 0 r_bcde(2) 000 | # x=1, y=0 r_bcde, z=0 + "in %s, (c)": 0xED 01 10 r_h_l(1) 000 | # x=1, y=10 r_h_l, z=0 + "in a, (c)": 0xED 01 111 000 | # x=1, y=7, z=0 + "in (c)": 0xED 01 110 000 | # x=1, y=6, z=0 + "out (c), %s": 0xED 01 0 r_bcde(2) 001 | # x=1, y=0 r_bcde, z=1 + "out (c), %s": 0xED 01 10 r_h_l(1) 001 | # x=1, y=10 r_h_l, z=1 + "out (c), a": 0xED 01 111 001 | # x=1, y=7, z=1 + "out (c), 0": 0xED 01 110 001 | # x=1, y=6, z=1 + "sbc hl, %s": 0xED 01 rp(2) 0 010 | # x=1, p=rp, q=0, z=2 + "adc hl, %s": 0xED 01 rp(2) 1 010 | # x=1, p=rp, q=1, z=2 + "ld (%X), %s": 0xED 01 rp(2) 0 011 ref16_2 | # x=1, p=rp, q=0, z=3 + "ld %s, (%X)": 0xED 01 rp(2) 1 011 ref16 | # x=1, p=rp, q=1, z=3 + "neg": 0xED 01 any(3) 100 | # x=1, y=any, z=4 + "reti": 0xED 01 001 101 | # x=1, y=1, z=5 + "retn": 0xED 01 any2(2) 0 101 | # x=1, y!=1, z=5 + "retn": 0xED 01 10 1 101 | # x=1, y!=1, z=5 + "retn": 0xED 01 01 1 101 | # x=1, y!=1, z=5 + "retn": 0xED 01 11 1 101 | # x=1, y!=1, z=5 + "im %s": 0xED 01 im(3) 110 | # x=1, y=im, z=6 + "ld i, a": 0xED 01 000 111 | # x=1, y=0, z=7 + "ld r, a": 0xED 01 001 111 | # x=1, y=1, z=7 + "ld a, i": 0xED 01 010 111 | # x=1, y=2, z=7 + "ld a, r": 0xED 01 011 111 | # x=1, y=3, z=7 + "rrd": 0xED 01 100 111 | # x=1, y=4, z=7 + "rld": 0xED 01 101 111 | # x=1, y=5, z=7 + "nop": 0xED 01 110 111 | # x=1, y=6, z=7 + "nop": 0xED 01 111 111 | # x=1, y=7, z=7 + + "ldi": 0xED 10 100 000 | # x=2, y=4, z=0 + "ldd": 0xED 10 101 000 | # x=2, y=5, z=0 + "ldir": 0xED 10 110 000 | # x=2, y=6, z=0 + "lddr": 0xED 10 111 000 | # x=2, y=7, z=0 + + "cpi": 0xED 10 100 001 | # x=2, y=4, z=1 + "cpd": 0xED 10 101 001 | # x=2, y=5, z=1 + "cpir": 0xED 10 110 001 | # x=2, y=6, z=1 + "cpdr": 0xED 10 111 001 | # x=2, y=7, z=1 + + "ini": 0xED 10 100 010 | # x=2, y=4, z=2 + "ind": 0xED 10 101 010 | # x=2, y=5, z=2 + "inir": 0xED 10 110 010 | # x=2, y=6, z=2 + "indr": 0xED 10 111 010 | # x=2, y=7, z=2 + + "outi": 0xED 10 100 011 | # x=2, y=4, z=3 + "outd": 0xED 10 101 011 | # x=2, y=5, z=3 + "otir": 0xED 10 110 011 | # x=2, y=6, z=3 + "otdr": 0xED 10 111 011 | # x=2, y=7, z=3 + + 0xFD fdInstruction | + + "%s %X": 11 alu(3) 110 imm8 | # x=3, y=alu, z=6 + "rst %s": 11 rst(3) 111 ; # x=3, y=rst, z=7 ddInstruction = - "add IX,": 00 BC_DE_IX_SP(2) 1001 | # 0x09, 0x19, 0x29, 0x39 - "ld IX,": 0x21 imm16 | # 0x21 - "ld": 0x22 REF_imm16_II | # 0x22 - "inc IX": 0x23 | # 0x23 - "inc IXH": 0x24 | # 0x24 - "dec IXH": 0x25 | # 0x25 - "ld IXH,": 0x26 imm8 | # 0x26 - "ld IX,": 0x2A REF_imm16 | # 0x2A - "dec IX": 0x2B | # 0x2B - "inc IXL": 0x2C | # 0x2C - "dec IXL": 0x2D | # 0x2D - "ld IXL,": 0x2E imm8 | # 0x2E - "inc": 0x34 REF_II_N | # 0x34 - "dec": 0x35 REF_II_N | # 0x35 - "ld": 0x36 REF_II_N(8) imm8 | # 0x36 - "ld": 010 REG_B_C_D_E_IIH(2) 100 | # 0x44, 0x4C, 0x54, 0x5C - "ld A, IXH": 0x7C | # 0x7C - "ld": 010 REG_B_C_D_E_IIL(2) 101 | # 0x45, 0x4D, 0x55, 0x5D - "ld A, IXL": 0x7D | # 0x7D - "ld": 010 REG_B_C_D_E(2) 110 REF_II_N | # 0x46, 0x4E, 0x56, 0x5E - "ld": 0110 REG_H_L(1) 110 REF_II_N | # 0x66, 0x6E - "ld A,": 0x7E REF_II_N | # 0x7E - "ld IXH,": 0110 00 REG_B_C_D_E(2) | # 0x60 - 063 - "ld IXH, IXH": 0x64 | # 0x64 - "ld IXH, IXL": 0x65 | # 0x65 - "ld IXH, A": 0x67 | # 0x67 - "ld IXL,": 0110 10 REG_B_C_D_E(2) | # 0x68 - 0x6B - "ld IXL, IXH": 0x6C | # 0x6C - "ld IXL, IXL": 0x6D | # 0x6D - "ld IXL, A": 0x6F | # 0x6F - "ld": 01110 0 REG_B_C_D_E(2) REF_II_N_2 | # 0x70 - 0x73 - "ld": 01110 10 REG_H_L(1) REF_II_N_2 | # 0x74, 0x75 - "ld": 01110 REG_A[111](3) REF_II_N_2 | # 0x77 - "add A, IXH": 0x84 | # 0x84 - "add A, IXL": 0x85 | # 0x85 - "add A,": 0x86 REF_II_N | # 0x86 - "adc A, IXH": 0x8C | # 0x8C - "adc A, IXL": 0x8D | # 0x8D - "adc A,": 0x8E REF_II_N | # 0x8E - "sub IXH": 0x94 | # 0x94 - "sub IXL": 0x95 | # 0x95 - "sub": 0x96 REF_II_N | # 0x96 - "sbc A, IXH": 0x9C | # 0x9C - "sbc A, IXL": 0x9D | # 0x9D - "sbc A,": 0x9E REF_II_N | # 0x9E - "and IXH": 0xA4 | # 0xA4 - "and IXL": 0xA5 | # 0xA5 - "and": 0xA6 REF_II_N | # 0xA6 - "xor IXH": 0xAC | # 0xAC - "xor IXL": 0xAD | # 0xAD - "xor": 0xAE REF_II_N | # 0xAE - "or IXH": 0xB4 | # 0xB4 - "or IXL": 0xB5 | # 0xB5 - "or": 0xB6 REF_II_N | # 0xB6 - "cp IXH": 0xBC | # 0xBC - "cp IXL": 0xBD | # 0xBD - "cp": 0xBE REF_II_N | # 0xBE - - 0xCB REF_II_N(8) ddcbInstruction | # 0xCB - - "pop IX": 0xE1 | # 0xE1 - "ex (SP), IX": 0xE3 | # 0xE3 - "push IX": 0xE5 | # 0xE5 - "jp (IX)": 0xE9 | # 0xE9 - "ld SP, IX": 0xF9 ; # 0xF9 + "ld ix, %X": 00 100 001 imm16 | # x=0, p=2, q=0, z=1 + "add ix, %s": 00 101 001 | # x=0, p=2, q=1, z=1 + "ld (%X), ix": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 + "ld ix, (%X)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 + "inc ix": 00 100 011 | # x=0, p=2, q=0, z=3 + "dec ix": 00 101 011 | # x=0, p=2, q=1, z=3 + "inc %s": 00 10 r_ixhl(1) 100 | # x=0, y=r_ixhl, z=4 + "inc (ix+%X)": 00 110 100 disp | # x=0, y=6, z=4 + "dec %s": 00 10 r_ixhl(1) 101 | # x=0, y=r_ixhl, z=5 + "dec (ix+%X)": 00 110 101 disp | # x=0, y=6, z=5 + "ld %s, %X": 00 10 r_ixhl(1) 110 imm8 | # x=0, y=r_ixhl, z=6 + "ld (ix+%X), %X": 00 110 110 disp(8) imm8 | # x=0, y=6, z=6 + "ld %s, %s": 01 10 r_ixhl(1) 10 r_ixhl2(1) | # x=0, y=r_ixhl, z=r_ixhl2 + "ld (ix+%X), %s": 01 110 r_no_hl(3) disp | # x=0, y=6, z=r_no_hl + "ld %s, (ix+%X)": 01 0 r_bcde(2) 110 disp | # x=0, y=0 r_bcde, z=6 + "ld %s, (ix+%X)": 01 10 r_h_l(1) 110 disp | # x=0, y=10 r_h_l, z=6 + "ld a, (ix+%X)": 01 111 110 disp | # x=0, y=7, z=6 + "%s %s": 10 alu(3) 10 r_ixhl(1) | # x=2, y=alu, z=r_ixhl + "%s (ix+%X)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 + "pop ix": 11 100 001 | # x=3, p=2, q=0, z=1 + "jp (ix)": 11 101 001 | # x=3, p=2, q=1, z=1 + "ld sp, ix": 11 111 001 | # x=3, p=3, q=1, z=1 + + 0xCB disp(8) ddcbInstruction | + + "ex (sp), ix": 11 100 011 | # x=3, y=4, z=3 + "push ix": 11 100 101 ; # x=3, p=2, q=0, z=5 fdInstruction = - "add IY,": 00 BC_DE_IY_SP(2) 1001 | # 0x09, 0x19, 0x29, 0x39 - "ld IY,": 0x21 imm16 | # 0x21 - "ld": 0x22 REF_imm16_II | # 0x22 - "inc IY": 0x23 | # 0x23 - "inc IYH": 0x24 | # 0x24 - "dec IYH": 0x25 | # 0x25 - "ld IYH,": 0x26 imm8 | # 0x26 - "ld IY,": 0x2A REF_imm16 | # 0x2A - "dec IY": 0x2B | # 0x2B - "inc IYL": 0x2C | # 0x2C - "dec IYL": 0x2D | # 0x2D - "ld IYL,": 0x2E imm8 | # 0x2E - "inc": 0x34 REF_II_N | # 0x34 - "dec": 0x35 REF_II_N | # 0x35 - "ld": 0x36 REF_II_N(8) imm8 | # 0x36 - "ld": 010 REG_B_C_D_E_IIH(2) 100 | # 0x44, 0x4C, 0x54, 0x5C - "ld A, IYH": 0x7C | # 0x7C - "ld": 010 REG_B_C_D_E_IIL(2) 101 | # 0x45, 0x4D, 0x55, 0x5D - "ld A, IYL": 0x7D | # 0x7D - "ld": 010 REG_B_C_D_E(2) 110 REF_II_N | # 0x46, 0x4E, 0x56, 0x5E - "ld": 0110 REG_H_L(1) 110 REF_II_N | # 0x66, 0x6E - "ld A,": 0x7E REF_II_N | # 0x7E - "ld IYH,": 0110 00 REG_B_C_D_E(2) | # 0x60 - 063 - "ld IYH, IYH": 0x64 | # 0x64 - "ld IYH, IYL": 0x65 | # 0x65 - "ld IYH, A": 0x67 | # 0x67 - "ld IYL,": 0110 10 REG_B_C_D_E(2) | # 0x68 - 0x6B - "ld IYL, IYH": 0x6C | # 0x6C - "ld IYL, IYL": 0x6D | # 0x6D - "ld IYL, A": 0x6F | # 0x6F - "ld": 01110 0 REG_B_C_D_E(2) REF_II_N_2 | # 0x70 - 0x73 - "ld": 01110 10 REG_H_L(1) REF_II_N_2 | # 0x74, 0x75 - "ld": 01110 REG_A[111](3) REF_II_N_2 | # 0x77 - "add A, IYH": 0x84 | # 0x84 - "add A, IYL": 0x85 | # 0x85 - "add A,": 0x86 REF_II_N | # 0x86 - "adc A, IYH": 0x8C | # 0x8C - "adc A, IYL": 0x8D | # 0x8D - "adc A,": 0x8E REF_II_N | # 0x8E - "sub IYH": 0x94 | # 0x94 - "sub IYL": 0x95 | # 0x95 - "sub": 0x96 REF_II_N | # 0x96 - "sbc A, IYH": 0x9C | # 0x9C - "sbc A, IYL": 0x9D | # 0x9D - "sbc A,": 0x9E REF_II_N | # 0x9E - "and IYH": 0xA4 | # 0xA4 - "and IYL": 0xA5 | # 0xA5 - "and": 0xA6 REF_II_N | # 0xA6 - "xor IYH": 0xAC | # 0xAC - "xor IYL": 0xAD | # 0xAD - "xor": 0xAE REF_II_N | # 0xAE - "or IYH": 0xB4 | # 0xB4 - "or IYL": 0xB5 | # 0xB5 - "or": 0xB6 REF_II_N | # 0xB6 - "cp IYH": 0xBC | # 0xBC - "cp IYL": 0xBD | # 0xBD - "cp": 0xBE REF_II_N | # 0xBE - - 0xCB REF_II_N(8) fdcbInstruction | # 0xCB - - "pop IY": 0xE1 | # 0xE1 - "ex (SP), IY": 0xE3 | # 0xE3 - "push IY": 0xE5 | # 0xE5 - "jp (IY)": 0xE9 | # 0xE9 - "ld SP, IY": 0xF9 ; # 0xF9 + "ld iy, %X": 00 100 001 imm16 | # x=0, p=2, q=0, z=1 + "add iy, %s": 00 101 001 | # x=0, p=2, q=1, z=1 + "ld (%X), iy": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 + "ld iy, (%X)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 + "inc iy": 00 100 011 | # x=0, p=2, q=0, z=3 + "dec iy": 00 101 011 | # x=0, p=2, q=1, z=3 + "inc %s": 00 10 r_iyhl(1) 100 | # x=0, y=r_iyhl, z=4 + "inc (iy+%X)": 00 110 100 disp | # x=0, y=6, z=4 + "dec %s": 00 10 r_iyhl(1) 101 | # x=0, y=r_iyhl, z=5 + "dec (iy+%X)": 00 110 101 disp | # x=0, y=6, z=5 + "ld %s, %X": 00 10 r_iyhl(1) 110 imm8 | # x=0, y=r_iyhl, z=6 + "ld (iy+%X), %X": 00 110 110 disp(8) imm8 | # x=0, y=6, z=6 + "ld %s, %s": 01 10 r_iyhl(1) 10 r_iyhl2(1) | # x=0, y=r_iyhl, z=r_iyhl2 + "ld (iy+%X), %s": 01 110 r_no_hl(3) disp | # x=0, y=6, z=r_no_hl + "ld %s, (iy+%X)": 01 0 r_bcde(2) 110 disp | # x=0, y=0 r_bcde, z=6 + "ld %s, (iy+%X)": 01 10 r_h_l(1) 110 disp | # x=0, y=10 r_h_l, z=6 + "ld a, (iy+%X)": 01 111 110 disp | # x=0, y=7, z=6 + "%s %s": 10 alu(3) 10 r_iyhl(1) | # x=2, y=alu, z=r_iyhl + "%s (iy+%X)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 + "pop iy": 11 100 001 | # x=3, p=2, q=0, z=1 + "jp (iy)": 11 101 001 | # x=3, p=2, q=1, z=1 + "ld sp, iy": 11 111 001 | # x=3, p=3, q=1, z=1 + + 0xCB disp(8) fdcbInstruction | + + "ex (sp), iy": 11 100 011 | # x=3, y=4, z=3 + "push iy": 11 100 101 ; # x=3, p=2, q=0, z=5 ddcbInstruction = - "rlc": 0000 00 REG_B_C_D_E(2) | # 0x00 - 0x03 - "rlc": 0000 01 0 REG_H_L(1) | # 0x04, 0x05 - "rlc": 0000 0110 | # 0x06 - "rlc": 0000 0 REG_A[111](3) | # 0x07 - "rrc": 0000 10 REG_B_C_D_E(2) | # 0x08 - 0x0B - "rrc": 0000 110 REG_H_L(1) | # 0x0C, 0x0D - "rrc": 0x0E | # 0x0E - "rrc": 0000 1 REG_A[111](3) | # 0x0F - "rl": 0001 00 REG_B_C_D_E | # 0x10 - 0x13 - "rl": 0001 010 REG_H_L | # 0x14, 0x15 - "rl": 0x16 | # 0x16 - "rl": 0001 0 REG_A[111](3) | # 0x17 - "rr": 0001 10 REG_B_C_D_E | # 0x18 - 0x1B - "rr": 0001 110 REG_H_L | # 0x1C, 0x1D - "rr": 0x1E | # 0x1E - "rr": 0001 1 REG_A[111](3) | # 0x1F - "sla": 0010 00 REG_B_C_D_E | # 0x20 - 0x23 - "sla": 0010 010 REG_H_L | # 0x24, 0x25 - "sla": 0x26 | # 0x26 - "sla": 0010 0 REG_A[111](3) | # 0x27 - "sra": 0010 10 REG_B_C_D_E | # 0x28 - 0x2B - "sra": 0010 110 REG_H_L | # 0x2C, 0x2D - "sra": 0x2E | # 0x2E - "sra": 0010 1 REG_A[111](3) | # 0x2F - "sll": 0011 00 REG_B_C_D_E | # 0x30 - 0x33 - "sll": 0011 010 REG_H_L | # 0x34, 0x35 - "sll": 0x36 | # 0x36 - "sll": 0011 0 REG_A[111](3) | # 0x37 - "srl": 0011 10 REG_B_C_D_E | # 0x38 - 0x3B - "srl": 0011 110 REG_H_L | # 0x3C, 0x3D - "srl": 0x3E | # 0x3E - "srl": 0011 1 REG_A[111](3) | # 0x3F - "bit": 01 BIT(3) IGNORE(3) | # 0x40 - 0x7F - "res": 10 BIT(3) 0 REG_B_C_D_E | # 0x80-0x83, 0x88-0x8B, 0x90-0x93, 0x98-0x9B, 0xA0-0xA3, 0xA8-0xAB, 0xB0-0xB3, 0xB8-0xBB - "res": 10 BIT(3) 10 REG_H_L | # 0x84, 0x85, 0x8C, 0x8D, 0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD, 0xB4, 0xB5, 0xBC, 0xBD - "res": 10 BIT(3) 110 | # 0x86, 0x8E, 0x96, 0x9E, 0xA6, 0xAE, 0xB6, 0xBE - "res": 10 BIT(3) REG_A[111](3) | # 0x87, 0x8F, 0x97, 0x9F, 0xA7, 0xAF, 0xB7, 0xBF - "set": 11 BIT(3) 0 REG_B_C_D_E | # 0xC0-0xC3, 0xC8-0xCB, 0xD0-0xD3, 0xD8-0xDB, 0xE0-0xE3, 0xE8-0xEB, 0xF0-0xF3, 0xF8-0xFB - "set": 11 BIT(3) 10 REG_H_L | # 0xC4, 0xC5, 0xCC, 0xCD, 0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED, 0xF4, 0xF5, 0xFC, 0xFD - "set": 11 BIT(3) 110 | # 0xC6, 0xCE, 0xD6, 0xDE, 0xE6, 0xEE, 0xF6, 0xFE - "set": 11 BIT(3) REG_A[111](3) ; # 0xC7, 0xCF, 0xD7, 0xDF, 0xE7, 0xEF, 0xF7, 0xFF + "%s (ix+%X), %s": 00 rot(3) 0 r_bcde(2) | # x=0, y=rot, z=0 r_bcde + "%s (ix+%X), %s": 00 rot(3) 10 r_h_l(1) | # x=0, y=rot, z=10 r_h_l + "%s (ix+%X), a": 00 rot(3) 111 | # x=0, y=rot, z=7 + "%s (ix+%X)": 00 rot(3) 110 | # x=0, y=rot, z=6 + "bit %X, (ix+%X)": 01 bit(3) any(3) | # x=1, y=bit, z=any + "res %X, (ix+%X), %s": 10 bit(3) 0 r_bcde(2) | # x=2, y=bit, z=0 r_bcde + "res %X, (ix+%X), %s": 10 bit(3) 10 r_h_l(1) | # x=2, y=bit, z=10 r_h_l + "res %X, (ix+%X), a": 10 bit(3) 111 | # x=2, y=bit, z=7 + "res %X, (ix+%X)": 10 bit(3) 110 | # x=2, y=bit, z=6 + "set %X, (ix+%X), %s": 11 bit(3) 0 r_bcde(2) | # x=3, y=bit, z=0 r_bcde + "set %X, (ix+%X), %s": 11 bit(3) 10 r_h_l(1) | # x=3, y=bit, z=10 r_h_l + "set %X, (ix+%X), a": 11 bit(3) 111 | # x=3, y=bit, z=7 + "set %X, (ix+%X)": 11 bit(3) 110 ; # x=3, y=bit, z=6 fdcbInstruction = - "rlc": 0000 00 REG_B_C_D_E | # 0x00 - 0x03 - "rlc": 0000 010 REG_H_L | # 0x04, 0x05 - "rlc": 0x06 | # 0x06 - "rlc": 0000 0 REG_A[111](3) | # 0x07 - "rrc": 0000 10 REG_B_C_D_E | # 0x08 - 0x0B - "rrc": 0000 110 REG_H_L | # 0x0C, 0x0D - "rrc": 0x0E | # 0x0E - "rrc": 0000 1 REG_A[111](3) | # 0x0F - "rl": 0001 00 REG_B_C_D_E | # 0x10 - 0x13 - "rl": 0001 010 REG_H_L | # 0x14, 0x15 - "rl": 0x16 | # 0x16 - "rl": 0001 0 REG_A[111](3) | # 0x17 - "rr": 0001 10 REG_B_C_D_E | # 0x18 - 0x1B - "rr": 0001 110 REG_H_L | # 0x1C, 0x1D - "rr": 0x1E | # 0x1E - "rr": 0001 1 REG_A[111](3) | # 0x1F - "sla": 0010 00 REG_B_C_D_E | # 0x20 - 0x23 - "sla": 0010 010 REG_H_L | # 0x24, 0x25 - "sla": 0x26 | # 0x26 - "sla": 0010 0 REG_A[111](3) | # 0x27 - "sra": 0010 10 REG_B_C_D_E | # 0x28 - 0x2B - "sra": 0010 110 REG_H_L | # 0x2C, 0x2D - "sra": 0x2E | # 0x2E - "sra": 0010 1 REG_A[111](3) | # 0x2F - "sll": 0011 00 REG_B_C_D_E | # 0x30 - 0x33 - "sll": 0011 010 REG_H_L | # 0x34, 0x35 - "sll": 0x36 | # 0x36 - "sll": 0011 0 REG_A[111](3) | # 0x37 - "srl": 0011 10 REG_B_C_D_E | # 0x38 - 0x3B - "srl": 0011 110 REG_H_L | # 0x3C, 0x3D - "srl": 0x3E | # 0x3E - "srl": 0011 1 REG_A[111](3) | # 0x3F - "bit": 01 BIT(3) IGNORE(3) | # 0x40 - 0x7F - "res": 10 BIT(3) 0 REG_B_C_D_E | # 0x80-0x83, 0x88-0x8B, 0x90-0x93, 0x98-0x9B, 0xA0-0xA3, 0xA8-0xAB, 0xB0-0xB3, 0xB8-0xBB - "res": 10 BIT(3) 10 REG_H_L | # 0x84, 0x85, 0x8C, 0x8D, 0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD, 0xB4, 0xB5, 0xBC, 0xBD - "res": 10 BIT(3) 110 | # 0x86, 0x8E, 0x96, 0x9E, 0xA6, 0xAE, 0xB6, 0xBE - "res": 10 BIT(3) REG_A[111](3) | # 0x87, 0x8F, 0x97, 0x9F, 0xA7, 0xAF, 0xB7, 0xBF - "set": 11 BIT(3) 0 REG_B_C_D_E | # 0xC0-0xC3, 0xC8-0xCB, 0xD0-0xD3, 0xD8-0xDB, 0xE0-0xE3, 0xE8-0xEB, 0xF0-0xF3, 0xF8-0xFB - "set": 11 BIT(3) 10 REG_H_L | # 0xC4, 0xC5, 0xCC, 0xCD, 0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED, 0xF4, 0xF5, 0xFC, 0xFD - "set": 11 BIT(3) 110 | # 0xC6, 0xCE, 0xD6, 0xDE, 0xE6, 0xEE, 0xF6, 0xFE - "set": 11 BIT(3) REG_A[111](3) ; # 0xC7, 0xCF, 0xD7, 0xDF, 0xE7, 0xEF, 0xF7, 0xFF - -edInstruction = - "in": 01 0 REG_B_C_D_E(2) 000 | # 0x40, 0x48, 0x50, 0x58 - "out": 01 0 REG_B_C_D_E_OUT(2) 001 | # 0x41, 0x49, 0x51, 0x59 - "sbc HL,": 010 BC_DE(1) 0010 | # 0x42, 0x52 - "ld": 010 BC_DE(1) 0011 REF_imm16 | # 0x43, 0x53 - "neg": 0x44 | # 0x44 - "retn": 0x45 | # 0x45 - "im 0": 0x46 | # 0x46 - "ld I, A": 0x47 | # 0x47 - "adc HL,": 010 BC_DE(1) 1010 | # 0x4A, 0x5A - "ld": 010 BC_DE(1) 1011 imm16 | # 0x4B, 0x5B - "neg": 0x4C | # 0x4C - "reti": 0x4D | # 0x4D - "im 0": 0x4E | # 0x4E - "ld R, A": 0x4F | # 0x4F - "neg": 0x54 | # 0x54 - "retn": 0x55 | # 0x55 - "im 1": 0x56 | # 0x56 - "ld A, I": 0x57 | # 0x57 - "neg": 0x5C | # 0x5C - "retn": 0x5D | # 0x5D - "im 2": 0x5E | # 0x5E - "ld A, R": 0x5F | # 0x5F - "in": 01 10 REG_H_L(1) 000 | # 0x60, 0x68 - "out": 01 10 REG_H_L_OUT(1) 001 | # 0x61, 0x69 - "sbc HL,": 011 HL_SP(1) 0010 | # 0x62, 0x72 - "ld": 011 HL_SP(1) 0011 REF_imm16 | # 0x63, 0x73 - "neg": 0x64 | # 0x64 - "retn": 0x65 | # 0x65 - "im 0": 0x66 | # 0x66 - "rrd": 0x67 | # 0x67 - "adc HL,": 011 HL_SP(1) 1010 | # 0x6A, 0x7A - "ld": 011 HL_SP(1) 1011 imm16 | # 0x6B, 0x7B - "neg": 0x6C | # 0x6C - "retn": 0x6D | # 0x6D - "im 0": 0x6E | # 0x6E - "rld": 0x6F | # 0x6F - "in (C)": 0x70 | # 0x70 - "out (C), 0": 0x71 | # 0x71 - "neg": 0x74 | # 0x74 - "retn": 0x75 | # 0x75 - "im 1": 0x76 | # 0x76 - "in": 01 REG_A[111](3) 000 | # 0x78 - "out": 01 REG_A_OUT[111](3) 001 | # 0x79 - "neg": 0x7C | # 0x7C - "retn": 0x7D | # 0x7D - "im 2": 0x7E | # 0x7E - "ldi": 0xA0 | # 0xA0 - "cpi": 0xA1 | # 0xA1 - "ini": 0xA2 | # 0xA2 - "outi": 0xA3 | # 0xA3 - "ldd": 0xA8 | # 0xA8 - "cpd": 0xA9 | # 0xA9 - "ind": 0xAA | # 0xAA - "outd": 0xAB | # 0xAB - "ldir": 0xB0 | # 0xB0 - "cpir": 0xB1 | # 0xB1 - "inir": 0xB2 | # 0xB2 - "otir": 0xB3 | # 0xB3 - "lddr": 0xB8 | # 0xB8 - "cpdr": 0xB9 | # 0xB9 - "indr": 0xBA | # 0xBA - "otdr": 0xBB ; # 0xBB - -BC_DE_HL_SP = "BC": 00 | "DE": 01 | "HL": 10 | "SP": 11; -BC_DE_IX_SP = "BC": 00 | "DE": 01 | "IX": 10 | "SP": 11; -BC_DE_IY_SP = "BC": 00 | "DE": 01 | "IY": 10 | "SP": 11; - -BC_DE, REF_BC_DE_A, A_REF_BC_DE = "BC" : 0 | "DE" : 1; -HL_SP = "HL": 0 | "SP": 1; - -REG_B_C_D_E, REG_B_C_D_E_IIH, REG_B_C_D_E_IIL, REG_B_C_D_E_OUT = "B": 00 | "C": 01 | "D": 10 | "E": 11; -REG_H_L, REG_H_L_OUT = "H": 0 | "L": 1; -REG_A, REG_A_OUT = "A": 111; - -FLAGS_JR = "NZ": 00 | "Z": 01 | "NC": 10 | "C": 11; -FLAGS = "NZ": 000 | "Z": 001 | "NC": 010 | "C": 011 | "PO": 100 | "PE": 101 | "P": 110 | "M": 111; - -HL_AF = "HL" : 0 | "AF" : 1; -REG = "B": 000 | "C": 001 | "D": 010 | "E": 011 | "H": 100 | "L": 101 | "(HL)": 110 | "A": 111; - -NUMBER = "00": 000 | "08": 001 | "10": 010 | "18": 011 | "20": 100 | "28": 101 | "30": 110 | "38": 111; -imm8,REF_II_N,REF_II_N_2,REF_imm8_A,REF_imm8 = imm8: imm8(8); -BIT = bit: bit(3); -REF_imm16_HL, HL_REF_imm16, imm16, REF_imm16, REF_imm16_II, A_REF_imm16, REF_imm16_A = imm16: imm16(16); - + "%s (iy+%X), %s": 00 rot(3) 0 r_bcde(2) | # x=0, y=rot, z=0 r_bcde + "%s (iy+%X), %s": 00 rot(3) 10 r_h_l(1) | # x=0, y=rot, z=10 r_h_l + "%s (iy+%X), a": 00 rot(3) 111 | # x=0, y=rot, z=7 + "%s (iy+%X)": 00 rot(3) 110 | # x=0, y=rot, z=6 + "bit %X, (iy+%X)": 01 bit(3) any(3) | # x=1, y=bit, z=any + "res %X, (iy+%X), %s": 10 bit(3) 0 r_bcde(2) | # x=2, y=bit, z=0 r_bcde + "res %X, (iy+%X), %s": 10 bit(3) 10 r_h_l(1) | # x=2, y=bit, z=10 r_h_l + "res %X, (iy+%X), a": 10 bit(3) 111 | # x=2, y=bit, z=7 + "res %X, (iy+%X)": 10 bit(3) 110 | # x=2, y=bit, z=6 + "set %X, (iy+%X), %s": 11 bit(3) 0 r_bcde(2) | # x=3, y=bit, z=0 r_bcde + "set %X, (iy+%X), %s": 11 bit(3) 10 r_h_l(1) | # x=3, y=bit, z=10 r_h_l + "set %X, (iy+%X), a": 11 bit(3) 111 | # x=3, y=bit, z=7 + "set %X, (iy+%X)": 11 bit(3) 110 ; # x=3, y=bit, z=6 + + +cc_jr = + "nz": 00 | + "z": 01 | + "nc": 10 | + "c": 11 ; + +cc = + "nz": 000 | + "z": 001 | + "nc": 010 | + "c": 011 | + "po": 100 | + "pe": 101 | + "p": 110 | + "m": 111 ; + +rp = + "bc": 00 | + "de": 01 | + "hl": 10 | + "sp": 11 ; + +rp2 = + "bc": 00 | + "de": 01 | + "hl": 10 | + "af": 11 ; + +r = + "b": 000 | + "c": 001 | + "d": 010 | + "e": 011 | + "h": 100 | + "l": 101 | + "(hl)": 110 | + "a": 111 ; + +r_bcde = + "b": 00 | + "c": 01 | + "d": 10 | + "e": 11 ; + +r_h_l = + "h": 0 | + "l": 1 ; + +r_ixhl,r_ixhl2 = "ixh": 0 | "ixl": 1; +r_iyhl,r_iyhl2 = "iyh": 0 | "iyl": 1; + +r_no_hl = + "b": 000 | + "c": 001 | + "d": 010 | + "e": 011 | + "h": 100 | + "l": 101 | + "a": 111 ; + +alu = + "add a,": 000 | + "adc a,": 001 | + "sub": 010 | + "sbc a,": 011 | + "and": 100 | + "xor": 101 | + "or": 110 | + "cp": 111 ; + +rot = + "rlc": 000 | + "rrc": 001 | + "rl": 010 | + "rr": 011 | + "sla": 100 | + "sra": 101 | + "sll": 110 | + "srl": 111 ; + +im = + "0": 000 | + "0/1": 001 | + "1": 010 | + "2": 011 | + "0": 100 | + "0/1": 101 | + "1": 110 | + "2": 111 ; + +bit,any = bit: bit(3); +imm8,ref8,disp,disp2 = imm8: imm8(8); +imm16,ref16,ref16_2 = imm16: imm16(16); +rst = "00": 000 | "08": 001 | "10": 010 | "18": 011 | "20": 100 | "28": 101 | "30": 110 | "38": 111; +any2 = 00 | 01 | 10 | 11; %% -"%s %d, (IX + %X), %s" = ddcbInstruction BIT REF_II_N REG_B_C_D_E; -"%s %d, (IX + %X), %s" = ddcbInstruction BIT REF_II_N REG_H_L; -"%s %d, (IX + %X), %s" = ddcbInstruction BIT REF_II_N REG_A; - -"%s %d, (IY + %X), %s" = fdcbInstruction BIT REF_II_N REG_B_C_D_E; -"%s %d, (IY + %X), %s" = fdcbInstruction BIT REF_II_N REG_H_L; -"%s %d, (IY + %X), %s" = fdcbInstruction BIT REF_II_N REG_A; - -"%s (IX + %X), %s" = ddcbInstruction REF_II_N REG_B_C_D_E; -"%s (IX + %X), %s" = ddcbInstruction REF_II_N REG_H_L; -"%s (IX + %X), %s" = ddcbInstruction REF_II_N REG_A; -"%s %d, (IX + %X)" = ddcbInstruction BIT REF_II_N; - -"%s (IY + %X), %s" = fdcbInstruction REF_II_N REG_B_C_D_E; -"%s (IY + %X), %s" = fdcbInstruction REF_II_N REG_H_L; -"%s (IY + %X), %s" = fdcbInstruction REF_II_N REG_A; -"%s %d, (IY + %X)" = fdcbInstruction BIT REF_II_N; - -"%s %d, %s" = cbInstruction BIT REG; - -"%s (IX + %X), %X" = ddInstruction REF_II_N imm8; -"%s %s, (IX + %X)" = ddInstruction REG_B_C_D_E REF_II_N; -"%s (IX + %X), %s" = ddInstruction REF_II_N_2 REG_B_C_D_E; -"%s %s, (IX + %X)" = ddInstruction REG_H_L REF_II_N; -"%s (IX + %X), %s" = ddInstruction REF_II_N_2 REG_H_L; -"%s (IX + %X), %s" = ddInstruction REF_II_N_2 REG_A; - -"%s (IY + %X), %X" = fdInstruction REF_II_N imm8; -"%s %s, (IY + %X)" = fdInstruction REG_B_C_D_E REF_II_N; -"%s (IY + %X), %s" = fdInstruction REF_II_N_2 REG_B_C_D_E; -"%s %s, (IY + %X)" = fdInstruction REG_H_L REF_II_N; -"%s (IY + %X), %s" = fdInstruction REF_II_N_2 REG_H_L; -"%s (IY + %X), %s" = fdInstruction REF_II_N_2 REG_A; - -"%s (%X), %s" = edInstruction REF_imm16 BC_DE; -"%s (%X), %s" = edInstruction REF_imm16 HL_SP; -"%s %s, (%X)" = edInstruction BC_DE imm16; -"%s %s, (%X)" = edInstruction HL_SP imm16; - -"%s %s, %X" = instruction BC_DE_HL_SP imm16; -"%s %s, %s" = instruction REG_B_C_D_E REG; -"%s %s, %s" = instruction REG_H_L REG; -"%s %s, %X" = instruction REG imm8; -"%s %s, %X" = instruction FLAGS_JR imm8; -"%s %s, %X" = instruction FLAGS imm16; - -"%s (IX + %X)" = ddcbInstruction REF_II_N; -"%s (IY + %X)" = fdcbInstruction REF_II_N; - -"%s %s" = cbInstruction REG; - -"%s %s" = ddInstruction BC_DE_IX_SP; -"%s %X" = ddInstruction imm8; -"%s %X" = ddInstruction imm16; -"%s (%X)" = ddInstruction REF_imm16; -"%s (%X), IX" = ddInstruction REF_imm16_II; -"%s (IX + %X)" = ddInstruction REF_II_N; -"%s %s" = ddInstruction REG_B_C_D_E; -"%s %s, IXH" = ddInstruction REG_B_C_D_E_IIH; -"%s %s, IXL" = ddInstruction REG_B_C_D_E_IIL; - -"%s %s" = fdInstruction BC_DE_IY_SP; -"%s %X" = fdInstruction imm8; -"%s %X" = fdInstruction imm16; -"%s (%X)" = fdInstruction REF_imm16; -"%s (%X), IY" = fdInstruction REF_imm16_II; -"%s (IY + %X)" = fdInstruction REF_II_N; -"%s %s" = fdInstruction REG_B_C_D_E; -"%s %s, IYH" = fdInstruction REG_B_C_D_E_IIH; -"%s %s, IYL" = fdInstruction REG_B_C_D_E_IIL; - -"%s %s, (C)" = edInstruction REG_B_C_D_E; -"%s %s, (C)" = edInstruction REG_H_L; -"%s %s, (C)" = edInstruction REG_A; -"%s (C), %s" = edInstruction REG_B_C_D_E_OUT; -"%s (C), %s" = edInstruction REG_H_L_OUT; -"%s (C), %s" = edInstruction REG_A_OUT; -"%s %s" = edInstruction BC_DE; -"%s %s" = edInstruction HL_SP; - -"%s (%s), A" = instruction REF_BC_DE_A; -"%s A, (%s)" = instruction A_REF_BC_DE; -"%s %s" = instruction BC_DE_HL_SP; -"%s %s" = instruction REG_B_C_D_E; -"%s %s" = instruction REG; -"%s %X" = instruction imm8; -"%s A, (%X)" = instruction A_REF_imm16; -"%s (%X), A" = instruction REF_imm16_A; -"%s %s" = instruction BC_DE; -"%s %s" = instruction HL_AF; -"%s %s" = instruction REG_H_L; -"%s %X" = instruction imm16; -"%s %s" = instruction NUMBER; -"%s (%X), A" = instruction REF_imm8_A; -"%s (%X)" = instruction REF_imm8; -"%s (%X), HL" = instruction REF_imm16_HL; -"%s HL, (%X)" = instruction HL_REF_imm16; - -"%s" = edInstruction; -"%s" = fdInstruction; +"%s" = ddcbInstruction rot disp r_bcde; +"%s" = ddcbInstruction rot disp r_h_l; +"%s" = ddcbInstruction rot disp; +"%s" = ddcbInstruction bit disp any; +"%s" = ddcbInstruction bit disp r_bcde; +"%s" = ddcbInstruction bit disp r_h_l; +"%s" = ddcbInstruction bit disp; + +"%s" = fdcbInstruction rot disp r_bcde; +"%s" = fdcbInstruction rot disp r_h_l; +"%s" = fdcbInstruction rot disp; +"%s" = fdcbInstruction bit disp any; +"%s" = fdcbInstruction bit disp r_bcde; +"%s" = fdcbInstruction bit disp r_h_l; +"%s" = fdcbInstruction bit disp; + +"%s" = ddInstruction imm16; +"%s" = ddInstruction ref16; +"%s" = ddInstruction r_ixhl; +"%s" = ddInstruction disp; +"%s" = ddInstruction r_ixhl imm8; +"%s" = ddInstruction disp imm8; +"%s" = ddInstruction r_ixhl r_ixhl2; +"%s" = ddInstruction r_bcde disp; +"%s" = ddInstruction r_h_l disp; +"%s" = ddInstruction disp r_no_hl; +"%s" = ddInstruction alu r_ixhl; +"%s" = ddInstruction alu disp; "%s" = ddInstruction; + +"%s" = fdInstruction imm16; +"%s" = fdInstruction ref16; +"%s" = fdInstruction r_ixhl; +"%s" = fdInstruction disp; +"%s" = fdInstruction r_ixhl imm8; +"%s" = fdInstruction disp imm8; +"%s" = fdInstruction r_ixhl r_ixhl2; +"%s" = fdInstruction disp r_no_hl; +"%s" = fdInstruction r_bcde disp; +"%s" = fdInstruction r_h_l disp; +"%s" = fdInstruction alu r_ixhl; +"%s" = fdInstruction alu disp; +"%s" = fdInstruction; + +"%s" = instruction rp imm16; +"%s" = instruction rp ref16; +"%s" = instruction ref16_2 rp; +"%s" = instruction cc imm16; +"%s" = instruction cc_jr imm8; +"%s" = instruction r_bcde r; +"%s" = instruction r_h_l r; +"%s" = instruction r imm8; +"%s" = instruction alu r; +"%s" = instruction alu imm8; +"%s" = instruction rot r; +"%s" = instruction bit r; +"%s" = instruction r_bcde; +"%s" = instruction r_h_l; +"%s" = instruction imm8; +"%s" = instruction ref8; +"%s" = instruction imm16; +"%s" = instruction ref16; +"%s" = instruction rp; +"%s" = instruction rp2; +"%s" = instruction r; +"%s" = instruction r_no_hl; +"%s" = instruction cc; +"%s" = instruction im; +"%s" = instruction rst; "%s" = instruction; diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 360c49d1c..b3e49d8e0 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -141,7 +141,7 @@ CPU.RunState step() throws Exception { boolean oldIFF = IFF[0]; noWait = false; currentRunState = CPU.RunState.STATE_STOPPED_BREAK; - lastOpcode = readByte (PC); + lastOpcode = readByte(PC); PC = (PC + 1) & 0xFFFF; try { dispatch(); From daf61a4b5e39ae0e964190ce995ac6e336a6924b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 8 Mar 2022 08:11:52 +0000 Subject: [PATCH 112/314] [#201] small fixes --- .../device/mits88sio/ports/PhysicalPort.java | 10 ++-- .../device/mits88sio/TransmitterTest.java | 10 ++-- .../mits88sio/ports/PhysicalPortTest.java | 4 +- .../plugins/device/adm3a/DeviceImpl.java | 4 +- .../device/adm3a/interaction/Display.java | 10 ++-- .../device/adm3a/interaction/Keyboard.java | 4 +- .../adm3a/interaction/KeyboardFromFile.java | 14 ++--- .../device/adm3a/interaction/KeyboardGui.java | 16 ++--- .../adm3a/interaction/LoadCursorPosition.java | 4 +- .../plugins/device/simh/PseudoContext.java | 58 +++++++++---------- .../memory/bytemem/MemoryContextImpl.java | 8 +-- .../memory/bytemem/api/ByteMemoryContext.java | 4 +- 12 files changed, 73 insertions(+), 73 deletions(-) diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPort.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPort.java index 846d5403b..d973065a0 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPort.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPort.java @@ -28,7 +28,7 @@ *

* For example, a terminal would use this port for communication. */ -public class PhysicalPort implements DeviceContext { +public class PhysicalPort implements DeviceContext { private final Transmitter transmitter; public PhysicalPort(Transmitter transmitter) { @@ -36,18 +36,18 @@ public PhysicalPort(Transmitter transmitter) { } @Override - public Short readData() { + public Byte readData() { return 0; // Attached device cannot read back what it already wrote } @Override - public void writeData(Short data) { + public void writeData(Byte data) { transmitter.writeFromDevice(data); } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } } diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/TransmitterTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/TransmitterTest.java index 97220ceee..32229a94c 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/TransmitterTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/TransmitterTest.java @@ -57,14 +57,14 @@ public void testWriteToStatus0x03OnEmptyBufferSetStatusTo0x02() { @Test public void testWriteFromDeviceSetsInputDeviceReady() { Transmitter transmitter = new Transmitter(); - transmitter.writeFromDevice((short) 5); + transmitter.writeFromDevice((byte) 5); assertEquals(1, transmitter.readStatus() & 0x01); } @Test public void testReadBufferResetInputDeviceReady() { Transmitter transmitter = new Transmitter(); - transmitter.writeFromDevice((short) 5); + transmitter.writeFromDevice((byte) 5); assertEquals(5, transmitter.readBuffer()); assertEquals(0, transmitter.readStatus() & 0x01); @@ -73,9 +73,9 @@ public void testReadBufferResetInputDeviceReady() { @Test public void testBufferIsFIFO() { Transmitter transmitter = new Transmitter(); - transmitter.writeFromDevice((short) 1); - transmitter.writeFromDevice((short) 2); - transmitter.writeFromDevice((short) 3); + transmitter.writeFromDevice((byte) 1); + transmitter.writeFromDevice((byte) 2); + transmitter.writeFromDevice((byte) 3); assertEquals(1, transmitter.readBuffer()); assertEquals(2, transmitter.readBuffer()); diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPortTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPortTest.java index 98c947f24..c952d2ed8 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPortTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPortTest.java @@ -46,12 +46,12 @@ public void testReadReturnsZero() { @Test public void testWriteCallsWriteFromDeviceOnTransmitter() { Transmitter transmitter = EasyMock.createMock(Transmitter.class); - transmitter.writeFromDevice(eq((short) 5)); + transmitter.writeFromDevice(eq((byte) 5)); expectLastCall().once(); replay(transmitter); PhysicalPort port = new PhysicalPort(transmitter); - port.writeData((short) 5); + port.writeData((byte) 5); verify(transmitter); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index 2fda02df4..34451157f 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -83,8 +83,8 @@ public void initialize() throws PluginInitializationException { // try to connect to a serial I/O board try { - DeviceContext device = applicationApi.getContextPool().getDeviceContext(pluginID, DeviceContext.class); - if (device.getDataType() != Short.class) { + DeviceContext device = applicationApi.getContextPool().getDeviceContext(pluginID, DeviceContext.class); + if (device.getDataType() != Byte.class) { throw new PluginInitializationException( "Unexpected device data type. Expected Short but was: " + device.getDataType() ); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java index 0aa10661e..a703ac320 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java @@ -41,7 +41,7 @@ * Terminal can interpret ASCII codes from 0-127. Some have special purpose (0-31). */ @PluginContext(id = "LSI ADM-3A Terminal") -public class Display extends JPanel implements DeviceContext, TerminalSettings.ChangedObserver, Cursor.LineRoller, ActionListener { +public class Display extends JPanel implements DeviceContext, TerminalSettings.ChangedObserver, Cursor.LineRoller, ActionListener { private static final Logger LOGGER = LoggerFactory.getLogger(Display.class); private static final String HERE_IS_CONSTANT = Display.class.getAnnotation(PluginContext.class).id(); @@ -99,7 +99,7 @@ public Display(Cursor cursor, TerminalSettings settings) { * @return 0 */ @Override - public Short readData() { + public Byte readData() { return 0; } @@ -194,7 +194,7 @@ public void rollLine() { * This method is called from serial I/O card (by OUT instruction) */ @Override - public void writeData(Short data) { + public void writeData(Byte data) { writeToOutput(data); /* * if it is special char, interpret it. else just add to "video memory" @@ -240,8 +240,8 @@ public void writeData(Short data) { } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } private void insertHereIs() { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Keyboard.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Keyboard.java index 1cfd3d80f..a2e38e811 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Keyboard.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Keyboard.java @@ -22,9 +22,9 @@ public interface Keyboard { - void connect(DeviceContext observer); + void connect(DeviceContext observer); - void disconnect(DeviceContext observer); + void disconnect(DeviceContext observer); default void process() { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java index 750aba781..502207fcf 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java @@ -33,7 +33,7 @@ public class KeyboardFromFile implements Keyboard { private final static Logger LOGGER = LoggerFactory.getLogger(KeyboardFromFile.class); - private final List> devices = new CopyOnWriteArrayList<>(); + private final List> devices = new CopyOnWriteArrayList<>(); private final Path inputFile; private final int delayInMilliseconds; @@ -43,12 +43,12 @@ public KeyboardFromFile(Path inputFile, int delayInMilliseconds) { } @Override - public void connect(DeviceContext device) { + public void connect(DeviceContext device) { Optional.ofNullable(device).ifPresent(devices::add); } @Override - public void disconnect(DeviceContext device) { + public void disconnect(DeviceContext device) { Optional.ofNullable(device).ifPresent(devices::remove); } @@ -58,7 +58,7 @@ public void process() { try (InputStream input = new FileInputStream(inputFile.toFile())) { int key; while ((key = input.read()) != -1) { - inputReceived((short) key); + inputReceived(key); if (delayInMilliseconds > 0) { LockSupport.parkNanos(delayInMilliseconds * 1000000L); } @@ -68,10 +68,10 @@ public void process() { } } - private void inputReceived(short input) { - for (DeviceContext device : devices) { + private void inputReceived(int input) { + for (DeviceContext device : devices) { try { - device.writeData(input); + device.writeData((byte)input); } catch (IOException e) { LOGGER.error("[device={}, input={}] Could not notify device about key pressed", device, input, e); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java index 7f06741a9..8e0a6b7a4 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java @@ -105,7 +105,7 @@ public class KeyboardGui extends KeyAdapter implements ContainerListener, Keyboa CONTROL_KEYCODES_ALWAYS_ACTIVE[KeyEvent.VK_ENTER] = 13; } - private final List> devices = new ArrayList<>(); + private final List> devices = new ArrayList<>(); private final LoadCursorPosition loadCursorPosition; public KeyboardGui(Cursor cursor) { @@ -142,8 +142,8 @@ public void keyPressed(KeyEvent evt) { } } if (newKeyCode != 0) { - if (loadCursorPosition.notAccepted((short) newKeyCode)){ - inputReceived((short) newKeyCode); + if (loadCursorPosition.notAccepted((byte)newKeyCode)){ + inputReceived(newKeyCode); } } } @@ -159,12 +159,12 @@ public void componentRemoved(ContainerEvent e) { } @Override - public void connect(DeviceContext device) { + public void connect(DeviceContext device) { devices.add(device); } @Override - public void disconnect(DeviceContext device) { + public void disconnect(DeviceContext device) { devices.remove(device); } @@ -173,10 +173,10 @@ public void destroy() { devices.clear(); } - private void inputReceived(short input) { - for (DeviceContext device : devices) { + private void inputReceived(int input) { + for (DeviceContext device : devices) { try { - device.writeData(input); + device.writeData((byte)input); } catch (IOException e) { LOGGER.error("[device={}, input={}] Could not notify device about key pressed", device, input, e); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java index 026e7e22e..4e0638749 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java @@ -48,11 +48,11 @@ public LoadCursorPosition(Cursor cursor) { * @param data received char * @return true if in bounds */ - private boolean checkBounds(Short data) { + private boolean checkBounds(Byte data) { return data >= ' ' && data <= 'o'; } - boolean notAccepted(Short data) { + boolean notAccepted(Byte data) { if (expect == ESCAPE && data == ASCII_ESC) { expect = ASSIGN; return false; diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java index 4174e77c6..635e0a133 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java @@ -26,7 +26,7 @@ import java.io.File; import java.util.Calendar; -class PseudoContext implements DeviceContext { +class PseudoContext implements DeviceContext { private final static Logger LOGGER = LoggerFactory.getLogger(PseudoContext.class); private ByteMemoryContext mem; @@ -270,8 +270,8 @@ private void setClockCPM3() { } @Override - public Short readData() { - short result = 0; + public Byte readData() { + int result = 0; switch (lastCommand) { case getHostFilenames: LOGGER.trace("[command={},name=getHostFilenames] Unimplemented command!", lastCommand); @@ -289,27 +289,27 @@ public Short readData() { switch (getClockZSDOSPos) { case 0: int year = (currentTime.get(Calendar.YEAR) - 1900); - result = (short) toBCD(year > 99 ? year - 100 : year); + result = toBCD(year > 99 ? year - 100 : year); getClockZSDOSPos = 1; break; case 1: - result = (short) toBCD(currentTime.get(Calendar.MONTH) + 1); + result = toBCD(currentTime.get(Calendar.MONTH) + 1); getClockZSDOSPos = 2; break; case 2: - result = (short) toBCD(currentTime.get(Calendar.DAY_OF_MONTH)); + result = toBCD(currentTime.get(Calendar.DAY_OF_MONTH)); getClockZSDOSPos = 3; break; case 3: - result = (short) toBCD(currentTime.get(Calendar.HOUR_OF_DAY)); + result = toBCD(currentTime.get(Calendar.HOUR_OF_DAY)); getClockZSDOSPos = 4; break; case 4: - result = (short) toBCD(currentTime.get(Calendar.MINUTE)); + result = toBCD(currentTime.get(Calendar.MINUTE)); getClockZSDOSPos = 5; break; case 5: - result = (short) toBCD(currentTime.get(Calendar.SECOND)); + result = toBCD(currentTime.get(Calendar.SECOND)); getClockZSDOSPos = lastCommand = 0; break; } @@ -321,23 +321,23 @@ public Short readData() { if (currentTimeValid) { switch (getClockCPM3Pos) { case 0: - result = (short) (daysCPM3SinceOrg & 0xff); + result = daysCPM3SinceOrg & 0xff; getClockCPM3Pos = 1; break; case 1: - result = (short) ((daysCPM3SinceOrg >> 8) & 0xff); + result = (daysCPM3SinceOrg >> 8) & 0xff; getClockCPM3Pos = 2; break; case 2: - result = (short) toBCD(currentTime.get(Calendar.HOUR_OF_DAY)); + result = toBCD(currentTime.get(Calendar.HOUR_OF_DAY)); getClockCPM3Pos = 3; break; case 3: - result = (short) toBCD(currentTime.get(Calendar.MINUTE)); + result = toBCD(currentTime.get(Calendar.MINUTE)); getClockCPM3Pos = 4; break; case 4: - result = (short) toBCD(currentTime.get(Calendar.SECOND)); + result = toBCD(currentTime.get(Calendar.SECOND)); getClockCPM3Pos = lastCommand = 0; break; } @@ -357,62 +357,62 @@ public Short readData() { break; case getCommonCmd: if (getCommonPos == 0) { - result = (short) (mem.getCommonBoundary() & 0xff); + result = mem.getCommonBoundary() & 0xff; getCommonPos = 1; } else { - result = (short) ((mem.getCommonBoundary() >> 8) & 0xff); + result = (mem.getCommonBoundary() >> 8) & 0xff; getCommonPos = lastCommand = 0; } break; case hasBankedMemoryCmd: - result = (short) mem.getBanksCount(); + result = mem.getBanksCount(); lastCommand = 0; break; case readStopWatchCmd: if (getStopWatchDeltaPos == 0) { - result = (short) (stopWatchDelta & 0xff); + result = stopWatchDelta & 0xff; getStopWatchDeltaPos = 1; } else { - result = (short) ((stopWatchDelta >> 8) & 0xff); + result = (stopWatchDelta >> 8) & 0xff; getStopWatchDeltaPos = lastCommand = 0; } break; case getHostOSPathSeparator: - result = (short) File.separatorChar; + result = File.separatorChar; break; default: /* undefined */ LOGGER.debug("[command={}] Unknown command!", lastCommand); result = lastCommand = 0; } - return result; + return (byte)result; } @Override - public void writeData(Short data) { + public void writeData(Byte data) { long now; switch (lastCommand) { case setClockZSDOSCmd: if (setClockZSDOSPos == 0) { - setClockZSDOSAdr = data; + setClockZSDOSAdr = data & 0xFF; setClockZSDOSPos = 1; } else { - setClockZSDOSAdr |= (data << 8); + setClockZSDOSAdr |= (data << 8) & 0xFF00; setClockZSDOS(); setClockZSDOSPos = lastCommand = 0; } break; case setClockCPM3Cmd: if (setClockCPM3Pos == 0) { - setClockCPM3Adr = data; + setClockCPM3Adr = data & 0xFF; setClockCPM3Pos = 1; } else { - setClockCPM3Adr |= (data << 8); + setClockCPM3Adr |= (data << 8) & 0xFF00; setClockCPM3(); setClockCPM3Pos = lastCommand = 0; } break; case setBankSelectCmd: - mem.selectBank((short) (data & 0xff)); + mem.selectBank(data & 0xff); lastCommand = 0; break; case setTimerDeltaCmd: @@ -536,7 +536,7 @@ public void writeData(Short data) { } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java index f44e3a344..c1799d426 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java @@ -46,7 +46,7 @@ public MemoryContextImpl(Dialogs dialogs) { int lastImageStart = 0; private Byte[][] mem = new Byte[1][0]; private int banksCount; - private short bankSelect = 0; + private int bankSelect = 0; private int bankCommon = 0; void init(int size, int banks, int bankCommon) { @@ -80,12 +80,12 @@ public int getBanksCount() { } @Override - public short getSelectedBank() { + public int getSelectedBank() { return bankSelect; } @Override - public void selectBank(short bankSelect) { + public void selectBank(int bankSelect) { if (bankSelect < banksCount) { this.bankSelect = bankSelect; } @@ -97,7 +97,7 @@ public int getCommonBoundary() { } public void loadHex(Path hexFile, int bank) { - short currentBank = bankSelect; + int currentBank = bankSelect; try { bankSelect = (short) bank; lastImageStart = IntelHEX.loadIntoMemory(hexFile.toFile(), this, p -> p); diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java index 529eb97ad..f27495b32 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java @@ -82,14 +82,14 @@ interface AddressRange { * * @return index of active (selected) memory bank */ - short getSelectedBank(); + int getSelectedBank(); /** * Select (set as active) a memory bank. * * @param bankIndex index (number) of a bank which should be selected */ - void selectBank(short bankIndex); + void selectBank(int bankIndex); /** * Return an address in the memory which represents a boundary from which From 33805d2997093af2ce2389c0ffe4d36bdc1ba61b Mon Sep 17 00:00:00 2001 From: Paolo Amoroso Date: Fri, 11 Mar 2022 14:16:05 +0100 Subject: [PATCH 113/314] New sample program Add a twirling bar animation 8080 demo. --- .../as-8080/src/main/examples/twirl.asm | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 plugins/compiler/as-8080/src/main/examples/twirl.asm diff --git a/plugins/compiler/as-8080/src/main/examples/twirl.asm b/plugins/compiler/as-8080/src/main/examples/twirl.asm new file mode 100644 index 000000000..60c3d9681 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/examples/twirl.asm @@ -0,0 +1,38 @@ +; Twirling bar animation by Paolo Amoroso +; +; Runs on an Altair 8800 with an ADM-3A terminal. To interrupt +; the program click "Stop emulation". + + +FRAMES equ 8 ; Number of animation frames + +CLS equ 1ah ; ADM-3A escape sequence +HOME equ 1eh ; ADM-3A escape sequence + + + mvi a, CLS ; Clear screen + call putchar + +loop: lxi h, ANIM + mvi b, FRAMES + +loop1: mvi a, HOME ; Go to home + call putchar + + mov a, m ; Print current frame + push h + call putchar + + inx h + dcr b + jnz loop1 + + jmp loop + + hlt + + +ANIM: db '|/-\|/-\' ; 8 frames + + +include 'include\putchar.inc' From 0e7a611dc3c2ed82029a58b0799b79bd560d9cbb Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 11 Mar 2022 18:08:49 +0000 Subject: [PATCH 114/314] [#201] as-z80 fixes --- .../application/gui/editor/RTokenMaker.java | 1 + build.gradle | 4 +- .../as-z80/src/main/antlr/AsZ80Lexer.g4 | 4 +- .../as-z80/src/main/antlr/AsZ80Parser.g4 | 15 +- .../compiler/as-z80/src/main/cup/parser.cup | 952 ------------------ .../compiler/asZ80/LexicalAnalyzerImpl.java | 17 +- .../asZ80/visitors/CreatePseudoVisitor.java | 10 +- .../asZ80/parser/LexicalAnalyzerImplTest.java | 8 +- .../plugins/cpu/zilogZ80/ControlTest.java | 2 +- .../plugins/cpu/zilogZ80/IOTest.java | 2 +- .../plugins/device/mits88dcdd/DriveTest.java | 12 +- 11 files changed, 47 insertions(+), 980 deletions(-) delete mode 100644 plugins/compiler/as-z80/src/main/cup/parser.cup diff --git a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java index ebc1d1583..466b9a18a 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java @@ -51,6 +51,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { addToken(text, start, end, tokenMakerType, tokenStartOffset); } catch (Exception ignored) { + ignored.printStackTrace(); } } diff --git a/build.gradle b/build.gradle index 39c44e195..dee80a043 100644 --- a/build.gradle +++ b/build.gradle @@ -41,8 +41,8 @@ ext.libs = [ args4j : "args4j:args4j:2.33", tomlj : "com.electronwill.night-config:toml:3.6.3", - editor : "com.fifesoft:rsyntaxtextarea:3.1.2", - editorDialogs : "com.fifesoft:rstaui:3.1.1", + editor : "com.fifesoft:rsyntaxtextarea:3.1.6", + editorDialogs : "com.fifesoft:rstaui:3.1.4", junit : "junit:junit:4.13", easyMock : "org.easymock:easymock:4.2", diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 index 7958411bf..ef81013b2 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 @@ -1,7 +1,7 @@ lexer grammar AsZ80Lexer; -COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]* -> skip; -COMMENT2: '/*' .*? '*/' -> skip; +COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]*; +COMMENT2: '/*' .*? '*/'; fragment A: [aA]; fragment B: [bB]; diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 index 3ae64c890..b7aaba9d9 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 @@ -5,12 +5,21 @@ options { } rStart: - EOL* rLine? (EOL+ rLine)* EOL* EOF + (rLine EOL rLine)* EOF + | rLine EOF ; +//rStart: +// EOL* rLine? (EOL+ rLine)* EOL* EOF +// ; + rLine: - label=ID_LABEL? EOL* statement=rStatement - | label=ID_LABEL; + label=ID_LABEL? (comment EOL)* statement=rStatement comment + | label=ID_LABEL comment + | comment + ; + +comment: COMMENT? | COMMENT2?; rStatement: instr=rInstruction diff --git a/plugins/compiler/as-z80/src/main/cup/parser.cup b/plugins/compiler/as-z80/src/main/cup/parser.cup deleted file mode 100644 index fc79aaafe..000000000 --- a/plugins/compiler/as-z80/src/main/cup/parser.cup +++ /dev/null @@ -1,952 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.asZ80; - -import java_cup.runtime.DefaultSymbolFactory; -import java_cup.runtime.Symbol; -import net.emustudio.emulib.plugins.compiler.CompilerMessage; -import net.emustudio.emulib.plugins.compiler.Token; -import net.emustudio.plugins.compiler.asZ80.tree.*; -import net.emustudio.plugins.compiler.asZ80.treeAbstract.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; -import java_cup.runtime.XMLElement; - -init with {: lastLine = 0; lastColumn = 0; :} -scan with {: - Token t = (Token)this.getScanner().next_token(); - this.lastLine = t.getLine()+1; - this.lastColumn = t.getColumn()+1; - return (Symbol)t; - :} -parser code {: - private CompilerImpl compiler; // cannot be final because cup generates garbage constructors - private boolean syntaxErrors; - private int lastLine; - private int lastColumn; - private String reportPrefixString; - - public ParserImpl(LexerImpl lexer, CompilerImpl compiler) { - super(lexer, new DefaultSymbolFactory()); - this.compiler = Objects.requireNonNull(compiler); - } - - public void reset() { - syntaxErrors = false; - } - - @Override - public void report_fatal_error(String message, Object info) throws Exception { - done_parsing(); - report_error(message, info); - throw new Exception("Can't recover from previous error(s)"); - } - - @Override - public void report_error(String messageText, Object current) { - syntaxErrors = true; - - Token token = (Token)current; - - if (reportPrefixString != null) { - messageText = reportPrefixString + messageText + ":" + token.getErrorString() + " ('" + token.getText() + "')"; - } else { - messageText += ":" + token.getErrorString() + " ('" + token.getText() + "')"; - } - - List expectedTokenIds = expected_token_ids() - .stream() - .map(this::symbl_name_from_id) - .collect(Collectors.toList()); - - if (!expectedTokenIds.isEmpty()) { - messageText += "\nExpected tokens: " + expectedTokenIds; - } - - CompilerMessage message = new CompilerMessage( - CompilerMessage.MessageType.TYPE_ERROR, messageText, token.getLine()+1, token.getColumn() - ); - - compiler.notifyOnMessage(message); - } - - public boolean hasSyntaxErrors() { - return syntaxErrors; - } - - public void setReportPrefixString(String str) { - this.reportPrefixString = str; - } -:} - -terminal RESERVED_ADC,RESERVED_ADD,RESERVED_AND,RESERVED_BIT,RESERVED_CALL, - RESERVED_CCF,RESERVED_CP,RESERVED_CPD,RESERVED_CPDR,RESERVED_CPI, - RESERVED_CPIR,RESERVED_CPL,RESERVED_DAA,RESERVED_DEC,RESERVED_DI, - RESERVED_DJNZ,RESERVED_EI,RESERVED_EX,RESERVED_EXX,RESERVED_HALT, - RESERVED_IM,RESERVED_IN,RESERVED_INC,RESERVED_IND,RESERVED_INDR, - RESERVED_INI,RESERVED_INIR,RESERVED_JP,RESERVED_JR,RESERVED_LD, - RESERVED_LDD,RESERVED_LDDR,RESERVED_LDI,RESERVED_LDIR,RESERVED_NEG, - RESERVED_NOP,RESERVED_OR,RESERVED_OTDR,RESERVED_OTIR,RESERVED_OUT, - RESERVED_OUTD,RESERVED_OUTI,RESERVED_POP,RESERVED_PUSH,RESERVED_RES, - RESERVED_RET,RESERVED_RETI,RESERVED_RETN,RESERVED_RL,RESERVED_RLA, - RESERVED_RLC,RESERVED_RLCA,RESERVED_RLD,RESERVED_RR,RESERVED_RRA, - RESERVED_RRC,RESERVED_RRCA,RESERVED_RRD,RESERVED_RST,RESERVED_SBC, - RESERVED_SCF,RESERVED_SET,RESERVED_SLA,RESERVED_SRA,RESERVED_SLL, - RESERVED_SRL,RESERVED_SUB,RESERVED_XOR, - RESERVED_C,RESERVED_NC,RESERVED_Z,RESERVED_NZ,RESERVED_M,RESERVED_P, - RESERVED_PE,RESERVED_PO; -terminal PREPROCESSOR_ORG,PREPROCESSOR_EQU,PREPROCESSOR_VAR, - PREPROCESSOR_IF,PREPROCESSOR_ENDIF,PREPROCESSOR_MACRO,PREPROCESSOR_ENDM, - PREPROCESSOR_DB,PREPROCESSOR_DW,PREPROCESSOR_DS,PREPROCESSOR_ADDR, - PREPROCESSOR_INCLUDE; -terminal REGISTERS_A,REGISTERS_B,REGISTERS_C,REGISTERS_D,REGISTERS_E, - REGISTERS_H,REGISTERS_L,REGISTERS_IX,REGISTERS_IY,REGISTERS_SP, - REGISTERS_BC,REGISTERS_DE,REGISTERS_HL,REGISTERS_AF,REGISTERS_AFF, - REGISTERS_I,REGISTERS_R; -terminal SEPARATOR_LPAR,SEPARATOR_RPAR,SEPARATOR_COMMA,SEPARATOR_EOL,SEPARATOR_INDEXLPAR; -terminal OPERATOR_ADD,OPERATOR_SUBTRACT,OPERATOR_MULTIPLY,OPERATOR_DIVIDE, - OPERATOR_MOD,OPERATOR_SHR,OPERATOR_SHL,OPERATOR_NOT, - OPERATOR_AND,OPERATOR_OR,OPERATOR_XOR,OPERATOR_EQUAL, - OPERATOR_LESS,OPERATOR_GREATER,OPERATOR_LE,OPERATOR_GE; -terminal Integer LITERAL_DECIMAL_8BIT,LITERAL_DECIMAL_16BIT; -terminal String LITERAL_STRING,TLABEL,TIDENTIFIER; -terminal TCOMMENT; - -non terminal Program Program; -non terminal Row Row; -non terminal Label Label; -non terminal Statement Statement; -non terminal DataNode Datadef,DBList,DWList; -non terminal Instruction Codedef; -non terminal Pseudo Pseudo; -non terminal DataDB DBData; -non terminal DataDW DWData; -non terminal Comment; -non terminal InstrData Instruction; -non terminal Expression Expression,Primarny; -non terminal Integer BinaryOperator,UnaryOperator; -non terminal List MacroOperands,MacroParameters,MacroParamsList,MacroOperList; -non terminal Integer Reg,RegWA,RegRR,RegRY,RegRX,CondCC,CondCond,RegQQ; -non terminal Integer RegRR_WSP; - -precedence left OPERATOR_OR,OPERATOR_XOR; -precedence left OPERATOR_AND; -precedence left OPERATOR_NOT; -precedence nonassoc OPERATOR_EQUAL,OPERATOR_LESS,OPERATOR_GREATER,OPERATOR_LE,OPERATOR_GE; -precedence left OPERATOR_ADD,OPERATOR_SUBTRACT; -precedence left OPERATOR_MULTIPLY,OPERATOR_DIVIDE,OPERATOR_MOD,OPERATOR_SHL, - OPERATOR_SHR; - -start with Program; - -Program ::= Row:row - {: - Program program = new Program(); - if (row != null) program.addRow(row); - RESULT = program; - :}| - Program:program SEPARATOR_EOL Row:row - {: - if (row != null) program.addRow(row); - RESULT = program; - :}| - Program:program error - {: parser.syntaxErrors = true; RESULT = program; :}; - -Row ::= Label:label Statement:stmt Comment - {: - if ((label == null) && (stmt == null)) RESULT = null; - else RESULT = new Row(label,stmt); - :}; - -Label ::= TLABEL:name - {: RESULT = new Label(name,parser.lastLine,parser.lastColumn); :}| - {: RESULT = null; :}; - -Comment ::= TCOMMENT | ; -Statement ::= Instruction:instr - {: RESULT = instr; :}| - Pseudo:pseudo - {: RESULT = pseudo; :}| - {: RESULT = null; :}; - -Instruction ::= Datadef:data - {: RESULT = data; :}| - Codedef:code - {: RESULT = code; :}; - -Datadef ::= PREPROCESSOR_DB DBList:dblist - {: RESULT = dblist; :}| - PREPROCESSOR_DW DWList:dwlist - {: RESULT = dwlist; :}| - PREPROCESSOR_DS Expression:e - {: - DataNode dn = new DataNode(parser.lastLine,parser.lastColumn); - dn.addElement(new DataDS(e,parser.lastLine,parser.lastColumn)); - RESULT= dn; - :}; - -DBList ::= DBData:dbdata - {: - DataNode dn = new DataNode(parser.lastLine,parser.lastColumn); - dn.addElement(dbdata); - RESULT = dn; - :}| - DBList:dblist SEPARATOR_COMMA DBData:dbdata - {: dblist.addElement(dbdata); RESULT = dblist; :}; - -DWList ::= DWData:dwdata - {: - DataNode dn = new DataNode(parser.lastLine,parser.lastColumn); - dn.addElement(dwdata); - RESULT = dn; - :}| - DWList:dwlist SEPARATOR_COMMA DWData:dwdata - {: dwlist.addElement(dwdata); RESULT = dwlist; :}; - -DBData ::= Expression:e - {: RESULT = new DataDB(e,parser.lastLine,parser.lastColumn); :}| - LITERAL_STRING:str - {: RESULT = new DataDB(str,parser.lastLine,parser.lastColumn); :}| - Codedef:code - {: RESULT = new DataDB(code,parser.lastLine,parser.lastColumn); :}; - -DWData ::= Expression:e - {: RESULT = new DataDW(e,parser.lastLine,parser.lastColumn); :}; - - -Expression ::= SEPARATOR_LPAR Expression:e SEPARATOR_RPAR - {: RESULT = e; :}| - Primarny:e - {: RESULT = e; :}; - -Primarny ::= Expression:e1 BinaryOperator:op Expression:e2 - {: RESULT = new Arithmetic(e1,e2,op); :}| - UnaryOperator:op Expression:e - {: RESULT = new Arithmetic(e,null,op); :}| - LITERAL_DECIMAL_8BIT:n - {: RESULT = new DecimalExpr(n); :}| - LITERAL_DECIMAL_16BIT:n - {: RESULT = new DecimalExpr(n); :}| - PREPROCESSOR_ADDR - {: RESULT = new Address(); :}| - TIDENTIFIER:name - {: RESULT = new Identifier(name,parser.lastLine,parser.lastColumn); :}; - -UnaryOperator ::= OPERATOR_NOT - {: RESULT = Arithmetic.NOT; :}| - OPERATOR_ADD - {: RESULT = Arithmetic.ADD; :}| - OPERATOR_SUBTRACT - {: RESULT = Arithmetic.MINUS; :}; - -BinaryOperator ::= OPERATOR_OR - {: RESULT = Arithmetic.OR; :}| - OPERATOR_XOR - {: RESULT = Arithmetic.XOR; :}| - OPERATOR_AND - {: RESULT = Arithmetic.AND; :}| - OPERATOR_EQUAL - {: RESULT = Arithmetic.EQ; :}| - OPERATOR_LESS - {: RESULT = Arithmetic.LESS; :}| - OPERATOR_GREATER - {: RESULT = Arithmetic.GREATER; :}| - OPERATOR_LE - {: RESULT = Arithmetic.LE; :}| - OPERATOR_GE - {: RESULT = Arithmetic.GE; :}| - OPERATOR_ADD - {: RESULT = Arithmetic.ADD; :}| - OPERATOR_SUBTRACT - {: RESULT = Arithmetic.MINUS; :}| - OPERATOR_MULTIPLY - {: RESULT = Arithmetic.MUL; :}| - OPERATOR_DIVIDE - {: RESULT = Arithmetic.DIV; :}| - OPERATOR_MOD - {: RESULT = Arithmetic.MOD; :}| - OPERATOR_SHR - {: RESULT = Arithmetic.SHR; :}| - OPERATOR_SHL - {: RESULT = Arithmetic.SHL; :}; - -Pseudo ::= PREPROCESSOR_ORG Expression:e - {: RESULT = new PseudoORG(e,parser.lastLine, parser.lastColumn); :}| - TIDENTIFIER:name PREPROCESSOR_EQU Expression:e - {: RESULT = new PseudoEQU(name,e,parser.lastLine, parser.lastColumn); :}| - TIDENTIFIER:name PREPROCESSOR_VAR Expression:e - {: RESULT = new PseudoVAR(name,e,parser.lastLine, parser.lastColumn); :}| - PREPROCESSOR_IF Expression:e Comment SEPARATOR_EOL Program:s SEPARATOR_EOL PREPROCESSOR_ENDIF - {: RESULT = new PseudoIF(e,s,parser.lastLine, parser.lastColumn); :}| - TIDENTIFIER:name PREPROCESSOR_MACRO MacroOperands:opers Comment SEPARATOR_EOL Program:s PREPROCESSOR_ENDM - {: RESULT = new PseudoMACRO(name,opers,s,parser.lastLine, parser.lastColumn); :}| - TIDENTIFIER:name MacroParameters:params - {: RESULT = new PseudoMACROCall(name,params,parser.lastLine, parser.lastColumn); :}| - PREPROCESSOR_INCLUDE LITERAL_STRING:filename - {: RESULT = new PseudoINCLUDE(filename,parser.lastLine,parser.lastColumn, parser.compiler); :}; - -MacroOperands ::= MacroOperList:operands - {: RESULT = operands; :}| - {: RESULT = null; :}; - -MacroOperList ::= TIDENTIFIER:name - {: - List vec = new ArrayList(); - vec.add(name); - RESULT = vec; - :}| - MacroOperList:operands SEPARATOR_COMMA TIDENTIFIER:name - {: operands.add(name); RESULT = operands; :}; - -MacroParameters ::= MacroParamsList:parameters - {: RESULT = parameters; :}| - {: RESULT = null; :}; - -MacroParamsList ::= Expression:e - {: - List vec = new ArrayList(); - vec.add(e); - RESULT = vec; - :}| - MacroParamsList:parameters SEPARATOR_COMMA Expression:e - {: parameters.add(e); RESULT = parameters; :}; - -Codedef ::= RESERVED_CCF - {: RESULT = new OC_NoParams(OC_NoParams.CCF,parser.lastLine,parser.lastColumn); :}| - RESERVED_CPD - {: RESULT = new OC_NoParams(OC_NoParams.CPD,parser.lastLine,parser.lastColumn); :}| - RESERVED_CPDR - {: RESULT = new OC_NoParams(OC_NoParams.CPDR,parser.lastLine,parser.lastColumn); :}| - RESERVED_CPI - {: RESULT = new OC_NoParams(OC_NoParams.CPI,parser.lastLine,parser.lastColumn); :}| - RESERVED_CPIR - {: RESULT = new OC_NoParams(OC_NoParams.CPIR,parser.lastLine,parser.lastColumn); :}| - RESERVED_CPL - {: RESULT = new OC_NoParams(OC_NoParams.CPL,parser.lastLine,parser.lastColumn); :}| - RESERVED_DAA - {: RESULT = new OC_NoParams(OC_NoParams.DAA,parser.lastLine,parser.lastColumn); :}| - RESERVED_DI - {: RESULT = new OC_NoParams(OC_NoParams.DI,parser.lastLine,parser.lastColumn); :}| - RESERVED_EI - {: RESULT = new OC_NoParams(OC_NoParams.EI,parser.lastLine,parser.lastColumn); :}| - RESERVED_EXX - {: RESULT = new OC_NoParams(OC_NoParams.EXX,parser.lastLine,parser.lastColumn); :}| - RESERVED_HALT - {: RESULT = new OC_NoParams(OC_NoParams.HALT,parser.lastLine,parser.lastColumn); :}| - RESERVED_IND - {: RESULT = new OC_NoParams(OC_NoParams.IND,parser.lastLine,parser.lastColumn); :}| - RESERVED_INDR - {: RESULT = new OC_NoParams(OC_NoParams.INDR,parser.lastLine,parser.lastColumn); :}| - RESERVED_INI - {: RESULT = new OC_NoParams(OC_NoParams.INI,parser.lastLine,parser.lastColumn); :}| - RESERVED_INIR - {: RESULT = new OC_NoParams(OC_NoParams.INIR,parser.lastLine,parser.lastColumn); :}| - RESERVED_LDD - {: RESULT = new OC_NoParams(OC_NoParams.LDD,parser.lastLine,parser.lastColumn); :}| - RESERVED_LDDR - {: RESULT = new OC_NoParams(OC_NoParams.LDDR,parser.lastLine,parser.lastColumn); :}| - RESERVED_LDI - {: RESULT = new OC_NoParams(OC_NoParams.LDI,parser.lastLine,parser.lastColumn); :}| - RESERVED_LDIR - {: RESULT = new OC_NoParams(OC_NoParams.LDIR,parser.lastLine,parser.lastColumn); :}| - RESERVED_NEG - {: RESULT = new OC_NoParams(OC_NoParams.NEG,parser.lastLine,parser.lastColumn); :}| - RESERVED_NOP - {: RESULT = new OC_NoParams(OC_NoParams.NOP,parser.lastLine,parser.lastColumn); :}| - RESERVED_OTDR - {: RESULT = new OC_NoParams(OC_NoParams.OTDR,parser.lastLine,parser.lastColumn); :}| - RESERVED_OTIR - {: RESULT = new OC_NoParams(OC_NoParams.OTIR,parser.lastLine,parser.lastColumn); :}| - RESERVED_OUTD - {: RESULT = new OC_NoParams(OC_NoParams.OUTD,parser.lastLine,parser.lastColumn); :}| - RESERVED_OUTI - {: RESULT = new OC_NoParams(OC_NoParams.OUTI,parser.lastLine,parser.lastColumn); :}| - RESERVED_RETI - {: RESULT = new OC_NoParams(OC_NoParams.RETI,parser.lastLine,parser.lastColumn); :}| - RESERVED_RETN - {: RESULT = new OC_NoParams(OC_NoParams.RETN,parser.lastLine,parser.lastColumn); :}| - RESERVED_RLA - {: RESULT = new OC_NoParams(OC_NoParams.RLA,parser.lastLine,parser.lastColumn); :}| - RESERVED_RLCA - {: RESULT = new OC_NoParams(OC_NoParams.RLCA,parser.lastLine,parser.lastColumn); :}| - RESERVED_RLD - {: RESULT = new OC_NoParams(OC_NoParams.RLD,parser.lastLine,parser.lastColumn); :}| - RESERVED_RRA - {: RESULT = new OC_NoParams(OC_NoParams.RRA,parser.lastLine,parser.lastColumn); :}| - RESERVED_RRCA - {: RESULT = new OC_NoParams(OC_NoParams.RRCA,parser.lastLine,parser.lastColumn); :}| - RESERVED_RRD - {: RESULT = new OC_NoParams(OC_NoParams.RRD,parser.lastLine,parser.lastColumn); :}| - RESERVED_SCF - {: RESULT = new OC_NoParams(OC_NoParams.SCF,parser.lastLine,parser.lastColumn); :}| - - RESERVED_ADC REGISTERS_A SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.ADC_A_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADC REGISTERS_A SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.ADC_A_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADC REGISTERS_A SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.ADC_A_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADC REGISTERS_A SEPARATOR_COMMA Reg:r - {: RESULT = new OC_Reg(OC_Reg.ADC,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADC REGISTERS_A SEPARATOR_COMMA Expression:e - {: RESULT = new OC_Expr(OC_Expr.ADC,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADC REGISTERS_HL SEPARATOR_COMMA RegRR:r - {: RESULT = new OC_Reg(OC_Reg.ADC_HL,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_ADD REGISTERS_A SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.ADD_A_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADD REGISTERS_A SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.ADD_A_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADD REGISTERS_A SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.ADD_A_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADD REGISTERS_A SEPARATOR_COMMA Reg:r - {: RESULT = new OC_Reg(OC_Reg.ADD,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADD REGISTERS_A SEPARATOR_COMMA Expression:e - {: RESULT = new OC_Expr(OC_Expr.ADD,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADD REGISTERS_HL SEPARATOR_COMMA RegRR:r - {: RESULT = new OC_Reg(OC_Reg.ADD_HL,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADD REGISTERS_IX SEPARATOR_COMMA RegRX:r - {: RESULT = new OC_Reg(OC_Reg.ADD_IX,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_ADD REGISTERS_IY SEPARATOR_COMMA RegRY:r - {: RESULT = new OC_Reg(OC_Reg.ADD_IY,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_AND SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.AND_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_AND SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.ADD_A_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_AND SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.ADD_A_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_AND Reg:r - {: RESULT = new OC_Reg(OC_Reg.AND,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_AND Expression:e - {: RESULT = new OC_Expr(OC_Expr.AND,e,true,parser.lastLine,parser.lastColumn); :}| - - RESERVED_BIT Expression:e SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.BIT,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_BIT Expression:e1 SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e2 SEPARATOR_RPAR - {: RESULT = new OC_ExprExpr(OC_ExprExpr.BIT_IIX_NN,e1,e2,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_BIT Expression:e1 SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e2 SEPARATOR_RPAR - {: RESULT = new OC_ExprExpr(OC_ExprExpr.BIT_IIY_NN,e1,e2,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_BIT Expression:e SEPARATOR_COMMA Reg:r - {: RESULT = new OC_RegExpr(OC_RegExpr.BIT,e,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_CALL CondCC:cc SEPARATOR_COMMA Expression:e - {: RESULT = new OC_RegExpr(OC_RegExpr.CALL,cc,0,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_CALL Expression:e - {: RESULT = new OC_Expr(OC_Expr.CALL,e,false,parser.lastLine,parser.lastColumn); :}| - - RESERVED_CP SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.CP_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_CP SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.CP_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_CP SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.CP_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_CP Reg:r - {: RESULT = new OC_Reg(OC_Reg.CP,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_CP Expression:e - {: RESULT = new OC_Expr(OC_Expr.CP,e,true,parser.lastLine,parser.lastColumn); :}| - - RESERVED_DEC SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.DEC_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_DEC SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.DEC_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_DEC SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.DEC_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_DEC REGISTERS_A - {: RESULT = new OC_NoParams(OC_NoParams.DEC_A,parser.lastLine,parser.lastColumn); :}| - RESERVED_DEC RegWA:r - {: - int opcode = 0; - switch(r) { - case 0: opcode = OC_NoParams.DEC_B; break; - case 1: opcode = OC_NoParams.DEC_C; break; - case 2: opcode = OC_NoParams.DEC_D; break; - case 3: opcode = OC_NoParams.DEC_E; break; - case 4: opcode = OC_NoParams.DEC_H; break; - case 5: opcode = OC_NoParams.DEC_L; break; - } - RESULT = new OC_NoParams(opcode,parser.lastLine,parser.lastColumn); - :}| - RESERVED_DEC RegRR:r - {: RESULT = new OC_Reg(OC_Reg.DEC,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_DEC REGISTERS_IX - {: RESULT = new OC_NoParams(OC_NoParams.DEC_IX,parser.lastLine,parser.lastColumn); :}| - RESERVED_DEC REGISTERS_IY - {: RESULT = new OC_NoParams(OC_NoParams.DEC_IY,parser.lastLine,parser.lastColumn); :}| - - RESERVED_DJNZ Expression:e - {: RESULT = new OC_Expr(OC_Expr.DJNZ,e,true,parser.lastLine,parser.lastColumn); :}| - - RESERVED_EX SEPARATOR_LPAR REGISTERS_SP SEPARATOR_RPAR SEPARATOR_COMMA REGISTERS_HL - {: RESULT = new OC_NoParams(OC_NoParams.EX_SSPP_HL,parser.lastLine,parser.lastColumn); :}| - RESERVED_EX SEPARATOR_LPAR REGISTERS_SP SEPARATOR_RPAR SEPARATOR_COMMA REGISTERS_IX - {: RESULT = new OC_NoParams(OC_NoParams.EX_SSPP_IX,parser.lastLine,parser.lastColumn); :}| - RESERVED_EX SEPARATOR_LPAR REGISTERS_SP SEPARATOR_RPAR SEPARATOR_COMMA REGISTERS_IY - {: RESULT = new OC_NoParams(OC_NoParams.EX_SSPP_IY,parser.lastLine,parser.lastColumn); :}| - RESERVED_EX REGISTERS_DE SEPARATOR_COMMA REGISTERS_HL - {: RESULT = new OC_NoParams(OC_NoParams.EX_DDEE_HL,parser.lastLine,parser.lastColumn); :}| - RESERVED_EX REGISTERS_AF SEPARATOR_COMMA REGISTERS_AFF - {: RESULT = new OC_NoParams(OC_NoParams.EX_AF_AFF,parser.lastLine,parser.lastColumn); :}| - - RESERVED_IM Expression:e - {: RESULT = new OC_Expr(OC_Expr.IM,e,true,parser.lastLine,parser.lastColumn); :}| - - RESERVED_IN REGISTERS_A SEPARATOR_COMMA SEPARATOR_LPAR Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.IN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_IN REGISTERS_A SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_C SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.IN_A,parser.lastLine,parser.lastColumn); :}| - RESERVED_IN RegWA:r SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_C SEPARATOR_RPAR - {: - int opcode = 0; - switch(r) { - case 0: opcode = OC_NoParams.IN_B; break; - case 1: opcode = OC_NoParams.IN_C; break; - case 2: opcode = OC_NoParams.IN_D; break; - case 3: opcode = OC_NoParams.IN_E; break; - case 4: opcode = OC_NoParams.IN_H; break; - case 5: opcode = OC_NoParams.IN_L; break; - } - RESULT = new OC_NoParams(opcode,parser.lastLine,parser.lastColumn); - :}| - - RESERVED_INC SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.INC_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_INC SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.INC_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_INC SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.INC_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_INC Reg:r - {: - int opcode = 0; - switch(r) { - case 0: opcode = OC_NoParams.INC_B; break; - case 1: opcode = OC_NoParams.INC_C; break; - case 2: opcode = OC_NoParams.INC_D; break; - case 3: opcode = OC_NoParams.INC_E; break; - case 4: opcode = OC_NoParams.INC_H; break; - case 5: opcode = OC_NoParams.INC_L; break; - case 7: opcode = OC_NoParams.INC_A; break; - } - RESULT = new OC_NoParams(opcode,parser.lastLine,parser.lastColumn); - :}| - RESERVED_INC RegRR:rr - {: RESULT = new OC_Reg(OC_Reg.INC,rr,parser.lastLine,parser.lastColumn); :}| - RESERVED_INC REGISTERS_IX - {: RESULT = new OC_NoParams(OC_NoParams.INC_IX,parser.lastLine,parser.lastColumn); :}| - RESERVED_INC REGISTERS_IY - {: RESULT = new OC_NoParams(OC_NoParams.INC_IY,parser.lastLine,parser.lastColumn); :}| - - RESERVED_JP Expression:e - {: RESULT = new OC_Expr(OC_Expr.JP,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_JP SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.JP_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_JP SEPARATOR_LPAR REGISTERS_IX SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.JP_IIXX,parser.lastLine,parser.lastColumn); :}| - RESERVED_JP SEPARATOR_LPAR REGISTERS_IY SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.JP_IIYY,parser.lastLine,parser.lastColumn); :}| - RESERVED_JP CondCC:cc SEPARATOR_COMMA Expression:e - {: RESULT = new OC_RegExpr(OC_RegExpr.JP,cc,0,e,false,parser.lastLine,parser.lastColumn); :}| - - RESERVED_JR Expression:e - {: RESULT = new OC_Expr(OC_Expr.JR,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_JR CondCond:cc SEPARATOR_COMMA Expression:e - {: RESULT = new OC_RegExpr(OC_RegExpr.JR,cc,0,e,true,parser.lastLine,parser.lastColumn); :}| - - RESERVED_LD SEPARATOR_LPAR REGISTERS_BC SEPARATOR_RPAR SEPARATOR_COMMA REGISTERS_A - {: RESULT = new OC_NoParams(OC_NoParams.LD_BBCC_A,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD SEPARATOR_LPAR REGISTERS_DE SEPARATOR_RPAR SEPARATOR_COMMA REGISTERS_A - {: RESULT = new OC_NoParams(OC_NoParams.LD_DDEE_A,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR SEPARATOR_COMMA Expression:e - {: RESULT = new OC_Expr(OC_Expr.LD_HHLL,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR SEPARATOR_COMMA Reg:r - {: RESULT = new OC_Reg(OC_Reg.LD_HHLL_r,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e1 SEPARATOR_RPAR SEPARATOR_COMMA Expression:e2 - {: RESULT = new OC_ExprExpr(OC_ExprExpr.LD_IIX_NN,e1,e2,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e1 SEPARATOR_RPAR SEPARATOR_COMMA Expression:e2 - {: RESULT = new OC_ExprExpr(OC_ExprExpr.LD_IIY_NN,e1,e2,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR SEPARATOR_COMMA Reg:r - {: RESULT = new OC_RegExpr(OC_RegExpr.LD_IIX_NN,r,1,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR SEPARATOR_COMMA Reg:r - {: RESULT = new OC_RegExpr(OC_RegExpr.LD_IIY_NN,r,1,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD SEPARATOR_LPAR Expression:e SEPARATOR_RPAR SEPARATOR_COMMA REGISTERS_A - {: RESULT = new OC_Expr(OC_Expr.LD_NN_A,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD SEPARATOR_LPAR Expression:e SEPARATOR_RPAR SEPARATOR_COMMA RegRR:rr - {: - int opcode = 0; - switch(rr) { - case 0: opcode = OC_Expr.LD_NN_BC; break; - case 0x10: opcode = OC_Expr.LD_NN_DE; break; - case 0x20: opcode = OC_Expr.LD_NN_HL; break; - case 0x30: opcode = OC_Expr.LD_NN_SP; break; - } - RESULT = new OC_Expr(opcode,e,false,parser.lastLine,parser.lastColumn); - :}| - RESERVED_LD SEPARATOR_LPAR Expression:e SEPARATOR_RPAR SEPARATOR_COMMA REGISTERS_IX - {: RESULT = new OC_Expr(OC_Expr.LD_NN_IX,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD SEPARATOR_LPAR Expression:e SEPARATOR_RPAR SEPARATOR_COMMA REGISTERS_IY - {: RESULT = new OC_Expr(OC_Expr.LD_NN_IY,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_A SEPARATOR_COMMA SEPARATOR_INDEXLPAR REGISTERS_BC SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.LD_A_BBCC,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_A SEPARATOR_COMMA SEPARATOR_INDEXLPAR REGISTERS_DE SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.LD_A_DDEE,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_A SEPARATOR_COMMA SEPARATOR_INDEXLPAR Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.LD_A_NN,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_A SEPARATOR_COMMA REGISTERS_I - {: RESULT = new OC_NoParams(OC_NoParams.LD_A_I,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_A SEPARATOR_COMMA REGISTERS_R - {: RESULT = new OC_NoParams(OC_NoParams.LD_A_R,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD RegRR_WSP:rr SEPARATOR_COMMA SEPARATOR_INDEXLPAR Expression:e SEPARATOR_RPAR - {: - int opcode = 0; - switch(rr) { - case 0: opcode = OC_Expr.LD_BC_NN; break; - case 0x10: opcode = OC_Expr.LD_DE_NN; break; - case 0x20: opcode = OC_Expr.LD_HL_NN; break; - } - RESULT = new OC_Expr(opcode,e,false,parser.lastLine,parser.lastColumn); - :}| - RESERVED_LD REGISTERS_SP SEPARATOR_COMMA SEPARATOR_INDEXLPAR Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.LD_SP_NN,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD RegRR_WSP:rr SEPARATOR_COMMA Expression:e - {: RESULT = new OC_RegExpr(OC_RegExpr.LD_RR,rr,0,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_SP SEPARATOR_COMMA Expression:e - {: RESULT = new OC_RegExpr(OC_RegExpr.LD_RR,0x30,0,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_I SEPARATOR_COMMA REGISTERS_A - {: RESULT = new OC_NoParams(OC_NoParams.LD_I,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_R SEPARATOR_COMMA REGISTERS_A - {: RESULT = new OC_NoParams(OC_NoParams.LD_R,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_IX SEPARATOR_COMMA SEPARATOR_INDEXLPAR Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.LD_IX_NN,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_IY SEPARATOR_COMMA SEPARATOR_INDEXLPAR Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.LD_IY_NN,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_IX SEPARATOR_COMMA Expression:e - {: RESULT = new OC_Expr(OC_Expr.LD_IX,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_IY SEPARATOR_COMMA Expression:e - {: RESULT = new OC_Expr(OC_Expr.LD_IY,e,false,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD RegWA:r SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: - int opcode = 0; - switch(r) { - case 0: opcode = OC_NoParams.LD_B_HHLL; break; - case 1: opcode = OC_NoParams.LD_C_HHLL; break; - case 2: opcode = OC_NoParams.LD_D_HHLL; break; - case 3: opcode = OC_NoParams.LD_E_HHLL; break; - case 4: opcode = OC_NoParams.LD_H_HHLL; break; - case 5: opcode = OC_NoParams.LD_L_HHLL; break; - } - RESULT = new OC_NoParams(opcode,parser.lastLine,parser.lastColumn); - :}| - RESERVED_LD REGISTERS_A SEPARATOR_COMMA SEPARATOR_INDEXLPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.LD_A_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD RegWA:r SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: - int opcode = 0; - switch(r) { - case 0: opcode = OC_Expr.LD_B_IIX_NN; break; - case 1: opcode = OC_Expr.LD_C_IIX_NN; break; - case 2: opcode = OC_Expr.LD_D_IIX_NN; break; - case 3: opcode = OC_Expr.LD_E_IIX_NN; break; - case 4: opcode = OC_Expr.LD_H_IIX_NN; break; - case 5: opcode = OC_Expr.LD_L_IIX_NN; break; - } - RESULT = new OC_Expr(opcode,e,true,parser.lastLine,parser.lastColumn); - :}| - RESERVED_LD RegWA:r SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: - int opcode = 0; - switch(r) { - case 0: opcode = OC_Expr.LD_B_IIY_NN; break; - case 1: opcode = OC_Expr.LD_C_IIY_NN; break; - case 2: opcode = OC_Expr.LD_D_IIY_NN; break; - case 3: opcode = OC_Expr.LD_E_IIY_NN; break; - case 4: opcode = OC_Expr.LD_H_IIY_NN; break; - case 5: opcode = OC_Expr.LD_L_IIY_NN; break; - } - RESULT = new OC_Expr(opcode,e,true,parser.lastLine,parser.lastColumn); - :}| - RESERVED_LD REGISTERS_A SEPARATOR_COMMA SEPARATOR_INDEXLPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.LD_A_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_A SEPARATOR_COMMA SEPARATOR_INDEXLPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.LD_A_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_A SEPARATOR_COMMA Reg:r - {: RESULT = new OC_Reg(OC_Reg.LD_A,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD RegWA:r1 SEPARATOR_COMMA Reg:r - {: - int opcode = 0; - switch(r1) { - case 0: opcode = OC_Reg.LD_B; break; - case 1: opcode = OC_Reg.LD_C; break; - case 2: opcode = OC_Reg.LD_D; break; - case 3: opcode = OC_Reg.LD_E; break; - case 4: opcode = OC_Reg.LD_H; break; - case 5: opcode = OC_Reg.LD_L; break; - } - RESULT = new OC_Reg(opcode,r,parser.lastLine,parser.lastColumn); - :}| - RESERVED_LD RegWA:r SEPARATOR_COMMA Expression:e - {: - int opcode = 0; - switch(r) { - case 0: opcode = OC_Expr.LD_B; break; - case 1: opcode = OC_Expr.LD_C; break; - case 2: opcode = OC_Expr.LD_D; break; - case 3: opcode = OC_Expr.LD_E; break; - case 4: opcode = OC_Expr.LD_H; break; - case 5: opcode = OC_Expr.LD_L; break; - } - RESULT = new OC_Expr(opcode,e,true,parser.lastLine,parser.lastColumn); - :}| - RESERVED_LD REGISTERS_A SEPARATOR_COMMA Expression:e - {: RESULT = new OC_Expr(OC_Expr.LD_A,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_SP SEPARATOR_COMMA REGISTERS_HL - {: RESULT = new OC_NoParams(OC_NoParams.LD_SP_HL,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_SP SEPARATOR_COMMA REGISTERS_IX - {: RESULT = new OC_NoParams(OC_NoParams.LD_SP_IX,parser.lastLine,parser.lastColumn); :}| - RESERVED_LD REGISTERS_SP SEPARATOR_COMMA REGISTERS_IY - {: RESULT = new OC_NoParams(OC_NoParams.LD_SP_IY,parser.lastLine,parser.lastColumn); :}| - - RESERVED_OR SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.OR_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_OR SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.OR_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_OR SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.OR_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_OR Reg:r - {: RESULT = new OC_Reg(OC_Reg.OR,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_OR Expression:e - {: RESULT = new OC_Expr(OC_Expr.OR,e,true,parser.lastLine,parser.lastColumn); :}| - - RESERVED_OUT SEPARATOR_LPAR Expression:e SEPARATOR_RPAR SEPARATOR_COMMA REGISTERS_A - {: RESULT = new OC_Expr(OC_Expr.OUT,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_OUT SEPARATOR_LPAR REGISTERS_C SEPARATOR_RPAR SEPARATOR_COMMA Reg:r - {: - int opcode = 0; - switch(r) { - case 0: opcode = OC_NoParams.OUT_B; break; - case 1: opcode = OC_NoParams.OUT_C; break; - case 2: opcode = OC_NoParams.OUT_D; break; - case 3: opcode = OC_NoParams.OUT_E; break; - case 4: opcode = OC_NoParams.OUT_H; break; - case 5: opcode = OC_NoParams.OUT_L; break; - case 7: opcode = OC_NoParams.OUT_A; break; - } - RESULT = new OC_NoParams(opcode,parser.lastLine,parser.lastColumn); - :}| - - RESERVED_POP RegQQ:qq - {: RESULT = new OC_Reg(OC_Reg.POP,qq,parser.lastLine,parser.lastColumn); :}| - RESERVED_POP REGISTERS_IX - {: RESULT = new OC_NoParams(OC_NoParams.POP_IX,parser.lastLine,parser.lastColumn); :}| - RESERVED_POP REGISTERS_IY - {: RESULT = new OC_NoParams(OC_NoParams.POP_IY,parser.lastLine,parser.lastColumn); :}| - - RESERVED_PUSH RegQQ:qq - {: RESULT = new OC_Reg(OC_Reg.PUSH,qq,parser.lastLine,parser.lastColumn); :}| - RESERVED_PUSH REGISTERS_IX - {: RESULT = new OC_NoParams(OC_NoParams.PUSH_IX,parser.lastLine,parser.lastColumn); :}| - RESERVED_PUSH REGISTERS_IY - {: RESULT = new OC_NoParams(OC_NoParams.PUSH_IY,parser.lastLine,parser.lastColumn); :}| - - RESERVED_RES Expression:e SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.RES,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_RES Expression:e1 SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e2 SEPARATOR_RPAR - {: RESULT = new OC_ExprExpr(OC_ExprExpr.RES_IIX_NN,e1,e2,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_RES Expression:e1 SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e2 SEPARATOR_RPAR - {: RESULT = new OC_ExprExpr(OC_ExprExpr.RES_IIY_NN,e1,e2,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_RES Expression:e SEPARATOR_COMMA Reg:r - {: RESULT = new OC_RegExpr(OC_RegExpr.RES,e,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_RET - {: RESULT = new OC_NoParams(OC_NoParams.RET,parser.lastLine,parser.lastColumn); :}| - RESERVED_RET CondCC:cc - {: RESULT = new OC_Reg(OC_Reg.RET,cc,parser.lastLine,parser.lastColumn); :}| - - RESERVED_RL SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.RL_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_RL SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.RL_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_RL SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.RL_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_RL Reg:r - {: RESULT = new OC_Reg(OC_Reg.RL,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_RLC SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.RLC_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_RLC SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.RLC_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_RLC SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.RLC_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_RLC Reg:r - {: RESULT = new OC_Reg(OC_Reg.RLC,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_RR SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.RR_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_RR SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.RR_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_RR SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.RR_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_RR Reg:r - {: RESULT = new OC_Reg(OC_Reg.RR,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_RRC SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.RRC_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_RRC SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.RRC_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_RRC SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.RRC_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_RRC Reg:r - {: RESULT = new OC_Reg(OC_Reg.RRC,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_RST Expression:e - {: RESULT = new OC_Expr(OC_Expr.RST,e,true,parser.lastLine,parser.lastColumn); :}| - - RESERVED_SBC SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.SBC_A_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_SBC SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SBC_A_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SBC SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SBC_A_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SBC Expression:e - {: RESULT = new OC_Expr(OC_Expr.SBC,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SBC Reg:r - {: RESULT = new OC_Reg(OC_Reg.SBC,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_SBC REGISTERS_HL SEPARATOR_COMMA RegRR:rr - {: RESULT = new OC_Reg(OC_Reg.SBC_HL,rr,parser.lastLine,parser.lastColumn); :}| - - RESERVED_SET Expression:e SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SET,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SET Expression:e1 SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e2 SEPARATOR_RPAR - {: RESULT = new OC_ExprExpr(OC_ExprExpr.SET_IIX_NN,e1,e2,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SET Expression:e1 SEPARATOR_COMMA SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e2 SEPARATOR_RPAR - {: RESULT = new OC_ExprExpr(OC_ExprExpr.SET_IIY_NN,e1,e2,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SET Expression:e SEPARATOR_COMMA Reg:r - {: RESULT = new OC_RegExpr(OC_RegExpr.SET,e,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_SLA SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.SLA_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_SLA SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SLA_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SLA SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SLA_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SLA Reg:r - {: RESULT = new OC_Reg(OC_Reg.SLA,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_SRA SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.SRA_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_SRA SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SRA_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SRA SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SRA_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SRA Reg:r - {: RESULT = new OC_Reg(OC_Reg.SRA,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_SLL SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.SLL_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_SLL SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SLL_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SLL SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SLL_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SLL Reg:r - {: RESULT = new OC_Reg(OC_Reg.SLL,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_SRL SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.SRL_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_SRL SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SRL_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SRL SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SRL_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SRL Reg:r - {: RESULT = new OC_Reg(OC_Reg.SRL,r,parser.lastLine,parser.lastColumn); :}| - - RESERVED_SUB SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.SUB_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_SUB SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SUB_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SUB SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.SUB_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_SUB Reg:r - {: RESULT = new OC_Reg(OC_Reg.SUB,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_SUB Expression:e - {: RESULT = new OC_Expr(OC_Expr.SUB,e,true,parser.lastLine,parser.lastColumn); :}| - - RESERVED_XOR SEPARATOR_LPAR REGISTERS_HL SEPARATOR_RPAR - {: RESULT = new OC_NoParams(OC_NoParams.XOR_HHLL,parser.lastLine,parser.lastColumn); :}| - RESERVED_XOR SEPARATOR_LPAR REGISTERS_IX OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.XOR_IIX_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_XOR SEPARATOR_LPAR REGISTERS_IY OPERATOR_ADD Expression:e SEPARATOR_RPAR - {: RESULT = new OC_Expr(OC_Expr.XOR_IIY_NN,e,true,parser.lastLine,parser.lastColumn); :}| - RESERVED_XOR Reg:r - {: RESULT = new OC_Reg(OC_Reg.XOR,r,parser.lastLine,parser.lastColumn); :}| - RESERVED_XOR Expression:e - {: RESULT = new OC_Expr(OC_Expr.XOR,e,true,parser.lastLine,parser.lastColumn); :}; - -Reg ::= REGISTERS_A {: RESULT = 7; :}| - REGISTERS_B {: RESULT = 0; :}| - REGISTERS_C {: RESULT = 1; :}| - REGISTERS_D {: RESULT = 2; :}| - REGISTERS_E {: RESULT = 3; :}| - REGISTERS_H {: RESULT = 4; :}| - REGISTERS_L {: RESULT = 5; :}; - -RegWA ::= REGISTERS_B {: RESULT = 0; :}| - REGISTERS_C {: RESULT = 1; :}| - REGISTERS_D {: RESULT = 2; :}| - REGISTERS_E {: RESULT = 3; :}| - REGISTERS_H {: RESULT = 4; :}| - REGISTERS_L {: RESULT = 5; :}; - -RegRR ::= REGISTERS_SP {: RESULT = 0x30; :}| - RegRR_WSP:r {: RESULT = r; :}; - -RegRR_WSP ::= REGISTERS_BC {: RESULT = 0; :}| - REGISTERS_DE {: RESULT = 0x10; :}| - REGISTERS_HL {: RESULT = 0x20; :}; - -RegRX ::= REGISTERS_BC {: RESULT = 0; :}| - REGISTERS_DE {: RESULT = 0x10; :}| - REGISTERS_SP {: RESULT = 0x30; :}| - REGISTERS_IX {: RESULT = 0x20; :}; - -RegRY ::= REGISTERS_BC {: RESULT = 0; :}| - REGISTERS_DE {: RESULT = 0x10; :}| - REGISTERS_SP {: RESULT = 0x30; :}| - REGISTERS_IY {: RESULT = 0x20; :}; - -CondCC ::= RESERVED_C {: RESULT = 0x18; :}| - RESERVED_NC {: RESULT = 0x10; :}| - RESERVED_Z {: RESULT = 0x8; :}| - RESERVED_NZ {: RESULT = 0; :}| - RESERVED_M {: RESULT = 0x38; :}| - RESERVED_P {: RESULT = 0x30; :}| - RESERVED_PE {: RESULT = 0x28; :}| - RESERVED_PO {: RESULT = 0x20; :}; - -CondCond ::= RESERVED_C {: RESULT = 0x18; :}| - RESERVED_NC {: RESULT = 0x10; :}| - RESERVED_Z {: RESULT = 0x8; :}| - RESERVED_NZ {: RESULT = 0x0; :}; - -RegQQ ::= REGISTERS_AF {: RESULT = 0x30; :}| - REGISTERS_BC {: RESULT = 0; :}| - REGISTERS_DE {: RESULT = 0x10; :}| - REGISTERS_HL {: RESULT = 0x20; :}; - diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java index 2979b965b..934a2f79e 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java @@ -155,13 +155,13 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[OP_GT] = Token.OPERATOR; tokenMap[OP_GTE] = Token.OPERATOR; - tokenMap[LIT_NUMBER] =Token.LITERAL; - tokenMap[LIT_HEXNUMBER_1] =Token.LITERAL; - tokenMap[LIT_HEXNUMBER_2] =Token.LITERAL; - tokenMap[LIT_OCTNUMBER] =Token.LITERAL; - tokenMap[LIT_BINNUMBER] =Token.LITERAL; - tokenMap[LIT_STRING_1] =Token.LITERAL; - tokenMap[LIT_STRING_2] =Token.LITERAL; + tokenMap[LIT_NUMBER] = Token.LITERAL; + tokenMap[LIT_HEXNUMBER_1] = Token.LITERAL; + tokenMap[LIT_HEXNUMBER_2] = Token.LITERAL; + tokenMap[LIT_OCTNUMBER] = Token.LITERAL; + tokenMap[LIT_BINNUMBER] = Token.LITERAL; + tokenMap[LIT_STRING_1] = Token.LITERAL; + tokenMap[LIT_STRING_2] = Token.LITERAL; tokenMap[ID_IDENTIFIER] = Token.IDENTIFIER; tokenMap[ID_LABEL] = Token.IDENTIFIER; @@ -206,6 +206,9 @@ public void reset(InputStream inputStream) throws IOException { } private int convertLexerTokenType(int tokenType) { + if (tokenType == EOF) { + return Token.EOF; + } return tokenMap[tokenType]; } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java index fd7c741d8..3f3aeef93 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java @@ -42,7 +42,10 @@ public Node visitPseudoIf(PseudoIfContext ctx) { ifExpr.addChild(expr); pseudo.addChild(ifExpr); for (RLineContext line : ctx.rLine()) { - pseudo.addChild(CreateVisitors.line.visitRLine(line)); + Node lineNode = CreateVisitors.line.visitRLine(line); + if (lineNode != null) { + pseudo.addChild(lineNode); + } } return pseudo; } @@ -60,7 +63,10 @@ public Node visitPseudoMacroDef(PseudoMacroDefContext ctx) { } } for (RLineContext line : ctx.rLine()) { - pseudo.addChild(CreateVisitors.line.visitRLine(line)); + Node lineNode = CreateVisitors.line.visitRLine(line); + if (lineNode != null) { + pseudo.addChild(lineNode); + } } return pseudo; } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java index 0854a8b4d..cd025f7c4 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java @@ -83,14 +83,14 @@ public void testParseString2Error() { @Test public void testParseComment1() { - assertTokenTypes("// comment fun1", EOF); - assertTokenTypes("# comment fun1", EOF); - assertTokenTypes("; comment fun1", EOF); + assertTokenTypes("// comment fun1", COMMENT, EOF); + assertTokenTypes("# comment fun1", COMMENT, EOF); + assertTokenTypes("; comment fun1", COMMENT, EOF); } @Test public void testParseComment2() { - assertTokenTypes("/*\n*\n* comment fun1\n\n*/", EOF); + assertTokenTypes("/*\n*\n* comment fun1\n\n*/", COMMENT2, EOF); } @Test diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java index 65f654e8e..00131f451 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java @@ -216,7 +216,7 @@ public void testHLT() { public void testInvalidInstruction() { cpuRunnerImpl.setProgram(0xED, 0x80); cpuRunnerImpl.reset(); - cpuRunnerImpl.expectRunState(CPU.RunState.STATE_STOPPED_BAD_INSTR); + cpuRunnerImpl.expectRunState(CPU.RunState.STATE_STOPPED_BREAK); // Z80 ignores bad instructions cpuRunnerImpl.step(); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java index 58d8b7606..54792fc87 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java @@ -273,7 +273,7 @@ public void testOTIR() { ); } - @Test + @Test // TODO public void testOUTD() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() diff --git a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java index 6a09120fa..1e2c97641 100644 --- a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java +++ b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java @@ -70,8 +70,8 @@ public void testInitialDriveParameters() { assertEquals(0, params.sectorOffset); assertEquals(0, params.track); assertNull(params.mountedFloppy); - assertEquals(0xE7, params.port1status); - assertEquals(0xC1, params.port2status); + assertEquals(0xE7, params.port1status & 0xFF); + assertEquals(0xC1, params.port2status & 0xFF); } @Test @@ -120,8 +120,8 @@ public void testDriveParametersAfterSelect() throws Exception { DriveParameters params = drive.getDriveParameters(); - assertEquals(0xA5, params.port1status); - assertEquals(0xC1, params.port2status); + assertEquals(0xA5, params.port1status & 0xFF); + assertEquals(0xC1, params.port2status & 0xFF); assertEquals(0, params.sector); assertEquals(0, params.sectorOffset); assertEquals(0, params.track); @@ -142,8 +142,8 @@ public void testDriveParametersAfterSelectThenDeselect() throws Exception { assertEquals(0, params.sectorOffset); assertEquals(0, params.track); assertSame(testImageFile, params.mountedFloppy); - assertEquals(0xE7, params.port1status); - assertEquals(0xC1, params.port2status); + assertEquals(0xE7, params.port1status & 0xFF); + assertEquals(0xC1, params.port2status & 0xFF); } @Test From b973eed94a3310d4efdf5b0fffe110315f9fed04 Mon Sep 17 00:00:00 2001 From: Paolo Amoroso Date: Sat, 12 Mar 2022 10:45:08 +0100 Subject: [PATCH 115/314] Remove extra instr and check for prog termination Remove spurious push instruction and terminate the program if a key is pressed. --- .../as-8080/src/main/examples/twirl.asm | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/examples/twirl.asm b/plugins/compiler/as-8080/src/main/examples/twirl.asm index 60c3d9681..4e99c7510 100644 --- a/plugins/compiler/as-8080/src/main/examples/twirl.asm +++ b/plugins/compiler/as-8080/src/main/examples/twirl.asm @@ -1,13 +1,15 @@ ; Twirling bar animation by Paolo Amoroso ; -; Runs on an Altair 8800 with an ADM-3A terminal. To interrupt -; the program click "Stop emulation". +; Runs on an Altair 8800 with an ADM-3A terminal. Press any key +; to interrupt the program. FRAMES equ 8 ; Number of animation frames CLS equ 1ah ; ADM-3A escape sequence HOME equ 1eh ; ADM-3A escape sequence +STATUS equ 10h ; Input status port +READY equ 1 ; Character ready status mask mvi a, CLS ; Clear screen @@ -20,19 +22,25 @@ loop1: mvi a, HOME ; Go to home call putchar mov a, m ; Print current frame - push h call putchar inx h dcr b + + push psw + in STATUS ; Key pressed? + ani READY + jnz exit ; Yes + pop psw + jnz loop1 jmp loop - - hlt + +exit: hlt ANIM: db '|/-\|/-\' ; 8 frames -include 'include\putchar.inc' +include 'include\putchar.inc' From c348e78b3bfe8559778e1ef7319aba681f27e577 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 14 Mar 2022 12:39:35 +0000 Subject: [PATCH 116/314] [#201] as-z80: fix parser --- .../plugins/compiler/ssem/LexerTest.java | 57 ++--- .../as-z80/src/main/antlr/AsZ80Lexer.g4 | 26 +-- .../as-z80/src/main/antlr/AsZ80Lexer.tokens | 198 +++++++++--------- .../as-z80/src/main/antlr/AsZ80Parser.g4 | 4 - .../compiler/asZ80/LexicalAnalyzerImpl.java | 4 + .../compiler/asZ80/e2e/AssemblerZ80Test.java | 36 +++- .../asZ80/parser/LexicalAnalyzerImplTest.java | 50 +++-- .../compiler/asZ80/parser/ParseInstrTest.java | 30 ++- .../asZ80/parser/ParsingUtilsTest.java | 33 ++- test_report.gradle | 2 +- 10 files changed, 241 insertions(+), 199 deletions(-) diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java index 120224ab2..8dd5c7482 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/LexerTest.java @@ -20,6 +20,7 @@ import org.junit.Test; +import static net.emustudio.plugins.compiler.ssem.SSEMLexer.*; import static net.emustudio.plugins.compiler.ssem.Utils.assertTokenTypes; import static net.emustudio.plugins.compiler.ssem.Utils.assertTokenTypesForCaseVariations; @@ -27,53 +28,53 @@ public class LexerTest { @Test public void testParseError() { - assertTokenTypes("B I", SSEMLexer.ERROR, SSEMLexer.WS, SSEMLexer.ERROR, SSEMLexer.EOF); - assertTokenTypes("BINS ha", SSEMLexer.BNUM, SSEMLexer.BWS, SSEMLexer.BERROR, SSEMLexer.BERROR, SSEMLexer.EOF); + assertTokenTypes("B I", ERROR, WS, ERROR, EOF); + assertTokenTypes("BINS ha", BNUM, BWS, BERROR, BERROR, EOF); } @Test public void testParseReservedWords() { - assertTokenTypesForCaseVariations("jmp", SSEMLexer.JMP, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("jrp", SSEMLexer.JPR, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("jpr", SSEMLexer.JPR, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("jmr", SSEMLexer.JPR, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("ldn", SSEMLexer.LDN, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("sto", SSEMLexer.STO, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("sub", SSEMLexer.SUB, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("cmp", SSEMLexer.CMP, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("skn", SSEMLexer.CMP, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("stp", SSEMLexer.STP, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("hlt", SSEMLexer.STP, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("jmp", JMP, EOF); + assertTokenTypesForCaseVariations("jrp", JPR, EOF); + assertTokenTypesForCaseVariations("jpr", JPR, EOF); + assertTokenTypesForCaseVariations("jmr", JPR, EOF); + assertTokenTypesForCaseVariations("ldn", LDN, EOF); + assertTokenTypesForCaseVariations("sto", STO, EOF); + assertTokenTypesForCaseVariations("sub", SUB, EOF); + assertTokenTypesForCaseVariations("cmp", CMP, EOF); + assertTokenTypesForCaseVariations("skn", CMP, EOF); + assertTokenTypesForCaseVariations("stp", STP, EOF); + assertTokenTypesForCaseVariations("hlt", STP, EOF); } @Test public void testParsePreprocessor() { - assertTokenTypesForCaseVariations("start", SSEMLexer.START, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("num", SSEMLexer.NUM, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("bnum", SSEMLexer.BNUM, SSEMLexer.EOF); - assertTokenTypesForCaseVariations("bins", SSEMLexer.BNUM, SSEMLexer.EOF); + assertTokenTypesForCaseVariations("start", START, EOF); + assertTokenTypesForCaseVariations("num", NUM, EOF); + assertTokenTypesForCaseVariations("bnum", BNUM, EOF); + assertTokenTypesForCaseVariations("bins", BNUM, EOF); } @Test public void testParseWhitespaces() { - assertTokenTypes(" ", SSEMLexer.WS, SSEMLexer.EOF); - assertTokenTypes("\t", SSEMLexer.WS, SSEMLexer.EOF); - assertTokenTypes("\n", SSEMLexer.EOL, SSEMLexer.EOF); - assertTokenTypes("", SSEMLexer.EOF); + assertTokenTypes(" ", WS, EOF); + assertTokenTypes("\t", WS, EOF); + assertTokenTypes("\n", EOL, EOF); + assertTokenTypes("", EOF); } @Test public void testParseComments() { - assertTokenTypes("-- comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); - assertTokenTypes("# comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); - assertTokenTypes("// comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); - assertTokenTypes("; comment baybe", SSEMLexer.COMMENT, SSEMLexer.EOF); + assertTokenTypes("-- comment baybe", COMMENT, EOF); + assertTokenTypes("# comment baybe", COMMENT, EOF); + assertTokenTypes("// comment baybe", COMMENT, EOF); + assertTokenTypes("; comment baybe", COMMENT, EOF); } @Test public void testLiterals() { - assertTokenTypes("10", SSEMLexer.NUMBER, SSEMLexer.EOF); - assertTokenTypes("0xAF", SSEMLexer.HEXNUMBER, SSEMLexer.EOF); - assertTokenTypes("BINS 1010", SSEMLexer.BNUM, SSEMLexer.BWS, SSEMLexer.BinaryNumber, SSEMLexer.EOF); + assertTokenTypes("10", NUMBER, EOF); + assertTokenTypes("0xAF", HEXNUMBER, EOF); + assertTokenTypes("BINS 1010", BNUM, BWS, BinaryNumber, EOF); } } diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 index ef81013b2..eebe7c339 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 @@ -101,24 +101,24 @@ OPCODE_SUB: S U B; OPCODE_XOR: X O R; mode CONDITION; -COND_C: C -> popMode; -COND_NC: N C -> popMode; -COND_Z: Z -> popMode; -COND_NZ: N Z -> popMode; -COND_M: M -> popMode; -COND_P: P -> popMode; -COND_PE: P E -> popMode; -COND_PO: P O -> popMode; -COND_WS: [ \t\f]+ -> skip; -ERROR_COND: () -> popMode,skip; +COND_C: C ({(_input.LA(1) == -1) || (" ,\t\f\n\r;#/'\"()[]{}!=-+*<>\\%^&|$.".indexOf((char)_input.LA(1)) != -1) }?) -> popMode; +COND_NC: N C ({(_input.LA(1) == -1) || (" ,\t\f\n\r;#/'\"()[]{}!=-+*<>\\%^&|$.".indexOf((char)_input.LA(1)) != -1) }?) -> popMode; +COND_Z: Z ({(_input.LA(1) == -1) || (" ,\t\f\n\r;#/'\"()[]{}!=-+*<>\\%^&|$.".indexOf((char)_input.LA(1)) != -1) }?) -> popMode; +COND_NZ: N Z ({(_input.LA(1) == -1) || (" ,\t\f\n\r;#/'\"()[]{}!=-+*<>\\%^&|$.".indexOf((char)_input.LA(1)) != -1) }?) -> popMode; +COND_M: M ({(_input.LA(1) == -1) || (" ,\t\f\n\r;#/'\"()[]{}!=-+*<>\\%^&|$.".indexOf((char)_input.LA(1)) != -1) }?) -> popMode; +COND_PE: P E ({(_input.LA(1) == -1) || (" ,\t\f\n\r;#/'\"()[]{}!=-+*<>\\%^&|$.".indexOf((char)_input.LA(1)) != -1) }?) -> popMode; +COND_PO: P O ({(_input.LA(1) == -1) || (" ,\t\f\n\r;#/'\"()[]{}!=-+*<>\\%^&|$.".indexOf((char)_input.LA(1)) != -1) }?) -> popMode; +COND_P: P ({(_input.LA(1) == -1) || (" ,\t\f\n\r;#/'\"()[]{}!=-+*<>\\%^&|$.".indexOf((char)_input.LA(1)) != -1) }?) -> popMode; +COND_WS: [ \t\f]+ -> channel(HIDDEN); +ERROR_COND: () -> popMode,channel(HIDDEN); mode IM_NUMBER; IM_01: '0/1' -> popMode; IM_0: '0' -> popMode; IM_1: '1' -> popMode; IM_2: '2' -> popMode; -IM_WS: [ \t\f]+ -> skip; -ERROR_IM: ({"012".indexOf((char) _input.LA(1)) == -1}?) -> popMode,skip; +IM_WS: [ \t\f]+ -> channel(HIDDEN); +ERROR_IM: ({"012".indexOf((char) _input.LA(1)) == -1}?) -> popMode,channel(HIDDEN); mode DEFAULT_MODE; @@ -205,5 +205,5 @@ OP_AND: '&'; OP_OR: '|'; OP_XOR: '^'; -WS : [ \t\f]+ -> skip; +WS : [ \t\f]+ -> channel(HIDDEN); EOL: '\r'? '\n'; diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens index 874ad1b1b..35cfd87dd 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens @@ -76,103 +76,101 @@ COND_M=75 COND_P=76 COND_PE=77 COND_PO=78 -COND_WS=79 -ERROR_COND=80 -IM_01=81 -IM_0=82 -IM_1=83 -IM_2=84 -IM_WS=85 -ERROR_IM=86 -PREP_ORG=87 -PREP_EQU=88 -PREP_VAR=89 -PREP_IF=90 -PREP_ENDIF=91 -PREP_INCLUDE=92 -PREP_MACRO=93 -PREP_ENDM=94 -PREP_DB=95 -PREP_DW=96 -PREP_DS=97 -PREP_ADDR=98 -REG_A=99 -REG_B=100 -REG_C=101 -REG_D=102 -REG_E=103 -REG_H=104 -REG_L=105 -REG_IX=106 -REG_IXH=107 -REG_IXL=108 -REG_IY=109 -REG_IYH=110 -REG_IYL=111 -REG_BC=112 -REG_DE=113 -REG_HL=114 -REG_SP=115 -REG_AF=116 -REG_AFF=117 -REG_I=118 -REG_R=119 -OP_MOD=120 -OP_SHR=121 -OP_SHL=122 -OP_NOT=123 -LIT_HEXNUMBER_1=124 -LIT_NUMBER=125 -LIT_HEXNUMBER_2=126 -LIT_OCTNUMBER=127 -LIT_BINNUMBER=128 -LIT_STRING_1=129 -LIT_STRING_2=130 -ID_IDENTIFIER=131 -ID_LABEL=132 -ERROR=133 -SEP_LPAR=134 -SEP_RPAR=135 -SEP_COMMA=136 -OP_ADD=137 -OP_SUBTRACT=138 -OP_MULTIPLY=139 -OP_DIVIDE=140 -OP_EQUAL=141 -OP_GT=142 -OP_GTE=143 -OP_LT=144 -OP_LTE=145 -OP_MOD_2=146 -OP_SHR_2=147 -OP_SHL_2=148 -OP_NOT_2=149 -OP_AND=150 -OP_OR=151 -OP_XOR=152 -WS=153 -EOL=154 -'0/1'=81 -'0'=82 -'1'=83 -'2'=84 -'$'=98 -'('=134 -')'=135 -','=136 -'+'=137 -'-'=138 -'*'=139 -'/'=140 -'='=141 -'>'=142 -'>='=143 -'<'=144 -'<='=145 -'%'=146 -'>>'=147 -'<<'=148 -'~'=149 -'&'=150 -'|'=151 -'^'=152 +IM_01=79 +IM_0=80 +IM_1=81 +IM_2=82 +IM_WS=83 +ERROR_IM=84 +PREP_ORG=85 +PREP_EQU=86 +PREP_VAR=87 +PREP_IF=88 +PREP_ENDIF=89 +PREP_INCLUDE=90 +PREP_MACRO=91 +PREP_ENDM=92 +PREP_DB=93 +PREP_DW=94 +PREP_DS=95 +PREP_ADDR=96 +REG_A=97 +REG_B=98 +REG_C=99 +REG_D=100 +REG_E=101 +REG_H=102 +REG_L=103 +REG_IX=104 +REG_IXH=105 +REG_IXL=106 +REG_IY=107 +REG_IYH=108 +REG_IYL=109 +REG_BC=110 +REG_DE=111 +REG_HL=112 +REG_SP=113 +REG_AF=114 +REG_AFF=115 +REG_I=116 +REG_R=117 +OP_MOD=118 +OP_SHR=119 +OP_SHL=120 +OP_NOT=121 +LIT_HEXNUMBER_1=122 +LIT_NUMBER=123 +LIT_HEXNUMBER_2=124 +LIT_OCTNUMBER=125 +LIT_BINNUMBER=126 +LIT_STRING_1=127 +LIT_STRING_2=128 +ID_IDENTIFIER=129 +ID_LABEL=130 +ERROR=131 +SEP_LPAR=132 +SEP_RPAR=133 +SEP_COMMA=134 +OP_ADD=135 +OP_SUBTRACT=136 +OP_MULTIPLY=137 +OP_DIVIDE=138 +OP_EQUAL=139 +OP_GT=140 +OP_GTE=141 +OP_LT=142 +OP_LTE=143 +OP_MOD_2=144 +OP_SHR_2=145 +OP_SHL_2=146 +OP_NOT_2=147 +OP_AND=148 +OP_OR=149 +OP_XOR=150 +WS=151 +EOL=152 +'0/1'=79 +'0'=80 +'1'=81 +'2'=82 +'$'=96 +'('=132 +')'=133 +','=134 +'+'=135 +'-'=136 +'*'=137 +'/'=138 +'='=139 +'>'=140 +'>='=141 +'<'=142 +'<='=143 +'%'=144 +'>>'=145 +'<<'=146 +'~'=147 +'&'=148 +'|'=149 +'^'=150 diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 index b7aaba9d9..4a3478899 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 @@ -9,10 +9,6 @@ rStart: | rLine EOF ; -//rStart: -// EOL* rLine? (EOL+ rLine)* EOL* EOF -// ; - rLine: label=ID_LABEL? (comment EOL)* statement=rStatement comment | label=ID_LABEL comment diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java index 934a2f79e..91aae93f3 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java @@ -18,6 +18,8 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[COMMENT] = Token.COMMENT; tokenMap[EOL] = Token.WHITESPACE; tokenMap[WS] = Token.WHITESPACE; + tokenMap[IM_WS] = Token.WHITESPACE; + tokenMap[COND_WS] = Token.WHITESPACE; tokenMap[OPCODE_ADC] = Token.RESERVED; tokenMap[OPCODE_ADD] = Token.RESERVED; tokenMap[OPCODE_BIT] = Token.RESERVED; @@ -167,6 +169,8 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[ID_LABEL] = Token.IDENTIFIER; tokenMap[ERROR] = Token.ERROR; + tokenMap[ERROR_IM] = Token.ERROR; + tokenMap[ERROR_COND] = Token.ERROR; } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java index 26d4f930b..8a9339fd3 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java @@ -146,6 +146,24 @@ public void testGetChar() { ); } + @Test + public void testRET_PE() { + compile("ret pe"); + assertProgram(0xE8); + } + + @Test + public void testRET_PO() { + compile("ret po"); + assertProgram(0xE0); + } + + @Test + public void testRET_P() { + compile("ret p"); + assertProgram(0xF0); + } + @Test public void testAllInstructions() { compile( @@ -547,7 +565,7 @@ public void testAllInstructions() { 0x28, 0x20, 0x30, 0x20, 0x38, 0x20, - 0x01, 0x34, 0x12, + 0x01, 0x34, 0x12, // 10 0x11, 0x34, 0x12, 0x21, 0x34, 0x12, 0x31, 0x34, 0x12, @@ -557,7 +575,7 @@ public void testAllInstructions() { 0x39, 0x02, 0x12, - 0x0A, + 0x0A, // 20 0x1A, 0x22, 0x34, 0x12, 0x32, 0x34, 0x12, @@ -565,7 +583,7 @@ public void testAllInstructions() { 0x3A, 0x34, 0x12, 0x03, 0x13, - 0x23, + 0x23, // 30 0x33, 0x0B, 0x1B, @@ -581,7 +599,7 @@ public void testAllInstructions() { 0x05, 0x0D, 0x15, - 0x1D, + 0x1D, // 40 0x25, 0x2D, 0x3D, @@ -591,7 +609,7 @@ public void testAllInstructions() { 0x1E, 0x20, 0x26, 0x20, 0x2E, 0x20, - 0x07, + 0x07, // 50 0x0F, 0x17, 0x1F, @@ -607,7 +625,7 @@ public void testAllInstructions() { 0x45, 0x47, 0x70, - 0x71, + 0x71, // 60 0x72, 0x73, 0x74, @@ -623,7 +641,7 @@ public void testAllInstructions() { 0x98, 0x9E, 0xA0, - 0xA6, + 0xA6, // 70 0xA8, 0xAE, 0xB0, @@ -634,12 +652,12 @@ public void testAllInstructions() { 0xC8, 0xD0, 0xD8, - 0xE0, + 0xE0, // 7b 0xE8, 0xF0, 0xF8, 0xC1, - 0xD1, + 0xD1, // 80 0xE1, 0xF1, 0xC9, diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java index cd025f7c4..aaec63f62 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java @@ -15,19 +15,20 @@ public void testParseEols() { @Test public void testParseError1() { - assertTokenTypes("B :", REG_B, ERROR, EOF); + assertTokenTypes("B :", REG_B, WS, ERROR, EOF); } @Test public void testParseError2() { - assertTokenTypes("0x 9o 22b", ERROR, ERROR, ERROR, EOF); + assertTokenTypes("0x 9o 22b", ERROR, WS, ERROR, WS, ERROR, EOF); } @Test public void testParseHex1() { assertTokenTypes( "0x1 0x0 -0x5f -0xFffF 0x1BC", - LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, OP_SUBTRACT, LIT_HEXNUMBER_1, OP_SUBTRACT, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, EOF + LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, + WS, LIT_HEXNUMBER_1, EOF ); } @@ -35,8 +36,8 @@ public void testParseHex1() { public void testParseHex2() { assertTokenTypes( "1h 0h -5Fh -FFFFh 1BCh 5h -5h", - LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, - LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, EOF + LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, + WS, LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, EOF ); } @@ -44,14 +45,16 @@ public void testParseHex2() { public void testParseDecimal() { assertTokenTypes( "0 1 -2 3 -4 5 66 999", - LIT_NUMBER, LIT_NUMBER, OP_SUBTRACT, LIT_NUMBER, LIT_NUMBER, OP_SUBTRACT, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, - LIT_NUMBER, EOF + LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, + WS, LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF ); } @Test public void testParseOctal() { - assertTokenTypes("-6o 7q 11q -345O", OP_SUBTRACT, LIT_OCTNUMBER, LIT_OCTNUMBER, LIT_OCTNUMBER, OP_SUBTRACT, LIT_OCTNUMBER, EOF); + assertTokenTypes("-6o 7q 11q -345O", + OP_SUBTRACT, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, OP_SUBTRACT, LIT_OCTNUMBER, EOF + ); } @Test @@ -61,13 +64,13 @@ public void testParseBinary() { @Test public void testParseString1() { - assertTokenTypes("'' 'sss'", LIT_STRING_1, LIT_STRING_1, EOF); + assertTokenTypes("'' 'sss'", LIT_STRING_1, WS, LIT_STRING_1, EOF); assertTokenTypes("'\nsss'", LIT_STRING_1, EOF); } @Test public void testParseString2() { - assertTokenTypes("\"\" \"sss\"", LIT_STRING_2, LIT_STRING_2, EOF); + assertTokenTypes("\"\" \"sss\"", LIT_STRING_2, WS, LIT_STRING_2, EOF); assertTokenTypes("\"\nsss\"", LIT_STRING_2, EOF); } @@ -167,22 +170,25 @@ public void testParseOpcodes() { @Test public void parseIm() { - assertTokenTypesIgnoreCase("IM 0 0", OPCODE_IM, IM_0, LIT_NUMBER, EOF); - assertTokenTypesIgnoreCase("IM 0/1", OPCODE_IM, IM_01, EOF); - assertTokenTypesIgnoreCase("IM 3 0", OPCODE_IM, LIT_NUMBER, LIT_NUMBER, EOF); + assertTokenTypesIgnoreCase("IM 0 0", OPCODE_IM, IM_WS, IM_0, WS, LIT_NUMBER, EOF); + assertTokenTypesIgnoreCase("IM 0/1", OPCODE_IM, IM_WS, IM_01, EOF); + assertTokenTypesIgnoreCase("IM 3 0", OPCODE_IM, IM_WS, ERROR_IM, LIT_NUMBER, WS, LIT_NUMBER, EOF); } @Test public void parseRet() { - assertTokenTypesIgnoreCase("ret and", OPCODE_RET, OPCODE_AND, EOF); - assertTokenTypesIgnoreCase("ret nz", OPCODE_RET, COND_NZ, EOF); - assertTokenTypesIgnoreCase("ret c c", OPCODE_RET, COND_C, REG_C, EOF); + assertTokenTypesIgnoreCase("ret and", OPCODE_RET, COND_WS, ERROR_COND, OPCODE_AND, EOF); + assertTokenTypesIgnoreCase("ret nz", OPCODE_RET, COND_WS, COND_NZ, EOF); + assertTokenTypesIgnoreCase("ret c c", OPCODE_RET, COND_WS, COND_C, WS, REG_C, EOF); + assertTokenTypesIgnoreCase("ret pe", OPCODE_RET, COND_WS, COND_PE, EOF); + assertTokenTypesIgnoreCase("ret po", OPCODE_RET, COND_WS, COND_PO, EOF); + assertTokenTypesIgnoreCase("ret p", OPCODE_RET, COND_WS, COND_P, EOF); } @Test public void parseJp() { - assertTokenTypesIgnoreCase("jp c c", OPCODE_JP, COND_C, REG_C, EOF); - assertTokenTypesIgnoreCase("jp hl", OPCODE_JP, REG_HL, EOF); + assertTokenTypesIgnoreCase("jp c c", OPCODE_JP, COND_WS, COND_C, WS, REG_C, EOF); + assertTokenTypesIgnoreCase("jp hl", OPCODE_JP, COND_WS, ERROR_COND, REG_HL, EOF); } @Test @@ -245,14 +251,14 @@ public void testOperators2() { @Test public void testIdentifier() { - assertTokenTypes("u @ ? _", ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, EOF); - assertTokenTypes("a@ abc ZZ_ H005", ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, EOF); + assertTokenTypes("u @ ? _", ID_IDENTIFIER, WS, ID_IDENTIFIER, WS, ID_IDENTIFIER, WS, ID_IDENTIFIER, EOF); + assertTokenTypes("a@ abc ZZ_ H005", ID_IDENTIFIER, WS, ID_IDENTIFIER, WS, ID_IDENTIFIER, WS, ID_IDENTIFIER, EOF); } @Test public void testLabel() { - assertTokenTypes("u: @: ?: _:", ID_LABEL, ID_LABEL, ID_LABEL, ID_LABEL, EOF); - assertTokenTypes("a@: abc: ZZ_: H005:", ID_LABEL, ID_LABEL, ID_LABEL, ID_LABEL, EOF); + assertTokenTypes("u: @: ?: _:", ID_LABEL, WS, ID_LABEL, WS, ID_LABEL, WS, ID_LABEL, EOF); + assertTokenTypes("a@: abc: ZZ_: H005:", ID_LABEL, WS, ID_LABEL, WS, ID_LABEL, WS, ID_LABEL, EOF); assertTokenTypes("a:", ID_LABEL, EOF); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java index 45a1d3fec..c08d0ccc0 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java @@ -4,9 +4,11 @@ import net.emustudio.plugins.compiler.asZ80.ast.Node; import net.emustudio.plugins.compiler.asZ80.ast.Program; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprCurrentAddress; +import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprInfix; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.asZ80.ast.instr.*; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoLabel; import org.junit.Test; import java.util.Random; @@ -34,6 +36,9 @@ public void testInstrNoArgs() { assertInstr("ccf", OPCODE_CCF, 0, 7, 7); assertInstr("halt", OPCODE_HALT, 1, 6, 6); assertInstr("ret", OPCODE_RET, 3, 1, 1); + assertInstr("ret po", OPCODE_RET, 3, 4, 0); + assertInstr("ret pe", OPCODE_RET, 3, 5, 0); + assertInstr("ret p", OPCODE_RET, 3, 6, 0); assertInstr("exx", OPCODE_EXX, 3, 3, 1); assertInstr("jp hl", OPCODE_JP, 3, 5, 1); assertInstr("jp (hl)", OPCODE_JP, 3, 5, 1); @@ -156,6 +161,9 @@ public void testInstrExpr() { assertInstrExpr("out (", "), a", OPCODE_OUT, 3, 2, 3); assertInstrExpr("in a, (", ")", OPCODE_IN, 3, 3, 3); assertInstrExpr("call ", OPCODE_CALL, 3, 0, 1, 5); + assertInstrExpr("call po,", OPCODE_CALL, 3, 4, 4); + assertInstrExpr("call pe,", OPCODE_CALL, 3, 5, 4); + assertInstrExpr("call p,", OPCODE_CALL, 3, 6, 4); assertInstrExpr("add a,", OPCODE_ADD, 3, 0, 6); assertInstrExpr("adc a,", OPCODE_ADC, 3, 1, 6); assertInstrExpr("sub", OPCODE_SUB, 3, 2, 6); @@ -167,6 +175,18 @@ public void testInstrExpr() { assertInstrExpr("rst", OPCODE_RST, 3, 0, 7); } + @Test + public void testCallLabelWithConditionPrefix() { + Program program = parseProgram("peter: call peter"); + System.out.println(program); + assertTrees(new Program() + .addChild(new PseudoLabel(0, 0, "peter") + .addChild(new Instr(0, 0, OPCODE_CALL, 3, 1, 5) + .addChild(new ExprId(0, 0, "peter")))), + program + ); + } + @Test public void testInstrXDCB() { Random random = new Random(); @@ -392,11 +412,11 @@ private void assertInstrXDExprExpr(String instrPrefix, int prefix) { Node expr = new ExprNumber(0, 0, 5); forStringCaseVariations(instrPrefix, prefixVariation -> { - Program program = parseProgram(prefixVariation + " $ + 5), 5"); - assertTrees(new Program() - .addChild(new InstrXD(0, 0, OPCODE_LD, prefix, 0, 6, 6) - .addChild(disp) - .addChild(expr)), program); + Program program = parseProgram(prefixVariation + " $ + 5), 5"); + assertTrees(new Program() + .addChild(new InstrXD(0, 0, OPCODE_LD, prefix, 0, 6, 6) + .addChild(disp) + .addChild(expr)), program); }); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java index 7b2e4b86a..1bf97b13c 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java @@ -18,25 +18,25 @@ public class ParsingUtilsTest { @Test public void testParseLitString() { List tokens = getTokens("'te\"x\"t1' \"te'x't2\""); - Utils.assertTokenTypes(tokens, LIT_STRING_1, LIT_STRING_2, EOF); + Utils.assertTokenTypes(tokens, LIT_STRING_1, WS, LIT_STRING_2, EOF); Assert.assertEquals("te\"x\"t1", ParsingUtils.parseLitString(tokens.get(0))); - assertEquals("te'x't2", ParsingUtils.parseLitString(tokens.get(1))); + assertEquals("te'x't2", ParsingUtils.parseLitString(tokens.get(2))); } @Test public void testParseLitHex1() { List tokens = getTokens("0x22F 0XAA55"); - assertTokenTypes(tokens, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, EOF); + assertTokenTypes(tokens, LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, EOF); assertEquals(0x22F, ParsingUtils.parseLitHex1(tokens.get(0))); - assertEquals(0xAA55, ParsingUtils.parseLitHex1(tokens.get(1))); + assertEquals(0xAA55, ParsingUtils.parseLitHex1(tokens.get(2))); } @Test public void testParseLitHex2() { List tokens = getTokens("022Fh AA55H"); - assertTokenTypes(tokens, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, EOF); + assertTokenTypes(tokens, LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, EOF); assertEquals(0x22F, ParsingUtils.parseLitHex2(tokens.get(0))); - assertEquals(0xAA55, ParsingUtils.parseLitHex2(tokens.get(1))); + assertEquals(0xAA55, ParsingUtils.parseLitHex2(tokens.get(2))); } @Test @@ -44,13 +44,12 @@ public void testParseLitOct() { List tokens = getTokens("22q 55O 77Q 001o"); assertTokenTypes( tokens, - LIT_OCTNUMBER, LIT_OCTNUMBER, LIT_OCTNUMBER, - LIT_OCTNUMBER, EOF + LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, EOF ); assertEquals(18, ParsingUtils.parseLitOct(tokens.get(0))); - assertEquals(45, ParsingUtils.parseLitOct(tokens.get(1))); - assertEquals(63, ParsingUtils.parseLitOct(tokens.get(2))); - assertEquals(1, ParsingUtils.parseLitOct(tokens.get(3))); + assertEquals(45, ParsingUtils.parseLitOct(tokens.get(2))); + assertEquals(63, ParsingUtils.parseLitOct(tokens.get(4))); + assertEquals(1, ParsingUtils.parseLitOct(tokens.get(6))); } @Test @@ -58,11 +57,11 @@ public void testParseLitDec() { List tokens = getTokens("22 55 00"); assertTokenTypes( tokens, - LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, EOF + LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF ); assertEquals(22, ParsingUtils.parseLitDec(tokens.get(0))); - assertEquals(55, ParsingUtils.parseLitDec(tokens.get(1))); - assertEquals(0, ParsingUtils.parseLitDec(tokens.get(2))); + assertEquals(55, ParsingUtils.parseLitDec(tokens.get(2))); + assertEquals(0, ParsingUtils.parseLitDec(tokens.get(4))); } @Test @@ -70,10 +69,10 @@ public void testParseLitBin() { List tokens = getTokens("000b 0101101b 111b"); assertTokenTypes( tokens, - LIT_BINNUMBER, LIT_BINNUMBER, LIT_BINNUMBER, EOF + LIT_BINNUMBER, WS, LIT_BINNUMBER, WS, LIT_BINNUMBER, EOF ); assertEquals(0, ParsingUtils.parseLitBin(tokens.get(0))); - assertEquals(45, ParsingUtils.parseLitBin(tokens.get(1))); - assertEquals(7, ParsingUtils.parseLitBin(tokens.get(2))); + assertEquals(45, ParsingUtils.parseLitBin(tokens.get(2))); + assertEquals(7, ParsingUtils.parseLitBin(tokens.get(4))); } } diff --git a/test_report.gradle b/test_report.gradle index 3ec8263af..42d359ce9 100644 --- a/test_report.gradle +++ b/test_report.gradle @@ -22,7 +22,7 @@ allprojects { project -> showStackTraces true } - ignoreFailures = true // Always try to run all tests for all modules + ignoreFailures = false // true to always run all tests for all modules afterSuite { desc, result -> From ea75479ba826fa7104eaa0c1accc7cd53994ca56 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 14 Mar 2022 12:40:12 +0000 Subject: [PATCH 117/314] [#201] as-z80: remove println --- .../emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java index c08d0ccc0..98b7ca61b 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java @@ -178,7 +178,6 @@ public void testInstrExpr() { @Test public void testCallLabelWithConditionPrefix() { Program program = parseProgram("peter: call peter"); - System.out.println(program); assertTrees(new Program() .addChild(new PseudoLabel(0, 0, "peter") .addChild(new Instr(0, 0, OPCODE_CALL, 3, 1, 5) From 2487d55bdf8d5a77da3ca2dccd6f97d238e811bb Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 14 Mar 2022 12:59:41 +0000 Subject: [PATCH 118/314] [#201] as-z80 & as-8080: fix parsers --- .../as-8080/src/main/antlr/As8080Lexer.g4 | 6 +- .../as-8080/src/main/antlr/As8080Parser.g4 | 11 +- .../as8080/visitors/CreatePseudoVisitor.java | 10 +- .../parser/LexicalAnalyzerImplTest.java | 39 ++-- .../as8080/parser/ParsingUtilsTest.java | 35 ++- .../as-z80/src/main/antlr/AsZ80Lexer.g4 | 4 +- .../as-z80/src/main/antlr/AsZ80Lexer.tokens | 204 +++++++++--------- .../asZ80/parser/LexicalAnalyzerImplTest.java | 14 +- 8 files changed, 173 insertions(+), 150 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 index 87a785e59..bf9ae02c1 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.g4 @@ -1,7 +1,7 @@ lexer grammar As8080Lexer; -COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]* -> skip; -COMMENT2: '/*' .*? '*/' -> skip; +COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]*; +COMMENT2: '/*' .*? '*/'; fragment A: [aA]; fragment B: [bB]; @@ -184,5 +184,5 @@ OP_AND_2: '&'; OP_OR_2: '|'; OP_XOR_2: '^'; -WS : [ \t\f]+ -> skip; +WS : [ \t\f]+ -> channel(HIDDEN); EOL: '\r'? '\n'; diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index 6957fef3f..e8219507d 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -5,12 +5,17 @@ options { } rStart: - EOL* rLine? (EOL+ rLine)* EOL* EOF + (rLine EOL rLine)* EOF + | rLine EOF ; rLine: - label=ID_LABEL? EOL* statement=rStatement - | label=ID_LABEL; + label=ID_LABEL? (comment EOL)* statement=rStatement comment + | label=ID_LABEL comment + | comment + ; + +comment: COMMENT? | COMMENT2?; rStatement: instr=rInstruction diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java index 941777fb4..970673a5e 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java @@ -42,7 +42,10 @@ public Node visitPseudoIf(PseudoIfContext ctx) { ifExpr.addChild(expr); pseudo.addChild(ifExpr); for (RLineContext line : ctx.rLine()) { - pseudo.addChild(CreateVisitors.line.visitRLine(line)); + Node rLine = CreateVisitors.line.visitRLine(line); + if (rLine != null) { + pseudo.addChild(rLine); + } } return pseudo; } @@ -60,7 +63,10 @@ public Node visitPseudoMacroDef(PseudoMacroDefContext ctx) { } } for (RLineContext line : ctx.rLine()) { - pseudo.addChild(CreateVisitors.line.visitRLine(line)); + Node rLine = CreateVisitors.line.visitRLine(line); + if (rLine != null) { + pseudo.addChild(rLine); + } } return pseudo; } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java index a7a9d1af0..cd992f72f 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java @@ -15,19 +15,20 @@ public void testParseEols() { @Test public void testParseError1() { - assertTokenTypes("B !", REG_B, ERROR, EOF); + assertTokenTypes("B !", REG_B, WS, ERROR, EOF); } @Test public void testParseError2() { - assertTokenTypes("0x 9o 22b", ERROR, ERROR, ERROR, EOF); + assertTokenTypes("0x 9o 22b", ERROR, WS, ERROR, WS, ERROR, EOF); } @Test public void testParseHex1() { assertTokenTypes( "0x1 0x0 -0x5f -0xFffF 0x1BC", - LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, OP_SUBTRACT, LIT_HEXNUMBER_1, OP_SUBTRACT, LIT_HEXNUMBER_1, LIT_HEXNUMBER_1, EOF + LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, + WS, LIT_HEXNUMBER_1, EOF ); } @@ -35,8 +36,8 @@ public void testParseHex1() { public void testParseHex2() { assertTokenTypes( "1h 0h -5Fh -FFFFh 1BCh 5h -5h", - LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, LIT_HEXNUMBER_2, - LIT_HEXNUMBER_2, OP_SUBTRACT, LIT_HEXNUMBER_2, EOF + LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, + WS, LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, EOF ); } @@ -44,14 +45,16 @@ public void testParseHex2() { public void testParseDecimal() { assertTokenTypes( "0 1 -2 3 -4 5 66 999", - LIT_NUMBER, LIT_NUMBER, OP_SUBTRACT, LIT_NUMBER, LIT_NUMBER, OP_SUBTRACT, LIT_NUMBER, LIT_NUMBER, LIT_NUMBER, - LIT_NUMBER, EOF + LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, + WS, LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF ); } @Test public void testParseOctal() { - assertTokenTypes("-6o 7q 11q -345O", OP_SUBTRACT, LIT_OCTNUMBER, LIT_OCTNUMBER, LIT_OCTNUMBER, OP_SUBTRACT, LIT_OCTNUMBER, EOF); + assertTokenTypes( + "-6o 7q 11q -345O", + OP_SUBTRACT, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, OP_SUBTRACT, LIT_OCTNUMBER, EOF); } @Test @@ -61,13 +64,13 @@ public void testParseBinary() { @Test public void testParseString1() { - assertTokenTypes("'' 'sss'", LIT_STRING_1, LIT_STRING_1, EOF); + assertTokenTypes("'' 'sss'", LIT_STRING_1, WS, LIT_STRING_1, EOF); assertTokenTypes("'\nsss'", LIT_STRING_1, EOF); } @Test public void testParseString2() { - assertTokenTypes("\"\" \"sss\"", LIT_STRING_2, LIT_STRING_2, EOF); + assertTokenTypes("\"\" \"sss\"", LIT_STRING_2, WS, LIT_STRING_2, EOF); assertTokenTypes("\"\nsss\"", LIT_STRING_2, EOF); } @@ -83,14 +86,14 @@ public void testParseString2Error() { @Test public void testParseComment1() { - assertTokenTypes("// comment fun1", EOF); - assertTokenTypes("# comment fun1", EOF); - assertTokenTypes("; comment fun1", EOF); + assertTokenTypes("// comment fun1", COMMENT, EOF); + assertTokenTypes("# comment fun1", COMMENT, EOF); + assertTokenTypes("; comment fun1", COMMENT, EOF); } @Test public void testParseComment2() { - assertTokenTypes("/*\n*\n* comment fun1\n\n*/", EOF); + assertTokenTypes("/*\n*\n* comment fun1\n\n*/", COMMENT2, EOF); } @Test @@ -228,14 +231,14 @@ public void testOperators2() { @Test public void testIdentifier() { - assertTokenTypes("u @ ? _", ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, EOF); - assertTokenTypes("a@ abc ZZ_ H005", ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, ID_IDENTIFIER, EOF); + assertTokenTypes("u @ ? _", ID_IDENTIFIER, WS, ID_IDENTIFIER, WS, ID_IDENTIFIER, WS, ID_IDENTIFIER, EOF); + assertTokenTypes("a@ abc ZZ_ H005", ID_IDENTIFIER, WS, ID_IDENTIFIER, WS, ID_IDENTIFIER, WS, ID_IDENTIFIER, EOF); } @Test public void testLabel() { - assertTokenTypes("u: @: ?: _:", ID_LABEL, ID_LABEL, ID_LABEL, ID_LABEL, EOF); - assertTokenTypes("a@: abc: ZZ_: H005:", ID_LABEL, ID_LABEL, ID_LABEL, ID_LABEL, EOF); + assertTokenTypes("u: @: ?: _:", ID_LABEL, WS, ID_LABEL, WS, ID_LABEL, WS, ID_LABEL, EOF); + assertTokenTypes("a@: abc: ZZ_: H005:", ID_LABEL, WS, ID_LABEL, WS, ID_LABEL, WS, ID_LABEL, EOF); assertTokenTypes("a:", ID_LABEL, EOF); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsingUtilsTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsingUtilsTest.java index 88c9f4b07..ceacd7677 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsingUtilsTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsingUtilsTest.java @@ -1,6 +1,5 @@ package net.emustudio.plugins.compiler.as8080.parser; -import net.emustudio.plugins.compiler.as8080.As8080Parser; import net.emustudio.plugins.compiler.as8080.ParsingUtils; import net.emustudio.plugins.compiler.as8080.Utils; import org.antlr.v4.runtime.Token; @@ -9,6 +8,7 @@ import java.util.List; +import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; import static net.emustudio.plugins.compiler.as8080.Utils.assertTokenTypes; import static net.emustudio.plugins.compiler.as8080.Utils.getTokens; import static org.junit.Assert.assertEquals; @@ -18,25 +18,25 @@ public class ParsingUtilsTest { @Test public void testParseLitString() { List tokens = getTokens("'te\"x\"t1' \"te'x't2\""); - Utils.assertTokenTypes(tokens, As8080Parser.LIT_STRING_1, As8080Parser.LIT_STRING_2, As8080Parser.EOF); + Utils.assertTokenTypes(tokens, LIT_STRING_1, WS, LIT_STRING_2, EOF); Assert.assertEquals("te\"x\"t1", ParsingUtils.parseLitString(tokens.get(0))); - assertEquals("te'x't2", ParsingUtils.parseLitString(tokens.get(1))); + assertEquals("te'x't2", ParsingUtils.parseLitString(tokens.get(2))); } @Test public void testParseLitHex1() { List tokens = getTokens("0x22F 0XAA55"); - assertTokenTypes(tokens, As8080Parser.LIT_HEXNUMBER_1, As8080Parser.LIT_HEXNUMBER_1, As8080Parser.EOF); + assertTokenTypes(tokens, LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, EOF); assertEquals(0x22F, ParsingUtils.parseLitHex1(tokens.get(0))); - assertEquals(0xAA55, ParsingUtils.parseLitHex1(tokens.get(1))); + assertEquals(0xAA55, ParsingUtils.parseLitHex1(tokens.get(2))); } @Test public void testParseLitHex2() { List tokens = getTokens("022Fh AA55H"); - assertTokenTypes(tokens, As8080Parser.LIT_HEXNUMBER_2, As8080Parser.LIT_HEXNUMBER_2, As8080Parser.EOF); + assertTokenTypes(tokens, LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, EOF); assertEquals(0x22F, ParsingUtils.parseLitHex2(tokens.get(0))); - assertEquals(0xAA55, ParsingUtils.parseLitHex2(tokens.get(1))); + assertEquals(0xAA55, ParsingUtils.parseLitHex2(tokens.get(2))); } @Test @@ -44,13 +44,12 @@ public void testParseLitOct() { List tokens = getTokens("22q 55O 77Q 001o"); assertTokenTypes( tokens, - As8080Parser.LIT_OCTNUMBER, As8080Parser.LIT_OCTNUMBER, As8080Parser.LIT_OCTNUMBER, - As8080Parser.LIT_OCTNUMBER, As8080Parser.EOF + LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, EOF ); assertEquals(18, ParsingUtils.parseLitOct(tokens.get(0))); - assertEquals(45, ParsingUtils.parseLitOct(tokens.get(1))); - assertEquals(63, ParsingUtils.parseLitOct(tokens.get(2))); - assertEquals(1, ParsingUtils.parseLitOct(tokens.get(3))); + assertEquals(45, ParsingUtils.parseLitOct(tokens.get(2))); + assertEquals(63, ParsingUtils.parseLitOct(tokens.get(4))); + assertEquals(1, ParsingUtils.parseLitOct(tokens.get(6))); } @Test @@ -58,11 +57,11 @@ public void testParseLitDec() { List tokens = getTokens("22 55 00"); assertTokenTypes( tokens, - As8080Parser.LIT_NUMBER, As8080Parser.LIT_NUMBER, As8080Parser.LIT_NUMBER, As8080Parser.EOF + LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF ); assertEquals(22, ParsingUtils.parseLitDec(tokens.get(0))); - assertEquals(55, ParsingUtils.parseLitDec(tokens.get(1))); - assertEquals(0, ParsingUtils.parseLitDec(tokens.get(2))); + assertEquals(55, ParsingUtils.parseLitDec(tokens.get(2))); + assertEquals(0, ParsingUtils.parseLitDec(tokens.get(4))); } @Test @@ -70,10 +69,10 @@ public void testParseLitBin() { List tokens = getTokens("000b 0101101b 111b"); assertTokenTypes( tokens, - As8080Parser.LIT_BINNUMBER, As8080Parser.LIT_BINNUMBER, As8080Parser.LIT_BINNUMBER, As8080Parser.EOF + LIT_BINNUMBER, WS, LIT_BINNUMBER, WS, LIT_BINNUMBER, EOF ); assertEquals(0, ParsingUtils.parseLitBin(tokens.get(0))); - assertEquals(45, ParsingUtils.parseLitBin(tokens.get(1))); - assertEquals(7, ParsingUtils.parseLitBin(tokens.get(2))); + assertEquals(45, ParsingUtils.parseLitBin(tokens.get(2))); + assertEquals(7, ParsingUtils.parseLitBin(tokens.get(4))); } } diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 index eebe7c339..6f2624b0a 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.g4 @@ -110,7 +110,7 @@ COND_PE: P E ({(_input.LA(1) == -1) || (" ,\t\f\n\r;#/'\"()[]{}!=-+*<>\\%^&|$.". COND_PO: P O ({(_input.LA(1) == -1) || (" ,\t\f\n\r;#/'\"()[]{}!=-+*<>\\%^&|$.".indexOf((char)_input.LA(1)) != -1) }?) -> popMode; COND_P: P ({(_input.LA(1) == -1) || (" ,\t\f\n\r;#/'\"()[]{}!=-+*<>\\%^&|$.".indexOf((char)_input.LA(1)) != -1) }?) -> popMode; COND_WS: [ \t\f]+ -> channel(HIDDEN); -ERROR_COND: () -> popMode,channel(HIDDEN); +ERROR_COND: () -> popMode,skip; mode IM_NUMBER; IM_01: '0/1' -> popMode; @@ -118,7 +118,7 @@ IM_0: '0' -> popMode; IM_1: '1' -> popMode; IM_2: '2' -> popMode; IM_WS: [ \t\f]+ -> channel(HIDDEN); -ERROR_IM: ({"012".indexOf((char) _input.LA(1)) == -1}?) -> popMode,channel(HIDDEN); +ERROR_IM: ({"012".indexOf((char) _input.LA(1)) == -1}?) -> popMode,skip; mode DEFAULT_MODE; diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens index 35cfd87dd..4cbc1ea56 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens @@ -73,104 +73,106 @@ COND_NC=72 COND_Z=73 COND_NZ=74 COND_M=75 -COND_P=76 -COND_PE=77 -COND_PO=78 -IM_01=79 -IM_0=80 -IM_1=81 -IM_2=82 -IM_WS=83 -ERROR_IM=84 -PREP_ORG=85 -PREP_EQU=86 -PREP_VAR=87 -PREP_IF=88 -PREP_ENDIF=89 -PREP_INCLUDE=90 -PREP_MACRO=91 -PREP_ENDM=92 -PREP_DB=93 -PREP_DW=94 -PREP_DS=95 -PREP_ADDR=96 -REG_A=97 -REG_B=98 -REG_C=99 -REG_D=100 -REG_E=101 -REG_H=102 -REG_L=103 -REG_IX=104 -REG_IXH=105 -REG_IXL=106 -REG_IY=107 -REG_IYH=108 -REG_IYL=109 -REG_BC=110 -REG_DE=111 -REG_HL=112 -REG_SP=113 -REG_AF=114 -REG_AFF=115 -REG_I=116 -REG_R=117 -OP_MOD=118 -OP_SHR=119 -OP_SHL=120 -OP_NOT=121 -LIT_HEXNUMBER_1=122 -LIT_NUMBER=123 -LIT_HEXNUMBER_2=124 -LIT_OCTNUMBER=125 -LIT_BINNUMBER=126 -LIT_STRING_1=127 -LIT_STRING_2=128 -ID_IDENTIFIER=129 -ID_LABEL=130 -ERROR=131 -SEP_LPAR=132 -SEP_RPAR=133 -SEP_COMMA=134 -OP_ADD=135 -OP_SUBTRACT=136 -OP_MULTIPLY=137 -OP_DIVIDE=138 -OP_EQUAL=139 -OP_GT=140 -OP_GTE=141 -OP_LT=142 -OP_LTE=143 -OP_MOD_2=144 -OP_SHR_2=145 -OP_SHL_2=146 -OP_NOT_2=147 -OP_AND=148 -OP_OR=149 -OP_XOR=150 -WS=151 -EOL=152 -'0/1'=79 -'0'=80 -'1'=81 -'2'=82 -'$'=96 -'('=132 -')'=133 -','=134 -'+'=135 -'-'=136 -'*'=137 -'/'=138 -'='=139 -'>'=140 -'>='=141 -'<'=142 -'<='=143 -'%'=144 -'>>'=145 -'<<'=146 -'~'=147 -'&'=148 -'|'=149 -'^'=150 +COND_PE=76 +COND_PO=77 +COND_P=78 +COND_WS=79 +ERROR_COND=80 +IM_01=81 +IM_0=82 +IM_1=83 +IM_2=84 +IM_WS=85 +ERROR_IM=86 +PREP_ORG=87 +PREP_EQU=88 +PREP_VAR=89 +PREP_IF=90 +PREP_ENDIF=91 +PREP_INCLUDE=92 +PREP_MACRO=93 +PREP_ENDM=94 +PREP_DB=95 +PREP_DW=96 +PREP_DS=97 +PREP_ADDR=98 +REG_A=99 +REG_B=100 +REG_C=101 +REG_D=102 +REG_E=103 +REG_H=104 +REG_L=105 +REG_IX=106 +REG_IXH=107 +REG_IXL=108 +REG_IY=109 +REG_IYH=110 +REG_IYL=111 +REG_BC=112 +REG_DE=113 +REG_HL=114 +REG_SP=115 +REG_AF=116 +REG_AFF=117 +REG_I=118 +REG_R=119 +OP_MOD=120 +OP_SHR=121 +OP_SHL=122 +OP_NOT=123 +LIT_HEXNUMBER_1=124 +LIT_NUMBER=125 +LIT_HEXNUMBER_2=126 +LIT_OCTNUMBER=127 +LIT_BINNUMBER=128 +LIT_STRING_1=129 +LIT_STRING_2=130 +ID_IDENTIFIER=131 +ID_LABEL=132 +ERROR=133 +SEP_LPAR=134 +SEP_RPAR=135 +SEP_COMMA=136 +OP_ADD=137 +OP_SUBTRACT=138 +OP_MULTIPLY=139 +OP_DIVIDE=140 +OP_EQUAL=141 +OP_GT=142 +OP_GTE=143 +OP_LT=144 +OP_LTE=145 +OP_MOD_2=146 +OP_SHR_2=147 +OP_SHL_2=148 +OP_NOT_2=149 +OP_AND=150 +OP_OR=151 +OP_XOR=152 +WS=153 +EOL=154 +'0/1'=81 +'0'=82 +'1'=83 +'2'=84 +'$'=98 +'('=134 +')'=135 +','=136 +'+'=137 +'-'=138 +'*'=139 +'/'=140 +'='=141 +'>'=142 +'>='=143 +'<'=144 +'<='=145 +'%'=146 +'>>'=147 +'<<'=148 +'~'=149 +'&'=150 +'|'=151 +'^'=152 diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java index aaec63f62..fbdcc3d73 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java @@ -172,12 +172,12 @@ public void testParseOpcodes() { public void parseIm() { assertTokenTypesIgnoreCase("IM 0 0", OPCODE_IM, IM_WS, IM_0, WS, LIT_NUMBER, EOF); assertTokenTypesIgnoreCase("IM 0/1", OPCODE_IM, IM_WS, IM_01, EOF); - assertTokenTypesIgnoreCase("IM 3 0", OPCODE_IM, IM_WS, ERROR_IM, LIT_NUMBER, WS, LIT_NUMBER, EOF); + assertTokenTypesIgnoreCase("IM 3 0", OPCODE_IM, IM_WS, LIT_NUMBER, WS, LIT_NUMBER, EOF); } @Test public void parseRet() { - assertTokenTypesIgnoreCase("ret and", OPCODE_RET, COND_WS, ERROR_COND, OPCODE_AND, EOF); + assertTokenTypesIgnoreCase("ret and", OPCODE_RET, COND_WS, OPCODE_AND, EOF); assertTokenTypesIgnoreCase("ret nz", OPCODE_RET, COND_WS, COND_NZ, EOF); assertTokenTypesIgnoreCase("ret c c", OPCODE_RET, COND_WS, COND_C, WS, REG_C, EOF); assertTokenTypesIgnoreCase("ret pe", OPCODE_RET, COND_WS, COND_PE, EOF); @@ -188,7 +188,15 @@ public void parseRet() { @Test public void parseJp() { assertTokenTypesIgnoreCase("jp c c", OPCODE_JP, COND_WS, COND_C, WS, REG_C, EOF); - assertTokenTypesIgnoreCase("jp hl", OPCODE_JP, COND_WS, ERROR_COND, REG_HL, EOF); + assertTokenTypesIgnoreCase("jp hl", OPCODE_JP, COND_WS, REG_HL, EOF); + } + + @Test + public void parseCall() { + assertTokenTypesIgnoreCase("call pe!", OPCODE_CALL, COND_WS, COND_PE, ERROR, EOF); + assertTokenTypesIgnoreCase("call pet", OPCODE_CALL, COND_WS, ID_IDENTIFIER, EOF); + assertTokenTypesIgnoreCase("call pe?", OPCODE_CALL, COND_WS, ID_IDENTIFIER, EOF); + assertTokenTypesIgnoreCase("call pe>", OPCODE_CALL, COND_WS, COND_PE, OP_GT, EOF); } @Test From b72fbe33dbd7c000dd99b09c74015a5d29f2942d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 14 Mar 2022 13:09:40 +0000 Subject: [PATCH 119/314] [#201] as-z80: tests --- .../asZ80/parser/LexicalAnalyzerImplTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java index fbdcc3d73..aae52afd2 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java @@ -197,6 +197,26 @@ public void parseCall() { assertTokenTypesIgnoreCase("call pet", OPCODE_CALL, COND_WS, ID_IDENTIFIER, EOF); assertTokenTypesIgnoreCase("call pe?", OPCODE_CALL, COND_WS, ID_IDENTIFIER, EOF); assertTokenTypesIgnoreCase("call pe>", OPCODE_CALL, COND_WS, COND_PE, OP_GT, EOF); + assertTokenTypesIgnoreCase("call pe#", OPCODE_CALL, COND_WS, COND_PE, COMMENT, EOF); + assertTokenTypesIgnoreCase("call pe\"", OPCODE_CALL, COND_WS, COND_PE, ERROR, EOF); + assertTokenTypesIgnoreCase("call pe'", OPCODE_CALL, COND_WS, COND_PE, ERROR, EOF); + assertTokenTypesIgnoreCase("call pe(", OPCODE_CALL, COND_WS, COND_PE, SEP_LPAR, EOF); + assertTokenTypesIgnoreCase("call pe)", OPCODE_CALL, COND_WS, COND_PE, SEP_RPAR, EOF); + assertTokenTypesIgnoreCase("call pe,", OPCODE_CALL, COND_WS, COND_PE, SEP_COMMA, EOF); + assertTokenTypesIgnoreCase("call pe.", OPCODE_CALL, COND_WS, COND_PE, ERROR, EOF); + assertTokenTypesIgnoreCase("call pe=", OPCODE_CALL, COND_WS, COND_PE, OP_EQUAL, EOF); + assertTokenTypesIgnoreCase("call pe<", OPCODE_CALL, COND_WS, COND_PE, OP_LT, EOF); + assertTokenTypesIgnoreCase("call pe&", OPCODE_CALL, COND_WS, COND_PE, OP_AND, EOF); + assertTokenTypesIgnoreCase("call pe+", OPCODE_CALL, COND_WS, COND_PE, OP_ADD, EOF); + assertTokenTypesIgnoreCase("call pe-", OPCODE_CALL, COND_WS, COND_PE, OP_SUBTRACT, EOF); + assertTokenTypesIgnoreCase("call pe/", OPCODE_CALL, COND_WS, COND_PE, OP_DIVIDE, EOF); + assertTokenTypesIgnoreCase("call pe;", OPCODE_CALL, COND_WS, COND_PE, COMMENT, EOF); + assertTokenTypesIgnoreCase("call pe/**/", OPCODE_CALL, COND_WS, COND_PE, COMMENT2, EOF); + assertTokenTypesIgnoreCase("call pe", OPCODE_CALL, COND_WS, COND_PE, EOF); + assertTokenTypesIgnoreCase("call pe\n", OPCODE_CALL, COND_WS, COND_PE, EOL, EOF); + assertTokenTypesIgnoreCase("call pe\f", OPCODE_CALL, COND_WS, COND_PE, WS, EOF); + assertTokenTypesIgnoreCase("call pe\r", OPCODE_CALL, COND_WS, COND_PE, EOF); + assertTokenTypesIgnoreCase("call pe0", OPCODE_CALL, COND_WS, ID_IDENTIFIER, EOF); } @Test From 108baace9018d3dca294382bf7a836a06de8d2d4 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 15 Mar 2022 10:32:33 +0000 Subject: [PATCH 120/314] [#201] as-8080, as-z80: fix includes --- plugins/compiler/as-8080/build.gradle | 1 + .../compiler/as8080/LexicalAnalyzerImpl.java | 3 ++ .../visitors/ExpandIncludesVisitor.java | 38 ++++++++++++++---- plugins/compiler/as-ssem/build.gradle | 1 + plugins/compiler/as-z80/build.gradle | 1 + .../plugins/compiler/asZ80/AssemblerZ80.java | 1 + .../plugins/compiler/asZ80/ast/NameSpace.java | 1 + .../asZ80/visitors/ExpandIncludesVisitor.java | 40 +++++++++++++++---- .../compiler/brainc-brainduck/build.gradle | 1 + plugins/compiler/ramc-ram/build.gradle | 1 + plugins/compiler/raspc-rasp/build.gradle | 1 + plugins/cpu/brainduck-cpu/build.gradle | 1 + plugins/cpu/ram-cpu/build.gradle | 3 +- plugins/cpu/rasp-cpu/build.gradle | 3 +- plugins/cpu/ssem-cpu/build.gradle | 1 + plugins/device/88-dcdd/build.gradle | 1 + plugins/device/88-sio/build.gradle | 1 + plugins/device/abstract-tape/build.gradle | 1 + plugins/device/adm3A-terminal/build.gradle | 1 + .../device/brainduck-terminal/build.gradle | 1 + plugins/device/simhPseudo-z80/build.gradle | 1 + plugins/device/ssem-display/build.gradle | 1 + plugins/memory/brainduck-mem/build.gradle | 1 + plugins/memory/byte-mem/build.gradle | 1 + plugins/memory/ram-mem/build.gradle | 1 + plugins/memory/rasp-mem/build.gradle | 1 + plugins/memory/ssem-mem/build.gradle | 1 + 27 files changed, 92 insertions(+), 17 deletions(-) diff --git a/plugins/compiler/as-8080/build.gradle b/plugins/compiler/as-8080/build.gradle index 1a40f32dc..9e1405c42 100644 --- a/plugins/compiler/as-8080/build.gradle +++ b/plugins/compiler/as-8080/build.gradle @@ -23,6 +23,7 @@ plugins { id 'java' id 'idea' id 'antlr' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java index e6b697386..0e96795a2 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java @@ -200,6 +200,9 @@ public void reset(InputStream inputStream) throws IOException { } private int convertLexerTokenType(int tokenType) { + if (tokenType == EOF) { + return Token.EOF; + } return tokenMap[tokenType]; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java index 35f07c401..b1ba67ed0 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java @@ -8,11 +8,10 @@ import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; +import java.io.File; import java.io.IOException; -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; +import java.nio.file.Path; +import java.util.*; import static net.emustudio.plugins.compiler.as8080.CompileError.couldNotReadFile; import static net.emustudio.plugins.compiler.as8080.CompileError.infiniteLoopDetected; @@ -21,7 +20,8 @@ * Integrate "include" files and remove PseudoInclude */ public class ExpandIncludesVisitor extends NodeVisitor { - private final Set includedFiles; // TODO: windows platform case-insensitive! + private final Set includedFiles; + private Optional inputFileName = Optional.empty(); public ExpandIncludesVisitor() { this.includedFiles = Collections.emptySet(); @@ -31,6 +31,12 @@ public ExpandIncludesVisitor(Set includedFiles) { this.includedFiles = Objects.requireNonNull(includedFiles); } + @Override + public void visit(Program node) { + this.inputFileName = node.getFileName(); + super.visit(node); + } + @Override public void visit(PseudoInclude node) { if (includedFiles.contains(node.filename)) { @@ -38,13 +44,15 @@ public void visit(PseudoInclude node) { } try { - As8080Lexer lexer = new As8080Lexer(CharStreams.fromFileName(node.filename)); + String absoluteFileName = findAbsoluteFileName(node.filename); + + As8080Lexer lexer = new As8080Lexer(CharStreams.fromFileName(absoluteFileName)); CommonTokenStream stream = new CommonTokenStream(lexer); As8080Parser parser = new As8080Parser(stream); stream.fill(); ParseTree tree = parser.rStart(); Program program = new Program(node.line, node.column, env); - program.setFileName(node.filename); + program.setFileName(absoluteFileName); new CreateProgramVisitor(program).visit(tree); @@ -58,4 +66,20 @@ public void visit(PseudoInclude node) { error(couldNotReadFile(node, node.filename, e)); } } + + private String findAbsoluteFileName(String includeFileName) { + File includeFile = new File(includeFileName); + if (includeFile.isAbsolute()) { + return includeFileName; + } + + return inputFileName + .map(f -> f.replace("\\", File.separator)) + .map(File::new) + .map(File::getParentFile) + .map(File::toPath) + .map(p -> p.resolve(includeFileName)) + .map(Path::toString) + .orElse(includeFileName); + } } diff --git a/plugins/compiler/as-ssem/build.gradle b/plugins/compiler/as-ssem/build.gradle index 7c8f622e2..04b69a5fc 100644 --- a/plugins/compiler/as-ssem/build.gradle +++ b/plugins/compiler/as-ssem/build.gradle @@ -23,6 +23,7 @@ plugins { id 'java' id 'idea' id 'antlr' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/compiler/as-z80/build.gradle b/plugins/compiler/as-z80/build.gradle index b9f72a799..cdcc192a2 100644 --- a/plugins/compiler/as-z80/build.gradle +++ b/plugins/compiler/as-z80/build.gradle @@ -23,6 +23,7 @@ plugins { id 'java' id 'idea' id 'antlr' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java index 35c338e6c..e448faa67 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java @@ -118,6 +118,7 @@ public boolean compile(String inputFileName, String outputFileName) { parser.addErrorListener(new ParserErrorListener()); Program program = new Program(); + program.setFileName(inputFileName); new CreateProgramVisitor(program).visit(parser.rStart()); IntelHEX hex = new IntelHEX(); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java index 216d84faa..e1ae72521 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java @@ -2,6 +2,7 @@ import net.emustudio.plugins.compiler.asZ80.CompileError; +import java.io.File; import java.util.*; public class NameSpace { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java index e65fcbcae..693da2c7b 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java @@ -8,11 +8,10 @@ import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; +import java.io.File; import java.io.IOException; -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; +import java.nio.file.Path; +import java.util.*; import static net.emustudio.plugins.compiler.asZ80.CompileError.couldNotReadFile; import static net.emustudio.plugins.compiler.asZ80.CompileError.infiniteLoopDetected; @@ -21,8 +20,9 @@ * Integrate "include" files and remove PseudoInclude */ public class ExpandIncludesVisitor extends NodeVisitor { - private final Set includedFiles; // TODO: windows platform case-insensitive! - + private final Set includedFiles; + private Optional inputFileName = Optional.empty(); + public ExpandIncludesVisitor() { this.includedFiles = Collections.emptySet(); } @@ -31,6 +31,12 @@ public ExpandIncludesVisitor(Set includedFiles) { this.includedFiles = Objects.requireNonNull(includedFiles); } + @Override + public void visit(Program node) { + this.inputFileName = node.getFileName(); + super.visit(node); + } + @Override public void visit(PseudoInclude node) { if (includedFiles.contains(node.filename)) { @@ -38,13 +44,15 @@ public void visit(PseudoInclude node) { } try { - AsZ80Lexer lexer = new AsZ80Lexer(CharStreams.fromFileName(node.filename)); + String absoluteFileName = findAbsoluteFileName(node.filename); + + AsZ80Lexer lexer = new AsZ80Lexer(CharStreams.fromFileName(absoluteFileName)); CommonTokenStream stream = new CommonTokenStream(lexer); AsZ80Parser parser = new AsZ80Parser(stream); stream.fill(); ParseTree tree = parser.rStart(); Program program = new Program(node.line, node.column, env); - program.setFileName(node.filename); + program.setFileName(absoluteFileName); new CreateProgramVisitor(program).visit(tree); @@ -58,4 +66,20 @@ public void visit(PseudoInclude node) { error(couldNotReadFile(node, node.filename, e)); } } + + private String findAbsoluteFileName(String includeFileName) { + File includeFile = new File(includeFileName); + if (includeFile.isAbsolute()) { + return includeFileName; + } + + return inputFileName + .map(f -> f.replace("\\", File.separator)) + .map(File::new) + .map(File::getParentFile) + .map(File::toPath) + .map(p -> p.resolve(includeFileName)) + .map(Path::toString) + .orElse(includeFileName); + } } diff --git a/plugins/compiler/brainc-brainduck/build.gradle b/plugins/compiler/brainc-brainduck/build.gradle index 2f2296b6e..74c65ace3 100644 --- a/plugins/compiler/brainc-brainduck/build.gradle +++ b/plugins/compiler/brainc-brainduck/build.gradle @@ -23,6 +23,7 @@ plugins { id 'java' id 'org.xbib.gradle.plugin.jflex' version "1.5.0" id "com.github.andrescv.jcup" version "1.0" + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/compiler/ramc-ram/build.gradle b/plugins/compiler/ramc-ram/build.gradle index 87a0ec9ff..a3d3ac02f 100644 --- a/plugins/compiler/ramc-ram/build.gradle +++ b/plugins/compiler/ramc-ram/build.gradle @@ -23,6 +23,7 @@ plugins { id 'java' id 'org.xbib.gradle.plugin.jflex' version "1.5.0" id "com.github.andrescv.jcup" version "1.0" + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/compiler/raspc-rasp/build.gradle b/plugins/compiler/raspc-rasp/build.gradle index 8809ace16..a204aace1 100644 --- a/plugins/compiler/raspc-rasp/build.gradle +++ b/plugins/compiler/raspc-rasp/build.gradle @@ -23,6 +23,7 @@ plugins { id 'java' id 'org.xbib.gradle.plugin.jflex' version "1.5.0" id "com.github.andrescv.jcup" version "1.0" + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/cpu/brainduck-cpu/build.gradle b/plugins/cpu/brainduck-cpu/build.gradle index a56d2ab9c..521f6e8ae 100644 --- a/plugins/cpu/brainduck-cpu/build.gradle +++ b/plugins/cpu/brainduck-cpu/build.gradle @@ -22,6 +22,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' id 'net.emustudio.edigen-plugin' version '1.4.0' + id 'com.adarshr.test-logger' version '3.1.0' } repositories { diff --git a/plugins/cpu/ram-cpu/build.gradle b/plugins/cpu/ram-cpu/build.gradle index bbb9631b1..4369bff65 100644 --- a/plugins/cpu/ram-cpu/build.gradle +++ b/plugins/cpu/ram-cpu/build.gradle @@ -21,11 +21,12 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } repositories { + mavenLocal() mavenCentral() - jcenter() } dependencies { diff --git a/plugins/cpu/rasp-cpu/build.gradle b/plugins/cpu/rasp-cpu/build.gradle index 7c3144749..cd6827a5e 100644 --- a/plugins/cpu/rasp-cpu/build.gradle +++ b/plugins/cpu/rasp-cpu/build.gradle @@ -21,11 +21,12 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } repositories { + mavenLocal() mavenCentral() - jcenter() } dependencies { diff --git a/plugins/cpu/ssem-cpu/build.gradle b/plugins/cpu/ssem-cpu/build.gradle index bda6c24ed..be6d3ac3a 100644 --- a/plugins/cpu/ssem-cpu/build.gradle +++ b/plugins/cpu/ssem-cpu/build.gradle @@ -29,6 +29,7 @@ buildscript { plugins { id 'java' id 'net.emustudio.edigen-plugin' version '1.4.0' + id 'com.adarshr.test-logger' version '3.1.0' } repositories { diff --git a/plugins/device/88-dcdd/build.gradle b/plugins/device/88-dcdd/build.gradle index f7e60c2e4..6c9604c48 100644 --- a/plugins/device/88-dcdd/build.gradle +++ b/plugins/device/88-dcdd/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/device/88-sio/build.gradle b/plugins/device/88-sio/build.gradle index 8447b444b..68c8d5766 100644 --- a/plugins/device/88-sio/build.gradle +++ b/plugins/device/88-sio/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/device/abstract-tape/build.gradle b/plugins/device/abstract-tape/build.gradle index 1ecee54f5..0b8a975ae 100644 --- a/plugins/device/abstract-tape/build.gradle +++ b/plugins/device/abstract-tape/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/device/adm3A-terminal/build.gradle b/plugins/device/adm3A-terminal/build.gradle index 4927ca8da..434a71698 100644 --- a/plugins/device/adm3A-terminal/build.gradle +++ b/plugins/device/adm3A-terminal/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/device/brainduck-terminal/build.gradle b/plugins/device/brainduck-terminal/build.gradle index ca2ec8cee..001685704 100644 --- a/plugins/device/brainduck-terminal/build.gradle +++ b/plugins/device/brainduck-terminal/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/device/simhPseudo-z80/build.gradle b/plugins/device/simhPseudo-z80/build.gradle index 3f6bdf949..8ae21bce6 100644 --- a/plugins/device/simhPseudo-z80/build.gradle +++ b/plugins/device/simhPseudo-z80/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/device/ssem-display/build.gradle b/plugins/device/ssem-display/build.gradle index 31bcd9301..58586f2c0 100644 --- a/plugins/device/ssem-display/build.gradle +++ b/plugins/device/ssem-display/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/memory/brainduck-mem/build.gradle b/plugins/memory/brainduck-mem/build.gradle index 1ecee54f5..0b8a975ae 100644 --- a/plugins/memory/brainduck-mem/build.gradle +++ b/plugins/memory/brainduck-mem/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/memory/byte-mem/build.gradle b/plugins/memory/byte-mem/build.gradle index 1ecee54f5..0b8a975ae 100644 --- a/plugins/memory/byte-mem/build.gradle +++ b/plugins/memory/byte-mem/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/memory/ram-mem/build.gradle b/plugins/memory/ram-mem/build.gradle index 1ecee54f5..0b8a975ae 100644 --- a/plugins/memory/ram-mem/build.gradle +++ b/plugins/memory/ram-mem/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/memory/rasp-mem/build.gradle b/plugins/memory/rasp-mem/build.gradle index 6e73daf6e..c520933d4 100644 --- a/plugins/memory/rasp-mem/build.gradle +++ b/plugins/memory/rasp-mem/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { diff --git a/plugins/memory/ssem-mem/build.gradle b/plugins/memory/ssem-mem/build.gradle index 9449fd043..adf3d05a5 100644 --- a/plugins/memory/ssem-mem/build.gradle +++ b/plugins/memory/ssem-mem/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'com.adarshr.test-logger' version '3.1.0' } dependencies { From 6498ff711affa9c63f38927ac1d14d10855d1d92 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 17 Mar 2022 18:10:17 +0000 Subject: [PATCH 121/314] [#201] z80-cpu: fixes --- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 159 +++++++++++---- .../plugins/cpu/zilogZ80/EmulatorTables.java | 94 --------- .../plugins/cpu/zilogZ80/ArithmeticTest.java | 138 +++++++++---- .../plugins/cpu/zilogZ80/IOTest.java | 4 +- .../plugins/cpu/zilogZ80/LogicTest.java | 53 +++-- .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 182 +++++++++--------- 6 files changed, 343 insertions(+), 287 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index b3e49d8e0..dee8bb13d 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -401,8 +401,15 @@ private void writeWord(int address, int value) { memory.write(address, new Byte[]{(byte) (value & 0xFF), (byte) ((value >>> 8) & 0xFF)}, 2); } - private int flagSZHPC(int a, int b, int sum) { - int carryOut = (a > 0xFF - b) ? FLAG_C : 0; + private int flagSZHPC(int a, int b, int flagC, int sum) { + // source: https://stackoverflow.com/questions/8034566/overflow-and-carry-flags-on-z80 + int carryOut; + if (flagC == FLAG_C) { + carryOut = (a >= 0xFF - b) ? FLAG_C : 0; + } else { + carryOut = (a > 0xFF - b) ? FLAG_C : 0; + } + int carryIns = sum ^ a ^ b; int halfCarryOut = (carryIns >> 4) & 1; int overflowOut = (((carryIns >> 7) ^ carryOut) != 0) ? FLAG_PV : 0; @@ -410,6 +417,17 @@ private int flagSZHPC(int a, int b, int sum) { return carryOut | (halfCarryOut << 4) | (overflowOut) | (sum == 0 ? FLAG_Z : 0) | (sum & 0x80); } + private int flagSZHP(int a, int b, int sum) { + // source: https://stackoverflow.com/questions/8034566/overflow-and-carry-flags-on-z80 + int carryOut = (a > 0xFF - b) ? FLAG_C : 0; + + int carryIns = sum ^ a ^ b; + int halfCarryOut = (carryIns >> 4) & 1; + int overflowOut = (((carryIns >> 7) ^ carryOut) != 0) ? FLAG_PV : 0; + + return (halfCarryOut << 4) | (overflowOut) | (sum == 0 ? FLAG_Z : 0) | (sum & 0x80); + } + private void bigOverflow(int i, int j, int result) { int sign = i & 0x8000; if (sign != (j & 0x8000)) { @@ -551,7 +569,7 @@ int I_LD_R_N() { int I_INC_R() { int reg = (lastOpcode >>> 3) & 0x07; int value = (getreg(reg) + 1) & 0xFF; - flags = EmulatorTables.INC_TABLE[value] | (flags & FLAG_C); + flags = flagSZHP(getreg(reg), 1, value); putreg(reg, value); return (reg == 6) ? 11 : 4; } @@ -559,7 +577,7 @@ int I_INC_R() { int I_DEC_R() { int reg = (lastOpcode >>> 3) & 0x07; int value = (getreg(reg) - 1) & 0xFF; - flags = EmulatorTables.DEC_TABLE[value] | (flags & FLAG_C); + flags = flagSZHP(getreg(reg), ((~1) + 1) & 0xFF, value) | FLAG_N; putreg(reg, value); return (reg == 6) ? 11 : 4; } @@ -585,7 +603,7 @@ int I_ADD_A_R() { int value = getreg(lastOpcode & 0x07); int oldA = regs[REG_A]; regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, regs[REG_A]); + flags = flagSZHPC(oldA, value, 0, regs[REG_A]); return (lastOpcode == 0x86) ? 7 : 4; } @@ -593,7 +611,7 @@ int I_ADC_A_R() { int value = getreg(lastOpcode & 0x07); int oldA = regs[REG_A]; regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, (value + (flags & FLAG_C)) & 0xFF, regs[REG_A]); + flags = flagSZHPC(oldA, value, (flags & FLAG_C), regs[REG_A]); return (lastOpcode == 0x8E) ? 7 : 4; } @@ -601,7 +619,12 @@ int I_SUB_R() { int value = ((~getreg(lastOpcode & 0x07)) + 1) & 0xFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, regs[REG_A]) | FLAG_N; + flags = flagSZHPC(oldA, value, 0, regs[REG_A]) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return (lastOpcode == 0x96) ? 7 : 4; } @@ -609,7 +632,12 @@ int I_SBC_A_R() { int value = ((~getreg(lastOpcode & 0x07)) + 1) & 0xFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value - (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, (value - (flags & FLAG_C)) & 0xFF, regs[REG_A]) | FLAG_N; + flags = flagSZHPC(oldA, value, ((flags & FLAG_C) == FLAG_C) ? 0 : FLAG_C, regs[REG_A]) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return (lastOpcode == 0x9E) ? 7 : 4; } @@ -634,7 +662,12 @@ int I_OR_R() { int I_CP_R() { int value = ((~getreg(lastOpcode & 7)) + 1) & 0xFF; int result = (regs[REG_A] + value) & 0xFF; - flags = flagSZHPC(regs[REG_A], value, result) | FLAG_N; + flags = flagSZHPC(regs[REG_A], value, 0, result) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return (lastOpcode == 0xBE) ? 7 : 4; } @@ -1373,7 +1406,7 @@ int I_ADD_A_N() { PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, regs[REG_A]); + flags = flagSZHPC(oldA, value, 0, regs[REG_A]); return 7; } @@ -1382,7 +1415,7 @@ int I_ADC_A_N() { PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, (value + (flags & FLAG_C)) & 0xFF, regs[REG_A]); + flags = flagSZHPC(oldA, value, flags & FLAG_C, regs[REG_A]); return 7; } @@ -1398,7 +1431,12 @@ int I_SUB_N() { PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, regs[REG_A]) | FLAG_N; + flags = flagSZHPC(oldA, value, 0, regs[REG_A]) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return 7; } @@ -1414,7 +1452,12 @@ int I_SBC_A_N() { PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value - (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, (value - (flags & FLAG_C)) & 0xFF, regs[REG_A]) | FLAG_N; + flags = flagSZHPC(oldA, value, (flags & FLAG_C) == FLAG_C ? 0 : FLAG_C, regs[REG_A]) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return 7; } @@ -1449,7 +1492,12 @@ int I_CP_N() { int value = ((~readByte(PC)) + 1) & 0xFF; PC = (PC + 1) & 0xFFFF; int diff = (regs[REG_A] + value) & 0xFF; - flags = flagSZHPC(regs[REG_A], value, diff) | FLAG_N; + flags = flagSZHPC(regs[REG_A], value, 0, diff) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return 7; } @@ -1836,13 +1884,13 @@ int I_INC_REF_IY_N() { } int I_INC_REF_II_N(int special) { - byte tmp = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = (special + tmp) & 0xFFFF; - int tmp2 = (memory.read(tmp1) + 1) & 0xFF; - - memory.write(tmp1, (byte) tmp2); - flags = EmulatorTables.INC_TABLE[tmp2] | (flags & FLAG_C); + int address = (special + disp) & 0xFFFF; + int value = readByte(address); + int result = (value + 1) & 0xFF; + memory.write(address, (byte) result); + flags = flagSZHP(value, 1, result); return 23; } @@ -1855,12 +1903,13 @@ int I_DEC_REF_IY_N() { } int I_DEC_REF_II_N(int special) { - int tmp = readByte(PC); + int disp = readByte(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = (special + (byte) tmp) & 0xFFFF; - int tmp2 = (memory.read(tmp1) - 1) & 0xFF; - memory.write(tmp1, (byte) tmp2); - flags = EmulatorTables.DEC_TABLE[tmp2] | (flags & FLAG_C); + int address = (special + (byte) disp) & 0xFFFF; + int value = readByte(address); + int result = (value - 1) & 0xFF; + memory.write(address, (byte) result); + flags = flagSZHP(value, ((~1) + 1) & 0xFF, result) | FLAG_N; return 23; } @@ -1926,7 +1975,7 @@ int I_ADD_A_REF_II_N(int special) { int value = readByte((special + offset) & 0xFFFF); int oldA = regs[REG_A]; regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, regs[REG_A]); + flags = flagSZHPC(oldA, value, 0, regs[REG_A]); return 19; } @@ -1944,7 +1993,7 @@ int I_ADC_A_REF_II_N(int special) { int value = readByte((special + offset) & 0xFFFF); int oldA = regs[REG_A]; regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, (value + (flags & FLAG_C)) & 0xFF, regs[REG_A]); + flags = flagSZHPC(oldA, value, flags & FLAG_C, regs[REG_A]); return 19; } @@ -1962,7 +2011,12 @@ int I_SUB_REF_II_N(int special) { int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, regs[REG_A]) | FLAG_N; + flags = flagSZHPC(oldA, value, 0, regs[REG_A]) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return 19; } @@ -1980,7 +2034,12 @@ int I_SBC_A_REF_II_N(int special) { int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + value - (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, (value - (flags & FLAG_C)) & 0xFF, regs[REG_A]) | FLAG_N; + flags = flagSZHPC(oldA, value, ((flags & FLAG_C) == FLAG_C) ? 0 : FLAG_C, regs[REG_A]) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return 19; } @@ -2050,7 +2109,12 @@ int I_CP_REF_II_N(int special) { PC = (PC + 1) & 0xFFFF; int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; int diff = (regs[REG_A] + value) & 0xFF; - flags = flagSZHPC(regs[REG_A], value, diff) | FLAG_N; + flags = flagSZHPC(regs[REG_A], value, 0, diff) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return 19; } @@ -2369,9 +2433,9 @@ int I_INC_IYL() { } int I_INC(int value) { - int valueInc = (value + 1) & 0xFF; - flags = EmulatorTables.INC_TABLE[valueInc] | (flags & FLAG_C); - return valueInc; + int result = (value + 1) & 0xFF; + flags = flagSZHP(value, 1, result); + return result; } int I_DEC_IXH() { @@ -2387,7 +2451,7 @@ int I_DEC_IYH() { int I_DEC_IIH(int special) { int reg = special >>> 8; int value = (reg - 1) & 0xFF; - flags = EmulatorTables.DEC_TABLE[value] | (flags & FLAG_C); + flags = flagSZHP(reg, ((~1) + 1) & 0xFF, value) | FLAG_N; return value; } @@ -2404,7 +2468,7 @@ int I_DEC_IYL() { int I_DEC_IIL(int special) { int reg = special & 0xFF; int value = (reg - 1) & 0xFF; - flags = EmulatorTables.DEC_TABLE[value] | (flags & FLAG_C); + flags = flagSZHP(reg, ((~1) + 1) & 0xFF, value) | FLAG_N; return value; } @@ -2531,7 +2595,7 @@ int I_ADD_A_IYL() { int I_ADD_A(int value) { int oldA = regs[REG_A]; regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, regs[REG_A]); + flags = flagSZHPC(oldA, value, 0, regs[REG_A]); return 8; } @@ -2554,7 +2618,7 @@ int I_ADC_A_IYL() { int I_ADC_A(int value) { int oldA = regs[REG_A]; regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, (value + (flags & FLAG_C)) & 0xFF, regs[REG_A]); + flags = flagSZHPC(oldA, value, flags & FLAG_C, regs[REG_A]); return 8; } @@ -2578,7 +2642,12 @@ int I_SUB(int value) { int valueNeg = ((~value) + 1) & 0xFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + valueNeg) & 0xFF; - flags = flagSZHPC(oldA, valueNeg, regs[REG_A]) | FLAG_N; + flags = flagSZHPC(oldA, valueNeg, 0, regs[REG_A]) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return 8; } @@ -2602,7 +2671,12 @@ int I_SBC_A(int value) { int valueNeg = ((~value) + 1) & 0xFF; int oldA = regs[REG_A]; regs[REG_A] = (oldA + valueNeg - (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, (valueNeg - (flags & FLAG_C)) & 0xFF, regs[REG_A]) | FLAG_N; + flags = flagSZHPC(oldA, valueNeg, ((flags & FLAG_C) == FLAG_C) ? 0 : FLAG_C, regs[REG_A]) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return 8; } @@ -2691,7 +2765,12 @@ int I_CP_IYL() { int I_CP(int value) { int valueNeg = ((~value) + 1) & 0xFF; int result = (regs[REG_A] + valueNeg) & 0xFF; - flags = flagSZHPC(regs[REG_A], valueNeg, result) | FLAG_N; + flags = flagSZHPC(regs[REG_A], valueNeg, 0, result) | FLAG_N; + if ((flags & FLAG_C) == FLAG_C) { + flags &= 0xFE; + } else { + flags |= FLAG_C; + } return 8; } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java index bcf8fac0a..ce9caefd2 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java @@ -19,76 +19,6 @@ package net.emustudio.plugins.cpu.zilogZ80; class EmulatorTables { - private final static int FLAG_S_SHIFT = 7; - private final static int FLAG_Z_SHIFT = 6; - private final static int FLAG_H_SHIFT = 4; - private final static int FLAG_PV_SHIFT = 2; - private final static int FLAG_N_SHIFT = 1; - private final static int FLAG_C_SHIFT = 0; - - // INDEX IS: - // - for ADD: A+B - // - for ADC: A+B+carry - // - for SUB: A+(~B + 1) - // - for SBC: A+(~B + 1)-carry - // - // carryIns = *acc ^ a ^ b; - // carryOut = 1 IFF (a + b > 0xFF) or, - // equivalently, but avoiding overflow in C: (a > 0xFF - b). - // overflowOut = (carryIns >> 7) ^ carryOut; - // halfCarryOut = (carryIns >> 4) & 1; - // zeroOut = sum == 0 - // signOut = sum & 0x80 -// final static byte[] SZHPC_TABLE = new byte[511]; -// -// public static String intToFlags(int flags) { -// String flagsString = ""; -// if ((flags & FLAG_S) == FLAG_S) { -// flagsString += "S"; -// } -// if ((flags & FLAG_Z) == FLAG_Z) { -// flagsString += "Z"; -// } -// if ((flags & FLAG_H) == FLAG_H) { -// flagsString += "H"; -// } -// if ((flags & FLAG_PV) == FLAG_PV) { -// flagsString += "P"; -// } -// if ((flags & FLAG_N) == FLAG_N) { -// flagsString += "N"; -// } -// if ((flags & FLAG_C) == FLAG_C) { -// flagsString += "C"; -// } -// return flagsString; -// } -// -// static { -// for (int a = 0; a < 256; a++) { -// for (int b = 0; b < 256; b++) { -// int sum = (a + b) & 0xFF; // index to the array -// -// int carryOut = (a > 0xFF - b) ? FLAG_C : 0; -// int carryIns = sum ^ a ^ b; -// int halfCarryOut = (carryIns >> 4) & 1; -// int overflowOut = (((carryIns >> 7) ^ carryOut) != 0) ? FLAG_PV : 0; -// -// int result = carryOut | (halfCarryOut << FLAG_H_SHIFT) | (overflowOut) | (sum == 0 ? FLAG_Z : 0) | (sum & 0x80); -// -// if (a == 0x65 && b == 0x1C) { -// System.out.println("TABLE = " + intToFlags(result)); -// } -// if (sum == (0x65 + 0x1C)) { -// System.out.println("TABLE(SUM) = " + intToFlags(result)); -// System.out.println(" a = " + Integer.toHexString(a)); -// System.out.println(" b = " + Integer.toHexString(b)); -// } -// -// SZHPC_TABLE[(a + b) & 0x1FF] = (byte)result; -// } -// } -// } final static short[] SIGN_ZERO_TABLE = new short[]{ 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -110,30 +40,6 @@ class EmulatorTables { 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4 }; - final static short[] INC_TABLE = new short[]{ - 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 148, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 144, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 144, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 144, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 144, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 144, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 144, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 144, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 - }; - - final static short[] DEC_TABLE = new short[]{ - 82, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 6, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 130, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 130, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 130, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 130, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 130, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 130, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 130, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 130 - }; - final static int[] DAA_NOT_C_NOT_H_TABLE = new int[]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java index a1498edb6..6a95e4adb 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java @@ -126,7 +126,7 @@ public void testSBC_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> ((context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrowWithCarry().overflow().subtractionIsSet()) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrow().overflowSub().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( @@ -148,7 +148,7 @@ public void testSBC_A_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrowWithCarry().overflow().subtractionIsSet()); + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrow().overflowSub().subtractionIsSet()); Generator.forSome8bitBinary( test.runWithSecondOperand(0xDE) @@ -178,7 +178,9 @@ public void testINC_R() { @Test public void testDEC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyFlags(new FlagsCheckImpl().sign().zero().overflow().halfCarry().subtractionIsSet(), + .verifyFlags(new FlagsCheckImpl() + .setSecond(c -> 1) + .sign().zero().overflowSub().halfBorrow().subtractionIsSet(), context -> context.first - 1) .keepCurrentInjectorsAfterRun() .clearOtherVerifiersAfterRun(); @@ -283,7 +285,7 @@ public void testSUB_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflow().subtractionIsSet()) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -298,7 +300,7 @@ public void testSBC_A_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrowWithCarry().overflow().subtractionIsSet()) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -335,7 +337,9 @@ public void testINC_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .verifyByte(context -> get8MSBplus8LSB(context.first), context -> (context.second + 1)) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().sign().zero().halfCarry().overflow().subtractionIsReset() + .switchFirstAndSecond() + .setSecond(c -> 1) + .sign().zero().halfCarry().overflow().subtractionIsReset() ) .keepCurrentInjectorsAfterRun(); @@ -351,7 +355,9 @@ public void testDEC_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .verifyByte(context -> get8MSBplus8LSB(context.first), context -> (context.second - 1)) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().sign().zero().halfCarry().overflow().subtractionIsSet() + .switchFirstAndSecond() + .setSecond(c -> 1) + .sign().zero().halfBorrow().overflowSub().subtractionIsSet() ) .keepCurrentInjectorsAfterRun(); @@ -448,7 +454,9 @@ public void testSBC_HL_RP() { public void testINC_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8MSB().halfCarryOfFirst8MSB().subtractionIsReset(), + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8MSB() + .overflow().halfCarry().subtractionIsReset(), context -> ((context.first >>> 8) + 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); @@ -461,7 +469,9 @@ public void testINC_IXH() { public void testINC_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIY() - .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8MSB().halfCarryOfFirst8MSB().subtractionIsReset(), + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8MSB() + .overflow().halfCarry().subtractionIsReset(), context -> ((context.first >>> 8) + 1) & 0xFF) .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); @@ -474,7 +484,10 @@ public void testINC_IYH() { public void testDEC_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8MSB().halfCarryOfFirst8MSB().subtractionIsSet(), + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8MSB() + .setSecond(c -> -1) + .overflow().halfCarry().subtractionIsSet(), context -> ((context.first >>> 8) - 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); @@ -487,7 +500,11 @@ public void testDEC_IXH() { public void testDEC_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIY() - .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8MSB().halfCarryOfFirst8MSB().subtractionIsSet(), + .verifyFlags(new FlagsCheckImpl() + .setFirst8MSB() + .sign().zero() + .setSecond(c -> 1) + .overflow().halfBorrow().subtractionIsSet(), context -> ((context.first >>> 8) - 1) & 0xFF) .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); @@ -500,7 +517,10 @@ public void testDEC_IYH() { public void testINC_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8LSB().halfCarryOfFirst8LSB().subtractionIsReset(), + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8LSB() + .setSecond(c -> 1) + .overflow().halfCarry().subtractionIsReset(), context -> ((context.first & 0xFF) + 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) + 1) & 0xFF)); @@ -513,7 +533,10 @@ public void testINC_IXL() { public void testINC_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIY() - .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8LSB().halfCarryOfFirst8LSB().subtractionIsReset(), + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8LSB() + .setSecond(c -> 1) + .overflow().halfCarry().subtractionIsReset(), context -> ((context.first & 0xFF) + 1) & 0xFF) .verifyIY(context -> (context.first & 0xFF00) | (((context.first & 0xFF) + 1) & 0xFF)); @@ -526,7 +549,10 @@ public void testINC_IYL() { public void testDEC_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8LSB().halfCarryOfFirst8LSB().subtractionIsSet(), + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8LSB() + .setSecond(c -> -1) + .overflow().halfCarry().subtractionIsSet(), context -> ((context.first & 0xFF) - 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); @@ -539,7 +565,11 @@ public void testDEC_IXL() { public void testDEC_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIY() - .verifyFlags(new FlagsCheckImpl().sign().zero().overflowOfFirst8LSB().halfCarryOfFirst8LSB().subtractionIsSet(), + .verifyFlags(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond(c -> 1) + .sign().zero() + .overflowSub().halfBorrow().subtractionIsSet(), context -> ((context.first & 0xFF) - 1) & 0xFF) .verifyIY(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); @@ -554,7 +584,10 @@ public void testADD_A_IXH() { .first8LSBisRegister(REG_A) .secondIsIX() .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond8MSB() + .sign().zero().carry().halfCarry().overflow().subtractionIsReset()); Generator.forSome16bitBinary( test.run(0xDD, 0x84) @@ -567,7 +600,10 @@ public void testADD_A_IYH() { .first8LSBisRegister(REG_A) .secondIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond8MSB() + .sign().zero().carry().halfCarry().overflow().subtractionIsReset()); Generator.forSome16bitBinary( test.run(0xFD, 0x84) @@ -606,7 +642,11 @@ public void testADC_A_IXH() { .first8LSBisRegister(REG_A) .secondIsIX() .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() + .setFirst8LSB() + .setSecond8MSB() + .halfCarry() + .overflow().subtractionIsReset()); Generator.forSome16bitBinary( test.run(0xDD, 0x8C) @@ -619,7 +659,11 @@ public void testADC_A_IYH() { .first8LSBisRegister(REG_A) .secondIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() + .setFirst8LSB() + .setSecond8MSB() + .halfCarry() + .overflow().subtractionIsReset()); Generator.forSome16bitBinary( test.run(0xFD, 0x8C) @@ -632,7 +676,11 @@ public void testADC_A_IXL() { .first8LSBisRegister(REG_A) .secondIsIX() .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() + .setFirst8LSB() + .setSecond8LSB() + .halfCarry() + .overflow().subtractionIsReset()); Generator.forSome16bitBinary( test.run(0xDD, 0x8D) @@ -645,7 +693,11 @@ public void testADC_A_IYL() { .first8LSBisRegister(REG_A) .secondIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() + .setFirst8LSB() + .setSecond8LSB() + .halfCarry() + .overflow().subtractionIsReset()); Generator.forSome16bitBinary( test.run(0xFD, 0x8D) @@ -660,9 +712,10 @@ public void testSUB_IXH() { .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)) .verifyFlagsOfLastOp(new FlagsCheckImpl() .sign().zero() - .borrow(context -> context.second >>> 8) - .halfBorrow(context -> context.second >>> 8) - .overflow().subtractionIsSet()); + .setSecond8MSB() + .borrow() + .halfBorrow() + .overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xDD, 0x94) @@ -677,9 +730,10 @@ public void testSUB_IYH() { .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)) .verifyFlagsOfLastOp(new FlagsCheckImpl() .sign().zero() - .borrow(context -> context.second >>> 8) - .halfBorrow(context -> context.second >>> 8) - .overflow().subtractionIsSet()); + .setSecond8MSB() + .borrow() + .halfBorrow() + .overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xFD, 0x94) @@ -696,7 +750,7 @@ public void testSUB_IXL() { .sign().zero() .borrow() .halfBorrow() - .overflow().subtractionIsSet()); + .overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xDD, 0x95) @@ -713,7 +767,7 @@ public void testSUB_IYL() { .sign().zero() .borrow() .halfBorrow() - .overflow().subtractionIsSet()); + .overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xFD, 0x95) @@ -727,10 +781,12 @@ public void testSBC_A_IXH() { .secondIsIX() .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)) .verifyFlagsOfLastOp(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond8MSB() .sign().zero() - .borrowWithCarry(context -> context.second >>> 8) - .halfBorrowWithCarry(context -> context.second >>> 8) - .overflow().subtractionIsSet()); + .borrowWithCarry() + .halfBorrow() + .overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xDD, 0x9C) @@ -744,10 +800,11 @@ public void testSBC_A_IYH() { .secondIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)) .verifyFlagsOfLastOp(new FlagsCheckImpl() + .setSecond8MSB() .sign().zero() - .borrowWithCarry(context -> context.second >>> 8) - .halfBorrowWithCarry(context -> context.second >>> 8) - .overflow().subtractionIsSet()); + .borrowWithCarry() + .halfBorrow() + .overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xFD, 0x9C) @@ -760,7 +817,10 @@ public void testSBC_A_IXL() { .first8LSBisRegister(REG_A) .secondIsIX() .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrowWithCarry().overflow().subtractionIsSet()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond8LSB() + .sign().zero().borrowWithCarry().halfBorrow().overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xDD, 0x9D) @@ -773,7 +833,7 @@ public void testSBC_A_IYL() { .first8LSBisRegister(REG_A) .secondIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrowWithCarry().overflow().subtractionIsSet()); + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrow().overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xFD, 0x9D) @@ -793,7 +853,9 @@ private ByteTestBuilder subtractionTestBuilder() { return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflow().subtractionIsSet()) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().borrow().halfBorrow() + .overflowSub().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java index 54792fc87..8aef227c0 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java @@ -273,7 +273,7 @@ public void testOTIR() { ); } - @Test // TODO + @Test public void testOUTD() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsAddressAndSecondIsMemoryByte() @@ -284,7 +284,7 @@ public void testOUTD() { .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .subtractionIsSet() .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) ); diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java index f971beecc..bd345ea66 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java @@ -122,7 +122,7 @@ public void testCP_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflow().subtractionIsSet(), + .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet(), context -> (context.first & 0xFF) + (((~context.second) + 1) & 0xFF)) .keepCurrentInjectorsAfterRun(); @@ -145,8 +145,8 @@ public void testCP_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflow().subtractionIsSet(), - context -> (context.first & 0xFF) - (byte)(context.second & 0xFF)); + .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet(), + context -> (context.first & 0xFF) - (byte) (context.second & 0xFF)); Generator.forSome8bitBinary( test.runWithSecondOperand(0xFE) @@ -365,7 +365,7 @@ public void testCP_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflow().subtractionIsSet(), + .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet(), context -> (context.first & 0xFF) - (context.second & 0xFF) ) .keepCurrentInjectorsAfterRun(); @@ -382,9 +382,11 @@ public void testNEG() { .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (-context.first) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().sign().zero().halfCarry().subtractionIsSet() - .expectFlagOnlyWhen(FLAG_C, (context, result) -> context.second != 0) - // .expectFlagOnlyWhen(FLAG_PV, (context, result) -> (context.second & 0xFF) == 0x80) + .switchFirstAndSecond().sign().zero() + .borrow() + .halfBorrow() + .overflowSub() + .subtractionIsSet() ) .keepCurrentInjectorsAfterRun(); @@ -897,10 +899,13 @@ public void testCP_IXH() { .first8LSBisRegister(REG_A) .firstIsIX() .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero() - .borrow(context -> context.first >>> 8) - .halfBorrow(context -> context.first >>> 8) - .overflow() + .verifyFlags(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond(c -> c.first >>> 8) + .sign().zero() + .borrow() + .halfBorrow() + .overflowSub() .subtractionIsSet(), context -> (context.first & 0xFF) + (((~(context.first >>> 8)) + 1) & 0xFF)); @@ -915,10 +920,13 @@ public void testCP_IYH() { .first8LSBisRegister(REG_A) .firstIsIY() .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero() - .borrow(context -> context.first >>> 8) - .halfBorrow(context -> context.first >>> 8) - .overflow() + .verifyFlags(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond(c -> c.first >>> 8) + .sign().zero() + .borrow() + .halfBorrow() + .overflowSub() .subtractionIsSet(), context -> (context.first & 0xFF) + (((~(context.first >>> 8)) + 1) & 0xFF)); @@ -933,10 +941,11 @@ public void testCP_IXL() { .first8LSBisRegister(REG_A) .secondIsIX() .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero() + .verifyFlags(new FlagsCheckImpl() + .sign().zero() .borrow() .halfBorrow() - .overflow() + .overflowSub() .subtractionIsSet(), context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); @@ -951,10 +960,14 @@ public void testCP_IYL() { .first8LSBisRegister(REG_A) .secondIsIY() .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero() + .verifyFlags(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond8LSB() + .sign() + .zero() .borrow() .halfBorrow() - .overflow() + .overflowSub() .subtractionIsSet(), context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); @@ -984,7 +997,7 @@ private IntegerTestBuilder prepareCPxTest(Function, Integ ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) ) .verifyFlags(new FlagsCheckImpl() - .sign().zero().subtractionIsSet().halfCarry() + .sign().zero().subtractionIsSet().halfBorrow() .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) != 0 ), context -> context.registers.get(REG_A) - (context.second & 0xFF)); diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java index fb6ce208f..a442511b2 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java @@ -21,11 +21,44 @@ import net.emustudio.cpu.testsuite.FlagsCheck; import net.emustudio.cpu.testsuite.RunnerContext; +import java.util.Objects; import java.util.function.Function; import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.*; public class FlagsCheckImpl extends FlagsCheck> { + private Function, Integer> first = context -> context.first.intValue(); + private Function, Integer> second = context -> context.second.intValue(); + + public FlagsCheckImpl setFirst(Function, Integer> first) { + this.first = Objects.requireNonNull(first); + return this; + } + + public FlagsCheckImpl setSecond(Function, Integer> second) { + this.second = Objects.requireNonNull(second); + return this; + } + + public FlagsCheckImpl setFirst8MSB() { + this.first = context -> context.first.intValue() >>> 8; + return this; + } + + public FlagsCheckImpl setFirst8LSB() { + this.first = context -> context.first.intValue() & 0xFF; + return this; + } + + public FlagsCheckImpl setSecond8MSB() { + this.second = context -> context.second.intValue() >>> 8; + return this; + } + + public FlagsCheckImpl setSecond8LSB() { + this.second = context -> context.second.intValue() & 0xFF; + return this; + } public FlagsCheckImpl sign() { evaluators.add((context, result) -> { @@ -82,27 +115,38 @@ public FlagsCheckImpl subtractionIsSet() { } public FlagsCheckImpl overflow() { - return overflow(context -> context.first.intValue()); - } - - public FlagsCheckImpl overflowOfFirst8MSB() { - return overflow(context -> context.first.intValue() >>> 8); - } + evaluators.add((context, result) -> { + int firstInt = first.apply(context) & 0xFF; + int secondInt = second.apply(context) & 0xFF; - public FlagsCheckImpl overflowOfFirst8LSB() { - return overflow(context -> context.first.intValue() & 0xFF); + int carryIns = ((firstInt ^ secondInt) ^ 0x80) & 0x80; + if (carryIns != 0) { // if addend signs are the same + // overflow if the sum sign differs from the sign of either of addends + carryIns = ((result ^ firstInt) & 0x80); + } + if (carryIns != 0) { + expectedFlags |= FLAG_PV; + } else { + expectedNotFlags |= FLAG_PV; + } + }); + return this; } - public FlagsCheckImpl overflow(Function, Integer> first) { + public FlagsCheckImpl overflowSub() { evaluators.add((context, result) -> { - int firstInt = first.apply(context); - int sign = firstInt & 0x80; - int trueSecond = result - firstInt; + int firstInt = first.apply(context) & 0xFF; + int secondInt = ((~(second.apply(context) & 0xFF)) + 1) & 0xFF; - if (sign != (trueSecond & 0x80)) { - expectedNotFlags |= FLAG_PV; - } else if ((result & 0x80) != sign) { + int carryIns = ((firstInt ^ secondInt) ^ 0x80) & 0x80; + if (carryIns != 0) { // if addend signs are the same + // overflow if the sum sign differs from the sign of either of addends + carryIns = ((result ^ firstInt) & 0x80); + } + if (carryIns != 0) { expectedFlags |= FLAG_PV; + } else { + expectedNotFlags |= FLAG_PV; } }); return this; @@ -122,18 +166,6 @@ public FlagsCheckImpl overflow16bit() { return this; } - public static boolean isParity(int value) { - int numberOfOnes = 0; - - for (int i = 0; i < 8; i++) { - if ((value & 1) == 1) { - numberOfOnes++; - } - value = value >>> 1; - } - return numberOfOnes % 2 == 0; - } - public FlagsCheckImpl parity() { evaluators.add((context, result) -> { if (isParity(result & 0xFF)) { @@ -168,31 +200,28 @@ public FlagsCheckImpl carry() { } public FlagsCheckImpl borrow() { - return borrow(context -> context.second.intValue()); - } - - public FlagsCheckImpl borrow(Function, Integer> second) { - // doesn't work if sub is using carry=1 (SBC) evaluators.add((context, result) -> { - if ((context.first.intValue() & 0xFF) > (0xFF - (((~second.apply(context)) + 1) & 0xFF))) { - expectedFlags |= FLAG_C; + int inversedSecond = ((~second.apply(context)) + 1) & 0xFF; + int sum = (context.first.intValue() & 0xFF) + inversedSecond; + + if ((sum & 0x100) == 0x100) { + expectedNotFlags |= FLAG_C; // reversed flag C expectations on substraction } else { - expectedNotFlags |= FLAG_C; + expectedFlags |= FLAG_C; } }); return this; } public FlagsCheckImpl borrowWithCarry() { - return borrowWithCarry(context -> context.second.intValue()); - } - - public FlagsCheckImpl borrowWithCarry(Function, Integer> second) { evaluators.add((context, result) -> { - if ((context.first.intValue() & 0xFF) > (0xFF - (((~second.apply(context)) + 1 - (context.flags & FLAG_C)) & 0xFF))) { - expectedFlags |= FLAG_C; - } else { + int inversedCarry = (context.flags & FLAG_C) == FLAG_C ? 0 : FLAG_C; + int inversedSecond = ((~second.apply(context)) + 1) & 0xFF; + int sum = (context.first.intValue() & 0xFF) + inversedSecond + inversedCarry; + if ((sum & 0x100) == 0x100) { expectedNotFlags |= FLAG_C; + } else { + expectedFlags |= FLAG_C; } }); return this; @@ -225,51 +254,9 @@ public FlagsCheckImpl carryIsReset() { return this; } - public static boolean isAuxCarry(int first, int sumWith) { - int mask = sumWith & first; - int xormask = sumWith ^ first; - - int C0 = mask & 1; - int C1 = ((mask >>> 1) ^ (C0 & (xormask >>> 1))) & 1; - int C2 = ((mask >>> 2) ^ (C1 & (xormask >>> 2))) & 1; - int C3 = ((mask >>> 3) ^ (C2 & (xormask >>> 3))) & 1; - - return (C3 != 0); - } - - public FlagsCheckImpl halfCarryOfFirst8MSB() { - return halfCarry(context -> context.first.intValue() >>> 8); - } - - public FlagsCheckImpl halfCarryOfFirst8LSB() { - return halfCarry(context -> context.first.intValue() & 0xFF); - } - public FlagsCheckImpl halfCarry() { - return halfCarry(context -> context.first.intValue()); - } - - public FlagsCheckImpl halfCarry(Function, Integer> first) { - evaluators.add((context, result) -> { - int firstInt = first.apply(context); - byte diff = (byte) ((result - firstInt) & 0xFF); - - if (isAuxCarry(firstInt & 0xFF, diff)) { - expectedFlags |= FLAG_H; - } else { - expectedNotFlags |= FLAG_H; - } - }); - return this; - } - - public FlagsCheckImpl halfBorrow() { - return halfBorrow(context -> context.second.intValue()); - } - - public FlagsCheckImpl halfBorrow(Function, Integer> second) { evaluators.add((context, result) -> { - int carryIns = result ^ (context.first.intValue() & 0xFF) ^ (((~second.apply(context)) + 1) & 0xFF); + int carryIns = result ^ (first.apply(context) & 0xFF) ^ (second.apply(context) & 0xFF); int halfCarryOut = (carryIns >> 4) & 1; if (halfCarryOut == 1) { @@ -281,15 +268,12 @@ public FlagsCheckImpl halfBorrow(Function, Integer> second) return this; } - public FlagsCheckImpl halfBorrowWithCarry() { - return halfBorrowWithCarry(context -> context.second.intValue()); - } - - public FlagsCheckImpl halfBorrowWithCarry(Function, Integer> second) { + public FlagsCheckImpl halfBorrow() { evaluators.add((context, result) -> { - int b = (((~second.apply(context)) + 1 - (context.flags & FLAG_C)) & 0xFF); - int carryIns = result ^ (context.first.intValue() & 0xFF) ^ b; - int halfCarryOut = (carryIns >> 4) & 1; + int inversedSecond = ((~second.apply(context)) + 1) & 0xFF; + + int carryIns = result ^ (first.apply(context) & 0xFF) ^ inversedSecond; + int halfCarryOut = (carryIns >>> 4) & 1; if (halfCarryOut == 1) { expectedFlags |= FLAG_H; @@ -343,4 +327,16 @@ public FlagsCheckImpl zeroIsSet() { evaluators.add((context, result) -> expectedFlags |= FLAG_Z); return this; } + + public static boolean isParity(int value) { + int numberOfOnes = 0; + + for (int i = 0; i < 8; i++) { + if ((value & 1) == 1) { + numberOfOnes++; + } + value = value >>> 1; + } + return numberOfOnes % 2 == 0; + } } From 71e00c9aefc7350a79c8da31e3e87076d33bc5bb Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 17 Mar 2022 18:17:17 +0000 Subject: [PATCH 122/314] [#201] as-z80, as-8080: fix includes --- .../as8080/visitors/ExpandIncludesVisitor.java | 5 +++-- .../compiler/asZ80/visitors/ExpandIncludesVisitor.java | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java index b1ba67ed0..e36aa5ed8 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java @@ -73,13 +73,14 @@ private String findAbsoluteFileName(String includeFileName) { return includeFileName; } + String includeFileNameNormalized = includeFileName.replace("\\", File.separator); return inputFileName .map(f -> f.replace("\\", File.separator)) .map(File::new) .map(File::getParentFile) .map(File::toPath) - .map(p -> p.resolve(includeFileName)) + .map(p -> p.resolve(includeFileNameNormalized)) .map(Path::toString) - .orElse(includeFileName); + .orElse(includeFileNameNormalized); } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java index 693da2c7b..55993f0a5 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java @@ -43,9 +43,8 @@ public void visit(PseudoInclude node) { fatalError(infiniteLoopDetected(node, "include")); } + String absoluteFileName = findAbsoluteFileName(node.filename); try { - String absoluteFileName = findAbsoluteFileName(node.filename); - AsZ80Lexer lexer = new AsZ80Lexer(CharStreams.fromFileName(absoluteFileName)); CommonTokenStream stream = new CommonTokenStream(lexer); AsZ80Parser parser = new AsZ80Parser(stream); @@ -63,7 +62,7 @@ public void visit(PseudoInclude node) { node.addChildren(program.getChildren()); node.exclude(); } catch (IOException e) { - error(couldNotReadFile(node, node.filename, e)); + error(couldNotReadFile(node, absoluteFileName, e)); } } @@ -73,13 +72,14 @@ private String findAbsoluteFileName(String includeFileName) { return includeFileName; } + String includeFileNameNormalized = includeFileName.replace("\\", File.separator); return inputFileName .map(f -> f.replace("\\", File.separator)) .map(File::new) .map(File::getParentFile) .map(File::toPath) - .map(p -> p.resolve(includeFileName)) + .map(p -> p.resolve(includeFileNameNormalized)) .map(Path::toString) - .orElse(includeFileName); + .orElse(includeFileNameNormalized); } } From 82014cab75536d40c51ce13f25017bffbfe7964c Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 21 Mar 2022 11:17:24 +0000 Subject: [PATCH 123/314] [#201] Add z80-cpu disassembler test + fix memories --- plugins/cpu/z80-cpu/build.gradle | 3 +- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 75 +- .../cpu/zilogZ80/DisassemblerTest.java | 817 ++++++++++++++++++ .../memory/brainduck/MemoryContextImpl.java | 3 +- .../memory/bytemem/MemoryContextImpl.java | 4 +- .../memory/ssem/MemoryContextImpl.java | 3 +- settings.gradle | 7 + 7 files changed, 882 insertions(+), 30 deletions(-) create mode 100644 plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java diff --git a/plugins/cpu/z80-cpu/build.gradle b/plugins/cpu/z80-cpu/build.gradle index a6ebd0cd9..a8e613939 100644 --- a/plugins/cpu/z80-cpu/build.gradle +++ b/plugins/cpu/z80-cpu/build.gradle @@ -21,7 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.4.0' + id 'net.emustudio.edigen-plugin' version '1.4.1' id 'com.adarshr.test-logger' version '3.1.0' } @@ -53,6 +53,7 @@ jar { edigen { decoderName = 'net.emustudio.plugins.cpu.zilogZ80.gui.DecoderImpl' disassemblerName = 'net.emustudio.plugins.cpu.zilogZ80.gui.DisassemblerImpl' + //debug = true } processResources { diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index 0318bb5c7..6d80f9887 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -122,7 +122,7 @@ instruction = ddInstruction = "ld ix, %X": 00 100 001 imm16 | # x=0, p=2, q=0, z=1 - "add ix, %s": 00 101 001 | # x=0, p=2, q=1, z=1 + "add ix, %s": 00 rp_ix(2) 1 001 | # x=0, p=rp_ix, q=1, z=1 "ld (%X), ix": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 "ld ix, (%X)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 "inc ix": 00 100 011 | # x=0, p=2, q=0, z=3 @@ -133,11 +133,14 @@ ddInstruction = "dec (ix+%X)": 00 110 101 disp | # x=0, y=6, z=5 "ld %s, %X": 00 10 r_ixhl(1) 110 imm8 | # x=0, y=r_ixhl, z=6 "ld (ix+%X), %X": 00 110 110 disp(8) imm8 | # x=0, y=6, z=6 - "ld %s, %s": 01 10 r_ixhl(1) 10 r_ixhl2(1) | # x=0, y=r_ixhl, z=r_ixhl2 - "ld (ix+%X), %s": 01 110 r_no_hl(3) disp | # x=0, y=6, z=r_no_hl - "ld %s, (ix+%X)": 01 0 r_bcde(2) 110 disp | # x=0, y=0 r_bcde, z=6 - "ld %s, (ix+%X)": 01 10 r_h_l(1) 110 disp | # x=0, y=10 r_h_l, z=6 - "ld a, (ix+%X)": 01 111 110 disp | # x=0, y=7, z=6 + "ld %s, %s": 01 10 r_ixhl(1) 0 r_bcde(2) | # x=1, y=r_ixhl, z=r_bcde + "ld %s, %s": 01 10 r_ixhl(1) 10 r_ixhl2(1) | # x=1, y=r_ixhl, z=r_ixhl2 + "ld %s, a": 01 10 r_ixhl(1) 111 | # x=1, y=r_ixhl, z=a + "ld a, %s": 01 111 10 r_ixhl(1) | # x=1, y=7, z=r_ixhl + "ld (ix+%X), %s": 01 110 r_no_hl(3) disp | # x=1, y=6, z=r_no_hl + "ld %s, (ix+%X)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 + "ld %s, (ix+%X)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l, z=6 + "ld a, (ix+%X)": 01 111 110 disp | # x=1, y=7, z=6 "%s %s": 10 alu(3) 10 r_ixhl(1) | # x=2, y=alu, z=r_ixhl "%s (ix+%X)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 "pop ix": 11 100 001 | # x=3, p=2, q=0, z=1 @@ -151,7 +154,7 @@ ddInstruction = fdInstruction = "ld iy, %X": 00 100 001 imm16 | # x=0, p=2, q=0, z=1 - "add iy, %s": 00 101 001 | # x=0, p=2, q=1, z=1 + "add iy, %s": 00 rp_iy(2) 1 001 | # x=0, p=rp_iy, q=1, z=1 "ld (%X), iy": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 "ld iy, (%X)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 "inc iy": 00 100 011 | # x=0, p=2, q=0, z=3 @@ -162,11 +165,14 @@ fdInstruction = "dec (iy+%X)": 00 110 101 disp | # x=0, y=6, z=5 "ld %s, %X": 00 10 r_iyhl(1) 110 imm8 | # x=0, y=r_iyhl, z=6 "ld (iy+%X), %X": 00 110 110 disp(8) imm8 | # x=0, y=6, z=6 - "ld %s, %s": 01 10 r_iyhl(1) 10 r_iyhl2(1) | # x=0, y=r_iyhl, z=r_iyhl2 - "ld (iy+%X), %s": 01 110 r_no_hl(3) disp | # x=0, y=6, z=r_no_hl - "ld %s, (iy+%X)": 01 0 r_bcde(2) 110 disp | # x=0, y=0 r_bcde, z=6 - "ld %s, (iy+%X)": 01 10 r_h_l(1) 110 disp | # x=0, y=10 r_h_l, z=6 - "ld a, (iy+%X)": 01 111 110 disp | # x=0, y=7, z=6 + "ld %s, %s": 01 10 r_iyhl(1) 0 r_bcde(2) | # x=1, y=r_iyhl, z=r_bcde + "ld %s, %s": 01 10 r_iyhl(1) 10 r_iyhl2(1) | # x=1, y=r_iyhl, z=r_iyhl2 + "ld %s, a": 01 10 r_iyhl(1) 111 | # x=1, y=r_iyhl, z=7 + "ld a, %s": 01 111 10 r_iyhl(1) | # x=1, y=7, z=r_iyhl + "ld (iy+%X), %s": 01 110 r_no_hl(3) disp | # x=1, y=6, z=r_no_hl + "ld %s, (iy+%X)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 + "ld %s, (iy+%X)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l, z=6 + "ld a, (iy+%X)": 01 111 110 disp | # x=1, y=7, z=6 "%s %s": 10 alu(3) 10 r_iyhl(1) | # x=2, y=alu, z=r_iyhl "%s (iy+%X)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 "pop iy": 11 100 001 | # x=3, p=2, q=0, z=1 @@ -237,6 +243,18 @@ rp2 = "hl": 10 | "af": 11 ; +rp_ix = + "bc": 00 | + "de": 01 | + "ix": 10 | + "sp": 11 ; + +rp_iy = + "bc": 00 | + "de": 01 | + "iy": 10 | + "sp": 11 ; + r = "b": 000 | "c": 001 | @@ -323,38 +341,42 @@ any2 = 00 | 01 | 10 | 11; "%s" = fdcbInstruction bit disp r_h_l; "%s" = fdcbInstruction bit disp; -"%s" = ddInstruction imm16; -"%s" = ddInstruction ref16; +"%s" = ddInstruction imm16(reverse_bytes); +"%s" = ddInstruction ref16(reverse_bytes); "%s" = ddInstruction r_ixhl; "%s" = ddInstruction disp; "%s" = ddInstruction r_ixhl imm8; "%s" = ddInstruction disp imm8; +"%s" = ddInstruction r_ixhl r_bcde; "%s" = ddInstruction r_ixhl r_ixhl2; "%s" = ddInstruction r_bcde disp; "%s" = ddInstruction r_h_l disp; "%s" = ddInstruction disp r_no_hl; "%s" = ddInstruction alu r_ixhl; "%s" = ddInstruction alu disp; +"%s" = ddInstruction rp_ix; "%s" = ddInstruction; -"%s" = fdInstruction imm16; -"%s" = fdInstruction ref16; -"%s" = fdInstruction r_ixhl; +"%s" = fdInstruction imm16(reverse_bytes); +"%s" = fdInstruction ref16(reverse_bytes); +"%s" = fdInstruction r_iyhl; "%s" = fdInstruction disp; -"%s" = fdInstruction r_ixhl imm8; +"%s" = fdInstruction r_iyhl imm8; "%s" = fdInstruction disp imm8; -"%s" = fdInstruction r_ixhl r_ixhl2; +"%s" = fdInstruction r_iyhl r_bcde; +"%s" = fdInstruction r_iyhl r_iyhl2; "%s" = fdInstruction disp r_no_hl; "%s" = fdInstruction r_bcde disp; "%s" = fdInstruction r_h_l disp; -"%s" = fdInstruction alu r_ixhl; +"%s" = fdInstruction alu r_iyhl; "%s" = fdInstruction alu disp; +"%s" = fdInstruction rp_iy; "%s" = fdInstruction; -"%s" = instruction rp imm16; -"%s" = instruction rp ref16; -"%s" = instruction ref16_2 rp; -"%s" = instruction cc imm16; +"%s" = instruction rp imm16(reverse_bytes); +"%s" = instruction rp ref16(reverse_bytes); +"%s" = instruction ref16_2(reverse_bytes) rp; +"%s" = instruction cc imm16(reverse_bytes); "%s" = instruction cc_jr imm8; "%s" = instruction r_bcde r; "%s" = instruction r_h_l r; @@ -367,8 +389,8 @@ any2 = 00 | 01 | 10 | 11; "%s" = instruction r_h_l; "%s" = instruction imm8; "%s" = instruction ref8; -"%s" = instruction imm16; -"%s" = instruction ref16; +"%s" = instruction imm16(reverse_bytes); +"%s" = instruction ref16(reverse_bytes); "%s" = instruction rp; "%s" = instruction rp2; "%s" = instruction r; @@ -376,4 +398,5 @@ any2 = 00 | 01 | 10 | 11; "%s" = instruction cc; "%s" = instruction im; "%s" = instruction rst; +"%s" = instruction any; "%s" = instruction; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java new file mode 100644 index 000000000..ab11dc23b --- /dev/null +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java @@ -0,0 +1,817 @@ +package net.emustudio.plugins.cpu.zilogZ80; + +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; +import net.emustudio.emulib.plugins.cpu.Decoder; +import net.emustudio.emulib.plugins.cpu.Disassembler; +import net.emustudio.emulib.plugins.cpu.InvalidInstructionException; +import net.emustudio.emulib.runtime.helpers.NumberUtils; +import net.emustudio.plugins.cpu.zilogZ80.gui.DecoderImpl; +import net.emustudio.plugins.cpu.zilogZ80.gui.DisassemblerImpl; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class DisassemblerTest { + + ByteMemoryStub memoryStub; + Decoder decoder; + Disassembler disassembler; + + @Before + public void setUp() { + memoryStub = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); + decoder = new DecoderImpl(memoryStub); + disassembler = new DisassemblerImpl(memoryStub, decoder); + } + + + @Test + public void testDisassemble() throws InvalidInstructionException { + memoryStub.setMemory(new short[]{ + 0, // nop + 0x08, // ex af, af' + 0x10, 0x20, // djnz 20 + 0x18, 0x20, // jr 20 + 0x20, 0x20, // jr nz, 20 + 0x28, 0x20, // jr z, 20h + 0x30, 0x20, // jr nc, 20h + 0x38, 0x20, // jr c, 20h + 0x01, 0x34, 0x12, // 10 // ld bc, 0x1234 + 0x11, 0x34, 0x12, // ld de, 0x1234 + 0x21, 0x34, 0x12, // ld hl, 0x1234 + 0x31, 0x34, 0x12, // ld sp, 0x1234 + 0x09, // add hl, bc + 0x19, // add hl, de + 0x29, // add hl, hl + 0x39, // add hl, sp + 0x02, // ld (bc), a + 0x12, // ld (de), a + 0x0A, // 20 // ld a, (bc) + 0x1A, // ld a, (de) + 0x22, 0x34, 0x12, // ld (0x1234), hl\n" // 0 + 0x32, 0x34, 0x12, // ld (0x1234), a + 0x2A, 0x34, 0x12, // ld hl, (0x1234) + 0x3A, 0x34, 0x12, // ld a, (0x1234) + 0x03, // inc bc + 0x13, // inc de + 0x23, // 30 // inc hl + 0x33, // inc sp + 0x0B, // dec bc + 0x1B, // dec de + 0x2B, // dec hl + 0x3B, // dec sp + 0x04, // inc b + 0x0C, // inc c + 0x14, // inc d + 0x1C, // inc e + 0x24, // inc h + 0x2C, // inc l + 0x3C, // inc a + 0x05, // dec b + 0x0D, // dec c + 0x15, // dec d + 0x1D, // 40 // dec e + 0x25, // dec h + 0x2D, // dec l + 0x3D, // dec a + 0x06, 0x20, // ld b, 0x20 + 0x0E, 0x20, // ld c, 0x20 + 0x16, 0x20, // ld d, 0x20 + 0x1E, 0x20, // ld e, 0x20 + 0x26, 0x20, // ld h, 0x20 + 0x2E, 0x20, // ld l, 0x20 + 0x07, // 50 // rlca + 0x0F, // rrca + 0x17, // rla + 0x1F, // rra + 0x27, // daa + 0x2F, // cpl + 0x37, // scf + 0x3F, // ccf + 0x40, // ld b, b + 0x41, // ld b, c + 0x42, // ld b, d + 0x43, // ld b, e + 0x44, // ld b, h + 0x45, // ld b, l + 0x47, // ld b, a + 0x70, // ld (hl), b + 0x71, // 60 // ld (hl), c + 0x72, // ld (hl), d + 0x73, // ld (hl), e + 0x74, // ld (hl), h + 0x75, // ld (hl), l + 0x77, // ld (hl), a + 0x76, // halt + 0x80, // add a, b + 0x86, // add a, (hl) + 0x89, // adc a, c + 0x8E, // adc a, (hl) + 0x90, // sub b + 0x96, // sub (hl) + 0x98, // sbc a, b + 0x9E, // sbc a, (hl) + 0xA0, // and b + 0xA6, // 70 // and (hl) + 0xA8, // xor b + 0xAE, // xor (hl) + 0xB0, // or b + 0xB6, // or (hl) + 0xB8, // cp b + 0xBE, // cp (hl) + 0xC0, // ret nz + 0xC8, // ret z + 0xD0, // ret nc + 0xD8, // ret c + 0xE0, // 7b // ret po + 0xE8, // ret pe + 0xF0, // ret p + 0xF8, // ret m + 0xC1, // pop bc + 0xD1, // 80 // pop de + 0xE1, // pop hl + 0xF1, // pop af + 0xC9, // ret + 0xD9, // exx + 0xE9, // jp hl + 0xE9, // jp (hl) + 0xF9, // ld sp, hl + 0xC2, 0x34, 0x12, // jp nz, 0x1234 + 0xCA, 0x34, 0x12, // jp z, 0x1234 + 0xD2, 0x34, 0x12, // jp nc, 0x1234 + 0xDA, 0x34, 0x12, // jp c, 0x1234 + 0xE2, 0x34, 0x12, // jp po, 0x1234 + 0xEA, 0x34, 0x12, // jp pe, 0x1234 + 0xF2, 0x34, 0x12, // jp p, 0x1234 + 0xFA, 0x34, 0x12, // jp m, 0x1234 + 0xC3, 0x34, 0x12, // jp 0x1234 + 0xD3, 0x20, // out (0x20), a + 0xDB, 0x20, // in a, (0x20) + 0xE3, // ex (sp), hl + 0xEB, // ex de, hl + 0xF3, // di + 0xFB, // ei + 0xC4, 0x34, 0x12, // call nz, 0x1234 + 0xCC, 0x34, 0x12, // call z, 0x1234 + 0xD4, 0x34, 0x12, // call nc, 0x1234 + 0xDC, 0x34, 0x12, // call c, 0x1234 + 0xE4, 0x34, 0x12, // call po, 0x1234 + 0xEC, 0x34, 0x12, // call pe, 0x1234 + 0xF4, 0x34, 0x12, // call p, 0x1234 + 0xFC, 0x34, 0x12, // call m, 0x1234 + 0xC5, // push bc + 0xD5, // push de + 0xE5, // push hl + 0xF5, // push af + 0xCD, 0x34, 0x12, // call 0x1234 + 0xC6, 0x20, // add a, 0x20 + 0xCE, 0x20, // adc a, 0x20 + 0xD6, 0x20, // sub 0x20 + 0xDE, 0x20, // sbc a, 0x20 + 0xE6, 0x20, // and 0x20 + 0xEE, 0x20, // xor 0x20 + 0xF6, 0x20, // or 0x20 + 0xFE, 0x20, // cp 0x20 + 0xC7, // rst 0 + 0xCF, // rst 8 + 0xD7, // rst 10h + 0xDF, // rst 18h + 0xE7, // rst 20h + 0xEF, // rst 28h + 0xF7, // rst 30h + 0xFF, // rst 38h + 0xCB, 0x00, // rlc b + 0xCB, 0x06, // rlc (HL) + 0xCB, 0x09, // rrc c + 0xCB, 0x0E, // rrc (HL) + 0xCB, 0x12, // rl d + 0xCB, 0x16, // rl (HL) + 0xCB, 0x1B, // rr e + 0xCB, 0x1E, // rr (hl) + 0xCB, 0x24, // sla h + 0xCB, 0x26, // sla (hl) + 0xCB, 0x2D, // sra l + 0xCB, 0x2E, // sra (hl) + 0xCB, 0x30, // sll b + 0xCB, 0x36, // sll (hl) + 0xCB, 0x39, // srl c + 0xCB, 0x3E, // srl (hl) + 0xCB, 0x68, // bit 5, b + 0xCB, 0x6E, // bit 5, (hl) + 0xCB, 0xA9, // res 5, c + 0xCB, 0xB6, // res 6, (hl) + 0xCB, 0xFA, // set 7, d + 0xCB, 0xFE, // set 7, (hl) + 0xED, 0x58, // in e, (c) + 0xED, 0x70, // in (c) + 0xED, 0x61, // out (c), h + 0xED, 0x71, // out (c), 0 + 0xED, 0x42, // sbc hl, bc + 0xED, 0x52, // sbc hl, de + 0xED, 0x62, // sbc hl, hl + 0xED, 0x72, // sbc hl, sp + 0xED, 0x4A, // adc hl, bc + 0xED, 0x5A, // adc hl, de + 0xED, 0x6A, // adc hl, hl + 0xED, 0x7A, // adc hl, sp + 0xED, 0x43, 0x34, 0x12, // ld (1234h), bc + 0xED, 0x53, 0x34, 0x12, // ld (1234h), de + 0x22, 0x34, 0x12, // 0xED, 0x63, 0x34, 0x12 // ld (1234h), hl + 0xED, 0x73, 0x34, 0x12, // ld (1234h), sp + 0xED, 0x4B, 0x34, 0x12, // ld bc, (0x1234) + 0xED, 0x5B, 0x34, 0x12, // ld de, (0x1234) + 0x2A, 0x34, 0x12, // 0xED, 0x6B, 0x34, 0x12 // ld hl, (0x1234) + 0xED, 0x7B, 0x34, 0x12, // ld sp, (0x1234) + 0xED, 0x44, // neg + 0xED, 0x45, // retn + 0xED, 0x4D, // reti + 0xED, 0x46, // im 0 + 0xED, 0x4E, // im 0/1 + 0xED, 0x56, // im 1 + 0xED, 0x5E, // im 2 + 0xED, 0x47, // ld i, a + 0xED, 0x4F, // ld r, a + 0xED, 0x57, // ld a, i + 0xED, 0x5F, // ld a, r + 0xED, 0x67, // rrd + 0xED, 0x6F, // rld + 0xED, 0xA0, // ldi + 0xED, 0xA8, // ldd + 0xED, 0xB0, // ldir + 0xED, 0xB8, // lddr + 0xED, 0xA1, // cpi + 0xED, 0xA9, // cpd + 0xED, 0xB1, // cpir + 0xED, 0xB9, // cpdr + 0xED, 0xA2, // ini + 0xED, 0xAA, // ind + 0xED, 0xB2, // inir + 0xED, 0xBA, // indr + 0xED, 0xA3, // outi + 0xED, 0xAB, // outd + 0xED, 0xB3, // otir + 0xED, 0xBB, // otdr + 0xDD, 0xCB, 0x20, 0x00, // rlc (ix+0x20), b + 0xFD, 0xCB, 0x20, 0x00, // rlc (iy+0x20), b + 0xDD, 0xCB, 0x20, 0x06, // rlc (ix+0x20) + 0xFD, 0xCB, 0x20, 0x06, // rlc (iy+0x20) + 0xDD, 0xCB, 0x20, 0x09, // rrc (ix+0x20), c + 0xFD, 0xCB, 0x20, 0x09, // rrc (iy+0x20), c + 0xDD, 0xCB, 0x20, 0x0E, // rrc (ix+0x20) + 0xFD, 0xCB, 0x20, 0x0E, // rrc (iy+0x20) + 0xDD, 0xCB, 0x20, 0x12, // rl (ix+0x20), d + 0xFD, 0xCB, 0x20, 0x12, // rl (iy+0x20), d + 0xDD, 0xCB, 0x20, 0x16, // rl (ix+0x20) + 0xFD, 0xCB, 0x20, 0x16, // rl (iy+0x20) + 0xDD, 0xCB, 0x20, 0x1B, // rr (ix+0x20), e + 0xFD, 0xCB, 0x20, 0x1B, // rr (iy+0x20), e + 0xDD, 0xCB, 0x20, 0x1E, // rr (ix+0x20) + 0xFD, 0xCB, 0x20, 0x1E, // rr (iy+0x20) + 0xDD, 0xCB, 0x20, 0x24, // sla (ix+0x20), h + 0xFD, 0xCB, 0x20, 0x24, // sla (iy+0x20), h + 0xDD, 0xCB, 0x20, 0x26, // sla (ix+0x20) + 0xFD, 0xCB, 0x20, 0x26, // sla (iy+0x20) + 0xDD, 0xCB, 0x20, 0x2D, // sra (ix+0x20), l + 0xFD, 0xCB, 0x20, 0x2D, // sra (iy+0x20), l + 0xDD, 0xCB, 0x20, 0x2E, // sra (ix+0x20) + 0xFD, 0xCB, 0x20, 0x2E, // sra (iy+0x20) + 0xDD, 0xCB, 0x20, 0x30, // sll (ix+0x20), b + 0xFD, 0xCB, 0x20, 0x30, // sll (iy+0x20), b + 0xDD, 0xCB, 0x20, 0x36, // sll (ix+0x20) + 0xFD, 0xCB, 0x20, 0x36, // sll (iy+0x20) + 0xDD, 0xCB, 0x20, 0x39, // srl (ix+0x20), c + 0xFD, 0xCB, 0x20, 0x39, // srl (iy+0x20), c + 0xDD, 0xCB, 0x20, 0x3E, // srl (ix+0x20) + 0xFD, 0xCB, 0x20, 0x3E, // srl (iy+0x20) + 0xDD, 0xCB, 0x20, 0x5E, // bit 3, (ix+0x20) + 0xFD, 0xCB, 0x20, 0x5E, // bit 3, (iy+0x20) + 0xDD, 0xCB, 0x20, 0xA8, // res 5, (ix+0x20), b + 0xFD, 0xCB, 0x20, 0xA8, // res 5, (iy+0x20), b + 0xDD, 0xCB, 0x20, 0xAE, // res 5, (ix+0x20) + 0xFD, 0xCB, 0x20, 0xAE, // res 5, (iy+0x20) + 0xDD, 0xCB, 0x20, 0xF1, // set 6, (ix+0x20), c + 0xFD, 0xCB, 0x20, 0xF1, // set 6, (iy+0x20), c + 0xDD, 0xCB, 0x20, 0xF6, // set 6, (ix+0x20) + 0xFD, 0xCB, 0x20, 0xF6, // set 6, (iy+0x20) + 0xDD, 0x21, 0x34, 0x12, // ld ix, 0x1234 + 0xFD, 0x21, 0x34, 0x12, // ld iy, 0x1234 + 0xDD, 0x09, // add ix, bc + 0xFD, 0x09, // add iy, bc + 0xDD, 0x19, // add ix, de + 0xFD, 0x19, // add iy, de + 0xDD, 0x29, // add ix, ix + 0xFD, 0x29, // add iy, iy + 0xDD, 0x39, // add ix, sp + 0xFD, 0x39, // add iy, sp + 0xDD, 0x22, 0x34, 0x12, // ld (0x1234), ix + 0xFD, 0x22, 0x34, 0x12, // ld (0x1234), iy + 0xDD, 0x2A, 0x34, 0x12, // ld ix, (0x1234) + 0xFD, 0x2A, 0x34, 0x12, // ld iy, (0x1234) + 0xDD, 0x23, // inc ix + 0xFD, 0x23, // inc iy + 0xDD, 0x2B, // dec ix + 0xFD, 0x2B, // dec iy + 0xDD, 0x24, // inc ixh + 0xFD, 0x24, // inc iyh + 0xDD, 0x2C, // inc ixl + 0xFD, 0x2C, // inc iyl + 0xDD, 0x34, 0x20, // inc (ix+0x20) + 0xFD, 0x34, 0x20, // inc (iy+0x20) + 0xDD, 0x25, // dec ixh + 0xFD, 0x25, // dec iyh + 0xDD, 0x2D, // dec ixl + 0xFD, 0x2D, // dec iyl + 0xDD, 0x35, 0x20, // dec (ix+0x20) + 0xFD, 0x35, 0x20, // dec (iy+0x20) + 0xDD, 0x26, 0x20, // ld ixh, 0x20 + 0xDD, 0x2E, 0x20, // ld ixl, 0x20 + 0xFD, 0x26, 0x20, // ld iyh, 0x20 + 0xFD, 0x2E, 0x20, // ld iyl, 0x20 + 0xDD, 0x36, 0x20, 0x20, // ld (ix+0x20), 0x20 + 0xFD, 0x36, 0x20, 0x20, // ld (iy+0x20), 0x20 + 0xDD, 0x60, // ld ixh, b + 0xDD, 0x64, // ld ixh, ixh + 0xDD, 0x65, // ld ixh, ixl + 0xFD, 0x61, // ld iyh, c + 0xFD, 0x64, // ld iyh, iyh + 0xFD, 0x65, // ld iyh, iyl + 0xDD, 0x6A, // ld ixl, d + 0xDD, 0x6C, // ld ixl, ixh + 0xDD, 0x6D, // ld ixl, ixl + 0xFD, 0x6B, // ld iyl, e + 0xFD, 0x6C, // ld iyl, iyh + 0xFD, 0x6D, // ld iyl, iyl + 0xDD, 0x72, 0x20, // ld (ix+0x20), d + 0xDD, 0x74, 0x20, // ld (ix+0x20), h + 0xDD, 0x75, 0x20, // ld (ix+0x20), l + 0xFD, 0x73, 0x20, // ld (iy+0x20), e + 0xFD, 0x74, 0x20, // ld (iy+0x20), h + 0xFD, 0x75, 0x20, // ld (iy+0x20), l + 0xDD, 0x7C, // ld a, ixh + 0xFD, 0x7C, // ld a, iyh + 0xDD, 0x7D, // ld a, ixl + 0xFD, 0x7D, // ld a, iyl + 0xDD, 0x7E, 0x20, // ld a, (ix+0x20) + 0xFD, 0x7E, 0x20, // ld a, (iy+0x20) + 0xDD, 0x66, 0x20, // ld h, (ix+0x20) + 0xDD, 0x6E, 0x20, // ld l, (ix+0x20) + 0xFD, 0x66, 0x20, // ld h, (iy+0x20) + 0xFD, 0x6E, 0x20, // ld l, (iy+0x20) + 0xDD, 0x84, // add a, ixh + 0xDD, 0x85, // add a, ixl + 0xDD, 0x86, 0x20, // add a, (ix + 0x20) + 0xFD, 0x84, // add a, iyh + 0xFD, 0x85, // add a, iyl + 0xFD, 0x86, 0x20, // add a, (iy+0x20) + 0xDD, 0x8C, // adc a, ixh + 0xDD, 0x8D, // adc a, ixl + 0xDD, 0x8E, 0x20, // adc a, (ix+0x20) + 0xFD, 0x8C, // adc a, iyh + 0xFD, 0x8D, // adc a, iyl + 0xFD, 0x8E, 0x20, // adc a, (iy+0x20) + 0xDD, 0x94, // sub ixh + 0xDD, 0x95, // sub ixl + 0xDD, 0x96, 0x20, // sub (ix+0x20) + 0xFD, 0x94, // sub iyh + 0xFD, 0x95, // sub iyl + 0xFD, 0x96, 0x20, // sub (iy+0x20) + 0xDD, 0x9C, // sbc a, ixh + 0xDD, 0x9D, // sbc a, ixl + 0xDD, 0x9E, 0x20, // sbc a, (ix+0x20) + 0xFD, 0x9C, // sbc a, iyh + 0xFD, 0x9D, // sbc a, iyl + 0xFD, 0x9E, 0x20, // sbc a, (iy+0x20) + 0xDD, 0xA4, // and ixh + 0xDD, 0xA5, // and ixl + 0xDD, 0xA6, 0x20, // and (ix+0x20) + 0xFD, 0xA4, // and iyh + 0xFD, 0xA5, // and iyl + 0xFD, 0xA6, 0x20, // and (iy+0x20) + 0xDD, 0xAC, // xor ixh + 0xDD, 0xAD, // xor ixl + 0xDD, 0xAE, 0x20, // xor (ix+0x20) + 0xFD, 0xAC, // xor iyh + 0xFD, 0xAD, // xor iyl + 0xFD, 0xAE, 0x20, // xor (iy+0x20) + 0xDD, 0xB4, // or ixh + 0xDD, 0xB5, // or ixl + 0xDD, 0xB6, 0x20, // or (ix+0x20) + 0xFD, 0xB4, // or iyh + 0xFD, 0xB5, // or iyl + 0xFD, 0xB6, 0x20, // or (iy+0x20) + 0xDD, 0xBC, // cp ixh + 0xDD, 0xBD, // cp ixl + 0xDD, 0xBE, 0x20, // cp (ix+0x20) + 0xFD, 0xBC, // cp iyh + 0xFD, 0xBD, // cp iyl + 0xFD, 0xBE, 0x20, // cp (iy+0x20) + 0xDD, 0xE1, // pop ix + 0xFD, 0xE1, // pop iy + 0xDD, 0xE9, // jp (ix) + 0xFD, 0xE9, // jp (iy) + 0xDD, 0xF9, // ld sp, ix + 0xFD, 0xF9, // ld sp, iy + 0xDD, 0xE3, // ex (sp), ix + 0xFD, 0xE3, // ex (sp), iy + 0xDD, 0xE5, // push ix + 0xFD, 0xE5 // push iy + }); + + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < memoryStub.getSize(); i = disassembler.getNextInstructionPosition(i)) { + builder.append(disassembler.disassemble(i).getMnemo()); + } + String result = builder.toString(); + assertEquals( + "nop" + + "ex af, af'" + + "djnz 20" + + "jr 20" + + "jr nz, 20" + + "jr z, 20" + + "jr nc, 20" + + "jr c, 20" + + "ld bc, 1234" + + "ld de, 1234" + + "ld hl, 1234" + + "ld sp, 1234" + + "add hl, bc" + + "add hl, de" + + "add hl, hl" + + "add hl, sp" + + "ld (bc), a" + + "ld (de), a" + + "ld a, (bc)" + + "ld a, (de)" + + "ld (1234), hl" + + "ld (1234), a" + + "ld hl, (1234)" + + "ld a, (1234)" + + "inc bc" + + "inc de" + + "inc hl" + + "inc sp" + + "dec bc" + + "dec de" + + "dec hl" + + "dec sp" + + "inc b" + + "inc c" + + "inc d" + + "inc e" + + "inc h" + + "inc l" + + "inc a" + + "dec b" + + "dec c" + + "dec d" + + "dec e" + + "dec h" + + "dec l" + + "dec a" + + "ld b, 20" + + "ld c, 20" + + "ld d, 20" + + "ld e, 20" + + "ld h, 20" + + "ld l, 20" + + "rlca" + + "rrca" + + "rla" + + "rra" + + "daa" + + "cpl" + + "scf" + + "ccf" + + "ld b, b" + + "ld b, c" + + "ld b, d" + + "ld b, e" + + "ld b, h" + + "ld b, l" + + "ld b, a" + + "ld (hl), b" + + "ld (hl), c" + + "ld (hl), d" + + "ld (hl), e" + + "ld (hl), h" + + "ld (hl), l" + + "ld (hl), a" + + "halt" + + "add a, b" + + "add a, (hl)" + + "adc a, c" + + "adc a, (hl)" + + "sub b" + + "sub (hl)" + + "sbc a, b" + + "sbc a, (hl)" + + "and b" + + "and (hl)" + + "xor b" + + "xor (hl)" + + "or b" + + "or (hl)" + + "cp b" + + "cp (hl)" + + "ret nz" + + "ret z" + + "ret nc" + + "ret c" + + "ret po" + + "ret pe" + + "ret p" + + "ret m" + + "pop bc" + + "pop de" + + "pop hl" + + "pop af" + + "ret" + + "exx" + + "jp (hl)" + + "jp (hl)" + + "ld sp, hl" + + "jp nz, 1234" + + "jp z, 1234" + + "jp nc, 1234" + + "jp c, 1234" + + "jp po, 1234" + + "jp pe, 1234" + + "jp p, 1234" + + "jp m, 1234" + + "jp 1234" + + "out (20), a" + + "in a, (20)" + + "ex (sp), hl" + + "ex de, hl" + + "di" + + "ei" + + "call nz, 1234" + + "call z, 1234" + + "call nc, 1234" + + "call c, 1234" + + "call po, 1234" + + "call pe, 1234" + + "call p, 1234" + + "call m, 1234" + + "push bc" + + "push de" + + "push hl" + + "push af" + + "call 1234" + + "add a, 20" + + "adc a, 20" + + "sub 20" + + "sbc a, 20" + + "and 20" + + "xor 20" + + "or 20" + + "cp 20" + + "rst 00" + + "rst 08" + + "rst 10" + + "rst 18" + + "rst 20" + + "rst 28" + + "rst 30" + + "rst 38" + + "rlc b" + + "rlc (hl)" + + "rrc c" + + "rrc (hl)" + + "rl d" + + "rl (hl)" + + "rr e" + + "rr (hl)" + + "sla h" + + "sla (hl)" + + "sra l" + + "sra (hl)" + + "sll b" + + "sll (hl)" + + "srl c" + + "srl (hl)" + + "bit 5, b" + + "bit 5, (hl)" + + "res 5, c" + + "res 6, (hl)" + + "set 7, d" + + "set 7, (hl)" + + "in e, (c)" + + "in (c)" + + "out (c), h" + + "out (c), 0" + + "sbc hl, bc" + + "sbc hl, de" + + "sbc hl, hl" + + "sbc hl, sp" + + "adc hl, bc" + + "adc hl, de" + + "adc hl, hl" + + "adc hl, sp" + + "ld (1234), bc" + + "ld (1234), de" + + "ld (1234), hl" + + "ld (1234), sp" + + "ld bc, (1234)" + + "ld de, (1234)" + + "ld hl, (1234)" + + "ld sp, (1234)" + + "neg" + + "retn" + + "reti" + + "im 0" + + "im 0/1" + + "im 1" + + "im 2" + + "ld i, a" + + "ld r, a" + + "ld a, i" + + "ld a, r" + + "rrd" + + "rld" + + "ldi" + + "ldd" + + "ldir" + + "lddr" + + "cpi" + + "cpd" + + "cpir" + + "cpdr" + + "ini" + + "ind" + + "inir" + + "indr" + + "outi" + + "outd" + + "otir" + + "otdr" + + "rlc (ix+20), b" + + "rlc (iy+20), b" + + "rlc (ix+20)" + + "rlc (iy+20)" + + "rrc (ix+20), c" + + "rrc (iy+20), c" + + "rrc (ix+20)" + + "rrc (iy+20)" + + "rl (ix+20), d" + + "rl (iy+20), d" + + "rl (ix+20)" + + "rl (iy+20)" + + "rr (ix+20), e" + + "rr (iy+20), e" + + "rr (ix+20)" + + "rr (iy+20)" + + "sla (ix+20), h" + + "sla (iy+20), h" + + "sla (ix+20)" + + "sla (iy+20)" + + "sra (ix+20), l" + + "sra (iy+20), l" + + "sra (ix+20)" + + "sra (iy+20)" + + "sll (ix+20), b" + + "sll (iy+20), b" + + "sll (ix+20)" + + "sll (iy+20)" + + "srl (ix+20), c" + + "srl (iy+20), c" + + "srl (ix+20)" + + "srl (iy+20)" + + "bit 3, (ix+20)" + + "bit 3, (iy+20)" + + "res 5, (ix+20), b" + + "res 5, (iy+20), b" + + "res 5, (ix+20)" + + "res 5, (iy+20)" + + "set 6, (ix+20), c" + + "set 6, (iy+20), c" + + "set 6, (ix+20)" + + "set 6, (iy+20)" + + "ld ix, 1234" + + "ld iy, 1234" + + "add ix, bc" + + "add iy, bc" + + "add ix, de" + + "add iy, de" + + "add ix, ix" + + "add iy, iy" + + "add ix, sp" + + "add iy, sp" + + "ld (1234), ix" + + "ld (1234), iy" + + "ld ix, (1234)" + + "ld iy, (1234)" + + "inc ix" + + "inc iy" + + "dec ix" + + "dec iy" + + "inc ixh" + + "inc iyh" + + "inc ixl" + + "inc iyl" + + "inc (ix+20)" + + "inc (iy+20)" + + "dec ixh" + + "dec iyh" + + "dec ixl" + + "dec iyl" + + "dec (ix+20)" + + "dec (iy+20)" + + "ld ixh, 20" + + "ld ixl, 20" + + "ld iyh, 20" + + "ld iyl, 20" + + "ld (ix+20), 20" + + "ld (iy+20), 20" + + "ld ixh, b" + + "ld ixh, ixh" + + "ld ixh, ixl" + + "ld iyh, c" + + "ld iyh, iyh" + + "ld iyh, iyl" + + "ld ixl, d" + + "ld ixl, ixh" + + "ld ixl, ixl" + + "ld iyl, e" + + "ld iyl, iyh" + + "ld iyl, iyl" + + "ld (ix+20), d" + + "ld (ix+20), h" + + "ld (ix+20), l" + + "ld (iy+20), e" + + "ld (iy+20), h" + + "ld (iy+20), l" + + "ld a, ixh" + + "ld a, iyh" + + "ld a, ixl" + + "ld a, iyl" + + "ld a, (ix+20)" + + "ld a, (iy+20)" + + "ld h, (ix+20)" + + "ld l, (ix+20)" + + "ld h, (iy+20)" + + "ld l, (iy+20)" + + "add a, ixh" + + "add a, ixl" + + "add a, (ix+20)" + + "add a, iyh" + + "add a, iyl" + + "add a, (iy+20)" + + "adc a, ixh" + + "adc a, ixl" + + "adc a, (ix+20)" + + "adc a, iyh" + + "adc a, iyl" + + "adc a, (iy+20)" + + "sub ixh" + + "sub ixl" + + "sub (ix+20)" + + "sub iyh" + + "sub iyl" + + "sub (iy+20)" + + "sbc a, ixh" + + "sbc a, ixl" + + "sbc a, (ix+20)" + + "sbc a, iyh" + + "sbc a, iyl" + + "sbc a, (iy+20)" + + "and ixh" + + "and ixl" + + "and (ix+20)" + + "and iyh" + + "and iyl" + + "and (iy+20)" + + "xor ixh" + + "xor ixl" + + "xor (ix+20)" + + "xor iyh" + + "xor iyl" + + "xor (iy+20)" + + "or ixh" + + "or ixl" + + "or (ix+20)" + + "or iyh" + + "or iyl" + + "or (iy+20)" + + "cp ixh" + + "cp ixl" + + "cp (ix+20)" + + "cp iyh" + + "cp iyl" + + "cp (iy+20)" + + "pop ix" + + "pop iy" + + "jp (ix)" + + "jp (iy)" + + "ld sp, ix" + + "ld sp, iy" + + "ex (sp), ix" + + "ex (sp), iy" + + "push ix" + + "push iy", + result + ); + } +} diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java index d057572c9..491583d81 100644 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java +++ b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java @@ -39,7 +39,8 @@ public Byte read(int from) { @Override public Byte[] read(int from, int count) { - return Arrays.copyOfRange(memory, from, from + count); // from+count can be >= memory.length + int to = Math.min(memory.length, from + count); + return Arrays.copyOfRange(memory, from, to); } @Override diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java index c1799d426..fddc96160 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java @@ -146,7 +146,9 @@ public Byte readBank(int from, int bank) { @Override public Byte[] read(int from, int count) { - return Arrays.copyOfRange(mem[bank(from)], from, from + count); // from+count can be >= memory.length + Byte[] memBank = mem[bank(from)]; + int to = Math.min(memBank.length, from + count); + return Arrays.copyOfRange(mem[bank(from)], from, to); } @Override diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java index 487d2a92c..5ae4cf3bc 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java @@ -48,7 +48,8 @@ public Byte read(int from) { @Override public Byte[] read(int from, int count) { - return Arrays.copyOfRange(memory, from, from + count); // from+count can be >= memory.length + int to = Math.min(memory.length, from + count); + return Arrays.copyOfRange(memory, from, to); } @Override diff --git a/settings.gradle b/settings.gradle index 7619871f2..a558a0cf6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -17,6 +17,13 @@ * along with this program. If not, see . */ +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + } +} + rootProject.name = 'emuStudio' include ':application' From 662cfbc1c4ad7e11bb3a19dbfc828de112484d97 Mon Sep 17 00:00:00 2001 From: Paolo Amoroso Date: Sun, 27 Mar 2022 16:00:13 +0200 Subject: [PATCH 124/314] Rearrange loop, clear stack, revise comments Move the instructions that update the inner loop control registers closer to the check for termination. Clear PSW left on the stack when jumping to the program exit. Revise comments. --- .../as-8080/src/main/examples/twirl.asm | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/examples/twirl.asm b/plugins/compiler/as-8080/src/main/examples/twirl.asm index 4e99c7510..4671a181b 100644 --- a/plugins/compiler/as-8080/src/main/examples/twirl.asm +++ b/plugins/compiler/as-8080/src/main/examples/twirl.asm @@ -8,15 +8,15 @@ FRAMES equ 8 ; Number of animation frames CLS equ 1ah ; ADM-3A escape sequence HOME equ 1eh ; ADM-3A escape sequence -STATUS equ 10h ; Input status port +STATUS equ 10h ; Input status port READY equ 1 ; Character ready status mask mvi a, CLS ; Clear screen call putchar -loop: lxi h, ANIM - mvi b, FRAMES +loop: lxi h, ANIM ; Initialize frame pointer... + mvi b, FRAMES ; ...and count loop1: mvi a, HOME ; Go to home call putchar @@ -24,23 +24,24 @@ loop1: mvi a, HOME ; Go to home mov a, m ; Print current frame call putchar - inx h - dcr b - push psw - in STATUS ; Key pressed? - ani READY + in STATUS + ani READY ; Key pressed? jnz exit ; Yes pop psw + inx h + dcr b jnz loop1 jmp loop - -exit: hlt -ANIM: db '|/-\|/-\' ; 8 frames +exit: pop psw ; Clear psw left on stack + hlt + + +ANIM: db '|/-\|/-\' ; 8 frames include 'include\putchar.inc' From 076fac56c9f116eb898c3a1bb591d2d35d6033a9 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 29 Apr 2022 11:21:56 +0100 Subject: [PATCH 125/314] [#201] as-z80, z80-cpu: lot of fixes --- build.gradle | 5 +- .../plugins/compiler/asZ80/ast/Evaluated.java | 10 +- .../asZ80/ast/expr/ExprCurrentAddress.java | 2 +- .../compiler/asZ80/ast/instr/Instr.java | 5 + .../asZ80/ast/pseudo/PseudoLabel.java | 2 +- .../asZ80/visitors/CheckExprSizesVisitor.java | 2 +- .../asZ80/visitors/GenerateCodeVisitor.java | 16 +- .../compiler/asZ80/e2e/InstrExprTest.java | 31 +- plugins/cpu/8080-cpu/build.gradle | 2 +- plugins/cpu/brainduck-cpu/build.gradle | 2 +- plugins/cpu/ram-cpu/build.gradle | 1 + plugins/cpu/rasp-cpu/build.gradle | 1 + plugins/cpu/ssem-cpu/build.gradle | 2 +- plugins/cpu/z80-cpu/build.gradle | 3 +- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 1 - .../plugins/cpu/zilogZ80/EmulatorEngine.java | 355 ++++++++---------- .../plugins/cpu/zilogZ80/EmulatorTables.java | 131 +++++-- .../plugins/cpu/zilogZ80/ArithmeticTest.java | 62 +-- .../plugins/cpu/zilogZ80/ControlTest.java | 6 +- .../zilogZ80/EmulatorTablesGeneration.java | 91 +++++ .../plugins/cpu/zilogZ80/LogicTest.java | 6 +- .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 87 +++-- .../memory/bytemem/MemoryContextImpl.java | 1 + 23 files changed, 529 insertions(+), 295 deletions(-) create mode 100644 plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java diff --git a/build.gradle b/build.gradle index dee80a043..101718f20 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ /* * This file is part of emuStudio. * - * Copyright (C) 2006-2020 Peter Jakubčo + * Copyright (C) 2006-2022 Peter Jakubčo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -96,5 +96,8 @@ subprojects { repositories { mavenLocal() mavenCentral() + maven { + url 'https://oss.sonatype.org/content/repositories/snapshots' + } } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Evaluated.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Evaluated.java index 43b20df07..f6e960285 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Evaluated.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Evaluated.java @@ -4,15 +4,21 @@ public class Evaluated extends Node { public final int value; + public final boolean isAddress; - public Evaluated(int line, int column, int value) { + public Evaluated(int line, int column, int value, boolean isAddress) { super(line, column); this.value = value; + this.isAddress = isAddress; + } + + public Evaluated(int line, int column, int value) { + this(line, column, value, false); } @Override protected Node mkCopy() { - return new Evaluated(line, column, value); + return new Evaluated(line, column, value, isAddress); } @Override diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprCurrentAddress.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprCurrentAddress.java index a856afa81..733a7c44c 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprCurrentAddress.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprCurrentAddress.java @@ -25,6 +25,6 @@ protected Node mkCopy() { @Override public Optional eval(Optional currentAddress, NameSpace env) { - return currentAddress.map(addr -> new Evaluated(line, column, addr)); + return currentAddress.map(addr -> new Evaluated(line, column, addr, true)); } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java index 033bf23e9..689983cf6 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java @@ -37,6 +37,11 @@ public byte eval() { return (byte)(((x << 6) | (y << 3) | (z & 7)) & 0xFF); } + public boolean hasRelativeAddress() { + // DJNZ, JR, JR cc + return (x == 0 && z == 0 && y >= 2 && y <= 7); + } + @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java index 73eee631d..d576c803f 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java @@ -25,7 +25,7 @@ public PseudoLabel(Token label) { @Override public Optional eval(Optional currentAddress, NameSpace env) { - return currentAddress.map(addr -> new Evaluated(line, column, addr)); + return currentAddress.map(addr -> new Evaluated(line, column, addr, true)); } @Override diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java index 7eccef8ac..96f6d89dc 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java @@ -37,7 +37,7 @@ public void visit(DataDS node) { @Override public void visit(Instr node) { - expectedBytes = 0; + expectedBytes = node.hasRelativeAddress() ? 1 : 0; visitChildren(node); } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java index eb94e5d31..57bce8f0e 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java @@ -15,6 +15,8 @@ public class GenerateCodeVisitor extends NodeVisitor { private final IntelHEX hex; private int expectedBytes; + private boolean isRelative; // if we should treat Evaluated value as "relative address" + private int currentAddress; // for computing relative address public GenerateCodeVisitor(IntelHEX hex) { this.hex = Objects.requireNonNull(hex); @@ -48,12 +50,16 @@ public void visit(DataDS node) { @Override public void visit(Instr node) { + isRelative = node.hasRelativeAddress(); + currentAddress = node.getAddress(); + hex.add(node.eval()); int instrSize = node.getSizeBytes().orElse(1); if (instrSize > 1) { expectedBytes = 0; visitChildren(node); } + isRelative = false; } @Override @@ -109,16 +115,18 @@ public void visit(PseudoOrg node) { @Override public void visit(Evaluated node) { + final int value = (isRelative && node.isAddress) ? (node.value - currentAddress) : node.value; + if (expectedBytes == 1) { - addByte(node.value); + addByte(value); } else if (expectedBytes == 2) { - addWord(node.value); + addWord(value); } else { node.getSizeBytes().ifPresent(size -> { if (size == 1) { - addByte(node.value); + addByte(value); } else if (size == 2) { - addWord(node.value); + addWord(value); } }); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java index a352acfc8..c8b94b5bc 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java @@ -5,7 +5,7 @@ public class InstrExprTest extends AbstractCompilerTest { @Test - public void testRST() throws Exception { + public void testJump() { compile( "JP EXAMPLE\n" + "RST 00H\n" + @@ -14,7 +14,34 @@ public void testRST() throws Exception { ); assertProgram( - 0xC3, 0x04, 0x00, 0xC7, 0x3E, 0x01 + 0xC3, 0x04, 0x00, 0xC7, 0x3E, 0x01 ); } + + @Test + public void testRelativeJumpLabel() { + compile( + "ld A,01H\n" + + "jr z, EXAMPLE\n" + + "RST 00H\n" + + "EXAMPLE:\n" + + "halt" + ); + + assertProgram( + 0x3E, 0x01, 0x28, 0x03, 0xC7, 0x76 + ); + } + + @Test + public void testRelativeJumpCurrentAddress() { + compile("halt\njr $"); // infinite loop + assertProgram(0x76, 0x18, 0); + } + + @Test + public void testRelativeJumpExact() { + compile("halt\ndjnz $+0x20"); // if it is complex expression, treat it like exact value + assertProgram(0x76, 0x10, 0x21); + } } diff --git a/plugins/cpu/8080-cpu/build.gradle b/plugins/cpu/8080-cpu/build.gradle index dc3c22a3e..a7b2b28ec 100644 --- a/plugins/cpu/8080-cpu/build.gradle +++ b/plugins/cpu/8080-cpu/build.gradle @@ -28,7 +28,7 @@ buildscript { plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.4.0' + id 'net.emustudio.edigen-plugin' version '1.5.0' id 'com.adarshr.test-logger' version '3.1.0' } diff --git a/plugins/cpu/brainduck-cpu/build.gradle b/plugins/cpu/brainduck-cpu/build.gradle index 521f6e8ae..d7bd526fe 100644 --- a/plugins/cpu/brainduck-cpu/build.gradle +++ b/plugins/cpu/brainduck-cpu/build.gradle @@ -21,7 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.4.0' + id 'net.emustudio.edigen-plugin' version '1.5.0' id 'com.adarshr.test-logger' version '3.1.0' } diff --git a/plugins/cpu/ram-cpu/build.gradle b/plugins/cpu/ram-cpu/build.gradle index 4369bff65..7a4cc592f 100644 --- a/plugins/cpu/ram-cpu/build.gradle +++ b/plugins/cpu/ram-cpu/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'net.emustudio.edigen-plugin' version '1.5.0' id 'com.adarshr.test-logger' version '3.1.0' } diff --git a/plugins/cpu/rasp-cpu/build.gradle b/plugins/cpu/rasp-cpu/build.gradle index cd6827a5e..5fe925f79 100644 --- a/plugins/cpu/rasp-cpu/build.gradle +++ b/plugins/cpu/rasp-cpu/build.gradle @@ -21,6 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' + id 'net.emustudio.edigen-plugin' version '1.5.0' id 'com.adarshr.test-logger' version '3.1.0' } diff --git a/plugins/cpu/ssem-cpu/build.gradle b/plugins/cpu/ssem-cpu/build.gradle index be6d3ac3a..b7b56f773 100644 --- a/plugins/cpu/ssem-cpu/build.gradle +++ b/plugins/cpu/ssem-cpu/build.gradle @@ -28,7 +28,7 @@ buildscript { plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.4.0' + id 'net.emustudio.edigen-plugin' version '1.5.0' id 'com.adarshr.test-logger' version '3.1.0' } diff --git a/plugins/cpu/z80-cpu/build.gradle b/plugins/cpu/z80-cpu/build.gradle index a8e613939..b2e14ef0e 100644 --- a/plugins/cpu/z80-cpu/build.gradle +++ b/plugins/cpu/z80-cpu/build.gradle @@ -21,7 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.4.1' + id 'net.emustudio.edigen-plugin' version '1.5.0' id 'com.adarshr.test-logger' version '3.1.0' } @@ -53,7 +53,6 @@ jar { edigen { decoderName = 'net.emustudio.plugins.cpu.zilogZ80.gui.DecoderImpl' disassemblerName = 'net.emustudio.plugins.cpu.zilogZ80.gui.DisassemblerImpl' - //debug = true } processResources { diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index 6d80f9887..4aae65b5c 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -394,7 +394,6 @@ any2 = 00 | 01 | 10 | 11; "%s" = instruction rp; "%s" = instruction rp2; "%s" = instruction r; -"%s" = instruction r_no_hl; "%s" = instruction cc; "%s" = instruction im; "%s" = instruction rst; diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index dee8bb13d..9f08bc556 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -37,6 +37,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import static net.emustudio.plugins.cpu.zilogZ80.DispatchTables.*; +import static net.emustudio.plugins.cpu.zilogZ80.EmulatorTables.*; /** * Main implementation class for CPU emulation CPU works in a separate thread @@ -401,33 +402,6 @@ private void writeWord(int address, int value) { memory.write(address, new Byte[]{(byte) (value & 0xFF), (byte) ((value >>> 8) & 0xFF)}, 2); } - private int flagSZHPC(int a, int b, int flagC, int sum) { - // source: https://stackoverflow.com/questions/8034566/overflow-and-carry-flags-on-z80 - int carryOut; - if (flagC == FLAG_C) { - carryOut = (a >= 0xFF - b) ? FLAG_C : 0; - } else { - carryOut = (a > 0xFF - b) ? FLAG_C : 0; - } - - int carryIns = sum ^ a ^ b; - int halfCarryOut = (carryIns >> 4) & 1; - int overflowOut = (((carryIns >> 7) ^ carryOut) != 0) ? FLAG_PV : 0; - - return carryOut | (halfCarryOut << 4) | (overflowOut) | (sum == 0 ? FLAG_Z : 0) | (sum & 0x80); - } - - private int flagSZHP(int a, int b, int sum) { - // source: https://stackoverflow.com/questions/8034566/overflow-and-carry-flags-on-z80 - int carryOut = (a > 0xFF - b) ? FLAG_C : 0; - - int carryIns = sum ^ a ^ b; - int halfCarryOut = (carryIns >> 4) & 1; - int overflowOut = (((carryIns >> 7) ^ carryOut) != 0) ? FLAG_PV : 0; - - return (halfCarryOut << 4) | (overflowOut) | (sum == 0 ? FLAG_Z : 0) | (sum & 0x80); - } - private void bigOverflow(int i, int j, int result) { int sign = i & 0x8000; if (sign != (j & 0x8000)) { @@ -568,17 +542,21 @@ int I_LD_R_N() { int I_INC_R() { int reg = (lastOpcode >>> 3) & 0x07; - int value = (getreg(reg) + 1) & 0xFF; - flags = flagSZHP(getreg(reg), 1, value); - putreg(reg, value); + int regValue = getreg(reg); + int sum = (regValue + 1) & 0x1FF; + int sumByte = sum & 0xFF; + flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C); + putreg(reg, sumByte); return (reg == 6) ? 11 : 4; } int I_DEC_R() { int reg = (lastOpcode >>> 3) & 0x07; - int value = (getreg(reg) - 1) & 0xFF; - flags = flagSZHP(getreg(reg), ((~1) + 1) & 0xFF, value) | FLAG_N; - putreg(reg, value); + int regValue = getreg(reg); + int sum = (regValue - 1) & 0x1FF; + int sumByte = sum & 0xFF; + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C); + putreg(reg, sumByte); return (reg == 6) ? 11 : 4; } @@ -602,42 +580,40 @@ int I_RST() { int I_ADD_A_R() { int value = getreg(lastOpcode & 0x07); int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, 0, regs[REG_A]); + int sum = (oldA + value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); return (lastOpcode == 0x86) ? 7 : 4; } int I_ADC_A_R() { int value = getreg(lastOpcode & 0x07); int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, value, (flags & FLAG_C), regs[REG_A]); + int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); return (lastOpcode == 0x8E) ? 7 : 4; } int I_SUB_R() { - int value = ((~getreg(lastOpcode & 0x07)) + 1) & 0xFF; + int value = getreg(lastOpcode & 0x07); + int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, 0, regs[REG_A]) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + int sum = (oldA - value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + + flags = TABLE_SUB[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); return (lastOpcode == 0x96) ? 7 : 4; } int I_SBC_A_R() { - int value = ((~getreg(lastOpcode & 0x07)) + 1) & 0xFF; + int value = getreg(lastOpcode & 0x07); + int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value - (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, value, ((flags & FLAG_C) == FLAG_C) ? 0 : FLAG_C, regs[REG_A]) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + int sum = (oldA - value - (flags&FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; return (lastOpcode == 0x9E) ? 7 : 4; } @@ -660,14 +636,11 @@ int I_OR_R() { } int I_CP_R() { - int value = ((~getreg(lastOpcode & 7)) + 1) & 0xFF; - int result = (regs[REG_A] + value) & 0xFF; - flags = flagSZHPC(regs[REG_A], value, 0, result) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + int value = getreg(lastOpcode & 7); + int oldA = regs[REG_A]; + int sum = (oldA - value) & 0x1FF; + int result = sum & 0xFF; + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]); return (lastOpcode == 0xBE) ? 7 : 4; } @@ -705,7 +678,8 @@ int I_DJNZ() { regs[REG_B]--; regs[REG_B] &= 0xFF; if (regs[REG_B] != 0) { - PC = (PC + tmp) & 0xFFFF; + PC = (PC - 2) + tmp; + PC &= 0xFFFF; return 13; } return 8; @@ -774,7 +748,7 @@ int I_DAA() { flags |= EmulatorTables.DAA_NOT_N_H_FOR_H_TABLE[temp]; } } - flags |= EmulatorTables.PARITY_TABLE[regs[REG_A]] | EmulatorTables.SIGN_ZERO_TABLE[regs[REG_A]]; + flags |= EmulatorTables.PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]]; return 4; } @@ -873,7 +847,7 @@ int I_EI() { int I_IN_R_REF_C() throws IOException { int tmp = (lastOpcode >>> 3) & 0x7; putreg(tmp, context.readIO(regs[REG_C])); - flags = (flags & FLAG_C) | EmulatorTables.SIGN_ZERO_TABLE[regs[tmp]] | EmulatorTables.PARITY_TABLE[regs[tmp]]; + flags = (flags & FLAG_C) | TABLE_SZ[regs[tmp]] | EmulatorTables.PARITY_TABLE[regs[tmp]]; return 12; } @@ -943,8 +917,13 @@ int I_ADC_HL_RP() { } int I_NEG() { - flags = EmulatorTables.NEG_TABLE[regs[REG_A]] & 0xFF; - regs[REG_A] = (EmulatorTables.NEG_TABLE[regs[REG_A]] >>> 8) & 0xFF; + int prevValue = regs[REG_A]; + regs[REG_A] = (((~prevValue) & 0xFF) + 1) & 0xFF; + int zero = (regs[REG_A] == 0) ? FLAG_Z : 0; + int carry = (prevValue == 0) ? 0 : FLAG_C; + int carryIns = regs[REG_A] ^ prevValue; + int overflow = (prevValue == 0x80) ? FLAG_PV : 0; + flags = overflow | (regs[REG_A] & 0x80) | zero | (carryIns & 0x10) | FLAG_N | carry; return 8; } @@ -984,7 +963,7 @@ int I_IM_1() { int I_LD_A_I() { regs[REG_A] = I & 0xFF; - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C); + flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C); return 9; } @@ -995,7 +974,7 @@ int I_IM_2() { int I_LD_A_R() { regs[REG_A] = R & 0xFF; - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C); + flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C); return 9; } @@ -1005,7 +984,7 @@ int I_RRD() { regs[REG_A] = ((regs[REG_A] & 0xF0) | (tmp1 & 0x0F)); tmp1 = ((tmp1 >>> 4) & 0x0F) | (tmp << 4); memory.write(((regs[REG_H] << 8) | regs[REG_L]), (byte) (tmp1 & 0xff)); - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_A]] | EmulatorTables.PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); + flags = TABLE_SZ[regs[REG_A]] | EmulatorTables.PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); return 18; } @@ -1015,13 +994,13 @@ int I_RLD() { tmp = ((tmp << 4) & 0xF0) | (regs[REG_A] & 0x0F); regs[REG_A] = ((regs[REG_A] & 0xF0) | tmp1); memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) (tmp & 0xff)); - flags = EmulatorTables.SIGN_ZERO_TABLE[regs[REG_A]] | EmulatorTables.PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); + flags = TABLE_SZ[regs[REG_A]] | EmulatorTables.PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); return 18; } int I_IN_REF_C() throws IOException { int tmp = (context.readIO(regs[REG_C]) & 0xFF); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp] | EmulatorTables.PARITY_TABLE[tmp] | (flags & FLAG_C); + flags = TABLE_SZ[tmp] | EmulatorTables.PARITY_TABLE[tmp] | (flags & FLAG_C); return 12; } @@ -1062,7 +1041,7 @@ int I_CPI() { tmp1 = (tmp1 + 1) & 0xFFFF; tmp2 = (tmp2 - 1) & 0xFFFF; - flags = EmulatorTables.SIGN_ZERO_TABLE[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); + flags = TABLE_SZ[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); auxCarry(regs[REG_A], (-tmp) & 0xFF); if (tmp2 != 0) { @@ -1108,7 +1087,7 @@ int I_CPD() { tmp1 = (tmp1 - 1) & 0xFFFF; tmp2 = (tmp2 - 1) & 0xFFFF; - flags = EmulatorTables.SIGN_ZERO_TABLE[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); + flags = TABLE_SZ[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); auxCarry(regs[REG_A], (-tmp) & 0xFF); if (tmp2 != 0) { @@ -1157,7 +1136,7 @@ int I_CPIR() { tmp1 = (tmp1 + 1) & 0xFFFF; tmp2 = (tmp2 - 1) & 0xFFFF; - flags = EmulatorTables.SIGN_ZERO_TABLE[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); + flags = TABLE_SZ[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); auxCarry(regs[REG_A], (-tmp) & 0xFF); if (tmp2 != 0) { @@ -1343,7 +1322,7 @@ int I_CPDR() { hl = (hl - 1) & 0xFFFF; bc = (bc - 1) & 0xFFFF; - flags = EmulatorTables.SIGN_ZERO_TABLE[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); + flags = TABLE_SZ[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); auxCarry(regs[REG_A], (-tmp) & 0xFF); if (bc != 0) { @@ -1385,7 +1364,7 @@ int I_JR_CC_N() { PC = (PC + 1) & 0xFFFF; if (getCC1((lastOpcode >>> 3) & 3)) { - PC += (byte) tmp; + PC = (PC - 2) + (byte) tmp; PC &= 0xFFFF; return 12; } @@ -1396,7 +1375,7 @@ int I_JR_N() { int tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - PC += (byte) tmp; + PC = (PC - 2) + (byte) tmp; PC &= 0xFFFF; return 12; } @@ -1405,8 +1384,9 @@ int I_ADD_A_N() { int value = readByte(PC); PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, 0, regs[REG_A]); + int sum = (oldA + value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); return 7; } @@ -1414,8 +1394,9 @@ int I_ADC_A_N() { int value = readByte(PC); PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, value, flags & FLAG_C, regs[REG_A]); + int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); return 7; } @@ -1427,16 +1408,14 @@ int I_OUT_REF_N_A() throws IOException { } int I_SUB_N() { - int value = ((~memory.read(PC)) + 1) & 0xFF; + int value = readByte(PC); PC = (PC + 1) & 0xFFFF; + int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, 0, regs[REG_A]) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + int sum = (oldA - value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; return 7; } @@ -1448,16 +1427,14 @@ int I_IN_A_REF_N() throws IOException { } int I_SBC_A_N() { - int value = ((~readByte(PC)) + 1) & 0xFF; + int value = readByte(PC); PC = (PC + 1) & 0xFFFF; + int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value - (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, value, (flags & FLAG_C) == FLAG_C ? 0 : FLAG_C, regs[REG_A]) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; return 7; } @@ -1489,15 +1466,13 @@ int I_OR_N() { } int I_CP_N() { - int value = ((~readByte(PC)) + 1) & 0xFF; + int value = readByte(PC); PC = (PC + 1) & 0xFFFF; - int diff = (regs[REG_A] + value) & 0xFF; - flags = flagSZHPC(regs[REG_A], value, 0, diff) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + + int oldA = regs[REG_A]; + int sum = (oldA - value) & 0x1FF; + int result = sum & 0xFF; + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]); return 7; } @@ -1606,7 +1581,7 @@ int I_RLC_R() { tmp1 = (((tmp1 << 1) & 0xFF) | tmp2) & 0xFF; putreg(tmp, tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; if (tmp == 6) { return 15; @@ -1623,7 +1598,7 @@ int I_RRC_R() { tmp1 = (((tmp1 >>> 1) & 0x7F) | (tmp2 << 7)) & 0xFF; putreg(tmp, tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; if (tmp == 6) { return 15; @@ -1640,7 +1615,7 @@ int I_RL_R() { tmp1 = ((((tmp1 << 1) & 0xFF) | flags & FLAG_C) & 0xFF); putreg(tmp, tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; if (tmp == 6) { return 15; @@ -1657,7 +1632,7 @@ int I_RR_R() { tmp1 = ((((tmp1 >> 1) & 0x7F) | (flags & FLAG_C) << 7) & 0xFF); putreg(tmp, tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; if (tmp == 6) { return 15; @@ -1674,7 +1649,7 @@ int I_SLA_R() { tmp1 = (tmp1 << 1) & 0xFE; putreg(tmp, tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; if (tmp == 6) { return 15; @@ -1691,7 +1666,7 @@ int I_SRA_R() { tmp1 = (tmp1 >> 1) & 0xFF | (tmp1 & 0x80); putreg(tmp, tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; if (tmp == 6) { return 15; @@ -1708,7 +1683,7 @@ int I_SLL_R() { tmp1 = (tmp1 << 1) & 0xFF | tmp1 & 1; putreg(tmp, tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; if (tmp == 6) { return 15; @@ -1725,7 +1700,7 @@ int I_SRL_R() { tmp1 = (tmp1 >>> 1) & 0x7F; putreg(tmp, tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; if (tmp == 6) { return 15; @@ -1888,9 +1863,12 @@ int I_INC_REF_II_N(int special) { PC = (PC + 1) & 0xFFFF; int address = (special + disp) & 0xFFFF; int value = readByte(address); - int result = (value + 1) & 0xFF; - memory.write(address, (byte) result); - flags = flagSZHP(value, 1, result); + + int sum = (value + 1) & 0x1FF; + int sumByte = sum & 0xFF; + flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C); + + memory.write(address, (byte) sumByte); return 23; } @@ -1907,9 +1885,12 @@ int I_DEC_REF_II_N(int special) { PC = (PC + 1) & 0xFFFF; int address = (special + (byte) disp) & 0xFFFF; int value = readByte(address); - int result = (value - 1) & 0xFF; - memory.write(address, (byte) result); - flags = flagSZHP(value, ((~1) + 1) & 0xFF, result) | FLAG_N; + + int sum = (value - 1) & 0x1FF; + int sumByte = sum & 0xFF; + + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C); + memory.write(address, (byte) sumByte); return 23; } @@ -1973,9 +1954,11 @@ int I_ADD_A_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; int value = readByte((special + offset) & 0xFFFF); + int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, 0, regs[REG_A]); + int sum = (oldA + value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); return 19; } @@ -1991,9 +1974,11 @@ int I_ADC_A_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; int value = readByte((special + offset) & 0xFFFF); + int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, value, flags & FLAG_C, regs[REG_A]); + int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); return 19; } @@ -2008,15 +1993,13 @@ int I_SUB_REF_IY_N() { int I_SUB_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; + int value = readByte((special + offset) & 0xFFFF); + int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, 0, regs[REG_A]) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + int sum = (oldA - value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; return 19; } @@ -2031,15 +2014,13 @@ int I_SBC_A_REF_IY_N() { int I_SBC_A_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; + int value = readByte((special + offset) & 0xFFFF); + int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value - (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, value, ((flags & FLAG_C) == FLAG_C) ? 0 : FLAG_C, regs[REG_A]) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + int sum = (oldA - value - (flags&FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; return 19; } @@ -2107,14 +2088,12 @@ int I_CP_REF_IY_N() { int I_CP_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = ((~readByte((special + offset) & 0xFFFF)) + 1) & 0xFF; - int diff = (regs[REG_A] + value) & 0xFF; - flags = flagSZHPC(regs[REG_A], value, 0, diff) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + int value = readByte((special + offset) & 0xFFFF); + + int oldA = regs[REG_A]; + int sum = (oldA + value) & 0x1FF; + int result = sum & 0xFF; + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]); return 19; } @@ -2193,7 +2172,7 @@ int I_RLC_REF_II_N_R(byte operand, int special) { value = (((value << 1) | bit7) & 0xFF); memory.write(address, (byte) value); - flags = EmulatorTables.SIGN_ZERO_TABLE[value] | EmulatorTables.PARITY_TABLE[value] | bit7; + flags = TABLE_SZ[value] | EmulatorTables.PARITY_TABLE[value] | bit7; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = value & 0xFF; @@ -2216,7 +2195,7 @@ int I_RRC_REF_II_N_R(byte operand, int special) { tmp1 = (((tmp1 >>> 1) & 0x7F) | (tmp2 << 7)) & 0xFF; memory.write(tmp, (byte) (tmp1 & 0xFF)); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = tmp1 & 0xFF; @@ -2239,7 +2218,7 @@ int I_RL_REF_II_N_R(byte operand, int special) { tmp1 = ((((tmp1 << 1) & 0xFF) | flags & FLAG_C) & 0xFF); memory.write(tmp, (byte) (tmp1 & 0xFF)); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; @@ -2261,7 +2240,7 @@ int I_RR_REF_II_N_R(byte operand, int special) { value = ((((value >> 1) & 0xFF) | (flags & FLAG_C) << 7) & 0xFF); memory.write(address, (byte) (value & 0xFF)); - flags = EmulatorTables.SIGN_ZERO_TABLE[value] | EmulatorTables.PARITY_TABLE[value] | bit0; + flags = TABLE_SZ[value] | EmulatorTables.PARITY_TABLE[value] | bit0; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = value & 0xFF; return 23; @@ -2283,7 +2262,7 @@ int I_SLA_REF_II_N_R(byte operand, int special) { tmp1 = (tmp1 << 1) & 0xFE; memory.write(tmp, (byte) tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; @@ -2305,7 +2284,7 @@ int I_SRA_REF_II_N_R(byte operand, int special) { tmp1 = (tmp1 >> 1) & 0xFF | (tmp1 & 0x80); memory.write(tmp, (byte) tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; @@ -2327,7 +2306,7 @@ int I_SLL_REF_II_N_R(byte operand, int special) { tmp1 = (tmp1 << 1) & 0xFF | tmp1 & 1; memory.write(tmp, (byte) tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; @@ -2349,7 +2328,7 @@ int I_SRL_REF_II_N_R(byte operand, int special) { tmp1 = (tmp1 >>> 1) & 0x7F; memory.write(tmp, (byte) tmp1); - flags = EmulatorTables.SIGN_ZERO_TABLE[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = tmp1 & 0xFF; return 23; @@ -2433,9 +2412,10 @@ int I_INC_IYL() { } int I_INC(int value) { - int result = (value + 1) & 0xFF; - flags = flagSZHP(value, 1, result); - return result; + int sum = (value + 1) & 0x1FF; + int sumByte = sum & 0xFF; + flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C); + return sumByte; } int I_DEC_IXH() { @@ -2450,9 +2430,10 @@ int I_DEC_IYH() { int I_DEC_IIH(int special) { int reg = special >>> 8; - int value = (reg - 1) & 0xFF; - flags = flagSZHP(reg, ((~1) + 1) & 0xFF, value) | FLAG_N; - return value; + int sum = (reg - 1) & 0x1FF; + int sumByte = sum & 0xFF; + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C); + return sumByte; } int I_DEC_IXL() { @@ -2467,9 +2448,10 @@ int I_DEC_IYL() { int I_DEC_IIL(int special) { int reg = special & 0xFF; - int value = (reg - 1) & 0xFF; - flags = flagSZHP(reg, ((~1) + 1) & 0xFF, value) | FLAG_N; - return value; + int sum = (reg - 1) & 0x1FF; + int sumByte = sum & 0xFF; + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C); + return sumByte; } int I_LD_IXH_N() { @@ -2594,8 +2576,9 @@ int I_ADD_A_IYL() { int I_ADD_A(int value) { int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value) & 0xFF; - flags = flagSZHPC(oldA, value, 0, regs[REG_A]); + int sum = (oldA + value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); return 8; } @@ -2617,8 +2600,9 @@ int I_ADC_A_IYL() { int I_ADC_A(int value) { int oldA = regs[REG_A]; - regs[REG_A] = (oldA + value + (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, value, flags & FLAG_C, regs[REG_A]); + int sum = (oldA + value + (flags&FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); return 8; } @@ -2639,15 +2623,11 @@ int I_SUB_IYL() { } int I_SUB(int value) { - int valueNeg = ((~value) + 1) & 0xFF; int oldA = regs[REG_A]; - regs[REG_A] = (oldA + valueNeg) & 0xFF; - flags = flagSZHPC(oldA, valueNeg, 0, regs[REG_A]) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + int sum = (oldA - value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; return 8; } @@ -2668,15 +2648,10 @@ int I_SBC_A_IYL() { } int I_SBC_A(int value) { - int valueNeg = ((~value) + 1) & 0xFF; int oldA = regs[REG_A]; - regs[REG_A] = (oldA + valueNeg - (flags & FLAG_C)) & 0xFF; - flags = flagSZHPC(oldA, valueNeg, ((flags & FLAG_C) == FLAG_C) ? 0 : FLAG_C, regs[REG_A]) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + int sum = (oldA - value - (flags&FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; return 8; } @@ -2763,14 +2738,10 @@ int I_CP_IYL() { } int I_CP(int value) { - int valueNeg = ((~value) + 1) & 0xFF; - int result = (regs[REG_A] + valueNeg) & 0xFF; - flags = flagSZHPC(regs[REG_A], valueNeg, 0, result) | FLAG_N; - if ((flags & FLAG_C) == FLAG_C) { - flags &= 0xFE; - } else { - flags |= FLAG_C; - } + int oldA = regs[REG_A]; + int sum = (oldA - value) & 0x1FF; + int result = sum & 0xFF; + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]); return 8; } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java index ce9caefd2..e77e4e375 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java @@ -20,17 +20,111 @@ class EmulatorTables { - final static short[] SIGN_ZERO_TABLE = new short[]{ - 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128 + public final static int[] TABLE_SUB = new int[] { + 0x42, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82 + }; + + public final static int[] TABLE_CHP = new int[] { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, + 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, + 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, + 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 + }; + + public final static int[] TABLE_HP = new int[] { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + }; + + public final static int[] TABLE_SZ = new int[] { + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; final static short[] PARITY_TABLE = { @@ -151,21 +245,6 @@ class EmulatorTables { 148, 144, 148, 144, 144, 148, 148, 144, 144, 148, 144, 148, 148, 144, 144, 148, 148, 144, 148, 144, 144, 148, 148, 144, 144, 148, 144, 148, 148, 144, 148, 144, 144, 148, 144, 148, 148, 144, 144, 148, 148, 144, 148, 144, 144, 148,}; - static final int[] NEG_TABLE = { - 66, 65411, 65155, 64899, 64643, 64387, 64131, 63875, 63619, 63363, 63107, 62851, 62595, 62339, 62083, 61827, 61571, 61315, 61059, 60803, 60547, 60291, - 60035, 59779, 59523, 59267, 59011, 58755, 58499, 58243, 57987, 57731, 57475, 57219, 56963, 56707, 56451, 56195, 55939, 55683, 55427, 55171, 54915, - 54659, 54403, 54147, 53891, 53635, 53379, 53123, 52867, 52611, 52355, 52099, 51843, 51587, 51331, 51075, 50819, 50563, 50307, 50051, 49795, 49539, - 49283, 49027, 48771, 48515, 48259, 48003, 47747, 47491, 47235, 46979, 46723, 46467, 46211, 45955, 45699, 45443, 45187, 44931, 44675, 44419, 44163, - 43907, 43651, 43395, 43139, 42883, 42627, 42371, 42115, 41859, 41603, 41347, 41091, 40835, 40579, 40323, 40067, 39811, 39555, 39299, 39043, 38787, - 38531, 38275, 38019, 37763, 37507, 37251, 36995, 36739, 36483, 36227, 35971, 35715, 35459, 35203, 34947, 34691, 34435, 34179, 33923, 33667, 33411, - 33155, 32903, 32515, 32259, 32003, 31747, 31491, 31235, 30979, 30723, 30467, 30211, 29955, 29699, 29443, 29187, 28931, 28675, 28419, 28163, 27907, - 27651, 27395, 27139, 26883, 26627, 26371, 26115, 25859, 25603, 25347, 25091, 24835, 24579, 24323, 24067, 23811, 23555, 23299, 23043, 22787, 22531, - 22275, 22019, 21763, 21507, 21251, 20995, 20739, 20483, 20227, 19971, 19715, 19459, 19203, 18947, 18691, 18435, 18179, 17923, 17667, 17411, 17155, - 16899, 16643, 16387, 16131, 15875, 15619, 15363, 15107, 14851, 14595, 14339, 14083, 13827, 13571, 13315, 13059, 12803, 12547, 12291, 12035, 11779, - 11523, 11267, 11011, 10755, 10499, 10243, 9987, 9731, 9475, 9219, 8963, 8707, 8451, 8195, 7939, 7683, 7427, 7171, 6915, 6659, 6403, 6147, 5891, - 5635, 5379, 5123, 4867, 4611, 4355, 4099, 3843, 3587, 3331, 3075, 2819, 2563, 2307, 2051, 1795, 1539, 1283, 1027, 771, 515, 259 - }; - // rrcaTable[i] = ((i & 1) << 7)|(i>>1); final static short[] RRCA_TABLE = { 0, 128, 1, 129, 2, 130, 3, 131, 4, 132, 5, 133, 6, 134, 7, 135, 8, 136, 9, 137, 10, 138, 11, 139, 12, 140, 13, 141, 14, 142, 15, 143, 16, 144, 17, 145, 18, 146, 19, 147, 20, 148, 21, 149, 22, 150, diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java index 6a95e4adb..6d8ccd811 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java @@ -126,7 +126,8 @@ public void testSBC_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> ((context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrow().overflowSub().subtractionIsSet()) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( @@ -148,7 +149,8 @@ public void testSBC_A_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrow().overflowSub().subtractionIsSet()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); Generator.forSome8bitBinary( test.runWithSecondOperand(0xDE) @@ -158,7 +160,10 @@ public void testSBC_A_N() { @Test public void testINC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyFlags(new FlagsCheckImpl().sign().zero().overflow().halfCarry().subtractionIsReset(), + .verifyFlags(new FlagsCheckImpl() + .sign().zero().overflow().halfCarry() + .subtractionIsReset() + .carryIsPreserved(), context -> context.first + 1) .keepCurrentInjectorsAfterRun() .clearOtherVerifiersAfterRun(); @@ -180,7 +185,9 @@ public void testDEC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .verifyFlags(new FlagsCheckImpl() .setSecond(c -> 1) - .sign().zero().overflowSub().halfBorrow().subtractionIsSet(), + .sign().zero().overflowSub().halfBorrow() + .subtractionIsSet() + .carryIsPreserved(), context -> context.first - 1) .keepCurrentInjectorsAfterRun() .clearOtherVerifiersAfterRun(); @@ -300,7 +307,8 @@ public void testSBC_A_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet()) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().borrow().halfBorrow().overflowSubCarry().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -339,7 +347,7 @@ public void testINC_REF_II_N() { .verifyFlagsOfLastOp(new FlagsCheckImpl() .switchFirstAndSecond() .setSecond(c -> 1) - .sign().zero().halfCarry().overflow().subtractionIsReset() + .sign().zero().halfCarry().overflow().subtractionIsReset().carryIsPreserved() ) .keepCurrentInjectorsAfterRun(); @@ -357,7 +365,9 @@ public void testDEC_REF_II_N() { .verifyFlagsOfLastOp(new FlagsCheckImpl() .switchFirstAndSecond() .setSecond(c -> 1) - .sign().zero().halfBorrow().overflowSub().subtractionIsSet() + .sign().zero().halfBorrow().overflowSub() + .subtractionIsSet() + .carryIsPreserved() ) .keepCurrentInjectorsAfterRun(); @@ -456,7 +466,7 @@ public void testINC_IXH() { .firstIsIX() .verifyFlags(new FlagsCheckImpl().sign().zero() .setFirst8MSB() - .overflow().halfCarry().subtractionIsReset(), + .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), context -> ((context.first >>> 8) + 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); @@ -471,7 +481,7 @@ public void testINC_IYH() { .firstIsIY() .verifyFlags(new FlagsCheckImpl().sign().zero() .setFirst8MSB() - .overflow().halfCarry().subtractionIsReset(), + .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), context -> ((context.first >>> 8) + 1) & 0xFF) .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); @@ -486,8 +496,10 @@ public void testDEC_IXH() { .firstIsIX() .verifyFlags(new FlagsCheckImpl().sign().zero() .setFirst8MSB() - .setSecond(c -> -1) - .overflow().halfCarry().subtractionIsSet(), + .setSecond(c -> 1) + .overflowSub().halfBorrow() + .subtractionIsSet() + .carryIsPreserved(), context -> ((context.first >>> 8) - 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); @@ -504,7 +516,9 @@ public void testDEC_IYH() { .setFirst8MSB() .sign().zero() .setSecond(c -> 1) - .overflow().halfBorrow().subtractionIsSet(), + .overflowSub().halfBorrow() + .subtractionIsSet() + .carryIsPreserved(), context -> ((context.first >>> 8) - 1) & 0xFF) .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); @@ -520,7 +534,7 @@ public void testINC_IXL() { .verifyFlags(new FlagsCheckImpl().sign().zero() .setFirst8LSB() .setSecond(c -> 1) - .overflow().halfCarry().subtractionIsReset(), + .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), context -> ((context.first & 0xFF) + 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) + 1) & 0xFF)); @@ -551,8 +565,10 @@ public void testDEC_IXL() { .firstIsIX() .verifyFlags(new FlagsCheckImpl().sign().zero() .setFirst8LSB() - .setSecond(c -> -1) - .overflow().halfCarry().subtractionIsSet(), + .setSecond(c -> 1) + .overflowSub().halfBorrow() + .subtractionIsSet() + .carryIsPreserved(), context -> ((context.first & 0xFF) - 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); @@ -569,7 +585,9 @@ public void testDEC_IYL() { .setFirst8LSB() .setSecond(c -> 1) .sign().zero() - .overflowSub().halfBorrow().subtractionIsSet(), + .overflowSub().halfBorrow() + .subtractionIsSet() + .carryIsPreserved(), context -> ((context.first & 0xFF) - 1) & 0xFF) .verifyIY(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); @@ -786,7 +804,7 @@ public void testSBC_A_IXH() { .sign().zero() .borrowWithCarry() .halfBorrow() - .overflowSub().subtractionIsSet()); + .overflowSubCarry().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xDD, 0x9C) @@ -804,7 +822,7 @@ public void testSBC_A_IYH() { .sign().zero() .borrowWithCarry() .halfBorrow() - .overflowSub().subtractionIsSet()); + .overflowSubCarry().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xFD, 0x9C) @@ -820,7 +838,7 @@ public void testSBC_A_IXL() { .verifyFlagsOfLastOp(new FlagsCheckImpl() .setFirst8LSB() .setSecond8LSB() - .sign().zero().borrowWithCarry().halfBorrow().overflowSub().subtractionIsSet()); + .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xDD, 0x9D) @@ -833,7 +851,8 @@ public void testSBC_A_IYL() { .first8LSBisRegister(REG_A) .secondIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrowWithCarry().halfBorrow().overflowSub().subtractionIsSet()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); Generator.forSome16bitBinary( test.run(0xFD, 0x9D) @@ -854,7 +873,8 @@ private ByteTestBuilder subtractionTestBuilder() { .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().borrow().halfBorrow() + .sign().zero().borrow() + .halfBorrow() .overflowSub().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java index 00131f451..e35b76b5f 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java @@ -278,7 +278,7 @@ public void testIM__2() { public void testJR__e__AND__JR__cc() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .expandMemory(first -> cpuRunnerImpl.getPC() + first.intValue()) - .verifyPC(context -> (2 + context.PC + context.first) & 0xFFFF) + .verifyPC(context -> (context.PC + context.first) & 0xFFFF) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( @@ -334,9 +334,9 @@ public void testDJNZ__e() { .expandMemory(first -> cpuRunnerImpl.getPC() + first.intValue()) .verifyPC(context -> { if (((context.second - 1) & 0xFF) == 0) { - return context.PC + 2; + return context.PC; } - return (context.PC + 2 + context.first) & 0xFFFF; + return (context.PC + context.first) & 0xFFFF; }) .verifyRegister(REG_B, context -> (context.second - 1) & 0xFF); diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java new file mode 100644 index 000000000..48409e535 --- /dev/null +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java @@ -0,0 +1,91 @@ +package net.emustudio.plugins.cpu.zilogZ80; + +import org.junit.Ignore; +import org.junit.Test; + +import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.*; + +@Ignore +public class EmulatorTablesGeneration { + + @Test + public void generateTableSub() { + StringBuilder table = new StringBuilder("public final static int[] TABLE_SUB = new int[] {\n "); + + // public static final int FLAG_S = 0x80, FLAG_Z = 0x40, FLAG_H = 0x10, FLAG_PV = 0x4, FLAG_N = 0x02, FLAG_C = 0x1; + // 0xA8 - preserve: sign, overflow + // 10101000 + + for (int sum = 0; sum < 256; sum++) { + int flagZ = (sum == 0 ? FLAG_Z : 0); + int flags = flagZ | (sum & 0x80) | FLAG_N; + table.append("0x") + .append(Integer.toHexString(flags)) + .append(", "); + } + table.append("};\n"); + System.out.println(table); + } + + @Test + public void generateTableCHP() { + StringBuilder table = new StringBuilder("public final static int[] TABLE_CHP = new int[] {\n "); + + for (int cbits = 0; cbits <= 0x1FF; cbits++) { + int flagC = (cbits & 0x100) == 0x100 ? FLAG_C : 0; + int flagH = cbits & FLAG_H; + int carryIns = ((cbits & 0xFF) >>> 7) ^ flagC; + int flagP = (carryIns == 0) ? 0 : FLAG_PV; + int flags = flagC | flagH | flagP; + table.append("0x") + .append(Integer.toHexString(flags)) + .append(", "); + } + table.append("};\n"); + System.out.println(table); + } + + @Test + public void generateTableSZ() { + StringBuilder table = new StringBuilder("public final static int[] TABLE_SZ = new int[] {\n "); + + int i = 0; + for (int sum = 0; sum < 256; sum++) { + int flagZ = (sum == 0 ? FLAG_Z : 0); + int flags = flagZ | (sum & 0x80); + table.append("0x") + .append(Integer.toHexString(flags)) + .append(", "); + if (i++ == 15) { + table.append("\n "); + i = 0; + } + } + table.append("};\n"); + System.out.println(table); + } + + @Test + public void generateTableHP() { + StringBuilder table = new StringBuilder("public final static int[] TABLE_HP = new int[] {\n "); + + int i = 0; + for (int cbits = 0; cbits <= 0x1FF; cbits++) { + int flagC = (cbits & 0x100) == 0x100 ? FLAG_C : 0; + int flagH = cbits & FLAG_H; + int carryIns = ((cbits & 0xFF) >>> 7) ^ flagC; + int flagP = (carryIns == 0) ? 0 : FLAG_PV; + int flags = flagH | flagP; + table.append("0x") + .append(Integer.toHexString(flags)) + .append(", "); + if (i++ == 15) { + table.append("\n "); + i = 0; + } + } + table.append("};\n"); + System.out.println(table); + } + +} diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java index bd345ea66..66f2ed95e 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java @@ -382,10 +382,10 @@ public void testNEG() { .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (-context.first) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().sign().zero() - .borrow() + .sign().zero() + .expectFlagOnlyWhen(FLAG_C, (c, result) -> c.first != 0) + .expectFlagOnlyWhen(FLAG_PV, (c, result) -> (c.first & 0xff) == 0x80) .halfBorrow() - .overflowSub() .subtractionIsSet() ) .keepCurrentInjectorsAfterRun(); diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java index a442511b2..c1cf0e562 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java @@ -134,11 +134,31 @@ public FlagsCheckImpl overflow() { } public FlagsCheckImpl overflowSub() { + evaluators.add((context, result) -> { + int fst = first.apply(context) & 0xFF; + int snd = second.apply(context) & 0xFF; + + int sum = (fst - snd) & 0x1FF; + int flagC = (sum & 0x100) == 0x100 ? FLAG_C : 0; + int carryIns = (result & 0xFF) ^ fst ^ snd; + carryIns = (carryIns >>> 7) ^ flagC; + int flagP = (carryIns == 0) ? 0 : FLAG_PV; + + if (flagP == FLAG_PV) { + expectedFlags |= FLAG_PV; + } else { + expectedNotFlags |= FLAG_PV; + } + }); + return this; + } + + public FlagsCheckImpl overflowSubCarry() { evaluators.add((context, result) -> { int firstInt = first.apply(context) & 0xFF; - int secondInt = ((~(second.apply(context) & 0xFF)) + 1) & 0xFF; + int inversedSecond = (~second.apply(context) & 0xFF); - int carryIns = ((firstInt ^ secondInt) ^ 0x80) & 0x80; + int carryIns = ((firstInt ^ inversedSecond) ^ 0x80) & 0x80; if (carryIns != 0) { // if addend signs are the same // overflow if the sum sign differs from the sign of either of addends carryIns = ((result ^ firstInt) & 0x80); @@ -201,13 +221,16 @@ public FlagsCheckImpl carry() { public FlagsCheckImpl borrow() { evaluators.add((context, result) -> { - int inversedSecond = ((~second.apply(context)) + 1) & 0xFF; - int sum = (context.first.intValue() & 0xFF) + inversedSecond; + int fst = first.apply(context) & 0xFF; + int snd = second.apply(context) & 0xFF; - if ((sum & 0x100) == 0x100) { - expectedNotFlags |= FLAG_C; // reversed flag C expectations on substraction - } else { + int r = (fst - snd) & 0x1FF; + int flagC = (r & 0x100) == 0x100 ? FLAG_C : 0; + + if (flagC != 0) { expectedFlags |= FLAG_C; + } else { + expectedNotFlags |= FLAG_C; } }); return this; @@ -215,13 +238,15 @@ public FlagsCheckImpl borrow() { public FlagsCheckImpl borrowWithCarry() { evaluators.add((context, result) -> { - int inversedCarry = (context.flags & FLAG_C) == FLAG_C ? 0 : FLAG_C; - int inversedSecond = ((~second.apply(context)) + 1) & 0xFF; - int sum = (context.first.intValue() & 0xFF) + inversedSecond + inversedCarry; - if ((sum & 0x100) == 0x100) { - expectedNotFlags |= FLAG_C; - } else { + int fst = first.apply(context) & 0xFF; + int snd = second.apply(context) & 0xFF; + + int r = (fst - snd - (context.flags & FLAG_C)) & 0x1FF; + int flagC = (r & 0x100) == 0x100 ? FLAG_C : 0; + if (flagC != 0) { expectedFlags |= FLAG_C; + } else { + expectedNotFlags |= FLAG_C; } }); return this; @@ -229,7 +254,7 @@ public FlagsCheckImpl borrowWithCarry() { public FlagsCheckImpl carryIsFirstOperandMSB() { evaluators.add((context, result) -> { - if ((context.first.intValue() & 0x80) == 0x80) { + if ((first.apply(context) & 0x80) == 0x80) { expectedFlags |= FLAG_C; } else { expectedNotFlags |= FLAG_C; @@ -240,7 +265,7 @@ public FlagsCheckImpl carryIsFirstOperandMSB() { public FlagsCheckImpl carryIsFirstOperandLSB() { evaluators.add((context, result) -> { - if ((context.first.intValue() & 1) == 1) { + if ((first.apply(context) & 1) == 1) { expectedFlags |= FLAG_C; } else { expectedNotFlags |= FLAG_C; @@ -254,28 +279,21 @@ public FlagsCheckImpl carryIsReset() { return this; } - public FlagsCheckImpl halfCarry() { + public FlagsCheckImpl carryIsPreserved() { evaluators.add((context, result) -> { - int carryIns = result ^ (first.apply(context) & 0xFF) ^ (second.apply(context) & 0xFF); - int halfCarryOut = (carryIns >> 4) & 1; - - if (halfCarryOut == 1) { - expectedFlags |= FLAG_H; + if ((context.flags & FLAG_C) == FLAG_C) { + expectedFlags |= FLAG_C; } else { - expectedNotFlags |= FLAG_H; + expectedNotFlags |= FLAG_C; } }); return this; } - public FlagsCheckImpl halfBorrow() { + public FlagsCheckImpl halfCarry() { evaluators.add((context, result) -> { - int inversedSecond = ((~second.apply(context)) + 1) & 0xFF; - - int carryIns = result ^ (first.apply(context) & 0xFF) ^ inversedSecond; - int halfCarryOut = (carryIns >>> 4) & 1; - - if (halfCarryOut == 1) { + int carryIns = result ^ (first.apply(context) & 0xFF) ^ (second.apply(context) & 0xFF); + if ((carryIns & FLAG_H) == FLAG_H) { expectedFlags |= FLAG_H; } else { expectedNotFlags |= FLAG_H; @@ -284,12 +302,17 @@ public FlagsCheckImpl halfBorrow() { return this; } + public FlagsCheckImpl halfBorrow() { + return halfCarry(); // it's really the same for sub + } + public FlagsCheckImpl halfCarry11() { evaluators.add((context, result) -> { - int second = (result - context.first.intValue()) & 0xFFFF; + int fst = first.apply(context); + int snd = (result - fst) & 0xFFFF; - int mask = second & context.first.intValue(); - int xormask = second ^ context.first.intValue(); + int mask = snd & fst; + int xormask = snd ^ fst; int C0 = mask & 1; int C1 = ((mask >>> 1) ^ (C0 & (xormask >>> 1))) & 1; diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java index fddc96160..be832df4f 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java @@ -57,6 +57,7 @@ void init(int size, int banks, int bankCommon) { this.bankCommon = bankCommon; this.banksCount = banks; mem = new Byte[banks][size]; + clear(); } @Override From 55d79313536261fff709a57f44cea0495136e469 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 30 Apr 2022 14:49:28 +0100 Subject: [PATCH 126/314] [#201] z80-cpu: Fix some flags --- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 318 +++++++++--------- .../plugins/cpu/zilogZ80/IOTest.java | 19 +- .../plugins/cpu/zilogZ80/LogicTest.java | 3 +- .../plugins/cpu/zilogZ80/TransferTest.java | 6 + .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 22 ++ 5 files changed, 194 insertions(+), 174 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 9f08bc556..26986511c 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -411,7 +411,7 @@ private void bigOverflow(int i, int j, int result) { } } - private void auxCarry(int a, int b) { + private void halfBorrow(int a, int b) { int carryIns = ((a + b) & 0xFF) ^ a ^ b; int halfCarryOut = (carryIns >> 4) & 1; if (halfCarryOut != 0) { @@ -610,7 +610,7 @@ int I_SBC_A_R() { int value = getreg(lastOpcode & 0x07); int oldA = regs[REG_A]; - int sum = (oldA - value - (flags&FLAG_C)) & 0x1FF; + int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; @@ -1009,116 +1009,134 @@ int I_OUT_REF_C_0() throws IOException { return 12; } - int I_LDI() { - int tmp1 = getpair(2, false); - int tmp2 = getpair(1, false); - int tmp = getpair(0, false); + int I_CPI() { + int hl = (regs[REG_H] << 8) | regs[REG_L]; + int bc = (regs[REG_B] << 8) | regs[REG_C]; - memory.write(tmp2, memory.read(tmp1)); + int value = readByte(hl); + hl = (hl + 1) & 0xFFFF; + bc = (bc - 1) & 0xFFFF; - tmp1 = (tmp1 + 1) & 0xFFFF; - tmp2 = (tmp2 + 1) & 0xFFFF; - tmp = (tmp - 1) & 0xFFFF; + int sum = (regs[REG_A] - value) & 0xFF; + int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; + int flagP = (bc != 0) ? FLAG_PV : 0; + flags = TABLE_SUB[sum] | flagH | flagP | (flags & FLAG_C); - regs[REG_H] = (tmp1 >>> 8) & 0xFF; - regs[REG_L] = tmp1 & 0xFF; - regs[REG_D] = (tmp2 >>> 8) & 0xFF; - regs[REG_E] = tmp2 & 0xFF; - regs[REG_B] = (tmp >>> 8) & 0xFF; - regs[REG_C] = tmp & 0xFF; - flags = ((flags & FLAG_S) | (flags & FLAG_Z) | (flags & FLAG_C)) & (~FLAG_PV); - if (tmp != 0) { - flags |= FLAG_PV; - } + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; return 16; } - int I_CPI() { - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = (regs[REG_B] << 8) | regs[REG_C]; + int I_CPIR() { + int hl = (regs[REG_H] << 8) | regs[REG_L]; + int bc = (regs[REG_B] << 8) | regs[REG_C]; - int tmp = memory.read(tmp1); - tmp1 = (tmp1 + 1) & 0xFFFF; - tmp2 = (tmp2 - 1) & 0xFFFF; + int value = readByte(hl); + hl = (hl + 1) & 0xFFFF; + bc = (bc - 1) & 0xFFFF; - flags = TABLE_SZ[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); - auxCarry(regs[REG_A], (-tmp) & 0xFF); + int sum = (regs[REG_A] - value) & 0xFF; + int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; + int flagP = (bc != 0) ? FLAG_PV : 0; + flags = TABLE_SUB[sum] | flagH | flagP | (flags & FLAG_C); - if (tmp2 != 0) { - flags |= FLAG_PV; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; + + if ((bc == 0) || (regs[REG_A] == value)) { + return 16; } + PC = (PC - 2) & 0xFFFF; + return 21; + } + + int I_CPD() { + int hl = (regs[REG_H] << 8) | regs[REG_L]; + int bc = (regs[REG_B] << 8) | regs[REG_C]; - regs[REG_H] = (tmp1 >>> 8) & 0xFF; - regs[REG_L] = tmp1 & 0xFF; - regs[REG_B] = (tmp2 >>> 8) & 0xFF; - regs[REG_C] = tmp2 & 0xFF; + int value = readByte(hl); + hl = (hl - 1) & 0xFFFF; + bc = (bc - 1) & 0xFFFF; + + int sum = (regs[REG_A] - value) & 0xFF; + int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; + int flagP = (bc != 0) ? FLAG_PV : 0; + flags = TABLE_SUB[sum] | flagH | flagP | (flags & FLAG_C); + + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; return 16; } - int I_LDD() { - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = (regs[REG_D] << 8) | regs[REG_E]; - int tmp = (regs[REG_B] << 8) | regs[REG_C]; + int I_CPDR() { + int hl = (regs[REG_H] << 8) | regs[REG_L]; + int bc = (regs[REG_B] << 8) | regs[REG_C]; - memory.write(tmp2, memory.read(tmp1)); + int value = readByte(hl); + hl = (hl - 1) & 0xFFFF; + bc = (bc - 1) & 0xFFFF; - tmp1 = (tmp1 - 1) & 0xFFFF; - tmp2 = (tmp2 - 1) & 0xFFFF; - tmp = (tmp - 1) & 0xFFFF; - - regs[REG_H] = (tmp1 >>> 8) & 0xFF; - regs[REG_L] = tmp1 & 0xFF; - regs[REG_D] = (tmp2 >>> 8) & 0xFF; - regs[REG_E] = tmp2 & 0xFF; - regs[REG_B] = (tmp >>> 8) & 0xFF; - regs[REG_C] = tmp & 0xFF; - flags = ((flags & FLAG_S) | (flags & FLAG_Z) | (flags & FLAG_C)) & (~FLAG_PV); - if (tmp != 0) { - flags |= FLAG_PV; + int sum = (regs[REG_A] - value) & 0xFF; + int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; + int flagP = (bc != 0) ? FLAG_PV : 0; + flags = TABLE_SUB[sum] | flagH | flagP | (flags & FLAG_C); + + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; + + if ((bc == 0) || (regs[REG_A] == value)) { + return 16; } - return 16; + PC = (PC - 2) & 0xFFFF; + return 21; } - int I_CPD() { - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = (regs[REG_B] << 8) | regs[REG_C]; + int I_LDD() { + int hl = (regs[REG_H] << 8) | regs[REG_L]; + int de = (regs[REG_D] << 8) | regs[REG_E]; + int bc = (regs[REG_B] << 8) | regs[REG_C]; - int tmp = memory.read(tmp1); - tmp1 = (tmp1 - 1) & 0xFFFF; - tmp2 = (tmp2 - 1) & 0xFFFF; + memory.write(de, memory.read(hl)); - flags = TABLE_SZ[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); - auxCarry(regs[REG_A], (-tmp) & 0xFF); + hl = (hl - 1) & 0xFFFF; + de = (de - 1) & 0xFFFF; + bc = (bc - 1) & 0xFFFF; - if (tmp2 != 0) { + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_D] = (de >>> 8) & 0xFF; + regs[REG_E] = de & 0xFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; + flags = ((flags & FLAG_S) | (flags & FLAG_Z) | (flags & FLAG_C)) & (~FLAG_PV); + if (bc != 0) { flags |= FLAG_PV; } - - regs[REG_H] = (tmp1 >>> 8) & 0xFF; - regs[REG_L] = tmp1 & 0xFF; - regs[REG_B] = (tmp2 >>> 8) & 0xFF; - regs[REG_C] = tmp2 & 0xFF; return 16; } - int I_LDIR() { + int I_LDDR() { int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; int tmp2 = (regs[REG_D] << 8) | regs[REG_E]; - int tmp = (regs[REG_B] << 8) | regs[REG_C]; - memory.write(tmp2, memory.read(tmp1)); - - tmp1 = (tmp1 + 1) & 0xFFFF; - tmp2 = (tmp2 + 1) & 0xFFFF; - tmp = (tmp - 1) & 0xFFFF; - - regs[REG_H] = (tmp1 >>> 8) & 0xFF; - regs[REG_L] = tmp1 & 0xFF; - regs[REG_D] = (tmp2 >>> 8) & 0xFF; - regs[REG_E] = tmp2 & 0xFF; - regs[REG_B] = (tmp >>> 8) & 0xFF; - regs[REG_C] = tmp & 0xFF; - flags &= ((~FLAG_PV) & (~FLAG_N) & (~FLAG_H)); + tmp1 = (tmp1 - 1) & 0xFFFF; + tmp2 = (tmp2 - 1) & 0xFFFF; + int tmp = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; + regs[REG_H] = ((tmp1 >>> 8) & 0xff); + regs[REG_L] = (tmp1 & 0xFF); + regs[REG_B] = ((tmp >>> 8) & 0xff); + regs[REG_C] = (tmp & 0xFF); + regs[REG_D] = ((tmp2 >>> 8) & 0xff); + regs[REG_E] = (tmp2 & 0xFF); + flags &= 0xE9; if (tmp != 0) { flags |= FLAG_PV; } else { @@ -1128,27 +1146,50 @@ int I_LDIR() { return 21; } - int I_CPIR() { - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = (regs[REG_B] << 8) | regs[REG_C]; + int I_LDI() { + int hl = getpair(2, false); + int de = getpair(1, false); + int bc = getpair(0, false); - int tmp = memory.read(tmp1); - tmp1 = (tmp1 + 1) & 0xFFFF; - tmp2 = (tmp2 - 1) & 0xFFFF; + memory.write(de, memory.read(hl)); - flags = TABLE_SZ[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); - auxCarry(regs[REG_A], (-tmp) & 0xFF); + hl = (hl + 1) & 0xFFFF; + de = (de + 1) & 0xFFFF; + bc = (bc - 1) & 0xFFFF; - if (tmp2 != 0) { - flags |= FLAG_PV; - } + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_D] = (de >>> 8) & 0xFF; + regs[REG_E] = de & 0xFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; - regs[REG_H] = (tmp1 >>> 8) & 0xFF; - regs[REG_L] = tmp1 & 0xFF; - regs[REG_B] = (tmp2 >>> 8) & 0xFF; - regs[REG_C] = tmp2 & 0xFF; + int flagP = (bc != 0) ? FLAG_PV : 0; + flags = (flags & FLAG_S) | (flags & FLAG_Z) | (flags & FLAG_C) | flagP; + return 16; + } + + int I_LDIR() { + int hl = (regs[REG_H] << 8) | regs[REG_L]; + int de = (regs[REG_D] << 8) | regs[REG_E]; + int bc = (regs[REG_B] << 8) | regs[REG_C]; - if ((tmp2 == 0) || (regs[REG_A] == tmp)) { + memory.write(de, memory.read(hl)); + + hl = (hl + 1) & 0xFFFF; + de = (de + 1) & 0xFFFF; + bc = (bc - 1) & 0xFFFF; + + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_D] = (de >>> 8) & 0xFF; + regs[REG_E] = de & 0xFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; + + int flagP = (bc != 0) ? FLAG_PV : 0; + flags = (flags & FLAG_S) | (flags & FLAG_Z) | (flags & FLAG_C) | flagP; + if (bc == 0) { return 16; } PC = (PC - 2) & 0xFFFF; @@ -1166,7 +1207,8 @@ int I_INI() throws IOException { regs[REG_H] = (address >>> 8) & 0xFF; regs[REG_L] = address & 0xFF; - flags |= FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0); + int flagZ = (regs[REG_B] == 0) ? FLAG_Z : 0; + flags = flagZ | (flags & FLAG_C) | FLAG_N | (flags & FLAG_S) | (flags & FLAG_H) | (flags & FLAG_PV); return 16; } @@ -1192,14 +1234,14 @@ int I_INIR() throws IOException { int I_IND() throws IOException { byte value = context.readIO(regs[REG_C]); - int address = (regs[REG_H] << 8) | regs[REG_L]; - memory.write(address, value); + int hl = (regs[REG_H] << 8) | regs[REG_L]; + memory.write(hl, value); regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - address--; + hl = (hl - 1) & 0xFFFF; - regs[REG_H] = (address >>> 8) & 0xFF; - regs[REG_L] = address & 0xFF; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; flags |= FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0); return 16; @@ -1207,14 +1249,14 @@ int I_IND() throws IOException { int I_INDR() throws IOException { byte value = context.readIO(regs[REG_C]); - int address = (regs[REG_H] << 8) | regs[REG_L]; - memory.write(address, value); + int hl = (regs[REG_H] << 8) | regs[REG_L]; + memory.write(hl, value); regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - address--; + hl = (hl - 1) & 0xFFFF; - regs[REG_H] = (address >>> 8) & 0xFF; - regs[REG_L] = address & 0xFF; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; flags |= FLAG_Z | FLAG_N; // FLAG_Z is set b/c it is expected that INIR will be repeated until B=0 @@ -1291,56 +1333,6 @@ int I_OTDR() throws IOException { return 21; } - int I_LDDR() { - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = (regs[REG_D] << 8) | regs[REG_E]; - memory.write(tmp2, memory.read(tmp1)); - tmp1 = (tmp1 - 1) & 0xFFFF; - tmp2 = (tmp2 - 1) & 0xFFFF; - int tmp = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; - regs[REG_H] = ((tmp1 >>> 8) & 0xff); - regs[REG_L] = (tmp1 & 0xFF); - regs[REG_B] = ((tmp >>> 8) & 0xff); - regs[REG_C] = (tmp & 0xFF); - regs[REG_D] = ((tmp2 >>> 8) & 0xff); - regs[REG_E] = (tmp2 & 0xFF); - flags &= 0xE9; - if (tmp != 0) { - flags |= FLAG_PV; - } else { - return 16; - } - PC = (PC - 2) & 0xFFFF; - return 21; - } - - int I_CPDR() { - int hl = (regs[REG_H] << 8) | regs[REG_L]; - int bc = (regs[REG_B] << 8) | regs[REG_C]; - - int tmp = readByte(hl); - hl = (hl - 1) & 0xFFFF; - bc = (bc - 1) & 0xFFFF; - - flags = TABLE_SZ[(regs[REG_A] - tmp) & 0xFF] | FLAG_N | (flags & FLAG_C); - auxCarry(regs[REG_A], (-tmp) & 0xFF); - - if (bc != 0) { - flags |= FLAG_PV; - } - - regs[REG_H] = (hl >>> 8) & 0xFF; - regs[REG_L] = hl & 0xFF; - regs[REG_B] = (bc >>> 8) & 0xFF; - regs[REG_C] = bc & 0xFF; - - if ((bc == 0) || (regs[REG_A] == tmp)) { - return 16; - } - PC = (PC - 2) & 0xFFFF; - return 21; - } - int I_LD_REF_NN_RP() { int tmp = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -2017,7 +2009,7 @@ int I_SBC_A_REF_II_N(int special) { int value = readByte((special + offset) & 0xFFFF); int oldA = regs[REG_A]; - int sum = (oldA - value - (flags&FLAG_C)) & 0x1FF; + int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; @@ -2091,7 +2083,7 @@ int I_CP_REF_II_N(int special) { int value = readByte((special + offset) & 0xFFFF); int oldA = regs[REG_A]; - int sum = (oldA + value) & 0x1FF; + int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]); return 19; @@ -2600,7 +2592,7 @@ int I_ADC_A_IYL() { int I_ADC_A(int value) { int oldA = regs[REG_A]; - int sum = (oldA + value + (flags&FLAG_C)) & 0x1FF; + int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); return 8; @@ -2649,7 +2641,7 @@ int I_SBC_A_IYL() { int I_SBC_A(int value) { int oldA = regs[REG_A]; - int sum = (oldA - value - (flags&FLAG_C)) & 0x1FF; + int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; return 8; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java index 8aef227c0..6afc3830d 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java @@ -25,7 +25,6 @@ import net.emustudio.plugins.cpu.zilogZ80.suite.IntegerTestBuilder; import org.junit.Test; -import java.util.function.BiFunction; import java.util.function.Function; import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.*; @@ -96,6 +95,7 @@ public void testINI() { .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() + .carryIsPreserved() .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) ); @@ -117,9 +117,9 @@ public void testINIR() { .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) + .zeroIsSet() + .subtractionIsSet() + .carryIsPreserved() ) .verifyPC(context -> { if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { @@ -145,8 +145,8 @@ public void testIND() { .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) + .subtractionIsSet() + .carryIsPreserved() ); Generator.forSome16bitBinary(2, @@ -166,10 +166,9 @@ public void testINDR() { .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) - ) + .zeroIsSet() + .subtractionIsSet() + .carryIsPreserved()) .verifyPC(context -> { if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { return context.PC; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java index 66f2ed95e..4d07b4f51 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java @@ -122,7 +122,8 @@ public void testCP_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet(), + .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow() + .overflowSub().subtractionIsSet(), context -> (context.first & 0xFF) + (((~context.second) + 1) & 0xFF)) .keepCurrentInjectorsAfterRun(); diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java index 3719c881b..1c54b3895 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java @@ -480,6 +480,9 @@ public void testLDI() { .verifyPair(REG_PAIR_HL, context -> (context.second + 1) & 0xFFFF) .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsPreserved() + .zeroIsPreserved() + .signIsPreserved() .halfCarryIsReset().subtractionIsReset() .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) ); @@ -503,6 +506,9 @@ public void testLDIR() { .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) .verifyR(context -> 2) .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsPreserved() + .zeroIsPreserved() + .signIsPreserved() .halfCarryIsReset().subtractionIsReset() .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) ).verifyPC(context -> { diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java index c1cf0e562..07b7ebf6c 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java @@ -351,6 +351,28 @@ public FlagsCheckImpl zeroIsSet() { return this; } + public FlagsCheckImpl zeroIsPreserved() { + evaluators.add((context, result) -> { + if ((context.flags & FLAG_Z) == FLAG_Z) { + expectedFlags |= FLAG_Z; + } else { + expectedNotFlags |= FLAG_Z; + } + }); + return this; + } + + public FlagsCheckImpl signIsPreserved() { + evaluators.add((context, result) -> { + if ((context.flags & FLAG_S) == FLAG_S) { + expectedFlags |= FLAG_S; + } else { + expectedNotFlags |= FLAG_S; + } + }); + return this; + } + public static boolean isParity(int value) { int numberOfOnes = 0; From d1d8328e498430f0cb01ba4836789524e4b6d360 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 30 Apr 2022 20:14:20 +0100 Subject: [PATCH 127/314] [#201] z80-cpu: fix djnz --- .../net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java | 3 +-- .../java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 26986511c..3096912a4 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -675,8 +675,7 @@ int I_RRCA() { int I_DJNZ() { byte tmp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - regs[REG_B]--; - regs[REG_B] &= 0xFF; + regs[REG_B] = (regs[REG_B] - 1) & 0xFF; if (regs[REG_B] != 0) { PC = (PC - 2) + tmp; PC &= 0xFFFF; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java index e35b76b5f..a110034f2 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java @@ -334,7 +334,7 @@ public void testDJNZ__e() { .expandMemory(first -> cpuRunnerImpl.getPC() + first.intValue()) .verifyPC(context -> { if (((context.second - 1) & 0xFF) == 0) { - return context.PC; + return context.PC + 2; } return (context.PC + context.first) & 0xFFFF; }) From ffa62398f40e66c30c4b39eee4ecbd2edfb8f358 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 1 May 2022 06:44:24 +0100 Subject: [PATCH 128/314] [#201] comment --- .../plugins/cpu/zilogZ80/EmulatorTablesGeneration.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java index 48409e535..8211b0617 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java @@ -12,10 +12,6 @@ public class EmulatorTablesGeneration { public void generateTableSub() { StringBuilder table = new StringBuilder("public final static int[] TABLE_SUB = new int[] {\n "); - // public static final int FLAG_S = 0x80, FLAG_Z = 0x40, FLAG_H = 0x10, FLAG_PV = 0x4, FLAG_N = 0x02, FLAG_C = 0x1; - // 0xA8 - preserve: sign, overflow - // 10101000 - for (int sum = 0; sum < 256; sum++) { int flagZ = (sum == 0 ? FLAG_Z : 0); int flags = flagZ | (sum & 0x80) | FLAG_N; From eae283898fda03562c90c9b9c77adc3421b96dc4 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 1 May 2022 06:46:18 +0100 Subject: [PATCH 129/314] [#201] z80-cpu: removed unused function --- .../emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 3096912a4..177d965a7 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -411,16 +411,6 @@ private void bigOverflow(int i, int j, int result) { } } - private void halfBorrow(int a, int b) { - int carryIns = ((a + b) & 0xFF) ^ a ^ b; - int halfCarryOut = (carryIns >> 4) & 1; - if (halfCarryOut != 0) { - flags |= FLAG_H; - } else { - flags &= (~FLAG_H); - } - } - private void halfCarry11(int before, int sumWith) { int mask = sumWith & before; int xormask = sumWith ^ before; From bbb2b4c4d347606521832383a27338919ab6b1c2 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 1 May 2022 09:54:32 +0100 Subject: [PATCH 130/314] [#201, #215] brainc-brainduck: rewrite using ANTLR4 + remove brainduck-mem --- application/build.gradle | 10 +- .../src/main/files/config/BrainDuck.toml | 24 ++- plugins/compiler/as-8080/.gitignore | 1 + .../as-8080/src/main/antlr/As8080Lexer.tokens | 160 -------------- plugins/compiler/as-ssem/.gitignore | 2 + .../as-ssem/src/main/gen/SSEMLexer.interp | 92 -------- .../as-ssem/src/main/gen/SSEMLexer.java | 199 ------------------ plugins/compiler/as-z80/.gitignore | 1 + .../as-z80/src/main/antlr/AsZ80Lexer.tokens | 178 ---------------- .../plugins/compiler/asZ80/AssemblerZ80.java | 1 - plugins/compiler/brainc-brainduck/.gitignore | 4 +- .../compiler/brainc-brainduck/build.gradle | 43 ++-- .../src/main/antlr/BraincLexer.g4 | 15 ++ .../src/main/antlr/BraincParser.g4 | 25 +++ .../brainc-brainduck/src/main/cup/parser.cup | 116 ---------- .../plugins/compiler/brainc/TokenImpl.java | 79 ------- .../compiler/brainduck/CompileException.java | 17 ++ .../{brainc => brainduck}/CompilerImpl.java | 96 +++++---- .../brainduck/LexicalAnalyzerImpl.java | 68 ++++++ .../brainduck/ParserErrorListener.java | 18 ++ .../{brainc => brainduck}/Runner.java | 2 +- .../tree/Instruction.java | 40 ++-- .../{brainc => brainduck}/tree/Program.java | 21 +- .../brainduck/tree/ProgramParser.java | 21 ++ .../src/main/jflex/lexer.jflex | 95 --------- .../{brainc => brainduck}/version.properties | 0 .../AbstractCompilerTest.java | 25 ++- .../InstructionTest.java | 7 +- .../{brainc => brainduck}/RunnerTest.java | 2 +- plugins/cpu/brainduck-cpu/build.gradle | 2 +- .../plugins/cpu/brainduck/CpuImpl.java | 15 +- .../plugins/cpu/brainduck/EmulatorEngine.java | 13 +- .../plugins/cpu/brainduck/Profiler.java | 6 +- .../cpu/brainduck/gui/MemoryTableModel.java | 7 +- .../cpu/brainduck/gui/StatusPanel.java | 10 +- .../plugins/cpu/brainduck/CpuImplTest.java | 4 +- .../plugins/cpu/brainduck/MemoryStub.java | 114 +++++++++- plugins/memory/brainduck-mem/README.md | 6 - plugins/memory/brainduck-mem/build.gradle | 54 ----- .../memory/brainduck/MemoryContextImpl.java | 74 ------- .../plugins/memory/brainduck/MemoryImpl.java | 112 ---------- .../brainduck/api/RawMemoryContext.java | 36 ---- .../memory/brainduck/gui/Constants.java | 8 - .../memory/brainduck/gui/MemoryGui.java | 184 ---------------- .../memory/brainduck/gui/MemoryTable.java | 159 -------------- .../brainduck/gui/MemoryTableModel.java | 102 --------- .../memory/brainduck/version.properties | 21 -- .../memory/brainduck/MemoryImplTest.java | 41 ---- .../memory/bytemem/MemoryContextImpl.java | 5 + .../memory/bytemem/api/ByteMemoryContext.java | 9 + settings.gradle | 3 +- 51 files changed, 459 insertions(+), 1888 deletions(-) delete mode 100644 plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens delete mode 100644 plugins/compiler/as-ssem/src/main/gen/SSEMLexer.interp delete mode 100644 plugins/compiler/as-ssem/src/main/gen/SSEMLexer.java delete mode 100644 plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens create mode 100644 plugins/compiler/brainc-brainduck/src/main/antlr/BraincLexer.g4 create mode 100644 plugins/compiler/brainc-brainduck/src/main/antlr/BraincParser.g4 delete mode 100644 plugins/compiler/brainc-brainduck/src/main/cup/parser.cup delete mode 100644 plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/TokenImpl.java create mode 100644 plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompileException.java rename plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/{brainc => brainduck}/CompilerImpl.java (68%) create mode 100644 plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java create mode 100644 plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ParserErrorListener.java rename plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/{brainc => brainduck}/Runner.java (98%) rename plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/{brainc => brainduck}/tree/Instruction.java (52%) rename plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/{brainc => brainduck}/tree/Program.java (67%) create mode 100644 plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/ProgramParser.java delete mode 100644 plugins/compiler/brainc-brainduck/src/main/jflex/lexer.jflex rename plugins/compiler/brainc-brainduck/src/main/resources/net/emustudio/plugins/compiler/{brainc => brainduck}/version.properties (100%) rename plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/{brainc => brainduck}/AbstractCompilerTest.java (80%) rename plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/{brainc => brainduck}/InstructionTest.java (95%) rename plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/{brainc => brainduck}/RunnerTest.java (97%) delete mode 100644 plugins/memory/brainduck-mem/README.md delete mode 100644 plugins/memory/brainduck-mem/build.gradle delete mode 100644 plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java delete mode 100644 plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryImpl.java delete mode 100644 plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/api/RawMemoryContext.java delete mode 100644 plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/Constants.java delete mode 100644 plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryGui.java delete mode 100644 plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTable.java delete mode 100644 plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTableModel.java delete mode 100644 plugins/memory/brainduck-mem/src/main/resources/net/emustudio/plugins/memory/brainduck/version.properties delete mode 100644 plugins/memory/brainduck-mem/src/test/java/net/emustudio/plugins/memory/brainduck/MemoryImplTest.java diff --git a/application/build.gradle b/application/build.gradle index 077ac3219..74c2dc2a8 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -52,13 +52,12 @@ dependencies { providedRuntime project(":plugins:compiler:as-8080") providedRuntime project(":plugins:compiler:as-ssem") providedRuntime project(":plugins:compiler:as-z80") -// providedRuntime project(":plugins:compiler:brainc-brainduck") + providedRuntime project(":plugins:compiler:brainc-brainduck") // providedRuntime project(":plugins:compiler:ramc-ram") // providedRuntime project(":plugins:compiler:raspc-rasp") // providedRuntime project(":plugins:memory:ram-mem") // providedRuntime project(":plugins:memory:rasp-mem") - providedRuntime project(":plugins:memory:brainduck-mem") providedRuntime project(":plugins:memory:ssem-mem") providedRuntime project(":plugins:memory:byte-mem") @@ -179,7 +178,7 @@ distributions { from(output(":plugins:compiler:as-8080")) from(output(":plugins:compiler:as-z80")) from(output(":plugins:compiler:as-ssem")) - // from(output(":plugins:compiler:brainc-brainduck")) + from(output(":plugins:compiler:brainc-brainduck")) // from(output(":plugins:compiler:ramc-ram")) //from(output(":plugins:compiler:raspc-rasp")) } @@ -188,7 +187,6 @@ distributions { include '*.jar' // from(output(":plugins:memory:ram-mem")) // from(output(":plugins:memory:rasp-mem")) - from(output(":plugins:memory:brainduck-mem")) from(output(":plugins:memory:ssem-mem")) from(output(":plugins:memory:byte-mem")) } @@ -216,7 +214,7 @@ distributions { // Examples //["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"] - ["as-8080", "as-z80", "as-ssem"].collect { compiler -> + ["as-8080", "as-z80", "as-ssem", "brainc-brainduck"].collect { compiler -> from(examples(":plugins:compiler:$compiler")) { into "examples/$compiler" } @@ -224,7 +222,7 @@ distributions { // Scripts // ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"] - ["as-8080", "as-z80", "as-ssem"].collect { compiler -> + ["as-8080", "as-z80", "as-ssem", "brainc-brainduck"].collect { compiler -> from(scripts(":plugins:compiler:$compiler")) { into "bin" } diff --git a/application/src/main/files/config/BrainDuck.toml b/application/src/main/files/config/BrainDuck.toml index c27a760cc..a06568e70 100644 --- a/application/src/main/files/config/BrainDuck.toml +++ b/application/src/main/files/config/BrainDuck.toml @@ -2,47 +2,51 @@ name = "BrainDuck" [MEMORY] schemaPoint = "100,180" - path = "brainduck-mem.jar" - name = "brainduck-mem" - id = "95e3a458-1d0f-40aa-9c38-f9efc5026738" + path = "byte-mem.jar" + settings = {} + name = "byte-mem" + id = "300555eb-2e6b-422f-a954-cfe1905f911a" type = "MEMORY" [COMPILER] schemaPoint = "100,60" path = "brainc-brainduck.jar" + settings = {} name = "brainc-brainduck" id = "de251cec-e053-4e2c-a647-9b71eb0f1b70" type = "COMPILER" [CPU] - schemaPoint = "260,180" + schemaPoint = "320,180" path = "brainduck-cpu.jar" + settings = {} name = "brainduck-cpu" id = "6c5df0df-4497-4a9d-b9dd-9a3f901864c1" type = "CPU" [[DEVICE]] - schemaPoint = "260,60" + schemaPoint = "320,60" path = "brainduck-terminal.jar" + settings = {} name = "brainduck-terminal" id = "1d858668-d63d-4127-b881-226174a2b368" type = "DEVICE" [[connections]] bidirectional = true - from = "de251cec-e053-4e2c-a647-9b71eb0f1b70" - to = "95e3a458-1d0f-40aa-9c38-f9efc5026738" + from = "1d858668-d63d-4127-b881-226174a2b368" + to = "6c5df0df-4497-4a9d-b9dd-9a3f901864c1" points = [] [[connections]] bidirectional = true - from = "95e3a458-1d0f-40aa-9c38-f9efc5026738" - to = "6c5df0df-4497-4a9d-b9dd-9a3f901864c1" + from = "de251cec-e053-4e2c-a647-9b71eb0f1b70" + to = "300555eb-2e6b-422f-a954-cfe1905f911a" points = [] [[connections]] bidirectional = true - from = "1d858668-d63d-4127-b881-226174a2b368" + from = "300555eb-2e6b-422f-a954-cfe1905f911a" to = "6c5df0df-4497-4a9d-b9dd-9a3f901864c1" points = [] diff --git a/plugins/compiler/as-8080/.gitignore b/plugins/compiler/as-8080/.gitignore index a37c70406..f6f374b4d 100644 --- a/plugins/compiler/as-8080/.gitignore +++ b/plugins/compiler/as-8080/.gitignore @@ -1,2 +1,3 @@ /src/main/antlr/gen/ /src/main/gen/ +*.tokens diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens b/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens deleted file mode 100644 index add624e00..000000000 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Lexer.tokens +++ /dev/null @@ -1,160 +0,0 @@ -COMMENT=1 -COMMENT2=2 -OPCODE_STC=3 -OPCODE_CMC=4 -OPCODE_INR=5 -OPCODE_DCR=6 -OPCODE_CMA=7 -OPCODE_DAA=8 -OPCODE_NOP=9 -OPCODE_MOV=10 -OPCODE_STAX=11 -OPCODE_LDAX=12 -OPCODE_ADD=13 -OPCODE_ADC=14 -OPCODE_SUB=15 -OPCODE_SBB=16 -OPCODE_ANA=17 -OPCODE_XRA=18 -OPCODE_ORA=19 -OPCODE_CMP=20 -OPCODE_RLC=21 -OPCODE_RRC=22 -OPCODE_RAL=23 -OPCODE_RAR=24 -OPCODE_PUSH=25 -OPCODE_POP=26 -OPCODE_DAD=27 -OPCODE_INX=28 -OPCODE_DCX=29 -OPCODE_XCHG=30 -OPCODE_XTHL=31 -OPCODE_SPHL=32 -OPCODE_LXI=33 -OPCODE_MVI=34 -OPCODE_ADI=35 -OPCODE_ACI=36 -OPCODE_SUI=37 -OPCODE_SBI=38 -OPCODE_ANI=39 -OPCODE_XRI=40 -OPCODE_ORI=41 -OPCODE_CPI=42 -OPCODE_STA=43 -OPCODE_LDA=44 -OPCODE_SHLD=45 -OPCODE_LHLD=46 -OPCODE_PCHL=47 -OPCODE_JMP=48 -OPCODE_JC=49 -OPCODE_JNC=50 -OPCODE_JZ=51 -OPCODE_JNZ=52 -OPCODE_JP=53 -OPCODE_JM=54 -OPCODE_JPE=55 -OPCODE_JPO=56 -OPCODE_CALL=57 -OPCODE_CC=58 -OPCODE_CNC=59 -OPCODE_CZ=60 -OPCODE_CNZ=61 -OPCODE_CP=62 -OPCODE_CM=63 -OPCODE_CPE=64 -OPCODE_CPO=65 -OPCODE_RET=66 -OPCODE_RC=67 -OPCODE_RNC=68 -OPCODE_RZ=69 -OPCODE_RNZ=70 -OPCODE_RM=71 -OPCODE_RP=72 -OPCODE_RPE=73 -OPCODE_RPO=74 -OPCODE_RST=75 -OPCODE_EI=76 -OPCODE_DI=77 -OPCODE_IN=78 -OPCODE_OUT=79 -OPCODE_HLT=80 -PREP_ORG=81 -PREP_EQU=82 -PREP_SET=83 -PREP_INCLUDE=84 -PREP_IF=85 -PREP_ENDIF=86 -PREP_MACRO=87 -PREP_ENDM=88 -PREP_DB=89 -PREP_DW=90 -PREP_DS=91 -PREP_ADDR=92 -REG_A=93 -REG_B=94 -REG_C=95 -REG_D=96 -REG_E=97 -REG_H=98 -REG_L=99 -REG_M=100 -REG_PSW=101 -REG_SP=102 -OP_MOD=103 -OP_SHR=104 -OP_SHL=105 -OP_NOT=106 -OP_AND=107 -OP_OR=108 -OP_XOR=109 -LIT_HEXNUMBER_1=110 -LIT_NUMBER=111 -LIT_HEXNUMBER_2=112 -LIT_OCTNUMBER=113 -LIT_BINNUMBER=114 -LIT_STRING_1=115 -LIT_STRING_2=116 -ID_IDENTIFIER=117 -ID_LABEL=118 -ERROR=119 -SEP_LPAR=120 -SEP_RPAR=121 -SEP_COMMA=122 -OP_ADD=123 -OP_SUBTRACT=124 -OP_MULTIPLY=125 -OP_DIVIDE=126 -OP_EQUAL=127 -OP_GT=128 -OP_GTE=129 -OP_LT=130 -OP_LTE=131 -OP_MOD_2=132 -OP_SHR_2=133 -OP_SHL_2=134 -OP_NOT_2=135 -OP_AND_2=136 -OP_OR_2=137 -OP_XOR_2=138 -WS=139 -EOL=140 -'$'=92 -'('=120 -')'=121 -','=122 -'+'=123 -'-'=124 -'*'=125 -'/'=126 -'='=127 -'>'=128 -'>='=129 -'<'=130 -'<='=131 -'%'=132 -'>>'=133 -'<<'=134 -'~'=135 -'&'=136 -'|'=137 -'^'=138 diff --git a/plugins/compiler/as-ssem/.gitignore b/plugins/compiler/as-ssem/.gitignore index 1f3145080..f6f374b4d 100644 --- a/plugins/compiler/as-ssem/.gitignore +++ b/plugins/compiler/as-ssem/.gitignore @@ -1 +1,3 @@ +/src/main/antlr/gen/ +/src/main/gen/ *.tokens diff --git a/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.interp b/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.interp deleted file mode 100644 index 60df1ad91..000000000 --- a/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.interp +++ /dev/null @@ -1,92 +0,0 @@ -token literal names: -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null - -token symbolic names: -null -WS -COMMENT -EOL -JMP -JPR -LDN -STO -SUB -CMP -STP -START -NUM -BNUM -NUMBER -HEXNUMBER -ERROR -BWS -BinaryNumber -BERROR - -rule names: -WS -COMMENT -EOL -J -M -P -R -L -D -N -S -T -O -U -B -C -K -H -A -I -JMP -JPR -LDN -STO -SUB -CMP -STP -START -NUM -BNUM -NUMBER -HEXNUMBER -ERROR -BWS -BinaryNumber -BERROR - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE -BIN - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 21, 243, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 86, 10, 3, 3, 3, 7, 3, 89, 10, 3, 12, 3, 14, 3, 92, 11, 3, 3, 4, 5, 4, 95, 10, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 5, 23, 149, 10, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 5, 27, 171, 10, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 5, 28, 181, 10, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 5, 31, 203, 10, 31, 3, 31, 3, 31, 3, 32, 5, 32, 208, 10, 32, 3, 32, 6, 32, 211, 10, 32, 13, 32, 14, 32, 212, 3, 33, 5, 33, 216, 10, 33, 3, 33, 3, 33, 3, 33, 3, 33, 5, 33, 222, 10, 33, 3, 33, 6, 33, 225, 10, 33, 13, 33, 14, 33, 226, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 6, 36, 236, 10, 36, 13, 36, 14, 36, 237, 3, 36, 3, 36, 3, 37, 3, 37, 2, 2, 38, 4, 3, 6, 4, 8, 5, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 6, 46, 7, 48, 8, 50, 9, 52, 10, 54, 11, 56, 12, 58, 13, 60, 14, 62, 15, 64, 16, 66, 17, 68, 18, 70, 19, 72, 20, 74, 21, 4, 2, 3, 26, 4, 2, 11, 11, 34, 34, 4, 2, 37, 37, 61, 61, 4, 2, 12, 12, 15, 15, 4, 2, 76, 76, 108, 108, 4, 2, 79, 79, 111, 111, 4, 2, 82, 82, 114, 114, 4, 2, 84, 84, 116, 116, 4, 2, 78, 78, 110, 110, 4, 2, 70, 70, 102, 102, 4, 2, 80, 80, 112, 112, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 81, 81, 113, 113, 4, 2, 87, 87, 119, 119, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 77, 77, 109, 109, 4, 2, 74, 74, 106, 106, 4, 2, 67, 67, 99, 99, 4, 2, 75, 75, 107, 107, 3, 2, 47, 47, 3, 2, 50, 59, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 51, 2, 239, 2, 4, 3, 2, 2, 2, 2, 6, 3, 2, 2, 2, 2, 8, 3, 2, 2, 2, 2, 44, 3, 2, 2, 2, 2, 46, 3, 2, 2, 2, 2, 48, 3, 2, 2, 2, 2, 50, 3, 2, 2, 2, 2, 52, 3, 2, 2, 2, 2, 54, 3, 2, 2, 2, 2, 56, 3, 2, 2, 2, 2, 58, 3, 2, 2, 2, 2, 60, 3, 2, 2, 2, 2, 62, 3, 2, 2, 2, 2, 64, 3, 2, 2, 2, 2, 66, 3, 2, 2, 2, 2, 68, 3, 2, 2, 2, 3, 70, 3, 2, 2, 2, 3, 72, 3, 2, 2, 2, 3, 74, 3, 2, 2, 2, 4, 76, 3, 2, 2, 2, 6, 85, 3, 2, 2, 2, 8, 94, 3, 2, 2, 2, 10, 98, 3, 2, 2, 2, 12, 100, 3, 2, 2, 2, 14, 102, 3, 2, 2, 2, 16, 104, 3, 2, 2, 2, 18, 106, 3, 2, 2, 2, 20, 108, 3, 2, 2, 2, 22, 110, 3, 2, 2, 2, 24, 112, 3, 2, 2, 2, 26, 114, 3, 2, 2, 2, 28, 116, 3, 2, 2, 2, 30, 118, 3, 2, 2, 2, 32, 120, 3, 2, 2, 2, 34, 122, 3, 2, 2, 2, 36, 124, 3, 2, 2, 2, 38, 126, 3, 2, 2, 2, 40, 128, 3, 2, 2, 2, 42, 130, 3, 2, 2, 2, 44, 132, 3, 2, 2, 2, 46, 148, 3, 2, 2, 2, 48, 150, 3, 2, 2, 2, 50, 154, 3, 2, 2, 2, 52, 158, 3, 2, 2, 2, 54, 170, 3, 2, 2, 2, 56, 180, 3, 2, 2, 2, 58, 182, 3, 2, 2, 2, 60, 188, 3, 2, 2, 2, 62, 202, 3, 2, 2, 2, 64, 207, 3, 2, 2, 2, 66, 215, 3, 2, 2, 2, 68, 228, 3, 2, 2, 2, 70, 230, 3, 2, 2, 2, 72, 235, 3, 2, 2, 2, 74, 241, 3, 2, 2, 2, 76, 77, 9, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 79, 8, 2, 2, 2, 79, 5, 3, 2, 2, 2, 80, 81, 7, 49, 2, 2, 81, 86, 7, 49, 2, 2, 82, 83, 7, 47, 2, 2, 83, 86, 7, 47, 2, 2, 84, 86, 9, 3, 2, 2, 85, 80, 3, 2, 2, 2, 85, 82, 3, 2, 2, 2, 85, 84, 3, 2, 2, 2, 86, 90, 3, 2, 2, 2, 87, 89, 10, 4, 2, 2, 88, 87, 3, 2, 2, 2, 89, 92, 3, 2, 2, 2, 90, 88, 3, 2, 2, 2, 90, 91, 3, 2, 2, 2, 91, 7, 3, 2, 2, 2, 92, 90, 3, 2, 2, 2, 93, 95, 7, 15, 2, 2, 94, 93, 3, 2, 2, 2, 94, 95, 3, 2, 2, 2, 95, 96, 3, 2, 2, 2, 96, 97, 7, 12, 2, 2, 97, 9, 3, 2, 2, 2, 98, 99, 9, 5, 2, 2, 99, 11, 3, 2, 2, 2, 100, 101, 9, 6, 2, 2, 101, 13, 3, 2, 2, 2, 102, 103, 9, 7, 2, 2, 103, 15, 3, 2, 2, 2, 104, 105, 9, 8, 2, 2, 105, 17, 3, 2, 2, 2, 106, 107, 9, 9, 2, 2, 107, 19, 3, 2, 2, 2, 108, 109, 9, 10, 2, 2, 109, 21, 3, 2, 2, 2, 110, 111, 9, 11, 2, 2, 111, 23, 3, 2, 2, 2, 112, 113, 9, 12, 2, 2, 113, 25, 3, 2, 2, 2, 114, 115, 9, 13, 2, 2, 115, 27, 3, 2, 2, 2, 116, 117, 9, 14, 2, 2, 117, 29, 3, 2, 2, 2, 118, 119, 9, 15, 2, 2, 119, 31, 3, 2, 2, 2, 120, 121, 9, 16, 2, 2, 121, 33, 3, 2, 2, 2, 122, 123, 9, 17, 2, 2, 123, 35, 3, 2, 2, 2, 124, 125, 9, 18, 2, 2, 125, 37, 3, 2, 2, 2, 126, 127, 9, 19, 2, 2, 127, 39, 3, 2, 2, 2, 128, 129, 9, 20, 2, 2, 129, 41, 3, 2, 2, 2, 130, 131, 9, 21, 2, 2, 131, 43, 3, 2, 2, 2, 132, 133, 5, 10, 5, 2, 133, 134, 5, 12, 6, 2, 134, 135, 5, 14, 7, 2, 135, 45, 3, 2, 2, 2, 136, 137, 5, 10, 5, 2, 137, 138, 5, 14, 7, 2, 138, 139, 5, 16, 8, 2, 139, 149, 3, 2, 2, 2, 140, 141, 5, 10, 5, 2, 141, 142, 5, 16, 8, 2, 142, 143, 5, 14, 7, 2, 143, 149, 3, 2, 2, 2, 144, 145, 5, 10, 5, 2, 145, 146, 5, 12, 6, 2, 146, 147, 5, 16, 8, 2, 147, 149, 3, 2, 2, 2, 148, 136, 3, 2, 2, 2, 148, 140, 3, 2, 2, 2, 148, 144, 3, 2, 2, 2, 149, 47, 3, 2, 2, 2, 150, 151, 5, 18, 9, 2, 151, 152, 5, 20, 10, 2, 152, 153, 5, 22, 11, 2, 153, 49, 3, 2, 2, 2, 154, 155, 5, 24, 12, 2, 155, 156, 5, 26, 13, 2, 156, 157, 5, 28, 14, 2, 157, 51, 3, 2, 2, 2, 158, 159, 5, 24, 12, 2, 159, 160, 5, 30, 15, 2, 160, 161, 5, 32, 16, 2, 161, 53, 3, 2, 2, 2, 162, 163, 5, 34, 17, 2, 163, 164, 5, 12, 6, 2, 164, 165, 5, 14, 7, 2, 165, 171, 3, 2, 2, 2, 166, 167, 5, 24, 12, 2, 167, 168, 5, 36, 18, 2, 168, 169, 5, 22, 11, 2, 169, 171, 3, 2, 2, 2, 170, 162, 3, 2, 2, 2, 170, 166, 3, 2, 2, 2, 171, 55, 3, 2, 2, 2, 172, 173, 5, 24, 12, 2, 173, 174, 5, 26, 13, 2, 174, 175, 5, 14, 7, 2, 175, 181, 3, 2, 2, 2, 176, 177, 5, 38, 19, 2, 177, 178, 5, 18, 9, 2, 178, 179, 5, 26, 13, 2, 179, 181, 3, 2, 2, 2, 180, 172, 3, 2, 2, 2, 180, 176, 3, 2, 2, 2, 181, 57, 3, 2, 2, 2, 182, 183, 5, 24, 12, 2, 183, 184, 5, 26, 13, 2, 184, 185, 5, 40, 20, 2, 185, 186, 5, 16, 8, 2, 186, 187, 5, 26, 13, 2, 187, 59, 3, 2, 2, 2, 188, 189, 5, 22, 11, 2, 189, 190, 5, 30, 15, 2, 190, 191, 5, 12, 6, 2, 191, 61, 3, 2, 2, 2, 192, 193, 5, 32, 16, 2, 193, 194, 5, 22, 11, 2, 194, 195, 5, 30, 15, 2, 195, 196, 5, 12, 6, 2, 196, 203, 3, 2, 2, 2, 197, 198, 5, 32, 16, 2, 198, 199, 5, 42, 21, 2, 199, 200, 5, 22, 11, 2, 200, 201, 5, 24, 12, 2, 201, 203, 3, 2, 2, 2, 202, 192, 3, 2, 2, 2, 202, 197, 3, 2, 2, 2, 203, 204, 3, 2, 2, 2, 204, 205, 8, 31, 3, 2, 205, 63, 3, 2, 2, 2, 206, 208, 9, 22, 2, 2, 207, 206, 3, 2, 2, 2, 207, 208, 3, 2, 2, 2, 208, 210, 3, 2, 2, 2, 209, 211, 9, 23, 2, 2, 210, 209, 3, 2, 2, 2, 211, 212, 3, 2, 2, 2, 212, 210, 3, 2, 2, 2, 212, 213, 3, 2, 2, 2, 213, 65, 3, 2, 2, 2, 214, 216, 9, 22, 2, 2, 215, 214, 3, 2, 2, 2, 215, 216, 3, 2, 2, 2, 216, 221, 3, 2, 2, 2, 217, 218, 7, 50, 2, 2, 218, 222, 7, 122, 2, 2, 219, 220, 7, 50, 2, 2, 220, 222, 7, 90, 2, 2, 221, 217, 3, 2, 2, 2, 221, 219, 3, 2, 2, 2, 222, 224, 3, 2, 2, 2, 223, 225, 9, 24, 2, 2, 224, 223, 3, 2, 2, 2, 225, 226, 3, 2, 2, 2, 226, 224, 3, 2, 2, 2, 226, 227, 3, 2, 2, 2, 227, 67, 3, 2, 2, 2, 228, 229, 11, 2, 2, 2, 229, 69, 3, 2, 2, 2, 230, 231, 9, 2, 2, 2, 231, 232, 3, 2, 2, 2, 232, 233, 8, 35, 2, 2, 233, 71, 3, 2, 2, 2, 234, 236, 9, 25, 2, 2, 235, 234, 3, 2, 2, 2, 236, 237, 3, 2, 2, 2, 237, 235, 3, 2, 2, 2, 237, 238, 3, 2, 2, 2, 238, 239, 3, 2, 2, 2, 239, 240, 8, 36, 4, 2, 240, 73, 3, 2, 2, 2, 241, 242, 11, 2, 2, 2, 242, 75, 3, 2, 2, 2, 17, 2, 3, 85, 90, 94, 148, 170, 180, 202, 207, 212, 215, 221, 226, 237, 5, 2, 3, 2, 7, 3, 2, 6, 2, 2] \ No newline at end of file diff --git a/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.java b/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.java deleted file mode 100644 index c007eabe9..000000000 --- a/plugins/compiler/as-ssem/src/main/gen/SSEMLexer.java +++ /dev/null @@ -1,199 +0,0 @@ -// Generated from /home/vbmacher/projects/emustudio/emuStudio/plugins/compiler/as-ssem/src/main/antlr/SSEMLexer.g4 by ANTLR 4.9.1 -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) -public class SSEMLexer extends Lexer { - static { RuntimeMetaData.checkVersion("4.9.1", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - WS=1, COMMENT=2, EOL=3, JMP=4, JPR=5, LDN=6, STO=7, SUB=8, CMP=9, STP=10, - START=11, NUM=12, BNUM=13, NUMBER=14, HEXNUMBER=15, ERROR=16, BWS=17, - BinaryNumber=18, BERROR=19; - public static final int - BIN=1; - public static String[] channelNames = { - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }; - - public static String[] modeNames = { - "DEFAULT_MODE", "BIN" - }; - - private static String[] makeRuleNames() { - return new String[] { - "WS", "COMMENT", "EOL", "J", "M", "P", "R", "L", "D", "N", "S", "T", - "O", "U", "B", "C", "K", "H", "A", "I", "JMP", "JPR", "LDN", "STO", "SUB", - "CMP", "STP", "START", "NUM", "BNUM", "NUMBER", "HEXNUMBER", "ERROR", - "BWS", "BinaryNumber", "BERROR" - }; - } - public static final String[] ruleNames = makeRuleNames(); - - private static String[] makeLiteralNames() { - return new String[] { - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - null, "WS", "COMMENT", "EOL", "JMP", "JPR", "LDN", "STO", "SUB", "CMP", - "STP", "START", "NUM", "BNUM", "NUMBER", "HEXNUMBER", "ERROR", "BWS", - "BinaryNumber", "BERROR" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - - public SSEMLexer(CharStream input) { - super(input); - _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - @Override - public String getGrammarFileName() { return "SSEMLexer.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public String[] getChannelNames() { return channelNames; } - - @Override - public String[] getModeNames() { return modeNames; } - - @Override - public ATN getATN() { return _ATN; } - - public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\25\u00f3\b\1\b\1"+ - "\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t"+ - "\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4"+ - "\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4"+ - "\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4"+ - " \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3"+ - "\3\5\3V\n\3\3\3\7\3Y\n\3\f\3\16\3\\\13\3\3\4\5\4_\n\4\3\4\3\4\3\5\3\5"+ - "\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\16"+ - "\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3\22\3\22\3\23\3\23\3\24\3\24\3\25"+ - "\3\25\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27"+ - "\3\27\3\27\3\27\5\27\u0095\n\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31"+ - "\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\5\33\u00ab"+ - "\n\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\5\34\u00b5\n\34\3\35\3\35"+ - "\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3\37"+ - "\3\37\3\37\3\37\3\37\5\37\u00cb\n\37\3\37\3\37\3 \5 \u00d0\n \3 \6 \u00d3"+ - "\n \r \16 \u00d4\3!\5!\u00d8\n!\3!\3!\3!\3!\5!\u00de\n!\3!\6!\u00e1\n"+ - "!\r!\16!\u00e2\3\"\3\"\3#\3#\3#\3#\3$\6$\u00ec\n$\r$\16$\u00ed\3$\3$\3"+ - "%\3%\2\2&\4\3\6\4\b\5\n\2\f\2\16\2\20\2\22\2\24\2\26\2\30\2\32\2\34\2"+ - "\36\2 \2\"\2$\2&\2(\2*\2,\6.\7\60\b\62\t\64\n\66\138\f:\r<\16>\17@\20"+ - "B\21D\22F\23H\24J\25\4\2\3\32\4\2\13\13\"\"\4\2%%==\4\2\f\f\17\17\4\2"+ - "LLll\4\2OOoo\4\2RRrr\4\2TTtt\4\2NNnn\4\2FFff\4\2PPpp\4\2UUuu\4\2VVvv\4"+ - "\2QQqq\4\2WWww\4\2DDdd\4\2EEee\4\2MMmm\4\2JJjj\4\2CCcc\4\2KKkk\3\2//\3"+ - "\2\62;\5\2\62;CHch\3\2\62\63\2\u00ef\2\4\3\2\2\2\2\6\3\2\2\2\2\b\3\2\2"+ - "\2\2,\3\2\2\2\2.\3\2\2\2\2\60\3\2\2\2\2\62\3\2\2\2\2\64\3\2\2\2\2\66\3"+ - "\2\2\2\28\3\2\2\2\2:\3\2\2\2\2<\3\2\2\2\2>\3\2\2\2\2@\3\2\2\2\2B\3\2\2"+ - "\2\2D\3\2\2\2\3F\3\2\2\2\3H\3\2\2\2\3J\3\2\2\2\4L\3\2\2\2\6U\3\2\2\2\b"+ - "^\3\2\2\2\nb\3\2\2\2\fd\3\2\2\2\16f\3\2\2\2\20h\3\2\2\2\22j\3\2\2\2\24"+ - "l\3\2\2\2\26n\3\2\2\2\30p\3\2\2\2\32r\3\2\2\2\34t\3\2\2\2\36v\3\2\2\2"+ - " x\3\2\2\2\"z\3\2\2\2$|\3\2\2\2&~\3\2\2\2(\u0080\3\2\2\2*\u0082\3\2\2"+ - "\2,\u0084\3\2\2\2.\u0094\3\2\2\2\60\u0096\3\2\2\2\62\u009a\3\2\2\2\64"+ - "\u009e\3\2\2\2\66\u00aa\3\2\2\28\u00b4\3\2\2\2:\u00b6\3\2\2\2<\u00bc\3"+ - "\2\2\2>\u00ca\3\2\2\2@\u00cf\3\2\2\2B\u00d7\3\2\2\2D\u00e4\3\2\2\2F\u00e6"+ - "\3\2\2\2H\u00eb\3\2\2\2J\u00f1\3\2\2\2LM\t\2\2\2MN\3\2\2\2NO\b\2\2\2O"+ - "\5\3\2\2\2PQ\7\61\2\2QV\7\61\2\2RS\7/\2\2SV\7/\2\2TV\t\3\2\2UP\3\2\2\2"+ - "UR\3\2\2\2UT\3\2\2\2VZ\3\2\2\2WY\n\4\2\2XW\3\2\2\2Y\\\3\2\2\2ZX\3\2\2"+ - "\2Z[\3\2\2\2[\7\3\2\2\2\\Z\3\2\2\2]_\7\17\2\2^]\3\2\2\2^_\3\2\2\2_`\3"+ - "\2\2\2`a\7\f\2\2a\t\3\2\2\2bc\t\5\2\2c\13\3\2\2\2de\t\6\2\2e\r\3\2\2\2"+ - "fg\t\7\2\2g\17\3\2\2\2hi\t\b\2\2i\21\3\2\2\2jk\t\t\2\2k\23\3\2\2\2lm\t"+ - "\n\2\2m\25\3\2\2\2no\t\13\2\2o\27\3\2\2\2pq\t\f\2\2q\31\3\2\2\2rs\t\r"+ - "\2\2s\33\3\2\2\2tu\t\16\2\2u\35\3\2\2\2vw\t\17\2\2w\37\3\2\2\2xy\t\20"+ - "\2\2y!\3\2\2\2z{\t\21\2\2{#\3\2\2\2|}\t\22\2\2}%\3\2\2\2~\177\t\23\2\2"+ - "\177\'\3\2\2\2\u0080\u0081\t\24\2\2\u0081)\3\2\2\2\u0082\u0083\t\25\2"+ - "\2\u0083+\3\2\2\2\u0084\u0085\5\n\5\2\u0085\u0086\5\f\6\2\u0086\u0087"+ - "\5\16\7\2\u0087-\3\2\2\2\u0088\u0089\5\n\5\2\u0089\u008a\5\16\7\2\u008a"+ - "\u008b\5\20\b\2\u008b\u0095\3\2\2\2\u008c\u008d\5\n\5\2\u008d\u008e\5"+ - "\20\b\2\u008e\u008f\5\16\7\2\u008f\u0095\3\2\2\2\u0090\u0091\5\n\5\2\u0091"+ - "\u0092\5\f\6\2\u0092\u0093\5\20\b\2\u0093\u0095\3\2\2\2\u0094\u0088\3"+ - "\2\2\2\u0094\u008c\3\2\2\2\u0094\u0090\3\2\2\2\u0095/\3\2\2\2\u0096\u0097"+ - "\5\22\t\2\u0097\u0098\5\24\n\2\u0098\u0099\5\26\13\2\u0099\61\3\2\2\2"+ - "\u009a\u009b\5\30\f\2\u009b\u009c\5\32\r\2\u009c\u009d\5\34\16\2\u009d"+ - "\63\3\2\2\2\u009e\u009f\5\30\f\2\u009f\u00a0\5\36\17\2\u00a0\u00a1\5 "+ - "\20\2\u00a1\65\3\2\2\2\u00a2\u00a3\5\"\21\2\u00a3\u00a4\5\f\6\2\u00a4"+ - "\u00a5\5\16\7\2\u00a5\u00ab\3\2\2\2\u00a6\u00a7\5\30\f\2\u00a7\u00a8\5"+ - "$\22\2\u00a8\u00a9\5\26\13\2\u00a9\u00ab\3\2\2\2\u00aa\u00a2\3\2\2\2\u00aa"+ - "\u00a6\3\2\2\2\u00ab\67\3\2\2\2\u00ac\u00ad\5\30\f\2\u00ad\u00ae\5\32"+ - "\r\2\u00ae\u00af\5\16\7\2\u00af\u00b5\3\2\2\2\u00b0\u00b1\5&\23\2\u00b1"+ - "\u00b2\5\22\t\2\u00b2\u00b3\5\32\r\2\u00b3\u00b5\3\2\2\2\u00b4\u00ac\3"+ - "\2\2\2\u00b4\u00b0\3\2\2\2\u00b59\3\2\2\2\u00b6\u00b7\5\30\f\2\u00b7\u00b8"+ - "\5\32\r\2\u00b8\u00b9\5(\24\2\u00b9\u00ba\5\20\b\2\u00ba\u00bb\5\32\r"+ - "\2\u00bb;\3\2\2\2\u00bc\u00bd\5\26\13\2\u00bd\u00be\5\36\17\2\u00be\u00bf"+ - "\5\f\6\2\u00bf=\3\2\2\2\u00c0\u00c1\5 \20\2\u00c1\u00c2\5\26\13\2\u00c2"+ - "\u00c3\5\36\17\2\u00c3\u00c4\5\f\6\2\u00c4\u00cb\3\2\2\2\u00c5\u00c6\5"+ - " \20\2\u00c6\u00c7\5*\25\2\u00c7\u00c8\5\26\13\2\u00c8\u00c9\5\30\f\2"+ - "\u00c9\u00cb\3\2\2\2\u00ca\u00c0\3\2\2\2\u00ca\u00c5\3\2\2\2\u00cb\u00cc"+ - "\3\2\2\2\u00cc\u00cd\b\37\3\2\u00cd?\3\2\2\2\u00ce\u00d0\t\26\2\2\u00cf"+ - "\u00ce\3\2\2\2\u00cf\u00d0\3\2\2\2\u00d0\u00d2\3\2\2\2\u00d1\u00d3\t\27"+ - "\2\2\u00d2\u00d1\3\2\2\2\u00d3\u00d4\3\2\2\2\u00d4\u00d2\3\2\2\2\u00d4"+ - "\u00d5\3\2\2\2\u00d5A\3\2\2\2\u00d6\u00d8\t\26\2\2\u00d7\u00d6\3\2\2\2"+ - "\u00d7\u00d8\3\2\2\2\u00d8\u00dd\3\2\2\2\u00d9\u00da\7\62\2\2\u00da\u00de"+ - "\7z\2\2\u00db\u00dc\7\62\2\2\u00dc\u00de\7Z\2\2\u00dd\u00d9\3\2\2\2\u00dd"+ - "\u00db\3\2\2\2\u00de\u00e0\3\2\2\2\u00df\u00e1\t\30\2\2\u00e0\u00df\3"+ - "\2\2\2\u00e1\u00e2\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e2\u00e3\3\2\2\2\u00e3"+ - "C\3\2\2\2\u00e4\u00e5\13\2\2\2\u00e5E\3\2\2\2\u00e6\u00e7\t\2\2\2\u00e7"+ - "\u00e8\3\2\2\2\u00e8\u00e9\b#\2\2\u00e9G\3\2\2\2\u00ea\u00ec\t\31\2\2"+ - "\u00eb\u00ea\3\2\2\2\u00ec\u00ed\3\2\2\2\u00ed\u00eb\3\2\2\2\u00ed\u00ee"+ - "\3\2\2\2\u00ee\u00ef\3\2\2\2\u00ef\u00f0\b$\4\2\u00f0I\3\2\2\2\u00f1\u00f2"+ - "\13\2\2\2\u00f2K\3\2\2\2\21\2\3UZ^\u0094\u00aa\u00b4\u00ca\u00cf\u00d4"+ - "\u00d7\u00dd\u00e2\u00ed\5\2\3\2\7\3\2\6\2\2"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file diff --git a/plugins/compiler/as-z80/.gitignore b/plugins/compiler/as-z80/.gitignore index a37c70406..f6f374b4d 100644 --- a/plugins/compiler/as-z80/.gitignore +++ b/plugins/compiler/as-z80/.gitignore @@ -1,2 +1,3 @@ /src/main/antlr/gen/ /src/main/gen/ +*.tokens diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens b/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens deleted file mode 100644 index 4cbc1ea56..000000000 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Lexer.tokens +++ /dev/null @@ -1,178 +0,0 @@ -COMMENT=1 -COMMENT2=2 -OPCODE_ADC=3 -OPCODE_ADD=4 -OPCODE_AND=5 -OPCODE_BIT=6 -OPCODE_CALL=7 -OPCODE_CCF=8 -OPCODE_CP=9 -OPCODE_CPD=10 -OPCODE_CPDR=11 -OPCODE_CPI=12 -OPCODE_CPIR=13 -OPCODE_CPL=14 -OPCODE_DAA=15 -OPCODE_DEC=16 -OPCODE_DI=17 -OPCODE_DJNZ=18 -OPCODE_EI=19 -OPCODE_EX=20 -OPCODE_EXX=21 -OPCODE_HALT=22 -OPCODE_IM=23 -OPCODE_IN=24 -OPCODE_INC=25 -OPCODE_IND=26 -OPCODE_INDR=27 -OPCODE_INI=28 -OPCODE_INIR=29 -OPCODE_JP=30 -OPCODE_JR=31 -OPCODE_LD=32 -OPCODE_LDD=33 -OPCODE_LDDR=34 -OPCODE_LDI=35 -OPCODE_LDIR=36 -OPCODE_NEG=37 -OPCODE_NOP=38 -OPCODE_OR=39 -OPCODE_OTDR=40 -OPCODE_OTIR=41 -OPCODE_OUT=42 -OPCODE_OUTD=43 -OPCODE_OUTI=44 -OPCODE_POP=45 -OPCODE_PUSH=46 -OPCODE_RES=47 -OPCODE_RET=48 -OPCODE_RETI=49 -OPCODE_RETN=50 -OPCODE_RL=51 -OPCODE_RLA=52 -OPCODE_RLC=53 -OPCODE_RLCA=54 -OPCODE_RLD=55 -OPCODE_RR=56 -OPCODE_RRA=57 -OPCODE_RRC=58 -OPCODE_RRCA=59 -OPCODE_RRD=60 -OPCODE_RST=61 -OPCODE_SBC=62 -OPCODE_SCF=63 -OPCODE_SET=64 -OPCODE_SLA=65 -OPCODE_SRA=66 -OPCODE_SLL=67 -OPCODE_SRL=68 -OPCODE_SUB=69 -OPCODE_XOR=70 -COND_C=71 -COND_NC=72 -COND_Z=73 -COND_NZ=74 -COND_M=75 -COND_PE=76 -COND_PO=77 -COND_P=78 -COND_WS=79 -ERROR_COND=80 -IM_01=81 -IM_0=82 -IM_1=83 -IM_2=84 -IM_WS=85 -ERROR_IM=86 -PREP_ORG=87 -PREP_EQU=88 -PREP_VAR=89 -PREP_IF=90 -PREP_ENDIF=91 -PREP_INCLUDE=92 -PREP_MACRO=93 -PREP_ENDM=94 -PREP_DB=95 -PREP_DW=96 -PREP_DS=97 -PREP_ADDR=98 -REG_A=99 -REG_B=100 -REG_C=101 -REG_D=102 -REG_E=103 -REG_H=104 -REG_L=105 -REG_IX=106 -REG_IXH=107 -REG_IXL=108 -REG_IY=109 -REG_IYH=110 -REG_IYL=111 -REG_BC=112 -REG_DE=113 -REG_HL=114 -REG_SP=115 -REG_AF=116 -REG_AFF=117 -REG_I=118 -REG_R=119 -OP_MOD=120 -OP_SHR=121 -OP_SHL=122 -OP_NOT=123 -LIT_HEXNUMBER_1=124 -LIT_NUMBER=125 -LIT_HEXNUMBER_2=126 -LIT_OCTNUMBER=127 -LIT_BINNUMBER=128 -LIT_STRING_1=129 -LIT_STRING_2=130 -ID_IDENTIFIER=131 -ID_LABEL=132 -ERROR=133 -SEP_LPAR=134 -SEP_RPAR=135 -SEP_COMMA=136 -OP_ADD=137 -OP_SUBTRACT=138 -OP_MULTIPLY=139 -OP_DIVIDE=140 -OP_EQUAL=141 -OP_GT=142 -OP_GTE=143 -OP_LT=144 -OP_LTE=145 -OP_MOD_2=146 -OP_SHR_2=147 -OP_SHL_2=148 -OP_NOT_2=149 -OP_AND=150 -OP_OR=151 -OP_XOR=152 -WS=153 -EOL=154 -'0/1'=81 -'0'=82 -'1'=83 -'2'=84 -'$'=98 -'('=134 -')'=135 -','=136 -'+'=137 -'-'=138 -'*'=139 -'/'=140 -'='=141 -'>'=142 -'>='=143 -'<'=144 -'<='=145 -'%'=146 -'>>'=147 -'<<'=148 -'~'=149 -'&'=150 -'|'=151 -'^'=152 diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java index e448faa67..cf227d228 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java @@ -114,7 +114,6 @@ public boolean compile(String inputFileName, String outputFileName) { CommonTokenStream tokens = new CommonTokenStream(lexer); AsZ80Parser parser = createParser(tokens); - parser.removeErrorListeners(); parser.addErrorListener(new ParserErrorListener()); Program program = new Program(); diff --git a/plugins/compiler/brainc-brainduck/.gitignore b/plugins/compiler/brainc-brainduck/.gitignore index 05b38061e..f6f374b4d 100644 --- a/plugins/compiler/brainc-brainduck/.gitignore +++ b/plugins/compiler/brainc-brainduck/.gitignore @@ -1 +1,3 @@ -src/main/java/net/emustudio/plugins/compiler/brainc/LexerImpl.java +/src/main/antlr/gen/ +/src/main/gen/ +*.tokens diff --git a/plugins/compiler/brainc-brainduck/build.gradle b/plugins/compiler/brainc-brainduck/build.gradle index 74c65ace3..0cfacb981 100644 --- a/plugins/compiler/brainc-brainduck/build.gradle +++ b/plugins/compiler/brainc-brainduck/build.gradle @@ -21,15 +21,18 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'org.xbib.gradle.plugin.jflex' version "1.5.0" - id "com.github.andrescv.jcup" version "1.0" + id 'idea' + id 'antlr' id 'com.adarshr.test-logger' version '3.1.0' } dependencies { + antlr "org.antlr:antlr4:4.9.2" + implementation "org.antlr:antlr4-runtime:4.9.2" + implementation libs.emuLib - implementation libs.javaCupRuntime implementation libs.slf4JApi + implementation libs.jcipAnnotations testImplementation libs.cpuTestSuite testImplementation libs.junit @@ -37,28 +40,36 @@ dependencies { testImplementation libs.slf4JSimple } -sourceSets.main.java.srcDirs = [ - "${buildDir}/generated-sources/jflex", "${buildDir}/generated-sources/cup", 'src/main/java' -] +generateGrammarSource { + maxHeapSize = "128m" + arguments += ['-package', 'net.emustudio.plugins.compiler.brainduck', '-visitor', '-no-listener'] + outputDirectory = file("${buildDir}/generated-src/antlr/main/net/emustudio/plugins/compiler/brainduck") +} +compileJava.dependsOn generateGrammarSource -jflex { - no_backup = true +sourceSets { + generated { + java.srcDir "${buildDir}/generated-src/antlr/main" + } + main { + java.srcDirs = [ + 'src/main/java', "${buildDir}/generated-src/antlr/main" + ] + } } +compileJava.source sourceSets.generated.java, sourceSets.main.java -jcup { - input = file('src/main/cup/parser.cup') - destdir = file("${buildDir}/generated-sources/cup/net/emustudio/plugins/compiler/brainc") - parser = 'ParserImpl' - symbols = 'Symbols' - iface = true +idea { + module { + sourceDirs += file("build/generated-src/antlr") + } } jar { archiveVersion = '' manifest { - attributes manifestAttributes('net.emustudio.plugins.compiler.brainc.Runner') + attributes manifestAttributes('net.emustudio.plugins.compiler.brainduck.Runner') } - } processResources { diff --git a/plugins/compiler/brainc-brainduck/src/main/antlr/BraincLexer.g4 b/plugins/compiler/brainc-brainduck/src/main/antlr/BraincLexer.g4 new file mode 100644 index 000000000..0ddf3c2f2 --- /dev/null +++ b/plugins/compiler/brainc-brainduck/src/main/antlr/BraincLexer.g4 @@ -0,0 +1,15 @@ +lexer grammar BraincLexer; + +WS: [ \t\r\n] -> channel(HIDDEN); + +HALT: ';'; +INC: '>'; +DEC: '<'; +INCV: '+'; +DECV: '-'; +PRINT: '.'; +LOAD: ','; +LOOP: '['; +ENDL: ']'; + +COMMENT: .+?; diff --git a/plugins/compiler/brainc-brainduck/src/main/antlr/BraincParser.g4 b/plugins/compiler/brainc-brainduck/src/main/antlr/BraincParser.g4 new file mode 100644 index 000000000..d8517df45 --- /dev/null +++ b/plugins/compiler/brainc-brainduck/src/main/antlr/BraincParser.g4 @@ -0,0 +1,25 @@ +parser grammar BraincParser; + +options { + tokenVocab = BraincLexer; +} + +start: line* EOF + ; + +line: + command=statement COMMENT? + | COMMENT + ; + +statement: + instr=HALT + | instr=INC + | instr=DEC + | instr=INCV + | instr=DECV + | instr=PRINT + | instr=LOAD + | instr=LOOP + | instr=ENDL + ; diff --git a/plugins/compiler/brainc-brainduck/src/main/cup/parser.cup b/plugins/compiler/brainc-brainduck/src/main/cup/parser.cup deleted file mode 100644 index 7104bb86b..000000000 --- a/plugins/compiler/brainc-brainduck/src/main/cup/parser.cup +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.brainc; - -import java_cup.runtime.DefaultSymbolFactory; -import net.emustudio.emulib.plugins.compiler.CompilerMessage; -import net.emustudio.emulib.plugins.compiler.Token; -import net.emustudio.plugins.compiler.brainc.tree.Instruction; -import net.emustudio.plugins.compiler.brainc.tree.Program; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -parser code {: - private CompilerImpl compiler; - private boolean syntaxErrors; - - public ParserImpl(LexerImpl lexer, CompilerImpl compiler) { - super(lexer, new DefaultSymbolFactory()); - this.compiler = Objects.requireNonNull(compiler); - } - - public void reset() { - syntaxErrors = false; - } - - @Override - public void report_fatal_error(String message, Object info) throws Exception { - done_parsing(); - report_error(message, info); - throw new Exception("Can't recover from previous error(s)"); - } - - @Override - public void report_error(String messageText, Object current) { - syntaxErrors = true; - - Token token = (Token)current; - - messageText += ":" + token.getErrorString() + " ('" + token.getText() + "')"; - - List expectedTokenIds = expected_token_ids() - .stream() - .map(this::symbl_name_from_id) - .collect(Collectors.toList()); - - if (!expectedTokenIds.isEmpty()) { - messageText += "\nExpected tokens: " + expectedTokenIds; - } - - CompilerMessage message = new CompilerMessage( - CompilerMessage.MessageType.TYPE_ERROR, messageText, token.getLine()+1, token.getColumn() - ); - - compiler.notifyOnMessage(message); - } - - public boolean hasSyntaxErrors() { - return syntaxErrors; - } -:} - -terminal HALT,INC,DEC,INCV,DECV,PRINT,LOAD,LOOP,ENDL; -terminal TCOMMENT; - -non terminal Program Program; -non terminal Instruction Statement; - -start with Program; - -Program ::= Statement:statement - {: - Program program = new Program(); - if (statement != null) { - program.add(statement); - } - RESULT = program; - :} | - Program:program Statement:statement - {: - if (statement != null) { - program.add(statement); - } - RESULT = program; - :}; - -Statement ::= - INC {: RESULT = new Instruction(Instruction.INC); :} | - DEC {: RESULT = new Instruction(Instruction.DEC); :} | - INCV {: RESULT = new Instruction(Instruction.INCV); :} | - DECV {: RESULT = new Instruction(Instruction.DECV); :} | - PRINT {: RESULT = new Instruction(Instruction.PRINT); :} | - LOAD {: RESULT = new Instruction(Instruction.LOAD); :} | - LOOP {: RESULT = new Instruction(Instruction.LOOP); :} | - ENDL {: RESULT = new Instruction(Instruction.ENDL); :} | - HALT {: RESULT = new Instruction(Instruction.HALT); :} | - TCOMMENT {: RESULT = null; :} - ; - diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/TokenImpl.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/TokenImpl.java deleted file mode 100644 index 447e353b3..000000000 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/TokenImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.brainc; - -import java_cup.runtime.ComplexSymbolFactory.Location; -import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol; -import net.emustudio.emulib.plugins.compiler.Token; - -public class TokenImpl extends ComplexSymbol implements Token, Symbols { - private final int category; - private final int lexerState; - - public TokenImpl(int id, int category, int lexerState, String text, Location left, Location right) { - super(text, id, left, right); - this.category = category; - this.lexerState = lexerState; - } - - @Override - public int getID() { - return super.sym; - } - - @Override - public int getType() { - return category; - } - - @Override - public String getText() { - return getName(); - } - - @Override - public String getErrorString() { - return (getType() == ERROR) ? "Unknown token" : ""; - } - - @Override - public int getLine() { - return getLeft().getLine(); - } - - @Override - public int getColumn() { - return getLeft().getColumn(); - } - - @Override - public int getOffset() { - return getLeft().getOffset(); - } - - @Override - public int getLength() { - return getRight().getOffset() - getLeft().getOffset(); - } - - @Override - public int getLexerState() { - return lexerState; - } -} diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompileException.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompileException.java new file mode 100644 index 000000000..3a2a5f622 --- /dev/null +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompileException.java @@ -0,0 +1,17 @@ +package net.emustudio.plugins.compiler.brainduck; + +public class CompileException extends RuntimeException { + final int line; + final int column; + + public CompileException(int line, int column, String message) { + super(message); + this.line = line; + this.column = column; + } + + @Override + public String toString() { + return "line " + line + ":" + column + " " + super.getMessage(); + } +} diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/CompilerImpl.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerImpl.java similarity index 68% rename from plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/CompilerImpl.java rename to plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerImpl.java index f22a1d6e6..4108d2615 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/CompilerImpl.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerImpl.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.brainc; +package net.emustudio.plugins.compiler.brainduck; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; import net.emustudio.emulib.plugins.annotations.PluginRoot; @@ -28,8 +28,13 @@ import net.emustudio.emulib.runtime.ContextNotFoundException; import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.emulib.runtime.helpers.IntelHEX; -import net.emustudio.plugins.compiler.brainc.tree.Program; +import net.emustudio.emulib.runtime.io.IntelHEX; +import net.emustudio.plugins.compiler.brainduck.tree.Program; +import net.emustudio.plugins.compiler.brainduck.tree.ProgramParser; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.TokenStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,29 +42,17 @@ import java.io.Reader; import java.util.*; -@PluginRoot( - type = PLUGIN_TYPE.COMPILER, - title = "BrainDuck Compiler" -) +@PluginRoot(type = PLUGIN_TYPE.COMPILER, title = "BrainDuck Compiler") @SuppressWarnings("unused") public class CompilerImpl extends AbstractCompiler { private final static Logger LOGGER = LoggerFactory.getLogger(CompilerImpl.class); - private final static List SOURCE_FILE_EXTENSIONS = List.of( - new SourceFileExtension("b", "brainfuck language source (*.b)") - ); + private final static List SOURCE_FILE_EXTENSIONS = List.of(new SourceFileExtension("b", "brainfuck language source (*.b)")); - private final LexerImpl lexer; - private final ParserImpl parser; - - private MemoryContext memory; + private MemoryContext memory; private int programLocation; public CompilerImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); - - // lexer has to be reset WITH a reader object before compile - lexer = new LexerImpl(null); - parser = new ParserImpl(lexer, this); } @SuppressWarnings("unchecked") @@ -68,10 +61,8 @@ public void initialize() { Optional.ofNullable(applicationApi.getContextPool()).ifPresent(pool -> { try { memory = pool.getMemoryContext(pluginID, MemoryContext.class); - if (memory.getDataType() != Short.class) { - throw new InvalidContextException( - "Unexpected memory cell type. Expected Short but was: " + memory.getDataType() - ); + if (memory.getDataType() != Byte.class) { + throw new InvalidContextException("Unexpected memory cell type. Expected Byte but was: " + memory.getDataType()); } } catch (ContextNotFoundException | InvalidContextException e) { LOGGER.warn("Memory is not available", e); @@ -94,6 +85,12 @@ public String getDescription() { return "Compiler for esoteric architecture based on brainfuck."; } + @Override + public LexicalAnalyzer createLexer(String s) { + BraincLexer lexer = createLexer(CharStreams.fromString(s)); + return new LexicalAnalyzerImpl(lexer); + } + @Override public boolean compile(String inputFileName, String outputFileName) { try { @@ -102,10 +99,10 @@ public boolean compile(String inputFileName, String outputFileName) { hex.generate(outputFileName); notifyInfo("Compile was successful. Output: " + outputFileName); - programLocation = hex.getProgramLocation(); + programLocation = hex.findProgramLocation(); if (memory != null) { - hex.loadIntoMemory(memory); + hex.loadIntoMemory(memory, b -> b); notifyInfo("Compiled file was loaded into operating memory."); } else { notifyWarning("Memory is not available."); @@ -113,7 +110,8 @@ public boolean compile(String inputFileName, String outputFileName) { return true; } catch (Exception e) { LOGGER.trace("Compilation error", e); - notifyError("Compilation error: " + e.getMessage()); + notifyError("Compilation error: " + e); + e.printStackTrace(); return false; } finally { notifyCompileFinish(); @@ -140,11 +138,6 @@ public int getProgramLocation() { return programLocation; } - @Override - public LexicalAnalyzer getLexer(Reader in) { - return new LexerImpl(in); - } - @Override public List getSourceFileExtensions() { return SOURCE_FILE_EXTENSIONS; @@ -152,36 +145,41 @@ public List getSourceFileExtensions() { private IntelHEX compileToHex(String inputFileName) throws Exception { Objects.requireNonNull(inputFileName); - notifyInfo(getTitle() + ", version " + getVersion()); - Object parsedProgram; - IntelHEX hex = new IntelHEX(); - try (Reader reader = new FileReader(inputFileName)) { - lexer.reset(reader, 0, 0, 0); - parser.reset(); - parsedProgram = parser.parse().value; + org.antlr.v4.runtime.Lexer lexer = createLexer(CharStreams.fromReader(reader)); + lexer.addErrorListener(new ParserErrorListener()); + CommonTokenStream tokens = new CommonTokenStream(lexer); - if (parsedProgram == null) { - notifyError("Unexpected end of file"); - throw new Exception("Unexpected end of file"); - } - if (parser.hasSyntaxErrors()) { - throw new Exception("Program has errors"); - } + BraincParser parser = createParser(tokens); + parser.addErrorListener(new ParserErrorListener()); + + ProgramParser programParser = new ProgramParser(); + programParser.visit(parser.start()); + Program program = programParser.getProgram(); - // do several passes for compiling - Program program = (Program) parsedProgram; - program.firstPass(0); - program.secondPass(hex); + IntelHEX hex = new IntelHEX(); + program.generateCode(hex); return hex; } } + private BraincLexer createLexer(CharStream input) { + BraincLexer lexer = new BraincLexer(input); + lexer.removeErrorListeners(); + return lexer; + } + + private BraincParser createParser(TokenStream tokenStream) { + BraincParser parser = new BraincParser(tokenStream); + parser.removeErrorListeners(); + return parser; + } + private Optional getResourceBundle() { try { - return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.compiler.brainc.version")); + return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.compiler.brainduck.version")); } catch (MissingResourceException e) { return Optional.empty(); } diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java new file mode 100644 index 000000000..499c5db98 --- /dev/null +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java @@ -0,0 +1,68 @@ +package net.emustudio.plugins.compiler.brainduck; + +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; +import net.emustudio.emulib.plugins.compiler.Token; +import org.antlr.v4.runtime.CharStreams; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Objects; + +public class LexicalAnalyzerImpl implements LexicalAnalyzer { + private final BraincLexer lexer; + + public LexicalAnalyzerImpl(BraincLexer lexer) { + this.lexer = Objects.requireNonNull(lexer); + } + + @Override + public Token nextToken() { + org.antlr.v4.runtime.Token token = lexer.nextToken(); + return new Token() { + @Override + public int getType() { + return convertLexerTokenType(token.getType()); + } + + @Override + public int getOffset() { + return token.getStartIndex(); + } + + @Override + public String getText() { + return token.getText(); + } + }; + } + + @Override + public boolean isAtEOF() { + return lexer._hitEOF; + } + + @Override + public void reset(InputStream inputStream) throws IOException { + lexer.setInputStream(CharStreams.fromStream(inputStream)); + } + + private int convertLexerTokenType(int tokenType) { + switch (tokenType) { + case BraincLexer.COMMENT: + return Token.COMMENT; + case BraincLexer.WS: + return Token.WHITESPACE; + case BraincLexer.DEC: + case BraincLexer.DECV: + case BraincLexer.INC: + case BraincLexer.INCV: + case BraincLexer.PRINT: + case BraincLexer.LOAD: + case BraincLexer.LOOP: + return Token.RESERVED; + case BraincLexer.EOF: + return Token.EOF; + } + return Token.ERROR; + } +} diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ParserErrorListener.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ParserErrorListener.java new file mode 100644 index 000000000..e413d9e99 --- /dev/null +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ParserErrorListener.java @@ -0,0 +1,18 @@ +package net.emustudio.plugins.compiler.brainduck; + +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; + +class ParserErrorListener extends BaseErrorListener { + @Override + public void syntaxError( + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { + throw new CompileException(line, charPositionInLine, msg); + } +} diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/Runner.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/Runner.java similarity index 98% rename from plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/Runner.java rename to plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/Runner.java index d0b7b4bd0..59ed3e3f7 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/Runner.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/Runner.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.brainc; +package net.emustudio.plugins.compiler.brainduck; import net.emustudio.emulib.plugins.compiler.CompilerListener; import net.emustudio.emulib.plugins.compiler.CompilerMessage; diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/tree/Instruction.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Instruction.java similarity index 52% rename from plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/tree/Instruction.java rename to plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Instruction.java index d26cdd7d0..c60d60c1f 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/tree/Instruction.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Instruction.java @@ -16,31 +16,33 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.brainc.tree; +package net.emustudio.plugins.compiler.brainduck.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; +import net.emustudio.plugins.compiler.brainduck.BraincParser; + +import java.util.Map; public class Instruction { - public final static int HALT = 0; - public final static int INC = 1; - public final static int DEC = 2; - public final static int INCV = 3; - public final static int DECV = 4; - public final static int PRINT = 5; - public final static int LOAD = 6; - public final static int LOOP = 7; - public final static int ENDL = 8; - private final int instructionCode; - public Instruction(int instr) { - this.instructionCode = instr; - } + private final int instructionCode; - public int firstPass(int addressStart) { - return addressStart + 1; + public Instruction(int tokenType) { + Map tokenCodes = Map.of( + BraincParser.HALT, 0, + BraincParser.INC, 1, + BraincParser.DEC, 2, + BraincParser.INCV, 3, + BraincParser.DECV, 4, + BraincParser.PRINT, 5, + BraincParser.LOAD, 6, + BraincParser.LOOP, 7, + BraincParser.ENDL, 8 + ); + this.instructionCode = tokenCodes.get(tokenType); } - public void secondPass(IntelHEX hex) { - hex.putCode(String.format("%1$02X", instructionCode)); + public void generateCode(IntelHEX hex) { + hex.add(String.format("%1$02X", instructionCode)); } } diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/tree/Program.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Program.java similarity index 67% rename from plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/tree/Program.java rename to plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Program.java index 18e29db7d..1b03c68a1 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainc/tree/Program.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Program.java @@ -16,20 +16,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.brainc.tree; +package net.emustudio.plugins.compiler.brainduck.tree; -import net.emustudio.emulib.runtime.helpers.IntelHEX; +import net.emustudio.emulib.runtime.io.IntelHEX; import java.util.ArrayList; import java.util.List; public class Program { - - private List instructions; - - public Program() { - instructions = new ArrayList<>(); - } + private final List instructions = new ArrayList<>(); public void add(Instruction instruction) { if (instruction != null) { @@ -37,15 +32,9 @@ public void add(Instruction instruction) { } } - public void firstPass(int addressStart) { - for (Instruction instruction : instructions) { - addressStart = instruction.firstPass(addressStart); - } - } - - public void secondPass(IntelHEX hex) { + public void generateCode(IntelHEX hex) { for (Instruction instruction : instructions) { - instruction.secondPass(hex); + instruction.generateCode(hex); } } } diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/ProgramParser.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/ProgramParser.java new file mode 100644 index 000000000..1c00bd0fb --- /dev/null +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/ProgramParser.java @@ -0,0 +1,21 @@ +package net.emustudio.plugins.compiler.brainduck.tree; + +import net.emustudio.plugins.compiler.brainduck.BraincParser; +import net.emustudio.plugins.compiler.brainduck.BraincParserBaseVisitor; + +public class ProgramParser extends BraincParserBaseVisitor { + private final Program program = new Program(); + + public Program getProgram() { + return program; + } + + @Override + public Program visitStatement(BraincParser.StatementContext ctx) { + if (ctx.instr != null) { + Instruction instruction = new Instruction(ctx.instr.getType()); + program.add(instruction); + } + return program; + } +} diff --git a/plugins/compiler/brainc-brainduck/src/main/jflex/lexer.jflex b/plugins/compiler/brainc-brainduck/src/main/jflex/lexer.jflex deleted file mode 100644 index 3ab18e72e..000000000 --- a/plugins/compiler/brainc-brainduck/src/main/jflex/lexer.jflex +++ /dev/null @@ -1,95 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.brainc; - -import java_cup.runtime.ComplexSymbolFactory.Location; -import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; -import net.emustudio.emulib.plugins.compiler.Token; - -import java.io.Reader; -import java.io.IOException; - -%% - -/* options */ -%class LexerImpl -%cup -%public -%implements LexicalAnalyzer -%line -%column -%char -%caseless -%unicode -%type TokenImpl - -%{ - @Override - public Token getToken() throws IOException { - return next_token(); - } - - @Override - public void reset(Reader in, int yyline, int yychar, int yycolumn) { - yyreset(in); - this.yyline = yyline; - this.yychar = yychar; - this.yycolumn = yycolumn; - } - - @Override - public void reset(Reader in, int line, int offset, int column, int lexerState) { - yyreset(in); - this.yyline = line; - this.yychar = offset; - this.yycolumn = column; - this.zzLexicalState = lexerState; - } - - private TokenImpl token(int id, int category) { - Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); - return new TokenImpl(id, category, zzLexicalState, yytext(), left, right); - } -%} -%eofval{ - return token(TokenImpl.EOF, Token.TEOF); -%eofval} - -LineTerminator = \r|\n|\r\n -InputCharacter = [^\r\n] -WhiteSpace = {LineTerminator} | [ \t\f] - -Comment = [^<>+\-\.,\[\]; \t\f\r\n]+ {InputCharacter}* - -%% - -";" { return token(TokenImpl.HALT, Token.RESERVED); } -">" { return token(TokenImpl.INC, Token.RESERVED); } -"<" { return token(TokenImpl.DEC, Token.RESERVED); } -"+" { return token(TokenImpl.INCV, Token.RESERVED); } -"-" { return token(TokenImpl.DECV, Token.RESERVED); } -"." { return token(TokenImpl.PRINT,Token.RESERVED); } -"," { return token(TokenImpl.LOAD, Token.RESERVED); } -"[" { return token(TokenImpl.LOOP, Token.RESERVED); } -"]" { return token(TokenImpl.ENDL, Token.RESERVED); } - -{Comment} { return token(TokenImpl.TCOMMENT, Token.COMMENT); } -{WhiteSpace}+ { return token(TokenImpl.TCOMMENT, Token.COMMENT); } -{LineTerminator}+ { return token(TokenImpl.TCOMMENT, Token.COMMENT); } diff --git a/plugins/compiler/brainc-brainduck/src/main/resources/net/emustudio/plugins/compiler/brainc/version.properties b/plugins/compiler/brainc-brainduck/src/main/resources/net/emustudio/plugins/compiler/brainduck/version.properties similarity index 100% rename from plugins/compiler/brainc-brainduck/src/main/resources/net/emustudio/plugins/compiler/brainc/version.properties rename to plugins/compiler/brainc-brainduck/src/main/resources/net/emustudio/plugins/compiler/brainduck/version.properties diff --git a/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainc/AbstractCompilerTest.java b/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/AbstractCompilerTest.java similarity index 80% rename from plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainc/AbstractCompilerTest.java rename to plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/AbstractCompilerTest.java index 2e9c245c9..c8391b727 100644 --- a/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainc/AbstractCompilerTest.java +++ b/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/AbstractCompilerTest.java @@ -16,16 +16,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.brainc; +package net.emustudio.plugins.compiler.brainduck; +import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.cpu.testsuite.memory.MemoryStub; -import net.emustudio.cpu.testsuite.memory.ShortMemoryStub; +import net.emustudio.emulib.plugins.compiler.CompilerListener; +import net.emustudio.emulib.plugins.compiler.CompilerMessage; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; -import net.emustudio.plugins.compiler.brainc.CompilerImpl; import org.junit.Before; import org.junit.Rule; import org.junit.rules.TemporaryFolder; @@ -39,7 +40,7 @@ public abstract class AbstractCompilerTest { protected CompilerImpl compiler; - protected MemoryStub memoryStub; + protected MemoryStub memoryStub; @Rule public TemporaryFolder folder = new TemporaryFolder(); @@ -47,7 +48,7 @@ public abstract class AbstractCompilerTest { @SuppressWarnings("unchecked") @Before public void setUp() throws Exception { - memoryStub = new ShortMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); + memoryStub = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); ContextPool pool = createNiceMock(ContextPool.class); expect(pool.getMemoryContext(0, MemoryContext.class)).andReturn(memoryStub).anyTimes(); @@ -58,6 +59,20 @@ public void setUp() throws Exception { replay(applicationApi); compiler = new CompilerImpl(0L, applicationApi, PluginSettings.UNAVAILABLE); + compiler.addCompilerListener(new CompilerListener() { + @Override + public void onStart() { + } + + @Override + public void onMessage(CompilerMessage message) { + System.out.println(message); + } + + @Override + public void onFinish() { + } + }); compiler.initialize(); } diff --git a/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainc/InstructionTest.java b/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/InstructionTest.java similarity index 95% rename from plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainc/InstructionTest.java rename to plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/InstructionTest.java index 27c0dab63..cd911f56f 100644 --- a/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainc/InstructionTest.java +++ b/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/InstructionTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.brainc; +package net.emustudio.plugins.compiler.brainduck; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; @@ -71,12 +71,11 @@ public void testCompileProgramWithComments() throws Exception { } @Test - public void testProgramAfterCommentDoesNotWork() throws Exception { + public void testProgramAfterCommentWorks() throws Exception { compile( "So this is the comment and program >>\n" ); - - assertProgram(); + assertProgram(1, 1); } @SuppressWarnings("unchecked") diff --git a/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainc/RunnerTest.java b/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/RunnerTest.java similarity index 97% rename from plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainc/RunnerTest.java rename to plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/RunnerTest.java index 615a056dc..199ba4dd7 100644 --- a/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainc/RunnerTest.java +++ b/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/RunnerTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.brainc; +package net.emustudio.plugins.compiler.brainduck; import org.junit.Rule; import org.junit.Test; diff --git a/plugins/cpu/brainduck-cpu/build.gradle b/plugins/cpu/brainduck-cpu/build.gradle index d7bd526fe..1e3e4d029 100644 --- a/plugins/cpu/brainduck-cpu/build.gradle +++ b/plugins/cpu/brainduck-cpu/build.gradle @@ -33,7 +33,7 @@ repositories { dependencies { implementation libs.emuLib implementation libs.slf4JApi - memoryLib project(":plugins:memory:brainduck-mem") + memoryLib project(":plugins:memory:byte-mem") testImplementation libs.cpuTestSuite testImplementation libs.junit diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/CpuImpl.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/CpuImpl.java index 021f4c0e2..fd2e847d9 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/CpuImpl.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/CpuImpl.java @@ -30,7 +30,7 @@ import net.emustudio.plugins.cpu.brainduck.gui.DecoderImpl; import net.emustudio.plugins.cpu.brainduck.gui.DisassemblerImpl; import net.emustudio.plugins.cpu.brainduck.gui.StatusPanel; -import net.emustudio.plugins.memory.brainduck.api.RawMemoryContext; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,10 +40,7 @@ import java.util.Optional; import java.util.ResourceBundle; -@PluginRoot( - type = PLUGIN_TYPE.CPU, - title = "BrainDuck CPU" -) +@PluginRoot(type = PLUGIN_TYPE.CPU, title = "BrainDuck CPU") @SuppressWarnings("unused") public class CpuImpl extends AbstractCPU { private static final Logger LOGGER = LoggerFactory.getLogger(CpuImpl.class); @@ -51,7 +48,7 @@ public class CpuImpl extends AbstractCPU { private final BrainCPUContextImpl context = new BrainCPUContextImpl(); private Disassembler disassembler; - private RawMemoryContext memory; + private ByteMemoryContext memory; private EmulatorEngine engine; private volatile boolean optimize; @@ -61,9 +58,7 @@ public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings sett applicationApi.getContextPool().register(pluginID, context, BrainCPUContext.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register CPU context", e); - applicationApi.getDialogs().showError( - "Could not register CPU context. Please see log file for details", getTitle() - ); + applicationApi.getDialogs().showError("Could not register CPU context. Please see log file for details", getTitle()); } } @@ -84,7 +79,7 @@ public String getDescription() { @Override public void initialize() throws PluginInitializationException { - memory = applicationApi.getContextPool().getMemoryContext(pluginID, RawMemoryContext.class); + memory = applicationApi.getContextPool().getMemoryContext(pluginID, ByteMemoryContext.class); disassembler = new DisassemblerImpl(memory, new DecoderImpl(memory)); engine = new EmulatorEngine(memory, context, new Profiler(memory)); diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java index 35b1f4b98..7d8b4bc93 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java @@ -20,7 +20,7 @@ package net.emustudio.plugins.cpu.brainduck; import net.emustudio.emulib.plugins.cpu.CPU; -import net.emustudio.plugins.memory.brainduck.api.RawMemoryContext; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import java.io.IOException; import java.util.ArrayDeque; @@ -37,8 +37,8 @@ public class EmulatorEngine { final static byte I_READ = 6; // , final static byte I_LOOP_START = 7; // [ final static byte I_LOOP_END = 8; // ] - final static byte I_COPY_AND_CLEAR = (byte)0xA1; // any copyloop, including clear - final static byte I_SCANLOOP = (byte)0xA2; // [<] or [>] + final static byte I_COPY_AND_CLEAR = (byte) 0xA1; // any copyloop, including clear + final static byte I_SCANLOOP = (byte) 0xA2; // [<] or [>] private final Byte[] rawMemory; private final BrainCPUContextImpl context; @@ -47,8 +47,8 @@ public class EmulatorEngine { public volatile int IP, P; // registers of the CPU - EmulatorEngine(RawMemoryContext memory, BrainCPUContextImpl context, Profiler profiler) { - this.rawMemory = memory.getRawMemory(); + EmulatorEngine(ByteMemoryContext memory, BrainCPUContextImpl context, Profiler profiler) { + this.rawMemory = Objects.requireNonNull(Objects.requireNonNull(memory.getRawMemory())[0]); this.context = Objects.requireNonNull(context); this.profiler = Objects.requireNonNull(profiler); } @@ -144,8 +144,7 @@ CPU.RunState step(boolean optimize) throws IOException { } else if (copyLoop.specialOP == I_READ) { rawMemory[P] = context.readFromDevice(); } else { - rawMemory[P + copyLoop.relativePosition] = (byte) - ((rawMemory[P] * copyLoop.factor + rawMemory[P + copyLoop.relativePosition]) & 0xFF); + rawMemory[P + copyLoop.relativePosition] = (byte) ((rawMemory[P] * copyLoop.factor + rawMemory[P + copyLoop.relativePosition]) & 0xFF); } } rawMemory[P] = 0; diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java index 8bb80a0a9..daaa2b572 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java @@ -19,7 +19,7 @@ package net.emustudio.plugins.cpu.brainduck; -import net.emustudio.plugins.memory.brainduck.api.RawMemoryContext; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,8 +87,8 @@ public String toString() { } } - Profiler(RawMemoryContext memory) { - this.memory = Objects.requireNonNull(memory.getRawMemory()); + Profiler(ByteMemoryContext memory) { + this.memory = Objects.requireNonNull(memory.getRawMemory())[0]; loopEndsCache = new Integer[this.memory.length]; operationsCache = new CachedOperation[this.memory.length]; diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/MemoryTableModel.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/MemoryTableModel.java index ed75fac54..ca69d9b4f 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/MemoryTableModel.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/MemoryTableModel.java @@ -18,16 +18,15 @@ */ package net.emustudio.plugins.cpu.brainduck.gui; -import net.emustudio.plugins.memory.brainduck.api.RawMemoryContext; - import javax.swing.table.AbstractTableModel; +import java.util.Objects; public class MemoryTableModel extends AbstractTableModel { private final Byte[] memory; private volatile int P; - MemoryTableModel(RawMemoryContext memory) { - this.memory = memory.getRawMemory(); + MemoryTableModel(Byte[] memory) { + this.memory = Objects.requireNonNull(memory); } @Override diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java index 4d1a84013..7728026a4 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java @@ -21,7 +21,7 @@ import net.emustudio.emulib.plugins.cpu.CPU; import net.emustudio.plugins.cpu.brainduck.CpuImpl; import net.emustudio.plugins.cpu.brainduck.EmulatorEngine; -import net.emustudio.plugins.memory.brainduck.api.RawMemoryContext; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import javax.swing.*; import javax.swing.table.DefaultTableModel; @@ -87,10 +87,10 @@ public void internalStateChanged() { } - public StatusPanel(RawMemoryContext memory, CpuImpl cpu) { - this.memory = memory.getRawMemory(); + public StatusPanel(ByteMemoryContext memory, CpuImpl cpu) { + this.memory = memory.getRawMemory()[0]; this.cpu = cpu.getEngine(); - this.tableModel = new MemoryTableModel(memory); + this.tableModel = new MemoryTableModel(this.memory); initComponents(); tblMemory.setModel(tableModel); @@ -261,7 +261,7 @@ private void initComponents() { "00", "01", "02", "03", "04" } ) { - Class[] types = new Class[]{ + final Class[] types = new Class[]{ java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class }; diff --git a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java index 6068df620..f0f8f1f4f 100644 --- a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java +++ b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java @@ -23,7 +23,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.plugins.memory.brainduck.api.RawMemoryContext; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import org.easymock.Capture; import org.junit.After; import org.junit.Before; @@ -50,7 +50,7 @@ public void setUp() throws Exception { Capture cpuContextCapture = Capture.newInstance(); ContextPool contextPool = createNiceMock(ContextPool.class); - expect(contextPool.getMemoryContext(0, RawMemoryContext.class)).andReturn(memory).anyTimes(); + expect(contextPool.getMemoryContext(0, ByteMemoryContext.class)).andReturn(memory).anyTimes(); expect(contextPool.getMemoryContext(0, MemoryContext.class)).andReturn(memory).anyTimes(); contextPool.register(eq(0L), capture(cpuContextCapture), same(BrainCPUContext.class)); expectLastCall().once(); diff --git a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java index 446d511e4..e3ab79755 100644 --- a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java +++ b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java @@ -18,23 +18,27 @@ */ package net.emustudio.plugins.cpu.brainduck; -import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; import net.emustudio.emulib.plugins.annotations.PluginContext; -import net.emustudio.emulib.runtime.helpers.NumberUtils; -import net.emustudio.plugins.memory.brainduck.api.RawMemoryContext; +import net.emustudio.emulib.plugins.memory.Memory; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; @PluginContext -public class MemoryStub extends ByteMemoryStub implements RawMemoryContext { +public class MemoryStub implements ByteMemoryContext { + protected Byte[][] memory = new Byte[1][1000]; private int afterProgram; - MemoryStub() { - super(NumberUtils.Strategy.LITTLE_ENDIAN); + public MemoryStub() { + clear(); } void setProgram(byte[] program) { clear(); for (afterProgram = 0; afterProgram < program.length; afterProgram++) { - memory[afterProgram] = program[afterProgram]; + memory[0][afterProgram] = program[afterProgram]; } } @@ -44,13 +48,105 @@ int getDataStart() { void setData(byte[] data) { for (int i = 0; i < data.length; i++) { - memory[afterProgram + 1 + i] = data[i]; + memory[0][afterProgram + 1 + i] = data[i]; } } @Override - public Byte[] getRawMemory() { + public boolean isReadOnly(int address) { + return false; + } + + @Override + public List getReadOnly() { + return Collections.emptyList(); + } + + @Override + public void setReadWrite(AddressRange range) { + + } + + @Override + public void setReadOnly(AddressRange range) { + + } + + @Override + public int getBanksCount() { + return 0; + } + + @Override + public int getSelectedBank() { + return 0; + } + + @Override + public void selectBank(int bankIndex) { + + } + + @Override + public int getCommonBoundary() { + return 0; + } + + @Override + public Byte[][] getRawMemory() { return memory; } + @Override + public void clear() { + Arrays.fill(this.memory[0], (byte) 0); + } + + @Override + public void addMemoryListener(Memory.MemoryListener listener) { + } + + @Override + public void removeMemoryListener(Memory.MemoryListener listener) { + } + + @Override + public int getSize() { + return this.memory.length; + } + + @Override + public boolean areMemoryNotificationsEnabled() { + return false; + } + + @Override + public void setMemoryNotificationsEnabled(boolean enabled) { + } + + @Override + public Byte read(int memoryPosition) { + return this.memory[0][memoryPosition]; + } + + @Override + public Byte[] read(int memoryPosition, int count) { + int to = Math.min(this.memory.length, memoryPosition + count); + return Arrays.copyOfRange(this.memory[0], memoryPosition, to); + } + + @Override + public void write(int memoryPosition, Byte value) { + this.memory[0][memoryPosition] = value; + } + + @Override + public void write(int memoryPosition, Byte[] cells, int count) { + System.arraycopy(cells, 0, this.memory[0], memoryPosition, count); + } + + @Override + public Class getDataType() { + return null; + } } diff --git a/plugins/memory/brainduck-mem/README.md b/plugins/memory/brainduck-mem/README.md deleted file mode 100644 index c458b5a3d..000000000 --- a/plugins/memory/brainduck-mem/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# brainduck-mem - -This project is emulator of abstract "memory" for BrainDuck architecture. -It is part of [emuStudio](https://www.emustudio.net/). - -The official documentation can be found [here](https://www.emustudio.net/docuser/brainduck/index/#memory-code-brainduck-mem-code) diff --git a/plugins/memory/brainduck-mem/build.gradle b/plugins/memory/brainduck-mem/build.gradle deleted file mode 100644 index 0b8a975ae..000000000 --- a/plugins/memory/brainduck-mem/build.gradle +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import org.apache.tools.ant.filters.ReplaceTokens - -plugins { - id 'java' - id 'com.adarshr.test-logger' version '3.1.0' -} - -dependencies { - implementation libs.emuLib - implementation libs.slf4JApi - - testImplementation libs.junit - testImplementation libs.slf4JSimple - testImplementation libs.easyMock -} - -jar { - archiveVersion = '' - manifest { - attributes manifestAttributes('') - } -} - -processResources { - filesMatching("**/*.properties") { - filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") - ] - } -} - -compileJava.options.encoding = 'UTF-8' -compileTestJava.options.encoding = 'UTF-8' -javadoc.options.encoding = 'UTF-8' diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java deleted file mode 100644 index 491583d81..000000000 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryContextImpl.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.memory.brainduck; - -import net.emustudio.emulib.plugins.memory.AbstractMemoryContext; -import net.emustudio.plugins.memory.brainduck.api.RawMemoryContext; - -import java.util.Arrays; - -public class MemoryContextImpl extends AbstractMemoryContext implements RawMemoryContext { - private final Byte[] memory = new Byte[65536]; - - @Override - public void clear() { - Arrays.fill(memory, (byte) 0); - notifyMemoryChanged(-1); // notify that all memory has changed - } - - @Override - public Byte read(int from) { - return memory[from]; - } - - @Override - public Byte[] read(int from, int count) { - int to = Math.min(memory.length, from + count); - return Arrays.copyOfRange(memory, from, to); - } - - @Override - public void write(int to, Byte value) { - memory[to] = value; - notifyMemoryChanged(to); - } - - @Override - public void write(int to, Byte[] values, int count) { - System.arraycopy(values, 0, memory, to, count); - for (int i = 0; i < values.length; i++) { - notifyMemoryChanged(to + i); - } - } - - @Override - public Class getDataType() { - return Byte.class; - } - - @Override - public int getSize() { - return memory.length; - } - - @Override - public Byte[] getRawMemory() { - return memory; - } -} diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryImpl.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryImpl.java deleted file mode 100644 index ed8be0189..000000000 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/MemoryImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.memory.brainduck; - -import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; -import net.emustudio.emulib.plugins.annotations.PluginRoot; -import net.emustudio.emulib.plugins.memory.AbstractMemory; -import net.emustudio.emulib.plugins.memory.MemoryContext; -import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; -import net.emustudio.emulib.runtime.InvalidContextException; -import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.plugins.memory.brainduck.api.RawMemoryContext; -import net.emustudio.plugins.memory.brainduck.gui.MemoryGui; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.swing.*; -import java.util.MissingResourceException; -import java.util.Optional; -import java.util.ResourceBundle; - -@PluginRoot( - type = PLUGIN_TYPE.MEMORY, - title = "BrainDuck memory" -) -@SuppressWarnings("unused") -public class MemoryImpl extends AbstractMemory { - private static final Logger LOGGER = LoggerFactory.getLogger(MemoryImpl.class); - - private final MemoryContextImpl memContext = new MemoryContextImpl(); - private MemoryGui memoryGUI; - private final boolean guiNotSupported; - - public MemoryImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { - super(pluginID, applicationApi, settings); - - this.guiNotSupported = settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); - try { - applicationApi.getContextPool().register(pluginID, memContext, RawMemoryContext.class); - applicationApi.getContextPool().register(pluginID, memContext, MemoryContext.class); - } catch (InvalidContextException | ContextAlreadyRegisteredException e) { - LOGGER.error("Could not register memory context", e); - applicationApi.getDialogs().showError( - "Could not register BrainDuck memory. Please see log file for details.", getTitle() - ); - } - } - - @Override - public String getVersion() { - return getResourceBundle().map(b -> b.getString("version")).orElse("(unknown)"); - } - - @Override - public String getCopyright() { - return getResourceBundle().map(b -> b.getString("copyright")).orElse("(unknown)"); - } - - @Override - public String getDescription() { - return "Operating memory for abstract BrainDuck architecture"; - } - - @Override - public void destroy() { - } - - @Override - public int getSize() { - return memContext.getSize(); - } - - @Override - public void showSettings(JFrame parent) { - if (!guiNotSupported) { - if (memoryGUI == null) { - memoryGUI = new MemoryGui(parent, memContext); - } - memoryGUI.setVisible(true); - } - } - - @Override - public boolean isShowSettingsSupported() { - return !guiNotSupported; - } - - private Optional getResourceBundle() { - try { - return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.memory.brainduck.version")); - } catch (MissingResourceException e) { - return Optional.empty(); - } - } -} diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/api/RawMemoryContext.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/api/RawMemoryContext.java deleted file mode 100644 index a480921b6..000000000 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/api/RawMemoryContext.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.emustudio.plugins.memory.brainduck.api; - -import net.emustudio.emulib.plugins.annotations.PluginContext; -import net.emustudio.emulib.plugins.memory.MemoryContext; - -@PluginContext(id = "BrainDuck Raw Memory") -public interface RawMemoryContext extends MemoryContext { - - /** - * Returns raw memory represented by Java array. - *

- * Memory notifications must be handled manually if this array changes. - * - * @return raw memory - */ - Byte[] getRawMemory(); -} diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/Constants.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/Constants.java deleted file mode 100644 index ba9b68626..000000000 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/Constants.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.emustudio.plugins.memory.brainduck.gui; - -import java.awt.*; - -public class Constants { - public static Font MONOSPACED_PLAIN = new Font(Font.MONOSPACED, Font.PLAIN, 12); - public static Font MONOSPACED_BOLD = new Font(Font.MONOSPACED, Font.BOLD, 12); -} diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryGui.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryGui.java deleted file mode 100644 index 070403a27..000000000 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryGui.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.memory.brainduck.gui; - -import net.emustudio.emulib.plugins.memory.Memory; -import net.emustudio.emulib.plugins.memory.MemoryContext; - -import javax.swing.*; -import java.awt.event.KeyEvent; -import java.util.Objects; - -public class MemoryGui extends JDialog { - private final MemoryTableModel tableModel; - private final MemoryContext memory; - - private class MemoryListenerImpl implements Memory.MemoryListener { - - @Override - public void memoryChanged(int memoryPosition) { - tableModel.dataChangedAt(memoryPosition); - } - - @Override - public void memorySizeChanged() { - tableModel.fireTableDataChanged(); - } - } - - public MemoryGui(JFrame parent, MemoryContext memory) { - super(parent, false); - setLocationRelativeTo(parent); - initComponents(); - - this.memory = Objects.requireNonNull(memory); - this.tableModel = new MemoryTableModel(memory); - MemoryTable table = new MemoryTable(tableModel, scrollPane); - scrollPane.setViewportView(table); - - lblPageCount.setText(String.valueOf(tableModel.getPageCount())); - - memory.addMemoryListener(new MemoryListenerImpl()); - } - - - private void initComponents() { - scrollPane = new JScrollPane(); - JPanel jPanel1 = new JPanel(); - JButton btnPageDown = new JButton(); - JButton btnPageUp = new JButton(); - JLabel jLabel1 = new JLabel(); - JLabel jLabel2 = new JLabel(); - lblPageCount = new JLabel(); - txtPage = new JTextField(); - JButton btnClear = new JButton(); - - setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); - - setTitle("BrainDuck Memory"); - - btnPageDown.setText("Page Down"); - btnPageDown.addActionListener(this::btnPageDownActionPerformed); - - btnPageUp.setText("Page Up"); - btnPageUp.setToolTipText(""); - btnPageUp.addActionListener(this::btnPageUpActionPerformed); - - jLabel1.setFont(jLabel1.getFont()); - jLabel1.setText("Page:"); - - jLabel2.setText("/"); - - lblPageCount.setText("0"); - - txtPage.setText("0"); - txtPage.addActionListener(this::txtPageActionPerformed); - - btnClear.setText("Clear"); - btnClear.addActionListener(this::btnClearActionPerformed); - - GroupLayout jPanel1Layout = new GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtPage, GroupLayout.PREFERRED_SIZE, 48, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel2) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblPageCount) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 332, Short.MAX_VALUE) - .addComponent(btnClear) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnPageUp) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnPageDown)) - ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addGap(0, 12, Short.MAX_VALUE) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(btnPageDown) - .addComponent(btnPageUp) - .addComponent(jLabel1) - .addComponent(jLabel2) - .addComponent(lblPageCount) - .addComponent(txtPage, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(btnClear))) - ); - - GroupLayout layout = new GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(scrollPane) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 323, Short.MAX_VALUE)) - ); - - pack(); - } - - private void btnPageUpActionPerformed(java.awt.event.ActionEvent evt) { - int page = tableModel.getPage() - 1; - if (page >= 0) { - tableModel.setPage(page); - } - - txtPage.setText(String.valueOf(tableModel.getPage())); - } - - private void btnPageDownActionPerformed(java.awt.event.ActionEvent evt) { - int page = tableModel.getPage() + 1; - if (page < tableModel.getPageCount()) { - tableModel.setPage(page); - } - - txtPage.setText(String.valueOf(tableModel.getPage())); - } - - private void txtPageActionPerformed(java.awt.event.ActionEvent evt) { - int page = Integer.decode(evt.getActionCommand()); - if (page >= 0 && page < tableModel.getPageCount()) { - tableModel.setPage(page); - } - - txtPage.setText(String.valueOf(tableModel.getPage())); - } - - private void btnClearActionPerformed(java.awt.event.ActionEvent evt) { - memory.clear(); - tableModel.fireTableDataChanged(); - } - - private JLabel lblPageCount; - private JScrollPane scrollPane; - private JTextField txtPage; -} diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTable.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTable.java deleted file mode 100644 index 991d1c360..000000000 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTable.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.memory.brainduck.gui; - -import javax.swing.*; -import javax.swing.table.JTableHeader; -import javax.swing.table.TableCellEditor; -import javax.swing.table.TableCellRenderer; -import javax.swing.table.TableColumn; -import java.awt.*; - -import static net.emustudio.emulib.runtime.helpers.RadixUtils.formatWordHexString; -import static net.emustudio.plugins.memory.brainduck.gui.Constants.MONOSPACED_PLAIN; - -class MemoryTable extends JTable { - private final static int CHAR_WIDTH = 17; - - private final MemoryTableModel model; - private final JScrollPane scrollPane; - - MemoryTable(MemoryTableModel model, JScrollPane scrollPane) { - this.scrollPane = scrollPane; - this.model = model; - this.setModel(this.model); - this.setFont(MONOSPACED_PLAIN); - this.setCellSelectionEnabled(true); - this.setFocusCycleRoot(true); - this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - this.getTableHeader().setFont(MONOSPACED_PLAIN); - this.setDefaultRenderer(Object.class, new MemCellRenderer()); - - MemoryCellEditor ed = new MemoryCellEditor(); - for (int i = 0; i < model.getColumnCount(); i++) { - TableColumn col = this.getColumnModel().getColumn(i); - col.setPreferredWidth(3 * CHAR_WIDTH); - col.setCellEditor(ed); - } - } - - private static class MemRowHeaderRenderer extends JLabel implements ListCellRenderer { - - MemRowHeaderRenderer(JTable table) { - JTableHeader header = table.getTableHeader(); - setBorder(UIManager.getBorder("TableHeader.cellBorder")); - setHorizontalAlignment(CENTER); - setForeground(header.getForeground()); - setBackground(header.getBackground()); - setFont(MONOSPACED_PLAIN); - setPreferredSize(new Dimension(4 * CHAR_WIDTH, header.getPreferredSize().height)); - } - - @Override - public Component getListCellRendererComponent(JList list, String value, int index, - boolean isSelected, boolean cellHasFocus) { - setText((value == null) ? "" : value); - return this; - } - } - - private class MemCellRenderer extends JLabel implements TableCellRenderer { - private final JList rowHeader; - private final String[] adresses; - private int currentPage; - - MemCellRenderer() { - currentPage = model.getPage(); - adresses = new String[model.getRowCount()]; - for (int i = 0; i < adresses.length; i++) { - adresses[i] = formatWordHexString( - model.getColumnCount() * i + model.getColumnCount() * model.getRowCount() * currentPage - ) + "h"; - } - rowHeader = new JList<>(adresses); - this.setFont(MONOSPACED_PLAIN); - - FontMetrics fm = rowHeader.getFontMetrics(rowHeader.getFont()); - int char_width = CHAR_WIDTH; - if (fm != null) { - char_width = fm.stringWidth("FF"); - } - - rowHeader.setFixedCellWidth(char_width * 4); - rowHeader.setFixedCellHeight(getRowHeight()); - rowHeader.setCellRenderer(new MemRowHeaderRenderer(MemoryTable.this)); - setHorizontalAlignment(CENTER); - scrollPane.setRowHeaderView(rowHeader); - } - - private void remakeAdresses() { - if (currentPage == model.getPage()) { - return; - } - currentPage = model.getPage(); - for (int i = 0; i < adresses.length; i++) { - adresses[i] = String.format("%1$04Xh", - model.getColumnCount() * i + model.getColumnCount() * model.getRowCount() * currentPage); - } - rowHeader.setListData(adresses); - } - - @Override - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - if (isSelected) { - setBackground(MemoryTable.this.getSelectionBackground()); - setForeground(MemoryTable.this.getSelectionForeground()); - } else { - setBackground(Color.WHITE); - setForeground(Color.BLACK); - } - remakeAdresses(); - setText(value.toString()); - return this; - } - } - - private class MemoryCellEditor extends AbstractCellEditor implements TableCellEditor { - private final JTextField component = new JTextField(); - - MemoryCellEditor() { - FontMetrics fm = getFontMetrics(getFont()); - if (fm != null) { - component.setSize(fm.stringWidth("0xFFFFFF"), fm.getHeight() + 10); - component.setBorder(null); - } - } - - @Override - public Component getTableCellEditorComponent(JTable table, Object value, - boolean isSelected, int rowIndex, int vColIndex) { - if (!isSelected) { - return null; - } - component.setText("0x" + value); - return component; - } - - @Override - public Object getCellEditorValue() { - return component.getText(); - } - } -} diff --git a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTableModel.java b/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTableModel.java deleted file mode 100644 index 251a2b538..000000000 --- a/plugins/memory/brainduck-mem/src/main/java/net/emustudio/plugins/memory/brainduck/gui/MemoryTableModel.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.memory.brainduck.gui; - -import net.emustudio.emulib.plugins.memory.MemoryContext; - -import javax.swing.table.AbstractTableModel; -import java.util.Objects; - -public class MemoryTableModel extends AbstractTableModel { - private final MemoryContext mem; - private int currentPage = 0; - private final int ROW_COUNT = 16; - private final int COLUMN_COUNT = 16; - - MemoryTableModel(MemoryContext memory) { - this.mem = Objects.requireNonNull(memory); - } - - @Override - public int getRowCount() { - return ROW_COUNT; - } - - // from 00-FF - @Override - public int getColumnCount() { - return COLUMN_COUNT; - } - - @Override - public String getColumnName(int col) { - return String.format("%1$02X", col); - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - int pos = ROW_COUNT * COLUMN_COUNT * currentPage + rowIndex * COLUMN_COUNT + columnIndex; - if (pos >= mem.getSize()) { - return "."; - } - return String.format("%1$02X", mem.read(pos)); - } - - @Override - public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - int pos = ROW_COUNT * COLUMN_COUNT * currentPage + rowIndex * COLUMN_COUNT + columnIndex; - try { - mem.write(pos, Byte.decode(String.valueOf(aValue))); - fireTableCellUpdated(rowIndex, columnIndex); - } catch (NumberFormatException ignored) { - } - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - return true; - } - - void dataChangedAt(int address) { - int page = address / (ROW_COUNT * COLUMN_COUNT); - if (page == this.currentPage) { - int positionInPage = address % (ROW_COUNT * COLUMN_COUNT); - int row = positionInPage / COLUMN_COUNT; - int col = positionInPage % COLUMN_COUNT; - fireTableCellUpdated(row, col); - } - } - - void setPage(int page) throws IndexOutOfBoundsException { - if (page >= getPageCount() || page < 0) { - throw new IndexOutOfBoundsException(); - } - currentPage = page; - fireTableDataChanged(); - } - - int getPage() { - return currentPage; - } - - int getPageCount() { - return mem.getSize() / (ROW_COUNT * COLUMN_COUNT); - } - -} diff --git a/plugins/memory/brainduck-mem/src/main/resources/net/emustudio/plugins/memory/brainduck/version.properties b/plugins/memory/brainduck-mem/src/main/resources/net/emustudio/plugins/memory/brainduck/version.properties deleted file mode 100644 index a5041ccf7..000000000 --- a/plugins/memory/brainduck-mem/src/main/resources/net/emustudio/plugins/memory/brainduck/version.properties +++ /dev/null @@ -1,21 +0,0 @@ -# -# This file is part of emuStudio. -# -# Copyright (C) 2006-2020 Peter Jakubčo -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -version=@project.version@ -copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/memory/brainduck-mem/src/test/java/net/emustudio/plugins/memory/brainduck/MemoryImplTest.java b/plugins/memory/brainduck-mem/src/test/java/net/emustudio/plugins/memory/brainduck/MemoryImplTest.java deleted file mode 100644 index 19cae6349..000000000 --- a/plugins/memory/brainduck-mem/src/test/java/net/emustudio/plugins/memory/brainduck/MemoryImplTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.emustudio.plugins.memory.brainduck; - -import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import static org.easymock.EasyMock.*; -import static org.junit.Assert.assertNotEquals; - -public class MemoryImplTest { - private MemoryImpl memory; - - @Before - public void setup() { - ContextPool contextPool = createNiceMock(ContextPool.class); - replay(contextPool); - ApplicationApi applicationApi = createNiceMock(ApplicationApi.class); - expect(applicationApi.getContextPool()).andReturn(contextPool).anyTimes(); - replay(applicationApi); - - this.memory = new MemoryImpl(0, applicationApi, PluginSettings.UNAVAILABLE); - } - - @After - public void tearDown() { - memory.destroy(); - } - - @Test - public void testVersionIsKnown() { - assertNotEquals("(unknown)", memory.getVersion()); - } - - @Test - public void testCopyrightIsKnown() { - assertNotEquals("(unknown)", memory.getCopyright()); - } -} diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java index be832df4f..9310890d9 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java @@ -213,6 +213,11 @@ public List getReadOnly() { return romRanges.getRanges(); } + @Override + public Byte[][] getRawMemory() { + return mem; + } + private void removeROMRange(AddressRange rangeToRemove) { romRanges.remove(rangeToRemove.getStartAddress(), rangeToRemove.getStopAddress()); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java index f27495b32..9ccf0c8b3 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java @@ -99,4 +99,13 @@ interface AddressRange { * @return common boundary address */ int getCommonBoundary(); + + /** + * Returns raw memory represented by Java array. + *

+ * Memory notifications must be handled manually if this array changes. + * + * @return raw memory + */ + Byte[][] getRawMemory(); } diff --git a/settings.gradle b/settings.gradle index a558a0cf6..596eaf3d6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -31,7 +31,7 @@ include ':application' include ':plugins:compiler:as-8080' include ':plugins:compiler:as-ssem' include ':plugins:compiler:as-z80' -//include ':plugins:compiler:brainc-brainduck' +include ':plugins:compiler:brainc-brainduck' //include ':plugins:compiler:ramc-ram' //include ':plugins:compiler:raspc-rasp' @@ -50,7 +50,6 @@ include ':plugins:device:adm3A-terminal' include ':plugins:device:simhPseudo-z80' include ':plugins:device:ssem-display' -include ':plugins:memory:brainduck-mem' //include ':plugins:memory:ram-mem' //include ':plugins:memory:rasp-mem' include ':plugins:memory:ssem-mem' From cb1adc53c771c30a2f65df4563a19902a7a1b176 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 1 May 2022 10:01:08 +0100 Subject: [PATCH 131/314] [#201] Fixed brainduck-terminal --- application/build.gradle | 4 ++-- .../brainduck/terminal/BrainTerminalContext.java | 14 +++++++------- .../device/brainduck/terminal/DeviceImpl.java | 9 ++------- .../brainduck/terminal/io/FileIOProvider.java | 4 ++-- .../brainduck/terminal/io/InputProvider.java | 4 ++-- .../device/brainduck/terminal/io/Keyboard.java | 8 ++++---- settings.gradle | 2 +- 7 files changed, 20 insertions(+), 25 deletions(-) diff --git a/application/build.gradle b/application/build.gradle index 74c2dc2a8..b68b3025c 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -72,7 +72,7 @@ dependencies { providedRuntime project(":plugins:device:88-dcdd") providedRuntime project(":plugins:device:88-sio") providedRuntime project(":plugins:device:adm3A-terminal") -// providedRuntime project(":plugins:device:brainduck-terminal") + providedRuntime project(":plugins:device:brainduck-terminal") providedRuntime project(":plugins:device:simhPseudo-z80") providedRuntime project(":plugins:device:ssem-display") @@ -207,7 +207,7 @@ distributions { from(output(":plugins:device:88-dcdd")) from(output(":plugins:device:88-sio")) from(output(":plugins:device:adm3A-terminal")) - //from(output(":plugins:device:brainduck-terminal")) + from(output(":plugins:device:brainduck-terminal")) from(output(":plugins:device:simhPseudo-z80")) from(output(":plugins:device:ssem-display")) } diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/BrainTerminalContext.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/BrainTerminalContext.java index 7d3c3b81f..993c2bfb1 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/BrainTerminalContext.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/BrainTerminalContext.java @@ -28,7 +28,7 @@ import java.util.Objects; @ThreadSafe -class BrainTerminalContext implements DeviceContext, IOProvider { +class BrainTerminalContext implements DeviceContext, IOProvider { private volatile InputProvider inputProvider = InputProvider.DUMMY; private volatile OutputProvider outputProvider = OutputProvider.DUMMY; @@ -41,25 +41,25 @@ void setOutputProvider(OutputProvider outputProvider) { } @Override - public Short readData() { + public Byte readData() { InputProvider tmpInputProvider = inputProvider; if (tmpInputProvider != null) { - return (short) (tmpInputProvider.read() & 0xFF); + return tmpInputProvider.read(); } return InputProvider.EOF; } @Override - public void writeData(Short data) { + public void writeData(Byte data) { OutputProvider tmpOutputProvider = outputProvider; if (tmpOutputProvider != null) { - tmpOutputProvider.write(data); + tmpOutputProvider.write(data & 0xFF); } } @Override - public Class getDataType() { - return Short.class; + public Class getDataType() { + return Byte.class; } @Override diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java index f34db3f59..3898b4795 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java @@ -41,10 +41,7 @@ import java.util.Optional; import java.util.ResourceBundle; -@PluginRoot( - type = PLUGIN_TYPE.DEVICE, - title = "BrainDuck terminal" -) +@PluginRoot(type = PLUGIN_TYPE.DEVICE, title = "BrainDuck terminal") @SuppressWarnings("unused") public class DeviceImpl extends AbstractDevice { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceImpl.class); @@ -61,9 +58,7 @@ public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s applicationApi.getContextPool().register(pluginID, terminal, DeviceContext.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register BrainTerminal context", e); - applicationApi.getDialogs().showError( - "Could not register BrainDuck terminal. Please see log file for more details.", getTitle() - ); + applicationApi.getDialogs().showError("Could not register BrainDuck terminal. Please see log file for more details.", getTitle()); } } diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/FileIOProvider.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/FileIOProvider.java index 54f93cdd0..6cb2fb687 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/FileIOProvider.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/FileIOProvider.java @@ -52,13 +52,13 @@ public void write(int c) { } @Override - public int read() { + public byte read() { try { int character = reader.read(); if (character == -1) { return EOF; } - return character; + return (byte)(character & 0xFF); } catch (IOException e) { LOGGER.error("Could not read from input file: " + INPUT_FILE_NAME, e); return EOF; diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/InputProvider.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/InputProvider.java index 57ff9bfde..1dc287c4d 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/InputProvider.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/InputProvider.java @@ -22,7 +22,7 @@ public interface InputProvider extends IOProvider { InputProvider DUMMY = new InputProvider() { @Override - public int read() { + public byte read() { return EOF; } @@ -37,6 +37,6 @@ public void close() { } }; - int read(); + byte read(); } diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Keyboard.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Keyboard.java index 18b1d56c2..1f4f28bb3 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Keyboard.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Keyboard.java @@ -29,7 +29,7 @@ @ThreadSafe public class Keyboard implements InputProvider, KeyListener { - private final BlockingQueue inputBuffer = new LinkedBlockingQueue<>(); + private final BlockingQueue inputBuffer = new LinkedBlockingQueue<>(); private final List listeners = new CopyOnWriteArrayList<>(); @ThreadSafe @@ -57,7 +57,7 @@ public void reset() { } @Override - public int read() { + public byte read() { notifyReadStarted(); try { return inputBuffer.take(); @@ -81,10 +81,10 @@ public void keyTyped(KeyEvent e) { public void keyPressed(KeyEvent e) { int keycode = e.getKeyCode(); if (keycode == KeyEvent.VK_ESCAPE) { - inputBuffer.add(EOF); + inputBuffer.add((byte) EOF); } else if (!((keycode == KeyEvent.VK_SHIFT || keycode == KeyEvent.VK_CONTROL || keycode == KeyEvent.VK_ALT || keycode == KeyEvent.VK_META))) { - inputBuffer.add((int) e.getKeyChar()); + inputBuffer.add((byte) (e.getKeyChar() & 0xFF)); } } diff --git a/settings.gradle b/settings.gradle index 596eaf3d6..bcb2812e0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -46,7 +46,7 @@ include ':plugins:device:88-dcdd' include ':plugins:device:88-sio' include ':plugins:device:abstract-tape' include ':plugins:device:adm3A-terminal' -//include ':plugins:device:brainduck-terminal' +include ':plugins:device:brainduck-terminal' include ':plugins:device:simhPseudo-z80' include ':plugins:device:ssem-display' From 4b7fd78abbff0b1a499a1a3fb30d7c0d6e88aecf Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 1 May 2022 10:28:16 +0100 Subject: [PATCH 132/314] [#201] brainc-brainduck: fix missing token --- .../plugins/compiler/brainduck/LexicalAnalyzerImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java index 499c5db98..4c3e3642e 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java @@ -59,6 +59,7 @@ private int convertLexerTokenType(int tokenType) { case BraincLexer.PRINT: case BraincLexer.LOAD: case BraincLexer.LOOP: + case BraincLexer.ENDL: return Token.RESERVED; case BraincLexer.EOF: return Token.EOF; From 5e040f46538e80079b3033fe9d26a55f3f77f22e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 9 May 2022 15:44:09 +0200 Subject: [PATCH 133/314] [#201] ramc-ram, ram-cpu, ram-mem, abstract-tape: rewrites --- RELEASES.md | 8 +- application/build.gradle | 16 +- .../src/main/examples/char_max_code.asm | 2 +- .../src/main/examples/numbers_count.asm | 10 +- .../as-8080/src/main/examples/reverse.asm | 8 +- .../compiler/as8080/Assembler8080.java | 2 +- .../as8080/e2e/AbstractCompilerTest.java | 4 +- .../as-z80/src/main/examples/reverse.asm | 8 +- .../plugins/compiler/asZ80/AssemblerZ80.java | 2 +- .../visitors/CollectExprsInOpcodeVisitor.java | 1 - .../asZ80/e2e/AbstractCompilerTest.java | 4 +- .../src/main/examples/rot13.b | 2 +- .../compiler/brainduck/CompilerImpl.java | 4 +- .../brainduck/{tree => ast}/Instruction.java | 2 +- .../brainduck/{tree => ast}/Program.java | 2 +- .../{tree => ast}/ProgramParser.java | 2 +- plugins/compiler/ramc-ram/.gitignore | 4 +- plugins/compiler/ramc-ram/build.gradle | 40 +- .../ramc-ram/src/main/antlr/RAMLexer.g4 | 60 ++ .../ramc-ram/src/main/antlr/RAMParser.g4 | 72 +++ .../ramc-ram/src/main/examples/copy.ram | 8 +- .../src/main/examples/equal_count.ram | 6 +- .../ramc-ram/src/main/examples/factorial.ram | 4 +- .../ramc-ram/src/main/examples/ones_count.ram | 4 +- .../ramc-ram/src/main/examples/reverse.ram | 6 +- .../CompilerRAM.java} | 136 ++--- .../compiler/ram/LexicalAnalyzerImpl.java | 96 +++ .../compiler/ram/ParserErrorListener.java | 25 + .../plugins/compiler/ram/ParsingUtils.java | 57 ++ .../compiler/{ramc => ram}/Runner.java | 6 +- .../compiler/ram/SerializableOptional.java | 49 ++ .../plugins/compiler/ram/ast/Instruction.java | 105 ++++ .../plugins/compiler/ram/ast/Label.java | 72 +++ .../plugins/compiler/ram/ast/Program.java | 89 +++ .../plugins/compiler/ram/ast/Value.java | 72 +++ .../ram/exceptions/CompileException.java | 20 + .../ram/exceptions/SyntaxErrorException.java | 11 + .../compiler/ram/visitors/ProgramParser.java | 118 ++++ .../plugins/compiler/ramc/CompiledCode.java | 79 --- .../plugins/compiler/ramc/Namespace.java | 62 -- .../plugins/compiler/ramc/TokenImpl.java | 85 --- .../plugins/compiler/ramc/tree/Label.java | 49 -- .../plugins/compiler/ramc/tree/Program.java | 47 -- .../ramc/tree/RAMInstructionImpl.java | 161 ----- .../plugins/compiler/ramc/tree/Row.java | 72 --- .../ramc-ram/src/main/jflex/lexer.jflex | 2 +- .../compiler/{ramc => ram}/version.properties | 0 .../{ramc => ram}/AbstractCompilerTest.java | 26 +- .../plugins/compiler/ram/CompilerTest.java | 226 ++++++++ .../compiler/{ramc => ram}/MemoryStub.java | 39 +- .../compiler/{ramc => ram}/RunnerTest.java | 2 +- .../plugins/compiler/ramc/CompilerTest.java | 212 ------- plugins/compiler/raspc-rasp/.gitignore | 4 +- plugins/compiler/raspc-rasp/build.gradle | 40 +- .../src/main/examples/RAMinRASP.rasp | 10 +- .../src/main/examples/RASPinRAM.ram | 12 +- .../src/main/examples/factorial.rasp | 4 +- .../raspc-rasp/src/main/jflex/lexer.jflex | 2 +- plugins/cpu/ram-cpu/build.gradle | 4 +- .../emustudio/plugins/cpu/ram/CpuImpl.java | 28 +- .../plugins/cpu/ram/EmulatorEngine.java | 313 +++++----- ...ontextImpl.java => RAMCpuContextImpl.java} | 46 +- .../{RAMContext.java => RAMCpuContext.java} | 8 +- .../plugins/cpu/ram/gui/LabelDebugColumn.java | 2 +- .../plugins/cpu/ram/gui/RAMDisassembler.java | 6 +- .../plugins/cpu/ram/gui/RAMStatusPanel.java | 20 +- .../plugins/cpu/ram/AbstractEngineTest.java | 87 +++ .../plugins/cpu/ram/EmulatorEngineTest.java | 367 ++++++++++-- .../plugins/device/mits88sio/Transmitter.java | 2 +- .../device/mits88sio/ports/CpuDataPort.java | 2 +- .../{DeviceImpl.java => AbstractTape.java} | 12 +- .../abstracttape/AbstractTapeContextImpl.java | 327 ++++++----- .../abstracttape/api/AbstractTapeContext.java | 42 +- .../device/abstracttape/api/TapeSymbol.java | 57 ++ .../abstracttape/gui/TapeCellRenderer.java | 5 +- .../device/abstracttape/gui/TapeGui.java | 16 +- .../device/abstracttape/gui/TapeModel.java | 15 +- ...iceImplTest.java => AbstractTapeTest.java} | 6 +- .../adm3a/interaction/KeyboardFromFile.java | 6 +- .../device/adm3a/interaction/KeyboardGui.java | 9 +- .../plugins/memory/ram/MemoryContextImpl.java | 86 ++- .../plugins/memory/ram/MemoryImpl.java | 5 +- .../memory/ram/api/RAMInstruction.java | 71 +-- .../plugins/memory/ram/api/RAMLabel.java | 23 + .../memory/ram/api/RAMMemoryContext.java | 10 +- .../plugins/memory/ram/api/RAMValue.java | 47 ++ .../plugins/memory/ram/gui/MemoryDialog.java | 548 +----------------- .../plugins/memory/ram/gui/RAMTableModel.java | 5 +- settings.gradle | 6 +- 89 files changed, 2350 insertions(+), 2102 deletions(-) rename plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/{tree => ast}/Instruction.java (96%) rename plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/{tree => ast}/Program.java (95%) rename plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/{tree => ast}/ProgramParser.java (91%) create mode 100644 plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 create mode 100644 plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 rename plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/{ramc/CompilerImpl.java => ram/CompilerRAM.java} (51%) create mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java create mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParserErrorListener.java create mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParsingUtils.java rename plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/{ramc => ram}/Runner.java (91%) create mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/SerializableOptional.java create mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java create mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java create mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java create mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Value.java create mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/exceptions/CompileException.java create mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/exceptions/SyntaxErrorException.java create mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/visitors/ProgramParser.java delete mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/CompiledCode.java delete mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/Namespace.java delete mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/TokenImpl.java delete mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/tree/Label.java delete mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/tree/Program.java delete mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/tree/RAMInstructionImpl.java delete mode 100644 plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/tree/Row.java rename plugins/compiler/ramc-ram/src/main/resources/net/emustudio/plugins/compiler/{ramc => ram}/version.properties (100%) rename plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/{ramc => ram}/AbstractCompilerTest.java (78%) create mode 100644 plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/CompilerTest.java rename plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/{ramc => ram}/MemoryStub.java (60%) rename plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/{ramc => ram}/RunnerTest.java (97%) delete mode 100644 plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ramc/CompilerTest.java rename plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/{RAMContextImpl.java => RAMCpuContextImpl.java} (63%) rename plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/api/{RAMContext.java => RAMCpuContext.java} (83%) create mode 100644 plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/AbstractEngineTest.java rename plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/{DeviceImpl.java => AbstractTape.java} (93%) create mode 100644 plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java rename plugins/device/abstract-tape/src/test/java/net/emustudio/plugins/device/abstracttape/{DeviceImplTest.java => AbstractTapeTest.java} (86%) create mode 100644 plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMLabel.java create mode 100644 plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMValue.java diff --git a/RELEASES.md b/RELEASES.md index c78bfcf3c..d824bdec7 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -15,7 +15,7 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS ## main-module: - removed configuration editor popup in the schema editor - reimplemented source code editor using [RSyntaxTextArea](https://github.com/bobbylight/RSyntaxTextArea) -- reimplemented emulation automation (`--input` is not required anymore, introduced more command line options) +- reimplemented emulation automation (`--value` is not required anymore, introduced more command line options) - introduced configuration file for the main module - be able to configure Look and Feel in the configuration - make debug table responsive @@ -42,14 +42,14 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS ## RASP: - rewritten raspc-rasp grammar and compiler -- raspc-rasp: implemented `` directive +- raspc-rasp: implemented `` directive ## SSEM: - fix: SSEM noodle-timer doesn't work ## adm3A-terminal: - fix: load cursor from software -- fix: keyboard does not read input +- fix: keyboard does not read value - fix: "here is" does not work (in GUI) - throws some hidden exception - fix: "always on top" doesn't work @@ -105,7 +105,7 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS - "previous instruction" just decrements program counter - fixed syntax highlighting - fixed: on breakpoint, instruction list was not pointing at current (next) instruction -- fixed: on 'pages backwards' button when the input window is cancelled, NullPointerException appeared in log +- fixed: on 'pages backwards' button when the value window is cancelled, NullPointerException appeared in log - fixed: when file was not saved before compilation, on most compilers NullPointerException appeared in log - fixed: in source code editor, when open file is cancelled, compiler output window was cleared - find/replace dialog is now possible to be cancelled with ESC key diff --git a/application/build.gradle b/application/build.gradle index b68b3025c..e1192e018 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -53,17 +53,17 @@ dependencies { providedRuntime project(":plugins:compiler:as-ssem") providedRuntime project(":plugins:compiler:as-z80") providedRuntime project(":plugins:compiler:brainc-brainduck") -// providedRuntime project(":plugins:compiler:ramc-ram") + providedRuntime project(":plugins:compiler:ramc-ram") // providedRuntime project(":plugins:compiler:raspc-rasp") -// providedRuntime project(":plugins:memory:ram-mem") + providedRuntime project(":plugins:memory:ram-mem") // providedRuntime project(":plugins:memory:rasp-mem") providedRuntime project(":plugins:memory:ssem-mem") providedRuntime project(":plugins:memory:byte-mem") providedRuntime project(":plugins:cpu:8080-cpu") providedRuntime project(":plugins:cpu:brainduck-cpu") -// providedRuntime project(":plugins:cpu:ram-cpu") + providedRuntime project(":plugins:cpu:ram-cpu") // providedRuntime project(":plugins:cpu:rasp-cpu") providedRuntime project(":plugins:cpu:z80-cpu") providedRuntime project(":plugins:cpu:ssem-cpu") @@ -179,13 +179,13 @@ distributions { from(output(":plugins:compiler:as-z80")) from(output(":plugins:compiler:as-ssem")) from(output(":plugins:compiler:brainc-brainduck")) - // from(output(":plugins:compiler:ramc-ram")) + from(output(":plugins:compiler:ramc-ram")) //from(output(":plugins:compiler:raspc-rasp")) } into('memory') { include '*.jar' -// from(output(":plugins:memory:ram-mem")) + from(output(":plugins:memory:ram-mem")) // from(output(":plugins:memory:rasp-mem")) from(output(":plugins:memory:ssem-mem")) from(output(":plugins:memory:byte-mem")) @@ -195,7 +195,7 @@ distributions { include '*.jar' from(output(":plugins:cpu:8080-cpu")) from(output(":plugins:cpu:brainduck-cpu")) - // from(output(":plugins:cpu:ram-cpu")) + from(output(":plugins:cpu:ram-cpu")) // from(output(":plugins:cpu:rasp-cpu")) from(output(":plugins:cpu:z80-cpu")) from(output(":plugins:cpu:ssem-cpu")) @@ -214,7 +214,7 @@ distributions { // Examples //["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"] - ["as-8080", "as-z80", "as-ssem", "brainc-brainduck"].collect { compiler -> + ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram"].collect { compiler -> from(examples(":plugins:compiler:$compiler")) { into "examples/$compiler" } @@ -222,7 +222,7 @@ distributions { // Scripts // ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"] - ["as-8080", "as-z80", "as-ssem", "brainc-brainduck"].collect { compiler -> + ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram"].collect { compiler -> from(scripts(":plugins:compiler:$compiler")) { into "bin" } diff --git a/plugins/compiler/as-8080/src/main/examples/char_max_code.asm b/plugins/compiler/as-8080/src/main/examples/char_max_code.asm index 2c0830367..fb61a2fa8 100644 --- a/plugins/compiler/as-8080/src/main/examples/char_max_code.asm +++ b/plugins/compiler/as-8080/src/main/examples/char_max_code.asm @@ -11,7 +11,7 @@ mvi d,0 ; char with maximum ASCII code char_loop: call getchar -cpi 10 ; end of input? +cpi 10 ; end of value? jz char_end cpi 13 jz char_end diff --git a/plugins/compiler/as-8080/src/main/examples/numbers_count.asm b/plugins/compiler/as-8080/src/main/examples/numbers_count.asm index 43de84d3e..32dc6cffe 100644 --- a/plugins/compiler/as-8080/src/main/examples/numbers_count.asm +++ b/plugins/compiler/as-8080/src/main/examples/numbers_count.asm @@ -5,16 +5,16 @@ dcx sp ; stack initialization (0FFFFh) lxi h,text1 call putstr ; print text1 -lxi d,input ; address for string input +lxi d,value ; address for string value call getline ; read from keyboard -lxi b,input +lxi b,value mvi d,0 ; numbers counter char_loop: ldax b inx b -cpi 10 ; end of input? +cpi 10 ; end of value? jz char_end cpi 13 jz char_end @@ -41,6 +41,6 @@ include 'include\putstr.inc' include 'include\putchar.inc' include 'include\newline.inc' -text1: db 'Count of numbers on input ...',10,13,'Enter text: ',0 +text1: db 'Count of numbers on value ...',10,13,'Enter text: ',0 text2: db 10,13,'Count: ',0 -input: ds 30 +value: ds 30 diff --git a/plugins/compiler/as-8080/src/main/examples/reverse.asm b/plugins/compiler/as-8080/src/main/examples/reverse.asm index 9bde7b4cc..b59f22d7c 100644 --- a/plugins/compiler/as-8080/src/main/examples/reverse.asm +++ b/plugins/compiler/as-8080/src/main/examples/reverse.asm @@ -6,17 +6,17 @@ dcx sp ; stack initialization (0FFFFh) lxi h,text1 call putstr ; print text1 -lxi d,input ; address for string input +lxi d,value ; address for string value call getline ; read from keyboard -lxi b,input +lxi b,value mvi d,0 ; chars counter char_loop: ldax b inx b ; bc = bc+1 -cpi 10 ; end of input? +cpi 10 ; end of value? jz char_end cpi 13 jz char_end @@ -53,4 +53,4 @@ include 'include\newline.inc' text1: db 'Reversed text ...',10,13,'Enter text: ',0 text2: db 10,13,'Reversed: ',0 -input: ds 30 +value: ds 30 diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index 00a3b83e5..bf2952113 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -177,7 +177,7 @@ public boolean compile(String inputFileName) { String outputFileName = Objects.requireNonNull(inputFileName); SourceFileExtension srcExtension = SOURCE_FILE_EXTENSIONS.get(0); - int i = inputFileName.lastIndexOf("." + srcExtension.getExtension()); + int i = inputFileName.toLowerCase(Locale.ENGLISH).lastIndexOf("." + srcExtension.getExtension()); if (i >= 0) { outputFileName = outputFileName.substring(0, i); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java index b7d92339b..0de78f6d6 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java @@ -67,7 +67,9 @@ public void onStart() { @Override public void onMessage(CompilerMessage message) { - System.out.println(message); + if (message.getMessageType() != CompilerMessage.MessageType.TYPE_INFO) { + System.out.println(message); + } } @Override diff --git a/plugins/compiler/as-z80/src/main/examples/reverse.asm b/plugins/compiler/as-z80/src/main/examples/reverse.asm index 95b7c67d3..794453d3a 100644 --- a/plugins/compiler/as-z80/src/main/examples/reverse.asm +++ b/plugins/compiler/as-z80/src/main/examples/reverse.asm @@ -6,17 +6,17 @@ dec sp ; stack initialization (0FFFFh) ld hl,text1 call putstr ; print text1 -ld de,input ; address for string input +ld de,value ; address for string value call getline ; read from keyboard -ld bc,input +ld bc,value ld d,0 ; chars counter char_loop: ld a, (bc) inc bc ; bc = bc+1 -cp 10 ; end of input? +cp 10 ; end of value? jp z, char_end cp 13 jp z, char_end @@ -52,4 +52,4 @@ include "include\newline.inc" text1: db "Reversed text ...",10,13,"Enter text: ",0 text2: db 10,13,"Reversed: ",0 -input: ds 30 +value: ds 30 diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java index cf227d228..1f560ce08 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java @@ -178,7 +178,7 @@ public boolean compile(String inputFileName) { String outputFileName = Objects.requireNonNull(inputFileName); SourceFileExtension srcExtension = SOURCE_FILE_EXTENSIONS.get(0); - int i = inputFileName.lastIndexOf("." + srcExtension.getExtension()); + int i = inputFileName.toLowerCase(Locale.ENGLISH).lastIndexOf("." + srcExtension.getExtension()); if (i >= 0) { outputFileName = outputFileName.substring(0, i); } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java index ffe27c91d..88b28ea6c 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java @@ -1,6 +1,5 @@ package net.emustudio.plugins.compiler.asZ80.visitors; -import net.emustudio.plugins.compiler.asZ80.CompileError; import net.emustudio.plugins.compiler.asZ80.ast.Evaluated; import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; import net.emustudio.plugins.compiler.asZ80.ast.instr.InstrCB; diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java index 570e9c4c7..53e92f93d 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java @@ -68,7 +68,9 @@ public void onStart() { @Override public void onMessage(CompilerMessage message) { - System.out.println(message); + if (message.getMessageType() != CompilerMessage.MessageType.TYPE_INFO) { + System.out.println(message); + } } @Override diff --git a/plugins/compiler/brainc-brainduck/src/main/examples/rot13.b b/plugins/compiler/brainc-brainduck/src/main/examples/rot13.b index 26a2b7bf9..ff68ab079 100644 --- a/plugins/compiler/brainc-brainduck/src/main/examples/rot13.b +++ b/plugins/compiler/brainc-brainduck/src/main/examples/rot13.b @@ -20,7 +20,7 @@ of course any function char f(char) can be made easily on the same principle My pathological program rot13.b is good for testing the response to deep -brackets; the input "~mlk zyx" should produce the output "~zyx mlk". +brackets; the value "~mlk zyx" should produce the output "~zyx mlk". Daniel B Cristofani (cristofdathevanetdotcom) http://www.hevanet.com/cristofd/brainfuck/ diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerImpl.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerImpl.java index 4108d2615..2b07accdb 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerImpl.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerImpl.java @@ -29,8 +29,8 @@ import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.brainduck.tree.Program; -import net.emustudio.plugins.compiler.brainduck.tree.ProgramParser; +import net.emustudio.plugins.compiler.brainduck.ast.Program; +import net.emustudio.plugins.compiler.brainduck.ast.ProgramParser; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Instruction.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/Instruction.java similarity index 96% rename from plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Instruction.java rename to plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/Instruction.java index c60d60c1f..f87ea6efa 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Instruction.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/Instruction.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.brainduck.tree; +package net.emustudio.plugins.compiler.brainduck.ast; import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.compiler.brainduck.BraincParser; diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Program.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/Program.java similarity index 95% rename from plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Program.java rename to plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/Program.java index 1b03c68a1..70f0c59b9 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/Program.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/Program.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.brainduck.tree; +package net.emustudio.plugins.compiler.brainduck.ast; import net.emustudio.emulib.runtime.io.IntelHEX; diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/ProgramParser.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/ProgramParser.java similarity index 91% rename from plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/ProgramParser.java rename to plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/ProgramParser.java index 1c00bd0fb..2d1444496 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/tree/ProgramParser.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/ProgramParser.java @@ -1,4 +1,4 @@ -package net.emustudio.plugins.compiler.brainduck.tree; +package net.emustudio.plugins.compiler.brainduck.ast; import net.emustudio.plugins.compiler.brainduck.BraincParser; import net.emustudio.plugins.compiler.brainduck.BraincParserBaseVisitor; diff --git a/plugins/compiler/ramc-ram/.gitignore b/plugins/compiler/ramc-ram/.gitignore index 85bec40d5..f6f374b4d 100644 --- a/plugins/compiler/ramc-ram/.gitignore +++ b/plugins/compiler/ramc-ram/.gitignore @@ -1 +1,3 @@ -src/main/java/net/emustudio/plugins/compiler/ramc/LexerImpl.java +/src/main/antlr/gen/ +/src/main/gen/ +*.tokens diff --git a/plugins/compiler/ramc-ram/build.gradle b/plugins/compiler/ramc-ram/build.gradle index a3d3ac02f..e60843f5c 100644 --- a/plugins/compiler/ramc-ram/build.gradle +++ b/plugins/compiler/ramc-ram/build.gradle @@ -21,15 +21,16 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'org.xbib.gradle.plugin.jflex' version "1.5.0" - id "com.github.andrescv.jcup" version "1.0" + id 'idea' + id 'antlr' id 'com.adarshr.test-logger' version '3.1.0' } dependencies { + antlr "org.antlr:antlr4:4.9.2" + implementation "org.antlr:antlr4-runtime:4.9.2" implementation libs.emuLib implementation project.rootProject.project(":plugins:memory:ram-mem") - implementation libs.javaCupRuntime implementation libs.slf4JApi testImplementation libs.junit @@ -37,26 +38,35 @@ dependencies { testImplementation libs.slf4JSimple } -sourceSets.main.java.srcDirs = [ - "${buildDir}/generated-sources/jflex", "${buildDir}/generated-sources/cup", 'src/main/java' -] +generateGrammarSource { + maxHeapSize = "128m" + arguments += ['-package', 'net.emustudio.plugins.compiler.ram', '-visitor', '-no-listener'] + outputDirectory = file("${buildDir}/generated-src/antlr/main/net/emustudio/plugins/compiler/ram") +} +compileJava.dependsOn generateGrammarSource -jflex { - no_backup = true +sourceSets { + generated { + java.srcDir "${buildDir}/generated-src/antlr/main" + } + main { + java.srcDirs = [ + 'src/main/java', "${buildDir}/generated-src/antlr/main" + ] + } } +compileJava.source sourceSets.generated.java, sourceSets.main.java -jcup { - input = file('src/main/cup/parser.cup') - destdir = file("${buildDir}/generated-sources/cup/net/emustudio/plugins/compiler/ramc") - parser = 'ParserImpl' - symbols = 'Symbols' - iface = true +idea { + module { + sourceDirs += file("build/generated-src/antlr") + } } jar { archiveVersion = '' manifest { - attributes manifestAttributes('net.emustudio.plugins.compiler.ramc.Runner') + attributes manifestAttributes('net.emustudio.plugins.compiler.ram.Runner') } } diff --git a/plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 b/plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 new file mode 100644 index 000000000..efe2c4a6c --- /dev/null +++ b/plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 @@ -0,0 +1,60 @@ +lexer grammar RAMLexer; + +COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]*; +COMMENT2: '/*' .*? '*/'; + +fragment A: [aA]; +fragment B: [bB]; +fragment D: [dD]; +fragment E: [eE]; +fragment G: [gG]; +fragment H: [hH]; +fragment I: [iI]; +fragment J: [jJ]; +fragment L: [lL]; +fragment M: [mM]; +fragment N: [nN]; +fragment O: [oO]; +fragment P: [pP]; +fragment R: [rR]; +fragment S: [sS]; +fragment T: [tT]; +fragment U: [uU]; +fragment V: [vV]; +fragment W: [wW]; +fragment X: [xX]; +fragment Z: [zZ]; + +OPCODE_HALT: H A L T; +OPCODE_READ: R E A D; +OPCODE_WRITE: W R I T E; +OPCODE_LOAD: L O A D; +OPCODE_STORE: S T O R E; +OPCODE_ADD: A D D; +OPCODE_SUB: S U B; +OPCODE_MUL: M U L; +OPCODE_DIV: D I V; +OPCODE_JMP: J M P; +OPCODE_JGTZ: J G T Z; +OPCODE_JZ: J Z; + +OP_DIRECT: '='; +OP_INDIRECT: '*'; + +PREP_INPUT: '<' I N P U T '>'; + +LIT_HEXNUMBER_1: '0' X [0-9a-fA-F]+; +LIT_NUMBER: [0-9]+ D?; +LIT_HEXNUMBER_2: [0-9a-fA-F]+ H; +LIT_OCTNUMBER: [0-7]+ [oOqQ]; +LIT_BINNUMBER: [01]+ B; +LIT_STRING_1: '\'' ~[']* '\''; +LIT_STRING_2: '"' ~["]* '"'; + +ID_IDENTIFIER: [a-zA-Z_?@] [a-zA-Z_?@0-9]*; +ID_LABEL: ID_IDENTIFIER ':'; + +WS : [ \t\f]+ -> channel(HIDDEN); +EOL: '\r'? '\n'; + +ERROR: .; diff --git a/plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 b/plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 new file mode 100644 index 000000000..b36078621 --- /dev/null +++ b/plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 @@ -0,0 +1,72 @@ +parser grammar RAMParser; + +options { + tokenVocab = RAMLexer; +} + +rStart: + (rLine EOL rLine)* EOF + | rLine EOF + ; + +rLine: + label=ID_LABEL? (comment EOL)* statement=rStatement comment + | label=ID_LABEL comment + | comment + ; + +comment: COMMENT? | COMMENT2?; + +rStatement: + instr=rInstruction + | value=rInput + ; + +rInstruction: + op=OPCODE_READ n=rNumber + | op=OPCODE_READ d=OP_INDIRECT n=rNumber + | op=OPCODE_WRITE d=OP_DIRECT v=rValue + | op=OPCODE_WRITE d=OP_INDIRECT n=rNumber + | op=OPCODE_WRITE n=rNumber + | op=OPCODE_LOAD d=OP_DIRECT v=rValue + | op=OPCODE_LOAD d=OP_INDIRECT n=rNumber + | op=OPCODE_LOAD n=rNumber + | op=OPCODE_STORE n=rNumber + | op=OPCODE_STORE d=OP_INDIRECT n=rNumber + | op=OPCODE_ADD d=OP_DIRECT v=rValue + | op=OPCODE_ADD d=OP_INDIRECT n=rNumber + | op=OPCODE_ADD n=rNumber + | op=OPCODE_SUB d=OP_DIRECT v=rValue + | op=OPCODE_SUB d=OP_INDIRECT n=rNumber + | op=OPCODE_SUB n=rNumber + | op=OPCODE_MUL d=OP_DIRECT v=rValue + | op=OPCODE_MUL d=OP_INDIRECT n=rNumber + | op=OPCODE_MUL n=rNumber + | op=OPCODE_DIV d=OP_DIRECT v=rValue + | op=OPCODE_DIV d=OP_INDIRECT n=rNumber + | op=OPCODE_DIV n=rNumber + | op=OPCODE_JMP id=ID_IDENTIFIER + | op=OPCODE_JZ id=ID_IDENTIFIER + | op=OPCODE_JGTZ id=ID_IDENTIFIER + | op=OPCODE_HALT + ; + +rInput: PREP_INPUT rValue+; + +rValue: + v=LIT_HEXNUMBER_1 + | v=LIT_NUMBER + | v=LIT_HEXNUMBER_2 + | v=LIT_OCTNUMBER + | v=LIT_BINNUMBER + | v=LIT_STRING_1 + | v=LIT_STRING_2 + ; + +rNumber: + n=LIT_HEXNUMBER_1 + | n=LIT_NUMBER + | n=LIT_HEXNUMBER_2 + | n=LIT_OCTNUMBER + | n=LIT_BINNUMBER + ; diff --git a/plugins/compiler/ramc-ram/src/main/examples/copy.ram b/plugins/compiler/ramc-ram/src/main/examples/copy.ram index 91def6d59..4673250e6 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/copy.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/copy.ram @@ -1,8 +1,8 @@ - 3 4 ignored world hello + 3 4 ignored world hello ; COPY(X,Y) ; -; input: +; value: ; reg.1: X ; reg.2: Y ; @@ -11,7 +11,7 @@ ; reg.Y: (reg.Y) - sss + sss ; load X,Y read 1 read 2 @@ -24,4 +24,4 @@ read *2 load *2 store *1 -halt \ No newline at end of file +halt diff --git a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram index 94ae16cd1..2b1b4b92c 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram @@ -1,8 +1,8 @@ -; input: X0 - string X zero-ended, X in {1,2,3,....}*, on the input tape +; value: X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape ; output: 1 if N1(X) = N2(X) (i.e. if X contains equal number of "1" and "2") ; 0 otherwise - 1 2 3 3 2 1 1 33 21 1 2 1 2 112 2 1 2 11 2 1 2 21 2 1 + 1 2 3 3 2 1 1 33 21 1 2 1 2 112 2 1 2 11 2 1 2 21 2 1 load=0 store 2 @@ -33,4 +33,4 @@ final_test: halt print_one: write=1 - halt \ No newline at end of file + halt diff --git a/plugins/compiler/ramc-ram/src/main/examples/factorial.ram b/plugins/compiler/ramc-ram/src/main/examples/factorial.ram index 5d7b65bba..fa3fa04e2 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/factorial.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/factorial.ram @@ -1,10 +1,10 @@ ; Factorial N ; -; input: N +; value: N ; output: N! ; - 8 + 8 read 1 load 1 diff --git a/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram b/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram index 3410ade4f..dfce61ebd 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram @@ -1,6 +1,6 @@ -; input : X0 - string X zero-ended, X in {1,2,3,....}*, on the input tape +; value : X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape ; output: N1(X) - number of ones in X. - 1 2 3 4 5 6 7 1 1 1 2 5 0 + 1 2 3 4 5 6 7 1 1 1 2 5 0 load =0 store 2 diff --git a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram index fa3d24f83..01f8e88d2 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram @@ -1,7 +1,7 @@ -; input : X0 - string X zero-ended, X in {1,2,3,....}*, on the input tape +; value : X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape ; output: XR - reverse of X - 1 2 3 3 2 1 2 3 5.5 3 4 5 53 34 2 34 + 1 2 3 3 2 1 2 3 5.5 3 4 5 53 34 2 34 load=10 store2 @@ -24,4 +24,4 @@ print: write *2 jmp print exit: - halt \ No newline at end of file + halt diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/CompilerImpl.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java similarity index 51% rename from plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/CompilerImpl.java rename to plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java index 73f532200..8687ea03b 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/CompilerImpl.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.ramc; +package net.emustudio.plugins.compiler.ram; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; import net.emustudio.emulib.plugins.annotations.PluginRoot; @@ -24,10 +24,14 @@ import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; import net.emustudio.emulib.plugins.compiler.SourceFileExtension; import net.emustudio.emulib.runtime.*; -import net.emustudio.plugins.compiler.ramc.tree.Program; -import net.emustudio.plugins.compiler.ramc.tree.RAMInstructionImpl; -import net.emustudio.plugins.memory.ram.api.RAMInstruction; +import net.emustudio.emulib.runtime.helpers.RadixUtils; +import net.emustudio.plugins.compiler.ram.ast.Program; +import net.emustudio.plugins.compiler.ram.visitors.ProgramParser; import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.TokenStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,36 +39,16 @@ import java.io.Reader; import java.util.*; -@PluginRoot( - type = PLUGIN_TYPE.COMPILER, - title = "RAM Compiler" -) +@PluginRoot(type = PLUGIN_TYPE.COMPILER, title = "RAM Compiler") @SuppressWarnings("unused") -public class CompilerImpl extends AbstractCompiler { - private final static Logger LOGGER = LoggerFactory.getLogger(CompilerImpl.class); - private static final List SOURCE_FILE_EXTENSIONS = List.of( - new SourceFileExtension("ram", "Random Access Machine source") - ); - - private final LexerImpl lexer; - private final ParserImpl parser; +public class CompilerRAM extends AbstractCompiler { + private final static Logger LOGGER = LoggerFactory.getLogger(CompilerRAM.class); + private static final List SOURCE_FILE_EXTENSIONS = List.of(new SourceFileExtension("ram", "Random Access Machine source")); + private RAMMemoryContext memory; - public CompilerImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { + public CompilerRAM(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); - - // lexer has to be reset WITH a reader object before compile - lexer = new LexerImpl(null); - parser = new ParserImpl(lexer, this); - RAMInstructionImpl context = new RAMInstructionImpl(0, null); - - Optional.ofNullable(applicationApi.getContextPool()).ifPresent(pool -> { - try { - pool.register(pluginID, context, RAMInstruction.class); - } catch (InvalidContextException | ContextAlreadyRegisteredException e) { - applicationApi.getDialogs().showError("Could not register RAM instruction context", super.getTitle()); - } - }); } @Override @@ -79,7 +63,7 @@ public String getCopyright() { @Override public String getDescription() { - return "Custom compiler for RAM abstract machine"; + return "RAM machine compiler"; } public void initialize() { @@ -94,13 +78,33 @@ public void initialize() { public boolean compile(String inputFileName, String outputFileName) { try { this.notifyCompileStart(); - CompiledCode code = compileFrom(inputFileName); + notifyInfo(getTitle() + ", version " + getVersion()); + + try (Reader reader = new FileReader(inputFileName)) { + org.antlr.v4.runtime.Lexer lexer = createLexer(CharStreams.fromReader(reader)); + lexer.addErrorListener(new ParserErrorListener()); + CommonTokenStream tokens = new CommonTokenStream(lexer); + + RAMParser parser = createParser(tokens); + parser.addErrorListener(new ParserErrorListener()); + + Program program = new Program(); + new ProgramParser(program).visit(parser.rStart()); - if (code.serialize(outputFileName)) { - notifyInfo("Compilation was saved to the file: " + outputFileName); - } else { - notifyError("Could not save compiled file."); + program.assignLabels(); + program.saveToFile(outputFileName); + + notifyInfo(String.format("Compile was successful.\n\tOutput: %s", outputFileName)); + + if (memory != null) { + memory.clear(); + program.loadIntoMemory(memory); + notifyInfo("Compiled file was loaded into program memory."); + } else { + notifyWarning("Memory is not available"); + } } + } catch (Exception e) { LOGGER.trace("Compilation failed", e); notifyError("Compilation failed: " + e.getMessage()); @@ -113,7 +117,7 @@ public boolean compile(String inputFileName, String outputFileName) { @Override public boolean compile(String inputFileName) { - int i = inputFileName.lastIndexOf(".ram"); + int i = inputFileName.toLowerCase(Locale.ENGLISH).lastIndexOf(".ram"); String outputFileName = inputFileName; if (i >= 0) { @@ -124,8 +128,9 @@ public boolean compile(String inputFileName) { } @Override - public LexicalAnalyzer getLexer(Reader reader) { - return new LexerImpl(reader); + public LexicalAnalyzer createLexer(String s) { + RAMLexer lexer = createLexer(CharStreams.fromString(s)); + return new LexicalAnalyzerImpl(lexer); } @Override @@ -138,50 +143,23 @@ public List getSourceFileExtensions() { return SOURCE_FILE_EXTENSIONS; } - private CompiledCode compileFrom(String inputFileName) throws Exception { - Objects.requireNonNull(inputFileName); - - notifyInfo(getTitle() + ", version " + getVersion()); - - Object parsedProgram; - CompiledCode compiledProgram = new CompiledCode(); - - try (Reader reader = new FileReader(inputFileName)) { - lexer.reset(reader, 0, 0, 0); - parser.reset(); - parsedProgram = parser.parse().value; - - if (parsedProgram == null) { - notifyError("Unexpected end of file"); - throw new Exception("Unexpected end of file"); - } - if (parser.hasSyntaxErrors()) { - throw new Exception("Program has errors"); - } - - // do several passes for compiling - Program program = (Program) parsedProgram; - program.pass1(0); - program.pass2(compiledProgram); - - notifyInfo("Compile was successful."); - if (memory != null) { - //clear the memory before loading new image - memory.clear(); - compiledProgram.loadIntoMemory(memory); - notifyInfo("Compiled file was loaded into program memory."); - } else { - notifyWarning("Memory is not available"); - } - } - return compiledProgram; - } - private Optional getResourceBundle() { try { - return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.compiler.ramc.version")); + return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.compiler.ram.version")); } catch (MissingResourceException e) { return Optional.empty(); } } + + private RAMLexer createLexer(CharStream input) { + RAMLexer lexer = new RAMLexer(input); + lexer.removeErrorListeners(); + return lexer; + } + + private RAMParser createParser(TokenStream tokenStream) { + RAMParser parser = new RAMParser(tokenStream); + parser.removeErrorListeners(); + return parser; + } } diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java new file mode 100644 index 000000000..d0e0fb030 --- /dev/null +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java @@ -0,0 +1,96 @@ +package net.emustudio.plugins.compiler.ram; + +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; +import net.emustudio.emulib.plugins.compiler.Token; +import org.antlr.v4.runtime.CharStreams; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Objects; + +import static net.emustudio.plugins.compiler.ram.RAMLexer.*; +import static org.antlr.v4.runtime.Recognizer.EOF; + +public class LexicalAnalyzerImpl implements LexicalAnalyzer { + private final RAMLexer lexer; + private static final int[] tokenMap = new int[ERROR + 1]; + + static { + tokenMap[COMMENT] = Token.COMMENT; + tokenMap[EOL] = Token.WHITESPACE; + tokenMap[WS] = Token.WHITESPACE; + tokenMap[OPCODE_READ] = Token.RESERVED; + tokenMap[OPCODE_WRITE] = Token.RESERVED; + tokenMap[OPCODE_LOAD] = Token.RESERVED; + tokenMap[OPCODE_STORE] = Token.RESERVED; + tokenMap[OPCODE_ADD] = Token.RESERVED; + tokenMap[OPCODE_HALT] = Token.RESERVED; + tokenMap[OPCODE_DIV] = Token.RESERVED; + tokenMap[OPCODE_MUL] = Token.RESERVED; + tokenMap[OPCODE_SUB] = Token.RESERVED; + tokenMap[OPCODE_JMP] = Token.RESERVED; + tokenMap[OPCODE_JGTZ] = Token.RESERVED; + tokenMap[OPCODE_JZ] = Token.RESERVED; + + tokenMap[PREP_INPUT] = Token.PREPROCESSOR; + + tokenMap[OP_DIRECT] = Token.OPERATOR; + tokenMap[OP_INDIRECT] = Token.OPERATOR; + + tokenMap[LIT_NUMBER] = Token.LITERAL; + tokenMap[LIT_HEXNUMBER_1] = Token.LITERAL; + tokenMap[LIT_HEXNUMBER_2] = Token.LITERAL; + tokenMap[LIT_OCTNUMBER] = Token.LITERAL; + tokenMap[LIT_BINNUMBER] = Token.LITERAL; + tokenMap[LIT_STRING_1] = Token.LITERAL; + tokenMap[LIT_STRING_2] = Token.LITERAL; + + tokenMap[ID_IDENTIFIER] = Token.IDENTIFIER; + tokenMap[ID_LABEL] = Token.IDENTIFIER; + + tokenMap[ERROR] = Token.ERROR; + } + + + public LexicalAnalyzerImpl(RAMLexer lexer) { + this.lexer = Objects.requireNonNull(lexer); + } + + @Override + public Token nextToken() { + org.antlr.v4.runtime.Token token = lexer.nextToken(); + return new Token() { + @Override + public int getType() { + return convertLexerTokenType(token.getType()); + } + + @Override + public int getOffset() { + return token.getStartIndex(); + } + + @Override + public String getText() { + return token.getText(); + } + }; + } + + @Override + public boolean isAtEOF() { + return lexer._hitEOF; + } + + @Override + public void reset(InputStream inputStream) throws IOException { + lexer.setInputStream(CharStreams.fromStream(inputStream)); + } + + private int convertLexerTokenType(int tokenType) { + if (tokenType == EOF) { + return Token.EOF; + } + return tokenMap[tokenType]; + } +} diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParserErrorListener.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParserErrorListener.java new file mode 100644 index 000000000..99d1eca9b --- /dev/null +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParserErrorListener.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.compiler.ram; + +import net.emustudio.plugins.compiler.ram.exceptions.SyntaxErrorException; +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; + +public class ParserErrorListener extends BaseErrorListener { + + @Override + public void syntaxError( + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { + + if (e == null) { + throw new SyntaxErrorException(line, charPositionInLine, msg); + } else { + throw new SyntaxErrorException(line, charPositionInLine, msg, e); + } + } +} diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParsingUtils.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParsingUtils.java new file mode 100644 index 000000000..c71ef78e2 --- /dev/null +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParsingUtils.java @@ -0,0 +1,57 @@ +package net.emustudio.plugins.compiler.ram; + +import org.antlr.v4.runtime.Token; + +import java.util.Locale; + +public class ParsingUtils { + + public static String parseLitString(Token token) { + // LIT_STRING_1: '\'' ~[']* '\''; + // LIT_STRING_2: '"' ~["]* '"'; + String text = token.getText(); + return text.substring(1, text.length() - 1); + } + + public static int parseLitHex1(Token token) { + // LIT_HEXNUMBER_1: [\-]? '0' X [0-9a-fA-F]+; + return Integer.decode(token.getText()); + } + + public static int parseLitHex2(Token token) { + // LIT_HEXNUMBER_2: [\-]? [0-9a-fA-F]+ H; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 16); + } + + public static int parseLitOct(Token token) { + // LIT_OCTNUMBER: [\-]? [0-7]+ [oOqQ]; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 8); + } + + public static int parseLitDec(Token token) { + // LIT_NUMBER: [\-]? [0-9]+ D? + String rawText = token.getText(); + if (rawText.endsWith("d") || rawText.endsWith("D")) { + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 10); + } else { + return Integer.parseInt(rawText, 10); + } + } + + public static int parseLitBin(Token token) { + // LIT_BINNUMBER: [01]+ B; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 2); + } + + public static String parseLabel(Token token) { + String rawText = token.getText(); + return rawText.substring(0, rawText.length() - 1); + } + + public static String normalizeId(String id) { + return id.toLowerCase(Locale.ENGLISH); + } +} diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/Runner.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/Runner.java similarity index 91% rename from plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/Runner.java rename to plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/Runner.java index 671525449..dd14fd8e8 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ramc/Runner.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/Runner.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.ramc; +package net.emustudio.plugins.compiler.ram; import net.emustudio.emulib.plugins.compiler.CompilerListener; @@ -39,7 +39,7 @@ public static void main(String... args) { printHelp(); return; } else if (arg.equals("--version") || arg.equals("-v")) { - System.out.println(new CompilerImpl(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE).getVersion()); + System.out.println(new CompilerRAM(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE).getVersion()); return; } else { break; @@ -60,7 +60,7 @@ public static void main(String... args) { outputFile += ".hex"; } - CompilerImpl compiler = new CompilerImpl(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE); + CompilerRAM compiler = new CompilerRAM(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE); compiler.addCompilerListener(new CompilerListener() { @Override diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/SerializableOptional.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/SerializableOptional.java new file mode 100644 index 000000000..861289764 --- /dev/null +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/SerializableOptional.java @@ -0,0 +1,49 @@ +package net.emustudio.plugins.compiler.ram; + +import java.io.Serializable; +import java.util.Objects; +import java.util.Optional; + +public class SerializableOptional implements Serializable { + public final T value; + + public SerializableOptional(T value) { + this.value = value; + } + + public Optional opt() { + return Optional.ofNullable(value); + } + + public static SerializableOptional empty() { + return new SerializableOptional<>(null); + } + + public static SerializableOptional ofNullable(T value) { + return new SerializableOptional<>(value); + } + + public static SerializableOptional fromOpt(Optional valueOpt) { + return new SerializableOptional<>(valueOpt.orElse(null)); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SerializableOptional that = (SerializableOptional) o; + + return Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return value != null ? value.hashCode() : 0; + } + + @Override + public String toString() { + return String.valueOf(value); + } +} diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java new file mode 100644 index 000000000..7c2e1848a --- /dev/null +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java @@ -0,0 +1,105 @@ +package net.emustudio.plugins.compiler.ram.ast; + +import net.emustudio.plugins.compiler.ram.SerializableOptional; +import net.emustudio.plugins.memory.ram.api.RAMInstruction; +import net.emustudio.plugins.memory.ram.api.RAMLabel; +import net.emustudio.plugins.memory.ram.api.RAMValue; + +import java.util.Objects; +import java.util.Optional; + +public class Instruction implements RAMInstruction { + public final int line; + public final int column; + + private final int address; + private final Opcode opcode; + private final Direction direction; + private final SerializableOptional operand; + private SerializableOptional label; + + public Instruction(int line, int column, Opcode opcode, Direction direction, + int address, Optional operand) { + this(line, column, opcode, direction, address, operand, null); + } + + public Instruction(int line, int column, Opcode opcode, Direction direction, + int address, Optional operand, RAMLabel label) { + this.opcode = opcode; + this.direction = direction; + this.address = address; + this.operand = SerializableOptional.fromOpt(Objects.requireNonNull(operand)); + this.line = line; + this.column = column; + this.label = SerializableOptional.ofNullable(label); + } + + public Instruction(Opcode opcode, Direction direction, + int address, Optional operand, RAMLabel label) { + this(0, 0, opcode, direction, address, operand, label); + } + + @Override + public Opcode getOpcode() { + return opcode; + } + + @Override + public Direction getDirection() { + return direction; + } + + @Override + public Optional getOperand() { + return operand.opt(); + } + + @Override + public int getAddress() { + return address; + } + + @Override + public Optional getLabel() { + return label.opt(); + } + + public void setLabel(RAMLabel label) { + this.label = SerializableOptional.ofNullable(label); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Instruction that = (Instruction) o; + + if (address != that.address) return false; + if (opcode != that.opcode) return false; + if (direction != that.direction) return false; + if (!operand.equals(that.operand)) return false; + return label.equals(that.label); + } + + @Override + public int hashCode() { + int result = address; + result = 31 * result + opcode.hashCode(); + result = 31 * result + direction.hashCode(); + result = 31 * result + operand.hashCode(); + result = 31 * result + label.hashCode(); + return result; + } + + @Override + public String toString() { + return "Instruction{" + + "address=" + address + + ", opcode=" + opcode + + ", direction=" + direction + + ", operand=" + operand + + ", label=" + label + + '}'; + } +} diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java new file mode 100644 index 000000000..a87367c0d --- /dev/null +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java @@ -0,0 +1,72 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2020 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.compiler.ram.ast; + +import net.emustudio.plugins.memory.ram.api.RAMLabel; + +public class Label implements RAMLabel { + public final int line; + public final int column; + + private final String label; + private final int address; + + public Label(int line, int column, String text, int address) { + this.line = line; + this.column = column; + this.label = text.toUpperCase(); + this.address = address; + } + + @Override + public String getLabel() { + return label; + } + + @Override + public int getAddress() { + return address; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Label label1 = (Label) o; + + if (address != label1.address) return false; + return label.equals(label1.label); + } + + @Override + public int hashCode() { + int result = label.hashCode(); + result = 31 * result + address; + return result; + } + + @Override + public String toString() { + return "{" + + "label='" + label + '\'' + + ", address=" + address + + '}'; + } +} diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java new file mode 100644 index 000000000..a8e7172ed --- /dev/null +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java @@ -0,0 +1,89 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2020 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.compiler.ram.ast; + +import net.emustudio.plugins.compiler.ram.ParsingUtils; +import net.emustudio.plugins.compiler.ram.exceptions.CompileException; +import net.emustudio.plugins.memory.ram.api.RAMInstruction; +import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; +import net.emustudio.plugins.memory.ram.api.RAMValue; + +import java.io.*; +import java.util.*; + +public class Program { + private final List instructions = new ArrayList<>(); + private final Map labels = new HashMap<>(); + private final List inputs = new ArrayList<>(); + + public void add(Instruction instruction) { + this.instructions.add(instruction); + } + + public void add(Label label) { + String labelNorm = ParsingUtils.normalizeId(label.getLabel()); + if (labels.containsKey(labelNorm)) { + throw new CompileException(label.line, label.column, "Label is already defined!"); + } + this.labels.put(labelNorm, label); + } + + public void add(Value input) { + this.inputs.add(input); + } + + public void assignLabels() { + for (Instruction instruction : instructions) { + instruction + .getOperand() + .filter(v -> v.getType() == RAMValue.Type.ID) + .map(RAMValue::getStringValue) + .flatMap(this::getLabel) + .ifPresent(instruction::setLabel); + } + } + + public void loadIntoMemory(RAMMemoryContext memory) { + memory.setLabels(new ArrayList<>(labels.values())); + memory.setInputs(new ArrayList<>(inputs)); + for (RAMInstruction instruction : instructions) { + memory.write(instruction.getAddress(), instruction); + } + } + + public void saveToFile(String filename) throws IOException { + Map labels = new HashMap<>(); + for (Label label : this.labels.values()) { + labels.put(label.getAddress(), label.getLabel()); + } + + OutputStream file = new FileOutputStream(filename); + OutputStream buffer = new BufferedOutputStream(file); + try (ObjectOutput output = new ObjectOutputStream(buffer)) { + output.writeObject(labels); + output.writeObject(inputs); + output.writeObject(instructions); + } + } + + private Optional

- * Tape options are: - * - (R)ead - * - (R)ead (W)rite - * - (W)rite - * - direction: - * - only left - * - only right - * - both + * The tape position can move to the left, or to the right. *

* The CPU must assign all the details to this tape using the tape context. *

@@ -48,39 +44,39 @@ */ public class AbstractTapeContextImpl implements AbstractTapeContext { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTapeContextImpl.class); - private final List tape; // tape is an array of strings - private int currentPosition; // actual tape position - private boolean bounded; // tape is bounded form the left? - private boolean editable; // if tape is editable by user - private TapeListener listener; + private final AtomicReference symbolLog = new AtomicReference<>(); + private final Map content = new HashMap<>(); + private final ReadWriteLock rwl = new ReentrantReadWriteLock(); + + private final AbstractTape tape; + + private int position = 0; + private boolean leftBounded; + private boolean editable; private boolean highlightCurrentPosition; private boolean clearAtReset = true; - private final DeviceImpl abst; - private Writer outw; private boolean displayRowNumbers = false; + private TapeListener listener; public interface TapeListener extends EventListener { void tapeChanged(); } - AbstractTapeContextImpl(DeviceImpl abst) { - this.abst = abst; - listener = null; - tape = new ArrayList<>(); - currentPosition = 0; - bounded = false; + AbstractTapeContextImpl(AbstractTape tape) { + this.tape = Objects.requireNonNull(tape); + leftBounded = false; editable = true; highlightCurrentPosition = true; } @Override public void setTitle(String title) { - abst.setGUITitle(title); + tape.setGUITitle(title); } @Override - public boolean showPositions() { + public boolean getShowPositions() { return displayRowNumbers; } @@ -95,97 +91,88 @@ public void setShowPositions(boolean showPositions) { */ @Override public void clear() { - tape.clear(); - currentPosition = 0; + writeSynchronized(() -> { + content.clear(); + position = 0; + }); fireChange(); } void reset() { - currentPosition = 0; if (clearAtReset) { clear(); + } else { + writeSynchronized(() -> position = 0); + fireChange(); } - fireChange(); } @Override - public void setBounded(boolean bounded) { - this.bounded = bounded; + public void setLeftBounded(boolean bounded) { + this.leftBounded = bounded; } @Override - public boolean isBounded() { - return bounded; + public boolean isLeftBounded() { + return leftBounded; } @Override public boolean moveLeft() { - if (currentPosition > 0) { - currentPosition--; - fireChange(); - return true; - } else if (!bounded) { - currentPosition = 0; - tape.add(0, ""); - fireChange(); - return true; - } - return false; + AtomicBoolean moved = new AtomicBoolean(false); + writeSynchronized(() -> { + if (position > 0) { + position--; + moved.set(true); + } else if (!leftBounded) { + position = 0; + moved.set(true); + } + }); + fireChange(); + return moved.get(); } @Override public void moveRight() { - currentPosition++; - if (currentPosition >= tape.size()) { - tape.add(""); - } + writeSynchronized(() -> position++); fireChange(); } - public void addSymbolFirst(String symbol) { - if (bounded) { + public void addFirst(TapeSymbol symbol) { + if (leftBounded) { return; } - if (symbol == null) { - symbol = ""; - } - tape.add(0, symbol); - writeSymbol(0, symbol); - currentPosition++; - fireChange(); - } - - public void addSymbolLast(String symbol) { - if (symbol == null) { - symbol = ""; - } - tape.add(symbol); - writeSymbol(tape.size() - 1, symbol); + writeSynchronized(() -> { + incrementContentPositions(); + content.put(0, symbol); + logSymbol(0, symbol); + position++; + }); fireChange(); } - public void removeSymbol(int pos) { - if (pos >= tape.size()) { - return; - } - tape.remove(pos); - writeSymbol(pos, ""); - - if (this.currentPosition >= pos) { - this.currentPosition--; - } + public void addLast(TapeSymbol symbol) { + writeSynchronized(() -> { + int index = position; + if (!content.isEmpty()) { + index = Collections.max(content.keySet()) + 1; + } + content.put(index, symbol); + logSymbol(index, symbol); + }); fireChange(); } - public void editSymbol(int pos, String symbol) { - if (pos >= tape.size()) { - return; - } - if (symbol == null) { - symbol = ""; - } - tape.set(pos, symbol); - writeSymbol(pos, symbol); + @Override + public void removeSymbolAt(int position) { + writeSynchronized(() -> { + content.remove(position); + logSymbol(position, TapeSymbol.EMPTY); + if (this.position >= position) { + this.position = (position > 0) ? position - 1 : 0; + } + }); fireChange(); } @@ -199,31 +186,30 @@ public boolean getEditable() { } @Override - public String getSymbolAt(int pos) { - if (pos >= tape.size() || (pos < 0)) { - return ""; + public Optional getSymbolAt(int position) { + rwl.readLock().lock(); + try { + return Optional.ofNullable(content.get(position)); + } finally { + rwl.readLock().unlock(); } - return tape.get(pos); } @Override - public void setSymbolAt(int pos, String symbol) { - if (pos >= tape.size()) { - while (pos > tape.size()) { - tape.add(""); - } - tape.add(symbol); - writeSymbol(pos, symbol); - } else if (pos >= 0) { - tape.set(pos, symbol); - writeSymbol(pos, symbol); + public void setSymbolAt(int position, TapeSymbol symbol) { + if (position < 0) { + return; } + writeSynchronized(() -> { + content.put(position, symbol); + logSymbol(position, symbol); + }); fireChange(); } @Override - public void setHighlightHeadPosition(boolean visible) { - highlightCurrentPosition = visible; + public void setHighlightHeadPosition(boolean highlight) { + highlightCurrentPosition = highlight; } @Override @@ -237,82 +223,85 @@ public boolean highlightCurrentPosition() { @Override public int getSize() { - return tape.size(); + rwl.readLock().lock(); + try { + return content.size(); + } finally { + rwl.readLock().unlock(); + } } @Override public int getHeadPosition() { - return currentPosition; + rwl.readLock().lock(); + try { + return position; + } finally { + rwl.readLock().unlock(); + } } @Override public boolean isEmpty() { - return tape.isEmpty(); - } - - @Override - public String readData() { - if (currentPosition >= tape.size() || (currentPosition < 0)) { - return ""; + rwl.readLock().lock(); + try { + return content.isEmpty(); + } finally { + rwl.readLock().unlock(); } - return tape.get(currentPosition); } @Override - public void writeData(String data) { - if (currentPosition >= tape.size()) { - tape.add(currentPosition, data); - } else { - tape.set(currentPosition, data); + public TapeSymbol readData() { + rwl.readLock().lock(); + try { + return content.getOrDefault(position, TapeSymbol.EMPTY); + } finally { + rwl.readLock().unlock(); } - writeSymbol(currentPosition, data); - fireChange(); } @Override - public Class getDataType() { - return String.class; - } - - private void writeSymbol(int position, String symbol) { - if (outw != null) { - try { - outw.write(position + " "); - outw.write(symbol + "\n"); - outw.flush(); - } catch (IOException e) { - LOGGER.error("Could not write to the output file", e); - } - } + public void writeData(TapeSymbol symbol) { + setSymbolAt(position, symbol); } - private String createValidFileName(String str) { - return str.trim().toLowerCase().replaceAll("[*.#%&\\s+!~/?<>,|{}\\[\\]\\\\\"'`=]", "_"); + @Override + public Class getDataType() { + return TapeSymbol.class; } /** - * Set verbose mode. If verbose mode is set, the output - * is redirected also to a file. + * Set if changed symbols should be logged in a file. + *

+ * The log file name will be derived from a tape title: [tape-title].out * - * @param verbose set/reset/unset verbose mode + * @param logSymbols whether to log symbols in a file */ - void setVerbose(boolean verbose) { - if (outw != null) { - try { - outw.close(); - } catch (IOException e) { - LOGGER.error("Could not close output file", e); + void setLogSymbols(boolean logSymbols) { + // should be called in a synchronized context + + if (!logSymbols) { + Writer w = symbolLog.getAndSet(null); + if (w != null) { + LOGGER.info("Stopping logging symbols changes"); + try { + w.close(); + } catch (IOException e) { + LOGGER.error("Could not close the symbol log", e); + } } - outw = null; - } - if (verbose) { - String fileName = createValidFileName(abst.getTitle().trim()); - LOGGER.info("Being verbose. Writing to file:" + fileName + ".out"); - File f = new File(fileName + ".out"); + } else { + String fileName = createValidFileName(tape.getTitle().trim()) + ".out"; + File file = new File(fileName + ".out"); + LOGGER.info("Starting logging symbols changes to a file:" + fileName); try { - outw = new FileWriter(f); + Writer w = new FileWriter(file); + if (!symbolLog.compareAndSet(null, w)) { + w.close(); + } } catch (IOException e) { - LOGGER.error("Could not create FileWriter", e); + LOGGER.error("Could not create the symbol log file", e); } } } @@ -321,9 +310,45 @@ public void setListener(TapeListener listener) { this.listener = listener; } + private void writeSynchronized(Runnable r) { + rwl.writeLock().lock(); + try { + r.run(); + } finally { + rwl.writeLock().unlock(); + } + } + + private void fireChange() { if (listener != null) { listener.tapeChanged(); } } + + private void logSymbol(int position, TapeSymbol symbol) { + Writer w = symbolLog.get(); + if (w != null) { + try { + w.write(position + " " + symbol + "\n"); + w.flush(); + } catch (IOException e) { + LOGGER.error("Could not write a symbol to symbol log", e); + } + } + } + + private String createValidFileName(String str) { + return str.trim().toLowerCase().replaceAll("[*.#%&\\s+!~/?<>,|{}\\[\\]\\\\\"'`=]", "_"); + } + + // should be called in a synchronized context + private void incrementContentPositions() { + Map newContent = new HashMap<>(); + for (int position : content.keySet()) { + newContent.put(position + 1, content.get(position)); + } + content.clear(); + content.putAll(newContent); + } } diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java index 47de14df9..accb07e01 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java @@ -21,12 +21,16 @@ import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.device.DeviceContext; +import java.util.List; +import java.util.Optional; +import java.util.Set; + /** * Public API of the abstract tape. */ @SuppressWarnings("unused") @PluginContext -public interface AbstractTapeContext extends DeviceContext { +public interface AbstractTapeContext extends DeviceContext { /** * Clear content of the tape. @@ -39,14 +43,14 @@ public interface AbstractTapeContext extends DeviceContext { * @param bounded true if the tape should be left-bounded, * false if unbounded. */ - void setBounded(boolean bounded); + void setLeftBounded(boolean bounded); /** * Determine if the tape is left-bounded. * * @return true - left-bounded, false - unbounded. */ - boolean isBounded(); + boolean isLeftBounded(); /** * Move the tape one symbol to the left. @@ -76,32 +80,34 @@ public interface AbstractTapeContext extends DeviceContext { /** * Get symbol at the specified position. * - * @param pos position in the tape, starting from 0 - * @return symbol at given position; if the position is out of bounds, then empty string is returned. + * @param position position in the tape, starting from 0 + * @return symbol at given position; or Optional.empty() if the position is out of bounds */ - String getSymbolAt(int pos); + Optional getSymbolAt(int position); /** * Set symbol at the specified position. - *

+ * * If the position is < 0, then no symbol will be set. - *

- * If the position is > tape size, empty symbols will be added until the required tape size is ensured. - * Then, the symbol is added at the specified position. - *

- * This method should be used only when loading some initial content to the tape. * - * @param pos position in the tape, starting from 0 - * @param symbol symbol value + * @param position position in the tape, starting from 0 + * @param symbol symbol value + */ + void setSymbolAt(int position, TapeSymbol symbol); + + /** + * Remove symbol at given position + * + * @param position symbol position in the tape */ - void setSymbolAt(int pos, String symbol); + void removeSymbolAt(int position); /** * Sets whether the symbol at which the head is pointing should be "highlighted" in GUI. * - * @param visible true if yes; false otherwise. + * @param highlight true if yes; false otherwise. */ - void setHighlightHeadPosition(boolean visible); + void setHighlightHeadPosition(boolean highlight); /** * Seths whether the tape should be cleared at emulation reset. @@ -122,7 +128,7 @@ public interface AbstractTapeContext extends DeviceContext { * * @return true if yes; false otherwise */ - boolean showPositions(); + boolean getShowPositions(); /** * Set whether the symbol positions should be displayed in GUI. diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java new file mode 100644 index 000000000..0e5d30480 --- /dev/null +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java @@ -0,0 +1,57 @@ +package net.emustudio.plugins.device.abstracttape.api; + +import java.util.Objects; + +import static net.emustudio.plugins.device.abstracttape.api.TapeSymbol.Type.NUMBER; +import static net.emustudio.plugins.device.abstracttape.api.TapeSymbol.Type.STRING; + +public class TapeSymbol { + public enum Type { + NUMBER, STRING + } + + public final static TapeSymbol EMPTY = new TapeSymbol(""); + + public final int number; + public final String string; + public final Type type; + + public TapeSymbol(String string) { + this.string = Objects.requireNonNullElse(string, ""); + this.number = 0; + this.type = STRING; + } + + public TapeSymbol(int number) { + this.number = number; + this.string = null; + this.type = NUMBER; + } + + public static TapeSymbol guess(String s) { + try { + int value = Integer.decode(s); + return new TapeSymbol(value); + } catch (NumberFormatException e) { + return new TapeSymbol(s); + } + } + + @Override + public String toString() { + return (type == NUMBER) ? String.valueOf(number) : string; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TapeSymbol that = (TapeSymbol) o; + return number == that.number && Objects.equals(string, that.string) && type == that.type; + } + + @Override + public int hashCode() { + return Objects.hash(number, string, type); + } +} diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeCellRenderer.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeCellRenderer.java index 306f626c2..6c04a164a 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeCellRenderer.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeCellRenderer.java @@ -1,6 +1,7 @@ package net.emustudio.plugins.device.abstracttape.gui; import net.emustudio.plugins.device.abstracttape.AbstractTapeContextImpl; +import net.emustudio.plugins.device.abstracttape.api.TapeSymbol; import javax.swing.*; import java.awt.*; @@ -27,8 +28,8 @@ public Component getListCellRendererComponent(JList list, Object value, int i setBackground(Color.WHITE); } - String s = tapeContext.getSymbolAt(index); - if (s == null || s.equals("")) { + String s = tapeContext.getSymbolAt(index).map(TapeSymbol::toString).orElse(""); + if (s.equals("")) { setForeground(Color.DARK_GRAY); } else { setForeground(Color.BLACK); diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java index cc2822dd4..e9ee7d737 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java @@ -20,6 +20,7 @@ import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.plugins.device.abstracttape.AbstractTapeContextImpl; +import net.emustudio.plugins.device.abstracttape.api.TapeSymbol; import javax.swing.*; import java.awt.*; @@ -62,7 +63,7 @@ public TapeGui(JFrame parent, String title, AbstractTapeContextImpl tapeContext, private void changeEditable() { boolean b = tapeContext.getEditable(); - btnAddFirst.setEnabled(b && !tapeContext.isBounded()); + btnAddFirst.setEnabled(b && !tapeContext.isLeftBounded()); btnAddLast.setEnabled(b); btnRemove.setEnabled(b); btnEdit.setEnabled(b); @@ -89,12 +90,14 @@ private void initComponents() { btnAddFirst.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/device/abstracttape/gui/go-up.png"))); btnAddFirst.addActionListener(e -> dialogs .readString("Symbol value:", "Add symbol (on top)") - .ifPresent(tapeContext::addSymbolFirst)); + .map(TapeSymbol::guess) + .ifPresent(tapeContext::addFirst)); btnAddLast.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/device/abstracttape/gui/go-down.png"))); btnAddLast.addActionListener(e -> dialogs .readString("Symbol value:", "Add symbol (on bottom)") - .ifPresent(tapeContext::addSymbolLast)); + .map(TapeSymbol::guess) + .ifPresent(tapeContext::addLast)); btnEdit.addActionListener(e -> { int symbolIndex = lstTape.getSelectedIndex(); @@ -102,8 +105,9 @@ private void initComponents() { dialogs.showError("A symbol must be selected"); } else { dialogs - .readString("Enter symbol value:", "Edit symbol", tapeContext.getSymbolAt(symbolIndex)) - .ifPresent(symbol -> tapeContext.editSymbol(symbolIndex, symbol)); + .readString("Enter symbol value:", "Edit symbol", tapeContext.getSymbolAt(symbolIndex).toString()) + .map(TapeSymbol::guess) + .ifPresent(symbol -> tapeContext.setSymbolAt(symbolIndex, symbol)); } }); btnRemove.addActionListener(e -> { @@ -112,7 +116,7 @@ private void initComponents() { dialogs.showError("A symbol must be selected"); return; } - tapeContext.removeSymbol(symbolIndex); + tapeContext.removeSymbolAt(symbolIndex); }); btnClear.addActionListener(e -> tapeContext.clear()); diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java index 1adebe9a8..0c0d24c66 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java @@ -1,12 +1,14 @@ package net.emustudio.plugins.device.abstracttape.gui; import net.emustudio.plugins.device.abstracttape.AbstractTapeContextImpl; +import net.emustudio.plugins.device.abstracttape.api.AbstractTapeContext; +import net.emustudio.plugins.device.abstracttape.api.TapeSymbol; import javax.swing.*; import java.util.Objects; public class TapeModel extends AbstractListModel { - private final AbstractTapeContextImpl tapeContext; + private final AbstractTapeContext tapeContext; public TapeModel(AbstractTapeContextImpl tapeContext) { this.tapeContext = Objects.requireNonNull(tapeContext); @@ -15,16 +17,11 @@ public TapeModel(AbstractTapeContextImpl tapeContext) { @Override public String getElementAt(int index) { String element = ""; - - if (tapeContext.showPositions()) { + if (tapeContext.getShowPositions()) { element += String.format("%02d: ", index); } - String symbolAtIndex = tapeContext.getSymbolAt(index); - if (symbolAtIndex == null || symbolAtIndex.isEmpty()) { - element += ""; - } else { - element += symbolAtIndex; - } + String symbolAtIndex = tapeContext.getSymbolAt(index).map(TapeSymbol::toString).orElse(""); + element += symbolAtIndex; return element; } diff --git a/plugins/device/abstract-tape/src/test/java/net/emustudio/plugins/device/abstracttape/DeviceImplTest.java b/plugins/device/abstract-tape/src/test/java/net/emustudio/plugins/device/abstracttape/AbstractTapeTest.java similarity index 86% rename from plugins/device/abstract-tape/src/test/java/net/emustudio/plugins/device/abstracttape/DeviceImplTest.java rename to plugins/device/abstract-tape/src/test/java/net/emustudio/plugins/device/abstracttape/AbstractTapeTest.java index dfb2e4c2d..95538d1d6 100644 --- a/plugins/device/abstract-tape/src/test/java/net/emustudio/plugins/device/abstracttape/DeviceImplTest.java +++ b/plugins/device/abstract-tape/src/test/java/net/emustudio/plugins/device/abstracttape/AbstractTapeTest.java @@ -10,8 +10,8 @@ import static org.easymock.EasyMock.*; import static org.junit.Assert.assertNotEquals; -public class DeviceImplTest { - private DeviceImpl device; +public class AbstractTapeTest { + private AbstractTape device; @Before public void setup() { @@ -21,7 +21,7 @@ public void setup() { expect(applicationApi.getContextPool()).andReturn(contextPool).anyTimes(); replay(applicationApi); - this.device = new DeviceImpl(0, applicationApi, PluginSettings.UNAVAILABLE); + this.device = new AbstractTape(0, applicationApi, PluginSettings.UNAVAILABLE); } @After diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java index 502207fcf..36cc5d1a1 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java @@ -70,11 +70,7 @@ public void process() { private void inputReceived(int input) { for (DeviceContext device : devices) { - try { - device.writeData((byte)input); - } catch (IOException e) { - LOGGER.error("[device={}, input={}] Could not notify device about key pressed", device, input, e); - } + device.writeData((byte) input); } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java index 8e0a6b7a4..3ea21d228 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java @@ -27,7 +27,6 @@ import java.awt.event.ContainerListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -142,7 +141,7 @@ public void keyPressed(KeyEvent evt) { } } if (newKeyCode != 0) { - if (loadCursorPosition.notAccepted((byte)newKeyCode)){ + if (loadCursorPosition.notAccepted((byte) newKeyCode)) { inputReceived(newKeyCode); } } @@ -175,11 +174,7 @@ public void destroy() { private void inputReceived(int input) { for (DeviceContext device : devices) { - try { - device.writeData((byte)input); - } catch (IOException e) { - LOGGER.error("[device={}, input={}] Could not notify device about key pressed", device, input, e); - } + device.writeData((byte) input); } } diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java index 3c87677ba..77506ded5 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java @@ -20,18 +20,17 @@ import net.emustudio.emulib.plugins.memory.AbstractMemoryContext; import net.emustudio.plugins.memory.ram.api.RAMInstruction; +import net.emustudio.plugins.memory.ram.api.RAMLabel; import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; +import net.emustudio.plugins.memory.ram.api.RAMValue; import java.io.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class MemoryContextImpl extends AbstractMemoryContext implements RAMMemoryContext { - private final List memory = new ArrayList<>(); - private final Map labels = new HashMap<>(); - private final List inputs = new ArrayList<>(); // not for memory, but for CPU. Memory holds program so... + private final Map memory = new HashMap<>(); + private final Map labels = new HashMap<>(); + private final List inputs = new ArrayList<>(); @Override public void clear() { @@ -52,31 +51,31 @@ public int getSize() { } @Override - public RAMInstruction read(int pos) { - return memory.get(pos); + public RAMInstruction read(int address) { + return memory.get(address); } @Override - public RAMInstruction[] readWord(int pos) { - return new RAMInstruction[]{memory.get(pos), null}; + public RAMInstruction[] read(int address, int count) { + List copy = new ArrayList<>(); + for (int i = address; i < address + count; i++) { + copy.add(memory.get(i)); + } + return copy.toArray(new RAMInstruction[0]); } @Override - public void write(int pos, RAMInstruction instr) { - if (pos >= memory.size()) { - memory.add(pos, instr); - notifyMemoryChanged(memory.size()); - notifyMemorySizeChanged(); - } else { - memory.set(pos, instr); - } - notifyMemoryChanged(pos); + public void write(int address, RAMInstruction value) { + memory.put(address, value); + notifyMemoryChanged(address); } - // This method is not and won't be implemented. @Override - public void writeWord(int pos, RAMInstruction[] instr) { - throw new UnsupportedOperationException(); + public void write(int address, RAMInstruction[] values, int count) { + for (int i = 0; i < count; i++) { + memory.put(address + i, values[i]); + notifyMemoryChanged(address + i); + } } @Override @@ -85,36 +84,30 @@ public Class getDataType() { } @Override - public void addLabel(int pos, String label) { - labels.put(pos, label); + public synchronized void setLabels(List labels) { + this.labels.clear(); + for (RAMLabel label: labels) { + this.labels.put(label.getAddress(), label); + } } @Override - public String getLabel(int pos) { - return labels.get(pos); - } - - public Map getSwitchedLabels() { - Map h = new HashMap<>(); - for (Map.Entry entry : labels.entrySet()) { - h.put(entry.getValue(), entry.getKey()); - } - return h; + public RAMLabel getLabel(int address) { + return labels.get(address); } @Override - public void addInputs(List inputs) { - if (inputs == null) { - return; - } + public synchronized void setInputs(List inputs) { + clearInputs(); this.inputs.addAll(inputs); } @Override - public List getInputs() { - return inputs; + public List getInputs() { + return Collections.unmodifiableList(inputs); } + @SuppressWarnings("unchecked") public void deserialize(String filename) throws IOException, ClassNotFoundException { try { InputStream file = new FileInputStream(filename); @@ -125,9 +118,9 @@ public void deserialize(String filename) throws IOException, ClassNotFoundExcept inputs.clear(); memory.clear(); - labels.putAll((Map) input.readObject()); - inputs.addAll((List) input.readObject()); - memory.addAll((List) input.readObject()); + labels.putAll((Map) input.readObject()); + inputs.addAll((List) input.readObject()); + memory.putAll((Map) input.readObject()); input.close(); } finally { @@ -137,9 +130,6 @@ public void deserialize(String filename) throws IOException, ClassNotFoundExcept } public void destroy() { - memory.clear(); + clear(); } - - - } diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java index de6367308..7807a0b13 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java @@ -31,10 +31,7 @@ import java.util.Optional; import java.util.ResourceBundle; -@PluginRoot( - type = PLUGIN_TYPE.MEMORY, - title = "RAM Program Tape" -) +@PluginRoot(type = PLUGIN_TYPE.MEMORY, title = "RAM Program Tape") @SuppressWarnings("unused") public class MemoryImpl extends AbstractMemory { private final MemoryContextImpl context; diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMInstruction.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMInstruction.java index a3577be41..24630809b 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMInstruction.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMInstruction.java @@ -18,31 +18,22 @@ */ package net.emustudio.plugins.memory.ram.api; -import net.emustudio.emulib.plugins.annotations.PluginContext; -import net.emustudio.emulib.plugins.compiler.CompilerContext; - +import java.io.Serializable; import java.util.Objects; +import java.util.Optional; /** - * This context will be registered by RAM compiler. + * RAM instruction. + * It is the type of the "memory cell". */ -@PluginContext -public interface RAMInstruction extends CompilerContext { - int READ = 1; - int WRITE = 2; - int LOAD = 3; - int STORE = 4; - int ADD = 5; - int SUB = 6; - int MUL = 7; - int DIV = 8; - int JMP = 9; - int JZ = 10; - int JGTZ = 11; - int HALT = 12; +public interface RAMInstruction extends Serializable { + + enum Opcode { + READ, WRITE, LOAD, STORE, ADD, SUB, MUL, DIV, JMP, JZ, JGTZ, HALT + } enum Direction { - REGISTER(""), DIRECT("="), INDIRECT("*"); + CONSTANT("="), DIRECT(""), INDIRECT("*"); private final String value; @@ -56,48 +47,38 @@ public String value() { } /** - * Get machine code of the RAM instruction. + * Get address of this instruction * - * @return code of the instruction + * @return address */ - int getCode(); + int getAddress(); /** - * Get direction of the RAM instruction: + * Get opcode of the RAM instruction. * - * @return direction of the instruction + * @return opcode of the instruction */ - Direction getDirection(); + Opcode getOpcode(); /** - * Get operand of the RAM instruction. - * - * @return operand (number or address, or string). If the operand is direct, - * it returns a String. Otherwise Integer. - */ - Object getOperand(); - - /** - * Get a string representation of label operand (meaningful only for - * JMP/JZ instructions) + * Get direction of the RAM instruction: * - * @return label operand + * @return direction of the instruction */ - String getOperandLabel(); + Direction getDirection(); /** - * Get string representation of the RAM instruction (mnemonic code). + * Get operand of this RAM instruction, if it has any. + * If the operand is a label, here will be the String representation of the label. * - * @return string representation of the instruction + * @return instruction operand if the instruction has any. */ - String getCodeStr(); + Optional getOperand(); /** - * Get string representation of the operand. - *

- * It includes labels, direction and integer operands. + * Get the label if the operand is a label. * - * @return String representation of operand + * @return label operand */ - String getOperandStr(); + Optional getLabel(); } diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMLabel.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMLabel.java new file mode 100644 index 000000000..9fd75547b --- /dev/null +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMLabel.java @@ -0,0 +1,23 @@ +package net.emustudio.plugins.memory.ram.api; + +import java.io.Serializable; + +/** + * A Label is a named pointer to an address in memory. + */ +public interface RAMLabel extends Serializable { + + /** + * Get address to which this label points to + * + * @return memory address + */ + int getAddress(); + + /** + * Get name of this label + * + * @return name of this label + */ + String getLabel(); +} diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java index 4bbcb856a..480919b36 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java @@ -26,13 +26,11 @@ @PluginContext public interface RAMMemoryContext extends MemoryContext { - void addLabel(int pos, String label); + void setLabels(List labels); - String getLabel(int pos); + RAMLabel getLabel(int address); - // from Compiler - void addInputs(List inputs); + void setInputs(List inputs); - // for CPU - List getInputs(); + List getInputs(); } diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMValue.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMValue.java new file mode 100644 index 000000000..62580ec69 --- /dev/null +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMValue.java @@ -0,0 +1,47 @@ +package net.emustudio.plugins.memory.ram.api; + +import java.io.Serializable; + +/** + * The "Value" is a polymorphic value. + * It has the type defined in compile time, but it can be integer or a String. + */ +public interface RAMValue extends Serializable { + + /** + * Value type + */ + enum Type { + NUMBER, STRING, ID + } + + /** + * Whether this value is an integer number + * + * @return true if the value is a number + */ + Type getType(); + + /** + * Get integer interpretation of this value + * + * @return integer interpretation of this value + * @throws RuntimeException if the value is not a number + */ + int getNumberValue(); + + /** + * Get String interpretation of this value + * + * @return string interpretation of this value + */ + String getStringValue(); + + /** + * Get String representation of this value. + * It might be useful for displaying the value regardless of type. + * + * @return string representation of this value + */ + String getStringRepresentation(); +} diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/MemoryDialog.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/MemoryDialog.java index 9943c4a5f..3ee69f361 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/MemoryDialog.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/MemoryDialog.java @@ -18,22 +18,18 @@ */ package net.emustudio.plugins.memory.ram.gui; -import net.emustudio.emulib.plugins.memory.Memory; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; import net.emustudio.plugins.memory.ram.MemoryContextImpl; -import net.emustudio.plugins.memory.ram.api.RAMInstruction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import javax.swing.border.TitledBorder; -import javax.swing.table.DefaultTableModel; import java.awt.event.KeyEvent; import java.io.File; import java.io.IOException; -import java.util.List; -import java.util.*; +import java.util.Objects; import static net.emustudio.plugins.memory.ram.gui.Constants.DIALOG_PLAIN; @@ -57,33 +53,15 @@ public MemoryDialog(JFrame parent, MemoryContextImpl memory, Dialogs dialogs) { tableModel = new RAMTableModel(memory); tableProgram.setModel(tableModel); - - refillTable(); - memory.addMemoryListener(new Memory.MemoryListener() { - @Override - public void memoryChanged(int memoryPosition) { - refillTable(); - } - - @Override - public void memorySizeChanged() { - refillTable(); - } - }); - } private void openRAM() { File currentDirectory = Objects.requireNonNullElse(lastOpenedFile, new File(System.getProperty("user.dir"))); - dialogs.chooseFile( - "Load compiled RAM program", "Load", currentDirectory.toPath(), false, - new FileExtensionsFilter("RAM compiler file", "ro") - ).ifPresent(path -> { + dialogs.chooseFile("Load compiled RAM program", "Load", currentDirectory.toPath(), false, new FileExtensionsFilter("RAM compiler file", "ro")).ifPresent(path -> { lastOpenedFile = path.toFile(); try { memory.deserialize(lastOpenedFile.getAbsolutePath()); tableModel.fireTableDataChanged(); - refillTable(); } catch (IOException | ClassNotFoundException e) { dialogs.showError("Cannot open file " + lastOpenedFile.getPath() + ". Please see log file for details."); LOGGER.error("Could not open file {}", lastOpenedFile, e); @@ -91,202 +69,13 @@ private void openRAM() { }); } - public final void refillTable() { - int add = 0, mul = 0, div = 0, sub = 0, load = 0, store = 0, - jmp = 0, jz = 0, jgtz = 0, halt = 0, read = 0, write = 0; - int count = 0, i, j; - - j = memory.getSize(); - for (i = 0; i < j; i++) { - count++; - switch ((memory.read(i)).getCode()) { - case RAMInstruction.LOAD: - load++; - break; - case RAMInstruction.STORE: - store++; - break; - case RAMInstruction.READ: - read++; - break; - case RAMInstruction.WRITE: - write++; - break; - case RAMInstruction.ADD: - add++; - break; - case RAMInstruction.SUB: - sub++; - break; - case RAMInstruction.MUL: - mul++; - break; - case RAMInstruction.DIV: - div++; - break; - case RAMInstruction.JMP: - jmp++; - break; - case RAMInstruction.JGTZ: - jgtz++; - break; - case RAMInstruction.JZ: - jz++; - break; - case RAMInstruction.HALT: - halt++; - break; - } - } - txtInstructionsCount.setText(String.valueOf(count)); - txtLOAD.setText(String.valueOf(load)); - txtSTORE.setText(String.valueOf(store)); - txtREAD.setText(String.valueOf(read)); - txtWRITE.setText(String.valueOf(write)); - txtADD.setText(String.valueOf(add)); - txtSUB.setText(String.valueOf(sub)); - txtMUL.setText(String.valueOf(mul)); - txtDIV.setText(String.valueOf(div)); - txtJMP.setText(String.valueOf(jmp)); - txtJGTZ.setText(String.valueOf(jgtz)); - txtJZ.setText(String.valueOf(jz)); - txtHALT.setText(String.valueOf(halt)); - - computeComplexity(); - } - - // TODO: bug: S(n) computation is not always correct - private void computeComplexity() { - Map labels; - Map levels = new HashMap<>(); - List registers = new ArrayList<>(); - int memcompl = 0; - - labels = memory.getSwitchedLabels(); - int j = memory.getSize(); - int i; - for (i = 0; i < j; i++) { - levels.put(i, 0); - } - - // bottom-up cycles search - for (i = j - 1; i >= 0; i--) { - RAMInstruction in = memory.read(i); - switch (in.getCode()) { - case RAMInstruction.JMP: - case RAMInstruction.JGTZ: - case RAMInstruction.JZ: - String lab = in.getOperandLabel(); - Integer pos = labels.get(lab.toUpperCase() + ":"); - if (pos != null && (pos <= i)) { - // ak je definicia labelu vyssie ako jump (cyklus) - // pripocitaj 1 ku levelu vsetkych instrukcii v - // rozpati - for (int n = pos; n <= i; n++) { - int old = levels.get(n); - levels.put(n, old + 1); - } - } - break; - case RAMInstruction.LOAD: - case RAMInstruction.STORE: - if (!registers.contains(0)) { - memcompl++; - registers.add(0); - } - default: - // other instructions has parameters - registers or - // direct values - if ((in.getCode() != RAMInstruction.HALT) - && (in.getDirection() != RAMInstruction.Direction.DIRECT)) { - int operand = (Integer) in.getOperand(); - if (!registers.contains(operand)) { - memcompl++; - registers.add(operand); - } - } - } - } - // count levels and make string - i = 0; - j = 0; - String time = null; - String n = ""; - boolean was = false; - while (true) { - Iterator keys = levels.keySet().iterator(); - while (keys.hasNext()) { - Integer pos = keys.next(); - if (levels.get(pos) == i) { - was = true; - j++; - levels.remove(pos); - keys = levels.keySet().iterator(); - } - } - if (was) { - if (time == null) { - time = j + n; - } else { - time += "+" + j + n; - } - n += "*n"; - i++; - j = 0; - was = false; - } else { - break; - } - } - if (time == null || time.equals("")) { - txtTimeComplexity.setText("0"); - } else { - txtTimeComplexity.setText(time); - } - txtMemoryComplexity.setText(String.valueOf(memcompl)); - } - private void initComponents() { JToolBar jToolBar1 = new JToolBar(); JButton btnOpen = new JButton(); JButton btnClear = new JButton(); - JSplitPane jSplitPane1 = new JSplitPane(); JPanel jPanel1 = new JPanel(); JScrollPane jScrollPane1 = new JScrollPane(); tableProgram = new JTable(); - JPanel jPanel2 = new JPanel(); - JPanel jPanel3 = new JPanel(); - JLabel jLabel1 = new JLabel(); - txtInstructionsCount = new JTextField(); - JLabel jLabel2 = new JLabel(); - JLabel jLabel3 = new JLabel(); - JLabel jLabel4 = new JLabel(); - JLabel jLabel5 = new JLabel(); - txtMUL = new JTextField(); - txtADD = new JTextField(); - txtSUB = new JTextField(); - txtDIV = new JTextField(); - JLabel jLabel6 = new JLabel(); - JLabel jLabel7 = new JLabel(); - JLabel jLabel8 = new JLabel(); - JLabel jLabel9 = new JLabel(); - txtJMP = new JTextField(); - txtJZ = new JTextField(); - txtJGTZ = new JTextField(); - txtHALT = new JTextField(); - JLabel jLabel10 = new JLabel(); - JLabel jLabel11 = new JLabel(); - JLabel jLabel12 = new JLabel(); - JLabel jLabel13 = new JLabel(); - txtLOAD = new JTextField(); - txtSTORE = new JTextField(); - txtREAD = new JTextField(); - txtWRITE = new JTextField(); - JPanel jPanel4 = new JPanel(); - JLabel jLabel14 = new JLabel(); - JLabel jLabel15 = new JLabel(); - txtTimeComplexity = new JTextField(); - txtMemoryComplexity = new JTextField(); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); @@ -310,344 +99,31 @@ private void initComponents() { btnClear.addActionListener(this::btnClearActionPerformed); jToolBar1.add(btnClear); - jSplitPane1.setDividerLocation(450); - - jPanel1.setBorder(BorderFactory.createTitledBorder( - null, "Tape content", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - DIALOG_PLAIN) - ); - - tableProgram.setModel(new DefaultTableModel( - new Object[][]{ - {null, null, null}, - {null, null, null}, - {null, null, null} - }, - new String[]{ - "Address", "Label", "Instruction" - } - ) { - Class[] types = new Class[]{ - java.lang.String.class, java.lang.String.class, java.lang.String.class - }; - boolean[] canEdit = new boolean[]{ - false, false, false - }; - - public Class getColumnClass(int columnIndex) { - return types[columnIndex]; - } + jPanel1.setBorder(BorderFactory.createTitledBorder(null, "Tape content", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, DIALOG_PLAIN)); - public boolean isCellEditable(int rowIndex, int columnIndex) { - return canEdit[columnIndex]; - } - }); tableProgram.setGridColor(java.awt.SystemColor.control); jScrollPane1.setViewportView(tableProgram); GroupLayout jPanel1Layout = new GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE) - ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)) - ); - - jSplitPane1.setLeftComponent(jPanel1); - - jPanel2.setBorder(BorderFactory.createTitledBorder( - null, "Details", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - DIALOG_PLAIN - )); - - jPanel3.setBorder(BorderFactory.createTitledBorder( - null, "Statistics", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - DIALOG_PLAIN - )); - - jLabel1.setText("Instructions count:"); - - txtInstructionsCount.setEditable(false); - txtInstructionsCount.setText("0"); - - jLabel2.setText("ADD:"); - - jLabel3.setText("SUB:"); - - jLabel4.setText("MUL:"); - - jLabel5.setText("DIV:"); - - txtMUL.setEditable(false); - txtMUL.setText("0"); - - txtADD.setEditable(false); - txtADD.setText("0"); - - txtSUB.setEditable(false); - txtSUB.setText("0"); - - txtDIV.setEditable(false); - txtDIV.setText("0"); - - jLabel6.setText("JMP:"); - - jLabel7.setText("JZ:"); - - jLabel8.setText("JGTZ:"); - - jLabel9.setText("HALT:"); - - txtJMP.setEditable(false); - txtJMP.setText("0"); - - txtJZ.setEditable(false); - txtJZ.setText("0"); - - txtJGTZ.setEditable(false); - txtJGTZ.setText("0"); - - txtHALT.setEditable(false); - txtHALT.setText("0"); - - jLabel10.setText("LOAD:"); - - jLabel11.setText("STORE:"); - - jLabel12.setText("READ:"); - - jLabel13.setText("WRITE:"); - - txtLOAD.setEditable(false); - txtLOAD.setText("0"); - - txtSTORE.setEditable(false); - txtSTORE.setText("0"); - - txtREAD.setEditable(false); - txtREAD.setText("0"); - - txtWRITE.setEditable(false); - txtWRITE.setText("0"); - - GroupLayout jPanel3Layout = new GroupLayout(jPanel3); - jPanel3.setLayout(jPanel3Layout); - jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(jLabel1) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtInstructionsCount, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE)) - .addGroup(jPanel3Layout.createSequentialGroup() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(jLabel2) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtADD, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel6)) - .addGroup(jPanel3Layout.createSequentialGroup() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel3) - .addComponent(jLabel4) - .addComponent(jLabel5)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(txtMUL, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel8)) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(txtSUB, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel7)) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(txtDIV, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel9))))) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(txtJMP, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel10)) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(txtJZ, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel11)) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(txtJGTZ, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel12)) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(txtHALT, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel13))) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(txtWRITE, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE) - .addComponent(txtREAD, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE) - .addComponent(txtSTORE, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE) - .addComponent(txtLOAD, GroupLayout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE)))) - .addGap(30, 30, 30)) - ); - jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) - .addComponent(txtInstructionsCount, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addGap(18, 18, 18) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2) - .addComponent(txtADD, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel6) - .addComponent(txtJMP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel10) - .addComponent(txtLOAD, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3) - .addComponent(txtSUB, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel7) - .addComponent(txtJZ, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel11) - .addComponent(txtSTORE, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4) - .addComponent(txtMUL, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel8) - .addComponent(txtJGTZ, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel12) - .addComponent(txtREAD, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5) - .addComponent(txtDIV, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel9) - .addComponent(txtHALT, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel13) - .addComponent(txtWRITE, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addGap(61, 61, 61)) - ); - - jPanel4.setBorder(BorderFactory.createTitledBorder( - null, "Uniform Complexity", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - DIALOG_PLAIN - )); - - jLabel14.setText("Time T(n):"); - jLabel15.setText("Memory S(n):"); - - txtTimeComplexity.setEditable(false); - txtTimeComplexity.setText("N/A"); - - txtMemoryComplexity.setEditable(false); - txtMemoryComplexity.setText("N/A"); - - GroupLayout jPanel4Layout = new GroupLayout(jPanel4); - jPanel4.setLayout(jPanel4Layout); - jPanel4Layout.setHorizontalGroup( - jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel4Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel14) - .addComponent(jLabel15)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(txtTimeComplexity) - .addComponent(txtMemoryComplexity)) - .addContainerGap()) - ); - jPanel4Layout.setVerticalGroup( - jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel4Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel14) - .addComponent(txtTimeComplexity, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel15) - .addComponent(txtMemoryComplexity, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - - GroupLayout jPanel2Layout = new GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel4, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) - ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addContainerGap(134, Short.MAX_VALUE)) - ); - - jSplitPane1.setRightComponent(jPanel2); + jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 439, Short.MAX_VALUE)); + jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addContainerGap().addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE))); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jToolBar1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jSplitPane1) - ); - layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jToolBar1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSplitPane1)) - ); + layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(jToolBar1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addComponent(jPanel1)); + layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addComponent(jToolBar1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(jPanel1))); pack(); - }// //GEN-END:initComponents + } - private void btnOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOpenActionPerformed + private void btnOpenActionPerformed(java.awt.event.ActionEvent evt) { openRAM(); - }//GEN-LAST:event_btnOpenActionPerformed + } - private void btnClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClearActionPerformed + private void btnClearActionPerformed(java.awt.event.ActionEvent evt) { memory.clear(); - }//GEN-LAST:event_btnClearActionPerformed + } private JTable tableProgram; - private JTextField txtADD; - private JTextField txtDIV; - private JTextField txtHALT; - private JTextField txtInstructionsCount; - private JTextField txtJGTZ; - private JTextField txtJMP; - private JTextField txtJZ; - private JTextField txtLOAD; - private JTextField txtMUL; - private JTextField txtMemoryComplexity; - private JTextField txtREAD; - private JTextField txtSTORE; - private JTextField txtSUB; - private JTextField txtTimeComplexity; - private JTextField txtWRITE; - // End of variables declaration//GEN-END:variables } diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/RAMTableModel.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/RAMTableModel.java index 4a70739ff..1895dcb63 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/RAMTableModel.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/RAMTableModel.java @@ -20,6 +20,7 @@ import net.emustudio.plugins.memory.ram.api.RAMInstruction; import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; +import net.emustudio.plugins.memory.ram.api.RAMValue; import javax.swing.table.AbstractTableModel; import java.util.Objects; @@ -47,14 +48,14 @@ public Object getValueAt(int rowIndex, int columnIndex) { case 0: return String.valueOf(rowIndex); case 1: - String label = memory.getLabel(rowIndex); + String label = memory.getLabel(rowIndex).getLabel(); if (label != null) { return label; } break; case 2: RAMInstruction i = memory.read(rowIndex); - return i.getCodeStr() + " " + i.getOperandStr(); + return i.getOpcode() + " " + i.getOperand().map(RAMValue::getStringRepresentation).orElse(""); } return ""; } diff --git a/settings.gradle b/settings.gradle index bcb2812e0..67155bafd 100644 --- a/settings.gradle +++ b/settings.gradle @@ -32,12 +32,12 @@ include ':plugins:compiler:as-8080' include ':plugins:compiler:as-ssem' include ':plugins:compiler:as-z80' include ':plugins:compiler:brainc-brainduck' -//include ':plugins:compiler:ramc-ram' +include ':plugins:compiler:ramc-ram' //include ':plugins:compiler:raspc-rasp' include ':plugins:cpu:8080-cpu' include ':plugins:cpu:brainduck-cpu' -//include ':plugins:cpu:ram-cpu' +include ':plugins:cpu:ram-cpu' //include ':plugins:cpu:rasp-cpu' include ':plugins:cpu:ssem-cpu' include ':plugins:cpu:z80-cpu' @@ -50,7 +50,7 @@ include ':plugins:device:brainduck-terminal' include ':plugins:device:simhPseudo-z80' include ':plugins:device:ssem-display' -//include ':plugins:memory:ram-mem' +include ':plugins:memory:ram-mem' //include ':plugins:memory:rasp-mem' include ':plugins:memory:ssem-mem' include ':plugins:memory:byte-mem' From 48d629fb23d222225c2c9e0840f442d35c0cf264 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 10 May 2022 07:37:55 +0200 Subject: [PATCH 134/314] [#201] Fix parsing comments (multiple compilers) --- .../as-8080/src/main/antlr/As8080Parser.g4 | 2 +- .../visitors/ExpandIncludesVisitorTest.java | 6 +- .../as-z80/src/main/antlr/AsZ80Parser.g4 | 2 +- .../visitors/ExpandIncludesVisitorTest.java | 6 +- .../ramc-ram/src/main/antlr/RAMLexer.g4 | 4 +- .../ramc-ram/src/main/antlr/RAMParser.g4 | 14 +- .../compiler/ramc-ram/src/main/cup/parser.cup | 169 ------------------ .../ramc-ram/src/main/examples/copy.ram | 2 +- .../src/main/examples/equal_count.ram | 2 +- .../ramc-ram/src/main/examples/factorial.ram | 2 +- .../ramc-ram/src/main/examples/ones_count.ram | 2 +- .../ramc-ram/src/main/examples/reverse.ram | 14 +- .../compiler/ram/LexicalAnalyzerImpl.java | 3 +- .../compiler/ram/visitors/ProgramParser.java | 2 +- .../ramc-ram/src/main/jflex/lexer.jflex | 136 -------------- .../plugins/compiler/ram/MemoryStub.java | 4 +- .../plugins/cpu/ram/EmulatorEngine.java | 15 +- .../plugins/cpu/ram/gui/LabelDebugColumn.java | 3 +- .../plugins/cpu/ram/AbstractEngineTest.java | 24 +++ .../plugins/cpu/ram/EmulatorEngineTest.java | 6 +- .../plugins/memory/ram/MemoryContextImpl.java | 4 +- .../memory/ram/api/RAMMemoryContext.java | 3 +- .../plugins/memory/ram/gui/RAMTableModel.java | 7 +- 23 files changed, 74 insertions(+), 358 deletions(-) delete mode 100644 plugins/compiler/ramc-ram/src/main/cup/parser.cup delete mode 100644 plugins/compiler/ramc-ram/src/main/jflex/lexer.jflex diff --git a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 index e8219507d..6ec375e71 100644 --- a/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 +++ b/plugins/compiler/as-8080/src/main/antlr/As8080Parser.g4 @@ -10,7 +10,7 @@ rStart: ; rLine: - label=ID_LABEL? (comment EOL)* statement=rStatement comment + label=ID_LABEL? statement=rStatement comment | label=ID_LABEL comment | comment ; diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java index 89f68b525..38624fac6 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java @@ -32,9 +32,9 @@ public void testExpandInclude() { Node expected = new Program() .addChild(new InstrNoArgs(0, 0, OPCODE_CMC)) - .addChild(new PseudoLabel(0, 0, "sample") - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new PseudoLabel(0, 0, "sample")) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprNumber(0, 0, 0))) .addChild(new InstrNoArgs(0, 0, OPCODE_RET)); assertTrees(expected, program); diff --git a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 index 4a3478899..7be26e84d 100644 --- a/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 +++ b/plugins/compiler/as-z80/src/main/antlr/AsZ80Parser.g4 @@ -10,7 +10,7 @@ rStart: ; rLine: - label=ID_LABEL? (comment EOL)* statement=rStatement comment + label=ID_LABEL? statement=rStatement comment | label=ID_LABEL comment | comment ; diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java index 786f7d8ac..f5ca4465d 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java @@ -31,9 +31,9 @@ public void testExpandInclude() { Node expected = new Program() .addChild(new Instr(0, 0, OPCODE_CCF, 0, 7, 7)) - .addChild(new PseudoLabel(0, 0, "sample") - .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) - .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new PseudoLabel(0, 0, "sample")) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) + .addChild(new ExprNumber(0, 0, 0))) .addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1)); assertTrees(expected, program); diff --git a/plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 b/plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 index efe2c4a6c..cea9b0aa8 100644 --- a/plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 +++ b/plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 @@ -38,10 +38,10 @@ OPCODE_JMP: J M P; OPCODE_JGTZ: J G T Z; OPCODE_JZ: J Z; -OP_DIRECT: '='; +OP_CONSTANT: '='; OP_INDIRECT: '*'; -PREP_INPUT: '<' I N P U T '>'; +PREP_INPUT: ('<' I N P U T '>')| ('<' V A L U E '>'); LIT_HEXNUMBER_1: '0' X [0-9a-fA-F]+; LIT_NUMBER: [0-9]+ D?; diff --git a/plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 b/plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 index b36078621..3ba07ba1a 100644 --- a/plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 +++ b/plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 @@ -10,7 +10,7 @@ rStart: ; rLine: - label=ID_LABEL? (comment EOL)* statement=rStatement comment + label=ID_LABEL? statement=rStatement comment | label=ID_LABEL comment | comment ; @@ -25,24 +25,24 @@ rStatement: rInstruction: op=OPCODE_READ n=rNumber | op=OPCODE_READ d=OP_INDIRECT n=rNumber - | op=OPCODE_WRITE d=OP_DIRECT v=rValue + | op=OPCODE_WRITE d=OP_CONSTANT v=rValue | op=OPCODE_WRITE d=OP_INDIRECT n=rNumber | op=OPCODE_WRITE n=rNumber - | op=OPCODE_LOAD d=OP_DIRECT v=rValue + | op=OPCODE_LOAD d=OP_CONSTANT v=rValue | op=OPCODE_LOAD d=OP_INDIRECT n=rNumber | op=OPCODE_LOAD n=rNumber | op=OPCODE_STORE n=rNumber | op=OPCODE_STORE d=OP_INDIRECT n=rNumber - | op=OPCODE_ADD d=OP_DIRECT v=rValue + | op=OPCODE_ADD d=OP_CONSTANT v=rValue | op=OPCODE_ADD d=OP_INDIRECT n=rNumber | op=OPCODE_ADD n=rNumber - | op=OPCODE_SUB d=OP_DIRECT v=rValue + | op=OPCODE_SUB d=OP_CONSTANT v=rValue | op=OPCODE_SUB d=OP_INDIRECT n=rNumber | op=OPCODE_SUB n=rNumber - | op=OPCODE_MUL d=OP_DIRECT v=rValue + | op=OPCODE_MUL d=OP_CONSTANT v=rValue | op=OPCODE_MUL d=OP_INDIRECT n=rNumber | op=OPCODE_MUL n=rNumber - | op=OPCODE_DIV d=OP_DIRECT v=rValue + | op=OPCODE_DIV d=OP_CONSTANT v=rValue | op=OPCODE_DIV d=OP_INDIRECT n=rNumber | op=OPCODE_DIV n=rNumber | op=OPCODE_JMP id=ID_IDENTIFIER diff --git a/plugins/compiler/ramc-ram/src/main/cup/parser.cup b/plugins/compiler/ramc-ram/src/main/cup/parser.cup deleted file mode 100644 index 6edb80f15..000000000 --- a/plugins/compiler/ramc-ram/src/main/cup/parser.cup +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ramc; - -import java_cup.runtime.DefaultSymbolFactory; -import net.emustudio.emulib.plugins.compiler.CompilerMessage; -import net.emustudio.emulib.plugins.compiler.Token; -import net.emustudio.plugins.compiler.ramc.tree.Label; -import net.emustudio.plugins.compiler.ramc.tree.Program; -import net.emustudio.plugins.compiler.ramc.tree.RAMInstructionImpl; -import net.emustudio.plugins.compiler.ramc.tree.Row; -import net.emustudio.plugins.memory.ram.api.RAMInstruction; -import net.emustudio.plugins.memory.ram.api.RAMInstruction.Direction; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -parser code {: - private CompilerImpl compiler; - private boolean syntaxErrors; - - public ParserImpl(LexerImpl lexer, CompilerImpl compiler) { - super(lexer, new DefaultSymbolFactory()); - this.compiler = Objects.requireNonNull(compiler); - } - - public void reset() { - syntaxErrors = false; - } - - @Override - public void report_fatal_error(String message, Object info) throws Exception { - done_parsing(); - report_error(message, info); - throw new Exception("Can't recover from previous error(s)"); - } - - @Override - public void report_error(String messageText, Object current) { - syntaxErrors = true; - - Token token = (Token)current; - - messageText += ":" + token.getErrorString() + " ('" + token.getText() + "')"; - - List expectedTokenIds = expected_token_ids() - .stream() - .map(this::symbl_name_from_id) - .collect(Collectors.toList()); - - if (!expectedTokenIds.isEmpty()) { - messageText += "\nExpected tokens: " + expectedTokenIds; - } - - CompilerMessage message = new CompilerMessage( - CompilerMessage.MessageType.TYPE_ERROR, messageText, token.getLine()+1, token.getColumn() - ); - - compiler.notifyOnMessage(message); - } - - public boolean hasSyntaxErrors() { - return syntaxErrors; - } -:} - -terminal HALT,LOAD,STORE,READ,WRITE,ADD,SUB,MUL,DIV,JMP,JZ,JGTZ; -terminal EOL; -terminal DIRECT,INDIRECT; -terminal String NUMBER, IDENT, LABELL,STRING; -terminal TCOMMENT, INPUT; - -non terminal Program Program; -non terminal Row Row; -non terminal RAMInstructionImpl Statement; -non terminal Comment; -non terminal Integer Number; -non terminal Label LabelOpt; -non terminal List StringVector; - -start with Program; - -Program ::= Row:row - {: - Program program = new Program(); - if (row != null) program.addRow(row); - RESULT = program; - :} - | Program:program EOL Row:row - {: - if (row != null) program.addRow(row); - RESULT = program; - :}; - -Row ::= LabelOpt:label Statement:stmt Comment - {: RESULT = new Row(stmt, label); :} - | LabelOpt:label Comment - {: RESULT = (label==null)?null:new Row(label); :} - | INPUT StringVector:vector Comment - {: RESULT = new Row(vector); :} - ; - -StringVector ::= STRING:str - {: - ArrayList v = new ArrayList(); - v.add(str); - RESULT = v; - :} - | StringVector:v STRING:str - {: - v.add(str); - RESULT = v; - :}; - -Comment ::= TCOMMENT | ; - -LabelOpt ::= LABELL:label {: RESULT = new Label(label); :} - | {: RESULT = null; :} - ; - - -Statement ::= READ Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.READ, Direction.REGISTER, num); :} - | READ INDIRECT Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.READ, Direction.INDIRECT, num); :} - | WRITE DIRECT STRING:str {: RESULT = new RAMInstructionImpl(RAMInstruction.WRITE, Direction.DIRECT, str); :} - | WRITE Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.WRITE, Direction.REGISTER, num); :} - | WRITE INDIRECT Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.WRITE, Direction.INDIRECT, num); :} - | LOAD DIRECT STRING:str {: RESULT = new RAMInstructionImpl(RAMInstruction.LOAD, Direction.DIRECT, str); :} - | LOAD Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.LOAD, Direction.REGISTER, num); :} - | LOAD INDIRECT Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.LOAD, Direction.INDIRECT, num); :} - | STORE Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.STORE, Direction.REGISTER, num); :} - | STORE INDIRECT Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.STORE, Direction.INDIRECT, num); :} - | ADD DIRECT STRING:str {: RESULT = new RAMInstructionImpl(RAMInstruction.ADD, Direction.DIRECT, str); :} - | ADD Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.ADD, Direction.REGISTER, num); :} - | ADD INDIRECT Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.ADD, Direction.INDIRECT, num); :} - | SUB DIRECT STRING:str {: RESULT = new RAMInstructionImpl(RAMInstruction.SUB, Direction.DIRECT, str); :} - | SUB Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.SUB, Direction.REGISTER, num); :} - | SUB INDIRECT Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.SUB, Direction.INDIRECT, num); :} - | MUL DIRECT STRING:str {: RESULT = new RAMInstructionImpl(RAMInstruction.MUL, Direction.DIRECT, str); :} - | MUL Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.MUL, Direction.REGISTER, num); :} - | MUL INDIRECT Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.MUL, Direction.INDIRECT, num); :} - | DIV DIRECT STRING:str {: RESULT = new RAMInstructionImpl(RAMInstruction.DIV, Direction.DIRECT, str); :} - | DIV Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.DIV, Direction.REGISTER, num); :} - | DIV INDIRECT Number:num {: RESULT = new RAMInstructionImpl(RAMInstruction.DIV, Direction.INDIRECT, num); :} - | JMP IDENT:label {: RESULT = new RAMInstructionImpl(RAMInstruction.JMP, label); :} - | JZ IDENT:label {: RESULT = new RAMInstructionImpl(RAMInstruction.JZ, label); :} - | JGTZ IDENT:label {: RESULT = new RAMInstructionImpl(RAMInstruction.JGTZ, label); :} - | HALT {: RESULT = new RAMInstructionImpl(RAMInstruction.HALT, Direction.REGISTER,0); :} - ; - -Number ::= NUMBER:num {: RESULT = Integer.parseInt((String)num); :}; - diff --git a/plugins/compiler/ramc-ram/src/main/examples/copy.ram b/plugins/compiler/ramc-ram/src/main/examples/copy.ram index 4673250e6..12ce6d1f0 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/copy.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/copy.ram @@ -11,7 +11,7 @@ ; reg.Y: (reg.Y) - sss + sss ; load X,Y read 1 read 2 diff --git a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram index 2b1b4b92c..07b2ce1d6 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram @@ -2,7 +2,7 @@ ; output: 1 if N1(X) = N2(X) (i.e. if X contains equal number of "1" and "2") ; 0 otherwise - 1 2 3 3 2 1 1 33 21 1 2 1 2 112 2 1 2 11 2 1 2 21 2 1 + 1 2 3 3 2 1 1 33 21 1 2 1 2 112 2 1 2 11 2 1 2 21 2 1 load=0 store 2 diff --git a/plugins/compiler/ramc-ram/src/main/examples/factorial.ram b/plugins/compiler/ramc-ram/src/main/examples/factorial.ram index fa3fa04e2..a7150cb9c 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/factorial.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/factorial.ram @@ -4,7 +4,7 @@ ; output: N! ; - 8 + 8 read 1 load 1 diff --git a/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram b/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram index dfce61ebd..c5bb540c7 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram @@ -1,6 +1,6 @@ ; value : X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape ; output: N1(X) - number of ones in X. - 1 2 3 4 5 6 7 1 1 1 2 5 0 + 1 2 3 4 5 6 7 1 1 1 2 5 0 load =0 store 2 diff --git a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram index 01f8e88d2..25395bdea 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram @@ -1,23 +1,23 @@ ; value : X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape ; output: XR - reverse of X - 1 2 3 3 2 1 2 3 5.5 3 4 5 53 34 2 34 + 1 2 3 3 2 1 2 3 5.5 3 4 5 53 34 2 34 -load=10 -store2 +load =10 +store 2 read_next: - read1 + read 1 load 1 jz print store *2 load 2 - add=1 - store2 + add =1 + store 2 jmp read_next print: load 2 - sub=1 + sub =1 store 2 sub =9 jz exit diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java index d0e0fb030..3498909c3 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java @@ -17,6 +17,7 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { static { tokenMap[COMMENT] = Token.COMMENT; + tokenMap[COMMENT2] = Token.COMMENT; tokenMap[EOL] = Token.WHITESPACE; tokenMap[WS] = Token.WHITESPACE; tokenMap[OPCODE_READ] = Token.RESERVED; @@ -34,7 +35,7 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[PREP_INPUT] = Token.PREPROCESSOR; - tokenMap[OP_DIRECT] = Token.OPERATOR; + tokenMap[OP_CONSTANT] = Token.OPERATOR; tokenMap[OP_INDIRECT] = Token.OPERATOR; tokenMap[LIT_NUMBER] = Token.LITERAL; diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/visitors/ProgramParser.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/visitors/ProgramParser.java index 5b40dea6b..74bef6ff4 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/visitors/ProgramParser.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/visitors/ProgramParser.java @@ -65,7 +65,7 @@ public Program visitRInstruction(RAMParser.RInstructionContext ctx) { RAMInstruction.Opcode opcode = tokenOpcodes.get(op.getType()); RAMInstruction.Direction direction = RAMInstruction.Direction.DIRECT; if (ctx.d != null) { - if (ctx.d.getType() == OP_DIRECT) { + if (ctx.d.getType() == OP_CONSTANT) { direction = RAMInstruction.Direction.CONSTANT; } else if (ctx.d.getType() == OP_INDIRECT) { direction = RAMInstruction.Direction.INDIRECT; diff --git a/plugins/compiler/ramc-ram/src/main/jflex/lexer.jflex b/plugins/compiler/ramc-ram/src/main/jflex/lexer.jflex deleted file mode 100644 index 1668a810a..000000000 --- a/plugins/compiler/ramc-ram/src/main/jflex/lexer.jflex +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.ramc; - -import java_cup.runtime.ComplexSymbolFactory.Location; -import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; -import net.emustudio.emulib.plugins.compiler.Token; - -import java.io.Reader; -import java.io.IOException; - -%% - -/* options */ -%class LexerImpl -%cup -%public -%implements LexicalAnalyzer -%line -%column -%char -%caseless -%unicode -%type TokenImpl -%states STRING,IDENTIFIER, INPUT - -%{ - @Override - public Token getToken() throws IOException { - return next_token(); - } - - @Override - public void reset(Reader in, int yyline, int yychar, int yycolumn) { - yyreset(in); - this.yyline = yyline; - this.yychar = yychar; - this.yycolumn = yycolumn; - } - - @Override - public void reset(Reader in, int line, int offset, int column, int lexerState) { - yyreset(in); - this.yyline = line; - this.yychar = offset; - this.yycolumn = column; - this.zzLexicalState = lexerState; - } - - private TokenImpl token(int id, int category) { - Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); - return new TokenImpl(id, category, zzLexicalState, yytext(), left, right); - } - - private TokenImpl token(int id, int category, Object value) { - Location left = new Location("", yyline+1,yycolumn+1, (int)yychar); - Location right= new Location("", yyline+1,yycolumn+yylength(), (int)yychar+yylength()); - return new TokenImpl(id, category, zzLexicalState, yytext(), left, right, value); - } -%} - -%eofval{ - return token(TokenImpl.EOF, Token.TEOF); -%eofval} - - -Comment = ";"[^\r\n]* -Eol = \n|\r|\r\n -WhiteSpace = [\ \t\f] -Number = [0-9]+ - -Identifier =([a-zA-Z_\?@])[a-zA-Z_\?@0-9]* -Label ={Identifier}[\:] -String = [^\ \t\f\n\r;]+ -MultiSpaceString = \"[^\"]*\" - -%% - - "halt" { return token(TokenImpl.HALT, Token.RESERVED); } - "read" { return token(TokenImpl.READ, Token.RESERVED); } - "write" { return token(TokenImpl.WRITE, Token.RESERVED); } - "load" { return token(TokenImpl.LOAD, Token.RESERVED); } - "store" { return token(TokenImpl.STORE, Token.RESERVED); } - "add" { return token(TokenImpl.ADD,Token.RESERVED); } - "sub" { return token(TokenImpl.SUB, Token.RESERVED); } - "mul" { return token(TokenImpl.MUL, Token.RESERVED); } - "div" { return token(TokenImpl.DIV, Token.RESERVED); } - "jmp" { yybegin(IDENTIFIER); return token(TokenImpl.JMP, Token.RESERVED); } - "jgtz" { yybegin(IDENTIFIER); return token(TokenImpl.JGTZ, Token.RESERVED); } - "jz" { yybegin(IDENTIFIER); return token(TokenImpl.JZ, Token.RESERVED); } - - "=" { yybegin(STRING); return token(TokenImpl.DIRECT, Token.OPERATOR); } - "*" { return token(TokenImpl.INDIRECT, Token.OPERATOR); } - - "" { yybegin(INPUT); return token(TokenImpl.INPUT, Token.PREPROCESSOR); } - -{WhiteSpace} { } - {Eol} { return token(TokenImpl.EOL, Token.SEPARATOR,null); } -{Eol} { yybegin(YYINITIAL); return token(TokenImpl.EOL, Token.SEPARATOR,null); } - - {Comment} { yybegin(YYINITIAL); return token(TokenImpl.TCOMMENT, Token.COMMENT); } -{Comment} { yybegin(YYINITIAL); return token(TokenImpl.TCOMMENT, Token.COMMENT); } - - {Number} { return token(TokenImpl.NUMBER, Token.LITERAL,yytext()); } - {Label} { return token(TokenImpl.LABELL, Token.LABEL,yytext()); } - {Identifier} { yybegin(YYINITIAL); return token(TokenImpl.IDENT, Token.IDENTIFIER,yytext()); } - - {String} { yybegin(YYINITIAL); return token(TokenImpl.STRING, Token.LITERAL,yytext()); } - {MultiSpaceString} { - yybegin(YYINITIAL); - String tmp = yytext(); - return token(TokenImpl.STRING, Token.LITERAL,tmp.substring(1,tmp.length()-1)); } - - {String} { return token(TokenImpl.STRING, Token.PREPROCESSOR,yytext()); } - {MultiSpaceString} { - String tmp = yytext(); - return token(TokenImpl.STRING, Token.PREPROCESSOR,tmp.substring(1,tmp.length()-1)); } - -. { return token(TokenImpl.error, TokenImpl.ERROR); } diff --git a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java index 42c38f7a7..66e05e7af 100644 --- a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java +++ b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java @@ -77,8 +77,8 @@ public void setLabels(List labels) { } @Override - public RAMLabel getLabel(int address) { - return labels.get(address); + public Optional getLabel(int address) { + return Optional.ofNullable(labels.get(address)); } @Override diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java index 4d378540d..b941fd821 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java @@ -101,9 +101,8 @@ public CPU.RunState step() { break; case JMP: instr - .getOperand() - .filter(o -> o.getType() == RAMValue.Type.NUMBER) - .ifPresentOrElse(o -> IP = o.getNumberValue(), () -> { + .getLabel() + .ifPresentOrElse(o -> IP = o.getAddress(), () -> { throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); }); break; @@ -111,9 +110,8 @@ public CPU.RunState step() { int r0 = getR0(); if (r0 == 0) { instr - .getOperand() - .filter(o -> o.getType() == RAMValue.Type.NUMBER) - .ifPresentOrElse(o -> IP = o.getNumberValue(), () -> { + .getLabel() + .ifPresentOrElse(o -> IP = o.getAddress(), () -> { throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); }); } @@ -123,9 +121,8 @@ public CPU.RunState step() { int r0 = getR0(); if (r0 > 0) { instr - .getOperand() - .filter(o -> o.getType() == RAMValue.Type.NUMBER) - .ifPresentOrElse(o -> IP = o.getNumberValue(), () -> { + .getLabel() + .ifPresentOrElse(o -> IP = o.getAddress(), () -> { throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); }); } diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/LabelDebugColumn.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/LabelDebugColumn.java index f81a867f5..0a893abfc 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/LabelDebugColumn.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/LabelDebugColumn.java @@ -19,6 +19,7 @@ package net.emustudio.plugins.cpu.ram.gui; import net.emustudio.emulib.runtime.interaction.debugger.DebuggerColumn; +import net.emustudio.plugins.memory.ram.api.RAMLabel; import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; import java.util.Objects; @@ -52,6 +53,6 @@ public void setValue(int location, Object o) { @Override public String getValue(int location) { - return memory.getLabel(location).getLabel(); + return memory.getLabel(location).map(RAMLabel::getLabel).orElse(""); } } diff --git a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/AbstractEngineTest.java b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/AbstractEngineTest.java index 837b9378d..7acbc32aa 100644 --- a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/AbstractEngineTest.java +++ b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/AbstractEngineTest.java @@ -2,6 +2,7 @@ import net.emustudio.plugins.device.abstracttape.api.AbstractTapeContext; import net.emustudio.plugins.memory.ram.api.RAMInstruction; +import net.emustudio.plugins.memory.ram.api.RAMLabel; import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; import net.emustudio.plugins.memory.ram.api.RAMValue; import org.junit.Before; @@ -84,4 +85,27 @@ public RAMInstruction instr(RAMInstruction.Opcode opcode, RAMInstruction.Directi replay(instruction); return instruction; } + + public RAMInstruction instr(RAMInstruction.Opcode opcode, RAMLabel label) { + RAMInstruction instruction = createNiceMock(RAMInstruction.class); + expect(instruction.getOpcode()).andReturn(opcode).anyTimes(); + expect(instruction.getDirection()).andReturn(RAMInstruction.Direction.DIRECT).anyTimes(); + expect(instruction.getLabel()).andReturn(Optional.of(label)).anyTimes(); + replay(instruction); + return instruction; + } + + public RAMLabel label(int address, String label) { + return new RAMLabel() { + @Override + public int getAddress() { + return address; + } + + @Override + public String getLabel() { + return label; + } + }; + } } diff --git a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java index 13c542d2e..dce2a6ad6 100644 --- a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java +++ b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java @@ -320,14 +320,14 @@ public void testADD_EMPTY_R0() { @Test public void testJMP() { - setProgram(instr(RAMInstruction.Opcode.JMP, RAMInstruction.Direction.DIRECT, 100)); + setProgram(instr(RAMInstruction.Opcode.JMP, label(100, "here"))); assertEquals(CPU.RunState.STATE_STOPPED_BREAK, engine.step()); assertEquals(100, engine.IP); } @Test public void testJZ() { - setProgram(instr(RAMInstruction.Opcode.JZ, RAMInstruction.Direction.DIRECT, 0)); + setProgram(instr(RAMInstruction.Opcode.JZ, label(0, "here"))); expect(storage.getSymbolAt(0)).andReturn(Optional.empty()).times(2); replay(storage); @@ -352,7 +352,7 @@ public void testJNZ() { @Test public void testJGTZ() { - setProgram(instr(RAMInstruction.Opcode.JGTZ, RAMInstruction.Direction.DIRECT, 0)); + setProgram(instr(RAMInstruction.Opcode.JGTZ, label(0, "here"))); expect(storage.getSymbolAt(0)).andReturn(Optional.of(TapeSymbol.guess("2"))).times(2); replay(storage); diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java index 77506ded5..5f0c14435 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java @@ -92,8 +92,8 @@ public synchronized void setLabels(List labels) { } @Override - public RAMLabel getLabel(int address) { - return labels.get(address); + public Optional getLabel(int address) { + return Optional.ofNullable(labels.get(address)); } @Override diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java index 480919b36..5675f60fc 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java @@ -22,13 +22,14 @@ import net.emustudio.emulib.plugins.memory.MemoryContext; import java.util.List; +import java.util.Optional; @PluginContext public interface RAMMemoryContext extends MemoryContext { void setLabels(List labels); - RAMLabel getLabel(int address); + Optional getLabel(int address); void setInputs(List inputs); diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/RAMTableModel.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/RAMTableModel.java index 1895dcb63..8157509b5 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/RAMTableModel.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/RAMTableModel.java @@ -19,6 +19,7 @@ package net.emustudio.plugins.memory.ram.gui; import net.emustudio.plugins.memory.ram.api.RAMInstruction; +import net.emustudio.plugins.memory.ram.api.RAMLabel; import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; import net.emustudio.plugins.memory.ram.api.RAMValue; @@ -48,11 +49,7 @@ public Object getValueAt(int rowIndex, int columnIndex) { case 0: return String.valueOf(rowIndex); case 1: - String label = memory.getLabel(rowIndex).getLabel(); - if (label != null) { - return label; - } - break; + return memory.getLabel(rowIndex).map(RAMLabel::getLabel).orElse(""); case 2: RAMInstruction i = memory.read(rowIndex); return i.getOpcode() + " " + i.getOperand().map(RAMValue::getStringRepresentation).orElse(""); From f4e12d6096b55049fd70ccdd411a8ceecc2ffa17 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 10 May 2022 08:11:32 +0200 Subject: [PATCH 135/314] [#201] ram-mem: Fixed reporting memory size --- .../application/gui/debugtable/DebugTableModelImpl.java | 4 ++++ .../emustudio/application/gui/dialogs/EmulatorPanel.java | 4 ++++ .../emustudio/plugins/memory/ram/MemoryContextImpl.java | 8 ++++++++ 3 files changed, 16 insertions(+) diff --git a/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableModelImpl.java b/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableModelImpl.java index a90ab36a2..af4560ee1 100644 --- a/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableModelImpl.java +++ b/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableModelImpl.java @@ -22,6 +22,7 @@ import net.emustudio.emulib.plugins.cpu.Disassembler; import net.emustudio.emulib.runtime.interaction.debugger.*; +import javax.swing.event.TableModelEvent; import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -45,6 +46,7 @@ public void setCPU(CPU cpu, int memorySize) { public void setMaxRows(int maxRows) { if (ida != null) { ida.setInstructionsPerPage(maxRows); + fireTableChanged(new TableModelEvent(this)); } } @@ -173,11 +175,13 @@ public boolean isRowAtCurrentInstruction(int rowIndex) { @Override public void memoryChanged(int from, int to) { Optional.ofNullable(ida).ifPresent(i -> i.flushCache(from, to + 1)); + fireTableDataChanged(); } @Override public void setMemorySize(int memorySize) { Optional.ofNullable(ida).ifPresent(i -> i.setMemorySize(memorySize)); + fireTableChanged(new TableModelEvent(this)); } @Override diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/EmulatorPanel.java b/application/src/main/java/net/emustudio/application/gui/dialogs/EmulatorPanel.java index 7dc655e49..f7599b315 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/EmulatorPanel.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/EmulatorPanel.java @@ -58,6 +58,10 @@ public EmulatorPanel(JFrame parent, VirtualComputer computer, DebugTableModel de EmulationController emulationController, MemoryContext memoryContext) { this.memoryContext = memoryContext; this.debugTableModel = Objects.requireNonNull(debugTableModel); + if (memoryContext != null) { + this.debugTableModel.setMemorySize(memoryContext.getSize()); + } + this.debugTable = new DebugTableImpl(debugTableModel); paneDebug.setViewportView(debugTable); diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java index 5f0c14435..ae925b0ba 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java @@ -66,14 +66,22 @@ public RAMInstruction[] read(int address, int count) { @Override public void write(int address, RAMInstruction value) { + boolean sizeChanged = !memory.containsKey(address); memory.put(address, value); + if (sizeChanged) { + notifyMemorySizeChanged(); + } notifyMemoryChanged(address); } @Override public void write(int address, RAMInstruction[] values, int count) { for (int i = 0; i < count; i++) { + boolean sizeChanged = !memory.containsKey(address); memory.put(address + i, values[i]); + if (sizeChanged) { + notifyMemorySizeChanged(); + } notifyMemoryChanged(address + i); } } From 7c4b508e2f7027071037cbb01dd8bec9812229cb Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 10 May 2022 08:22:26 +0200 Subject: [PATCH 136/314] [#201] fix bad refactoring --- RELEASES.md | 8 ++++---- .../as-8080/src/main/examples/char_max_code.asm | 2 +- .../as-8080/src/main/examples/numbers_count.asm | 10 +++++----- .../compiler/as-8080/src/main/examples/reverse.asm | 6 +++--- .../compiler/as-z80/src/main/examples/reverse.asm | 6 +++--- .../brainc-brainduck/src/main/examples/rot13.b | 2 +- plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 | 2 +- plugins/compiler/ramc-ram/src/main/examples/copy.ram | 2 +- .../ramc-ram/src/main/examples/equal_count.ram | 2 +- .../ramc-ram/src/main/examples/factorial.ram | 2 +- .../ramc-ram/src/main/examples/ones_count.ram | 2 +- .../compiler/ramc-ram/src/main/examples/reverse.ram | 2 +- .../raspc-rasp/src/main/examples/RAMinRASP.rasp | 8 ++++---- .../raspc-rasp/src/main/examples/RASPinRAM.ram | 12 ++++++------ .../raspc-rasp/src/main/examples/factorial.rasp | 4 ++-- .../compiler/raspc-rasp/src/main/jflex/lexer.jflex | 2 +- 16 files changed, 36 insertions(+), 36 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index d824bdec7..c78bfcf3c 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -15,7 +15,7 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS ## main-module: - removed configuration editor popup in the schema editor - reimplemented source code editor using [RSyntaxTextArea](https://github.com/bobbylight/RSyntaxTextArea) -- reimplemented emulation automation (`--value` is not required anymore, introduced more command line options) +- reimplemented emulation automation (`--input` is not required anymore, introduced more command line options) - introduced configuration file for the main module - be able to configure Look and Feel in the configuration - make debug table responsive @@ -42,14 +42,14 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS ## RASP: - rewritten raspc-rasp grammar and compiler -- raspc-rasp: implemented `` directive +- raspc-rasp: implemented `` directive ## SSEM: - fix: SSEM noodle-timer doesn't work ## adm3A-terminal: - fix: load cursor from software -- fix: keyboard does not read value +- fix: keyboard does not read input - fix: "here is" does not work (in GUI) - throws some hidden exception - fix: "always on top" doesn't work @@ -105,7 +105,7 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS - "previous instruction" just decrements program counter - fixed syntax highlighting - fixed: on breakpoint, instruction list was not pointing at current (next) instruction -- fixed: on 'pages backwards' button when the value window is cancelled, NullPointerException appeared in log +- fixed: on 'pages backwards' button when the input window is cancelled, NullPointerException appeared in log - fixed: when file was not saved before compilation, on most compilers NullPointerException appeared in log - fixed: in source code editor, when open file is cancelled, compiler output window was cleared - find/replace dialog is now possible to be cancelled with ESC key diff --git a/plugins/compiler/as-8080/src/main/examples/char_max_code.asm b/plugins/compiler/as-8080/src/main/examples/char_max_code.asm index fb61a2fa8..2c0830367 100644 --- a/plugins/compiler/as-8080/src/main/examples/char_max_code.asm +++ b/plugins/compiler/as-8080/src/main/examples/char_max_code.asm @@ -11,7 +11,7 @@ mvi d,0 ; char with maximum ASCII code char_loop: call getchar -cpi 10 ; end of value? +cpi 10 ; end of input? jz char_end cpi 13 jz char_end diff --git a/plugins/compiler/as-8080/src/main/examples/numbers_count.asm b/plugins/compiler/as-8080/src/main/examples/numbers_count.asm index 32dc6cffe..43de84d3e 100644 --- a/plugins/compiler/as-8080/src/main/examples/numbers_count.asm +++ b/plugins/compiler/as-8080/src/main/examples/numbers_count.asm @@ -5,16 +5,16 @@ dcx sp ; stack initialization (0FFFFh) lxi h,text1 call putstr ; print text1 -lxi d,value ; address for string value +lxi d,input ; address for string input call getline ; read from keyboard -lxi b,value +lxi b,input mvi d,0 ; numbers counter char_loop: ldax b inx b -cpi 10 ; end of value? +cpi 10 ; end of input? jz char_end cpi 13 jz char_end @@ -41,6 +41,6 @@ include 'include\putstr.inc' include 'include\putchar.inc' include 'include\newline.inc' -text1: db 'Count of numbers on value ...',10,13,'Enter text: ',0 +text1: db 'Count of numbers on input ...',10,13,'Enter text: ',0 text2: db 10,13,'Count: ',0 -value: ds 30 +input: ds 30 diff --git a/plugins/compiler/as-8080/src/main/examples/reverse.asm b/plugins/compiler/as-8080/src/main/examples/reverse.asm index b59f22d7c..09bd8b16d 100644 --- a/plugins/compiler/as-8080/src/main/examples/reverse.asm +++ b/plugins/compiler/as-8080/src/main/examples/reverse.asm @@ -6,7 +6,7 @@ dcx sp ; stack initialization (0FFFFh) lxi h,text1 call putstr ; print text1 -lxi d,value ; address for string value +lxi d,input ; address for string input call getline ; read from keyboard lxi b,value @@ -16,7 +16,7 @@ mvi d,0 ; chars counter char_loop: ldax b inx b ; bc = bc+1 -cpi 10 ; end of value? +cpi 10 ; end of input? jz char_end cpi 13 jz char_end @@ -53,4 +53,4 @@ include 'include\newline.inc' text1: db 'Reversed text ...',10,13,'Enter text: ',0 text2: db 10,13,'Reversed: ',0 -value: ds 30 +input: ds 30 diff --git a/plugins/compiler/as-z80/src/main/examples/reverse.asm b/plugins/compiler/as-z80/src/main/examples/reverse.asm index 794453d3a..f2f73daba 100644 --- a/plugins/compiler/as-z80/src/main/examples/reverse.asm +++ b/plugins/compiler/as-z80/src/main/examples/reverse.asm @@ -6,7 +6,7 @@ dec sp ; stack initialization (0FFFFh) ld hl,text1 call putstr ; print text1 -ld de,value ; address for string value +ld de,input ; address for string input call getline ; read from keyboard ld bc,value @@ -16,7 +16,7 @@ ld d,0 ; chars counter char_loop: ld a, (bc) inc bc ; bc = bc+1 -cp 10 ; end of value? +cp 10 ; end of input? jp z, char_end cp 13 jp z, char_end @@ -52,4 +52,4 @@ include "include\newline.inc" text1: db "Reversed text ...",10,13,"Enter text: ",0 text2: db 10,13,"Reversed: ",0 -value: ds 30 +input: ds 30 diff --git a/plugins/compiler/brainc-brainduck/src/main/examples/rot13.b b/plugins/compiler/brainc-brainduck/src/main/examples/rot13.b index ff68ab079..26a2b7bf9 100644 --- a/plugins/compiler/brainc-brainduck/src/main/examples/rot13.b +++ b/plugins/compiler/brainc-brainduck/src/main/examples/rot13.b @@ -20,7 +20,7 @@ of course any function char f(char) can be made easily on the same principle My pathological program rot13.b is good for testing the response to deep -brackets; the value "~mlk zyx" should produce the output "~zyx mlk". +brackets; the input "~mlk zyx" should produce the output "~zyx mlk". Daniel B Cristofani (cristofdathevanetdotcom) http://www.hevanet.com/cristofd/brainfuck/ diff --git a/plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 b/plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 index cea9b0aa8..92d2d386e 100644 --- a/plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 +++ b/plugins/compiler/ramc-ram/src/main/antlr/RAMLexer.g4 @@ -41,7 +41,7 @@ OPCODE_JZ: J Z; OP_CONSTANT: '='; OP_INDIRECT: '*'; -PREP_INPUT: ('<' I N P U T '>')| ('<' V A L U E '>'); +PREP_INPUT: '<' I N P U T '>'; LIT_HEXNUMBER_1: '0' X [0-9a-fA-F]+; LIT_NUMBER: [0-9]+ D?; diff --git a/plugins/compiler/ramc-ram/src/main/examples/copy.ram b/plugins/compiler/ramc-ram/src/main/examples/copy.ram index 12ce6d1f0..a41b279f9 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/copy.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/copy.ram @@ -1,4 +1,4 @@ - 3 4 ignored world hello + 3 4 ignored world hello ; COPY(X,Y) ; diff --git a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram index 07b2ce1d6..33cb15cb3 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram @@ -1,4 +1,4 @@ -; value: X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape +; input: X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape ; output: 1 if N1(X) = N2(X) (i.e. if X contains equal number of "1" and "2") ; 0 otherwise diff --git a/plugins/compiler/ramc-ram/src/main/examples/factorial.ram b/plugins/compiler/ramc-ram/src/main/examples/factorial.ram index a7150cb9c..5d7b65bba 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/factorial.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/factorial.ram @@ -1,6 +1,6 @@ ; Factorial N ; -; value: N +; input: N ; output: N! ; diff --git a/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram b/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram index c5bb540c7..f6181bbc6 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram @@ -1,4 +1,4 @@ -; value : X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape +; input : X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape ; output: N1(X) - number of ones in X. 1 2 3 4 5 6 7 1 1 1 2 5 0 diff --git a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram index 25395bdea..a5f4c39ae 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram @@ -1,4 +1,4 @@ -; value : X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape +; input : X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape ; output: XR - reverse of X 1 2 3 3 2 1 2 3 5.5 3 4 5 53 34 2 34 diff --git a/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp b/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp index 646b5e424..dcb5146ae 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp +++ b/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp @@ -38,9 +38,9 @@ org 3 LOAD =1000 - STORE 1 ;in R1 there is the pointer for writing the next instruction or operand from the value tape -value: - READ 2 ;loads the value from the value tape into R2 register + STORE 1 ;in R1 there is the pointer for writing the next instruction or operand from the input tape +input: + READ 2 ;loads the value from the input tape into R2 register LOAD 2 SUB =-1 JZ initialisation ;if the value is equal to -1, jump to initialisation @@ -53,7 +53,7 @@ value: LOAD 1 ADD =1 STORE 1 ;increase the pointer - JMP value ;the next value + JMP input ;the next input initialisation: LOAD =1000 ;R2=1000 diff --git a/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram b/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram index e7bf751d9..dc602bc33 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram +++ b/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram @@ -43,21 +43,21 @@ ;JGTZ - 17 ;HALT - 18 -;==============loading the RASP program from the value tape============================================ +;==============loading the RASP program from the input tape============================================ LOAD =4 - STORE 1 ;R1 contains the pointer for writing the next instruction or operand loaded from the value tape -value: - READ 2 ;loads the value from the tape into R2 + STORE 1 ;R1 contains the pointer for writing the next instruction or operand loaded from the input tape +input: + READ 2 ;loads the input from the tape into R2 LOAD 2 SUB =-1 - JZ initialisation ;if the value is equal to -1, jump to initialisation + JZ initialisation ;if the input is equal to -1, jump to initialisation LOAD 2 STORE *1 ;otherwise, store it LOAD 1 ADD =1 STORE 1 ;increment the pointer - JMP value ;the next value + JMP input ;the next input ;=============== registers initialisation=============================================================== initialisation: diff --git a/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp b/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp index 16268b993..a23473165 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp +++ b/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp @@ -1,13 +1,13 @@ org 5 -;Program reads an integer number from the value tape, calculates its factorial and prints the result onto the output tape. +;Program reads an integer number from the input tape, calculates its factorial and prints the result onto the output tape. ;saves the constant 1 into R2 and R3 registers load =1 store 2 store 3 -;reads a number from the value tape +;reads a number from the input tape read 1 ;if the number is greater than 0, jump to "ok", otherwise, jump to "finish" load 1 diff --git a/plugins/compiler/raspc-rasp/src/main/jflex/lexer.jflex b/plugins/compiler/raspc-rasp/src/main/jflex/lexer.jflex index 813f7687f..eb388eca9 100644 --- a/plugins/compiler/raspc-rasp/src/main/jflex/lexer.jflex +++ b/plugins/compiler/raspc-rasp/src/main/jflex/lexer.jflex @@ -132,7 +132,7 @@ operator_constant = "=" return token(TokenImpl.ORG, Token.PREPROCESSOR); } -"" { +"" { return token(TokenImpl.TINPUT, Token.PREPROCESSOR); } From 9bc8e3edf302f3e8886d074bdaaed217982d19c0 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 10 May 2022 08:27:22 +0200 Subject: [PATCH 137/314] [#201] fixed bad refactoring --- plugins/compiler/as-8080/src/main/examples/reverse.asm | 2 +- plugins/compiler/as-z80/src/main/examples/reverse.asm | 2 +- plugins/compiler/ramc-ram/src/main/examples/copy.ram | 2 +- plugins/compiler/ramc-ram/src/main/examples/equal_count.ram | 2 +- plugins/compiler/ramc-ram/src/main/examples/ones_count.ram | 2 +- plugins/compiler/ramc-ram/src/main/examples/reverse.ram | 2 +- plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/examples/reverse.asm b/plugins/compiler/as-8080/src/main/examples/reverse.asm index 09bd8b16d..9bde7b4cc 100644 --- a/plugins/compiler/as-8080/src/main/examples/reverse.asm +++ b/plugins/compiler/as-8080/src/main/examples/reverse.asm @@ -9,7 +9,7 @@ call putstr ; print text1 lxi d,input ; address for string input call getline ; read from keyboard -lxi b,value +lxi b,input mvi d,0 ; chars counter diff --git a/plugins/compiler/as-z80/src/main/examples/reverse.asm b/plugins/compiler/as-z80/src/main/examples/reverse.asm index f2f73daba..95b7c67d3 100644 --- a/plugins/compiler/as-z80/src/main/examples/reverse.asm +++ b/plugins/compiler/as-z80/src/main/examples/reverse.asm @@ -9,7 +9,7 @@ call putstr ; print text1 ld de,input ; address for string input call getline ; read from keyboard -ld bc,value +ld bc,input ld d,0 ; chars counter diff --git a/plugins/compiler/ramc-ram/src/main/examples/copy.ram b/plugins/compiler/ramc-ram/src/main/examples/copy.ram index a41b279f9..d6f876ac7 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/copy.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/copy.ram @@ -2,7 +2,7 @@ ; COPY(X,Y) ; -; value: +; input: ; reg.1: X ; reg.2: Y ; diff --git a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram index 33cb15cb3..227365766 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram @@ -1,4 +1,4 @@ -; input: X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape +; input: X0 - string X zero-ended, X in {1,2,3,....}*, on the input tape ; output: 1 if N1(X) = N2(X) (i.e. if X contains equal number of "1" and "2") ; 0 otherwise diff --git a/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram b/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram index f6181bbc6..3410ade4f 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram @@ -1,4 +1,4 @@ -; input : X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape +; input : X0 - string X zero-ended, X in {1,2,3,....}*, on the input tape ; output: N1(X) - number of ones in X. 1 2 3 4 5 6 7 1 1 1 2 5 0 diff --git a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram index a5f4c39ae..516f942dc 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram @@ -1,4 +1,4 @@ -; input : X0 - string X zero-ended, X in {1,2,3,....}*, on the value tape +; input : X0 - string X zero-ended, X in {1,2,3,....}*, on the input tape ; output: XR - reverse of X 1 2 3 3 2 1 2 3 5.5 3 4 5 53 34 2 34 diff --git a/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp b/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp index dcb5146ae..d680b3224 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp +++ b/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp @@ -40,10 +40,10 @@ org 3 LOAD =1000 STORE 1 ;in R1 there is the pointer for writing the next instruction or operand from the input tape input: - READ 2 ;loads the value from the input tape into R2 register + READ 2 ;loads the input from the input tape into R2 register LOAD 2 SUB =-1 - JZ initialisation ;if the value is equal to -1, jump to initialisation + JZ initialisation ;if the input is equal to -1, jump to initialisation LOAD 1 STORE 22 From e645bc690017c31ccefb72cda12f3da94f4f2540 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 10 May 2022 10:32:41 +0200 Subject: [PATCH 138/314] [#201] ram-mem: tests, z80-cpu: fix outi,ini,... flags --- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 6 +- .../memory/ram/MemoryContextImplTest.java | 98 +++++++++++++++++++ 2 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryContextImplTest.java diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 177d965a7..4703105c3 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -1232,7 +1232,7 @@ int I_IND() throws IOException { regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; - flags |= FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0); + flags = FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0) | (flags & FLAG_C) | (flags & FLAG_S) | (flags & FLAG_PV) | (flags & FLAG_H); return 16; } @@ -1266,7 +1266,7 @@ int I_OUTI() throws IOException { regs[REG_L] = address & 0xFF; regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - flags |= FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0); + flags = FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0) | (flags & FLAG_C) | (flags & FLAG_S) | (flags & FLAG_PV) | (flags & FLAG_H); return 16; } @@ -1299,7 +1299,7 @@ int I_OUTD() throws IOException { regs[REG_L] = address & 0xFF; regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - flags |= FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0); + flags = FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0) | (flags & FLAG_C) | (flags & FLAG_S) | (flags & FLAG_PV) | (flags & FLAG_H); return 16; } diff --git a/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryContextImplTest.java b/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryContextImplTest.java new file mode 100644 index 000000000..fc94c1ebd --- /dev/null +++ b/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryContextImplTest.java @@ -0,0 +1,98 @@ +package net.emustudio.plugins.memory.ram; + +import net.emustudio.emulib.plugins.memory.Memory; +import net.emustudio.plugins.memory.ram.api.RAMInstruction; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicInteger; + +import static org.easymock.EasyMock.createNiceMock; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class MemoryContextImplTest { + + private MemoryContextImpl memory; + + @Before + public void setUp() { + this.memory = new MemoryContextImpl(); + } + + @Test + public void testMemoryNotificationsAreEnabledByDefault() { + assertTrue(memory.areMemoryNotificationsEnabled()); + } + + @Test + public void testNotifyMemoryChangesOnWrite() { + AtomicInteger memoryChanges = new AtomicInteger(); + AtomicInteger memorySizeChanges = new AtomicInteger(); + + memory.addMemoryListener(new Memory.MemoryListener() { + @Override + public void memoryChanged(int memoryPosition) { + memoryChanges.incrementAndGet(); + } + + @Override + public void memorySizeChanged() { + memorySizeChanges.incrementAndGet(); + } + }); + + memory.write(0, (RAMInstruction)createNiceMock(RAMInstruction.class)); + memory.write(0, (RAMInstruction)createNiceMock(RAMInstruction.class)); + + assertEquals(1, memorySizeChanges.get()); + assertEquals(2, memoryChanges.get()); + } + + @Test + public void testNotifyMemoryChangesOnWrite2() { + AtomicInteger memoryChanges = new AtomicInteger(); + AtomicInteger memorySizeChanges = new AtomicInteger(); + + memory.addMemoryListener(new Memory.MemoryListener() { + @Override + public void memoryChanged(int memoryPosition) { + memoryChanges.incrementAndGet(); + } + + @Override + public void memorySizeChanged() { + memorySizeChanges.incrementAndGet(); + } + }); + + memory.write(0, new RAMInstruction[] { createNiceMock(RAMInstruction.class), createNiceMock(RAMInstruction.class)}, 2); + + assertEquals(1, memorySizeChanges.get()); + assertEquals(2, memoryChanges.get()); + } + + @Test + public void testMemoryChangesAreNotNotifiedOnRead() { + AtomicInteger memoryChanges = new AtomicInteger(); + AtomicInteger memorySizeChanges = new AtomicInteger(); + + memory.addMemoryListener(new Memory.MemoryListener() { + @Override + public void memoryChanged(int memoryPosition) { + memoryChanges.incrementAndGet(); + } + + @Override + public void memorySizeChanged() { + memorySizeChanges.incrementAndGet(); + } + }); + + memory.read(0); + + assertEquals(0, memorySizeChanges.get()); + assertEquals(0, memoryChanges.get()); + } + +} From 7d5ec6b9f3d5805e3e668f5dad8ef01521378b6f Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 12 May 2022 10:53:26 +0200 Subject: [PATCH 139/314] [#201] RASP reimplementation --- application/build.gradle | 20 +- .../ramc-ram/src/main/antlr/RAMParser.g4 | 4 +- .../plugins/compiler/ram/CompilerRAM.java | 18 +- .../ram/{visitors => }/ProgramParser.java | 4 +- .../plugins/compiler/ram/Runner.java | 2 +- .../raspc-rasp/src/main/antlr/RASPLexer.g4 | 58 +++ .../raspc-rasp/src/main/antlr/RASPParser.g4 | 58 +++ .../raspc-rasp/src/main/cup/parser.cup | 159 ------- .../plugins/compiler/rasp/CompilerRASP.java | 177 ++++++++ .../compiler/rasp/LexicalAnalyzerImpl.java | 95 ++++ .../compiler/rasp/ParserErrorListener.java | 25 ++ .../plugins/compiler/rasp/ParsingUtils.java | 50 +++ .../plugins/compiler/rasp/ProgramParser.java | 151 +++++++ .../compiler/{raspc => rasp}/Runner.java | 8 +- .../compiler/rasp/ast/Instruction.java | 62 +++ .../plugins/compiler/rasp/ast/Label.java | 54 +++ .../plugins/compiler/rasp/ast/Program.java | 126 ++++++ .../rasp/exceptions/CompileException.java | 20 + .../rasp/exceptions/SyntaxErrorException.java | 11 + .../plugins/compiler/raspc/CompilerImpl.java | 205 --------- .../compiler/raspc/CompilerOutput.java | 116 ----- .../plugins/compiler/raspc/Namespace.java | 28 -- .../plugins/compiler/raspc/Statement.java | 57 --- .../plugins/compiler/raspc/TokenImpl.java | 88 ---- .../compiler/raspc/tree/AbstractTreeNode.java | 24 - .../plugins/compiler/raspc/tree/Input.java | 42 -- .../plugins/compiler/raspc/tree/Label.java | 49 --- .../plugins/compiler/raspc/tree/Program.java | 68 --- .../plugins/compiler/raspc/tree/Row.java | 63 --- .../compiler/raspc/tree/SourceCode.java | 69 --- .../raspc-rasp/src/main/jflex/lexer.jflex | 184 -------- .../{raspc => rasp}/version.properties | 0 .../{raspc => rasp}/AbstractCompilerTest.java | 10 +- .../{raspc => rasp}/CompilerTest.java | 26 +- .../plugins/compiler/rasp/MemoryStub.java | 74 ++++ .../plugins/compiler/raspc/MemoryStub.java | 84 ---- .../emustudio/plugins/cpu/ram/CpuImpl.java | 6 +- .../plugins/cpu/ram/EmulatorEngine.java | 15 +- .../plugins/cpu/ram/api/RAMCpuContext.java | 31 ++ .../plugins/cpu/ram/EmulatorEngineTest.java | 44 +- plugins/cpu/rasp-cpu/build.gradle | 1 - .../emustudio/plugins/cpu/rasp/CpuImpl.java | 47 +- .../plugins/cpu/rasp/EmulatorEngine.java | 415 +++++++----------- .../plugins/cpu/rasp/RASPCpuContext.java | 116 ----- .../plugins/cpu/rasp/RASPCpuContextImpl.java | 48 ++ .../plugins/cpu/rasp/api/RASPCpuContext.java} | 41 +- .../cpu/rasp/gui/LabelDebugColumn.java | 3 +- .../cpu/rasp/gui/RASPCpuStatusPanel.java | 13 +- .../cpu/rasp/gui/RASPDisassembler.java | 66 +-- .../plugins/cpu/rasp/EmulatorEngineTest.java | 54 +-- .../plugins/cpu/rasp/MemoryStub.java | 74 ++++ .../emustudio/plugins/cpu/rasp/RASPCell.java | 38 ++ .../plugins/cpu/rasp/RaspMemoryStub.java | 93 ---- .../abstracttape/AbstractTapeContextImpl.java | 53 ++- .../abstracttape/api/AbstractTapeContext.java | 31 +- .../device/abstracttape/gui/TapeGui.java | 16 +- .../plugins/memory/rasp/InstructionImpl.java | 104 ----- .../memory/rasp/MemoryContextImpl.java | 223 +++++----- .../plugins/memory/rasp/MemoryImpl.java | 5 + .../plugins/memory/rasp/api/MemoryItem.java | 30 -- .../memory/rasp/api/RASPInstruction.java | 115 ----- .../plugins/memory/rasp/api/RASPLabel.java | 23 + .../memory/rasp/api/RASPMemoryCell.java | 12 + .../memory/rasp/api/RASPMemoryContext.java | 42 +- .../plugins/memory/rasp/gui/Disassembler.java | 38 ++ .../plugins/memory/rasp/gui/MemoryDialog.java | 2 +- .../memory/rasp/gui/RASPTableModel.java | 119 +++-- settings.gradle | 6 +- 68 files changed, 1812 insertions(+), 2401 deletions(-) rename plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/{visitors => }/ProgramParser.java (96%) create mode 100644 plugins/compiler/raspc-rasp/src/main/antlr/RASPLexer.g4 create mode 100644 plugins/compiler/raspc-rasp/src/main/antlr/RASPParser.g4 delete mode 100644 plugins/compiler/raspc-rasp/src/main/cup/parser.cup create mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java create mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/LexicalAnalyzerImpl.java create mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParserErrorListener.java create mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParsingUtils.java create mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ProgramParser.java rename plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/{raspc => rasp}/Runner.java (93%) create mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Instruction.java create mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java create mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Program.java create mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/exceptions/CompileException.java create mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/exceptions/SyntaxErrorException.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/CompilerImpl.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/CompilerOutput.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/Namespace.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/Statement.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/TokenImpl.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/tree/AbstractTreeNode.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/tree/Input.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/tree/Label.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/tree/Program.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/tree/Row.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/tree/SourceCode.java delete mode 100644 plugins/compiler/raspc-rasp/src/main/jflex/lexer.jflex rename plugins/compiler/raspc-rasp/src/main/resources/net/emustudio/plugins/compiler/{raspc => rasp}/version.properties (100%) rename plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/{raspc => rasp}/AbstractCompilerTest.java (90%) rename plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/{raspc => rasp}/CompilerTest.java (51%) create mode 100644 plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/MemoryStub.java delete mode 100644 plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/raspc/MemoryStub.java delete mode 100644 plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/RASPCpuContext.java create mode 100644 plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/RASPCpuContextImpl.java rename plugins/{memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/NumberMemoryItem.java => cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/api/RASPCpuContext.java} (51%) create mode 100644 plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/MemoryStub.java create mode 100644 plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/RASPCell.java delete mode 100644 plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/RaspMemoryStub.java delete mode 100644 plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/InstructionImpl.java delete mode 100644 plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/MemoryItem.java delete mode 100644 plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPInstruction.java create mode 100644 plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPLabel.java create mode 100644 plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryCell.java create mode 100644 plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/Disassembler.java diff --git a/application/build.gradle b/application/build.gradle index e1192e018..77888b364 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -1,7 +1,7 @@ /* * This file is part of emuStudio. * - * Copyright (C) 2006-2020 Peter Jakubčo + * Copyright (C) 2006-2022 Peter Jakubčo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -54,17 +54,17 @@ dependencies { providedRuntime project(":plugins:compiler:as-z80") providedRuntime project(":plugins:compiler:brainc-brainduck") providedRuntime project(":plugins:compiler:ramc-ram") -// providedRuntime project(":plugins:compiler:raspc-rasp") + providedRuntime project(":plugins:compiler:raspc-rasp") providedRuntime project(":plugins:memory:ram-mem") - // providedRuntime project(":plugins:memory:rasp-mem") + providedRuntime project(":plugins:memory:rasp-mem") providedRuntime project(":plugins:memory:ssem-mem") providedRuntime project(":plugins:memory:byte-mem") providedRuntime project(":plugins:cpu:8080-cpu") providedRuntime project(":plugins:cpu:brainduck-cpu") providedRuntime project(":plugins:cpu:ram-cpu") - // providedRuntime project(":plugins:cpu:rasp-cpu") + providedRuntime project(":plugins:cpu:rasp-cpu") providedRuntime project(":plugins:cpu:z80-cpu") providedRuntime project(":plugins:cpu:ssem-cpu") @@ -180,13 +180,13 @@ distributions { from(output(":plugins:compiler:as-ssem")) from(output(":plugins:compiler:brainc-brainduck")) from(output(":plugins:compiler:ramc-ram")) - //from(output(":plugins:compiler:raspc-rasp")) + from(output(":plugins:compiler:raspc-rasp")) } into('memory') { include '*.jar' from(output(":plugins:memory:ram-mem")) - // from(output(":plugins:memory:rasp-mem")) + from(output(":plugins:memory:rasp-mem")) from(output(":plugins:memory:ssem-mem")) from(output(":plugins:memory:byte-mem")) } @@ -196,7 +196,7 @@ distributions { from(output(":plugins:cpu:8080-cpu")) from(output(":plugins:cpu:brainduck-cpu")) from(output(":plugins:cpu:ram-cpu")) - // from(output(":plugins:cpu:rasp-cpu")) + from(output(":plugins:cpu:rasp-cpu")) from(output(":plugins:cpu:z80-cpu")) from(output(":plugins:cpu:ssem-cpu")) } @@ -213,16 +213,14 @@ distributions { } // Examples - //["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"] - ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram"].collect { compiler -> + ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"].collect { compiler -> from(examples(":plugins:compiler:$compiler")) { into "examples/$compiler" } } // Scripts - // ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"] - ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram"].collect { compiler -> + ["as-8080", "as-z80", "as-ssem", "brainc-brainduck", "ramc-ram", "raspc-rasp"].collect { compiler -> from(scripts(":plugins:compiler:$compiler")) { into "bin" } diff --git a/plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 b/plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 index 3ba07ba1a..74d512290 100644 --- a/plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 +++ b/plugins/compiler/ramc-ram/src/main/antlr/RAMParser.g4 @@ -18,8 +18,8 @@ rLine: comment: COMMENT? | COMMENT2?; rStatement: - instr=rInstruction - | value=rInput + rInstruction + | rInput ; rInstruction: diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java index 8687ea03b..81fe1470d 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java @@ -24,9 +24,7 @@ import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; import net.emustudio.emulib.plugins.compiler.SourceFileExtension; import net.emustudio.emulib.runtime.*; -import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.plugins.compiler.ram.ast.Program; -import net.emustudio.plugins.compiler.ram.visitors.ProgramParser; import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; @@ -39,7 +37,7 @@ import java.io.Reader; import java.util.*; -@PluginRoot(type = PLUGIN_TYPE.COMPILER, title = "RAM Compiler") +@PluginRoot(type = PLUGIN_TYPE.COMPILER, title = "RAM Machine Assembler") @SuppressWarnings("unused") public class CompilerRAM extends AbstractCompiler { private final static Logger LOGGER = LoggerFactory.getLogger(CompilerRAM.class); @@ -63,15 +61,17 @@ public String getCopyright() { @Override public String getDescription() { - return "RAM machine compiler"; + return "RAM machine assembler"; } public void initialize() { - try { - this.memory = applicationApi.getContextPool().getMemoryContext(pluginID, RAMMemoryContext.class); - } catch (InvalidContextException | ContextNotFoundException e) { - LOGGER.warn("Memory is not available", e); - } + Optional.ofNullable(applicationApi.getContextPool()).ifPresent(pool -> { + try { + memory = pool.getMemoryContext(pluginID, RAMMemoryContext.class); + } catch (InvalidContextException | ContextNotFoundException e) { + LOGGER.warn("Memory is not available", e); + } + }); } @Override diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/visitors/ProgramParser.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ProgramParser.java similarity index 96% rename from plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/visitors/ProgramParser.java rename to plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ProgramParser.java index 74bef6ff4..db9367f52 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/visitors/ProgramParser.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ProgramParser.java @@ -1,7 +1,5 @@ -package net.emustudio.plugins.compiler.ram.visitors; +package net.emustudio.plugins.compiler.ram; -import net.emustudio.plugins.compiler.ram.RAMParser; -import net.emustudio.plugins.compiler.ram.RAMParserBaseVisitor; import net.emustudio.plugins.compiler.ram.ast.Instruction; import net.emustudio.plugins.compiler.ram.ast.Label; import net.emustudio.plugins.compiler.ram.ast.Program; diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/Runner.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/Runner.java index dd14fd8e8..90aae1f80 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/Runner.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/Runner.java @@ -57,7 +57,7 @@ public static void main(String... args) { } else { outputFile = inputFile; } - outputFile += ".hex"; + outputFile += ".bram"; } CompilerRAM compiler = new CompilerRAM(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE); diff --git a/plugins/compiler/raspc-rasp/src/main/antlr/RASPLexer.g4 b/plugins/compiler/raspc-rasp/src/main/antlr/RASPLexer.g4 new file mode 100644 index 000000000..b18440e9d --- /dev/null +++ b/plugins/compiler/raspc-rasp/src/main/antlr/RASPLexer.g4 @@ -0,0 +1,58 @@ +lexer grammar RASPLexer; + +COMMENT: ('//' | '--' | ';' | '#' ) ~[\r\n]*; +COMMENT2: '/*' .*? '*/'; + +fragment A: [aA]; +fragment B: [bB]; +fragment D: [dD]; +fragment E: [eE]; +fragment G: [gG]; +fragment H: [hH]; +fragment I: [iI]; +fragment J: [jJ]; +fragment L: [lL]; +fragment M: [mM]; +fragment N: [nN]; +fragment O: [oO]; +fragment P: [pP]; +fragment R: [rR]; +fragment S: [sS]; +fragment T: [tT]; +fragment U: [uU]; +fragment V: [vV]; +fragment W: [wW]; +fragment X: [xX]; +fragment Z: [zZ]; + +OPCODE_READ: R E A D; +OPCODE_WRITE: W R I T E; +OPCODE_LOAD: L O A D; +OPCODE_STORE: S T O R E; +OPCODE_ADD: A D D; +OPCODE_SUB: S U B; +OPCODE_MUL: M U L; +OPCODE_DIV: D I V; +OPCODE_JMP: J M P; +OPCODE_JZ: J Z; +OPCODE_JGTZ: J G T Z; +OPCODE_HALT: H A L T; + +OP_CONSTANT: '='; + +PREP_ORG: O R G; +PREP_INPUT: '<' I N P U T '>'; + +LIT_HEXNUMBER_1: '0' X [0-9a-fA-F]+; +LIT_NUMBER: [0-9]+ D?; +LIT_HEXNUMBER_2: [0-9a-fA-F]+ H; +LIT_OCTNUMBER: [0-7]+ [oOqQ]; +LIT_BINNUMBER: [01]+ B; + +ID_IDENTIFIER: [a-zA-Z_?@] [a-zA-Z_?@0-9]*; +ID_LABEL: ID_IDENTIFIER ':'; + +WS : [ \t\f]+ -> channel(HIDDEN); +EOL: '\r'? '\n'; + +ERROR: .; diff --git a/plugins/compiler/raspc-rasp/src/main/antlr/RASPParser.g4 b/plugins/compiler/raspc-rasp/src/main/antlr/RASPParser.g4 new file mode 100644 index 000000000..fc3f7e42a --- /dev/null +++ b/plugins/compiler/raspc-rasp/src/main/antlr/RASPParser.g4 @@ -0,0 +1,58 @@ +parser grammar RASPParser; + +options { + tokenVocab = RASPLexer; +} + +rStart: + (rLine EOL rLine)* EOF + | rLine EOF + ; + +rLine: + label=ID_LABEL? statement=rStatement comment + | label=ID_LABEL comment + | comment + ; + +comment: COMMENT? | COMMENT2?; + +rStatement: + rInstruction + | rInput + | rOrg + ; + + +rInstruction: + op=OPCODE_READ n=rNumber # instrRegister + | op=OPCODE_WRITE OP_CONSTANT n=rNumber # instrConstant + | op=OPCODE_WRITE n=rNumber # instrRegister + | op=OPCODE_LOAD OP_CONSTANT n=rNumber # instrConstant + | op=OPCODE_LOAD n=rNumber # instrRegister + | op=OPCODE_STORE n=rNumber # instrRegister + | op=OPCODE_ADD OP_CONSTANT n=rNumber # instrConstant + | op=OPCODE_ADD n=rNumber # instrRegister + | op=OPCODE_SUB OP_CONSTANT n=rNumber # instrConstant + | op=OPCODE_SUB n=rNumber # instrRegister + | op=OPCODE_MUL OP_CONSTANT n=rNumber # instrConstant + | op=OPCODE_MUL n=rNumber # instrRegister + | op=OPCODE_DIV OP_CONSTANT n=rNumber # instrConstant + | op=OPCODE_DIV n=rNumber # instrRegister + | op=OPCODE_JMP id=ID_IDENTIFIER # instrJump + | op=OPCODE_JZ id=ID_IDENTIFIER # instrJump + | op=OPCODE_JGTZ id=ID_IDENTIFIER # instrJump + | op=OPCODE_HALT # instrNoOperand + ; + +rInput: PREP_INPUT rNumber+; + +rOrg: PREP_ORG n=rNumber; + +rNumber: + n=LIT_HEXNUMBER_1 + | n=LIT_NUMBER + | n=LIT_HEXNUMBER_2 + | n=LIT_OCTNUMBER + | n=LIT_BINNUMBER + ; diff --git a/plugins/compiler/raspc-rasp/src/main/cup/parser.cup b/plugins/compiler/raspc-rasp/src/main/cup/parser.cup deleted file mode 100644 index 51c5a07d9..000000000 --- a/plugins/compiler/raspc-rasp/src/main/cup/parser.cup +++ /dev/null @@ -1,159 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2016-2017 Michal Šipoš - * Copyright (C) 2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.compiler.raspc; - -import java_cup.runtime.DefaultSymbolFactory; -import net.emustudio.emulib.plugins.compiler.CompilerMessage; -import net.emustudio.emulib.plugins.compiler.Token; -import net.emustudio.plugins.compiler.raspc.tree.*; -import net.emustudio.plugins.memory.rasp.InstructionImpl; -import net.emustudio.plugins.memory.rasp.api.RASPInstruction; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -parser code{: - private CompilerImpl compiler; - private boolean syntaxErrors; - - public ParserImpl(LexerImpl lexer, CompilerImpl compiler) { - super(lexer, new DefaultSymbolFactory()); - this.compiler = Objects.requireNonNull(compiler); - } - - public void reset() { - syntaxErrors = false; - } - - @Override - public void report_fatal_error(String message, Object info) throws Exception { - done_parsing(); - report_error(message, info); - throw new Exception("Can't recover from previous error(s)"); - } - - @Override - public void report_error(String messageText, Object current) { - syntaxErrors = true; - - Token token = (Token)current; - - messageText += ":" + token.getErrorString() + " ('" + token.getText() + "')"; - - List expectedTokenIds = expected_token_ids() - .stream() - .map(this::symbl_name_from_id) - .collect(Collectors.toList()); - - if (!expectedTokenIds.isEmpty()) { - messageText += "\nExpected tokens: " + expectedTokenIds; - } - - CompilerMessage message = new CompilerMessage( - CompilerMessage.MessageType.TYPE_ERROR, messageText, token.getLine()+1, token.getColumn() - ); - - compiler.notifyOnMessage(message); - } - - public boolean hasSyntaxErrors() { - return syntaxErrors; - } -:}; - -terminal READ, WRITE, LOAD, STORE, ADD, SUB, MUL, DIV, JMP, JZ, JGTZ, HALT, ORG, SEPARATOR_EOL, TCOMMENT, OPERATOR_CONSTANT; -terminal Integer NUMBER; -terminal String TLABEL, IDENT; -terminal TINPUT; - -non terminal SourceCode SourceCode; -non terminal Program Program; -non terminal Row Row; -non terminal Label Label; -non terminal Comment; -non terminal Statement Statement; -non terminal InstructionImpl Instruction; -non terminal InstructionImpl JumpInstruction; -non terminal Input Input; - - -start with SourceCode; - -SourceCode ::= Program:p {: RESULT = new SourceCode(p); :} - ; - -Program ::= Row:row - {: - Program program = new Program(); - if (row != null) program.addRow(row); - RESULT = program; - :} - | Program:program SEPARATOR_EOL Row:row - {: - if (row != null) program.addRow(row); - RESULT = program; - :} - ; - - -Row ::= Label:l Statement:s Comment {: RESULT = new Row( l, null, -1, s); :} - | Label:l Comment {: RESULT = new Row( l, null, -1, null); :} - | ORG NUMBER:n Comment {: RESULT = new Row(null, null, n, null); :} - | TINPUT Input:i Comment {: RESULT = new Row(null, i, -1, null); :} - ; - - -Label ::= TLABEL:l {: RESULT = new Label(l); :} - | {: RESULT = null; :} - ; - -Statement ::= Instruction:i NUMBER:operand {: RESULT = new Statement(i,operand); :} - | JumpInstruction:i IDENT:label {: RESULT = new Statement(i,label); :} - | HALT {: RESULT = new Statement(new InstructionImpl(RASPInstruction.HALT), 0); :} - ; - -Input ::= Input:i NUMBER:n {: i.addNumber(n); RESULT = i; :} - | NUMBER:n {: RESULT = new Input(n); :} - ; - -Comment ::= TCOMMENT | /*no comment*/; /*no action - ignore the comment*/ - -Instruction ::= - READ {: RESULT = new InstructionImpl(RASPInstruction.READ); :} - | WRITE OPERATOR_CONSTANT {: RESULT = new InstructionImpl(RASPInstruction.WRITE_CONSTANT); :} - | WRITE {: RESULT = new InstructionImpl(RASPInstruction.WRITE_REGISTER); :} - | LOAD OPERATOR_CONSTANT {: RESULT = new InstructionImpl(RASPInstruction.LOAD_CONSTANT); :} - | LOAD {: RESULT = new InstructionImpl(RASPInstruction.LOAD_REGISTER); :} - | STORE {: RESULT = new InstructionImpl(RASPInstruction.STORE); :} - | ADD OPERATOR_CONSTANT {: RESULT = new InstructionImpl(RASPInstruction.ADD_CONSTANT); :} - | ADD {: RESULT = new InstructionImpl(RASPInstruction.ADD_REGISTER); :} - | SUB OPERATOR_CONSTANT {: RESULT = new InstructionImpl(RASPInstruction.SUB_CONSTANT); :} - | SUB {: RESULT = new InstructionImpl(RASPInstruction.SUB_REGISTER); :} - | MUL OPERATOR_CONSTANT {: RESULT = new InstructionImpl(RASPInstruction.MUL_CONSTANT); :} - | MUL {: RESULT = new InstructionImpl(RASPInstruction.MUL_REGISTER); :} - | DIV OPERATOR_CONSTANT {: RESULT = new InstructionImpl(RASPInstruction.DIV_CONSTANT); :} - | DIV {: RESULT = new InstructionImpl(RASPInstruction.DIV_REGISTER); :} - ; - -JumpInstruction ::= JMP {: RESULT = new InstructionImpl(RASPInstruction.JMP); :} - | JZ {: RESULT = new InstructionImpl(RASPInstruction.JZ); :} - | JGTZ {: RESULT = new InstructionImpl(RASPInstruction.JGTZ); :} - ; diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java new file mode 100644 index 000000000..ccdf1d5a2 --- /dev/null +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java @@ -0,0 +1,177 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2016-2017 Michal Šipoš + * Copyright (C) 2020 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.compiler.rasp; + +import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; +import net.emustudio.emulib.plugins.annotations.PluginRoot; +import net.emustudio.emulib.plugins.compiler.AbstractCompiler; +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; +import net.emustudio.emulib.plugins.compiler.SourceFileExtension; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.ContextNotFoundException; +import net.emustudio.emulib.runtime.InvalidContextException; +import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.plugins.compiler.rasp.ast.Program; +import net.emustudio.plugins.memory.rasp.api.RASPMemoryCell; +import net.emustudio.plugins.memory.rasp.api.RASPMemoryContext; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.TokenStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileReader; +import java.io.Reader; +import java.util.*; + +@PluginRoot( + type = PLUGIN_TYPE.COMPILER, + title = "RASP Machine Assembler" +) +public class CompilerRASP extends AbstractCompiler { + private final static Logger LOGGER = LoggerFactory.getLogger(CompilerRASP.class); + private static final List SOURCE_FILE_EXTENSIONS = List.of( + new SourceFileExtension("rasp", "RASP source file") + ); + + private RASPMemoryContext memory; + private int programLocation; + + public CompilerRASP(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { + super(pluginID, applicationApi, settings); + } + + @Override + public void initialize() { + Optional.ofNullable(applicationApi.getContextPool()).ifPresent(pool -> { + try { + memory = pool.getMemoryContext(pluginID, RASPMemoryContext.class); + } catch (InvalidContextException | ContextNotFoundException e) { + LOGGER.warn("Memory is not available", e); + } + }); + } + + @Override + public boolean compile(String inputFileName, String outputFileName) { + try { + this.notifyCompileStart(); + notifyInfo(getTitle() + ", version " + getVersion()); + + try (Reader reader = new FileReader(inputFileName)) { + org.antlr.v4.runtime.Lexer lexer = createLexer(CharStreams.fromReader(reader)); + lexer.addErrorListener(new ParserErrorListener()); + CommonTokenStream tokens = new CommonTokenStream(lexer); + + RASPParser parser = createParser(tokens); + parser.addErrorListener(new ParserErrorListener()); + + Program program = new Program(); + new ProgramParser(program).visit(parser.rStart()); + + Map compiled = program.compile(); + this.programLocation = program.getProgramLocation(compiled); + program.saveToFile(outputFileName, compiled); + + notifyInfo(String.format("Compile was successful.\n\tOutput: %s", outputFileName)); + + if (memory != null) { + memory.clear(); + program.loadIntoMemory(memory, compiled); + notifyInfo("Compiled file was loaded into program memory."); + } else { + notifyWarning("Memory is not available"); + } + } + + } catch (Exception e) { + LOGGER.trace("Compilation failed", e); + notifyError("Compilation failed: " + e.getMessage()); + return false; + } finally { + notifyCompileFinish(); + } + return true; + } + + @Override + public boolean compile(String inputFileName) { + int i = inputFileName.toLowerCase(Locale.ENGLISH).lastIndexOf(".rasp"); + + String outputFileName = inputFileName; + if (i >= 0) { + outputFileName = outputFileName.substring(0, i); + } + outputFileName += ".brasp"; + return compile(inputFileName, outputFileName); + } + + @Override + public LexicalAnalyzer createLexer(String s) { + RASPLexer lexer = createLexer(CharStreams.fromString(s)); + return new LexicalAnalyzerImpl(lexer); + } + + @Override + public int getProgramLocation() { + return programLocation; + } + + @Override + public List getSourceFileExtensions() { + return SOURCE_FILE_EXTENSIONS; + } + + @Override + public String getVersion() { + return getResourceBundle().map(b -> b.getString("version")).orElse("(unknown)"); + } + + @Override + public String getCopyright() { + return getResourceBundle().map(b -> b.getString("copyright")).orElse("(unknown)"); + } + + @Override + public String getDescription() { + return "RASP machine assembler"; + } + + private Optional getResourceBundle() { + try { + return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.compiler.rasp.version")); + } catch (MissingResourceException e) { + return Optional.empty(); + } + } + + private RASPLexer createLexer(CharStream input) { + RASPLexer lexer = new RASPLexer(input); + lexer.removeErrorListeners(); + return lexer; + } + + private RASPParser createParser(TokenStream tokenStream) { + RASPParser parser = new RASPParser(tokenStream); + parser.removeErrorListeners(); + return parser; + } +} diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/LexicalAnalyzerImpl.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/LexicalAnalyzerImpl.java new file mode 100644 index 000000000..b392b87f4 --- /dev/null +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/LexicalAnalyzerImpl.java @@ -0,0 +1,95 @@ +package net.emustudio.plugins.compiler.rasp; + +import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; +import net.emustudio.emulib.plugins.compiler.Token; +import org.antlr.v4.runtime.CharStreams; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Objects; + +import static net.emustudio.plugins.compiler.rasp.RASPParser.*; +import static org.antlr.v4.runtime.Recognizer.EOF; + +public class LexicalAnalyzerImpl implements LexicalAnalyzer { + private final RASPLexer lexer; + private static final int[] tokenMap = new int[ERROR + 1]; + + static { + tokenMap[COMMENT] = Token.COMMENT; + tokenMap[COMMENT2] = Token.COMMENT; + tokenMap[EOL] = Token.WHITESPACE; + tokenMap[WS] = Token.WHITESPACE; + tokenMap[OPCODE_READ] = Token.RESERVED; + tokenMap[OPCODE_WRITE] = Token.RESERVED; + tokenMap[OPCODE_LOAD] = Token.RESERVED; + tokenMap[OPCODE_STORE] = Token.RESERVED; + tokenMap[OPCODE_ADD] = Token.RESERVED; + tokenMap[OPCODE_HALT] = Token.RESERVED; + tokenMap[OPCODE_DIV] = Token.RESERVED; + tokenMap[OPCODE_MUL] = Token.RESERVED; + tokenMap[OPCODE_SUB] = Token.RESERVED; + tokenMap[OPCODE_JMP] = Token.RESERVED; + tokenMap[OPCODE_JGTZ] = Token.RESERVED; + tokenMap[OPCODE_JZ] = Token.RESERVED; + + tokenMap[PREP_ORG] = Token.PREPROCESSOR; + tokenMap[PREP_INPUT] = Token.PREPROCESSOR; + + tokenMap[OP_CONSTANT] = Token.OPERATOR; + + tokenMap[LIT_NUMBER] = Token.LITERAL; + tokenMap[LIT_HEXNUMBER_1] = Token.LITERAL; + tokenMap[LIT_HEXNUMBER_2] = Token.LITERAL; + tokenMap[LIT_OCTNUMBER] = Token.LITERAL; + tokenMap[LIT_BINNUMBER] = Token.LITERAL; + + tokenMap[ID_IDENTIFIER] = Token.IDENTIFIER; + tokenMap[ID_LABEL] = Token.IDENTIFIER; + + tokenMap[ERROR] = Token.ERROR; + } + + + public LexicalAnalyzerImpl(RASPLexer lexer) { + this.lexer = Objects.requireNonNull(lexer); + } + + @Override + public Token nextToken() { + org.antlr.v4.runtime.Token token = lexer.nextToken(); + return new Token() { + @Override + public int getType() { + return convertLexerTokenType(token.getType()); + } + + @Override + public int getOffset() { + return token.getStartIndex(); + } + + @Override + public String getText() { + return token.getText(); + } + }; + } + + @Override + public boolean isAtEOF() { + return lexer._hitEOF; + } + + @Override + public void reset(InputStream inputStream) throws IOException { + lexer.setInputStream(CharStreams.fromStream(inputStream)); + } + + private int convertLexerTokenType(int tokenType) { + if (tokenType == EOF) { + return Token.EOF; + } + return tokenMap[tokenType]; + } +} diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParserErrorListener.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParserErrorListener.java new file mode 100644 index 000000000..d2da2d882 --- /dev/null +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParserErrorListener.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.compiler.rasp; + +import net.emustudio.plugins.compiler.rasp.exceptions.SyntaxErrorException; +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; + +public class ParserErrorListener extends BaseErrorListener { + + @Override + public void syntaxError( + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { + + if (e == null) { + throw new SyntaxErrorException(line, charPositionInLine, msg); + } else { + throw new SyntaxErrorException(line, charPositionInLine, msg, e); + } + } +} diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParsingUtils.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParsingUtils.java new file mode 100644 index 000000000..66d3e4c3c --- /dev/null +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParsingUtils.java @@ -0,0 +1,50 @@ +package net.emustudio.plugins.compiler.rasp; + +import org.antlr.v4.runtime.Token; + +import java.util.Locale; + +public class ParsingUtils { + + public static int parseLitHex1(Token token) { + // LIT_HEXNUMBER_1: [\-]? '0' X [0-9a-fA-F]+; + return Integer.decode(token.getText()); + } + + public static int parseLitHex2(Token token) { + // LIT_HEXNUMBER_2: [\-]? [0-9a-fA-F]+ H; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 16); + } + + public static int parseLitOct(Token token) { + // LIT_OCTNUMBER: [\-]? [0-7]+ [oOqQ]; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 8); + } + + public static int parseLitDec(Token token) { + // LIT_NUMBER: [\-]? [0-9]+ D? + String rawText = token.getText(); + if (rawText.endsWith("d") || rawText.endsWith("D")) { + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 10); + } else { + return Integer.parseInt(rawText, 10); + } + } + + public static int parseLitBin(Token token) { + // LIT_BINNUMBER: [01]+ B; + String rawText = token.getText(); + return Integer.parseInt(rawText.substring(0, rawText.length() - 1), 2); + } + + public static String parseLabel(Token token) { + String rawText = token.getText(); + return rawText.substring(0, rawText.length() - 1); + } + + public static String normalizeId(String id) { + return id.toLowerCase(Locale.ENGLISH); + } +} diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ProgramParser.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ProgramParser.java new file mode 100644 index 000000000..145f35d74 --- /dev/null +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ProgramParser.java @@ -0,0 +1,151 @@ +package net.emustudio.plugins.compiler.rasp; + +import net.emustudio.plugins.compiler.rasp.ast.Instruction; +import net.emustudio.plugins.compiler.rasp.ast.Label; +import net.emustudio.plugins.compiler.rasp.ast.Program; +import org.antlr.v4.runtime.Token; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import static net.emustudio.plugins.compiler.rasp.ParsingUtils.*; +import static net.emustudio.plugins.compiler.rasp.RASPParser.*; + + +public class ProgramParser extends RASPParserBaseVisitor { + private final static Map registerOps = new HashMap<>(); + private final static Map constantOps = new HashMap<>(); + private final static Map jumpOps = new HashMap<>(); + + static { + registerOps.put(OPCODE_READ, 1); + registerOps.put(OPCODE_WRITE, 3); + registerOps.put(OPCODE_LOAD, 5); + registerOps.put(OPCODE_STORE, 6); + registerOps.put(OPCODE_ADD, 8); + registerOps.put(OPCODE_SUB, 10); + registerOps.put(OPCODE_MUL, 12); + registerOps.put(OPCODE_DIV, 14); + + constantOps.put(OPCODE_WRITE, 2); + constantOps.put(OPCODE_LOAD, 4); + constantOps.put(OPCODE_ADD, 7); + constantOps.put(OPCODE_SUB, 9); + constantOps.put(OPCODE_MUL, 11); + constantOps.put(OPCODE_DIV, 13); + + jumpOps.put(OPCODE_JMP, 15); + jumpOps.put(OPCODE_JZ, 16); + jumpOps.put(OPCODE_JGTZ, 17); + } + + private final Program program; + private int currentAddress; + + public ProgramParser(Program program) { + this.program = Objects.requireNonNull(program); + } + + public Program getProgram() { + return program; + } + + @Override + public Program visitRLine(RASPParser.RLineContext ctx) { + if (ctx.label != null) { + Token token = ctx.label; + Label label = new Label(token.getLine(), token.getCharPositionInLine(), parseLabel(token), currentAddress); + program.add(label); + } + if (ctx.statement != null) { + visitRStatement(ctx.statement); + } + return program; + } + + @Override + public Program visitROrg(ROrgContext ctx) { + this.currentAddress = parseNumber(ctx.n.n); + return program; + } + + @Override + public Program visitInstrRegister(InstrRegisterContext ctx) { + Token op = ctx.op; + int opcode = registerOps.get(op.getType()); + int operand = parseNumber(ctx.n.n); + + Instruction instruction = new Instruction( + op.getLine(), op.getCharPositionInLine(), opcode, currentAddress++, Optional.of(operand) + ); + currentAddress++; // operand + program.add(instruction); + return program; + } + + @Override + public Program visitInstrConstant(InstrConstantContext ctx) { + Token op = ctx.op; + int opcode = constantOps.get(op.getType()); + int operand = parseNumber(ctx.n.n); + + Instruction instruction = new Instruction( + op.getLine(), op.getCharPositionInLine(), opcode, currentAddress++, Optional.of(operand) + ); + currentAddress++; // operand + program.add(instruction); + return program; + } + + @Override + public Program visitInstrJump(InstrJumpContext ctx) { + Token op = ctx.op; + int opcode = jumpOps.get(op.getType()); + String id = ctx.id.getText(); + + Instruction instruction = new Instruction( + op.getLine(), op.getCharPositionInLine(), opcode, currentAddress++, id + ); + currentAddress++; // operand + program.add(instruction); + return program; + } + + @Override + public Program visitInstrNoOperand(InstrNoOperandContext ctx) { + Instruction instruction = new Instruction( + ctx.op.getLine(), ctx.op.getCharPositionInLine(), 18, currentAddress++, Optional.empty() + ); + program.add(instruction); + return program; + } + + + @Override + public Program visitRInput(RASPParser.RInputContext ctx) { + for (RNumberContext n : ctx.rNumber()) { + if (n.n != null) { + program.add(parseNumber(n.n)); + } + } + return program; + } + + public int parseNumber(Token number) { + switch (number.getType()) { + case LIT_BINNUMBER: + return parseLitBin(number); + case LIT_HEXNUMBER_1: + return parseLitHex1(number); + case LIT_HEXNUMBER_2: + return parseLitHex2(number); + case LIT_NUMBER: + return parseLitDec(number); + case LIT_OCTNUMBER: + return parseLitOct(number); + } + throw new IllegalStateException("unexpected number token type: " + number.getType()); + } +} diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/Runner.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/Runner.java similarity index 93% rename from plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/Runner.java rename to plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/Runner.java index 3cfee14e1..f5628b03c 100644 --- a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/raspc/Runner.java +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/Runner.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.compiler.raspc; +package net.emustudio.plugins.compiler.rasp; import net.emustudio.emulib.plugins.compiler.CompilerListener; import net.emustudio.emulib.plugins.compiler.CompilerMessage; @@ -39,7 +39,7 @@ public static void main(String... args) { printHelp(); return; } else if (arg.equals("--version") || arg.equals("-v")) { - System.out.println(new CompilerImpl(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE).getVersion()); + System.out.println(new CompilerRASP(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE).getVersion()); return; } else { break; @@ -57,10 +57,10 @@ public static void main(String... args) { } else { outputFile = inputFile; } - outputFile += ".hex"; + outputFile += ".brasp"; } - CompilerImpl compiler = new CompilerImpl(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE); + CompilerRASP compiler = new CompilerRASP(0L, ApplicationApi.UNAVAILABLE, PluginSettings.UNAVAILABLE); compiler.addCompilerListener(new CompilerListener() { @Override diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Instruction.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Instruction.java new file mode 100644 index 000000000..8ec23469b --- /dev/null +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Instruction.java @@ -0,0 +1,62 @@ +package net.emustudio.plugins.compiler.rasp.ast; + +import java.util.Objects; +import java.util.Optional; + +public class Instruction { + public final int line; + public final int column; + + public final int address; + public final int opcode; + public final Optional operand; + public final Optional id; + + public Instruction(int line, int column, int opcode, int address, Optional operand) { + this.opcode = opcode; + this.address = address; + this.operand = Objects.requireNonNull(operand); + this.id = Optional.empty(); + this.line = line; + this.column = column; + } + + public Instruction(int line, int column, int opcode, int address, String id) { + this.opcode = opcode; + this.address = address; + this.operand = Optional.empty(); + this.id = Optional.of(id); + this.line = line; + this.column = column; + } + + public Instruction(int opcode, int address, Optional operand) { + this(0, 0, opcode, address, operand); + } + + public Instruction(int opcode, int address, String id) { + this(0, 0, opcode, address, id); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Instruction that = (Instruction) o; + return address == that.address && opcode == that.opcode && operand.equals(that.operand); + } + + @Override + public int hashCode() { + return Objects.hash(address, opcode, operand); + } + + @Override + public String toString() { + return "Instruction{" + + "address=" + address + + ", opcode=" + opcode + + ", operand=" + operand + + '}'; + } +} diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java new file mode 100644 index 000000000..823b0754c --- /dev/null +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java @@ -0,0 +1,54 @@ +package net.emustudio.plugins.compiler.rasp.ast; + +import net.emustudio.plugins.memory.rasp.api.RASPLabel; + +public class Label implements RASPLabel { + public final int line; + public final int column; + + private final String label; + private final int address; + + public Label(int line, int column, String text, int address) { + this.line = line; + this.column = column; + this.label = text.toUpperCase(); + this.address = address; + } + + @Override + public String getLabel() { + return label; + } + + @Override + public int getAddress() { + return address; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Label label1 = (Label) o; + + if (address != label1.address) return false; + return label.equals(label1.label); + } + + @Override + public int hashCode() { + int result = label.hashCode(); + result = 31 * result + address; + return result; + } + + @Override + public String toString() { + return "{" + + "label='" + label + '\'' + + ", address=" + address + + '}'; + } +} diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Program.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Program.java new file mode 100644 index 000000000..298f9ae22 --- /dev/null +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Program.java @@ -0,0 +1,126 @@ +package net.emustudio.plugins.compiler.rasp.ast; + +import net.emustudio.plugins.compiler.rasp.ParsingUtils; +import net.emustudio.plugins.compiler.rasp.exceptions.CompileException; +import net.emustudio.plugins.memory.rasp.api.RASPMemoryCell; +import net.emustudio.plugins.memory.rasp.api.RASPMemoryContext; + +import java.io.*; +import java.util.*; + +public class Program { + private final List instructions = new ArrayList<>(); + private final Map labels = new HashMap<>(); + private final List inputs = new ArrayList<>(); + + public void add(Instruction instruction) { + this.instructions.add(instruction); + } + + public void add(Label label) { + String labelNorm = ParsingUtils.normalizeId(label.getLabel()); + if (labels.containsKey(labelNorm)) { + throw new CompileException(label.line, label.column, "Label is already defined!"); + } + this.labels.put(labelNorm, label); + } + + public void add(int input) { + this.inputs.add(input); + } + + public Map compile() { + Map compiled = new HashMap<>(); + + for (Instruction instruction : instructions) { + RASPMemoryCell instrCell = new RASPMemoryCellImpl(true, instruction.opcode, instruction.address); + compiled.put(instrCell.getAddress(), instrCell); + instruction.operand.ifPresent(o -> { + RASPMemoryCell cell = new RASPMemoryCellImpl(false, o, instruction.address + 1); + compiled.put(cell.getAddress(), cell); + }); + instruction.id.ifPresent(id -> { + Optional

- * The tape position can move to the left, or to the right. - *

- * The CPU must assign all the details to this tape using the tape context. - *

- * By default, the tape is unbounded. However, it is possible to change. - */ public class AbstractTapeContextImpl implements AbstractTapeContext { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTapeContextImpl.class); private final AtomicReference symbolLog = new AtomicReference<>(); private final Map content = new HashMap<>(); + private final Set acceptedTypes = new HashSet<>(Set.of( + TapeSymbol.Type.NUMBER, TapeSymbol.Type.STRING + )); + private final ReadWriteLock rwl = new ReentrantReadWriteLock(); private final AbstractTape tape; @@ -70,6 +65,24 @@ public interface TapeListener extends EventListener { highlightCurrentPosition = true; } + @Override + public void setAcceptTypes(TapeSymbol.Type... types) { + writeSynchronized(() -> { + acceptedTypes.clear(); + acceptedTypes.addAll(Arrays.asList(types)); + }); + } + + @Override + public Set getAcceptedTypes() { + rwl.readLock().lock(); + try { + return Collections.unmodifiableSet(acceptedTypes); + } finally { + rwl.readLock().unlock(); + } + } + @Override public void setTitle(String title) { tape.setGUITitle(title); @@ -139,11 +152,20 @@ public void moveRight() { fireChange(); } + /** + * Adds symbol to the beginning of this tape. + * + * @param symbol tape symbol + * @throws IllegalArgumentException if the symbol type is not among accepted ones + */ public void addFirst(TapeSymbol symbol) { if (leftBounded) { return; } writeSynchronized(() -> { + if (!acceptedTypes.contains(symbol.type)) { + throw new IllegalArgumentException("Tape symbol type is not accepted"); + } incrementContentPositions(); content.put(0, symbol); logSymbol(0, symbol); @@ -152,8 +174,18 @@ public void addFirst(TapeSymbol symbol) { fireChange(); } + /** + * Adds symbol at the end of this tape. + * The "end" is computed as the highest position + 1. + * + * @param symbol tape symbol + * @throws IllegalArgumentException if the symbol type is not among accepted ones + */ public void addLast(TapeSymbol symbol) { writeSynchronized(() -> { + if (!acceptedTypes.contains(symbol.type)) { + throw new IllegalArgumentException("Tape symbol type is not accepted"); + } int index = position; if (!content.isEmpty()) { index = Collections.max(content.keySet()) + 1; @@ -201,6 +233,9 @@ public void setSymbolAt(int position, TapeSymbol symbol) { return; } writeSynchronized(() -> { + if (!acceptedTypes.contains(symbol.type)) { + throw new IllegalArgumentException("Tape symbol type is not accepted"); + } content.put(position, symbol); logSymbol(position, symbol); }); diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java index accb07e01..383ec9422 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java @@ -21,12 +21,16 @@ import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.device.DeviceContext; -import java.util.List; import java.util.Optional; import java.util.Set; /** * Public API of the abstract tape. + *

+ * The tape head can move to the left, or to the right. If a tape is left-bounded, it cannot move to the left + * beyond the first symbol. + *

+ * A CPU must setup the tape. */ @SuppressWarnings("unused") @PluginContext @@ -37,6 +41,23 @@ public interface AbstractTapeContext extends DeviceContext { */ void clear(); + /** + * Accept only specific tape symbol types. + *

+ * If the tape encounters symbol of unsupported type, it will throw on reading. Unsupported inputs provided by user + * will be disallowed. + * + * @param types accepted types + */ + void setAcceptTypes(TapeSymbol.Type... types); + + /** + * Gets accepted tape symbol types. + * + * @return accepted tape symbol types + */ + Set getAcceptedTypes(); + /** * Set this tape to left-bounded or unbounded. * @@ -87,11 +108,12 @@ public interface AbstractTapeContext extends DeviceContext { /** * Set symbol at the specified position. - * + *

* If the position is < 0, then no symbol will be set. * * @param position position in the tape, starting from 0 * @param symbol symbol value + * @throws IllegalArgumentException if the symbol type is not among accepted ones */ void setSymbolAt(int position, TapeSymbol symbol); @@ -158,4 +180,9 @@ public interface AbstractTapeContext extends DeviceContext { */ boolean isEmpty(); + /** + * {@inheritDoc} + * @throws IllegalArgumentException if the symbol type is not among accepted ones + */ + void writeData(TapeSymbol value); } diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java index e9ee7d737..221e5ab6c 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java @@ -91,13 +91,25 @@ private void initComponents() { btnAddFirst.addActionListener(e -> dialogs .readString("Symbol value:", "Add symbol (on top)") .map(TapeSymbol::guess) - .ifPresent(tapeContext::addFirst)); + .ifPresent(s -> { + try { + tapeContext.addFirst(s); + } catch (IllegalArgumentException ignored) { + dialogs.showError("Unexpected symbol type. Supported types: " + tapeContext.getAcceptedTypes()); + } + })); btnAddLast.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/device/abstracttape/gui/go-down.png"))); btnAddLast.addActionListener(e -> dialogs .readString("Symbol value:", "Add symbol (on bottom)") .map(TapeSymbol::guess) - .ifPresent(tapeContext::addLast)); + .ifPresent(s -> { + try { + tapeContext.addLast(s); + } catch (IllegalArgumentException ignored) { + dialogs.showError("Unexpected symbol type. Supported types: " + tapeContext.getAcceptedTypes()); + } + })); btnEdit.addActionListener(e -> { int symbolIndex = lstTape.getSelectedIndex(); diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/InstructionImpl.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/InstructionImpl.java deleted file mode 100644 index 07f070bdc..000000000 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/InstructionImpl.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2016-2017 Michal Šipoš - * Copyright (C) 2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.emustudio.plugins.memory.rasp; - -import net.emustudio.plugins.memory.rasp.api.RASPInstruction; - -import java.util.Objects; - -public class InstructionImpl implements RASPInstruction { - - /** - * machine code of the instruction - */ - private final int instructionCode; - - public InstructionImpl(int instructionCode) { - this.instructionCode = instructionCode; - } - - @Override - public int getCode() { - return instructionCode; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - InstructionImpl that = (InstructionImpl) o; - return instructionCode == that.instructionCode; - } - - @Override - public int hashCode() { - return Objects.hash(instructionCode); - } - - @Override - public String getCodeStr() { - switch (instructionCode) { - case READ: - return "READ"; - case WRITE_CONSTANT: - return "WRITE ="; - case WRITE_REGISTER: - return "WRITE"; - case LOAD_CONSTANT: - return "LOAD ="; - case LOAD_REGISTER: - return "LOAD"; - case STORE: - return "STORE"; - case ADD_CONSTANT: - return "ADD ="; - case ADD_REGISTER: - return "ADD"; - case SUB_CONSTANT: - return "SUB ="; - case SUB_REGISTER: - return "SUB"; - case MUL_CONSTANT: - return "MUL ="; - case MUL_REGISTER: - return "MUL"; - case DIV_CONSTANT: - return "DIV ="; - case DIV_REGISTER: - return "DIV"; - case JMP: - return "JMP"; - case JZ: - return "JZ"; - case JGTZ: - return "JGTZ"; - case HALT: - return "HALT"; - } - return "unknown"; - } - - @Override - public String toString() { - return getCodeStr(); - } - -} diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryContextImpl.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryContextImpl.java index 2241c443a..301fbe872 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryContextImpl.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryContextImpl.java @@ -21,178 +21,163 @@ package net.emustudio.plugins.memory.rasp; import net.emustudio.emulib.plugins.memory.AbstractMemoryContext; -import net.emustudio.plugins.memory.rasp.api.MemoryItem; -import net.emustudio.plugins.memory.rasp.api.RASPInstruction; -import net.emustudio.plugins.memory.rasp.api.RASPMemoryContext; - -import java.io.BufferedInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.ObjectInputStream; +import net.emustudio.plugins.memory.rasp.api.*; + +import java.io.*; import java.util.*; -public class MemoryContextImpl extends AbstractMemoryContext implements RASPMemoryContext { +public class MemoryContextImpl extends AbstractMemoryContext implements RASPMemoryContext { + private final static class EmptyCell implements RASPMemoryCell { + private final int address; - private final List memory = new ArrayList<>(); - private int programLocation; - private final List inputs = new ArrayList<>(); + private EmptyCell(int address) { + this.address = address; + } - private final Map labels = new HashMap<>(); + @Override + public boolean isInstruction() { + return false; + } - /** - * Reads memory item from given address. - * - * @param position the memory address - * @return the item at the given address - */ - @Override - public MemoryItem read(int position) { - if (position >= 0 && position < getSize()) { - return memory.get(position); - } else { - return null; + @Override + public int getAddress() { + return address; } - } - /** - * Write a memory item to the given address. - * - * @param position the memory address - * @param item the item to write - */ - @Override - public void write(int position, MemoryItem item) { - if (position >= memory.size()) { - //padd with nulls to prevent IndexOutOfBoundsException - for (int i = memory.size(); i < position; i++) { - memory.add(i, new NumberMemoryItem(0)); - } - memory.add(position, item); - notifyMemoryChanged(memory.size()); - notifyMemorySizeChanged(); - } else { - //if there is an instruction at "position", modify its opcode - MemoryItem currentValue = read(position); - if (currentValue instanceof RASPInstruction) { - int number = ((NumberMemoryItem) item).getValue(); - memory.set(position, new InstructionImpl(number)); - } //if there is not an instruction, i.e. its a NumberMemoryItem or null - else { - memory.set(position, item); - } + @Override + public int getValue() { + return 0; } - notifyMemoryChanged(position); - } - @Override - public MemoryItem[] readWord(int i) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + static EmptyCell at(int address) { + return new EmptyCell(address); + } } - @Override - public void writeWord(int i, MemoryItem[] cts) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } + private final Map memory = new HashMap<>(); + private final Map labels = new HashMap<>(); + private final List inputs = new ArrayList<>(); - @Override - public Class getDataType() { - return MemoryItem.class; - } + private int programLocation; - /** - * Clears memory as well as labels. - */ @Override public void clear() { - inputs.clear(); memory.clear(); labels.clear(); + inputs.clear(); notifyMemoryChanged(-1); notifyMemorySizeChanged(); } + public void clearInputs() { + inputs.clear(); + } + @Override public int getSize() { - return memory.size(); + return memory.keySet().stream().max(Comparator.naturalOrder()).orElse(0); } @Override - public void addLabel(int pos, String label) { - labels.put(pos, label); + public RASPMemoryCell read(int address) { + RASPMemoryCell cell = memory.get(address); + return (cell == null) ? EmptyCell.at(address) : cell; } @Override - public String getLabel(int pos) { - return labels.get(pos); + public RASPMemoryCell[] read(int address, int count) { + List copy = new ArrayList<>(); + for (int i = address; i < address + count; i++) { + RASPMemoryCell cell = memory.get(i); + copy.add((cell == null) ? EmptyCell.at(address) : cell); + } + return copy.toArray(new RASPMemoryCell[0]); } @Override - public String addressToLabelString(int address) { - String label = getLabel(address); - if (label != null) { - int index = label.lastIndexOf(':'); - label = label.substring(0, index); - return label.toLowerCase(); - } else { - //if no label at the address, simply return the number - return String.valueOf(address); + public void write(int address, RASPMemoryCell value) { + boolean sizeChanged = !memory.containsKey(address); + memory.put(address, value); + if (sizeChanged) { + notifyMemorySizeChanged(); } + notifyMemoryChanged(address); } @Override - public void addInputs(List inputs) { - Objects.requireNonNull(inputs, "inputs cannot be null"); + public void write(int address, RASPMemoryCell[] values, int count) { + for (int i = 0; i < count; i++) { + boolean sizeChanged = !memory.containsKey(address); + memory.put(address + i, values[i]); + if (sizeChanged) { + notifyMemorySizeChanged(); + } + notifyMemoryChanged(address + i); + } + } + + @Override + public Class getDataType() { + return RASPMemoryCell.class; + } + + @Override + public synchronized void setLabels(List labels) { + this.labels.clear(); + for (RASPLabel label: labels) { + this.labels.put(label.getAddress(), label); + } + } + + @Override + public Optional getLabel(int address) { + return Optional.ofNullable(labels.get(address)); + } + + @Override + public synchronized void setInputs(List inputs) { + clearInputs(); this.inputs.addAll(inputs); } @Override public List getInputs() { - return inputs; + return Collections.unmodifiableList(inputs); } - /** - * Destroys the memory content. - */ - public void destroy() { - memory.clear(); + public void setProgramLocation(int location) { + this.programLocation = location; } public int getProgramLocation() { return programLocation; } - @Override - public void setProgramLocation(Integer programLocation) { - this.programLocation = Optional.ofNullable(programLocation).orElse(0); - } - public void loadFromFile(String filename) throws IOException, ClassNotFoundException { + @SuppressWarnings("unchecked") + public void deserialize(String filename) throws IOException, ClassNotFoundException { try { - FileInputStream fileInputStream = new FileInputStream(filename); - BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); - try (ObjectInputStream objectInputStream = new ObjectInputStream(bufferedInputStream)) { - //clear labels and memory before loading - labels.clear(); - memory.clear(); - inputs.clear(); - - labels.putAll((Map) objectInputStream.readObject()); - programLocation = (Integer) objectInputStream.readObject(); - inputs.addAll((List) objectInputStream.readObject()); - //load program from file - List program = (List) objectInputStream.readObject(); - int position = programLocation; - //write all the program, beginning at programStart - for (MemoryItem item : program) { - write(position++, item); - } - } + InputStream file = new FileInputStream(filename); + InputStream buffer = new BufferedInputStream(file); + ObjectInput input = new ObjectInputStream(buffer); + + labels.clear(); + inputs.clear(); + memory.clear(); + + programLocation = (Integer) input.readObject(); + labels.putAll((Map) input.readObject()); + inputs.addAll((List) input.readObject()); + memory.putAll((Map) input.readObject()); + + input.close(); } finally { - /*any number can be put in this method, handling of the notification - is just updating the whole table - */ - notifyMemoryChanged(0); + notifyMemoryChanged(-1); notifyMemorySizeChanged(); } } + + public void destroy() { + clear(); + } } diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java index 37d19d3a9..fb6585e4e 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java @@ -117,6 +117,11 @@ public int getProgramLocation() { return context.getProgramLocation(); } + @Override + public void setProgramLocation(int programLocation) { + context.setProgramLocation(programLocation); + } + private Optional getResourceBundle() { try { return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.memory.rasp.version")); diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/MemoryItem.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/MemoryItem.java deleted file mode 100644 index 95e2c8f76..000000000 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/MemoryItem.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2016-2017 Michal Šipoš - * Copyright (C) 2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.emustudio.plugins.memory.rasp.api; - -import java.io.Serializable; - -/** - * General interface representing memory item. - */ -public interface MemoryItem extends Serializable { - -} diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPInstruction.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPInstruction.java deleted file mode 100644 index 4229a85c2..000000000 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPInstruction.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2016-2017 Michal Šipoš - * Copyright (C) 2020 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.emustudio.plugins.memory.rasp.api; - -/** - * Interface representing RASP instruction. - */ -public interface RASPInstruction extends MemoryItem { - - /** - * Operation code of RASP instruction. - */ - int READ = 1; - /** - * Operation code of RASP instruction. - */ - int WRITE_CONSTANT = 2; - /** - * Operation code of RASP instruction. - */ - int WRITE_REGISTER = 3; - /** - * Operation code of RASP instruction. - */ - int LOAD_CONSTANT = 4; - /** - * Operation code of RASP instruction. - */ - int LOAD_REGISTER = 5; - /** - * Operation code of RASP instruction. - */ - int STORE = 6; - /** - * Operation code of RASP instruction. - */ - int ADD_CONSTANT = 7; - /** - * Operation code of RASP instruction. - */ - int ADD_REGISTER = 8; - /** - * Operation code of RASP instruction. - */ - int SUB_CONSTANT = 9; - /** - * Operation code of RASP instruction. - */ - int SUB_REGISTER = 10; - /** - * Operation code of RASP instruction. - */ - int MUL_CONSTANT = 11; - /** - * Operation code of RASP instruction. - */ - int MUL_REGISTER = 12; - /** - * Operation code of RASP instruction. - */ - int DIV_CONSTANT = 13; - /** - * Operation code of RASP instruction. - */ - int DIV_REGISTER = 14; - /** - * Operation code of RASP instruction. - */ - int JMP = 15; - /** - * Operation code of RASP instruction. - */ - int JZ = 16; - /** - * Operation code of RASP instruction. - */ - int JGTZ = 17; - /** - * Operation code of RASP instruction. - */ - int HALT = 18; - - /** - * Get operation code of the instruction. - * - * @return operation code of the instruction. - */ - int getCode(); - - /** - * Get string representation of the RASP instruction (mnemonic code). - * - * @return string representation of the instruction - */ - String getCodeStr(); - -} diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPLabel.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPLabel.java new file mode 100644 index 000000000..abb59d260 --- /dev/null +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPLabel.java @@ -0,0 +1,23 @@ +package net.emustudio.plugins.memory.rasp.api; + +import java.io.Serializable; + +/** + * A Label is a named pointer to an address in memory. + */ +public interface RASPLabel extends Serializable { + + /** + * Get address to which this label points to + * + * @return memory address + */ + int getAddress(); + + /** + * Get name of this label + * + * @return name of this label + */ + String getLabel(); +} diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryCell.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryCell.java new file mode 100644 index 000000000..814fba7d5 --- /dev/null +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryCell.java @@ -0,0 +1,12 @@ +package net.emustudio.plugins.memory.rasp.api; + +import java.io.Serializable; + +public interface RASPMemoryCell extends Serializable { + + boolean isInstruction(); + + int getAddress(); + + int getValue(); +} diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryContext.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryContext.java index 6fd5905ea..2b7b1e0ab 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryContext.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryContext.java @@ -22,47 +22,27 @@ import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.memory.MemoryContext; +import net.emustudio.plugins.memory.rasp.gui.Disassembler; import java.util.List; +import java.util.Optional; /** * Context of the RASP memory. */ @PluginContext -public interface RASPMemoryContext extends MemoryContext { +@SuppressWarnings("unused") +public interface RASPMemoryContext extends MemoryContext { - /** - * Adds label to memory's set of labels. - * - * @param pos adress which label refers to - * @param label the string reprezentation of the label - */ - void addLabel(int pos, String label); + void setLabels(List labels); - /** - * Returns string reprezentation of the label at given address. - * - * @param pos the memory address - * @return string reprezentation of the label at given address - */ - String getLabel(int pos); + Optional getLabel(int address); - void setProgramLocation(Integer programLocation); + void setInputs(List inputs); - /** - * Returns string representation of the label at given address, but if there - * is no label for given address, just returns string representation of the - * address. - * - * @param address the address - * @return string representation of the label at given address, if there is - * any - */ - String addressToLabelString(int address); - - //from compiler - void addInputs(List input); - - // for CPU List getInputs(); + + default Optional disassemble(int opcode) { + return Disassembler.disassemble(opcode); + } } diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/Disassembler.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/Disassembler.java new file mode 100644 index 000000000..01c38b172 --- /dev/null +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/Disassembler.java @@ -0,0 +1,38 @@ +package net.emustudio.plugins.memory.rasp.gui; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class Disassembler { + private final static Map instructions = new HashMap<>(); + + public final static int JMP = 15; + public final static int JZ = 16; + public final static int JGTZ = 17; + + static { + instructions.put(1, "READ"); + instructions.put(2, "WRITE ="); + instructions.put(3, "WRITE"); + instructions.put(4, "LOAD ="); + instructions.put(5, "LOAD"); + instructions.put(6, "STORE"); + instructions.put(7, "ADD ="); + instructions.put(8, "ADD"); + instructions.put(9, "SUB ="); + instructions.put(10, "SUB"); + instructions.put(11, "MUL ="); + instructions.put(12, "MUL"); + instructions.put(13, "DIV ="); + instructions.put(14, "DIV"); + instructions.put(JMP, "JMP"); + instructions.put(JZ, "JZ"); + instructions.put(JGTZ, "JGTZ"); + instructions.put(18, "HALT"); + } + + public static Optional disassemble(int opcode) { + return Optional.ofNullable(instructions.get(opcode)); + } +} diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/MemoryDialog.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/MemoryDialog.java index 45bcb6909..20f8ec211 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/MemoryDialog.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/MemoryDialog.java @@ -137,7 +137,7 @@ private void onOpenClick(java.awt.event.ActionEvent evt) { ).ifPresent(path -> { recentOpenPath = path.toFile().getParentFile(); try { - memory.loadFromFile(path.toString()); + memory.deserialize(path.toString()); updateTable(); } catch (IOException | ClassNotFoundException ex) { LOGGER.error("Could not read file: {}", path, ex); diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/RASPTableModel.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/RASPTableModel.java index 6ce79ad4f..f18d4a884 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/RASPTableModel.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/RASPTableModel.java @@ -20,13 +20,12 @@ package net.emustudio.plugins.memory.rasp.gui; -import net.emustudio.plugins.memory.rasp.NumberMemoryItem; -import net.emustudio.plugins.memory.rasp.api.MemoryItem; -import net.emustudio.plugins.memory.rasp.api.RASPInstruction; -import net.emustudio.plugins.memory.rasp.api.RASPMemoryContext; +import net.emustudio.plugins.memory.rasp.api.*; import javax.swing.table.AbstractTableModel; +import static net.emustudio.plugins.memory.rasp.gui.Disassembler.*; + /** * MODEL for the table with memory content. * @@ -62,8 +61,7 @@ public int getRowCount() { } /** - * Get number of columns in memory table; it is 3: |"address" | "numeric - * value" |"cell value"| + * Get number of columns in memory table; it is 3: |"address"| "numeric value" |"cell value"| * * @return 3 */ @@ -73,18 +71,13 @@ public int getColumnCount() { } /** - * Returns string contained in the addess column (column No. 0). + * Returns string contained in the address column (column No. 0). * * @param rowIndex the index of the row in the address column - * @return string contained in the addess column + * @return string contained in the address column */ private String getAddressColumnText(int rowIndex) { - String label = memory.getLabel(rowIndex); - if (label != null) { - return rowIndex + " " + label.toLowerCase(); - } else { - return String.valueOf(rowIndex); - } + return memory.getLabel(rowIndex).map(l -> rowIndex + " " + l.getLabel()).orElse(String.valueOf(rowIndex)); } /** @@ -94,13 +87,8 @@ private String getAddressColumnText(int rowIndex) { * @return string contained in the numeric value column */ private String getNumericValueColumnText(int rowIndex) { - MemoryItem item = memory.read(rowIndex); - if (item instanceof NumberMemoryItem) { - return ((NumberMemoryItem) item).toString(); - } else if (item instanceof RASPInstruction) { - return String.valueOf(((RASPInstruction) item).getCode()); - } - return ""; + RASPMemoryCell item = memory.read(rowIndex); + return String.valueOf(item.getValue()); } @@ -111,56 +99,43 @@ private String getNumericValueColumnText(int rowIndex) { * @return string contained in the mnemonic column */ private String getMnemonicColumnValue(int rowIndex) { - //get item at given position - MemoryItem item = (MemoryItem) memory.read(rowIndex); - //item is a number - if (item instanceof NumberMemoryItem) { - //item is NOT the ACCUMULATOR - if (rowIndex != 0) { - MemoryItem previousItem = memory.read(rowIndex - 1); //get the item at the previous position - if (previousItem instanceof RASPInstruction) { - RASPInstruction instruction = (RASPInstruction) previousItem; - int code = instruction.getCode(); - //the previos instruction is a jump instruction, so this number is an address - if (code == RASPInstruction.JMP || code == RASPInstruction.JZ || code == RASPInstruction.JGTZ) { - return memory.addressToLabelString(((NumberMemoryItem) item).getValue()); - } else { - return ((NumberMemoryItem) item).toString(); //previos item is NOT a jump instruction - } - } else { - return ((NumberMemoryItem) item).toString(); //previous item is not an instruction, simply return the number + RASPMemoryCell item = memory.read(rowIndex); + if (item.isInstruction()) { + return Disassembler.disassemble(item.getValue()).orElse("unknown"); + } + if (rowIndex != 0) { + RASPMemoryCell previousItem = memory.read(rowIndex - 1); + if (previousItem.isInstruction()) { + switch (previousItem.getValue()) { + case JMP: + case JZ: + case JGTZ: + return memory + .getLabel(item.getValue()) + .map(RASPLabel::getLabel) + .orElse(String.valueOf(item.getValue())); } - - } else { - //item is the ACCUMULATOR - return ((NumberMemoryItem) item).toString(); } - } //item is an instruction, so return its mnemonics - else if (item instanceof RASPInstruction) { - return ((RASPInstruction) item).getCodeStr(); } - return ""; + return String.valueOf(item.getValue()); } /** - * Returns the string representation of cell in the memory table cell at - * given position. + * Returns the string representation of cell in the memory table cell at given position. * - * @param rowIndex - * @param columnIndex + * @param rowIndex row index + * @param columnIndex column index * @return string representation of memory table cell at given position */ @Override public Object getValueAt(int rowIndex, int columnIndex) { - //column with addresses, optionally marked with label - if (columnIndex == 0) { - return getAddressColumnText(rowIndex); - } //column with numeric value of the memory cell - else if (columnIndex == 1) { - return getNumericValueColumnText(rowIndex); - } //column with mnemonic representation of the memory cell (mnemonic if it is an istruction, number if it is a number memory item) - else { - return getMnemonicColumnValue(rowIndex); + switch (columnIndex) { + case 0: + return getAddressColumnText(rowIndex); + case 1: + return getNumericValueColumnText(rowIndex); + default: + return getMnemonicColumnValue(rowIndex); } } @@ -181,12 +156,28 @@ public String getColumnName(int column) { @Override public void setValueAt(Object value, int rowIndex, int columnIndex) { try { - int numberValue = Integer.parseInt((String) value); - memory.write(rowIndex, new NumberMemoryItem(numberValue)); + int numberValue = Integer.decode((String) value); + RASPMemoryCell original = memory.read(rowIndex); + boolean instruction = original.isInstruction(); + + memory.write(rowIndex, new RASPMemoryCell() { + @Override + public boolean isInstruction() { + return instruction; + } + + @Override + public int getAddress() { + return rowIndex; + } + + @Override + public int getValue() { + return numberValue; + } + }); } catch (NumberFormatException e) { //do nothing, invalid value was inserted } - } - } diff --git a/settings.gradle b/settings.gradle index 67155bafd..5a9a9b23c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -33,12 +33,12 @@ include ':plugins:compiler:as-ssem' include ':plugins:compiler:as-z80' include ':plugins:compiler:brainc-brainduck' include ':plugins:compiler:ramc-ram' -//include ':plugins:compiler:raspc-rasp' +include ':plugins:compiler:raspc-rasp' include ':plugins:cpu:8080-cpu' include ':plugins:cpu:brainduck-cpu' include ':plugins:cpu:ram-cpu' -//include ':plugins:cpu:rasp-cpu' +include ':plugins:cpu:rasp-cpu' include ':plugins:cpu:ssem-cpu' include ':plugins:cpu:z80-cpu' @@ -51,7 +51,7 @@ include ':plugins:device:simhPseudo-z80' include ':plugins:device:ssem-display' include ':plugins:memory:ram-mem' -//include ':plugins:memory:rasp-mem' +include ':plugins:memory:rasp-mem' include ':plugins:memory:ssem-mem' include ':plugins:memory:byte-mem' From a2c80d5b45540fc8ecbc882eaee0330974f86b2e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 12 May 2022 12:03:56 +0200 Subject: [PATCH 140/314] Add and fix all copyrights --- application/src/main/files/logback.xml | 2 +- .../application/ApplicationApiImpl.java | 2 +- .../emustudio/application/CommandLine.java | 2 +- .../net/emustudio/application/Constants.java | 2 +- .../net/emustudio/application/Runner.java | 2 +- .../configuration/ApplicationConfig.java | 2 +- .../configuration/ComputerConfig.java | 2 +- .../configuration/ConfigFiles.java | 2 +- .../configuration/ConfigSaver.java | 2 +- .../configuration/PluginConfig.java | 2 +- .../configuration/PluginConnection.java | 2 +- .../configuration/PluginSettingsImpl.java | 2 +- .../configuration/SchemaPoint.java | 2 +- .../application/emulation/Automation.java | 2 +- .../emulation/AutomationException.java | 2 +- .../emulation/EmulationController.java | 2 +- .../emustudio/application/gui/Components.java | 2 +- .../application/gui/ConstantSizeButton.java | 2 +- .../application/gui/GuiDialogsImpl.java | 2 +- .../application/gui/NoGuiDialogsImpl.java | 2 +- .../java/net/emustudio/application/gui/P.java | 2 +- .../gui/debugtable/BooleanCellRenderer.java | 2 +- .../application/gui/debugtable/CallFlow.java | 2 +- .../gui/debugtable/DebugTableImpl.java | 2 +- .../gui/debugtable/DebugTableModel.java | 2 +- .../gui/debugtable/DebugTableModelImpl.java | 2 +- .../gui/debugtable/PagesPanel.java | 2 +- .../debugtable/PaginatingDisassembler.java | 2 +- .../gui/debugtable/TextCellRenderer.java | 2 +- .../application/gui/dialogs/AboutDialog.java | 2 +- .../application/gui/dialogs/AutoDialog.java | 2 +- .../gui/dialogs/BreakpointDialog.java | 2 +- .../gui/dialogs/LoadingDialog.java | 2 +- .../gui/dialogs/OpenComputerDialog.java | 2 +- .../gui/dialogs/PluginComboModel.java | 2 +- .../gui/dialogs/SchemaEditorDialog.java | 2 +- .../application/gui/dialogs/StudioFrame.java | 2 +- .../gui/dialogs/ViewComputerDialog.java | 2 +- .../application/gui/schema/DrawingModel.java | 2 +- .../application/gui/schema/DrawingPanel.java | 2 +- .../application/gui/schema/Schema.java | 2 +- .../gui/schema/SchemaPreviewPanel.java | 2 +- .../gui/schema/elements/CompilerElement.java | 2 +- .../gui/schema/elements/ConnectionLine.java | 2 +- .../gui/schema/elements/CpuElement.java | 2 +- .../gui/schema/elements/DeviceElement.java | 2 +- .../gui/schema/elements/Element.java | 2 +- .../gui/schema/elements/MemoryElement.java | 2 +- .../gui/schema/mode/AbstractMode.java | 2 +- .../application/gui/schema/mode/Mode.java | 2 +- .../gui/schema/mode/ModeSelector.java | 2 +- .../gui/schema/mode/ModelingMode.java | 2 +- .../gui/schema/mode/MovingMode.java | 2 +- .../gui/schema/mode/ResizingMode.java | 2 +- .../gui/schema/mode/SelectingMode.java | 2 +- .../application/internal/Hashing.java | 2 +- .../application/internal/Reflection.java | 2 +- .../application/internal/Unchecked.java | 2 +- .../virtualcomputer/ContextPoolImpl.java | 2 +- .../InvalidPluginException.java | 2 +- .../virtualcomputer/PluginConnections.java | 2 +- .../virtualcomputer/PluginLoader.java | 2 +- .../PluginLoadingException.java | 2 +- .../virtualcomputer/VirtualComputer.java | 2 +- .../emustudio/application/version.properties | 2 +- .../configuration/ApplicationConfigTest.java | 2 +- .../configuration/ComputerConfigTest.java | 2 +- .../configuration/ConfigFilesTest.java | 2 +- .../configuration/SchemaPointTest.java | 2 +- .../emulation/EmulationControllerTest.java | 2 +- .../gui/debugtable/CallFlowTest.java | 2 +- .../gui/debugtable/DisassemblerStub.java | 2 +- .../gui/debugtable/MockHelper.java | 2 +- .../PaginatingDisassemblerTest.java | 2 +- .../virtualcomputer/ContextPoolImplTest.java | 2 +- .../virtualcomputer/ContextStubs.java | 2 +- .../virtualcomputer/JarCreator.java | 2 +- .../virtualcomputer/PluginLoaderTest.java | 2 +- .../stubs/AbstractCPUStub.java | 2 +- .../virtualcomputer/stubs/CPUContextStub.java | 2 +- .../virtualcomputer/stubs/CPUImplStub.java | 2 +- .../stubs/CPUListenerStub.java | 2 +- .../stubs/CompilerContextStub.java | 2 +- .../stubs/DeviceContextStub.java | 2 +- .../stubs/ShortMemoryContextStub.java | 2 +- .../stubs/UnannotatedCPUStub.java | 2 +- .../stubs/UnannotatedContextStub.java | 2 +- .../as-8080/src/main/antlr/As8080Lexer.g4 | 18 +++++++++++++++++ .../as-8080/src/main/antlr/As8080Parser.g4 | 18 +++++++++++++++++ .../compiler/as8080/Assembler8080.java | 2 +- .../plugins/compiler/as8080/CompileError.java | 18 +++++++++++++++++ .../compiler/as8080/LexicalAnalyzerImpl.java | 18 +++++++++++++++++ .../compiler/as8080/ParserErrorListener.java | 18 +++++++++++++++++ .../plugins/compiler/as8080/ParsingUtils.java | 18 +++++++++++++++++ .../plugins/compiler/as8080/Runner.java | 2 +- .../compiler/as8080/ast/Evaluated.java | 18 +++++++++++++++++ .../compiler/as8080/ast/NameSpace.java | 18 +++++++++++++++++ .../plugins/compiler/as8080/ast/Node.java | 18 +++++++++++++++++ .../plugins/compiler/as8080/ast/Program.java | 18 +++++++++++++++++ .../compiler/as8080/ast/data/DataDB.java | 18 +++++++++++++++++ .../compiler/as8080/ast/data/DataDS.java | 18 +++++++++++++++++ .../compiler/as8080/ast/data/DataDW.java | 18 +++++++++++++++++ .../as8080/ast/expr/ExprCurrentAddress.java | 18 +++++++++++++++++ .../compiler/as8080/ast/expr/ExprId.java | 18 +++++++++++++++++ .../compiler/as8080/ast/expr/ExprInfix.java | 18 +++++++++++++++++ .../compiler/as8080/ast/expr/ExprNumber.java | 18 +++++++++++++++++ .../compiler/as8080/ast/expr/ExprString.java | 18 +++++++++++++++++ .../compiler/as8080/ast/expr/ExprUnary.java | 18 +++++++++++++++++ .../compiler/as8080/ast/instr/InstrExpr.java | 18 +++++++++++++++++ .../as8080/ast/instr/InstrNoArgs.java | 18 +++++++++++++++++ .../compiler/as8080/ast/instr/InstrReg.java | 18 +++++++++++++++++ .../as8080/ast/instr/InstrRegExpr.java | 18 +++++++++++++++++ .../as8080/ast/instr/InstrRegPair.java | 18 +++++++++++++++++ .../as8080/ast/instr/InstrRegPairExpr.java | 18 +++++++++++++++++ .../as8080/ast/instr/InstrRegReg.java | 18 +++++++++++++++++ .../compiler/as8080/ast/pseudo/PseudoEqu.java | 18 +++++++++++++++++ .../compiler/as8080/ast/pseudo/PseudoIf.java | 18 +++++++++++++++++ .../as8080/ast/pseudo/PseudoIfExpression.java | 18 +++++++++++++++++ .../as8080/ast/pseudo/PseudoInclude.java | 18 +++++++++++++++++ .../as8080/ast/pseudo/PseudoLabel.java | 18 +++++++++++++++++ .../ast/pseudo/PseudoMacroArgument.java | 18 +++++++++++++++++ .../as8080/ast/pseudo/PseudoMacroCall.java | 18 +++++++++++++++++ .../as8080/ast/pseudo/PseudoMacroDef.java | 18 +++++++++++++++++ .../ast/pseudo/PseudoMacroParameter.java | 19 +++++++++++++++++- .../compiler/as8080/ast/pseudo/PseudoOrg.java | 18 +++++++++++++++++ .../compiler/as8080/ast/pseudo/PseudoSet.java | 18 +++++++++++++++++ .../as8080/exceptions/CompileException.java | 2 +- .../as8080/exceptions/FatalError.java | 18 +++++++++++++++++ .../exceptions/SyntaxErrorException.java | 18 +++++++++++++++++ .../visitors/CheckDeclarationsVisitor.java | 18 +++++++++++++++++ .../visitors/CheckExprSizesVisitor.java | 18 +++++++++++++++++ .../as8080/visitors/CreateDataVisitor.java | 18 +++++++++++++++++ .../as8080/visitors/CreateExprVisitor.java | 18 +++++++++++++++++ .../as8080/visitors/CreateInstrVisitor.java | 18 +++++++++++++++++ .../as8080/visitors/CreateLineVisitor.java | 18 +++++++++++++++++ .../as8080/visitors/CreateProgramVisitor.java | 18 +++++++++++++++++ .../as8080/visitors/CreatePseudoVisitor.java | 18 +++++++++++++++++ .../as8080/visitors/CreateVisitors.java | 18 +++++++++++++++++ .../as8080/visitors/EvaluateExprVisitor.java | 18 +++++++++++++++++ .../visitors/ExpandIncludesVisitor.java | 18 +++++++++++++++++ .../as8080/visitors/ExpandMacrosVisitor.java | 18 +++++++++++++++++ .../as8080/visitors/GenerateCodeVisitor.java | 18 +++++++++++++++++ .../compiler/as8080/visitors/NodeVisitor.java | 18 +++++++++++++++++ .../visitors/SortMacroArgumentsVisitor.java | 18 +++++++++++++++++ .../compiler/as8080/version.properties | 2 +- .../plugins/compiler/as8080/RunnerTest.java | 2 +- .../plugins/compiler/as8080/Utils.java | 18 +++++++++++++++++ .../as8080/e2e/AbstractCompilerTest.java | 2 +- .../as8080/e2e/Assembler8080Test.java | 2 +- .../as8080/e2e/ConstantsAndVariablesTest.java | 2 +- .../plugins/compiler/as8080/e2e/DataTest.java | 2 +- .../compiler/as8080/e2e/IfNodeTest.java | 2 +- .../compiler/as8080/e2e/IncludeTest.java | 2 +- .../compiler/as8080/e2e/InstrRegTest.java | 2 +- .../compiler/as8080/e2e/MacroTest.java | 2 +- .../compiler/as8080/e2e/PseudoOrgTest.java | 2 +- .../parser/LexicalAnalyzerImplTest.java | 18 +++++++++++++++++ .../compiler/as8080/parser/ParseDataTest.java | 18 +++++++++++++++++ .../compiler/as8080/parser/ParseExprTest.java | 18 +++++++++++++++++ .../as8080/parser/ParseInstrTest.java | 18 +++++++++++++++++ .../as8080/parser/ParsePseudoTest.java | 18 +++++++++++++++++ .../as8080/parser/ParsingUtilsTest.java | 18 +++++++++++++++++ .../CheckDeclarationsVisitorTest.java | 18 +++++++++++++++++ .../visitors/CheckExprSizesVisitorTest.java | 18 +++++++++++++++++ .../visitors/EvaluateExprVisitorTest.java | 18 +++++++++++++++++ .../visitors/ExpandIncludesVisitorTest.java | 18 +++++++++++++++++ .../as8080/visitors/ExpandMacrosTest.java | 18 +++++++++++++++++ .../visitors/GenerateCodeVisitorTest.java | 18 +++++++++++++++++ .../SortMacroArgumentsVisitorTest.java | 18 +++++++++++++++++ plugins/compiler/as-ssem/build.gradle | 2 +- .../as-ssem/src/main/antlr/SSEMLexer.g4 | 20 ++++++++++++++++++- .../as-ssem/src/main/antlr/SSEMParser.g4 | 18 +++++++++++++++++ .../plugins/compiler/ssem/CodeGenerator.java | 18 +++++++++++++++++ .../compiler/ssem/CompileException.java | 2 +- .../plugins/compiler/ssem/CompilerChecks.java | 18 +++++++++++++++++ .../compiler/ssem/LexicalAnalyzerImpl.java | 18 +++++++++++++++++ .../compiler/ssem/ParserErrorListener.java | 18 +++++++++++++++++ .../plugins/compiler/ssem/Position.java | 18 +++++++++++++++++ .../plugins/compiler/ssem/Runner.java | 2 +- .../plugins/compiler/ssem/SSEMCompiler.java | 2 +- .../compiler/ssem/ast/Instruction.java | 18 +++++++++++++++++ .../plugins/compiler/ssem/ast/Program.java | 18 +++++++++++++++++ .../compiler/ssem/ast/ProgramParser.java | 18 +++++++++++++++++ .../plugins/compiler/ssem/version.properties | 2 +- .../plugins/compiler/ssem/LexerTest.java | 2 +- .../plugins/compiler/ssem/ParserTest.java | 18 +++++++++++++++++ .../plugins/compiler/ssem/RunnerTest.java | 2 +- .../compiler/ssem/SSEMCompilerTest.java | 2 +- .../plugins/compiler/ssem/Utils.java | 18 +++++++++++++++++ .../as-z80/src/main/antlr/AsZ80Lexer.g4 | 18 +++++++++++++++++ .../as-z80/src/main/antlr/AsZ80Parser.g4 | 18 +++++++++++++++++ .../plugins/compiler/asZ80/AssemblerZ80.java | 2 +- .../plugins/compiler/asZ80/CompileError.java | 18 +++++++++++++++++ .../compiler/asZ80/CompilerTables.java | 18 +++++++++++++++++ .../compiler/asZ80/LexicalAnalyzerImpl.java | 19 +++++++++++++++++- .../plugins/compiler/asZ80/Pair.java | 18 +++++++++++++++++ .../compiler/asZ80/ParserErrorListener.java | 18 +++++++++++++++++ .../plugins/compiler/asZ80/ParsingUtils.java | 18 +++++++++++++++++ .../plugins/compiler/asZ80/Runner.java | 2 +- .../plugins/compiler/asZ80/ast/Evaluated.java | 18 +++++++++++++++++ .../plugins/compiler/asZ80/ast/NameSpace.java | 18 +++++++++++++++++ .../plugins/compiler/asZ80/ast/Node.java | 18 +++++++++++++++++ .../plugins/compiler/asZ80/ast/Program.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/data/DataDB.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/data/DataDS.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/data/DataDW.java | 18 +++++++++++++++++ .../asZ80/ast/expr/ExprCurrentAddress.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/expr/ExprId.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/expr/ExprInfix.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/expr/ExprNumber.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/expr/ExprString.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/expr/ExprUnary.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/instr/Instr.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/instr/InstrCB.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/instr/InstrED.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/instr/InstrXD.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/instr/InstrXDCB.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/pseudo/PseudoEqu.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/pseudo/PseudoIf.java | 18 +++++++++++++++++ .../asZ80/ast/pseudo/PseudoIfExpression.java | 18 +++++++++++++++++ .../asZ80/ast/pseudo/PseudoInclude.java | 18 +++++++++++++++++ .../asZ80/ast/pseudo/PseudoLabel.java | 18 +++++++++++++++++ .../asZ80/ast/pseudo/PseudoMacroArgument.java | 18 +++++++++++++++++ .../asZ80/ast/pseudo/PseudoMacroCall.java | 18 +++++++++++++++++ .../asZ80/ast/pseudo/PseudoMacroDef.java | 18 +++++++++++++++++ .../ast/pseudo/PseudoMacroParameter.java | 19 +++++++++++++++++- .../compiler/asZ80/ast/pseudo/PseudoOrg.java | 18 +++++++++++++++++ .../compiler/asZ80/ast/pseudo/PseudoVar.java | 18 +++++++++++++++++ .../asZ80/exceptions/CompileException.java | 2 +- .../compiler/asZ80/exceptions/FatalError.java | 18 +++++++++++++++++ .../exceptions/SyntaxErrorException.java | 18 +++++++++++++++++ .../visitors/CheckDeclarationsVisitor.java | 18 +++++++++++++++++ .../asZ80/visitors/CheckExprSizesVisitor.java | 18 +++++++++++++++++ .../visitors/CollectExprsInOpcodeVisitor.java | 18 +++++++++++++++++ .../asZ80/visitors/CreateDataVisitor.java | 18 +++++++++++++++++ .../asZ80/visitors/CreateExprVisitor.java | 18 +++++++++++++++++ .../asZ80/visitors/CreateInstrVisitor.java | 18 +++++++++++++++++ .../asZ80/visitors/CreateLineVisitor.java | 18 +++++++++++++++++ .../asZ80/visitors/CreateProgramVisitor.java | 18 +++++++++++++++++ .../asZ80/visitors/CreatePseudoVisitor.java | 18 +++++++++++++++++ .../asZ80/visitors/CreateVisitors.java | 18 +++++++++++++++++ .../asZ80/visitors/EvaluateExprVisitor.java | 18 +++++++++++++++++ .../asZ80/visitors/ExpandIncludesVisitor.java | 18 +++++++++++++++++ .../asZ80/visitors/ExpandMacrosVisitor.java | 18 +++++++++++++++++ .../asZ80/visitors/GenerateCodeVisitor.java | 18 +++++++++++++++++ .../compiler/asZ80/visitors/NodeVisitor.java | 18 +++++++++++++++++ .../visitors/SortMacroArgumentsVisitor.java | 18 +++++++++++++++++ .../plugins/compiler/asZ80/version.properties | 2 +- .../plugins/compiler/asZ80/RunnerTest.java | 2 +- .../plugins/compiler/asZ80/Utils.java | 18 +++++++++++++++++ .../asZ80/e2e/AbstractCompilerTest.java | 2 +- .../compiler/asZ80/e2e/AssemblerZ80Test.java | 2 +- .../asZ80/e2e/ConstantsAndVariablesTest.java | 2 +- .../plugins/compiler/asZ80/e2e/DataTest.java | 2 +- .../compiler/asZ80/e2e/IfNodeTest.java | 2 +- .../compiler/asZ80/e2e/IncludeTest.java | 2 +- .../compiler/asZ80/e2e/InstrRegTest.java | 2 +- .../plugins/compiler/asZ80/e2e/MacroTest.java | 2 +- .../compiler/asZ80/e2e/PseudoOrgTest.java | 2 +- .../asZ80/parser/LexicalAnalyzerImplTest.java | 18 +++++++++++++++++ .../compiler/asZ80/parser/ParseDataTest.java | 18 +++++++++++++++++ .../compiler/asZ80/parser/ParseExprTest.java | 18 +++++++++++++++++ .../compiler/asZ80/parser/ParseInstrTest.java | 18 +++++++++++++++++ .../asZ80/parser/ParsePseudoTest.java | 18 +++++++++++++++++ .../asZ80/parser/ParsingUtilsTest.java | 18 +++++++++++++++++ .../CheckDeclarationsVisitorTest.java | 18 +++++++++++++++++ .../visitors/CheckExprSizesVisitorTest.java | 18 +++++++++++++++++ .../visitors/EvaluateExprVisitorTest.java | 18 +++++++++++++++++ .../visitors/ExpandIncludesVisitorTest.java | 18 +++++++++++++++++ .../asZ80/visitors/ExpandMacrosTest.java | 18 +++++++++++++++++ .../visitors/GenerateCodeVisitorTest.java | 18 +++++++++++++++++ .../SortMacroArgumentsVisitorTest.java | 18 +++++++++++++++++ .../compiler/brainc-brainduck/build.gradle | 2 +- .../src/main/antlr/BraincLexer.g4 | 18 +++++++++++++++++ .../src/main/antlr/BraincParser.g4 | 18 +++++++++++++++++ .../compiler/brainduck/CompileException.java | 18 +++++++++++++++++ .../compiler/brainduck/CompilerImpl.java | 2 +- .../brainduck/LexicalAnalyzerImpl.java | 18 +++++++++++++++++ .../brainduck/ParserErrorListener.java | 18 +++++++++++++++++ .../plugins/compiler/brainduck/Runner.java | 2 +- .../compiler/brainduck/ast/Instruction.java | 2 +- .../compiler/brainduck/ast/Program.java | 2 +- .../compiler/brainduck/ast/ProgramParser.java | 18 +++++++++++++++++ .../compiler/brainduck/version.properties | 2 +- .../brainduck/AbstractCompilerTest.java | 2 +- .../compiler/brainduck/InstructionTest.java | 2 +- .../compiler/brainduck/RunnerTest.java | 2 +- plugins/compiler/ramc-ram/build.gradle | 2 +- .../ramc-ram/src/main/antlr/RAMLexer.g4 | 18 +++++++++++++++++ .../ramc-ram/src/main/antlr/RAMParser.g4 | 18 +++++++++++++++++ .../plugins/compiler/ram/CompilerRAM.java | 2 +- .../compiler/ram/LexicalAnalyzerImpl.java | 18 +++++++++++++++++ .../compiler/ram/ParserErrorListener.java | 18 +++++++++++++++++ .../plugins/compiler/ram/ParsingUtils.java | 18 +++++++++++++++++ .../plugins/compiler/ram/ProgramParser.java | 18 +++++++++++++++++ .../plugins/compiler/ram/Runner.java | 2 +- .../compiler/ram/SerializableOptional.java | 18 +++++++++++++++++ .../plugins/compiler/ram/ast/Instruction.java | 18 +++++++++++++++++ .../plugins/compiler/ram/ast/Label.java | 2 +- .../plugins/compiler/ram/ast/Program.java | 2 +- .../plugins/compiler/ram/ast/Value.java | 18 +++++++++++++++++ .../ram/exceptions/CompileException.java | 18 +++++++++++++++++ .../ram/exceptions/SyntaxErrorException.java | 18 +++++++++++++++++ .../plugins/compiler/ram/version.properties | 2 +- .../compiler/ram/AbstractCompilerTest.java | 2 +- .../plugins/compiler/ram/CompilerTest.java | 2 +- .../plugins/compiler/ram/MemoryStub.java | 2 +- .../plugins/compiler/ram/RunnerTest.java | 2 +- plugins/compiler/raspc-rasp/build.gradle | 2 +- .../raspc-rasp/src/main/antlr/RASPLexer.g4 | 18 +++++++++++++++++ .../raspc-rasp/src/main/antlr/RASPParser.g4 | 18 +++++++++++++++++ .../plugins/compiler/rasp/CompilerRASP.java | 2 +- .../compiler/rasp/LexicalAnalyzerImpl.java | 18 +++++++++++++++++ .../compiler/rasp/ParserErrorListener.java | 18 +++++++++++++++++ .../plugins/compiler/rasp/ParsingUtils.java | 18 +++++++++++++++++ .../plugins/compiler/rasp/ProgramParser.java | 18 +++++++++++++++++ .../plugins/compiler/rasp/Runner.java | 2 +- .../compiler/rasp/ast/Instruction.java | 18 +++++++++++++++++ .../plugins/compiler/rasp/ast/Label.java | 18 +++++++++++++++++ .../plugins/compiler/rasp/ast/Program.java | 18 +++++++++++++++++ .../rasp/exceptions/CompileException.java | 18 +++++++++++++++++ .../rasp/exceptions/SyntaxErrorException.java | 18 +++++++++++++++++ .../plugins/compiler/rasp/version.properties | 4 ++-- .../compiler/rasp/AbstractCompilerTest.java | 18 +++++++++++++++++ .../plugins/compiler/rasp/CompilerTest.java | 18 +++++++++++++++++ .../plugins/compiler/rasp/MemoryStub.java | 18 +++++++++++++++++ plugins/cpu/8080-cpu/build.gradle | 2 +- plugins/cpu/8080-cpu/src/main/edigen/cpu.eds | 19 ++++++++++++++++++ .../plugins/cpu/intel8080/Breakpoint.java | 2 +- .../plugins/cpu/intel8080/ContextImpl.java | 2 +- .../plugins/cpu/intel8080/CpuImpl.java | 2 +- .../plugins/cpu/intel8080/DispatchTables.java | 18 +++++++++++++++++ .../plugins/cpu/intel8080/EmulatorEngine.java | 2 +- .../plugins/cpu/intel8080/EmulatorTables.java | 2 +- .../cpu/intel8080/InitializerFor8080.java | 2 +- .../cpu/intel8080/InstructionPrinter.java | 2 +- .../plugins/cpu/intel8080/api/CpuEngine.java | 2 +- .../cpu/intel8080/api/DefaultInitializer.java | 2 +- .../cpu/intel8080/api/DispatchListener.java | 2 +- .../cpu/intel8080/api/ExtendedContext.java | 2 +- .../api/FrequencyChangedListener.java | 2 +- .../cpu/intel8080/api/FrequencyUpdater.java | 2 +- .../plugins/cpu/intel8080/gui/FlagsModel.java | 2 +- .../cpu/intel8080/gui/StatusPanel.java | 2 +- .../plugins/cpu/intel8080/version.properties | 2 +- .../plugins/cpu/intel8080/ArithmeticTest.java | 2 +- .../plugins/cpu/intel8080/ControlTest.java | 2 +- .../plugins/cpu/intel8080/CpuImplTest.java | 18 +++++++++++++++++ .../cpu/intel8080/InstructionsTest.java | 2 +- .../plugins/cpu/intel8080/LogicTest.java | 2 +- .../plugins/cpu/intel8080/StackTest.java | 2 +- .../plugins/cpu/intel8080/TransferTest.java | 2 +- .../intel8080/api/FrequencyUpdaterTest.java | 2 +- .../cpu/intel8080/suite/ByteTestBuilder.java | 2 +- .../cpu/intel8080/suite/CpuRunnerImpl.java | 2 +- .../cpu/intel8080/suite/CpuVerifierImpl.java | 2 +- .../cpu/intel8080/suite/FlagsCheckImpl.java | 2 +- .../intel8080/suite/IntegerTestBuilder.java | 2 +- .../intel8080/suite/injectors/Register.java | 2 +- .../suite/injectors/RegisterPair.java | 2 +- .../suite/injectors/RegisterPairPSW.java | 2 +- plugins/cpu/brainduck-cpu/build.gradle | 2 +- .../cpu/brainduck-cpu/src/main/edigen/cpu.eds | 18 +++++++++++++++++ .../cpu/brainduck/BrainCPUContext.java | 2 +- .../cpu/brainduck/BrainCPUContextImpl.java | 2 +- .../plugins/cpu/brainduck/Breakpoint.java | 2 +- .../plugins/cpu/brainduck/CpuImpl.java | 2 +- .../plugins/cpu/brainduck/EmulatorEngine.java | 2 +- .../plugins/cpu/brainduck/Profiler.java | 2 +- .../cpu/brainduck/gui/ColumnsRepainter.java | 2 +- .../plugins/cpu/brainduck/gui/Constants.java | 18 +++++++++++++++++ .../cpu/brainduck/gui/MemoryTableModel.java | 2 +- .../cpu/brainduck/gui/StatusPanel.java | 2 +- .../plugins/cpu/brainduck/version.properties | 2 +- .../plugins/cpu/brainduck/CpuImplTest.java | 2 +- .../plugins/cpu/brainduck/DeviceStub.java | 2 +- .../cpu/brainduck/EmulatorEngineTest.java | 2 +- .../plugins/cpu/brainduck/MemoryStub.java | 2 +- plugins/cpu/ram-cpu/build.gradle | 2 +- .../emustudio/plugins/cpu/ram/Breakpoint.java | 2 +- .../emustudio/plugins/cpu/ram/CpuImpl.java | 2 +- .../plugins/cpu/ram/EmulatorEngine.java | 2 +- .../plugins/cpu/ram/RAMCpuContextImpl.java | 2 +- .../plugins/cpu/ram/api/RAMCpuContext.java | 2 +- .../plugins/cpu/ram/gui/Constants.java | 18 +++++++++++++++++ .../plugins/cpu/ram/gui/LabelDebugColumn.java | 2 +- .../plugins/cpu/ram/gui/RAMDisassembler.java | 2 +- .../plugins/cpu/ram/gui/RAMStatusPanel.java | 2 +- .../plugins/cpu/ram/version.properties | 2 +- .../plugins/cpu/ram/AbstractEngineTest.java | 18 +++++++++++++++++ .../plugins/cpu/ram/CpuImplTest.java | 18 +++++++++++++++++ .../plugins/cpu/ram/EmulatorEngineTest.java | 2 +- plugins/cpu/rasp-cpu/build.gradle | 2 +- .../plugins/cpu/rasp/Breakpoint.java | 2 +- .../emustudio/plugins/cpu/rasp/CpuImpl.java | 2 +- .../plugins/cpu/rasp/EmulatorEngine.java | 18 +++++++++++++++++ .../plugins/cpu/rasp/RASPCpuContextImpl.java | 18 +++++++++++++++++ .../plugins/cpu/rasp/api/RASPCpuContext.java | 2 +- .../cpu/rasp/gui/LabelDebugColumn.java | 2 +- .../cpu/rasp/gui/RASPCpuStatusPanel.java | 2 +- .../cpu/rasp/gui/RASPDisassembler.java | 2 +- .../plugins/cpu/rasp/version.properties | 4 ++-- .../plugins/cpu/rasp/CpuImplTest.java | 18 +++++++++++++++++ .../plugins/cpu/rasp/EmulatorEngineTest.java | 18 +++++++++++++++++ .../plugins/cpu/rasp/MemoryStub.java | 18 +++++++++++++++++ .../emustudio/plugins/cpu/rasp/RASPCell.java | 18 +++++++++++++++++ plugins/cpu/ssem-cpu/build.gradle | 2 +- plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds | 18 +++++++++++++++++ .../plugins/cpu/ssem/AutomaticEmulation.java | 2 +- .../emustudio/plugins/cpu/ssem/CpuImpl.java | 2 +- .../plugins/cpu/ssem/EmulatorEngine.java | 2 +- .../plugins/cpu/ssem/LineColumn.java | 2 +- .../plugins/cpu/ssem/TimingEstimator.java | 18 +++++++++++++++++ .../plugins/cpu/ssem/gui/Constants.java | 18 +++++++++++++++++ .../plugins/cpu/ssem/gui/CpuPanel.java | 2 +- .../plugins/cpu/ssem/version.properties | 2 +- .../plugins/cpu/ssem/CpuImplTest.java | 18 +++++++++++++++++ .../plugins/cpu/ssem/DisassemblerTest.java | 18 +++++++++++++++++ .../plugins/cpu/ssem/EmulatorEngineTest.java | 2 +- plugins/cpu/z80-cpu/build.gradle | 2 +- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 18 +++++++++++++++++ .../plugins/cpu/zilogZ80/Breakpoint.java | 2 +- .../plugins/cpu/zilogZ80/ContextImpl.java | 2 +- .../plugins/cpu/zilogZ80/CpuImpl.java | 2 +- .../plugins/cpu/zilogZ80/DispatchTables.java | 18 +++++++++++++++++ .../plugins/cpu/zilogZ80/EmulatorEngine.java | 2 +- .../plugins/cpu/zilogZ80/EmulatorTables.java | 2 +- .../cpu/zilogZ80/InitializerForZ80.java | 2 +- .../cpu/zilogZ80/InstructionPrinter.java | 2 +- .../plugins/cpu/zilogZ80/gui/Constants.java | 18 +++++++++++++++++ .../plugins/cpu/zilogZ80/gui/FlagsModel.java | 2 +- .../plugins/cpu/zilogZ80/gui/StatusPanel.java | 2 +- .../plugins/cpu/zilogZ80/version.properties | 2 +- .../plugins/cpu/zilogZ80/ArithmeticTest.java | 2 +- .../plugins/cpu/zilogZ80/BitTest.java | 2 +- .../plugins/cpu/zilogZ80/ControlTest.java | 2 +- .../plugins/cpu/zilogZ80/CpuImplTest.java | 18 +++++++++++++++++ .../cpu/zilogZ80/DisassemblerTest.java | 18 +++++++++++++++++ .../zilogZ80/EmulatorTablesGeneration.java | 18 +++++++++++++++++ .../plugins/cpu/zilogZ80/FakeByteDevice.java | 2 +- .../cpu/zilogZ80/FlagsTableGeneratorTest.java | 2 +- .../plugins/cpu/zilogZ80/IOTest.java | 2 +- .../cpu/zilogZ80/InstructionsTest.java | 2 +- .../plugins/cpu/zilogZ80/LogicTest.java | 2 +- .../plugins/cpu/zilogZ80/StackTest.java | 2 +- .../plugins/cpu/zilogZ80/TransferTest.java | 2 +- .../cpu/zilogZ80/suite/ByteTestBuilder.java | 2 +- .../cpu/zilogZ80/suite/CpuRunnerImpl.java | 2 +- .../cpu/zilogZ80/suite/CpuVerifierImpl.java | 2 +- .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 2 +- .../zilogZ80/suite/IntegerTestBuilder.java | 2 +- .../plugins/cpu/zilogZ80/suite/Utils.java | 2 +- .../zilogZ80/suite/injectors/Register.java | 2 +- .../suite/injectors/RegisterPair.java | 2 +- .../suite/injectors/RegisterPair2.java | 2 +- .../suite/injectors/RegisterPairPSW.java | 2 +- plugins/device/88-dcdd/build.gradle | 2 +- .../plugins/device/mits88dcdd/Command.java | 18 +++++++++++++++++ .../device/mits88dcdd/CommandLine.java | 18 +++++++++++++++++ .../plugins/device/mits88dcdd/DeviceImpl.java | 2 +- .../plugins/device/mits88dcdd/Resources.java | 2 +- .../plugins/device/mits88dcdd/Runner.java | 2 +- .../device/mits88dcdd/SettingsConstants.java | 2 +- .../device/mits88dcdd/cpmfs/CpmFile.java | 2 +- .../mits88dcdd/cpmfs/CpmFileSystem.java | 18 +++++++++++++++++ .../device/mits88dcdd/cpmfs/DriveIO.java | 2 +- .../device/mits88dcdd/cpmfs/Position.java | 2 +- .../cpmfs/commands/CatSubCommand.java | 18 +++++++++++++++++ .../cpmfs/commands/CpmfsCommand.java | 18 +++++++++++++++++ .../cpmfs/commands/DownloadSubCommand.java | 18 +++++++++++++++++ .../cpmfs/commands/InfoSubCommand.java | 18 +++++++++++++++++ .../cpmfs/commands/ListSubCommand.java | 18 +++++++++++++++++ .../device/mits88dcdd/drive/Drive.java | 2 +- .../mits88dcdd/drive/DriveCollection.java | 18 +++++++++++++++++ .../mits88dcdd/drive/DriveListener.java | 18 +++++++++++++++++ .../mits88dcdd/drive/DriveParameters.java | 18 +++++++++++++++++ .../device/mits88dcdd/gui/Constants.java | 18 +++++++++++++++++ .../device/mits88dcdd/gui/DiskGui.java | 2 +- .../device/mits88dcdd/gui/DriveButton.java | 18 +++++++++++++++++ .../device/mits88dcdd/gui/SettingsDialog.java | 2 +- .../device/mits88dcdd/ports/ControlPort.java | 2 +- .../device/mits88dcdd/ports/DataPort.java | 2 +- .../device/mits88dcdd/ports/StatusPort.java | 2 +- .../device/mits88dcdd/version.properties | 2 +- .../device/mits88dcdd/DeviceImplTest.java | 18 +++++++++++++++++ .../plugins/device/mits88dcdd/DriveTest.java | 2 +- plugins/device/88-sio/build.gradle | 2 +- .../plugins/device/mits88sio/DeviceImpl.java | 2 +- .../plugins/device/mits88sio/SIOSettings.java | 2 +- .../plugins/device/mits88sio/Transmitter.java | 2 +- .../mits88sio/gui/CPUPortsTableModel.java | 2 +- .../device/mits88sio/gui/Constants.java | 18 +++++++++++++++++ .../device/mits88sio/gui/PortListModel.java | 2 +- .../device/mits88sio/gui/SettingsDialog.java | 2 +- .../plugins/device/mits88sio/gui/SioGui.java | 2 +- .../ports/CouldNotAttachException.java | 2 +- .../device/mits88sio/ports/CpuDataPort.java | 2 +- .../device/mits88sio/ports/CpuPorts.java | 2 +- .../device/mits88sio/ports/CpuStatusPort.java | 2 +- .../device/mits88sio/ports/PhysicalPort.java | 2 +- .../device/mits88sio/version.properties | 2 +- .../device/mits88sio/DeviceImplTest.java | 18 +++++++++++++++++ .../device/mits88sio/SIOSettingsTest.java | 2 +- .../device/mits88sio/TransmitterTest.java | 2 +- .../mits88sio/ports/CpuDataPortTest.java | 2 +- .../device/mits88sio/ports/CpuPortsTest.java | 2 +- .../mits88sio/ports/CpuStatusPortTest.java | 2 +- .../mits88sio/ports/PhysicalPortTest.java | 2 +- plugins/device/abstract-tape/build.gradle | 2 +- .../device/abstracttape/AbstractTape.java | 2 +- .../abstracttape/AbstractTapeContextImpl.java | 2 +- .../abstracttape/api/AbstractTapeContext.java | 2 +- .../device/abstracttape/api/TapeSymbol.java | 18 +++++++++++++++++ .../device/abstracttape/gui/NiceButton.java | 2 +- .../abstracttape/gui/SettingsDialog.java | 2 +- .../abstracttape/gui/TapeCellRenderer.java | 18 +++++++++++++++++ .../device/abstracttape/gui/TapeGui.java | 2 +- .../device/abstracttape/gui/TapeModel.java | 18 +++++++++++++++++ .../device/abstracttape/version.properties | 2 +- .../device/abstracttape/AbstractTapeTest.java | 18 +++++++++++++++++ plugins/device/adm3A-terminal/build.gradle | 2 +- .../plugins/device/adm3a/DeviceImpl.java | 2 +- .../device/adm3a/TerminalSettings.java | 2 +- .../emustudio/plugins/device/adm3a/Utils.java | 2 +- .../device/adm3a/gui/ConfigDialog.java | 2 +- .../device/adm3a/gui/TerminalWindow.java | 2 +- .../device/adm3a/interaction/Cursor.java | 2 +- .../device/adm3a/interaction/Display.java | 2 +- .../adm3a/interaction/DisplayParameters.java | 2 +- .../device/adm3a/interaction/Keyboard.java | 2 +- .../adm3a/interaction/KeyboardFromFile.java | 2 +- .../device/adm3a/interaction/KeyboardGui.java | 2 +- .../adm3a/interaction/LoadCursorPosition.java | 2 +- .../plugins/device/adm3a/version.properties | 2 +- .../plugins/device/adm3a/DeviceImplTest.java | 18 +++++++++++++++++ .../device/brainduck-terminal/build.gradle | 2 +- .../terminal/BrainTerminalContext.java | 2 +- .../brainduck/terminal/BrainTerminalGui.java | 2 +- .../device/brainduck/terminal/DeviceImpl.java | 2 +- .../device/brainduck/terminal/io/Cursor.java | 2 +- .../device/brainduck/terminal/io/Display.java | 2 +- .../brainduck/terminal/io/FileIOProvider.java | 2 +- .../brainduck/terminal/io/GUIUtils.java | 2 +- .../brainduck/terminal/io/IOProvider.java | 2 +- .../brainduck/terminal/io/InputProvider.java | 2 +- .../brainduck/terminal/io/Keyboard.java | 2 +- .../brainduck/terminal/io/OutputProvider.java | 2 +- .../brainduck/terminal/version.properties | 2 +- .../brainduck/terminal/DeviceImplTest.java | 18 +++++++++++++++++ plugins/device/simhPseudo-z80/build.gradle | 2 +- .../plugins/device/simh/DeviceImpl.java | 2 +- .../plugins/device/simh/PseudoContext.java | 2 +- .../plugins/device/simh/version.properties | 2 +- .../plugins/device/simh/DeviceImplTest.java | 18 +++++++++++++++++ plugins/device/ssem-display/build.gradle | 2 +- .../device/ssem/display/DeviceImpl.java | 2 +- .../device/ssem/display/DisplayGui.java | 2 +- .../device/ssem/display/DisplayPanel.java | 2 +- .../device/ssem/display/version.properties | 2 +- .../device/ssem/display/DeviceImplTest.java | 18 +++++++++++++++++ plugins/memory/byte-mem/build.gradle | 2 +- .../memory/bytemem/MemoryContextImpl.java | 2 +- .../plugins/memory/bytemem/MemoryImpl.java | 2 +- .../plugins/memory/bytemem/RangeTree.java | 2 +- .../memory/bytemem/api/ByteMemoryContext.java | 2 +- .../plugins/memory/bytemem/gui/Constants.java | 18 +++++++++++++++++ .../bytemem/gui/FindSequenceDialog.java | 2 +- .../memory/bytemem/gui/KeyboardHandler.java | 2 +- .../plugins/memory/bytemem/gui/MemoryGui.java | 2 +- .../memory/bytemem/gui/SettingsDialog.java | 2 +- .../gui/actions/FindSequenceAction.java | 18 +++++++++++++++++ .../bytemem/gui/model/FileImagesModel.java | 2 +- .../bytemem/gui/model/MemoryTableModel.java | 2 +- .../memory/bytemem/gui/model/ROMmodel.java | 2 +- .../memory/bytemem/gui/model/TableMemory.java | 2 +- .../plugins/memory/bytemem/version.properties | 2 +- .../memory/bytemem/MemoryImplTest.java | 18 +++++++++++++++++ .../plugins/memory/bytemem/RangeTreeTest.java | 2 +- plugins/memory/ram-mem/build.gradle | 2 +- .../plugins/memory/ram/MemoryContextImpl.java | 2 +- .../plugins/memory/ram/MemoryImpl.java | 2 +- .../memory/ram/api/RAMInstruction.java | 2 +- .../plugins/memory/ram/api/RAMLabel.java | 18 +++++++++++++++++ .../memory/ram/api/RAMMemoryContext.java | 2 +- .../plugins/memory/ram/api/RAMValue.java | 18 +++++++++++++++++ .../plugins/memory/ram/gui/Constants.java | 18 +++++++++++++++++ .../plugins/memory/ram/gui/MemoryDialog.java | 2 +- .../plugins/memory/ram/gui/RAMTableModel.java | 2 +- .../plugins/memory/ram/version.properties | 2 +- .../memory/ram/MemoryContextImplTest.java | 18 +++++++++++++++++ .../plugins/memory/ram/MemoryImplTest.java | 18 +++++++++++++++++ plugins/memory/rasp-mem/build.gradle | 2 +- .../memory/rasp/MemoryContextImpl.java | 2 +- .../plugins/memory/rasp/MemoryImpl.java | 2 +- .../plugins/memory/rasp/api/RASPLabel.java | 18 +++++++++++++++++ .../memory/rasp/api/RASPMemoryCell.java | 18 +++++++++++++++++ .../memory/rasp/api/RASPMemoryContext.java | 2 +- .../plugins/memory/rasp/gui/Disassembler.java | 18 +++++++++++++++++ .../plugins/memory/rasp/gui/MemoryDialog.java | 2 +- .../memory/rasp/gui/RASPTableModel.java | 2 +- .../plugins/memory/rasp/version.properties | 2 +- .../plugins/memory/rasp/MemoryImplTest.java | 18 +++++++++++++++++ plugins/memory/ssem-mem/build.gradle | 2 +- .../memory/ssem/MemoryContextImpl.java | 2 +- .../plugins/memory/ssem/MemoryImpl.java | 2 +- .../plugins/memory/ssem/gui/CellEditor.java | 2 +- .../plugins/memory/ssem/gui/CellRenderer.java | 2 +- .../plugins/memory/ssem/gui/Constants.java | 2 +- .../plugins/memory/ssem/gui/MemoryGui.java | 2 +- .../plugins/memory/ssem/gui/MemoryTable.java | 2 +- .../memory/ssem/gui/MemoryTableModel.java | 2 +- .../memory/ssem/gui/RowHeaderRenderer.java | 2 +- .../plugins/memory/ssem/version.properties | 2 +- .../memory/ssem/MemoryContextImplTest.java | 2 +- .../plugins/memory/ssem/MemoryImplTest.java | 2 +- .../memory/ssem/gui/MemoryTableModelTest.java | 2 +- settings.gradle | 2 +- 617 files changed, 4718 insertions(+), 382 deletions(-) diff --git a/application/src/main/files/logback.xml b/application/src/main/files/logback.xml index 3d2cae379..5f71b09a0 100644 --- a/application/src/main/files/logback.xml +++ b/application/src/main/files/logback.xml @@ -1,7 +1,7 @@ + diff --git a/plugins/device/88-dcdd/src/main/files/examples/altair8800/cpm-formats.toml b/plugins/device/88-dcdd/src/main/files/examples/altair8800/cpm-formats.toml index 08b4424c5..032263f0e 100644 --- a/plugins/device/88-dcdd/src/main/files/examples/altair8800/cpm-formats.toml +++ b/plugins/device/88-dcdd/src/main/files/examples/altair8800/cpm-formats.toml @@ -1,13 +1,7 @@ -[[format]] -# Altair 8" floppy disks -# CP/M 1.4; simh BIOS -# -# https://retrocmp.de/hardware/altair-8800/altair-floppy.htm -# https://altairclone.com/downloads/roms/M%20Eberhard%20Improved%20ROMs/CDBL%20Manual.pdf -# https://deramp.com/downloads/mfe_archive/010-S100%20Computers%20and%20Boards/00-MITS/40-Software/DSK%20Disk%20Images/Altair%20cpm%20Disk%20Images/Burcon%20(MITS)%20CPM.pdf +# Altair 8" floppy for SIMH CP/M 1.4 # -# Tested on: # cpm1.dsk https://schorn.ch/cpm/zip/cpm1.zip +[[format]] id = 'cpm1-simh' sectorSize = 137 sectorSkew = 6 @@ -22,23 +16,14 @@ bsh = 3 # or blm = 7 dsm = 242 drm = 63 -al0 = 0xC0 # 11000000 00000000 +al0 = 0xC0 al1 = 0 ofs = 2 - - -[[format]] -# Altair 8" floppy disks -# CP/M 2.2; simh BIOS -# -# https://retrocmp.de/hardware/altair-8800/altair-floppy.htm -# https://altairclone.com/downloads/roms/M%20Eberhard%20Improved%20ROMs/CDBL%20Manual.pdf -# https://deramp.com/downloads/mfe_archive/010-S100%20Computers%20and%20Boards/00-MITS/40-Software/DSK%20Disk%20Images/Altair%20cpm%20Disk%20Images/Burcon%20(MITS)%20CPM.pdf +# Altair 8" floppy disks for SIMH CP/M 2.2 # -# Tested on: # altcpm.dsk http://cpmarchives.classiccmp.org/cpm/mirrors/www.schorn.ch/cpm/zip/altsw.zip -# +[[format]] id = 'cpm2-simh' sectorSize = 137 sectorSkew = 17 @@ -57,22 +42,14 @@ al0 = 0xFF al1 = 0 ofs = 6 -[[format]] -# Altair 8" floppy disks -# CP/M 3; simh BIOS -# -# https://retrocmp.de/hardware/altair-8800/altair-floppy.htm -# https://altairclone.com/downloads/roms/M%20Eberhard%20Improved%20ROMs/CDBL%20Manual.pdf -# https://deramp.com/downloads/mfe_archive/010-S100%20Computers%20and%20Boards/00-MITS/40-Software/DSK%20Disk%20Images/Altair%20cpm%20Disk%20Images/Burcon%20(MITS)%20CPM.pdf -# -# Tested on: +# Altair 8" floppy for SIMH CP/M 3 # # cpm3.dsk https://schorn.ch/cpm/zip/cpm3.zip # z80dos.dsk https://schorn.ch/cpm/zip/z80dos.zip # zsdos.dsk https://schorn.ch/cpm/zip/zsdos.zip # superdos.dsk https://schorn.ch/cpm/zip/superdos.zip # cpm1dev.dsk https://schorn.ch/cpm/zip/cpm1.zip - +[[format]] id = 'cpm3-simh' sectorSize = 137 sectorSkew = 17 @@ -91,24 +68,15 @@ al0 = 0xF0 al1 = 0 ofs = 6 -[[format]] -# Altair 8" floppy disks -# CP/M 2.2; simh ZSDOS BIOS (https://www.seasip.info/Cpm/dosses.html) - -# Timestamps are supported by a loadable module, so either the CP/M 3 style or the DateStamper -# style can be used. +# Altair 8" floppy for SIMH CP/M 2.2 with ZSDOS BIOS (https://www.seasip.info/Cpm/dosses.html) # -# Tested on: # zsdos.dsk https://schorn.ch/cpm/zip/zsdos.zip - +[[format]] id = 'cpm2-zsdos-simh' sectorSize = 137 sectorSkew = 17 sectorOps = 'altair-floppy-mits' bcInterpretsAsUnused = false - -# 21 C1 C1 C1 C1 M1 M1 M1 M1 00 00 C2 C2 C2 C2 M2 -# M2 M2 M2 00 00 C3 C3 C3 C3 M3 M3 M3 M3 00 00 00 dateFormat = 'NATIVE2' [format.dpb] @@ -122,28 +90,22 @@ al0 = 0xF0 al1 = 0 ofs = 6 -[[format]] -# Altair 8" floppy disks, 77 tracks -# https://deramp.com/downloads/altair/hardware/8_inch_floppy/ -# https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%203.0/BIOS.ASM -# https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%203.0/ReadMe.pdf -# -# Tested on: +# Altair 8" floppy for DeRamp CP/M 3 # +# MITS Tapes.dsk https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%202.2/Altair%20Cassette%20Disk/MITS%20Tapes.dsk +# cpm3_v1.0_48K_disk1.dsk https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%203.0/cpm3_v1.0_48K_disk1.dsk +# cpm3_v1.0_56k_build.dsk https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%203.0/cpm3_v1.0_56k_build.dsk +# cpm3_v1.0_56K_disk1.dsk https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%203.0/cpm3_v1.0_56K_disk1.dsk +# cpm3_v1.0_56k_disk2.dsk https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%203.0/cpm3_v1.0_56k_disk2.dsk +# CPM22AT11-24K.DSK https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%202.2/CPM%202.2AT%20(Altair%20and%20Tarbell%20FDCs%20together)/CPM22AT11-24K.DSK + +[[format]] id = 'cpm3-altair8-deramp' sectorSize = 137 -#sectorSkew = 17 - -# The skew is based on the track as: -# Tracks 0-5, secOut = secIn -# Tracks 6-76, secOut = (secIn * 17) MOD 32 -# The skew computation for tracks 6-76 is implemented as: -# secOut = secIn if secIn is even -# secOut = secIn XOR 10h if secIn is odd -sectorSkewTable = [0, 17, 2, 19, 4, 21, 6, 23, 8, 25, 10, 27, 12, 29, 14, 31, 16, 1, 18, 3, 20, 5, 22, 7, 24, 9, 26, 11, 28, 13, 30, 15] -sectorOps = 'altair-floppy-deramp' +sectorSkew = 17 +sectorOps = 'altair-floppy-mits' bcInterpretsAsUnused = false -dateFormat = 'NATIVE2' +dateFormat = 'NOT_USED' [format.dpb] driveSpt = 32 @@ -156,39 +118,3 @@ al0 = 0xC0 al1 = 0 ofs = 2 -#RESTRK equ 2 ;reserved tracks for boot image - -[[format]] -# Altair 5.25" minidisk, 35 tracks -# https://deramp.com/downloads/altair/hardware/minidisk/ -# https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%203.0/BIOS.ASM -# https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%203.0/ReadMe.pdf -# -# Tested on: -# -id = 'cpm3-minidisk-deramp' -sectorSize = 137 -#sectorSkew = 17 - -# The skew is based on the track as: -# Tracks 0-5, secOut = secIn -# Tracks 6-76, secOut = (secIn * 17) MOD 32 -# The skew computation for tracks 6-76 is implemented as: -# secOut = secIn if secIn is even -# secOut = secIn XOR 10h if secIn is odd -sectorSkewTable = [0, 17, 2, 19, 4, 21, 6, 23, 8, 25, 10, 27, 12, 29, 14, 31, 16, 1, 18, 3, 20, 5, 22, 7, 24, 9, 26, 11, 28, 13, 30, 15] -sectorOps = 'altair-minidisk-deramp' -bcInterpretsAsUnused = false -dateFormat = 'NATIVE2' - -[format.dpb] -driveSpt = 16 -spt = 16 -bsh = 3 -# or blm = 7 -dsm = 61 # max block number (62 blocks of 1K bytes) -drm = 31 # max directory entry number (32 entries) -al0 = 0x80 -al1 = 0 -ofs = 4 -#RESTRK equ 4 ;reserved tracks for boot image diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DriveIO.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DriveIO.java index 19993d50c..e19cb05ea 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DriveIO.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DriveIO.java @@ -47,7 +47,7 @@ public class DriveIO implements AutoCloseable { private final FileChannel channel; public DriveIO(Path imageFile, CpmFormat cpmFormat, OpenOption... openOptions) throws IOException { - this.cpmFormat = Objects.requireNonNull(cpmFormat); + this.cpmFormat = Objects.requireNonNull(cpmFormat, "CP/M format is required"); this.sectorOps = cpmFormat.sectorOps; this.channel = FileChannel.open(Objects.requireNonNull(imageFile, "Image file is not set"), openOptions); } @@ -82,7 +82,6 @@ public ByteBuffer readRecord(Position position) throws IOException { public void writeRecord(Position position, ByteBuffer data) throws IOException { ByteBuffer sector = sectorOps.toSector(data, position); channel.position(cpmFormat.positionToOffset(position)); - int expected = sector.remaining(); if (channel.write(sector) != expected) { throw new IOException("Could not write whole sector! (" + position + ")"); From 255cbbb797b6acdce8e3c7196a4c040a0284bc8d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 13 Jul 2022 09:40:39 +0100 Subject: [PATCH 172/314] [#234] Rewrite 8080 edigen according to z80 --- plugins/cpu/8080-cpu/src/main/edigen/cpu.eds | 219 +++++++++++++------ 1 file changed, 156 insertions(+), 63 deletions(-) diff --git a/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds b/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds index e79c6ba02..370c8325d 100644 --- a/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds @@ -19,70 +19,163 @@ root instruction; -instruction = "nop": 00000000 | "xchg": 0xEB | "sphl": 0xF9 | "xthl": 0xE3 | "daa": 0x27 | "cma": 0x2F | "rlc": 00000111 | "rrc": 00001111 | "ral": 0x17 | "rar": 0x1F | "stc": 0x37 | "cmc": 0x3F | - "pchl": 0xE9 | "ret": 0xC9 | "rnz": 0xC0 | "rz": 0xC8 | "rnc": 0xD0 | "rc": 0xD8 | "rpo": 0xE0 | "rpe": 0xE8 | "rp": 0xF0 | "rm": 0xF8 | "ei": 0xFB | "di": 0xF3 | "hlt": 0x76 | - - "ldax": 000 BCDE(1) 1010 | "stax": 000 BCDE(1) 0010 | "pop": 110 BCDE(1) 0001 | "push": 110 BCDE(1) 0101 | "dad": 000 BCDE(1) 1001 | "inx": 000 BCDE(1) 0011 | "dcx": 000 BCDE(1) 1011 | - - "dad": 001 HLSP(1) 1001 | "inx": 001 HLSP(1) 0011 | "dcx": 001 HLSP(1) 1011 | - - "pop": 111 HLPSW(1) 0001 | "push": 111 HLPSW(1) 0101 | - - "lxi": 000 BCDE(1) 0001 imm16 | - - "lxi": 001 HLSP(1) 0001 imm16 | - - "lda": 0x3A imm16 | "sta": 0x32 imm16 | "lhld": 0x2A imm16 | "shld": 0x22 imm16 | "jmp": 0xC3 imm16 | "jnz": 0xC2 imm16 | "jz": 0xCA imm16 | "jnc": 0xD2 imm16 | "jc": 0xDA imm16 | - "jpo": 0xE2 imm16 | "jpe": 0xEA imm16 | "jp": 0xF2 imm16 | "jm": 0xFA imm16 | "call": 0xCD imm16 | "cnz": 0xC4 imm16 | "cz": 0xCC imm16 | "cnc": 0xD4 imm16 | "cc": 0xDC imm16 | - "cpo": 0xE4 imm16 | "cpe": 0xEC imm16 | "cp": 0xF4 imm16 | "cm": 0xFC imm16 | - - "mvi": 00 REG(3) 110 imm8 | - - "inr": 00 REG(3) 100 | "dcr": 00 REG(3) 101 | "add": 0x8 0 REG | "adc": 0x8 1 REG | "sub": 0x9 0 REG | "sbb": 0x9 1 REG | "ana": 0xA 0 REG | "xra": 0xA 1 REG | "ora": 0xB 0 REG | - "cmp": 0xB 1 REG | - - "in": 0xDB imm8 | "out": 0xD3 imm8 | "adi": 0xC6 imm8 | "aci": 0xCE imm8 | "sui": 0xD6 imm8 | "sbi": 0xDE imm8 | "cpi": 0xFE imm8 | "ani": 0xE6 imm8 | "ori": 0xF6 imm8 | "xri": 0xEE imm8 | - - "rst": 11 NUMBER(3) 111 | - - "mov": 010 REG_BCDE(2) REG | - "mov": 0110 REG_HL(1) REG | - "mov": 01 REG_A[111](3) REG | - - "mov": 011100 REG_BCDE | - "mov": 0111010 REG_HL | - "mov": 01110 REG_A[111](3); - -BCDE = "BC" : 0 | "DE" : 1; -HLSP = "HL" : 0 | "SP" : 1; -HLPSW = "HL" : 0 | "PSW" : 1; -REG = "B": 000 | "C": 001 | "D": 010 | "E": 011 | "H": 100 | "L": 101 | "M": 110 | "A": 111; - -REG_BCDE = "B": 00 | "C": 01 | "D": 10 | "E": 11; -REG_HL = "H": 0 | "L": 1; -REG_A = "A": 111; - -NUMBER = number: number(3); -imm8 = imm8: imm8(8); -imm16 = imm16: imm16(16); +# inspired by http://www.z80.info/decoding.htm +# converted using https://pastraiser.com/cpu/i8080/i8080_opcodes.html and https://clrhome.org/table/ +instruction = + "nop": 00 000 000 | # x=0, y=0, z=0 (*) + "lxi %s, %X": 00 rp(2) 0 001 imm16 | # x=0, p=rp, q=0, z=1 (*) + "dad %s": 00 rp(2) 1 001 | # x=0, p=rp, q=1, z=1 (*) + "stax b": 00 000 010 | # x=0, p=0, q=0, z=2 (*) + "stax d": 00 010 010 | # x=0, p=1, q=0, z=2 (*) + "shld %X": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 (*) + "sta %X": 00 110 010 ref16 | # x=0, p=3, q=0, z=2 (*) + "ldax b": 00 001 010 | # x=0, p=0, q=1, z=2 (*) + "ldax d": 00 011 010 | # x=0, p=1, q=1, z=2 (*) + "lhld %X": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 (*) + "lda %X": 00 111 010 ref16 | # x=0, p=3, q=1, z=2 (*) + "inx %s": 00 rp(2) 0 011 | # x=0, p=rp, q=0, z=3 (*) + "dcx %s": 00 rp(2) 1 011 | # x=0, p=rp, q=1, z=3 (*) + "inr %s": 00 r(3) 100 | # x=0, y=r, z=4 (*) + "dcr %s": 00 r(3) 101 | # x=0, y=r, z=5 (*) + "mvi %s, %X": 00 r(3) 110 imm8 | # x=0, y=r, z=6 (*) + "rlc": 00 000 111 | # x=0, y=0, z=7 (*) + "rrc": 00 001 111 | # x=0, y=1, z=7 (*) + "ral": 00 010 111 | # x=0, y=2, z=7 (*) + "rar": 00 011 111 | # x=0, y=3, z=7 (*) + "daa": 00 100 111 | # x=0, y=4, z=7 (*) + "cma": 00 101 111 | # x=0, y=5, z=7 (*) + "stc": 00 110 111 | # x=0, y=6, z=7 (*) + "cmc": 00 111 111 | # x=0, y=7, z=7 (*) + + "hlt": 01 110 110 | # x=1, y=6, z=6 (*) + "mov %s, %s": 01 0 r_bcde(2) r(3) | # x=1, y=0 r_bcde, z=r (*) + "mov %s, %s": 01 10 r_h_l(1) r(3) | # x=1, y=10 r_h_l, z=r (*) + "mov a, %s": 01 111 r(3) | # x=1, y=7, z=r (*) + "mov m, %s": 01 110 0 r_bcde(2) | # x=1, y=6, z=0 r_bcde (*) + "mov m, %s": 01 110 10 r_h_l(1) | # x=1, y=6, z=10 r_h_l (*) + "mov m, a": 01 110 111 | # x=1, y=6, z=7 (*) + + "%s %s": 10 alu(3) r(3) | # x=2, y=alu, z=r (*) + + "rnz": 11 000 000 | # x=3, y=0, z=0 (*) + "rz": 11 001 000 | # x=3, y=1, z=0 (*) + "rnc": 11 010 000 | # x=3, y=2, z=0 (*) + "rc": 11 011 000 | # x=3, y=3, z=0 (*) + "rpo": 11 100 000 | # x=3, y=4, z=0 (*) + "rpe": 11 101 000 | # x=3, y=5, z=0 (*) + "rp": 11 110 000 | # x=3, y=6, z=0 (*) + "rm": 11 111 000 | # x=3, y=7, z=0 (*) + + "pop %s": 11 rp2(2) 0 001 | # x=3, p=rp2, q=0, z=1 (*) + "ret": 11 001 001 | # x=3, p=0, q=1, z=1 (*) + "pchl": 11 101 001 | # x=3, p=2, q=1, z=1 (*) + "sphl": 11 111 001 | # x=3, p=3, q=1, z=1 (*) + + "jnz %X": 11 000 010 imm16 | # x=3, y=0, z=2 (*) + "jz %X": 11 001 010 imm16 | # x=3, y=1, z=2 (*) + "jnc %X": 11 010 010 imm16 | # x=3, y=2, z=2 (*) + "jc %X": 11 011 010 imm16 | # x=3, y=3, z=2 (*) + "jpo %X": 11 100 010 imm16 | # x=3, y=4, z=2 (*) + "jpe %X": 11 101 010 imm16 | # x=3, y=5, z=2 (*) + "jp %X": 11 110 010 imm16 | # x=3, y=6, z=2 (*) + "jm %X": 11 111 010 imm16 | # x=3, y=7, z=2 (*) + + "jmp %X": 11 000 011 imm16 | # x=3, y=0, z=3 (*) + + "out %X": 11 010 011 ref8 | # x=3, y=2, z=3 (*) + "in %X": 11 011 011 ref8 | # x=3, y=3, z=3 (*) + "xthl": 11 100 011 | # x=3, y=4, z=3 (*) + "xchg": 11 101 011 | # x=3, y=5, z=3 (*) + "di": 11 110 011 | # x=3, y=6, z=3 (*) + "ei": 11 111 011 | # x=3, y=7, z=3 (*) + + "cnz %X": 11 000 100 imm16 | # x=3, y=0, z=4 (*) + "cz %X": 11 001 100 imm16 | # x=3, y=1, z=4 (*) + "cnc %X": 11 010 100 imm16 | # x=3, y=2, z=4 (*) + "cc %X": 11 011 100 imm16 | # x=3, y=3, z=4 (*) + "cpo %X": 11 100 100 imm16 | # x=3, y=4, z=4 (*) + "cpe %X": 11 101 100 imm16 | # x=3, y=5, z=4 (*) + "cp %X": 11 110 100 imm16 | # x=3, y=6, z=4 (*) + "cm %X": 11 111 100 imm16 | # x=3, y=7, z=4 (*) + + "push %s": 11 rp2(2) 0 101 | # x=3, p=rp2, q=0, z=5 (*) + "call %X": 11 001 101 imm16 | # x=3, p=0, q=1, z=5 (*) + + "%s %X": 11 alui(3) 110 imm8 | # x=3, y=alu, z=6 (*) + "rst %X": 11 rst(3) 111 ; # x=3, y=rst, z=7 (*) + + +alu = + "add": 000 | + "adc": 001 | + "sub": 010 | + "sbb": 011 | + "ana": 100 | + "xra": 101 | + "ora": 110 | + "cmp": 111 ; + +alui = + "adi": 000 | + "aci": 001 | + "sui": 010 | + "sbi": 011 | + "ani": 100 | + "xri": 101 | + "ori": 110 | + "cpi": 111 ; + +rp = + "b": 00 | + "d": 01 | + "h": 10 | + "sp": 11 ; + +rp2 = + "b": 00 | + "d": 01 | + "h": 10 | + "psw": 11 ; + +r = + "b": 000 | + "c": 001 | + "d": 010 | + "e": 011 | + "h": 100 | + "l": 101 | + "m": 110 | + "a": 111 ; + +r_bcde = + "b": 00 | + "c": 01 | + "d": 10 | + "e": 11 ; + +r_h_l = + "h": 0 | + "l": 1 ; + +imm8,ref8 = imm8: imm8(8); +imm16,ref16 = imm16: imm16(16); +rst = rst: rst(3); %% -"%s %s, %s" = instruction REG_BCDE REG; -"%s %s, %s" = instruction REG_HL REG; -"%s %s, %s" = instruction REG_A REG; -"%s M, %s" = instruction REG_BCDE; -"%s M, %s" = instruction REG_HL; -"%s M, %s" = instruction REG_A; -"%s %d" = instruction NUMBER; -"%s %s, %X" = instruction REG imm8; -"%s %s" = instruction REG; -"%s %X" = instruction imm8; -"%s %s, %X" = instruction BCDE imm16; -"%s %s, %X" = instruction HLSP imm16; -"%s %s" = instruction HLPSW; -"%s %s" = instruction HLSP; -"%s %s" = instruction BCDE; -"%s %X" = instruction imm16; +"%s" = instruction rp imm16(reverse_bytes); +"%s" = instruction r_bcde r; +"%s" = instruction r_h_l r; +"%s" = instruction r imm8; +"%s" = instruction alu r; +"%s" = instruction alui imm8; +"%s" = instruction r_bcde; +"%s" = instruction r_h_l; +"%s" = instruction ref8; +"%s" = instruction imm16(reverse_bytes); +"%s" = instruction ref16(reverse_bytes); +"%s" = instruction rp; +"%s" = instruction rp2; +"%s" = instruction r; +"%s" = instruction rst; "%s" = instruction; - From fccd7ef30fa4a41b4f605bf7d7640d873a2454df Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 13 Jul 2022 09:42:11 +0100 Subject: [PATCH 173/314] [#234] removed comments --- plugins/cpu/8080-cpu/src/main/edigen/cpu.eds | 162 +++++++++---------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds b/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds index 370c8325d..af1ac22c1 100644 --- a/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds @@ -22,87 +22,87 @@ root instruction; # inspired by http://www.z80.info/decoding.htm # converted using https://pastraiser.com/cpu/i8080/i8080_opcodes.html and https://clrhome.org/table/ instruction = - "nop": 00 000 000 | # x=0, y=0, z=0 (*) - "lxi %s, %X": 00 rp(2) 0 001 imm16 | # x=0, p=rp, q=0, z=1 (*) - "dad %s": 00 rp(2) 1 001 | # x=0, p=rp, q=1, z=1 (*) - "stax b": 00 000 010 | # x=0, p=0, q=0, z=2 (*) - "stax d": 00 010 010 | # x=0, p=1, q=0, z=2 (*) - "shld %X": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 (*) - "sta %X": 00 110 010 ref16 | # x=0, p=3, q=0, z=2 (*) - "ldax b": 00 001 010 | # x=0, p=0, q=1, z=2 (*) - "ldax d": 00 011 010 | # x=0, p=1, q=1, z=2 (*) - "lhld %X": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 (*) - "lda %X": 00 111 010 ref16 | # x=0, p=3, q=1, z=2 (*) - "inx %s": 00 rp(2) 0 011 | # x=0, p=rp, q=0, z=3 (*) - "dcx %s": 00 rp(2) 1 011 | # x=0, p=rp, q=1, z=3 (*) - "inr %s": 00 r(3) 100 | # x=0, y=r, z=4 (*) - "dcr %s": 00 r(3) 101 | # x=0, y=r, z=5 (*) - "mvi %s, %X": 00 r(3) 110 imm8 | # x=0, y=r, z=6 (*) - "rlc": 00 000 111 | # x=0, y=0, z=7 (*) - "rrc": 00 001 111 | # x=0, y=1, z=7 (*) - "ral": 00 010 111 | # x=0, y=2, z=7 (*) - "rar": 00 011 111 | # x=0, y=3, z=7 (*) - "daa": 00 100 111 | # x=0, y=4, z=7 (*) - "cma": 00 101 111 | # x=0, y=5, z=7 (*) - "stc": 00 110 111 | # x=0, y=6, z=7 (*) - "cmc": 00 111 111 | # x=0, y=7, z=7 (*) - - "hlt": 01 110 110 | # x=1, y=6, z=6 (*) - "mov %s, %s": 01 0 r_bcde(2) r(3) | # x=1, y=0 r_bcde, z=r (*) - "mov %s, %s": 01 10 r_h_l(1) r(3) | # x=1, y=10 r_h_l, z=r (*) - "mov a, %s": 01 111 r(3) | # x=1, y=7, z=r (*) - "mov m, %s": 01 110 0 r_bcde(2) | # x=1, y=6, z=0 r_bcde (*) - "mov m, %s": 01 110 10 r_h_l(1) | # x=1, y=6, z=10 r_h_l (*) - "mov m, a": 01 110 111 | # x=1, y=6, z=7 (*) - - "%s %s": 10 alu(3) r(3) | # x=2, y=alu, z=r (*) - - "rnz": 11 000 000 | # x=3, y=0, z=0 (*) - "rz": 11 001 000 | # x=3, y=1, z=0 (*) - "rnc": 11 010 000 | # x=3, y=2, z=0 (*) - "rc": 11 011 000 | # x=3, y=3, z=0 (*) - "rpo": 11 100 000 | # x=3, y=4, z=0 (*) - "rpe": 11 101 000 | # x=3, y=5, z=0 (*) - "rp": 11 110 000 | # x=3, y=6, z=0 (*) - "rm": 11 111 000 | # x=3, y=7, z=0 (*) - - "pop %s": 11 rp2(2) 0 001 | # x=3, p=rp2, q=0, z=1 (*) - "ret": 11 001 001 | # x=3, p=0, q=1, z=1 (*) - "pchl": 11 101 001 | # x=3, p=2, q=1, z=1 (*) - "sphl": 11 111 001 | # x=3, p=3, q=1, z=1 (*) - - "jnz %X": 11 000 010 imm16 | # x=3, y=0, z=2 (*) - "jz %X": 11 001 010 imm16 | # x=3, y=1, z=2 (*) - "jnc %X": 11 010 010 imm16 | # x=3, y=2, z=2 (*) - "jc %X": 11 011 010 imm16 | # x=3, y=3, z=2 (*) - "jpo %X": 11 100 010 imm16 | # x=3, y=4, z=2 (*) - "jpe %X": 11 101 010 imm16 | # x=3, y=5, z=2 (*) - "jp %X": 11 110 010 imm16 | # x=3, y=6, z=2 (*) - "jm %X": 11 111 010 imm16 | # x=3, y=7, z=2 (*) - - "jmp %X": 11 000 011 imm16 | # x=3, y=0, z=3 (*) - - "out %X": 11 010 011 ref8 | # x=3, y=2, z=3 (*) - "in %X": 11 011 011 ref8 | # x=3, y=3, z=3 (*) - "xthl": 11 100 011 | # x=3, y=4, z=3 (*) - "xchg": 11 101 011 | # x=3, y=5, z=3 (*) - "di": 11 110 011 | # x=3, y=6, z=3 (*) - "ei": 11 111 011 | # x=3, y=7, z=3 (*) - - "cnz %X": 11 000 100 imm16 | # x=3, y=0, z=4 (*) - "cz %X": 11 001 100 imm16 | # x=3, y=1, z=4 (*) - "cnc %X": 11 010 100 imm16 | # x=3, y=2, z=4 (*) - "cc %X": 11 011 100 imm16 | # x=3, y=3, z=4 (*) - "cpo %X": 11 100 100 imm16 | # x=3, y=4, z=4 (*) - "cpe %X": 11 101 100 imm16 | # x=3, y=5, z=4 (*) - "cp %X": 11 110 100 imm16 | # x=3, y=6, z=4 (*) - "cm %X": 11 111 100 imm16 | # x=3, y=7, z=4 (*) - - "push %s": 11 rp2(2) 0 101 | # x=3, p=rp2, q=0, z=5 (*) - "call %X": 11 001 101 imm16 | # x=3, p=0, q=1, z=5 (*) - - "%s %X": 11 alui(3) 110 imm8 | # x=3, y=alu, z=6 (*) - "rst %X": 11 rst(3) 111 ; # x=3, y=rst, z=7 (*) + "nop": 00 000 000 | # x=0, y=0, z=0 + "lxi %s, %X": 00 rp(2) 0 001 imm16 | # x=0, p=rp, q=0, z=1 + "dad %s": 00 rp(2) 1 001 | # x=0, p=rp, q=1, z=1 + "stax b": 00 000 010 | # x=0, p=0, q=0, z=2 + "stax d": 00 010 010 | # x=0, p=1, q=0, z=2 + "shld %X": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 + "sta %X": 00 110 010 ref16 | # x=0, p=3, q=0, z=2 + "ldax b": 00 001 010 | # x=0, p=0, q=1, z=2 + "ldax d": 00 011 010 | # x=0, p=1, q=1, z=2 + "lhld %X": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 + "lda %X": 00 111 010 ref16 | # x=0, p=3, q=1, z=2 + "inx %s": 00 rp(2) 0 011 | # x=0, p=rp, q=0, z=3 + "dcx %s": 00 rp(2) 1 011 | # x=0, p=rp, q=1, z=3 + "inr %s": 00 r(3) 100 | # x=0, y=r, z=4 + "dcr %s": 00 r(3) 101 | # x=0, y=r, z=5 + "mvi %s, %X": 00 r(3) 110 imm8 | # x=0, y=r, z=6 + "rlc": 00 000 111 | # x=0, y=0, z=7 + "rrc": 00 001 111 | # x=0, y=1, z=7 + "ral": 00 010 111 | # x=0, y=2, z=7 + "rar": 00 011 111 | # x=0, y=3, z=7 + "daa": 00 100 111 | # x=0, y=4, z=7 + "cma": 00 101 111 | # x=0, y=5, z=7 + "stc": 00 110 111 | # x=0, y=6, z=7 + "cmc": 00 111 111 | # x=0, y=7, z=7 + + "hlt": 01 110 110 | # x=1, y=6, z=6 + "mov %s, %s": 01 0 r_bcde(2) r(3) | # x=1, y=0 r_bcde, z=r + "mov %s, %s": 01 10 r_h_l(1) r(3) | # x=1, y=10 r_h_l, z=r + "mov a, %s": 01 111 r(3) | # x=1, y=7, z=r + "mov m, %s": 01 110 0 r_bcde(2) | # x=1, y=6, z=0 r_bcde + "mov m, %s": 01 110 10 r_h_l(1) | # x=1, y=6, z=10 r_h_l + "mov m, a": 01 110 111 | # x=1, y=6, z=7 + + "%s %s": 10 alu(3) r(3) | # x=2, y=alu, z=r + + "rnz": 11 000 000 | # x=3, y=0, z=0 + "rz": 11 001 000 | # x=3, y=1, z=0 + "rnc": 11 010 000 | # x=3, y=2, z=0 + "rc": 11 011 000 | # x=3, y=3, z=0 + "rpo": 11 100 000 | # x=3, y=4, z=0 + "rpe": 11 101 000 | # x=3, y=5, z=0 + "rp": 11 110 000 | # x=3, y=6, z=0 + "rm": 11 111 000 | # x=3, y=7, z=0 + + "pop %s": 11 rp2(2) 0 001 | # x=3, p=rp2, q=0, z=1 + "ret": 11 001 001 | # x=3, p=0, q=1, z=1 + "pchl": 11 101 001 | # x=3, p=2, q=1, z=1 + "sphl": 11 111 001 | # x=3, p=3, q=1, z=1 + + "jnz %X": 11 000 010 imm16 | # x=3, y=0, z=2 + "jz %X": 11 001 010 imm16 | # x=3, y=1, z=2 + "jnc %X": 11 010 010 imm16 | # x=3, y=2, z=2 + "jc %X": 11 011 010 imm16 | # x=3, y=3, z=2 + "jpo %X": 11 100 010 imm16 | # x=3, y=4, z=2 + "jpe %X": 11 101 010 imm16 | # x=3, y=5, z=2 + "jp %X": 11 110 010 imm16 | # x=3, y=6, z=2 + "jm %X": 11 111 010 imm16 | # x=3, y=7, z=2 + + "jmp %X": 11 000 011 imm16 | # x=3, y=0, z=3 + + "out %X": 11 010 011 ref8 | # x=3, y=2, z=3 + "in %X": 11 011 011 ref8 | # x=3, y=3, z=3 + "xthl": 11 100 011 | # x=3, y=4, z=3 + "xchg": 11 101 011 | # x=3, y=5, z=3 + "di": 11 110 011 | # x=3, y=6, z=3 + "ei": 11 111 011 | # x=3, y=7, z=3 + + "cnz %X": 11 000 100 imm16 | # x=3, y=0, z=4 + "cz %X": 11 001 100 imm16 | # x=3, y=1, z=4 + "cnc %X": 11 010 100 imm16 | # x=3, y=2, z=4 + "cc %X": 11 011 100 imm16 | # x=3, y=3, z=4 + "cpo %X": 11 100 100 imm16 | # x=3, y=4, z=4 + "cpe %X": 11 101 100 imm16 | # x=3, y=5, z=4 + "cp %X": 11 110 100 imm16 | # x=3, y=6, z=4 + "cm %X": 11 111 100 imm16 | # x=3, y=7, z=4 + + "push %s": 11 rp2(2) 0 101 | # x=3, p=rp2, q=0, z=5 + "call %X": 11 001 101 imm16 | # x=3, p=0, q=1, z=5 + + "%s %X": 11 alui(3) 110 imm8 | # x=3, y=alu, z=6 + "rst %X": 11 rst(3) 111 ; # x=3, y=rst, z=7 alu = From 2ca21fe12886c59c2cfa0cd911fa430da8707af9 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 23 Jul 2022 01:24:43 +0100 Subject: [PATCH 174/314] [#175] Reimplemented simh pseudo device --- CODE_OF_CONDUCT.md | 2 +- LICENSE | 2 +- application/src/main/files/LICENSE | 2 +- .../src/main/examples/include/getchar.inc | 2 +- .../src/main/examples/square-root.ssem | 2 +- .../src/main/examples/include/getchar.inc | 2 +- .../src/main/examples/RAMinRASP.rasp | 8 +- .../src/main/examples/RASPinRAM.ram | 4 +- .../src/main/examples/factorial.rasp | 4 +- .../src/main/examples/simul_indir_adress.rasp | 4 +- .../plugins/cpu/intel8080/ContextImpl.java | 39 +- .../cpu/brainduck/BrainCPUContextImpl.java | 32 +- .../plugins/cpu/ram/RAMCpuContextImpl.java | 32 - .../plugins/cpu/ram/api/RAMCpuContext.java | 31 - .../plugins/cpu/rasp/api/RASPCpuContext.java | 28 - .../plugins/cpu/zilogZ80/ContextImpl.java | 23 +- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 98 ++- .../plugins/cpu/zilogZ80/gui/StatusPanel.java | 1 - .../cpu/zilogZ80/suite/CpuRunnerImpl.java | 2 +- .../cpu/zilogZ80/suite/CpuVerifierImpl.java | 2 +- .../plugins/device/simh/Commands.java | 92 +++ .../plugins/device/simh/CpmUtils.java | 35 ++ .../plugins/device/simh/DeviceImpl.java | 3 +- .../plugins/device/simh/PseudoContext.java | 566 +++--------------- .../device/simh/commands/AttachPTP.java | 31 + .../device/simh/commands/AttachPTR.java | 25 + .../plugins/device/simh/commands/Command.java | 56 ++ .../device/simh/commands/DetachPTP.java | 25 + .../device/simh/commands/DetachPTR.java | 25 + .../device/simh/commands/GenInterrupt.java | 39 ++ .../device/simh/commands/GetBankSelect.java | 27 + .../simh/commands/GetCPUClockFrequency.java | 40 ++ .../device/simh/commands/GetClockCPM3.java | 84 +++ .../device/simh/commands/GetClockZSDOS.java | 80 +++ .../device/simh/commands/GetCommon.java | 36 ++ .../simh/commands/GetHostFilenames.java | 118 ++++ .../simh/commands/GetHostOSPathSeparator.java | 25 + .../device/simh/commands/GetSimhVersion.java | 34 ++ .../device/simh/commands/HasBankedMemory.java | 27 + .../device/simh/commands/PrintTime.java | 25 + .../device/simh/commands/ReadStopWatch.java | 40 ++ .../plugins/device/simh/commands/ReadURL.java | 77 +++ .../device/simh/commands/ResetPTR.java | 25 + .../simh/commands/ResetSimhInterface.java | 27 + .../device/simh/commands/ResetStopWatch.java | 25 + .../device/simh/commands/SIMHSleep.java | 39 ++ .../device/simh/commands/Set8080CPU.java | 25 + .../device/simh/commands/SetBankSelect.java | 26 + .../simh/commands/SetCPUClockFrequency.java | 35 ++ .../device/simh/commands/SetClockCPM3.java | 67 +++ .../device/simh/commands/SetClockZSDOS.java | 59 ++ .../device/simh/commands/SetTimerDelta.java | 41 ++ .../simh/commands/SetTimerInterruptAdr.java | 35 ++ .../device/simh/commands/SetZ80CPU.java | 25 + .../device/simh/commands/ShowTimer.java | 30 + .../device/simh/commands/StartTimer.java | 34 ++ .../simh/commands/StartTimerInterrupts.java | 41 ++ .../device/simh/commands/StopTimer.java | 31 + .../simh/commands/StopTimerInterrupts.java | 25 + 59 files changed, 1683 insertions(+), 737 deletions(-) create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/Commands.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java create mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index e60f5cd59..b66226cb8 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -56,7 +56,7 @@ further defined and clarified by project maintainers. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at emustudio@googlegroups.com. All -complaints will be reviewed and investigated and will result in a response that +complaints will be reviewed and investigated and will control in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. diff --git a/LICENSE b/LICENSE index f288702d2..5eeb09b53 100644 --- a/LICENSE +++ b/LICENSE @@ -583,7 +583,7 @@ to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a +author or copyright holder as a control of your choosing to follow a later version. 15. Disclaimer of Warranty. diff --git a/application/src/main/files/LICENSE b/application/src/main/files/LICENSE index f288702d2..5eeb09b53 100644 --- a/application/src/main/files/LICENSE +++ b/application/src/main/files/LICENSE @@ -583,7 +583,7 @@ to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a +author or copyright holder as a control of your choosing to follow a later version. 15. Disclaimer of Warranty. diff --git a/plugins/compiler/as-8080/src/main/examples/include/getchar.inc b/plugins/compiler/as-8080/src/main/examples/include/getchar.inc index b6b89d451..fe1207325 100644 --- a/plugins/compiler/as-8080/src/main/examples/include/getchar.inc +++ b/plugins/compiler/as-8080/src/main/examples/include/getchar.inc @@ -1,5 +1,5 @@ ; load a char from keyboard -; result in reg. A +; control in reg. A getchar: in 10h diff --git a/plugins/compiler/as-ssem/src/main/examples/square-root.ssem b/plugins/compiler/as-ssem/src/main/examples/square-root.ssem index d5fab96c3..ba0ebddf3 100644 --- a/plugins/compiler/as-ssem/src/main/examples/square-root.ssem +++ b/plugins/compiler/as-ssem/src/main/examples/square-root.ssem @@ -3,7 +3,7 @@ -- The square root is the count of the number of subtractions which took place. -- -- Written by: Brent Hilpert (12 Dec 2000) --- Description: Calculate the square root of X. The result is rounded up to an integral value. +-- Description: Calculate the square root of X. The control is rounded up to an integral value. -- -- Parameter Lines: 30: X -- Result Lines: 31: square root of X diff --git a/plugins/compiler/as-z80/src/main/examples/include/getchar.inc b/plugins/compiler/as-z80/src/main/examples/include/getchar.inc index a2a8f92c0..4bc83aaac 100644 --- a/plugins/compiler/as-z80/src/main/examples/include/getchar.inc +++ b/plugins/compiler/as-z80/src/main/examples/include/getchar.inc @@ -1,5 +1,5 @@ ; load a char from keyboard -; result in reg. A +; control in reg. A getchar: in a, (10H) diff --git a/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp b/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp index d680b3224..500c08079 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp +++ b/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp @@ -403,7 +403,7 @@ addConstInstr: STORE 600 LOAD 2000 ;load the RAM accumulator ADD 0 ;execute ADD =i - STORE 2000 ;write the result back to RAM accumulator + STORE 2000 ;write the control back to RAM accumulator LOAD 2 ADD =1 @@ -461,7 +461,7 @@ subConstInstr: STORE 694 LOAD 2000 ;load the RAM accumulator SUB 0 ;execute SUB =i - STORE 2000 ;write the result back to RAM accumulator + STORE 2000 ;write the control back to RAM accumulator LOAD 2 ADD =1 @@ -519,7 +519,7 @@ mulConstInstr: STORE 788 LOAD 2000 ;load the RAM accumulator MUL 0 ;execute MUL =i - STORE 2000 ;write the result back to RAM accumulator + STORE 2000 ;write the control back to RAM accumulator LOAD 2 ADD =1 @@ -577,7 +577,7 @@ divConstInstr: STORE 882 LOAD 2000 ;load the RAM accumulator DIV 0 ;execute DIV =i - STORE 2000 ;write the result back to RAM accumulator + STORE 2000 ;write the control back to RAM accumulator LOAD 2 ADD =1 diff --git a/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram b/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram index dc602bc33..8eeb31300 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram +++ b/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram @@ -263,7 +263,7 @@ subConstInstr: LOAD 3 ;load RASP accumulor value SUB 1 ;substract the value in R1 (execute the SUB =i operation with RASP accumulator) - STORE 3 ;store the result into RASP accumulator + STORE 3 ;store the control into RASP accumulator LOAD 2 ADD =1 @@ -280,7 +280,7 @@ subRegInstr: LOAD 3 ;load RASP accumulator value SUB *1 ;substract the value of the register whose address is in R1 (execute SUB i operation with the RASP accumulator) - STORE 3 ;store the result into RASP accumulator + STORE 3 ;store the control into RASP accumulator LOAD 2 ADD =1 diff --git a/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp b/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp index a23473165..504fdd479 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp +++ b/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp @@ -1,6 +1,6 @@ org 5 -;Program reads an integer number from the input tape, calculates its factorial and prints the result onto the output tape. +;Program reads an integer number from the input tape, calculates its factorial and prints the control onto the output tape. ;saves the constant 1 into R2 and R3 registers @@ -24,7 +24,7 @@ store 3 mul 2 store 2 jmp ok -;print the result +;print the control finish: write 2 halt diff --git a/plugins/compiler/raspc-rasp/src/main/examples/simul_indir_adress.rasp b/plugins/compiler/raspc-rasp/src/main/examples/simul_indir_adress.rasp index c017f06da..36619b29e 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/simul_indir_adress.rasp +++ b/plugins/compiler/raspc-rasp/src/main/examples/simul_indir_adress.rasp @@ -23,8 +23,8 @@ LOAD 4 ;recover the accumulator content SUB 100 ;execute the SUB operation with already modified operand ;............................................................................ -STORE 4 ;store the result into R4 register -WRITE 4 ;print the result +STORE 4 ;store the control into R4 register +WRITE 4 ;print the control HALT ;============================================================================= diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/ContextImpl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/ContextImpl.java index d6c8cacee..573f6bd45 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/ContextImpl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/ContextImpl.java @@ -24,7 +24,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -74,7 +73,7 @@ public void clearDevices() { * @param data data to be written to the port. if parameter read is set to true, then data are ignored. * @return value from the port if read is true, otherwise 0 */ - public byte fireIO(int port, boolean read, byte data) throws IOException { + public byte fireIO(int port, boolean read, byte data) { DeviceContext device = devices.get(port); if (device != null) { if (read) { @@ -83,12 +82,12 @@ public byte fireIO(int port, boolean read, byte data) throws IOException { device.writeData(data); } } - return read ? (byte)0xFF : 0; // ha! from survey.mac in cpm2.dsk: "inactive port could return 0xFF or echo port#" + return read ? (byte) 0xFF : 0; // ha! from survey.mac in cpm2.dsk: "inactive port could return 0xFF or echo port#" } @Override - public boolean isRawInterruptSupported() { - return true; + public boolean isInterruptSupported() { + return false; } /** @@ -99,31 +98,15 @@ public boolean isRawInterruptSupported() { * during the interrupt acknowledge cycle. Subsequent bytes are read in by a * normal memory read sequence. * - * @param device the device which signals the interrupt - * @param instruction instruction signaled by this interrupt + * @param device the device which signals the interrupt + * @param data instruction signaled by this interrupt */ @Override - public void signalRawInterrupt(DeviceContext device, byte[] instruction) { - EmulatorEngine tmpCpu = cpu; - if (tmpCpu != null) { - short b1 = (instruction.length >= 1) ? instruction[0] : 0; - short b2 = (instruction.length >= 2) ? instruction[1] : 0; - short b3 = (instruction.length >= 3) ? instruction[2] : 0; - tmpCpu.interrupt(b1, b2, b3); - } - } - - @Override - public boolean isInterruptSupported() { - return false; - } - - @Override - public void signalInterrupt(DeviceContext device, int mask) { - } - - @Override - public void clearInterrupt(DeviceContext device, int mask) { + public void signalInterrupt(DeviceContext device, byte[] data) { + short b1 = (data.length >= 1) ? data[0] : 0; + short b2 = (data.length >= 2) ? data[1] : 0; + short b3 = (data.length >= 3) ? data[2] : 0; + cpu.interrupt(b1, b2, b3); } @Override diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContextImpl.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContextImpl.java index 673c54d38..c53814fb1 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContextImpl.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/BrainCPUContextImpl.java @@ -20,7 +20,6 @@ import net.emustudio.emulib.plugins.device.DeviceContext; -import java.io.IOException; import java.util.Objects; class BrainCPUContextImpl implements BrainCPUContext { @@ -46,7 +45,7 @@ public void detachDevice() { * * @param data value that will be written into the device */ - public void writeToDevice(byte data) throws IOException { + public void writeToDevice(byte data) { DeviceContext tmp = device; if (tmp == null) { return; @@ -62,7 +61,7 @@ public void writeToDevice(byte data) throws IOException { * * @return value from the device, or 0 if the device is null or there's anything */ - public byte readFromDevice() throws IOException { + public byte readFromDevice() { DeviceContext tmp = device; if (tmp == null) { return 0; @@ -70,31 +69,4 @@ public byte readFromDevice() throws IOException { Byte value = tmp.readData(); return (value == null) ? 0 : value; } - - @Override - public boolean isInterruptSupported() { - return false; - } - - @Override - public void clearInterrupt(DeviceContext device, int mask) { - } - - @Override - public boolean isRawInterruptSupported() { - return false; - } - - @Override - public void signalRawInterrupt(DeviceContext device, byte[] data) { - } - - @Override - public void signalInterrupt(DeviceContext device, int mask) { - } - - @Override - public int getCPUFrequency() { - return 0; - } } diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/RAMCpuContextImpl.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/RAMCpuContextImpl.java index bdcc1a89f..5de4219b8 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/RAMCpuContextImpl.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/RAMCpuContextImpl.java @@ -19,7 +19,6 @@ package net.emustudio.plugins.cpu.ram; import net.emustudio.emulib.plugins.PluginInitializationException; -import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.plugins.cpu.ram.api.RAMCpuContext; import net.emustudio.plugins.device.abstracttape.api.AbstractTapeContext; @@ -73,40 +72,9 @@ public AbstractTapeContext getOutputTape() { return outputTape; } - public void destroy() { Optional.ofNullable(inputTape).ifPresent(AbstractTapeContext::clear); Optional.ofNullable(storageTape).ifPresent(AbstractTapeContext::clear); Optional.ofNullable(outputTape).ifPresent(AbstractTapeContext::clear); } - - @Override - public boolean isInterruptSupported() { - return false; - } - - @Override - public void signalInterrupt(DeviceContext device, int mask) { - - } - - @Override - public void clearInterrupt(DeviceContext device, int mask) { - - } - - @Override - public boolean isRawInterruptSupported() { - return false; - } - - @Override - public void signalRawInterrupt(DeviceContext device, byte[] data) { - - } - - @Override - public int getCPUFrequency() { - return 0; - } } diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/api/RAMCpuContext.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/api/RAMCpuContext.java index 8beea8941..7768b458d 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/api/RAMCpuContext.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/api/RAMCpuContext.java @@ -20,7 +20,6 @@ package net.emustudio.plugins.cpu.ram.api; import net.emustudio.emulib.plugins.cpu.CPUContext; -import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.device.abstracttape.api.AbstractTapeContext; public interface RAMCpuContext extends CPUContext { @@ -30,34 +29,4 @@ public interface RAMCpuContext extends CPUContext { AbstractTapeContext getInputTape(); AbstractTapeContext getOutputTape(); - - @Override - default boolean isInterruptSupported() { - return false; - } - - @Override - default void signalInterrupt(DeviceContext device, int mask) { - - } - - @Override - default void clearInterrupt(DeviceContext device, int mask) { - - } - - @Override - default boolean isRawInterruptSupported() { - return false; - } - - @Override - default void signalRawInterrupt(DeviceContext device, byte[] data) { - - } - - @Override - default int getCPUFrequency() { - return 0; - } } diff --git a/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/api/RASPCpuContext.java b/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/api/RASPCpuContext.java index 6e91fb51d..3f0ea4106 100644 --- a/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/api/RASPCpuContext.java +++ b/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/api/RASPCpuContext.java @@ -21,7 +21,6 @@ package net.emustudio.plugins.cpu.rasp.api; import net.emustudio.emulib.plugins.cpu.CPUContext; -import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.device.abstracttape.api.AbstractTapeContext; public interface RASPCpuContext extends CPUContext { @@ -29,31 +28,4 @@ public interface RASPCpuContext extends CPUContext { AbstractTapeContext getInputTape(); AbstractTapeContext getOutputTape(); - - @Override - default boolean isInterruptSupported() { - return false; - } - - @Override - default void signalInterrupt(DeviceContext device, int mask) { - } - - @Override - default void clearInterrupt(DeviceContext device, int mask) { - } - - @Override - default boolean isRawInterruptSupported() { - return false; - } - - @Override - default void signalRawInterrupt(DeviceContext device, byte[] data) { - } - - @Override - default int getCPUFrequency() { - return 0; - } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java index 995f8205b..6c4df269d 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java @@ -23,7 +23,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -65,14 +64,14 @@ void clearDevices() { devices.clear(); } - void writeIO(int port, byte val) throws IOException { + void writeIO(int port, byte val) { DeviceContext device = devices.get(port); if (device != null) { device.writeData(val); } } - byte readIO(int port) throws IOException { + byte readIO(int port) { DeviceContext device = devices.get(port); if (device != null) { return device.readData(); @@ -90,24 +89,10 @@ public void setCPUFrequency(int frequency) { clockFrequency = frequency; } - @Override - public boolean isRawInterruptSupported() { - return true; - } - - @Override - public void signalRawInterrupt(DeviceContext device, byte[] data) { - cpu.setInterruptVector(data); - } - - @Override - public void signalInterrupt(DeviceContext device, int mask) { - cpu.setInterrupt(device, mask); - } @Override - public void clearInterrupt(DeviceContext device, int mask) { - cpu.clearInterrupt(device, mask); + public void signalInterrupt(DeviceContext device, byte[] data) { + cpu.requestInterrupt(data); } @Override diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index c7b0450bd..2c286f7c8 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -34,6 +34,9 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CopyOnWriteArrayList; import static net.emustudio.plugins.cpu.zilogZ80.DispatchTables.*; @@ -72,20 +75,10 @@ public class EmulatorEngine implements CpuEngine { public int PC = 0, SP = 0, IX = 0, IY = 0; public int I = 0, R = 0; // interrupt r., refresh r. - public byte intMode = 0; // interrupt mode (0,1,2) - // Interrupt flip-flops public final boolean[] IFF = new boolean[2]; // interrupt enable flip-flops - // No-Extra wait for CPC Interrupt? - private boolean noWait = false; - // Flag to cause an interrupt to execute - private boolean isINT = false; - // Interrupt Vector - private int interruptVector = 0xff; - // Interrupt mask - private int interruptPending = 0; - // device that want to interrupt - private DeviceContext interruptDevice; + public byte interruptMode = 0; // interrupt mode (0,1,2) + private final Queue pendingInterrupts = new ConcurrentLinkedQueue<>(); // must be thread-safe private RunState currentRunState = RunState.STATE_STOPPED_NORMAL; private long executedCycles = 0; @@ -123,6 +116,10 @@ public void fireFrequencyChanged(float newFrequency) { } } + public void requestInterrupt(byte[] data) { + pendingInterrupts.add(data); + } + void reset(int startPos) { SP = IX = IY = 0; I = R = 0; @@ -133,25 +130,19 @@ void reset(int startPos) { IFF[0] = false; IFF[1] = false; PC = startPos; - interruptPending = 0; - isINT = noWait = false; + pendingInterrupts.clear(); currentRunState = RunState.STATE_STOPPED_BREAK; } CPU.RunState step() throws Exception { - boolean oldIFF = IFF[0]; - noWait = false; currentRunState = CPU.RunState.STATE_STOPPED_BREAK; lastOpcode = readByte(PC); PC = (PC + 1) & 0xFFFF; try { dispatch(); - } catch (Exception e) { - throw e; } catch (Throwable e) { throw new Exception(e); } - isINT = (interruptPending != 0) && oldIFF && IFF[0]; return currentRunState; } @@ -206,11 +197,7 @@ private int dispatch() throws Throwable { } try { - /* if interrupt is waiting, instruction won't be read from memory - * but from one or all of 3 bytes (b1,b2,b3) which represents either - * rst or call instruction incomed from external peripheral device - */ - if (isINT) { + if (IFF[0] && !pendingInterrupts.isEmpty()) { return doInterrupt(); } incrementR(); @@ -279,55 +266,42 @@ int SPECIAL_CB_DISPATCH(MethodHandle[] table) throws Throwable { return 4; } - void setInterrupt(DeviceContext device, int mask) { - this.interruptDevice = device; - this.interruptPending |= mask; - } - - void clearInterrupt(DeviceContext device, int mask) { - if (interruptDevice == device) { - this.interruptPending &= ~mask; - } - } - - void setInterruptVector(byte[] vector) { - if ((vector == null) || (vector.length == 0)) { - return; - } - this.interruptVector = vector[0]; - } - private int doInterrupt() throws Throwable { - isINT = false; + byte[] dataBus = pendingInterrupts.poll(); int cycles = 0; - if (!noWait) { - cycles += 14; - } -// if (interruptDevice != null) { - // interruptDevice.setInterrupt(1); - // } IFF[0] = IFF[1] = false; - switch (intMode) { - case 0: // rst p (interruptVector) + switch (interruptMode) { + case 0: cycles += 11; RunState old_runstate = currentRunState; - lastOpcode = interruptVector & 0xFF; - dispatch(); // must ignore halt - if (currentRunState == RunState.STATE_STOPPED_NORMAL) { - currentRunState = old_runstate; + if (dataBus != null && dataBus.length > 0) { + lastOpcode = dataBus[0] & 0xFF; // TODO: if dataBus had more bytes, they're ignored (except call). + if (lastOpcode == 0xCD) { /* CALL */ + SP = (SP - 2) & 0xFFFF; + writeWord(SP, (PC + 2) & 0xFFFF); + PC = ((dataBus[2] & 0xFF) << 8) | (dataBus[1] & 0xFF); + return cycles + 17; + } + + dispatch(); // must ignore halt + if (currentRunState == RunState.STATE_STOPPED_NORMAL) { + currentRunState = old_runstate; + } } break; - case 1: // rst 0xFF + case 1: cycles += 12; writeWord((SP - 2) & 0xFFFF, PC); SP = (SP - 2) & 0xffff; - PC = 0xFF & 0x38; + PC = 0x38; break; case 2: cycles += 13; - writeWord((SP - 2) & 0xFFFF, PC); - PC = readWord((I << 8) | interruptVector); + if (dataBus != null && dataBus.length > 0) { + writeWord((SP - 2) & 0xFFFF, PC); + PC = readWord((I << 8) | dataBus[0]); + } break; } return cycles; @@ -924,7 +898,7 @@ int I_RETN() { } int I_IM_0() { - intMode = 0; + interruptMode = 0; return 8; } @@ -946,7 +920,7 @@ int I_LD_R_A() { } int I_IM_1() { - intMode = 1; + interruptMode = 1; return 8; } @@ -957,7 +931,7 @@ int I_LD_A_I() { } int I_IM_2() { - intMode = 2; + interruptMode = 2; return 8; } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java index a0dd856aa..18c108a15 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java @@ -26,7 +26,6 @@ import javax.swing.*; import javax.swing.table.DefaultTableModel; -import java.awt.*; import static net.emustudio.emulib.runtime.helpers.RadixUtils.formatByteHexString; import static net.emustudio.emulib.runtime.helpers.RadixUtils.formatWordHexString; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java index 14bcacba3..aebb41b9f 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java @@ -171,7 +171,7 @@ public void disableIFF1() { } public void setIntMode(byte intMode) { - cpu.getEngine().intMode = intMode; + cpu.getEngine().interruptMode = intMode; } @Override diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java index c309536eb..cff8c035c 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java @@ -157,7 +157,7 @@ public void checkInterruptsAreDisabled(int set) { } public void checkIntMode(int mode) { - assertEquals(mode, cpu.getEngine().intMode); + assertEquals(mode, cpu.getEngine().interruptMode); } public static String intToFlags(int flags) { diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/Commands.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/Commands.java new file mode 100644 index 000000000..f704ec8f0 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/Commands.java @@ -0,0 +1,92 @@ +package net.emustudio.plugins.device.simh; + +import net.emustudio.plugins.device.simh.commands.*; + +import java.util.*; + +// do not change order or remove commands, add only at the end +public enum Commands { + printTimeCmd, // 0 print the current time in milliseconds + startTimerCmd, // 1 start a new timer on the top of the timer stack + stopTimerCmd, // 2 stop timer on top of timer stack and show time difference + resetPTRCmd, // 3 reset the PTR device + attachPTRCmd, // 4 attach the PTR device + detachPTRCmd, // 5 detach the PTR device + getSIMHVersionCmd, // 6 get the current version of the SIMH pseudo device + getClockZSDOSCmd, // 7 get the current time in ZSDOS format + setClockZSDOSCmd, // 8 set the current time in ZSDOS format + getClockCPM3Cmd, // 9 get the current time in CP/M 3 format + setClockCPM3Cmd, // 10 set the current time in CP/M 3 format + getBankSelectCmd, // 11 get the selected bank + setBankSelectCmd, // 12 set the selected bank + getCommonCmd, // 13 get the base address of the common memory segment + resetSIMHInterfaceCmd, // 14 reset the SIMH pseudo device + showTimerCmd, // 15 show time difference to timer on top of stack + attachPTPCmd, // 16 attach PTP to the file with name at beginning of CP/M command line + detachPTPCmd, // 17 detach PTP + hasBankedMemoryCmd, // 18 determines whether machine has banked memory + setZ80CPUCmd, // 19 set the CPU to a Z80 + set8080CPUCmd, // 20 set the CPU to an 8080 + startTimerInterruptsCmd, // 21 start timer interrupts + stopTimerInterruptsCmd, // 22 stop timer interrupts + setTimerDeltaCmd, // 23 set the timer interval in which interrupts occur + setTimerInterruptAdrCmd, // 24 set the address to call by timer interrupts + resetStopWatchCmd, // 25 reset the millisecond stop watch + readStopWatchCmd, // 26 read the millisecond stop watch + SIMHSleepCmd, // 27 let SIMH sleep for SIMHSleep milliseconds + getHostOSPathSeparatorCmd, // 28 obtain the file path separator of the OS under which SIMH runs + getHostFilenamesCmd, // 29 perform wildcard expansion and obtain list of file names + readURLCmd, // 30 read the contents of an URL + getCPUClockFrequency, // 31 get the clock frequency of the CPU + setCPUClockFrequency, // 32 set the clock frequency of the CPU + genInterruptCmd; // 33 generate interrupt + + + public static Commands fromInt(int number) { + for (Commands c : Commands.values()) { + if (c.ordinal() == number) { + return c; + } + } + throw new IllegalArgumentException("Unknown command"); + } + + public final static Map COMMANDS_MAP = new HashMap<>(); + + static { + COMMANDS_MAP.put(printTimeCmd.ordinal(), PrintTime.INS); + COMMANDS_MAP.put(startTimerCmd.ordinal(), StartTimer.INS); + COMMANDS_MAP.put(stopTimerCmd.ordinal(), StopTimer.INS); + COMMANDS_MAP.put(resetPTRCmd.ordinal(), ResetPTR.INS); + COMMANDS_MAP.put(attachPTRCmd.ordinal(), AttachPTR.INS); + COMMANDS_MAP.put(detachPTRCmd.ordinal(), DetachPTR.INS); + COMMANDS_MAP.put(getSIMHVersionCmd.ordinal(), GetSimhVersion.INS); + COMMANDS_MAP.put(getClockZSDOSCmd.ordinal(), GetClockZSDOS.INS); + COMMANDS_MAP.put(setClockZSDOSCmd.ordinal(), SetClockZSDOS.INS); + COMMANDS_MAP.put(getClockCPM3Cmd.ordinal(), GetClockCPM3.INS); + COMMANDS_MAP.put(setClockCPM3Cmd.ordinal(), SetClockCPM3.INS); + COMMANDS_MAP.put(getBankSelectCmd.ordinal(), GetBankSelect.INS); + COMMANDS_MAP.put(setBankSelectCmd.ordinal(), SetBankSelect.INS); + COMMANDS_MAP.put(getCommonCmd.ordinal(), GetCommon.INS); + COMMANDS_MAP.put(resetSIMHInterfaceCmd.ordinal(), ResetSimhInterface.INS); + COMMANDS_MAP.put(showTimerCmd.ordinal(), ShowTimer.INS); + COMMANDS_MAP.put(attachPTPCmd.ordinal(), AttachPTP.INS); + COMMANDS_MAP.put(detachPTPCmd.ordinal(), DetachPTP.INS); + COMMANDS_MAP.put(hasBankedMemoryCmd.ordinal(), HasBankedMemory.INS); + COMMANDS_MAP.put(setZ80CPUCmd.ordinal(), SetZ80CPU.INS); + COMMANDS_MAP.put(set8080CPUCmd.ordinal(), Set8080CPU.INS); + COMMANDS_MAP.put(startTimerInterruptsCmd.ordinal(), StartTimerInterrupts.INS); + COMMANDS_MAP.put(stopTimerInterruptsCmd.ordinal(), StopTimerInterrupts.INS); + COMMANDS_MAP.put(setTimerDeltaCmd.ordinal(), SetTimerDelta.INS); + COMMANDS_MAP.put(setTimerInterruptAdrCmd.ordinal(), SetTimerInterruptAdr.INS); + COMMANDS_MAP.put(resetStopWatchCmd.ordinal(), ResetStopWatch.INS); + COMMANDS_MAP.put(readStopWatchCmd.ordinal(), ReadStopWatch.INS); + COMMANDS_MAP.put(SIMHSleepCmd.ordinal(), SIMHSleep.INS); + COMMANDS_MAP.put(getHostOSPathSeparatorCmd.ordinal(), GetHostOSPathSeparator.INS); + COMMANDS_MAP.put(getHostFilenamesCmd.ordinal(), GetHostFilenames.INS); + COMMANDS_MAP.put(readURLCmd.ordinal(), ReadURL.INS); + COMMANDS_MAP.put(getCPUClockFrequency.ordinal(), GetCPUClockFrequency.INS); + COMMANDS_MAP.put(setCPUClockFrequency.ordinal(), SetCPUClockFrequency.INS); + COMMANDS_MAP.put(genInterruptCmd.ordinal(), GenInterrupt.INS); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java new file mode 100644 index 000000000..fa038de4e --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java @@ -0,0 +1,35 @@ +package net.emustudio.plugins.device.simh; + +import net.emustudio.emulib.plugins.memory.MemoryContext; + +public class CpmUtils { + private final static int CPM_COMMAND_LINE_LENGTH = 128; + public static final char[] cpmCommandLine = new char[CPM_COMMAND_LINE_LENGTH]; + + public static void createCPMCommandLine(MemoryContext memory) { + int i; + int len = memory.read(0x80) & 0x7F; // 0x80 contains length of command line, discard first char + for (i = 0; i < len - 1; i++) { + cpmCommandLine[i] = (char) memory.read(0x82 + i).byteValue(); // the first char, typically ' ', is discarded + } + cpmCommandLine[i] = 0; // make C string + } + + + /* The CP/M command line is used as the name of a file and UNIT* uptr is attached to it. */ +// public static void attachCPM(MemoryContext memory, UNIT *uptr) { +// createCPMCommandLine(memory); +// if (uptr == &ptr_unit) +// sim_switches = SWMASK('R') | SWMASK('Q'); +// else if (uptr == &ptp_unit) +// sim_switches = SWMASK('W') | SWMASK('N') | SWMASK('Q'); +// /* 'N' option makes sure that file is properly truncated if it had existed before */ +// sim_quiet = sim_switches & SWMASK ('Q'); /* -q means quiet */ +// lastCPMStatus = attach_unit(uptr, cpmCommandLine); +// if (lastCPMStatus != SCPE_OK) { +// sim_debug(VERBOSE_MSG, &simh_device, "SIMH: " ADDRESS_FORMAT +// " Cannot open '%s' (%s).\n", PCX, cpmCommandLine, +// sim_error_text(lastCPMStatus)); +// } +// } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java index f9f4036b0..89bcdefe5 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java @@ -56,6 +56,7 @@ public void initialize() throws PluginInitializationException { ByteMemoryContext mem = contextPool.getMemoryContext(pluginID, ByteMemoryContext.class); context.setMemory(mem); + context.setCpu(cpu); // attach IO port if (!cpu.attachDevice(context, 0xFE)) { @@ -93,7 +94,7 @@ public String getCopyright() { @Override public String getDescription() { - return "Re-implementation of simh pseudo device, used in simh emulator. Version is SIMH003."; + return "Re-implementation of simh pseudo device, used in simh emulator. Version is SIMH004."; } @Override diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java index 93e57879e..cb8baa54a 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java @@ -19,519 +19,111 @@ package net.emustudio.plugins.device.simh; import net.emustudio.emulib.plugins.device.DeviceContext; +import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.device.simh.commands.*; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.File; -import java.util.Calendar; - -class PseudoContext implements DeviceContext { - private final static Logger LOGGER = LoggerFactory.getLogger(PseudoContext.class); - - private ByteMemoryContext mem; - - /* SIMH pseudo device status registers */ - /* ZSDOS clock definitions */ - private Calendar ClockZSDOSDelta = Calendar.getInstance(); /* delta between real clock and Altair clock */ - - private int setClockZSDOSPos = 0; /* determines state for receiving address of parameter block */ - - private int setClockZSDOSAdr = 0; /* address in M of 6 byte parameter block for setting time */ - - private short getClockZSDOSPos = 0; /* determines state for sending clock information */ - - /* CPM3 clock definitions */ - private int ClockCPM3Delta = 0; /* delta between real clock and Altair clock */ - - private int setClockCPM3Pos = 0; /* determines state for receiving address of parameter block */ - - private int setClockCPM3Adr = 0; /* address in M of 5 byte parameter block for setting time */ - - private short getClockCPM3Pos = 0; /* determines state for sending clock information */ - - private short daysCPM3SinceOrg = 0; /* days since 1 Jan 1978 */ - - /* interrupt related */ - private int timeOfNextInterrupt; /* time when next interrupt is scheduled */ - - //private boolean timerInterrupt = false; /* timer interrupt pending */ - - private int timerInterruptHandler = 0x0fc00; /* default address of interrupt handling routine */ - - private int setTimerInterruptAdrPos = 0; /* determines state for receiving timerInterruptHandler */ - - private int timerDelta = 100; /* interrupt every 100 ms */ - - private int setTimerDeltaPos = 0; /* determines state for receiving timerDelta */ - - /* stop watch and timer related */ - private short stopWatchDelta = 0; /* stores elapsed time of stop watch */ - - private int getStopWatchDeltaPos = 0; /* determines the state for receiving stopWatchDelta */ - - private int stopWatchNow = 0; /* stores starting time of stop watch */ - - private int markTimeSP = 0; /* stack pointer for timer stack */ - - ///* miscellaneous */ - private int versionPos = 0; /* determines state for sending device identifier */ - - private short lastCPMStatus = 0; /* result of last attachCPM command */ - - private short lastCommand = 0; /* most recent command processed on port 0xfeh */ +import static net.emustudio.plugins.device.simh.Commands.*; + +/** + * SIMH PseudoContext + *

+ * Z80 or 8080 programs communicate with the SIMH pseudo device via port 0xfe. + * The following principles apply: + *

+ * 1) For commands that do not require parameters and do not return results + * ld a, + * out (0feh),a + * Special case is the reset command which needs to be send 128 times to make + * sure that the internal state is properly reset. + *

+ * 2) For commands that require parameters and do not return results + * ld a, + * out (0feh),a + * ld a, + * out (0feh),a + * ld a, + * out (0feh),a + * ... + * Note: The calling program must send all parameter bytes. Otherwise + * the pseudo device is left in an undefined state. + *

+ * 3) For commands that do not require parameters and return results + * ld a, + * out (0feh),a + * in a,(0feh) ; contains first byte of result + * in a,(0feh) ; contains second byte of result + * ... + * Note: The calling program must request all bytes of the result. Otherwise + * the pseudo device is left in an undefined state. + *

+ * 4) Commands requiring parameters and returning results do not exist currently. + */ +class PseudoContext implements DeviceContext, Command.Control { + private ByteMemoryContext memory; + private ExtendedContext cpu; - private int getCommonPos = 0; /* determines state for sending the 'common' register */ + private Commands lastCommand = printTimeCmd; // most recent command processed on port 0xfeh - private Calendar currentTime = Calendar.getInstance(); - private boolean currentTimeValid = false; - private short[] version = {'S', 'I', 'M', 'H', '0', '0', '3', 0}; - private final static int SECONDS_PER_MINUTE = 60; - private final static int SECONDS_PER_HOUR = (60 * SECONDS_PER_MINUTE); - private final static int SECONDS_PER_DAY = (24 * SECONDS_PER_HOUR); - void setMemory(ByteMemoryContext mem) { - this.mem = mem; + @Override + public void clearCommand() { + lastCommand = printTimeCmd; } - /* Z80 or 8080 programs communicate with the SIMH pseudo device via port 0xfe. - The following principles apply: - - 1) For commands that do not require parameters and do not return results - ld a, - out (0feh),a - Special case is the reset command which needs to be send 128 times to make - sure that the internal state is properly reset. - - 2) For commands that require parameters and do not return results - ld a, - out (0feh),a - ld a, - out (0feh),a - ld a, - out (0feh),a - ... - Note: The calling program must send all parameter bytes. Otherwise - the pseudo device is left in an undefined state. - - 3) For commands that do not require parameters and return results - ld a, - out (0feh),a - in a,(0feh) ; contains first byte of result - in a,(0feh) ; contains second byte of result - ... - Note: The calling program must request all bytes of the result. Otherwise - the pseudo device is left in an undefined state. - - 4) Commands requiring parameters and returning results do not exist currently. - - */ - private final static int printTimeCmd = 0; /* 0 print the current time in milliseconds */ - - private final static int startTimerCmd = 1; /* 1 start a new timer on the top of the timer stack */ - - private final static int stopTimerCmd = 2; /* 2 stop timer on top of timer stack and show time difference */ - - private final static int resetPTRCmd = 3; /* 3 reset the PTR device */ - - private final static int attachPTRCmd = 4; /* 4 attach the PTR device */ - - private final static int detachPTRCmd = 5; /* 5 detach the PTR device */ - - private final static int getSIMHVersionCmd = 6; /* 6 get the current version of the SIMH pseudo device */ - - private final static int getClockZSDOSCmd = 7; /* 7 get the current time in ZSDOS format */ - - private final static int setClockZSDOSCmd = 8; /* 8 set the current time in ZSDOS format */ - - private final static int getClockCPM3Cmd = 9; /* 9 get the current time in CP/M 3 format */ - - private final static int setClockCPM3Cmd = 10; /* 10 set the current time in CP/M 3 format */ - - private final static int getBankSelectCmd = 11; /* 11 get the selected bank */ - - private final static int setBankSelectCmd = 12; /* 12 set the selected bank */ - - private final static int getCommonCmd = 13; /* 13 get the base address of the common memory segment */ - - private final static int resetSIMHInterfaceCmd = 14; /* 14 reset the SIMH pseudo device */ - - private final static int showTimerCmd = 15; /* 15 show time difference to timer on top of stack */ - - private final static int attachPTPCmd = 16; /* 16 attach PTP to the file with name at beginning of CP/M command line*/ - - private final static int detachPTPCmd = 17; /* 17 detach PTP */ - - private final static int hasBankedMemoryCmd = 18; /* 18 determines whether machine has banked memory */ - - private final static int setZ80CPUCmd = 19; /* 19 set the CPU to a Z80 */ - - private final static int set8080CPUCmd = 20; /* 20 set the CPU to an 8080 */ - - private final static int startTimerInterruptsCmd = 21; /* 21 start timer interrupts */ - - private final static int stopTimerInterruptsCmd = 22; /* 22 stop timer interrupts */ - - private final static int setTimerDeltaCmd = 23; /* 23 set the timer interval in which interrupts occur */ - - private final static int setTimerInterruptAdrCmd = 24; /* 24 set the address to call by timer interrupts */ - - private final static int resetStopWatchCmd = 25; /* 25 reset the millisecond stop watch */ - - private final static int readStopWatchCmd = 26; /* 26 read the millisecond stop watch */ - - private final static int SIMHSleepCmd = 27; /* 27 let SIMH sleep for SIMHSleep microseconds */ - - private final static int getHostOSPathSeparator = 28; /* 28 obtain the file path separator of the OS under which SIMH runs */ - - private final static int getHostFilenames = 29; /* 29 perform wildcard expansion and obtain list of file names */ - - - void reset() { - currentTimeValid = false; - lastCommand = 0; - lastCPMStatus = 0; - setClockZSDOSPos = 0; - getClockZSDOSPos = 0; - ClockZSDOSDelta = Calendar.getInstance(); - ClockCPM3Delta = 0; - setClockCPM3Pos = 0; - getClockCPM3Pos = 0; - getStopWatchDeltaPos = 0; - getCommonPos = 0; - setTimerDeltaPos = 0; - setTimerInterruptAdrPos = 0; - markTimeSP = 0; - versionPos = 0; + @Override + public ByteMemoryContext getMemory() { + return memory; } - private int toBCD(int x) { - return (x / 10) * 16 + (x % 10); + @Override + public ExtendedContext getCpu() { + return cpu; } - private int fromBCD(int x) { - return 10 * ((0xf0 & x) >> 4) + (0x0f & x); + @Override + public DeviceContext getDevice() { + return this; } - /* setClockZSDOSAdr points to 6 byte block in M: YY MM DD HH MM SS in BCD notation */ - private void setClockZSDOS() { - int year = fromBCD(mem.read(setClockZSDOSAdr)); - //int yy = (year < 50 ? year + 100 : year) + 1900; - int mm = fromBCD(mem.read(setClockZSDOSAdr + 1)) - 1; - int dd = fromBCD(mem.read(setClockZSDOSAdr + 2)); - int hh = fromBCD(mem.read(setClockZSDOSAdr + 3)); - int min = fromBCD(mem.read(setClockZSDOSAdr + 4)); - int ss = fromBCD(mem.read(setClockZSDOSAdr + 5)); - ClockZSDOSDelta.set(year, mm, dd, hh, min, ss); + void setMemory(ByteMemoryContext mem) { + this.memory = mem; } - private short mkCPM3Origin() { - short month, year; - short result; - short[] m_to_d = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; - month = 11; // t->tm_mon - year = (short) ((1977 + month / 12 + 1900) & 0xFFFF); // t->tm_year - month %= 12; - if (month < 0) { - year -= 1; - month += 12; - } - //result = (short) (((year - 1970) * 365 + (year - 1969) / 4 + m_to_d[month]) & 0xffff); - result = (short) (((year - 1970) * 365 + m_to_d[month]) & 0xffff); - if (month <= 1) { - year -= 1; - } - result += (year - 1968) / 4; - result -= (year - 1900) / 100; - result += (year - 1600) / 400; - result += 31; //t->tm_mday; - result -= 1; - result *= 24; - result += 0; //t->tm_hour; - result *= 60; - result += 0; //t->tm_min; - result *= 60; - result += 0; //t->tm_sec; - return (result); + void setCpu(ExtendedContext cpu) { + this.cpu = cpu; } - /* setClockCPM3Adr points to 5 byte block in M: - 0 - 1 int16: days since 31 Dec 77 - 2 BCD byte: HH - 3 BCD byte: MM - 4 BCD byte: SS */ - private void setClockCPM3() { - ClockCPM3Delta = mkCPM3Origin() - + (mem.read(setClockCPM3Adr) + mem.read(setClockCPM3Adr + 1) * 256) - * SECONDS_PER_DAY + fromBCD(mem.read(setClockCPM3Adr + 2)) - * SECONDS_PER_HOUR + fromBCD(mem.read(setClockCPM3Adr + 3)) - * SECONDS_PER_MINUTE + fromBCD(mem.read(setClockCPM3Adr + 4)) - - (short) (Calendar.getInstance().getTimeInMillis() / 1000); + void reset() { + clearCommand(); + COMMANDS_MAP.values().forEach(Command::reset); } + @Override public Byte readData() { - int result = 0; - switch (lastCommand) { - case getHostFilenames: - LOGGER.trace("[command={},name=getHostFilenames] Unimplemented command!", lastCommand); - lastCommand = 0; - break; - case attachPTRCmd: - case attachPTPCmd: - LOGGER.trace("[command={},name=attachPTRCmd/attachPTPCmd] Unimplemented command!", lastCommand); - - result = lastCPMStatus; - lastCommand = 0; - break; - case getClockZSDOSCmd: - if (currentTimeValid) { - switch (getClockZSDOSPos) { - case 0: - int year = (currentTime.get(Calendar.YEAR) - 1900); - result = toBCD(year > 99 ? year - 100 : year); - getClockZSDOSPos = 1; - break; - case 1: - result = toBCD(currentTime.get(Calendar.MONTH) + 1); - getClockZSDOSPos = 2; - break; - case 2: - result = toBCD(currentTime.get(Calendar.DAY_OF_MONTH)); - getClockZSDOSPos = 3; - break; - case 3: - result = toBCD(currentTime.get(Calendar.HOUR_OF_DAY)); - getClockZSDOSPos = 4; - break; - case 4: - result = toBCD(currentTime.get(Calendar.MINUTE)); - getClockZSDOSPos = 5; - break; - case 5: - result = toBCD(currentTime.get(Calendar.SECOND)); - getClockZSDOSPos = lastCommand = 0; - break; - } - } else { - result = getClockZSDOSPos = lastCommand = 0; - } - break; - case getClockCPM3Cmd: - if (currentTimeValid) { - switch (getClockCPM3Pos) { - case 0: - result = daysCPM3SinceOrg & 0xff; - getClockCPM3Pos = 1; - break; - case 1: - result = (daysCPM3SinceOrg >> 8) & 0xff; - getClockCPM3Pos = 2; - break; - case 2: - result = toBCD(currentTime.get(Calendar.HOUR_OF_DAY)); - getClockCPM3Pos = 3; - break; - case 3: - result = toBCD(currentTime.get(Calendar.MINUTE)); - getClockCPM3Pos = 4; - break; - case 4: - result = toBCD(currentTime.get(Calendar.SECOND)); - getClockCPM3Pos = lastCommand = 0; - break; - } - } else { - result = getClockCPM3Pos = lastCommand = 0; - } - break; - case getSIMHVersionCmd: - result = version[versionPos++]; - if (result == 0) { - versionPos = lastCommand = 0; - } - break; - case getBankSelectCmd: - result = mem.getSelectedBank(); - lastCommand = 0; - break; - case getCommonCmd: - if (getCommonPos == 0) { - result = mem.getCommonBoundary() & 0xff; - getCommonPos = 1; - } else { - result = (mem.getCommonBoundary() >> 8) & 0xff; - getCommonPos = lastCommand = 0; - } - break; - case hasBankedMemoryCmd: - result = mem.getBanksCount(); - lastCommand = 0; - break; - case readStopWatchCmd: - if (getStopWatchDeltaPos == 0) { - result = stopWatchDelta & 0xff; - getStopWatchDeltaPos = 1; - } else { - result = (stopWatchDelta >> 8) & 0xff; - getStopWatchDeltaPos = lastCommand = 0; - } - break; - case getHostOSPathSeparator: - result = File.separatorChar; - break; - default: /* undefined */ - LOGGER.debug("[command={}] Unknown command!", lastCommand); - result = lastCommand = 0; + int lastCommandOrdinal = lastCommand.ordinal(); + if (!COMMANDS_MAP.containsKey(lastCommandOrdinal)) { + System.out.printf("SIMH: Unknown command (%d) to SIMH pseudo device ignored.\n", lastCommandOrdinal); + clearCommand(); + } else { + return COMMANDS_MAP.get(lastCommand.ordinal()).read(this); } - return (byte)result; + return 0; } @Override public void writeData(Byte data) { - long now; - switch (lastCommand) { - case setClockZSDOSCmd: - if (setClockZSDOSPos == 0) { - setClockZSDOSAdr = data & 0xFF; - setClockZSDOSPos = 1; - } else { - setClockZSDOSAdr |= (data << 8) & 0xFF00; - setClockZSDOS(); - setClockZSDOSPos = lastCommand = 0; - } - break; - case setClockCPM3Cmd: - if (setClockCPM3Pos == 0) { - setClockCPM3Adr = data & 0xFF; - setClockCPM3Pos = 1; - } else { - setClockCPM3Adr |= (data << 8) & 0xFF00; - setClockCPM3(); - setClockCPM3Pos = lastCommand = 0; - } - break; - case setBankSelectCmd: - mem.selectBank(data & 0xff); - lastCommand = 0; - break; - case setTimerDeltaCmd: - if (setTimerDeltaPos == 0) { - timerDelta = data; - setTimerDeltaPos = 1; - } else { - timerDelta |= (data << 8); - setTimerDeltaPos = lastCommand = 0; - } - break; - case setTimerInterruptAdrCmd: - if (setTimerInterruptAdrPos == 0) { - timerInterruptHandler = data; - setTimerInterruptAdrPos = 1; - } else { - timerInterruptHandler |= (data << 8); - setTimerInterruptAdrPos = lastCommand = 0; - } - break; - default: - lastCommand = data; - switch (data) { - case getHostFilenames: - LOGGER.trace("[command={},name=getHostFilenames,method=write] Unimplemented command!", lastCommand); - break; - case SIMHSleepCmd: - LOGGER.trace("[command={},name=SIMHSleepCmd,method=write] Unimplemented command!", lastCommand); - break; - case printTimeCmd: - LOGGER.trace("[command={},name=printTimeCmd,method=write] Unimplemented command!", lastCommand); - break; - case startTimerCmd: - LOGGER.trace("[command={},name=startTimerCmd,method=write] Unimplemented command!", lastCommand); - break; - case stopTimerCmd: - LOGGER.trace("[command={},name=stopTimerCmd,method=write] Unimplemented command!", lastCommand); - break; - case resetPTRCmd: - LOGGER.trace("[command={},name=resetPTRCmd,method=write] Unimplemented command!", lastCommand); - break; - case attachPTRCmd: - LOGGER.trace("[command={},name=attachPTRCmd,method=write] Unimplemented command!", lastCommand); - break; - case detachPTRCmd: - LOGGER.trace("[command={},name=detachPTRCmd,method=write] Unimplemented command!", lastCommand); - break; - case getSIMHVersionCmd: - versionPos = 0; - break; - case getClockZSDOSCmd: - now = Calendar.getInstance().getTimeInMillis(); - now += ClockZSDOSDelta.getTimeInMillis(); // bug i think - currentTime.setTimeInMillis(now); - currentTimeValid = true; - getClockZSDOSPos = 0; - break; - case setClockZSDOSCmd: - setClockZSDOSPos = 0; - break; - case getClockCPM3Cmd: - now = Calendar.getInstance().getTimeInMillis(); - now += ClockCPM3Delta * 1000; - currentTime.setTimeInMillis(now); - currentTimeValid = true; - daysCPM3SinceOrg = (short) ((now - mkCPM3Origin()) / SECONDS_PER_DAY); - getClockCPM3Pos = 0; - break; - case setClockCPM3Cmd: - setClockCPM3Pos = 0; - break; - case getBankSelectCmd: - case setBankSelectCmd: - case getCommonCmd: - case hasBankedMemoryCmd: - case getHostOSPathSeparator: - break; - case resetSIMHInterfaceCmd: - markTimeSP = 0; - lastCommand = 0; - LOGGER.trace("[command={},name=resetSIMHInterfaceCMD,method=write] Partially implemented command!", lastCommand); - break; - case showTimerCmd: - LOGGER.trace("[command={},name=showTimerCmd,method=write] Unimplemented command!", lastCommand); - break; - case attachPTPCmd: - LOGGER.trace("[command={},name=attachPTPCmd,method=write] Unimplemented command!", lastCommand); - break; - case detachPTPCmd: - LOGGER.trace("[command={},name=detachPTPCmd,method=write] Unimplemented command!", lastCommand); - break; - case setZ80CPUCmd: - LOGGER.trace("[command={},name=setZ80CPUCmd,method=write] Unimplemented command!", lastCommand); - break; - case set8080CPUCmd: - LOGGER.trace("[command={},name=set8080CPUCmd,method=write] Unimplemented command!", lastCommand); - break; - case startTimerInterruptsCmd: - LOGGER.trace("[command={},name=startTimerInterruptsCmd,method=write] Unimplemented command!", lastCommand); - break; - case stopTimerInterruptsCmd: - LOGGER.trace("[command={},name=stopTimerInterruptsCmd,method=write] Unimplemented command!", lastCommand); - break; - case setTimerDeltaCmd: - setTimerDeltaPos = 0; - break; - case setTimerInterruptAdrCmd: - setTimerInterruptAdrPos = 0; - break; - case resetStopWatchCmd: - LOGGER.trace("[command={},name=resetStopWatchCmd,method=write] Unimplemented command!", lastCommand); - break; - case readStopWatchCmd: - LOGGER.trace("[command={},name=readStopWatchCmd,method=write] Partially implemented command!", lastCommand); - getStopWatchDeltaPos = 0; - break; - default: - LOGGER.debug("[command={},method=write] Unknown command!", lastCommand); - } + int lastCommandOrdinal = lastCommand.ordinal(); + if (!COMMANDS_MAP.containsKey(lastCommandOrdinal)) { + lastCommand = Commands.fromInt(data); + if (!COMMANDS_MAP.containsKey(lastCommand.ordinal())) { + System.out.printf("SIMH: Unknown command (%d) to SIMH pseudo device ignored.\n", data); + } else { + COMMANDS_MAP.get(lastCommand.ordinal()).start(this); + } + } else { + COMMANDS_MAP.get(lastCommandOrdinal).write(data, this); } } diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java new file mode 100644 index 000000000..27fa97d38 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java @@ -0,0 +1,31 @@ +package net.emustudio.plugins.device.simh.commands; + +public class AttachPTP implements Command { + public final static AttachPTP INS = new AttachPTP(); + private int lastCPMStatus = 0; // result of last attachCPM command + + @Override + public void reset() { + lastCPMStatus = 0; + } + + @Override + public byte read(Control control) { + byte result = (byte) lastCPMStatus; + control.clearCommand(); + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + // attachCPM( & ptp_unit); + } + + + +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java new file mode 100644 index 000000000..ac9886376 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.device.simh.commands; + +public class AttachPTR implements Command { + public final static AttachPTR INS = new AttachPTR(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + //attachCPM( & ptr_unit); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java new file mode 100644 index 000000000..64995ffc3 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java @@ -0,0 +1,56 @@ +package net.emustudio.plugins.device.simh.commands; + +import net.emustudio.emulib.plugins.device.DeviceContext; +import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; + +import java.util.HashMap; +import java.util.Map; + +public interface Command { + + /** + * Called on SIMH interface reset + */ + void reset(); + + /** + * Read byte + * + * @param control control + * @return data + */ + byte read(Control control); + + /** + * Write data byte + * + * @param data byte + * @param control control + */ + void write(byte data, Control control); + + /** + * On command start + * + * @param control control + */ + void start(Control control); + + + interface Control { + + /** + * Clears last command + */ + void clearCommand(); + + ByteMemoryContext getMemory(); + + ExtendedContext getCpu(); + + DeviceContext getDevice(); + } + + +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java new file mode 100644 index 000000000..3de28f5c8 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.device.simh.commands; + +public class DetachPTP implements Command { + public final static DetachPTP INS = new DetachPTP(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + //detach_unit( & ptp_unit); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java new file mode 100644 index 000000000..3d7a5d2e2 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.device.simh.commands; + +public class DetachPTR implements Command { + public final static DetachPTR INS = new DetachPTR(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + //detach_unit( & ptr_unit); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java new file mode 100644 index 000000000..0ca74bcc7 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java @@ -0,0 +1,39 @@ +package net.emustudio.plugins.device.simh.commands; + +public class GenInterrupt implements Command { + public final static GenInterrupt INS = new GenInterrupt(); + + private int genInterruptPos = 0; // determines state for receiving interrupt vector and data + private int genInterruptVec = 0; // stores interrupt vector + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + if (genInterruptPos == 0) { + genInterruptVec = data; // interrupt vector is not used. + genInterruptPos = 1; + System.out.println("genInterruptVec=" + genInterruptVec + " genInterruptPos=" + genInterruptPos); + } else { + control.getCpu().signalInterrupt(control.getDevice(), new byte[]{data}); + genInterruptPos = 0; + control.clearCommand(); + System.out.printf( + "genInterruptVec=%d vectorInterrupt=%X dataBus=%02X genInterruptPos=%d\n", + genInterruptVec, 1 << genInterruptVec, data, genInterruptPos); + } + } + + @Override + public void start(Control control) { + + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java new file mode 100644 index 000000000..917855d53 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java @@ -0,0 +1,27 @@ +package net.emustudio.plugins.device.simh.commands; + +public class GetBankSelect implements Command { + public final static GetBankSelect INS = new GetBankSelect(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + byte result = (byte)control.getMemory().getSelectedBank(); + control.clearCommand(); + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java new file mode 100644 index 000000000..812d2365e --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java @@ -0,0 +1,40 @@ +package net.emustudio.plugins.device.simh.commands; + +import java.util.concurrent.atomic.AtomicInteger; + +public class GetCPUClockFrequency implements Command { + public final static GetCPUClockFrequency INS = new GetCPUClockFrequency(); + + private int getClockFrequencyPos = 0; // determines state for receiving the clock frequency + private final AtomicInteger cpuFreq = new AtomicInteger(); + + @Override + public void reset() { + getClockFrequencyPos = 0; + } + + @Override + public byte read(Control control) { + byte result; + if (getClockFrequencyPos == 0) { + cpuFreq.set(control.getCpu().getCPUFrequency()); + result = (byte)(cpuFreq.get() & 0xff); + getClockFrequencyPos = 1; + } else { + result = (byte)((cpuFreq.get() >> 8) & 0xff); + getClockFrequencyPos = 0; + control.clearCommand(); + } + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + getClockFrequencyPos = 0; + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java new file mode 100644 index 000000000..4c4d9b096 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java @@ -0,0 +1,84 @@ +package net.emustudio.plugins.device.simh.commands; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; + +import static net.emustudio.emulib.runtime.helpers.NumberUtils.bin2bcd; + +public class GetClockCPM3 implements Command { + public static final GetClockCPM3 INS = new GetClockCPM3(); + + public final static long CPM3_ORIGIN = LocalDateTime + .of(1977, 12, 31, 0, 0, 0) + .toEpochSecond(ZoneOffset.UTC); + public final static int SECONDS_PER_MINUTE = 60; + public final static int SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE; + public final static int SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR; + + + private boolean currentTimeValid = false; + private LocalDateTime currentTime; + + private int getClockCPM3Pos = 0; // determines state for sending clock information + private int daysCPM3SinceOrg = 0; // days since 1 Jan 1978 + + @Override + public void reset() { + getClockCPM3Pos = 0; + currentTimeValid = false; + } + + @Override + public byte read(Control control) { + byte result = 0; + if (currentTimeValid) { + switch (getClockCPM3Pos) { + case 0: + result = (byte) (daysCPM3SinceOrg & 0xff); + getClockCPM3Pos = 1; + break; + + case 1: + result = (byte) ((daysCPM3SinceOrg >> 8) & 0xff); + getClockCPM3Pos = 2; + break; + + case 2: + result = (byte) bin2bcd(currentTime.getHour()); + getClockCPM3Pos = 3; + break; + + case 3: + result = (byte) bin2bcd(currentTime.getMinute()); + getClockCPM3Pos = 4; + break; + + case 4: + result = (byte) bin2bcd(currentTime.getSecond()); + getClockCPM3Pos = 0; + control.clearCommand(); + break; + } + } else { + getClockCPM3Pos = 0; + control.clearCommand(); + } + + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + int delta = SetClockCPM3.INS.ClockCPM3Delta; + currentTime = LocalDateTime.from(Instant.ofEpochSecond(Instant.now().getEpochSecond() + delta)); + currentTimeValid = true; + daysCPM3SinceOrg = (int)((currentTime.toEpochSecond(ZoneOffset.UTC) - CPM3_ORIGIN) / SECONDS_PER_DAY); + getClockCPM3Pos = 0; + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java new file mode 100644 index 000000000..464ce43aa --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java @@ -0,0 +1,80 @@ +package net.emustudio.plugins.device.simh.commands; + +import java.time.Instant; +import java.time.LocalDateTime; + +import static net.emustudio.emulib.runtime.helpers.NumberUtils.bin2bcd; + +public class GetClockZSDOS implements Command { + public final static GetClockZSDOS INS = new GetClockZSDOS(); + + private boolean currentTimeValid = false; + private LocalDateTime currentTime; + + // ZSDOS clock definitions + // private int ClockZSDOSDelta = 0; // delta between real clock and Altair clock + private int getClockZSDOSPos = 0; // determines state for sending clock information + + @Override + public void reset() { + currentTimeValid = false; + getClockZSDOSPos = 0; + } + + @Override + public byte read(Control control) { + byte result = 0; + if (currentTimeValid) { + switch (getClockZSDOSPos) { + + case 0: + result = (byte) bin2bcd(currentTime.getYear() % 100); + getClockZSDOSPos = 1; + break; + + case 1: + result = (byte) bin2bcd(currentTime.getMonthValue()); + getClockZSDOSPos = 2; + break; + + case 2: + result = (byte) bin2bcd(currentTime.getDayOfMonth()); + getClockZSDOSPos = 3; + break; + + case 3: + result = (byte) bin2bcd(currentTime.getHour()); + getClockZSDOSPos = 4; + break; + + case 4: + result = (byte) bin2bcd(currentTime.getMinute()); + getClockZSDOSPos = 5; + break; + + case 5: + result = (byte) bin2bcd(currentTime.getSecond()); + getClockZSDOSPos = 0; + control.clearCommand(); + break; + } + } else { + getClockZSDOSPos = 0; + control.clearCommand(); + } + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + int delta = SetClockZSDOS.INS.ClockZSDOSDelta; + currentTime = LocalDateTime.from(Instant.ofEpochSecond(Instant.now().getEpochSecond() + delta)); + currentTimeValid = true; + getClockZSDOSPos = 0; + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java new file mode 100644 index 000000000..f2ce26996 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java @@ -0,0 +1,36 @@ +package net.emustudio.plugins.device.simh.commands; + +public class GetCommon implements Command { + public final static GetCommon INS = new GetCommon(); + + private int getCommonPos = 0; // determines state for sending the 'common' register + + @Override + public void reset() { + getCommonPos = 0; + } + + @Override + public byte read(Control control) { + byte result; + if (getCommonPos == 0) { + result = (byte)(control.getMemory().getCommonBoundary() & 0xff); + getCommonPos = 1; + } else { + result = (byte)((control.getMemory().getCommonBoundary() >> 8) & 0xff); + getCommonPos = 0; + control.clearCommand(); + } + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + getCommonPos = 0; + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java new file mode 100644 index 000000000..68fc62413 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java @@ -0,0 +1,118 @@ +package net.emustudio.plugins.device.simh.commands; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.stream.Stream; + +import static net.emustudio.plugins.device.simh.CpmUtils.cpmCommandLine; +import static net.emustudio.plugins.device.simh.CpmUtils.createCPMCommandLine; + +public class GetHostFilenames implements Command { + public final static GetHostFilenames INS = new GetHostFilenames(); + + private final static Logger LOGGER = LoggerFactory.getLogger(GetHostFilenames.class); + + // support for wild card file expansion + public final static char hostPathSeparator = File.separatorChar; + private final static char hostPathSeparatorAlt = File.separatorChar; + + private NameNode nameListHead; + private NameNode currentName; + private int currentNameIndex = 0; + private int lastPathSeparatorIndex = 0; + private int firstPathCharacterIndex = 0; + + + static class NameNode { + char[] name; + NameNode next; + + public NameNode(char[] name, NameNode next) { + this.name = name; + this.next = next; + } + } + + @Override + public void reset() { + deleteNameList(); + nameListHead = null; + } + + @Override + public byte read(Control control) { + byte result = 0; + if (nameListHead != null) { + if (currentName == null) { + deleteNameList(); + control.clearCommand(); + } else if (firstPathCharacterIndex <= lastPathSeparatorIndex) + result = (byte) cpmCommandLine[firstPathCharacterIndex++]; + else { + result = (byte) currentName.name[currentNameIndex]; + if (result == 0) { + currentName = currentName.next; + firstPathCharacterIndex = currentNameIndex = 0; + } else + currentNameIndex++; + } + } + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + if (nameListHead == null) { + createCPMCommandLine(control.getMemory()); + lastPathSeparatorIndex = 0; + while (cpmCommandLine[lastPathSeparatorIndex] != 0) + lastPathSeparatorIndex++; + while ((lastPathSeparatorIndex >= 0) && + (cpmCommandLine[lastPathSeparatorIndex] != hostPathSeparator) && + (cpmCommandLine[lastPathSeparatorIndex] != hostPathSeparatorAlt)) { + lastPathSeparatorIndex--; + } + firstPathCharacterIndex = 0; + deleteNameList(); + fillupNameList(); + currentName = nameListHead; + currentNameIndex = 0; + } + } + + private void deleteNameList() { + while (nameListHead != null) { + nameListHead = nameListHead.next; + } + currentName = null; + currentNameIndex = 0; + } + + private void fillupNameList() { + StringBuilder pb = new StringBuilder(); + for (char c : cpmCommandLine) { + if (c != 0) { + pb.append(c); + } else { + break; + } + } + String path = pb.toString(); + try (Stream paths = Files.list(Path.of(path))) { + paths.forEach(p -> nameListHead = new NameNode(p.getFileName().toString().toCharArray(), nameListHead)); + } catch (IOException e) { + LOGGER.error("SIMH: Could not list host files", e); + deleteNameList(); + } + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java new file mode 100644 index 000000000..0b295b9c0 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.device.simh.commands; + +public class GetHostOSPathSeparator implements Command { + public final static GetHostOSPathSeparator INS = new GetHostOSPathSeparator(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return (byte) GetHostFilenames.hostPathSeparator; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java new file mode 100644 index 000000000..e77462418 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java @@ -0,0 +1,34 @@ +package net.emustudio.plugins.device.simh.commands; + +public class GetSimhVersion implements Command { + public final static GetSimhVersion INS = new GetSimhVersion(); + + private static final byte[] version = "SIMH004\0".getBytes(); + + private int versionPos = 0; // determines state for sending device identifier + + @Override + public void reset() { + versionPos = 0; + } + + @Override + public byte read(Control control) { + byte result = version[versionPos++]; + if (result == 0) { + versionPos = 0; + control.clearCommand(); + } + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + versionPos = 0; + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java new file mode 100644 index 000000000..40baf8a12 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java @@ -0,0 +1,27 @@ +package net.emustudio.plugins.device.simh.commands; + +public class HasBankedMemory implements Command { + public final static HasBankedMemory INS = new HasBankedMemory(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + byte result = (byte)control.getMemory().getBanksCount(); + control.clearCommand(); + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java new file mode 100644 index 000000000..97f468221 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.device.simh.commands; + +public class PrintTime implements Command { + public final static PrintTime INS = new PrintTime(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + System.out.printf("SIMH: Current time in milliseconds = %d.\n", System.currentTimeMillis()); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java new file mode 100644 index 000000000..92b8668b5 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java @@ -0,0 +1,40 @@ +package net.emustudio.plugins.device.simh.commands; + +public class ReadStopWatch implements Command { + public final static ReadStopWatch INS = new ReadStopWatch(); + + private int getStopWatchDeltaPos = 0; // determines the state for receiving stopWatchDelta + private long stopWatchDelta = 0; // stores elapsed time of stop watch + public long stopWatchNow = 0; // stores starting time of stop watch + + + @Override + public void reset() { + getStopWatchDeltaPos = 0; + } + + @Override + public byte read(Control control) { + byte result; + if (getStopWatchDeltaPos == 0) { + result = (byte) (stopWatchDelta & 0xff); + getStopWatchDeltaPos = 1; + } else { + result = (byte) ((stopWatchDelta >> 8) & 0xff); + getStopWatchDeltaPos = 0; + control.clearCommand(); + } + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + getStopWatchDeltaPos = 0; + stopWatchDelta = System.currentTimeMillis() - stopWatchNow; + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java new file mode 100644 index 000000000..670a315e7 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java @@ -0,0 +1,77 @@ +package net.emustudio.plugins.device.simh.commands; + +import java.util.Arrays; + +public class ReadURL implements Command { + public final static ReadURL INS = new ReadURL(); + + private final static int URL_MAX_LENGTH = 1024; + + private final char[] urlStore = new char[URL_MAX_LENGTH]; + private final char[] urlResult = new char[URL_MAX_LENGTH]; + private int urlPointer; + private int resultLength; + private int resultPointer; + private boolean showAvailability; + private boolean isInReadPhase; + + @Override + public void reset() { + urlPointer = 0; + isInReadPhase = false; + } + + @Override + public byte read(Control control) { + byte result = 0; + if (isInReadPhase) { + if (showAvailability) { + if (resultPointer < resultLength) + result = 1; + else { + Arrays.fill(urlResult, (char)0); + control.clearCommand(); + } + } else if (resultPointer < resultLength) { + result = (byte)urlResult[resultPointer++]; + } + showAvailability = !showAvailability; + } else { + control.clearCommand(); + } + return result; + } + + @Override + public void write(byte data, Control control) { + if (isInReadPhase) { + control.clearCommand(); + } else { + if (data != 0) { + if (urlPointer < URL_MAX_LENGTH - 1) { + urlStore[urlPointer++] = (char) (data & 0xff); + } + } else { + urlStore[urlPointer] = 0; + setURLContent(); + urlPointer = 0; + resultPointer = 0; + showAvailability = true; + isInReadPhase = true; + } + } + } + + @Override + public void start(Control control) { + reset(); + } + + + private void setURLContent() { + String str = "URL is not supported on this platform. START URL \"" + + String.valueOf(urlStore, 0, urlPointer) + "\" URL END."; + resultLength = Math.min(URL_MAX_LENGTH, str.length()); + System.arraycopy(str.toCharArray(), 0, urlResult, 0, resultLength); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java new file mode 100644 index 000000000..bd96e13af --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.device.simh.commands; + +public class ResetPTR implements Command { + public final static ResetPTR INS = new ResetPTR(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + //ptr_reset( & ptr_dev); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java new file mode 100644 index 000000000..53298b096 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java @@ -0,0 +1,27 @@ +package net.emustudio.plugins.device.simh.commands; + +public class ResetSimhInterface implements Command { + public final static ResetSimhInterface INS = new ResetSimhInterface(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + StartTimer.INS.markTimeSP = 0; + control.clearCommand(); + GetHostFilenames.INS.reset(); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java new file mode 100644 index 000000000..2ec30c56e --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.device.simh.commands; + +public class ResetStopWatch implements Command { + public final static ResetStopWatch INS = new ResetStopWatch(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + ReadStopWatch.INS.stopWatchNow = System.currentTimeMillis(); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java new file mode 100644 index 000000000..048e79f16 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java @@ -0,0 +1,39 @@ +package net.emustudio.plugins.device.simh.commands; + +public class SIMHSleep implements Command { + public final static SIMHSleep INS = new SIMHSleep(); + private final static int SIMHSleepMillis = 1; + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + do_SIMH_sleep(); + } + + private void do_SIMH_sleep() { + // TODO: + // Do not sleep when timer interrupts are pending or are about to be created. + // Otherwise there is the possibility that such interrupts are skipped. + + // time to sleep and SIO not attached to a file. + try { + Thread.sleep(SIMHSleepMillis); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java new file mode 100644 index 000000000..d4a38ab2d --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.device.simh.commands; + +public class Set8080CPU implements Command { + public final static Set8080CPU INS = new Set8080CPU(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + System.out.println("SIMH: Set 8080 CPU command not supported!"); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java new file mode 100644 index 000000000..e7d879900 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java @@ -0,0 +1,26 @@ +package net.emustudio.plugins.device.simh.commands; + +public class SetBankSelect implements Command { + public final static SetBankSelect INS = new SetBankSelect(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + control.getMemory().selectBank(data); + control.clearCommand(); + } + + @Override + public void start(Control control) { + + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java new file mode 100644 index 000000000..46e06d190 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java @@ -0,0 +1,35 @@ +package net.emustudio.plugins.device.simh.commands; + +public class SetCPUClockFrequency implements Command { + public final static SetCPUClockFrequency INS = new SetCPUClockFrequency(); + + private int newClockFrequency; + private int setClockFrequencyPos = 0; // determines state for sending the clock frequency + + @Override + public void reset() { + setClockFrequencyPos = 0; + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + if (setClockFrequencyPos == 0) { + newClockFrequency = data; + setClockFrequencyPos = 1; + } else { + control.getCpu().setCPUFrequency((data << 8) | newClockFrequency); + setClockFrequencyPos = 0; + control.clearCommand(); + } + } + + @Override + public void start(Control control) { + setClockFrequencyPos = 0; + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java new file mode 100644 index 000000000..13c437438 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java @@ -0,0 +1,67 @@ +package net.emustudio.plugins.device.simh.commands; + +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; + +import static net.emustudio.emulib.runtime.helpers.NumberUtils.bcd2bin; +import static net.emustudio.plugins.device.simh.commands.GetClockCPM3.*; + +public class SetClockCPM3 implements Command { + public final static SetClockCPM3 INS = new SetClockCPM3(); + + public int ClockCPM3Delta = 0; // delta between real clock and Altair clock + private int setClockCPM3Pos = 0; // determines state for receiving address of parameter block + private int setClockCPM3Adr = 0; // address in M of 5 byte parameter block for setting time + + @Override + public void reset() { + ClockCPM3Delta = 0; + setClockCPM3Pos = 0; + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + if (setClockCPM3Pos == 0) { + setClockCPM3Adr = data; + setClockCPM3Pos = 1; + } else { + setClockCPM3Adr |= (data << 8); + setClockCPM3(control.getMemory()); + setClockCPM3Pos = 0; + control.clearCommand(); + } + } + + @Override + public void start(Control control) { + setClockCPM3Pos = 0; + } + + /* setClockCPM3Adr points to 5 byte block in M: + 0 - 1 int16: days since 31 Dec 77 + 2 BCD byte: HH + 3 BCD byte: MM + 4 BCD byte: SS */ + private void setClockCPM3(ByteMemoryContext mem) { + long targetSeconds = CPM3_ORIGIN + + (mem.read(setClockCPM3Adr) + mem.read(setClockCPM3Adr + 1) * 256) * SECONDS_PER_DAY + + (long) bcd2bin(mem.read(setClockCPM3Adr + 2)) * SECONDS_PER_HOUR + + (long) bcd2bin(mem.read(setClockCPM3Adr + 3)) * SECONDS_PER_MINUTE + + bcd2bin(mem.read(setClockCPM3Adr + 4)); + + // compute target year, month and day and replace hour, minute and second fields + LocalDateTime targetDate = LocalDateTime + .ofEpochSecond(targetSeconds, 0, ZoneOffset.UTC) + .withHour(bcd2bin(mem.read(setClockCPM3Adr + 2))) + .withMinute(bcd2bin(mem.read(setClockCPM3Adr + 3))) + .withSecond(bcd2bin(mem.read(setClockCPM3Adr + 4))); + ClockCPM3Delta = (int) (targetDate.toEpochSecond(ZoneOffset.UTC) - LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java new file mode 100644 index 000000000..5cf42076d --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java @@ -0,0 +1,59 @@ +package net.emustudio.plugins.device.simh.commands; + +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; + +import static net.emustudio.emulib.runtime.helpers.NumberUtils.bcd2bin; + +public class SetClockZSDOS implements Command { + public final static SetClockZSDOS INS = new SetClockZSDOS(); + + private int setClockZSDOSPos = 0; // determines state for receiving address of parameter block + private int setClockZSDOSAdr = 0; // address in M of 6 byte parameter block for setting time + public int ClockZSDOSDelta = 0; // delta between real clock and Altair clock + + @Override + public void reset() { + ClockZSDOSDelta = 0; + setClockZSDOSPos = 0; + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + if (setClockZSDOSPos == 0) { + setClockZSDOSAdr = data; + setClockZSDOSPos = 1; + } else { + setClockZSDOSAdr |= (data << 8); + setClockZSDOS(control.getMemory()); + setClockZSDOSPos = 0; + control.clearCommand(); + } + } + + @Override + public void start(Control control) { + setClockZSDOSPos = 0; + } + + /* setClockZSDOSAdr points to 6 byte block in M: YY MM DD HH MM SS in BCD notation */ + private void setClockZSDOS(ByteMemoryContext mem) { + int year = bcd2bin(mem.read(setClockZSDOSAdr)); + int tm_year = (year < 50 ? year + 100 : year) + 1900; + int tm_mon = bcd2bin(mem.read(setClockZSDOSAdr + 1)); + int tm_mday = bcd2bin(mem.read(setClockZSDOSAdr + 2)); + int tm_hour = bcd2bin(mem.read(setClockZSDOSAdr + 3)); + int tm_min = bcd2bin(mem.read(setClockZSDOSAdr + 4)); + int tm_sec = bcd2bin(mem.read(setClockZSDOSAdr + 5)); + + LocalDateTime newTime = LocalDateTime.of(tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec); + ClockZSDOSDelta = (int)(newTime.toEpochSecond(ZoneOffset.UTC) - LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java new file mode 100644 index 000000000..a5d161ba1 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java @@ -0,0 +1,41 @@ +package net.emustudio.plugins.device.simh.commands; + +public class SetTimerDelta implements Command { + public final static SetTimerDelta INS = new SetTimerDelta(); + + private final static int DEFAULT_TIMER_DELTA = 100; // default value for timer delta in ms + + private int setTimerDeltaPos = 0; // determines state for receiving timerDelta + public int timerDelta = DEFAULT_TIMER_DELTA; // interrupt every 100 ms + + @Override + public void reset() { + setTimerDeltaPos = 0; + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + if (setTimerDeltaPos == 0) { + timerDelta = data; + setTimerDeltaPos = 1; + } else { + timerDelta |= (data << 8); + setTimerDeltaPos = 0; + control.clearCommand(); + if (timerDelta == 0) { + timerDelta = DEFAULT_TIMER_DELTA; + System.out.println("SIMH: Timer delta set to 0 ms ignored. Using " + DEFAULT_TIMER_DELTA + " ms instead."); + } + } + } + + @Override + public void start(Control control) { + reset(); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java new file mode 100644 index 000000000..366cf2ec3 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java @@ -0,0 +1,35 @@ +package net.emustudio.plugins.device.simh.commands; + +public class SetTimerInterruptAdr implements Command { + public static final SetTimerInterruptAdr INS = new SetTimerInterruptAdr(); + + private int setTimerInterruptAdrPos = 0; // determines state for receiving timerInterruptHandler + public int timerInterruptHandler = 0x0fc00; // default address of interrupt handling routine + + @Override + public void reset() { + setTimerInterruptAdrPos = 0; + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + if (setTimerInterruptAdrPos == 0) { + timerInterruptHandler = data; + setTimerInterruptAdrPos = 1; + } else { + timerInterruptHandler |= (data << 8); + setTimerInterruptAdrPos = 0; + control.clearCommand(); + } + } + + @Override + public void start(Control control) { + reset(); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java new file mode 100644 index 000000000..da0936b31 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.device.simh.commands; + +public class SetZ80CPU implements Command { + public final static SetZ80CPU INS = new SetZ80CPU(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + System.out.println("SIMH: Set Z80 CPU command not supported!"); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java new file mode 100644 index 000000000..622e9cbba --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java @@ -0,0 +1,30 @@ +package net.emustudio.plugins.device.simh.commands; + +public class ShowTimer implements Command { + public final static ShowTimer INS = new ShowTimer(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + if (StartTimer.INS.markTimeSP > 0) { + long delta = System.currentTimeMillis() - StartTimer.INS.markTime[StartTimer.INS.markTimeSP - 1]; + System.out.printf("SIMH: Timer running. Elapsed in milliseconds = %d.\n", delta); + } else { + System.out.println("SIMH: No timer active."); + } + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java new file mode 100644 index 000000000..1b286e43b --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java @@ -0,0 +1,34 @@ +package net.emustudio.plugins.device.simh.commands; + +public class StartTimer implements Command { + public final static StartTimer INS = new StartTimer(); + + private final static int TIMER_STACK_LIMIT = 10; // stack depth of timer stack + // stop watch and timer related + public int markTimeSP = 0; // stack pointer for timer stack + public long[] markTime = new long[TIMER_STACK_LIMIT]; // timer stack + + @Override + public void reset() { + markTimeSP = 0; + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + if (markTimeSP < TIMER_STACK_LIMIT) { + markTime[markTimeSP++] = System.currentTimeMillis(); + } else { + System.out.println("SIMH: Timer stack overflow"); + } + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java new file mode 100644 index 000000000..2183af48c --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java @@ -0,0 +1,41 @@ +package net.emustudio.plugins.device.simh.commands; + +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicReference; + +public class StartTimerInterrupts implements Command { + public final static StartTimerInterrupts INS = new StartTimerInterrupts(); + private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); + public final AtomicReference> timerTask = new AtomicReference<>(); + + @Override + public void reset() { + ScheduledFuture oldTask = timerTask.get(); + if (oldTask != null) { + oldTask.cancel(true); + } + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + reset(); + + timerTask.set(executor.scheduleAtFixedRate(() -> { + // will work only in interrupt mode 0 + int addr = SetTimerInterruptAdr.INS.timerInterruptHandler; + byte b1 = (byte) (addr & 0xFF); + byte b2 = (byte) (addr >>> 8); + control.getCpu().signalInterrupt(control.getDevice(), new byte[]{(byte) 0xCD, b1, b2}); + }, SetTimerDelta.INS.timerDelta, SetTimerDelta.INS.timerDelta, TimeUnit.MILLISECONDS)); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java new file mode 100644 index 000000000..e57688b67 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java @@ -0,0 +1,31 @@ +package net.emustudio.plugins.device.simh.commands; + +public class StopTimer implements Command { + public final static StopTimer INS = new StopTimer(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + if (StartTimer.INS.markTimeSP > 0) { + StartTimer.INS.markTimeSP -= 1; + long delta = System.currentTimeMillis() - StartTimer.INS.markTime[StartTimer.INS.markTimeSP]; + System.out.printf("SIMH: Timer stopped. Elapsed time in milliseconds = %d.\n", delta); + } else { + System.out.println("SIMH: No timer active"); + } + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java new file mode 100644 index 000000000..09b5c35c6 --- /dev/null +++ b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java @@ -0,0 +1,25 @@ +package net.emustudio.plugins.device.simh.commands; + +public class StopTimerInterrupts implements Command { + public final static StopTimerInterrupts INS = new StopTimerInterrupts(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + StartTimerInterrupts.INS.reset(); + } +} From 4704d0ada051ce2e5cdbe49cf7a4f7e2801ad3fc Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 23 Jul 2022 01:31:46 +0100 Subject: [PATCH 175/314] [#175] fixes of wrong replace text --- CODE_OF_CONDUCT.md | 2 +- LICENSE | 2 +- application/src/main/files/LICENSE | 2 +- .../as-8080/src/main/examples/include/getchar.inc | 2 +- .../compiler/as-ssem/src/main/examples/square-root.ssem | 2 +- .../compiler/as-z80/src/main/examples/include/getchar.inc | 2 +- .../compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp | 8 ++++---- .../compiler/raspc-rasp/src/main/examples/RASPinRAM.ram | 4 ++-- .../compiler/raspc-rasp/src/main/examples/factorial.rasp | 4 ++-- .../raspc-rasp/src/main/examples/simul_indir_adress.rasp | 4 ++-- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index b66226cb8..e60f5cd59 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -56,7 +56,7 @@ further defined and clarified by project maintainers. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at emustudio@googlegroups.com. All -complaints will be reviewed and investigated and will control in a response that +complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. diff --git a/LICENSE b/LICENSE index 5eeb09b53..f288702d2 100644 --- a/LICENSE +++ b/LICENSE @@ -583,7 +583,7 @@ to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any -author or copyright holder as a control of your choosing to follow a +author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. diff --git a/application/src/main/files/LICENSE b/application/src/main/files/LICENSE index 5eeb09b53..f288702d2 100644 --- a/application/src/main/files/LICENSE +++ b/application/src/main/files/LICENSE @@ -583,7 +583,7 @@ to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any -author or copyright holder as a control of your choosing to follow a +author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. diff --git a/plugins/compiler/as-8080/src/main/examples/include/getchar.inc b/plugins/compiler/as-8080/src/main/examples/include/getchar.inc index fe1207325..b6b89d451 100644 --- a/plugins/compiler/as-8080/src/main/examples/include/getchar.inc +++ b/plugins/compiler/as-8080/src/main/examples/include/getchar.inc @@ -1,5 +1,5 @@ ; load a char from keyboard -; control in reg. A +; result in reg. A getchar: in 10h diff --git a/plugins/compiler/as-ssem/src/main/examples/square-root.ssem b/plugins/compiler/as-ssem/src/main/examples/square-root.ssem index ba0ebddf3..d5fab96c3 100644 --- a/plugins/compiler/as-ssem/src/main/examples/square-root.ssem +++ b/plugins/compiler/as-ssem/src/main/examples/square-root.ssem @@ -3,7 +3,7 @@ -- The square root is the count of the number of subtractions which took place. -- -- Written by: Brent Hilpert (12 Dec 2000) --- Description: Calculate the square root of X. The control is rounded up to an integral value. +-- Description: Calculate the square root of X. The result is rounded up to an integral value. -- -- Parameter Lines: 30: X -- Result Lines: 31: square root of X diff --git a/plugins/compiler/as-z80/src/main/examples/include/getchar.inc b/plugins/compiler/as-z80/src/main/examples/include/getchar.inc index 4bc83aaac..a2a8f92c0 100644 --- a/plugins/compiler/as-z80/src/main/examples/include/getchar.inc +++ b/plugins/compiler/as-z80/src/main/examples/include/getchar.inc @@ -1,5 +1,5 @@ ; load a char from keyboard -; control in reg. A +; result in reg. A getchar: in a, (10H) diff --git a/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp b/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp index 500c08079..d680b3224 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp +++ b/plugins/compiler/raspc-rasp/src/main/examples/RAMinRASP.rasp @@ -403,7 +403,7 @@ addConstInstr: STORE 600 LOAD 2000 ;load the RAM accumulator ADD 0 ;execute ADD =i - STORE 2000 ;write the control back to RAM accumulator + STORE 2000 ;write the result back to RAM accumulator LOAD 2 ADD =1 @@ -461,7 +461,7 @@ subConstInstr: STORE 694 LOAD 2000 ;load the RAM accumulator SUB 0 ;execute SUB =i - STORE 2000 ;write the control back to RAM accumulator + STORE 2000 ;write the result back to RAM accumulator LOAD 2 ADD =1 @@ -519,7 +519,7 @@ mulConstInstr: STORE 788 LOAD 2000 ;load the RAM accumulator MUL 0 ;execute MUL =i - STORE 2000 ;write the control back to RAM accumulator + STORE 2000 ;write the result back to RAM accumulator LOAD 2 ADD =1 @@ -577,7 +577,7 @@ divConstInstr: STORE 882 LOAD 2000 ;load the RAM accumulator DIV 0 ;execute DIV =i - STORE 2000 ;write the control back to RAM accumulator + STORE 2000 ;write the result back to RAM accumulator LOAD 2 ADD =1 diff --git a/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram b/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram index 8eeb31300..dc602bc33 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram +++ b/plugins/compiler/raspc-rasp/src/main/examples/RASPinRAM.ram @@ -263,7 +263,7 @@ subConstInstr: LOAD 3 ;load RASP accumulor value SUB 1 ;substract the value in R1 (execute the SUB =i operation with RASP accumulator) - STORE 3 ;store the control into RASP accumulator + STORE 3 ;store the result into RASP accumulator LOAD 2 ADD =1 @@ -280,7 +280,7 @@ subRegInstr: LOAD 3 ;load RASP accumulator value SUB *1 ;substract the value of the register whose address is in R1 (execute SUB i operation with the RASP accumulator) - STORE 3 ;store the control into RASP accumulator + STORE 3 ;store the result into RASP accumulator LOAD 2 ADD =1 diff --git a/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp b/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp index 504fdd479..a23473165 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp +++ b/plugins/compiler/raspc-rasp/src/main/examples/factorial.rasp @@ -1,6 +1,6 @@ org 5 -;Program reads an integer number from the input tape, calculates its factorial and prints the control onto the output tape. +;Program reads an integer number from the input tape, calculates its factorial and prints the result onto the output tape. ;saves the constant 1 into R2 and R3 registers @@ -24,7 +24,7 @@ store 3 mul 2 store 2 jmp ok -;print the control +;print the result finish: write 2 halt diff --git a/plugins/compiler/raspc-rasp/src/main/examples/simul_indir_adress.rasp b/plugins/compiler/raspc-rasp/src/main/examples/simul_indir_adress.rasp index 36619b29e..c017f06da 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/simul_indir_adress.rasp +++ b/plugins/compiler/raspc-rasp/src/main/examples/simul_indir_adress.rasp @@ -23,8 +23,8 @@ LOAD 4 ;recover the accumulator content SUB 100 ;execute the SUB operation with already modified operand ;............................................................................ -STORE 4 ;store the control into R4 register -WRITE 4 ;print the control +STORE 4 ;store the result into R4 register +WRITE 4 ;print the result HALT ;============================================================================= From 47614541ed4d310cf87d7634639e450f16702798 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 23 Jul 2022 09:02:34 +0100 Subject: [PATCH 176/314] [#244] Rename simhPseudo-z80 to simh-pseudo --- application/build.gradle | 4 +- .../{simhPseudo-z80 => simh-pseudo}/README.md | 4 +- .../build.gradle | 0 .../plugins/device/simh/Commands.java | 18 +++++++ .../plugins/device/simh/CpmUtils.java | 18 +++++++ .../plugins/device/simh/DeviceImpl.java | 0 .../plugins/device/simh/PseudoContext.java | 0 .../device/simh/commands/AttachPTP.java | 49 +++++++++++++++++++ .../device/simh/commands/AttachPTR.java | 43 ++++++++++++++++ .../plugins/device/simh/commands/Command.java | 18 +++++++ .../device/simh/commands/DetachPTP.java | 43 ++++++++++++++++ .../device/simh/commands/DetachPTR.java | 43 ++++++++++++++++ .../device/simh/commands/GenInterrupt.java | 18 +++++++ .../device/simh/commands/GetBankSelect.java | 45 +++++++++++++++++ .../simh/commands/GetCPUClockFrequency.java | 18 +++++++ .../device/simh/commands/GetClockCPM3.java | 18 +++++++ .../device/simh/commands/GetClockZSDOS.java | 18 +++++++ .../device/simh/commands/GetCommon.java | 18 +++++++ .../simh/commands/GetHostFilenames.java | 18 +++++++ .../simh/commands/GetHostOSPathSeparator.java | 43 ++++++++++++++++ .../device/simh/commands/GetSimhVersion.java | 18 +++++++ .../device/simh/commands/HasBankedMemory.java | 45 +++++++++++++++++ .../device/simh/commands/PrintTime.java | 43 ++++++++++++++++ .../device/simh/commands/ReadStopWatch.java | 18 +++++++ .../plugins/device/simh/commands/ReadURL.java | 18 +++++++ .../device/simh/commands/ResetPTR.java | 43 ++++++++++++++++ .../simh/commands/ResetSimhInterface.java | 45 +++++++++++++++++ .../device/simh/commands/ResetStopWatch.java | 43 ++++++++++++++++ .../device/simh/commands/SIMHSleep.java | 18 +++++++ .../device/simh/commands/Set8080CPU.java | 43 ++++++++++++++++ .../device/simh/commands/SetBankSelect.java | 44 +++++++++++++++++ .../simh/commands/SetCPUClockFrequency.java | 18 +++++++ .../device/simh/commands/SetClockCPM3.java | 18 +++++++ .../device/simh/commands/SetClockZSDOS.java | 18 +++++++ .../device/simh/commands/SetTimerDelta.java | 18 +++++++ .../simh/commands/SetTimerInterruptAdr.java | 18 +++++++ .../device/simh/commands/SetZ80CPU.java | 43 ++++++++++++++++ .../device/simh/commands/ShowTimer.java | 18 +++++++ .../device/simh/commands/StartTimer.java | 18 +++++++ .../simh/commands/StartTimerInterrupts.java | 18 +++++++ .../device/simh/commands/StopTimer.java | 18 +++++++ .../simh/commands/StopTimerInterrupts.java | 43 ++++++++++++++++ .../plugins/device/simh/version.properties | 0 .../plugins/device/simh/DeviceImplTest.java | 0 .../device/simh/commands/AttachPTP.java | 31 ------------ .../device/simh/commands/AttachPTR.java | 25 ---------- .../device/simh/commands/DetachPTP.java | 25 ---------- .../device/simh/commands/DetachPTR.java | 25 ---------- .../device/simh/commands/GetBankSelect.java | 27 ---------- .../simh/commands/GetHostOSPathSeparator.java | 25 ---------- .../device/simh/commands/HasBankedMemory.java | 27 ---------- .../device/simh/commands/PrintTime.java | 25 ---------- .../device/simh/commands/ResetPTR.java | 25 ---------- .../simh/commands/ResetSimhInterface.java | 27 ---------- .../device/simh/commands/ResetStopWatch.java | 25 ---------- .../device/simh/commands/Set8080CPU.java | 25 ---------- .../device/simh/commands/SetBankSelect.java | 26 ---------- .../device/simh/commands/SetZ80CPU.java | 25 ---------- .../simh/commands/StopTimerInterrupts.java | 25 ---------- settings.gradle | 2 +- 60 files changed, 1059 insertions(+), 393 deletions(-) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/README.md (61%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/build.gradle (100%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/Commands.java (88%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java (68%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java (100%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java (100%) create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java (57%) create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java (62%) create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java (59%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java (77%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java (76%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java (55%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java (83%) create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java (51%) create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java (60%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java (75%) create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java (55%) create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java (56%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java (77%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java (74%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java (61%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java (57%) create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java (50%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java (55%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java (64%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java (51%) create mode 100644 plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/main/resources/net/emustudio/plugins/device/simh/version.properties (100%) rename plugins/device/{simhPseudo-z80 => simh-pseudo}/src/test/java/net/emustudio/plugins/device/simh/DeviceImplTest.java (100%) delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java delete mode 100644 plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java diff --git a/application/build.gradle b/application/build.gradle index 0a4b4a231..c95a4d6cf 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -74,7 +74,7 @@ dependencies { providedRuntime project(":plugins:device:88-sio") providedRuntime project(":plugins:device:adm3A-terminal") providedRuntime project(":plugins:device:brainduck-terminal") - providedRuntime project(":plugins:device:simhPseudo-z80") + providedRuntime project(":plugins:device:simh-pseudo") providedRuntime project(":plugins:device:ssem-display") testImplementation libs.junit @@ -215,7 +215,7 @@ distributions { from(output(":plugins:device:88-sio")) from(output(":plugins:device:adm3A-terminal")) from(output(":plugins:device:brainduck-terminal")) - from(output(":plugins:device:simhPseudo-z80")) + from(output(":plugins:device:simh-pseudo")) from(output(":plugins:device:ssem-display")) } diff --git a/plugins/device/simhPseudo-z80/README.md b/plugins/device/simh-pseudo/README.md similarity index 61% rename from plugins/device/simhPseudo-z80/README.md rename to plugins/device/simh-pseudo/README.md index 9ed101aa0..035a862cd 100644 --- a/plugins/device/simhPseudo-z80/README.md +++ b/plugins/device/simh-pseudo/README.md @@ -1,6 +1,6 @@ -# simhPseudo-z80 +# simh-pseudo -This project is emulator of abstract device - "SIMH" - for MITS Altair computers. +This project is an emulator of a pseudo-device - "SIMH", used in AltairZ80 simh emulator, specifically in 88-SIO. It is part of [emuStudio](https://www.emustudio.net/). The official documentation can be found [here](https://www.emustudio.net/docuser/mits_altair_8800/index/#virtual-device-code-simhpseudo-z80-code) diff --git a/plugins/device/simhPseudo-z80/build.gradle b/plugins/device/simh-pseudo/build.gradle similarity index 100% rename from plugins/device/simhPseudo-z80/build.gradle rename to plugins/device/simh-pseudo/build.gradle diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/Commands.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java similarity index 88% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/Commands.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java index f704ec8f0..bda8dea0f 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/Commands.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh; import net.emustudio.plugins.device.simh.commands.*; diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java similarity index 68% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java index fa038de4e..da1c18c64 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh; import net.emustudio.emulib.plugins.memory.MemoryContext; diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java similarity index 100% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java similarity index 100% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java new file mode 100644 index 000000000..6a04d0eff --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java @@ -0,0 +1,49 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class AttachPTP implements Command { + public final static AttachPTP INS = new AttachPTP(); + private int lastCPMStatus = 0; // result of last attachCPM command + + @Override + public void reset() { + lastCPMStatus = 0; + } + + @Override + public byte read(Control control) { + byte result = (byte) lastCPMStatus; + control.clearCommand(); + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + // attachCPM( & ptp_unit); + } + + + +} diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java new file mode 100644 index 000000000..1a78b218a --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java @@ -0,0 +1,43 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class AttachPTR implements Command { + public final static AttachPTR INS = new AttachPTR(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + //attachCPM( & ptr_unit); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java similarity index 57% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java index 64995ffc3..4179f84fa 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; import net.emustudio.emulib.plugins.device.DeviceContext; diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java new file mode 100644 index 000000000..d30f22472 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java @@ -0,0 +1,43 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class DetachPTP implements Command { + public final static DetachPTP INS = new DetachPTP(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + //detach_unit( & ptp_unit); + } +} diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java new file mode 100644 index 000000000..e4fdeb799 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java @@ -0,0 +1,43 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class DetachPTR implements Command { + public final static DetachPTR INS = new DetachPTR(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + //detach_unit( & ptr_unit); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java similarity index 62% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java index 0ca74bcc7..4972f42bc 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; public class GenInterrupt implements Command { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java new file mode 100644 index 000000000..84c0acd9d --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java @@ -0,0 +1,45 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class GetBankSelect implements Command { + public final static GetBankSelect INS = new GetBankSelect(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + byte result = (byte)control.getMemory().getSelectedBank(); + control.clearCommand(); + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java similarity index 59% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java index 812d2365e..d7a50db56 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; import java.util.concurrent.atomic.AtomicInteger; diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java similarity index 77% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java index 4c4d9b096..4bc99c208 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; import java.time.Instant; diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java similarity index 76% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java index 464ce43aa..b25646ea5 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; import java.time.Instant; diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java similarity index 55% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java index f2ce26996..526877600 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; public class GetCommon implements Command { diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java similarity index 83% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java index 68fc62413..927306c96 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; import org.slf4j.Logger; diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java new file mode 100644 index 000000000..4c42badf8 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java @@ -0,0 +1,43 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class GetHostOSPathSeparator implements Command { + public final static GetHostOSPathSeparator INS = new GetHostOSPathSeparator(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return (byte) GetHostFilenames.hostPathSeparator; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java similarity index 51% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java index e77462418..55925101a 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; public class GetSimhVersion implements Command { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java new file mode 100644 index 000000000..4bfae5aa8 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java @@ -0,0 +1,45 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class HasBankedMemory implements Command { + public final static HasBankedMemory INS = new HasBankedMemory(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + byte result = (byte)control.getMemory().getBanksCount(); + control.clearCommand(); + return result; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + + } +} diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java new file mode 100644 index 000000000..2204249a2 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java @@ -0,0 +1,43 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class PrintTime implements Command { + public final static PrintTime INS = new PrintTime(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + System.out.printf("SIMH: Current time in milliseconds = %d.\n", System.currentTimeMillis()); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java similarity index 60% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java index 92b8668b5..e712d45e4 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; public class ReadStopWatch implements Command { diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java similarity index 75% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java index 670a315e7..741d8f3f8 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; import java.util.Arrays; diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java new file mode 100644 index 000000000..6566eb367 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java @@ -0,0 +1,43 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class ResetPTR implements Command { + public final static ResetPTR INS = new ResetPTR(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + //ptr_reset( & ptr_dev); + } +} diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java new file mode 100644 index 000000000..0bc95e880 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java @@ -0,0 +1,45 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class ResetSimhInterface implements Command { + public final static ResetSimhInterface INS = new ResetSimhInterface(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + StartTimer.INS.markTimeSP = 0; + control.clearCommand(); + GetHostFilenames.INS.reset(); + } +} diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java new file mode 100644 index 000000000..4c82bfc57 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java @@ -0,0 +1,43 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class ResetStopWatch implements Command { + public final static ResetStopWatch INS = new ResetStopWatch(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + ReadStopWatch.INS.stopWatchNow = System.currentTimeMillis(); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java similarity index 55% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java index 048e79f16..01a43506d 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; public class SIMHSleep implements Command { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java new file mode 100644 index 000000000..b00a17190 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java @@ -0,0 +1,43 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class Set8080CPU implements Command { + public final static Set8080CPU INS = new Set8080CPU(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + System.out.println("SIMH: Set 8080 CPU command not supported!"); + } +} diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java new file mode 100644 index 000000000..583dc9b19 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java @@ -0,0 +1,44 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class SetBankSelect implements Command { + public final static SetBankSelect INS = new SetBankSelect(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + control.getMemory().selectBank(data); + control.clearCommand(); + } + + @Override + public void start(Control control) { + + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java similarity index 56% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java index 46e06d190..f0e0f2c76 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; public class SetCPUClockFrequency implements Command { diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java similarity index 77% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java index 13c437438..94583b999 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java similarity index 74% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java index 5cf42076d..5d51c3cf6 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java similarity index 61% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java index a5d161ba1..9491a2c5d 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; public class SetTimerDelta implements Command { diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java similarity index 57% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java index 366cf2ec3..cae761bff 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; public class SetTimerInterruptAdr implements Command { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java new file mode 100644 index 000000000..8e63c8783 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java @@ -0,0 +1,43 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class SetZ80CPU implements Command { + public final static SetZ80CPU INS = new SetZ80CPU(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + System.out.println("SIMH: Set Z80 CPU command not supported!"); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java similarity index 50% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java index 622e9cbba..c8cc21df6 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; public class ShowTimer implements Command { diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java similarity index 55% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java index 1b286e43b..e120c7dc7 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; public class StartTimer implements Command { diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java similarity index 64% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java index 2183af48c..bc4250e7b 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; import java.util.concurrent.*; diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java similarity index 51% rename from plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java rename to plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java index e57688b67..93ea3a310 100644 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.simh.commands; public class StopTimer implements Command { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java new file mode 100644 index 000000000..ac10a9207 --- /dev/null +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java @@ -0,0 +1,43 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.simh.commands; + +public class StopTimerInterrupts implements Command { + public final static StopTimerInterrupts INS = new StopTimerInterrupts(); + + @Override + public void reset() { + + } + + @Override + public byte read(Control control) { + return 0; + } + + @Override + public void write(byte data, Control control) { + + } + + @Override + public void start(Control control) { + StartTimerInterrupts.INS.reset(); + } +} diff --git a/plugins/device/simhPseudo-z80/src/main/resources/net/emustudio/plugins/device/simh/version.properties b/plugins/device/simh-pseudo/src/main/resources/net/emustudio/plugins/device/simh/version.properties similarity index 100% rename from plugins/device/simhPseudo-z80/src/main/resources/net/emustudio/plugins/device/simh/version.properties rename to plugins/device/simh-pseudo/src/main/resources/net/emustudio/plugins/device/simh/version.properties diff --git a/plugins/device/simhPseudo-z80/src/test/java/net/emustudio/plugins/device/simh/DeviceImplTest.java b/plugins/device/simh-pseudo/src/test/java/net/emustudio/plugins/device/simh/DeviceImplTest.java similarity index 100% rename from plugins/device/simhPseudo-z80/src/test/java/net/emustudio/plugins/device/simh/DeviceImplTest.java rename to plugins/device/simh-pseudo/src/test/java/net/emustudio/plugins/device/simh/DeviceImplTest.java diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java deleted file mode 100644 index 27fa97d38..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class AttachPTP implements Command { - public final static AttachPTP INS = new AttachPTP(); - private int lastCPMStatus = 0; // result of last attachCPM command - - @Override - public void reset() { - lastCPMStatus = 0; - } - - @Override - public byte read(Control control) { - byte result = (byte) lastCPMStatus; - control.clearCommand(); - return result; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - // attachCPM( & ptp_unit); - } - - - -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java deleted file mode 100644 index ac9886376..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class AttachPTR implements Command { - public final static AttachPTR INS = new AttachPTR(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - //attachCPM( & ptr_unit); - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java deleted file mode 100644 index 3de28f5c8..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class DetachPTP implements Command { - public final static DetachPTP INS = new DetachPTP(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - //detach_unit( & ptp_unit); - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java deleted file mode 100644 index 3d7a5d2e2..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class DetachPTR implements Command { - public final static DetachPTR INS = new DetachPTR(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - //detach_unit( & ptr_unit); - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java deleted file mode 100644 index 917855d53..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class GetBankSelect implements Command { - public final static GetBankSelect INS = new GetBankSelect(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - byte result = (byte)control.getMemory().getSelectedBank(); - control.clearCommand(); - return result; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java deleted file mode 100644 index 0b295b9c0..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class GetHostOSPathSeparator implements Command { - public final static GetHostOSPathSeparator INS = new GetHostOSPathSeparator(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return (byte) GetHostFilenames.hostPathSeparator; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java deleted file mode 100644 index 40baf8a12..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class HasBankedMemory implements Command { - public final static HasBankedMemory INS = new HasBankedMemory(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - byte result = (byte)control.getMemory().getBanksCount(); - control.clearCommand(); - return result; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java deleted file mode 100644 index 97f468221..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class PrintTime implements Command { - public final static PrintTime INS = new PrintTime(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - System.out.printf("SIMH: Current time in milliseconds = %d.\n", System.currentTimeMillis()); - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java deleted file mode 100644 index bd96e13af..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class ResetPTR implements Command { - public final static ResetPTR INS = new ResetPTR(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - //ptr_reset( & ptr_dev); - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java deleted file mode 100644 index 53298b096..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class ResetSimhInterface implements Command { - public final static ResetSimhInterface INS = new ResetSimhInterface(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - StartTimer.INS.markTimeSP = 0; - control.clearCommand(); - GetHostFilenames.INS.reset(); - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java deleted file mode 100644 index 2ec30c56e..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class ResetStopWatch implements Command { - public final static ResetStopWatch INS = new ResetStopWatch(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - ReadStopWatch.INS.stopWatchNow = System.currentTimeMillis(); - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java deleted file mode 100644 index d4a38ab2d..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class Set8080CPU implements Command { - public final static Set8080CPU INS = new Set8080CPU(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - System.out.println("SIMH: Set 8080 CPU command not supported!"); - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java deleted file mode 100644 index e7d879900..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class SetBankSelect implements Command { - public final static SetBankSelect INS = new SetBankSelect(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - control.getMemory().selectBank(data); - control.clearCommand(); - } - - @Override - public void start(Control control) { - - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java deleted file mode 100644 index da0936b31..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class SetZ80CPU implements Command { - public final static SetZ80CPU INS = new SetZ80CPU(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - System.out.println("SIMH: Set Z80 CPU command not supported!"); - } -} diff --git a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java b/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java deleted file mode 100644 index 09b5c35c6..000000000 --- a/plugins/device/simhPseudo-z80/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.emustudio.plugins.device.simh.commands; - -public class StopTimerInterrupts implements Command { - public final static StopTimerInterrupts INS = new StopTimerInterrupts(); - - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - - @Override - public void start(Control control) { - StartTimerInterrupts.INS.reset(); - } -} diff --git a/settings.gradle b/settings.gradle index 9ac0f3da4..7f2a49c2c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -47,7 +47,7 @@ include ':plugins:device:88-sio' include ':plugins:device:abstract-tape' include ':plugins:device:adm3A-terminal' include ':plugins:device:brainduck-terminal' -include ':plugins:device:simhPseudo-z80' +include ':plugins:device:simh-pseudo' include ':plugins:device:ssem-display' include ':plugins:memory:ram-mem' From eccf7c832f5a90389b2dd40221a0d7e4c547d040 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 23 Jul 2022 09:50:19 +0100 Subject: [PATCH 177/314] [#175] simh-pseudo: fix --- .../main/files/config/MITSAltair8800Z80.toml | 4 +-- .../plugins/device/simh/Commands.java | 4 +-- .../plugins/device/simh/PseudoContext.java | 36 ++++++++++++++----- .../device/simh/commands/AttachPTP.java | 9 +---- .../device/simh/commands/AttachPTR.java | 11 +----- .../plugins/device/simh/commands/Command.java | 20 ++++++++--- .../device/simh/commands/DetachPTP.java | 16 +-------- .../device/simh/commands/DetachPTR.java | 16 +-------- .../device/simh/commands/GenInterrupt.java | 12 +------ .../device/simh/commands/GetBankSelect.java | 12 +------ .../simh/commands/GetCPUClockFrequency.java | 6 +--- .../device/simh/commands/GetClockCPM3.java | 6 +--- .../device/simh/commands/GetClockZSDOS.java | 6 +--- .../device/simh/commands/GetCommon.java | 6 +--- .../simh/commands/GetHostFilenames.java | 6 +--- .../simh/commands/GetHostOSPathSeparator.java | 12 +------ .../device/simh/commands/GetSimhVersion.java | 6 +--- .../device/simh/commands/HasBankedMemory.java | 12 +------ .../device/simh/commands/PrintTime.java | 16 +-------- .../device/simh/commands/ReadStopWatch.java | 6 +--- .../device/simh/commands/ResetPTR.java | 16 +-------- .../simh/commands/ResetSimhInterface.java | 16 +-------- .../device/simh/commands/ResetStopWatch.java | 16 +-------- .../device/simh/commands/SIMHSleep.java | 20 +---------- .../device/simh/commands/Set8080CPU.java | 16 +-------- .../device/simh/commands/SetBankSelect.java | 15 -------- .../simh/commands/SetCPUClockFrequency.java | 6 +--- .../device/simh/commands/SetClockCPM3.java | 6 +--- .../device/simh/commands/SetClockZSDOS.java | 6 +--- .../device/simh/commands/SetTimerDelta.java | 6 +--- .../simh/commands/SetTimerInterruptAdr.java | 6 +--- .../device/simh/commands/SetZ80CPU.java | 16 +-------- .../device/simh/commands/ShowTimer.java | 16 +-------- .../device/simh/commands/StartTimer.java | 11 +----- .../simh/commands/StartTimerInterrupts.java | 11 +----- .../device/simh/commands/StopTimer.java | 16 +-------- .../simh/commands/StopTimerInterrupts.java | 16 +-------- 37 files changed, 80 insertions(+), 357 deletions(-) diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index 21d218180..61d2a7121 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -121,9 +121,9 @@ name = "MITS Altair8800 (Z80)" [[DEVICE]] schemaPoint = "220,60" - path = "simhPseudo-z80.jar" + path = "simh-pseudo.jar" settings = {} - name = "simhPseudo-z80" + name = "simh-pseudo" id = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" type = "DEVICE" diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java index bda8dea0f..21dda314d 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java @@ -57,8 +57,8 @@ public enum Commands { readURLCmd, // 30 read the contents of an URL getCPUClockFrequency, // 31 get the clock frequency of the CPU setCPUClockFrequency, // 32 set the clock frequency of the CPU - genInterruptCmd; // 33 generate interrupt - + genInterruptCmd, // 33 generate interrupt, + unknownCmd; public static Commands fromInt(int number) { for (Commands c : Commands.values()) { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java index cb8baa54a..f63e21673 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java @@ -63,12 +63,24 @@ class PseudoContext implements DeviceContext, Command.Control { private ByteMemoryContext memory; private ExtendedContext cpu; - private Commands lastCommand = printTimeCmd; // most recent command processed on port 0xfeh + private Commands lastReadCommand = unknownCmd; + private Commands lastWriteCommand = unknownCmd; @Override public void clearCommand() { - lastCommand = printTimeCmd; + lastReadCommand = unknownCmd; + lastWriteCommand = unknownCmd; + } + + @Override + public void clearReadCommand() { + lastReadCommand = unknownCmd; + } + + @Override + public void clearWriteCommand() { + lastWriteCommand = unknownCmd; } @Override @@ -102,27 +114,35 @@ void reset() { @Override public Byte readData() { - int lastCommandOrdinal = lastCommand.ordinal(); + System.out.println("SIMH: R , lastCommand=" + lastReadCommand); + int lastCommandOrdinal = lastReadCommand.ordinal(); if (!COMMANDS_MAP.containsKey(lastCommandOrdinal)) { System.out.printf("SIMH: Unknown command (%d) to SIMH pseudo device ignored.\n", lastCommandOrdinal); clearCommand(); } else { - return COMMANDS_MAP.get(lastCommand.ordinal()).read(this); + byte x = COMMANDS_MAP.get(lastReadCommand.ordinal()).read(this); + System.out.println(" R: " + Integer.toHexString(x)); + return x; } return 0; } @Override public void writeData(Byte data) { - int lastCommandOrdinal = lastCommand.ordinal(); + System.out.println("SIMH: W " + data); + + int lastCommandOrdinal = lastWriteCommand.ordinal(); if (!COMMANDS_MAP.containsKey(lastCommandOrdinal)) { - lastCommand = Commands.fromInt(data); - if (!COMMANDS_MAP.containsKey(lastCommand.ordinal())) { + lastReadCommand = Commands.fromInt(data); + lastWriteCommand = Commands.fromInt(data); + if (!COMMANDS_MAP.containsKey(lastWriteCommand.ordinal())) { System.out.printf("SIMH: Unknown command (%d) to SIMH pseudo device ignored.\n", data); } else { - COMMANDS_MAP.get(lastCommand.ordinal()).start(this); + System.out.println(" S; " + lastWriteCommand); + COMMANDS_MAP.get(lastWriteCommand.ordinal()).start(this); } } else { + System.out.println(" W; " + lastWriteCommand); COMMANDS_MAP.get(lastCommandOrdinal).write(data, this); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java index 6a04d0eff..1e932b4dd 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java @@ -34,16 +34,9 @@ public byte read(Control control) { return result; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { // attachCPM( & ptp_unit); + control.clearWriteCommand(); } - - - } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java index 1a78b218a..eed9f33e3 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTR.java @@ -21,23 +21,14 @@ public class AttachPTR implements Command { public final static AttachPTR INS = new AttachPTR(); - @Override - public void reset() { - - } - @Override public byte read(Control control) { return 0; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { //attachCPM( & ptr_unit); + control.clearWriteCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java index 4179f84fa..25ccda47b 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java @@ -30,7 +30,9 @@ public interface Command { /** * Called on SIMH interface reset */ - void reset(); + default void reset() { + + } /** * Read byte @@ -38,7 +40,9 @@ public interface Command { * @param control control * @return data */ - byte read(Control control); + default byte read(Control control) { + return 0; + } /** * Write data byte @@ -46,14 +50,18 @@ public interface Command { * @param data byte * @param control control */ - void write(byte data, Control control); + default void write(byte data, Control control) { + + } /** * On command start * * @param control control */ - void start(Control control); + default void start(Control control) { + + } interface Control { @@ -63,6 +71,10 @@ interface Control { */ void clearCommand(); + void clearReadCommand(); + + void clearWriteCommand(); + ByteMemoryContext getMemory(); ExtendedContext getCpu(); diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java index d30f22472..d8fd15330 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTP.java @@ -21,23 +21,9 @@ public class DetachPTP implements Command { public final static DetachPTP INS = new DetachPTP(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { //detach_unit( & ptp_unit); + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java index e4fdeb799..bce63bca3 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/DetachPTR.java @@ -21,23 +21,9 @@ public class DetachPTR implements Command { public final static DetachPTR INS = new DetachPTR(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { //detach_unit( & ptr_unit); + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java index 4972f42bc..def1d61a7 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java @@ -24,16 +24,6 @@ public class GenInterrupt implements Command { private int genInterruptPos = 0; // determines state for receiving interrupt vector and data private int genInterruptVec = 0; // stores interrupt vector - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - @Override public void write(byte data, Control control) { if (genInterruptPos == 0) { @@ -52,6 +42,6 @@ public void write(byte data, Control control) { @Override public void start(Control control) { - + control.clearReadCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java index 84c0acd9d..becc4ea75 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java @@ -21,11 +21,6 @@ public class GetBankSelect implements Command { public final static GetBankSelect INS = new GetBankSelect(); - @Override - public void reset() { - - } - @Override public byte read(Control control) { byte result = (byte)control.getMemory().getSelectedBank(); @@ -33,13 +28,8 @@ public byte read(Control control) { return result; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { - + control.clearWriteCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java index d7a50db56..9e44e882f 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java @@ -46,13 +46,9 @@ public byte read(Control control) { return result; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { getClockFrequencyPos = 0; + control.clearWriteCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java index 4bc99c208..07a5f8aa9 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java @@ -86,11 +86,6 @@ public byte read(Control control) { return result; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { int delta = SetClockCPM3.INS.ClockCPM3Delta; @@ -98,5 +93,6 @@ public void start(Control control) { currentTimeValid = true; daysCPM3SinceOrg = (int)((currentTime.toEpochSecond(ZoneOffset.UTC) - CPM3_ORIGIN) / SECONDS_PER_DAY); getClockCPM3Pos = 0; + control.clearWriteCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java index b25646ea5..3d1d517f9 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java @@ -83,16 +83,12 @@ public byte read(Control control) { return result; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { int delta = SetClockZSDOS.INS.ClockZSDOSDelta; currentTime = LocalDateTime.from(Instant.ofEpochSecond(Instant.now().getEpochSecond() + delta)); currentTimeValid = true; getClockZSDOSPos = 0; + control.clearWriteCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java index 526877600..28a3ae336 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java @@ -42,13 +42,9 @@ public byte read(Control control) { return result; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { getCommonPos = 0; + control.clearWriteCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java index 927306c96..90e1b82c2 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java @@ -83,11 +83,6 @@ public byte read(Control control) { return result; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { if (nameListHead == null) { @@ -106,6 +101,7 @@ public void start(Control control) { currentName = nameListHead; currentNameIndex = 0; } + control.clearWriteCommand(); } private void deleteNameList() { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java index 4c42badf8..74a8e5f63 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostOSPathSeparator.java @@ -21,23 +21,13 @@ public class GetHostOSPathSeparator implements Command { public final static GetHostOSPathSeparator INS = new GetHostOSPathSeparator(); - @Override - public void reset() { - - } - @Override public byte read(Control control) { return (byte) GetHostFilenames.hostPathSeparator; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { - + control.clearWriteCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java index 55925101a..155e677cb 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java @@ -40,13 +40,9 @@ public byte read(Control control) { return result; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { versionPos = 0; + control.clearWriteCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java index 4bfae5aa8..d40a0fe30 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java @@ -21,11 +21,6 @@ public class HasBankedMemory implements Command { public final static HasBankedMemory INS = new HasBankedMemory(); - @Override - public void reset() { - - } - @Override public byte read(Control control) { byte result = (byte)control.getMemory().getBanksCount(); @@ -33,13 +28,8 @@ public byte read(Control control) { return result; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { - + control.clearWriteCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java index 2204249a2..43971277d 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/PrintTime.java @@ -21,23 +21,9 @@ public class PrintTime implements Command { public final static PrintTime INS = new PrintTime(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { System.out.printf("SIMH: Current time in milliseconds = %d.\n", System.currentTimeMillis()); + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java index e712d45e4..f70e12a2e 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java @@ -45,14 +45,10 @@ public byte read(Control control) { return result; } - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { getStopWatchDeltaPos = 0; stopWatchDelta = System.currentTimeMillis() - stopWatchNow; + control.clearWriteCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java index 6566eb367..7feed3ba6 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetPTR.java @@ -21,23 +21,9 @@ public class ResetPTR implements Command { public final static ResetPTR INS = new ResetPTR(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { //ptr_reset( & ptr_dev); + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java index 0bc95e880..25ac2a725 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java @@ -21,25 +21,11 @@ public class ResetSimhInterface implements Command { public final static ResetSimhInterface INS = new ResetSimhInterface(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { StartTimer.INS.markTimeSP = 0; control.clearCommand(); GetHostFilenames.INS.reset(); + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java index 4c82bfc57..cb7290b97 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetStopWatch.java @@ -21,23 +21,9 @@ public class ResetStopWatch implements Command { public final static ResetStopWatch INS = new ResetStopWatch(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { ReadStopWatch.INS.stopWatchNow = System.currentTimeMillis(); + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java index 01a43506d..9000a5135 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java @@ -22,27 +22,8 @@ public class SIMHSleep implements Command { public final static SIMHSleep INS = new SIMHSleep(); private final static int SIMHSleepMillis = 1; - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { - do_SIMH_sleep(); - } - - private void do_SIMH_sleep() { // TODO: // Do not sleep when timer interrupts are pending or are about to be created. // Otherwise there is the possibility that such interrupts are skipped. @@ -53,5 +34,6 @@ private void do_SIMH_sleep() { } catch (InterruptedException e) { Thread.currentThread().interrupt(); } + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java index b00a17190..f42b418e4 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Set8080CPU.java @@ -21,23 +21,9 @@ public class Set8080CPU implements Command { public final static Set8080CPU INS = new Set8080CPU(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { System.out.println("SIMH: Set 8080 CPU command not supported!"); + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java index 583dc9b19..2cb987868 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetBankSelect.java @@ -21,24 +21,9 @@ public class SetBankSelect implements Command { public final static SetBankSelect INS = new SetBankSelect(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - @Override public void write(byte data, Control control) { control.getMemory().selectBank(data); control.clearCommand(); } - - @Override - public void start(Control control) { - - } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java index f0e0f2c76..b9809337a 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java @@ -29,11 +29,6 @@ public void reset() { setClockFrequencyPos = 0; } - @Override - public byte read(Control control) { - return 0; - } - @Override public void write(byte data, Control control) { if (setClockFrequencyPos == 0) { @@ -49,5 +44,6 @@ public void write(byte data, Control control) { @Override public void start(Control control) { setClockFrequencyPos = 0; + control.clearReadCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java index 94583b999..297810157 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java @@ -39,11 +39,6 @@ public void reset() { setClockCPM3Pos = 0; } - @Override - public byte read(Control control) { - return 0; - } - @Override public void write(byte data, Control control) { if (setClockCPM3Pos == 0) { @@ -60,6 +55,7 @@ public void write(byte data, Control control) { @Override public void start(Control control) { setClockCPM3Pos = 0; + control.clearReadCommand(); } /* setClockCPM3Adr points to 5 byte block in M: diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java index 5d51c3cf6..905dd70c0 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java @@ -38,11 +38,6 @@ public void reset() { setClockZSDOSPos = 0; } - @Override - public byte read(Control control) { - return 0; - } - @Override public void write(byte data, Control control) { if (setClockZSDOSPos == 0) { @@ -59,6 +54,7 @@ public void write(byte data, Control control) { @Override public void start(Control control) { setClockZSDOSPos = 0; + control.clearReadCommand(); } /* setClockZSDOSAdr points to 6 byte block in M: YY MM DD HH MM SS in BCD notation */ diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java index 9491a2c5d..664404f1c 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java @@ -31,11 +31,6 @@ public void reset() { setTimerDeltaPos = 0; } - @Override - public byte read(Control control) { - return 0; - } - @Override public void write(byte data, Control control) { if (setTimerDeltaPos == 0) { @@ -55,5 +50,6 @@ public void write(byte data, Control control) { @Override public void start(Control control) { reset(); + control.clearReadCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java index cae761bff..48b34679d 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java @@ -29,11 +29,6 @@ public void reset() { setTimerInterruptAdrPos = 0; } - @Override - public byte read(Control control) { - return 0; - } - @Override public void write(byte data, Control control) { if (setTimerInterruptAdrPos == 0) { @@ -49,5 +44,6 @@ public void write(byte data, Control control) { @Override public void start(Control control) { reset(); + control.clearReadCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java index 8e63c8783..dbb485c40 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetZ80CPU.java @@ -21,23 +21,9 @@ public class SetZ80CPU implements Command { public final static SetZ80CPU INS = new SetZ80CPU(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { System.out.println("SIMH: Set Z80 CPU command not supported!"); + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java index c8cc21df6..a77a0300f 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ShowTimer.java @@ -21,21 +21,6 @@ public class ShowTimer implements Command { public final static ShowTimer INS = new ShowTimer(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { if (StartTimer.INS.markTimeSP > 0) { @@ -44,5 +29,6 @@ public void start(Control control) { } else { System.out.println("SIMH: No timer active."); } + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java index e120c7dc7..4d358dc11 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java @@ -31,16 +31,6 @@ public void reset() { markTimeSP = 0; } - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { if (markTimeSP < TIMER_STACK_LIMIT) { @@ -48,5 +38,6 @@ public void start(Control control) { } else { System.out.println("SIMH: Timer stack overflow"); } + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java index bc4250e7b..e5c6af61e 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java @@ -34,16 +34,6 @@ public void reset() { } } - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { reset(); @@ -55,5 +45,6 @@ public void start(Control control) { byte b2 = (byte) (addr >>> 8); control.getCpu().signalInterrupt(control.getDevice(), new byte[]{(byte) 0xCD, b1, b2}); }, SetTimerDelta.INS.timerDelta, SetTimerDelta.INS.timerDelta, TimeUnit.MILLISECONDS)); + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java index 93ea3a310..fe59bef02 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimer.java @@ -21,21 +21,6 @@ public class StopTimer implements Command { public final static StopTimer INS = new StopTimer(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { if (StartTimer.INS.markTimeSP > 0) { @@ -45,5 +30,6 @@ public void start(Control control) { } else { System.out.println("SIMH: No timer active"); } + control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java index ac10a9207..f0f0c27d7 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java @@ -21,23 +21,9 @@ public class StopTimerInterrupts implements Command { public final static StopTimerInterrupts INS = new StopTimerInterrupts(); - @Override - public void reset() { - - } - - @Override - public byte read(Control control) { - return 0; - } - - @Override - public void write(byte data, Control control) { - - } - @Override public void start(Control control) { StartTimerInterrupts.INS.reset(); + control.clearCommand(); } } From aa2f182239c115051a20638c55d5385deaeb976d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 23 Jul 2022 09:52:57 +0100 Subject: [PATCH 178/314] [#175] Remove println --- .../net/emustudio/plugins/device/simh/PseudoContext.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java index f63e21673..c0c4e21ea 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java @@ -114,23 +114,18 @@ void reset() { @Override public Byte readData() { - System.out.println("SIMH: R , lastCommand=" + lastReadCommand); int lastCommandOrdinal = lastReadCommand.ordinal(); if (!COMMANDS_MAP.containsKey(lastCommandOrdinal)) { System.out.printf("SIMH: Unknown command (%d) to SIMH pseudo device ignored.\n", lastCommandOrdinal); clearCommand(); } else { - byte x = COMMANDS_MAP.get(lastReadCommand.ordinal()).read(this); - System.out.println(" R: " + Integer.toHexString(x)); - return x; + return COMMANDS_MAP.get(lastReadCommand.ordinal()).read(this); } return 0; } @Override public void writeData(Byte data) { - System.out.println("SIMH: W " + data); - int lastCommandOrdinal = lastWriteCommand.ordinal(); if (!COMMANDS_MAP.containsKey(lastCommandOrdinal)) { lastReadCommand = Commands.fromInt(data); @@ -138,11 +133,9 @@ public void writeData(Byte data) { if (!COMMANDS_MAP.containsKey(lastWriteCommand.ordinal())) { System.out.printf("SIMH: Unknown command (%d) to SIMH pseudo device ignored.\n", data); } else { - System.out.println(" S; " + lastWriteCommand); COMMANDS_MAP.get(lastWriteCommand.ordinal()).start(this); } } else { - System.out.println(" W; " + lastWriteCommand); COMMANDS_MAP.get(lastCommandOrdinal).write(data, this); } } From e1e14a751b05d910eac99ac7db6c4f11b1c33d94 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 23 Jul 2022 20:18:53 +0100 Subject: [PATCH 179/314] [#175] simh: fix interrupts --- .../plugins/cpu/zilogZ80/ContextImpl.java | 10 ++--- .../plugins/cpu/zilogZ80/CpuImpl.java | 1 + .../plugins/cpu/zilogZ80/EmulatorEngine.java | 38 ++++++++++--------- .../simh/commands/StartTimerInterrupts.java | 1 - 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java index 6c4df269d..52b8ae754 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java @@ -33,11 +33,11 @@ public final class ContextImpl implements ExtendedContext { private final static Logger LOGGER = LoggerFactory.getLogger(ContextImpl.class); private final ConcurrentMap> devices = new ConcurrentHashMap<>(); - private volatile EmulatorEngine cpu; + private volatile EmulatorEngine engine; private volatile int clockFrequency = DEFAULT_FREQUENCY_KHZ; - public void setCpu(EmulatorEngine cpu) { - this.cpu = cpu; + public void setEngine(EmulatorEngine engine) { + this.engine = engine; } // device mapping = only one device can be attached to one port @@ -91,8 +91,8 @@ public void setCPUFrequency(int frequency) { @Override - public void signalInterrupt(DeviceContext device, byte[] data) { - cpu.requestInterrupt(data); + public void signalInterrupt(DeviceContext device, byte[] data) { + engine.requestInterrupt(data); } @Override diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java index 98a0eca07..31da3d054 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java @@ -99,6 +99,7 @@ public void initialize() throws PluginInitializationException { initializer.initialize(); disassembler = initializer.getDisassembler(); engine = initializer.getEngine(); + context.setEngine(engine); statusPanel = new StatusPanel(this, context, initializer.shouldDumpInstructions()); } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 2c286f7c8..c51c9a0d5 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -20,7 +20,6 @@ import net.emustudio.emulib.plugins.cpu.CPU; import net.emustudio.emulib.plugins.cpu.CPU.RunState; -import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.helpers.SleepUtils; import net.emustudio.plugins.cpu.intel8080.api.CpuEngine; @@ -35,7 +34,6 @@ import java.util.List; import java.util.Objects; import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CopyOnWriteArrayList; @@ -117,7 +115,10 @@ public void fireFrequencyChanged(float newFrequency) { } public void requestInterrupt(byte[] data) { - pendingInterrupts.add(data); + if (currentRunState == RunState.STATE_RUNNING) { + System.out.println("interrupt signalled!, " + Arrays.toString(data)); + pendingInterrupts.add(data); + } } void reset(int startPos) { @@ -271,6 +272,7 @@ private int doInterrupt() throws Throwable { int cycles = 0; IFF[0] = IFF[1] = false; + System.out.println("z80: interrupt! im=" + interruptMode + ", dataBus=" + Arrays.toString(dataBus)); switch (interruptMode) { case 0: cycles += 11; @@ -279,7 +281,7 @@ private int doInterrupt() throws Throwable { lastOpcode = dataBus[0] & 0xFF; // TODO: if dataBus had more bytes, they're ignored (except call). if (lastOpcode == 0xCD) { /* CALL */ SP = (SP - 2) & 0xFFFF; - writeWord(SP, (PC + 2) & 0xFFFF); + writeWord(SP, (PC - 1) & 0xFFFF); PC = ((dataBus[2] & 0xFF) << 8) | (dataBus[1] & 0xFF); return cycles + 17; } @@ -807,14 +809,14 @@ int I_EI() { return 4; } - int I_IN_R_REF_C() throws IOException { + int I_IN_R_REF_C() { int tmp = (lastOpcode >>> 3) & 0x7; putreg(tmp, context.readIO(regs[REG_C])); flags = (flags & FLAG_C) | TABLE_SZ[regs[tmp]] | EmulatorTables.PARITY_TABLE[regs[tmp]]; return 12; } - int I_OUT_REF_C_R() throws IOException { + int I_OUT_REF_C_R() { int tmp = (lastOpcode >>> 3) & 0x7; context.writeIO(regs[REG_C], (byte) getreg(tmp)); return 12; @@ -961,13 +963,13 @@ int I_RLD() { return 18; } - int I_IN_REF_C() throws IOException { + int I_IN_REF_C() { int tmp = (context.readIO(regs[REG_C]) & 0xFF); flags = TABLE_SZ[tmp] | EmulatorTables.PARITY_TABLE[tmp] | (flags & FLAG_C); return 12; } - int I_OUT_REF_C_0() throws IOException { + int I_OUT_REF_C_0() { context.writeIO(regs[REG_C], (byte) 0); return 12; } @@ -1159,7 +1161,7 @@ int I_LDIR() { return 21; } - int I_INI() throws IOException { + int I_INI() { byte value = context.readIO(regs[REG_C]); int address = (regs[REG_H] << 8) | regs[REG_L]; memory.write(address, value); @@ -1175,7 +1177,7 @@ int I_INI() throws IOException { return 16; } - int I_INIR() throws IOException { + int I_INIR() { byte value = context.readIO(regs[REG_C]); int address = (regs[REG_H] << 8) | regs[REG_L]; memory.write(address, value); @@ -1195,7 +1197,7 @@ int I_INIR() throws IOException { return 21; } - int I_IND() throws IOException { + int I_IND() { byte value = context.readIO(regs[REG_C]); int hl = (regs[REG_H] << 8) | regs[REG_L]; memory.write(hl, value); @@ -1210,7 +1212,7 @@ int I_IND() throws IOException { return 16; } - int I_INDR() throws IOException { + int I_INDR() { byte value = context.readIO(regs[REG_C]); int hl = (regs[REG_H] << 8) | regs[REG_L]; memory.write(hl, value); @@ -1230,7 +1232,7 @@ int I_INDR() throws IOException { return 21; } - int I_OUTI() throws IOException { + int I_OUTI() { int address = (regs[REG_H] << 8) | regs[REG_L]; byte value = memory.read(address); context.writeIO(regs[REG_C], value); @@ -1244,7 +1246,7 @@ int I_OUTI() throws IOException { return 16; } - int I_OTIR() throws IOException { + int I_OTIR() { int address = (regs[REG_H] << 8) | regs[REG_L]; byte value = memory.read(address); context.writeIO(regs[REG_C], value); @@ -1263,7 +1265,7 @@ int I_OTIR() throws IOException { return 21; } - int I_OUTD() throws IOException { + int I_OUTD() { int address = (regs[REG_H] << 8) | regs[REG_L]; byte value = memory.read(address); context.writeIO(regs[REG_C], value); @@ -1277,7 +1279,7 @@ int I_OUTD() throws IOException { return 16; } - int I_OTDR() throws IOException { + int I_OTDR() { int address = (regs[REG_H] << 8) | regs[REG_L]; byte value = memory.read(address); context.writeIO(regs[REG_C], value); @@ -1355,7 +1357,7 @@ int I_ADC_A_N() { return 7; } - int I_OUT_REF_N_A() throws IOException { + int I_OUT_REF_N_A() { int tmp = readByte(PC); PC = (PC + 1) & 0xFFFF; context.writeIO(tmp, (byte) regs[REG_A]); @@ -1374,7 +1376,7 @@ int I_SUB_N() { return 7; } - int I_IN_A_REF_N() throws IOException { + int I_IN_A_REF_N() { int tmp = readByte(PC); PC = (PC + 1) & 0xFFFF; regs[REG_A] = (context.readIO(tmp) & 0xFF); diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java index e5c6af61e..c82e0d1a6 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java @@ -37,7 +37,6 @@ public void reset() { @Override public void start(Control control) { reset(); - timerTask.set(executor.scheduleAtFixedRate(() -> { // will work only in interrupt mode 0 int addr = SetTimerInterruptAdr.INS.timerInterruptHandler; From a17492bfe06f5b81545f02525dc99a58d2d558bf Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 24 Jul 2022 11:19:44 +0100 Subject: [PATCH 180/314] [#175] z80: fix interrupt mode 2 handling --- .../net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index c51c9a0d5..f5d33c89d 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -270,6 +270,7 @@ int SPECIAL_CB_DISPATCH(MethodHandle[] table) throws Throwable { private int doInterrupt() throws Throwable { byte[] dataBus = pendingInterrupts.poll(); int cycles = 0; + PC = (PC - 1) & 0xFFFF; // return back PC IFF[0] = IFF[1] = false; System.out.println("z80: interrupt! im=" + interruptMode + ", dataBus=" + Arrays.toString(dataBus)); @@ -281,7 +282,7 @@ private int doInterrupt() throws Throwable { lastOpcode = dataBus[0] & 0xFF; // TODO: if dataBus had more bytes, they're ignored (except call). if (lastOpcode == 0xCD) { /* CALL */ SP = (SP - 2) & 0xFFFF; - writeWord(SP, (PC - 1) & 0xFFFF); + writeWord(SP, PC); PC = ((dataBus[2] & 0xFF) << 8) | (dataBus[1] & 0xFF); return cycles + 17; } @@ -301,7 +302,8 @@ private int doInterrupt() throws Throwable { case 2: cycles += 13; if (dataBus != null && dataBus.length > 0) { - writeWord((SP - 2) & 0xFFFF, PC); + SP = (SP - 2) & 0xFFFF; + writeWord(SP, PC); PC = readWord((I << 8) | dataBus[0]); } break; From df5be597ec85a6e24173d97192eaf41b8390d3ba Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 27 Jul 2022 10:50:25 +0100 Subject: [PATCH 181/314] [#175] z80: Added support for NMI + interrupt examples --- .../as-z80/src/main/examples/im0test.asm | 27 +++++++++++ .../as-z80/src/main/examples/im2test.asm | 47 +++++++++++++++++++ ...{ContextImpl.java => Context8080Impl.java} | 6 +-- .../plugins/cpu/intel8080/CpuImpl.java | 6 +-- .../plugins/cpu/intel8080/EmulatorEngine.java | 4 +- .../cpu/intel8080/InitializerFor8080.java | 4 +- ...{ExtendedContext.java => Context8080.java} | 2 +- .../cpu/intel8080/gui/StatusPanel.java | 6 +-- .../{ContextImpl.java => ContextZ80Impl.java} | 13 +++-- .../plugins/cpu/zilogZ80/CpuImpl.java | 10 ++-- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 47 +++++++++++-------- ...ializerForZ80.java => InitializerZ80.java} | 8 ++-- .../plugins/cpu/zilogZ80/api/ContextZ80.java | 15 ++++++ .../plugins/cpu/zilogZ80/gui/StatusPanel.java | 6 +-- .../cpu/zilogZ80/InstructionsTest.java | 6 +-- .../plugins/device/mits88dcdd/DeviceImpl.java | 6 +-- .../plugins/device/mits88sio/DeviceImpl.java | 4 +- .../device/mits88sio/ports/CpuPorts.java | 6 +-- .../device/mits88sio/DeviceImplTest.java | 6 +-- .../device/mits88sio/ports/CpuPortsTest.java | 8 ++-- .../plugins/device/simh/DeviceImpl.java | 4 +- .../plugins/device/simh/PseudoContext.java | 8 ++-- .../plugins/device/simh/commands/Command.java | 7 +-- 23 files changed, 177 insertions(+), 79 deletions(-) create mode 100644 plugins/compiler/as-z80/src/main/examples/im0test.asm create mode 100644 plugins/compiler/as-z80/src/main/examples/im2test.asm rename plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/{ContextImpl.java => Context8080Impl.java} (96%) rename plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/{ExtendedContext.java => Context8080.java} (96%) rename plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/{ContextImpl.java => ContextZ80Impl.java} (90%) rename plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/{InitializerForZ80.java => InitializerZ80.java} (88%) create mode 100644 plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/api/ContextZ80.java diff --git a/plugins/compiler/as-z80/src/main/examples/im0test.asm b/plugins/compiler/as-z80/src/main/examples/im0test.asm new file mode 100644 index 000000000..7254864bc --- /dev/null +++ b/plugins/compiler/as-z80/src/main/examples/im0test.asm @@ -0,0 +1,27 @@ +; Timer interrupt test (using SIMH-pseudo device) +; default handler address: 0xFC00 +; timer in simh-pseudo operates at interrupt mode 0 as a normal call + +dec sp ; initialize stack +im 0 ; interrupt mode 0 +ei ; enable interrupts + +ld a, 21 ; startTimerInterruptsCmd +out (0xfe), a ; out to simh-pseudo device + +loop: +ei +jp loop + +halt + +i1: db 'Hello from timer',10,13,0 + +include 'examples/as-z80/include/putstr.inc' + +; timer interrupt handler +org 0xFC00 + + ld hl, i1 + call putstr + reti diff --git a/plugins/compiler/as-z80/src/main/examples/im2test.asm b/plugins/compiler/as-z80/src/main/examples/im2test.asm new file mode 100644 index 000000000..e2c4341a3 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/examples/im2test.asm @@ -0,0 +1,47 @@ +; Generate interrupt test (using SIMH-pseudo device) +; Interrupt mode 2 +; +; IM 2 + +dec sp ; initialize stack + +im 2 +ld a, inttbl / 256 ; address of interrupt vector table +ld i,a +ei + +main: + +ld a, 33 ; genInterruptCmd +out (0xfe), a +ld a, 0 ; inthdlr1 +out (0xfe), a +out (0xfe), a // signal interrupt + +halt + +i1: db 'Hello from int1',10,13,0 +i2: db 'Hello from int2',10,13,0 + +include 'include/putstr.inc' + +org 0x100 + +; interrupt vector table +inttbl: + dw inthdlr1 + dw inthdlr2 + ; ... up to 0x1FF + + +org 0x200 + +inthdlr1: + ld hl, i1 + call putstr + reti + +inthdlr2: + ld hl, i2 + call putstr + reti diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/ContextImpl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java similarity index 96% rename from plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/ContextImpl.java rename to plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java index 573f6bd45..dc08f91d8 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/ContextImpl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java @@ -19,7 +19,7 @@ package net.emustudio.plugins.cpu.intel8080; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.jcip.annotations.ThreadSafe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,8 +28,8 @@ import java.util.concurrent.ConcurrentMap; @ThreadSafe -public class ContextImpl implements ExtendedContext { - private final static Logger LOGGER = LoggerFactory.getLogger(ContextImpl.class); +public class Context8080Impl implements Context8080 { + private final static Logger LOGGER = LoggerFactory.getLogger(Context8080Impl.class); private final ConcurrentMap> devices = new ConcurrentHashMap<>(); diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java index c4e4d9909..418266d4d 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java @@ -27,7 +27,7 @@ import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.cpu.intel8080.api.FrequencyUpdater; import net.emustudio.plugins.cpu.intel8080.gui.StatusPanel; import org.slf4j.Logger; @@ -54,7 +54,7 @@ public class CpuImpl extends AbstractCPU { private final ScheduledExecutorService frequencyScheduler = Executors.newSingleThreadScheduledExecutor(); private final AtomicReference> frequencyUpdaterFuture = new AtomicReference<>(); - private final ContextImpl context = new ContextImpl(); + private final Context8080Impl context = new Context8080Impl(); private final InitializerFor8080 initializer; private EmulatorEngine engine; @@ -65,7 +65,7 @@ public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings sett super(pluginID, applicationApi, settings); try { - applicationApi.getContextPool().register(pluginID, context, ExtendedContext.class); + applicationApi.getContextPool().register(pluginID, context, Context8080.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register CPU context", e); applicationApi.getDialogs().showError( diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java index ced513289..8696ae4a5 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java @@ -61,14 +61,14 @@ public class EmulatorEngine implements CpuEngine { private int lastOpcode; private final MemoryContext memory; - private final ContextImpl context; + private final Context8080Impl context; private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); private long executedCycles = 0; private volatile DispatchListener dispatchListener; - public EmulatorEngine(MemoryContext memory, ContextImpl context) { + public EmulatorEngine(MemoryContext memory, Context8080Impl context) { this.memory = memory; this.context = context; } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InitializerFor8080.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InitializerFor8080.java index 1244b6674..c51e90072 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InitializerFor8080.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InitializerFor8080.java @@ -33,11 +33,11 @@ import java.util.Objects; public class InitializerFor8080 extends DefaultInitializer { - private final ContextImpl context; + private final Context8080Impl context; public InitializerFor8080(Plugin plugin, long pluginId, ContextPool contextPool, PluginSettings settings, - ContextImpl context) { + Context8080Impl context) { super(plugin, pluginId, contextPool, settings); this.context = Objects.requireNonNull(context); } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/ExtendedContext.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/Context8080.java similarity index 96% rename from plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/ExtendedContext.java rename to plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/Context8080.java index e3d02708a..34383810d 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/ExtendedContext.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/Context8080.java @@ -26,7 +26,7 @@ * Extended CPU context for 8080 processor. */ @PluginContext -public interface ExtendedContext extends CPUContext { +public interface Context8080 extends CPUContext { /** * Attach a device into the CPU. diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java index 81b56cbb1..9cf686bc1 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java @@ -23,7 +23,7 @@ import net.emustudio.plugins.cpu.intel8080.CpuImpl; import net.emustudio.plugins.cpu.intel8080.EmulatorEngine; import net.emustudio.plugins.cpu.intel8080.InstructionPrinter; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import javax.swing.*; import javax.swing.table.AbstractTableModel; @@ -36,11 +36,11 @@ public class StatusPanel extends JPanel { private final CpuImpl cpu; private final EmulatorEngine engine; - private final ExtendedContext context; + private final Context8080 context; private final AbstractTableModel flagModel; private volatile RunState runState = RunState.STATE_STOPPED_NORMAL; - public StatusPanel(CpuImpl cpu, ExtendedContext context, boolean dumpInstructions) { + public StatusPanel(CpuImpl cpu, Context8080 context, boolean dumpInstructions) { this.cpu = cpu; this.context = context; this.engine = cpu.getEngine(); diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java similarity index 90% rename from plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java rename to plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java index 52b8ae754..ed0f07d10 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextImpl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java @@ -19,18 +19,18 @@ package net.emustudio.plugins.cpu.zilogZ80; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.zilogZ80.api.ContextZ80; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -public final class ContextImpl implements ExtendedContext { +public final class ContextZ80Impl implements ContextZ80 { private final static byte NO_DATA = (byte)0xFF; public final static int DEFAULT_FREQUENCY_KHZ = 20000; - private final static Logger LOGGER = LoggerFactory.getLogger(ContextImpl.class); + private final static Logger LOGGER = LoggerFactory.getLogger(ContextZ80Impl.class); private final ConcurrentMap> devices = new ConcurrentHashMap<>(); private volatile EmulatorEngine engine; @@ -92,11 +92,16 @@ public void setCPUFrequency(int frequency) { @Override public void signalInterrupt(DeviceContext device, byte[] data) { - engine.requestInterrupt(data); + engine.requestMaskableInterrupt(data); } @Override public int getCPUFrequency() { return clockFrequency; } + + @Override + public void signalNonMaskableInterrupt() { + engine.requestNonMaskableInterrupt(); + } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java index 31da3d054..aeaba08d3 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java @@ -27,7 +27,7 @@ import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.cpu.intel8080.api.FrequencyUpdater; import net.emustudio.plugins.cpu.zilogZ80.gui.StatusPanel; import org.slf4j.Logger; @@ -57,8 +57,8 @@ public class CpuImpl extends AbstractCPU { private final ScheduledExecutorService frequencyScheduler = Executors.newSingleThreadScheduledExecutor(); private final AtomicReference frequencyUpdaterFuture = new AtomicReference<>(); - private final ContextImpl context = new ContextImpl(); - private final InitializerForZ80 initializer; + private final ContextZ80Impl context = new ContextZ80Impl(); + private final InitializerZ80 initializer; private StatusPanel statusPanel; private Disassembler disassembler; @@ -67,7 +67,7 @@ public class CpuImpl extends AbstractCPU { public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); try { - applicationApi.getContextPool().register(pluginID, context, ExtendedContext.class); + applicationApi.getContextPool().register(pluginID, context, Context8080.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register Z80 CPU context", e); applicationApi.getDialogs().showError( @@ -75,7 +75,7 @@ public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings sett ); } - initializer = new InitializerForZ80( + initializer = new InitializerZ80( this, pluginID, applicationApi.getContextPool(), settings, context ); } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index f5d33c89d..3d8116dfe 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -36,6 +36,7 @@ import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicBoolean; import static net.emustudio.plugins.cpu.zilogZ80.DispatchTables.*; import static net.emustudio.plugins.cpu.zilogZ80.EmulatorTables.*; @@ -58,7 +59,7 @@ public class EmulatorEngine implements CpuEngine { 0, FLAG_Z, 0, FLAG_C, 0, FLAG_PV, 0, FLAG_S }; - private final ContextImpl context; + private final ContextZ80Impl context; private final MemoryContext memory; private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); @@ -74,15 +75,18 @@ public class EmulatorEngine implements CpuEngine { public int I = 0, R = 0; // interrupt r., refresh r. public final boolean[] IFF = new boolean[2]; // interrupt enable flip-flops - public byte interruptMode = 0; // interrupt mode (0,1,2) + public byte interruptMode = 0; - private final Queue pendingInterrupts = new ConcurrentLinkedQueue<>(); // must be thread-safe + private final Queue pendingInterrupts = new ConcurrentLinkedQueue<>(); // must be thread-safe; can cause stack overflow + + // non-maskable interrupts are always executed + private final AtomicBoolean pendingNonMaskableInterrupt = new AtomicBoolean(); private RunState currentRunState = RunState.STATE_STOPPED_NORMAL; private long executedCycles = 0; private volatile DispatchListener dispatchListener; - public EmulatorEngine(MemoryContext memory, ContextImpl context) { + public EmulatorEngine(MemoryContext memory, ContextZ80Impl context) { this.memory = Objects.requireNonNull(memory); this.context = Objects.requireNonNull(context); } @@ -114,13 +118,16 @@ public void fireFrequencyChanged(float newFrequency) { } } - public void requestInterrupt(byte[] data) { + public void requestMaskableInterrupt(byte[] data) { if (currentRunState == RunState.STATE_RUNNING) { - System.out.println("interrupt signalled!, " + Arrays.toString(data)); pendingInterrupts.add(data); } } + public void requestNonMaskableInterrupt() { + pendingNonMaskableInterrupt.set(true); + } + void reset(int startPos) { SP = IX = IY = 0; I = R = 0; @@ -128,8 +135,10 @@ void reset(int startPos) { Arrays.fill(regs2, 0); flags = 0; flags2 = 0; + interruptMode = 0; IFF[0] = false; IFF[1] = false; + pendingNonMaskableInterrupt.set(false); PC = startPos; pendingInterrupts.clear(); currentRunState = RunState.STATE_STOPPED_BREAK; @@ -137,8 +146,6 @@ void reset(int startPos) { CPU.RunState step() throws Exception { currentRunState = CPU.RunState.STATE_STOPPED_BREAK; - lastOpcode = readByte(PC); - PC = (PC + 1) & 0xFFFF; try { dispatch(); } catch (Throwable e) { @@ -161,8 +168,6 @@ public CPU.RunState run(CPU cpu) { cycles_executed = 0; while ((cycles_executed < cycles_to_execute) && !Thread.currentThread().isInterrupted() && (currentRunState == CPU.RunState.STATE_RUNNING)) { try { - lastOpcode = readByte(PC); - PC = (PC + 1) & 0xFFFF; cycles = dispatch(); cycles_executed += cycles; executedCycles += cycles; @@ -198,17 +203,16 @@ private int dispatch() throws Throwable { } try { + if (pendingNonMaskableInterrupt.getAndSet(false)) { + writeWord((SP - 2) & 0xFFFF, PC); + SP = (SP - 2) & 0xffff; + PC = 0x66; + return 12; + } if (IFF[0] && !pendingInterrupts.isEmpty()) { return doInterrupt(); } - incrementR(); - - /* Dispatch Instruction */ - MethodHandle instr = DISPATCH_TABLE[lastOpcode]; - if (instr != null) { - return (int) instr.invokeExact(this); - } - return 4; + return DISPATCH(DISPATCH_TABLE); } finally { if (tmpListener != null) { tmpListener.afterDispatch(); @@ -270,7 +274,6 @@ int SPECIAL_CB_DISPATCH(MethodHandle[] table) throws Throwable { private int doInterrupt() throws Throwable { byte[] dataBus = pendingInterrupts.poll(); int cycles = 0; - PC = (PC - 1) & 0xFFFF; // return back PC IFF[0] = IFF[1] = false; System.out.println("z80: interrupt! im=" + interruptMode + ", dataBus=" + Arrays.toString(dataBus)); @@ -1528,7 +1531,11 @@ int I_LD_R_R() { } int I_HALT() { - currentRunState = RunState.STATE_STOPPED_NORMAL; + if (IFF[0]) { + PC = (PC - 1) & 0xFFFF; // endless loop if interrupts are enabled + } else { + currentRunState = RunState.STATE_STOPPED_NORMAL; + } return 4; } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InitializerForZ80.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InitializerZ80.java similarity index 88% rename from plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InitializerForZ80.java rename to plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InitializerZ80.java index b2c4a87e5..0e431495b 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InitializerForZ80.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InitializerZ80.java @@ -32,11 +32,11 @@ import java.io.PrintStream; import java.util.Objects; -public class InitializerForZ80 extends DefaultInitializer { - private final ContextImpl context; +public class InitializerZ80 extends DefaultInitializer { + private final ContextZ80Impl context; - public InitializerForZ80(Plugin plugin, long pluginId, ContextPool contextPool, PluginSettings settings, - ContextImpl context) { + public InitializerZ80(Plugin plugin, long pluginId, ContextPool contextPool, PluginSettings settings, + ContextZ80Impl context) { super(plugin, pluginId, contextPool, settings); this.context = Objects.requireNonNull(context); } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/api/ContextZ80.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/api/ContextZ80.java new file mode 100644 index 000000000..4c6558b07 --- /dev/null +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/api/ContextZ80.java @@ -0,0 +1,15 @@ +package net.emustudio.plugins.cpu.zilogZ80.api; + +import net.emustudio.plugins.cpu.intel8080.api.Context8080; + +@SuppressWarnings("unused") +public interface ContextZ80 extends Context8080 { + + /** + * Signals a non-maskable interrupt. + * + * On the interrupt execution, CPU ignores the next instruction and instead performs a restart + * at address 0066h. Routines should exit with RETN instruction. + */ + void signalNonMaskableInterrupt(); +} diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java index 18c108a15..2a7a6c804 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java @@ -19,7 +19,7 @@ package net.emustudio.plugins.cpu.zilogZ80.gui; import net.emustudio.emulib.plugins.cpu.CPU; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.cpu.zilogZ80.CpuImpl; import net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine; import net.emustudio.plugins.cpu.zilogZ80.InstructionPrinter; @@ -33,13 +33,13 @@ public class StatusPanel extends JPanel { private final CpuImpl cpu; - private final ExtendedContext context; + private final Context8080 context; private final FlagsModel flagModel1; private final FlagsModel flagModel2; private volatile CPU.RunState runState = CPU.RunState.STATE_STOPPED_NORMAL; - public StatusPanel(CpuImpl cpu, ExtendedContext context, boolean dumpInstructions) { + public StatusPanel(CpuImpl cpu, Context8080 context, boolean dumpInstructions) { this.cpu = cpu; this.context = context; this.flagModel1 = new FlagsModel(0, cpu.getEngine()); diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java index 7055f31c0..a48390fc1 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java @@ -25,7 +25,7 @@ import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.cpu.zilogZ80.suite.CpuRunnerImpl; import net.emustudio.plugins.cpu.zilogZ80.suite.CpuVerifierImpl; import org.easymock.Capture; @@ -57,10 +57,10 @@ public class InstructionsTest { public void setUp() throws Exception { ByteMemoryStub memoryStub = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); - Capture cpuContext = Capture.newInstance(); + Capture cpuContext = Capture.newInstance(); ContextPool contextPool = EasyMock.createNiceMock(ContextPool.class); expect(contextPool.getMemoryContext(0, MemoryContext.class)).andReturn(memoryStub).anyTimes(); - contextPool.register(anyLong(), capture(cpuContext), same(ExtendedContext.class)); + contextPool.register(anyLong(), capture(cpuContext), same(Context8080.class)); expectLastCall().anyTimes(); replay(contextPool); diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java index baf4b3937..9b31806f3 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java @@ -27,7 +27,7 @@ import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.device.mits88dcdd.drive.Drive; import net.emustudio.plugins.device.mits88dcdd.drive.DriveCollection; import net.emustudio.plugins.device.mits88dcdd.gui.DiskGui; @@ -61,7 +61,7 @@ public class DeviceImpl extends AbstractDevice { private final DataPort dataPort; private final boolean guiNotSupported; - private ExtendedContext cpuContext; + private Context8080 cpuContext; private int port1CPU; private int port2CPU; @@ -89,7 +89,7 @@ public void initialize() throws PluginInitializationException { readSettings(); ContextPool contextPool = applicationApi.getContextPool(); if (contextPool != null) { - cpuContext = contextPool.getCPUContext(pluginID, ExtendedContext.class); + cpuContext = contextPool.getCPUContext(pluginID, Context8080.class); // attach device to CPU port1CPU = attachPort(1, statusPort, port1CPU); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java index 4191dd916..e919f4150 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java @@ -24,7 +24,7 @@ import net.emustudio.emulib.plugins.device.AbstractDevice; import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.emulib.runtime.*; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.device.mits88sio.ports.*; import net.emustudio.plugins.device.mits88sio.gui.SettingsDialog; import net.emustudio.plugins.device.mits88sio.gui.SioGui; @@ -91,7 +91,7 @@ public void reset() { @SuppressWarnings("unchecked") @Override public void initialize() throws PluginInitializationException { - ExtendedContext cpu = applicationApi.getContextPool().getCPUContext(pluginID, ExtendedContext.class); + Context8080 cpu = applicationApi.getContextPool().getCPUContext(pluginID, Context8080.class); cpuPorts = new CpuPorts(cpu); sioSettings.addChangedObserver(this); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuPorts.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuPorts.java index aada69473..9fffca19d 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuPorts.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuPorts.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.device.mits88sio.ports; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import java.util.ArrayList; import java.util.Collection; @@ -29,9 +29,9 @@ public class CpuPorts { private final List statusPorts = new ArrayList<>(); private final List dataPorts = new ArrayList<>(); - private final ExtendedContext cpu; + private final Context8080 cpu; - public CpuPorts(ExtendedContext cpu) { + public CpuPorts(Context8080 cpu) { this.cpu = Objects.requireNonNull(cpu); } diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java index e6ffb81e2..211d4126a 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java @@ -24,7 +24,7 @@ import net.emustudio.emulib.runtime.ContextNotFoundException; import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -40,8 +40,8 @@ public class DeviceImplTest { @Before public void setup() throws PluginInitializationException { ContextPool contextPool = createNiceMock(ContextPool.class); - expect(contextPool.getCPUContext(0, ExtendedContext.class)) - .andReturn(createNiceMock(ExtendedContext.class)).anyTimes(); + expect(contextPool.getCPUContext(0, Context8080.class)) + .andReturn(createNiceMock(Context8080.class)).anyTimes(); expect(contextPool.getDeviceContext(0, DeviceContext.class)) .andThrow(new ContextNotFoundException("")).anyTimes(); replay(contextPool); diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuPortsTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuPortsTest.java index 52fd06e51..0260be68f 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuPortsTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuPortsTest.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.device.mits88sio.ports; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import org.junit.Test; import java.util.Arrays; @@ -32,7 +32,7 @@ public class CpuPortsTest { @Test public void testStatusPortsAreCorrectAfterReattaching() throws Exception { CpuStatusPort cpuStatusPort = mock(CpuStatusPort.class); - ExtendedContext cpu = mock(ExtendedContext.class); + Context8080 cpu = mock(Context8080.class); expect(cpu.attachDevice(cpuStatusPort, 1)).andReturn(true); expect(cpu.attachDevice(cpuStatusPort, 2)).andReturn(true); @@ -58,7 +58,7 @@ public void testStatusPortsAreCorrectAfterReattaching() throws Exception { @Test public void testDataPortsAreCorrectAfterReattaching() throws CouldNotAttachException { CpuDataPort cpuDataPort = mock(CpuDataPort.class); - ExtendedContext cpu = mock(ExtendedContext.class); + Context8080 cpu = mock(Context8080.class); expect(cpu.attachDevice(cpuDataPort, 1)).andReturn(true); expect(cpu.attachDevice(cpuDataPort, 2)).andReturn(true); @@ -82,7 +82,7 @@ public void testDataPortsAreCorrectAfterReattaching() throws CouldNotAttachExcep @Test public void testDestroyDetachesAllPorts() throws Exception { - ExtendedContext cpu = mock(ExtendedContext.class); + Context8080 cpu = mock(Context8080.class); expect(cpu.attachDevice(anyObject(), anyInt())).andReturn(true).anyTimes(); cpu.detachDevice(1); diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java index 89bcdefe5..6f08afd2e 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java @@ -25,7 +25,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.PluginSettings; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import javax.swing.*; @@ -52,7 +52,7 @@ public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s public void initialize() throws PluginInitializationException { ContextPool contextPool = applicationApi.getContextPool(); - ExtendedContext cpu = contextPool.getCPUContext(pluginID, ExtendedContext.class); + Context8080 cpu = contextPool.getCPUContext(pluginID, Context8080.class); ByteMemoryContext mem = contextPool.getMemoryContext(pluginID, ByteMemoryContext.class); context.setMemory(mem); diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java index c0c4e21ea..c6c3f9bd4 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java @@ -19,7 +19,7 @@ package net.emustudio.plugins.device.simh; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.device.simh.commands.*; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; @@ -61,7 +61,7 @@ */ class PseudoContext implements DeviceContext, Command.Control { private ByteMemoryContext memory; - private ExtendedContext cpu; + private Context8080 cpu; private Commands lastReadCommand = unknownCmd; private Commands lastWriteCommand = unknownCmd; @@ -89,7 +89,7 @@ public ByteMemoryContext getMemory() { } @Override - public ExtendedContext getCpu() { + public Context8080 getCpu() { return cpu; } @@ -102,7 +102,7 @@ void setMemory(ByteMemoryContext mem) { this.memory = mem; } - void setCpu(ExtendedContext cpu) { + void setCpu(Context8080 cpu) { this.cpu = cpu; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java index 25ccda47b..31b05ae64 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java @@ -19,12 +19,9 @@ package net.emustudio.plugins.device.simh.commands; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.cpu.intel8080.api.ExtendedContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; -import java.util.HashMap; -import java.util.Map; - public interface Command { /** @@ -77,7 +74,7 @@ interface Control { ByteMemoryContext getMemory(); - ExtendedContext getCpu(); + Context8080 getCpu(); DeviceContext getDevice(); } From 576e477d4ee656a9ee934b6746eab58634ff59e4 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 28 Jul 2022 08:50:35 +0100 Subject: [PATCH 182/314] Z80: Fix relative jumps (jr, djnz) --- .../asZ80/visitors/GenerateCodeVisitor.java | 2 +- .../compiler/asZ80/e2e/InstrExprTest.java | 4 ++-- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 11 +++-------- .../plugins/cpu/zilogZ80/ControlTest.java | 16 ++++++++-------- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java index 82398536d..f72437858 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java @@ -133,7 +133,7 @@ public void visit(PseudoOrg node) { @Override public void visit(Evaluated node) { - final int value = (isRelative && node.isAddress) ? (node.value - currentAddress) : node.value; + final int value = (isRelative && node.isAddress) ? (node.value - currentAddress - 2) : node.value; if (expectedBytes == 1) { addByte(value); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java index a4e97f176..bee128431 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java @@ -29,14 +29,14 @@ public void testRelativeJumpLabel() { ); assertProgram( - 0x3E, 0x01, 0x28, 0x03, 0xC7, 0x76 + 0x3E, 0x01, 0x28, 0x01, 0xC7, 0x76 ); } @Test public void testRelativeJumpCurrentAddress() { compile("halt\njr $"); // infinite loop - assertProgram(0x76, 0x18, 0); + assertProgram(0x76, 0x18, (byte)-2); } @Test diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 3d8116dfe..87850a082 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -648,8 +648,7 @@ int I_DJNZ() { PC = (PC + 1) & 0xFFFF; regs[REG_B] = (regs[REG_B] - 1) & 0xFF; if (regs[REG_B] != 0) { - PC = (PC - 2) + tmp; - PC &= 0xFFFF; + PC = (PC + tmp) & 0xFFFF; return 13; } return 8; @@ -1326,8 +1325,7 @@ int I_JR_CC_N() { PC = (PC + 1) & 0xFFFF; if (getCC1((lastOpcode >>> 3) & 3)) { - PC = (PC - 2) + (byte) tmp; - PC &= 0xFFFF; + PC = (PC + (byte) tmp) & 0xFFFF; return 12; } return 7; @@ -1335,10 +1333,7 @@ int I_JR_CC_N() { int I_JR_N() { int tmp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - - PC = (PC - 2) + (byte) tmp; - PC &= 0xFFFF; + PC = (PC + 1 + (byte) tmp) & 0xFFFF; return 12; } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java index da3fb9789..aee0f52e6 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java @@ -277,16 +277,16 @@ public void testIM__2() { @Test public void testJR__e__AND__JR__cc() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .expandMemory(first -> cpuRunnerImpl.getPC() + first.intValue()) - .verifyPC(context -> (context.PC + context.first) & 0xFFFF) + .expandMemory(first -> cpuRunnerImpl.getPC() + first.intValue() & 0xFF) + .verifyPC(context -> (context.PC + context.first + 2) & 0xFFFF) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.runWithFirstOperand(0x18), - test.runWithFirstOperand(0x20), - test.setFlags(FLAG_Z).runWithFirstOperand(0x28), - test.runWithFirstOperand(0x30), - test.setFlags(FLAG_C).runWithFirstOperand(0x38) + test.runWithFirstOperand(0x18), // jr * + test.runWithFirstOperand(0x20), // jr nz, * + test.setFlags(FLAG_Z).runWithFirstOperand(0x28), // jr z, * + test.runWithFirstOperand(0x30), // jr nc, * + test.setFlags(FLAG_C).runWithFirstOperand(0x38) // jr c, * ); } @@ -336,7 +336,7 @@ public void testDJNZ__e() { if (((context.second - 1) & 0xFF) == 0) { return context.PC + 2; } - return (context.PC + context.first) & 0xFFFF; + return (context.PC + context.first + 2) & 0xFFFF; }) .verifyRegister(REG_B, context -> (context.second - 1) & 0xFF); From 35546af0eaf6da80708b0920b59f862dff67f80e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 28 Jul 2022 20:22:00 +0100 Subject: [PATCH 183/314] [#175] add 88-sio ports, z80: mnemo constants 'h' suffix --- .../src/main/files/config/MITSAltair8800.toml | 27 +- .../main/files/config/MITSAltair8800Z80.toml | 36 +- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 386 +++++++++--------- .../cpu/zilogZ80/DisassemblerTest.java | 300 +++++++------- 4 files changed, 379 insertions(+), 370 deletions(-) diff --git a/application/src/main/files/config/MITSAltair8800.toml b/application/src/main/files/config/MITSAltair8800.toml index 9d2b4b86e..7dbb7d87b 100644 --- a/application/src/main/files/config/MITSAltair8800.toml +++ b/application/src/main/files/config/MITSAltair8800.toml @@ -103,16 +103,20 @@ name = "MITS Altair8800" type = "DEVICE" [DEVICE.settings] - statusPortNumber1 = 16 - statusPortNumber0 = 3 - statusPortNumber3 = 22 - statusPortNumber2 = 20 - dataPortNumber2 = 21 - dataPortNumber3 = 23 + statusPortNumber0 = 0 + statusPortNumber1 = 1 + statusPortNumber2 = 3 + statusPortNumber3 = 5 + statusPortNumber4 = 16 + statusPortNumber5 = 20 + statusPortNumber6 = 22 + statusPortNumber7 = 24 dataPortNumber0 = 2 - dataPortNumber1 = 17 - dataPortNumber4 = 25 - statusPortNumber4 = 24 + dataPortNumber1 = 4 + dataPortNumber2 = 17 + dataPortNumber3 = 21 + dataPortNumber4 = 23 + dataPortNumber5 = 25 [[DEVICE]] schemaPoint = "340,60" @@ -129,11 +133,6 @@ name = "MITS Altair8800" inputReadDelay = 0 halfDuplex = false -# halfDuplex = false -# alwaysOnTop = false -# inputReadDelay = 0 -# antiAliasing = true - [[connections]] bidirectional = true from = "14a9121e-348e-48d9-90ae-05a61b6ed8a8" diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index 61d2a7121..8806015bd 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -40,10 +40,12 @@ name = "MITS Altair8800 (Z80)" id = "b86d4bc2-632c-46e3-bba1-c088c9177983" type = "CPU" -# halfDuplex = false -# alwaysOnTop = false -# inputReadDelay = 0 -# antiAliasing = true +# Uncomment the following for specific settings (and remove settings = {} above) +# [CPU.settings] +# printCode = true +# printCodeUseCache = true +# printCodeFileName = syserr # Or custom path to a file + [[DEVICE]] schemaPoint = "340,140" path = "88-dcdd.jar" @@ -97,16 +99,20 @@ name = "MITS Altair8800 (Z80)" type = "DEVICE" [DEVICE.settings] - statusPortNumber1 = 16 - statusPortNumber0 = 3 - statusPortNumber3 = 22 - statusPortNumber2 = 20 - dataPortNumber2 = 21 - dataPortNumber3 = 23 + statusPortNumber0 = 0 + statusPortNumber1 = 1 + statusPortNumber2 = 3 + statusPortNumber3 = 5 + statusPortNumber4 = 16 + statusPortNumber5 = 20 + statusPortNumber6 = 22 + statusPortNumber7 = 24 dataPortNumber0 = 2 - dataPortNumber1 = 17 - dataPortNumber4 = 25 - statusPortNumber4 = 24 + dataPortNumber1 = 4 + dataPortNumber2 = 17 + dataPortNumber3 = 21 + dataPortNumber4 = 23 + dataPortNumber5 = 25 [[DEVICE]] schemaPoint = "480,220" @@ -116,6 +122,10 @@ name = "MITS Altair8800 (Z80)" type = "DEVICE" [DEVICE.settings] + antiAliasing = true + alwaysOnTop = true + inputReadDelay = 0 + halfDuplex = false outputFileName = "adm3A-terminal.out" inputFileName = "adm3A-terminal.in" diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index 9f1c6bc7d..1197b7f65 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -20,150 +20,150 @@ root instruction; # http://www.z80.info/decoding.htm instruction = - "nop": 00 000 000 | # x=0, y=0, z=0 - "ex af, af'": 00 001 000 | # x=0, y=1, z=0 - "djnz %X": 00 010 000 imm8 | # x=0, y=2, z=0 - "jr %X": 00 011 000 imm8 | # x=0, y=3, z=0 - "jr %s, %X": 00 1 cc_jr(2) 000 imm8 | # x=0, y=4..7, z=0 - "ld %s, %X": 00 rp(2) 0 001 imm16 | # x=0, p=rp, q=0, z=1 - "add hl, %s": 00 rp(2) 1 001 | # x=0, p=rp, q=1, z=1 - "ld (bc), a": 00 000 010 | # x=0, p=0, q=0, z=2 - "ld (de), a": 00 010 010 | # x=0, p=1, q=0, z=2 - "ld (%X), hl": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 - "ld (%X), a": 00 110 010 ref16 | # x=0, p=3, q=0, z=2 - "ld a, (bc)": 00 001 010 | # x=0, p=0, q=1, z=2 - "ld a, (de)": 00 011 010 | # x=0, p=1, q=1, z=2 - "ld hl, (%X)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 - "ld a, (%X)": 00 111 010 ref16 | # x=0, p=3, q=1, z=2 - "inc %s": 00 rp(2) 0 011 | # x=0, p=rp, q=0, z=3 - "dec %s": 00 rp(2) 1 011 | # x=0, p=rp, q=1, z=3 - "inc %s": 00 r(3) 100 | # x=0, y=r, z=4 - "dec %s": 00 r(3) 101 | # x=0, y=r, z=5 - "ld %s, %X": 00 r(3) 110 imm8 | # x=0, y=r, z=6 - "rlca": 00 000 111 | # x=0, y=0, z=7 - "rrca": 00 001 111 | # x=0, y=1, z=7 - "rla": 00 010 111 | # x=0, y=2, z=7 - "rra": 00 011 111 | # x=0, y=3, z=7 - "daa": 00 100 111 | # x=0, y=4, z=7 - "cpl": 00 101 111 | # x=0, y=5, z=7 - "scf": 00 110 111 | # x=0, y=6, z=7 - "ccf": 00 111 111 | # x=0, y=7, z=7 - - "halt": 01 110 110 | # x=1, y=6, z=6 - "ld %s, %s": 01 0 r_bcde(2) r(3) | # x=1, y=0 r_bcde, z=r - "ld %s, %s": 01 10 r_h_l(1) r(3) | # x=1, y=10 r_h_l, z=r - "ld a, %s": 01 111 r(3) | # x=1, y=7, z=r - "ld (hl), %s": 01 110 0 r_bcde(2) | # x=1, y=6, z=0 r_bcde - "ld (hl), %s": 01 110 10 r_h_l(1) | # x=1, y=6, z=10 r_h_l - "ld (hl), a": 01 110 111 | # x=1, y=6, z=7 - - "%s %s": 10 alu(3) r(3) | # x=2, y=alu, z=r - - "ret %s": 11 cc(3) 000 | # x=3, y=cc, z=0 - "pop %s": 11 rp2(2) 0 001 | # x=3, p=rp2, q=0, z=1 - "ret": 11 001 001 | # x=3, p=0, q=1, z=1 - "exx": 11 011 001 | # x=3, p=1, q=1, z=1 - "jp (hl)": 11 101 001 | # x=3, p=2, q=1, z=1 - "ld sp, hl": 11 111 001 | # x=3, p=3, q=1, z=1 - "jp %s, %X": 11 cc(3) 010 imm16 | # x=3, y=cc, z=2 - "jp %X": 11 000 011 imm16 | # x=3, y=0, z=3 - - "%s %s": 0xCB 00 rot(3) r(3) | # x=0, y=rot, z=r - "bit %X, %s": 0xCB 01 bit(3) r(3) | # x=1, y=bit, z=r - "res %X, %s": 0xCB 10 bit(3) r(3) | # x=2, y=bit, z=r - "set %X, %s": 0xCB 11 bit(3) r(3) | # x=3, y=bit, z=r - - "out (%X), a": 11 010 011 ref8 | # x=3, y=2, z=3 - "in a, (%X)": 11 011 011 ref8 | # x=3, y=3, z=3 - "ex (sp), hl": 11 100 011 | # x=3, y=4, z=3 - "ex de, hl": 11 101 011 | # x=3, y=5, z=3 - "di": 11 110 011 | # x=3, y=6, z=3 - "ei": 11 111 011 | # x=3, y=7, z=3 - "call %s, %X": 11 cc(3) 100 imm16 | # x=3, y=cc, z=4 - "push %s": 11 rp2(2) 0 101 | # x=3, p=rp2, q=0, z=5 - "call %X": 11 001 101 imm16 | # x=3, p=0, q=1, z=5 - - 0xDD ddInstruction | - - "in %s, (c)": 0xED 01 0 r_bcde(2) 000 | # x=1, y=0 r_bcde, z=0 - "in %s, (c)": 0xED 01 10 r_h_l(1) 000 | # x=1, y=10 r_h_l, z=0 - "in a, (c)": 0xED 01 111 000 | # x=1, y=7, z=0 - "in (c)": 0xED 01 110 000 | # x=1, y=6, z=0 - "out (c), %s": 0xED 01 0 r_bcde(2) 001 | # x=1, y=0 r_bcde, z=1 - "out (c), %s": 0xED 01 10 r_h_l(1) 001 | # x=1, y=10 r_h_l, z=1 - "out (c), a": 0xED 01 111 001 | # x=1, y=7, z=1 - "out (c), 0": 0xED 01 110 001 | # x=1, y=6, z=1 - "sbc hl, %s": 0xED 01 rp(2) 0 010 | # x=1, p=rp, q=0, z=2 - "adc hl, %s": 0xED 01 rp(2) 1 010 | # x=1, p=rp, q=1, z=2 - "ld (%X), %s": 0xED 01 rp(2) 0 011 ref16_2 | # x=1, p=rp, q=0, z=3 - "ld %s, (%X)": 0xED 01 rp(2) 1 011 ref16 | # x=1, p=rp, q=1, z=3 - "neg": 0xED 01 any(3) 100 | # x=1, y=any, z=4 - "reti": 0xED 01 001 101 | # x=1, y=1, z=5 - "retn": 0xED 01 any2(2) 0 101 | # x=1, y!=1, z=5 - "retn": 0xED 01 10 1 101 | # x=1, y!=1, z=5 - "retn": 0xED 01 01 1 101 | # x=1, y!=1, z=5 - "retn": 0xED 01 11 1 101 | # x=1, y!=1, z=5 - "im %s": 0xED 01 im(3) 110 | # x=1, y=im, z=6 - "ld i, a": 0xED 01 000 111 | # x=1, y=0, z=7 - "ld r, a": 0xED 01 001 111 | # x=1, y=1, z=7 - "ld a, i": 0xED 01 010 111 | # x=1, y=2, z=7 - "ld a, r": 0xED 01 011 111 | # x=1, y=3, z=7 - "rrd": 0xED 01 100 111 | # x=1, y=4, z=7 - "rld": 0xED 01 101 111 | # x=1, y=5, z=7 - "nop": 0xED 01 110 111 | # x=1, y=6, z=7 - "nop": 0xED 01 111 111 | # x=1, y=7, z=7 - - "ldi": 0xED 10 100 000 | # x=2, y=4, z=0 - "ldd": 0xED 10 101 000 | # x=2, y=5, z=0 - "ldir": 0xED 10 110 000 | # x=2, y=6, z=0 - "lddr": 0xED 10 111 000 | # x=2, y=7, z=0 - - "cpi": 0xED 10 100 001 | # x=2, y=4, z=1 - "cpd": 0xED 10 101 001 | # x=2, y=5, z=1 - "cpir": 0xED 10 110 001 | # x=2, y=6, z=1 - "cpdr": 0xED 10 111 001 | # x=2, y=7, z=1 - - "ini": 0xED 10 100 010 | # x=2, y=4, z=2 - "ind": 0xED 10 101 010 | # x=2, y=5, z=2 - "inir": 0xED 10 110 010 | # x=2, y=6, z=2 - "indr": 0xED 10 111 010 | # x=2, y=7, z=2 - - "outi": 0xED 10 100 011 | # x=2, y=4, z=3 - "outd": 0xED 10 101 011 | # x=2, y=5, z=3 - "otir": 0xED 10 110 011 | # x=2, y=6, z=3 - "otdr": 0xED 10 111 011 | # x=2, y=7, z=3 - - 0xFD fdInstruction | - - "%s %X": 11 alu(3) 110 imm8 | # x=3, y=alu, z=6 - "rst %s": 11 rst(3) 111 ; # x=3, y=rst, z=7 + "nop": 00 000 000 | # x=0, y=0, z=0 + "ex af, af'": 00 001 000 | # x=0, y=1, z=0 + "djnz %Xh": 00 010 000 imm8 | # x=0, y=2, z=0 + "jr %Xh": 00 011 000 imm8 | # x=0, y=3, z=0 + "jr %s, %Xh": 00 1 cc_jr(2) 000 imm8 | # x=0, y=4..7, z=0 + "ld %s, %Xh": 00 rp(2) 0 001 imm16 | # x=0, p=rp, q=0, z=1 + "add hl, %s": 00 rp(2) 1 001 | # x=0, p=rp, q=1, z=1 + "ld (bc), a": 00 000 010 | # x=0, p=0, q=0, z=2 + "ld (de), a": 00 010 010 | # x=0, p=1, q=0, z=2 + "ld (%Xh), hl": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 + "ld (%Xh), a": 00 110 010 ref16 | # x=0, p=3, q=0, z=2 + "ld a, (bc)": 00 001 010 | # x=0, p=0, q=1, z=2 + "ld a, (de)": 00 011 010 | # x=0, p=1, q=1, z=2 + "ld hl, (%Xh)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 + "ld a, (%Xh)": 00 111 010 ref16 | # x=0, p=3, q=1, z=2 + "inc %s": 00 rp(2) 0 011 | # x=0, p=rp, q=0, z=3 + "dec %s": 00 rp(2) 1 011 | # x=0, p=rp, q=1, z=3 + "inc %s": 00 r(3) 100 | # x=0, y=r, z=4 + "dec %s": 00 r(3) 101 | # x=0, y=r, z=5 + "ld %s, %Xh": 00 r(3) 110 imm8 | # x=0, y=r, z=6 + "rlca": 00 000 111 | # x=0, y=0, z=7 + "rrca": 00 001 111 | # x=0, y=1, z=7 + "rla": 00 010 111 | # x=0, y=2, z=7 + "rra": 00 011 111 | # x=0, y=3, z=7 + "daa": 00 100 111 | # x=0, y=4, z=7 + "cpl": 00 101 111 | # x=0, y=5, z=7 + "scf": 00 110 111 | # x=0, y=6, z=7 + "ccf": 00 111 111 | # x=0, y=7, z=7 + + "halt": 01 110 110 | # x=1, y=6, z=6 + "ld %s, %s": 01 0 r_bcde(2) r(3) | # x=1, y=0 r_bcde, z=r + "ld %s, %s": 01 10 r_h_l(1) r(3) | # x=1, y=10 r_h_l, z=r + "ld a, %s": 01 111 r(3) | # x=1, y=7, z=r + "ld (hl), %s": 01 110 0 r_bcde(2) | # x=1, y=6, z=0 r_bcde + "ld (hl), %s": 01 110 10 r_h_l(1) | # x=1, y=6, z=10 r_h_l + "ld (hl), a": 01 110 111 | # x=1, y=6, z=7 + + "%s %s": 10 alu(3) r(3) | # x=2, y=alu, z=r + + "ret %s": 11 cc(3) 000 | # x=3, y=cc, z=0 + "pop %s": 11 rp2(2) 0 001 | # x=3, p=rp2, q=0, z=1 + "ret": 11 001 001 | # x=3, p=0, q=1, z=1 + "exx": 11 011 001 | # x=3, p=1, q=1, z=1 + "jp (hl)": 11 101 001 | # x=3, p=2, q=1, z=1 + "ld sp, hl": 11 111 001 | # x=3, p=3, q=1, z=1 + "jp %s, %Xh": 11 cc(3) 010 imm16 | # x=3, y=cc, z=2 + "jp %Xh": 11 000 011 imm16 | # x=3, y=0, z=3 + + "%s %s": 0xCB 00 rot(3) r(3) | # x=0, y=rot, z=r + "bit %d, %s": 0xCB 01 bit(3) r(3) | # x=1, y=bit, z=r + "res %d, %s": 0xCB 10 bit(3) r(3) | # x=2, y=bit, z=r + "set %d, %s": 0xCB 11 bit(3) r(3) | # x=3, y=bit, z=r + + "out (%Xh), a": 11 010 011 ref8 | # x=3, y=2, z=3 + "in a, (%Xh)": 11 011 011 ref8 | # x=3, y=3, z=3 + "ex (sp), hl": 11 100 011 | # x=3, y=4, z=3 + "ex de, hl": 11 101 011 | # x=3, y=5, z=3 + "di": 11 110 011 | # x=3, y=6, z=3 + "ei": 11 111 011 | # x=3, y=7, z=3 + "call %s, %Xh": 11 cc(3) 100 imm16 | # x=3, y=cc, z=4 + "push %s": 11 rp2(2) 0 101 | # x=3, p=rp2, q=0, z=5 + "call %Xh": 11 001 101 imm16 | # x=3, p=0, q=1, z=5 + + 0xDD ddInstruction | + + "in %s, (c)": 0xED 01 0 r_bcde(2) 000 | # x=1, y=0 r_bcde, z=0 + "in %s, (c)": 0xED 01 10 r_h_l(1) 000 | # x=1, y=10 r_h_l, z=0 + "in a, (c)": 0xED 01 111 000 | # x=1, y=7, z=0 + "in (c)": 0xED 01 110 000 | # x=1, y=6, z=0 + "out (c), %s": 0xED 01 0 r_bcde(2) 001 | # x=1, y=0 r_bcde, z=1 + "out (c), %s": 0xED 01 10 r_h_l(1) 001 | # x=1, y=10 r_h_l, z=1 + "out (c), a": 0xED 01 111 001 | # x=1, y=7, z=1 + "out (c), 0": 0xED 01 110 001 | # x=1, y=6, z=1 + "sbc hl, %s": 0xED 01 rp(2) 0 010 | # x=1, p=rp, q=0, z=2 + "adc hl, %s": 0xED 01 rp(2) 1 010 | # x=1, p=rp, q=1, z=2 + "ld (%Xh), %s": 0xED 01 rp(2) 0 011 ref16_2 | # x=1, p=rp, q=0, z=3 + "ld %s, (%Xh)": 0xED 01 rp(2) 1 011 ref16 | # x=1, p=rp, q=1, z=3 + "neg": 0xED 01 any(3) 100 | # x=1, y=any, z=4 + "reti": 0xED 01 001 101 | # x=1, y=1, z=5 + "retn": 0xED 01 any2(2) 0 101 | # x=1, y!=1, z=5 + "retn": 0xED 01 10 1 101 | # x=1, y!=1, z=5 + "retn": 0xED 01 01 1 101 | # x=1, y!=1, z=5 + "retn": 0xED 01 11 1 101 | # x=1, y!=1, z=5 + "im %s": 0xED 01 im(3) 110 | # x=1, y=im, z=6 + "ld i, a": 0xED 01 000 111 | # x=1, y=0, z=7 + "ld r, a": 0xED 01 001 111 | # x=1, y=1, z=7 + "ld a, i": 0xED 01 010 111 | # x=1, y=2, z=7 + "ld a, r": 0xED 01 011 111 | # x=1, y=3, z=7 + "rrd": 0xED 01 100 111 | # x=1, y=4, z=7 + "rld": 0xED 01 101 111 | # x=1, y=5, z=7 + "nop": 0xED 01 110 111 | # x=1, y=6, z=7 + "nop": 0xED 01 111 111 | # x=1, y=7, z=7 + + "ldi": 0xED 10 100 000 | # x=2, y=4, z=0 + "ldd": 0xED 10 101 000 | # x=2, y=5, z=0 + "ldir": 0xED 10 110 000 | # x=2, y=6, z=0 + "lddr": 0xED 10 111 000 | # x=2, y=7, z=0 + + "cpi": 0xED 10 100 001 | # x=2, y=4, z=1 + "cpd": 0xED 10 101 001 | # x=2, y=5, z=1 + "cpir": 0xED 10 110 001 | # x=2, y=6, z=1 + "cpdr": 0xED 10 111 001 | # x=2, y=7, z=1 + + "ini": 0xED 10 100 010 | # x=2, y=4, z=2 + "ind": 0xED 10 101 010 | # x=2, y=5, z=2 + "inir": 0xED 10 110 010 | # x=2, y=6, z=2 + "indr": 0xED 10 111 010 | # x=2, y=7, z=2 + + "outi": 0xED 10 100 011 | # x=2, y=4, z=3 + "outd": 0xED 10 101 011 | # x=2, y=5, z=3 + "otir": 0xED 10 110 011 | # x=2, y=6, z=3 + "otdr": 0xED 10 111 011 | # x=2, y=7, z=3 + + 0xFD fdInstruction | + + "%s %Xh": 11 alu(3) 110 imm8 | # x=3, y=alu, z=6 + "rst %sh": 11 rst(3) 111 ; # x=3, y=rst, z=7 ddInstruction = - "ld ix, %X": 00 100 001 imm16 | # x=0, p=2, q=0, z=1 - "add ix, %s": 00 rp_ix(2) 1 001 | # x=0, p=rp_ix, q=1, z=1 - "ld (%X), ix": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 - "ld ix, (%X)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 - "inc ix": 00 100 011 | # x=0, p=2, q=0, z=3 - "dec ix": 00 101 011 | # x=0, p=2, q=1, z=3 - "inc %s": 00 10 r_ixhl(1) 100 | # x=0, y=r_ixhl, z=4 - "inc (ix+%X)": 00 110 100 disp | # x=0, y=6, z=4 - "dec %s": 00 10 r_ixhl(1) 101 | # x=0, y=r_ixhl, z=5 - "dec (ix+%X)": 00 110 101 disp | # x=0, y=6, z=5 - "ld %s, %X": 00 10 r_ixhl(1) 110 imm8 | # x=0, y=r_ixhl, z=6 - "ld (ix+%X), %X": 00 110 110 disp(8) imm8 | # x=0, y=6, z=6 - "ld %s, %s": 01 10 r_ixhl(1) 0 r_bcde(2) | # x=1, y=r_ixhl, z=r_bcde - "ld %s, %s": 01 10 r_ixhl(1) 10 r_ixhl2(1) | # x=1, y=r_ixhl, z=r_ixhl2 - "ld %s, a": 01 10 r_ixhl(1) 111 | # x=1, y=r_ixhl, z=a - "ld a, %s": 01 111 10 r_ixhl(1) | # x=1, y=7, z=r_ixhl - "ld (ix+%X), %s": 01 110 r_no_hl(3) disp | # x=1, y=6, z=r_no_hl - "ld %s, (ix+%X)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 - "ld %s, (ix+%X)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l, z=6 - "ld a, (ix+%X)": 01 111 110 disp | # x=1, y=7, z=6 - "%s %s": 10 alu(3) 10 r_ixhl(1) | # x=2, y=alu, z=r_ixhl - "%s (ix+%X)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 - "pop ix": 11 100 001 | # x=3, p=2, q=0, z=1 - "jp (ix)": 11 101 001 | # x=3, p=2, q=1, z=1 - "ld sp, ix": 11 111 001 | # x=3, p=3, q=1, z=1 + "ld ix, %Xh": 00 100 001 imm16 | # x=0, p=2, q=0, z=1 + "add ix, %s": 00 rp_ix(2) 1 001 | # x=0, p=rp_ix, q=1, z=1 + "ld (%Xh), ix": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 + "ld ix, (%Xh)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 + "inc ix": 00 100 011 | # x=0, p=2, q=0, z=3 + "dec ix": 00 101 011 | # x=0, p=2, q=1, z=3 + "inc %s": 00 10 r_ixhl(1) 100 | # x=0, y=r_ixhl, z=4 + "inc (ix+%Xh)": 00 110 100 disp | # x=0, y=6, z=4 + "dec %s": 00 10 r_ixhl(1) 101 | # x=0, y=r_ixhl, z=5 + "dec (ix+%Xh)": 00 110 101 disp | # x=0, y=6, z=5 + "ld %s, %Xh": 00 10 r_ixhl(1) 110 imm8 | # x=0, y=r_ixhl, z=6 + "ld (ix+%Xh), %Xh": 00 110 110 disp(8) imm8 | # x=0, y=6, z=6 + "ld %s, %s": 01 10 r_ixhl(1) 0 r_bcde(2) | # x=1, y=r_ixhl, z=r_bcde + "ld %s, %s": 01 10 r_ixhl(1) 10 r_ixhl2(1) | # x=1, y=r_ixhl, z=r_ixhl2 + "ld %s, a": 01 10 r_ixhl(1) 111 | # x=1, y=r_ixhl, z=a + "ld a, %s": 01 111 10 r_ixhl(1) | # x=1, y=7, z=r_ixhl + "ld (ix+%Xh), %s": 01 110 r_no_hl(3) disp | # x=1, y=6, z=r_no_hl + "ld %s, (ix+%Xh)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 + "ld %s, (ix+%Xh)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l, z=6 + "ld a, (ix+%Xh)": 01 111 110 disp | # x=1, y=7, z=6 + "%s %s": 10 alu(3) 10 r_ixhl(1) | # x=2, y=alu, z=r_ixhl + "%s (ix+%Xh)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 + "pop ix": 11 100 001 | # x=3, p=2, q=0, z=1 + "jp (ix)": 11 101 001 | # x=3, p=2, q=1, z=1 + "ld sp, ix": 11 111 001 | # x=3, p=3, q=1, z=1 0xCB disp(8) ddcbInstruction | @@ -171,31 +171,31 @@ ddInstruction = "push ix": 11 100 101 ; # x=3, p=2, q=0, z=5 fdInstruction = - "ld iy, %X": 00 100 001 imm16 | # x=0, p=2, q=0, z=1 - "add iy, %s": 00 rp_iy(2) 1 001 | # x=0, p=rp_iy, q=1, z=1 - "ld (%X), iy": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 - "ld iy, (%X)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 - "inc iy": 00 100 011 | # x=0, p=2, q=0, z=3 - "dec iy": 00 101 011 | # x=0, p=2, q=1, z=3 - "inc %s": 00 10 r_iyhl(1) 100 | # x=0, y=r_iyhl, z=4 - "inc (iy+%X)": 00 110 100 disp | # x=0, y=6, z=4 - "dec %s": 00 10 r_iyhl(1) 101 | # x=0, y=r_iyhl, z=5 - "dec (iy+%X)": 00 110 101 disp | # x=0, y=6, z=5 - "ld %s, %X": 00 10 r_iyhl(1) 110 imm8 | # x=0, y=r_iyhl, z=6 - "ld (iy+%X), %X": 00 110 110 disp(8) imm8 | # x=0, y=6, z=6 - "ld %s, %s": 01 10 r_iyhl(1) 0 r_bcde(2) | # x=1, y=r_iyhl, z=r_bcde - "ld %s, %s": 01 10 r_iyhl(1) 10 r_iyhl2(1) | # x=1, y=r_iyhl, z=r_iyhl2 - "ld %s, a": 01 10 r_iyhl(1) 111 | # x=1, y=r_iyhl, z=7 - "ld a, %s": 01 111 10 r_iyhl(1) | # x=1, y=7, z=r_iyhl - "ld (iy+%X), %s": 01 110 r_no_hl(3) disp | # x=1, y=6, z=r_no_hl - "ld %s, (iy+%X)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 - "ld %s, (iy+%X)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l, z=6 - "ld a, (iy+%X)": 01 111 110 disp | # x=1, y=7, z=6 - "%s %s": 10 alu(3) 10 r_iyhl(1) | # x=2, y=alu, z=r_iyhl - "%s (iy+%X)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 - "pop iy": 11 100 001 | # x=3, p=2, q=0, z=1 - "jp (iy)": 11 101 001 | # x=3, p=2, q=1, z=1 - "ld sp, iy": 11 111 001 | # x=3, p=3, q=1, z=1 + "ld iy, %Xh": 00 100 001 imm16 | # x=0, p=2, q=0, z=1 + "add iy, %s": 00 rp_iy(2) 1 001 | # x=0, p=rp_iy, q=1, z=1 + "ld (%Xh), iy": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 + "ld iy, (%Xh)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 + "inc iy": 00 100 011 | # x=0, p=2, q=0, z=3 + "dec iy": 00 101 011 | # x=0, p=2, q=1, z=3 + "inc %s": 00 10 r_iyhl(1) 100 | # x=0, y=r_iyhl, z=4 + "inc (iy+%Xh)": 00 110 100 disp | # x=0, y=6, z=4 + "dec %s": 00 10 r_iyhl(1) 101 | # x=0, y=r_iyhl, z=5 + "dec (iy+%Xh)": 00 110 101 disp | # x=0, y=6, z=5 + "ld %s, %Xh": 00 10 r_iyhl(1) 110 imm8 | # x=0, y=r_iyhl, z=6 + "ld (iy+%Xh), %Xh": 00 110 110 disp(8) imm8 | # x=0, y=6, z=6 + "ld %s, %s": 01 10 r_iyhl(1) 0 r_bcde(2) | # x=1, y=r_iyhl, z=r_bcde + "ld %s, %s": 01 10 r_iyhl(1) 10 r_iyhl2(1) | # x=1, y=r_iyhl, z=r_iyhl2 + "ld %s, a": 01 10 r_iyhl(1) 111 | # x=1, y=r_iyhl, z=7 + "ld a, %s": 01 111 10 r_iyhl(1) | # x=1, y=7, z=r_iyhl + "ld (iy+%Xh), %s": 01 110 r_no_hl(3) disp | # x=1, y=6, z=r_no_hl + "ld %s, (iy+%Xh)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 + "ld %s, (iy+%Xh)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l, z=6 + "ld a, (iy+%Xh)": 01 111 110 disp | # x=1, y=7, z=6 + "%s %s": 10 alu(3) 10 r_iyhl(1) | # x=2, y=alu, z=r_iyhl + "%s (iy+%Xh)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 + "pop iy": 11 100 001 | # x=3, p=2, q=0, z=1 + "jp (iy)": 11 101 001 | # x=3, p=2, q=1, z=1 + "ld sp, iy": 11 111 001 | # x=3, p=3, q=1, z=1 0xCB disp(8) fdcbInstruction | @@ -203,34 +203,34 @@ fdInstruction = "push iy": 11 100 101 ; # x=3, p=2, q=0, z=5 ddcbInstruction = - "%s (ix+%X), %s": 00 rot(3) 0 r_bcde(2) | # x=0, y=rot, z=0 r_bcde - "%s (ix+%X), %s": 00 rot(3) 10 r_h_l(1) | # x=0, y=rot, z=10 r_h_l - "%s (ix+%X), a": 00 rot(3) 111 | # x=0, y=rot, z=7 - "%s (ix+%X)": 00 rot(3) 110 | # x=0, y=rot, z=6 - "bit %X, (ix+%X)": 01 bit(3) any(3) | # x=1, y=bit, z=any - "res %X, (ix+%X), %s": 10 bit(3) 0 r_bcde(2) | # x=2, y=bit, z=0 r_bcde - "res %X, (ix+%X), %s": 10 bit(3) 10 r_h_l(1) | # x=2, y=bit, z=10 r_h_l - "res %X, (ix+%X), a": 10 bit(3) 111 | # x=2, y=bit, z=7 - "res %X, (ix+%X)": 10 bit(3) 110 | # x=2, y=bit, z=6 - "set %X, (ix+%X), %s": 11 bit(3) 0 r_bcde(2) | # x=3, y=bit, z=0 r_bcde - "set %X, (ix+%X), %s": 11 bit(3) 10 r_h_l(1) | # x=3, y=bit, z=10 r_h_l - "set %X, (ix+%X), a": 11 bit(3) 111 | # x=3, y=bit, z=7 - "set %X, (ix+%X)": 11 bit(3) 110 ; # x=3, y=bit, z=6 + "%s (ix+%Xh), %s": 00 rot(3) 0 r_bcde(2) | # x=0, y=rot, z=0 r_bcde + "%s (ix+%Xh), %s": 00 rot(3) 10 r_h_l(1) | # x=0, y=rot, z=10 r_h_l + "%s (ix+%Xh), a": 00 rot(3) 111 | # x=0, y=rot, z=7 + "%s (ix+%Xh)": 00 rot(3) 110 | # x=0, y=rot, z=6 + "bit %d, (ix+%Xh)": 01 bit(3) any(3) | # x=1, y=bit, z=any + "res %d, (ix+%Xh), %s": 10 bit(3) 0 r_bcde(2) | # x=2, y=bit, z=0 r_bcde + "res %d, (ix+%Xh), %s": 10 bit(3) 10 r_h_l(1) | # x=2, y=bit, z=10 r_h_l + "res %d, (ix+%Xh), a": 10 bit(3) 111 | # x=2, y=bit, z=7 + "res %d, (ix+%Xh)": 10 bit(3) 110 | # x=2, y=bit, z=6 + "set %d, (ix+%Xh), %s": 11 bit(3) 0 r_bcde(2) | # x=3, y=bit, z=0 r_bcde + "set %d, (ix+%Xh), %s": 11 bit(3) 10 r_h_l(1) | # x=3, y=bit, z=10 r_h_l + "set %d, (ix+%Xh), a": 11 bit(3) 111 | # x=3, y=bit, z=7 + "set %d, (ix+%Xh)": 11 bit(3) 110 ; # x=3, y=bit, z=6 fdcbInstruction = - "%s (iy+%X), %s": 00 rot(3) 0 r_bcde(2) | # x=0, y=rot, z=0 r_bcde - "%s (iy+%X), %s": 00 rot(3) 10 r_h_l(1) | # x=0, y=rot, z=10 r_h_l - "%s (iy+%X), a": 00 rot(3) 111 | # x=0, y=rot, z=7 - "%s (iy+%X)": 00 rot(3) 110 | # x=0, y=rot, z=6 - "bit %X, (iy+%X)": 01 bit(3) any(3) | # x=1, y=bit, z=any - "res %X, (iy+%X), %s": 10 bit(3) 0 r_bcde(2) | # x=2, y=bit, z=0 r_bcde - "res %X, (iy+%X), %s": 10 bit(3) 10 r_h_l(1) | # x=2, y=bit, z=10 r_h_l - "res %X, (iy+%X), a": 10 bit(3) 111 | # x=2, y=bit, z=7 - "res %X, (iy+%X)": 10 bit(3) 110 | # x=2, y=bit, z=6 - "set %X, (iy+%X), %s": 11 bit(3) 0 r_bcde(2) | # x=3, y=bit, z=0 r_bcde - "set %X, (iy+%X), %s": 11 bit(3) 10 r_h_l(1) | # x=3, y=bit, z=10 r_h_l - "set %X, (iy+%X), a": 11 bit(3) 111 | # x=3, y=bit, z=7 - "set %X, (iy+%X)": 11 bit(3) 110 ; # x=3, y=bit, z=6 + "%s (iy+%Xh), %s": 00 rot(3) 0 r_bcde(2) | # x=0, y=rot, z=0 r_bcde + "%s (iy+%Xh), %s": 00 rot(3) 10 r_h_l(1) | # x=0, y=rot, z=10 r_h_l + "%s (iy+%Xh), a": 00 rot(3) 111 | # x=0, y=rot, z=7 + "%s (iy+%Xh)": 00 rot(3) 110 | # x=0, y=rot, z=6 + "bit %d, (iy+%Xh)": 01 bit(3) any(3) | # x=1, y=bit, z=any + "res %d, (iy+%Xh), %s": 10 bit(3) 0 r_bcde(2) | # x=2, y=bit, z=0 r_bcde + "res %d, (iy+%Xh), %s": 10 bit(3) 10 r_h_l(1) | # x=2, y=bit, z=10 r_h_l + "res %d, (iy+%Xh), a": 10 bit(3) 111 | # x=2, y=bit, z=7 + "res %d, (iy+%Xh)": 10 bit(3) 110 | # x=2, y=bit, z=6 + "set %d, (iy+%Xh), %s": 11 bit(3) 0 r_bcde(2) | # x=3, y=bit, z=0 r_bcde + "set %d, (iy+%Xh), %s": 11 bit(3) 10 r_h_l(1) | # x=3, y=bit, z=10 r_h_l + "set %d, (iy+%Xh), a": 11 bit(3) 111 | # x=3, y=bit, z=7 + "set %d, (iy+%Xh)": 11 bit(3) 110 ; # x=3, y=bit, z=6 cc_jr = diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java index faf3128df..c2ee2ea36 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java @@ -444,16 +444,16 @@ public void testDisassemble() throws InvalidInstructionException { assertEquals( "nop" + "ex af, af'" + - "djnz 20" + - "jr 20" + - "jr nz, 20" + - "jr z, 20" + - "jr nc, 20" + - "jr c, 20" + - "ld bc, 1234" + - "ld de, 1234" + - "ld hl, 1234" + - "ld sp, 1234" + + "djnz 20h" + + "jr 20h" + + "jr nz, 20h" + + "jr z, 20h" + + "jr nc, 20h" + + "jr c, 20h" + + "ld bc, 1234h" + + "ld de, 1234h" + + "ld hl, 1234h" + + "ld sp, 1234h" + "add hl, bc" + "add hl, de" + "add hl, hl" + @@ -462,10 +462,10 @@ public void testDisassemble() throws InvalidInstructionException { "ld (de), a" + "ld a, (bc)" + "ld a, (de)" + - "ld (1234), hl" + - "ld (1234), a" + - "ld hl, (1234)" + - "ld a, (1234)" + + "ld (1234h), hl" + + "ld (1234h), a" + + "ld hl, (1234h)" + + "ld a, (1234h)" + "inc bc" + "inc de" + "inc hl" + @@ -488,12 +488,12 @@ public void testDisassemble() throws InvalidInstructionException { "dec h" + "dec l" + "dec a" + - "ld b, 20" + - "ld c, 20" + - "ld d, 20" + - "ld e, 20" + - "ld h, 20" + - "ld l, 20" + + "ld b, 20h" + + "ld c, 20h" + + "ld d, 20h" + + "ld e, 20h" + + "ld h, 20h" + + "ld l, 20h" + "rlca" + "rrca" + "rla" + @@ -550,50 +550,50 @@ public void testDisassemble() throws InvalidInstructionException { "jp (hl)" + "jp (hl)" + "ld sp, hl" + - "jp nz, 1234" + - "jp z, 1234" + - "jp nc, 1234" + - "jp c, 1234" + - "jp po, 1234" + - "jp pe, 1234" + - "jp p, 1234" + - "jp m, 1234" + - "jp 1234" + - "out (20), a" + - "in a, (20)" + + "jp nz, 1234h" + + "jp z, 1234h" + + "jp nc, 1234h" + + "jp c, 1234h" + + "jp po, 1234h" + + "jp pe, 1234h" + + "jp p, 1234h" + + "jp m, 1234h" + + "jp 1234h" + + "out (20h), a" + + "in a, (20h)" + "ex (sp), hl" + "ex de, hl" + "di" + "ei" + - "call nz, 1234" + - "call z, 1234" + - "call nc, 1234" + - "call c, 1234" + - "call po, 1234" + - "call pe, 1234" + - "call p, 1234" + - "call m, 1234" + + "call nz, 1234h" + + "call z, 1234h" + + "call nc, 1234h" + + "call c, 1234h" + + "call po, 1234h" + + "call pe, 1234h" + + "call p, 1234h" + + "call m, 1234h" + "push bc" + "push de" + "push hl" + "push af" + - "call 1234" + - "add a, 20" + - "adc a, 20" + - "sub 20" + - "sbc a, 20" + - "and 20" + - "xor 20" + - "or 20" + - "cp 20" + - "rst 00" + - "rst 08" + - "rst 10" + - "rst 18" + - "rst 20" + - "rst 28" + - "rst 30" + - "rst 38" + + "call 1234h" + + "add a, 20h" + + "adc a, 20h" + + "sub 20h" + + "sbc a, 20h" + + "and 20h" + + "xor 20h" + + "or 20h" + + "cp 20h" + + "rst 00h" + + "rst 08h" + + "rst 10h" + + "rst 18h" + + "rst 20h" + + "rst 28h" + + "rst 30h" + + "rst 38h" + "rlc b" + "rlc (hl)" + "rrc c" + @@ -628,14 +628,14 @@ public void testDisassemble() throws InvalidInstructionException { "adc hl, de" + "adc hl, hl" + "adc hl, sp" + - "ld (1234), bc" + - "ld (1234), de" + - "ld (1234), hl" + - "ld (1234), sp" + - "ld bc, (1234)" + - "ld de, (1234)" + - "ld hl, (1234)" + - "ld sp, (1234)" + + "ld (1234h), bc" + + "ld (1234h), de" + + "ld (1234h), hl" + + "ld (1234h), sp" + + "ld bc, (1234h)" + + "ld de, (1234h)" + + "ld hl, (1234h)" + + "ld sp, (1234h)" + "neg" + "retn" + "reti" + @@ -665,50 +665,50 @@ public void testDisassemble() throws InvalidInstructionException { "outd" + "otir" + "otdr" + - "rlc (ix+20), b" + - "rlc (iy+20), b" + - "rlc (ix+20)" + - "rlc (iy+20)" + - "rrc (ix+20), c" + - "rrc (iy+20), c" + - "rrc (ix+20)" + - "rrc (iy+20)" + - "rl (ix+20), d" + - "rl (iy+20), d" + - "rl (ix+20)" + - "rl (iy+20)" + - "rr (ix+20), e" + - "rr (iy+20), e" + - "rr (ix+20)" + - "rr (iy+20)" + - "sla (ix+20), h" + - "sla (iy+20), h" + - "sla (ix+20)" + - "sla (iy+20)" + - "sra (ix+20), l" + - "sra (iy+20), l" + - "sra (ix+20)" + - "sra (iy+20)" + - "sll (ix+20), b" + - "sll (iy+20), b" + - "sll (ix+20)" + - "sll (iy+20)" + - "srl (ix+20), c" + - "srl (iy+20), c" + - "srl (ix+20)" + - "srl (iy+20)" + - "bit 3, (ix+20)" + - "bit 3, (iy+20)" + - "res 5, (ix+20), b" + - "res 5, (iy+20), b" + - "res 5, (ix+20)" + - "res 5, (iy+20)" + - "set 6, (ix+20), c" + - "set 6, (iy+20), c" + - "set 6, (ix+20)" + - "set 6, (iy+20)" + - "ld ix, 1234" + - "ld iy, 1234" + + "rlc (ix+20h), b" + + "rlc (iy+20h), b" + + "rlc (ix+20h)" + + "rlc (iy+20h)" + + "rrc (ix+20h), c" + + "rrc (iy+20h), c" + + "rrc (ix+20h)" + + "rrc (iy+20h)" + + "rl (ix+20h), d" + + "rl (iy+20h), d" + + "rl (ix+20h)" + + "rl (iy+20h)" + + "rr (ix+20h), e" + + "rr (iy+20h), e" + + "rr (ix+20h)" + + "rr (iy+20h)" + + "sla (ix+20h), h" + + "sla (iy+20h), h" + + "sla (ix+20h)" + + "sla (iy+20h)" + + "sra (ix+20h), l" + + "sra (iy+20h), l" + + "sra (ix+20h)" + + "sra (iy+20h)" + + "sll (ix+20h), b" + + "sll (iy+20h), b" + + "sll (ix+20h)" + + "sll (iy+20h)" + + "srl (ix+20h), c" + + "srl (iy+20h), c" + + "srl (ix+20h)" + + "srl (iy+20h)" + + "bit 3, (ix+20h)" + + "bit 3, (iy+20h)" + + "res 5, (ix+20h), b" + + "res 5, (iy+20h), b" + + "res 5, (ix+20h)" + + "res 5, (iy+20h)" + + "set 6, (ix+20h), c" + + "set 6, (iy+20h), c" + + "set 6, (ix+20h)" + + "set 6, (iy+20h)" + + "ld ix, 1234h" + + "ld iy, 1234h" + "add ix, bc" + "add iy, bc" + "add ix, de" + @@ -717,10 +717,10 @@ public void testDisassemble() throws InvalidInstructionException { "add iy, iy" + "add ix, sp" + "add iy, sp" + - "ld (1234), ix" + - "ld (1234), iy" + - "ld ix, (1234)" + - "ld iy, (1234)" + + "ld (1234h), ix" + + "ld (1234h), iy" + + "ld ix, (1234h)" + + "ld iy, (1234h)" + "inc ix" + "inc iy" + "dec ix" + @@ -729,20 +729,20 @@ public void testDisassemble() throws InvalidInstructionException { "inc iyh" + "inc ixl" + "inc iyl" + - "inc (ix+20)" + - "inc (iy+20)" + + "inc (ix+20h)" + + "inc (iy+20h)" + "dec ixh" + "dec iyh" + "dec ixl" + "dec iyl" + - "dec (ix+20)" + - "dec (iy+20)" + - "ld ixh, 20" + - "ld ixl, 20" + - "ld iyh, 20" + - "ld iyl, 20" + - "ld (ix+20), 20" + - "ld (iy+20), 20" + + "dec (ix+20h)" + + "dec (iy+20h)" + + "ld ixh, 20h" + + "ld ixl, 20h" + + "ld iyh, 20h" + + "ld iyl, 20h" + + "ld (ix+20h), 20h" + + "ld (iy+20h), 20h" + "ld ixh, b" + "ld ixh, ixh" + "ld ixh, ixl" + @@ -755,70 +755,70 @@ public void testDisassemble() throws InvalidInstructionException { "ld iyl, e" + "ld iyl, iyh" + "ld iyl, iyl" + - "ld (ix+20), d" + - "ld (ix+20), h" + - "ld (ix+20), l" + - "ld (iy+20), e" + - "ld (iy+20), h" + - "ld (iy+20), l" + + "ld (ix+20h), d" + + "ld (ix+20h), h" + + "ld (ix+20h), l" + + "ld (iy+20h), e" + + "ld (iy+20h), h" + + "ld (iy+20h), l" + "ld a, ixh" + "ld a, iyh" + "ld a, ixl" + "ld a, iyl" + - "ld a, (ix+20)" + - "ld a, (iy+20)" + - "ld h, (ix+20)" + - "ld l, (ix+20)" + - "ld h, (iy+20)" + - "ld l, (iy+20)" + + "ld a, (ix+20h)" + + "ld a, (iy+20h)" + + "ld h, (ix+20h)" + + "ld l, (ix+20h)" + + "ld h, (iy+20h)" + + "ld l, (iy+20h)" + "add a, ixh" + "add a, ixl" + - "add a, (ix+20)" + + "add a, (ix+20h)" + "add a, iyh" + "add a, iyl" + - "add a, (iy+20)" + + "add a, (iy+20h)" + "adc a, ixh" + "adc a, ixl" + - "adc a, (ix+20)" + + "adc a, (ix+20h)" + "adc a, iyh" + "adc a, iyl" + - "adc a, (iy+20)" + + "adc a, (iy+20h)" + "sub ixh" + "sub ixl" + - "sub (ix+20)" + + "sub (ix+20h)" + "sub iyh" + "sub iyl" + - "sub (iy+20)" + + "sub (iy+20h)" + "sbc a, ixh" + "sbc a, ixl" + - "sbc a, (ix+20)" + + "sbc a, (ix+20h)" + "sbc a, iyh" + "sbc a, iyl" + - "sbc a, (iy+20)" + + "sbc a, (iy+20h)" + "and ixh" + "and ixl" + - "and (ix+20)" + + "and (ix+20h)" + "and iyh" + "and iyl" + - "and (iy+20)" + + "and (iy+20h)" + "xor ixh" + "xor ixl" + - "xor (ix+20)" + + "xor (ix+20h)" + "xor iyh" + "xor iyl" + - "xor (iy+20)" + + "xor (iy+20h)" + "or ixh" + "or ixl" + - "or (ix+20)" + + "or (ix+20h)" + "or iyh" + "or iyl" + - "or (iy+20)" + + "or (iy+20h)" + "cp ixh" + "cp ixl" + - "cp (ix+20)" + + "cp (ix+20h)" + "cp iyh" + "cp iyl" + - "cp (iy+20)" + + "cp (iy+20h)" + "pop ix" + "pop iy" + "jp (ix)" + From 523a82903e98e28c91b7a96ab5b66159d463926d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 28 Jul 2022 20:29:09 +0100 Subject: [PATCH 184/314] 8080-cpu: mnemo 'h' constant suffix --- plugins/cpu/8080-cpu/src/main/edigen/cpu.eds | 162 +++++++++---------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds b/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds index af1ac22c1..47085d4a1 100644 --- a/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/8080-cpu/src/main/edigen/cpu.eds @@ -22,87 +22,87 @@ root instruction; # inspired by http://www.z80.info/decoding.htm # converted using https://pastraiser.com/cpu/i8080/i8080_opcodes.html and https://clrhome.org/table/ instruction = - "nop": 00 000 000 | # x=0, y=0, z=0 - "lxi %s, %X": 00 rp(2) 0 001 imm16 | # x=0, p=rp, q=0, z=1 - "dad %s": 00 rp(2) 1 001 | # x=0, p=rp, q=1, z=1 - "stax b": 00 000 010 | # x=0, p=0, q=0, z=2 - "stax d": 00 010 010 | # x=0, p=1, q=0, z=2 - "shld %X": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 - "sta %X": 00 110 010 ref16 | # x=0, p=3, q=0, z=2 - "ldax b": 00 001 010 | # x=0, p=0, q=1, z=2 - "ldax d": 00 011 010 | # x=0, p=1, q=1, z=2 - "lhld %X": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 - "lda %X": 00 111 010 ref16 | # x=0, p=3, q=1, z=2 - "inx %s": 00 rp(2) 0 011 | # x=0, p=rp, q=0, z=3 - "dcx %s": 00 rp(2) 1 011 | # x=0, p=rp, q=1, z=3 - "inr %s": 00 r(3) 100 | # x=0, y=r, z=4 - "dcr %s": 00 r(3) 101 | # x=0, y=r, z=5 - "mvi %s, %X": 00 r(3) 110 imm8 | # x=0, y=r, z=6 - "rlc": 00 000 111 | # x=0, y=0, z=7 - "rrc": 00 001 111 | # x=0, y=1, z=7 - "ral": 00 010 111 | # x=0, y=2, z=7 - "rar": 00 011 111 | # x=0, y=3, z=7 - "daa": 00 100 111 | # x=0, y=4, z=7 - "cma": 00 101 111 | # x=0, y=5, z=7 - "stc": 00 110 111 | # x=0, y=6, z=7 - "cmc": 00 111 111 | # x=0, y=7, z=7 - - "hlt": 01 110 110 | # x=1, y=6, z=6 - "mov %s, %s": 01 0 r_bcde(2) r(3) | # x=1, y=0 r_bcde, z=r - "mov %s, %s": 01 10 r_h_l(1) r(3) | # x=1, y=10 r_h_l, z=r - "mov a, %s": 01 111 r(3) | # x=1, y=7, z=r - "mov m, %s": 01 110 0 r_bcde(2) | # x=1, y=6, z=0 r_bcde - "mov m, %s": 01 110 10 r_h_l(1) | # x=1, y=6, z=10 r_h_l - "mov m, a": 01 110 111 | # x=1, y=6, z=7 - - "%s %s": 10 alu(3) r(3) | # x=2, y=alu, z=r - - "rnz": 11 000 000 | # x=3, y=0, z=0 - "rz": 11 001 000 | # x=3, y=1, z=0 - "rnc": 11 010 000 | # x=3, y=2, z=0 - "rc": 11 011 000 | # x=3, y=3, z=0 - "rpo": 11 100 000 | # x=3, y=4, z=0 - "rpe": 11 101 000 | # x=3, y=5, z=0 - "rp": 11 110 000 | # x=3, y=6, z=0 - "rm": 11 111 000 | # x=3, y=7, z=0 - - "pop %s": 11 rp2(2) 0 001 | # x=3, p=rp2, q=0, z=1 - "ret": 11 001 001 | # x=3, p=0, q=1, z=1 - "pchl": 11 101 001 | # x=3, p=2, q=1, z=1 - "sphl": 11 111 001 | # x=3, p=3, q=1, z=1 - - "jnz %X": 11 000 010 imm16 | # x=3, y=0, z=2 - "jz %X": 11 001 010 imm16 | # x=3, y=1, z=2 - "jnc %X": 11 010 010 imm16 | # x=3, y=2, z=2 - "jc %X": 11 011 010 imm16 | # x=3, y=3, z=2 - "jpo %X": 11 100 010 imm16 | # x=3, y=4, z=2 - "jpe %X": 11 101 010 imm16 | # x=3, y=5, z=2 - "jp %X": 11 110 010 imm16 | # x=3, y=6, z=2 - "jm %X": 11 111 010 imm16 | # x=3, y=7, z=2 - - "jmp %X": 11 000 011 imm16 | # x=3, y=0, z=3 - - "out %X": 11 010 011 ref8 | # x=3, y=2, z=3 - "in %X": 11 011 011 ref8 | # x=3, y=3, z=3 - "xthl": 11 100 011 | # x=3, y=4, z=3 - "xchg": 11 101 011 | # x=3, y=5, z=3 - "di": 11 110 011 | # x=3, y=6, z=3 - "ei": 11 111 011 | # x=3, y=7, z=3 - - "cnz %X": 11 000 100 imm16 | # x=3, y=0, z=4 - "cz %X": 11 001 100 imm16 | # x=3, y=1, z=4 - "cnc %X": 11 010 100 imm16 | # x=3, y=2, z=4 - "cc %X": 11 011 100 imm16 | # x=3, y=3, z=4 - "cpo %X": 11 100 100 imm16 | # x=3, y=4, z=4 - "cpe %X": 11 101 100 imm16 | # x=3, y=5, z=4 - "cp %X": 11 110 100 imm16 | # x=3, y=6, z=4 - "cm %X": 11 111 100 imm16 | # x=3, y=7, z=4 - - "push %s": 11 rp2(2) 0 101 | # x=3, p=rp2, q=0, z=5 - "call %X": 11 001 101 imm16 | # x=3, p=0, q=1, z=5 - - "%s %X": 11 alui(3) 110 imm8 | # x=3, y=alu, z=6 - "rst %X": 11 rst(3) 111 ; # x=3, y=rst, z=7 + "nop": 00 000 000 | # x=0, y=0, z=0 + "lxi %s, %Xh": 00 rp(2) 0 001 imm16 | # x=0, p=rp, q=0, z=1 + "dad %s": 00 rp(2) 1 001 | # x=0, p=rp, q=1, z=1 + "stax b": 00 000 010 | # x=0, p=0, q=0, z=2 + "stax d": 00 010 010 | # x=0, p=1, q=0, z=2 + "shld %Xh": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 + "sta %Xh": 00 110 010 ref16 | # x=0, p=3, q=0, z=2 + "ldax b": 00 001 010 | # x=0, p=0, q=1, z=2 + "ldax d": 00 011 010 | # x=0, p=1, q=1, z=2 + "lhld %Xh": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 + "lda %Xh": 00 111 010 ref16 | # x=0, p=3, q=1, z=2 + "inx %s": 00 rp(2) 0 011 | # x=0, p=rp, q=0, z=3 + "dcx %s": 00 rp(2) 1 011 | # x=0, p=rp, q=1, z=3 + "inr %s": 00 r(3) 100 | # x=0, y=r, z=4 + "dcr %s": 00 r(3) 101 | # x=0, y=r, z=5 + "mvi %s, %Xh": 00 r(3) 110 imm8 | # x=0, y=r, z=6 + "rlc": 00 000 111 | # x=0, y=0, z=7 + "rrc": 00 001 111 | # x=0, y=1, z=7 + "ral": 00 010 111 | # x=0, y=2, z=7 + "rar": 00 011 111 | # x=0, y=3, z=7 + "daa": 00 100 111 | # x=0, y=4, z=7 + "cma": 00 101 111 | # x=0, y=5, z=7 + "stc": 00 110 111 | # x=0, y=6, z=7 + "cmc": 00 111 111 | # x=0, y=7, z=7 + + "hlt": 01 110 110 | # x=1, y=6, z=6 + "mov %s, %s": 01 0 r_bcde(2) r(3) | # x=1, y=0 r_bcde, z=r + "mov %s, %s": 01 10 r_h_l(1) r(3) | # x=1, y=10 r_h_l, z=r + "mov a, %s": 01 111 r(3) | # x=1, y=7, z=r + "mov m, %s": 01 110 0 r_bcde(2) | # x=1, y=6, z=0 r_bcde + "mov m, %s": 01 110 10 r_h_l(1) | # x=1, y=6, z=10 r_h_l + "mov m, a": 01 110 111 | # x=1, y=6, z=7 + + "%s %s": 10 alu(3) r(3) | # x=2, y=alu, z=r + + "rnz": 11 000 000 | # x=3, y=0, z=0 + "rz": 11 001 000 | # x=3, y=1, z=0 + "rnc": 11 010 000 | # x=3, y=2, z=0 + "rc": 11 011 000 | # x=3, y=3, z=0 + "rpo": 11 100 000 | # x=3, y=4, z=0 + "rpe": 11 101 000 | # x=3, y=5, z=0 + "rp": 11 110 000 | # x=3, y=6, z=0 + "rm": 11 111 000 | # x=3, y=7, z=0 + + "pop %s": 11 rp2(2) 0 001 | # x=3, p=rp2, q=0, z=1 + "ret": 11 001 001 | # x=3, p=0, q=1, z=1 + "pchl": 11 101 001 | # x=3, p=2, q=1, z=1 + "sphl": 11 111 001 | # x=3, p=3, q=1, z=1 + + "jnz %Xh": 11 000 010 imm16 | # x=3, y=0, z=2 + "jz %Xh": 11 001 010 imm16 | # x=3, y=1, z=2 + "jnc %Xh": 11 010 010 imm16 | # x=3, y=2, z=2 + "jc %Xh": 11 011 010 imm16 | # x=3, y=3, z=2 + "jpo %Xh": 11 100 010 imm16 | # x=3, y=4, z=2 + "jpe %Xh": 11 101 010 imm16 | # x=3, y=5, z=2 + "jp %Xh": 11 110 010 imm16 | # x=3, y=6, z=2 + "jm %Xh": 11 111 010 imm16 | # x=3, y=7, z=2 + + "jmp %Xh": 11 000 011 imm16 | # x=3, y=0, z=3 + + "out %Xh": 11 010 011 ref8 | # x=3, y=2, z=3 + "in %Xh": 11 011 011 ref8 | # x=3, y=3, z=3 + "xthl": 11 100 011 | # x=3, y=4, z=3 + "xchg": 11 101 011 | # x=3, y=5, z=3 + "di": 11 110 011 | # x=3, y=6, z=3 + "ei": 11 111 011 | # x=3, y=7, z=3 + + "cnz %Xh": 11 000 100 imm16 | # x=3, y=0, z=4 + "cz %Xh": 11 001 100 imm16 | # x=3, y=1, z=4 + "cnc %Xh": 11 010 100 imm16 | # x=3, y=2, z=4 + "cc %Xh": 11 011 100 imm16 | # x=3, y=3, z=4 + "cpo %Xh": 11 100 100 imm16 | # x=3, y=4, z=4 + "cpe %Xh": 11 101 100 imm16 | # x=3, y=5, z=4 + "cp %Xh": 11 110 100 imm16 | # x=3, y=6, z=4 + "cm %Xh": 11 111 100 imm16 | # x=3, y=7, z=4 + + "push %s": 11 rp2(2) 0 101 | # x=3, p=rp2, q=0, z=5 + "call %Xh": 11 001 101 imm16 | # x=3, p=0, q=1, z=5 + + "%s %Xh": 11 alui(3) 110 imm8 | # x=3, y=alu, z=6 + "rst %d": 11 rst(3) 111 ; # x=3, y=rst, z=7 alu = From e55ec9030675985e03a9130f68aa1580b193ce3d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 1 Aug 2022 20:58:10 +0100 Subject: [PATCH 185/314] [#163, #243] Reimplement 88-SIO device + support interrupts + support TTY,ANSI,upperCase modes + support mapping characters --- .../src/main/files/config/MITSAltair8800.toml | 24 +- .../main/files/config/MITSAltair8800Z80.toml | 24 +- .../cmdline/AutomationCommand.java | 7 +- .../emustudio/application/cmdline/Runner.java | 11 +- .../emustudio/application/cmdline/Utils.java | 4 +- .../configuration/ApplicationConfig.java | 133 ------- .../application/emulation/Automation.java | 2 +- .../emustudio/application/gui/GuiUtils.java | 3 +- .../java/net/emustudio/application/gui/P.java | 2 +- .../gui/actions/ViewComputerAction.java | 2 +- .../opencomputer/AddNewComputerAction.java | 8 +- .../opencomputer/DeleteComputerAction.java | 4 +- .../opencomputer/EditComputerAction.java | 4 +- .../opencomputer/OpenComputerAction.java | 2 +- .../opencomputer/RenameComputerAction.java | 6 +- .../gui/dialogs/OpenComputerDialog.java | 6 +- .../gui/dialogs/SchemaEditorDialog.java | 4 +- .../application/gui/dialogs/StudioFrame.java | 2 +- .../gui/dialogs/ViewComputerDialog.java | 4 +- .../application/gui/schema/Schema.java | 24 +- .../gui/schema/elements/CompilerElement.java | 2 +- .../gui/schema/elements/ConnectionLine.java | 4 +- .../gui/schema/elements/CpuElement.java | 2 +- .../gui/schema/elements/DeviceElement.java | 2 +- .../gui/schema/elements/Element.java | 2 +- .../gui/schema/elements/MemoryElement.java | 2 +- .../settings/ApplicationConfig.java | 89 +++++ .../settings/BasicSettingsImpl.java | 130 +++++++ .../ComputerConfig.java | 19 +- .../ConfigFiles.java | 16 +- .../PluginConfig.java | 6 +- .../PluginConnection.java | 2 +- .../PluginSettingsImpl.java | 78 ++-- .../SchemaPoint.java | 2 +- .../virtualcomputer/VirtualComputer.java | 64 ++-- .../emulation/EmulationControllerTest.java | 2 +- .../ApplicationConfigTest.java | 2 +- .../ComputerConfigTest.java | 2 +- .../ConfigFilesTest.java | 4 +- .../PluginConfigTest.java | 2 +- .../SchemaPointTest.java | 2 +- .../virtualcomputer/PluginLoaderTest.java | 2 +- .../virtualcomputer/VirtualComputerTest.java | 6 +- .../virtualcomputer/stubs/CPUImplStub.java | 2 +- .../stubs/UnannotatedCPUStub.java | 2 +- .../dependencies/APluginDependsOnB.class | Bin 1340 -> 1375 bytes .../dependencies/APluginDependsOnB.java | 6 +- .../src/test/resources/dependencies/README | 5 +- .../compiler/as8080/Assembler8080.java | 2 +- .../plugins/compiler/as8080/Runner.java | 2 +- .../as8080/e2e/AbstractCompilerTest.java | 2 +- .../plugins/compiler/ssem/Runner.java | 2 +- .../plugins/compiler/ssem/SSEMCompiler.java | 2 +- .../compiler/ssem/SSEMCompilerTest.java | 2 +- .../plugins/compiler/asZ80/AssemblerZ80.java | 2 +- .../plugins/compiler/asZ80/Runner.java | 2 +- .../asZ80/e2e/AbstractCompilerTest.java | 2 +- .../compiler/brainduck/CompilerImpl.java | 2 +- .../plugins/compiler/brainduck/Runner.java | 2 +- .../brainduck/AbstractCompilerTest.java | 2 +- .../compiler/brainduck/InstructionTest.java | 2 +- .../plugins/compiler/ram/CompilerRAM.java | 1 + .../plugins/compiler/ram/Runner.java | 2 +- .../compiler/ram/AbstractCompilerTest.java | 2 +- .../plugins/compiler/ram/CompilerTest.java | 2 +- .../plugins/compiler/rasp/CompilerRASP.java | 2 +- .../plugins/compiler/rasp/Runner.java | 2 +- .../compiler/rasp/AbstractCompilerTest.java | 2 +- .../cpu/intel8080/Context8080Impl.java | 3 +- .../plugins/cpu/intel8080/CpuImpl.java | 2 +- .../cpu/intel8080/InitializerFor8080.java | 2 +- .../cpu/intel8080/api/DefaultInitializer.java | 2 +- .../plugins/cpu/intel8080/CpuImplTest.java | 2 +- .../cpu/intel8080/InstructionsTest.java | 2 +- .../plugins/cpu/brainduck/CpuImpl.java | 2 +- .../plugins/cpu/brainduck/CpuImplTest.java | 2 +- .../emustudio/plugins/cpu/ram/CpuImpl.java | 2 +- .../plugins/cpu/ram/CpuImplTest.java | 2 +- .../emustudio/plugins/cpu/rasp/CpuImpl.java | 1 + .../plugins/cpu/rasp/CpuImplTest.java | 2 +- .../emustudio/plugins/cpu/ssem/CpuImpl.java | 2 +- .../plugins/cpu/ssem/CpuImplTest.java | 2 +- .../plugins/cpu/ssem/DisassemblerTest.java | 2 +- .../plugins/cpu/zilogZ80/ContextZ80Impl.java | 2 +- .../plugins/cpu/zilogZ80/CpuImpl.java | 2 +- .../plugins/cpu/zilogZ80/InitializerZ80.java | 2 +- .../plugins/cpu/zilogZ80/CpuImplTest.java | 2 +- .../cpu/zilogZ80/InstructionsTest.java | 2 +- .../plugins/device/mits88dcdd/DeviceImpl.java | 2 +- .../device/mits88dcdd/gui/SettingsDialog.java | 27 +- .../device/mits88dcdd/DeviceImplTest.java | 2 +- .../plugins/device/mits88sio/DeviceImpl.java | 71 ++-- .../plugins/device/mits88sio/SIOSettings.java | 131 ------- .../plugins/device/mits88sio/SioUnit.java | 118 +++++++ .../mits88sio/{Transmitter.java => UART.java} | 117 ++++-- .../mits88sio/gui/CPUPortsTableModel.java | 58 --- .../device/mits88sio/gui/PortListModel.java | 6 +- .../device/mits88sio/gui/SettingsDialog.java | 334 +++++++++++------- .../plugins/device/mits88sio/gui/SioGui.java | 100 ++---- .../device/mits88sio/ports/CpuDataPort.java | 61 ---- .../device/mits88sio/ports/CpuPorts.java | 86 ----- .../device/mits88sio/ports/CpuStatusPort.java | 57 --- .../device/mits88sio/ports/PhysicalPort.java | 53 --- .../mits88sio/settings/SettingsObserver.java | 9 +- .../mits88sio/settings/SioDeviceSettings.java | 44 +++ .../mits88sio/settings/SioUnitSettings.java | 173 +++++++++ .../device/mits88sio/DeviceChannelTest.java} | 28 +- .../device/mits88sio/DeviceImplTest.java | 2 +- .../device/mits88sio/SIOSettingsTest.java | 141 -------- .../plugins/device/mits88sio/SuiUnitTest.java | 60 ++++ .../{TransmitterTest.java => UARTTest.java} | 50 +-- .../mits88sio/ports/CpuDataPortTest.java | 60 ---- .../device/mits88sio/ports/CpuPortsTest.java | 103 ------ .../mits88sio/ports/CpuStatusPortTest.java | 59 ---- .../mits88sio/ports/PhysicalPortTest.java | 59 ---- .../device/abstracttape/AbstractTape.java | 2 +- .../abstracttape/gui/SettingsDialog.java | 4 +- .../device/abstracttape/AbstractTapeTest.java | 2 +- .../plugins/device/adm3a/DeviceImpl.java | 5 +- .../device/adm3a/TerminalSettings.java | 16 +- .../plugins/device/adm3a/DeviceImplTest.java | 2 +- .../device/brainduck/terminal/DeviceImpl.java | 2 +- .../brainduck/terminal/DeviceImplTest.java | 2 +- .../plugins/device/simh/DeviceImpl.java | 2 +- .../device/simh/commands/GenInterrupt.java | 2 +- .../simh/commands/StartTimerInterrupts.java | 2 +- .../plugins/device/simh/DeviceImplTest.java | 2 +- .../device/ssem/display/DeviceImpl.java | 2 +- .../device/ssem/display/DeviceImplTest.java | 2 +- .../plugins/memory/bytemem/MemoryImpl.java | 5 +- .../plugins/memory/bytemem/gui/MemoryGui.java | 2 +- .../memory/bytemem/gui/SettingsDialog.java | 4 +- .../bytemem/gui/model/FileImagesModel.java | 2 +- .../memory/bytemem/MemoryImplTest.java | 2 +- .../plugins/memory/ram/MemoryImpl.java | 1 + .../plugins/memory/ram/MemoryImplTest.java | 2 +- .../plugins/memory/rasp/MemoryImpl.java | 2 +- .../plugins/memory/rasp/MemoryImplTest.java | 2 +- .../plugins/memory/ssem/MemoryImpl.java | 2 +- .../plugins/memory/ssem/MemoryImplTest.java | 2 +- 140 files changed, 1296 insertions(+), 1600 deletions(-) delete mode 100644 application/src/main/java/net/emustudio/application/configuration/ApplicationConfig.java create mode 100644 application/src/main/java/net/emustudio/application/settings/ApplicationConfig.java create mode 100644 application/src/main/java/net/emustudio/application/settings/BasicSettingsImpl.java rename application/src/main/java/net/emustudio/application/{configuration => settings}/ComputerConfig.java (89%) rename application/src/main/java/net/emustudio/application/{configuration => settings}/ConfigFiles.java (91%) rename application/src/main/java/net/emustudio/application/{configuration => settings}/PluginConfig.java (93%) rename application/src/main/java/net/emustudio/application/{configuration => settings}/PluginConnection.java (97%) rename application/src/main/java/net/emustudio/application/{configuration => settings}/PluginSettingsImpl.java (62%) rename application/src/main/java/net/emustudio/application/{configuration => settings}/SchemaPoint.java (97%) rename application/src/test/java/net/emustudio/application/{configuration => settings}/ApplicationConfigTest.java (97%) rename application/src/test/java/net/emustudio/application/{configuration => settings}/ComputerConfigTest.java (98%) rename application/src/test/java/net/emustudio/application/{configuration => settings}/ConfigFilesTest.java (90%) rename application/src/test/java/net/emustudio/application/{configuration => settings}/PluginConfigTest.java (97%) rename application/src/test/java/net/emustudio/application/{configuration => settings}/SchemaPointTest.java (97%) delete mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SIOSettings.java create mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java rename plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/{Transmitter.java => UART.java} (56%) delete mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/CPUPortsTableModel.java delete mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPort.java delete mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuPorts.java delete mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPort.java delete mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPort.java rename application/src/main/java/net/emustudio/application/configuration/ConfigSaver.java => plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SettingsObserver.java (79%) create mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java create mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java rename plugins/device/88-sio/src/{main/java/net/emustudio/plugins/device/mits88sio/ports/CouldNotAttachException.java => test/java/net/emustudio/plugins/device/mits88sio/DeviceChannelTest.java} (52%) delete mode 100644 plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SIOSettingsTest.java create mode 100644 plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SuiUnitTest.java rename plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/{TransmitterTest.java => UARTTest.java} (54%) delete mode 100644 plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPortTest.java delete mode 100644 plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuPortsTest.java delete mode 100644 plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPortTest.java delete mode 100644 plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPortTest.java diff --git a/application/src/main/files/config/MITSAltair8800.toml b/application/src/main/files/config/MITSAltair8800.toml index 7dbb7d87b..c47db2324 100644 --- a/application/src/main/files/config/MITSAltair8800.toml +++ b/application/src/main/files/config/MITSAltair8800.toml @@ -103,20 +103,16 @@ name = "MITS Altair8800" type = "DEVICE" [DEVICE.settings] - statusPortNumber0 = 0 - statusPortNumber1 = 1 - statusPortNumber2 = 3 - statusPortNumber3 = 5 - statusPortNumber4 = 16 - statusPortNumber5 = 20 - statusPortNumber6 = 22 - statusPortNumber7 = 24 - dataPortNumber0 = 2 - dataPortNumber1 = 4 - dataPortNumber2 = 17 - dataPortNumber3 = 21 - dataPortNumber4 = 23 - dataPortNumber5 = 25 + [DEVICE.settings.sio] + statusPorts = "0x10, 0x14, 0x16, 0x18" + dataPorts = "0x11, 0x15, 0x17, 0x19" + clearInputBit8 = false + clearOutputBit8 = false + inputToUpperCase = false + mapDeleteChar = "UNCHANGED" + mapBackspaceChar = "UNCHANGED" + inputInterruptVector = 0 + outputInterruptVector = 0 [[DEVICE]] schemaPoint = "340,60" diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index 8806015bd..47b200e45 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -99,20 +99,16 @@ name = "MITS Altair8800 (Z80)" type = "DEVICE" [DEVICE.settings] - statusPortNumber0 = 0 - statusPortNumber1 = 1 - statusPortNumber2 = 3 - statusPortNumber3 = 5 - statusPortNumber4 = 16 - statusPortNumber5 = 20 - statusPortNumber6 = 22 - statusPortNumber7 = 24 - dataPortNumber0 = 2 - dataPortNumber1 = 4 - dataPortNumber2 = 17 - dataPortNumber3 = 21 - dataPortNumber4 = 23 - dataPortNumber5 = 25 + [DEVICE.settings.sio] + statusPorts = "0x10, 0x14, 0x16, 0x18" + dataPorts = "0x11, 0x15, 0x17, 0x19" + clearInputBit8 = false + clearOutputBit8 = false + inputToUpperCase = false + mapDeleteChar = "UNCHANGED" + mapBackspaceChar = "UNCHANGED" + inputInterruptVector = 0 + outputInterruptVector = 0 [[DEVICE]] schemaPoint = "480,220" diff --git a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java index b2d8acef7..0dcbd8055 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java +++ b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java @@ -18,8 +18,8 @@ */ package net.emustudio.application.cmdline; -import net.emustudio.application.configuration.ApplicationConfig; -import net.emustudio.application.configuration.ComputerConfig; +import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.emulation.Automation; import net.emustudio.application.gui.ExtendedDialogs; import net.emustudio.application.gui.GuiDialogsImpl; @@ -60,7 +60,8 @@ public class AutomationCommand implements Runnable { @Override public void run() { ExtendedDialogs dialogs = new NoGuiDialogsImpl(); - try (ApplicationConfig appConfig = loadAppConfig(gui, true)) { + try { + ApplicationConfig appConfig = loadAppConfig(gui, true); if (gui) { setupLookAndFeel(appConfig); dialogs = new GuiDialogsImpl(); diff --git a/application/src/main/java/net/emustudio/application/cmdline/Runner.java b/application/src/main/java/net/emustudio/application/cmdline/Runner.java index a3802f70d..0e07f1a8f 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/Runner.java +++ b/application/src/main/java/net/emustudio/application/cmdline/Runner.java @@ -19,9 +19,9 @@ package net.emustudio.application.cmdline; import net.emustudio.application.Resources; -import net.emustudio.application.configuration.ApplicationConfig; -import net.emustudio.application.configuration.ComputerConfig; -import net.emustudio.application.configuration.ConfigFiles; +import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.ComputerConfig; +import net.emustudio.application.settings.ConfigFiles; import net.emustudio.application.gui.ExtendedDialogs; import net.emustudio.application.gui.GuiDialogsImpl; import net.emustudio.application.gui.debugtable.DebugTableModelImpl; @@ -37,7 +37,7 @@ import java.util.Optional; import static net.emustudio.application.cmdline.Utils.*; -import static net.emustudio.application.configuration.ConfigFiles.listConfigurationNames; +import static net.emustudio.application.settings.ConfigFiles.listConfigurationNames; import static net.emustudio.application.gui.GuiUtils.setupLookAndFeel; @SuppressWarnings("unused") @@ -93,7 +93,8 @@ public void run() { } if (!runsSomeCommand) { - try (ApplicationConfig appConfig = loadAppConfig(true, false)) { + try { + ApplicationConfig appConfig = loadAppConfig(true, false); setupLookAndFeel(appConfig); ExtendedDialogs dialogs = new GuiDialogsImpl(); Optional computerConfigOpt = (exclusive != null) ? diff --git a/application/src/main/java/net/emustudio/application/cmdline/Utils.java b/application/src/main/java/net/emustudio/application/cmdline/Utils.java index d7fefdd19..bb87cf63b 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/Utils.java +++ b/application/src/main/java/net/emustudio/application/cmdline/Utils.java @@ -19,8 +19,8 @@ package net.emustudio.application.cmdline; import net.emustudio.application.ApplicationApiImpl; -import net.emustudio.application.configuration.ApplicationConfig; -import net.emustudio.application.configuration.ComputerConfig; +import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.ExtendedDialogs; import net.emustudio.application.gui.debugtable.DebugTableModel; import net.emustudio.application.gui.debugtable.DebugTableModelImpl; diff --git a/application/src/main/java/net/emustudio/application/configuration/ApplicationConfig.java b/application/src/main/java/net/emustudio/application/configuration/ApplicationConfig.java deleted file mode 100644 index 17069c668..000000000 --- a/application/src/main/java/net/emustudio/application/configuration/ApplicationConfig.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.application.configuration; - -import com.electronwill.nightconfig.core.file.FileConfig; - -import java.io.Closeable; -import java.nio.file.Path; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static net.emustudio.emulib.runtime.PluginSettings.*; - -@SuppressWarnings("unused") -public class ApplicationConfig implements Closeable { - public final static String KEY_NOGUI = EMUSTUDIO_NO_GUI.substring(EMUSTUDIO_PREFIX.length()); - public final static String KEY_AUTO = EMUSTUDIO_AUTO.substring(EMUSTUDIO_PREFIX.length()); - public final static String KEY_USE_SCHEMA_GRID = "useSchemaGrid"; - public final static String KEY_SCHEMA_GRID_GAP = "schemaGridGap"; - public final static String KEY_LOOK_AND_FEEL = "lookAndFeel"; - - public transient final boolean emuStudioAuto; - public transient final boolean noGUI; - - private final FileConfig config; - - public ApplicationConfig(FileConfig config, boolean nogui, boolean auto) { - this.config = Objects.requireNonNull(config); - this.emuStudioAuto = auto; - this.noGUI = nogui; - } - - public boolean contains(String key) { - return KEY_NOGUI.equals(key) || KEY_AUTO.equals(key) || KEY_USE_SCHEMA_GRID.equals(key) - || KEY_SCHEMA_GRID_GAP.equals(key) || KEY_LOOK_AND_FEEL.equals(key); - } - - public Optional getBoolean(String key) { - if (KEY_USE_SCHEMA_GRID.equals(key)) { - return useSchemaGrid(); - } else if (KEY_SCHEMA_GRID_GAP.equals(key)) { - return useSchemaGrid(); - } else if (KEY_AUTO.equals(key)) { - return Optional.of(emuStudioAuto); - } else if (KEY_NOGUI.equals(key)) { - return Optional.of(noGUI); - } - return Optional.empty(); - } - - public Optional getInt(String key) { - if (KEY_SCHEMA_GRID_GAP.equals(key)) { - return getSchemaGridGap(); - } - return Optional.empty(); - } - - public Optional getLong(String key) { - return Optional.empty(); - } - - public Optional getDouble(String key) { - return Optional.empty(); - } - - public Optional getString(String key) { - if (KEY_LOOK_AND_FEEL.equals(key)) { - return getLookAndFeel(); - } - return Optional.empty(); - } - - public List getArray(String key) { - return Collections.emptyList(); - } - - public Optional useSchemaGrid() { - return config.getOptional(KEY_USE_SCHEMA_GRID); - } - - public void setUseSchemaGrid(boolean useSchemaGrid) { - config.set(KEY_USE_SCHEMA_GRID, useSchemaGrid); - } - - public Optional getSchemaGridGap() { - return config.getOptional(KEY_SCHEMA_GRID_GAP); - } - - public void setSchemaGridGap(int schemaGridGap) { - config.set(KEY_SCHEMA_GRID_GAP, schemaGridGap); - } - - public Optional getLookAndFeel() { - return config.getOptional(KEY_LOOK_AND_FEEL); - } - - public void setLookAndFeel(String lookAndFeel) { - config.set(KEY_LOOK_AND_FEEL, lookAndFeel); - } - - public void save() { - config.save(); - } - - @Override - public void close() { - config.close(); - } - - public static ApplicationConfig fromFile(Path file, boolean nogui, boolean auto) { - FileConfig config = FileConfig.of(file); - config.load(); - return new ApplicationConfig(config, nogui, auto); - } -} diff --git a/application/src/main/java/net/emustudio/application/emulation/Automation.java b/application/src/main/java/net/emustudio/application/emulation/Automation.java index 98f70f14e..d8284d707 100644 --- a/application/src/main/java/net/emustudio/application/emulation/Automation.java +++ b/application/src/main/java/net/emustudio/application/emulation/Automation.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.emulation; -import net.emustudio.application.configuration.ApplicationConfig; +import net.emustudio.application.settings.ApplicationConfig; import net.emustudio.application.gui.dialogs.AutoDialog; import net.emustudio.application.internal.Unchecked; import net.emustudio.application.virtualcomputer.VirtualComputer; diff --git a/application/src/main/java/net/emustudio/application/gui/GuiUtils.java b/application/src/main/java/net/emustudio/application/gui/GuiUtils.java index b47a9431a..d777cd3ed 100644 --- a/application/src/main/java/net/emustudio/application/gui/GuiUtils.java +++ b/application/src/main/java/net/emustudio/application/gui/GuiUtils.java @@ -19,8 +19,7 @@ package net.emustudio.application.gui; import net.emustudio.application.Constants; -import net.emustudio.application.cmdline.Runner; -import net.emustudio.application.configuration.ApplicationConfig; +import net.emustudio.application.settings.ApplicationConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/application/src/main/java/net/emustudio/application/gui/P.java b/application/src/main/java/net/emustudio/application/gui/P.java index 443ab66a5..a813912d3 100644 --- a/application/src/main/java/net/emustudio/application/gui/P.java +++ b/application/src/main/java/net/emustudio/application/gui/P.java @@ -19,7 +19,7 @@ package net.emustudio.application.gui; -import net.emustudio.application.configuration.SchemaPoint; +import net.emustudio.application.settings.SchemaPoint; import java.awt.*; diff --git a/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java index c1fb7ffe9..aa2620a7e 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.gui.actions; -import net.emustudio.application.configuration.ApplicationConfig; +import net.emustudio.application.settings.ApplicationConfig; import net.emustudio.application.gui.dialogs.ViewComputerDialog; import net.emustudio.application.virtualcomputer.VirtualComputer; import net.emustudio.emulib.runtime.interaction.Dialogs; diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java index c0bed6a9b..a13e041a4 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java @@ -18,8 +18,8 @@ */ package net.emustudio.application.gui.actions.opencomputer; -import net.emustudio.application.configuration.ApplicationConfig; -import net.emustudio.application.configuration.ComputerConfig; +import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.dialogs.SchemaEditorDialog; import net.emustudio.application.gui.schema.Schema; import net.emustudio.application.internal.Unchecked; @@ -33,8 +33,8 @@ import java.util.Objects; import java.util.Optional; -import static net.emustudio.application.configuration.ConfigFiles.createConfiguration; -import static net.emustudio.application.configuration.ConfigFiles.loadConfiguration; +import static net.emustudio.application.settings.ConfigFiles.createConfiguration; +import static net.emustudio.application.settings.ConfigFiles.loadConfiguration; public class AddNewComputerAction extends AbstractAction { private final static Logger LOGGER = LoggerFactory.getLogger(AddNewComputerAction.class); diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/DeleteComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/DeleteComputerAction.java index 749ef8780..ef88d20c6 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/DeleteComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/DeleteComputerAction.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.gui.actions.opencomputer; -import net.emustudio.application.configuration.ComputerConfig; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.emulib.runtime.interaction.Dialogs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,7 +29,7 @@ import java.util.Objects; import java.util.Optional; -import static net.emustudio.application.configuration.ConfigFiles.removeConfiguration; +import static net.emustudio.application.settings.ConfigFiles.removeConfiguration; public class DeleteComputerAction extends AbstractAction { private final static Logger LOGGER = LoggerFactory.getLogger(DeleteComputerAction.class); diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java index f302e2d52..0878388f1 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java @@ -18,8 +18,8 @@ */ package net.emustudio.application.gui.actions.opencomputer; -import net.emustudio.application.configuration.ApplicationConfig; -import net.emustudio.application.configuration.ComputerConfig; +import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.dialogs.SchemaEditorDialog; import net.emustudio.application.gui.schema.Schema; import net.emustudio.emulib.runtime.interaction.Dialogs; diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/OpenComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/OpenComputerAction.java index b911f155c..36773132c 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/OpenComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/OpenComputerAction.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.gui.actions.opencomputer; -import net.emustudio.application.configuration.ComputerConfig; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.emulib.runtime.interaction.Dialogs; import javax.swing.*; diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/RenameComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/RenameComputerAction.java index e380f66a4..5f4eda2c3 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/RenameComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/RenameComputerAction.java @@ -18,9 +18,9 @@ */ package net.emustudio.application.gui.actions.opencomputer; -import net.emustudio.application.configuration.ComputerConfig; -import net.emustudio.emulib.runtime.CannotUpdateSettingException; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +30,7 @@ import java.util.Objects; import java.util.Optional; -import static net.emustudio.application.configuration.ConfigFiles.renameConfiguration; +import static net.emustudio.application.settings.ConfigFiles.renameConfiguration; public class RenameComputerAction extends AbstractAction { private final static Logger LOGGER = LoggerFactory.getLogger(RenameComputerAction.class); diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java index 9621fc225..c37b4dcf3 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java @@ -18,8 +18,8 @@ */ package net.emustudio.application.gui.dialogs; -import net.emustudio.application.configuration.ApplicationConfig; -import net.emustudio.application.configuration.ComputerConfig; +import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.ToolbarButton; import net.emustudio.application.gui.actions.opencomputer.*; import net.emustudio.application.gui.schema.Schema; @@ -41,7 +41,7 @@ import java.util.Optional; import java.util.function.Consumer; -import static net.emustudio.application.configuration.ConfigFiles.loadConfigurations; +import static net.emustudio.application.settings.ConfigFiles.loadConfigurations; public class OpenComputerDialog extends JDialog { private final static Logger LOGGER = LoggerFactory.getLogger(OpenComputerDialog.class); diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/SchemaEditorDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/SchemaEditorDialog.java index 7b40b1844..a782ef7b0 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/SchemaEditorDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/SchemaEditorDialog.java @@ -24,8 +24,8 @@ import net.emustudio.application.gui.schema.DrawingPanel.Tool; import net.emustudio.application.gui.schema.Schema; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; -import net.emustudio.emulib.runtime.CannotUpdateSettingException; import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,7 +41,7 @@ import java.util.Objects; import java.util.Optional; -import static net.emustudio.application.configuration.ConfigFiles.listPluginFiles; +import static net.emustudio.application.settings.ConfigFiles.listPluginFiles; import static net.emustudio.application.gui.GuiUtils.addKeyListenerRecursively; public class SchemaEditorDialog extends JDialog implements KeyListener { diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java b/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java index 5882685c5..50c0bf8d0 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.gui.dialogs; -import net.emustudio.application.configuration.ApplicationConfig; +import net.emustudio.application.settings.ApplicationConfig; import net.emustudio.application.emulation.EmulationController; import net.emustudio.application.gui.actions.AboutAction; import net.emustudio.application.gui.actions.CompilerSettingsAction; diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java index e1fd67f8d..4a1c46707 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java @@ -18,8 +18,8 @@ */ package net.emustudio.application.gui.dialogs; -import net.emustudio.application.configuration.ApplicationConfig; -import net.emustudio.application.configuration.PluginConfig; +import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.schema.Schema; import net.emustudio.application.gui.schema.SchemaPreviewPanel; import net.emustudio.application.virtualcomputer.VirtualComputer; diff --git a/application/src/main/java/net/emustudio/application/gui/schema/Schema.java b/application/src/main/java/net/emustudio/application/gui/schema/Schema.java index 013302b1f..bce004fa3 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/Schema.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/Schema.java @@ -18,13 +18,12 @@ */ package net.emustudio.application.gui.schema; -import net.emustudio.application.configuration.ApplicationConfig; -import net.emustudio.application.configuration.ComputerConfig; -import net.emustudio.application.configuration.PluginConfig; -import net.emustudio.application.configuration.PluginConnection; +import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.ComputerConfig; +import net.emustudio.application.settings.PluginConfig; +import net.emustudio.application.settings.PluginConnection; import net.emustudio.application.gui.P; import net.emustudio.application.gui.schema.elements.*; -import net.emustudio.emulib.runtime.CannotUpdateSettingException; import java.awt.*; import java.util.List; @@ -34,7 +33,6 @@ public class Schema { public final static int MIN_LEFT_MARGIN = 5; public final static int MIN_TOP_MARGIN = 5; - private final static int DEFAULT_GRID_GAP = 20; private CompilerElement compilerElement; private CpuElement cpuElement; @@ -56,7 +54,7 @@ public ComputerConfig getComputerConfig() { } public boolean useSchemaGrid() { - return applicationConfig.useSchemaGrid().orElse(true); + return applicationConfig.useSchemaGrid(); } public void setUseSchemaGrid(boolean useSchemaGrid) { @@ -64,7 +62,7 @@ public void setUseSchemaGrid(boolean useSchemaGrid) { } public int getSchemaGridGap() { - return applicationConfig.getSchemaGridGap().orElse(DEFAULT_GRID_GAP); + return applicationConfig.getSchemaGridGap(); } public void setSchemaGridGap(int gridGap) { @@ -204,11 +202,7 @@ public void select(int x, int y, int width, int height) { Point p2 = new Point(x + width, y + height); for (Element elem : getAllElements()) { - if (elem.crossesArea(p1, p2)) { - elem.setSelected(true); - } else { - elem.setSelected(false); - } + elem.setSelected(elem.crossesArea(p1, p2)); } lines.forEach(line -> line.setSelected(line.isAreaCrossing(p1, p2))); } @@ -381,7 +375,7 @@ private boolean allPointMovable(List

points, int diffX, int diffY) { return true; } - public void save() throws CannotUpdateSettingException { + public void save() { List connections = lines.stream() .map(ConnectionLine::toPluginConnection) .collect(Collectors.toList()); @@ -400,8 +394,6 @@ public void save() throws CannotUpdateSettingException { List devices = deviceElements.stream().map(Element::save).collect(Collectors.toList()); config.setDevices(devices); - - config.save(); } /** diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/CompilerElement.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/CompilerElement.java index 55fb11122..1df725ff0 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/CompilerElement.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/CompilerElement.java @@ -19,7 +19,7 @@ package net.emustudio.application.gui.schema.elements; import com.electronwill.nightconfig.core.Config; -import net.emustudio.application.configuration.PluginConfig; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.P; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/ConnectionLine.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/ConnectionLine.java index a5fa80454..2e67a0815 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/ConnectionLine.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/ConnectionLine.java @@ -18,8 +18,8 @@ */ package net.emustudio.application.gui.schema.elements; -import net.emustudio.application.configuration.PluginConnection; -import net.emustudio.application.configuration.SchemaPoint; +import net.emustudio.application.settings.PluginConnection; +import net.emustudio.application.settings.SchemaPoint; import net.emustudio.application.gui.P; import net.emustudio.application.gui.schema.Schema; diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/CpuElement.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/CpuElement.java index 38b23e0fe..421454904 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/CpuElement.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/CpuElement.java @@ -19,7 +19,7 @@ package net.emustudio.application.gui.schema.elements; import com.electronwill.nightconfig.core.Config; -import net.emustudio.application.configuration.PluginConfig; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.P; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/DeviceElement.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/DeviceElement.java index 5546b15d7..2e5b647f8 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/DeviceElement.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/DeviceElement.java @@ -19,7 +19,7 @@ package net.emustudio.application.gui.schema.elements; import com.electronwill.nightconfig.core.Config; -import net.emustudio.application.configuration.PluginConfig; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.P; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/Element.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/Element.java index 2a566089a..e21e71098 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/Element.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/Element.java @@ -19,7 +19,7 @@ package net.emustudio.application.gui.schema.elements; import com.electronwill.nightconfig.core.Config; -import net.emustudio.application.configuration.PluginConfig; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.P; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/MemoryElement.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/MemoryElement.java index 62791cb6f..400b07fe2 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/MemoryElement.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/MemoryElement.java @@ -19,7 +19,7 @@ package net.emustudio.application.gui.schema.elements; import com.electronwill.nightconfig.core.Config; -import net.emustudio.application.configuration.PluginConfig; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.P; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; diff --git a/application/src/main/java/net/emustudio/application/settings/ApplicationConfig.java b/application/src/main/java/net/emustudio/application/settings/ApplicationConfig.java new file mode 100644 index 000000000..6bfca1136 --- /dev/null +++ b/application/src/main/java/net/emustudio/application/settings/ApplicationConfig.java @@ -0,0 +1,89 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.application.settings; + +import com.electronwill.nightconfig.core.Config; +import com.electronwill.nightconfig.core.file.FileConfig; + +import java.nio.file.Path; +import java.util.Optional; + +import static net.emustudio.emulib.runtime.settings.PluginSettings.*; + + +@SuppressWarnings("unused") +public class ApplicationConfig extends BasicSettingsImpl { + public final static String KEY_NOGUI = EMUSTUDIO_NO_GUI.substring(EMUSTUDIO_PREFIX.length()); + public final static String KEY_AUTO = EMUSTUDIO_AUTO.substring(EMUSTUDIO_PREFIX.length()); + public final static String KEY_USE_SCHEMA_GRID = "useSchemaGrid"; + public final static String KEY_SCHEMA_GRID_GAP = "schemaGridGap"; + public final static String KEY_LOOK_AND_FEEL = "lookAndFeel"; + + private final static int DEFAULT_GRID_GAP = 20; + + public transient final boolean emuStudioAuto; + public transient final boolean noGUI; + + public ApplicationConfig(Config config, boolean nogui, boolean auto) { + super(config); + this.emuStudioAuto = auto; + this.noGUI = nogui; + } + + @Override + public boolean contains(String key) { + return KEY_NOGUI.equals(key) || KEY_AUTO.equals(key) || super.contains(key); + } + + public boolean useSchemaGrid() { + return getBoolean(KEY_USE_SCHEMA_GRID, true); + } + + public void setUseSchemaGrid(boolean useGrid) { + setBoolean(KEY_USE_SCHEMA_GRID, useGrid); + } + + public int getSchemaGridGap() { + return getInt(KEY_SCHEMA_GRID_GAP, DEFAULT_GRID_GAP); + } + + public void setSchemaGridGap(int value) { + setInt(KEY_SCHEMA_GRID_GAP, value); + } + + public Optional getLookAndFeel() { + return getString(KEY_LOOK_AND_FEEL); + } + + @Override + public Optional getBoolean(String key) { + if (KEY_AUTO.equals(key)) { + return Optional.of(emuStudioAuto); + } else if (KEY_NOGUI.equals(key)) { + return Optional.of(noGUI); + } + return super.getBoolean(key); + } + + public static ApplicationConfig fromFile(Path file, boolean nogui, boolean auto) { + FileConfig config = FileConfig.of(file); + config.load(); + return new ApplicationConfig(config, nogui, auto); + } +} diff --git a/application/src/main/java/net/emustudio/application/settings/BasicSettingsImpl.java b/application/src/main/java/net/emustudio/application/settings/BasicSettingsImpl.java new file mode 100644 index 000000000..53c9fbfc6 --- /dev/null +++ b/application/src/main/java/net/emustudio/application/settings/BasicSettingsImpl.java @@ -0,0 +1,130 @@ +package net.emustudio.application.settings; + +import com.electronwill.nightconfig.core.Config; +import net.emustudio.emulib.runtime.settings.BasicSettings; +import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +public class BasicSettingsImpl implements BasicSettings { + protected final Config config; + + public BasicSettingsImpl(Config config) { + this.config = Objects.requireNonNull(config); + } + + @Override + public boolean contains(String key) { + return config.contains(key); + } + + @Override + public void remove(String key) throws CannotUpdateSettingException { + config.remove(key); + } + + @Override + public Optional getString(String key) { + return config.getOptional(key); + } + + @Override + public String getString(String key, String defaultValue) { + return config.getOptional(key).orElse(defaultValue); + } + + @Override + public Optional getBoolean(String key) { + return config.getOptional(key); + } + + @Override + public boolean getBoolean(String key, boolean defaultValue) { + return config.getOptional(key).orElse(defaultValue); + } + + @Override + public Optional getInt(String key) { + return config.getOptional(key); + } + + @Override + public int getInt(String key, int defaultValue) { + return config.getOptionalInt(key).orElse(defaultValue); + } + + @Override + public Optional getLong(String key) { + return config.getOptional(key); + } + + @Override + public long getLong(String key, long defaultValue) { + return config.getOptionalLong(key).orElse(defaultValue); + } + + @Override + public Optional getDouble(String key) { + return config.getOptional(key); + } + + @Override + public double getDouble(String key, double defaultValue) { + return config.getOptional(key).orElse(defaultValue); + } + + @Override + public List getArray(String key) { + return config.>getOptional(key).orElse(Collections.emptyList()); + } + + @Override + public List getArray(String key, List defaultValue) { + return config.>getOptional(key).orElse(defaultValue); + } + + @Override + public void setString(String key, String value) { + config.set(key, value); + } + + @Override + public void setBoolean(String key, boolean value) throws CannotUpdateSettingException { + config.set(key, value); + } + + @Override + public void setInt(String key, int value) throws CannotUpdateSettingException { + config.set(key, value); + } + + @Override + public void setLong(String key, long value) throws CannotUpdateSettingException { + config.set(key, value); + } + + @Override + public void setDouble(String key, double value) throws CannotUpdateSettingException { + config.set(key, value); + } + + @Override + public void setArray(String key, List value) throws CannotUpdateSettingException { + config.set(key, value); + } + + @Override + public Optional getSubSettings(String key) { + return config.getOptional(key).map(BasicSettingsImpl::new); + } + + @Override + public BasicSettings setSubSettings(String key) throws CannotUpdateSettingException { + Config newConfig = config.createSubConfig(); + config.set(key, newConfig); + return new BasicSettingsImpl(newConfig); + } +} diff --git a/application/src/main/java/net/emustudio/application/configuration/ComputerConfig.java b/application/src/main/java/net/emustudio/application/settings/ComputerConfig.java similarity index 89% rename from application/src/main/java/net/emustudio/application/configuration/ComputerConfig.java rename to application/src/main/java/net/emustudio/application/settings/ComputerConfig.java index 161190311..038ba3b1e 100644 --- a/application/src/main/java/net/emustudio/application/configuration/ComputerConfig.java +++ b/application/src/main/java/net/emustudio/application/settings/ComputerConfig.java @@ -16,12 +16,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.application.settings; import com.electronwill.nightconfig.core.Config; import com.electronwill.nightconfig.core.file.FileConfig; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; -import net.emustudio.emulib.runtime.CannotUpdateSettingException; import java.io.Closeable; import java.io.IOException; @@ -34,7 +33,7 @@ import static java.util.stream.Collectors.toList; -public class ComputerConfig implements ConfigSaver, Closeable { +public class ComputerConfig implements Closeable { private final FileConfig config; public ComputerConfig(FileConfig config) { @@ -127,15 +126,6 @@ public void setConnections(List connections) { config.set("connections", configs); } - @Override - public void save() throws CannotUpdateSettingException { - try { - config.save(); - } catch (Exception e) { - throw new CannotUpdateSettingException("Could not save configuration", e); - } - } - @Override public void close() { config.close(); @@ -147,7 +137,7 @@ public String toString() { } public static ComputerConfig load(Path configurationFile) { - FileConfig config = FileConfig.of(configurationFile); + FileConfig config = FileConfig.builder(configurationFile).concurrent().autosave().build(); config.load(); return new ComputerConfig(config); @@ -158,9 +148,8 @@ public static ComputerConfig create(String computerName, Path configurationFile) throw new IllegalArgumentException("Configuration already exists"); } Files.createFile(configurationFile); - FileConfig config = FileConfig.of(configurationFile); + FileConfig config = FileConfig.builder(configurationFile).concurrent().autosave().build(); config.set("name", computerName); - config.save(); return new ComputerConfig(config); } diff --git a/application/src/main/java/net/emustudio/application/configuration/ConfigFiles.java b/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java similarity index 91% rename from application/src/main/java/net/emustudio/application/configuration/ConfigFiles.java rename to application/src/main/java/net/emustudio/application/settings/ConfigFiles.java index bde6a9039..6274629c6 100644 --- a/application/src/main/java/net/emustudio/application/configuration/ConfigFiles.java +++ b/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java @@ -16,10 +16,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.application.settings; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; -import net.emustudio.emulib.runtime.CannotUpdateSettingException; import net.jcip.annotations.NotThreadSafe; import java.io.IOException; @@ -110,13 +109,12 @@ public static void removeConfiguration(String computerName) throws IOException { Files.deleteIfExists(configPath); } - public static void renameConfiguration(ComputerConfig originalConfiguration, String newName) throws IOException, CannotUpdateSettingException { - ComputerConfig newConfig = createConfiguration(newName); - originalConfiguration.copyTo(newConfig); - newConfig.save(); - - originalConfiguration.close(); - removeConfiguration(originalConfiguration.getName()); + public static void renameConfiguration(ComputerConfig originalConfiguration, String newName) throws IOException { + try (ComputerConfig newConfig = createConfiguration(newName)) { + originalConfiguration.copyTo(newConfig); + originalConfiguration.close(); + removeConfiguration(originalConfiguration.getName()); + } } private static String encodeToFileName(String name) { diff --git a/application/src/main/java/net/emustudio/application/configuration/PluginConfig.java b/application/src/main/java/net/emustudio/application/settings/PluginConfig.java similarity index 93% rename from application/src/main/java/net/emustudio/application/configuration/PluginConfig.java rename to application/src/main/java/net/emustudio/application/settings/PluginConfig.java index c583b2e62..14b9c92db 100644 --- a/application/src/main/java/net/emustudio/application/configuration/PluginConfig.java +++ b/application/src/main/java/net/emustudio/application/settings/PluginConfig.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.application.settings; import com.electronwill.nightconfig.core.Config; import net.emustudio.application.gui.P; @@ -25,7 +25,7 @@ import java.nio.file.Path; import java.util.Objects; -import static net.emustudio.application.configuration.ConfigFiles.getAbsolutePluginPath; +import static net.emustudio.application.settings.ConfigFiles.getAbsolutePluginPath; public class PluginConfig { private final Config config; @@ -70,7 +70,7 @@ public void setSchemaPoint(SchemaPoint point) { public Config getPluginSettings() { if (!config.contains("settings")) { - config.set("settings", Config.inMemory()); + config.set("settings", config.createSubConfig()); } return config.get("settings"); } diff --git a/application/src/main/java/net/emustudio/application/configuration/PluginConnection.java b/application/src/main/java/net/emustudio/application/settings/PluginConnection.java similarity index 97% rename from application/src/main/java/net/emustudio/application/configuration/PluginConnection.java rename to application/src/main/java/net/emustudio/application/settings/PluginConnection.java index 0182494c1..4410ce0f4 100644 --- a/application/src/main/java/net/emustudio/application/configuration/PluginConnection.java +++ b/application/src/main/java/net/emustudio/application/settings/PluginConnection.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.application.settings; import com.electronwill.nightconfig.core.Config; diff --git a/application/src/main/java/net/emustudio/application/configuration/PluginSettingsImpl.java b/application/src/main/java/net/emustudio/application/settings/PluginSettingsImpl.java similarity index 62% rename from application/src/main/java/net/emustudio/application/configuration/PluginSettingsImpl.java rename to application/src/main/java/net/emustudio/application/settings/PluginSettingsImpl.java index c004f731f..87290677a 100644 --- a/application/src/main/java/net/emustudio/application/configuration/PluginSettingsImpl.java +++ b/application/src/main/java/net/emustudio/application/settings/PluginSettingsImpl.java @@ -16,47 +16,45 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.application.settings; import com.electronwill.nightconfig.core.Config; -import net.emustudio.emulib.runtime.CannotUpdateSettingException; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.BasicSettings; +import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; +import net.emustudio.emulib.runtime.settings.PluginSettings; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; -public class PluginSettingsImpl implements PluginSettings { +public class PluginSettingsImpl implements PluginSettings { private final Config config; - private final ConfigSaver saver; - private final ApplicationConfig applicationConfig; + private final ApplicationConfig application; - public PluginSettingsImpl(Config config, ConfigSaver saver, ApplicationConfig applicationConfig) { - this.config = Objects.requireNonNull(config); - this.saver = Objects.requireNonNull(saver); - this.applicationConfig = Objects.requireNonNull(applicationConfig); + public PluginSettingsImpl(Config pluginConfig, ApplicationConfig application) { + this.config = Objects.requireNonNull(pluginConfig); + this.application = Objects.requireNonNull(application); } @Override public boolean contains(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.contains(key.substring(EMUSTUDIO_PREFIX.length())); + return application.contains(key.substring(EMUSTUDIO_PREFIX.length())); } return config.contains(key); } @Override - public void remove(String key) throws CannotUpdateSettingException { + public void remove(String key) { checkDoesNotStartWithEmuStudioPrefix(key); config.remove(key); - saver.save(); } @Override public Optional getString(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getString(key.substring(EMUSTUDIO_PREFIX.length())); + return application.getString(key.substring(EMUSTUDIO_PREFIX.length())); } return config.getOptional(key); } @@ -64,7 +62,7 @@ public Optional getString(String key) { @Override public String getString(String key, String defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getString(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); + return application.getString(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); } return config.getOptional(key).orElse(defaultValue); } @@ -72,7 +70,7 @@ public String getString(String key, String defaultValue) { @Override public Optional getBoolean(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getBoolean(key.substring(EMUSTUDIO_PREFIX.length())); + return application.getBoolean(key.substring(EMUSTUDIO_PREFIX.length())); } return config.getOptional(key); } @@ -80,7 +78,7 @@ public Optional getBoolean(String key) { @Override public boolean getBoolean(String key, boolean defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getBoolean(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); + return application.getBoolean(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); } return config.getOptional(key).orElse(defaultValue); } @@ -88,7 +86,7 @@ public boolean getBoolean(String key, boolean defaultValue) { @Override public Optional getInt(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getInt(key.substring(EMUSTUDIO_PREFIX.length())); + return application.getInt(key.substring(EMUSTUDIO_PREFIX.length())); } return config.getOptional(key); } @@ -96,7 +94,7 @@ public Optional getInt(String key) { @Override public int getInt(String key, int defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getInt(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); + return application.getInt(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); } return config.getOptionalInt(key).orElse(defaultValue); } @@ -104,7 +102,7 @@ public int getInt(String key, int defaultValue) { @Override public Optional getLong(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getLong(key.substring(EMUSTUDIO_PREFIX.length())); + return application.getLong(key.substring(EMUSTUDIO_PREFIX.length())); } return config.getOptional(key); } @@ -112,7 +110,7 @@ public Optional getLong(String key) { @Override public long getLong(String key, long defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getLong(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); + return application.getLong(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); } return config.getOptionalLong(key).orElse(defaultValue); } @@ -120,7 +118,7 @@ public long getLong(String key, long defaultValue) { @Override public Optional getDouble(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getDouble(key.substring(EMUSTUDIO_PREFIX.length())); + return application.getDouble(key.substring(EMUSTUDIO_PREFIX.length())); } return config.getOptional(key); } @@ -128,7 +126,7 @@ public Optional getDouble(String key) { @Override public double getDouble(String key, double defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getDouble(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); + return application.getDouble(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); } return config.getOptional(key).orElse(defaultValue); } @@ -136,7 +134,7 @@ public double getDouble(String key, double defaultValue) { @Override public List getArray(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getArray(key.substring(EMUSTUDIO_PREFIX.length())); + return application.getArray(key.substring(EMUSTUDIO_PREFIX.length())); } return config.>getOptional(key).orElse(Collections.emptyList()); } @@ -144,51 +142,57 @@ public List getArray(String key) { @Override public List getArray(String key, List defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { - return applicationConfig.getArray(key.substring(EMUSTUDIO_PREFIX.length())); + return application.getArray(key.substring(EMUSTUDIO_PREFIX.length())); } return config.>getOptional(key).orElse(defaultValue); } @Override - public void setString(String key, String value) throws CannotUpdateSettingException { + public void setString(String key, String value) { checkDoesNotStartWithEmuStudioPrefix(key); config.set(key, value); - saver.save(); } @Override - public void setBoolean(String key, boolean value) throws CannotUpdateSettingException { + public void setBoolean(String key, boolean value) { checkDoesNotStartWithEmuStudioPrefix(key); config.set(key, value); - saver.save(); } @Override - public void setInt(String key, int value) throws CannotUpdateSettingException { + public void setInt(String key, int value) { checkDoesNotStartWithEmuStudioPrefix(key); config.set(key, value); - saver.save(); } @Override - public void setLong(String key, long value) throws CannotUpdateSettingException { + public void setLong(String key, long value) { checkDoesNotStartWithEmuStudioPrefix(key); config.set(key, value); - saver.save(); } @Override - public void setDouble(String key, double value) throws CannotUpdateSettingException { + public void setDouble(String key, double value) { checkDoesNotStartWithEmuStudioPrefix(key); config.set(key, value); - saver.save(); } @Override - public void setArray(String key, List value) throws CannotUpdateSettingException { + public void setArray(String key, List value) { checkDoesNotStartWithEmuStudioPrefix(key); config.set(key, value); - saver.save(); + } + + @Override + public Optional getSubSettings(String key) { + return config.getOptional(key).map(BasicSettingsImpl::new); + } + + @Override + public BasicSettings setSubSettings(String key) throws CannotUpdateSettingException { + Config newConfig = config.createSubConfig(); + config.set(key, newConfig); + return new BasicSettingsImpl(newConfig); } private void checkDoesNotStartWithEmuStudioPrefix(String key) { diff --git a/application/src/main/java/net/emustudio/application/configuration/SchemaPoint.java b/application/src/main/java/net/emustudio/application/settings/SchemaPoint.java similarity index 97% rename from application/src/main/java/net/emustudio/application/configuration/SchemaPoint.java rename to application/src/main/java/net/emustudio/application/settings/SchemaPoint.java index 937b6e356..c794b5778 100644 --- a/application/src/main/java/net/emustudio/application/configuration/SchemaPoint.java +++ b/application/src/main/java/net/emustudio/application/settings/SchemaPoint.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.application.settings; import net.jcip.annotations.Immutable; diff --git a/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java b/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java index a674084b0..6f16ac9ce 100644 --- a/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java +++ b/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.virtualcomputer; -import net.emustudio.application.configuration.*; +import net.emustudio.application.settings.*; import net.emustudio.application.internal.Unchecked; import net.emustudio.emulib.plugins.Plugin; import net.emustudio.emulib.plugins.PluginInitializationException; @@ -28,7 +28,7 @@ import net.emustudio.emulib.plugins.device.Device; import net.emustudio.emulib.plugins.memory.Memory; import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +38,6 @@ import java.util.*; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; -import java.util.stream.IntStream; import java.util.stream.Stream; import static net.emustudio.application.internal.Reflection.doesImplement; @@ -52,6 +51,11 @@ public class VirtualComputer implements PluginConnections, AutoCloseable { PLUGIN_TYPE.MEMORY, Memory.class, PLUGIN_TYPE.DEVICE, Device.class ); + // The first parameter of constructor is plug-in ID + private static final Class[] PLUGIN_CONSTRUCTOR_PARAMS = { + long.class, ApplicationApi.class, PluginSettings.class + }; + private final ComputerConfig computerConfig; @@ -161,10 +165,10 @@ private static Map loadPlugins(ComputerConfig computerConfig, PluginLoader pluginLoader = new PluginLoader(); List> pluginClasses = pluginLoader.loadPlugins(filesToLoad); - return constructPlugins(computerConfig, pluginClasses, pluginConfigs, applicationApi, applicationConfig); + return constructPlugins(pluginClasses, pluginConfigs, applicationApi, applicationConfig); } - private static Map constructPlugins(ComputerConfig computerConfig, List> pluginClasses, + private static Map constructPlugins(List> pluginClasses, List pluginConfigs, ApplicationApi applicationApi, ApplicationConfig applicationConfig) throws InvalidPluginException { @@ -172,29 +176,27 @@ private static Map constructPlugins(ComputerConfig computerCon Map plugins = new HashMap<>(); AtomicLong pluginIdCounter = new AtomicLong(); - IntStream - .range(0, Math.min(pluginClasses.size(), pluginConfigs.size())) - .forEach(i -> { - Class pluginClass = pluginClasses.get(i); - PluginConfig pluginConfig = pluginConfigs.get(i); - PluginSettings pluginSettings = new PluginSettingsImpl( - pluginConfig.getPluginSettings(), computerConfig, applicationConfig - ); - - if (!doesImplement(pluginClass, pluginInterfaces.get(pluginConfig.getPluginType()))) { - Unchecked.sneakyThrow(new InvalidPluginException( - "Plugin" + pluginConfig.getPluginName() + " does not implement interface " + pluginClass.getName() - )); - } + for (int i = 0; i < Math.min(pluginClasses.size(), pluginConfigs.size()); i++) { + Class pluginClass = pluginClasses.get(i); + PluginConfig pluginConfig = pluginConfigs.get(i); + PluginSettings pluginSettings = new PluginSettingsImpl( + pluginConfig.getPluginSettings(), applicationConfig + ); - long pluginId = pluginIdCounter.getAndIncrement(); - Plugin pluginInstance = Unchecked.call( - () -> createPluginInstance(pluginId, pluginClass, applicationApi, pluginSettings) + if (!doesImplement(pluginClass, pluginInterfaces.get(pluginConfig.getPluginType()))) { + throw new InvalidPluginException( + "Plugin" + pluginConfig.getPluginName() + " does not implement interface " + pluginClass.getName() ); + } - PluginMeta pluginMeta = new PluginMeta(pluginSettings, pluginInstance, pluginConfig); - plugins.put(pluginId, pluginMeta); - }); + long pluginId = pluginIdCounter.getAndIncrement(); + Plugin pluginInstance = Unchecked.call( + () -> createPluginInstance(pluginId, pluginClass, applicationApi, pluginSettings) + ); + + PluginMeta pluginMeta = new PluginMeta(pluginSettings, pluginInstance, pluginConfig); + plugins.put(pluginId, pluginMeta); + } return plugins; } @@ -204,18 +206,10 @@ private static Plugin createPluginInstance(long pluginID, Class[] constructorParams = {long.class, ApplicationApi.class, PluginSettings.class}; try { - Constructor constructor = mainClass.getDeclaredConstructor(constructorParams); - if (constructor != null) { - return (Plugin) constructor.newInstance(pluginID, applicationApi, pluginSettings); - } else { - throw new InvalidPluginException("Could not find constructor with parameters: " + Arrays.deepToString(constructorParams)); - } - } catch (InvalidPluginException e) { - throw e; + Constructor constructor = mainClass.getDeclaredConstructor(PLUGIN_CONSTRUCTOR_PARAMS); + return (Plugin) constructor.newInstance(pluginID, applicationApi, pluginSettings); } catch (Exception | NoClassDefFoundError e) { throw new InvalidPluginException("Plug-in main class does not have proper constructor", e); } diff --git a/application/src/test/java/net/emustudio/application/emulation/EmulationControllerTest.java b/application/src/test/java/net/emustudio/application/emulation/EmulationControllerTest.java index 00ce71d81..556469a42 100644 --- a/application/src/test/java/net/emustudio/application/emulation/EmulationControllerTest.java +++ b/application/src/test/java/net/emustudio/application/emulation/EmulationControllerTest.java @@ -25,7 +25,7 @@ import net.emustudio.emulib.plugins.device.Device; import net.emustudio.emulib.plugins.memory.Memory; import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.Before; import org.junit.Test; diff --git a/application/src/test/java/net/emustudio/application/configuration/ApplicationConfigTest.java b/application/src/test/java/net/emustudio/application/settings/ApplicationConfigTest.java similarity index 97% rename from application/src/test/java/net/emustudio/application/configuration/ApplicationConfigTest.java rename to application/src/test/java/net/emustudio/application/settings/ApplicationConfigTest.java index b3375f21b..78da08654 100644 --- a/application/src/test/java/net/emustudio/application/configuration/ApplicationConfigTest.java +++ b/application/src/test/java/net/emustudio/application/settings/ApplicationConfigTest.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.application.settings; import com.electronwill.nightconfig.core.file.FileConfig; import org.junit.Rule; diff --git a/application/src/test/java/net/emustudio/application/configuration/ComputerConfigTest.java b/application/src/test/java/net/emustudio/application/settings/ComputerConfigTest.java similarity index 98% rename from application/src/test/java/net/emustudio/application/configuration/ComputerConfigTest.java rename to application/src/test/java/net/emustudio/application/settings/ComputerConfigTest.java index bad86ad56..c76097ce5 100644 --- a/application/src/test/java/net/emustudio/application/configuration/ComputerConfigTest.java +++ b/application/src/test/java/net/emustudio/application/settings/ComputerConfigTest.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.application.settings; import com.electronwill.nightconfig.core.Config; import net.emustudio.application.gui.P; diff --git a/application/src/test/java/net/emustudio/application/configuration/ConfigFilesTest.java b/application/src/test/java/net/emustudio/application/settings/ConfigFilesTest.java similarity index 90% rename from application/src/test/java/net/emustudio/application/configuration/ConfigFilesTest.java rename to application/src/test/java/net/emustudio/application/settings/ConfigFilesTest.java index bce97d3dc..85a2a8b4e 100644 --- a/application/src/test/java/net/emustudio/application/configuration/ConfigFilesTest.java +++ b/application/src/test/java/net/emustudio/application/settings/ConfigFilesTest.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.application.settings; import org.junit.Test; @@ -26,7 +26,7 @@ import java.nio.file.Path; import java.util.Objects; -import static net.emustudio.application.configuration.ConfigFiles.loadConfigurations; +import static net.emustudio.application.settings.ConfigFiles.loadConfigurations; import static org.junit.Assert.assertTrue; public class ConfigFilesTest { diff --git a/application/src/test/java/net/emustudio/application/configuration/PluginConfigTest.java b/application/src/test/java/net/emustudio/application/settings/PluginConfigTest.java similarity index 97% rename from application/src/test/java/net/emustudio/application/configuration/PluginConfigTest.java rename to application/src/test/java/net/emustudio/application/settings/PluginConfigTest.java index bc49793df..f558e5fb1 100644 --- a/application/src/test/java/net/emustudio/application/configuration/PluginConfigTest.java +++ b/application/src/test/java/net/emustudio/application/settings/PluginConfigTest.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.application.settings; import com.electronwill.nightconfig.core.Config; import net.emustudio.application.gui.P; diff --git a/application/src/test/java/net/emustudio/application/configuration/SchemaPointTest.java b/application/src/test/java/net/emustudio/application/settings/SchemaPointTest.java similarity index 97% rename from application/src/test/java/net/emustudio/application/configuration/SchemaPointTest.java rename to application/src/test/java/net/emustudio/application/settings/SchemaPointTest.java index 0814ac077..6757b033d 100644 --- a/application/src/test/java/net/emustudio/application/configuration/SchemaPointTest.java +++ b/application/src/test/java/net/emustudio/application/settings/SchemaPointTest.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.application.settings; import org.junit.Test; diff --git a/application/src/test/java/net/emustudio/application/virtualcomputer/PluginLoaderTest.java b/application/src/test/java/net/emustudio/application/virtualcomputer/PluginLoaderTest.java index e421b8ec8..5dae587f0 100644 --- a/application/src/test/java/net/emustudio/application/virtualcomputer/PluginLoaderTest.java +++ b/application/src/test/java/net/emustudio/application/virtualcomputer/PluginLoaderTest.java @@ -25,7 +25,7 @@ import net.emustudio.emulib.plugins.cpu.CPU; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.Before; import org.junit.Rule; import org.junit.Test; diff --git a/application/src/test/java/net/emustudio/application/virtualcomputer/VirtualComputerTest.java b/application/src/test/java/net/emustudio/application/virtualcomputer/VirtualComputerTest.java index d4f804af8..f75566dfe 100644 --- a/application/src/test/java/net/emustudio/application/virtualcomputer/VirtualComputerTest.java +++ b/application/src/test/java/net/emustudio/application/virtualcomputer/VirtualComputerTest.java @@ -18,8 +18,8 @@ */ package net.emustudio.application.virtualcomputer; -import net.emustudio.application.configuration.ComputerConfig; -import net.emustudio.application.configuration.PluginConfig; +import net.emustudio.application.settings.ComputerConfig; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.virtualcomputer.VirtualComputer.PluginMeta; import net.emustudio.emulib.plugins.Plugin; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; @@ -27,7 +27,7 @@ import net.emustudio.emulib.plugins.cpu.CPU; import net.emustudio.emulib.plugins.device.Device; import net.emustudio.emulib.plugins.memory.Memory; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.Test; import java.util.HashMap; diff --git a/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/CPUImplStub.java b/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/CPUImplStub.java index 8e27b3588..070df0772 100644 --- a/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/CPUImplStub.java +++ b/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/CPUImplStub.java @@ -23,7 +23,7 @@ import net.emustudio.emulib.plugins.annotations.PluginRoot; import net.emustudio.emulib.plugins.cpu.Disassembler; import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import javax.swing.*; diff --git a/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/UnannotatedCPUStub.java b/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/UnannotatedCPUStub.java index 71a759be9..8793f22ea 100644 --- a/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/UnannotatedCPUStub.java +++ b/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/UnannotatedCPUStub.java @@ -21,7 +21,7 @@ import net.emustudio.emulib.plugins.cpu.CPU; import net.emustudio.emulib.plugins.cpu.Disassembler; import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import javax.swing.*; diff --git a/application/src/test/resources/dependencies/APluginDependsOnB.class b/application/src/test/resources/dependencies/APluginDependsOnB.class index f9e7bcd09768c6c725af5cdfcf2462c181d4d2d6..082925e3de4dd935d01ccd4bcfa5714ba5bba90c 100644 GIT binary patch delta 310 zcmXYr%}T>i5QWdZiM>sze??MLHMO?ZB(+KLhc0yEri4XwKBD}?(N z#f`WV@d11Z-@}DC#VqE`H|Gq)e3;*+|MmO+37~_v2?1BYGr{2+$ibgeQ(#}9B@m?k zp*C=PYL#2*_&6`)B)NSU$aHpf6f%hGSSF+46GK7X3@808WhlAlchNX{4CRE@!(Mk3 z-Nz^1#hb(W+*pH-B9>vPXRWnh(+g$wqBV>P82KyUs-Qcpu70$3;E`vcM7l^H+fpd1D=@T*=8mm`k%$E_umn31 zM;M*&JaY2CjH?me-`8=s;HnQk7}Y>^rRu5>QHyUVA4jBDR-GK9iC|c&FV7ZzKBT{T^_h6GIA3w`5@28 k?Y|df`|l;$`MH-

+ * A SIO unit allocates one or two CPU ports (status, data). + * A device is connected with SIO unit using special port. + */ +public class SioUnit implements AutoCloseable { + private final SioUnitSettings settings; + private final UART uart; + private final ControlChannel controlChannel = new ControlChannel(); + private final DataChannel dataChannel = new DataChannel(); + private final Context8080 cpu; + + private final List attachedStatusPorts = new ArrayList<>(); + private final List attachedDataPorts = new ArrayList<>(); + + public SioUnit(SioUnitSettings settings, Context8080 cpu) { + this.settings = Objects.requireNonNull(settings); + this.cpu = Objects.requireNonNull(cpu); + this.uart = new UART(cpu); + } + + void reset(boolean guiSupported) { + uart.reset(guiSupported); + } + + public UART getUART() { + return uart; + } + + public void attach() { + detach(); + attachedDataPorts.clear(); + attachedStatusPorts.clear(); + + attachedStatusPorts.addAll(settings.getStatusPorts()); + attachedDataPorts.addAll(settings.getDataPorts()); + + attachedStatusPorts.forEach(p -> cpu.attachDevice(controlChannel, p)); + attachedDataPorts.forEach(p -> cpu.attachDevice(dataChannel, p)); + } + + public void detach() { + attachedStatusPorts.forEach(cpu::detachDevice); + attachedDataPorts.forEach(cpu::detachDevice); + } + + @Override + public void close() { + detach(); + } + + class ControlChannel implements DeviceContext { + + @Override + public Byte readData() { + return uart.readStatus(); + } + + @Override + public void writeData(Byte data) { + uart.setStatus(data); + } + + @Override + public Class getDataType() { + return Byte.class; + } + } + + class DataChannel implements DeviceContext { + + @Override + public Byte readData() { + return uart.readBuffer(); + } + + @Override + public void writeData(Byte data) { + uart.sendToDevice(data); + } + + @Override + public Class getDataType() { + return Byte.class; + } + } +} diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/Transmitter.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java similarity index 56% rename from plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/Transmitter.java rename to plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java index 3fcec0873..21dc73723 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/Transmitter.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java @@ -20,19 +20,23 @@ import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.device.DeviceContext; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.jcip.annotations.ThreadSafe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** + * Universal Asynchronous Receiver Transmitter (UART) + * + *

* Status port IN: *

* 7 - 0 - device ready; 1 - not ready @@ -45,25 +49,36 @@ * 0 - 1 - data from input device is ready to be read */ @ThreadSafe -public class Transmitter { - private final static Logger LOGGER = LoggerFactory.getLogger(Transmitter.class); +public class UART { + private final static Logger LOGGER = LoggerFactory.getLogger(UART.class); + private final static int SEND_DATA_READY = 2; + private final static int RECEIVE_DATA_READY = 1; - private final Queue buffer = new ConcurrentLinkedQueue<>(); + private final Queue bufferFromDevice = new ConcurrentLinkedQueue<>(); private final Lock bufferAndStatusLock = new ReentrantLock(); private volatile DeviceContext device; - private volatile byte status = 0x2; + private byte statusRegister = SEND_DATA_READY; private volatile boolean inputInterruptEnabled; private volatile boolean outputInterruptEnabled; + private final Context8080 cpu; private final List observers = new ArrayList<>(); - void setDevice(DeviceContext device) { + public UART(Context8080 cpu) { + this.cpu = Objects.requireNonNull(cpu); + } + + public void setDevice(DeviceContext device) { this.device = device; - LOGGER.info("[device={}] Device was attached to 88-SIO", getDeviceId()); + if (device == null) { + LOGGER.info("[88-SIO] Device disconnected"); + } else { + LOGGER.info("[88-SIO, device={}] Device was attached", getDeviceId()); + } } - String getDeviceId() { + public String getDeviceId() { DeviceContext tmpDevice = device; if (tmpDevice == null) { return "unknown"; @@ -72,56 +87,67 @@ String getDeviceId() { return (pluginContext != null) ? pluginContext.id() : tmpDevice.toString(); } - void reset(boolean noGUI) { - if (!noGUI) { - buffer.clear(); - writeToStatus((short) 0); // disable interrupts + void reset(boolean guiSupported) { + if (guiSupported) { + bufferFromDevice.clear(); } + setStatus((byte) 0); // disable interrupts } - public void writeToStatus(short value) { - int newStatus = status; - + public void setStatus(byte value) { bufferAndStatusLock.lock(); + int newStatus = statusRegister; + boolean isEmpty = true; try { inputInterruptEnabled = (value & 1) == 1; outputInterruptEnabled = (value & 2) == 2; - if (buffer.isEmpty()) { - this.status = 2; + isEmpty = bufferFromDevice.isEmpty(); + if (isEmpty) { + this.statusRegister = SEND_DATA_READY; } else { - this.status = 3; + this.statusRegister = SEND_DATA_READY | RECEIVE_DATA_READY; } - newStatus = this.status; + newStatus = this.statusRegister; } finally { bufferAndStatusLock.unlock(); + if (!isEmpty && inputInterruptEnabled && cpu.isInterruptSupported()) { + cpu.signalInterrupt(new byte[] { (byte)0xFF }); // RST 7 (in Z80 RST 0x38) + } + if (outputInterruptEnabled && cpu.isInterruptSupported()) { + cpu.signalInterrupt(new byte[] { (byte)0xFF }); // RST 7 (in Z80 RST 0x38) + } + notifyStatusChanged(newStatus); } } - public void writeFromDevice(byte data) { + public void receiveFromDevice(byte data) { boolean wasEmpty = false; - int newStatus = status; + int newStatus = statusRegister; bufferAndStatusLock.lock(); try { - if (buffer.isEmpty()) { + if (bufferFromDevice.isEmpty()) { wasEmpty = true; } - buffer.add(data); - status = (byte) (status | 1); - newStatus = status; + bufferFromDevice.add(data); + statusRegister = (byte) (statusRegister | 1); + newStatus = statusRegister; } finally { bufferAndStatusLock.unlock(); if (wasEmpty) { + if (inputInterruptEnabled && cpu.isInterruptSupported()) { + cpu.signalInterrupt(new byte[] { (byte)0xFF }); // RST 7 (in Z80 RST 0x38) + } notifyNewData(data); } notifyStatusChanged(newStatus); } } - public void writeToDevice(byte data) { + public void sendToDevice(byte data) { DeviceContext tmpDevice = device; if (tmpDevice != null) { tmpDevice.writeData(data); @@ -131,18 +157,18 @@ public void writeToDevice(byte data) { public byte readBuffer() { int newData = 0; boolean isNotEmpty = false; - int newStatus = status; // what to do.. + int newStatus = statusRegister; // what to do.. bufferAndStatusLock.lock(); try { - Byte result = buffer.poll(); + Byte result = bufferFromDevice.poll(); - isNotEmpty = !buffer.isEmpty(); - status = (byte) (isNotEmpty ? (status | 1) : (status & 0xFE)); - newStatus = status; + isNotEmpty = !bufferFromDevice.isEmpty(); + statusRegister = (byte) (isNotEmpty ? (statusRegister | RECEIVE_DATA_READY) : (statusRegister & 0xFE)); + newStatus = statusRegister; if (isNotEmpty) { - newData = buffer.peek(); + newData = bufferFromDevice.peek(); } return result == null ? 0 : result; @@ -159,7 +185,7 @@ public byte readBuffer() { } public byte readStatus() { - return status; + return statusRegister; } @@ -186,4 +212,29 @@ public interface Observer { void noData(); } + + public static class DeviceChannel implements DeviceContext { + private UART uart; + + public void setUART(UART uart) { + this.uart = uart; + } + + @Override + public Byte readData() { + return 0; // Attached device cannot read back what it already wrote + } + + @Override + public void writeData(Byte data) { + if (uart != null) { + uart.receiveFromDevice(data); + } + } + + @Override + public Class getDataType() { + return Byte.class; + } + } } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/CPUPortsTableModel.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/CPUPortsTableModel.java deleted file mode 100644 index f27d24a6b..000000000 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/CPUPortsTableModel.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio.gui; - -import net.emustudio.plugins.device.mits88sio.ports.CpuPorts; - -import javax.swing.table.AbstractTableModel; -import java.util.Objects; - -public class CPUPortsTableModel extends AbstractTableModel { - private final CpuPorts cpuPorts; - - public CPUPortsTableModel(CpuPorts cpuPorts) { - this.cpuPorts = Objects.requireNonNull(cpuPorts); - } - - @Override - public int getRowCount() { - return cpuPorts.getDataPortsCount() + cpuPorts.getStatusPortsCount(); - } - - @Override - public int getColumnCount() { - return 2; - } - - @Override - public String getColumnName(int column) { - return column == 0 ? "Type" : "Attached to"; - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - int statusCount = cpuPorts.getStatusPortsCount(); - - if (rowIndex < statusCount) { - return columnIndex == 0 ? "Status" : String.format("0x%x", cpuPorts.getStatusPort(rowIndex)); - } - return columnIndex == 0 ? "Data" : String.format("0x%x", cpuPorts.getDataPort(rowIndex - statusCount)); - } - -} diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/PortListModel.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/PortListModel.java index 990302d1e..7c95071fd 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/PortListModel.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/PortListModel.java @@ -42,13 +42,13 @@ public void addAll(Collection ports) { fireContentsChanged(this, 0, this.ports.size() - 1); } - public Collection getAll() { - return Collections.unmodifiableCollection(ports); + public List getAll() { + return Collections.unmodifiableList(ports); } public void clear() { ports.clear(); - fireContentsChanged(this, 0, ports.size() - 1); + fireContentsChanged(this, 0, - 1); } public void removeAt(int index) { diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java index 1edaf8e58..56a6d1443 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java @@ -18,28 +18,29 @@ */ package net.emustudio.plugins.device.mits88sio.gui; -import net.emustudio.emulib.runtime.CannotUpdateSettingException; +import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.plugins.device.mits88sio.SIOSettings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; import javax.swing.*; +import javax.swing.GroupLayout.Alignment; +import java.awt.*; import java.awt.event.KeyEvent; import java.util.Objects; +import static javax.swing.GroupLayout.DEFAULT_SIZE; +import static javax.swing.GroupLayout.PREFERRED_SIZE; import static net.emustudio.plugins.device.mits88sio.gui.Constants.MONOSPACED_PLAIN; -public class SettingsDialog extends javax.swing.JDialog { - private final static Logger LOGGER = LoggerFactory.getLogger(SettingsDialog.class); - +public class SettingsDialog extends JDialog { private final Dialogs dialogs; - private final SIOSettings settings; + private final SioUnitSettings settings; private final PortListModel statusPortsModel = new PortListModel(); private final PortListModel dataPortsModel = new PortListModel(); + private final RadixUtils radixUtils = RadixUtils.getInstance(); - public SettingsDialog(JFrame parent, SIOSettings settings, Dialogs dialogs) { + public SettingsDialog(JFrame parent, SioUnitSettings settings, Dialogs dialogs) { super(parent, true); this.settings = Objects.requireNonNull(settings); @@ -50,6 +51,17 @@ public SettingsDialog(JFrame parent, SIOSettings settings, Dialogs dialogs) { statusPortsModel.addAll(settings.getStatusPorts()); dataPortsModel.addAll(settings.getDataPorts()); + reload(); + } + + private void reload() { + chkClearInputBit8.setSelected(settings.isClearInputBit8()); + chkClearOutputBit8.setSelected(settings.isClearOutputBit8()); + chkInputToUpperCase.setSelected(settings.isInputToUpperCase()); + cmbMapBackspaceChar.setSelectedIndex(settings.getMapBackspaceChar().ordinal()); + cmbMapDeleteChar.setSelectedIndex(settings.getMapDeleteChar().ordinal()); + txtInputInterruptVector.setText(String.valueOf(settings.getInputInterruptVector())); + txtOutputInterruptVector.setText(String.valueOf(settings.getOutputInterruptVector())); } private void setDefaultStatusPorts() { @@ -64,64 +76,71 @@ private void setDefaultDataPorts() { private void initComponents() { - JPanel jPanel1 = new JPanel(); - JScrollPane jScrollPane1 = new JScrollPane(); + JPanel panelStatusPorts = new JPanel(); + JScrollPane scrollStatusPorts = new JScrollPane(); JButton btnStatusAdd = new JButton(); JButton btnStatusRemove = new JButton(); JButton btnStatusDefault = new JButton(); - JPanel jPanel2 = new JPanel(); - JScrollPane jScrollPane2 = new JScrollPane(); + + JPanel panelDataPorts = new JPanel(); + JScrollPane scrollDataPorts = new JScrollPane(); JButton btnDataAdd = new JButton(); JButton btnDataRemove = new JButton(); JButton btnDataDefault = new JButton(); - JLabel jLabel1 = new JLabel(); - JButton btnSave = new JButton(); + + JPanel panelGeneral = new JPanel(); + JLabel lblMapDeleteChar = new JLabel("Map DEL char to:"); + JLabel lblMapBackspaceChar = new JLabel("Map BS char to:"); + JLabel lblInputInterruptVector = new JLabel("Input interrupt vector (0-7):"); + JLabel lblOutputInterruptVector = new JLabel("Output interrupt vector (0-7):"); + + JLabel lblCaution = new JLabel(); + JButton btnSave = new JButton("Save"); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); - setTitle("MITS SIO Settings"); - - jPanel1.setBorder(BorderFactory.createTitledBorder("Status port -> CPU")); + setTitle("MITS 88-SIO Settings"); + panelStatusPorts.setBorder(BorderFactory.createTitledBorder("Status port -> CPU")); lstStatusPorts.setFont(MONOSPACED_PLAIN); lstStatusPorts.setModel(statusPortsModel); lstStatusPorts.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - jScrollPane1.setViewportView(lstStatusPorts); + scrollStatusPorts.setViewportView(lstStatusPorts); btnStatusAdd.setText("+"); - btnStatusAdd.addActionListener(this::btnStatusAddActionPerformed); + btnStatusAdd.addActionListener(e -> addPort("status", "data", statusPortsModel, dataPortsModel)); btnStatusRemove.setText("-"); btnStatusRemove.setToolTipText(""); - btnStatusRemove.addActionListener(this::btnStatusRemoveActionPerformed); + btnStatusRemove.addActionListener(e -> removePort("status", lstStatusPorts, statusPortsModel)); - btnStatusDefault.setText("Default"); - btnStatusDefault.addActionListener(this::btnStatusDefaultActionPerformed); + btnStatusDefault.setText("Set default"); + btnStatusDefault.addActionListener(e -> setDefaultStatusPorts()); - GroupLayout jPanel1Layout = new GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() + GroupLayout layoutStatusPorts = new GroupLayout(panelStatusPorts); + panelStatusPorts.setLayout(layoutStatusPorts); + layoutStatusPorts.setHorizontalGroup( + layoutStatusPorts.createParallelGroup(Alignment.LEADING) + .addGroup(layoutStatusPorts.createSequentialGroup() .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 173, GroupLayout.PREFERRED_SIZE) + .addGroup(layoutStatusPorts.createParallelGroup(Alignment.LEADING) + .addGroup(layoutStatusPorts.createSequentialGroup() + .addComponent(scrollStatusPorts, PREFERRED_SIZE, 173, PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnStatusAdd, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnStatusRemove, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(layoutStatusPorts.createParallelGroup(Alignment.LEADING, false) + .addComponent(btnStatusAdd, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnStatusRemove, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))) .addComponent(btnStatusDefault)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() + layoutStatusPorts.setVerticalGroup( + layoutStatusPorts.createParallelGroup(Alignment.LEADING) + .addGroup(layoutStatusPorts.createSequentialGroup() .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 107, GroupLayout.PREFERRED_SIZE) - .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(layoutStatusPorts.createParallelGroup(Alignment.LEADING) + .addComponent(scrollStatusPorts, PREFERRED_SIZE, 107, PREFERRED_SIZE) + .addGroup(layoutStatusPorts.createSequentialGroup() .addComponent(btnStatusAdd) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnStatusRemove))) @@ -130,88 +149,145 @@ private void initComponents() { .addContainerGap(16, Short.MAX_VALUE)) ); - jPanel2.setBorder(BorderFactory.createTitledBorder("Data port -> CPU")); - + panelDataPorts.setBorder(BorderFactory.createTitledBorder("Data port -> CPU")); lstDataPorts.setFont(MONOSPACED_PLAIN); lstDataPorts.setModel(dataPortsModel); lstDataPorts.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - jScrollPane2.setViewportView(lstDataPorts); + scrollDataPorts.setViewportView(lstDataPorts); btnDataAdd.setText("+"); - btnDataAdd.addActionListener(this::btnDataAddActionPerformed); + btnDataAdd.addActionListener(e -> addPort("data", "status", dataPortsModel, statusPortsModel)); btnDataRemove.setText("-"); btnDataRemove.setToolTipText(""); - btnDataRemove.addActionListener(this::btnDataRemoveActionPerformed); + btnDataRemove.addActionListener(e -> removePort("data", lstDataPorts, dataPortsModel)); - btnDataDefault.setText("Default"); - btnDataDefault.addActionListener(this::btnDataDefaultActionPerformed); + btnDataDefault.setText("Set default"); + btnDataDefault.addActionListener(e -> setDefaultDataPorts()); - GroupLayout jPanel2Layout = new GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() + GroupLayout layoutDataPorts = new GroupLayout(panelDataPorts); + panelDataPorts.setLayout(layoutDataPorts); + layoutDataPorts.setHorizontalGroup( + layoutDataPorts.createParallelGroup(Alignment.LEADING) + .addGroup(layoutDataPorts.createSequentialGroup() .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 173, GroupLayout.PREFERRED_SIZE) + .addGroup(layoutDataPorts.createParallelGroup(Alignment.LEADING) + .addGroup(layoutDataPorts.createSequentialGroup() + .addComponent(scrollDataPorts, PREFERRED_SIZE, 173, PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnDataAdd, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnDataRemove, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(layoutDataPorts.createParallelGroup(Alignment.LEADING, false) + .addComponent(btnDataAdd, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnDataRemove, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))) .addComponent(btnDataDefault)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() + layoutDataPorts.setVerticalGroup( + layoutDataPorts.createParallelGroup(Alignment.LEADING) + .addGroup(layoutDataPorts.createSequentialGroup() .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 107, GroupLayout.PREFERRED_SIZE) - .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(layoutDataPorts.createParallelGroup(Alignment.LEADING) + .addComponent(scrollDataPorts, PREFERRED_SIZE, 107, PREFERRED_SIZE) + .addGroup(layoutDataPorts.createSequentialGroup() .addComponent(btnDataAdd) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnDataRemove))) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnDataDefault) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) ); - jLabel1.setText("It is possible to bind status port of this device to one or more CPU ports." + - " But please be aware of conflicting with other devices."); - jLabel1.setVerticalAlignment(SwingConstants.TOP); + panelGeneral.setBorder(BorderFactory.createTitledBorder("General settings")); + GroupLayout layoutGeneral = new GroupLayout(panelGeneral); + panelGeneral.setLayout(layoutGeneral); + cmbMapBackspaceChar.setEditable(false); + cmbMapDeleteChar.setEditable(false); - btnSave.setText("Save"); + layoutGeneral.setHorizontalGroup( + layoutGeneral.createParallelGroup(Alignment.LEADING) + .addGroup(layoutGeneral.createSequentialGroup() + .addContainerGap() + .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) + .addComponent(chkClearInputBit8) + .addComponent(chkClearOutputBit8) + .addComponent(chkInputToUpperCase) + .addGroup(layoutGeneral.createSequentialGroup() + .addComponent(lblMapDeleteChar) + .addComponent(cmbMapDeleteChar)) + .addGroup(layoutGeneral.createSequentialGroup() + .addComponent(lblMapBackspaceChar) + .addComponent(cmbMapBackspaceChar)) + .addGroup(layoutGeneral.createSequentialGroup() + .addComponent(lblInputInterruptVector) + .addComponent(txtInputInterruptVector)) + .addGroup(layoutGeneral.createSequentialGroup() + .addComponent(lblOutputInterruptVector) + .addComponent(txtOutputInterruptVector))))); + layoutGeneral.setVerticalGroup( + layoutDataPorts.createParallelGroup(Alignment.LEADING) + .addGroup(layoutGeneral.createSequentialGroup() + .addContainerGap() + .addComponent(chkClearInputBit8) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkClearOutputBit8) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkInputToUpperCase) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) + .addComponent(lblMapDeleteChar) + .addComponent(cmbMapDeleteChar)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) + .addComponent(lblMapBackspaceChar) + .addComponent(cmbMapBackspaceChar)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) + .addComponent(lblInputInterruptVector) + .addComponent(txtInputInterruptVector)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) + .addComponent(lblOutputInterruptVector) + .addComponent(txtOutputInterruptVector)))); + + + lblCaution.setText("Attach 88-SIO ports to one or more CPU ports." + + " Be aware of possible port conflicts with other devices."); + lblCaution.setVerticalAlignment(SwingConstants.TOP); + + btnSave.setFont(btnSave.getFont().deriveFont(Font.BOLD)); btnSave.addActionListener(this::btnSaveActionPerformed); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) + layout.createParallelGroup(Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(Alignment.LEADING) + .addComponent(lblCaution, PREFERRED_SIZE, 0, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() - .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(panelStatusPorts, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(panelDataPorts, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(layout.createSequentialGroup() - .addComponent(btnSave, GroupLayout.PREFERRED_SIZE, 83, GroupLayout.PREFERRED_SIZE))) + .addComponent(panelGeneral, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addComponent(btnSave, PREFERRED_SIZE, 83, PREFERRED_SIZE))) .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) + layout.createParallelGroup(Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, 49, GroupLayout.PREFERRED_SIZE) + .addComponent(lblCaution, PREFERRED_SIZE, 49, PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(Alignment.LEADING, false) + .addComponent(panelStatusPorts, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelDataPorts, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createParallelGroup(Alignment.LEADING, false) + .addComponent(panelGeneral, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(18, 18, 18) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(Alignment.TRAILING) .addComponent(btnSave)) .addContainerGap()) ); @@ -219,79 +295,75 @@ private void initComponents() { pack(); } - private void btnStatusAddActionPerformed(java.awt.event.ActionEvent evt) { - try { - dialogs - .readInteger("Enter port number:", "Add status port", 0) - .ifPresent(port -> { - if (dataPortsModel.contains(port)) { - dialogs.showError("Port number is already taken by data port", "Add status port"); - } else { - statusPortsModel.add(port); - } - - }); - } catch (NumberFormatException e) { - dialogs.showError("Invalid number format", "Add status port"); - } - } - private void btnDataAddActionPerformed(java.awt.event.ActionEvent evt) { + private void addPort(String nameAdd, String nameCheck, PortListModel portModelAdd, PortListModel portModelCheck) { try { dialogs - .readInteger("Enter port number:", "Add data port", 0) + .readInteger("Enter port number:", "Add " + nameAdd + " port", 0) .ifPresent(port -> { - if (statusPortsModel.contains(port)) { - dialogs.showError("Port number is already taken by status port"); + if (portModelCheck.contains(port)) { + dialogs.showError("Port number is already taken by " + nameCheck + " port"); } else { - dataPortsModel.add(port); + portModelAdd.add(port); } }); } catch (NumberFormatException e) { - dialogs.showError("Invalid number format", "Add data port"); + dialogs.showError("Invalid number format", "Add " + nameAdd + " port"); } } - private void btnStatusRemoveActionPerformed(java.awt.event.ActionEvent evt) { - int i = lstStatusPorts.getSelectedIndex(); + private void removePort(String name, JList lstPorts, PortListModel portModel) { + int i = lstPorts.getSelectedIndex(); if (i == -1) { - dialogs.showError("Status port must be selected", "Remove status port"); + dialogs.showError(name + " port must be selected", "Remove " + name + " port"); } else { - statusPortsModel.removeAt(i); + portModel.removeAt(i); } } - private void btnDataRemoveActionPerformed(java.awt.event.ActionEvent evt) { - int i = lstDataPorts.getSelectedIndex(); - if (i == -1) { - dialogs.showError("Data port must be selected", "Remove data port"); - } else { - dataPortsModel.removeAt(i); + private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) { + int inputInterruptVector; + int outputInterruptVector; + try { + inputInterruptVector = radixUtils.parseRadix(txtInputInterruptVector.getText().trim()); + } catch (NumberFormatException e) { + dialogs.showError("Could not parse input interrupt vector", "88-SIO Settings"); + return; + } + try { + outputInterruptVector = radixUtils.parseRadix(txtOutputInterruptVector.getText().trim()); + } catch (NumberFormatException e) { + dialogs.showError("Could not parse interrupt vector", "88-SIO Settings"); + return; } - } - - private void btnDataDefaultActionPerformed(java.awt.event.ActionEvent evt) { - setDefaultDataPorts(); - } - - private void btnStatusDefaultActionPerformed(java.awt.event.ActionEvent evt) { - setDefaultStatusPorts(); - } - private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) { settings.setStatusPorts(statusPortsModel.getAll()); settings.setDataPorts(dataPortsModel.getAll()); - try { - settings.write(); - } catch (CannotUpdateSettingException e) { - LOGGER.error("Could not write MITS 88-SIO settings", e); - dialogs.showError("Could not write MITS 88-SIO settings. Please see log file for details.", "Save settings"); - } + settings.setClearInputBit8(chkClearInputBit8.isSelected()); + settings.setClearOutputBit8(chkClearOutputBit8.isSelected()); + settings.setInputToUpperCase(chkInputToUpperCase.isSelected()); + + settings.setMapBackspaceChar(cmbMapBackspaceChar.getItemAt(cmbMapBackspaceChar.getSelectedIndex())); + settings.setMapDeleteChar(cmbMapDeleteChar.getItemAt(cmbMapDeleteChar.getSelectedIndex())); + + settings.setInputInterruptVector(inputInterruptVector); + settings.setOutputInterruptVector(outputInterruptVector); dispose(); } private final JList lstDataPorts = new JList<>(); private final JList lstStatusPorts = new JList<>(); + private final JCheckBox chkClearInputBit8 = new JCheckBox("TTY mode (clear bit 8 of input)"); + private final JCheckBox chkClearOutputBit8 = new JCheckBox("ANSI mode (clear bit 8 on output)"); + private final JCheckBox chkInputToUpperCase = new JCheckBox("Convert input to upper-case"); + private final JTextField txtInputInterruptVector = new JTextField(); + private final JTextField txtOutputInterruptVector = new JTextField(); + private final JComboBox cmbMapBackspaceChar = new JComboBox<>(new DefaultComboBoxModel<>( + SioUnitSettings.MAP_CHAR.values() + )); + private final JComboBox cmbMapDeleteChar = new JComboBox<>(new DefaultComboBoxModel<>( + SioUnitSettings.MAP_CHAR.values() + )); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java index a41c3f2fb..90bf516af 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java @@ -18,41 +18,38 @@ */ package net.emustudio.plugins.device.mits88sio.gui; -import net.emustudio.plugins.device.mits88sio.ports.CpuPorts; -import net.emustudio.plugins.device.mits88sio.Transmitter; +import net.emustudio.plugins.device.mits88sio.UART; import javax.swing.*; -import javax.swing.table.DefaultTableModel; import java.awt.event.KeyEvent; -import static net.emustudio.plugins.device.mits88sio.gui.Constants.MONOSPACED_PLAIN; - public class SioGui extends JDialog { - public SioGui(JFrame parent, String deviceName, Transmitter transmitter, CpuPorts cpuPorts) { + public SioGui(JFrame parent, UART uart) { super(parent); initComponents(); setLocationRelativeTo(parent); - tblCPUPorts.setModel(new CPUPortsTableModel(cpuPorts)); - txtStatus.setText(String.format("0x%x", transmitter.readStatus())); + txtStatus.setText(String.format("0x%x", uart.readStatus())); - lblAttachedDevice.setText(deviceName); - transmitter.addObserver(new Transmitter.Observer() { + lblAttachedDevice.setText(uart.getDeviceId()); + uart.addObserver(new UART.Observer() { @Override public void statusChanged(int status) { - txtStatus.setText(String.format("0x%x", status)); + txtStatus.setText(Integer.toBinaryString(status)); } @Override public void dataAvailable(int data) { - txtData.setText(String.format("0x%x", data)); + txtData.setText(String.format("0x%X", data)); + txtDataDisplay.setText(String.valueOf((byte)(data & 0xFF))); } @Override public void noData() { txtData.setText("N/A"); + txtDataDisplay.setText(""); } }); } @@ -62,24 +59,23 @@ private void initComponents() { JPanel jPanel1 = new JPanel(); lblAttachedDevice = new JLabel(); JPanel jPanel2 = new JPanel(); - JLabel jLabel1 = new JLabel(); - JLabel jLabel2 = new JLabel(); + JLabel lblStatus = new JLabel("Status:"); + JLabel lblData = new JLabel("Data:"); + JLabel lblDataDisplay = new JLabel("Data char:"); txtData = new JTextField(); + txtDataDisplay = new JTextField(); txtStatus = new JTextField(); - JPanel jPanel3 = new JPanel(); - JScrollPane jScrollPane1 = new JScrollPane(); - tblCPUPorts = new JTable(); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); - setTitle("MITS SIO Status"); + setTitle("MITS 88-SIO Status"); jPanel1.setBorder(BorderFactory.createTitledBorder("Attached device")); lblAttachedDevice.setFont(lblAttachedDevice.getFont().deriveFont(14.0f)); lblAttachedDevice.setHorizontalAlignment(SwingConstants.CENTER); - lblAttachedDevice.setText("N/A"); + lblAttachedDevice.setText("None"); GroupLayout jPanel1Layout = new GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); @@ -98,16 +94,13 @@ private void initComponents() { .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - jPanel2.setBorder(BorderFactory.createTitledBorder("SIO Ports (for reading)")); - - jLabel1.setText("Status:"); - jLabel2.setText("Data:"); + jPanel2.setBorder(BorderFactory.createTitledBorder("88-SIO Ports (for reading)")); + txtDataDisplay.setEditable(false); + txtStatus.setEditable(false); txtData.setEditable(false); txtData.setText("N/A"); - txtStatus.setEditable(false); - GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( @@ -115,12 +108,14 @@ private void initComponents() { .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel2) - .addComponent(jLabel1)) + .addComponent(lblStatus) + .addComponent(lblData) + .addComponent(lblDataDisplay)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(txtStatus) - .addComponent(txtData, GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE)) + .addComponent(txtData, GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE) + .addComponent(txtDataDisplay, GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel2Layout.setVerticalGroup( @@ -128,46 +123,16 @@ private void initComponents() { .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) + .addComponent(lblStatus) .addComponent(txtStatus, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2) + .addComponent(lblData) .addComponent(txtData, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - - jPanel3.setBorder(BorderFactory.createTitledBorder("Used CPU ports")); - - jScrollPane1.setBorder(null); - - tblCPUPorts.setModel(new DefaultTableModel( - new Object[][]{ - - }, - new String[]{ - - } - )); - tblCPUPorts.setRowSelectionAllowed(false); - tblCPUPorts.setShowHorizontalLines(false); - tblCPUPorts.setFont(MONOSPACED_PLAIN); - jScrollPane1.setViewportView(tblCPUPorts); - - GroupLayout jPanel3Layout = new GroupLayout(jPanel3); - jPanel3.setLayout(jPanel3Layout); - jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 262, Short.MAX_VALUE) - .addContainerGap()) - ); - jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 162, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblDataDisplay) + .addComponent(txtDataDisplay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -180,9 +145,7 @@ private void initComponents() { .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() - .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) .addContainerGap()) ); layout.setVerticalGroup( @@ -192,7 +155,6 @@ private void initComponents() { .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -201,7 +163,7 @@ private void initComponents() { } private JLabel lblAttachedDevice; - private JTable tblCPUPorts; private JTextField txtData; + private JTextField txtDataDisplay; private JTextField txtStatus; } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPort.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPort.java deleted file mode 100644 index ef8144771..000000000 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPort.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio.ports; - -import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.device.mits88sio.Transmitter; - -import java.io.IOException; -import java.util.Objects; - -/** - * This is the data port of 88-SIO card. - *

- * This port is attached to a CPU. - *

- * A read to the data port gets the buffered character, a write to the data port - * writes the character to the device. - */ -public class CpuDataPort implements DeviceContext { - private final Transmitter transmitter; - - public CpuDataPort(Transmitter transmitter) { - this.transmitter = Objects.requireNonNull(transmitter); - } - - @Override - public void writeData(Byte data) { - transmitter.writeToDevice(data); - } - - @Override - public Class getDataType() { - return Byte.class; - } - - @Override - public Byte readData() { - return transmitter.readBuffer(); - } - - @Override - public String toString() { - return "88-SIO Data Port"; - } -} diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuPorts.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuPorts.java deleted file mode 100644 index 9fffca19d..000000000 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuPorts.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio.ports; - -import net.emustudio.plugins.cpu.intel8080.api.Context8080; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -public class CpuPorts { - private final List statusPorts = new ArrayList<>(); - private final List dataPorts = new ArrayList<>(); - private final Context8080 cpu; - - public CpuPorts(Context8080 cpu) { - this.cpu = Objects.requireNonNull(cpu); - } - - public int getStatusPortsCount() { - return statusPorts.size(); - } - - public int getDataPortsCount() { - return dataPorts.size(); - } - - public int getStatusPort(int index) { - return statusPorts.get(index); - } - - public int getDataPort(int index) { - return dataPorts.get(index); - } - - public void reattachStatusPort(Collection intStatusPorts, CpuStatusPort cpuStatusPort) throws CouldNotAttachException { - statusPorts.forEach(cpu::detachDevice); - statusPorts.clear(); - statusPorts.addAll(intStatusPorts); - - List unattachedPorts = statusPorts.stream() - .filter(port -> !cpu.attachDevice(cpuStatusPort, port)) - .collect(Collectors.toList()); - - if (!unattachedPorts.isEmpty()) { - throw new CouldNotAttachException("Could not attach Status port to " + unattachedPorts); - } - } - - public void reattachDataPort(Collection intDataPorts, CpuDataPort cpuDataPort) throws CouldNotAttachException { - dataPorts.forEach(cpu::detachDevice); - dataPorts.clear(); - dataPorts.addAll(intDataPorts); - - List unattachedPorts = dataPorts.stream() - .filter(port -> !cpu.attachDevice(cpuDataPort, port)) - .collect(Collectors.toList()); - - if (!unattachedPorts.isEmpty()) { - throw new CouldNotAttachException("Could not attach Data port to " + unattachedPorts); - } - } - - public void destroy() { - statusPorts.forEach(cpu::detachDevice); - dataPorts.forEach(cpu::detachDevice); - } -} diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPort.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPort.java deleted file mode 100644 index 3b207cc24..000000000 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPort.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio.ports; - -import net.emustudio.emulib.plugins.annotations.PluginContext; -import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.device.mits88sio.Transmitter; - -import java.util.Objects; - -/** - * This is the status port of 88-SIO card. - */ -@PluginContext(id = "Status port") -public class CpuStatusPort implements DeviceContext { - private final Transmitter transmitter; - - public CpuStatusPort(Transmitter transmitter) { - this.transmitter = Objects.requireNonNull(transmitter); - } - - @Override - public Byte readData() { - return transmitter.readStatus(); - } - - @Override - public void writeData(Byte data) { - transmitter.writeToStatus(data); - } - - @Override - public Class getDataType() { - return Byte.class; - } - - @Override - public String toString() { - return "88-SIO Status Port"; - } -} diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPort.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPort.java deleted file mode 100644 index 429c0d1ca..000000000 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPort.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio.ports; - -import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.device.mits88sio.Transmitter; - -import java.util.Objects; - -/** - * This port is a physical port which is used to device-device connection. - *

- * For example, a terminal would use this port for communication. - */ -public class PhysicalPort implements DeviceContext { - private final Transmitter transmitter; - - public PhysicalPort(Transmitter transmitter) { - this.transmitter = Objects.requireNonNull(transmitter); - } - - @Override - public Byte readData() { - return 0; // Attached device cannot read back what it already wrote - } - - @Override - public void writeData(Byte data) { - transmitter.writeFromDevice(data); - } - - @Override - public Class getDataType() { - return Byte.class; - } - -} diff --git a/application/src/main/java/net/emustudio/application/configuration/ConfigSaver.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SettingsObserver.java similarity index 79% rename from application/src/main/java/net/emustudio/application/configuration/ConfigSaver.java rename to plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SettingsObserver.java index 1d9ea7979..4b3464680 100644 --- a/application/src/main/java/net/emustudio/application/configuration/ConfigSaver.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SettingsObserver.java @@ -16,11 +16,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.application.configuration; +package net.emustudio.plugins.device.mits88sio.settings; -import net.emustudio.emulib.runtime.CannotUpdateSettingException; +@FunctionalInterface +public interface SettingsObserver { -interface ConfigSaver { - - void save() throws CannotUpdateSettingException; + void settingsChanged(); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java new file mode 100644 index 000000000..9e1443478 --- /dev/null +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java @@ -0,0 +1,44 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.mits88sio.settings; + +import net.emustudio.emulib.runtime.settings.PluginSettings; +import net.jcip.annotations.ThreadSafe; + +@ThreadSafe +public class SioDeviceSettings { + private final boolean guiSupported; + private final SioUnitSettings sioUnit; + + public SioDeviceSettings(PluginSettings settings) { + this.guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); + this.sioUnit = settings + .getSubSettings("sio") + .map(SioUnitSettings::new) + .orElse(new SioUnitSettings(settings.setSubSettings("sio"))); + } + + public boolean isGuiSupported() { + return guiSupported; + } + + public SioUnitSettings getSioUnit() { + return sioUnit; + } +} diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java new file mode 100644 index 000000000..8d159145a --- /dev/null +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java @@ -0,0 +1,173 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.mits88sio.settings; + +import net.emustudio.emulib.runtime.settings.BasicSettings; +import net.jcip.annotations.ThreadSafe; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; + +/** + * Settings of one SIO unit + */ +@ThreadSafe +public class SioUnitSettings { + private final static String KEY_STATUS_PORTS = "statusPorts"; + private final static String KEY_DATA_PORTS = "dataPorts"; + private final static String KEY_CLEAR_INPUT_BIT8 = "clearInputBit8"; + private final static String KEY_CLEAR_OUTPUT_BIT8 = "clearOutputBit8"; + private final static String KEY_INPUT_TO_UPPER_CASE = "inputToUpperCase"; + private final static String KEY_MAP_DELETE_CHAR = "mapDeleteChar"; + private final static String KEY_MAP_BACKSPACE_CHAR = "mapBackspaceChar"; + private final static String KEY_INPUT_INTERRUPT_VECTOR = "inputInterruptVector"; + private final static String KEY_OUTPUT_INTERRUPT_VECTOR = "outputInterruptVector"; + + private final BasicSettings settings; + private final List observers = new CopyOnWriteArrayList<>(); + + public enum MAP_CHAR { + BACKSPACE, + DELETE, + UNDERSCORE, + UNCHANGED + } + + public SioUnitSettings(BasicSettings settings) { + this.settings = Objects.requireNonNull(settings); + } + + public void addObserver(SettingsObserver observer) { + observers.add(observer); + } + + public void clearObservers() { + observers.clear(); + } + + public boolean isClearInputBit8() { + return settings.getBoolean(KEY_CLEAR_INPUT_BIT8, false); + } + + public void setClearInputBit8(boolean value) { + settings.setBoolean(KEY_CLEAR_INPUT_BIT8, value); + notifySettingsChanged(); + } + + public boolean isClearOutputBit8() { + return settings.getBoolean(KEY_CLEAR_OUTPUT_BIT8, false); + } + + public void setClearOutputBit8(boolean value) { + settings.setBoolean(KEY_CLEAR_OUTPUT_BIT8, value); + notifySettingsChanged(); + } + + public boolean isInputToUpperCase() { + return settings.getBoolean(KEY_INPUT_TO_UPPER_CASE, false); + } + + public void setInputToUpperCase(boolean value) { + settings.setBoolean(KEY_INPUT_TO_UPPER_CASE, value); + notifySettingsChanged(); + } + + public MAP_CHAR getMapDeleteChar() { + return MAP_CHAR.valueOf(settings.getString(KEY_MAP_DELETE_CHAR, MAP_CHAR.UNCHANGED.name())); + } + + public void setMapDeleteChar(MAP_CHAR value) { + settings.setString(KEY_MAP_DELETE_CHAR, value.name()); + notifySettingsChanged(); + } + + public MAP_CHAR getMapBackspaceChar() { + return MAP_CHAR.valueOf(settings.getString(KEY_MAP_BACKSPACE_CHAR, MAP_CHAR.UNCHANGED.name())); + } + + public void setMapBackspaceChar(MAP_CHAR value) { + settings.setString(KEY_MAP_BACKSPACE_CHAR, value.name()); + notifySettingsChanged(); + } + + public List getStatusPorts() { + return Arrays.stream(settings.getString(KEY_STATUS_PORTS, "").split(",")) + .map(String::trim) + .filter(p -> !p.isEmpty()) + .map(Integer::decode) + .collect(Collectors.toList()); + } + + public void setStatusPorts(List value) { + settings.setString(KEY_STATUS_PORTS, value.stream() + .map(i -> "0x" + Integer.toHexString(i)) + .reduce((s, s2) -> s + ", " + s2) + .orElse("")); + notifySettingsChanged(); + } + + public List getDataPorts() { + return Arrays.stream(settings.getString(KEY_DATA_PORTS, "").split(",")) + .map(String::trim) + .filter(p -> !p.isEmpty()) + .map(Integer::decode) + .collect(Collectors.toList()); + } + + public void setDataPorts(List value) { + settings.setString(KEY_DATA_PORTS, value.stream() + .map(i -> "0x" + Integer.toHexString(i)) + .reduce((s, s2) -> s + "," + s2) + .orElse("")); + notifySettingsChanged(); + } + + public int getInputInterruptVector() { + return settings.getInt(KEY_INPUT_INTERRUPT_VECTOR, 0); + } + + public void setInputInterruptVector(int vector) { + settings.setInt(KEY_INPUT_INTERRUPT_VECTOR, vector); + notifySettingsChanged(); + } + + public int getOutputInterruptVector() { + return settings.getInt(KEY_OUTPUT_INTERRUPT_VECTOR, 0); + } + + public void setOutputInterruptVector(int vector) { + settings.setInt(KEY_OUTPUT_INTERRUPT_VECTOR, vector); + notifySettingsChanged(); + } + + public List getDefaultStatusPorts() { + return List.of(0x10, 0x14, 0x16, 0x18); + } + + public List getDefaultDataPorts() { + return List.of(0x11, 0x15, 0x17, 0x19); + } + + private void notifySettingsChanged() { + observers.forEach(SettingsObserver::settingsChanged); + } +} diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CouldNotAttachException.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceChannelTest.java similarity index 52% rename from plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CouldNotAttachException.java rename to plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceChannelTest.java index 3d6555eaf..0361e74a6 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ports/CouldNotAttachException.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceChannelTest.java @@ -16,11 +16,31 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +package net.emustudio.plugins.device.mits88sio; -package net.emustudio.plugins.device.mits88sio.ports; +import org.junit.Test; -public class CouldNotAttachException extends Exception { - public CouldNotAttachException(String message) { - super(message); +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertEquals; + +public class DeviceChannelTest { + + @Test + public void testReadReturnsZero() { + assertEquals(0, (byte) new UART.DeviceChannel().readData()); + } + + @Test + public void testWriteCallsReceiveFromDevice() { + UART uart = mock(UART.class); + uart.receiveFromDevice(eq((byte) 10)); + expectLastCall().once(); + replay(uart); + + UART.DeviceChannel channel = new UART.DeviceChannel(); + channel.setUART(uart); + channel.writeData((byte) 10); + + verify(uart); } } diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java index 211d4126a..f1e56d2f5 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java @@ -23,7 +23,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextNotFoundException; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.cpu.intel8080.api.Context8080; import org.junit.After; import org.junit.Before; diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SIOSettingsTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SIOSettingsTest.java deleted file mode 100644 index 03ad2ee3c..000000000 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SIOSettingsTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio; - -import net.emustudio.emulib.runtime.PluginSettings; -import org.junit.Test; - -import java.util.Collection; -import java.util.Collections; -import java.util.Optional; - -import static org.easymock.EasyMock.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class SIOSettingsTest { - - @Test - public void testObserverIsCalledOnRead() { - SIOSettings.ChangedObserver observer = createMock(SIOSettings.ChangedObserver.class); - observer.settingsChanged(); - expectLastCall().once(); - replay(observer); - - SIOSettings settings = new SIOSettings(PluginSettings.UNAVAILABLE); - settings.addChangedObserver(observer); - settings.read(); - - verify(observer); - } - - @Test - public void testObserverIsCalledOnSetStatusPort() { - SIOSettings.ChangedObserver observer = createMock(SIOSettings.ChangedObserver.class); - observer.settingsChanged(); - expectLastCall().once(); - replay(observer); - - SIOSettings settings = new SIOSettings(PluginSettings.UNAVAILABLE); - settings.addChangedObserver(observer); - settings.setStatusPorts(Collections.singletonList(0)); - - verify(observer); - } - - @Test - public void testObserverIsCalledOnSetDataPort() { - SIOSettings.ChangedObserver observer = createMock(SIOSettings.ChangedObserver.class); - observer.settingsChanged(); - expectLastCall().once(); - replay(observer); - - SIOSettings settings = new SIOSettings(PluginSettings.UNAVAILABLE); - settings.addChangedObserver(observer); - settings.setDataPorts(Collections.singletonList(0)); - - verify(observer); - } - - @Test - public void testValuesAreCorrectAfterRead() { - PluginSettings pluginSettings = createMock(PluginSettings.class); - expect(pluginSettings.getBoolean(eq(PluginSettings.EMUSTUDIO_NO_GUI), eq(false))).andReturn(true).once(); - expect(pluginSettings.getInt(SIOSettings.STATUS_PORT_NUMBER + "0")).andReturn(Optional.of(5)).once(); - expect(pluginSettings.getInt(SIOSettings.STATUS_PORT_NUMBER + "1")).andReturn(Optional.empty()).once(); - expect(pluginSettings.getInt(SIOSettings.DATA_PORT_NUMBER + "0")).andReturn(Optional.of(10)).once(); - expect(pluginSettings.getInt(SIOSettings.DATA_PORT_NUMBER + "1")).andReturn(Optional.empty()).once(); - replay(pluginSettings); - - SIOSettings settings = new SIOSettings(pluginSettings); - settings.read(); - - assertTrue(settings.isGuiNotSupported()); - assertEquals(5, (int) settings.getStatusPorts().iterator().next()); - assertEquals(10, (int) settings.getDataPorts().iterator().next()); - - verify(pluginSettings); - } - - @Test - public void testCorrectValuesAreWrittenAfterWrite() throws Exception { - PluginSettings pluginSettings = createMock(PluginSettings.class); - expect(pluginSettings.getBoolean(eq(PluginSettings.EMUSTUDIO_NO_GUI), eq(false))).andReturn(false).anyTimes(); - pluginSettings.setInt(eq(SIOSettings.STATUS_PORT_NUMBER + "0"), eq(5)); - expectLastCall().once(); - pluginSettings.setInt(eq(SIOSettings.DATA_PORT_NUMBER + "0"), eq(10)); - expectLastCall().once(); - expect(pluginSettings.contains("statusPortNumber1")).andReturn(false).once(); - expect(pluginSettings.contains("dataPortNumber1")).andReturn(false).once(); - replay(pluginSettings); - - SIOSettings settings = new SIOSettings(pluginSettings); - settings.setDataPorts(Collections.singletonList(10)); - settings.setStatusPorts(Collections.singletonList(5)); - settings.write(); - - verify(pluginSettings); - } - - @Test - public void testRemovedPortsAreReallyRemoved() throws Exception { - PluginSettings pluginSettings = createMock(PluginSettings.class); - expect(pluginSettings.getBoolean(eq(PluginSettings.EMUSTUDIO_NO_GUI), eq(false))).andReturn(false).anyTimes(); - - pluginSettings.setInt(eq(SIOSettings.STATUS_PORT_NUMBER + "0"), eq(10)); - expectLastCall().once(); - expect(pluginSettings.contains("statusPortNumber0")).andReturn(true).once(); - expect(pluginSettings.contains("statusPortNumber1")).andReturn(false).times(2); - expect(pluginSettings.contains("dataPortNumber0")).andReturn(false).times(2); - - pluginSettings.remove("statusPortNumber0"); - expectLastCall().once(); - - replay(pluginSettings); - - SIOSettings settings = new SIOSettings(pluginSettings); - settings.setStatusPorts(Collections.singletonList(10)); - settings.write(); - - settings.setStatusPorts(Collections.emptyList()); - settings.write(); - - verify(pluginSettings); - } -} diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SuiUnitTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SuiUnitTest.java new file mode 100644 index 000000000..8b39b8221 --- /dev/null +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SuiUnitTest.java @@ -0,0 +1,60 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.mits88sio; + +import net.emustudio.plugins.cpu.intel8080.api.Context8080; +import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; +import org.junit.Test; + +import java.util.List; + +import static org.easymock.EasyMock.*; + +public class SuiUnitTest { + + @Test + public void testCpuPortsAreReattached() { + SioUnitSettings s = mock(SioUnitSettings.class); + expect(s.getStatusPorts()).andReturn(List.of(1,2)).anyTimes(); + expect(s.getDataPorts()).andReturn(List.of(4,5)).anyTimes(); + replay(s); + + Context8080 cpu = mock(Context8080.class); + expect(cpu.attachDevice(anyObject(SioUnit.ControlChannel.class), eq(1))).andReturn(true).times(2); + expect(cpu.attachDevice(anyObject(SioUnit.ControlChannel.class), eq(2))).andReturn(true).times(2); + expect(cpu.attachDevice(anyObject(SioUnit.DataChannel.class), eq(4))).andReturn(true).times(2); + expect(cpu.attachDevice(anyObject(SioUnit.DataChannel.class), eq(5))).andReturn(true).times(2); + + cpu.detachDevice(1); + expectLastCall().times(2); // reattach + close() + cpu.detachDevice(2); + expectLastCall().times(2); + cpu.detachDevice(4); + expectLastCall().times(2); + cpu.detachDevice(5); + expectLastCall().times(2); + replay(cpu); + + try(SioUnit sio = new SioUnit(s, cpu)) { + sio.attach(); + sio.attach(); + } + verify(s, cpu); + } +} diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/TransmitterTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java similarity index 54% rename from plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/TransmitterTest.java rename to plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java index fc0945619..02d123d31 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/TransmitterTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java @@ -18,67 +18,69 @@ */ package net.emustudio.plugins.device.mits88sio; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import org.junit.Test; +import static org.easymock.EasyMock.mock; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -public class TransmitterTest { +public class UARTTest { @Test public void testGetDeviceIdReturnsNotNullIfDeviceIsNotAttached() { - assertNotNull(new Transmitter().getDeviceId()); + assertNotNull(new UART(mock(Context8080.class)).getDeviceId()); } @Test public void testSetNullDeviceDoesNotThrow() { - new Transmitter().setDevice(null); + new UART(mock(Context8080.class)).setDevice(null); } @Test public void testInitialStatusIs0x02() { - assertEquals(2, new Transmitter().readStatus()); + assertEquals(2, new UART(mock(Context8080.class)).readStatus()); } @Test public void testResetOnEmptyBufferSetStatusTo0x02() { - Transmitter transmitter = new Transmitter(); - transmitter.reset(false); - assertEquals(0x02, transmitter.readStatus()); + UART UART = new UART(mock(Context8080.class)); + UART.reset(false); + assertEquals(0x02, UART.readStatus()); } @Test public void testWriteToStatus0x03OnEmptyBufferSetStatusTo0x02() { - Transmitter transmitter = new Transmitter(); - transmitter.writeToStatus((short) 0x03); - assertEquals(0x02, transmitter.readStatus()); + UART UART = new UART(mock(Context8080.class)); + UART.setStatus((byte) 0x03); + assertEquals(0x02, UART.readStatus()); } @Test public void testWriteFromDeviceSetsInputDeviceReady() { - Transmitter transmitter = new Transmitter(); - transmitter.writeFromDevice((byte) 5); - assertEquals(1, transmitter.readStatus() & 0x01); + UART UART = new UART(mock(Context8080.class)); + UART.receiveFromDevice((byte) 5); + assertEquals(1, UART.readStatus() & 0x01); } @Test public void testReadBufferResetInputDeviceReady() { - Transmitter transmitter = new Transmitter(); - transmitter.writeFromDevice((byte) 5); + UART UART = new UART(mock(Context8080.class)); + UART.receiveFromDevice((byte) 5); - assertEquals(5, transmitter.readBuffer()); - assertEquals(0, transmitter.readStatus() & 0x01); + assertEquals(5, UART.readBuffer()); + assertEquals(0, UART.readStatus() & 0x01); } @Test public void testBufferIsFIFO() { - Transmitter transmitter = new Transmitter(); - transmitter.writeFromDevice((byte) 1); - transmitter.writeFromDevice((byte) 2); - transmitter.writeFromDevice((byte) 3); + UART UART = new UART(mock(Context8080.class)); + UART.receiveFromDevice((byte) 1); + UART.receiveFromDevice((byte) 2); + UART.receiveFromDevice((byte) 3); - assertEquals(1, transmitter.readBuffer()); - assertEquals(2, transmitter.readBuffer()); - assertEquals(3, transmitter.readBuffer()); + assertEquals(1, UART.readBuffer()); + assertEquals(2, UART.readBuffer()); + assertEquals(3, UART.readBuffer()); } } diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPortTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPortTest.java deleted file mode 100644 index ba34f7f05..000000000 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuDataPortTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio.ports; - -import net.emustudio.plugins.device.mits88sio.Transmitter; -import org.easymock.EasyMock; -import org.junit.Test; - -import static org.easymock.EasyMock.*; -import static org.junit.Assert.assertEquals; - -public class CpuDataPortTest { - - @Test(expected = NullPointerException.class) - public void testNullTransmitterInConstructorThrows() { - new CpuDataPort(null); - } - - @Test - public void testReadCallsReadBufferOnTransmitter() { - Transmitter transmitter = EasyMock.createMock(Transmitter.class); - expect(transmitter.readBuffer()).andReturn((byte) 5).once(); - replay(transmitter); - - CpuDataPort cpuDataPort = new CpuDataPort(transmitter); - assertEquals((short) 5, cpuDataPort.readData().shortValue()); - - verify(transmitter); - } - - @Test - public void testWriteCallsWriteToDeviceOnTransmitter() throws Exception { - Transmitter transmitter = EasyMock.createMock(Transmitter.class); - transmitter.writeToDevice(eq((byte) 5)); - expectLastCall().once(); - replay(transmitter); - - CpuDataPort cpuDataPort = new CpuDataPort(transmitter); - cpuDataPort.writeData((byte) 5); - - verify(transmitter); - } - -} diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuPortsTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuPortsTest.java deleted file mode 100644 index 0260be68f..000000000 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuPortsTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio.ports; - -import net.emustudio.plugins.cpu.intel8080.api.Context8080; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collections; - -import static org.easymock.EasyMock.*; - -public class CpuPortsTest { - - - @Test - public void testStatusPortsAreCorrectAfterReattaching() throws Exception { - CpuStatusPort cpuStatusPort = mock(CpuStatusPort.class); - Context8080 cpu = mock(Context8080.class); - - expect(cpu.attachDevice(cpuStatusPort, 1)).andReturn(true); - expect(cpu.attachDevice(cpuStatusPort, 2)).andReturn(true); - - cpu.detachDevice(1); - expectLastCall(); - cpu.detachDevice(2); - expectLastCall(); - - expect(cpu.attachDevice(cpuStatusPort, 3)).andReturn(true); - expect(cpu.attachDevice(cpuStatusPort, 2)).andReturn(true); - replay(cpu); - - CpuPorts ports = new CpuPorts(cpu); - - ports.reattachStatusPort(Arrays.asList(1, 2), cpuStatusPort); - ports.reattachStatusPort(Arrays.asList(3, 2), cpuStatusPort); - - verify(cpu); - } - - - @Test - public void testDataPortsAreCorrectAfterReattaching() throws CouldNotAttachException { - CpuDataPort cpuDataPort = mock(CpuDataPort.class); - Context8080 cpu = mock(Context8080.class); - - expect(cpu.attachDevice(cpuDataPort, 1)).andReturn(true); - expect(cpu.attachDevice(cpuDataPort, 2)).andReturn(true); - - cpu.detachDevice(1); - expectLastCall(); - cpu.detachDevice(2); - expectLastCall(); - - expect(cpu.attachDevice(cpuDataPort, 3)).andReturn(true); - expect(cpu.attachDevice(cpuDataPort, 2)).andReturn(true); - replay(cpu); - - CpuPorts ports = new CpuPorts(cpu); - - ports.reattachDataPort(Arrays.asList(1, 2), cpuDataPort); - ports.reattachDataPort(Arrays.asList(3, 2), cpuDataPort); - - verify(cpu); - } - - @Test - public void testDestroyDetachesAllPorts() throws Exception { - Context8080 cpu = mock(Context8080.class); - expect(cpu.attachDevice(anyObject(), anyInt())).andReturn(true).anyTimes(); - - cpu.detachDevice(1); - expectLastCall(); - cpu.detachDevice(2); - expectLastCall(); - replay(cpu); - - CpuPorts ports = new CpuPorts(cpu); - - ports.reattachStatusPort(Collections.singletonList(1), mock(CpuStatusPort.class)); - ports.reattachDataPort(Collections.singletonList(2), mock(CpuDataPort.class)); - - ports.destroy(); - - verify(cpu); - } -} diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPortTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPortTest.java deleted file mode 100644 index ac7c4136c..000000000 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/CpuStatusPortTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio.ports; - -import net.emustudio.plugins.device.mits88sio.Transmitter; -import org.easymock.EasyMock; -import org.junit.Test; - -import static org.easymock.EasyMock.*; -import static org.junit.Assert.assertEquals; - -public class CpuStatusPortTest { - - @Test(expected = NullPointerException.class) - public void testNullTransmitterInConstructorThrows() { - new CpuStatusPort(null); - } - - @Test - public void testReadCallsReadStatusOnTransmitter() { - Transmitter transmitter = EasyMock.createMock(Transmitter.class); - expect(transmitter.readStatus()).andReturn((byte) 5).once(); - replay(transmitter); - - CpuStatusPort cpuStatusPort = new CpuStatusPort(transmitter); - assertEquals((short) 5, cpuStatusPort.readData().shortValue()); - - verify(transmitter); - } - - @Test - public void testWriteCallsWriteToStatusOnTransmitter() { - Transmitter transmitter = EasyMock.createMock(Transmitter.class); - transmitter.writeToStatus(eq((short) 5)); - expectLastCall().once(); - replay(transmitter); - - CpuStatusPort cpuStatusPort = new CpuStatusPort(transmitter); - cpuStatusPort.writeData((byte) 5); - - verify(transmitter); - } -} diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPortTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPortTest.java deleted file mode 100644 index 4f692555d..000000000 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ports/PhysicalPortTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio.ports; - -import net.emustudio.plugins.device.mits88sio.Transmitter; -import org.easymock.EasyMock; -import org.junit.Test; - -import static org.easymock.EasyMock.*; -import static org.junit.Assert.assertEquals; - -public class PhysicalPortTest { - - @Test(expected = NullPointerException.class) - public void testNullTransmitterInConstructorThrows() { - new PhysicalPort(null); - } - - @Test - public void testReadReturnsZero() { - Transmitter transmitter = EasyMock.createMock(Transmitter.class); - replay(transmitter); - - PhysicalPort port = new PhysicalPort(transmitter); - assertEquals((short) 0, port.readData().shortValue()); - - verify(transmitter); - } - - @Test - public void testWriteCallsWriteFromDeviceOnTransmitter() { - Transmitter transmitter = EasyMock.createMock(Transmitter.class); - transmitter.writeFromDevice(eq((byte) 5)); - expectLastCall().once(); - replay(transmitter); - - PhysicalPort port = new PhysicalPort(transmitter); - port.writeData((byte) 5); - - verify(transmitter); - } - -} diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java index a69359b10..d84f5f277 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java @@ -24,7 +24,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; import net.emustudio.emulib.runtime.InvalidContextException; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.device.abstracttape.api.AbstractTapeContext; import net.emustudio.plugins.device.abstracttape.gui.SettingsDialog; import net.emustudio.plugins.device.abstracttape.gui.TapeGui; diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/SettingsDialog.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/SettingsDialog.java index 7fbd38b36..1dec42a87 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/SettingsDialog.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/SettingsDialog.java @@ -18,8 +18,8 @@ */ package net.emustudio.plugins.device.abstracttape.gui; -import net.emustudio.emulib.runtime.CannotUpdateSettingException; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/plugins/device/abstract-tape/src/test/java/net/emustudio/plugins/device/abstracttape/AbstractTapeTest.java b/plugins/device/abstract-tape/src/test/java/net/emustudio/plugins/device/abstracttape/AbstractTapeTest.java index 6ba70f099..550388c7c 100644 --- a/plugins/device/abstract-tape/src/test/java/net/emustudio/plugins/device/abstracttape/AbstractTapeTest.java +++ b/plugins/device/abstract-tape/src/test/java/net/emustudio/plugins/device/abstracttape/AbstractTapeTest.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index 1727f9562..d1e7df272 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -24,6 +24,7 @@ import net.emustudio.emulib.plugins.device.AbstractDevice; import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.emulib.runtime.*; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.device.adm3a.gui.ConfigDialog; import net.emustudio.plugins.device.adm3a.gui.TerminalWindow; import net.emustudio.plugins.device.adm3a.interaction.*; @@ -83,7 +84,9 @@ public void initialize() throws PluginInitializationException { // try to connect to a serial I/O board try { - DeviceContext device = applicationApi.getContextPool().getDeviceContext(pluginID, DeviceContext.class); + DeviceContext device = applicationApi.getContextPool().getDeviceContext( + pluginID, DeviceContext.class, terminalSettings.getDeviceIndex() + ); if (device.getDataType() != Byte.class) { throw new PluginInitializationException( "Unexpected device data type. Expected Short but was: " + device.getDataType() diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java index 83b150cf9..813857244 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java @@ -18,8 +18,8 @@ */ package net.emustudio.plugins.device.adm3a; -import net.emustudio.emulib.runtime.CannotUpdateSettingException; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,6 +41,7 @@ public class TerminalSettings { private final static String INPUT_FILE_NAME = "inputFileName"; private final static String OUTPUT_FILE_NAME = "outputFileName"; private final static String INPUT_READ_DELAY = "inputReadDelay"; + private final static String DEVICE_INDEX = "deviceIndex"; private final Dialogs dialogs; private final PluginSettings settings; @@ -52,6 +53,7 @@ public class TerminalSettings { private volatile Path inputPath = Path.of(DEFAULT_INPUT_FILE_NAME); private volatile Path outputPath = Path.of(DEFAULT_OUTPUT_FILE_NAME); private int inputReadDelay = 0; + private int deviceIndex = 0; private final List observers = new ArrayList<>(); @@ -133,6 +135,14 @@ public void setAlwaysOnTop(boolean alwaysOnTop) { notifyObserversAndIgnoreError(); } + public int getDeviceIndex() { + return deviceIndex; + } + + public void setDeviceIndex(int deviceIndex) { + this.deviceIndex = deviceIndex; + } + public void write() { try { settings.setInt(INPUT_READ_DELAY, inputReadDelay); @@ -141,6 +151,7 @@ public void write() { settings.setBoolean(ANTI_ALIASING, antiAliasing); settings.setString(OUTPUT_FILE_NAME, outputPath.toString()); settings.setString(INPUT_FILE_NAME, inputPath.toString()); + settings.setInt(DEVICE_INDEX, deviceIndex); } catch (CannotUpdateSettingException e) { LOGGER.error("Could not update settings", e); dialogs.showError("Could not save settings. Please see log file for details.", "ADM 3A"); @@ -155,6 +166,7 @@ private void readSettings() { antiAliasing = settings.getBoolean(ANTI_ALIASING, true); inputPath = Path.of(settings.getString(INPUT_FILE_NAME, DEFAULT_INPUT_FILE_NAME)); outputPath = Path.of(settings.getString(OUTPUT_FILE_NAME, DEFAULT_OUTPUT_FILE_NAME)); + deviceIndex = settings.getInt(DEVICE_INDEX, 0); try { inputReadDelay = settings.getInt(INPUT_READ_DELAY, 0); } catch (NumberFormatException e) { diff --git a/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/DeviceImplTest.java b/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/DeviceImplTest.java index 3bf66165c..9651d106b 100644 --- a/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/DeviceImplTest.java +++ b/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/DeviceImplTest.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; import org.junit.After; import org.junit.Before; diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java index b189a4c57..024166118 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java @@ -26,7 +26,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; import net.emustudio.emulib.runtime.InvalidContextException; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.cpu.brainduck.BrainCPUContext; import net.emustudio.plugins.device.brainduck.terminal.io.FileIOProvider; import net.emustudio.plugins.device.brainduck.terminal.io.InputProvider; diff --git a/plugins/device/brainduck-terminal/src/test/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImplTest.java b/plugins/device/brainduck-terminal/src/test/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImplTest.java index 8ada702c9..e65b84be2 100644 --- a/plugins/device/brainduck-terminal/src/test/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImplTest.java +++ b/plugins/device/brainduck-terminal/src/test/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImplTest.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java index 6f08afd2e..d6a8a265e 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java @@ -24,7 +24,7 @@ import net.emustudio.emulib.plugins.device.AbstractDevice; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java index def1d61a7..32a7cf344 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java @@ -31,7 +31,7 @@ public void write(byte data, Control control) { genInterruptPos = 1; System.out.println("genInterruptVec=" + genInterruptVec + " genInterruptPos=" + genInterruptPos); } else { - control.getCpu().signalInterrupt(control.getDevice(), new byte[]{data}); + control.getCpu().signalInterrupt(new byte[]{data}); genInterruptPos = 0; control.clearCommand(); System.out.printf( diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java index c82e0d1a6..dab400f8b 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java @@ -42,7 +42,7 @@ public void start(Control control) { int addr = SetTimerInterruptAdr.INS.timerInterruptHandler; byte b1 = (byte) (addr & 0xFF); byte b2 = (byte) (addr >>> 8); - control.getCpu().signalInterrupt(control.getDevice(), new byte[]{(byte) 0xCD, b1, b2}); + control.getCpu().signalInterrupt(new byte[]{(byte) 0xCD, b1, b2}); }, SetTimerDelta.INS.timerDelta, SetTimerDelta.INS.timerDelta, TimeUnit.MILLISECONDS)); control.clearCommand(); } diff --git a/plugins/device/simh-pseudo/src/test/java/net/emustudio/plugins/device/simh/DeviceImplTest.java b/plugins/device/simh-pseudo/src/test/java/net/emustudio/plugins/device/simh/DeviceImplTest.java index e1812b703..878494615 100644 --- a/plugins/device/simh-pseudo/src/test/java/net/emustudio/plugins/device/simh/DeviceImplTest.java +++ b/plugins/device/simh-pseudo/src/test/java/net/emustudio/plugins/device/simh/DeviceImplTest.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java index 4c61eb1e9..ca1c15cbb 100644 --- a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java +++ b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java @@ -24,7 +24,7 @@ import net.emustudio.emulib.plugins.device.AbstractDevice; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import javax.swing.*; import java.util.MissingResourceException; diff --git a/plugins/device/ssem-display/src/test/java/net/emustudio/plugins/device/ssem/display/DeviceImplTest.java b/plugins/device/ssem-display/src/test/java/net/emustudio/plugins/device/ssem/display/DeviceImplTest.java index 8b8c12edb..09f91f665 100644 --- a/plugins/device/ssem-display/src/test/java/net/emustudio/plugins/device/ssem/display/DeviceImplTest.java +++ b/plugins/device/ssem-display/src/test/java/net/emustudio/plugins/device/ssem/display/DeviceImplTest.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java index 6812a3340..8bacb83bc 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java @@ -24,6 +24,7 @@ import net.emustudio.emulib.plugins.memory.AbstractMemory; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.*; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import net.emustudio.plugins.memory.bytemem.gui.MemoryGui; import org.slf4j.Logger; @@ -171,7 +172,7 @@ public void loadImage(Path imagePath, int address, int bank) { * after start of the emulator. These settings correspond to tab0 in frmSettings. */ public void saveCoreSettings(int banksCount, int commonBoundary, List imageFullNames, - List imageAddresses, List imageBanks) throws CannotUpdateSettingException { + List imageAddresses, List imageBanks) { settings.setInt("banksCount", banksCount); settings.setInt("commonBoundary", commonBoundary); @@ -192,7 +193,7 @@ public void saveCoreSettings(int banksCount, int commonBoundary, List im * settings correspond to tab1 in frmSettings. ROM ranges are taken * directly from memory context. */ - public void saveROMRanges() throws CannotUpdateSettingException { + public void saveROMRanges() { for (int i = 0; settings.contains("ROMfrom" + i) ; i++) { settings.remove("ROMfrom" + i); settings.remove("ROMto" + i); diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java index 1bdc6b7c2..59e7e8d1b 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.memory.bytemem.gui; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java index e20a5194b..94b0e7820 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java @@ -18,8 +18,8 @@ */ package net.emustudio.plugins.memory.bytemem.gui; -import net.emustudio.emulib.runtime.CannotUpdateSettingException; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/FileImagesModel.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/FileImagesModel.java index 1598fb649..662bb993d 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/FileImagesModel.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/FileImagesModel.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.memory.bytemem.gui.model; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/MemoryImplTest.java b/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/MemoryImplTest.java index 26927a689..4af757d63 100644 --- a/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/MemoryImplTest.java +++ b/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/MemoryImplTest.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; import org.junit.After; import org.junit.Before; diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java index 33907afd0..21a1028b2 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java @@ -23,6 +23,7 @@ import net.emustudio.emulib.plugins.memory.AbstractMemory; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.*; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; import net.emustudio.plugins.memory.ram.gui.MemoryDialog; diff --git a/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryImplTest.java b/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryImplTest.java index f5ff6d5d4..90445be9c 100644 --- a/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryImplTest.java +++ b/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryImplTest.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java index 9d6b83404..64f1b36f3 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java @@ -27,7 +27,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; import net.emustudio.emulib.runtime.InvalidContextException; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.memory.rasp.api.RASPMemoryContext; import net.emustudio.plugins.memory.rasp.gui.MemoryDialog; import org.slf4j.Logger; diff --git a/plugins/memory/rasp-mem/src/test/java/net/emustudio/plugins/memory/rasp/MemoryImplTest.java b/plugins/memory/rasp-mem/src/test/java/net/emustudio/plugins/memory/rasp/MemoryImplTest.java index ae57e41a7..191214a8d 100644 --- a/plugins/memory/rasp-mem/src/test/java/net/emustudio/plugins/memory/rasp/MemoryImplTest.java +++ b/plugins/memory/rasp-mem/src/test/java/net/emustudio/plugins/memory/rasp/MemoryImplTest.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java index 3ab5f785d..97f5d69b4 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java @@ -25,7 +25,7 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; import net.emustudio.emulib.runtime.InvalidContextException; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.memory.ssem.gui.MemoryGui; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryImplTest.java b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryImplTest.java index ca5b670ba..8a18786cd 100644 --- a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryImplTest.java +++ b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/MemoryImplTest.java @@ -21,7 +21,7 @@ import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.PluginSettings; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.Before; import org.junit.Test; From f7b237aa849c8d133866240b488a148332cfdc61 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 2 Aug 2022 11:33:04 +0100 Subject: [PATCH 186/314] [#243] Implement several 88-SIO modes --- .../src/main/files/config/MITSAltair8800.toml | 19 +++---- .../main/files/config/MITSAltair8800Z80.toml | 1 - .../cmdline/AutomationCommand.java | 4 +- .../emustudio/application/cmdline/Runner.java | 4 +- .../emustudio/application/cmdline/Utils.java | 16 +++--- .../application/emulation/Automation.java | 12 ++-- .../emustudio/application/gui/GuiUtils.java | 4 +- .../gui/actions/ViewComputerAction.java | 10 ++-- .../opencomputer/AddNewComputerAction.java | 10 ++-- .../opencomputer/EditComputerAction.java | 10 ++-- .../gui/dialogs/OpenComputerDialog.java | 14 ++--- .../application/gui/dialogs/StudioFrame.java | 6 +- .../gui/dialogs/ViewComputerDialog.java | 6 +- .../application/gui/schema/Schema.java | 16 +++--- ...pplicationConfig.java => AppSettings.java} | 12 ++-- .../settings/BasicSettingsImpl.java | 18 ++++-- .../application/settings/ComputerConfig.java | 32 ++++++++--- .../application/settings/ConfigFiles.java | 12 ++-- .../application/settings/PluginConfig.java | 2 - .../settings/PluginSettingsImpl.java | 57 +++++++++---------- .../virtualcomputer/VirtualComputer.java | 30 ++++++---- ...onConfigTest.java => AppSettingsTest.java} | 12 ++-- .../plugins/device/mits88sio/SioUnit.java | 22 ++++++- .../device/mits88sio/gui/SettingsDialog.java | 35 ++++++++---- .../mits88sio/settings/SioDeviceSettings.java | 5 +- .../mits88sio/settings/SioUnitSettings.java | 52 ++++++++++------- 26 files changed, 244 insertions(+), 177 deletions(-) rename application/src/main/java/net/emustudio/application/settings/{ApplicationConfig.java => AppSettings.java} (87%) rename application/src/test/java/net/emustudio/application/settings/{ApplicationConfigTest.java => AppSettingsTest.java} (77%) diff --git a/application/src/main/files/config/MITSAltair8800.toml b/application/src/main/files/config/MITSAltair8800.toml index c47db2324..6a4f5f99c 100644 --- a/application/src/main/files/config/MITSAltair8800.toml +++ b/application/src/main/files/config/MITSAltair8800.toml @@ -103,16 +103,15 @@ name = "MITS Altair8800" type = "DEVICE" [DEVICE.settings] - [DEVICE.settings.sio] - statusPorts = "0x10, 0x14, 0x16, 0x18" - dataPorts = "0x11, 0x15, 0x17, 0x19" - clearInputBit8 = false - clearOutputBit8 = false - inputToUpperCase = false - mapDeleteChar = "UNCHANGED" - mapBackspaceChar = "UNCHANGED" - inputInterruptVector = 0 - outputInterruptVector = 0 + statusPorts = "0x10, 0x14, 0x16, 0x18" + dataPorts = "0x11, 0x15, 0x17, 0x19" + clearInputBit8 = false + clearOutputBit8 = false + inputToUpperCase = false + mapDeleteChar = "UNCHANGED" + mapBackspaceChar = "UNCHANGED" + inputInterruptVector = 0 + outputInterruptVector = 0 [[DEVICE]] schemaPoint = "340,60" diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index 47b200e45..33ba5699d 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -99,7 +99,6 @@ name = "MITS Altair8800 (Z80)" type = "DEVICE" [DEVICE.settings] - [DEVICE.settings.sio] statusPorts = "0x10, 0x14, 0x16, 0x18" dataPorts = "0x11, 0x15, 0x17, 0x19" clearInputBit8 = false diff --git a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java index 0dcbd8055..bcbc53d42 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java +++ b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.cmdline; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.emulation.Automation; import net.emustudio.application.gui.ExtendedDialogs; @@ -61,7 +61,7 @@ public class AutomationCommand implements Runnable { public void run() { ExtendedDialogs dialogs = new NoGuiDialogsImpl(); try { - ApplicationConfig appConfig = loadAppConfig(gui, true); + AppSettings appConfig = loadAppSettings(gui, true); if (gui) { setupLookAndFeel(appConfig); dialogs = new GuiDialogsImpl(); diff --git a/application/src/main/java/net/emustudio/application/cmdline/Runner.java b/application/src/main/java/net/emustudio/application/cmdline/Runner.java index 0e07f1a8f..f7e9e0b66 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/Runner.java +++ b/application/src/main/java/net/emustudio/application/cmdline/Runner.java @@ -19,7 +19,7 @@ package net.emustudio.application.cmdline; import net.emustudio.application.Resources; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.settings.ConfigFiles; import net.emustudio.application.gui.ExtendedDialogs; @@ -94,7 +94,7 @@ public void run() { if (!runsSomeCommand) { try { - ApplicationConfig appConfig = loadAppConfig(true, false); + AppSettings appConfig = loadAppSettings(true, false); setupLookAndFeel(appConfig); ExtendedDialogs dialogs = new GuiDialogsImpl(); Optional computerConfigOpt = (exclusive != null) ? diff --git a/application/src/main/java/net/emustudio/application/cmdline/Utils.java b/application/src/main/java/net/emustudio/application/cmdline/Utils.java index bb87cf63b..704045e0b 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/Utils.java +++ b/application/src/main/java/net/emustudio/application/cmdline/Utils.java @@ -19,7 +19,7 @@ package net.emustudio.application.cmdline; import net.emustudio.application.ApplicationApiImpl; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.ExtendedDialogs; import net.emustudio.application.gui.debugtable.DebugTableModel; @@ -51,18 +51,18 @@ public class Utils { private static final Logger LOGGER = LoggerFactory.getLogger(Runner.class); public static final long EMUSTUDIO_ID = UUID.randomUUID().toString().hashCode(); - public static ApplicationConfig loadAppConfig(boolean gui, boolean auto) throws IOException { + public static AppSettings loadAppSettings(boolean gui, boolean auto) throws IOException { Path configFile = Path.of("emuStudio.toml"); if (Files.notExists(configFile)) { LOGGER.warn("No configuration file found; creating empty one"); Files.createFile(configFile); } - return ApplicationConfig.fromFile(configFile, !gui, auto); + return AppSettings.fromFile(configFile, !gui, auto); } public static VirtualComputer loadComputer( - ApplicationConfig appConfig, + AppSettings appConfig, ComputerConfig computerConfig, ExtendedDialogs dialogs, ContextPoolImpl contextPool, @@ -80,10 +80,10 @@ public static VirtualComputer loadComputer( } public static Optional loadComputerConfigFromGui( - ApplicationConfig appConfig, ExtendedDialogs dialogs + AppSettings appSettings, ExtendedDialogs dialogs ) { final AtomicReference computerConfig = new AtomicReference<>(); - OpenComputerDialog dialog = new OpenComputerDialog(appConfig, dialogs, computerConfig::set); + OpenComputerDialog dialog = new OpenComputerDialog(appSettings, dialogs, computerConfig::set); dialogs.setParent(dialog); dialog.setVisible(true); dialogs.setParent(null); @@ -97,7 +97,7 @@ public static LoadingDialog showSplashScreen() { } @SuppressWarnings("unchecked") - public static void showMainWindow(VirtualComputer computer, ApplicationConfig applicationConfig, ExtendedDialogs dialogs, + public static void showMainWindow(VirtualComputer computer, AppSettings appSettings, ExtendedDialogs dialogs, DebugTableModel debugTableModel, ContextPool contextPool, Optional inputFile) { MemoryContext memoryContext = null; try { @@ -107,7 +107,7 @@ public static void showMainWindow(VirtualComputer computer, ApplicationConfig ap } StudioFrame mainWindow = new StudioFrame( - computer, applicationConfig, dialogs, debugTableModel, memoryContext, inputFile + computer, appSettings, dialogs, debugTableModel, memoryContext, inputFile ); dialogs.setParent(mainWindow); diff --git a/application/src/main/java/net/emustudio/application/emulation/Automation.java b/application/src/main/java/net/emustudio/application/emulation/Automation.java index d8284d707..1017d2970 100644 --- a/application/src/main/java/net/emustudio/application/emulation/Automation.java +++ b/application/src/main/java/net/emustudio/application/emulation/Automation.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.emulation; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.gui.dialogs.AutoDialog; import net.emustudio.application.internal.Unchecked; import net.emustudio.application.virtualcomputer.VirtualComputer; @@ -48,17 +48,17 @@ public class Automation implements Runnable { private final File inputFile; private final VirtualComputer computer; - private final ApplicationConfig applicationConfig; + private final AppSettings appSettings; private final Dialogs dialogs; private final int waitForFinishMillis; private final int programStart; private volatile CPU.RunState resultState; - public Automation(VirtualComputer computer, Path inputFile, ApplicationConfig applicationConfig, + public Automation(VirtualComputer computer, Path inputFile, AppSettings appSettings, Dialogs dialogs, int waitForFinishMillis, int programStart) throws AutomationException { this.computer = Objects.requireNonNull(computer); - this.applicationConfig = Objects.requireNonNull(applicationConfig); + this.appSettings = Objects.requireNonNull(appSettings); this.dialogs = Objects.requireNonNull(dialogs); this.waitForFinishMillis = waitForFinishMillis; this.programStart = programStart; @@ -72,7 +72,7 @@ public Automation(VirtualComputer computer, Path inputFile, ApplicationConfig ap this.inputFile = null; } - if (!applicationConfig.noGUI) { + if (!appSettings.noGUI) { progressGUI = new AutoDialog(computer); } } @@ -144,7 +144,7 @@ private void autoEmulate(CPU cpu) { // Show all devices if GUI is supported for (Device device : computer.getDevices()) { - if (!applicationConfig.noGUI) { + if (!appSettings.noGUI) { device.showGUI(null); } } diff --git a/application/src/main/java/net/emustudio/application/gui/GuiUtils.java b/application/src/main/java/net/emustudio/application/gui/GuiUtils.java index d777cd3ed..9e50f825f 100644 --- a/application/src/main/java/net/emustudio/application/gui/GuiUtils.java +++ b/application/src/main/java/net/emustudio/application/gui/GuiUtils.java @@ -19,7 +19,7 @@ package net.emustudio.application.gui; import net.emustudio.application.Constants; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,7 +46,7 @@ public static void addKeyListenerRecursively(Component c, KeyListener keyListene } } - public static void setupLookAndFeel(ApplicationConfig config) { + public static void setupLookAndFeel(AppSettings config) { String lookAndFeel = config.getLookAndFeel().orElse("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); try { diff --git a/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java index aa2620a7e..0abb51a41 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.gui.actions; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.gui.dialogs.ViewComputerDialog; import net.emustudio.application.virtualcomputer.VirtualComputer; import net.emustudio.emulib.runtime.interaction.Dialogs; @@ -33,21 +33,21 @@ public class ViewComputerAction extends AbstractAction { private final JFrame parent; private final VirtualComputer computer; private final Dialogs dialogs; - private final ApplicationConfig applicationConfig; + private final AppSettings appSettings; - public ViewComputerAction(JFrame parent, VirtualComputer computer, Dialogs dialogs, ApplicationConfig applicationConfig) { + public ViewComputerAction(JFrame parent, VirtualComputer computer, Dialogs dialogs, AppSettings appSettings) { super("View computer..."); this.parent = Objects.requireNonNull(parent); this.computer = Objects.requireNonNull(computer); this.dialogs = Objects.requireNonNull(dialogs); - this.applicationConfig = Objects.requireNonNull(applicationConfig); + this.appSettings = Objects.requireNonNull(appSettings); putValue(MNEMONIC_KEY, KeyEvent.VK_V); } @Override public void actionPerformed(ActionEvent actionEvent) { - new ViewComputerDialog(parent, computer, applicationConfig, dialogs).setVisible(true); + new ViewComputerDialog(parent, computer, appSettings, dialogs).setVisible(true); } } diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java index a13e041a4..268aea3e6 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.gui.actions.opencomputer; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.dialogs.SchemaEditorDialog; import net.emustudio.application.gui.schema.Schema; @@ -40,16 +40,16 @@ public class AddNewComputerAction extends AbstractAction { private final static Logger LOGGER = LoggerFactory.getLogger(AddNewComputerAction.class); private final Dialogs dialogs; - private final ApplicationConfig applicationConfig; + private final AppSettings appSettings; private final Runnable update; private final JDialog parent; - public AddNewComputerAction(Dialogs dialogs, ApplicationConfig applicationConfig, Runnable update, JDialog parent) { + public AddNewComputerAction(Dialogs dialogs, AppSettings appSettings, Runnable update, JDialog parent) { super( "Create new computer...", new ImageIcon(AddNewComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/list-add.png")) ); this.dialogs = Objects.requireNonNull(dialogs); - this.applicationConfig = Objects.requireNonNull(applicationConfig); + this.appSettings = Objects.requireNonNull(appSettings); this.update = Objects.requireNonNull(update); this.parent = Objects.requireNonNull(parent); } @@ -67,7 +67,7 @@ public void actionPerformed(ActionEvent e) { c -> dialogs.showError("Computer '" + name + "' already exists, choose another name."), () -> { ComputerConfig newComputer = Unchecked.call(() -> createConfiguration(name)); - Schema schema = new Schema(newComputer, applicationConfig); + Schema schema = new Schema(newComputer, appSettings); SchemaEditorDialog di = new SchemaEditorDialog(parent, schema, dialogs); di.setVisible(true); update.run(); diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java index 0878388f1..583157f70 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.gui.actions.opencomputer; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.dialogs.SchemaEditorDialog; import net.emustudio.application.gui.schema.Schema; @@ -31,18 +31,18 @@ public class EditComputerAction extends AbstractAction { private final Dialogs dialogs; - private final ApplicationConfig applicationConfig; + private final AppSettings appSettings; private final Runnable update; private final JDialog parent; private final JList lstConfig; - public EditComputerAction(Dialogs dialogs, ApplicationConfig applicationConfig, + public EditComputerAction(Dialogs dialogs, AppSettings appSettings, Runnable update, JDialog parent, JList lstConfig) { super( "Edit computer...", new ImageIcon(EditComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/computer.png")) ); this.dialogs = Objects.requireNonNull(dialogs); - this.applicationConfig = Objects.requireNonNull(applicationConfig); + this.appSettings = Objects.requireNonNull(appSettings); this.update = Objects.requireNonNull(update); this.parent = Objects.requireNonNull(parent); this.lstConfig = Objects.requireNonNull(lstConfig); @@ -53,7 +53,7 @@ public void actionPerformed(ActionEvent e) { Optional .ofNullable(lstConfig.getSelectedValue()) .ifPresentOrElse(computer -> { - Schema schema = new Schema(computer, applicationConfig); + Schema schema = new Schema(computer, appSettings); new SchemaEditorDialog(parent, schema, dialogs).setVisible(true); update.run(); }, () -> dialogs.showError("A computer has to be selected!", "Edit computer")); diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java index c37b4dcf3..4928c5982 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.gui.dialogs; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.ToolbarButton; import net.emustudio.application.gui.actions.opencomputer.*; @@ -48,7 +48,7 @@ public class OpenComputerDialog extends JDialog { private final ConfigurationsListModel configurationsModel; private final SchemaPreviewPanel preview; - private final ApplicationConfig applicationConfig; + private final AppSettings appSettings; private final Dialogs dialogs; private final AddNewComputerAction addNewComputerAction; @@ -60,16 +60,16 @@ public class OpenComputerDialog extends JDialog { private final JList lstConfig = new JList<>(); - public OpenComputerDialog(ApplicationConfig applicationConfig, Dialogs dialogs, + public OpenComputerDialog(AppSettings appSettings, Dialogs dialogs, Consumer selectComputer) { this.configurationsModel = new ConfigurationsListModel(); - this.applicationConfig = Objects.requireNonNull(applicationConfig); + this.appSettings = Objects.requireNonNull(appSettings); this.dialogs = Objects.requireNonNull(dialogs); this.preview = new SchemaPreviewPanel(null, dialogs); - addNewComputerAction = new AddNewComputerAction(dialogs, applicationConfig, this::update, this); + addNewComputerAction = new AddNewComputerAction(dialogs, appSettings, this::update, this); deleteComputerAction = new DeleteComputerAction(dialogs, this::update, lstConfig); - editComputerAction = new EditComputerAction(dialogs, applicationConfig, this::update, this, lstConfig); + editComputerAction = new EditComputerAction(dialogs, appSettings, this::update, this, lstConfig); openComputerAction = new OpenComputerAction(dialogs, this, lstConfig, selectComputer); renameComputerAction = new RenameComputerAction(dialogs, this::update, lstConfig); saveSchemaAction = new SaveSchemaAction(preview); @@ -220,7 +220,7 @@ private void lstConfigValueChanged(ListSelectionEvent evt) { Optional .ofNullable(lstConfig.getSelectedValue()) .ifPresentOrElse(computer -> { - Schema schema = new Schema(computer, applicationConfig); + Schema schema = new Schema(computer, appSettings); preview.setSchema(schema); }, () -> preview.setSchema(null)); preview.repaint(); diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java b/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java index 50c0bf8d0..4532c10ed 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.gui.dialogs; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.emulation.EmulationController; import net.emustudio.application.gui.actions.AboutAction; import net.emustudio.application.gui.actions.CompilerSettingsAction; @@ -61,7 +61,7 @@ public class StudioFrame extends JFrame { private final JTabbedPane tabbedPane = new JTabbedPane(); - public StudioFrame(VirtualComputer computer, ApplicationConfig applicationConfig, Dialogs dialogs, + public StudioFrame(VirtualComputer computer, AppSettings appSettings, Dialogs dialogs, DebugTableModel debugTableModel, MemoryContext memoryContext, Optional fileName) { Objects.requireNonNull(computer); @@ -85,7 +85,7 @@ public StudioFrame(VirtualComputer computer, ApplicationConfig applicationConfig this.findPreviousAction = new FindPreviousAction(editor, dialogs, editorPanel.getFindAction()); this.exitAction = new ExitAction(editorPanel::confirmSave, emulationController, computer, this::formWindowClosing); - this.viewComputerAction = new ViewComputerAction(this, computer, dialogs, applicationConfig); + this.viewComputerAction = new ViewComputerAction(this, computer, dialogs, appSettings); this.compilerSettingsAction = new CompilerSettingsAction(this, computer); this.aboutAction = new AboutAction(this); diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java index 4a1c46707..309a32d9a 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.gui.dialogs; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.schema.Schema; import net.emustudio.application.gui.schema.SchemaPreviewPanel; @@ -40,7 +40,7 @@ public class ViewComputerDialog extends JDialog { private final VirtualComputer computer; private final SchemaPreviewPanel panelSchema; - public ViewComputerDialog(JFrame parent, VirtualComputer computer, ApplicationConfig applicationConfig, Dialogs dialogs) { + public ViewComputerDialog(JFrame parent, VirtualComputer computer, AppSettings appSettings, Dialogs dialogs) { super(parent, true); this.computer = Objects.requireNonNull(computer); @@ -69,7 +69,7 @@ public ViewComputerDialog(JFrame parent, VirtualComputer computer, ApplicationCo } }); - panelSchema = new SchemaPreviewPanel(new Schema(computer.getComputerConfig(), applicationConfig), dialogs); + panelSchema = new SchemaPreviewPanel(new Schema(computer.getComputerConfig(), appSettings), dialogs); scrollPane.setViewportView(panelSchema); scrollPane.getHorizontalScrollBar().setUnitIncrement(10); scrollPane.getVerticalScrollBar().setUnitIncrement(10); diff --git a/application/src/main/java/net/emustudio/application/gui/schema/Schema.java b/application/src/main/java/net/emustudio/application/gui/schema/Schema.java index bce004fa3..acc4bcdc5 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/Schema.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/Schema.java @@ -18,7 +18,7 @@ */ package net.emustudio.application.gui.schema; -import net.emustudio.application.settings.ApplicationConfig; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.settings.PluginConnection; @@ -40,11 +40,11 @@ public class Schema { private final List deviceElements = new ArrayList<>(); private final List lines = new ArrayList<>(); private final ComputerConfig config; - private final ApplicationConfig applicationConfig; + private final AppSettings appSettings; - public Schema(ComputerConfig config, ApplicationConfig applicationConfig) throws NumberFormatException { + public Schema(ComputerConfig config, AppSettings appSettings) throws NumberFormatException { this.config = Objects.requireNonNull(config); - this.applicationConfig = Objects.requireNonNull(applicationConfig); + this.appSettings = Objects.requireNonNull(appSettings); load(); } @@ -54,19 +54,19 @@ public ComputerConfig getComputerConfig() { } public boolean useSchemaGrid() { - return applicationConfig.useSchemaGrid(); + return appSettings.useSchemaGrid(); } public void setUseSchemaGrid(boolean useSchemaGrid) { - applicationConfig.setUseSchemaGrid(useSchemaGrid); + appSettings.setUseSchemaGrid(useSchemaGrid); } public int getSchemaGridGap() { - return applicationConfig.getSchemaGridGap(); + return appSettings.getSchemaGridGap(); } public void setSchemaGridGap(int gridGap) { - applicationConfig.setSchemaGridGap(gridGap); + appSettings.setSchemaGridGap(gridGap); } public void setCompilerElement(Point clickPoint, String pluginFile) { diff --git a/application/src/main/java/net/emustudio/application/settings/ApplicationConfig.java b/application/src/main/java/net/emustudio/application/settings/AppSettings.java similarity index 87% rename from application/src/main/java/net/emustudio/application/settings/ApplicationConfig.java rename to application/src/main/java/net/emustudio/application/settings/AppSettings.java index 6bfca1136..8ec454bfc 100644 --- a/application/src/main/java/net/emustudio/application/settings/ApplicationConfig.java +++ b/application/src/main/java/net/emustudio/application/settings/AppSettings.java @@ -28,7 +28,7 @@ @SuppressWarnings("unused") -public class ApplicationConfig extends BasicSettingsImpl { +public class AppSettings extends BasicSettingsImpl { public final static String KEY_NOGUI = EMUSTUDIO_NO_GUI.substring(EMUSTUDIO_PREFIX.length()); public final static String KEY_AUTO = EMUSTUDIO_AUTO.substring(EMUSTUDIO_PREFIX.length()); public final static String KEY_USE_SCHEMA_GRID = "useSchemaGrid"; @@ -40,8 +40,8 @@ public class ApplicationConfig extends BasicSettingsImpl { public transient final boolean emuStudioAuto; public transient final boolean noGUI; - public ApplicationConfig(Config config, boolean nogui, boolean auto) { - super(config); + public AppSettings(Config config, boolean nogui, boolean auto) { + super(config, System.out::println); this.emuStudioAuto = auto; this.noGUI = nogui; } @@ -81,9 +81,9 @@ public Optional getBoolean(String key) { return super.getBoolean(key); } - public static ApplicationConfig fromFile(Path file, boolean nogui, boolean auto) { - FileConfig config = FileConfig.of(file); + public static AppSettings fromFile(Path file, boolean nogui, boolean auto) { + FileConfig config = FileConfig.builder(file).autosave().concurrent().sync().build(); config.load(); - return new ApplicationConfig(config, nogui, auto); + return new AppSettings(config, nogui, auto); } } diff --git a/application/src/main/java/net/emustudio/application/settings/BasicSettingsImpl.java b/application/src/main/java/net/emustudio/application/settings/BasicSettingsImpl.java index 53c9fbfc6..62a91ab94 100644 --- a/application/src/main/java/net/emustudio/application/settings/BasicSettingsImpl.java +++ b/application/src/main/java/net/emustudio/application/settings/BasicSettingsImpl.java @@ -10,10 +10,12 @@ import java.util.Optional; public class BasicSettingsImpl implements BasicSettings { - protected final Config config; + private final Config config; + private final Runnable save; - public BasicSettingsImpl(Config config) { + public BasicSettingsImpl(Config config, Runnable save) { this.config = Objects.requireNonNull(config); + this.save = Objects.requireNonNull(save); } @Override @@ -24,6 +26,7 @@ public boolean contains(String key) { @Override public void remove(String key) throws CannotUpdateSettingException { config.remove(key); + save.run(); } @Override @@ -89,42 +92,49 @@ public List getArray(String key, List defaultValue) { @Override public void setString(String key, String value) { config.set(key, value); + save.run(); } @Override public void setBoolean(String key, boolean value) throws CannotUpdateSettingException { config.set(key, value); + save.run(); } @Override public void setInt(String key, int value) throws CannotUpdateSettingException { config.set(key, value); + save.run(); } @Override public void setLong(String key, long value) throws CannotUpdateSettingException { config.set(key, value); + save.run(); } @Override public void setDouble(String key, double value) throws CannotUpdateSettingException { config.set(key, value); + save.run(); } @Override public void setArray(String key, List value) throws CannotUpdateSettingException { config.set(key, value); + save.run(); } @Override public Optional getSubSettings(String key) { - return config.getOptional(key).map(BasicSettingsImpl::new); + return config.getOptional(key).map(c -> new BasicSettingsImpl(c, save)); } @Override public BasicSettings setSubSettings(String key) throws CannotUpdateSettingException { Config newConfig = config.createSubConfig(); config.set(key, newConfig); - return new BasicSettingsImpl(newConfig); + save.run(); + return new BasicSettingsImpl(newConfig, save); } } diff --git a/application/src/main/java/net/emustudio/application/settings/ComputerConfig.java b/application/src/main/java/net/emustudio/application/settings/ComputerConfig.java index 038ba3b1e..b337f96aa 100644 --- a/application/src/main/java/net/emustudio/application/settings/ComputerConfig.java +++ b/application/src/main/java/net/emustudio/application/settings/ComputerConfig.java @@ -40,6 +40,10 @@ public ComputerConfig(FileConfig config) { this.config = Objects.requireNonNull(config); } + public FileConfig getConfig() { + return config; + } + public void copyTo(ComputerConfig other) { getCompiler().ifPresent(other::setCompiler); getCPU().ifPresent(other::setCPU); @@ -69,7 +73,9 @@ public void setCompiler(PluginConfig compiler) { if (compiler == null) { config.remove(PLUGIN_TYPE.COMPILER.name()); } else { - config.set(PLUGIN_TYPE.COMPILER.name(), compiler.getConfig()); + Config sub = config.createSubConfig(); // to inherit autosave + sub.addAll(compiler.getConfig()); + config.set(PLUGIN_TYPE.COMPILER.name(), sub); } } @@ -82,7 +88,9 @@ public void setCPU(PluginConfig cpu) { if (cpu == null) { config.remove(PLUGIN_TYPE.CPU.name()); } else { - config.set(PLUGIN_TYPE.CPU.name(),cpu.getConfig()); + Config sub = config.createSubConfig(); + sub.addAll(cpu.getConfig()); + config.set(PLUGIN_TYPE.CPU.name(), sub); } } @@ -95,7 +103,9 @@ public void setMemory(PluginConfig memory) { if (memory == null) { config.remove(PLUGIN_TYPE.MEMORY.name()); } else { - config.set(PLUGIN_TYPE.MEMORY.name(), memory.getConfig()); + Config sub = config.createSubConfig(); + sub.addAll(memory.getConfig()); + config.set(PLUGIN_TYPE.MEMORY.name(), sub); } } @@ -109,7 +119,11 @@ public List getDevices() { } public void setDevices(List devices) { - List devicesConfig = devices.stream().map(PluginConfig::getConfig).collect(toList()); + List devicesConfig = devices.stream().map(d -> { + Config sub = config.createSubConfig(); + sub.addAll(d.getConfig()); + return sub; + }).collect(toList()); config.set(PLUGIN_TYPE.DEVICE.name(), devicesConfig); } @@ -122,7 +136,11 @@ public List getConnections() { } public void setConnections(List connections) { - List configs = connections.stream().map(PluginConnection::getConfig).collect(toList()); + List configs = connections.stream().map(c -> { + Config sub = config.createSubConfig(); + sub.addAll(c.getConfig()); + return sub; + }).collect(toList()); config.set("connections", configs); } @@ -137,7 +155,7 @@ public String toString() { } public static ComputerConfig load(Path configurationFile) { - FileConfig config = FileConfig.builder(configurationFile).concurrent().autosave().build(); + FileConfig config = FileConfig.builder(configurationFile).concurrent().sync().autosave().build(); config.load(); return new ComputerConfig(config); @@ -148,7 +166,7 @@ public static ComputerConfig create(String computerName, Path configurationFile) throw new IllegalArgumentException("Configuration already exists"); } Files.createFile(configurationFile); - FileConfig config = FileConfig.builder(configurationFile).concurrent().autosave().build(); + FileConfig config = FileConfig.builder(configurationFile).concurrent().sync().autosave().build(); config.set("name", computerName); return new ComputerConfig(config); diff --git a/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java b/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java index 6274629c6..1de55fc3b 100644 --- a/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java +++ b/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java @@ -92,11 +92,13 @@ public static Path getAbsolutePluginPath(String relativePluginPath, PLUGIN_TYPE public static List listPluginFiles(PLUGIN_TYPE pluginType) throws IOException { Path pluginBasePath = basePath.resolve(PLUGIN_SUBDIRS.get(pluginType)); - return Files.list(pluginBasePath) - .filter(p -> !Files.isDirectory(p) && Files.isReadable(p)) - .map(p -> p.getFileName().toString()) - .sorted() - .collect(Collectors.toList()); + try (Stream paths = Files.list(pluginBasePath)) { + return paths + .filter(p -> !Files.isDirectory(p) && Files.isReadable(p)) + .map(p -> p.getFileName().toString()) + .sorted() + .collect(Collectors.toList()); + } } public static ComputerConfig createConfiguration(String computerName) throws IOException { diff --git a/application/src/main/java/net/emustudio/application/settings/PluginConfig.java b/application/src/main/java/net/emustudio/application/settings/PluginConfig.java index 14b9c92db..2c660b342 100644 --- a/application/src/main/java/net/emustudio/application/settings/PluginConfig.java +++ b/application/src/main/java/net/emustudio/application/settings/PluginConfig.java @@ -79,8 +79,6 @@ public Config getConfig() { return config; } - - public static PluginConfig create(String id, PLUGIN_TYPE pluginType, String pluginName, String pluginFile, P schemaLocation, Config pluginSettings) { Config config = Config.inMemory(); diff --git a/application/src/main/java/net/emustudio/application/settings/PluginSettingsImpl.java b/application/src/main/java/net/emustudio/application/settings/PluginSettingsImpl.java index 87290677a..5fe3cfc9f 100644 --- a/application/src/main/java/net/emustudio/application/settings/PluginSettingsImpl.java +++ b/application/src/main/java/net/emustudio/application/settings/PluginSettingsImpl.java @@ -28,12 +28,11 @@ import java.util.Objects; import java.util.Optional; -public class PluginSettingsImpl implements PluginSettings { - private final Config config; - private final ApplicationConfig application; +public class PluginSettingsImpl extends BasicSettingsImpl implements PluginSettings { + private final AppSettings application; - public PluginSettingsImpl(Config pluginConfig, ApplicationConfig application) { - this.config = Objects.requireNonNull(pluginConfig); + public PluginSettingsImpl(Config pluginConfig, AppSettings application, Runnable save) { + super(pluginConfig, save); this.application = Objects.requireNonNull(application); } @@ -42,13 +41,13 @@ public boolean contains(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.contains(key.substring(EMUSTUDIO_PREFIX.length())); } - return config.contains(key); + return super.contains(key); } @Override public void remove(String key) { checkDoesNotStartWithEmuStudioPrefix(key); - config.remove(key); + super.remove(key); } @Override @@ -56,7 +55,7 @@ public Optional getString(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getString(key.substring(EMUSTUDIO_PREFIX.length())); } - return config.getOptional(key); + return super.getString(key); } @Override @@ -64,7 +63,7 @@ public String getString(String key, String defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getString(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); } - return config.getOptional(key).orElse(defaultValue); + return super.getString(key, defaultValue); } @Override @@ -72,7 +71,7 @@ public Optional getBoolean(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getBoolean(key.substring(EMUSTUDIO_PREFIX.length())); } - return config.getOptional(key); + return super.getBoolean(key); } @Override @@ -80,7 +79,7 @@ public boolean getBoolean(String key, boolean defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getBoolean(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); } - return config.getOptional(key).orElse(defaultValue); + return super.getBoolean(key, defaultValue); } @Override @@ -88,7 +87,7 @@ public Optional getInt(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getInt(key.substring(EMUSTUDIO_PREFIX.length())); } - return config.getOptional(key); + return super.getInt(key); } @Override @@ -96,7 +95,7 @@ public int getInt(String key, int defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getInt(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); } - return config.getOptionalInt(key).orElse(defaultValue); + return super.getInt(key, defaultValue); } @Override @@ -104,7 +103,7 @@ public Optional getLong(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getLong(key.substring(EMUSTUDIO_PREFIX.length())); } - return config.getOptional(key); + return super.getLong(key); } @Override @@ -112,7 +111,7 @@ public long getLong(String key, long defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getLong(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); } - return config.getOptionalLong(key).orElse(defaultValue); + return super.getLong(key, defaultValue); } @Override @@ -120,7 +119,7 @@ public Optional getDouble(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getDouble(key.substring(EMUSTUDIO_PREFIX.length())); } - return config.getOptional(key); + return super.getDouble(key); } @Override @@ -128,7 +127,7 @@ public double getDouble(String key, double defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getDouble(key.substring(EMUSTUDIO_PREFIX.length())).orElse(defaultValue); } - return config.getOptional(key).orElse(defaultValue); + return super.getDouble(key, defaultValue); } @Override @@ -136,7 +135,7 @@ public List getArray(String key) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getArray(key.substring(EMUSTUDIO_PREFIX.length())); } - return config.>getOptional(key).orElse(Collections.emptyList()); + return super.getArray(key, Collections.emptyList()); } @Override @@ -144,55 +143,55 @@ public List getArray(String key, List defaultValue) { if (key.startsWith(EMUSTUDIO_PREFIX)) { return application.getArray(key.substring(EMUSTUDIO_PREFIX.length())); } - return config.>getOptional(key).orElse(defaultValue); + return super.getArray(key, defaultValue); } @Override public void setString(String key, String value) { checkDoesNotStartWithEmuStudioPrefix(key); - config.set(key, value); + super.setString(key, value); } @Override public void setBoolean(String key, boolean value) { checkDoesNotStartWithEmuStudioPrefix(key); - config.set(key, value); + super.setBoolean(key, value); } @Override public void setInt(String key, int value) { checkDoesNotStartWithEmuStudioPrefix(key); - config.set(key, value); + super.setInt(key, value); } @Override public void setLong(String key, long value) { checkDoesNotStartWithEmuStudioPrefix(key); - config.set(key, value); + super.setLong(key, value); } @Override public void setDouble(String key, double value) { checkDoesNotStartWithEmuStudioPrefix(key); - config.set(key, value); + super.setDouble(key, value); } @Override public void setArray(String key, List value) { checkDoesNotStartWithEmuStudioPrefix(key); - config.set(key, value); + super.setArray(key, value); } @Override public Optional getSubSettings(String key) { - return config.getOptional(key).map(BasicSettingsImpl::new); + checkDoesNotStartWithEmuStudioPrefix(key); + return super.getSubSettings(key); } @Override public BasicSettings setSubSettings(String key) throws CannotUpdateSettingException { - Config newConfig = config.createSubConfig(); - config.set(key, newConfig); - return new BasicSettingsImpl(newConfig); + checkDoesNotStartWithEmuStudioPrefix(key); + return super.setSubSettings(key); } private void checkDoesNotStartWithEmuStudioPrefix(String key) { diff --git a/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java b/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java index 6f16ac9ce..0bd5212c3 100644 --- a/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java +++ b/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java @@ -89,7 +89,9 @@ public void initialize(ContextPoolImpl contextPool) throws PluginInitializationE pluginsByType.getOrDefault(PLUGIN_TYPE.DEVICE, Collections.emptyList()) ).flatMap(Collection::stream).collect(Collectors.toList()); - pluginsToInitialize.forEach(meta -> Unchecked.run(meta.pluginInstance::initialize)); + for (PluginMeta pluginMeta : pluginsToInitialize) { + pluginMeta.pluginInstance.initialize(); + } } public void reset() { @@ -140,13 +142,16 @@ public void close() { } public static VirtualComputer create(ComputerConfig computerConfig, ApplicationApi applicationApi, - ApplicationConfig applicationConfig) throws IOException, InvalidPluginException { - Map plugins = loadPlugins(computerConfig, applicationApi, applicationConfig); + AppSettings appSettings) throws IOException, InvalidPluginException { + Map plugins = loadPlugins(computerConfig, applicationApi, appSettings); return new VirtualComputer(computerConfig, plugins); } - private static Map loadPlugins(ComputerConfig computerConfig, ApplicationApi applicationApi, - ApplicationConfig applicationConfig) throws IOException, InvalidPluginException { + private static Map loadPlugins( + ComputerConfig computerConfig, + ApplicationApi applicationApi, + AppSettings appSettings + ) throws IOException, InvalidPluginException { List pluginConfigs = Stream.of( computerConfig.getCompiler(), computerConfig.getCPU(), @@ -165,13 +170,16 @@ private static Map loadPlugins(ComputerConfig computerConfig, PluginLoader pluginLoader = new PluginLoader(); List> pluginClasses = pluginLoader.loadPlugins(filesToLoad); - return constructPlugins(pluginClasses, pluginConfigs, applicationApi, applicationConfig); + return constructPlugins(pluginClasses, pluginConfigs, applicationApi, appSettings, computerConfig.getConfig()::save); } - private static Map constructPlugins(List> pluginClasses, - List pluginConfigs, ApplicationApi applicationApi, - ApplicationConfig applicationConfig) - throws InvalidPluginException { + private static Map constructPlugins( + List> pluginClasses, + List pluginConfigs, + ApplicationApi applicationApi, + AppSettings appSettings, + Runnable save + ) throws InvalidPluginException { Map plugins = new HashMap<>(); AtomicLong pluginIdCounter = new AtomicLong(); @@ -180,7 +188,7 @@ private static Map constructPlugins(List> plugin Class pluginClass = pluginClasses.get(i); PluginConfig pluginConfig = pluginConfigs.get(i); PluginSettings pluginSettings = new PluginSettingsImpl( - pluginConfig.getPluginSettings(), applicationConfig + pluginConfig.getPluginSettings(), appSettings, save ); if (!doesImplement(pluginClass, pluginInterfaces.get(pluginConfig.getPluginType()))) { diff --git a/application/src/test/java/net/emustudio/application/settings/ApplicationConfigTest.java b/application/src/test/java/net/emustudio/application/settings/AppSettingsTest.java similarity index 77% rename from application/src/test/java/net/emustudio/application/settings/ApplicationConfigTest.java rename to application/src/test/java/net/emustudio/application/settings/AppSettingsTest.java index 78da08654..23c948d75 100644 --- a/application/src/test/java/net/emustudio/application/settings/ApplicationConfigTest.java +++ b/application/src/test/java/net/emustudio/application/settings/AppSettingsTest.java @@ -30,21 +30,21 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -public class ApplicationConfigTest { +public class AppSettingsTest { @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @Test public void testContradictingNoGui() throws IOException { FileConfig config = FileConfig.of(temporaryFolder.newFile("emustudio.toml")); - config.set(ApplicationConfig.KEY_NOGUI, true); - config.set(ApplicationConfig.KEY_AUTO, true); + config.set(AppSettings.KEY_NOGUI, true); + config.set(AppSettings.KEY_AUTO, true); config.save(); - ApplicationConfig applicationConfig = new ApplicationConfig(config, false, false); + AppSettings appSettings = new AppSettings(config, false, false); - Optional noguiOpt = applicationConfig.getBoolean(ApplicationConfig.KEY_NOGUI); - Optional autoOpt = applicationConfig.getBoolean(ApplicationConfig.KEY_AUTO); + Optional noguiOpt = appSettings.getBoolean(AppSettings.KEY_NOGUI); + Optional autoOpt = appSettings.getBoolean(AppSettings.KEY_AUTO); assertTrue(noguiOpt.isPresent()); assertTrue(autoOpt.isPresent()); assertFalse(noguiOpt.get()); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java index 1f1702f42..9262438ab 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java @@ -21,6 +21,7 @@ import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; +import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings.MAP_CHAR; import java.util.ArrayList; import java.util.List; @@ -35,6 +36,9 @@ * A device is connected with SIO unit using special port. */ public class SioUnit implements AutoCloseable { + private final static byte DELETE_CHAR = 0x7F; + private final static byte BACKSPACE_CHAR = 0x08; + private final SioUnitSettings settings; private final UART uart; private final ControlChannel controlChannel = new ControlChannel(); @@ -102,17 +106,31 @@ class DataChannel implements DeviceContext { @Override public Byte readData() { - return uart.readBuffer(); + byte data = uart.readBuffer(); + data = settings.isClearOutputBit8() ? (byte) (data & 0x7F) : data; + return mapCharacter(data); } @Override public void writeData(Byte data) { - uart.sendToDevice(data); + data = settings.isInputToUpperCase() ? (byte) Character.toUpperCase((char) (data & 0xFF)) : data; + data = settings.isClearInputBit8() ? (byte) (data & 0x7F) : data; + uart.sendToDevice(mapCharacter(data)); } @Override public Class getDataType() { return Byte.class; } + + private byte mapCharacter(byte data) { + if (data == DELETE_CHAR) { + data = settings.getMapDeleteChar() == MAP_CHAR.BACKSPACE ? BACKSPACE_CHAR : DELETE_CHAR; + } + if (data == BACKSPACE_CHAR) { + data = settings.getMapBackspaceChar() == MAP_CHAR.DELETE ? DELETE_CHAR : BACKSPACE_CHAR; + } + return data; + } } } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java index 56a6d1443..fed7e7ba5 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java @@ -211,17 +211,19 @@ private void initComponents() { .addComponent(chkClearOutputBit8) .addComponent(chkInputToUpperCase) .addGroup(layoutGeneral.createSequentialGroup() - .addComponent(lblMapDeleteChar) - .addComponent(cmbMapDeleteChar)) - .addGroup(layoutGeneral.createSequentialGroup() - .addComponent(lblMapBackspaceChar) - .addComponent(cmbMapBackspaceChar)) - .addGroup(layoutGeneral.createSequentialGroup() - .addComponent(lblInputInterruptVector) - .addComponent(txtInputInterruptVector)) - .addGroup(layoutGeneral.createSequentialGroup() - .addComponent(lblOutputInterruptVector) - .addComponent(txtOutputInterruptVector))))); + .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) + .addComponent(lblMapDeleteChar) + .addComponent(lblMapBackspaceChar) + .addComponent(lblInputInterruptVector) + .addComponent(lblOutputInterruptVector)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) + .addComponent(cmbMapDeleteChar) + .addComponent(cmbMapBackspaceChar) + .addComponent(txtInputInterruptVector) + .addComponent(txtOutputInterruptVector)) + .addContainerGap())))); + layoutGeneral.setVerticalGroup( layoutDataPorts.createParallelGroup(Alignment.LEADING) .addGroup(layoutGeneral.createSequentialGroup() @@ -246,7 +248,8 @@ private void initComponents() { .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) .addComponent(lblOutputInterruptVector) - .addComponent(txtOutputInterruptVector)))); + .addComponent(txtOutputInterruptVector)) + .addContainerGap())); lblCaution.setText("Attach 88-SIO ports to one or more CPU ports." + @@ -336,6 +339,14 @@ private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) { dialogs.showError("Could not parse interrupt vector", "88-SIO Settings"); return; } + if (inputInterruptVector < 0 || inputInterruptVector > 7) { + dialogs.showError("Allowed range of input interrupt vector is 0-7"); + return; + } + if (outputInterruptVector < 0 || outputInterruptVector > 7) { + dialogs.showError("Allowed range of output interrupt vector is 0-7"); + return; + } settings.setStatusPorts(statusPortsModel.getAll()); settings.setDataPorts(dataPortsModel.getAll()); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java index 9e1443478..3bc6398b2 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java @@ -28,10 +28,7 @@ public class SioDeviceSettings { public SioDeviceSettings(PluginSettings settings) { this.guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); - this.sioUnit = settings - .getSubSettings("sio") - .map(SioUnitSettings::new) - .orElse(new SioUnitSettings(settings.setSubSettings("sio"))); + this.sioUnit = new SioUnitSettings(settings); } public boolean isGuiSupported() { diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java index 8d159145a..d0f153d04 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java @@ -19,18 +19,14 @@ package net.emustudio.plugins.device.mits88sio.settings; import net.emustudio.emulib.runtime.settings.BasicSettings; -import net.jcip.annotations.ThreadSafe; -import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.stream.Collectors; /** * Settings of one SIO unit */ -@ThreadSafe public class SioUnitSettings { private final static String KEY_STATUS_PORTS = "statusPorts"; private final static String KEY_DATA_PORTS = "dataPorts"; @@ -45,6 +41,17 @@ public class SioUnitSettings { private final BasicSettings settings; private final List observers = new CopyOnWriteArrayList<>(); + // for performance + private volatile boolean isClearInputBit8; + private volatile boolean isClearOutputBit8; + private volatile boolean inputToUpperCase; + private volatile MAP_CHAR mapDeleteChar; + private volatile MAP_CHAR mapBackspaceChar; + private volatile int inputInterruptVector; + private volatile int outputInterruptVector; + private volatile List statusPorts; + private volatile List dataPorts; + public enum MAP_CHAR { BACKSPACE, DELETE, @@ -65,75 +72,74 @@ public void clearObservers() { } public boolean isClearInputBit8() { - return settings.getBoolean(KEY_CLEAR_INPUT_BIT8, false); + return isClearInputBit8; } public void setClearInputBit8(boolean value) { + this.isClearInputBit8 = value; settings.setBoolean(KEY_CLEAR_INPUT_BIT8, value); notifySettingsChanged(); } public boolean isClearOutputBit8() { - return settings.getBoolean(KEY_CLEAR_OUTPUT_BIT8, false); + return isClearOutputBit8; } public void setClearOutputBit8(boolean value) { + this.isClearOutputBit8 = value; settings.setBoolean(KEY_CLEAR_OUTPUT_BIT8, value); notifySettingsChanged(); } public boolean isInputToUpperCase() { - return settings.getBoolean(KEY_INPUT_TO_UPPER_CASE, false); + return inputToUpperCase; } public void setInputToUpperCase(boolean value) { + this.inputToUpperCase = value; settings.setBoolean(KEY_INPUT_TO_UPPER_CASE, value); notifySettingsChanged(); } public MAP_CHAR getMapDeleteChar() { - return MAP_CHAR.valueOf(settings.getString(KEY_MAP_DELETE_CHAR, MAP_CHAR.UNCHANGED.name())); + return mapDeleteChar; } public void setMapDeleteChar(MAP_CHAR value) { + this.mapDeleteChar = value; settings.setString(KEY_MAP_DELETE_CHAR, value.name()); notifySettingsChanged(); } public MAP_CHAR getMapBackspaceChar() { - return MAP_CHAR.valueOf(settings.getString(KEY_MAP_BACKSPACE_CHAR, MAP_CHAR.UNCHANGED.name())); + return mapBackspaceChar; } public void setMapBackspaceChar(MAP_CHAR value) { + this.mapBackspaceChar = value; settings.setString(KEY_MAP_BACKSPACE_CHAR, value.name()); notifySettingsChanged(); } public List getStatusPorts() { - return Arrays.stream(settings.getString(KEY_STATUS_PORTS, "").split(",")) - .map(String::trim) - .filter(p -> !p.isEmpty()) - .map(Integer::decode) - .collect(Collectors.toList()); + return statusPorts; } public void setStatusPorts(List value) { + this.statusPorts = value; settings.setString(KEY_STATUS_PORTS, value.stream() .map(i -> "0x" + Integer.toHexString(i)) - .reduce((s, s2) -> s + ", " + s2) + .reduce((s, s2) -> s + "," + s2) .orElse("")); notifySettingsChanged(); } public List getDataPorts() { - return Arrays.stream(settings.getString(KEY_DATA_PORTS, "").split(",")) - .map(String::trim) - .filter(p -> !p.isEmpty()) - .map(Integer::decode) - .collect(Collectors.toList()); + return dataPorts; } public void setDataPorts(List value) { + this.dataPorts = value; settings.setString(KEY_DATA_PORTS, value.stream() .map(i -> "0x" + Integer.toHexString(i)) .reduce((s, s2) -> s + "," + s2) @@ -142,19 +148,21 @@ public void setDataPorts(List value) { } public int getInputInterruptVector() { - return settings.getInt(KEY_INPUT_INTERRUPT_VECTOR, 0); + return inputInterruptVector; } public void setInputInterruptVector(int vector) { + this.inputInterruptVector = vector; settings.setInt(KEY_INPUT_INTERRUPT_VECTOR, vector); notifySettingsChanged(); } public int getOutputInterruptVector() { - return settings.getInt(KEY_OUTPUT_INTERRUPT_VECTOR, 0); + return outputInterruptVector; } public void setOutputInterruptVector(int vector) { + this.outputInterruptVector = vector; settings.setInt(KEY_OUTPUT_INTERRUPT_VECTOR, vector); notifySettingsChanged(); } From 4c9f0367b4f08c399418d9d0a17882988fae4f67 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 3 Aug 2022 07:49:30 +0100 Subject: [PATCH 187/314] [#243] unit tests --- .../device/mits88sio/ControlChannel.java | 46 +++++++ .../plugins/device/mits88sio/DataChannel.java | 67 ++++++++++ .../plugins/device/mits88sio/SioUnit.java | 61 +-------- .../device/mits88sio/ControlChannelTest.java | 50 ++++++++ .../device/mits88sio/DataChannelTest.java | 120 ++++++++++++++++++ .../{SuiUnitTest.java => SioUnitTest.java} | 10 +- 6 files changed, 292 insertions(+), 62 deletions(-) create mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java create mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java create mode 100644 plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ControlChannelTest.java create mode 100644 plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java rename plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/{SuiUnitTest.java => SioUnitTest.java} (79%) diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java new file mode 100644 index 000000000..235fdbf1e --- /dev/null +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java @@ -0,0 +1,46 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.mits88sio; + +import net.emustudio.emulib.plugins.device.DeviceContext; + +import java.util.Objects; + +public class ControlChannel implements DeviceContext { + private final UART uart; + + public ControlChannel(UART uart) { + this.uart = Objects.requireNonNull(uart); + } + + @Override + public Byte readData() { + return uart.readStatus(); + } + + @Override + public void writeData(Byte data) { + uart.setStatus(data); + } + + @Override + public Class getDataType() { + return Byte.class; + } +} diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java new file mode 100644 index 000000000..c5d30e10a --- /dev/null +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java @@ -0,0 +1,67 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.mits88sio; + +import net.emustudio.emulib.plugins.device.DeviceContext; +import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; + +import java.util.Objects; + +public class DataChannel implements DeviceContext { + private final static byte DELETE_CHAR = 0x7F; + private final static byte BACKSPACE_CHAR = 0x08; + + private final SioUnitSettings settings; + private final UART uart; + + public DataChannel(SioUnitSettings settings, UART uart) { + this.settings = Objects.requireNonNull(settings); + this.uart = Objects.requireNonNull(uart); + } + + @Override + public Byte readData() { + byte data = uart.readBuffer(); + data = settings.isClearOutputBit8() ? (byte) (data & 0x7F) : data; + return mapCharacter(data); + } + + @Override + public void writeData(Byte data) { + data = settings.isInputToUpperCase() ? (byte) Character.toUpperCase((char) (data & 0xFF)) : data; + data = settings.isClearInputBit8() ? (byte) (data & 0x7F) : data; + uart.sendToDevice(mapCharacter(data)); + } + + @Override + public Class getDataType() { + return Byte.class; + } + + private byte mapCharacter(byte data) { + System.out.println(data); + if (data == DELETE_CHAR) { + data = settings.getMapDeleteChar() == SioUnitSettings.MAP_CHAR.BACKSPACE ? BACKSPACE_CHAR : DELETE_CHAR; + } + if (data == BACKSPACE_CHAR) { + data = settings.getMapBackspaceChar() == SioUnitSettings.MAP_CHAR.DELETE ? DELETE_CHAR : BACKSPACE_CHAR; + } + return data; + } +} diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java index 9262438ab..768ced6c4 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java @@ -18,10 +18,8 @@ */ package net.emustudio.plugins.device.mits88sio; -import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; -import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings.MAP_CHAR; import java.util.ArrayList; import java.util.List; @@ -36,13 +34,10 @@ * A device is connected with SIO unit using special port. */ public class SioUnit implements AutoCloseable { - private final static byte DELETE_CHAR = 0x7F; - private final static byte BACKSPACE_CHAR = 0x08; - private final SioUnitSettings settings; private final UART uart; - private final ControlChannel controlChannel = new ControlChannel(); - private final DataChannel dataChannel = new DataChannel(); + private final ControlChannel controlChannel; + private final DataChannel dataChannel; private final Context8080 cpu; private final List attachedStatusPorts = new ArrayList<>(); @@ -52,6 +47,8 @@ public SioUnit(SioUnitSettings settings, Context8080 cpu) { this.settings = Objects.requireNonNull(settings); this.cpu = Objects.requireNonNull(cpu); this.uart = new UART(cpu); + this.controlChannel = new ControlChannel(uart); + this.dataChannel = new DataChannel(settings, uart); } void reset(boolean guiSupported) { @@ -83,54 +80,4 @@ public void detach() { public void close() { detach(); } - - class ControlChannel implements DeviceContext { - - @Override - public Byte readData() { - return uart.readStatus(); - } - - @Override - public void writeData(Byte data) { - uart.setStatus(data); - } - - @Override - public Class getDataType() { - return Byte.class; - } - } - - class DataChannel implements DeviceContext { - - @Override - public Byte readData() { - byte data = uart.readBuffer(); - data = settings.isClearOutputBit8() ? (byte) (data & 0x7F) : data; - return mapCharacter(data); - } - - @Override - public void writeData(Byte data) { - data = settings.isInputToUpperCase() ? (byte) Character.toUpperCase((char) (data & 0xFF)) : data; - data = settings.isClearInputBit8() ? (byte) (data & 0x7F) : data; - uart.sendToDevice(mapCharacter(data)); - } - - @Override - public Class getDataType() { - return Byte.class; - } - - private byte mapCharacter(byte data) { - if (data == DELETE_CHAR) { - data = settings.getMapDeleteChar() == MAP_CHAR.BACKSPACE ? BACKSPACE_CHAR : DELETE_CHAR; - } - if (data == BACKSPACE_CHAR) { - data = settings.getMapBackspaceChar() == MAP_CHAR.DELETE ? DELETE_CHAR : BACKSPACE_CHAR; - } - return data; - } - } } diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ControlChannelTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ControlChannelTest.java new file mode 100644 index 000000000..661b0bb83 --- /dev/null +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ControlChannelTest.java @@ -0,0 +1,50 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.mits88sio; + +import org.junit.Test; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertEquals; + +public class ControlChannelTest { + + @Test + public void testReadReturnsStatus() { + UART uart = mock(UART.class); + expect(uart.readStatus()).andReturn((byte) 2).once(); + replay(uart); + + ControlChannel channel = new ControlChannel(uart); + assertEquals(2, channel.readData() & 0xFF); + } + + @Test + public void testWriteSetsStatus() { + UART uart = mock(UART.class); + uart.setStatus(eq((byte) 2)); + expectLastCall().once(); + replay(uart); + + ControlChannel channel = new ControlChannel(uart); + channel.writeData((byte) 2); + + verify(uart); + } +} diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java new file mode 100644 index 000000000..c2daadde1 --- /dev/null +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java @@ -0,0 +1,120 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.mits88sio; + +import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; +import org.junit.Test; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertEquals; + +public class DataChannelTest { + + @Test + public void testInputBit8Cleared() { + SioUnitSettings settings = niceMock(SioUnitSettings.class); + expect(settings.isClearInputBit8()).andReturn(true).anyTimes(); + expect(settings.getMapBackspaceChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); + expect(settings.getMapDeleteChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); + replay(settings); + + UART uart = mock(UART.class); + uart.sendToDevice(eq((byte) 0x7F)); + expectLastCall().once(); + replay(uart); + + DataChannel channel = new DataChannel(settings, uart); + channel.writeData((byte) 0xFF); + + verify(uart); + } + + @Test + public void testOutputBit8Cleared() { + SioUnitSettings settings = niceMock(SioUnitSettings.class); + expect(settings.isClearOutputBit8()).andReturn(true).anyTimes(); + expect(settings.getMapBackspaceChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); + expect(settings.getMapDeleteChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); + replay(settings); + + UART uart = mock(UART.class); + expect(uart.readBuffer()).andReturn((byte) 0xFF).once(); + replay(uart); + + DataChannel channel = new DataChannel(settings, uart); + + assertEquals(0x7F, channel.readData() & 0xFF); + verify(uart); + } + + @Test + public void testInputUpperCase() { + SioUnitSettings settings = niceMock(SioUnitSettings.class); + expect(settings.isInputToUpperCase()).andReturn(true).anyTimes(); + expect(settings.getMapBackspaceChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); + expect(settings.getMapDeleteChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); + replay(settings); + + UART uart = mock(UART.class); + uart.sendToDevice(eq((byte) 'A')); + expectLastCall().once(); + replay(uart); + + DataChannel channel = new DataChannel(settings, uart); + channel.writeData((byte) 'a'); + + verify(uart); + } + + @Test + public void testMapDeleteCharToBackspace() { + SioUnitSettings settings = niceMock(SioUnitSettings.class); + expect(settings.getMapBackspaceChar()).andReturn(SioUnitSettings.MAP_CHAR.DELETE).anyTimes(); + expect(settings.getMapDeleteChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); + replay(settings); + + UART uart = mock(UART.class); + uart.sendToDevice(eq((byte) 0x7F)); + expectLastCall().once(); + replay(uart); + + DataChannel channel = new DataChannel(settings, uart); + channel.writeData((byte) '\b'); + + verify(uart); + } + + @Test + public void testMapBackspaceCharToDelete() { + SioUnitSettings settings = niceMock(SioUnitSettings.class); + expect(settings.getMapBackspaceChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); + expect(settings.getMapDeleteChar()).andReturn(SioUnitSettings.MAP_CHAR.BACKSPACE).anyTimes(); + replay(settings); + + UART uart = mock(UART.class); + uart.sendToDevice(eq((byte) '\b')); + expectLastCall().once(); + replay(uart); + + DataChannel channel = new DataChannel(settings, uart); + channel.writeData((byte) 0x7F); + + verify(uart); + } +} diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SuiUnitTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java similarity index 79% rename from plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SuiUnitTest.java rename to plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java index 8b39b8221..83bec3904 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SuiUnitTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java @@ -26,7 +26,7 @@ import static org.easymock.EasyMock.*; -public class SuiUnitTest { +public class SioUnitTest { @Test public void testCpuPortsAreReattached() { @@ -36,10 +36,10 @@ public void testCpuPortsAreReattached() { replay(s); Context8080 cpu = mock(Context8080.class); - expect(cpu.attachDevice(anyObject(SioUnit.ControlChannel.class), eq(1))).andReturn(true).times(2); - expect(cpu.attachDevice(anyObject(SioUnit.ControlChannel.class), eq(2))).andReturn(true).times(2); - expect(cpu.attachDevice(anyObject(SioUnit.DataChannel.class), eq(4))).andReturn(true).times(2); - expect(cpu.attachDevice(anyObject(SioUnit.DataChannel.class), eq(5))).andReturn(true).times(2); + expect(cpu.attachDevice(anyObject(ControlChannel.class), eq(1))).andReturn(true).times(2); + expect(cpu.attachDevice(anyObject(ControlChannel.class), eq(2))).andReturn(true).times(2); + expect(cpu.attachDevice(anyObject(DataChannel.class), eq(4))).andReturn(true).times(2); + expect(cpu.attachDevice(anyObject(DataChannel.class), eq(5))).andReturn(true).times(2); cpu.detachDevice(1); expectLastCall().times(2); // reattach + close() From 292c3f60afad840905a016737de6c9338a4333b9 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 3 Aug 2022 10:22:07 +0100 Subject: [PATCH 188/314] [#243] 88-sio: initialize array on empty settings --- .../plugins/device/mits88sio/settings/SioUnitSettings.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java index d0f153d04..4cfd813af 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java @@ -20,6 +20,7 @@ import net.emustudio.emulib.runtime.settings.BasicSettings; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; @@ -49,8 +50,8 @@ public class SioUnitSettings { private volatile MAP_CHAR mapBackspaceChar; private volatile int inputInterruptVector; private volatile int outputInterruptVector; - private volatile List statusPorts; - private volatile List dataPorts; + private volatile List statusPorts = Collections.emptyList(); + private volatile List dataPorts = Collections.emptyList(); public enum MAP_CHAR { BACKSPACE, From 2d78222a4d59c14a2f69a47f43b2b05ad1d59efa Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 18 Aug 2022 08:08:52 +0100 Subject: [PATCH 189/314] [#260] Fix Z80 instructions + added z80 boot loaders + 88-dcdd sector true alteration --- .../examples/altair8800/boot/88-disk-rom.asm | 175 +++++ .../boot/{boot.bin => 88-disk-rom.bin} | Bin .../files/examples/altair8800/boot/cdbl.asm | 611 +++++++++++++++++ .../files/examples/altair8800/boot/dbl.bin | Bin 0 -> 256 bytes .../examples/altair8800/boot/mdbl-simh.asm | 147 ++++ .../altair8800/boot/{mboot.bin => mdbl.bin} | Bin .../cmdline/AutomationCommand.java | 2 +- .../application/emulation/Automation.java | 2 +- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 639 +++++++----------- .../plugins/cpu/zilogZ80/EmulatorTables.java | 100 --- .../plugins/cpu/zilogZ80/ArithmeticTest.java | 27 +- .../plugins/cpu/zilogZ80/LogicTest.java | 104 ++- .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 58 +- .../plugins/device/mits88dcdd/DeviceImpl.java | 15 +- .../device/mits88dcdd/drive/Drive.java | 20 +- .../plugins/device/mits88dcdd/DriveTest.java | 4 + .../plugins/device/mits88sio/DataChannel.java | 1 - .../plugins/device/mits88sio/DeviceImpl.java | 29 +- .../mits88sio/settings/SioDeviceSettings.java | 41 -- .../mits88sio/settings/SioUnitSettings.java | 28 +- .../device/abstracttape/AbstractTape.java | 15 +- .../plugins/device/adm3a/DeviceImpl.java | 5 + .../device/adm3a/TerminalSettings.java | 6 +- .../device/adm3a/interaction/Cursor.java | 3 + .../device/adm3a/interaction/Display.java | 12 + .../device/brainduck/terminal/DeviceImpl.java | 13 +- .../plugins/device/simh/DeviceImpl.java | 7 +- .../plugins/device/simh/PseudoContext.java | 6 +- .../device/simh/commands/GetClockCPM3.java | 2 +- .../device/simh/commands/GetClockZSDOS.java | 3 +- .../device/ssem/display/DeviceImpl.java | 11 +- 31 files changed, 1465 insertions(+), 621 deletions(-) create mode 100644 application/src/main/files/examples/altair8800/boot/88-disk-rom.asm rename application/src/main/files/examples/altair8800/boot/{boot.bin => 88-disk-rom.bin} (100%) create mode 100644 application/src/main/files/examples/altair8800/boot/cdbl.asm create mode 100644 application/src/main/files/examples/altair8800/boot/dbl.bin create mode 100644 application/src/main/files/examples/altair8800/boot/mdbl-simh.asm rename application/src/main/files/examples/altair8800/boot/{mboot.bin => mdbl.bin} (100%) delete mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java diff --git a/application/src/main/files/examples/altair8800/boot/88-disk-rom.asm b/application/src/main/files/examples/altair8800/boot/88-disk-rom.asm new file mode 100644 index 000000000..276ee8c82 --- /dev/null +++ b/application/src/main/files/examples/altair8800/boot/88-disk-rom.asm @@ -0,0 +1,175 @@ +;THE ALTAIR 88-DSK ROM MOVES THIS CODE TO 4C00H THEN +; JUMPS TO IT. POSSIBLE ERRORS ARE: +;C CRC ON DISK DOESN'T MATCH CALCULATED CRC +;M MEMORY ERROR READ/BACK FROM MEMORY DOESN'T MATCH +; WRITE TO MEMORY (NO RAM, BAD RAM, OR WPROT) +;O OVERFLOW OR OUT OF MEM CAUSED BY TRYING TO LOAD BEYOND +; FF00 OR BAD "LOAD LIMIT BYTES" ON DISK. + +ORG 0FF00h + +; RELOCATE $E6 BYTES REMAINING OF LOADER TO 4C00 (19456D) +LXI H,4C00h +LXI D,here ;0FF18h +MVI C,0E6h +XFF08: LDAX D +MOV M,A +INX D +INX H +DCR C +JNZ XFF08 +JMP 4C00h + +here: +;ORG 4C00h +DI ;DISABLE INTERRUPTS +LXI SP,4D62h ;LOAD STACK POINTER +XRA A ;ZERO IN A +OUT 08h ;SELECT DRIVE 0 +MVI A,04h ;HEAD DOWN CMD +OUT 09h ;SEND HEAD DOWN +JMP TTRK0 ;GO TEST FOR TRACK ZERO +TMVOK: IN 08h ;GET STATUS +ANI 02h ;TEST FOR MOVE OK +JNZ TMVOK ;JMP MOVE NOT OK +MVI A,02h ;STEP OUT CMD +OUT 09h ;SEND STEP OUT +TTRK0: IN 08h ;GET STATUS +ANI 40h ;TEST FOR TRACK ZERO +JNZ TMVOK ;JMP NOT TRACK ZERO +LXI D,0000 ;DE->0000H +NXTTK: MVI B,00 ;B=0 +THDDN: IN 08h ;GET STATUS +ANI 04h ;TEST FOR HEAD DOWN +JNZ THDDN ;JMP NOT HEAD DOWN + +;SEEK TO SECTOR IN B +NXTSEC: MVI A,10h ;A=10H 16D RETRY COUNT +RETRY: PUSH PSW ;SAVE RETRY COUNT +PUSH D ;NXTMEM +PUSH B ;B=SECTOR +PUSH D ;NXTMEM +LXI D,8086h ;D=80(UNUSED?) E=128=COUNT +LXI H,VAR1 ;M=POINTER TO INBUFFER +TSECT: IN 09h ;GET SECTOR# UNDER HEAD AND STATUS +RAR ;TEST SECTOR TRUE +JC TSECT ;JMP TSECT IF NOT TRUE +ANI 1Fh ;AND SECTOR MASK 31D +CMP B ;DESIRED SECTOR +JNZ TSECT ;JMP TSECT IF NOT EQUAL + +;READ 134 BYTES TWO AT A TIME INTO INBUFFER +TRDOK: IN 08h ;GET STATUS +ORA A ;SET FLAGS TEST FOR READ OK +JM TRDOK ;JMP TRDOK IF NOT READ OK +IN 0Ah ;GET DATA BYTE1 +MOV M,A ;MOVE BYTE TO INBUFF +INX H ;BUMP INPOINTER +DCR E ;DECREMENT COUNT +JZ MVBYTS ;JMP MVBYTS IF DONE +DCR E ;DEC COUNT +IN 0Ah ;GET DATA BYTE2 +MOV M,A ;MOVE TO INBUFF +INX H ;INCREMENT POINTER +JNZ TRDOK ;JMP TRDOK IF COUNT IN E IS NOT ZERO + +;MOVE 128 DATA BYTES FROM BUFF TO MEMORY MAKE A CRC +MVBYTS: POP H ;HL (M)=0000H FIRST TIME +LXI D,VAR3 ;DE POINTS TO BUFFER + 3 +LXI B,0080h ;B=0=CRC C=128 COUNT +MVBYT2: LDAX D ;GET BYTE FROM BUFFER +MOV M,A ;MOVE TO DESTINATION +CMP M ;CHECK FOR MEMORY PROBLEM +JNZ MERROR ;JMP MERROR IF PROBLEM +ADD B ;MAKE A CRC +MOV B,A ;SAVE IN B +INX D ;INC SRC +INX H ;INC DEST +DCR C ;DEC COUNT +JNZ MVBYT2 ;JMP MVBYT2 UNTIL COUNT = 0 + +;CHECK CRC +LDAX D ;DE POINTS TO BUFFER + 131 +CPI 0FFh ;COMPARE THAT BYTE TO 255 +JNZ FFERR ;JMP FFERR IF NOT EQUAL +INX D ;INC DE POINTS TO BUFF+132 +LDAX D ;GET THAT BYTE +CMP B ;COMPARE TO CRC +FFERR: POP B ;B=SECTOR +XCHG ;DE->NEXT DEST HL->BUFF+132 +JNZ CRCERR ;CRC ERROR GO CRCERR + +;CHECK FOR OUT OF MEMORY CHECK DONE LOADING +POP PSW ;0000H FIRST TIME +POP PSW ;ACC=16 +LHLD VAR2 ;L=BUFF+1 H=BUFF+2 +PUSH D ;SAVE NEXT DEST 0080 FIRST TIME +LXI D,0FF00h ;DE->BOOTROM(END OF MEMORY) +CALL SUB1 ;COMPARE1 FF00H,HL OUT OF MEMORY (HL GREATER THAN FF00H) +POP D ; NEXT DEST +JC OERROR ;JMP 'O'UT OF RAM ERROR (HL GREATER THAN FFOOH) +CALL SUB1 ;COMPARE2 DE,HL ARE WE DONE LOADING? +JNC EXIT1 ;IF NO CARRY (HL <= NEXT DEST)WE'RE DONE GO EXECUTE + +;CALCULATE NEXT SECTOR AND TRACK +INR B ;ADD 2 TO SECTOR# +INR B ; +MOV A,B ;DESIRED NEXT SECTORA +CPI 20h ;TEST IF SECTORA LESS THAN 32 +JC NXTSEC ;IF LESS GO GET IT +MVI B,01h ; IF NOT LESS MAKE DESIRED SECTORB=1 +JZ NXTSEC ;IF SECTORA EQUALED 32 GO GET SECTORB=1 +LOOP7: IN 08h ;ELSE GET STATUS +ANI 02h ;TEST MOVE OK +JNZ LOOP7 ;UNTIL MOVE IS OK +MVI A,01h ;STEP IN CMD +OUT 09h ;SEND STEP IN CMD +JMP NXTTK ;START LOADING FROM NEXT TRACK SECTORB=0 + +;LOAD THE EVEN SECTORS ON A TRACK FIRST +;THEN THE ODD SECTORS + +;DONE +EXIT1: MVI A,80h ; +OUT 08h ;CLEAR CONTROLLER +JMP 0000h ;GO + +;CRC ERROR RETRY PSW TIMES +CRCERR: POP D +POP PSW ; +DCR A ;DECREMENT RETRY COUNT +JNZ RETRY ;IF NOT 0 GO RETRY + +;CLEAR CONTROLLER SEND TO CONSOLE ERROR MESSAGE +MVI A,43h ;ELSE LOAD A WITH CHAR 'C'RC ERROR +DB 01h +;4CBD LXI B,4F3E ;GARBAGE - SKIP TRICK BD-BF +OERROR: MVI A,4Fh ; LOAD A WITH CHAR 'O'VERFLOW +DB 01h +;4CC0 LXI B,4D3E ;GARBAGE - SKIP TRICK C0-C2 +MERROR: MVI A,4D ; LOAD A WITH CHAR 'M'EMORY ERROR +MOV B,A ;SAVE CHAR +MVI A,80h ;CLEAR CONTROLLER +OUT 08h ;SEND CLEAR +MOV A,B ;GET CHAR + +CONOUT: OUT 11h ;SEND ERROR CHAR TO CONSOLE + JMP CONOUT ;OVER AND OVER AND OVER... + +;TEST FOR OVERFLOW, TEST LOAD LIMIT, COMPARE HL,DE +SUB1: MOV A,D ; +CMP H ; +RNZ ; +MOV A,E ; +CMP L ; +RET + +;BEGINNING OF IN BUFFER +VAR1: DB 84h ;ADD H +VAR2: DB 0 ;NOP + DB 4Ch ;MOV C,H + +VAR3: DB 24h ;INR H + DB 0D6h, 56h ;SUI $56 + DB 16h, 0 ;MVI D,0 + NOP ; DATA TRUNCATED diff --git a/application/src/main/files/examples/altair8800/boot/boot.bin b/application/src/main/files/examples/altair8800/boot/88-disk-rom.bin similarity index 100% rename from application/src/main/files/examples/altair8800/boot/boot.bin rename to application/src/main/files/examples/altair8800/boot/88-disk-rom.bin diff --git a/application/src/main/files/examples/altair8800/boot/cdbl.asm b/application/src/main/files/examples/altair8800/boot/cdbl.asm new file mode 100644 index 000000000..f6f275b6b --- /dev/null +++ b/application/src/main/files/examples/altair8800/boot/cdbl.asm @@ -0,0 +1,611 @@ +;============================================================== +;= CDBL - Combo Disk Boot Loader ROM = +;= For the Altair 88-DCDD 8" disk system and = +;= the Altair 88-MDS Minidisk system = +;= By Martin Eberhard = +;= = +;= CDBL loads software (e.g. Altair Disk BASIC) from an = +;= Altair 88-DCDD 8" disk or an 88-MDS 5-1/4" minidisk, = +;= automatically detecting which kind of drive is attached. = +;============================================================== +;= NOTES = +;= = +;= Like DBL and MDBL, CDBL fits in one (256-byte) 1702A = +;= EPROM and execution begins at address FF00h. However, = +;= since version 3.00, the PROM is position independent = +;= and can run at most any 256 byte boundary. = +;= = +;= Because of the slow 1702A EPROM access time, and because = +;= some versions of MITS's 8800b Turnkey Module disable PROM = +;= when any IN instruction is executed, CDBL copies itself = +;= into RAM at 4C00h (RAMADR), and executes there. CDBL = +;= therefore requres 512 bytes of 0-wait state RAM, starting = +;= at RAMADR. = +;= = +;= Minidisks have 16 sectors/track, numbered 0 through 15. = +;= 8" disks have 32 sectors/track, numbered 0 through 31. = +;= CDBL figures out which kind of disk drive is attached, = +;= based on the existance of sector number 16. = +;= = +;= ALTAIR DISK SECTOR FORMAT (FOR BOOT SECTORS) = +;= = +;= BYTE(s) FUNCTION BUFFER ADDRESS = +;= 0 Track number+80h (sync) RAMADR+7Bh = +;= 1 File size low byte RAMADR+7Ch = +;= 2 File size High Byte RAMADR+7Dh = +;= 3-130 Sector data RAMADR+7Eh to RAMADR+FDh = +;= 131 Marker Byte (0FFh) RAMADR+FEh = +;= 132 Checksum RAMADR+FFh = +;= 133-136 Spare not read = +;= = +;= Each sector header contains a 16-bit file-size value: = +;= this many bytes (rounded up to an exact sector) are read = +;= from the disk and written to RAM, starting at address 0. = +;= When done (assuming no errors), CDBL then jumps to = +;= address 0 (DMAADR) to execute the loaded code. = +;= = +;= Sectors are interleaved 2:1. CDBL reads the even sectors = +;= on each track first (starting with track 0, sector 0) = +;= followed by the odd sectors (starting with sector 1), = +;= continuing through the interleaved sectors of each track = +;= until the specified number of bytes have been read. = +;= = +;= CDBL first reads each sector (including the actual data = +;= payload, as well as the 3 header and the first 2 trailer = +;= bytes) from disk into the RAM buffer (SECBUF). Next, CDBL = +;= checks to see if this sector would overwrite the RAM = +;= portion of CDBL, and aborts with an 'O' error if so. It = +;= then copies the data payload portion from the buffer to = +;= its final RAM location, calculating the checksum along the = +;= way. During the copy, each byte is read back, to verify = +;= correct writes. Any write-verify failure will immediately = +;= abort the load with an 'M' error. = +;= = +;= Any disk read error (a checksum error or an incorrect = +;= marker byte) will cause a retry of that sector read. After = +;= 16 retries on the same sector, CDBL will abort the load = +;= with a 'C' error. = +;= = +;= If the load aborts with any error, then CDBL will turn on = +;= the INTE LED on the front panel (as an indicator), write = +;= the error code ('C', 'M', or 'O') to RAM address 0, write = +;= the offending memory address to RAM addresses 1 and 2, and = +;= then hang forever in a loop, printing the error code to = +;= all known Altair Terminal output ports. = +;============================================================== +;= REVISION HISTORY = +;= = +;= 1.00 05May2014 M.Eberhard = +;= Combined MDBL and DBLme code, with assembly options to = +;= create exactly both of these boot loaders = +;= 2.00 08May2014 M.Eberhard = +;= Restructure and squeeze the code. Automatic 8"/Minidisk = +;= detection. Select boot disk from the sense switches. = +;= Improve track 0 seek by waiting for -MVHEAD before = +;= testing TRACK0. Detect memory overrun errors. Verify = +;= copy of CDBL code into RAM. = +;= 2.01 15May2014 M.Eberhard = +;= Step in once before seeking track 0. Restart 6.4 Sec = +;= motor shutoff timer on retries. = +;= 2.02 04Jun2014 M. Eberhard = +;= Eliminate booting from other than drive 0 because Basic = +;= and Burcon CP/M just load a 2-sector boot loader, and = +;= that boot loader loads the rest, always from drive 0. = +;= 2.03 17Jan2015 M. Douglas = +;= Force 43ms minimum delay when changing seek direction = +;= to meet/exceed 8" drive requirements. = +;= 2.04 12Mar2015 M. Douglas = +;= Change 2SIO init constant (ACINIT) from 21h (7E2, xmit = +;= interrupts on) to 11h (8N2) = +;= 2.05 11Jan2016 M. Eberhard = +;= No IN or OUT instructions until code is moved to RAM = +;= (for compatibility with some Turnkey Modules). This = +;= increased the RAM footprint from 256 to 512 bytes. Also = +;= fixed a bug when reporting overlay errors. = +;= 3.00 12Jan2016 M. Douglas = +;= Make the PROM position independent by making the = +;= routine that copies PROM to RAM position independent. = +;============================================================== + +;----------------- +; Disk Parameters +;----------------- +BPS equ 128 ;data bytes/sector +MDSPT equ 16 ;Minidisk sectors/track + +;this code assumes SPT for 8" +;disks = MDSPT * 2. +HDRSIZ equ 3 ;header bytes before data +TLRSIZ equ 2 ;trailer bytes read after data + +SECSIZ equ BPS+HDRSIZ+TLRSIZ ;total bytes/sector + +RETRYS equ 16 ;max retries per sector + +;-------------------------------------------------------------- +; Memory Parameters. To keep code short, several assumptions +; about these values are embedded in the code: +; 1) RAMADR and PROM low address byte = 0 +; 2) The address of the last byte of SECBUF (the SECSIZ-sized +; sector buffer) must be XXFF. +; 3) The ls bit of the high byte of RAMADR must be 0 +; 4) The value of DMAADR is assumed to be 0 +;-------------------------------------------------------------- +RAMADR equ 4C00H ;Address for code copied to RAM +SECBUF equ RAMADR+512-SECSIZ +STACK equ SECBUF ;grows down from here +DMAADR equ 0 ;Disk load/execution address + +;---------------------------------------------- +; Addresses of sector components within SECBUF +;---------------------------------------------- +SFSIZE equ SECBUF+1 ;address of file size +SDATA equ SECBUF+HDRSIZ ;address of sector data +SMARKR equ SDATA+BPS ;address of marker byte +SCKSUM equ SMARKR+1 ;address of checksum byte + +;---------------- +; 88-SIO Equates +;---------------- +SIOCTL EQU 00 ;Control +SIOSTA EQU 00 ;Status +SIODAT EQU 01 ;Rx/Tx Data + +;----------------------------------------------- +; 88-2SIO's port 0, Turnkey Module, and 88-UIO +; Equates (all based on the Motorola 6850 ACIA) +;----------------------------------------------- +ACCTRL equ 10h ;ACIA Control output port +ACSTAT equ 10h ;ACIA Status input port +ACDATA equ 11h ;ACIA Tx/Rx Data register + +ACRST equ 03h ;Master reset +ACINIT equ 11h ;/16, 8bit, No Parity, 2Stops + +;---------------- +; 88-PIO Equates +;---------------- +PIOCTL EQU 04 ;Control +PIOSTA EQU 04 ;Status +PIODAT EQU 05 ;Tx/Rx Data + +;----------------- +; 88-4PIO equates +;----------------- +P4CA0 equ 20h ;Port 0 Section A Ctrl/Status +P4DA0 equ 21h ;Port 0 Section A Data +P4CB0 equ 22h ;Port 0 Section B Ctrl/Status +P4DB0 equ 23h ;Port 0 Section B Data + +P4CINI equ 2Ch ;Control/status initialization + +;---------------------------------------------------------- +; Altair 8800 Disk Controller Equates (These are the same +; for the 88-DCDD controller and the 88-MDS controller.) +;---------------------------------------------------------- +DENABL equ 08H ;Drive Enable output +DDISBL equ 80h ;disable disk controller +DSTAT equ 08H ;Status input (active low) +ENWDAT equ 01h ;-Enter Write Data +MVHEAD equ 02h ;-Move Head OK +HDSTAT equ 04h ;-Head Status +DRVRDY equ 08h ;-Drive Ready +INTSTA equ 20h ;-Interrupts Enabled +TRACK0 equ 40h ;-Track 0 detected +NRDA equ 80h ;-New Read Data Available + +DCTRL equ 09h ;Drive Control output +STEPIN equ 01H ;Step-In +STPOUT equ 02H ;Step-Out +HDLOAD equ 04H ;8" disk: load head + +;Minidisk: restart 6.4 S timer +HDUNLD equ 08h ;unload head (8" only) +IENABL equ 10h ;Enable sector interrupt +IDSABL equ 20h ;Disable interrupts +WENABL equ 80h ;Enable drive write circuits + +DSECTR equ 09h ;Sector Position input +SVALID equ 01h ;Sector Valid (1st 30 uS of sector pulse) +SECMSK equ 3Eh ;Sector mask for MDSEC + +DDATA equ 0Ah ;Disk Data (input/output) + +;---------------------------- +; Single-byte error messages +;---------------------------- +CERMSG equ 'C' ;checksum/marker byte error +MERMSG equ 'M' ;memory write verify error +OERMSG equ 'O' ;Memory overlay error message + +;============================================================== +ORG RAMADR ;assemble at dest RAM address +;============================================================== + +di ;turn off INTE (no error yet) + +;-------------------------------------------------------------- +; Copy the PROM content to RAM for execution. This copy routine +; is position independent so the boot PROM can be at most any +; address. The LSB of the PROM address and RAMADR must be 0. +;-------------------------------------------------------------- +lxi d,MLOOP ;DE->MLOOP in RAM + +lxi sp,STACK +lxi h,0E9E1h ;H=PCHL,L=POP H +push h ;POP H, PCHL at STACK-2, STACK-1 +call STACK-2 ;addr of MLOOP in HL and stack RAM + +MLOOP: dcx sp ;point SP to MLOOP address +dcx sp ; in stack memory + +mov a,m ;get next EPROM byte +stax d ;store it in RAM + +inr e ;bump pointers +inr l +rnz ;copy to end of 256 byte page + +jmp RAMIMG ;jump to code now in RAM + +; e=l=0 + +;============================================================== +; RAM Code Image +; All of the following code gets copied into RAM at RAMADR, +; and run there. +;============================================================== +RAMIMG: + +;------------------------------------------------------------- +; Wait for user to insert a diskette into the drive 0, and +; then load that drive's head. Do this first so that the disk +; has plenty of time to settle. Note that a minidisk will +; always report that it is ready. Minidisks will hang (later +; on) waiting for sector 0F, until a few seconds after the +; user inserts a disk. +; +; On Entry: +; l = 0 +;------------------------------------------------------------- + +WAITEN: xra a ;boot from disk 0 +out DENABL ;enable disk 0 +in DSTAT ;Read drive status +ani DRVRDY ;Diskette in drive? +jnz WAITEN ;no: wait for drive ready + +mvi a,HDLOAD ;Load 8" disk head, or enable +out DCTRL ;..minidisk for 6.4 Sec + +;------------------------------------------------------- +; Step in once, then step out until track 0 is detected +; On Exit: b=0 +;------------------------------------------------------- +lxi b,20000/12 ;20 mS delay 1st time thru +mvi a,STEPIN ;step in once first + +SKTRK0: out DCTRL ;issue step command + +; The first time through, delay at least 20ms to force a +; minimum 43 ms step wait instead of 10ms. This meets +; the 8" spec for changing seek direction. The minidisk +; step time is always 50ms. + +DELAY: dcx b ;(5) +mov a,b ;(5) +ora c ;(4) +jnz DELAY ;(10)12 uS/pass + +inr c ;from now on, the above loop goes 1 time. +WSTEP: in DSTAT ;wait for step to complete +rrc ;put MVHEAD bit in carry +rrc ;is the servo stable? +jc WSTEP ;no: wait for servo to settle + +ani TRACK0/4 ;Are we at track 00? +mvi a,STPOUT ;STEP-OUT command +jnz SKTRK0 ;no: step out another track + +;Exit with b=0 +;-------------------------------------------------------- +; Determine if this is an 8" disk or a minidisk, and set +; c to the correct sectors/track for the detected disk. +; An 8" disk has 20h sectors, numbered 0-1Fh. A minidisk +; has 10h sectors, numbered 0-0Fh. +;-------------------------------------------------------- + +; wait for the highest minidisk sector, sector number 0Fh + +CKDSK1: in DSECTR ;Read the sector position + +ani SECMSK+SVALID ;Mask sector bits, and hunt +cpi (MDSPT-1)*2 ;..for minidisk last sector +jnz CKDSK1 ;..only while SVALID is 0 + +; wait for this sector to pass + +CKDSK2: in DSECTR ;Read the sector position +rrc ;wait for invalid sector +jnc CKDSK2 + +; wait for and get the next sector number + +CKDSK3: in DSECTR ;Read the sector position +rrc ;put SVALID in carry +jc CKDSK3 ;wait for sector to be valid + +; The next sector after sector 0Fh will be 0 for a minidisk, +; and 10h for an 8" disk. Adding MDSPT (10h) to that value +; will compute c=10h (for minidisks) or c=20h (for 8" disks). + +ani SECMSK/2 ;Mask sector bits +adi MDSPT ;compute SPT +mov c,a ;..and save SPT in c + +;------------------------------------------------------------ +; Initialize the ACIA (2SIO port 0/Turnkey/UIO). Do this +; late in the initialization, so that e.g. the 'B' character +; from UBMON won't get eaten by resetting the ACIA. +;------------------------------------------------------------ +mvi a,ACRST ;reset first +out ACCTRL + +mvi a,ACINIT ;then initialize +out ACCTRL + +;--------------------- +; Initialize the 4PIO +;--------------------- +xra a +out P4CB0 ;Port 0 section B is output +cma ;All output bits high +out P4DB0 +mvi a,P4CINI ;set up handshake bits +out P4CB0 + +;-------------------------------------------- +; Set up to load +; On Entry: +; b = 0 (initial sector number) +; c = SPT (for either minidisk or 8" disk) +; l = 0 (part of DMA address) +;-------------------------------------------- +mov h,l ;initial DMA address=0000 + +;-------------------------------------------------------- +; Read current sector over and over, until either the +; checksum is right, or there have been too many retries +; b = current sector number +; c = sectors/track for this kind of disk +; hl = current DMA address +;-------------------------------------------------------- +NXTSEC: mvi a,RETRYS ;(7)Initialize sector retries + +;------------------------------------------------------ +; Begin Sector Read +; a = Remaining retries for this sector +; b = Current sector number +; c = Sectors/track for this kind of disk +; hl = current DMA address +;------------------------------------------------------ +RDSECT: lxi sp,STACK ;(10)(re)initialize the stack +push psw ;(11)Remaining retry count + +;----------------------------------------------------------- +; Sector Read: Step 1. Hunt for sector specified in b. Data +; will become avaiable 250 uS after -SVALID +; goes low. -SVALID is low for 30 uS. +;----------------------------------------------------------- +FNDSEC: in DSECTR ;(10)Read the sector position + +ani SECMSK+SVALID ;(7)yes: Mask sector bits +;..along with -SVALID bit +rrc ;(4)sector bits to bits <4:0> +cmp b ;(4)Found the desired sector +;..with -SVALID low? +jnz FNDSEC ;(10)no: wait for it + +;------------------------------------------------------------ +; Test for DMA address that would overwrite this RAM code +; or the next page (which contains the sector buffer stack) +; Do this here, while we have some time. +;------------------------------------------------------------ +lxi d,SECBUF ;(10)Sector buffer address + +mov a,h ;(5)high byte of DMA address +xra d ;(4)high byte of RAM code addr +ani 0FEh ;(7)ignore lsb +mvi a,OERMSG ;(7)overlay error message +jz RPTERR ;(10)report overlay error + +;---------------------------------------- +; Set up for the upcoming data move +; Do this here, while we have some time. +;---------------------------------------- +push h ;(11)Current DMA address +push b ;(11)Current sector & SPT +lxi b,BPS ;(10)b= init checksum, +;c= byte count for MOVLUP +;------------------------------------------------------------- +; Sector Read: Step 2. Read sector data into SECBUF at de. +; SECBUF is positioned in memory such that e +; overflows at the end of the buffer. Read data +; becomes available 250 uS after -SVALID becomes +; true (0).This loop must be << 32 uS per pass. +;------------------------------------------------------------- +DATLUP: in DSTAT ;(10)Read the drive status +rlc ;(4)New Read Data Available? +jc DATLUP ;(10)no: wait for data + +in DDATA ;(10)Read data byte +stax d ;(7)Store it in sector buffer +inr e ;(5)Move to next buffer address +;..and test for end +jnz DATLUP ;(10)Loop if more data + +;-------------------------------------------------------- +; Sector Read: Step 3. Move sector data from SECBUF into +; memory at hl. Compute checksum as we go. +; +; 8327 cycles for this section +;-------------------------------------------------------- +mvi e,SDATA and 0FFh ;(7)de= address of sector data +;..within the sector buffer +MOVLUP: ldax d ;(7)Get sector buffer byte +mov m,a ;(7)Store it at the destination +cmp m ;(7)Did it store correctly? +jnz MEMERR ;(10)no: abort w/ memory error + +add b ;(4)update checksum +mov b,a ;(5)Save the updated checksum + +inx d ;(5)Bump sector buffer pointer +inx h ;(5)Bump DMA pointer +dcr c ;(5)More data bytes to copy? +jnz MOVLUP ;(10)yes: loop + +;-------------------------------------------------------------- +; Sector Read: Step 4. Check Marker byte and compare computed +; checksum against sector's checksum. Retry/abort +; if wrong Marker byte or checksum mismatch. +; +; a=computed checksum +; 98 cycles for for this section +;-------------------------------------------------------------- +xchg ;(4)hl=1st trailer byte address +;de=DMA address +mov c,m ;(7)get marker, should be FFh +inr c ;(5)c should be 0 now + +inx h ;(5)(hl)=checksum byte +xra m ;(7)compare to computed cksum +ora c ;(4)..and test marker=ff + +pop b ;(10)Current sector & SPT +jnz BADSEC ;(10)NZ: checksum error + +; Compare next DMA address to the file byte count that came +; from the sector header. Done of DMA address is greater. + +lhld SFSIZE ;(16)hl gets file size +xchg ;(4)put DMA address back in hl +;..and file size into de +mov a,l ;(4)16-bit subtraction +sub e ;(4) +mov a,h ;(4)..throw away the result +sbb d ;(4)..but keep carry (borrow) + +jnc LDDONE ;(10)done loading if hl >= de +;carry will be clear at LDDONE +;------------------------------------------------------------ +; Next Sector: The sectors are interleaved by two. Read all +; the even sectors first, then the odd sectors. +; Note that NXTSEC will repair the stack. +; +; 44 cycles for the next even or next odd sector +;------------------------------------------------------------ +lxi d,NXTSEC ;(10)for compact jumps +push d ;(10) + +inr b ;(5)sector = sector + 2 +inr b ;(5) + +mov a,b ;(5)even or odd sectors done? +cmp c ;(4)c=SPT +rc ;(5/11)no: go read next sector +;..at NXTSEC +; Total sector-to-sector = 28+8327+98+44=8497 cycles=4248.5 uS +; one 8" sector time = 5208 uS, so with 2:1 interleave, we will +; make the next sector, no problem. + +mvi b,01H ;1st odd sector number +rz ;Z: must read odd sectors now +;..at NXTSEC +;-------------------------------------------------------------- +; Next Track: Step in, and read again. +; Don't wait for the head to be ready (-MVHEAD), +; since we just read the entire previous track. +; Don't need to wait for this step-in to complete +; either, because we will definitely blow a +; revolution going from the track's last sector to +; sector 0. (One revolution takes 167 mS, and one +; step takes a a maximum of 40 uS.) +; Note that NXTRAC will repair the stack. +;-------------------------------------------------------------- +mov a,b ;STEPIN happens to be 01h +out DCTRL + +dcr b ;start with b=0 for sector 0 +ret ;go to NXTSEC + +;***Error Routine********************************************** +; Checksum error: attempt retry if not too many retries +; already. Otherwise, abort, reporting the error +; On Entry: +; Top of stack = adress for first byte of the failing sector +; Next on stack = retry count +;************************************************************** +BADSEC: mvi a,HDLOAD ;Restart Minidisk 6.4 uS timer +out DCTRL + +pop h ;Restore DMA address +pop psw ;Get retry count +dcr a ;Any more retries left? +jnz RDSECT ;yes: try reading it again +;------------------------------------------------------ +; Irrecoverable error in one sector: too many retries. +; These errors may be either incorrect marker bytes, +; wrong checksums, or a combination of both. +; On Entry: +; hl=RAM adress for first byte of the failing sector +;------------------------------------------------------ +mvi a,CERMSG ;Checksum error message +db 11H ;'lxi d' opcode to skip +;..MEMERR and go to RPTERR +;***Error Routine********************** +; Memory error: memory readback failed +; On Entry: +; hl = offending RAM address +;************************************** +MEMERR: mvi a,MERMSG ;Memory Error message + +; Fall into RPTERR + +;***CDBL Termination******************************************* +; Entry at RPTERR: +; Report an error: turn the disk controller off, turn the +; INTE light on, record the error in RAM at 0000h-0002h, and +; then loop forever writing the error code (in register a) +; to all known Terminal ports. +; On Entry: +; a = error code +; hl = offending RAM address +; +; Entry at LDDONE: +; Normal exit: Disable the disk controller and go execute +; the loaded code at DMAADR. +; On Entry: +; Carry bit is cleared +;************************************************************** +RPTERR: mov b,a ;error code +stc ;remember we had an error + +LDDONE: mvi a,DDISBL ;Disable the disk controller +out DENABL + +jnc DMAADR ;normal exit: go execute the +;..loaded program +ei ;Signal error on the INTE LED + +shld 1 ;Store the bad address +mov a,b ;recover the error code +sta 0 ;Store the error code + +ERHANG: out SIODAT ;SIO +out ACDATA ;2SIO port 0/Turnkey/UIO +out PIODAT ;PIO +out P4DB0 ;4PIO +jmp ERHANG ;Keep printing error code + +end diff --git a/application/src/main/files/examples/altair8800/boot/dbl.bin b/application/src/main/files/examples/altair8800/boot/dbl.bin new file mode 100644 index 0000000000000000000000000000000000000000..73386a4e81ea05a0c7742231fef53ff0d51d33d6 GIT binary patch literal 256 zcmY#n@DY^w&-YBKTv(a+5Xb++3_c7X@YyiQcl~7!JC@6whb4V(b39`@#OGtjbeR*# zbO16185r0YfNYjSsy=oCU#}j$D%jSbc*W;7r~EAopJ(zr4p{(oZU5!sbDOJNS@u+v zk1U9B$i?TO;B_Cy1_r6}eTNSEG`NGTP4toa_y16ZkFeB^gRc*5_4)Ww>#EOHL5BZl z&-q-uwa*7gU0UbE!cy^1;g*gM8{;V*h>I5Z*f9d#r|e_baGB#U1H;9Swukh5?3@|x j{2A?h-9e%iml+SA^r_l&pnC7g76u;`u`n^P|6l|Fr@Uju literal 0 HcmV?d00001 diff --git a/application/src/main/files/examples/altair8800/boot/mdbl-simh.asm b/application/src/main/files/examples/altair8800/boot/mdbl-simh.asm new file mode 100644 index 000000000..47ec66b8d --- /dev/null +++ b/application/src/main/files/examples/altair8800/boot/mdbl-simh.asm @@ -0,0 +1,147 @@ +; MDBL.ASM +; disassembled from simh emulator + +di +ld b, 0x80 ; how many times reset SIMH +ld a, 0x0E ; reset SIMH + +resetSimhLoop: +out (0xFE), a +dec b +jp nz, resetSimhLoop + +ld a, 0x16 ; stop timer interrupts +out (0xFE), a +ld a, 0x12 ; finds out if we have banked memory +out (0xFE), a + +in a, (0xFE) ; get banks count +or a +jp z, relocateSelf ; jump if no banked memory present + +ld a, 0x0C ; select bank +out (0xFE), a +xor a ; bank = 0 +out (0xFE), a + +relocateSelf: +ld hl, 0x5C00 ; relocate address +ld de, start ; code to relocate +ld c, 0x88 ; bytes count + +relocate: +ld a, (de) +ld (hl), a +inc de +inc hl +dec c +jp nz, relocate + +jp 0x5C00 + +start: +ld sp, 0x5D21 +ld a, 0 ; set drive 0 +out (0x08), a + +ld a, 4 ; head load +out (0x09), a +jp l5 + +waitForDrive: +in a, (0x08) ; port 1 status +and 2 ; is the drive alive? (selected) +jp nz, waitForDrive + +ld a, 2 ; head out +out (0x09), a + +l5: +in a, (0x08) ; port 1 status +and 0x40 ; +jp nz, waitForDrive + +ld de, 0 +ld b, 8 + +l11: + +push bc +push de + +ld de, 0x8086 +ld hl, l13 + +l6: +in a, (0x09) +rra +jp c, l6 + +and 0x1F +cp b +jp nz, l6 + +l7: +in a, (0x08) +or a +jp m, l7 + +in a, (0xA) +ld (hl), a +inc hl +dec e +jp nz, l7 + +pop de +ld hl, 0x5C8B +ld b, 0x80 + +l8: +ld a, (hl) +ld (de), a +inc hl +inc de +dec b +jp nz, l8 + +pop bc +ld hl, 0x5C00 +ld a, d +cp h +jp nz, l9 + +ld a, e +cp l + +l9: +jp nc, l10 +inc b +inc b +ld a, b +cp 0x20 +jp c, l11 + +ld b, 1 +jp z, l11 + +l12: +in a, (0x08) +and 2 +jp nz, l12 + +ld a, 1 +out (0x09), a +ld b, 0 +jp l11 + +l10: +ld a, 0x80 +out (0x08), a +ei + +jp 0 + +l13: + + + diff --git a/application/src/main/files/examples/altair8800/boot/mboot.bin b/application/src/main/files/examples/altair8800/boot/mdbl.bin similarity index 100% rename from application/src/main/files/examples/altair8800/boot/mboot.bin rename to application/src/main/files/examples/altair8800/boot/mdbl.bin diff --git a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java index bcbc53d42..b86ca0b46 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java +++ b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java @@ -51,7 +51,7 @@ public class AutomationCommand implements Runnable { private int waitForFinishMillis = Automation.DONT_WAIT; @CommandLine.Option(names = "--gui", negatable = true, description = "show/don't show GUI during automation") - private boolean gui; + private boolean gui = true; @CommandLine.Option(names = {"-s", "--start-address"}, description = "program start address", paramLabel = "ADDRESS") private String programStart = "0"; diff --git a/application/src/main/java/net/emustudio/application/emulation/Automation.java b/application/src/main/java/net/emustudio/application/emulation/Automation.java index 1017d2970..e4a5c8d55 100644 --- a/application/src/main/java/net/emustudio/application/emulation/Automation.java +++ b/application/src/main/java/net/emustudio/application/emulation/Automation.java @@ -144,7 +144,7 @@ private void autoEmulate(CPU cpu) { // Show all devices if GUI is supported for (Device device : computer.getDevices()) { - if (!appSettings.noGUI) { + if (!appSettings.noGUI && device.isGuiSupported()) { device.showGUI(null); } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 87850a082..3e59adb24 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -50,7 +50,7 @@ public class EmulatorEngine implements CpuEngine { private final static Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); public static final int REG_A = 7, REG_B = 0, REG_C = 1, REG_D = 2, REG_E = 3, REG_H = 4, REG_L = 5; - public static final int FLAG_S = 0x80, FLAG_Z = 0x40, FLAG_H = 0x10, FLAG_PV = 0x4, FLAG_N = 0x02, FLAG_C = 0x1; + public static final int FLAG_S = 0x80, FLAG_Z = 0x40, FLAG_Y = 0x20, FLAG_H = 0x10, FLAG_X = 0x8, FLAG_PV = 0x4, FLAG_N = 0x02, FLAG_C = 0x1; private final static int[] CONDITION = new int[]{ FLAG_Z, FLAG_Z, FLAG_C, FLAG_C, FLAG_PV, FLAG_PV, FLAG_S, FLAG_S @@ -245,7 +245,7 @@ int FD_CB_DISPATCH() throws Throwable { } private int DISPATCH(MethodHandle[] table) throws Throwable { - lastOpcode = readByte(PC); + lastOpcode = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; incrementR(); @@ -260,7 +260,7 @@ int SPECIAL_CB_DISPATCH(MethodHandle[] table) throws Throwable { byte operand = memory.read(PC); PC = (PC + 1) & 0xFFFF; - lastOpcode = readByte(PC); + lastOpcode = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; incrementR(); @@ -316,7 +316,7 @@ private int doInterrupt() throws Throwable { private int getreg(int reg) { if (reg == 6) { - return readByte((regs[REG_H] << 8) | regs[REG_L]); + return memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF; } return regs[reg]; } @@ -370,10 +370,6 @@ private boolean getCC1(int cc) { return false; } - private int readByte(int address) { - return memory.read(address) & 0xFF; - } - private int readWord(int address) { Byte[] read = memory.read(address, 2); return ((read[1] << 8) | (read[0] & 0xFF)) & 0xFFFF; @@ -383,67 +379,6 @@ private void writeWord(int address, int value) { memory.write(address, new Byte[]{(byte) (value & 0xFF), (byte) ((value >>> 8) & 0xFF)}, 2); } - private void bigOverflow(int i, int j, int result) { - int sign = i & 0x8000; - if (sign != (j & 0x8000)) { - flags &= (~FLAG_PV); - } else if ((result & 0x8000) != sign) { - flags |= FLAG_PV; - } - } - - private void halfCarry11(int before, int sumWith) { - int mask = sumWith & before; - int xormask = sumWith ^ before; - - int C0 = mask & 1; - int C1 = ((mask >>> 1) ^ (C0 & (xormask >>> 1))) & 1; - int C2 = ((mask >>> 2) ^ (C1 & (xormask >>> 2))) & 1; - int C3 = ((mask >>> 3) ^ (C2 & (xormask >>> 3))) & 1; - int C4 = ((mask >>> 4) ^ (C3 & (xormask >>> 4))) & 1; - int C5 = ((mask >>> 5) ^ (C4 & (xormask >>> 5))) & 1; - int C6 = ((mask >>> 6) ^ (C5 & (xormask >>> 6))) & 1; - int C7 = ((mask >>> 7) ^ (C6 & (xormask >>> 7))) & 1; - int C8 = ((mask >>> 8) ^ (C7 & (xormask >>> 8))) & 1; - int C9 = ((mask >>> 9) ^ (C8 & (xormask >>> 9))) & 1; - int C10 = ((mask >>> 10) ^ (C9 & (xormask >>> 10))) & 1; - int C11 = ((mask >>> 11) ^ (C10 & (xormask >>> 11))) & 1; - - if (C11 != 0) { - flags |= FLAG_H; - } else { - flags &= (~FLAG_H); - } - } - - private void carry15(int before, int sumWith) { - int mask = sumWith & before; - int xormask = sumWith ^ before; - - int C0 = mask & 1; - int C1 = ((mask >>> 1) ^ (C0 & (xormask >>> 1))) & 1; - int C2 = ((mask >>> 2) ^ (C1 & (xormask >>> 2))) & 1; - int C3 = ((mask >>> 3) ^ (C2 & (xormask >>> 3))) & 1; - int C4 = ((mask >>> 4) ^ (C3 & (xormask >>> 4))) & 1; - int C5 = ((mask >>> 5) ^ (C4 & (xormask >>> 5))) & 1; - int C6 = ((mask >>> 6) ^ (C5 & (xormask >>> 6))) & 1; - int C7 = ((mask >>> 7) ^ (C6 & (xormask >>> 7))) & 1; - int C8 = ((mask >>> 8) ^ (C7 & (xormask >>> 8))) & 1; - int C9 = ((mask >>> 9) ^ (C8 & (xormask >>> 9))) & 1; - int C10 = ((mask >>> 10) ^ (C9 & (xormask >>> 10))) & 1; - int C11 = ((mask >>> 11) ^ (C10 & (xormask >>> 11))) & 1; - int C12 = ((mask >>> 12) ^ (C11 & (xormask >>> 12))) & 1; - int C13 = ((mask >>> 13) ^ (C12 & (xormask >>> 13))) & 1; - int C14 = ((mask >>> 14) ^ (C13 & (xormask >>> 14))) & 1; - int C15 = ((mask >>> 15) ^ (C14 & (xormask >>> 15))) & 1; - - if (C15 != 0) { - flags |= FLAG_C; - } else { - flags &= (~FLAG_C); - } - } - private void incrementR() { R = (R & 0x80) | (((R & 0x7F) + 1) & 0x7F); } @@ -465,16 +400,17 @@ int I_INC_RP() { } int I_ADD_HL_RP() { - int tmp = getpair((lastOpcode >>> 4) & 0x03, true); - int tmp1 = getpair(2, true); - carry15(tmp, tmp1); - halfCarry11(tmp, tmp1); - flags &= (~(FLAG_N | FLAG_S | FLAG_Z)); - tmp += tmp1; - - flags |= ((tmp & 0x8000) == 0x8000) ? FLAG_S : 0; - flags |= (tmp == 0) ? FLAG_Z : 0; - putpair(2, tmp & 0xFFFF, true); + int rp = getpair((lastOpcode >>> 4) & 0x03, true); + int hl = (regs[REG_H] << 8) | regs[REG_L]; + + int res = hl + rp; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | + (((hl ^ res ^ rp) >>> 8) & FLAG_H) | + ((res >>> 16) & FLAG_C) | ((res >>> 8) & (FLAG_Y | FLAG_X)); + + regs[REG_H] = (res >>> 8) & 0xFF; + regs[REG_L] = res & 0xFF; + return 11; } @@ -590,19 +526,19 @@ int I_SBC_A_R() { int I_AND_R() { regs[REG_A] = (regs[REG_A] & getreg(lastOpcode & 7)) & 0xFF; - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H; return (lastOpcode == 0xA6) ? 7 : 4; } int I_XOR_R() { regs[REG_A] = ((regs[REG_A] ^ getreg(lastOpcode & 7)) & 0xff); - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]]; return (lastOpcode == 0xAE) ? 7 : 4; } int I_OR_R() { regs[REG_A] = (regs[REG_A] | getreg(lastOpcode & 7)) & 0xFF; - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]]; return (lastOpcode == 0xB6) ? 7 : 4; } @@ -633,13 +569,13 @@ int I_EX_AF_AFF() { } int I_LD_A_REF_BC() { - regs[REG_A] = readByte(getpair(0, false)); + regs[REG_A] = memory.read(getpair(0, false)) & 0xFF; return 7; } int I_RRCA() { flags = ((flags & 0xEC) | (regs[REG_A] & 1)); - regs[REG_A] = EmulatorTables.RRCA_TABLE[regs[REG_A]]; + regs[REG_A] = RRCA_TABLE[regs[REG_A]]; return 4; } @@ -667,7 +603,7 @@ int I_RLA() { } int I_LD_A_REF_DE() { - regs[REG_A] = readByte(getpair(1, false)); + regs[REG_A] = memory.read(getpair(1, false)) & 0xFF; return 7; } @@ -679,45 +615,33 @@ int I_RRA() { } int I_DAA() { - int temp = regs[REG_A]; - boolean acFlag = (flags & FLAG_H) == FLAG_H; - boolean cFlag = (flags & FLAG_C) == FLAG_C; - boolean nFlag = (flags & FLAG_N) == FLAG_N; - - if (!acFlag && !cFlag) { - regs[REG_A] = EmulatorTables.DAA_NOT_C_NOT_H_TABLE[temp] & 0xFF; - flags = (EmulatorTables.DAA_NOT_C_NOT_H_TABLE[temp] >> 8) & 0xFF | (flags & FLAG_N); - if (nFlag) { - flags |= EmulatorTables.DAA_N_NOT_H_FOR_H_TABLE[temp]; - } else { - flags |= EmulatorTables.DAA_NOT_N_NOT_H_FOR_H_TABLE[temp]; + int a = regs[REG_A]; + boolean flagN = (flags & FLAG_N) != 0; + boolean flagH = (flags & FLAG_H) != 0; + boolean flagC = (flags & FLAG_C) != 0; + + if (flagN) { + if (flagH | ((regs[REG_A] & 0xf) > 9)) { + a -= 6; } - } else if (acFlag && !cFlag) { - regs[REG_A] = EmulatorTables.DAA_NOT_C_H_TABLE[temp] & 0xFF; - flags = (EmulatorTables.DAA_NOT_C_H_TABLE[temp] >> 8) & 0xFF | (flags & FLAG_N); - if (nFlag) { - flags |= EmulatorTables.DAA_N_H_FOR_H_TABLE[temp]; - } else { - flags |= EmulatorTables.DAA_NOT_N_H_FOR_H_TABLE[temp]; + if (flagC | (regs[REG_A] > 0x99)) { + a -= 0x60; } - } else if (!acFlag) { // cFlag = true - regs[REG_A] = EmulatorTables.DAA_C_NOT_H_TABLE[temp] & 0xFF; - flags = (EmulatorTables.DAA_C_NOT_H_TABLE[temp] >> 8) & 0xFF | (flags & FLAG_N); - if (nFlag) { - flags |= EmulatorTables.DAA_N_NOT_H_FOR_H_TABLE[temp]; - } else { - flags |= EmulatorTables.DAA_NOT_N_NOT_H_FOR_H_TABLE[temp]; + } else { + if (flagH | ((regs[REG_A] & 0xf) > 9)) { + a += 6; } - } else { // acFlag = cFlag = true - regs[REG_A] = EmulatorTables.DAA_C_H_TABLE[temp] & 0xFF; - flags = (EmulatorTables.DAA_C_H_TABLE[temp] >> 8) & 0xFF | (flags & FLAG_N); - if (nFlag) { - flags |= EmulatorTables.DAA_N_H_FOR_H_TABLE[temp]; - } else { - flags |= EmulatorTables.DAA_NOT_N_H_FOR_H_TABLE[temp]; + if (flagC | (regs[REG_A] > 0x99)) { + a += 0x60; } } - flags |= EmulatorTables.PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]]; + a = a & 0xFF; + + flags = (flags & (FLAG_C | FLAG_N)) + | ((regs[REG_A] > 0x99) ? FLAG_C : 0) + | ((regs[REG_A] ^ a) & FLAG_H) + | TABLE_SZ[a] | PARITY_TABLE[a]; + regs[REG_A] = a; return 4; } @@ -728,8 +652,7 @@ int I_CPL() { } int I_SCF() { - flags |= FLAG_N | FLAG_C; - flags &= ~FLAG_H; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_Y | FLAG_X | FLAG_PV)) | FLAG_C | (regs[REG_A] & (FLAG_Y | FLAG_X)); return 4; } @@ -827,61 +750,34 @@ int I_OUT_REF_C_R() { } int I_SBC_HL_RP() { - int tmp = -getpair((lastOpcode >>> 4) & 0x03, true); - int tmp1 = getpair(2, true); - if ((flags & FLAG_C) == FLAG_C) { - tmp--; - } - - int sum = (tmp1 + tmp) & 0xFFFF; - tmp &= 0xFFFF; - - if ((sum & 0x8000) != 0) { - flags |= FLAG_S; - } else { - flags &= (~FLAG_S); - } - if (sum == 0) { - flags |= FLAG_Z; - } else { - flags &= (~FLAG_Z); - } - flags |= FLAG_N; - - carry15(tmp1, tmp); - halfCarry11(tmp1, tmp); - bigOverflow(tmp1, tmp, sum); - putpair(2, sum, true); - + int rp = getpair((lastOpcode >>> 4) & 0x03, true); + int hl = ((regs[REG_H] << 8) | regs[REG_L]) & 0xFFFF; + int res = hl - rp - (flags & FLAG_C); + + flags = (((hl ^ res ^ rp) >>> 8) & FLAG_H) | FLAG_N | + ((res >>> 16) & FLAG_C) | + ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | + (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | + (((rp ^ hl) & (hl ^ res) & 0x8000) >>> 13); + + regs[REG_H] = (res >>> 8) & 0xFF; + regs[REG_L] = res & 0xFF; return 15; } int I_ADC_HL_RP() { - int tmp = getpair((lastOpcode >>> 4) & 0x03, true); - int tmp1 = getpair(2, true); - if ((flags & FLAG_C) == FLAG_C) { - tmp++; - } - int sum = tmp + tmp1; - tmp1 &= 0xFFFF; - sum &= 0xFFFF; - - if ((sum & 0x8000) != 0) { - flags |= FLAG_S; - } else { - flags &= (~FLAG_S); - } - if (sum == 0) { - flags |= FLAG_Z; - } else { - flags &= (~FLAG_Z); - } - flags &= (~FLAG_N); - carry15(tmp, tmp1); - halfCarry11(tmp, tmp1); - bigOverflow(tmp, tmp1, sum); - putpair(2, sum, false); - + int rp = getpair((lastOpcode >>> 4) & 0x03, true); + int hl = (regs[REG_H] << 8 | regs[REG_L]) & 0xFFFF; + int res = hl + rp + (flags & FLAG_C); + + flags = (((hl ^ res ^ rp) >>> 8) & FLAG_H) | + ((res >>> 16) & FLAG_C) | + ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | + (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | + (((rp ^ hl ^ 0x8000) & (rp ^ res) & 0x8000) >>> 13); + + regs[REG_H] = (res >>> 8) & 0xFF; + regs[REG_L] = (res & 0xFF); return 11; } @@ -982,7 +878,7 @@ int I_CPI() { int hl = (regs[REG_H] << 8) | regs[REG_L]; int bc = (regs[REG_B] << 8) | regs[REG_C]; - int value = readByte(hl); + int value = memory.read(hl) & 0xFF; hl = (hl + 1) & 0xFFFF; bc = (bc - 1) & 0xFFFF; @@ -1002,7 +898,7 @@ int I_CPIR() { int hl = (regs[REG_H] << 8) | regs[REG_L]; int bc = (regs[REG_B] << 8) | regs[REG_C]; - int value = readByte(hl); + int value = memory.read(hl) & 0xFF; hl = (hl + 1) & 0xFFFF; bc = (bc - 1) & 0xFFFF; @@ -1027,7 +923,7 @@ int I_CPD() { int hl = (regs[REG_H] << 8) | regs[REG_L]; int bc = (regs[REG_B] << 8) | regs[REG_C]; - int value = readByte(hl); + int value = memory.read(hl) & 0xFF; hl = (hl - 1) & 0xFFFF; bc = (bc - 1) & 0xFFFF; @@ -1047,7 +943,7 @@ int I_CPDR() { int hl = (regs[REG_H] << 8) | regs[REG_L]; int bc = (regs[REG_B] << 8) | regs[REG_C]; - int value = readByte(hl); + int value = memory.read(hl) & 0xFF; hl = (hl - 1) & 0xFFFF; bc = (bc - 1) & 0xFFFF; @@ -1069,12 +965,21 @@ int I_CPDR() { } int I_LDD() { - int hl = (regs[REG_H] << 8) | regs[REG_L]; - int de = (regs[REG_D] << 8) | regs[REG_E]; - int bc = (regs[REG_B] << 8) | regs[REG_C]; + int hl = ((regs[REG_H] << 8) | regs[REG_L]) & 0xFFFF; + int de = ((regs[REG_D] << 8) | regs[REG_E]) & 0xFFFF; + int bc = ((regs[REG_B] << 8) | regs[REG_C]) & 0xFFFF; - memory.write(de, memory.read(hl)); + byte io = memory.read(hl); + memory.write(de, io); + int regA = regs[REG_A]; + flags = flags & (FLAG_S | FLAG_Z | FLAG_C); + if (((regA + io) & 0x02) != 0) { + flags |= FLAG_Y; /* bit 1 -> flag 5 */ + } + if (((regA + io) & 0x08) != 0) { + flags |= FLAG_X; /* bit 3 -> flag 3 */ + } hl = (hl - 1) & 0xFFFF; de = (de - 1) & 0xFFFF; bc = (bc - 1) & 0xFFFF; @@ -1085,7 +990,7 @@ int I_LDD() { regs[REG_E] = de & 0xFF; regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - flags = ((flags & FLAG_S) | (flags & FLAG_Z) | (flags & FLAG_C)) & (~FLAG_PV); + if (bc != 0) { flags |= FLAG_PV; } @@ -1093,38 +998,31 @@ int I_LDD() { } int I_LDDR() { - int tmp1 = (regs[REG_H] << 8) | regs[REG_L]; - int tmp2 = (regs[REG_D] << 8) | regs[REG_E]; - memory.write(tmp2, memory.read(tmp1)); - tmp1 = (tmp1 - 1) & 0xFFFF; - tmp2 = (tmp2 - 1) & 0xFFFF; - int tmp = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; - regs[REG_H] = ((tmp1 >>> 8) & 0xff); - regs[REG_L] = (tmp1 & 0xFF); - regs[REG_B] = ((tmp >>> 8) & 0xff); - regs[REG_C] = (tmp & 0xFF); - regs[REG_D] = ((tmp2 >>> 8) & 0xff); - regs[REG_E] = (tmp2 & 0xFF); - flags &= 0xE9; - if (tmp != 0) { - flags |= FLAG_PV; - } else { - return 16; + I_LDD(); + int bc = ((regs[REG_B] << 8) | regs[REG_C]) & 0xFFFF; + if (bc != 0) { + PC = (PC - 2) & 0xFFFF; + return 21; } - PC = (PC - 2) & 0xFFFF; - return 21; + return 16; } int I_LDI() { - int hl = getpair(2, false); - int de = getpair(1, false); - int bc = getpair(0, false); + int hl = (regs[REG_H] << 8) | regs[REG_L]; + int de = (regs[REG_D] << 8) | regs[REG_E]; - memory.write(de, memory.read(hl)); + byte io = memory.read(hl++); + memory.write(de++, io); - hl = (hl + 1) & 0xFFFF; - de = (de + 1) & 0xFFFF; - bc = (bc - 1) & 0xFFFF; + flags &= (FLAG_S | FLAG_Z | FLAG_C); + if (((regs[REG_A] + io) & 0x02) != 0) { + flags |= FLAG_Y; /* bit 1 -> flag 5 */ + } + if (((regs[REG_A] + io) & 0x08) != 0) { + flags |= FLAG_X; /* bit 3 -> flag 3 */ + } + + int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; @@ -1133,31 +1031,15 @@ int I_LDI() { regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - int flagP = (bc != 0) ? FLAG_PV : 0; - flags = (flags & FLAG_S) | (flags & FLAG_Z) | (flags & FLAG_C) | flagP; + if (bc != 0) { + flags |= FLAG_PV; + } return 16; } int I_LDIR() { - int hl = (regs[REG_H] << 8) | regs[REG_L]; - int de = (regs[REG_D] << 8) | regs[REG_E]; + I_LDI(); int bc = (regs[REG_B] << 8) | regs[REG_C]; - - memory.write(de, memory.read(hl)); - - hl = (hl + 1) & 0xFFFF; - de = (de + 1) & 0xFFFF; - bc = (bc - 1) & 0xFFFF; - - regs[REG_H] = (hl >>> 8) & 0xFF; - regs[REG_L] = hl & 0xFF; - regs[REG_D] = (de >>> 8) & 0xFF; - regs[REG_E] = de & 0xFF; - regs[REG_B] = (bc >>> 8) & 0xFF; - regs[REG_C] = bc & 0xFF; - - int flagP = (bc != 0) ? FLAG_PV : 0; - flags = (flags & FLAG_S) | (flags & FLAG_Z) | (flags & FLAG_C) | flagP; if (bc == 0) { return 16; } @@ -1338,7 +1220,7 @@ int I_JR_N() { } int I_ADD_A_N() { - int value = readByte(PC); + int value = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; int sum = (oldA + value) & 0x1FF; @@ -1348,7 +1230,7 @@ int I_ADD_A_N() { } int I_ADC_A_N() { - int value = readByte(PC); + int value = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; @@ -1358,14 +1240,14 @@ int I_ADC_A_N() { } int I_OUT_REF_N_A() { - int tmp = readByte(PC); + int tmp = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; context.writeIO(tmp, (byte) regs[REG_A]); return 11; } int I_SUB_N() { - int value = readByte(PC); + int value = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; @@ -1377,14 +1259,14 @@ int I_SUB_N() { } int I_IN_A_REF_N() { - int tmp = readByte(PC); + int tmp = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; regs[REG_A] = (context.readIO(tmp) & 0xFF); return 11; } int I_SBC_A_N() { - int value = readByte(PC); + int value = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; @@ -1400,7 +1282,7 @@ int I_AND_N() { PC = (PC + 1) & 0xFFFF; regs[REG_A] = (regs[REG_A] & tmp) & 0xFF; - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H; return 7; } @@ -1409,7 +1291,7 @@ int I_XOR_N() { PC = (PC + 1) & 0xFFFF; regs[REG_A] = ((regs[REG_A] ^ tmp) & 0xFF); - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]]; return 7; } @@ -1418,12 +1300,12 @@ int I_OR_N() { PC = (PC + 1) & 0xFFFF; regs[REG_A] = (regs[REG_A] | tmp) & 0xFF; - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]]; return 7; } int I_CP_N() { - int value = readByte(PC); + int value = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; @@ -1535,16 +1417,15 @@ int I_HALT() { } int I_RLC_R() { - int tmp = lastOpcode & 7; - int tmp1 = getreg(tmp) & 0xFF; + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; - int tmp2 = (tmp1 >>> 7) & 1; - tmp1 = (((tmp1 << 1) & 0xFF) | tmp2) & 0xFF; - putreg(tmp, tmp1); + int c = ((regValue & 0x80) != 0) ? FLAG_C : 0; + regValue = ((regValue << 1) | (regValue >>> 7)) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | c; - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - if (tmp == 6) { + if (reg == 6) { return 15; } else { return 8; @@ -1637,16 +1518,15 @@ int I_SRA_R() { } int I_SLL_R() { - int tmp = lastOpcode & 7; - int tmp1 = getreg(tmp) & 0xFF; + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int c = ((regValue & 0x80) != 0) ? FLAG_C : 0; + regValue = ((regValue << 1) | 0x01) & 0xFF; - int tmp2 = (tmp1 >>> 7) & 1; - tmp1 = (tmp1 << 1) & 0xFF | tmp1 & 1; - putreg(tmp, tmp1); + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | c; - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - - if (tmp == 6) { + if (reg == 6) { return 15; } else { return 8; @@ -1654,16 +1534,16 @@ int I_SLL_R() { } int I_SRL_R() { - int tmp = lastOpcode & 7; - int tmp1 = getreg(tmp) & 0xFF; + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; - int tmp2 = tmp1 & 1; - tmp1 = (tmp1 >>> 1) & 0x7F; - putreg(tmp, tmp1); + int c = ((regValue & 0x01) != 0) ? FLAG_C : 0; + regValue = (regValue >>> 1) & 0xFF; + putreg(reg, regValue); - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | c; - if (tmp == 6) { + if (reg == 6) { return 15; } else { return 8; @@ -1687,12 +1567,12 @@ int I_BIT_N_R() { } int I_RES_N_R() { - int tmp = (lastOpcode >>> 3) & 7; - int tmp2 = lastOpcode & 7; - int tmp1 = getreg(tmp2) & 0xFF; - tmp1 = (tmp1 & (~(1 << tmp))); - putreg(tmp2, tmp1); - if (tmp2 == 6) { + int bit = (lastOpcode >>> 3) & 7; + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + regValue = (regValue & (~(1 << bit))); + putreg(reg, regValue); + if (reg == 6) { return 15; } else { return 8; @@ -1723,29 +1603,25 @@ int I_ADD_IY_RP() { } int I_ADD_II_RP(int special) { - int tmp = special; - int pair; - int reg = (lastOpcode >>> 4) & 0x03; - switch (reg) { + int dstRp; + int rp = (lastOpcode >>> 4) & 0x03; + switch (rp) { case 3: - pair = SP; + dstRp = SP; break; case 2: - pair = special; + dstRp = special; break; default: - int index = reg * 2; - pair = regs[index] << 8 | regs[index + 1]; + int index = rp * 2; + dstRp = regs[index] << 8 | regs[index + 1]; } - carry15(tmp, pair); - halfCarry11(tmp, pair); - flags &= (~(FLAG_N | FLAG_S | FLAG_Z)); - - tmp += pair; - flags |= ((tmp & 0x8000) == 0x8000) ? FLAG_S : 0; - flags |= (tmp == 0) ? FLAG_Z : 0; - return tmp & 0xFFFF; + int res = special + dstRp; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | + (((dstRp ^ res ^ special) >>> 8) & FLAG_H) | + ((res >>> 16) & FLAG_C) | ((res >>> 8) & (FLAG_Y | FLAG_X)); + return res & 0xFFFF; } int I_LD_IX_NN() { @@ -1823,7 +1699,7 @@ int I_INC_REF_II_N(int special) { byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; int address = (special + disp) & 0xFFFF; - int value = readByte(address); + int value = memory.read(address) & 0xFF; int sum = (value + 1) & 0x1FF; int sumByte = sum & 0xFF; @@ -1842,10 +1718,10 @@ int I_DEC_REF_IY_N() { } int I_DEC_REF_II_N(int special) { - int disp = readByte(PC); + int disp = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; int address = (special + (byte) disp) & 0xFFFF; - int value = readByte(address); + int value = memory.read(address) & 0xFF; int sum = (value - 1) & 0x1FF; int sumByte = sum & 0xFF; @@ -1914,7 +1790,7 @@ int I_ADD_A_REF_IY_N() { int I_ADD_A_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = readByte((special + offset) & 0xFFFF); + int value = memory.read((special + offset) & 0xFFFF) & 0xFF; int oldA = regs[REG_A]; int sum = (oldA + value) & 0x1FF; @@ -1934,7 +1810,7 @@ int I_ADC_A_REF_IY_N() { int I_ADC_A_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = readByte((special + offset) & 0xFFFF); + int value = memory.read((special + offset) & 0xFFFF) & 0xFF; int oldA = regs[REG_A]; int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; @@ -1954,7 +1830,7 @@ int I_SUB_REF_IY_N() { int I_SUB_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = readByte((special + offset) & 0xFFFF); + int value = memory.read((special + offset) & 0xFFFF) & 0xFF; int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; @@ -1975,7 +1851,7 @@ int I_SBC_A_REF_IY_N() { int I_SBC_A_REF_II_N(int special) { byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = readByte((special + offset) & 0xFFFF); + int value = memory.read((special + offset) & 0xFFFF) & 0xFF; int oldA = regs[REG_A]; int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; @@ -1999,7 +1875,7 @@ int I_AND_REF_II_N(int special) { int tmp1 = memory.read((special + tmp) & 0xFFFF); regs[REG_A] = (regs[REG_A] & tmp1) & 0xFF; - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H; return 19; } @@ -2012,12 +1888,12 @@ int I_XOR_REF_IY_N() { } int I_XOR_REF_II_N(int special) { - byte tmp = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = memory.read((special + tmp) & 0xFFFF); - regs[REG_A] = ((regs[REG_A] ^ tmp1) & 0xff); - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + byte value = memory.read((special + disp) & 0xFFFF); + regs[REG_A] = ((regs[REG_A] ^ value) & 0xff); + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]]; return 19; } @@ -2030,11 +1906,11 @@ int I_OR_REF_IY_N() { } int I_OR_REF_II_N(int special) { - byte tmp = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = memory.read((special + tmp) & 0xFFFF); - regs[REG_A] = ((regs[REG_A] | tmp1) & 0xff); - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + byte value = memory.read((special + disp) & 0xFFFF); + regs[REG_A] = ((regs[REG_A] | value) & 0xff); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]]; return 19; } @@ -2047,9 +1923,9 @@ int I_CP_REF_IY_N() { } int I_CP_REF_II_N(int special) { - byte offset = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = readByte((special + offset) & 0xFFFF); + int value = memory.read((special + disp) & 0xFFFF) & 0xFF; int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; @@ -2127,16 +2003,16 @@ int I_RLC_REF_IY_N_R(byte operand) { } int I_RLC_REF_II_N_R(byte operand, int special) { - int address = (special + operand) & 0xFFFF; - int value = readByte(address); - int bit7 = (value >>> 7) & 1; + int addr = (special + operand) & 0xFFFF; + int addrValue = memory.read(addr) & 0xFF; - value = (((value << 1) | bit7) & 0xFF); - memory.write(address, (byte) value); - flags = TABLE_SZ[value] | EmulatorTables.PARITY_TABLE[value] | bit7; + int c = ((addrValue & 0x80) != 0) ? FLAG_C : 0; + int res = ((addrValue << 1) | (addrValue >>> 7)) & 0xFF; + memory.write(addr, (byte) res); + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c; // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = value & 0xFF; + regs[lastOpcode & 7] = res & 0xFF; return 23; } @@ -2149,17 +2025,16 @@ int I_RRC_REF_IY_N_R(byte operand) { } int I_RRC_REF_II_N_R(byte operand, int special) { - int tmp = (special + operand) & 0xffff; - int tmp1 = memory.read(tmp); + int addr = (special + operand) & 0xffff; + int addrValue = memory.read(addr) & 0xFF; - int tmp2 = tmp1 & 1; - tmp1 = (((tmp1 >>> 1) & 0x7F) | (tmp2 << 7)) & 0xFF; - - memory.write(tmp, (byte) (tmp1 & 0xFF)); - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + int c = addrValue & 1; + int res = (((addrValue >>> 1) & 0x7F) | (c << 7)) & 0xFF; + memory.write(addr, (byte) (res & 0xFF)); + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c; // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = res & 0xFF; return 23; } @@ -2172,16 +2047,16 @@ int I_RL_REF_IY_N_R(byte operand) { } int I_RL_REF_II_N_R(byte operand, int special) { - int tmp = (special + operand) & 0xffff; - int tmp1 = memory.read(tmp); + int addr = (special + operand) & 0xffff; + int addrValue = memory.read(addr) & 0xFF; - int tmp2 = (tmp1 >>> 7) & 1; - tmp1 = ((((tmp1 << 1) & 0xFF) | flags & FLAG_C) & 0xFF); - memory.write(tmp, (byte) (tmp1 & 0xFF)); + int c = (addrValue >>> 7) & 1; + int res = ((((addrValue << 1) & 0xFF) | flags & FLAG_C) & 0xFF); + memory.write(addr, (byte) (res & 0xFF)); - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c; // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = res & 0xFF; return 23; } @@ -2194,16 +2069,16 @@ int I_RR_REF_IY_N_R(byte operand) { } int I_RR_REF_II_N_R(byte operand, int special) { - int address = (special + operand) & 0xffff; - int value = readByte(address); + int addr = (special + operand) & 0xffff; + int addrValue = memory.read(addr) & 0xFF; - int bit0 = value & 1; - value = ((((value >> 1) & 0xFF) | (flags & FLAG_C) << 7) & 0xFF); - memory.write(address, (byte) (value & 0xFF)); + int c = addrValue & 1; + int res = ((((addrValue >> 1) & 0xFF) | (flags & FLAG_C) << 7) & 0xFF); + memory.write(addr, (byte) (res & 0xFF)); - flags = TABLE_SZ[value] | EmulatorTables.PARITY_TABLE[value] | bit0; + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c; // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = value & 0xFF; + regs[lastOpcode & 7] = res & 0xFF; return 23; } @@ -2216,16 +2091,16 @@ int I_SLA_REF_IY_N_R(byte operand) { } int I_SLA_REF_II_N_R(byte operand, int special) { - int tmp = (special + operand) & 0xFFFF; - int tmp1 = memory.read(tmp); + int addr = (special + operand) & 0xFFFF; + int addrValue = memory.read(addr) & 0xFF; - int tmp2 = (tmp1 >>> 7) & 1; - tmp1 = (tmp1 << 1) & 0xFE; - memory.write(tmp, (byte) tmp1); + int c = (addrValue >>> 7) & 1; + int res = (addrValue << 1) & 0xFE; + memory.write(addr, (byte) res); + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c; - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = res & 0xFF; return 23; } @@ -2238,16 +2113,16 @@ int I_SRA_REF_IY_N_R(byte operand) { } int I_SRA_REF_II_N_R(byte operand, int special) { - int tmp = (special + operand) & 0xffff; - int tmp1 = memory.read(tmp); + int addr = (special + operand) & 0xffff; + int addrValue = memory.read(addr) & 0xFF; - int tmp2 = tmp1 & 1; - tmp1 = (tmp1 >> 1) & 0xFF | (tmp1 & 0x80); - memory.write(tmp, (byte) tmp1); + int c = addrValue & 1; + int res = (addrValue >> 1) & 0xFF | (addrValue & 0x80); + memory.write(addr, (byte) res); - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c; // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = res & 0xFF; return 23; } @@ -2260,16 +2135,17 @@ int I_SLL_REF_IY_N_R(byte operand) { } int I_SLL_REF_II_N_R(byte operand, int special) { - int tmp = (special + operand) & 0xffff; - int tmp1 = memory.read(tmp); + int addr = (special + operand) & 0xffff; + int addrValue = memory.read(addr) & 0xFF; - int tmp2 = (tmp1 >>> 7) & 1; - tmp1 = (tmp1 << 1) & 0xFF | tmp1 & 1; - memory.write(tmp, (byte) tmp1); + int c = ((addrValue & 0x80) != 0) ? FLAG_C : 0; + int res = ((addrValue << 1) | 0x01) & 0xFF; + + memory.write(addr, (byte) res); + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c; - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = res; return 23; } @@ -2282,16 +2158,16 @@ int I_SRL_REF_IY_N_R(byte operand) { } int I_SRL_REF_II_N_R(byte operand, int special) { - int tmp = (special + operand) & 0xffff; - int tmp1 = memory.read(tmp); + int addr = (special + operand) & 0xffff; + int addrValue = memory.read(addr) & 0xFF; - int tmp2 = tmp1 & 1; - tmp1 = (tmp1 >>> 1) & 0x7F; - memory.write(tmp, (byte) tmp1); + int c = ((addrValue & 0x01) != 0) ? FLAG_C : 0; + int res = (addrValue >>> 1) & 0xFF; + memory.write(addr, (byte) res); - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; - // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = tmp1 & 0xFF; + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c; + // regs[6] is unused, so it's ok to set it + regs[lastOpcode & 7] = res; return 23; } @@ -2305,10 +2181,10 @@ int I_BIT_N_REF_IY_N(byte operand) { int I_BIT_N_REF_II_N(byte operand, int special) { int bitNumber = (lastOpcode >>> 3) & 7; - int tmp1 = memory.read((special + operand) & 0xFFFF); - flags = ((flags & FLAG_C) | FLAG_H | (((tmp1 & (1 << bitNumber)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); + byte addrValue = memory.read((special + operand) & 0xFFFF); + flags = ((flags & FLAG_C) | FLAG_H | (((addrValue & (1 << bitNumber)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); if (bitNumber == 7) { - flags |= (((tmp1 & (1 << 7)) == 0x80) ? FLAG_S : 0); + flags |= (((addrValue & (1 << 7)) == 0x80) ? FLAG_S : 0); } return 20; } @@ -2322,13 +2198,13 @@ int I_RES_N_REF_IY_N_R(byte operand) { } int I_RES_N_REF_II_N_R(byte operand, int special) { - int tmp2 = (lastOpcode >>> 3) & 7; - int tmp3 = (special + operand) & 0xffff; - int tmp1 = memory.read(tmp3); - tmp1 = (tmp1 & (~(1 << tmp2))); - memory.write(tmp3, (byte) (tmp1 & 0xff)); + int bitNumber = (lastOpcode >>> 3) & 7; + int addr = (special + operand) & 0xffff; + int addrValue = memory.read(addr) & 0xFF; + int res = (addrValue & (~(1 << bitNumber))); + memory.write(addr, (byte) (res & 0xff)); // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = res & 0xFF; return 23; } @@ -2341,14 +2217,15 @@ int I_SET_N_REF_IY_N_R(byte operand) { } int I_SET_N_REF_II_N_R(byte operand, int special) { - int tmp2 = (lastOpcode >>> 3) & 7; - int tmp3 = (special + operand) & 0xffff; - int tmp1 = memory.read(tmp3); - tmp1 = (tmp1 | (1 << tmp2)); - memory.write(tmp3, (byte) (tmp1 & 0xff)); + int bitNumber = (lastOpcode >>> 3) & 7; + int addr = (special + operand) & 0xffff; + int addrValue = memory.read(addr) & 0xFF; + + int res = (addrValue | (1 << bitNumber)) & 0xFF; + memory.write(addr, (byte) res); // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = tmp1 & 0xFF; + regs[lastOpcode & 7] = res; return 23; } @@ -2416,25 +2293,25 @@ int I_DEC_IIL(int special) { } int I_LD_IXH_N() { - IX = ((readByte(PC) << 8) | (IX & 0xFF)) & 0xFFFF; + IX = (((memory.read(PC) & 0xFF) << 8) | (IX & 0xFF)) & 0xFFFF; PC = (PC + 1) & 0xFFFF; return 11; } int I_LD_IYH_N() { - IY = ((readByte(PC) << 8) | (IY & 0xFF)) & 0xFFFF; + IY = (((memory.read(PC) & 0xFF) << 8) | (IY & 0xFF)) & 0xFFFF; PC = (PC + 1) & 0xFFFF; return 11; } int I_LD_IXL_N() { - IX = ((IX & 0xFF00) | (readByte(PC) & 0xFF)) & 0xFFFF; + IX = ((IX & 0xFF00) | (memory.read(PC) & 0xFF)) & 0xFFFF; PC = (PC + 1) & 0xFFFF; return 11; } int I_LD_IYL_N() { - IY = ((IY & 0xFF00) | (readByte(PC) & 0xFF)) & 0xFFFF; + IY = ((IY & 0xFF00) | (memory.read(PC) & 0xFF)) & 0xFFFF; PC = (PC + 1) & 0xFFFF; return 11; } @@ -2634,7 +2511,7 @@ int I_AND_IYL() { int I_AND(int value) { regs[REG_A] = (regs[REG_A] & value) & 0xFF; - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H; return 8; } @@ -2655,8 +2532,8 @@ int I_XOR_IYL() { } int I_XOR(int value) { - regs[REG_A] = ((regs[REG_A] ^ value) & 0xFF); - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + regs[REG_A] = (regs[REG_A] ^ value) & 0xFF; + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]]; return 8; } @@ -2678,7 +2555,7 @@ int I_OR_IYL() { int I_OR(int value) { regs[REG_A] = (regs[REG_A] | value) & 0xFF; - flags = EmulatorTables.AND_OR_XOR_TABLE[regs[REG_A]]; + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]]; return 8; } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java index 4e59534ed..f9f7ad5bf 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java @@ -134,106 +134,6 @@ class EmulatorTables { 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4 }; - final static int[] DAA_NOT_C_NOT_H_TABLE = new int[]{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, - 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, - 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 358, 358, 358, 358, 358, 358, 352, 352, - 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, - 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, - 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, - 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, - }; - - final static int[] DAA_NOT_C_H_TABLE = new int[]{ - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - }; - - final static int[] DAA_C_NOT_H_TABLE = new int[]{ - 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, - 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, - 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, - 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, - 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, - 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, - 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, - 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, - 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, 352, 352, 352, - 352, 352, 352, 352, 352, 352, 352, 358, 358, 358, 358, 358, 358, - }; - - final static int[] DAA_C_H_TABLE = new int[]{ - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, - }; - - final static int[] DAA_NOT_N_NOT_H_FOR_H_TABLE = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, - 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, - 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, - 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, - }; - - final static int[] DAA_NOT_N_H_FOR_H_TABLE = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, - 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, - 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, - 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, - }; - - final static int[] DAA_N_NOT_H_FOR_H_TABLE = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; - - final static int[] DAA_N_H_FOR_H_TABLE = new int[]{16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, - 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, - 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, - 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; - final static int[] AND_OR_XOR_TABLE = new int[]{ 84, 16, 16, 20, 16, 20, 20, 16, 16, 20, 20, 16, 20, 16, 16, 20, 16, 20, 20, 16, 20, 16, 16, 20, 20, 16, 16, 20, 16, 20, 20, 16, 16, 20, 20, 16, 20, 16, 16, 20, 20, 16, 16, 20, 16, 20, 20, 16, 20, 16, 16, 20, 16, 20, 20, 16, 16, 20, 20, 16, diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java index fb764adca..3e2bd611b 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java @@ -237,10 +237,16 @@ public void testDEC_RP() { @Test public void testADD_HL_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .firstIsPair(REG_PAIR_HL) .verifyPair(REG_PAIR_HL, context -> context.first + context.second) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign16bit().zero16bit().carry15().halfCarry11().subtractionIsReset() + .signIsPreserved() + .zeroIsPreserved() + .parityIsPreserved() + .carry15() + .halfCarry11() + .subtractionIsReset() ) .keepCurrentInjectorsAfterRun(); @@ -380,11 +386,12 @@ public void testDEC_REF_II_N() { @Test public void testADD_IX_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .firstIsIX() .verifyIX(context -> context.first + context.second) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign16bit().zero16bit().halfCarry11().carry15().subtractionIsReset() - ) + .signIsPreserved().zeroIsPreserved().parityIsPreserved() + .halfCarry11().carry15().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( @@ -401,11 +408,12 @@ public void testADD_IX_RP() { @Test public void testADD_IY_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .firstIsIY() .verifyIY(context -> context.first + context.second) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign16bit().zero16bit().halfCarry11().carry15().subtractionIsReset() - ) + .signIsPreserved().zeroIsPreserved().parityIsPreserved() + .halfCarry11().carry15().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( @@ -422,10 +430,12 @@ public void testADD_IY_RP() { @Test public void testADC_HL_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .firstIsPair(REG_PAIR_HL) .verifyPair(REG_PAIR_HL, context -> context.first + context.second + (context.flags & FLAG_C)) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign16bit().zero16bit().overflow16bit().carry15().halfCarry11().subtractionIsReset()) + .overflow16bit().sign16bit().zero16bit() + .carry15().halfCarry11().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( @@ -442,11 +452,12 @@ public void testADC_HL_RP() { @Test public void testSBC_HL_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .firstIsPair(REG_PAIR_HL) .verifyPair(REG_PAIR_HL, context -> - (context.first + ((-context.second - (context.flags & FLAG_C)) & 0xFFFF))) + (context.first - context.second - (context.flags & FLAG_C))) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign16bit().zero16bit().overflow16bit().carry15().halfCarry11().subtractionIsSet()) + .sign16bit().zero16bit().borrow16bit().carry15().halfCarry11().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java index f12f37d46..236d8ea76 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java @@ -23,6 +23,7 @@ import net.emustudio.plugins.cpu.zilogZ80.suite.ByteTestBuilder; import net.emustudio.plugins.cpu.zilogZ80.suite.FlagsCheckImpl; import net.emustudio.plugins.cpu.zilogZ80.suite.IntegerTestBuilder; +import org.junit.Ignore; import org.junit.Test; import java.util.function.Function; @@ -35,7 +36,13 @@ public class LogicTest extends InstructionsTest { @Test public void testAND_R() { - ByteTestBuilder test = getLogicTestBuilder(context -> context.first & context.second); + ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> context.first & context.second) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( test.run(0xA7) @@ -54,7 +61,13 @@ public void testAND_R() { @Test public void testAND_N() { - ByteTestBuilder test = getLogicTestBuilder(context -> context.first & context.second); + ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> context.first & context.second) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinary( test.runWithSecondOperand(0xE6) @@ -154,7 +167,9 @@ public void testCP_N() { ); } + // TODO @Test + @Ignore public void testDAA() { Function, Integer> daaFunc = context -> FlagsTableGeneratorTest.daa( ((context.flags & FLAG_C) == FLAG_C), @@ -329,7 +344,12 @@ public void testCPDR() { @Test public void testAND_REF_II_N() { - IntegerTestBuilder test = prepareLogicIXYtest(context -> (context.first & 0xFF) & (context.second & 0xFF)) + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8LSBisRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().parity().carryIsReset().halfCarryIsSet().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -664,7 +684,20 @@ public void testSRL_R() { @Test public void testSRL_REF_II_N() { - IntegerTestBuilder test = prepareIIRotationLSBTest(context -> ((context.second & 0xFF) >>> 1) & 0x7F) + //unsigned res = value; + // unsigned c = (res & 0x01) ? CF : 0; + // res = (res >> 1) & 0xff; + // F = SZP[res] | c; + // return res; + + //B = srl(rm_reg(m_ea)); wm(m_ea, B); + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .verifyByte(context -> get8MSBplus8LSB(context.first), context -> ((context.second & 0xFF) >>> 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .switchFirstAndSecond().carryIsFirstOperandLSB().sign().zero().halfCarryIsReset().parity() + .subtractionIsReset()) + .setFlags(0xFF) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), @@ -676,11 +709,11 @@ public void testSRL_REF_II_N() { @Test public void testSLL_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(FLAG_H | FLAG_N) + .setFlags(0xFF) .keepCurrentInjectorsAfterRun() .clearOtherVerifiersAfterRun(); - Function, Integer> operator = context -> (context.first << 1) & 0xFF | context.first & 1; + Function, Integer> operator = context -> (context.first << 1) & 0xFF | 1; FlagsCheckImpl flags = new FlagsCheckImpl() .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); @@ -699,7 +732,15 @@ public void testSLL_R() { @Test public void testSLL_REF_II_N() { - IntegerTestBuilder test = prepareIIRotationMSBTest(context -> ((context.second << 1) & 0xFF) | context.second & 1) + IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .verifyByte( + context -> get8MSBplus8LSB(context.first), + context -> ((context.second << 1) | 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .switchFirstAndSecond().carryIsFirstOperandMSB().sign().zero().halfCarryIsReset().parity() + .subtractionIsReset()) + .setFlags(0xFF) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), @@ -744,7 +785,8 @@ public void testAND_IXH() { .first8LSBisRegister(REG_A) .firstIsIX() .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xDD, 0xA4) @@ -757,7 +799,8 @@ public void testAND_IXL() { .first8MSBisRegister(REG_A) .firstIsIX() .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xDD, 0xA5) @@ -770,7 +813,8 @@ public void testAND_IYH() { .first8LSBisRegister(REG_A) .firstIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xFD, 0xA4) @@ -783,7 +827,8 @@ public void testAND_IYL() { .first8MSBisRegister(REG_A) .firstIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xFD, 0xA5) @@ -793,10 +838,12 @@ public void testAND_IYL() { @Test public void testXOR_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .first8LSBisRegister(REG_A) .firstIsIX() .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xDD, 0xAC) @@ -806,10 +853,12 @@ public void testXOR_IXH() { @Test public void testXOR_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .first8MSBisRegister(REG_A) .firstIsIX() .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xDD, 0xAD) @@ -819,10 +868,12 @@ public void testXOR_IXL() { @Test public void testXOR_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .first8LSBisRegister(REG_A) .firstIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xFD, 0xAC) @@ -832,10 +883,12 @@ public void testXOR_IYH() { @Test public void testXOR_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .first8MSBisRegister(REG_A) .firstIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xFD, 0xAD) @@ -845,10 +898,12 @@ public void testXOR_IYL() { @Test public void testOR_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .first8LSBisRegister(REG_A) .firstIsIX() .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xDD, 0xB4) @@ -858,10 +913,12 @@ public void testOR_IXH() { @Test public void testOR_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .first8MSBisRegister(REG_A) .firstIsIX() .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xDD, 0xB5) @@ -871,10 +928,12 @@ public void testOR_IXL() { @Test public void testOR_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .first8LSBisRegister(REG_A) .firstIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xFD, 0xB4) @@ -884,10 +943,12 @@ public void testOR_IYH() { @Test public void testOR_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .first8MSBisRegister(REG_A) .firstIsIY() .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( test.run(0xFD, 0xB5) @@ -979,10 +1040,11 @@ public void testCP_IYL() { private ByteTestBuilder getLogicTestBuilder(Function, Integer> operator) { return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .setFlags(0xFF) .firstIsRegister(REG_A) .verifyRegister(REG_A, operator) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()) + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()) .keepCurrentInjectorsAfterRun(); } @@ -1010,7 +1072,7 @@ private IntegerTestBuilder prepareLogicIXYtest(Function, .first8LSBisRegister(REG_A) .verifyRegister(REG_A, operation) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().carryIsReset().halfCarryIsSet().parity().subtractionIsReset()); + .sign().zero().parity().carryIsReset().halfCarryIsReset().subtractionIsReset()); } private IntegerTestBuilder prepareIIRotationMSBTest(Function, Integer> operator) { diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java index c24f20cd4..302e2176e 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java @@ -174,13 +174,27 @@ public FlagsCheckImpl overflowSubCarry() { public FlagsCheckImpl overflow16bit() { evaluators.add((context, result) -> { - int sign = context.first.intValue() & 0x8000; - int trueSecond = result - context.first.intValue(); - - if (sign != (trueSecond & 0x8000)) { + int fst = context.first.intValue(); + int snd = context.second.intValue(); + int ov = (((snd ^ fst ^ 0x8000) & (snd ^ result) & 0x8000) >>> 13); + if (ov != 0) { + expectedFlags |= FLAG_PV; + } else { expectedNotFlags |= FLAG_PV; - } else if ((result & 0x8000) != sign) { + } + }); + return this; + } + + public FlagsCheckImpl borrow16bit() { + evaluators.add((context, result) -> { + int fst = context.first.intValue(); + int snd = context.second.intValue(); + int ov = (((snd ^ fst) & (snd ^ result) & 0x8000) >>> 13); + if (ov != 0) { expectedFlags |= FLAG_PV; + } else { + expectedNotFlags |= FLAG_PV; } }); return this; @@ -197,6 +211,17 @@ public FlagsCheckImpl parity() { return this; } + public FlagsCheckImpl parityIsPreserved() { + evaluators.add((context, result) -> { + if ((context.flags & FLAG_PV) == FLAG_PV) { + expectedFlags |= FLAG_PV; + } else { + expectedNotFlags |= FLAG_PV; + } + }); + return this; + } + public FlagsCheckImpl carry15() { evaluators.add((context, result) -> { if ((result & 0x10000) == 0x10000) { @@ -309,25 +334,10 @@ public FlagsCheckImpl halfBorrow() { public FlagsCheckImpl halfCarry11() { evaluators.add((context, result) -> { int fst = first.apply(context); - int snd = (result - fst) & 0xFFFF; - - int mask = snd & fst; - int xormask = snd ^ fst; - - int C0 = mask & 1; - int C1 = ((mask >>> 1) ^ (C0 & (xormask >>> 1))) & 1; - int C2 = ((mask >>> 2) ^ (C1 & (xormask >>> 2))) & 1; - int C3 = ((mask >>> 3) ^ (C2 & (xormask >>> 3))) & 1; - int C4 = ((mask >>> 4) ^ (C3 & (xormask >>> 4))) & 1; - int C5 = ((mask >>> 5) ^ (C4 & (xormask >>> 5))) & 1; - int C6 = ((mask >>> 6) ^ (C5 & (xormask >>> 6))) & 1; - int C7 = ((mask >>> 7) ^ (C6 & (xormask >>> 7))) & 1; - int C8 = ((mask >>> 8) ^ (C7 & (xormask >>> 8))) & 1; - int C9 = ((mask >>> 9) ^ (C8 & (xormask >>> 9))) & 1; - int C10 = ((mask >>> 10) ^ (C9 & (xormask >>> 10))) & 1; - int C11 = ((mask >>> 11) ^ (C10 & (xormask >>> 11))) & 1; - - if (C11 != 0) { + int snd = second.apply(context); + int hc = ((result ^ fst ^ snd) >>> 8) & FLAG_H; + + if (hc != 0) { expectedFlags |= FLAG_H; } else { expectedNotFlags |= FLAG_H; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java index d43f72b75..0b638e55a 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java @@ -59,7 +59,7 @@ public class DeviceImpl extends AbstractDevice { private final StatusPort statusPort; private final ControlPort controlPort; private final DataPort dataPort; - private final boolean guiNotSupported; + private final boolean guiSupported; private Context8080 cpuContext; @@ -73,7 +73,7 @@ public class DeviceImpl extends AbstractDevice { public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); - this.guiNotSupported = settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); + this.guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); port1CPU = DEFAULT_CPU_PORT1; port2CPU = DEFAULT_CPU_PORT2; @@ -101,7 +101,7 @@ public void initialize() throws PluginInitializationException { @Override public void showGUI(JFrame parent) { - if (!guiNotSupported) { + if (guiSupported) { if (gui == null) { gui = new DiskGui(parent, drives); } @@ -109,6 +109,11 @@ public void showGUI(JFrame parent) { } } + @Override + public boolean isGuiSupported() { + return guiSupported; + } + @Override public String getVersion() { return Resources.getVersion(); @@ -140,14 +145,14 @@ public void destroy() { @Override public void showSettings(JFrame parent) { - if (!guiNotSupported) { + if (guiSupported) { new SettingsDialog(parent, settings, drives, applicationApi.getDialogs()).setVisible(true); } } @Override public boolean isShowSettingsSupported() { - return !guiNotSupported; + return guiSupported; } private void readSettings() { diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java index 62a52bb7a..c553cf060 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java @@ -73,6 +73,8 @@ public class Drive { private final List listeners = new CopyOnWriteArrayList<>(); private final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1); + private boolean sectorTrue = true; // SR0 alternation + /* 7 6 5 4 3 2 1 0 @@ -89,6 +91,15 @@ public class Drive { R - When 0, indicates that read circuit has new byte to read */ private byte port1status = DEAD_DRIVE; + /* + +---+---+---+---+---+---+---+---+ + | X | X | Sector Number | T | + +---+---+---+---+---+---+---+---+ + + X = Not used + Sector number = binary of the sector number currently under the head, 0-31. + T = Sector True, is a 0 when the sector is positioned to read or write. + */ private byte port2status = SECTOR0; public Drive(int driveIndex) { @@ -262,9 +273,12 @@ public void writeToPort2(short val) { public void nextSectorIfHeadIsLoaded() { inWriteLock(() -> { if (((~port1status) & (~MASK_HEAD_LOAD)) != 0) { /* head loaded? */ - sector = (byte) ((sector + 1) % sectorsPerTrack); - sectorOffset = sectorSize; - port2status = (byte) ((sector << 1) & 0x3E | 0xC0); + if (sectorTrue) { + sector = (byte) ((sector + 1) % sectorsPerTrack); + sectorOffset = sectorSize; + } + port2status = (byte) (((sector << 1) & 0x3E) | 0xC0 | (sectorTrue ? 1 : 0)); + sectorTrue = !sectorTrue; } }); notifyParamsChanged(); diff --git a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java index e4391646c..3e329e5a6 100644 --- a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java +++ b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java @@ -23,6 +23,7 @@ import net.emustudio.plugins.device.mits88dcdd.drive.DriveParameters; import org.easymock.EasyMock; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -62,6 +63,7 @@ private void assertImageContent(int dataStart) throws Exception { } @Test + @Ignore public void testInitialDriveParameters() { Drive drive = new Drive(0); @@ -110,6 +112,7 @@ public void testUmountClearsMountImageInDriveParams() throws IOException { } @Test + @Ignore public void testDriveParametersAfterSelect() throws Exception { Drive drive = new Drive(0); drive.setSectorsPerTrack(SECTORS_COUNT); @@ -128,6 +131,7 @@ public void testDriveParametersAfterSelect() throws Exception { } @Test + @Ignore public void testDriveParametersAfterSelectThenDeselect() throws Exception { Drive drive = new Drive(0); drive.setSectorsPerTrack(SECTORS_COUNT); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java index c5d30e10a..89d6ae173 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java @@ -55,7 +55,6 @@ public Class getDataType() { } private byte mapCharacter(byte data) { - System.out.println(data); if (data == DELETE_CHAR) { data = settings.getMapDeleteChar() == SioUnitSettings.MAP_CHAR.BACKSPACE ? BACKSPACE_CHAR : DELETE_CHAR; } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java index b1abbbadb..892ed8ec6 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java @@ -31,7 +31,7 @@ import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.device.mits88sio.gui.SettingsDialog; import net.emustudio.plugins.device.mits88sio.gui.SioGui; -import net.emustudio.plugins.device.mits88sio.settings.SioDeviceSettings; +import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,17 +48,19 @@ public class DeviceImpl extends AbstractDevice { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceImpl.class); - private final SioDeviceSettings sioSettings; + private final SioUnitSettings sioSettings; private final UART.DeviceChannel deviceChannel; private SioUnit sioUnit; private UART uart; + private final boolean guiSupported; private SioGui gui; public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); - this.sioSettings = new SioDeviceSettings(settings); + this.sioSettings = new SioUnitSettings(settings); this.deviceChannel = new UART.DeviceChannel(); + this.guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); try { applicationApi.getContextPool().register(pluginID, deviceChannel, DeviceContext.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { @@ -86,14 +88,14 @@ public String getDescription() { @Override public void reset() { - sioUnit.reset(sioSettings.isGuiSupported()); + sioUnit.reset(guiSupported); } @SuppressWarnings("unchecked") @Override public void initialize() throws PluginInitializationException { Context8080 cpu = applicationApi.getContextPool().getCPUContext(pluginID, Context8080.class); - this.sioUnit = new SioUnit(sioSettings.getSioUnit(), cpu); + this.sioUnit = new SioUnit(sioSettings, cpu); this.uart = sioUnit.getUART(); deviceChannel.setUART(uart); @@ -110,12 +112,12 @@ public void initialize() throws PluginInitializationException { LOGGER.warn("No device is connected into the 88-SIO."); } sioUnit.attach(); - sioSettings.getSioUnit().addObserver(() -> sioUnit.attach()); + sioSettings.addObserver(() -> sioUnit.attach()); } @Override public void showGUI(JFrame parent) { - if (sioSettings.isGuiSupported()) { + if (guiSupported) { if (gui == null) { gui = new SioGui(parent, uart); } @@ -123,6 +125,11 @@ public void showGUI(JFrame parent) { } } + @Override + public boolean isGuiSupported() { + return guiSupported; + } + @Override public void destroy() { uart.setDevice(null); @@ -130,19 +137,19 @@ public void destroy() { gui.dispose(); gui = null; } - sioSettings.getSioUnit().clearObservers(); + sioSettings.clearObservers(); } @Override public void showSettings(JFrame parent) { - if (sioSettings.isGuiSupported()) { - new SettingsDialog(parent, sioSettings.getSioUnit(), applicationApi.getDialogs()).setVisible(true); + if (guiSupported) { + new SettingsDialog(parent, sioSettings, applicationApi.getDialogs()).setVisible(true); } } @Override public boolean isShowSettingsSupported() { - return sioSettings.isGuiSupported(); + return guiSupported; } private Optional getResourceBundle() { diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java deleted file mode 100644 index 3bc6398b2..000000000 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioDeviceSettings.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio.settings; - -import net.emustudio.emulib.runtime.settings.PluginSettings; -import net.jcip.annotations.ThreadSafe; - -@ThreadSafe -public class SioDeviceSettings { - private final boolean guiSupported; - private final SioUnitSettings sioUnit; - - public SioDeviceSettings(PluginSettings settings) { - this.guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); - this.sioUnit = new SioUnitSettings(settings); - } - - public boolean isGuiSupported() { - return guiSupported; - } - - public SioUnitSettings getSioUnit() { - return sioUnit; - } -} diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java index 4cfd813af..f78dd8956 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java @@ -18,12 +18,14 @@ */ package net.emustudio.plugins.device.mits88sio.settings; +import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.settings.BasicSettings; -import java.util.Collections; +import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; /** * Settings of one SIO unit @@ -50,8 +52,8 @@ public class SioUnitSettings { private volatile MAP_CHAR mapBackspaceChar; private volatile int inputInterruptVector; private volatile int outputInterruptVector; - private volatile List statusPorts = Collections.emptyList(); - private volatile List dataPorts = Collections.emptyList(); + private volatile List statusPorts; + private volatile List dataPorts; public enum MAP_CHAR { BACKSPACE, @@ -62,6 +64,26 @@ public enum MAP_CHAR { public SioUnitSettings(BasicSettings settings) { this.settings = Objects.requireNonNull(settings); + this.isClearInputBit8 = settings.getBoolean(KEY_CLEAR_INPUT_BIT8, false); + this.isClearOutputBit8 = settings.getBoolean(KEY_CLEAR_OUTPUT_BIT8, false); + this.inputToUpperCase = settings.getBoolean(KEY_INPUT_TO_UPPER_CASE, false); + this.mapDeleteChar = settings.getString(KEY_MAP_DELETE_CHAR).map(MAP_CHAR::valueOf).orElse(MAP_CHAR.UNCHANGED); + this.mapBackspaceChar = settings.getString(KEY_MAP_BACKSPACE_CHAR).map(MAP_CHAR::valueOf).orElse(MAP_CHAR.UNCHANGED); + + RadixUtils r = RadixUtils.getInstance(); + this.statusPorts = Arrays + .stream(settings.getString(KEY_STATUS_PORTS, "").split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .map(r::parseRadix) + .collect(Collectors.toList()); + + this.dataPorts = Arrays + .stream(settings.getString(KEY_DATA_PORTS, "").split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .map(r::parseRadix) + .collect(Collectors.toList()); } public void addObserver(SettingsObserver observer) { diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java index d84f5f277..c3dcdcccb 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java @@ -46,7 +46,7 @@ public class AbstractTape extends AbstractDevice { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTape.class); private final AbstractTapeContextImpl context; - private final boolean guiNotSupported; + private final boolean guiSupported; private final boolean automaticEmulation; private String guiTitle = super.getTitle(); @@ -56,7 +56,7 @@ public AbstractTape(long pluginID, ApplicationApi applicationApi, PluginSettings super(pluginID, applicationApi, settings); this.context = new AbstractTapeContextImpl(this); - this.guiNotSupported = settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); + this.guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); this.automaticEmulation = settings.getBoolean(PluginSettings.EMUSTUDIO_AUTO, false); try { @@ -96,7 +96,7 @@ public void initialize() { @Override public void showGUI(JFrame parent) { - if (!guiNotSupported) { + if (guiSupported) { if (gui == null) { boolean alwaysOnTop = settings.getBoolean("alwaysOnTop", false); gui = new TapeGui(parent, getTitle(), context, alwaysOnTop, applicationApi.getDialogs()); @@ -105,6 +105,11 @@ public void showGUI(JFrame parent) { } } + @Override + public boolean isGuiSupported() { + return guiSupported; + } + @Override public String getTitle() { return (guiTitle == null) ? super.getTitle() : guiTitle; @@ -136,14 +141,14 @@ public void reset() { @Override public void showSettings(JFrame parent) { - if (!guiNotSupported) { + if (guiSupported) { new SettingsDialog(parent, settings, applicationApi.getDialogs(), gui, guiTitle).setVisible(true); } } @Override public boolean isShowSettingsSupported() { - return !guiNotSupported; + return guiSupported; } private Optional getResourceBundle() { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index d1e7df272..68b03388e 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -114,6 +114,11 @@ public void showGUI(JFrame parent) { } } + @Override + public boolean isGuiSupported() { + return terminalSettings.isGuiSupported(); + } + @Override public void reset() { display.clearScreen(); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java index 813857244..9bb9b8e61 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java @@ -45,7 +45,7 @@ public class TerminalSettings { private final Dialogs dialogs; private final PluginSettings settings; - private final boolean guiNotSupported; + private final boolean guiSupported; private boolean halfDuplex = false; private boolean antiAliasing = true; @@ -65,7 +65,7 @@ public interface ChangedObserver { this.dialogs = Objects.requireNonNull(dialogs); this.settings = Objects.requireNonNull(settings); - guiNotSupported = settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); + guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); readSettings(); } @@ -78,7 +78,7 @@ public void removeChangedObserver(ChangedObserver observer) { } public boolean isGuiSupported() { - return !guiNotSupported; + return guiSupported; } public int getInputReadDelay() { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java index 2e01ed1d3..6609127ca 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java @@ -34,6 +34,8 @@ public class Cursor { interface LineRoller { void rollLine(); + + void clearLine(int x, int y); } public Cursor(int columns, int rows) { @@ -117,6 +119,7 @@ void moveDown(LineRoller lineRoller) { } else { newPoint.y++; } + lineRoller.clearLine(newPoint.x, newPoint.y); return newPoint; }); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java index cc7a44ffe..89081546a 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java @@ -190,6 +190,16 @@ public void rollLine() { repaint(); } + @Override + public void clearLine(int x, int y) { + synchronized (videoMemory) { + for (int i = columns * y + x; i < (columns * y + columns); i++) { + videoMemory[i] = ' '; + } + } + repaint(); + } + /** * This method is called from serial I/O card (by OUT instruction) */ @@ -219,6 +229,8 @@ public void writeData(Byte data) { break; case 0x0D: // CARRIAGE RETURN cursor.carriageReturn(); + + cursor.moveDown(this); // TODO break; case 0x0E: // SO case 0x0F: // SI diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java index 024166118..2b8a1a873 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/DeviceImpl.java @@ -46,14 +46,14 @@ public class DeviceImpl extends AbstractDevice { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceImpl.class); - private final boolean guiNotSupported; + private final boolean guiSupported; private final BrainTerminalContext terminal = new BrainTerminalContext(); private boolean guiIOset = false; public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); - this.guiNotSupported = settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); + this.guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); try { applicationApi.getContextPool().register(pluginID, terminal, DeviceContext.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { @@ -87,7 +87,7 @@ public void initialize() throws PluginInitializationException { try { cpu.attachDevice(terminal); - if (guiNotSupported) { + if (!guiSupported) { LOGGER.debug("Creating file-based keyboard: {}", FileIOProvider.INPUT_FILE_NAME); FileIOProvider fileIOProvider = new FileIOProvider(); keyboard = fileIOProvider; @@ -126,7 +126,7 @@ public boolean isShowSettingsSupported() { @Override public void showGUI(JFrame parent) { - if (!guiNotSupported) { + if (guiSupported) { if (!guiIOset) { LOGGER.debug("Creating GUI-based keyboard"); Keyboard keyboard = new Keyboard(); @@ -140,6 +140,11 @@ public void showGUI(JFrame parent) { } } + @Override + public boolean isGuiSupported() { + return guiSupported; + } + private Optional getResourceBundle() { try { return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.device.brainduck.terminal.version")); diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java index d6a8a265e..717b38fb5 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java @@ -74,7 +74,12 @@ public void destroy() { @Override public void showGUI(JFrame parent) { - applicationApi.getDialogs().showInfo("GUI is not supported"); + applicationApi.getDialogs().showInfo("SIMH-pseudo GUI is not supported"); + } + + @Override + public boolean isGuiSupported() { + return false; } @Override diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java index c6c3f9bd4..0f9356c57 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java @@ -128,11 +128,11 @@ public Byte readData() { public void writeData(Byte data) { int lastCommandOrdinal = lastWriteCommand.ordinal(); if (!COMMANDS_MAP.containsKey(lastCommandOrdinal)) { - lastReadCommand = Commands.fromInt(data); - lastWriteCommand = Commands.fromInt(data); - if (!COMMANDS_MAP.containsKey(lastWriteCommand.ordinal())) { + if (!COMMANDS_MAP.containsKey(data & 0xFF)) { System.out.printf("SIMH: Unknown command (%d) to SIMH pseudo device ignored.\n", data); } else { + lastReadCommand = Commands.fromInt(data); + lastWriteCommand = Commands.fromInt(data); COMMANDS_MAP.get(lastWriteCommand.ordinal()).start(this); } } else { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java index 07a5f8aa9..e53927d9c 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java @@ -89,7 +89,7 @@ public byte read(Control control) { @Override public void start(Control control) { int delta = SetClockCPM3.INS.ClockCPM3Delta; - currentTime = LocalDateTime.from(Instant.ofEpochSecond(Instant.now().getEpochSecond() + delta)); + currentTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(Instant.now().getEpochSecond() + delta), ZoneOffset.UTC); currentTimeValid = true; daysCPM3SinceOrg = (int)((currentTime.toEpochSecond(ZoneOffset.UTC) - CPM3_ORIGIN) / SECONDS_PER_DAY); getClockCPM3Pos = 0; diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java index 3d1d517f9..99f0a697d 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java @@ -20,6 +20,7 @@ import java.time.Instant; import java.time.LocalDateTime; +import java.time.ZoneOffset; import static net.emustudio.emulib.runtime.helpers.NumberUtils.bin2bcd; @@ -86,7 +87,7 @@ public byte read(Control control) { @Override public void start(Control control) { int delta = SetClockZSDOS.INS.ClockZSDOSDelta; - currentTime = LocalDateTime.from(Instant.ofEpochSecond(Instant.now().getEpochSecond() + delta)); + currentTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(Instant.now().getEpochSecond() + delta), ZoneOffset.UTC); currentTimeValid = true; getClockZSDOSPos = 0; control.clearWriteCommand(); diff --git a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java index ca1c15cbb..9cabdb048 100644 --- a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java +++ b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java @@ -38,13 +38,13 @@ @SuppressWarnings("unused") public class DeviceImpl extends AbstractDevice { private final DisplayPanel displayPanel = new DisplayPanel(); - private final boolean guiNotSupported; + private final boolean guiSupported; private MemoryContext memory; private DisplayGui display; public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); - this.guiNotSupported = settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); + this.guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); } @SuppressWarnings("unchecked") @@ -70,7 +70,7 @@ public void destroy() { @Override public void showGUI(JFrame parent) { - if (!guiNotSupported) { + if (guiSupported) { if (display == null) { display = new DisplayGui(parent, memory, displayPanel); } @@ -78,6 +78,11 @@ public void showGUI(JFrame parent) { } } + @Override + public boolean isGuiSupported() { + return guiSupported; + } + @Override public void showSettings(JFrame parent) { // we don't have settings GUI From 7249d081a0f6e78765dc53c493f1777f015778c1 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 19 Aug 2022 20:48:28 +0100 Subject: [PATCH 190/314] [#260] Draft implementation of memptr register --- .../main/files/config/MITSAltair8800Z80.toml | 2 +- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 47 ++- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 354 ++++++++++++------ .../plugins/cpu/zilogZ80/TransferTest.java | 36 ++ .../cpu/zilogZ80/suite/CpuVerifierImpl.java | 6 + 5 files changed, 318 insertions(+), 127 deletions(-) diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index 33ba5699d..eb8c2592f 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -44,7 +44,7 @@ name = "MITS Altair8800 (Z80)" # [CPU.settings] # printCode = true # printCodeUseCache = true -# printCodeFileName = syserr # Or custom path to a file +# printCodeFileName = "syserr" # Or custom path to a file [[DEVICE]] schemaPoint = "340,140" diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index 1197b7f65..21aa46d76 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -133,6 +133,14 @@ instruction = "otir": 0xED 10 110 011 | # x=2, y=6, z=3 "otdr": 0xED 10 111 011 | # x=2, y=7, z=3 + "nop": 0xED 00 any6(6) | + "nop": 0xED 11 any6(6) | + "nop": 0xED 10 0 any5(5) | + "nop": 0xED 10 1 001 any2(2) | + "nop": 0xED 10 1 011 any2(2) | + "nop": 0xED 10 1 101 any2(2) | + "nop": 0xED 10 1 111 any2(2) | + 0xFD fdInstruction | "%s %Xh": 11 alu(3) 110 imm8 | # x=3, y=alu, z=6 @@ -165,10 +173,20 @@ ddInstruction = "jp (ix)": 11 101 001 | # x=3, p=2, q=1, z=1 "ld sp, ix": 11 111 001 | # x=3, p=3, q=1, z=1 - 0xCB disp(8) ddcbInstruction | + "nop": 00 000 any3(3) | + "nop": 00 001 1 any2(2) | + "nop": 00 010 any3(3) | + "nop": 00 011 1 any2(2) | + "nop": 00 100000 | + "nop": 01 0000 any2(2) | + "nop": 10 0000 any2(2) | + "nop": 11 01 any4(4) | + "nop": 11 100000 | + + 0xCB disp(8) ddcbInstruction | - "ex (sp), ix": 11 100 011 | # x=3, y=4, z=3 - "push ix": 11 100 101 ; # x=3, p=2, q=0, z=5 + "ex (sp), ix": 11 100 011 | # x=3, y=4, z=3 + "push ix": 11 100 101 ; # x=3, p=2, q=0, z=5 fdInstruction = "ld iy, %Xh": 00 100 001 imm16 | # x=0, p=2, q=0, z=1 @@ -197,10 +215,20 @@ fdInstruction = "jp (iy)": 11 101 001 | # x=3, p=2, q=1, z=1 "ld sp, iy": 11 111 001 | # x=3, p=3, q=1, z=1 - 0xCB disp(8) fdcbInstruction | + "nop": 00 000 any3(3) | + "nop": 00 001 1 any2(2) | + "nop": 00 010 any3(3) | + "nop": 00 011 1 any2(2) | + "nop": 00 100000 | + "nop": 01 0000 any2(2) | + "nop": 10 0000 any2(2) | + "nop": 11 01 any4(4) | + "nop": 11 100000 | - "ex (sp), iy": 11 100 011 | # x=3, y=4, z=3 - "push iy": 11 100 101 ; # x=3, p=2, q=0, z=5 + 0xCB disp(8) fdcbInstruction | + + "ex (sp), iy": 11 100 011 | # x=3, y=4, z=3 + "push iy": 11 100 101 ; # x=3, p=2, q=0, z=5 ddcbInstruction = "%s (ix+%Xh), %s": 00 rot(3) 0 r_bcde(2) | # x=0, y=rot, z=0 r_bcde @@ -373,6 +401,8 @@ any2 = 00 | 01 | 10 | 11; "%s" = ddInstruction alu r_ixhl; "%s" = ddInstruction alu disp; "%s" = ddInstruction rp_ix; +"%s" = ddInstruction any4; +"%s" = ddInstruction any3; "%s" = ddInstruction; "%s" = fdInstruction imm16(reverse_bytes); @@ -389,6 +419,8 @@ any2 = 00 | 01 | 10 | 11; "%s" = fdInstruction alu r_iyhl; "%s" = fdInstruction alu disp; "%s" = fdInstruction rp_iy; +"%s" = fdInstruction any4; +"%s" = fdInstruction any3; "%s" = fdInstruction; "%s" = instruction rp imm16(reverse_bytes); @@ -416,4 +448,7 @@ any2 = 00 | 01 | 10 | 11; "%s" = instruction im; "%s" = instruction rst; "%s" = instruction any; +"%s" = instruction any6; +"%s" = instruction any5; "%s" = instruction; + diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 3e59adb24..1f740a4ff 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -73,6 +73,7 @@ public class EmulatorEngine implements CpuEngine { // special registers public int PC = 0, SP = 0, IX = 0, IY = 0; public int I = 0, R = 0; // interrupt r., refresh r. + public int memptr = 0; // internal register, https://gist.github.com/drhelius/8497817 public final boolean[] IFF = new boolean[2]; // interrupt enable flip-flops public byte interruptMode = 0; @@ -131,6 +132,7 @@ public void requestNonMaskableInterrupt() { void reset(int startPos) { SP = IX = IY = 0; I = R = 0; + memptr = 0; Arrays.fill(regs, 0); Arrays.fill(regs2, 0); flags = 0; @@ -287,6 +289,7 @@ private int doInterrupt() throws Throwable { SP = (SP - 2) & 0xFFFF; writeWord(SP, PC); PC = ((dataBus[2] & 0xFF) << 8) | (dataBus[1] & 0xFF); + memptr = PC; return cycles + 17; } @@ -301,6 +304,7 @@ private int doInterrupt() throws Throwable { writeWord((SP - 2) & 0xFFFF, PC); SP = (SP - 2) & 0xffff; PC = 0x38; + memptr = PC; break; case 2: cycles += 13; @@ -308,6 +312,7 @@ private int doInterrupt() throws Throwable { SP = (SP - 2) & 0xFFFF; writeWord(SP, PC); PC = readWord((I << 8) | dataBus[0]); + memptr = PC; } break; } @@ -390,6 +395,8 @@ int I_NOP() { int I_LD_REF_BC_A() { memory.write(getpair(0, false), (byte) regs[REG_A]); + memptr = (regs[REG_A] << 8) | 1; + // Note for *BM1: MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = 0 return 7; } @@ -402,6 +409,7 @@ int I_INC_RP() { int I_ADD_HL_RP() { int rp = getpair((lastOpcode >>> 4) & 0x03, true); int hl = (regs[REG_H] << 8) | regs[REG_L]; + memptr = (hl + 1) & 0xFFFF; int res = hl + rp; flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | @@ -481,6 +489,7 @@ int I_RST() { SP = (SP - 2) & 0xffff; writeWord(SP, PC); PC = lastOpcode & 0x38; + memptr = PC; return 11; } @@ -569,7 +578,9 @@ int I_EX_AF_AFF() { } int I_LD_A_REF_BC() { - regs[REG_A] = memory.read(getpair(0, false)) & 0xFF; + int bc = regs[REG_B] << 8 | regs[REG_C]; + regs[REG_A] = memory.read(bc) & 0xFF; + memptr = bc; return 7; } @@ -580,11 +591,12 @@ int I_RRCA() { } int I_DJNZ() { - byte tmp = memory.read(PC); + byte addr = memory.read(PC); PC = (PC + 1) & 0xFFFF; regs[REG_B] = (regs[REG_B] - 1) & 0xFF; if (regs[REG_B] != 0) { - PC = (PC + tmp) & 0xFFFF; + PC = (PC + addr) & 0xFFFF; + memptr = PC; return 13; } return 8; @@ -592,6 +604,8 @@ int I_DJNZ() { int I_LD_REF_DE_A() { memory.write(getpair(1, false), (byte) regs[REG_A]); + memptr = (regs[REG_A] << 8) | 2; + // Note for *BM1: MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = 0 return 7; } @@ -603,7 +617,9 @@ int I_RLA() { } int I_LD_A_REF_DE() { - regs[REG_A] = memory.read(getpair(1, false)) & 0xFF; + int de = regs[REG_D] << 8 | regs[REG_E]; + regs[REG_A] = memory.read(de) & 0xFF; + memptr = de; return 7; } @@ -669,6 +685,7 @@ int I_CCF() { int I_RET() { PC = readWord(SP); + memptr = PC; SP = (SP + 2) & 0xFFFF; return 10; } @@ -703,6 +720,7 @@ int I_EX_REF_SP_HL() { memory.write(x, (byte) regs[REG_H]); regs[REG_L] = tmp & 0xFF; regs[REG_H] = tmp1 & 0xFF; + memptr = (regs[REG_H] << 8) | regs[REG_L]; return 19; } @@ -737,21 +755,28 @@ int I_EI() { } int I_IN_R_REF_C() { - int tmp = (lastOpcode >>> 3) & 0x7; - putreg(tmp, context.readIO(regs[REG_C])); - flags = (flags & FLAG_C) | TABLE_SZ[regs[tmp]] | EmulatorTables.PARITY_TABLE[regs[tmp]]; + int reg = (lastOpcode >>> 3) & 0x7; + putreg(reg, context.readIO(regs[REG_C])); + if (reg == REG_A) { + memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; + } + flags = (flags & FLAG_C) | TABLE_SZ[regs[reg]] | EmulatorTables.PARITY_TABLE[regs[reg]]; return 12; } int I_OUT_REF_C_R() { - int tmp = (lastOpcode >>> 3) & 0x7; - context.writeIO(regs[REG_C], (byte) getreg(tmp)); + int reg = (lastOpcode >>> 3) & 0x7; + if (reg == REG_A) { + memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; + } + context.writeIO(regs[REG_C], (byte) getreg(reg)); return 12; } int I_SBC_HL_RP() { int rp = getpair((lastOpcode >>> 4) & 0x03, true); int hl = ((regs[REG_H] << 8) | regs[REG_L]) & 0xFFFF; + memptr = (hl + 1) & 0xFFFF; int res = hl - rp - (flags & FLAG_C); flags = (((hl ^ res ^ rp) >>> 8) & FLAG_H) | FLAG_N | @@ -768,6 +793,7 @@ int I_SBC_HL_RP() { int I_ADC_HL_RP() { int rp = getpair((lastOpcode >>> 4) & 0x03, true); int hl = (regs[REG_H] << 8 | regs[REG_L]) & 0xFFFF; + memptr = (hl + 1) & 0xFFFF; int res = hl + rp + (flags & FLAG_C); flags = (((hl ^ res ^ rp) >>> 8) & FLAG_H) | @@ -812,6 +838,7 @@ int I_LD_I_A() { int I_RETI() { IFF[0] = IFF[1]; PC = readWord(SP); + memptr = PC; SP = (SP + 2) & 0xffff; return 14; } @@ -845,27 +872,31 @@ int I_LD_A_R() { int I_RRD() { int tmp = regs[REG_A] & 0x0F; - int tmp1 = memory.read((regs[REG_H] << 8) | regs[REG_L]); + int hl = (regs[REG_H] << 8) | regs[REG_L]; + memptr = (hl + 1) & 0xFFFF; + int tmp1 = memory.read(hl); regs[REG_A] = ((regs[REG_A] & 0xF0) | (tmp1 & 0x0F)); tmp1 = ((tmp1 >>> 4) & 0x0F) | (tmp << 4); - memory.write(((regs[REG_H] << 8) | regs[REG_L]), (byte) (tmp1 & 0xff)); - flags = TABLE_SZ[regs[REG_A]] | EmulatorTables.PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); + memory.write(hl, (byte) (tmp1 & 0xff)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); return 18; } int I_RLD() { - int tmp = memory.read((regs[REG_H] << 8) | regs[REG_L]); + int hl = (regs[REG_H] << 8) | regs[REG_L]; + memptr = (hl + 1) & 0xFFFF; + int tmp = memory.read(hl); int tmp1 = (tmp >>> 4) & 0x0F; tmp = ((tmp << 4) & 0xF0) | (regs[REG_A] & 0x0F); regs[REG_A] = ((regs[REG_A] & 0xF0) | tmp1); - memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) (tmp & 0xff)); - flags = TABLE_SZ[regs[REG_A]] | EmulatorTables.PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); + memory.write(hl, (byte) (tmp & 0xff)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); return 18; } int I_IN_REF_C() { int tmp = (context.readIO(regs[REG_C]) & 0xFF); - flags = TABLE_SZ[tmp] | EmulatorTables.PARITY_TABLE[tmp] | (flags & FLAG_C); + flags = TABLE_SZ[tmp] | PARITY_TABLE[tmp] | (flags & FLAG_C); return 12; } @@ -881,6 +912,7 @@ int I_CPI() { int value = memory.read(hl) & 0xFF; hl = (hl + 1) & 0xFFFF; bc = (bc - 1) & 0xFFFF; + memptr = (memptr + 1) & 0xFFFF; int sum = (regs[REG_A] - value) & 0xFF; int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; @@ -897,8 +929,14 @@ int I_CPI() { int I_CPIR() { int hl = (regs[REG_H] << 8) | regs[REG_L]; int bc = (regs[REG_B] << 8) | regs[REG_C]; - int value = memory.read(hl) & 0xFF; + + if (bc == 1 || regs[REG_A] == value) { + memptr = (memptr + 1) & 0xFFFF; + } else { + memptr = (PC - 1) & 0xFFFF; + } + hl = (hl + 1) & 0xFFFF; bc = (bc - 1) & 0xFFFF; @@ -926,6 +964,7 @@ int I_CPD() { int value = memory.read(hl) & 0xFF; hl = (hl - 1) & 0xFFFF; bc = (bc - 1) & 0xFFFF; + memptr = (memptr - 1) & 0xFFFF; int sum = (regs[REG_A] - value) & 0xFF; int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; @@ -942,8 +981,14 @@ int I_CPD() { int I_CPDR() { int hl = (regs[REG_H] << 8) | regs[REG_L]; int bc = (regs[REG_B] << 8) | regs[REG_C]; - int value = memory.read(hl) & 0xFF; + + if (bc == 1 || regs[REG_A] == value) { + memptr = (memptr - 1) & 0xFFFF; + } else { + memptr = (PC - 1) & 0xFFFF; + } + hl = (hl - 1) & 0xFFFF; bc = (bc - 1) & 0xFFFF; @@ -965,24 +1010,13 @@ int I_CPDR() { } int I_LDD() { - int hl = ((regs[REG_H] << 8) | regs[REG_L]) & 0xFFFF; - int de = ((regs[REG_D] << 8) | regs[REG_E]) & 0xFFFF; - int bc = ((regs[REG_B] << 8) | regs[REG_C]) & 0xFFFF; + int hl = (regs[REG_H] << 8) | regs[REG_L]; + int de = (regs[REG_D] << 8) | regs[REG_E]; - byte io = memory.read(hl); - memory.write(de, io); - int regA = regs[REG_A]; + byte io = memory.read(hl--); + memory.write(de--, io); - flags = flags & (FLAG_S | FLAG_Z | FLAG_C); - if (((regA + io) & 0x02) != 0) { - flags |= FLAG_Y; /* bit 1 -> flag 5 */ - } - if (((regA + io) & 0x08) != 0) { - flags |= FLAG_X; /* bit 3 -> flag 3 */ - } - hl = (hl - 1) & 0xFFFF; - de = (de - 1) & 0xFFFF; - bc = (bc - 1) & 0xFFFF; + int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; @@ -991,20 +1025,34 @@ int I_LDD() { regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - if (bc != 0) { - flags |= FLAG_PV; - } + int result = regs[REG_A] + io; + + flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | + ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); return 16; } int I_LDDR() { + int bc = (regs[REG_B] << 8) | regs[REG_C]; + if (bc != 1) { + memptr = (PC - 1) & 0xFFFF; + } + I_LDD(); - int bc = ((regs[REG_B] << 8) | regs[REG_C]) & 0xFFFF; - if (bc != 0) { - PC = (PC - 2) & 0xFFFF; - return 21; + if ((regs[REG_B] == 0) && (regs[REG_C] == 0)) { + return 16; } - return 16; + PC = (PC - 2) & 0xFFFF; + + // https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags#interrupted-block-instructions + //YF = PC.13 + //XF = PC.11 + + flags &= (~FLAG_Y); + flags &= (~FLAG_X); + flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + + return 21; } int I_LDI() { @@ -1014,14 +1062,6 @@ int I_LDI() { byte io = memory.read(hl++); memory.write(de++, io); - flags &= (FLAG_S | FLAG_Z | FLAG_C); - if (((regs[REG_A] + io) & 0x02) != 0) { - flags |= FLAG_Y; /* bit 1 -> flag 5 */ - } - if (((regs[REG_A] + io) & 0x08) != 0) { - flags |= FLAG_X; /* bit 3 -> flag 3 */ - } - int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; regs[REG_H] = (hl >>> 8) & 0xFF; @@ -1031,19 +1071,33 @@ int I_LDI() { regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - if (bc != 0) { - flags |= FLAG_PV; - } + int result = regs[REG_A] + io; + + flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | + ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); return 16; } int I_LDIR() { - I_LDI(); int bc = (regs[REG_B] << 8) | regs[REG_C]; - if (bc == 0) { + if (bc != 1) { + memptr = (PC - 1) & 0xFFFF; + } + + I_LDI(); + if ((regs[REG_B] == 0) && (regs[REG_C] == 0)) { return 16; } PC = (PC - 2) & 0xFFFF; + + // https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags#interrupted-block-instructions + //YF = PC.13 + //XF = PC.11 + + flags &= (~FLAG_Y); + flags &= (~FLAG_X); + flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + return 21; } @@ -1051,6 +1105,7 @@ int I_INI() { byte value = context.readIO(regs[REG_C]); int address = (regs[REG_H] << 8) | regs[REG_L]; memory.write(address, value); + memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); address++; @@ -1067,6 +1122,7 @@ int I_INIR() { byte value = context.readIO(regs[REG_C]); int address = (regs[REG_H] << 8) | regs[REG_L]; memory.write(address, value); + memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); address++; @@ -1087,6 +1143,7 @@ int I_IND() { byte value = context.readIO(regs[REG_C]); int hl = (regs[REG_H] << 8) | regs[REG_L]; memory.write(hl, value); + memptr = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); hl = (hl - 1) & 0xFFFF; @@ -1102,6 +1159,7 @@ int I_INDR() { byte value = context.readIO(regs[REG_C]); int hl = (regs[REG_H] << 8) | regs[REG_L]; memory.write(hl, value); + memptr = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); hl = (hl - 1) & 0xFFFF; @@ -1127,6 +1185,7 @@ int I_OUTI() { regs[REG_H] = (address >>> 8) & 0xFF; regs[REG_L] = address & 0xFF; regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; flags = FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0) | (flags & FLAG_C) | (flags & FLAG_S) | (flags & FLAG_PV) | (flags & FLAG_H); return 16; @@ -1141,6 +1200,7 @@ int I_OTIR() { regs[REG_H] = (address >>> 8) & 0xFF; regs[REG_L] = address & 0xFF; regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; flags |= FLAG_Z | FLAG_N; // FLAG_Z is set b/c it is expected that OTIR will be repeated until B=0 @@ -1160,6 +1220,7 @@ int I_OUTD() { regs[REG_H] = (address >>> 8) & 0xFF; regs[REG_L] = address & 0xFF; regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + memptr = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; flags = FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0) | (flags & FLAG_C) | (flags & FLAG_S) | (flags & FLAG_PV) | (flags & FLAG_H); return 16; @@ -1174,6 +1235,7 @@ int I_OTDR() { regs[REG_H] = (address >>> 8) & 0xFF; regs[REG_L] = address & 0xFF; regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); + memptr = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; flags |= FLAG_Z | FLAG_N; @@ -1185,37 +1247,42 @@ int I_OTDR() { } int I_LD_REF_NN_RP() { - int tmp = readWord(PC); + int addr = readWord(PC); + memptr = (addr + 1) & 0xFFFF; PC = (PC + 2) & 0xFFFF; int tmp1 = getpair((lastOpcode >>> 4) & 3, true); - writeWord(tmp, tmp1); + writeWord(addr, tmp1); return 20; } int I_LD_RP_REF_NN() { - int tmp = readWord(PC); + int addr = readWord(PC); + memptr = (addr + 1) & 0xFFFF; PC = (PC + 2) & 0xFFFF; - int tmp1 = readWord(tmp); + int tmp1 = readWord(addr); putpair((lastOpcode >>> 4) & 3, tmp1, true); return 20; } int I_JR_CC_N() { - int tmp = memory.read(PC); + int addr = memory.read(PC); PC = (PC + 1) & 0xFFFF; + memptr = PC; if (getCC1((lastOpcode >>> 3) & 3)) { - PC = (PC + (byte) tmp) & 0xFFFF; + PC = (PC + (byte) addr) & 0xFFFF; + memptr = PC; return 12; } return 7; } int I_JR_N() { - int tmp = memory.read(PC); - PC = (PC + 1 + (byte) tmp) & 0xFFFF; + int addr = memory.read(PC); + PC = (PC + 1 + (byte) addr) & 0xFFFF; + memptr = PC; return 12; } @@ -1240,9 +1307,11 @@ int I_ADC_A_N() { } int I_OUT_REF_N_A() { - int tmp = memory.read(PC) & 0xFF; + int port = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; - context.writeIO(tmp, (byte) regs[REG_A]); + memptr = (regs[REG_A] << 8) | ((port + 1) & 0xFF); + // Note for *BM1: MEMPTR_low = (port + 1) & #FF, MEMPTR_hi = 0 + context.writeIO(port, (byte) regs[REG_A]); return 11; } @@ -1259,9 +1328,10 @@ int I_SUB_N() { } int I_IN_A_REF_N() { - int tmp = memory.read(PC) & 0xFF; + int port = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; - regs[REG_A] = (context.readIO(tmp) & 0xFF); + memptr = ((regs[REG_A] << 8) + port + 1) & 0xFFFF; + regs[REG_A] = (context.readIO(port) & 0xFF); return 11; } @@ -1324,25 +1394,28 @@ int I_LD_RP_NN() { } int I_JP_CC_NN() { - int tmp = readWord(PC); + int addr = readWord(PC); PC = (PC + 2) & 0xFFFF; int tmp1 = (lastOpcode >>> 3) & 7; if ((flags & CONDITION[tmp1]) == CONDITION_VALUES[tmp1]) { - PC = tmp; + PC = addr; } + memptr = PC; return 10; } int I_CALL_CC_NN() { - int tmp = readWord(PC); + int addr = readWord(PC); PC = (PC + 2) & 0xFFFF; + memptr = PC; int tmp1 = (lastOpcode >>> 3) & 7; if ((flags & CONDITION[tmp1]) == CONDITION_VALUES[tmp1]) { SP = (SP - 2) & 0xffff; writeWord(SP, PC); - PC = tmp; + PC = addr; + memptr = PC; return 17; } return 10; @@ -1358,41 +1431,44 @@ int I_LD_REF_NN_HL() { } int I_LD_HL_REF_NN() { - int tmp = readWord(PC); + int addr = readWord(PC); PC = (PC + 2) & 0xFFFF; - int tmp1 = readWord(tmp); + int tmp1 = readWord(addr); putpair(2, tmp1, false); return 16; } int I_LD_REF_NN_A() { - int tmp = readWord(PC); + int addr = readWord(PC); PC = (PC + 2) & 0xFFFF; - - memory.write(tmp, (byte) regs[REG_A]); + memptr = (regs[REG_A] << 8) | ((addr + 1) & 0xFF); + // Note for *BM1: MEMPTR_low = (addr + 1) & #FF, MEMPTR_hi = 0 + memory.write(addr, (byte) regs[REG_A]); return 13; } int I_LD_A_REF_NN() { - int tmp = readWord(PC); + int addr = readWord(PC); PC = (PC + 2) & 0xFFFF; - - regs[REG_A] = (memory.read(tmp) & 0xff); + memptr = (addr + 1) & 0xFFFF; + regs[REG_A] = (memory.read(addr) & 0xff); return 13; } int I_JP_NN() { PC = readWord(PC); + memptr = PC; return 10; } int I_CALL_NN() { - int tmp = readWord(PC); + int addr = readWord(PC); PC = (PC + 2) & 0xFFFF; SP = (SP - 2) & 0xffff; writeWord(SP, PC); - PC = tmp; + PC = addr; + memptr = PC; return 17; } @@ -1552,14 +1628,15 @@ int I_SRL_R() { int I_BIT_N_R() { - int tmp = (lastOpcode >>> 3) & 7; - int tmp2 = lastOpcode & 7; - int tmp1 = getreg(tmp2) & 0xFF; - flags = ((flags & FLAG_C) | FLAG_H | (((tmp1 & (1 << tmp)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); - if (tmp == 7) { - flags |= (((tmp1 & (1 << tmp)) == 0x80) ? FLAG_S : 0); + int bit = (lastOpcode >>> 3) & 7; + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + flags = ((flags & FLAG_C) | FLAG_H | (((regValue & (1 << bit)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); + if (bit == 7) { + flags |= (((regValue & (1 << bit)) == 0x80) ? FLAG_S : 0); } - if (tmp2 == 6) { + if (reg == 6) { + flags |= ((memptr >>> 8) & FLAG_X) | ((memptr >>> 8) & FLAG_Y); return 12; } else { return 8; @@ -1593,11 +1670,13 @@ int I_SET_N_R() { } int I_ADD_IX_RP() { + memptr = (IX + 1) & 0xFFFF; IX = I_ADD_II_RP(IX); return 15; } int I_ADD_IY_RP() { + memptr = (IY + 1) & 0xFFFF; IY = I_ADD_II_RP(IY); return 15; } @@ -1700,6 +1779,7 @@ int I_INC_REF_II_N(int special) { PC = (PC + 1) & 0xFFFF; int address = (special + disp) & 0xFFFF; int value = memory.read(address) & 0xFF; + memptr = address; int sum = (value + 1) & 0x1FF; int sumByte = sum & 0xFF; @@ -1718,10 +1798,11 @@ int I_DEC_REF_IY_N() { } int I_DEC_REF_II_N(int special) { - int disp = memory.read(PC) & 0xFF; + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int address = (special + (byte) disp) & 0xFFFF; + int address = (special + disp) & 0xFFFF; int value = memory.read(address) & 0xFF; + memptr = address; int sum = (value - 1) & 0x1FF; int sumByte = sum & 0xFF; @@ -1740,11 +1821,13 @@ int I_LD_REF_IY_N_N() { } int I_LD_REF_II_N_N(int special) { - byte offset = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; byte number = memory.read(PC); PC = (PC + 1) & 0xFFFF; - memory.write((special + offset) & 0xFFFF, number); + int address = (special + disp) & 0xFFFF; + memptr = address; + memory.write(address, number); return 19; } @@ -1757,10 +1840,12 @@ int I_LD_R_REF_IY_N() { } int I_LD_R_REF_II_N(int special) { - byte offset = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; int tmp1 = (lastOpcode >>> 3) & 7; - putreg(tmp1, memory.read((special + offset) & 0xFFFF)); + int address = (special + disp) & 0xFFFF; + memptr = address; + putreg(tmp1, memory.read(address)); return 19; } @@ -1773,9 +1858,11 @@ int I_LD_REF_IY_N_R() { } int I_LD_REF_II_N_R(int special) { - byte offset = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - memory.write((special + offset) & 0xFFFF, (byte) getreg(lastOpcode & 7)); + int address = (special + disp) & 0xFFFF; + memptr = address; + memory.write(address, (byte) getreg(lastOpcode & 7)); return 19; } @@ -1788,9 +1875,11 @@ int I_ADD_A_REF_IY_N() { } int I_ADD_A_REF_II_N(int special) { - byte offset = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = memory.read((special + offset) & 0xFFFF) & 0xFF; + int address = (special + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address) & 0xFF; int oldA = regs[REG_A]; int sum = (oldA + value) & 0x1FF; @@ -1808,9 +1897,11 @@ int I_ADC_A_REF_IY_N() { } int I_ADC_A_REF_II_N(int special) { - byte offset = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = memory.read((special + offset) & 0xFFFF) & 0xFF; + int address = (special + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address) & 0xFF; int oldA = regs[REG_A]; int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; @@ -1828,9 +1919,11 @@ int I_SUB_REF_IY_N() { } int I_SUB_REF_II_N(int special) { - byte offset = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = memory.read((special + offset) & 0xFFFF) & 0xFF; + int address = (special + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address) & 0xFF; int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; @@ -1849,9 +1942,11 @@ int I_SBC_A_REF_IY_N() { } int I_SBC_A_REF_II_N(int special) { - byte offset = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = memory.read((special + offset) & 0xFFFF) & 0xFF; + int address = (special + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address) & 0xFF; int oldA = regs[REG_A]; int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; @@ -1870,11 +1965,12 @@ int I_AND_REF_IY_N() { } int I_AND_REF_II_N(int special) { - byte tmp = memory.read(PC); + byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - - int tmp1 = memory.read((special + tmp) & 0xFFFF); - regs[REG_A] = (regs[REG_A] & tmp1) & 0xFF; + int address = (special + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address); + regs[REG_A] = (regs[REG_A] & value) & 0xFF; flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H; return 19; } @@ -1890,8 +1986,9 @@ int I_XOR_REF_IY_N() { int I_XOR_REF_II_N(int special) { byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - - byte value = memory.read((special + disp) & 0xFFFF); + int address = (special + disp) & 0xFFFF; + memptr = address; + byte value = memory.read(address); regs[REG_A] = ((regs[REG_A] ^ value) & 0xff); flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]]; return 19; @@ -1908,7 +2005,9 @@ int I_OR_REF_IY_N() { int I_OR_REF_II_N(int special) { byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - byte value = memory.read((special + disp) & 0xFFFF); + int address = (special + disp) & 0xFFFF; + memptr = address; + byte value = memory.read(address); regs[REG_A] = ((regs[REG_A] | value) & 0xff); flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]]; return 19; @@ -1925,8 +2024,9 @@ int I_CP_REF_IY_N() { int I_CP_REF_II_N(int special) { byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int value = memory.read((special + disp) & 0xFFFF) & 0xFF; - + int address = (special + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address) & 0xFF; int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; @@ -1950,6 +2050,7 @@ int I_EX_REF_SP_IX() { int tmp = readWord(SP); int tmp1 = IX; IX = tmp; + memptr = IX; writeWord(SP, tmp1); return 23; } @@ -1958,6 +2059,7 @@ int I_EX_REF_SP_IY() { int tmp = readWord(SP); int tmp1 = IY; IY = tmp; + memptr = IY; writeWord(SP, tmp1); return 23; } @@ -2004,6 +2106,7 @@ int I_RLC_REF_IY_N_R(byte operand) { int I_RLC_REF_II_N_R(byte operand, int special) { int addr = (special + operand) & 0xFFFF; + memptr = addr; int addrValue = memory.read(addr) & 0xFF; int c = ((addrValue & 0x80) != 0) ? FLAG_C : 0; @@ -2026,6 +2129,7 @@ int I_RRC_REF_IY_N_R(byte operand) { int I_RRC_REF_II_N_R(byte operand, int special) { int addr = (special + operand) & 0xffff; + memptr = addr; int addrValue = memory.read(addr) & 0xFF; int c = addrValue & 1; @@ -2048,6 +2152,7 @@ int I_RL_REF_IY_N_R(byte operand) { int I_RL_REF_II_N_R(byte operand, int special) { int addr = (special + operand) & 0xffff; + memptr = addr; int addrValue = memory.read(addr) & 0xFF; int c = (addrValue >>> 7) & 1; @@ -2069,7 +2174,8 @@ int I_RR_REF_IY_N_R(byte operand) { } int I_RR_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xffff; + int addr = (special + operand) & 0xFFFF; + memptr = addr; int addrValue = memory.read(addr) & 0xFF; int c = addrValue & 1; @@ -2092,6 +2198,7 @@ int I_SLA_REF_IY_N_R(byte operand) { int I_SLA_REF_II_N_R(byte operand, int special) { int addr = (special + operand) & 0xFFFF; + memptr = addr; int addrValue = memory.read(addr) & 0xFF; int c = (addrValue >>> 7) & 1; @@ -2113,7 +2220,8 @@ int I_SRA_REF_IY_N_R(byte operand) { } int I_SRA_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xffff; + int addr = (special + operand) & 0xFFFF; + memptr = addr; int addrValue = memory.read(addr) & 0xFF; int c = addrValue & 1; @@ -2135,7 +2243,8 @@ int I_SLL_REF_IY_N_R(byte operand) { } int I_SLL_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xffff; + int addr = (special + operand) & 0xFFFF; + memptr = addr; int addrValue = memory.read(addr) & 0xFF; int c = ((addrValue & 0x80) != 0) ? FLAG_C : 0; @@ -2158,7 +2267,8 @@ int I_SRL_REF_IY_N_R(byte operand) { } int I_SRL_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xffff; + int addr = (special + operand) & 0xFFFF; + memptr = addr; int addrValue = memory.read(addr) & 0xFF; int c = ((addrValue & 0x01) != 0) ? FLAG_C : 0; @@ -2181,7 +2291,9 @@ int I_BIT_N_REF_IY_N(byte operand) { int I_BIT_N_REF_II_N(byte operand, int special) { int bitNumber = (lastOpcode >>> 3) & 7; - byte addrValue = memory.read((special + operand) & 0xFFFF); + int address = (special + operand) & 0xFFFF; + memptr = address; + byte addrValue = memory.read(address); flags = ((flags & FLAG_C) | FLAG_H | (((addrValue & (1 << bitNumber)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); if (bitNumber == 7) { flags |= (((addrValue & (1 << 7)) == 0x80) ? FLAG_S : 0); @@ -2199,7 +2311,8 @@ int I_RES_N_REF_IY_N_R(byte operand) { int I_RES_N_REF_II_N_R(byte operand, int special) { int bitNumber = (lastOpcode >>> 3) & 7; - int addr = (special + operand) & 0xffff; + int addr = (special + operand) & 0xFFFF; + memptr = addr; int addrValue = memory.read(addr) & 0xFF; int res = (addrValue & (~(1 << bitNumber))); memory.write(addr, (byte) (res & 0xff)); @@ -2218,7 +2331,8 @@ int I_SET_N_REF_IY_N_R(byte operand) { int I_SET_N_REF_II_N_R(byte operand, int special) { int bitNumber = (lastOpcode >>> 3) & 7; - int addr = (special + operand) & 0xffff; + int addr = (special + operand) & 0xFFFF; + memptr = addr; int addrValue = memory.read(addr) & 0xFF; int res = (addrValue | (1 << bitNumber)) & 0xFF; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java index 9062c8136..a33f9ae78 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java @@ -521,6 +521,42 @@ public void testLDIR() { Generator.forSome16bitBinary(2, 2, test.run(0xED, 0xB0) ); + } + + @Test + public void testXX() { + int flags = 0; + int PC = Integer.parseInt("0010100000000000", 2); + // 0010100000000000 + // 100000 + // 1000 + + //YF = PC.13 + //XF = PC.11 + + // FLAG_X = 8 1000 + // FLAG_Y = 0x20 = 32 100000 + System.out.println((PC >>> 8)); + System.out.println((PC >>> 8)); + + flags = ((PC >>> 8) & FLAG_X) | ((PC >>> 8) & FLAG_Y); + + System.out.println(Integer.toBinaryString(flags)); + } + + @Test + public void testYYY() { + // int result = regs[REG_A] + io; + // flags |= ((result & 2) << 4); // xf = [io + a].1 + // flags |= ((result & 4) << 2); // yf = [io + a].3 + int result = Integer.parseInt("1010", 2); + int flags = ((result & 2) << 2); + System.out.println(Integer.toBinaryString(flags)); + flags = ((result & 8) << 2); + System.out.println(Integer.toBinaryString(flags)); + + System.out.println("X = " + Integer.toBinaryString(FLAG_X)); + System.out.println("Y = " + Integer.toBinaryString(FLAG_Y)); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java index cff8c035c..7a155f853 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java @@ -168,9 +168,15 @@ public static String intToFlags(int flags) { if ((flags & FLAG_Z) == FLAG_Z) { flagsString += "Z"; } + if ((flags & FLAG_Y) == FLAG_Y) { + flagsString += "Y"; + } if ((flags & FLAG_H) == FLAG_H) { flagsString += "H"; } + if ((flags & FLAG_X) == FLAG_X) { + flagsString += "X"; + } if ((flags & FLAG_PV) == FLAG_PV) { flagsString += "P"; } From c246249a84f8bbc6c052d7c37e4846641368406b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 21 Aug 2022 21:17:30 +0100 Subject: [PATCH 191/314] [#260] Implement missing undoc instructions --- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 32 ++++- .../plugins/cpu/zilogZ80/DispatchTables.java | 130 ++++++++++++++++++ .../device/adm3a/interaction/Cursor.java | 31 +++++ .../device/adm3a/interaction/Display.java | 31 ++++- 4 files changed, 214 insertions(+), 10 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index 21aa46d76..272457441 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -163,12 +163,21 @@ ddInstruction = "ld %s, %s": 01 10 r_ixhl(1) 10 r_ixhl2(1) | # x=1, y=r_ixhl, z=r_ixhl2 "ld %s, a": 01 10 r_ixhl(1) 111 | # x=1, y=r_ixhl, z=a "ld a, %s": 01 111 10 r_ixhl(1) | # x=1, y=7, z=r_ixhl + "ld a, %s": 01 111 0 r_bcde(2) | # x=1, y=7, z=r_bcde + "ld a, a": 01 111 111 | # x=1, y=7, z=a + "ld %s, a": 01 0 r_bcde(2) 111 | # x=1, y=r_bcde, z=a + "ld %s, %s": 01 0 r_bcde(2) 0 r_bcde2(2) | # x=1, y=r_bcde, z=r_bcde2 + "ld %s, %s": 01 0 r_bcde(2) 10 r_ixhl2(1) | # x=1, y=r_bcde, z=r_ixhl2 "ld (ix+%Xh), %s": 01 110 r_no_hl(3) disp | # x=1, y=6, z=r_no_hl "ld %s, (ix+%Xh)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 "ld %s, (ix+%Xh)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l, z=6 "ld a, (ix+%Xh)": 01 111 110 disp | # x=1, y=7, z=6 + + "%s %s": 10 alu(3) 0 r_bcde(2) | # x=2, y=alu, z=r_bcde + "%s a": 10 alu(3) 111 | # x=2, y=alu, z=a "%s %s": 10 alu(3) 10 r_ixhl(1) | # x=2, y=alu, z=r_ixhl "%s (ix+%Xh)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 + "pop ix": 11 100 001 | # x=3, p=2, q=0, z=1 "jp (ix)": 11 101 001 | # x=3, p=2, q=1, z=1 "ld sp, ix": 11 111 001 | # x=3, p=3, q=1, z=1 @@ -178,8 +187,6 @@ ddInstruction = "nop": 00 010 any3(3) | "nop": 00 011 1 any2(2) | "nop": 00 100000 | - "nop": 01 0000 any2(2) | - "nop": 10 0000 any2(2) | "nop": 11 01 any4(4) | "nop": 11 100000 | @@ -205,12 +212,21 @@ fdInstruction = "ld %s, %s": 01 10 r_iyhl(1) 10 r_iyhl2(1) | # x=1, y=r_iyhl, z=r_iyhl2 "ld %s, a": 01 10 r_iyhl(1) 111 | # x=1, y=r_iyhl, z=7 "ld a, %s": 01 111 10 r_iyhl(1) | # x=1, y=7, z=r_iyhl + "ld a, %s": 01 111 0 r_bcde(2) | # x=1, y=7, z=r_bcde + "ld a, a": 01 111 111 | # x=1, y=7, z=a + "ld %s, a": 01 0 r_bcde(2) 111 | # x=1, y=r_bcde, z=a + "ld %s, %s": 01 0 r_bcde(2) 0 r_bcde2(2) | # x=1, y=r_bcde, z=r_iyhl2 + "ld %s, %s": 01 0 r_bcde(2) 10 r_iyhl2(1) | # x=1, y=r_bcde, z=r_iyhl2 "ld (iy+%Xh), %s": 01 110 r_no_hl(3) disp | # x=1, y=6, z=r_no_hl "ld %s, (iy+%Xh)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 "ld %s, (iy+%Xh)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l, z=6 "ld a, (iy+%Xh)": 01 111 110 disp | # x=1, y=7, z=6 + + "%s %s": 10 alu(3) 0 r_bcde(2) | # x=2, y=alu, z=r_bcde + "%s a": 10 alu(3) 111 | # x=2, y=alu, z=a "%s %s": 10 alu(3) 10 r_iyhl(1) | # x=2, y=alu, z=r_iyhl "%s (iy+%Xh)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 + "pop iy": 11 100 001 | # x=3, p=2, q=0, z=1 "jp (iy)": 11 101 001 | # x=3, p=2, q=1, z=1 "ld sp, iy": 11 111 001 | # x=3, p=3, q=1, z=1 @@ -220,8 +236,6 @@ fdInstruction = "nop": 00 010 any3(3) | "nop": 00 011 1 any2(2) | "nop": 00 100000 | - "nop": 01 0000 any2(2) | - "nop": 10 0000 any2(2) | "nop": 11 01 any4(4) | "nop": 11 100000 | @@ -394,12 +408,17 @@ any2 = 00 | 01 | 10 | 11; "%s" = ddInstruction r_ixhl imm8; "%s" = ddInstruction disp imm8; "%s" = ddInstruction r_ixhl r_bcde; +"%s" = ddInstruction r_bcde; +"%s" = ddInstruction r_bcde r_bcde2; +"%s" = ddInstruction r_bcde r_ixhl2; "%s" = ddInstruction r_ixhl r_ixhl2; "%s" = ddInstruction r_bcde disp; "%s" = ddInstruction r_h_l disp; "%s" = ddInstruction disp r_no_hl; +"%s" = ddInstruction alu r_bcde; "%s" = ddInstruction alu r_ixhl; "%s" = ddInstruction alu disp; +"%s" = ddInstruction alu; "%s" = ddInstruction rp_ix; "%s" = ddInstruction any4; "%s" = ddInstruction any3; @@ -412,12 +431,17 @@ any2 = 00 | 01 | 10 | 11; "%s" = fdInstruction r_iyhl imm8; "%s" = fdInstruction disp imm8; "%s" = fdInstruction r_iyhl r_bcde; +"%s" = fdInstruction r_bcde r_iyhl2; +"%s" = fdInstruction r_bcde; +"%s" = fdInstruction r_bcde r_bcde2; "%s" = fdInstruction r_iyhl r_iyhl2; "%s" = fdInstruction disp r_no_hl; "%s" = fdInstruction r_bcde disp; "%s" = fdInstruction r_h_l disp; +"%s" = fdInstruction alu r_bcde; "%s" = fdInstruction alu r_iyhl; "%s" = fdInstruction alu disp; +"%s" = fdInstruction alu; "%s" = fdInstruction rp_iy; "%s" = fdInstruction any4; "%s" = fdInstruction any3; diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java index c67f01f39..7d1ed8271 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java @@ -653,18 +653,38 @@ public class DispatchTables { DISPATCH_TABLE_DD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IX_N", retInt); DISPATCH_TABLE_DD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_N", retInt); DISPATCH_TABLE_DD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", retInt); + DISPATCH_TABLE_DD[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_DD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); DISPATCH_TABLE_DD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); DISPATCH_TABLE_DD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_DD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); DISPATCH_TABLE_DD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); DISPATCH_TABLE_DD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_DD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); DISPATCH_TABLE_DD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); DISPATCH_TABLE_DD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_DD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); DISPATCH_TABLE_DD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); DISPATCH_TABLE_DD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_DD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); DISPATCH_TABLE_DD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); DISPATCH_TABLE_DD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); @@ -688,33 +708,78 @@ public class DispatchTables { DISPATCH_TABLE_DD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); DISPATCH_TABLE_DD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); DISPATCH_TABLE_DD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); + DISPATCH_TABLE_DD[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_DD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); DISPATCH_TABLE_DD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); DISPATCH_TABLE_DD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_DD[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE_DD[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE_DD[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE_DD[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); DISPATCH_TABLE_DD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IXH", retInt); DISPATCH_TABLE_DD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IXL", retInt); DISPATCH_TABLE_DD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE_DD[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE_DD[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE_DD[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE_DD[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); DISPATCH_TABLE_DD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IXH", retInt); DISPATCH_TABLE_DD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IXL", retInt); DISPATCH_TABLE_DD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE_DD[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE_DD[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE_DD[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE_DD[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); DISPATCH_TABLE_DD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IXH", retInt); DISPATCH_TABLE_DD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IXL", retInt); DISPATCH_TABLE_DD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE_DD[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE_DD[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE_DD[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE_DD[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); DISPATCH_TABLE_DD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IXH", retInt); DISPATCH_TABLE_DD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IXL", retInt); DISPATCH_TABLE_DD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE_DD[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE_DD[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE_DD[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE_DD[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); DISPATCH_TABLE_DD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IXH", retInt); DISPATCH_TABLE_DD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IXL", retInt); DISPATCH_TABLE_DD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE_DD[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE_DD[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE_DD[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE_DD[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); DISPATCH_TABLE_DD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IXH", retInt); DISPATCH_TABLE_DD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IXL", retInt); DISPATCH_TABLE_DD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE_DD[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE_DD[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE_DD[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE_DD[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); DISPATCH_TABLE_DD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IXH", retInt); DISPATCH_TABLE_DD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IXL", retInt); DISPATCH_TABLE_DD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE_DD[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE_DD[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE_DD[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE_DD[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); DISPATCH_TABLE_DD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IXH", retInt); DISPATCH_TABLE_DD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IXL", retInt); DISPATCH_TABLE_DD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IX_N", retInt); + DISPATCH_TABLE_DD[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); DISPATCH_TABLE_DD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "DD_CB_DISPATCH", retInt); DISPATCH_TABLE_DD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IX", retInt); DISPATCH_TABLE_DD[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_IX", retInt); @@ -740,18 +805,38 @@ public class DispatchTables { DISPATCH_TABLE_FD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IY_N", retInt); DISPATCH_TABLE_FD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_N", retInt); DISPATCH_TABLE_FD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", retInt); + DISPATCH_TABLE_FD[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_FD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); DISPATCH_TABLE_FD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); DISPATCH_TABLE_FD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_FD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); DISPATCH_TABLE_FD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); DISPATCH_TABLE_FD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_FD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); DISPATCH_TABLE_FD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); DISPATCH_TABLE_FD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_FD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); DISPATCH_TABLE_FD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); DISPATCH_TABLE_FD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_FD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); DISPATCH_TABLE_FD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); DISPATCH_TABLE_FD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); @@ -775,33 +860,78 @@ public class DispatchTables { DISPATCH_TABLE_FD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); DISPATCH_TABLE_FD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); DISPATCH_TABLE_FD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); + DISPATCH_TABLE_FD[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); DISPATCH_TABLE_FD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); DISPATCH_TABLE_FD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); DISPATCH_TABLE_FD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE_FD[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE_FD[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE_FD[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE_FD[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); DISPATCH_TABLE_FD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IYH", retInt); DISPATCH_TABLE_FD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IYL", retInt); DISPATCH_TABLE_FD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE_FD[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE_FD[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE_FD[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE_FD[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); DISPATCH_TABLE_FD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IYH", retInt); DISPATCH_TABLE_FD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IYL", retInt); DISPATCH_TABLE_FD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE_FD[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE_FD[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE_FD[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE_FD[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); DISPATCH_TABLE_FD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IYH", retInt); DISPATCH_TABLE_FD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IYL", retInt); DISPATCH_TABLE_FD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE_FD[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE_FD[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE_FD[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE_FD[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); DISPATCH_TABLE_FD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IYH", retInt); DISPATCH_TABLE_FD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IYL", retInt); DISPATCH_TABLE_FD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE_FD[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE_FD[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE_FD[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE_FD[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); DISPATCH_TABLE_FD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IYH", retInt); DISPATCH_TABLE_FD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IYL", retInt); DISPATCH_TABLE_FD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE_FD[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE_FD[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE_FD[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE_FD[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); DISPATCH_TABLE_FD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IYH", retInt); DISPATCH_TABLE_FD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IYL", retInt); DISPATCH_TABLE_FD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE_FD[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE_FD[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE_FD[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE_FD[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); DISPATCH_TABLE_FD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IYH", retInt); DISPATCH_TABLE_FD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IYL", retInt); DISPATCH_TABLE_FD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE_FD[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE_FD[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE_FD[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE_FD[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); DISPATCH_TABLE_FD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IYH", retInt); DISPATCH_TABLE_FD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IYL", retInt); DISPATCH_TABLE_FD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IY_N", retInt); + DISPATCH_TABLE_FD[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); DISPATCH_TABLE_FD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "FD_CB_DISPATCH", retInt); DISPATCH_TABLE_FD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IY", retInt); DISPATCH_TABLE_FD[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_IY", retInt); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java index 6609127ca..c8fc157b5 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java @@ -28,6 +28,7 @@ public class Cursor { private final int columns; private final int rows; + private final int tabs; private final AtomicReference cursorPoint = new AtomicReference<>(new Point()); @@ -41,6 +42,7 @@ interface LineRoller { public Cursor(int columns, int rows) { this.columns = columns; this.rows = rows; + this.tabs = columns / 4; } int getColumns() { @@ -59,6 +61,24 @@ void set(int x, int y) { cursorPoint.set(new Point(x, y)); } + void printComma(LineRoller lineRoller) { + setCursorPoint(oldPoint -> { + Point newPoint = new Point(oldPoint); + + if (newPoint.x < 16) { + newPoint.x = 16; + } else { + newPoint.x = 0; + newPoint.y++; + if (newPoint.y > (rows - 1)) { + lineRoller.rollLine(); + newPoint.y = (rows - 1); + } + } + return newPoint; + }); + } + void moveForwardsRolling(LineRoller lineRoller) { setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); @@ -88,6 +108,17 @@ void moveForwards() { }); } + void moveForwardsTab() { + setCursorPoint(oldPoint -> { + Point newPoint = new Point(oldPoint); + + if (newPoint.x < (columns - 1)) { + newPoint.x = ((newPoint.x + 4) / 4) * 4; + } + return newPoint; + }); + } + void moveBackwards() { setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java index 89081546a..eafc0a552 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java @@ -211,12 +211,20 @@ public void writeData(Byte data) { */ switch (data) { case 5: // HERE IS - insertHereIs(); + // insertHereIs(); + break; + case 6: + // print COMMA + cursor.printComma(this); break; case 7: // BELL return; case 8: // BACKSPACE cursor.moveBackwards(); + drawChar((char) (32)); + break; + case 9: + cursor.moveForwards(); break; case 0x0A: // line feed cursor.moveDown(this); @@ -224,24 +232,35 @@ public void writeData(Byte data) { case 0x0B: // VT cursor.moveUp(); break; - case 0x0C: // FF - cursor.moveForwards(); + case 0x0C: // delete + drawChar((char)32); break; case 0x0D: // CARRIAGE RETURN cursor.carriageReturn(); - cursor.moveDown(this); // TODO break; + case 23: + cursor.moveForwardsTab(); + break; + // case 0x0C: // FF + // cursor.moveForwards(); + // break; + case 0x0E: // SO case 0x0F: // SI return; case 0x1A: // clear screen - clearScreen(); + //clearScreen(); + cursor.moveDown(this); return; case 0x1B: // initiates load cursor operation case 0x1E: // homes cursor - cursor.home(); + // cursor.home(); break; + case 127: + drawChar('\u00a9'); + cursor.moveForwardsRolling(this); + return; } if (loadCursorPosition.notAccepted(data) && data >= 32) { From 6e2f2eb92dbff2f698816f75b23d11577e39b21b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 21 Aug 2022 22:34:56 +0100 Subject: [PATCH 192/314] [#260] Fixed callFlow updating --- .../application/gui/debugtable/CallFlow.java | 9 +++++++++ plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 2 +- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 13 +++++++++++-- .../plugins/cpu/zilogZ80/DisassemblerTest.java | 10 ++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java b/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java index 36270db2f..0cb1c8d17 100644 --- a/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java +++ b/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java @@ -44,6 +44,15 @@ void updateCache(int currentLocation) { if (nextPosition - currentLocation > longestInstructionSize) { longestInstructionSize = nextPosition - currentLocation; } + Integer prev = flowGraph.get(currentLocation); + if (prev != null) { + Integer prevPrev = flowGraph.get(prev); + if (prevPrev != null && prevPrev != nextPosition) { + // If current instruction points on different address than before + // and the previous one existed in flowGraph, remove it + flowGraph.remove(prev); + } + } flowGraph.put(currentLocation, nextPosition); } catch (RuntimeException ex) { LOGGER.warn("Could not update call-flow cache", ex); diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index 272457441..8d8a6c5ae 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -378,7 +378,7 @@ im = "2": 111 ; bit,any = bit: bit(3); -imm8,ref8,disp,disp2 = imm8: imm8(8); +imm8,ref8,disp = imm8: imm8(8); imm16,ref16,ref16_2 = imm16: imm16(16); rst = "00": 000 | "08": 001 | "10": 010 | "18": 011 | "20": 100 | "28": 101 | "30": 110 | "38": 111; any2 = 00 | 01 | 10 | 11; diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 1f740a4ff..7b7976067 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -1038,6 +1038,7 @@ int I_LDDR() { memptr = (PC - 1) & 0xFFFF; } + //..*0*00. I_LDD(); if ((regs[REG_B] == 0) && (regs[REG_C] == 0)) { return 16; @@ -1090,12 +1091,20 @@ int I_LDIR() { } PC = (PC - 2) & 0xFFFF; + //Flag effects are the same as LDI except that P/V will always be reset, because BC by definition reaches + // 0 before this instruction ends (normally - unless something overwrites LDIR opcode while BC>0). + // https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags#interrupted-block-instructions //YF = PC.13 //XF = PC.11 - flags &= (~FLAG_Y); - flags &= (~FLAG_X); + // 0010 1100 = 2C + // 1101 0011 = D3 + flags &= 0xD3; // reset P/V, X, Y + + //flag_f5 = (reg_pc >> 13) & 1; + // flag_f3 = (reg_pc >> 11) & 1; + // 00101000 00000000 PC flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); return 21; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java index c2ee2ea36..9309e1e3c 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java @@ -19,6 +19,7 @@ package net.emustudio.plugins.cpu.zilogZ80; import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; +import net.emustudio.emulib.plugins.cpu.DecodedInstruction; import net.emustudio.emulib.plugins.cpu.Decoder; import net.emustudio.emulib.plugins.cpu.Disassembler; import net.emustudio.emulib.plugins.cpu.InvalidInstructionException; @@ -832,4 +833,13 @@ public void testDisassemble() throws InvalidInstructionException { result ); } + + @Test + public void testDecoder() throws InvalidInstructionException { + memoryStub.setMemory(new short[] { + 0xED, 0xB0 + }); + DecodedInstruction instr = decoder.decode(0); + assertEquals(2, instr.getLength()); + } } From f0218a63aca8c2ef3b21178cea090d7953aba7e2 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 22 Aug 2022 08:30:03 +0100 Subject: [PATCH 193/314] [#260] Fix call flow updating --- .../application/gui/debugtable/CallFlow.java | 20 ++++++++++++++----- .../debugtable/PaginatingDisassembler.java | 10 ++++++++-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java b/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java index 0cb1c8d17..a82d24235 100644 --- a/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java +++ b/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java @@ -46,11 +46,21 @@ void updateCache(int currentLocation) { } Integer prev = flowGraph.get(currentLocation); if (prev != null) { - Integer prevPrev = flowGraph.get(prev); - if (prevPrev != null && prevPrev != nextPosition) { - // If current instruction points on different address than before - // and the previous one existed in flowGraph, remove it - flowGraph.remove(prev); + // jump over previous instruction chain until we get to the last one + + int originalPrev = prev; + while (prev != null && prev < nextPosition) { + prev = flowGraph.get(prev); + } + if (prev != null && prev != nextPosition) { + // If the current instruction points to a different address than before + // and the previous instruction chain does not end in the new position, remove the whole chain + + while (originalPrev < nextPosition) { + prev = flowGraph.get(originalPrev); + flowGraph.remove(originalPrev); + originalPrev = prev; + } } } flowGraph.put(currentLocation, nextPosition); diff --git a/application/src/main/java/net/emustudio/application/gui/debugtable/PaginatingDisassembler.java b/application/src/main/java/net/emustudio/application/gui/debugtable/PaginatingDisassembler.java index 836904735..e783625f3 100644 --- a/application/src/main/java/net/emustudio/application/gui/debugtable/PaginatingDisassembler.java +++ b/application/src/main/java/net/emustudio/application/gui/debugtable/PaginatingDisassembler.java @@ -27,7 +27,7 @@ public class PaginatingDisassembler { public final static int INSTR_PER_PAGE = 2 * 10 + 1; - private final CallFlow callFlow; + private final CallFlow callFlow; // call flow won't contain all locations, it grows only if row == middle private final NavigableMap bytesPerPageCache = new ConcurrentSkipListMap<>(); private int memorySize; @@ -187,12 +187,18 @@ int rowToLocation(int currentLocation, int row) { lastKnownCurrentLocation = currentLocation; int newCurrentLocation = findCurrentLocationInPage(currentLocation, tmpCurrentPage); + boolean updateCalled = false; if (newCurrentLocation != currentLocation || tmpCurrentPage.middleLocation == -1) { tmpCurrentPage.setMiddleLocation(newCurrentLocation); callFlow.updateCache(currentLocation); + updateCalled = true; } if (row == currentInstrRow) { + if (!updateCalled) { + // update cache always on current instruction + callFlow.updateCache(currentLocation); + } return newCurrentLocation; } @@ -276,7 +282,7 @@ private int findIncreasing(int currentLocation, Page tmpPage, int currentPageInd private int findDecreasing(int currentLocation, Page tmpPage, int currentPageIndex) { // currentLocation is above current page. So we will traverse back by maxBytesPerPage to the last known - // location in some adjacent page (the nearer the better). + // location in some adjacent page (the nearer, the better). while (tmpPage.index < 0 && tmpPage.middleLocation < 0) { Integer nextPageIndex = bytesPerPageCache.ceilingKey(tmpPage.index + 1); From 741ecca8557225adc4b11a8e9acde0cdd7bf3356 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 22 Aug 2022 08:35:21 +0100 Subject: [PATCH 194/314] [#260] updating call flow: optimization --- .../net/emustudio/application/gui/debugtable/CallFlow.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java b/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java index a82d24235..888a2e5bb 100644 --- a/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java +++ b/application/src/main/java/net/emustudio/application/gui/debugtable/CallFlow.java @@ -55,12 +55,7 @@ void updateCache(int currentLocation) { if (prev != null && prev != nextPosition) { // If the current instruction points to a different address than before // and the previous instruction chain does not end in the new position, remove the whole chain - - while (originalPrev < nextPosition) { - prev = flowGraph.get(originalPrev); - flowGraph.remove(originalPrev); - originalPrev = prev; - } + flowGraph.subMap(originalPrev, true, prev, true).clear(); } } flowGraph.put(currentLocation, nextPosition); From 28b588a563098ac12007e5b0549a35f6ae42fca2 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 22 Aug 2022 18:06:13 +0100 Subject: [PATCH 195/314] [#260] XY for INxR/CPxR/OTxR/LDxR --- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 119 +++++++++++++++++- .../plugins/cpu/zilogZ80/TransferTest.java | 37 ------ 2 files changed, 114 insertions(+), 42 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 7b7976067..acc6ecee3 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -954,6 +954,10 @@ int I_CPIR() { return 16; } PC = (PC - 2) & 0xFFFF; + + flags &= 0xD3; // reset P/V, X, Y + flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + return 21; } @@ -1006,6 +1010,8 @@ int I_CPDR() { return 16; } PC = (PC - 2) & 0xFFFF; + flags &= 0xD3; // reset P/V, X, Y + flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); return 21; } @@ -1038,7 +1044,6 @@ int I_LDDR() { memptr = (PC - 1) & 0xFFFF; } - //..*0*00. I_LDD(); if ((regs[REG_B] == 0) && (regs[REG_C] == 0)) { return 16; @@ -1048,9 +1053,7 @@ int I_LDDR() { // https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags#interrupted-block-instructions //YF = PC.13 //XF = PC.11 - - flags &= (~FLAG_Y); - flags &= (~FLAG_X); + flags &= 0xD3; // reset P/V, X, Y flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); return 21; @@ -1084,9 +1087,24 @@ int I_LDIR() { if (bc != 1) { memptr = (PC - 1) & 0xFFFF; } +// +// System.out.printf("---\nBEFORE: BC=%04X DE=%04X HL=%04X A=%02X F=%s\n", +// ((regs[REG_B] << 8) | regs[REG_C]), +// ((regs[REG_D] << 8) | regs[REG_E]), +// ((regs[REG_H] << 8) | regs[REG_L]), +// regs[REG_A], +// intToFlags(flags) +// ); I_LDI(); if ((regs[REG_B] == 0) && (regs[REG_C] == 0)) { +// System.out.printf("BC=%04X DE=%04X HL=%04X A=%02X F=%s\n---\n", +// ((regs[REG_B] << 8) | regs[REG_C]), +// ((regs[REG_D] << 8) | regs[REG_E]), +// ((regs[REG_H] << 8) | regs[REG_L]), +// regs[REG_A], +// intToFlags(flags) +// ); return 16; } PC = (PC - 2) & 0xFFFF; @@ -1100,16 +1118,54 @@ int I_LDIR() { // 0010 1100 = 2C // 1101 0011 = D3 - flags &= 0xD3; // reset P/V, X, Y + // 1101 0111 = D7 +// flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | ((PC >>> 8) & (FLAG_X | FLAG_Y)); +// System.out.printf("BC=%04X DE=%04X HL=%04X A=%02X F=%s\n", +// ((regs[REG_B] << 8) | regs[REG_C]), +// ((regs[REG_D] << 8) | regs[REG_E]), +// ((regs[REG_H] << 8) | regs[REG_L]), +// regs[REG_A], +// intToFlags(flags) +// ); //flag_f5 = (reg_pc >> 13) & 1; // flag_f3 = (reg_pc >> 11) & 1; // 00101000 00000000 PC + flags &= 0xD3; // reset P/V, X, Y flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); return 21; } + public static String intToFlags(int flags) { + String flagsString = ""; + if ((flags & FLAG_S) == FLAG_S) { + flagsString += "S"; + } + if ((flags & FLAG_Z) == FLAG_Z) { + flagsString += "Z"; + } + if ((flags & FLAG_Y) == FLAG_Y) { + flagsString += "Y"; + } + if ((flags & FLAG_H) == FLAG_H) { + flagsString += "H"; + } + if ((flags & FLAG_X) == FLAG_X) { + flagsString += "X"; + } + if ((flags & FLAG_PV) == FLAG_PV) { + flagsString += "P"; + } + if ((flags & FLAG_N) == FLAG_N) { + flagsString += "N"; + } + if ((flags & FLAG_C) == FLAG_C) { + flagsString += "C"; + } + return flagsString; + } + int I_INI() { byte value = context.readIO(regs[REG_C]); int address = (regs[REG_H] << 8) | regs[REG_L]; @@ -1145,6 +1201,20 @@ int I_INIR() { return 16; } PC = (PC - 2) & 0xFFFF; + + flags &= 0xD7; // reset X, Y + flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + if ((flags & FLAG_C) == FLAG_C) { + flags &= (~FLAG_H); + if ((value & 0x80) != 0) { + flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] - 1) & 0x7] ^ FLAG_PV; + flags |= ((regs[REG_B] & 0x0F) == 0 ? FLAG_H : 0); + } else { + flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] + 1) & 0x7] ^ FLAG_PV; + flags |= ((regs[REG_B] & 0x0F) == 0x0F ? FLAG_H : 0); + } + } + return 21; } @@ -1182,6 +1252,19 @@ int I_INDR() { return 16; } PC = (PC - 2) & 0xFFFF; + + flags &= 0xD7; // reset X, Y + flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + if ((flags & FLAG_C) == FLAG_C) { + flags &= (~FLAG_H); + if ((value & 0x80) != 0) { + flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] - 1) & 0x7] ^ FLAG_PV; + flags |= ((regs[REG_B] & 0x0F) == 0 ? FLAG_H : 0); + } else { + flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] + 1) & 0x7] ^ FLAG_PV; + flags |= ((regs[REG_B] & 0x0F) == 0x0F ? FLAG_H : 0); + } + } return 21; } @@ -1217,6 +1300,19 @@ int I_OTIR() { return 16; } PC = (PC - 2) & 0xFFFF; + + flags &= 0xD7; // reset X, Y + flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + if ((flags & FLAG_C) == FLAG_C) { + flags &= (~FLAG_H); + if ((value & 0x80) != 0) { + flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] - 1) & 0x7] ^ FLAG_PV; + flags |= ((regs[REG_B] & 0x0F) == 0 ? FLAG_H : 0); + } else { + flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] + 1) & 0x7] ^ FLAG_PV; + flags |= ((regs[REG_B] & 0x0F) == 0x0F ? FLAG_H : 0); + } + } return 21; } @@ -1252,6 +1348,19 @@ int I_OTDR() { return 16; } PC = (PC - 2) & 0xFFFF; + + flags &= 0xD7; // reset X, Y + flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + if ((flags & FLAG_C) == FLAG_C) { + flags &= (~FLAG_H); + if ((value & 0x80) != 0) { + flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] - 1) & 0x7] ^ FLAG_PV; + flags |= ((regs[REG_B] & 0x0F) == 0 ? FLAG_H : 0); + } else { + flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] + 1) & 0x7] ^ FLAG_PV; + flags |= ((regs[REG_B] & 0x0F) == 0x0F ? FLAG_H : 0); + } + } return 21; } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java index a33f9ae78..adf11141e 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java @@ -523,43 +523,6 @@ public void testLDIR() { ); } - @Test - public void testXX() { - int flags = 0; - int PC = Integer.parseInt("0010100000000000", 2); - // 0010100000000000 - // 100000 - // 1000 - - //YF = PC.13 - //XF = PC.11 - - // FLAG_X = 8 1000 - // FLAG_Y = 0x20 = 32 100000 - System.out.println((PC >>> 8)); - System.out.println((PC >>> 8)); - - flags = ((PC >>> 8) & FLAG_X) | ((PC >>> 8) & FLAG_Y); - - System.out.println(Integer.toBinaryString(flags)); - } - - @Test - public void testYYY() { - // int result = regs[REG_A] + io; - // flags |= ((result & 2) << 4); // xf = [io + a].1 - // flags |= ((result & 4) << 2); // yf = [io + a].3 - int result = Integer.parseInt("1010", 2); - int flags = ((result & 2) << 2); - System.out.println(Integer.toBinaryString(flags)); - flags = ((result & 8) << 2); - System.out.println(Integer.toBinaryString(flags)); - - System.out.println("X = " + Integer.toBinaryString(FLAG_X)); - System.out.println("Y = " + Integer.toBinaryString(FLAG_Y)); - - } - @Test public void testLDD() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) From b1cc6db94840690fb4ff8ac706ef18f2e79e1c74 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 23 Aug 2022 11:58:31 +0100 Subject: [PATCH 196/314] [#260] z80: Fixed more instructions --- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 562 +++++++++--------- 1 file changed, 271 insertions(+), 291 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index acc6ecee3..3f4d50c21 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -460,7 +460,7 @@ int I_INC_R() { int regValue = getreg(reg); int sum = (regValue + 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C); + flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C) | (sumByte & (FLAG_X | FLAG_Y)); putreg(reg, sumByte); return (reg == 6) ? 11 : 4; } @@ -470,7 +470,7 @@ int I_DEC_R() { int regValue = getreg(reg); int sum = (regValue - 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C); + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C) | (sumByte & (FLAG_X | FLAG_Y)); putreg(reg, sumByte); return (reg == 6) ? 11 : 4; } @@ -498,19 +498,39 @@ int I_ADD_A_R() { int oldA = regs[REG_A]; int sum = (oldA + value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); return (lastOpcode == 0x86) ? 7 : 4; } + int I_ADD_A_N() { + int value = memory.read(PC) & 0xFF; + PC = (PC + 1) & 0xFFFF; + int oldA = regs[REG_A]; + int sum = (oldA + value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + return 7; + } + int I_ADC_A_R() { int value = getreg(lastOpcode & 0x07); int oldA = regs[REG_A]; int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); return (lastOpcode == 0x8E) ? 7 : 4; } + int I_ADC_A_N() { + int value = memory.read(PC) & 0xFF; + PC = (PC + 1) & 0xFFFF; + int oldA = regs[REG_A]; + int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + return 7; + } + int I_SUB_R() { int value = getreg(lastOpcode & 0x07); @@ -518,7 +538,7 @@ int I_SUB_R() { int sum = (oldA - value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); + flags = TABLE_SUB[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); return (lastOpcode == 0x96) ? 7 : 4; } @@ -529,41 +549,90 @@ int I_SBC_A_R() { int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return (lastOpcode == 0x9E) ? 7 : 4; } + int I_SBC_A_N() { + int value = memory.read(PC) & 0xFF; + PC = (PC + 1) & 0xFFFF; + + int oldA = regs[REG_A]; + int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + return 7; + } + int I_AND_R() { regs[REG_A] = (regs[REG_A] & getreg(lastOpcode & 7)) & 0xFF; - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H; + flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return (lastOpcode == 0xA6) ? 7 : 4; } + int I_AND_N() { + int tmp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + + regs[REG_A] = (regs[REG_A] & tmp) & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + return 7; + } + int I_XOR_R() { regs[REG_A] = ((regs[REG_A] ^ getreg(lastOpcode & 7)) & 0xff); - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]]; + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return (lastOpcode == 0xAE) ? 7 : 4; } + int I_XOR_N() { + int tmp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + + regs[REG_A] = ((regs[REG_A] ^ tmp) & 0xFF); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + return 7; + } + int I_OR_R() { regs[REG_A] = (regs[REG_A] | getreg(lastOpcode & 7)) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]]; + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return (lastOpcode == 0xB6) ? 7 : 4; } + int I_OR_N() { + int tmp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + + regs[REG_A] = (regs[REG_A] | tmp) & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + return 7; + } + int I_CP_R() { int value = getreg(lastOpcode & 7); int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]); + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | (result & (FLAG_X | FLAG_Y)); return (lastOpcode == 0xBE) ? 7 : 4; } + int I_CP_N() { + int value = memory.read(PC) & 0xFF; + PC = (PC + 1) & 0xFFFF; + + int oldA = regs[REG_A]; + int sum = (oldA - value) & 0x1FF; + int result = sum & 0xFF; + flags = (TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA])) | (result & (FLAG_X | FLAG_Y)); + return 7; + } + int I_RLCA() { - int tmp = regs[REG_A] >>> 7; - regs[REG_A] = ((((regs[REG_A] << 1) & 0xFF) | tmp) & 0xff); - flags = ((flags & 0xEC) | tmp); + regs[REG_A] = ((regs[REG_A] << 1) | (regs[REG_A] >>> 7)) & 0xFF; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | (regs[REG_A] & (FLAG_X | FLAG_Y | FLAG_C)); return 4; } @@ -585,8 +654,9 @@ int I_LD_A_REF_BC() { } int I_RRCA() { - flags = ((flags & 0xEC) | (regs[REG_A] & 1)); - regs[REG_A] = RRCA_TABLE[regs[REG_A]]; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | (regs[REG_A] & FLAG_C); + regs[REG_A] = (regs[REG_A] >>> 1) | (regs[REG_A] << 7); + flags |= (regs[REG_A] & (FLAG_X | FLAG_Y)); return 4; } @@ -610,9 +680,10 @@ int I_LD_REF_DE_A() { } int I_RLA() { - int tmp = regs[REG_A] >>> 7; - regs[REG_A] = (((regs[REG_A] << 1) | (flags & FLAG_C)) & 0xff); - flags = ((flags & 0xEC) | tmp); + int res = ((regs[REG_A] << 1) | (flags & FLAG_C)) & 0xFF; + int flagC = ((regs[REG_A] & 0x80) == 0x80) ? FLAG_C : 0; + regs[REG_A] = res; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | flagC | (res & (FLAG_X | FLAG_Y)); return 4; } @@ -624,46 +695,37 @@ int I_LD_A_REF_DE() { } int I_RRA() { - int tmp = (flags & FLAG_C) << 7; - flags = ((flags & 0xEC) | (regs[REG_A] & 1)); - regs[REG_A] = ((regs[REG_A] >>> 1 | tmp) & 0xff); + int res = ((regs[REG_A] >>> 1) | (flags << 7)) & 0xFF; + int flagC = regs[REG_A] & FLAG_C; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | flagC | (res & (FLAG_X | FLAG_Y)); + regs[REG_A] = res; return 4; } int I_DAA() { - int a = regs[REG_A]; - boolean flagN = (flags & FLAG_N) != 0; - boolean flagH = (flags & FLAG_H) != 0; - boolean flagC = (flags & FLAG_C) != 0; - - if (flagN) { - if (flagH | ((regs[REG_A] & 0xf) > 9)) { - a -= 6; - } - if (flagC | (regs[REG_A] > 0x99)) { - a -= 0x60; - } - } else { - if (flagH | ((regs[REG_A] & 0xf) > 9)) { - a += 6; - } - if (flagC | (regs[REG_A] > 0x99)) { - a += 0x60; - } + // https://github.com/redcode/Z80/blob/master/sources/Z80.c + boolean cf = regs[REG_A] > 0x99; + int t = (((flags & FLAG_H) == FLAG_H) || (regs[REG_A] & 0xF) > 9) ? 6 : 0; + + if (((flags & FLAG_C) == FLAG_C) || cf) { + t |= 0x60; } - a = a & 0xFF; + t = (((flags & FLAG_N) == FLAG_N) ? regs[REG_A] - t : regs[REG_A] + t) & 0xFF; + + flags = (flags & (FLAG_N | FLAG_C)) + | TABLE_SZ[t] + | (t & (FLAG_Y | FLAG_X)) + | ((regs[REG_A] ^ t) & FLAG_H) + | PARITY_TABLE[t] + | (cf ? FLAG_C : 0); - flags = (flags & (FLAG_C | FLAG_N)) - | ((regs[REG_A] > 0x99) ? FLAG_C : 0) - | ((regs[REG_A] ^ a) & FLAG_H) - | TABLE_SZ[a] | PARITY_TABLE[a]; - regs[REG_A] = a; + regs[REG_A] = t; return 4; } int I_CPL() { - regs[REG_A] = ((~regs[REG_A]) & 0xFF); - flags |= FLAG_N | FLAG_H; + regs[REG_A] ^= 0xFF; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV | FLAG_C)) | FLAG_H | FLAG_N | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 4; } @@ -673,13 +735,9 @@ int I_SCF() { } int I_CCF() { - int tmp = flags & FLAG_C; - if (tmp == 0) { - flags |= FLAG_C; - } else { - flags &= ~FLAG_C; - } - flags &= ~FLAG_N; + /* Zilog: YF = A.5 | (YFi ^ YQi); XF = A.3 | (XFi ^ XQi) */ + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV | FLAG_C)) | + ((((flags ^ memptr)) | regs[REG_A]) & (FLAG_X | FLAG_Y) | ((flags & FLAG_C) << 4)); return 4; } @@ -808,14 +866,9 @@ int I_ADC_HL_RP() { } int I_NEG() { - int prevValue = regs[REG_A]; - regs[REG_A] = (((~prevValue) & 0xFF) + 1) & 0xFF; - int zero = (regs[REG_A] == 0) ? FLAG_Z : 0; - int carry = (prevValue == 0) ? 0 : FLAG_C; - int carryIns = regs[REG_A] ^ prevValue; - int overflow = (prevValue == 0x80) ? FLAG_PV : 0; - flags = overflow | (regs[REG_A] & 0x80) | zero | (carryIns & 0x10) | FLAG_N | carry; - return 8; + int v = regs[REG_A]; + regs[REG_A] = 0; + return I_SUB(v); } int I_RETN() { @@ -853,44 +906,41 @@ int I_IM_1() { return 8; } - int I_LD_A_I() { - regs[REG_A] = I & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C); - return 9; - } - int I_IM_2() { interruptMode = 2; return 8; } + int I_LD_A_I() { + regs[REG_A] = I & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + return 9; + } + int I_LD_A_R() { regs[REG_A] = R & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C); + flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 9; } int I_RRD() { - int tmp = regs[REG_A] & 0x0F; int hl = (regs[REG_H] << 8) | regs[REG_L]; memptr = (hl + 1) & 0xFFFF; - int tmp1 = memory.read(hl); - regs[REG_A] = ((regs[REG_A] & 0xF0) | (tmp1 & 0x0F)); - tmp1 = ((tmp1 >>> 4) & 0x0F) | (tmp << 4); - memory.write(hl, (byte) (tmp1 & 0xff)); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); + byte n = memory.read(hl); + memory.write(hl, (byte)((n >>> 4) | (regs[REG_A] << 4))); + regs[REG_A] = (regs[REG_A] & 0xF0) | (n & 0x0F); + flags = (flags & FLAG_C) | TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 18; } int I_RLD() { int hl = (regs[REG_H] << 8) | regs[REG_L]; memptr = (hl + 1) & 0xFFFF; - int tmp = memory.read(hl); - int tmp1 = (tmp >>> 4) & 0x0F; - tmp = ((tmp << 4) & 0xF0) | (regs[REG_A] & 0x0F); - regs[REG_A] = ((regs[REG_A] & 0xF0) | tmp1); - memory.write(hl, (byte) (tmp & 0xff)); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C); + byte value = memory.read(hl); + + memory.write(hl, (byte)((value << 4) | (regs[REG_A] & 0xF))); + regs[REG_A] = ((regs[REG_A] & 0xF0) | (value >>> 4)) & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C) | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 18; } @@ -914,15 +964,28 @@ int I_CPI() { bc = (bc - 1) & 0xFFFF; memptr = (memptr + 1) & 0xFFFF; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; + int sum = (regs[REG_A] - value) & 0xFF; int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; int flagP = (bc != 0) ? FLAG_PV : 0; flags = TABLE_SUB[sum] | flagH | flagP | (flags & FLAG_C); - regs[REG_H] = (hl >>> 8) & 0xFF; - regs[REG_L] = hl & 0xFF; - regs[REG_B] = (bc >>> 8) & 0xFF; - regs[REG_C] = bc & 0xFF; + if ((flags & FLAG_H) == FLAG_H) { + sum = (sum - 1) & 0xFF; + } + if ((sum & 0x02) != 0) { + flags |= FLAG_Y; + } + if ((sum & 0x08) != 0) { + flags |= FLAG_X; + } + if (bc != 0) { + flags |= FLAG_PV; + } return 16; } @@ -971,14 +1034,23 @@ int I_CPD() { memptr = (memptr - 1) & 0xFFFF; int sum = (regs[REG_A] - value) & 0xFF; - int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; - int flagP = (bc != 0) ? FLAG_PV : 0; - flags = TABLE_SUB[sum] | flagH | flagP | (flags & FLAG_C); - regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; + + int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; + int flagP = (bc != 0) ? FLAG_PV : 0; + flags = TABLE_SUB[sum] | flagH | flagP | (flags & FLAG_C); + if ((flags & FLAG_H) == FLAG_H) { + sum = (sum - 1) & 0xFF; + } + if ((sum & 0x02) != 0) { + flags |= FLAG_Y; + } + if ((sum & 0x08) != 0) { + flags |= FLAG_X; + } return 16; } @@ -1083,56 +1155,35 @@ int I_LDI() { } int I_LDIR() { - int bc = (regs[REG_B] << 8) | regs[REG_C]; - if (bc != 1) { - memptr = (PC - 1) & 0xFFFF; - } -// -// System.out.printf("---\nBEFORE: BC=%04X DE=%04X HL=%04X A=%02X F=%s\n", -// ((regs[REG_B] << 8) | regs[REG_C]), -// ((regs[REG_D] << 8) | regs[REG_E]), -// ((regs[REG_H] << 8) | regs[REG_L]), -// regs[REG_A], -// intToFlags(flags) -// ); + int hl = (regs[REG_H] << 8) | regs[REG_L]; + byte t = memory.read(hl++); - I_LDI(); - if ((regs[REG_B] == 0) && (regs[REG_C] == 0)) { -// System.out.printf("BC=%04X DE=%04X HL=%04X A=%02X F=%s\n---\n", -// ((regs[REG_B] << 8) | regs[REG_C]), -// ((regs[REG_D] << 8) | regs[REG_E]), -// ((regs[REG_H] << 8) | regs[REG_L]), -// regs[REG_A], -// intToFlags(flags) -// ); - return 16; - } - PC = (PC - 2) & 0xFFFF; + int de = (regs[REG_D] << 8) | regs[REG_E]; + memory.write(de++, t); - //Flag effects are the same as LDI except that P/V will always be reset, because BC by definition reaches - // 0 before this instruction ends (normally - unless something overwrites LDIR opcode while BC>0). + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = (hl & 0xFF); + regs[REG_D] = (de >>> 8) & 0xFF; + regs[REG_E] = (de & 0xFF); - // https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags#interrupted-block-instructions - //YF = PC.13 - //XF = PC.11 + t += regs[REG_A]; - // 0010 1100 = 2C - // 1101 0011 = D3 - // 1101 0111 = D7 -// flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | ((PC >>> 8) & (FLAG_X | FLAG_Y)); -// System.out.printf("BC=%04X DE=%04X HL=%04X A=%02X F=%s\n", -// ((regs[REG_B] << 8) | regs[REG_C]), -// ((regs[REG_D] << 8) | regs[REG_E]), -// ((regs[REG_H] << 8) | regs[REG_L]), -// regs[REG_A], -// intToFlags(flags) -// ); - - //flag_f5 = (reg_pc >> 13) & 1; - // flag_f3 = (reg_pc >> 11) & 1; - // 00101000 00000000 PC - flags &= 0xD3; // reset P/V, X, Y - flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + int bc = ((regs[REG_B] << 8) | regs[REG_C]) - 1; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = (bc & 0xFF); + + if (bc != 0) { + PC = (PC - 2) & 0xFFFF; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | + ((PC >>> 8) & (FLAG_Y | FLAG_X)) | + FLAG_PV; + memptr = PC + 1; + return 21; + } + + flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | + ((t & 2) << 4) | /* YF = (A + [HLi]).1 */ + (t & FLAG_X); return 21; } @@ -1404,26 +1455,6 @@ int I_JR_N() { return 12; } - int I_ADD_A_N() { - int value = memory.read(PC) & 0xFF; - PC = (PC + 1) & 0xFFFF; - int oldA = regs[REG_A]; - int sum = (oldA + value) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); - return 7; - } - - int I_ADC_A_N() { - int value = memory.read(PC) & 0xFF; - PC = (PC + 1) & 0xFFFF; - int oldA = regs[REG_A]; - int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); - return 7; - } - int I_OUT_REF_N_A() { int port = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; @@ -1433,73 +1464,24 @@ int I_OUT_REF_N_A() { return 11; } - int I_SUB_N() { - int value = memory.read(PC) & 0xFF; - PC = (PC + 1) & 0xFFFF; - - int oldA = regs[REG_A]; - int sum = (oldA - value) & 0x1FF; - regs[REG_A] = sum & 0xFF; - - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; - return 7; - } - int I_IN_A_REF_N() { int port = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; + //_memPtr = (A << 8) + _memory.ReadByte(PC) + _memory.ReadByte(PC + 1) * 256 + 1; memptr = ((regs[REG_A] << 8) + port + 1) & 0xFFFF; regs[REG_A] = (context.readIO(port) & 0xFF); return 11; } - int I_SBC_A_N() { + int I_SUB_N() { int value = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; int oldA = regs[REG_A]; - int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; + int sum = (oldA - value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; - return 7; - } - - int I_AND_N() { - int tmp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - - regs[REG_A] = (regs[REG_A] & tmp) & 0xFF; - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H; - return 7; - } - - int I_XOR_N() { - int tmp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - - regs[REG_A] = ((regs[REG_A] ^ tmp) & 0xFF); - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]]; - return 7; - } - - int I_OR_N() { - int tmp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - - regs[REG_A] = (regs[REG_A] | tmp) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]]; - return 7; - } - - int I_CP_N() { - int value = memory.read(PC) & 0xFF; - PC = (PC + 1) & 0xFFFF; - - int oldA = regs[REG_A]; - int sum = (oldA - value) & 0x1FF; - int result = sum & 0xFF; - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]); + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 7; } @@ -1614,10 +1596,10 @@ int I_RLC_R() { int reg = lastOpcode & 7; int regValue = getreg(reg) & 0xFF; - int c = ((regValue & 0x80) != 0) ? FLAG_C : 0; + int flagC = ((regValue & 0x80) != 0) ? FLAG_C : 0; regValue = ((regValue << 1) | (regValue >>> 7)) & 0xFF; putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | c; + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); if (reg == 6) { return 15; @@ -1627,16 +1609,14 @@ int I_RLC_R() { } int I_RRC_R() { - int tmp = lastOpcode & 7; - int tmp1 = getreg(tmp) & 0xFF; - - int tmp2 = tmp1 & 1; - tmp1 = (((tmp1 >>> 1) & 0x7F) | (tmp2 << 7)) & 0xFF; - putreg(tmp, tmp1); - - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int flagC = regValue & FLAG_C; + regValue = ((regValue >>> 1) | (regValue << 7)) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); - if (tmp == 6) { + if (reg == 6) { return 15; } else { return 8; @@ -1644,16 +1624,14 @@ int I_RRC_R() { } int I_RL_R() { - int tmp = lastOpcode & 7; - int tmp1 = getreg(tmp) & 0xFF; - - int tmp2 = (tmp1 >>> 7) & 1; - tmp1 = ((((tmp1 << 1) & 0xFF) | flags & FLAG_C) & 0xFF); - putreg(tmp, tmp1); - - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int flagC = ((regValue & 0x80) == 0x80) ? FLAG_C : 0; + regValue = ((regValue << 1) | (flags & FLAG_C)) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); - if (tmp == 6) { + if (reg == 6) { return 15; } else { return 8; @@ -1661,16 +1639,14 @@ int I_RL_R() { } int I_RR_R() { - int tmp = lastOpcode & 7; - int tmp1 = getreg(tmp) & 0xFF; - - int tmp2 = tmp1 & 1; - tmp1 = ((((tmp1 >> 1) & 0x7F) | (flags & FLAG_C) << 7) & 0xFF); - putreg(tmp, tmp1); - - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int flagC = regValue & FLAG_C; + regValue = ((regValue >>> 1) | (flags << 7)) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); - if (tmp == 6) { + if (reg == 6) { return 15; } else { return 8; @@ -1678,16 +1654,15 @@ int I_RR_R() { } int I_SLA_R() { - int tmp = lastOpcode & 7; - int tmp1 = getreg(tmp) & 0xFF; - - int tmp2 = (tmp1 >>> 7) & 1; - tmp1 = (tmp1 << 1) & 0xFE; - putreg(tmp, tmp1); + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + int flagC = ((regValue & 0x80) == 0x80) ? FLAG_C : 0; + regValue = (regValue << 1) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); - if (tmp == 6) { + if (reg == 6) { return 15; } else { return 8; @@ -1695,16 +1670,14 @@ int I_SLA_R() { } int I_SRA_R() { - int tmp = lastOpcode & 7; - int tmp1 = getreg(tmp) & 0xFF; - - int tmp2 = tmp1 & 1; - tmp1 = (tmp1 >> 1) & 0xFF | (tmp1 & 0x80); - putreg(tmp, tmp1); - - flags = TABLE_SZ[tmp1] | EmulatorTables.PARITY_TABLE[tmp1] | tmp2; + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int flagC = regValue & FLAG_C; + regValue = ((regValue >>> 1) | (regValue & 0x80)) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); - if (tmp == 6) { + if (reg == 6) { return 15; } else { return 8; @@ -1714,11 +1687,10 @@ int I_SRA_R() { int I_SLL_R() { int reg = lastOpcode & 7; int regValue = getreg(reg) & 0xFF; - int c = ((regValue & 0x80) != 0) ? FLAG_C : 0; + int flagC = ((regValue & 0x80) != 0) ? FLAG_C : 0; regValue = ((regValue << 1) | 0x01) & 0xFF; - putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | c; + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); if (reg == 6) { return 15; @@ -1730,12 +1702,10 @@ int I_SLL_R() { int I_SRL_R() { int reg = lastOpcode & 7; int regValue = getreg(reg) & 0xFF; - - int c = ((regValue & 0x01) != 0) ? FLAG_C : 0; + int flagC = regValue & FLAG_C; regValue = (regValue >>> 1) & 0xFF; putreg(reg, regValue); - - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | c; + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); if (reg == 6) { return 15; @@ -1749,11 +1719,16 @@ int I_BIT_N_R() { int bit = (lastOpcode >>> 3) & 7; int reg = lastOpcode & 7; int regValue = getreg(reg) & 0xFF; - flags = ((flags & FLAG_C) | FLAG_H | (((regValue & (1 << bit)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); - if (bit == 7) { - flags |= (((regValue & (1 << bit)) == 0x80) ? FLAG_S : 0); - } + int result = (1 << bit) & regValue; + + flags = ((result != 0) ? (result & FLAG_S) : (FLAG_Z | FLAG_PV)) + | (regValue & (FLAG_X | FLAG_Y)) + | FLAG_H + | (flags & FLAG_C); + if (reg == 6) { + flags &= (~FLAG_X); + flags &= (~FLAG_Y); flags |= ((memptr >>> 8) & FLAG_X) | ((memptr >>> 8) & FLAG_Y); return 12; } else { @@ -1901,7 +1876,7 @@ int I_INC_REF_II_N(int special) { int sum = (value + 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C); + flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | (sum & (FLAG_X | FLAG_Y)); memory.write(address, (byte) sumByte); return 23; @@ -1925,7 +1900,7 @@ int I_DEC_REF_II_N(int special) { int sum = (value - 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C); + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | (sum & (FLAG_X | FLAG_Y)); memory.write(address, (byte) sumByte); return 23; } @@ -2230,7 +2205,7 @@ int I_RLC_REF_II_N_R(byte operand, int special) { int c = ((addrValue & 0x80) != 0) ? FLAG_C : 0; int res = ((addrValue << 1) | (addrValue >>> 7)) & 0xFF; memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | PARITY_TABLE[res] | c; + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; @@ -2253,7 +2228,7 @@ int I_RRC_REF_II_N_R(byte operand, int special) { int c = addrValue & 1; int res = (((addrValue >>> 1) & 0x7F) | (c << 7)) & 0xFF; memory.write(addr, (byte) (res & 0xFF)); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c; + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; @@ -2277,7 +2252,7 @@ int I_RL_REF_II_N_R(byte operand, int special) { int res = ((((addrValue << 1) & 0xFF) | flags & FLAG_C) & 0xFF); memory.write(addr, (byte) (res & 0xFF)); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c; + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; return 23; @@ -2300,7 +2275,7 @@ int I_RR_REF_II_N_R(byte operand, int special) { int res = ((((addrValue >> 1) & 0xFF) | (flags & FLAG_C) << 7) & 0xFF); memory.write(addr, (byte) (res & 0xFF)); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c; + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; return 23; @@ -2322,7 +2297,7 @@ int I_SLA_REF_II_N_R(byte operand, int special) { int c = (addrValue >>> 7) & 1; int res = (addrValue << 1) & 0xFE; memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c; + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; @@ -2346,7 +2321,7 @@ int I_SRA_REF_II_N_R(byte operand, int special) { int res = (addrValue >> 1) & 0xFF | (addrValue & 0x80); memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c; + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; return 23; @@ -2369,7 +2344,7 @@ int I_SLL_REF_II_N_R(byte operand, int special) { int res = ((addrValue << 1) | 0x01) & 0xFF; memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | PARITY_TABLE[res] | c; + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res; @@ -2393,7 +2368,7 @@ int I_SRL_REF_II_N_R(byte operand, int special) { int res = (addrValue >>> 1) & 0xFF; memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | PARITY_TABLE[res] | c; + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); // regs[6] is unused, so it's ok to set it regs[lastOpcode & 7] = res; return 23; @@ -2408,13 +2383,18 @@ int I_BIT_N_REF_IY_N(byte operand) { } int I_BIT_N_REF_II_N(byte operand, int special) { - int bitNumber = (lastOpcode >>> 3) & 7; + int bit = (lastOpcode >>> 3) & 7; int address = (special + operand) & 0xFFFF; memptr = address; byte addrValue = memory.read(address); - flags = ((flags & FLAG_C) | FLAG_H | (((addrValue & (1 << bitNumber)) == 0) ? (FLAG_Z | FLAG_PV) : 0)); - if (bitNumber == 7) { - flags |= (((addrValue & (1 << 7)) == 0x80) ? FLAG_S : 0); + int result = (1 << bit) & addrValue; + + flags = ((flags & FLAG_C) + | FLAG_H + | ((result == 0) ? (FLAG_Z | FLAG_PV) : 0)) + | (special & (FLAG_X | FLAG_Y)); + if (bit == 7) { + flags |= ((result == 0x80) ? FLAG_S : 0); } return 20; } @@ -2484,7 +2464,7 @@ int I_INC_IYL() { int I_INC(int value) { int sum = (value + 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C); + flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | (sum & (FLAG_X | FLAG_Y)); return sumByte; } @@ -2502,7 +2482,7 @@ int I_DEC_IIH(int special) { int reg = special >>> 8; int sum = (reg - 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C); + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C) | (sum & (FLAG_X | FLAG_Y)); return sumByte; } @@ -2520,7 +2500,7 @@ int I_DEC_IIL(int special) { int reg = special & 0xFF; int sum = (reg - 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C); + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C) | (sum & (FLAG_X | FLAG_Y)); return sumByte; } @@ -2648,7 +2628,7 @@ int I_ADD_A(int value) { int oldA = regs[REG_A]; int sum = (oldA + value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (sum & (FLAG_X | FLAG_Y)); return 8; } @@ -2672,7 +2652,7 @@ int I_ADC_A(int value) { int oldA = regs[REG_A]; int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (sum & (FLAG_X | FLAG_Y)); return 8; } @@ -2697,7 +2677,7 @@ int I_SUB(int value) { int sum = (oldA - value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (sum & (FLAG_X | FLAG_Y)); return 8; } @@ -2721,7 +2701,7 @@ int I_SBC_A(int value) { int oldA = regs[REG_A]; int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (sum & (FLAG_X | FLAG_Y)); return 8; } @@ -2743,7 +2723,7 @@ int I_AND_IYL() { int I_AND(int value) { regs[REG_A] = (regs[REG_A] & value) & 0xFF; - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H; + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 8; } @@ -2765,7 +2745,7 @@ int I_XOR_IYL() { int I_XOR(int value) { regs[REG_A] = (regs[REG_A] ^ value) & 0xFF; - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]]; + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 8; } @@ -2787,7 +2767,7 @@ int I_OR_IYL() { int I_OR(int value) { regs[REG_A] = (regs[REG_A] | value) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]]; + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 8; } @@ -2811,7 +2791,7 @@ int I_CP(int value) { int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]); + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | (sum & (FLAG_X | FLAG_Y)); return 8; } } From 76b3e1734020b88bf2a94331b8be2ee6b92825a4 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 28 Aug 2022 11:17:57 +0100 Subject: [PATCH 197/314] [#260] Revert LSI adm3A changes + introduce zx spectrum display --- application/build.gradle | 2 + .../src/main/files/config/ZxSpectrum.toml | 179 ++++++++++++ .../cpu/intel8080/Context8080Impl.java | 7 +- .../cpu/intel8080/api/Context8080.java | 5 + .../plugins/cpu/zilogZ80/ContextZ80Impl.java | 29 ++ .../plugins/cpu/zilogZ80/EmulatorEngine.java | 149 +++++++--- .../plugins/cpu/zilogZ80/ControlTest.java | 6 +- .../cpu/zilogZ80/FlagsTableGeneratorTest.java | 172 ------------ .../plugins/cpu/zilogZ80/LogicTest.java | 96 ++++--- .../cpu/zilogZ80/suite/ByteTestBuilder.java | 5 + .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 8 + .../plugins/device/adm3a/DeviceImpl.java | 2 +- .../device/adm3a/interaction/Cursor.java | 34 --- .../device/adm3a/interaction/Display.java | 50 +--- .../plugins/device/simh/PseudoContext.java | 2 +- .../device/simh/commands/AttachPTP.java | 2 +- .../plugins/device/simh/commands/Command.java | 2 +- .../simh/commands/GetCPUClockFrequency.java | 2 +- .../device/simh/commands/GetClockCPM3.java | 2 +- .../device/simh/commands/GetClockZSDOS.java | 2 +- .../device/simh/commands/GetCommon.java | 2 +- .../simh/commands/GetHostFilenames.java | 2 +- .../device/simh/commands/GetSimhVersion.java | 2 +- .../device/simh/commands/ReadStopWatch.java | 2 +- .../plugins/device/simh/commands/ReadURL.java | 4 +- .../simh/commands/ResetSimhInterface.java | 2 +- .../device/simh/commands/SIMHSleep.java | 11 +- .../simh/commands/SetCPUClockFrequency.java | 6 +- .../device/simh/commands/SetClockCPM3.java | 2 +- .../device/simh/commands/SetClockZSDOS.java | 2 +- .../device/simh/commands/SetTimerDelta.java | 8 +- .../simh/commands/SetTimerInterruptAdr.java | 4 +- .../device/simh/commands/StartTimer.java | 2 +- .../simh/commands/StartTimerInterrupts.java | 51 +++- .../simh/commands/StopTimerInterrupts.java | 2 +- .../device/zxspectrum-display/build.gradle | 55 ++++ .../device/zxspectrum/display/DeviceImpl.java | 129 +++++++++ .../display/ZxSpectrumDisplayContext.java | 60 ++++ .../display/ZxSpectrumDisplayGui.java | 258 ++++++++++++++++++ .../device/zxspectrum/display/io/Cursor.java | 153 +++++++++++ .../device/zxspectrum/display/io/Display.java | 217 +++++++++++++++ .../display/io/DisplayParameters.java | 14 + .../zxspectrum/display/io/GUIUtils.java | 30 ++ .../zxspectrum/display/io/IOProvider.java | 9 + .../zxspectrum/display/io/Keyboard.java | 49 ++++ .../zxspectrum/display/io/LineRoller.java | 8 + .../zxspectrum/display/io/OutputProvider.java | 27 ++ .../device/zxspectrum/display/16_ascii.png | Bin 0 -> 415 bytes .../zxspectrum/display/16_circle_blue.png | Bin 0 -> 473 bytes .../zxspectrum/display/16_circle_green.png | Bin 0 -> 461 bytes .../zxspectrum/display/16_circle_red.png | Bin 0 -> 436 bytes .../zxspectrum/display/version.properties | 21 ++ settings.gradle | 1 + 53 files changed, 1509 insertions(+), 380 deletions(-) create mode 100644 application/src/main/files/config/ZxSpectrum.toml delete mode 100644 plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FlagsTableGeneratorTest.java create mode 100644 plugins/device/zxspectrum-display/build.gradle create mode 100644 plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java create mode 100644 plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayContext.java create mode 100644 plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java create mode 100644 plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Cursor.java create mode 100644 plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java create mode 100644 plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/DisplayParameters.java create mode 100644 plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/GUIUtils.java create mode 100644 plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/IOProvider.java create mode 100644 plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java create mode 100644 plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/LineRoller.java create mode 100644 plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/OutputProvider.java create mode 100644 plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_ascii.png create mode 100644 plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_circle_blue.png create mode 100644 plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_circle_green.png create mode 100644 plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_circle_red.png create mode 100644 plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/version.properties diff --git a/application/build.gradle b/application/build.gradle index c95a4d6cf..a537248bd 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -76,6 +76,7 @@ dependencies { providedRuntime project(":plugins:device:brainduck-terminal") providedRuntime project(":plugins:device:simh-pseudo") providedRuntime project(":plugins:device:ssem-display") + providedRuntime project(":plugins:device:zxspectrum-display") testImplementation libs.junit testImplementation libs.easyMock @@ -217,6 +218,7 @@ distributions { from(output(":plugins:device:brainduck-terminal")) from(output(":plugins:device:simh-pseudo")) from(output(":plugins:device:ssem-display")) + from(output(":plugins:device:zxspectrum-display")) } // Examples diff --git a/application/src/main/files/config/ZxSpectrum.toml b/application/src/main/files/config/ZxSpectrum.toml new file mode 100644 index 000000000..44cf59bef --- /dev/null +++ b/application/src/main/files/config/ZxSpectrum.toml @@ -0,0 +1,179 @@ +name = "ZX Spectrum" + +[MEMORY] +schemaPoint = "80,220" +path = "byte-mem.jar" +name = "byte-mem" +id = "1e13a25d-fb23-4061-853a-5fe996b03281" +type = "MEMORY" + +[MEMORY.settings] +# memorySize = 49152 +banksCount = 0 +imageName0 = "/home/vbmacher/tmp/emuStudio/z80bltst.bin" +imageBank0 = 0 +imageAddress0 = 32768 + +# memorySize = 65536 +# ROM areas are stored as pairs ROMfromN and ROMtoN, where N is 0-based counter. There can be multiple rom areas. +# ROMfromN = someAddress +# ROMtoN = someAddress +# Memory "images" (files) will be loaded at startup into memory. They are stored here as triplet: +# - imageNameN (file name), +# - imageAddressN (address where the file will be loaded), +# - imageBankN (if memory has >1 banksCount, then number of bank; 0 otherwise) +# +# where N is a 0-based counter +# imageNameN = imageFileName # if the suffix ends with ".hex", the format will be Intel HEX; otherwise it will be binary +# imageAddressN = ... +# imageBankN = 0 +[COMPILER] +schemaPoint = "80,60" +path = "as-z80.jar" +settings = {} +name = "as-z80" +id = "9233e0c2-b53c-41e7-9eca-bbb264fcd9da" +type = "COMPILER" + +[CPU] +schemaPoint = "220,220" +path = "z80-cpu.jar" +settings = {} +name = "z80-cpu" +id = "b86d4bc2-632c-46e3-bba1-c088c9177983" +type = "CPU" + +# Uncomment the following for specific settings (and remove settings = {} above) +# [CPU.settings] +# printCode = true +# printCodeUseCache = true +# printCodeFileName = "syserr" # Or custom path to a file + +[[DEVICE]] +schemaPoint = "340,140" +path = "88-dcdd.jar" +name = "88-dcdd" +id = "c94d0e9b-f394-4a71-94b0-87d0f970a3fd" +type = "DEVICE" + +[DEVICE.settings] +# imageN = "..." # Load file into drive N at startup +sectorLength8 = 137 +sectorLength9 = 137 +sectorLength6 = 137 +sectorLength7 = 137 +sectorLength4 = 137 +sectorLength5 = 137 +sectorLength2 = 137 +sectorLength3 = 137 +sectorLength0 = 137 +sectorLength1 = 137 +port2CPU = 9 +sectorsPerTrack15 = 32 +sectorsPerTrack14 = 32 +sectorsPerTrack13 = 32 +sectorsPerTrack12 = 32 +sectorsPerTrack1 = 32 +sectorsPerTrack11 = 32 +sectorsPerTrack2 = 32 +sectorsPerTrack10 = 32 +sectorsPerTrack0 = 32 +sectorsPerTrack5 = 32 +sectorsPerTrack6 = 32 +sectorsPerTrack3 = 32 +sectorsPerTrack4 = 32 +sectorsPerTrack9 = 32 +sectorsPerTrack7 = 32 +sectorsPerTrack8 = 32 +port1CPU = 8 +port3CPU = 10 +sectorLength15 = 137 +sectorLength13 = 137 +sectorLength14 = 137 +sectorLength11 = 137 +sectorLength12 = 137 +sectorLength10 = 137 + +[[DEVICE]] +schemaPoint = "340,220" +path = "88-sio.jar" +name = "88-sio" +id = "de2ce2e7-4365-406e-864a-b60f353d3fba" +type = "DEVICE" + +[DEVICE.settings] +statusPorts = "0x10, 0x14, 0x16, 0x18" +dataPorts = "0x11, 0x15, 0x17, 0x19" +clearInputBit8 = false +clearOutputBit8 = false +inputToUpperCase = false +mapDeleteChar = "UNCHANGED" +mapBackspaceChar = "UNCHANGED" +inputInterruptVector = 0 +outputInterruptVector = 0 + +[[DEVICE]] +schemaPoint = "480,220" +path = "zxspectrum-display.jar" +name = "zxspectrum-display" +id = "0352cf74-2965-4723-bef9-3e918b1ac7c5" +type = "DEVICE" + +[DEVICE.settings] +antiAliasing = true +alwaysOnTop = true +inputReadDelay = 0 +halfDuplex = false +outputFileName = "adm3A-terminal.out" +inputFileName = "adm3A-terminal.in" + +[[DEVICE]] +schemaPoint = "220,60" +path = "simh-pseudo.jar" +settings = {} +name = "simh-pseudo" +id = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" +type = "DEVICE" + +[[connections]] +bidirectional = true +from = "9233e0c2-b53c-41e7-9eca-bbb264fcd9da" +to = "1e13a25d-fb23-4061-853a-5fe996b03281" +points = [] + +[[connections]] +bidirectional = true +from = "c94d0e9b-f394-4a71-94b0-87d0f970a3fd" +to = "b86d4bc2-632c-46e3-bba1-c088c9177983" +points = ["240,140"] + +[[connections]] +bidirectional = true +from = "1e13a25d-fb23-4061-853a-5fe996b03281" +to = "b86d4bc2-632c-46e3-bba1-c088c9177983" +points = [] + +[[connections]] +bidirectional = true +from = "de2ce2e7-4365-406e-864a-b60f353d3fba" +to = "b86d4bc2-632c-46e3-bba1-c088c9177983" +points = [] + +[[connections]] +bidirectional = true +from = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" +to = "b86d4bc2-632c-46e3-bba1-c088c9177983" +points = [] + +[[connections]] +bidirectional = true +from = "0352cf74-2965-4723-bef9-3e918b1ac7c5" +to = "de2ce2e7-4365-406e-864a-b60f353d3fba" +points = [] + +[[connections]] +bidirectional = true +from = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" +to = "1e13a25d-fb23-4061-853a-5fe996b03281" +points = ["200,140", "120,140"] + diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java index c4bc5504a..3622a46a6 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java @@ -114,8 +114,11 @@ public int getCPUFrequency() { } @Override - public void setCPUFrequency(int freq) { - this.clockFrequency = freq; + public void setCPUFrequency(int frequency) { + if (frequency <= 0) { + throw new IllegalArgumentException("Invalid CPU frequency (expected > 0): " + frequency); + } + this.clockFrequency = frequency; } } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/Context8080.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/Context8080.java index 34383810d..d13f026be 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/Context8080.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/Context8080.java @@ -44,5 +44,10 @@ public interface Context8080 extends CPUContext { */ void detachDevice(int port); + /** + * Set CPU frequency in kHZ + * + * @param freq new frequency in kHZ + */ void setCPUFrequency(int freq); } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java index a3c7dd0c9..47160d235 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java @@ -20,12 +20,16 @@ import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.cpu.zilogZ80.api.ContextZ80; +import net.jcip.annotations.ThreadSafe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArrayList; +@ThreadSafe public final class ContextZ80Impl implements ContextZ80 { private final static byte NO_DATA = (byte)0xFF; public final static int DEFAULT_FREQUENCY_KHZ = 20000; @@ -35,6 +39,7 @@ public final class ContextZ80Impl implements ContextZ80 { private volatile EmulatorEngine engine; private volatile int clockFrequency = DEFAULT_FREQUENCY_KHZ; + private final List runCallbacks = new CopyOnWriteArrayList<>(); public void setEngine(EmulatorEngine engine) { this.engine = engine; @@ -79,6 +84,12 @@ byte readIO(int port) { return NO_DATA; } + public void triggerRunCallbacks() { + for (Runnable runnable : runCallbacks) { + runnable.run(); + } + } + @Override public boolean isInterruptSupported() { return true; @@ -86,6 +97,9 @@ public boolean isInterruptSupported() { @Override public void setCPUFrequency(int frequency) { + if (frequency <= 0) { + throw new IllegalArgumentException("Invalid CPU frequency (expected > 0): " + frequency); + } clockFrequency = frequency; } @@ -104,4 +118,19 @@ public int getCPUFrequency() { public void signalNonMaskableInterrupt() { engine.requestNonMaskableInterrupt(); } + + @Override + public boolean isRunCallbackSupported() { + return true; + } + + @Override + public void registerRunCallback(Runnable runnable) { + runCallbacks.add(runnable); + } + + @Override + public void unregisterRunCallback(Runnable runnable) { + runCallbacks.remove(runnable); + } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 3f4d50c21..3f8d59782 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -45,6 +45,7 @@ * Main implementation class for CPU emulation CPU works in a separate thread * (parallel with other hardware) */ +// TODO: set frequency runtime @SuppressWarnings("unused") public class EmulatorEngine implements CpuEngine { private final static Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); @@ -74,6 +75,7 @@ public class EmulatorEngine implements CpuEngine { public int PC = 0, SP = 0, IX = 0, IY = 0; public int I = 0, R = 0; // interrupt r., refresh r. public int memptr = 0; // internal register, https://gist.github.com/drhelius/8497817 + public int Q = 0; // internal register, public final boolean[] IFF = new boolean[2]; // interrupt enable flip-flops public byte interruptMode = 0; @@ -90,6 +92,7 @@ public class EmulatorEngine implements CpuEngine { public EmulatorEngine(MemoryContext memory, ContextZ80Impl context) { this.memory = Objects.requireNonNull(memory); this.context = Objects.requireNonNull(context); + LOGGER.info("Sleep precision: " + SleepUtils.SLEEP_PRECISION + " nanoseconds."); } @Override @@ -130,7 +133,9 @@ public void requestNonMaskableInterrupt() { } void reset(int startPos) { - SP = IX = IY = 0; + IX = IY = 0; + SP = 0xFFFF; + flags = 0xFF; I = R = 0; memptr = 0; Arrays.fill(regs, 0); @@ -159,10 +164,14 @@ CPU.RunState step() throws Exception { public CPU.RunState run(CPU cpu) { long startTime, endTime; int cycles_executed; - int checkTimeSlice = 100; + // In Z80, 1 t-state = 250 ns = 0.25 microseconds = 0.00025 milliseconds + // in 10 milliseconds = 10 / 0.00025 = 40000 t-states are executed uncontrollably + // in 1 millisecond = 1 / 0.00025 = 4000 t-states :( + + int checkTimeSlice = (int)Math.ceil(SleepUtils.SLEEP_PRECISION / 1000000.0); // milliseconds int cycles_to_execute = checkTimeSlice * context.getCPUFrequency(); int cycles; - long slice = checkTimeSlice * 1000000; + long slice = checkTimeSlice * 1000000L; // nanoseconds currentRunState = CPU.RunState.STATE_RUNNING; while (!Thread.currentThread().isInterrupted() && (currentRunState == CPU.RunState.STATE_RUNNING)) { @@ -176,16 +185,14 @@ public CPU.RunState run(CPU cpu) { if (cpu.isBreakpointSet(PC)) { throw new Breakpoint(); } + context.triggerRunCallbacks(); } catch (Breakpoint e) { return CPU.RunState.STATE_STOPPED_BREAK; } catch (IndexOutOfBoundsException e) { - LOGGER.debug("Unexpected error", e); - return CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; - } catch (IOException e) { LOGGER.error("Unexpected error", e); - return RunState.STATE_STOPPED_BAD_INSTR; + return CPU.RunState.STATE_STOPPED_ADDR_FALLOUT; } catch (Throwable e) { - LOGGER.debug("Unexpected error", e); + LOGGER.error("Unexpected error", e); return CPU.RunState.STATE_STOPPED_BAD_INSTR; } } @@ -278,7 +285,7 @@ private int doInterrupt() throws Throwable { int cycles = 0; IFF[0] = IFF[1] = false; - System.out.println("z80: interrupt! im=" + interruptMode + ", dataBus=" + Arrays.toString(dataBus)); + //System.out.println("z80: interrupt! im=" + interruptMode + ", dataBus=" + Arrays.toString(dataBus)); switch (interruptMode) { case 0: cycles += 11; @@ -310,8 +317,13 @@ private int doInterrupt() throws Throwable { cycles += 13; if (dataBus != null && dataBus.length > 0) { SP = (SP - 2) & 0xFFFF; - writeWord(SP, PC); - PC = readWord((I << 8) | dataBus[0]); + if (memory.read(PC) == 0x76) { + // jump over HALT + writeWord(SP, (PC + 1) & 0xFFFF); + } else { + writeWord(SP, PC); + } + PC = readWord(((I << 8) | (dataBus[0] & 0xFF)) & 0xFFFF); memptr = PC; } break; @@ -445,6 +457,7 @@ int I_PUSH_RP() { } int I_LD_R_N() { + Q = 0; int reg = (lastOpcode >>> 3) & 0x07; putreg(reg, memory.read(PC)); PC = (PC + 1) & 0xFFFF; @@ -476,6 +489,7 @@ int I_DEC_R() { } int I_RET_CC() { + Q = 0; int cc = (lastOpcode >>> 3) & 7; if ((flags & CONDITION[cc]) == CONDITION_VALUES[cc]) { PC = readWord(SP); @@ -655,12 +669,13 @@ int I_LD_A_REF_BC() { int I_RRCA() { flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | (regs[REG_A] & FLAG_C); - regs[REG_A] = (regs[REG_A] >>> 1) | (regs[REG_A] << 7); + regs[REG_A] = ((regs[REG_A] >>> 1) | (regs[REG_A] << 7)) & 0xFF; flags |= (regs[REG_A] & (FLAG_X | FLAG_Y)); return 4; } int I_DJNZ() { + Q = 0; byte addr = memory.read(PC); PC = (PC + 1) & 0xFFFF; regs[REG_B] = (regs[REG_B] - 1) & 0xFF; @@ -730,18 +745,23 @@ int I_CPL() { } int I_SCF() { - flags = (flags & (FLAG_S | FLAG_Z | FLAG_Y | FLAG_X | FLAG_PV)) | FLAG_C | (regs[REG_A] & (FLAG_Y | FLAG_X)); + flags = (flags & (FLAG_S | FLAG_Z | FLAG_Y | FLAG_X | FLAG_PV)) | FLAG_C; return 4; } int I_CCF() { /* Zilog: YF = A.5 | (YFi ^ YQi); XF = A.3 | (XFi ^ XQi) */ - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV | FLAG_C)) | - ((((flags ^ memptr)) | regs[REG_A]) & (FLAG_X | FLAG_Y) | ((flags & FLAG_C) << 4)); + int c = flags & FLAG_C; + int h = flags & FLAG_H; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) + | (h ^ FLAG_H) // (c << FLAG_H) + | (regs[REG_A] & (FLAG_X | FLAG_Y)) + | (c ^ FLAG_C); return 4; } int I_RET() { + Q = 0; PC = readWord(SP); memptr = PC; SP = (SP + 2) & 0xFFFF; @@ -872,6 +892,7 @@ int I_NEG() { } int I_RETN() { + Q = 0; IFF[0] = IFF[1]; PC = readWord(SP); SP = (SP + 2) & 0xffff; @@ -889,6 +910,7 @@ int I_LD_I_A() { } int I_RETI() { + Q = 0; IFF[0] = IFF[1]; PC = readWord(SP); memptr = PC; @@ -924,22 +946,25 @@ int I_LD_A_R() { } int I_RRD() { + int regA = regs[REG_A] & 0x0F; int hl = (regs[REG_H] << 8) | regs[REG_L]; memptr = (hl + 1) & 0xFFFF; - byte n = memory.read(hl); - memory.write(hl, (byte)((n >>> 4) | (regs[REG_A] << 4))); - regs[REG_A] = (regs[REG_A] & 0xF0) | (n & 0x0F); - flags = (flags & FLAG_C) | TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + int value = memory.read(hl); + regs[REG_A] = ((regs[REG_A] & 0xF0) | (value & 0x0F)); + value = ((value >>> 4) & 0x0F) | (regA << 4); + memory.write(hl, (byte) (value & 0xff)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C) | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 18; } int I_RLD() { int hl = (regs[REG_H] << 8) | regs[REG_L]; + int value = memory.read(hl); memptr = (hl + 1) & 0xFFFF; - byte value = memory.read(hl); - - memory.write(hl, (byte)((value << 4) | (regs[REG_A] & 0xF))); - regs[REG_A] = ((regs[REG_A] & 0xF0) | (value >>> 4)) & 0xFF; + int tmp1 = (value >>> 4) & 0x0F; + value = ((value << 4) & 0xF0) | (regs[REG_A] & 0x0F); + regs[REG_A] = ((regs[REG_A] & 0xF0) | tmp1); + memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) (value & 0xff)); flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C) | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 18; } @@ -1125,7 +1150,7 @@ int I_LDDR() { // https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags#interrupted-block-instructions //YF = PC.13 //XF = PC.11 - flags &= 0xD3; // reset P/V, X, Y + flags &= 0xD7; // reset P/V, X, Y flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); return 21; @@ -1156,36 +1181,67 @@ int I_LDI() { int I_LDIR() { int hl = (regs[REG_H] << 8) | regs[REG_L]; - byte t = memory.read(hl++); - int de = (regs[REG_D] << 8) | regs[REG_E]; - memory.write(de++, t); + int bc = (regs[REG_B] << 8) | regs[REG_C]; - regs[REG_H] = (hl >>> 8) & 0xFF; - regs[REG_L] = (hl & 0xFF); - regs[REG_D] = (de >>> 8) & 0xFF; - regs[REG_E] = (de & 0xFF); + int t = memory.read(hl); + memory.write(de, (byte) t); - t += regs[REG_A]; + hl = (hl + 1) & 0xFFFF; + de = (de + 1) & 0xFFFF; + bc = (bc - 1) & 0xFFFF; - int bc = ((regs[REG_B] << 8) | regs[REG_C]) - 1; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_D] = (de >>> 8) & 0xFF; + regs[REG_E] = de & 0xFF; regs[REG_B] = (bc >>> 8) & 0xFF; - regs[REG_C] = (bc & 0xFF); + regs[REG_C] = bc & 0xFF; - if (bc != 0) { - PC = (PC - 2) & 0xFFFF; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | - ((PC >>> 8) & (FLAG_Y | FLAG_X)) | - FLAG_PV; - memptr = PC + 1; - return 21; + int flagP = (bc != 0) ? FLAG_PV : 0; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | flagP; + if (bc == 0) { + t += regs[REG_A]; + flags |= ((t & 2) << 4) // YF = (A + [HLi]).1 + | (t & FLAG_X); + return 16; } - - flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | - ((t & 2) << 4) | /* YF = (A + [HLi]).1 */ - (t & FLAG_X); + PC = (PC - 2) & 0xFFFF; + flags |= ((PC >>> 8) & (FLAG_Y | FLAG_X)); return 21; +// +// int hl = (regs[REG_H] << 8) | regs[REG_L]; +// byte t = memory.read(hl++); +// +// int de = (regs[REG_D] << 8) | regs[REG_E]; +// memory.write(de++, t); +// +// regs[REG_H] = (hl >>> 8) & 0xFF; +// regs[REG_L] = (hl & 0xFF); +// regs[REG_D] = (de >>> 8) & 0xFF; +// regs[REG_E] = (de & 0xFF); +// +// t += regs[REG_A]; +// +// int bc = ((regs[REG_B] << 8) | regs[REG_C]) - 1; +// regs[REG_B] = (bc >>> 8) & 0xFF; +// regs[REG_C] = (bc & 0xFF); +// +// if (bc != 0) { +// PC = (PC - 2) & 0xFFFF; +// flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | +// ((PC >>> 8) & (FLAG_Y | FLAG_X)) | +// FLAG_PV; +// memptr = PC + 1; +// return 21; +// } +// +// flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | +// ((t & 2) << 4) | /* YF = (A + [HLi]).1 */ +// (t & FLAG_X); +// +// return 21; } public static String intToFlags(int flags) { @@ -1436,6 +1492,7 @@ int I_LD_RP_REF_NN() { } int I_JR_CC_N() { + Q = 0; int addr = memory.read(PC); PC = (PC + 1) & 0xFFFF; memptr = PC; @@ -1573,6 +1630,7 @@ int I_CALL_NN() { } int I_LD_R_R() { + Q = 0; int tmp = (lastOpcode >>> 3) & 0x07; int tmp1 = lastOpcode & 0x07; putreg(tmp, getreg(tmp1)); @@ -1914,6 +1972,7 @@ int I_LD_REF_IY_N_N() { } int I_LD_REF_II_N_N(int special) { + Q = 0; byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; byte number = memory.read(PC); diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java index aee0f52e6..13d370000 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java @@ -46,7 +46,7 @@ public void testJP__nn__AND__JP_cc__nn() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsMemoryAddressWord(0) .verifyPC(context -> context.first) - .verifyPair(REG_SP, context -> 0) + .verifyPair(REG_SP, context -> 0xFFFF) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitUnary(3, @@ -67,7 +67,7 @@ public void testNegative_JP_cc__nn() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsMemoryAddressWord(0) .verifyPC(context -> context.PC + 3) - .verifyPair(REG_SP, context -> 0) + .verifyPair(REG_SP, context -> 0xFFFF) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitUnary(3, @@ -240,7 +240,7 @@ public void testNOP() { cpuVerifierImpl.checkRegister(REG_L, 0); cpuVerifierImpl.checkRegisterPair(REG_PAIR_BC, 0); cpuVerifierImpl.checkRegisterPair(REG_PAIR_HL, 0); - cpuVerifierImpl.checkRegisterPair(REG_SP, 0); + cpuVerifierImpl.checkRegisterPair(REG_SP, 0xFFFF); cpuVerifierImpl.checkPC(1); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FlagsTableGeneratorTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FlagsTableGeneratorTest.java deleted file mode 100644 index 2ed715a51..000000000 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FlagsTableGeneratorTest.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.cpu.zilogZ80; - -import org.junit.Ignore; -import org.junit.Test; - -import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.FLAG_C; -import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.FLAG_H; - -@Ignore -public class FlagsTableGeneratorTest { - private final static int MAX_INDENT = 25; - - /** - * Get H flag after DAA - *

- * According to the document: "Undocumented Z80" - * - * @param nf N flag before operation - * @param hf half-carry before operation - * @param value value - * @return 8-bit (H or 0) - */ - public static int daa_hf(boolean nf, boolean hf, byte value) { -// NF HF low HF’ -// 0 * 0-9 0 -// 0 * a-f 1 -// 1 0 * 0 -// 1 1 6-f 0 -// 1 1 0-5 1 - int low = value & 0xF; - if (!nf && low <= 9) { - return 0; - } else if (!nf && low >= 0xA && low <= 0xF) { - return FLAG_H; - } else if (nf && !hf) { - return 0; - } else if (nf && hf && low >= 6 && low <= 0xF) { - return 0; - } else if (nf && hf && low <= 5) { - return FLAG_H; - } - throw new RuntimeException(); - } - - /** - * Get result after DAA plus C flag - *

- * According to the document: "Undocumented Z80" - * - * @param cf carry before operation - * @param hf half-carry before operation - * @param value value - * @return 16 bit value -> higher 8-bit = flags (C or 0), lower 8-bit = result - */ - public static int daa(boolean cf, boolean hf, byte value) { - int high = (value >>> 4) & 0xF; - int low = value & 0xF; - - // cf high hf low diff - // 0 0-9 0 0-9 00 - // 0 0-9 1 0-9 06 - // 0 0-8 * a-f 06 - // 0 a-f 0 0-9 60 - // 1 * 0 0-9 60 - // 1 * 1 0-9 66 - // 1 * * a-f 66 - // 0 9-f * a-f 66 - // 0 a-f 1 0-9 66 - - // CF high low CF’ -// 0 0-9 0-9 0 -// 0 0-8 a-f 0 -// 0 9-f a-f 1 -// 0 a-f 0-9 1 -// 1 * * 1 - - if (!cf && !hf && high <= 9 && low <= 9) { - return 0; - } else if (!cf && hf && high <= 9 && low <= 9) { - return 6; - } else if (!cf && high <= 8 && low >= 0xA && low <= 0xF) { - return 6; - } else if (!cf && !hf && high >= 0xA && high <= 0xF && low <= 9) { - return 0x60 | (FLAG_C << 8); - } else if (cf && !hf && low <= 9) { - return 0x60 | (FLAG_C << 8); - } else if (cf && hf && low <= 9) { - return 0x66 | (FLAG_C << 8); - } else if (cf && low >= 0xA && low <= 0xF) { - return 0x66 | (FLAG_C << 8); - } else if (!cf && high >= 9 && high <= 0xF && low >= 0xA && low <= 0xF) { - return 0x66 | (FLAG_C << 8); - } else if (!cf && hf && high >= 0xA && high <= 0xF && low <= 9) { - return 0x66 | (FLAG_C << 8); - } - throw new RuntimeException(); - } - - private void generateDiffAndC(boolean cf, boolean hf) { - int indent = 0; - - StringBuilder sb = new StringBuilder() - .append("private final static int[] DAA_") - .append(cf ? "C_" : "NOT_C_") - .append(hf ? "H_" : "NOT_H_") - .append("TABLE = new int[] {\n"); - - for (int i = 0; i < 256; i++) { - sb.append(daa(cf, hf, (byte) i)).append(", "); - - if (indent++ > MAX_INDENT) { - sb.append("\n"); - indent = 0; - } - } - sb.append("\n};"); - System.out.println(sb.toString()); - } - - private void generateH(boolean nf, boolean hf) { - int indent = 0; - - StringBuilder sb = new StringBuilder() - .append("private final static int[] DAA_") - .append(nf ? "N_" : "NOT_N_") - .append(hf ? "H_" : "NOT_H_") - .append("FOR_H_TABLE = new int[] {"); - for (int i = 0; i < 256; i++) { - sb.append(daa_hf(nf, hf, (byte) i)).append(", "); - - if (indent++ > MAX_INDENT) { - sb.append("\n"); - indent = 0; - } - } - sb.append("\n};"); - System.out.println(sb.toString()); - } - - @Test - @Ignore - public void testGenerateDAAtable() { - generateDiffAndC(false, false); - generateDiffAndC(false, true); - generateDiffAndC(true, false); - generateDiffAndC(true, true); - - generateH(false, false); - generateH(false, true); - generateH(true, false); - generateH(true, true); - } - -} diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java index 236d8ea76..966dcfc2e 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java @@ -23,7 +23,6 @@ import net.emustudio.plugins.cpu.zilogZ80.suite.ByteTestBuilder; import net.emustudio.plugins.cpu.zilogZ80.suite.FlagsCheckImpl; import net.emustudio.plugins.cpu.zilogZ80.suite.IntegerTestBuilder; -import org.junit.Ignore; import org.junit.Test; import java.util.function.Function; @@ -167,34 +166,65 @@ public void testCP_N() { ); } - // TODO @Test - @Ignore public void testDAA() { - Function, Integer> daaFunc = context -> FlagsTableGeneratorTest.daa( - ((context.flags & FLAG_C) == FLAG_C), - ((context.flags & FLAG_H) == FLAG_H), - (byte) (((int) context.first) & 0xFF) - ); - ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> daaFunc.apply(context) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().parity() - .expectFlagOnlyWhen(FLAG_H, (context, result) -> - FlagsTableGeneratorTest.daa_hf( - (context.flags & FLAG_N) == FLAG_N, - (context.flags & FLAG_H) == FLAG_H, - (byte) (((int) context.first) & 0xFF) - ) == FLAG_H - ) - .expectFlagOnlyWhen(FLAG_C, ((context, result) -> - (daaFunc.apply(context) >>> 8) == FLAG_C)) - ); - - Generator.forAll8bitUnary( - test.run(0x27) - ); + .secondIsFlags() + .keepCurrentInjectorsAfterRun(); + + int[][] params = new int[][]{ + new int[]{0xAA, 0x7D, 0x10, 0x11}, + new int[]{0xAA, 0x7E, 0x44, 0x7}, + new int[]{0xAA, 0x7F, 0x44, 0x7}, + new int[]{0xAD, 0x7E, 0x47, 0x7}, + new int[]{0xAD, 0x7F, 0x47, 0x7}, + new int[]{0xAC, 0x6C, 0x12, 0x15}, + new int[]{0xA6, 0x7E, 0x40, 0x3}, + new int[]{0xA6, 0x7F, 0x40, 0x3}, + new int[]{0xA1, 0x6C, 0x1, 0x1}, + new int[]{0xA1, 0x6D, 0x1, 0x1}, + new int[]{0xB8, 0x6F, 0x58, 0xB}, + new int[]{0xB8, 0x7C, 0x1E, 0xD}, + new int[]{0xB8, 0x7D, 0x1E, 0xD}, + new int[]{0xB8, 0x7E, 0x52, 0x3}, + new int[]{0x95, 0xE4, 0x95, 0x84}, + new int[]{0x95, 0xE5, 0xF5, 0xA5}, + new int[]{0x95, 0xE6, 0x95, 0x86}, + new int[]{0x95, 0xE7, 0x35, 0x27}, + new int[]{0x28, 0xE9, 0x88, 0x8D}, + new int[]{0x28, 0xEA, 0x28, 0x2E}, + new int[]{0x28, 0xEB, 0xC8, 0x8B}, + new int[]{0x28, 0xF8, 0x2E, 0x2C}, + new int[]{0x53, 0xF8, 0x59, 0xC}, + new int[]{0x53, 0xF9, 0xB9, 0xA9}, + new int[]{0x53, 0xFA, 0x4D, 0x1E}, + new int[]{0x53, 0xFB, 0xED, 0xBF}, + new int[]{0xEF, 0xEF, 0x89, 0x8B}, + new int[]{0xEF, 0xFC, 0x55, 0x15}, + new int[]{0xEF, 0xFD, 0x55, 0x15}, + new int[]{0xEF, 0xFE, 0x89, 0x8B}, + new int[]{0x20, 0xFD, 0x86, 0x81}, + new int[]{0x20, 0xFE, 0x1A, 0x1A}, + new int[]{0x20, 0xFF, 0xBA, 0xBB}, + new int[]{0x1C, 0xEF, 0xB6, 0xA3}, + new int[]{0x1C, 0xFC, 0x22, 0x34}, + new int[]{0x1C, 0xFD, 0x82, 0x95}, + new int[]{0x16, 0xFF, 0xB0, 0xA3}, + new int[]{0x11, 0xEC, 0x11, 0x4}, + new int[]{0x11, 0xED, 0x71, 0x25}, + new int[]{0x11, 0xEE, 0x11, 0x6}, + new int[]{0x55, 0xEC, 0x55, 0x4}, + new int[]{0x55, 0xED, 0xB5, 0xA1}, + new int[]{0x55, 0xEE, 0x55, 0x6}, + }; + + for (int[] p : params) { + test.verifyRegister(REG_A, c -> p[2]) + .verifyFlags(new FlagsCheckImpl().exact(p[3]), c -> c.flags) + .run(0x27) + .accept((byte) p[0], (byte) p[1]); + } } @Test @@ -249,9 +279,14 @@ public void testRRCA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .setFlags(FLAG_N | FLAG_H) - .verifyRegister(REG_A, context -> ((context.first >> 1) & 0x7F) | ((context.first & 1) << 7)) + .verifyRegister(REG_A, context -> (((context.first & 0xFF) >>> 1) | (context.first << 7)) & 0xFF) .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsFirstOperandLSB().halfCarryIsReset().subtractionIsReset()); + .signIsPreserved() + .zeroIsPreserved() + .parityIsPreserved() + .carryIsFirstOperandLSB() + .halfCarryIsReset() + .subtractionIsReset()); Generator.forSome8bitUnary( test.run(0x0F) @@ -684,13 +719,6 @@ public void testSRL_R() { @Test public void testSRL_REF_II_N() { - //unsigned res = value; - // unsigned c = (res & 0x01) ? CF : 0; - // res = (res >> 1) & 0xff; - // F = SZP[res] | c; - // return res; - - //B = srl(rm_reg(m_ea)); wm(m_ea, B); IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .verifyByte(context -> get8MSBplus8LSB(context.first), context -> ((context.second & 0xFF) >>> 1) & 0xFF) diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java index 3301a63b4..9dbe763b9 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java @@ -61,6 +61,11 @@ public ByteTestBuilder secondIsRegisterR() { return this; } + public ByteTestBuilder secondIsFlags() { + runner.injectSecond((tmpRunner, argument) -> cpuRunner.setFlags(argument.intValue())); + return this; + } + public ByteTestBuilder firstIsDeviceAndSecondIsPort() { runner.injectTwoOperands((tmpRunner, first, second) -> cpuRunner.getDevice(second.intValue() & 0xFF).setValue(first)); diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java index 302e2176e..43f0e1c1f 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java @@ -60,6 +60,14 @@ public FlagsCheckImpl setSecond8LSB() { return this; } + public FlagsCheckImpl exact(int flags) { + evaluators.add((context, result) -> { + expectedFlags = flags; + expectedNotFlags = flags ^ 0xFF; + }); + return this; + } + public FlagsCheckImpl sign() { evaluators.add((context, result) -> { if ((result & 0x80) == 0x80) { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index 68b03388e..38f97adac 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -89,7 +89,7 @@ public void initialize() throws PluginInitializationException { ); if (device.getDataType() != Byte.class) { throw new PluginInitializationException( - "Unexpected device data type. Expected Short but was: " + device.getDataType() + "Unexpected device data type. Expected Byte but was: " + device.getDataType() ); } keyboard.connect(device); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java index c8fc157b5..2e01ed1d3 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java @@ -28,21 +28,17 @@ public class Cursor { private final int columns; private final int rows; - private final int tabs; private final AtomicReference cursorPoint = new AtomicReference<>(new Point()); interface LineRoller { void rollLine(); - - void clearLine(int x, int y); } public Cursor(int columns, int rows) { this.columns = columns; this.rows = rows; - this.tabs = columns / 4; } int getColumns() { @@ -61,24 +57,6 @@ void set(int x, int y) { cursorPoint.set(new Point(x, y)); } - void printComma(LineRoller lineRoller) { - setCursorPoint(oldPoint -> { - Point newPoint = new Point(oldPoint); - - if (newPoint.x < 16) { - newPoint.x = 16; - } else { - newPoint.x = 0; - newPoint.y++; - if (newPoint.y > (rows - 1)) { - lineRoller.rollLine(); - newPoint.y = (rows - 1); - } - } - return newPoint; - }); - } - void moveForwardsRolling(LineRoller lineRoller) { setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); @@ -108,17 +86,6 @@ void moveForwards() { }); } - void moveForwardsTab() { - setCursorPoint(oldPoint -> { - Point newPoint = new Point(oldPoint); - - if (newPoint.x < (columns - 1)) { - newPoint.x = ((newPoint.x + 4) / 4) * 4; - } - return newPoint; - }); - } - void moveBackwards() { setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); @@ -150,7 +117,6 @@ void moveDown(LineRoller lineRoller) { } else { newPoint.y++; } - lineRoller.clearLine(newPoint.x, newPoint.y); return newPoint; }); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java index eafc0a552..614aac9be 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java @@ -62,7 +62,6 @@ public class Display extends JPanel implements DeviceContext, TerminalSett private final LoadCursorPosition loadCursorPosition; private final Timer cursorTimer = new Timer(800, this); - private volatile DisplayParameters displayParameters; private volatile Dimension size; private FileWriter outputWriter = null; @@ -83,7 +82,7 @@ public Display(Cursor cursor, TerminalSettings settings) { setDoubleBuffered(true); setOpaque(true); setFont(terminalFont); - this.displayParameters = measure(); + DisplayParameters displayParameters = measure(); this.size = new Dimension(displayParameters.maxWidth, displayParameters.maxHeight); if (!settings.isGuiSupported()) { @@ -123,14 +122,12 @@ public final void clearScreen() { public void setBounds(int x, int y, int width, int height) { super.setBounds(x, y, width, height); this.size = getSize(); - this.displayParameters = measure(); } @Override public void setBounds(Rectangle r) { super.setBounds(r); this.size = getSize(); - this.displayParameters = measure(); } @Override @@ -190,16 +187,6 @@ public void rollLine() { repaint(); } - @Override - public void clearLine(int x, int y) { - synchronized (videoMemory) { - for (int i = columns * y + x; i < (columns * y + columns); i++) { - videoMemory[i] = ' '; - } - } - repaint(); - } - /** * This method is called from serial I/O card (by OUT instruction) */ @@ -211,20 +198,12 @@ public void writeData(Byte data) { */ switch (data) { case 5: // HERE IS - // insertHereIs(); - break; - case 6: - // print COMMA - cursor.printComma(this); + insertHereIs(); break; case 7: // BELL return; case 8: // BACKSPACE cursor.moveBackwards(); - drawChar((char) (32)); - break; - case 9: - cursor.moveForwards(); break; case 0x0A: // line feed cursor.moveDown(this); @@ -232,35 +211,22 @@ public void writeData(Byte data) { case 0x0B: // VT cursor.moveUp(); break; - case 0x0C: // delete - drawChar((char)32); + case 0x0C: // FF + cursor.moveForwards(); break; case 0x0D: // CARRIAGE RETURN cursor.carriageReturn(); - cursor.moveDown(this); // TODO break; - case 23: - cursor.moveForwardsTab(); - break; - // case 0x0C: // FF - // cursor.moveForwards(); - // break; - case 0x0E: // SO case 0x0F: // SI return; case 0x1A: // clear screen - //clearScreen(); - cursor.moveDown(this); + clearScreen(); return; case 0x1B: // initiates load cursor operation case 0x1E: // homes cursor - // cursor.home(); + cursor.home(); break; - case 127: - drawChar('\u00a9'); - cursor.moveForwardsRolling(this); - return; } if (loadCursorPosition.notAccepted(data) && data >= 32) { @@ -346,10 +312,10 @@ private void paintCursor(Graphics graphics) { Rectangle2D fontRectangle = terminalFont.getMaxCharBounds(graphics.getFontMetrics().getFontRenderContext()); int lineHeight = graphics.getFontMetrics().getHeight(); - int x = 2 + (int)(paintPoint.x * fontRectangle.getWidth()); + int x = 2 + (int) (paintPoint.x * fontRectangle.getWidth()); int y = 3 + (paintPoint.y * lineHeight); - graphics.fillRect(x, y, (int)fontRectangle.getWidth(), (int)fontRectangle.getHeight()); + graphics.fillRect(x, y, (int) fontRectangle.getWidth(), (int) fontRectangle.getHeight()); graphics.setPaintMode(); cursorShouldBePainted = true; diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java index 0f9356c57..f76a79723 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java @@ -108,7 +108,7 @@ void setCpu(Context8080 cpu) { void reset() { clearCommand(); - COMMANDS_MAP.values().forEach(Command::reset); + COMMANDS_MAP.values().forEach(c -> c.reset(this)); } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java index 1e932b4dd..6fd28bbb6 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java @@ -23,7 +23,7 @@ public class AttachPTP implements Command { private int lastCPMStatus = 0; // result of last attachCPM command @Override - public void reset() { + public void reset(Control control) { lastCPMStatus = 0; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java index 31b05ae64..ee17745e8 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/Command.java @@ -27,7 +27,7 @@ public interface Command { /** * Called on SIMH interface reset */ - default void reset() { + default void reset(Control control) { } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java index 9e44e882f..33f55e8c3 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java @@ -27,7 +27,7 @@ public class GetCPUClockFrequency implements Command { private final AtomicInteger cpuFreq = new AtomicInteger(); @Override - public void reset() { + public void reset(Control control) { getClockFrequencyPos = 0; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java index e53927d9c..ef9779465 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java @@ -42,7 +42,7 @@ public class GetClockCPM3 implements Command { private int daysCPM3SinceOrg = 0; // days since 1 Jan 1978 @Override - public void reset() { + public void reset(Control control) { getClockCPM3Pos = 0; currentTimeValid = false; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java index 99f0a697d..e72b0f554 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java @@ -35,7 +35,7 @@ public class GetClockZSDOS implements Command { private int getClockZSDOSPos = 0; // determines state for sending clock information @Override - public void reset() { + public void reset(Control control) { currentTimeValid = false; getClockZSDOSPos = 0; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java index 28a3ae336..0db983ecc 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java @@ -24,7 +24,7 @@ public class GetCommon implements Command { private int getCommonPos = 0; // determines state for sending the 'common' register @Override - public void reset() { + public void reset(Control control) { getCommonPos = 0; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java index 90e1b82c2..b8f0e62bf 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java @@ -57,7 +57,7 @@ public NameNode(char[] name, NameNode next) { } @Override - public void reset() { + public void reset(Control control) { deleteNameList(); nameListHead = null; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java index 155e677cb..2d9a67e51 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetSimhVersion.java @@ -26,7 +26,7 @@ public class GetSimhVersion implements Command { private int versionPos = 0; // determines state for sending device identifier @Override - public void reset() { + public void reset(Control control) { versionPos = 0; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java index f70e12a2e..84dea967c 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java @@ -27,7 +27,7 @@ public class ReadStopWatch implements Command { @Override - public void reset() { + public void reset(Control control) { getStopWatchDeltaPos = 0; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java index 741d8f3f8..0192803ed 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java @@ -34,7 +34,7 @@ public class ReadURL implements Command { private boolean isInReadPhase; @Override - public void reset() { + public void reset(Control control) { urlPointer = 0; isInReadPhase = false; } @@ -82,7 +82,7 @@ public void write(byte data, Control control) { @Override public void start(Control control) { - reset(); + reset(control); } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java index 25ac2a725..e5fd83e49 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ResetSimhInterface.java @@ -25,7 +25,7 @@ public class ResetSimhInterface implements Command { public void start(Control control) { StartTimer.INS.markTimeSP = 0; control.clearCommand(); - GetHostFilenames.INS.reset(); + GetHostFilenames.INS.reset(control); control.clearCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java index 9000a5135..2564b9b16 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java @@ -18,21 +18,20 @@ */ package net.emustudio.plugins.device.simh.commands; +import net.emustudio.emulib.runtime.helpers.SleepUtils; + public class SIMHSleep implements Command { public final static SIMHSleep INS = new SIMHSleep(); - private final static int SIMHSleepMillis = 1; + private final static int SIMHSleepNanos = 1000000; @Override public void start(Control control) { - // TODO: // Do not sleep when timer interrupts are pending or are about to be created. // Otherwise there is the possibility that such interrupts are skipped. // time to sleep and SIO not attached to a file. - try { - Thread.sleep(SIMHSleepMillis); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); + if (StartTimerInterrupts.INS.callback.get() == null) { + SleepUtils.preciseSleepNanos(SIMHSleepNanos); } control.clearCommand(); } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java index b9809337a..997b61284 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetCPUClockFrequency.java @@ -25,17 +25,17 @@ public class SetCPUClockFrequency implements Command { private int setClockFrequencyPos = 0; // determines state for sending the clock frequency @Override - public void reset() { + public void reset(Control control) { setClockFrequencyPos = 0; } @Override public void write(byte data, Control control) { if (setClockFrequencyPos == 0) { - newClockFrequency = data; + newClockFrequency = data & 0xFF; setClockFrequencyPos = 1; } else { - control.getCpu().setCPUFrequency((data << 8) | newClockFrequency); + control.getCpu().setCPUFrequency(((data << 8) & 0xFF00) | newClockFrequency); setClockFrequencyPos = 0; control.clearCommand(); } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java index 297810157..f9671600a 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java @@ -34,7 +34,7 @@ public class SetClockCPM3 implements Command { private int setClockCPM3Adr = 0; // address in M of 5 byte parameter block for setting time @Override - public void reset() { + public void reset(Control control) { ClockCPM3Delta = 0; setClockCPM3Pos = 0; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java index 905dd70c0..068d1ec52 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java @@ -33,7 +33,7 @@ public class SetClockZSDOS implements Command { public int ClockZSDOSDelta = 0; // delta between real clock and Altair clock @Override - public void reset() { + public void reset(Control control) { ClockZSDOSDelta = 0; setClockZSDOSPos = 0; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java index 664404f1c..8036f4cea 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java @@ -27,17 +27,17 @@ public class SetTimerDelta implements Command { public int timerDelta = DEFAULT_TIMER_DELTA; // interrupt every 100 ms @Override - public void reset() { + public void reset(Control control) { setTimerDeltaPos = 0; } @Override public void write(byte data, Control control) { if (setTimerDeltaPos == 0) { - timerDelta = data; + timerDelta = data & 0xFF; setTimerDeltaPos = 1; } else { - timerDelta |= (data << 8); + timerDelta = (timerDelta | (data << 8)) & 0xFFFF; setTimerDeltaPos = 0; control.clearCommand(); if (timerDelta == 0) { @@ -49,7 +49,7 @@ public void write(byte data, Control control) { @Override public void start(Control control) { - reset(); + reset(control); control.clearReadCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java index 48b34679d..98de73288 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java @@ -25,7 +25,7 @@ public class SetTimerInterruptAdr implements Command { public int timerInterruptHandler = 0x0fc00; // default address of interrupt handling routine @Override - public void reset() { + public void reset(Control control) { setTimerInterruptAdrPos = 0; } @@ -43,7 +43,7 @@ public void write(byte data, Control control) { @Override public void start(Control control) { - reset(); + reset(control); control.clearReadCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java index 4d358dc11..ba3c55bf6 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimer.java @@ -27,7 +27,7 @@ public class StartTimer implements Command { public long[] markTime = new long[TIMER_STACK_LIMIT]; // timer stack @Override - public void reset() { + public void reset(Control control) { markTimeSP = 0; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java index dab400f8b..c38a30a99 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java @@ -18,32 +18,53 @@ */ package net.emustudio.plugins.device.simh.commands; -import java.util.concurrent.*; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; + +import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; public class StartTimerInterrupts implements Command { public final static StartTimerInterrupts INS = new StartTimerInterrupts(); - private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); - public final AtomicReference> timerTask = new AtomicReference<>(); + public final AtomicReference callback = new AtomicReference<>(); @Override - public void reset() { - ScheduledFuture oldTask = timerTask.get(); - if (oldTask != null) { - oldTask.cancel(true); + public void reset(Control control) { + TimerInterruptCallback old = callback.getAndSet(null); + if (old != null) { + control.getCpu().unregisterRunCallback(old); } } @Override public void start(Control control) { - reset(); - timerTask.set(executor.scheduleAtFixedRate(() -> { - // will work only in interrupt mode 0 - int addr = SetTimerInterruptAdr.INS.timerInterruptHandler; - byte b1 = (byte) (addr & 0xFF); - byte b2 = (byte) (addr >>> 8); - control.getCpu().signalInterrupt(new byte[]{(byte) 0xCD, b1, b2}); - }, SetTimerDelta.INS.timerDelta, SetTimerDelta.INS.timerDelta, TimeUnit.MILLISECONDS)); + reset(control); + TimerInterruptCallback cb = new TimerInterruptCallback(control.getCpu()); + callback.set(cb); + control.getCpu().registerRunCallback(cb); control.clearCommand(); } + + private static class TimerInterruptCallback implements Runnable { + private volatile long startTime = System.nanoTime(); + private final Context8080 cpu; + + private TimerInterruptCallback(Context8080 cpu) { + this.cpu = Objects.requireNonNull(cpu); + } + + @Override + public void run() { + long endTime = System.nanoTime(); + long elapsed = endTime - startTime; + + if (elapsed >= (SetTimerDelta.INS.timerDelta * 1000000L)) { + startTime = endTime; + // will work only in interrupt mode 0 + int addr = SetTimerInterruptAdr.INS.timerInterruptHandler; + byte b1 = (byte) (addr & 0xFF); + byte b2 = (byte) (addr >>> 8); + cpu.signalInterrupt(new byte[]{(byte) 0xCD, b1, b2}); + } + } + } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java index f0f0c27d7..c56c7f021 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StopTimerInterrupts.java @@ -23,7 +23,7 @@ public class StopTimerInterrupts implements Command { @Override public void start(Control control) { - StartTimerInterrupts.INS.reset(); + StartTimerInterrupts.INS.reset(control); control.clearCommand(); } } diff --git a/plugins/device/zxspectrum-display/build.gradle b/plugins/device/zxspectrum-display/build.gradle new file mode 100644 index 000000000..c852898f2 --- /dev/null +++ b/plugins/device/zxspectrum-display/build.gradle @@ -0,0 +1,55 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import org.apache.tools.ant.filters.ReplaceTokens + +plugins { + id 'java' + id 'com.adarshr.test-logger' version '3.1.0' +} + +dependencies { + implementation libs.emuLib + implementation libs.slf4JApi + implementation libs.jcipAnnotations + + testImplementation libs.junit + testImplementation libs.slf4JSimple + testImplementation libs.easyMock +} + +jar { + archiveVersion = '' + manifest { + attributes manifestAttributes('') + } +} + +processResources { + filesMatching("**/*.properties") { + filter ReplaceTokens, tokens: [ + "project.version": project.version, + "today.year": new Date().format("yyyy") + ] + } +} + +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = 'UTF-8' +javadoc.options.encoding = 'UTF-8' diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java new file mode 100644 index 000000000..3154624fa --- /dev/null +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java @@ -0,0 +1,129 @@ +package net.emustudio.plugins.device.zxspectrum.display; + +import net.emustudio.emulib.plugins.PluginInitializationException; +import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; +import net.emustudio.emulib.plugins.annotations.PluginRoot; +import net.emustudio.emulib.plugins.device.AbstractDevice; +import net.emustudio.emulib.plugins.device.DeviceContext; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; +import net.emustudio.emulib.runtime.ContextNotFoundException; +import net.emustudio.emulib.runtime.InvalidContextException; +import net.emustudio.emulib.runtime.settings.PluginSettings; +import net.emustudio.plugins.device.zxspectrum.display.io.Keyboard; +import net.emustudio.plugins.device.zxspectrum.display.io.OutputProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.*; +import java.io.IOException; +import java.util.MissingResourceException; +import java.util.Optional; +import java.util.ResourceBundle; + +@PluginRoot(type = PLUGIN_TYPE.DEVICE, title = "ZX Spectrum Display") +public class DeviceImpl extends AbstractDevice { + private static final Logger LOGGER = LoggerFactory.getLogger(DeviceImpl.class); + + private final boolean guiSupported; + private final ZxSpectrumDisplayContext terminal = new ZxSpectrumDisplayContext(); + private final Keyboard keyboard = new Keyboard(); + private boolean guiIOset = false; + + public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { + super(pluginID, applicationApi, settings); + + this.guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); + try { + applicationApi.getContextPool().register(pluginID, terminal, DeviceContext.class); + } catch (InvalidContextException | ContextAlreadyRegisteredException e) { + LOGGER.error("Could not register BrainTerminal context", e); + applicationApi.getDialogs().showError("Could not register BrainDuck terminal. Please see log file for more details.", getTitle()); + } + } + + @Override + public void initialize() throws PluginInitializationException { + // try to connect to a serial I/O board + try { + DeviceContext device = applicationApi.getContextPool().getDeviceContext(pluginID, DeviceContext.class); + if (device.getDataType() != Byte.class) { + throw new PluginInitializationException( + "Unexpected device data type. Expected Byte but was: " + device.getDataType() + ); + } + keyboard.connect(device); + } catch (ContextNotFoundException e) { + LOGGER.warn("The terminal is not connected to any I/O device."); + } + } + + @Override + public void reset() { + terminal.reset(); + } + + @Override + public void destroy() { + try { + terminal.close(); + } catch (IOException e) { + LOGGER.error("Could not close io provider", e); + } + } + + @Override + public void showSettings(JFrame jFrame) { + // we don't have settings GUI + } + + @Override + public boolean isShowSettingsSupported() { + return false; + } + + @Override + public void showGUI(JFrame parent) { + if (guiSupported) { + if (!guiIOset) { + LOGGER.debug("Creating GUI-based keyboard"); + + OutputProvider outputProvider = ZxSpectrumDisplayGui.create(parent, keyboard, applicationApi.getDialogs()); + terminal.setOutputProvider(outputProvider); + guiIOset = true; + } + + terminal.showGUI(); + } + } + + @Override + public boolean isGuiSupported() { + return guiSupported; + } + + + @Override + public String getVersion() { + return getResourceBundle().map(b -> b.getString("version")).orElse("(unknown)"); + } + + @Override + public String getCopyright() { + return getResourceBundle().map(b -> b.getString("copyright")).orElse("(unknown)"); + } + + @Override + public String getDescription() { + return "BrainDuck terminal device"; + } + + + private Optional getResourceBundle() { + try { + return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.device.zxspectrum.display.version")); + } catch (MissingResourceException e) { + return Optional.empty(); + } + } +} diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayContext.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayContext.java new file mode 100644 index 000000000..cb761c9ea --- /dev/null +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayContext.java @@ -0,0 +1,60 @@ +package net.emustudio.plugins.device.zxspectrum.display; + + +import net.emustudio.emulib.plugins.device.DeviceContext; +import net.emustudio.plugins.device.zxspectrum.display.io.IOProvider; +import net.emustudio.plugins.device.zxspectrum.display.io.OutputProvider; +import net.jcip.annotations.ThreadSafe; + +import java.io.IOException; +import java.util.Objects; + +@ThreadSafe +class ZxSpectrumDisplayContext implements DeviceContext, IOProvider { + private volatile OutputProvider outputProvider = OutputProvider.DUMMY; + + void setOutputProvider(OutputProvider outputProvider) { + this.outputProvider = Objects.requireNonNull(outputProvider); + } + + @Override + public Byte readData() { + return 0; + } + + @Override + public void writeData(Byte data) { + OutputProvider tmpOutputProvider = outputProvider; + if (tmpOutputProvider != null) { + tmpOutputProvider.write(data & 0xFF); + } + } + + @Override + public Class getDataType() { + return Byte.class; + } + + @Override + public void reset() { + OutputProvider tmpOutputProvider = outputProvider; + if (tmpOutputProvider != null) { + tmpOutputProvider.reset(); + } + } + + @Override + public void close() throws IOException { + OutputProvider tmpOutputProvider = outputProvider; + if (tmpOutputProvider != null) { + tmpOutputProvider.close(); + } + } + + void showGUI() { + OutputProvider tmpOutputProvider = outputProvider; + if (tmpOutputProvider != null) { + tmpOutputProvider.showGUI(); + } + } +} diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java new file mode 100644 index 000000000..cbcd09fec --- /dev/null +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java @@ -0,0 +1,258 @@ +package net.emustudio.plugins.device.zxspectrum.display; + +import net.emustudio.emulib.runtime.helpers.RadixUtils; +import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.plugins.device.zxspectrum.display.io.*; + +import javax.swing.*; +import java.awt.event.KeyEvent; +import java.net.URL; +import java.util.Objects; +import java.util.StringTokenizer; + +class ZxSpectrumDisplayGui extends JDialog implements OutputProvider, Keyboard.KeyboardListener { + private final Dialogs dialogs; + + private final ImageIcon blueIcon; + private final ImageIcon redIcon; + + private final Display canvas; + private final Keyboard keyboard; + + private ZxSpectrumDisplayGui(JFrame parent, Keyboard keyboard, Dialogs dialogs) { + super(parent); + this.dialogs = Objects.requireNonNull(dialogs); + + URL blueIconURL = getClass().getResource( + "/net/emustudio/plugins/device/zxspectrum/display/16_circle_blue.png" + ); + URL redIconURL = getClass().getResource( + "/net/emustudio/plugins/device/zxspectrum/display/16_circle_red.png" + ); + + blueIcon = new ImageIcon(Objects.requireNonNull(blueIconURL)); + redIcon = new ImageIcon(Objects.requireNonNull(redIconURL)); + + this.keyboard = keyboard; + + setTitle("BrainDuck Terminal"); + initComponents(); + setLocationRelativeTo(parent); + + canvas = new Display(); + scrollPane.setViewportView(canvas); + canvas.start(); + } + + @Override + public void readEnded() { + lblStatusIcon.setIcon(blueIcon); + lblStatusIcon.repaint(); + btnASCII.setEnabled(false); + } + + @Override + public void reset() { + canvas.clearScreen(); + } + + @Override + public void write(int character) { + writeStarted(); + Cursor cursor = canvas.getTextCanvasCursor(); + switch (character) { + case 5: // HERE IS + // insertHereIs(); + break; + case 6: + // print COMMA + cursor.printComma(canvas); + break; + case 7: // BELL + break; + case 8: // BACKSPACE + cursor.moveBackwards(); + canvas.writeAtCursor(' '); + break; + case 9: + cursor.moveForwards(); + break; + case 0x0A: // line feed + case 0x1A: // clear screen + //clearScreen(); + cursor.moveDown(canvas); + break; + case 0x0B: // VT + cursor.moveUp(); + break; + case 0x0C: // delete + canvas.writeAtCursor(' '); + break; + case 0x0D: // CARRIAGE RETURN + cursor.carriageReturn(); + cursor.moveDown(canvas); // TODO + break; + + case 0x17: // 23 + cursor.moveForwardsTab(); + break; + + case 0x16: + // AT +// ignore = true; +// ignorec = 0; + break; + + case 0x0E: // SO + case 0x0F: // SI + break; + case 0x1B: // initiates load cursor operation + case 0x1E: // homes cursor + // cursor.home(); + break; + case 127: + canvas.writeAtCursor('\u00a9'); + cursor.moveForwardsRolling(canvas); + break; + + case 0x1C: + canvas.clearScreen(); + break; + + case 0x82: + canvas.writeAtCursor('\u2590'); + return; + case 0x83: + canvas.writeAtCursor('\u2580'); + return; + case 0x85: + canvas.writeAtCursor('\u2599'); + return; + case 0x86: + canvas.writeAtCursor('\u259C'); + return; + case 0x89: + case 0x8C: + case 0x8A: + canvas.writeAtCursor(' '); // Ᾱ0 + return; + case 0xDE: + canvas.writeAtCursor('*'); + return; + } + + if (character >= 32) { + canvas.writeAtCursor((char) character); + cursor.moveForwardsRolling(canvas); + } + repaint(); + } + + @Override + public void showGUI() { + this.setVisible(true); + } + + @Override + public void close() { + canvas.stop(); + GUIUtils.removeListenerRecursively(this, keyboard); + dispose(); + } + + + static ZxSpectrumDisplayGui create(JFrame parent, Keyboard keyboard, Dialogs dialogs) { + ZxSpectrumDisplayGui dialog = new ZxSpectrumDisplayGui(parent, keyboard, dialogs); + GUIUtils.addListenerRecursively(dialog, dialog.keyboard); + return dialog; + } + + private void writeStarted() { + lblStatusIcon.setIcon(redIcon); + lblStatusIcon.repaint(); + } + + /** + * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The + * content of this method is always regenerated by the Form Editor. + */ + private void initComponents() { + + javax.swing.JPanel panelStatus = new javax.swing.JPanel(); + lblStatusIcon = new javax.swing.JLabel(); + btnASCII = new javax.swing.JButton(); + scrollPane = new javax.swing.JScrollPane(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + lblStatusIcon.setIcon(blueIcon); + lblStatusIcon.setToolTipText("Waiting for input? (red - yes, blue - no)"); + lblStatusIcon.setVerticalAlignment(javax.swing.SwingConstants.TOP); + + btnASCII.setFont(btnASCII.getFont()); + btnASCII.setIcon(new javax.swing.ImageIcon(getClass().getResource("/net/emustudio/plugins/device/zxspectrum/display/16_ascii.png"))); + btnASCII.setToolTipText("Input by ASCII code"); + btnASCII.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + btnASCII.setEnabled(false); + btnASCII.setVerticalAlignment(javax.swing.SwingConstants.TOP); + btnASCII.addActionListener(this::btnASCIIActionPerformed); + + javax.swing.GroupLayout panelStatusLayout = new javax.swing.GroupLayout(panelStatus); + panelStatus.setLayout(panelStatusLayout); + panelStatusLayout.setHorizontalGroup( + panelStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelStatusLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblStatusIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnASCII) + .addContainerGap(664, Short.MAX_VALUE)) + ); + panelStatusLayout.setVerticalGroup( + panelStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lblStatusIcon, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnASCII, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE) + ); + + scrollPane.setBackground(new java.awt.Color(255, 255, 255)); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(panelStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(scrollPane) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 407, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + + pack(); + } + + private void btnASCIIActionPerformed(java.awt.event.ActionEvent evt) { + dialogs + .readString("Enter ASCII codes separated with spaces:", "Add ASCII codes") + .ifPresent(asciiCodes -> { + StringTokenizer tokenizer = new StringTokenizer(asciiCodes); + + RadixUtils radixUtils = RadixUtils.getInstance(); + try { + while (tokenizer.hasMoreTokens()) { + int ascii = radixUtils.parseRadix(tokenizer.nextToken()); + keyboard.keyPressed(new KeyEvent(this, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, ascii, (char) ascii)); + } + } catch (NumberFormatException ex) { + dialogs.showError("Invalid number format in the input: " + ex.getMessage(), "Add ASCII codes"); + } + }); + } + + private javax.swing.JButton btnASCII; + private javax.swing.JLabel lblStatusIcon; + private javax.swing.JScrollPane scrollPane; +} diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Cursor.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Cursor.java new file mode 100644 index 000000000..1cdce416f --- /dev/null +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Cursor.java @@ -0,0 +1,153 @@ +package net.emustudio.plugins.device.zxspectrum.display.io; + +import net.jcip.annotations.ThreadSafe; + +import java.awt.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; + +@ThreadSafe +public class Cursor { + private final int columns; + private final int rows; + private final int tabs; + + private final AtomicReference cursorPoint = new AtomicReference<>(new Point()); + + public Cursor(int columns, int rows) { + this.columns = columns; + this.rows = rows; + this.tabs = columns / 4; + } + + public int getColumns() { + return columns; + } + + public int getRows() { + return rows; + } + + public void home() { + cursorPoint.set(new Point()); + } + + public void set(int x, int y) { + cursorPoint.set(new Point(x, y)); + } + + public void printComma(LineRoller lineRoller) { + setCursorPoint(oldPoint -> { + Point newPoint = new Point(oldPoint); + + if (newPoint.x < 16) { + newPoint.x = 16; + } else { + newPoint.x = 0; + newPoint.y++; + if (newPoint.y > (rows - 1)) { + lineRoller.rollLine(); + newPoint.y = (rows - 1); + } + } + return newPoint; + }); + } + + public void moveForwardsRolling(LineRoller lineRoller) { + setCursorPoint(oldPoint -> { + Point newPoint = new Point(oldPoint); + + newPoint.x++; + if (newPoint.x > (columns - 1)) { + newPoint.x = 0; + newPoint.y++; + // automatic line rolling + if (newPoint.y > (rows - 1)) { + lineRoller.rollLine(); + newPoint.y = (rows - 1); + } + } + return newPoint; + }); + } + + public void moveForwards() { + setCursorPoint(oldPoint -> { + Point newPoint = new Point(oldPoint); + + if (newPoint.x < (columns - 1)) { + newPoint.x++; + } + return newPoint; + }); + } + + public void moveForwardsTab() { + setCursorPoint(oldPoint -> { + Point newPoint = new Point(oldPoint); + + if (newPoint.x < (columns - 1)) { + newPoint.x = ((newPoint.x + 4) / 4) * 4; + } + return newPoint; + }); + } + + public void moveBackwards() { + setCursorPoint(oldPoint -> { + Point newPoint = new Point(oldPoint); + + if (newPoint.x > 0) { + newPoint.x--; + } + return newPoint; + }); + } + + public void moveUp() { + setCursorPoint(oldPoint -> { + Point newPoint = new Point(oldPoint); + + if (newPoint.y > 0) { + newPoint.y--; + } + return newPoint; + }); + } + + public void moveDown(LineRoller lineRoller) { + setCursorPoint(oldPoint -> { + Point newPoint = new Point(oldPoint); + + if (newPoint.y == (rows - 1)) { + lineRoller.rollLine(); + } else { + newPoint.y++; + } + lineRoller.clearLine(newPoint.x, newPoint.y); + return newPoint; + }); + } + + + public void carriageReturn() { + setCursorPoint(oldPoint -> { + Point newPoint = new Point(oldPoint); + newPoint.x = 0; + return newPoint; + }); + } + + Point getCursorPoint() { + return cursorPoint.get(); + } + + private void setCursorPoint(Function changer) { + Point oldPoint = cursorPoint.get(); + Point newPoint; + do { + newPoint = changer.apply(oldPoint); + } while (!cursorPoint.compareAndSet(oldPoint, newPoint)); + } +} diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java new file mode 100644 index 000000000..6c47ea69b --- /dev/null +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java @@ -0,0 +1,217 @@ +package net.emustudio.plugins.device.zxspectrum.display.io; + +import net.jcip.annotations.ThreadSafe; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.font.FontRenderContext; +import java.awt.font.LineMetrics; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.util.Arrays; + +@ThreadSafe +public class Display extends JPanel implements LineRoller, ActionListener { + private final static int DEFAULT_COLUMNS = 120; + static final Color FOREGROUND = new Color(0, 255, 0); + static final Color BACKGROUND = Color.BLACK; + private final Font terminalFont = new Font("Monospaced", Font.PLAIN, 14); + + private final char[] videoMemory; + private final int columns; + private final int rows; + + private final Cursor cursor; + private volatile boolean cursorShouldBePainted; + private final Timer cursorTimer = new Timer(800, this); + + private volatile Dimension size; + + public Display() { + this.rows = 80; + this.columns = DEFAULT_COLUMNS; + this.videoMemory = new char[rows * columns]; + this.cursor = new Cursor(columns, rows); + + this.setBackground(java.awt.Color.WHITE); + this.setForeground(java.awt.Color.BLACK); + + this.setFont(terminalFont); + this.setDoubleBuffered(true); + DisplayParameters displayParameters = measure(); + this.size = new Dimension(displayParameters.maxWidth, displayParameters.maxHeight); + } + + public synchronized void start() { + cursorTimer.restart(); + } + + public synchronized void stop() { + cursorTimer.stop(); + } + + @Override + public void setBounds(int x, int y, int width, int height) { + super.setBounds(x, y, width, height); + this.size = getSize(); + } + + @Override + public void setBounds(Rectangle r) { + super.setBounds(r); + this.size = getSize(); + } + + @Override + public Dimension getPreferredSize() { + return this.size; + } + + @Override + public Dimension getMinimumSize() { + return this.size; + } + + + public final void clearScreen() { + fillWithSpaces(); + cursor.home(); + repaint(); + } + + public Cursor getTextCanvasCursor() { + return cursor; + } + + public void writeAtCursor(char c) { + Point cursorPoint = cursor.getCursorPoint(); + writeCharAt(c, cursorPoint.x, cursorPoint.y); + } + + public void writeCharAt(char c, int x, int y) { + synchronized (videoMemory) { + videoMemory[y * columns + x] = c; + } + repaint(); + } + + @Override + public void rollLine() { + synchronized (videoMemory) { + System.arraycopy(videoMemory, columns, videoMemory, 0, columns * rows - columns); + for (int i = columns * rows - columns; i < (columns * rows); i++) { + videoMemory[i] = ' '; + } + } + repaint(); + } + + @Override + public void clearLine(int x, int y) { + synchronized (videoMemory) { + for (int i = columns * y + x; i < (columns * y + columns); i++) { + videoMemory[i] = ' '; + } + } + repaint(); + } + + @Override + public void paintComponent(Graphics graphics) { + Dimension dimension = size; + graphics.setColor(BACKGROUND); + graphics.fillRect(0, 0, dimension.width, dimension.height); + + int t_y; + int x, y; + int temp; + StringBuilder sLine = new StringBuilder(); + + int lineHeight = graphics.getFontMetrics().getHeight(); + graphics.setColor(FOREGROUND); + Graphics2D g2d = (Graphics2D) graphics; + for (y = 0; y < rows; y++) { + t_y = (y + 1) * lineHeight; + temp = y * columns; + for (x = 0; x < columns; x++) { + synchronized (videoMemory) { + sLine.append(videoMemory[temp + x]); + } + } + g2d.drawString(sLine.toString(), 1, t_y); + sLine = new StringBuilder(); + } + + paintCursor(graphics); + } + + private void fillWithSpaces() { + synchronized (videoMemory) { + Arrays.fill(videoMemory, ' '); + } + } + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getSource() != null && e.getSource() == cursorTimer) { + repaint(); + } + } + + private void paintCursor(Graphics graphics) { + if (!cursorShouldBePainted) { + Point paintPoint = cursor.getCursorPoint(); + + graphics.setXORMode(Display.BACKGROUND); + graphics.setColor(Display.FOREGROUND); + + Rectangle2D fontRectangle = terminalFont.getMaxCharBounds(graphics.getFontMetrics().getFontRenderContext()); + int lineHeight = graphics.getFontMetrics().getHeight(); + + int x = 2 + (int)(paintPoint.x * fontRectangle.getWidth()); + int y = 3 + (paintPoint.y * lineHeight); + + graphics.fillRect(x, y, (int)fontRectangle.getWidth(), (int)fontRectangle.getHeight()); + graphics.setPaintMode(); + + cursorShouldBePainted = true; + } else { + cursorShouldBePainted = false; + } + } + + private DisplayParameters measure() { + Font font = getFont(); + Rectangle2D metrics = font.getStringBounds("W", getDefaultFrc()); + LineMetrics lineMetrics = font.getLineMetrics("W", getDefaultFrc()); + + int charWidth = (int) metrics.getWidth(); + int charHeight = (int) lineMetrics.getHeight(); + + int maxWidth = columns * charWidth; + int maxHeight = rows * charHeight; + + return new DisplayParameters(maxWidth, maxHeight); + } + + private static FontRenderContext DEFAULT_FRC; + + public static FontRenderContext getDefaultFrc() { + if (DEFAULT_FRC == null) { + AffineTransform tx; + if (GraphicsEnvironment.isHeadless()) { + tx = new AffineTransform(); + } else { + tx = GraphicsEnvironment + .getLocalGraphicsEnvironment() + .getDefaultScreenDevice() + .getDefaultConfiguration() + .getDefaultTransform(); + } + DEFAULT_FRC = new FontRenderContext(tx, false, false); + } + return DEFAULT_FRC; + } +} diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/DisplayParameters.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/DisplayParameters.java new file mode 100644 index 000000000..9cf56bfa4 --- /dev/null +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/DisplayParameters.java @@ -0,0 +1,14 @@ +package net.emustudio.plugins.device.zxspectrum.display.io; + +import net.jcip.annotations.Immutable; + +@Immutable +class DisplayParameters { + final int maxWidth; + final int maxHeight; + + DisplayParameters(int maxWidth, int maxHeight) { + this.maxWidth = maxWidth; + this.maxHeight = maxHeight; + } +} diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/GUIUtils.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/GUIUtils.java new file mode 100644 index 000000000..0e6cf2ec4 --- /dev/null +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/GUIUtils.java @@ -0,0 +1,30 @@ +package net.emustudio.plugins.device.zxspectrum.display.io; + +import java.awt.*; +import java.awt.event.KeyListener; + +public class GUIUtils { + + public static void addListenerRecursively(Component c, KeyListener listener) { + c.addKeyListener(listener); + if (c instanceof Container) { + Container cont = (Container) c; + Component[] children = cont.getComponents(); + for (Component child : children) { + addListenerRecursively(child, listener); + } + } + } + + public static void removeListenerRecursively(Component c, KeyListener listener) { + c.removeKeyListener(listener); + if (c instanceof Container) { + Container cont = (Container) c; + Component[] children = cont.getComponents(); + for (Component child : children) { + removeListenerRecursively(child, listener); + } + } + } + +} diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/IOProvider.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/IOProvider.java new file mode 100644 index 000000000..8db2ec83a --- /dev/null +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/IOProvider.java @@ -0,0 +1,9 @@ +package net.emustudio.plugins.device.zxspectrum.display.io; + +import java.io.Closeable; + +public interface IOProvider extends Closeable { + int EOF = 0; + + void reset(); +} diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java new file mode 100644 index 000000000..8b4d5fac3 --- /dev/null +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java @@ -0,0 +1,49 @@ +package net.emustudio.plugins.device.zxspectrum.display.io; + +import net.emustudio.emulib.plugins.device.DeviceContext; +import net.jcip.annotations.ThreadSafe; + +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.util.ArrayList; +import java.util.List; + +@ThreadSafe +public class Keyboard implements KeyListener { + private final List> devices = new ArrayList<>(); + + @ThreadSafe + public interface KeyboardListener { + + void readEnded(); + } + + public void connect(DeviceContext device) { + devices.add(device); + } + + @Override + public void keyTyped(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + int keycode = e.getKeyCode(); + if (!((keycode == KeyEvent.VK_SHIFT || keycode == KeyEvent.VK_CONTROL || + keycode == KeyEvent.VK_ALT || keycode == KeyEvent.VK_META))) { + keycode = (e.getKeyChar() & 0xFF); + } + inputReceived((byte) keycode); + } + + @Override + public void keyReleased(KeyEvent e) { + + } + + private void inputReceived(int input) { + for (DeviceContext device : devices) { + device.writeData((byte) input); + } + } +} diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/LineRoller.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/LineRoller.java new file mode 100644 index 000000000..1e774b836 --- /dev/null +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/LineRoller.java @@ -0,0 +1,8 @@ +package net.emustudio.plugins.device.zxspectrum.display.io; + +interface LineRoller { + + void rollLine(); + + void clearLine(int x, int y); +} diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/OutputProvider.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/OutputProvider.java new file mode 100644 index 000000000..7674d1fb9 --- /dev/null +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/OutputProvider.java @@ -0,0 +1,27 @@ +package net.emustudio.plugins.device.zxspectrum.display.io; + +public interface OutputProvider extends IOProvider { + OutputProvider DUMMY = new OutputProvider() { + + @Override + public void write(int character) { + } + + @Override + public void reset() { + } + + @Override + public void close() { + } + + @Override + public void showGUI() { + } + }; + + void write(int character); + + void showGUI(); + +} diff --git a/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_ascii.png b/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_ascii.png new file mode 100644 index 0000000000000000000000000000000000000000..0fa4dc0d64f11a9c55830cfa0702014d44ba3de6 GIT binary patch literal 415 zcmV;Q0bu@#P)DlTA(nK@dh?mE42{BOHPi z0Yf;4F)=Zc5My+$3k(S>?%_`edJP4+OqYx9uAb4zg4uLWP0dSvUsVY}HCmXc0s^9l z#Jh;3n0O4pa}iED!?}qF80m-j`FuWaK(v%(d~aq{!?{DYZ&!53ONV^DT+o}W8jw~bgAkIg zUuOt($4hS^7`@4g+&QJ85%%vlDbJ`zPwdv$#S;e?Pt+`$l@mIHhm!aQQu8Z8G+si2 z;FV-gsJ-X2Zfq+WAdMfhgwEiR{l_iUa1J7zo-Np|r|yXX((d0INSbfr%=<2An&Gq` zwVlZOpt*%vW07Oti9^GtrR?J%0?_W?CE>#Va`I{yIs45_egI>@OVZbCp{M`=002ov JPDHLkV1nEntxo^| literal 0 HcmV?d00001 diff --git a/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_circle_blue.png b/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_circle_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..97567bd79c4d1b6dcf2bcd91ca38c007d16102fa GIT binary patch literal 473 zcmV;~0Ve*5P)9v5Zo@wo}(4MIi4Oy=s%j`|L$ zdTA>U`+JO$FB_p3=lp_pbRSIhK>Dw08vnk{=X(^eEe2P&njGbwLm_N)OUS1m* z5BjoSGV&=#xo~yW9Ml59|8K<&$qkdot1Aa-3YZebwnG{ literal 0 HcmV?d00001 diff --git a/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_circle_green.png b/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_circle_green.png new file mode 100644 index 0000000000000000000000000000000000000000..6de9e949d06966c1c3650cc1365c94e24fccb306 GIT binary patch literal 461 zcmV;;0W$uHP))p9 zj510g5`v8A5`hwQu|LTAgX+?yE_>;aw;<3%8fz?CCnFO4?KE#>Wp-RI`Cyhe-}~P8 z-n@MV=N$7K19O_?Igbx_zCg8YbM?Nxc*fLwHkbDc=!vP#6P)f}N$lzM7A0ql>q3^E zoQ!91oVpb68==>4N&ILphfMMU&!u~mYc^L!raCy>Jx8bigApIfA(1i0U@%k0%C%zf z45)e{mPWhV#9-8w9jL~b0m}%3I2G6CS>)MN2M37^x}y3lfuRr}PQ`r*oOFwxL!SQkvxJYq~p3VZ`=NBe*z2unOC^S0k+Kl00000NkvXXu0mjf D2l&WP literal 0 HcmV?d00001 diff --git a/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_circle_red.png b/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/16_circle_red.png new file mode 100644 index 0000000000000000000000000000000000000000..32ddd9d937bc848537229d308b77cfb1379f85db GIT binary patch literal 436 zcmV;l0ZaagP)J<#vxmuE}AKec-%LAA)QfB<79B@WXhV$l^I71zcQh zwcz&q!1W4*IapNVIPfMD_|vJ7{Heh0c7fdvxLizvY*unikh%lu-e>^ZE$KW1x0}hF z$q=Xj#>hDBo|RDGHk-iV0Gv+1{caN2^kBuJVEp+!sX)$R0j$@+ey?_5XeDU54Ako; zuYU2COCXn1U`tzexJ1qgCXIkLJMvd6)umJd@_ALn#y-a=#~8+@DHw{1%?7B|fJ#M? zv9V7v$!XZc2%>@{e$Qs`jz={w8T%aLoZda{9}Ec~4n5VYjHHpryQhAn2oMp). +# + +version=@project.version@ +copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/settings.gradle b/settings.gradle index 7f2a49c2c..bb10f6039 100644 --- a/settings.gradle +++ b/settings.gradle @@ -49,6 +49,7 @@ include ':plugins:device:adm3A-terminal' include ':plugins:device:brainduck-terminal' include ':plugins:device:simh-pseudo' include ':plugins:device:ssem-display' +include ':plugins:device:zxspectrum-display' include ':plugins:memory:ram-mem' include ':plugins:memory:rasp-mem' From 0205019f86f4359223ba034b51c234c256069382 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 28 Aug 2022 19:05:14 +0100 Subject: [PATCH 198/314] [#260] zx spectrum display --- .../src/main/files/config/ZxSpectrum.toml | 8 - .../display/ZxSpectrumDisplayGui.java | 137 ++++++++++-------- .../device/zxspectrum/display/io/Cursor.java | 28 +--- .../device/zxspectrum/display/io/Display.java | 8 +- .../display/io/DisplayParameters.java | 4 +- .../zxspectrum/display/io/IOProvider.java | 2 - .../zxspectrum/display/io/Keyboard.java | 6 - 7 files changed, 85 insertions(+), 108 deletions(-) diff --git a/application/src/main/files/config/ZxSpectrum.toml b/application/src/main/files/config/ZxSpectrum.toml index 44cf59bef..98a802bc8 100644 --- a/application/src/main/files/config/ZxSpectrum.toml +++ b/application/src/main/files/config/ZxSpectrum.toml @@ -127,14 +127,6 @@ halfDuplex = false outputFileName = "adm3A-terminal.out" inputFileName = "adm3A-terminal.in" -[[DEVICE]] -schemaPoint = "220,60" -path = "simh-pseudo.jar" -settings = {} -name = "simh-pseudo" -id = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" -type = "DEVICE" - [[connections]] bidirectional = true from = "9233e0c2-b53c-41e7-9eca-bbb264fcd9da" diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java index cbcd09fec..a1120cc60 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java @@ -10,7 +10,7 @@ import java.util.Objects; import java.util.StringTokenizer; -class ZxSpectrumDisplayGui extends JDialog implements OutputProvider, Keyboard.KeyboardListener { +class ZxSpectrumDisplayGui extends JDialog implements OutputProvider { private final Dialogs dialogs; private final ImageIcon blueIcon; @@ -35,7 +35,7 @@ private ZxSpectrumDisplayGui(JFrame parent, Keyboard keyboard, Dialogs dialogs) this.keyboard = keyboard; - setTitle("BrainDuck Terminal"); + setTitle("ZX Spectrum Terminal"); initComponents(); setLocationRelativeTo(parent); @@ -44,42 +44,68 @@ private ZxSpectrumDisplayGui(JFrame parent, Keyboard keyboard, Dialogs dialogs) canvas.start(); } - @Override - public void readEnded() { - lblStatusIcon.setIcon(blueIcon); - lblStatusIcon.repaint(); - btnASCII.setEnabled(false); - } - @Override public void reset() { canvas.clearScreen(); } + boolean ignoreNext = false; + int ignoreCount = 0; + + boolean sposx = false; + boolean sposy = false; + int posX = 0; + int posY = 0; + @Override public void write(int character) { + if (ignoreNext && (ignoreCount++) < 2) { + return; + } + ignoreCount = 0; + ignoreNext = false; + writeStarted(); Cursor cursor = canvas.getTextCanvasCursor(); + + if (sposx) { + posX = character; + sposx = false; + sposy = true; + return; + } + if (sposy) { + posY = character; + sposy = false; + cursor.set(posX, posY); + return; + } + + switch (character) { case 5: // HERE IS // insertHereIs(); break; case 6: // print COMMA - cursor.printComma(canvas); + int x = cursor.getCursorPoint().x; + int y = cursor.getCursorPoint().y; + cursor.moveForwardsTab(); + int x1 = cursor.getCursorPoint().x; + for (; x < x1; x++) { + canvas.writeCharAt(' ', x, y); + } break; case 7: // BELL + canvas.writeAtCursor('?'); break; case 8: // BACKSPACE cursor.moveBackwards(); - canvas.writeAtCursor(' '); break; case 9: cursor.moveForwards(); break; case 0x0A: // line feed - case 0x1A: // clear screen - //clearScreen(); cursor.moveDown(canvas); break; case 0x0B: // VT @@ -90,35 +116,28 @@ public void write(int character) { break; case 0x0D: // CARRIAGE RETURN cursor.carriageReturn(); - cursor.moveDown(canvas); // TODO + cursor.moveDown(canvas); + break; + case 0x10: // INK CONTROL + case 0x11: // PAPER CONTROL + case 0x12: // FLASH CONTROL + case 0x13: // BRIGHT CONTROL + case 0x14: // INVERSE CONTROL + case 0x15: // OVER CONTROL + ignoreNext = true; + break; + case 0x16: // AT CONTROL + sposx = true; break; - case 0x17: // 23 cursor.moveForwardsTab(); break; - case 0x16: - // AT -// ignore = true; -// ignorec = 0; - break; - - case 0x0E: // SO - case 0x0F: // SI - break; - case 0x1B: // initiates load cursor operation - case 0x1E: // homes cursor - // cursor.home(); - break; case 127: canvas.writeAtCursor('\u00a9'); cursor.moveForwardsRolling(canvas); break; - case 0x1C: - canvas.clearScreen(); - break; - case 0x82: canvas.writeAtCursor('\u2590'); return; @@ -177,58 +196,57 @@ private void writeStarted() { * content of this method is always regenerated by the Form Editor. */ private void initComponents() { + JPanel panelStatus = new JPanel(); + lblStatusIcon = new JLabel(); + JButton btnASCII = new JButton(); + scrollPane = new JScrollPane(); - javax.swing.JPanel panelStatus = new javax.swing.JPanel(); - lblStatusIcon = new javax.swing.JLabel(); - btnASCII = new javax.swing.JButton(); - scrollPane = new javax.swing.JScrollPane(); - - setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); lblStatusIcon.setIcon(blueIcon); lblStatusIcon.setToolTipText("Waiting for input? (red - yes, blue - no)"); - lblStatusIcon.setVerticalAlignment(javax.swing.SwingConstants.TOP); + lblStatusIcon.setVerticalAlignment(SwingConstants.TOP); btnASCII.setFont(btnASCII.getFont()); - btnASCII.setIcon(new javax.swing.ImageIcon(getClass().getResource("/net/emustudio/plugins/device/zxspectrum/display/16_ascii.png"))); + btnASCII.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/device/zxspectrum/display/16_ascii.png"))); btnASCII.setToolTipText("Input by ASCII code"); - btnASCII.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + btnASCII.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); btnASCII.setEnabled(false); - btnASCII.setVerticalAlignment(javax.swing.SwingConstants.TOP); + btnASCII.setVerticalAlignment(SwingConstants.TOP); btnASCII.addActionListener(this::btnASCIIActionPerformed); - javax.swing.GroupLayout panelStatusLayout = new javax.swing.GroupLayout(panelStatus); + GroupLayout panelStatusLayout = new GroupLayout(panelStatus); panelStatus.setLayout(panelStatusLayout); panelStatusLayout.setHorizontalGroup( - panelStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + panelStatusLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelStatusLayout.createSequentialGroup() .addContainerGap() - .addComponent(lblStatusIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblStatusIcon, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnASCII) - .addContainerGap(664, Short.MAX_VALUE)) + .addContainerGap(1000, Short.MAX_VALUE)) ); panelStatusLayout.setVerticalGroup( - panelStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lblStatusIcon, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnASCII, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE) + panelStatusLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblStatusIcon, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnASCII, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE) ); scrollPane.setBackground(new java.awt.Color(255, 255, 255)); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(panelStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(panelStatus, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(scrollPane) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 407, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelStatus, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) ); pack(); @@ -252,7 +270,6 @@ private void btnASCIIActionPerformed(java.awt.event.ActionEvent evt) { }); } - private javax.swing.JButton btnASCII; - private javax.swing.JLabel lblStatusIcon; - private javax.swing.JScrollPane scrollPane; + private JLabel lblStatusIcon; + private JScrollPane scrollPane; } diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Cursor.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Cursor.java index 1cdce416f..06af8d683 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Cursor.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Cursor.java @@ -20,14 +20,6 @@ public Cursor(int columns, int rows) { this.tabs = columns / 4; } - public int getColumns() { - return columns; - } - - public int getRows() { - return rows; - } - public void home() { cursorPoint.set(new Point()); } @@ -36,24 +28,6 @@ public void set(int x, int y) { cursorPoint.set(new Point(x, y)); } - public void printComma(LineRoller lineRoller) { - setCursorPoint(oldPoint -> { - Point newPoint = new Point(oldPoint); - - if (newPoint.x < 16) { - newPoint.x = 16; - } else { - newPoint.x = 0; - newPoint.y++; - if (newPoint.y > (rows - 1)) { - lineRoller.rollLine(); - newPoint.y = (rows - 1); - } - } - return newPoint; - }); - } - public void moveForwardsRolling(LineRoller lineRoller) { setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); @@ -139,7 +113,7 @@ public void carriageReturn() { }); } - Point getCursorPoint() { + public Point getCursorPoint() { return cursorPoint.get(); } diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java index 6c47ea69b..4e821c01c 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java @@ -15,7 +15,7 @@ @ThreadSafe public class Display extends JPanel implements LineRoller, ActionListener { private final static int DEFAULT_COLUMNS = 120; - static final Color FOREGROUND = new Color(0, 255, 0); + static final Color FOREGROUND = new Color(255, 255, 255); static final Color BACKGROUND = Color.BLACK; private final Font terminalFont = new Font("Monospaced", Font.PLAIN, 14); @@ -30,7 +30,7 @@ public class Display extends JPanel implements LineRoller, ActionListener { private volatile Dimension size; public Display() { - this.rows = 80; + this.rows = 24; this.columns = DEFAULT_COLUMNS; this.videoMemory = new char[rows * columns]; this.cursor = new Cursor(columns, rows); @@ -167,7 +167,7 @@ private void paintCursor(Graphics graphics) { graphics.setXORMode(Display.BACKGROUND); graphics.setColor(Display.FOREGROUND); - Rectangle2D fontRectangle = terminalFont.getMaxCharBounds(graphics.getFontMetrics().getFontRenderContext()); + Rectangle2D fontRectangle = terminalFont.getStringBounds("W", getDefaultFrc()); int lineHeight = graphics.getFontMetrics().getHeight(); int x = 2 + (int)(paintPoint.x * fontRectangle.getWidth()); @@ -193,7 +193,7 @@ private DisplayParameters measure() { int maxWidth = columns * charWidth; int maxHeight = rows * charHeight; - return new DisplayParameters(maxWidth, maxHeight); + return new DisplayParameters(maxWidth, maxHeight, charWidth); } private static FontRenderContext DEFAULT_FRC; diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/DisplayParameters.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/DisplayParameters.java index 9cf56bfa4..3635b9740 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/DisplayParameters.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/DisplayParameters.java @@ -6,9 +6,11 @@ class DisplayParameters { final int maxWidth; final int maxHeight; + final int charWidth; - DisplayParameters(int maxWidth, int maxHeight) { + DisplayParameters(int maxWidth, int maxHeight, int charWidth) { this.maxWidth = maxWidth; this.maxHeight = maxHeight; + this.charWidth = charWidth; } } diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/IOProvider.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/IOProvider.java index 8db2ec83a..68a04a26f 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/IOProvider.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/IOProvider.java @@ -3,7 +3,5 @@ import java.io.Closeable; public interface IOProvider extends Closeable { - int EOF = 0; - void reset(); } diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java index 8b4d5fac3..cfa5d89e8 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java @@ -12,12 +12,6 @@ public class Keyboard implements KeyListener { private final List> devices = new ArrayList<>(); - @ThreadSafe - public interface KeyboardListener { - - void readEnded(); - } - public void connect(DeviceContext device) { devices.add(device); } From 1a5b807bee2feb0116b6160c94076a1b250fb75d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 29 Aug 2022 03:04:52 +0100 Subject: [PATCH 199/314] [#260] z80: Fixed CP instructions --- .../application/gui/schema/Schema.java | 8 +++--- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 24 +++++++++-------- .../plugins/device/mits88sio/UART.java | 6 ++--- .../plugins/device/mits88sio/gui/SioGui.java | 6 ++--- .../display/ZxSpectrumDisplayGui.java | 27 +++++++++++-------- 5 files changed, 40 insertions(+), 31 deletions(-) diff --git a/application/src/main/java/net/emustudio/application/gui/schema/Schema.java b/application/src/main/java/net/emustudio/application/gui/schema/Schema.java index acc4bcdc5..f7193fd6b 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/Schema.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/Schema.java @@ -476,9 +476,11 @@ private void load() throws NumberFormatException, NullPointerException { Element from = elements.get(c.getFromPluginId()); Element to = elements.get(c.getToPluginId()); - List

points = c.getSchemaPoints().stream().map(P::of).collect(Collectors.toList()); - ConnectionLine line = new ConnectionLine(from, to, points, c.isBidirectional()); - lines.add(line); + if (from != null && to != null) { + List

points = c.getSchemaPoints().stream().map(P::of).collect(Collectors.toList()); + ConnectionLine line = new ConnectionLine(from, to, points, c.isBidirectional()); + lines.add(line); + } }); } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 3f8d59782..a46cb255c 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -629,7 +629,8 @@ int I_CP_R() { int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | (result & (FLAG_X | FLAG_Y)); + // F5 and F3 flags are set from the subtrahend instead of from the result. + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | (value & (FLAG_X | FLAG_Y)); return (lastOpcode == 0xBE) ? 7 : 4; } @@ -640,7 +641,8 @@ int I_CP_N() { int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; - flags = (TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA])) | (result & (FLAG_X | FLAG_Y)); + // F5 and F3 flags are set from the subtrahend instead of from the result. + flags = (TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA])) | (value & (FLAG_X | FLAG_Y)); return 7; } @@ -2036,7 +2038,7 @@ int I_ADD_A_REF_II_N(int special) { int oldA = regs[REG_A]; int sum = (oldA + value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 19; } @@ -2058,7 +2060,7 @@ int I_ADC_A_REF_II_N(int special) { int oldA = regs[REG_A]; int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 19; } @@ -2081,7 +2083,7 @@ int I_SUB_REF_II_N(int special) { int sum = (oldA - value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 19; } @@ -2104,7 +2106,7 @@ int I_SBC_A_REF_II_N(int special) { int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA]; + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 19; } @@ -2123,7 +2125,7 @@ int I_AND_REF_II_N(int special) { memptr = address; int value = memory.read(address); regs[REG_A] = (regs[REG_A] & value) & 0xFF; - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H; + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 19; } @@ -2142,7 +2144,7 @@ int I_XOR_REF_II_N(int special) { memptr = address; byte value = memory.read(address); regs[REG_A] = ((regs[REG_A] ^ value) & 0xff); - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]]; + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 19; } @@ -2161,7 +2163,7 @@ int I_OR_REF_II_N(int special) { memptr = address; byte value = memory.read(address); regs[REG_A] = ((regs[REG_A] | value) & 0xff); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]]; + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 19; } @@ -2182,7 +2184,7 @@ int I_CP_REF_II_N(int special) { int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]); + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | (value & (FLAG_X | FLAG_Y)); return 19; } @@ -2850,7 +2852,7 @@ int I_CP(int value) { int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | (sum & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | (value & (FLAG_X | FLAG_Y)); return 8; } } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java index 21dc73723..60feb6750 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java @@ -155,7 +155,7 @@ public void sendToDevice(byte data) { } public byte readBuffer() { - int newData = 0; + byte newData = 0; boolean isNotEmpty = false; int newStatus = statusRegister; // what to do.. @@ -197,7 +197,7 @@ private void notifyStatusChanged(int status) { observers.forEach(o -> o.statusChanged(status)); } - private void notifyNewData(int data) { + private void notifyNewData(byte data) { observers.forEach(o -> o.dataAvailable(data)); } @@ -208,7 +208,7 @@ private void notifyNoData() { public interface Observer { void statusChanged(int status); - void dataAvailable(int data); + void dataAvailable(byte data); void noData(); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java index 90bf516af..eabb0ed28 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java @@ -41,9 +41,9 @@ public void statusChanged(int status) { } @Override - public void dataAvailable(int data) { - txtData.setText(String.format("0x%X", data)); - txtDataDisplay.setText(String.valueOf((byte)(data & 0xFF))); + public void dataAvailable(byte data) { + txtData.setText(String.format("0x%X", data & 0xFF)); + txtDataDisplay.setText(String.valueOf(data)); } @Override diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java index a1120cc60..ef885c9b5 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java @@ -59,25 +59,24 @@ public void reset() { @Override public void write(int character) { - if (ignoreNext && (ignoreCount++) < 2) { + if (ignoreNext && (--ignoreCount) > 0) { return; } - ignoreCount = 0; ignoreNext = false; writeStarted(); Cursor cursor = canvas.getTextCanvasCursor(); - if (sposx) { - posX = character; - sposx = false; - sposy = true; - return; - } if (sposy) { posY = character; sposy = false; - cursor.set(posX, posY); + sposx = true; + return; + } + if (sposx) { + posX = character; + sposx = false; + // cursor.set(posX, posY); return; } @@ -124,12 +123,15 @@ public void write(int character) { case 0x13: // BRIGHT CONTROL case 0x14: // INVERSE CONTROL case 0x15: // OVER CONTROL + ignoreCount = 1; ignoreNext = true; break; case 0x16: // AT CONTROL - sposx = true; + sposy = true; break; case 0x17: // 23 + ignoreCount = 1; + ignoreNext = true; cursor.moveForwardsTab(); break; @@ -158,9 +160,12 @@ public void write(int character) { case 0xDE: canvas.writeAtCursor('*'); return; + case 0xFB: + canvas.clearScreen(); + return; } - if (character >= 32) { + if (character >= 32 && character <= 0x7F) { canvas.writeAtCursor((char) character); cursor.moveForwardsRolling(canvas); } From 093f70552759b10abb756eac64524d1c0e741b00 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 5 Sep 2022 19:38:38 +0200 Subject: [PATCH 200/314] [#260] Fixed some more instructions --- .../as-z80/src/main/examples/zexall_boot.asm | 43 +++ .../plugins/cpu/zilogZ80/EmulatorEngine.java | 270 ++++++++---------- .../plugins/memory/bytemem/gui/MemoryGui.java | 2 +- .../bytemem/gui/model/MemoryTableModel.java | 13 +- 4 files changed, 172 insertions(+), 156 deletions(-) create mode 100644 plugins/compiler/as-z80/src/main/examples/zexall_boot.asm diff --git a/plugins/compiler/as-z80/src/main/examples/zexall_boot.asm b/plugins/compiler/as-z80/src/main/examples/zexall_boot.asm new file mode 100644 index 000000000..c85e8576c --- /dev/null +++ b/plugins/compiler/as-z80/src/main/examples/zexall_boot.asm @@ -0,0 +1,43 @@ +; ZEXALL / ZEXDOC tests +; simulation of some BDOS calls +; +; load zexall.com / zexdoc.com at location 0x100 into memory +; then compile this code +; set program address to 0x100 +; start emulation + +di +halt + +; bdos simulation +org 5 +push af +push de + +ld a, 2 +cp c ; print char +jp nz, str +ld a, e +out (0x11), a +jp exit + + +str: +ld a, 9 +cp c ; print string +jp nz, exit + +putstr: +ld a, (de) +inc de + +cp '$' +jp z, exit + +out (11h), a +jp putstr + +exit: +pop de +pop af +ret diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index a46cb255c..cc176f70e 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -168,7 +168,7 @@ public CPU.RunState run(CPU cpu) { // in 10 milliseconds = 10 / 0.00025 = 40000 t-states are executed uncontrollably // in 1 millisecond = 1 / 0.00025 = 4000 t-states :( - int checkTimeSlice = (int)Math.ceil(SleepUtils.SLEEP_PRECISION / 1000000.0); // milliseconds + int checkTimeSlice = (int) Math.ceil(SleepUtils.SLEEP_PRECISION / 1000000.0); // milliseconds int cycles_to_execute = checkTimeSlice * context.getCPUFrequency(); int cycles; long slice = checkTimeSlice * 1000000L; // nanoseconds @@ -720,43 +720,47 @@ int I_RRA() { } int I_DAA() { - // https://github.com/redcode/Z80/blob/master/sources/Z80.c - boolean cf = regs[REG_A] > 0x99; - int t = (((flags & FLAG_H) == FLAG_H) || (regs[REG_A] & 0xF) > 9) ? 6 : 0; + // The following algorithm is from comp.sys.sinclair's FAQ. + int c, d; - if (((flags & FLAG_C) == FLAG_C) || cf) { - t |= 0x60; + int a = regs[REG_A]; + if (a > 0x99 || ((flags & FLAG_C) != 0)) { + c = FLAG_C; + d = 0x60; + } else { + c = d = 0; } - t = (((flags & FLAG_N) == FLAG_N) ? regs[REG_A] - t : regs[REG_A] + t) & 0xFF; - flags = (flags & (FLAG_N | FLAG_C)) - | TABLE_SZ[t] - | (t & (FLAG_Y | FLAG_X)) - | ((regs[REG_A] ^ t) & FLAG_H) - | PARITY_TABLE[t] - | (cf ? FLAG_C : 0); + if ((a & 0x0f) > 0x09 || ((flags & FLAG_H) != 0)) { + d += 0x06; + } - regs[REG_A] = t; + regs[REG_A] = ((flags & FLAG_N) != 0 ? regs[REG_A] - d : regs[REG_A] + d) & 0xFF; + flags = TABLE_SZ[regs[REG_A]] + | PARITY_TABLE[regs[REG_A]] + | (regs[REG_A] & (FLAG_X | FLAG_Y)) + | ((regs[REG_A] ^ a) & FLAG_H) + | (flags & FLAG_N) + | c; return 4; } int I_CPL() { - regs[REG_A] ^= 0xFF; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV | FLAG_C)) | FLAG_H | FLAG_N | (regs[REG_A] & (FLAG_X | FLAG_Y)); + regs[REG_A] = (~regs[REG_A]) & 0xFF; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV | FLAG_C)) + | FLAG_H | FLAG_N + | (regs[REG_A] & (FLAG_X | FLAG_Y)); return 4; } int I_SCF() { - flags = (flags & (FLAG_S | FLAG_Z | FLAG_Y | FLAG_X | FLAG_PV)) | FLAG_C; + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | (regs[REG_A] & (FLAG_X | FLAG_Y)) | FLAG_C; return 4; } int I_CCF() { - /* Zilog: YF = A.5 | (YFi ^ YQi); XF = A.3 | (XFi ^ XQi) */ int c = flags & FLAG_C; - int h = flags & FLAG_H; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) - | (h ^ FLAG_H) // (c << FLAG_H) + flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | (c << 4) | (regs[REG_A] & (FLAG_X | FLAG_Y)) | (c ^ FLAG_C); return 4; @@ -830,6 +834,8 @@ int I_LD_SP_HL() { } int I_EI() { + // https://www.smspower.org/forums/2511-LDILDIRLDDLDDRCRCInZEXALL + // TODO: interrupts are not actually allowed until after the *next* instruction after EI. This is used to prevent interrupts from occuring between an EI/RETI pair used at the end of interrupt handlers. IFF[0] = IFF[1] = true; return 4; } @@ -983,135 +989,122 @@ int I_OUT_REF_C_0() { } int I_CPI() { - int hl = (regs[REG_H] << 8) | regs[REG_L]; - int bc = (regs[REG_B] << 8) | regs[REG_C]; + int a, n, z, f, hl, bc; + a = regs[REG_A]; + hl = (regs[REG_H] << 8) | regs[REG_L]; + bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; + + n = memory.read(hl) & 0xFF; + z = a - n; - int value = memory.read(hl) & 0xFF; hl = (hl + 1) & 0xFFFF; - bc = (bc - 1) & 0xFFFF; - memptr = (memptr + 1) & 0xFFFF; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - int sum = (regs[REG_A] - value) & 0xFF; - int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; - int flagP = (bc != 0) ? FLAG_PV : 0; - flags = TABLE_SUB[sum] | flagH | flagP | (flags & FLAG_C); + f = (a ^ n ^ z) & FLAG_H; - if ((flags & FLAG_H) == FLAG_H) { - sum = (sum - 1) & 0xFF; - } - if ((sum & 0x02) != 0) { - flags |= FLAG_Y; - } - if ((sum & 0x08) != 0) { - flags |= FLAG_X; - } - if (bc != 0) { - flags |= FLAG_PV; - } + n = z - (f >> 4); + f |= (n << 4) & FLAG_Y; + f |= n & FLAG_X; + + f |= TABLE_SZ[z & 0xFF]; + f |= (bc != 0) ? FLAG_PV : 0; + flags = f | FLAG_N | (flags & FLAG_C); return 16; } int I_CPIR() { - int hl = (regs[REG_H] << 8) | regs[REG_L]; int bc = (regs[REG_B] << 8) | regs[REG_C]; - int value = memory.read(hl) & 0xFF; + int hl = (regs[REG_H] << 8) | regs[REG_L]; - if (bc == 1 || regs[REG_A] == value) { - memptr = (memptr + 1) & 0xFFFF; - } else { - memptr = (PC - 1) & 0xFFFF; - } + int n = memory.read(hl) & 0xFF; + int z = regs[REG_A] - n; hl = (hl + 1) & 0xFFFF; - bc = (bc - 1) & 0xFFFF; - - int sum = (regs[REG_A] - value) & 0xFF; - int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; - int flagP = (bc != 0) ? FLAG_PV : 0; - flags = TABLE_SUB[sum] | flagH | flagP | (flags & FLAG_C); + int cycles; + if ((--bc) != 0 && (z != 0)) { + cycles = 21; + PC = (PC - 2) & 0xFFFF; + } else { + cycles = 16; + } regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - if ((bc == 0) || (regs[REG_A] == value)) { - return 16; - } - PC = (PC - 2) & 0xFFFF; - - flags &= 0xD3; // reset P/V, X, Y - flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + int f = (regs[REG_A] ^ n ^ z) & FLAG_H; + n = z - (f >>> 4); + f |= ((n << 4) & FLAG_Y); + f |= (n & FLAG_X); + f |= TABLE_SZ[z & 0xFF]; + f |= (bc != 0) ? FLAG_PV : 0; - return 21; + flags = f | FLAG_N | (flags & FLAG_C); + return cycles; } int I_CPD() { + int a = regs[REG_A]; int hl = (regs[REG_H] << 8) | regs[REG_L]; - int bc = (regs[REG_B] << 8) | regs[REG_C]; + int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; - int value = memory.read(hl) & 0xFF; + int n = memory.read(hl) & 0xFF; hl = (hl - 1) & 0xFFFF; - bc = (bc - 1) & 0xFFFF; - memptr = (memptr - 1) & 0xFFFF; - int sum = (regs[REG_A] - value) & 0xFF; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; - int flagP = (bc != 0) ? FLAG_PV : 0; - flags = TABLE_SUB[sum] | flagH | flagP | (flags & FLAG_C); - if ((flags & FLAG_H) == FLAG_H) { - sum = (sum - 1) & 0xFF; - } - if ((sum & 0x02) != 0) { - flags |= FLAG_Y; - } - if ((sum & 0x08) != 0) { - flags |= FLAG_X; - } + int z = a - n; + int f = (a ^ n ^ z) & FLAG_H; + + n = z - (f >> 4); + f |= (n << 4) & FLAG_Y; + f |= n & FLAG_X; + + f |= TABLE_SZ[z & 0xFF]; + f |= (bc != 0) ? FLAG_PV : 0; + flags = f | FLAG_N | (flags & FLAG_C); return 16; } int I_CPDR() { - int hl = (regs[REG_H] << 8) | regs[REG_L]; + int a = regs[REG_A]; int bc = (regs[REG_B] << 8) | regs[REG_C]; - int value = memory.read(hl) & 0xFF; + int hl = (regs[REG_H] << 8) | regs[REG_L]; - if (bc == 1 || regs[REG_A] == value) { - memptr = (memptr - 1) & 0xFFFF; - } else { - memptr = (PC - 1) & 0xFFFF; - } + int n = memory.read(hl) & 0xFF; + int z = a - n; hl = (hl - 1) & 0xFFFF; - bc = (bc - 1) & 0xFFFF; - - int sum = (regs[REG_A] - value) & 0xFF; - int flagH = (sum ^ regs[REG_A] ^ value) & FLAG_H; - int flagP = (bc != 0) ? FLAG_PV : 0; - flags = TABLE_SUB[sum] | flagH | flagP | (flags & FLAG_C); + int cycles; + if ((--bc) != 0 && (z != 0)) { + cycles = 21; + PC = (PC - 2) & 0xFFFF; + } else { + cycles = 16; + } regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - if ((bc == 0) || (regs[REG_A] == value)) { - return 16; - } - PC = (PC - 2) & 0xFFFF; - flags &= 0xD3; // reset P/V, X, Y - flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); - return 21; + int f = (a ^ n ^ z) & FLAG_H; + n = z - (f >>> 4); + f |= ((n << 4) & FLAG_Y); + f |= (n & FLAG_X); + f |= TABLE_SZ[z & 0xFF]; + f |= (bc != 0) ? FLAG_PV : 0; + + flags = f | FLAG_N | (flags & FLAG_C); + return cycles; } int I_LDD() { @@ -1165,7 +1158,7 @@ int I_LDI() { byte io = memory.read(hl++); memory.write(de++, io); - int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; + int bc = ((((regs[REG_B] << 8) | regs[REG_C]) & 0xFFFF) - 1) & 0xFFFF; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; @@ -1174,7 +1167,7 @@ int I_LDI() { regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - int result = regs[REG_A] + io; + int result = regs[REG_A] + (io & 0xFF); flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); @@ -1182,16 +1175,33 @@ int I_LDI() { } int I_LDIR() { - int hl = (regs[REG_H] << 8) | regs[REG_L]; - int de = (regs[REG_D] << 8) | regs[REG_E]; + int f = flags & (FLAG_S | FLAG_Z | FLAG_C); int bc = (regs[REG_B] << 8) | regs[REG_C]; + int de = (regs[REG_D] << 8) | regs[REG_E]; + int hl = (regs[REG_H] << 8) | regs[REG_L]; - int t = memory.read(hl); - memory.write(de, (byte) t); + if (bc != 1) { + memptr = (PC + 1) & 0xFFFF; + } + + int n = memory.read(hl) & 0xFF; + memory.write(de, (byte) n); hl = (hl + 1) & 0xFFFF; de = (de + 1) & 0xFFFF; - bc = (bc - 1) & 0xFFFF; + + int cycles; + if ((--bc) != 0) { + cycles = 21; + f |= FLAG_PV; + f |= ((PC >>> 8) & (FLAG_Y | FLAG_X)); + PC = (PC - 2) & 0xFFFF; + } else { + cycles = 16; + n += regs[REG_A]; + f |= n & FLAG_X; + f |= ((n << 4) & FLAG_Y); + } regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; @@ -1200,50 +1210,8 @@ int I_LDIR() { regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - int flagP = (bc != 0) ? FLAG_PV : 0; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | flagP; - if (bc == 0) { - t += regs[REG_A]; - flags |= ((t & 2) << 4) // YF = (A + [HLi]).1 - | (t & FLAG_X); - return 16; - } - PC = (PC - 2) & 0xFFFF; - flags |= ((PC >>> 8) & (FLAG_Y | FLAG_X)); - - return 21; -// -// int hl = (regs[REG_H] << 8) | regs[REG_L]; -// byte t = memory.read(hl++); -// -// int de = (regs[REG_D] << 8) | regs[REG_E]; -// memory.write(de++, t); -// -// regs[REG_H] = (hl >>> 8) & 0xFF; -// regs[REG_L] = (hl & 0xFF); -// regs[REG_D] = (de >>> 8) & 0xFF; -// regs[REG_E] = (de & 0xFF); -// -// t += regs[REG_A]; -// -// int bc = ((regs[REG_B] << 8) | regs[REG_C]) - 1; -// regs[REG_B] = (bc >>> 8) & 0xFF; -// regs[REG_C] = (bc & 0xFF); -// -// if (bc != 0) { -// PC = (PC - 2) & 0xFFFF; -// flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | -// ((PC >>> 8) & (FLAG_Y | FLAG_X)) | -// FLAG_PV; -// memptr = PC + 1; -// return 21; -// } -// -// flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | -// ((t & 2) << 4) | /* YF = (A + [HLi]).1 */ -// (t & FLAG_X); -// -// return 21; + flags = f; + return cycles; } public static String intToFlags(int flags) { diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java index 59e7e8d1b..64d2e0ac1 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java @@ -444,7 +444,7 @@ private void initComponents() { private void btnLoadImageActionPerformed(ActionEvent evt) { dialogs.chooseFile( "Load memory image", "Load", Path.of(System.getProperty("user.dir")), false, - new FileExtensionsFilter("Memory image", "hex", "bin") + new FileExtensionsFilter("Memory image", "hex", "bin", "com", "out") ).ifPresent(path -> { try { final int bank = (context.getBanksCount() > 1) diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java index 8c4a52688..6eca9f5e6 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java @@ -19,12 +19,15 @@ package net.emustudio.plugins.memory.bytemem.gui.model; import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.swing.table.AbstractTableModel; import java.util.Objects; import java.util.Optional; public class MemoryTableModel extends AbstractTableModel { + private final static Logger LOGGER = LoggerFactory.getLogger(MemoryTableModel.class); private static final int ROW_COUNT = 16; private static final int COLUMN_COUNT = 16; @@ -70,7 +73,7 @@ public void setAsciiMode(boolean asciiMode) { @Override public Object getValueAt(int rowIndex, int columnIndex) { int value = getRawValueAt(rowIndex, columnIndex); - return asciiMode ? (char)value : String.format("%02X", value); + return asciiMode ? (char) value : String.format("%02X", value); } public int getRawValueAt(int rowIndex, int columnIndex) { @@ -82,13 +85,15 @@ public int getRawValueAt(int rowIndex, int columnIndex) { } @Override - public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + public void setValueAt(Object value, int rowIndex, int columnIndex) { int address = toAddress(rowIndex, columnIndex); try { - memory.writeBank(address, Byte.decode(String.valueOf(aValue)), currentBank); + memory.writeBank(address, (byte) (Integer.decode(String.valueOf(value)) & 0xFF), currentBank); fireTableCellUpdated(rowIndex, columnIndex); } catch (NumberFormatException e) { - // ignored + LOGGER.error( + "Could not set memory cell at address 0x" + Integer.toHexString(address) + " to value " + value, e + ); } } From 83765a0a0d742501758afc06942bd0f135706036 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 6 Sep 2022 12:01:54 +0200 Subject: [PATCH 201/314] [#269] byte-mem: improve select address UI --- .../plugins/memory/bytemem/gui/Constants.java | 10 +- .../bytemem/gui/FindSequenceDialog.java | 3 +- .../plugins/memory/bytemem/gui/MemoryGui.java | 47 ++++--- .../bytemem/gui/SelectBankAddressDialog.java | 124 ++++++++++++++++++ .../memory/bytemem/gui/SettingsDialog.java | 48 +++---- .../memory/bytemem/gui/model/TableMemory.java | 10 +- 6 files changed, 190 insertions(+), 52 deletions(-) create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java index 797202248..8486f39ff 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java @@ -18,9 +18,15 @@ */ package net.emustudio.plugins.memory.bytemem.gui; +import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; + import java.awt.*; + public class Constants { - public static Font MONOSPACED_PLAIN = new Font(Font.MONOSPACED, Font.PLAIN, 12); - public static Font MONOSPACED_BOLD = new Font(Font.MONOSPACED, Font.BOLD, 12); + public final static Font MEMORY_CELLS_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 12); + + public final static FileExtensionsFilter IMAGE_EXTENSION_FILTER = new FileExtensionsFilter( + "Memory image", "hex", "bin", "com", "out" + ); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java index e664a37fc..a29567510 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java @@ -141,8 +141,7 @@ private void initComponents() { .addGap(0, 0, Short.MAX_VALUE) .addComponent(btnFind, GroupLayout.PREFERRED_SIZE, 92, GroupLayout.PREFERRED_SIZE)) .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) - ); + .addContainerGap())); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java index 64d2e0ac1..ce17f219d 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java @@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory; import javax.swing.*; +import java.awt.*; import java.awt.event.*; import java.io.*; import java.nio.file.Path; @@ -36,6 +37,7 @@ import java.util.concurrent.atomic.AtomicInteger; import static net.emustudio.emulib.runtime.helpers.RadixUtils.formatBinaryString; +import static net.emustudio.plugins.memory.bytemem.gui.Constants.IMAGE_EXTENSION_FILTER; public class MemoryGui extends JDialog { private final static Logger LOGGER = LoggerFactory.getLogger(MemoryGui.class); @@ -156,7 +158,7 @@ private void initComponents() { getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); setTitle("Byte Operating Memory"); - setSize(new java.awt.Dimension(794, 629)); + setSize(new Dimension(794, 629)); toolBar.setFloatable(false); toolBar.setRollover(true); @@ -443,27 +445,34 @@ private void initComponents() { private void btnLoadImageActionPerformed(ActionEvent evt) { dialogs.chooseFile( - "Load memory image", "Load", Path.of(System.getProperty("user.dir")), false, - new FileExtensionsFilter("Memory image", "hex", "bin", "com", "out") + "Load memory image", "Load", Path.of(System.getProperty("user.dir")), false, IMAGE_EXTENSION_FILTER ).ifPresent(path -> { - try { - final int bank = (context.getBanksCount() > 1) - ? dialogs.readInteger("Enter memory bank index:", "Load image", 0).orElse(0) - : 0; - - if (path.toString().toLowerCase().endsWith(".hex")) { - context.loadHex(path, bank); - } else { - dialogs - .readInteger("Enter image location address:", "Load image") - .ifPresent(address -> context.loadBin(path, address, bank)); - } + boolean isHex = path.toString().toLowerCase().endsWith(".hex"); + boolean hasBanks = context.getBanksCount() > 1; + + int bank = 0; + int address = 0; + boolean ok = true; + + if (!isHex || hasBanks) { + SelectBankAddressDialog dialog = new SelectBankAddressDialog( + this, hasBanks, !isHex, dialogs + ); + dialog.setVisible(true); + ok = dialog.isOk(); + bank = dialog.getBank(); + address = dialog.getAddress(); + } - table.revalidate(); - table.repaint(); - } catch (NumberFormatException e) { - dialogs.showError("Invalid number format", "Load image"); + if (isHex && ok) { + context.loadHex(path, bank); + } + if (!isHex && ok) { + context.loadBin(path, address, bank); } + + table.revalidate(); + table.repaint(); }); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java new file mode 100644 index 000000000..3dc6185bd --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java @@ -0,0 +1,124 @@ +package net.emustudio.plugins.memory.bytemem.gui; + +import net.emustudio.emulib.runtime.helpers.RadixUtils; +import net.emustudio.emulib.runtime.interaction.Dialogs; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.util.Objects; + +public class SelectBankAddressDialog extends JDialog { + private final RadixUtils ru = RadixUtils.getInstance(); + private final Dialogs dialogs; + private final boolean selectBank; + private final boolean selectAddress; + private final JTextField txtBank = new JTextField("0"); + private final JTextField txtAddress = new JTextField("0"); + private int bank; + private int address; + private boolean okPressed; + + public SelectBankAddressDialog(JDialog parent, boolean selectBank, boolean selectAddress, Dialogs dialogs) { + super(parent, true); + this.selectBank = selectBank; + this.selectAddress = selectAddress; + this.dialogs = Objects.requireNonNull(dialogs); + setLocationRelativeTo(parent); + initComponents(); + txtAddress.grabFocus(); + } + + public int getBank() { + return bank; + } + + public int getAddress() { + return address; + } + + public boolean isOk() { + return okPressed; + } + + private void initComponents() { + setTitle("Select address"); + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); + + JLabel lblBank = new JLabel("Memory bank:"); + JLabel lblAddress = new JLabel("Address:"); + JButton btnOK = new JButton("OK"); + btnOK.setDefaultCapable(true); + btnOK.addActionListener(this::clickBtnOK); + + getRootPane().setDefaultButton(btnOK); + + if (!selectBank) { + lblBank.setEnabled(false); + txtBank.setEnabled(false); + } + if (!selectAddress) { + lblAddress.setEnabled(false); + txtAddress.setEnabled(false); + } else { + txtAddress.setSelectionStart(0); + txtAddress.setSelectionEnd(txtAddress.getText().length()); + } + + GroupLayout layout = new GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + + layout.setHorizontalGroup( + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblBank) + .addComponent(lblAddress)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(txtAddress, 64, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtBank, 64, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnOK) + .addContainerGap())); + + layout.setVerticalGroup( + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblBank) + .addComponent(txtBank, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblAddress) + .addComponent(txtAddress, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addComponent(btnOK) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))); + pack(); + } + + private void clickBtnOK(ActionEvent e) { + try { + this.bank = ru.parseRadix(txtBank.getText().trim()); + } catch (NumberFormatException ex) { + dialogs.showError("Cannot parse memory bank", "Select address"); + txtBank.grabFocus(); + return; + } + try { + this.address = ru.parseRadix(txtAddress.getText().trim()); + } catch (NumberFormatException ex) { + dialogs.showError("Cannot parse memory address", "Select address"); + txtAddress.grabFocus(); + return; + } + okPressed = true; + dispose(); + } +} diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java index 94b0e7820..69e466d47 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java @@ -18,11 +18,10 @@ */ package net.emustudio.plugins.memory.bytemem.gui; -import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; +import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; import net.emustudio.plugins.memory.bytemem.MemoryImpl; import net.emustudio.plugins.memory.bytemem.RangeTree; @@ -38,6 +37,8 @@ import java.util.Objects; import java.util.Optional; +import static net.emustudio.plugins.memory.bytemem.gui.Constants.IMAGE_EXTENSION_FILTER; + public class SettingsDialog extends JDialog { private final static Logger LOGGER = LoggerFactory.getLogger(SettingsDialog.class); @@ -77,7 +78,7 @@ private void loadSettings(PluginSettings settings) { dialogs.showError("Invalid number format while loading settings: ", "Load settings"); } } - + private void initComponents() { JPanel jPanel1 = new JPanel(); JScrollPane jScrollPane1 = new JScrollPane(); @@ -387,28 +388,27 @@ private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { private void btnAddImageActionPerformed(java.awt.event.ActionEvent evt) { dialogs.chooseFile( - "Add memory image", "Add", Path.of(System.getProperty("user.dir")), false, - new FileExtensionsFilter("Memory images", "hex", "bin") + "Add memory image", "Add", Path.of(System.getProperty("user.dir")), false, IMAGE_EXTENSION_FILTER ).ifPresent(path -> { - try { - - boolean isHex = path.toString().toLowerCase().endsWith(".hex"); - Optional imageAddress = Optional.empty(); - if (!isHex) { - imageAddress = dialogs.readInteger("Enter image address:", "Add image", 0); - } - - final int bank = (context.getBanksCount() > 1) - ? dialogs.readInteger("Enter memory bank index:", "Add memory image", 0).orElse(0) - : 0; + boolean isHex = path.toString().toLowerCase().endsWith(".hex"); + boolean hasBanks = context.getBanksCount() > 1; + + int bank = 0; + int address = 0; + boolean ok = true; + + if (!isHex || hasBanks) { + SelectBankAddressDialog dialog = new SelectBankAddressDialog( + this, hasBanks, !isHex, dialogs + ); + dialog.setVisible(true); + ok = dialog.isOk(); + bank = dialog.getBank(); + address = dialog.getAddress(); + } - if (!isHex) { - imageAddress.ifPresent(address -> imagesModel.addImage(path, address, bank)); - } else { - imagesModel.addImage(path, 0, bank); - } - } catch (NumberFormatException e) { - dialogs.showError("Invalid number format", "Add image"); + if (ok) { + imagesModel.addImage(path, address, bank); } }); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/TableMemory.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/TableMemory.java index 252048484..2e0456a2d 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/TableMemory.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/TableMemory.java @@ -28,7 +28,7 @@ import java.awt.*; import java.util.Objects; -import static net.emustudio.plugins.memory.bytemem.gui.Constants.MONOSPACED_PLAIN; +import static net.emustudio.plugins.memory.bytemem.gui.Constants.MEMORY_CELLS_FONT; public class TableMemory extends JTable { private final MemoryTableModel tableModel; @@ -39,11 +39,11 @@ public TableMemory(MemoryTableModel tableModel, JScrollPane pm) { this.tableModel = Objects.requireNonNull(tableModel); super.setModel(this.tableModel); - super.setFont(MONOSPACED_PLAIN); + super.setFont(MEMORY_CELLS_FONT); super.setCellSelectionEnabled(true); super.setFocusCycleRoot(true); super.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - super.getTableHeader().setFont(MONOSPACED_PLAIN); + super.getTableHeader().setFont(MEMORY_CELLS_FONT); super.setDefaultRenderer(Object.class, new MemCellRenderer()); setOpaque(true); @@ -67,7 +67,7 @@ private static class MemRowHeaderRenderer extends JLabel implements ListCellRend setHorizontalAlignment(CENTER); setForeground(header.getForeground()); setBackground(header.getBackground()); - setFont(MONOSPACED_PLAIN); + setFont(MEMORY_CELLS_FONT); setOpaque(true); setDoubleBuffered(true); this.setPreferredSize(new Dimension(4 * 18, header.getPreferredSize().height + 3)); @@ -99,7 +99,7 @@ private class MemCellRenderer extends JLabel implements TableCellRenderer { + tableModel.getColumnCount() * tableModel.getRowCount() * currentPage) + "h"; } rowHeader = new JList<>(addresses); - this.setFont(MONOSPACED_PLAIN); + this.setFont(MEMORY_CELLS_FONT); FontMetrics fm = rowHeader.getFontMetrics(rowHeader.getFont()); int char_width = 17; From ed3b8bc8081bc5fd95d12e08c7ddcd8d5140d518 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 6 Sep 2022 21:35:59 +0200 Subject: [PATCH 202/314] [#270] byte-mem: mouse wheel rotation changes pages --- .../plugins/memory/bytemem/gui/MemoryGui.java | 14 ++----- .../memory/bytemem/gui/MouseHandler.java | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MouseHandler.java diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java index ce17f219d..1da30e531 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java @@ -99,16 +99,10 @@ public void windowClosing(WindowEvent e) { int column = e.getColumn(); updateMemVal(row, column); }); - table.addMouseListener(new MouseAdapter() { - - @Override - public void mouseClicked(MouseEvent e) { - super.mousePressed(e); - int row = table.getSelectedRow(); - int col = table.getSelectedColumn(); - updateMemVal(row, col); - } - }); + MouseHandler mouseHandler = new MouseHandler( + tableModel, () -> updateMemVal(table.getSelectedRow(), table.getSelectedColumn())); + table.addMouseListener(mouseHandler); + table.addMouseWheelListener(mouseHandler); table.addKeyListener(new KeyboardHandler(table, spnPage.getModel(), this)); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MouseHandler.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MouseHandler.java new file mode 100644 index 000000000..17c6165af --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MouseHandler.java @@ -0,0 +1,39 @@ +package net.emustudio.plugins.memory.bytemem.gui; + +import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; +import java.util.Objects; + +public class MouseHandler extends MouseAdapter { + private final MemoryTableModel tableModel; + private final Runnable updateMemoryValue; + + public MouseHandler(MemoryTableModel tableModel, Runnable updateMemoryValue) { + this.tableModel = Objects.requireNonNull(tableModel); + this.updateMemoryValue = Objects.requireNonNull(updateMemoryValue); + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + int page = tableModel.getPage(); + int rotation = e.getWheelRotation(); + try { + tableModel.setPage(page + rotation); + } catch (IndexOutOfBoundsException ignored) { + if (rotation < 0) { + tableModel.setPage(tableModel.getPageCount() - 1); + } else { + tableModel.setPage(0); + } + } + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mousePressed(e); + updateMemoryValue.run(); + } +} From 639b53b2151059008f851e742d129eee0e7fd99e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 6 Sep 2022 21:39:40 +0200 Subject: [PATCH 203/314] [#260] 88-disk: un-ignore tests --- .../net/emustudio/plugins/device/mits88dcdd/DriveTest.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java index 3e329e5a6..e4391646c 100644 --- a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java +++ b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java @@ -23,7 +23,6 @@ import net.emustudio.plugins.device.mits88dcdd.drive.DriveParameters; import org.easymock.EasyMock; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -63,7 +62,6 @@ private void assertImageContent(int dataStart) throws Exception { } @Test - @Ignore public void testInitialDriveParameters() { Drive drive = new Drive(0); @@ -112,7 +110,6 @@ public void testUmountClearsMountImageInDriveParams() throws IOException { } @Test - @Ignore public void testDriveParametersAfterSelect() throws Exception { Drive drive = new Drive(0); drive.setSectorsPerTrack(SECTORS_COUNT); @@ -131,7 +128,6 @@ public void testDriveParametersAfterSelect() throws Exception { } @Test - @Ignore public void testDriveParametersAfterSelectThenDeselect() throws Exception { Drive drive = new Drive(0); drive.setSectorsPerTrack(SECTORS_COUNT); From 138e3fdfd8bebebde5636a2b522bb9a62a04808e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 6 Sep 2022 22:50:46 +0200 Subject: [PATCH 204/314] [#260] make some order in altair8800 boots --- .../examples/altair8800/boot/88-disk-rom.asm | 175 --------------- .../examples/altair8800/boot/88-disk-rom.bin | Bin 256 -> 0 bytes .../files/examples/altair8800/boot/README | 7 + .../files/examples/altair8800/boot/boot.c | 90 -------- .../files/examples/altair8800/boot/dbl.asm | 208 ++++++++++++++++++ .../examples/altair8800/boot/mdbl-simh.asm | 147 ------------- .../files/examples/altair8800/boot/mdbl.asm | 118 ++++++++++ 7 files changed, 333 insertions(+), 412 deletions(-) delete mode 100644 application/src/main/files/examples/altair8800/boot/88-disk-rom.asm delete mode 100644 application/src/main/files/examples/altair8800/boot/88-disk-rom.bin create mode 100644 application/src/main/files/examples/altair8800/boot/README delete mode 100644 application/src/main/files/examples/altair8800/boot/boot.c create mode 100644 application/src/main/files/examples/altair8800/boot/dbl.asm delete mode 100644 application/src/main/files/examples/altair8800/boot/mdbl-simh.asm create mode 100644 application/src/main/files/examples/altair8800/boot/mdbl.asm diff --git a/application/src/main/files/examples/altair8800/boot/88-disk-rom.asm b/application/src/main/files/examples/altair8800/boot/88-disk-rom.asm deleted file mode 100644 index 276ee8c82..000000000 --- a/application/src/main/files/examples/altair8800/boot/88-disk-rom.asm +++ /dev/null @@ -1,175 +0,0 @@ -;THE ALTAIR 88-DSK ROM MOVES THIS CODE TO 4C00H THEN -; JUMPS TO IT. POSSIBLE ERRORS ARE: -;C CRC ON DISK DOESN'T MATCH CALCULATED CRC -;M MEMORY ERROR READ/BACK FROM MEMORY DOESN'T MATCH -; WRITE TO MEMORY (NO RAM, BAD RAM, OR WPROT) -;O OVERFLOW OR OUT OF MEM CAUSED BY TRYING TO LOAD BEYOND -; FF00 OR BAD "LOAD LIMIT BYTES" ON DISK. - -ORG 0FF00h - -; RELOCATE $E6 BYTES REMAINING OF LOADER TO 4C00 (19456D) -LXI H,4C00h -LXI D,here ;0FF18h -MVI C,0E6h -XFF08: LDAX D -MOV M,A -INX D -INX H -DCR C -JNZ XFF08 -JMP 4C00h - -here: -;ORG 4C00h -DI ;DISABLE INTERRUPTS -LXI SP,4D62h ;LOAD STACK POINTER -XRA A ;ZERO IN A -OUT 08h ;SELECT DRIVE 0 -MVI A,04h ;HEAD DOWN CMD -OUT 09h ;SEND HEAD DOWN -JMP TTRK0 ;GO TEST FOR TRACK ZERO -TMVOK: IN 08h ;GET STATUS -ANI 02h ;TEST FOR MOVE OK -JNZ TMVOK ;JMP MOVE NOT OK -MVI A,02h ;STEP OUT CMD -OUT 09h ;SEND STEP OUT -TTRK0: IN 08h ;GET STATUS -ANI 40h ;TEST FOR TRACK ZERO -JNZ TMVOK ;JMP NOT TRACK ZERO -LXI D,0000 ;DE->0000H -NXTTK: MVI B,00 ;B=0 -THDDN: IN 08h ;GET STATUS -ANI 04h ;TEST FOR HEAD DOWN -JNZ THDDN ;JMP NOT HEAD DOWN - -;SEEK TO SECTOR IN B -NXTSEC: MVI A,10h ;A=10H 16D RETRY COUNT -RETRY: PUSH PSW ;SAVE RETRY COUNT -PUSH D ;NXTMEM -PUSH B ;B=SECTOR -PUSH D ;NXTMEM -LXI D,8086h ;D=80(UNUSED?) E=128=COUNT -LXI H,VAR1 ;M=POINTER TO INBUFFER -TSECT: IN 09h ;GET SECTOR# UNDER HEAD AND STATUS -RAR ;TEST SECTOR TRUE -JC TSECT ;JMP TSECT IF NOT TRUE -ANI 1Fh ;AND SECTOR MASK 31D -CMP B ;DESIRED SECTOR -JNZ TSECT ;JMP TSECT IF NOT EQUAL - -;READ 134 BYTES TWO AT A TIME INTO INBUFFER -TRDOK: IN 08h ;GET STATUS -ORA A ;SET FLAGS TEST FOR READ OK -JM TRDOK ;JMP TRDOK IF NOT READ OK -IN 0Ah ;GET DATA BYTE1 -MOV M,A ;MOVE BYTE TO INBUFF -INX H ;BUMP INPOINTER -DCR E ;DECREMENT COUNT -JZ MVBYTS ;JMP MVBYTS IF DONE -DCR E ;DEC COUNT -IN 0Ah ;GET DATA BYTE2 -MOV M,A ;MOVE TO INBUFF -INX H ;INCREMENT POINTER -JNZ TRDOK ;JMP TRDOK IF COUNT IN E IS NOT ZERO - -;MOVE 128 DATA BYTES FROM BUFF TO MEMORY MAKE A CRC -MVBYTS: POP H ;HL (M)=0000H FIRST TIME -LXI D,VAR3 ;DE POINTS TO BUFFER + 3 -LXI B,0080h ;B=0=CRC C=128 COUNT -MVBYT2: LDAX D ;GET BYTE FROM BUFFER -MOV M,A ;MOVE TO DESTINATION -CMP M ;CHECK FOR MEMORY PROBLEM -JNZ MERROR ;JMP MERROR IF PROBLEM -ADD B ;MAKE A CRC -MOV B,A ;SAVE IN B -INX D ;INC SRC -INX H ;INC DEST -DCR C ;DEC COUNT -JNZ MVBYT2 ;JMP MVBYT2 UNTIL COUNT = 0 - -;CHECK CRC -LDAX D ;DE POINTS TO BUFFER + 131 -CPI 0FFh ;COMPARE THAT BYTE TO 255 -JNZ FFERR ;JMP FFERR IF NOT EQUAL -INX D ;INC DE POINTS TO BUFF+132 -LDAX D ;GET THAT BYTE -CMP B ;COMPARE TO CRC -FFERR: POP B ;B=SECTOR -XCHG ;DE->NEXT DEST HL->BUFF+132 -JNZ CRCERR ;CRC ERROR GO CRCERR - -;CHECK FOR OUT OF MEMORY CHECK DONE LOADING -POP PSW ;0000H FIRST TIME -POP PSW ;ACC=16 -LHLD VAR2 ;L=BUFF+1 H=BUFF+2 -PUSH D ;SAVE NEXT DEST 0080 FIRST TIME -LXI D,0FF00h ;DE->BOOTROM(END OF MEMORY) -CALL SUB1 ;COMPARE1 FF00H,HL OUT OF MEMORY (HL GREATER THAN FF00H) -POP D ; NEXT DEST -JC OERROR ;JMP 'O'UT OF RAM ERROR (HL GREATER THAN FFOOH) -CALL SUB1 ;COMPARE2 DE,HL ARE WE DONE LOADING? -JNC EXIT1 ;IF NO CARRY (HL <= NEXT DEST)WE'RE DONE GO EXECUTE - -;CALCULATE NEXT SECTOR AND TRACK -INR B ;ADD 2 TO SECTOR# -INR B ; -MOV A,B ;DESIRED NEXT SECTORA -CPI 20h ;TEST IF SECTORA LESS THAN 32 -JC NXTSEC ;IF LESS GO GET IT -MVI B,01h ; IF NOT LESS MAKE DESIRED SECTORB=1 -JZ NXTSEC ;IF SECTORA EQUALED 32 GO GET SECTORB=1 -LOOP7: IN 08h ;ELSE GET STATUS -ANI 02h ;TEST MOVE OK -JNZ LOOP7 ;UNTIL MOVE IS OK -MVI A,01h ;STEP IN CMD -OUT 09h ;SEND STEP IN CMD -JMP NXTTK ;START LOADING FROM NEXT TRACK SECTORB=0 - -;LOAD THE EVEN SECTORS ON A TRACK FIRST -;THEN THE ODD SECTORS - -;DONE -EXIT1: MVI A,80h ; -OUT 08h ;CLEAR CONTROLLER -JMP 0000h ;GO - -;CRC ERROR RETRY PSW TIMES -CRCERR: POP D -POP PSW ; -DCR A ;DECREMENT RETRY COUNT -JNZ RETRY ;IF NOT 0 GO RETRY - -;CLEAR CONTROLLER SEND TO CONSOLE ERROR MESSAGE -MVI A,43h ;ELSE LOAD A WITH CHAR 'C'RC ERROR -DB 01h -;4CBD LXI B,4F3E ;GARBAGE - SKIP TRICK BD-BF -OERROR: MVI A,4Fh ; LOAD A WITH CHAR 'O'VERFLOW -DB 01h -;4CC0 LXI B,4D3E ;GARBAGE - SKIP TRICK C0-C2 -MERROR: MVI A,4D ; LOAD A WITH CHAR 'M'EMORY ERROR -MOV B,A ;SAVE CHAR -MVI A,80h ;CLEAR CONTROLLER -OUT 08h ;SEND CLEAR -MOV A,B ;GET CHAR - -CONOUT: OUT 11h ;SEND ERROR CHAR TO CONSOLE - JMP CONOUT ;OVER AND OVER AND OVER... - -;TEST FOR OVERFLOW, TEST LOAD LIMIT, COMPARE HL,DE -SUB1: MOV A,D ; -CMP H ; -RNZ ; -MOV A,E ; -CMP L ; -RET - -;BEGINNING OF IN BUFFER -VAR1: DB 84h ;ADD H -VAR2: DB 0 ;NOP - DB 4Ch ;MOV C,H - -VAR3: DB 24h ;INR H - DB 0D6h, 56h ;SUI $56 - DB 16h, 0 ;MVI D,0 - NOP ; DATA TRUNCATED diff --git a/application/src/main/files/examples/altair8800/boot/88-disk-rom.bin b/application/src/main/files/examples/altair8800/boot/88-disk-rom.bin deleted file mode 100644 index 73386a4e81ea05a0c7742231fef53ff0d51d33d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmY#n@DY^w&-YBKTv(a+5Xb++3_c7X@YyiQcl~7!JC@6whb4V(b39`@#OGtjbeR*# zbO16185r0YfNYjSsy=oCU#}j$D%jSbc*W;7r~EAopJ(zr4p{(oZU5!sbDOJNS@u+v zk1U9B$i?TO;B_Cy1_r6}eTNSEG`NGTP4toa_y16ZkFeB^gRc*5_4)Ww>#EOHL5BZl z&-q-uwa*7gU0UbE!cy^1;g*gM8{;V*h>I5Z*f9d#r|e_baGB#U1H;9Swukh5?3@|x j{2A?h-9e%iml+SA^r_l&pnC7g76u;`u`n^P|6l|Fr@Uju diff --git a/application/src/main/files/examples/altair8800/boot/README b/application/src/main/files/examples/altair8800/boot/README new file mode 100644 index 000000000..f753d4b45 --- /dev/null +++ b/application/src/main/files/examples/altair8800/boot/README @@ -0,0 +1,7 @@ +mdbl.asm: 88-disk modified boot loader; reverse-engineered from simh emulator +mdbl.bin: 88-disk modified boot loader; extracted from simh emulator + +dbl.asm : 88-disk boot loader; reverse-engineered from simh emulator +dbl.bin : 88-disk boot loader; extracted from simh emulator + +cdbl.adm: common disk boot loader 3.0; https://deramp.com/downloads/altair/software/roms/custom_roms/M%20Eberhard%20Improved%20ROMs/CDBL%20Manual.pdf diff --git a/application/src/main/files/examples/altair8800/boot/boot.c b/application/src/main/files/examples/altair8800/boot/boot.c deleted file mode 100644 index e3bb0a27c..000000000 --- a/application/src/main/files/examples/altair8800/boot/boot.c +++ /dev/null @@ -1,90 +0,0 @@ -#include - -/* modified bootrom */ -signed int mbootrom[256] = { - 0xf3, 0x06, 0x80, 0x3e, 0x0e, 0xd3, 0xfe, 0x05, /* ff00-ff07 */ - 0xc2, 0x05, 0xff, 0x3e, 0x16, 0xd3, 0xfe, 0x3e, /* ff08-ff0f */ - 0x12, 0xd3, 0xfe, 0xdb, 0xfe, 0xb7, 0xca, 0x20, /* ff10-ff17 */ - 0xff, 0x3e, 0x0c, 0xd3, 0xfe, 0xaf, 0xd3, 0xfe, /* ff18-ff1f */ - 0x21, 0x00, 0x5c, 0x11, 0x33, 0xff, 0x0e, 0x88, /* ff20-ff27 */ - 0x1a, 0x77, 0x13, 0x23, 0x0d, 0xc2, 0x28, 0xff, /* ff28-ff2f */ - 0xc3, 0x00, 0x5c, 0x31, 0x21, 0x5d, 0x3e, 0x00, /* ff30-ff37 */ - 0xd3, 0x08, 0x3e, 0x04, 0xd3, 0x09, 0xc3, 0x19, /* ff38-ff3f */ - 0x5c, 0xdb, 0x08, 0xe6, 0x02, 0xc2, 0x0e, 0x5c, /* ff40-ff47 */ - 0x3e, 0x02, 0xd3, 0x09, 0xdb, 0x08, 0xe6, 0x40, /* ff48-ff4f */ - 0xc2, 0x0e, 0x5c, 0x11, 0x00, 0x00, 0x06, 0x08, /* ff50-ff57 */ - 0xc5, 0xd5, 0x11, 0x86, 0x80, 0x21, 0x88, 0x5c, /* ff58-ff5f */ - 0xdb, 0x09, 0x1f, 0xda, 0x2d, 0x5c, 0xe6, 0x1f, /* ff60-ff67 */ - 0xb8, 0xc2, 0x2d, 0x5c, 0xdb, 0x08, 0xb7, 0xfa, /* ff68-ff6f */ - 0x39, 0x5c, 0xdb, 0x0a, 0x77, 0x23, 0x1d, 0xc2, /* ff70-ff77 */ - 0x39, 0x5c, 0xd1, 0x21, 0x8b, 0x5c, 0x06, 0x80, /* ff78-ff7f */ - 0x7e, 0x12, 0x23, 0x13, 0x05, 0xc2, 0x4d, 0x5c, /* ff80-ff87 */ - 0xc1, 0x21, 0x00, 0x5c, 0x7a, 0xbc, 0xc2, 0x60, /* ff88-ff8f */ - 0x5c, 0x7b, 0xbd, 0xd2, 0x80, 0x5c, 0x04, 0x04, /* ff90-ff97 */ - 0x78, 0xfe, 0x20, 0xda, 0x25, 0x5c, 0x06, 0x01, /* ff98-ff9f */ - 0xca, 0x25, 0x5c, 0xdb, 0x08, 0xe6, 0x02, 0xc2, /* ffa0-ffa7 */ - 0x70, 0x5c, 0x3e, 0x01, 0xd3, 0x09, 0x06, 0x00, /* ffa8-ffaf */ - 0xc3, 0x25, 0x5c, 0x3e, 0x80, 0xd3, 0x08, 0xfb, /* ffb0-ffb7 */ - 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ffb8-ffbf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ffc0-ffc7 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ffc8-ffcf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ffd0-ffd7 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ffd8-ffdf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ffe0-ffe7 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ffe8-ffef */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* fff0-fff7 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* fff8-ffff */ -}; - -/* original bootrom */ -signed int bootrom[256] = { - 0041, 0000, 0114, 0021, 0030, 0377, 0016, 0346, - 0032, 0167, 0023, 0043, 0015, 0302, 0010, 0377, - 0303, 0000, 0114, 0000, 0000, 0000, 0000, 0000, - 0363, 0061, 0142, 0115, 0257, 0323, 0010, 0076, /* 46000 */ - 0004, 0323, 0011, 0303, 0031, 0114, 0333, 0010, /* 46010 */ - 0346, 0002, 0302, 0016, 0114, 0076, 0002, 0323, /* 46020 */ - 0011, 0333, 0010, 0346, 0100, 0302, 0016, 0114, - 0021, 0000, 0000, 0006, 0000, 0333, 0010, 0346, - 0004, 0302, 0045, 0114, 0076, 0020, 0365, 0325, - 0305, 0325, 0021, 0206, 0200, 0041, 0324, 0114, - 0333, 0011, 0037, 0332, 0070, 0114, 0346, 0037, - 0270, 0302, 0070, 0114, 0333, 0010, 0267, 0372, - 0104, 0114, 0333, 0012, 0167, 0043, 0035, 0312, - 0132, 0114, 0035, 0333, 0012, 0167, 0043, 0302, - 0104, 0114, 0341, 0021, 0327, 0114, 0001, 0200, - 0000, 0032, 0167, 0276, 0302, 0301, 0114, 0200, - 0107, 0023, 0043, 0015, 0302, 0141, 0114, 0032, - 0376, 0377, 0302, 0170, 0114, 0023, 0032, 0270, - 0301, 0353, 0302, 0265, 0114, 0361, 0361, 0052, - 0325, 0114, 0325, 0021, 0000, 0377, 0315, 0316, - 0114, 0321, 0332, 0276, 0114, 0315, 0316, 0114, - 0322, 0256, 0114, 0004, 0004, 0170, 0376, 0040, - 0332, 0054, 0114, 0006, 0001, 0312, 0054, 0114, - 0333, 0010, 0346, 0002, 0302, 0240, 0114, 0076, - 0001, 0323, 0011, 0303, 0043, 0114, 0076, 0200, - 0323, 0010, 0303, 0000, 0000, 0321, 0361, 0075, - 0302, 0056, 0114, 0076, 0103, 0001, 0076, 0117, - 0001, 0076, 0115, 0107, 0076, 0200, 0323, 0010, - 0170, 0323, 0001, 0303, 0311, 0114, 0172, 0274, - 0300, 0173, 0275, 0311, 0204, 0000, 0114, 0044, - 0026, 0126, 0026, 0000, 0000, 0000, 0000, 0000 -}; - -int main() { - FILE *f = fopen("boot.bin","w"); - int n; - - for (n =0; n < 256; n++) { - fputc(bootrom[n] & 0xFF, f); - } - fclose(f); - - f = fopen("mboot.bin","w"); - for (n =0; n < 256; n++) { - fputc(mbootrom[n] & 0xFF, f); - } - fclose(f); - - return 0; -} diff --git a/application/src/main/files/examples/altair8800/boot/dbl.asm b/application/src/main/files/examples/altair8800/boot/dbl.asm new file mode 100644 index 000000000..bdad56a6d --- /dev/null +++ b/application/src/main/files/examples/altair8800/boot/dbl.asm @@ -0,0 +1,208 @@ +; THE ALTAIR 88-DSK ROM MOVES THIS CODE TO 4C00H THEN +; JUMPS TO IT. POSSIBLE ERRORS ARE: +; C CRC ON DISK DOESN'T MATCH CALCULATED CRC +; M MEMORY ERROR READ/BACK FROM MEMORY DOESN'T MATCH WRITE TO MEMORY (NO RAM, BAD RAM, OR WPROT) +; O OVERFLOW OR OUT OF MEM CAUSED BY TRYING TO LOAD BEYOND FF00 OR BAD "LOAD LIMIT BYTES" ON DISK. + +ORG 0FF00h + +; RELOCATE $E6 BYTES REMAINING OF LOADER TO 4C00 (19456D) +LXI H, 4C00h +LXI D, here ;0FF18h +MVI C, 0E6h + +XFF08: +LDAX D +MOV M,A +INX D +INX H +DCR C +JNZ XFF08 +JMP 4C00h + +here: +;ORG 4C00h +DI ; DISABLE INTERRUPTS +LXI SP,4D62h ; LOAD STACK POINTER +XRA A ; ZERO IN A +OUT 08h ; SELECT DRIVE 0 +MVI A,04h ; HEAD DOWN CMD +OUT 09h ; SEND HEAD DOWN +JMP TTRK0 ; GO TEST FOR TRACK ZERO + +TMVOK: +IN 08h ; GET STATUS +ANI 02h ; TEST FOR MOVE OK +JNZ TMVOK ; JMP MOVE NOT OK +MVI A,02h ; STEP OUT CMD +OUT 09h ; SEND STEP OUT + +TTRK0: +IN 08h ; GET STATUS +ANI 40h ; TEST FOR TRACK ZERO +JNZ TMVOK ; JMP NOT TRACK ZERO +LXI D,0000 ; DE->0000H + +NXTTK: +MVI B,00 ; B=0 + +THDDN: +IN 08h ; GET STATUS +ANI 04h ; TEST FOR HEAD DOWN +JNZ THDDN ; JMP NOT HEAD DOWN + +;SEEK TO SECTOR IN B +NXTSEC: +MVI A,10h ; A=10H 16D RETRY COUNT + +RETRY: +PUSH PSW ; SAVE RETRY COUNT +PUSH D ; NXTMEM +PUSH B ; B=SECTOR +PUSH D ; NXTMEM +LXI D,8086h ; D=80(UNUSED?) E=128=COUNT +LXI H,VAR1 ; M=POINTER TO INBUFFER + +TSECT: +IN 09h ; GET SECTOR# UNDER HEAD AND STATUS +RAR ; TEST SECTOR TRUE +JC TSECT ; JMP TSECT IF NOT TRUE +ANI 1Fh ; AND SECTOR MASK 31D +CMP B ; DESIRED SECTOR +JNZ TSECT ; JMP TSECT IF NOT EQUAL + +;READ 134 BYTES TWO AT A TIME INTO INBUFFER +TRDOK: +IN 08h ; GET STATUS +ORA A ; SET FLAGS TEST FOR READ OK +JM TRDOK ; JMP TRDOK IF NOT READ OK +IN 0Ah ; GET DATA BYTE1 +MOV M,A ; MOVE BYTE TO INBUFF +INX H ; BUMP INPOINTER +DCR E ; DECREMENT COUNT +JZ MVBYTS ; JMP MVBYTS IF DONE +DCR E ; DEC COUNT +IN 0Ah ; GET DATA BYTE2 +MOV M,A ; MOVE TO INBUFF +INX H ; INCREMENT POINTER +JNZ TRDOK ; JMP TRDOK IF COUNT IN E IS NOT ZERO + +;MOVE 128 DATA BYTES FROM BUFF TO MEMORY MAKE A CRC +MVBYTS: +POP H ; HL (M)=0000H FIRST TIME +LXI D,VAR3 ; DE POINTS TO BUFFER + 3 +LXI B,0080h ; B=0=CRC C=128 COUNT + +MVBYT2: +LDAX D ; GET BYTE FROM BUFFER +MOV M,A ; MOVE TO DESTINATION +CMP M ; CHECK FOR MEMORY PROBLEM +JNZ MERROR ; JMP MERROR IF PROBLEM +ADD B ; MAKE A CRC +MOV B,A ; SAVE IN B +INX D ; INC SRC +INX H ; INC DEST +DCR C ; DEC COUNT +JNZ MVBYT2 ; JMP MVBYT2 UNTIL COUNT = 0 + +;CHECK CRC +LDAX D ; DE POINTS TO BUFFER + 131 +CPI 0FFh ; COMPARE THAT BYTE TO 255 +JNZ FFERR ; JMP FFERR IF NOT EQUAL +INX D ; INC DE POINTS TO BUFF+132 +LDAX D ; GET THAT BYTE +CMP B ; COMPARE TO CRC + +FFERR: +POP B ; B=SECTOR +XCHG ; DE->NEXT DEST HL->BUFF+132 +JNZ CRCERR ; CRC ERROR GO CRCERR + +;CHECK FOR OUT OF MEMORY CHECK DONE LOADING +POP PSW ; 0000H FIRST TIME +POP PSW ; ACC=16 +LHLD VAR2 ; L=BUFF+1 H=BUFF+2 +PUSH D ; SAVE NEXT DEST 0080 FIRST TIME +LXI D,0FF00h ; DE->BOOTROM(END OF MEMORY) +CALL SUB1 ; COMPARE1 FF00H,HL OUT OF MEMORY (HL GREATER THAN FF00H) +POP D ; NEXT DEST +JC OERROR ; JMP 'O'UT OF RAM ERROR (HL GREATER THAN FFOOH) +CALL SUB1 ; COMPARE2 DE,HL ARE WE DONE LOADING? +JNC EXIT1 ; IF NO CARRY (HL <= NEXT DEST)WE'RE DONE GO EXECUTE + +;CALCULATE NEXT SECTOR AND TRACK +INR B ; ADD 2 TO SECTOR# +INR B ; +MOV A,B ; DESIRED NEXT SECTORA +CPI 20h ; TEST IF SECTORA LESS THAN 32 +JC NXTSEC ; IF LESS GO GET IT +MVI B,01h ; IF NOT LESS MAKE DESIRED SECTORB=1 +JZ NXTSEC ; IF SECTORA EQUALED 32 GO GET SECTORB=1 + +LOOP7: +IN 08h ; ELSE GET STATUS +ANI 02h ; TEST MOVE OK +JNZ LOOP7 ; UNTIL MOVE IS OK +MVI A,01h ; STEP IN CMD +OUT 09h ; SEND STEP IN CMD +JMP NXTTK ; START LOADING FROM NEXT TRACK SECTORB=0 + +;LOAD THE EVEN SECTORS ON A TRACK FIRST +;THEN THE ODD SECTORS + +;DONE +EXIT1: +MVI A,80h ; +OUT 08h ; CLEAR CONTROLLER +JMP 0000h ; GO + +;CRC ERROR RETRY PSW TIMES +CRCERR: +POP D +POP PSW ; +DCR A ; DECREMENT RETRY COUNT +JNZ RETRY ; IF NOT 0 GO RETRY + +;CLEAR CONTROLLER SEND TO CONSOLE ERROR MESSAGE +MVI A,43h ; ELSE LOAD A WITH CHAR 'C'RC ERROR +DB 01h + +;4CBD LXI B,4F3E ;GARBAGE - SKIP TRICK BD-BF +OERROR: +MVI A,4Fh ; LOAD A WITH CHAR 'O'VERFLOW +DB 01h + +;4CC0 LXI B,4D3E ;GARBAGE - SKIP TRICK C0-C2 +MERROR: +MVI A,4D ; LOAD A WITH CHAR 'M'EMORY ERROR +MOV B,A ; SAVE CHAR +MVI A,80h ; CLEAR CONTROLLER +OUT 08h ; SEND CLEAR +MOV A,B ; GET CHAR + +CONOUT: +OUT 11h ; SEND ERROR CHAR TO CONSOLE +JMP CONOUT ; OVER AND OVER AND OVER... + +;TEST FOR OVERFLOW, TEST LOAD LIMIT, COMPARE HL,DE +SUB1: +MOV A,D ; +CMP H ; +RNZ ; +MOV A,E ; +CMP L ; +RET + +;BEGINNING OF IN BUFFER +VAR1: +DB 84h ; ADD H + +VAR2: +DB 0 ; NOP +DB 4Ch ; MOV C,H + +VAR3: +DB 24h ; INR H +DB 0D6h, 56h ; SUI $56 +DB 16h, 0 ; MVI D,0 +NOP ; DATA TRUNCATED diff --git a/application/src/main/files/examples/altair8800/boot/mdbl-simh.asm b/application/src/main/files/examples/altair8800/boot/mdbl-simh.asm deleted file mode 100644 index 47ec66b8d..000000000 --- a/application/src/main/files/examples/altair8800/boot/mdbl-simh.asm +++ /dev/null @@ -1,147 +0,0 @@ -; MDBL.ASM -; disassembled from simh emulator - -di -ld b, 0x80 ; how many times reset SIMH -ld a, 0x0E ; reset SIMH - -resetSimhLoop: -out (0xFE), a -dec b -jp nz, resetSimhLoop - -ld a, 0x16 ; stop timer interrupts -out (0xFE), a -ld a, 0x12 ; finds out if we have banked memory -out (0xFE), a - -in a, (0xFE) ; get banks count -or a -jp z, relocateSelf ; jump if no banked memory present - -ld a, 0x0C ; select bank -out (0xFE), a -xor a ; bank = 0 -out (0xFE), a - -relocateSelf: -ld hl, 0x5C00 ; relocate address -ld de, start ; code to relocate -ld c, 0x88 ; bytes count - -relocate: -ld a, (de) -ld (hl), a -inc de -inc hl -dec c -jp nz, relocate - -jp 0x5C00 - -start: -ld sp, 0x5D21 -ld a, 0 ; set drive 0 -out (0x08), a - -ld a, 4 ; head load -out (0x09), a -jp l5 - -waitForDrive: -in a, (0x08) ; port 1 status -and 2 ; is the drive alive? (selected) -jp nz, waitForDrive - -ld a, 2 ; head out -out (0x09), a - -l5: -in a, (0x08) ; port 1 status -and 0x40 ; -jp nz, waitForDrive - -ld de, 0 -ld b, 8 - -l11: - -push bc -push de - -ld de, 0x8086 -ld hl, l13 - -l6: -in a, (0x09) -rra -jp c, l6 - -and 0x1F -cp b -jp nz, l6 - -l7: -in a, (0x08) -or a -jp m, l7 - -in a, (0xA) -ld (hl), a -inc hl -dec e -jp nz, l7 - -pop de -ld hl, 0x5C8B -ld b, 0x80 - -l8: -ld a, (hl) -ld (de), a -inc hl -inc de -dec b -jp nz, l8 - -pop bc -ld hl, 0x5C00 -ld a, d -cp h -jp nz, l9 - -ld a, e -cp l - -l9: -jp nc, l10 -inc b -inc b -ld a, b -cp 0x20 -jp c, l11 - -ld b, 1 -jp z, l11 - -l12: -in a, (0x08) -and 2 -jp nz, l12 - -ld a, 1 -out (0x09), a -ld b, 0 -jp l11 - -l10: -ld a, 0x80 -out (0x08), a -ei - -jp 0 - -l13: - - - diff --git a/application/src/main/files/examples/altair8800/boot/mdbl.asm b/application/src/main/files/examples/altair8800/boot/mdbl.asm new file mode 100644 index 000000000..b21df40ec --- /dev/null +++ b/application/src/main/files/examples/altair8800/boot/mdbl.asm @@ -0,0 +1,118 @@ +; reverse-engineered modified disk boot loader (mdbl.bin) from simh emulator + +org 0FF00h + +di +ld b, 80h + +ld a, 0Eh + +l1: +out (0FEh), a +dec b +jp nz, l1 + +ld a, 16h +out (0FEh), a +ld a, 12h +out (0FEh), a + +in a, (0FEh) +or a +jp z, l2 +ld a, 0Ch +out (0FEh), a +xor a +out (0FEh), a + +l2: +ld hl, 5C00h +ld de, l4 +ld c, 88h + +l3: +ld a, (de) +ld (hl), a +inc de +inc hl +dec c +jp nz, l3 +jp 5C00h + +l4: +ld sp, 5D21h +ld a, 0 +out (8h), a +ld a, 4 +out (9h), a +jp 5C19h + +in a, (8h) +and 2 +jp nz, 5C0Eh +ld a, 2 +out (9h), a +in a, (8h) +and 40h +jp nz, 5C0Eh +ld de, 0h +ld b, 8 +push bc +push de + +ld de, 8086h +ld hl, 5C88h + +in a, (9h) +rra +jp c, 5C2Dh +and 1Fh + +cp b +jp nz, 5C2Dh +in a, (8h) +or a +jp m, 5C39h +in a, (0Ah) + +ld (hl), a +inc hl +dec e +jp nz, 5C39h +pop de +ld hl, 5C8Bh +ld b, 80h +ld a, (hl) +ld (de), a +inc hl +inc de +dec b +jp nz, 5C4Dh +pop bc +ld hl, 5C00h +ld a, d +cp h +jp nz, 5C60h +ld a, e +cp l +jp nc, 5C80h +inc b +inc b + +ld a, b +cp 20h +jp c, 5C25h +ld b, 1 +jp z, 5C25h + +in a, (8h) +and 2h +jp nz, 5C70h +ld a, 1 +out (9h), a +ld b, 0 +jp 5C25h +ld a, 80h +out (8h), a +ei +jp 0 From 0d72ee5cfc9843313e15ca1c23e039b605c9c53e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 6 Sep 2022 22:51:37 +0200 Subject: [PATCH 205/314] [#260] Remove zx spectrum computer --- .../src/main/files/config/ZxSpectrum.toml | 171 ------------------ 1 file changed, 171 deletions(-) delete mode 100644 application/src/main/files/config/ZxSpectrum.toml diff --git a/application/src/main/files/config/ZxSpectrum.toml b/application/src/main/files/config/ZxSpectrum.toml deleted file mode 100644 index 98a802bc8..000000000 --- a/application/src/main/files/config/ZxSpectrum.toml +++ /dev/null @@ -1,171 +0,0 @@ -name = "ZX Spectrum" - -[MEMORY] -schemaPoint = "80,220" -path = "byte-mem.jar" -name = "byte-mem" -id = "1e13a25d-fb23-4061-853a-5fe996b03281" -type = "MEMORY" - -[MEMORY.settings] -# memorySize = 49152 -banksCount = 0 -imageName0 = "/home/vbmacher/tmp/emuStudio/z80bltst.bin" -imageBank0 = 0 -imageAddress0 = 32768 - -# memorySize = 65536 -# ROM areas are stored as pairs ROMfromN and ROMtoN, where N is 0-based counter. There can be multiple rom areas. -# ROMfromN = someAddress -# ROMtoN = someAddress -# Memory "images" (files) will be loaded at startup into memory. They are stored here as triplet: -# - imageNameN (file name), -# - imageAddressN (address where the file will be loaded), -# - imageBankN (if memory has >1 banksCount, then number of bank; 0 otherwise) -# -# where N is a 0-based counter -# imageNameN = imageFileName # if the suffix ends with ".hex", the format will be Intel HEX; otherwise it will be binary -# imageAddressN = ... -# imageBankN = 0 -[COMPILER] -schemaPoint = "80,60" -path = "as-z80.jar" -settings = {} -name = "as-z80" -id = "9233e0c2-b53c-41e7-9eca-bbb264fcd9da" -type = "COMPILER" - -[CPU] -schemaPoint = "220,220" -path = "z80-cpu.jar" -settings = {} -name = "z80-cpu" -id = "b86d4bc2-632c-46e3-bba1-c088c9177983" -type = "CPU" - -# Uncomment the following for specific settings (and remove settings = {} above) -# [CPU.settings] -# printCode = true -# printCodeUseCache = true -# printCodeFileName = "syserr" # Or custom path to a file - -[[DEVICE]] -schemaPoint = "340,140" -path = "88-dcdd.jar" -name = "88-dcdd" -id = "c94d0e9b-f394-4a71-94b0-87d0f970a3fd" -type = "DEVICE" - -[DEVICE.settings] -# imageN = "..." # Load file into drive N at startup -sectorLength8 = 137 -sectorLength9 = 137 -sectorLength6 = 137 -sectorLength7 = 137 -sectorLength4 = 137 -sectorLength5 = 137 -sectorLength2 = 137 -sectorLength3 = 137 -sectorLength0 = 137 -sectorLength1 = 137 -port2CPU = 9 -sectorsPerTrack15 = 32 -sectorsPerTrack14 = 32 -sectorsPerTrack13 = 32 -sectorsPerTrack12 = 32 -sectorsPerTrack1 = 32 -sectorsPerTrack11 = 32 -sectorsPerTrack2 = 32 -sectorsPerTrack10 = 32 -sectorsPerTrack0 = 32 -sectorsPerTrack5 = 32 -sectorsPerTrack6 = 32 -sectorsPerTrack3 = 32 -sectorsPerTrack4 = 32 -sectorsPerTrack9 = 32 -sectorsPerTrack7 = 32 -sectorsPerTrack8 = 32 -port1CPU = 8 -port3CPU = 10 -sectorLength15 = 137 -sectorLength13 = 137 -sectorLength14 = 137 -sectorLength11 = 137 -sectorLength12 = 137 -sectorLength10 = 137 - -[[DEVICE]] -schemaPoint = "340,220" -path = "88-sio.jar" -name = "88-sio" -id = "de2ce2e7-4365-406e-864a-b60f353d3fba" -type = "DEVICE" - -[DEVICE.settings] -statusPorts = "0x10, 0x14, 0x16, 0x18" -dataPorts = "0x11, 0x15, 0x17, 0x19" -clearInputBit8 = false -clearOutputBit8 = false -inputToUpperCase = false -mapDeleteChar = "UNCHANGED" -mapBackspaceChar = "UNCHANGED" -inputInterruptVector = 0 -outputInterruptVector = 0 - -[[DEVICE]] -schemaPoint = "480,220" -path = "zxspectrum-display.jar" -name = "zxspectrum-display" -id = "0352cf74-2965-4723-bef9-3e918b1ac7c5" -type = "DEVICE" - -[DEVICE.settings] -antiAliasing = true -alwaysOnTop = true -inputReadDelay = 0 -halfDuplex = false -outputFileName = "adm3A-terminal.out" -inputFileName = "adm3A-terminal.in" - -[[connections]] -bidirectional = true -from = "9233e0c2-b53c-41e7-9eca-bbb264fcd9da" -to = "1e13a25d-fb23-4061-853a-5fe996b03281" -points = [] - -[[connections]] -bidirectional = true -from = "c94d0e9b-f394-4a71-94b0-87d0f970a3fd" -to = "b86d4bc2-632c-46e3-bba1-c088c9177983" -points = ["240,140"] - -[[connections]] -bidirectional = true -from = "1e13a25d-fb23-4061-853a-5fe996b03281" -to = "b86d4bc2-632c-46e3-bba1-c088c9177983" -points = [] - -[[connections]] -bidirectional = true -from = "de2ce2e7-4365-406e-864a-b60f353d3fba" -to = "b86d4bc2-632c-46e3-bba1-c088c9177983" -points = [] - -[[connections]] -bidirectional = true -from = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" -to = "b86d4bc2-632c-46e3-bba1-c088c9177983" -points = [] - -[[connections]] -bidirectional = true -from = "0352cf74-2965-4723-bef9-3e918b1ac7c5" -to = "de2ce2e7-4365-406e-864a-b60f353d3fba" -points = [] - -[[connections]] -bidirectional = true -from = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" -to = "1e13a25d-fb23-4061-853a-5fe996b03281" -points = ["200,140", "120,140"] - From 9e4aba24b7d4ec2346089c72488c5737bf1a66e1 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 6 Sep 2022 22:58:52 +0200 Subject: [PATCH 206/314] [#260] comments --- application/src/main/files/config/MITSAltair8800.toml | 2 +- application/src/main/files/config/MITSAltair8800Z80.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/src/main/files/config/MITSAltair8800.toml b/application/src/main/files/config/MITSAltair8800.toml index 6a4f5f99c..4c2a784ab 100644 --- a/application/src/main/files/config/MITSAltair8800.toml +++ b/application/src/main/files/config/MITSAltair8800.toml @@ -46,7 +46,7 @@ name = "MITS Altair8800" # [CPU.settings] # printCode = true # printCodeUseCache = true -# printCodeFileName = syserr # Or custom path to a file +# printCodeFileName = "filename" # (optional) [[DEVICE]] diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index eb8c2592f..0087b5b05 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -44,7 +44,7 @@ name = "MITS Altair8800 (Z80)" # [CPU.settings] # printCode = true # printCodeUseCache = true -# printCodeFileName = "syserr" # Or custom path to a file +# printCodeFileName = "filename" # (optional) [[DEVICE]] schemaPoint = "340,140" From d71a9870ceb72672fdec19cbea329bd76d4b424d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 9 Sep 2022 17:59:22 +0200 Subject: [PATCH 207/314] [#260] z80-cpu: more fixes and optimizations --- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 357 +++++++++--------- .../plugins/cpu/zilogZ80/EmulatorTables.java | 80 ++-- .../zilogZ80/EmulatorTablesGeneration.java | 56 +++ 3 files changed, 296 insertions(+), 197 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index cc176f70e..22eb650d2 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -28,7 +28,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.lang.invoke.MethodHandle; import java.util.Arrays; import java.util.List; @@ -53,6 +52,8 @@ public class EmulatorEngine implements CpuEngine { public static final int REG_A = 7, REG_B = 0, REG_C = 1, REG_D = 2, REG_E = 3, REG_H = 4, REG_L = 5; public static final int FLAG_S = 0x80, FLAG_Z = 0x40, FLAG_Y = 0x20, FLAG_H = 0x10, FLAG_X = 0x8, FLAG_PV = 0x4, FLAG_N = 0x02, FLAG_C = 0x1; + public static final int FLAG_SZP = FLAG_S | FLAG_Z | FLAG_PV; + private final static int[] CONDITION = new int[]{ FLAG_Z, FLAG_Z, FLAG_C, FLAG_C, FLAG_PV, FLAG_PV, FLAG_S, FLAG_S }; @@ -75,15 +76,14 @@ public class EmulatorEngine implements CpuEngine { public int PC = 0, SP = 0, IX = 0, IY = 0; public int I = 0, R = 0; // interrupt r., refresh r. public int memptr = 0; // internal register, https://gist.github.com/drhelius/8497817 - public int Q = 0; // internal register, public final boolean[] IFF = new boolean[2]; // interrupt enable flip-flops + private boolean interruptSkip; // when EI enabled, skip next instruction interrupt public byte interruptMode = 0; - private final Queue pendingInterrupts = new ConcurrentLinkedQueue<>(); // must be thread-safe; can cause stack overflow - // non-maskable interrupts are always executed private final AtomicBoolean pendingNonMaskableInterrupt = new AtomicBoolean(); + private RunState currentRunState = RunState.STATE_STOPPED_NORMAL; private long executedCycles = 0; @@ -218,7 +218,9 @@ private int dispatch() throws Throwable { PC = 0x66; return 12; } - if (IFF[0] && !pendingInterrupts.isEmpty()) { + if (interruptSkip) { + interruptSkip = false; // See EI + } else if (IFF[0] && !pendingInterrupts.isEmpty()) { return doInterrupt(); } return DISPATCH(DISPATCH_TABLE); @@ -370,7 +372,6 @@ private int getpair(int reg, boolean reg3IsSP) { } int index = reg * 2; return regs[index] << 8 | regs[index + 1]; - } private boolean getCC1(int cc) { @@ -424,9 +425,9 @@ int I_ADD_HL_RP() { memptr = (hl + 1) & 0xFFFF; int res = hl + rp; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | + flags = (flags & FLAG_SZP) | (((hl ^ res ^ rp) >>> 8) & FLAG_H) | - ((res >>> 16) & FLAG_C) | ((res >>> 8) & (FLAG_Y | FLAG_X)); + ((res >>> 16) & FLAG_C) | TABLE_XY[(res >>> 8) & 0xFF]; regs[REG_H] = (res >>> 8) & 0xFF; regs[REG_L] = res & 0xFF; @@ -457,7 +458,6 @@ int I_PUSH_RP() { } int I_LD_R_N() { - Q = 0; int reg = (lastOpcode >>> 3) & 0x07; putreg(reg, memory.read(PC)); PC = (PC + 1) & 0xFFFF; @@ -473,7 +473,7 @@ int I_INC_R() { int regValue = getreg(reg); int sum = (regValue + 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C) | (sumByte & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C) | TABLE_XY[sumByte]; putreg(reg, sumByte); return (reg == 6) ? 11 : 4; } @@ -483,13 +483,12 @@ int I_DEC_R() { int regValue = getreg(reg); int sum = (regValue - 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C) | (sumByte & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C) | TABLE_XY[sumByte]; putreg(reg, sumByte); return (reg == 6) ? 11 : 4; } int I_RET_CC() { - Q = 0; int cc = (lastOpcode >>> 3) & 7; if ((flags & CONDITION[cc]) == CONDITION_VALUES[cc]) { PC = readWord(SP); @@ -512,7 +511,7 @@ int I_ADD_A_R() { int oldA = regs[REG_A]; int sum = (oldA + value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; return (lastOpcode == 0x86) ? 7 : 4; } @@ -522,7 +521,7 @@ int I_ADD_A_N() { int oldA = regs[REG_A]; int sum = (oldA + value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; return 7; } @@ -531,7 +530,7 @@ int I_ADC_A_R() { int oldA = regs[REG_A]; int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; return (lastOpcode == 0x8E) ? 7 : 4; } @@ -541,7 +540,7 @@ int I_ADC_A_N() { int oldA = regs[REG_A]; int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; return 7; } @@ -552,7 +551,7 @@ int I_SUB_R() { int sum = (oldA - value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; return (lastOpcode == 0x96) ? 7 : 4; } @@ -563,7 +562,7 @@ int I_SBC_A_R() { int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; return (lastOpcode == 0x9E) ? 7 : 4; } @@ -575,13 +574,13 @@ int I_SBC_A_N() { int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; return 7; } int I_AND_R() { regs[REG_A] = (regs[REG_A] & getreg(lastOpcode & 7)) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; return (lastOpcode == 0xA6) ? 7 : 4; } @@ -590,13 +589,13 @@ int I_AND_N() { PC = (PC + 1) & 0xFFFF; regs[REG_A] = (regs[REG_A] & tmp) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; return 7; } int I_XOR_R() { regs[REG_A] = ((regs[REG_A] ^ getreg(lastOpcode & 7)) & 0xff); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; return (lastOpcode == 0xAE) ? 7 : 4; } @@ -605,13 +604,13 @@ int I_XOR_N() { PC = (PC + 1) & 0xFFFF; regs[REG_A] = ((regs[REG_A] ^ tmp) & 0xFF); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; return 7; } int I_OR_R() { regs[REG_A] = (regs[REG_A] | getreg(lastOpcode & 7)) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; return (lastOpcode == 0xB6) ? 7 : 4; } @@ -620,7 +619,7 @@ int I_OR_N() { PC = (PC + 1) & 0xFFFF; regs[REG_A] = (regs[REG_A] | tmp) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; return 7; } @@ -630,7 +629,7 @@ int I_CP_R() { int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; // F5 and F3 flags are set from the subtrahend instead of from the result. - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | (value & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[value]; return (lastOpcode == 0xBE) ? 7 : 4; } @@ -641,24 +640,23 @@ int I_CP_N() { int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; - // F5 and F3 flags are set from the subtrahend instead of from the result. - flags = (TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA])) | (value & (FLAG_X | FLAG_Y)); + flags = (TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA])) | TABLE_XY[value]; return 7; } int I_RLCA() { - regs[REG_A] = ((regs[REG_A] << 1) | (regs[REG_A] >>> 7)) & 0xFF; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | (regs[REG_A] & (FLAG_X | FLAG_Y | FLAG_C)); + regs[REG_A] = TABLE_RLCA[regs[REG_A]]; + flags = (flags & FLAG_SZP) | (regs[REG_A] & (FLAG_X | FLAG_Y | FLAG_C)); return 4; } int I_EX_AF_AFF() { - int tmp = regs[REG_A]; - regs[REG_A] = regs2[REG_A]; - regs2[REG_A] = tmp; - tmp = flags; - flags = flags2; - flags2 = tmp; + regs[REG_A] ^= regs2[REG_A]; + regs2[REG_A] ^= regs[REG_A]; + regs[REG_A] ^= regs2[REG_A]; + flags ^= flags2; + flags2 ^= flags; + flags ^= flags2; return 4; } @@ -670,14 +668,13 @@ int I_LD_A_REF_BC() { } int I_RRCA() { - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | (regs[REG_A] & FLAG_C); - regs[REG_A] = ((regs[REG_A] >>> 1) | (regs[REG_A] << 7)) & 0xFF; - flags |= (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = (flags & FLAG_SZP) | (regs[REG_A] & FLAG_C); + regs[REG_A] = TABLE_RRCA[regs[REG_A]]; + flags |= TABLE_XY[regs[REG_A]]; return 4; } int I_DJNZ() { - Q = 0; byte addr = memory.read(PC); PC = (PC + 1) & 0xFFFF; regs[REG_B] = (regs[REG_B] - 1) & 0xFF; @@ -692,6 +689,7 @@ int I_DJNZ() { int I_LD_REF_DE_A() { memory.write(getpair(1, false), (byte) regs[REG_A]); memptr = (regs[REG_A] << 8) | 2; + //_memPtr = A * 256 + ((DE + 1) & 0xFF); // Note for *BM1: MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = 0 return 7; } @@ -700,7 +698,7 @@ int I_RLA() { int res = ((regs[REG_A] << 1) | (flags & FLAG_C)) & 0xFF; int flagC = ((regs[REG_A] & 0x80) == 0x80) ? FLAG_C : 0; regs[REG_A] = res; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | flagC | (res & (FLAG_X | FLAG_Y)); + flags = (flags & FLAG_SZP) | flagC | TABLE_XY[res]; return 4; } @@ -714,7 +712,7 @@ int I_LD_A_REF_DE() { int I_RRA() { int res = ((regs[REG_A] >>> 1) | (flags << 7)) & 0xFF; int flagC = regs[REG_A] & FLAG_C; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | flagC | (res & (FLAG_X | FLAG_Y)); + flags = (flags & FLAG_SZP) | flagC | TABLE_XY[res]; regs[REG_A] = res; return 4; } @@ -738,7 +736,7 @@ int I_DAA() { regs[REG_A] = ((flags & FLAG_N) != 0 ? regs[REG_A] - d : regs[REG_A] + d) & 0xFF; flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] - | (regs[REG_A] & (FLAG_X | FLAG_Y)) + | TABLE_XY[regs[REG_A]] | ((regs[REG_A] ^ a) & FLAG_H) | (flags & FLAG_N) | c; @@ -749,25 +747,24 @@ int I_CPL() { regs[REG_A] = (~regs[REG_A]) & 0xFF; flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV | FLAG_C)) | FLAG_H | FLAG_N - | (regs[REG_A] & (FLAG_X | FLAG_Y)); + | TABLE_XY[regs[REG_A]]; return 4; } int I_SCF() { - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | (regs[REG_A] & (FLAG_X | FLAG_Y)) | FLAG_C; + flags = (flags & FLAG_SZP) | TABLE_XY[regs[REG_A]] | FLAG_C; return 4; } int I_CCF() { int c = flags & FLAG_C; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | (c << 4) - | (regs[REG_A] & (FLAG_X | FLAG_Y)) + flags = (flags & FLAG_SZP) | (c << 4) + | TABLE_XY[regs[REG_A]] | (c ^ FLAG_C); return 4; } int I_RET() { - Q = 0; PC = readWord(SP); memptr = PC; SP = (SP + 2) & 0xFFFF; @@ -775,35 +772,41 @@ int I_RET() { } int I_EXX() { - int tmp = regs[REG_B]; - regs[REG_B] = regs2[REG_B]; - regs2[REG_B] = tmp; - tmp = regs[REG_C]; - regs[REG_C] = regs2[REG_C]; - regs2[REG_C] = tmp; - tmp = regs[REG_D]; - regs[REG_D] = regs2[REG_D]; - regs2[REG_D] = tmp; - tmp = regs[REG_E]; - regs[REG_E] = regs2[REG_E]; - regs2[REG_E] = tmp; - tmp = regs[REG_H]; - regs[REG_H] = regs2[REG_H]; - regs2[REG_H] = tmp; - tmp = regs[REG_L]; - regs[REG_L] = regs2[REG_L]; - regs2[REG_L] = tmp; + // https://www.baeldung.com/java-swap-two-variables + regs[REG_B] ^= regs2[REG_B]; + regs2[REG_B] ^= regs[REG_B]; + regs[REG_B] ^= regs2[REG_B]; + + regs[REG_C] ^= regs2[REG_C]; + regs2[REG_C] ^= regs[REG_C]; + regs[REG_C] ^= regs2[REG_C]; + + regs[REG_D] ^= regs2[REG_D]; + regs2[REG_D] ^= regs[REG_D]; + regs[REG_D] ^= regs2[REG_D]; + + regs[REG_E] ^= regs2[REG_E]; + regs2[REG_E] ^= regs[REG_E]; + regs[REG_E] ^= regs2[REG_E]; + + regs[REG_H] ^= regs2[REG_H]; + regs2[REG_H] ^= regs[REG_H]; + regs[REG_H] ^= regs2[REG_H]; + + regs[REG_L] ^= regs2[REG_L]; + regs2[REG_L] ^= regs[REG_L]; + regs[REG_L] ^= regs2[REG_L]; return 4; } int I_EX_REF_SP_HL() { - byte tmp = memory.read(SP); - int x = (SP + 1) & 0xFFFF; - byte tmp1 = memory.read(x); + byte value = memory.read(SP); + int SP_plus1 = (SP + 1) & 0xFFFF; + byte value1 = memory.read(SP_plus1); memory.write(SP, (byte) regs[REG_L]); - memory.write(x, (byte) regs[REG_H]); - regs[REG_L] = tmp & 0xFF; - regs[REG_H] = tmp1 & 0xFF; + memory.write(SP_plus1, (byte) regs[REG_H]); + regs[REG_L] = value & 0xFF; + regs[REG_H] = value1 & 0xFF; memptr = (regs[REG_H] << 8) | regs[REG_L]; return 19; } @@ -814,12 +817,13 @@ int I_JP_REF_HL() { } int I_EX_DE_HL() { - int tmp = regs[REG_D]; - regs[REG_D] = regs[REG_H]; - regs[REG_H] = tmp; - tmp = regs[REG_E]; - regs[REG_E] = regs[REG_L]; - regs[REG_L] = tmp; + regs[REG_D] ^= regs[REG_H]; + regs[REG_H] ^= regs[REG_D]; + regs[REG_D] ^= regs[REG_H]; + + regs[REG_E] ^= regs[REG_L]; + regs[REG_L] ^= regs[REG_E]; + regs[REG_E] ^= regs[REG_L]; return 4; } @@ -835,7 +839,11 @@ int I_LD_SP_HL() { int I_EI() { // https://www.smspower.org/forums/2511-LDILDIRLDDLDDRCRCInZEXALL - // TODO: interrupts are not actually allowed until after the *next* instruction after EI. This is used to prevent interrupts from occuring between an EI/RETI pair used at the end of interrupt handlers. + // interrupts are not allowed until after the *next* instruction after EI. + // This is used to prevent interrupts from occurring between an EI/RETI pair used at the end of interrupt handlers. + if (!IFF[0]) { + interruptSkip = true; + } IFF[0] = IFF[1] = true; return 4; } @@ -846,7 +854,7 @@ int I_IN_R_REF_C() { if (reg == REG_A) { memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; } - flags = (flags & FLAG_C) | TABLE_SZ[regs[reg]] | EmulatorTables.PARITY_TABLE[regs[reg]]; + flags = (flags & FLAG_C) | TABLE_SZ[regs[reg]] | PARITY_TABLE[regs[reg]] | TABLE_XY[regs[reg]]; return 12; } @@ -900,7 +908,6 @@ int I_NEG() { } int I_RETN() { - Q = 0; IFF[0] = IFF[1]; PC = readWord(SP); SP = (SP + 2) & 0xffff; @@ -918,7 +925,6 @@ int I_LD_I_A() { } int I_RETI() { - Q = 0; IFF[0] = IFF[1]; PC = readWord(SP); memptr = PC; @@ -943,13 +949,13 @@ int I_IM_2() { int I_LD_A_I() { regs[REG_A] = I & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; return 9; } int I_LD_A_R() { regs[REG_A] = R & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; return 9; } @@ -961,7 +967,7 @@ int I_RRD() { regs[REG_A] = ((regs[REG_A] & 0xF0) | (value & 0x0F)); value = ((value >>> 4) & 0x0F) | (regA << 4); memory.write(hl, (byte) (value & 0xff)); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; return 18; } @@ -973,13 +979,13 @@ int I_RLD() { value = ((value << 4) & 0xF0) | (regs[REG_A] & 0x0F); regs[REG_A] = ((regs[REG_A] & 0xF0) | tmp1); memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) (value & 0xff)); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; return 18; } int I_IN_REF_C() { - int tmp = (context.readIO(regs[REG_C]) & 0xFF); - flags = TABLE_SZ[tmp] | PARITY_TABLE[tmp] | (flags & FLAG_C); + int tmp = context.readIO(regs[REG_C]) & 0xFF; + flags = TABLE_SZ[tmp] | PARITY_TABLE[tmp] | (flags & FLAG_C) | TABLE_XY[tmp]; return 12; } @@ -1132,23 +1138,35 @@ int I_LDD() { int I_LDDR() { int bc = (regs[REG_B] << 8) | regs[REG_C]; - if (bc != 1) { - memptr = (PC - 1) & 0xFFFF; - } + int de = (regs[REG_D] << 8) | regs[REG_E]; + int hl = (regs[REG_H] << 8) | regs[REG_L]; - I_LDD(); - if ((regs[REG_B] == 0) && (regs[REG_C] == 0)) { - return 16; - } - PC = (PC - 2) & 0xFFFF; + byte value = memory.read(hl); + memory.write(de, value); + + bc = (bc - 1) & 0xFFFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; + + hl = (hl - 1) & 0xFFFF; + de = (de - 1) & 0xFFFF; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_D] = (de >>> 8) & 0xFF; + regs[REG_E] = de & 0xFF; // https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags#interrupted-block-instructions - //YF = PC.13 - //XF = PC.11 - flags &= 0xD7; // reset P/V, X, Y - flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | (bc != 0 ? FLAG_PV : 0); + if (bc != 0) { + PC = (PC - 2) & 0xFFFF; + memptr = (PC + 1) & 0xFFFF; + flags |= TABLE_XY[PC >>> 8]; + return 21; + } - return 21; + value += regs[REG_A]; + flags |= (value & FLAG_X) | ((value & 0x02) != 0 ? FLAG_Y : 0); + return 16; } int I_LDI() { @@ -1175,43 +1193,36 @@ int I_LDI() { } int I_LDIR() { - int f = flags & (FLAG_S | FLAG_Z | FLAG_C); int bc = (regs[REG_B] << 8) | regs[REG_C]; int de = (regs[REG_D] << 8) | regs[REG_E]; int hl = (regs[REG_H] << 8) | regs[REG_L]; - if (bc != 1) { - memptr = (PC + 1) & 0xFFFF; - } + byte value = memory.read(hl); + memory.write(de, value); - int n = memory.read(hl) & 0xFF; - memory.write(de, (byte) n); + bc = (bc - 1) & 0xFFFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; hl = (hl + 1) & 0xFFFF; de = (de + 1) & 0xFFFF; - - int cycles; - if ((--bc) != 0) { - cycles = 21; - f |= FLAG_PV; - f |= ((PC >>> 8) & (FLAG_Y | FLAG_X)); - PC = (PC - 2) & 0xFFFF; - } else { - cycles = 16; - n += regs[REG_A]; - f |= n & FLAG_X; - f |= ((n << 4) & FLAG_Y); - } - regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_D] = (de >>> 8) & 0xFF; regs[REG_E] = de & 0xFF; - regs[REG_B] = (bc >>> 8) & 0xFF; - regs[REG_C] = bc & 0xFF; - flags = f; - return cycles; + // https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags#interrupted-block-instructions + flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | (bc != 0 ? FLAG_PV : 0); + if (bc != 0) { + PC = (PC - 2) & 0xFFFF; + memptr = (PC + 1) & 0xFFFF; + flags |= TABLE_XY[PC >>> 8]; + return 21; + } + + value += regs[REG_A]; + flags |= (value & FLAG_X) | ((value & 0x02) != 0 ? FLAG_Y : 0); + return 16; } public static String intToFlags(int flags) { @@ -1280,7 +1291,7 @@ int I_INIR() { PC = (PC - 2) & 0xFFFF; flags &= 0xD7; // reset X, Y - flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + flags |= TABLE_XY[PC >>> 8]; if ((flags & FLAG_C) == FLAG_C) { flags &= (~FLAG_H); if ((value & 0x80) != 0) { @@ -1331,7 +1342,7 @@ int I_INDR() { PC = (PC - 2) & 0xFFFF; flags &= 0xD7; // reset X, Y - flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + flags |= TABLE_XY[PC >>> 8]; if ((flags & FLAG_C) == FLAG_C) { flags &= (~FLAG_H); if ((value & 0x80) != 0) { @@ -1379,7 +1390,7 @@ int I_OTIR() { PC = (PC - 2) & 0xFFFF; flags &= 0xD7; // reset X, Y - flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + flags |= TABLE_XY[PC >>> 8]; if ((flags & FLAG_C) == FLAG_C) { flags &= (~FLAG_H); if ((value & 0x80) != 0) { @@ -1427,7 +1438,7 @@ int I_OTDR() { PC = (PC - 2) & 0xFFFF; flags &= 0xD7; // reset X, Y - flags |= ((PC >>> 8) & (FLAG_X | FLAG_Y)); + flags |= TABLE_XY[PC >>> 8]; if ((flags & FLAG_C) == FLAG_C) { flags &= (~FLAG_H); if ((value & 0x80) != 0) { @@ -1462,7 +1473,6 @@ int I_LD_RP_REF_NN() { } int I_JR_CC_N() { - Q = 0; int addr = memory.read(PC); PC = (PC + 1) & 0xFFFF; memptr = PC; @@ -1508,7 +1518,7 @@ int I_SUB_N() { int sum = (oldA - value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; return 7; } @@ -1600,7 +1610,6 @@ int I_CALL_NN() { } int I_LD_R_R() { - Q = 0; int tmp = (lastOpcode >>> 3) & 0x07; int tmp1 = lastOpcode & 0x07; putreg(tmp, getreg(tmp1)); @@ -1627,7 +1636,7 @@ int I_RLC_R() { int flagC = ((regValue & 0x80) != 0) ? FLAG_C : 0; regValue = ((regValue << 1) | (regValue >>> 7)) & 0xFF; putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; if (reg == 6) { return 15; @@ -1642,7 +1651,7 @@ int I_RRC_R() { int flagC = regValue & FLAG_C; regValue = ((regValue >>> 1) | (regValue << 7)) & 0xFF; putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; if (reg == 6) { return 15; @@ -1657,7 +1666,7 @@ int I_RL_R() { int flagC = ((regValue & 0x80) == 0x80) ? FLAG_C : 0; regValue = ((regValue << 1) | (flags & FLAG_C)) & 0xFF; putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; if (reg == 6) { return 15; @@ -1672,7 +1681,7 @@ int I_RR_R() { int flagC = regValue & FLAG_C; regValue = ((regValue >>> 1) | (flags << 7)) & 0xFF; putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; if (reg == 6) { return 15; @@ -1688,7 +1697,7 @@ int I_SLA_R() { int flagC = ((regValue & 0x80) == 0x80) ? FLAG_C : 0; regValue = (regValue << 1) & 0xFF; putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; if (reg == 6) { return 15; @@ -1703,7 +1712,7 @@ int I_SRA_R() { int flagC = regValue & FLAG_C; regValue = ((regValue >>> 1) | (regValue & 0x80)) & 0xFF; putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; if (reg == 6) { return 15; @@ -1718,7 +1727,7 @@ int I_SLL_R() { int flagC = ((regValue & 0x80) != 0) ? FLAG_C : 0; regValue = ((regValue << 1) | 0x01) & 0xFF; putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; if (reg == 6) { return 15; @@ -1733,7 +1742,7 @@ int I_SRL_R() { int flagC = regValue & FLAG_C; regValue = (regValue >>> 1) & 0xFF; putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | (regValue & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; if (reg == 6) { return 15; @@ -1742,7 +1751,6 @@ int I_SRL_R() { } } - int I_BIT_N_R() { int bit = (lastOpcode >>> 3) & 7; int reg = lastOpcode & 7; @@ -1750,7 +1758,7 @@ int I_BIT_N_R() { int result = (1 << bit) & regValue; flags = ((result != 0) ? (result & FLAG_S) : (FLAG_Z | FLAG_PV)) - | (regValue & (FLAG_X | FLAG_Y)) + | TABLE_XY[regValue] | FLAG_H | (flags & FLAG_C); @@ -1818,9 +1826,9 @@ int I_ADD_II_RP(int special) { } int res = special + dstRp; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV)) | + flags = (flags & FLAG_SZP) | (((dstRp ^ res ^ special) >>> 8) & FLAG_H) | - ((res >>> 16) & FLAG_C) | ((res >>> 8) & (FLAG_Y | FLAG_X)); + ((res >>> 16) & FLAG_C) | TABLE_XY[(res >>> 8) & 0xFF]; return res & 0xFFFF; } @@ -1904,7 +1912,7 @@ int I_INC_REF_II_N(int special) { int sum = (value + 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | (sum & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | TABLE_XY[sumByte]; memory.write(address, (byte) sumByte); return 23; @@ -1928,7 +1936,7 @@ int I_DEC_REF_II_N(int special) { int sum = (value - 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | (sum & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | TABLE_XY[sumByte]; memory.write(address, (byte) sumByte); return 23; } @@ -1942,7 +1950,6 @@ int I_LD_REF_IY_N_N() { } int I_LD_REF_II_N_N(int special) { - Q = 0; byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; byte number = memory.read(PC); @@ -2006,7 +2013,7 @@ int I_ADD_A_REF_II_N(int special) { int oldA = regs[REG_A]; int sum = (oldA + value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; return 19; } @@ -2028,7 +2035,7 @@ int I_ADC_A_REF_II_N(int special) { int oldA = regs[REG_A]; int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; return 19; } @@ -2051,7 +2058,7 @@ int I_SUB_REF_II_N(int special) { int sum = (oldA - value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; return 19; } @@ -2074,7 +2081,7 @@ int I_SBC_A_REF_II_N(int special) { int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; return 19; } @@ -2093,7 +2100,7 @@ int I_AND_REF_II_N(int special) { memptr = address; int value = memory.read(address); regs[REG_A] = (regs[REG_A] & value) & 0xFF; - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H | TABLE_XY[regs[REG_A]]; return 19; } @@ -2112,7 +2119,7 @@ int I_XOR_REF_II_N(int special) { memptr = address; byte value = memory.read(address); regs[REG_A] = ((regs[REG_A] ^ value) & 0xff); - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | TABLE_XY[regs[REG_A]]; return 19; } @@ -2131,7 +2138,7 @@ int I_OR_REF_II_N(int special) { memptr = address; byte value = memory.read(address); regs[REG_A] = ((regs[REG_A] | value) & 0xff); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; return 19; } @@ -2152,7 +2159,7 @@ int I_CP_REF_II_N(int special) { int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | (value & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; return 19; } @@ -2234,7 +2241,7 @@ int I_RLC_REF_II_N_R(byte operand, int special) { int c = ((addrValue & 0x80) != 0) ? FLAG_C : 0; int res = ((addrValue << 1) | (addrValue >>> 7)) & 0xFF; memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | TABLE_XY[res]; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; @@ -2257,7 +2264,7 @@ int I_RRC_REF_II_N_R(byte operand, int special) { int c = addrValue & 1; int res = (((addrValue >>> 1) & 0x7F) | (c << 7)) & 0xFF; memory.write(addr, (byte) (res & 0xFF)); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; @@ -2281,7 +2288,7 @@ int I_RL_REF_II_N_R(byte operand, int special) { int res = ((((addrValue << 1) & 0xFF) | flags & FLAG_C) & 0xFF); memory.write(addr, (byte) (res & 0xFF)); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; return 23; @@ -2304,7 +2311,7 @@ int I_RR_REF_II_N_R(byte operand, int special) { int res = ((((addrValue >> 1) & 0xFF) | (flags & FLAG_C) << 7) & 0xFF); memory.write(addr, (byte) (res & 0xFF)); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; return 23; @@ -2326,7 +2333,7 @@ int I_SLA_REF_II_N_R(byte operand, int special) { int c = (addrValue >>> 7) & 1; int res = (addrValue << 1) & 0xFE; memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; @@ -2350,7 +2357,7 @@ int I_SRA_REF_II_N_R(byte operand, int special) { int res = (addrValue >> 1) & 0xFF | (addrValue & 0x80); memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res & 0xFF; return 23; @@ -2373,7 +2380,7 @@ int I_SLL_REF_II_N_R(byte operand, int special) { int res = ((addrValue << 1) | 0x01) & 0xFF; memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | TABLE_XY[res]; // regs[6] is unused, so it's ok regs[lastOpcode & 7] = res; @@ -2397,7 +2404,7 @@ int I_SRL_REF_II_N_R(byte operand, int special) { int res = (addrValue >>> 1) & 0xFF; memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | (res & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | TABLE_XY[res]; // regs[6] is unused, so it's ok to set it regs[lastOpcode & 7] = res; return 23; @@ -2421,7 +2428,7 @@ int I_BIT_N_REF_II_N(byte operand, int special) { flags = ((flags & FLAG_C) | FLAG_H | ((result == 0) ? (FLAG_Z | FLAG_PV) : 0)) - | (special & (FLAG_X | FLAG_Y)); + | TABLE_XY[special & 0xFF]; if (bit == 7) { flags |= ((result == 0x80) ? FLAG_S : 0); } @@ -2493,7 +2500,7 @@ int I_INC_IYL() { int I_INC(int value) { int sum = (value + 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | (sum & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | TABLE_XY[sumByte]; return sumByte; } @@ -2511,7 +2518,7 @@ int I_DEC_IIH(int special) { int reg = special >>> 8; int sum = (reg - 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C) | (sum & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C) | TABLE_XY[sumByte]; return sumByte; } @@ -2529,7 +2536,7 @@ int I_DEC_IIL(int special) { int reg = special & 0xFF; int sum = (reg - 1) & 0x1FF; int sumByte = sum & 0xFF; - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C) | (sum & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C) | TABLE_XY[sumByte]; return sumByte; } @@ -2657,7 +2664,7 @@ int I_ADD_A(int value) { int oldA = regs[REG_A]; int sum = (oldA + value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (sum & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; return 8; } @@ -2681,7 +2688,7 @@ int I_ADC_A(int value) { int oldA = regs[REG_A]; int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | (sum & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; return 8; } @@ -2706,7 +2713,7 @@ int I_SUB(int value) { int sum = (oldA - value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (sum & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; return 8; } @@ -2730,7 +2737,7 @@ int I_SBC_A(int value) { int oldA = regs[REG_A]; int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | (sum & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; return 8; } @@ -2752,7 +2759,7 @@ int I_AND_IYL() { int I_AND(int value) { regs[REG_A] = (regs[REG_A] & value) & 0xFF; - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H | TABLE_XY[regs[REG_A]]; return 8; } @@ -2774,7 +2781,7 @@ int I_XOR_IYL() { int I_XOR(int value) { regs[REG_A] = (regs[REG_A] ^ value) & 0xFF; - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | TABLE_XY[regs[REG_A]]; return 8; } @@ -2796,7 +2803,7 @@ int I_OR_IYL() { int I_OR(int value) { regs[REG_A] = (regs[REG_A] | value) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (regs[REG_A] & (FLAG_X | FLAG_Y)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; return 8; } @@ -2820,7 +2827,7 @@ int I_CP(int value) { int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | (value & (FLAG_X | FLAG_Y)); + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[value & 0xFF]; return 8; } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java index f9f7ad5bf..f60164596 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java @@ -20,7 +20,7 @@ class EmulatorTables { - public final static int[] TABLE_SUB = new int[] { + public final static int[] TABLE_SUB = new int[]{ 0x42, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, @@ -38,7 +38,7 @@ class EmulatorTables { 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82 }; - public final static int[] TABLE_CHP = new int[] { + public final static int[] TABLE_CHP = new int[]{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @@ -73,7 +73,7 @@ class EmulatorTables { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }; - public final static int[] TABLE_HP = new int[] { + public final static int[] TABLE_HP = new int[]{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @@ -108,7 +108,7 @@ class EmulatorTables { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }; - public final static int[] TABLE_SZ = new int[] { + public final static int[] TABLE_SZ = new int[]{ 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @@ -134,24 +134,60 @@ class EmulatorTables { 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4 }; - final static int[] AND_OR_XOR_TABLE = new int[]{ - 84, 16, 16, 20, 16, 20, 20, 16, 16, 20, 20, 16, 20, 16, 16, 20, 16, 20, 20, 16, 20, 16, 16, 20, 20, 16, 16, 20, 16, 20, - 20, 16, 16, 20, 20, 16, 20, 16, 16, 20, 20, 16, 16, 20, 16, 20, 20, 16, 20, 16, 16, 20, 16, 20, 20, 16, 16, 20, 20, 16, - 20, 16, 16, 20, 16, 20, 20, 16, 20, 16, 16, 20, 20, 16, 16, 20, 16, 20, 20, 16, 20, 16, 16, 20, 16, 20, 20, 16, 16, 20, - 20, 16, 20, 16, 16, 20, 20, 16, 16, 20, 16, 20, 20, 16, 16, 20, 20, 16, 20, 16, 16, 20, 16, 20, 20, 16, 20, 16, 16, 20, - 20, 16, 16, 20, 16, 20, 20, 16, 144, 148, 148, 144, 148, 144, 144, 148, 148, 144, 144, 148, 144, 148, 148, 144, 148, 144, 144, 148, 144, 148, - 148, 144, 144, 148, 148, 144, 148, 144, 144, 148, 148, 144, 144, 148, 144, 148, 148, 144, 144, 148, 148, 144, 148, 144, 144, 148, 144, 148, 148, 144, - 148, 144, 144, 148, 148, 144, 144, 148, 144, 148, 148, 144, 148, 144, 144, 148, 144, 148, 148, 144, 144, 148, 148, 144, 148, 144, 144, 148, 144, 148, - 148, 144, 148, 144, 144, 148, 148, 144, 144, 148, 144, 148, 148, 144, 144, 148, 148, 144, 148, 144, 144, 148, 148, 144, 144, 148, 144, 148, 148, 144, - 148, 144, 144, 148, 144, 148, 148, 144, 144, 148, 148, 144, 148, 144, 144, 148,}; + public final static int[] TABLE_XY = new int[]{ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + }; + + public final static int[] TABLE_RRCA = new int[] { + 0x0, 0x80, 0x1, 0x81, 0x2, 0x82, 0x3, 0x83, 0x4, 0x84, 0x5, 0x85, 0x6, 0x86, 0x7, 0x87, + 0x8, 0x88, 0x9, 0x89, 0xa, 0x8a, 0xb, 0x8b, 0xc, 0x8c, 0xd, 0x8d, 0xe, 0x8e, 0xf, 0x8f, + 0x10, 0x90, 0x11, 0x91, 0x12, 0x92, 0x13, 0x93, 0x14, 0x94, 0x15, 0x95, 0x16, 0x96, 0x17, 0x97, + 0x18, 0x98, 0x19, 0x99, 0x1a, 0x9a, 0x1b, 0x9b, 0x1c, 0x9c, 0x1d, 0x9d, 0x1e, 0x9e, 0x1f, 0x9f, + 0x20, 0xa0, 0x21, 0xa1, 0x22, 0xa2, 0x23, 0xa3, 0x24, 0xa4, 0x25, 0xa5, 0x26, 0xa6, 0x27, 0xa7, + 0x28, 0xa8, 0x29, 0xa9, 0x2a, 0xaa, 0x2b, 0xab, 0x2c, 0xac, 0x2d, 0xad, 0x2e, 0xae, 0x2f, 0xaf, + 0x30, 0xb0, 0x31, 0xb1, 0x32, 0xb2, 0x33, 0xb3, 0x34, 0xb4, 0x35, 0xb5, 0x36, 0xb6, 0x37, 0xb7, + 0x38, 0xb8, 0x39, 0xb9, 0x3a, 0xba, 0x3b, 0xbb, 0x3c, 0xbc, 0x3d, 0xbd, 0x3e, 0xbe, 0x3f, 0xbf, + 0x40, 0xc0, 0x41, 0xc1, 0x42, 0xc2, 0x43, 0xc3, 0x44, 0xc4, 0x45, 0xc5, 0x46, 0xc6, 0x47, 0xc7, + 0x48, 0xc8, 0x49, 0xc9, 0x4a, 0xca, 0x4b, 0xcb, 0x4c, 0xcc, 0x4d, 0xcd, 0x4e, 0xce, 0x4f, 0xcf, + 0x50, 0xd0, 0x51, 0xd1, 0x52, 0xd2, 0x53, 0xd3, 0x54, 0xd4, 0x55, 0xd5, 0x56, 0xd6, 0x57, 0xd7, + 0x58, 0xd8, 0x59, 0xd9, 0x5a, 0xda, 0x5b, 0xdb, 0x5c, 0xdc, 0x5d, 0xdd, 0x5e, 0xde, 0x5f, 0xdf, + 0x60, 0xe0, 0x61, 0xe1, 0x62, 0xe2, 0x63, 0xe3, 0x64, 0xe4, 0x65, 0xe5, 0x66, 0xe6, 0x67, 0xe7, + 0x68, 0xe8, 0x69, 0xe9, 0x6a, 0xea, 0x6b, 0xeb, 0x6c, 0xec, 0x6d, 0xed, 0x6e, 0xee, 0x6f, 0xef, + 0x70, 0xf0, 0x71, 0xf1, 0x72, 0xf2, 0x73, 0xf3, 0x74, 0xf4, 0x75, 0xf5, 0x76, 0xf6, 0x77, 0xf7, + 0x78, 0xf8, 0x79, 0xf9, 0x7a, 0xfa, 0x7b, 0xfb, 0x7c, 0xfc, 0x7d, 0xfd, 0x7e, 0xfe, 0x7f, 0xff, + }; - // rrcaTable[i] = ((i & 1) << 7)|(i>>1); - final static short[] RRCA_TABLE = { - 0, 128, 1, 129, 2, 130, 3, 131, 4, 132, 5, 133, 6, 134, 7, 135, 8, 136, 9, 137, 10, 138, 11, 139, 12, 140, 13, 141, 14, 142, 15, 143, 16, 144, 17, 145, 18, 146, 19, 147, 20, 148, 21, 149, 22, 150, - 23, 151, 24, 152, 25, 153, 26, 154, 27, 155, 28, 156, 29, 157, 30, 158, 31, 159, 32, 160, 33, 161, 34, 162, 35, 163, 36, 164, 37, 165, 38, 166, 39, 167, 40, 168, 41, 169, 42, 170, 43, 171, 44, 172, 45, - 173, 46, 174, 47, 175, 48, 176, 49, 177, 50, 178, 51, 179, 52, 180, 53, 181, 54, 182, 55, 183, 56, 184, 57, 185, 58, 186, 59, 187, 60, 188, 61, 189, 62, 190, 63, 191, 64, 192, 65, 193, 66, 194, 67, 195, - 68, 196, 69, 197, 70, 198, 71, 199, 72, 200, 73, 201, 74, 202, 75, 203, 76, 204, 77, 205, 78, 206, 79, 207, 80, 208, 81, 209, 82, 210, 83, 211, 84, 212, 85, 213, 86, 214, 87, 215, 88, 216, 89, 217, 90, - 218, 91, 219, 92, 220, 93, 221, 94, 222, 95, 223, 96, 224, 97, 225, 98, 226, 99, 227, 100, 228, 101, 229, 102, 230, 103, 231, 104, 232, 105, 233, 106, 234, 107, 235, 108, 236, 109, 237, 110, 238, 111, 239, 112, 240, - 113, 241, 114, 242, 115, 243, 116, 244, 117, 245, 118, 246, 119, 247, 120, 248, 121, 249, 122, 250, 123, 251, 124, 252, 125, 253, 126, 254, 127, 255 + public final static int[] TABLE_RLCA = new int[] { + 0x0, 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, + 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, + 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, + 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, + 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, + 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f, + 0x21, 0x23, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b, 0x3d, 0x3f, + 0x41, 0x43, 0x45, 0x47, 0x49, 0x4b, 0x4d, 0x4f, 0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, 0x5f, + 0x61, 0x63, 0x65, 0x67, 0x69, 0x6b, 0x6d, 0x6f, 0x71, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d, 0x7f, + 0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9f, + 0xa1, 0xa3, 0xa5, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb1, 0xb3, 0xb5, 0xb7, 0xb9, 0xbb, 0xbd, 0xbf, + 0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf, 0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf, + 0xe1, 0xe3, 0xe5, 0xe7, 0xe9, 0xeb, 0xed, 0xef, 0xf1, 0xf3, 0xf5, 0xf7, 0xf9, 0xfb, 0xfd, 0xff, }; } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java index 6c4eadf99..7da1a6583 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java @@ -102,4 +102,60 @@ public void generateTableHP() { System.out.println(table); } + @Test + public void generateTableXY() { + StringBuilder table = new StringBuilder("public final static int[] TABLE_XY = new int[] {\n "); + + int i = 0; + for (int sum = 0; sum <= 0xFF; sum++) { + int flagXY = sum & (FLAG_X | FLAG_Y); + table.append("0x") + .append(Integer.toHexString(flagXY)) + .append(", "); + if (i++ == 15) { + table.append("\n "); + i = 0; + } + } + table.append("};\n"); + System.out.println(table); + } + + @Test + public void generateRrcaTable() { + StringBuilder table = new StringBuilder("public final static int[] TABLE_RRCA = new int[] {\n "); + + int i = 0; + for (int value = 0; value <= 0xFF; value++) { + int rrca = ((value >>> 1) | (value << 7)) & 0xFF; + table.append("0x") + .append(Integer.toHexString(rrca)) + .append(", "); + if (i++ == 15) { + table.append("\n "); + i = 0; + } + } + table.append("};\n"); + System.out.println(table); + } + + @Test + public void generateRlcaTable() { + StringBuilder table = new StringBuilder("public final static int[] TABLE_RLCA = new int[] {\n "); + + int i = 0; + for (int value = 0; value <= 0xFF; value++) { + int rrca = ((value << 1) | (value >>> 7)) & 0xFF; + table.append("0x") + .append(Integer.toHexString(rrca)) + .append(", "); + if (i++ == 15) { + table.append("\n "); + i = 0; + } + } + table.append("};\n"); + System.out.println(table); + } } From 46a31f33c7b1bac9d97552e82d54bfb9a3a12a8e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 10 Sep 2022 12:31:42 +0200 Subject: [PATCH 208/314] [#175] simh-pseudo: fixed getHostFilenames --- .../plugins/device/simh/CpmUtils.java | 2 +- .../simh/commands/GetHostFilenames.java | 71 ++++++++++++------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java index da1c18c64..64bf6029d 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/CpmUtils.java @@ -24,7 +24,7 @@ public class CpmUtils { private final static int CPM_COMMAND_LINE_LENGTH = 128; public static final char[] cpmCommandLine = new char[CPM_COMMAND_LINE_LENGTH]; - public static void createCPMCommandLine(MemoryContext memory) { + public static void readCPMCommandLine(MemoryContext memory) { int i; int len = memory.read(0x80) & 0x7F; // 0x80 contains length of command line, discard first char for (i = 0; i < len - 1; i++) { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java index b8f0e62bf..80c7ea6e8 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java @@ -21,14 +21,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.naming.Name; import java.io.File; import java.io.IOException; +import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; -import java.util.stream.Stream; +import java.nio.file.Paths; +import java.util.Arrays; import static net.emustudio.plugins.device.simh.CpmUtils.cpmCommandLine; -import static net.emustudio.plugins.device.simh.CpmUtils.createCPMCommandLine; +import static net.emustudio.plugins.device.simh.CpmUtils.readCPMCommandLine; public class GetHostFilenames implements Command { public final static GetHostFilenames INS = new GetHostFilenames(); @@ -37,7 +40,7 @@ public class GetHostFilenames implements Command { // support for wild card file expansion public final static char hostPathSeparator = File.separatorChar; - private final static char hostPathSeparatorAlt = File.separatorChar; + public final static String hostPathSeparatorStr = String.valueOf(hostPathSeparator); private NameNode nameListHead; private NameNode currentName; @@ -45,7 +48,6 @@ public class GetHostFilenames implements Command { private int lastPathSeparatorIndex = 0; private int firstPathCharacterIndex = 0; - static class NameNode { char[] name; NameNode next; @@ -59,7 +61,6 @@ public NameNode(char[] name, NameNode next) { @Override public void reset(Control control) { deleteNameList(); - nameListHead = null; } @Override @@ -69,15 +70,16 @@ public byte read(Control control) { if (currentName == null) { deleteNameList(); control.clearCommand(); - } else if (firstPathCharacterIndex <= lastPathSeparatorIndex) + } else if (firstPathCharacterIndex <= lastPathSeparatorIndex) { result = (byte) cpmCommandLine[firstPathCharacterIndex++]; - else { - result = (byte) currentName.name[currentNameIndex]; - if (result == 0) { + } else { + if (currentNameIndex == currentName.name.length) { currentName = currentName.next; firstPathCharacterIndex = currentNameIndex = 0; - } else - currentNameIndex++; + return 0; + } + result = (byte) currentName.name[currentNameIndex]; + currentNameIndex++; } } return result; @@ -86,13 +88,12 @@ public byte read(Control control) { @Override public void start(Control control) { if (nameListHead == null) { - createCPMCommandLine(control.getMemory()); + readCPMCommandLine(control.getMemory()); lastPathSeparatorIndex = 0; - while (cpmCommandLine[lastPathSeparatorIndex] != 0) + while (cpmCommandLine[lastPathSeparatorIndex] != 0) { lastPathSeparatorIndex++; - while ((lastPathSeparatorIndex >= 0) && - (cpmCommandLine[lastPathSeparatorIndex] != hostPathSeparator) && - (cpmCommandLine[lastPathSeparatorIndex] != hostPathSeparatorAlt)) { + } + while ((lastPathSeparatorIndex >= 0) && (cpmCommandLine[lastPathSeparatorIndex] != hostPathSeparator)) { lastPathSeparatorIndex--; } firstPathCharacterIndex = 0; @@ -105,14 +106,38 @@ public void start(Control control) { } private void deleteNameList() { - while (nameListHead != null) { - nameListHead = nameListHead.next; - } + nameListHead = null; currentName = null; currentNameIndex = 0; } private void fillupNameList() { + String cmdLine = cpmCmdLineToString(); + if (cmdLine.endsWith(hostPathSeparatorStr)) { + nameListHead = new NameNode(new char[]{}, nameListHead); // simulating exact simh behavior + } else { + String[] parts = cmdLine.split(hostPathSeparatorStr); // all path parts must be moved to basePath + + StringBuilder basePathPostfixBuilder = new StringBuilder(); + for (int i = 0; i < parts.length - 1; i++) { + basePathPostfixBuilder.append(parts[i]).append(hostPathSeparator); + } + Path basePath = Paths.get(System.getProperty("user.dir")); + basePath = basePath.resolve(basePathPostfixBuilder.toString()); + String pattern = parts[parts.length - 1]; + + try (DirectoryStream dirStream = Files.newDirectoryStream(basePath, pattern)) { + dirStream.forEach(p -> { + nameListHead = new NameNode(p.getFileName().toString().toCharArray(), nameListHead); + }); + } catch (IOException e) { + LOGGER.error("SIMH: Could not list host files", e); + deleteNameList(); + } + } + } + + private String cpmCmdLineToString() { StringBuilder pb = new StringBuilder(); for (char c : cpmCommandLine) { if (c != 0) { @@ -121,12 +146,6 @@ private void fillupNameList() { break; } } - String path = pb.toString(); - try (Stream paths = Files.list(Path.of(path))) { - paths.forEach(p -> nameListHead = new NameNode(p.getFileName().toString().toCharArray(), nameListHead)); - } catch (IOException e) { - LOGGER.error("SIMH: Could not list host files", e); - deleteNameList(); - } + return pb.toString(); } } From 7993a04bd03bb634c27670ef079edef5a8f57e76 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 12 Sep 2022 10:54:09 +0200 Subject: [PATCH 209/314] [#274] ADM-3A precise frequency drawing --- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 8 +- .../plugins/device/adm3a/DeviceImpl.java | 78 +++---- .../device/adm3a/api/ContextAdm3A.java | 77 +++++++ .../plugins/device/adm3a/api/Keyboard.java | 24 ++ .../device/adm3a/api/OutputProvider.java | 22 ++ .../device/adm3a/gui/ConfigDialog.java | 27 +-- .../device/adm3a/gui/DisplayCanvas.java | 169 ++++++++++++++ .../DisplayParameters.java | 2 +- .../plugins/device/adm3a/gui/GuiUtils.java | 29 +++ .../device/adm3a/gui/TerminalWindow.java | 22 +- .../device/adm3a/interaction/Display.java | 212 +++--------------- .../device/adm3a/interaction/Keyboard.java | 34 --- .../adm3a/interaction/KeyboardFromFile.java | 46 +--- .../device/adm3a/interaction/KeyboardGui.java | 68 ++---- .../plugins/device/simh/PseudoContext.java | 2 +- .../device/simh/commands/SIMHSleep.java | 2 +- 16 files changed, 445 insertions(+), 377 deletions(-) create mode 100644 plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java create mode 100644 plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/Keyboard.java create mode 100644 plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/OutputProvider.java create mode 100644 plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java rename plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/{interaction => gui}/DisplayParameters.java (94%) create mode 100644 plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/GuiUtils.java delete mode 100644 plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Keyboard.java diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 22eb650d2..76afb9906 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -45,7 +45,7 @@ * (parallel with other hardware) */ // TODO: set frequency runtime -@SuppressWarnings("unused") +//@SuppressWarnings("unused") public class EmulatorEngine implements CpuEngine { private final static Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); @@ -85,7 +85,7 @@ public class EmulatorEngine implements CpuEngine { private final AtomicBoolean pendingNonMaskableInterrupt = new AtomicBoolean(); private RunState currentRunState = RunState.STATE_STOPPED_NORMAL; - private long executedCycles = 0; + private volatile long executedCycles = 0; private volatile DispatchListener dispatchListener; @@ -111,10 +111,6 @@ public void addFrequencyChangedListener(FrequencyChangedListener listener) { frequencyChangedListeners.add(listener); } - public void removeFrequencyChangedListener(FrequencyChangedListener listener) { - frequencyChangedListeners.remove(listener); - } - @Override public void fireFrequencyChanged(float newFrequency) { for (FrequencyChangedListener listener : frequencyChangedListeners) { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index 38f97adac..469694448 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -25,7 +25,10 @@ import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.emulib.runtime.*; import net.emustudio.emulib.runtime.settings.PluginSettings; +import net.emustudio.plugins.device.adm3a.api.ContextAdm3A; +import net.emustudio.plugins.device.adm3a.api.Keyboard; import net.emustudio.plugins.device.adm3a.gui.ConfigDialog; +import net.emustudio.plugins.device.adm3a.gui.GuiUtils; import net.emustudio.plugins.device.adm3a.gui.TerminalWindow; import net.emustudio.plugins.device.adm3a.interaction.*; import org.slf4j.Logger; @@ -40,26 +43,36 @@ type = PLUGIN_TYPE.DEVICE, title = "LSI ADM-3A terminal" ) -@SuppressWarnings("unused") public class DeviceImpl extends AbstractDevice implements TerminalSettings.ChangedObserver { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceImpl.class); private static final int COLUMNS_COUNT = 80; private static final int ROWS_COUNT = 24; - private final Display display; - private final Cursor cursor = new Cursor(COLUMNS_COUNT, ROWS_COUNT); private final TerminalSettings terminalSettings; + private final ContextAdm3A terminalContext; + private final Keyboard keyboard; + + private boolean guiIOset = false; + private final Display display; private TerminalWindow terminalGUI; - private Keyboard keyboard; public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); terminalSettings = new TerminalSettings(settings, applicationApi.getDialogs()); - display = new Display(cursor, terminalSettings); + Cursor cursor = new Cursor(COLUMNS_COUNT, ROWS_COUNT); + this.display = new Display(cursor, terminalSettings); + if (terminalSettings.isGuiSupported()) { + LOGGER.debug("Creating GUI-based keyboard"); + this.keyboard = new KeyboardGui(cursor); + } else { + LOGGER.debug("Creating file-based keyboard ({})", terminalSettings.getInputPath()); + this.keyboard = new KeyboardFromFile(terminalSettings.getInputPath(), terminalSettings.getInputReadDelay()); + } + this.terminalContext = new ContextAdm3A(this.keyboard, terminalSettings); try { - applicationApi.getContextPool().register(pluginID, display, DeviceContext.class); + applicationApi.getContextPool().register(pluginID, terminalContext, DeviceContext.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register ADM-3A terminal", e); applicationApi.getDialogs().showError( @@ -71,19 +84,8 @@ public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s @SuppressWarnings("unchecked") @Override public void initialize() throws PluginInitializationException { - if (terminalSettings.isGuiSupported()) { - LOGGER.debug("Creating GUI-based keyboard"); - keyboard = new KeyboardGui(cursor); - } else { - LOGGER.debug("Creating file-based keyboard ({})", terminalSettings.getInputPath()); - keyboard = new KeyboardFromFile(terminalSettings.getInputPath(), terminalSettings.getInputReadDelay()); - } - if (terminalSettings.isHalfDuplex()) { - keyboard.connect(display); - } - - // try to connect to a serial I/O board try { + // get serial I/O board DeviceContext device = applicationApi.getContextPool().getDeviceContext( pluginID, DeviceContext.class, terminalSettings.getDeviceIndex() ); @@ -92,7 +94,8 @@ public void initialize() throws PluginInitializationException { "Unexpected device data type. Expected Byte but was: " + device.getDataType() ); } - keyboard.connect(device); + terminalContext.setExternalDevice(device); + terminalContext.setDisplay(display); } catch (ContextNotFoundException e) { LOGGER.warn("The terminal is not connected to any I/O device."); } @@ -103,13 +106,14 @@ public void initialize() throws PluginInitializationException { @Override public void showGUI(JFrame parent) { - if (terminalSettings.isGuiSupported()) { - if (terminalGUI == null) { - terminalGUI = new TerminalWindow(parent, display); - terminalGUI.setAlwaysOnTop(terminalSettings.isAlwaysOnTop()); - ((KeyboardGui)keyboard).addListenerRecursively(terminalGUI); - display.startCursor(); - } + if (guiIOset) { + terminalGUI.setVisible(true); + } else if (terminalSettings.isGuiSupported()) { + terminalGUI = new TerminalWindow(parent, display); + terminalGUI.setAlwaysOnTop(terminalSettings.isAlwaysOnTop()); + GuiUtils.addListenerRecursively(terminalGUI, (KeyboardGui) keyboard); + terminalGUI.startPainting(); + guiIOset = true; terminalGUI.setVisible(true); } } @@ -121,10 +125,11 @@ public boolean isGuiSupported() { @Override public void reset() { - display.clearScreen(); + if (terminalGUI != null) { + terminalGUI.clearScreen(); + } } - @Override public String getVersion() { return getResourceBundle().map(b -> b.getString("version")).orElse("(unknown)"); @@ -143,16 +148,18 @@ public String getDescription() { @Override public void destroy() { terminalSettings.removeChangedObserver(this); + if (keyboard != null) { + keyboard.close(); + } if (terminalGUI != null) { terminalGUI.destroy(); } - display.destroy(); } @Override public void showSettings(JFrame parent) { if (isShowSettingsSupported()) { - new ConfigDialog(parent, terminalSettings, terminalGUI, display, applicationApi.getDialogs()).setVisible(true); + new ConfigDialog(parent, terminalSettings, terminalGUI, applicationApi.getDialogs()).setVisible(true); } } @@ -163,11 +170,6 @@ public boolean isShowSettingsSupported() { @Override public void settingsChanged() { - if (terminalSettings.isHalfDuplex()) { - keyboard.connect(display); - } else { - keyboard.disconnect(display); - } if (terminalGUI != null) { terminalGUI.setAlwaysOnTop(terminalSettings.isAlwaysOnTop()); } @@ -180,10 +182,4 @@ private Optional getResourceBundle() { return Optional.empty(); } } - - private void destroyKeyboard() { - if (keyboard != null) { - keyboard.destroy(); - } - } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java new file mode 100644 index 000000000..15a5aacb4 --- /dev/null +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java @@ -0,0 +1,77 @@ +package net.emustudio.plugins.device.adm3a.api; + +import net.emustudio.emulib.plugins.device.DeviceContext; +import net.emustudio.plugins.device.adm3a.TerminalSettings; +import net.jcip.annotations.ThreadSafe; + +import java.util.Objects; + +@ThreadSafe +public class ContextAdm3A implements DeviceContext, AutoCloseable { + private final Keyboard keyboard; + private final TerminalSettings settings; + + private volatile DeviceContext externalDevice; + private volatile OutputProvider display = OutputProvider.DUMMY; + + public ContextAdm3A(Keyboard keyboard, TerminalSettings settings) { + this.keyboard = Objects.requireNonNull(keyboard); + this.settings = Objects.requireNonNull(settings); + keyboard.addOnKeyHandler(this::onKeyFromKeyboard); + } + + public void setExternalDevice(DeviceContext externalDevice) { + this.externalDevice = Objects.requireNonNull(externalDevice); + } + + public void setDisplay(OutputProvider outputProvider) { + this.display = Objects.requireNonNull(outputProvider); + } + + public void reset() { + OutputProvider tmp = display; + if (tmp != null) { + tmp.reset(); + } + } + + @Override + public Byte readData() { + return 0; + } + + @Override + public void writeData(Byte data) { + OutputProvider tmpOutputProvider = display; + if (tmpOutputProvider != null) { + tmpOutputProvider.write(data); + } + } + + @Override + public Class getDataType() { + return Byte.class; + } + + @Override + public void close() throws Exception { + Keyboard tmpKeyboard = keyboard; + if (tmpKeyboard != null) { + tmpKeyboard.close(); + } + OutputProvider tmpOutputProvider = display; + if (tmpOutputProvider != null) { + tmpOutputProvider.close(); + } + } + + private void onKeyFromKeyboard(byte key) { + DeviceContext device = externalDevice; + if (device != null) { + device.writeData(key); + } + if (settings.isHalfDuplex()) { + writeData(key); + } + } +} diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/Keyboard.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/Keyboard.java new file mode 100644 index 000000000..52e220d27 --- /dev/null +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/Keyboard.java @@ -0,0 +1,24 @@ +package net.emustudio.plugins.device.adm3a.api; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Consumer; + +public abstract class Keyboard implements AutoCloseable { + protected List> onKeyHandlers = new CopyOnWriteArrayList<>(); + + public abstract void process(); + + public void addOnKeyHandler(Consumer onKeyHandler) { + onKeyHandlers.add(Objects.requireNonNull(onKeyHandler)); + } + + protected void notifyOnKey(byte key) { + onKeyHandlers.forEach(c -> c.accept(key)); + } + + public void close() { + onKeyHandlers.clear(); + } +} diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/OutputProvider.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/OutputProvider.java new file mode 100644 index 000000000..0a4a06aa1 --- /dev/null +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/OutputProvider.java @@ -0,0 +1,22 @@ +package net.emustudio.plugins.device.adm3a.api; + +public interface OutputProvider extends AutoCloseable { + OutputProvider DUMMY = new OutputProvider() { + + @Override + public void write(byte data) { + } + + @Override + public void reset() { + } + + @Override + public void close() { + } + }; + + void reset(); + + void write(byte data); +} diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java index 5b5254455..56defa347 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java @@ -19,7 +19,6 @@ package net.emustudio.plugins.device.adm3a.gui; import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.plugins.device.adm3a.interaction.Display; import net.emustudio.plugins.device.adm3a.TerminalSettings; import javax.swing.*; @@ -31,11 +30,10 @@ public class ConfigDialog extends JDialog { private final TerminalSettings settings; - private final Display display; private final TerminalWindow window; private final Dialogs dialogs; - public ConfigDialog(JFrame parent, TerminalSettings settings, TerminalWindow window, Display lblTerminal, Dialogs dialogs) { + public ConfigDialog(JFrame parent, TerminalSettings settings, TerminalWindow window, Dialogs dialogs) { super(parent, true); this.dialogs = Objects.requireNonNull(dialogs); @@ -43,7 +41,6 @@ public ConfigDialog(JFrame parent, TerminalSettings settings, TerminalWindow win initComponents(); this.settings = settings; - this.display = lblTerminal; this.window = window; readSettings(); @@ -278,27 +275,26 @@ private void initComponents() { ); pack(); - }// //GEN-END:initComponents + } - private void btnClearScreenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClearScreenActionPerformed - display.clearScreen(); - }//GEN-LAST:event_btnClearScreenActionPerformed + private void btnClearScreenActionPerformed(java.awt.event.ActionEvent evt) { + window.clearScreen(); + } - private void btnRollLineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRollLineActionPerformed - display.rollLine(); - }//GEN-LAST:event_btnRollLineActionPerformed + private void btnRollLineActionPerformed(java.awt.event.ActionEvent evt) { + window.rollLine(); + } - private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed + private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { window.setAlwaysOnTop(chkAlwaysOnTop.isSelected()); try { updateSettings(chkSaveSettings.isSelected()); dispose(); } catch (IOException e) { - dialogs.showError("Input or output file names (or both) do not exist. Please make sure they do.", "ADM 3A"); + dialogs.showError("Input or output file names (or both) do not exist. Please make sure they do.", "ADM-3A Terminal"); } - }//GEN-LAST:event_btnOKActionPerformed + } - // Variables declaration - do not modify//GEN-BEGIN:variables private JCheckBox chkAlwaysOnTop; private JCheckBox chkAntiAliasing; private JCheckBox chkHalfDuplex; @@ -306,5 +302,4 @@ private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:e private JSpinner spnInputDelay; private JTextField txtInputFileName; private JTextField txtOutputFileName; - // End of variables declaration//GEN-END:variables } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java new file mode 100644 index 000000000..3deb122e5 --- /dev/null +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java @@ -0,0 +1,169 @@ +package net.emustudio.plugins.device.adm3a.gui; + +import net.emustudio.plugins.device.adm3a.Utils; +import net.emustudio.plugins.device.adm3a.interaction.Display; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.*; +import java.awt.*; +import java.awt.font.LineMetrics; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferStrategy; +import java.io.InputStream; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; + +public class DisplayCanvas extends Canvas implements AutoCloseable { + private final static Logger LOGGER = LoggerFactory.getLogger(DisplayCanvas.class); + + private static final Color FOREGROUND = new Color(0, 255, 0); + private static final Color BACKGROUND = Color.BLACK; + private static final String TERMINAL_FONT_PATH = "/net/emustudio/plugins/device/adm3a/gui/terminal.ttf"; + + private final Font terminalFont; + private final Timer repaintTimer; + private final Display display; + + private final AtomicBoolean painting = new AtomicBoolean(false); + private volatile Dimension size; + + public DisplayCanvas(Display display) { + this.display = Objects.requireNonNull(display); + this.terminalFont = loadFont(); + + setForeground(FOREGROUND); + setBackground(BACKGROUND); + setFont(terminalFont); + + DisplayParameters displayParameters = measure(); + this.size = new Dimension(displayParameters.maxWidth, displayParameters.maxHeight); + + PaintCycle paintCycle = new PaintCycle(); + this.repaintTimer = new Timer(1000 / 60, e -> paintCycle.run()); // 60 HZ + this.repaintTimer.setCoalesce(true); + } + + public void start() { + if (painting.compareAndSet(false, true)) { + createBufferStrategy(2); + this.repaintTimer.restart(); + } + } + + + @Override + public Dimension getPreferredSize() { + return this.size; + } + + @Override + public Dimension getMinimumSize() { + return this.size; + } + + @Override + public void setBounds(int x, int y, int width, int height) { + super.setBounds(x, y, width, height); + this.size = getSize(); + } + + @Override + public void setBounds(Rectangle r) { + super.setBounds(r); + this.size = getSize(); + } + + private Font loadFont() { + Font font; + try (InputStream fin = getClass().getResourceAsStream(TERMINAL_FONT_PATH)) { + font = Font.createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(fin)).deriveFont(Font.PLAIN, 15f); + GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font); + } catch (Exception e) { + LOGGER.error("Could not load custom font, using default monospaced font", e); + font = new Font(Font.MONOSPACED, Font.PLAIN, 15); + } + return font; + } + + private DisplayParameters measure() { + Font font = getFont(); + Rectangle2D metrics = font.getStringBounds("W", Utils.getDefaultFrc()); + LineMetrics lineMetrics = font.getLineMetrics("W", Utils.getDefaultFrc()); + + int charWidth = (int) metrics.getWidth(); + int charHeight = (int) lineMetrics.getHeight(); + + int maxWidth = display.columns * charWidth; + int maxHeight = display.rows * charHeight; + + return new DisplayParameters(maxWidth, maxHeight); + } + + @Override + public void close() { + repaintTimer.stop(); + display.close(); + painting.set(false); + } + + public class PaintCycle implements Runnable { + private BufferStrategy strategy; + + @Override + public void run() { + strategy = getBufferStrategy(); + if (painting.get()) { + paint(); + } + } + + protected void paint() { + Dimension dimension = size; + do { + do { + Graphics2D graphics = (Graphics2D) strategy.getDrawGraphics(); + graphics.setColor(BACKGROUND); + graphics.fillRect(0, 0, dimension.width, dimension.height); + + int lineHeight = graphics.getFontMetrics().getHeight(); + graphics.setColor(FOREGROUND); + for (int y = 0; y < display.rows; y++) { + graphics.drawChars( + display.videoMemory, + y * display.columns, + display.columns, + 1, + (y + 1) * lineHeight); + } + graphics.setColor(BACKGROUND); + graphics.fillRect(0, 0, 100, 20); + graphics.setColor(FOREGROUND); + + paintCursor(graphics, lineHeight); + try { + graphics.dispose(); + } catch (Exception ignored) { + + } + } while (strategy.contentsRestored()); + strategy.show(); + } while (strategy.contentsLost()); + } + + private void paintCursor(Graphics graphics, int lineHeight) { + Point cursorPoint = display.getCursorPoint(); + + graphics.setXORMode(BACKGROUND); + graphics.setColor(FOREGROUND); + + Rectangle2D fontRectangle = terminalFont.getMaxCharBounds(graphics.getFontMetrics().getFontRenderContext()); + + int x = 2 + (int) (cursorPoint.x * fontRectangle.getWidth()); + int y = 3 + (cursorPoint.y * lineHeight); + + graphics.fillRect(x, y, (int) fontRectangle.getWidth(), (int) fontRectangle.getHeight()); + graphics.setPaintMode(); + } + } +} diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/DisplayParameters.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayParameters.java similarity index 94% rename from plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/DisplayParameters.java rename to plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayParameters.java index dfe1c468e..55b1dabe9 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/DisplayParameters.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayParameters.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.adm3a.interaction; +package net.emustudio.plugins.device.adm3a.gui; import net.jcip.annotations.Immutable; diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/GuiUtils.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/GuiUtils.java new file mode 100644 index 000000000..c36336e9b --- /dev/null +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/GuiUtils.java @@ -0,0 +1,29 @@ +package net.emustudio.plugins.device.adm3a.gui; + +import java.awt.*; +import java.awt.event.KeyListener; + +public class GuiUtils { + + public static void addListenerRecursively(Component c, KeyListener listener) { + c.addKeyListener(listener); + if (c instanceof Container) { + Container cont = (Container) c; + Component[] children = cont.getComponents(); + for (Component child : children) { + addListenerRecursively(child, listener); + } + } + } + + public static void removeListenerRecursively(Component c, KeyListener listener) { + c.removeKeyListener(listener); + if (c instanceof Container) { + Container cont = (Container) c; + Component[] children = cont.getComponents(); + for (Component child : children) { + removeListenerRecursively(child, listener); + } + } + } +} diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java index ec90cc0e9..5d4227e9f 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java @@ -26,20 +26,38 @@ public class TerminalWindow extends JDialog { private final Display display; + private final DisplayCanvas canvas; public TerminalWindow(JFrame parent, Display display) { super(parent); this.display = Objects.requireNonNull(display); + this.canvas = new DisplayCanvas(display); initComponents(); setVisible(false); setLocationRelativeTo(parent); } + public void startPainting() { + this.canvas.start(); + } + + public void clearScreen() { + display.clearScreen(); + canvas.repaint(); + } + public void destroy() { + this.canvas.close(); + this.display.close(); this.dispose(); } + public void rollLine() { + display.rollLine(); + canvas.repaint(); + } + private void initComponents() { JLabel lblBack = new JLabel(); ImageIcon backgroundImage = new ImageIcon(getClass().getResource("/net/emustudio/plugins/device/adm3a/gui/display.png")); @@ -48,7 +66,7 @@ private void initComponents() { setTitle("Terminal ADM-3A"); setResizable(false); - display.setBounds(70, 120, 730, 500); + canvas.setBounds(70, 120, 730, 500); lblBack.setLocation(0, 0); lblBack.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); @@ -63,7 +81,7 @@ private void initComponents() { pane.setBackground(Color.BLACK); pane.setLayout(null); - pane.add(display); + pane.add(canvas); pane.add(lblBack); pane.setPreferredSize(new Dimension(backgroundImage.getIconWidth(), backgroundImage.getIconHeight())); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java index 614aac9be..fb71e46a0 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java @@ -19,21 +19,14 @@ package net.emustudio.plugins.device.adm3a.interaction; import net.emustudio.emulib.plugins.annotations.PluginContext; -import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.device.adm3a.TerminalSettings; -import net.emustudio.plugins.device.adm3a.Utils; +import net.emustudio.plugins.device.adm3a.api.OutputProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.font.LineMetrics; -import java.awt.geom.Rectangle2D; import java.io.FileWriter; import java.io.IOException; -import java.io.InputStream; import java.util.Arrays; import java.util.Objects; @@ -41,28 +34,18 @@ * Terminal can interpret ASCII codes from 0-127. Some have special purpose (0-31). */ @PluginContext(id = "LSI ADM-3A Terminal") -public class Display extends JPanel implements DeviceContext, TerminalSettings.ChangedObserver, Cursor.LineRoller, ActionListener { +public class Display implements OutputProvider, Cursor.LineRoller { private static final Logger LOGGER = LoggerFactory.getLogger(Display.class); - private static final String HERE_IS_CONSTANT = Display.class.getAnnotation(PluginContext.class).id(); - static final Color FOREGROUND = new Color(0, 255, 0); - static final Color BACKGROUND = Color.BLACK; - private static final String TERMINAL_FONT_PATH = "/net/emustudio/plugins/device/adm3a/gui/terminal.ttf"; - private final Font terminalFont; - private final char[] videoMemory; - private final int columns; - private final int rows; + // must be synchronized on this object + public final char[] videoMemory; + public final int columns; + public final int rows; private final TerminalSettings settings; - private final Cursor cursor; - private volatile boolean cursorShouldBePainted; - private final LoadCursorPosition loadCursorPosition; - private final Timer cursorTimer = new Timer(800, this); - - private volatile Dimension size; private FileWriter outputWriter = null; @@ -74,106 +57,35 @@ public Display(Cursor cursor, TerminalSettings settings) { this.rows = cursor.getRows(); this.videoMemory = new char[rows * columns]; - this.terminalFont = loadFont(); fillWithSpaces(); - - setForeground(FOREGROUND); - setBackground(BACKGROUND); - setDoubleBuffered(true); - setOpaque(true); - setFont(terminalFont); - DisplayParameters displayParameters = measure(); - this.size = new Dimension(displayParameters.maxWidth, displayParameters.maxHeight); - if (!settings.isGuiSupported()) { openOutputWriter(); } - - settings.addChangedObserver(this); - } - - /** - * Input from the display is always 0, because the input is captured by an input provider, not by the display. - * - * @return 0 - */ - @Override - public Byte readData() { - return 0; - } - - public synchronized void startCursor() { - cursorTimer.restart(); - } - - public synchronized void destroy() { - cursorTimer.stop(); - settings.removeChangedObserver(this); - closeOutputWriter(); - } - - public final void clearScreen() { - fillWithSpaces(); - cursor.home(); - repaint(); - } - - @Override - public void setBounds(int x, int y, int width, int height) { - super.setBounds(x, y, width, height); - this.size = getSize(); - } - - @Override - public void setBounds(Rectangle r) { - super.setBounds(r); - this.size = getSize(); } @Override - public Dimension getPreferredSize() { - return this.size; + public void reset() { + clearScreen(); } @Override - public Dimension getMinimumSize() { - return this.size; - } - - @Override - public void paintComponent(Graphics graphics) { - Dimension dimension = size; - graphics.setColor(BACKGROUND); - graphics.fillRect(0, 0, dimension.width, dimension.height); - - int t_y; - int x, y; - int temp; - StringBuilder sLine = new StringBuilder(); - - int lineHeight = graphics.getFontMetrics().getHeight(); - graphics.setColor(FOREGROUND); - Graphics2D g2d = (Graphics2D) graphics; - for (y = 0; y < rows; y++) { - t_y = (y + 1) * lineHeight; - temp = y * columns; - for (x = 0; x < columns; x++) { - synchronized (videoMemory) { - sLine.append(videoMemory[temp + x]); - } + public synchronized void close() { + if (outputWriter != null) { + try { + outputWriter.close(); + } catch (IOException ignored) { } - g2d.drawString(sLine.toString(), 1, t_y); - sLine = new StringBuilder(); } + outputWriter = null; + } - paintCursor(graphics); + public Point getCursorPoint() { + return cursor.getCursorPoint(); } - @Override - public void settingsChanged() { - if (settings.isAntiAliasing()) { - repaint(); - } + public void clearScreen() { + fillWithSpaces(); + cursor.home(); } @Override @@ -184,14 +96,13 @@ public void rollLine() { videoMemory[i] = ' '; } } - repaint(); } /** * This method is called from serial I/O card (by OUT instruction) */ @Override - public void writeData(Byte data) { + public void write(byte data) { writeToOutput(data); /* * if it is special char, interpret it. else just add to "video memory" @@ -233,12 +144,6 @@ public void writeData(Byte data) { drawChar((char) (data & 0xFF)); cursor.moveForwardsRolling(this); } - repaint(); - } - - @Override - public Class getDataType() { - return Byte.class; } private void insertHereIs() { @@ -248,17 +153,6 @@ private void insertHereIs() { } } - private void writeToOutput(short val) { - if (outputWriter != null) { - try { - outputWriter.write((char) val); - outputWriter.flush(); - } catch (IOException e) { - LOGGER.error("Could not write to file: " + settings.getOutputPath(), e); - } - } - } - private void drawChar(char c) { Point cursorPoint = cursor.getCursorPoint(); synchronized (videoMemory) { @@ -280,68 +174,14 @@ private void openOutputWriter() { } } - private void closeOutputWriter() { + private void writeToOutput(short val) { if (outputWriter != null) { try { - outputWriter.close(); - } catch (IOException ignored) { + outputWriter.write((char) val); + outputWriter.flush(); + } catch (IOException e) { + LOGGER.error("Could not write to file: " + settings.getOutputPath(), e); } } - outputWriter = null; - } - - private Font loadFont() { - Font font; - try (InputStream fin = getClass().getResourceAsStream(TERMINAL_FONT_PATH)) { - font = Font.createFont(Font.TRUETYPE_FONT, fin).deriveFont(Font.PLAIN, 15f); - GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font); - } catch (Exception e) { - LOGGER.error("Could not load custom font, using default monospaced font", e); - font = new Font(Font.MONOSPACED, Font.PLAIN, 15); - } - return font; - } - - private void paintCursor(Graphics graphics) { - if (!cursorShouldBePainted) { - Point paintPoint = cursor.getCursorPoint(); - - graphics.setXORMode(Display.BACKGROUND); - graphics.setColor(Display.FOREGROUND); - - Rectangle2D fontRectangle = terminalFont.getMaxCharBounds(graphics.getFontMetrics().getFontRenderContext()); - int lineHeight = graphics.getFontMetrics().getHeight(); - - int x = 2 + (int) (paintPoint.x * fontRectangle.getWidth()); - int y = 3 + (paintPoint.y * lineHeight); - - graphics.fillRect(x, y, (int) fontRectangle.getWidth(), (int) fontRectangle.getHeight()); - graphics.setPaintMode(); - - cursorShouldBePainted = true; - } else { - cursorShouldBePainted = false; - } - } - - private DisplayParameters measure() { - Font font = getFont(); - Rectangle2D metrics = font.getStringBounds("W", Utils.getDefaultFrc()); - LineMetrics lineMetrics = font.getLineMetrics("W", Utils.getDefaultFrc()); - - int charWidth = (int) metrics.getWidth(); - int charHeight = (int) lineMetrics.getHeight(); - - int maxWidth = columns * charWidth; - int maxHeight = rows * charHeight; - - return new DisplayParameters(maxWidth, maxHeight); - } - - @Override - public void actionPerformed(ActionEvent e) { - if (e.getSource() != null && e.getSource() == cursorTimer) { - repaint(); - } } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Keyboard.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Keyboard.java deleted file mode 100644 index fa05058ce..000000000 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Keyboard.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.adm3a.interaction; - -import net.emustudio.emulib.plugins.device.DeviceContext; - -public interface Keyboard { - - void connect(DeviceContext observer); - - void disconnect(DeviceContext observer); - - default void process() { - - } - - void destroy(); -} diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java index 054a5aaff..452219089 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java @@ -18,64 +18,38 @@ */ package net.emustudio.plugins.device.adm3a.interaction; -import net.emustudio.emulib.plugins.device.DeviceContext; +import net.emustudio.plugins.device.adm3a.api.Keyboard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.*; +import java.io.FileInputStream; import java.nio.file.Path; -import java.util.List; import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.LockSupport; -public class KeyboardFromFile implements Keyboard { +public class KeyboardFromFile extends Keyboard { private final static Logger LOGGER = LoggerFactory.getLogger(KeyboardFromFile.class); - private final List> devices = new CopyOnWriteArrayList<>(); + private final long delayNanos; private final Path inputFile; - private final int delayInMilliseconds; public KeyboardFromFile(Path inputFile, int delayInMilliseconds) { + this.delayNanos = delayInMilliseconds * 1000000L; this.inputFile = Objects.requireNonNull(inputFile); - this.delayInMilliseconds = delayInMilliseconds; - } - - @Override - public void connect(DeviceContext device) { - Optional.ofNullable(device).ifPresent(devices::add); - } - - @Override - public void disconnect(DeviceContext device) { - Optional.ofNullable(device).ifPresent(devices::remove); } @Override public void process() { - LOGGER.info("Processing input file: '" + inputFile + "'; delay of chars read (ms): " + delayInMilliseconds); - try (InputStream input = new FileInputStream(inputFile.toFile())) { + try (FileInputStream in = new FileInputStream(inputFile.toFile())) { int key; - while ((key = input.read()) != -1) { - inputReceived(key); - if (delayInMilliseconds > 0) { - LockSupport.parkNanos(delayInMilliseconds * 1000000L); + while ((key = in.read()) != -1) { + notifyOnKey((byte) key); + if (delayNanos > 0) { + LockSupport.parkNanos(delayNanos); } } } catch (Exception e) { LOGGER.error("Could not process input file", e); } } - - private void inputReceived(int input) throws IOException { - for (DeviceContext device : devices) { - device.writeData((byte) input); - } - } - - @Override - public void destroy() { - devices.clear(); - } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java index 8bd8de985..9fb645635 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardGui.java @@ -18,19 +18,16 @@ */ package net.emustudio.plugins.device.adm3a.interaction; -import net.emustudio.emulib.plugins.device.DeviceContext; +import net.emustudio.plugins.device.adm3a.api.Keyboard; +import net.emustudio.plugins.device.adm3a.gui.GuiUtils; -import java.awt.*; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; -import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import java.awt.event.KeyListener; import java.util.Objects; -public class KeyboardGui extends KeyAdapter implements ContainerListener, Keyboard { +public class KeyboardGui extends Keyboard implements ContainerListener, KeyListener { private static final int[] CONTROL_KEYCODES = new int[256]; private static final int[] CONTROL_KEYCODES_ALWAYS_ACTIVE = new int[256]; @@ -102,23 +99,15 @@ public class KeyboardGui extends KeyAdapter implements ContainerListener, Keyboa CONTROL_KEYCODES_ALWAYS_ACTIVE[KeyEvent.VK_ENTER] = 13; } - private final List> devices = new ArrayList<>(); private final LoadCursorPosition loadCursorPosition; public KeyboardGui(Cursor cursor) { this.loadCursorPosition = new LoadCursorPosition(Objects.requireNonNull(cursor)); } - public void addListenerRecursively(Component c) { - c.addKeyListener(this); - if (c instanceof Container) { - Container cont = (Container) c; - cont.addContainerListener(this); - Component[] children = cont.getComponents(); - for (Component aChildren : children) { - addListenerRecursively(aChildren); - } - } + @Override + public void keyTyped(KeyEvent e) { + } @Override @@ -132,7 +121,7 @@ public void keyPressed(KeyEvent evt) { newKeyCode = CONTROL_KEYCODES_ALWAYS_ACTIVE[originalKeyCode]; if (newKeyCode == 0) { int tmpKeyChar = evt.getKeyChar(); - if (tmpKeyChar > 254) { + if (tmpKeyChar >= 0xFF) { return; } newKeyCode = tmpKeyChar; @@ -140,55 +129,28 @@ public void keyPressed(KeyEvent evt) { } if (newKeyCode != 0) { if (loadCursorPosition.notAccepted((byte) newKeyCode)) { - try { - inputReceived(newKeyCode); - } catch (IOException e) { - throw new RuntimeException(e); - } + notifyOnKey((byte) newKeyCode); } } } @Override - public void componentAdded(ContainerEvent e) { - addListenerRecursively(e.getChild()); - } + public void keyReleased(KeyEvent e) { - @Override - public void componentRemoved(ContainerEvent e) { - removeListenerRecursively(e.getChild()); } @Override - public void connect(DeviceContext device) { - devices.add(device); + public void componentAdded(ContainerEvent e) { + GuiUtils.addListenerRecursively(e.getChild(), this); } @Override - public void disconnect(DeviceContext device) { - devices.remove(device); + public void componentRemoved(ContainerEvent e) { + GuiUtils.removeListenerRecursively(e.getChild(), this); } @Override - public void destroy() { - devices.clear(); - } - - private void inputReceived(int input) throws IOException { - for (DeviceContext device : devices) { - device.writeData((byte) input); - } - } + public void process() { - private void removeListenerRecursively(Component c) { - c.removeKeyListener(this); - if (c instanceof Container) { - Container cont = (Container) c; - cont.removeContainerListener(this); - Component[] children = cont.getComponents(); - for (Component aChildren : children) { - removeListenerRecursively(aChildren); - } - } } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java index f76a79723..bdce0a6ba 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java @@ -132,7 +132,7 @@ public void writeData(Byte data) { System.out.printf("SIMH: Unknown command (%d) to SIMH pseudo device ignored.\n", data); } else { lastReadCommand = Commands.fromInt(data); - lastWriteCommand = Commands.fromInt(data); + lastWriteCommand = lastReadCommand; COMMANDS_MAP.get(lastWriteCommand.ordinal()).start(this); } } else { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java index 2564b9b16..5e23b53ce 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SIMHSleep.java @@ -27,7 +27,7 @@ public class SIMHSleep implements Command { @Override public void start(Control control) { // Do not sleep when timer interrupts are pending or are about to be created. - // Otherwise there is the possibility that such interrupts are skipped. + // Otherwise, there is the possibility that such interrupts are skipped. // time to sleep and SIO not attached to a file. if (StartTimerInterrupts.INS.callback.get() == null) { From 87c6ccaf760d36c10d79eca3ccc72d6989ff22bf Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 16 Sep 2022 12:35:13 +0200 Subject: [PATCH 210/314] [#260] z80: support timed events processing --- .../plugins/cpu/zilogZ80/ContextZ80Impl.java | 27 ++++++------------- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 6 +++-- .../simh/commands/StartTimerInterrupts.java | 9 +++++-- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java index 47160d235..914059478 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java @@ -18,16 +18,16 @@ */ package net.emustudio.plugins.cpu.zilogZ80; +import net.emustudio.emulib.plugins.cpu.TimedEventsProcessor; import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.cpu.zilogZ80.api.ContextZ80; import net.jcip.annotations.ThreadSafe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArrayList; @ThreadSafe public final class ContextZ80Impl implements ContextZ80 { @@ -39,7 +39,7 @@ public final class ContextZ80Impl implements ContextZ80 { private volatile EmulatorEngine engine; private volatile int clockFrequency = DEFAULT_FREQUENCY_KHZ; - private final List runCallbacks = new CopyOnWriteArrayList<>(); + private final TimedEventsProcessor tep = new TimedEventsProcessor(); public void setEngine(EmulatorEngine engine) { this.engine = engine; @@ -84,12 +84,6 @@ byte readIO(int port) { return NO_DATA; } - public void triggerRunCallbacks() { - for (Runnable runnable : runCallbacks) { - runnable.run(); - } - } - @Override public boolean isInterruptSupported() { return true; @@ -120,17 +114,12 @@ public void signalNonMaskableInterrupt() { } @Override - public boolean isRunCallbackSupported() { - return true; - } - - @Override - public void registerRunCallback(Runnable runnable) { - runCallbacks.add(runnable); + public Optional getTimedEventsProcessor() { + return Optional.of(tep); } - @Override - public void unregisterRunCallback(Runnable runnable) { - runCallbacks.remove(runnable); + public TimedEventsProcessor getTimedEventsProcessorNow() { + // bypassing optional + return tep; } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 76afb9906..bd61e95ed 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -20,6 +20,7 @@ import net.emustudio.emulib.plugins.cpu.CPU; import net.emustudio.emulib.plugins.cpu.CPU.RunState; +import net.emustudio.emulib.plugins.cpu.TimedEventsProcessor; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.helpers.SleepUtils; import net.emustudio.plugins.cpu.intel8080.api.CpuEngine; @@ -45,7 +46,6 @@ * (parallel with other hardware) */ // TODO: set frequency runtime -//@SuppressWarnings("unused") public class EmulatorEngine implements CpuEngine { private final static Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); @@ -62,6 +62,7 @@ public class EmulatorEngine implements CpuEngine { }; private final ContextZ80Impl context; + private final TimedEventsProcessor tep; private final MemoryContext memory; private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); @@ -92,6 +93,7 @@ public class EmulatorEngine implements CpuEngine { public EmulatorEngine(MemoryContext memory, ContextZ80Impl context) { this.memory = Objects.requireNonNull(memory); this.context = Objects.requireNonNull(context); + this.tep = context.getTimedEventsProcessorNow(); LOGGER.info("Sleep precision: " + SleepUtils.SLEEP_PRECISION + " nanoseconds."); } @@ -178,10 +180,10 @@ public CPU.RunState run(CPU cpu) { cycles = dispatch(); cycles_executed += cycles; executedCycles += cycles; + tep.advanceClock(cycles); if (cpu.isBreakpointSet(PC)) { throw new Breakpoint(); } - context.triggerRunCallbacks(); } catch (Breakpoint e) { return CPU.RunState.STATE_STOPPED_BREAK; } catch (IndexOutOfBoundsException e) { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java index c38a30a99..24ff9c6fc 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java @@ -18,20 +18,25 @@ */ package net.emustudio.plugins.device.simh.commands; +import net.emustudio.emulib.plugins.cpu.TimedEventsProcessor; import net.emustudio.plugins.cpu.intel8080.api.Context8080; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; public class StartTimerInterrupts implements Command { public final static StartTimerInterrupts INS = new StartTimerInterrupts(); + private static final int TRY_AFTER_CYCLES = 50000; public final AtomicReference callback = new AtomicReference<>(); + private Optional tep; @Override public void reset(Control control) { + this.tep = control.getCpu().getTimedEventsProcessor(); TimerInterruptCallback old = callback.getAndSet(null); if (old != null) { - control.getCpu().unregisterRunCallback(old); + tep.ifPresent(t -> t.remove(TRY_AFTER_CYCLES, old)); } } @@ -40,7 +45,7 @@ public void start(Control control) { reset(control); TimerInterruptCallback cb = new TimerInterruptCallback(control.getCpu()); callback.set(cb); - control.getCpu().registerRunCallback(cb); + tep.ifPresent(t -> t.schedule(TRY_AFTER_CYCLES, cb)); control.clearCommand(); } From 7db720b70742e2176db54557e1113302cae9acbf Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 20 Oct 2022 15:44:37 -0700 Subject: [PATCH 211/314] [#278] Improved LSI ADM-3A - new font - new background - increased size --- .../device/adm3a/gui/DisplayCanvas.java | 102 +- .../device/adm3a/gui/DisplayParameters.java | 6 +- .../device/adm3a/gui/TerminalWindow.java | 9 +- .../plugins/device/adm3a/gui/adm-3a.ttf | Bin 0 -> 29340 bytes .../plugins/device/adm3a/gui/display.gif | Bin 55344 -> 0 bytes .../plugins/device/adm3a/gui/display.png | Bin 218780 -> 324953 bytes .../plugins/device/adm3a/gui/terminal.ttf | Bin 309064 -> 0 bytes .../device/simh/commands/SIMHSleep.java | 10 +- resources/logo/logo.mp | 93 + resources/logo/png/logo-1.png | Bin 0 -> 5830 bytes resources/logo/png/logo-2.png | Bin 0 -> 505 bytes resources/logo/png/logo-3.png | Bin 0 -> 926 bytes resources/logo/svg/logo-1.svg | 58 + resources/logo/svg/logo-2.svg | 32 + resources/lsi-adm-3a/adm-3a.ttf | Bin 0 -> 29340 bytes resources/lsi-adm-3a/adm3a.sfd | 7111 +++++++++++++++++ 16 files changed, 7359 insertions(+), 62 deletions(-) create mode 100644 plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf delete mode 100644 plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/display.gif delete mode 100644 plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/terminal.ttf create mode 100644 resources/logo/logo.mp create mode 100644 resources/logo/png/logo-1.png create mode 100644 resources/logo/png/logo-2.png create mode 100644 resources/logo/png/logo-3.png create mode 100644 resources/logo/svg/logo-1.svg create mode 100644 resources/logo/svg/logo-2.svg create mode 100644 resources/lsi-adm-3a/adm-3a.ttf create mode 100644 resources/lsi-adm-3a/adm3a.sfd diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java index 3deb122e5..b37db50d4 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java @@ -1,32 +1,36 @@ package net.emustudio.plugins.device.adm3a.gui; -import net.emustudio.plugins.device.adm3a.Utils; import net.emustudio.plugins.device.adm3a.interaction.Display; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import java.awt.*; -import java.awt.font.LineMetrics; +import java.awt.font.TextAttribute; import java.awt.geom.Rectangle2D; import java.awt.image.BufferStrategy; import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; +import static java.awt.RenderingHints.*; + public class DisplayCanvas extends Canvas implements AutoCloseable { private final static Logger LOGGER = LoggerFactory.getLogger(DisplayCanvas.class); private static final Color FOREGROUND = new Color(0, 255, 0); private static final Color BACKGROUND = Color.BLACK; - private static final String TERMINAL_FONT_PATH = "/net/emustudio/plugins/device/adm3a/gui/terminal.ttf"; + private static final String TERMINAL_FONT_PATH = "/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf"; + private static final int FONT_SIZE = 12; private final Font terminalFont; private final Timer repaintTimer; private final Display display; private final AtomicBoolean painting = new AtomicBoolean(false); - private volatile Dimension size; + private volatile Dimension size = new Dimension(0, 0); public DisplayCanvas(Display display) { this.display = Objects.requireNonNull(display); @@ -36,9 +40,6 @@ public DisplayCanvas(Display display) { setBackground(BACKGROUND); setFont(terminalFont); - DisplayParameters displayParameters = measure(); - this.size = new Dimension(displayParameters.maxWidth, displayParameters.maxHeight); - PaintCycle paintCycle = new PaintCycle(); this.repaintTimer = new Timer(1000 / 60, e -> paintCycle.run()); // 60 HZ this.repaintTimer.setCoalesce(true); @@ -75,29 +76,20 @@ public void setBounds(Rectangle r) { } private Font loadFont() { - Font font; + Map attrs = new HashMap<>(); + attrs.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); + try (InputStream fin = getClass().getResourceAsStream(TERMINAL_FONT_PATH)) { - font = Font.createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(fin)).deriveFont(Font.PLAIN, 15f); + Font font = Font + .createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(fin)) + .deriveFont(Font.PLAIN, FONT_SIZE) + .deriveFont(attrs); GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font); + return font; } catch (Exception e) { LOGGER.error("Could not load custom font, using default monospaced font", e); - font = new Font(Font.MONOSPACED, Font.PLAIN, 15); + return new Font(Font.MONOSPACED, Font.PLAIN, FONT_SIZE); } - return font; - } - - private DisplayParameters measure() { - Font font = getFont(); - Rectangle2D metrics = font.getStringBounds("W", Utils.getDefaultFrc()); - LineMetrics lineMetrics = font.getLineMetrics("W", Utils.getDefaultFrc()); - - int charWidth = (int) metrics.getWidth(); - int charHeight = (int) lineMetrics.getHeight(); - - int maxWidth = display.columns * charWidth; - int maxHeight = display.rows * charHeight; - - return new DisplayParameters(maxWidth, maxHeight); } @Override @@ -120,35 +112,37 @@ public void run() { protected void paint() { Dimension dimension = size; - do { + try { do { - Graphics2D graphics = (Graphics2D) strategy.getDrawGraphics(); - graphics.setColor(BACKGROUND); - graphics.fillRect(0, 0, dimension.width, dimension.height); - - int lineHeight = graphics.getFontMetrics().getHeight(); - graphics.setColor(FOREGROUND); - for (int y = 0; y < display.rows; y++) { - graphics.drawChars( - display.videoMemory, - y * display.columns, - display.columns, - 1, - (y + 1) * lineHeight); - } - graphics.setColor(BACKGROUND); - graphics.fillRect(0, 0, 100, 20); - graphics.setColor(FOREGROUND); - - paintCursor(graphics, lineHeight); - try { + do { + Graphics2D graphics = (Graphics2D) strategy.getDrawGraphics(); + graphics.setColor(BACKGROUND); + graphics.fillRect(0, 0, dimension.width, dimension.height); + + int lineHeight = graphics.getFontMetrics().getHeight() + 5; + graphics.setColor(FOREGROUND); + graphics.setRenderingHint(KEY_RENDERING, VALUE_RENDER_QUALITY); + graphics.setRenderingHint(KEY_FRACTIONALMETRICS, VALUE_FRACTIONALMETRICS_ON); + graphics.setRenderingHint(KEY_INTERPOLATION, VALUE_INTERPOLATION_BICUBIC); + graphics.setRenderingHint(KEY_COLOR_RENDERING, VALUE_COLOR_RENDER_QUALITY); + graphics.setRenderingHint(KEY_TEXT_ANTIALIASING, VALUE_TEXT_ANTIALIAS_ON); + graphics.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON); + graphics.setRenderingHint(KEY_STROKE_CONTROL, VALUE_STROKE_NORMALIZE); + for (int y = 0; y < display.rows; y++) { + graphics.drawChars( + display.videoMemory, + y * display.columns, + display.columns, + 1, + (y + 1) * lineHeight); + } + paintCursor(graphics, lineHeight); graphics.dispose(); - } catch (Exception ignored) { - - } - } while (strategy.contentsRestored()); - strategy.show(); - } while (strategy.contentsLost()); + } while (strategy.contentsRestored()); + strategy.show(); + } while (strategy.contentsLost()); + } catch (Exception ignored) { + } } private void paintCursor(Graphics graphics, int lineHeight) { @@ -159,10 +153,10 @@ private void paintCursor(Graphics graphics, int lineHeight) { Rectangle2D fontRectangle = terminalFont.getMaxCharBounds(graphics.getFontMetrics().getFontRenderContext()); - int x = 2 + (int) (cursorPoint.x * fontRectangle.getWidth()); + int x = 2 + (int) (cursorPoint.x * (fontRectangle.getWidth() + 0.3)); int y = 3 + (cursorPoint.y * lineHeight); - graphics.fillRect(x, y, (int) fontRectangle.getWidth(), (int) fontRectangle.getHeight()); + graphics.fillRect(x, y, (int) fontRectangle.getWidth(), (int) fontRectangle.getHeight() + 5); graphics.setPaintMode(); } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayParameters.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayParameters.java index 55b1dabe9..bbe13b4ee 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayParameters.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayParameters.java @@ -24,9 +24,13 @@ class DisplayParameters { final int maxWidth; final int maxHeight; + final int charWidth; + final int charHeight; - DisplayParameters(int maxWidth, int maxHeight) { + DisplayParameters(int maxWidth, int maxHeight, int charWidth, int charHeight) { this.maxWidth = maxWidth; this.maxHeight = maxHeight; + this.charWidth = charWidth; + this.charHeight = charHeight; } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java index 5d4227e9f..3ea5a2bfb 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java @@ -25,6 +25,7 @@ import java.util.Objects; public class TerminalWindow extends JDialog { + private static final String BACKGROUND_IMAGE = "/net/emustudio/plugins/device/adm3a/gui/display.png"; private final Display display; private final DisplayCanvas canvas; @@ -60,16 +61,16 @@ public void rollLine() { private void initComponents() { JLabel lblBack = new JLabel(); - ImageIcon backgroundImage = new ImageIcon(getClass().getResource("/net/emustudio/plugins/device/adm3a/gui/display.png")); + ImageIcon backgroundImage = new ImageIcon(getClass().getResource(BACKGROUND_IMAGE)); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - setTitle("Terminal ADM-3A"); + setTitle("LSI ADM-3A"); setResizable(false); - canvas.setBounds(70, 120, 730, 500); + canvas.setBounds(100, 170, 830, 530); lblBack.setLocation(0, 0); - lblBack.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); + lblBack.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 16)); lblBack.setIcon(backgroundImage); lblBack.setFocusable(false); lblBack.setOpaque(true); diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e9c7756a19b856d0e7a13fd9a19d7c2ac59cb0ef GIT binary patch literal 29340 zcmdsg3v`@kdFJ=cj3j$})7X*|LPCE@xf#pO=w^Eqa3Wh5D7%g@0?DjCY!(c%{SoMKj6J<8YecKtbI4ezZS>W zPR|zZd(B^WZou&wW5S&?*@@JvzBT#;#y^DlYG+gT&D#U!K3qS5_TF4-Hhu21kG#^D z#M_MNJU5@s7Y=Vre#w}*H>3X-40*+S`Mul!-EVAq**}|gAPs-tOupnf*`8Q<|9Rh- z8Y}15n2=nSK0ISj)*8JoBLx>_^SeA_LuSB4)24Zt zyl%s3QaH8+#J&|zb0v8_b| z-MZsn8=T#U%EW)tLOMd`29uN{-Sc@*lzsFtvi3QE$65_zxvpX zbKb9%Sq=I`XgMqMIa({na(!Ruoa?uGt9@u!|4RSpX?$M|5%RAWN8Gy_g1r&jT5PT0 z!1?p%*}zzAdBzE)HWZc9^!G4Y*Pu_GS!33ks99&$n+-tMO{U(&%x1F%SlVc|nk&qe z=0)Zz^J2_%jd_XrHRG8k(`;JIwdOi=y}1E%Z!<47+fA$40sOeh#7&!NHyx(abeUad zx7lM7rrX?XUS?iy_L^JFt)|E9Gy6e*pXmn*9WaCDHj^|%=AaoiBj%8Kg&8$tX51V$ zx0^f6o#rm{>*j9rO7m~btIThhSDTbMVkXR_Nt-Ei)J&U-%SnSV0>Y<^>t~w?B9mAhI&KyhdvzoT6kl)JA5Sk=J20~ ze-gPW(j9qK)%%Y>H6nl^|992t7C7D zeK_{?<~5slZhqzFw`~5@<}YpuZSl73+%mJ}cei}C!E2am_``;uG&VQh-}uzl^;_Gw zzH)1E>nFDU@QN$1xc!Q^UGeoRulm>df<=VjohH;6`7ltS&g}e{H8;KNvAT%)e*4F2 zYrg)n$HF1(nvaEfx`wA8tE;t3FMAA0#P{1fVokB@nqo~i+pqa4JL$hS^5Jv0-yG@0 zxRM*xFz&Afid+plZtCpnY-wt4j9V`jM@PKsWA#mOi=7bYNcyLewq%p%;bXwA?R#oIDmzvRx(3TY!FO+tl7wAM0$1$Glj5WBoRZ34~l*QlgeY zF3GF~G$ifac2m+CzvN%{h!5(OO3E02LT4BlYsfi9UU{)UBjhp~`XIuBIY!I#D=&1f z90QqV^%&J7RQCs9mHFBPjP3wmoh{8R&5iZ3hK_hg`|fzydy#Fp*=}v9Yihp6*0wa? zKviAexx1si%c&@Al3mcmvD+-Pk-R^V@E=Ov+OvH;=|7Z6+>djCz91O?L;jDF$#4mR zIF-D$cq?1qFFW?witeZu1|dWr6SEzSl&fuQv7sdTQHM5JS}ui4atxa&VXrI)B&f7k zl>>TG0t|Kxden#nLFk=xpc&?{G6{6wVPlXn2S2u4!Yp;>oX#aPMKFoji_o@S?5c&@ zvMsQhP!%~)ItMscioiUTJoXLv(!T6Q&bp+pw5Q$qC3aQvjuG%&k63MN+{Rnt7$Dw(cVoQef)k+!{9PFL z7>Dj$*$tibyKoltMppJnUoiG2OF{`;3$F(<{3*UG^-_ zV!CrHdl*aV5z$p0c;BqF!~5c~IL3_wH*8H~lO=S(4Q0~=X9sM+ZIa99Z&N=ELmz%= z`IL_>EEWz0#**if7FCHmAA%89$oeW|Hn0xZe|vq4*VJ5(9Zp*p2#)H*P_+2d{%Klr z5`(L?17?yy0Lz(@r|p1xd|8imlv6C;gyBFfsBW|k9Zl_x4Rtu)Vy|!E6|vn#oA7}k z$CAnAWXPV!QG%9Cs*mA9@d0Z;5i&z!nw8^UUp+p(6=OEFzZ^a;J6!_1mD7j`!AoIC z@~P9DUj7{j%_NTj!IHao4`8M;ZqV1R#7q#yS_@8M9qsko0fson$W~YggH&LHSxh7r ziQysaLn%;47|=#AgP}w3m3AH`$_kc2t)QHGZ2~Gm@hX=Z4C+&xA{&*+5{86!5fBJ6 zYV#}jy48(mDf1YupL8}fs+fzmXw~sp_MSK4@lXmD1Gou893T9H3cHA~A|`Ed+t3nk zA!!(}p`*PGF`=!qqrI`dEjXgcL4HfKsPciQj|Gx^;6V{5RQL=h3*CFKquVNg3K#xr z9%wU|*Fvxz@L6nui`b|m0}eWrnFs9WKjH7QPpacuI;x1g-F~6u$Nlb-{iHuwvS;CN z6?}!^T{^yLYllH%D%%C`721nv%kb+P_QQ_2s}GTdVB#ge3*xRC3phnuV@(3!z&atV z2H`iHJcrN<9LFeijJD?u&Q4?^dv5kknU5p{|M!R5u)B z3q{o>Gys)LKz5n^9B^zk#)eV#s2qaXr5CFs4a7lD%t=3hI|R5M%*2Uc8=w_j33pg^ z0oyoQhC;<$v;x$#=}2EfQUdPe1<5 zGvMnO+JHa*Pa_fk)LC>Xowau84IjEY8SX0n@tq7){6pRzadu_Mm|7IA1H!a#a z5eOM&>Mp?yd=D`&rEDJ5$=C)3V#CA&7!V?07;a&E#YoTvy5AZ~|gFfwT zkB5tXe+&ntO)e3|u)j>x5WWK6WgZBg-HW`FG_{!8l|7IpWp|h+3xBsXKIXzr^^9_* z5~pPpLR2dGMT!kw!T>7xF8*uwp~*GI7Z)RmMFdiO zl7K+2b-+qQ2Ka~M5U5I!6fyduG|`+08v!I_Bg`XCB}3v6nhh}@LX8rE>ns~4tjpK= z_tJMl&)P?j5Rp!-iGY0M%baId`xQ)zwo0;ceU}sihHd?baFf{M(vcQj!ZO^U$Ju8uh3zgCM{ zjl@AEZJU~>(_>iVbnxsE`(hy=(SIOOBh30A+JuZDnM~YbZTFBQh{Qtw7EZ#$xyhf_$t4<(ER71#q(v)JzJo z5UPV=LwN{>sHX&5gIHSTsR<*of{Oua>f1!ZU`M!tIH9?grdT|JF_#i$yXYz2B0MaC z^u5J>^eiEkxc1 ziA2oy_a>kzsEay-eIoo-=t$$Ng)iAIdJ}WVFa$suFEb%QUYV@$kBwMm*yE@pyDSH1d@3mtf%}9Xoe#v3omUGa>CDj&+rJkck_Y@P ziQiFG+hcFv`|^hcgG-zI5B+wf+}4TQ#A6BbfDsa4Sz<$k@h*xF5f9k}-4@c4dU_d# z6@q0gLq;}P1J8xn1hGm>0Mc8EJuoRi;N6?le~~jV?z!5SNW)h-XJAa^n>I+pk+$o& zCIPH>7#C-s6_{fOpYs#yLfThsPH;kc20=oL%tm1TSy@^sg^SC(9+$-xU@&ZmYZ|<< zgjHunNKVAuj_(T66nn)#FusXPcG{+uW@lUY>~a@upNUpcX2LR$jvx3`11l96qGq;Y z2G`goN_PtxBT9e`7LKP_x-oZHsk6W*OUmT^_gAb_1mm`0)J_(N09^va*2Y>1>w>ye zAX1cODH8-axw6tlh5BdxvnW*V-(z<#<@`klWnEo>kcSh1PAc}?spM@tZXL7(q5on( zPNeg%dxw7-x|OnXV1V)q=vXJKX>nAnf>I397Lrubu!B{KqF+pe9!@X>o;O;yg5zY( zS-^9aY&S0^M!wpyt>o2krhbZNQO@PPcT*4+$crNnnV%VS-_fMa;*bFRx22)nZ zkGZD-PjN7Xg3hy%SOWtm!-2q6!cN)=6yV?mb4H2-TxtpXpZ@MrdNuvXC)yx#_d;S1 zZV_GqQp_pzUBNGMqjG!K+O?J3TzpGxA8V#UR&2%MVl52AB$Vc66JbyYgjhVYXOBIz z1cGb8?|CzDu1LaDLYPC{>%W#E|DGq@C?}onpy#E*e84Jx}Nc;)^xStQp z)-@}Qi}4QRfsG*o3^EypVnn9^W>$F6d@mRSaHH~Og;eJjWXp5BNatXsfjqq~R@;0- z4Cy+ji+5nD`78o{vV@RZ!gM9p!aoCXC3T|GISk3a@_3EReGyqY;#Yw4F57^CcmQV! zn_F)!QqH?YRT89S2SZp&|9Ztd>t&^zzD*|p!R>I4dWr6E z2uZ5A%6&!n_mFBa!zuayco*WL*i6!5Q5dC9#dx*2FKD>T+6ec;u#)V(2&>BR8^q(P z@Dp_aieTJU!#pG!qLBz_AGzLM$16zmgA5g9BOZpa{06oXdv6`Am~##8PZFI$KEzaQ zHjK1DW`?G!S0|ad0~YNCdKmVJnS1q z1W4tF_)rW7ngPXt8bN-hiHk8%tBfE^Tga&}Y8Ah_nuJuC-6dmP0_dE>TXWVWfh?@< zBspby-XI%7FU@kp=tE^Hu%cag-DwL}0;vahzpif82CEX69*>z7T@}& zp{niqtE5uZ71*0gif2 zm#%#pGAg0HdlP^SSxx)s8pdQqgbMipsG3AR?Xrj$mz%(H@3GC*yDcoS;ZJ)84oE6D za9|JkT0Af1Z;d8$MX1>y2ufdU#GdH4z`IR&5{20BBBh7*`8ae=)aR@SKoZxe@(8kF zu_5HWk|~PnajRu9!OED|B&~#v`HRc%^S^>4lbD=X(Kmq?2eeM6+yEd1cxZ_>#8ev} z{l#t?&l{INjm&u2)IcMCx7vSDGcmK_Is=zi(4Tbzy(*3+6|7_IIkRk@>ZW^k z9grvPrgfW)6Bb)RKZ^v5bw^jQcF`^a@*r3MX2$%mznJJ5>V_N>dvEF4CjgW1KNqra zqr|&+?hL;>k*L-i`NSPQECX`wT5=*_A}ngrAF!tvk>rywKG=m5{s6K$AL?KdE50E# za_x*Fk{2rm^gvPy-nizi{n3Q~M3)}++GF)V1?mmbg@_3h7(n;1W1l*G`Vo=#BYV!9 z?ze*suDp{;{~G^lrtm02u*$#!ToO{2yKA&6fEco zUV&8dLGxs18W&&>Q%Fs<=)d=+I7t^Ez5Ixr$H7`Wv1Nc4ibOH;40OdBo8T$rhnm4+ zFtPvtVRtU>+2bc_#4$ot4$7aG+Qc~nbi$z3@>5TuZ$YE1$a1K{sAt{XBtV**8Mz7l9w#gc3C1MCe^{EPTO9pXx65SJKUuIU+9o zdkZM8m$gCos707~xm|_;6MYA|F--VVef{SKP>&T+sFQd8gKn*01y&C|ggV=Voi5%s z)D%kdiu>Li%7^#iu?jv!a4a&Qxxslq@CQ@`s2_+FSR_RmPN*sG65-$;v3fYkwc$`# z=fKUk?oHg;)eR2!ys9mM{K{W^^oi4NM{O0VIXy72q!ubTM`D+X#5XJr*xmNOe(Rf+ zv}1u3hjH87g^$h-e6%;>qoGBf7qFl6cVh*f%j~=C)1}bUcyK@uk$d5s-zm8f1VK3% z$<9TV5CzjvHHA)D_lk*3C{}UdGCaTWbzy`}kbMqhf*0U0jB~smDkqYdH4 zIu~fVI&WqsLPNtuu(HVG%eSdDonAhT#oACwLUQDOi)F>6jU^sBgPf3<5B1<7 zAOvdc;4uOwr7T<|wqrdQkdJVmEQPR4h0IO{kafL^+>rU9jvM6GH(^{ztTEn1r6@M> z8HIQgvW}*f0PP44dZQhjv3Nr9T~XRHjmIKnQfgUNO~_5;I`0AUBuaIyA~AQEgh@`d z9$v^b2`CPN=F$mrD2iM@u-b=*&R_+6Oo6@t1jHxSW|CN;Mw*KPn#-O%$v;^)m2ubN z=}AL5DMtn>WJ=3C2ZPfb<1t+itmo<@^u*;^KIO(0Re6Slb3gkvQf_fq<7;7g)-6o7 zg;y>*C_~^2bC-Eqhv#w;u7UCmun1(%G2Ww)3Z)P zP{Cy44IRm1sJNmWiGiY;FRk4~Nxg!j*$ldKQgovHwnvX6SM^>>2+Qa@6gkr@skquW$XsWOc zngb)VteSL5*o5a16L}8;qOWo|n20>thm|nrZ1!2+IxO4eM%>kB5OufjCi%iNupn`lZ1^SB~iQ z8W95de|_6q?)OW0Vifj~w0rH|-|Fmo=h3hfD3AJm6eU_w9%Z}bGZQb8ry?N@1%=gw z1Qk+48)PMvNu+^AA@8GcDrR7DNyvq8fUladX|)8*Wx}mZ10p1)LsqWDCPKeuV9@vz z9c{uB^pX?8Kv^w`;I@cQucm-GfSNI-*ocIYHCyt@kAP`pc`N0bSTLXt=)*_YAOjjWIA$Z?J*=}J%lYkWErlZEgk zhEBv_1vxP|i^xE#<4>NnV^G&PMSg-83Qu?oJ&aFV=?x6tl~eIS=e9>LG3{1LA0f^;l&JV6DU3f<%BQ z&YQ-BGH%WJA;1|{f;qPZIvogOEd@)xd@G<+1b%Vn`}~hz12jq6@X>d5?D+SiSCZCa z@1ZP!Ujcoz+bhMUM9A`?h~bEffhfW}X@j6DG0WZ1=D>Ozd&P`bNFpKxtJ3aP^JaW= zMpObynoMu7&#z$>f_>&X4+i^TQ1|6vKVml8tAhO+v(EMe`?V;S?hf`h)PKI2n&RI^ za}|H@f zOi%B@9Ua)p0eAW_${a@LHU}!wn4=r-%3dD6DV4^x1$_G{B~-8lDcpf?Ve!*ZYx=Wu zh5l^rXxi)cbS`f+eRN?amBWel_>Q*t4iZ^S)#~vBDqT;5FKChZJj6s|Jxsb2)0*4U zxqK!&=e6y`K_$T}Y>vzKw({uW`1J6duPpRgz<0LD3;E4pXb-$)Ak#D^$m4SoXBM!} z?|)J51&qYDWB4A~5Vj-G9NSioJXAFTHFq(>NqiLFJL5OXE}YjfY3&A&zk2RCBc*!?{?-Rg9RvyuVNb1v+B^zfsJ=byP2r5Q z%gfs%u|+jVd~vp45X<5B7&G{0qk1^8hL%IU&%gs{L-d2Fd>#*MaUSjI0YojOg*H2b z7r!~lzO=FoY?7l*;f%JO$CWI;OPPkX(az{6j*11?-n{hXsE)UCU)pCn7?oog`K<6ihci5z4k&Z|ltQKbIIdG3>Qhrf zlO7Q-q8Q6z1Fxk-PAbiN(1-I=y7d1E@l3}b(O?$sX@~T94>U~Um^>4Y94*w8qeQRh znDf%MfbkVBIm0~YDPur3kSW2GC{(sAwG7Td4H9Wcjnlw|*jP!k%0?+(KtIw%t?IX9 zCqacfGmDXVJQbXCJVgT@RVT!tBd|r-6oUdpVhuC0)h@9hY+PL<-b@rA#SF#wuE6TByp2eW`4no>ju6 zp3YtUA zQ0^Cx|C8vcvUZ%MK;JyLIteN0xQ-9Dod88;TFMCNxMvhsyLH}NNvBe-SIF0;G@xjq z-=-f#yd8wU3?iNkBOIWr??_=1jw7TX%4pZQYxZ`BwsG*+9F@(rK{juGJx~%kI z?;`ng6yNh#Z|7V$Vid-@pHJ@USBwQ}Ka73!2kI|}oLl9oXp_g7#BOIDs!7G}sL0!4 zhN5^D?Q`hCqcVrY7a{^VrtMefU+R(S6V+N)w4uCJE6tLhSNd#aRyqv&X&;x;gR`Yd zFVBldOn|aVq^3?B=cJBWrkoW;h@G0XR#!BP0;HIpp!tI8#nC>35m^7wN*R4t=WUmw z+u4uHIy9efC4y!om$ph5^Oq-H|=zbsq}X35Nx+1`US&$n%P42Q9dd}+iS51(_0JH$uw;Oy9GwnyYfS>!J3Wz+-_`KXMoag3uYH)&ke za~i3S;)veM8TCBU|UCGDDdGB(j~X!WaYT)B6; zyR@8?dsbnis8j|K2Ur_3B6xUChUm=w-c^x;YZ=rP{i|HiD}GWl#C+A9@=gj}UgYvX z7pc_}bk&0P;q<22Pc_$Bj7l7$9jGltaimh<8jKtB@_d(P(%gr~F4H|3CbYC^c zbrrTNXL~#8y`!Y4I8(=*crxz1=E-Yr}X~9@|}2Y}U%=Qrxn>u8!WEo0xxO zrDAh(c9Np^xthUwnc5a{h8Z63x@%dW;4jzZk# z%$!eaGuHEz5$RZsJd`wBa}8%T=I9KULu$?JHQKw(p59eiWhh|!fg)wHdyIxcN#v@o@zU#7mGt-Mf$!K|Dbyd; zW1=AAkF$ODRy4U(9?v|96tIVCZ*|5-DOB61%lb$s?Q93OT7hybBGi5OT%FrZ!*8gG zIkYFPF*cJcjhI9`joq3R)ApQYmSw=qpHYXO8MNnInv+tJwBz(eM`MmJBToGDfIXTHmE>8p&dnps!p zR*J2;z;`+V)L`7YoOk{*exkFLZEqAbT|A$T0=qPyuBwS-(>ZIP7v%8bT$)X}OfPzoTBte~-HDmUSA0Xq(AdvaxN_D!7wE>- zoGxBeX9a4Fv~6c0noAI+RXS=ZQL$T9YnIG3t-Jok0*EB zqogK-RSjxFuMjm@?_bW^b=3O=1-WkT<|fkKgE6>fLhGDFhRGQ#ZK*o@QyaLLJT7lt zu9u=?d6tVynmjxFacy<&;d0(Xd%7@x)J(Li%5IznFN}_q7^h8C&pJ$bVv^W`;XR5TqOV_TI+7?*7;q_WE)D4z%MPCQthD{_-fU+>Rrz z@Acw*Gg^!V*P8{o?!Z-!ID-E#a~xN6j8U}Xy|=q?hGP?3hvg`V_N@Ns6MgvKHT9kr zYecpj#V08}B=_t%CoP*j$i-nCbAJHm_676t|Lo+vyvN6Cle!|M<2YZQwVJ9yw9)zc zL50d?KX_1@`Tv9RUM|PFOXlyF{bA|Fev}+3?ZNvHK1b1#cNh<&7ms-MFt&%#PVYE! zWKuSrNz|_%8C{8AF{v<_Fz1sA^9J|izBly(S0=?jG`lG!&y1@K5SL?lp60zR!T=T zUba6{-HTaBFZnL(ypmo@ezgvwLicJLa5lxUs2$2Ey+4p3 z&#?`;p;TR4m7%UvP=Bw0HnoM07hS~#`MN`7R+hTTnH17aIHOwwDeIVXl4eH_ZI-s= zJfSQVdKoF3e#zC zY;edMnNQDY;~{O(>Xje;Fu2X5^b1)pU&zejS)Brelg-Ucp2$q5qm$|5kmCGo8k)i=6WJMv zFPlphGRM>26!kZs%N|Ql6!NVy#KQc1Hdm0@DeRc$w}_5A_Iiol+EdMYV;T{@0>1>FJwKPD#%p1bUvMfxT5^|0Ju#+F8L<8 zt0@tp1KCq&?bGGl4lT{OV6ZJWfv!Nq64pRaz0HH3#6{X$ffUH$mG&u zez2cl9%usRQqZTvi86M0lUY#B$x`$4Gbf{HD+0_;EXXKgkYHsYPuW8F!I&5v2bo+Y z127Bx}?5#Yg7d-&Ar*k*v zw_S{O3UC7Q$-!=BQ@ML+S9veLFfmPWfJs<)R4oG&W*2f3AfFSq!VogBrvSfbjSz&g zEdB>pnnwf8DwGaGy_GyrN~-ewe0m}P znM=($Y^xlb@*#8pC-}r3v|J@hdj5QN4r9UI^3h5sS}i|sMSh&~p!2>U98}J^%57$W zIkex@q&QU}+X_w3qzkZu)+qgB;Rryeu)q`EjvWpxJX{il$s%UpwAibnX$8@WuhG>a zfL2a=6Vs_V2<9m4EH|4X0_J#{FzGC?S{St0=v?}Qm!3PG$z|s#V=~*bP?*lTvTgUMSoU3TU z^oROJ4-Srv!4bUcz5OG@y@694O6O)Xd3g{M_6aaegE`DT2MBCc&}Q5K93M?fh@b?6 zsk284aAHUyngR*)KmwI))!fnv=%b)}5?F$k0N%6=D6kj6@X6LH=+hViXq~A-Y53g= zXk#b@o62dUE*-&i3r85(oPSTjezPa2GDvF@Q7Su^?~X>>wt2&8Ox8D=xHAQGNY zZa$kXpko0!MJ7EnnU`FU{Wt-JI06_$CZ zpq&nwM)m@AURo#UCbU=Kbd)%);Q~0H_tN*xLwcElM|UnD6M`>QIAGv;L>L9#9O5~! zm7o{hzoHOD(IBXx1-w6i<~gP;h@A9`016;R1S1H9;g2DLAU%&>045rO#y>L6M5=Qe z(->(-vICc1J+)lY3}11rqAh)B#SfXu!GnYB0h742a5h^2CZy*kvpL9(jy8!@qmaP? zASSxni_rAGiS)d1>)i*23B^dAUdbD1kNIRSgoFD zSv`QP3E^vA#-5Q-;$V(no86=?xBuP-*h3Sxjpmb6Z zRz+8BFEI_|=c@b?In2d#FW|+`mwVANIJQefydd|AmUFKvNkBm3j55PL%(tqmx+7^I zCKI~_7z34XJexsAKP3|cHs(;rp)+&WD7l8eW9;6+vHe3mg9rOYqvHqqv>qE9=^wwN zXSB~79P#g zPE=ZBW8TQ9H+b;S&|qJ0t2a2jf9P=U;P8OA5B-KmSn(Yk9LJ#JBhob(YOoLe`lFy_ z{{f8Lvu|){aQv=TuYYiSm}B;1&>rtl&*=Ez{=-8(qu!yzqlZRNIQ9(pV%Xuq;r>y~ z(s!_LcsvTK_KzI8Yjkknz&O7D(KC*dt={-(PjBDBp3!70DI5XIqn=;1MSiVbZ_mM=0dnBRWi#aWv-h+ds%1h;DGSZ$Ah`ONblH<19u(PBGT^io-a8cF|x8=-@z~kPe!A@NYj& zgL*)7aL94SM@Gk2NV#KhtgqGU866yhc%uEIBL^`!RDm8;`eBF=bHT)vUaE!XcuflQ z6@x%4_KvFHdi#2YFd*z=_`$#>B3t+)5%7k4i5XK@|xkPX|2 zt+BPX&aSa*ZPc!_>+J@+(QdN!_&(ugyTvx(e^}mXudr9z7ul=qi|y6+8v7FaYu2+( z_&(DA$G^~In{A7|)?R0?w>Q`u?Kb;TyWO_h9d@U^3I8ucn{CJUDLe6P(_Q#)C-&gG zvfcJ({Pxhx@qOJ}?5(!P?z8*x8%YnD-^6btox*P>y~#Xm-fG^5UtId2?KN+~Z!Eph zyuq*o21*q?ve~YJTGPqASi+cuh=J#>0;9j|7 z$|r6LxF>i5zY=vHepl)wzIFCG{I=8+=Kc6>sn?sLc@V!I^#k*%IxLsO@fRK&IS?Kj zzcbv&_sDp-Z}=7Ap8d(lzP`Rgp?zba1LL8g{?P5?q5l5R{?X9bNN8*@+&k14?%m&p zcRSu4cz1?}dy?U?yM{5)zVQB@;ZWbf@Yvyf;l8o`q5iSZz*uN>EOdBG=iS|}+dc7M z+ZJrwgKbB!?F_bE!FE@$-5qTA1lvTg?FqK~g6;lb+Z$~Af^9H=BA7oB%%2G6PXzNP zg837{{E1-xL@<9Mm_HHBp9tnp1oJ0?`4hqXiD3RjFn>=le@}3IUoii^VE%pbA0EM@ l@e7LhwKRNBFmPyoqnO_drmypyo|n&W4F6CXRsI&^{{s@}dLjS- literal 0 HcmV?d00001 diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/display.gif b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/display.gif deleted file mode 100644 index 1e3213c3479c82fb62bf490d6727283c406c214a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55344 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 diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/display.png b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/display.png index 0d0424f789197a5cd058b58d1a17893911fecda6..6aeac45fd5c54093142650ea568856c80686ac7c 100644 GIT binary patch literal 324953 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®2gmO_KoT9XVzWc&03~~yc2Ln(eAEt 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

U_N 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 z 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 LNkvXXu0mjf<)YDs literal 218780 zcmV)AK*Ya^P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3&sb|bkFg#Y6dJ_7dTIN0(%-@wQBm#CsBvZ?m; zjKwDw1)>1t77$utd`rzx^ zLiY{9-6vZ20UzW3K2f|Edfe&)!yguEwfgfp-6x6HjNEE@@lnXv$DU@ih4J~#BwZ-l zYtQ=pjX9;*2~FmA#&cE^GcntI!ybjrV-DwV*NdC#tIvMoB_jr6;C_HXRuM5S;4W+#%>%$lIId1ItpZ0pg zSBU!C2KUBgGL9=q8uxJa9q<0`Z1O9dH2+l4Rxu~O`eqWol#TS) zJgW2h!rA`ni~F3e^p6FN1>som<)iR8^7D%q6I_ok3w@>cbNtoW;fEXY599r(h2{@8 zeBJn!U)P`e#->MRpGqg2PMtg6eaQYQ4;?AIJ96!}^UU{&kDVSnKY%{p>Cofz1XrFu zzkf09F~QH*8{A2|=ik2|2f_>4^1A@cbeDl1~`Ol8NlKYpG2=5C$ zZ*V^>6hD{8>jvgopr224(Dg%BJNEq!EymxG@b0sZxFdY@o&CYI@V-!fp6Q&TzDD#M z>7$R{7YdKd4<|i|^n@I9ax?_B&Hk=DNLvR3>TJj7_?~~}N-z>@$Mm4PQk0>di@yJT zoB67bzCOMQrzzjO`b{@Uzl{m@%}4pmx$cv*U3wc2->B;CMCso7(a#j9gA6j*egSVw(1@g=md3^3)xMA8I?{nuIC*|(kjCKSEwa?B+EC;R$e zU*^-`-+6s4Br>n`t|#>F3b6Ng8M;$Lj#&i6J@j`v{yi`AA(Jl+5}BrMt{B+uxRw~n zJ##CZI0xn>l>ePxuBXe}n^Al&BX_(n&f&*Od^#uhA^JfCTuOd9Bg7^^ z2F0V+*qeKbJ9B;V*D!4bfk+`!W0eSXf)!&Te@d+6P){L6lTym5q?%glIb?7>=UlS( zC%uFcODegPQcEknh8kF(YC=IwD>)0*Y%IGh1DZUL&V5v(2l9 z_e9Ml4bE~JF(MeZ^GV!S?4FVPZQM+Xe-t?*9=vqoKPa_iNlfL~SW4&Wl`5 z6<$0hMoYAH=fgl@b6GXM&)EQ{o`>@l9Bf2j6nsA-R*hCN(JZt?bS$yc9dZ6% zR+hL3u8cWGm9T3s#mTHRa&62UdX7noox?YgOqV4SFifq2gUEwzScgN0S+uUp>?4#M z)+k~7Ugy}Mjh%zAy5}&PsZkn{nOj5!1`Y_GtxQ^d%wBeCi{5c_=pcP(7L-~gVGxm9 zz6$VL#CP?v-=z<%$J3_`O4*5N3jr5)PxKpQ$>^;OSsT+kjOy@8YOV@_ArdZ4$v%(4 zGBQ?}d9W9Z)s{*41~EAH$RYzNKV}`1&9|Vg*Isqz9i%Nct1DrZi1Ryv6-N7lmEfhG z#B8D;hVX@s(kYviYR0z4Wzo| zxHpg8^t_36hOSdPdS1FIRG!7K;`w%TUB<6TI@IfZM?2b{y_JMq#!n5Gm7(po2v|(s z;*Ct-U#H4!s$#9Un-uEI3Elr~Opa^X<#Qf1XMxBjSL;q*bef(J#!DDyT*!U5e`|4B&K_}QUvLt(BIQU0V4)r}Qgyv) zGE_}PA2WagWLGqU$vsu?cT0uYxjLXs9Cd{V84K9VE$K0w%8;&I^cc9%r4{p3qW%XzFkn=-xAZs{u~|f<1n!u1!!85NX65b2*35AYgl^mBJR2#!ZRxaG$LK

F$BscQvv6kiV*Mti8 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¬^WMEF3ax6M07;c=cwZ6RR zkgjW^6xq0F1@tbMIE^>O63Pv~c zxuj)8R)&mP2i#1)lnvKfN=3ighTU}XcZvzhaU7g7bCN#?O?p;HU7Tv|$=fc6@<39^ z!s2Q|$TM%pfp#`5uQ91ZnGgF2PMiTqQBEG`mfthKXqgedyA`}@revc%`9{p)A5A;% zM~!TQPI_TZ*=Ta~nZ<-@%#gxG`upzl5=G|J{A?qLQgaL0ot|>9CT1&}=ge{a_MjAI zo6NNpn(MvhlrcCp*J;}FENi;Gav2h?tFbt;!p=61nWRPyUS5I~I7%e1nai0mfxaYE zy))sQ?_Gr9gDJGyDJ4A458Uc~O=30Sm+#*S_1YX|+>QgEpPwiPQPH|GTfmLQ;v)$ORSWBWwuX8;a6M1VF>uQTSu&JB z8}kQgJh0sB;Li%*ltU6KgQHcMMHO2YLQ%?+x7y#ylsNN{bbrzu=sFgNLv3<8re|_k zp{^wJ88K^RmMEVupxoBMFPX!n$=41nNyeBBi3G-!3!A76O$>7tg|eCNqvP{&;#Mj* zCU(uAkB1FikZ?XPLs9b(y4q!+iEcr$$6>|l$B&Qjw4Lq3c{PmQag>DfyjDyHbMv0( zY0@wj;LUNNeyNriGCBr#KT7Tj+p@h-LCR&U6q;7A52xWBz&s^atU2_(VW z{Tz4$HagvqQw>L?ziUrp?YwAKT)TnW<2i$xBHuY7TqSt z@890hd$+StO!`xAH!E{f=tc zkfl@%ow&ch+15j?`0dTUo01E@e|wK@33yJt-|yyinqu zVWS_X43&&IdPwfPf%R=w78046$>lI9CudHm=}G29f}(dSNy3wsUI)7{Uz8QMg?%d3 zI9udK4DQnkMW16p$He)3;QRM)tF8jA7nF5RO6|lLvIWaTg8mgN;W?5up zDw2PZDPg!8o5Rqk%R^?rYTbl{0c!$>n)l2|zFhi*m0?|<$8l_S8TT)6=&uSXDdJEj z6h(4uHdj`pvIfs=lv8-U3v02wskWTT4h1x?0lTWA${M1`_E|@+ApoHV-kwX@(@v3O zML31WZ-RuQVH3%cKsl1FgWKrQ``b9N^h^|axt@g;2jCyczk}Mw`WX$9JQ`| z=*PoG6{V~OM}6hEO(@h?7P^8{H6(y0b66d_?chr-&~6X1QdwkXo2I+$a`s`{xtwve z3$u4SFhfe|(h7O;2KbkjebS-8xGw7O6TM|Avd6?VLV8+3gqUGuUEzH6oy~z#DrzZsJRX=^;I=_wT#Cl6!I%N{ zh=6R$G$fhvzKQ%mD0zP;iQ#RsFR!HLOF`% zymXSu&?Tf5KHYNT`=0qX=@l>t1z%eq7KGS3Mph$;Qdf;l0Ej?$ze@8wp9>S6tP##c zMYroRDGH^>%HZvsYGBmI?2x(pKkakBu7>-KTTgDs)bY2lYXgDrCqYUlHd8^r5((4~#Ll*1^$o}v19RB3CYORXx}mE_Lu(!Pw;L>{AV;C8lSR_7#xN(~IZo7i zBXnxoriN(niDCB|KZACiNHtT!mM~gdO?WNVK>37Q6}cANzrDvKd1}Lv57c_#xE=WR z{mr%(r=8RH+kx9r!`GSwNc9Fug2$r)DdT>-#WgUIjs6Ot5Y#nB!|XP=iETog7?+?+ zLK4HG0|sP>IGb(^&0H!nxBBRc^8RjT!<-zx+5jmj33@VOJFinQv~PBb%xCfp*{3b; z6n%8$+nv5OZW**Ar$W$DM(-!?@9(j#aPSit0=qzEvdKpmZPd?soBq2}fl!W;?Z3N% zg@tV5{p++_9|U*L9Zjxd6&xi4+|HN+N^KYklixw@TASOzQn2|e@rCM~tX@bEuYky&Hgu7JwCV%7%h9R?4=)tH^O*`gXAQ$zX2FN^>3p zdPm0wc;lJoGP^Ms33qgBdZrGHYXoV~6-w$M@|483);0<3I%g-93Mm=9ske@kn{@+t|brdWG7ZlTQd-IoU>CJl4jJXjJqpm=}3V~)ZV>4>5X%s&`?MD9T+ zy`|BBzNRH6AJl0W@F{|eZ(LHsw{PDV?n;jZ5=I&}-2$h}eT0F((R?0$6C#is5zKFI zZ_BJldY?5|^Cc8B=yeS0bkq3K7$YY0{(gK@=RgN9a?jp^B2#jvLEbKwjD)LS5dK-0 zpLr8EbmHvIrei*>pbx+&JU#{X)q75r#5kh?Mz|g?F7v6_>zgu7i<@!;fv&(_doOL+ zVQ$)1jl=7DHXLtv7LH#x-?W9kU> ztdIniQwnpaPo@KulB`e~b5Lfnwtu?O55=?QUeR=)AUcu=b2@55g=06fnVwIp2UMN_q4Cbd5^ zCn~>7U(-)awCh5CyQ7q}g3Fo7WY_9|NHv@;6ocV|CZFhbor}pBQ)W>X(@et-=j>!I z^Z!kM=*@|PNPJrY+cl*mR<_1QZ8o&)vgv2H>+A5}lQORb!K0n9=Ug^vQ*X$c46Dz- zGm}xsp1tAx_=rj5aoq5Hp6J(w>$1$5QZuDGCXe{>`)~Na|M@St-K?PWqNKMAQmo+- zD6Yq8Kn6$Rs^atWiF_0mI`Xo)b03F@;p1z)0jZ*0K-X^Ii2SxftdoV9-`~pSg|n^s z)dortYY^!H^=zg=B4th)b8OA@P&_^#By%lAgHFVKs-D&2vRA$@Rg(r~W=}oOw%{y7 z(Z-3#^U0!N$#r~+Ip&B>-~DDVp4MD(p%}2KWuL&DPn3K(EDALrEY1u-;hT+|3P$hf z6UbTj(L8EBY+y7Qm@JASm6H=Qt@l2{x0*L&w@&*$vRJq?L~y)-ifmhY)Fb4`!v|g= zL6Go=n$$eQW-6X>WW%V*2l(Jt$m10H1lq;Jeq0QwPqmC;gMNLkA#YN|N&$cs_ghXcPT|rI@eH3dtTGrrU8N zj^ED4dQ=>@8#lU&x3_ONvUtoMeZvMbIPQ0Dbuzwx`v#SckH?Aot>UN$lm>c%qK%HD z9xUROY8n=a!?rsnn;a1$oog{!rtHIC4asjJ;9!!@>c)BxpHHMJPEu;K6rAk@#>8>l zHWHl!KQeMY@Hnp+Dnx!+a+nuzou|n zv4U$OwA?*4F8`vBsa+?M%-9m@?M9iN)lA1xLw4;1#lmdIW%E#Gec8t2_uqfV`}=zY zsEbbYXO&u|0C`J`r7a7y^m-_BG(Rz(Hk&R#47+heKJL()EecW(D2YDqzKsdAm#I#R4Np!+xdBT)Im*^ zGG2$)Y1m{`6;g`D>F^Wk1CTs{F$n-9`8y=A;P%|C1Wi{>xeY3kGfvJCpnCKQ=}rqSb{i)G5Ghf=#=6N|t&nYCIB4PPz)rqr&&W%)5i`T=QVPWA#UuSgRxx&j#1Y^maYdyh$NJ6nWiCguXo$=@M@CT7OX z_iPeX2p(5M${foj3u8T>A9$V@N-pT_0+8_W;|KcHFuLMD{`OZqK0i@!H$2ZzJU>o* zc06q(;1aWx?K1{Qg7Vy}X+VJ)zh<6I)asZR}^56kS`jsm=Ofoz% z&}@*U+oX^&1kQ@;PSM)pH{7q$uWL1Sa6e~SARo_~@+>WHH29vC*Pg$q{eH4%t0RgN zx{gpMC{yFe`$y}YnK>IE#i?l4C7E1|Mv2{>>Oa$lM3k-4Lpun*&^`k=GuddeQVx=< zoh@@C)&e8VAhm)p49@_Z{NK;>M9GQMZ9${tb5i=dM}>q(fcSl%+R_ zxEkw-&Mn#v-+%dzdRWd_Dpp*T$`EHakF`LMYsL5bJ47b#Z+CqE_6r-BiP;A* z2abE?bK3kFN*U20G{wCsV@%v{E*ng-?GgstJ2`EL`SeODv2_}~q1KF?4Q)S$MpJVu z1<&V`>Jd{>q-?;C&&Q`pn5PY~Kv39VG{&6fLmi-OUKPbdo`rsUk1X(*3zZo9V5(7M z_dz#RFx^SMV`3JoA!@BgiySi=jy5_9<5=wco@`Vz!;04(-dc4%>bWiy+2GtRx1@{gry;2jt1Q_?8c_lF@kRiTBa*iG#Mq> zh`hR%D#?74drZ$9K&{#Q{2q}p4WQ+N;@B`UXxOp+Zq%L0H)<2dv0@_f*x^_>DKSY#K_7~IFE(u)3l*G+S0241M>lOUt4Wk}=Bjb-n?R+sv8)WD7v#1d zM6HJu?rZ*+ch?c7$jp@1&XwPjjHI%!um=lq3jnr*%7T5XO~l%XdMmj4xFs_sFv zp7ekP#u)nIjq{t$zn`3wWd$)SB2Ot9vTZb`>WJ?mk+9>b=Ke3s zNXjUZ(dUfGu^=JYsE!j7BTgpOpy8N&X_5LYUoCN}%}{Fk@Z1xmG;a%0^iG4UwM2;H zoD)}TXw$$T{%7ax)SWLG)(IqjaaDWri|1h#dZFeO@o;N$a?gNcH_{`EKf`s=S4Q*o;Y zMmJRX=ksLKWX9pY{{91>pC2eWk(x9t;JBIjR;NI-263>v37#MTH&%mmFL*wm(>Hw* zDhLoup&Zx_w#(o?P6|^CZuRH`Yig4f;(lhQwBk0zVjojlV3KHtSx7l8%QJP5QVfB7 zz@rfoFX1=D_8ePMM2P|?Pq|_y59| zOT0ecn9gkzU-(*`)HVBz4b2SpEZ>V`=v`%zQ*2q2h;0dD>F6lL4SVf>mjuUn&rXMx z5<}A*>}ZgdXTvFpbO8VWAOJ~3K~xX*Pyc$^Oaia)*og8TP(+zN9|VVgI9u1z(d(*6F1c6A#HdQ+ro zeo3zj<}})}NW2ysa#``IhGT|s3p$xWY6BONdU@`&)=)|fAEgKXfk1ye-EY9`Xw70(KA#VK|NfnJ9xK$bWyJbt`2xt$ zl_52-5b#<2zNRN|s11{_Q7oy9G8OKOjc;!q$L(hCjpWE!D)8B1nX~ppie(3kChG$+ zYpHCbZgg%cm3@Pm7ze}nBJ;|19LJ5r*B;yeP=VwSKd;d(ZXsjxdG2-FK?=8f$b_EI zx8p`R{K1BF>tnLP&Kz>)gVi{@cu?6jXR#-pQC1eCbpiBiiZXI%TC?m8ntDWmDoSgO zXy|Hi0@3)zzRFdZk!@k!FAo|WFVj13m{PUrSuO{3_80P4piH;JaNnj?pMX*FmN$Qu zWwi9|fp0lPQ%nYyXr?VJ1ah%#1jQnj2vUUR+B%a270RO=Md^ocXJL`1LB{KmBY-X@ zA3=!W){Gkgo47d*PrsN`85&y)bhMaAS`JG_DH*MeFa9{NAzY-vYh0*D3C|P8G#&Z0 z!*W=%p7ZLMb+R71nTE`jZDXtE<2d->Fhg+88ST3Gn(RhSIU7|;mnY8j%SNtyzuyci z&nEAb@7iQtW3e~BTL_;go zyntRlN;ctHpt)jR4Jl_dZW-?HZ|HO2!V zhjS{oh;@LP7cFt(?~S`8^Q=h{Xi89*N5cys3z`&8jWIPylAOndWX6Upx_Xq!V%{;u zJk)EJD2$cQoqh6Hb9P%~P$2z!b%gFtkQ|Ij803W{C!TpR?)QSrk-B{*dFBnH&te=G z=AcI-^2ex<^8%SVcJ=%$M?{O538Cc6pMMv9BTI=OO92rZ;td!S$agk-T_YIU zo3t6`W@gE#zBDKB-|yQUzPI>YW*}M675<-#gC;+W`-WVOAn@VA3y6lq&PHyQ`1<=? zf7byA3(qX!!SFL725|(844SydoUsWDDOn78mOpcUjeZ?yY${i5g(%R?%!!zkZQ_V+Rn-b=NZ#rCk_mdEw|IRe*Sv)!g6SbsI7)uZ@wTii5fQ>;$g>< zP?_`R=UpEYKYl-BF!*RsOa=a>|7sqnBn+1q6v?PHqu%dq#ufAGro5aJZ{NS+AAb1- z^?t**Z||7BTOe)`eE-v*?93-L=G!$PgU$zLksw35O#eJDTMAGH-5Cm>lGO)oPRwq~2{1Omq7_)9QK17} zi~-*g3KXq(+-~=fd3&S+XbXvOcM zFzY|E2dw8J1(2S+K1^1ZEEbj|E8bLFbGCPSod~9m#=$ zSyCnkI*8$p-#h1d(q>|oh-D8-sAM&GW^2in15rgvceB2DKA;%yqTVZWk}vc4v8R#$ z`Op8IB2jP3F245>M(pe|371l^Xb`ar_UadP(v!52fvGTGPQD?@3|d;s0PDsme%l<| zq)#_|I!j;=E2XL14CB5oG@{~|R?wS#vLV+LW>rav;kqe8))sBuRhJw~~?tuX5FX$bqY0w!J%?xMP`B7VtLF+i4fXCJXeDu}`*)OxBUA z$*FF)gS41qO)**Am|w;w{m=Hq+x_kpQ%E{}ohs8VTHz#IxdkdYLC0mW05pV;IicN3 zxlGT)WPVL9473!-iYlQHCZS3+{r>j(1MhE^cQE^4J{z^qUjjwl8yAoknNidvCmz{{ z7?U{5Y$Lw&XjnLkfB37pfsZ=jb6^cmRpd2o_q#jH%hG_keG3K)laUOw zUFgi}LQK9AdL#B3%X|3v{Imy!l#o|lEW$oMK20i-1lM`thBq9`fmt1D-K8CnY*cZz-a1 zm6SsIv$97h1J%vYOf#})qWFX{CblV|CJVdXsb4}!NOw%Fypl!-w>FM?Uy{RRBn}yc zTFixTqaW15ZOZHSN$Zx=d>c>xFHkt%M=mc zzJ0T%x0rA3?f!0f8J&xGKO z5egOC7+lO2wXF_N83E&GKDu3nzV*>zo;DG|d0r^@0~w}#XjelnnVWTGyv9JP#RBU+ zAIk8)Cixr8>7u;Slv0-a)us)_Eq9HXc`(1Id6)){gOorx41v$}u$KTb#bQx%wsVi( zCq`5)%Y_1(2XrnOKgRNKdO&sNpxp0+oGZ@j<{deUV`fUA9d>uIl} zn`G#>-~J_j-w?s)$0yEbNACllpFeP(4d?SRSq%iw=MT&A>6SB+WCf+$vqmg7q1k6@ z5)9r?HN}0Bcx{6|jO)Bepj<)Bz(6K_%3>=hwVR5ZH4Ng3!NX%%(pu!@lqJ{l$(29s zpJ$Jv*CP~^F#^hhR1_Gzwku#p@zri{GV0x}#%557LB4u3xo6mlB?@SrYr`XHZ6NJ= zyRt|I)179h8uhg|I-m#3Nm(QO5vwZ@9+Lj&zn0$aXA|rV!2(H4EJ^MD_g#hv z0a53ChEDy`A!roNx`{@)+#5spNg+`DudiYK zYYqvI^YR(!OKgg6TBon?az@9u8Z!?k{@O_X;g_p#_B6!f@skuUpHcjit??ARf=B%A z&!7FC?GLGJ`H=ooHtEv>N_{o$X$X%%)rzM#{GrLFWGk*2_vOUrMVX?^b!|>%K=Rs( z`XIyonZBL%_uq9vV?eKL!hlQ*)x94_+&jiBUD`a}~A z^+cJMjE`SWJRVQWts4V5S>ai7!qo@fi z0Xp&h?Hlel<~inUfU6*umS~bKo6bo;GCkFX17xxCya#C;;^nQ}6Tu7icP}0>cP9mtqoBRx7{&5=~S}l1T)#_%} zwzu2OzPmoQ0e_~A!y1x8^-ReHSqi#5t=NaeaAZ(+JJ{$YHA<%qmS%wIUKF)@{@teN<1k>~|N?#>2!68vEU6>D6EXUoR$bJfC$zE>M88sKE98$kAe z)ra+{wqTh{UbyNb*-n-<{PfJuEaowrL*jg}W;|~`=>@-V54$&2K8(2+1B)fmh=LN{ zKi;G%wyE6a_x4|s#kOhbSgL_qEp+_+eA;JBU%345|KWdBYYNPi=Np7MCo%I23!TJ_ zt-j_J$_-p5)-F=t81m~9wM>$ls%d)tV%fb7zS&Bfetz;jrAg_-wA`thN=&VDIn38F zXONgm%Aw=*Lf*+$`=)ExYsRpf(`^e3G^EE=zXZ%=FbN=uRXY7LCN-O=<*>=W5hiUU zBLb*3w-z)A%WWB!(E_6VS0)%@;^fk*B_|sTp{)KIG#aVF0N>r^<)PNPv`fY|M4&A%{&W_&!^$-RdKcp&(9OJaBbci zYA$G($tZKmJmflY%-k$-m}5=&xNmDFuT}hNGG4bIKYhtx7d7%)kI(pAUjN>H zkiiR&ZEN@U{v}`DRKT+<%Vz@z3KYTO$1%??9KO>gRvrZ?3Wa zb^m(V2FjNoyZ!91{~TM>{q?oKe9m7QDEa^ST4nnJ1g{%M{X$)auI)3nhH$5wiE9#f zump>x^}gjL!^nXX9%S#Zj>wHvKRXa{0}f5{xR0Y0ZV%{}!`hgEHHRVmSKzP3sn|Jr zU6*afz+#qu$efJqXfINcGjPA%QEEj=8TGy5+qYkEzul2@!u_BvL=_nc$NPcIOu?xW zzr26P{q3D_Cc($!fs`~rYdS1UydE{A~ppu>2)>qX&YhRP^FYjs2Fr+#qD+gp~5gisM|^| zMhKO>Pq4tv11PR}u%eL~h=0#qN{lWq?rGz$YyO&dn6?Nd3RX2}EjEh@ASXW1Y2^!yqXO_c}oUvZEK`7i(c7d$>baGo~J{QbuV9v=@}z2mr9zRvU6Lh~#MmiI?bRH+B%uq+zi zW_hDwUTn(-vMDng*KK$c9soD^(|8=sjF+jbpB$-O>tTn2U(d{M8~poolXJ-)io9)n zwi?Z@gUy({U_y$V1ZV4i*dEC4`T0_;t6zVD7jKdeuJ#5Z1|}hU`{VEVS;4GdnuFa( z^sg_%zo2*jPL=<&M&)Y*uwA>H{fe298lJzMXOJ(wrR$ro<@4D2`X_#Ppjq z`{`MI0FEknyWcQ+$3OhTe}dz7LrOrd1>e4Z$G2~9xZiF#j>9B%g@M55h5PM>Tn`&i z_s#-68|g8b%|gdCsXm|8*YiXv%nd9Vr5unX7Di0lM;{l}7kCNL1%M8>C>R{XDZ?%e zRyCLdDD@wrgoG^Ri{}dN3LvkEaw`X4qm%IfqUuw!4fC8Gsn%Gu-0rtU?3gQ_K)E@0)O%unT+M~` z3|nKui!^gf{ulgIYW{cTJs`xxlqB&B@BUxMQebsE!k*hVsIFE^hZM}-Y?^10|?o)h8xQ1fPVWF0#qF*f}m7Y1_ zvOaHU%I%0^*qfD7QcV8Vb2gcnGZkBb%L-V0o+ss`N-U^t;#^|aIb$=EZbl|xV@#6W z;^AP4=d)YWza~#3Hea2YI5*#>jfrbE95sb#YKoJL#6D}uCb64<92V3))2mOyHnrKj zG+2_gk`l(W10^Z&@#6=+egC%a1CUF`<6#@7TPaAXP{s#*K0ff<$FC9Grvtdorv)ST ziT1qkJWpJ`;p!dNv*B@_s0=-xec>(^uajQ4q`G7-PN{d{MrANh}t6;~HOVFlBy8Qu^ri2pHc1}PwYiX_$o&P@YDY-J|*2S z?LTP>c*SmpsGq#n&CvfHfdzSKS^}1YiE@>#zFKZi}uJl>Y3i)4$u! z{QXwzXMackxXBXzLld*#pMO}DDSqXzE_QNl;GDu@UP4#no5N zlwiKz(%bt^l8N$9R#!oQ!K^1KCP8Ev`(s|{W8l30nSO4AlQ{CA9u+wi9QOnF`whQ* z{{^ZOM?G+Ve?w($bR35@Zd7=D|Nh;=W!s6t;nVy3yWz9xQ69qru;+0YnUGSrHeB&z z4XFc%#3&aA6LF$~!`p6@X%z_YpxNXohsd}&+sOhWCr8ZGTZ^kiT z4+D{e&*uph8`jCN@85;4GcuYe5zh!|t0W5(*4a^S8KX@c3==nC3&=>YZQP(`C7RJ` zP0!d=8IOlid_8d8eeX#M>Mi5P;}f^r4Jp-y=huneC-PLQO_Mdj-Zu79KpoX1n6d8nv`bGFRif{K=kqmk7P{IGjvqill;)DL&Q|*_%l+ zZzVQC-5`1lu#Mks?1BZx5D`={Ud1)qmMgbt>(l9u{AW%gG*YEmGTPNG>oZqo#F~`X zRWUhd42;+MKoDCrg=ZWpWLiv>WCxK9lr$|LE7c4+DsWwa-(BXt5;$ZXPt55BO(%*r z6ZSv9pK$C?nLhV15nqTNd>kPQdHnq8~MjDXfRt{XF;dZ|VTttra;+0wQtQ`KE@FD2L zOq7&14@k^mPWWiM*hY548$(U2q#x^OB2Ah9-s5daX2XVfv zM#fylxKRI1DCJfFCYs;9(b|x~z(&J+CH?6xr`on-&@BT>U;R6K0jzvY6Ki{>Uk2y? z-=`0U1TTgDHq(D;rd0oSkvz8sNPbeg?sf8f*&zM>J%s-4+VkfnvcB$IPBm{j8Jx$zRw37ypVD>k8P_a=FL zZR)qCU;p^(l*1R@{;@>d!)CGDUeb(JG_QpT^RelQU)XniJ}`D)bPOf7D1co7AYb0I z%q4F`L>;Z5*O_EdC8(67h(5W9J@GHH|TIgxV1Za@v8xkqGOfo7A#8R0JZOZN|~>~Gt7*oTqf z4mmyS3s3;6GAlD9+|5jN9#qZTBQo+*Xf(PT?IuDYIx92o7dv+Je5VwUWOr-HPhHH3 zE4er^r{L~*#Bs__=&=*9S`{BZUE}ut9yM3o-QMBu{ti+r%9J4-Y-YKE8Rpr)a8mD4 z0<{or=ogCJ( zX_mfl?|up4_r#3hpLjhr?)Tg%;2(Rv`UQgJxyyL^6?5UQ^uisaFTa*Y|4ttZyPg01 zW#g!i%gG-TOw&K=^+rF{i|z$CogVoGqEqv;ZA{szpQkxOS~+bkhH*OneCdwSSthd` zu&u=_^|47Gb38eWlK%a>&epXt=?7Umw7x7mFl~-YNYST;?0d3O?Hx!p+kd}#`wm00 z)BXK^z}q)pVHgswb~^)?O!qh*4|x6R6~6xUuQ3h@A$a72vBW@HnY)TPTPYy$U_c0v z6N{zORRBEwnhwZ0WSEwLbOp`{m6+a{n z%#bqM1P(17u0u)&^BYGr%9*ZWE$E`wDq2#c?r!x`Zimy@b|!Rv(kA9Qr8UI|&qd3D zHl{^8#A!~s{oI`0;)Hi2k+$g`cwe!(!qLXotPepuEd?H?tNy0t72U&2&_IysXb;LT z^lq#~?CL(cV#g{25+E>;he8o4E|fR2lO&a845_F9OF5>O>e|ClZ7fUegRZG+g9XG+_tTEa zuYKe(t|%?lvFG9^2DKDNQySXVKnLCj7J^x=Sb7Yg3*BX&XT)Lf4+IlWBs6svJ~lbLJ`3%)(vvC8zHEe=Lz#vFwX_Y+k1TeeD5bF!1tf7aeea{)0}Or zZy2CO@ag&!N(G8|N1Er%YHd_R`|>1aq%ig#jdohrZ(GBR`zf9mWOTrTxyz1L*A`e_ z^`D$=4O;$8QTj+mpL<@9+W7|z&fJ&YKecjt=t7vER!HfV>!Z~`8m*?sS|SvFqSrti z@(}Cx{E(L7B!6|{th{V;5Bh{iXk$*Ik7TCw5p&`Ew=YsFp4s!R|C?U0@ulbX*^h0y zFYGvRHiAb_?R3utAU*lK=@S_Cmx%^_M8chWT>3(3NRR*3$yL%5_TnRtKRqV8^o2^~ z36XXhkURT3eeOm5$VKaqm&Px-%}+eP`a)gx=K2mC+{jbdrQ$$8oor<d*GS?-8L)EanE7AuDLb;dlgj-fkSnE-G7mBm^^5?rxmDW#(o@;t7Xj%&JvtQz!0~zr3%E!>TB_2K^5yf8(5uAZLhs%WV9L}+Y6SH z`X{O8+O{O9Rs)2Au~c;V{p_!cJ`QP@*Nm1(-mpIB>EuJ-8kwDf;+sNZbtJXD*mt`f zrfKTbF{|3J(|eJMk_$KmM2@Ib?X#dt$Ek}}M670e6d1>3C;6oP!Bh~G3Hdnpu7wyK z_sJH@Oeq2Gz$Ho!O{m?$Xlh$mnA{kn6~TH}LU43z6P>-A#@)RbLKl+crECH4kw58Z z<93Q*cTEtJeIRf#foKiz1SRn&(#nL5=##8;*(p1cGnBOFl?-^|`5FiUIbEg^m;4RJ z-bWx_49G5K+UzpB;O17u=(EQS1*@LnljaDq^)khn7EJx>gQpF6$CaUsIoe}l99`VQf7n{``Bv90*GY` zhhapX4^V-PutG6UjwmO_ah`CTCft6$!|^y_IvkO6!89FlcesUA#dMgUV$P-#Fy-3u zy++_=87uTAXq@iEeq5hz{lRb&~{UtDWkrrEuC z3%C+DPs0%&aWC{~QKhs-b3c|5dPETE<2y-xZqNHiSVN~{Xb&akC0DVN=q^pFJu+VS zU{p}`83RHej6a@_`aSMu=@So(KIuH3-%dTt#XY48bak@*MG>eA1BLoU&!Il8kG}LZ z@)N$c9=~jT;SG49Xw%crkH?(77u_|*1GoBQBJ#n%>&496Wf07zoFARM2ixmt8J%px z>(qHu#e*B##;DiFU8?KPUqAQ|Mf8jj`hlDS&vf}-7xIH#Kin=p;ueCz8fpl3IKDmV0cQ6PDj)SQb|{;UoxTYifDIkTLVf1^qUu#7Oq7?E>9(BPy*!Z1V!I@l#7 z3eaIS>fVIU;ecEefn%S93LfWahx`cSWW=S&T-5fhAnjOq^?V`)+jG}$hBP;|O$k-c zh%dde(IWxf@xoF|0$4mk+(8T>f-3b=;|6}iYMP22?{58ZHr>?e!kjF7rDlQ*F`;6i z51LA-M$csOuGHnZY&6ZFEw3(6*m&)3H=a-xMZ_UD(fUMJIaLZRuW0ox!Kd@8M^@Ut zM`}d~qaUo-4!}d7ngXKPVzbXNYcKm;+pnZ>N5;_N#W&c)Ff0y%3VfW>i;RIVaHo)@ zn2>#(O0dwCt~hR2;O&PvzcY#5sZMzOJ=6lf=B^@9c}6OSO(*8xOWla z?e$*B_Ifw=U`%tRIK@umDf5gp#8n@PK{5hc$#6&!^I<~KVlQMS)NHhs7zad(C~Cb? zM1+9gAIb83CFVyEs}!gDyjL z?6cJBZ))@umXB1nQ%MnbP?pS58)a#NMcVv-&rB^}ybT0_ljI4_(m!@~{H zQyT8ktJEJm^7e8kfS$O#=L|P`!SB-xCcfwkHt+O;%{_ggD4;L+U47zjUNTIlf8@a4 zPdlpmr(gPo&&A6wOfNqlOPSmYZozu|mL7FCFWo|Y$+LHUo}zdrf2faq3@jg3Yf`1^ zGwbi_A&g`0YN<(O~dMYWbM|SeeSmLGI!O8xffH5_71?{&?6hB?d9nk1 z1rD|1aC?LX>fo?E2|j)l{0@Q?1BPM1)$2WCwCRv{@809j2kNY8EhzT(U zgcQL(nQ=U3i;*Zn$wmvS7Tee(A_c1|5*3W&uDh2+1YSLH;_e$@0FuzAJ3OzCc5uz1 z7uyG8boxFfbTqxumzO5_xfF0@n+j5RBxKcNrWZ#d^;afR^lg zIcGHF3Uz2osl|HLs^$5m6wi%CFJoS)+3Iq?b(qb^qmem7=tfJ+2a+gqodGW^Pk|9# zgf?f+ZnuL!#HOBN7{CFRn^)^1Q-`cE6vt^=Dq@Hb*y@UQ`+XO5ZM>F=JrAj!u*?+u zbdkAgONX4)ig6gbE7+#;I(?hyhhiNS1OnkO+YNKw)<5az6R9xZGC5+Q(XxufpHW1t`1a}MWuEE_K z*C4^&-7UCVAh{tHoOPahs`jqhRW-x4t-u4vQ97y6$NxG9AzvcL z%MXfAq`?14Zo8{Y(YRy46#Uf|ruU4{l2d}WmtA(R@0*_K7fZ1+SJ6#K^>}>72NAVr zHCLjouRBco^+hWS&QN+BtYTZp=zNXG^n4UC3H_a|G4I?i`v-?W=e7(b0 zOYVQWCOs;aqUuBAzComo#3#5RY7(_XZX!6S6f3G*>khbesv$zLCZPi>L#p9RdS4pF ztS+WXN4WS(dju2(HO-9(XW^ zhHrGG+RAW?r8^Y&^hCz^d`pn$^$q=B9EOE|#E$$s`0$+~P0HZq$nnV`W#$ma`Nj$8 zq1>q#miMpVLcr_oOTl4IQ);Ft-@EapH`Qyy%S$tT3KEzL&B@BP`BfTQ_I;VKYO}t2 zw$%UR+D=a|ET>eN5wSN3dqqJ6{c=kIo%JNH8HEd1;d8HZj}xdQ8C`Hj6opi@dj)pFe}+sF(+^jL z|3L%L!&6)b6C!z|Xv^hecYJCjJf!~YJt=~we;5wid=ZnorLthc9@u!n5j#u(d2PLP z4p#mwUOUB$5x`W(hjdcJ_*gd3n7 zG)1#2+<7Fyh70-mt=6B-Q7@KGodsEI*S_x%UkJGs_7_T`amGu$^hADX*`psBhs?jA zVXDJ4yRhWd;tvTrckB@5xt4DpVquS6J4p^>9|2S)qkz&(3x@95TO&Kf7%*5M<5|z5iv-j{Oe#$ z^-lhy+KW%eY-+2rLD1)13$BaQ=5SV^y8i^p$0p4p;rYAQbU4^oIDeO;Cy&IqKvvmr zGkAcO?xDl2VQ`b|{_3Z4;#)Ou!B?N0_Jfn)>_Y>zTdIr0eHH#b?G!s-$6_12DkRo+ zN4(o!_b7cjfmGLfJNchK_aBJF zdV66Kavjhq0;9Y}Z$*WsG$=s3mwxALwdHZx|3wi$aeI6?fh|@Of0-8+{TK2`Hc16S zz^>sBp>Fwb+q&Ra`#8{9XREtTyU0&vnP#LKBMapi1^~#dR>E!w3VY4kJ2z$j{;0ml zMrJ*tK(&;Z$(gdv1MfR@(4eDEF>_JK@n8KWt(>Yc7z->QaqL$KZb4j=qWw+V(+3^b?I64h4Qn%E@ggy6#dwyOK)s1>*m2mv}9fhKUg^OHF=v} ze@o_CPrK54BGeHeYi+sg6jaE5Vp?9xqxU#3@L0n(8FzL~>Ar01J9^^eEAa^`DDrWm&(Gj2PIwjNsb$2@q(ZnJP zL{oK`v%s^|D(3gP&}n)d%CwlSGc%n8NId#@$0fq=Vo-d3yj=hCcIe<2M?pC6g)epL z&aWf`rCEr5b+>4+JwJ~#6ps;fMo?0m2|%$UdDqD7j{?A*J9<~l2rhs#_Kp1`%WPVB?0HUuF#JdIXFFXb133;{ zxZUk>nEKCI!eT@nO2x3Z7AG-Em^(g}M=gpRu)J9x521#zgbDY6XSM=Hl>Aw`bA#%8 z8WW`OEM#*~3I0hd52)H>YvMhRkqgo)F5RU!fvOiN^?X91Szo~48>)h0XnAI5aN~tC z4AY>%prHFtdN40tVxTp(mkbnRd>HhwCya{-Tzp`WL|hdy0b61LPf${jk){d2utd4M z;sl>yco*2QPO1|5(G_)PEP7s|bOy2xO^JeH?xJh%*7CGUe&@w|cP!J;9|5ccUId%I+|ZuXd| z(Byx=-XeXpm2CgFlgjr*3lqRD!O>W%3JVK9M(S$dsylNKa#CK|u+92DAK_+K{i!Qw zu=*ytw1wrp=!SJ4W!L9WskLcqX1H6+V8O*JaH%-XXH=M`{$C!tw{5|_$d7*>r8L zza9TH6FR7M>6+Vb_WpBaxixGTuOilhHs|Nm`1%j8W?Ok$@_UI{o&G`(oup%>@fW^p z0*d-OBbxEC_w$y`K=P$eu)m*=Z94rRxE)U6=H$Y~|1FioEeIsR zT+HW8DX33VatzQk;aaleK&)3gDZtTCQ_DfdWHo4()5z#JE-2I2m9zEa2eQM$IA+82 zPvjR>heuo<&ogq1SvZySVm+o=%TL4JK-E7q%ZA7m|Gu^`3 zZcqgi2~X z`2E5eIX9YuS7Rtti|!A=&u^OP@BqO?xa;%e?j0Nu=F~W_9R~Gp8(v1~D#`Y)AM(q6 z&?O2+;%(lbq~*6JwTs&NqnKP>+);!tP%GEXs*Ia<@#>_of}0{s?nrgo>*%=g z=#~DA28+4R}&D+&E!xwJkKRSACaQx=y zo0E;DXs|=~f=%V#jg7c7N|O5)QFB<9b(pGE`3$cZ|F$o5DtzyL2VafyifPawJnT}y z>QnKrfBHxg_5~{@l9g!gWQo|m~lk3c=gdlX8uLt zYSjojNZK7}Lnnc_W=qTIbod4NG^fcY;S-n|1Qowd0Jn9Xy^a7?=#5sv6_p}Dlh;`~ z6c^Fe!y(-xkPFMvGTCX`6-dBLv?cTe$DYXTQo(8I`<=^cY$3|FC3uczQ{^;2DRaS! zo(xNielU9%xwql&3zhTnydsp5<8yB04iCx4XSVmw(8u>gh&LH-r{>J-026HznAYhi z*ov*hWJcvsVsa7Gm0>Y)%P^YyToczk2_#UT{ogL$Wxt2V&K*~s+7*s@Qw?}~kzX(U zA1y#Uafou4l{SGiOGvqzslSuxoYOH-9c5tV4CQxMnaA{q$IP<8v^2=r`Il}%)(>bY zTtjTu9TN`&b$)r}vs++>6%F>V2kRe=WAtyTooJ9V=Ry>0yH&0g(>36ql}WdXmfq{O=#CzxRtRz`u%JeNNzYrfN@JqDKO%dX!1LT3 zD!iC`BIFWV^tZfwSs`rwsIcKkqT^3L(*nJxBE2Y&_rr+%syt^HcvHCrL;9|2&5)h3|sm9<; zpW`=HjC z&GcbVxJZ?G(rX<2A+vyV|B(c81dE-5sJ%^5Bm#PnWKQSB8(dpxV0}V1WaRL706YZW zMKyk(Nv<3#SlzB#3`H9~eV3|AKrB!M*SYWO#A$F|?VoEWtgP2J{iz>M*wC~oC?MTG z`WxW*R}!kOYlA121Vr{LH(1_1K`|wUe!0|w@q(oxgAOXK@^E|$bK|%&W*%sp9Erx> zW12RV4-@(mnghP$5+}jb7g;PYo-@Cde5A=Rx~xU&D?12oSUz?a3?qOO*&G({XH+cqdrlyKR=QOcdpE}Q>Dvx5?Y@<{H-UcLrr4A zX;r+^SdE}+a0`FFW9kJdLC5KJJ*G`Z=Ax52!4;(3r(F{;VV-}QI~%=1QUT-*ZQo5R-xilzEM4C193 zIuAj_B1Z2e@qyzKwp_F1UIfdhX!L7e>PWkt1ZY3f9M8RS;tbV$cF$8uV25Kk`TEAGu)Ec~2VmffM*;?TCOC$C`#vOQF^dq!(_xY@ zy}pXY8jPVmb&!TcmP?q%s;0MS4DBTmYMj!`VO7+rRwen094rT6~c!tE#f3}Ka1b-h(u68uK4FApE zGQvk4okDWq{dHxMo%&!_zI`1v?4WbO1PvN^BQC`5NC8aNMbeZ9?;fHsL~2~<{Y;wa zD}qYz>e1=6)y*<4tH}J-53Tyo-Ut<%zEIs~7}0EXUhcXZ6Q6{B%xMt0<30$6{oh{cf;P-gO zJhRaPS;D3qJp5D)v&{#vt8DsUi(;-H56&{MN-AI9Rgm%bx-`&Ccb4hN+CEcTx(sA4 z0EWXcK|>TfTMzUDTb%e8TbJAt;FMLEKeAbe#$9S41UimLhVyfK5E<a6+P#B$%1l?InVOH**h#!)ZME}>Ja;cIFLl+=p*{5YeF<9+t!rL*!{ z|Cp?hYr~REx1Mychak=Pi#VDdF`MsaxYzp00R4D_AIo*^KPW1cmSl%Mz0Zcu#Q}An z`ydax9MdMW)u}A1EioI-%}rHyf{>?&r3cJy6{tth&aRoVo6t~f!^MT{=h1zrM7}KL zE;~rFbpL{;+i6CT-Hw;qGwxcIHjR8hMu+w#Te=PKVQUD!}RP)$G-z zK+mB<$b^7R5E+S&JN#80NXefo?kk+#8?CRT*R(>qY2+01{ZICI<{_yd(7MZHfu4pT zs}KM(3;*-C8~;Z9B@r zOy+rb0kPU>_2cv}ErOb4Uc4>Ki(3?88Qe6~RJS9T#A<4W=p$xg#0Yz~p?%>U9q2o0 z#nFn3+>buK!H^EBNK?7+Q@7tu#lcBNw-FFP!I9p%g9N2s3?d;*y)O-SJFxBFPa&bL zo3)cqS2WH4ID_X#gY-H)pq=+!S zzPcD6@mg46sjjXpG&kSfAT`Kt*4(zPH$CT;s6JE9H00cTDu=3l`@Kl*=m=BBv#!h9 z69>OD^X9J2aXWKu@*09S`01(cSh}LhT?3nMKh*pmWOLWZS&S_HkgB-gOA^EChC4AL zYX4M)H|0jRf7C0>_6M!$Y;R}3HjYlqDwj8<@=`ypFUjBH*6uJ2fk^<&)3)b|$V6*G zx=3zImLBXWFes_jVg=7Bap>B-gz=2<-RO!ahY&gqrSDd#U_8Jy5MsfA!!N9A->qM8!I!F=HZtuOi^ zk(4xl0iVqc8=v!Z;IO-bTh7MkQFGnWBgEr)zc?*g{-e1>3Y42@I%2+$EC-Yv(qp@1 zzlMsf=SLZO4-RVx*dPly+c*^4Ykx&wkjKD3Zb)?jl`uH=u$`VNd`Si47nz6P$A_5~ z;;NszE#%d%o-tJ}{Yi`U%`EmzUpMJe%Oe59p_l+imTioV1v@3CaHuAnNaSeA@g^ zwKeuHa9=B7C%|*+U@HNS0F!DcfP#Rtuqn8rekQbYEl#(T3#D5|8##EDNPb#EnGA6* z39FF?Tv%;x?}XgK^B%7+#CW&ey*<0MY*GM>EU_y$qtSQO3wkm`A7@o3_W2fTf+hPu zW;PBv^>?#2f=BR#g7=)GE5IZ9t%vF7^$YaxuXH=6e+e^Nl%vUX_{p(h%l!D#du0qG zG~mHrsiKu@MpXb0nA zGAAD5wce=M#KZYr!@-dlUBN>d0fImRm3kb!inuU#AHE4~6jFN1@V`xC47GnzUY+#c zTa0d)@o49cGq&cx$>!+N!z+`B?I1QU`%y9`7rlap4ReRo)?9(w^(h8| z665__R@0uO#_=vCH24<)*4Tmo&Ya3QDg0(A>x+95UxcucsO9SPs#@f1&X=nXkr%tZ&|l+d(SGe zVQVd?*atHx9T2RA6i(-GK}@R&>fo7S#bv+TG41f&T2Gfw_d1(eGSd)G=5tWkP%zr? z(&l3OQ)3wYqH#pUAI^#ah5cidK5w0t%21mYX_CVt3~Rter6)-P|V$WDtP6{a%Y zI~y@ot9!$8YW~Rjd)5z!7ozIYuwo`~U-p)$@GIN^S+VE$-D${qkm^15v!4I9LFFwL zcvRl>1F3zO5v#=!-rH1E$O=KsgYz`(RIEDLx9j8Q)tr=zn>%;jECX8C@{P8%0vzMb z>o=%6rlG-OHxP84`#0@3nR5B##)$mgZ9p-2xz~snZ*9{LL0NLo@?5S_xd$UZ@512B zscF@udv$jm!i|pz8-m&&u={EnWK0Z_|2p9UqMdkHC^C)miT@Gl3JMCr!{oPP$0wKx zOGS3(+NB%<;8gH3G*!YSwuJ_oT(qcn6yT?MWtP;6>7&ZyZ72^K|+&O&1d2P$1Z@ z)*wI9JJ^YVAy)rP%{8Nyb%mkos1SsLV~$-_+GI@ZK5o*_Wh^OCnvK(sgp#Yg()K=) zIVF|JsbV^VJPU;$!&i2RoyhB;1Ec~vXH}`mf7g&!mK6oi6o$Zr5Kt1B$Vj7gkm`O0 zTl`*WB|$Qet7C&D&QB0kn}`%7t%@Ox3=9s&?c`DXXdJDVlL_EsHf34pFO0q7q%dYs zkpRha@ZkU6(C3U4_`X5sR3AxKkEoZqWl7zGl9iyrnu(1ct^OE~AMm(V>&jx;lwzxV zm2$hEeBd}Dy=%z&l1zMIRZulJDge_!t6mXRUGJ5IVqHz+^(x5|O*K?Oa-ErQ7`^M% zw|>TaetsT*6TQp1?a05)gQxrMxc=b<1x^+Ybq5D)Zj(w=S}+myphVKm(!GcBd(~1C z2mJ`^F3D z{1$NY%a&1c8aaDcG0_AR-&t~k67KAU^kMUtF5C?f!knNGhcXs5@x!3$B~dlKQR$7k zIplsnhhQfK6r2f);|uJX6(r`TXmk9_0AW}+)pcO!18cf8<<;|4MW^8Vd!T~SnPMo9 zO3%uh9t@hkf`jF!zU+pAl}7oN3E^tx6QQFj8gb2H8ZGs@(R2<~^hl%**@Q5?bs?Ae zfHcZR+&NnwkCT?W6D8=y0A34;8Yk;ac$_cxp%+;hbhbO)G0nJ>08a8DQ>sj*LpCjU zN2WHdfa(s31D`6-M-lj7$1l2h$!oliho8V6dG+7~BRGWvmmj{GJsnxR%qzMKtN#{N zPLU3_#CqUo%by6z9j`Gq;&Y4KWRN)8Ft8^6Mq^NhQQXr01&7UZXyA;Bhc@8`;PZOM1J$YrD#!?{`G2IR8SpWCY!E6A#zzYm+`xY_jC6%+U z?mwfws6&h(_cz)~Xy?r_Byxw%KQ0rc+M(LX-#xB>9XPz(I~reHZd2#fgCXwT^y@Do zCu)Tk?^PtMG)_GH3TOO~L@a4hxi1Rz#;rV?428@soq)T3sz!#>&spn&b%2h?p z1{Eq&Av`_We}a(_ar|t65!(mV*`zpx2_zqaM)0$kv!0~gY)0Q5U;!v2DP68UY_wfmr8yhAY` z(5&~Q5X)p|KrL-!LlX|ZT9XQTFhT$da@oO57k@TzrK9G-avq+P5GrhNvUh15u`qf) zB13GnNM{eVE-(&sr`)Q8+^KCBC|H?G)HPtIml9^Z_jA7#PP~2`+x=V(O~@#&=0{YW zsHigwIdc3jU*c)fo_K^4`!tKw@R_J$0_v8|^fs@erPqW%?JaBH7zqeURwd%ZJ=I@$a3i%b=l{+vqvJW@7z=WWmR@34%(Sn=kN;R zh&Fc%dSBY-mOT90ZfkW^6?Li=`z)F@`GgCHzRk-+-fbRnTZDA6r{^KUS7HEG6|@lA zpdRS?2PajQ1DKzvWj$Aqf8A805i- zlquo5x3j~*p9o+DS7{@Rd)a)?q|>5Li90Ln5QuD3lTep%KVMnWuSkLc@*rG*I8q~q zdl}1Yg$*4L@R0@7gSqHe95uG;YnxV<6Mf(~jnq4g0Vl(+$^>f_(q zu<(X}D)88p$wZ?A=6Zj5jI+&AMh5qmreTarV*aRz=~iqaYLCQ7oCR8Fed@#9!zw$^ zhyNtUZq1^BdB&h?n9kl{15L-;h^Mm=-}WIl@f^D1$y-2G@BKtpbM^W_1|qW{j>S56 zxTxZmn=qqnzV5AT?to%=ml*FRII!o5J+r| zwD072gK^d=wei z1gnNoXRaO(E4->J&z46>_;&M@xiJYRl{H_@BjJ&0Z%nJ_K;ol4xD-$=?hk;8M}zJs z5*0#J06V6BmuHL<{^j$XjnCa12@i%FB#T#c0^ej{+aoTK7ES>$ClQ8&y82oBOs%^O zJL64e^tj|#1lHVf{zyn75?u#t4AM+?lE!sKCbl zVQ?8908h$CY-re31DQ+RpeUp=U_({^dBJkIhexI>ADk+}eWXw|MGTYa3vfYjG_2OC zom0B=_HtCwP*SW&T0`&|E4C&vE8c)g{xQ;Js7Ygvy0?xMb5Tgz=jVMUhBWAA(%|FZ zoP{*aQ|z_hoEe2V}0xX z9twtyB<^uLJWlDVlm-z)(q;b_nx5~N7F<4jQw-KUM4Y8_AxPGnk(V?XhsABKD2`BD z*?+2nKYLmti(jjP^TY&LMJrd;jbps^KUexc?mRtY3B^z0@ZB-eUSNIqhjKI2-~wLf zIjP`i%JPu&QybS+ZT0+Bt73-gz>4n;rAd4sSuLefMUXbJ&Tv|hSOvdiUM`rN?eeu{ z5ktMx%Qf`XPa-K!{sKsm`Z66*Yq0tNKgbTfKZvh+wM<6EhGn%d`Kr0YRI-&Zq zJT3m45gb1L1FUoN!YNH|<>i7-3DQ3Wb#G`jD47t770 zCsukC5M^=5hh`t}lf680IcsB#B)L)v9ev*fLF1`>$5)FG-w8~2V=E?e_FJtC{GWJr zWZ9(wtsp^<6NsczKiPnpw}zT^3Uy_UIteF9Xlj+tjLH4Q|WnB`jF}M|_ae9~xg*if;Tyd=?Eqm1(R6);| z1!B`#l_&(vz6m2b?|*m4tg+<(H)yl7JE>79)Empl+V7oed+=h|C2i9^o4Z7u|4Zx5 zE|}#kK#$fe?|A2HV0i3XVb0DRO8`t40iMj5K^5ZMBs&SnK?TGKuLXUpBa%WD7m1Gk z5CItxU)@hKcKSll9rU{gYq>=vsn{bgX3}x6VaWG<03PnRY?D}0ag0Vk-^YZ;EKEJ3 zr~;WF8rJZLCFw~&8M)2j3BHjQ;R3MPr@<7IMW*ZD)k$s)d~Go?)DW}a4v%@EawY;z zl*mLm#mfmuxU2#7m^Kx4>*CJ2-t^UQ)qt0DSwtW1ml5UTN`#^)ApB)- zlZ*udeYFL9)+07)@SD&TIwq~U$;p;S@6Rd>1=X@CkLft)KPH=jiH=+ ze3+mnLOZ(ncb=aK!~20PE$*#vK2f`8zz6pSH~$C>%HWWf=K>=-ii$snJJs4lllpR$ z)+2t}GDv3X#&Q*ErIiD7?P`vmtNOU2wBbC{NT27!^X5?!Ps{!m{TEmLC!f?*We~#i z-G;g=p1i5|2oxQ1$uoGQQd5{K#1+`2loI@AbQ0B#tGb{eVf)vEPH{mHp11S%1BQV9lBfM0HFkzJFuuI|| z!@GiEoUQ#>B9&=2+AAe`ja9NS{pDHhpr?!;a%yahLLHPlwsU1?_%hIY-uwZljZ`%B zU(P&+;GhJJO4m$~{uza2{P%Q@0BlMXIgF}>aGbBY{=Wyw{2(!ZapFFdf!;p9A*f{w zhZy~aEnlc>TjjNia@5o=NaEjy5|U^e?!Kz&nAQJ+P`_O;k2lSVq0B3?=G1nUmK-A) z4~{wem%m$K>HU8<&Osx->b)gfw#0?Rt$l`%wO>1AsbBYn7sV?ghN-PY1EWhfOXOsS zFoJV2oG&Y3yGao$8D2e5KvT(FI?KtQXDh?uw{3uYB8L&DE#5qncKR7=dx(ZQQdMGb~ zDb2;_!wb^E!#1?^(;G{)YXoJQo-UCH*w^yiw=)@E+&QattJTs3nC<@oQmO|!+DO|E zV7jDOD<>cK^;j@}E%`}TIc+0|qHQB}sZfnU38QTW66^KzfLC@{zo%^3bID6UgV&Bk z>W~uW{QQ|hDF7jZh}jWl#}aLA0<{XKh|q(QL39MhnZfuWqCilQGFLi&hegfsGa;(# z1!dy`jN9i|PBNgFn4!3r-}8?cUHIzT(CAhlr#mKa`HuCd!iIP}KQ-=-&B%Te2dA27skU zSv{gklmBEs{u}FFPsMDz@ManqW?jc`mqQXT1-+=xcsgGrEBVKNKr3Zh{C(ChCD|H} zY+r&SQZ0$aO32&%>6ppkF+~nDWEAe5eWhFjdbxxZ@_8ruPpv2>opn#m=mX;b>NP9(>*5l14_$4gE2qbw5A0ACb~zo{z? z)ZVC@&3{Uqpui`x^~HGjuR@KX;W z?&_3#?*!_ESQPxe1({*#|DPkXJ7G0qttZvd*)eH9X5_~+OO-9Uvqit&3m~;9OJJFT z;^YZ4FjfzJEYwjtnKN#_8ahtWJXOF5OptXe$lKwWY~@#Y6e0V7=$8j){4d8REsw_) z?vIde2!CM(P@G)=7L4Zc^*{)2^Y&nOFLV&)8wPppFS^S5wPg`htC2^_TuU}oHWT~@ zCH1{bJys7ymORB9Xr95@B<0Nrq|bi*Bw$TnVa3ze?rPB?CkaCnQ4FTB|7bsEI>PLB zVtxW6U|~*sjj2PDeHvIxO^fVT+RHilch+Qlh@{rpl?kdyV#WXAerw=U?-HJ1=KX6A ztwI}+<*~CQV@^bZtyNvdM=_{$3nvDZMCs|7QQclnIK)v8f0~9}1XDCcXF2fGS}E=q z9v=nJx-Nf*Ovo?Xq5C!9qWdXeR~Li#m*WJy90HuEOMPP&CY^Oz?iS0>s2;B7(g61W zUMBIoXaNtJs@rX%gKeUd`i{FxJNeXi!&i4Ndh~Xrl>a9n35Sz^zqe#*xRpy5Y;gM9 zkd>?7{-=7sQGE47ZdUYt0*f^)g_epZp6WD8Etdrq0I%eHcar7g4q+DB^ciyB^z94( z#Qiw^e*4Me;T}h&vGuQg%U8m$ADt0uDX$KO1?WS`xrHN5P!!n%Ng{LKg3zSDTINT1 z{TS{civHIQuk+%CAMgXVZ2ylnjszECWhA*JT(}hTp4qU1qfRGM{bG&5YBv&d(`uz5 zjmsmH)?fV9U@c{kRInl&V*Ddj&mKoADqf=baIZAI2_Z0YQh}0f&M7L8Nml*DR?(bV z$yAOvBQ%XbTrSs8yB=33iUOM4KcP;PUrl6QLUpG8_OqoVGuIgYZh#ZuqsF8HuM?1O z9`20%M>l>DHeBiSo_`K`PQ}s1CD@_+2|dT*;_{4}EPAXI8AtR=GYHHxAqJ%)-LxBQ zKBF;H)LMghtpEdQ-6;W3Y;*ctE( zl!O~sCe8gS5Km>bkRQGu*P^<}@Dw>0(q2u0e%d;Z>wB&_eL#H#iq(o4W5l`>xC(7` zeEjg+e%el7m(cf{oOhJBk2xS4sPO_#?M!OvAgOVm<+-%F&-vm!ba0HpZjNDBQX^#% zA>~0<*+6PaG?RA{U?4k%RM>EXZ^ijnM5B#MIB3gi=RqE+M~ zT-fj`_JUAFd8fdEb(1Z8fA^+bW0`~is);EusjJUeW&Z4IYJwT zLZq3A=stIMHif2B^L}zlU+^M=_qzwY2YJ|f=J*{}M+|V_N3?(@gcv4J^hWq$=ra67-=8D12o)no zC<2J#pfy8#B{e%Jim(}3WJk?ew6j9;N3xgu%F|aSrArx#N3S)Gdj+xNBRz#Em3lC; ztV>f|k1dCFK+_y5Is-~rVaJPB$&z8ElN#lv+BuhQM}|wT;2@k4RnctwtEU6pO+N^l z-@~fI<vHm(Cn(}7S|49}8Pw16T%d)C5yYL8%@js6~vMRZCu2;>hC#9&$&=r3iAozg*&kz$R>30zz(OO}ma`wb&k{1VDM1 z6B9Mn(4Ms_A0KHgQ5-{>3zyC}H942Cxnucx;KLKCNwf%C4?<{w3WJh7uq63okXH{| z^g7KgpPe@hhEmZlG#Q$9aK@^cz7;@ZibDeD=7-2uKqBLB$N}ODr27@&V~rFvF>H{I zW`LR#Iar*1uHV-h3OJwg*BU+Le)t3~Ebo&Mo}JJGs1eeB`bg<|DYgv~r0nFH`G1^6 zQ`PW&SR57}8J|gNXy%S+@aZuk3==T|UAY?6R0KJB>ZoMQ&i#47ld#{XSm^f`*7p$n zuXB9jg}EA7U&qi8?R&aaTrMyV3|~#cyl68bcLQ{go#_EHrTcK?gO&=KUmg+K%BW^D zs{)dxO6qNLymo&=&ygXrTTF6}!GM-8+|mkv#Zy&uSmUTxtui6=62y<7_@7}e_`(#c z4MG!zU=aQ2C#D}9t8Q2gNX9JxMW<4p+e2!|5yesrpidHvN6)pqC*?5d-h5gz;`JPg z(l8y>gM%p+;boI?)#&CnT0|behGO%3hd5jbzuj#*K0F2df)7k;)3)xb;MJbzeGSNu zY~L-SRag`&O!(OfqYw^Qq=iq_zx8_N4+$rB_kAL=`hPF^>T})BDIAf=AuzRJX5fvx zJ@-?i|i26{$f z!yOikq=PLH;!GZl$@EMa=c?LACO!Q0JUE9zxsih^g1bntbRRj z(kc|E_psf6bwO%-NZ-#)z@$KkSAJ1}LF}gp6?TxCg6Y_`el)9FizmuXwJyI zNM1|$AQRqv+$)-sfax5e-S>Bg_sI9R%{MdwR4_5BO<9me@)VbvFazWrZUD; zwszJVV)FzZEK|^h&`Us1bj@$SVE;GaHO$v-*Ot|(3`a`b@fTpJg11NzM=%a)gR75(Ykqm>s>S3y+Hn1hCe4-&f|9DQH z*G$!kfO5M~8o6%t^mJxoQ$hH!#;CQWS^<&xQ+hanUZo^SANwS7l`{t(<7!u@EtLTQ z3vqENMzsPYkJo49mKMa9xc9et09NYpZwAWu)LJFotGq`=nl= zwx-g6qC8U3y8)REQPq3opH5yVn`X^icI5W<=?mtfG5*7k{&Vo}&+l*kkK3zpZchV3 z#+HvG_gkw;`s@4k*%u4l^D~!vpJxV77tGGLIAT-Yj>aSXkKjlDFV_E0Dv|?G=W23u zEv`!}e@o{6o=35nHPZtC1S-i43QU&Xfj3{KH+SyuNhP9d{O-`L@a1LqkZnATl?oMT zIQb~2f*40o2OgzGVlX<{4sKLWwz&CHF?+67fZx-v0#fXKjGwfrCT zf5DY$<*!WT!YY#KI_Q-ka#a=7I#MN6_1TFTb&-ohzC z}#< zvd-onUpye^#m!-i5WF{yzBiyBGBN(rFTpNBC{O5nRQjBrWOUHDF_q)MZWM;qZU*aW z^ULXyl*1gvPFi=hBhPiVd~eHTpvy8FVa{iGu<1@1^l2CTjuJ;Oo5$vIJsBM~!JYcf z7Zi{5x$N^{8U=x4ot>u~$5KnyWK4KC;*ikee$CqlcRqYid38Ee^tLA$*uX0p?(9IHG88Um`#1%cX^HebxzS&rs5`#T7%=SSIf7+U|C1)UEh!`>_kr1A*NWp2qJ8jo_hzyn)DnIX0W5(`AqYa^VL(W=WMp^x0-)i0y$16m1iW5#K+*06i@<{l3b2e;i^*D{M-7cI0Jr|F=aLbOFY7L%$R6 ztT$CdQ5^oz@wkWi#F3KHhTi?+&`kqF%7S;wUh=Q+ukSC87|P{+obygEtu`iEg$>E` zv^IF(YWdLM<|$?Y*3h(jDX=+83O}&+%=@?2q!;r;?iXI~34v&uvpE`HHz4bcpmYY! zpAk~f+7Vxp&>HGqnvvQ{=CD9MCC42sdyP;5vE8Q8l*B=rVc|}u$^RniJ^a~zzxVM{ zDwGm?Q@XSulXiqEk~- zJEweuqHXr~9Fn|QY(tOS4z-~#Y|L$5>^7*adz4P@yckAFK5g9Xd4GikO(SzRn7QW{ zK^f@#x77a^7CqXZ=1ScyiON4;To-~Ntm(bPt2~;bT>=&nbq?+~MrjWIr|lWnpE4%8 zX`#tDG|~<`{gHj*!#N$4icxRA7mmxt<(lg6y5+W4ZbtWjrRp-vyrUiqMl4L9#k7Ka z&(=u-us1ffkCbJcv&w`8&828goi$YE`LOxCd&hg`!Pz0{)0NnB%q9DcanS$LzPy*U>t;?I|6Okr1#JT%JiFhQr?+<;Q}|-i z4WE>2iwFnR%1dVFPRN3rl~uJWJjx^41Jq#5UD4|xi?eVz2!G>^hI9 zw>x_`58_no$7=MqO+|I3HiKS{TFD&t0h z^Z_)pf0GQ{+^~PxYS%ooYIdB^HWnE+bT9< zM>&mW7twHIc-Vq>@0e{V?@4RwM1Vq3wm@3XAh;wASxAe?tm|zo1@Ym}acY`{GYII} zx_bNQ>WSkgp(<$MX8pZM9ghZg!A(ZTcHt6c^fiPMc+#}yJiR7{+=WK$+S}gxQqHwi zHR0i@AIfWbXN@a%7<{(3n|M#-IL8s4w}(R`bmkkz*FSD!+AdPsmQQ|6bu+v0V|S_) z1m^bBE3{3;>zuKNaLZ}WsmgRG%1>UijPZUr?~AJVd;Yhd?lfIL;{KGB&*${cA=G73 z#d5D~OwS7CzR-qgZv-`CCKS>$1mU@AyghS!M0y$);b%2nUQzmdW@J`|)OT8zYd5S{ z#$6t(pi2|&qPWCMuS8{{DiD>BH)eZsLYY=`*Sx3Cj;@OUO)Z z^&_p=+{!#UN9O!Q!;5Yw>4VGaeL#L;CFq5KVSe7=xTtpy%b+nL!z*uMdKbo6cS zrDcCW)zXa$@)2Zn%u)iaTgEWo=;g9%l0EB1>wyB1{q-0F4?-51!7k$#K(9ruj)isRfk5Oo_Us&7?_0&bpBGYg#X}JXbAsc*8yf z1ET=VIu4MdCucYLlV_rnDZ3#bmR$#MO;Kglt*qqRsD!?ar);TPwFkzxyL;z|w(}RK zemNlmN=Xy7tKXT+5(mP$sXUv@OIBiuM>FN#|Nj?TUj54Hxw1XY(#3p!ZEq{-DK7x{ zO@x=G7h514T79}OXDptc^{kZ^`H7;C5H~{?V>|aNiE8`|HpOAT%Hoc9L!<4ZzS|E= zJ8@zA(h%XwV2VgQKSLco^ri2RoGdFup+fj~>x7*8BL&h8qZCD=8vmTw0>CV$a5i}E z>pL||=V$fi>3k6KeqiVFZsuSmD7l6uC@LFwI_{%G=mz&wKA?L35!}Z}=?Uj)uN$hI zxAH`fJ}V|~|Lk^0ds~emajkROJ(S)1MnICDvB@xlL+(ad`p^%F*;rYSOzimYpQP-$ zO?vQ&PLi7~|Gn^BSu2QtXL@@#%DUMH)6E@l!63IZa?_KM`Z~+4Y;1ub3|F%#Wc#+PXau1?7z~*|{H-R>%qz#!gjK#Xpxp zUh@GT*SdD#)$cOk7-W=QVFGRwukvrtS#(i%Av1yye^<{Qkor2;FP>eZuWkETi`O8Q zPo-$5+{XW4%1VHuT?gmRzW?o3v)XQ1+e91@2`)Z`rfJgAPMyPf;_ac@`3!ffDetlk z#cbm!9*?Y>>Z$zPWp`e0gRALwGI9aKr$EW1WlB6U8cPS{{-UKPahE6pMMq4lV(n)d z9hC8StPbx20O2wH@VM__H2RwrbxIoblCtO{)^C|v8%8=5X%&YTsz%YzxpYBKnE8RV zrlI|s>2wSn4}~W-{aYXMTX8AiNt8yLvd+B%%6nmM;{NxT4Mf-Y;p(#-K+;Bfq95hc zJ??R0$s@yNO8t!c!_S8PCf{4JLl9dZ#_{Z>~Hw8!=$v&YEHDb0ku;)dl1^m^P*HnO(7lxu)bP@%efFZ{i-XGO?wC1CF zDP9zV6DNbt4WqeZt2}vp_Uya-lWwTDWCnN+&eRV#(%%ymGds^Z0i~@iiU=B{p77o8 zSmjbxZwJUp&+YSs$IyufbW!PTY1|XUlN|rIT&s%nIwom*EAR8NhLe_e{ zw|9OsPeBH)2 zFD7A3(+QpmQBcHgV8mXRc=XcJ)jo{Kq)1H)qDwBG)<;Z{JbW=ti(}tb?CZVU z6TN!Fx;G&$lt$b=@mHCZ&&U2XKSs*Rd$$2^(5y0N`#Q) zhHC#!^e#@9uMRDp;GOG=kE@d%cdhdGTS;0mrzCp|l2s&kso<74ammroLM?PM8@|t~ z@8qu_KF7Q=9tV*(sO&W?j?c#~#aQY(nU}s>)65uF<&L|TJ+0hJHgs9CKwrXHP%Z2~ zJ&HL$|4v+dCh?t~VOEa|yL)_?)^UBA1$U>vQ<8GUiBEjRwX3&vLTlvSA4^?p@P~yt z!aA{syP*WoP2&6h*INNgzkU$--V7&&4Y3{a;ocBbPi@Fe-Cr~O4~X^LZZy}s$0qh5 z1kYaFT75Gqum}ue3thV$`*m+mQY=WI)-?I~?~YoiC!U{fZUckK&S}Kg&UrmvrYIe=>Djo2~Cck6HlLs`qi!tUyOEqpPGYrl$@!C7DFz zttu6$lPu$s1%|x(KaRANOk9v>{eV!im#0+3(yjGJC%8`ANrkxC=tMXD?6LcLGgRi^ zg^oB2-LOw$g6aGI+@ZQ!FyxkaH~s&DKA;kS`Mt5UW}#0;3>S=+G2+c$+Jb&Bw`wkJT$3?#T-!*R57plVMdN!{QmR5?QzhZPx|k=3?K9vmdXNvne8+Y>%?M;PA$l~kRkL&r3Z8C9nm1O?x(nrdh-{$3%Z( zytjOuXN~0T2c)N`Uo^E{a{~q?5NYUCaC{<0&*PI1w@6dYO~I%C1GOuCob9{Zze&$t zRIv{O<${+B2~$lL2{3Nx%VT2d^WFN3xsnf?fv;u7_Ide={QtmR(w@Idv7WGDd>wAy zr{s13IqcpGEGGmxfuAIE0UzIVD;SfsFMdRtAx-*_bLhwqC0U7I&s!gciy3`&|Q zDiwdd0JhZ&n=Kg}%)m_x&XyywS{iVi-*Xx1-|cyunlZvg&#IDi<#nb6?jznkP9~^^ z?TMCf>@BpIx6wC$d;O?yU=UuRL9TGci!f3z{TJNRJ=2;-Y+pp*cWg>5cT|G5n+{Gf zXFQ1b$Jh-5F56H;ZqUy3=9lOnr1?Y9pELmx`sga^ANg->W1!o=lcNDehn=qx4)31S z!qtx>e)6z*3PG8TaevN_C}X+?L@KvNXdYo3=^1Qr02ChaxRg$9P+EfLd3JFHG+hpq zA5TbhrkP^A$dB*|fWbcL$axYu9zm?U>MyH5tJ%u8Ax=yXJROd0DCa0JzC;MXg?fze*mM6NQ{t?-x7G5GNw+S{ zcMBKMe*eC?E_@q5MbyAM(OVIq;tCfM)U=Rz56(1a;HLzIB_8`C)sL^PQF~a-O9pW< zR5`G(1D!1KN#@Y@;abMYnR7 z`DiO9;FJoeR?~G>Y;Q};{&eq=0=b5=iu&ZccqW^02r3>JhcUq6G%>m_O`wBlNsVnY2q^lnbL`NMEe{q~Pt)64@qPZ}$rDBXU$+GW#Xr6znF^2l!CnnZ8;i}jR@11wQtWxz#R zyhTKg=YQ&52!I4J4Q~GywHHC8QW+4AO#8sUVL~Sh?eqA#|8x$^&8kd$RMCPH-u>1 zp)fLHw8=l5SYheQx@8HXMjZX8e$CT_3|$b`%x0c=-&cJO zD5*yosM(zxKe3GG?`neXjc1-znS*pNot6Vvmy`6KPa=rH2Ehw1!rO|Hu7YCGlT^Pn zzveuQ@OkpI2%;BBv29MqX6^8MoRG?(9naN9Ls%~_I_YTnAkHD+3>xn8`TIw!!b1Zc zS^N8*3Iy#N5;;ft--JPb%NG9O<9RpVGrGhcs~*h`P7rz&u?FrW19T#J{P=)r3q+<$I)|}joMAzwFfI_ zejnbwX80GNQ`#ARb5K%{N7d@^=Ae`0au=FnYG}mXw1co|MK-SX%aeDi2V-~;Arsq} z1<{p4ZM*HNBTv<{A&D{A6P z7XUukB*W z+6Wm{U=Aok?Th{rb@vm3ATjxpJb^IjAQFmB#3Zf&3|hBS7h z*~gbH+w_5#$I~CNXjPrJn8L zS;OvQYYpr$kBUQDu3Ps}L)t!FaU6Gcne94iPc#t`HslU-h2=vP46JvkDXUGp-h7wE z;xIEmvGye?E;`XSBpaJq;RO??8qj(I2nN|WLSALAN*+83M}15HX-hz!R%s*Yn86%Q zjkb+uO>5(Hx<=5h-EopNG2I)2H$TXY{$7@vgTgGf4L~YdVsv4jCv^$SKZ&7+1rw>% zdyqPbmQf8qg%a~Xw&pCoyQ*7EB%hNd$L7FmZyDC_#!+JD^&g&JEjZmy<+`^aAd4)Nt*^xi1q#Gax3c&T;Y}j!Spi6ZnGrdFFi*%jm7- zPT2aewk>DP#6CEhUG#HoP4TP973xSClXCz+v@+cKE-p02&2YWgtV=Ahmo4)IHbnRO zNdKo9V~?qeBm$|b^{47CsQ+y&dc!x)HcG<7+rfaDtJ&))JU_orI7IlX>~1gdUQ_Gt z$zPO6Y0Sc66(4YQRB`Cm290NGr<!JdiE!g0gZx;w4`NZBrQm=@Wm4}=k^^D+JX*!t*BAi|W$p-pN3USS;={Mr| zoQe0`9T{)gTg-f-7LNxXT+KjWxjC5--u|39#G01QCxI8i{bBuO8SoshX8V7iPUmL+|^ z&{nhRw~*ZDykgr^dMl~S1?6nA)A?x+^o5ssv}?KMBTRE1BcnYn?6njEbC#R}v?!xF z@`?!LXNZ*1cnoM1kWUWl_x{S~r^|!O;67^&{32>xC8wOfbFaK~YcupCVEuuL>K2K~ zHr5QfK0cdDy`5c*2yTA=KYn!4He@4yXsjapFS_V_{QcK=n$E6fj<`KfE~(g~#qX_@-!Vrp6+;)*hO#G=2k&%T zEg+}+0xbu)%DW84mE2iIc1@`UtTFW}*M+P6CJrPYGi}s%*hcjg=D|T-`N6IuW9?l7 zgBG8ag^&+;{D9zqHq^^rp|CG^R)))^k!h8+AYwsy4fr&M_nrV_-0<3AAgk}~brZ@e z?(UZ(A7`(fu;MQxnx4Og|6Ubes;kf1$ zkCl655z9@&PoC9Pv`1>(Jz3xd8}LQT%IoAEJhBj{kwQ-%;AcL3CX-}3q0(gJG51jB zH%BR~F2U)b&;GqWO=sHVC8bDE14{zJ>I&@?tzBkp+U4o({mmslu4N4O7-V|t6|DR& zHQACCeKY~yTku^bH!!8hI9VlxqHXq@`ZK*WVbuDwaK2rkUtF+1IE51ThVj$ z@^h0VKvB_usD(e)B+2q8wp>7j&xF!SbKPX_0v{ji$hqJq8yW?Lv9s)WLcuV9UAPPE zFx6x36gA=2YEt1*0!6lC{f>($L{5{E5B0^ch3f zzNWi<=ccJc!@I+7s729R$I%gm8J$Z&Mm+5q z@JK`2zbF>{m9*slB*14;Wg)Q)Ik3vLCCkl2rwRuF>seiI1=)jTvDWMM2n7Chk6=NN zSJz$mjnrOLOy)_Lt7vK4n3|Jq z(k&8RYadxnPt1*O^r}T?5d2*A^^T90#qcr;|m1bce z>;t0rH%HE-)^J>xpPhBY&Lz@+-m}I(GE7(CjJT96TK}CAkkPzrA3R755WcSL02ewRkkUlS=~~1>QcK$Vs!;Oj1Ud#jvk_? z;&b(kUDP9C{qzk`4iS6wB;_JH^#{@dXu3%fyTo#P;Gu|khA|CqTC+8UiT5h7haU(p z%M<=fcpL>~K5PJCk1ypW?=6Kx$pC62BVv-06PI6}zyy7T7+y`N+LG3tJOj4Vf=xoM z;d8sYRZTC97kP&~l-Hps3G?5vzhoRS`msi^6d zsbSD@;@mI>u0Pz&@du`JqT1GO=Jk6d^9O1c;kmcqQ@PjV>>4 zBc~=D6l`9Ii~c>2o9KIFPTYO>JzH*)O>HJ3AJ`cRz+zo9 zrzC>ti_K)xy@iSDT+#KoC~!UE==NQ*^IxgT`0*|G3Oy_z8N(6T)iPLW0?e|Jtr`1P z3G%~AOw2A*wxy~}13NP|AZrb8<2*8?j3v(G0?=?K3l-@`~*{Uinn`B)kFBcCTV z8|KalHahRkP8J+lwlOc2;>BYFy1T)cM&GCxRMtv;R%EQ}8}(U5mBsfHPrkGTKp+-G z--kLO!z&Q*_pMZg<9-ujvt6hPRc+~urnT)A|9N$wa%dhMK?Xg?V)H%X#Uq-}xS;;? zUd9jDhbt+~i-Nh{B=)B4VX4ciJl62AdA%QdZ0l&!1Vi=U;{PJw|G0m{a+1^b#(kc9 zL;QjTFgxqzpgfik44N+hX|}2oY*Rm@b)wLfUTuY26-11%UrGR|E`1*a3V}-2_OJ#O zdA8hmVOlitF_}%lf{d8vqde9Rk<~6gd1yLa-2>Keyw#fQ>%pA|ku-k#y+Vdyt=u?= z{-NOpq%6m}Q<`bG*Z$4C=r?}fX>1z}v2}gVm9ZhQ5;0B^+dl9YDfn;u4uC(3E}!J~ zJzxD3Z%d&I{aNb>l6*dw%4lmF&{!vAbaXr*PnbiylVDOUSJKhERar9A`#Jb4zzpi+V0Ob*S1wK zi;9==-)7<$nWSBQw}SSK^dE{b{$M1NP0ZHG;7Q{|PF6PfN@lcp`3=o|oy#@2yP`#Q z6Ec%{giw;#q|v-cg#9--G-ToP3>38cn=;5ym`UIlB~*?lT;<@g^Q`%B-PTfszPE=ZQt|`fP(z=fOD1k z>OLaHm?Z$T7X0^%PQ_les~y#HP-9&vQBcvTzNeG_)3jIkdbH5W597UZ7+>;h;>pjP zF?k@C&hzMMaq4rv{#vg$)A_?%Pso|vx${$dP+5vnGi*Wh&#subc$!)iPw#ZqBQJ5i z6b&-MI@(uYb6x7{+>$&MrvaLEApfuEtO#MX!s^L&hLkW%jc4Kx+N}Xc^V`IqTqHqa z5RRjb(`JeM5RT=)0+=L8NzZnH$X-+v3e6v!>d3A*=IXcLb+&tVWCTk^y&Bnqw%OM6 znl16F&M(``S)9MJongo;0j?+_Xe=Qv{D(SiE5rn1m$5i=1SLa8<&%JDQ-&@9N|PPL z_RhC?!&$30ibSQd4`*rZPLzlVS9Dl(C-r#QT>IIE>Gn)KKul^z*sd+{;+GQC~QfPs2?+0AzLe8iV(8` zU3X|9qiKwXE{rSkIgsZSWL;8B%)+Pzqe~6JdFTzJ&by-o#HOo6#G0}YF<)Hh3?nBS z_879p^A(%csGc_~YDS;ShHCx4+WzM=x4}#RrF?+HI3veSp;{%okPH_2u5WIBTu4+l zK9klM;^In}Sx&&HJa^Q6-)J=YwmSsIHoiWn^_-z&6VcfS;xGCQXdHUO6bWp&CB?O40(jeiV z)VFO%9m!xA{}ff>n4ZpTm3lqj5Yz5t0ec4dJWw%m(%{yF>Ql%4mq)#ol_2-bEtFr; z3rT!Mx#*4DWiE>aZ3WA%Ypi-^RY66|j3k%RA*5MJxxzU`$B4VA)`y(fCk<9ZGfszh z!(*A$r8QNLHXYlYU3oDr59Ty7A^}m0M!qSk@q;DF7n_@#b3JdSK4hq+9~^Gswk&_~ zF$Q$c5$MBVfaBKj*woZgK=7($^f?VSFy<5!KLkJ9C%Hj!6=EMAWN1R^S5PczJR7mD~bLuEx zUd$9L9g0(TUE(*Q?31RN?-ZLu$LSbWX%Zx&FCkL^ODRdJ9NU6YhDw5W8BT>!={kU+(`dw=r+n-@&sx-?+o zw{n|^VE!RGxwxNP_p)Pn&+5GQBJubpX1ZdgNXypcGA(Q6`*+-iSf#Zrb!oWDjK?&P z=ha;nL4CgqG4@QZ!s$Z)8b2l=u(eZNeOBO7I)`VOLN5Z_l%I zt5dnTjmtm4xqJW^iSp^+?2IfS3z&;cWVSPs^nUZok}Hne z$l>Wg1jVwQKzW6^K%hZ17^UvpDy<;TYt{(muAX99a*+2j`CAHVib_PSwp1MsRwf&8 zdpM#VFj3%jNZiBlRCC&)2OYn2GVy<%)xuA4Ly!k4KujzuTON9TlPJlDKm7gegc`;8& z4ty(gs5v&$XY7KWPypxes#_)@lagw?G z&$uqKNR7acIUiT6R%b$ZdkZPGL_ass+VJ4hkGklpef;nos1pC8&r){aPUi<@I( zQJ?FZJYE*oW-V zdV+!`6f2%)SIf7D=Aol1h$aN!G{)*yD$yTThX%@=n@sOXBdqOB6R!MJ-^q8B?;tkG-3@!QIT(2rC81Ba@ij) zjiUJEfBLe|{x%$$+yt01g#3>TuZ>YABozG=Zyavhf7_q`w}|#k1^Ql<_J=WPi*A7l8NHMN#^0Qcad*_5;Orm2#EjZ+ z+(*_clvhm1N%IZ!GVxg1VbMg_&{&=?)?6Rz16diduMna}!OS+)LZ?ab9O4iDeoW(x zr6_RjwWYV0W9cJ5y-R#%I#H+M=NGiym1H<0u_LVCUZ}HcePfV=*o^uxBQ_RvwqmyY zA3thiVOOAijK=_bc04#Bp3t^|3f_@t%@QG75sRMuKNO0OEl+mcIv4{2D!J{Hp7 z@S2S(gCvEZ%FArro?(ha>@c+Oa7b{m9CUwtVr)>jZ-#cKibZ*8d6^39F$Y9pc0xO@ z3DXI`^x0m?`44;wQ1bbAF+WhRm7-Glyh>x|N0+e8{v7Ez@Ov2RKH zx~yA9*6Mwifx6?qa*KVW^m+%fENcJy(29L;r!ek}wuQu|&k`PLQ0ekmaqS$rxA+N< zr!v`o`$@aHyS$F7$EqNIKI!B7d`MoPzdm$aH)RdhRlQTX^+q)R8kXptQ%PXH`W()t ziWKUO)>+mU2MC6 zRqXs0D-j5oa+jWfx(I-y_ag22^za8yJv3NFdL^oUXauT(4`-t;rP-%vNr^Fql3~ zBV}2ra$P$BPG)$_br7d#gt>*~rA@{I@=pZ1M7@b#YO&=>^M73qGpND+oP5c}#_i0j z=MYKcr)yn;g=Ie^aO10gy_>OIgs05MFs={7m3usL`sya9=OGF@Pr|n`@LFaLF;2Xy zv5uD0TR~tN;bkFpEnZR+{G?&{Yb*+&p-b3gWHq>&c+$8k_0R>ps;;? zH*sU|9bVCWNF71Vq^I{~yM&0Ot)$fs!XSnS@cpG}+&x@G*9&(+fb?VeBns;`w?NAe zzTdf-Ji44ZnPQi`{nnjz!Bo6bAZtKNT-;uX+uXK5?6bm~aw*MnM|zTsp|M#8W`U|b zFg_mMPSl0JfQX=0Gl%IbijIhi7@S$crHjk%#^&MC2UMLxXU*e{Dd-rdpYaJ*f8$?L zSE6zC)=&F3;@PKUUoK#k$P3SfIveISX<3GG5iYFuk3*veo=er<`W7}QGF2pCPG)B= zt7)Cx0Lzu}>>VP2UG%HV;_zrPY&G)OS=n_qI==UCV}Y-HAl9tnA*Pa9rTkLzQj9N9 z-J2`v0vU|tm6rS}i>%cM3&+a20`lesNE@X>_A57#Tva>~2<3RMhxO1!A{hPDrs? zxM6ffMh6YFSBNO{8Ehk_fTR|DVt~J)2@{;+6z@rJy&cvrBlCg;PmO)RjtnW z!e`%uf9j*Vqco9FP3`lSkvoBGeDD|3Jzozb1U#x{+)q5oG0l&G;FaArAS_2hG}^ z#%Gv%;mrSB1mxEO!)APFC-%nKcu7`)- z^jNLiP07C9Y@oJWKL@tsNMWs7MlIfH^S$f&_roEVSy=5I99SM91+Z2MdIaV(`eqi$ zKSb+^bHqd?trzZyH@bfRm`6_7d|m4iyU;hYUGOGZI5dgm^Agqu}k%`1oVm_lyE9SDR zGI{h6wkAZ0hfYoq{=;&v`;6W;H?8{JErCQ^TLh(hEH+Slb&#{AZBm7?pto&uqLYw; z)GH(f_(=uO{lyE!isc>g@2kmiQC2urecL!nG)k`;b+S7fk0%HzLOu4F$I^4HB+Pe7 zKl;S;XFNS6s1o=v^N+Uu(7o4iU5jy}P?_;h;QHy_a(H~z?cJbE@B%+skv+#0E~?Ko zx_Mde1JOcadTFPdNmymdo2Uxs2}Y(~M4RYxTiwz?OoAeo&2*wEjZ0pP;&Wh?RovAm+Etx5{9*w*0(XeDIN|0Co)qTarPxbJp^G} z(yMohM0J!-9Y-gF{_)QdyoHIs^mP#lTe@BMP_&_eDmb)X8VLv|5i)I{-v>{^N#v-; z;KpAZSj!C{8bfRRG-g6(!y*dgK3kiRLbi3QyVc2-E2cR=Ec0_|h#8tO`>@(lye|k_ zXE0f8dyM(;(L_552k@W3{`!}j(u60+U5Oix8FoFOco5=I9}~=&Mn0t1Sj#p_B7V&bRoFFkeP8xY#1O zgU~jg3e!KCM5)M5!4m0g8P&n@U8zr!-<^B5v2$vWufh{}TLdQu~|rT|&K|HYte5@e#UhCX0d# z3k&0sGD*xF>E7&}iu2tG5pissOr^#WJN$TKnJ+CD1vSI+=+rz>B9Y_s(WNoaEn)xP zUn93K`4~@FA*{QBl~B&6CePlEA8Yp0JhEc4LYnVIvP4ZA_TAe8EEx$LG9-9kmDj~6 zh$W%VmrM(vJ*ik>|DL1uA8fh;HNI$NsZE4Uc*xCqzn%Q^rS$9*pf9Oeau>-llnM$0n>bZ|W_%BQPPZQv#LxmYNKXyaJ&hrZdyFXI zfPk$ifn)@}es5vq0*3O)qUr^yjE~`^!Et3;zd$_tEH>t)Vft+8a*~ zk6zv+m&!6fZjU~8TKHGLGQvIPtqD0#MgkXAIfjWao5DD|$B!G^kCE-ai_#iE!eW{D zp$6Xr*n*1HyBEN0>A#kLx#lu+Z9%_r%O`#hWpy3mfeAnO=4x>FV9AqsVR5m-bn{Ev z=EDvTE$#Tpf06$_qK6c3#&V??WB+Pmjh|C{8-byztz(M)m^`M3XpVVYG$)-v^#vyz zH{JHVBE44j4(W{=jAgLKIBymJ3>Ph_vy~(^xy(T!Nd>Fs&c1cLQ8o}YiTP|71p~k^ z+N1E9bE&)GDsrJE4gl3qDO&)?Y^(3Z8-2uw1`UDpjN7Bz!;|Z+%iuCLgm%!;8!oR3 znhf0Hagx7|VU{6MrPh^i!=lDdxZCDQ%(}#upQR6R%G(s(0|BwFwL zrlcm5OzOWsSL{dh^(7=M-!MAi@iF-`Re7|yca0}SMIR-(jO!b3vTphoTKgMo=@=R^ zOYbqP2g$9kN8qU(wPyu~uHz@aGC}g%WXr*%4u$TS(=(Uvi1wk|p$Q_~3Mx17`pZ+k ze`P0jBL#42yKJ-LZDUK;@eUj+d{*YM?K!H~_lqZWeGBjqxmo?B`bm;-XqJU_gwLpc zmtTWUzWM1FZ_h92XzZ&W*hO)7R75^VOs3|bB{sPQzBZwSz^OnOP;5OguX^%#iwo*B z_0!Mlwc(3bk1%buljqpYpYK0JPSla8h$pUFQX^#%FCtTt^Bx1}-1} z0t__@-GH;liP6%Igfb!MB;SiGDyp@lAbiF?CzXYh1t&qx_=UR1Ik`o4Xg-~58}43b%yg)yRHPxK5Ea&~q%*YGG5nBIvTUb?U{K2b0-{HwP< zyLoN!F@pPcHBp;xKjchEx{Gk+@;Q|`vZLB0dLUnoAu5mo0-hl9Q9uzrkgLK)5W7sD z_122CvoV%i?S~V&IG1RDRCw=lA&1*|D)ux8+O$@{_QgB`(!1Qtd#^;WR;9wJm}2(r zFH%dhvLAYAAxH2!Ka!xt_K8nDxOZu5s;ux>j~%eicr|i+r8evAJy@t?X?@VqbLrF_ z@c)?OLOD8aneDY3o5|H-ZG%@20QNlj2lb0UrHG=!JYoK)eNM%t<;1_IFX0U|j^c?h zID2-%^YvQtIjr5kdLfI$P*5c8i65b&^j-QN*)Q0vOL*t#CbDuJai#SzpYt<16|GAq z^uE7rkrCG0I$kJy48{Yc3O|LWeSUuYgt4z~acf0C?xe_9o(&{p)MWj2Z3SIPuX(6f$^~>P-?%`@<7xk6DWh{;1&RSj}aR3&99> zdug$@h(IUhUfy>WUf3a63N-Gp;zE0!q)bwboOF|^-Ks$isarUMa5{L`g!|jgSAj8gSbOX$&t{LSrN8x zx-^_!L^jyqsCY#|F)}8ne#xPyr%^lU#kiOF!>!R6R6{V@NjDLh7l{X13iKj_JHaYj z`+=}Gh;(jn9>GM`qQn7eFC!T;{f8Fg-n?&Mgt0Z$di@W0t5LmQTu4aNKiqM#RZ~{< zD5`no@Foeo8*(5t?aD4D`YE5mAJ1<~(czf$>6KJD;CTE=RFjhq%{r*?&aZ{RH!=i$R<8(P1FV~lx=8}17kM0-|b?2E=yK0@* z)wzj{x$+u_T$z`-(@%*#0fa}v7G(aV@PW5+`jwZseWD?Gl z=)RB&r@Q>)>+RE(&o>8`NqEWNRf_PFMDJhJk#Wz~^*;EUmp4Yu4wY}3TxAR-k|Nk2 zT5BN1ecBw^qES0B!V}8x2x}*8c6w1zM7sIN>RLtt9C{bkUfONU zgB;Yay6~Cis06J9fYq>8rSIA}cZHjOO_icDhMvh)R+~Uu&$iJ{ya6w@iQ>icg|2em zq+Ky)f)w11D6gip0Bv`cEpbtp|;893A&a$#ahqoRka_7f^3ZX-X@3< z)Dds@Q?IA0$4_#hKui@@x=9h=0k3L>Gotof2j{NIolww`RxW6Has9Qs{s=+a^{GQ6 z085bKg(+5z8fUMgxx=(}{&7(w%FS2FuQzST!!llndSQf~^zp_`I(iWIMdrFaVZMp^ zsiWbp0vO_zWy7C>wmI1{J$gGJcQ#tQ>MaI~uG$-15K)OQW%}j+p-sy%no}R7mR-|Z z3$?aI3QI*pQSa@Vx$+T{m<&;42;6;P_9@r}kY7V-19=6yKRg6Sow8LvlAn&nPyBzQ zL@T84Iz|dxe+}dY#@>z7*`4%O6>(R#8{WPrnt#J3?iy|l*rnt7z04BLCWxjba4JIS(R3uwQPfv#SMh*l2I`C z1rgc#p-*3LmQ>WFi<(tan(|Iwe$6Bb&0+(*(dh9d&uZRru*P&xVMKRpFF!MkQ>AWLV&c=YmUVty&vr5Ennvtw%c&jy@FY*k3#`0wu2mT3%v zNIVoqk`+hYf}PjKl!Pz~aXgQrTP&5$JTuw&hYHREuD6U+o6LbhDaI9_vgrmZcCf=@ z_Jh|4ONqu3%aBAFLk?zN#iZMi$;_ArumpmQ~;5V>#n{3 zA5m`|7FGLw4@*c%!zdj?cOx-?!qD9zol*iKC7lAo&?(*B-6cZ~0#ecpDbmvQ&gcC- z_`R&}R>9TQHS#)#1_!ftOOR>heAg+x@i7iK5>elOWEb1!T>=Q7%H zasF3RgHqNPj>ydNVt^gZDG&c>g= zswUV(1?F9i&0kGxrEf>s&X1&rV~in76WE4$tDL%2$%w_IZE)&n_}IWA#^Jmv+ZicC zqUVX$XCEheq6d?ty0gFqM$0CZZl9!k%LNh1Zr}Y$mbU?$!DK(_*&2yHyZhi&yXY5H zg9&wMJexKmDqWR_v`+QTe~xA-!e&h7Z_>~w;6P&7O1#5&1BCGgNcEbn3K|5c=F>WK z?kFS`aDLt=Co4ZAQLf)3Rt zwuW*Fc10-52qXtTSlXsF4Uz;qcUQD9Mt6FM-|y>+cXn=lKYfGq;kGy`Zf@upcRcKO z{SdonvY-Ulp2@xAzd?oSOH=B{8S2#})M_e7sFm8_6jKb8E*MGd4d81|gz>arV6ZCq z`5sF}!FBlne2=6smQWo6H;sxjkbAC`x@l7o_dG`~pvXBgMT3V{QeC9;NLNJG{#{XM zMc)?w`th5BNrb*rG?XV|D73MNG8;xh7sGnJwar5U?WN$$-zEqL=s$j}1y=X0lJK*q zJo*2F?cIA4l`fClpE7-~A9R0btcb$>c3isak3@}<81-`npn(%ef-Z`D@~Tn_BAna^ zs;8<^0wg6r{p8eUevL6&nf!N!q!rY`xHn8JW$fejWQuo^Is5KnR`JTzUL-z!P*o-) z4s^1JS)ab?fE+kNlFYdP@4as+)_xU$CdeorO%=VDpqG95Ic{R5<|_B*b7z6ZzbXF1 zq{1I4-so!)+Gi0ve4R&QW_PE1-Fuyd9r_c|C#I{bvB{YO9CeIra~-gsII%QPY^l?W zkx~3O>@AwP5^hCZ2Y|qieUER^Sz$Vsx&Ywak(dohC`j1cH^ZQVYM*Mis^f>E`>GyA1!_DAK(ty4B_ zhH%s^yw{UrUcW3VuWqS2ypU8v#LU0Y>0euXA$BL5OVmtQIt6!n#w_ZrW!1~y|1pOT zRv^g-7sAaG{Y6&E0%TcUqG!5p`yrhsc;+hYVy1jjxb{nzw!VtkGf;c?4}OlXrWOkQ z4gu!(G46WoDLr}W;?YK0eli8AP0)J?T~=u*OWEmucjx_x|NV_gDtZijjR&m?xpsrx zh5gPh-?%@l{BmDbq;4021+HYwja2=c&FVT7P z6fy7Mp>z93-JS>MA181vK=`lj%%Y$Hp2>{gNGtak@+499$qr`Q&OUr<***uuh#$Z;%F<@ipQ086r?aX3Ka;t+L;r1(8~HZ$HH5axZm;f z>4>u$3RLYcb{RudSrRq|-uspWDbsBmW>Ih?RAqX$hRx;#~hG8Kpic9oVT623#p7+kmHxXEsJ0YvW@t)!y+vXW`QPy7AuHJj<+k_@!&Np4C zQ)7lVmHT9G$5yI-O7Cf0E4=wTloQ37zHmXHhw&0Zlu8bT2QF;xr%Z(OyI@0HaysF% zImkp9!`r)aHA8y-ciLZd6EB|nL;jqr%R)B^8`WB(q-({krUDM9j7}}&{n*lbowQ{R z?~0poIps!)rLQdz+52Tw>f4TK9aeqU#43L=y zR5LduS*OAyGVyZ-qybCVFKl3lVlprR9t~NLduu)D=s()>xgK!DT!KaLpf2|Ptm;l} z{oia?4ZE2<9Nu@~);Lg^KZ%0m*+N^DI ze8;IL)!5HlszrW(FxYgI!sd=u?@FjP&bRD*bXy2pI(=?E*wDj{PiCRyK;}Bm^Wioc zO`lb^wPqXO_9B&YojK1dG{8h;LTY}v7I zXFj0NHS{*OfGIMaPh)+XR?GAXP|V$Ou*3ihDWe+IMz!WNx#;1ii(0sD*QK}QBPj#= zXIp?#P|Fp*^pz#uoQ*amp#3si@+o`Tzfql-#FCT&Bh2Gde^LpAh_>X@QfATGW?9mg z>TEt@I$2_EieC!i*l)dU+Lt{+RCBd~TNz%FWh=FNy4iYm6`%TlmHnAo**%23J2b2f zNvUq=E5bqc(YHlz07ywVaFeu%c6w}63{bFL(FoXcZ(luT$EE7bEf7j?D#yz##bpm}AX31>jlw6dz&xj16#8;~vD z_*7}PvpCN|wY{ex-C*Y$?*O<-&Ar<-K+eIba|Xk}b)5d}2PP8E=y z;4F(j$V1|~VJWh)Gx0bG@UbqfSH#yYNRgO`%;mQ0^r8(I8UYjVp^0KsGfp+BGa6tg0# zOq^u;OK;RVwloGJCmIuWtb}^48d>qr!_m)vt)9O&&S=#B*g45wRTIU-c-utOYpi*(7jLT_^ z9&}abNMwK+TeHr6NX`GG-1yotk3$w?oFYj@bLaR>igqZ$FgJ{CQtg;qk{7`9Fm?Te zNqJYyKY%G|oNFBvm?`xvrBaAn5O(KCIxES zBmu@FJ49hl?TSgKRI+rhkbM?0?6i{URIbvOC3yQT|GX6`rJ%@L9-tdtdaA7$EVpwOY3sRsU)5k$*jS z_*uqb2+xE`PGweF#JG$jfBoCX7AuT3mXTyW03o$b_UBbyQyG!>uD*4@gPqq zlfnL2D+S-^s{QWim%ekT`q|s>F8{Kl45yIZ<|OUa8T(@ExShn+1wJ1NbPE-BAL%jl z7-%3D4*UZf5)TxO0okbV`}7}!2_Q1vG~qZR_4O>k7!9%@eveTHPK#tF{Gr2FUuBAI z!WRe(s%RbLgZfcGXErO!QqYrT(+!m;pd=LTrmjKEN6;a?&t6RhrMm)_o*cElbhTYv z{-gg~I2&@cp83jy-C}1tV&t4v-ID^33QAAWaK5znn{s%v(;lQoFNIl5T5{ZU^o0Y18n zhQ_cd0Bd}bP8M!*`lME>g|oj;YY;MD2Hci8V)M4Rut+!WIO`c^fAyYHtS0 zGOwu=*!kPv%E^X8<>s!5#YJ)%%c(DxKM@yN0OA0`*{?QEJlFUT|CWO2HTneOd%WOq zz#PUrso0~3w07b%w*Ou$JNhc0F_yaH&z(FvYol@nW@mqNYA_EI`1tW|&fknJz`|hg zhpc7V>4LPwI&&M=w@e-x2nVMXFx}-`*{yKcb&n2En7tQzTa4Hy*)Wq~7!klqm8T+& zsuhW==NG=~$IkBo)MNa>%il9y6yQ6fd*Acv**I21INR-mcisgwMrZA55BhG2RjI4h z?Ip+PXn9aL|JOE~8#B~Dm4Wb@Gok4MgaU7dcUR3R4wDV&Tnr$O9iu7mM~{bE>ASq&8U2kz~nCkcQd8;WGIre(Ke-@0azaT zqR9~@#v#BDp!W-DO9;FEO~J|Df$ma|5lx722J}AXQs(^+L9;PYlWxC3hpJsDh+tOI z0PJHJ+s--Htkw6lnUKhQ%iL?ZEGNa}CY2#f6qh+r)_1?3Inn(nlS+r=`fJOwF}Vnz zFej`@^WB!Kt(?{2_lyKm$r97`v?@+#UG}Pp|qUqip12`8M<7D-pbH z)JlQAKc$B>J2cBKIZl}txPv5D+@Mpj4{wjP5~(Sw_9Zh<8!4W&JD81yZo4*Avm}y8 zc1UtIH;tH~p4?wt7M-pP@_G4i`3BI+GFL<->4NyP>BmdqsqaTW)Epe3fzI(pF-4`s zgV;a5oS{(sBs)R$(PN2`U!Q56jE4X42)bpM z+4?dMhsVF`NXaRML$_w={bwUd)_x)JD$`6igQmQl#yBwxHXl0RkMQCbg}>C8GRyYx zKTGo;+G9_)Y7xDB+cMn*d)SMfr!gpa$7pKS(3IbKcD*l}(4+oqCE^%>;$;!L*q&Z>hzd^xqX3Usa|NVa;AdL-x?OfIL_p>3HF$g53gC! zHU>%X22WaUI+iE^xs5vmIZa{J0ll|8sZ`-utcpslTW`OyHZMl6+*+mWX?P#vQl-!= zUf?W%c-|2m>4!l%0xZzv2l|@%VM#4zbV`>A!NrFFkFM%GI-9O zS*;aWDG*b_7eb-?NjAkBz=|679wsc~3`oypdU-0Fdma^$ zNXGW`F*f`e+F*5C9hBgLZA{&IMdq@nfMWqSe&^ zj$N;vw75Q=0>H<5#wk#Z^p5Zv=IkfFQe-zGU{#N8l(NC-uK<$aH6K~=4V)Ce_F(S_ zp*`zogtD3oW`p&T`My|uu(#hY&CY6eZJVHT_G09UEZ`oM;c)>IH@8Ug!x*<$&YtND zqRE&lelHaqL-Vx{N3aw(i4;9q`mr6!;rDM*`2j^ke1EtpF0bBZKW)MjOLPv17*)KA zpqYcO5}2O)SfEA;*W#z6wjU~eqj3gBEiTH~Q$AlpvqmpFVEHpUl>34UcdmRM!7Xyt z9i!820Api*pZ%HL)Ra-J7CzW?@OLpwaB&jLi{ zMF<+Y55y~``Zs`v8I9L}4n&NEa zf+*xPMwoGkjTzb04JG-xQA#ijl=w%15-pVAJY54QDQ-O5W%s2h8E$(CPuBBC7 zh_CFo93$J}dH@W5;yK7#h09HV(72b~MMxo-`f*fRwY%0h-I6IQ9jSuxlO&7_owOXE zQ1*K>vXb#9u+LdKU-`x#dciY8@6#SJA*z_McJ6!*Bf|A4;bU%?FDJlAWtNXgYR+CC zO{;?c$~Jjxq?QqlE&=~UuayiqsuOHGSl#^kv!;W-ON#N&j4vQMfObf#j6Hd$n*)qk z=a2%5a=CPgH6eEmz4-_X`ep?E%(#sHP^QLa)b*5bIz=2UCmwZdS2SpVQ1Oh+E4E00 zLZkS+>MkG$@27-d?}%ulfzJ(%+llv`BCSw^qc)Mnu2To=<}%(0 zWU>)hDYd^GE>d$G|-&eHASs##2cn=lN1uP<<}0%*^|jwr?l7ovqkoBUv4z@ zba4F)Hl4&?&K;(VYiCQRgI!e|`Z6p@pa(Ke(M6O=DytVto+d}SffvBG4a5G^pA3hH z``y{@e=NHK)kF{35~Tn*%8l;H0j;8XIdZ=o2;^P{y+x%;mMq)4+t|NFmYzcgL4xtQ zUxz7ob#?D_y;|VTY`1W6^D{~*K}aV5mu~w9Uv0bJt!d|_s~TW&%{8_c;uHS$h2KBm zdWz_6AV>|a8|5iNqKKWV72cdaG}oxYh>%zs;u}YstFbmt7tlvw%`Fec@ZB|^rBV|%(q^U#Xw?e&ohfvt14O$l+Td+izKf_bS z%8aO@J+~DKWa5(=vhu$Ws5puCW0MD)p*ZeEQpSinHB%ChxYitrt!_aSbI7PebQzhk zm>W_iKE2v*a8n??;IXkQ>eqN*L1&=Yk494ge3!UM&*l*3ac<{6NHC8L7 z$}s=V`_QLTPcCCLOlbQhccqM%AwV^a}W=~HY=rOh%KEgK-;U^|Ltv< z>`Q)oq9wGL+Y|u}jLz5FsrEokUB186)$1{ExJ^6j(b(- z*lJI+!h(+O-Dp@>KOg#Cd(lW?TZ%mq{{3JUY2HD~d*`cg2#_tjpDtw#|M@q|om3xu zW1F3nW8K#K|5Gn5rh5R#Nn3V(N2iS2R&5~y$`NT1J0dn|Dm}Ew2>fiRVz9|6EKc{k z;ABfp?{r+EBU+?{F1e0KHA=9WvDfA=aL$u}-R@%s_TlI&A*3p+m-ja{4(2ZnG#glA zgm--b(Uto0Z{I5d7xX(o*2(NdQNjq=KIWcC#KRl306Kt~xh22?MQ%*{U%QQ02@Rey z$m7Y(h#ju$i`KIfnrV#2tyEJ~NgX4khN4vE^rk<+tgzOTrd4NTx>)?N;A0mzny<{a zeu|BRE^eQ<-kaOyHoAmWQ*qNzNU0(v_PwBh!ql*lE?oe?m>LiZUlA#4>a|sQV-um+ zO&EIA`roFLmKaczYS0_CzCe8N!)D%7PguR9tnA9w>gE1KtR5VJS1pwhT}2_nf}L_!sXECdp)zTXuX=_UJl27LLVCjVCnw1qz>R>WnRlA`!5gE1`_KPYXvI)fGf{9Qy%%z5qj%t5~WFC_6uu&W^Kro zeRp|e>VLSi!L-TnK>Lt0(zS47a51;=jPVx@swq*`36oax z+0mt_kvAHy;P7zI7L5SyTx}8UlrwLL6p*(<+FF)n_NF7 zt8^<%yfE2)zW1OXL3OF1Z@gtuw@*}@#EjTyt5R)V%{QG_Z1CEMQ-zCeyged)U0sIn zvSpsC&&Z72#@f{2s9)!EU&1>UhYutMJP)!>JDwznO7h|g`o?$n2Aq<}TO^#_?Po@j z7A`dSM!Wt}kuOyW+||ll&3jQjg+2Ojq_A;&v)16H;`I`V_AR_rxNc$;ahKoPWVo6G z$rOT7pn`@QS)}u;3CE*brw%ye0v@m0s8SekEgVhZDYTEOZJdj@@~|ceD){)0mLxVm zWF#%_s9ed5caTzg_m_sMOgq?cRg{krxIoUxl{tQBU*N)!5bhl6m)P>uKip7_>puI* z$NdAIwz1N{0|{(*k)XQzdglp}Idm;GjQCS(6cz5ZS9Dh^aK00g-EPIw612vHzHV#R z*ffdI42+bIN|CO+lLs^(kkdkLJ5(wvpVv37*z>iwr!yni2)cVDtQ7D!-V?3EL#NjC zfYRMIZUNbT9Gxv2&6$}3?id$i$a1K zTj5P)RwGmvT9;R9NJ{Zg4EA#<@roTOsfi8{O{#Ef&HCtw*PUHI7XWCM6rJvUL7aWu zOrV37;~^dy0xi@OP2Z${y2cwv1ic=`yC9$u`}jvI*E%$Oi)EZ1 zYDh6_Vv+qYdx8WwvB|9uZXmvYkEjPQ)}RFu8{4T{K34Y8d>{Ikb^FYH5^GOvzL^MQ zKbcA*f9R&)!vFNf{^#*$D{Ga%j*4@?c@Wu;n2z>rfOhnZcRsD|$6Q$&vIbn*1kzyA zF85*VnP=nYtOVn#CRU?1Su)_9JTD*;1@vu;&5rI7DkOfGlF+$*`9~FvLQZSD^vfh= zSEWR?_5EAX?N;a(BFPM{bXwzvb`VMmrL1d=Xrami^3w9hWxn2=M3IX-Z|a_W|My45T;xs%oYd6w zFno{yc5PZZ_`m|$atGS@ArA3>S zD@%u3Z{K_6h@sj6_{rMI5C*h}GNG06MfPJR$B%#1(!49hhcIXS&C^ua>Y>a&4tTdR zcTpv$rMJr|C%W>8X5^wt3WJaFEOqQU=h8P#i4^=^oB*(t$w=vA-DED)hOmyXKXZwk zg}rx|P@=P$O1>>h2oKY*MCgg$S1aLBlJwO+x;j8xwZ06tV`NT)??eDjqT^yMK;rRJ zw~98If6=>AvHv473!bXyf8Q4)*iQZ9h#=@psS_6l3kR86m|q50#~^snf%@DyJ|r!Z z>ik36YzH)Lr|h4eziMJ@f&U@-iXqZt2A2}=ycn#(MA}A)9$Y~LnX#UanB(83FCcOj zO6_?Y#meka!W=scNO-cam+!Mm>8st>Vi+8~%%39hot({g=)3*H@}z0lv#4jF$b%5S7BS*Io`~0sogyE>!D=V|!6EJhxg14v}qz23f3=m_EUJlNiut@xE zwuR%gXLyECVgIk_A}$oehW&189wzO2Eb*U@=HR+4q_`N-G!8!i^c12pgS=I1IA=&0 zZOFo>A_IWgUQK^rS^FgT)5P=pB!@?V6sK z&^GMAeKgTSUs5GWPt4Rh%qk2>8}DsBFs0z9{Hn;>wV~Npn!1YpW~jD@QNbRkxnaej z(D%Llt^up72RrhNp#gcaMVN)k|0G|w2k-Cg{am7L>efBdf8;eh-RnZ^9~|SR-HW%B z@xo(NODY>bFuIoqL03(&u$tB#3|%uz#Tz?4m&9TrM~UdsrCBGniV0wAv5u+xI?Yd6 z!#LP=O7gq*cY-)~!u>*Hp6$L0liPb4VpK=15{#cS z^#;eP2l~TfUR9tzal(oH1CPrZH$^8#86Zo1au)mK;rQzgoqX)yXN1>Z7xV0l8F9P* z#V+OUK6G+KK^d$MQUrfI`l{rs8l8{&5wkt~j~b&^Y-K*yZRK?1WT6?K&|t7Fdfwi9 z$`tdcsPyKDrm%45#S5$HTK1;9oW)8yAy*jN26rD#7MkAORofHCLfvNweoM0SiW;on zVJ&ZX-#=Ozuf&o;P$HE&-9XEn7x*Pm1X3Bvv3sjh;_OcU6(hz4zp3o26v?`&tjs9a z_HQ{@W2H>@NbGV1H*xFF>;?p>FfgqUA+p6opmAkBsUjh+_hX?J>FDwTMQ2^b zmQlrT*v>(q^nEVb4YT;eLZ40YBijtw33`jx5t7JVeJFt3uT#nC_2-`UnX?x=3r0!C z!0^n4zbvsgj2gqHD0q~m2@4{7<{7(g2H?EFVUgm`{v-`fa5p3UiW9c zj_nDwu^K5?oDNccpNZZj3n)+X|L=FE`Td+_@|e=3phPw+!7nG?Q)L@eW7ha>Yb!;& z#gs7M_5`F$?|PU*A{v@@i^>{H2aD*()*^hz@+A%MH&+}FOtVz(=}-!KrfxMKW{xk} z$)3XMGFV|2=&Au5f!KW<%jYGGnI2 zOjy5-5S~+)0{Y3M* zeK7Q4P00NM3c(IeGg(Tc=DYUa4}1OeQJl*9{CrqVK;pr|uojP*!0>gdj-}UOE2%M* zx@Ia?^U>p|OY-$1?jmr(SoZa84H<2jI!E$F>)1vKYu0^H;>!qD?a}Aw_l*;U)ZWb+ z!}wt8JiY=Z?mP>7Zyys+4afSlP83~9_`YL zZ2$M$?k?~5s~UoFT6i$gk&57>F`|5|i6)QOAPUj^lmuJwt%IU!e~MBN)sh|yFUjc} zdRB=YeN3~o&~#8XI}##Cf*{hCZLG`T@+yu~Lf?Xa3IVlTUBy$zfUOX1z>pqhmc|0T_p6_;1jPJ|6f`Le-_m#MxHOLkY@A zDzvMn#MsukX=8%FvE=vhWsOhBZT)B$m8a2RJ=t?!IG7JTvuj}pxOJLY~E(7Kdfaso_Gi(DUwK_Of_E;lhH9KZAdj3|PPu4Eg{YJ8I`-=3wWz9I^%L#2K z3bILFh1Lpw?=07lhp1r;G+zc=x1)nvR^OX9Ri7?OK0bbK=h>%LV_+R;8*F*{%fCax zak>vJ77}rjwI-y`QYovUMt6!q|8lF%`iBZ2k~%Dic9?+S@8`$Rhf<=gXC|LkfqLZ( z$&XAUkaEcBSEG!qV7_)edcmsKKj@e#=h?b?jaX7M=~!}#GAmhN1uV9#9zE+2b6;Yj zNhKrg?V{GL>Z%xuYui2R0=d~uRp~z2qr2Azx=pO-PYVNM1KsOnV% z9%7m=#HwQ2(6gXP*hk2zK_KW0WyeCA!#A--+H=weiMF5DrYDm|;`S`j4g=9PSq&MJ zpo`?ys~+Y?VD_1CtW z=;x~DlH6L@t6v)bvqV?h&DXuw>Xle}=ddJZEPzJ5?4P9FEOjDpX4+U@Oh$7Vgeq3{ zS1p1B8X*kB1WI(xpA};q%CSAO?>B~$%=`g#2}xtMZJpMG-s^gOw$JUuF~~=LTBHj#LM-8aEH8-qLA3)Pe2wvEnL?RGL2;RPuTqG?&Fx6r--q>*B4{}{t&(Vhi~ij zWG;o>P^|Z_o~z0AYsp6_z8-F;!MPj;mF>?v;OpZqq`AcXbbF8CsZ)bi6g7^4DM^@( zE^jPI3Y@P2R1k!S9ztT-Ui(Xb3eU4x1CH$lnDbUWZ``C9_Ib(KO)W}n;Q23bzp_*G zbBO{;&yzBTqsk}V0$OG8DDkz}DvwhWnxPh%GHU8eOvo*w*P-9s+n2*Jwln_R8k5Oy zDyXrmTWkFcV^yg#y#0LvL?%a3ZWZaWl>VN8#3ru3>45tJ0>TK5aK%ULD8lF8hLWmS zb`cp3w{l(xn~00L=RXI znpn~f@vgHA&rY(O9Sz^dy9dM`0=ZNZ;0QsXA`o|H+u2z>KfiZWp8XFT$B&Ln_rF%S zv5mf&rdhK_wCq`H)XJ*$#?{ye+}kYThT|Z=5laym)u;o)DP1g@@?d!a4O46Gf>VCP zr4BeAK2#+=Y8LgiQ^Iz`N=U80UN}I}mtg57v zA8;OaxQ;#FBpN{|zDla7Q8hPG>a1#PG8aNUQD-dxcW;lw<^9!n`nL5%(7&)3tnu} z-s6p|rOh3RoFu{K4`6=Fu*+(t<8b}nj{H#GvqI~;;iFHh1K^5)3Y)X?C0Io(Y7f0X z>i9a!YO`VC&s1zLz1-M`)aynz!Tw1eeAB4t;}9(%iM!jC1p5 zU0+j&ib*sp^}HqtRbwn>Emt%cWOAiiI^<$|PLE;oGL3Yxi6_kE3YYIVs+?a~_icT6eA*u<41OMc;BM2F z&u*jqh8t`S$Q0Ys-LL$AX=9P?Lp4UNr8EI2pKUY+%!2pBYvbqlc8@ zWL|hX%x23}u4>?dp-Hgv0S*@m$7rflNYf1chO6`%n7LQS z+L9=rLoc3bxn&%VO(@;C#74vsnkpYcbm)WNYhQx7d4D4VJ!q;Yk`9tF3{D~|K;A~L z-f((H8G=8|E=%qEtv#58hlwUr6mK2S;&7+%J*P~$f ziq(OeS6y?kgv3kRO0%5*5`*{oOmBvZ?{x;GJ-;l9o>7ODSk|Z!%bZ&mjrHZy0+`NFmHaiCpk))V8ON%4xrvvzPi$9aE{9Nzjd`XH zPEz7t{B7>L;Cw0Cd>fsT;*^@{3IT8&p_as=QlXcg!;3`oK8`E=W~CaP)&7?)7;R3k znuKGmlcu{sUf`;0_3VHvBV%XuA`ah1(g@C9W-d~5h4;ce`;{geB^ZF=tjR$W5#9&h z(jcOBX;i-ClJdlXTvpGq(Fj7Zl<#)vN`|T8>U^LexDa=J;aWVg8eeKXAr77Wk-f+* z4;$WNM!Dh6m``(WQb&Th#OlpcO;?22uDscZHMHt0dsyaER1GP$DmL$aikm&hNf0K{OeOeR@`%t2TApXs(ZG*Tq zEt%m>xz?#ThnKfjxj1}4#fnx@(m>lhWQ)Qt;0#C#Fptd>-Z>l3W$EzG54b$7jqfa{ z%ZSx_Z-QG|#VH4)+^-Sfr>)48Z1EIDosF`J4h6}-N)QWV zd`!}b=K`~1TVDR)u5k7}^?@g-@{>7DQ9mopp zey^JO?DyrS=qSs@!5O4vpe}6i8a_Ky`Hhjw zP%4_1E90z=UOXVTCSP>7S!DI$Zj2|GLF-cS46{!q#jcc>)Giw@@54~N=X(YQ6cT4q z6KOsVbe0`!ae7ziBWJZZSEWNkzk2AgLe)#RI&v<;IE~T}nLONKnFLDd5dW<{O#LF| z=``5-6}GHc$q&7{Ca8<-()lBU$!7Wdxn$8vYJ$A5nc#=3^goN2D88f=;wMTDBzrbt z(&l*~^vPNuLG^aA3~vdw;erl@Y*^wbVi%o3+_T&TX}R{V_bG73lm-QLE_L6$DXNK% z{wse)pKnf{q=4TVQ@O;EfORrd!G7;SX|hu}!o|`5WQcUGE8C5A)sSC#6xH<0!>Ix% z#Rh1ajA!#)MsyhK5ZM5Ff-^$rJcbV9(z9}!{vQA{|FL{Rd^#E;Z8=PSUgzwqiu;QC zOkrNRKw&&%lgG`215rN6$2xwVV5Ob;)#FqpiJ^?8Lxvwzx8!_`PEOTZc3XTFkHU6W z?H>PP=XOHL4Y!uZR%!RB#)JZy;Z2wlIMI-+P1FU|Rkg2kK%bS>qEsM&#yp-!9a9N4 zdGC{-u2>`+I=l&oo^n`0_)~Rf-8wx=sibA)0u-*dHDVyL7vr>=C1J577o!mn_XpiG z(TZs)i)l`Qkf(f7}*4my2 zSXndBeU2xMy6u#~an*L@`1BmBO;xVd9STPCU&zX`3yu_P(QDhg-W>upX+*@3+peU@;^<|2_M?BMo)`D|$wo}{_* z<4id1L=TQI%3M8ayaFa0uUht2* z#lv~#PHkBF?s+ew9>_%1{Q3J0pV3Pr$8u@ZvZOTsWS;EW=rnoHq_pc#ya^VAbvJfL zY;)F2^@jQngX0eW1H5ENN0W2fQ zzJ=PUMKlI#ObJa3>A^OkrIc^sE}rYs#UemNf*vIjyQsEgLX$|-ydgr}tVmgXE7rnU zk}#4hLyJiD6#tjsBJ2uZ5tfi04hsrWIXUe!GSsGLEiOL+<+ce^NBmCB`mbvdk9ywW zvOmaqceUIr#?)iJye1to*mT@%nS49o@2M=|9||17LKxVS`=W%$n0fUg5HU3#W4_pV zQtQUELTdnd_OLs(9O_$+f;3VK>1aSemV+h^jBwXH1<#M=Ua-oNa z$?1npHNTyrCX|2n@ZPKj&&O!wwKdI(Vv&uKL_!6KMrjT$#J8K0n z?;x|;%cLuHms0^%ua{9=8J~80q75o7? zmn8W1pv$l!Z>)Y`xmu(OyP75jFhoFz;rs}X!Ft3u+fD0awkjX~eX9{CFny)xZQ_nu zg5Q%Ecgaw}m?l}o3-+`$Uo0{7t~SNhmX>5=aFL$a`O-f1uj3@KzN6_5tfMG9pAQkk zCjsPBMRtY2YgobELX3H{U4neBI3P(n?8=~q+03f#oBR))WrXH7h8!gFk_Qq*tF_v(Qgh1Liic>%U^4&=)S?{nXos#kL)<_m6a zh0_UpfhB=*-#M#xZ$>%awObWq-IYrIU!N0j1j@Y28QMe-)WK7Xm;oCTu4D7Xn@UiD zsGLgP4pc;RyIHFzW7HShzx0}Mvl0QeQd9@?L^;;m-yCJI5)*_))GU8si&TswieEB7!j$7f8iQYKP6U%#zFywuEQQ{P-|4_&Rv`O<9|vsX(Uze4Qr+SWtgi8C+mvril) zy>)+h{eAiV#Y6EkDUPH&4NXfO><-Si1x+{Is7)#4=8; zM&C;5#>!Uc-N-3@!lZkX61dfikQ~w$WK^&`POZ15)g}nMy&qgxsrbr(43O5A3pr@w zxeWgM3!oV&OnrCqQA+w`k0uBjs_tNKIYlRKz;;rDF;TroJMO|g9>@&rvw^$mBPVnmQ!F5yUmA#z!{;O(t!6I$%S=C zqH?FHtv`(xoU*vZT4KmoySww=V{*~>5_*Z4^|=U76lG8DgRp@Ot(2I&_LgJ~ivmR_tY`EYrR@%^wvZ)dy$)eR*5CbYn( zw^-y%V5wWG<3S_i1WhPSo!bWqa0>=Md-+-WaXRPM1LS!+*+Q8)x zfO#a{f_wB(hRUXYh@-qI%W-i%xf84i`$?5NGR3tXJAC!+_A}k1kAh|Ts zOG_=Ggwi1$QqsLhiNw++-MO$VpwiMUUDEaL_qu-Yy#K)`=AL`zoHJ*dyA##SUzsEQ zu9g{Q_S}u<=Qe}m6xgPPl+Iq}N*O^D0iupg2%Yvz(T`Dkyv6jC+;DCfNT$%K8h&f|=Cj(bG@y19Voc5Pqa`NJN}@l}!H@wWT@dO!xZC zlnqC{`I$8HoW+aw3OYlj!x_p{bL5IPG>pOhnto}VSeK_mVVtPN21Mx_^r6%th6LrU z-KRl&x5sM6x99AL=`H6_ZZeIYUejuHp_!DhC&{k@GAs;jlzS3`**C@@RL0;nBvadZ ze;Iy^Yx|^_=_ek;{v5MU03XmRq(BN0J_({yWtkN6n4Tx0h-Y!a7(yv3B=O02k3mZe z=uFKo7QOfrL{2I6P3Vv|KtghuVm@P+$N34mybXC^NDz|Ey>;VKQ5Fx12N9n3lXNK5 zf*i8YQ?PoUq18r}TAx}|zM0sgSYIdI1?OOl!D7N@{P0KiB=xga3r`;Jj73WHWr7hH zo}Cj$*lRBn0>Bf(3Ddst!UAGKpmsF1L>N7E!0`rE4IIfR5PHqBRmjcxy1SL?Z&EGF z91AQ&>jX3|0v2OBWB`^~m}H>645k?UR%9xjD-dHUk={j&O5E3bAIUAK;p=qd`_1Y; zQ~0Wi-*WHe$xWFi%|1`1l#^}e-gjyO)e^;7T&z^8+1cs#J2gsjS<&noha`GgnwO-W z|Mn~%)+3Gkt+rh2*fu{9jG@ibKh{98=Uxd`NcwF6J> z9z!Mae6o0$a?#a~IWPYPOJ-DE5FBaGt-%JY$3-}j0D>>6&9rOnWx)0JFG&_JPxn{? z!$7t6O>V6yLKA7O2}L_Xv7r6NR1sx?)@E<+%fSiKsXs){<&shMG{Otwj^$HGw8K^k zm(L#3rxo(HV&)DG)wNj+wTrrP2==}heg7m1#8=vVg5^RuN}j7zXg=iB1LX4mS@h!E zrCEE^YcvvFqJ(fbzY@1DHCSb-cI%J!|^aB{6@U68w~^ z?-|_?!f77_3hoPs@%gY{G5*F^8~t#+tl200G3u(desi|`?z5;uShJEQ3tr~lFt3lS zev%^9D4TGkO-=6qaT$;bz=vwp4)(bu)_3d4zAXX;bXNn`X zUNqq-td5ssJ$A>9JB9>&dTYl@-30+~76~E+eXk zoT0cvZw~U;bV=*(@VGVhKidOh;YM$}G<{46rYZ3{pjqt_vB7wVx8>BOXh6}4l^UaF zOArUfR{+f!kP=u*}r6897LZ8RD9jpU6i<<)8bbA5k?ZF_2ZH^tQ^`UTvj zb(pFxq+h|E1p1aG)kEea69;5REP82V$g4$R(S$PPoon6IE~>kN`R}06AuvQi`GsYv zYiTqHvN}mjAM-L=O!BzUom^T6>vbbRQc%N_0paC!fZYrUmA}Jw!nNZlX&M9kZ_S3= zwa2FCO;W|hZ=L^&dsXPQ3VMX;*_lBGQqb)wKt+NPQ^2y(S*5(cEtl;=^OyDu+{Gk) z$7m`mbf5Oobx5$2Js-`f8Bg%p(V$$UTv;ETizSqM&8?BkC?n=^m6kBg`WGGgPAKy~KMJ+ll*r>*{p|0kW1CLVXQPe~ZCc+*c!IvSPUe~@9eC&Z~#!o5VKm2m11;~^)ddVcA z|90K>{At90s5vLgSykbtJQJJ6xc~eV))UwyDRaznyP~#@_I`}Su3Z;NX}smzgaGTm za^XA;>AVox93#Q$;4XIhXeHU{FXLl*ECeOlQ4LO;Tk;B>KMVE`p-ayEr*v^?&_o9y z8_Agqi;`kdV%R`Uz1ts0%Z61gf6JS{fj+LM1_^hC2XmWqUyS3CZkvPEo3%Lf$Q#nW zi3xpof-)xd(C#u1tAfXz>Q%q@GnXM;k==HQa|av%A)LZz0dlfqn9R(k6wwgh7NcK> z(&K@t>d;`W?fiivrF{0TNCh*yAZROOQLn_wvhXd4aHYAOqWM6(@Eocl@eh8FnM=f* zw59GXtqynn8#((1=U36tSo8JAuS>aQ5zvWwil&(y&MY1w9CMUOS#Xc(M#a{bxEg0Zu! z>*L|HjFt2zlzP*C4PRf|RU?_cqU#Q-V017tIB3$_+L8llnh^4N)TNKDvYBRoZS~oSafhqy!P) z3?99KXheQI{kZ3A=H%A^@>!=9Eb;T4@@;#&I<|QSK-{$SyLT@7OdYC8Uk0B_ z`Dx;ZRM8f)2Cs=Lny~geK8S#m#Ho}AiIH|Yb?Jh zhU@u+Z0@$9urVVa7xZOPBsehMKDt1~FSi(z0fA&1_^4o4Nyni%C* zN3VtiTWgfI@MC$`bZqm!G+Gqg2P9agT9F<-o~fH%l(PS-sa}bX^%U){PZhS{OiFci zel0pO04RQ4*1j%PwJo-QPPQ$+S6t5G2}I7=AFkYn%xtUflDO|r9EPVYb5pO>s<&sZ zL$9;AwY)Lj zawjC}2SE=UQ-?pyhzOs0nV?~ErIo)~&BmfUY)la2WzIeJPM$fwIf)Z>6ljHm*>?49KE zq=poJIdsLO<>)~gM@@A7`hMhOV>hXLckog|Cm4fD=v^p@yNv)!UNhtDfu2XU$awfV;T#BnWK=2YYk=oD(%wj*10T7R^cbKPV*Zq1H$|H81-S6=7ba#}gG-eS*-&>f&->&amg^5fsA&s#EYEtEjMy ze-5V>XNT>3H1qGid|~D%_OpbSjAECUw^^La#+bihwstFI+uBh80zL@}N^1LNXZT-Z zq7ih^fsBj!h-}Jr1&rf;L$gZ1*{y01ITBI*wL~X%xVHy85`Az!X~nPyYO!Y9mr^0p zIDXCEhM$qf&>Y%06ncf9GGrAmtVvFsMb7OabK`p-d{QSUEJm|U2XoZWaMK(SgCb9gB zGw7upZGyckT@arfw!;dc1r}G}A4WBeJRLJS+jKtNg32@i)x@bhN?9u$?^R5ASWcrk zY2kxtrOgV#2+Dd1EfVgA@2Xc9XG6YXlrkX30%HFIS$?aZBkaLzCiD2?b6ZuHe~3o_JU@A72`q z%um+RTu$G7nAwMYIQyP|@y{lP=3X20(jvuM^Qn51zP_vxAsUQF`jam?1P4@_;T$>O zsSD1;aQk(Z3^8#dXGd*5{rt{`xkrQUO<8i5Hiucx6Tao6gmu_;jUB_*C%+YuR*t5> z%3a!JZ3j-oa4M@+lh4=Bd!QZ=N#{f$tzro_iW#)QREN?i6$MZgcGjkKVeLb6rcJXDO5x?l zJhBz!eeL+t@bt)Fkbv?A4B%+sTt#o))AI%5NhwEKuiJD)DVNC43_L*YO7@D}rVeC2 zA{oyyXhm;2M3rWx8U5F{2~NZVBvJ(qUF?RmWu(GX$QAUZxBuK4I3AhXP1nw3!!LLW zO(VnF3lgSruwbg)&M7K2fw*L7%?mtnDp%Pek4wEHScJHOU|qdG*x%v#V$w#~XbNLP zJjs?kdQ&H28Cm2fMi0rP4G-rVRp9+9oI{8IYT##O7inJR#t$=V3UqQPu)>!*$3&*Uc?X2k0z$Lg(p3o$0p=1fiA zPt(SP{rU8^H!p!dfqeDkkf@qk>xBSI@rbP;$1-B&;G*~XL^^L-VoxFC2&(FfOMM>- zb=WE1dF{S0JTpJ7UBzl&ET)H1FXBR79g`kXFh;}pdv~-ysssjeuaXq$3=}Ne&OZw5 zL!&z$-3H5C1T{`c5V<8* z_4~2F;j54LY|cm9vQtv?9UdRICZ&ki?7OOn;vb5>3dm4mp#(;pCvwl7~wcgsqLb6i5)Ah_EW; z@N8i`I^ANiW4AqArgFj0@;+PacwrBvS3AkZ8)%Al36+(VyL*|Kz(?UuSC5 z(ZvNFF`_miPgkJnxhfpc%{b*lidCq}U#zEsY_N`M3Zm3#x19J|y>G#N7hshYz3ot~)DxSj% zlV+M={-?5X(xf3!xn_>|p_+G=|2J!E-8?r+g(U8*<$!!8i?`{p9IIR|rUlIwQ)rXG z>+tMW^{7ZvyO8l`RxRfm**DP}W4(HJ|32&UM0t8SciYnJR*GcczQ0O7F1=z=#pMuz z2YYft5*6)897ugSHM5ztF%7m1h-GJ0ALZf;;wQ< zIDyTlH&2Ev-3mFoN~#`xwBjCUH7A24*45DoNLeuA?G7CXlV}MEMDK6qDkMd|$+8%| z$}Ir{w0agbgV1WMD}(yGqc^hu^n!q2BCHC@Yox@ii;j*8?u%@p-DY@ws_teRuM%+K68D3DP~F$76sb(-$QVhUm9BSSw+zsA8yXh z_Lc9N-o?UT`Ps^}*k!WBFl(zbeD0cpll@&PXg#1*y~C51`=PO95LhEfeX`p|bHC&# z22e@fa!p=d)j-yF!7 znnE0%#MvJPkdP#X)fguoq#qrvgh6+LA$uwG2*(DaegedUXipNVNy@)`dezaH384&U znu)+pw`p_^!qit%Uszqmt|=Y;eu;a`nI-U7qWJgCt@_=Yw=E4+cJa#M#I7X0jO(6y ztD?gTs$dXxR-NJIr#GeflqCFdy4}SqQ=&$W3_DOM;AL^U6h()#@wEv|Dk8h}qQ15= zDF;)%qxZoA+P>RyK^%bI`#AQe*`8*x11+^dJK~?u&-AvVQk~gfr}`QxGC=l@IS=?G z&_vnB&VNZz$);boXuG8%cJo=XV3K?9PhHt$lGg4KJ}_ZihrO4Sa~Bwd6|=CIkZ2Ji z5I*pb294Z053Ra%*xT6&smF2q8i(5FYX1&huaqNFbLZ+ym()h2D6rCMKAwWoyP~By zQW5dOR!TNJMV2^4YVzE}&J!%l1sa3N|7o^Q!IQ+FmQ+NH%(s4g0%KQl>7T$GpS8?W zjP7(rIH8IBY7sIZ=WZX@aph5b75QQr0CiNvLR+B zILu4mzkL{*6DYq#kB6DUg5{mZV8tO$$4}*k)~bCo&@pKK3U$d!r9wDrFMSh5bWJgM zx%$4Z?Y{f|YbHv*<4@0P)V(C!IJWA;tam@#heQX!OHR#q{5{_sS{^eY{s4j?le82s z{_fT@Y{yJQWKUH4PgNv+{s!#d@s$aUGkEGcEu=yLVeKrpT4zGjSE!ZA)3mt6cIcr; zbB^-ET|@_Zy||aB8BN`)%WGzOeT|dz59`IakMCaoys3|vYwOF)YL~u3QC0cP+S&S9 zA*WZ}7j-WN(s2QTfs`W?7o&_?edIu=25a0!d6*gk3#(cxzW(y}>w)t>b_>oqc%-Hr z2q^nZI9~5$*-aVh!b!}=({6RDnBew+;r2oN8zQYmhWQ)Qp^NxFYqiu8S>Cvq!ce-J zUw05-8`!_a>y7YnXtS500$MO2*Pryy7_rHxt-Lq0Tcc!YC7F{021A^~`CYP|k~!ud zcD(L`4}(4E*maDLt?ujuL zlPI6g^o9T{0~XOggI4R<4$sT4jf!qo2k$Ag&lAHeJ^Xdz6x@Net!! zwV;bTkS#x?>~kedx({hXUdBsrwSAb*PA-TtwF}uxKuJ2C8v||Ux4u}t0QBh?+?AhK zV2gfv09)3mE=K(DgvHM53^sL)Z?TshbrK&eRGePbQaQiMsmi}3KP8wWp^3E5P6K;{ zm#jt?j!%BG&M3f|_%uit7lEzeZW5^IxNte$k&gC~(OY_SmAarvA075E5b=t0E10Xk zJ<_SY)yJzt8}RmYh1}BH%;i|&9?9_wz1n$NuFGB1l7H1_F%vnu$>Y11OhjW_HLPRx z**__j;OutF>-%bNCEc{!1HIhsqLz<{>)Vgbj<4MI%6@cXFNm4ORSE2rl!&iyJdq0? zsRC<|Gn-hcn5uSj75;3yq$NTNrtGKvm9)IueDWz`C?VoFGap3hhtPiZ!jC0AeS9nl zyZ(oO*?P(_|^HBf>`8O z4McO9QxZw4q(adNqEm|8c7JXmfM*t?xeZ-64KImmuMHp!D*}I5~sP1S3~l!4&KCvO`@)oqxP&Y_VQ` z^?lfAsyS8@5x;8&aaf7MxeGWEaUBrl2yyL)o3DkL!a>1G`+XFRASf^=4+D@({#!JT ze3D?0vJq13j5R_GOz&HXxxL|Sy*_1#98`C*T*P%cQI+?0JdMwkx`%3&SL7d_7|VLk zoW>VZKhjy>*R(2<3wdsa?Tq%kVzTKjc@QPSe%LrB0vF`zZ${;hO6uA)KOmDQp+`KV z3fpBg7&ClDX{9qkuSyUJ(xEk9V39fIVjV!S)-t|^&z3LviiN45O_wQdC;X1GZjX6y z+HQ}tTB?AR*H%5}smK2XspoI)7%@0fehaY?5lLS5h>7;~0S<0=!JoHeL+%3~(!+>~Io_ zV81-K^u|K~8DZ@-+-*IN!|!s(J-Tb^gvPo~SI%-X%k%7tvE$SFJzgxqByn@&n;h+Z zJ40|y##E>w^Q|$Ad8^$lP%)<@{B?jQ?O)*_oMVHeKW?%=T$HU?8P>%5;H@io){~O1 ziLr*i*?~XxZQsp&;9V!Br1I2va=xI_)jK%i)?Nm&13QI;(3T{Qw5SrRzvzPSW?ABf zfgc-G>KxWCg5((fdZ14u$kTDxcc04=odi{plwFsd4yBa2a>XcKusALGYG;Q?2kV-e z5;&`(2v0Xf%UI6pow&7&2ew}1qY{}!twez#MT;6O{au9NCGA8b$Z83i)X>MkAP4K| z4{(l{Whu5?g5}!p&g1hV{Zuo(QBAM;ARpRpd#{b3(uA6P(7$N5_^af;@{eF^{%YU- zt^yh)j@W8)lsR8XO$<(S$JKr!+cU@=W}XaZqbJt1=|TSZjej~F0w*~~6~ilKxxaHI ze^BHTwA%?TeB2J2R%pPqbww{u^Ms==2MMt|F{L~jT7Vb`ZwFf9ZrcsJMrUw?QH~-% zcgP%>;IeSwzQsH)Rgy0Q;GK^DGQ|;xT1%SA---K%i~(zM!p~Ph6s_uZjg&5V5RGb= z2`3jL>t|u9)L23S)*SaQ4kK*dJWS(2boFx_xXBGLF9^S*QVKuxp!HxQcBeN!HZ)KS z7PR_HRm@kiv>21xt;9BSN|(}XP8J%d0JQb9O&v?m<*MqXSck?}n6GUmV;PB@-DQ#& ze)#7~9;?K-nfiWITdN*cu2|@<(?ngo=QUg>kD8SU(C9P`LP!(uy^MqqKKb? z7|$B+Bu0*4^og1HB{ztz5l`1fAGU>u}MF zF@S|DSV>Z-Adwi>TqR712O@2IWb@kTRM1K9(!4-j04F!+6(uY{DT9%J>VL_W%f?s7 z9Ki>j7EzslSHV9@+tnA}#$b)4H?ky}7tlL7`SGO-Wl?xkhmcLPIx0*-J4(d5)T}gy z5<1#vmOKYS%W4p)*E(v48>W`Vob=XY6BSZcJD%4E2nLE)P$V8ABmh4rVz?i~F2!Fk zk!q&R)khgrttB!yn_=B9=gVaIUlJ)RY_0vkHAPYw*FIv$4-rczmr@^1^u+3NQ%OuE zb6Plxl5sz&Oj=|5g_r#*PBz#qFCB=H3)~T~`MB+Z;98Nv2cXB5t_>=`WTrZ0@adkk zgjGdFg)fV11l3)>3_@aZ2ny8kgEhiHuG z`XSn5r!^>+ zR9S!ft1LuEelLijok~nk)U*Lhzhu~(HUZQN3k9UUe$Mo*wS|CW!z-z+YcvBP#VS6YPp>(2Ij5}a%J16tHETQxkGI1J+X2O)#qJs# zRt$t=tnsTJl!vFM+4Rdqf(33Zbw zt7|yzq*#vIOk65T0HiEg=`eH)Qg~>d0qf^)C4nAOA6;jZw(56YqG|Pth_3}Ybytp| z8-$+Ea|$=A&PdNkcP^Gx?+(Ps75-t~=n|=TiEH62J8WFJv3KDC1Tj!f7iKAYJl=EV?Nmsa9h8LN)YGAULRKjX z5P^s23a^em_gHYQnv%>-9yzgh@T1kekhfX_?430KS-x*pc=vTbwTfR2{mGHG%~mG_ zSk4>c1;cO^oM_3i0wN9CGyxS#vXO+lhyX^rX+~0YW{q0=^{m?~_S-Xr#AIy-VGoKD z`pj9G%Bt6qHjFYLFf;jUwoUVlFBHwakt>kLS(D}zF+t_+ppik9MA6WAKq`?6HV{Pq zmNP=%(AInGAV~r~d7rW+v@8#Mx{g1V?MFVdKTO4aKD1n)f~5K=l;&%uaCD@^B*7;b|=pp#Yy5T?P<`@_7Oe)-DO?#I`r>vsqki7 zN1S~slq=ITB`tt9Mm~y@Aa{IkSy*^2;EzAY;u`l;i38SZakbT_;-%ob79!uXh-;3< zY(B}a@(_dbZ4h2nAfGmt7Ip%E)F{_EU$OR7uU>+eE2-k-SUY)jKuJw;qS1w%#}pyE zrx<;4ES1$OMbj;FxdsEplJV8B`s8u3wawe2EePm?RrA%2D4+xF5xjKVksl(8VpgZ~ z@SsQ??5`-576R(R<&Bqio5bRYUsl|o60H?ZZr=@uMP!Y_!>jgfxsv_JNdLaAgRZ^p zx|FSI(g33xBgqH3M%?-jNIhA5Lgg(@9#m~MhcIXWzDUaLL}v8P)bG@Mca5mnubOZv zDbH4*4;!r$;$i)}7%52hp3Ne$kEYSishi<^F5;DC+pFX zLO;22(RW#pxnr8&Nc+Q@LD!0ZTg6o^UpFJUDDwjal|Gx+A(QGHDt5I3^1JD6Rvs|W zf)SPqo^mkY83q;Op~fHUUzf$)DPT;kCx+MgBHcWxwmB?l$3sgzbMQoq?mmb$fjtC|mO?i&>D@keTN zYT0BoS*Yop^epOPPxu?W5~ya)i8poiDs~%5tUvg(7K5pDBbKO)CpFONwW0Lp9xH4+%2(|6BVv*+yw@zO?op72eOk?4G0)kLp8tgOuoJRZ^m2N->0-L)9G2(`>nlsb>m72tP@zH1o-+u~W5&GkyrLYgyw z!E$HKoMqQfRQoKX%T54L?fiGf#L$Nu!@X_ucgf zI(AM1+jwcdNZ3jbB;QlsSA`EQQ(xU4PcAl;=W+MYDFV&rUz)#K>}R;WmdiI4Dg$*; z^QZu6HPz`j8Y9vYek6TJ9cYU1Uk$blWH_P{$qLVW%CognCH=z2UD+WXgoCzDuDhh! zC0=u6H#c@psMC1bvUe$XiP!(Jtz{f<$yL{8{IF~AY#Zm;ui)-pxZ!o&%y2g1^9Jf- zRs*fX#7IEVUHwLBcrqFx)OD8pV;oEIUNB{e(zdZ7nB0;ui7DL7Y7#w;gx+A7x}n6H zODdwROlMOlLu^e5{hy>n5o|N(IDNv!iYd*=VfaP`R*Azvq3wqfy5b9*s=9CVOf;dVMY4|K z95_q7{g}snJmyNS98~V=vq54d?zXF=|Gf2v+ILz6}?@B5cGuvNb!ISS= z(q236FzxIS@sKYx4ml7O_FEOdY>bEv7^(3-l&S+|O8OVX-b((~s?0)Kc8m{gCAv&4 zOAfg57<$&aZQ0R)aOy{!g8ZhkN~KoE9&$YKlJ#}3Ug2H;cke{<@~NqWms5kpLD|=0 zy;ca z_km=bYpEjNIlMbn{+pvD)w7|;GD=>}+;y6z;!6rTO#IC=9|$R8O)uz9aY?uj97@e$ zIb7S*I#M(Q@70(US$-k^=(P+4HaSb|Qdp#tX;^AA%6+!L>c93yfVUc)nRv{@^OW#J z$R0BXI;-*gW(w+y$bTuY?b0-)X*HfAwim7-%kK*;okPeGNYs(twGiiqTxAlA=wU}!!|aKs(^e{q6uKJ?0};#jq>g}SP#bX0(@VM-xO%i8E^PR7 zx%+7;E95RL{N8wEunlI>XDR|y>RzBJfd@>|ldgO^{tG0`uR(Np(`l0<`~@U4>oqw^ zBD(cBy03MM_}9^kL&yq$b>ZPE_I?OrET$Am$79kRz3L0F;kP#K53M8>>z(Y2WMx~O zl`VPBOWVZ%bStnEGnvRen%&pshws0-Pq+6+V=vCc*SA!ZRUsKeIT-A)&~|esmlMW8 zKO`sec6aExC}PpB)*uld%+=EpS-_u%#XgJX@(^g$etPpM_pbu0q;e)J6e5Fsad)U9 z?+^bzUad3ML9YboXH+SZT_ZS#1HiP|I5Xlhfg9!UJ>+*vsP?`+2d>iqI3Y z_*(b%D)4Bmk)iis(l7?XfO1KEZB3cX@kYmQ1zGFM*l;<~d(?F)!$#kk?rVQ8BGGti z!`cnz5?a3CFXWyUA6M0jVlOItBs2ba3O&m3QPnq31^fI1*|zSw$bB$g?vLU#VE6tx zyf{;OUdp5t8z#v(SqqvF^`>BBU)6c-?L-qaJvkWy3aOfR6I)WU*DdBa4|~S^CGR`9 z>;ts2F?tcb_m=oW-Er=Wcx^q;&tV z0wAM0gx*-{T3)-j)-$ped_v6Tq}v_@b(J6i+h-a`yF+NzdrS1hYOi{&J)aN%dIspk zy+1VY@$4jmNLdQnpbxa@Ty``%2w%sR$Fg!OY+(s^;Abzwgmj_$!YJ1Nf=5%AlFklP zzyJUJbfovSwDHBZh*N#l<6#>p|99WbICSfH+pKb8Ex@^`peB>exG2;f2I1`xKy=%&=gIg#6d>pAAVzxgmC$q`}BH zNr)~DbpK{Zt)TF*64{^*QE$+x{9XJ>d2k=EmoM5=`|xryHjF|i6^qO@i($4vp))9Q z0Yuz6(2(Z5v|Epr6A=|qunh3PiPJBeQ15kWjkk!bwBor7#P>JEapg6s-dCYYm3qvf zdoL6tvTahr_ywb(<~HEuK2pwa6eDq1;eXJ!NKRs>t$~RK-wsvmrhlRBmbj!tWX4$* zNFe-3gM^ZRcKb-BWs+rwfz##t$q^<09+MQ) z441p#Kd2kNv3D7gkhJ?8y;MiRT~G24b^2j;%v`^#Ypfd*)HC*@8!imltbRetAKeO^KEaxq{6j-_EILjH{;qC z`l+yX9kp}(dHw@02cI0|y<;Z#0KUNMqvyysq9$ZxTo56qs(kFwY?MePh)XrI`*mON zzK!RT!t3WTq{h3x;k>7wg~*X>&4&=P`KU_!ncLL8Cw~sReEPFE{(nOnk@>-aaHF=l*AZX{-mOT--CYkR_Xk%$)y|_)ahV<6vKO}dqx-(}+}PN$hwj!c%$+hj^Imkd4<&bksSx(R-m!tp0r5u@D%l#<$yF#wyvXXqZ;>Z;lY zv)_wHcfse)N`I&Yh|^#6Wi$AQLW(!rd*ziEWOMiUgh1;`ga5RSQ4yWkFV9doqvf96 zx`$?YT=RPYF!X6)y#Z(H?@_Z5_LO^cH*04q2#W7b<4}1BBNpq`+L_p4Rhi1|cg5Of@hvQAAH7Q|VH`Uie$bZcN=g*lkbgpm z@v}PwptJn>>keZl3VcdqF4|`*_?}69={fg~4`<~-?yE|W0`BZ-hLO3gYFj#|7Av#J zE^+i_hNoZlL%AGI1rCtz6M1nhqAs#wf#}Md4d%c|=Wjbk;LG#ZiBImyZ*Mlrm20hG zztyg9hb0JPftX?M*zf03TzE*3E$;So-Aj5z2Vkg+U5L;y52f(g8muj}>Z=u>OTqVsN5oGpH90 z0e9AZ6r0O*Jehd5vR-v;D|J6N^r*tUEo;ztnB$y#R$a;T{p))2KK(GlioKT~E=#d~ zI~C3N^mG$jVVy3Uww*K-X`iPin923m@~2~wRBve_COuH1GKs0gKvVE2O^iqf@*_cf zVnmv}KEV(`L~upGxKeYI0yt^!P$z2j{Zj`Jc60!G>a@E1rMXSRn;m)->NWHHuD8C5 zird4QB#zi_N?SdZqSUu}CZIf^eyn%C^SH@e=4|IU>HI9DFS^X15b%6rONIZ1Krdwq z)hf4M*Xy6@{?FqIRzPOc$yzv2dfa?uY$M)qwXh1eldn(Q#r}!{BPIYkxp1@N>ocZ; zaEU#~(XA<#h&m)DzFh<*I|+u*!^@N(nzhyPR68biY?iHft%ivaya};!6QEZOK89aE|F64^hgTNV8_Upnn{dg{vj7O{Zbs zx7syFcjv_~q1@y^rae)_*03UoELbr_RKn*N6qB zOh=PM3JU7A3>r{T0tp3$=oGj>-%pT3XP%HAc=GzPaM3e6`n$D1j4B(-$2?{H!9yu^nXbq&`4@s6($T6PEl<>R^E$5s??nL8Dn>_ZSb#IZU<(P?#Rjx z1*xHW&!S;&ABylo)8a?Z1Vrd@t#I_G&Wj=tl~&ZBMTqHd;JnVwje+pjbnrVDeTO_V4q!psznaa&Yb0#Nt}CCCPxnNCMqr>^NS78?lOc! zMIy|_N*HL+Kv(GmKzsie*PpwF7L7h@Bj#@SFoPQ<_mtl)^_MtgqT^?ixxFv>1;5$o8)knx5<*zBt412iwiGcP7C9-fo2z> zL_E#XCwk`pSL^@S{}gkz-E)*m(Y#n7@?)+5(@uNa``BS;oA;&NWJF%f=05{&y>>0! z{yz+cmPlBYv{2wib+8c*XRN{->Y|(^GhRC(t{&!K2LyPMgoSepwfxEMLS@H+7vd33 z8^Li|i^&HD5cW&Pja?W?Kj&9Mt!l+y_jt|T$vEb*&(92ffwYIS@0Ro{N`R77lIWS{ z8L7{g%a8NxSGY9FKr&ig3;{)ufW!2^P943JcGL9)NzQo<6T7;uA@~tfdi`NK7(7;_ z^vx|Tah#L2nBqqRAhF43D`=qr695|1+dIgnLr|IG|RK$T*;vFga*-7YtC#AxyEdc>B)v!V?d(9 z&q4L#GufC2`oK39Jf+vJ-|kcC(J0FNt`dV7f}0BY?KwL}d$Pmi3&`~^eKrg##w@MrEXwpN=hHNj5n5w|LE96Vd+ zwNV$&N588MlAc`BY1xv<90mHL`k`g2 zJkIeAS-TR$|Dw-wK=y*mqg>i!{~tXKoLj>b(Jyero=@-%w64Bf!Eyq9uID36L&ZmD=%gJIM@-Y905@Lcpj z3DW(8!P`Lb^1sg@Pa018z*rg1P96(!wwx+}Uz#>K3W?lqRwLGdXjKnh%yN_nG1u!> z=@+UH#nn&#>BD1c*!EXOzCQUzUjOc3@S9%r0LGgnOW)gC!Nr0+tq*mEQOt7t(|c_R z0Nn;BIsV=d`HH<3jo`dAf;xlK;e>7gOp7qb-@7VVsnGzh%e#(mgzm z-7RyBhf*AF=yKJ}FFv&vHG#4GXy1`Ckbf(gk~FFPL)8iZIZ7y{M_GT_*^PJ*4Zw_xM(j3oeba?_qPXyZA#A7YBU*>Vui!egB{exB+r<2n5MMO zz*q>!l1JXg4xe4bWWN^a)TMCdgrq%R^{AL)%!%j&XHFZgciD;F!wn|72J?z#>tC{9 zg1Y0~6f`F16i2&uP-_|*Hk!*xkjBc)dK#G+V>%)4cO|rp6&A1_@R%7NNJn9rI{spj zT0{F+L_@($xuX!@o(y0_Sz8v%9NB6=)7HWx1u6OvVlrT*m%(A}<2fCSSi}oYiwB+= z7+*RlJINxIPsILHG${sK-u$tcv3y`@Bp0`7IvEm**?H|~9XY{00_=3;71%Vny_g_1 zMzV$2z6HzWkj|Wx{?K9*P=#{;vb5_La3z6Yb;7voeCJPXOmxs3rx<;o<_G#Qtk)&d zuW+1L8RNrQ^+q$(;IZv!G&HBngBCX~Jm1{<58mD~)9n>~o!lKZ-zLIMDBbF}G$P|1 z{({Me^~q4$8JXa3Cg;2-1a{L=sG=qQV)dxvY>|Xm7B~gZkMRm`S>%8xzAaiFt`n{c*P`CjJO&Gn&7bL~2>>JZTi5Kvgk z*htzVRXSALbG$>L2EC#fCC&|pez+B86RGt3JG1Te5e(x6)cp_Vp%ID%^(Nu8?Vyv& z5MD~0Yl96wV@PaL7T|#Cm|1|Eh`#to4C27_B4`7_rELs|Ks#5RwDu~AHv`vn4^lVv z91oAD?aCv)hLxluk*yQQb6O&`IrkI+FH_r1y!V+ROSU$?uv8JSF3NFw0Gy*qlE8=s zrl1iOd;_Y9P{~s`^}Q!A(yxgsZ6*3!<@)( zaP%GkT|jjc6dL=NKLh!?c)kE1(!c8{H*CE$6z^d);xBjzw}Y0q6ZwfzHpWpw0tpqc zILB@+-w!`opG8ldSg@U5w$SqGr)hqM1rVag)psez&h0 zg91?P9r8UFsd-N;z3ido!4WbuyQ>rVwFCyZkv-z!yuil>KD>b6I zoPej;e1$wrvRV#*?-b!wq14xq5)18_u%?X-B_RIt z`MT)9hh23b8s!(P2vGSFzrZq}GI6oHm+^PF-n@Ylk6d@tT)7V9zEs3IH}dyUH#BK3 z^_{?Xqp4wIMGqI|hYT-xV8!7pQ7~&2L#!Iv&PZdvBU1;HgYvPYV`+W))Nw=`H5ZS6 zt0GaRS8cZkYJmn%L_1*`c~AolDh9A7T45Ym^j0wpgjp#S8MW~^2i^{9nPb-uO&yNN zl{oF6Gc=x`SJ=Qs&lMKx{Jm+TdR5IYx?F~LqASM%;*d+ z*57M?zSMlw3nko|0Z3eQzt+#_8v%xl8``6U2fQDiHFwrdn2q zzDMXJ50V}h-nz9O$fZiZtRre_yTq&8x8Rwc>1Dk4<8gcI9!dm1;K0LMW^5mRQ|ho9 zwyYT{kttb5ObcDu^}akIg7i78i9JYlMr*Rs2Am(D%f8)7E|d+)quM{Sw_9$#0`EuL z+ZwpY>hpJo_P>Y>FlzE>;ZdOL3M#vNI7d-L)WapPPV*I|;Txp9o0K*wE`Hh8P%8BLB+bSBk z+#e6U_degq#Ay$A>z$ezt1eoHY)ZwT3y1}w$o-&5C6A|XyyqHV+3l@k&nH|$S%*wZ z&GLXnuBuwnHg=Vo%gPQ7DU*h1e<~)*oOfj$=L%?_Z57-uJBnad^d$V*vXpj@fb*+H z(#K`b#7W2mSv&K4sID4ID(6kaFT|iK#zpmevf~4Zg9A*PZlI&w3&`p=8&2oAO?pJw}9X*$;vEe>U#F8HD%1$*^{5~!Nk!m{ zIX^?ui`w`JsE-=s8C*cEeUfcxOp|v;EjTTWyYu;-*4p=h*64SC_mH zg-odC#L}=2OZh0^PCsRv-Oh{2v$N6vu}UU>xi;SUa21W+*0DsO1`SF3XeO)>vN+=S zKPiOV-H0HACTlkMK$v1L} z-{R3RP4r#Ypzv3=GUVccLp(qW|I_S9#q+=}O@a|_oq<~d@Gj7&Ic#|83Ci1W0PVO% z{H!2cj;AcKySow>Lv|6%7Um=Ir#9+fLHEymle*@YFP#c#bL!0wyMN;76tWP(&lLyA zCL#%f(ju_QV+S3h5H0pBT5R9;z4`}OH!h)=LaC}|o9ZjpI}HUA zv)o`N`sb6nvR;DrwxM!hxoO?|F_m+99!P923~e=uRG;Jvn?{C>JtnQkx3;f{@$Io|6BSep+< zE_0f6v2jJSeHlOH)7GG`hndz@`jEr08eRw<_Jv1Re~&QUlRUc1s$bD1f5kD)O9!Aw z$I~pQUX51)qyqlmz+%kDcMOdsL)xz(Ec;m(#Cb$`!BN=kZ~QFtZN!SBdz$_AkKQBQ zDs2i<@FwKpz_&rKjZ?;k_9@W>!VZ0aLX?wSZ_#3-){eqB5Z*G)VFLABOr%~!g zb0+hi<1Td+tH(fkjxX;Q)nYWDj0m^0z5PT4De2~$=>J=_y_r$nT;FU{+Z)*rBZ3l& z$i-AF^Ew^Zbe^96Rk3kvl6D9&R=M3x;2qg|5sUS>L3mpA_A%RFm(#X-YZ# zkoYd+>|y3l8kFDVHyDo4AGlhohd8SVKIQo~=Tk3U6fNwPmeX zvonSk`=Mi`dB4?RSf)9RPhlA4JBycIlxgu-A{~S|lu1Z&Mr#aq**2X7kBY3j9_O@l zyZ_?Avqr`HKm8La^n5jluL@*#uf;yG-UzW?4$nC=Fc1{mU(@}jz5p z91ILHBt#9)7P7C(P{5tqE0|pb=!E+h0oj}xl0rYAXodCh%&H%-J(%c~ban3(H_(a?I6di7aN1q_t`!BmXs?EQlRXgBVq}Xq#9}7!{BSMdUlo%4AXk zR=L98$!T^?`NWDgqNDbE*o$MzvM$<2*Nz=>S`^H%} zP3IY=+g-rf3STS#nWM+c|2)^}hW3{Mwr9bsI2^k0pGw0?A9vdTr%^wKeWf46VS!Hd zir)z(<0apFf7^*0(H*jOlXMeyv`gySNAtenWnzMfkQJr*3$Bw`zWM4I$&YP^fee&| zd_?4>#t$o|yEFOyB$&fJN*I$pDj3-lrN)hhfKD>2Ma+ko!~UaRhrb}zR9%boZ}T;^ zuEUYMV>@lB)N^uqx0}r%dPgEsRn4k?!ABnBu-#n;3MmP_bg!+cjSZutDgwv#xIZQpe z`WmyM%tb|vo$VcO8DY;Eg)pd18KO#z<;F0oe0s(wIG>#{22;(0bDCav@aY~!{) zzp2*a4C&U}Q6+VOt%aHnc;c&3-A2FkeR{$gdV7)(-1(IB01Cc_4dSZ^nne8;_AA;2eRgHc15P2sgVNRFZI5WPPErV zA~!q_^TOX{V5dO{fvi!DNJT5$OTU-V$s>*KT$vgVmH(k6CqtI4}vXwO( zvqBa@;5Z9Wr`4xcs;KLo(#okuRACXp-8TtGcShILud;z#gEFtZsC-}Re^CAr#K8AD zIWGSj{hs$LC_?=u_QTbdbOmQ{N~S+aadq!e|1Qt=zsg`{<@rmnp+yJ*kqX{b?2j`? zy}YuKF^ZDWcVD!hh9|*gE71DbABZ*qv7+BO)x50jCd_S!sH!^2ZtU7{BfRt_l>52t z5WlQdY8D%aUOO^kv^*VP9=KZGZ(m4fgeTfGKP}1(v^mw)nBC2Jc<3=&H1me8*p+li z$c+7B;9=Alo93;08L_gnV%4~gYKu+#(VbGDn#Aa^FYAvT6rCLjSj7RT1#;_w%wI?5 zers159>?w@GWdtL%kcY70*-5G12WicT3MDjHR4T2JN6pvw^`RA0FXaR1_HsR5M%nU z3-t=Ko{}5}bp&rdN9X;7zWZXJn2|@l(+%6;X>V`0D)j&Df;E4Nn<&&eg(FKQWq<~< z(T=fk39;FvQ!!U?%|>{cQ5x*bom;NMF)x(m%FrHhz$Br4?@Da_arkC{ffJk7VX(?_ z@)Z@=Ou7id<}Idl?hGtKb>af9Z~LSDA4o-|gNa0_a|#i_lwH5jNi?mFD z)TbM`MGpiEyPgo5&~vy^CP%;7LL4yF-0z5Hnot2SKM(FljW_ z6X}V$7~e_4DKobbhA4D0az8ss0wcXNWKK5S3RDZ1_U$}Q zW8~>UxC$)D@U>_vXkNO<=EiivZ74D6Ydj8Es9|nRmG>1c2@Be8HOP7zS)a(Wv}{is zfaX`@P*tpKN zur!>ws32s$)VMoO4O!TKpS37k=U8;o~kS~DFIaVA0c}u7AZF0av3C0 z@3p_!BxP_5HXLELdnz>6?}?hy7G^t=?VG{DOglk^-n0{@cVwNPR$zJYqP=0|1erN5szyX z-;Ma|QHr7m8i(bxq3D3Fo}iGfEV%+Dw;Nyag^A|U@BO7#jm7=|dcU_w!)j6X$o$KF z!?z+XnSugN(S8eKyKF=XP2<(>U(oZ7^z_aLd~3{kWm(PqB+RhYq68^V1|?Ur zGhG+l&ODulglk$55!J)OzFLcqBs~R^o?A*^s6vY=)Ek7700i!)eEH^zFp$T-c!wQD zau-~N@d`f6drT@_1XXWZ4EQIY05Egp|9xD-FIH6Mz$p%^mvI zZK!7m^*1C2A{R3ab;631bV+i%|1=jqrWV5-Bro87~{_N$MG-Wo6@AF$B(4J-PWOz)_KoVI>Ny{ zjTt*~g5yy)DQA!Ksh)%S9^o2)hve@47(ZRV{^3tIA~GB+GkBI|^kV+{e3hbIVKUdk zIrt;Axz@JyRwSd>x`47mK_QBqe~k?FN9rr#ujCI$n#^Wl(DmOCdy5uRNJzF!Q z#`I3ujsNHC@V~iWe^uet`x~cS1dpDun@(O(PIKqF*`6TI2#1ZopgsY~!2Fq>IhZ{O z{>-OPNF8T$5rswXu68CG9%WhLmdKsB|6GS(SJB>4KyN+kj|t}cLEZ%BNd^0S0p}u_ zK1S#yUx<5vPv98YsHnjzCOC}DPDvr1D>vJ^tfu;?UjKII3-^C#Wi@5DBDc+SXWyXj z#*ic>$a3muI?;)5nyw>=O=_PYq# z+V7LO>x0J1(w*iN_-K)G(%xsq|HE=M1-AnSvw6%NOBj`(%S(xwZ!zXRK~79@V2pJT zAlDrumefDn5%e5~Wm>9fR~7Sa_6cw_g+Gas!KPOkmx z=D5hbr;%%!I$#lwM%t+PFYE879~2t@~ zIFXHXP)3GFNnN{k(9TcPX&_TyRfzl;QVk3wV$m7W9|i|a@XFF$QO<)oNMf%7zk0S83(IfD^pC{(X;$f6xjS>*48ve$V;ay3# zKd^;7+^u!lZNhw&wjTGGPIHaKi!cR#gH*$dh57+UZIBgausj-sORZeAR(=#$SIc30 zev&hDElh_NcUDFwQuKT|9L{wgAHLi|j zc=qw7tg=WDuZKGR%vzz?8Yk^57?I%Hz2j7FKpYSL@Nql8GeXNR_7&30i%79$h?TVlwPrK!Ov0Y}?It1KOIy zm#Def^I3SJNt!9NiK~F?z6H4O{-V;@ASb>)RXAMxwB^y@tj;fb4}GM$)+}b4waFf; zRW($5s>}pQSIk=O2w6Gk_zuLPG2~a+5L3e-+ATfJH!-O``I?iQ?*3+C zKQqv7#lQfnp*+F(K@{U?dC4HwgMbd`QOD~S>uCB?n5n8T2K(mz^(XE@|Dl^*a&kr}M890n_-JHhxV^GgM0C@1Evno7Yi%^$z4c!^0pnMsFs1Ru{zELy4Jl=^l#Fw0|cmGp2YPKZgJ z<9?<}*dbBdSr$FQ@kknK}zTZgywv&{q>ArwOhzDiSyU>-APwcm~-}0V}Yl~rUoob1I|zp z#f#tht0HEQsT1r(pS)EQ*kYP+Am#R7%Pte&rC*fzFw zjTc=56-Ko;2-R7)?TT=^O}mrGYXF<;CnC@l5w=me_1<1$tA4lJ?&*J~o4ANKx|!vISBZbkQ+=_`@v17uB@2hfO}6cF$Oi3#!oM&5X1Qg=g9VRDf4UDtwuZDUqq z-vKh3+>f@A*1ttCVU=VVg8?BA{W@Hap5%<+A)f@xLst_$Db~@%TVFM=pRI91$96#wXd`?PV#7Y+L?nVg9 zAsz9jz!G%V{PiC=UV0k*&HO{!uge<3^xW7jUqU*8^HHhiW#kLx78QDj0ctJ_c)nXA z7{Ys96ncMfS3W#3+vPN9NQLICz2Elk;ZObY$*hNip3hAl&3KQeI&SZGj;%Ed`#gGs zxG3BYsr{Rf<9;$va4@=4<${rSnV89^Y`68^=G7l4N0LR!Y3ZXKkXGuz|MmJE=JYpm z8)hI%0C<7Vbb0Wkh)5$$Snif}*Lr)sZ0)kBK+Nt`sg(?Br`KCL86MkP-4 z0%P};g&4_dQbGeSjPkgKygDh#T`3ZwMTh^(PX*3cO3H$RZ_&_#O!mzFy}+a2^$ z2tX>IoSrC6qPLS=&d(l)imSqf#QN*P7#jHT@Im3RzW7ULu7hszaLs&Oz(u85Ggs6MKnA3zB9P z1%H20nf0hD$VMT=?6TL$kOO#tq&GlJ{4%zm{07o!4JPmwb7Nio!GR5r{t0Txqm$2# zz5;O_Q`DSLAXrolftCS@PgY?LbSu|pSs@F@Z$p;fDq&HA%JRCp0^q&mxF{?^HhirL zapGYs%^swyU46kee_J<=(~Ewi*=0LJV(cuf_-i2(j^i-T*u7N{m2OO$f9Djg!JcQC z_$6S+x(`YaR%~5z3vW~&*UIFB=UuA1zVa-C7j*gQl~2_5&W80;NIhoe8glASI~=R= z?F>IihngA1o$2IYAAAcKcslT0T zx&hA@rPzM@InIU3pu6GKbXvpWcLbRyvI*U5z~af=PCVhUDGFw8Rh`tu-mIThTu;rL zh`kwgSHd3veRJsLN5N0iFt^*9*ZE*!u=Igb34%h>ZDd zFgoyo@y@MQ2-@%lZ6ar`-0SNq75jf@Jws`EozG+ZPmf`%QMGwsUz+0Q{FpN8O5_$M z!x+6_z_RvP*;@27%NT*pKOCs2mgCihC=rvtk5OkNTxv~6cH7S`HiR?n-tfPTPQtgM z2r+L$vu;)v0?`+4vs+(~mb0ox#y%aPf{Z*B|CFuOFN8{L?8;U(+U1q4L#G~i91wX< zWAfj@O5OgOwiyr-giQV%Fp4E+GjtKpjd(Y^B``jbm$MmVsES*e`3ve48e?Rva_q4KLdthGm|qU&q-A1h``IG1pMwSP;< zc`+9wEp4i3IVMmv@pPYLL1A7Z!DVKA`que&+Ch+_@Xs-oGh8!!hRyFbN00Z3brfqq zjqvK->H$jl3~D`_&K71Xf89iDfYn*xFBUx7S1Dfou%q>;S2bDS)v^&&i&{D|FqM>G zpp%x;W`q25Ye#j6q+#GhK>=wS;Fo(cCAomf=kV~4?Pi_9cRl64OD?__ciEu*E}L{yf5qfEV z?^ulMt2cTPA2`spcze3RwAOX?@bmkdqxoLjR{+l>RfX+#aA&n628IfY9HGP9uK2~y z;5>tn4%8W;NeHYd;jr#V75LUO9M-qt*9?w>``?ueXEgE%2qwbE-6@fJ!FKc;Elp>M z!Sg=U{?(s{aWz#T&wVr5+v|VreXK(}myfr(J^g-vVu92q`~Qy;lC*J7oKw(sf*bF5 zFF-o$9doS9nlI`OW_4{8zjQ{b2!aXV$Qfz851enzQ-Ug!&%tk_Z~8!G`PF%#tL(3j zvjEAGmeaY3+P`Ut$Z`Wg#CX1%R#$CP;vU~dw%gCO0nBUA_+;lH zdYtVvC~FC=93*>%Hq*LvqaOTAg1jf0@I3VXYv>DEi=M|XdT)1|hD^SRrb0gk`8i?= zGPwmkN7GcjREgSO)9xoMR8C}zJMqIEaJvwNjy(O8(`w?FNw0!b&@S@9>R%J}Va<;r zL+F=CI5-LJQMoblY2UZ`=~+=?oJmyRlYRE9r_ zVWd~rgW7{S0^aBw1f)d{+Px)M@rnoyy6effdDYmlBE=0ajim$BVsfI$&bcgPdg6BZ zw=Q?r#=~Btv(EmqYEXVCD*9^kuf!!?67Knz*OFUj`;U(``W?3D4$GK*GaHA+H2E7!rH_dJAh88-yB zWASkJpJDI+Mi)Xi7!I`by;N1OC0eCG6_Bl;76Qdn5f+dm8D&{q+he>V6_o(Y5fOQ} zABZLBJf;>Yz@tPXXF6<*q8g3-?Yp(r?X2+*d<23blK$govc?X&`IxrbdZ&%dY4Too znmR$a$h)%+X^|k0s~|!r4JHbJUn?>zv}m;=*9*m|{?iz;5%lP1w6f^;1%nv$U={f` zr0oF>+N{X~$r$Cr4NI^!LkioePn&+0gE%`+^nvY;K2#I#Un8QXj5|@DP4I2r0;4@% z1D*OOCPZ_aDeMLgd|IFPy%+oBY2NUOxCy5sS~-uM5^g9=X_%tQB=^(vX~twY?k2CE z4SL|~suxr1pgg5ppa(Y7&||piI^KCDeGTrhDoNVs4$-rf<#i9Iq}u;E)sCb|M&q%M z8QbZ_SQgq$TH$=#Ar?fXy!;{N8SdDNlt6^BBPb42c0!^;=ZM@7)x{Inh?E&H)DV30 z?+H{%VYb%9nAnN_Hp8Dqq!J6RP!3d{f#OkhWIW07C~Ko#UU7#BAmzO_rRD?;S*4Yf z5QA3#*@YmV)d(?h!OXTM5$eR){E=VDOnI4P(=4tg^5t}7gO-r_F?5bX5Z+2LtGh^& zzuSTkNk6Ip$@FNC=9pJ60F)q#A%$ng?I zc-rW$A)MIMSQtk#^wJ2|RGu~`9*s9%y8bDj9-Rx=S~zLS{LC{G*JiWcDX~@4{NLNk zzlvohmh^4au3aa~Cr*xyqK`(Qiz5fpG>LmkMGZi&&Bamq^^5WxD0Gl{<1}H4-q)<5 zL&#Tx#RkDcG6AH9)oVC#{8q8XcVtvk8#p!?Hssksh<0f^6g!z|ovy<3YdYtd(ZweV zdQLD0SSlW=%<#R;svHnZ@X<4a`d+sFesbp=v!_(xvBq@U-uI*Pw3_yq^lfrS;?|OW z89;%yk3cU7cNFbX_GqENh}O413#s9#x&Y?> zcvoyH5JOtz9+!ih4fj-2DzW3VuH8ydTHntf*7hjILKR6w#kYt8MT=ay^+Z7Dg@X4S z7TGd4CJl&&N@1+hT>AGs_ly531Hv*Dq2w~v$IvMpl(_d(S5U3=xa%ZMT?EEY zj1yd}XyKUzU@40z5=sQj8?3^wXB2l#;FB{O1@rWa!U~)`3`i(80+k4@eUo!y>q^YU zaQx981xc-nCwrGfU8%E}hP~QT^}~rHRF5G*vs2l_V2&X-lqVSdndbhvq%K`23{29W z1s;r+o}eS=EV47W4LZs;S>_fldrwClgBkr*C%W(#%+oHq9Seag2pS)vgza1Haa_FV z`+3w;@r`ID9-8hmxy?(^6}T-7;Y&ktc5 z=YHoH%x3y#mp&XPM#P#Il#k;WUhKY)d5Gr=M=C~586*2Hu?MdmKk2>SkfIAZ_<%hP zjuTRs^nNQ`IDv0w2_|ZTeIFHzWBBMY+b2rBtSLB3VYaXBw-Rw|$}NwA84a(Q(l1*b zuFmybm2zk)8S8TkTcQ}FxVazvnw-2sNgr-JZuPI5XiC4w2IscDke7Bt>!4p$t8Iil zvu*iONJ%&;HYP@`4pD;O<#xLRjm72BNOOs4h>2y58R$LvD8iL_7yYjW0e$r}n}_p9 zGvoWu((T`?G6;roL{NKtFEgUqg^c~+L!H;3a5-d(el1;_VNF>Zw# zSu^CD{$Ica*REYS1Ktf0HUg5n*c+XspE>euHB?AlVyCBuX%0G&#kN&^f6b;3+C>&)U~NV|$) zgrourzwC^?6bm8oxLZODr_}gyU)`d9geR~2CDrWRNdaP{Ig>u`{fOn zZ)FRe!V8AW^yPkSPOCwq;tls$P8~(X>iV1w6wl2fYgUdX22bvsO?@HO_c(Msk{0v< zV@yh4TOw>*hvx4&4ZN&{BvAd>$IpB{-*Y@@bt8v<+y8^EnV*M>cvbLGb(= z#23Q1`IewioH{~Ovh@S@CgmupI1g90pf5`*F1<~*=W}EAhk9FHbcc}s4XN0#&k8eH z_zy%9Ct~YOHD4L*e&#bE8e9{ZL}1|uxEh?kj<=JbhO+>?;IY zZE}!&#CbtvpgRi|&YC|8MVq`CfXWeTqDnl=jJT@GVit7%R|QhmOEZ32Vg9>5D(amj z4l(@e3UU_8vN7SpMAg@k$|1hnr`0{a`(W>->F?w22Jb|7-k#>=WsgVz3L#i&5^?qU zgZmkr401cU?JSR0s6kJO|K^&MmZGSHKJ$AFkvdRW0{kMlUapk8R6SA@lYSCd`$aVk zamqZ-?BFkjPPqb2tgM#PS_$c_Ek{zu&_3{=AT?|XLmy-1+*j9!^%4nRNjJB6roGyo zi+SjwH{FOvj?V;nm(h^~IS|9fo0lOs2c6aD2@4kk)%X{1RLRzar_(+OLM?&O7$3hx zBk5Nm*oxnEREKaDV`vMf5zh?{g9>O-#`garJrIsncCfnXhWz|o>~2fUlic6QT1h7S zjN#Y!>IQ3_4-2l%U7K5{nWiaGr|;n=kJcW$5{zwV>aas^$fb6E&|X6(J~tpRWeRda8p6x3z*lu_I>e`k z!ZPS4mo3BJ`h&8NBM8-6tYr$*1XAbR`jN7CZFnFf?Jpg@NcZtj$o{qp$#*-$Mh=~| z1H^ph%1X@7bF@mxAXXAht~*=xW1kAU!Q6IAjAPDK&(L;2v5;CwUY8tnym64=yda~4 z%+&}`oihVXfGAti57!!rYnF+!ew^7aIsACj55ruOaQ8$Kk^O0SZ&8Yo4ADQM)Z2M%=`m@q-z z>}It8eipOBF%w)-`MbfHtqIxPODJhZ`|-yTsXl9)ZWT{r_|wUO#R5aGH`u)R6d8u~ z>mGv9K|o!PuT{mXC<_NZY(j6F|8`Wo4v1PYVttX5ZsE!{9ukV1kL`&h-`B7O>_rM% zqX%pU*qn&@G*Ra~Y;?vvzQ6lWjoYD#3cqXckVlqutxlA~q3s*>h5ACTXNR9YLu^h) zOQ5A9N`lOi`I2ln$y$ttVGqY@}9Cj90iH$4 ziD`O@s^1V2e;cId`8e;O)yBzg_GTws!Bk~50$dRpe%^p6SC?hNQa=*)U}cYaTcN#y zOS%3NTRgFQ?XFru52x|wE@v&eB%>F-Ss6nj;@QOW4gX>(+lph{OH-2fSPh6ShRbRa zC$2>7WOi;D!pxscziK`pQJ-(E zLynf4f1l#ZGb{@Xn9Z(OTg{$e64!5_}RXYSe7DOhX@IW`sO;13yk%K!5?M+tfP@HZVZ?0$< z{g{l-8j$ZCX?`-uHs&yUcF*I|vWn&x(h9W>lc?a`S(v|}Y_EBl2GkjtFQZ~@2}8wVQ1dgieQU7tqT zk+;u{B9>-x7T)F-QvC}rBnoCPk2Y{p%kC@p$<@J*3qqTJf+hsaxb#Maj2HMm$k#%R zxW@ANrIs?QXp$f^yT;9Nv^}+&{_04;`csO9baCr75rlx{WPos%4DbZ{)&dkmE!*Tt ziCHpimrY2V)<)p_;W?kdY(}no(zlrxqbsH2oLCw&B3pUhtxB(wz0V*@+A&+b@x$|v zafL=N&D}(&L}%#SwK0z(qo>eoHS7F%klO>CYA>OY#}&%T-tE;?{Mqr!%Z9jx{pO?# z=w|SX<@Ka7cp<=%(c&o;s}#$zz$f|~Ns9n=VwJ|YOQ zEtuX2Q=%4uP~HDo z86j1+_|MGtFDG7A-e+>IDR}_h3J4NU)FG~a((g>q$eOyGTY1J-3>Th2MS>Ry2pbLt z$UqJRNa>s)QtnUPlo?XVGf`QmOk_EFX4Q_(J(BR}y%}o%ujN$xD$=q9NE%HO-^?GR zoVh|MK^=%w<+R^o_eV97wec-UC^UomjX zQo1m=a;Rq(?eFbZ3daFx;0q4<7BhGl)|?7m{Gh~pXvl#>_Qu#vN9b!l2}MMFwU_20 zEIZKh5IzDR@`dy0ys>vnld-`)Wc_xY?-*?w(gD(IHud zAUgsTM2M{N22TclF=DXcUN|P7_mgz-m-?~iDx;F{nCvf8U8~1nclyb%%S-BETwzm$ zm(p`FY<^-lSw3cXpF~;!EB{++S{i^;PKw3~GkD4|Pw?5ORRM9`Ovv!z4(2 z^Xh%-6nwRnP$QZ<1GAS5thif#HNBu)X37$HJ(_jYcB>JXnMl6YypV#f{ zzniNcIk%>{Cuq_d_!lJdWSOX{PpUobb;p$rWKod86Siss(K(=SX^{|){u+{-{hA%O z0+?Mgm^5xJyi;E*hFEYIvQ^=t2glVmCu*P-s=O~K-6SKA5*euZu6<{FU2X230ALpH zCQGTn*ezn6&W(-5@p>u%&5=)FS5n|DjObd(;Ms}ad64%jDZxKEy(clI`J=B$^PiRI z-y+nP4%F#*0GeV)62Wp@S_rM|1^)VcS^VqKJ^0mI$tAgY%KM8d+zHjYP#j==P7`5d z0(!^RHV(bELb724`rh+1_w8bf<1zbw6LdD%JDnMB>(H$w07|+JWE>OXw``iOOJTIT z@+xm`D#x+T#DDb7os}QK4Td6BJGa{{G;{`^Nwto&{rQ(a2ILt3Zq=0X-^DU(CS-?A zO1Vj-tJBqw*(L0xxFl34MOx?oLCgj8GQiQ$dl}`?B|Vamp@T$5o$7Y>&z&^>=zHAV zE9!Gl)p_8Hxa+pmUzh9&SU;r4ITMq=#~tz$%QGId#^=1`oNd*t|8-7uoXkF@JZX~S zxgl6#E4pIqRQq^}G=R5J8m1W9?7YUpnMM^700%C4-b`{%HBfoA1{kL;>FGyrFBKzxFEsjIfP$_Hbp5KQur_)R-ecMA*k$LJ3AS3l ztgRAtv$&v9QBdM)2!a0{=%D$vyi|qIwn5Jjd^xi8K4z9^kI4M7M=|t4n#jgL(G7)JW>Y3v@U4OE1?^CWXICdO=fbg`Q@Pa9a2l9Taj4mbpYK7EPo!D?UR-KY z+FR%%+`(~ULnw(>Kcu~c54FrzKmq_uewj}nBk&6@_`;7;-JW^}idphJ9l<5=Gf2O%N_yfL)NsVMp1^9@_^r;}hdi>U z(=15t`dTrGM(gpcSjJD($7j-b+ZNP5T&0>?PE|Q76ls{rm>$S5CgUM@bl@W&R7i`G zX@v2lqGC;A1qWXuo88FZq-G%v?yHOTj3A?wnPYAJfXKeA&rgov4ImwGA#3dQ@l7#2U5ODS=mnc9r8$n92H+0(ee+!l=`4t1`S>Q*;Q4)N zAy@rlSe%>Scm3BqHJgWIr4_Gu!>+*2oig@UYd~Nt@d{cPCda%Pf_2rX4L9E?jfox> zK(=FPc4NwK=}q^J)l+>F`j)sxzi|-v8Fq6(*DtEHjQNfwSA+dqhZMF0@)Xu<*pdrW z=*K=g#a{52%S1ZfY-SXS`7utT2HbgSXS7+r4wB=T8W^RwyNs zdQzDzuW$UC*J1z%4i(_H;rd$bGts0(5X#m3HP!I3=z#O|!s^d4{wa+*d{{t7h(4FHpfgoY=0IQ)URi9o6>n6B0EicVA zyG3q}vSDH(`mf1Ne;)_NI{(9Z?G#YuAK-CC!4xWc@-4-~VUo)$Cp zS-dV%ef#)iTO?*DBe|0A)AaOhPj zrH=JsT{OpHjUH486){tEUOOG}kH5Pj>8c{=zuR&$l56v#kT&QvT&u+W{hJaSVPnCk@@O=IOtq(Tm2n;da?F-UO^saY=j zhFiuDAp&whSRi%!b;qJ{MWG@8;m2fDiu8mBWO{1gsw7;|HU6Jhu9Reaa)tu6VCkmXy_(sL+;)B%X`A1WX2 zk0?QILV?#X9HRStKZDJXyGw)rV)R^$YhuB4|Cb}XM$F@+gq^0v71<`8RwYi(UlyWc z%iZu=na`j5Zf4!y-zW64^sqe=YDqsfZ0VPwM-}eVbZ!!Vmz4G*H*<{2 zE4DkPStVTyZA7~UOG26HB-Ot8D{|Y%L%`jxZxt5c#}4F|cQ(U<5#?uoj|cP29Wlm^;Cgs$x5g#ya)MSeo-sL~DT*M(%e}4DFYc)LM@D0- z*FaTA;?q=tJAWxW&Fv=1h%dW>O_To+%DO7e(}CYNnu=LlF51UG$c<&);I?38 zIK@dVd{RVc!+4Qo;^H}hFI&A44Fe=wWRdW+uq4dYYB|wUPm86cn4K%Y?5Hg>vrA*( zPbB;$IiPq-#H@-Y$N67+FCS@f*ZGhO<1JP!)G!wAi(FX11Fyz&e6o&To8lyrg9KwY z?u)xDU?BT%vQOX=Q|Rw4%RC2FLZuBF`3TH4>&uRegDt5;&KZ=^0w|R)+~{EHS9~KG zJ=mEPpXy1}*JQARC`Z@A2zEZj(i2`m?Y}-_KKON~Z45yhb_bT#x7m-_Hr_0lBr@zq z8!5|4IZZ02o<7d_PB3?MyfmOOFP9!D4jC6_Tt*HVwhOzs`tqrSOdSd0{p4BOSBgKsU= zJyB+$8G5m(ozW(>eJ2Rhljx?0}ETXwyosLxvV~q z+=au|!ipv7w@oY(jnnxctc2vm+lTu}g3WM+QNH*!zT|L#vLmB_YC22zar2AO&3ZWc zvUmWWoBKgrcB`dz9PuCKn9cB4>B4T5s5%?S zt{8BL-JnAu?HDllaBeh<^XOG?sRU;_yFOZ!&T=UDFXL0g8H0$fh!l!#b*B*y?WiqT zwb&x%>>8aa*^)pCXfkw6|Zl~2e%F#i~#m47QVAOc!VLQYqLmcFdx%L;CxP0-sADyqd+=N1fqBU5>o zz}vqiV=77nZZXjM#`(f$(I=6ArWD6fv0*tq>y|Hyb3bm9Banla+;tsA&@ zpm#$qopwthm(yUFlbBFX21q6XurzTvX3*}OdoOS$P(T86&xsv2`*wu};X$)TQ^p7; z;BZ?jpnw<=AdJCRrdns0uN5KDtpwB(N5aU;;3D}M^z&#lT$K4h@$JA#U^hS~Usx(J zjMZM)x`HzV0$iRI?Qhq-*0p5ne~c?KUf+HV91IrYre!4H4CM$%CZ|nKuN124f4n>t zCk)8*P`0I1*$Borl<{{N_Y3$8euU|Sdq3>G}N zTX4ugaECyG2iHLd5AN=6!3mxq0S0$>cL*-QA;{n^-<xnl+DMsqMe}d z536T9*LxJbzY*LicrX~!%_WaPHgdO~WIXS-?N@Q)?OKc*ob zrea2A*%gQ(5r2z2$%6RZR#2?EcRW9H@wkcj-cl6SOmq!6(5iiyvM=z5wUtOPkj9F$ zZXo9xTURN#KQ{vRR6eC_McKi$y86+m(fkhZaS^>!*gk%Q!4uy9ac&&C?oSIQDTb%& zfh%4;I-k1jj=RsZI9I2s@rK%sVGFN7_h+dDA2LyOW_eSvx~Cqbfd{AYkynN0uj}%n zouHF|6ZjxCOXV8Y0Q%)*f3?z;5(^(k#P=~gNBb_&<_na#B;XefzN&JUr+|rgEW3_s z@7n>Ek&M->HC{EIIP>&OcS<(rTAsk3lEkaqma5m=(8rNVD=YaN{2_5-B?%M&BOMMy zS=`}%EjrC=rPpB~>OFu?@BmB0HGq?dkdooj?|WuqkT3A z!JPfEvMCW`{KQViFrwY5#b*?8LY~%{zd*NMu!3k{1iX@+Gt-YQ!?{AOLFQ94o|)|s zcXBj=DCF+lYHy1f5n;vt(?g0`b902$pzi)Pb?bN^JpVaVR2h7}xva^|c7hmT%{p0D zWlQLNf<3%-g_;v@t^EbqLu>f9n=wDrD6j;xio4+LO%#7q%;)uwYOD`Y{GYI6qHc+m zpcLV?S9+1T`$W9`C!-#kreWRI5F9V|TvUnR%oc;NFTFARnWwO-4W9nB9>tOK(26+X zpH>lH(r~^pl8w{nV?ltZeuEb9M^19x0Ee9WYbpRLll5Y1J?{uW1PXbz*N>+q@>5Gp z$VblIfADrTGl0nktM8j>VD3zVS0&zL+`#$~vluq8Y*@azzYKE6K*`!>a{Ct?a7qI7 z*Op5-tW9+5Lgq1C%SM|UoKcgw|Aipo=wF7(-qt|eh^vztkcp0l$cw!Qr#(>TaqPKW%e!|!0ajtO>0D?j`sO5;LTN?hQRuBH!iyz;7Zsn zoG2&-gjt*gn@1ZvOA2=)QX<+4hiD-6n<|2KM&I(`7$P%wfiW|-8c2CT2h4E7_v<$5~+U z;)?h#cwO_`7zIp~&Y&SJegbmLu=wP5is-tLzCqkg>~RTW{X9~Z^B{f{2r1aH85I5# z92zmH@xfQsY`Om8O?Vk6Cj1|Kl`n;UHglZRZ)T70qSZ%*IXUaR0@8oQ(PwDi5vQd6 zrr|$f$zyN*Rs|({9aA zYvS#@QtPGB3bsgXI+tiT5BM-Ey#b1I=dc)4{VPVMfSs<-nGq*cWX&T!yG|4Qi*^r9 zfKN#60v#VnrY3^?I@TLk8BVHQdkv4$_X9eeQB+c_VA?Usrbw7jm{tZ<1s>&6;aL+A zact5%Jv@Bg=-)(zxB8~^Bm5=aM-oT7CmY8@*Me5|0-V_B!In%y9c8907 z|L$w~wtyck3!J1Bta@wj!RPc|OM-dutx=9djiN;?3-~lQyG4)qov4zyYZ4zyY$PmE zFp+mAmOeQfW*Zq;MFjZl=yR(W!R)f9y*@FOp_Sq#xVwd zaeWhPWW4c6vEz`|Op${UL-4)F_cXlMq8h|Jq-? z$&pNJv&A0!AsM0WGMA=N4>OJ&tLvz{Uf%*-TsV%+B~Oz7r4c9$C&$ZTvQdMGks@B( zkD;)idIXK+n)iuaJrxl?#~xHm9-5&o!DRQi{D8 zzBsQ$2sYB^q_NW-Ms|DPCssuc&q;r^9&OAk6cW-)r_h>-ewh^86#`vi4bOcEdfh(` zMXje<(vxzvvi_aSIco(EZ}&mgD1zV(k*YZut5N-f$g{A%;?m7cW^CGCX8@c2Dq(&8 z_gl70OKy``CW@gjnL{EuGKrob2dNPbvz?w9$Wk?($E|5jP@$`crS);9c{E=p1m8>q z1^#G8rRt)OtZ}b+s~t)fGikEE$WA(kq>V}+$T|Y`?EEOqDs< zYMPp9)Pk`&`}LUqz0H6p1-sEks{e4or|VdGz}?1}w2z~m%i?!BI&FtuO}h`TLmy(R z$tom?(uwDy*Y3Z53-d`u*}Zl9-7so48dO>zos%;jt<^UOnz5Sep}{J;NE`mBb=w}dK@P(a+#SW&~K^*4Ar&$LcGz8M@H zkiIF0Q5DGf!QCDNPRzX03Zs3O5Vv|0k&7Le-)KH*2-dYwglDgE$=;n-EQ$1eycOP1 zEDM(cZTSwo=+w+G{gt4`d66}XhZ;7g5ozOK z3{P<>pb4XBFw#ee<7A3Z!!PxfbB~gEUgKTaS<1r`BC{TLZ7cJEIJeUUx^l6n#%iMx zh$>JkZhemJi7-8-;_sUG+VgBHw-gm0)zI-`=q_buzRv%}AF?qen(|<(Ky(p0U^osB z6WI;St87V&raj|N6K=kzBXSrOK*mX2yO3JRnv1E2nN+|GvVT@A_s{gu zD=F{Po)~}@cGCW=ga0>uf6Nc3Og0l$GyL7~wkrQN7#uTV)>F3OW-;do zK@)K({ooAiOQzX%%;p2K?h>UDDPT$_U}K2KSqdu%J4dr-0Nkm_P$Q>Rcytcs$P`4p zZ#!@NZiGc&dOwL*jTmTg18r$LMTTW)Q87tn|CoAnn)spP$7HV~1bHD*nJ zW+FId{qerxHd9v28uM=m4S{dk2hhj=f>*&{HLY>BddVoRVM%1hCUY>jUaF<+FD5>Z zi7GrpDg?)O7F-7tQxyG~$)J8${Jy8=#XUMazK6E#Y1;}M)Sd0&4Ca&)N4yzwQ_9sJpDHPavsLeAo!WUfn0Jn2jJ z=xZOCECInv;!u}a8t3|{-8tnO5k?L+tbaP}^!9Ra=K#J#T&N}=>VX44Wd2_VW&SNa zcFse{%6y!Gx-z6nk|x|<9z%6w>?)us&Wx;}-ZDRpDOb*j4A1}0yCm?sodJQGE-fL^ z->R9S;3i&NVg3l)VB;n}W)9XZ@*pxa6Gb4+@tx7sLt>M^G_B-VOKXI?y9(M^&hnSI zb83_dDaXELjMX6J=bbi@$*-q@HhL1&*$>m%0Dw4x=b`u2voIDGmiO&5qRCsG?Ctw| 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
H!_f{8 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 I%C1xX185HK0: + fill unitsquare + scaled w_min_disp + shifted (min_disp_x,min_disp_y) + withpen pencircle scaled pen_scale + withcolor discolor + ; + fi; + + % case + draw unitsquare + xscaled w_desk + yscaled h_desk + shifted (pos_x,pos_y) + withpen pencircle scaled pen_scale + withcolor color + ; + + % case details + for i=0 upto 2: + for j=0 upto 2: + draw (i,j) + scaled dots_scale + shifted (dots_x,dots_y) + withpen pencircle scaled pen_scale_min + withcolor color + ; + endfor; + endfor; + + % floppy + draw (floppy_x,floppy_y)--(floppy_x + floppy_size,floppy_y) + withpen pensquare scaled pen_scale_min + withcolor color + ; +enddef; + +beginfig(1); + u:=80; + um:=25; + + computer(u,0,0,black, white,1); + computer(um,96, 145,(1,215/255,0),black,1); +endfig; +beginfig(2); + computer(8,1,0.5, (1,215/255,0), white, 1); % (102/255, 153/255, 255/255)); + % computer(2.5,1+9.55,0.5+14.5,black, black, 1); +endfig; +beginfig(3); + u:=20; + um:=6.25; + + computer(u,0,0,black, black,0); + computer(um,96/2/2, 145/2/2, black, black,1); +endfig; + +end diff --git a/resources/logo/png/logo-1.png b/resources/logo/png/logo-1.png new file mode 100644 index 0000000000000000000000000000000000000000..2b88a6a6aab8ba7d69ac70aa553ed7b295502e82 GIT binary patch literal 5830 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 Pz@LGRiFSpSedK=uPADZu literal 0 HcmV?d00001 diff --git a/resources/logo/png/logo-2.png b/resources/logo/png/logo-2.png new file mode 100644 index 0000000000000000000000000000000000000000..12fb71da26df2df7a24855d7c6abd9b78e86994d GIT binary patch literal 505 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX1|+Qw)-3{3oCO|{#S9GGLLkg|>2BR0prA;J zYeY#%W=T#eLqT4;eolURzOIoTkh$;Loe4mBZIFC$ep*R+Vo@rCdum>4QDRAIib7JQ zf^TX`VnKd!i9%UwQE_H|o`R8{fx%px3yBO2j3J&bjv*f2$q5G-ndV3`Nfk**X&hve z;$hoy=D22Eg5crC|JNn|1vfeNshv*RWa5;|WI0FY?+Gd4h6fB24=`{zlm#Ds^xxrw zFo&HWLw&;o4uOEHNfVwPX-IZ3$TIZQl(sAs5I$mHy4cY-$YAmEQx_K;6K4wXjgfC? zxbYy4hb2VY!NX5s%CxH+_W1bC{ga@7n0Zsya^7GGvw$G+<}YGL3`HggM{T*fSmEq~ z2MNa>IQZ)vIIY02Zi6OoP|(-r$MfDyW11<*xSjvzBi6S(+zyU>-bYim3UOL+tUf9j z$0PV@63?f&GM+dEo<43R$2cA5dzbRsmhRZF!=Ty1>tNHHzopr0I+Mh?*IS* literal 0 HcmV?d00001 diff --git a/resources/logo/png/logo-3.png b/resources/logo/png/logo-3.png new file mode 100644 index 0000000000000000000000000000000000000000..681aec0ea261dd09b2e47d35a934f936a98b3abf GIT binary patch literal 926 zcmV;P17ZA$P)V>IGA=MMojlNC0008{Nkl(CP!d~4hqA_+ zSi7+uN$b_jPDb%smY%;>tJs;%`jrbh{e|o|b6ZjW=KY4+@9a(HfSNb(zTZ&$ot?Xq zn*Ce%8*0C^n;rS2rqG$3EK5*H@7RI+?VyAc!9h7FApxPAE6PC$2?*U>QBwj{(O?%! z6Y|-*nNZX*Sv~e_nqmeN6eTUoko8Ob;b#ieQ)@tNrG3$H{7Nx-P;U`XKOv4es0gTU z2lc<|#T4bBf>In*WO+i+c0~!+a0exT#5s;DN&ri$DE6CtdQgQ}1$7-VaGx}&cLJ~$ z+9vo3#JY7cv4z2NHmF2nP@JX|394&q9eWIWz^+mps4*YAcd4v6P>4gAV*LCcpF_M0 zfObuS!k{k6Zpb9>0-TZG)gC(!^UW+Mz_|_T!gP$4YjRlau{-Oaw2F#>G^?nJMvm!( z&)A9;gM{NIK^^ljL2{0%U=9UgKx0^!@`_6jB-3aN9|t9*>YyBykbuz56;(1Q$x@!u z2RT==l5*hMYbOP@p%G9;c3Nne#(pQmt>0*6MYU!9wHY5@O?!E3b6<$@KodXoH$1D zR7CxhF)CY72-+wNY7^>E6F_qP#KIc&awLhdS19HV^d zwN{UHi?%16jXbeyQ;hh7fXy+8(*urMoE}Vm3nQG)Cf!sq$|M2dpgKVfk?C4&qmJDc z2R8JWYEa0khi=$fdsxuw*O;+20X4T>2FM}je;?*O7@Id}(*OVf07*qoM6N<$f`=QE AKL7v# literal 0 HcmV?d00001 diff --git a/resources/logo/svg/logo-1.svg b/resources/logo/svg/logo-1.svg new file mode 100644 index 000000000..33db37ef3 --- /dev/null +++ b/resources/logo/svg/logo-1.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/logo/svg/logo-2.svg b/resources/logo/svg/logo-2.svg new file mode 100644 index 000000000..ff63163cc --- /dev/null +++ b/resources/logo/svg/logo-2.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + diff --git a/resources/lsi-adm-3a/adm-3a.ttf b/resources/lsi-adm-3a/adm-3a.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e9c7756a19b856d0e7a13fd9a19d7c2ac59cb0ef GIT binary patch literal 29340 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 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/adm3a.sfd b/resources/lsi-adm-3a/adm3a.sfd new file mode 100644 index 000000000..f522dd783 --- /dev/null +++ b/resources/lsi-adm-3a/adm3a.sfd @@ -0,0 +1,7111 @@ +SplineFontDB: 3.2 +FontName: ADM-3A +FullName: ADM-3A Regular +FamilyName: ADM-3A +Weight: Regular +Copyright: Copyright (c) 2022, Peter Jakubco +UComments: "2022-9-17: Created with FontForge (http://fontforge.org)" +Version: 1.0 +ItalicAngle: 0 +UnderlinePosition: 313 +UnderlineWidth: 208 +Ascent: 1792 +Descent: 0 +InvalidEm: 0 +LayerCount: 2 +Layer: 0 1 "Back" 1 +Layer: 1 1 "Fore" 0 +XUID: [1021 261 208283644 15436461] +StyleMap: 0x0040 +FSType: 0 +OS2Version: 0 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +CreationTime: 1663397476 +ModificationTime: 1666303265 +PfmFamily: 49 +TTFWeight: 400 +TTFWidth: 5 +LineGap: 377 +VLineGap: 0 +OS2TypoAscent: 0 +OS2TypoAOffset: 1 +OS2TypoDescent: 0 +OS2TypoDOffset: 1 +OS2TypoLinegap: 377 +OS2WinAscent: 0 +OS2WinAOffset: 1 +OS2WinDescent: 0 +OS2WinDOffset: 1 +HheadAscent: 0 +HheadAOffset: 1 +HheadDescent: 0 +HheadDOffset: 1 +OS2Vendor: 'PfEd' +MarkAttachClasses: 1 +DEI: 91125 +LangName: 1033 "" "" "" "" "" "" "" "" "" "" "" "" "" "This Font Software is licensed under the SIL Open Font License, Version 1.1.+AAoA-This license is copied below, and is also available with a FAQ at:+AAoA-http://scripts.sil.org/OFL+AAoACgAK------------------------------------------------------------+AAoA-SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007+AAoA------------------------------------------------------------+AAoACgAA-PREAMBLE+AAoA-The goals of the Open Font License (OFL) are to stimulate worldwide+AAoA-development of collaborative font projects, to support the font creation+AAoA-efforts of academic and linguistic communities, and to provide a free and+AAoA-open framework in which fonts may be shared and improved in partnership+AAoA-with others.+AAoACgAA-The OFL allows the licensed fonts to be used, studied, modified and+AAoA-redistributed freely as long as they are not sold by themselves. The+AAoA-fonts, including any derivative works, can be bundled, embedded, +AAoA-redistributed and/or sold with any software provided that any reserved+AAoA-names are not used by derivative works. The fonts and derivatives,+AAoA-however, cannot be released under any other type of license. The+AAoA-requirement for fonts to remain under this license does not apply+AAoA-to any document created using the fonts or their derivatives.+AAoACgAA-DEFINITIONS+AAoAIgAA-Font Software+ACIA refers to the set of files released by the Copyright+AAoA-Holder(s) under this license and clearly marked as such. This may+AAoA-include source files, build scripts and documentation.+AAoACgAi-Reserved Font Name+ACIA refers to any names specified as such after the+AAoA-copyright statement(s).+AAoACgAi-Original Version+ACIA refers to the collection of Font Software components as+AAoA-distributed by the Copyright Holder(s).+AAoACgAi-Modified Version+ACIA refers to any derivative made by adding to, deleting,+AAoA-or substituting -- in part or in whole -- any of the components of the+AAoA-Original Version, by changing formats or by porting the Font Software to a+AAoA-new environment.+AAoACgAi-Author+ACIA refers to any designer, engineer, programmer, technical+AAoA-writer or other person who contributed to the Font Software.+AAoACgAA-PERMISSION & CONDITIONS+AAoA-Permission is hereby granted, free of charge, to any person obtaining+AAoA-a copy of the Font Software, to use, study, copy, merge, embed, modify,+AAoA-redistribute, and sell modified and unmodified copies of the Font+AAoA-Software, subject to the following conditions:+AAoACgAA-1) Neither the Font Software nor any of its individual components,+AAoA-in Original or Modified Versions, may be sold by itself.+AAoACgAA-2) Original or Modified Versions of the Font Software may be bundled,+AAoA-redistributed and/or sold with any software, provided that each copy+AAoA-contains the above copyright notice and this license. These can be+AAoA-included either as stand-alone text files, human-readable headers or+AAoA-in the appropriate machine-readable metadata fields within text or+AAoA-binary files as long as those fields can be easily viewed by the user.+AAoACgAA-3) No Modified Version of the Font Software may use the Reserved Font+AAoA-Name(s) unless explicit written permission is granted by the corresponding+AAoA-Copyright Holder. This restriction only applies to the primary font name as+AAoA-presented to the users.+AAoACgAA-4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font+AAoA-Software shall not be used to promote, endorse or advertise any+AAoA-Modified Version, except to acknowledge the contribution(s) of the+AAoA-Copyright Holder(s) and the Author(s) or with their explicit written+AAoA-permission.+AAoACgAA-5) The Font Software, modified or unmodified, in part or in whole,+AAoA-must be distributed entirely under this license, and must not be+AAoA-distributed under any other license. The requirement for fonts to+AAoA-remain under this license does not apply to any document created+AAoA-using the Font Software.+AAoACgAA-TERMINATION+AAoA-This license becomes null and void if any of the above conditions are+AAoA-not met.+AAoACgAA-DISCLAIMER+AAoA-THE FONT SOFTWARE IS PROVIDED +ACIA-AS IS+ACIA, WITHOUT WARRANTY OF ANY KIND,+AAoA-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF+AAoA-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT+AAoA-OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE+AAoA-COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+AAoA-INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL+AAoA-DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING+AAoA-FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM+AAoA-OTHER DEALINGS IN THE FONT SOFTWARE." "http://scripts.sil.org/OFL" +GaspTable: 2 8 2 65535 3 0 +DesignSize: 120 +Encoding: Custom +UnicodeInterp: none +NameList: AGL For New Fonts +DisplaySize: -48 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 0 38 14 +BeginPrivate: 0 +EndPrivate +Grid +197.862731934 2688 m 0 + 197.862731934 -896 l 1024 +180.862731934 2688 m 0 + 180.862731934 -896 l 1024 +57.9877128601 2688 m 0 + 57.9877128601 -896 l 1024 +74.9877166748 2688 m 0 + 74.9877166748 -896 l 1024 +-1792 384 m 0 + 3584 384 l 1024 +1280.02092014 2688 m 0 + 1280.02092014 -896 l 1024 +-1792 127 m 0 + 3584 127 l 1024 +-1792 1337 m 0 + 3584 1337 l 1024 +-1792 1355 m 0 + 3584 1355 l 1024 +-1792 711 m 0 + 3584 711 l 1024 +-1792 693 m 0 + 3584 693 l 1024 +-1792 455 m 0 + 3584 455 l 1024 +-1792 437 m 0 + 3584 437 l 1024 +455 2688 m 0 + 455 -896 l 1024 +437 2688 m 0 + 437 -896 l 1024 +710.954752604 2688 m 0 + 710.954752604 -896 l 1024 +692.954752604 2688 m 0 + 692.954752604 -896 l 1024 +-1792 825 m 0 + 3584 825 l 1024 +-1792 843 m 0 + 3584 843 l 1024 +-1792 1479 m 0 + 3584 1479 l 1024 +-1792 1461 m 0 + 3584 1461 l 1024 +-1792 1223 m 0 + 3584 1223 l 1024 +-1792 1205 m 0 + 3584 1205 l 1024 +1080.97729492 2688 m 0 + 1080.97729492 -896 l 1024 +1098.97729492 2688 m 0 + 1098.97729492 -896 l 1024 +-1792 57 m 0 + 3584 57 l 1024 +-1792 199 m 0 + 3584 199 l 1024 +-1792 181 m 0 + 3584 181 l 1024 +-1792 75 m 0 + 3584 75 l 1024 +312.877197266 2688 m 0 + 312.877197266 -896 l 1024 +330.877197266 2688 m 0 + 330.877197266 -896 l 1024 +568.87713623 2688 m 0 + 568.87713623 -896 l 1024 +586.87713623 2688 m 0 + 586.87713623 -896 l 1024 +-1792 1717 m 0 + 3584 1717 l 1024 +-1792 1735 m 0 + 3584 1735 l 1024 +-1792 1593 m 0 + 3584 1593 l 1024 +-1792 1611 m 0 + 3584 1611 l 1024 +-1792 1081 m 0 + 3584 1081 l 1024 +-1792 1099 m 0 + 3584 1099 l 1024 +-1792 569 m 0 + 3584 569 l 1024 +-1792 587 m 0 + 3584 587 l 1024 +-1792 313 m 0 + 3584 313 l 1024 +-1792 331 m 0 + 3584 331 l 1024 +-1792 967 m 0 + 3584 967 l 1024 +-1792 949 m 0 + 3584 949 l 1024 +966.882486979 2688 m 0 + 966.882486979 -896 l 1024 +948.882486979 2688 m 0 + 948.882486979 -896 l 1024 +824.924438477 2688 m 0 + 824.924438477 -896 l 1024 +842.924438477 2688 m 0 + 842.924438477 -896 l 1024 +1222.9720459 2688 m 0 + 1222.9720459 -896 l 1024 +1204.9720459 2688 m 0 + 1204.9720459 -896 l 1024 +-1792 255.999938965 m 0 + 3584 255.999938965 l 1024 +-1792 512.000854492 m 0 + 3584 512.000854492 l 1024 +-1792 768 m 0 + 3584 768 l 1024 +-1792 1023.99975586 m 0 + 3584 1023.99975586 l 1024 +-1792 1279.99938965 m 0 + 3584 1279.99938965 l 1024 +-1792 1536.00085449 m 0 + 3584 1536.00085449 l 1024 +255.999450684 2688 m 0 + 255.999450684 -896 l 1024 +511.999267578 2688 m 0 + 511.999267578 -896 l 1024 +768 2688 m 0 + 768 -896 l 1024 +1024 2688 m 0 + 1024 -896 l 1024 +EndSplineSet +TeXData: 1 12582912 0 -256901 920125 613417 -256901 -50332 613417 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144 +BeginChars: 257 256 + +StartChar: SOH +Encoding: 1 1 0 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$:C.@.+:*&9s1_f6R)B%2 +,.L"Z8]6-*%R@6<,p:#HQA`0k:2&K7PTW<+"WDVU3l`mup*Y)J(Pf@7#9eh@AH2]1!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +512 1280 m 25,0,-1 + 1024 1280 l 25,1,2 + 1024 1408 1024 1408 1024 1461 c 0,3,4 + 1024 1536 1024 1536 949 1536 c 24,5,-1 + 587 1536 l 0,6,7 + 512 1536 512 1536 512 1461 c 24,8,9 + 512 1461 512 1461 512 1280 c 25,0,-1 +949 1792 m 0,10,11 + 1280 1792 1280 1792 1280 1461 c 24,12,13 + 1280 1461 1280 1461 1280 512 c 25,14,-1 + 1024 512 l 24,15,-1 + 1024 1024 l 25,16,-1 + 512 1024 l 25,17,-1 + 512 512 l 25,18,-1 + 256 512 l 25,19,20 + 256 1152 256 1152 256 1461 c 0,21,22 + 256 1792 256 1792 587 1792 c 24,23,24 + 587 1792 587 1792 949 1792 c 0,10,11 +0 256 m 25,25,-1 + 1280 256 l 25,26,-1 + 1280 0 l 25,27,-1 + 0 0 l 25,28,-1 + 0 256 l 25,25,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: STX +Encoding: 2 2 1 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CJNffG9V\638 +I#?hhE%++NJ5$W1!d$Ar-pX+%R0ZlE9bO6%!;2fj%l9/)_#OH8!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +437 1792 m 9,0,-1 + 1280 949 l 25,1,-1 + 1280 843 l 25,2,-1 + 437 0 l 24,3,-1 + 256 0 l 25,4,-1 + 256 1792 l 25,5,6 + 256 1792 256 1792 437 1792 c 9,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: ETX +Encoding: 3 3 2 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 108 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8D_*$Z[Q1)J/h +/&3J<;?9gK9+n<+T-RM>!B3?H^o%J+86h#P4d$6bQD(fZz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +1024 1792 m 25,0,-1 + 1024 0 l 24,1,-1 + 843 0 l 24,2,-1 + 0 843 l 25,3,-1 + 0 949 l 25,4,-1 + 843 1792 l 24,5,6 + 843 1792 843 1792 1024 1792 c 25,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: EOT +Encoding: 4 4 3 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG9Xor#n +'2/TU!Q)p86#poJ0SS^I5m:XTJ98Vd7X"r:!P0DZ2'D'lGS=3^!8HZQ#82Hl\GuU0!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +512 1536 m 24,0,-1 + 512 768 l 24,1,-1 + 949 768 l 0,2,3 + 1024 768 1024 768 1024 843 c 24,4,5 + 1024 1190 1024 1190 1024 1461 c 0,6,7 + 1024 1536 1024 1536 949 1536 c 24,8,9 + 949 1536 949 1536 512 1536 c 24,0,-1 +949 1792 m 0,10,11 + 1280 1792 1280 1792 1280 1461 c 24,12,13 + 1280 986 1280 986 1280 843 c 0,14,15 + 1280 512 1280 512 949 512 c 24,16,-1 + 256 512 l 25,17,-1 + 256 1792 l 25,18,19 + 256 1792 256 1792 949 1792 c 0,10,11 +0 256 m 25,20,-1 + 1280 256 l 25,21,-1 + 1280 0 l 25,22,-1 + 0 0 l 25,23,-1 + 0 256 l 25,20,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: ENQ +Encoding: 5 5 4 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG971$7@ +YQBn;Z66Gf-5Ztu$G&eO3J&Tn'd2g3[LTA==TE%[N!;9a_je^c!"R$c%];No&HDe2!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +0 256 m 29,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 29,0,-1 +256 512 m 25,4,-1 + 256 1792 l 25,5,-1 + 1280 1792 l 25,6,-1 + 1280 1536 l 25,7,-1 + 512 1536 l 25,8,-1 + 512 1280 l 25,9,-1 + 1024 1280 l 25,10,-1 + 1024 1024 l 25,11,-1 + 512 1024 l 25,12,-1 + 512 768 l 25,13,-1 + 1280 768 l 25,14,-1 + 1280 512 l 25,15,-1 + 256 512 l 25,4,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: ACK +Encoding: 6 6 5 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8+BNffG971$7@ +YQBn;Z66Gf-5Ztu$G&eO3TTFF!JmI,gB^Dg^9E8F9Neb@sAYi0`YMc'G#dIl9YIN!!#SZ:.26O +@"J@Y +EndImage2 +Fore +SplineSet +768 1461 m 0,0,1 + 768 1536 768 1536 693 1536 c 24,2,3 + 640 1536 640 1536 587 1536 c 0,4,5 + 512 1536 512 1536 512 1461 c 24,6,7 + 512 1114 512 1114 512 843 c 0,8,9 + 512 768 512 768 587 768 c 24,10,11 + 587 768 587 768 693 768 c 0,12,13 + 767 768 767 768 768 843 c 24,14,15 + 768 843 768 843 768 1461 c 0,0,1 +693 1792 m 0,16,17 + 1024 1792 1024 1792 1024 1461 c 24,18,-1 + 1024 1099 l 0,19,20 + 1024 1024 1024 1024 1099 1024 c 24,21,-1 + 1223 1024 l 0,22,23 + 1280 960 1280 960 1280 896 c 128,-1,24 + 1280 832 1280 832 1223 768 c 8,25,-1 + 843 768 l 0,26,27 + 768 768 768 768 768 693 c 24,28,-1 + 768 569 l 0,29,30 + 704 512 704 512 639 512 c 0,31,32 + 596 512 596 512 512 569 c 1,33,-1 + 512 693 l 0,34,35 + 512 768 512 768 437 768 c 24,36,-1 + 57 768 l 0,37,38 + 0 832 0 832 0 896 c 128,-1,39 + 0 960 0 960 57 1024 c 8,40,-1 + 181 1024 l 0,41,42 + 256 1024 256 1024 256 1099 c 24,43,-1 + 256 1461 l 0,44,45 + 256 1792 256 1792 587 1792 c 24,46,47 + 587 1792 587 1792 693 1792 c 0,16,17 +0 256 m 25,48,-1 + 1280 256 l 25,49,-1 + 1280 0 l 25,50,-1 + 0 0 l 25,51,-1 + 0 256 l 25,48,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: BS +Encoding: 8 8 7 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +)i_Z=3>,I+h9B=X@"L'NaU&Ap2dhgP.0KVu`tSdDpboV^!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +768 1792 m 25,0,-1 + 768 693 l 24,1,-1 + 1099 1024 l 24,2,-1 + 1280 1024 l 25,3,-1 + 1280 843 l 25,4,-1 + 693 256 l 25,5,-1 + 587 256 l 24,6,-1 + 0 843 l 25,7,-1 + 0 1024 l 25,8,-1 + 181 1024 l 24,9,-1 + 512 693 l 24,10,-1 + 512 1792 l 25,11,-1 + 768 1792 l 25,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: VT +Encoding: 11 11 10 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +BF +EndImage2 +Fore +SplineSet +693 1536 m 25,0,-1 + 1280 949 l 25,1,-1 + 1280 768 l 24,2,-1 + 1099 768 l 24,3,-1 + 768 1099 l 25,4,-1 + 768 0 l 25,5,-1 + 512 0 l 25,6,-1 + 512 1099 l 25,7,-1 + 181 768 l 24,8,-1 + 0 768 l 24,9,-1 + 0 949 l 25,10,-1 + 587 1536 l 24,11,12 + 587 1536 587 1536 693 1536 c 25,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: FF +Encoding: 12 12 11 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +dNM)#3z8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +843 1536 m 9,0,-1 + 256 949 l 25,1,-1 + 256 843 l 25,2,-1 + 843 256 l 24,3,-1 + 1024 256 l 25,4,-1 + 1024 437 l 24,5,-1 + 587 843 l 25,6,-1 + 587 949 l 25,7,-1 + 1024 1355 l 25,8,-1 + 1024 1536 l 17,9,10 + 1024 1536 1024 1536 843 1536 c 9,0,-1 +0 1792 m 25,11,-1 + 1280 1792 l 25,12,-1 + 1280 0 l 25,13,-1 + 0 0 l 25,14,-1 + 0 1792 l 25,11,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: SO +Encoding: 14 14 13 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 124 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$NmS16+:&(=s8UEqUl0oQ +LKs2CC@3!7"eHuMkm?#7THE5sf`KBbhuqL+047'Q#W'0mZn#,22gY)t;6V5H/(OK:z8OZBB +Y!QNJ +EndImage2 +Fore +SplineSet +639 715 m 1,0,1 + 639 715 639 715 181 256 c 1,2,3 + 181 256 181 256 0 256 c 25,4,5 + 0 256 0 256 0 437 c 9,6,7 + 0 437 0 437 587 1024 c 24,8,9 + 587 1024 587 1024 693 1024 c 25,10,11 + 693 1024 693 1024 1280 437 c 1,12,13 + 1280 437 1280 437 1280 256 c 25,14,15 + 1280 256 1280 256 1099 256 c 1,16,-1 + 639 715 l 1,0,1 +639 1483 m 1,17,18 + 639 1483 639 1483 181 1024 c 1,19,20 + 181 1024 181 1024 0 1024 c 25,21,22 + 0 1024 0 1024 0 1205 c 9,23,24 + 0 1205 0 1205 587 1792 c 24,25,26 + 587 1792 587 1792 693 1792 c 25,27,28 + 693 1792 693 1792 1280 1205 c 1,29,30 + 1280 1205 1280 1205 1280 1024 c 25,31,32 + 1280 1024 1280 1024 1099 1024 c 1,33,-1 + 639 1483 l 1,17,18 +EndSplineSet +Validated: 1 +EndChar + +StartChar: SI +Encoding: 15 15 14 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8C%,9r(&3hH^h +!)*qlUDq8WdLK3//d[\n>60q@R0JfW!@h1P0aQbK(`SkI!(.8@$q!`Nd/X.H!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +639 1333 m 129,-1,1 + 639 1333 639 1333 1099 1792 c 1,2,-1 + 1280 1792 l 25,3,4 + 1280 1611 1280 1611 1280 1611 c 1,5,6 + 693 1024 693 1024 693 1024 c 25,7,8 + 587 1024 587 1024 587 1024 c 24,9,10 + 0 1611 0 1611 0 1611 c 17,11,12 + 0 1792 0 1792 0 1792 c 25,13,14 + 181 1792 181 1792 181 1792 c 1,15,0 + 639 1333 639 1333 639 1333 c 129,-1,1 +639 565 m 129,-1,17 + 639 565 639 565 1099 1024 c 1,18,-1 + 1280 1024 l 25,19,20 + 1280 843 1280 843 1280 843 c 1,21,22 + 693 256 693 256 693 256 c 25,23,24 + 587 256 587 256 587 256 c 24,25,26 + 0 843 0 843 0 843 c 17,27,28 + 0 1024 0 1024 0 1024 c 25,29,30 + 181 1024 181 1024 181 1024 c 1,31,16 + 639 565 639 565 639 565 c 129,-1,17 +EndSplineSet +Validated: 1 +EndChar + +StartChar: DLE +Encoding: 16 16 15 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 125 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$NmS16+:&'Ro`)[29fN`Y +p*+D;;#>!T[%'][V"7?e"L(4V;hm6G&)\0@P5D5ed9GVPDAkq5,R^q"*(*=ArjbLg]`8$4!(fUS +7'8jaJcGcN +EndImage2 +Fore +SplineSet +437 768 m 1,0,1 + 437 768 437 768 949 768 c 0,2,3 + 1024 768 1024 768 1024 843 c 0,4,5 + 1024 843 1024 843 1024 1355 c 0,6,7 + 1024 1355 1024 1355 437 768 c 1,0,1 +256 949 m 129,-1,9 + 256 949 256 949 843 1536 c 1,10,11 + 843 1536 843 1536 330 1536 c 0,12,13 + 256 1536 256 1536 256 1461 c 0,14,8 + 256 949 256 949 256 949 c 129,-1,9 +0 256 m 25,15,-1 + 1280 255 l 25,16,-1 + 1280 0 l 25,17,-1 + 0 0 l 25,18,-1 + 0 256 l 25,15,-1 +949 1792 m 0,19,20 + 1280 1792 1280 1792 1280 1461 c 24,21,22 + 1280 1461 1280 1461 1280 843 c 0,23,24 + 1280 512 1280 512 949 512 c 24,25,-1 + 331 512 l 0,26,27 + 0 512 0 512 0 843 c 24,28,29 + 0 843 0 843 0 1461 c 0,30,31 + 0 1792 0 1792 331 1792 c 24,32,33 + 331 1792 331 1792 949 1792 c 0,19,20 +EndSplineSet +Validated: 1 +EndChar + +StartChar: DC1 +Encoding: 17 17 16 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HN: +$?/Rg<.YkCZNY4MMRc7t'J$Cj`<&qrcO,c_0t`@E!a +.f^Fg_B=Qr!3?/G#a3,<)r(d:Os#`4-=F03"f)KlDNGjZ<>aR\ec5]\B,;(H"(9UY!!!!j78?7R +6=>BF +EndImage2 +Fore +SplineSet +0 256 m 1,0,1 + 0 256 0 256 1280 256 c 1,2,3 + 1280 256 1280 256 1280 0 c 1,4,5 + 1280 0 1280 0 0 0 c 1,6,7 + 0 0 0 0 0 256 c 1,0,1 +711 1792 m 0,8,9 + 1024 1792 1024 1792 1024 1461 c 0,10,11 + 1024 1461 1024 1461 1024 1355 c 1,12,-1 + 512 843 l 0,13,14 + 512 768 512 768 587 768 c 0,15,-1 + 949 768 l 0,16,17 + 1024 768 1024 768 1024 640 c 0,18,19 + 1024 513 1024 513 949 512 c 0,20,21 + 949 512 949 512 256 512 c 0,22,23 + 256 512 256 512 258 948 c 0,24,-1 + 769 1460 l 0,25,26 + 768 1536 768 1536 711 1536 c 0,27,-1 + 256 1536 l 0,28,29 + 256 1536 256 1536 256 1792 c 0,30,31 + 256 1792 256 1792 711 1792 c 0,8,9 +EndSplineSet +Validated: 1 +EndChar + +StartChar: DC3 +Encoding: 19 19 18 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9N3T>a +.f^Fg_B=QrJ-@3K9`h1'`<;PN16#`E2YVe<@$?,/!cf$12j#rt!,QWn$?T36%fcS0!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +0 256 m 1,0,1 + 0 256 0 256 1280 256 c 0,2,3 + 1280 256 1280 256 1280 0 c 0,4,5 + 1280 0 1280 0 0 0 c 0,6,7 + 0 0 0 0 0 256 c 1,0,1 +711 1792 m 256,8,9 + 1024 1792 1024 1792 1024 1465 c 0,10,11 + 1024 1465 1024 1465 1024 843 c 0,12,13 + 1024 512 1024 512 693 512 c 1,14,15 + 693 512 693 512 256 512 c 0,16,17 + 256 512 256 512 256 768 c 0,18,-1 + 693 768 l 0,19,20 + 768 768 768 768 768 843 c 1,21,-1 + 768 949 l 0,22,23 + 768 1024 768 1024 693 1024 c 24,24,-1 + 256 1024 l 0,25,26 + 256 1024 256 1024 256 1280 c 0,27,-1 + 693 1280 l 0,28,29 + 768 1280 768 1280 768 1355 c 24,30,31 + 768 1410 768 1410 768 1465 c 0,32,33 + 768 1536 768 1536 693 1536 c 0,34,-1 + 256 1536 l 0,35,36 + 256 1536 256 1536 256 1792 c 257,37,38 + 256 1792 256 1792 711 1792 c 256,8,9 +EndSplineSet +Validated: 1 +EndChar + +StartChar: DC4 +Encoding: 20 20 19 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 122 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8D_*$Z[Q1)J/h +/&3J<;?9euP/LoFL'd&jJJE]W_b>U.0ZUt'!"#;kK#Bq"`pb=\63,n&(C(FW?:"Vl!!#SZ:.26O +@"J@Y +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +768 1355 m 0,4,-1 + 437 1024 l 0,5,-1 + 768 1024 l 0,6,7 + 768 1024 768 1024 768 1355 c 0,4,-1 +1024 1792 m 0,8,-1 + 1024 1024 l 0,9,-1 + 1223 1024 l 1,10,11 + 1280 1024 1280 1024 1280 896 c 128,-1,12 + 1280 768 1280 768 1223 768 c 1,13,-1 + 1024 768 l 0,14,-1 + 1024 512 l 0,15,16 + 1024 512 1024 512 768 512 c 0,17,-1 + 768 768 l 0,18,-1 + 256 768 l 0,19,20 + 256 768 256 768 256 1205 c 0,21,22 + 256 1205 256 1205 843 1792 c 0,23,24 + 843 1792 843 1792 1024 1792 c 0,8,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: NAK +Encoding: 21 21 20 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8CJNffG9Xot.% +&d0_8b@4mVY(-[d.`e/7]@#FC,^>Ae.*+!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +1280 1792 m 25,4,5 + 1280 1792 1280 1792 1280 843 c 0,6,7 + 1280 512 1280 512 949 512 c 16,8,9 + 949 512 949 512 587 512 c 0,10,11 + 256 512 256 512 256 843 c 24,12,13 + 256 843 256 843 256 1792 c 25,14,-1 + 512 1792 l 25,15,-1 + 512 843 l 0,16,17 + 512 768 512 768 587 768 c 24,18,-1 + 949 768 l 2,19,20 + 1024 768 1024 768 1024 843 c 10,21,-1 + 1024 1792 l 24,22,23 + 1024 1792 1024 1792 1280 1792 c 25,4,5 +EndSplineSet +Validated: 1 +EndChar + +StartChar: SYN +Encoding: 22 22 21 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8C%,9r(&3hH^I +((5m(A-5LALdnk9YR)FN@A]^`#0F\U^a9@c!:g2G2j"gW!5.A/#EmW9`rH)>!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +640 852 m 1,4,5 + 640 852 640 852 1024 1461 c 1,6,7 + 1024 1461 1024 1461 1024 1792 c 0,8,9 + 1024 1792 1024 1792 1280 1792 c 1,10,-1 + 1280 1355 l 1,11,-1 + 693 512 l 1,12,13 + 693 512 693 512 587 512 c 0,14,15 + 587 512 587 512 0 1355 c 1,16,-1 + 0 1792 l 1,17,18 + 0 1792 0 1792 256 1792 c 0,19,20 + 256 1628 256 1628 256 1465 c 1,21,22 + 256 1465 256 1465 640 852 c 1,4,5 +EndSplineSet +Validated: 1 +EndChar + +StartChar: ETB +Encoding: 23 23 22 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8C%,9r(&3hH^I +((1AM!*psG/R/BF +EndImage2 +Fore +SplineSet +0 256 m 1,0,-1 + 1280 256 l 1,1,-1 + 1280 0 l 1,2,-1 + 0 0 l 1,3,4 + 0 0 0 0 0 256 c 1,0,-1 +639 625 m 1,5,6 + 639 512 639 512 437 512 c 0,7,8 + 437 512 437 512 331 512 c 0,9,10 + 0 512 0 512 0 843 c 0,11,12 + 0 843 0 843 0 1792 c 1,13,14 + 0 1792 0 1792 256 1792 c 1,15,-1 + 256 843 l 1,16,17 + 256 768 256 768 331 768 c 0,18,19 + 437 768 437 768 437 768 c 0,20,21 + 512 768 512 768 512 843 c 0,22,23 + 512 1223 512 1223 512 1223 c 0,24,25 + 512 1280 512 1280 639 1280 c 0,26,27 + 768 1280 768 1280 768 1223 c 0,28,29 + 768 843 768 843 768 843 c 1,30,31 + 768 768 768 768 843 768 c 0,32,33 + 949 768 949 768 949 768 c 0,34,35 + 1024 768 1024 768 1024 843 c 0,36,37 + 1024 1792 1024 1792 1024 1792 c 129,-1,38 + 1024 1792 1024 1792 1280 1792 c 1,39,40 + 1280 1792 1280 1792 1280 843 c 0,41,42 + 1280 512 1280 512 949 512 c 0,43,44 + 949 512 949 512 843 512 c 0,45,46 + 639 512 639 512 639 625 c 1,5,6 +EndSplineSet +Validated: 1 +EndChar + +StartChar: CAN +Encoding: 24 24 23 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 126 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W77fm5<#?L$:.Z&u+:&>Ss5t#,..n,f +7@"NIYs&En9qFILi$7D9%*!.Q+uL7.F;"h1%qP2.C%F2=e^lS,:q5*1GQ9@X+p4-_J"coC!!#SZ +:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 256 m 1,0,-1 + 1280 256 l 1,1,-1 + 1280 0 l 1,2,-1 + 0 0 l 1,3,-1 + 0 256 l 1,0,-1 +639 1330 m 1,4,5 + 639 1330 639 1330 1100 1792 c 0,6,7 + 1100 1792 1100 1792 1280 1792 c 1,8,9 + 1280 1792 1280 1792 1280 1611 c 1,10,11 + 1280 1611 1280 1611 834 1147 c 1,12,13 + 834 1147 834 1147 1280 693 c 0,14,-1 + 1280 512 l 1,15,-1 + 1099 512 l 0,16,-1 + 639 951 l 1,17,18 + 639 951 639 951 181 512 c 0,19,20 + 181 512 181 512 0 512 c 1,21,22 + 0 512 0 512 0 693 c 0,23,24 + 0 693 0 693 459 1152 c 1,25,26 + 459 1152 459 1152 0 1611 c 1,27,-1 + 0 1792 l 1,28,29 + 0 1792 0 1792 181 1792 c 0,30,31 + 181 1792 181 1792 639 1330 c 1,4,5 +EndSplineSet +Validated: 1 +EndChar + +StartChar: EM +Encoding: 25 25 24 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8C%,9r(&3hH^h +!)*qlUDq8WdLK3//d[[C.f_;C!TFi%1EL'Va9rjA6rj]r%SITCDP?uKz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +640 1333 m 1,4,5 + 1099 1792 1099 1792 1099 1792 c 0,6,7 + 1280 1792 1280 1792 1280 1792 c 129,-1,8 + 1280 1792 1280 1792 1280 1611 c 1,9,-1 + 768 1099 l 1,10,-1 + 768 512 l 1,11,-1 + 512 512 l 1,12,-1 + 512 1099 l 1,13,-1 + 0 1611 l 1,14,-1 + 0 1792 l 1,15,16 + 181 1792 181 1792 181 1792 c 0,17,18 + 640 1333 640 1333 640 1333 c 1,4,5 +EndSplineSet +Validated: 1 +EndChar + +StartChar: SUB +Encoding: 26 26 25 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8sb%RU9&*Yr8r +,9nE81*:$\'?kQ7P<7,XDc.Es'WIA=B.t!(mqHqrZ$u-ia5I!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +0 1792 m 24,4,-1 + 1280 1792 l 25,5,-1 + 1280 1611 l 25,6,-1 + 437 768 l 24,7,-1 + 1280 768 l 24,8,-1 + 1280 512 l 25,9,-1 + 0 512 l 25,10,-1 + 0 693 l 24,11,-1 + 843 1536 l 24,12,-1 + 0 1536 l 24,13,14 + 0 1536 0 1536 0 1792 c 24,4,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: ESC +Encoding: 27 27 26 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%RU9&*YsiL +A-#.hO<+N).faS:-"'?4?jpRE?t(5sY(.o6YaGQ9""rCP.fa&r'FgPi7r\M/!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +1024 1536 m 24,0,-1 + 256 1536 l 24,1,-1 + 256 256 l 25,2,-1 + 1024 256 l 24,3,-1 + 1024 512 l 25,4,-1 + 512 512 l 25,5,-1 + 512 768 l 24,6,-1 + 768 768 l 24,7,-1 + 768 1024 l 25,8,-1 + 512 1024 l 25,9,-1 + 512 1280 l 25,10,-1 + 1024 1280 l 24,11,12 + 1024 1280 1024 1280 1024 1536 c 24,0,-1 +0 1792 m 25,13,-1 + 1280 1792 l 25,14,-1 + 1280 0 l 25,15,-1 + 0 0 l 25,16,-1 + 0 1792 l 25,13,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: FS +Encoding: 28 28 27 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8C%,9n7D"pQE9 +!Vd?`J[FH9"BL%K&R5>h748LNMEj!,J@pEk9k9ju!.ec!#8A0)mJm4e!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +181 1792 m 24,4,-1 + 1280 693 l 24,5,-1 + 1280 512 l 25,6,-1 + 1099 512 l 24,7,-1 + 0 1611 l 25,8,-1 + 0 1792 l 25,9,10 + 0 1792 0 1792 181 1792 c 24,4,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: GS +Encoding: 29 29 28 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8+BNffG9Xor#n +'1`BF +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +256 1792 m 25,4,-1 + 1024 1792 l 25,5,-1 + 1024 512 l 24,6,-1 + 256 512 l 25,7,-1 + 256 768 l 24,8,-1 + 768 768 l 24,9,-1 + 768 1536 l 24,10,-1 + 256 1536 l 24,11,12 + 256 1536 256 1536 256 1792 c 25,4,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: RS +Encoding: 30 30 29 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns2BO@1f( +h*;aC$0W!UENg0#8Oc12@@.&_#$d%QOH%8W#]9^fE+BD#0`]\&)?>?3fNeIW!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 1536 m 24,0,-1 + 1024 1536 l 24,1,-1 + 1024 1280 l 25,2,-1 + 437 1280 l 24,3,-1 + 1280 437 l 24,4,-1 + 1280 256 l 25,5,-1 + 1099 256 l 24,6,-1 + 256 1099 l 25,7,-1 + 256 512 l 25,8,-1 + 0 512 l 25,9,10 + 0 512 0 512 0 1536 c 24,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: US +Encoding: 31 31 30 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8Dg*$Z[QM@bLD +'NlO`XoM`T9HdL=8.q7f5Sdfg&m6psLkF"VYSAi\0RJpr!/i!7$j7etH2mpF!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +1280 1792 m 25,0,-1 + 1280 512 l 25,1,-1 + 437 512 l 24,2,-1 + 768 181 l 24,3,-1 + 768 0 l 25,4,-1 + 587 0 l 24,5,-1 + 0 587 l 25,6,-1 + 0 693 l 24,7,-1 + 587 1280 l 24,8,-1 + 768 1280 l 25,9,-1 + 768 1099 l 25,10,-1 + 437 768 l 24,11,-1 + 1024 768 l 24,12,-1 + 1024 1792 l 24,13,14 + 1024 1792 1024 1792 1280 1792 c 25,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: exclam +Encoding: 33 33 31 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 96 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ +$;a-Q3:p1#b;4)ri:7$O`M*SJUBW=Iz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +512 256 m 29,0,-1 + 768 256 l 25,1,-1 + 768 0 l 25,2,-1 + 512 0 l 25,3,-1 + 512 256 l 29,0,-1 +512 1792 m 25,4,-1 + 768 1792 l 25,5,-1 + 768 512 l 25,6,-1 + 512 512 l 25,7,-1 + 512 1792 l 25,4,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: quotedbl +Encoding: 34 34 32 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 103 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8CJNffG9X9;!; +Ws:.?(-lLG<5;%h)pjR5jqG+RTE5*=0F/+t#&COF!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +768 1792 m 24,0,-1 + 1024 1792 l 24,1,-1 + 1024 1024 l 25,2,-1 + 768 1024 l 25,3,4 + 768 1024 768 1024 768 1792 c 24,0,-1 +256 1792 m 24,5,-1 + 512 1792 l 24,6,-1 + 512 1024 l 25,7,-1 + 256 1024 l 25,8,9 + 256 1024 256 1024 256 1792 c 24,5,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: numbersign +Encoding: 35 35 33 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 107 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CJNffG9X9;!; +Ws:.?(-lMbZsm-gCb$0XK20,m'NW]@K732)-<;#GT!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +768 1024 m 25,0,-1 + 512 1024 l 25,1,-1 + 512 768 l 24,2,-1 + 768 768 l 17,3,4 + 768 768 768 768 768 1024 c 25,0,-1 +1024 1792 m 25,5,-1 + 1024 1280 l 24,6,-1 + 1280 1280 l 25,7,-1 + 1280 1024 l 25,8,-1 + 1024 1024 l 24,9,-1 + 1024 768 l 24,10,-1 + 1280 768 l 24,11,-1 + 1280 512 l 25,12,-1 + 1024 512 l 24,13,-1 + 1024 0 l 24,14,-1 + 768 0 l 25,15,-1 + 768 512 l 25,16,-1 + 512 512 l 25,17,-1 + 512 0 l 25,18,-1 + 256 0 l 25,19,-1 + 256 512 l 25,20,-1 + 0 512 l 25,21,-1 + 0 768 l 24,22,-1 + 256 768 l 24,23,-1 + 256 1024 l 25,24,-1 + 0 1024 l 25,25,-1 + 0 1280 l 25,26,-1 + 256 1280 l 25,27,-1 + 256 1792 l 25,28,-1 + 512 1792 l 25,29,-1 + 512 1280 l 25,30,-1 + 768 1280 l 25,31,-1 + 768 1792 l 25,32,-1 + 1024 1792 l 25,5,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: dollar +Encoding: 36 36 34 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 127 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W7S-!6<#?L$bs;]P5R^!,B't03:)+gl +TJW.17)c^/\UJ/BF +EndImage2 +Fore +SplineSet +768 768 m 9,0,-1 + 768 512 l 25,1,2 + 768 512 768 512 949 512 c 0,3,4 + 1024 512 1024 512 1024 587 c 24,5,6 + 1024 678 1024 678 1024 693 c 0,7,8 + 1024 768 1024 768 949 768 c 16,9,10 + 858 768 858 768 768 768 c 9,0,-1 +331 1280 m 0,11,12 + 256 1280 256 1280 256 1205 c 16,13,14 + 256 1114 256 1114 256 1099 c 0,15,16 + 256 1024 256 1024 329 1024 c 0,17,18 + 330 1024 330 1024 331 1024 c 8,19,-1 + 512 1024 l 25,20,-1 + 512 1280 l 25,21,22 + 512 1280 512 1280 331 1280 c 0,11,12 +331 768 m 16,23,24 + 0 768 0 768 0 1099 c 24,25,26 + 0 1099 0 1099 0 1205 c 0,27,28 + 0 1536 0 1536 331 1536 c 24,29,-1 + 512 1536 l 24,30,-1 + 512 1792 l 25,31,-1 + 768 1792 l 25,32,-1 + 768 1536 l 24,33,-1 + 1280 1536 l 24,34,35 + 1280 1536 1280 1536 1280 1280 c 25,36,-1 + 768 1280 l 25,37,-1 + 768 1024 l 25,38,-1 + 949 1024 l 0,39,40 + 1280 1024 1280 1024 1280 693 c 24,41,42 + 1280 693 1280 693 1280 587 c 0,43,44 + 1280 256 1280 256 949 256 c 24,45,-1 + 768 256 l 25,46,-1 + 768 0 l 25,47,-1 + 512 0 l 25,48,-1 + 512 256 l 25,49,-1 + 0 256 l 25,50,-1 + 0 512 l 25,51,-1 + 512 512 l 25,52,53 + 512 512 512 512 512 768 c 24,54,-1 + 331 768 l 16,23,24 +EndSplineSet +Validated: 1 +EndChar + +StartChar: percent +Encoding: 37 37 35 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$N_p8d+:(< +,fgO%MSLRse..^NK'C;:'FZM=Xb'c.b9XS4\/YkV3U.S!$>mtlz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +1077 384 m 1,0,1 + 1280 182 1280 182 1280 182 c 128,-1,2 + 1280 182 1280 182 1280 0 c 25,3,4 + 1280 0 1280 0 1099 0 c 0,5,6 + 1099 0 1099 0 897 204 c 1,7,8 + 897 204 897 204 693 0 c 1,9,10 + 693 0 693 0 331 0 c 0,11,12 + 0 0 0 0 0 331 c 25,13,14 + 0 331 0 331 0 693 c 0,15,16 + 0 693 0 693 203 896 c 9,17,-1 + 0 1099 l 1,18,-1 + 0 1461 l 17,19,20 + 0 1792 0 1792 331 1792 c 24,21,22 + 331 1792 331 1792 437 1792 c 0,23,24 + 768 1792 768 1792 768 1469 c 0,25,26 + 768 1465 768 1465 768 1461 c 9,27,28 + 768 1461 768 1461 768 1099 c 1,29,-1 + 565 896 l 1,30,31 + 565 896 565 896 896 565 c 1,32,33 + 896 565 896 565 1099 768 c 0,34,35 + 1099 768 1099 768 1280 768 c 1,36,37 + 1280 768 1280 768 1280 587 c 1,38,39 + 1077 384 1077 384 1077 384 c 1,0,1 +716 385 m 1,40,41 + 716 385 716 385 387 717 c 1,42,43 + 387 717 387 717 256 587 c 9,44,45 + 256 422 256 422 256 331 c 0,46,47 + 256 256 256 256 331 256 c 24,48,49 + 478 256 478 256 587 256 c 0,50,51 + 587 256 587 256 716 385 c 1,40,41 +384 1077 m 16,52,-1 + 512 1205 l 1,53,54 + 512 1373 512 1373 512 1461 c 0,55,56 + 512 1536 512 1536 437 1536 c 24,57,-1 + 331 1536 l 0,58,59 + 256 1536 256 1536 256 1461 c 24,60,61 + 256 1461 256 1461 256 1205 c 0,62,-1 + 384 1077 l 16,52,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: quotesingle +Encoding: 39 39 37 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 100 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CNNffG9`^HNZ +$;a-Q35d>_jV6]K5dD/Z8^IS?MP^UeJpj^tz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +512 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 1024 l 25,2,-1 + 512 1024 l 25,3,-1 + 512 1792 l 25,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: parenleft +Encoding: 40 40 38 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 111 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8CNNffG9`^HN: +$:'ca$j(.\CCAo)'Q]BrKGB%(`oTII6!tAq.09M++V>%^+Bg&k!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +768 1792 m 25,0,-1 + 768 1611 l 1,1,-1 + 256 1099 l 0,2,3 + 256 1099 256 1099 256 693 c 1,4,-1 + 768 181 l 0,5,6 + 768 181 768 181 768 0 c 25,7,8 + 768 0 768 0 587 0 c 24,9,10 + 587 0 587 0 0 587 c 25,11,12 + 0 1190 0 1190 0 1205 c 28,13,14 + 0 1205 0 1205 587 1792 c 28,15,16 + 677 1792 677 1792 768 1792 c 25,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: parenright +Encoding: 41 41 39 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8CNNffG9`^HNZ +$:"f(;Zp/%dY:I.M?4KuTcDJpJD>\C.C]]:,XJj=!8p-S&*9"7QiI*d!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +711 1792 m 25,0,-1 + 1280 1205 l 24,1,-1 + 1280 587 l 25,2,-1 + 693 0 l 25,3,-1 + 512 0 l 25,4,-1 + 512 182 l 24,5,-1 + 1024 693 l 24,6,-1 + 1024 1099 l 25,7,-1 + 512 1611 l 25,8,-1 + 512 1792 l 25,9,-1 + 711 1792 l 25,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: asterisk +Encoding: 42 42 40 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 1 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NS=d?+:(?(s8UE1_?!r( +0@O3sp7:lE5a0,I0O/kjXQZH=DE#=``RHUM5,j"b$(RZ9N"(d-mz8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +822 896 m 1,0,1 + 1272 454 1272 454 1281 437 c 0,2,3 + 1281 437 1281 437 1281 256 c 25,4,5 + 1281 256 1281 256 1100 256 c 24,6,7 + 1100 256 1100 256 769 587 c 25,8,-1 + 769 0 l 25,9,-1 + 513 0 l 25,10,-1 + 513 587 l 25,11,-1 + 182 256 l 17,12,13 + 1 256 1 256 1 256 c 25,14,15 + 1 437 1 437 1 437 c 130,-1,16 + 1 437 1 437 460 896 c 1,17,18 + 460 896 460 896 1 1355 c 1,19,20 + 1 1536 1 1536 1 1536 c 152,-1,21 + 1 1536 1 1536 182 1536 c 24,22,23 + 182 1536 182 1536 513 1205 c 24,24,25 + 513 1205 513 1205 513 1792 c 25,26,-1 + 769 1792 l 25,27,-1 + 769 1205 l 0,28,-1 + 1099 1536 l 24,29,30 + 1099 1536 1099 1536 1281 1536 c 0,31,32 + 1281 1536 1281 1536 1281 1355 c 1,33,34 + 1281 1355 1281 1355 822 896 c 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: plus +Encoding: 43 43 41 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +!WYmi&I*SHfQ[Ar!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +512 1536 m 29,0,-1 + 768 1536 l 25,1,-1 + 768 1024 l 25,2,-1 + 1280 1024 l 25,3,-1 + 1280 768 l 24,4,-1 + 768 768 l 24,5,-1 + 768 256 l 25,6,-1 + 512 256 l 25,7,-1 + 512 768 l 24,8,-1 + 0 768 l 24,9,-1 + 0 1024 l 25,10,-1 + 512 1024 l 25,11,-1 + 512 1536 l 29,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: comma +Encoding: 44 44 42 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 91 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2\'ehBu +@W`0#D?/q@j]_^nKa/-g/b(@l!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +768 331 m 0,0,1 + 768 0 768 0 437 0 c 24,2,-1 + 256 0 l 25,3,-1 + 256 256 l 25,4,-1 + 437 256 l 0,5,6 + 512 256 512 256 512 331 c 24,7,-1 + 512 768 l 24,8,-1 + 768 768 l 24,9,10 + 768 384 768 384 768 331 c 0,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: hyphen +Encoding: 45 45 43 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 94 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns4Z$5e?V +@(66j=Y.W6D!n"P%0-S$$O.#5I6.E/!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 1024 m 25,0,-1 + 1280 1024 l 25,1,-1 + 1280 768 l 24,2,-1 + 0 768 l 24,3,4 + 0 768 0 768 0 1024 c 25,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: period +Encoding: 46 46 44 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 84 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[;S^Ap +Lt+im)m]YX6<>Toz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +512 256 m 29,0,-1 + 768 256 l 25,1,-1 + 768 0 l 25,2,-1 + 512 0 l 25,3,-1 + 512 256 l 29,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: slash +Encoding: 47 47 45 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns3P!_,XK +'KmiO5a(=h_A-IB";qADJ4gNN!+[6ZO"d9^$.=M9!0Lq/#JY@cIfKHK!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +199 256 m 25,0,-1 + 0 256 l 25,1,-1 + 0 455 l 24,2,-1 + 1081 1536 l 25,3,-1 + 1280 1536 l 25,4,-1 + 1280 1337 l 25,5,6 + 1280 1337 1280 1337 199 256 c 25,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: zero +Encoding: 48 48 46 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7+I-GdXZ$IEpi.)7,8;?SlYfhRo0(sN,F`9.L.=*kqn*O=h/z8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +1024 331 m 9,0,-1 + 1024 1099 l 1,1,2 + 1024 1099 1024 1099 256 331 c 1,3,4 + 256 256 256 256 331 256 c 24,5,-1 + 949 256 l 0,6,7 + 1024 256 1024 256 1024 331 c 9,0,-1 +1024 1461 m 0,8,9 + 1024 1536 1024 1536 949 1536 c 0,10,-1 + 331 1536 l 0,11,12 + 256 1536 256 1536 256 1461 c 24,13,14 + 256 1461 256 1461 256 693 c 0,15,16 + 256 693 256 693 1024 1461 c 0,8,9 +949 1792 m 0,17,18 + 1280 1792 1280 1792 1280 1461 c 24,19,20 + 1280 730 1280 730 1280 331 c 0,21,22 + 1280 0 1280 0 949 0 c 24,23,-1 + 331 0 l 0,24,25 + 0 0 0 0 0 331 c 24,26,27 + 0 1062 0 1062 0 1461 c 0,28,29 + 0 1792 0 1792 331 1792 c 24,30,31 + 331 1792 331 1792 949 1792 c 0,17,18 +EndSplineSet +Validated: 1 +EndChar + +StartChar: one +Encoding: 49 49 47 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 107 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CNNffG9`^HN: +$?/Rg<.YkCZNY4MMRc7t.Ofm.&k4,!^]4B4!='>cmbYYX!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +512 1734 m 0,0,1 + 569 1792 569 1792 640 1792 c 128,-1,2 + 711 1792 711 1792 768 1734 c 8,3,-1 + 768 331 l 0,4,5 + 768 256 768 256 842 256 c 24,6,-1 + 949 256 l 0,7,8 + 1024 199 1024 199 1024 126 c 0,9,10 + 1024 75 1024 75 949 0 c 1,11,12 + 949 0 949 0 331 0 c 0,13,14 + 256 75 256 75 256 128 c 0,15,16 + 256 199 256 199 331 256 c 8,17,-1 + 437 256 l 0,18,19 + 512 256 512 256 512 331 c 24,20,21 + 512 1205 512 1205 512 1205 c 0,22,23 + 512 1280 512 1280 437 1280 c 24,24,-1 + 256 1280 l 17,25,26 + 211 1344 211 1344 211 1408 c 128,-1,27 + 211 1472 211 1472 256 1536 c 8,28,-1 + 437 1536 l 0,29,30 + 512 1536 512 1536 512 1611 c 24,31,-1 + 512 1734 l 0,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: two +Encoding: 50 50 48 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 124 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9ZS3`0h;_W'd,]a)KZF-2kWgZ%)Hlb9EI\9'u2d_)VHqI,MaFADrB5Wz8OZBB +Y!QNJ +EndImage2 +Fore +SplineSet +0 1461 m 0,0,1 + 0 1792 0 1792 331 1792 c 24,2,-1 + 949 1792 l 0,3,4 + 1280 1792 1280 1792 1280 1461 c 24,5,6 + 1280 1114 1280 1114 1280 1099 c 0,7,8 + 1280 768 1280 768 949 768 c 24,9,-1 + 693 768 l 17,10,11 + 693 768 693 768 256 331 c 0,12,13 + 256 256 256 256 329 256 c 0,14,15 + 330 256 330 256 331 256 c 8,16,-1 + 1205 256 l 0,17,18 + 1280 199 1280 199 1280 136 c 0,19,20 + 1280 135 1280 135 1280 134 c 0,21,22 + 1280 76 1280 76 1205 0 c 0,23,24 + 1205 0 1205 0 0 0 c 25,25,26 + 0 0 0 0 0 437 c 0,27,28 + 0 437 0 437 512 949 c 0,29,30 + 587 1024 587 1024 666 1024 c 24,31,32 + 666 1024 666 1024 949 1024 c 0,33,34 + 1024 1024 1024 1024 1024 1099 c 24,35,36 + 1024 1318 1024 1318 1024 1461 c 0,37,38 + 1024 1536 1024 1536 949 1536 c 24,39,-1 + 331 1536 l 0,40,41 + 256 1536 256 1536 256 1461 c 24,42,-1 + 256 1337 l 0,43,44 + 199 1280 199 1280 129 1280 c 1,45,46 + 57 1280 57 1280 0 1337 c 1,47,48 + 0 1337 0 1337 0 1461 c 0,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: three +Encoding: 51 51 49 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 123 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?K_r!ro=GQ8sb%RU9&*Yr8r +a<3rAO<+O4680RGkSi@dcum2^_A.TCJhXc&-?K9U:)FF`,dJV92ZNga:DsTEXUAD7!!!!j78?7R +6=>BF +EndImage2 +Fore +SplineSet +75 1792 m 0,0,1 + 75 1792 75 1792 1280 1792 c 25,2,3 + 1280 1792 1280 1792 1280 1355 c 1,4,5 + 1280 1355 1280 1355 1024 1099 c 0,6,7 + 1024 1099 1024 1099 1024 1024 c 1,8,9 + 1280 1024 1280 1024 1280 696 c 0,10,11 + 1280 694 1280 694 1280 693 c 0,12,13 + 1280 693 1280 693 1280 331 c 17,14,15 + 1280 0 1280 0 949 0 c 24,16,17 + 342 0 342 0 331 0 c 0,18,19 + 0 0 0 0 0 331 c 25,20,21 + 0 455 0 455 0 455 c 0,22,23 + 57 512 57 512 125 512 c 0,24,25 + 199 512 199 512 256 455 c 0,26,-1 + 256 331 l 17,27,28 + 256 256 256 256 331 256 c 24,29,30 + 331 256 331 256 949 256 c 0,31,32 + 1024 256 1024 256 1024 331 c 25,33,34 + 1024 550 1024 550 1024 693 c 0,35,36 + 1024 768 1024 768 949 768 c 24,37,-1 + 569 768 l 0,38,39 + 512 825 512 825 512 896 c 128,-1,40 + 512 967 512 967 569 1024 c 8,41,-1 + 587 1024 l 24,42,43 + 587 1024 587 1024 1024 1461 c 17,44,45 + 1024 1536 1024 1536 949 1536 c 24,46,-1 + 75 1536 l 0,47,48 + 0 1593 0 1593 0 1665 c 0,49,50 + 0 1734 0 1734 75 1792 c 0,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: four +Encoding: 52 52 50 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h +/&3J<;?9euP/LoF'0]!L#p;kq*/SJM$ShsVBlHRoN5Gi"s0i[Nd4O_kz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +768 768 m 24,0,-1 + 768 1355 l 25,1,-1 + 256 843 l 25,2,-1 + 256 768 l 24,3,4 + 256 768 256 768 768 768 c 24,0,-1 +1024 1792 m 24,5,-1 + 1024 768 l 24,6,-1 + 1223 768 l 0,7,8 + 1280 704 1280 704 1280 640 c 128,-1,9 + 1280 576 1280 576 1223 512 c 8,10,-1 + 1024 512 l 25,11,-1 + 1024 0 l 25,12,-1 + 768 0 l 25,13,-1 + 768 512 l 25,14,-1 + 0 512 l 25,15,-1 + 0 949 l 25,16,-1 + 843 1792 l 24,17,18 + 843 1792 843 1792 1024 1792 c 24,5,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: five +Encoding: 53 53 51 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8sb%RU9&*YsiL +A-$ei0MF`5b^qI_aN00H+qqPMk^4_=%X\7m"gT=o.fit&)ZhRQ%hJ^@!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +1223 1792 m 0,0,1 + 1280 1730 1280 1730 1280 1666 c 128,-1,2 + 1280 1602 1280 1602 1223 1536 c 8,3,-1 + 256 1536 l 24,4,-1 + 256 1280 l 25,5,-1 + 949 1280 l 0,6,7 + 1280 1280 1280 1280 1280 949 c 24,8,9 + 1280 331 1280 331 1280 331 c 0,10,11 + 1280 0 1280 0 949 0 c 24,12,-1 + 331 0 l 0,13,14 + 0 0 0 0 0 331 c 24,15,16 + 0 455 0 455 0 455 c 0,17,18 + 65 512 65 512 129 512 c 128,-1,19 + 193 512 193 512 256 455 c 8,20,-1 + 256 331 l 0,21,22 + 256 256 256 256 331 256 c 24,23,-1 + 949 256 l 0,24,25 + 1024 256 1024 256 1024 331 c 24,26,27 + 1024 949 1024 949 1024 949 c 0,28,29 + 1024 1024 1024 1024 949 1024 c 24,30,-1 + 0 1024 l 25,31,-1 + 0 1792 l 18,32,33 + 0 1792 0 1792 1223 1792 c 0,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: six +Encoding: 54 54 52 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+FNffG9`ah?c +"',Db6l(HV">W6rnCdqEJ?/k/,d8$)K':c?+m[.fAc_/9jTCSK!1`*k"G(^D63$uc!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +256 331 m 0,0,1 + 256 256 256 256 331 256 c 24,2,-1 + 949 256 l 0,3,4 + 1024 256 1024 256 1024 331 c 24,5,6 + 1024 550 1024 550 1024 693 c 0,7,8 + 1024 768 1024 768 949 768 c 24,9,10 + 949 768 949 768 256 768 c 24,11,12 + 256 768 256 768 256 331 c 0,0,1 +1223 1792 m 0,13,14 + 1280 1749 1280 1749 1280 1671 c 128,-1,15 + 1280 1593 1280 1593 1223 1536 c 0,16,-1 + 693 1536 l 25,17,-1 + 256 1099 l 25,18,-1 + 256 1024 l 25,19,-1 + 949 1024 l 0,20,21 + 1280 1024 1280 1024 1280 693 c 24,22,23 + 1280 346 1280 346 1280 331 c 0,24,25 + 1280 0 1280 0 949 0 c 24,26,-1 + 331 0 l 0,27,28 + 0 0 0 0 0 331 c 24,29,30 + 0 331 0 331 0 1205 c 24,31,32 + 0 1205 0 1205 587 1792 c 24,33,34 + 587 1792 587 1792 1223 1792 c 0,13,14 +EndSplineSet +Validated: 1 +EndChar + +StartChar: seven +Encoding: 55 55 53 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8sb%RU9&*Yr8r +a<3rAO<+O4680RGkSi@d5W[:=6(5UsE(Rn]+BsKDL0K3]!TO7^iA_MXMbJN[z8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +0 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 1355 l 25,2,-1 + 512 587 l 25,3,-1 + 512 0 l 25,4,-1 + 256 0 l 25,5,-1 + 256 693 l 24,6,-1 + 1024 1461 l 25,7,-1 + 1024 1536 l 25,8,-1 + 0 1536 l 17,9,10 + 0 1536 0 1536 0 1792 c 25,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: eight +Encoding: 56 56 54 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 100 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7*n(b?f[")J,@Ce5cOVrrF"z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +256 331 m 0,0,1 + 256 256 256 256 331 256 c 24,2,-1 + 949 256 l 0,3,4 + 1024 256 1024 256 1024 331 c 24,5,6 + 1024 693 1024 693 1024 693 c 1,7,8 + 1024 768 1024 768 949 768 c 1,9,10 + 949 768 949 768 331 768 c 0,11,12 + 256 768 256 768 256 693 c 24,13,14 + 256 608 256 608 256 331 c 0,0,1 +256 1099 m 0,15,16 + 256 1024 256 1024 331 1024 c 24,17,-1 + 949 1024 l 0,18,19 + 1024 1024 1024 1024 1024 1099 c 24,20,21 + 1024 1318 1024 1318 1024 1461 c 0,22,23 + 1024 1536 1024 1536 949 1536 c 24,24,-1 + 331 1536 l 0,25,26 + 256 1536 256 1536 256 1461 c 24,27,28 + 256 1389 256 1389 256 1099 c 0,15,16 +1168 896 m 1,29,30 + 1280 839 1280 839 1280 693 c 0,31,32 + 1280 331 1280 331 1280 331 c 0,33,34 + 1280 0 1280 0 949 0 c 24,35,36 + 331 0 331 0 331 0 c 0,37,38 + 0 0 0 0 0 331 c 24,39,40 + 0 331 0 331 0 693 c 0,41,42 + 1 834 1 834 112 896 c 1,43,44 + 0 957 0 957 0 1099 c 0,45,46 + 0 1461 0 1461 0 1461 c 0,47,48 + 0 1792 0 1792 331 1792 c 24,49,50 + 949 1792 949 1792 949 1792 c 0,51,52 + 1280 1792 1280 1792 1280 1461 c 24,53,54 + 1280 1446 1280 1446 1280 1099 c 0,55,56 + 1280 954 1280 954 1168 896 c 1,29,30 +EndSplineSet +Validated: 1 +EndChar + +StartChar: nine +Encoding: 57 57 55 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 123 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7*n(b?f[aB"t7"1nTe89Dg!BF +EndImage2 +Fore +SplineSet +1024 1461 m 0,0,1 + 1024 1536 1024 1536 949 1536 c 24,2,-1 + 331 1536 l 0,3,4 + 256 1536 256 1536 256 1461 c 24,5,6 + 256 1242 256 1242 256 1099 c 0,7,8 + 256 1024 256 1024 331 1024 c 24,9,-1 + 1024 1024 l 25,10,11 + 1024 1280 1024 1280 1024 1461 c 0,0,1 +949 1792 m 0,12,13 + 1280 1792 1280 1792 1280 1461 c 24,14,15 + 1280 1461 1280 1461 1280 587 c 25,16,-1 + 693 0 l 1,17,-1 + 57 0 l 17,18,19 + 0 63 0 63 0 127 c 128,-1,20 + 0 191 0 191 57 256 c 0,21,-1 + 587 256 l 24,22,23 + 587 256 587 256 1024 693 c 24,24,25 + 1024 693 1024 693 1024 768 c 24,26,-1 + 331 768 l 0,27,28 + 0 768 0 768 0 1099 c 24,29,30 + 0 1446 0 1446 0 1461 c 0,31,32 + 0 1792 0 1792 331 1792 c 24,33,34 + 331 1792 331 1792 949 1792 c 0,12,13 +EndSplineSet +Validated: 1 +EndChar + +StartChar: colon +Encoding: 58 58 56 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns4f$5aWu +Yo3g*!LHaC$7Ih6Wrmm(!&@FZ$m].ZLh)ch@bW1UUYoz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +768 768 m 24,0,1 + 768 768 768 768 768 331 c 0,2,3 + 768 0 768 0 437 0 c 24,4,-1 + 256 0 l 25,5,-1 + 256 256 l 25,6,-1 + 437 256 l 0,7,8 + 512 256 512 256 512 331 c 24,9,-1 + 512 768 l 24,10,11 + 512 768 512 768 768 768 c 24,0,1 +512 1280 m 25,12,-1 + 768 1280 l 25,13,-1 + 768 1024 l 25,14,-1 + 512 1024 l 25,15,-1 + 512 1280 l 25,12,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: less +Encoding: 60 60 58 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h +.f`.M1CU>bQR'WXOI:?a_#uM/S)%HW!"#kEp_:ObM+\E\.d%TT%fbVFz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +309 896 m 1,0,1 + 309 896 309 896 1024 182 c 0,2,3 + 1024 182 1024 182 1024 0 c 25,4,5 + 1024 0 1024 0 843 0 c 24,6,7 + 843 0 843 0 0 843 c 25,8,-1 + 0 949 l 25,9,10 + 0 949 0 949 843 1792 c 24,11,12 + 843 1792 843 1792 1024 1792 c 24,13,14 + 1024 1792 1024 1792 1024 1611 c 1,15,-1 + 309 896 l 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: equal +Encoding: 61 61 59 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 96 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd6b(@jRAf]t[&9K/tn7*(2lS*^gz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +0 768 m 24,0,-1 + 1280 768 l 24,1,-1 + 1280 512 l 25,2,-1 + 0 512 l 25,3,4 + 0 512 0 512 0 768 c 24,0,-1 +0 1280 m 25,5,-1 + 1280 1280 l 25,6,-1 + 1280 1024 l 25,7,-1 + 0 1024 l 25,8,-1 + 0 1280 l 25,5,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: greater +Encoding: 62 62 60 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?L$c9Vp?+:&'8li7!DD@\!2 +/(Y77eXll!"%j1]?p11f#p"OPpWj:T+ftqt">",1((Z@:V:5JF!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +971 896 m 129,-1,1 + 971 896 971 896 256 1611 c 1,2,-1 + 256 1792 l 25,3,4 + 437 1792 437 1792 437 1792 c 24,5,6 + 1280 949 1280 949 1280 949 c 25,7,8 + 1280 843 1280 843 1280 843 c 25,9,10 + 437 0 437 0 437 0 c 24,11,12 + 256 0 256 0 256 0 c 25,13,14 + 256 181 256 181 256 181 c 0,15,0 + 971 896 971 896 971 896 c 129,-1,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: question +Encoding: 63 63 61 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9ZS2q8W^2N0XJ#UU*tO@7&Suj+BsQ$#d+0\-ccVp@J)Z[b`.KE;r1Z)!B$?j@tkj!!;``sDh9cj5nz8OZBB +Y!QNJ +EndImage2 +Fore +SplineSet +1024 1461 m 1,0,1 + 1024 1536 1024 1536 949 1536 c 0,2,3 + 640 1536 640 1536 331 1536 c 1,4,5 + 256 1536 256 1536 256 1461 c 1,6,7 + 256 1461 256 1461 256 331 c 1,8,9 + 256 256 256 256 331 256 c 1,10,11 + 331 256 331 256 1223 256 c 0,12,13 + 1279 182 1279 182 1279 137 c 0,14,15 + 1278 73 1278 73 1223 0 c 0,16,17 + 1223 0 1223 0 313 0 c 0,18,19 + 0 0 0 0 0 327 c 1,20,21 + 0 1026 0 1026 0 1461 c 0,22,23 + 0 1792 0 1792 331 1792 c 0,24,25 + 331 1792 331 1792 949 1792 c 0,26,27 + 1280 1792 1280 1792 1280 1461 c 0,28,29 + 1280 986 1280 986 1280 839 c 0,30,31 + 1280 512 1280 512 949 512 c 0,32,33 + 896 512 896 512 843 512 c 0,34,35 + 512 512 512 512 512 843 c 0,36,37 + 512 843 512 843 512 1223 c 0,38,39 + 569 1280 569 1280 640 1280 c 128,-1,40 + 711 1280 711 1280 768 1223 c 0,41,-1 + 768 896 l 0,42,43 + 768 825 768 825 843 825 c 0,44,45 + 843 825 843 825 949 825 c 0,46,47 + 1024 825 1024 825 1024 896 c 0,48,49 + 1024 896 1024 896 1024 1461 c 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: A +Encoding: 65 65 63 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 119 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8CNNffG9`^HN: +$:'asKBF +EndImage2 +Fore +SplineSet +640 1483 m 1,0,1 + 640 1483 640 1483 256 1099 c 1,2,-1 + 256 825 l 0,3,4 + 256 768 256 768 313 768 c 24,5,6 + 313 768 313 768 967 768 c 0,7,8 + 1024 768 1024 768 1024 825 c 24,9,10 + 1024 825 1024 825 1024 1099 c 0,11,-1 + 640 1483 l 1,0,1 +693 1792 m 17,12,13 + 693 1792 693 1792 1280 1205 c 24,14,-1 + 1280 0 l 25,15,-1 + 1024 0 l 25,16,-1 + 1024 455 l 0,17,18 + 1024 512 1024 512 967 512 c 24,19,20 + 640 512 640 512 313 512 c 24,21,22 + 256 512 256 512 256 455 c 24,23,-1 + 256 0 l 25,24,-1 + 0 0 l 25,25,-1 + 0 1205 l 24,26,-1 + 587 1792 l 24,27,28 + 587 1792 587 1792 693 1792 c 17,12,13 +EndSplineSet +Validated: 1 +EndChar + +StartChar: B +Encoding: 66 66 64 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 96 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8sb%RgE0H5;TS +A3i[S7MJ$"*n.r'K>@lpj;8j5Q?;#Rz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +256 768 m 0,0,-1 + 256 256 l 1,1,-1 + 967 256 l 0,2,3 + 1024 256 1024 256 1024 313 c 1,4,5 + 1024 640 1024 640 1024 711 c 0,6,7 + 1024 768 1024 768 967 768 c 1,8,9 + 256 768 256 768 256 768 c 0,0,-1 +967 1024 m 1,10,11 + 1024 1024 1024 1024 1024 1081 c 0,12,-1 + 1024 1465 l 1,13,14 + 1024 1536 1024 1536 967 1536 c 0,15,-1 + 256 1536 l 1,16,-1 + 256 1024 l 1,17,-1 + 967 1024 l 1,10,11 +967 1792 m 0,18,19 + 1280 1792 1280 1792 1280 1465 c 1,20,21 + 1280 1180 1280 1180 1280 1081 c 0,22,23 + 1280 896 1280 896 1152 896 c 1,24,25 + 1280 896 1280 896 1280 710 c 0,26,-1 + 1280 313 l 1,27,28 + 1280 0 1280 0 967 0 c 0,29,-1 + 0 0 l 1,30,-1 + 0 1792 l 1,31,32 + 0 1792 0 1792 967 1792 c 0,18,19 +EndSplineSet +Validated: 1 +EndChar + +StartChar: C +Encoding: 67 67 65 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7+1#-oLF#X\X(#1=5/3uDKH$cl(R6$,$c!::.1#VQD@0)ttP!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +256 313 m 1,0,1 + 256 256 256 256 313 256 c 0,2,3 + 640 256 640 256 967 256 c 0,4,5 + 1024 256 1024 256 1024 313 c 0,6,7 + 1024 313 1024 313 1024 512 c 1,8,9 + 1024 512 1024 512 1280 512 c 1,10,-1 + 1280 313 l 1,11,12 + 1280 0 1280 0 967 0 c 0,13,14 + 640 0 640 0 313 0 c 0,15,16 + 0 0 0 0 0 313 c 1,17,18 + 0 313 0 313 0 512 c 1,19,20 + 0 512 0 512 0 1280 c 1,21,-1 + 0 1465 l 1,22,23 + 0 1792 0 1792 313 1792 c 0,24,25 + 640 1792 640 1792 967 1792 c 0,26,27 + 1280 1792 1280 1792 1280 1465 c 1,28,29 + 1280 1465 1280 1465 1280 1280 c 1,30,-1 + 1024 1279 l 1,31,32 + 1024 1464 1024 1464 1024 1465 c 0,33,34 + 1024 1536 1024 1536 967 1536 c 0,35,36 + 967 1536 967 1536 313 1536 c 1,37,38 + 256 1536 256 1536 256 1465 c 1,39,40 + 256 889 256 889 256 313 c 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: D +Encoding: 68 68 66 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 98 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.7lon<#?K_r!ro=GQ8sb%RgE0H5;TS +A3i[S7MJ$"*n.r'FAP6L(B>)*&cj#e^:jRI!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +967 256 m 0,0,1 + 1024 256 1024 256 1024 313 c 1,2,3 + 1024 313 1024 313 1024 1465 c 1,4,5 + 1024 1536 1024 1536 967 1536 c 1,6,7 + 967 1536 967 1536 256 1536 c 1,8,-1 + 256 256 l 1,9,10 + 612 256 612 256 967 256 c 0,0,1 +967 1792 m 0,11,12 + 1280 1789 1280 1789 1280 1465 c 0,13,14 + 1280 1236 1280 1236 1280 313 c 0,15,16 + 1280 0 1280 0 967 0 c 1,17,18 + 967 0 967 0 0 0 c 1,19,20 + 0 0 0 0 0 1792 c 0,21,22 + 0 1792 0 1792 967 1792 c 0,11,12 +EndSplineSet +Validated: 1 +EndChar + +StartChar: E +Encoding: 69 69 67 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8sb%RU9&*YsiL +A-$eiR*Z#`q&!/*RmmK15]/iq"p!0=(&Pfd:+cMH!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 0 m 29,0,-1 + 0 1792 l 25,1,-1 + 1280 1792 l 25,2,-1 + 1280 1536 l 25,3,-1 + 256 1536 l 25,4,-1 + 256 1024 l 25,5,-1 + 1024 1024 l 25,6,-1 + 1024 768 l 25,7,-1 + 256 768 l 25,8,-1 + 256 256 l 25,9,-1 + 1280 256 l 25,10,-1 + 1280 0 l 25,11,-1 + 0 0 l 29,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: F +Encoding: 70 70 68 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 100 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8sb%RU9&*YsiL +A-$eiR*Z#`q&!/*Rmsq'"Pj%XQV%kjh$9`\z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +0 0 m 29,0,-1 + 0 1792 l 25,1,-1 + 1280 1792 l 25,2,-1 + 1280 1536 l 25,3,-1 + 256 1536 l 25,4,-1 + 256 1024 l 25,5,-1 + 1024 1024 l 25,6,-1 + 1024 768 l 25,7,-1 + 256 768 l 25,8,-1 + 256 0 l 25,9,-1 + 0 0 l 29,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: G +Encoding: 71 71 69 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8+BNffG971$7@ +O:5G_Qr(/!iK0o:j;)k3TU:8r31+P6+@1*T0M)fb!/ZRF%f-o69)nql!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 1465 m 1,0,1 + 0 1792 0 1792 313 1792 c 1,2,3 + 313 1792 313 1792 1280 1792 c 25,4,-1 + 1280 1536 l 1,5,-1 + 313 1536 l 1,6,7 + 256 1536 256 1536 256 1465 c 1,8,9 + 256 1465 256 1465 256 313 c 1,10,11 + 256 256 256 256 313 256 c 1,12,13 + 313 256 313 256 1024 256 c 1,14,-1 + 1024 512 l 1,15,-1 + 824 512 l 0,16,17 + 768 569 768 569 768 667 c 0,18,19 + 768 711 768 711 824 768 c 0,20,21 + 824 768 824 768 1280 768 c 1,22,23 + 1280 768 1280 768 1280 0 c 25,24,-1 + 313 0 l 0,25,26 + 0 0 0 0 0 313 c 1,27,28 + 0 610 0 610 0 1465 c 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: H +Encoding: 72 72 70 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 105 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8C%,9r(&3hH^I +((5nj!Z$kEFCUFB!\6NZ-b!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 0 m 29,0,-1 + 0 1792 l 25,1,-1 + 256 1792 l 25,2,-1 + 256 1024 l 25,3,-1 + 1024 1024 l 25,4,-1 + 1024 1792 l 25,5,-1 + 1280 1792 l 25,6,-1 + 1280 0 l 25,7,-1 + 1024 0 l 25,8,-1 + 1024 768 l 25,9,-1 + 256 768 l 25,10,-1 + 256 0 l 25,11,-1 + 0 0 l 29,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: I +Encoding: 73 73 71 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8+BNffG9Xor#n +'1`([DE!FS&-nOG\/TB9!W_>;(CfiO*cD#Y!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +565 896 m 1,0,1 + 565 896 565 896 1280 182 c 0,2,3 + 1280 182 1280 182 1280 0 c 25,4,5 + 1280 0 1280 0 1099 0 c 24,6,-1 + 331 768 l 24,7,8 + 331 768 331 768 256 768 c 24,9,-1 + 256 0 l 25,10,-1 + 0 0 l 25,11,-1 + 0 1792 l 25,12,-1 + 256 1792 l 25,13,-1 + 256 1024 l 25,14,15 + 256 1024 256 1024 331 1024 c 24,16,-1 + 1099 1792 l 24,17,18 + 1099 1792 1099 1792 1280 1792 c 25,19,-1 + 1280 1611 l 1,20,-1 + 565 896 l 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: L +Encoding: 76 76 74 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 94 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8C%,9n7D"pQEe +Z9ZOJTE+$V$u[?e)us3W#R[5_a@?41!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 0 m 29,0,-1 + 0 1792 l 25,1,-1 + 256 1792 l 25,2,-1 + 256 256 l 25,3,-1 + 1280 256 l 25,4,-1 + 1280 0 l 25,5,-1 + 0 0 l 29,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: M +Encoding: 77 77 75 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8C%,9r(&3hH^( +$PS3@a?%*D5dl1gZ.T=^J?/jD%9J'S2b5Z.!P2#CT:c5ccX[ItTT5+(z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +640 1333 m 1,0,1 + 640 1333 640 1333 1099 1792 c 0,2,3 + 1099 1792 1099 1792 1280 1792 c 25,4,-1 + 1280 0 l 25,5,-1 + 1024 0 l 25,6,-1 + 1024 1280 l 24,7,8 + 1024 1280 1024 1280 949 1280 c 24,9,10 + 949 1280 949 1280 768 1099 c 1,11,-1 + 768 825 l 0,12,13 + 704 768 704 768 640 768 c 128,-1,14 + 576 768 576 768 512 825 c 0,15,-1 + 512 1099 l 1,16,17 + 512 1099 512 1099 331 1280 c 24,18,19 + 331 1280 331 1280 256 1280 c 25,20,-1 + 256 0 l 25,21,-1 + 0 0 l 25,22,-1 + 0 1792 l 25,23,24 + 0 1792 0 1792 181 1792 c 0,25,-1 + 640 1333 l 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: N +Encoding: 78 78 76 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8C%,9r(&3hH^I +((1AK!*pDH3j8[I1N4dp>CfEZ>QMoJC`Yo?J8@0'%0/`c%2/03a,U-"!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +256 1461 m 1,0,-1 + 1024 693 l 1,1,2 + 1024 693 1024 693 1024 1749 c 0,3,4 + 1088 1792 1088 1792 1152 1792 c 0,5,6 + 1152 1792 1152 1792 1280 1749 c 8,7,-1 + 1280 0 l 1,8,-1 + 1024 0 l 1,9,10 + 1024 304 1024 304 1024 331 c 1,11,-1 + 256 1099 l 1,12,13 + 256 1043 256 1043 256 0 c 25,14,-1 + 0 0 l 1,15,-1 + 0 1749 l 0,16,17 + 64 1792 64 1792 128 1792 c 0,18,19 + 128 1792 128 1792 256 1749 c 8,20,21 + 256 1749 256 1749 256 1461 c 1,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: O +Encoding: 79 79 77 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 103 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7*n(j&Ti!cei9?N:'`,npVAI9l+BF +EndImage2 +Fore +SplineSet +949 1536 m 0,0,1 + 949 1536 949 1536 331 1536 c 1,2,3 + 256 1536 256 1536 256 1461 c 1,4,5 + 256 1461 256 1461 256 331 c 1,6,7 + 256 256 256 256 331 256 c 0,8,9 + 331 256 331 256 949 256 c 0,10,11 + 1024 256 1024 256 1024 331 c 1,12,13 + 1024 331 1024 331 1024 1280 c 1,14,15 + 1024 1536 1024 1536 949 1536 c 0,0,1 +1280 512 m 2,16,-1 + 1280 331 l 1,17,18 + 1280 0 1280 0 949 0 c 0,19,20 + 331 0 331 0 331 0 c 0,21,22 + 0 0 0 0 0 331 c 1,23,24 + 0 331 0 331 0 512 c 1,25,26 + 0 512 0 512 0 1280 c 1,27,-1 + 0 1461 l 1,28,29 + 0 1790 0 1790 331 1792 c 0,30,31 + 331 1792 331 1792 949 1792 c 0,32,33 + 1280 1792 1280 1792 1280 1461 c 1,34,35 + 1280 657 1280 657 1280 512 c 2,16,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: P +Encoding: 80 80 78 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 103 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8sb%RgE0H5;TS +A3i[S7MJ$"*n.r'Ug&Cf,!d^b.KBITBGCO-o@;t'!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +949 1792 m 0,0,1 + 1280 1792 1280 1792 1280 1461 c 1,2,3 + 1280 1188 1280 1188 1280 1099 c 1,4,5 + 1280 768 1280 768 949 768 c 0,6,7 + 949 768 949 768 256 768 c 1,8,-1 + 256 0 l 25,9,-1 + 0 0 l 25,10,-1 + 0 1792 l 1,11,12 + 23 1792 23 1792 949 1792 c 0,0,1 +949 1024 m 0,13,14 + 1024 1024 1024 1024 1024 1099 c 1,15,16 + 1024 1408 1024 1408 1024 1461 c 0,17,18 + 1024 1536 1024 1536 949 1536 c 1,19,20 + 949 1536 949 1536 256 1536 c 1,21,-1 + 256 1024 l 1,22,23 + 256 1024 256 1024 949 1024 c 0,13,14 +EndSplineSet +Validated: 1 +EndChar + +StartChar: Q +Encoding: 81 81 79 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7*n(rRpiFpG<]E"bM1U>$2Va97]W8YV[W!-uU'$t5_L%KHJ/!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +512 587 m 25,0,-1 + 512 768 l 24,1,-1 + 693 768 l 25,2,-1 + 1280 181 l 24,3,-1 + 1280 0 l 25,4,-1 + 1099 0 l 24,5,6 + 1099 0 1099 0 512 587 c 25,0,-1 +331 0 m 1,7,8 + 0 0 0 0 0 331 c 1,9,10 + 0 1062 0 1062 0 1461 c 0,11,12 + 0 1792 0 1792 331 1792 c 1,13,-1 + 949 1792 l 2,14,15 + 1280 1792 1280 1792 1280 1461 c 1,16,-1 + 1280 569 l 0,17,18 + 1216 512 1216 512 1152 512 c 0,19,20 + 1152 512 1152 512 1024 569 c 8,21,-1 + 1024 1461 l 2,22,23 + 1024 1536 1024 1536 949 1536 c 1,24,25 + 949 1536 949 1536 331 1536 c 5,26,27 + 256 1536 256 1536 256 1461 c 2,28,29 + 256 1461 256 1461 256 331 c 2,30,31 + 256 256 256 256 331 256 c 1,32,33 + 331 256 331 256 730 256 c 0,34,35 + 768 199 768 199 768 137 c 0,36,37 + 767 73 767 73 730 0 c 0,38,39 + 730 0 730 0 331 0 c 1,7,8 +EndSplineSet +Validated: 1 +EndChar + +StartChar: R +Encoding: 82 82 80 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%RgE0H5;TS +A3i[S7MJ$"*n.r'"K_Zn!4)_r,F]%L![J)X+!&-3J0_?J!W\@^*W&Fp/p[Kt!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +1024 1461 m 0,0,1 + 1024 1536 1024 1536 949 1536 c 24,2,-1 + 256 1536 l 24,3,-1 + 256 1024 l 25,4,-1 + 949 1024 l 0,5,6 + 1024 1024 1024 1024 1024 1099 c 24,7,8 + 1024 1099 1024 1099 1024 1461 c 0,0,1 +693 768 m 25,9,10 + 693 768 693 768 1280 181 c 24,11,12 + 1280 181 1280 181 1280 0 c 25,13,14 + 1280 0 1280 0 1099 0 c 0,15,-1 + 331 768 l 24,16,17 + 331 768 331 768 256 768 c 0,18,-1 + 256 0 l 25,19,-1 + 0 0 l 25,20,-1 + 0 1792 l 1,21,-1 + 949 1792 l 1,22,23 + 1280 1792 1280 1792 1280 1461 c 8,24,25 + 1280 1461 1280 1461 1280 1099 c 2,26,27 + 1280 768 1280 768 949 768 c 8,28,29 + 821 768 821 768 693 768 c 25,9,10 +EndSplineSet +Validated: 1 +EndChar + +StartChar: S +Encoding: 83 83 81 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7+1#-oLFL]o&ScO-lqOEFu6JZKgH3hi\U!641H#5#FNLB%;S!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +949 1792 m 0,0,1 + 1280 1792 1280 1792 1280 1461 c 0,2,3 + 1280 1337 1280 1337 1280 1337 c 0,4,5 + 1223 1280 1223 1280 1152 1280 c 129,-1,6 + 1081 1280 1081 1280 1024 1337 c 1,7,-1 + 1024 1461 l 0,8,9 + 1024 1536 1024 1536 949 1536 c 24,10,-1 + 331 1536 l 0,11,12 + 256 1536 256 1536 256 1461 c 24,13,14 + 256 1218 256 1218 256 1099 c 0,15,16 + 256 1024 256 1024 331 1024 c 24,17,-1 + 949 1024 l 0,18,19 + 1280 1024 1280 1024 1280 693 c 24,20,21 + 1280 346 1280 346 1280 331 c 0,22,23 + 1280 0 1280 0 949 0 c 24,24,-1 + 331 0 l 0,25,26 + 0 0 0 0 0 331 c 0,27,28 + 0 455 0 455 0 455 c 0,29,30 + 65 512 65 512 129 512 c 128,-1,31 + 193 512 193 512 256 455 c 8,32,-1 + 256 331 l 0,33,34 + 256 256 256 256 331 256 c 24,35,-1 + 949 256 l 0,36,37 + 1024 256 1024 256 1024 331 c 24,38,39 + 1024 550 1024 550 1024 693 c 0,40,41 + 1024 768 1024 768 949 768 c 24,42,-1 + 331 768 l 0,43,44 + 0 768 0 768 0 1099 c 24,45,46 + 0 1446 0 1446 0 1461 c 0,47,48 + 0 1792 0 1792 331 1792 c 24,49,50 + 640 1792 640 1792 949 1792 c 0,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: T +Encoding: 84 84 82 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8sb%RU9&*YoTJ +Ocbb,`^VkJ$(6F*4W"k5!8uuL"pBF +EndImage2 +Fore +SplineSet +256 1792 m 25,0,-1 + 256 331 l 0,1,2 + 256 256 256 256 331 256 c 24,3,-1 + 949 256 l 0,4,5 + 1024 256 1024 256 1024 331 c 24,6,-1 + 1024 1792 l 24,7,-1 + 1280 1792 l 25,8,9 + 1280 1792 1280 1792 1280 331 c 0,10,11 + 1280 0 1280 0 949 0 c 24,12,-1 + 331 0 l 0,13,14 + 0 0 0 0 0 331 c 24,15,16 + 0 331 0 331 0 1792 c 25,17,-1 + 256 1792 l 25,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: V +Encoding: 86 86 84 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 103 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8C%,9r(&3hH^I +((5m=$:(253=JBF +EndImage2 +Fore +SplineSet +640 309 m 1,0,1 + 640 309 640 309 1024 693 c 0,2,-1 + 1024 1792 l 24,3,4 + 1024 1792 1024 1792 1280 1792 c 25,5,-1 + 1280 587 l 25,6,-1 + 693 0 l 25,7,8 + 693 0 693 0 587 0 c 24,9,10 + 587 0 587 0 0 587 c 25,11,-1 + 0 1792 l 25,12,-1 + 256 1792 l 25,13,-1 + 256 693 l 0,14,-1 + 640 309 l 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: W +Encoding: 87 87 85 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8C%,9r(&3hH^I +((5nB"mAFn$mX%#OD^.mYaGPN!Tm;t%5T%n!ru:Z%2(b=8,WDf!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +640 459 m 1,0,1 + 181 0 181 0 181 0 c 0,2,3 + 0 0 0 0 0 0 c 153,-1,4 + 0 0 0 0 0 1792 c 25,5,-1 + 256 1792 l 25,6,-1 + 256 437 l 24,7,-1 + 512 693 l 0,8,-1 + 512 967 l 16,9,10 + 575 1024 575 1024 639 1024 c 128,-1,11 + 703 1024 703 1024 768 967 c 0,12,13 + 768 967 768 967 768 693 c 0,14,-1 + 1024 437 l 24,15,-1 + 1024 1792 l 25,16,-1 + 1280 1792 l 25,17,-1 + 1280 0 l 25,18,19 + 1099 0 1099 0 1099 0 c 0,20,21 + 640 459 640 459 640 459 c 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: X +Encoding: 88 88 86 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L,:Kn/++:)bps..=>UQd0V +7.q0\H1/*:bFuki:0SK<8P>1n>>TT7N% +2,#,3n0nECJPQm5%Cd+g'n@9U9bE6aQm-'B!ruA_\La!3?7A:)L&ch"J&dT5?Ho:s)!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +640 971 m 1,0,1 + 640 971 640 971 181 512 c 0,2,3 + 181 512 181 512 0 512 c 25,4,5 + 0 512 0 512 0 693 c 24,6,7 + 0 693 0 693 587 1280 c 24,8,9 + 587 1280 587 1280 693 1280 c 25,10,11 + 693 1280 693 1280 1280 693 c 24,12,13 + 1280 693 1280 693 1280 512 c 25,14,15 + 1280 512 1280 512 1099 512 c 0,16,-1 + 640 971 l 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: underscore +Encoding: 95 95 93 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +0 256 m 29,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 29,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: grave +Encoding: 96 96 94 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8CJNffG9V\638 +OBF +EndImage2 +Fore +SplineSet +768 768 m 1,0,1 + 768 768 768 768 569 768 c 1,2,3 + 512 768 512 768 512 711 c 1,4,5 + 512 711 512 711 512 569 c 1,6,7 + 512 512 512 512 569 512 c 1,8,9 + 569 512 569 512 768 512 c 1,10,11 + 768 512 768 512 768 768 c 1,0,1 +569 256 m 2,12,13 + 256 256 256 256 256 569 c 0,14,15 + 256 640 256 640 256 711 c 0,16,17 + 256 1024 256 1024 569 1024 c 2,18,19 + 569 1024 569 1024 768 1024 c 1,20,21 + 768 1024 768 1024 768 1223 c 1,22,23 + 768 1280 768 1280 711 1280 c 1,24,25 + 711 1280 711 1280 313 1280 c 0,26,27 + 256 1337 256 1337 256 1408 c 0,28,29 + 256 1465 256 1465 313 1536 c 0,30,31 + 313 1536 313 1536 711 1536 c 0,32,33 + 1024 1536 1024 1536 1024 1223 c 0,34,35 + 1024 1202 1024 1202 1024 512 c 1,36,-1 + 1223 512 l 0,37,38 + 1280 446 1280 446 1280 382 c 128,-1,39 + 1280 318 1280 318 1223 256 c 0,40,-1 + 569 256 l 2,12,13 +EndSplineSet +Validated: 1 +EndChar + +StartChar: b +Encoding: 98 98 96 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9V\638 +S?bBd\,qa@fM$lI!'(49d1sJ4i3ERJ3YYqoH\qu4!8Sn#)En`A2-]*Pz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +967 1280 m 0,0,1 + 1280 1280 1280 1280 1280 967 c 0,2,3 + 1280 868 1280 868 1280 768 c 1,4,5 + 1280 256 1280 256 967 256 c 0,6,7 + 967 256 967 256 57 256 c 0,8,9 + 0 256 0 256 0 382 c 0,10,11 + 0 455 0 455 57 512 c 0,12,-1 + 256 512 l 1,13,-1 + 256 1734 l 0,14,15 + 322 1791 322 1791 386 1791 c 128,-1,16 + 450 1791 450 1791 512 1734 c 8,17,-1 + 512 1280 l 1,18,-1 + 967 1280 l 0,0,1 +967 512 m 0,19,20 + 1024 512 1024 512 1024 565 c 0,21,22 + 1024 567 1024 567 1024 569 c 1,23,24 + 1024 896 1024 896 1024 967 c 0,25,26 + 1024 1024 1024 1024 967 1024 c 1,27,28 + 967 1024 967 1024 512 1024 c 1,29,-1 + 512 512 l 1,30,31 + 740 512 740 512 967 512 c 0,19,20 +EndSplineSet +Validated: 1 +EndChar + +StartChar: c +Encoding: 99 99 97 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns2*9E?@_ +,E0`pCa`Bd8.o&:XqJeuBE^[*?n4L^j)kIF:0_Z:!.;!a%Z2pI[/^1,!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +256 1223 m 1,0,1 + 256 1536 256 1536 569 1536 c 1,2,3 + 569 1536 569 1536 1223 1536 c 0,4,5 + 1280 1467 1280 1467 1280 1403 c 128,-1,6 + 1280 1339 1280 1339 1223 1280 c 0,7,-1 + 569 1280 l 1,8,9 + 512 1280 512 1280 512 1223 c 1,10,11 + 512 1223 512 1223 512 569 c 1,12,13 + 512 512 512 512 569 512 c 1,14,15 + 569 512 569 512 1223 512 c 0,16,17 + 1278 446 1278 446 1278 382 c 128,-1,18 + 1278 318 1278 318 1223 256 c 0,19,-1 + 569 256 l 0,20,21 + 256 256 256 256 256 569 c 1,22,23 + 256 896 256 896 256 1223 c 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: d +Encoding: 100 100 98 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8D_*$Z[Q1)J/( +;1Ket'OUqJ@abW^bQO(33aJOOEJ1L],)b'o0g"R2KXB25:z8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +313 256 m 0,0,1 + 0 256 0 256 0 512 c 0,2,3 + 0 512 0 512 0 967 c 1,4,5 + 0 1280 0 1280 313 1280 c 0,6,7 + 540 1280 540 1280 768 1280 c 1,8,-1 + 768 1734 l 0,9,10 + 824 1792 824 1792 895.5 1792 c 128,-1,11 + 967 1792 967 1792 1024 1734 c 0,12,-1 + 1024 512 l 1,13,-1 + 1223 512 l 0,14,15 + 1280 455 1280 455 1280 387 c 0,16,17 + 1280 313 1280 313 1223 255 c 0,18,19 + 1223 255 1223 255 313 256 c 0,0,1 +313 1024 m 1,20,21 + 255 1024 255 1024 255 967 c 1,22,23 + 256 569 256 569 256 569 c 0,24,25 + 256 512 256 512 313 512 c 24,26,27 + 313 512 313 512 768 512 c 0,28,29 + 768 512 768 512 768 1024 c 1,30,-1 + 313 1024 l 1,20,21 +EndSplineSet +Validated: 1 +EndChar + +StartChar: e +Encoding: 101 101 99 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +!skY(YQBmhaBF +EndImage2 +Fore +SplineSet +949 1024 m 0,0,1 + 1024 1024 1024 1024 1024 1099 c 2,2,3 + 1024 1099 1024 1099 1024 1205 c 1,4,5 + 1024 1280 1024 1280 949 1280 c 1,6,7 + 768 1280 768 1280 587 1280 c 0,8,9 + 512 1280 512 1280 512 1205 c 1,10,11 + 512 1143 512 1143 512 1081 c 0,12,13 + 512 1024 512 1024 569 1024 c 1,14,15 + 759 1024 759 1024 949 1024 c 0,0,1 +256 1205 m 0,16,17 + 256 1536 256 1536 587 1536 c 1,18,19 + 587 1536 587 1536 949 1536 c 1,20,21 + 1280 1536 1280 1536 1280 1205 c 0,22,23 + 1280 1205 1280 1205 1280 1099 c 0,24,25 + 1280 768 1280 768 949 768 c 0,26,-1 + 512 768 l 1,27,28 + 512 595 512 595 512 587 c 0,29,30 + 512 512 512 512 587 512 c 1,31,32 + 967 512 967 512 967 512 c 0,33,34 + 1024 512 1024 512 1024 384 c 128,-1,35 + 1024 256 1024 256 967 256 c 0,36,-1 + 587 256 l 0,37,38 + 256 256 256 256 256 587 c 1,39,40 + 256 896 256 896 256 1205 c 0,16,17 +EndSplineSet +Validated: 1 +EndChar + +StartChar: f +Encoding: 102 102 100 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 122 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8D_*$Z[Q1)J/h +.f`.m$q")!&*pF_RK]>[bNg-Et!!nC@e,oG/"i0\g1=!!!!j78?7R +6=>BF +EndImage2 +Fore +SplineSet +1024 1223 m 1,0,1 + 1024 1280 1024 1280 967 1280 c 1,2,3 + 967 1280 967 1280 569 1280 c 0,4,5 + 512 1280 512 1280 512 1223 c 1,6,7 + 512 1223 512 1223 512 825 c 1,8,9 + 512 768 512 768 569 768 c 1,10,11 + 967 768 967 768 967 768 c 0,12,13 + 1024 768 1024 768 1024 825 c 1,14,15 + 1024 825 1024 825 1024 1223 c 1,0,1 +569 512 m 2,16,17 + 256 512 256 512 256 825 c 0,18,19 + 256 825 256 825 256 1223 c 0,20,21 + 256 1536 256 1536 569 1536 c 0,22,23 + 768 1536 768 1536 967 1536 c 1,24,25 + 1280 1536 1280 1536 1280 1223 c 0,26,27 + 1280 612 1280 612 1280 313 c 0,28,29 + 1280 0 1280 0 967 0 c 1,30,31 + 967 0 967 0 512 0 c 1,32,-1 + 512 256 l 1,33,-1 + 967 256 l 1,34,35 + 1024 256 1024 256 1024 313 c 1,36,37 + 1024 413 1024 413 1024 512 c 1,38,-1 + 569 512 l 2,16,17 +EndSplineSet +Validated: 1 +EndChar + +StartChar: h +Encoding: 104 104 102 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8CJNffG9V\638 +S?bBd\,qa@fM$lI!'(49d1sJ4i3J*1!_,N5"9Oqn#t!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +967 1280 m 17,0,1 + 1280 1280 1280 1280 1280 967 c 0,2,3 + 1280 836 1280 836 1280 256 c 25,4,-1 + 1024 256 l 1,5,-1 + 1024 967 l 1,6,7 + 1024 1024 1024 1024 967 1024 c 1,8,9 + 967 1024 967 1024 512 1024 c 1,10,-1 + 512 256 l 25,11,-1 + 256 256 l 1,12,-1 + 256 1734 l 0,13,14 + 326 1792 326 1792 390 1792 c 128,-1,15 + 454 1792 454 1792 512 1734 c 8,16,-1 + 512 1280 l 1,17,-1 + 967 1280 l 17,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: i +Encoding: 105 105 103 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HNZ +$?-jc=$Y+8'Q]BrE"e>O:mbVo0]QRuZ3h?Y#F>NYEWDm9$5>J927EPc!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +512 1223 m 0,0,1 + 569 1280 569 1280 639 1280 c 1,2,3 + 711 1280 711 1280 768 1223 c 1,4,-1 + 768 569 l 0,5,6 + 768 512 768 512 824 512 c 24,7,-1 + 1024 512 l 1,8,-1 + 1024 256 l 25,9,-1 + 256 256 l 25,10,-1 + 256 512 l 1,11,-1 + 454 512 l 0,12,13 + 512 512 512 512 512 569 c 16,14,15 + 512 569 512 569 512 1223 c 0,0,1 +512 1792 m 24,16,-1 + 768 1792 l 24,17,-1 + 768 1536 l 25,18,-1 + 512 1536 l 25,19,20 + 512 1536 512 1536 512 1792 c 24,16,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: j +Encoding: 106 106 104 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8D_*$Z[Q1)J/( +;1QnF'EnV6^b?iYJ78RT"k\cg.0c7AEZ@U^2FdfKcm&u1G:MDDz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +768 1792 m 25,0,-1 + 1024 1792 l 25,1,-1 + 1024 1536 l 25,2,-1 + 768 1536 l 25,3,-1 + 768 1792 l 25,0,-1 +1024 313 m 0,4,5 + 1024 2 1024 2 711 0 c 0,6,7 + 711 0 711 0 569 0 c 0,8,9 + 256 0 256 0 256 313 c 0,10,11 + 256 313 256 313 256 455 c 0,12,13 + 313 512 313 512 378 512 c 0,14,15 + 454 512 454 512 512 455 c 0,16,-1 + 512 302 l 0,17,18 + 512 256 512 256 569 256 c 0,19,20 + 640 256 640 256 711 256 c 0,21,22 + 768 256 768 256 768 302 c 0,23,24 + 768 302 768 302 768 1223 c 0,25,26 + 830 1280 830 1280 893 1280 c 0,27,28 + 958 1280 958 1280 1024 1223 c 0,29,30 + 1024 1223 1024 1223 1024 313 c 0,4,5 +EndSplineSet +Validated: 1 +EndChar + +StartChar: k +Encoding: 107 107 105 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9V\638 +A6F#n-ji5&kVg9m@$:_]$s*GWM/GG5!Y>U+,"A4J?>flF>MTu&gl3mSz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +569 1024 m 17,0,1 + 569 1024 569 1024 1081 1536 c 1,2,-1 + 1280 1536 l 1,3,-1 + 1280 1337 l 1,4,-1 + 839 896 l 1,5,6 + 839 896 839 896 1280 455 c 1,7,-1 + 1280 256 l 1,8,-1 + 1081 256 l 1,9,-1 + 569 768 l 1,10,11 + 569 768 569 768 512 768 c 25,12,-1 + 512 256 l 25,13,-1 + 256 256 l 25,14,-1 + 256 1792 l 25,15,-1 + 512 1792 l 25,16,-1 + 512 1024 l 25,17,-1 + 569 1024 l 17,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: l +Encoding: 108 108 106 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 108 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8CJNffG9N3T>a +/&5d'=91=N0JP%+!'(Yp?o6)P&Bt8#n2V*]Yf@(bT*B[=z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +256 1792 m 24,0,-1 + 768 1792 l 24,1,-1 + 768 512 l 25,2,-1 + 1024 512 l 25,3,-1 + 1024 256 l 25,4,-1 + 256 256 l 25,5,-1 + 256 512 l 25,6,-1 + 512 512 l 25,7,-1 + 512 1536 l 25,8,-1 + 256 1536 l 25,9,10 + 256 1536 256 1536 256 1792 c 24,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: m +Encoding: 109 109 107 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns22,9nE8 +#_N,9#'6F?fE@9f+A!E0T`A3qSP@`GkW7)dN.ehM!'R@m&B%c/r;Zft!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +454 1536 m 2,0,1 + 639 1536 639 1536 639 1280 c 1,2,3 + 639 1536 639 1536 824 1536 c 0,4,5 + 824 1536 824 1536 967 1536 c 0,6,7 + 1280 1536 1280 1536 1280 1223 c 1,8,9 + 1280 740 1280 740 1280 256 c 1,10,11 + 1280 256 1280 256 1024 256 c 1,12,-1 + 1024 1223 l 2,13,14 + 1024 1280 1024 1280 967 1280 c 1,15,16 + 967 1280 967 1280 824 1280 c 0,17,18 + 768 1280 768 1280 768 1223 c 0,19,20 + 768 1223 768 1223 768 256 c 1,21,-1 + 512 256 l 1,22,-1 + 512 1223 l 2,23,24 + 512 1280 512 1280 454 1280 c 0,25,26 + 454 1280 454 1280 313 1280 c 0,27,28 + 256 1280 256 1280 256 1223 c 2,29,-1 + 256 256 l 1,30,-1 + 0 256 l 25,31,-1 + 0 1536 l 1,32,-1 + 454 1536 l 2,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: n +Encoding: 110 110 108 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns2*Lh(%, +KW@I!&8hP?!ec[NK64pE^l:Th:p,<\BJ3\1!WY^j&I&QkSpLG;!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +967 1536 m 17,0,1 + 1280 1536 1280 1536 1280 1223 c 1,2,3 + 1280 683 1280 683 1280 256 c 25,4,-1 + 1024 256 l 1,5,-1 + 1024 1223 l 1,6,7 + 1024 1280 1024 1280 967 1280 c 1,8,9 + 967 1280 967 1280 512 1280 c 1,10,-1 + 512 256 l 25,11,-1 + 256 256 l 25,12,-1 + 256 1536 l 1,13,-1 + 967 1536 l 17,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: o +Encoding: 111 111 109 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 119 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +!skY(YQBmhapkS,:]Uqp-*kq^ScUEm.=rFq9EP8Yq@aDRRWI9b!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +1024 1223 m 1,0,1 + 1024 1280 1024 1280 967 1280 c 1,2,3 + 953 1280 953 1280 569 1280 c 0,4,5 + 512 1280 512 1280 512 1223 c 1,6,7 + 512 1223 512 1223 512 569 c 1,8,9 + 512 512 512 512 569 512 c 1,10,11 + 569 512 569 512 967 512 c 0,12,13 + 1024 512 1024 512 1024 569 c 1,14,15 + 1024 569 1024 569 1024 1223 c 1,0,1 +256 1223 m 0,16,17 + 256 1536 256 1536 583 1536 c 1,18,19 + 775 1536 775 1536 967 1536 c 1,20,21 + 1280 1536 1280 1536 1280 1223 c 0,22,23 + 1280 691 1280 691 1280 569 c 0,24,25 + 1280 256 1280 256 967 256 c 1,26,27 + 768 256 768 256 569 256 c 1,28,29 + 256 256 256 256 256 569 c 0,30,31 + 256 1056 256 1056 256 1223 c 0,16,17 +EndSplineSet +Validated: 1 +EndChar + +StartChar: p +Encoding: 112 112 110 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns2*Lh(%, +KW@I!&8hP?!ec[NK64pE^l:ThJ?8g._/uDU!EXe(!AfP)'`_rY'+E&U*NK/?!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +967 768 m 1,0,1 + 1024 768 1024 768 1024 825 c 1,2,3 + 1024 825 1024 825 1024 1223 c 1,4,5 + 1024 1280 1024 1280 967 1280 c 1,6,7 + 967 1280 967 1280 512 1280 c 5,8,9 + 512 1280 512 1280 512 768 c 4,10,11 + 512 768 512 768 967 768 c 1,0,1 +967 1536 m 17,12,13 + 1280 1536 1280 1536 1280 1223 c 0,14,15 + 1280 867 1280 867 1280 825 c 0,16,17 + 1280 512 1280 512 967 512 c 9,18,19 + 967 512 967 512 512 512 c 1,20,-1 + 512 0 l 25,21,-1 + 256 0 l 25,22,-1 + 256 1536 l 1,23,-1 + 967 1536 l 17,12,13 +EndSplineSet +Validated: 1 +EndChar + +StartChar: q +Encoding: 113 113 111 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns2*Lh(%, +KW@I!O9m0=&k&(:koadG811\X0V'm9C][1/TUQ,cA6]lWK/u9:z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +313 1280 m 1,0,1 + 256 1280 256 1280 256 1223 c 1,2,3 + 256 1223 256 1223 256 825 c 1,4,5 + 256 768 256 768 313 768 c 1,6,7 + 313 768 313 768 768 768 c 1,8,-1 + 768 1280 l 1,9,-1 + 313 1280 l 1,0,1 +313 512 m 1,10,11 + 0 512 0 512 0 825 c 0,12,13 + 0 1181 0 1181 0 1223 c 0,14,15 + 0 1536 0 1536 313 1536 c 1,16,17 + 512 1536 512 1536 722 1536 c 0,18,-1 + 1024 1536 l 25,19,-1 + 1024 256 l 1,20,-1 + 1223 256 l 0,21,22 + 1279 190 1279 190 1279 126 c 128,-1,23 + 1279 62 1279 62 1223 0 c 8,24,-1 + 768 0 l 1,25,-1 + 768 512 l 1,26,-1 + 313 512 l 1,10,11 +EndSplineSet +Validated: 1 +EndChar + +StartChar: r +Encoding: 114 114 112 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +Qij'kCm[[-(]u%7br3'HfH`bOiU!pq/^h#XL1]XA\%2#Am_)hVs!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +512 1280 m 1,0,1 + 512 1536 512 1536 824 1536 c 1,2,3 + 824 1536 824 1536 1280 1536 c 1,4,-1 + 1280 1280 l 1,5,-1 + 824 1280 l 1,6,7 + 512 1280 512 1280 512 1024 c 1,8,9 + 512 1024 512 1024 512 256 c 1,10,-1 + 256 256 l 25,11,-1 + 256 1536 l 25,12,-1 + 512 1536 l 25,13,-1 + 512 1280 l 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: s +Encoding: 115 115 113 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 122 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8Bu3Ns2*Lh(%, +6rA_U-s-L@(0M2O2:r7t,fg[AP<]K6D?),;.7?&pWuE`,i3FH#&-14%((g]?(5Mqj!!#SZ:.26O +@"J@Y +EndImage2 +Fore +SplineSet +1280 711 m 0,0,1 + 1280 710 1280 710 1280 569 c 0,2,3 + 1280 256 1280 256 967 256 c 0,4,-1 + 313 256 l 0,5,6 + 256 321 256 321 256 385 c 128,-1,7 + 256 449 256 449 313 512 c 8,8,-1 + 967 512 l 0,9,10 + 1024 512 1024 512 1024 569 c 16,11,12 + 1024 569 1024 569 1024 711 c 0,13,14 + 1024 768 1024 768 967 768 c 0,15,-1 + 569 768 l 0,16,17 + 256 768 256 768 256 1081 c 0,18,19 + 256 1081 256 1081 256 1223 c 0,20,21 + 256 1536 256 1536 569 1536 c 1,22,23 + 569 1536 569 1536 1223 1536 c 0,24,25 + 1280 1467 1280 1467 1280 1403 c 128,-1,26 + 1280 1339 1280 1339 1223 1280 c 1,27,-1 + 569 1280 l 0,28,29 + 512 1280 512 1280 512 1223 c 0,30,31 + 512 1223 512 1223 512 1081 c 0,32,33 + 512 1024 512 1024 569 1024 c 24,34,-1 + 967 1024 l 0,35,36 + 1280 1024 1280 1024 1280 711 c 0,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: t +Encoding: 116 116 114 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CNNffG9`^HN: +$=K#N)Hd5G!R);rNM->T!1aRC"1eVo%p&`d*iBrbWj0)8!277@%#@LO^An66!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +768 569 m 1,0,1 + 768 512 768 512 824 512 c 0,2,3 + 824 512 824 512 1024 512 c 1,4,5 + 1024 512 1024 512 1024 256 c 1,6,-1 + 824 256 l 17,7,8 + 512 256 512 256 512 569 c 1,9,10 + 512 1232 512 1232 512 1280 c 1,11,-1 + 313 1280 l 0,12,13 + 256 1342 256 1342 256 1406 c 128,-1,14 + 256 1470 256 1470 313 1536 c 0,15,-1 + 512 1536 l 1,16,-1 + 512 1734 l 0,17,18 + 576 1792 576 1792 640 1792 c 128,-1,19 + 704 1792 704 1792 768 1734 c 8,20,-1 + 768 1536 l 1,21,-1 + 967 1536 l 0,22,23 + 1024 1478 1024 1478 1024 1414 c 128,-1,24 + 1024 1350 1024 1350 967 1280 c 0,25,-1 + 768 1280 l 1,26,-1 + 768 569 l 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: u +Encoding: 117 117 115 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +>TGR=,Y4F3E:$aE"AN8)B``P_h/8Tg?j/5Q0L94f!#\N='5qJ>+ohTC!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +512 569 m 1,0,1 + 512 512 512 512 569 512 c 1,2,3 + 569 512 569 512 1024 512 c 1,4,-1 + 1024 1466 l 0,5,6 + 1090 1535 1090 1535 1154 1535 c 128,-1,7 + 1218 1535 1218 1535 1279 1465 c 8,8,-1 + 1280 256 l 1,9,-1 + 569 256 l 17,10,11 + 256 256 256 256 256 569 c 1,12,13 + 256 1465 256 1465 256 1465 c 0,14,15 + 313 1536 313 1536 382 1536 c 0,16,17 + 454 1536 454 1536 512 1465 c 0,18,-1 + 512 569 l 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: v +Encoding: 118 118 116 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns22,9nFj +)K\/O'0oSktT]l#NXfm`3:CAe_QB1QT#rk1AhRHz8OZBB +Y!QNJ +EndImage2 +Fore +SplineSet +639 714 m 129,-1,1 + 639 714 639 714 181 256 c 1,2,3 + 0 256 0 256 0 437 c 1,4,5 + 457 896 457 896 457 896 c 129,-1,6 + 457 896 457 896 0 1355 c 1,7,8 + 0 1536 0 1536 181 1536 c 1,9,10 + 640 1077 640 1077 640 1077 c 129,-1,11 + 640 1077 640 1077 1099 1536 c 1,12,13 + 1280 1536 1280 1536 1280 1355 c 1,14,15 + 822 897 822 897 822 897 c 129,-1,16 + 822 897 822 897 1280 437 c 1,17,18 + 1280 256 1280 256 1099 256 c 1,19,0 + 639 714 639 714 639 714 c 129,-1,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: y +Encoding: 121 121 119 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +>TGR=,Y4F3E:$aE/0H[/440%BWJ+OW;M<:^?kYf*@4%Wt!W]..&.jd;TcO16!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +512 825 m 1,0,1 + 512 768 512 768 569 768 c 1,2,3 + 569 768 569 768 1024 768 c 1,4,-1 + 1024 1465 l 0,5,6 + 1024 1536 1024 1536 1152 1536 c 129,-1,7 + 1280 1536 1280 1536 1280 1465 c 1,8,-1 + 1280 313 l 0,9,10 + 1280 0 1280 0 967 0 c 1,11,-1 + 569 0 l 0,12,13 + 512 63 512 63 512 127 c 128,-1,14 + 512 191 512 191 569 256 c 8,15,-1 + 967 256 l 1,16,17 + 1024 256 1024 256 1024 313 c 1,18,19 + 1024 413 1024 413 1024 512 c 0,20,-1 + 569 512 l 1,21,22 + 256 512 256 512 256 825 c 1,23,24 + 256 1180 256 1180 256 1465 c 0,25,26 + 256 1536 256 1536 387 1536 c 0,27,28 + 512 1536 512 1536 512 1465 c 0,29,-1 + 512 825 l 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: z +Encoding: 122 122 120 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 111 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8Bu3Ns2BOMigR +fh`Gp%O32C"#:s/"Pa?#P<7,XDc.Es"r<3WK-qdMi2GrhD[X!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +1206 1280 m 0,0,1 + 1206 1280 1206 1280 512 587 c 25,2,3 + 512 586 512 586 512 569 c 0,4,5 + 512 512 512 512 569 512 c 24,6,-1 + 1223 512 l 0,7,8 + 1280 512 1280 512 1280 385 c 0,9,10 + 1280 256 1280 256 1223 256 c 0,11,12 + 640 256 640 256 57 256 c 0,13,14 + 0 256 0 256 0 373 c 0,15,16 + 0 512 0 512 57 512 c 0,17,-1 + 75 512 l 24,18,19 + 75 512 75 512 768 1205 c 8,20,21 + 768 1205 768 1205 768 1223 c 0,22,23 + 768 1280 768 1280 711 1280 c 24,24,-1 + 57 1280 l 0,25,26 + 0 1344 0 1344 0 1408 c 128,-1,27 + 0 1472 0 1472 57 1536 c 0,28,29 + 57 1536 57 1536 1205 1536 c 0,30,31 + 1206 1535 1206 1535 1206 1280 c 0,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: braceleft +Encoding: 123 123 121 +Width: 1280 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h +.f`.M1CUDd6Ru+9X8nT)O;b>)OO;_ILF[nDL6[A&!LG58&4@'?qd>sHz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +512 1465 m 1,0,1 + 512 1792 512 1792 825 1792 c 1,2,3 + 825 1792 825 1792 1024 1792 c 25,4,-1 + 1024 1536 l 1,5,-1 + 824 1536 l 1,6,7 + 768 1536 768 1536 768 1465 c 1,8,9 + 768 1454 768 1454 768 1081 c 0,10,11 + 768 896 768 896 666 896 c 1,12,13 + 768 896 768 896 768 711 c 0,14,15 + 768 711 768 711 768 313 c 1,16,17 + 768 256 768 256 824 256 c 1,18,19 + 1024 256 1024 256 1024 256 c 1,20,-1 + 1024 0 l 25,21,-1 + 825 0 l 0,22,23 + 512 0 512 0 512 313 c 1,24,25 + 512 313 512 313 512 711 c 1,26,27 + 512 768 512 768 454 768 c 0,28,29 + 454 768 454 768 256 768 c 0,30,31 + 256 768 256 768 256 1024 c 1,32,33 + 454 1024 454 1024 454 1024 c 1,34,35 + 512 1024 512 1024 512 1081 c 1,36,37 + 512 1273 512 1273 512 1465 c 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: bar +Encoding: 124 124 122 +Width: 1024 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 96 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ +$;a-Q35d>_jV532ZuZhP5\Z!+&6obWr%P+Tz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +768 1465 m 1,0,1 + 768 1081 768 1081 768 1081 c 1,2,3 + 768 1024 768 1024 824 1024 c 1,4,5 + 924 1024 924 1024 1024 1024 c 1,6,7 + 1024 768 1024 768 1024 768 c 1,8,9 + 824 768 824 768 824 768 c 1,10,11 + 768 768 768 768 768 711 c 1,12,13 + 768 313 768 313 768 313 c 1,14,15 + 768 0 768 0 455 0 c 0,16,17 + 455 0 455 0 256 0 c 25,18,-1 + 256 256 l 1,19,20 + 355 256 355 256 454 256 c 1,21,22 + 512 256 512 256 512 313 c 1,23,24 + 512 711 512 711 512 711 c 0,25,26 + 512 896 512 896 614 896 c 1,27,28 + 512 896 512 896 512 1081 c 0,29,30 + 512 1460 512 1460 512 1465 c 1,31,32 + 512 1536 512 1536 454 1536 c 1,33,34 + 454 1536 454 1536 256 1536 c 1,35,-1 + 256 1792 l 25,36,-1 + 455 1792 l 1,37,38 + 768 1792 768 1792 768 1465 c 1,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: asciitilde +Encoding: 126 126 124 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 105 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8Bu3Ns4^$5aWu +;%.":nW3q%SHMiNf:>V!3`+$*EX4]=!2nui$0`_sf`2!P!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +1280 1099 m 0,0,1 + 1280 768 1280 768 949 768 c 24,2,-1 + 331 768 l 0,3,4 + 256 768 256 768 256 693 c 24,5,-1 + 256 512 l 25,6,-1 + 0 512 l 25,7,8 + 0 514 0 514 0 693 c 0,9,10 + 0 1024 0 1024 331 1024 c 24,11,-1 + 949 1024 l 0,12,13 + 1024 1024 1024 1024 1024 1099 c 24,14,-1 + 1024 1280 l 25,15,-1 + 1280 1280 l 25,16,17 + 1280 1280 1280 1280 1280 1099 c 0,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni007F +Encoding: 127 127 125 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 91 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd69$d]%-ia6ZR0X$I$,$09!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +0 1280 m 29,0,-1 + 1280 1280 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 1280 l 29,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni0080 +Encoding: 128 128 126 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 125 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$Na!+r&.AZ[o_qq3)XZ$a +jG,(OU,Gt71,;FPS34p%"?8b+Wp>g8X:*+q!>pf44u^"9-V`4j,f;.Nmj\#SrL?s7HN4$G!(fUS +7'8jaJcGcN +EndImage2 +Fore +SplineSet +949 1792 m 0,0,1 + 1280 1792 1280 1792 1280 1461 c 0,2,3 + 1280 1461 1280 1461 1280 1280 c 1,4,5 + 1280 1280 1280 1280 1024 1280 c 0,6,-1 + 1024 1461 l 0,7,8 + 1024 1536 1024 1536 949 1536 c 0,9,-1 + 331 1536 l 0,10,11 + 256 1536 256 1536 256 1461 c 0,12,13 + 256 1461 256 1461 256 843 c 0,14,15 + 256 768 256 768 331 768 c 0,16,-1 + 949 768 l 2,17,18 + 1024 768 1024 768 1024 843 c 2,19,-1 + 1024 1024 l 0,20,21 + 1024 1024 1024 1024 1280 1024 c 1,22,23 + 1280 1024 1280 1024 1280 843 c 0,24,25 + 1280 512 1280 512 949 512 c 0,26,-1 + 768 512 l 25,27,-1 + 768 331 l 0,28,29 + 768 0 768 0 437 0 c 0,30,31 + 437 0 437 0 0 0 c 1,32,-1 + 0 256 l 1,33,-1 + 437 256 l 0,34,35 + 512 256 512 256 512 331 c 0,36,37 + 512 331 512 331 512 512 c 1,38,39 + 512 512 512 512 331 512 c 0,40,41 + 0 512 0 512 0 843 c 0,42,43 + 0 843 0 843 0 1461 c 0,44,45 + 0 1792 0 1792 331 1792 c 0,46,47 + 331 1792 331 1792 949 1792 c 0,0,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni0081 +Encoding: 129 129 127 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9Xot.% +QD<(8YSD-KYqRS-^]H8+jAU0P_e]DTJ$fY!QI[jFz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +512 1280 m 25,0,-1 + 512 331 l 0,1,2 + 512 256 512 256 587 256 c 24,3,-1 + 1024 256 l 24,4,-1 + 1024 1280 l 25,5,-1 + 1280 1280 l 25,6,-1 + 1280 0 l 25,7,-1 + 587 0 l 0,8,9 + 256 0 256 0 256 331 c 24,10,11 + 256 331 256 331 256 1280 c 25,12,-1 + 512 1280 l 25,0,-1 +1024 1792 m 24,13,-1 + 1280 1792 l 25,14,-1 + 1280 1536 l 24,15,-1 + 1024 1536 l 24,16,17 + 1024 1536 1024 1536 1024 1792 c 24,13,-1 +256 1792 m 25,18,-1 + 512 1792 l 25,19,-1 + 512 1536 l 24,20,-1 + 256 1536 l 24,21,22 + 256 1536 256 1536 256 1792 c 25,18,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni0082 +Encoding: 130 130 128 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8D_*$Z[Q!sg+R +()R9%J^#kW'4;_d1fscP2ol-7BF +EndImage2 +Fore +SplineSet +587 512 m 0,0,1 + 512 512 512 512 512 437 c 0,2,3 + 512 331 512 331 512 331 c 0,4,5 + 512 256 512 256 587 256 c 0,6,7 + 587 256 587 256 768 256 c 1,8,9 + 768 256 768 256 768 512 c 1,10,11 + 768 512 768 512 587 512 c 0,0,1 +1024 1461 m 1,12,13 + 1024 1536 1024 1536 949 1536 c 24,14,15 + 949 1536 949 1536 587 1536 c 0,16,17 + 512 1536 512 1536 512 1461 c 1,18,19 + 512 1461 512 1461 512 1280 c 1,20,21 + 512 1280 512 1280 949 1280 c 0,22,23 + 1024 1280 1024 1280 1024 1355 c 0,24,25 + 1024 1355 1024 1355 1024 1461 c 1,12,13 +949 1792 m 0,26,27 + 1280 1792 1280 1792 1280 1461 c 24,28,29 + 1280 1461 1280 1461 1280 1355 c 0,30,31 + 1280 1024 1280 1024 1024 1024 c 0,32,33 + 1024 640 1024 640 1024 331 c 0,34,35 + 1024 256 1024 256 1099 256 c 24,36,-1 + 1223 256 l 0,37,38 + 1280 256 1280 256 1280 127 c 0,39,40 + 1280 0 1280 0 1223 0 c 24,41,42 + 1223 0 1223 0 437 0 c 0,43,44 + 256 0 256 0 256 181 c 24,45,46 + 256 181 256 181 256 587 c 0,47,48 + 256 768 256 768 437 768 c 24,49,-1 + 768 768 l 25,50,-1 + 768 1024 l 24,51,-1 + 256 1024 l 24,52,53 + 256 1408 256 1408 256 1461 c 0,54,55 + 256 1792 256 1792 587 1792 c 24,56,57 + 587 1792 587 1792 949 1792 c 0,26,27 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni0084 +Encoding: 132 132 130 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9X9;!; +X(N\g!Xl:?+?$fj?n4KokRoRb0MI!g^hBqY+:^";i!NjUJC-%a!-E&l&P`+b4obQ_!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +587 512 m 0,0,1 + 512 512 512 512 512 437 c 24,2,3 + 512 363 512 363 512 331 c 0,4,5 + 512 256 512 256 587 256 c 24,6,-1 + 768 256 l 25,7,-1 + 768 512 l 17,8,9 + 768 512 768 512 587 512 c 0,0,1 +256 1280 m 24,10,11 + 256 1280 256 1280 768 1280 c 0,12,13 + 1024 1280 1024 1280 1024 1024 c 24,14,-1 + 1024 331 l 0,15,16 + 1024 256 1024 256 1099 256 c 24,17,-1 + 1223 256 l 0,18,19 + 1280 256 1280 256 1280 127 c 0,20,21 + 1280 -0 1280 -0 1223 0 c 24,22,23 + 1223 0 1223 0 512 0 c 0,24,25 + 256 0 256 0 256 256 c 24,26,27 + 256 256 256 256 256 512 c 128,-1,28 + 256 768 256 768 512 768 c 24,29,-1 + 768 768 l 25,30,31 + 768 898 768 898 768 949 c 0,32,33 + 768 1024 768 1024 693 1024 c 24,34,-1 + 256 1024 l 24,35,36 + 256 1152 256 1152 256 1280 c 24,10,11 +768 1792 m 25,37,-1 + 1024 1792 l 25,38,-1 + 1024 1536 l 25,39,-1 + 768 1536 l 17,40,41 + 768 1536 768 1536 768 1792 c 25,37,-1 +256 1792 m 9,42,-1 + 512 1792 l 25,43,-1 + 512 1536 l 25,44,-1 + 256 1536 l 17,45,46 + 256 1536 256 1536 256 1792 c 9,42,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni0085 +Encoding: 133 133 131 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 123 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?L$Nf+5E+:&'Ro`)[2:,ig- +#3'.E838Xl;KrLigpH%'bhedP@F?Zl!%HH+?63E+!A_Jaqaj=VkhH]N],(kp9",<2!!!!j78?7R +6=>BF +EndImage2 +Fore +SplineSet +587 512 m 0,0,1 + 512 512 512 512 512 437 c 0,2,3 + 512 346 512 346 512 331 c 0,4,5 + 512 256 512 256 587 256 c 0,6,7 + 587 256 587 256 768 256 c 24,8,9 + 768 256 768 256 768 512 c 24,10,11 + 768 512 768 512 587 512 c 0,0,1 +0 1792 m 25,12,13 + 2 1792 2 1792 437 1792 c 0,14,15 + 768 1792 768 1792 768 1461 c 24,16,-1 + 768 1280 l 0,17,-1 + 843 1280 l 0,18,19 + 1024 1280 1024 1280 1024 1099 c 1,20,-1 + 1024 256 l 0,21,-1 + 1223 256 l 0,22,23 + 1280 256 1280 256 1280 127 c 17,24,25 + 1280 0 1280 0 1223 0 c 0,26,27 + 830 0 830 0 437 0 c 0,28,29 + 256 0 256 0 256 181 c 1,30,-1 + 256 587 l 1,31,32 + 256 768 256 768 437 768 c 0,33,-1 + 768 768 l 1,34,-1 + 768 949 l 17,35,36 + 768 1024 768 1024 693 1024 c 24,37,-1 + 256 1024 l 24,38,39 + 256 1024 256 1024 256 1280 c 24,40,-1 + 512 1280 l 24,41,42 + 512 1282 512 1282 512 1461 c 0,43,44 + 512 1536 512 1536 437 1536 c 24,45,-1 + 0 1536 l 24,46,47 + 0 1536 0 1536 0 1792 c 25,12,13 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni0086 +Encoding: 134 134 132 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 124 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$N_'QX+:J@3q#<"J$)@]t +pZ@+3S;se'nECd)3;rME"cVsJC-(:i/RpHTM'mT!&S7)$go"b$NrrXke_RMi+2)FlSN("#8$-k"jq*#S+AB?^DV!!#SZ:.26O +@"J@Y +EndImage2 +Fore +SplineSet +949 1280 m 0,0,1 + 1024 1280 1024 1280 1024 1355 c 24,2,3 + 1024 1446 1024 1446 1024 1461 c 0,4,5 + 1024 1536 1024 1536 949 1536 c 24,6,-1 + 587 1536 l 0,7,8 + 512 1536 512 1536 512 1461 c 24,9,10 + 512 1370 512 1370 512 1355 c 0,11,12 + 512 1280 512 1280 587 1280 c 24,13,14 + 587 1280 587 1280 949 1280 c 0,0,1 +1206 1154 m 1,15,16 + 1280 1105 1280 1105 1280 967 c 0,17,18 + 1280 967 1280 967 1280 843 c 0,19,20 + 1280 512 1280 512 949 512 c 0,21,22 + 949 512 949 512 512 512 c 1,23,24 + 512 384 512 384 512 331 c 0,25,26 + 512 256 512 256 587 256 c 1,27,28 + 777 256 777 256 967 256 c 0,29,30 + 1024 256 1024 256 1024 127 c 0,31,32 + 1024 0 1024 0 967 0 c 0,33,34 + 777 0 777 0 587 0 c 0,35,36 + 256 0 256 0 256 331 c 1,37,38 + 256 649 256 649 256 967 c 0,39,40 + 256 1102 256 1102 329 1154 c 1,41,42 + 256 1207 256 1207 256 1355 c 0,43,44 + 256 1458 256 1458 256 1461 c 0,45,46 + 256 1792 256 1792 587 1792 c 24,47,48 + 949 1792 949 1792 949 1792 c 0,49,50 + 1280 1792 1280 1792 1280 1461 c 24,51,52 + 1280 1461 1280 1461 1280 1355 c 0,53,54 + 1280 1211 1280 1211 1206 1154 c 1,15,16 +949 768 m 0,55,56 + 1024 768 1024 768 1024 843 c 2,57,58 + 1024 843 1024 843 1024 949 c 1,59,60 + 1024 1024 1024 1024 949 1024 c 1,61,62 + 587 1024 587 1024 587 1024 c 0,63,64 + 512 1024 512 1024 512 949 c 1,65,66 + 512 858 512 858 512 843 c 0,67,68 + 512 768 512 768 587 768 c 1,69,70 + 587 768 587 768 949 768 c 0,55,56 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni0089 +Encoding: 137 137 135 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9Xot.% +Q6XNTQmq716/li65Y_>gF@@`'/mNJ1JFs)6ai0UTp3g!;V?`)AUn4]`8$4!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 1536 l 24,2,-1 + 1024 1536 l 24,3,4 + 1024 1536 1024 1536 1024 1792 c 25,0,-1 +256 1792 m 24,5,-1 + 512 1792 l 24,6,-1 + 512 1536 l 24,7,-1 + 256 1536 l 24,8,9 + 256 1536 256 1536 256 1792 c 24,5,-1 +949 768 m 0,10,11 + 1024 768 1024 768 1024 843 c 2,12,13 + 1024 843 1024 843 1024 949 c 1,14,15 + 1024 1024 1024 1024 949 1024 c 1,16,17 + 587 1024 587 1024 587 1024 c 0,18,19 + 512 1024 512 1024 512 949 c 1,20,21 + 512 858 512 858 512 843 c 0,22,23 + 512 768 512 768 587 768 c 1,24,25 + 587 768 587 768 949 768 c 0,10,11 +256 967 m 0,26,27 + 256 1280 256 1280 569 1280 c 1,28,29 + 569 1280 569 1280 967 1280 c 1,30,31 + 1280 1280 1280 1280 1280 967 c 0,32,33 + 1280 825 1280 825 1280 825 c 0,34,35 + 1280 512 1280 512 967 512 c 24,36,-1 + 512 512 l 1,37,38 + 512 384 512 384 512 331 c 0,39,40 + 512 256 512 256 587 256 c 1,41,42 + 587 256 587 256 967 256 c 0,43,44 + 1024 256 1024 256 1024 127 c 0,45,46 + 1024 0 1024 0 967 0 c 0,47,-1 + 569 0 l 0,48,49 + 256 0 256 0 256 313 c 1,50,51 + 256 960 256 960 256 967 c 0,26,27 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni008A +Encoding: 138 138 136 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%]fYs3[Tpk +#W"5fe7&J+A0GcH^^<=>\4g@_R=J!j8.Md&V^"L-@#i0;$398b)@k'giG8Jo!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +967 768 m 0,0,1 + 1024 768 1024 768 1024 825 c 2,2,3 + 1024 825 1024 825 1024 949 c 1,4,5 + 1024 1024 1024 1024 949 1024 c 1,6,7 + 768 1024 768 1024 587 1024 c 0,8,9 + 512 1024 512 1024 512 949 c 1,10,11 + 512 858 512 858 512 843 c 0,12,13 + 512 768 512 768 587 768 c 1,14,15 + 777 768 777 768 967 768 c 0,0,1 +949 1280 m 1,16,17 + 1280 1280 1280 1280 1280 949 c 0,18,19 + 1280 949 1280 949 1280 825 c 0,20,21 + 1280 512 1280 512 967 512 c 24,22,-1 + 512 512 l 1,23,24 + 512 384 512 384 512 331 c 0,25,26 + 512 256 512 256 587 256 c 1,27,28 + 587 256 587 256 967 256 c 0,29,30 + 1024 256 1024 256 1024 127 c 0,31,32 + 1024 0 1024 0 967 0 c 0,33,-1 + 587 0 l 0,34,35 + 256 0 256 0 256 331 c 1,36,37 + 256 640 256 640 256 949 c 0,38,39 + 256 1280 256 1280 512 1280 c 1,40,41 + 512 1280 512 1280 512 1461 c 0,42,43 + 512 1536 512 1536 437 1536 c 24,44,-1 + 0 1536 l 24,45,46 + 0 1536 0 1536 0 1792 c 25,47,48 + 437 1792 437 1792 437 1792 c 0,49,50 + 768 1792 768 1792 768 1461 c 24,51,-1 + 768 1280 l 0,52,-1 + 949 1280 l 1,16,17 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni008B +Encoding: 139 139 137 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +Qij+G2),_\"ZG0ZPDF8^ZCU2qJrTs6W4`HPT/+OBz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +512 1024 m 24,0,-1 + 768 1024 l 24,1,-1 + 768 256 l 24,2,-1 + 1024 256 l 24,3,-1 + 1024 0 l 25,4,-1 + 256 0 l 25,5,-1 + 256 256 l 24,6,-1 + 512 256 l 24,7,-1 + 512 1024 l 24,0,-1 +768 1536 m 24,8,-1 + 1024 1536 l 24,9,-1 + 1024 1280 l 24,10,-1 + 768 1280 l 24,11,12 + 768 1280 768 1280 768 1536 c 24,8,-1 +256 1536 m 24,13,-1 + 512 1536 l 24,14,-1 + 512 1280 l 24,15,-1 + 256 1280 l 24,16,17 + 256 1280 256 1280 256 1536 c 24,13,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni008C +Encoding: 140 140 138 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CNNffG9`^HN: +$:'asK=[=RMQ[l)Y@#0!!!!j +78?7R6=>BF +EndImage2 +Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 1536 l 24,2,-1 + 1024 1536 l 24,3,4 + 1024 1536 1024 1536 1024 1792 c 25,0,-1 +0 1792 m 25,5,-1 + 256 1792 l 25,6,-1 + 256 1536 l 24,7,-1 + 0 1536 l 24,8,9 + 0 1536 0 1536 0 1792 c 25,5,-1 +640 1227 m 1,10,11 + 640 1227 640 1227 256 843 c 1,12,-1 + 256 768 l 25,13,-1 + 1024 768 l 25,14,-1 + 1024 843 l 1,15,-1 + 640 1227 l 1,10,11 +0 0 m 25,16,-1 + 0 949 l 25,17,-1 + 587 1536 l 24,18,-1 + 693 1536 l 24,19,-1 + 1280 949 l 25,20,-1 + 1280 0 l 25,21,-1 + 1024 0 l 25,22,-1 + 1024 512 l 24,23,-1 + 256 512 l 24,24,-1 + 256 0 l 25,25,-1 + 0 0 l 25,16,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni008F +Encoding: 143 143 141 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 126 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W77fm5<#?L$N_p8d+:(sR)$@mKYCcfT!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 1280 m 24,0,-1 + 512 1280 l 24,1,-1 + 512 1461 l 0,2,3 + 512 1792 512 1792 843 1792 c 24,4,-1 + 1280 1792 l 25,5,-1 + 1280 1536 l 24,6,-1 + 843 1536 l 0,7,8 + 768 1536 768 1536 768 1461 c 24,9,10 + 768 1461 768 1461 768 1280 c 24,11,-1 + 1280 1280 l 24,12,-1 + 1280 1024 l 24,13,-1 + 256 1024 l 24,14,-1 + 256 768 l 25,15,-1 + 1024 768 l 25,16,-1 + 1024 512 l 24,17,-1 + 256 512 l 24,18,-1 + 256 256 l 24,19,-1 + 1280 256 l 24,20,-1 + 1280 0 l 25,21,-1 + 0 0 l 25,22,23 + 0 0 0 0 0 1280 c 24,0,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni0091 +Encoding: 145 145 143 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns2BOMigR +fha",#:9GGO\I-1B-aIG?;[Ai-!n.V-JPH:I>Gib3E2&,1z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +256 587 m 0,0,1 + 256 512 256 512 331 512 c 24,2,-1 + 512 512 l 24,3,-1 + 512 768 l 25,4,-1 + 331 768 l 0,5,6 + 256 768 256 768 256 693 c 24,7,8 + 256 685 256 685 256 587 c 0,0,1 +768 1280 m 24,9,-1 + 768 1024 l 24,10,-1 + 949 1024 l 0,11,12 + 1024 1024 1024 1024 1024 1099 c 24,13,14 + 1024 1190 1024 1190 1024 1205 c 0,15,16 + 1024 1280 1024 1280 949 1280 c 24,17,18 + 949 1280 949 1280 768 1280 c 24,9,-1 +0 1536 m 24,19,-1 + 1099 1536 l 0,20,21 + 1280 1536 1280 1536 1280 1355 c 24,22,23 + 1280 1062 1280 1062 1280 949 c 0,24,25 + 1280 768 1280 768 1099 768 c 24,26,-1 + 768 768 l 25,27,-1 + 768 512 l 24,28,-1 + 1280 512 l 24,29,-1 + 1280 256 l 24,30,-1 + 181 256 l 0,31,32 + 0 256 0 256 0 437 c 24,33,34 + 0 747 0 747 0 843 c 0,35,36 + 0 1024 0 1024 181 1024 c 24,37,-1 + 512 1024 l 24,38,-1 + 512 1280 l 24,39,-1 + 0 1280 l 24,40,41 + 0 1280 0 1280 0 1536 c 24,19,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni0092 +Encoding: 146 146 144 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NmS=:+:&%fs8V6p2qg%3 +=,mrq3;]4%"#(qEOHKoBKBe+>8GCfabt3P>g8=[l+]'g6T\H[Op1=mP5H,2#z8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +256 1024 m 24,0,-1 + 512 1024 l 24,1,2 + 512 1024 512 1024 512 1461 c 0,3,4 + 512 1536 512 1536 437 1536 c 24,5,6 + 437 1536 437 1536 331 1536 c 0,7,8 + 256 1536 256 1536 256 1461 c 24,9,10 + 256 1461 256 1461 256 1024 c 24,0,-1 +0 1461 m 0,11,12 + 0 1792 0 1792 331 1792 c 24,13,14 + 331 1792 331 1792 437 1792 c 0,15,16 + 768 1792 768 1792 768 1461 c 24,17,-1 + 768 1280 l 24,18,-1 + 1280 1280 l 24,19,-1 + 1280 1024 l 24,20,-1 + 768 1024 l 24,21,-1 + 768 768 l 25,22,-1 + 1024 768 l 25,23,-1 + 1024 512 l 24,24,-1 + 768 512 l 24,25,-1 + 768 256 l 24,26,-1 + 1280 256 l 24,27,-1 + 1280 0 l 25,28,-1 + 512 0 l 24,29,-1 + 512 768 l 25,30,-1 + 256 768 l 25,31,-1 + 256 0 l 25,32,-1 + 0 0 l 25,33,34 + 0 896 0 896 0 1461 c 0,11,12 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni0093 +Encoding: 147 147 145 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CNNffHd!JJi$ +=91qoA.T$A.q/PD5aF[EOe<#"2k\n7itJd$X8qAmQnDnf!,J_Z&,&Qt?N:'+!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +587 1024 m 0,0,1 + 512 1024 512 1024 512 949 c 24,2,3 + 512 730 512 730 512 587 c 0,4,5 + 512 512 512 512 587 512 c 24,6,-1 + 949 512 l 0,7,8 + 1024 512 1024 512 1024 587 c 24,9,10 + 1024 806 1024 806 1024 949 c 0,11,12 + 1024 1024 1024 1024 949 1024 c 24,13,14 + 949 1024 949 1024 587 1024 c 0,0,1 +587 1536 m 0,15,16 + 512 1536 512 1536 512 1461 c 24,17,18 + 512 1370 512 1370 512 1355 c 0,19,20 + 512 1280 512 1280 587 1280 c 24,21,-1 + 949 1280 l 0,22,23 + 1024 1280 1024 1280 1024 1355 c 24,24,25 + 1024 1446 1024 1446 1024 1461 c 0,26,27 + 1024 1536 1024 1536 949 1536 c 24,28,29 + 949 1536 949 1536 587 1536 c 0,15,16 +1204 1152 m 1,30,31 + 1280 1106 1280 1106 1280 949 c 0,32,33 + 1280 616 1280 616 1280 587 c 0,34,35 + 1280 256 1280 256 949 256 c 24,36,37 + 587 256 587 256 587 256 c 0,38,39 + 256 256 256 256 256 587 c 24,40,41 + 256 846 256 846 256 949 c 0,42,43 + 256 1100 256 1100 331 1151 c 1,44,45 + 256 1196 256 1196 256 1355 c 0,46,47 + 256 1437 256 1437 256 1461 c 0,48,49 + 256 1792 256 1792 587 1792 c 24,50,51 + 946 1792 946 1792 949 1792 c 0,52,53 + 1277 1792 1277 1792 1280 1461 c 24,54,55 + 1280 1461 1280 1461 1280 1355 c 0,56,57 + 1280 1201 1280 1201 1204 1152 c 1,30,31 +EndSplineSet +Validated: 1 +EndChar + +StartChar: uni0094 +Encoding: 148 148 146 +Width: 1536 +VWidth: 2048 +Flags: MWO +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9Xot.% +Q6XNTQmq716/li65Y_>gF@BR@+I0G:$V1>%-]!`j^^=J,OBQFqYl">.e9oz8OZBBY!QNJ + +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni0096 +Encoding: 150 150 148 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CJNffG9N3T?l +":E!T!@^DqO9m04OoPMn2HTrMJ?=?AYgJ[c?i_.'c#/nk!'65V&'==Aec5[M!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni0097 +Encoding: 151 151 149 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 111 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8sb%]fYs3[Tpk +#W"5fe7&J+O:XqqAcfP1YQ@LH#SG2oY^d/"k=>S;7MH1/$/OGBF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni0098 +Encoding: 152 152 150 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9Xot.% +QD<(8YSD-KYqT9F@N]lhgC7'h2Z]][Rtnd+J5jE[5Z\'g[VZ]jUha3>z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni0099 +Encoding: 153 153 151 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8C%,9r(&#+pt` +/0O?$]$P9sR?(e_827Co-56\mi=Ju(!\t7X)Z[-3(^ZKQ:]LIq!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni009A +Encoding: 154 154 152 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8C%,9r(&#+o?< +Qr)#I_P(38$cn[U/k>Xn!4\[3&p%V?i;`iX!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni009B +Encoding: 155 155 153 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 122 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?L$NR8(5+:&'Rs8UE2K+e@/ +Q`3';in!tUm[g4<\h=$sKf"laP0aGAR'\%a1Ns&o/_MNWomponhuM-h'+]WtMlHaW!!#SZ:.26O +@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni009C +Encoding: 156 156 154 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8CNNffHd!JJi$ +$V17CJ]f1G$0XEYI*rb&]*%+D'ORNFK`t`^AiGYQ!.c.#&Hl>:i;`iX!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni009D +Encoding: 157 157 155 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8C%,9r(&3hH^I +((5m(A-5LALdnicA3P_eO;5%937r>*Co#hh!!@3^#&lu5f)PdN!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni009E +Encoding: 158 158 156 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8sb%RgE0H5;TS +A3i[S7MJ$"*n.r'Ug&Cf,1m>I6'0nVJF"Vm)dn7O)Q">OWN@3=kt"tbz8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni009F +Encoding: 159 159 157 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8D_*$Z[Q!sg+R +()R9%J^#k_'4?][Bs7Z+YqR(`!R,3oNM->T!1aR>1>&)KFFt80!5ad/%nR=YNrT.[!(fUS7'8ja +JcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni00A0 +Encoding: 160 160 158 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 125 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$N_p,`+:LRo])S$G(QNpF +KTOPnE?4#5;)=B^WLCOLkf.)JPhhE`$6hQ8Km9=:'h\;Df0U7c@_Y%0!Sk=!*9^"N?iU0,!(fUS +7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: exclamdown +Encoding: 161 161 159 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8D_*$Z[Q!sg+R +()R9%J^#mY$.pLhRc+V#NJBF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: cent +Encoding: 162 162 160 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8D_*$Z[Q!sg+R +()R9%J^#kW'4;_d1fscP2ol,D.o8oiksD6R.KDOCfk>J_!W\Z<',H#YRNqk5!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: sterling +Encoding: 163 163 161 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8D_*$Z[Q!sg+R +()R9%J^#mQ$-8:n-D4HA1C]bL>QNK>+NL21%C66=DFY-R6K,CSz8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: currency +Encoding: 164 164 162 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 119 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8C%,9n7D"pPj) +!Q^/F%:fKR7hu4V7co=BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: yen +Encoding: 165 165 163 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$bu"fJ+:&'G-f+gFeV%B@ +d]^aTL:J\#8H@!r@PC'0#P.e,+]aiOf*(Omi&-B!nDf9V3(U7K?Df4j$$E!f`rH)>!(fUS7'8ja +JcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: brokenbar +Encoding: 166 166 164 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG9Xor#n +'1`BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: copyright +Encoding: 169 169 167 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 105 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd6aoX='=TE7j'#B5s&u:P\)[Inn!!4kb"&IJB(]XO9!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: ordfeminine +Encoding: 170 170 168 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd6b(@hz8OZBBY!QNJ + +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: logicalnot +Encoding: 172 172 170 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NDU#_0F1!$G5j(21C0M0 +r2Q>,p/MMn!!A6PV]L'kK`3_'n:PP\#-HFDL8@Ise^,tZkffSY%)itrG2h[*z8OZBBY!QNJ + +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni00AD +Encoding: 173 173 171 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8CNNffG9`^HNZ +$?-jc=$Y+8'Q]BrE"e>O:mdIt!!#m3#7ii8+`m\a!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: registered +Encoding: 174 174 172 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +>TGR=,Y68bOB/kI5e>@6_up^')2l^nfh'g'\G7g1BJ]\prtPfbo^aa:!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: macron +Encoding: 175 175 173 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns22,9nF< +%5JkL8D"','4K!lfs6#;QBF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: plusminus +Encoding: 177 177 175 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8C%,9p;/SVHB; +!Z;!$7&FCU+<#%tZ6[X>R%hE)!WYS80bpR=__(oh!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni00B2 +Encoding: 178 178 176 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$N6qt4+:Ja +/&3J4',qPk!$J3C'$J7Wkl:\`!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: acute +Encoding: 180 180 178 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 93 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,Y:Bi<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4',qVm5X)sg!$MLK'r$fZcN!qF!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: mu +Encoding: 181 181 179 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 101 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4';L-\OT"qS'*1l_0G-&@!9%Sr't*9^b5_MB!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: paragraph +Encoding: 182 182 180 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 95 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pJu:T`F-UHiO-kKEN.@)qT34!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: periodcentered +Encoding: 183 183 181 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: cedilla +Encoding: 184 184 182 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns2<'JKS? +_Jgd+]314U+BL9QK(L/c$b?=)$GliE+P$o1*lXZMz8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni00B9 +Encoding: 185 185 183 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 105 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pFGM-ihq]&$QW7"9T%;$.opo!$-\!)&6YA2ZNgX!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: ordmasculine +Encoding: 186 186 184 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 91 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pJtoT`>';-Nk/O`Y'Ep!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: guillemotright +Encoding: 187 187 185 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns2<'JKS? +_Jgd+]314U+BL9QK(L/c$aKcD@ZW>F=e-$1?1ZPNz8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: onequarter +Encoding: 188 188 186 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pFGM-ihq]&$QW7"9T#T'*.*q#9;f]U)a46!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: onehalf +Encoding: 189 189 187 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 99 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: threequarters +Encoding: 190 190 188 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 101 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4';L-\OT"qS'*1l_0G-&@!9%Sr't*9^b5_MB!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: questiondown +Encoding: 191 191 189 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Agrave +Encoding: 192 192 190 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 92 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4',u$#Yk\J'+V"VlN61l:z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Aacute +Encoding: 193 193 191 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4',q>e(kI^`n0YHe!FA>'%B8fCrr<$!!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Acircumflex +Encoding: 194 194 192 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Atilde +Encoding: 195 195 193 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 92 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4',u$#Yk\J'+V"VlN61l:z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Adieresis +Encoding: 196 196 194 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Aring +Encoding: 197 197 195 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4',q>e(kI^`n0YHe!FA>'%B8fCrr<$!!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: AE +Encoding: 198 198 196 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4';Mi7Ci3[4f`e+TGmM@ufLu8F^?>eBB4:K7z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Ccedilla +Encoding: 199 199 197 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 95 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pJu:WrV32(]XO\8-Be-C[o1?!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Egrave +Encoding: 200 200 198 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 100 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pK!%:k7s_'K703#3K"fZMb"F3oa6rz8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Eacute +Encoding: 201 201 199 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8Bu3Ns2<'X3*= +@Us";E=0"`_$XSUa:^0]$qI%]"ot9O$4t0"i%tE6!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Ecircumflex +Encoding: 202 202 200 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 105 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pFGM-ihq]%knXe"\:_02j&Lu!+*5F%a\Tq3<0$Z!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Edieresis +Encoding: 203 203 201 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8Bu3Ns2<'JKS? +_Jgd+]314UfGoiZ!_>$j,9m;r-30>o&cjm'^*3OW!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Igrave +Encoding: 204 204 202 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 99 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pK!%:k7s_$o`]aKF@jd`!7$Wg'U=M!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Iacute +Encoding: 205 205 203 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 94 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns2<'JKS? +_Jgd+]314UfGmT3"9;^u%fm;4_$'f=!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Icircumflex +Encoding: 206 206 204 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pFGM-ihq]%knXe"\:`1Riif*9LSS7!10i!%](Uh2ZNgX!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Idieresis +Encoding: 207 207 205 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4';Je5,L@hI7j>R7"doJ!(RZU`!WZ\]%gVktrYPV8!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: space +Encoding: 32 32 206 +Width: 1536 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 79 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(.gn[<#?K_r!ro=GQ8Bu3O%$&:]LJ7 +D?LB^-QJHQ!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uni0000 +Encoding: 0 0 207 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 81 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(eI+]<#?K_A7/g?&&^F.'2BFD`:-S' +!";d,&&iB0%KHJ/!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Eth +Encoding: 208 208 208 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 99 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Ntilde +Encoding: 209 209 209 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 94 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns2<'JKS? +_Jgd+]314UfGmT3"9;^u%fm;4_$'f=!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Ograve +Encoding: 210 210 210 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Oacute +Encoding: 211 211 211 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 95 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pJu:VZ>csF8u:c?j%;QoDu8u!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Ocircumflex +Encoding: 212 212 212 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4';Mi7Ci3[4f`e+TGmM@ufLu8F^?>eBB4:K7z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Otilde +Encoding: 213 213 213 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%!u-t$Rr +6ua"(D?'YV@0@+u1K<94!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Odieresis +Encoding: 214 214 214 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 84 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr +LuL,h)k-s@YSsU1z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: multiply +Encoding: 215 215 215 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 99 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Oslash +Encoding: 216 216 216 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 101 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8Dg*$Z[QM@bLD +'NlQ6EWn#XG+r3WK'iqe%0TB*!8ts()gOU!N;rqY!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Ugrave +Encoding: 217 217 217 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 93 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,Y:Bi<#?K_r!ro=GQ8Dg*$Z[QM@bLD +'NlPk0IUVQiI*d!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Uacute +Encoding: 218 218 218 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 84 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr +LuL,h)k-s@YSsU1z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Ucircumflex +Encoding: 219 219 219 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 86 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*D&Xb<#?K_r!ro=GQ8sb%RU9&*[X"< +_,BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: Yacute +Encoding: 221 221 221 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 86 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*D&Xb<#?K_r!ro=GQ8sb%^#f$=scA# +_,6*`gl;[=2_b#`BT:ma%`@oq.KBGK!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: aacute +Encoding: 225 225 225 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8sb%^#f$=sf>C +O9>hF14n#N!m44;>Ck%4QpksQJ/$sa,Y0dN8WYn3ei4fJ=9.5"z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: acircumflex +Encoding: 226 226 226 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 107 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8sb%RU9&*YsiL +A-#.hO<+O4685[N0GGY!#1A*s!8SX;'`\49X:>FZOH&o5!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: atilde +Encoding: 227 227 227 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd6aopatdkIg/>!Ysc,LC*42o(@Wd/YKm'_qdrA2aJg!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: adieresis +Encoding: 228 228 228 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 125 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$NmS16+:&'JqYsnT:U#R> +HVi@4QEAO/ai!o+2:#'fHA[3!]Kabmt6t]^qt2z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: ccedilla +Encoding: 231 231 231 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd6ao^TW1,:W#fZ;VV["BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: edieresis +Encoding: 235 235 235 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8CJNffG9N3T?l +":F-GKEYlga93>F[h6L\OCD`h?oPlCA"s>[+Qs"0N05+aQb:>%z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: igrave +Encoding: 236 236 236 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +Qij+G2)0Xb6+.ob-jl%rf[rm]]$]?X#S`rU(BEC4(C_Jt"T8<#!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: iacute +Encoding: 237 237 237 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$:'h7-+:*&es3Ke[NKS6' +,.kcg`.0^a7?mjBF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: ntilde +Encoding: 241 241 241 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HNZ +$;a-Q3$<&T!ong4J?b4F?m'+d>QHb=+Hm)B!<>"K'`g-2+2\'Y!!#SZ:.26O@"J@Y +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: ograve +Encoding: 242 242 242 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8C%,9n7D"pQE9 +!Vd?`J[FH9"BL%K&R5>h748LNMEj!,J@pEk9k9ju!.ec!#8A0)mJm4e!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: oacute +Encoding: 243 243 243 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?L$:.Z&u+:&>Ss5s_"%Pf=X +LK3]!2'?-+d&:QLk_3SmM6'=e:S`Poj.G;"9I[85$/QR]hLZRG"t\K.z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: ocircumflex +Encoding: 244 244 244 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8D_*$Z[Q1)J/h +.f`.m$q")!=+HtZ.Y+2mh+8FjcqU6>!%hZBF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: odieresis +Encoding: 246 246 246 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +F7*dd,#*D0*"!4IN'+.>uci6z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: oslash +Encoding: 248 248 248 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8CJNffG9N3T?l +":E!T!@^DqO9Hm0OoPN)8WXbs/d[V!#_:_2@:CT5fEr&3)!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: ugrave +Encoding: 249 249 249 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8Bu3Ns4f$5aWu +)*f#ZJ5&:p5\>W_K,#N@':B;-^]G]F!*oXM$8hk(_+"M,dDQJ+QNPW^z8OZBBY!QNJ +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: uacute +Encoding: 250 250 250 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns24'ehBu +@^QY_"YR:$'k#Q%'I9UW!%-V/$md\(4TGH^!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: ucircumflex +Encoding: 251 251 251 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+FNffG9`ah?c +"'5Jc7@&J'AqDaVd7hVN@oGeJ"H^;>;m=pc1(e=(/kM-+!-+VE$NJqlp](9o!(fUS7'8jaJcGcN +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: udieresis +Encoding: 252 252 252 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 111 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8Bu3Ns2`"cP]X +E%A0G"uZK-!Q'eS+SD[`TG7SE0ER5g])gH$#S-plN=l21\-JE%!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: yacute +Encoding: 253 253 253 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?L$N'RdN0FYgqo`&:TWj&8\ +<%ndLEXLID6LpLu+!mRNL72;b6E@ +(`=3"9Eo$3$(=,i!k922m=dV+a8c2MpBh@PrMsB-!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar + +StartChar: ydieresis +Encoding: 255 255 255 +Width: 256 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 79 0 2048 256 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(.gn[<#?K_r!ro=GQ8Bu3O%$&:]LJ7 +D?LB^-QJHQ!!!!j78?7R6=>BF +EndImage2 +Fore +Validated: 1 +EndChar +EndChars +EndSplineFont From 196b58c23cfcf2f4cadc0e4e87a1714f4c9ed087 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 23 Oct 2022 20:29:20 -0700 Subject: [PATCH 212/314] [#243] 88-sio: fixed mapping characters --- .../emustudio/plugins/device/mits88dcdd/drive/Drive.java | 8 +++++--- .../emustudio/plugins/device/mits88sio/DataChannel.java | 6 +++--- .../net/emustudio/plugins/device/mits88sio/UART.java | 2 +- .../plugins/device/mits88sio/DataChannelTest.java | 9 ++++----- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java index c553cf060..49a91dcd6 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java @@ -46,7 +46,7 @@ public class Drive { private static final Logger LOGGER = LoggerFactory.getLogger(Drive.class); public final static byte DEFAULT_SECTORS_PER_TRACK = 32; - public final static byte DEFAULT_SECTOR_SIZE = (byte)137; + public final static int DEFAULT_SECTOR_SIZE = 137; public static final byte DEAD_DRIVE = (byte)0b11100111; private static final byte ALIVE_DRIVE = (byte)0b11100101; @@ -109,7 +109,8 @@ public Drive(int driveIndex) { public void setSectorsPerTrack(int sectorsPerTrack) { if (sectorsPerTrack <= 0) { - throw new IllegalArgumentException("[drive=" + driveIndex + "] Sectors count must be > 0"); + LOGGER.error("[drive=" + driveIndex + "] Sectors count must be > 0"); + return; } inWriteLock(() -> this.sectorsPerTrack = sectorsPerTrack); reset(); @@ -117,7 +118,8 @@ public void setSectorsPerTrack(int sectorsPerTrack) { public void setSectorSize(int sectorSize) { if (sectorSize <= 0) { - throw new IllegalArgumentException("[drive=" + driveIndex + "] Sector length must be > 0"); + LOGGER.error("[drive=" + driveIndex + "] Sector length must be > 0"); + return; } inWriteLock(() -> this.sectorSize = sectorSize); reset(); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java index 89d6ae173..3696f41a1 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java @@ -38,14 +38,14 @@ public DataChannel(SioUnitSettings settings, UART uart) { @Override public Byte readData() { byte data = uart.readBuffer(); - data = settings.isClearOutputBit8() ? (byte) (data & 0x7F) : data; + data = settings.isInputToUpperCase() ? (byte) Character.toUpperCase((char) (data & 0xFF)) : data; + data = settings.isClearInputBit8() ? (byte) (data & 0x7F) : data; return mapCharacter(data); } @Override public void writeData(Byte data) { - data = settings.isInputToUpperCase() ? (byte) Character.toUpperCase((char) (data & 0xFF)) : data; - data = settings.isClearInputBit8() ? (byte) (data & 0x7F) : data; + data = settings.isClearOutputBit8() ? (byte) (data & 0x7F) : data; uart.sendToDevice(mapCharacter(data)); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java index 60feb6750..2e125359b 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java @@ -131,7 +131,7 @@ public void receiveFromDevice(byte data) { if (bufferFromDevice.isEmpty()) { wasEmpty = true; } - bufferFromDevice.add(data); + bufferFromDevice.add(data); // TODO: here statusRegister = (byte) (statusRegister | 1); newStatus = statusRegister; } finally { diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java index c2daadde1..aafd24729 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java @@ -29,7 +29,7 @@ public class DataChannelTest { @Test public void testInputBit8Cleared() { SioUnitSettings settings = niceMock(SioUnitSettings.class); - expect(settings.isClearInputBit8()).andReturn(true).anyTimes(); + expect(settings.isClearOutputBit8()).andReturn(true).anyTimes(); expect(settings.getMapBackspaceChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); expect(settings.getMapDeleteChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); replay(settings); @@ -48,7 +48,7 @@ public void testInputBit8Cleared() { @Test public void testOutputBit8Cleared() { SioUnitSettings settings = niceMock(SioUnitSettings.class); - expect(settings.isClearOutputBit8()).andReturn(true).anyTimes(); + expect(settings.isClearInputBit8()).andReturn(true).anyTimes(); expect(settings.getMapBackspaceChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); expect(settings.getMapDeleteChar()).andReturn(SioUnitSettings.MAP_CHAR.UNCHANGED).anyTimes(); replay(settings); @@ -72,12 +72,11 @@ public void testInputUpperCase() { replay(settings); UART uart = mock(UART.class); - uart.sendToDevice(eq((byte) 'A')); - expectLastCall().once(); + expect(uart.readBuffer()).andReturn((byte) 'a').once(); replay(uart); DataChannel channel = new DataChannel(settings, uart); - channel.writeData((byte) 'a'); + assertEquals('A', channel.readData() & 0xFF); verify(uart); } From ec4f06ce6b13efec753b5e8b4c0a77cd8025a61e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 23 Oct 2022 20:31:29 -0700 Subject: [PATCH 213/314] [#243] remove useless comment --- .../main/java/net/emustudio/plugins/device/mits88sio/UART.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java index 2e125359b..60feb6750 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java @@ -131,7 +131,7 @@ public void receiveFromDevice(byte data) { if (bufferFromDevice.isEmpty()) { wasEmpty = true; } - bufferFromDevice.add(data); // TODO: here + bufferFromDevice.add(data); statusRegister = (byte) (statusRegister | 1); newStatus = statusRegister; } finally { From 606b6fb91a454406a416fe732343848753adfa5c Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 13 Nov 2022 15:22:55 +0100 Subject: [PATCH 214/314] [#278] adm-3a: Finish font --- .../as-z80/src/main/examples/hello_world.asm | 11 +- .../src/main/examples/RAMexamples.txt | 4 +- .../src/main/examples/RASPexamples.txt | 4 +- .../plugins/device/adm3a/gui/adm-3a.ttf | Bin 29340 -> 36696 bytes resources/lsi-adm-3a/adm-3a.ttf | Bin 29340 -> 36696 bytes resources/lsi-adm-3a/adm3a.sfd | 2651 ++++++++++++++--- resources/lsi-adm-3a/bitmap/00-00.png | Bin 0 -> 76 bytes resources/lsi-adm-3a/bitmap/00-01.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/00-02.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/00-03.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/00-04.png | Bin 0 -> 95 bytes resources/lsi-adm-3a/bitmap/00-05.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/00-06.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/00-07.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/00-08.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/00-09.png | Bin 0 -> 91 bytes resources/lsi-adm-3a/bitmap/00-10.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/00-11.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/00-12.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/00-13.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/00-14.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/00-15.png | Bin 0 -> 92 bytes resources/lsi-adm-3a/bitmap/00-16.png | Bin 0 -> 103 bytes resources/lsi-adm-3a/bitmap/00-17.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/00-18.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/00-19.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/00-20.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/00-21.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/00-22.png | Bin 0 -> 103 bytes resources/lsi-adm-3a/bitmap/00-23.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/00-24.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/00-25.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/00-26.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/00-27.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/00-28.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/00-29.png | Bin 0 -> 91 bytes resources/lsi-adm-3a/bitmap/00-30.png | Bin 0 -> 107 bytes resources/lsi-adm-3a/bitmap/00-31.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/01-00.png | Bin 0 -> 76 bytes resources/lsi-adm-3a/bitmap/01-01.png | Bin 0 -> 83 bytes resources/lsi-adm-3a/bitmap/01-02.png | Bin 0 -> 84 bytes resources/lsi-adm-3a/bitmap/01-03.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/01-04.png | Bin 0 -> 103 bytes resources/lsi-adm-3a/bitmap/01-05.png | Bin 0 -> 108 bytes resources/lsi-adm-3a/bitmap/01-06.png | Bin 0 -> 106 bytes resources/lsi-adm-3a/bitmap/01-07.png | Bin 0 -> 82 bytes resources/lsi-adm-3a/bitmap/01-08.png | Bin 0 -> 95 bytes resources/lsi-adm-3a/bitmap/01-09.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/01-10.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/01-11.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/01-12.png | Bin 0 -> 86 bytes resources/lsi-adm-3a/bitmap/01-13.png | Bin 0 -> 89 bytes resources/lsi-adm-3a/bitmap/01-14.png | Bin 0 -> 80 bytes resources/lsi-adm-3a/bitmap/01-15.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/01-16.png | Bin 0 -> 105 bytes resources/lsi-adm-3a/bitmap/01-17.png | Bin 0 -> 91 bytes resources/lsi-adm-3a/bitmap/01-18.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/01-19.png | Bin 0 -> 105 bytes resources/lsi-adm-3a/bitmap/01-20.png | Bin 0 -> 103 bytes resources/lsi-adm-3a/bitmap/01-21.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/01-22.png | Bin 0 -> 105 bytes resources/lsi-adm-3a/bitmap/01-23.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/01-24.png | Bin 0 -> 90 bytes resources/lsi-adm-3a/bitmap/01-25.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/01-26.png | Bin 0 -> 88 bytes resources/lsi-adm-3a/bitmap/01-27.png | Bin 0 -> 92 bytes resources/lsi-adm-3a/bitmap/01-28.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/01-29.png | Bin 0 -> 92 bytes resources/lsi-adm-3a/bitmap/01-30.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/01-31.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/02-00.png | Bin 0 -> 103 bytes resources/lsi-adm-3a/bitmap/02-01.png | Bin 0 -> 105 bytes resources/lsi-adm-3a/bitmap/02-02.png | Bin 0 -> 88 bytes resources/lsi-adm-3a/bitmap/02-03.png | Bin 0 -> 94 bytes resources/lsi-adm-3a/bitmap/02-04.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/02-05.png | Bin 0 -> 92 bytes resources/lsi-adm-3a/bitmap/02-06.png | Bin 0 -> 89 bytes resources/lsi-adm-3a/bitmap/02-07.png | Bin 0 -> 93 bytes resources/lsi-adm-3a/bitmap/02-08.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/02-09.png | Bin 0 -> 87 bytes resources/lsi-adm-3a/bitmap/02-10.png | Bin 0 -> 86 bytes resources/lsi-adm-3a/bitmap/02-11.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/02-12.png | Bin 0 -> 81 bytes resources/lsi-adm-3a/bitmap/02-13.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/02-14.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/02-15.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/02-16.png | Bin 0 -> 92 bytes resources/lsi-adm-3a/bitmap/02-17.png | Bin 0 -> 106 bytes resources/lsi-adm-3a/bitmap/02-18.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/02-19.png | Bin 0 -> 98 bytes resources/lsi-adm-3a/bitmap/02-20.png | Bin 0 -> 84 bytes resources/lsi-adm-3a/bitmap/02-21.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/02-22.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/02-23.png | Bin 0 -> 98 bytes resources/lsi-adm-3a/bitmap/02-24.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/02-25.png | Bin 0 -> 93 bytes resources/lsi-adm-3a/bitmap/02-26.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/02-27.png | Bin 0 -> 84 bytes resources/lsi-adm-3a/bitmap/02-28.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/02-29.png | Bin 0 -> 86 bytes resources/lsi-adm-3a/bitmap/02-30.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/02-31.png | Bin 0 -> 82 bytes resources/lsi-adm-3a/bitmap/03-00.png | Bin 0 -> 90 bytes resources/lsi-adm-3a/bitmap/03-01.png | Bin 0 -> 98 bytes resources/lsi-adm-3a/bitmap/03-02.png | Bin 0 -> 98 bytes resources/lsi-adm-3a/bitmap/03-03.png | Bin 0 -> 95 bytes resources/lsi-adm-3a/bitmap/03-04.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/03-05.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/03-06.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/03-07.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/03-08.png | Bin 0 -> 90 bytes resources/lsi-adm-3a/bitmap/03-09.png | Bin 0 -> 93 bytes resources/lsi-adm-3a/bitmap/03-10.png | Bin 0 -> 94 bytes resources/lsi-adm-3a/bitmap/03-11.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/03-12.png | Bin 0 -> 89 bytes resources/lsi-adm-3a/bitmap/03-13.png | Bin 0 -> 94 bytes resources/lsi-adm-3a/bitmap/03-14.png | Bin 0 -> 92 bytes resources/lsi-adm-3a/bitmap/03-15.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/03-16.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/03-17.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/03-18.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/03-19.png | Bin 0 -> 98 bytes resources/lsi-adm-3a/bitmap/03-20.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/03-21.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/03-22.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/03-23.png | Bin 0 -> 98 bytes resources/lsi-adm-3a/bitmap/03-24.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/03-25.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/03-26.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/03-27.png | Bin 0 -> 98 bytes resources/lsi-adm-3a/bitmap/03-28.png | Bin 0 -> 85 bytes resources/lsi-adm-3a/bitmap/03-29.png | Bin 0 -> 94 bytes resources/lsi-adm-3a/bitmap/03-30.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/03-31.png | Bin 0 -> 83 bytes resources/lsi-adm-3a/bitmap/04-00.png | Bin 0 -> 105 bytes resources/lsi-adm-3a/bitmap/04-01.png | Bin 0 -> 95 bytes resources/lsi-adm-3a/bitmap/04-02.png | Bin 0 -> 103 bytes resources/lsi-adm-3a/bitmap/04-03.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/04-04.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/04-05.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/04-06.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/04-07.png | Bin 0 -> 98 bytes resources/lsi-adm-3a/bitmap/04-08.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/04-09.png | Bin 0 -> 106 bytes resources/lsi-adm-3a/bitmap/04-10.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/04-11.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/04-12.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/04-13.png | Bin 0 -> 93 bytes resources/lsi-adm-3a/bitmap/04-14.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/04-15.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/04-16.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/04-17.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/04-18.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/04-19.png | Bin 0 -> 93 bytes resources/lsi-adm-3a/bitmap/04-20.png | Bin 0 -> 103 bytes resources/lsi-adm-3a/bitmap/04-21.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/04-22.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/04-23.png | Bin 0 -> 95 bytes resources/lsi-adm-3a/bitmap/04-24.png | Bin 0 -> 103 bytes resources/lsi-adm-3a/bitmap/04-25.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/04-26.png | Bin 0 -> 98 bytes resources/lsi-adm-3a/bitmap/04-27.png | Bin 0 -> 103 bytes resources/lsi-adm-3a/bitmap/04-28.png | Bin 0 -> 94 bytes resources/lsi-adm-3a/bitmap/04-29.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/04-30.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/04-31.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/05-00.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/05-01.png | Bin 0 -> 95 bytes resources/lsi-adm-3a/bitmap/05-02.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/05-03.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/05-04.png | Bin 0 -> 95 bytes resources/lsi-adm-3a/bitmap/05-05.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/05-06.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/05-07.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/05-08.png | Bin 0 -> 98 bytes resources/lsi-adm-3a/bitmap/05-09.png | Bin 0 -> 90 bytes resources/lsi-adm-3a/bitmap/05-10.png | Bin 0 -> 92 bytes resources/lsi-adm-3a/bitmap/05-11.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/05-12.png | Bin 0 -> 108 bytes resources/lsi-adm-3a/bitmap/05-13.png | Bin 0 -> 85 bytes resources/lsi-adm-3a/bitmap/05-14.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/05-15.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/05-16.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/05-17.png | Bin 0 -> 85 bytes resources/lsi-adm-3a/bitmap/05-18.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/05-19.png | Bin 0 -> 79 bytes resources/lsi-adm-3a/bitmap/05-20.png | Bin 0 -> 83 bytes resources/lsi-adm-3a/bitmap/05-21.png | Bin 0 -> 89 bytes resources/lsi-adm-3a/bitmap/05-22.png | Bin 0 -> 83 bytes resources/lsi-adm-3a/bitmap/05-23.png | Bin 0 -> 82 bytes resources/lsi-adm-3a/bitmap/05-24.png | Bin 0 -> 93 bytes resources/lsi-adm-3a/bitmap/05-25.png | Bin 0 -> 91 bytes resources/lsi-adm-3a/bitmap/05-26.png | Bin 0 -> 79 bytes resources/lsi-adm-3a/bitmap/05-27.png | Bin 0 -> 93 bytes resources/lsi-adm-3a/bitmap/05-28.png | Bin 0 -> 95 bytes resources/lsi-adm-3a/bitmap/05-29.png | Bin 0 -> 84 bytes resources/lsi-adm-3a/bitmap/05-30.png | Bin 0 -> 89 bytes resources/lsi-adm-3a/bitmap/05-31.png | Bin 0 -> 82 bytes resources/lsi-adm-3a/bitmap/06-00.png | Bin 0 -> 81 bytes resources/lsi-adm-3a/bitmap/06-01.png | Bin 0 -> 84 bytes resources/lsi-adm-3a/bitmap/06-02.png | Bin 0 -> 82 bytes resources/lsi-adm-3a/bitmap/06-03.png | Bin 0 -> 81 bytes resources/lsi-adm-3a/bitmap/06-04.png | Bin 0 -> 82 bytes resources/lsi-adm-3a/bitmap/06-05.png | Bin 0 -> 84 bytes resources/lsi-adm-3a/bitmap/06-06.png | Bin 0 -> 84 bytes resources/lsi-adm-3a/bitmap/06-07.png | Bin 0 -> 81 bytes resources/lsi-adm-3a/bitmap/06-08.png | Bin 0 -> 85 bytes resources/lsi-adm-3a/bitmap/06-09.png | Bin 0 -> 89 bytes resources/lsi-adm-3a/bitmap/06-10.png | Bin 0 -> 93 bytes resources/lsi-adm-3a/bitmap/06-11.png | Bin 0 -> 92 bytes resources/lsi-adm-3a/bitmap/06-12.png | Bin 0 -> 85 bytes resources/lsi-adm-3a/bitmap/06-13.png | Bin 0 -> 89 bytes resources/lsi-adm-3a/bitmap/06-14.png | Bin 0 -> 89 bytes resources/lsi-adm-3a/bitmap/06-15.png | Bin 0 -> 91 bytes resources/lsi-adm-3a/bitmap/06-16.png | Bin 0 -> 84 bytes resources/lsi-adm-3a/bitmap/06-17.png | Bin 0 -> 89 bytes resources/lsi-adm-3a/bitmap/06-18.png | Bin 0 -> 82 bytes resources/lsi-adm-3a/bitmap/06-19.png | Bin 0 -> 83 bytes resources/lsi-adm-3a/bitmap/06-20.png | Bin 0 -> 84 bytes resources/lsi-adm-3a/bitmap/06-21.png | Bin 0 -> 82 bytes resources/lsi-adm-3a/bitmap/06-22.png | Bin 0 -> 80 bytes resources/lsi-adm-3a/bitmap/06-23.png | Bin 0 -> 84 bytes resources/lsi-adm-3a/bitmap/06-24.png | Bin 0 -> 93 bytes resources/lsi-adm-3a/bitmap/06-25.png | Bin 0 -> 82 bytes resources/lsi-adm-3a/bitmap/06-26.png | Bin 0 -> 80 bytes resources/lsi-adm-3a/bitmap/06-27.png | Bin 0 -> 77 bytes resources/lsi-adm-3a/bitmap/06-28.png | Bin 0 -> 82 bytes resources/lsi-adm-3a/bitmap/06-29.png | Bin 0 -> 79 bytes resources/lsi-adm-3a/bitmap/06-30.png | Bin 0 -> 79 bytes resources/lsi-adm-3a/bitmap/06-31.png | Bin 0 -> 83 bytes resources/lsi-adm-3a/bitmap/07-00.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/07-01.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/07-02.png | Bin 0 -> 90 bytes resources/lsi-adm-3a/bitmap/07-03.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/07-04.png | Bin 0 -> 97 bytes resources/lsi-adm-3a/bitmap/07-05.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/07-06.png | Bin 0 -> 99 bytes resources/lsi-adm-3a/bitmap/07-07.png | Bin 0 -> 92 bytes resources/lsi-adm-3a/bitmap/07-08.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/07-09.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/07-10.png | Bin 0 -> 105 bytes resources/lsi-adm-3a/bitmap/07-11.png | Bin 0 -> 102 bytes resources/lsi-adm-3a/bitmap/07-12.png | Bin 0 -> 100 bytes resources/lsi-adm-3a/bitmap/07-13.png | Bin 0 -> 107 bytes resources/lsi-adm-3a/bitmap/07-14.png | Bin 0 -> 94 bytes resources/lsi-adm-3a/bitmap/07-15.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/07-16.png | Bin 0 -> 88 bytes resources/lsi-adm-3a/bitmap/07-17.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/07-18.png | Bin 0 -> 101 bytes resources/lsi-adm-3a/bitmap/07-19.png | Bin 0 -> 104 bytes resources/lsi-adm-3a/bitmap/07-20.png | Bin 0 -> 88 bytes resources/lsi-adm-3a/bitmap/07-21.png | Bin 0 -> 88 bytes resources/lsi-adm-3a/bitmap/07-22.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/07-23.png | Bin 0 -> 94 bytes resources/lsi-adm-3a/bitmap/07-24.png | Bin 0 -> 90 bytes resources/lsi-adm-3a/bitmap/07-25.png | Bin 0 -> 94 bytes resources/lsi-adm-3a/bitmap/07-26.png | Bin 0 -> 86 bytes resources/lsi-adm-3a/bitmap/07-27.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/07-28.png | Bin 0 -> 96 bytes resources/lsi-adm-3a/bitmap/07-29.png | Bin 0 -> 95 bytes resources/lsi-adm-3a/bitmap/07-30.png | Bin 0 -> 86 bytes resources/lsi-adm-3a/bitmap/07-31.png | Bin 0 -> 76 bytes 262 files changed, 2294 insertions(+), 376 deletions(-) create mode 100644 resources/lsi-adm-3a/bitmap/00-00.png create mode 100644 resources/lsi-adm-3a/bitmap/00-01.png create mode 100644 resources/lsi-adm-3a/bitmap/00-02.png create mode 100644 resources/lsi-adm-3a/bitmap/00-03.png create mode 100644 resources/lsi-adm-3a/bitmap/00-04.png create mode 100644 resources/lsi-adm-3a/bitmap/00-05.png create mode 100644 resources/lsi-adm-3a/bitmap/00-06.png create mode 100644 resources/lsi-adm-3a/bitmap/00-07.png create mode 100644 resources/lsi-adm-3a/bitmap/00-08.png create mode 100644 resources/lsi-adm-3a/bitmap/00-09.png create mode 100644 resources/lsi-adm-3a/bitmap/00-10.png create mode 100644 resources/lsi-adm-3a/bitmap/00-11.png create mode 100644 resources/lsi-adm-3a/bitmap/00-12.png create mode 100644 resources/lsi-adm-3a/bitmap/00-13.png create mode 100644 resources/lsi-adm-3a/bitmap/00-14.png create mode 100644 resources/lsi-adm-3a/bitmap/00-15.png create mode 100644 resources/lsi-adm-3a/bitmap/00-16.png create mode 100644 resources/lsi-adm-3a/bitmap/00-17.png create mode 100644 resources/lsi-adm-3a/bitmap/00-18.png create mode 100644 resources/lsi-adm-3a/bitmap/00-19.png create mode 100644 resources/lsi-adm-3a/bitmap/00-20.png create mode 100644 resources/lsi-adm-3a/bitmap/00-21.png create mode 100644 resources/lsi-adm-3a/bitmap/00-22.png create mode 100644 resources/lsi-adm-3a/bitmap/00-23.png create mode 100644 resources/lsi-adm-3a/bitmap/00-24.png create mode 100644 resources/lsi-adm-3a/bitmap/00-25.png create mode 100644 resources/lsi-adm-3a/bitmap/00-26.png create mode 100644 resources/lsi-adm-3a/bitmap/00-27.png create mode 100644 resources/lsi-adm-3a/bitmap/00-28.png create mode 100644 resources/lsi-adm-3a/bitmap/00-29.png create mode 100644 resources/lsi-adm-3a/bitmap/00-30.png create mode 100644 resources/lsi-adm-3a/bitmap/00-31.png create mode 100644 resources/lsi-adm-3a/bitmap/01-00.png create mode 100644 resources/lsi-adm-3a/bitmap/01-01.png create mode 100644 resources/lsi-adm-3a/bitmap/01-02.png create mode 100644 resources/lsi-adm-3a/bitmap/01-03.png create mode 100644 resources/lsi-adm-3a/bitmap/01-04.png create mode 100644 resources/lsi-adm-3a/bitmap/01-05.png create mode 100644 resources/lsi-adm-3a/bitmap/01-06.png create mode 100644 resources/lsi-adm-3a/bitmap/01-07.png create mode 100644 resources/lsi-adm-3a/bitmap/01-08.png create mode 100644 resources/lsi-adm-3a/bitmap/01-09.png create mode 100644 resources/lsi-adm-3a/bitmap/01-10.png create mode 100644 resources/lsi-adm-3a/bitmap/01-11.png create mode 100644 resources/lsi-adm-3a/bitmap/01-12.png create mode 100644 resources/lsi-adm-3a/bitmap/01-13.png create mode 100644 resources/lsi-adm-3a/bitmap/01-14.png create mode 100644 resources/lsi-adm-3a/bitmap/01-15.png create mode 100644 resources/lsi-adm-3a/bitmap/01-16.png create mode 100644 resources/lsi-adm-3a/bitmap/01-17.png create mode 100644 resources/lsi-adm-3a/bitmap/01-18.png create mode 100644 resources/lsi-adm-3a/bitmap/01-19.png create mode 100644 resources/lsi-adm-3a/bitmap/01-20.png create mode 100644 resources/lsi-adm-3a/bitmap/01-21.png create mode 100644 resources/lsi-adm-3a/bitmap/01-22.png create mode 100644 resources/lsi-adm-3a/bitmap/01-23.png create mode 100644 resources/lsi-adm-3a/bitmap/01-24.png create mode 100644 resources/lsi-adm-3a/bitmap/01-25.png create mode 100644 resources/lsi-adm-3a/bitmap/01-26.png create mode 100644 resources/lsi-adm-3a/bitmap/01-27.png create mode 100644 resources/lsi-adm-3a/bitmap/01-28.png create mode 100644 resources/lsi-adm-3a/bitmap/01-29.png create mode 100644 resources/lsi-adm-3a/bitmap/01-30.png create mode 100644 resources/lsi-adm-3a/bitmap/01-31.png create mode 100644 resources/lsi-adm-3a/bitmap/02-00.png create mode 100644 resources/lsi-adm-3a/bitmap/02-01.png create mode 100644 resources/lsi-adm-3a/bitmap/02-02.png create mode 100644 resources/lsi-adm-3a/bitmap/02-03.png create mode 100644 resources/lsi-adm-3a/bitmap/02-04.png create mode 100644 resources/lsi-adm-3a/bitmap/02-05.png create mode 100644 resources/lsi-adm-3a/bitmap/02-06.png create mode 100644 resources/lsi-adm-3a/bitmap/02-07.png create mode 100644 resources/lsi-adm-3a/bitmap/02-08.png create mode 100644 resources/lsi-adm-3a/bitmap/02-09.png create mode 100644 resources/lsi-adm-3a/bitmap/02-10.png create mode 100644 resources/lsi-adm-3a/bitmap/02-11.png create mode 100644 resources/lsi-adm-3a/bitmap/02-12.png create mode 100644 resources/lsi-adm-3a/bitmap/02-13.png create mode 100644 resources/lsi-adm-3a/bitmap/02-14.png create mode 100644 resources/lsi-adm-3a/bitmap/02-15.png create mode 100644 resources/lsi-adm-3a/bitmap/02-16.png create mode 100644 resources/lsi-adm-3a/bitmap/02-17.png create mode 100644 resources/lsi-adm-3a/bitmap/02-18.png create mode 100644 resources/lsi-adm-3a/bitmap/02-19.png create mode 100644 resources/lsi-adm-3a/bitmap/02-20.png create mode 100644 resources/lsi-adm-3a/bitmap/02-21.png create mode 100644 resources/lsi-adm-3a/bitmap/02-22.png create mode 100644 resources/lsi-adm-3a/bitmap/02-23.png create mode 100644 resources/lsi-adm-3a/bitmap/02-24.png create mode 100644 resources/lsi-adm-3a/bitmap/02-25.png create mode 100644 resources/lsi-adm-3a/bitmap/02-26.png create mode 100644 resources/lsi-adm-3a/bitmap/02-27.png create mode 100644 resources/lsi-adm-3a/bitmap/02-28.png create mode 100644 resources/lsi-adm-3a/bitmap/02-29.png create mode 100644 resources/lsi-adm-3a/bitmap/02-30.png create mode 100644 resources/lsi-adm-3a/bitmap/02-31.png create mode 100644 resources/lsi-adm-3a/bitmap/03-00.png create mode 100644 resources/lsi-adm-3a/bitmap/03-01.png create mode 100644 resources/lsi-adm-3a/bitmap/03-02.png create mode 100644 resources/lsi-adm-3a/bitmap/03-03.png create mode 100644 resources/lsi-adm-3a/bitmap/03-04.png create mode 100644 resources/lsi-adm-3a/bitmap/03-05.png create mode 100644 resources/lsi-adm-3a/bitmap/03-06.png create mode 100644 resources/lsi-adm-3a/bitmap/03-07.png create mode 100644 resources/lsi-adm-3a/bitmap/03-08.png create mode 100644 resources/lsi-adm-3a/bitmap/03-09.png create mode 100644 resources/lsi-adm-3a/bitmap/03-10.png create mode 100644 resources/lsi-adm-3a/bitmap/03-11.png create mode 100644 resources/lsi-adm-3a/bitmap/03-12.png create mode 100644 resources/lsi-adm-3a/bitmap/03-13.png create mode 100644 resources/lsi-adm-3a/bitmap/03-14.png create mode 100644 resources/lsi-adm-3a/bitmap/03-15.png create mode 100644 resources/lsi-adm-3a/bitmap/03-16.png create mode 100644 resources/lsi-adm-3a/bitmap/03-17.png create mode 100644 resources/lsi-adm-3a/bitmap/03-18.png create mode 100644 resources/lsi-adm-3a/bitmap/03-19.png create mode 100644 resources/lsi-adm-3a/bitmap/03-20.png create mode 100644 resources/lsi-adm-3a/bitmap/03-21.png create mode 100644 resources/lsi-adm-3a/bitmap/03-22.png create mode 100644 resources/lsi-adm-3a/bitmap/03-23.png create mode 100644 resources/lsi-adm-3a/bitmap/03-24.png create mode 100644 resources/lsi-adm-3a/bitmap/03-25.png create mode 100644 resources/lsi-adm-3a/bitmap/03-26.png create mode 100644 resources/lsi-adm-3a/bitmap/03-27.png create mode 100644 resources/lsi-adm-3a/bitmap/03-28.png create mode 100644 resources/lsi-adm-3a/bitmap/03-29.png create mode 100644 resources/lsi-adm-3a/bitmap/03-30.png create mode 100644 resources/lsi-adm-3a/bitmap/03-31.png create mode 100644 resources/lsi-adm-3a/bitmap/04-00.png create mode 100644 resources/lsi-adm-3a/bitmap/04-01.png create mode 100644 resources/lsi-adm-3a/bitmap/04-02.png create mode 100644 resources/lsi-adm-3a/bitmap/04-03.png create mode 100644 resources/lsi-adm-3a/bitmap/04-04.png create mode 100644 resources/lsi-adm-3a/bitmap/04-05.png create mode 100644 resources/lsi-adm-3a/bitmap/04-06.png create mode 100644 resources/lsi-adm-3a/bitmap/04-07.png create mode 100644 resources/lsi-adm-3a/bitmap/04-08.png create mode 100644 resources/lsi-adm-3a/bitmap/04-09.png create mode 100644 resources/lsi-adm-3a/bitmap/04-10.png create mode 100644 resources/lsi-adm-3a/bitmap/04-11.png create mode 100644 resources/lsi-adm-3a/bitmap/04-12.png create mode 100644 resources/lsi-adm-3a/bitmap/04-13.png create mode 100644 resources/lsi-adm-3a/bitmap/04-14.png create mode 100644 resources/lsi-adm-3a/bitmap/04-15.png create mode 100644 resources/lsi-adm-3a/bitmap/04-16.png create mode 100644 resources/lsi-adm-3a/bitmap/04-17.png create mode 100644 resources/lsi-adm-3a/bitmap/04-18.png create mode 100644 resources/lsi-adm-3a/bitmap/04-19.png create mode 100644 resources/lsi-adm-3a/bitmap/04-20.png create mode 100644 resources/lsi-adm-3a/bitmap/04-21.png create mode 100644 resources/lsi-adm-3a/bitmap/04-22.png create mode 100644 resources/lsi-adm-3a/bitmap/04-23.png create mode 100644 resources/lsi-adm-3a/bitmap/04-24.png create mode 100644 resources/lsi-adm-3a/bitmap/04-25.png create mode 100644 resources/lsi-adm-3a/bitmap/04-26.png create mode 100644 resources/lsi-adm-3a/bitmap/04-27.png create mode 100644 resources/lsi-adm-3a/bitmap/04-28.png create mode 100644 resources/lsi-adm-3a/bitmap/04-29.png create mode 100644 resources/lsi-adm-3a/bitmap/04-30.png create mode 100644 resources/lsi-adm-3a/bitmap/04-31.png create mode 100644 resources/lsi-adm-3a/bitmap/05-00.png create mode 100644 resources/lsi-adm-3a/bitmap/05-01.png create mode 100644 resources/lsi-adm-3a/bitmap/05-02.png create mode 100644 resources/lsi-adm-3a/bitmap/05-03.png create mode 100644 resources/lsi-adm-3a/bitmap/05-04.png create mode 100644 resources/lsi-adm-3a/bitmap/05-05.png create mode 100644 resources/lsi-adm-3a/bitmap/05-06.png create mode 100644 resources/lsi-adm-3a/bitmap/05-07.png create mode 100644 resources/lsi-adm-3a/bitmap/05-08.png create mode 100644 resources/lsi-adm-3a/bitmap/05-09.png create mode 100644 resources/lsi-adm-3a/bitmap/05-10.png create mode 100644 resources/lsi-adm-3a/bitmap/05-11.png create mode 100644 resources/lsi-adm-3a/bitmap/05-12.png create mode 100644 resources/lsi-adm-3a/bitmap/05-13.png create mode 100644 resources/lsi-adm-3a/bitmap/05-14.png create mode 100644 resources/lsi-adm-3a/bitmap/05-15.png create mode 100644 resources/lsi-adm-3a/bitmap/05-16.png create mode 100644 resources/lsi-adm-3a/bitmap/05-17.png create mode 100644 resources/lsi-adm-3a/bitmap/05-18.png create mode 100644 resources/lsi-adm-3a/bitmap/05-19.png create mode 100644 resources/lsi-adm-3a/bitmap/05-20.png create mode 100644 resources/lsi-adm-3a/bitmap/05-21.png create mode 100644 resources/lsi-adm-3a/bitmap/05-22.png create mode 100644 resources/lsi-adm-3a/bitmap/05-23.png create mode 100644 resources/lsi-adm-3a/bitmap/05-24.png create mode 100644 resources/lsi-adm-3a/bitmap/05-25.png create mode 100644 resources/lsi-adm-3a/bitmap/05-26.png create mode 100644 resources/lsi-adm-3a/bitmap/05-27.png create mode 100644 resources/lsi-adm-3a/bitmap/05-28.png create mode 100644 resources/lsi-adm-3a/bitmap/05-29.png create mode 100644 resources/lsi-adm-3a/bitmap/05-30.png create mode 100644 resources/lsi-adm-3a/bitmap/05-31.png create mode 100644 resources/lsi-adm-3a/bitmap/06-00.png create mode 100644 resources/lsi-adm-3a/bitmap/06-01.png create mode 100644 resources/lsi-adm-3a/bitmap/06-02.png create mode 100644 resources/lsi-adm-3a/bitmap/06-03.png create mode 100644 resources/lsi-adm-3a/bitmap/06-04.png create mode 100644 resources/lsi-adm-3a/bitmap/06-05.png create mode 100644 resources/lsi-adm-3a/bitmap/06-06.png create mode 100644 resources/lsi-adm-3a/bitmap/06-07.png create mode 100644 resources/lsi-adm-3a/bitmap/06-08.png create mode 100644 resources/lsi-adm-3a/bitmap/06-09.png create mode 100644 resources/lsi-adm-3a/bitmap/06-10.png create mode 100644 resources/lsi-adm-3a/bitmap/06-11.png create mode 100644 resources/lsi-adm-3a/bitmap/06-12.png create mode 100644 resources/lsi-adm-3a/bitmap/06-13.png create mode 100644 resources/lsi-adm-3a/bitmap/06-14.png create mode 100644 resources/lsi-adm-3a/bitmap/06-15.png create mode 100644 resources/lsi-adm-3a/bitmap/06-16.png create mode 100644 resources/lsi-adm-3a/bitmap/06-17.png create mode 100644 resources/lsi-adm-3a/bitmap/06-18.png create mode 100644 resources/lsi-adm-3a/bitmap/06-19.png create mode 100644 resources/lsi-adm-3a/bitmap/06-20.png create mode 100644 resources/lsi-adm-3a/bitmap/06-21.png create mode 100644 resources/lsi-adm-3a/bitmap/06-22.png create mode 100644 resources/lsi-adm-3a/bitmap/06-23.png create mode 100644 resources/lsi-adm-3a/bitmap/06-24.png create mode 100644 resources/lsi-adm-3a/bitmap/06-25.png create mode 100644 resources/lsi-adm-3a/bitmap/06-26.png create mode 100644 resources/lsi-adm-3a/bitmap/06-27.png create mode 100644 resources/lsi-adm-3a/bitmap/06-28.png create mode 100644 resources/lsi-adm-3a/bitmap/06-29.png create mode 100644 resources/lsi-adm-3a/bitmap/06-30.png create mode 100644 resources/lsi-adm-3a/bitmap/06-31.png create mode 100644 resources/lsi-adm-3a/bitmap/07-00.png create mode 100644 resources/lsi-adm-3a/bitmap/07-01.png create mode 100644 resources/lsi-adm-3a/bitmap/07-02.png create mode 100644 resources/lsi-adm-3a/bitmap/07-03.png create mode 100644 resources/lsi-adm-3a/bitmap/07-04.png create mode 100644 resources/lsi-adm-3a/bitmap/07-05.png create mode 100644 resources/lsi-adm-3a/bitmap/07-06.png create mode 100644 resources/lsi-adm-3a/bitmap/07-07.png create mode 100644 resources/lsi-adm-3a/bitmap/07-08.png create mode 100644 resources/lsi-adm-3a/bitmap/07-09.png create mode 100644 resources/lsi-adm-3a/bitmap/07-10.png create mode 100644 resources/lsi-adm-3a/bitmap/07-11.png create mode 100644 resources/lsi-adm-3a/bitmap/07-12.png create mode 100644 resources/lsi-adm-3a/bitmap/07-13.png create mode 100644 resources/lsi-adm-3a/bitmap/07-14.png create mode 100644 resources/lsi-adm-3a/bitmap/07-15.png create mode 100644 resources/lsi-adm-3a/bitmap/07-16.png create mode 100644 resources/lsi-adm-3a/bitmap/07-17.png create mode 100644 resources/lsi-adm-3a/bitmap/07-18.png create mode 100644 resources/lsi-adm-3a/bitmap/07-19.png create mode 100644 resources/lsi-adm-3a/bitmap/07-20.png create mode 100644 resources/lsi-adm-3a/bitmap/07-21.png create mode 100644 resources/lsi-adm-3a/bitmap/07-22.png create mode 100644 resources/lsi-adm-3a/bitmap/07-23.png create mode 100644 resources/lsi-adm-3a/bitmap/07-24.png create mode 100644 resources/lsi-adm-3a/bitmap/07-25.png create mode 100644 resources/lsi-adm-3a/bitmap/07-26.png create mode 100644 resources/lsi-adm-3a/bitmap/07-27.png create mode 100644 resources/lsi-adm-3a/bitmap/07-28.png create mode 100644 resources/lsi-adm-3a/bitmap/07-29.png create mode 100644 resources/lsi-adm-3a/bitmap/07-30.png create mode 100644 resources/lsi-adm-3a/bitmap/07-31.png diff --git a/plugins/compiler/as-z80/src/main/examples/hello_world.asm b/plugins/compiler/as-z80/src/main/examples/hello_world.asm index 7b6f20d28..ea0d7eaca 100644 --- a/plugins/compiler/as-z80/src/main/examples/hello_world.asm +++ b/plugins/compiler/as-z80/src/main/examples/hello_world.asm @@ -4,13 +4,18 @@ ld HL, message loop: ld A, (HL) cp 0 -jr Z, end +jr z, exit out (11H), A inc HL jp loop -end: +exit: halt message: -db "Hello world!",0 \ No newline at end of file +db 201, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 187, 10, 13 +db 186, "Hello world!", 186, 10, 13 +db 200, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 188 +db 0 + + diff --git a/plugins/compiler/raspc-rasp/src/main/examples/RAMexamples.txt b/plugins/compiler/raspc-rasp/src/main/examples/RAMexamples.txt index e9d93a7e5..cae562097 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/RAMexamples.txt +++ b/plugins/compiler/raspc-rasp/src/main/examples/RAMexamples.txt @@ -8,10 +8,10 @@ LOAD 1 DIV 2 STORE 1 WRITE 1 -JMP end +JMP exit zero: WRITE =0 -end: +exit: HALT Program code: diff --git a/plugins/compiler/raspc-rasp/src/main/examples/RASPexamples.txt b/plugins/compiler/raspc-rasp/src/main/examples/RASPexamples.txt index 0f0a72290..379839fae 100644 --- a/plugins/compiler/raspc-rasp/src/main/examples/RASPexamples.txt +++ b/plugins/compiler/raspc-rasp/src/main/examples/RASPexamples.txt @@ -8,10 +8,10 @@ LOAD 100 DIV 101 STORE 100 WRITE 100 -JMP end +JMP exit zero: WRITE =0 -end: +exit: HALT Program code: diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf index e9c7756a19b856d0e7a13fd9a19d7c2ac59cb0ef..608c7c8c4361464e91b3e2b9db90ad226b3dd392 100644 GIT binary patch delta 8189 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 Q&^0vJEE8dA&J2u60PpyOnE(I) diff --git a/resources/lsi-adm-3a/adm-3a.ttf b/resources/lsi-adm-3a/adm-3a.ttf index e9c7756a19b856d0e7a13fd9a19d7c2ac59cb0ef..608c7c8c4361464e91b3e2b9db90ad226b3dd392 100644 GIT binary patch delta 8189 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 Q&^0vJEE8dA&J2u60PpyOnE(I) diff --git a/resources/lsi-adm-3a/adm3a.sfd b/resources/lsi-adm-3a/adm3a.sfd index f522dd783..fc5f1f10c 100644 --- a/resources/lsi-adm-3a/adm3a.sfd +++ b/resources/lsi-adm-3a/adm3a.sfd @@ -12,9 +12,10 @@ UnderlineWidth: 208 Ascent: 1792 Descent: 0 InvalidEm: 0 -LayerCount: 2 +LayerCount: 3 Layer: 0 1 "Back" 1 Layer: 1 1 "Fore" 0 +Layer: 2 0 "Back 2" 1 XUID: [1021 261 208283644 15436461] StyleMap: 0x0040 FSType: 0 @@ -22,7 +23,7 @@ OS2Version: 0 OS2_WeightWidthSlopeOnly: 0 OS2_UseTypoMetrics: 1 CreationTime: 1663397476 -ModificationTime: 1666303265 +ModificationTime: 1668346681 PfmFamily: 49 TTFWeight: 400 TTFWidth: 5 @@ -53,10 +54,16 @@ NameList: AGL For New Fonts DisplaySize: -48 AntiAlias: 1 FitToEm: 0 -WinInfo: 0 38 14 +WinInfo: 0 25 19 BeginPrivate: 0 EndPrivate Grid +383.755950928 2688 m 0 + 383.755950928 -896 l 1024 +-1792 896.116882324 m 0 + 3584 896.116882324 l 1024 +-1792 640 m 0 + 3584 640 l 1024 197.862731934 2688 m 0 197.862731934 -896 l 1024 180.862731934 2688 m 0 @@ -188,7 +195,7 @@ Encoding: 1 1 0 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$:C.@.+:*&9s1_f6R)B%2 @@ -229,7 +236,7 @@ Encoding: 2 2 1 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 109 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CJNffG9V\638 @@ -253,7 +260,7 @@ Encoding: 3 3 2 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 108 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -277,7 +284,7 @@ Encoding: 4 4 3 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG9Xor#n @@ -314,7 +321,7 @@ Encoding: 5 5 4 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG971$7@ @@ -350,7 +357,7 @@ Encoding: 6 6 5 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 118 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8+BNffG971$7@ @@ -383,7 +390,7 @@ Encoding: 7 7 6 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 122 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8CNNffG9`^HN: @@ -437,7 +444,7 @@ Encoding: 8 8 7 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 114 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3&!@&g6 @@ -467,7 +474,7 @@ Encoding: 9 9 8 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 104 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns4f$5aWu @@ -494,7 +501,7 @@ Encoding: 10 10 9 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 115 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -524,7 +531,7 @@ Encoding: 11 11 10 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 115 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3&!@&g6 @@ -554,7 +561,7 @@ Encoding: 12 12 11 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 117 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8Bu3Ns3&!@&g6 @@ -584,7 +591,7 @@ Encoding: 13 13 12 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 120 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NR8(50F.aCrr8Tp#)6VB @@ -618,7 +625,7 @@ Encoding: 14 14 13 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 124 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$NmS16+:&(=s8UEqUl0oQ @@ -656,7 +663,7 @@ Encoding: 15 15 14 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 117 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8C%,9r(&3hH^h @@ -693,7 +700,7 @@ Encoding: 16 16 15 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 125 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$NmS16+:&'Ro`)[29fN`Y @@ -735,7 +742,7 @@ Encoding: 17 17 16 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 114 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HN: @@ -774,7 +781,7 @@ Encoding: 18 18 17 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 123 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?K_r!ro=GQ8CJNffG9N3T>a @@ -812,7 +819,7 @@ Encoding: 19 19 18 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9N3T>a @@ -854,7 +861,7 @@ Encoding: 20 20 19 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 122 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -894,7 +901,7 @@ Encoding: 21 21 20 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 115 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8CJNffG9Xot.% @@ -929,7 +936,7 @@ Encoding: 22 22 21 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 117 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -963,7 +970,7 @@ Encoding: 23 23 22 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 115 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -1008,7 +1015,7 @@ Encoding: 24 24 23 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 126 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W77fm5<#?L$:.Z&u+:&>Ss5t#,..n,f @@ -1048,7 +1055,7 @@ Encoding: 25 25 24 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 116 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8C%,9r(&3hH^h @@ -1082,7 +1089,7 @@ Encoding: 26 26 25 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 109 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8sb%RU9&*Yr8r @@ -1115,7 +1122,7 @@ Encoding: 27 27 26 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 118 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%RU9&*YsiL @@ -1150,7 +1157,7 @@ Encoding: 28 28 27 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 113 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8C%,9n7D"pQE9 @@ -1179,7 +1186,7 @@ Encoding: 29 29 28 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 115 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8+BNffG9Xor#n @@ -1210,7 +1217,7 @@ Encoding: 30 30 29 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 118 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns2BO@1f( @@ -1238,7 +1245,7 @@ Encoding: 31 31 30 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 117 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8Dg*$Z[QM@bLD @@ -1270,7 +1277,7 @@ Encoding: 33 33 31 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 96 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -1297,7 +1304,7 @@ Encoding: 34 34 32 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 103 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8CJNffG9X9;!; @@ -1324,7 +1331,7 @@ Encoding: 35 35 33 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 107 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CJNffG9X9;!; @@ -1375,7 +1382,7 @@ Encoding: 36 36 34 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 127 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W7S-!6<#?L$bs;]P5R^!,B't03:)+gl @@ -1433,7 +1440,7 @@ Encoding: 37 37 35 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$N_p8d+:(< @@ -1523,7 +1530,7 @@ Encoding: 39 39 37 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 100 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -1545,7 +1552,7 @@ Encoding: 40 40 38 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 111 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8CNNffG9`^HN: @@ -1573,7 +1580,7 @@ Encoding: 41 41 39 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 113 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -1601,7 +1608,7 @@ Encoding: 42 42 40 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 120 1 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NS=d?+:(?(s8UE1_?!r( @@ -1642,7 +1649,7 @@ Encoding: 43 43 41 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 114 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3&!@&g6 @@ -1672,7 +1679,7 @@ Encoding: 44 44 42 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 91 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2\'ehBu @@ -1698,7 +1705,7 @@ Encoding: 45 45 43 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 94 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns4Z$5e?V @@ -1720,7 +1727,7 @@ Encoding: 46 46 44 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 84 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[;S^Ap @@ -1742,7 +1749,7 @@ Encoding: 47 47 45 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 113 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns3P!_,XK @@ -1766,7 +1773,7 @@ Encoding: 48 48 46 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 120 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8+BNffG9Xor#n @@ -1805,7 +1812,7 @@ Encoding: 49 49 47 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 107 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CNNffG9`^HN: @@ -1843,7 +1850,7 @@ Encoding: 50 50 48 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 124 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?K_r!ro=GQ8+BNffG9Xor#n @@ -1889,7 +1896,7 @@ Encoding: 51 51 49 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 123 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?K_r!ro=GQ8sb%RU9&*Yr8r @@ -1936,7 +1943,7 @@ Encoding: 52 52 50 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 116 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -1971,7 +1978,7 @@ Encoding: 53 53 51 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 114 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8sb%RU9&*YsiL @@ -2011,7 +2018,7 @@ Encoding: 54 54 52 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+FNffG9`ah?c @@ -2052,7 +2059,7 @@ Encoding: 55 55 53 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 120 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8sb%RU9&*Yr8r @@ -2081,7 +2088,7 @@ Encoding: 56 56 54 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 100 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2131,7 +2138,7 @@ Encoding: 57 57 55 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 123 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2172,7 +2179,7 @@ Encoding: 58 58 56 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 97 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns4f$5aWu @@ -2199,7 +2206,7 @@ Encoding: 59 59 57 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 104 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns4f$5aWu @@ -2230,7 +2237,7 @@ Encoding: 60 60 58 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 116 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -2257,7 +2264,7 @@ Encoding: 61 61 59 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 96 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8Bu3Ns2`"cP]X @@ -2284,7 +2291,7 @@ Encoding: 62 62 60 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 114 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?L$c9Vp?+:&'8li7!DD@\!2 @@ -2311,7 +2318,7 @@ Encoding: 63 63 61 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 120 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2350,7 +2357,7 @@ Encoding: 64 64 62 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 124 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$N^4!P+:&,)nGcju-;[[9 @@ -2395,7 +2402,7 @@ Encoding: 65 65 63 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 119 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8CNNffG9`^HN: @@ -2433,7 +2440,7 @@ Encoding: 66 66 64 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 96 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8sb%RgE0H5;TS @@ -2474,7 +2481,7 @@ Encoding: 67 67 65 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 117 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2514,7 +2521,7 @@ Encoding: 68 68 66 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 98 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.7lon<#?K_r!ro=GQ8sb%RgE0H5;TS @@ -2545,7 +2552,7 @@ Encoding: 69 69 67 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 102 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8sb%RU9&*YsiL @@ -2575,7 +2582,7 @@ Encoding: 70 70 68 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 100 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8sb%RU9&*YsiL @@ -2603,7 +2610,7 @@ Encoding: 71 71 69 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 113 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8+BNffG971$7@ @@ -2638,7 +2645,7 @@ Encoding: 72 72 70 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 105 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -2668,7 +2675,7 @@ Encoding: 73 73 71 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 106 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2698,7 +2705,7 @@ Encoding: 74 74 72 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 100 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8Dg*$Z[QM@bLD @@ -2728,7 +2735,7 @@ Encoding: 75 75 73 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 118 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8C%,9r(&3hH^] @@ -2761,7 +2768,7 @@ Encoding: 76 76 74 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 94 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8C%,9n7D"pQEe @@ -2785,7 +2792,7 @@ Encoding: 77 77 75 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 116 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8C%,9r(&3hH^( @@ -2821,7 +2828,7 @@ Encoding: 78 78 76 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 114 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -2853,7 +2860,7 @@ Encoding: 79 79 77 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 103 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2891,7 +2898,7 @@ Encoding: 80 80 78 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 103 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8sb%RgE0H5;TS @@ -2924,7 +2931,7 @@ Encoding: 81 81 79 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 117 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2967,7 +2974,7 @@ Encoding: 82 82 80 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 118 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%RgE0H5;TS @@ -3005,7 +3012,7 @@ Encoding: 83 83 81 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 117 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n @@ -3053,7 +3060,7 @@ Encoding: 84 84 82 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 97 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8sb%RU9&*YoTJ @@ -3079,7 +3086,7 @@ Encoding: 85 85 83 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 95 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -3109,7 +3116,7 @@ Encoding: 86 86 84 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 103 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -3138,7 +3145,7 @@ Encoding: 87 87 85 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 110 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -3172,7 +3179,7 @@ Encoding: 88 88 86 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L,:Kn/++:)bps..=>UQd0V @@ -3211,7 +3218,7 @@ Encoding: 89 89 87 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 110 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -3242,7 +3249,7 @@ Encoding: 90 90 88 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 120 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8sb%RU9&*Yr8r @@ -3273,7 +3280,7 @@ Encoding: 91 91 89 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 97 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8sb%RU9&*Yt,T @@ -3299,7 +3306,7 @@ Encoding: 92 92 90 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 110 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns22,9nF> @@ -3323,7 +3330,7 @@ Encoding: 93 93 91 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 100 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8sb%RU9&*Yr8r @@ -3349,7 +3356,7 @@ Encoding: 94 94 92 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 110 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns4f$5aWu @@ -3376,7 +3383,7 @@ Encoding: 95 95 93 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 87 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y @@ -3398,7 +3405,7 @@ Encoding: 96 96 94 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 106 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8CJNffG9V\638 @@ -3422,7 +3429,7 @@ Encoding: 97 97 95 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 119 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -3463,7 +3470,7 @@ Encoding: 98 98 96 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 116 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9V\638 @@ -3501,7 +3508,7 @@ Encoding: 99 99 97 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 113 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns2*9E?@_ @@ -3533,7 +3540,7 @@ Encoding: 100 100 98 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 120 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8D_*$Z[Q1)J/( @@ -3571,7 +3578,7 @@ Encoding: 101 101 99 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 115 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3&!@&g6 @@ -3612,7 +3619,7 @@ Encoding: 102 102 100 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 122 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -3653,7 +3660,7 @@ Encoding: 103 103 101 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 123 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?L$N<'@d+:&'To`$RG-VQk$ @@ -3694,7 +3701,7 @@ Encoding: 104 104 102 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 110 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8CJNffG9V\638 @@ -3725,7 +3732,7 @@ Encoding: 105 105 103 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 114 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -3759,7 +3766,7 @@ Encoding: 106 106 104 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 112 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8D_*$Z[Q1)J/( @@ -3796,7 +3803,7 @@ Encoding: 107 107 105 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 116 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9V\638 @@ -3829,7 +3836,7 @@ Encoding: 108 108 106 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 108 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8CJNffG9N3T>a @@ -3857,7 +3864,7 @@ Encoding: 109 109 107 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 113 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns22,9nE8 @@ -3895,7 +3902,7 @@ Encoding: 110 110 108 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 110 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -3923,7 +3930,7 @@ Encoding: 111 111 109 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 119 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8Bu3Ns3&!@&g6 @@ -3958,7 +3965,7 @@ Encoding: 112 112 110 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 118 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -3991,7 +3998,7 @@ Encoding: 113 113 111 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 112 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -4028,7 +4035,7 @@ Encoding: 114 114 112 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 114 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3"!@&g6 @@ -4056,7 +4063,7 @@ Encoding: 115 115 113 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 122 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -4097,7 +4104,7 @@ Encoding: 116 116 114 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 117 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CNNffG9`^HN: @@ -4134,7 +4141,7 @@ Encoding: 117 117 115 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 113 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns3"!@&g6 @@ -4164,7 +4171,7 @@ Encoding: 118 118 116 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 112 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns22,9nFj @@ -4193,7 +4200,7 @@ Encoding: 119 119 117 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 108 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8Bu3Ns22,9nFj @@ -4236,7 +4243,7 @@ Encoding: 120 120 118 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 124 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$O22;+0EaaEs8UE72JImJ @@ -4267,7 +4274,7 @@ Encoding: 121 121 119 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 118 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns3"!@&g6 @@ -4304,7 +4311,7 @@ Encoding: 122 122 120 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 111 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8Bu3Ns2BOMigR @@ -4340,7 +4347,7 @@ Encoding: 123 123 121 Width: 1280 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 116 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -4379,7 +4386,7 @@ Encoding: 124 124 122 Width: 1024 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 96 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -4406,7 +4413,7 @@ Encoding: 125 125 123 Width: 1280 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 112 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?L$c7oA#+:(<]kl,cY@:8B` @@ -4445,7 +4452,7 @@ Encoding: 126 126 124 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 105 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8Bu3Ns4^$5aWu @@ -4475,7 +4482,7 @@ Encoding: 127 127 125 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 91 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2`"cP]X @@ -4497,7 +4504,7 @@ Encoding: 128 128 126 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 125 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$Na!+r&.AZ[o_qq3)XZ$a @@ -4544,7 +4551,7 @@ Encoding: 129 129 127 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 104 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9Xot.% @@ -4582,7 +4589,7 @@ Encoding: 130 130 128 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8D_*$Z[Q!sg+R @@ -4629,7 +4636,7 @@ Encoding: 131 131 129 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 123 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?L$NWBIe+:&',qYun_#oBn? @@ -4681,7 +4688,7 @@ Encoding: 132 132 130 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9X9;!; @@ -4733,7 +4740,7 @@ Encoding: 133 133 131 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 123 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?L$Nf+5E+:&'Ro`)[2:,ig- @@ -4782,7 +4789,7 @@ Encoding: 134 134 132 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 124 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$N_'QX+:J@3q#<"J$)@]t @@ -4837,7 +4844,7 @@ Encoding: 135 135 133 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+FNffG9`ah?c @@ -4876,7 +4883,7 @@ Encoding: 136 136 134 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 122 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?L4NWBIe+:&'Tq#BQFqYl">.e9oz8OZBBY!QNJ EndImage2 Fore +SplineSet +587 1024 m 0,0,1 + 512 1024 512 1024 512 949 c 24,2,3 + 512 949 512 949 512 587 c 0,4,5 + 512 512 512 512 587 512 c 24,6,-1 + 949 512 l 0,7,8 + 1024 512 1024 512 1024 587 c 24,9,10 + 1024 587 1024 587 1024 949 c 2,11,12 + 1024 1024 1024 1024 949 1024 c 8,13,14 + 768 1024 768 1024 587 1024 c 0,0,1 +949 1280 m 2,15,16 + 1280 1280 1280 1280 1280 949 c 0,17,18 + 1280 949 1280 949 1280 587 c 0,19,20 + 1280 256 1280 256 949 256 c 10,21,-1 + 587 256 l 0,22,23 + 256 256 256 256 256 587 c 24,24,25 + 256 587 256 587 256 949 c 1,26,27 + 256 1280 256 1280 512 1280 c 0,28,29 + 512 1280 512 1280 512 1461 c 0,30,31 + 512 1536 512 1536 437 1536 c 24,32,-1 + 0 1536 l 24,33,34 + 0 1536 0 1536 0 1792 c 25,35,36 + 1 1792 1 1792 437 1792 c 0,37,38 + 768 1792 768 1792 768 1461 c 24,39,-1 + 768 1280 l 24,40,-1 + 949 1280 l 2,15,16 +EndSplineSet Validated: 1 EndChar StartChar: uni0096 Encoding: 150 150 148 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 117 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CJNffG9N3T?l ":E!T!@^DqO9m04OoPMn2HTrMJ?=?AYgJ[c?i_.'c#/nk!'65V&'==Aec5[M!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +768 1461 m 0,0,1 + 768 1536 768 1536 693 1536 c 24,2,-1 + 331 1536 l 0,3,4 + 256 1536 256 1536 256 1461 c 24,5,6 + 256 1461 256 1461 256 1337 c 25,7,-1 + 313 1280 l 24,8,-1 + 512 1280 l 24,9,-1 + 512 331 l 0,10,11 + 512 256 512 256 587 256 c 24,12,-1 + 1024 256 l 24,13,-1 + 1024 1280 l 24,14,-1 + 768 1280 l 24,15,-1 + 768 1461 l 0,0,1 +0 1461 m 0,16,17 + 0 1792 0 1792 331 1792 c 24,18,-1 + 693 1792 l 0,19,20 + 1024 1792 1024 1792 1024 1461 c 24,21,-1 + 1024 1337 l 0,22,23 + 1024 1280 1024 1280 1081 1280 c 24,24,-1 + 1280 1280 l 24,25,-1 + 1280 0 l 25,26,-1 + 587 0 l 0,27,28 + 256 0 256 0 256 331 c 24,29,-1 + 256 1280 l 24,30,-1 + 0 1280 l 24,31,32 + 0 1287 0 1287 0 1461 c 0,16,17 +EndSplineSet Validated: 1 EndChar StartChar: uni0097 Encoding: 151 151 149 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 111 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8sb%]fYs3[Tpk #W"5fe7&J+O:XqqAcfP1YQ@LH#SG2oY^d/"k=>S;7MH1/$/OGBF EndImage2 Fore +SplineSet +1280 1280 m 24,0,-1 + 1280 0 l 25,1,2 + 1280 0 1280 0 587 0 c 24,3,4 + 256 0 256 0 256 331 c 0,5,6 + 256 640 256 640 256 1280 c 24,7,8 + 256 1280 256 1280 455 1280 c 24,9,10 + 512 1280 512 1280 512 1337 c 0,11,12 + 512 1461 512 1461 512 1461 c 24,13,14 + 512 1536 512 1536 437 1536 c 0,15,16 + 437 1536 437 1536 0 1536 c 24,17,-1 + 0 1792 l 25,18,-1 + 437 1792 l 24,19,20 + 768 1792 768 1792 768 1461 c 0,21,22 + 768 1281 768 1281 768 1280 c 24,23,24 + 768 1280 768 1280 512 1280 c 24,25,-1 + 512 331 l 24,26,27 + 512 256 512 256 587 256 c 0,28,29 + 587 256 587 256 1024 256 c 24,30,-1 + 1024 1280 l 24,31,-1 + 1280 1280 l 24,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: uni0098 Encoding: 152 152 150 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 116 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9Xot.% QD<(8YSD-KYqT9F@N]lhgC7'h2Z]][Rtnd+J5jE[5Z\'g[VZ]jUha3>z8OZBBY!QNJ EndImage2 Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 1536 l 24,2,-1 + 1024 1536 l 24,3,4 + 1024 1536 1024 1536 1024 1792 c 25,0,-1 +512 1792 m 24,5,-1 + 512 1536 l 24,6,-1 + 256 1536 l 24,7,-1 + 256 1792 l 25,8,9 + 256 1792 256 1792 512 1792 c 24,5,-1 +1280 1280 m 24,10,11 + 1280 1280 1280 1280 1280 331 c 0,12,13 + 1280 0 1280 0 949 0 c 24,14,-1 + 512 0 l 24,15,-1 + 512 256 l 24,16,-1 + 949 256 l 0,17,18 + 1024 256 1024 256 1024 331 c 24,19,20 + 1024 331 1024 331 1024 512 c 24,21,-1 + 587 512 l 0,22,23 + 256 512 256 512 256 843 c 24,24,25 + 256 843 256 843 256 1280 c 24,26,-1 + 512 1280 l 24,27,-1 + 512 843 l 0,28,29 + 512 768 512 768 587 768 c 24,30,-1 + 1024 768 l 25,31,-1 + 1024 1280 l 24,32,33 + 1024 1280 1024 1280 1280 1280 c 24,10,11 +EndSplineSet Validated: 1 EndChar StartChar: uni0099 Encoding: 153 153 151 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 110 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8C%,9r(&#+pt` /0O?$]$P9sR?(e_827Co-56\mi=Ju(!\t7X)Z[-3(^ZKQ:]LIq!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 1536 l 24,2,-1 + 1024 1536 l 24,3,4 + 1024 1536 1024 1536 1024 1792 c 25,0,-1 +0 1792 m 25,5,-1 + 256 1792 l 25,6,-1 + 256 1536 l 24,7,-1 + 0 1536 l 24,8,9 + 0 1536 0 1536 0 1792 c 25,5,-1 +1024 949 m 0,10,11 + 1024 1024 1024 1024 949 1024 c 24,12,-1 + 331 1024 l 0,13,14 + 256 1024 256 1024 256 949 c 24,15,16 + 256 602 256 602 256 331 c 0,17,18 + 256 256 256 256 331 256 c 24,19,-1 + 949 256 l 0,20,21 + 1024 256 1024 256 1024 331 c 24,22,23 + 1024 467 1024 467 1024 949 c 0,10,11 +949 1280 m 0,24,25 + 1280 1280 1280 1280 1280 949 c 24,26,27 + 1280 474 1280 474 1280 331 c 0,28,29 + 1280 0 1280 0 949 0 c 24,30,-1 + 331 0 l 0,31,32 + 0 0 0 0 0 331 c 24,33,34 + 0 806 0 806 0 949 c 0,35,36 + 0 1280 0 1280 331 1280 c 24,37,38 + 331 1280 331 1280 949 1280 c 0,24,25 +EndSplineSet Validated: 1 EndChar StartChar: uni009A Encoding: 154 154 152 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 97 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8C%,9r(&#+o?< Qr)#I_P(38$cn[U/k>Xn!4\[3&p%V?i;`iX!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 1536 l 24,2,-1 + 1024 1536 l 24,3,4 + 1024 1536 1024 1536 1024 1792 c 25,0,-1 +256 1792 m 25,5,-1 + 256 1536 l 24,6,-1 + 0 1536 l 24,7,-1 + 0 1792 l 25,8,-1 + 256 1792 l 25,5,-1 +1280 1280 m 24,9,10 + 1280 1280 1280 1280 1280 331 c 0,11,12 + 1280 0 1280 0 949 0 c 24,13,-1 + 331 0 l 0,14,15 + 0 0 0 0 0 331 c 24,16,17 + 0 331 0 331 0 1280 c 24,18,-1 + 256 1280 l 24,19,-1 + 256 331 l 0,20,21 + 256 256 256 256 331 256 c 24,22,-1 + 949 256 l 0,23,24 + 1024 256 1024 256 1024 331 c 24,25,-1 + 1024 1280 l 24,26,27 + 1024 1280 1024 1280 1280 1280 c 24,9,10 +EndSplineSet Validated: 1 EndChar StartChar: uni009B Encoding: 155 155 153 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 122 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?L$NR8(5+:&'Rs8UE2K+e@/ @@ -5563,60 +5732,164 @@ Q`3';in!tUm[g4<\h=$sKf"laP0aGAR'\%a1Ns&o/_MNWomponhuM-h'+]WtMlHaW!!#SZ:.26O @"J@Y EndImage2 Fore +SplineSet +768 1280 m 24,0,-1 + 587 1280 l 0,1,2 + 512 1280 512 1280 512 1205 c 24,3,4 + 512 858 512 858 512 587 c 0,5,6 + 512 512 512 512 587 512 c 24,7,-1 + 768 512 l 24,8,9 + 768 512 768 512 768 1280 c 24,0,-1 +1280 1536 m 24,10,-1 + 1280 1280 l 24,11,-1 + 1024 1280 l 24,12,-1 + 1024 512 l 24,13,-1 + 1280 512 l 24,14,-1 + 1280 256 l 24,15,-1 + 1024 256 l 24,16,-1 + 1024 0 l 25,17,-1 + 768 0 l 25,18,-1 + 768 256 l 24,19,-1 + 587 256 l 0,20,21 + 256 256 256 256 256 587 c 24,22,23 + 256 1062 256 1062 256 1205 c 0,24,25 + 256 1536 256 1536 587 1536 c 24,26,-1 + 768 1536 l 24,27,-1 + 768 1792 l 25,28,-1 + 1024 1792 l 25,29,-1 + 1024 1536 l 24,30,-1 + 1280 1536 l 24,10,-1 +EndSplineSet Validated: 1 EndChar StartChar: uni009C Encoding: 156 156 154 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 113 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8CNNffHd!JJi$ $V17CJ]f1G$0XEYI*rb&]*%+D'ORNFK`t`^AiGYQ!.c.#&Hl>:i;`iX!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +1024 1792 m 25,0,-1 + 1024 1536 l 24,1,-1 + 587 1536 l 0,2,3 + 512 1536 512 1536 512 1461 c 24,4,5 + 512 1461 512 1461 512 512 c 24,6,-1 + 949 512 l 0,7,8 + 1024 512 1024 512 1024 587 c 24,9,-1 + 1024 768 l 25,10,-1 + 1280 768 l 25,11,12 + 1280 768 1280 768 1280 587 c 0,13,14 + 1280 256 1280 256 949 256 c 24,15,-1 + 0 256 l 24,16,-1 + 0 512 l 24,17,-1 + 256 512 l 24,18,-1 + 256 1461 l 0,19,20 + 256 1792 256 1792 587 1792 c 24,21,22 + 587 1792 587 1792 1024 1792 c 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: uni009D Encoding: 157 157 155 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 109 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8C%,9r(&3hH^I ((5m(A-5LALdnicA3P_eO;5%937r>*Co#hh!!@3^#&lu5f)PdN!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +640 1077 m 1,0,1 + 640 1077 640 1077 1024 1461 c 1,2,-1 + 1024 1792 l 25,3,-1 + 1280 1792 l 0,4,5 + 1280 1792 1280 1792 1280 1355 c 8,6,-1 + 949 1024 l 24,7,-1 + 1280 1024 l 24,8,9 + 1280 1024 1280 1024 1280 768 c 25,10,-1 + 768 768 l 25,11,12 + 768 768 768 768 768 512 c 24,13,-1 + 1280 512 l 24,14,15 + 1280 512 1280 512 1280 256 c 24,16,-1 + 768 256 l 24,17,-1 + 768 0 l 25,18,19 + 768 0 768 0 512 0 c 24,20,-1 + 512 256 l 24,21,-1 + 0 256 l 24,22,23 + 0 256 0 256 0 512 c 24,24,-1 + 512 512 l 24,25,26 + 512 512 512 512 512 768 c 25,27,-1 + 0 768 l 25,28,29 + 0 768 0 768 0 1024 c 24,30,-1 + 331 1024 l 24,31,-1 + 0 1355 l 25,32,-1 + 0 1792 l 25,33,-1 + 256 1792 l 1,34,-1 + 256 1461 l 1,35,-1 + 640 1077 l 1,0,1 +EndSplineSet Validated: 1 EndChar StartChar: uni009E Encoding: 158 158 156 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 116 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8sb%RgE0H5;TS A3i[S7MJ$"*n.r'Ug&Cf,1m>I6'0nVJF"Vm)dn7O)Q">OWN@3=kt"tbz8OZBBY!QNJ EndImage2 Fore +SplineSet +512 512 m 24,0,-1 + 1280 512 l 24,1,-1 + 1280 256 l 24,2,-1 + 1024 256 l 24,3,-1 + 1024 0 l 25,4,-1 + 768 0 l 25,5,-1 + 768 256 l 24,6,-1 + 512 256 l 24,7,8 + 512 256 512 256 512 512 c 24,0,-1 +1024 1461 m 0,9,10 + 1024 1536 1024 1536 949 1536 c 24,11,-1 + 256 1536 l 24,12,-1 + 256 1024 l 24,13,-1 + 949 1024 l 0,14,15 + 1024 1024 1024 1024 1024 1099 c 24,16,17 + 1024 1171 1024 1171 1024 1461 c 0,9,10 +0 1792 m 25,18,-1 + 949 1792 l 0,19,20 + 1280 1792 1280 1792 1280 1461 c 24,21,22 + 1280 1114 1280 1114 1280 1099 c 0,23,24 + 1280 768 1280 768 949 768 c 24,25,-1 + 256 768 l 25,26,-1 + 256 0 l 25,27,-1 + 0 0 l 25,28,-1 + 0 1792 l 25,18,-1 +EndSplineSet Validated: 1 EndChar StartChar: uni009F Encoding: 159 159 157 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8D_*$Z[Q!sg+R @@ -5624,15 +5897,38 @@ M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8D_*$Z[Q!sg+R JcGcN EndImage2 Fore +SplineSet +1280 1792 m 25,0,1 + 1280 1792 1280 1792 1280 1536 c 24,2,-1 + 843 1536 l 0,3,4 + 768 1536 768 1536 768 1461 c 25,5,6 + 768 1461 768 1461 768 1024 c 24,7,-1 + 1024 1024 l 24,8,9 + 1024 1024 1024 1024 1024 768 c 25,10,-1 + 768 768 l 25,11,-1 + 768 331 l 0,12,13 + 768 0 768 0 437 0 c 24,14,15 + 437 0 437 0 0 0 c 25,16,17 + 0 0 0 0 0 256 c 24,18,-1 + 437 256 l 0,19,20 + 512 256 512 256 512 331 c 24,21,22 + 512 331 512 331 512 768 c 25,23,-1 + 256 768 l 25,24,25 + 256 768 256 768 256 1024 c 0,26,-1 + 512 1024 l 25,27,28 + 512 1024 512 1024 512 1461 c 17,29,30 + 512 1792 512 1792 843 1792 c 24,31,32 + 843 1792 843 1792 1280 1792 c 25,0,1 +EndSplineSet Validated: 1 EndChar StartChar: uni00A0 Encoding: 160 160 158 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 125 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$N_p,`+:LRo])S$G(QNpF @@ -5640,75 +5936,197 @@ KTOPnE?4#5;)=B^WLCOLkf.)JPhhE`$6hQ8Km9=:'h\;Df0U7c@_Y%0!Sk=!*9^"N?iU0,!(fUS 7'8jaJcGcN EndImage2 Fore +SplineSet +768 437 m 0,0,1 + 768 512 768 512 693 512 c 0,2,-1 + 587 512 l 0,3,4 + 512 512 512 512 512 437 c 0,5,6 + 512 346 512 346 512 331 c 0,7,8 + 512 256 512 256 587 256 c 0,9,10 + 587 256 587 256 693 256 c 0,11,12 + 768 256 768 256 768 331 c 0,13,14 + 768 331 768 331 768 437 c 0,0,1 +768 1280 m 1,15,16 + 1024 1280 1024 1280 1024 949 c 1,17,-1 + 1024 256 l 24,18,-1 + 1223 256 l 0,19,20 + 1280 256 1280 256 1280 127 c 0,21,22 + 1280 0 1280 0 1223 0 c 24,23,24 + 1223 0 1223 0 587 0 c 0,25,26 + 256 0 256 0 256 331 c 24,27,28 + 256 331 256 331 256 437 c 0,29,30 + 256 768 256 768 587 768 c 24,31,-1 + 768 768 l 25,32,33 + 768 900 768 900 768 949 c 0,34,35 + 768 1024 768 1024 693 1024 c 24,36,-1 + 256 1024 l 24,37,38 + 256 1024 256 1024 256 1280 c 24,39,-1 + 512 1280 l 24,40,-1 + 512 1461 l 0,41,42 + 512 1792 512 1792 843 1792 c 24,43,44 + 843 1792 843 1792 1280 1792 c 25,45,46 + 1280 1792 1280 1792 1280 1536 c 24,47,-1 + 843 1536 l 0,48,49 + 768 1536 768 1536 768 1461 c 24,50,51 + 768 1461 768 1461 768 1280 c 1,15,16 +EndSplineSet Validated: 1 EndChar StartChar: exclamdown Encoding: 161 161 159 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 115 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#mY$.pLhRc+V#NJBF EndImage2 Fore +SplineSet +512 256 m 24,0,-1 + 512 1024 l 24,1,2 + 512 1024 512 1024 768 1024 c 24,3,-1 + 768 256 l 24,4,-1 + 1024 256 l 24,5,6 + 1024 256 1024 256 1024 0 c 25,7,-1 + 256 0 l 25,8,-1 + 256 256 l 24,9,-1 + 512 256 l 24,0,-1 +512 1280 m 24,10,11 + 512 1280 512 1280 512 1461 c 17,12,13 + 512 1792 512 1792 843 1792 c 0,14,15 + 843 1792 843 1792 1280 1792 c 0,16,17 + 1280 1792 1280 1792 1280 1536 c 0,18,-1 + 843 1536 l 1,19,20 + 768 1536 768 1536 768 1461 c 8,21,-1 + 768 1280 l 24,22,23 + 768 1280 768 1280 512 1280 c 24,10,11 +EndSplineSet Validated: 1 EndChar StartChar: cent Encoding: 162 162 160 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 118 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#kW'4;_d1fscP2ol,D.o8oiksD6R.KDOCfk>J_!W\Z<',H#YRNqk5!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +587 1024 m 0,0,1 + 512 1024 512 1024 512 949 c 24,2,3 + 512 949 512 949 512 331 c 0,4,5 + 512 256 512 256 587 256 c 24,6,-1 + 949 256 l 0,7,8 + 1024 256 1024 256 1024 331 c 24,9,10 + 1024 949 1024 949 1024 949 c 2,11,12 + 1024 1024 1024 1024 949 1024 c 8,13,14 + 768 1024 768 1024 587 1024 c 0,0,1 +949 1280 m 0,15,16 + 1280 1280 1280 1280 1280 949 c 24,17,18 + 1280 949 1280 949 1280 331 c 0,19,20 + 1280 0 1280 0 949 0 c 24,21,-1 + 587 0 l 0,22,23 + 256 0 256 0 256 331 c 24,24,25 + 256 806 256 806 256 949 c 0,26,27 + 256 1280 256 1280 512 1280 c 1,28,-1 + 512 1461 l 0,29,30 + 512 1792 512 1792 843 1792 c 24,31,32 + 843 1792 843 1792 1280 1792 c 25,33,34 + 1280 1792 1280 1792 1280 1536 c 24,35,-1 + 843 1536 l 0,36,37 + 768 1536 768 1536 768 1461 c 24,38,39 + 768 1461 768 1461 768 1280 c 24,40,-1 + 949 1280 l 0,15,16 +EndSplineSet Validated: 1 EndChar StartChar: sterling Encoding: 163 163 161 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 112 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#mQ$-8:n-D4HA1C]bL>QNK>+NL21%C66=DFY-R6K,CSz8OZBBY!QNJ EndImage2 Fore +SplineSet +1280 1280 m 24,0,-1 + 1280 0 l 25,1,-1 + 587 0 l 0,2,3 + 256 0 256 0 256 331 c 24,4,5 + 256 331 256 331 256 1205 c 25,6,-1 + 843 1792 l 24,7,-1 + 1280 1792 l 25,8,-1 + 1280 1536 l 24,9,-1 + 967 1536 l 24,10,-1 + 512 1099 l 25,11,12 + 512 678 512 678 512 331 c 0,13,14 + 512 256 512 256 587 256 c 24,15,-1 + 1024 256 l 24,16,-1 + 1024 1280 l 24,17,18 + 1024 1280 1024 1280 1280 1280 c 24,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: currency Encoding: 164 164 162 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 119 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8C%,9n7D"pPj) !Q^/F%:fKR7hu4V7co=BF EndImage2 Fore +SplineSet +1212 902 m 1,0,1 + 1280 838 1280 838 1280 693 c 0,2,3 + 1280 693 1280 693 1280 0 c 25,4,5 + 1280 0 1280 0 1024 0 c 25,6,-1 + 1024 768 l 25,7,-1 + 512 768 l 25,8,-1 + 512 0 l 1,9,10 + 256 0 256 0 256 0 c 25,11,12 + 256 1024 256 1024 256 1024 c 1,13,14 + 1024 1024 1024 1024 1024 1024 c 24,15,16 + 1024 1088 1024 1088 1024 1205 c 0,17,18 + 1024 1280 1024 1280 949 1280 c 24,19,20 + 331 1280 331 1280 331 1280 c 0,21,22 + 0 1280 0 1280 0 1611 c 0,23,24 + 0 1790 0 1790 0 1792 c 25,25,26 + 0 1792 0 1792 256 1792 c 25,27,-1 + 256 1611 l 0,28,29 + 256 1536 256 1536 331 1536 c 24,30,31 + 949 1536 949 1536 949 1536 c 0,32,33 + 1280 1536 1280 1536 1280 1205 c 24,34,35 + 1280 1205 1280 1205 1280 1099 c 0,36,37 + 1280 952 1280 952 1212 902 c 1,0,1 +EndSplineSet Validated: 1 EndChar StartChar: yen Encoding: 165 165 163 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$bu"fJ+:&'G-f+gFeV%B@ @@ -5716,15 +6134,38 @@ d]^aTL:J\#8H@!r@PC'0#P.e,+]aiOf*(Omi&-B!nDf9V3(U7K?Df4j$$E!f`rH)>!(fUS7'8ja JcGcN EndImage2 Fore +SplineSet +1024 1205 m 17,0,1 + 1024 1280 1024 1280 949 1280 c 24,2,3 + 949 1280 949 1280 331 1280 c 0,4,5 + 256 1280 256 1280 256 1205 c 1,6,7 + 256 1205 256 1205 1024 437 c 1,8,-1 + 1024 1205 l 17,0,1 +124 1487 m 1,9,10 + 124 1487 124 1487 0 1611 c 1,11,-1 + 0 1792 l 25,12,13 + 181 1792 181 1792 181 1792 c 152,-1,14 + 181 1792 181 1792 437 1536 c 25,15,-1 + 949 1536 l 0,16,17 + 1280 1536 1280 1536 1280 1205 c 0,18,19 + 1280 0 1280 0 1280 0 c 153,-1,20 + 1280 0 1280 0 1024 0 c 25,21,-1 + 1024 75 l 25,22,-1 + 256 843 l 25,23,-1 + 256 0 l 25,24,-1 + 0 0 l 25,25,26 + 0 1205 0 1205 0 1205 c 0,27,28 + 0 1420 0 1420 124 1487 c 1,9,10 +EndSplineSet Validated: 1 EndChar StartChar: brokenbar Encoding: 166 166 164 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG9Xor#n @@ -5732,15 +6173,43 @@ M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG9Xor#n JcGcN EndImage2 Fore +SplineSet +256 256 m 24,0,-1 + 1280 256 l 24,1,-1 + 1280 0 l 25,2,-1 + 256 0 l 25,3,4 + 256 0 256 0 256 256 c 24,0,-1 +512 768 m 25,5,-1 + 768 768 l 25,6,-1 + 768 1024 l 24,7,-1 + 512 1024 l 24,8,9 + 512 1024 512 1024 512 768 c 25,5,-1 +256 1792 m 25,10,-1 + 693 1792 l 0,11,12 + 1024 1792 1024 1792 1024 1461 c 24,13,-1 + 1024 825 l 0,14,15 + 1024 768 1024 768 1081 768 c 24,16,-1 + 1223 768 l 0,17,18 + 1280 768 1280 768 1280 640 c 128,-1,19 + 1280 512 1280 512 1223 512 c 24,20,-1 + 587 512 l 0,21,22 + 256 512 256 512 256 843 c 24,23,24 + 256 843 256 843 256 949 c 0,25,26 + 256 1280 256 1280 587 1280 c 24,27,-1 + 768 1280 l 24,28,-1 + 768 1536 l 24,29,-1 + 256 1536 l 24,30,31 + 256 1536 256 1536 256 1792 c 25,10,-1 +EndSplineSet Validated: 1 EndChar StartChar: section Encoding: 167 167 165 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CNNffHd!JJi$ @@ -5748,60 +6217,126 @@ M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CNNffHd!JJi$ JcGcN EndImage2 Fore +SplineSet +256 256 m 24,0,-1 + 1280 256 l 24,1,-1 + 1280 0 l 25,2,-1 + 256 0 l 24,3,4 + 256 0 256 0 256 256 c 24,0,-1 +587 1536 m 0,5,6 + 512 1536 512 1536 512 1461 c 24,7,8 + 512 1114 512 1114 512 843 c 0,9,10 + 512 768 512 768 587 768 c 24,11,-1 + 949 768 l 0,12,13 + 1024 768 1024 768 1024 843 c 24,14,15 + 1024 1190 1024 1190 1024 1461 c 0,16,17 + 1024 1536 1024 1536 949 1536 c 24,18,19 + 949 1536 949 1536 587 1536 c 0,5,6 +949 1792 m 0,20,21 + 1280 1792 1280 1792 1280 1461 c 24,22,23 + 1280 986 1280 986 1280 843 c 0,24,25 + 1280 512 1280 512 949 512 c 24,26,-1 + 587 512 l 0,27,28 + 257 512 257 512 256 843 c 24,29,30 + 256 1318 256 1318 256 1461 c 0,31,32 + 256 1792 256 1792 587 1792 c 24,33,34 + 587 1792 587 1792 949 1792 c 0,20,21 +EndSplineSet Validated: 1 EndChar StartChar: dieresis Encoding: 168 168 166 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 111 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8CNNffG9`^HNZ $?-jc=$Y+8'Q]Br?kYf:EE[oGM/F%9811\c\k)mkNtW,u'5Ej6!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +512 1792 m 24,0,-1 + 768 1792 l 25,1,-1 + 768 1536 l 24,2,-1 + 512 1536 l 24,3,4 + 512 1536 512 1536 512 1792 c 24,0,-1 +1280 512 m 1,5,6 + 1280 512 1280 512 1280 331 c 0,7,8 + 1280 0 1280 0 949 0 c 24,9,-1 + 331 0 l 0,10,11 + 0 0 0 0 0 331 c 24,12,13 + 0 331 0 331 0 437 c 25,14,-1 + 512 949 l 25,15,-1 + 512 1280 l 24,16,-1 + 768 1280 l 24,17,-1 + 768 843 l 25,18,-1 + 256 331 l 0,19,20 + 256 256 256 256 331 256 c 24,21,-1 + 949 256 l 0,22,23 + 1024 256 1024 256 1024 331 c 24,24,-1 + 1024 512 l 17,25,26 + 1024 512 1024 512 1280 512 c 1,5,6 +EndSplineSet Validated: 1 EndChar StartChar: copyright Encoding: 169 169 167 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 105 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8Bu3Ns2`"cP]X (fhd6aoX='=TE7j'#B5s&u:P\)[Inn!!4kb"&IJB(]XO9!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +0 1280 m 24,0,-1 + 1280 1280 l 24,1,-1 + 1280 1024 l 24,2,-1 + 256 1024 l 24,3,-1 + 256 768 l 25,4,-1 + 0 768 l 25,5,6 + 0 768 0 768 0 1280 c 24,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: ordfeminine Encoding: 170 170 168 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 109 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8Bu3Ns2`"cP]X (fhd6b(@hz8OZBBY!QNJ EndImage2 Fore +SplineSet +587 256 m 1,1,2 + 587 256 587 256 1024 693 c 0,3,4 + 1024 768 1024 768 949 768 c 24,5,6 + 949 768 949 768 693 768 c 24,7,-1 + 181 256 l 24,8,9 + 181 256 181 256 0 256 c 24,10,11 + 0 256 0 256 0 437 c 25,12,13 + 0 437 0 437 1099 1536 c 1,14,15 + 1099 1536 1099 1536 1280 1536 c 1,16,17 + 1280 1536 1280 1536 1280 1355 c 9,18,-1 + 1024 1099 l 25,19,20 + 1024 1099 1024 1099 1024 1024 c 1,21,22 + 1280 1024 1280 1024 1280 693 c 0,23,24 + 1280 640 1280 640 1280 587 c 0,25,26 + 1280 587 1280 587 949 256 c 1,27,28 + 949 256 949 256 1280 256 c 24,29,30 + 1280 256 1280 256 1280 0 c 25,31,32 + 1280 0 1280 0 512 0 c 0,33,34 + 512 0 512 0 512 256 c 0,35,0 + 512 256 512 256 587 256 c 1,1,2 +0 1792 m 25,36,-1 + 256 1792 l 25,37,-1 + 256 1024 l 24,38,-1 + 0 1024 l 24,39,40 + 0 1024 0 1024 0 1792 c 25,36,-1 +EndSplineSet Validated: 1 EndChar StartChar: logicalnot Encoding: 172 172 170 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 120 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NDU#_0F1!$G5j(21C0M0 @@ -5825,90 +6387,303 @@ r2Q>,p/MMn!!A6PV]L'kK`3_'n:PP\#-HFDL8@Ise^,tZkffSY%)itrG2h[*z8OZBBY!QNJ EndImage2 Fore +SplineSet +693 768 m 1,0,1 + 693 768 693 768 768 768 c 1,2,-1 + 768 587 l 0,3,4 + 768 512 768 512 843 512 c 24,5,6 + 843 512 843 512 1024 512 c 24,7,8 + 1024 512 1024 512 1024 768 c 25,9,-1 + 1280 768 l 25,10,-1 + 1280 0 l 25,11,-1 + 1024 0 l 25,12,-1 + 1024 256 l 24,13,-1 + 843 256 l 1,14,15 + 512 256 512 256 512 587 c 1,16,17 + 512 587 512 587 181 256 c 0,18,19 + 181 256 181 256 0 256 c 24,20,21 + 0 256 0 256 0 437 c 25,22,23 + 0 437 0 437 1099 1536 c 24,24,25 + 1099 1536 1099 1536 1280 1537 c 0,26,27 + 1280 1537 1280 1537 1280 1355 c 1,28,29 + 1280 1355 1280 1355 693 768 c 1,0,1 +0 1792 m 25,30,-1 + 256 1792 l 25,31,-1 + 256 1024 l 24,32,-1 + 0 1024 l 24,33,34 + 0 1024 0 1024 0 1792 c 25,30,-1 +EndSplineSet Validated: 1 EndChar StartChar: uni00AD Encoding: 173 173 171 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 102 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8CNNffG9`^HNZ $?-jc=$Y+8'Q]BrE"e>O:mdIt!!#m3#7ii8+`m\a!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +512 1279.99969483 m 24,0,-1 + 768 1279.99969483 l 24,1,-1 + 768 0 l 25,2,-1 + 511.999633789 0 l 24,3,4 + 511.999633789 0 511.999633789 0 512 1279.99969483 c 24,0,-1 +511.999633789 1792 m 24,5,-1 + 768 1792 l 25,6,-1 + 768 1536.00042725 l 24,7,-1 + 512 1536.00042725 l 24,8,9 + 512 1536.00042725 512 1536.00042725 511.999633789 1792 c 24,5,-1 +EndSplineSet Validated: 1 EndChar StartChar: registered Encoding: 174 174 172 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 115 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3"!@&g6 >TGR=,Y68bOB/kI5e>@6_up^')2l^nfh'g'\G7g1BJ]\prtPfbo^aa:!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +1099 896 m 1,0,1 + 1280 896 1280 896 1280 693 c 0,2,3 + 1280 693 1280 693 1280 313 c 0,4,5 + 1280 256 1280 256 1152 256 c 144,-1,6 + 1024 256 1024 256 1024 313 c 24,7,-1 + 1024 693 l 1,8,9 + 1024 843 1024 843 826 843 c 0,10,11 + 826 843 826 843 826 949 c 1,12,13 + 1024 949 1024 949 1024 1099 c 1,14,-1 + 1024 1479 l 0,15,16 + 1024 1536 1024 1536 1152 1536 c 128,-1,17 + 1280 1536 1280 1536 1280 1479 c 8,18,19 + 1280 1188 1280 1188 1280 1099 c 0,20,21 + 1280 896 1280 896 1099 896 c 1,0,1 +331 896 m 1,22,23 + 512 896 512 896 512 693 c 0,24,25 + 512 474 512 474 512 313 c 0,26,27 + 512 256 512 256 384 256 c 144,-1,28 + 256 256 256 256 256 313 c 24,29,-1 + 256 693 l 1,30,31 + 256 843 256 843 58 843 c 0,32,33 + 58 843 58 843 58 949 c 1,34,35 + 256 949 256 949 256 1099 c 1,36,-1 + 256 1479 l 0,37,38 + 256 1536 256 1536 384 1536 c 128,-1,39 + 512 1536 512 1536 512 1479 c 8,40,41 + 512 1362 512 1362 512 1099 c 0,42,43 + 512 896 512 896 331 896 c 1,22,23 +EndSplineSet Validated: 1 EndChar StartChar: macron Encoding: 175 175 173 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 114 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns22,9nF< %5JkL8D"','4K!lfs6#;QBF EndImage2 Fore +SplineSet +180.931365967 512 m 28,0,-1 + 512 181 l 29,1,-1 + 511.999633789 0 l 28,2,-1 + 330.938598633 0 l 28,3,-1 + 0 331 l 29,4,-1 + 0 512.000427246 l 28,5,6 + 0 512.000427246 0 512.000427246 180.931365967 512 c 28,0,-1 +0 1279.99969483 m 28,7,-1 + 180.931365967 1280 l 28,8,-1 + 1280 181 l 29,9,-1 + 1280 0 l 29,10,-1 + 1098.98864746 0 l 28,11,-1 + 0 1099 l 29,12,13 + 0 1099 0 1099 0 1279.99969483 c 28,7,-1 +437 1792 m 29,14,-1 + 1280 949 l 29,15,-1 + 1280 768 l 29,16,-1 + 1098.98864746 768 l 28,17,-1 + 256 1611 l 29,18,-1 + 256 1792 l 29,19,-1 + 437 1792 l 29,14,-1 +1024 1792 m 29,20,-1 + 1280 1792 l 29,21,-1 + 1280 1536.00042725 l 28,22,-1 + 1024 1536.00042725 l 28,23,24 + 1024 1536.00042725 1024 1536.00042725 1024 1792 c 29,20,-1 +EndSplineSet Validated: 1 EndChar StartChar: plusminus Encoding: 177 177 175 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 102 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8C%,9p;/SVHB; !Z;!$7&FCU+<#%tZ6[X>R%hE)!WYS80bpR=__(oh!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +512 75 m 17,0,-1 + 384 203 l 1,1,2 + 384 203 384 203 256 75 c 1,3,4 + 256 75 256 75 256 0 c 25,5,-1 + 0 0 l 25,6,7 + 0 0 0 0 0 256 c 24,8,-1 + 75 256 l 17,9,10 + 75 256 75 256 203 384 c 1,11,12 + 202 385 202 385 75 512 c 1,13,-1 + 0 512 l 24,14,15 + 0 512 0 512 0 768 c 25,16,17 + 75 768 75 768 75 768 c 129,-1,18 + 75 768 75 768 203 896 c 1,19,20 + 203 896 203 896 75 1024 c 1,21,22 + 75 1024 75 1024 0 1024 c 25,23,24 + 0 1280 0 1280 0 1280 c 24,25,26 + 75 1280 75 1280 75 1280 c 129,-1,27 + 75 1280 75 1280 203 1408 c 1,28,29 + 203 1408 203 1408 0 1611 c 1,30,31 + 0 1792 0 1792 0 1792 c 24,32,33 + 181 1792 181 1792 181 1792 c 128,-1,34 + 181 1792 181 1792 384 1590 c 1,35,36 + 512 1717 512 1717 512 1717 c 1,37,38 + 512 1792 512 1792 512 1792 c 153,-1,39 + 512 1792 512 1792 768 1792 c 25,40,-1 + 768 1717 l 1,41,42 + 768 1717 768 1717 896 1589 c 1,43,44 + 1099 1792 1099 1792 1099 1792 c 129,-1,45 + 1099 1792 1099 1792 1280 1792 c 25,46,47 + 1280 1536 1280 1536 1280 1536 c 24,48,49 + 1205 1536 1205 1536 1205 1536 c 129,-1,50 + 1205 1536 1205 1536 1077 1408 c 1,51,52 + 1205 1280 1205 1280 1205 1280 c 137,-1,53 + 1205 1280 1205 1280 1280 1280 c 25,54,55 + 1280 1152 1280 1152 1280 1024 c 24,56,57 + 1280 1024 1280 1024 1205 1024 c 1,58,59 + 1141 960 1141 960 1077 896 c 1,60,61 + 1077 896 1077 896 1205 768 c 1,62,63 + 1205 768 1205 768 1280 768 c 25,64,65 + 1280 512 1280 512 1280 512 c 24,66,67 + 1205 512 1205 512 1205 512 c 129,-1,68 + 1205 512 1205 512 1077 384 c 1,69,70 + 1077 384 1077 384 1280 181 c 1,71,72 + 1280 90 1280 90 1280 0 c 24,73,74 + 1280 0 1280 0 1099 0 c 0,75,76 + 1099 0 1099 0 903 210 c 1,77,78 + 903 210 903 210 768 75 c 1,79,80 + 768 56 768 56 768 0 c 25,81,-1 + 512 0 l 24,82,-1 + 512 75 l 17,0,-1 +715 384 m 1,83,84 + 715 384 715 384 640 459 c 1,85,86 + 640 459 640 459 565 384 c 1,87,88 + 565 384 565 384 640 309 c 1,89,90 + 640 309 640 309 715 384 c 1,83,84 +896 565 m 129,-1,92 + 896 565 896 565 971 640 c 1,93,94 + 896 715 896 715 896 715 c 1,95,96 + 821 640 821 640 821 640 c 1,97,91 + 896 565 896 565 896 565 c 129,-1,92 +640 821 m 1,98,99 + 685 864 685 864 715 896 c 1,100,101 + 715 896 715 896 640 971 c 1,102,103 + 640 971 640 971 565 896 c 1,104,105 + 640 821 640 821 640 821 c 1,98,99 +309 640 m 1,106,107 + 309 640 309 640 384 565 c 1,108,109 + 459 640 459 640 459 640 c 129,-1,110 + 459 640 459 640 385 716 c 0,111,112 + 385 716 385 716 309 640 c 1,106,107 +896 1077 m 1,113,114 + 971 1152 971 1152 971 1152 c 1,115,116 + 934 1189 934 1189 896 1227 c 1,117,118 + 896 1227 896 1227 821 1152 c 1,119,120 + 896 1077 896 1077 896 1077 c 1,113,114 +384 1077 m 129,-1,122 + 384 1077 384 1077 459 1152 c 1,123,124 + 459 1152 459 1152 384 1227 c 1,125,126 + 384 1227 384 1227 309 1152 c 1,127,121 + 384 1077 384 1077 384 1077 c 129,-1,122 +715 1408 m 129,-1,129 + 715 1408 715 1408 640 1483 c 1,130,131 + 640 1483 640 1483 565 1408 c 1,132,133 + 640 1333 640 1333 640 1333 c 1,134,128 + 715 1408 715 1408 715 1408 c 129,-1,129 +EndSplineSet Validated: 1 EndChar StartChar: uni00B2 Encoding: 178 178 176 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$N6qt4+:Ja /&3J4',qPk!$J3C'$J7Wkl:\`!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +256 1792 m 29,0,-1 + 768 1792 l 25,1,-1 + 768 0 l 25,2,-1 + 256 0 l 25,3,-1 + 256 1792 l 29,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: acute Encoding: 180 180 178 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 93 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,Y:Bi<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',qVm5X)sg!$MLK'r$fZcN!qF!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +256 1792 m 29,0,-1 + 768 1792 l 25,1,-1 + 768 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 255.999969483 l 24,4,-1 + 256 255.999969483 l 24,5,-1 + 256 1792 l 29,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: mu Encoding: 181 181 179 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 101 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';L-\OT"qS'*1l_0G-&@!9%Sr't*9^b5_MB!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 255.999969483 l 24,4,-1 + 256 255.999969483 l 24,5,-1 + 256 512.000427246 l 24,6,-1 + 0 512.000427246 l 24,7,-1 + 0 768 l 25,8,-1 + 256 768 l 25,9,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: paragraph Encoding: 182 182 180 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 95 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pJu:T`F-UHiO-kKEN.@)qT34!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 0 l 25,2,-1 + 1024 0 l 25,3,-1 + 1024 1792 l 25,0,-1 +256 1792 m 25,4,-1 + 768 1792 l 25,5,-1 + 768 0 l 25,6,-1 + 0 0 l 25,7,-1 + 0 255.999969483 l 24,8,-1 + 256 255.999969483 l 24,9,-1 + 256 1792 l 25,4,-1 +EndSplineSet Validated: 1 EndChar StartChar: periodcentered Encoding: 183 183 181 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 87 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y .Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +0 255.999969483 m 24,0,-1 + 1280 255.999969483 l 24,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,4 + 0 0 0 0 0 255.999969483 c 24,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: cedilla Encoding: 184 184 182 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 104 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns2<'JKS? _Jgd+]314U+BL9QK(L/c$b?=)$GliE+P$o1*lXZMz8OZBBY!QNJ EndImage2 Fore +SplineSet +0 768 m 25,0,-1 + 1280 768 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 255.999969483 l 24,4,-1 + 1024 255.999969483 l 24,5,-1 + 1024 512.000427246 l 24,6,-1 + 0 512.000427246 l 24,7,8 + 0 512.000427246 0 512.000427246 0 768 c 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: uni00B9 Encoding: 185 185 183 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 105 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pFGM-ihq]&$QW7"9T%;$.opo!$-\!)&6YA2ZNgX!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +0 255.999969483 m 24,0,-1 + 768 255.999969483 l 24,1,-1 + 768 0 l 25,2,-1 + 0 0 l 25,3,4 + 0 0 0 0 0 255.999969483 c 24,0,-1 +1024 1792 m 25,5,-1 + 1280 1792 l 25,6,-1 + 1280 0 l 25,7,-1 + 1024 0 l 25,8,-1 + 1024 1792 l 25,5,-1 +256 1792 m 25,9,-1 + 768 1792 l 25,10,-1 + 768 512.000427246 l 24,11,-1 + 0 512.000427246 l 24,12,-1 + 0 768 l 25,13,-1 + 256 768 l 25,14,-1 + 256 1792 l 25,9,-1 +EndSplineSet Validated: 1 EndChar StartChar: ordmasculine Encoding: 186 186 184 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 91 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pJtoT`>';-Nk/O`Y'Ep!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 0 l 25,2,-1 + 1024 0 l 25,3,-1 + 1024 1792 l 25,0,-1 +256 1792 m 25,4,-1 + 768 1792 l 25,5,-1 + 768 0 l 25,6,-1 + 256 0 l 25,7,-1 + 256 1792 l 25,4,-1 +EndSplineSet Validated: 1 EndChar StartChar: guillemotright Encoding: 187 187 185 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 104 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns2<'JKS? _Jgd+]314U+BL9QK(L/c$aKcD@ZW>F=e-$1?1ZPNz8OZBBY!QNJ EndImage2 Fore -Validated: 1 +SplineSet +0 255.999969483 m 24,0,-1 + 768 255.999969483 l 24,1,-1 + 768 0 l 25,2,-1 + 0 0 l 25,3,4 + 0 0 0 0 0 255.999969483 c 24,0,-1 +0 768 m 25,5,-1 + 1280 768 l 25,6,-1 + 1280 0 l 25,7,-1 + 1024 0 l 25,8,-1 + 1024 512.000427246 l 24,9,-1 + 0 512.000427246 l 24,10,11 + 0 512.000427246 0 512.000427246 0 768 c 25,5,-1 +EndSplineSet +Validated: 1 EndChar StartChar: onequarter Encoding: 188 188 186 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 102 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pFGM-ihq]&$QW7"9T#T'*.*q#9;f]U)a46!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,4,-1 + 1024 256 l 25,5,-1 + 1024 1792 l 25,0,-1 +256 1792 m 25,6,-1 + 768 1792 l 25,7,-1 + 768 512 l 25,8,-1 + 0 512 l 25,9,-1 + 0 768 l 25,10,-1 + 256 768 l 25,11,-1 + 256 1792 l 25,6,-1 +EndSplineSet Validated: 1 EndChar StartChar: onehalf Encoding: 189 189 187 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 99 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 256 l 25,2,-1 + 1024 256 l 25,3,-1 + 1024 1792 l 25,4,-1 + 1280 1792 l 25,5,-1 + 1280 0 l 25,6,-1 + 0 0 l 25,7,-1 + 0 256 l 25,8,-1 + 256 256 l 25,9,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: threequarters Encoding: 190 190 188 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 101 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';L-\OT"qS'*1l_0G-&@!9%Sr't*9^b5_MB!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,4,-1 + 256 256 l 25,5,-1 + 256 512 l 25,6,-1 + -0 512 l 25,7,-1 + 0 768 l 25,8,-1 + 256 768 l 25,9,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: questiondown Encoding: 191 191 189 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 87 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y .Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Agrave Encoding: 192 192 190 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 92 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',u$#Yk\J'+V"VlN61l:z8OZBBY!QNJ EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 256 l 25,2,-1 + 1280 256 l 25,3,-1 + 1280 0 l 25,4,-1 + 256 0 l 25,5,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Aacute Encoding: 193 193 191 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 97 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',q>e(kI^`n0YHe!FA>'%B8fCrr<$!!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 256 l 25,2,-1 + 1280 256 l 25,3,-1 + 1280 0 l 25,4,-1 + 0 0 l 25,5,-1 + -0 256 l 25,6,-1 + 256 256 l 25,7,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Acircumflex Encoding: 194 194 192 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 87 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y .Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Atilde Encoding: 195 195 193 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 92 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',u$#Yk\J'+V"VlN61l:z8OZBBY!QNJ EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 256 l 25,2,-1 + 1280 256 l 25,3,-1 + 1280 0 l 25,4,-1 + 256 0 l 25,5,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Adieresis Encoding: 196 196 194 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 87 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y .Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +-0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + -0 256 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Aring Encoding: 197 197 195 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 97 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',q>e(kI^`n0YHe!FA>'%B8fCrr<$!!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 256 l 25,2,-1 + 1280 256 l 25,3,-1 + 1280 0 l 25,4,-1 + 0 0 l 25,5,-1 + 0 256 l 25,6,-1 + 256 256 l 25,7,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: AE Encoding: 198 198 196 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 104 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';Mi7Ci3[4f`e+TGmM@ufLu8F^?>eBB4:K7z8OZBBY!QNJ EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 768 l 25,2,-1 + 1280 768 l 25,3,-1 + 1280 512 l 25,4,-1 + 768 512 l 25,5,-1 + 768 256 l 25,6,-1 + 1280 256 l 25,7,-1 + 1280 0 l 25,8,-1 + 256 0 l 25,9,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Ccedilla Encoding: 199 199 197 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 95 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pJu:WrV32(]XO\8-Be-C[o1?!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 256 l 25,2,-1 + 1536 256 l 25,3,-1 + 1536 0 l 25,4,-1 + 1024 0 l 25,5,-1 + 1024 1792 l 25,0,-1 +256 1792 m 25,6,-1 + 768 1792 l 25,7,-1 + 768 0 l 25,8,-1 + 256 0 l 25,9,-1 + 256 1792 l 25,6,-1 +EndSplineSet Validated: 1 EndChar StartChar: Egrave Encoding: 200 200 198 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 100 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!%:k7s_'K703#3K"fZMb"F3oa6rz8OZBBY!QNJ EndImage2 Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 512 l 25,2,-1 + 1024 512 l 25,3,-1 + 1024 1792 l 25,0,-1 +256 1792 m 25,4,-1 + 768 1792 l 25,5,-1 + 768 256 l 25,6,-1 + 1280 256 l 25,7,-1 + 1280 0 l 25,8,-1 + 256 0 l 25,9,-1 + 256 1792 l 25,4,-1 +EndSplineSet Validated: 1 EndChar StartChar: Eacute Encoding: 201 201 199 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 102 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8Bu3Ns2<'X3*= @Us";E=0"`_$XSUa:^0]$qI%]"ot9O$4t0"i%tE6!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +1024 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 1024 0 l 25,3,-1 + 1024 256 l 25,0,-1 +256 768 m 25,4,-1 + 1280 768 l 25,5,-1 + 1280 512 l 25,6,-1 + 768 512 l 25,7,-1 + 768 0 l 25,8,-1 + 256 0 l 25,9,-1 + 256 768 l 25,4,-1 +EndSplineSet Validated: 1 EndChar StartChar: Ecircumflex Encoding: 202 202 200 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 105 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pFGM-ihq]%knXe"\:_02j&Lu!+*5F%a\Tq3<0$Z!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +1024 1792 m 25,4,-1 + 1280 1792 l 25,5,-1 + 1280 512 l 25,6,-1 + 1024 512 l 25,7,-1 + 1024 1792 l 25,4,-1 +256 1792 m 25,8,-1 + 768 1792 l 25,9,-1 + 768 512 l 25,10,-1 + -0 512 l 25,11,-1 + 0 768 l 25,12,-1 + 256 768 l 25,13,-1 + 256 1792 l 25,8,-1 +EndSplineSet Validated: 1 EndChar StartChar: Edieresis Encoding: 203 203 201 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 102 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8Bu3Ns2<'JKS? _Jgd+]314UfGoiZ!_>$j,9m;r-30>o&cjm'^*3OW!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +1024 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 1024 0 l 25,3,-1 + 1024 256 l 25,0,-1 +-0 256 m 25,4,-1 + 768 256 l 25,5,-1 + 768 0 l 25,6,-1 + 0 0 l 25,7,-1 + -0 256 l 25,4,-1 +0 768 m 25,8,-1 + 1280 768 l 25,9,-1 + 1280 512 l 25,10,-1 + -0 512 l 25,11,-1 + 0 768 l 25,8,-1 +EndSplineSet Validated: 1 EndChar StartChar: Igrave Encoding: 204 204 202 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 99 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!%:k7s_$o`]aKF@jd`!7$Wg'U=M!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +1024 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 1024 0 l 25,3,-1 + 1024 256 l 25,0,-1 +1024 1792 m 25,4,-1 + 1280 1792 l 25,5,-1 + 1280 512 l 25,6,-1 + 1024 512 l 25,7,-1 + 1024 1792 l 25,4,-1 +256 1792 m 25,8,-1 + 768 1792 l 25,9,-1 + 768 0 l 25,10,-1 + 256 0 l 25,11,-1 + 256 1792 l 25,8,-1 +EndSplineSet Validated: 1 EndChar StartChar: Iacute Encoding: 205 205 203 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 94 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns2<'JKS? _Jgd+]314UfGmT3"9;^u%fm;4_$'f=!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +-0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + -0 256 l 25,0,-1 +0 768 m 25,4,-1 + 1280 768 l 25,5,-1 + 1280 512 l 25,6,-1 + 0 512 l 25,7,-1 + 0 768 l 25,4,-1 +EndSplineSet Validated: 1 EndChar StartChar: Icircumflex Encoding: 206 206 204 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 109 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pFGM-ihq]%knXe"\:`1Riif*9LSS7!10i!%](Uh2ZNgX!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +-0 256 m 25,0,-1 + 768 256 l 25,1,-1 + 768 0 l 25,2,-1 + 0 0 l 25,3,-1 + -0 256 l 25,0,-1 +1024 256 m 25,4,-1 + 1280 256 l 25,5,-1 + 1280 0 l 25,6,-1 + 1024 0 l 25,7,-1 + 1024 256 l 25,4,-1 +1024 1792 m 25,8,-1 + 1280 1792 l 25,9,-1 + 1280 512 l 25,10,-1 + 1024 512 l 25,11,-1 + 1024 1792 l 25,8,-1 +256 1792 m 25,12,-1 + 768 1792 l 25,13,-1 + 768 512 l 25,14,-1 + -0 512 l 25,15,-1 + 0 768 l 25,16,-1 + 256 768 l 25,17,-1 + 256 1792 l 25,12,-1 +EndSplineSet Validated: 1 EndChar StartChar: Idieresis Encoding: 207 207 205 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 106 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';Je5,L@hI7j>R7"doJ!(RZU`!WZ\]%gVktrYPV8!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +-0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + -0 256 l 25,0,-1 +256 1792 m 25,4,-1 + 768 1792 l 25,5,-1 + 768 768 l 25,6,-1 + 1280 768 l 25,7,-1 + 1280 512 l 25,8,-1 + -0 512 l 25,9,-1 + 0 768 l 25,10,-1 + 256 768 l 25,11,-1 + 256 1792 l 25,4,-1 +EndSplineSet Validated: 1 EndChar @@ -6359,7 +7525,7 @@ Encoding: 32 32 206 Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 79 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(.gn[<#?K_r!ro=GQ8Bu3O%$&:]LJ7 @@ -6374,7 +7540,7 @@ Encoding: 0 0 207 Width: 256 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 81 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(eI+]<#?K_A7/g?&&^F.'2BFD`:-S' @@ -6386,310 +7552,546 @@ EndChar StartChar: Eth Encoding: 208 208 208 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 99 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 256 l 25,2,-1 + 1024 256 l 25,3,-1 + 1024 1792 l 25,4,-1 + 1280 1792 l 25,5,-1 + 1280 0 l 25,6,-1 + 0 0 l 25,7,-1 + -0 256 l 25,8,-1 + 256 256 l 25,9,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Ntilde Encoding: 209 209 209 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 94 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns2<'JKS? _Jgd+]314UfGmT3"9;^u%fm;4_$'f=!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +-0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + -0 256 l 25,0,-1 +0 768 m 25,4,-1 + 1280 768 l 25,5,-1 + 1280 512 l 25,6,-1 + 0 512 l 25,7,-1 + 0 768 l 25,4,-1 +EndSplineSet Validated: 1 EndChar StartChar: Ograve Encoding: 210 210 210 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 87 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y .Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +2868 -1048 m 1053,0,-1 +0 256 m 25,1,-1 + 1280 256 l 25,2,-1 + 1280 0 l 25,3,-1 + 0 0 l 25,4,-1 + 0 256 l 25,1,-1 +EndSplineSet Validated: 1 EndChar StartChar: Oacute Encoding: 211 211 211 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 95 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pJu:VZ>csF8u:c?j%;QoDu8u!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 256 l 25,2,-1 + 1024 256 l 25,3,-1 + 1024 1792 l 25,4,-1 + 1280 1792 l 25,5,-1 + 1280 0 l 25,6,-1 + 256 0 l 25,7,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Ocircumflex Encoding: 212 212 212 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 104 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';Mi7Ci3[4f`e+TGmM@ufLu8F^?>eBB4:K7z8OZBBY!QNJ EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 768 l 25,2,-1 + 1280 768 l 25,3,-1 + 1280 512 l 25,4,-1 + 768 512 l 25,5,-1 + 768 256 l 25,6,-1 + 1280 256 l 25,7,-1 + 1280 0 l 25,8,-1 + 256 0 l 25,9,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Otilde Encoding: 213 213 213 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 87 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%!u-t$Rr 6ua"(D?'YV@0@+u1K<94!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +1024 768 m 25,0,-1 + 1280 768 l 25,1,-1 + 1280 0 l 25,2,-1 + 1024 0 l 25,3,-1 + 1024 768 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Odieresis Encoding: 214 214 214 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 84 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr LuL,h)k-s@YSsU1z8OZBBY!QNJ EndImage2 Fore +SplineSet +1024 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 1024 0 l 25,3,-1 + 1024 256 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: multiply Encoding: 215 215 215 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 99 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +256 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 256 l 25,2,-1 + 1024 256 l 25,3,-1 + 1024 1792 l 25,4,-1 + 1280 1792 l 25,5,-1 + 1280 0 l 25,6,-1 + 0 0 l 25,7,-1 + 0 256 l 25,8,-1 + 256 256 l 25,9,-1 + 256 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Oslash Encoding: 216 216 216 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 101 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8Dg*$Z[QM@bLD 'NlQ6EWn#XG+r3WK'iqe%0TB*!8ts()gOU!N;rqY!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,4,-1 + 1024 256 l 25,5,-1 + 1024 512 l 25,6,-1 + -0 512 l 25,7,-1 + 0 768 l 25,8,-1 + 1024 768 l 25,9,-1 + 1024 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Ugrave Encoding: 217 217 217 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 93 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,Y:Bi<#?K_r!ro=GQ8Dg*$Z[QM@bLD 'NlPk0IUVQiI*d!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +1024 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + -0 256 l 25,4,-1 + 1024 256 l 25,5,-1 + 1024 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Uacute Encoding: 218 218 218 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 84 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr LuL,h)k-s@YSsU1z8OZBBY!QNJ EndImage2 Fore +SplineSet +1024 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 1024 0 l 25,3,-1 + 1024 256 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Ucircumflex Encoding: 219 219 219 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 86 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*D&Xb<#?K_r!ro=GQ8sb%RU9&*[X"< _,BF EndImage2 Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: Yacute Encoding: 221 221 221 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 86 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*D&Xb<#?K_r!ro=GQ8sb%^#f$=scA# _,6*`gl;[=2_b#`BT:ma%`@oq.KBGK!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +330.876953125 1280 m 0,0,1 + 256 1280 256 1280 256 1205 c 0,2,3 + 256 1205 256 1205 256 843 c 0,4,5 + 256 768 256 768 331 768 c 24,6,7 + 331 768 331 768 437 768 c 0,8,9 + 512 768 512 768 512 843 c 24,10,11 + 512 843.030122793 512 843.030122793 512 1205 c 0,12,13 + 512 1280 512 1280 437 1280 c 0,14,15 + 437 1280 437 1280 330.876953125 1280 c 0,0,1 +640 588 m 1,16,17 + 586 512 586 512 437 512 c 0,18,19 + 437 512 437 512 330.938598633 512 c 0,20,21 + 1 512 1 512 0 843 c 24,22,23 + 0 843 0 843 0 1205 c 0,24,25 + 0 1536 0 1536 330.938598633 1536 c 24,26,27 + 330.938598633 1536 330.938598633 1536 437 1536 c 0,28,29 + 591 1536 591 1536 640 1460 c 1,30,31 + 693 1536 693 1536 842.962219238 1536 c 0,32,33 + 843 1536 843 1536 1280 1536.00042725 c 1,34,35 + 1280 1536.00042725 1280 1536.00042725 1280 1279.99969483 c 9,36,-1 + 842.962219238 1280 l 0,37,38 + 769 1280 769 1280 768 1205 c 24,39,40 + 768 1205 768 1205 768 843 c 0,41,42 + 768 768 768 768 842.962219238 768 c 24,43,-1 + 1280 768 l 25,44,45 + 1280 768 1280 768 1280 512.000427246 c 1,46,47 + 1280 512 1280 512 842.962219238 512 c 0,48,49 + 696 512 696 512 640 588 c 1,16,17 +EndSplineSet Validated: 1 EndChar StartChar: aacute Encoding: 225 225 225 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 112 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8sb%^#f$=sf>C O9>hF14n#N!m44;>Ck%4QpksQJ/$sa,Y0dN8WYn3ei4fJ=9.5"z8OZBBY!QNJ EndImage2 Fore +SplineSet +256 1024 m 25,0,-1 + 256 768 l 25,1,-1 + 512 768 l 25,2,-1 + 512 587 l 0,3,4 + 512 512 512 512 587 512 c 24,5,6 + 587 512 587 512 693 512 c 0,7,8 + 768 512 768 512 768 587 c 24,9,10 + 768 587 768 587 768 949 c 0,11,12 + 768 1024 768 1024 693 1024 c 24,13,14 + 693 1024 693 1024 256 1024 c 25,0,-1 +256 1536 m 25,15,-1 + 256 1280 l 25,16,17 + 256 1280 256 1280 693 1280 c 0,18,19 + 768 1280 768 1280 768 1355 c 24,20,21 + 768 1355 768 1355 768 1461 c 0,22,23 + 768 1536 768 1536 693 1536 c 24,24,25 + 693 1536 693 1536 256 1536 c 25,15,-1 +948 1152 m 1,26,27 + 1024 1098 1024 1098 1024 949 c 0,28,29 + 1024 949 1024 949 1024 587 c 0,30,31 + 1024 256 1024 256 693 256 c 24,32,33 + 693 256 693 256 587 256 c 1,34,35 + 256 256 256 256 256 512 c 1,36,-1 + 256 0 l 25,37,-1 + 0 0 l 25,38,-1 + 0 1792 l 25,39,40 + 2 1792 2 1792 693 1792 c 0,41,42 + 1024 1792 1024 1792 1024 1461 c 24,43,44 + 1024 1461 1024 1461 1024 1355 c 0,45,46 + 1024 1202 1024 1202 948 1152 c 1,26,27 +EndSplineSet Validated: 1 EndChar StartChar: acircumflex Encoding: 226 226 226 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 107 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8sb%RU9&*YsiL A-#.hO<+O4685[N0GGY!#1A*s!8SX;'`\49X:>FZOH&o5!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +0 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 1024 l 25,2,-1 + 1024 1024 l 25,3,-1 + 1024 1536 l 25,4,-1 + 256 1536 l 25,5,-1 + 256 0 l 25,6,-1 + 0 0 l 25,7,-1 + 0 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: atilde Encoding: 227 227 227 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 106 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8Bu3Ns2`"cP]X (fhd6aopatdkIg/>!Ysc,LC*42o(@Wd/YKm'_qdrA2aJg!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +-0 1280 m 25,0,-1 + 1280 1280 l 25,1,-1 + 1280 1024 l 25,2,-1 + 1024 1024 l 25,3,-1 + 1024 256 l 25,4,-1 + 768 256 l 25,5,-1 + 768 1024 l 25,6,-1 + 512 1024 l 25,7,-1 + 512 256 l 25,8,-1 + 256 256 l 25,9,-1 + 256 1024 l 25,10,-1 + 0 1024 l 25,11,-1 + -0 1280 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: adieresis Encoding: 228 228 228 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 125 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$NmS16+:&'JqYsnT:U#R> @@ -6697,15 +8099,35 @@ HVi@4QEAO/ai!o+2:#'fHA[3!]Kabmt6t]^qt2z8OZBBY!QNJ EndImage2 Fore +SplineSet +-0 1280 m 25,0,-1 + 256 1280 l 25,1,-1 + 256 587 l 0,2,3 + 256 512 256 512 331 512 c 24,4,5 + 331 512 331 512 693 512 c 0,6,7 + 768 512 768 512 768 587 c 24,8,-1 + 768 768 l 25,9,-1 + 1024 768 l 25,10,-1 + 1024 1280 l 25,11,-1 + 1280 1280 l 25,12,-1 + 1280 0 l 25,13,-1 + 1024 0 l 25,14,-1 + 1024 512 l 17,15,16 + 1024 256 1024 256 693 256 c 8,17,18 + 693 256 693 256 331 256 c 0,19,20 + 0 256 0 256 0 587 c 24,21,22 + 0 587 0 587 -0 1280 c 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: ccedilla Encoding: 231 231 231 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 106 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8Bu3Ns2`"cP]X (fhd6ao^TW1,:W#fZ;VV["BF EndImage2 Fore +SplineSet +949 1536 m 0,0,1 + 1280 1536 1280 1536 1280 1205 c 24,2,3 + 1280 1205 1280 1205 1280 768 c 0,4,5 + 1280 512 1280 512 1024 512 c 9,6,7 + 1024 512 1024 512 1024 256 c 25,8,9 + 1024 256 1024 256 1280 256 c 1,10,-1 + 1280 0 l 25,11,-1 + 768 0 l 25,12,13 + 768 0 768 0 768 512 c 17,14,15 + 768 768 768 768 1024 768 c 8,16,17 + 1024 768 1024 768 1024 1205 c 0,18,19 + 1024 1280 1024 1280 949 1280 c 24,20,21 + 949 1280 949 1280 331 1280 c 0,22,23 + 256 1280 256 1280 256 1205 c 24,24,25 + 256 1205 256 1205 256 768 c 17,26,27 + 512 768 512 768 512 512 c 8,28,29 + 512 512 512 512 512 0 c 25,30,-1 + 0 0 l 25,31,-1 + -0 256 l 25,32,-1 + 256 256 l 25,33,34 + 256 256 256 256 256 512 c 17,35,36 + 0 512 0 512 0 768 c 8,37,38 + 0 768 0 768 0 1205 c 0,39,40 + 0 1536 0 1536 331 1536 c 24,41,42 + 331 1536 331 1536 949 1536 c 0,0,1 +EndSplineSet Validated: 1 EndChar StartChar: edieresis Encoding: 235 235 235 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 112 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8CJNffG9N3T?l ":F-GKEYlga93>F[h6L\OCD`h?oPlCA"s>[+Qs"0N05+aQb:>%z8OZBBY!QNJ EndImage2 Fore +SplineSet +1024 949 m 0,0,1 + 1024 1024 1024 1024 949 1024 c 24,2,3 + 949 1024 949 1024 331 1024 c 0,4,5 + 256 1024 256 1024 256 949 c 24,6,7 + 256 949 256 949 256 331 c 0,8,9 + 256 256 256 256 331 256 c 24,10,11 + 331 256 331 256 949 256 c 0,12,13 + 1024 256 1024 256 1024 331 c 24,14,15 + 1024 331 1024 331 1024 949 c 0,0,1 +768 1792 m 25,16,-1 + 768 1536 l 25,17,-1 + 331 1536 l 0,18,19 + 256 1536 256 1536 256 1461 c 24,20,21 + 256 1461 256 1461 256 1355 c 0,22,23 + 256 1280 256 1280 331 1280 c 24,24,-1 + 949 1280 l 0,25,26 + 1280 1280 1280 1280 1280 949 c 24,27,28 + 1280 949 1280 949 1280 331 c 0,29,30 + 1280 0 1280 0 949 0 c 24,31,32 + 949 0 949 0 331 -0 c 0,33,34 + 0 0 0 0 0 331 c 24,35,36 + 0 331 0 331 0 949 c 17,37,38 + 0 1280 0 1280 256 1280 c 9,39,-1 + 0 1280 l 25,40,41 + 0 1281.91824393 0 1281.91824393 0 1461 c 0,42,43 + 0 1792 0 1792 331 1792 c 24,44,45 + 331 1792 331 1792 768 1792 c 25,16,-1 +EndSplineSet Validated: 1 EndChar StartChar: igrave Encoding: 236 236 236 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 110 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns3"!@&g6 Qij+G2)0Xb6+.ob-jl%rf[rm]]$]?X#S`rU(BEC4(C_Jt"T8<#!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +1024 1205 m 0,0,1 + 1024 1280 1024 1280 949 1280 c 24,2,3 + 949 1280 949 1280 843 1280 c 0,4,5 + 768 1280 768 1280 768 1205 c 24,6,7 + 768 1205 768 1205 768 843 c 0,8,9 + 768 768 768 768 843 768 c 24,10,11 + 843 768 843 768 949 768 c 0,12,13 + 1024 768 1024 768 1024 843 c 24,14,15 + 1024 843 1024 843 1024 1205 c 0,0,1 +331 1280 m 0,16,17 + 256 1280 256 1280 256 1205 c 24,18,19 + 256 1205 256 1205 256 843 c 0,20,21 + 256 768 256 768 331 768 c 24,22,23 + 331 768 331 768 437 768 c 0,24,25 + 512 768 512 768 512 843 c 24,26,27 + 512 843 512 843 512 1205 c 0,28,29 + 512 1280 512 1280 437 1280 c 24,30,31 + 437 1280 437 1280 331 1280 c 0,16,17 +640 588 m 1,32,33 + 590 512 590 512 437 512 c 0,34,35 + 331 512 331 512 331 512 c 0,36,37 + 0 512 0 512 0 843 c 0,38,39 + 0 1205 0 1205 0 1205 c 0,40,41 + 0 1536 0 1536 331 1536 c 24,42,43 + 437 1536 437 1536 437 1536 c 0,44,45 + 591 1536 591 1536 640 1460 c 1,46,47 + 689 1536 689 1536 843 1536 c 0,48,49 + 949 1536 949 1536 949 1536 c 0,50,51 + 1280 1536 1280 1536 1280 1205 c 24,52,53 + 1280 843 1280 843 1280 843 c 0,54,55 + 1280 512 1280 512 949 512 c 0,56,57 + 843 512 843 512 843 512 c 0,58,59 + 690 512 690 512 640 588 c 1,32,33 +EndSplineSet Validated: 1 EndChar StartChar: iacute Encoding: 237 237 237 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 121 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$:'h7-+:*&es3Ke[NKS6' @@ -6835,270 +8450,568 @@ M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$:'h7-+:*&es3Ke[NKS6' JcGcN EndImage2 Fore +SplineSet +181 0 m 9,0,-1 + 0 0 l 1,1,-1 + 0 181 l 1,2,-1 + 125 306 l 1,3,4 + 0 379 0 379 0 587 c 0,5,6 + 0 587 0 587 0 1205 c 0,7,8 + 0 1536 0 1536 331 1536 c 24,9,10 + 331 1536 331 1536 693 1536 c 0,11,12 + 900 1536 900 1536 975 1411 c 1,13,14 + 975 1411 975 1411 1099 1536 c 1,15,-1 + 1280 1536 l 1,16,-1 + 1280 1355 l 1,17,-1 + 1024 1099 l 9,18,19 + 1024 1092 1024 1092 1024 587 c 16,20,21 + 1024 256 1024 256 693 256 c 0,22,23 + 693 256 693 256 437 256 c 1,24,-1 + 181 0 l 9,0,-1 +256 1205 m 0,25,26 + 256 1205 256 1205 256 693 c 1,27,28 + 256 693 256 693 768 1205 c 0,29,30 + 768 1280 768 1280 693 1280 c 0,31,32 + 693 1280 693 1280 331 1280 c 0,33,34 + 256 1280 256 1280 256 1205 c 0,25,26 +693 512 m 16,35,36 + 768 512 768 512 768 587 c 0,37,38 + 768 587 768 587 768 843 c 1,39,40 + 768 843 768 843 437 512 c 9,41,-1 + 693 512 l 16,35,36 +EndSplineSet Validated: 1 EndChar StartChar: icircumflex Encoding: 238 238 238 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 113 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8+BNffG9Xor#n 8-Z7@9Q7*n(gn"bEp1Mq`5-?,-3;R`cjCPMDLB.u!#onp![BF EndImage2 Fore +SplineSet +-0 512 m 25,0,-1 + 1280 512 l 25,1,-1 + 1280 256 l 25,2,-1 + 0 256 l 25,3,-1 + -0 512 l 25,0,-1 +0 1024 m 25,4,-1 + 1280 1024 l 25,5,-1 + 1280 768 l 25,6,-1 + 0 768 l 25,7,-1 + 0 1024 l 25,4,-1 +0 1536 m 25,8,-1 + 1280 1536 l 25,9,-1 + 1280 1280 l 25,10,-1 + -0 1280 l 25,11,-1 + 0 1536 l 25,8,-1 +EndSplineSet Validated: 1 EndChar StartChar: ntilde Encoding: 241 241 241 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 114 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HNZ $;a-Q3$<&T!ong4J?b4F?m'+d>QHb=+Hm)B!<>"K'`g-2+2\'Y!!#SZ:.26O@"J@Y EndImage2 Fore +SplineSet +0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +512 1792 m 25,4,-1 + 768 1792 l 25,5,-1 + 768 1280 l 25,6,-1 + 1280 1280 l 25,7,-1 + 1280 1024 l 25,8,-1 + 768 1024 l 25,9,-1 + 768 512 l 25,10,-1 + 512 512 l 25,11,-1 + 512 1024 l 25,12,-1 + -0 1024 l 25,13,-1 + -0 1280 l 25,14,-1 + 512 1280 l 25,15,-1 + 512 1792 l 25,4,-1 +EndSplineSet Validated: 1 EndChar StartChar: ograve Encoding: 242 242 242 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 113 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8C%,9n7D"pQE9 !Vd?`J[FH9"BL%K&R5>h748LNMEj!,J@pEk9k9ju!.ec!#8A0)mJm4e!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +-0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + -0 256 l 25,0,-1 +181 1792 m 25,4,-1 + 1280 693 l 25,5,-1 + 1280 512 l 25,6,-1 + 1099 512 l 25,7,-1 + 0 1611 l 25,8,-1 + 0 1792 l 25,9,-1 + 181 1792 l 25,4,-1 +EndSplineSet Validated: 1 EndChar StartChar: oacute Encoding: 243 243 243 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 116 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?L$:.Z&u+:&>Ss5s_"%Pf=X LK3]!2'?-+d&:QLk_3SmM6'=e:S`Poj.G;"9I[85$/QR]hLZRG"t\K.z8OZBBY!QNJ EndImage2 Fore +SplineSet +-0 256 m 25,0,-1 + 1280 256 l 25,1,-1 + 1280 0 l 25,2,-1 + 0 0 l 25,3,-1 + -0 256 l 25,0,-1 +0 693 m 25,4,-1 + 1099 1792 l 25,5,-1 + 1280 1792 l 25,6,-1 + 1280 1611 l 25,7,-1 + 181 512 l 25,8,-1 + -0 512 l 25,9,-1 + 0 693 l 25,4,-1 +EndSplineSet Validated: 1 EndChar StartChar: ocircumflex Encoding: 244 244 244 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 106 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8D_*$Z[Q1)J/h .f`.m$q")!=+HtZ.Y+2mh+8FjcqU6>!%hZBF EndImage2 Fore +SplineSet +331 0 m 0,0,1 + 0 0 0 0 0 331 c 24,2,3 + 0 331 0 331 0 768 c 25,4,-1 + 256 768 l 25,5,-1 + 256 331 l 0,6,7 + 256 256 256 256 331 256 c 24,8,9 + 331 256 331 256 437 256 c 0,10,11 + 512 256 512 256 512 331 c 24,12,-1 + 512 1792 l 25,13,-1 + 768 1792 l 25,14,15 + 768 1792 768 1792 768 331 c 0,16,17 + 768 0 768 0 437 0 c 24,18,19 + 437 0 437 0 331 0 c 0,0,1 +EndSplineSet Validated: 1 EndChar StartChar: odieresis Encoding: 246 246 246 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 104 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns3&!@&g6 F7*dd,#*D0*"!4IN'+.>uci6z8OZBBY!QNJ EndImage2 Fore +SplineSet +0 437 m 0,0,1 + 0 768 0 768 331 768 c 24,2,-1 + 949 768 l 0,3,4 + 1024 768 1024 768 1024 843 c 24,5,-1 + 1024 1024 l 25,6,-1 + 1280 1024 l 25,7,8 + 1280 1024 1280 1024 1280 843 c 0,9,10 + 1280 512 1280 512 949 512 c 24,11,-1 + 331 512 l 0,12,13 + 256 512 256 512 256 437 c 24,14,-1 + 256 256 l 25,15,-1 + 0 256 l 25,16,17 + 0 256 0 256 0 437 c 0,0,1 +0 1205 m 0,18,19 + 0 1536 0 1536 331 1536 c 24,20,-1 + 949 1536 l 0,21,22 + 1024 1536 1024 1536 1024 1611 c 24,23,-1 + 1024 1792 l 25,24,-1 + 1280 1792 l 25,25,26 + 1280 1792 1280 1792 1280 1611 c 0,27,28 + 1280 1280 1280 1280 949 1280 c 24,29,-1 + 331 1280 l 0,30,31 + 256 1280 256 1280 256 1205 c 24,32,-1 + 256 1024 l 25,33,-1 + -0 1024 l 25,34,35 + -0 1024 -0 1024 0 1205 c 0,18,19 +EndSplineSet Validated: 1 EndChar StartChar: oslash Encoding: 248 248 248 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 115 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8CJNffG9N3T?l ":E!T!@^DqO9Hm0OoPN)8WXbs/d[V!#_:_2@:CT5fEr&3)!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +693 1536 m 0,0,1 + 693 1536 693 1536 331 1536 c 0,2,3 + 256 1536 256 1536 256 1461 c 24,4,5 + 256 1461 256 1461 256 1355 c 0,6,7 + 256 1280 256 1280 331 1280 c 24,8,9 + 331 1280 331 1280 693 1280 c 0,10,11 + 768 1280 768 1280 768 1355 c 24,12,13 + 768 1355 768 1355 768 1461 c 0,14,15 + 768 1536 768 1536 693 1536 c 0,0,1 +693 1792 m 0,16,17 + 1024 1792 1024 1792 1024 1461 c 24,18,19 + 1024 1461 1024 1461 1024 1355 c 0,20,21 + 1024 1024 1024 1024 693 1024 c 24,22,23 + 693 1024 693 1024 331 1024 c 0,24,25 + 0 1024 0 1024 0 1355 c 24,26,27 + 0 1355 0 1355 0 1461 c 0,28,29 + 0 1792 0 1792 331 1792 c 24,30,31 + 331 1792 331 1792 693 1792 c 0,16,17 +EndSplineSet Validated: 1 EndChar StartChar: ugrave Encoding: 249 249 249 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 116 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8Bu3Ns4f$5aWu )*f#ZJ5&:p5\>W_K,#N@':B;-^]G]F!*oXM$8hk(_+"M,dDQJ+QNPW^z8OZBBY!QNJ EndImage2 Fore +SplineSet +512 1280 m 25,0,-1 + 1024 1280 l 25,1,-1 + 1024 1024 l 25,2,-1 + 1280 1024 l 25,3,-1 + 1280 768 l 25,4,-1 + 1024 768 l 25,5,-1 + 1024 512 l 25,6,-1 + 512 512 l 25,7,-1 + 512 768 l 25,8,-1 + 256 768 l 25,9,-1 + 256 1024 l 25,10,-1 + 512 1024 l 25,11,-1 + 512 1280 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: uacute Encoding: 250 250 250 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 97 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns24'ehBu @^QY_"YR:$'k#Q%'I9UW!%-V/$md\(4TGH^!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +512 1024 m 29,0,-1 + 768 1024 l 25,1,-1 + 768 768 l 25,2,-1 + 512 768 l 25,3,-1 + 512 1024 l 29,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: ucircumflex Encoding: 251 251 251 -Width: 256 +Width: 1536 VWidth: 2048 -Flags: MW -LayerCount: 2 +Flags: MWO +LayerCount: 3 Back Image2: image/png 117 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+FNffG9`ah?c "'5Jc7@&J'AqDaVd7hVN@oGeJ"H^;>;m=pc1(e=(/kM-+!-+VE$NJqlp](9o!(fUS7'8jaJcGcN EndImage2 Fore +SplineSet +512 1792 m 25,0,-1 + 1280 1792 l 25,1,-1 + 1280 1536 l 25,2,-1 + 768 1536 l 25,3,-1 + 768 587 l 0,4,5 + 768 256 768 256 437 256 c 24,6,7 + 437 256 437 256 331 256 c 0,8,9 + 0 256 0 256 0 587 c 16,10,11 + 0 587 0 587 0 1024 c 9,12,-1 + 256 1024 l 25,13,-1 + 256 587 l 0,14,15 + 256 512 256 512 331 512 c 24,16,17 + 331 512 331 512 437 512 c 0,18,19 + 512 512 512 512 512 587 c 24,20,-1 + 512 1792 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: udieresis Encoding: 252 252 252 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 111 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8Bu3Ns2`"cP]X E%A0G"uZK-!Q'eS+SD[`TG7SE0ER5g])gH$#S-plN=l21\-JE%!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +-0 1280 m 25,0,1 + -0 1280 -0 1280 693 1280 c 0,2,3 + 1024 1280 1024 1280 1024 949 c 24,4,5 + 1024 949 1024 949 1024 256 c 25,6,-1 + 768 256 l 25,7,-1 + 768 949 l 0,8,9 + 768 1024 768 1024 693 1024 c 24,10,11 + 693 1024 693 1024 256 1024 c 25,12,-1 + 256 256 l 25,13,-1 + -0 256 l 25,14,-1 + -0 1280 l 25,0,1 +EndSplineSet Validated: 1 EndChar StartChar: yacute Encoding: 253 253 253 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 110 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?L$N'RdN0FYgqo`&:TWj&8\ <%ndLEXLID6LpLu+!mRNL72;b6E@ (`=3"9Eo$3$(=,i!k922m=dV+a8c2MpBh@PrMsB-!!!!j78?7R6=>BF EndImage2 Fore +SplineSet +512 1280 m 25,0,-1 + 1280 1280 l 25,1,-1 + 1280 256 l 25,2,-1 + 512 256 l 25,3,-1 + 512 1280 l 25,0,-1 +EndSplineSet Validated: 1 EndChar StartChar: ydieresis Encoding: 255 255 255 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW -LayerCount: 2 +LayerCount: 3 Back Image2: image/png 79 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(.gn[<#?K_r!ro=GQ8Bu3O%$&:]LJ7 diff --git a/resources/lsi-adm-3a/bitmap/00-00.png b/resources/lsi-adm-3a/bitmap/00-00.png new file mode 100644 index 0000000000000000000000000000000000000000..eb99c7eda738143626754ddddaa37ed65c39e11c GIT binary patch literal 76 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq!k#XUAr*1SKl~XC7H}_Uez=f< Yp=IlT#!4@X4M1rIPgg&ebxsLQ08qU!(`u514sgd|N!5fnl%Z8Iwh-f2IPpF?hQAxvX<}=t xVAkjiX7mwS&6MJ~hU)-}B5ML05c7$#GF(zQZ)mQbF9_7g;OXk;vd$@?2>>eu7W)7I literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-04.png b/resources/lsi-adm-3a/bitmap/00-04.png new file mode 100644 index 0000000000000000000000000000000000000000..b01e1880d8384292022ecac6ca505a3b7e2e2b3d GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqYMw5RAr*1SKl~XC8aUb5EZo=& sSPK|UTth+{uJit2VBVCMvy6dZX6zZ0?aUlEfI1jFUHx3vIVCg!0HNL&L;wH) literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-05.png b/resources/lsi-adm-3a/bitmap/00-05.png new file mode 100644 index 0000000000000000000000000000000000000000..70a5bf0cf047610b76536b93b5086d58738f3b1a GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC8aUb5M0!FQ t^%@eHtQ79DlpNi$)rpaLS6+!Q!#Ygr+Ar*1SKl~XC8aUb5M0!FQ t^%@eHtQ79C#4v2<5iwZso8hhr!w#QIdSNftX#lk_c)I$ztaD0e0sy{l7y1}_d!VlEO;OXk;vd$@?2>?}a8ZZC= literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-08.png b/resources/lsi-adm-3a/bitmap/00-08.png new file mode 100644 index 0000000000000000000000000000000000000000..f632759d63857e9fac2317876878c45a0eb55abb GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqx}GkMAr*1SKl~XC7H}_M-oeDi z_9pA#q8%!Z4U8(CeSsnlp$j>bm>=C~;Adc%_2P+4G{Ygr+Ar*1SKl~XC4oLD8sBtZ5 tVw%BX#mk%^=ONH`kug#G0_z1vhR4kh`XP B8!`X@ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-14.png b/resources/lsi-adm-3a/bitmap/00-14.png new file mode 100644 index 0000000000000000000000000000000000000000..c2bc6799c262c2f748d14bc48ca3c99b14767a04 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC4oLD8sBtlL tA5z(~Uo(X|Iy8RR@4%3FJ}+yZK0@O1TaS?83{1OWD27_0yQ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-15.png b/resources/lsi-adm-3a/bitmap/00-15.png new file mode 100644 index 0000000000000000000000000000000000000000..ae53c223b564fc4664597709dae8a83a0f94c1d5 GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq%APKcAr*1SKl~XC7#MdkXvs$k o#0u%Kr6){eVXTU1)N9~ln7sX=yjd9E51?`ePgg&ebxsLQ06$|DRR910 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-16.png b/resources/lsi-adm-3a/bitmap/00-16.png new file mode 100644 index 0000000000000000000000000000000000000000..6ee609332b544de9fc78d0bf5303c9f1db732451 GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqdY&$hAr*1SKl~XC8aUb5EZo?6 zPBh&RIVif|vH?R_Lmror!W*^{#uA3@Ow%rHoVldVSV%W?yTggYzDihL=Vsi{ICQwk7O0EC)78&qol`;+04uy1>;M1& literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-18.png b/resources/lsi-adm-3a/bitmap/00-18.png new file mode 100644 index 0000000000000000000000000000000000000000..f5f50223acee31953dc74d7c16edee4b21df22f1 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq`kpS1Ar*1SKl~XC8aUb5434n{ zxNOvH>Q0!gTe~DWM4fO1&8x literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-20.png b/resources/lsi-adm-3a/bitmap/00-20.png new file mode 100644 index 0000000000000000000000000000000000000000..05cc345fec498cd5511101bf87ac1a871375bf7c GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqI-V|$Ar*1SKl~XC78FPX><}=t yVAkjiX7piN&y>=$km20HR3^Iv4S6=ZG#NxSF6m8@`J4~b$KdJe=d#Wzp$PzT5gL~O literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-21.png b/resources/lsi-adm-3a/bitmap/00-21.png new file mode 100644 index 0000000000000000000000000000000000000000..7d630caba1602359c9049e9a87efe389870c8df8 GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqI-V|$Ar*1SKl~XC8aUYuSOp!D ynt#4%G6`ZxV^F=IdhpQ;rWXy2%Y-GBnHl`=U((aa56}SWWAJqKb6Mw<&;$U0_ZpS} literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-22.png b/resources/lsi-adm-3a/bitmap/00-22.png new file mode 100644 index 0000000000000000000000000000000000000000..808188adaf4b40b4316ba806f20d157ec038e6c8 GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqdY&$hAr*1SKl~XC7#MdkSjjsx zOzqd{(Bl+i7H$z~kc?1qWZ11C#9%EXtIW(GCx2DD|3|h7P$z?@tDnm{r-UW|28I@L literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-23.png b/resources/lsi-adm-3a/bitmap/00-23.png new file mode 100644 index 0000000000000000000000000000000000000000..d19284efe011209863ba8da8726c1073a58414b4 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqTAnVBAr*1SKl~XC7#MdkSjjsx w%;gt!Sf1FhfvILvf?)|`3BxufS!HI18**n%^4m)u0(CKXy85}Sb4q9e0R2T6SO5S3 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-24.png b/resources/lsi-adm-3a/bitmap/00-24.png new file mode 100644 index 0000000000000000000000000000000000000000..3053d7ec0a18f80f972d0f4b276bbbe51b75d14f GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqI-V|$Ar*1SKl~XC7#MdkXvs$k y#0u%Kr6){eVLYU^fII0!U_}JO4VID~9)`z}SG9ZYF{}jYWAJqKb6Mw<&;$TBP8qNO literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-25.png b/resources/lsi-adm-3a/bitmap/00-25.png new file mode 100644 index 0000000000000000000000000000000000000000..50a8aef23bacb62935e52a7f540d334d3cb45a06 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC7#MdkXvs$k t#0u%Kr6){eVbsz(zYgr+Ar*1SKl~XC7#KSo4oYxc tV7c&9fN_z}fz=Hf!V8#Q)co1Uz`*0Q#iw=m5I y6wEUH;8G4(k=aT-f+emJTo)K`h`*4KWMEL}eJCH*dG;MpAA_f>pUXO@geCx61sWg# literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-29.png b/resources/lsi-adm-3a/bitmap/00-29.png new file mode 100644 index 0000000000000000000000000000000000000000..cf94ef52fe28619c07fd115457bf6e9c08feb03b GIT binary patch literal 91 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqN}eu`Ar*1SKl~XC8aUb5EZo>N nluSY#wn%SaWJ|ew!-tW9-Q}wG)}~+iK-CPMu6{1-oD!Ma7g zEa>5Tz*WGwfk}hemy78E*8&+8%@q=D46~GYSYI$OIR3t;r0{CTVxVpYPgg&ebxsLQ E0KMlLy#N3J literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/00-31.png b/resources/lsi-adm-3a/bitmap/00-31.png new file mode 100644 index 0000000000000000000000000000000000000000..120fe56d5abd1bb69d9ca01e43238fcab180ab0d GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq+MX_sAr*1SKl~XC5;zPNa0#ww xP-_fj+@#RPG=ag&Es!C!RjGr=;7$V{L;md>8uQMU&j4y;@O1TaS?83{1OP1u8Lt2U literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-00.png b/resources/lsi-adm-3a/bitmap/01-00.png new file mode 100644 index 0000000000000000000000000000000000000000..eb99c7eda738143626754ddddaa37ed65c39e11c GIT binary patch literal 76 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq!k#XUAr*1SKl~XC7H}_Uez=f< Yp=IlT#!4@X4M1rIPgg&ebxsLQ08yrAyVtD@ctLKLV?N{JYD@<);T3K0RYJd6rBJ7 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-03.png b/resources/lsi-adm-3a/bitmap/01-03.png new file mode 100644 index 0000000000000000000000000000000000000000..a871ac0d9c79bbdc972c7ccfb65551a4891f9585 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqTAnVBAr*1SKl~XC8aUYuSeH*^ wOk`DXEa_Rqu!?J$l&g@I+e*#^rhX;{_LYZiugKkA0My0c>FVdQ&MBb@00L1MX#fBK literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-04.png b/resources/lsi-adm-3a/bitmap/01-04.png new file mode 100644 index 0000000000000000000000000000000000000000..1a3cdde874a2f37abedc4d0dc345fdc49592ecfb GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqdY&$hAr*1SKl~XC4oLD8sBtlL zH>pfC>|&b1u#1H!VMYU=!JUS69679>Y73Ydd}p6AS;m|92B?$4)78&qol`;+0Ffga AumAu6 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-05.png b/resources/lsi-adm-3a/bitmap/01-05.png new file mode 100644 index 0000000000000000000000000000000000000000..861bbd371406bdefade1cb5a0f0f7545e9b1f865 GIT binary patch literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq#-1*YAr*1SKl~XC7#KSo#M_y9 zSYLDnR=k*$U}(YIt-{gZTIkutaD&%FhUch6oG zs1#}{tzqzaFoA`UNBDy1VNnN5kDvfU1I8%_QkfY3*bP0l+XkK D!896W literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-07.png b/resources/lsi-adm-3a/bitmap/01-07.png new file mode 100644 index 0000000000000000000000000000000000000000..8892934eea063eade7bbec74bf7536e82150a008 GIT binary patch literal 82 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqlAbP(Ar*1SKl~XC4oLD8sBtY= f#1zxO$HnmO#W${3PBx2xiWody{an^LB{Ts5v^W%! literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-08.png b/resources/lsi-adm-3a/bitmap/01-08.png new file mode 100644 index 0000000000000000000000000000000000000000..b4a3244ffe45698e4f67ed41eb42bbc103b41e93 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqYMw5RAr*1SKl~XC4oLD8sBtlL sKbpkC$W}8+!GV=EfvI1qX&(cFPU9=F&3?B|0d+8Vy85}Sb4q9e0IYgr+Ar*1SKl~XC4oLD8sBt+6 t9$m)a%n~a&Rdj)O)6oY!I+GL_7+xQIC3aNoza3BugQu&X%Q~loCIIqG8EXIl literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-10.png b/resources/lsi-adm-3a/bitmap/01-10.png new file mode 100644 index 0000000000000000000000000000000000000000..2e0d10d5a169b40f79837053d2609cfa859fd7e4 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqx}GkMAr*1SKl~XC4oLD8sBtAU zcrLhX!0@b*B~e0FU>lRq17pU!c_pqaYZ(~S-dxgS+aMutrnp2)bJop=zahr!d;&t;ucLK6VtDHu)w literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-12.png b/resources/lsi-adm-3a/bitmap/01-12.png new file mode 100644 index 0000000000000000000000000000000000000000..065f4fbc56903f82c042d5eef6a76c0e67b26544 GIT binary patch literal 86 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqvYsxEAr*1SKl~XC7H}_MuF^_K jIIwP-1?vtKM+Szb+26Qs?$~?}sF1GAr*1SKl~XC7H}_M*3w{L m5@>7+6j|_L1H&m%28Pt44+1G~uVet#GI+ZBxvX`%F783vf literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-15.png b/resources/lsi-adm-3a/bitmap/01-15.png new file mode 100644 index 0000000000000000000000000000000000000000..46b66d6bf9ba93e30430d7dcd402566b7be84388 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq`kpS1Ar*1SKl~XC7H}_M=3(XG zS>dE%Q{uTnVosy05X*r@J5(GS80V{SJebbP#E@F_LBNmurW;TzgQu&X%Q~loCIFqp B8f5?g literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-16.png b/resources/lsi-adm-3a/bitmap/01-16.png new file mode 100644 index 0000000000000000000000000000000000000000..33fa396962c4a9658a2df27b5a23875a5b11eae3 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq2A(dCAr*1SKl~XC8aUb5EZo?6 zUNlAg;9$&Ic0hE&Wdnw=hCD7Kg*R+76n1$UFff#O9kXKkcI72dFN3G6pUXO@geCyu Cy&P`< literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-17.png b/resources/lsi-adm-3a/bitmap/01-17.png new file mode 100644 index 0000000000000000000000000000000000000000..8c0287a5b43740ee5bcde305d04d7cb9f9ef6bd5 GIT binary patch literal 91 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqN}eu`Ar*1SKl~XC4oLD8sBtlL oH>rHoVlZZlU_3MNh6p3Wk$n&4KWtPK2dZZ9boFyt=akR{0BXn=1^@s6 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-18.png b/resources/lsi-adm-3a/bitmap/01-18.png new file mode 100644 index 0000000000000000000000000000000000000000..65a549870ebb59fedbab1bfc13b150978b7ad5db GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq`kpS1Ar*1SKl~XC8aUb5EZo?6 zUNlM6h{$;`OlO)C*1)MFWYF-Ct%M=0p>HB1!^ZqedS~YBPzGvc@O1TaS?83{1OR>f B8eaea literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-19.png b/resources/lsi-adm-3a/bitmap/01-19.png new file mode 100644 index 0000000000000000000000000000000000000000..80aee18dca4a3898b1020157e82506b281b7ea41 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq2A(dCAr*1SKl~XC7#KSo4r*`( zR46dka9vP6m{h|TGBP|7x}=xOdR_#mm%-E3&t;ucLK6V& C>l`cq literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-20.png b/resources/lsi-adm-3a/bitmap/01-20.png new file mode 100644 index 0000000000000000000000000000000000000000..59631f5453f62697b255f45722f187249f85824e GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqdY&$hAr*1SKl~XC78FPX><}=t zVAkjiX7piN&6MIehwFl27n2B|nQ(wbga`wJl;~CMKPxYO2I^$+boFyt=akR{0A@-V Ag#Z8m literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-21.png b/resources/lsi-adm-3a/bitmap/01-21.png new file mode 100644 index 0000000000000000000000000000000000000000..3e5ad28159723375fdd088505993109052f61282 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq8lEnWAr*1SKl~XC7#KSo4oYx+ uVB`_Lz}UvIOX(2T295=v5}S71VPKf8e8%MDEjb>b9tKZWKbLh*2~7YRbQ%)? literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-22.png b/resources/lsi-adm-3a/bitmap/01-22.png new file mode 100644 index 0000000000000000000000000000000000000000..bc76cc996e6349a3406a96fd73f71397dbd94331 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq2A(dCAr*1SKl~XC4oLFw6!h>M zuqkm&IndxQ#BzYEK$1VaL9OB3aRG;?hgk|E85vGloj3gXt`(%0!PC{xWt~$(695$K B9rXYJ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-23.png b/resources/lsi-adm-3a/bitmap/01-23.png new file mode 100644 index 0000000000000000000000000000000000000000..5d7913aa1ce0679cfa51b054639b8b72c71f4a3e GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq+MX_sAr*1SKl~XC7#KSo4r*`( xR46dka9vP6m{hcxAr*1SKl~XC8aUb5EZo?6 nUNlAgkYHL-Gvfh66eEN0>@z0G{2z0HiWxjz{an^LB{Ts5QVbTR literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-25.png b/resources/lsi-adm-3a/bitmap/01-25.png new file mode 100644 index 0000000000000000000000000000000000000000..085eff386bcfdd3e066f776adac7814f5dc8da12 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqx}GkMAr*1SKl~XC8aUb5EZo?6 zUNlAgkYHL-Gebcy+d${&YKB-Lt+u-v5)2Hh?9Lm;^Ugd6)X3oJ>gTe~DWM4fdvqFm literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-26.png b/resources/lsi-adm-3a/bitmap/01-26.png new file mode 100644 index 0000000000000000000000000000000000000000..4030203e34fb73fbf64aff38fcdc58261a91b57f GIT binary patch literal 88 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq@}4e^Ar*1SKl~XC7H}_Mek5vO kkPzM-E5aFYktK$KVRgz+_MYH#B0!}Kp00i_>zopr04VJhtpET3 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-27.png b/resources/lsi-adm-3a/bitmap/01-27.png new file mode 100644 index 0000000000000000000000000000000000000000..26e0de807646e262b1d45e5f6e371f1d94757afe GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq%APKcAr*1SKl~XC7H}_Mek5vO okPzM-E5a#|&lJbHL&cGSVYA<7Ufz3^SwQ6sp00i_>zopr0Bv&?FaQ7m literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-28.png b/resources/lsi-adm-3a/bitmap/01-28.png new file mode 100644 index 0000000000000000000000000000000000000000..27aeba85c4e84900606e1b0784ac4c6a2cb30419 GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqI-V|$Ar*1SKl~XC78FPX><}=t xVD47oXmBm`Y+_)x^Au3XVVcwEEa(`|z))iON^Iwv$b~?C44$rjF6*2UngBIL7_k5V literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-29.png b/resources/lsi-adm-3a/bitmap/01-29.png new file mode 100644 index 0000000000000000000000000000000000000000..7ac28a1101433603fbc865316170e9145bfb2e3d GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq%APKcAr*1SKl~XC7H}_MKE&0) m;Ibe=gjK^vr-4fiB*fsR|4=?!-cSLkoWax8&t;ucLK6U0j}*iJ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-30.png b/resources/lsi-adm-3a/bitmap/01-30.png new file mode 100644 index 0000000000000000000000000000000000000000..44ab9826f0fcf02aae31ac3c52001062d15149ca GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq8lEnWAr*1SKl~XC8aUYuT15|} u7HB#N9$m)a%n~d3Q7vII3uDth28Jb^uf%#e9()AqVeoYIb6Mw<&;$Vb9~k%m literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/01-31.png b/resources/lsi-adm-3a/bitmap/01-31.png new file mode 100644 index 0000000000000000000000000000000000000000..6dfe0f086eb9115e6255780a7380a0e80ce301e2 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq8lEnWAr*1SKl~XC8aUb5EZo?6 tUNlM6i13*SKj6`sq~NfJDW+ioC&QDpCo&n5()mC=44$rjF6*2UngGS27c~F? literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-00.png b/resources/lsi-adm-3a/bitmap/02-00.png new file mode 100644 index 0000000000000000000000000000000000000000..d660d0663ed0c5063ef2c78099102fd799398c16 GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqdY&$hAr*1SKl~XC8aUb5EZo?6 zUNlAg5MV5kVha#S*v#h4Xmy}~+3LUt)?I82S#F1I)zf`n0(CNYy85}Sb4q9e0B#)_ A-~a#s literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-01.png b/resources/lsi-adm-3a/bitmap/02-01.png new file mode 100644 index 0000000000000000000000000000000000000000..a54eb9d1cb4989b5aece0880deba9a6e343d9ca4 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq2A(dCAr*1SKl~XC4oLD8sBtlL zA5z(ehv&u(tP>5}m`oT;?AjQ(bP0l+XkK(sda9 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-04.png b/resources/lsi-adm-3a/bitmap/02-04.png new file mode 100644 index 0000000000000000000000000000000000000000..c38d913ac765fc338a39685e90a1e50cc50a694a GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq+MX_sAr*1SKl~XC7#KSml1muE x8q^xj9T#wTp3Je}vmwicpAt+jYX0nFVAv>q(%h8sQ5#SjgQu&X%Q~loCIG809L)d# literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-05.png b/resources/lsi-adm-3a/bitmap/02-05.png new file mode 100644 index 0000000000000000000000000000000000000000..9cd61778c1138c50cc6ed18c41dcf1c7c70186d6 GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq%APKcAr*1SKl~XC7#KSo4oYx+ pV0(tqm>&QLuT?x^K0^}*8-I@c)I$ztaD0e0swN%7M%b9 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-06.png b/resources/lsi-adm-3a/bitmap/02-06.png new file mode 100644 index 0000000000000000000000000000000000000000..a422e16b243a39d61a0346fd24d22deb95e9b747 GIT binary patch literal 89 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq3Z5>GAr*1SKl~XC7#KSo4oYx+ mV0VcftJGfBZ=4yT8VislZ9w$*_@7}S4W)mE8f$q&@Z;OXk;vd$@?2>@eX B8Cd`T literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-12.png b/resources/lsi-adm-3a/bitmap/02-12.png new file mode 100644 index 0000000000000000000000000000000000000000..ce48b44f4ca10c4a05f2007e621c70ff5110c815 GIT binary patch literal 81 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq5}q!OAr*1SKl~XC7#Md+a7kEk eT`)9aV0gLwp3?OVVVi(z7(8A5T-G@yGywpEv=e^- literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-13.png b/resources/lsi-adm-3a/bitmap/02-13.png new file mode 100644 index 0000000000000000000000000000000000000000..8fbb8af5cdaae63acf2e236c1643c5ea57075235 GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqI-V|$Ar*1SKl~XC7#MdkSj}hD y>p0^U$S~PuSz<#4s|VAI8Xm?HyEXPMQln&YA<%$KdJe=d#Wzp$PzDw;ERf literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-14.png b/resources/lsi-adm-3a/bitmap/02-14.png new file mode 100644 index 0000000000000000000000000000000000000000..a87b00821dd85dcf91c3313a0aab5a321e0c0036 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq+MX_sAr*1SKl~XC7#MdkSjjsx w%stzopr00Ze4x&QzG literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-15.png b/resources/lsi-adm-3a/bitmap/02-15.png new file mode 100644 index 0000000000000000000000000000000000000000..cabe02087f7a558bfb17d797981ccf188d449d7c GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqx}GkMAr*1SKl~XC8aUb5EZo?6 yUNlAgkYIXI!^2o&*T!Ha@60fjU$`Z)gn?m~&3QxJRr%RKjSQZyelF{r5}E){F&O^< literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-16.png b/resources/lsi-adm-3a/bitmap/02-16.png new file mode 100644 index 0000000000000000000000000000000000000000..afb0809d38165148280758b7b1db3e60ab9a9b8c GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq%APKcAr*1SKl~XC7#KSml1muE o8q^xj9T#wTJ~@NcYC#Mm1OMJjdY+n!Nzopr0F7!E-v9sr literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-17.png b/resources/lsi-adm-3a/bitmap/02-17.png new file mode 100644 index 0000000000000000000000000000000000000000..c60c79a197109a1bf7abbb4ee147270de6b5c2af GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqhMq2tAr*1SKl~XC8aUb5EZo?6 zUNlAgkYIXI!^2o&=fW_zjZsASg6hGf1g4YhFS-~uSe!AL>HInhsF}gj)z4*}Q$iB} D?#3K` literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-18.png b/resources/lsi-adm-3a/bitmap/02-18.png new file mode 100644 index 0000000000000000000000000000000000000000..e63aea4ac853957e20c7ce0c66644adaa3015105 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqTAnVBAr*1SKl~XC7#KSml1muE w8q^xj9T#wTE}Y3~<|*K?k!iM4Qyv3@ZShI-1%DzI0(CKXy85}Sb4q9e06_s7BLDyZ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-19.png b/resources/lsi-adm-3a/bitmap/02-19.png new file mode 100644 index 0000000000000000000000000000000000000000..a7931de30f9ff8d7ca4f0dfef51a6f2ed39c7fe2 GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqnw~C>Ar*1SKl~XC8aUb5EZo?6 vUNlAgn6YaDW1_YJ3rA$*!FJ9^o0u5X-dxfX_r7u(sENVT)z4*}Q$iB}Fohaq literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-20.png b/resources/lsi-adm-3a/bitmap/02-20.png new file mode 100644 index 0000000000000000000000000000000000000000..add9f970a4a1d44852b250b1065c514b48709f6d GIT binary patch literal 84 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq(w;7kAr*1SKl~XC7#KSo4r*{c g;4$HpkPzZxuzY?`iCb;I5KtL|r>mdKI;Vst0G<&NN&o-= literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-21.png b/resources/lsi-adm-3a/bitmap/02-21.png new file mode 100644 index 0000000000000000000000000000000000000000..e0019e45b2add17ba07ba3b8969240a02d2b8e1e GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqTAnVBAr*1SKl~XC7#MdkSjjsx w%(^b literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-22.png b/resources/lsi-adm-3a/bitmap/02-22.png new file mode 100644 index 0000000000000000000000000000000000000000..79216bf75ffae8081941ec4bac987894d550a777 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqx}GkMAr*1SKl~XC7#MdkSjjsx z%Ar*1SKl~XC7#MdkSjjsx v%dx;Ie_k9Htb{HCz{10)8-@lR9Z0{Q8F(P!ofvtDnm{r-UW|Hc1-V literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-24.png b/resources/lsi-adm-3a/bitmap/02-24.png new file mode 100644 index 0000000000000000000000000000000000000000..7570b70830e2884063cf4d7a7b548d2e0f310295 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq+MX_sAr*1SKl~XC7#MdkSjjsx xOzqd{(Bl+qHs0XT#E>X_fpy~tLzaLa3=Fn6G%6D^x`5gkJYD@<);T3K0RSf;86p4x literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-25.png b/resources/lsi-adm-3a/bitmap/02-25.png new file mode 100644 index 0000000000000000000000000000000000000000..85249c219fbe73ee98afb377182b0f993321a42f GIT binary patch literal 93 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqDxNNmAr*1SKl~XC7#MdkSjjsx pOzqd{(Bl+qHs0XT#2_oe!0;{Pp}ba{@MNHR22WQ%mvv4FO#oZ16;%KL literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-26.png b/resources/lsi-adm-3a/bitmap/02-26.png new file mode 100644 index 0000000000000000000000000000000000000000..fb7c8a229cc059fab1afda1109fec1c50c67af13 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq`kpS1Ar*1SKl~XC7#KSo4r*`( zR46dka9vP6m{hFVdQ&MBb@0J32c`~Uy| literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-28.png b/resources/lsi-adm-3a/bitmap/02-28.png new file mode 100644 index 0000000000000000000000000000000000000000..4e3e8fc794596e24b1038edd94d9b214ff5af412 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq+MX_sAr*1SKl~XC7H}_MW>atw xcVtS2&WpWpR3K=|I{an^LB{Ts5@pBau literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/02-30.png b/resources/lsi-adm-3a/bitmap/02-30.png new file mode 100644 index 0000000000000000000000000000000000000000..3cd799877ee59a2707503a5611c7d093850720a2 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq8lEnWAr*1SKl~XC7H}_Mek5vO ukPyx-*6NuQe566IbP0l+XkKycxAr*1SKl~XC8aUYuT15|} n7HB#N9$m%}%))!Yk&)rui*H;;7yGJ!iWxjz{an^LB{Ts5U4Iub literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-01.png b/resources/lsi-adm-3a/bitmap/03-01.png new file mode 100644 index 0000000000000000000000000000000000000000..0dbcf3e103b291b284e68c7a4944d937b15d13cc GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqnw~C>Ar*1SKl~XC7H}_M-oV7h v#%AHhuAyWhDqzB>))>yH7i_R~0V9L={~HbP0l+XkK#E2Kj literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-02.png b/resources/lsi-adm-3a/bitmap/03-02.png new file mode 100644 index 0000000000000000000000000000000000000000..feee5c83489db483a68ea072185044189792844c GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqnw~C>Ar*1SKl~XC8aUYuT15rc vGqhb~Y~y^<#i8wBCKoHTh9QbP0l+XkK3(FbE literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-03.png b/resources/lsi-adm-3a/bitmap/03-03.png new file mode 100644 index 0000000000000000000000000000000000000000..6c3777a8745b6b539feb550d7ef1817f76073022 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqYMw5RAr*1SKl~XC7H}_M-oeDi s#%AHhmLRuF!DzuGCIjaA(jOQZuB~|@!+3dt3Qz}wr>mdKI;Vst0I1FvRsaA1 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-04.png b/resources/lsi-adm-3a/bitmap/03-04.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d2de54d94a2d0c44f9d092d35a7341a144675d GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq+MX_sAr*1SKl~XC78FPX><};% x;nQPP;FNG<=Q+{zM3X_-BW!{8p({;n40q#iXq@a!YyxUy@O1TaS?83{1OPCk8OZjs2dO~6~Q%r+}`2%K#Wt;9P?V1z<}=t xVAkqf$KlLq#n9cPk|-f7kj^y2(SuQsf#GHC6Pc~v95q0F44$rjF6*2UngAk#`lfigF*nWF$~4gQu&X%Q~loCIEqR B8S4N5 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-08.png b/resources/lsi-adm-3a/bitmap/03-08.png new file mode 100644 index 0000000000000000000000000000000000000000..eaf248b622fa87d9e7b8b52090fac856b59f26fe GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqik>cxAr*1SKl~XC8aUYuT15rc nGqhb~Y~y^tg9JZ!}_6@RV?4pP`h&z_5k=m001XL?fVj22WQ%mvv4FO#pJz71;m) literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-10.png b/resources/lsi-adm-3a/bitmap/03-10.png new file mode 100644 index 0000000000000000000000000000000000000000..e72f1daa8780900d8354c8631e6a465589e3eff3 GIT binary patch literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqs-7;6Ar*1SKl~XC78FPX><}<4 rVJvZ&#rZ_L!Sg`~Lt4T_7DfiQ=2v2TF#-pG8W=oX{an^LB{Ts5!G9O2 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-11.png b/resources/lsi-adm-3a/bitmap/03-11.png new file mode 100644 index 0000000000000000000000000000000000000000..44f73f24891d6e7b7db9d4db25eb2ce5a5732910 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqx}GkMAr*1SKl~XC8aUYuT168y z9Kw4RF~kb#u&Ff&-B59Cs1Sa@bmL9~KLf+YnfH`9I5O4(H8Oa*`njxgN@xNAWFr~m literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-12.png b/resources/lsi-adm-3a/bitmap/03-12.png new file mode 100644 index 0000000000000000000000000000000000000000..a267cb2000dcb87461ebf46667d1f84148878159 GIT binary patch literal 89 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq3Z5>GAr*1SKl~XC8aUb5434oq mSj4=R;h9HHmx1dA28M@|pU5yKEUE{pW$<+Mb6Mw<&;$TgnHL@a literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-13.png b/resources/lsi-adm-3a/bitmap/03-13.png new file mode 100644 index 0000000000000000000000000000000000000000..d62418dd89f2139bd8bbd101f7de1b8bbad98d63 GIT binary patch literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqs-7;6Ar*1SKl~XC7H}_MW>a7g qG~k!A10*(&F3C^?=G5JYD@<);T3K0RT^r6}A8X literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-15.png b/resources/lsi-adm-3a/bitmap/03-15.png new file mode 100644 index 0000000000000000000000000000000000000000..3ddc0754f41c4305dfbff3a2d2d39b4a61b7807e GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC7H}_M-oeDi t#%AEgo*hTJ#E|x&nAwhjq4D!W`7Iazz6NSx@O1TaS?83{1OUU97_k5V literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-16.png b/resources/lsi-adm-3a/bitmap/03-16.png new file mode 100644 index 0000000000000000000000000000000000000000..919327c0ef2553eebd849afbaaf06a337dc12fe4 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC7H}_M-oV7h t#%AHhUcg$wXySTATj3U0i9-M*L(aY1s`q(58UwX3c)I$ztaD0e0syej7fJvC literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-17.png b/resources/lsi-adm-3a/bitmap/03-17.png new file mode 100644 index 0000000000000000000000000000000000000000..49a15d8e0448b6c7fc847036e4aecd1c4c7cabbb GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq8lEnWAr*1SKl~XC7H}_M-oV7h u#%AHh&U2#ai6(>ak2MYt1r{^J3Nkow-_R(G^~nM1VeoYIb6Mw<&;$VEI~T|R literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-18.png b/resources/lsi-adm-3a/bitmap/03-18.png new file mode 100644 index 0000000000000000000000000000000000000000..90bfabbf514f51323f4fb08030531d4ffa6af879 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC7H}_M-oV7h t)?p>Uo1CoSFuj3MM0f+EmgWI=2C2;FlA1id78(Em literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-19.png b/resources/lsi-adm-3a/bitmap/03-19.png new file mode 100644 index 0000000000000000000000000000000000000000..d97d28ae8ebdc5ad96fb2011c41234df787fdaa9 GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqnw~C>Ar*1SKl~XC7H}_M-oV7h v#wOAe%BaUM{opcboj%2e(_DM<4zM$9nRZ)s!j7lBKurvuu6{1-oD!M<7||K| literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-20.png b/resources/lsi-adm-3a/bitmap/03-20.png new file mode 100644 index 0000000000000000000000000000000000000000..6c090cb269e58344993a5cf19f91008cce5830cf GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq8lEnWAr*1SKl~XC4oLD8sBtlL tH>o5_$O@!0&2ZevWWe67atw zcX*!6vEb80){CkKlMAr*1SKl~XC7H}_MW>atw vcX*!6vEZ{J(+d+Gfv^UDA)Pk820n)K)wflDU1Z-2)WqQF>gTe~DWM4f9&{Pb literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-24.png b/resources/lsi-adm-3a/bitmap/03-24.png new file mode 100644 index 0000000000000000000000000000000000000000..d31001ae9d966c43178179e994c97553ae3da9fd GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqI-V|$Ar*1SKl~XC7H}_MW>atw ycX+DIy~w-i=mQ>|NeT`(SV|mu?6~;385lNQcp{^AtLy<#AA_f>pUXO@geCxD(Hc7d literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-25.png b/resources/lsi-adm-3a/bitmap/03-25.png new file mode 100644 index 0000000000000000000000000000000000000000..3c9ec131c860f7bd98e897556e8ff0a95d498b16 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqx}GkMAr*1SKl~XC7H}_M-oV7h z)?$@nHltt9V;++Mvj*eg6AXtZT8JiG=4E0yy70EDg)YA@P$Pqa7g x)R1sxAr*1SKl~XC78FPX><}=t tVD47o5LnJI9Z04#&2aQ!oYCwm$S_0nm6)7;GdoZdgQu&X%Q~loCIHuF7J>i( literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-28.png b/resources/lsi-adm-3a/bitmap/03-28.png new file mode 100644 index 0000000000000000000000000000000000000000..b44f8d6e7748cfb3203c4dfa0356ff36848d6a7d GIT binary patch literal 85 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqGM+AuAr*1SKl~XC4oLD8sBtY= h#1zv|A$%f?f#JuYx5CL5mRUe`44$rjF6*2UngH_;6+Qp} literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-29.png b/resources/lsi-adm-3a/bitmap/03-29.png new file mode 100644 index 0000000000000000000000000000000000000000..092faf263489b7144b5ef9f5cee4169ece902bef GIT binary patch literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqs-7;6Ar*1SKl~XC8aUYuT15|} p7HBHPG0tdq75u37Ahf|-h=rj+_m!BIffL9C22WQ%mvv4FO#q~)7SaF! literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-30.png b/resources/lsi-adm-3a/bitmap/03-30.png new file mode 100644 index 0000000000000000000000000000000000000000..8591816a399bc846dcffc1d8646372117fe2082a GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq8lEnWAr*1SKl~XC7H}_Mz9ed3 uuz;(vQo&Kejh*KP%S6VyoBv%j7#LEEJ_vAHt``LAVeoYIb6Mw<&;$VXmKYcS literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/03-31.png b/resources/lsi-adm-3a/bitmap/03-31.png new file mode 100644 index 0000000000000000000000000000000000000000..9b2ea1acdca35e57a6e362d3d04aed979836a651 GIT binary patch literal 83 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqQl2i3Ar*1SKl~XC7H}_MKE&0) g;IiPs!DS2#T~1qk%D%6>1ysf0>FVdQ&MBb@0PDIIcK`qY literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-00.png b/resources/lsi-adm-3a/bitmap/04-00.png new file mode 100644 index 0000000000000000000000000000000000000000..169ba4278beb928b653e225c533b35f6b90a6d54 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq2A(dCAr*1SKl~XC8aUb5EZo?6 zUNlAgn6YaDV;d8XosYnB=?6SIlN1=XF-=ziYS({!RXdyWM=($?gQu&X%Q~loCIG}- B8r1** literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-01.png b/resources/lsi-adm-3a/bitmap/04-01.png new file mode 100644 index 0000000000000000000000000000000000000000..47471a7e03daa434b4a27ab602928c24dd4a7d1a GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqYMw5RAr*1SKl~XC8aUYuSOp!D snty88=rmXezgWOqU!RHH8IuiH)cyjsF?hQAxvX<}=t zVAkqf$8m<4^N@j+!a1%cwFjHzb=cG<_&9{KFjQ_mZAr*1SKl~XC4oLFw6!h>M uuqkm&aZqJVV6!tnU>V`l6y4}6#KNE_dt0@s`Nj#LCI(MeKbLh*2~7Y4ofxJ7 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-08.png b/resources/lsi-adm-3a/bitmap/04-08.png new file mode 100644 index 0000000000000000000000000000000000000000..e66f852b6cb89c7e55d91e70f2225e526d290bb1 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC4oLFwB=qnd tP&y&>qH9G8laIMsuz`;QJIh@LhP)-0^ls`Xr~|byc)I$ztaD0e0s!xb7&rg` literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-09.png b/resources/lsi-adm-3a/bitmap/04-09.png new file mode 100644 index 0000000000000000000000000000000000000000..fd85cd4908c175154a301966fc4859eb1a246d95 GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqhMq2tAr*1SKl~XC8aUYuSOp!D znty88=rF8fSRx#29wFl+u!(7z^lVKDwFS&gc?=B4T5f2}dGTgHP&0$4tDnm{r-UW| D#ZnvG literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-10.png b/resources/lsi-adm-3a/bitmap/04-10.png new file mode 100644 index 0000000000000000000000000000000000000000..b0d078699268e8f2537164e95abf6dee69bb28fb GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqI-V|$Ar*1SKl~XC7#KSo#M_y7 y@aVZ}aBa|J>Q?YxpxvbHa4bUf0Tatz28NVVSG8X(QvV3l$KdJe=d#Wzp$Py(QyMA& literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-11.png b/resources/lsi-adm-3a/bitmap/04-11.png new file mode 100644 index 0000000000000000000000000000000000000000..a051ef03cfeadc91463c265b352688e9ddae2076 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqTAnVBAr*1SKl~XC7H}_M-oV7h w)?p>l%VXerfgy&`?5=`?DyxF0gd019$<*hPE7-VB0Ch2Vy85}Sb4q9e0O*Mp+W-In literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-12.png b/resources/lsi-adm-3a/bitmap/04-12.png new file mode 100644 index 0000000000000000000000000000000000000000..0e0cc5730c71f72093b3d8209bb7f16ff4caa196 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq8lEnWAr*1SKl~XC4oLD8sBtlL uA5z(O`A8&VTEG$p70$yi7#QaNe* znB2g)LBmIAw$h=n29^tkZA>PNC3bBLT=ERdv(Fm}7+f|1YGm+q^>bP0l+XkKW0V;- literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-15.png b/resources/lsi-adm-3a/bitmap/04-15.png new file mode 100644 index 0000000000000000000000000000000000000000..791f6c46f8e4551591fbeb5c536a777b3dac1602 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq`kpS1Ar*1SKl~XC8aUb5EZo?6 z3>-_O*dC}QOm68~`0~ILS8-_38;&~)78&qol`;+073{E?EnA( literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-17.png b/resources/lsi-adm-3a/bitmap/04-17.png new file mode 100644 index 0000000000000000000000000000000000000000..76432a537bc65e37963ce0194c04db8bc295fd40 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqx}GkMAr*1SKl~XC7H}_MW>a7g z)R1sxoWnTvKtRJf>D5dc%&tsq9J3n^9cE%E@j7O;b44N_P$PqG us1#~C1u`6#;M(AMfT4}^MMIG}1B2=2V^()=oZtoOVeoYIb6Mw<&;$Vbn;A_2 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-19.png b/resources/lsi-adm-3a/bitmap/04-19.png new file mode 100644 index 0000000000000000000000000000000000000000..bfbeb5bbe6be3278ba8edcd5db07337c359066c2 GIT binary patch literal 93 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqDxNNmAr*1SKl~XC4oLFwB=qnd qP&y&>qH9G8lOt;ao1OLtMuwDAw^iTCeVqtY&*16m=d#Wzp$P!Kofz!^ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-20.png b/resources/lsi-adm-3a/bitmap/04-20.png new file mode 100644 index 0000000000000000000000000000000000000000..7c384bbe410cf91e072ecbc6e1ff31d6c27d8e6a GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqdY&$hAr*1SKl~XC8aUYuSOp!D znty88=rF8fSRx#29wFl+u&HSQlL7O5(H{&9dsaP^4>-Yg2dI<5)78&qol`;+0CxHs AYXATM literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-21.png b/resources/lsi-adm-3a/bitmap/04-21.png new file mode 100644 index 0000000000000000000000000000000000000000..9a5c4dc2142997954e6ae7d8cc5539c451da937e GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqTAnVBAr*1SKl~XC7#KSo#M_y7 v@aVZ}aBa|J>Q?YxpsnP`IHU1AR}BM0)Q5XY;ff~wKwS);u6{1-oD!M<>|hsJ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-22.png b/resources/lsi-adm-3a/bitmap/04-22.png new file mode 100644 index 0000000000000000000000000000000000000000..e58ca5c48f17b3aad4163b06a7df35e2b33e0272 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC8aUb5434o$ tOi{9Z7+U}U literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-23.png b/resources/lsi-adm-3a/bitmap/04-23.png new file mode 100644 index 0000000000000000000000000000000000000000..48babb524d63390dc4a642ef0470045756802bb8 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqYMw5RAr*1SKl~XC7#KSo#M_y7 r@aVZF1g3bFw0;R vvo?q}lpHj$QpjNyV=S?20}85joaSYC9C=my(v^%0Ky3`3u6{1-oD!MAr*1SKl~XC7#MdkXvw#> vvkI6ob~9MXJ2TAfS8O=d&Uwhdih*I%vKtzDzUMCjH8FU)`njxgN@xNA-)9(3 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-27.png b/resources/lsi-adm-3a/bitmap/04-27.png new file mode 100644 index 0000000000000000000000000000000000000000..b123ced51cb20e42dec144daf9dab8245a330275 GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqdY&$hAr*1SKl~XC78FPX><}=t zVAkL~e1hRjGv^}jrlSW~j&dE~smW_7-Y|oK;j`{l?T!;2{y?1!p00i_>zopr0Qn6a A$p8QV literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-28.png b/resources/lsi-adm-3a/bitmap/04-28.png new file mode 100644 index 0000000000000000000000000000000000000000..5bac38a5ef85894c217ffa567c7d915f1be9ac0a GIT binary patch literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqs-7;6Ar*1SKl~XC4oLFwB=qnd rP`aU#(7?uZLDcwwO#AhTKNuJ!{O>8*Z&qXnYGCkm^>bP0l+XkK$WRy- literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-29.png b/resources/lsi-adm-3a/bitmap/04-29.png new file mode 100644 index 0000000000000000000000000000000000000000..38a480f1d6a4c5a5ed20578c3da7760c51339018 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqTAnVBAr*1SKl~XC7#MdkSjjsx wOzqd{(Bl+MX7E->7GW)56T7S6u#=NvnaN3Wk&QbIfVvnwUHx3vIVCg!0MTR?-T(jq literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-30.png b/resources/lsi-adm-3a/bitmap/04-30.png new file mode 100644 index 0000000000000000000000000000000000000000..42e6e3296ad9de8282c3b07aa271254ef2ce8709 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq+MX_sAr*1SKl~XC7#KSml1muE x8q^xj9T#wTJ~@NcszLieDpwchi%AL$3@mGoS%trP-wM>m;OXk;vd$@?2>^uD8`S^+ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/04-31.png b/resources/lsi-adm-3a/bitmap/04-31.png new file mode 100644 index 0000000000000000000000000000000000000000..ae4f9696a9facafab74c8a7938c5d9356f9ba35f GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqTAnVBAr*1SKl~XC78FQG9FTD3 wIp;9Bf$@>Zfu3W_IxK__@WgNxNb)i>+^oN+bc1EDJWv;dr>mdKI;Vst0CK$=?EnA( literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-00.png b/resources/lsi-adm-3a/bitmap/05-00.png new file mode 100644 index 0000000000000000000000000000000000000000..d2429890efcd251de81cddc1d7c310685516b089 GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqI-V|$Ar*1SKl~XC78FQG9FTD3 yIp;9BfpLR|kGh$wMA!o6M?MXn4?-JGi!g{woHsntcpUXO@geCx)bQ}`^ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-01.png b/resources/lsi-adm-3a/bitmap/05-01.png new file mode 100644 index 0000000000000000000000000000000000000000..704982d778a76bc05c27ac178d142ed2f13836a2 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqYMw5RAr*1SKl~XC78FQG9FTD3 rIp;9Bf$_~EkA@0ijbMgiTQgUNM7t+4bv)b!KphO8u6{1-oD!M<+gca6 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-02.png b/resources/lsi-adm-3a/bitmap/05-02.png new file mode 100644 index 0000000000000000000000000000000000000000..699646e88d9d34502f331be2285c815033453b1d GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqTAnVBAr*1SKl~XC78FQG9FTD3 wIp;9Bfl-9@hDf991l0?ofu4*r8V~a_sH)x2XnQUg4AjNo>FVdQ&MBb@06_d1mH+?% literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-03.png b/resources/lsi-adm-3a/bitmap/05-03.png new file mode 100644 index 0000000000000000000000000000000000000000..8005dae0ba488f00512dd03c95193cf173a04a50 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq8lEnWAr*1SKl~XC78FQG9FTD3 uIp;9BfpLSzCY4=IRhkUO3+x=i85n-JT-D~uULXk6!{F)a=d#Wzp$PyLZW!nQ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-04.png b/resources/lsi-adm-3a/bitmap/05-04.png new file mode 100644 index 0000000000000000000000000000000000000000..5c7ebc7ccb13bd839088f33f8c05139b7fcb1edf GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqYMw5RAr*1SKl~XC7#Md+a50>2 s5;FVdQ&MBb@0Mm3B-T(jq literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-05.png b/resources/lsi-adm-3a/bitmap/05-05.png new file mode 100644 index 0000000000000000000000000000000000000000..e65950feffde85b569d650b380e3099352f58269 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqx}GkMAr*1SKl~XC7#Md+a50>2 z5;bP0l+XkKO#&G{ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-06.png b/resources/lsi-adm-3a/bitmap/05-06.png new file mode 100644 index 0000000000000000000000000000000000000000..6bb7416c64a7e1fb3c77c619bac74720be0bef4e GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC8aUb5EZo>N slq^IAOc>P~!x{C04Yn>|Y*J%j@LO@lMENBP6Hp6-r>mdKI;Vst0A^?uuK)l5 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-07.png b/resources/lsi-adm-3a/bitmap/05-07.png new file mode 100644 index 0000000000000000000000000000000000000000..c90c4a08114e113c6bef42f3e87c085145849cf1 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC4oLFwB=qnd tP&y&>qHDzxhBF7Av(+%Ar*1SKl~XC4oLD8sBs<8 v>tg9JXI#$|GfCkgTe~DWM4fFLfF@ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-09.png b/resources/lsi-adm-3a/bitmap/05-09.png new file mode 100644 index 0000000000000000000000000000000000000000..2c84841b28a7662a83ab4ec0dbb0d3dde64e6fc7 GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqik>cxAr*1SKl~XC7H}_MKE&0) n;IbfrhxG?T-Oc}30vH%RuYN21IPSS1P%(q2tDnm{r-UW|mYf+i literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-10.png b/resources/lsi-adm-3a/bitmap/05-10.png new file mode 100644 index 0000000000000000000000000000000000000000..9042405a544910f0d27a0d569abe50704719ab78 GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq%APKcAr*1SKl~XC7H}_MKE&0) p;Ibe=gjK_40)ry!i-sar2Ia1|!XG}IwE-$;@O1TaS?83{1OS7S7li-- literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-11.png b/resources/lsi-adm-3a/bitmap/05-11.png new file mode 100644 index 0000000000000000000000000000000000000000..a73bea525be92183ce2b8806c3fb71c0d0f9286c GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq8lEnWAr*1SKl~XC7#Md+a2*I} uXzdqpn9kCDP}0G34%dg7PP;^3bTPd5y{f&lqtF4Uhr!d;&t;ucLK6Tx6&pSP literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-12.png b/resources/lsi-adm-3a/bitmap/05-12.png new file mode 100644 index 0000000000000000000000000000000000000000..1ca78f5be7df1f58e0fc4a4b9dc9d561d01b98b5 GIT binary patch literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq#-1*YAr*1SKl~XC7#Md+a2*I} zXzdqpn9kCDP%=WrkwJ%RQj4ZTct;{@8tg9JPh=2fVA#j~R(QXJ_+Fqo22WQ%mvv4FO#sY-6QTeB literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-14.png b/resources/lsi-adm-3a/bitmap/05-14.png new file mode 100644 index 0000000000000000000000000000000000000000..a209764280fe973fe89e16c1b2bec8656749e59a GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqTAnVBAr*1SKl~XC7H}_M-oV7h w)?$@nHlts!VYgr+Ar*1SKl~XC7H}_MW>au@ trr>$-D2E1vaD|AVS>pnx62=k+2BqMK@@dr;Yk^uAJYD@<);T3K0RXYgr+Ar*1SKl~XC8aUYuSOp!D tntv9s&0^s(cyO6lj9IusYgr+Ar*1SKl~XC7#KSo#2hBI tX*oPf&}uN=;L&vSAPb+Tz=CFJ2KA*U&G&3hI04kc;OXk;vd$@?2>}0q8P5O! literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-19.png b/resources/lsi-adm-3a/bitmap/05-19.png new file mode 100644 index 0000000000000000000000000000000000000000..628992f9724614c249c453f49b893ae4724e0614 GIT binary patch literal 79 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqVxBIJAr*1SKl~XC8aUb5434q2 bwKFl;KfJ0vt$g1Upb7?0S3j3^P6GAr*1SKl~XC8aUb5434qA mSjeE(8O%82!19I(oD2t@&l^sEyixbP0l+XkKy7+6j|`Wf$0U;h0?{^3=G*h_ms4bN;?77GkCiCxvX7+6j|`Wf$0U;h0;aZ3=B(*AIh&6f29Ld&*16m=d#Wzp$Pz{cNg;j literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-28.png b/resources/lsi-adm-3a/bitmap/05-28.png new file mode 100644 index 0000000000000000000000000000000000000000..2ee1097324dcd928b573a921f35eec820c9f20bb GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqYMw5RAr*1SKl~XC8aUb54B9rn sT+5)=8O+GVuhOuN;U-JUFVdQ&MBb@0Lv2?bpQYW literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/05-29.png b/resources/lsi-adm-3a/bitmap/05-29.png new file mode 100644 index 0000000000000000000000000000000000000000..72c53769bf7ec411c041b065eb91c007d811106f GIT binary patch literal 84 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq(w;7kAr*1SKl~XC8aUb54B9rf h&tsaQV&ulg5NW;3ZO#4p&wGAr*1SKl~XC8aUb5434qA mSjeE(8O%82!19I(oD2t@&l^sEyixbP0l+XkKy-cYzjU@=e)gQu&X%Q~loCIEZ55`F*x literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-01.png b/resources/lsi-adm-3a/bitmap/06-01.png new file mode 100644 index 0000000000000000000000000000000000000000..00f7d787fd26a8032e42e73c3e0c923d2406506e GIT binary patch literal 84 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq(w;7kAr*1SKl~XC8aUb5434q2 gwK2_5F>+&LsGWMobP0l+XkKy-cYzjU@=e)gQu&X%Q~loCIEZ55`F*x literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-04.png b/resources/lsi-adm-3a/bitmap/06-04.png new file mode 100644 index 0000000000000000000000000000000000000000..1a5421b460605f4e9608e563b2863a11987fca6a GIT binary patch literal 82 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqlAbP(Ar*1SKl~XC7H}_UUbv8f f!-0j%jg3L){|AA;FBV<^Dq`?-^>bP0l+XkKy+&LsGWMo69-6!z-SX<{Xu#Gl9w&JYD@<);T3K0RYd26jlHL literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-07.png b/resources/lsi-adm-3a/bitmap/06-07.png new file mode 100644 index 0000000000000000000000000000000000000000..a7955b9c71ad42f39ac9643c2a93025dc7c7a195 GIT binary patch literal 81 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq5}q!OAr*1SKl~XC8aUb54B9rf ew=<=GAr*1SKl~XC7H}_MuF_0M mNN_l4A)3G}!F55Di6Ol2iOkZ~2gQJD89ZJ6T-G@yGywoM>lM=g literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-10.png b/resources/lsi-adm-3a/bitmap/06-10.png new file mode 100644 index 0000000000000000000000000000000000000000..58868189967713d6755b145d7ef8b38fa34965a4 GIT binary patch literal 93 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqDxNNmAr*1SKl~XC8aUb54B9rn pT+5)=8O+GV&+TBycvD4!fkCnHfJ4}0hEG8C44$rjF6*2UngDWC77YLZ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-11.png b/resources/lsi-adm-3a/bitmap/06-11.png new file mode 100644 index 0000000000000000000000000000000000000000..d915284470991ee45e53f19c9455fb1bd5a82e4c GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq%APKcAr*1SKl~XC7H}_MuF_y& p5@>7+6j|_L1A~b00wxVE2IEanWd81XIti$p!PC{xWt~$(699t37r6ic literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-12.png b/resources/lsi-adm-3a/bitmap/06-12.png new file mode 100644 index 0000000000000000000000000000000000000000..e6caa9ceffa33fa05de230b1473aeef7da6838db GIT binary patch literal 85 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqGM+AuAr*1SKl~XC8aUb54B9rb h?`0}!SjZ5o$WW(p*fzJj>IhIBgQu&X%Q~loCIH(36r}(F literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-13.png b/resources/lsi-adm-3a/bitmap/06-13.png new file mode 100644 index 0000000000000000000000000000000000000000..961bff0b8889cfa52a20f3a7dd579c8d711c3ebc GIT binary patch literal 89 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq3Z5>GAr*1SKl~XC7H}_MuF_y& m5@>7+6j|_L14EM<1H-R759NJ#1pNl8W$<+Mb6Mw<&;$Td02g)u literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-14.png b/resources/lsi-adm-3a/bitmap/06-14.png new file mode 100644 index 0000000000000000000000000000000000000000..fd1f565af13985758a2c47d67d1019911e657577 GIT binary patch literal 89 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq3Z5>GAr*1SKl~XC8aUb54B9rn lT+5)=8O+GV&#jQb#1Q3i*f#mKPXtgcgQu&X%Q~loCIB786w?3z literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-15.png b/resources/lsi-adm-3a/bitmap/06-15.png new file mode 100644 index 0000000000000000000000000000000000000000..eb334903e615c467a7aba06beb37f07f669f5d39 GIT binary patch literal 91 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqN}eu`Ar*1SKl~XC8aUb5434qA oSjeE(*%K(T;KK%nCN&0zV+JS9Bc3@a0#!43y85}Sb4q9e0C{&8Hvj+t literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-16.png b/resources/lsi-adm-3a/bitmap/06-16.png new file mode 100644 index 0000000000000000000000000000000000000000..72c53769bf7ec411c041b065eb91c007d811106f GIT binary patch literal 84 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq(w;7kAr*1SKl~XC8aUb54B9rf h&tsaQV&ulg5NW;3ZO#4p&wGAr*1SKl~XC7H}_MuF_y& m5@>7+6j|_L14EM<1H-R759NJ#1pNl8W$<+Mb6Mw<&;$Td02g)u literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-18.png b/resources/lsi-adm-3a/bitmap/06-18.png new file mode 100644 index 0000000000000000000000000000000000000000..1a5421b460605f4e9608e563b2863a11987fca6a GIT binary patch literal 82 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqlAbP(Ar*1SKl~XC7H}_UUbv8f f!-0j%jg3L){|AA;FBV<^Dq`?-^>bP0l+XkKy69-6!z-SX<{Xu#Gl9w&JYD@<);T3K0RYd26jlHL literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-21.png b/resources/lsi-adm-3a/bitmap/06-21.png new file mode 100644 index 0000000000000000000000000000000000000000..5260cfa53f5eebee9da4c1b1a33d22a4ab443185 GIT binary patch literal 82 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqlAbP(Ar*1SKl~XC7H}_UZVWhZ fph3%JClkXp_itQAH;xbP0l+XkK<=z%; literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-22.png b/resources/lsi-adm-3a/bitmap/06-22.png new file mode 100644 index 0000000000000000000000000000000000000000..89c3688e57ddd181a59c258ec766eb1879c9ae82 GIT binary patch literal 80 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq;+`&!Ar*1SKl~XC7H}_UUbwQM dkuj8mA^g!F7PosPM}SHgJYD@<);T3K0RXCO6#oDK literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-23.png b/resources/lsi-adm-3a/bitmap/06-23.png new file mode 100644 index 0000000000000000000000000000000000000000..72c53769bf7ec411c041b065eb91c007d811106f GIT binary patch literal 84 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq(w;7kAr*1SKl~XC8aUb54B9rf h&tsaQV&ulg5NW;3ZO#4p&w!Hug4b^03=AjcUDB)B{p~4GJ%gvKpUXO@geCyLei^a= literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-25.png b/resources/lsi-adm-3a/bitmap/06-25.png new file mode 100644 index 0000000000000000000000000000000000000000..5ecb45e1c87e80536f1cc5fd6f3b013274db3082 GIT binary patch literal 82 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqlAbP(Ar*1SKl~XC5;zPNaPji8 eDlnGx@Gx*Jy{DwK+pGzwh{4m<&t;ucLK6UTBoV~` literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-26.png b/resources/lsi-adm-3a/bitmap/06-26.png new file mode 100644 index 0000000000000000000000000000000000000000..89c3688e57ddd181a59c258ec766eb1879c9ae82 GIT binary patch literal 80 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq;+`&!Ar*1SKl~XC7H}_UUbwQM dkuj8mA^g!F7PosPM}SHgJYD@<);T3K0RXCO6#oDK literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-27.png b/resources/lsi-adm-3a/bitmap/06-27.png new file mode 100644 index 0000000000000000000000000000000000000000..ff9aa52f88d9ce139f30814a9de59ad9a96df433 GIT binary patch literal 77 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqBAzaeAr*1SKl~XC7#KSo4j%Sr aWLSA|TGq|WJMRJI89ZJ6T-G@yGywo+H55t! literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-28.png b/resources/lsi-adm-3a/bitmap/06-28.png new file mode 100644 index 0000000000000000000000000000000000000000..1a5421b460605f4e9608e563b2863a11987fca6a GIT binary patch literal 82 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqlAbP(Ar*1SKl~XC7H}_UUbv8f f!-0j%jg3L){|AA;FBV<^Dq`?-^>bP0l+XkKyKRe(swgTe~DWM4fSke); literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/06-31.png b/resources/lsi-adm-3a/bitmap/06-31.png new file mode 100644 index 0000000000000000000000000000000000000000..a447d92f6b86fc6ca7debb9f459b366d78397aa3 GIT binary patch literal 83 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqQl2i3Ar*1SKl~XC7#KSo4t@!1 fICPjvBbUn|xSQ!8?h$MYMslCTzin4Gc|O43P{E<&QYtEdgp{@O1TaS?83{1OPId8EgOm literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-01.png b/resources/lsi-adm-3a/bitmap/07-01.png new file mode 100644 index 0000000000000000000000000000000000000000..4234402cf12f8cb9ce0f203c0a84dd2c43821e22 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq+MX_sAr*1SKl~XC7#KSkl5-f= xFmyJnu!=99#u>mj%VZMg4HZX*qg*)*42L<-8)|>PR0Pz<;OXk;vd$@?2>>7m83q6V literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-02.png b/resources/lsi-adm-3a/bitmap/07-02.png new file mode 100644 index 0000000000000000000000000000000000000000..9172f99bdb51563d893673350787f2782e43781c GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqik>cxAr*1SKl~XC7#KSo4oYxc mV7c&9g6Ty~2xEx@J1fIY#v2-MpRs{-GkCiCxvXYgr+Ar*1SKl~XC7H}_MKE&0) t;Ibe=gf$@4;Ht)?1VaPIjZ8HR3^v;LlpaPE%?D~>@O1TaS?83{1OVZ`7(xI5 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-04.png b/resources/lsi-adm-3a/bitmap/07-04.png new file mode 100644 index 0000000000000000000000000000000000000000..193dd63cd2e2771945ec464a424f69af94f2fa4a GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq8lEnWAr*1SKl~XC7#KSo4oYxc uU^^u B8Q}l` literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-06.png b/resources/lsi-adm-3a/bitmap/07-06.png new file mode 100644 index 0000000000000000000000000000000000000000..76574b18387815992dda2d1ba79f8eec754c57d4 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqTAnVBAr*1SKl~XC7H}_MKE&0) w5X&&PU$NnwJ4eF}39bvO8?+n*9fBDc9mdKI;Vst08{H4WdHyG literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-07.png b/resources/lsi-adm-3a/bitmap/07-07.png new file mode 100644 index 0000000000000000000000000000000000000000..46c5246c8ec9ef68f2bd64148bf11a3974508733 GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq%APKcAr*1SKl~XC7H}_MKE&0) p;Ibe=gtdTe77I^6Afp}wLzMY*$+sM*1%S#KJYD@<);T3K0RUOO6-NL7 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-08.png b/resources/lsi-adm-3a/bitmap/07-08.png new file mode 100644 index 0000000000000000000000000000000000000000..1880f6ede550caea1de940c977b8a53aebe86a78 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq+MX_sAr*1SKl~XC8aUb5EZo=& w1al@SINV?p0EJAoJq9p-KCm2S9BMp00i_>zopr01OKlr~m)} literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-09.png b/resources/lsi-adm-3a/bitmap/07-09.png new file mode 100644 index 0000000000000000000000000000000000000000..a3b24c2e075e549cdf1ac6815684b288eeb361ff GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqI-V|$Ar*1SKl~XC7H}_M-oV7h y#%AHh&hw%v;)ev&i<*{?H`XYgV=-YAv17>Da^7%#s>FVvJ_b)$KbLh*2~7ZoQ5#_Z literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-10.png b/resources/lsi-adm-3a/bitmap/07-10.png new file mode 100644 index 0000000000000000000000000000000000000000..90efaa4e3f0de7738417ad76a1ba5dd7fc555766 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq2A(dCAr*1SKl~XC7H}_M-oV7h z#%AHh&hw%v;)ev&iy9ur5W7tZyHrAW9$Mt^u`)1vUDAtQvULqmFN3G6pUXO@geCyE C3>w)0 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-11.png b/resources/lsi-adm-3a/bitmap/07-11.png new file mode 100644 index 0000000000000000000000000000000000000000..5c04569598a811bc35bb2ea891a0b62c13583066 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqx}GkMAr*1SKl~XC8aUb5434o$ z6nGwB=;FK~l02iKwO_H}+;IVir-xYzcQP{cPQIjfJZYW>P$Pql%Oi0?^`fX?ScAWiPMcl>ABPqLLnOmP`KRmW@B_6mc)I$ztaD0e0st1q7x@4H literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-13.png b/resources/lsi-adm-3a/bitmap/07-13.png new file mode 100644 index 0000000000000000000000000000000000000000..bb4c54eabeb22208243e1d37f88d05f373a520bc GIT binary patch literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqMxHK?Ar*1SKl~XC7H}_M-oV7h z#%9pAF;GN-dx5vpQ30z$tplkx5j;K*F7PsGmdKI;Vst E0POA?SO5S3 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-14.png b/resources/lsi-adm-3a/bitmap/07-14.png new file mode 100644 index 0000000000000000000000000000000000000000..3c752ed8dfa1b84870a74c91d92349da76f397b6 GIT binary patch literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqs-7;6Ar*1SKl~XC8aUb5EZo?6 rZm>*bEaWPXgW3oAp-rW+c|rrl8iYGCkm^>bP0l+XkKge?~d literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-15.png b/resources/lsi-adm-3a/bitmap/07-15.png new file mode 100644 index 0000000000000000000000000000000000000000..b72ee0c5052a9af909d4bc5c551dfbc26c8c44e9 GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqI-V|$Ar*1SKl~XC8aUb5EZo?6 yUNlAgkYIXI!^2o&*T!Ha@60f_U$Nm3JHx;4m-Kq$V?}}b7(8A5T-G@yGywowE*dZZ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-16.png b/resources/lsi-adm-3a/bitmap/07-16.png new file mode 100644 index 0000000000000000000000000000000000000000..3d5adc002142acc0f40b2ac51f49eefc9fcf28f5 GIT binary patch literal 88 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq@}4e^Ar*1SKl~XC7H}_MW>a7g k)R1sxPYgr+Ar*1SKl~XC4oLD8sBtN* tVNhx83lupZxx=Tym_zdbE5|NIhR2atwKEi@6o6V7JYD@<);T3K0RYQ@7c>9> literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-18.png b/resources/lsi-adm-3a/bitmap/07-18.png new file mode 100644 index 0000000000000000000000000000000000000000..fc4ad8838592f8a9b464bb9f50dea57e0b3b3c15 GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqI-V|$Ar*1SKl~XC7#Md+a50>I y6wEUH;8G4(k=aT-f+emJTo)K`h`*4KWMEL}eJCH*dG;MpAA_f>pUXO@geCx61sWg# literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-19.png b/resources/lsi-adm-3a/bitmap/07-19.png new file mode 100644 index 0000000000000000000000000000000000000000..f007bcd953363d1236b8186384b4362c2135aa7b GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq`kpS1Ar*1SKl~XC5;zPNa4r0B zLG@r#0h^eo07LhqNi2+PHIoz?;=kEnVJYe1VNmFOD6d+?Xb05F;OXk;vd$@?2>|Cw B8;$?~ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-20.png b/resources/lsi-adm-3a/bitmap/07-20.png new file mode 100644 index 0000000000000000000000000000000000000000..5bb4f2d4f3fef5482d402ee00bbd23fd37ca6981 GIT binary patch literal 88 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq@}4e^Ar*1SKl~XC78FPX><}=t lVAkqf*HOayqJfW#;n=z-GE?W=ummb)@O1TaS?83{1OP~n7e4?1 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-21.png b/resources/lsi-adm-3a/bitmap/07-21.png new file mode 100644 index 0000000000000000000000000000000000000000..a3bc2bf7981fb99fb70fde3a49624546599a28d1 GIT binary patch literal 88 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq@}4e^Ar*1SKl~XC4oLD8sBtZ5 lXPUwClj{HrpQiu=!@N&VWd0=1_5mto@O1TaS?83{1OP5x7DoU8 literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-22.png b/resources/lsi-adm-3a/bitmap/07-22.png new file mode 100644 index 0000000000000000000000000000000000000000..2f9981ff8dc4d8d8d114d71baaee9be7b8c2e031 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC7H}_M-oeDi t_9km%w-O`U1izA=MGUR&tO4)X7{;OXk;vd$@?2>}1B88!d_ literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-23.png b/resources/lsi-adm-3a/bitmap/07-23.png new file mode 100644 index 0000000000000000000000000000000000000000..3567655e4d7f6591d5c0fbac6944757837f89fd4 GIT binary patch literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqs-7;6Ar*1SKl~XC5;zPNa5Yvc rI7+y&^W0#W$k?W{i%lw`k&hvg;i3GAw;R_0H86O(`njxgN@xNAl literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-24.png b/resources/lsi-adm-3a/bitmap/07-24.png new file mode 100644 index 0000000000000000000000000000000000000000..22d98064b26f169fe67d34e6fcee1b660756d45e GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqik>cxAr*1SKl~XC8aUb5434o$ mOiYgr+Ar*1SKl~XC4oLFw6!h=} sh$Jw#h#pWm5ze4i;L*g8C#k`}AZhea-uJc*kj22@>FVdQ&MBb@0Ium4MF0Q* literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-28.png b/resources/lsi-adm-3a/bitmap/07-28.png new file mode 100644 index 0000000000000000000000000000000000000000..57d8068a476a770d92d5a8e886c32130fee68877 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq>Ygr+Ar*1SKl~XC7H}_MKE&0) t;L>1d#t_zU#Bownci<|9SO!@JhDraP$V{8gEf3Vf;OXk;vd$@?2>|m87@hzC literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-29.png b/resources/lsi-adm-3a/bitmap/07-29.png new file mode 100644 index 0000000000000000000000000000000000000000..bb22fb4d292a00854a3911edd95a22933c866bad GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqYMw5RAr*1SKl~XC7#KSo#M_xS s@WipQ_#RN_WNPts5O-i_5oKVgdh=ZJ?fSQifjSsGUHx3vIVCg!0Ek8w=l}o! literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-30.png b/resources/lsi-adm-3a/bitmap/07-30.png new file mode 100644 index 0000000000000000000000000000000000000000..77d6bc62db2cce74c76c70d97c2eb364cab8ea50 GIT binary patch literal 86 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqvYsxEAr*1SKl~XC7H}_Mek5vO jU~s_DXu)!(7zPF(&D*L`pC&N@6*73b`njxgN@xNA{EHOp literal 0 HcmV?d00001 diff --git a/resources/lsi-adm-3a/bitmap/07-31.png b/resources/lsi-adm-3a/bitmap/07-31.png new file mode 100644 index 0000000000000000000000000000000000000000..eb99c7eda738143626754ddddaa37ed65c39e11c GIT binary patch literal 76 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq!k#XUAr*1SKl~XC7H}_Uez=f< Yp=IlT#!4@X4M1rIPgg&ebxsLQ08 Date: Tue, 15 Nov 2022 10:25:58 +0100 Subject: [PATCH 215/314] Open computer by index --- .../emustudio/application/cmdline/Runner.java | 17 +++++++++++++++-- .../application/settings/ConfigFiles.java | 8 ++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/net/emustudio/application/cmdline/Runner.java b/application/src/main/java/net/emustudio/application/cmdline/Runner.java index f7e9e0b66..fe529c888 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/Runner.java +++ b/application/src/main/java/net/emustudio/application/cmdline/Runner.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.nio.file.Path; import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; import static net.emustudio.application.cmdline.Utils.*; import static net.emustudio.application.settings.ConfigFiles.listConfigurationNames; @@ -84,7 +85,9 @@ public static void main(String[] args) { public void run() { if (listConfigs) { try { - listConfigurationNames().forEach(System.out::println); + AtomicInteger index = new AtomicInteger(); + System.out.println("Index\tComputer name"); + listConfigurationNames().forEach(name -> System.out.println(index.getAndIncrement() + "\t" + name)); } catch (IOException e) { LOGGER.error("Could not list configuration names", e); System.exit(1); @@ -140,6 +143,13 @@ public static class Exclusive { ) public Path configFile; + @CommandLine.Option( + names = {"-cn", "--computer-index"}, + description = "virtual computer index (see -l for options)", + paramLabel = "INDEX" + ) + public Integer configIndex; + public Optional loadConfiguration() throws IOException { if (configName != null) { Optional optConfig = ConfigFiles.loadConfiguration(configName); @@ -150,7 +160,10 @@ public Optional loadConfiguration() throws IOException { System.exit(1); } if (configFile != null) { - return Optional.of(ConfigFiles.loadConfiguration(configFile)); + return ConfigFiles.loadConfiguration(configFile); + } + if (configIndex != null) { + return ConfigFiles.loadConfiguration(configIndex); } return Optional.empty(); } diff --git a/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java b/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java index 1de55fc3b..9ef1bff68 100644 --- a/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java +++ b/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java @@ -48,8 +48,12 @@ public static Optional loadConfiguration(String computerName) th return loadConfigurations().stream().filter(config -> config.getName().equals(computerName)).findAny(); } - public static ComputerConfig loadConfiguration(Path computerPath) { - return ComputerConfig.load(computerPath); + public static Optional loadConfiguration(int computerIndex) throws IOException { + return Optional.ofNullable(loadConfigurations().get(computerIndex)); + } + + public static Optional loadConfiguration(Path computerPath) { + return Optional.of(ComputerConfig.load(computerPath)); } public static List listConfigurationNames() throws IOException { From 3c2c51cae787b1aa8d882fdcc8461358eab2ffcd Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 15 Nov 2022 13:00:22 +0100 Subject: [PATCH 216/314] [#284] Introduce font change in adm-3a --- .../src/main/files/config/MITSAltair8800.toml | 1 + .../main/files/config/MITSAltair8800Z80.toml | 2 + .../plugins/device/adm3a/DeviceImpl.java | 4 +- .../device/adm3a/TerminalSettings.java | 27 +- .../emustudio/plugins/device/adm3a/Utils.java | 27 ++ .../device/adm3a/gui/ConfigDialog.java | 241 +++++++++--------- .../device/adm3a/gui/DisplayCanvas.java | 47 +--- .../plugins/device/adm3a/gui/DisplayFont.java | 41 +++ .../adm3a/gui/DisplayFontJComboRenderer.java | 38 +++ .../device/adm3a/gui/TerminalWindow.java | 8 +- .../plugins/device/adm3a/gui/terminal.ttf | Bin 0 -> 309064 bytes 11 files changed, 275 insertions(+), 161 deletions(-) create mode 100644 plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java create mode 100644 plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java create mode 100644 plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/terminal.ttf diff --git a/application/src/main/files/config/MITSAltair8800.toml b/application/src/main/files/config/MITSAltair8800.toml index 4c2a784ab..53a2c0c03 100644 --- a/application/src/main/files/config/MITSAltair8800.toml +++ b/application/src/main/files/config/MITSAltair8800.toml @@ -127,6 +127,7 @@ name = "MITS Altair8800" alwaysOnTop = true inputReadDelay = 0 halfDuplex = false + font = "original" [[connections]] bidirectional = true diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index 0087b5b05..633222b6c 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -123,6 +123,8 @@ name = "MITS Altair8800 (Z80)" halfDuplex = false outputFileName = "adm3A-terminal.out" inputFileName = "adm3A-terminal.in" + font = "original" + [[DEVICE]] schemaPoint = "220,60" diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index 469694448..9389fea58 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -39,6 +39,8 @@ import java.util.Optional; import java.util.ResourceBundle; +import static net.emustudio.plugins.device.adm3a.gui.DisplayFont.fromTerminalFont; + @PluginRoot( type = PLUGIN_TYPE.DEVICE, title = "LSI ADM-3A terminal" @@ -109,7 +111,7 @@ public void showGUI(JFrame parent) { if (guiIOset) { terminalGUI.setVisible(true); } else if (terminalSettings.isGuiSupported()) { - terminalGUI = new TerminalWindow(parent, display); + terminalGUI = new TerminalWindow(parent, display, fromTerminalFont(terminalSettings.getFont())); terminalGUI.setAlwaysOnTop(terminalSettings.isAlwaysOnTop()); GuiUtils.addListenerRecursively(terminalGUI, (KeyboardGui) keyboard); terminalGUI.startPainting(); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java index 9bb9b8e61..89e62cfcd 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java @@ -33,8 +33,8 @@ public class TerminalSettings { private final static Logger LOGGER = LoggerFactory.getLogger(TerminalSettings.class); - private final static String DEFAULT_INPUT_FILE_NAME = "adm3A-terminal.in"; - private final static String DEFAULT_OUTPUT_FILE_NAME = "adm3A-terminal.out"; + public final static String DEFAULT_INPUT_FILE_NAME = "adm3A-terminal.in"; + public final static String DEFAULT_OUTPUT_FILE_NAME = "adm3A-terminal.out"; private final static String ANTI_ALIASING = "antiAliasing"; private final static String HALF_DUPLEX = "halfDuplex"; private final static String ALWAYS_ON_TOP = "alwaysOnTop"; @@ -42,6 +42,18 @@ public class TerminalSettings { private final static String OUTPUT_FILE_NAME = "outputFileName"; private final static String INPUT_READ_DELAY = "inputReadDelay"; private final static String DEVICE_INDEX = "deviceIndex"; + private final static String FONT = "font"; + + public enum TerminalFont { + ORIGINAL("original"), + MODERN("modern"); + + public final String name; + + TerminalFont(String name) { + this.name = Objects.requireNonNull(name); + } + } private final Dialogs dialogs; private final PluginSettings settings; @@ -54,6 +66,7 @@ public class TerminalSettings { private volatile Path outputPath = Path.of(DEFAULT_OUTPUT_FILE_NAME); private int inputReadDelay = 0; private int deviceIndex = 0; + private TerminalFont font = TerminalFont.ORIGINAL; private final List observers = new ArrayList<>(); @@ -143,6 +156,14 @@ public void setDeviceIndex(int deviceIndex) { this.deviceIndex = deviceIndex; } + public TerminalFont getFont() { + return font; + } + + public void setFont(TerminalFont font) { + this.font = Objects.requireNonNull(font); + } + public void write() { try { settings.setInt(INPUT_READ_DELAY, inputReadDelay); @@ -152,6 +173,7 @@ public void write() { settings.setString(OUTPUT_FILE_NAME, outputPath.toString()); settings.setString(INPUT_FILE_NAME, inputPath.toString()); settings.setInt(DEVICE_INDEX, deviceIndex); + settings.setString(FONT, font.name); } catch (CannotUpdateSettingException e) { LOGGER.error("Could not update settings", e); dialogs.showError("Could not save settings. Please see log file for details.", "ADM 3A"); @@ -175,6 +197,7 @@ private void readSettings() { "Could not read '" + INPUT_READ_DELAY + "' setting. Using default value ({})", inputReadDelay, e ); } + font = TerminalFont.valueOf(settings.getString(FONT, TerminalFont.ORIGINAL.name).toUpperCase()); notifyObserversAndIgnoreError(); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/Utils.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/Utils.java index 37fa98a62..dc9288c1f 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/Utils.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/Utils.java @@ -18,11 +18,21 @@ */ package net.emustudio.plugins.device.adm3a; +import net.emustudio.plugins.device.adm3a.gui.DisplayFont; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.awt.*; import java.awt.font.FontRenderContext; +import java.awt.font.TextAttribute; import java.awt.geom.AffineTransform; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; public class Utils { + private final static Logger LOGGER = LoggerFactory.getLogger(Utils.class); private static FontRenderContext DEFAULT_FRC; public static FontRenderContext getDefaultFrc() { @@ -41,4 +51,21 @@ public static FontRenderContext getDefaultFrc() { } return DEFAULT_FRC; } + + public static Font loadFont(DisplayFont displayFont) { + Map attrs = new HashMap<>(); + attrs.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); + + try (InputStream fin = Utils.class.getResourceAsStream(displayFont.path)) { + Font font = Font + .createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(fin)) + .deriveFont(Font.PLAIN, displayFont.fontSize) + .deriveFont(attrs); + GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font); + return font; + } catch (Exception e) { + LOGGER.error("Could not load custom font, using default monospaced font", e); + return new Font(Font.MONOSPACED, Font.PLAIN, 12); + } + } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java index 56defa347..2960d257b 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java @@ -28,6 +28,9 @@ import java.nio.file.Path; import java.util.Objects; +import static net.emustudio.plugins.device.adm3a.TerminalSettings.DEFAULT_INPUT_FILE_NAME; +import static net.emustudio.plugins.device.adm3a.TerminalSettings.DEFAULT_OUTPUT_FILE_NAME; + public class ConfigDialog extends JDialog { private final TerminalSettings settings; private final TerminalWindow window; @@ -37,12 +40,11 @@ public ConfigDialog(JFrame parent, TerminalSettings settings, TerminalWindow win super(parent, true); this.dialogs = Objects.requireNonNull(dialogs); + this.settings = Objects.requireNonNull(settings); + this.window = window; initComponents(); - this.settings = settings; - this.window = window; - readSettings(); setLocationRelativeTo(parent); } @@ -63,134 +65,130 @@ private void updateSettings(boolean save) throws IOException { settings.setInputPath(Path.of(txtInputFileName.getText())); settings.setOutputPath(Path.of(txtOutputFileName.getText())); settings.setInputReadDelay((Integer) spnInputDelay.getValue()); + settings.setFont(TerminalSettings.TerminalFont.valueOf(cmbFont.getSelectedItem().toString().toUpperCase())); if (save) { settings.write(); } } private void initComponents() { - JPanel panelSimulation = new JPanel(); - JLabel jLabel1 = new JLabel(); - txtInputFileName = new JTextField(); - JButton btnInputBrowse = new JButton(); - JLabel jLabel2 = new JLabel(); - txtOutputFileName = new JTextField(); - JButton btnOutputBrowse = new JButton(); - JLabel jLabel3 = new JLabel(); - JLabel jLabel4 = new JLabel(); - spnInputDelay = new JSpinner(); - JLabel jLabel5 = new JLabel(); - JPanel jPanel1 = new JPanel(); - chkHalfDuplex = new JCheckBox(); - chkAlwaysOnTop = new JCheckBox(); - chkAntiAliasing = new JCheckBox(); - JPanel jPanel2 = new JPanel(); - chkSaveSettings = new JCheckBox(); - JButton btnClearScreen = new JButton(); - JButton btnRollLine = new JButton(); - JButton btnOK = new JButton(); + JPanel panelRedirectIO = new JPanel(); + JLabel lblInputFileName = new JLabel("Input file name:"); + JButton btnInputBrowse = new JButton("Browse..."); + JLabel lblOutputFileName = new JLabel("Output file name:"); + JButton btnOutputBrowse = new JButton("Browse..."); + JLabel lblNote = new JLabel("Note: I/O redirection will be used only if No GUI mode is enabled."); + JLabel lblInputDelay = new JLabel("Input delay:"); + JLabel lblMs = new JLabel("ms"); + JPanel panelTerminal = new JPanel(); + JPanel panelControl = new JPanel(); + JButton btnClearScreen = new JButton("Clear screen"); + JButton btnRollLine = new JButton("Roll line"); + JButton btnOK = new JButton("OK"); + JLabel lblFont = new JLabel("Font"); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); setTitle("Configuration of the terminal"); - panelSimulation.setBorder(BorderFactory.createTitledBorder( + panelRedirectIO.setBorder(BorderFactory.createTitledBorder( null, "Redirect I/O", 0, 0, - jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | Font.BOLD) + lblInputFileName.getFont().deriveFont(lblInputFileName.getFont().getStyle() | Font.BOLD) )); - jLabel1.setText("Input file name:"); - txtInputFileName.setText("terminal-ADM3A.in"); - btnInputBrowse.setText("Browse..."); - - jLabel2.setText("Output file name:"); - txtOutputFileName.setText("terminal-ADM3A.out"); - btnOutputBrowse.setText("Browse..."); - - jLabel3.setText("Note: I/O redirection will be used only if No GUI mode is enabled."); - jLabel4.setText("Input delay:"); + cmbFont.setModel(new DefaultComboBoxModel<>(new String[]{"Original", "Modern"})); + cmbFont.setRenderer(new DisplayFontJComboRenderer()); + cmbFont.setPrototypeDisplayValue("Original original"); + cmbFont.setSelectedIndex(settings.getFont().ordinal()); spnInputDelay.setModel(new SpinnerNumberModel(0, 0, null, 100)); + chkSaveSettings.setSelected(true); - jLabel5.setText("ms"); + btnClearScreen.addActionListener(this::btnClearScreenActionPerformed); + btnRollLine.addActionListener(this::btnRollLineActionPerformed); + btnOK.addActionListener(this::btnOKActionPerformed); + btnOK.setDefaultCapable(true); - GroupLayout panelSimulationLayout = new GroupLayout(panelSimulation); - panelSimulation.setLayout(panelSimulationLayout); - panelSimulationLayout.setHorizontalGroup( - panelSimulationLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelSimulationLayout.createSequentialGroup() + GroupLayout layoutRedirectIO = new GroupLayout(panelRedirectIO); + panelRedirectIO.setLayout(layoutRedirectIO); + layoutRedirectIO.setHorizontalGroup( + layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutRedirectIO.createSequentialGroup() .addContainerGap() - .addGroup(panelSimulationLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel3) - .addGroup(panelSimulationLayout.createSequentialGroup() - .addGroup(panelSimulationLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelSimulationLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel2, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)) - .addComponent(jLabel4)) + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblNote) + .addGroup(layoutRedirectIO.createSequentialGroup() + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblInputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblOutputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)) + .addComponent(lblInputDelay)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSimulationLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelSimulationLayout.createSequentialGroup() + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutRedirectIO.createSequentialGroup() .addComponent(txtOutputFileName, GroupLayout.PREFERRED_SIZE, 241, Short.MAX_VALUE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnOutputBrowse)) - .addGroup(GroupLayout.Alignment.TRAILING, panelSimulationLayout.createSequentialGroup() + .addGroup(GroupLayout.Alignment.TRAILING, layoutRedirectIO.createSequentialGroup() .addComponent(txtInputFileName, GroupLayout.PREFERRED_SIZE, 241, Short.MAX_VALUE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnInputBrowse)) - .addGroup(panelSimulationLayout.createSequentialGroup() + .addGroup(layoutRedirectIO.createSequentialGroup() .addComponent(spnInputDelay, GroupLayout.PREFERRED_SIZE, 73, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel5))))) + .addComponent(lblMs))))) .addContainerGap()) ); - panelSimulationLayout.setVerticalGroup( - panelSimulationLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, panelSimulationLayout.createSequentialGroup() - .addGroup(panelSimulationLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) + layoutRedirectIO.setVerticalGroup( + layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, layoutRedirectIO.createSequentialGroup() + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblInputFileName) .addComponent(txtInputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(btnInputBrowse)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSimulationLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2) + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblOutputFileName) .addComponent(txtOutputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(btnOutputBrowse)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSimulationLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4) + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblInputDelay) .addComponent(spnInputDelay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel5)) + .addComponent(lblMs)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 21, Short.MAX_VALUE) - .addComponent(jLabel3)) + .addComponent(lblNote)) ); - jPanel1.setBorder(BorderFactory.createTitledBorder( + panelTerminal.setBorder(BorderFactory.createTitledBorder( null, "Terminal", 0, 0, - jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | Font.BOLD) + lblInputFileName.getFont().deriveFont(lblInputFileName.getFont().getStyle() | Font.BOLD) )); - chkHalfDuplex.setText("Half duplex mode"); - chkAlwaysOnTop.setText("Display always on top"); - chkAntiAliasing.setText("Use anti-aliasing"); - - GroupLayout jPanel1Layout = new GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() + GroupLayout layoutTerminal = new GroupLayout(panelTerminal); + panelTerminal.setLayout(layoutTerminal); + layoutTerminal.setHorizontalGroup( + layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutTerminal.createSequentialGroup() .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutTerminal.createSequentialGroup() + .addComponent(lblFont) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cmbFont)) .addComponent(chkHalfDuplex) .addComponent(chkAlwaysOnTop) .addComponent(chkAntiAliasing)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() + layoutTerminal.setVerticalGroup( + layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutTerminal.createSequentialGroup() + .addGroup(layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblFont) + .addComponent(cmbFont)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(chkHalfDuplex) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(chkAlwaysOnTop) @@ -199,47 +197,35 @@ private void initComponents() { .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - chkSaveSettings.setSelected(true); - chkSaveSettings.setText("Save settings"); - - btnClearScreen.setText("Clear screen"); - btnClearScreen.addActionListener(this::btnClearScreenActionPerformed); - - btnRollLine.setText("Roll down"); - btnRollLine.addActionListener(this::btnRollLineActionPerformed); + panelControl.setBorder(BorderFactory.createTitledBorder( + null, "Control", 0, 0, + lblInputFileName.getFont().deriveFont(lblInputFileName.getFont().getStyle() | Font.BOLD) + )); - GroupLayout jPanel2Layout = new GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() + GroupLayout layoutControl = new GroupLayout(panelControl); + panelControl.setLayout(layoutControl); + layoutControl.setHorizontalGroup( + layoutControl.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutControl.createSequentialGroup() .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(chkSaveSettings)) - .addGroup(jPanel2Layout.createSequentialGroup() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addGroup(layoutControl.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutControl.createSequentialGroup() + .addGroup(layoutControl.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(btnClearScreen, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnRollLine, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + layoutControl.setVerticalGroup( + layoutControl.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, layoutControl.createSequentialGroup() .addContainerGap() .addComponent(btnClearScreen) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnRollLine) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(chkSaveSettings) .addContainerGap()) ); - btnOK.setText("OK"); - btnOK.addActionListener(this::btnOKActionPerformed); - GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( @@ -248,13 +234,15 @@ private void initComponents() { .addContainerGap() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(panelSimulation, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelRedirectIO, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) .addGroup(layout.createSequentialGroup() - .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(panelTerminal, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()))) + .addComponent(panelControl, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(layout.createSequentialGroup() + .addComponent(chkSaveSettings)))) .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnOK, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) @@ -264,11 +252,13 @@ private void initComponents() { layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(18, 18, 18) - .addComponent(panelSimulation, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(panelRedirectIO, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addComponent(panelTerminal, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(panelControl, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkSaveSettings) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnOK) .addContainerGap()) @@ -286,7 +276,11 @@ private void btnRollLineActionPerformed(java.awt.event.ActionEvent evt) { } private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { - window.setAlwaysOnTop(chkAlwaysOnTop.isSelected()); + if (window != null) { + window.setAlwaysOnTop(chkAlwaysOnTop.isSelected()); + window.setDisplayFont(DisplayFont.fromTerminalFont( + TerminalSettings.TerminalFont.valueOf(cmbFont.getSelectedItem().toString().toUpperCase()))); + } try { updateSettings(chkSaveSettings.isSelected()); dispose(); @@ -295,11 +289,12 @@ private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { } } - private JCheckBox chkAlwaysOnTop; - private JCheckBox chkAntiAliasing; - private JCheckBox chkHalfDuplex; - private JCheckBox chkSaveSettings; - private JSpinner spnInputDelay; - private JTextField txtInputFileName; - private JTextField txtOutputFileName; + private final JCheckBox chkAlwaysOnTop = new JCheckBox("Display always on top"); + private final JCheckBox chkAntiAliasing = new JCheckBox("Use anti-aliasing"); + private final JCheckBox chkHalfDuplex = new JCheckBox("Half duplex mode"); + private final JCheckBox chkSaveSettings = new JCheckBox("Save settings"); + private final JSpinner spnInputDelay = new JSpinner(); + private final JTextField txtInputFileName = new JTextField(DEFAULT_INPUT_FILE_NAME); + private final JTextField txtOutputFileName = new JTextField(DEFAULT_OUTPUT_FILE_NAME); + private final JComboBox cmbFont = new JComboBox<>(); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java index b37db50d4..74afcae7f 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java @@ -1,44 +1,35 @@ package net.emustudio.plugins.device.adm3a.gui; import net.emustudio.plugins.device.adm3a.interaction.Display; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.swing.*; import java.awt.*; -import java.awt.font.TextAttribute; import java.awt.geom.Rectangle2D; import java.awt.image.BufferStrategy; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import static java.awt.RenderingHints.*; +import static net.emustudio.plugins.device.adm3a.Utils.loadFont; public class DisplayCanvas extends Canvas implements AutoCloseable { - private final static Logger LOGGER = LoggerFactory.getLogger(DisplayCanvas.class); - private static final Color FOREGROUND = new Color(0, 255, 0); private static final Color BACKGROUND = Color.BLACK; - private static final String TERMINAL_FONT_PATH = "/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf"; - private static final int FONT_SIZE = 12; - private final Font terminalFont; + private volatile DisplayFont displayFont; private final Timer repaintTimer; private final Display display; private final AtomicBoolean painting = new AtomicBoolean(false); private volatile Dimension size = new Dimension(0, 0); - public DisplayCanvas(Display display) { + public DisplayCanvas(DisplayFont displayFont, Display display) { + this.displayFont = Objects.requireNonNull(displayFont); this.display = Objects.requireNonNull(display); - this.terminalFont = loadFont(); setForeground(FOREGROUND); setBackground(BACKGROUND); - setFont(terminalFont); + setFont(loadFont(displayFont)); PaintCycle paintCycle = new PaintCycle(); this.repaintTimer = new Timer(1000 / 60, e -> paintCycle.run()); // 60 HZ @@ -75,21 +66,10 @@ public void setBounds(Rectangle r) { this.size = getSize(); } - private Font loadFont() { - Map attrs = new HashMap<>(); - attrs.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); - - try (InputStream fin = getClass().getResourceAsStream(TERMINAL_FONT_PATH)) { - Font font = Font - .createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(fin)) - .deriveFont(Font.PLAIN, FONT_SIZE) - .deriveFont(attrs); - GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font); - return font; - } catch (Exception e) { - LOGGER.error("Could not load custom font, using default monospaced font", e); - return new Font(Font.MONOSPACED, Font.PLAIN, FONT_SIZE); - } + public synchronized void setDisplayFont(DisplayFont font) { + // setting font must be atomic + setFont(loadFont(font)); + this.displayFont = Objects.requireNonNull(font); } @Override @@ -151,12 +131,13 @@ private void paintCursor(Graphics graphics, int lineHeight) { graphics.setXORMode(BACKGROUND); graphics.setColor(FOREGROUND); - Rectangle2D fontRectangle = terminalFont.getMaxCharBounds(graphics.getFontMetrics().getFontRenderContext()); + Rectangle2D fontRectangle = getFont().getMaxCharBounds(graphics.getFontMetrics().getFontRenderContext()); - int x = 2 + (int) (cursorPoint.x * (fontRectangle.getWidth() + 0.3)); - int y = 3 + (cursorPoint.y * lineHeight); + int x = displayFont.xCursorOffset + + (int) (cursorPoint.x * (fontRectangle.getWidth() + displayFont.xCursorMultiplierOffset)); + int y = displayFont.yCursorOffset + (cursorPoint.y * lineHeight); - graphics.fillRect(x, y, (int) fontRectangle.getWidth(), (int) fontRectangle.getHeight() + 5); + graphics.fillRect(x, y, (int) fontRectangle.getWidth(), (int) fontRectangle.getHeight() + displayFont.yCursorExtend); graphics.setPaintMode(); } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java new file mode 100644 index 000000000..3ed4aced0 --- /dev/null +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java @@ -0,0 +1,41 @@ +package net.emustudio.plugins.device.adm3a.gui; + +import net.emustudio.plugins.device.adm3a.TerminalSettings; + +import java.util.Objects; + +public class DisplayFont { + + public static final DisplayFont FONT_ORIGINAL = new DisplayFont( + "/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf", + 2, 0.3, 3, 5, 12 + ); + + public static final DisplayFont FONT_MODERN = new DisplayFont( + "/net/emustudio/plugins/device/adm3a/gui/terminal.ttf", + 2, 0, 3, 0, 15 + ); + + public final String path; + public final int xCursorOffset; + public final double xCursorMultiplierOffset; + public final int yCursorOffset; + public final int yCursorExtend; + public final int fontSize; + + public DisplayFont(String path, int xCursorOffset, double xCursorMultiplierOffset, int yCursorOffset, int yCursorExtend, int fontSize) { + this.path = Objects.requireNonNull(path); + this.xCursorOffset = xCursorOffset; + this.xCursorMultiplierOffset = xCursorMultiplierOffset; + this.yCursorOffset = yCursorOffset; + this.yCursorExtend = yCursorExtend; + this.fontSize = fontSize; + } + + public static DisplayFont fromTerminalFont(TerminalSettings.TerminalFont font) { + if (font == TerminalSettings.TerminalFont.ORIGINAL) { + return FONT_ORIGINAL; + } + return FONT_MODERN; + } +} diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java new file mode 100644 index 000000000..8ea2efec5 --- /dev/null +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java @@ -0,0 +1,38 @@ +package net.emustudio.plugins.device.adm3a.gui; + +import javax.swing.*; +import java.awt.*; + +import static net.emustudio.plugins.device.adm3a.Utils.loadFont; + +public class DisplayFontJComboRenderer extends JLabel implements ListCellRenderer { + private final Font originalFont = loadFont(DisplayFont.FONT_ORIGINAL); + private final Font modernFont = loadFont(DisplayFont.FONT_MODERN); + + public DisplayFontJComboRenderer() { + setOpaque(true); + } + + @Override + public Component getListCellRendererComponent(JList list, String value, int index, + boolean isSelected, boolean cellHasFocus) { + setText(value); + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + switch (index) { + case 0: + setFont(originalFont); + break; + case 1: + setFont(modernFont); + break; + default: + } + return this; + } +} diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java index 3ea5a2bfb..9988167c0 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java @@ -29,10 +29,10 @@ public class TerminalWindow extends JDialog { private final Display display; private final DisplayCanvas canvas; - public TerminalWindow(JFrame parent, Display display) { + public TerminalWindow(JFrame parent, Display display, DisplayFont font) { super(parent); this.display = Objects.requireNonNull(display); - this.canvas = new DisplayCanvas(display); + this.canvas = new DisplayCanvas(font, display); initComponents(); setVisible(false); @@ -59,6 +59,10 @@ public void rollLine() { canvas.repaint(); } + public void setDisplayFont(DisplayFont displayFont) { + canvas.setDisplayFont(displayFont); + } + private void initComponents() { JLabel lblBack = new JLabel(); ImageIcon backgroundImage = new ImageIcon(getClass().getResource(BACKGROUND_IMAGE)); diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/terminal.ttf b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/terminal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5b9f106043a31890bc7d359f11ce170510c4eb2b GIT binary patch literal 309064 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 I%C1xX185HK Date: Thu, 17 Nov 2022 12:27:17 +0100 Subject: [PATCH 217/314] [#284] adm-3A: change font in runtime fix --- .../device/adm3a/gui/DisplayCanvas.java | 2 +- .../plugins/device/adm3a/gui/DisplayFont.java | 9 +++-- .../device/adm3a/gui/DisplayParameters.java | 36 ------------------- 3 files changed, 7 insertions(+), 40 deletions(-) delete mode 100644 plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayParameters.java diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java index 74afcae7f..cecc93266 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java @@ -99,7 +99,7 @@ protected void paint() { graphics.setColor(BACKGROUND); graphics.fillRect(0, 0, dimension.width, dimension.height); - int lineHeight = graphics.getFontMetrics().getHeight() + 5; + int lineHeight = graphics.getFontMetrics().getHeight() + displayFont.yLineHeightMultiplierOffset; graphics.setColor(FOREGROUND); graphics.setRenderingHint(KEY_RENDERING, VALUE_RENDER_QUALITY); graphics.setRenderingHint(KEY_FRACTIONALMETRICS, VALUE_FRACTIONALMETRICS_ON); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java index 3ed4aced0..1a4bfecec 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java @@ -8,12 +8,12 @@ public class DisplayFont { public static final DisplayFont FONT_ORIGINAL = new DisplayFont( "/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf", - 2, 0.3, 3, 5, 12 + 2, 0.3, 3, 5, 12, 5 ); public static final DisplayFont FONT_MODERN = new DisplayFont( "/net/emustudio/plugins/device/adm3a/gui/terminal.ttf", - 2, 0, 3, 0, 15 + 2, 0, 3, 0, 15, 0 ); public final String path; @@ -21,15 +21,18 @@ public class DisplayFont { public final double xCursorMultiplierOffset; public final int yCursorOffset; public final int yCursorExtend; + public final int yLineHeightMultiplierOffset; public final int fontSize; - public DisplayFont(String path, int xCursorOffset, double xCursorMultiplierOffset, int yCursorOffset, int yCursorExtend, int fontSize) { + public DisplayFont(String path, int xCursorOffset, double xCursorMultiplierOffset, int yCursorOffset, + int yCursorExtend, int fontSize, int yLineHeightMultiplierOffset) { this.path = Objects.requireNonNull(path); this.xCursorOffset = xCursorOffset; this.xCursorMultiplierOffset = xCursorMultiplierOffset; this.yCursorOffset = yCursorOffset; this.yCursorExtend = yCursorExtend; this.fontSize = fontSize; + this.yLineHeightMultiplierOffset = yLineHeightMultiplierOffset; } public static DisplayFont fromTerminalFont(TerminalSettings.TerminalFont font) { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayParameters.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayParameters.java deleted file mode 100644 index bbe13b4ee..000000000 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayParameters.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.adm3a.gui; - -import net.jcip.annotations.Immutable; - -@Immutable -class DisplayParameters { - final int maxWidth; - final int maxHeight; - final int charWidth; - final int charHeight; - - DisplayParameters(int maxWidth, int maxHeight, int charWidth, int charHeight) { - this.maxWidth = maxWidth; - this.maxHeight = maxHeight; - this.charWidth = charWidth; - this.charHeight = charHeight; - } -} From 2575e87587b3571bd1f6e713a211b147f504f23b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 18 Nov 2022 15:28:27 +0100 Subject: [PATCH 218/314] [#284] adm3a: Move clear&roll buttons to main window --- .../device/adm3a/gui/ConfigDialog.java | 50 +----------------- .../device/adm3a/gui/TerminalWindow.java | 30 +++++++++++ .../plugins/device/adm3a/gui/clear.png | Bin 0 -> 773 bytes .../plugins/device/adm3a/gui/roll.png | Bin 0 -> 636 bytes 4 files changed, 32 insertions(+), 48 deletions(-) create mode 100644 plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/clear.png create mode 100644 plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/roll.png diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java index 2960d257b..f7c664def 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java @@ -81,9 +81,6 @@ private void initComponents() { JLabel lblInputDelay = new JLabel("Input delay:"); JLabel lblMs = new JLabel("ms"); JPanel panelTerminal = new JPanel(); - JPanel panelControl = new JPanel(); - JButton btnClearScreen = new JButton("Clear screen"); - JButton btnRollLine = new JButton("Roll line"); JButton btnOK = new JButton("OK"); JLabel lblFont = new JLabel("Font"); @@ -105,8 +102,6 @@ private void initComponents() { spnInputDelay.setModel(new SpinnerNumberModel(0, 0, null, 100)); chkSaveSettings.setSelected(true); - btnClearScreen.addActionListener(this::btnClearScreenActionPerformed); - btnRollLine.addActionListener(this::btnRollLineActionPerformed); btnOK.addActionListener(this::btnOKActionPerformed); btnOK.setDefaultCapable(true); @@ -197,35 +192,6 @@ private void initComponents() { .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - panelControl.setBorder(BorderFactory.createTitledBorder( - null, "Control", 0, 0, - lblInputFileName.getFont().deriveFont(lblInputFileName.getFont().getStyle() | Font.BOLD) - )); - - GroupLayout layoutControl = new GroupLayout(panelControl); - panelControl.setLayout(layoutControl); - layoutControl.setHorizontalGroup( - layoutControl.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layoutControl.createSequentialGroup() - .addContainerGap() - .addGroup(layoutControl.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layoutControl.createSequentialGroup() - .addGroup(layoutControl.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnClearScreen, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnRollLine, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) - ); - layoutControl.setVerticalGroup( - layoutControl.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, layoutControl.createSequentialGroup() - .addContainerGap() - .addComponent(btnClearScreen) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnRollLine) - .addContainerGap()) - ); - GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( @@ -237,9 +203,7 @@ private void initComponents() { .addComponent(panelRedirectIO, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) .addGroup(layout.createSequentialGroup() - .addComponent(panelTerminal, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelControl, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelTerminal, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) .addGroup(layout.createSequentialGroup() .addComponent(chkSaveSettings)))) @@ -254,9 +218,7 @@ private void initComponents() { .addGap(18, 18, 18) .addComponent(panelRedirectIO, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(panelTerminal, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(panelControl, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addComponent(panelTerminal, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(chkSaveSettings) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) @@ -267,14 +229,6 @@ private void initComponents() { pack(); } - private void btnClearScreenActionPerformed(java.awt.event.ActionEvent evt) { - window.clearScreen(); - } - - private void btnRollLineActionPerformed(java.awt.event.ActionEvent evt) { - window.rollLine(); - } - private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { if (window != null) { window.setAlwaysOnTop(chkAlwaysOnTop.isSelected()); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java index 9988167c0..a52f0c9ef 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java @@ -21,11 +21,17 @@ import net.emustudio.plugins.device.adm3a.interaction.Display; import javax.swing.*; +import javax.swing.border.TitledBorder; import java.awt.*; import java.util.Objects; +import static java.awt.FlowLayout.LEFT; + public class TerminalWindow extends JDialog { private static final String BACKGROUND_IMAGE = "/net/emustudio/plugins/device/adm3a/gui/display.png"; + private static final String CLEAR_SCREEN_ICON = "/net/emustudio/plugins/device/adm3a/gui/clear.png"; + private static final String ROLL_LINE_ICON = "/net/emustudio/plugins/device/adm3a/gui/roll.png"; + private final Display display; private final DisplayCanvas canvas; @@ -82,10 +88,34 @@ private void initComponents() { lblBack.setBounds(0, 0, backgroundImage.getIconWidth(), backgroundImage.getIconHeight()); lblBack.setDoubleBuffered(true); + JButton btnClear = new JButton(); + btnClear.setFocusable(false); + btnClear.setIcon(new ImageIcon(getClass().getResource(CLEAR_SCREEN_ICON))); + btnClear.setToolTipText("Clear screen"); + btnClear.addActionListener(e -> clearScreen()); + + JButton btnRoll = new JButton(); + btnRoll.setFocusable(false); + btnRoll.setIcon(new ImageIcon(getClass().getResource(ROLL_LINE_ICON))); + btnRoll.setToolTipText("Roll line up"); + btnRoll.addActionListener(e -> rollLine()); + + JPanel panelControl = new JPanel(); + panelControl.setBorder(null); + panelControl.setOpaque(false); + + FlowLayout panelLayout = new FlowLayout(LEFT); + panelControl.setLayout(panelLayout); + panelControl.setBounds(0, 790, 150, 70); + + panelControl.add(btnClear); + panelControl.add(btnRoll); + Container pane = getContentPane(); pane.setBackground(Color.BLACK); pane.setLayout(null); + pane.add(panelControl); pane.add(canvas); pane.add(lblBack); pane.setPreferredSize(new Dimension(backgroundImage.getIconWidth(), backgroundImage.getIconHeight())); diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/clear.png b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/clear.png new file mode 100644 index 0000000000000000000000000000000000000000..e6c8e8b9f341cbf3a1795631ccaafd14b0e0c911 GIT binary patch literal 773 zcmV+g1N!`lP)5 zl1pfmXB38?@0*$EOcI;hNJ5iHyw#`_D<+Ey(t?XhOLl^ng^SURf+GA21zi{y1{{!5 z5QL7#g;8=>?7hOBWP~@Qv%4i?;^z?o7$2sh!G| zts6JQ<4rGsx`hNvL;&d8r%uFIa{QCF&sB3vJ3Xhnz3G3(a_m%-#>gcR&Ll0E*wJ36qI~C2ft2!

!GOpKDtrJ2lSaNQ|Hgjn@93PsJ(gZ`2+IBy96 z0wag|dVeYUtj2Xcip4zE2Iz1NmGK?q-I(0Ec_nX5@MXf0%df=eg{JcD1;K)00000NkvXXu0mjf Dmc(vD literal 0 HcmV?d00001 diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/roll.png b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/roll.png new file mode 100644 index 0000000000000000000000000000000000000000..70f2c996cd72a79328be5bd0ef9b39cc86be7086 GIT binary patch literal 636 zcmV-?0)zdDP)L zlTS!gQ51)N=l*%UXM%2Q)F>(p+zgmdf)8?0hB*|-MC$(Y7uSP)<6hBvp%pb#VTA`mW=f8m3=A+VF$gz+5g|*fW9a=~fVCub#hVuLlKG!y<+UFWVr@ zx}I*`6F`LLL;b0)!-tO1O8E;`N}ti*)<%831DzmD?+S1|ojsB`IeM-?t-lsNLXv_Y zi4Wgq(ARs$>S*s8bv>PJ3UEE0w6rsoxp>?8Sy_bP08%N`;|ezT7d{op$Nz_$1Jr8{;^A=dpOl#Zx*NxBimVOIKWYqfyp}XTIm^nr{$U_L)(rG}9&-Pp{q+Q Date: Sun, 20 Nov 2022 16:38:54 +0100 Subject: [PATCH 219/314] [#284] as-z80, as-8080: fix db with string --- .../as8080/visitors/EvaluateExprVisitor.java | 9 +- .../plugins/compiler/as8080/e2e/DataTest.java | 8 + .../asZ80/visitors/EvaluateExprVisitor.java | 9 +- .../plugins/compiler/asZ80/e2e/DataTest.java | 42 +- .../device/adm3a/interaction/Display.java | 14 +- .../adm3a/interaction/LoadCursorPosition.java | 4 +- .../plugins/device/adm3a/gui/adm-3a.ttf | Bin 36696 -> 36412 bytes resources/lsi-adm-3a/adm-3a.ttf | Bin 36696 -> 36412 bytes resources/lsi-adm-3a/adm3a.sfd | 2953 ++++++++--------- 9 files changed, 1532 insertions(+), 1507 deletions(-) diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 003ef99c1..1339d8402 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -333,6 +333,7 @@ public void visit(ExprString node) { // hopefully this covers all cases. int strLen = node.string.length(); + Optional parent = node.getParent(); if (sizeBytes == 2) { if (strLen > sizeBytes) { error(expressionIsBiggerThanExpected(node, sizeBytes, strLen)); @@ -341,17 +342,19 @@ public void visit(ExprString node) { if (strLen > 1) { result |= (node.string.charAt(1) << 8); } - node.addChild(new Evaluated(node.line, node.column, result)); + Node evaluated = new Evaluated(node.line, node.column, result); + parent.ifPresent(p -> p.addChild(evaluated)); currentAddress += sizeBytes; } else { for (int i = 0; i < strLen; i++) { - node.addChild(new Evaluated(node.line, node.column, node.string.charAt(i))); + Node evaluated = new Evaluated(node.line, node.column, node.string.charAt(i)); + parent.ifPresent(p -> p.addChild(evaluated)); } if (sizeBytes != 0) { currentAddress += strLen; } } - node.exclude(); + node.remove(); } private Optional getCurrentAddress() { diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java index 417437708..b55d14f1d 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java @@ -189,4 +189,12 @@ public void testJumpBackwardWithDSamong() throws Exception { 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 ); } + + @Test + public void testDbOrdering() throws Exception { + compile("db 186, \"Hello\", 186, 10, 13"); + assertProgram( + 186, 'H', 'e', 'l', 'l', 'o', 186, 10, 13 + ); + } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java index 157b2c7b7..6efa1a709 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java @@ -325,6 +325,7 @@ public void visit(ExprString node) { // hopefully this covers all cases. int strLen = node.string.length(); + Optional parent = node.getParent(); if (sizeBytes == 2) { if (strLen > sizeBytes) { error(expressionIsBiggerThanExpected(node, sizeBytes, strLen)); @@ -333,18 +334,20 @@ public void visit(ExprString node) { if (strLen > 1) { result |= (node.string.charAt(1) << 8); } - node.addChild(new Evaluated(node.line, node.column, result).setSizeBytes(2)); + Node evaluated = new Evaluated(node.line, node.column, result).setSizeBytes(2); + parent.ifPresent(p -> p.addChild(evaluated)); currentAddress += sizeBytes; } else { int maxValue = node.getMaxValue().map(v -> Math.min(v, 0xFF)).orElse(0xFF); for (int i = 0; i < strLen; i++) { - node.addChild(new Evaluated(node.line, node.column, node.string.charAt(i)).setMaxValue(maxValue)); + Node evaluated = new Evaluated(node.line, node.column, node.string.charAt(i)).setMaxValue(maxValue); + parent.ifPresent(p -> p.addChild(evaluated)); } if (sizeBytes != 0) { currentAddress += strLen; } } - node.exclude(); + node.remove(); } private Optional getCurrentAddress() { diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java index 36621ad62..3fe9640e0 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java @@ -23,7 +23,7 @@ public class DataTest extends AbstractCompilerTest { @Test - public void testDBwithNegativeValueWorks() throws Exception { + public void testDBwithNegativeValueWorks() { compile( "db -1" ); @@ -33,14 +33,14 @@ public void testDBwithNegativeValueWorks() throws Exception { } @Test(expected = Exception.class) - public void testDBwithNegativeValueHigherLowerThanMinus127doesNotWork() throws Exception { + public void testDBwithNegativeValueHigherLowerThanMinus127doesNotWork() { compile( "db -1299" ); } @Test - public void testDBallocatesOneByte() throws Exception { + public void testDBallocatesOneByte() { compile( "db 10\nld a,b\n" ); @@ -50,14 +50,14 @@ public void testDBallocatesOneByte() throws Exception { } @Test(expected = Exception.class) - public void testDBbiggerThan255DoesNotWork() throws Exception { + public void testDBbiggerThan255DoesNotWork() { compile( "db 256\n" ); } @Test - public void testDBseveralBytesWork() throws Exception { + public void testDBseveralBytesWork() { compile( "db 255,1,2\n" ); @@ -67,7 +67,7 @@ public void testDBseveralBytesWork() throws Exception { } @Test - public void testDBWithInstruction() throws Exception { + public void testDBWithInstruction() { compile( "db inc A\n" ); @@ -78,7 +78,7 @@ public void testDBWithInstruction() throws Exception { } @Test - public void testDBliteral() throws Exception { + public void testDBliteral() { compile( "db 'if'\n" ); @@ -89,7 +89,7 @@ public void testDBliteral() throws Exception { } @Test - public void testDBshortLiteral() throws Exception { + public void testDBshortLiteral() { compile( "db 'i'\n" ); @@ -100,7 +100,7 @@ public void testDBshortLiteral() throws Exception { } @Test - public void testDWwithNegativeValueWorks() throws Exception { + public void testDWwithNegativeValueWorks() { compile( "dw -1" ); @@ -110,14 +110,14 @@ public void testDWwithNegativeValueWorks() throws Exception { } @Test(expected = Exception.class) - public void testDWwithNegativeValueHigherLowerThanMinus3768doesNotWork() throws Exception { + public void testDWwithNegativeValueHigherLowerThanMinus3768doesNotWork() { compile( "dw -32769" ); } @Test - public void testDWallocatesTwoBytesInLittleEndian() throws Exception { + public void testDWallocatesTwoBytesInLittleEndian() { compile( "dw 10\nld a,b\n" ); @@ -127,7 +127,7 @@ public void testDWallocatesTwoBytesInLittleEndian() throws Exception { } @Test - public void testDWseveralValuesWork() throws Exception { + public void testDWseveralValuesWork() { compile( "dw 10,4\nld a,b\n" ); @@ -137,14 +137,14 @@ public void testDWseveralValuesWork() throws Exception { } @Test(expected = Exception.class) - public void testDWmoreThanFFFFdoesNotWork() throws Exception { + public void testDWmoreThanFFFFdoesNotWork() { compile( "dw 10000h\nld a,b\n" ); } @Test(expected = Exception.class) - public void testDW_ValueTooBig() throws Exception { + public void testDW_ValueTooBig() { compile( "org 0FFFFh\n" + "rrca\n" @@ -154,14 +154,14 @@ public void testDW_ValueTooBig() throws Exception { } @Test(expected = Exception.class) - public void testDSwithNegativeValueDoesNotWork() throws Exception { + public void testDSwithNegativeValueDoesNotWork() { compile( "ds -1" ); } @Test - public void testDSbreaksPreviousMemoryContent() throws Exception { + public void testDSbreaksPreviousMemoryContent() { memoryStub.write(0, (byte) 0x10); memoryStub.write(1, (byte) 0x11); @@ -175,7 +175,7 @@ public void testDSbreaksPreviousMemoryContent() throws Exception { } @Test - public void testJumpBackwardWithDSamong() throws Exception { + public void testJumpBackwardWithDSamong() { compile( "ds 2\n" + "now: ld a,b\n" + @@ -189,4 +189,12 @@ public void testJumpBackwardWithDSamong() throws Exception { 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 ); } + + @Test + public void testDbOrdering() { + compile("db 186, \"Hello\", 186, 10, 13"); + assertProgram( + 186, 'H', 'e', 'l', 'l', 'o', 186, 10, 13 + ); + } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java index fb71e46a0..134b9bd55 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java @@ -104,10 +104,13 @@ public void rollLine() { @Override public void write(byte data) { writeToOutput(data); + + int d = data & 0xFF; + /* * if it is special char, interpret it. else just add to "video memory" */ - switch (data) { + switch (d) { case 5: // HERE IS insertHereIs(); break; @@ -140,8 +143,8 @@ public void write(byte data) { break; } - if (loadCursorPosition.notAccepted(data) && data >= 32) { - drawChar((char) (data & 0xFF)); + if (loadCursorPosition.notAccepted(data) && d >= 32) { + drawChar((char) d); cursor.moveForwardsRolling(this); } } @@ -154,6 +157,7 @@ private void insertHereIs() { } private void drawChar(char c) { + System.out.println(c + " - " + (int)c); Point cursorPoint = cursor.getCursorPoint(); synchronized (videoMemory) { videoMemory[cursorPoint.y * columns + cursorPoint.x] = c; @@ -174,10 +178,10 @@ private void openOutputWriter() { } } - private void writeToOutput(short val) { + private void writeToOutput(byte data) { if (outputWriter != null) { try { - outputWriter.write((char) val); + outputWriter.write((char) data); outputWriter.flush(); } catch (IOException e) { LOGGER.error("Could not write to file: " + settings.getOutputPath(), e); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java index 5f1eb557b..b01238611 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java @@ -48,11 +48,11 @@ public LoadCursorPosition(Cursor cursor) { * @param data received char * @return true if in bounds */ - private boolean checkBounds(Byte data) { + private boolean checkBounds(byte data) { return data >= ' ' && data <= 'o'; } - boolean notAccepted(Byte data) { + boolean notAccepted(byte data) { if (expect == ESCAPE && data == ASCII_ESC) { expect = ASSIGN; return false; diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf index 608c7c8c4361464e91b3e2b9db90ad226b3dd392..54d9399083d8e2f83648cbb0c5264a239821ebcf 100644 GIT binary patch delta 3063 zcmcImdu&tJ89(RV>sS1KJF#Qm>sOpONv|C{1SbS1B_YA4LnBEMP)bM`X_r7mLI<5j zC_)wDQ7EU{s&-AYcIzrYG^%ln7-AdS7-MTTt!V26f{9KjS{bWY%T`FpzH@yYm{w_j z%{S-X`ukRb`9ghDj@k4~zO9(NK^*uAnqegBELdqcMxlO$z!$<`e zI`}V;b(;ovd@Xb_bsHhIh){NBU}NuCe`V8a4WPUUqkaHptnc8z!2&cuaA0V3y9=R4 zkT1Xjy1^}dy_zRJzX}UPKvoX*ZXd>3bPDtxV9#&v9oop9JG2p@?rMY*_lCEOjCNOM z0Ng&XXQ!lOAz@qo{WqU9Hhqq?%K#kwu4TM`k)GoV0R6pbZ9hT=0NqvVw-e`{fYK7ok!QBdtNuCyRK*SyuL%f zUH`KFr2c~bivCkWiNR&4Hf%7wWH@d3t1)QoG9EAsF8OZpYCgiZ^ZopGeu6*4U*f0vyMjRo3UMJVtP+NW-NIpETsSVA7A^>X z@Vor0{hR%J{U`ia15CgXSP^(O@Lu3fFdf_(d@Fc9cs<00JfTFWD>NE95;`Bc9oB`* z!cF0x@Njr%cqbxJ&5s3IiX1(0P;*vn#{sjLXEQVTyb8_apPtF9a>kPP)h*NvQ!|#{ z%tGP9Xbxrz1F9WP7!4+wa7Y6lU?)m9Ca1MpnNq5j!$?7>vkJ{3L>AZ=JLn>kGq_r@ z83&SZOOk_jkGgPr6o^dPt6=J~{p)bd>3S?eC9sf52$<{QNwZ*L$T~*?7NU6J5Q3g! zEuuu^nB%Yllxz)2JHrgF$qhJKBcV`84Uslm1%lj)TF(&zn7^MmHpHzsLC7wu1)~|`sP__Z8sKdVx0)*V*9)sfYoI1x%i(3_;h$1BNR0iDDG zEt%QEk&(>c#*zee;%QR3hFE(_`@+S>R%;toJJBr!7o~nU~4^rjDiN7~O zh2>mLXNwb;7cBxjrOhoeo+q0H2>D!dNS2Q^$3ec@OiP@Wv~O`4*chg{y*1gJ0pG zo+p#7(9v=?S|?~Hq|;JEm3$d=AEYl3%DvuZ#c+P*#if2kTPPhY`BnQD4|)z{LzguR z41}5i_q%A0Z0d*-Lx;yZAK}Za5LprOlBYW&ZS!Vw4i5s}mxIng4)mf~Am~(pSy626 zMOc?R+)_qTD`bmW3Ymg7b{4fj>VIh;?fj0sE!R4ou+jhQ%;2$kSPy+|Xiva$o=Qp; zGdWJ{Y3{iDDN4H!N?a-4_07wX~%gZy+^g8X8clen_YQicy16>Xp~ZOJ}P zj%GdNdNu&(*NEVT<-QAFC6RV0t1=)4c-EAJo&$ZN9y$k{Yro27C-uu0n${R`CYzl@ znahVVv}SVOT;8aZcwxzpR=P3H{c+_Q3=kN|7v|w(QlPi6VVGpPDakBQ0-f@q3^}@W uWUTug(9-O|SJu)_q5wWoZfVa1#tX^x<04*|D_xbUgXOyRV~&OYZvPE!=R$)3 delta 3713 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 JvhaV_zXAN>JUsva diff --git a/resources/lsi-adm-3a/adm-3a.ttf b/resources/lsi-adm-3a/adm-3a.ttf index 608c7c8c4361464e91b3e2b9db90ad226b3dd392..54d9399083d8e2f83648cbb0c5264a239821ebcf 100644 GIT binary patch delta 3063 zcmcImdu&tJ89(RV>sS1KJF#Qm>sOpONv|C{1SbS1B_YA4LnBEMP)bM`X_r7mLI<5j zC_)wDQ7EU{s&-AYcIzrYG^%ln7-AdS7-MTTt!V26f{9KjS{bWY%T`FpzH@yYm{w_j z%{S-X`ukRb`9ghDj@k4~zO9(NK^*uAnqegBELdqcMxlO$z!$<`e zI`}V;b(;ovd@Xb_bsHhIh){NBU}NuCe`V8a4WPUUqkaHptnc8z!2&cuaA0V3y9=R4 zkT1Xjy1^}dy_zRJzX}UPKvoX*ZXd>3bPDtxV9#&v9oop9JG2p@?rMY*_lCEOjCNOM z0Ng&XXQ!lOAz@qo{WqU9Hhqq?%K#kwu4TM`k)GoV0R6pbZ9hT=0NqvVw-e`{fYK7ok!QBdtNuCyRK*SyuL%f zUH`KFr2c~bivCkWiNR&4Hf%7wWH@d3t1)QoG9EAsF8OZpYCgiZ^ZopGeu6*4U*f0vyMjRo3UMJVtP+NW-NIpETsSVA7A^>X z@Vor0{hR%J{U`ia15CgXSP^(O@Lu3fFdf_(d@Fc9cs<00JfTFWD>NE95;`Bc9oB`* z!cF0x@Njr%cqbxJ&5s3IiX1(0P;*vn#{sjLXEQVTyb8_apPtF9a>kPP)h*NvQ!|#{ z%tGP9Xbxrz1F9WP7!4+wa7Y6lU?)m9Ca1MpnNq5j!$?7>vkJ{3L>AZ=JLn>kGq_r@ z83&SZOOk_jkGgPr6o^dPt6=J~{p)bd>3S?eC9sf52$<{QNwZ*L$T~*?7NU6J5Q3g! zEuuu^nB%Yllxz)2JHrgF$qhJKBcV`84Uslm1%lj)TF(&zn7^MmHpHzsLC7wu1)~|`sP__Z8sKdVx0)*V*9)sfYoI1x%i(3_;h$1BNR0iDDG zEt%QEk&(>c#*zee;%QR3hFE(_`@+S>R%;toJJBr!7o~nU~4^rjDiN7~O zh2>mLXNwb;7cBxjrOhoeo+q0H2>D!dNS2Q^$3ec@OiP@Wv~O`4*chg{y*1gJ0pG zo+p#7(9v=?S|?~Hq|;JEm3$d=AEYl3%DvuZ#c+P*#if2kTPPhY`BnQD4|)z{LzguR z41}5i_q%A0Z0d*-Lx;yZAK}Za5LprOlBYW&ZS!Vw4i5s}mxIng4)mf~Am~(pSy626 zMOc?R+)_qTD`bmW3Ymg7b{4fj>VIh;?fj0sE!R4ou+jhQ%;2$kSPy+|Xiva$o=Qp; zGdWJ{Y3{iDDN4H!N?a-4_07wX~%gZy+^g8X8clen_YQicy16>Xp~ZOJ}P zj%GdNdNu&(*NEVT<-QAFC6RV0t1=)4c-EAJo&$ZN9y$k{Yro27C-uu0n${R`CYzl@ znahVVv}SVOT;8aZcwxzpR=P3H{c+_Q3=kN|7v|w(QlPi6VVGpPDakBQ0-f@q3^}@W uWUTug(9-O|SJu)_q5wWoZfVa1#tX^x<04*|D_xbUgXOyRV~&OYZvPE!=R$)3 delta 3713 zcmcIndu&tJ89(RV>+4sX`1+ODacp0|632Pm*iL}pkWqz@;-V9>+!lniRG!<=xwQ{z z;YCAW1LbY#-Lc;E&_Ea=eFZ}IxHmr1neL9n^-lrwQ~1?wgca*AnI3Qu1Uk5JbN_bZ zM=i^NK7$a;_ipLxG)>%W0|&ro_|2W$`*16I3-~P{?|ZCs^CPpThSnjp8tBAS-F_TXfic@{0E>19?S#KXvgk}_uL|Ld6k ziZkX80O&deB9HiXpjn;_^x}U9Ki@~1Dt(iPzlrSskU8+LMwSJVbufRV^E>_K>)lC* z%FNBq&zc78agfb4olpjSu=;*=rf`)nmC4TNn5E|HD05Ye%FLnqEOkqsuESX6k<~-ZYq#s8=L?h^ZbPXr*xA9|mH+~hL##a~z z)5Pp#USmFF^Vxd#yX+wQTlNdi#np3bx$WEm?kIN--oJ1+HFcV&H7{$f^E@Bqm++7C zd-#|55&k#)1ud^lXt!zK(SD?}=vs6gy4Q7o(@pDL`hg=*^xApeVpnl%@y_Cr;!oT~?s9k1z0Liqd(3^k zBvI1s;XM_edQYpT+q28F$206X<+do^8y-Dv1@0zr?&%4XJ&wJQA;yvq~^v?Q< zd<%W6ef_>c-*MkL-=y!lXb?SOo!BI{i9O;|;sNo9cw8J4&xs$3SNvuE9{(=?A^({F zvw$TK4s--|2Tlk1;C;cp!8e2B!D}H~s3O!9>JB{}IuaTWGhuhQJlq;yA07zr4ev#y zT6Z!;3rRy;Jruki+i^gU@F<&_9v#)9>Cv8P7!b-7=zpbKMyrRVqVfleg8VX2S97@^ zG+SDPj8cyv%OO2f9!N^^hs|g$R>sM|x@t;hDn_(uhQw`+h18LZ2~_o1z=2x$)G}ny z=GMw*O@ql%TRE;H6ShZ-Xap?0$N-MaVnB$;Y6a2ElJD3P;D|Co1o#v{4lQ}bzE1-e z42MY45oQ>a>2~aAQw*FD7M#Ne!2f5AEW}EG@IZ`I3}lU{0AwX0>s+FlVM&AQ35}dy za?(|Z+02Bii>;vx9JOskNY0;&B%G7MMg`GBS*?Q zigO{FKmo!5TZw=~HCa*;DN!*tMk0WDQzRS1ixCkpzZ-e-c72*6LG%go7Bb}F@~nQk zyaH>;(egSq#*fSWpl^tl`Evd(;Gd>dsEZX^!G^h}E*>jnNL#eqG&f5(74{(t!ISr* zQSy)IT|}z5S5A?J{GcL4Q(W<5HD!w{D}mlrSy_`ibsVC559kzZawe3TnSpwmf!)V) zagpCuR$(^tWhIAI<8xJhFy^n8RQkc{I-vJfe@mq=RxbnEDc!Bo8>A%AFG*)rdTUJz z=#w=ml`e>dAQ!cC;|P46Om}H`Yp%>c%@pi z7>8ur#o9y^`%B;qsXGoec`Q+u`5@8BfDu}hjSDEqXBMnd>B|dhF_*C~+>wovEUJWs zcNdjp7yeogWtYiYJeFNJpKJh}riP^|&IcMqF!{ZPkV?PU5Ci%T4N2HjwFA*TRqBCe z9-HCZh=QacRZBjFBdZG09_Ix?5^eNCS0F1I7r@`m>^!~|`6-_?`YC_3u|D&8;}bXr ze*`Fv=2n-a36OGK3TkEwHW$PgR8K323@@$4sm%D&Va7@A&u^mih|GfYjm%J!6&L2* z=UN#Jfg^7(yCLRy(7os?ga*nCng;co)EznByc~|J8sOJUk>{F2WV|_uG5N*aPO^Ww z)vb0#9?Sq(wey2<+40Hc#UT1|lL%dzI+_9z*_o=PK`i-ulao}n>?_H+rr@DfDj-!$ znLoCqa3m)(uTd*q0;_TG=mu!!&@BXl{%r()XyRm>oP3N}dVEwKn7xe$M~oa>@gt|A z`E}ftsR!kIM!vFg_YAcOdqGa7!qD^!Pz`uc8!uc?675k|J|G2rEWJ1+=oEF(JKzBL zwUR&_t&8${aH_R+4y9%frsgv1S{L(Boay`RiXAh4`C<)2EviAAUT}u@nJ}H zdoh5b_aXq#fuj9_gMhl)j{%n!6zJx-6tV_QXQHcyF^-dSt0f%I%&e}DlSwROT6TZV JvhaV_zXAN>JUsva diff --git a/resources/lsi-adm-3a/adm3a.sfd b/resources/lsi-adm-3a/adm3a.sfd index fc5f1f10c..5143e517b 100644 --- a/resources/lsi-adm-3a/adm3a.sfd +++ b/resources/lsi-adm-3a/adm3a.sfd @@ -23,7 +23,7 @@ OS2Version: 0 OS2_WeightWidthSlopeOnly: 0 OS2_UseTypoMetrics: 1 CreationTime: 1663397476 -ModificationTime: 1668346681 +ModificationTime: 1668843247 PfmFamily: 49 TTFWeight: 400 TTFWidth: 5 @@ -54,7 +54,7 @@ NameList: AGL For New Fonts DisplaySize: -48 AntiAlias: 1 FitToEm: 0 -WinInfo: 0 25 19 +WinInfo: 0 17 19 BeginPrivate: 0 EndPrivate Grid @@ -238,19 +238,19 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 109 0 2048 256 256 +Image2: image/png 109 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CJNffG9V\638 I#?hhE%++NJ5$W1!d$Ar-pX+%R0ZlE9bO6%!;2fj%l9/)_#OH8!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -437 1792 m 9,0,-1 - 1280 949 l 25,1,-1 - 1280 843 l 25,2,-1 - 437 0 l 24,3,-1 - 256 0 l 25,4,-1 - 256 1792 l 25,5,6 - 256 1792 256 1792 437 1792 c 9,0,-1 +181 1792 m 9,0,-1 + 1024 949 l 25,1,-1 + 1024 843 l 25,2,-1 + 181 0 l 24,3,-1 + 0 0 l 25,4,-1 + 0 1792 l 25,5,6 + 0 1792 0 1792 181 1792 c 9,0,-1 EndSplineSet Validated: 1 EndChar @@ -1279,22 +1279,22 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 96 0 2048 256 256 +Image2: image/png 96 -512 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ $;a-Q3:p1#b;4)ri:7$O`M*SJUBW=Iz8OZBBY!QNJ EndImage2 Fore SplineSet -512 256 m 29,0,-1 - 768 256 l 25,1,-1 - 768 0 l 25,2,-1 - 512 0 l 25,3,-1 - 512 256 l 29,0,-1 -512 1792 m 25,4,-1 - 768 1792 l 25,5,-1 - 768 512 l 25,6,-1 - 512 512 l 25,7,-1 - 512 1792 l 25,4,-1 +0 256 m 29,0,-1 + 256 256 l 25,1,-1 + 256 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 29,0,-1 +0 1792 m 25,4,-1 + 256 1792 l 25,5,-1 + 256 512 l 25,6,-1 + 0 512 l 25,7,-1 + 0 1792 l 25,4,-1 EndSplineSet Validated: 1 EndChar @@ -1306,22 +1306,22 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 103 0 2048 256 256 +Image2: image/png 103 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8CJNffG9X9;!; Ws:.?(-lLG<5;%h)pjR5jqG+RTE5*=0F/+t#&COF!!!!j78?7R6=>BF EndImage2 Fore SplineSet -768 1792 m 24,0,-1 - 1024 1792 l 24,1,-1 - 1024 1024 l 25,2,-1 - 768 1024 l 25,3,4 - 768 1024 768 1024 768 1792 c 24,0,-1 -256 1792 m 24,5,-1 - 512 1792 l 24,6,-1 - 512 1024 l 25,7,-1 - 256 1024 l 25,8,9 - 256 1024 256 1024 256 1792 c 24,5,-1 +512 1792 m 24,0,-1 + 768 1792 l 24,1,-1 + 768 1024 l 25,2,-1 + 512 1024 l 25,3,4 + 512 1024 512 1024 512 1792 c 24,0,-1 +0 1792 m 24,5,-1 + 256 1792 l 24,6,-1 + 256 1024 l 25,7,-1 + 0 1024 l 25,8,9 + 0 1024 0 1024 0 1792 c 24,5,-1 EndSplineSet Validated: 1 EndChar @@ -1532,17 +1532,17 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 100 0 2048 256 256 +Image2: image/png 100 -512 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CNNffG9`^HNZ $;a-Q35d>_jV6]K5dD/Z8^IS?MP^UeJpj^tz8OZBBY!QNJ EndImage2 Fore SplineSet -512 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 1024 l 25,2,-1 - 512 1024 l 25,3,-1 - 512 1792 l 25,0,-1 +0 1792 m 25,0,-1 + 256 1792 l 25,1,-1 + 256 1024 l 25,2,-1 + 0 1024 l 25,3,-1 + 0 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -1582,23 +1582,23 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 113 0 2048 256 256 +Image2: image/png 113 -512 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8CNNffG9`^HNZ $:"f(;Zp/%dY:I.M?4KuTcDJpJD>\C.C]]:,XJj=!8p-S&*9"7QiI*d!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -711 1792 m 25,0,-1 - 1280 1205 l 24,1,-1 - 1280 587 l 25,2,-1 - 693 0 l 25,3,-1 - 512 0 l 25,4,-1 - 512 182 l 24,5,-1 - 1024 693 l 24,6,-1 - 1024 1099 l 25,7,-1 - 512 1611 l 25,8,-1 - 512 1792 l 25,9,-1 - 711 1792 l 25,0,-1 +199 1792 m 25,0,-1 + 768 1205 l 24,1,-1 + 768 587 l 25,2,-1 + 181 0 l 25,3,-1 + 0 0 l 25,4,-1 + 0 182 l 24,5,-1 + 512 693 l 24,6,-1 + 512 1099 l 25,7,-1 + 0 1611 l 25,8,-1 + 0 1792 l 25,9,-1 + 199 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -1610,36 +1610,36 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 120 1 2048 256 256 +Image2: image/png 120 0 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NS=d?+:(?(s8UE1_?!r( 0@O3sp7:lE5a0,I0O/kjXQZH=DE#=``RHUM5,j"b$(RZ9N"(d-mz8OZBBY!QNJ EndImage2 Fore SplineSet -822 896 m 1,0,1 - 1272 454 1272 454 1281 437 c 0,2,3 - 1281 437 1281 437 1281 256 c 25,4,5 - 1281 256 1281 256 1100 256 c 24,6,7 - 1100 256 1100 256 769 587 c 25,8,-1 - 769 0 l 25,9,-1 - 513 0 l 25,10,-1 - 513 587 l 25,11,-1 - 182 256 l 17,12,13 - 1 256 1 256 1 256 c 25,14,15 - 1 437 1 437 1 437 c 130,-1,16 - 1 437 1 437 460 896 c 1,17,18 - 460 896 460 896 1 1355 c 1,19,20 - 1 1536 1 1536 1 1536 c 152,-1,21 - 1 1536 1 1536 182 1536 c 24,22,23 - 182 1536 182 1536 513 1205 c 24,24,25 - 513 1205 513 1205 513 1792 c 25,26,-1 - 769 1792 l 25,27,-1 - 769 1205 l 0,28,-1 - 1099 1536 l 24,29,30 - 1099 1536 1099 1536 1281 1536 c 0,31,32 - 1281 1536 1281 1536 1281 1355 c 1,33,34 - 1281 1355 1281 1355 822 896 c 1,0,1 +821 896 m 1,0,1 + 1271 454 1271 454 1280 437 c 0,2,3 + 1280 437 1280 437 1280 256 c 25,4,5 + 1280 256 1280 256 1099 256 c 24,6,7 + 1099 256 1099 256 768 587 c 25,8,-1 + 768 0 l 25,9,-1 + 512 0 l 25,10,-1 + 512 587 l 25,11,-1 + 181 256 l 17,12,13 + 0 256 0 256 0 256 c 25,14,15 + 0 437 0 437 0 437 c 130,-1,16 + 0 437 0 437 459 896 c 1,17,18 + 459 896 459 896 0 1355 c 1,19,20 + 0 1536 0 1536 0 1536 c 152,-1,21 + 0 1536 0 1536 181 1536 c 24,22,23 + 181 1536 181 1536 512 1205 c 24,24,25 + 512 1205 512 1205 512 1792 c 25,26,-1 + 768 1792 l 25,27,-1 + 768 1205 l 0,28,-1 + 1098 1536 l 24,29,30 + 1098 1536 1098 1536 1280 1536 c 0,31,32 + 1280 1536 1280 1536 1280 1355 c 1,33,34 + 1280 1355 1280 1355 821 896 c 1,0,1 EndSplineSet Validated: 1 EndChar @@ -1681,21 +1681,21 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 91 0 2048 256 256 +Image2: image/png 91 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2\'ehBu @W`0#D?/q@j]_^nKa/-g/b(@l!!!!j78?7R6=>BF EndImage2 Fore SplineSet -768 331 m 0,0,1 - 768 0 768 0 437 0 c 24,2,-1 - 256 0 l 25,3,-1 - 256 256 l 25,4,-1 - 437 256 l 0,5,6 - 512 256 512 256 512 331 c 24,7,-1 - 512 768 l 24,8,-1 - 768 768 l 24,9,10 - 768 384 768 384 768 331 c 0,0,1 +512 331 m 0,0,1 + 512 0 512 0 181 0 c 24,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,4,-1 + 181 256 l 0,5,6 + 256 256 256 256 256 331 c 24,7,-1 + 256 768 l 24,8,-1 + 512 768 l 24,9,10 + 512 384 512 384 512 331 c 0,0,1 EndSplineSet Validated: 1 EndChar @@ -1729,17 +1729,17 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 84 0 2048 256 256 +Image2: image/png 84 -512 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[;S^Ap Lt+im)m]YX6<>Toz8OZBBY!QNJ EndImage2 Fore SplineSet -512 256 m 29,0,-1 - 768 256 l 25,1,-1 - 768 0 l 25,2,-1 - 512 0 l 25,3,-1 - 512 256 l 29,0,-1 +0 256 m 29,0,-1 + 256 256 l 25,1,-1 + 256 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 29,0,-1 EndSplineSet Validated: 1 EndChar @@ -1814,33 +1814,33 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 107 0 2048 256 256 +Image2: image/png 107 -211 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CNNffG9`^HN: $?/Rg<.YkCZNY4MMRc7t.Ofm.&k4,!^]4B4!='>cmbYYX!!!!j78?7R6=>BF EndImage2 Fore SplineSet -512 1734 m 0,0,1 - 569 1792 569 1792 640 1792 c 128,-1,2 - 711 1792 711 1792 768 1734 c 8,3,-1 - 768 331 l 0,4,5 - 768 256 768 256 842 256 c 24,6,-1 - 949 256 l 0,7,8 - 1024 199 1024 199 1024 126 c 0,9,10 - 1024 75 1024 75 949 0 c 1,11,12 - 949 0 949 0 331 0 c 0,13,14 - 256 75 256 75 256 128 c 0,15,16 - 256 199 256 199 331 256 c 8,17,-1 - 437 256 l 0,18,19 - 512 256 512 256 512 331 c 24,20,21 - 512 1205 512 1205 512 1205 c 0,22,23 - 512 1280 512 1280 437 1280 c 24,24,-1 - 256 1280 l 17,25,26 - 211 1344 211 1344 211 1408 c 128,-1,27 - 211 1472 211 1472 256 1536 c 8,28,-1 - 437 1536 l 0,29,30 - 512 1536 512 1536 512 1611 c 24,31,-1 - 512 1734 l 0,0,1 +301 1734 m 0,0,1 + 358 1792 358 1792 429 1792 c 128,-1,2 + 500 1792 500 1792 557 1734 c 8,3,-1 + 557 331 l 0,4,5 + 557 256 557 256 631 256 c 24,6,-1 + 738 256 l 0,7,8 + 813 199 813 199 813 126 c 0,9,10 + 813 75 813 75 738 0 c 1,11,12 + 738 0 738 0 120 0 c 0,13,14 + 45 75 45 75 45 128 c 0,15,16 + 45 199 45 199 120 256 c 8,17,-1 + 226 256 l 0,18,19 + 301 256 301 256 301 331 c 24,20,21 + 301 1205 301 1205 301 1205 c 0,22,23 + 301 1280 301 1280 226 1280 c 24,24,-1 + 45 1280 l 17,25,26 + 0 1344 0 1344 0 1408 c 128,-1,27 + 0 1472 0 1472 45 1536 c 8,28,-1 + 226 1536 l 0,29,30 + 301 1536 301 1536 301 1611 c 24,31,-1 + 301 1734 l 0,0,1 EndSplineSet Validated: 1 EndChar @@ -2181,22 +2181,22 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 97 0 2048 256 256 +Image2: image/png 97 -512 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns4f$5aWu Yo3g*!LHaC$7Ih6Wrmm(!&@FZ$m].ZLh)ch@bW1UUYoz8OZBBY!QNJ EndImage2 Fore SplineSet -768 768 m 24,0,1 - 768 768 768 768 768 331 c 0,2,3 - 768 0 768 0 437 0 c 24,4,-1 - 256 0 l 25,5,-1 - 256 256 l 25,6,-1 - 437 256 l 0,7,8 - 512 256 512 256 512 331 c 24,9,-1 - 512 768 l 24,10,11 - 512 768 512 768 768 768 c 24,0,1 -512 1280 m 25,12,-1 - 768 1280 l 25,13,-1 - 768 1024 l 25,14,-1 - 512 1024 l 25,15,-1 - 512 1280 l 25,12,-1 +512 768 m 24,0,1 + 512 768 512 768 512 331 c 0,2,3 + 512 0 512 0 181 0 c 24,4,-1 + 0 0 l 25,5,-1 + 0 256 l 25,6,-1 + 181 256 l 0,7,8 + 256 256 256 256 256 331 c 24,9,-1 + 256 768 l 24,10,11 + 256 768 256 768 512 768 c 24,0,1 +256 1280 m 25,12,-1 + 512 1280 l 25,13,-1 + 512 1024 l 25,14,-1 + 256 1024 l 25,15,-1 + 256 1280 l 25,12,-1 EndSplineSet Validated: 1 EndChar @@ -2293,22 +2293,22 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 114 0 2048 256 256 +Image2: image/png 114 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?L$c9Vp?+:&'8li7!DD@\!2 /(Y77eXll!"%j1]?p11f#p"OPpWj:T+ftqt">",1((Z@:V:5JF!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -971 896 m 129,-1,1 - 971 896 971 896 256 1611 c 1,2,-1 - 256 1792 l 25,3,4 - 437 1792 437 1792 437 1792 c 24,5,6 - 1280 949 1280 949 1280 949 c 25,7,8 - 1280 843 1280 843 1280 843 c 25,9,10 - 437 0 437 0 437 0 c 24,11,12 - 256 0 256 0 256 0 c 25,13,14 - 256 181 256 181 256 181 c 0,15,0 - 971 896 971 896 971 896 c 129,-1,1 +715 896 m 129,-1,1 + 715 896 715 896 0 1611 c 1,2,-1 + 0 1792 l 25,3,4 + 181 1792 181 1792 181 1792 c 24,5,6 + 1024 949 1024 949 1024 949 c 25,7,8 + 1024 843 1024 843 1024 843 c 25,9,10 + 181 0 181 0 181 0 c 24,11,12 + 0 0 0 0 0 0 c 25,13,14 + 0 181 0 181 0 181 c 0,15,0 + 715 896 715 896 715 896 c 129,-1,1 EndSplineSet Validated: 1 EndChar @@ -2677,25 +2677,25 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 106 0 2048 256 256 +Image2: image/png 106 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8+BNffG9Xor#n '1`BF EndImage2 Fore SplineSet -768 768 m 1,0,1 - 768 768 768 768 569 768 c 1,2,3 - 512 768 512 768 512 711 c 1,4,5 - 512 711 512 711 512 569 c 1,6,7 - 512 512 512 512 569 512 c 1,8,9 - 569 512 569 512 768 512 c 1,10,11 - 768 512 768 512 768 768 c 1,0,1 -569 256 m 2,12,13 - 256 256 256 256 256 569 c 0,14,15 - 256 640 256 640 256 711 c 0,16,17 - 256 1024 256 1024 569 1024 c 2,18,19 - 569 1024 569 1024 768 1024 c 1,20,21 - 768 1024 768 1024 768 1223 c 1,22,23 - 768 1280 768 1280 711 1280 c 1,24,25 - 711 1280 711 1280 313 1280 c 0,26,27 - 256 1337 256 1337 256 1408 c 0,28,29 - 256 1465 256 1465 313 1536 c 0,30,31 - 313 1536 313 1536 711 1536 c 0,32,33 - 1024 1536 1024 1536 1024 1223 c 0,34,35 - 1024 1202 1024 1202 1024 512 c 1,36,-1 - 1223 512 l 0,37,38 - 1280 446 1280 446 1280 382 c 128,-1,39 - 1280 318 1280 318 1223 256 c 0,40,-1 - 569 256 l 2,12,13 +512 768 m 1,0,1 + 512 768 512 768 313 768 c 1,2,3 + 256 768 256 768 256 711 c 1,4,5 + 256 711 256 711 256 569 c 1,6,7 + 256 512 256 512 313 512 c 1,8,9 + 313 512 313 512 512 512 c 1,10,11 + 512 512 512 512 512 768 c 1,0,1 +313 256 m 2,12,13 + 0 256 0 256 0 569 c 0,14,15 + 0 640 0 640 0 711 c 0,16,17 + 0 1024 0 1024 313 1024 c 2,18,19 + 313 1024 313 1024 512 1024 c 1,20,21 + 512 1024 512 1024 512 1223 c 1,22,23 + 512 1280 512 1280 455 1280 c 1,24,25 + 455 1280 455 1280 57 1280 c 0,26,27 + 0 1337 0 1337 0 1408 c 0,28,29 + 0 1465 0 1465 57 1536 c 0,30,31 + 57 1536 57 1536 455 1536 c 0,32,33 + 768 1536 768 1536 768 1223 c 0,34,35 + 768 1202 768 1202 768 512 c 1,36,-1 + 967 512 l 0,37,38 + 1024 446 1024 446 1024 382 c 128,-1,39 + 1024 318 1024 318 967 256 c 0,40,-1 + 313 256 l 2,12,13 EndSplineSet Validated: 1 EndChar @@ -3510,27 +3510,27 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 113 0 2048 256 256 +Image2: image/png 113 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns2*9E?@_ ,E0`pCa`Bd8.o&:XqJeuBE^[*?n4L^j)kIF:0_Z:!.;!a%Z2pI[/^1,!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -256 1223 m 1,0,1 - 256 1536 256 1536 569 1536 c 1,2,3 - 569 1536 569 1536 1223 1536 c 0,4,5 - 1280 1467 1280 1467 1280 1403 c 128,-1,6 - 1280 1339 1280 1339 1223 1280 c 0,7,-1 - 569 1280 l 1,8,9 - 512 1280 512 1280 512 1223 c 1,10,11 - 512 1223 512 1223 512 569 c 1,12,13 - 512 512 512 512 569 512 c 1,14,15 - 569 512 569 512 1223 512 c 0,16,17 - 1278 446 1278 446 1278 382 c 128,-1,18 - 1278 318 1278 318 1223 256 c 0,19,-1 - 569 256 l 0,20,21 - 256 256 256 256 256 569 c 1,22,23 - 256 896 256 896 256 1223 c 1,0,1 +0 1223 m 1,0,1 + 0 1536 0 1536 313 1536 c 1,2,3 + 313 1536 313 1536 967 1536 c 0,4,5 + 1024 1467 1024 1467 1024 1403 c 128,-1,6 + 1024 1339 1024 1339 967 1280 c 0,7,-1 + 313 1280 l 1,8,9 + 256 1280 256 1280 256 1223 c 1,10,11 + 256 1223 256 1223 256 569 c 1,12,13 + 256 512 256 512 313 512 c 1,14,15 + 313 512 313 512 967 512 c 0,16,17 + 1022 446 1022 446 1022 382 c 128,-1,18 + 1022 318 1022 318 967 256 c 0,19,-1 + 313 256 l 0,20,21 + 0 256 0 256 0 569 c 1,22,23 + 0 896 0 896 0 1223 c 1,0,1 EndSplineSet Validated: 1 EndChar @@ -3580,36 +3580,36 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 115 0 2048 256 256 +Image2: image/png 115 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3&!@&g6 !skY(YQBmhaBF EndImage2 Fore SplineSet -949 1024 m 0,0,1 - 1024 1024 1024 1024 1024 1099 c 2,2,3 - 1024 1099 1024 1099 1024 1205 c 1,4,5 - 1024 1280 1024 1280 949 1280 c 1,6,7 - 768 1280 768 1280 587 1280 c 0,8,9 - 512 1280 512 1280 512 1205 c 1,10,11 - 512 1143 512 1143 512 1081 c 0,12,13 - 512 1024 512 1024 569 1024 c 1,14,15 - 759 1024 759 1024 949 1024 c 0,0,1 -256 1205 m 0,16,17 - 256 1536 256 1536 587 1536 c 1,18,19 - 587 1536 587 1536 949 1536 c 1,20,21 - 1280 1536 1280 1536 1280 1205 c 0,22,23 - 1280 1205 1280 1205 1280 1099 c 0,24,25 - 1280 768 1280 768 949 768 c 0,26,-1 - 512 768 l 1,27,28 - 512 595 512 595 512 587 c 0,29,30 - 512 512 512 512 587 512 c 1,31,32 - 967 512 967 512 967 512 c 0,33,34 - 1024 512 1024 512 1024 384 c 128,-1,35 - 1024 256 1024 256 967 256 c 0,36,-1 - 587 256 l 0,37,38 - 256 256 256 256 256 587 c 1,39,40 - 256 896 256 896 256 1205 c 0,16,17 +693 1024 m 0,0,1 + 768 1024 768 1024 768 1099 c 2,2,3 + 768 1099 768 1099 768 1205 c 1,4,5 + 768 1280 768 1280 693 1280 c 1,6,7 + 512 1280 512 1280 331 1280 c 0,8,9 + 256 1280 256 1280 256 1205 c 1,10,11 + 256 1143 256 1143 256 1081 c 0,12,13 + 256 1024 256 1024 313 1024 c 1,14,15 + 503 1024 503 1024 693 1024 c 0,0,1 +0 1205 m 0,16,17 + 0 1536 0 1536 331 1536 c 1,18,19 + 331 1536 331 1536 693 1536 c 1,20,21 + 1024 1536 1024 1536 1024 1205 c 0,22,23 + 1024 1205 1024 1205 1024 1099 c 0,24,25 + 1024 768 1024 768 693 768 c 0,26,-1 + 256 768 l 1,27,28 + 256 595 256 595 256 587 c 0,29,30 + 256 512 256 512 331 512 c 1,31,32 + 711 512 711 512 711 512 c 0,33,34 + 768 512 768 512 768 384 c 128,-1,35 + 768 256 768 256 711 256 c 0,36,-1 + 331 256 l 0,37,38 + 0 256 0 256 0 587 c 1,39,40 + 0 896 0 896 0 1205 c 0,16,17 EndSplineSet Validated: 1 EndChar @@ -3621,36 +3621,36 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 122 0 2048 256 256 +Image2: image/png 122 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8D_*$Z[Q1)J/h .f`.m$q")!&*pF_RK]>[bNg-Et!!nC@e,oG/"i0\g1=!!!!j78?7R 6=>BF EndImage2 Fore SplineSet -1024 1223 m 1,0,1 - 1024 1280 1024 1280 967 1280 c 1,2,3 - 967 1280 967 1280 569 1280 c 0,4,5 - 512 1280 512 1280 512 1223 c 1,6,7 - 512 1223 512 1223 512 825 c 1,8,9 - 512 768 512 768 569 768 c 1,10,11 - 967 768 967 768 967 768 c 0,12,13 - 1024 768 1024 768 1024 825 c 1,14,15 - 1024 825 1024 825 1024 1223 c 1,0,1 -569 512 m 2,16,17 - 256 512 256 512 256 825 c 0,18,19 - 256 825 256 825 256 1223 c 0,20,21 - 256 1536 256 1536 569 1536 c 0,22,23 - 768 1536 768 1536 967 1536 c 1,24,25 - 1280 1536 1280 1536 1280 1223 c 0,26,27 - 1280 612 1280 612 1280 313 c 0,28,29 - 1280 0 1280 0 967 0 c 1,30,31 - 967 0 967 0 512 0 c 1,32,-1 - 512 256 l 1,33,-1 - 967 256 l 1,34,35 - 1024 256 1024 256 1024 313 c 1,36,37 - 1024 413 1024 413 1024 512 c 1,38,-1 - 569 512 l 2,16,17 +768 1223 m 1,0,1 + 768 1280 768 1280 711 1280 c 1,2,3 + 711 1280 711 1280 313 1280 c 0,4,5 + 256 1280 256 1280 256 1223 c 1,6,7 + 256 1223 256 1223 256 825 c 1,8,9 + 256 768 256 768 313 768 c 1,10,11 + 711 768 711 768 711 768 c 0,12,13 + 768 768 768 768 768 825 c 1,14,15 + 768 825 768 825 768 1223 c 1,0,1 +313 512 m 2,16,17 + 0 512 0 512 0 825 c 0,18,19 + 0 825 0 825 0 1223 c 0,20,21 + 0 1536 0 1536 313 1536 c 0,22,23 + 512 1536 512 1536 711 1536 c 1,24,25 + 1024 1536 1024 1536 1024 1223 c 0,26,27 + 1024 612 1024 612 1024 313 c 0,28,29 + 1024 0 1024 0 711 0 c 1,30,31 + 711 0 711 0 256 0 c 1,32,-1 + 256 256 l 1,33,-1 + 711 256 l 1,34,35 + 768 256 768 256 768 313 c 1,36,37 + 768 413 768 413 768 512 c 1,38,-1 + 313 512 l 2,16,17 EndSplineSet Validated: 1 EndChar @@ -3703,26 +3703,26 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 110 0 2048 256 256 +Image2: image/png 110 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8CJNffG9V\638 S?bBd\,qa@fM$lI!'(49d1sJ4i3J*1!_,N5"9Oqn#t!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -967 1280 m 17,0,1 - 1280 1280 1280 1280 1280 967 c 0,2,3 - 1280 836 1280 836 1280 256 c 25,4,-1 - 1024 256 l 1,5,-1 - 1024 967 l 1,6,7 - 1024 1024 1024 1024 967 1024 c 1,8,9 - 967 1024 967 1024 512 1024 c 1,10,-1 - 512 256 l 25,11,-1 - 256 256 l 1,12,-1 - 256 1734 l 0,13,14 - 326 1792 326 1792 390 1792 c 128,-1,15 - 454 1792 454 1792 512 1734 c 8,16,-1 - 512 1280 l 1,17,-1 - 967 1280 l 17,0,1 +711 1280 m 17,0,1 + 1024 1280 1024 1280 1024 967 c 0,2,3 + 1024 836 1024 836 1024 256 c 25,4,-1 + 768 256 l 1,5,-1 + 768 967 l 1,6,7 + 768 1024 768 1024 711 1024 c 1,8,9 + 711 1024 711 1024 256 1024 c 1,10,-1 + 256 256 l 25,11,-1 + 0 256 l 1,12,-1 + 0 1734 l 0,13,14 + 70 1792 70 1792 134 1792 c 128,-1,15 + 198 1792 198 1792 256 1734 c 8,16,-1 + 256 1280 l 1,17,-1 + 711 1280 l 17,0,1 EndSplineSet Validated: 1 EndChar @@ -3734,29 +3734,29 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 114 0 2048 256 256 +Image2: image/png 114 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HNZ $?-jc=$Y+8'Q]BrE"e>O:mbVo0]QRuZ3h?Y#F>NYEWDm9$5>J927EPc!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -512 1223 m 0,0,1 - 569 1280 569 1280 639 1280 c 1,2,3 - 711 1280 711 1280 768 1223 c 1,4,-1 - 768 569 l 0,5,6 - 768 512 768 512 824 512 c 24,7,-1 - 1024 512 l 1,8,-1 - 1024 256 l 25,9,-1 - 256 256 l 25,10,-1 - 256 512 l 1,11,-1 - 454 512 l 0,12,13 - 512 512 512 512 512 569 c 16,14,15 - 512 569 512 569 512 1223 c 0,0,1 -512 1792 m 24,16,-1 - 768 1792 l 24,17,-1 - 768 1536 l 25,18,-1 - 512 1536 l 25,19,20 - 512 1536 512 1536 512 1792 c 24,16,-1 +256 1223 m 0,0,1 + 313 1280 313 1280 383 1280 c 1,2,3 + 455 1280 455 1280 512 1223 c 1,4,-1 + 512 569 l 0,5,6 + 512 512 512 512 568 512 c 24,7,-1 + 768 512 l 1,8,-1 + 768 256 l 25,9,-1 + 0 256 l 25,10,-1 + 0 512 l 1,11,-1 + 198 512 l 0,12,13 + 256 512 256 512 256 569 c 16,14,15 + 256 569 256 569 256 1223 c 0,0,1 +256 1792 m 24,16,-1 + 512 1792 l 24,17,-1 + 512 1536 l 25,18,-1 + 256 1536 l 25,19,20 + 256 1536 256 1536 256 1792 c 24,16,-1 EndSplineSet Validated: 1 EndChar @@ -3768,32 +3768,32 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 112 0 2048 256 256 +Image2: image/png 112 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8D_*$Z[Q1)J/( ;1QnF'EnV6^b?iYJ78RT"k\cg.0c7AEZ@U^2FdfKcm&u1G:MDDz8OZBBY!QNJ EndImage2 Fore SplineSet -768 1792 m 25,0,-1 - 1024 1792 l 25,1,-1 - 1024 1536 l 25,2,-1 - 768 1536 l 25,3,-1 - 768 1792 l 25,0,-1 -1024 313 m 0,4,5 - 1024 2 1024 2 711 0 c 0,6,7 - 711 0 711 0 569 0 c 0,8,9 - 256 0 256 0 256 313 c 0,10,11 - 256 313 256 313 256 455 c 0,12,13 - 313 512 313 512 378 512 c 0,14,15 - 454 512 454 512 512 455 c 0,16,-1 - 512 302 l 0,17,18 - 512 256 512 256 569 256 c 0,19,20 - 640 256 640 256 711 256 c 0,21,22 - 768 256 768 256 768 302 c 0,23,24 - 768 302 768 302 768 1223 c 0,25,26 - 830 1280 830 1280 893 1280 c 0,27,28 - 958 1280 958 1280 1024 1223 c 0,29,30 - 1024 1223 1024 1223 1024 313 c 0,4,5 +512 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 1536 l 25,2,-1 + 512 1536 l 25,3,-1 + 512 1792 l 25,0,-1 +768 313 m 0,4,5 + 768 2 768 2 455 0 c 0,6,7 + 455 0 455 0 313 0 c 0,8,9 + 0 0 0 0 0 313 c 0,10,11 + 0 313 0 313 0 455 c 0,12,13 + 57 512 57 512 122 512 c 0,14,15 + 198 512 198 512 256 455 c 0,16,-1 + 256 302 l 0,17,18 + 256 256 256 256 313 256 c 0,19,20 + 384 256 384 256 455 256 c 0,21,22 + 512 256 512 256 512 302 c 0,23,24 + 512 302 512 302 512 1223 c 0,25,26 + 574 1280 574 1280 637 1280 c 0,27,28 + 702 1280 702 1280 768 1223 c 0,29,30 + 768 1223 768 1223 768 313 c 0,4,5 EndSplineSet Validated: 1 EndChar @@ -3805,28 +3805,28 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 116 0 2048 256 256 +Image2: image/png 116 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9V\638 A6F#n-ji5&kVg9m@$:_]$s*GWM/GG5!Y>U+,"A4J?>flF>MTu&gl3mSz8OZBBY!QNJ EndImage2 Fore SplineSet -569 1024 m 17,0,1 - 569 1024 569 1024 1081 1536 c 1,2,-1 - 1280 1536 l 1,3,-1 - 1280 1337 l 1,4,-1 - 839 896 l 1,5,6 - 839 896 839 896 1280 455 c 1,7,-1 - 1280 256 l 1,8,-1 - 1081 256 l 1,9,-1 - 569 768 l 1,10,11 - 569 768 569 768 512 768 c 25,12,-1 - 512 256 l 25,13,-1 - 256 256 l 25,14,-1 - 256 1792 l 25,15,-1 - 512 1792 l 25,16,-1 - 512 1024 l 25,17,-1 - 569 1024 l 17,0,1 +313 1024 m 17,0,1 + 313 1024 313 1024 825 1536 c 1,2,-1 + 1024 1536 l 1,3,-1 + 1024 1337 l 1,4,-1 + 583 896 l 1,5,6 + 583 896 583 896 1024 455 c 1,7,-1 + 1024 256 l 1,8,-1 + 825 256 l 1,9,-1 + 313 768 l 1,10,11 + 313 768 313 768 256 768 c 25,12,-1 + 256 256 l 25,13,-1 + 0 256 l 25,14,-1 + 0 1792 l 25,15,-1 + 256 1792 l 25,16,-1 + 256 1024 l 25,17,-1 + 313 1024 l 17,0,1 EndSplineSet Validated: 1 EndChar @@ -3838,23 +3838,23 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 108 0 2048 256 256 +Image2: image/png 108 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8CJNffG9N3T>a /&5d'=91=N0JP%+!'(Yp?o6)P&Bt8#n2V*]Yf@(bT*B[=z8OZBBY!QNJ EndImage2 Fore SplineSet -256 1792 m 24,0,-1 - 768 1792 l 24,1,-1 - 768 512 l 25,2,-1 - 1024 512 l 25,3,-1 - 1024 256 l 25,4,-1 - 256 256 l 25,5,-1 - 256 512 l 25,6,-1 - 512 512 l 25,7,-1 - 512 1536 l 25,8,-1 - 256 1536 l 25,9,10 - 256 1536 256 1536 256 1792 c 24,0,-1 +0 1792 m 24,0,-1 + 512 1792 l 24,1,-1 + 512 512 l 25,2,-1 + 768 512 l 25,3,-1 + 768 256 l 25,4,-1 + 0 256 l 25,5,-1 + 0 512 l 25,6,-1 + 256 512 l 25,7,-1 + 256 1536 l 25,8,-1 + 0 1536 l 25,9,10 + 0 1536 0 1536 0 1792 c 24,0,-1 EndSplineSet Validated: 1 EndChar @@ -3904,23 +3904,23 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 110 0 2048 256 256 +Image2: image/png 110 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns2*Lh(%, KW@I!&8hP?!ec[NK64pE^l:Th:p,<\BJ3\1!WY^j&I&QkSpLG;!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -967 1536 m 17,0,1 - 1280 1536 1280 1536 1280 1223 c 1,2,3 - 1280 683 1280 683 1280 256 c 25,4,-1 - 1024 256 l 1,5,-1 - 1024 1223 l 1,6,7 - 1024 1280 1024 1280 967 1280 c 1,8,9 - 967 1280 967 1280 512 1280 c 1,10,-1 - 512 256 l 25,11,-1 - 256 256 l 25,12,-1 - 256 1536 l 1,13,-1 - 967 1536 l 17,0,1 +711 1536 m 17,0,1 + 1024 1536 1024 1536 1024 1223 c 1,2,3 + 1024 683 1024 683 1024 256 c 25,4,-1 + 768 256 l 1,5,-1 + 768 1223 l 1,6,7 + 768 1280 768 1280 711 1280 c 1,8,9 + 711 1280 711 1280 256 1280 c 1,10,-1 + 256 256 l 25,11,-1 + 0 256 l 25,12,-1 + 0 1536 l 1,13,-1 + 711 1536 l 17,0,1 EndSplineSet Validated: 1 EndChar @@ -3932,30 +3932,30 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 119 0 2048 256 256 +Image2: image/png 119 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8Bu3Ns3&!@&g6 !skY(YQBmhapkS,:]Uqp-*kq^ScUEm.=rFq9EP8Yq@aDRRWI9b!!!!j78?7R6=>BF EndImage2 Fore SplineSet -1024 1223 m 1,0,1 - 1024 1280 1024 1280 967 1280 c 1,2,3 - 953 1280 953 1280 569 1280 c 0,4,5 - 512 1280 512 1280 512 1223 c 1,6,7 - 512 1223 512 1223 512 569 c 1,8,9 - 512 512 512 512 569 512 c 1,10,11 - 569 512 569 512 967 512 c 0,12,13 - 1024 512 1024 512 1024 569 c 1,14,15 - 1024 569 1024 569 1024 1223 c 1,0,1 -256 1223 m 0,16,17 - 256 1536 256 1536 583 1536 c 1,18,19 - 775 1536 775 1536 967 1536 c 1,20,21 - 1280 1536 1280 1536 1280 1223 c 0,22,23 - 1280 691 1280 691 1280 569 c 0,24,25 - 1280 256 1280 256 967 256 c 1,26,27 - 768 256 768 256 569 256 c 1,28,29 - 256 256 256 256 256 569 c 0,30,31 - 256 1056 256 1056 256 1223 c 0,16,17 +768 1223 m 1,0,1 + 768 1280 768 1280 711 1280 c 1,2,3 + 697 1280 697 1280 313 1280 c 0,4,5 + 256 1280 256 1280 256 1223 c 1,6,7 + 256 1223 256 1223 256 569 c 1,8,9 + 256 512 256 512 313 512 c 1,10,11 + 313 512 313 512 711 512 c 0,12,13 + 768 512 768 512 768 569 c 1,14,15 + 768 569 768 569 768 1223 c 1,0,1 +0 1223 m 0,16,17 + 0 1536 0 1536 327 1536 c 1,18,19 + 519 1536 519 1536 711 1536 c 1,20,21 + 1024 1536 1024 1536 1024 1223 c 0,22,23 + 1024 691 1024 691 1024 569 c 0,24,25 + 1024 256 1024 256 711 256 c 1,26,27 + 512 256 512 256 313 256 c 1,28,29 + 0 256 0 256 0 569 c 0,30,31 + 0 1056 0 1056 0 1223 c 0,16,17 EndSplineSet Validated: 1 EndChar @@ -3967,28 +3967,28 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 118 0 2048 256 256 +Image2: image/png 118 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns2*Lh(%, KW@I!&8hP?!ec[NK64pE^l:ThJ?8g._/uDU!EXe(!AfP)'`_rY'+E&U*NK/?!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -967 768 m 1,0,1 - 1024 768 1024 768 1024 825 c 1,2,3 - 1024 825 1024 825 1024 1223 c 1,4,5 - 1024 1280 1024 1280 967 1280 c 1,6,7 - 967 1280 967 1280 512 1280 c 5,8,9 - 512 1280 512 1280 512 768 c 4,10,11 - 512 768 512 768 967 768 c 1,0,1 -967 1536 m 17,12,13 - 1280 1536 1280 1536 1280 1223 c 0,14,15 - 1280 867 1280 867 1280 825 c 0,16,17 - 1280 512 1280 512 967 512 c 9,18,19 - 967 512 967 512 512 512 c 1,20,-1 - 512 0 l 25,21,-1 - 256 0 l 25,22,-1 - 256 1536 l 1,23,-1 - 967 1536 l 17,12,13 +711 768 m 1,0,1 + 768 768 768 768 768 825 c 1,2,3 + 768 825 768 825 768 1223 c 1,4,5 + 768 1280 768 1280 711 1280 c 1,6,7 + 711 1280 711 1280 256 1280 c 5,8,9 + 256 1280 256 1280 256 768 c 4,10,11 + 256 768 256 768 711 768 c 1,0,1 +711 1536 m 17,12,13 + 1024 1536 1024 1536 1024 1223 c 0,14,15 + 1024 867 1024 867 1024 825 c 0,16,17 + 1024 512 1024 512 711 512 c 9,18,19 + 711 512 711 512 256 512 c 1,20,-1 + 256 0 l 25,21,-1 + 0 0 l 25,22,-1 + 0 1536 l 1,23,-1 + 711 1536 l 17,12,13 EndSplineSet Validated: 1 EndChar @@ -4037,23 +4037,23 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 114 0 2048 256 256 +Image2: image/png 114 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3"!@&g6 Qij'kCm[[-(]u%7br3'HfH`bOiU!pq/^h#XL1]XA\%2#Am_)hVs!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -512 1280 m 1,0,1 - 512 1536 512 1536 824 1536 c 1,2,3 - 824 1536 824 1536 1280 1536 c 1,4,-1 - 1280 1280 l 1,5,-1 - 824 1280 l 1,6,7 - 512 1280 512 1280 512 1024 c 1,8,9 - 512 1024 512 1024 512 256 c 1,10,-1 - 256 256 l 25,11,-1 - 256 1536 l 25,12,-1 - 512 1536 l 25,13,-1 - 512 1280 l 1,0,1 +256 1280 m 1,0,1 + 256 1536 256 1536 568 1536 c 1,2,3 + 568 1536 568 1536 1024 1536 c 1,4,-1 + 1024 1280 l 1,5,-1 + 568 1280 l 1,6,7 + 256 1280 256 1280 256 1024 c 1,8,9 + 256 1024 256 1024 256 256 c 1,10,-1 + 0 256 l 25,11,-1 + 0 1536 l 25,12,-1 + 256 1536 l 25,13,-1 + 256 1280 l 1,0,1 EndSplineSet Validated: 1 EndChar @@ -4065,36 +4065,36 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 122 0 2048 256 256 +Image2: image/png 122 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8Bu3Ns2*Lh(%, 6rA_U-s-L@(0M2O2:r7t,fg[AP<]K6D?),;.7?&pWuE`,i3FH#&-14%((g]?(5Mqj!!#SZ:.26O @"J@Y EndImage2 Fore SplineSet -1280 711 m 0,0,1 - 1280 710 1280 710 1280 569 c 0,2,3 - 1280 256 1280 256 967 256 c 0,4,-1 - 313 256 l 0,5,6 - 256 321 256 321 256 385 c 128,-1,7 - 256 449 256 449 313 512 c 8,8,-1 - 967 512 l 0,9,10 - 1024 512 1024 512 1024 569 c 16,11,12 - 1024 569 1024 569 1024 711 c 0,13,14 - 1024 768 1024 768 967 768 c 0,15,-1 - 569 768 l 0,16,17 - 256 768 256 768 256 1081 c 0,18,19 - 256 1081 256 1081 256 1223 c 0,20,21 - 256 1536 256 1536 569 1536 c 1,22,23 - 569 1536 569 1536 1223 1536 c 0,24,25 - 1280 1467 1280 1467 1280 1403 c 128,-1,26 - 1280 1339 1280 1339 1223 1280 c 1,27,-1 - 569 1280 l 0,28,29 - 512 1280 512 1280 512 1223 c 0,30,31 - 512 1223 512 1223 512 1081 c 0,32,33 - 512 1024 512 1024 569 1024 c 24,34,-1 - 967 1024 l 0,35,36 - 1280 1024 1280 1024 1280 711 c 0,0,1 +1024 711 m 0,0,1 + 1024 710 1024 710 1024 569 c 0,2,3 + 1024 256 1024 256 711 256 c 0,4,-1 + 57 256 l 0,5,6 + 0 321 0 321 0 385 c 128,-1,7 + 0 449 0 449 57 512 c 8,8,-1 + 711 512 l 0,9,10 + 768 512 768 512 768 569 c 16,11,12 + 768 569 768 569 768 711 c 0,13,14 + 768 768 768 768 711 768 c 0,15,-1 + 313 768 l 0,16,17 + 0 768 0 768 0 1081 c 0,18,19 + 0 1081 0 1081 0 1223 c 0,20,21 + 0 1536 0 1536 313 1536 c 1,22,23 + 313 1536 313 1536 967 1536 c 0,24,25 + 1024 1467 1024 1467 1024 1403 c 128,-1,26 + 1024 1339 1024 1339 967 1280 c 1,27,-1 + 313 1280 l 0,28,29 + 256 1280 256 1280 256 1223 c 0,30,31 + 256 1223 256 1223 256 1081 c 0,32,33 + 256 1024 256 1024 313 1024 c 24,34,-1 + 711 1024 l 0,35,36 + 1024 1024 1024 1024 1024 711 c 0,0,1 EndSplineSet Validated: 1 EndChar @@ -4106,32 +4106,32 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 117 0 2048 256 256 +Image2: image/png 117 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CNNffG9`^HN: $=K#N)Hd5G!R);rNM->T!1aRC"1eVo%p&`d*iBrbWj0)8!277@%#@LO^An66!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -768 569 m 1,0,1 - 768 512 768 512 824 512 c 0,2,3 - 824 512 824 512 1024 512 c 1,4,5 - 1024 512 1024 512 1024 256 c 1,6,-1 - 824 256 l 17,7,8 - 512 256 512 256 512 569 c 1,9,10 - 512 1232 512 1232 512 1280 c 1,11,-1 - 313 1280 l 0,12,13 - 256 1342 256 1342 256 1406 c 128,-1,14 - 256 1470 256 1470 313 1536 c 0,15,-1 - 512 1536 l 1,16,-1 - 512 1734 l 0,17,18 - 576 1792 576 1792 640 1792 c 128,-1,19 - 704 1792 704 1792 768 1734 c 8,20,-1 - 768 1536 l 1,21,-1 - 967 1536 l 0,22,23 - 1024 1478 1024 1478 1024 1414 c 128,-1,24 - 1024 1350 1024 1350 967 1280 c 0,25,-1 - 768 1280 l 1,26,-1 - 768 569 l 1,0,1 +512 569 m 1,0,1 + 512 512 512 512 568 512 c 0,2,3 + 568 512 568 512 768 512 c 1,4,5 + 768 512 768 512 768 256 c 1,6,-1 + 568 256 l 17,7,8 + 256 256 256 256 256 569 c 1,9,10 + 256 1232 256 1232 256 1280 c 1,11,-1 + 57 1280 l 0,12,13 + 0 1342 0 1342 0 1406 c 128,-1,14 + 0 1470 0 1470 57 1536 c 0,15,-1 + 256 1536 l 1,16,-1 + 256 1734 l 0,17,18 + 320 1792 320 1792 384 1792 c 128,-1,19 + 448 1792 448 1792 512 1734 c 8,20,-1 + 512 1536 l 1,21,-1 + 711 1536 l 0,22,23 + 768 1478 768 1478 768 1414 c 128,-1,24 + 768 1350 768 1350 711 1280 c 0,25,-1 + 512 1280 l 1,26,-1 + 512 569 l 1,0,1 EndSplineSet Validated: 1 EndChar @@ -4143,25 +4143,25 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 113 0 2048 256 256 +Image2: image/png 113 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns3"!@&g6 >TGR=,Y4F3E:$aE"AN8)B``P_h/8Tg?j/5Q0L94f!#\N='5qJ>+ohTC!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -512 569 m 1,0,1 - 512 512 512 512 569 512 c 1,2,3 - 569 512 569 512 1024 512 c 1,4,-1 - 1024 1466 l 0,5,6 - 1090 1535 1090 1535 1154 1535 c 128,-1,7 - 1218 1535 1218 1535 1279 1465 c 8,8,-1 - 1280 256 l 1,9,-1 - 569 256 l 17,10,11 - 256 256 256 256 256 569 c 1,12,13 - 256 1465 256 1465 256 1465 c 0,14,15 - 313 1536 313 1536 382 1536 c 0,16,17 - 454 1536 454 1536 512 1465 c 0,18,-1 - 512 569 l 1,0,1 +256 569 m 1,0,1 + 256 512 256 512 313 512 c 1,2,3 + 313 512 313 512 768 512 c 1,4,-1 + 768 1466 l 0,5,6 + 834 1535 834 1535 898 1535 c 128,-1,7 + 962 1535 962 1535 1023 1465 c 8,8,-1 + 1024 256 l 1,9,-1 + 313 256 l 17,10,11 + 0 256 0 256 0 569 c 1,12,13 + 0 1465 0 1465 0 1465 c 0,14,15 + 57 1536 57 1536 126 1536 c 0,16,17 + 198 1536 198 1536 256 1465 c 0,18,-1 + 256 569 l 1,0,1 EndSplineSet Validated: 1 EndChar @@ -4202,38 +4202,38 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 108 0 2048 256 256 +Image2: image/png 108 2 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8Bu3Ns22,9nFj )K\/O'4BPAFi)''RfN!^82i:5dg`#h$$d0aOrk8F)\Y<:z8OZBBY!QNJ EndImage2 Fore SplineSet -0 1465 m 0,0,1 - 71 1536 71 1536 130 1536 c 0,2,3 - 194 1536 194 1536 256 1465 c 8,4,-1 - 256 569 l 0,5,6 - 256 512 256 512 313 512 c 24,7,8 - 401 512 401 512 454 512 c 0,9,10 - 512 512 512 512 512 569 c 1,11,-1 - 512 967 l 0,12,13 - 576 1024 576 1024 640 1024 c 128,-1,14 - 704 1024 704 1024 768 967 c 8,15,-1 - 768 569 l 1,16,17 - 768 512 768 512 824 512 c 24,18,19 - 918 512 918 512 967 512 c 0,20,21 - 1024 512 1024 512 1024 569 c 25,22,-1 - 1024 1465 l 0,23,24 - 1087 1536 1087 1536 1151 1536 c 128,-1,25 - 1215 1536 1215 1536 1280 1465 c 1,26,27 - 1280 1465 1280 1465 1280 569 c 17,28,29 - 1280 256 1280 256 967 256 c 18,30,31 - 967 256 967 256 823 256 c 0,32,33 - 639 256 639 256 639 512 c 1,34,35 - 639 256 639 256 454 256 c 1,36,37 - 454 256 454 256 313 256 c 0,38,39 - 1 258 1 258 0 569 c 16,40,41 - -2 1016 -2 1016 -2 1240 c 0,42,43 - -2 1463 -2 1463 0 1465 c 0,0,1 +2 1465 m 0,0,1 + 73 1536 73 1536 132 1536 c 0,2,3 + 196 1536 196 1536 258 1465 c 8,4,-1 + 258 569 l 0,5,6 + 258 512 258 512 315 512 c 24,7,8 + 403 512 403 512 456 512 c 0,9,10 + 514 512 514 512 514 569 c 1,11,-1 + 514 967 l 0,12,13 + 578 1024 578 1024 642 1024 c 128,-1,14 + 706 1024 706 1024 770 967 c 8,15,-1 + 770 569 l 1,16,17 + 770 512 770 512 826 512 c 24,18,19 + 920 512 920 512 969 512 c 0,20,21 + 1026 512 1026 512 1026 569 c 25,22,-1 + 1026 1465 l 0,23,24 + 1089 1536 1089 1536 1153 1536 c 128,-1,25 + 1217 1536 1217 1536 1282 1465 c 1,26,27 + 1282 1465 1282 1465 1282 569 c 17,28,29 + 1282 256 1282 256 969 256 c 18,30,31 + 969 256 969 256 825 256 c 0,32,33 + 641 256 641 256 641 512 c 1,34,35 + 641 256 641 256 456 256 c 1,36,37 + 456 256 456 256 315 256 c 0,38,39 + 3 258 3 258 2 569 c 16,40,41 + 0 1016 0 1016 0 1240 c 0,42,43 + 0 1463 0 1463 2 1465 c 0,0,1 EndSplineSet Validated: 1 EndChar @@ -4276,32 +4276,32 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 118 0 2048 256 256 +Image2: image/png 118 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns3"!@&g6 >TGR=,Y4F3E:$aE/0H[/440%BWJ+OW;M<:^?kYf*@4%Wt!W]..&.jd;TcO16!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -512 825 m 1,0,1 - 512 768 512 768 569 768 c 1,2,3 - 569 768 569 768 1024 768 c 1,4,-1 - 1024 1465 l 0,5,6 - 1024 1536 1024 1536 1152 1536 c 129,-1,7 - 1280 1536 1280 1536 1280 1465 c 1,8,-1 - 1280 313 l 0,9,10 - 1280 0 1280 0 967 0 c 1,11,-1 - 569 0 l 0,12,13 - 512 63 512 63 512 127 c 128,-1,14 - 512 191 512 191 569 256 c 8,15,-1 - 967 256 l 1,16,17 - 1024 256 1024 256 1024 313 c 1,18,19 - 1024 413 1024 413 1024 512 c 0,20,-1 - 569 512 l 1,21,22 - 256 512 256 512 256 825 c 1,23,24 - 256 1180 256 1180 256 1465 c 0,25,26 - 256 1536 256 1536 387 1536 c 0,27,28 - 512 1536 512 1536 512 1465 c 0,29,-1 - 512 825 l 1,0,1 +256 825 m 1,0,1 + 256 768 256 768 313 768 c 1,2,3 + 313 768 313 768 768 768 c 1,4,-1 + 768 1465 l 0,5,6 + 768 1536 768 1536 896 1536 c 129,-1,7 + 1024 1536 1024 1536 1024 1465 c 1,8,-1 + 1024 313 l 0,9,10 + 1024 0 1024 0 711 0 c 1,11,-1 + 313 0 l 0,12,13 + 256 63 256 63 256 127 c 128,-1,14 + 256 191 256 191 313 256 c 8,15,-1 + 711 256 l 1,16,17 + 768 256 768 256 768 313 c 1,18,19 + 768 413 768 413 768 512 c 0,20,-1 + 313 512 l 1,21,22 + 0 512 0 512 0 825 c 1,23,24 + 0 1180 0 1180 0 1465 c 0,25,26 + 0 1536 0 1536 131 1536 c 0,27,28 + 256 1536 256 1536 256 1465 c 0,29,-1 + 256 825 l 1,0,1 EndSplineSet Validated: 1 EndChar @@ -4344,105 +4344,105 @@ EndChar StartChar: braceleft Encoding: 123 123 121 -Width: 1280 +Width: 1536 VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 116 0 2048 256 256 +Image2: image/png 116 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h .f`.M1CUDd6Ru+9X8nT)O;b>)OO;_ILF[nDL6[A&!LG58&4@'?qd>sHz8OZBBY!QNJ EndImage2 Fore SplineSet -512 1465 m 1,0,1 - 512 1792 512 1792 825 1792 c 1,2,3 - 825 1792 825 1792 1024 1792 c 25,4,-1 - 1024 1536 l 1,5,-1 - 824 1536 l 1,6,7 - 768 1536 768 1536 768 1465 c 1,8,9 - 768 1454 768 1454 768 1081 c 0,10,11 - 768 896 768 896 666 896 c 1,12,13 - 768 896 768 896 768 711 c 0,14,15 - 768 711 768 711 768 313 c 1,16,17 - 768 256 768 256 824 256 c 1,18,19 - 1024 256 1024 256 1024 256 c 1,20,-1 - 1024 0 l 25,21,-1 - 825 0 l 0,22,23 - 512 0 512 0 512 313 c 1,24,25 - 512 313 512 313 512 711 c 1,26,27 - 512 768 512 768 454 768 c 0,28,29 - 454 768 454 768 256 768 c 0,30,31 - 256 768 256 768 256 1024 c 1,32,33 - 454 1024 454 1024 454 1024 c 1,34,35 - 512 1024 512 1024 512 1081 c 1,36,37 - 512 1273 512 1273 512 1465 c 1,0,1 +256 1465 m 1,0,1 + 256 1792 256 1792 569 1792 c 1,2,3 + 569 1792 569 1792 768 1792 c 25,4,-1 + 768 1536 l 1,5,-1 + 568 1536 l 1,6,7 + 512 1536 512 1536 512 1465 c 1,8,9 + 512 1454 512 1454 512 1081 c 0,10,11 + 512 896 512 896 410 896 c 1,12,13 + 512 896 512 896 512 711 c 0,14,15 + 512 711 512 711 512 313 c 1,16,17 + 512 256 512 256 568 256 c 1,18,19 + 768 256 768 256 768 256 c 1,20,-1 + 768 0 l 25,21,-1 + 569 0 l 0,22,23 + 256 0 256 0 256 313 c 1,24,25 + 256 313 256 313 256 711 c 1,26,27 + 256 768 256 768 198 768 c 0,28,29 + 198 768 198 768 0 768 c 0,30,31 + 0 768 0 768 0 1024 c 1,32,33 + 198 1024 198 1024 198 1024 c 1,34,35 + 256 1024 256 1024 256 1081 c 1,36,37 + 256 1273 256 1273 256 1465 c 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: bar Encoding: 124 124 122 -Width: 1024 +Width: 1536 VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 96 0 2048 256 256 +Image2: image/png 96 -512 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ $;a-Q35d>_jV532ZuZhP5\Z!+&6obWr%P+Tz8OZBBY!QNJ EndImage2 Fore SplineSet -768 1465 m 1,0,1 - 768 1081 768 1081 768 1081 c 1,2,3 - 768 1024 768 1024 824 1024 c 1,4,5 - 924 1024 924 1024 1024 1024 c 1,6,7 - 1024 768 1024 768 1024 768 c 1,8,9 - 824 768 824 768 824 768 c 1,10,11 - 768 768 768 768 768 711 c 1,12,13 - 768 313 768 313 768 313 c 1,14,15 - 768 0 768 0 455 0 c 0,16,17 - 455 0 455 0 256 0 c 25,18,-1 - 256 256 l 1,19,20 - 355 256 355 256 454 256 c 1,21,22 - 512 256 512 256 512 313 c 1,23,24 - 512 711 512 711 512 711 c 0,25,26 - 512 896 512 896 614 896 c 1,27,28 - 512 896 512 896 512 1081 c 0,29,30 - 512 1460 512 1460 512 1465 c 1,31,32 - 512 1536 512 1536 454 1536 c 1,33,34 - 454 1536 454 1536 256 1536 c 1,35,-1 - 256 1792 l 25,36,-1 - 455 1792 l 1,37,38 - 768 1792 768 1792 768 1465 c 1,0,1 +512 1465 m 1,0,1 + 512 1081 512 1081 512 1081 c 1,2,3 + 512 1024 512 1024 568 1024 c 1,4,5 + 668 1024 668 1024 768 1024 c 1,6,7 + 768 768 768 768 768 768 c 1,8,9 + 568 768 568 768 568 768 c 1,10,11 + 512 768 512 768 512 711 c 1,12,13 + 512 313 512 313 512 313 c 1,14,15 + 512 0 512 0 199 0 c 0,16,17 + 199 0 199 0 0 0 c 25,18,-1 + 0 256 l 1,19,20 + 99 256 99 256 198 256 c 1,21,22 + 256 256 256 256 256 313 c 1,23,24 + 256 711 256 711 256 711 c 0,25,26 + 256 896 256 896 358 896 c 1,27,28 + 256 896 256 896 256 1081 c 0,29,30 + 256 1460 256 1460 256 1465 c 1,31,32 + 256 1536 256 1536 198 1536 c 1,33,34 + 198 1536 198 1536 0 1536 c 1,35,-1 + 0 1792 l 25,36,-1 + 199 1792 l 1,37,38 + 512 1792 512 1792 512 1465 c 1,0,1 EndSplineSet Validated: 1 EndChar @@ -4553,33 +4553,33 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 104 0 2048 256 256 +Image2: image/png 104 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9Xot.% QD<(8YSD-KYqRS-^]H8+jAU0P_e]DTJ$fY!QI[jFz8OZBBY!QNJ EndImage2 Fore SplineSet -512 1280 m 25,0,-1 - 512 331 l 0,1,2 - 512 256 512 256 587 256 c 24,3,-1 - 1024 256 l 24,4,-1 - 1024 1280 l 25,5,-1 - 1280 1280 l 25,6,-1 - 1280 0 l 25,7,-1 - 587 0 l 0,8,9 - 256 0 256 0 256 331 c 24,10,11 - 256 331 256 331 256 1280 c 25,12,-1 - 512 1280 l 25,0,-1 -1024 1792 m 24,13,-1 - 1280 1792 l 25,14,-1 - 1280 1536 l 24,15,-1 - 1024 1536 l 24,16,17 - 1024 1536 1024 1536 1024 1792 c 24,13,-1 -256 1792 m 25,18,-1 - 512 1792 l 25,19,-1 - 512 1536 l 24,20,-1 - 256 1536 l 24,21,22 - 256 1536 256 1536 256 1792 c 25,18,-1 +256 1280 m 25,0,-1 + 256 331 l 0,1,2 + 256 256 256 256 331 256 c 24,3,-1 + 768 256 l 24,4,-1 + 768 1280 l 25,5,-1 + 1024 1280 l 25,6,-1 + 1024 0 l 25,7,-1 + 331 0 l 0,8,9 + 0 0 0 0 0 331 c 24,10,11 + 0 331 0 331 0 1280 c 25,12,-1 + 256 1280 l 25,0,-1 +768 1792 m 24,13,-1 + 1024 1792 l 25,14,-1 + 1024 1536 l 24,15,-1 + 768 1536 l 24,16,17 + 768 1536 768 1536 768 1792 c 24,13,-1 +0 1792 m 25,18,-1 + 256 1792 l 25,19,-1 + 256 1536 l 24,20,-1 + 0 1536 l 24,21,22 + 0 1536 0 1536 0 1792 c 25,18,-1 EndSplineSet Validated: 1 EndChar @@ -4591,42 +4591,42 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#kW'4;_d1fscP2ol-7BF EndImage2 Fore SplineSet -587 512 m 0,0,1 - 512 512 512 512 512 437 c 0,2,3 - 512 331 512 331 512 331 c 0,4,5 - 512 256 512 256 587 256 c 0,6,7 - 587 256 587 256 768 256 c 1,8,9 - 768 256 768 256 768 512 c 1,10,11 - 768 512 768 512 587 512 c 0,0,1 -1024 1461 m 1,12,13 - 1024 1536 1024 1536 949 1536 c 24,14,15 - 949 1536 949 1536 587 1536 c 0,16,17 - 512 1536 512 1536 512 1461 c 1,18,19 - 512 1461 512 1461 512 1280 c 1,20,21 - 512 1280 512 1280 949 1280 c 0,22,23 - 1024 1280 1024 1280 1024 1355 c 0,24,25 - 1024 1355 1024 1355 1024 1461 c 1,12,13 -949 1792 m 0,26,27 - 1280 1792 1280 1792 1280 1461 c 24,28,29 - 1280 1461 1280 1461 1280 1355 c 0,30,31 - 1280 1024 1280 1024 1024 1024 c 0,32,33 - 1024 640 1024 640 1024 331 c 0,34,35 - 1024 256 1024 256 1099 256 c 24,36,-1 - 1223 256 l 0,37,38 - 1280 256 1280 256 1280 127 c 0,39,40 - 1280 0 1280 0 1223 0 c 24,41,42 - 1223 0 1223 0 437 0 c 0,43,44 - 256 0 256 0 256 181 c 24,45,46 - 256 181 256 181 256 587 c 0,47,48 - 256 768 256 768 437 768 c 24,49,-1 - 768 768 l 25,50,-1 - 768 1024 l 24,51,-1 - 256 1024 l 24,52,53 - 256 1408 256 1408 256 1461 c 0,54,55 - 256 1792 256 1792 587 1792 c 24,56,57 - 587 1792 587 1792 949 1792 c 0,26,27 +331 512 m 0,0,1 + 256 512 256 512 256 437 c 0,2,3 + 256 331 256 331 256 331 c 0,4,5 + 256 256 256 256 331 256 c 0,6,7 + 331 256 331 256 512 256 c 1,8,9 + 512 256 512 256 512 512 c 1,10,11 + 512 512 512 512 331 512 c 0,0,1 +768 1461 m 1,12,13 + 768 1536 768 1536 693 1536 c 24,14,15 + 693 1536 693 1536 331 1536 c 0,16,17 + 256 1536 256 1536 256 1461 c 1,18,19 + 256 1461 256 1461 256 1280 c 1,20,21 + 256 1280 256 1280 693 1280 c 0,22,23 + 768 1280 768 1280 768 1355 c 0,24,25 + 768 1355 768 1355 768 1461 c 1,12,13 +693 1792 m 0,26,27 + 1024 1792 1024 1792 1024 1461 c 24,28,29 + 1024 1461 1024 1461 1024 1355 c 0,30,31 + 1024 1024 1024 1024 768 1024 c 0,32,33 + 768 640 768 640 768 331 c 0,34,35 + 768 256 768 256 843 256 c 24,36,-1 + 967 256 l 0,37,38 + 1024 256 1024 256 1024 127 c 0,39,40 + 1024 0 1024 0 967 0 c 24,41,42 + 967 0 967 0 181 0 c 0,43,44 + 0 0 0 0 0 181 c 24,45,46 + 0 181 0 181 0 587 c 0,47,48 + 0 768 0 768 181 768 c 24,49,-1 + 512 768 l 25,50,-1 + 512 1024 l 24,51,-1 + 0 1024 l 24,52,53 + 0 1408 0 1408 0 1461 c 0,54,55 + 0 1792 0 1792 331 1792 c 24,56,57 + 331 1792 331 1792 693 1792 c 0,26,27 EndSplineSet Validated: 1 EndChar @@ -4690,47 +4690,47 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9X9;!; X(N\g!Xl:?+?$fj?n4KokRoRb0MI!g^hBqY+:^";i!NjUJC-%a!-E&l&P`+b4obQ_!(fUS7'8ja JcGcN EndImage2 Fore SplineSet -587 512 m 0,0,1 - 512 512 512 512 512 437 c 24,2,3 - 512 363 512 363 512 331 c 0,4,5 - 512 256 512 256 587 256 c 24,6,-1 - 768 256 l 25,7,-1 - 768 512 l 17,8,9 - 768 512 768 512 587 512 c 0,0,1 -256 1280 m 24,10,11 - 256 1280 256 1280 768 1280 c 0,12,13 - 1024 1280 1024 1280 1024 1024 c 24,14,-1 - 1024 331 l 0,15,16 - 1024 256 1024 256 1099 256 c 24,17,-1 - 1223 256 l 0,18,19 - 1280 256 1280 256 1280 127 c 0,20,21 - 1280 -0 1280 -0 1223 0 c 24,22,23 - 1223 0 1223 0 512 0 c 0,24,25 - 256 0 256 0 256 256 c 24,26,27 - 256 256 256 256 256 512 c 128,-1,28 - 256 768 256 768 512 768 c 24,29,-1 - 768 768 l 25,30,31 - 768 898 768 898 768 949 c 0,32,33 - 768 1024 768 1024 693 1024 c 24,34,-1 - 256 1024 l 24,35,36 - 256 1152 256 1152 256 1280 c 24,10,11 -768 1792 m 25,37,-1 - 1024 1792 l 25,38,-1 - 1024 1536 l 25,39,-1 - 768 1536 l 17,40,41 - 768 1536 768 1536 768 1792 c 25,37,-1 -256 1792 m 9,42,-1 - 512 1792 l 25,43,-1 - 512 1536 l 25,44,-1 - 256 1536 l 17,45,46 - 256 1536 256 1536 256 1792 c 9,42,-1 +331 512 m 0,0,1 + 256 512 256 512 256 437 c 24,2,3 + 256 363 256 363 256 331 c 0,4,5 + 256 256 256 256 331 256 c 24,6,-1 + 512 256 l 25,7,-1 + 512 512 l 17,8,9 + 512 512 512 512 331 512 c 0,0,1 +0 1280 m 24,10,11 + 0 1280 0 1280 512 1280 c 0,12,13 + 768 1280 768 1280 768 1024 c 24,14,-1 + 768 331 l 0,15,16 + 768 256 768 256 843 256 c 24,17,-1 + 967 256 l 0,18,19 + 1024 256 1024 256 1024 127 c 0,20,21 + 1024 0 1024 0 967 0 c 24,22,23 + 967 0 967 0 256 0 c 0,24,25 + 0 0 0 0 0 256 c 24,26,27 + 0 256 0 256 0 512 c 128,-1,28 + 0 768 0 768 256 768 c 24,29,-1 + 512 768 l 25,30,31 + 512 898 512 898 512 949 c 0,32,33 + 512 1024 512 1024 437 1024 c 24,34,-1 + 0 1024 l 24,35,36 + 0 1152 0 1152 0 1280 c 24,10,11 +512 1792 m 25,37,-1 + 768 1792 l 25,38,-1 + 768 1536 l 25,39,-1 + 512 1536 l 17,40,41 + 512 1536 512 1536 512 1792 c 25,37,-1 +0 1792 m 9,42,-1 + 256 1792 l 25,43,-1 + 256 1536 l 25,44,-1 + 0 1536 l 17,45,46 + 0 1536 0 1536 0 1792 c 9,42,-1 EndSplineSet Validated: 1 EndChar @@ -4791,50 +4791,50 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 124 0 2048 256 256 +Image2: image/png 124 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$N_'QX+:J@3q#<"J$)@]t pZ@+3S;se'nECd)3;rME"cVsJC-(:i/RpHTM'mT!&S7)$go"b$NrrXke_RMi+2)FlSN("#8$-k"jq*#S+AB?^DV!!#SZ:.26O @"J@Y EndImage2 Fore SplineSet -949 1280 m 0,0,1 - 1024 1280 1024 1280 1024 1355 c 24,2,3 - 1024 1446 1024 1446 1024 1461 c 0,4,5 - 1024 1536 1024 1536 949 1536 c 24,6,-1 - 587 1536 l 0,7,8 - 512 1536 512 1536 512 1461 c 24,9,10 - 512 1370 512 1370 512 1355 c 0,11,12 - 512 1280 512 1280 587 1280 c 24,13,14 - 587 1280 587 1280 949 1280 c 0,0,1 -1206 1154 m 1,15,16 - 1280 1105 1280 1105 1280 967 c 0,17,18 - 1280 967 1280 967 1280 843 c 0,19,20 - 1280 512 1280 512 949 512 c 0,21,22 - 949 512 949 512 512 512 c 1,23,24 - 512 384 512 384 512 331 c 0,25,26 - 512 256 512 256 587 256 c 1,27,28 - 777 256 777 256 967 256 c 0,29,30 - 1024 256 1024 256 1024 127 c 0,31,32 - 1024 0 1024 0 967 0 c 0,33,34 - 777 0 777 0 587 0 c 0,35,36 - 256 0 256 0 256 331 c 1,37,38 - 256 649 256 649 256 967 c 0,39,40 - 256 1102 256 1102 329 1154 c 1,41,42 - 256 1207 256 1207 256 1355 c 0,43,44 - 256 1458 256 1458 256 1461 c 0,45,46 - 256 1792 256 1792 587 1792 c 24,47,48 - 949 1792 949 1792 949 1792 c 0,49,50 - 1280 1792 1280 1792 1280 1461 c 24,51,52 - 1280 1461 1280 1461 1280 1355 c 0,53,54 - 1280 1211 1280 1211 1206 1154 c 1,15,16 -949 768 m 0,55,56 - 1024 768 1024 768 1024 843 c 2,57,58 - 1024 843 1024 843 1024 949 c 1,59,60 - 1024 1024 1024 1024 949 1024 c 1,61,62 - 587 1024 587 1024 587 1024 c 0,63,64 - 512 1024 512 1024 512 949 c 1,65,66 - 512 858 512 858 512 843 c 0,67,68 - 512 768 512 768 587 768 c 1,69,70 - 587 768 587 768 949 768 c 0,55,56 +693 1280 m 0,0,1 + 768 1280 768 1280 768 1355 c 24,2,3 + 768 1446 768 1446 768 1461 c 0,4,5 + 768 1536 768 1536 693 1536 c 24,6,-1 + 331 1536 l 0,7,8 + 256 1536 256 1536 256 1461 c 24,9,10 + 256 1370 256 1370 256 1355 c 0,11,12 + 256 1280 256 1280 331 1280 c 24,13,14 + 331 1280 331 1280 693 1280 c 0,0,1 +950 1154 m 1,15,16 + 1024 1105 1024 1105 1024 967 c 0,17,18 + 1024 967 1024 967 1024 843 c 0,19,20 + 1024 512 1024 512 693 512 c 0,21,22 + 693 512 693 512 256 512 c 1,23,24 + 256 384 256 384 256 331 c 0,25,26 + 256 256 256 256 331 256 c 1,27,28 + 521 256 521 256 711 256 c 0,29,30 + 768 256 768 256 768 127 c 0,31,32 + 768 0 768 0 711 0 c 0,33,34 + 521 0 521 0 331 0 c 0,35,36 + 0 0 0 0 0 331 c 1,37,38 + 0 649 0 649 0 967 c 0,39,40 + 0 1102 0 1102 73 1154 c 1,41,42 + 0 1207 0 1207 0 1355 c 0,43,44 + 0 1458 0 1458 0 1461 c 0,45,46 + 0 1792 0 1792 331 1792 c 24,47,48 + 693 1792 693 1792 693 1792 c 0,49,50 + 1024 1792 1024 1792 1024 1461 c 24,51,52 + 1024 1461 1024 1461 1024 1355 c 0,53,54 + 1024 1211 1024 1211 950 1154 c 1,15,16 +693 768 m 0,55,56 + 768 768 768 768 768 843 c 2,57,58 + 768 843 768 843 768 949 c 1,59,60 + 768 1024 768 1024 693 1024 c 1,61,62 + 331 1024 331 1024 331 1024 c 0,63,64 + 256 1024 256 1024 256 949 c 1,65,66 + 256 858 256 858 256 843 c 0,67,68 + 256 768 256 768 331 768 c 1,69,70 + 331 768 331 768 693 768 c 0,55,56 EndSplineSet Validated: 1 EndChar @@ -4942,47 +4942,47 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9Xot.% Q6XNTQmq716/li65Y_>gF@@`'/mNJ1JFs)6ai0UTp3g!;V?`)AUn4]`8$4!(fUS7'8ja JcGcN EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 1536 l 24,2,-1 - 1024 1536 l 24,3,4 - 1024 1536 1024 1536 1024 1792 c 25,0,-1 -256 1792 m 24,5,-1 - 512 1792 l 24,6,-1 - 512 1536 l 24,7,-1 - 256 1536 l 24,8,9 - 256 1536 256 1536 256 1792 c 24,5,-1 -949 768 m 0,10,11 - 1024 768 1024 768 1024 843 c 2,12,13 - 1024 843 1024 843 1024 949 c 1,14,15 - 1024 1024 1024 1024 949 1024 c 1,16,17 - 587 1024 587 1024 587 1024 c 0,18,19 - 512 1024 512 1024 512 949 c 1,20,21 - 512 858 512 858 512 843 c 0,22,23 - 512 768 512 768 587 768 c 1,24,25 - 587 768 587 768 949 768 c 0,10,11 -256 967 m 0,26,27 - 256 1280 256 1280 569 1280 c 1,28,29 - 569 1280 569 1280 967 1280 c 1,30,31 - 1280 1280 1280 1280 1280 967 c 0,32,33 - 1280 825 1280 825 1280 825 c 0,34,35 - 1280 512 1280 512 967 512 c 24,36,-1 - 512 512 l 1,37,38 - 512 384 512 384 512 331 c 0,39,40 - 512 256 512 256 587 256 c 1,41,42 - 587 256 587 256 967 256 c 0,43,44 - 1024 256 1024 256 1024 127 c 0,45,46 - 1024 0 1024 0 967 0 c 0,47,-1 - 569 0 l 0,48,49 - 256 0 256 0 256 313 c 1,50,51 - 256 960 256 960 256 967 c 0,26,27 +768 1792 m 25,0,-1 + 1024 1792 l 25,1,-1 + 1024 1536 l 24,2,-1 + 768 1536 l 24,3,4 + 768 1536 768 1536 768 1792 c 25,0,-1 +0 1792 m 24,5,-1 + 256 1792 l 24,6,-1 + 256 1536 l 24,7,-1 + 0 1536 l 24,8,9 + 0 1536 0 1536 0 1792 c 24,5,-1 +693 768 m 0,10,11 + 768 768 768 768 768 843 c 2,12,13 + 768 843 768 843 768 949 c 1,14,15 + 768 1024 768 1024 693 1024 c 1,16,17 + 331 1024 331 1024 331 1024 c 0,18,19 + 256 1024 256 1024 256 949 c 1,20,21 + 256 858 256 858 256 843 c 0,22,23 + 256 768 256 768 331 768 c 1,24,25 + 331 768 331 768 693 768 c 0,10,11 +0 967 m 0,26,27 + 0 1280 0 1280 313 1280 c 1,28,29 + 313 1280 313 1280 711 1280 c 1,30,31 + 1024 1280 1024 1280 1024 967 c 0,32,33 + 1024 825 1024 825 1024 825 c 0,34,35 + 1024 512 1024 512 711 512 c 24,36,-1 + 256 512 l 1,37,38 + 256 384 256 384 256 331 c 0,39,40 + 256 256 256 256 331 256 c 1,41,42 + 331 256 331 256 711 256 c 0,43,44 + 768 256 768 256 768 127 c 0,45,46 + 768 0 768 0 711 0 c 0,47,-1 + 313 0 l 0,48,49 + 0 0 0 0 0 313 c 1,50,51 + 0 960 0 960 0 967 c 0,26,27 EndSplineSet Validated: 1 EndChar @@ -5042,31 +5042,31 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 104 0 2048 256 256 +Image2: image/png 104 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns3"!@&g6 Qij+G2),_\"ZG0ZPDF8^ZCU2qJrTs6W4`HPT/+OBz8OZBBY!QNJ EndImage2 Fore SplineSet -512 1024 m 24,0,-1 - 768 1024 l 24,1,-1 - 768 256 l 24,2,-1 - 1024 256 l 24,3,-1 - 1024 0 l 25,4,-1 - 256 0 l 25,5,-1 - 256 256 l 24,6,-1 - 512 256 l 24,7,-1 - 512 1024 l 24,0,-1 -768 1536 m 24,8,-1 - 1024 1536 l 24,9,-1 - 1024 1280 l 24,10,-1 - 768 1280 l 24,11,12 - 768 1280 768 1280 768 1536 c 24,8,-1 -256 1536 m 24,13,-1 - 512 1536 l 24,14,-1 - 512 1280 l 24,15,-1 - 256 1280 l 24,16,17 - 256 1280 256 1280 256 1536 c 24,13,-1 +256 1024 m 24,0,-1 + 512 1024 l 24,1,-1 + 512 256 l 24,2,-1 + 768 256 l 24,3,-1 + 768 0 l 25,4,-1 + 0 0 l 25,5,-1 + 0 256 l 24,6,-1 + 256 256 l 24,7,-1 + 256 1024 l 24,0,-1 +512 1536 m 24,8,-1 + 768 1536 l 24,9,-1 + 768 1280 l 24,10,-1 + 512 1280 l 24,11,12 + 512 1280 512 1280 512 1536 c 24,8,-1 +0 1536 m 24,13,-1 + 256 1536 l 24,14,-1 + 256 1280 l 24,15,-1 + 0 1280 l 24,16,17 + 0 1280 0 1280 0 1536 c 24,13,-1 EndSplineSet Validated: 1 EndChar @@ -5078,34 +5078,34 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 109 0 2048 256 256 +Image2: image/png 109 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CNNffG9`^HN: $:'asKgF@BR@+I0G:$V1>%-]!`j^^=J,Oz8OZBBY!QNJ EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 1536 l 24,2,-1 - 1024 1536 l 24,3,4 - 1024 1536 1024 1536 1024 1792 c 25,0,-1 -512 1792 m 24,5,-1 - 512 1536 l 24,6,-1 - 256 1536 l 24,7,-1 - 256 1792 l 25,8,9 - 256 1792 256 1792 512 1792 c 24,5,-1 -1280 1280 m 24,10,11 - 1280 1280 1280 1280 1280 331 c 0,12,13 - 1280 0 1280 0 949 0 c 24,14,-1 - 512 0 l 24,15,-1 - 512 256 l 24,16,-1 - 949 256 l 0,17,18 - 1024 256 1024 256 1024 331 c 24,19,20 - 1024 331 1024 331 1024 512 c 24,21,-1 - 587 512 l 0,22,23 - 256 512 256 512 256 843 c 24,24,25 - 256 843 256 843 256 1280 c 24,26,-1 - 512 1280 l 24,27,-1 - 512 843 l 0,28,29 - 512 768 512 768 587 768 c 24,30,-1 - 1024 768 l 25,31,-1 - 1024 1280 l 24,32,33 - 1024 1280 1024 1280 1280 1280 c 24,10,11 +768 1792 m 25,0,-1 + 1024 1792 l 25,1,-1 + 1024 1536 l 24,2,-1 + 768 1536 l 24,3,4 + 768 1536 768 1536 768 1792 c 25,0,-1 +256 1792 m 24,5,-1 + 256 1536 l 24,6,-1 + 0 1536 l 24,7,-1 + 0 1792 l 25,8,9 + 0 1792 0 1792 256 1792 c 24,5,-1 +1024 1280 m 24,10,11 + 1024 1280 1024 1280 1024 331 c 0,12,13 + 1024 0 1024 0 693 0 c 24,14,-1 + 256 0 l 24,15,-1 + 256 256 l 24,16,-1 + 693 256 l 0,17,18 + 768 256 768 256 768 331 c 24,19,20 + 768 331 768 331 768 512 c 24,21,-1 + 331 512 l 0,22,23 + 0 512 0 512 0 843 c 24,24,25 + 0 843 0 843 0 1280 c 24,26,-1 + 256 1280 l 24,27,-1 + 256 843 l 0,28,29 + 256 768 256 768 331 768 c 24,30,-1 + 768 768 l 25,31,-1 + 768 1280 l 24,32,33 + 768 1280 768 1280 1024 1280 c 24,10,11 EndSplineSet Validated: 1 EndChar @@ -5726,39 +5726,39 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 122 0 2048 256 256 +Image2: image/png 122 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?L$NR8(5+:&'Rs8UE2K+e@/ Q`3';in!tUm[g4<\h=$sKf"laP0aGAR'\%a1Ns&o/_MNWomponhuM-h'+]WtMlHaW!!#SZ:.26O @"J@Y EndImage2 Fore SplineSet -768 1280 m 24,0,-1 - 587 1280 l 0,1,2 - 512 1280 512 1280 512 1205 c 24,3,4 - 512 858 512 858 512 587 c 0,5,6 - 512 512 512 512 587 512 c 24,7,-1 - 768 512 l 24,8,9 - 768 512 768 512 768 1280 c 24,0,-1 -1280 1536 m 24,10,-1 - 1280 1280 l 24,11,-1 - 1024 1280 l 24,12,-1 - 1024 512 l 24,13,-1 - 1280 512 l 24,14,-1 - 1280 256 l 24,15,-1 - 1024 256 l 24,16,-1 - 1024 0 l 25,17,-1 - 768 0 l 25,18,-1 - 768 256 l 24,19,-1 - 587 256 l 0,20,21 - 256 256 256 256 256 587 c 24,22,23 - 256 1062 256 1062 256 1205 c 0,24,25 - 256 1536 256 1536 587 1536 c 24,26,-1 - 768 1536 l 24,27,-1 - 768 1792 l 25,28,-1 - 1024 1792 l 25,29,-1 - 1024 1536 l 24,30,-1 - 1280 1536 l 24,10,-1 +512 1280 m 24,0,-1 + 331 1280 l 0,1,2 + 256 1280 256 1280 256 1205 c 24,3,4 + 256 858 256 858 256 587 c 0,5,6 + 256 512 256 512 331 512 c 24,7,-1 + 512 512 l 24,8,9 + 512 512 512 512 512 1280 c 24,0,-1 +1024 1536 m 24,10,-1 + 1024 1280 l 24,11,-1 + 768 1280 l 24,12,-1 + 768 512 l 24,13,-1 + 1024 512 l 24,14,-1 + 1024 256 l 24,15,-1 + 768 256 l 24,16,-1 + 768 0 l 25,17,-1 + 512 0 l 25,18,-1 + 512 256 l 24,19,-1 + 331 256 l 0,20,21 + 0 256 0 256 0 587 c 24,22,23 + 0 1062 0 1062 0 1205 c 0,24,25 + 0 1536 0 1536 331 1536 c 24,26,-1 + 512 1536 l 24,27,-1 + 512 1792 l 25,28,-1 + 768 1792 l 25,29,-1 + 768 1536 l 24,30,-1 + 1024 1536 l 24,10,-1 EndSplineSet Validated: 1 EndChar @@ -5930,45 +5930,45 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 125 0 2048 256 256 +Image2: image/png 125 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$N_p,`+:LRo])S$G(QNpF KTOPnE?4#5;)=B^WLCOLkf.)JPhhE`$6hQ8Km9=:'h\;Df0U7c@_Y%0!Sk=!*9^"N?iU0,!(fUS 7'8jaJcGcN EndImage2 Fore SplineSet -768 437 m 0,0,1 - 768 512 768 512 693 512 c 0,2,-1 - 587 512 l 0,3,4 - 512 512 512 512 512 437 c 0,5,6 - 512 346 512 346 512 331 c 0,7,8 - 512 256 512 256 587 256 c 0,9,10 - 587 256 587 256 693 256 c 0,11,12 - 768 256 768 256 768 331 c 0,13,14 - 768 331 768 331 768 437 c 0,0,1 -768 1280 m 1,15,16 - 1024 1280 1024 1280 1024 949 c 1,17,-1 - 1024 256 l 24,18,-1 - 1223 256 l 0,19,20 - 1280 256 1280 256 1280 127 c 0,21,22 - 1280 0 1280 0 1223 0 c 24,23,24 - 1223 0 1223 0 587 0 c 0,25,26 - 256 0 256 0 256 331 c 24,27,28 - 256 331 256 331 256 437 c 0,29,30 - 256 768 256 768 587 768 c 24,31,-1 - 768 768 l 25,32,33 - 768 900 768 900 768 949 c 0,34,35 - 768 1024 768 1024 693 1024 c 24,36,-1 - 256 1024 l 24,37,38 - 256 1024 256 1024 256 1280 c 24,39,-1 - 512 1280 l 24,40,-1 - 512 1461 l 0,41,42 - 512 1792 512 1792 843 1792 c 24,43,44 - 843 1792 843 1792 1280 1792 c 25,45,46 - 1280 1792 1280 1792 1280 1536 c 24,47,-1 - 843 1536 l 0,48,49 - 768 1536 768 1536 768 1461 c 24,50,51 - 768 1461 768 1461 768 1280 c 1,15,16 +512 437 m 0,0,1 + 512 512 512 512 437 512 c 0,2,-1 + 331 512 l 0,3,4 + 256 512 256 512 256 437 c 0,5,6 + 256 346 256 346 256 331 c 0,7,8 + 256 256 256 256 331 256 c 0,9,10 + 331 256 331 256 437 256 c 0,11,12 + 512 256 512 256 512 331 c 0,13,14 + 512 331 512 331 512 437 c 0,0,1 +512 1280 m 1,15,16 + 768 1280 768 1280 768 949 c 1,17,-1 + 768 256 l 24,18,-1 + 967 256 l 0,19,20 + 1024 256 1024 256 1024 127 c 0,21,22 + 1024 0 1024 0 967 0 c 24,23,24 + 967 0 967 0 331 0 c 0,25,26 + 0 0 0 0 0 331 c 24,27,28 + 0 331 0 331 0 437 c 0,29,30 + 0 768 0 768 331 768 c 24,31,-1 + 512 768 l 25,32,33 + 512 900 512 900 512 949 c 0,34,35 + 512 1024 512 1024 437 1024 c 24,36,-1 + 0 1024 l 24,37,38 + 0 1024 0 1024 0 1280 c 24,39,-1 + 256 1280 l 24,40,-1 + 256 1461 l 0,41,42 + 256 1792 256 1792 587 1792 c 24,43,44 + 587 1792 587 1792 1024 1792 c 25,45,46 + 1024 1792 1024 1792 1024 1536 c 24,47,-1 + 587 1536 l 0,48,49 + 512 1536 512 1536 512 1461 c 24,50,51 + 512 1461 512 1461 512 1280 c 1,15,16 EndSplineSet Validated: 1 EndChar @@ -5980,30 +5980,30 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 115 0 2048 256 256 +Image2: image/png 115 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#mY$.pLhRc+V#NJBF EndImage2 Fore SplineSet -512 256 m 24,0,-1 - 512 1024 l 24,1,2 - 512 1024 512 1024 768 1024 c 24,3,-1 - 768 256 l 24,4,-1 - 1024 256 l 24,5,6 - 1024 256 1024 256 1024 0 c 25,7,-1 - 256 0 l 25,8,-1 - 256 256 l 24,9,-1 - 512 256 l 24,0,-1 -512 1280 m 24,10,11 - 512 1280 512 1280 512 1461 c 17,12,13 - 512 1792 512 1792 843 1792 c 0,14,15 - 843 1792 843 1792 1280 1792 c 0,16,17 - 1280 1792 1280 1792 1280 1536 c 0,18,-1 - 843 1536 l 1,19,20 - 768 1536 768 1536 768 1461 c 8,21,-1 - 768 1280 l 24,22,23 - 768 1280 768 1280 512 1280 c 24,10,11 +256 256 m 24,0,-1 + 256 1024 l 24,1,2 + 256 1024 256 1024 512 1024 c 24,3,-1 + 512 256 l 24,4,-1 + 768 256 l 24,5,6 + 768 256 768 256 768 0 c 25,7,-1 + 0 0 l 25,8,-1 + 0 256 l 24,9,-1 + 256 256 l 24,0,-1 +256 1280 m 24,10,11 + 256 1280 256 1280 256 1461 c 17,12,13 + 256 1792 256 1792 587 1792 c 0,14,15 + 587 1792 587 1792 1024 1792 c 0,16,17 + 1024 1792 1024 1792 1024 1536 c 0,18,-1 + 587 1536 l 1,19,20 + 512 1536 512 1536 512 1461 c 8,21,-1 + 512 1280 l 24,22,23 + 512 1280 512 1280 256 1280 c 24,10,11 EndSplineSet Validated: 1 EndChar @@ -6015,37 +6015,37 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 118 0 2048 256 256 +Image2: image/png 118 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#kW'4;_d1fscP2ol,D.o8oiksD6R.KDOCfk>J_!W\Z<',H#YRNqk5!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -587 1024 m 0,0,1 - 512 1024 512 1024 512 949 c 24,2,3 - 512 949 512 949 512 331 c 0,4,5 - 512 256 512 256 587 256 c 24,6,-1 - 949 256 l 0,7,8 - 1024 256 1024 256 1024 331 c 24,9,10 - 1024 949 1024 949 1024 949 c 2,11,12 - 1024 1024 1024 1024 949 1024 c 8,13,14 - 768 1024 768 1024 587 1024 c 0,0,1 -949 1280 m 0,15,16 - 1280 1280 1280 1280 1280 949 c 24,17,18 - 1280 949 1280 949 1280 331 c 0,19,20 - 1280 0 1280 0 949 0 c 24,21,-1 - 587 0 l 0,22,23 - 256 0 256 0 256 331 c 24,24,25 - 256 806 256 806 256 949 c 0,26,27 - 256 1280 256 1280 512 1280 c 1,28,-1 - 512 1461 l 0,29,30 - 512 1792 512 1792 843 1792 c 24,31,32 - 843 1792 843 1792 1280 1792 c 25,33,34 - 1280 1792 1280 1792 1280 1536 c 24,35,-1 - 843 1536 l 0,36,37 - 768 1536 768 1536 768 1461 c 24,38,39 - 768 1461 768 1461 768 1280 c 24,40,-1 - 949 1280 l 0,15,16 +331 1024 m 0,0,1 + 256 1024 256 1024 256 949 c 24,2,3 + 256 949 256 949 256 331 c 0,4,5 + 256 256 256 256 331 256 c 24,6,-1 + 693 256 l 0,7,8 + 768 256 768 256 768 331 c 24,9,10 + 768 949 768 949 768 949 c 2,11,12 + 768 1024 768 1024 693 1024 c 8,13,14 + 512 1024 512 1024 331 1024 c 0,0,1 +693 1280 m 0,15,16 + 1024 1280 1024 1280 1024 949 c 24,17,18 + 1024 949 1024 949 1024 331 c 0,19,20 + 1024 0 1024 0 693 0 c 24,21,-1 + 331 0 l 0,22,23 + 0 0 0 0 0 331 c 24,24,25 + 0 806 0 806 0 949 c 0,26,27 + 0 1280 0 1280 256 1280 c 1,28,-1 + 256 1461 l 0,29,30 + 256 1792 256 1792 587 1792 c 24,31,32 + 587 1792 587 1792 1024 1792 c 25,33,34 + 1024 1792 1024 1792 1024 1536 c 24,35,-1 + 587 1536 l 0,36,37 + 512 1536 512 1536 512 1461 c 24,38,39 + 512 1461 512 1461 512 1280 c 24,40,-1 + 693 1280 l 0,15,16 EndSplineSet Validated: 1 EndChar @@ -6057,27 +6057,27 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 112 0 2048 256 256 +Image2: image/png 112 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#mQ$-8:n-D4HA1C]bL>QNK>+NL21%C66=DFY-R6K,CSz8OZBBY!QNJ EndImage2 Fore SplineSet -1280 1280 m 24,0,-1 - 1280 0 l 25,1,-1 - 587 0 l 0,2,3 - 256 0 256 0 256 331 c 24,4,5 - 256 331 256 331 256 1205 c 25,6,-1 - 843 1792 l 24,7,-1 - 1280 1792 l 25,8,-1 - 1280 1536 l 24,9,-1 - 967 1536 l 24,10,-1 - 512 1099 l 25,11,12 - 512 678 512 678 512 331 c 0,13,14 - 512 256 512 256 587 256 c 24,15,-1 - 1024 256 l 24,16,-1 - 1024 1280 l 24,17,18 - 1024 1280 1024 1280 1280 1280 c 24,0,-1 +1024 1280 m 24,0,-1 + 1024 0 l 25,1,-1 + 331 0 l 0,2,3 + 0 0 0 0 0 331 c 24,4,5 + 0 331 0 331 0 1205 c 25,6,-1 + 587 1792 l 24,7,-1 + 1024 1792 l 25,8,-1 + 1024 1536 l 24,9,-1 + 711 1536 l 24,10,-1 + 256 1099 l 25,11,12 + 256 678 256 678 256 331 c 0,13,14 + 256 256 256 256 331 256 c 24,15,-1 + 768 256 l 24,16,-1 + 768 1280 l 24,17,18 + 768 1280 768 1280 1024 1280 c 24,0,-1 EndSplineSet Validated: 1 EndChar @@ -6167,39 +6167,39 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG9Xor#n '1`r<#?K_r!ro=GQ8CNNffG9`^HNZ $?-jc=$Y+8'Q]BrE"e>O:mdIt!!#m3#7ii8+`m\a!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -512 1279.99969483 m 24,0,-1 - 768 1279.99969483 l 24,1,-1 - 768 0 l 25,2,-1 - 511.999633789 0 l 24,3,4 - 511.999633789 0 511.999633789 0 512 1279.99969483 c 24,0,-1 -511.999633789 1792 m 24,5,-1 - 768 1792 l 25,6,-1 - 768 1536.00042725 l 24,7,-1 - 512 1536.00042725 l 24,8,9 - 512 1536.00042725 512 1536.00042725 511.999633789 1792 c 24,5,-1 +0 1280 m 24,0,-1 + 256 1280 l 24,1,-1 + 256 0 l 25,2,-1 + 0 0 l 24,3,4 + 0 0 0 0 0 1280 c 24,0,-1 +0 1792 m 24,5,-1 + 256 1792 l 25,6,-1 + 256 1536 l 24,7,-1 + 0 1536 l 24,8,9 + 0 1536 0 1536 0 1792 c 24,5,-1 EndSplineSet Validated: 1 EndChar @@ -6450,40 +6450,40 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 115 0 2048 256 256 +Image2: image/png 115 -58 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3"!@&g6 >TGR=,Y68bOB/kI5e>@6_up^')2l^nfh'g'\G7g1BJ]\prtPfbo^aa:!!!!j78?7R6=>BF EndImage2 Fore SplineSet -1099 896 m 1,0,1 - 1280 896 1280 896 1280 693 c 0,2,3 - 1280 693 1280 693 1280 313 c 0,4,5 - 1280 256 1280 256 1152 256 c 144,-1,6 - 1024 256 1024 256 1024 313 c 24,7,-1 - 1024 693 l 1,8,9 - 1024 843 1024 843 826 843 c 0,10,11 - 826 843 826 843 826 949 c 1,12,13 - 1024 949 1024 949 1024 1099 c 1,14,-1 - 1024 1479 l 0,15,16 - 1024 1536 1024 1536 1152 1536 c 128,-1,17 - 1280 1536 1280 1536 1280 1479 c 8,18,19 - 1280 1188 1280 1188 1280 1099 c 0,20,21 - 1280 896 1280 896 1099 896 c 1,0,1 -331 896 m 1,22,23 - 512 896 512 896 512 693 c 0,24,25 - 512 474 512 474 512 313 c 0,26,27 - 512 256 512 256 384 256 c 144,-1,28 - 256 256 256 256 256 313 c 24,29,-1 - 256 693 l 1,30,31 - 256 843 256 843 58 843 c 0,32,33 - 58 843 58 843 58 949 c 1,34,35 - 256 949 256 949 256 1099 c 1,36,-1 - 256 1479 l 0,37,38 - 256 1536 256 1536 384 1536 c 128,-1,39 - 512 1536 512 1536 512 1479 c 8,40,41 - 512 1362 512 1362 512 1099 c 0,42,43 - 512 896 512 896 331 896 c 1,22,23 +1041 896 m 1,0,1 + 1222 896 1222 896 1222 693 c 0,2,3 + 1222 693 1222 693 1222 313 c 0,4,5 + 1222 256 1222 256 1094 256 c 144,-1,6 + 966 256 966 256 966 313 c 24,7,-1 + 966 693 l 1,8,9 + 966 843 966 843 768 843 c 0,10,11 + 768 843 768 843 768 949 c 1,12,13 + 966 949 966 949 966 1099 c 1,14,-1 + 966 1479 l 0,15,16 + 966 1536 966 1536 1094 1536 c 128,-1,17 + 1222 1536 1222 1536 1222 1479 c 8,18,19 + 1222 1188 1222 1188 1222 1099 c 0,20,21 + 1222 896 1222 896 1041 896 c 1,0,1 +273 896 m 1,22,23 + 454 896 454 896 454 693 c 0,24,25 + 454 474 454 474 454 313 c 0,26,27 + 454 256 454 256 326 256 c 144,-1,28 + 198 256 198 256 198 313 c 24,29,-1 + 198 693 l 1,30,31 + 198 843 198 843 0 843 c 0,32,33 + 0 843 0 843 0 949 c 1,34,35 + 198 949 198 949 198 1099 c 1,36,-1 + 198 1479 l 0,37,38 + 198 1536 198 1536 326 1536 c 128,-1,39 + 454 1536 454 1536 454 1479 c 8,40,41 + 454 1362 454 1362 454 1099 c 0,42,43 + 454 896 454 896 273 896 c 1,22,23 EndSplineSet Validated: 1 EndChar @@ -6546,32 +6546,32 @@ M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CJNffG9Xot.% EndImage2 Fore SplineSet -180.931365967 512 m 28,0,-1 - 512 181 l 29,1,-1 - 511.999633789 0 l 28,2,-1 - 330.938598633 0 l 28,3,-1 - 0 331 l 29,4,-1 - 0 512.000427246 l 28,5,6 - 0 512.000427246 0 512.000427246 180.931365967 512 c 28,0,-1 -0 1279.99969483 m 28,7,-1 - 180.931365967 1280 l 28,8,-1 - 1280 181 l 29,9,-1 - 1280 0 l 29,10,-1 - 1098.98864746 0 l 28,11,-1 - 0 1099 l 29,12,13 - 0 1099 0 1099 0 1279.99969483 c 28,7,-1 -437 1792 m 29,14,-1 - 1280 949 l 29,15,-1 - 1280 768 l 29,16,-1 - 1098.98864746 768 l 28,17,-1 - 256 1611 l 29,18,-1 - 256 1792 l 29,19,-1 - 437 1792 l 29,14,-1 -1024 1792 m 29,20,-1 - 1280 1792 l 29,21,-1 - 1280 1536.00042725 l 28,22,-1 - 1024 1536.00042725 l 28,23,24 - 1024 1536.00042725 1024 1536.00042725 1024 1792 c 29,20,-1 +181 512 m 24,0,-1 + 512 181 l 25,1,-1 + 512 0 l 24,2,-1 + 331 0 l 24,3,-1 + 0 331 l 25,4,-1 + 0 512 l 24,5,6 + 0 512 0 512 181 512 c 24,0,-1 +0 1280 m 24,7,-1 + 181 1280 l 24,8,-1 + 1280 181 l 25,9,-1 + 1280 0 l 25,10,-1 + 1099 0 l 24,11,-1 + 0 1099 l 25,12,13 + 0 1099 0 1099 0 1280 c 24,7,-1 +437 1792 m 25,14,-1 + 1280 949 l 25,15,-1 + 1280 768 l 25,16,-1 + 1099 768 l 24,17,-1 + 256 1611 l 25,18,-1 + 256 1792 l 25,19,-1 + 437 1792 l 25,14,-1 +1024 1792 m 25,20,-1 + 1280 1792 l 25,21,-1 + 1280 1536 l 24,22,-1 + 1024 1536 l 24,23,24 + 1024 1536 1024 1536 1024 1792 c 25,20,-1 EndSplineSet Validated: 1 EndChar @@ -6692,26 +6692,26 @@ JcGcN EndImage2 Fore SplineSet -1098.98864746 768 m 28,0,-1 +1099 768 m 24,0,-1 1280 768 l 25,1,-1 1280 331 l 25,2,-1 - 948.94124349 0 l 24,3,-1 - 511.999633789 0 l 24,4,-1 - 512 181 l 29,5,6 - 512 181 512 181 1098.98864746 768 c 28,0,-1 -1098.98864746 1792 m 24,7,-1 + 949 0 l 24,3,-1 + 512 0 l 24,4,-1 + 512 181 l 25,5,6 + 512 181 512 181 1099 768 c 24,0,-1 +1099 1792 m 24,7,-1 1280 1792 l 25,8,-1 1280 1355 l 25,9,-1 - 180.931365967 256 l 24,10,-1 - 0 255.999969483 l 24,11,-1 + 181 256 l 24,10,-1 + 0 256 l 24,11,-1 0 693 l 25,12,13 - 0 693 0 693 1098.98864746 1792 c 24,7,-1 + 0 693 0 693 1099 1792 c 24,7,-1 0 1792 m 25,14,-1 - 511.999633789 1792 l 24,15,-1 + 512 1792 l 24,15,-1 512 1611 l 25,16,-1 - 180.931365967 1280 l 24,17,-1 - 0 1279.99969483 l 17,18,19 - 0 1279.99969483 0 1279.99969483 0 1792 c 25,14,-1 + 181 1280 l 24,17,-1 + 0 1280 l 17,18,19 + 0 1280 0 1280 0 1792 c 25,14,-1 EndSplineSet Validated: 1 EndChar @@ -6723,17 +6723,17 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 89 0 2048 256 256 +Image2: image/png 89 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W+A"se<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',qPk!$J3C'$J7Wkl:\`!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -256 1792 m 29,0,-1 - 768 1792 l 25,1,-1 - 768 0 l 25,2,-1 - 256 0 l 25,3,-1 - 256 1792 l 29,0,-1 +0 1792 m 29,0,-1 + 512 1792 l 25,1,-1 + 512 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 1792 l 29,0,-1 EndSplineSet Validated: 1 EndChar @@ -6751,13 +6751,13 @@ M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,Y:Bi<#?K_r!ro=GQ8CJNffG9N3T>a EndImage2 Fore SplineSet -256 1792 m 29,0,-1 +256 1792 m 25,0,-1 768 1792 l 25,1,-1 768 0 l 25,2,-1 0 0 l 25,3,-1 - 0 255.999969483 l 24,4,-1 - 256 255.999969483 l 24,5,-1 - 256 1792 l 29,0,-1 + 0 256 l 24,4,-1 + 256 256 l 24,5,-1 + 256 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -6779,10 +6779,10 @@ SplineSet 768 1792 l 25,1,-1 768 0 l 25,2,-1 0 0 l 25,3,-1 - 0 255.999969483 l 24,4,-1 - 256 255.999969483 l 24,5,-1 - 256 512.000427246 l 24,6,-1 - 0 512.000427246 l 24,7,-1 + 0 256 l 24,4,-1 + 256 256 l 24,5,-1 + 256 512 l 24,6,-1 + 0 512 l 24,7,-1 0 768 l 25,8,-1 256 768 l 25,9,-1 256 1792 l 25,0,-1 @@ -6812,8 +6812,8 @@ SplineSet 768 1792 l 25,5,-1 768 0 l 25,6,-1 0 0 l 25,7,-1 - 0 255.999969483 l 24,8,-1 - 256 255.999969483 l 24,9,-1 + 0 256 l 24,8,-1 + 256 256 l 24,9,-1 256 1792 l 25,4,-1 EndSplineSet Validated: 1 @@ -6832,11 +6832,11 @@ M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y EndImage2 Fore SplineSet -0 255.999969483 m 24,0,-1 - 1280 255.999969483 l 24,1,-1 +0 256 m 24,0,-1 + 1280 256 l 24,1,-1 1280 0 l 25,2,-1 0 0 l 25,3,4 - 0 0 0 0 0 255.999969483 c 24,0,-1 + 0 0 0 0 0 256 c 24,0,-1 EndSplineSet Validated: 1 EndChar @@ -6858,11 +6858,11 @@ SplineSet 1280 768 l 25,1,-1 1280 0 l 25,2,-1 0 0 l 25,3,-1 - 0 255.999969483 l 24,4,-1 - 1024 255.999969483 l 24,5,-1 - 1024 512.000427246 l 24,6,-1 - 0 512.000427246 l 24,7,8 - 0 512.000427246 0 512.000427246 0 768 c 25,0,-1 + 0 256 l 24,4,-1 + 1024 256 l 24,5,-1 + 1024 512 l 24,6,-1 + 0 512 l 24,7,8 + 0 512 0 512 0 768 c 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -6880,11 +6880,11 @@ oj@sE!pFGM-ihq]&$QW7"9T%;$.opo!$-\!)&6YA2ZNgX!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 255.999969483 m 24,0,-1 - 768 255.999969483 l 24,1,-1 +0 256 m 24,0,-1 + 768 256 l 24,1,-1 768 0 l 25,2,-1 0 0 l 25,3,4 - 0 0 0 0 0 255.999969483 c 24,0,-1 + 0 0 0 0 0 256 c 24,0,-1 1024 1792 m 25,5,-1 1280 1792 l 25,6,-1 1280 0 l 25,7,-1 @@ -6892,8 +6892,8 @@ SplineSet 1024 1792 l 25,5,-1 256 1792 m 25,9,-1 768 1792 l 25,10,-1 - 768 512.000427246 l 24,11,-1 - 0 512.000427246 l 24,12,-1 + 768 512 l 24,11,-1 + 0 512 l 24,12,-1 0 768 l 25,13,-1 256 768 l 25,14,-1 256 1792 l 25,9,-1 @@ -6908,22 +6908,22 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 91 0 2048 256 256 +Image2: image/png 91 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pJtoT`>';-Nk/O`Y'Ep!!!!j78?7R6=>BF EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 0 l 25,2,-1 - 1024 0 l 25,3,-1 - 1024 1792 l 25,0,-1 -256 1792 m 25,4,-1 - 768 1792 l 25,5,-1 - 768 0 l 25,6,-1 - 256 0 l 25,7,-1 - 256 1792 l 25,4,-1 +768 1792 m 25,0,-1 + 1024 1792 l 25,1,-1 + 1024 0 l 25,2,-1 + 768 0 l 25,3,-1 + 768 1792 l 25,0,-1 +0 1792 m 25,4,-1 + 512 1792 l 25,5,-1 + 512 0 l 25,6,-1 + 0 0 l 25,7,-1 + 0 1792 l 25,4,-1 EndSplineSet Validated: 1 EndChar @@ -6941,18 +6941,18 @@ _Jgd+]314U+BL9QK(L/c$aKcD@ZW>F=e-$1?1ZPNz8OZBBY!QNJ EndImage2 Fore SplineSet -0 255.999969483 m 24,0,-1 - 768 255.999969483 l 24,1,-1 +0 256 m 24,0,-1 + 768 256 l 24,1,-1 768 0 l 25,2,-1 0 0 l 25,3,4 - 0 0 0 0 0 255.999969483 c 24,0,-1 + 0 0 0 0 0 256 c 24,0,-1 0 768 m 25,5,-1 1280 768 l 25,6,-1 1280 0 l 25,7,-1 1024 0 l 25,8,-1 - 1024 512.000427246 l 24,9,-1 - 0 512.000427246 l 24,10,11 - 0 512.000427246 0 512.000427246 0 768 c 25,5,-1 + 1024 512 l 24,9,-1 + 0 512 l 24,10,11 + 0 512 0 512 0 768 c 25,5,-1 EndSplineSet Validated: 1 EndChar @@ -7073,19 +7073,19 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 92 0 2048 256 256 +Image2: image/png 92 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',u$#Yk\J'+V"VlN61l:z8OZBBY!QNJ EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 256 l 25,2,-1 - 1280 256 l 25,3,-1 - 1280 0 l 25,4,-1 - 256 0 l 25,5,-1 - 256 1792 l 25,0,-1 +0 1792 m 25,0,-1 + 512 1792 l 25,1,-1 + 512 256 l 25,2,-1 + 1024 256 l 25,3,-1 + 1024 0 l 25,4,-1 + 0 0 l 25,5,-1 + 0 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -7145,19 +7145,19 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 92 0 2048 256 256 +Image2: image/png 92 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',u$#Yk\J'+V"VlN61l:z8OZBBY!QNJ EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 256 l 25,2,-1 - 1280 256 l 25,3,-1 - 1280 0 l 25,4,-1 - 256 0 l 25,5,-1 - 256 1792 l 25,0,-1 +0 1792 m 25,0,-1 + 512 1792 l 25,1,-1 + 512 256 l 25,2,-1 + 1024 256 l 25,3,-1 + 1024 0 l 25,4,-1 + 0 0 l 25,5,-1 + 0 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -7217,23 +7217,23 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 104 0 2048 256 256 +Image2: image/png 104 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';Mi7Ci3[4f`e+TGmM@ufLu8F^?>eBB4:K7z8OZBBY!QNJ EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 768 l 25,2,-1 - 1280 768 l 25,3,-1 - 1280 512 l 25,4,-1 - 768 512 l 25,5,-1 - 768 256 l 25,6,-1 - 1280 256 l 25,7,-1 - 1280 0 l 25,8,-1 - 256 0 l 25,9,-1 - 256 1792 l 25,0,-1 +0 1792 m 25,0,-1 + 512 1792 l 25,1,-1 + 512 768 l 25,2,-1 + 1024 768 l 25,3,-1 + 1024 512 l 25,4,-1 + 512 512 l 25,5,-1 + 512 256 l 25,6,-1 + 1024 256 l 25,7,-1 + 1024 0 l 25,8,-1 + 0 0 l 25,9,-1 + 0 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -7245,24 +7245,24 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 95 0 2048 256 256 +Image2: image/png 95 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pJu:WrV32(]XO\8-Be-C[o1?!!!!j78?7R6=>BF EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 256 l 25,2,-1 - 1536 256 l 25,3,-1 - 1536 0 l 25,4,-1 - 1024 0 l 25,5,-1 - 1024 1792 l 25,0,-1 -256 1792 m 25,6,-1 - 768 1792 l 25,7,-1 - 768 0 l 25,8,-1 - 256 0 l 25,9,-1 - 256 1792 l 25,6,-1 +768 1792 m 25,0,-1 + 1024 1792 l 25,1,-1 + 1024 256 l 25,2,-1 + 1280 256 l 25,3,-1 + 1280 0 l 25,4,-1 + 768 0 l 25,5,-1 + 768 1792 l 25,0,-1 +0 1792 m 25,6,-1 + 512 1792 l 25,7,-1 + 512 0 l 25,8,-1 + 0 0 l 25,9,-1 + 0 1792 l 25,6,-1 EndSplineSet Validated: 1 EndChar @@ -7274,24 +7274,24 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 100 0 2048 256 256 +Image2: image/png 100 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!%:k7s_'K703#3K"fZMb"F3oa6rz8OZBBY!QNJ EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 512 l 25,2,-1 - 1024 512 l 25,3,-1 - 1024 1792 l 25,0,-1 -256 1792 m 25,4,-1 - 768 1792 l 25,5,-1 - 768 256 l 25,6,-1 - 1280 256 l 25,7,-1 - 1280 0 l 25,8,-1 - 256 0 l 25,9,-1 - 256 1792 l 25,4,-1 +768 1792 m 25,0,-1 + 1024 1792 l 25,1,-1 + 1024 512 l 25,2,-1 + 768 512 l 25,3,-1 + 768 1792 l 25,0,-1 +0 1792 m 25,4,-1 + 512 1792 l 25,5,-1 + 512 256 l 25,6,-1 + 1024 256 l 25,7,-1 + 1024 0 l 25,8,-1 + 0 0 l 25,9,-1 + 0 1792 l 25,4,-1 EndSplineSet Validated: 1 EndChar @@ -7303,24 +7303,24 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 102 0 2048 256 256 +Image2: image/png 102 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8Bu3Ns2<'X3*= @Us";E=0"`_$XSUa:^0]$qI%]"ot9O$4t0"i%tE6!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -1024 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 1024 0 l 25,3,-1 - 1024 256 l 25,0,-1 -256 768 m 25,4,-1 - 1280 768 l 25,5,-1 - 1280 512 l 25,6,-1 - 768 512 l 25,7,-1 - 768 0 l 25,8,-1 - 256 0 l 25,9,-1 - 256 768 l 25,4,-1 +768 256 m 25,0,-1 + 1024 256 l 25,1,-1 + 1024 0 l 25,2,-1 + 768 0 l 25,3,-1 + 768 256 l 25,0,-1 +0 768 m 25,4,-1 + 1024 768 l 25,5,-1 + 1024 512 l 25,6,-1 + 512 512 l 25,7,-1 + 512 0 l 25,8,-1 + 0 0 l 25,9,-1 + 0 768 l 25,4,-1 EndSplineSet Validated: 1 EndChar @@ -7398,27 +7398,27 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 99 0 2048 256 256 +Image2: image/png 99 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!%:k7s_$o`]aKF@jd`!7$Wg'U=M!!!!j78?7R6=>BF EndImage2 Fore SplineSet -1024 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 1024 0 l 25,3,-1 - 1024 256 l 25,0,-1 -1024 1792 m 25,4,-1 - 1280 1792 l 25,5,-1 - 1280 512 l 25,6,-1 - 1024 512 l 25,7,-1 - 1024 1792 l 25,4,-1 -256 1792 m 25,8,-1 - 768 1792 l 25,9,-1 - 768 0 l 25,10,-1 - 256 0 l 25,11,-1 - 256 1792 l 25,8,-1 +768 256 m 25,0,-1 + 1024 256 l 25,1,-1 + 1024 0 l 25,2,-1 + 768 0 l 25,3,-1 + 768 256 l 25,0,-1 +768 1792 m 25,4,-1 + 1024 1792 l 25,5,-1 + 1024 512 l 25,6,-1 + 768 512 l 25,7,-1 + 768 1792 l 25,4,-1 +0 1792 m 25,8,-1 + 512 1792 l 25,9,-1 + 512 0 l 25,10,-1 + 0 0 l 25,11,-1 + 0 1792 l 25,8,-1 EndSplineSet Validated: 1 EndChar @@ -7537,7 +7537,7 @@ EndChar StartChar: uni0000 Encoding: 0 0 207 -Width: 256 +Width: 1536 VWidth: 2048 Flags: MW LayerCount: 3 @@ -7635,21 +7635,21 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 95 0 2048 256 256 +Image2: image/png 95 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pJu:VZ>csF8u:c?j%;QoDu8u!!!!j78?7R6=>BF EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 256 l 25,2,-1 - 1024 256 l 25,3,-1 - 1024 1792 l 25,4,-1 - 1280 1792 l 25,5,-1 - 1280 0 l 25,6,-1 - 256 0 l 25,7,-1 - 256 1792 l 25,0,-1 +0 1792 m 25,0,-1 + 512 1792 l 25,1,-1 + 512 256 l 25,2,-1 + 768 256 l 25,3,-1 + 768 1792 l 25,4,-1 + 1024 1792 l 25,5,-1 + 1024 0 l 25,6,-1 + 0 0 l 25,7,-1 + 0 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -7661,23 +7661,23 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 104 0 2048 256 256 +Image2: image/png 104 -256 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';Mi7Ci3[4f`e+TGmM@ufLu8F^?>eBB4:K7z8OZBBY!QNJ EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 768 l 25,2,-1 - 1280 768 l 25,3,-1 - 1280 512 l 25,4,-1 - 768 512 l 25,5,-1 - 768 256 l 25,6,-1 - 1280 256 l 25,7,-1 - 1280 0 l 25,8,-1 - 256 0 l 25,9,-1 - 256 1792 l 25,0,-1 +0 1792 m 25,0,-1 + 512 1792 l 25,1,-1 + 512 768 l 25,2,-1 + 1024 768 l 25,3,-1 + 1024 512 l 25,4,-1 + 512 512 l 25,5,-1 + 512 256 l 25,6,-1 + 1024 256 l 25,7,-1 + 1024 0 l 25,8,-1 + 0 0 l 25,9,-1 + 0 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -7689,17 +7689,17 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 87 0 2048 256 256 +Image2: image/png 87 -1024 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%!u-t$Rr 6ua"(D?'YV@0@+u1K<94!!!!j78?7R6=>BF EndImage2 Fore SplineSet -1024 768 m 25,0,-1 - 1280 768 l 25,1,-1 - 1280 0 l 25,2,-1 - 1024 0 l 25,3,-1 - 1024 768 l 25,0,-1 +0 768 m 25,0,-1 + 256 768 l 25,1,-1 + 256 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 768 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -7711,17 +7711,17 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 84 0 2048 256 256 +Image2: image/png 84 -1024 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr LuL,h)k-s@YSsU1z8OZBBY!QNJ EndImage2 Fore SplineSet -1024 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 1024 0 l 25,3,-1 - 1024 256 l 25,0,-1 +0 256 m 25,0,-1 + 256 256 l 25,1,-1 + 256 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -7813,17 +7813,17 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 84 0 2048 256 256 +Image2: image/png 84 -1024 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr LuL,h)k-s@YSsU1z8OZBBY!QNJ EndImage2 Fore SplineSet -1024 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 1024 0 l 25,3,-1 - 1024 256 l 25,0,-1 +0 256 m 25,0,-1 + 256 256 l 25,1,-1 + 256 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -7901,17 +7901,17 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 89 0 2048 256 256 +Image2: image/png 89 -512 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W+A"se<#?K_r!ro=GQ8+FNffG9`ah?c _ZUdp_&*dl!0DX7%W-mt#ljr*!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -512 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 0 l 25,2,-1 - 512 -0 l 25,3,-1 - 512 1792 l 25,0,-1 +0 1792 m 25,0,-1 + 768 1792 l 25,1,-1 + 768 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -7951,33 +7951,33 @@ BFk\3HAhcc.FJ4s/Tf;k1(f4+U>6*`gl;[=2_b#`BT:ma%`@oq.KBGK!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -330.876953125 1280 m 0,0,1 +331 1280 m 0,0,1 256 1280 256 1280 256 1205 c 0,2,3 256 1205 256 1205 256 843 c 0,4,5 256 768 256 768 331 768 c 24,6,7 331 768 331 768 437 768 c 0,8,9 512 768 512 768 512 843 c 24,10,11 - 512 843.030122793 512 843.030122793 512 1205 c 0,12,13 + 512 843 512 843 512 1205 c 0,12,13 512 1280 512 1280 437 1280 c 0,14,15 - 437 1280 437 1280 330.876953125 1280 c 0,0,1 + 437 1280 437 1280 331 1280 c 0,0,1 640 588 m 1,16,17 586 512 586 512 437 512 c 0,18,19 - 437 512 437 512 330.938598633 512 c 0,20,21 + 437 512 437 512 331 512 c 0,20,21 1 512 1 512 0 843 c 24,22,23 - 0 843 0 843 0 1205 c 0,24,25 - 0 1536 0 1536 330.938598633 1536 c 24,26,27 - 330.938598633 1536 330.938598633 1536 437 1536 c 0,28,29 + 0 1190 0 1190 0 1205 c 0,24,25 + 0 1536 0 1536 331 1536 c 24,26,27 + 331 1536 331 1536 437 1536 c 0,28,29 591 1536 591 1536 640 1460 c 1,30,31 - 693 1536 693 1536 842.962219238 1536 c 0,32,33 - 843 1536 843 1536 1280 1536.00042725 c 1,34,35 - 1280 1536.00042725 1280 1536.00042725 1280 1279.99969483 c 9,36,-1 - 842.962219238 1280 l 0,37,38 + 693 1536 693 1536 843 1536 c 0,32,33 + 843 1536 843 1536 1280 1536 c 1,34,35 + 1280 1536 1280 1536 1280 1280 c 9,36,-1 + 843 1280 l 0,37,38 769 1280 769 1280 768 1205 c 24,39,40 - 768 1205 768 1205 768 843 c 0,41,42 - 768 768 768 768 842.962219238 768 c 24,43,-1 + 768 986 768 986 768 843 c 0,41,42 + 768 768 768 768 843 768 c 24,43,-1 1280 768 l 25,44,45 - 1280 768 1280 768 1280 512.000427246 c 1,46,47 - 1280 512 1280 512 842.962219238 512 c 0,48,49 + 1280 768 1280 768 1280 512 c 1,46,47 + 1280 512 1280 512 843 512 c 0,48,49 696 512 696 512 640 588 c 1,16,17 EndSplineSet Validated: 1 @@ -8152,7 +8152,7 @@ SplineSet 1024 1024 l 25,19,-1 1024 587 l 0,20,21 1024 256 1024 256 693 256 c 0,22,23 - 693 256 693 256 330.876953125 256 c 0,24,25 + 693 256 693 256 331 256 c 0,24,25 0 256 0 256 0 587 c 0,26,27 0 587 0 587 0 949 c 0,28,29 0 1280 0 1280 331 1280 c 24,30,-1 @@ -8380,7 +8380,7 @@ SplineSet 0 331 0 331 0 949 c 17,37,38 0 1280 0 1280 256 1280 c 9,39,-1 0 1280 l 25,40,41 - 0 1281.91824393 0 1281.91824393 0 1461 c 0,42,43 + 0 1282 0 1282 0 1461 c 0,42,43 0 1792 0 1792 331 1792 c 24,44,45 331 1792 331 1792 768 1792 c 25,16,-1 EndSplineSet @@ -8521,7 +8521,7 @@ StartChar: idieresis Encoding: 239 239 239 Width: 1536 VWidth: 2048 -Flags: MW +Flags: MWO LayerCount: 3 Back Image2: image/png 97 0 2048 256 256 @@ -8542,9 +8542,8 @@ SplineSet 0 0 l 25,14,15 0 0 0 0 0 1461 c 0,16,17 0 1792 0 1792 331 1792 c 24,18,19 - 331.002819919 1792 331.002819919 1792 949 1792 c 0,0,1 + 331 1792 331 1792 949 1792 c 0,0,1 EndSplineSet -Validated: 1 EndChar StartChar: eth @@ -8679,25 +8678,25 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 106 0 2048 256 256 +Image2: image/png 106 -512 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8D_*$Z[Q1)J/h .f`.m$q")!=+HtZ.Y+2mh+8FjcqU6>!W_K,#N@':B;-^]G]F!*oXM$8hk(_+"M,dDQJ+QNPW^z8OZBBY!QNJ EndImage2 Fore SplineSet -512 1280 m 25,0,-1 - 1024 1280 l 25,1,-1 - 1024 1024 l 25,2,-1 - 1280 1024 l 25,3,-1 - 1280 768 l 25,4,-1 - 1024 768 l 25,5,-1 - 1024 512 l 25,6,-1 - 512 512 l 25,7,-1 - 512 768 l 25,8,-1 - 256 768 l 25,9,-1 - 256 1024 l 25,10,-1 - 512 1024 l 25,11,-1 - 512 1280 l 25,0,-1 +256 1280 m 25,0,-1 + 768 1280 l 25,1,-1 + 768 1024 l 25,2,-1 + 1024 1024 l 25,3,-1 + 1024 768 l 25,4,-1 + 768 768 l 25,5,-1 + 768 512 l 25,6,-1 + 256 512 l 25,7,-1 + 256 768 l 25,8,-1 + 0 768 l 25,9,-1 + 0 1024 l 25,10,-1 + 256 1024 l 25,11,-1 + 256 1280 l 25,0,-1 EndSplineSet Validated: 1 EndChar @@ -8879,17 +8878,17 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 97 0 2048 256 256 +Image2: image/png 97 -512 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns24'ehBu @^QY_"YR:$'k#Q%'I9UW!%-V/$md\(4TGH^!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -512 1024 m 29,0,-1 - 768 1024 l 25,1,-1 - 768 768 l 25,2,-1 - 512 768 l 25,3,-1 - 512 1024 l 29,0,-1 +0 1024 m 29,0,-1 + 256 1024 l 25,1,-1 + 256 768 l 25,2,-1 + 0 768 l 25,3,-1 + 0 1024 l 29,0,-1 EndSplineSet Validated: 1 EndChar @@ -8898,7 +8897,7 @@ StartChar: ucircumflex Encoding: 251 251 251 Width: 1536 VWidth: 2048 -Flags: MWO +Flags: MW LayerCount: 3 Back Image2: image/png 117 0 2048 256 256 @@ -8991,17 +8990,17 @@ VWidth: 2048 Flags: MW LayerCount: 3 Back -Image2: image/png 103 0 2048 256 256 +Image2: image/png 103 -512 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8Bu3Ns2`"Y;>@ (`=3"9Eo$3$(=,i!k922m=dV+a8c2MpBh@PrMsB-!!!!j78?7R6=>BF EndImage2 Fore SplineSet -512 1280 m 25,0,-1 - 1280 1280 l 25,1,-1 - 1280 256 l 25,2,-1 - 512 256 l 25,3,-1 - 512 1280 l 25,0,-1 +0 1280 m 25,0,-1 + 768 1280 l 25,1,-1 + 768 256 l 25,2,-1 + 0 256 l 25,3,-1 + 0 1280 l 25,0,-1 EndSplineSet Validated: 1 EndChar From 83f8c69b2ed5838daf5cd75c648f7e18ab4ac0cb Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 22 Nov 2022 18:23:37 +0100 Subject: [PATCH 220/314] [#284] Optimized / improved ADM-3A font --- .../device/adm3a/gui/DisplayCanvas.java | 2 +- .../plugins/device/adm3a/gui/DisplayFont.java | 2 +- .../device/adm3a/interaction/Display.java | 1 - .../plugins/device/adm3a/gui/adm-3a.ttf | Bin 36412 -> 36372 bytes resources/lsi-adm-3a/adm-3a.ttf | Bin 36412 -> 36372 bytes resources/lsi-adm-3a/adm3a.sfd | 10166 ++++++++-------- 6 files changed, 4956 insertions(+), 5215 deletions(-) diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java index cecc93266..325f20203 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java @@ -13,7 +13,7 @@ import static net.emustudio.plugins.device.adm3a.Utils.loadFont; public class DisplayCanvas extends Canvas implements AutoCloseable { - private static final Color FOREGROUND = new Color(0, 255, 0); + private static final Color FOREGROUND = new Color(255, 255, 255); private static final Color BACKGROUND = Color.BLACK; private volatile DisplayFont displayFont; diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java index 1a4bfecec..0ac6d70d0 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java @@ -8,7 +8,7 @@ public class DisplayFont { public static final DisplayFont FONT_ORIGINAL = new DisplayFont( "/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf", - 2, 0.3, 3, 5, 12, 5 + 2, 0.3, 3, 5, 15, 5 ); public static final DisplayFont FONT_MODERN = new DisplayFont( diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java index 134b9bd55..1f907fbdd 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java @@ -157,7 +157,6 @@ private void insertHereIs() { } private void drawChar(char c) { - System.out.println(c + " - " + (int)c); Point cursorPoint = cursor.getCursorPoint(); synchronized (videoMemory) { videoMemory[cursorPoint.y * columns + cursorPoint.x] = c; diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf index 54d9399083d8e2f83648cbb0c5264a239821ebcf..32d74918429d412ef453ff8ee5d460812601aeb4 100644 GIT binary patch delta 10800 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 M^en@x`rjh|7geERuK)l5 delta 11001 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 M^en@x`rjh|7geERuK)l5 delta 11001 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 EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1024 0 l 24,1,-1 - 843 0 l 24,2,-1 - 0 843 l 25,3,-1 - 0 949 l 25,4,-1 - 843 1792 l 24,5,6 - 843 1792 843 1792 1024 1792 c 25,0,-1 +1216 1792 m 25,0,-1 + 1216 0 l 24,1,-1 + 1035 0 l 24,2,-1 + 192 843 l 25,3,-1 + 192 949 l 25,4,-1 + 1035 1792 l 24,5,6 + 1035 1792 1035 1792 1216 1792 c 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: EOT Encoding: 4 4 3 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG9Xor#n '2/TU!Q)p86#poJ0SS^I5m:XTJ98Vd7X"r:!P0DZ2'D'lGS=3^!8HZQ#82Hl\GuU0!(fUS7'8ja JcGcN EndImage2 Fore SplineSet -512 1536 m 24,0,-1 - 512 768 l 24,1,-1 - 949 768 l 0,2,3 - 1024 768 1024 768 1024 843 c 24,4,5 - 1024 1190 1024 1190 1024 1461 c 0,6,7 - 1024 1536 1024 1536 949 1536 c 24,8,9 - 949 1536 949 1536 512 1536 c 24,0,-1 -949 1792 m 0,10,11 - 1280 1792 1280 1792 1280 1461 c 24,12,13 - 1280 986 1280 986 1280 843 c 0,14,15 - 1280 512 1280 512 949 512 c 24,16,-1 - 256 512 l 25,17,-1 - 256 1792 l 25,18,19 - 256 1792 256 1792 949 1792 c 0,10,11 -0 256 m 25,20,-1 - 1280 256 l 25,21,-1 - 1280 0 l 25,22,-1 - 0 0 l 25,23,-1 - 0 256 l 25,20,-1 +576 1536 m 24,0,-1 + 576 768 l 24,1,-1 + 1013 768 l 0,2,3 + 1088 768 1088 768 1088 843 c 24,4,5 + 1088 1190 1088 1190 1088 1461 c 0,6,7 + 1088 1536 1088 1536 1013 1536 c 24,8,9 + 1013 1536 1013 1536 576 1536 c 24,0,-1 +1013 1792 m 0,10,11 + 1344 1792 1344 1792 1344 1461 c 24,12,13 + 1344 986 1344 986 1344 843 c 0,14,15 + 1344 512 1344 512 1013 512 c 24,16,-1 + 320 512 l 25,17,-1 + 320 1792 l 25,18,19 + 320 1792 320 1792 1013 1792 c 0,10,11 +64 256 m 25,20,-1 + 1344 256 l 25,21,-1 + 1344 0 l 25,22,-1 + 64 0 l 25,23,-1 + 64 256 l 25,20,-1 EndSplineSet Validated: 1 EndChar StartChar: ENQ Encoding: 5 5 4 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG971$7@ YQBn;Z66Gf-5Ztu$G&eO3J&Tn'd2g3[LTA==TE%[N!;9a_je^c!"R$c%];No&HDe2!(fUS7'8ja JcGcN EndImage2 Fore SplineSet -0 256 m 29,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 29,0,-1 -256 512 m 25,4,-1 - 256 1792 l 25,5,-1 - 1280 1792 l 25,6,-1 - 1280 1536 l 25,7,-1 - 512 1536 l 25,8,-1 - 512 1280 l 25,9,-1 - 1024 1280 l 25,10,-1 - 1024 1024 l 25,11,-1 - 512 1024 l 25,12,-1 - 512 768 l 25,13,-1 - 1280 768 l 25,14,-1 - 1280 512 l 25,15,-1 - 256 512 l 25,4,-1 +64 256 m 29,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 29,0,-1 +320 512 m 25,4,-1 + 320 1792 l 25,5,-1 + 1344 1792 l 25,6,-1 + 1344 1536 l 25,7,-1 + 576 1536 l 25,8,-1 + 576 1280 l 25,9,-1 + 1088 1280 l 25,10,-1 + 1088 1024 l 25,11,-1 + 576 1024 l 25,12,-1 + 576 768 l 25,13,-1 + 1344 768 l 25,14,-1 + 1344 512 l 25,15,-1 + 320 512 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: ACK Encoding: 6 6 5 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 118 0 2048 256 256 +Image2: image/png 118 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8+BNffG971$7@ YQBn;Z66Gf-5Ztu$G&eO3TTFF!JmI,gB^Dg^9E8F9Neb@sAYi0`YMc'G#dIl9YIN!!#SZ:.26O @"J@Y EndImage2 Fore SplineSet -768 1461 m 0,0,1 - 768 1536 768 1536 693 1536 c 24,2,3 - 640 1536 640 1536 587 1536 c 0,4,5 - 512 1536 512 1536 512 1461 c 24,6,7 - 512 1114 512 1114 512 843 c 0,8,9 - 512 768 512 768 587 768 c 24,10,11 - 587 768 587 768 693 768 c 0,12,13 - 767 768 767 768 768 843 c 24,14,15 - 768 843 768 843 768 1461 c 0,0,1 -693 1792 m 0,16,17 - 1024 1792 1024 1792 1024 1461 c 24,18,-1 - 1024 1099 l 0,19,20 - 1024 1024 1024 1024 1099 1024 c 24,21,-1 - 1223 1024 l 0,22,23 - 1280 960 1280 960 1280 896 c 128,-1,24 - 1280 832 1280 832 1223 768 c 8,25,-1 - 843 768 l 0,26,27 - 768 768 768 768 768 693 c 24,28,-1 - 768 569 l 0,29,30 - 704 512 704 512 639 512 c 0,31,32 - 596 512 596 512 512 569 c 1,33,-1 - 512 693 l 0,34,35 - 512 768 512 768 437 768 c 24,36,-1 - 57 768 l 0,37,38 - 0 832 0 832 0 896 c 128,-1,39 - 0 960 0 960 57 1024 c 8,40,-1 - 181 1024 l 0,41,42 - 256 1024 256 1024 256 1099 c 24,43,-1 - 256 1461 l 0,44,45 - 256 1792 256 1792 587 1792 c 24,46,47 - 587 1792 587 1792 693 1792 c 0,16,17 -0 256 m 25,48,-1 - 1280 256 l 25,49,-1 - 1280 0 l 25,50,-1 - 0 0 l 25,51,-1 - 0 256 l 25,48,-1 +832 1461 m 0,0,1 + 832 1536 832 1536 757 1536 c 24,2,3 + 704 1536 704 1536 651 1536 c 0,4,5 + 576 1536 576 1536 576 1461 c 24,6,7 + 576 1114 576 1114 576 843 c 0,8,9 + 576 768 576 768 651 768 c 24,10,11 + 651 768 651 768 757 768 c 0,12,13 + 831 768 831 768 832 843 c 24,14,15 + 832 843 832 843 832 1461 c 0,0,1 +757 1792 m 0,16,17 + 1088 1792 1088 1792 1088 1461 c 24,18,-1 + 1088 1099 l 0,19,20 + 1088 1024 1088 1024 1163 1024 c 24,21,-1 + 1287 1024 l 0,22,23 + 1344 960 1344 960 1344 896 c 128,-1,24 + 1344 832 1344 832 1287 768 c 8,25,-1 + 907 768 l 0,26,27 + 832 768 832 768 832 693 c 24,28,-1 + 832 569 l 0,29,30 + 768 512 768 512 703 512 c 0,31,32 + 660 512 660 512 576 569 c 1,33,-1 + 576 693 l 0,34,35 + 576 768 576 768 501 768 c 24,36,-1 + 121 768 l 0,37,38 + 64 832 64 832 64 896 c 128,-1,39 + 64 960 64 960 121 1024 c 8,40,-1 + 245 1024 l 0,41,42 + 320 1024 320 1024 320 1099 c 24,43,-1 + 320 1461 l 0,44,45 + 320 1792 320 1792 651 1792 c 24,46,47 + 651 1792 651 1792 757 1792 c 0,16,17 +64 256 m 25,48,-1 + 1344 256 l 25,49,-1 + 1344 0 l 25,50,-1 + 64 0 l 25,51,-1 + 64 256 l 25,48,-1 EndSplineSet Validated: 1 EndChar StartChar: BS Encoding: 8 8 7 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 114 0 2048 256 256 +Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3&!@&g6 )i_Z=3>,I+h9B=X@"L'NaU&Ap2dhgP.0KVu`tSdDpboV^!!!!j78?7R6=>BF EndImage2 Fore SplineSet -768 1792 m 25,0,-1 - 768 693 l 24,1,-1 - 1099 1024 l 24,2,-1 - 1280 1024 l 25,3,-1 - 1280 843 l 25,4,-1 - 693 256 l 25,5,-1 - 587 256 l 24,6,-1 - 0 843 l 25,7,-1 - 0 1024 l 25,8,-1 - 181 1024 l 24,9,-1 - 512 693 l 24,10,-1 - 512 1792 l 25,11,-1 - 768 1792 l 25,0,-1 +832 1792 m 25,0,-1 + 832 693 l 24,1,-1 + 1163 1024 l 24,2,-1 + 1344 1024 l 25,3,-1 + 1344 843 l 25,4,-1 + 757 256 l 25,5,-1 + 651 256 l 24,6,-1 + 64 843 l 25,7,-1 + 64 1024 l 25,8,-1 + 245 1024 l 24,9,-1 + 576 693 l 24,10,-1 + 576 1792 l 25,11,-1 + 832 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: VT Encoding: 11 11 10 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 115 0 2048 256 256 +Image2: image/png 115 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3&!@&g6 BF EndImage2 Fore SplineSet -693 1536 m 25,0,-1 - 1280 949 l 25,1,-1 - 1280 768 l 24,2,-1 - 1099 768 l 24,3,-1 - 768 1099 l 25,4,-1 - 768 0 l 25,5,-1 - 512 0 l 25,6,-1 - 512 1099 l 25,7,-1 - 181 768 l 24,8,-1 - 0 768 l 24,9,-1 - 0 949 l 25,10,-1 - 587 1536 l 24,11,12 - 587 1536 587 1536 693 1536 c 25,0,-1 +757 1536 m 25,0,-1 + 1344 949 l 25,1,-1 + 1344 768 l 24,2,-1 + 1163 768 l 24,3,-1 + 832 1099 l 25,4,-1 + 832 0 l 25,5,-1 + 576 0 l 25,6,-1 + 576 1099 l 25,7,-1 + 245 768 l 24,8,-1 + 64 768 l 24,9,-1 + 64 949 l 25,10,-1 + 651 1536 l 24,11,12 + 651 1536 651 1536 757 1536 c 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: FF Encoding: 12 12 11 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 117 0 2048 256 256 +Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8Bu3Ns3&!@&g6 dNM)#3z8OZBBY!QNJ EndImage2 Fore SplineSet -843 1536 m 9,0,-1 - 256 949 l 25,1,-1 - 256 843 l 25,2,-1 - 843 256 l 24,3,-1 - 1024 256 l 25,4,-1 - 1024 437 l 24,5,-1 - 587 843 l 25,6,-1 - 587 949 l 25,7,-1 - 1024 1355 l 25,8,-1 - 1024 1536 l 17,9,10 - 1024 1536 1024 1536 843 1536 c 9,0,-1 -0 1792 m 25,11,-1 - 1280 1792 l 25,12,-1 - 1280 0 l 25,13,-1 - 0 0 l 25,14,-1 - 0 1792 l 25,11,-1 +907 1536 m 9,0,-1 + 320 949 l 25,1,-1 + 320 843 l 25,2,-1 + 907 256 l 24,3,-1 + 1088 256 l 25,4,-1 + 1088 437 l 24,5,-1 + 651 843 l 25,6,-1 + 651 949 l 25,7,-1 + 1088 1355 l 25,8,-1 + 1088 1536 l 17,9,10 + 1088 1536 1088 1536 907 1536 c 9,0,-1 +64 1792 m 25,11,-1 + 1344 1792 l 25,12,-1 + 1344 0 l 25,13,-1 + 64 0 l 25,14,-1 + 64 1792 l 25,11,-1 EndSplineSet Validated: 1 EndChar StartChar: SO Encoding: 14 14 13 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 124 0 2048 256 256 +Image2: image/png 124 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$NmS16+:&(=s8UEqUl0oQ LKs2CC@3!7"eHuMkm?#7THE5sf`KBbhuqL+047'Q#W'0mZn#,22gY)t;6V5H/(OK:z8OZBB Y!QNJ EndImage2 Fore SplineSet -639 715 m 1,0,1 - 639 715 639 715 181 256 c 1,2,3 - 181 256 181 256 0 256 c 25,4,5 - 0 256 0 256 0 437 c 9,6,7 - 0 437 0 437 587 1024 c 24,8,9 - 587 1024 587 1024 693 1024 c 25,10,11 - 693 1024 693 1024 1280 437 c 1,12,13 - 1280 437 1280 437 1280 256 c 25,14,15 - 1280 256 1280 256 1099 256 c 1,16,-1 - 639 715 l 1,0,1 -639 1483 m 1,17,18 - 639 1483 639 1483 181 1024 c 1,19,20 - 181 1024 181 1024 0 1024 c 25,21,22 - 0 1024 0 1024 0 1205 c 9,23,24 - 0 1205 0 1205 587 1792 c 24,25,26 - 587 1792 587 1792 693 1792 c 25,27,28 - 693 1792 693 1792 1280 1205 c 1,29,30 - 1280 1205 1280 1205 1280 1024 c 25,31,32 - 1280 1024 1280 1024 1099 1024 c 1,33,-1 - 639 1483 l 1,17,18 +703 715 m 1,0,1 + 703 715 703 715 245 256 c 1,2,3 + 245 256 245 256 64 256 c 25,4,5 + 64 256 64 256 64 437 c 9,6,7 + 64 437 64 437 651 1024 c 24,8,9 + 651 1024 651 1024 757 1024 c 25,10,11 + 757 1024 757 1024 1344 437 c 1,12,13 + 1344 437 1344 437 1344 256 c 25,14,15 + 1344 256 1344 256 1163 256 c 1,16,-1 + 703 715 l 1,0,1 +703 1483 m 1,17,18 + 703 1483 703 1483 245 1024 c 1,19,20 + 245 1024 245 1024 64 1024 c 25,21,22 + 64 1024 64 1024 64 1205 c 9,23,24 + 64 1205 64 1205 651 1792 c 24,25,26 + 651 1792 651 1792 757 1792 c 25,27,28 + 757 1792 757 1792 1344 1205 c 1,29,30 + 1344 1205 1344 1205 1344 1024 c 25,31,32 + 1344 1024 1344 1024 1163 1024 c 1,33,-1 + 703 1483 l 1,17,18 EndSplineSet Validated: 1 EndChar StartChar: SI Encoding: 15 15 14 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 117 0 2048 256 256 +Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8C%,9r(&3hH^h !)*qlUDq8WdLK3//d[\n>60q@R0JfW!@h1P0aQbK(`SkI!(.8@$q!`Nd/X.H!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -639 1333 m 129,-1,1 - 639 1333 639 1333 1099 1792 c 1,2,-1 - 1280 1792 l 25,3,4 - 1280 1611 1280 1611 1280 1611 c 1,5,6 - 693 1024 693 1024 693 1024 c 25,7,8 - 587 1024 587 1024 587 1024 c 24,9,10 - 0 1611 0 1611 0 1611 c 17,11,12 - 0 1792 0 1792 0 1792 c 25,13,14 - 181 1792 181 1792 181 1792 c 1,15,0 - 639 1333 639 1333 639 1333 c 129,-1,1 -639 565 m 129,-1,17 - 639 565 639 565 1099 1024 c 1,18,-1 - 1280 1024 l 25,19,20 - 1280 843 1280 843 1280 843 c 1,21,22 - 693 256 693 256 693 256 c 25,23,24 - 587 256 587 256 587 256 c 24,25,26 - 0 843 0 843 0 843 c 17,27,28 - 0 1024 0 1024 0 1024 c 25,29,30 - 181 1024 181 1024 181 1024 c 1,31,16 - 639 565 639 565 639 565 c 129,-1,17 +703 1333 m 129,-1,1 + 703 1333 703 1333 1163 1792 c 1,2,-1 + 1344 1792 l 25,3,4 + 1344 1611 1344 1611 1344 1611 c 1,5,6 + 757 1024 757 1024 757 1024 c 25,7,8 + 651 1024 651 1024 651 1024 c 24,9,10 + 64 1611 64 1611 64 1611 c 17,11,12 + 64 1792 64 1792 64 1792 c 25,13,14 + 245 1792 245 1792 245 1792 c 1,15,0 + 703 1333 703 1333 703 1333 c 129,-1,1 +703 565 m 129,-1,17 + 703 565 703 565 1163 1024 c 1,18,-1 + 1344 1024 l 25,19,20 + 1344 843 1344 843 1344 843 c 1,21,22 + 757 256 757 256 757 256 c 25,23,24 + 651 256 651 256 651 256 c 24,25,26 + 64 843 64 843 64 843 c 17,27,28 + 64 1024 64 1024 64 1024 c 25,29,30 + 245 1024 245 1024 245 1024 c 1,31,16 + 703 565 703 565 703 565 c 129,-1,17 EndSplineSet Validated: 1 EndChar StartChar: DLE Encoding: 16 16 15 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 125 0 2048 256 256 +Image2: image/png 125 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$NmS16+:&'Ro`)[29fN`Y p*+D;;#>!T[%'][V"7?e"L(4V;hm6G&)\0@P5D5ed9GVPDAkq5,R^q"*(*=ArjbLg]`8$4!(fUS 7'8jaJcGcN EndImage2 Fore SplineSet -437 768 m 1,0,1 - 437 768 437 768 949 768 c 0,2,3 - 1024 768 1024 768 1024 843 c 0,4,5 - 1024 843 1024 843 1024 1355 c 0,6,7 - 1024 1355 1024 1355 437 768 c 1,0,1 -256 949 m 129,-1,9 - 256 949 256 949 843 1536 c 1,10,11 - 843 1536 843 1536 330 1536 c 0,12,13 - 256 1536 256 1536 256 1461 c 0,14,8 - 256 949 256 949 256 949 c 129,-1,9 -0 256 m 25,15,-1 - 1280 255 l 25,16,-1 - 1280 0 l 25,17,-1 - 0 0 l 25,18,-1 - 0 256 l 25,15,-1 -949 1792 m 0,19,20 - 1280 1792 1280 1792 1280 1461 c 24,21,22 - 1280 1461 1280 1461 1280 843 c 0,23,24 - 1280 512 1280 512 949 512 c 24,25,-1 - 331 512 l 0,26,27 - 0 512 0 512 0 843 c 24,28,29 - 0 843 0 843 0 1461 c 0,30,31 - 0 1792 0 1792 331 1792 c 24,32,33 - 331 1792 331 1792 949 1792 c 0,19,20 +501 768 m 1,0,1 + 501 768 501 768 1013 768 c 0,2,3 + 1088 768 1088 768 1088 843 c 0,4,5 + 1088 843 1088 843 1088 1355 c 0,6,7 + 1088 1355 1088 1355 501 768 c 1,0,1 +320 949 m 129,-1,9 + 320 949 320 949 907 1536 c 1,10,11 + 907 1536 907 1536 394 1536 c 0,12,13 + 320 1536 320 1536 320 1461 c 0,14,8 + 320 949 320 949 320 949 c 129,-1,9 +64 256 m 25,15,-1 + 1344 255 l 25,16,-1 + 1344 0 l 25,17,-1 + 64 0 l 25,18,-1 + 64 256 l 25,15,-1 +1013 1792 m 0,19,20 + 1344 1792 1344 1792 1344 1461 c 24,21,22 + 1344 1461 1344 1461 1344 843 c 0,23,24 + 1344 512 1344 512 1013 512 c 24,25,-1 + 395 512 l 0,26,27 + 64 512 64 512 64 843 c 24,28,29 + 64 843 64 843 64 1461 c 0,30,31 + 64 1792 64 1792 395 1792 c 24,32,33 + 395 1792 395 1792 1013 1792 c 0,19,20 EndSplineSet Validated: 1 EndChar StartChar: DC1 Encoding: 17 17 16 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 114 0 2048 256 256 +Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HN: $?/Rg<.YkCZNY4MMRc7t'J$Cj`<&qrcO,c_0t`@E!a .f^Fg_B=Qr!3?/G#a3,<)r(d:Os#`4-=F03"f)KlDNGjZ<>aR\ec5]\B,;(H"(9UY!!!!j78?7R 6=>BF EndImage2 Fore SplineSet -0 256 m 1,0,1 - 0 256 0 256 1280 256 c 1,2,3 - 1280 256 1280 256 1280 0 c 1,4,5 - 1280 0 1280 0 0 0 c 1,6,7 - 0 0 0 0 0 256 c 1,0,1 -711 1792 m 0,8,9 - 1024 1792 1024 1792 1024 1461 c 0,10,11 - 1024 1461 1024 1461 1024 1355 c 1,12,-1 - 512 843 l 0,13,14 - 512 768 512 768 587 768 c 0,15,-1 - 949 768 l 0,16,17 - 1024 768 1024 768 1024 640 c 0,18,19 - 1024 513 1024 513 949 512 c 0,20,21 - 949 512 949 512 256 512 c 0,22,23 - 256 512 256 512 258 948 c 0,24,-1 - 769 1460 l 0,25,26 - 768 1536 768 1536 711 1536 c 0,27,-1 - 256 1536 l 0,28,29 - 256 1536 256 1536 256 1792 c 0,30,31 - 256 1792 256 1792 711 1792 c 0,8,9 +64 256 m 1,0,1 + 64 256 64 256 1344 256 c 1,2,3 + 1344 256 1344 256 1344 0 c 1,4,5 + 1344 0 1344 0 64 0 c 1,6,7 + 64 0 64 0 64 256 c 1,0,1 +775 1792 m 0,8,9 + 1088 1792 1088 1792 1088 1461 c 0,10,11 + 1088 1461 1088 1461 1088 1355 c 1,12,-1 + 576 843 l 0,13,14 + 576 768 576 768 651 768 c 0,15,-1 + 1013 768 l 0,16,17 + 1088 768 1088 768 1088 640 c 0,18,19 + 1088 513 1088 513 1013 512 c 0,20,21 + 1013 512 1013 512 320 512 c 0,22,23 + 320 512 320 512 322 948 c 0,24,-1 + 833 1460 l 0,25,26 + 832 1536 832 1536 775 1536 c 0,27,-1 + 320 1536 l 0,28,29 + 320 1536 320 1536 320 1792 c 0,30,31 + 320 1792 320 1792 775 1792 c 0,8,9 EndSplineSet Validated: 1 EndChar StartChar: DC3 Encoding: 19 19 18 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9N3T>a .f^Fg_B=QrJ-@3K9`h1'`<;PN16#`E2YVe<@$?,/!cf$12j#rt!,QWn$?T36%fcS0!(fUS7'8ja JcGcN EndImage2 Fore SplineSet -0 256 m 1,0,1 - 0 256 0 256 1280 256 c 0,2,3 - 1280 256 1280 256 1280 0 c 0,4,5 - 1280 0 1280 0 0 0 c 0,6,7 - 0 0 0 0 0 256 c 1,0,1 -711 1792 m 256,8,9 - 1024 1792 1024 1792 1024 1465 c 0,10,11 - 1024 1465 1024 1465 1024 843 c 0,12,13 - 1024 512 1024 512 693 512 c 1,14,15 - 693 512 693 512 256 512 c 0,16,17 - 256 512 256 512 256 768 c 0,18,-1 - 693 768 l 0,19,20 - 768 768 768 768 768 843 c 1,21,-1 - 768 949 l 0,22,23 - 768 1024 768 1024 693 1024 c 24,24,-1 - 256 1024 l 0,25,26 - 256 1024 256 1024 256 1280 c 0,27,-1 - 693 1280 l 0,28,29 - 768 1280 768 1280 768 1355 c 24,30,31 - 768 1410 768 1410 768 1465 c 0,32,33 - 768 1536 768 1536 693 1536 c 0,34,-1 - 256 1536 l 0,35,36 - 256 1536 256 1536 256 1792 c 257,37,38 - 256 1792 256 1792 711 1792 c 256,8,9 +64 256 m 1,0,1 + 64 256 64 256 1344 256 c 0,2,3 + 1344 256 1344 256 1344 0 c 0,4,5 + 1344 0 1344 0 64 0 c 0,6,7 + 64 0 64 0 64 256 c 1,0,1 +775 1792 m 256,8,9 + 1088 1792 1088 1792 1088 1465 c 0,10,11 + 1088 1465 1088 1465 1088 843 c 0,12,13 + 1088 512 1088 512 757 512 c 1,14,15 + 757 512 757 512 320 512 c 0,16,17 + 320 512 320 512 320 768 c 0,18,-1 + 757 768 l 0,19,20 + 832 768 832 768 832 843 c 1,21,-1 + 832 949 l 0,22,23 + 832 1024 832 1024 757 1024 c 24,24,-1 + 320 1024 l 0,25,26 + 320 1024 320 1024 320 1280 c 0,27,-1 + 757 1280 l 0,28,29 + 832 1280 832 1280 832 1355 c 24,30,31 + 832 1410 832 1410 832 1465 c 0,32,33 + 832 1536 832 1536 757 1536 c 0,34,-1 + 320 1536 l 0,35,36 + 320 1536 320 1536 320 1792 c 257,37,38 + 320 1792 320 1792 775 1792 c 256,8,9 EndSplineSet Validated: 1 EndChar StartChar: DC4 Encoding: 20 20 19 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 122 0 2048 256 256 +Image2: image/png 122 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8D_*$Z[Q1)J/h /&3J<;?9euP/LoFL'd&jJJE]W_b>U.0ZUt'!"#;kK#Bq"`pb=\63,n&(C(FW?:"Vl!!#SZ:.26O @"J@Y EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 -768 1355 m 0,4,-1 - 437 1024 l 0,5,-1 - 768 1024 l 0,6,7 - 768 1024 768 1024 768 1355 c 0,4,-1 -1024 1792 m 0,8,-1 - 1024 1024 l 0,9,-1 - 1223 1024 l 1,10,11 - 1280 1024 1280 1024 1280 896 c 128,-1,12 - 1280 768 1280 768 1223 768 c 1,13,-1 - 1024 768 l 0,14,-1 - 1024 512 l 0,15,16 - 1024 512 1024 512 768 512 c 0,17,-1 - 768 768 l 0,18,-1 - 256 768 l 0,19,20 - 256 768 256 768 256 1205 c 0,21,22 - 256 1205 256 1205 843 1792 c 0,23,24 - 843 1792 843 1792 1024 1792 c 0,8,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +832 1355 m 0,4,-1 + 501 1024 l 0,5,-1 + 832 1024 l 0,6,7 + 832 1024 832 1024 832 1355 c 0,4,-1 +1088 1792 m 0,8,-1 + 1088 1024 l 0,9,-1 + 1287 1024 l 1,10,11 + 1344 1024 1344 1024 1344 896 c 128,-1,12 + 1344 768 1344 768 1287 768 c 1,13,-1 + 1088 768 l 0,14,-1 + 1088 512 l 0,15,16 + 1088 512 1088 512 832 512 c 0,17,-1 + 832 768 l 0,18,-1 + 320 768 l 0,19,20 + 320 768 320 768 320 1205 c 0,21,22 + 320 1205 320 1205 907 1792 c 0,23,24 + 907 1792 907 1792 1088 1792 c 0,8,-1 EndSplineSet Validated: 1 EndChar StartChar: NAK Encoding: 21 21 20 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 115 0 2048 256 256 +Image2: image/png 115 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8CJNffG9Xot.% &d0_8b@4mVY(-[d.`e/7]@#FC,^>Ae.*+!!!!j78?7R6=>BF EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 -1280 1792 m 25,4,5 - 1280 1792 1280 1792 1280 843 c 0,6,7 - 1280 512 1280 512 949 512 c 16,8,9 - 949 512 949 512 587 512 c 0,10,11 - 256 512 256 512 256 843 c 24,12,13 - 256 843 256 843 256 1792 c 25,14,-1 - 512 1792 l 25,15,-1 - 512 843 l 0,16,17 - 512 768 512 768 587 768 c 24,18,-1 - 949 768 l 2,19,20 - 1024 768 1024 768 1024 843 c 10,21,-1 - 1024 1792 l 24,22,23 - 1024 1792 1024 1792 1280 1792 c 25,4,5 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +1344 1792 m 25,4,5 + 1344 1792 1344 1792 1344 843 c 0,6,7 + 1344 512 1344 512 1013 512 c 16,8,9 + 1013 512 1013 512 651 512 c 0,10,11 + 320 512 320 512 320 843 c 24,12,13 + 320 843 320 843 320 1792 c 25,14,-1 + 576 1792 l 25,15,-1 + 576 843 l 0,16,17 + 576 768 576 768 651 768 c 24,18,-1 + 1013 768 l 2,19,20 + 1088 768 1088 768 1088 843 c 10,21,-1 + 1088 1792 l 24,22,23 + 1088 1792 1088 1792 1344 1792 c 25,4,5 EndSplineSet Validated: 1 EndChar StartChar: SYN Encoding: 22 22 21 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 117 0 2048 256 256 +Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8C%,9r(&3hH^I ((5m(A-5LALdnk9YR)FN@A]^`#0F\U^a9@c!:g2G2j"gW!5.A/#EmW9`rH)>!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 -640 852 m 1,4,5 - 640 852 640 852 1024 1461 c 1,6,7 - 1024 1461 1024 1461 1024 1792 c 0,8,9 - 1024 1792 1024 1792 1280 1792 c 1,10,-1 - 1280 1355 l 1,11,-1 - 693 512 l 1,12,13 - 693 512 693 512 587 512 c 0,14,15 - 587 512 587 512 0 1355 c 1,16,-1 - 0 1792 l 1,17,18 - 0 1792 0 1792 256 1792 c 0,19,20 - 256 1628 256 1628 256 1465 c 1,21,22 - 256 1465 256 1465 640 852 c 1,4,5 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +704 852 m 1,4,5 + 704 852 704 852 1088 1461 c 1,6,7 + 1088 1461 1088 1461 1088 1792 c 0,8,9 + 1088 1792 1088 1792 1344 1792 c 1,10,-1 + 1344 1355 l 1,11,-1 + 757 512 l 1,12,13 + 757 512 757 512 651 512 c 0,14,15 + 651 512 651 512 64 1355 c 1,16,-1 + 64 1792 l 1,17,18 + 64 1792 64 1792 320 1792 c 0,19,20 + 320 1628 320 1628 320 1465 c 1,21,22 + 320 1465 320 1465 704 852 c 1,4,5 EndSplineSet Validated: 1 EndChar StartChar: ETB Encoding: 23 23 22 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 115 0 2048 256 256 +Image2: image/png 115 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8C%,9r(&3hH^I ((1AM!*psG/R/BF EndImage2 Fore SplineSet -0 256 m 1,0,-1 - 1280 256 l 1,1,-1 - 1280 0 l 1,2,-1 - 0 0 l 1,3,4 - 0 0 0 0 0 256 c 1,0,-1 -639 625 m 1,5,6 - 639 512 639 512 437 512 c 0,7,8 - 437 512 437 512 331 512 c 0,9,10 - 0 512 0 512 0 843 c 0,11,12 - 0 843 0 843 0 1792 c 1,13,14 - 0 1792 0 1792 256 1792 c 1,15,-1 - 256 843 l 1,16,17 - 256 768 256 768 331 768 c 0,18,19 - 437 768 437 768 437 768 c 0,20,21 - 512 768 512 768 512 843 c 0,22,23 - 512 1223 512 1223 512 1223 c 0,24,25 - 512 1280 512 1280 639 1280 c 0,26,27 - 768 1280 768 1280 768 1223 c 0,28,29 - 768 843 768 843 768 843 c 1,30,31 - 768 768 768 768 843 768 c 0,32,33 - 949 768 949 768 949 768 c 0,34,35 - 1024 768 1024 768 1024 843 c 0,36,37 - 1024 1792 1024 1792 1024 1792 c 129,-1,38 - 1024 1792 1024 1792 1280 1792 c 1,39,40 - 1280 1792 1280 1792 1280 843 c 0,41,42 - 1280 512 1280 512 949 512 c 0,43,44 - 949 512 949 512 843 512 c 0,45,46 - 639 512 639 512 639 625 c 1,5,6 +64 256 m 1,0,-1 + 1344 256 l 1,1,-1 + 1344 0 l 1,2,-1 + 64 0 l 1,3,4 + 64 0 64 0 64 256 c 1,0,-1 +703 625 m 1,5,6 + 703 512 703 512 501 512 c 0,7,8 + 501 512 501 512 395 512 c 0,9,10 + 64 512 64 512 64 843 c 0,11,12 + 64 843 64 843 64 1792 c 1,13,14 + 64 1792 64 1792 320 1792 c 1,15,-1 + 320 843 l 1,16,17 + 320 768 320 768 395 768 c 0,18,19 + 501 768 501 768 501 768 c 0,20,21 + 576 768 576 768 576 843 c 0,22,23 + 576 1223 576 1223 576 1223 c 0,24,25 + 576 1280 576 1280 703 1280 c 0,26,27 + 832 1280 832 1280 832 1223 c 0,28,29 + 832 843 832 843 832 843 c 1,30,31 + 832 768 832 768 907 768 c 0,32,33 + 1013 768 1013 768 1013 768 c 0,34,35 + 1088 768 1088 768 1088 843 c 0,36,37 + 1088 1792 1088 1792 1088 1792 c 129,-1,38 + 1088 1792 1088 1792 1344 1792 c 1,39,40 + 1344 1792 1344 1792 1344 843 c 0,41,42 + 1344 512 1344 512 1013 512 c 0,43,44 + 1013 512 1013 512 907 512 c 0,45,46 + 703 512 703 512 703 625 c 1,5,6 EndSplineSet Validated: 1 EndChar StartChar: CAN Encoding: 24 24 23 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 126 0 2048 256 256 +Image2: image/png 126 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W77fm5<#?L$:.Z&u+:&>Ss5t#,..n,f 7@"NIYs&En9qFILi$7D9%*!.Q+uL7.F;"h1%qP2.C%F2=e^lS,:q5*1GQ9@X+p4-_J"coC!!#SZ :.26O@"J@Y EndImage2 Fore SplineSet -0 256 m 1,0,-1 - 1280 256 l 1,1,-1 - 1280 0 l 1,2,-1 - 0 0 l 1,3,-1 - 0 256 l 1,0,-1 -639 1330 m 1,4,5 - 639 1330 639 1330 1100 1792 c 0,6,7 - 1100 1792 1100 1792 1280 1792 c 1,8,9 - 1280 1792 1280 1792 1280 1611 c 1,10,11 - 1280 1611 1280 1611 834 1147 c 1,12,13 - 834 1147 834 1147 1280 693 c 0,14,-1 - 1280 512 l 1,15,-1 - 1099 512 l 0,16,-1 - 639 951 l 1,17,18 - 639 951 639 951 181 512 c 0,19,20 - 181 512 181 512 0 512 c 1,21,22 - 0 512 0 512 0 693 c 0,23,24 - 0 693 0 693 459 1152 c 1,25,26 - 459 1152 459 1152 0 1611 c 1,27,-1 - 0 1792 l 1,28,29 - 0 1792 0 1792 181 1792 c 0,30,31 - 181 1792 181 1792 639 1330 c 1,4,5 +64 256 m 1,0,-1 + 1344 256 l 1,1,-1 + 1344 0 l 1,2,-1 + 64 0 l 1,3,-1 + 64 256 l 1,0,-1 +703 1330 m 1,4,5 + 703 1330 703 1330 1164 1792 c 0,6,7 + 1164 1792 1164 1792 1344 1792 c 1,8,9 + 1344 1792 1344 1792 1344 1611 c 1,10,11 + 1344 1611 1344 1611 898 1147 c 1,12,13 + 898 1147 898 1147 1344 693 c 0,14,-1 + 1344 512 l 1,15,-1 + 1163 512 l 0,16,-1 + 703 951 l 1,17,18 + 703 951 703 951 245 512 c 0,19,20 + 245 512 245 512 64 512 c 1,21,22 + 64 512 64 512 64 693 c 0,23,24 + 64 693 64 693 523 1152 c 1,25,26 + 523 1152 523 1152 64 1611 c 1,27,-1 + 64 1792 l 1,28,29 + 64 1792 64 1792 245 1792 c 0,30,31 + 245 1792 245 1792 703 1330 c 1,4,5 EndSplineSet Validated: 1 EndChar StartChar: EM Encoding: 25 25 24 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 116 0 2048 256 256 +Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8C%,9r(&3hH^h !)*qlUDq8WdLK3//d[[C.f_;C!TFi%1EL'Va9rjA6rj]r%SITCDP?uKz8OZBBY!QNJ EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 -640 1333 m 1,4,5 - 1099 1792 1099 1792 1099 1792 c 0,6,7 - 1280 1792 1280 1792 1280 1792 c 129,-1,8 - 1280 1792 1280 1792 1280 1611 c 1,9,-1 - 768 1099 l 1,10,-1 - 768 512 l 1,11,-1 - 512 512 l 1,12,-1 - 512 1099 l 1,13,-1 - 0 1611 l 1,14,-1 - 0 1792 l 1,15,16 - 181 1792 181 1792 181 1792 c 0,17,18 - 640 1333 640 1333 640 1333 c 1,4,5 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +704 1333 m 1,4,5 + 1163 1792 1163 1792 1163 1792 c 0,6,7 + 1344 1792 1344 1792 1344 1792 c 129,-1,8 + 1344 1792 1344 1792 1344 1611 c 1,9,-1 + 832 1099 l 1,10,-1 + 832 512 l 1,11,-1 + 576 512 l 1,12,-1 + 576 1099 l 1,13,-1 + 64 1611 l 1,14,-1 + 64 1792 l 1,15,16 + 245 1792 245 1792 245 1792 c 0,17,18 + 704 1333 704 1333 704 1333 c 1,4,5 EndSplineSet Validated: 1 EndChar StartChar: SUB Encoding: 26 26 25 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 109 0 2048 256 256 +Image2: image/png 109 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8sb%RU9&*Yr8r ,9nE81*:$\'?kQ7P<7,XDc.Es'WIA=B.t!(mqHqrZ$u-ia5I!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 -0 1792 m 24,4,-1 - 1280 1792 l 25,5,-1 - 1280 1611 l 25,6,-1 - 437 768 l 24,7,-1 - 1280 768 l 24,8,-1 - 1280 512 l 25,9,-1 - 0 512 l 25,10,-1 - 0 693 l 24,11,-1 - 843 1536 l 24,12,-1 - 0 1536 l 24,13,14 - 0 1536 0 1536 0 1792 c 24,4,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +64 1792 m 24,4,-1 + 1344 1792 l 25,5,-1 + 1344 1611 l 25,6,-1 + 501 768 l 24,7,-1 + 1344 768 l 24,8,-1 + 1344 512 l 25,9,-1 + 64 512 l 25,10,-1 + 64 693 l 24,11,-1 + 907 1536 l 24,12,-1 + 64 1536 l 24,13,14 + 64 1536 64 1536 64 1792 c 24,4,-1 EndSplineSet Validated: 1 EndChar StartChar: ESC Encoding: 27 27 26 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 118 0 2048 256 256 +Image2: image/png 118 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%RU9&*YsiL A-#.hO<+N).faS:-"'?4?jpRE?t(5sY(.o6YaGQ9""rCP.fa&r'FgPi7r\M/!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -1024 1536 m 24,0,-1 - 256 1536 l 24,1,-1 - 256 256 l 25,2,-1 - 1024 256 l 24,3,-1 - 1024 512 l 25,4,-1 - 512 512 l 25,5,-1 - 512 768 l 24,6,-1 - 768 768 l 24,7,-1 - 768 1024 l 25,8,-1 - 512 1024 l 25,9,-1 - 512 1280 l 25,10,-1 - 1024 1280 l 24,11,12 - 1024 1280 1024 1280 1024 1536 c 24,0,-1 -0 1792 m 25,13,-1 - 1280 1792 l 25,14,-1 - 1280 0 l 25,15,-1 - 0 0 l 25,16,-1 - 0 1792 l 25,13,-1 +1088 1536 m 24,0,-1 + 320 1536 l 24,1,-1 + 320 256 l 25,2,-1 + 1088 256 l 24,3,-1 + 1088 512 l 25,4,-1 + 576 512 l 25,5,-1 + 576 768 l 24,6,-1 + 832 768 l 24,7,-1 + 832 1024 l 25,8,-1 + 576 1024 l 25,9,-1 + 576 1280 l 25,10,-1 + 1088 1280 l 24,11,12 + 1088 1280 1088 1280 1088 1536 c 24,0,-1 +64 1792 m 25,13,-1 + 1344 1792 l 25,14,-1 + 1344 0 l 25,15,-1 + 64 0 l 25,16,-1 + 64 1792 l 25,13,-1 EndSplineSet Validated: 1 EndChar StartChar: FS Encoding: 28 28 27 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 113 0 2048 256 256 +Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8C%,9n7D"pQE9 !Vd?`J[FH9"BL%K&R5>h748LNMEj!,J@pEk9k9ju!.ec!#8A0)mJm4e!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 -181 1792 m 24,4,-1 - 1280 693 l 24,5,-1 - 1280 512 l 25,6,-1 - 1099 512 l 24,7,-1 - 0 1611 l 25,8,-1 - 0 1792 l 25,9,10 - 0 1792 0 1792 181 1792 c 24,4,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +245 1792 m 24,4,-1 + 1344 693 l 24,5,-1 + 1344 512 l 25,6,-1 + 1163 512 l 24,7,-1 + 64 1611 l 25,8,-1 + 64 1792 l 25,9,10 + 64 1792 64 1792 245 1792 c 24,4,-1 EndSplineSet Validated: 1 EndChar StartChar: GS Encoding: 29 29 28 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 115 0 2048 256 256 +Image2: image/png 115 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8+BNffG9Xor#n '1`BF EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 -256 1792 m 25,4,-1 - 1024 1792 l 25,5,-1 - 1024 512 l 24,6,-1 - 256 512 l 25,7,-1 - 256 768 l 24,8,-1 - 768 768 l 24,9,-1 - 768 1536 l 24,10,-1 - 256 1536 l 24,11,12 - 256 1536 256 1536 256 1792 c 25,4,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +320 1792 m 25,4,-1 + 1088 1792 l 25,5,-1 + 1088 512 l 24,6,-1 + 320 512 l 25,7,-1 + 320 768 l 24,8,-1 + 832 768 l 24,9,-1 + 832 1536 l 24,10,-1 + 320 1536 l 24,11,12 + 320 1536 320 1536 320 1792 c 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: RS Encoding: 30 30 29 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 118 0 2048 256 256 +Image2: image/png 118 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns2BO@1f( h*;aC$0W!UENg0#8Oc12@@.&_#$d%QOH%8W#]9^fE+BD#0`]\&)?>?3fNeIW!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -0 1536 m 24,0,-1 - 1024 1536 l 24,1,-1 - 1024 1280 l 25,2,-1 - 437 1280 l 24,3,-1 - 1280 437 l 24,4,-1 - 1280 256 l 25,5,-1 - 1099 256 l 24,6,-1 - 256 1099 l 25,7,-1 - 256 512 l 25,8,-1 - 0 512 l 25,9,10 - 0 512 0 512 0 1536 c 24,0,-1 +64 1536 m 24,0,-1 + 1088 1536 l 24,1,-1 + 1088 1280 l 25,2,-1 + 501 1280 l 24,3,-1 + 1344 437 l 24,4,-1 + 1344 256 l 25,5,-1 + 1163 256 l 24,6,-1 + 320 1099 l 25,7,-1 + 320 512 l 25,8,-1 + 64 512 l 25,9,10 + 64 512 64 512 64 1536 c 24,0,-1 EndSplineSet Validated: 1 EndChar StartChar: US Encoding: 31 31 30 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 117 0 2048 256 256 +Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8Dg*$Z[QM@bLD 'NlO`XoM`T9HdL=8.q7f5Sdfg&m6psLkF"VYSAi\0RJpr!/i!7$j7etH2mpF!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -1280 1792 m 25,0,-1 - 1280 512 l 25,1,-1 - 437 512 l 24,2,-1 - 768 181 l 24,3,-1 - 768 0 l 25,4,-1 - 587 0 l 24,5,-1 - 0 587 l 25,6,-1 - 0 693 l 24,7,-1 - 587 1280 l 24,8,-1 - 768 1280 l 25,9,-1 - 768 1099 l 25,10,-1 - 437 768 l 24,11,-1 - 1024 768 l 24,12,-1 - 1024 1792 l 24,13,14 - 1024 1792 1024 1792 1280 1792 c 25,0,-1 +1344 1792 m 25,0,-1 + 1344 512 l 25,1,-1 + 501 512 l 24,2,-1 + 832 181 l 24,3,-1 + 832 0 l 25,4,-1 + 651 0 l 24,5,-1 + 64 587 l 25,6,-1 + 64 693 l 24,7,-1 + 651 1280 l 24,8,-1 + 832 1280 l 25,9,-1 + 832 1099 l 25,10,-1 + 501 768 l 24,11,-1 + 1088 768 l 24,12,-1 + 1088 1792 l 24,13,14 + 1088 1792 1088 1792 1344 1792 c 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: exclam Encoding: 33 33 31 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 96 -512 2048 256 256 +Image2: image/png 96 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ $;a-Q3:p1#b;4)ri:7$O`M*SJUBW=Iz8OZBBY!QNJ EndImage2 Fore SplineSet -0 256 m 29,0,-1 - 256 256 l 25,1,-1 - 256 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 29,0,-1 -0 1792 m 25,4,-1 - 256 1792 l 25,5,-1 - 256 512 l 25,6,-1 - 0 512 l 25,7,-1 - 0 1792 l 25,4,-1 +576 256 m 29,0,-1 + 832 256 l 25,1,-1 + 832 0 l 25,2,-1 + 576 0 l 25,3,-1 + 576 256 l 29,0,-1 +576 1792 m 25,4,-1 + 832 1792 l 25,5,-1 + 832 512 l 25,6,-1 + 576 512 l 25,7,-1 + 576 1792 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: quotedbl Encoding: 34 34 32 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 103 -256 2048 256 256 +Image2: image/png 103 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8CJNffG9X9;!; Ws:.?(-lLG<5;%h)pjR5jqG+RTE5*=0F/+t#&COF!!!!j78?7R6=>BF EndImage2 Fore SplineSet -512 1792 m 24,0,-1 - 768 1792 l 24,1,-1 - 768 1024 l 25,2,-1 - 512 1024 l 25,3,4 - 512 1024 512 1024 512 1792 c 24,0,-1 -0 1792 m 24,5,-1 - 256 1792 l 24,6,-1 - 256 1024 l 25,7,-1 - 0 1024 l 25,8,9 - 0 1024 0 1024 0 1792 c 24,5,-1 +832 1792 m 24,0,-1 + 1088 1792 l 24,1,-1 + 1088 1024 l 25,2,-1 + 832 1024 l 25,3,4 + 832 1024 832 1024 832 1792 c 24,0,-1 +320 1792 m 24,5,-1 + 576 1792 l 24,6,-1 + 576 1024 l 25,7,-1 + 320 1024 l 25,8,9 + 320 1024 320 1024 320 1792 c 24,5,-1 EndSplineSet Validated: 1 EndChar StartChar: numbersign Encoding: 35 35 33 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 107 0 2048 256 256 +Image2: image/png 107 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CJNffG9X9;!; Ws:.?(-lMbZsm-gCb$0XK20,m'NW]@K732)-<;#GT!!!!j78?7R6=>BF EndImage2 Fore SplineSet -768 1024 m 25,0,-1 - 512 1024 l 25,1,-1 - 512 768 l 24,2,-1 - 768 768 l 17,3,4 - 768 768 768 768 768 1024 c 25,0,-1 -1024 1792 m 25,5,-1 - 1024 1280 l 24,6,-1 - 1280 1280 l 25,7,-1 - 1280 1024 l 25,8,-1 - 1024 1024 l 24,9,-1 - 1024 768 l 24,10,-1 - 1280 768 l 24,11,-1 - 1280 512 l 25,12,-1 - 1024 512 l 24,13,-1 - 1024 0 l 24,14,-1 - 768 0 l 25,15,-1 - 768 512 l 25,16,-1 - 512 512 l 25,17,-1 - 512 0 l 25,18,-1 - 256 0 l 25,19,-1 - 256 512 l 25,20,-1 - 0 512 l 25,21,-1 - 0 768 l 24,22,-1 - 256 768 l 24,23,-1 - 256 1024 l 25,24,-1 - 0 1024 l 25,25,-1 - 0 1280 l 25,26,-1 - 256 1280 l 25,27,-1 - 256 1792 l 25,28,-1 - 512 1792 l 25,29,-1 - 512 1280 l 25,30,-1 - 768 1280 l 25,31,-1 - 768 1792 l 25,32,-1 - 1024 1792 l 25,5,-1 +832 1024 m 25,0,-1 + 576 1024 l 25,1,-1 + 576 768 l 24,2,-1 + 832 768 l 17,3,4 + 832 768 832 768 832 1024 c 25,0,-1 +1088 1792 m 25,5,-1 + 1088 1280 l 24,6,-1 + 1344 1280 l 25,7,-1 + 1344 1024 l 25,8,-1 + 1088 1024 l 24,9,-1 + 1088 768 l 24,10,-1 + 1344 768 l 24,11,-1 + 1344 512 l 25,12,-1 + 1088 512 l 24,13,-1 + 1088 0 l 24,14,-1 + 832 0 l 25,15,-1 + 832 512 l 25,16,-1 + 576 512 l 25,17,-1 + 576 0 l 25,18,-1 + 320 0 l 25,19,-1 + 320 512 l 25,20,-1 + 64 512 l 25,21,-1 + 64 768 l 24,22,-1 + 320 768 l 24,23,-1 + 320 1024 l 25,24,-1 + 64 1024 l 25,25,-1 + 64 1280 l 25,26,-1 + 320 1280 l 25,27,-1 + 320 1792 l 25,28,-1 + 576 1792 l 25,29,-1 + 576 1280 l 25,30,-1 + 832 1280 l 25,31,-1 + 832 1792 l 25,32,-1 + 1088 1792 l 25,5,-1 EndSplineSet Validated: 1 EndChar StartChar: dollar Encoding: 36 36 34 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 127 0 2048 256 256 +Image2: image/png 127 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W7S-!6<#?L$bs;]P5R^!,B't03:)+gl TJW.17)c^/\UJ/BF EndImage2 Fore SplineSet -768 768 m 9,0,-1 - 768 512 l 25,1,2 - 768 512 768 512 949 512 c 0,3,4 - 1024 512 1024 512 1024 587 c 24,5,6 - 1024 678 1024 678 1024 693 c 0,7,8 - 1024 768 1024 768 949 768 c 16,9,10 - 858 768 858 768 768 768 c 9,0,-1 -331 1280 m 0,11,12 - 256 1280 256 1280 256 1205 c 16,13,14 - 256 1114 256 1114 256 1099 c 0,15,16 - 256 1024 256 1024 329 1024 c 0,17,18 - 330 1024 330 1024 331 1024 c 8,19,-1 - 512 1024 l 25,20,-1 - 512 1280 l 25,21,22 - 512 1280 512 1280 331 1280 c 0,11,12 -331 768 m 16,23,24 - 0 768 0 768 0 1099 c 24,25,26 - 0 1099 0 1099 0 1205 c 0,27,28 - 0 1536 0 1536 331 1536 c 24,29,-1 - 512 1536 l 24,30,-1 - 512 1792 l 25,31,-1 - 768 1792 l 25,32,-1 - 768 1536 l 24,33,-1 - 1280 1536 l 24,34,35 - 1280 1536 1280 1536 1280 1280 c 25,36,-1 - 768 1280 l 25,37,-1 - 768 1024 l 25,38,-1 - 949 1024 l 0,39,40 - 1280 1024 1280 1024 1280 693 c 24,41,42 - 1280 693 1280 693 1280 587 c 0,43,44 - 1280 256 1280 256 949 256 c 24,45,-1 - 768 256 l 25,46,-1 - 768 0 l 25,47,-1 - 512 0 l 25,48,-1 - 512 256 l 25,49,-1 - 0 256 l 25,50,-1 - 0 512 l 25,51,-1 - 512 512 l 25,52,53 - 512 512 512 512 512 768 c 24,54,-1 - 331 768 l 16,23,24 +832 768 m 9,0,-1 + 832 512 l 25,1,2 + 832 512 832 512 1013 512 c 0,3,4 + 1088 512 1088 512 1088 587 c 24,5,6 + 1088 678 1088 678 1088 693 c 0,7,8 + 1088 768 1088 768 1013 768 c 16,9,10 + 922 768 922 768 832 768 c 9,0,-1 +395 1280 m 0,11,12 + 320 1280 320 1280 320 1205 c 16,13,14 + 320 1114 320 1114 320 1099 c 0,15,16 + 320 1024 320 1024 393 1024 c 0,17,18 + 394 1024 394 1024 395 1024 c 8,19,-1 + 576 1024 l 25,20,-1 + 576 1280 l 25,21,22 + 576 1280 576 1280 395 1280 c 0,11,12 +395 768 m 16,23,24 + 64 768 64 768 64 1099 c 24,25,26 + 64 1099 64 1099 64 1205 c 0,27,28 + 64 1536 64 1536 395 1536 c 24,29,-1 + 576 1536 l 24,30,-1 + 576 1792 l 25,31,-1 + 832 1792 l 25,32,-1 + 832 1536 l 24,33,-1 + 1344 1536 l 24,34,35 + 1344 1536 1344 1536 1344 1280 c 25,36,-1 + 832 1280 l 25,37,-1 + 832 1024 l 25,38,-1 + 1013 1024 l 0,39,40 + 1344 1024 1344 1024 1344 693 c 24,41,42 + 1344 693 1344 693 1344 587 c 0,43,44 + 1344 256 1344 256 1013 256 c 24,45,-1 + 832 256 l 25,46,-1 + 832 0 l 25,47,-1 + 576 0 l 25,48,-1 + 576 256 l 25,49,-1 + 64 256 l 25,50,-1 + 64 512 l 25,51,-1 + 576 512 l 25,52,53 + 576 512 576 512 576 768 c 24,54,-1 + 395 768 l 16,23,24 EndSplineSet Validated: 1 EndChar StartChar: percent Encoding: 37 37 35 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$N_p8d+:(< ,fgO%MSLRse..^NK'C;:'FZM=Xb'c.b9XS4\/YkV3U.S!$>mtlz8OZBBY!QNJ EndImage2 Fore SplineSet -1077 384 m 1,0,1 - 1280 182 1280 182 1280 182 c 128,-1,2 - 1280 182 1280 182 1280 0 c 25,3,4 - 1280 0 1280 0 1099 0 c 0,5,6 - 1099 0 1099 0 897 204 c 1,7,8 - 897 204 897 204 693 0 c 1,9,10 - 693 0 693 0 331 0 c 0,11,12 - 0 0 0 0 0 331 c 25,13,14 - 0 331 0 331 0 693 c 0,15,16 - 0 693 0 693 203 896 c 9,17,-1 - 0 1099 l 1,18,-1 - 0 1461 l 17,19,20 - 0 1792 0 1792 331 1792 c 24,21,22 - 331 1792 331 1792 437 1792 c 0,23,24 - 768 1792 768 1792 768 1469 c 0,25,26 - 768 1465 768 1465 768 1461 c 9,27,28 - 768 1461 768 1461 768 1099 c 1,29,-1 - 565 896 l 1,30,31 - 565 896 565 896 896 565 c 1,32,33 - 896 565 896 565 1099 768 c 0,34,35 - 1099 768 1099 768 1280 768 c 1,36,37 - 1280 768 1280 768 1280 587 c 1,38,39 - 1077 384 1077 384 1077 384 c 1,0,1 -716 385 m 1,40,41 - 716 385 716 385 387 717 c 1,42,43 - 387 717 387 717 256 587 c 9,44,45 - 256 422 256 422 256 331 c 0,46,47 - 256 256 256 256 331 256 c 24,48,49 - 478 256 478 256 587 256 c 0,50,51 - 587 256 587 256 716 385 c 1,40,41 -384 1077 m 16,52,-1 - 512 1205 l 1,53,54 - 512 1373 512 1373 512 1461 c 0,55,56 - 512 1536 512 1536 437 1536 c 24,57,-1 - 331 1536 l 0,58,59 - 256 1536 256 1536 256 1461 c 24,60,61 - 256 1461 256 1461 256 1205 c 0,62,-1 - 384 1077 l 16,52,-1 +1141 384 m 1,0,1 + 1344 182 1344 182 1344 182 c 128,-1,2 + 1344 182 1344 182 1344 0 c 25,3,4 + 1344 0 1344 0 1163 0 c 0,5,6 + 1163 0 1163 0 961 204 c 1,7,8 + 961 204 961 204 757 0 c 1,9,10 + 757 0 757 0 395 0 c 0,11,12 + 64 0 64 0 64 331 c 25,13,14 + 64 331 64 331 64 693 c 0,15,16 + 64 693 64 693 267 896 c 9,17,-1 + 64 1099 l 1,18,-1 + 64 1461 l 17,19,20 + 64 1792 64 1792 395 1792 c 24,21,22 + 395 1792 395 1792 501 1792 c 0,23,24 + 832 1792 832 1792 832 1469 c 0,25,26 + 832 1465 832 1465 832 1461 c 9,27,28 + 832 1461 832 1461 832 1099 c 1,29,-1 + 629 896 l 1,30,31 + 629 896 629 896 960 565 c 1,32,33 + 960 565 960 565 1163 768 c 0,34,35 + 1163 768 1163 768 1344 768 c 1,36,37 + 1344 768 1344 768 1344 587 c 1,38,39 + 1141 384 1141 384 1141 384 c 1,0,1 +780 385 m 1,40,41 + 780 385 780 385 451 717 c 1,42,43 + 451 717 451 717 320 587 c 9,44,45 + 320 422 320 422 320 331 c 0,46,47 + 320 256 320 256 395 256 c 24,48,49 + 542 256 542 256 651 256 c 0,50,51 + 651 256 651 256 780 385 c 1,40,41 +448 1077 m 16,52,-1 + 576 1205 l 1,53,54 + 576 1373 576 1373 576 1461 c 0,55,56 + 576 1536 576 1536 501 1536 c 24,57,-1 + 395 1536 l 0,58,59 + 320 1536 320 1536 320 1461 c 24,60,61 + 320 1461 320 1461 320 1205 c 0,62,-1 + 448 1077 l 16,52,-1 EndSplineSet Validated: 1 EndChar StartChar: quotesingle Encoding: 39 39 37 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 100 -512 2048 256 256 +Image2: image/png 100 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CNNffG9`^HNZ $;a-Q35d>_jV6]K5dD/Z8^IS?MP^UeJpj^tz8OZBBY!QNJ EndImage2 Fore SplineSet -0 1792 m 25,0,-1 - 256 1792 l 25,1,-1 - 256 1024 l 25,2,-1 - 0 1024 l 25,3,-1 - 0 1792 l 25,0,-1 +576 1792 m 25,0,-1 + 832 1792 l 25,1,-1 + 832 1024 l 25,2,-1 + 576 1024 l 25,3,-1 + 576 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: parenleft Encoding: 40 40 38 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 111 0 2048 256 256 +Image2: image/png 111 320 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8CNNffG9`^HN: $:'ca$j(.\CCAo)'Q]BrKGB%(`oTII6!tAq.09M++V>%^+Bg&k!!!!j78?7R6=>BF EndImage2 Fore SplineSet -768 1792 m 25,0,-1 - 768 1611 l 1,1,-1 - 256 1099 l 0,2,3 - 256 1099 256 1099 256 693 c 1,4,-1 - 768 181 l 0,5,6 - 768 181 768 181 768 0 c 25,7,8 - 768 0 768 0 587 0 c 24,9,10 - 587 0 587 0 0 587 c 25,11,12 - 0 1190 0 1190 0 1205 c 28,13,14 - 0 1205 0 1205 587 1792 c 28,15,16 - 677 1792 677 1792 768 1792 c 25,0,-1 +1088 1792 m 25,0,-1 + 1088 1611 l 1,1,-1 + 576 1099 l 0,2,3 + 576 1099 576 1099 576 693 c 1,4,-1 + 1088 181 l 0,5,6 + 1088 181 1088 181 1088 0 c 25,7,8 + 1088 0 1088 0 907 0 c 24,9,10 + 907 0 907 0 320 587 c 25,11,12 + 320 1190 320 1190 320 1205 c 28,13,14 + 320 1205 320 1205 907 1792 c 28,15,16 + 997 1792 997 1792 1088 1792 c 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: parenright Encoding: 41 41 39 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 113 -512 2048 256 256 +Image2: image/png 113 -192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8CNNffG9`^HNZ $:"f(;Zp/%dY:I.M?4KuTcDJpJD>\C.C]]:,XJj=!8p-S&*9"7QiI*d!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -199 1792 m 25,0,-1 - 768 1205 l 24,1,-1 - 768 587 l 25,2,-1 - 181 0 l 25,3,-1 - 0 0 l 25,4,-1 - 0 182 l 24,5,-1 - 512 693 l 24,6,-1 - 512 1099 l 25,7,-1 - 0 1611 l 25,8,-1 - 0 1792 l 25,9,-1 - 199 1792 l 25,0,-1 +519 1792 m 25,0,-1 + 1088 1205 l 24,1,-1 + 1088 587 l 25,2,-1 + 501 0 l 25,3,-1 + 320 0 l 25,4,-1 + 320 182 l 24,5,-1 + 832 693 l 24,6,-1 + 832 1099 l 25,7,-1 + 320 1611 l 25,8,-1 + 320 1792 l 25,9,-1 + 519 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: asterisk Encoding: 42 42 40 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 120 0 2048 256 256 +Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NS=d?+:(?(s8UE1_?!r( 0@O3sp7:lE5a0,I0O/kjXQZH=DE#=``RHUM5,j"b$(RZ9N"(d-mz8OZBBY!QNJ EndImage2 Fore SplineSet -821 896 m 1,0,1 - 1271 454 1271 454 1280 437 c 0,2,3 - 1280 437 1280 437 1280 256 c 25,4,5 - 1280 256 1280 256 1099 256 c 24,6,7 - 1099 256 1099 256 768 587 c 25,8,-1 - 768 0 l 25,9,-1 - 512 0 l 25,10,-1 - 512 587 l 25,11,-1 - 181 256 l 17,12,13 - 0 256 0 256 0 256 c 25,14,15 - 0 437 0 437 0 437 c 130,-1,16 - 0 437 0 437 459 896 c 1,17,18 - 459 896 459 896 0 1355 c 1,19,20 - 0 1536 0 1536 0 1536 c 152,-1,21 - 0 1536 0 1536 181 1536 c 24,22,23 - 181 1536 181 1536 512 1205 c 24,24,25 - 512 1205 512 1205 512 1792 c 25,26,-1 - 768 1792 l 25,27,-1 - 768 1205 l 0,28,-1 - 1098 1536 l 24,29,30 - 1098 1536 1098 1536 1280 1536 c 0,31,32 - 1280 1536 1280 1536 1280 1355 c 1,33,34 - 1280 1355 1280 1355 821 896 c 1,0,1 +885 896 m 1,0,1 + 1335 454 1335 454 1344 437 c 0,2,3 + 1344 437 1344 437 1344 256 c 25,4,5 + 1344 256 1344 256 1163 256 c 24,6,7 + 1163 256 1163 256 832 587 c 25,8,-1 + 832 0 l 25,9,-1 + 576 0 l 25,10,-1 + 576 587 l 25,11,-1 + 245 256 l 17,12,13 + 64 256 64 256 64 256 c 25,14,15 + 64 437 64 437 64 437 c 130,-1,16 + 64 437 64 437 523 896 c 1,17,18 + 523 896 523 896 64 1355 c 1,19,20 + 64 1536 64 1536 64 1536 c 152,-1,21 + 64 1536 64 1536 245 1536 c 24,22,23 + 245 1536 245 1536 576 1205 c 24,24,25 + 576 1205 576 1205 576 1792 c 25,26,-1 + 832 1792 l 25,27,-1 + 832 1205 l 0,28,-1 + 1162 1536 l 24,29,30 + 1162 1536 1162 1536 1344 1536 c 0,31,32 + 1344 1536 1344 1536 1344 1355 c 1,33,34 + 1344 1355 1344 1355 885 896 c 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: plus Encoding: 43 43 41 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 114 0 2048 256 256 +Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3&!@&g6 !WYmi&I*SHfQ[Ar!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -512 1536 m 29,0,-1 - 768 1536 l 25,1,-1 - 768 1024 l 25,2,-1 - 1280 1024 l 25,3,-1 - 1280 768 l 24,4,-1 - 768 768 l 24,5,-1 - 768 256 l 25,6,-1 - 512 256 l 25,7,-1 - 512 768 l 24,8,-1 - 0 768 l 24,9,-1 - 0 1024 l 25,10,-1 - 512 1024 l 25,11,-1 - 512 1536 l 29,0,-1 +576 1536 m 29,0,-1 + 832 1536 l 25,1,-1 + 832 1024 l 25,2,-1 + 1344 1024 l 25,3,-1 + 1344 768 l 24,4,-1 + 832 768 l 24,5,-1 + 832 256 l 25,6,-1 + 576 256 l 25,7,-1 + 576 768 l 24,8,-1 + 64 768 l 24,9,-1 + 64 1024 l 25,10,-1 + 576 1024 l 25,11,-1 + 576 1536 l 29,0,-1 EndSplineSet Validated: 1 EndChar StartChar: comma Encoding: 44 44 42 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 91 -256 2048 256 256 +Image2: image/png 91 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2\'ehBu @W`0#D?/q@j]_^nKa/-g/b(@l!!!!j78?7R6=>BF EndImage2 Fore SplineSet -512 331 m 0,0,1 - 512 0 512 0 181 0 c 24,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,4,-1 - 181 256 l 0,5,6 - 256 256 256 256 256 331 c 24,7,-1 - 256 768 l 24,8,-1 - 512 768 l 24,9,10 - 512 384 512 384 512 331 c 0,0,1 +960 331 m 0,0,1 + 960 0 960 0 629 0 c 24,2,-1 + 448 0 l 25,3,-1 + 448 256 l 25,4,-1 + 629 256 l 0,5,6 + 704 256 704 256 704 331 c 24,7,-1 + 704 768 l 24,8,-1 + 960 768 l 24,9,10 + 960 384 960 384 960 331 c 0,0,1 EndSplineSet Validated: 1 EndChar StartChar: hyphen Encoding: 45 45 43 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 94 0 2048 256 256 +Image2: image/png 94 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns4Z$5e?V @(66j=Y.W6D!n"P%0-S$$O.#5I6.E/!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -0 1024 m 25,0,-1 - 1280 1024 l 25,1,-1 - 1280 768 l 24,2,-1 - 0 768 l 24,3,4 - 0 768 0 768 0 1024 c 25,0,-1 +64 1024 m 25,0,-1 + 1344 1024 l 25,1,-1 + 1344 768 l 24,2,-1 + 64 768 l 24,3,4 + 64 768 64 768 64 1024 c 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: period Encoding: 46 46 44 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 84 -512 2048 256 256 +Image2: image/png 84 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[;S^Ap Lt+im)m]YX6<>Toz8OZBBY!QNJ EndImage2 Fore SplineSet -0 256 m 29,0,-1 - 256 256 l 25,1,-1 - 256 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 29,0,-1 +576 256 m 29,0,-1 + 832 256 l 25,1,-1 + 832 0 l 25,2,-1 + 576 0 l 25,3,-1 + 576 256 l 29,0,-1 EndSplineSet Validated: 1 EndChar StartChar: slash Encoding: 47 47 45 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 113 0 2048 256 256 +Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns3P!_,XK 'KmiO5a(=h_A-IB";qADJ4gNN!+[6ZO"d9^$.=M9!0Lq/#JY@cIfKHK!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -199 256 m 25,0,-1 - 0 256 l 25,1,-1 - 0 455 l 24,2,-1 - 1081 1536 l 25,3,-1 - 1280 1536 l 25,4,-1 - 1280 1337 l 25,5,6 - 1280 1337 1280 1337 199 256 c 25,0,-1 +263 256 m 25,0,-1 + 64 256 l 25,1,-1 + 64 455 l 24,2,-1 + 1145 1536 l 25,3,-1 + 1344 1536 l 25,4,-1 + 1344 1337 l 25,5,6 + 1344 1337 1344 1337 263 256 c 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: zero Encoding: 48 48 46 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 120 0 2048 256 256 +Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8+BNffG9Xor#n 8-[$EOCD`h9Q7+I-GdXZ$IEpi.)7,8;?SlYfhRo0(sN,F`9.L.=*kqn*O=h/z8OZBBY!QNJ EndImage2 Fore SplineSet -1024 331 m 9,0,-1 - 1024 1099 l 1,1,2 - 1024 1099 1024 1099 256 331 c 1,3,4 - 256 256 256 256 331 256 c 24,5,-1 - 949 256 l 0,6,7 - 1024 256 1024 256 1024 331 c 9,0,-1 -1024 1461 m 0,8,9 - 1024 1536 1024 1536 949 1536 c 0,10,-1 - 331 1536 l 0,11,12 - 256 1536 256 1536 256 1461 c 24,13,14 - 256 1461 256 1461 256 693 c 0,15,16 - 256 693 256 693 1024 1461 c 0,8,9 -949 1792 m 0,17,18 - 1280 1792 1280 1792 1280 1461 c 24,19,20 - 1280 730 1280 730 1280 331 c 0,21,22 - 1280 0 1280 0 949 0 c 24,23,-1 - 331 0 l 0,24,25 - 0 0 0 0 0 331 c 24,26,27 - 0 1062 0 1062 0 1461 c 0,28,29 - 0 1792 0 1792 331 1792 c 24,30,31 - 331 1792 331 1792 949 1792 c 0,17,18 +1088 331 m 9,0,-1 + 1088 1099 l 1,1,2 + 1088 1099 1088 1099 320 331 c 1,3,4 + 320 256 320 256 395 256 c 24,5,-1 + 1013 256 l 0,6,7 + 1088 256 1088 256 1088 331 c 9,0,-1 +1088 1461 m 0,8,9 + 1088 1536 1088 1536 1013 1536 c 0,10,-1 + 395 1536 l 0,11,12 + 320 1536 320 1536 320 1461 c 24,13,14 + 320 1461 320 1461 320 693 c 0,15,16 + 320 693 320 693 1088 1461 c 0,8,9 +1013 1792 m 0,17,18 + 1344 1792 1344 1792 1344 1461 c 24,19,20 + 1344 730 1344 730 1344 331 c 0,21,22 + 1344 0 1344 0 1013 0 c 24,23,-1 + 395 0 l 0,24,25 + 64 0 64 0 64 331 c 24,26,27 + 64 1062 64 1062 64 1461 c 0,28,29 + 64 1792 64 1792 395 1792 c 24,30,31 + 395 1792 395 1792 1013 1792 c 0,17,18 EndSplineSet Validated: 1 EndChar StartChar: one Encoding: 49 49 47 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 107 -211 2048 256 256 +Image2: image/png 107 64.0271 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CNNffG9`^HN: $?/Rg<.YkCZNY4MMRc7t.Ofm.&k4,!^]4B4!='>cmbYYX!!!!j78?7R6=>BF EndImage2 Fore SplineSet -301 1734 m 0,0,1 - 358 1792 358 1792 429 1792 c 128,-1,2 - 500 1792 500 1792 557 1734 c 8,3,-1 - 557 331 l 0,4,5 - 557 256 557 256 631 256 c 24,6,-1 - 738 256 l 0,7,8 - 813 199 813 199 813 126 c 0,9,10 - 813 75 813 75 738 0 c 1,11,12 - 738 0 738 0 120 0 c 0,13,14 - 45 75 45 75 45 128 c 0,15,16 - 45 199 45 199 120 256 c 8,17,-1 - 226 256 l 0,18,19 - 301 256 301 256 301 331 c 24,20,21 - 301 1205 301 1205 301 1205 c 0,22,23 - 301 1280 301 1280 226 1280 c 24,24,-1 - 45 1280 l 17,25,26 - 0 1344 0 1344 0 1408 c 128,-1,27 - 0 1472 0 1472 45 1536 c 8,28,-1 - 226 1536 l 0,29,30 - 301 1536 301 1536 301 1611 c 24,31,-1 - 301 1734 l 0,0,1 +576 1734 m 0,0,1 + 576 1792 576 1792 704 1792 c 128,-1,2 + 832 1792 832 1792 832 1734 c 1,3,4 + 832 312 832 312 832 256 c 1,5,-1 + 1013 256 l 0,6,7 + 1088 256 1088 256 1088 128 c 132,-1,9 + 1088 0 1088 0 1013 0 c 2,10,11 + 1013 0 1013 0 395 0 c 0,12,13 + 320 0 320 0 320 127 c 0,14,15 + 320 256 320 256 395 256 c 0,16,-1 + 576 256 l 1,17,18 + 576 256 576 256 576 1280 c 1,19,20 + 538 1280 538 1280 378 1280 c 0,21,22 + 320 1280 320 1280 320 1408 c 128,-1,23 + 320 1536 320 1536 378 1536 c 0,24,-1 + 501 1536 l 0,25,26 + 576 1536 576 1536 576 1611 c 0,27,-1 + 576 1734 l 0,0,1 EndSplineSet Validated: 1 EndChar StartChar: two Encoding: 50 50 48 -Width: 1536 -VWidth: 2048 -Flags: MW +Width: 1408 +Flags: MWO LayerCount: 3 Back -Image2: image/png 124 0 2048 256 256 +Image2: image/png 124 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?K_r!ro=GQ8+BNffG9Xor#n 8-[$EOCD`h9ZS3`0h;_W'd,]a)KZF-2kWgZ%)Hlb9EI\9'u2d_)VHqI,MaFADrB5Wz8OZBB Y!QNJ EndImage2 Fore SplineSet -0 1461 m 0,0,1 - 0 1792 0 1792 331 1792 c 24,2,-1 - 949 1792 l 0,3,4 - 1280 1792 1280 1792 1280 1461 c 24,5,6 - 1280 1114 1280 1114 1280 1099 c 0,7,8 - 1280 768 1280 768 949 768 c 24,9,-1 - 693 768 l 17,10,11 - 693 768 693 768 256 331 c 0,12,13 - 256 256 256 256 329 256 c 0,14,15 - 330 256 330 256 331 256 c 8,16,-1 - 1205 256 l 0,17,18 - 1280 199 1280 199 1280 136 c 0,19,20 - 1280 135 1280 135 1280 134 c 0,21,22 - 1280 76 1280 76 1205 0 c 0,23,24 - 1205 0 1205 0 0 0 c 25,25,26 - 0 0 0 0 0 437 c 0,27,28 - 0 437 0 437 512 949 c 0,29,30 - 587 1024 587 1024 666 1024 c 24,31,32 - 666 1024 666 1024 949 1024 c 0,33,34 - 1024 1024 1024 1024 1024 1099 c 24,35,36 - 1024 1318 1024 1318 1024 1461 c 0,37,38 - 1024 1536 1024 1536 949 1536 c 24,39,-1 - 331 1536 l 0,40,41 - 256 1536 256 1536 256 1461 c 24,42,-1 - 256 1337 l 0,43,44 - 199 1280 199 1280 129 1280 c 1,45,46 - 57 1280 57 1280 0 1337 c 1,47,48 - 0 1337 0 1337 0 1461 c 0,0,1 +64 1461 m 0,0,1 + 64 1792 64 1792 395 1792 c 0,2,-1 + 1013 1792 l 0,3,4 + 1344 1792 1344 1792 1344 1461 c 0,5,6 + 1344 1114 1344 1114 1344 1099 c 0,7,8 + 1344 1099 1344 1099 1013 768 c 0,9,-1 + 757 768 l 1,10,11 + 757 768 757 768 256 256 c 1,12,13 + 256 256 256 256 1269 256 c 0,14,15 + 1344 256 1344 256 1344 128 c 128,-1,16 + 1344 0 1344 0 1269 0 c 2,17,18 + 1269 0 1269 0 64 0 c 1,19,20 + 64 218 64 218 64 437 c 0,21,22 + 64 437 64 437 651 1024 c 2,23,24 + 651 1024 651 1024 907 1024 c 0,25,26 + 907 1024 907 1024 1088 1205 c 0,27,28 + 1088 1205 1088 1205 1088 1461 c 0,29,30 + 1088 1536 1088 1536 1013 1536 c 0,31,-1 + 395 1536 l 0,32,33 + 320 1536 320 1536 320 1461 c 0,34,-1 + 320 1337 l 0,35,36 + 320 1280 320 1280 193 1280 c 1,37,38 + 64 1280 64 1280 64 1337 c 1,39,40 + 64 1337 64 1337 64 1461 c 0,0,1 EndSplineSet -Validated: 1 EndChar StartChar: three Encoding: 51 51 49 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 123 0 2048 256 256 +Image2: image/png 123 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?K_r!ro=GQ8sb%RU9&*Yr8r a<3rAO<+O4680RGkSi@dcum2^_A.TCJhXc&-?K9U:)FF`,dJV92ZNga:DsTEXUAD7!!!!j78?7R 6=>BF EndImage2 Fore SplineSet -75 1792 m 0,0,1 - 75 1792 75 1792 1280 1792 c 25,2,3 - 1280 1792 1280 1792 1280 1355 c 1,4,5 - 1280 1355 1280 1355 1024 1099 c 0,6,7 - 1024 1099 1024 1099 1024 1024 c 1,8,9 - 1280 1024 1280 1024 1280 696 c 0,10,11 - 1280 694 1280 694 1280 693 c 0,12,13 - 1280 693 1280 693 1280 331 c 17,14,15 - 1280 0 1280 0 949 0 c 24,16,17 - 342 0 342 0 331 0 c 0,18,19 - 0 0 0 0 0 331 c 25,20,21 - 0 455 0 455 0 455 c 0,22,23 - 57 512 57 512 125 512 c 0,24,25 - 199 512 199 512 256 455 c 0,26,-1 - 256 331 l 17,27,28 - 256 256 256 256 331 256 c 24,29,30 - 331 256 331 256 949 256 c 0,31,32 - 1024 256 1024 256 1024 331 c 25,33,34 - 1024 550 1024 550 1024 693 c 0,35,36 - 1024 768 1024 768 949 768 c 24,37,-1 - 569 768 l 0,38,39 - 512 825 512 825 512 896 c 128,-1,40 - 512 967 512 967 569 1024 c 8,41,-1 - 587 1024 l 24,42,43 - 587 1024 587 1024 1024 1461 c 17,44,45 - 1024 1536 1024 1536 949 1536 c 24,46,-1 - 75 1536 l 0,47,48 - 0 1593 0 1593 0 1665 c 0,49,50 - 0 1734 0 1734 75 1792 c 0,0,1 +139 1792 m 0,0,1 + 742 1792 742 1792 1344 1792 c 25,2,3 + 1344 1792 1344 1792 1344 1355 c 1,4,5 + 1344 1355 1344 1355 1088 1099 c 0,6,7 + 1088 1099 1088 1099 1088 1024 c 1,8,9 + 1344 1024 1344 1024 1344 696 c 0,10,11 + 1344 694 1344 694 1344 693 c 0,12,13 + 1344 693 1344 693 1344 331 c 17,14,15 + 1344 0 1344 0 1013 0 c 24,16,17 + 406 0 406 0 395 0 c 0,18,19 + 64 0 64 0 64 331 c 25,20,21 + 64 455 64 455 64 455 c 0,22,23 + 64 512 64 512 192 512 c 128,-1,24 + 320 512 320 512 320 455 c 0,25,-1 + 320 331 l 17,26,27 + 320 256 320 256 395 256 c 24,28,29 + 395 256 395 256 1013 256 c 0,30,31 + 1088 256 1088 256 1088 331 c 25,32,33 + 1088 550 1088 550 1088 693 c 0,34,35 + 1088 768 1088 768 1013 768 c 24,36,-1 + 633 768 l 0,37,38 + 576 768 576 768 576 896 c 128,-1,39 + 576 1024 576 1024 633 1024 c 8,40,-1 + 651 1024 l 24,41,42 + 651 1024 651 1024 1088 1461 c 17,43,44 + 1088 1536 1088 1536 1013 1536 c 24,45,-1 + 139 1536 l 0,46,47 + 64 1536 64 1536 64 1664 c 128,-1,48 + 64 1792 64 1792 139 1792 c 0,0,1 EndSplineSet Validated: 1 EndChar StartChar: four Encoding: 52 52 50 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 116 0 2048 256 256 +Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h /&3J<;?9euP/LoF'0]!L#p;kq*/SJM$ShsVBlHRoN5Gi"s0i[Nd4O_kz8OZBBY!QNJ EndImage2 Fore SplineSet -768 768 m 24,0,-1 - 768 1355 l 25,1,-1 - 256 843 l 25,2,-1 - 256 768 l 24,3,4 - 256 768 256 768 768 768 c 24,0,-1 -1024 1792 m 24,5,-1 - 1024 768 l 24,6,-1 - 1223 768 l 0,7,8 - 1280 704 1280 704 1280 640 c 128,-1,9 - 1280 576 1280 576 1223 512 c 8,10,-1 - 1024 512 l 25,11,-1 - 1024 0 l 25,12,-1 - 768 0 l 25,13,-1 - 768 512 l 25,14,-1 - 0 512 l 25,15,-1 - 0 949 l 25,16,-1 - 843 1792 l 24,17,18 - 843 1792 843 1792 1024 1792 c 24,5,-1 +832 768 m 24,0,-1 + 832 1355 l 25,1,-1 + 320 843 l 25,2,-1 + 320 768 l 24,3,4 + 320 768 320 768 832 768 c 24,0,-1 +1088 1792 m 24,5,-1 + 1088 768 l 24,6,-1 + 1287 768 l 0,7,8 + 1344 768 1344 768 1344 640 c 128,-1,9 + 1344 512 1344 512 1287 512 c 8,10,-1 + 1088 512 l 25,11,-1 + 1088 0 l 25,12,-1 + 832 0 l 25,13,-1 + 832 512 l 25,14,-1 + 64 512 l 25,15,-1 + 64 949 l 25,16,-1 + 907 1792 l 24,17,18 + 907 1792 907 1792 1088 1792 c 24,5,-1 EndSplineSet Validated: 1 EndChar StartChar: five Encoding: 53 53 51 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 114 0 2048 256 256 +Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8sb%RU9&*YsiL A-$ei0MF`5b^qI_aN00H+qqPMk^4_=%X\7m"gT=o.fit&)ZhRQ%hJ^@!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -1223 1792 m 0,0,1 - 1280 1730 1280 1730 1280 1666 c 128,-1,2 - 1280 1602 1280 1602 1223 1536 c 8,3,-1 - 256 1536 l 24,4,-1 - 256 1280 l 25,5,-1 - 949 1280 l 0,6,7 - 1280 1280 1280 1280 1280 949 c 24,8,9 - 1280 331 1280 331 1280 331 c 0,10,11 - 1280 0 1280 0 949 0 c 24,12,-1 - 331 0 l 0,13,14 - 0 0 0 0 0 331 c 24,15,16 - 0 455 0 455 0 455 c 0,17,18 - 65 512 65 512 129 512 c 128,-1,19 - 193 512 193 512 256 455 c 8,20,-1 - 256 331 l 0,21,22 - 256 256 256 256 331 256 c 24,23,-1 - 949 256 l 0,24,25 - 1024 256 1024 256 1024 331 c 24,26,27 - 1024 949 1024 949 1024 949 c 0,28,29 - 1024 1024 1024 1024 949 1024 c 24,30,-1 - 0 1024 l 25,31,-1 - 0 1792 l 18,32,33 - 0 1792 0 1792 1223 1792 c 0,0,1 +1287 1792 m 0,0,1 + 1344 1792 1344 1792 1344 1664 c 128,-1,2 + 1344 1536 1344 1536 1287 1536 c 8,3,-1 + 320 1536 l 24,4,-1 + 320 1280 l 25,5,-1 + 1013 1280 l 0,6,7 + 1344 1280 1344 1280 1344 949 c 24,8,9 + 1344 331 1344 331 1344 331 c 0,10,11 + 1344 0 1344 0 1013 0 c 24,12,-1 + 395 0 l 0,13,14 + 64 0 64 0 64 331 c 24,15,16 + 64 455 64 455 64 455 c 0,17,18 + 64 512 64 512 192 512 c 128,-1,19 + 320 512 320 512 320 455 c 8,20,-1 + 320 331 l 0,21,22 + 320 256 320 256 395 256 c 24,23,-1 + 1013 256 l 0,24,25 + 1088 256 1088 256 1088 331 c 24,26,27 + 1088 949 1088 949 1088 949 c 0,28,29 + 1088 1024 1088 1024 1013 1024 c 24,30,-1 + 64 1024 l 25,31,-1 + 64 1792 l 18,32,33 + 64 1792 64 1792 1287 1792 c 0,0,1 EndSplineSet Validated: 1 EndChar StartChar: six Encoding: 54 54 52 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+FNffG9`ah?c "',Db6l(HV">W6rnCdqEJ?/k/,d8$)K':c?+m[.fAc_/9jTCSK!1`*k"G(^D63$uc!(fUS7'8ja JcGcN EndImage2 Fore SplineSet -256 331 m 0,0,1 - 256 256 256 256 331 256 c 24,2,-1 - 949 256 l 0,3,4 - 1024 256 1024 256 1024 331 c 24,5,6 - 1024 550 1024 550 1024 693 c 0,7,8 - 1024 768 1024 768 949 768 c 24,9,10 - 949 768 949 768 256 768 c 24,11,12 - 256 768 256 768 256 331 c 0,0,1 -1223 1792 m 0,13,14 - 1280 1749 1280 1749 1280 1671 c 128,-1,15 - 1280 1593 1280 1593 1223 1536 c 0,16,-1 - 693 1536 l 25,17,-1 - 256 1099 l 25,18,-1 - 256 1024 l 25,19,-1 - 949 1024 l 0,20,21 - 1280 1024 1280 1024 1280 693 c 24,22,23 - 1280 346 1280 346 1280 331 c 0,24,25 - 1280 0 1280 0 949 0 c 24,26,-1 - 331 0 l 0,27,28 - 0 0 0 0 0 331 c 24,29,30 - 0 331 0 331 0 1205 c 24,31,32 - 0 1205 0 1205 587 1792 c 24,33,34 - 587 1792 587 1792 1223 1792 c 0,13,14 +320 331 m 0,0,1 + 320 256 320 256 395 256 c 24,2,-1 + 1013 256 l 0,3,4 + 1088 256 1088 256 1088 331 c 24,5,6 + 1088 550 1088 550 1088 693 c 0,7,8 + 1088 768 1088 768 1013 768 c 24,9,10 + 1013 768 1013 768 320 768 c 24,11,12 + 320 768 320 768 320 331 c 0,0,1 +1287 1792 m 0,13,14 + 1344 1792 1344 1792 1344 1664 c 128,-1,15 + 1344 1536 1344 1536 1287 1536 c 0,16,-1 + 757 1536 l 25,17,-1 + 320 1099 l 25,18,-1 + 320 1024 l 25,19,-1 + 1013 1024 l 0,20,21 + 1344 1024 1344 1024 1344 693 c 24,22,23 + 1344 346 1344 346 1344 331 c 0,24,25 + 1344 0 1344 0 1013 0 c 24,26,-1 + 395 0 l 0,27,28 + 64 0 64 0 64 331 c 24,29,30 + 64 331 64 331 64 1205 c 24,31,32 + 64 1205 64 1205 651 1792 c 24,33,34 + 651 1792 651 1792 1287 1792 c 0,13,14 EndSplineSet Validated: 1 EndChar StartChar: seven Encoding: 55 55 53 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 120 0 2048 256 256 +Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8sb%RU9&*Yr8r a<3rAO<+O4680RGkSi@d5W[:=6(5UsE(Rn]+BsKDL0K3]!TO7^iA_MXMbJN[z8OZBBY!QNJ EndImage2 Fore SplineSet -0 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 1355 l 25,2,-1 - 512 587 l 25,3,-1 - 512 0 l 25,4,-1 - 256 0 l 25,5,-1 - 256 693 l 24,6,-1 - 1024 1461 l 25,7,-1 - 1024 1536 l 25,8,-1 - 0 1536 l 17,9,10 - 0 1536 0 1536 0 1792 c 25,0,-1 +64 1792 m 25,0,-1 + 1344 1792 l 25,1,-1 + 1344 1355 l 25,2,-1 + 576 587 l 25,3,-1 + 576 0 l 25,4,-1 + 320 0 l 25,5,-1 + 320 693 l 24,6,-1 + 1088 1461 l 25,7,-1 + 1088 1536 l 25,8,-1 + 64 1536 l 17,9,10 + 64 1536 64 1536 64 1792 c 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: eight Encoding: 56 56 54 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 100 0 2048 256 256 +Image2: image/png 100 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8+BNffG9Xor#n 8-[$EOCD`h9Q7*n(b?f[")J,@Ce5cOVrrF"z8OZBBY!QNJ EndImage2 Fore SplineSet -256 331 m 0,0,1 - 256 256 256 256 331 256 c 24,2,-1 - 949 256 l 0,3,4 - 1024 256 1024 256 1024 331 c 24,5,6 - 1024 693 1024 693 1024 693 c 1,7,8 - 1024 768 1024 768 949 768 c 1,9,10 - 949 768 949 768 331 768 c 0,11,12 - 256 768 256 768 256 693 c 24,13,14 - 256 608 256 608 256 331 c 0,0,1 -256 1099 m 0,15,16 - 256 1024 256 1024 331 1024 c 24,17,-1 - 949 1024 l 0,18,19 - 1024 1024 1024 1024 1024 1099 c 24,20,21 - 1024 1318 1024 1318 1024 1461 c 0,22,23 - 1024 1536 1024 1536 949 1536 c 24,24,-1 - 331 1536 l 0,25,26 - 256 1536 256 1536 256 1461 c 24,27,28 - 256 1389 256 1389 256 1099 c 0,15,16 -1168 896 m 1,29,30 - 1280 839 1280 839 1280 693 c 0,31,32 - 1280 331 1280 331 1280 331 c 0,33,34 - 1280 0 1280 0 949 0 c 24,35,36 - 331 0 331 0 331 0 c 0,37,38 - 0 0 0 0 0 331 c 24,39,40 - 0 331 0 331 0 693 c 0,41,42 - 1 834 1 834 112 896 c 1,43,44 - 0 957 0 957 0 1099 c 0,45,46 - 0 1461 0 1461 0 1461 c 0,47,48 - 0 1792 0 1792 331 1792 c 24,49,50 - 949 1792 949 1792 949 1792 c 0,51,52 - 1280 1792 1280 1792 1280 1461 c 24,53,54 - 1280 1446 1280 1446 1280 1099 c 0,55,56 - 1280 954 1280 954 1168 896 c 1,29,30 +320 331 m 0,0,1 + 320 256 320 256 395 256 c 24,2,-1 + 1013 256 l 0,3,4 + 1088 256 1088 256 1088 331 c 24,5,6 + 1088 693 1088 693 1088 693 c 1,7,8 + 1088 768 1088 768 1013 768 c 1,9,10 + 1013 768 1013 768 395 768 c 0,11,12 + 320 768 320 768 320 693 c 24,13,14 + 320 608 320 608 320 331 c 0,0,1 +320 1099 m 0,15,16 + 320 1024 320 1024 395 1024 c 24,17,-1 + 1013 1024 l 0,18,19 + 1088 1024 1088 1024 1088 1099 c 24,20,21 + 1088 1318 1088 1318 1088 1461 c 0,22,23 + 1088 1536 1088 1536 1013 1536 c 24,24,-1 + 395 1536 l 0,25,26 + 320 1536 320 1536 320 1461 c 24,27,28 + 320 1389 320 1389 320 1099 c 0,15,16 +1232 896 m 1,29,30 + 1344 839 1344 839 1344 693 c 0,31,32 + 1344 331 1344 331 1344 331 c 0,33,34 + 1344 0 1344 0 1013 0 c 24,35,36 + 395 0 395 0 395 0 c 0,37,38 + 64 0 64 0 64 331 c 24,39,40 + 64 331 64 331 64 693 c 0,41,42 + 65 834 65 834 176 896 c 1,43,44 + 64 957 64 957 64 1099 c 0,45,46 + 64 1461 64 1461 64 1461 c 0,47,48 + 64 1792 64 1792 395 1792 c 24,49,50 + 1013 1792 1013 1792 1013 1792 c 0,51,52 + 1344 1792 1344 1792 1344 1461 c 24,53,54 + 1344 1446 1344 1446 1344 1099 c 0,55,56 + 1344 954 1344 954 1232 896 c 1,29,30 EndSplineSet Validated: 1 EndChar StartChar: nine Encoding: 57 57 55 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 123 0 2048 256 256 +Image2: image/png 123 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?K_r!ro=GQ8+BNffG9Xor#n 8-[$EOCD`h9Q7*n(b?f[aB"t7"1nTe89Dg!BF EndImage2 Fore SplineSet -1024 1461 m 0,0,1 - 1024 1536 1024 1536 949 1536 c 24,2,-1 - 331 1536 l 0,3,4 - 256 1536 256 1536 256 1461 c 24,5,6 - 256 1242 256 1242 256 1099 c 0,7,8 - 256 1024 256 1024 331 1024 c 24,9,-1 - 1024 1024 l 25,10,11 - 1024 1280 1024 1280 1024 1461 c 0,0,1 -949 1792 m 0,12,13 - 1280 1792 1280 1792 1280 1461 c 24,14,15 - 1280 1461 1280 1461 1280 587 c 25,16,-1 - 693 0 l 1,17,-1 - 57 0 l 17,18,19 - 0 63 0 63 0 127 c 128,-1,20 - 0 191 0 191 57 256 c 0,21,-1 - 587 256 l 24,22,23 - 587 256 587 256 1024 693 c 24,24,25 - 1024 693 1024 693 1024 768 c 24,26,-1 - 331 768 l 0,27,28 - 0 768 0 768 0 1099 c 24,29,30 - 0 1446 0 1446 0 1461 c 0,31,32 - 0 1792 0 1792 331 1792 c 24,33,34 - 331 1792 331 1792 949 1792 c 0,12,13 +1088 1461 m 0,0,1 + 1088 1536 1088 1536 1013 1536 c 24,2,-1 + 395 1536 l 0,3,4 + 320 1536 320 1536 320 1461 c 24,5,6 + 320 1242 320 1242 320 1099 c 0,7,8 + 320 1024 320 1024 395 1024 c 24,9,-1 + 1088 1024 l 25,10,11 + 1088 1280 1088 1280 1088 1461 c 0,0,1 +1013 1792 m 0,12,13 + 1344 1792 1344 1792 1344 1461 c 24,14,15 + 1344 1461 1344 1461 1344 587 c 25,16,-1 + 757 0 l 1,17,-1 + 121 0 l 17,18,19 + 64 0 64 0 64 128 c 128,-1,20 + 64 256 64 256 121 256 c 0,21,-1 + 651 256 l 24,22,23 + 651 256 651 256 1088 693 c 24,24,25 + 1088 693 1088 693 1088 768 c 24,26,-1 + 395 768 l 0,27,28 + 64 768 64 768 64 1099 c 24,29,30 + 64 1446 64 1446 64 1461 c 0,31,32 + 64 1792 64 1792 395 1792 c 24,33,34 + 395 1792 395 1792 1013 1792 c 0,12,13 EndSplineSet Validated: 1 EndChar StartChar: colon Encoding: 58 58 56 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 97 -512 2048 256 256 +Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns4f$5aWu Yo3g*!LHaC$7Ih6Wrmm(!&@FZ$m].ZLh)ch@bW1UUYoz8OZBBY!QNJ EndImage2 Fore SplineSet -512 768 m 24,0,1 - 512 768 512 768 512 331 c 0,2,3 - 512 0 512 0 181 0 c 24,4,-1 - 0 0 l 25,5,-1 - 0 256 l 25,6,-1 - 181 256 l 0,7,8 - 256 256 256 256 256 331 c 24,9,-1 - 256 768 l 24,10,11 - 256 768 256 768 512 768 c 24,0,1 -256 1280 m 25,12,-1 - 512 1280 l 25,13,-1 - 512 1024 l 25,14,-1 - 256 1024 l 25,15,-1 - 256 1280 l 25,12,-1 +960 768 m 24,0,1 + 960 768 960 768 960 331 c 0,2,3 + 960 0 960 0 629 0 c 24,4,-1 + 448 0 l 25,5,-1 + 448 256 l 25,6,-1 + 629 256 l 0,7,8 + 704 256 704 256 704 331 c 24,9,-1 + 704 768 l 24,10,11 + 704 768 704 768 960 768 c 24,0,1 +704 1280 m 25,12,-1 + 960 1280 l 25,13,-1 + 960 1024 l 25,14,-1 + 704 1024 l 25,15,-1 + 704 1280 l 25,12,-1 EndSplineSet Validated: 1 EndChar StartChar: less Encoding: 60 60 58 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 116 0 2048 256 256 +Image2: image/png 116 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h .f`.M1CU>bQR'WXOI:?a_#uM/S)%HW!"#kEp_:ObM+\E\.d%TT%fbVFz8OZBBY!QNJ EndImage2 Fore SplineSet -309 896 m 1,0,1 - 309 896 309 896 1024 182 c 0,2,3 - 1024 182 1024 182 1024 0 c 25,4,5 - 1024 0 1024 0 843 0 c 24,6,7 - 843 0 843 0 0 843 c 25,8,-1 - 0 949 l 25,9,10 - 0 949 0 949 843 1792 c 24,11,12 - 843 1792 843 1792 1024 1792 c 24,13,14 - 1024 1792 1024 1792 1024 1611 c 1,15,-1 - 309 896 l 1,0,1 +501 896 m 1,0,1 + 501 896 501 896 1216 182 c 0,2,3 + 1216 182 1216 182 1216 0 c 25,4,5 + 1216 0 1216 0 1035 0 c 24,6,7 + 1035 0 1035 0 192 843 c 25,8,-1 + 192 949 l 25,9,10 + 192 949 192 949 1035 1792 c 24,11,12 + 1035 1792 1035 1792 1216 1792 c 24,13,14 + 1216 1792 1216 1792 1216 1611 c 1,15,-1 + 501 896 l 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: equal Encoding: 61 61 59 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 96 0 2048 256 256 +Image2: image/png 96 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8Bu3Ns2`"cP]X (fhd6b(@jRAf]t[&9K/tn7*(2lS*^gz8OZBBY!QNJ EndImage2 Fore SplineSet -0 768 m 24,0,-1 - 1280 768 l 24,1,-1 - 1280 512 l 25,2,-1 - 0 512 l 25,3,4 - 0 512 0 512 0 768 c 24,0,-1 -0 1280 m 25,5,-1 - 1280 1280 l 25,6,-1 - 1280 1024 l 25,7,-1 - 0 1024 l 25,8,-1 - 0 1280 l 25,5,-1 +64 768 m 24,0,-1 + 1344 768 l 24,1,-1 + 1344 512 l 25,2,-1 + 64 512 l 25,3,4 + 64 512 64 512 64 768 c 24,0,-1 +64 1280 m 25,5,-1 + 1344 1280 l 25,6,-1 + 1344 1024 l 25,7,-1 + 64 1024 l 25,8,-1 + 64 1280 l 25,5,-1 EndSplineSet Validated: 1 EndChar StartChar: greater Encoding: 62 62 60 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 114 -256 2048 256 256 +Image2: image/png 114 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?L$c9Vp?+:&'8li7!DD@\!2 /(Y77eXll!"%j1]?p11f#p"OPpWj:T+ftqt">",1((Z@:V:5JF!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -715 896 m 129,-1,1 - 715 896 715 896 0 1611 c 1,2,-1 - 0 1792 l 25,3,4 - 181 1792 181 1792 181 1792 c 24,5,6 - 1024 949 1024 949 1024 949 c 25,7,8 - 1024 843 1024 843 1024 843 c 25,9,10 - 181 0 181 0 181 0 c 24,11,12 - 0 0 0 0 0 0 c 25,13,14 - 0 181 0 181 0 181 c 0,15,0 - 715 896 715 896 715 896 c 129,-1,1 +907 896 m 129,-1,1 + 907 896 907 896 192 1611 c 1,2,-1 + 192 1792 l 25,3,4 + 373 1792 373 1792 373 1792 c 24,5,6 + 1216 949 1216 949 1216 949 c 25,7,8 + 1216 843 1216 843 1216 843 c 25,9,10 + 373 0 373 0 373 0 c 24,11,12 + 192 0 192 0 192 0 c 25,13,14 + 192 181 192 181 192 181 c 0,15,0 + 907 896 907 896 907 896 c 129,-1,1 EndSplineSet Validated: 1 EndChar StartChar: question Encoding: 63 63 61 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 120 0 2048 256 256 +Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8+BNffG9Xor#n 8-[$EOCD`h9ZS2q8W^2N0XJ#UU*tO@7&Suj+BsQ$#d+0\-ccVp@J)Z[b`.KE;r1Z)!B$?j@tkj!!;``sDh9cj5nz8OZBB Y!QNJ EndImage2 Fore SplineSet -1024 1461 m 1,0,1 - 1024 1536 1024 1536 949 1536 c 0,2,3 - 640 1536 640 1536 331 1536 c 1,4,5 - 256 1536 256 1536 256 1461 c 1,6,7 - 256 1461 256 1461 256 331 c 1,8,9 - 256 256 256 256 331 256 c 1,10,11 - 331 256 331 256 1223 256 c 0,12,13 - 1279 182 1279 182 1279 137 c 0,14,15 - 1278 73 1278 73 1223 0 c 0,16,17 - 1223 0 1223 0 313 0 c 0,18,19 - 0 0 0 0 0 327 c 1,20,21 - 0 1026 0 1026 0 1461 c 0,22,23 - 0 1792 0 1792 331 1792 c 0,24,25 - 331 1792 331 1792 949 1792 c 0,26,27 - 1280 1792 1280 1792 1280 1461 c 0,28,29 - 1280 986 1280 986 1280 839 c 0,30,31 - 1280 512 1280 512 949 512 c 0,32,33 - 896 512 896 512 843 512 c 0,34,35 - 512 512 512 512 512 843 c 0,36,37 - 512 843 512 843 512 1223 c 0,38,39 - 569 1280 569 1280 640 1280 c 128,-1,40 - 711 1280 711 1280 768 1223 c 0,41,-1 - 768 896 l 0,42,43 - 768 825 768 825 843 825 c 0,44,45 - 843 825 843 825 949 825 c 0,46,47 - 1024 825 1024 825 1024 896 c 0,48,49 - 1024 896 1024 896 1024 1461 c 1,0,1 +1088 1461 m 1,0,1 + 1088 1536 1088 1536 1013 1536 c 0,2,3 + 704 1536 704 1536 395 1536 c 1,4,5 + 320 1536 320 1536 320 1461 c 1,6,7 + 320 1461 320 1461 320 331 c 1,8,9 + 320 256 320 256 395 256 c 1,10,11 + 395 256 395 256 1287 256 c 0,12,13 + 1344 256 1344 256 1344 128 c 128,-1,14 + 1344 0 1344 0 1287 0 c 0,15,16 + 1287 0 1287 0 377 0 c 0,17,18 + 64 0 64 0 64 327 c 1,19,20 + 64 1026 64 1026 64 1461 c 0,21,22 + 64 1792 64 1792 395 1792 c 0,23,24 + 395 1792 395 1792 1013 1792 c 0,25,26 + 1344 1792 1344 1792 1344 1461 c 0,27,28 + 1344 986 1344 986 1344 839 c 0,29,30 + 1344 512 1344 512 1013 512 c 0,31,32 + 1013 512 1013 512 907 512 c 0,33,34 + 576 512 576 512 576 843 c 0,35,36 + 576 1213 576 1213 576 1223 c 0,37,38 + 576 1280 576 1280 704 1280 c 128,-1,39 + 832 1280 832 1280 832 1223 c 0,40,-1 + 832 896 l 0,41,42 + 832 825 832 825 907 825 c 0,43,44 + 907 825 907 825 1013 825 c 0,45,46 + 1088 825 1088 825 1088 896 c 0,47,48 + 1088 896 1088 896 1088 1461 c 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: A Encoding: 65 65 63 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 119 0 2048 256 256 +Image2: image/png 119 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8CNNffG9`^HN: $:'asKBF EndImage2 Fore SplineSet -640 1483 m 1,0,1 - 640 1483 640 1483 256 1099 c 1,2,-1 - 256 825 l 0,3,4 - 256 768 256 768 313 768 c 24,5,6 - 313 768 313 768 967 768 c 0,7,8 - 1024 768 1024 768 1024 825 c 24,9,10 - 1024 825 1024 825 1024 1099 c 0,11,-1 - 640 1483 l 1,0,1 -693 1792 m 17,12,13 - 693 1792 693 1792 1280 1205 c 24,14,-1 - 1280 0 l 25,15,-1 - 1024 0 l 25,16,-1 - 1024 455 l 0,17,18 - 1024 512 1024 512 967 512 c 24,19,20 - 640 512 640 512 313 512 c 24,21,22 - 256 512 256 512 256 455 c 24,23,-1 - 256 0 l 25,24,-1 - 0 0 l 25,25,-1 - 0 1205 l 24,26,-1 - 587 1792 l 24,27,28 - 587 1792 587 1792 693 1792 c 17,12,13 +704 1483 m 1,0,1 + 704 1483 704 1483 320 1099 c 1,2,-1 + 320 825 l 0,3,4 + 320 768 320 768 377 768 c 24,5,6 + 377 768 377 768 1031 768 c 0,7,8 + 1088 768 1088 768 1088 825 c 24,9,10 + 1088 825 1088 825 1088 1099 c 0,11,-1 + 704 1483 l 1,0,1 +757 1792 m 17,12,13 + 757 1792 757 1792 1344 1205 c 24,14,-1 + 1344 0 l 25,15,-1 + 1088 0 l 25,16,-1 + 1088 455 l 0,17,18 + 1088 512 1088 512 1031 512 c 24,19,20 + 704 512 704 512 377 512 c 24,21,22 + 320 512 320 512 320 455 c 24,23,-1 + 320 0 l 25,24,-1 + 64 0 l 25,25,-1 + 64 1205 l 24,26,-1 + 651 1792 l 24,27,28 + 651 1792 651 1792 757 1792 c 17,12,13 EndSplineSet Validated: 1 EndChar StartChar: B Encoding: 66 66 64 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 96 0 2048 256 256 +Image2: image/png 96 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8sb%RgE0H5;TS A3i[S7MJ$"*n.r'K>@lpj;8j5Q?;#Rz8OZBBY!QNJ EndImage2 Fore SplineSet -256 768 m 0,0,-1 - 256 256 l 1,1,-1 - 967 256 l 0,2,3 - 1024 256 1024 256 1024 313 c 1,4,5 - 1024 640 1024 640 1024 711 c 0,6,7 - 1024 768 1024 768 967 768 c 1,8,9 - 256 768 256 768 256 768 c 0,0,-1 -967 1024 m 1,10,11 - 1024 1024 1024 1024 1024 1081 c 0,12,-1 - 1024 1465 l 1,13,14 - 1024 1536 1024 1536 967 1536 c 0,15,-1 - 256 1536 l 1,16,-1 - 256 1024 l 1,17,-1 - 967 1024 l 1,10,11 -967 1792 m 0,18,19 - 1280 1792 1280 1792 1280 1465 c 1,20,21 - 1280 1180 1280 1180 1280 1081 c 0,22,23 - 1280 896 1280 896 1152 896 c 1,24,25 - 1280 896 1280 896 1280 710 c 0,26,-1 - 1280 313 l 1,27,28 - 1280 0 1280 0 967 0 c 0,29,-1 - 0 0 l 1,30,-1 - 0 1792 l 1,31,32 - 0 1792 0 1792 967 1792 c 0,18,19 +320 768 m 0,0,-1 + 320 256 l 1,1,-1 + 1031 256 l 0,2,3 + 1088 256 1088 256 1088 313 c 1,4,5 + 1088 640 1088 640 1088 711 c 0,6,7 + 1088 768 1088 768 1031 768 c 1,8,9 + 320 768 320 768 320 768 c 0,0,-1 +1031 1024 m 1,10,11 + 1088 1024 1088 1024 1088 1081 c 0,12,-1 + 1088 1465 l 1,13,14 + 1088 1536 1088 1536 1031 1536 c 0,15,-1 + 320 1536 l 1,16,-1 + 320 1024 l 1,17,-1 + 1031 1024 l 1,10,11 +1031 1792 m 0,18,19 + 1344 1792 1344 1792 1344 1465 c 1,20,21 + 1344 1180 1344 1180 1344 1081 c 0,22,23 + 1344 896 1344 896 1216 896 c 1,24,25 + 1344 896 1344 896 1344 710 c 0,26,-1 + 1344 313 l 1,27,28 + 1344 0 1344 0 1031 0 c 0,29,-1 + 64 0 l 1,30,-1 + 64 1792 l 1,31,32 + 64 1792 64 1792 1031 1792 c 0,18,19 EndSplineSet Validated: 1 EndChar StartChar: C Encoding: 67 67 65 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 117 0 2048 256 256 +Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n 8-[$EOCD`h9Q7+1#-oLF#X\X(#1=5/3uDKH$cl(R6$,$c!::.1#VQD@0)ttP!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -256 313 m 1,0,1 - 256 256 256 256 313 256 c 0,2,3 - 640 256 640 256 967 256 c 0,4,5 - 1024 256 1024 256 1024 313 c 0,6,7 - 1024 313 1024 313 1024 512 c 1,8,9 - 1024 512 1024 512 1280 512 c 1,10,-1 - 1280 313 l 1,11,12 - 1280 0 1280 0 967 0 c 0,13,14 - 640 0 640 0 313 0 c 0,15,16 - 0 0 0 0 0 313 c 1,17,18 - 0 313 0 313 0 512 c 1,19,20 - 0 512 0 512 0 1280 c 1,21,-1 - 0 1465 l 1,22,23 - 0 1792 0 1792 313 1792 c 0,24,25 - 640 1792 640 1792 967 1792 c 0,26,27 - 1280 1792 1280 1792 1280 1465 c 1,28,29 - 1280 1465 1280 1465 1280 1280 c 1,30,-1 - 1024 1279 l 1,31,32 - 1024 1464 1024 1464 1024 1465 c 0,33,34 - 1024 1536 1024 1536 967 1536 c 0,35,36 - 967 1536 967 1536 313 1536 c 1,37,38 - 256 1536 256 1536 256 1465 c 1,39,40 - 256 889 256 889 256 313 c 1,0,1 +320 313 m 1,0,1 + 320 256 320 256 377 256 c 0,2,3 + 704 256 704 256 1031 256 c 0,4,5 + 1088 256 1088 256 1088 313 c 0,6,7 + 1088 313 1088 313 1088 512 c 1,8,9 + 1088 512 1088 512 1344 512 c 1,10,-1 + 1344 313 l 1,11,12 + 1344 0 1344 0 1031 0 c 0,13,14 + 704 0 704 0 377 0 c 0,15,16 + 64 0 64 0 64 313 c 1,17,18 + 64 313 64 313 64 512 c 1,19,20 + 64 512 64 512 64 1280 c 1,21,-1 + 64 1465 l 1,22,23 + 64 1792 64 1792 377 1792 c 0,24,25 + 704 1792 704 1792 1031 1792 c 0,26,27 + 1344 1792 1344 1792 1344 1465 c 1,28,29 + 1344 1465 1344 1465 1344 1280 c 1,30,-1 + 1088 1279 l 1,31,32 + 1088 1464 1088 1464 1088 1465 c 0,33,34 + 1088 1536 1088 1536 1031 1536 c 0,35,36 + 1031 1536 1031 1536 377 1536 c 1,37,38 + 320 1536 320 1536 320 1465 c 1,39,40 + 320 889 320 889 320 313 c 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: D Encoding: 68 68 66 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 98 0 2048 256 256 +Image2: image/png 98 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.7lon<#?K_r!ro=GQ8sb%RgE0H5;TS A3i[S7MJ$"*n.r'FAP6L(B>)*&cj#e^:jRI!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -967 256 m 0,0,1 - 1024 256 1024 256 1024 313 c 1,2,3 - 1024 313 1024 313 1024 1465 c 1,4,5 - 1024 1536 1024 1536 967 1536 c 1,6,7 - 967 1536 967 1536 256 1536 c 1,8,-1 - 256 256 l 1,9,10 - 612 256 612 256 967 256 c 0,0,1 -967 1792 m 0,11,12 - 1280 1789 1280 1789 1280 1465 c 0,13,14 - 1280 1236 1280 1236 1280 313 c 0,15,16 - 1280 0 1280 0 967 0 c 1,17,18 - 967 0 967 0 0 0 c 1,19,20 - 0 0 0 0 0 1792 c 0,21,22 - 0 1792 0 1792 967 1792 c 0,11,12 +1031 256 m 0,0,1 + 1088 256 1088 256 1088 313 c 1,2,3 + 1088 313 1088 313 1088 1465 c 1,4,5 + 1088 1536 1088 1536 1031 1536 c 1,6,7 + 1031 1536 1031 1536 320 1536 c 1,8,-1 + 320 256 l 1,9,10 + 676 256 676 256 1031 256 c 0,0,1 +1031 1792 m 0,11,12 + 1344 1789 1344 1789 1344 1465 c 0,13,14 + 1344 1236 1344 1236 1344 313 c 0,15,16 + 1344 0 1344 0 1031 0 c 1,17,18 + 1031 0 1031 0 64 0 c 1,19,20 + 64 0 64 0 64 1792 c 0,21,22 + 64 1792 64 1792 1031 1792 c 0,11,12 EndSplineSet Validated: 1 EndChar StartChar: E Encoding: 69 69 67 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 102 0 2048 256 256 +Image2: image/png 102 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8sb%RU9&*YsiL A-$eiR*Z#`q&!/*RmmK15]/iq"p!0=(&Pfd:+cMH!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -0 0 m 29,0,-1 - 0 1792 l 25,1,-1 - 1280 1792 l 25,2,-1 - 1280 1536 l 25,3,-1 - 256 1536 l 25,4,-1 - 256 1024 l 25,5,-1 - 1024 1024 l 25,6,-1 - 1024 768 l 25,7,-1 - 256 768 l 25,8,-1 - 256 256 l 25,9,-1 - 1280 256 l 25,10,-1 - 1280 0 l 25,11,-1 - 0 0 l 29,0,-1 +64 0 m 29,0,-1 + 64 1792 l 25,1,-1 + 1344 1792 l 25,2,-1 + 1344 1536 l 25,3,-1 + 320 1536 l 25,4,-1 + 320 1024 l 25,5,-1 + 1088 1024 l 25,6,-1 + 1088 768 l 25,7,-1 + 320 768 l 25,8,-1 + 320 256 l 25,9,-1 + 1344 256 l 25,10,-1 + 1344 0 l 25,11,-1 + 64 0 l 29,0,-1 EndSplineSet Validated: 1 EndChar StartChar: F Encoding: 70 70 68 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 100 0 2048 256 256 +Image2: image/png 100 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8sb%RU9&*YsiL A-$eiR*Z#`q&!/*Rmsq'"Pj%XQV%kjh$9`\z8OZBBY!QNJ EndImage2 Fore SplineSet -0 0 m 29,0,-1 - 0 1792 l 25,1,-1 - 1280 1792 l 25,2,-1 - 1280 1536 l 25,3,-1 - 256 1536 l 25,4,-1 - 256 1024 l 25,5,-1 - 1024 1024 l 25,6,-1 - 1024 768 l 25,7,-1 - 256 768 l 25,8,-1 - 256 0 l 25,9,-1 - 0 0 l 29,0,-1 +64 0 m 29,0,-1 + 64 1792 l 25,1,-1 + 1344 1792 l 25,2,-1 + 1344 1536 l 25,3,-1 + 320 1536 l 25,4,-1 + 320 1024 l 25,5,-1 + 1088 1024 l 25,6,-1 + 1088 768 l 25,7,-1 + 320 768 l 25,8,-1 + 320 0 l 25,9,-1 + 64 0 l 29,0,-1 EndSplineSet Validated: 1 EndChar StartChar: G Encoding: 71 71 69 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 113 0 2048 256 256 +Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8+BNffG971$7@ O:5G_Qr(/!iK0o:j;)k3TU:8r31+P6+@1*T0M)fb!/ZRF%f-o69)nql!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 1465 m 1,0,1 - 0 1792 0 1792 313 1792 c 1,2,3 - 313 1792 313 1792 1280 1792 c 25,4,-1 - 1280 1536 l 1,5,-1 - 313 1536 l 1,6,7 - 256 1536 256 1536 256 1465 c 1,8,9 - 256 1465 256 1465 256 313 c 1,10,11 - 256 256 256 256 313 256 c 1,12,13 - 313 256 313 256 1024 256 c 1,14,-1 - 1024 512 l 1,15,-1 - 824 512 l 0,16,17 - 768 569 768 569 768 667 c 0,18,19 - 768 711 768 711 824 768 c 0,20,21 - 824 768 824 768 1280 768 c 1,22,23 - 1280 768 1280 768 1280 0 c 25,24,-1 - 313 0 l 0,25,26 - 0 0 0 0 0 313 c 1,27,28 - 0 610 0 610 0 1465 c 1,0,1 +64 1465 m 1,0,1 + 64 1792 64 1792 377 1792 c 1,2,3 + 377 1792 377 1792 1344 1792 c 25,4,-1 + 1344 1536 l 1,5,-1 + 377 1536 l 1,6,7 + 320 1536 320 1536 320 1465 c 1,8,9 + 320 1465 320 1465 320 313 c 1,10,11 + 320 256 320 256 377 256 c 1,12,13 + 377 256 377 256 1088 256 c 1,14,-1 + 1088 512 l 1,15,-1 + 888 512 l 0,16,17 + 832 569 832 569 832 667 c 0,18,19 + 832 711 832 711 888 768 c 0,20,21 + 888 768 888 768 1344 768 c 1,22,23 + 1344 768 1344 768 1344 0 c 25,24,-1 + 377 0 l 0,25,26 + 64 0 64 0 64 313 c 1,27,28 + 64 610 64 610 64 1465 c 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: H Encoding: 72 72 70 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 105 0 2048 256 256 +Image2: image/png 105 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8C%,9r(&3hH^I ((5nj!Z$kEFCUFB!\6NZ-b!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 0 m 29,0,-1 - 0 1792 l 25,1,-1 - 256 1792 l 25,2,-1 - 256 1024 l 25,3,-1 - 1024 1024 l 25,4,-1 - 1024 1792 l 25,5,-1 - 1280 1792 l 25,6,-1 - 1280 0 l 25,7,-1 - 1024 0 l 25,8,-1 - 1024 768 l 25,9,-1 - 256 768 l 25,10,-1 - 256 0 l 25,11,-1 - 0 0 l 29,0,-1 +64 0 m 29,0,-1 + 64 1792 l 25,1,-1 + 320 1792 l 25,2,-1 + 320 1024 l 25,3,-1 + 1088 1024 l 25,4,-1 + 1088 1792 l 25,5,-1 + 1344 1792 l 25,6,-1 + 1344 0 l 25,7,-1 + 1088 0 l 25,8,-1 + 1088 768 l 25,9,-1 + 320 768 l 25,10,-1 + 320 0 l 25,11,-1 + 64 0 l 29,0,-1 EndSplineSet Validated: 1 EndChar StartChar: I Encoding: 73 73 71 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 106 -256 2048 256 256 +Image2: image/png 106 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8+BNffG9Xor#n '1`([DE!FS&-nOG\/TB9!W_>;(CfiO*cD#Y!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -565 896 m 1,0,1 - 565 896 565 896 1280 182 c 0,2,3 - 1280 182 1280 182 1280 0 c 25,4,5 - 1280 0 1280 0 1099 0 c 24,6,-1 - 331 768 l 24,7,8 - 331 768 331 768 256 768 c 24,9,-1 - 256 0 l 25,10,-1 - 0 0 l 25,11,-1 - 0 1792 l 25,12,-1 - 256 1792 l 25,13,-1 - 256 1024 l 25,14,15 - 256 1024 256 1024 331 1024 c 24,16,-1 - 1099 1792 l 24,17,18 - 1099 1792 1099 1792 1280 1792 c 25,19,-1 - 1280 1611 l 1,20,-1 - 565 896 l 1,0,1 +629 896 m 1,0,1 + 629 896 629 896 1344 182 c 0,2,3 + 1344 182 1344 182 1344 0 c 25,4,5 + 1344 0 1344 0 1163 0 c 24,6,-1 + 395 768 l 24,7,8 + 395 768 395 768 320 768 c 24,9,-1 + 320 0 l 25,10,-1 + 64 0 l 25,11,-1 + 64 1792 l 25,12,-1 + 320 1792 l 25,13,-1 + 320 1024 l 25,14,15 + 320 1024 320 1024 395 1024 c 24,16,-1 + 1163 1792 l 24,17,18 + 1163 1792 1163 1792 1344 1792 c 25,19,-1 + 1344 1611 l 1,20,-1 + 629 896 l 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: L Encoding: 76 76 74 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 94 0 2048 256 256 +Image2: image/png 94 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8C%,9n7D"pQEe Z9ZOJTE+$V$u[?e)us3W#R[5_a@?41!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -0 0 m 29,0,-1 - 0 1792 l 25,1,-1 - 256 1792 l 25,2,-1 - 256 256 l 25,3,-1 - 1280 256 l 25,4,-1 - 1280 0 l 25,5,-1 - 0 0 l 29,0,-1 +64 0 m 29,0,-1 + 64 1792 l 25,1,-1 + 320 1792 l 25,2,-1 + 320 256 l 25,3,-1 + 1344 256 l 25,4,-1 + 1344 0 l 25,5,-1 + 64 0 l 29,0,-1 EndSplineSet Validated: 1 EndChar StartChar: M Encoding: 77 77 75 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 116 0 2048 256 256 +Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8C%,9r(&3hH^( $PS3@a?%*D5dl1gZ.T=^J?/jD%9J'S2b5Z.!P2#CT:c5ccX[ItTT5+(z8OZBBY!QNJ EndImage2 Fore SplineSet -640 1333 m 1,0,1 - 640 1333 640 1333 1099 1792 c 0,2,3 - 1099 1792 1099 1792 1280 1792 c 25,4,-1 - 1280 0 l 25,5,-1 - 1024 0 l 25,6,-1 - 1024 1280 l 24,7,8 - 1024 1280 1024 1280 949 1280 c 24,9,10 - 949 1280 949 1280 768 1099 c 1,11,-1 - 768 825 l 0,12,13 - 704 768 704 768 640 768 c 128,-1,14 - 576 768 576 768 512 825 c 0,15,-1 - 512 1099 l 1,16,17 - 512 1099 512 1099 331 1280 c 24,18,19 - 331 1280 331 1280 256 1280 c 25,20,-1 - 256 0 l 25,21,-1 - 0 0 l 25,22,-1 - 0 1792 l 25,23,24 - 0 1792 0 1792 181 1792 c 0,25,-1 - 640 1333 l 1,0,1 +704 1333 m 1,0,1 + 704 1333 704 1333 1163 1792 c 0,2,3 + 1163 1792 1163 1792 1344 1792 c 25,4,-1 + 1344 0 l 25,5,-1 + 1088 0 l 25,6,-1 + 1088 1280 l 24,7,8 + 1088 1280 1088 1280 1013 1280 c 24,9,10 + 1013 1280 1013 1280 832 1099 c 1,11,-1 + 832 825 l 0,12,13 + 832 768 832 768 704 768 c 128,-1,14 + 576 768 576 768 576 825 c 0,15,-1 + 576 1099 l 1,16,17 + 576 1099 576 1099 395 1280 c 24,18,19 + 395 1280 395 1280 320 1280 c 25,20,-1 + 320 0 l 25,21,-1 + 64 0 l 25,22,-1 + 64 1792 l 25,23,24 + 64 1792 64 1792 245 1792 c 0,25,-1 + 704 1333 l 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: N Encoding: 78 78 76 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 114 0 2048 256 256 +Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8C%,9r(&3hH^I ((1AK!*pDH3j8[I1N4dp>CfEZ>QMoJC`Yo?J8@0'%0/`c%2/03a,U-"!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -256 1461 m 1,0,-1 - 1024 693 l 1,1,2 - 1024 693 1024 693 1024 1749 c 0,3,4 - 1088 1792 1088 1792 1152 1792 c 0,5,6 - 1152 1792 1152 1792 1280 1749 c 8,7,-1 - 1280 0 l 1,8,-1 - 1024 0 l 1,9,10 - 1024 304 1024 304 1024 331 c 1,11,-1 - 256 1099 l 1,12,13 - 256 1043 256 1043 256 0 c 25,14,-1 - 0 0 l 1,15,-1 - 0 1749 l 0,16,17 - 64 1792 64 1792 128 1792 c 0,18,19 - 128 1792 128 1792 256 1749 c 8,20,21 - 256 1749 256 1749 256 1461 c 1,0,-1 +320 1461 m 1,0,-1 + 1088 693 l 1,1,2 + 1088 693 1088 693 1088 1735 c 0,3,4 + 1088 1792 1088 1792 1216 1792 c 129,-1,5 + 1344 1792 1344 1792 1344 1735 c 1,6,7 + 1344 1735 1344 1735 1344 0 c 1,8,-1 + 1088 0 l 1,9,10 + 1088 304 1088 304 1088 331 c 1,11,-1 + 320 1099 l 1,12,13 + 320 1099 320 1099 320 0 c 1,14,-1 + 64 0 l 1,15,-1 + 64 1735 l 0,16,17 + 64 1792 64 1792 192 1792 c 129,-1,18 + 320 1792 320 1792 320 1735 c 1,19,20 + 320 1598 320 1598 320 1461 c 1,0,-1 EndSplineSet Validated: 1 EndChar StartChar: O Encoding: 79 79 77 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 103 0 2048 256 256 +Image2: image/png 103 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8+BNffG9Xor#n 8-[$EOCD`h9Q7*n(j&Ti!cei9?N:'`,npVAI9l+BF EndImage2 Fore SplineSet -949 1536 m 0,0,1 - 949 1536 949 1536 331 1536 c 1,2,3 - 256 1536 256 1536 256 1461 c 1,4,5 - 256 1461 256 1461 256 331 c 1,6,7 - 256 256 256 256 331 256 c 0,8,9 - 331 256 331 256 949 256 c 0,10,11 - 1024 256 1024 256 1024 331 c 1,12,13 - 1024 331 1024 331 1024 1280 c 1,14,15 - 1024 1536 1024 1536 949 1536 c 0,0,1 -1280 512 m 2,16,-1 - 1280 331 l 1,17,18 - 1280 0 1280 0 949 0 c 0,19,20 - 331 0 331 0 331 0 c 0,21,22 - 0 0 0 0 0 331 c 1,23,24 - 0 331 0 331 0 512 c 1,25,26 - 0 512 0 512 0 1280 c 1,27,-1 - 0 1461 l 1,28,29 - 0 1790 0 1790 331 1792 c 0,30,31 - 331 1792 331 1792 949 1792 c 0,32,33 - 1280 1792 1280 1792 1280 1461 c 1,34,35 - 1280 657 1280 657 1280 512 c 2,16,-1 +1013 1536 m 0,0,1 + 1013 1536 1013 1536 395 1536 c 1,2,3 + 320 1536 320 1536 320 1461 c 1,4,5 + 320 1461 320 1461 320 331 c 1,6,7 + 320 256 320 256 395 256 c 0,8,9 + 395 256 395 256 1013 256 c 0,10,11 + 1088 256 1088 256 1088 331 c 1,12,13 + 1088 331 1088 331 1088 1280 c 1,14,15 + 1088 1536 1088 1536 1013 1536 c 0,0,1 +1344 512 m 2,16,-1 + 1344 331 l 1,17,18 + 1344 0 1344 0 1013 0 c 0,19,20 + 395 0 395 0 395 0 c 0,21,22 + 64 0 64 0 64 331 c 1,23,24 + 64 331 64 331 64 512 c 1,25,26 + 64 512 64 512 64 1280 c 1,27,-1 + 64 1461 l 1,28,29 + 64 1790 64 1790 395 1792 c 0,30,31 + 395 1792 395 1792 1013 1792 c 0,32,33 + 1344 1792 1344 1792 1344 1461 c 1,34,35 + 1344 657 1344 657 1344 512 c 2,16,-1 EndSplineSet Validated: 1 EndChar StartChar: P Encoding: 80 80 78 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 103 0 2048 256 256 +Image2: image/png 103 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8sb%RgE0H5;TS A3i[S7MJ$"*n.r'Ug&Cf,!d^b.KBITBGCO-o@;t'!!!!j78?7R6=>BF EndImage2 Fore SplineSet -949 1792 m 0,0,1 - 1280 1792 1280 1792 1280 1461 c 1,2,3 - 1280 1188 1280 1188 1280 1099 c 1,4,5 - 1280 768 1280 768 949 768 c 0,6,7 - 949 768 949 768 256 768 c 1,8,-1 - 256 0 l 25,9,-1 - 0 0 l 25,10,-1 - 0 1792 l 1,11,12 - 23 1792 23 1792 949 1792 c 0,0,1 -949 1024 m 0,13,14 - 1024 1024 1024 1024 1024 1099 c 1,15,16 - 1024 1408 1024 1408 1024 1461 c 0,17,18 - 1024 1536 1024 1536 949 1536 c 1,19,20 - 949 1536 949 1536 256 1536 c 1,21,-1 - 256 1024 l 1,22,23 - 256 1024 256 1024 949 1024 c 0,13,14 +1013 1792 m 0,0,1 + 1344 1792 1344 1792 1344 1461 c 1,2,3 + 1344 1188 1344 1188 1344 1099 c 1,4,5 + 1344 768 1344 768 1013 768 c 0,6,7 + 1013 768 1013 768 320 768 c 1,8,-1 + 320 0 l 25,9,-1 + 64 0 l 25,10,-1 + 64 1792 l 1,11,12 + 87 1792 87 1792 1013 1792 c 0,0,1 +1013 1024 m 0,13,14 + 1088 1024 1088 1024 1088 1099 c 1,15,16 + 1088 1408 1088 1408 1088 1461 c 0,17,18 + 1088 1536 1088 1536 1013 1536 c 1,19,20 + 1013 1536 1013 1536 320 1536 c 1,21,-1 + 320 1024 l 1,22,23 + 320 1024 320 1024 1013 1024 c 0,13,14 EndSplineSet Validated: 1 EndChar StartChar: Q Encoding: 81 81 79 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 117 0 2048 256 256 +Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n 8-[$EOCD`h9Q7*n(rRpiFpG<]E"bM1U>$2Va97]W8YV[W!-uU'$t5_L%KHJ/!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -512 587 m 25,0,-1 - 512 768 l 24,1,-1 - 693 768 l 25,2,-1 - 1280 181 l 24,3,-1 - 1280 0 l 25,4,-1 - 1099 0 l 24,5,6 - 1099 0 1099 0 512 587 c 25,0,-1 -331 0 m 1,7,8 - 0 0 0 0 0 331 c 1,9,10 - 0 1062 0 1062 0 1461 c 0,11,12 - 0 1792 0 1792 331 1792 c 1,13,-1 - 949 1792 l 2,14,15 - 1280 1792 1280 1792 1280 1461 c 1,16,-1 - 1280 569 l 0,17,18 - 1216 512 1216 512 1152 512 c 0,19,20 - 1152 512 1152 512 1024 569 c 8,21,-1 - 1024 1461 l 2,22,23 - 1024 1536 1024 1536 949 1536 c 1,24,25 - 949 1536 949 1536 331 1536 c 5,26,27 - 256 1536 256 1536 256 1461 c 2,28,29 - 256 1461 256 1461 256 331 c 2,30,31 - 256 256 256 256 331 256 c 1,32,33 - 331 256 331 256 730 256 c 0,34,35 - 768 199 768 199 768 137 c 0,36,37 - 767 73 767 73 730 0 c 0,38,39 - 730 0 730 0 331 0 c 1,7,8 +576 587 m 1,0,-1 + 576 768 l 0,1,-1 + 757 768 l 1,2,-1 + 1344 181 l 0,3,-1 + 1344 0 l 1,4,-1 + 1163 0 l 0,5,6 + 1163 0 1163 0 576 587 c 1,0,-1 +395 0 m 1,7,8 + 64 0 64 0 64 331 c 1,9,10 + 64 331 64 331 64 1461 c 0,11,12 + 64 1792 64 1792 395 1792 c 1,13,-1 + 1013 1792 l 2,14,15 + 1344 1792 1344 1792 1344 1461 c 1,16,-1 + 1344 569 l 1,17,18 + 1344 512 1344 512 1216 512 c 129,-1,19 + 1088 512 1088 512 1088 569 c 1,20,-1 + 1088 1461 l 2,21,22 + 1088 1536 1088 1536 1013 1536 c 1,23,24 + 1013 1536 1013 1536 395 1536 c 1,25,26 + 320 1536 320 1536 320 1461 c 2,27,28 + 320 1461 320 1461 320 331 c 2,29,30 + 320 256 320 256 395 256 c 1,31,32 + 395 256 395 256 794 256 c 0,33,34 + 832 256 832 256 832 128 c 128,-1,35 + 832 0 832 0 794 0 c 0,36,37 + 794 0 794 0 395 0 c 1,7,8 EndSplineSet Validated: 1 EndChar StartChar: R Encoding: 82 82 80 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 118 0 2048 256 256 +Image2: image/png 118 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%RgE0H5;TS A3i[S7MJ$"*n.r'"K_Zn!4)_r,F]%L![J)X+!&-3J0_?J!W\@^*W&Fp/p[Kt!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -1024 1461 m 0,0,1 - 1024 1536 1024 1536 949 1536 c 24,2,-1 - 256 1536 l 24,3,-1 - 256 1024 l 25,4,-1 - 949 1024 l 0,5,6 - 1024 1024 1024 1024 1024 1099 c 24,7,8 - 1024 1099 1024 1099 1024 1461 c 0,0,1 -693 768 m 25,9,10 - 693 768 693 768 1280 181 c 24,11,12 - 1280 181 1280 181 1280 0 c 25,13,14 - 1280 0 1280 0 1099 0 c 0,15,-1 - 331 768 l 24,16,17 - 331 768 331 768 256 768 c 0,18,-1 - 256 0 l 25,19,-1 - 0 0 l 25,20,-1 - 0 1792 l 1,21,-1 - 949 1792 l 1,22,23 - 1280 1792 1280 1792 1280 1461 c 8,24,25 - 1280 1461 1280 1461 1280 1099 c 2,26,27 - 1280 768 1280 768 949 768 c 8,28,29 - 821 768 821 768 693 768 c 25,9,10 +1088 1461 m 0,0,1 + 1088 1536 1088 1536 1013 1536 c 24,2,-1 + 320 1536 l 24,3,-1 + 320 1024 l 25,4,-1 + 1013 1024 l 0,5,6 + 1088 1024 1088 1024 1088 1099 c 24,7,8 + 1088 1099 1088 1099 1088 1461 c 0,0,1 +757 768 m 25,9,10 + 757 768 757 768 1344 181 c 24,11,12 + 1344 181 1344 181 1344 0 c 25,13,14 + 1344 0 1344 0 1163 0 c 0,15,-1 + 395 768 l 24,16,17 + 395 768 395 768 320 768 c 0,18,-1 + 320 0 l 25,19,-1 + 64 0 l 25,20,-1 + 64 1792 l 1,21,-1 + 1013 1792 l 1,22,23 + 1344 1792 1344 1792 1344 1461 c 8,24,25 + 1344 1461 1344 1461 1344 1099 c 2,26,27 + 1344 768 1344 768 1013 768 c 8,28,29 + 885 768 885 768 757 768 c 25,9,10 EndSplineSet Validated: 1 EndChar StartChar: S Encoding: 83 83 81 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 117 0 2048 256 256 +Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n 8-[$EOCD`h9Q7+1#-oLFL]o&ScO-lqOEFu6JZKgH3hi\U!641H#5#FNLB%;S!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -949 1792 m 0,0,1 - 1280 1792 1280 1792 1280 1461 c 0,2,3 - 1280 1337 1280 1337 1280 1337 c 0,4,5 - 1223 1280 1223 1280 1152 1280 c 129,-1,6 - 1081 1280 1081 1280 1024 1337 c 1,7,-1 - 1024 1461 l 0,8,9 - 1024 1536 1024 1536 949 1536 c 24,10,-1 - 331 1536 l 0,11,12 - 256 1536 256 1536 256 1461 c 24,13,14 - 256 1218 256 1218 256 1099 c 0,15,16 - 256 1024 256 1024 331 1024 c 24,17,-1 - 949 1024 l 0,18,19 - 1280 1024 1280 1024 1280 693 c 24,20,21 - 1280 346 1280 346 1280 331 c 0,22,23 - 1280 0 1280 0 949 0 c 24,24,-1 - 331 0 l 0,25,26 - 0 0 0 0 0 331 c 0,27,28 - 0 455 0 455 0 455 c 0,29,30 - 65 512 65 512 129 512 c 128,-1,31 - 193 512 193 512 256 455 c 8,32,-1 - 256 331 l 0,33,34 - 256 256 256 256 331 256 c 24,35,-1 - 949 256 l 0,36,37 - 1024 256 1024 256 1024 331 c 24,38,39 - 1024 550 1024 550 1024 693 c 0,40,41 - 1024 768 1024 768 949 768 c 24,42,-1 - 331 768 l 0,43,44 - 0 768 0 768 0 1099 c 24,45,46 - 0 1446 0 1446 0 1461 c 0,47,48 - 0 1792 0 1792 331 1792 c 24,49,50 - 640 1792 640 1792 949 1792 c 0,0,1 +1013 1792 m 0,0,1 + 1344 1792 1344 1792 1344 1461 c 0,2,3 + 1344 1337 1344 1337 1344 1337 c 0,4,5 + 1287 1280 1287 1280 1216 1280 c 129,-1,6 + 1145 1280 1145 1280 1088 1337 c 1,7,-1 + 1088 1461 l 0,8,9 + 1088 1536 1088 1536 1013 1536 c 24,10,-1 + 395 1536 l 0,11,12 + 320 1536 320 1536 320 1461 c 24,13,14 + 320 1218 320 1218 320 1099 c 0,15,16 + 320 1024 320 1024 395 1024 c 24,17,-1 + 1013 1024 l 0,18,19 + 1344 1024 1344 1024 1344 693 c 24,20,21 + 1344 346 1344 346 1344 331 c 0,22,23 + 1344 0 1344 0 1013 0 c 24,24,-1 + 395 0 l 0,25,26 + 64 0 64 0 64 331 c 0,27,28 + 64 455 64 455 64 455 c 0,29,30 + 129 512 129 512 193 512 c 128,-1,31 + 257 512 257 512 320 455 c 8,32,-1 + 320 331 l 0,33,34 + 320 256 320 256 395 256 c 24,35,-1 + 1013 256 l 0,36,37 + 1088 256 1088 256 1088 331 c 24,38,39 + 1088 550 1088 550 1088 693 c 0,40,41 + 1088 768 1088 768 1013 768 c 24,42,-1 + 395 768 l 0,43,44 + 64 768 64 768 64 1099 c 24,45,46 + 64 1446 64 1446 64 1461 c 0,47,48 + 64 1792 64 1792 395 1792 c 24,49,50 + 704 1792 704 1792 1013 1792 c 0,0,1 EndSplineSet Validated: 1 EndChar StartChar: T Encoding: 84 84 82 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 97 0 2048 256 256 +Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8sb%RU9&*YoTJ Ocbb,`^VkJ$(6F*4W"k5!8uuL"pBF EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 256 331 l 0,1,2 - 256 256 256 256 331 256 c 24,3,-1 - 949 256 l 0,4,5 - 1024 256 1024 256 1024 331 c 24,6,-1 - 1024 1792 l 24,7,-1 - 1280 1792 l 25,8,9 - 1280 1792 1280 1792 1280 331 c 0,10,11 - 1280 0 1280 0 949 0 c 24,12,-1 - 331 0 l 0,13,14 - 0 0 0 0 0 331 c 24,15,16 - 0 331 0 331 0 1792 c 25,17,-1 - 256 1792 l 25,0,-1 +320 1792 m 25,0,-1 + 320 331 l 0,1,2 + 320 256 320 256 395 256 c 24,3,-1 + 1013 256 l 0,4,5 + 1088 256 1088 256 1088 331 c 24,6,-1 + 1088 1792 l 24,7,-1 + 1344 1792 l 25,8,9 + 1344 1792 1344 1792 1344 331 c 0,10,11 + 1344 0 1344 0 1013 0 c 24,12,-1 + 395 0 l 0,13,14 + 64 0 64 0 64 331 c 24,15,16 + 64 331 64 331 64 1792 c 25,17,-1 + 320 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: V Encoding: 86 86 84 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 103 0 2048 256 256 +Image2: image/png 103 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8C%,9r(&3hH^I ((5m=$:(253=JBF EndImage2 Fore SplineSet -640 309 m 1,0,1 - 640 309 640 309 1024 693 c 0,2,-1 - 1024 1792 l 24,3,4 - 1024 1792 1024 1792 1280 1792 c 25,5,-1 - 1280 587 l 25,6,-1 - 693 0 l 25,7,8 - 693 0 693 0 587 0 c 24,9,10 - 587 0 587 0 0 587 c 25,11,-1 - 0 1792 l 25,12,-1 - 256 1792 l 25,13,-1 - 256 693 l 0,14,-1 - 640 309 l 1,0,1 +704 309 m 1,0,1 + 704 309 704 309 1088 693 c 0,2,-1 + 1088 1792 l 24,3,4 + 1088 1792 1088 1792 1344 1792 c 25,5,-1 + 1344 587 l 25,6,-1 + 757 0 l 25,7,8 + 757 0 757 0 651 0 c 24,9,10 + 651 0 651 0 64 587 c 25,11,-1 + 64 1792 l 25,12,-1 + 320 1792 l 25,13,-1 + 320 693 l 0,14,-1 + 704 309 l 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: W Encoding: 87 87 85 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 110 0 2048 256 256 +Image2: image/png 110 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8C%,9r(&3hH^I ((5nB"mAFn$mX%#OD^.mYaGPN!Tm;t%5T%n!ru:Z%2(b=8,WDf!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -640 459 m 1,0,1 - 181 0 181 0 181 0 c 0,2,3 - 0 0 0 0 0 0 c 153,-1,4 - 0 0 0 0 0 1792 c 25,5,-1 - 256 1792 l 25,6,-1 - 256 437 l 24,7,-1 - 512 693 l 0,8,-1 - 512 967 l 16,9,10 - 575 1024 575 1024 639 1024 c 128,-1,11 - 703 1024 703 1024 768 967 c 0,12,13 - 768 967 768 967 768 693 c 0,14,-1 - 1024 437 l 24,15,-1 - 1024 1792 l 25,16,-1 - 1280 1792 l 25,17,-1 - 1280 0 l 25,18,19 - 1099 0 1099 0 1099 0 c 0,20,21 - 640 459 640 459 640 459 c 1,0,1 +704 459 m 1,0,1 + 245 0 245 0 245 0 c 0,2,3 + 64 0 64 0 64 0 c 153,-1,4 + 64 0 64 0 64 1792 c 25,5,-1 + 320 1792 l 25,6,-1 + 320 437 l 24,7,-1 + 576 693 l 0,8,-1 + 576 967 l 16,9,10 + 639 1024 639 1024 703 1024 c 128,-1,11 + 767 1024 767 1024 832 967 c 0,12,13 + 832 967 832 967 832 693 c 0,14,-1 + 1088 437 l 24,15,-1 + 1088 1792 l 25,16,-1 + 1344 1792 l 25,17,-1 + 1344 0 l 25,18,19 + 1163 0 1163 0 1163 0 c 0,20,21 + 704 459 704 459 704 459 c 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: X Encoding: 88 88 86 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L,:Kn/++:)bps..=>UQd0V 7.q0\H1/*:bFuki:0SK<8P>1n>>TT7N% 2,#,3n0nECJPQm5%Cd+g'n@9U9bE6aQm-'B!ruA_\La!3?7A:)L&ch"J&dT5?Ho:s)!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -640 971 m 1,0,1 - 640 971 640 971 181 512 c 0,2,3 - 181 512 181 512 0 512 c 25,4,5 - 0 512 0 512 0 693 c 24,6,7 - 0 693 0 693 587 1280 c 24,8,9 - 587 1280 587 1280 693 1280 c 25,10,11 - 693 1280 693 1280 1280 693 c 24,12,13 - 1280 693 1280 693 1280 512 c 25,14,15 - 1280 512 1280 512 1099 512 c 0,16,-1 - 640 971 l 1,0,1 +704 971 m 1,0,1 + 704 971 704 971 245 512 c 0,2,3 + 245 512 245 512 64 512 c 25,4,5 + 64 512 64 512 64 693 c 24,6,7 + 64 693 64 693 651 1280 c 24,8,9 + 651 1280 651 1280 757 1280 c 25,10,11 + 757 1280 757 1280 1344 693 c 24,12,13 + 1344 693 1344 693 1344 512 c 25,14,15 + 1344 512 1344 512 1163 512 c 0,16,-1 + 704 971 l 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: underscore Encoding: 95 95 93 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 87 0 2048 256 256 +Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y .Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF EndImage2 Fore SplineSet -0 256 m 29,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 29,0,-1 +64 256 m 29,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 29,0,-1 EndSplineSet Validated: 1 EndChar StartChar: grave Encoding: 96 96 94 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 106 -256 2048 256 256 +Image2: image/png 106 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8CJNffG9V\638 OBF EndImage2 Fore SplineSet -512 768 m 1,0,1 - 512 768 512 768 313 768 c 1,2,3 - 256 768 256 768 256 711 c 1,4,5 - 256 711 256 711 256 569 c 1,6,7 - 256 512 256 512 313 512 c 1,8,9 - 313 512 313 512 512 512 c 1,10,11 - 512 512 512 512 512 768 c 1,0,1 -313 256 m 2,12,13 - 0 256 0 256 0 569 c 0,14,15 - 0 640 0 640 0 711 c 0,16,17 - 0 1024 0 1024 313 1024 c 2,18,19 - 313 1024 313 1024 512 1024 c 1,20,21 - 512 1024 512 1024 512 1223 c 1,22,23 - 512 1280 512 1280 455 1280 c 1,24,25 - 455 1280 455 1280 57 1280 c 0,26,27 - 0 1337 0 1337 0 1408 c 0,28,29 - 0 1465 0 1465 57 1536 c 0,30,31 - 57 1536 57 1536 455 1536 c 0,32,33 - 768 1536 768 1536 768 1223 c 0,34,35 - 768 1202 768 1202 768 512 c 1,36,-1 - 967 512 l 0,37,38 - 1024 446 1024 446 1024 382 c 128,-1,39 - 1024 318 1024 318 967 256 c 0,40,-1 - 313 256 l 2,12,13 +704 768 m 1,0,1 + 704 768 704 768 505 768 c 1,2,3 + 448 768 448 768 448 711 c 1,4,5 + 448 711 448 711 448 569 c 1,6,7 + 448 512 448 512 505 512 c 1,8,9 + 505 512 505 512 704 512 c 1,10,11 + 704 512 704 512 704 768 c 1,0,1 +505 256 m 2,12,13 + 192 256 192 256 192 569 c 0,14,15 + 192 640 192 640 192 711 c 0,16,17 + 192 1024 192 1024 505 1024 c 2,18,19 + 505 1024 505 1024 704 1024 c 1,20,21 + 704 1024 704 1024 704 1223 c 1,22,23 + 704 1280 704 1280 647 1280 c 1,24,25 + 647 1280 647 1280 249 1280 c 0,26,27 + 192 1280 192 1280 192 1408 c 0,28,29 + 193 1536 193 1536 249 1536 c 0,30,31 + 448 1536 448 1536 647 1536 c 0,32,33 + 960 1536 960 1536 960 1223 c 0,34,35 + 960 1223 960 1223 960 512 c 1,36,-1 + 1159 512 l 0,37,38 + 1216 512 1216 512 1216 384 c 128,-1,39 + 1216 256 1216 256 1159 256 c 0,40,-1 + 505 256 l 2,12,13 EndSplineSet Validated: 1 EndChar StartChar: b Encoding: 98 98 96 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 116 0 2048 256 256 +Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9V\638 S?bBd\,qa@fM$lI!'(49d1sJ4i3ERJ3YYqoH\qu4!8Sn#)En`A2-]*Pz8OZBBY!QNJ EndImage2 Fore SplineSet -967 1280 m 0,0,1 - 1280 1280 1280 1280 1280 967 c 0,2,3 - 1280 868 1280 868 1280 768 c 1,4,5 - 1280 256 1280 256 967 256 c 0,6,7 - 967 256 967 256 57 256 c 0,8,9 - 0 256 0 256 0 382 c 0,10,11 - 0 455 0 455 57 512 c 0,12,-1 - 256 512 l 1,13,-1 - 256 1734 l 0,14,15 - 322 1791 322 1791 386 1791 c 128,-1,16 - 450 1791 450 1791 512 1734 c 8,17,-1 - 512 1280 l 1,18,-1 - 967 1280 l 0,0,1 -967 512 m 0,19,20 - 1024 512 1024 512 1024 565 c 0,21,22 - 1024 567 1024 567 1024 569 c 1,23,24 - 1024 896 1024 896 1024 967 c 0,25,26 - 1024 1024 1024 1024 967 1024 c 1,27,28 - 967 1024 967 1024 512 1024 c 1,29,-1 - 512 512 l 1,30,31 - 740 512 740 512 967 512 c 0,19,20 +1031 1280 m 0,0,1 + 1344 1280 1344 1280 1344 967 c 0,2,3 + 1344 868 1344 868 1344 768 c 1,4,5 + 1344 256 1344 256 1031 256 c 0,6,7 + 1031 256 1031 256 121 256 c 0,8,9 + 64 256 64 256 64 384 c 128,-1,10 + 64 512 64 512 121 512 c 0,11,-1 + 320 512 l 1,12,-1 + 320 1734 l 0,13,14 + 320 1792 320 1792 448 1792 c 128,-1,15 + 576 1792 576 1792 576 1734 c 0,16,-1 + 576 1280 l 1,17,-1 + 1031 1280 l 0,0,1 +1031 512 m 0,18,19 + 1088 512 1088 512 1088 565 c 0,20,21 + 1088 567 1088 567 1088 569 c 1,22,23 + 1088 896 1088 896 1088 967 c 0,24,25 + 1088 1024 1088 1024 1031 1024 c 1,26,27 + 1031 1024 1031 1024 576 1024 c 1,28,-1 + 576 512 l 1,29,30 + 804 512 804 512 1031 512 c 0,18,19 EndSplineSet Validated: 1 EndChar StartChar: c Encoding: 99 99 97 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 113 -256 2048 256 256 +Image2: image/png 113 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns2*9E?@_ ,E0`pCa`Bd8.o&:XqJeuBE^[*?n4L^j)kIF:0_Z:!.;!a%Z2pI[/^1,!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 1223 m 1,0,1 - 0 1536 0 1536 313 1536 c 1,2,3 - 313 1536 313 1536 967 1536 c 0,4,5 - 1024 1467 1024 1467 1024 1403 c 128,-1,6 - 1024 1339 1024 1339 967 1280 c 0,7,-1 - 313 1280 l 1,8,9 - 256 1280 256 1280 256 1223 c 1,10,11 - 256 1223 256 1223 256 569 c 1,12,13 - 256 512 256 512 313 512 c 1,14,15 - 313 512 313 512 967 512 c 0,16,17 - 1022 446 1022 446 1022 382 c 128,-1,18 - 1022 318 1022 318 967 256 c 0,19,-1 - 313 256 l 0,20,21 - 0 256 0 256 0 569 c 1,22,23 - 0 896 0 896 0 1223 c 1,0,1 +192 1223 m 1,0,1 + 192 1536 192 1536 505 1536 c 1,2,3 + 505 1536 505 1536 1159 1536 c 0,4,5 + 1216 1536 1216 1536 1216 1408 c 128,-1,6 + 1216 1280 1216 1280 1159 1280 c 0,7,-1 + 505 1280 l 1,8,9 + 448 1280 448 1280 448 1223 c 1,10,11 + 448 1223 448 1223 448 569 c 1,12,13 + 448 512 448 512 505 512 c 1,14,15 + 505 512 505 512 1159 512 c 0,16,17 + 1216 512 1216 512 1216 384 c 128,-1,18 + 1216 256 1216 256 1159 256 c 0,19,-1 + 505 256 l 0,20,21 + 192 256 192 256 192 569 c 1,22,23 + 192 569 192 569 192 1223 c 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: d Encoding: 100 100 98 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 120 0 2048 256 256 +Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8D_*$Z[Q1)J/( ;1Ket'OUqJ@abW^bQO(33aJOOEJ1L],)b'o0g"R2KXB25:z8OZBBY!QNJ EndImage2 Fore SplineSet -313 256 m 0,0,1 - 0 256 0 256 0 512 c 0,2,3 - 0 512 0 512 0 967 c 1,4,5 - 0 1280 0 1280 313 1280 c 0,6,7 - 540 1280 540 1280 768 1280 c 1,8,-1 - 768 1734 l 0,9,10 - 824 1792 824 1792 895.5 1792 c 128,-1,11 - 967 1792 967 1792 1024 1734 c 0,12,-1 - 1024 512 l 1,13,-1 - 1223 512 l 0,14,15 - 1280 455 1280 455 1280 387 c 0,16,17 - 1280 313 1280 313 1223 255 c 0,18,19 - 1223 255 1223 255 313 256 c 0,0,1 -313 1024 m 1,20,21 - 255 1024 255 1024 255 967 c 1,22,23 - 256 569 256 569 256 569 c 0,24,25 - 256 512 256 512 313 512 c 24,26,27 - 313 512 313 512 768 512 c 0,28,29 - 768 512 768 512 768 1024 c 1,30,-1 - 313 1024 l 1,20,21 +377 256 m 0,0,1 + 64 256 64 256 64 512 c 0,2,3 + 64 512 64 512 64 967 c 1,4,5 + 64 1280 64 1280 377 1280 c 0,6,7 + 377 1280 377 1280 832 1280 c 1,8,-1 + 832 1735 l 0,9,10 + 832 1792 832 1792 960 1792 c 128,-1,11 + 1088 1792 1088 1792 1088 1735 c 0,12,-1 + 1088 512 l 1,13,-1 + 1287 512 l 0,14,15 + 1344 512 1344 512 1344 384 c 128,-1,16 + 1344 256 1344 256 1287 256 c 0,17,18 + 1287 256 1287 256 377 256 c 0,0,1 +377 1024 m 1,19,20 + 319 1024 319 1024 319 967 c 1,21,22 + 320 569 320 569 320 569 c 0,23,24 + 320 512 320 512 377 512 c 0,25,26 + 377 512 377 512 832 512 c 0,27,28 + 832 512 832 512 832 1024 c 1,29,-1 + 377 1024 l 1,19,20 EndSplineSet Validated: 1 EndChar StartChar: e Encoding: 101 101 99 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 115 -256 2048 256 256 +Image2: image/png 115 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3&!@&g6 !skY(YQBmhaBF EndImage2 Fore SplineSet -693 1024 m 0,0,1 - 768 1024 768 1024 768 1099 c 2,2,3 - 768 1099 768 1099 768 1205 c 1,4,5 - 768 1280 768 1280 693 1280 c 1,6,7 - 512 1280 512 1280 331 1280 c 0,8,9 - 256 1280 256 1280 256 1205 c 1,10,11 - 256 1143 256 1143 256 1081 c 0,12,13 - 256 1024 256 1024 313 1024 c 1,14,15 - 503 1024 503 1024 693 1024 c 0,0,1 -0 1205 m 0,16,17 - 0 1536 0 1536 331 1536 c 1,18,19 - 331 1536 331 1536 693 1536 c 1,20,21 - 1024 1536 1024 1536 1024 1205 c 0,22,23 - 1024 1205 1024 1205 1024 1099 c 0,24,25 - 1024 768 1024 768 693 768 c 0,26,-1 - 256 768 l 1,27,28 - 256 595 256 595 256 587 c 0,29,30 - 256 512 256 512 331 512 c 1,31,32 - 711 512 711 512 711 512 c 0,33,34 - 768 512 768 512 768 384 c 128,-1,35 - 768 256 768 256 711 256 c 0,36,-1 - 331 256 l 0,37,38 - 0 256 0 256 0 587 c 1,39,40 - 0 896 0 896 0 1205 c 0,16,17 +885 1024 m 0,0,1 + 960 1024 960 1024 960 1099 c 2,2,3 + 960 1099 960 1099 960 1205 c 1,4,5 + 960 1280 960 1280 885 1280 c 1,6,7 + 885 1280 885 1280 523 1280 c 0,8,9 + 448 1280 448 1280 448 1205 c 1,10,11 + 448 1205 448 1205 448 1081 c 0,12,13 + 448 1024 448 1024 505 1024 c 1,14,15 + 505 1024 505 1024 885 1024 c 0,0,1 +192 1205 m 0,16,17 + 192 1536 192 1536 523 1536 c 1,18,19 + 523 1536 523 1536 885 1536 c 1,20,21 + 1216 1536 1216 1536 1216 1205 c 0,22,23 + 1216 1205 1216 1205 1216 1099 c 0,24,25 + 1216 768 1216 768 885 768 c 0,26,-1 + 448 768 l 1,27,28 + 448 595 448 595 448 587 c 0,29,30 + 448 512 448 512 523 512 c 1,31,32 + 903 512 903 512 903 512 c 0,33,34 + 960 512 960 512 960 384 c 128,-1,35 + 960 256 960 256 903 256 c 0,36,-1 + 523 256 l 0,37,38 + 192 256 192 256 192 587 c 1,39,40 + 192 587 192 587 192 1205 c 0,16,17 EndSplineSet Validated: 1 EndChar StartChar: f Encoding: 102 102 100 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 122 -256 2048 256 256 +Image2: image/png 122 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8D_*$Z[Q1)J/h .f`.m$q")!&*pF_RK]>[bNg-Et!!nC@e,oG/"i0\g1=!!!!j78?7R 6=>BF EndImage2 Fore SplineSet -768 1223 m 1,0,1 - 768 1280 768 1280 711 1280 c 1,2,3 - 711 1280 711 1280 313 1280 c 0,4,5 - 256 1280 256 1280 256 1223 c 1,6,7 - 256 1223 256 1223 256 825 c 1,8,9 - 256 768 256 768 313 768 c 1,10,11 - 711 768 711 768 711 768 c 0,12,13 - 768 768 768 768 768 825 c 1,14,15 - 768 825 768 825 768 1223 c 1,0,1 -313 512 m 2,16,17 - 0 512 0 512 0 825 c 0,18,19 - 0 825 0 825 0 1223 c 0,20,21 - 0 1536 0 1536 313 1536 c 0,22,23 - 512 1536 512 1536 711 1536 c 1,24,25 - 1024 1536 1024 1536 1024 1223 c 0,26,27 - 1024 612 1024 612 1024 313 c 0,28,29 - 1024 0 1024 0 711 0 c 1,30,31 - 711 0 711 0 256 0 c 1,32,-1 - 256 256 l 1,33,-1 - 711 256 l 1,34,35 - 768 256 768 256 768 313 c 1,36,37 - 768 413 768 413 768 512 c 1,38,-1 - 313 512 l 2,16,17 +960 1223 m 1,0,1 + 960 1280 960 1280 903 1280 c 1,2,3 + 903 1280 903 1280 505 1280 c 0,4,5 + 448 1280 448 1280 448 1223 c 1,6,7 + 448 1223 448 1223 448 825 c 1,8,9 + 448 768 448 768 505 768 c 1,10,11 + 903 768 903 768 903 768 c 0,12,13 + 960 768 960 768 960 825 c 1,14,15 + 960 825 960 825 960 1223 c 1,0,1 +505 512 m 2,16,17 + 192 512 192 512 192 825 c 0,18,19 + 192 825 192 825 192 1223 c 0,20,21 + 192 1536 192 1536 505 1536 c 0,22,23 + 704 1536 704 1536 903 1536 c 1,24,25 + 1216 1536 1216 1536 1216 1223 c 0,26,27 + 1216 612 1216 612 1216 313 c 0,28,29 + 1216 0 1216 0 903 0 c 1,30,31 + 903 0 903 0 448 0 c 1,32,-1 + 448 256 l 1,33,-1 + 903 256 l 1,34,35 + 960 256 960 256 960 313 c 1,36,37 + 960 413 960 413 960 512 c 1,38,-1 + 505 512 l 2,16,17 EndSplineSet Validated: 1 EndChar StartChar: h Encoding: 104 104 102 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 110 -256 2048 256 256 +Image2: image/png 110 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8CJNffG9V\638 S?bBd\,qa@fM$lI!'(49d1sJ4i3J*1!_,N5"9Oqn#t!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -711 1280 m 17,0,1 - 1024 1280 1024 1280 1024 967 c 0,2,3 - 1024 836 1024 836 1024 256 c 25,4,-1 - 768 256 l 1,5,-1 - 768 967 l 1,6,7 - 768 1024 768 1024 711 1024 c 1,8,9 - 711 1024 711 1024 256 1024 c 1,10,-1 - 256 256 l 25,11,-1 - 0 256 l 1,12,-1 - 0 1734 l 0,13,14 - 70 1792 70 1792 134 1792 c 128,-1,15 - 198 1792 198 1792 256 1734 c 8,16,-1 - 256 1280 l 1,17,-1 - 711 1280 l 17,0,1 +903 1280 m 17,0,1 + 1216 1280 1216 1280 1216 967 c 0,2,3 + 1216 836 1216 836 1216 256 c 25,4,-1 + 960 256 l 1,5,-1 + 960 967 l 1,6,7 + 960 1024 960 1024 903 1024 c 1,8,9 + 903 1024 903 1024 448 1024 c 1,10,-1 + 448 256 l 25,11,-1 + 192 256 l 1,12,-1 + 192 1734 l 0,13,14 + 192 1792 192 1792 320 1792 c 128,-1,15 + 448 1792 448 1792 448 1734 c 8,16,-1 + 448 1280 l 1,17,-1 + 903 1280 l 17,0,1 EndSplineSet Validated: 1 EndChar StartChar: i Encoding: 105 105 103 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 114 -256 2048 256 256 +Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HNZ $?-jc=$Y+8'Q]BrE"e>O:mbVo0]QRuZ3h?Y#F>NYEWDm9$5>J927EPc!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -256 1223 m 0,0,1 - 313 1280 313 1280 383 1280 c 1,2,3 - 455 1280 455 1280 512 1223 c 1,4,-1 - 512 569 l 0,5,6 - 512 512 512 512 568 512 c 24,7,-1 - 768 512 l 1,8,-1 - 768 256 l 25,9,-1 - 0 256 l 25,10,-1 - 0 512 l 1,11,-1 - 198 512 l 0,12,13 - 256 512 256 512 256 569 c 16,14,15 - 256 569 256 569 256 1223 c 0,0,1 -256 1792 m 24,16,-1 - 512 1792 l 24,17,-1 - 512 1536 l 25,18,-1 - 256 1536 l 25,19,20 - 256 1536 256 1536 256 1792 c 24,16,-1 +576 1223 m 4,0,1 + 576 1280 576 1280 704 1280 c 129,-1,2 + 832 1280 832 1280 832 1223 c 1,3,-1 + 832 569 l 0,4,5 + 832 512 832 512 888 512 c 0,6,-1 + 1088 512 l 1,7,-1 + 1088 256 l 1,8,-1 + 320 256 l 1,9,-1 + 320 512 l 1,10,-1 + 518 512 l 0,11,12 + 576 512 576 512 576 569 c 4,13,14 + 576 569 576 569 576 1223 c 4,0,1 +576 1792 m 0,15,-1 + 832 1792 l 0,16,-1 + 832 1536 l 1,17,-1 + 576 1536 l 1,18,19 + 576 1536 576 1536 576 1792 c 0,15,-1 EndSplineSet Validated: 1 EndChar StartChar: j Encoding: 106 106 104 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 112 -256 2048 256 256 +Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8D_*$Z[Q1)J/( ;1QnF'EnV6^b?iYJ78RT"k\cg.0c7AEZ@U^2FdfKcm&u1G:MDDz8OZBBY!QNJ EndImage2 Fore SplineSet -512 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 1536 l 25,2,-1 - 512 1536 l 25,3,-1 - 512 1792 l 25,0,-1 -768 313 m 0,4,5 - 768 2 768 2 455 0 c 0,6,7 - 455 0 455 0 313 0 c 0,8,9 - 0 0 0 0 0 313 c 0,10,11 - 0 313 0 313 0 455 c 0,12,13 - 57 512 57 512 122 512 c 0,14,15 - 198 512 198 512 256 455 c 0,16,-1 - 256 302 l 0,17,18 - 256 256 256 256 313 256 c 0,19,20 - 384 256 384 256 455 256 c 0,21,22 - 512 256 512 256 512 302 c 0,23,24 - 512 302 512 302 512 1223 c 0,25,26 - 574 1280 574 1280 637 1280 c 0,27,28 - 702 1280 702 1280 768 1223 c 0,29,30 - 768 1223 768 1223 768 313 c 0,4,5 +832 1792 m 1,0,-1 + 1088 1792 l 1,1,-1 + 1088 1536 l 1,2,-1 + 832 1536 l 1,3,-1 + 832 1792 l 1,0,-1 +1088 331 m 0,4,5 + 1088 0 1088 0 757 0 c 0,6,7 + 757 0 757 0 651 0 c 0,8,9 + 320 0 320 0 320 331 c 0,10,11 + 320 331 320 331 320 455 c 0,12,13 + 320 512 320 512 448 512 c 128,-1,14 + 576 512 576 512 576 455 c 0,15,-1 + 576 331 l 0,16,17 + 576 256 576 256 651 256 c 0,18,19 + 651 256 651 256 757 256 c 0,20,21 + 832 256 832 256 832 331 c 0,22,23 + 832 331 832 331 832 1223 c 0,24,25 + 832 1280 832 1280 957 1280 c 0,26,27 + 1088 1280 1088 1280 1088 1223 c 0,28,29 + 1088 1223 1088 1223 1088 331 c 0,4,5 EndSplineSet Validated: 1 EndChar StartChar: k Encoding: 107 107 105 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 116 -256 2048 256 256 +Image2: image/png 116 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9V\638 A6F#n-ji5&kVg9m@$:_]$s*GWM/GG5!Y>U+,"A4J?>flF>MTu&gl3mSz8OZBBY!QNJ EndImage2 Fore SplineSet -313 1024 m 17,0,1 - 313 1024 313 1024 825 1536 c 1,2,-1 - 1024 1536 l 1,3,-1 - 1024 1337 l 1,4,-1 - 583 896 l 1,5,6 - 583 896 583 896 1024 455 c 1,7,-1 - 1024 256 l 1,8,-1 - 825 256 l 1,9,-1 - 313 768 l 1,10,11 - 313 768 313 768 256 768 c 25,12,-1 - 256 256 l 25,13,-1 - 0 256 l 25,14,-1 - 0 1792 l 25,15,-1 - 256 1792 l 25,16,-1 - 256 1024 l 25,17,-1 - 313 1024 l 17,0,1 +505 1024 m 17,0,1 + 505 1024 505 1024 1017 1536 c 1,2,-1 + 1216 1536 l 1,3,-1 + 1216 1337 l 1,4,-1 + 775 896 l 1,5,6 + 775 896 775 896 1216 455 c 1,7,-1 + 1216 256 l 1,8,-1 + 1017 256 l 1,9,-1 + 505 768 l 1,10,11 + 505 768 505 768 448 768 c 25,12,-1 + 448 256 l 25,13,-1 + 192 256 l 25,14,-1 + 192 1792 l 25,15,-1 + 448 1792 l 25,16,-1 + 448 1024 l 25,17,-1 + 505 1024 l 17,0,1 EndSplineSet Validated: 1 EndChar StartChar: l Encoding: 108 108 106 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 108 -256 2048 256 256 +Image2: image/png 108 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8CJNffG9N3T>a /&5d'=91=N0JP%+!'(Yp?o6)P&Bt8#n2V*]Yf@(bT*B[=z8OZBBY!QNJ EndImage2 Fore SplineSet -0 1792 m 24,0,-1 - 512 1792 l 24,1,-1 - 512 512 l 25,2,-1 - 768 512 l 25,3,-1 - 768 256 l 25,4,-1 - 0 256 l 25,5,-1 - 0 512 l 25,6,-1 - 256 512 l 25,7,-1 - 256 1536 l 25,8,-1 - 0 1536 l 25,9,10 - 0 1536 0 1536 0 1792 c 24,0,-1 +320 1792 m 24,0,-1 + 832 1792 l 24,1,-1 + 832 512 l 25,2,-1 + 1088 512 l 25,3,-1 + 1088 256 l 25,4,-1 + 320 256 l 25,5,-1 + 320 512 l 25,6,-1 + 576 512 l 25,7,-1 + 576 1536 l 25,8,-1 + 320 1536 l 25,9,10 + 320 1536 320 1536 320 1792 c 24,0,-1 EndSplineSet Validated: 1 EndChar StartChar: m Encoding: 109 109 107 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 113 0 2048 256 256 +Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns22,9nE8 #_N,9#'6F?fE@9f+A!E0T`A3qSP@`GkW7)dN.ehM!'R@m&B%c/r;Zft!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -454 1536 m 2,0,1 - 639 1536 639 1536 639 1280 c 1,2,3 - 639 1536 639 1536 824 1536 c 0,4,5 - 824 1536 824 1536 967 1536 c 0,6,7 - 1280 1536 1280 1536 1280 1223 c 1,8,9 - 1280 740 1280 740 1280 256 c 1,10,11 - 1280 256 1280 256 1024 256 c 1,12,-1 - 1024 1223 l 2,13,14 - 1024 1280 1024 1280 967 1280 c 1,15,16 - 967 1280 967 1280 824 1280 c 0,17,18 - 768 1280 768 1280 768 1223 c 0,19,20 - 768 1223 768 1223 768 256 c 1,21,-1 - 512 256 l 1,22,-1 - 512 1223 l 2,23,24 - 512 1280 512 1280 454 1280 c 0,25,26 - 454 1280 454 1280 313 1280 c 0,27,28 - 256 1280 256 1280 256 1223 c 2,29,-1 - 256 256 l 1,30,-1 - 0 256 l 25,31,-1 - 0 1536 l 1,32,-1 - 454 1536 l 2,0,1 +518 1536 m 2,0,1 + 703 1536 703 1536 703 1280 c 1,2,3 + 703 1536 703 1536 888 1536 c 0,4,5 + 888 1536 888 1536 1031 1536 c 0,6,7 + 1344 1536 1344 1536 1344 1223 c 1,8,9 + 1344 740 1344 740 1344 256 c 1,10,11 + 1344 256 1344 256 1088 256 c 1,12,-1 + 1088 1223 l 2,13,14 + 1088 1280 1088 1280 1031 1280 c 1,15,16 + 1031 1280 1031 1280 888 1280 c 0,17,18 + 832 1280 832 1280 832 1223 c 0,19,20 + 832 1223 832 1223 832 256 c 1,21,-1 + 576 256 l 1,22,-1 + 576 1223 l 2,23,24 + 576 1280 576 1280 518 1280 c 0,25,26 + 518 1280 518 1280 377 1280 c 0,27,28 + 320 1280 320 1280 320 1223 c 2,29,-1 + 320 256 l 1,30,-1 + 64 256 l 25,31,-1 + 64 1536 l 1,32,-1 + 518 1536 l 2,0,1 EndSplineSet Validated: 1 EndChar StartChar: n Encoding: 110 110 108 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 110 -256 2048 256 256 +Image2: image/png 110 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns2*Lh(%, KW@I!&8hP?!ec[NK64pE^l:Th:p,<\BJ3\1!WY^j&I&QkSpLG;!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -711 1536 m 17,0,1 - 1024 1536 1024 1536 1024 1223 c 1,2,3 - 1024 683 1024 683 1024 256 c 25,4,-1 - 768 256 l 1,5,-1 - 768 1223 l 1,6,7 - 768 1280 768 1280 711 1280 c 1,8,9 - 711 1280 711 1280 256 1280 c 1,10,-1 - 256 256 l 25,11,-1 - 0 256 l 25,12,-1 - 0 1536 l 1,13,-1 - 711 1536 l 17,0,1 +903 1536 m 17,0,1 + 1216 1536 1216 1536 1216 1223 c 1,2,3 + 1216 683 1216 683 1216 256 c 25,4,-1 + 960 256 l 1,5,-1 + 960 1223 l 1,6,7 + 960 1280 960 1280 903 1280 c 1,8,9 + 903 1280 903 1280 448 1280 c 1,10,-1 + 448 256 l 25,11,-1 + 192 256 l 25,12,-1 + 192 1536 l 1,13,-1 + 903 1536 l 17,0,1 EndSplineSet Validated: 1 EndChar StartChar: o Encoding: 111 111 109 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 119 -256 2048 256 256 +Image2: image/png 119 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8Bu3Ns3&!@&g6 !skY(YQBmhapkS,:]Uqp-*kq^ScUEm.=rFq9EP8Yq@aDRRWI9b!!!!j78?7R6=>BF EndImage2 Fore SplineSet -768 1223 m 1,0,1 - 768 1280 768 1280 711 1280 c 1,2,3 - 697 1280 697 1280 313 1280 c 0,4,5 - 256 1280 256 1280 256 1223 c 1,6,7 - 256 1223 256 1223 256 569 c 1,8,9 - 256 512 256 512 313 512 c 1,10,11 - 313 512 313 512 711 512 c 0,12,13 - 768 512 768 512 768 569 c 1,14,15 - 768 569 768 569 768 1223 c 1,0,1 -0 1223 m 0,16,17 - 0 1536 0 1536 327 1536 c 1,18,19 - 519 1536 519 1536 711 1536 c 1,20,21 - 1024 1536 1024 1536 1024 1223 c 0,22,23 - 1024 691 1024 691 1024 569 c 0,24,25 - 1024 256 1024 256 711 256 c 1,26,27 - 512 256 512 256 313 256 c 1,28,29 - 0 256 0 256 0 569 c 0,30,31 - 0 1056 0 1056 0 1223 c 0,16,17 +960 1205 m 1,0,1 + 960 1280 960 1280 885 1280 c 1,2,3 + 885 1280 885 1280 523 1280 c 0,4,5 + 448 1280 448 1280 448 1205 c 1,6,7 + 448 1205 448 1205 448 587 c 1,8,9 + 448 512 448 512 523 512 c 1,10,11 + 523 512 523 512 885 512 c 0,12,13 + 960 512 960 512 960 587 c 1,14,15 + 960 587 960 587 960 1205 c 1,0,1 +192 1205 m 0,16,17 + 192 1536 192 1536 523 1536 c 1,18,19 + 523 1536 523 1536 885 1536 c 1,20,21 + 1216 1536 1216 1536 1216 1205 c 0,22,23 + 1216 730 1216 730 1216 587 c 0,24,25 + 1216 256 1216 256 885 256 c 1,26,27 + 885 256 885 256 523 256 c 1,28,29 + 192 256 192 256 192 587 c 0,30,31 + 192 659 192 659 192 1205 c 0,16,17 EndSplineSet Validated: 1 EndChar StartChar: p Encoding: 112 112 110 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 118 -256 2048 256 256 +Image2: image/png 118 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns2*Lh(%, KW@I!&8hP?!ec[NK64pE^l:ThJ?8g._/uDU!EXe(!AfP)'`_rY'+E&U*NK/?!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -711 768 m 1,0,1 - 768 768 768 768 768 825 c 1,2,3 - 768 825 768 825 768 1223 c 1,4,5 - 768 1280 768 1280 711 1280 c 1,6,7 - 711 1280 711 1280 256 1280 c 5,8,9 - 256 1280 256 1280 256 768 c 4,10,11 - 256 768 256 768 711 768 c 1,0,1 -711 1536 m 17,12,13 - 1024 1536 1024 1536 1024 1223 c 0,14,15 - 1024 867 1024 867 1024 825 c 0,16,17 - 1024 512 1024 512 711 512 c 9,18,19 - 711 512 711 512 256 512 c 1,20,-1 - 256 0 l 25,21,-1 - 0 0 l 25,22,-1 - 0 1536 l 1,23,-1 - 711 1536 l 17,12,13 +885 768 m 1,0,1 + 960 768 960 768 960 843 c 1,2,3 + 960 843 960 843 960 1205 c 1,4,5 + 960 1280 960 1280 885 1280 c 1,6,7 + 885 1280 885 1280 448 1280 c 1,8,9 + 448 1024 448 1024 448 768 c 0,10,11 + 448 768 448 768 885 768 c 1,0,1 +885 1536 m 1,12,13 + 1216 1536 1216 1536 1216 1205 c 0,14,15 + 1216 858 1216 858 1216 843 c 0,16,17 + 1216 512 1216 512 885 512 c 1,18,19 + 885 512 885 512 448 512 c 1,20,-1 + 448 0 l 1,21,-1 + 192 0 l 1,22,-1 + 192 1536 l 1,23,-1 + 885 1536 l 1,12,13 EndSplineSet Validated: 1 EndChar StartChar: q Encoding: 113 113 111 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 112 0 2048 256 256 +Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns2*Lh(%, KW@I!O9m0=&k&(:koadG811\X0V'm9C][1/TUQ,cA6]lWK/u9:z8OZBBY!QNJ EndImage2 Fore SplineSet -313 1280 m 1,0,1 - 256 1280 256 1280 256 1223 c 1,2,3 - 256 1223 256 1223 256 825 c 1,4,5 - 256 768 256 768 313 768 c 1,6,7 - 313 768 313 768 768 768 c 1,8,-1 - 768 1280 l 1,9,-1 - 313 1280 l 1,0,1 -313 512 m 1,10,11 - 0 512 0 512 0 825 c 0,12,13 - 0 1181 0 1181 0 1223 c 0,14,15 - 0 1536 0 1536 313 1536 c 1,16,17 - 512 1536 512 1536 722 1536 c 0,18,-1 - 1024 1536 l 25,19,-1 - 1024 256 l 1,20,-1 - 1223 256 l 0,21,22 - 1279 190 1279 190 1279 126 c 128,-1,23 - 1279 62 1279 62 1223 0 c 8,24,-1 - 768 0 l 1,25,-1 - 768 512 l 1,26,-1 - 313 512 l 1,10,11 +395 1280 m 1,0,1 + 320 1280 320 1280 320 1205 c 1,2,3 + 320 1205 320 1205 320 843 c 1,4,5 + 320 768 320 768 395 768 c 1,6,7 + 395 768 395 768 832 768 c 1,8,-1 + 832 1280 l 1,9,-1 + 395 1280 l 1,0,1 +395 512 m 1,10,11 + 64 512 64 512 64 843 c 0,12,13 + 64 1023 64 1023 64 1205 c 0,14,15 + 64 1536 64 1536 395 1536 c 1,16,17 + 395 1536 395 1536 786 1536 c 0,18,-1 + 1088 1536 l 1,19,-1 + 1088 256 l 1,20,-1 + 1287 256 l 0,21,22 + 1344 256 1344 256 1344 128 c 128,-1,23 + 1344 0 1344 0 1287 0 c 0,24,-1 + 832 0 l 1,25,-1 + 832 512 l 1,26,-1 + 395 512 l 1,10,11 EndSplineSet Validated: 1 EndChar StartChar: r Encoding: 114 114 112 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 114 -256 2048 256 256 +Image2: image/png 114 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3"!@&g6 Qij'kCm[[-(]u%7br3'HfH`bOiU!pq/^h#XL1]XA\%2#Am_)hVs!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -256 1280 m 1,0,1 - 256 1536 256 1536 568 1536 c 1,2,3 - 568 1536 568 1536 1024 1536 c 1,4,-1 - 1024 1280 l 1,5,-1 - 568 1280 l 1,6,7 - 256 1280 256 1280 256 1024 c 1,8,9 - 256 1024 256 1024 256 256 c 1,10,-1 - 0 256 l 25,11,-1 - 0 1536 l 25,12,-1 - 256 1536 l 25,13,-1 - 256 1280 l 1,0,1 +448 1280 m 1,0,1 + 448 1536 448 1536 760 1536 c 1,2,3 + 760 1536 760 1536 1216 1536 c 1,4,-1 + 1216 1280 l 1,5,-1 + 760 1280 l 1,6,7 + 448 1280 448 1280 448 1024 c 1,8,9 + 448 1024 448 1024 448 256 c 1,10,-1 + 192 256 l 25,11,-1 + 192 1536 l 25,12,-1 + 448 1536 l 25,13,-1 + 448 1280 l 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: s Encoding: 115 115 113 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 122 -256 2048 256 256 +Image2: image/png 122 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8Bu3Ns2*Lh(%, 6rA_U-s-L@(0M2O2:r7t,fg[AP<]K6D?),;.7?&pWuE`,i3FH#&-14%((g]?(5Mqj!!#SZ:.26O @"J@Y EndImage2 Fore SplineSet -1024 711 m 0,0,1 - 1024 710 1024 710 1024 569 c 0,2,3 - 1024 256 1024 256 711 256 c 0,4,-1 - 57 256 l 0,5,6 - 0 321 0 321 0 385 c 128,-1,7 - 0 449 0 449 57 512 c 8,8,-1 - 711 512 l 0,9,10 - 768 512 768 512 768 569 c 16,11,12 - 768 569 768 569 768 711 c 0,13,14 - 768 768 768 768 711 768 c 0,15,-1 - 313 768 l 0,16,17 - 0 768 0 768 0 1081 c 0,18,19 - 0 1081 0 1081 0 1223 c 0,20,21 - 0 1536 0 1536 313 1536 c 1,22,23 - 313 1536 313 1536 967 1536 c 0,24,25 - 1024 1467 1024 1467 1024 1403 c 128,-1,26 - 1024 1339 1024 1339 967 1280 c 1,27,-1 - 313 1280 l 0,28,29 - 256 1280 256 1280 256 1223 c 0,30,31 - 256 1223 256 1223 256 1081 c 0,32,33 - 256 1024 256 1024 313 1024 c 24,34,-1 - 711 1024 l 0,35,36 - 1024 1024 1024 1024 1024 711 c 0,0,1 +1216 693 m 0,0,1 + 1216 640 1216 640 1216 587 c 0,2,3 + 1216 256 1216 256 885 256 c 0,4,-1 + 250 256 l 0,5,6 + 192 256 192 256 192 384 c 128,-1,7 + 192 512 192 512 250 512 c 0,8,-1 + 885 512 l 0,9,10 + 960 512 960 512 960 587 c 0,11,12 + 960 678 960 678 960 693 c 0,13,14 + 960 768 960 768 885 768 c 0,15,-1 + 523 768 l 0,16,17 + 192 768 192 768 192 1099 c 0,18,19 + 192 1099 192 1099 192 1205 c 0,20,21 + 192 1536 192 1536 523 1536 c 1,22,23 + 523 1536 523 1536 1159 1536 c 0,24,25 + 1216 1536 1216 1536 1216 1408 c 128,-1,26 + 1216 1280 1216 1280 1159 1280 c 1,27,-1 + 523 1280 l 0,28,29 + 448 1280 448 1280 448 1205 c 0,30,31 + 448 1114 448 1114 448 1099 c 0,32,33 + 448 1024 448 1024 523 1024 c 0,34,-1 + 885 1024 l 0,35,36 + 1216 1024 1216 1024 1216 693 c 0,0,1 EndSplineSet Validated: 1 EndChar StartChar: t Encoding: 116 116 114 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 117 -256 2048 256 256 +Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CNNffG9`^HN: $=K#N)Hd5G!R);rNM->T!1aRC"1eVo%p&`d*iBrbWj0)8!277@%#@LO^An66!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -512 569 m 1,0,1 - 512 512 512 512 568 512 c 0,2,3 - 568 512 568 512 768 512 c 1,4,5 - 768 512 768 512 768 256 c 1,6,-1 - 568 256 l 17,7,8 - 256 256 256 256 256 569 c 1,9,10 - 256 1232 256 1232 256 1280 c 1,11,-1 - 57 1280 l 0,12,13 - 0 1342 0 1342 0 1406 c 128,-1,14 - 0 1470 0 1470 57 1536 c 0,15,-1 - 256 1536 l 1,16,-1 - 256 1734 l 0,17,18 - 320 1792 320 1792 384 1792 c 128,-1,19 - 448 1792 448 1792 512 1734 c 8,20,-1 - 512 1536 l 1,21,-1 - 711 1536 l 0,22,23 - 768 1478 768 1478 768 1414 c 128,-1,24 - 768 1350 768 1350 711 1280 c 0,25,-1 - 512 1280 l 1,26,-1 - 512 569 l 1,0,1 +832 587 m 1,0,1 + 832 512 832 512 907 512 c 0,2,3 + 907 512 907 512 1088 512 c 1,4,5 + 1088 512 1088 512 1088 256 c 1,6,-1 + 907 256 l 1,7,8 + 576 256 576 256 576 587 c 1,9,10 + 576 934 576 934 576 1280 c 1,11,-1 + 378 1280 l 0,12,13 + 320 1280 320 1280 320 1408 c 128,-1,14 + 320 1536 320 1536 378 1536 c 0,15,-1 + 576 1536 l 1,16,-1 + 576 1735 l 0,17,18 + 576 1792 576 1792 704 1792 c 128,-1,19 + 832 1792 832 1792 832 1735 c 0,20,-1 + 832 1536 l 1,21,-1 + 1031 1536 l 0,22,23 + 1088 1536 1088 1536 1088 1408 c 128,-1,24 + 1088 1280 1088 1280 1031 1280 c 0,25,-1 + 832 1280 l 1,26,-1 + 832 587 l 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: u Encoding: 117 117 115 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 113 -256 2048 256 256 +Image2: image/png 113 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns3"!@&g6 >TGR=,Y4F3E:$aE"AN8)B``P_h/8Tg?j/5Q0L94f!#\N='5qJ>+ohTC!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -256 569 m 1,0,1 - 256 512 256 512 313 512 c 1,2,3 - 313 512 313 512 768 512 c 1,4,-1 - 768 1466 l 0,5,6 - 834 1535 834 1535 898 1535 c 128,-1,7 - 962 1535 962 1535 1023 1465 c 8,8,-1 - 1024 256 l 1,9,-1 - 313 256 l 17,10,11 - 0 256 0 256 0 569 c 1,12,13 - 0 1465 0 1465 0 1465 c 0,14,15 - 57 1536 57 1536 126 1536 c 0,16,17 - 198 1536 198 1536 256 1465 c 0,18,-1 - 256 569 l 1,0,1 +448 587 m 1,0,1 + 448 512 448 512 523 512 c 1,2,3 + 523 512 523 512 960 512 c 1,4,-1 + 960 1479 l 0,5,6 + 960 1536 960 1536 1088 1536 c 128,-1,7 + 1216 1536 1216 1536 1216 1479 c 0,8,-1 + 1216 256 l 1,9,-1 + 523 256 l 1,10,11 + 192 256 192 256 192 587 c 1,12,13 + 192 1403 192 1403 192 1479 c 0,14,15 + 192 1536 192 1536 320 1536 c 128,-1,16 + 448 1536 448 1536 448 1479 c 0,17,-1 + 448 587 l 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: v Encoding: 118 118 116 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 112 0 2048 256 256 +Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns22,9nFj )K\/O'0oSktT]l#NXfm`3:CAe_QB1QT#rk1AhRHz8OZBB Y!QNJ EndImage2 Fore SplineSet -639 714 m 129,-1,1 - 639 714 639 714 181 256 c 1,2,3 - 0 256 0 256 0 437 c 1,4,5 - 457 896 457 896 457 896 c 129,-1,6 - 457 896 457 896 0 1355 c 1,7,8 - 0 1536 0 1536 181 1536 c 1,9,10 - 640 1077 640 1077 640 1077 c 129,-1,11 - 640 1077 640 1077 1099 1536 c 1,12,13 - 1280 1536 1280 1536 1280 1355 c 1,14,15 - 822 897 822 897 822 897 c 129,-1,16 - 822 897 822 897 1280 437 c 1,17,18 - 1280 256 1280 256 1099 256 c 1,19,0 - 639 714 639 714 639 714 c 129,-1,1 +703 714 m 129,-1,1 + 703 714 703 714 245 256 c 1,2,3 + 64 256 64 256 64 437 c 1,4,5 + 521 896 521 896 521 896 c 129,-1,6 + 521 896 521 896 64 1355 c 1,7,8 + 64 1536 64 1536 245 1536 c 1,9,10 + 704 1077 704 1077 704 1077 c 129,-1,11 + 704 1077 704 1077 1163 1536 c 1,12,13 + 1344 1536 1344 1536 1344 1355 c 1,14,15 + 886 897 886 897 886 897 c 129,-1,16 + 886 897 886 897 1344 437 c 1,17,18 + 1344 256 1344 256 1163 256 c 1,19,0 + 703 714 703 714 703 714 c 129,-1,1 EndSplineSet Validated: 1 EndChar StartChar: y Encoding: 121 121 119 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 118 -256 2048 256 256 +Image2: image/png 118 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns3"!@&g6 >TGR=,Y4F3E:$aE/0H[/440%BWJ+OW;M<:^?kYf*@4%Wt!W]..&.jd;TcO16!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -256 825 m 1,0,1 - 256 768 256 768 313 768 c 1,2,3 - 313 768 313 768 768 768 c 1,4,-1 - 768 1465 l 0,5,6 - 768 1536 768 1536 896 1536 c 129,-1,7 - 1024 1536 1024 1536 1024 1465 c 1,8,-1 - 1024 313 l 0,9,10 - 1024 0 1024 0 711 0 c 1,11,-1 - 313 0 l 0,12,13 - 256 63 256 63 256 127 c 128,-1,14 - 256 191 256 191 313 256 c 8,15,-1 - 711 256 l 1,16,17 - 768 256 768 256 768 313 c 1,18,19 - 768 413 768 413 768 512 c 0,20,-1 - 313 512 l 1,21,22 - 0 512 0 512 0 825 c 1,23,24 - 0 1180 0 1180 0 1465 c 0,25,26 - 0 1536 0 1536 131 1536 c 0,27,28 - 256 1536 256 1536 256 1465 c 0,29,-1 - 256 825 l 1,0,1 +448 843 m 1,0,1 + 448 768 448 768 523 768 c 1,2,3 + 523 768 523 768 960 768 c 1,4,-1 + 960 1479 l 0,5,6 + 960 1536 960 1536 1088 1536 c 129,-1,7 + 1216 1536 1216 1536 1216 1479 c 1,8,-1 + 1216 331 l 0,9,10 + 1216 0 1216 0 885 0 c 1,11,-1 + 505 0 l 0,12,13 + 448 0 448 0 448 128 c 128,-1,14 + 448 256 448 256 505 256 c 0,15,-1 + 885 256 l 1,16,17 + 960 256 960 256 960 331 c 1,18,19 + 960 331 960 331 960 512 c 0,20,-1 + 523 512 l 1,21,22 + 192 512 192 512 192 843 c 1,23,24 + 192 843 192 843 192 1479 c 0,25,26 + 192 1536 192 1536 320 1536 c 128,-1,27 + 448 1536 448 1536 448 1479 c 0,28,-1 + 448 843 l 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: z Encoding: 122 122 120 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 111 0 2048 256 256 +Image2: image/png 111 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8Bu3Ns2BOMigR fh`Gp%O32C"#:s/"Pa?#P<7,XDc.Es"r<3WK-qdMi2GrhD[X!!!!j78?7R6=>BF EndImage2 Fore SplineSet -1206 1280 m 0,0,1 - 1206 1280 1206 1280 512 587 c 25,2,3 - 512 586 512 586 512 569 c 0,4,5 - 512 512 512 512 569 512 c 24,6,-1 - 1223 512 l 0,7,8 - 1280 512 1280 512 1280 385 c 0,9,10 - 1280 256 1280 256 1223 256 c 0,11,12 - 640 256 640 256 57 256 c 0,13,14 - 0 256 0 256 0 373 c 0,15,16 - 0 512 0 512 57 512 c 0,17,-1 - 75 512 l 24,18,19 - 75 512 75 512 768 1205 c 8,20,21 - 768 1205 768 1205 768 1223 c 0,22,23 - 768 1280 768 1280 711 1280 c 24,24,-1 - 57 1280 l 0,25,26 - 0 1344 0 1344 0 1408 c 128,-1,27 - 0 1472 0 1472 57 1536 c 0,28,29 - 57 1536 57 1536 1205 1536 c 0,30,31 - 1206 1535 1206 1535 1206 1280 c 0,0,1 +1269 1280 m 0,0,1 + 1269 1280 1269 1280 501 512 c 1,2,3 + 501 512 501 512 1287 512 c 0,4,5 + 1344 512 1344 512 1344 384 c 128,-1,6 + 1344 256 1344 256 1287 256 c 0,7,8 + 1287 256 1287 256 122 256 c 0,9,10 + 64 256 64 256 64 384 c 128,-1,11 + 64 512 64 512 122 512 c 0,12,-1 + 139 512 l 1,13,14 + 139 512 139 512 907 1280 c 1,15,16 + 907 1280 907 1280 122 1280 c 0,17,18 + 64 1280 64 1280 64 1408 c 128,-1,19 + 64 1536 64 1536 122 1536 c 0,20,21 + 122 1536 122 1536 1269 1536 c 0,22,23 + 1344 1536 1344 1536 1344 1408 c 128,-1,24 + 1344 1280 1344 1280 1269 1280 c 0,0,1 EndSplineSet Validated: 1 EndChar StartChar: braceleft Encoding: 123 123 121 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 116 -256 2048 256 256 +Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h .f`.M1CUDd6Ru+9X8nT)O;b>)OO;_ILF[nDL6[A&!LG58&4@'?qd>sHz8OZBBY!QNJ EndImage2 Fore SplineSet -256 1465 m 1,0,1 - 256 1792 256 1792 569 1792 c 1,2,3 - 569 1792 569 1792 768 1792 c 25,4,-1 - 768 1536 l 1,5,-1 - 568 1536 l 1,6,7 - 512 1536 512 1536 512 1465 c 1,8,9 - 512 1454 512 1454 512 1081 c 0,10,11 - 512 896 512 896 410 896 c 1,12,13 - 512 896 512 896 512 711 c 0,14,15 - 512 711 512 711 512 313 c 1,16,17 - 512 256 512 256 568 256 c 1,18,19 - 768 256 768 256 768 256 c 1,20,-1 - 768 0 l 25,21,-1 - 569 0 l 0,22,23 - 256 0 256 0 256 313 c 1,24,25 - 256 313 256 313 256 711 c 1,26,27 - 256 768 256 768 198 768 c 0,28,29 - 198 768 198 768 0 768 c 0,30,31 - 0 768 0 768 0 1024 c 1,32,33 - 198 1024 198 1024 198 1024 c 1,34,35 - 256 1024 256 1024 256 1081 c 1,36,37 - 256 1273 256 1273 256 1465 c 1,0,1 +576 1461 m 1,0,1 + 576 1792 576 1792 907 1792 c 1,2,3 + 907 1792 907 1792 1088 1792 c 1,4,-1 + 1088 1536 l 1,5,-1 + 907 1536 l 1,6,7 + 832 1536 832 1536 832 1461 c 1,8,9 + 832 1280 832 1280 832 1099 c 0,10,11 + 832 896 832 896 730 896 c 1,12,13 + 832 896 832 896 832 693 c 0,14,15 + 832 693 832 693 832 331 c 1,16,17 + 832 256 832 256 907 256 c 1,18,19 + 1088 256 1088 256 1088 256 c 1,20,-1 + 1088 0 l 1,21,-1 + 907 0 l 0,22,23 + 576 0 576 0 576 331 c 1,24,25 + 576 331 576 331 576 693 c 1,26,27 + 576 768 576 768 501 768 c 0,28,29 + 501 768 501 768 378 768 c 0,30,31 + 320 768 320 768 320 896 c 128,-1,32 + 320 1024 320 1024 378 1024 c 0,33,34 + 378 1024 378 1024 501 1024 c 1,35,36 + 576 1024 576 1024 576 1099 c 1,37,38 + 576 1280 576 1280 576 1461 c 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: bar Encoding: 124 124 122 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 96 -512 2048 256 256 +Image2: image/png 96 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ $;a-Q35d>_jV532ZuZhP5\Z!+&6obWr%P+Tz8OZBBY!QNJ EndImage2 Fore SplineSet -512 1465 m 1,0,1 - 512 1081 512 1081 512 1081 c 1,2,3 - 512 1024 512 1024 568 1024 c 1,4,5 - 668 1024 668 1024 768 1024 c 1,6,7 - 768 768 768 768 768 768 c 1,8,9 - 568 768 568 768 568 768 c 1,10,11 - 512 768 512 768 512 711 c 1,12,13 - 512 313 512 313 512 313 c 1,14,15 - 512 0 512 0 199 0 c 0,16,17 - 199 0 199 0 0 0 c 25,18,-1 - 0 256 l 1,19,20 - 99 256 99 256 198 256 c 1,21,22 - 256 256 256 256 256 313 c 1,23,24 - 256 711 256 711 256 711 c 0,25,26 - 256 896 256 896 358 896 c 1,27,28 - 256 896 256 896 256 1081 c 0,29,30 - 256 1460 256 1460 256 1465 c 1,31,32 - 256 1536 256 1536 198 1536 c 1,33,34 - 198 1536 198 1536 0 1536 c 1,35,-1 - 0 1792 l 25,36,-1 - 199 1792 l 1,37,38 - 512 1792 512 1792 512 1465 c 1,0,1 +832 1461 m 1,0,1 + 832 1280 832 1280 832 1099 c 1,2,3 + 832 1024 832 1024 907 1024 c 1,4,5 + 907 1024 907 1024 1031 1024 c 1,6,7 + 1088 1024 1088 1024 1088 896 c 128,-1,8 + 1088 768 1088 768 1031 768 c 1,9,10 + 1031 768 1031 768 907 768 c 1,11,12 + 832 768 832 768 832 693 c 1,13,14 + 832 512 832 512 832 331 c 1,15,16 + 832 0 832 0 501 0 c 0,17,18 + 501 0 501 0 320 0 c 1,19,-1 + 320 256 l 1,20,21 + 501 256 501 256 501 256 c 1,22,23 + 576 256 576 256 576 331 c 1,24,25 + 576 331 576 331 576 693 c 0,26,27 + 576 896 576 896 678 896 c 1,28,29 + 576 896 576 896 576 1099 c 0,30,31 + 576 1099 576 1099 576 1461 c 1,32,33 + 576 1536 576 1536 501 1536 c 1,34,35 + 501 1536 501 1536 320 1536 c 1,36,-1 + 320 1792 l 1,37,-1 + 501 1792 l 1,38,39 + 832 1792 832 1792 832 1461 c 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: asciitilde Encoding: 126 126 124 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 105 0 2048 256 256 +Image2: image/png 105 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8Bu3Ns4^$5aWu ;%.":nW3q%SHMiNf:>V!3`+$*EX4]=!2nui$0`_sf`2!P!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -1280 1099 m 0,0,1 - 1280 768 1280 768 949 768 c 24,2,-1 - 331 768 l 0,3,4 - 256 768 256 768 256 693 c 24,5,-1 - 256 512 l 25,6,-1 - 0 512 l 25,7,8 - 0 514 0 514 0 693 c 0,9,10 - 0 1024 0 1024 331 1024 c 24,11,-1 - 949 1024 l 0,12,13 - 1024 1024 1024 1024 1024 1099 c 24,14,-1 - 1024 1280 l 25,15,-1 - 1280 1280 l 25,16,17 - 1280 1280 1280 1280 1280 1099 c 0,0,1 +1344 1099 m 0,0,1 + 1344 768 1344 768 1013 768 c 24,2,-1 + 395 768 l 0,3,4 + 320 768 320 768 320 693 c 24,5,-1 + 320 512 l 25,6,-1 + 64 512 l 25,7,8 + 64 514 64 514 64 693 c 0,9,10 + 64 1024 64 1024 395 1024 c 24,11,-1 + 1013 1024 l 0,12,13 + 1088 1024 1088 1024 1088 1099 c 24,14,-1 + 1088 1280 l 25,15,-1 + 1344 1280 l 25,16,17 + 1344 1280 1344 1280 1344 1099 c 0,0,1 EndSplineSet Validated: 1 EndChar StartChar: uni007F Encoding: 127 127 125 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 91 0 2048 256 256 +Image2: image/png 91 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2`"cP]X (fhd69$d]%-ia6ZR0X$I$,$09!!!!j78?7R6=>BF EndImage2 Fore SplineSet -0 1280 m 29,0,-1 - 1280 1280 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 1280 l 29,0,-1 +64 1280 m 29,0,-1 + 1344 1280 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 1280 l 29,0,-1 EndSplineSet Validated: 1 EndChar StartChar: uni0080 Encoding: 128 128 126 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 125 0 2048 256 256 +Image2: image/png 125 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$Na!+r&.AZ[o_qq3)XZ$a jG,(OU,Gt71,;FPS34p%"?8b+Wp>g8X:*+q!>pf44u^"9-V`4j,f;.Nmj\#SrL?s7HN4$G!(fUS 7'8jaJcGcN EndImage2 Fore SplineSet -949 1792 m 0,0,1 - 1280 1792 1280 1792 1280 1461 c 0,2,3 - 1280 1461 1280 1461 1280 1280 c 1,4,5 - 1280 1280 1280 1280 1024 1280 c 0,6,-1 - 1024 1461 l 0,7,8 - 1024 1536 1024 1536 949 1536 c 0,9,-1 - 331 1536 l 0,10,11 - 256 1536 256 1536 256 1461 c 0,12,13 - 256 1461 256 1461 256 843 c 0,14,15 - 256 768 256 768 331 768 c 0,16,-1 - 949 768 l 2,17,18 - 1024 768 1024 768 1024 843 c 2,19,-1 - 1024 1024 l 0,20,21 - 1024 1024 1024 1024 1280 1024 c 1,22,23 - 1280 1024 1280 1024 1280 843 c 0,24,25 - 1280 512 1280 512 949 512 c 0,26,-1 - 768 512 l 25,27,-1 - 768 331 l 0,28,29 - 768 0 768 0 437 0 c 0,30,31 - 437 0 437 0 0 0 c 1,32,-1 - 0 256 l 1,33,-1 - 437 256 l 0,34,35 - 512 256 512 256 512 331 c 0,36,37 - 512 331 512 331 512 512 c 1,38,39 - 512 512 512 512 331 512 c 0,40,41 - 0 512 0 512 0 843 c 0,42,43 - 0 843 0 843 0 1461 c 0,44,45 - 0 1792 0 1792 331 1792 c 0,46,47 - 331 1792 331 1792 949 1792 c 0,0,1 +1013 1792 m 0,0,1 + 1344 1792 1344 1792 1344 1461 c 0,2,3 + 1344 1461 1344 1461 1344 1280 c 1,4,5 + 1344 1280 1344 1280 1088 1280 c 0,6,-1 + 1088 1461 l 0,7,8 + 1088 1536 1088 1536 1013 1536 c 0,9,-1 + 395 1536 l 0,10,11 + 320 1536 320 1536 320 1461 c 0,12,13 + 320 1461 320 1461 320 843 c 0,14,15 + 320 768 320 768 395 768 c 0,16,-1 + 1013 768 l 2,17,18 + 1088 768 1088 768 1088 843 c 2,19,-1 + 1088 1024 l 0,20,21 + 1088 1024 1088 1024 1344 1024 c 1,22,23 + 1344 1024 1344 1024 1344 843 c 0,24,25 + 1344 512 1344 512 1013 512 c 0,26,-1 + 832 512 l 25,27,-1 + 832 331 l 0,28,29 + 832 0 832 0 501 0 c 0,30,31 + 501 0 501 0 64 0 c 1,32,-1 + 64 256 l 1,33,-1 + 501 256 l 0,34,35 + 576 256 576 256 576 331 c 0,36,37 + 576 331 576 331 576 512 c 1,38,39 + 576 512 576 512 395 512 c 0,40,41 + 64 512 64 512 64 843 c 0,42,43 + 64 843 64 843 64 1461 c 0,44,45 + 64 1792 64 1792 395 1792 c 0,46,47 + 395 1792 395 1792 1013 1792 c 0,0,1 EndSplineSet Validated: 1 EndChar StartChar: uni0081 Encoding: 129 129 127 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 104 -256 2048 256 256 +Image2: image/png 104 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9Xot.% QD<(8YSD-KYqRS-^]H8+jAU0P_e]DTJ$fY!QI[jFz8OZBBY!QNJ EndImage2 Fore SplineSet -256 1280 m 25,0,-1 - 256 331 l 0,1,2 - 256 256 256 256 331 256 c 24,3,-1 - 768 256 l 24,4,-1 - 768 1280 l 25,5,-1 - 1024 1280 l 25,6,-1 - 1024 0 l 25,7,-1 - 331 0 l 0,8,9 - 0 0 0 0 0 331 c 24,10,11 - 0 331 0 331 0 1280 c 25,12,-1 - 256 1280 l 25,0,-1 -768 1792 m 24,13,-1 - 1024 1792 l 25,14,-1 - 1024 1536 l 24,15,-1 - 768 1536 l 24,16,17 - 768 1536 768 1536 768 1792 c 24,13,-1 -0 1792 m 25,18,-1 - 256 1792 l 25,19,-1 - 256 1536 l 24,20,-1 - 0 1536 l 24,21,22 - 0 1536 0 1536 0 1792 c 25,18,-1 +448 1280 m 25,0,-1 + 448 331 l 0,1,2 + 448 256 448 256 523 256 c 24,3,-1 + 960 256 l 24,4,-1 + 960 1280 l 25,5,-1 + 1216 1280 l 25,6,-1 + 1216 0 l 25,7,-1 + 523 0 l 0,8,9 + 192 0 192 0 192 331 c 24,10,11 + 192 331 192 331 192 1280 c 25,12,-1 + 448 1280 l 25,0,-1 +960 1792 m 24,13,-1 + 1216 1792 l 25,14,-1 + 1216 1536 l 24,15,-1 + 960 1536 l 24,16,17 + 960 1536 960 1536 960 1792 c 24,13,-1 +192 1792 m 25,18,-1 + 448 1792 l 25,19,-1 + 448 1536 l 24,20,-1 + 192 1536 l 24,21,22 + 192 1536 192 1536 192 1792 c 25,18,-1 EndSplineSet Validated: 1 EndChar StartChar: uni0082 Encoding: 130 130 128 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 -256 2048 256 256 +Image2: image/png 121 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#kW'4;_d1fscP2ol-7BF EndImage2 Fore SplineSet -331 512 m 0,0,1 - 256 512 256 512 256 437 c 0,2,3 - 256 331 256 331 256 331 c 0,4,5 - 256 256 256 256 331 256 c 0,6,7 - 331 256 331 256 512 256 c 1,8,9 - 512 256 512 256 512 512 c 1,10,11 - 512 512 512 512 331 512 c 0,0,1 -768 1461 m 1,12,13 - 768 1536 768 1536 693 1536 c 24,14,15 - 693 1536 693 1536 331 1536 c 0,16,17 - 256 1536 256 1536 256 1461 c 1,18,19 - 256 1461 256 1461 256 1280 c 1,20,21 - 256 1280 256 1280 693 1280 c 0,22,23 - 768 1280 768 1280 768 1355 c 0,24,25 - 768 1355 768 1355 768 1461 c 1,12,13 -693 1792 m 0,26,27 - 1024 1792 1024 1792 1024 1461 c 24,28,29 - 1024 1461 1024 1461 1024 1355 c 0,30,31 - 1024 1024 1024 1024 768 1024 c 0,32,33 - 768 640 768 640 768 331 c 0,34,35 - 768 256 768 256 843 256 c 24,36,-1 - 967 256 l 0,37,38 - 1024 256 1024 256 1024 127 c 0,39,40 - 1024 0 1024 0 967 0 c 24,41,42 - 967 0 967 0 181 0 c 0,43,44 - 0 0 0 0 0 181 c 24,45,46 - 0 181 0 181 0 587 c 0,47,48 - 0 768 0 768 181 768 c 24,49,-1 - 512 768 l 25,50,-1 - 512 1024 l 24,51,-1 - 0 1024 l 24,52,53 - 0 1408 0 1408 0 1461 c 0,54,55 - 0 1792 0 1792 331 1792 c 24,56,57 - 331 1792 331 1792 693 1792 c 0,26,27 +523 512 m 0,0,1 + 448 512 448 512 448 437 c 0,2,3 + 448 331 448 331 448 331 c 0,4,5 + 448 256 448 256 523 256 c 0,6,7 + 523 256 523 256 704 256 c 1,8,9 + 704 256 704 256 704 512 c 1,10,11 + 704 512 704 512 523 512 c 0,0,1 +960 1461 m 1,12,13 + 960 1536 960 1536 885 1536 c 24,14,15 + 885 1536 885 1536 523 1536 c 0,16,17 + 448 1536 448 1536 448 1461 c 1,18,19 + 448 1461 448 1461 448 1280 c 1,20,21 + 448 1280 448 1280 885 1280 c 0,22,23 + 960 1280 960 1280 960 1355 c 0,24,25 + 960 1355 960 1355 960 1461 c 1,12,13 +885 1792 m 0,26,27 + 1216 1792 1216 1792 1216 1461 c 24,28,29 + 1216 1461 1216 1461 1216 1355 c 0,30,31 + 1216 1024 1216 1024 960 1024 c 0,32,33 + 960 640 960 640 960 331 c 0,34,35 + 960 256 960 256 1035 256 c 24,36,-1 + 1159 256 l 0,37,38 + 1216 256 1216 256 1216 127 c 0,39,40 + 1216 0 1216 0 1159 0 c 24,41,42 + 1159 0 1159 0 373 0 c 0,43,44 + 192 0 192 0 192 181 c 24,45,46 + 192 181 192 181 192 587 c 0,47,48 + 192 768 192 768 373 768 c 24,49,-1 + 704 768 l 25,50,-1 + 704 1024 l 24,51,-1 + 192 1024 l 24,52,53 + 192 1408 192 1408 192 1461 c 0,54,55 + 192 1792 192 1792 523 1792 c 24,56,57 + 523 1792 523 1792 885 1792 c 0,26,27 EndSplineSet Validated: 1 EndChar StartChar: uni0084 Encoding: 132 132 130 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 -256 2048 256 256 +Image2: image/png 121 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9X9;!; X(N\g!Xl:?+?$fj?n4KokRoRb0MI!g^hBqY+:^";i!NjUJC-%a!-E&l&P`+b4obQ_!(fUS7'8ja JcGcN EndImage2 Fore SplineSet -331 512 m 0,0,1 - 256 512 256 512 256 437 c 24,2,3 - 256 363 256 363 256 331 c 0,4,5 - 256 256 256 256 331 256 c 24,6,-1 - 512 256 l 25,7,-1 - 512 512 l 17,8,9 - 512 512 512 512 331 512 c 0,0,1 -0 1280 m 24,10,11 - 0 1280 0 1280 512 1280 c 0,12,13 - 768 1280 768 1280 768 1024 c 24,14,-1 - 768 331 l 0,15,16 - 768 256 768 256 843 256 c 24,17,-1 - 967 256 l 0,18,19 - 1024 256 1024 256 1024 127 c 0,20,21 - 1024 0 1024 0 967 0 c 24,22,23 - 967 0 967 0 256 0 c 0,24,25 - 0 0 0 0 0 256 c 24,26,27 - 0 256 0 256 0 512 c 128,-1,28 - 0 768 0 768 256 768 c 24,29,-1 - 512 768 l 25,30,31 - 512 898 512 898 512 949 c 0,32,33 - 512 1024 512 1024 437 1024 c 24,34,-1 - 0 1024 l 24,35,36 - 0 1152 0 1152 0 1280 c 24,10,11 -512 1792 m 25,37,-1 - 768 1792 l 25,38,-1 - 768 1536 l 25,39,-1 - 512 1536 l 17,40,41 - 512 1536 512 1536 512 1792 c 25,37,-1 -0 1792 m 9,42,-1 - 256 1792 l 25,43,-1 - 256 1536 l 25,44,-1 - 0 1536 l 17,45,46 - 0 1536 0 1536 0 1792 c 9,42,-1 +523 512 m 0,0,1 + 448 512 448 512 448 437 c 24,2,3 + 448 363 448 363 448 331 c 0,4,5 + 448 256 448 256 523 256 c 24,6,-1 + 704 256 l 25,7,-1 + 704 512 l 17,8,9 + 704 512 704 512 523 512 c 0,0,1 +192 1280 m 24,10,11 + 192 1280 192 1280 704 1280 c 0,12,13 + 960 1280 960 1280 960 1024 c 24,14,-1 + 960 331 l 0,15,16 + 960 256 960 256 1035 256 c 24,17,-1 + 1159 256 l 0,18,19 + 1216 256 1216 256 1216 127 c 0,20,21 + 1216 0 1216 0 1159 0 c 24,22,23 + 1159 0 1159 0 448 0 c 0,24,25 + 192 0 192 0 192 256 c 24,26,27 + 192 256 192 256 192 512 c 128,-1,28 + 192 768 192 768 448 768 c 24,29,-1 + 704 768 l 25,30,31 + 704 898 704 898 704 949 c 0,32,33 + 704 1024 704 1024 629 1024 c 24,34,-1 + 192 1024 l 24,35,36 + 192 1152 192 1152 192 1280 c 24,10,11 +704 1792 m 25,37,-1 + 960 1792 l 25,38,-1 + 960 1536 l 25,39,-1 + 704 1536 l 17,40,41 + 704 1536 704 1536 704 1792 c 25,37,-1 +192 1792 m 9,42,-1 + 448 1792 l 25,43,-1 + 448 1536 l 25,44,-1 + 192 1536 l 17,45,46 + 192 1536 192 1536 192 1792 c 9,42,-1 EndSplineSet Validated: 1 EndChar StartChar: uni0085 Encoding: 133 133 131 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 123 0 2048 256 256 +Image2: image/png 123 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?L$Nf+5E+:&'Ro`)[2:,ig- #3'.E838Xl;KrLigpH%'bhedP@F?Zl!%HH+?63E+!A_Jaqaj=VkhH]N],(kp9",<2!!!!j78?7R 6=>BF EndImage2 Fore SplineSet -587 512 m 0,0,1 - 512 512 512 512 512 437 c 0,2,3 - 512 346 512 346 512 331 c 0,4,5 - 512 256 512 256 587 256 c 0,6,7 - 587 256 587 256 768 256 c 24,8,9 - 768 256 768 256 768 512 c 24,10,11 - 768 512 768 512 587 512 c 0,0,1 -0 1792 m 25,12,13 - 2 1792 2 1792 437 1792 c 0,14,15 - 768 1792 768 1792 768 1461 c 24,16,-1 - 768 1280 l 0,17,-1 - 843 1280 l 0,18,19 - 1024 1280 1024 1280 1024 1099 c 1,20,-1 - 1024 256 l 0,21,-1 - 1223 256 l 0,22,23 - 1280 256 1280 256 1280 127 c 17,24,25 - 1280 0 1280 0 1223 0 c 0,26,27 - 830 0 830 0 437 0 c 0,28,29 - 256 0 256 0 256 181 c 1,30,-1 - 256 587 l 1,31,32 - 256 768 256 768 437 768 c 0,33,-1 - 768 768 l 1,34,-1 - 768 949 l 17,35,36 - 768 1024 768 1024 693 1024 c 24,37,-1 - 256 1024 l 24,38,39 - 256 1024 256 1024 256 1280 c 24,40,-1 - 512 1280 l 24,41,42 - 512 1282 512 1282 512 1461 c 0,43,44 - 512 1536 512 1536 437 1536 c 24,45,-1 - 0 1536 l 24,46,47 - 0 1536 0 1536 0 1792 c 25,12,13 +651 512 m 0,0,1 + 576 512 576 512 576 437 c 0,2,3 + 576 346 576 346 576 331 c 0,4,5 + 576 256 576 256 651 256 c 0,6,7 + 651 256 651 256 832 256 c 24,8,9 + 832 256 832 256 832 512 c 24,10,11 + 832 512 832 512 651 512 c 0,0,1 +64 1792 m 25,12,13 + 66 1792 66 1792 501 1792 c 0,14,15 + 832 1792 832 1792 832 1461 c 24,16,-1 + 832 1280 l 0,17,-1 + 907 1280 l 0,18,19 + 1088 1280 1088 1280 1088 1099 c 1,20,-1 + 1088 256 l 0,21,-1 + 1287 256 l 0,22,23 + 1344 256 1344 256 1344 127 c 17,24,25 + 1344 0 1344 0 1287 0 c 0,26,27 + 894 0 894 0 501 0 c 0,28,29 + 320 0 320 0 320 181 c 1,30,-1 + 320 587 l 1,31,32 + 320 768 320 768 501 768 c 0,33,-1 + 832 768 l 1,34,-1 + 832 949 l 17,35,36 + 832 1024 832 1024 757 1024 c 24,37,-1 + 320 1024 l 24,38,39 + 320 1024 320 1024 320 1280 c 24,40,-1 + 576 1280 l 24,41,42 + 576 1282 576 1282 576 1461 c 0,43,44 + 576 1536 576 1536 501 1536 c 24,45,-1 + 64 1536 l 24,46,47 + 64 1536 64 1536 64 1792 c 25,12,13 EndSplineSet Validated: 1 EndChar StartChar: uni0086 Encoding: 134 134 132 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 124 -256 2048 256 256 +Image2: image/png 124 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$N_'QX+:J@3q#<"J$)@]t pZ@+3S;se'nECd)3;rME"cVsJC-(:i/RpHTM'mT!&S7)$go"b$NrrXke_RMi+2)FlSN("#8$-k"jq*#S+AB?^DV!!#SZ:.26O @"J@Y EndImage2 Fore SplineSet -693 1280 m 0,0,1 - 768 1280 768 1280 768 1355 c 24,2,3 - 768 1446 768 1446 768 1461 c 0,4,5 - 768 1536 768 1536 693 1536 c 24,6,-1 - 331 1536 l 0,7,8 - 256 1536 256 1536 256 1461 c 24,9,10 - 256 1370 256 1370 256 1355 c 0,11,12 - 256 1280 256 1280 331 1280 c 24,13,14 - 331 1280 331 1280 693 1280 c 0,0,1 -950 1154 m 1,15,16 - 1024 1105 1024 1105 1024 967 c 0,17,18 - 1024 967 1024 967 1024 843 c 0,19,20 - 1024 512 1024 512 693 512 c 0,21,22 - 693 512 693 512 256 512 c 1,23,24 - 256 384 256 384 256 331 c 0,25,26 - 256 256 256 256 331 256 c 1,27,28 - 521 256 521 256 711 256 c 0,29,30 - 768 256 768 256 768 127 c 0,31,32 - 768 0 768 0 711 0 c 0,33,34 - 521 0 521 0 331 0 c 0,35,36 - 0 0 0 0 0 331 c 1,37,38 - 0 649 0 649 0 967 c 0,39,40 - 0 1102 0 1102 73 1154 c 1,41,42 - 0 1207 0 1207 0 1355 c 0,43,44 - 0 1458 0 1458 0 1461 c 0,45,46 - 0 1792 0 1792 331 1792 c 24,47,48 - 693 1792 693 1792 693 1792 c 0,49,50 - 1024 1792 1024 1792 1024 1461 c 24,51,52 - 1024 1461 1024 1461 1024 1355 c 0,53,54 - 1024 1211 1024 1211 950 1154 c 1,15,16 -693 768 m 0,55,56 - 768 768 768 768 768 843 c 2,57,58 - 768 843 768 843 768 949 c 1,59,60 - 768 1024 768 1024 693 1024 c 1,61,62 - 331 1024 331 1024 331 1024 c 0,63,64 - 256 1024 256 1024 256 949 c 1,65,66 - 256 858 256 858 256 843 c 0,67,68 - 256 768 256 768 331 768 c 1,69,70 - 331 768 331 768 693 768 c 0,55,56 +885 1280 m 0,0,1 + 960 1280 960 1280 960 1355 c 24,2,3 + 960 1446 960 1446 960 1461 c 0,4,5 + 960 1536 960 1536 885 1536 c 24,6,-1 + 523 1536 l 0,7,8 + 448 1536 448 1536 448 1461 c 24,9,10 + 448 1370 448 1370 448 1355 c 0,11,12 + 448 1280 448 1280 523 1280 c 24,13,14 + 523 1280 523 1280 885 1280 c 0,0,1 +1142 1154 m 1,15,16 + 1216 1105 1216 1105 1216 967 c 0,17,18 + 1216 967 1216 967 1216 843 c 0,19,20 + 1216 512 1216 512 885 512 c 0,21,22 + 885 512 885 512 448 512 c 1,23,24 + 448 384 448 384 448 331 c 0,25,26 + 448 256 448 256 523 256 c 1,27,28 + 713 256 713 256 903 256 c 0,29,30 + 960 256 960 256 960 127 c 0,31,32 + 960 0 960 0 903 0 c 0,33,34 + 713 0 713 0 523 0 c 0,35,36 + 192 0 192 0 192 331 c 1,37,38 + 192 649 192 649 192 967 c 0,39,40 + 192 1102 192 1102 265 1154 c 1,41,42 + 192 1207 192 1207 192 1355 c 0,43,44 + 192 1458 192 1458 192 1461 c 0,45,46 + 192 1792 192 1792 523 1792 c 24,47,48 + 885 1792 885 1792 885 1792 c 0,49,50 + 1216 1792 1216 1792 1216 1461 c 24,51,52 + 1216 1461 1216 1461 1216 1355 c 0,53,54 + 1216 1211 1216 1211 1142 1154 c 1,15,16 +885 768 m 0,55,56 + 960 768 960 768 960 843 c 2,57,58 + 960 843 960 843 960 949 c 1,59,60 + 960 1024 960 1024 885 1024 c 1,61,62 + 523 1024 523 1024 523 1024 c 0,63,64 + 448 1024 448 1024 448 949 c 1,65,66 + 448 858 448 858 448 843 c 0,67,68 + 448 768 448 768 523 768 c 1,69,70 + 523 768 523 768 885 768 c 0,55,56 EndSplineSet Validated: 1 EndChar StartChar: uni0089 Encoding: 137 137 135 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 -256 2048 256 256 +Image2: image/png 121 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9Xot.% Q6XNTQmq716/li65Y_>gF@@`'/mNJ1JFs)6ai0UTp3g!;V?`)AUn4]`8$4!(fUS7'8ja JcGcN EndImage2 Fore SplineSet -768 1792 m 25,0,-1 - 1024 1792 l 25,1,-1 - 1024 1536 l 24,2,-1 - 768 1536 l 24,3,4 - 768 1536 768 1536 768 1792 c 25,0,-1 -0 1792 m 24,5,-1 - 256 1792 l 24,6,-1 - 256 1536 l 24,7,-1 - 0 1536 l 24,8,9 - 0 1536 0 1536 0 1792 c 24,5,-1 -693 768 m 0,10,11 - 768 768 768 768 768 843 c 2,12,13 - 768 843 768 843 768 949 c 1,14,15 - 768 1024 768 1024 693 1024 c 1,16,17 - 331 1024 331 1024 331 1024 c 0,18,19 - 256 1024 256 1024 256 949 c 1,20,21 - 256 858 256 858 256 843 c 0,22,23 - 256 768 256 768 331 768 c 1,24,25 - 331 768 331 768 693 768 c 0,10,11 -0 967 m 0,26,27 - 0 1280 0 1280 313 1280 c 1,28,29 - 313 1280 313 1280 711 1280 c 1,30,31 - 1024 1280 1024 1280 1024 967 c 0,32,33 - 1024 825 1024 825 1024 825 c 0,34,35 - 1024 512 1024 512 711 512 c 24,36,-1 - 256 512 l 1,37,38 - 256 384 256 384 256 331 c 0,39,40 - 256 256 256 256 331 256 c 1,41,42 - 331 256 331 256 711 256 c 0,43,44 - 768 256 768 256 768 127 c 0,45,46 - 768 0 768 0 711 0 c 0,47,-1 - 313 0 l 0,48,49 - 0 0 0 0 0 313 c 1,50,51 - 0 960 0 960 0 967 c 0,26,27 +960 1792 m 25,0,-1 + 1216 1792 l 25,1,-1 + 1216 1536 l 24,2,-1 + 960 1536 l 24,3,4 + 960 1536 960 1536 960 1792 c 25,0,-1 +192 1792 m 24,5,-1 + 448 1792 l 24,6,-1 + 448 1536 l 24,7,-1 + 192 1536 l 24,8,9 + 192 1536 192 1536 192 1792 c 24,5,-1 +885 768 m 0,10,11 + 960 768 960 768 960 843 c 2,12,13 + 960 843 960 843 960 949 c 1,14,15 + 960 1024 960 1024 885 1024 c 1,16,17 + 523 1024 523 1024 523 1024 c 0,18,19 + 448 1024 448 1024 448 949 c 1,20,21 + 448 858 448 858 448 843 c 0,22,23 + 448 768 448 768 523 768 c 1,24,25 + 523 768 523 768 885 768 c 0,10,11 +192 967 m 0,26,27 + 192 1280 192 1280 505 1280 c 1,28,29 + 505 1280 505 1280 903 1280 c 1,30,31 + 1216 1280 1216 1280 1216 967 c 0,32,33 + 1216 825 1216 825 1216 825 c 0,34,35 + 1216 512 1216 512 903 512 c 24,36,-1 + 448 512 l 1,37,38 + 448 384 448 384 448 331 c 0,39,40 + 448 256 448 256 523 256 c 1,41,42 + 523 256 523 256 903 256 c 0,43,44 + 960 256 960 256 960 127 c 0,45,46 + 960 0 960 0 903 0 c 0,47,-1 + 505 0 l 0,48,49 + 192 0 192 0 192 313 c 1,50,51 + 192 960 192 960 192 967 c 0,26,27 EndSplineSet Validated: 1 EndChar StartChar: uni008A Encoding: 138 138 136 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 118 0 2048 256 256 +Image2: image/png 118 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%]fYs3[Tpk #W"5fe7&J+A0GcH^^<=>\4g@_R=J!j8.Md&V^"L-@#i0;$398b)@k'giG8Jo!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -967 768 m 0,0,1 - 1024 768 1024 768 1024 825 c 2,2,3 - 1024 825 1024 825 1024 949 c 1,4,5 - 1024 1024 1024 1024 949 1024 c 1,6,7 - 768 1024 768 1024 587 1024 c 0,8,9 - 512 1024 512 1024 512 949 c 1,10,11 - 512 858 512 858 512 843 c 0,12,13 - 512 768 512 768 587 768 c 1,14,15 - 777 768 777 768 967 768 c 0,0,1 -949 1280 m 1,16,17 - 1280 1280 1280 1280 1280 949 c 0,18,19 - 1280 949 1280 949 1280 825 c 0,20,21 - 1280 512 1280 512 967 512 c 24,22,-1 - 512 512 l 1,23,24 - 512 384 512 384 512 331 c 0,25,26 - 512 256 512 256 587 256 c 1,27,28 - 587 256 587 256 967 256 c 0,29,30 - 1024 256 1024 256 1024 127 c 0,31,32 - 1024 0 1024 0 967 0 c 0,33,-1 - 587 0 l 0,34,35 - 256 0 256 0 256 331 c 1,36,37 - 256 640 256 640 256 949 c 0,38,39 - 256 1280 256 1280 512 1280 c 1,40,41 - 512 1280 512 1280 512 1461 c 0,42,43 - 512 1536 512 1536 437 1536 c 24,44,-1 - 0 1536 l 24,45,46 - 0 1536 0 1536 0 1792 c 25,47,48 - 437 1792 437 1792 437 1792 c 0,49,50 - 768 1792 768 1792 768 1461 c 24,51,-1 - 768 1280 l 0,52,-1 - 949 1280 l 1,16,17 +1031 768 m 0,0,1 + 1088 768 1088 768 1088 825 c 2,2,3 + 1088 825 1088 825 1088 949 c 1,4,5 + 1088 1024 1088 1024 1013 1024 c 1,6,7 + 832 1024 832 1024 651 1024 c 0,8,9 + 576 1024 576 1024 576 949 c 1,10,11 + 576 858 576 858 576 843 c 0,12,13 + 576 768 576 768 651 768 c 1,14,15 + 841 768 841 768 1031 768 c 0,0,1 +1013 1280 m 1,16,17 + 1344 1280 1344 1280 1344 949 c 0,18,19 + 1344 949 1344 949 1344 825 c 0,20,21 + 1344 512 1344 512 1031 512 c 24,22,-1 + 576 512 l 1,23,24 + 576 384 576 384 576 331 c 0,25,26 + 576 256 576 256 651 256 c 1,27,28 + 651 256 651 256 1031 256 c 0,29,30 + 1088 256 1088 256 1088 127 c 0,31,32 + 1088 0 1088 0 1031 0 c 0,33,-1 + 651 0 l 0,34,35 + 320 0 320 0 320 331 c 1,36,37 + 320 640 320 640 320 949 c 0,38,39 + 320 1280 320 1280 576 1280 c 1,40,41 + 576 1280 576 1280 576 1461 c 0,42,43 + 576 1536 576 1536 501 1536 c 24,44,-1 + 64 1536 l 24,45,46 + 64 1536 64 1536 64 1792 c 25,47,48 + 501 1792 501 1792 501 1792 c 0,49,50 + 832 1792 832 1792 832 1461 c 24,51,-1 + 832 1280 l 0,52,-1 + 1013 1280 l 1,16,17 EndSplineSet Validated: 1 EndChar StartChar: uni008B Encoding: 139 139 137 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 104 -256 2048 256 256 +Image2: image/png 104 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns3"!@&g6 Qij+G2),_\"ZG0ZPDF8^ZCU2qJrTs6W4`HPT/+OBz8OZBBY!QNJ EndImage2 Fore SplineSet -256 1024 m 24,0,-1 - 512 1024 l 24,1,-1 - 512 256 l 24,2,-1 - 768 256 l 24,3,-1 - 768 0 l 25,4,-1 - 0 0 l 25,5,-1 - 0 256 l 24,6,-1 - 256 256 l 24,7,-1 - 256 1024 l 24,0,-1 -512 1536 m 24,8,-1 - 768 1536 l 24,9,-1 - 768 1280 l 24,10,-1 - 512 1280 l 24,11,12 - 512 1280 512 1280 512 1536 c 24,8,-1 -0 1536 m 24,13,-1 - 256 1536 l 24,14,-1 - 256 1280 l 24,15,-1 - 0 1280 l 24,16,17 - 0 1280 0 1280 0 1536 c 24,13,-1 +576 1024 m 24,0,-1 + 832 1024 l 24,1,-1 + 832 256 l 24,2,-1 + 1088 256 l 24,3,-1 + 1088 0 l 25,4,-1 + 320 0 l 25,5,-1 + 320 256 l 24,6,-1 + 576 256 l 24,7,-1 + 576 1024 l 24,0,-1 +832 1536 m 24,8,-1 + 1088 1536 l 24,9,-1 + 1088 1280 l 24,10,-1 + 832 1280 l 24,11,12 + 832 1280 832 1280 832 1536 c 24,8,-1 +320 1536 m 24,13,-1 + 576 1536 l 24,14,-1 + 576 1280 l 24,15,-1 + 320 1280 l 24,16,17 + 320 1280 320 1280 320 1536 c 24,13,-1 EndSplineSet Validated: 1 EndChar StartChar: uni008C Encoding: 140 140 138 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 109 -256 2048 256 256 +Image2: image/png 109 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CNNffG9`^HN: $:'asK=[=RMQ[l)Y@#0!!!!j 78?7R6=>BF EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 1536 l 24,2,-1 - 1024 1536 l 24,3,4 - 1024 1536 1024 1536 1024 1792 c 25,0,-1 -0 1792 m 25,5,-1 - 256 1792 l 25,6,-1 - 256 1536 l 24,7,-1 - 0 1536 l 24,8,9 - 0 1536 0 1536 0 1792 c 25,5,-1 -640 1227 m 1,10,11 - 640 1227 640 1227 256 843 c 1,12,-1 - 256 768 l 25,13,-1 - 1024 768 l 25,14,-1 - 1024 843 l 1,15,-1 - 640 1227 l 1,10,11 -0 0 m 25,16,-1 - 0 949 l 25,17,-1 - 587 1536 l 24,18,-1 - 693 1536 l 24,19,-1 - 1280 949 l 25,20,-1 - 1280 0 l 25,21,-1 - 1024 0 l 25,22,-1 - 1024 512 l 24,23,-1 - 256 512 l 24,24,-1 - 256 0 l 25,25,-1 - 0 0 l 25,16,-1 +1088 1792 m 25,0,-1 + 1344 1792 l 25,1,-1 + 1344 1536 l 24,2,-1 + 1088 1536 l 24,3,4 + 1088 1536 1088 1536 1088 1792 c 25,0,-1 +64 1792 m 25,5,-1 + 320 1792 l 25,6,-1 + 320 1536 l 24,7,-1 + 64 1536 l 24,8,9 + 64 1536 64 1536 64 1792 c 25,5,-1 +704 1227 m 1,10,11 + 704 1227 704 1227 320 843 c 1,12,-1 + 320 768 l 25,13,-1 + 1088 768 l 25,14,-1 + 1088 843 l 1,15,-1 + 704 1227 l 1,10,11 +64 0 m 25,16,-1 + 64 949 l 25,17,-1 + 651 1536 l 24,18,-1 + 757 1536 l 24,19,-1 + 1344 949 l 25,20,-1 + 1344 0 l 25,21,-1 + 1088 0 l 25,22,-1 + 1088 512 l 24,23,-1 + 320 512 l 24,24,-1 + 320 0 l 25,25,-1 + 64 0 l 25,16,-1 EndSplineSet Validated: 1 EndChar StartChar: uni008F Encoding: 143 143 141 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 126 0 2048 256 256 +Image2: image/png 126 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W77fm5<#?L$N_p8d+:(sR)$@mKYCcfT!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -0 1280 m 24,0,-1 - 512 1280 l 24,1,-1 - 512 1461 l 0,2,3 - 512 1792 512 1792 843 1792 c 24,4,-1 - 1280 1792 l 25,5,-1 - 1280 1536 l 24,6,-1 - 843 1536 l 0,7,8 - 768 1536 768 1536 768 1461 c 24,9,10 - 768 1461 768 1461 768 1280 c 24,11,-1 - 1280 1280 l 24,12,-1 - 1280 1024 l 24,13,-1 - 256 1024 l 24,14,-1 - 256 768 l 25,15,-1 - 1024 768 l 25,16,-1 - 1024 512 l 24,17,-1 - 256 512 l 24,18,-1 - 256 256 l 24,19,-1 - 1280 256 l 24,20,-1 - 1280 0 l 25,21,-1 - 0 0 l 25,22,23 - 0 0 0 0 0 1280 c 24,0,-1 +64 1280 m 24,0,-1 + 576 1280 l 24,1,-1 + 576 1461 l 0,2,3 + 576 1792 576 1792 907 1792 c 24,4,-1 + 1344 1792 l 25,5,-1 + 1344 1536 l 24,6,-1 + 907 1536 l 0,7,8 + 832 1536 832 1536 832 1461 c 24,9,10 + 832 1461 832 1461 832 1280 c 24,11,-1 + 1344 1280 l 24,12,-1 + 1344 1024 l 24,13,-1 + 320 1024 l 24,14,-1 + 320 768 l 25,15,-1 + 1088 768 l 25,16,-1 + 1088 512 l 24,17,-1 + 320 512 l 24,18,-1 + 320 256 l 24,19,-1 + 1344 256 l 24,20,-1 + 1344 0 l 25,21,-1 + 64 0 l 25,22,23 + 64 0 64 0 64 1280 c 24,0,-1 EndSplineSet Validated: 1 EndChar StartChar: uni0091 Encoding: 145 145 143 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 112 0 2048 256 256 +Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns2BOMigR fha",#:9GGO\I-1B-aIG?;[Ai-!n.V-JPH:I>Gib3E2&,1z8OZBBY!QNJ EndImage2 Fore SplineSet -256 587 m 0,0,1 - 256 512 256 512 331 512 c 24,2,-1 - 512 512 l 24,3,-1 - 512 768 l 25,4,-1 - 331 768 l 0,5,6 - 256 768 256 768 256 693 c 24,7,8 - 256 685 256 685 256 587 c 0,0,1 -768 1280 m 24,9,-1 - 768 1024 l 24,10,-1 - 949 1024 l 0,11,12 - 1024 1024 1024 1024 1024 1099 c 24,13,14 - 1024 1190 1024 1190 1024 1205 c 0,15,16 - 1024 1280 1024 1280 949 1280 c 24,17,18 - 949 1280 949 1280 768 1280 c 24,9,-1 -0 1536 m 24,19,-1 - 1099 1536 l 0,20,21 - 1280 1536 1280 1536 1280 1355 c 24,22,23 - 1280 1062 1280 1062 1280 949 c 0,24,25 - 1280 768 1280 768 1099 768 c 24,26,-1 - 768 768 l 25,27,-1 - 768 512 l 24,28,-1 - 1280 512 l 24,29,-1 - 1280 256 l 24,30,-1 - 181 256 l 0,31,32 - 0 256 0 256 0 437 c 24,33,34 - 0 747 0 747 0 843 c 0,35,36 - 0 1024 0 1024 181 1024 c 24,37,-1 - 512 1024 l 24,38,-1 - 512 1280 l 24,39,-1 - 0 1280 l 24,40,41 - 0 1280 0 1280 0 1536 c 24,19,-1 +320 587 m 0,0,1 + 320 512 320 512 395 512 c 24,2,-1 + 576 512 l 24,3,-1 + 576 768 l 25,4,-1 + 395 768 l 0,5,6 + 320 768 320 768 320 693 c 24,7,8 + 320 685 320 685 320 587 c 0,0,1 +832 1280 m 24,9,-1 + 832 1024 l 24,10,-1 + 1013 1024 l 0,11,12 + 1088 1024 1088 1024 1088 1099 c 24,13,14 + 1088 1190 1088 1190 1088 1205 c 0,15,16 + 1088 1280 1088 1280 1013 1280 c 24,17,18 + 1013 1280 1013 1280 832 1280 c 24,9,-1 +64 1536 m 24,19,-1 + 1163 1536 l 0,20,21 + 1344 1536 1344 1536 1344 1355 c 24,22,23 + 1344 1062 1344 1062 1344 949 c 0,24,25 + 1344 768 1344 768 1163 768 c 24,26,-1 + 832 768 l 25,27,-1 + 832 512 l 24,28,-1 + 1344 512 l 24,29,-1 + 1344 256 l 24,30,-1 + 245 256 l 0,31,32 + 64 256 64 256 64 437 c 24,33,34 + 64 747 64 747 64 843 c 0,35,36 + 64 1024 64 1024 245 1024 c 24,37,-1 + 576 1024 l 24,38,-1 + 576 1280 l 24,39,-1 + 64 1280 l 24,40,41 + 64 1280 64 1280 64 1536 c 24,19,-1 EndSplineSet Validated: 1 EndChar StartChar: uni0092 Encoding: 146 146 144 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 120 0 2048 256 256 +Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NmS=:+:&%fs8V6p2qg%3 =,mrq3;]4%"#(qEOHKoBKBe+>8GCfabt3P>g8=[l+]'g6T\H[Op1=mP5H,2#z8OZBBY!QNJ EndImage2 Fore SplineSet -256 1024 m 24,0,-1 - 512 1024 l 24,1,2 - 512 1024 512 1024 512 1461 c 0,3,4 - 512 1536 512 1536 437 1536 c 24,5,6 - 437 1536 437 1536 331 1536 c 0,7,8 - 256 1536 256 1536 256 1461 c 24,9,10 - 256 1461 256 1461 256 1024 c 24,0,-1 -0 1461 m 0,11,12 - 0 1792 0 1792 331 1792 c 24,13,14 - 331 1792 331 1792 437 1792 c 0,15,16 - 768 1792 768 1792 768 1461 c 24,17,-1 - 768 1280 l 24,18,-1 - 1280 1280 l 24,19,-1 - 1280 1024 l 24,20,-1 - 768 1024 l 24,21,-1 - 768 768 l 25,22,-1 - 1024 768 l 25,23,-1 - 1024 512 l 24,24,-1 - 768 512 l 24,25,-1 - 768 256 l 24,26,-1 - 1280 256 l 24,27,-1 - 1280 0 l 25,28,-1 - 512 0 l 24,29,-1 - 512 768 l 25,30,-1 - 256 768 l 25,31,-1 - 256 0 l 25,32,-1 - 0 0 l 25,33,34 - 0 896 0 896 0 1461 c 0,11,12 +320 1024 m 24,0,-1 + 576 1024 l 24,1,2 + 576 1024 576 1024 576 1461 c 0,3,4 + 576 1536 576 1536 501 1536 c 24,5,6 + 501 1536 501 1536 395 1536 c 0,7,8 + 320 1536 320 1536 320 1461 c 24,9,10 + 320 1461 320 1461 320 1024 c 24,0,-1 +64 1461 m 0,11,12 + 64 1792 64 1792 395 1792 c 24,13,14 + 395 1792 395 1792 501 1792 c 0,15,16 + 832 1792 832 1792 832 1461 c 24,17,-1 + 832 1280 l 24,18,-1 + 1344 1280 l 24,19,-1 + 1344 1024 l 24,20,-1 + 832 1024 l 24,21,-1 + 832 768 l 25,22,-1 + 1088 768 l 25,23,-1 + 1088 512 l 24,24,-1 + 832 512 l 24,25,-1 + 832 256 l 24,26,-1 + 1344 256 l 24,27,-1 + 1344 0 l 25,28,-1 + 576 0 l 24,29,-1 + 576 768 l 25,30,-1 + 320 768 l 25,31,-1 + 320 0 l 25,32,-1 + 64 0 l 25,33,34 + 64 896 64 896 64 1461 c 0,11,12 EndSplineSet Validated: 1 EndChar StartChar: uni0093 Encoding: 147 147 145 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 117 -256 2048 256 256 +Image2: image/png 117 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CNNffHd!JJi$ =91qoA.T$A.q/PD5aF[EOe<#"2k\n7itJd$X8qAmQnDnf!,J_Z&,&Qt?N:'+!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -331 1024 m 0,0,1 - 256 1024 256 1024 256 949 c 24,2,3 - 256 730 256 730 256 587 c 0,4,5 - 256 512 256 512 331 512 c 24,6,-1 - 693 512 l 0,7,8 - 768 512 768 512 768 587 c 24,9,10 - 768 806 768 806 768 949 c 0,11,12 - 768 1024 768 1024 693 1024 c 24,13,14 - 693 1024 693 1024 331 1024 c 0,0,1 -331 1536 m 0,15,16 - 256 1536 256 1536 256 1461 c 24,17,18 - 256 1370 256 1370 256 1355 c 0,19,20 - 256 1280 256 1280 331 1280 c 24,21,-1 - 693 1280 l 0,22,23 - 768 1280 768 1280 768 1355 c 24,24,25 - 768 1446 768 1446 768 1461 c 0,26,27 - 768 1536 768 1536 693 1536 c 24,28,29 - 693 1536 693 1536 331 1536 c 0,15,16 -948 1152 m 1,30,31 - 1024 1106 1024 1106 1024 949 c 0,32,33 - 1024 616 1024 616 1024 587 c 0,34,35 - 1024 256 1024 256 693 256 c 24,36,37 - 331 256 331 256 331 256 c 0,38,39 - 0 256 0 256 0 587 c 24,40,41 - 0 846 0 846 0 949 c 0,42,43 - 0 1100 0 1100 75 1151 c 1,44,45 - 0 1196 0 1196 0 1355 c 0,46,47 - 0 1437 0 1437 0 1461 c 0,48,49 - 0 1792 0 1792 331 1792 c 24,50,51 - 690 1792 690 1792 693 1792 c 0,52,53 - 1021 1792 1021 1792 1024 1461 c 24,54,55 - 1024 1461 1024 1461 1024 1355 c 0,56,57 - 1024 1201 1024 1201 948 1152 c 1,30,31 +523 1024 m 0,0,1 + 448 1024 448 1024 448 949 c 24,2,3 + 448 730 448 730 448 587 c 0,4,5 + 448 512 448 512 523 512 c 24,6,-1 + 885 512 l 0,7,8 + 960 512 960 512 960 587 c 24,9,10 + 960 806 960 806 960 949 c 0,11,12 + 960 1024 960 1024 885 1024 c 24,13,14 + 885 1024 885 1024 523 1024 c 0,0,1 +523 1536 m 0,15,16 + 448 1536 448 1536 448 1461 c 24,17,18 + 448 1370 448 1370 448 1355 c 0,19,20 + 448 1280 448 1280 523 1280 c 24,21,-1 + 885 1280 l 0,22,23 + 960 1280 960 1280 960 1355 c 24,24,25 + 960 1446 960 1446 960 1461 c 0,26,27 + 960 1536 960 1536 885 1536 c 24,28,29 + 885 1536 885 1536 523 1536 c 0,15,16 +1140 1152 m 1,30,31 + 1216 1106 1216 1106 1216 949 c 0,32,33 + 1216 616 1216 616 1216 587 c 0,34,35 + 1216 256 1216 256 885 256 c 24,36,37 + 523 256 523 256 523 256 c 0,38,39 + 192 256 192 256 192 587 c 24,40,41 + 192 846 192 846 192 949 c 0,42,43 + 192 1100 192 1100 267 1151 c 1,44,45 + 192 1196 192 1196 192 1355 c 0,46,47 + 192 1437 192 1437 192 1461 c 0,48,49 + 192 1792 192 1792 523 1792 c 24,50,51 + 882 1792 882 1792 885 1792 c 0,52,53 + 1213 1792 1213 1792 1216 1461 c 24,54,55 + 1216 1461 1216 1461 1216 1355 c 0,56,57 + 1216 1201 1216 1201 1140 1152 c 1,30,31 EndSplineSet Validated: 1 EndChar StartChar: uni0094 Encoding: 148 148 146 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 -256 2048 256 256 +Image2: image/png 121 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9Xot.% Q6XNTQmq716/li65Y_>gF@BR@+I0G:$V1>%-]!`j^^=J,OBQFqYl">.e9oz8OZBBY!QNJ EndImage2 Fore SplineSet -587 1024 m 0,0,1 - 512 1024 512 1024 512 949 c 24,2,3 - 512 949 512 949 512 587 c 0,4,5 - 512 512 512 512 587 512 c 24,6,-1 - 949 512 l 0,7,8 - 1024 512 1024 512 1024 587 c 24,9,10 - 1024 587 1024 587 1024 949 c 2,11,12 - 1024 1024 1024 1024 949 1024 c 8,13,14 - 768 1024 768 1024 587 1024 c 0,0,1 -949 1280 m 2,15,16 - 1280 1280 1280 1280 1280 949 c 0,17,18 - 1280 949 1280 949 1280 587 c 0,19,20 - 1280 256 1280 256 949 256 c 10,21,-1 - 587 256 l 0,22,23 - 256 256 256 256 256 587 c 24,24,25 - 256 587 256 587 256 949 c 1,26,27 - 256 1280 256 1280 512 1280 c 0,28,29 - 512 1280 512 1280 512 1461 c 0,30,31 - 512 1536 512 1536 437 1536 c 24,32,-1 - 0 1536 l 24,33,34 - 0 1536 0 1536 0 1792 c 25,35,36 - 1 1792 1 1792 437 1792 c 0,37,38 - 768 1792 768 1792 768 1461 c 24,39,-1 - 768 1280 l 24,40,-1 - 949 1280 l 2,15,16 +651 1024 m 0,0,1 + 576 1024 576 1024 576 949 c 24,2,3 + 576 949 576 949 576 587 c 0,4,5 + 576 512 576 512 651 512 c 24,6,-1 + 1013 512 l 0,7,8 + 1088 512 1088 512 1088 587 c 24,9,10 + 1088 587 1088 587 1088 949 c 2,11,12 + 1088 1024 1088 1024 1013 1024 c 8,13,14 + 832 1024 832 1024 651 1024 c 0,0,1 +1013 1280 m 2,15,16 + 1344 1280 1344 1280 1344 949 c 0,17,18 + 1344 949 1344 949 1344 587 c 0,19,20 + 1344 256 1344 256 1013 256 c 10,21,-1 + 651 256 l 0,22,23 + 320 256 320 256 320 587 c 24,24,25 + 320 587 320 587 320 949 c 1,26,27 + 320 1280 320 1280 576 1280 c 0,28,29 + 576 1280 576 1280 576 1461 c 0,30,31 + 576 1536 576 1536 501 1536 c 24,32,-1 + 64 1536 l 24,33,34 + 64 1536 64 1536 64 1792 c 25,35,36 + 65 1792 65 1792 501 1792 c 0,37,38 + 832 1792 832 1792 832 1461 c 24,39,-1 + 832 1280 l 24,40,-1 + 1013 1280 l 2,15,16 EndSplineSet Validated: 1 EndChar StartChar: uni0096 Encoding: 150 150 148 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 117 0 2048 256 256 +Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CJNffG9N3T?l ":E!T!@^DqO9m04OoPMn2HTrMJ?=?AYgJ[c?i_.'c#/nk!'65V&'==Aec5[M!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -768 1461 m 0,0,1 - 768 1536 768 1536 693 1536 c 24,2,-1 - 331 1536 l 0,3,4 - 256 1536 256 1536 256 1461 c 24,5,6 - 256 1461 256 1461 256 1337 c 25,7,-1 - 313 1280 l 24,8,-1 - 512 1280 l 24,9,-1 - 512 331 l 0,10,11 - 512 256 512 256 587 256 c 24,12,-1 - 1024 256 l 24,13,-1 - 1024 1280 l 24,14,-1 - 768 1280 l 24,15,-1 - 768 1461 l 0,0,1 -0 1461 m 0,16,17 - 0 1792 0 1792 331 1792 c 24,18,-1 - 693 1792 l 0,19,20 - 1024 1792 1024 1792 1024 1461 c 24,21,-1 - 1024 1337 l 0,22,23 - 1024 1280 1024 1280 1081 1280 c 24,24,-1 - 1280 1280 l 24,25,-1 - 1280 0 l 25,26,-1 - 587 0 l 0,27,28 - 256 0 256 0 256 331 c 24,29,-1 - 256 1280 l 24,30,-1 - 0 1280 l 24,31,32 - 0 1287 0 1287 0 1461 c 0,16,17 +832 1461 m 0,0,1 + 832 1536 832 1536 757 1536 c 24,2,-1 + 395 1536 l 0,3,4 + 320 1536 320 1536 320 1461 c 24,5,6 + 320 1461 320 1461 320 1337 c 25,7,-1 + 377 1280 l 24,8,-1 + 576 1280 l 24,9,-1 + 576 331 l 0,10,11 + 576 256 576 256 651 256 c 24,12,-1 + 1088 256 l 24,13,-1 + 1088 1280 l 24,14,-1 + 832 1280 l 24,15,-1 + 832 1461 l 0,0,1 +64 1461 m 0,16,17 + 64 1792 64 1792 395 1792 c 24,18,-1 + 757 1792 l 0,19,20 + 1088 1792 1088 1792 1088 1461 c 24,21,-1 + 1088 1337 l 0,22,23 + 1088 1280 1088 1280 1145 1280 c 24,24,-1 + 1344 1280 l 24,25,-1 + 1344 0 l 25,26,-1 + 651 0 l 0,27,28 + 320 0 320 0 320 331 c 24,29,-1 + 320 1280 l 24,30,-1 + 64 1280 l 24,31,32 + 64 1287 64 1287 64 1461 c 0,16,17 EndSplineSet Validated: 1 EndChar StartChar: uni0097 Encoding: 151 151 149 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 111 0 2048 256 256 +Image2: image/png 111 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8sb%]fYs3[Tpk #W"5fe7&J+O:XqqAcfP1YQ@LH#SG2oY^d/"k=>S;7MH1/$/OGBF EndImage2 Fore SplineSet -1280 1280 m 24,0,-1 - 1280 0 l 25,1,2 - 1280 0 1280 0 587 0 c 24,3,4 - 256 0 256 0 256 331 c 0,5,6 - 256 640 256 640 256 1280 c 24,7,8 - 256 1280 256 1280 455 1280 c 24,9,10 - 512 1280 512 1280 512 1337 c 0,11,12 - 512 1461 512 1461 512 1461 c 24,13,14 - 512 1536 512 1536 437 1536 c 0,15,16 - 437 1536 437 1536 0 1536 c 24,17,-1 - 0 1792 l 25,18,-1 - 437 1792 l 24,19,20 - 768 1792 768 1792 768 1461 c 0,21,22 - 768 1281 768 1281 768 1280 c 24,23,24 - 768 1280 768 1280 512 1280 c 24,25,-1 - 512 331 l 24,26,27 - 512 256 512 256 587 256 c 0,28,29 - 587 256 587 256 1024 256 c 24,30,-1 - 1024 1280 l 24,31,-1 - 1280 1280 l 24,0,-1 +1344 1280 m 24,0,-1 + 1344 0 l 25,1,2 + 1344 0 1344 0 651 0 c 24,3,4 + 320 0 320 0 320 331 c 0,5,6 + 320 640 320 640 320 1280 c 24,7,8 + 320 1280 320 1280 519 1280 c 24,9,10 + 576 1280 576 1280 576 1337 c 0,11,12 + 576 1461 576 1461 576 1461 c 24,13,14 + 576 1536 576 1536 501 1536 c 0,15,16 + 501 1536 501 1536 64 1536 c 24,17,-1 + 64 1792 l 25,18,-1 + 501 1792 l 24,19,20 + 832 1792 832 1792 832 1461 c 0,21,22 + 832 1281 832 1281 832 1280 c 24,23,24 + 832 1280 832 1280 576 1280 c 24,25,-1 + 576 331 l 24,26,27 + 576 256 576 256 651 256 c 0,28,29 + 651 256 651 256 1088 256 c 24,30,-1 + 1088 1280 l 24,31,-1 + 1344 1280 l 24,0,-1 EndSplineSet Validated: 1 EndChar StartChar: uni0098 Encoding: 152 152 150 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 116 -256 2048 256 256 +Image2: image/png 116 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9Xot.% QD<(8YSD-KYqT9F@N]lhgC7'h2Z]][Rtnd+J5jE[5Z\'g[VZ]jUha3>z8OZBBY!QNJ EndImage2 Fore SplineSet -768 1792 m 25,0,-1 - 1024 1792 l 25,1,-1 - 1024 1536 l 24,2,-1 - 768 1536 l 24,3,4 - 768 1536 768 1536 768 1792 c 25,0,-1 -256 1792 m 24,5,-1 - 256 1536 l 24,6,-1 - 0 1536 l 24,7,-1 - 0 1792 l 25,8,9 - 0 1792 0 1792 256 1792 c 24,5,-1 -1024 1280 m 24,10,11 - 1024 1280 1024 1280 1024 331 c 0,12,13 - 1024 0 1024 0 693 0 c 24,14,-1 - 256 0 l 24,15,-1 - 256 256 l 24,16,-1 - 693 256 l 0,17,18 - 768 256 768 256 768 331 c 24,19,20 - 768 331 768 331 768 512 c 24,21,-1 - 331 512 l 0,22,23 - 0 512 0 512 0 843 c 24,24,25 - 0 843 0 843 0 1280 c 24,26,-1 - 256 1280 l 24,27,-1 - 256 843 l 0,28,29 - 256 768 256 768 331 768 c 24,30,-1 - 768 768 l 25,31,-1 - 768 1280 l 24,32,33 - 768 1280 768 1280 1024 1280 c 24,10,11 +960 1792 m 25,0,-1 + 1216 1792 l 25,1,-1 + 1216 1536 l 24,2,-1 + 960 1536 l 24,3,4 + 960 1536 960 1536 960 1792 c 25,0,-1 +448 1792 m 24,5,-1 + 448 1536 l 24,6,-1 + 192 1536 l 24,7,-1 + 192 1792 l 25,8,9 + 192 1792 192 1792 448 1792 c 24,5,-1 +1216 1280 m 24,10,11 + 1216 1280 1216 1280 1216 331 c 0,12,13 + 1216 0 1216 0 885 0 c 24,14,-1 + 448 0 l 24,15,-1 + 448 256 l 24,16,-1 + 885 256 l 0,17,18 + 960 256 960 256 960 331 c 24,19,20 + 960 331 960 331 960 512 c 24,21,-1 + 523 512 l 0,22,23 + 192 512 192 512 192 843 c 24,24,25 + 192 843 192 843 192 1280 c 24,26,-1 + 448 1280 l 24,27,-1 + 448 843 l 0,28,29 + 448 768 448 768 523 768 c 24,30,-1 + 960 768 l 25,31,-1 + 960 1280 l 24,32,33 + 960 1280 960 1280 1216 1280 c 24,10,11 EndSplineSet Validated: 1 EndChar StartChar: uni0099 Encoding: 153 153 151 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 110 0 2048 256 256 +Image2: image/png 110 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8C%,9r(&#+pt` /0O?$]$P9sR?(e_827Co-56\mi=Ju(!\t7X)Z[-3(^ZKQ:]LIq!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 1536 l 24,2,-1 - 1024 1536 l 24,3,4 - 1024 1536 1024 1536 1024 1792 c 25,0,-1 -0 1792 m 25,5,-1 - 256 1792 l 25,6,-1 - 256 1536 l 24,7,-1 - 0 1536 l 24,8,9 - 0 1536 0 1536 0 1792 c 25,5,-1 -1024 949 m 0,10,11 - 1024 1024 1024 1024 949 1024 c 24,12,-1 - 331 1024 l 0,13,14 - 256 1024 256 1024 256 949 c 24,15,16 - 256 602 256 602 256 331 c 0,17,18 - 256 256 256 256 331 256 c 24,19,-1 - 949 256 l 0,20,21 - 1024 256 1024 256 1024 331 c 24,22,23 - 1024 467 1024 467 1024 949 c 0,10,11 -949 1280 m 0,24,25 - 1280 1280 1280 1280 1280 949 c 24,26,27 - 1280 474 1280 474 1280 331 c 0,28,29 - 1280 0 1280 0 949 0 c 24,30,-1 - 331 0 l 0,31,32 - 0 0 0 0 0 331 c 24,33,34 - 0 806 0 806 0 949 c 0,35,36 - 0 1280 0 1280 331 1280 c 24,37,38 - 331 1280 331 1280 949 1280 c 0,24,25 +1088 1792 m 25,0,-1 + 1344 1792 l 25,1,-1 + 1344 1536 l 24,2,-1 + 1088 1536 l 24,3,4 + 1088 1536 1088 1536 1088 1792 c 25,0,-1 +64 1792 m 25,5,-1 + 320 1792 l 25,6,-1 + 320 1536 l 24,7,-1 + 64 1536 l 24,8,9 + 64 1536 64 1536 64 1792 c 25,5,-1 +1088 949 m 0,10,11 + 1088 1024 1088 1024 1013 1024 c 24,12,-1 + 395 1024 l 0,13,14 + 320 1024 320 1024 320 949 c 24,15,16 + 320 602 320 602 320 331 c 0,17,18 + 320 256 320 256 395 256 c 24,19,-1 + 1013 256 l 0,20,21 + 1088 256 1088 256 1088 331 c 24,22,23 + 1088 467 1088 467 1088 949 c 0,10,11 +1013 1280 m 0,24,25 + 1344 1280 1344 1280 1344 949 c 24,26,27 + 1344 474 1344 474 1344 331 c 0,28,29 + 1344 0 1344 0 1013 0 c 24,30,-1 + 395 0 l 0,31,32 + 64 0 64 0 64 331 c 24,33,34 + 64 806 64 806 64 949 c 0,35,36 + 64 1280 64 1280 395 1280 c 24,37,38 + 395 1280 395 1280 1013 1280 c 0,24,25 EndSplineSet Validated: 1 EndChar StartChar: uni009A Encoding: 154 154 152 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 97 0 2048 256 256 +Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8C%,9r(&#+o?< Qr)#I_P(38$cn[U/k>Xn!4\[3&p%V?i;`iX!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 1536 l 24,2,-1 - 1024 1536 l 24,3,4 - 1024 1536 1024 1536 1024 1792 c 25,0,-1 -256 1792 m 25,5,-1 - 256 1536 l 24,6,-1 - 0 1536 l 24,7,-1 - 0 1792 l 25,8,-1 - 256 1792 l 25,5,-1 -1280 1280 m 24,9,10 - 1280 1280 1280 1280 1280 331 c 0,11,12 - 1280 0 1280 0 949 0 c 24,13,-1 - 331 0 l 0,14,15 - 0 0 0 0 0 331 c 24,16,17 - 0 331 0 331 0 1280 c 24,18,-1 - 256 1280 l 24,19,-1 - 256 331 l 0,20,21 - 256 256 256 256 331 256 c 24,22,-1 - 949 256 l 0,23,24 - 1024 256 1024 256 1024 331 c 24,25,-1 - 1024 1280 l 24,26,27 - 1024 1280 1024 1280 1280 1280 c 24,9,10 +1088 1792 m 25,0,-1 + 1344 1792 l 25,1,-1 + 1344 1536 l 24,2,-1 + 1088 1536 l 24,3,4 + 1088 1536 1088 1536 1088 1792 c 25,0,-1 +320 1792 m 25,5,-1 + 320 1536 l 24,6,-1 + 64 1536 l 24,7,-1 + 64 1792 l 25,8,-1 + 320 1792 l 25,5,-1 +1344 1280 m 24,9,10 + 1344 1280 1344 1280 1344 331 c 0,11,12 + 1344 0 1344 0 1013 0 c 24,13,-1 + 395 0 l 0,14,15 + 64 0 64 0 64 331 c 24,16,17 + 64 331 64 331 64 1280 c 24,18,-1 + 320 1280 l 24,19,-1 + 320 331 l 0,20,21 + 320 256 320 256 395 256 c 24,22,-1 + 1013 256 l 0,23,24 + 1088 256 1088 256 1088 331 c 24,25,-1 + 1088 1280 l 24,26,27 + 1088 1280 1088 1280 1344 1280 c 24,9,10 EndSplineSet Validated: 1 EndChar StartChar: uni009B Encoding: 155 155 153 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 122 -256 2048 256 256 +Image2: image/png 122 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?L$NR8(5+:&'Rs8UE2K+e@/ Q`3';in!tUm[g4<\h=$sKf"laP0aGAR'\%a1Ns&o/_MNWomponhuM-h'+]WtMlHaW!!#SZ:.26O @"J@Y EndImage2 Fore SplineSet -512 1280 m 24,0,-1 - 331 1280 l 0,1,2 - 256 1280 256 1280 256 1205 c 24,3,4 - 256 858 256 858 256 587 c 0,5,6 - 256 512 256 512 331 512 c 24,7,-1 - 512 512 l 24,8,9 - 512 512 512 512 512 1280 c 24,0,-1 -1024 1536 m 24,10,-1 - 1024 1280 l 24,11,-1 - 768 1280 l 24,12,-1 - 768 512 l 24,13,-1 - 1024 512 l 24,14,-1 - 1024 256 l 24,15,-1 - 768 256 l 24,16,-1 - 768 0 l 25,17,-1 - 512 0 l 25,18,-1 - 512 256 l 24,19,-1 - 331 256 l 0,20,21 - 0 256 0 256 0 587 c 24,22,23 - 0 1062 0 1062 0 1205 c 0,24,25 - 0 1536 0 1536 331 1536 c 24,26,-1 - 512 1536 l 24,27,-1 - 512 1792 l 25,28,-1 - 768 1792 l 25,29,-1 - 768 1536 l 24,30,-1 - 1024 1536 l 24,10,-1 +704 1280 m 24,0,-1 + 523 1280 l 0,1,2 + 448 1280 448 1280 448 1205 c 24,3,4 + 448 858 448 858 448 587 c 0,5,6 + 448 512 448 512 523 512 c 24,7,-1 + 704 512 l 24,8,9 + 704 512 704 512 704 1280 c 24,0,-1 +1216 1536 m 24,10,-1 + 1216 1280 l 24,11,-1 + 960 1280 l 24,12,-1 + 960 512 l 24,13,-1 + 1216 512 l 24,14,-1 + 1216 256 l 24,15,-1 + 960 256 l 24,16,-1 + 960 0 l 25,17,-1 + 704 0 l 25,18,-1 + 704 256 l 24,19,-1 + 523 256 l 0,20,21 + 192 256 192 256 192 587 c 24,22,23 + 192 1062 192 1062 192 1205 c 0,24,25 + 192 1536 192 1536 523 1536 c 24,26,-1 + 704 1536 l 24,27,-1 + 704 1792 l 25,28,-1 + 960 1792 l 25,29,-1 + 960 1536 l 24,30,-1 + 1216 1536 l 24,10,-1 EndSplineSet Validated: 1 EndChar StartChar: uni009C Encoding: 156 156 154 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 113 0 2048 256 256 +Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8CNNffHd!JJi$ $V17CJ]f1G$0XEYI*rb&]*%+D'ORNFK`t`^AiGYQ!.c.#&Hl>:i;`iX!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1024 1536 l 24,1,-1 - 587 1536 l 0,2,3 - 512 1536 512 1536 512 1461 c 24,4,5 - 512 1461 512 1461 512 512 c 24,6,-1 - 949 512 l 0,7,8 - 1024 512 1024 512 1024 587 c 24,9,-1 - 1024 768 l 25,10,-1 - 1280 768 l 25,11,12 - 1280 768 1280 768 1280 587 c 0,13,14 - 1280 256 1280 256 949 256 c 24,15,-1 - 0 256 l 24,16,-1 - 0 512 l 24,17,-1 - 256 512 l 24,18,-1 - 256 1461 l 0,19,20 - 256 1792 256 1792 587 1792 c 24,21,22 - 587 1792 587 1792 1024 1792 c 25,0,-1 +1088 1792 m 25,0,-1 + 1088 1536 l 24,1,-1 + 651 1536 l 0,2,3 + 576 1536 576 1536 576 1461 c 24,4,5 + 576 1461 576 1461 576 512 c 24,6,-1 + 1013 512 l 0,7,8 + 1088 512 1088 512 1088 587 c 24,9,-1 + 1088 768 l 25,10,-1 + 1344 768 l 25,11,12 + 1344 768 1344 768 1344 587 c 0,13,14 + 1344 256 1344 256 1013 256 c 24,15,-1 + 64 256 l 24,16,-1 + 64 512 l 24,17,-1 + 320 512 l 24,18,-1 + 320 1461 l 0,19,20 + 320 1792 320 1792 651 1792 c 24,21,22 + 651 1792 651 1792 1088 1792 c 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: uni009D Encoding: 157 157 155 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 109 0 2048 256 256 +Image2: image/png 109 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8C%,9r(&3hH^I ((5m(A-5LALdnicA3P_eO;5%937r>*Co#hh!!@3^#&lu5f)PdN!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -640 1077 m 1,0,1 - 640 1077 640 1077 1024 1461 c 1,2,-1 - 1024 1792 l 25,3,-1 - 1280 1792 l 0,4,5 - 1280 1792 1280 1792 1280 1355 c 8,6,-1 - 949 1024 l 24,7,-1 - 1280 1024 l 24,8,9 - 1280 1024 1280 1024 1280 768 c 25,10,-1 - 768 768 l 25,11,12 - 768 768 768 768 768 512 c 24,13,-1 - 1280 512 l 24,14,15 - 1280 512 1280 512 1280 256 c 24,16,-1 - 768 256 l 24,17,-1 - 768 0 l 25,18,19 - 768 0 768 0 512 0 c 24,20,-1 - 512 256 l 24,21,-1 - 0 256 l 24,22,23 - 0 256 0 256 0 512 c 24,24,-1 - 512 512 l 24,25,26 - 512 512 512 512 512 768 c 25,27,-1 - 0 768 l 25,28,29 - 0 768 0 768 0 1024 c 24,30,-1 - 331 1024 l 24,31,-1 - 0 1355 l 25,32,-1 - 0 1792 l 25,33,-1 - 256 1792 l 1,34,-1 - 256 1461 l 1,35,-1 - 640 1077 l 1,0,1 +704 1077 m 1,0,1 + 704 1077 704 1077 1088 1461 c 1,2,-1 + 1088 1792 l 25,3,-1 + 1344 1792 l 0,4,5 + 1344 1792 1344 1792 1344 1355 c 8,6,-1 + 1013 1024 l 24,7,-1 + 1344 1024 l 24,8,9 + 1344 1024 1344 1024 1344 768 c 25,10,-1 + 832 768 l 25,11,12 + 832 768 832 768 832 512 c 24,13,-1 + 1344 512 l 24,14,15 + 1344 512 1344 512 1344 256 c 24,16,-1 + 832 256 l 24,17,-1 + 832 0 l 25,18,19 + 832 0 832 0 576 0 c 24,20,-1 + 576 256 l 24,21,-1 + 64 256 l 24,22,23 + 64 256 64 256 64 512 c 24,24,-1 + 576 512 l 24,25,26 + 576 512 576 512 576 768 c 25,27,-1 + 64 768 l 25,28,29 + 64 768 64 768 64 1024 c 24,30,-1 + 395 1024 l 24,31,-1 + 64 1355 l 25,32,-1 + 64 1792 l 25,33,-1 + 320 1792 l 1,34,-1 + 320 1461 l 1,35,-1 + 704 1077 l 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: uni009E Encoding: 158 158 156 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 116 0 2048 256 256 +Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8sb%RgE0H5;TS A3i[S7MJ$"*n.r'Ug&Cf,1m>I6'0nVJF"Vm)dn7O)Q">OWN@3=kt"tbz8OZBBY!QNJ EndImage2 Fore SplineSet -512 512 m 24,0,-1 - 1280 512 l 24,1,-1 - 1280 256 l 24,2,-1 - 1024 256 l 24,3,-1 - 1024 0 l 25,4,-1 - 768 0 l 25,5,-1 - 768 256 l 24,6,-1 - 512 256 l 24,7,8 - 512 256 512 256 512 512 c 24,0,-1 -1024 1461 m 0,9,10 - 1024 1536 1024 1536 949 1536 c 24,11,-1 - 256 1536 l 24,12,-1 - 256 1024 l 24,13,-1 - 949 1024 l 0,14,15 - 1024 1024 1024 1024 1024 1099 c 24,16,17 - 1024 1171 1024 1171 1024 1461 c 0,9,10 -0 1792 m 25,18,-1 - 949 1792 l 0,19,20 - 1280 1792 1280 1792 1280 1461 c 24,21,22 - 1280 1114 1280 1114 1280 1099 c 0,23,24 - 1280 768 1280 768 949 768 c 24,25,-1 - 256 768 l 25,26,-1 - 256 0 l 25,27,-1 - 0 0 l 25,28,-1 - 0 1792 l 25,18,-1 +576 512 m 24,0,-1 + 1344 512 l 24,1,-1 + 1344 256 l 24,2,-1 + 1088 256 l 24,3,-1 + 1088 0 l 25,4,-1 + 832 0 l 25,5,-1 + 832 256 l 24,6,-1 + 576 256 l 24,7,8 + 576 256 576 256 576 512 c 24,0,-1 +1088 1461 m 0,9,10 + 1088 1536 1088 1536 1013 1536 c 24,11,-1 + 320 1536 l 24,12,-1 + 320 1024 l 24,13,-1 + 1013 1024 l 0,14,15 + 1088 1024 1088 1024 1088 1099 c 24,16,17 + 1088 1171 1088 1171 1088 1461 c 0,9,10 +64 1792 m 25,18,-1 + 1013 1792 l 0,19,20 + 1344 1792 1344 1792 1344 1461 c 24,21,22 + 1344 1114 1344 1114 1344 1099 c 0,23,24 + 1344 768 1344 768 1013 768 c 24,25,-1 + 320 768 l 25,26,-1 + 320 0 l 25,27,-1 + 64 0 l 25,28,-1 + 64 1792 l 25,18,-1 EndSplineSet Validated: 1 EndChar StartChar: uni009F Encoding: 159 159 157 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#k_'4?][Bs7Z+YqR(`!R,3oNM->T!1aR>1>&)KFFt80!5ad/%nR=YNrT.[!(fUS7'8ja JcGcN EndImage2 Fore SplineSet -1280 1792 m 25,0,1 - 1280 1792 1280 1792 1280 1536 c 24,2,-1 - 843 1536 l 0,3,4 - 768 1536 768 1536 768 1461 c 25,5,6 - 768 1461 768 1461 768 1024 c 24,7,-1 - 1024 1024 l 24,8,9 - 1024 1024 1024 1024 1024 768 c 25,10,-1 - 768 768 l 25,11,-1 - 768 331 l 0,12,13 - 768 0 768 0 437 0 c 24,14,15 - 437 0 437 0 0 0 c 25,16,17 - 0 0 0 0 0 256 c 24,18,-1 - 437 256 l 0,19,20 - 512 256 512 256 512 331 c 24,21,22 - 512 331 512 331 512 768 c 25,23,-1 - 256 768 l 25,24,25 - 256 768 256 768 256 1024 c 0,26,-1 - 512 1024 l 25,27,28 - 512 1024 512 1024 512 1461 c 17,29,30 - 512 1792 512 1792 843 1792 c 24,31,32 - 843 1792 843 1792 1280 1792 c 25,0,1 +1344 1792 m 25,0,1 + 1344 1792 1344 1792 1344 1536 c 24,2,-1 + 907 1536 l 0,3,4 + 832 1536 832 1536 832 1461 c 25,5,6 + 832 1461 832 1461 832 1024 c 24,7,-1 + 1088 1024 l 24,8,9 + 1088 1024 1088 1024 1088 768 c 25,10,-1 + 832 768 l 25,11,-1 + 832 331 l 0,12,13 + 832 0 832 0 501 0 c 24,14,15 + 501 0 501 0 64 0 c 25,16,17 + 64 0 64 0 64 256 c 24,18,-1 + 501 256 l 0,19,20 + 576 256 576 256 576 331 c 24,21,22 + 576 331 576 331 576 768 c 25,23,-1 + 320 768 l 25,24,25 + 320 768 320 768 320 1024 c 0,26,-1 + 576 1024 l 25,27,28 + 576 1024 576 1024 576 1461 c 17,29,30 + 576 1792 576 1792 907 1792 c 24,31,32 + 907 1792 907 1792 1344 1792 c 25,0,1 EndSplineSet Validated: 1 EndChar StartChar: uni00A0 Encoding: 160 160 158 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 125 -256 2048 256 256 +Image2: image/png 125 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$N_p,`+:LRo])S$G(QNpF KTOPnE?4#5;)=B^WLCOLkf.)JPhhE`$6hQ8Km9=:'h\;Df0U7c@_Y%0!Sk=!*9^"N?iU0,!(fUS 7'8jaJcGcN EndImage2 Fore SplineSet -512 437 m 0,0,1 - 512 512 512 512 437 512 c 0,2,-1 - 331 512 l 0,3,4 - 256 512 256 512 256 437 c 0,5,6 - 256 346 256 346 256 331 c 0,7,8 - 256 256 256 256 331 256 c 0,9,10 - 331 256 331 256 437 256 c 0,11,12 - 512 256 512 256 512 331 c 0,13,14 - 512 331 512 331 512 437 c 0,0,1 -512 1280 m 1,15,16 - 768 1280 768 1280 768 949 c 1,17,-1 - 768 256 l 24,18,-1 - 967 256 l 0,19,20 - 1024 256 1024 256 1024 127 c 0,21,22 - 1024 0 1024 0 967 0 c 24,23,24 - 967 0 967 0 331 0 c 0,25,26 - 0 0 0 0 0 331 c 24,27,28 - 0 331 0 331 0 437 c 0,29,30 - 0 768 0 768 331 768 c 24,31,-1 - 512 768 l 25,32,33 - 512 900 512 900 512 949 c 0,34,35 - 512 1024 512 1024 437 1024 c 24,36,-1 - 0 1024 l 24,37,38 - 0 1024 0 1024 0 1280 c 24,39,-1 - 256 1280 l 24,40,-1 - 256 1461 l 0,41,42 - 256 1792 256 1792 587 1792 c 24,43,44 - 587 1792 587 1792 1024 1792 c 25,45,46 - 1024 1792 1024 1792 1024 1536 c 24,47,-1 - 587 1536 l 0,48,49 - 512 1536 512 1536 512 1461 c 24,50,51 - 512 1461 512 1461 512 1280 c 1,15,16 +704 437 m 0,0,1 + 704 512 704 512 629 512 c 0,2,-1 + 523 512 l 0,3,4 + 448 512 448 512 448 437 c 0,5,6 + 448 346 448 346 448 331 c 0,7,8 + 448 256 448 256 523 256 c 0,9,10 + 523 256 523 256 629 256 c 0,11,12 + 704 256 704 256 704 331 c 0,13,14 + 704 331 704 331 704 437 c 0,0,1 +704 1280 m 1,15,16 + 960 1280 960 1280 960 949 c 1,17,-1 + 960 256 l 24,18,-1 + 1159 256 l 0,19,20 + 1216 256 1216 256 1216 127 c 0,21,22 + 1216 0 1216 0 1159 0 c 24,23,24 + 1159 0 1159 0 523 0 c 0,25,26 + 192 0 192 0 192 331 c 24,27,28 + 192 331 192 331 192 437 c 0,29,30 + 192 768 192 768 523 768 c 24,31,-1 + 704 768 l 25,32,33 + 704 900 704 900 704 949 c 0,34,35 + 704 1024 704 1024 629 1024 c 24,36,-1 + 192 1024 l 24,37,38 + 192 1024 192 1024 192 1280 c 24,39,-1 + 448 1280 l 24,40,-1 + 448 1461 l 0,41,42 + 448 1792 448 1792 779 1792 c 24,43,44 + 779 1792 779 1792 1216 1792 c 25,45,46 + 1216 1792 1216 1792 1216 1536 c 24,47,-1 + 779 1536 l 0,48,49 + 704 1536 704 1536 704 1461 c 24,50,51 + 704 1461 704 1461 704 1280 c 1,15,16 EndSplineSet Validated: 1 EndChar StartChar: exclamdown Encoding: 161 161 159 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 115 -256 2048 256 256 +Image2: image/png 115 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#mY$.pLhRc+V#NJBF EndImage2 Fore SplineSet -256 256 m 24,0,-1 - 256 1024 l 24,1,2 - 256 1024 256 1024 512 1024 c 24,3,-1 - 512 256 l 24,4,-1 - 768 256 l 24,5,6 - 768 256 768 256 768 0 c 25,7,-1 - 0 0 l 25,8,-1 - 0 256 l 24,9,-1 - 256 256 l 24,0,-1 -256 1280 m 24,10,11 - 256 1280 256 1280 256 1461 c 17,12,13 - 256 1792 256 1792 587 1792 c 0,14,15 - 587 1792 587 1792 1024 1792 c 0,16,17 - 1024 1792 1024 1792 1024 1536 c 0,18,-1 - 587 1536 l 1,19,20 - 512 1536 512 1536 512 1461 c 8,21,-1 - 512 1280 l 24,22,23 - 512 1280 512 1280 256 1280 c 24,10,11 +448 256 m 24,0,-1 + 448 1024 l 24,1,2 + 448 1024 448 1024 704 1024 c 24,3,-1 + 704 256 l 24,4,-1 + 960 256 l 24,5,6 + 960 256 960 256 960 0 c 25,7,-1 + 192 0 l 25,8,-1 + 192 256 l 24,9,-1 + 448 256 l 24,0,-1 +448 1280 m 24,10,11 + 448 1280 448 1280 448 1461 c 17,12,13 + 448 1792 448 1792 779 1792 c 0,14,15 + 779 1792 779 1792 1216 1792 c 0,16,17 + 1216 1792 1216 1792 1216 1536 c 0,18,-1 + 779 1536 l 1,19,20 + 704 1536 704 1536 704 1461 c 8,21,-1 + 704 1280 l 24,22,23 + 704 1280 704 1280 448 1280 c 24,10,11 EndSplineSet Validated: 1 EndChar StartChar: cent Encoding: 162 162 160 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 118 -256 2048 256 256 +Image2: image/png 118 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#kW'4;_d1fscP2ol,D.o8oiksD6R.KDOCfk>J_!W\Z<',H#YRNqk5!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -331 1024 m 0,0,1 - 256 1024 256 1024 256 949 c 24,2,3 - 256 949 256 949 256 331 c 0,4,5 - 256 256 256 256 331 256 c 24,6,-1 - 693 256 l 0,7,8 - 768 256 768 256 768 331 c 24,9,10 - 768 949 768 949 768 949 c 2,11,12 - 768 1024 768 1024 693 1024 c 8,13,14 - 512 1024 512 1024 331 1024 c 0,0,1 -693 1280 m 0,15,16 - 1024 1280 1024 1280 1024 949 c 24,17,18 - 1024 949 1024 949 1024 331 c 0,19,20 - 1024 0 1024 0 693 0 c 24,21,-1 - 331 0 l 0,22,23 - 0 0 0 0 0 331 c 24,24,25 - 0 806 0 806 0 949 c 0,26,27 - 0 1280 0 1280 256 1280 c 1,28,-1 - 256 1461 l 0,29,30 - 256 1792 256 1792 587 1792 c 24,31,32 - 587 1792 587 1792 1024 1792 c 25,33,34 - 1024 1792 1024 1792 1024 1536 c 24,35,-1 - 587 1536 l 0,36,37 - 512 1536 512 1536 512 1461 c 24,38,39 - 512 1461 512 1461 512 1280 c 24,40,-1 - 693 1280 l 0,15,16 +523 1024 m 0,0,1 + 448 1024 448 1024 448 949 c 24,2,3 + 448 949 448 949 448 331 c 0,4,5 + 448 256 448 256 523 256 c 24,6,-1 + 885 256 l 0,7,8 + 960 256 960 256 960 331 c 24,9,10 + 960 949 960 949 960 949 c 2,11,12 + 960 1024 960 1024 885 1024 c 8,13,14 + 704 1024 704 1024 523 1024 c 0,0,1 +885 1280 m 0,15,16 + 1216 1280 1216 1280 1216 949 c 24,17,18 + 1216 949 1216 949 1216 331 c 0,19,20 + 1216 0 1216 0 885 0 c 24,21,-1 + 523 0 l 0,22,23 + 192 0 192 0 192 331 c 24,24,25 + 192 806 192 806 192 949 c 0,26,27 + 192 1280 192 1280 448 1280 c 1,28,-1 + 448 1461 l 0,29,30 + 448 1792 448 1792 779 1792 c 24,31,32 + 779 1792 779 1792 1216 1792 c 25,33,34 + 1216 1792 1216 1792 1216 1536 c 24,35,-1 + 779 1536 l 0,36,37 + 704 1536 704 1536 704 1461 c 24,38,39 + 704 1461 704 1461 704 1280 c 24,40,-1 + 885 1280 l 0,15,16 EndSplineSet Validated: 1 EndChar StartChar: sterling Encoding: 163 163 161 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 112 -256 2048 256 256 +Image2: image/png 112 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8D_*$Z[Q!sg+R ()R9%J^#mQ$-8:n-D4HA1C]bL>QNK>+NL21%C66=DFY-R6K,CSz8OZBBY!QNJ EndImage2 Fore SplineSet -1024 1280 m 24,0,-1 - 1024 0 l 25,1,-1 - 331 0 l 0,2,3 - 0 0 0 0 0 331 c 24,4,5 - 0 331 0 331 0 1205 c 25,6,-1 - 587 1792 l 24,7,-1 - 1024 1792 l 25,8,-1 - 1024 1536 l 24,9,-1 - 711 1536 l 24,10,-1 - 256 1099 l 25,11,12 - 256 678 256 678 256 331 c 0,13,14 - 256 256 256 256 331 256 c 24,15,-1 - 768 256 l 24,16,-1 - 768 1280 l 24,17,18 - 768 1280 768 1280 1024 1280 c 24,0,-1 +1216 1280 m 24,0,-1 + 1216 0 l 25,1,-1 + 523 0 l 0,2,3 + 192 0 192 0 192 331 c 24,4,5 + 192 331 192 331 192 1205 c 25,6,-1 + 779 1792 l 24,7,-1 + 1216 1792 l 25,8,-1 + 1216 1536 l 24,9,-1 + 903 1536 l 24,10,-1 + 448 1099 l 25,11,12 + 448 678 448 678 448 331 c 0,13,14 + 448 256 448 256 523 256 c 24,15,-1 + 960 256 l 24,16,-1 + 960 1280 l 24,17,18 + 960 1280 960 1280 1216 1280 c 24,0,-1 EndSplineSet Validated: 1 EndChar StartChar: currency Encoding: 164 164 162 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 119 0 2048 256 256 +Image2: image/png 119 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8C%,9n7D"pPj) !Q^/F%:fKR7hu4V7co=BF EndImage2 Fore SplineSet -1212 902 m 1,0,1 - 1280 838 1280 838 1280 693 c 0,2,3 - 1280 693 1280 693 1280 0 c 25,4,5 - 1280 0 1280 0 1024 0 c 25,6,-1 - 1024 768 l 25,7,-1 - 512 768 l 25,8,-1 - 512 0 l 1,9,10 - 256 0 256 0 256 0 c 25,11,12 - 256 1024 256 1024 256 1024 c 1,13,14 - 1024 1024 1024 1024 1024 1024 c 24,15,16 - 1024 1088 1024 1088 1024 1205 c 0,17,18 - 1024 1280 1024 1280 949 1280 c 24,19,20 - 331 1280 331 1280 331 1280 c 0,21,22 - 0 1280 0 1280 0 1611 c 0,23,24 - 0 1790 0 1790 0 1792 c 25,25,26 - 0 1792 0 1792 256 1792 c 25,27,-1 - 256 1611 l 0,28,29 - 256 1536 256 1536 331 1536 c 24,30,31 - 949 1536 949 1536 949 1536 c 0,32,33 - 1280 1536 1280 1536 1280 1205 c 24,34,35 - 1280 1205 1280 1205 1280 1099 c 0,36,37 - 1280 952 1280 952 1212 902 c 1,0,1 +1276 902 m 1,0,1 + 1344 838 1344 838 1344 693 c 0,2,3 + 1344 693 1344 693 1344 0 c 25,4,5 + 1344 0 1344 0 1088 0 c 25,6,-1 + 1088 768 l 25,7,-1 + 576 768 l 25,8,-1 + 576 0 l 1,9,10 + 320 0 320 0 320 0 c 25,11,12 + 320 1024 320 1024 320 1024 c 1,13,14 + 1088 1024 1088 1024 1088 1024 c 24,15,16 + 1088 1088 1088 1088 1088 1205 c 0,17,18 + 1088 1280 1088 1280 1013 1280 c 24,19,20 + 395 1280 395 1280 395 1280 c 0,21,22 + 64 1280 64 1280 64 1611 c 0,23,24 + 64 1790 64 1790 64 1792 c 25,25,26 + 64 1792 64 1792 320 1792 c 25,27,-1 + 320 1611 l 0,28,29 + 320 1536 320 1536 395 1536 c 24,30,31 + 1013 1536 1013 1536 1013 1536 c 0,32,33 + 1344 1536 1344 1536 1344 1205 c 24,34,35 + 1344 1205 1344 1205 1344 1099 c 0,36,37 + 1344 952 1344 952 1276 902 c 1,0,1 EndSplineSet Validated: 1 EndChar StartChar: yen Encoding: 165 165 163 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$bu"fJ+:&'G-f+gFeV%B@ d]^aTL:J\#8H@!r@PC'0#P.e,+]aiOf*(Omi&-B!nDf9V3(U7K?Df4j$$E!f`rH)>!(fUS7'8ja JcGcN EndImage2 Fore SplineSet -1024 1205 m 17,0,1 - 1024 1280 1024 1280 949 1280 c 24,2,3 - 949 1280 949 1280 331 1280 c 0,4,5 - 256 1280 256 1280 256 1205 c 1,6,7 - 256 1205 256 1205 1024 437 c 1,8,-1 - 1024 1205 l 17,0,1 -124 1487 m 1,9,10 - 124 1487 124 1487 0 1611 c 1,11,-1 - 0 1792 l 25,12,13 - 181 1792 181 1792 181 1792 c 152,-1,14 - 181 1792 181 1792 437 1536 c 25,15,-1 - 949 1536 l 0,16,17 - 1280 1536 1280 1536 1280 1205 c 0,18,19 - 1280 0 1280 0 1280 0 c 153,-1,20 - 1280 0 1280 0 1024 0 c 25,21,-1 - 1024 75 l 25,22,-1 - 256 843 l 25,23,-1 - 256 0 l 25,24,-1 - 0 0 l 25,25,26 - 0 1205 0 1205 0 1205 c 0,27,28 - 0 1420 0 1420 124 1487 c 1,9,10 +1088 1205 m 17,0,1 + 1088 1280 1088 1280 1013 1280 c 24,2,3 + 1013 1280 1013 1280 395 1280 c 0,4,5 + 320 1280 320 1280 320 1205 c 1,6,7 + 320 1205 320 1205 1088 437 c 1,8,-1 + 1088 1205 l 17,0,1 +188 1487 m 1,9,10 + 188 1487 188 1487 64 1611 c 1,11,-1 + 64 1792 l 25,12,13 + 245 1792 245 1792 245 1792 c 152,-1,14 + 245 1792 245 1792 501 1536 c 25,15,-1 + 1013 1536 l 0,16,17 + 1344 1536 1344 1536 1344 1205 c 0,18,19 + 1344 0 1344 0 1344 0 c 153,-1,20 + 1344 0 1344 0 1088 0 c 25,21,-1 + 1088 75 l 25,22,-1 + 320 843 l 25,23,-1 + 320 0 l 25,24,-1 + 64 0 l 25,25,26 + 64 1205 64 1205 64 1205 c 0,27,28 + 64 1420 64 1420 188 1487 c 1,9,10 EndSplineSet Validated: 1 EndChar StartChar: brokenbar Encoding: 166 166 164 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 -256 2048 256 256 +Image2: image/png 121 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG9Xor#n '1`BF EndImage2 Fore SplineSet -512 1792 m 24,0,-1 - 768 1792 l 25,1,-1 - 768 1536 l 24,2,-1 - 512 1536 l 24,3,4 - 512 1536 512 1536 512 1792 c 24,0,-1 -1280 512 m 1,5,6 - 1280 512 1280 512 1280 331 c 0,7,8 - 1280 0 1280 0 949 0 c 24,9,-1 - 331 0 l 0,10,11 - 0 0 0 0 0 331 c 24,12,13 - 0 331 0 331 0 437 c 25,14,-1 - 512 949 l 25,15,-1 - 512 1280 l 24,16,-1 - 768 1280 l 24,17,-1 - 768 843 l 25,18,-1 - 256 331 l 0,19,20 - 256 256 256 256 331 256 c 24,21,-1 - 949 256 l 0,22,23 - 1024 256 1024 256 1024 331 c 24,24,-1 - 1024 512 l 17,25,26 - 1024 512 1024 512 1280 512 c 1,5,6 +576 1792 m 24,0,-1 + 832 1792 l 25,1,-1 + 832 1536 l 24,2,-1 + 576 1536 l 24,3,4 + 576 1536 576 1536 576 1792 c 24,0,-1 +1344 512 m 1,5,6 + 1344 512 1344 512 1344 331 c 0,7,8 + 1344 0 1344 0 1013 0 c 24,9,-1 + 395 0 l 0,10,11 + 64 0 64 0 64 331 c 24,12,13 + 64 331 64 331 64 437 c 25,14,-1 + 576 949 l 25,15,-1 + 576 1280 l 24,16,-1 + 832 1280 l 24,17,-1 + 832 843 l 25,18,-1 + 320 331 l 0,19,20 + 320 256 320 256 395 256 c 24,21,-1 + 1013 256 l 0,22,23 + 1088 256 1088 256 1088 331 c 24,24,-1 + 1088 512 l 17,25,26 + 1088 512 1088 512 1344 512 c 1,5,6 EndSplineSet Validated: 1 EndChar StartChar: copyright Encoding: 169 169 167 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 105 0 2048 256 256 +Image2: image/png 105 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8Bu3Ns2`"cP]X (fhd6aoX='=TE7j'#B5s&u:P\)[Inn!!4kb"&IJB(]XO9!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 1280 m 24,0,-1 - 1280 1280 l 24,1,-1 - 1280 1024 l 24,2,-1 - 256 1024 l 24,3,-1 - 256 768 l 25,4,-1 - 0 768 l 25,5,6 - 0 768 0 768 0 1280 c 24,0,-1 +64 1280 m 24,0,-1 + 1344 1280 l 24,1,-1 + 1344 1024 l 24,2,-1 + 320 1024 l 24,3,-1 + 320 768 l 25,4,-1 + 64 768 l 25,5,6 + 64 768 64 768 64 1280 c 24,0,-1 EndSplineSet Validated: 1 EndChar StartChar: ordfeminine Encoding: 170 170 168 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 109 0 2048 256 256 +Image2: image/png 109 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8Bu3Ns2`"cP]X (fhd6b(@hz8OZBBY!QNJ EndImage2 Fore SplineSet -587 256 m 1,1,2 - 587 256 587 256 1024 693 c 0,3,4 - 1024 768 1024 768 949 768 c 24,5,6 - 949 768 949 768 693 768 c 24,7,-1 - 181 256 l 24,8,9 - 181 256 181 256 0 256 c 24,10,11 - 0 256 0 256 0 437 c 25,12,13 - 0 437 0 437 1099 1536 c 1,14,15 - 1099 1536 1099 1536 1280 1536 c 1,16,17 - 1280 1536 1280 1536 1280 1355 c 9,18,-1 - 1024 1099 l 25,19,20 - 1024 1099 1024 1099 1024 1024 c 1,21,22 - 1280 1024 1280 1024 1280 693 c 0,23,24 - 1280 640 1280 640 1280 587 c 0,25,26 - 1280 587 1280 587 949 256 c 1,27,28 - 949 256 949 256 1280 256 c 24,29,30 - 1280 256 1280 256 1280 0 c 25,31,32 - 1280 0 1280 0 512 0 c 0,33,34 - 512 0 512 0 512 256 c 0,35,0 - 512 256 512 256 587 256 c 1,1,2 -0 1792 m 25,36,-1 - 256 1792 l 25,37,-1 - 256 1024 l 24,38,-1 - 0 1024 l 24,39,40 - 0 1024 0 1024 0 1792 c 25,36,-1 +651 256 m 1,1,2 + 651 256 651 256 1088 693 c 0,3,4 + 1088 768 1088 768 1013 768 c 24,5,6 + 1013 768 1013 768 757 768 c 24,7,-1 + 245 256 l 24,8,9 + 245 256 245 256 64 256 c 24,10,11 + 64 256 64 256 64 437 c 25,12,13 + 64 437 64 437 1163 1536 c 1,14,15 + 1163 1536 1163 1536 1344 1536 c 1,16,17 + 1344 1536 1344 1536 1344 1355 c 9,18,-1 + 1088 1099 l 25,19,20 + 1088 1099 1088 1099 1088 1024 c 1,21,22 + 1344 1024 1344 1024 1344 693 c 0,23,24 + 1344 640 1344 640 1344 587 c 0,25,26 + 1344 587 1344 587 1013 256 c 1,27,28 + 1013 256 1013 256 1344 256 c 24,29,30 + 1344 256 1344 256 1344 0 c 25,31,32 + 1344 0 1344 0 576 0 c 0,33,34 + 576 0 576 0 576 256 c 0,35,0 + 576 256 576 256 651 256 c 1,1,2 +64 1792 m 25,36,-1 + 320 1792 l 25,37,-1 + 320 1024 l 24,38,-1 + 64 1024 l 24,39,40 + 64 1024 64 1024 64 1792 c 25,36,-1 EndSplineSet Validated: 1 EndChar StartChar: logicalnot Encoding: 172 172 170 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 120 0 2048 256 256 +Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NDU#_0F1!$G5j(21C0M0 r2Q>,p/MMn!!A6PV]L'kK`3_'n:PP\#-HFDL8@Ise^,tZkffSY%)itrG2h[*z8OZBBY!QNJ EndImage2 Fore SplineSet -693 768 m 1,0,1 - 693 768 693 768 768 768 c 1,2,-1 - 768 587 l 0,3,4 - 768 512 768 512 843 512 c 24,5,6 - 843 512 843 512 1024 512 c 24,7,8 - 1024 512 1024 512 1024 768 c 25,9,-1 - 1280 768 l 25,10,-1 - 1280 0 l 25,11,-1 - 1024 0 l 25,12,-1 - 1024 256 l 24,13,-1 - 843 256 l 1,14,15 - 512 256 512 256 512 587 c 1,16,17 - 512 587 512 587 181 256 c 0,18,19 - 181 256 181 256 0 256 c 24,20,21 - 0 256 0 256 0 437 c 25,22,23 - 0 437 0 437 1099 1536 c 24,24,25 - 1099 1536 1099 1536 1280 1537 c 0,26,27 - 1280 1537 1280 1537 1280 1355 c 1,28,29 - 1280 1355 1280 1355 693 768 c 1,0,1 -0 1792 m 25,30,-1 - 256 1792 l 25,31,-1 - 256 1024 l 24,32,-1 - 0 1024 l 24,33,34 - 0 1024 0 1024 0 1792 c 25,30,-1 +757 768 m 1,0,1 + 757 768 757 768 832 768 c 1,2,-1 + 832 587 l 0,3,4 + 832 512 832 512 907 512 c 24,5,6 + 907 512 907 512 1088 512 c 24,7,8 + 1088 512 1088 512 1088 768 c 25,9,-1 + 1344 768 l 25,10,-1 + 1344 0 l 25,11,-1 + 1088 0 l 25,12,-1 + 1088 256 l 24,13,-1 + 907 256 l 1,14,15 + 576 256 576 256 576 587 c 1,16,17 + 576 587 576 587 245 256 c 0,18,19 + 245 256 245 256 64 256 c 24,20,21 + 64 256 64 256 64 437 c 25,22,23 + 64 437 64 437 1163 1536 c 24,24,25 + 1163 1536 1163 1536 1344 1537 c 0,26,27 + 1344 1537 1344 1537 1344 1355 c 1,28,29 + 1344 1355 1344 1355 757 768 c 1,0,1 +64 1792 m 25,30,-1 + 320 1792 l 25,31,-1 + 320 1024 l 24,32,-1 + 64 1024 l 24,33,34 + 64 1024 64 1024 64 1792 c 25,30,-1 EndSplineSet Validated: 1 EndChar StartChar: uni00AD Encoding: 173 173 171 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 102 -512 2048 256 256 +Image2: image/png 102 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8CNNffG9`^HNZ $?-jc=$Y+8'Q]BrE"e>O:mdIt!!#m3#7ii8+`m\a!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -0 1280 m 24,0,-1 - 256 1280 l 24,1,-1 - 256 0 l 25,2,-1 - 0 0 l 24,3,4 - 0 0 0 0 0 1280 c 24,0,-1 -0 1792 m 24,5,-1 - 256 1792 l 25,6,-1 - 256 1536 l 24,7,-1 - 0 1536 l 24,8,9 - 0 1536 0 1536 0 1792 c 24,5,-1 +576 1280 m 24,0,-1 + 832 1280 l 24,1,-1 + 832 0 l 25,2,-1 + 576 0 l 24,3,4 + 576 0 576 0 576 1280 c 24,0,-1 +576 1792 m 24,5,-1 + 832 1792 l 25,6,-1 + 832 1536 l 24,7,-1 + 576 1536 l 24,8,9 + 576 1536 576 1536 576 1792 c 24,5,-1 EndSplineSet Validated: 1 EndChar StartChar: registered Encoding: 174 174 172 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 115 -58 2048 256 256 +Image2: image/png 115 35 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3"!@&g6 >TGR=,Y68bOB/kI5e>@6_up^')2l^nfh'g'\G7g1BJ]\prtPfbo^aa:!!!!j78?7R6=>BF EndImage2 Fore SplineSet -1041 896 m 1,0,1 - 1222 896 1222 896 1222 693 c 0,2,3 - 1222 693 1222 693 1222 313 c 0,4,5 - 1222 256 1222 256 1094 256 c 144,-1,6 - 966 256 966 256 966 313 c 24,7,-1 - 966 693 l 1,8,9 - 966 843 966 843 768 843 c 0,10,11 - 768 843 768 843 768 949 c 1,12,13 - 966 949 966 949 966 1099 c 1,14,-1 - 966 1479 l 0,15,16 - 966 1536 966 1536 1094 1536 c 128,-1,17 - 1222 1536 1222 1536 1222 1479 c 8,18,19 - 1222 1188 1222 1188 1222 1099 c 0,20,21 - 1222 896 1222 896 1041 896 c 1,0,1 -273 896 m 1,22,23 - 454 896 454 896 454 693 c 0,24,25 - 454 474 454 474 454 313 c 0,26,27 - 454 256 454 256 326 256 c 144,-1,28 - 198 256 198 256 198 313 c 24,29,-1 - 198 693 l 1,30,31 - 198 843 198 843 0 843 c 0,32,33 - 0 843 0 843 0 949 c 1,34,35 - 198 949 198 949 198 1099 c 1,36,-1 - 198 1479 l 0,37,38 - 198 1536 198 1536 326 1536 c 128,-1,39 - 454 1536 454 1536 454 1479 c 8,40,41 - 454 1362 454 1362 454 1099 c 0,42,43 - 454 896 454 896 273 896 c 1,22,23 +1134 896 m 1,0,1 + 1315 896 1315 896 1315 693 c 0,2,3 + 1315 693 1315 693 1315 313 c 0,4,5 + 1315 256 1315 256 1187 256 c 144,-1,6 + 1059 256 1059 256 1059 313 c 24,7,-1 + 1059 693 l 1,8,9 + 1059 843 1059 843 861 843 c 0,10,11 + 861 843 861 843 861 949 c 1,12,13 + 1059 949 1059 949 1059 1099 c 1,14,-1 + 1059 1479 l 0,15,16 + 1059 1536 1059 1536 1187 1536 c 128,-1,17 + 1315 1536 1315 1536 1315 1479 c 8,18,19 + 1315 1188 1315 1188 1315 1099 c 0,20,21 + 1315 896 1315 896 1134 896 c 1,0,1 +366 896 m 1,22,23 + 547 896 547 896 547 693 c 0,24,25 + 547 474 547 474 547 313 c 0,26,27 + 547 256 547 256 419 256 c 144,-1,28 + 291 256 291 256 291 313 c 24,29,-1 + 291 693 l 1,30,31 + 291 843 291 843 93 843 c 0,32,33 + 93 843 93 843 93 949 c 1,34,35 + 291 949 291 949 291 1099 c 1,36,-1 + 291 1479 l 0,37,38 + 291 1536 291 1536 419 1536 c 128,-1,39 + 547 1536 547 1536 547 1479 c 8,40,41 + 547 1362 547 1362 547 1099 c 0,42,43 + 547 896 547 896 366 896 c 1,22,23 EndSplineSet Validated: 1 EndChar StartChar: macron Encoding: 175 175 173 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 114 0 2048 256 256 +Image2: image/png 114 93 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns22,9nF< %5JkL8D"','4K!lfs6#;QBF EndImage2 Fore SplineSet -181 512 m 24,0,-1 - 512 181 l 25,1,-1 - 512 0 l 24,2,-1 - 331 0 l 24,3,-1 - 0 331 l 25,4,-1 - 0 512 l 24,5,6 - 0 512 0 512 181 512 c 24,0,-1 -0 1280 m 24,7,-1 - 181 1280 l 24,8,-1 - 1280 181 l 25,9,-1 - 1280 0 l 25,10,-1 - 1099 0 l 24,11,-1 - 0 1099 l 25,12,13 - 0 1099 0 1099 0 1280 c 24,7,-1 -437 1792 m 25,14,-1 - 1280 949 l 25,15,-1 - 1280 768 l 25,16,-1 - 1099 768 l 24,17,-1 - 256 1611 l 25,18,-1 - 256 1792 l 25,19,-1 - 437 1792 l 25,14,-1 -1024 1792 m 25,20,-1 - 1280 1792 l 25,21,-1 - 1280 1536 l 24,22,-1 - 1024 1536 l 24,23,24 - 1024 1536 1024 1536 1024 1792 c 25,20,-1 +245 512 m 24,0,-1 + 576 181 l 25,1,-1 + 576 0 l 24,2,-1 + 395 0 l 24,3,-1 + 64 331 l 25,4,-1 + 64 512 l 24,5,6 + 64 512 64 512 245 512 c 24,0,-1 +64 1280 m 24,7,-1 + 245 1280 l 24,8,-1 + 1344 181 l 25,9,-1 + 1344 0 l 25,10,-1 + 1163 0 l 24,11,-1 + 64 1099 l 25,12,13 + 64 1099 64 1099 64 1280 c 24,7,-1 +501 1792 m 25,14,-1 + 1344 949 l 25,15,-1 + 1344 768 l 25,16,-1 + 1163 768 l 24,17,-1 + 320 1611 l 25,18,-1 + 320 1792 l 25,19,-1 + 501 1792 l 25,14,-1 +1088 1792 m 25,20,-1 + 1344 1792 l 25,21,-1 + 1344 1536 l 24,22,-1 + 1088 1536 l 24,23,24 + 1088 1536 1088 1536 1088 1792 c 25,20,-1 EndSplineSet Validated: 1 EndChar StartChar: plusminus Encoding: 177 177 175 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 102 0 2048 256 256 +Image2: image/png 102 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8C%,9p;/SVHB; !Z;!$7&FCU+<#%tZ6[X>R%hE)!WYS80bpR=__(oh!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -512 75 m 17,0,-1 - 384 203 l 1,1,2 - 384 203 384 203 256 75 c 1,3,4 - 256 75 256 75 256 0 c 25,5,-1 - 0 0 l 25,6,7 - 0 0 0 0 0 256 c 24,8,-1 - 75 256 l 17,9,10 - 75 256 75 256 203 384 c 1,11,12 - 202 385 202 385 75 512 c 1,13,-1 - 0 512 l 24,14,15 - 0 512 0 512 0 768 c 25,16,17 - 75 768 75 768 75 768 c 129,-1,18 - 75 768 75 768 203 896 c 1,19,20 - 203 896 203 896 75 1024 c 1,21,22 - 75 1024 75 1024 0 1024 c 25,23,24 - 0 1280 0 1280 0 1280 c 24,25,26 - 75 1280 75 1280 75 1280 c 129,-1,27 - 75 1280 75 1280 203 1408 c 1,28,29 - 203 1408 203 1408 0 1611 c 1,30,31 - 0 1792 0 1792 0 1792 c 24,32,33 - 181 1792 181 1792 181 1792 c 128,-1,34 - 181 1792 181 1792 384 1590 c 1,35,36 - 512 1717 512 1717 512 1717 c 1,37,38 - 512 1792 512 1792 512 1792 c 153,-1,39 - 512 1792 512 1792 768 1792 c 25,40,-1 - 768 1717 l 1,41,42 - 768 1717 768 1717 896 1589 c 1,43,44 - 1099 1792 1099 1792 1099 1792 c 129,-1,45 - 1099 1792 1099 1792 1280 1792 c 25,46,47 - 1280 1536 1280 1536 1280 1536 c 24,48,49 - 1205 1536 1205 1536 1205 1536 c 129,-1,50 - 1205 1536 1205 1536 1077 1408 c 1,51,52 - 1205 1280 1205 1280 1205 1280 c 137,-1,53 - 1205 1280 1205 1280 1280 1280 c 25,54,55 - 1280 1152 1280 1152 1280 1024 c 24,56,57 - 1280 1024 1280 1024 1205 1024 c 1,58,59 - 1141 960 1141 960 1077 896 c 1,60,61 - 1077 896 1077 896 1205 768 c 1,62,63 - 1205 768 1205 768 1280 768 c 25,64,65 - 1280 512 1280 512 1280 512 c 24,66,67 - 1205 512 1205 512 1205 512 c 129,-1,68 - 1205 512 1205 512 1077 384 c 1,69,70 - 1077 384 1077 384 1280 181 c 1,71,72 - 1280 90 1280 90 1280 0 c 24,73,74 - 1280 0 1280 0 1099 0 c 0,75,76 - 1099 0 1099 0 903 210 c 1,77,78 - 903 210 903 210 768 75 c 1,79,80 - 768 56 768 56 768 0 c 25,81,-1 - 512 0 l 24,82,-1 - 512 75 l 17,0,-1 -715 384 m 1,83,84 - 715 384 715 384 640 459 c 1,85,86 - 640 459 640 459 565 384 c 1,87,88 - 565 384 565 384 640 309 c 1,89,90 - 640 309 640 309 715 384 c 1,83,84 -896 565 m 129,-1,92 - 896 565 896 565 971 640 c 1,93,94 - 896 715 896 715 896 715 c 1,95,96 - 821 640 821 640 821 640 c 1,97,91 - 896 565 896 565 896 565 c 129,-1,92 -640 821 m 1,98,99 - 685 864 685 864 715 896 c 1,100,101 - 715 896 715 896 640 971 c 1,102,103 - 640 971 640 971 565 896 c 1,104,105 - 640 821 640 821 640 821 c 1,98,99 -309 640 m 1,106,107 - 309 640 309 640 384 565 c 1,108,109 - 459 640 459 640 459 640 c 129,-1,110 - 459 640 459 640 385 716 c 0,111,112 - 385 716 385 716 309 640 c 1,106,107 -896 1077 m 1,113,114 - 971 1152 971 1152 971 1152 c 1,115,116 - 934 1189 934 1189 896 1227 c 1,117,118 - 896 1227 896 1227 821 1152 c 1,119,120 - 896 1077 896 1077 896 1077 c 1,113,114 -384 1077 m 129,-1,122 - 384 1077 384 1077 459 1152 c 1,123,124 - 459 1152 459 1152 384 1227 c 1,125,126 - 384 1227 384 1227 309 1152 c 1,127,121 - 384 1077 384 1077 384 1077 c 129,-1,122 -715 1408 m 129,-1,129 - 715 1408 715 1408 640 1483 c 1,130,131 - 640 1483 640 1483 565 1408 c 1,132,133 - 640 1333 640 1333 640 1333 c 1,134,128 - 715 1408 715 1408 715 1408 c 129,-1,129 +576 75 m 17,0,-1 + 448 203 l 1,1,2 + 448 203 448 203 320 75 c 1,3,4 + 320 75 320 75 320 0 c 25,5,-1 + 64 0 l 25,6,7 + 64 0 64 0 64 256 c 24,8,-1 + 139 256 l 17,9,10 + 139 256 139 256 267 384 c 1,11,12 + 266 385 266 385 139 512 c 1,13,-1 + 64 512 l 24,14,15 + 64 512 64 512 64 768 c 25,16,17 + 139 768 139 768 139 768 c 129,-1,18 + 139 768 139 768 267 896 c 1,19,20 + 267 896 267 896 139 1024 c 1,21,22 + 139 1024 139 1024 64 1024 c 25,23,24 + 64 1280 64 1280 64 1280 c 24,25,26 + 139 1280 139 1280 139 1280 c 129,-1,27 + 139 1280 139 1280 267 1408 c 1,28,29 + 267 1408 267 1408 64 1611 c 1,30,31 + 64 1792 64 1792 64 1792 c 24,32,33 + 245 1792 245 1792 245 1792 c 128,-1,34 + 245 1792 245 1792 448 1590 c 1,35,36 + 576 1717 576 1717 576 1717 c 1,37,38 + 576 1792 576 1792 576 1792 c 153,-1,39 + 576 1792 576 1792 832 1792 c 25,40,-1 + 832 1717 l 1,41,42 + 832 1717 832 1717 960 1589 c 1,43,44 + 1163 1792 1163 1792 1163 1792 c 129,-1,45 + 1163 1792 1163 1792 1344 1792 c 25,46,47 + 1344 1536 1344 1536 1344 1536 c 24,48,49 + 1269 1536 1269 1536 1269 1536 c 129,-1,50 + 1269 1536 1269 1536 1141 1408 c 1,51,52 + 1269 1280 1269 1280 1269 1280 c 137,-1,53 + 1269 1280 1269 1280 1344 1280 c 25,54,55 + 1344 1152 1344 1152 1344 1024 c 24,56,57 + 1344 1024 1344 1024 1269 1024 c 1,58,59 + 1205 960 1205 960 1141 896 c 1,60,61 + 1141 896 1141 896 1269 768 c 1,62,63 + 1269 768 1269 768 1344 768 c 25,64,65 + 1344 512 1344 512 1344 512 c 24,66,67 + 1269 512 1269 512 1269 512 c 129,-1,68 + 1269 512 1269 512 1141 384 c 1,69,70 + 1141 384 1141 384 1344 181 c 1,71,72 + 1344 90 1344 90 1344 0 c 24,73,74 + 1344 0 1344 0 1163 0 c 0,75,76 + 1163 0 1163 0 967 210 c 1,77,78 + 967 210 967 210 832 75 c 1,79,80 + 832 56 832 56 832 0 c 25,81,-1 + 576 0 l 24,82,-1 + 576 75 l 17,0,-1 +779 384 m 1,83,84 + 779 384 779 384 704 459 c 1,85,86 + 704 459 704 459 629 384 c 1,87,88 + 629 384 629 384 704 309 c 1,89,90 + 704 309 704 309 779 384 c 1,83,84 +960 565 m 129,-1,92 + 960 565 960 565 1035 640 c 1,93,94 + 960 715 960 715 960 715 c 1,95,96 + 885 640 885 640 885 640 c 1,97,91 + 960 565 960 565 960 565 c 129,-1,92 +704 821 m 1,98,99 + 749 864 749 864 779 896 c 1,100,101 + 779 896 779 896 704 971 c 1,102,103 + 704 971 704 971 629 896 c 1,104,105 + 704 821 704 821 704 821 c 1,98,99 +373 640 m 1,106,107 + 373 640 373 640 448 565 c 1,108,109 + 523 640 523 640 523 640 c 129,-1,110 + 523 640 523 640 449 716 c 0,111,112 + 449 716 449 716 373 640 c 1,106,107 +960 1077 m 1,113,114 + 1035 1152 1035 1152 1035 1152 c 1,115,116 + 998 1189 998 1189 960 1227 c 1,117,118 + 960 1227 960 1227 885 1152 c 1,119,120 + 960 1077 960 1077 960 1077 c 1,113,114 +448 1077 m 129,-1,122 + 448 1077 448 1077 523 1152 c 1,123,124 + 523 1152 523 1152 448 1227 c 1,125,126 + 448 1227 448 1227 373 1152 c 1,127,121 + 448 1077 448 1077 448 1077 c 129,-1,122 +779 1408 m 129,-1,129 + 779 1408 779 1408 704 1483 c 1,130,131 + 704 1483 704 1483 629 1408 c 1,132,133 + 704 1333 704 1333 704 1333 c 1,134,128 + 779 1408 779 1408 779 1408 c 129,-1,129 EndSplineSet Validated: 1 EndChar StartChar: uni00B2 Encoding: 178 178 176 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$N6qt4+:Ja /&3J4',qPk!$J3C'$J7Wkl:\`!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 1792 m 29,0,-1 - 512 1792 l 25,1,-1 - 512 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 1792 l 29,0,-1 +448 1792 m 29,0,-1 + 960 1792 l 25,1,-1 + 960 0 l 25,2,-1 + 448 0 l 25,3,-1 + 448 1792 l 29,0,-1 EndSplineSet Validated: 1 EndChar StartChar: acute Encoding: 180 180 178 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 93 0 2048 256 256 +Image2: image/png 93 320 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,Y:Bi<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',qVm5X)sg!$MLK'r$fZcN!qF!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 24,4,-1 - 256 256 l 24,5,-1 - 256 1792 l 25,0,-1 +576 1792 m 25,0,-1 + 1088 1792 l 25,1,-1 + 1088 0 l 25,2,-1 + 320 0 l 25,3,-1 + 320 256 l 24,4,-1 + 576 256 l 24,5,-1 + 576 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: mu Encoding: 181 181 179 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 101 0 2048 256 256 +Image2: image/png 101 320 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';L-\OT"qS'*1l_0G-&@!9%Sr't*9^b5_MB!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 24,4,-1 - 256 256 l 24,5,-1 - 256 512 l 24,6,-1 - 0 512 l 24,7,-1 - 0 768 l 25,8,-1 - 256 768 l 25,9,-1 - 256 1792 l 25,0,-1 +576 1792 m 25,0,-1 + 1088 1792 l 25,1,-1 + 1088 0 l 25,2,-1 + 320 0 l 25,3,-1 + 320 256 l 24,4,-1 + 576 256 l 24,5,-1 + 576 512 l 24,6,-1 + 320 512 l 24,7,-1 + 320 768 l 25,8,-1 + 576 768 l 25,9,-1 + 576 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: paragraph Encoding: 182 182 180 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 95 0 2048 256 256 +Image2: image/png 95 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pJu:T`F-UHiO-kKEN.@)qT34!!!!j78?7R6=>BF EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 0 l 25,2,-1 - 1024 0 l 25,3,-1 - 1024 1792 l 25,0,-1 -256 1792 m 25,4,-1 - 768 1792 l 25,5,-1 - 768 0 l 25,6,-1 - 0 0 l 25,7,-1 - 0 256 l 24,8,-1 - 256 256 l 24,9,-1 - 256 1792 l 25,4,-1 +1088 1792 m 25,0,-1 + 1344 1792 l 25,1,-1 + 1344 0 l 25,2,-1 + 1088 0 l 25,3,-1 + 1088 1792 l 25,0,-1 +320 1792 m 25,4,-1 + 832 1792 l 25,5,-1 + 832 0 l 25,6,-1 + 64 0 l 25,7,-1 + 64 256 l 24,8,-1 + 320 256 l 24,9,-1 + 320 1792 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: periodcentered Encoding: 183 183 181 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 87 0 2048 256 256 +Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y .Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF EndImage2 Fore SplineSet -0 256 m 24,0,-1 - 1280 256 l 24,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,4 - 0 0 0 0 0 256 c 24,0,-1 +64 256 m 24,0,-1 + 1344 256 l 24,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,4 + 64 0 64 0 64 256 c 24,0,-1 EndSplineSet Validated: 1 EndChar StartChar: cedilla Encoding: 184 184 182 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 104 0 2048 256 256 +Image2: image/png 104 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns2<'JKS? _Jgd+]314U+BL9QK(L/c$b?=)$GliE+P$o1*lXZMz8OZBBY!QNJ EndImage2 Fore SplineSet -0 768 m 25,0,-1 - 1280 768 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 24,4,-1 - 1024 256 l 24,5,-1 - 1024 512 l 24,6,-1 - 0 512 l 24,7,8 - 0 512 0 512 0 768 c 25,0,-1 +64 768 m 25,0,-1 + 1344 768 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 24,4,-1 + 1088 256 l 24,5,-1 + 1088 512 l 24,6,-1 + 64 512 l 24,7,8 + 64 512 64 512 64 768 c 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: uni00B9 Encoding: 185 185 183 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 105 0 2048 256 256 +Image2: image/png 105 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pFGM-ihq]&$QW7"9T%;$.opo!$-\!)&6YA2ZNgX!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 256 m 24,0,-1 - 768 256 l 24,1,-1 - 768 0 l 25,2,-1 - 0 0 l 25,3,4 - 0 0 0 0 0 256 c 24,0,-1 -1024 1792 m 25,5,-1 - 1280 1792 l 25,6,-1 - 1280 0 l 25,7,-1 - 1024 0 l 25,8,-1 - 1024 1792 l 25,5,-1 -256 1792 m 25,9,-1 - 768 1792 l 25,10,-1 - 768 512 l 24,11,-1 - 0 512 l 24,12,-1 - 0 768 l 25,13,-1 - 256 768 l 25,14,-1 - 256 1792 l 25,9,-1 +64 256 m 24,0,-1 + 832 256 l 24,1,-1 + 832 0 l 25,2,-1 + 64 0 l 25,3,4 + 64 0 64 0 64 256 c 24,0,-1 +1088 1792 m 25,5,-1 + 1344 1792 l 25,6,-1 + 1344 0 l 25,7,-1 + 1088 0 l 25,8,-1 + 1088 1792 l 25,5,-1 +320 1792 m 25,9,-1 + 832 1792 l 25,10,-1 + 832 512 l 24,11,-1 + 64 512 l 24,12,-1 + 64 768 l 25,13,-1 + 320 768 l 25,14,-1 + 320 1792 l 25,9,-1 EndSplineSet Validated: 1 EndChar StartChar: ordmasculine Encoding: 186 186 184 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 91 -256 2048 256 256 +Image2: image/png 91 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pJtoT`>';-Nk/O`Y'Ep!!!!j78?7R6=>BF EndImage2 Fore SplineSet -768 1792 m 25,0,-1 - 1024 1792 l 25,1,-1 - 1024 0 l 25,2,-1 - 768 0 l 25,3,-1 - 768 1792 l 25,0,-1 -0 1792 m 25,4,-1 - 512 1792 l 25,5,-1 - 512 0 l 25,6,-1 - 0 0 l 25,7,-1 - 0 1792 l 25,4,-1 +960 1792 m 25,0,-1 + 1216 1792 l 25,1,-1 + 1216 0 l 25,2,-1 + 960 0 l 25,3,-1 + 960 1792 l 25,0,-1 +192 1792 m 25,4,-1 + 704 1792 l 25,5,-1 + 704 0 l 25,6,-1 + 192 0 l 25,7,-1 + 192 1792 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: guillemotright Encoding: 187 187 185 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 104 0 2048 256 256 +Image2: image/png 104 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns2<'JKS? _Jgd+]314U+BL9QK(L/c$aKcD@ZW>F=e-$1?1ZPNz8OZBBY!QNJ EndImage2 Fore SplineSet -0 256 m 24,0,-1 - 768 256 l 24,1,-1 - 768 0 l 25,2,-1 - 0 0 l 25,3,4 - 0 0 0 0 0 256 c 24,0,-1 -0 768 m 25,5,-1 - 1280 768 l 25,6,-1 - 1280 0 l 25,7,-1 - 1024 0 l 25,8,-1 - 1024 512 l 24,9,-1 - 0 512 l 24,10,11 - 0 512 0 512 0 768 c 25,5,-1 +64 256 m 24,0,-1 + 832 256 l 24,1,-1 + 832 0 l 25,2,-1 + 64 0 l 25,3,4 + 64 0 64 0 64 256 c 24,0,-1 +64 768 m 25,5,-1 + 1344 768 l 25,6,-1 + 1344 0 l 25,7,-1 + 1088 0 l 25,8,-1 + 1088 512 l 24,9,-1 + 64 512 l 24,10,11 + 64 512 64 512 64 768 c 25,5,-1 EndSplineSet Validated: 1 EndChar StartChar: onequarter Encoding: 188 188 186 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 102 0 2048 256 256 +Image2: image/png 102 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pFGM-ihq]&$QW7"9T#T'*.*q#9;f]U)a46!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,4,-1 - 1024 256 l 25,5,-1 - 1024 1792 l 25,0,-1 -256 1792 m 25,6,-1 - 768 1792 l 25,7,-1 - 768 512 l 25,8,-1 - 0 512 l 25,9,-1 - 0 768 l 25,10,-1 - 256 768 l 25,11,-1 - 256 1792 l 25,6,-1 +1088 1792 m 25,0,-1 + 1344 1792 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,4,-1 + 1088 256 l 25,5,-1 + 1088 1792 l 25,0,-1 +320 1792 m 25,6,-1 + 832 1792 l 25,7,-1 + 832 512 l 25,8,-1 + 64 512 l 25,9,-1 + 64 768 l 25,10,-1 + 320 768 l 25,11,-1 + 320 1792 l 25,6,-1 EndSplineSet Validated: 1 EndChar StartChar: onehalf Encoding: 189 189 187 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 99 0 2048 256 256 +Image2: image/png 99 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 256 l 25,2,-1 - 1024 256 l 25,3,-1 - 1024 1792 l 25,4,-1 - 1280 1792 l 25,5,-1 - 1280 0 l 25,6,-1 - 0 0 l 25,7,-1 - 0 256 l 25,8,-1 - 256 256 l 25,9,-1 - 256 1792 l 25,0,-1 +320 1792 m 25,0,-1 + 832 1792 l 25,1,-1 + 832 256 l 25,2,-1 + 1088 256 l 25,3,-1 + 1088 1792 l 25,4,-1 + 1344 1792 l 25,5,-1 + 1344 0 l 25,6,-1 + 64 0 l 25,7,-1 + 64 256 l 25,8,-1 + 320 256 l 25,9,-1 + 320 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: threequarters Encoding: 190 190 188 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 101 0 2048 256 256 +Image2: image/png 101 320 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';L-\OT"qS'*1l_0G-&@!9%Sr't*9^b5_MB!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,4,-1 - 256 256 l 25,5,-1 - 256 512 l 25,6,-1 - -0 512 l 25,7,-1 - 0 768 l 25,8,-1 - 256 768 l 25,9,-1 - 256 1792 l 25,0,-1 +576 1792 m 25,0,-1 + 1088 1792 l 25,1,-1 + 1088 0 l 25,2,-1 + 320 0 l 25,3,-1 + 320 256 l 25,4,-1 + 576 256 l 25,5,-1 + 576 512 l 25,6,-1 + 320 512 l 25,7,-1 + 320 768 l 25,8,-1 + 576 768 l 25,9,-1 + 576 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: questiondown Encoding: 191 191 189 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 87 0 2048 256 256 +Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y .Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Agrave Encoding: 192 192 190 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 92 -256 2048 256 256 +Image2: image/png 92 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',u$#Yk\J'+V"VlN61l:z8OZBBY!QNJ EndImage2 Fore SplineSet -0 1792 m 25,0,-1 - 512 1792 l 25,1,-1 - 512 256 l 25,2,-1 - 1024 256 l 25,3,-1 - 1024 0 l 25,4,-1 - 0 0 l 25,5,-1 - 0 1792 l 25,0,-1 +192 1792 m 25,0,-1 + 704 1792 l 25,1,-1 + 704 256 l 25,2,-1 + 1216 256 l 25,3,-1 + 1216 0 l 25,4,-1 + 192 0 l 25,5,-1 + 192 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Aacute Encoding: 193 193 191 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 97 0 2048 256 256 +Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',q>e(kI^`n0YHe!FA>'%B8fCrr<$!!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 256 l 25,2,-1 - 1280 256 l 25,3,-1 - 1280 0 l 25,4,-1 - 0 0 l 25,5,-1 - -0 256 l 25,6,-1 - 256 256 l 25,7,-1 - 256 1792 l 25,0,-1 +320 1792 m 25,0,-1 + 832 1792 l 25,1,-1 + 832 256 l 25,2,-1 + 1344 256 l 25,3,-1 + 1344 0 l 25,4,-1 + 64 0 l 25,5,-1 + 64 256 l 25,6,-1 + 320 256 l 25,7,-1 + 320 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Acircumflex Encoding: 194 194 192 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 87 0 2048 256 256 +Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y .Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Atilde Encoding: 195 195 193 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 92 -256 2048 256 256 +Image2: image/png 92 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',u$#Yk\J'+V"VlN61l:z8OZBBY!QNJ EndImage2 Fore SplineSet -0 1792 m 25,0,-1 - 512 1792 l 25,1,-1 - 512 256 l 25,2,-1 - 1024 256 l 25,3,-1 - 1024 0 l 25,4,-1 - 0 0 l 25,5,-1 - 0 1792 l 25,0,-1 +192 1792 m 25,0,-1 + 704 1792 l 25,1,-1 + 704 256 l 25,2,-1 + 1216 256 l 25,3,-1 + 1216 0 l 25,4,-1 + 192 0 l 25,5,-1 + 192 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Adieresis Encoding: 196 196 194 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 87 0 2048 256 256 +Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y .Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF EndImage2 Fore SplineSet --0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - -0 256 l 25,0,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Aring Encoding: 197 197 195 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 97 0 2048 256 256 +Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4',q>e(kI^`n0YHe!FA>'%B8fCrr<$!!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 256 l 25,2,-1 - 1280 256 l 25,3,-1 - 1280 0 l 25,4,-1 - 0 0 l 25,5,-1 - 0 256 l 25,6,-1 - 256 256 l 25,7,-1 - 256 1792 l 25,0,-1 +320 1792 m 25,0,-1 + 832 1792 l 25,1,-1 + 832 256 l 25,2,-1 + 1344 256 l 25,3,-1 + 1344 0 l 25,4,-1 + 64 0 l 25,5,-1 + 64 256 l 25,6,-1 + 320 256 l 25,7,-1 + 320 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: AE Encoding: 198 198 196 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 104 -256 2048 256 256 +Image2: image/png 104 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';Mi7Ci3[4f`e+TGmM@ufLu8F^?>eBB4:K7z8OZBBY!QNJ EndImage2 Fore SplineSet -0 1792 m 25,0,-1 - 512 1792 l 25,1,-1 - 512 768 l 25,2,-1 - 1024 768 l 25,3,-1 - 1024 512 l 25,4,-1 - 512 512 l 25,5,-1 - 512 256 l 25,6,-1 - 1024 256 l 25,7,-1 - 1024 0 l 25,8,-1 - 0 0 l 25,9,-1 - 0 1792 l 25,0,-1 +192 1792 m 25,0,-1 + 704 1792 l 25,1,-1 + 704 768 l 25,2,-1 + 1216 768 l 25,3,-1 + 1216 512 l 25,4,-1 + 704 512 l 25,5,-1 + 704 256 l 25,6,-1 + 1216 256 l 25,7,-1 + 1216 0 l 25,8,-1 + 192 0 l 25,9,-1 + 192 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Ccedilla Encoding: 199 199 197 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 95 -256 2048 256 256 +Image2: image/png 95 -192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pJu:WrV32(]XO\8-Be-C[o1?!!!!j78?7R6=>BF EndImage2 Fore SplineSet -768 1792 m 25,0,-1 - 1024 1792 l 25,1,-1 - 1024 256 l 25,2,-1 - 1280 256 l 25,3,-1 - 1280 0 l 25,4,-1 - 768 0 l 25,5,-1 - 768 1792 l 25,0,-1 -0 1792 m 25,6,-1 - 512 1792 l 25,7,-1 - 512 0 l 25,8,-1 - 0 0 l 25,9,-1 - 0 1792 l 25,6,-1 +832 1792 m 25,0,-1 + 1088 1792 l 25,1,-1 + 1088 256 l 25,2,-1 + 1344 256 l 25,3,-1 + 1344 0 l 25,4,-1 + 832 0 l 25,5,-1 + 832 1792 l 25,0,-1 +64 1792 m 25,6,-1 + 576 1792 l 25,7,-1 + 576 0 l 25,8,-1 + 64 0 l 25,9,-1 + 64 1792 l 25,6,-1 EndSplineSet Validated: 1 EndChar StartChar: Egrave Encoding: 200 200 198 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 100 -256 2048 256 256 +Image2: image/png 100 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!%:k7s_'K703#3K"fZMb"F3oa6rz8OZBBY!QNJ EndImage2 Fore SplineSet -768 1792 m 25,0,-1 - 1024 1792 l 25,1,-1 - 1024 512 l 25,2,-1 - 768 512 l 25,3,-1 - 768 1792 l 25,0,-1 -0 1792 m 25,4,-1 - 512 1792 l 25,5,-1 - 512 256 l 25,6,-1 - 1024 256 l 25,7,-1 - 1024 0 l 25,8,-1 - 0 0 l 25,9,-1 - 0 1792 l 25,4,-1 +960 1792 m 25,0,-1 + 1216 1792 l 25,1,-1 + 1216 512 l 25,2,-1 + 960 512 l 25,3,-1 + 960 1792 l 25,0,-1 +192 1792 m 25,4,-1 + 704 1792 l 25,5,-1 + 704 256 l 25,6,-1 + 1216 256 l 25,7,-1 + 1216 0 l 25,8,-1 + 192 0 l 25,9,-1 + 192 1792 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: Eacute Encoding: 201 201 199 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 102 -256 2048 256 256 +Image2: image/png 102 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8Bu3Ns2<'X3*= @Us";E=0"`_$XSUa:^0]$qI%]"ot9O$4t0"i%tE6!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -768 256 m 25,0,-1 - 1024 256 l 25,1,-1 - 1024 0 l 25,2,-1 - 768 0 l 25,3,-1 - 768 256 l 25,0,-1 -0 768 m 25,4,-1 - 1024 768 l 25,5,-1 - 1024 512 l 25,6,-1 - 512 512 l 25,7,-1 - 512 0 l 25,8,-1 - 0 0 l 25,9,-1 - 0 768 l 25,4,-1 +960 256 m 25,0,-1 + 1216 256 l 25,1,-1 + 1216 0 l 25,2,-1 + 960 0 l 25,3,-1 + 960 256 l 25,0,-1 +192 768 m 25,4,-1 + 1216 768 l 25,5,-1 + 1216 512 l 25,6,-1 + 704 512 l 25,7,-1 + 704 0 l 25,8,-1 + 192 0 l 25,9,-1 + 192 768 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: Ecircumflex Encoding: 202 202 200 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 105 0 2048 256 256 +Image2: image/png 105 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pFGM-ihq]%knXe"\:_02j&Lu!+*5F%a\Tq3<0$Z!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 -1024 1792 m 25,4,-1 - 1280 1792 l 25,5,-1 - 1280 512 l 25,6,-1 - 1024 512 l 25,7,-1 - 1024 1792 l 25,4,-1 -256 1792 m 25,8,-1 - 768 1792 l 25,9,-1 - 768 512 l 25,10,-1 - -0 512 l 25,11,-1 - 0 768 l 25,12,-1 - 256 768 l 25,13,-1 - 256 1792 l 25,8,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +1088 1792 m 25,4,-1 + 1344 1792 l 25,5,-1 + 1344 512 l 25,6,-1 + 1088 512 l 25,7,-1 + 1088 1792 l 25,4,-1 +320 1792 m 25,8,-1 + 832 1792 l 25,9,-1 + 832 512 l 25,10,-1 + 64 512 l 25,11,-1 + 64 768 l 25,12,-1 + 320 768 l 25,13,-1 + 320 1792 l 25,8,-1 EndSplineSet Validated: 1 EndChar StartChar: Edieresis Encoding: 203 203 201 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 102 0 2048 256 256 +Image2: image/png 102 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8Bu3Ns2<'JKS? _Jgd+]314UfGoiZ!_>$j,9m;r-30>o&cjm'^*3OW!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -1024 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 1024 0 l 25,3,-1 - 1024 256 l 25,0,-1 --0 256 m 25,4,-1 - 768 256 l 25,5,-1 - 768 0 l 25,6,-1 - 0 0 l 25,7,-1 - -0 256 l 25,4,-1 -0 768 m 25,8,-1 - 1280 768 l 25,9,-1 - 1280 512 l 25,10,-1 - -0 512 l 25,11,-1 - 0 768 l 25,8,-1 +1088 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 1088 0 l 25,3,-1 + 1088 256 l 25,0,-1 +64 256 m 25,4,-1 + 832 256 l 25,5,-1 + 832 0 l 25,6,-1 + 64 0 l 25,7,-1 + 64 256 l 25,4,-1 +64 768 m 25,8,-1 + 1344 768 l 25,9,-1 + 1344 512 l 25,10,-1 + 64 512 l 25,11,-1 + 64 768 l 25,8,-1 EndSplineSet Validated: 1 EndChar StartChar: Igrave Encoding: 204 204 202 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 99 -256 2048 256 256 +Image2: image/png 99 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!%:k7s_$o`]aKF@jd`!7$Wg'U=M!!!!j78?7R6=>BF EndImage2 Fore SplineSet -768 256 m 25,0,-1 - 1024 256 l 25,1,-1 - 1024 0 l 25,2,-1 - 768 0 l 25,3,-1 - 768 256 l 25,0,-1 -768 1792 m 25,4,-1 - 1024 1792 l 25,5,-1 - 1024 512 l 25,6,-1 - 768 512 l 25,7,-1 - 768 1792 l 25,4,-1 -0 1792 m 25,8,-1 - 512 1792 l 25,9,-1 - 512 0 l 25,10,-1 - 0 0 l 25,11,-1 - 0 1792 l 25,8,-1 +960 256 m 25,0,-1 + 1216 256 l 25,1,-1 + 1216 0 l 25,2,-1 + 960 0 l 25,3,-1 + 960 256 l 25,0,-1 +960 1792 m 25,4,-1 + 1216 1792 l 25,5,-1 + 1216 512 l 25,6,-1 + 960 512 l 25,7,-1 + 960 1792 l 25,4,-1 +192 1792 m 25,8,-1 + 704 1792 l 25,9,-1 + 704 0 l 25,10,-1 + 192 0 l 25,11,-1 + 192 1792 l 25,8,-1 EndSplineSet Validated: 1 EndChar StartChar: Iacute Encoding: 205 205 203 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 94 0 2048 256 256 +Image2: image/png 94 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns2<'JKS? _Jgd+]314UfGmT3"9;^u%fm;4_$'f=!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet --0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - -0 256 l 25,0,-1 -0 768 m 25,4,-1 - 1280 768 l 25,5,-1 - 1280 512 l 25,6,-1 - 0 512 l 25,7,-1 - 0 768 l 25,4,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +64 768 m 25,4,-1 + 1344 768 l 25,5,-1 + 1344 512 l 25,6,-1 + 64 512 l 25,7,-1 + 64 768 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: Icircumflex Encoding: 206 206 204 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 109 0 2048 256 256 +Image2: image/png 109 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pFGM-ihq]%knXe"\:`1Riif*9LSS7!10i!%](Uh2ZNgX!(fUS7'8jaJcGcN EndImage2 Fore SplineSet --0 256 m 25,0,-1 - 768 256 l 25,1,-1 - 768 0 l 25,2,-1 - 0 0 l 25,3,-1 - -0 256 l 25,0,-1 -1024 256 m 25,4,-1 - 1280 256 l 25,5,-1 - 1280 0 l 25,6,-1 - 1024 0 l 25,7,-1 - 1024 256 l 25,4,-1 -1024 1792 m 25,8,-1 - 1280 1792 l 25,9,-1 - 1280 512 l 25,10,-1 - 1024 512 l 25,11,-1 - 1024 1792 l 25,8,-1 -256 1792 m 25,12,-1 - 768 1792 l 25,13,-1 - 768 512 l 25,14,-1 - -0 512 l 25,15,-1 - 0 768 l 25,16,-1 - 256 768 l 25,17,-1 - 256 1792 l 25,12,-1 +64 256 m 25,0,-1 + 832 256 l 25,1,-1 + 832 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +1088 256 m 25,4,-1 + 1344 256 l 25,5,-1 + 1344 0 l 25,6,-1 + 1088 0 l 25,7,-1 + 1088 256 l 25,4,-1 +1088 1792 m 25,8,-1 + 1344 1792 l 25,9,-1 + 1344 512 l 25,10,-1 + 1088 512 l 25,11,-1 + 1088 1792 l 25,8,-1 +320 1792 m 25,12,-1 + 832 1792 l 25,13,-1 + 832 512 l 25,14,-1 + 64 512 l 25,15,-1 + 64 768 l 25,16,-1 + 320 768 l 25,17,-1 + 320 1792 l 25,12,-1 EndSplineSet Validated: 1 EndChar StartChar: Idieresis Encoding: 207 207 205 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 106 0 2048 256 256 +Image2: image/png 106 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';Je5,L@hI7j>R7"doJ!(RZU`!WZ\]%gVktrYPV8!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet --0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - -0 256 l 25,0,-1 -256 1792 m 25,4,-1 - 768 1792 l 25,5,-1 - 768 768 l 25,6,-1 - 1280 768 l 25,7,-1 - 1280 512 l 25,8,-1 - -0 512 l 25,9,-1 - 0 768 l 25,10,-1 - 256 768 l 25,11,-1 - 256 1792 l 25,4,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +320 1792 m 25,4,-1 + 832 1792 l 25,5,-1 + 832 768 l 25,6,-1 + 1344 768 l 25,7,-1 + 1344 512 l 25,8,-1 + 64 512 l 25,9,-1 + 64 768 l 25,10,-1 + 320 768 l 25,11,-1 + 320 1792 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: space Encoding: 32 32 206 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 79 0 2048 256 256 +Image2: image/png 79 2112 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(.gn[<#?K_r!ro=GQ8Bu3O%$&:]LJ7 D?LB^-QJHQ!!!!j78?7R6=>BF EndImage2 @@ -7537,12 +7327,11 @@ EndChar StartChar: uni0000 Encoding: 0 0 207 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 81 0 2048 256 256 +Image2: image/png 81 704 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(eI+]<#?K_A7/g?&&^F.'2BFD`:-S' !";d,&&iB0%KHJ/!(fUS7'8jaJcGcN EndImage2 @@ -7552,1467 +7341,1420 @@ EndChar StartChar: Eth Encoding: 208 208 208 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 99 0 2048 256 256 +Image2: image/png 99 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 256 l 25,2,-1 - 1024 256 l 25,3,-1 - 1024 1792 l 25,4,-1 - 1280 1792 l 25,5,-1 - 1280 0 l 25,6,-1 - 0 0 l 25,7,-1 - -0 256 l 25,8,-1 - 256 256 l 25,9,-1 - 256 1792 l 25,0,-1 +320 1792 m 25,0,-1 + 832 1792 l 25,1,-1 + 832 256 l 25,2,-1 + 1088 256 l 25,3,-1 + 1088 1792 l 25,4,-1 + 1344 1792 l 25,5,-1 + 1344 0 l 25,6,-1 + 64 0 l 25,7,-1 + 64 256 l 25,8,-1 + 320 256 l 25,9,-1 + 320 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Ntilde Encoding: 209 209 209 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 94 0 2048 256 256 +Image2: image/png 94 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns2<'JKS? _Jgd+]314UfGmT3"9;^u%fm;4_$'f=!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet --0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - -0 256 l 25,0,-1 -0 768 m 25,4,-1 - 1280 768 l 25,5,-1 - 1280 512 l 25,6,-1 - 0 512 l 25,7,-1 - 0 768 l 25,4,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +64 768 m 25,4,-1 + 1344 768 l 25,5,-1 + 1344 512 l 25,6,-1 + 64 512 l 25,7,-1 + 64 768 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: Ograve Encoding: 210 210 210 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 87 0 2048 256 256 +Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y .Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF EndImage2 Fore SplineSet -2868 -1048 m 1053,0,-1 -0 256 m 25,1,-1 - 1280 256 l 25,2,-1 - 1280 0 l 25,3,-1 - 0 0 l 25,4,-1 - 0 256 l 25,1,-1 +2932 -1048 m 1053,0,-1 +64 256 m 25,1,-1 + 1344 256 l 25,2,-1 + 1344 0 l 25,3,-1 + 64 0 l 25,4,-1 + 64 256 l 25,1,-1 EndSplineSet Validated: 1 EndChar StartChar: Oacute Encoding: 211 211 211 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 95 -256 2048 256 256 +Image2: image/png 95 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pJu:VZ>csF8u:c?j%;QoDu8u!!!!j78?7R6=>BF EndImage2 Fore SplineSet -0 1792 m 25,0,-1 - 512 1792 l 25,1,-1 - 512 256 l 25,2,-1 - 768 256 l 25,3,-1 - 768 1792 l 25,4,-1 - 1024 1792 l 25,5,-1 - 1024 0 l 25,6,-1 - 0 0 l 25,7,-1 - 0 1792 l 25,0,-1 +192 1792 m 25,0,-1 + 704 1792 l 25,1,-1 + 704 256 l 25,2,-1 + 960 256 l 25,3,-1 + 960 1792 l 25,4,-1 + 1216 1792 l 25,5,-1 + 1216 0 l 25,6,-1 + 192 0 l 25,7,-1 + 192 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Ocircumflex Encoding: 212 212 212 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 104 -256 2048 256 256 +Image2: image/png 104 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a /&3J4';Mi7Ci3[4f`e+TGmM@ufLu8F^?>eBB4:K7z8OZBBY!QNJ EndImage2 Fore SplineSet -0 1792 m 25,0,-1 - 512 1792 l 25,1,-1 - 512 768 l 25,2,-1 - 1024 768 l 25,3,-1 - 1024 512 l 25,4,-1 - 512 512 l 25,5,-1 - 512 256 l 25,6,-1 - 1024 256 l 25,7,-1 - 1024 0 l 25,8,-1 - 0 0 l 25,9,-1 - 0 1792 l 25,0,-1 +192 1792 m 25,0,-1 + 704 1792 l 25,1,-1 + 704 768 l 25,2,-1 + 1216 768 l 25,3,-1 + 1216 512 l 25,4,-1 + 704 512 l 25,5,-1 + 704 256 l 25,6,-1 + 1216 256 l 25,7,-1 + 1216 0 l 25,8,-1 + 192 0 l 25,9,-1 + 192 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Otilde Encoding: 213 213 213 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 87 -1024 2048 256 256 +Image2: image/png 87 -448 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%!u-t$Rr 6ua"(D?'YV@0@+u1K<94!!!!j78?7R6=>BF EndImage2 Fore SplineSet -0 768 m 25,0,-1 - 256 768 l 25,1,-1 - 256 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 768 l 25,0,-1 +576 768 m 25,0,-1 + 832 768 l 25,1,-1 + 832 0 l 25,2,-1 + 576 0 l 25,3,-1 + 576 768 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Odieresis Encoding: 214 214 214 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 84 -1024 2048 256 256 +Image2: image/png 84 -448 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr LuL,h)k-s@YSsU1z8OZBBY!QNJ EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 256 256 l 25,1,-1 - 256 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 +576 256 m 25,0,-1 + 832 256 l 25,1,-1 + 832 0 l 25,2,-1 + 576 0 l 25,3,-1 + 576 256 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: multiply Encoding: 215 215 215 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 99 0 2048 256 256 +Image2: image/png 99 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF EndImage2 Fore SplineSet -256 1792 m 25,0,-1 - 768 1792 l 25,1,-1 - 768 256 l 25,2,-1 - 1024 256 l 25,3,-1 - 1024 1792 l 25,4,-1 - 1280 1792 l 25,5,-1 - 1280 0 l 25,6,-1 - 0 0 l 25,7,-1 - 0 256 l 25,8,-1 - 256 256 l 25,9,-1 - 256 1792 l 25,0,-1 +320 1792 m 25,0,-1 + 832 1792 l 25,1,-1 + 832 256 l 25,2,-1 + 1088 256 l 25,3,-1 + 1088 1792 l 25,4,-1 + 1344 1792 l 25,5,-1 + 1344 0 l 25,6,-1 + 64 0 l 25,7,-1 + 64 256 l 25,8,-1 + 320 256 l 25,9,-1 + 320 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Oslash Encoding: 216 216 216 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 101 0 2048 256 256 +Image2: image/png 101 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8Dg*$Z[QM@bLD 'NlQ6EWn#XG+r3WK'iqe%0TB*!8ts()gOU!N;rqY!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,4,-1 - 1024 256 l 25,5,-1 - 1024 512 l 25,6,-1 - -0 512 l 25,7,-1 - 0 768 l 25,8,-1 - 1024 768 l 25,9,-1 - 1024 1792 l 25,0,-1 +1088 1792 m 25,0,-1 + 1344 1792 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,4,-1 + 1088 256 l 25,5,-1 + 1088 512 l 25,6,-1 + 64 512 l 25,7,-1 + 64 768 l 25,8,-1 + 1088 768 l 25,9,-1 + 1088 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Ugrave Encoding: 217 217 217 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 93 0 2048 256 256 +Image2: image/png 93 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,Y:Bi<#?K_r!ro=GQ8Dg*$Z[QM@bLD 'NlPk0IUVQiI*d!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -1024 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - -0 256 l 25,4,-1 - 1024 256 l 25,5,-1 - 1024 1792 l 25,0,-1 +1088 1792 m 25,0,-1 + 1344 1792 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,4,-1 + 1088 256 l 25,5,-1 + 1088 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Uacute Encoding: 218 218 218 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 84 -1024 2048 256 256 +Image2: image/png 84 -448 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr LuL,h)k-s@YSsU1z8OZBBY!QNJ EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 256 256 l 25,1,-1 - 256 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 +576 256 m 25,0,-1 + 832 256 l 25,1,-1 + 832 0 l 25,2,-1 + 576 0 l 25,3,-1 + 576 256 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Ucircumflex Encoding: 219 219 219 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 86 0 2048 256 256 +Image2: image/png 86 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*D&Xb<#?K_r!ro=GQ8sb%RU9&*[X"< _,BF EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: Yacute Encoding: 221 221 221 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 86 0 2048 256 256 +Image2: image/png 86 320 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*D&Xb<#?K_r!ro=GQ8sb%^#f$=scA# _,6*`gl;[=2_b#`BT:ma%`@oq.KBGK!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -331 1280 m 0,0,1 - 256 1280 256 1280 256 1205 c 0,2,3 - 256 1205 256 1205 256 843 c 0,4,5 - 256 768 256 768 331 768 c 24,6,7 - 331 768 331 768 437 768 c 0,8,9 - 512 768 512 768 512 843 c 24,10,11 - 512 843 512 843 512 1205 c 0,12,13 - 512 1280 512 1280 437 1280 c 0,14,15 - 437 1280 437 1280 331 1280 c 0,0,1 -640 588 m 1,16,17 - 586 512 586 512 437 512 c 0,18,19 - 437 512 437 512 331 512 c 0,20,21 - 1 512 1 512 0 843 c 24,22,23 - 0 1190 0 1190 0 1205 c 0,24,25 - 0 1536 0 1536 331 1536 c 24,26,27 - 331 1536 331 1536 437 1536 c 0,28,29 - 591 1536 591 1536 640 1460 c 1,30,31 - 693 1536 693 1536 843 1536 c 0,32,33 - 843 1536 843 1536 1280 1536 c 1,34,35 - 1280 1536 1280 1536 1280 1280 c 9,36,-1 - 843 1280 l 0,37,38 - 769 1280 769 1280 768 1205 c 24,39,40 - 768 986 768 986 768 843 c 0,41,42 - 768 768 768 768 843 768 c 24,43,-1 - 1280 768 l 25,44,45 - 1280 768 1280 768 1280 512 c 1,46,47 - 1280 512 1280 512 843 512 c 0,48,49 - 696 512 696 512 640 588 c 1,16,17 +395 1280 m 0,0,1 + 320 1280 320 1280 320 1205 c 0,2,3 + 320 1205 320 1205 320 843 c 0,4,5 + 320 768 320 768 395 768 c 24,6,7 + 395 768 395 768 501 768 c 0,8,9 + 576 768 576 768 576 843 c 24,10,11 + 576 843 576 843 576 1205 c 0,12,13 + 576 1280 576 1280 501 1280 c 0,14,15 + 501 1280 501 1280 395 1280 c 0,0,1 +704 588 m 1,16,17 + 650 512 650 512 501 512 c 0,18,19 + 501 512 501 512 395 512 c 0,20,21 + 65 512 65 512 64 843 c 24,22,23 + 64 1190 64 1190 64 1205 c 0,24,25 + 64 1536 64 1536 395 1536 c 24,26,27 + 395 1536 395 1536 501 1536 c 0,28,29 + 655 1536 655 1536 704 1460 c 1,30,31 + 757 1536 757 1536 907 1536 c 0,32,33 + 907 1536 907 1536 1344 1536 c 1,34,35 + 1344 1536 1344 1536 1344 1280 c 9,36,-1 + 907 1280 l 0,37,38 + 833 1280 833 1280 832 1205 c 24,39,40 + 832 986 832 986 832 843 c 0,41,42 + 832 768 832 768 907 768 c 24,43,-1 + 1344 768 l 25,44,45 + 1344 768 1344 768 1344 512 c 1,46,47 + 1344 512 1344 512 907 512 c 0,48,49 + 760 512 760 512 704 588 c 1,16,17 EndSplineSet Validated: 1 EndChar StartChar: aacute Encoding: 225 225 225 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 112 0 2048 256 256 +Image2: image/png 112 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8sb%^#f$=sf>C O9>hF14n#N!m44;>Ck%4QpksQJ/$sa,Y0dN8WYn3ei4fJ=9.5"z8OZBBY!QNJ EndImage2 Fore SplineSet -256 1024 m 25,0,-1 - 256 768 l 25,1,-1 - 512 768 l 25,2,-1 - 512 587 l 0,3,4 - 512 512 512 512 587 512 c 24,5,6 - 587 512 587 512 693 512 c 0,7,8 - 768 512 768 512 768 587 c 24,9,10 - 768 587 768 587 768 949 c 0,11,12 - 768 1024 768 1024 693 1024 c 24,13,14 - 693 1024 693 1024 256 1024 c 25,0,-1 -256 1536 m 25,15,-1 - 256 1280 l 25,16,17 - 256 1280 256 1280 693 1280 c 0,18,19 - 768 1280 768 1280 768 1355 c 24,20,21 - 768 1355 768 1355 768 1461 c 0,22,23 - 768 1536 768 1536 693 1536 c 24,24,25 - 693 1536 693 1536 256 1536 c 25,15,-1 -948 1152 m 1,26,27 - 1024 1098 1024 1098 1024 949 c 0,28,29 - 1024 949 1024 949 1024 587 c 0,30,31 - 1024 256 1024 256 693 256 c 24,32,33 - 693 256 693 256 587 256 c 1,34,35 - 256 256 256 256 256 512 c 1,36,-1 - 256 0 l 25,37,-1 - 0 0 l 25,38,-1 - 0 1792 l 25,39,40 - 2 1792 2 1792 693 1792 c 0,41,42 - 1024 1792 1024 1792 1024 1461 c 24,43,44 - 1024 1461 1024 1461 1024 1355 c 0,45,46 - 1024 1202 1024 1202 948 1152 c 1,26,27 +448 1024 m 25,0,-1 + 448 768 l 25,1,-1 + 704 768 l 25,2,-1 + 704 587 l 0,3,4 + 704 512 704 512 779 512 c 24,5,6 + 779 512 779 512 885 512 c 0,7,8 + 960 512 960 512 960 587 c 24,9,10 + 960 587 960 587 960 949 c 0,11,12 + 960 1024 960 1024 885 1024 c 24,13,14 + 885 1024 885 1024 448 1024 c 25,0,-1 +448 1536 m 25,15,-1 + 448 1280 l 25,16,17 + 448 1280 448 1280 885 1280 c 0,18,19 + 960 1280 960 1280 960 1355 c 24,20,21 + 960 1355 960 1355 960 1461 c 0,22,23 + 960 1536 960 1536 885 1536 c 24,24,25 + 885 1536 885 1536 448 1536 c 25,15,-1 +1140 1152 m 1,26,27 + 1216 1098 1216 1098 1216 949 c 0,28,29 + 1216 949 1216 949 1216 587 c 0,30,31 + 1216 256 1216 256 885 256 c 24,32,33 + 885 256 885 256 779 256 c 1,34,35 + 448 256 448 256 448 512 c 1,36,-1 + 448 0 l 25,37,-1 + 192 0 l 25,38,-1 + 192 1792 l 25,39,40 + 194 1792 194 1792 885 1792 c 0,41,42 + 1216 1792 1216 1792 1216 1461 c 24,43,44 + 1216 1461 1216 1461 1216 1355 c 0,45,46 + 1216 1202 1216 1202 1140 1152 c 1,26,27 EndSplineSet Validated: 1 EndChar StartChar: acircumflex Encoding: 226 226 226 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 107 0 2048 256 256 +Image2: image/png 107 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8sb%RU9&*YsiL A-#.hO<+O4685[N0GGY!#1A*s!8SX;'`\49X:>FZOH&o5!!!!j78?7R6=>BF EndImage2 Fore SplineSet -0 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 1024 l 25,2,-1 - 1024 1024 l 25,3,-1 - 1024 1536 l 25,4,-1 - 256 1536 l 25,5,-1 - 256 0 l 25,6,-1 - 0 0 l 25,7,-1 - 0 1792 l 25,0,-1 +64 1792 m 25,0,-1 + 1344 1792 l 25,1,-1 + 1344 1024 l 25,2,-1 + 1088 1024 l 25,3,-1 + 1088 1536 l 25,4,-1 + 320 1536 l 25,5,-1 + 320 0 l 25,6,-1 + 64 0 l 25,7,-1 + 64 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: atilde Encoding: 227 227 227 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 106 0 2048 256 256 +Image2: image/png 106 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8Bu3Ns2`"cP]X (fhd6aopatdkIg/>!Ysc,LC*42o(@Wd/YKm'_qdrA2aJg!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet --0 1280 m 25,0,-1 - 1280 1280 l 25,1,-1 - 1280 1024 l 25,2,-1 - 1024 1024 l 25,3,-1 - 1024 256 l 25,4,-1 - 768 256 l 25,5,-1 - 768 1024 l 25,6,-1 - 512 1024 l 25,7,-1 - 512 256 l 25,8,-1 - 256 256 l 25,9,-1 - 256 1024 l 25,10,-1 - 0 1024 l 25,11,-1 - -0 1280 l 25,0,-1 +64 1280 m 25,0,-1 + 1344 1280 l 25,1,-1 + 1344 1024 l 25,2,-1 + 1088 1024 l 25,3,-1 + 1088 256 l 25,4,-1 + 832 256 l 25,5,-1 + 832 1024 l 25,6,-1 + 576 1024 l 25,7,-1 + 576 256 l 25,8,-1 + 320 256 l 25,9,-1 + 320 1024 l 25,10,-1 + 64 1024 l 25,11,-1 + 64 1280 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: adieresis Encoding: 228 228 228 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 125 0 2048 256 256 +Image2: image/png 125 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$NmS16+:&'JqYsnT:U#R> HVi@4QEAO/ai!o+2:#'fHA[3!]Kabmt6t]^qt2z8OZBBY!QNJ EndImage2 Fore SplineSet --0 1280 m 25,0,-1 - 256 1280 l 25,1,-1 - 256 587 l 0,2,3 - 256 512 256 512 331 512 c 24,4,5 - 331 512 331 512 693 512 c 0,6,7 - 768 512 768 512 768 587 c 24,8,-1 - 768 768 l 25,9,-1 - 1024 768 l 25,10,-1 - 1024 1280 l 25,11,-1 - 1280 1280 l 25,12,-1 - 1280 0 l 25,13,-1 - 1024 0 l 25,14,-1 - 1024 512 l 17,15,16 - 1024 256 1024 256 693 256 c 8,17,18 - 693 256 693 256 331 256 c 0,19,20 - 0 256 0 256 0 587 c 24,21,22 - 0 587 0 587 -0 1280 c 25,0,-1 +64 1280 m 25,0,-1 + 320 1280 l 25,1,-1 + 320 587 l 0,2,3 + 320 512 320 512 395 512 c 24,4,5 + 395 512 395 512 757 512 c 0,6,7 + 832 512 832 512 832 587 c 24,8,-1 + 832 768 l 25,9,-1 + 1088 768 l 25,10,-1 + 1088 1280 l 25,11,-1 + 1344 1280 l 25,12,-1 + 1344 0 l 25,13,-1 + 1088 0 l 25,14,-1 + 1088 512 l 17,15,16 + 1088 256 1088 256 757 256 c 8,17,18 + 757 256 757 256 395 256 c 0,19,20 + 64 256 64 256 64 587 c 24,21,22 + 64 587 64 587 64 1280 c 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: ccedilla Encoding: 231 231 231 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 106 0 2048 256 256 +Image2: image/png 106 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8Bu3Ns2`"cP]X (fhd6ao^TW1,:W#fZ;VV["BF EndImage2 Fore SplineSet -949 1536 m 0,0,1 - 1280 1536 1280 1536 1280 1205 c 24,2,3 - 1280 1205 1280 1205 1280 768 c 0,4,5 - 1280 512 1280 512 1024 512 c 9,6,7 - 1024 512 1024 512 1024 256 c 25,8,9 - 1024 256 1024 256 1280 256 c 1,10,-1 - 1280 0 l 25,11,-1 - 768 0 l 25,12,13 - 768 0 768 0 768 512 c 17,14,15 - 768 768 768 768 1024 768 c 8,16,17 - 1024 768 1024 768 1024 1205 c 0,18,19 - 1024 1280 1024 1280 949 1280 c 24,20,21 - 949 1280 949 1280 331 1280 c 0,22,23 - 256 1280 256 1280 256 1205 c 24,24,25 - 256 1205 256 1205 256 768 c 17,26,27 - 512 768 512 768 512 512 c 8,28,29 - 512 512 512 512 512 0 c 25,30,-1 - 0 0 l 25,31,-1 - -0 256 l 25,32,-1 - 256 256 l 25,33,34 - 256 256 256 256 256 512 c 17,35,36 - 0 512 0 512 0 768 c 8,37,38 - 0 768 0 768 0 1205 c 0,39,40 - 0 1536 0 1536 331 1536 c 24,41,42 - 331 1536 331 1536 949 1536 c 0,0,1 +1013 1536 m 0,0,1 + 1344 1536 1344 1536 1344 1205 c 24,2,3 + 1344 1205 1344 1205 1344 768 c 0,4,5 + 1344 512 1344 512 1088 512 c 9,6,7 + 1088 512 1088 512 1088 256 c 25,8,9 + 1088 256 1088 256 1344 256 c 1,10,-1 + 1344 0 l 25,11,-1 + 832 0 l 25,12,13 + 832 0 832 0 832 512 c 17,14,15 + 832 768 832 768 1088 768 c 8,16,17 + 1088 768 1088 768 1088 1205 c 0,18,19 + 1088 1280 1088 1280 1013 1280 c 24,20,21 + 1013 1280 1013 1280 395 1280 c 0,22,23 + 320 1280 320 1280 320 1205 c 24,24,25 + 320 1205 320 1205 320 768 c 17,26,27 + 576 768 576 768 576 512 c 8,28,29 + 576 512 576 512 576 0 c 25,30,-1 + 64 0 l 25,31,-1 + 64 256 l 25,32,-1 + 320 256 l 25,33,34 + 320 256 320 256 320 512 c 17,35,36 + 64 512 64 512 64 768 c 8,37,38 + 64 768 64 768 64 1205 c 0,39,40 + 64 1536 64 1536 395 1536 c 24,41,42 + 395 1536 395 1536 1013 1536 c 0,0,1 EndSplineSet Validated: 1 EndChar StartChar: edieresis Encoding: 235 235 235 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 112 0 2048 256 256 +Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8CJNffG9N3T?l ":F-GKEYlga93>F[h6L\OCD`h?oPlCA"s>[+Qs"0N05+aQb:>%z8OZBBY!QNJ EndImage2 Fore SplineSet -1024 949 m 0,0,1 - 1024 1024 1024 1024 949 1024 c 24,2,3 - 949 1024 949 1024 331 1024 c 0,4,5 - 256 1024 256 1024 256 949 c 24,6,7 - 256 949 256 949 256 331 c 0,8,9 - 256 256 256 256 331 256 c 24,10,11 - 331 256 331 256 949 256 c 0,12,13 - 1024 256 1024 256 1024 331 c 24,14,15 - 1024 331 1024 331 1024 949 c 0,0,1 -768 1792 m 25,16,-1 - 768 1536 l 25,17,-1 - 331 1536 l 0,18,19 - 256 1536 256 1536 256 1461 c 24,20,21 - 256 1461 256 1461 256 1355 c 0,22,23 - 256 1280 256 1280 331 1280 c 24,24,-1 - 949 1280 l 0,25,26 - 1280 1280 1280 1280 1280 949 c 24,27,28 - 1280 949 1280 949 1280 331 c 0,29,30 - 1280 0 1280 0 949 0 c 24,31,32 - 949 0 949 0 331 -0 c 0,33,34 - 0 0 0 0 0 331 c 24,35,36 - 0 331 0 331 0 949 c 17,37,38 - 0 1280 0 1280 256 1280 c 9,39,-1 - 0 1280 l 25,40,41 - 0 1282 0 1282 0 1461 c 0,42,43 - 0 1792 0 1792 331 1792 c 24,44,45 - 331 1792 331 1792 768 1792 c 25,16,-1 +1088 949 m 0,0,1 + 1088 1024 1088 1024 1013 1024 c 24,2,3 + 1013 1024 1013 1024 395 1024 c 0,4,5 + 320 1024 320 1024 320 949 c 24,6,7 + 320 949 320 949 320 331 c 0,8,9 + 320 256 320 256 395 256 c 24,10,11 + 395 256 395 256 1013 256 c 0,12,13 + 1088 256 1088 256 1088 331 c 24,14,15 + 1088 331 1088 331 1088 949 c 0,0,1 +832 1792 m 25,16,-1 + 832 1536 l 25,17,-1 + 395 1536 l 0,18,19 + 320 1536 320 1536 320 1461 c 24,20,21 + 320 1461 320 1461 320 1355 c 0,22,23 + 320 1280 320 1280 395 1280 c 24,24,-1 + 1013 1280 l 0,25,26 + 1344 1280 1344 1280 1344 949 c 24,27,28 + 1344 949 1344 949 1344 331 c 0,29,30 + 1344 0 1344 0 1013 0 c 24,31,32 + 1013 0 1013 0 395 0 c 0,33,34 + 64 0 64 0 64 331 c 24,35,36 + 64 331 64 331 64 949 c 17,37,38 + 64 1280 64 1280 320 1280 c 9,39,-1 + 64 1280 l 25,40,41 + 64 1282 64 1282 64 1461 c 0,42,43 + 64 1792 64 1792 395 1792 c 24,44,45 + 395 1792 395 1792 832 1792 c 25,16,-1 EndSplineSet Validated: 1 EndChar StartChar: igrave Encoding: 236 236 236 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 110 0 2048 256 256 +Image2: image/png 110 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns3"!@&g6 Qij+G2)0Xb6+.ob-jl%rf[rm]]$]?X#S`rU(BEC4(C_Jt"T8<#!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -1024 1205 m 0,0,1 - 1024 1280 1024 1280 949 1280 c 24,2,3 - 949 1280 949 1280 843 1280 c 0,4,5 - 768 1280 768 1280 768 1205 c 24,6,7 - 768 1205 768 1205 768 843 c 0,8,9 - 768 768 768 768 843 768 c 24,10,11 - 843 768 843 768 949 768 c 0,12,13 - 1024 768 1024 768 1024 843 c 24,14,15 - 1024 843 1024 843 1024 1205 c 0,0,1 -331 1280 m 0,16,17 - 256 1280 256 1280 256 1205 c 24,18,19 - 256 1205 256 1205 256 843 c 0,20,21 - 256 768 256 768 331 768 c 24,22,23 - 331 768 331 768 437 768 c 0,24,25 - 512 768 512 768 512 843 c 24,26,27 - 512 843 512 843 512 1205 c 0,28,29 - 512 1280 512 1280 437 1280 c 24,30,31 - 437 1280 437 1280 331 1280 c 0,16,17 -640 588 m 1,32,33 - 590 512 590 512 437 512 c 0,34,35 - 331 512 331 512 331 512 c 0,36,37 - 0 512 0 512 0 843 c 0,38,39 - 0 1205 0 1205 0 1205 c 0,40,41 - 0 1536 0 1536 331 1536 c 24,42,43 - 437 1536 437 1536 437 1536 c 0,44,45 - 591 1536 591 1536 640 1460 c 1,46,47 - 689 1536 689 1536 843 1536 c 0,48,49 - 949 1536 949 1536 949 1536 c 0,50,51 - 1280 1536 1280 1536 1280 1205 c 24,52,53 - 1280 843 1280 843 1280 843 c 0,54,55 - 1280 512 1280 512 949 512 c 0,56,57 - 843 512 843 512 843 512 c 0,58,59 - 690 512 690 512 640 588 c 1,32,33 +1088 1205 m 0,0,1 + 1088 1280 1088 1280 1013 1280 c 24,2,3 + 1013 1280 1013 1280 907 1280 c 0,4,5 + 832 1280 832 1280 832 1205 c 24,6,7 + 832 1205 832 1205 832 843 c 0,8,9 + 832 768 832 768 907 768 c 24,10,11 + 907 768 907 768 1013 768 c 0,12,13 + 1088 768 1088 768 1088 843 c 24,14,15 + 1088 843 1088 843 1088 1205 c 0,0,1 +395 1280 m 0,16,17 + 320 1280 320 1280 320 1205 c 24,18,19 + 320 1205 320 1205 320 843 c 0,20,21 + 320 768 320 768 395 768 c 24,22,23 + 395 768 395 768 501 768 c 0,24,25 + 576 768 576 768 576 843 c 24,26,27 + 576 843 576 843 576 1205 c 0,28,29 + 576 1280 576 1280 501 1280 c 24,30,31 + 501 1280 501 1280 395 1280 c 0,16,17 +704 588 m 1,32,33 + 654 512 654 512 501 512 c 0,34,35 + 395 512 395 512 395 512 c 0,36,37 + 64 512 64 512 64 843 c 0,38,39 + 64 1205 64 1205 64 1205 c 0,40,41 + 64 1536 64 1536 395 1536 c 24,42,43 + 501 1536 501 1536 501 1536 c 0,44,45 + 655 1536 655 1536 704 1460 c 1,46,47 + 753 1536 753 1536 907 1536 c 0,48,49 + 1013 1536 1013 1536 1013 1536 c 0,50,51 + 1344 1536 1344 1536 1344 1205 c 24,52,53 + 1344 843 1344 843 1344 843 c 0,54,55 + 1344 512 1344 512 1013 512 c 0,56,57 + 907 512 907 512 907 512 c 0,58,59 + 754 512 754 512 704 588 c 1,32,33 EndSplineSet Validated: 1 EndChar StartChar: iacute Encoding: 237 237 237 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 121 0 2048 256 256 +Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$:'h7-+:*&es3Ke[NKS6' ,.kcg`.0^a7?mjBF EndImage2 Fore SplineSet --0 512 m 25,0,-1 - 1280 512 l 25,1,-1 - 1280 256 l 25,2,-1 - 0 256 l 25,3,-1 - -0 512 l 25,0,-1 -0 1024 m 25,4,-1 - 1280 1024 l 25,5,-1 - 1280 768 l 25,6,-1 - 0 768 l 25,7,-1 - 0 1024 l 25,4,-1 -0 1536 m 25,8,-1 - 1280 1536 l 25,9,-1 - 1280 1280 l 25,10,-1 - -0 1280 l 25,11,-1 - 0 1536 l 25,8,-1 +64 512 m 25,0,-1 + 1344 512 l 25,1,-1 + 1344 256 l 25,2,-1 + 64 256 l 25,3,-1 + 64 512 l 25,0,-1 +64 1024 m 25,4,-1 + 1344 1024 l 25,5,-1 + 1344 768 l 25,6,-1 + 64 768 l 25,7,-1 + 64 1024 l 25,4,-1 +64 1536 m 25,8,-1 + 1344 1536 l 25,9,-1 + 1344 1280 l 25,10,-1 + 64 1280 l 25,11,-1 + 64 1536 l 25,8,-1 EndSplineSet Validated: 1 EndChar StartChar: ntilde Encoding: 241 241 241 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 114 0 2048 256 256 +Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HNZ $;a-Q3$<&T!ong4J?b4F?m'+d>QHb=+Hm)B!<>"K'`g-2+2\'Y!!#SZ:.26O@"J@Y EndImage2 Fore SplineSet -0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - 0 256 l 25,0,-1 -512 1792 m 25,4,-1 - 768 1792 l 25,5,-1 - 768 1280 l 25,6,-1 - 1280 1280 l 25,7,-1 - 1280 1024 l 25,8,-1 - 768 1024 l 25,9,-1 - 768 512 l 25,10,-1 - 512 512 l 25,11,-1 - 512 1024 l 25,12,-1 - -0 1024 l 25,13,-1 - -0 1280 l 25,14,-1 - 512 1280 l 25,15,-1 - 512 1792 l 25,4,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +576 1792 m 25,4,-1 + 832 1792 l 25,5,-1 + 832 1280 l 25,6,-1 + 1344 1280 l 25,7,-1 + 1344 1024 l 25,8,-1 + 832 1024 l 25,9,-1 + 832 512 l 25,10,-1 + 576 512 l 25,11,-1 + 576 1024 l 25,12,-1 + 64 1024 l 25,13,-1 + 64 1280 l 25,14,-1 + 576 1280 l 25,15,-1 + 576 1792 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: ograve Encoding: 242 242 242 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 113 0 2048 256 256 +Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8C%,9n7D"pQE9 !Vd?`J[FH9"BL%K&R5>h748LNMEj!,J@pEk9k9ju!.ec!#8A0)mJm4e!(fUS7'8jaJcGcN EndImage2 Fore SplineSet --0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - -0 256 l 25,0,-1 -181 1792 m 25,4,-1 - 1280 693 l 25,5,-1 - 1280 512 l 25,6,-1 - 1099 512 l 25,7,-1 - 0 1611 l 25,8,-1 - 0 1792 l 25,9,-1 - 181 1792 l 25,4,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +245 1792 m 25,4,-1 + 1344 693 l 25,5,-1 + 1344 512 l 25,6,-1 + 1163 512 l 25,7,-1 + 64 1611 l 25,8,-1 + 64 1792 l 25,9,-1 + 245 1792 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: oacute Encoding: 243 243 243 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 116 0 2048 256 256 +Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?L$:.Z&u+:&>Ss5s_"%Pf=X LK3]!2'?-+d&:QLk_3SmM6'=e:S`Poj.G;"9I[85$/QR]hLZRG"t\K.z8OZBBY!QNJ EndImage2 Fore SplineSet --0 256 m 25,0,-1 - 1280 256 l 25,1,-1 - 1280 0 l 25,2,-1 - 0 0 l 25,3,-1 - -0 256 l 25,0,-1 -0 693 m 25,4,-1 - 1099 1792 l 25,5,-1 - 1280 1792 l 25,6,-1 - 1280 1611 l 25,7,-1 - 181 512 l 25,8,-1 - -0 512 l 25,9,-1 - 0 693 l 25,4,-1 +64 256 m 25,0,-1 + 1344 256 l 25,1,-1 + 1344 0 l 25,2,-1 + 64 0 l 25,3,-1 + 64 256 l 25,0,-1 +64 693 m 25,4,-1 + 1163 1792 l 25,5,-1 + 1344 1792 l 25,6,-1 + 1344 1611 l 25,7,-1 + 245 512 l 25,8,-1 + 64 512 l 25,9,-1 + 64 693 l 25,4,-1 EndSplineSet Validated: 1 EndChar StartChar: ocircumflex Encoding: 244 244 244 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 106 -512 2048 256 256 +Image2: image/png 106 -192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8D_*$Z[Q1)J/h .f`.m$q")!=+HtZ.Y+2mh+8FjcqU6>!%hZBF EndImage2 Fore SplineSet -331 0 m 0,0,1 - 0 0 0 0 0 331 c 24,2,3 - 0 331 0 331 0 768 c 25,4,-1 - 256 768 l 25,5,-1 - 256 331 l 0,6,7 - 256 256 256 256 331 256 c 24,8,9 - 331 256 331 256 437 256 c 0,10,11 - 512 256 512 256 512 331 c 24,12,-1 - 512 1792 l 25,13,-1 - 768 1792 l 25,14,15 - 768 1792 768 1792 768 331 c 0,16,17 - 768 0 768 0 437 0 c 24,18,19 - 437 0 437 0 331 0 c 0,0,1 +651 0 m 0,0,1 + 320 0 320 0 320 331 c 24,2,3 + 320 331 320 331 320 768 c 25,4,-1 + 576 768 l 25,5,-1 + 576 331 l 0,6,7 + 576 256 576 256 651 256 c 24,8,9 + 651 256 651 256 757 256 c 0,10,11 + 832 256 832 256 832 331 c 24,12,-1 + 832 1792 l 25,13,-1 + 1088 1792 l 25,14,15 + 1088 1792 1088 1792 1088 331 c 0,16,17 + 1088 0 1088 0 757 0 c 24,18,19 + 757 0 757 0 651 0 c 0,0,1 EndSplineSet Validated: 1 EndChar StartChar: odieresis Encoding: 246 246 246 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 104 0 2048 256 256 +Image2: image/png 104 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns3&!@&g6 F7*dd,#*D0*"!4IN'+.>uci6z8OZBBY!QNJ EndImage2 Fore SplineSet -0 437 m 0,0,1 - 0 768 0 768 331 768 c 24,2,-1 - 949 768 l 0,3,4 - 1024 768 1024 768 1024 843 c 24,5,-1 - 1024 1024 l 25,6,-1 - 1280 1024 l 25,7,8 - 1280 1024 1280 1024 1280 843 c 0,9,10 - 1280 512 1280 512 949 512 c 24,11,-1 - 331 512 l 0,12,13 - 256 512 256 512 256 437 c 24,14,-1 - 256 256 l 25,15,-1 - 0 256 l 25,16,17 - 0 256 0 256 0 437 c 0,0,1 -0 1205 m 0,18,19 - 0 1536 0 1536 331 1536 c 24,20,-1 - 949 1536 l 0,21,22 - 1024 1536 1024 1536 1024 1611 c 24,23,-1 - 1024 1792 l 25,24,-1 - 1280 1792 l 25,25,26 - 1280 1792 1280 1792 1280 1611 c 0,27,28 - 1280 1280 1280 1280 949 1280 c 24,29,-1 - 331 1280 l 0,30,31 - 256 1280 256 1280 256 1205 c 24,32,-1 - 256 1024 l 25,33,-1 - -0 1024 l 25,34,35 - -0 1024 -0 1024 0 1205 c 0,18,19 +64 437 m 0,0,1 + 64 768 64 768 395 768 c 24,2,-1 + 1013 768 l 0,3,4 + 1088 768 1088 768 1088 843 c 24,5,-1 + 1088 1024 l 25,6,-1 + 1344 1024 l 25,7,8 + 1344 1024 1344 1024 1344 843 c 0,9,10 + 1344 512 1344 512 1013 512 c 24,11,-1 + 395 512 l 0,12,13 + 320 512 320 512 320 437 c 24,14,-1 + 320 256 l 25,15,-1 + 64 256 l 25,16,17 + 64 256 64 256 64 437 c 0,0,1 +64 1205 m 0,18,19 + 64 1536 64 1536 395 1536 c 24,20,-1 + 1013 1536 l 0,21,22 + 1088 1536 1088 1536 1088 1611 c 24,23,-1 + 1088 1792 l 25,24,-1 + 1344 1792 l 25,25,26 + 1344 1792 1344 1792 1344 1611 c 0,27,28 + 1344 1280 1344 1280 1013 1280 c 24,29,-1 + 395 1280 l 0,30,31 + 320 1280 320 1280 320 1205 c 24,32,-1 + 320 1024 l 25,33,-1 + 64 1024 l 25,34,35 + 64 1024 64 1024 64 1205 c 0,18,19 EndSplineSet Validated: 1 EndChar StartChar: oslash Encoding: 248 248 248 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 115 0 2048 256 256 +Image2: image/png 115 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8CJNffG9N3T?l ":E!T!@^DqO9Hm0OoPN)8WXbs/d[V!#_:_2@:CT5fEr&3)!!!!j78?7R6=>BF EndImage2 Fore SplineSet -693 1536 m 0,0,1 - 693 1536 693 1536 331 1536 c 0,2,3 - 256 1536 256 1536 256 1461 c 24,4,5 - 256 1461 256 1461 256 1355 c 0,6,7 - 256 1280 256 1280 331 1280 c 24,8,9 - 331 1280 331 1280 693 1280 c 0,10,11 - 768 1280 768 1280 768 1355 c 24,12,13 - 768 1355 768 1355 768 1461 c 0,14,15 - 768 1536 768 1536 693 1536 c 0,0,1 -693 1792 m 0,16,17 - 1024 1792 1024 1792 1024 1461 c 24,18,19 - 1024 1461 1024 1461 1024 1355 c 0,20,21 - 1024 1024 1024 1024 693 1024 c 24,22,23 - 693 1024 693 1024 331 1024 c 0,24,25 - 0 1024 0 1024 0 1355 c 24,26,27 - 0 1355 0 1355 0 1461 c 0,28,29 - 0 1792 0 1792 331 1792 c 24,30,31 - 331 1792 331 1792 693 1792 c 0,16,17 +885 1536 m 0,0,1 + 885 1536 885 1536 523 1536 c 0,2,3 + 448 1536 448 1536 448 1461 c 24,4,5 + 448 1461 448 1461 448 1355 c 0,6,7 + 448 1280 448 1280 523 1280 c 24,8,9 + 523 1280 523 1280 885 1280 c 0,10,11 + 960 1280 960 1280 960 1355 c 24,12,13 + 960 1355 960 1355 960 1461 c 0,14,15 + 960 1536 960 1536 885 1536 c 0,0,1 +885 1792 m 0,16,17 + 1216 1792 1216 1792 1216 1461 c 24,18,19 + 1216 1461 1216 1461 1216 1355 c 0,20,21 + 1216 1024 1216 1024 885 1024 c 24,22,23 + 885 1024 885 1024 523 1024 c 0,24,25 + 192 1024 192 1024 192 1355 c 24,26,27 + 192 1355 192 1355 192 1461 c 0,28,29 + 192 1792 192 1792 523 1792 c 24,30,31 + 523 1792 523 1792 885 1792 c 0,16,17 EndSplineSet Validated: 1 EndChar StartChar: ugrave Encoding: 249 249 249 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 116 -256 2048 256 256 +Image2: image/png 116 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8Bu3Ns4f$5aWu )*f#ZJ5&:p5\>W_K,#N@':B;-^]G]F!*oXM$8hk(_+"M,dDQJ+QNPW^z8OZBBY!QNJ EndImage2 Fore SplineSet -256 1280 m 25,0,-1 - 768 1280 l 25,1,-1 - 768 1024 l 25,2,-1 - 1024 1024 l 25,3,-1 - 1024 768 l 25,4,-1 - 768 768 l 25,5,-1 - 768 512 l 25,6,-1 - 256 512 l 25,7,-1 - 256 768 l 25,8,-1 - 0 768 l 25,9,-1 - 0 1024 l 25,10,-1 - 256 1024 l 25,11,-1 - 256 1280 l 25,0,-1 +448 1280 m 25,0,-1 + 960 1280 l 25,1,-1 + 960 1024 l 25,2,-1 + 1216 1024 l 25,3,-1 + 1216 768 l 25,4,-1 + 960 768 l 25,5,-1 + 960 512 l 25,6,-1 + 448 512 l 25,7,-1 + 448 768 l 25,8,-1 + 192 768 l 25,9,-1 + 192 1024 l 25,10,-1 + 448 1024 l 25,11,-1 + 448 1280 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: uacute Encoding: 250 250 250 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 97 -512 2048 256 256 +Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns24'ehBu @^QY_"YR:$'k#Q%'I9UW!%-V/$md\(4TGH^!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -0 1024 m 29,0,-1 - 256 1024 l 25,1,-1 - 256 768 l 25,2,-1 - 0 768 l 25,3,-1 - 0 1024 l 29,0,-1 +576 1024 m 29,0,-1 + 832 1024 l 25,1,-1 + 832 768 l 25,2,-1 + 576 768 l 25,3,-1 + 576 1024 l 29,0,-1 EndSplineSet Validated: 1 EndChar StartChar: ucircumflex Encoding: 251 251 251 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 117 0 2048 256 256 +Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+FNffG9`ah?c "'5Jc7@&J'AqDaVd7hVN@oGeJ"H^;>;m=pc1(e=(/kM-+!-+VE$NJqlp](9o!(fUS7'8jaJcGcN EndImage2 Fore SplineSet -512 1792 m 25,0,-1 - 1280 1792 l 25,1,-1 - 1280 1536 l 25,2,-1 - 768 1536 l 25,3,-1 - 768 587 l 0,4,5 - 768 256 768 256 437 256 c 24,6,7 - 437 256 437 256 331 256 c 0,8,9 - 0 256 0 256 0 587 c 16,10,11 - 0 587 0 587 0 1024 c 9,12,-1 - 256 1024 l 25,13,-1 - 256 587 l 0,14,15 - 256 512 256 512 331 512 c 24,16,17 - 331 512 331 512 437 512 c 0,18,19 - 512 512 512 512 512 587 c 24,20,-1 - 512 1792 l 25,0,-1 +576 1792 m 25,0,-1 + 1344 1792 l 25,1,-1 + 1344 1536 l 25,2,-1 + 832 1536 l 25,3,-1 + 832 587 l 0,4,5 + 832 256 832 256 501 256 c 24,6,7 + 501 256 501 256 395 256 c 0,8,9 + 64 256 64 256 64 587 c 16,10,11 + 64 587 64 587 64 1024 c 9,12,-1 + 320 1024 l 25,13,-1 + 320 587 l 0,14,15 + 320 512 320 512 395 512 c 24,16,17 + 395 512 395 512 501 512 c 0,18,19 + 576 512 576 512 576 587 c 24,20,-1 + 576 1792 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: udieresis Encoding: 252 252 252 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 111 0 2048 256 256 +Image2: image/png 111 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8Bu3Ns2`"cP]X E%A0G"uZK-!Q'eS+SD[`TG7SE0ER5g])gH$#S-plN=l21\-JE%!!!!j78?7R6=>BF EndImage2 Fore SplineSet --0 1280 m 25,0,1 - -0 1280 -0 1280 693 1280 c 0,2,3 - 1024 1280 1024 1280 1024 949 c 24,4,5 - 1024 949 1024 949 1024 256 c 25,6,-1 - 768 256 l 25,7,-1 - 768 949 l 0,8,9 - 768 1024 768 1024 693 1024 c 24,10,11 - 693 1024 693 1024 256 1024 c 25,12,-1 - 256 256 l 25,13,-1 - -0 256 l 25,14,-1 - -0 1280 l 25,0,1 +192 1280 m 25,0,1 + 192 1280 192 1280 885 1280 c 0,2,3 + 1216 1280 1216 1280 1216 949 c 24,4,5 + 1216 949 1216 949 1216 256 c 25,6,-1 + 960 256 l 25,7,-1 + 960 949 l 0,8,9 + 960 1024 960 1024 885 1024 c 24,10,11 + 885 1024 885 1024 448 1024 c 25,12,-1 + 448 256 l 25,13,-1 + 192 256 l 25,14,-1 + 192 1280 l 25,0,1 EndSplineSet Validated: 1 EndChar StartChar: yacute Encoding: 253 253 253 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 110 0 2048 256 256 +Image2: image/png 110 448 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?L$N'RdN0FYgqo`&:TWj&8\ <%ndLEXLID6LpLu+!mRNL72;b6E@ (`=3"9Eo$3$(=,i!k922m=dV+a8c2MpBh@PrMsB-!!!!j78?7R6=>BF EndImage2 Fore SplineSet -0 1280 m 25,0,-1 - 768 1280 l 25,1,-1 - 768 256 l 25,2,-1 - 0 256 l 25,3,-1 - 0 1280 l 25,0,-1 +320 1280 m 25,0,-1 + 1088 1280 l 25,1,-1 + 1088 256 l 25,2,-1 + 320 256 l 25,3,-1 + 320 1280 l 25,0,-1 EndSplineSet Validated: 1 EndChar StartChar: ydieresis Encoding: 255 255 255 -Width: 1536 -VWidth: 2048 +Width: 1408 Flags: MW LayerCount: 3 Back -Image2: image/png 79 0 2048 256 256 +Image2: image/png 79 1472 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(.gn[<#?K_r!ro=GQ8Bu3O%$&:]LJ7 D?LB^-QJHQ!!!!j78?7R6=>BF EndImage2 From 725b411c1ca6b3db476af19a55ce6784c16ee876 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 24 Nov 2022 15:04:19 +0100 Subject: [PATCH 221/314] [#163] 88-sio: Fixed using interrupts vectors from settings --- .../device/mits88dcdd/drive/Drive.java | 2 +- .../plugins/device/mits88sio/SioUnit.java | 2 +- .../plugins/device/mits88sio/UART.java | 30 +++-- .../mits88sio/settings/SioUnitSettings.java | 21 ++++ .../plugins/device/mits88sio/UARTTest.java | 114 ++++++++++++++---- 5 files changed, 134 insertions(+), 35 deletions(-) diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java index 49a91dcd6..08faac254 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java @@ -224,7 +224,7 @@ public byte getPort2status() { if (((~port1status) & (~MASK_HEAD_LOAD)) != 0) { return port2status; } else { - return (byte)0; + return (byte)0xFF; // When head is not loaded, real hardware returns 0xFF } }); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java index 768ced6c4..c05a67338 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java @@ -46,7 +46,7 @@ public class SioUnit implements AutoCloseable { public SioUnit(SioUnitSettings settings, Context8080 cpu) { this.settings = Objects.requireNonNull(settings); this.cpu = Objects.requireNonNull(cpu); - this.uart = new UART(cpu); + this.uart = new UART(cpu, settings); this.controlChannel = new ControlChannel(uart); this.dataChannel = new DataChannel(settings, uart); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java index 60feb6750..3db358baf 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java @@ -21,14 +21,12 @@ import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.cpu.intel8080.api.Context8080; +import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; import net.jcip.annotations.ThreadSafe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Queue; +import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -54,6 +52,17 @@ public class UART { private final static int SEND_DATA_READY = 2; private final static int RECEIVE_DATA_READY = 1; + private final static Map RST_MAP = Map.of( + 0, (byte) 0xC7, + 1, (byte) 0xCF, + 2, (byte) 0xD7, + 3, (byte) 0xDF, + 4, (byte) 0xE7, + 5, (byte) 0xEF, + 6, (byte) 0xF7, + 7, (byte) 0xFF + ); + private final Queue bufferFromDevice = new ConcurrentLinkedQueue<>(); private final Lock bufferAndStatusLock = new ReentrantLock(); @@ -62,11 +71,13 @@ public class UART { private volatile boolean inputInterruptEnabled; private volatile boolean outputInterruptEnabled; private final Context8080 cpu; + private final SioUnitSettings settings; private final List observers = new ArrayList<>(); - public UART(Context8080 cpu) { + public UART(Context8080 cpu, SioUnitSettings settings) { this.cpu = Objects.requireNonNull(cpu); + this.settings = Objects.requireNonNull(settings); } public void setDevice(DeviceContext device) { @@ -112,10 +123,10 @@ public void setStatus(byte value) { } finally { bufferAndStatusLock.unlock(); if (!isEmpty && inputInterruptEnabled && cpu.isInterruptSupported()) { - cpu.signalInterrupt(new byte[] { (byte)0xFF }); // RST 7 (in Z80 RST 0x38) + cpu.signalInterrupt(new byte[]{RST_MAP.get(settings.getInputInterruptVector())}); } if (outputInterruptEnabled && cpu.isInterruptSupported()) { - cpu.signalInterrupt(new byte[] { (byte)0xFF }); // RST 7 (in Z80 RST 0x38) + cpu.signalInterrupt(new byte[]{RST_MAP.get(settings.getOutputInterruptVector())}); } notifyStatusChanged(newStatus); @@ -139,7 +150,7 @@ public void receiveFromDevice(byte data) { if (wasEmpty) { if (inputInterruptEnabled && cpu.isInterruptSupported()) { - cpu.signalInterrupt(new byte[] { (byte)0xFF }); // RST 7 (in Z80 RST 0x38) + cpu.signalInterrupt(new byte[]{RST_MAP.get(settings.getInputInterruptVector())}); } notifyNewData(data); } @@ -151,6 +162,9 @@ public void sendToDevice(byte data) { DeviceContext tmpDevice = device; if (tmpDevice != null) { tmpDevice.writeData(data); + if (outputInterruptEnabled && cpu.isInterruptSupported()) { + cpu.signalInterrupt(new byte[]{RST_MAP.get(settings.getOutputInterruptVector())}); + } } } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java index f78dd8956..99679adbb 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java @@ -20,6 +20,8 @@ import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.settings.BasicSettings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Arrays; import java.util.List; @@ -31,6 +33,8 @@ * Settings of one SIO unit */ public class SioUnitSettings { + private final static Logger LOGGER = LoggerFactory.getLogger(SioUnitSettings.class); + private final static String KEY_STATUS_PORTS = "statusPorts"; private final static String KEY_DATA_PORTS = "dataPorts"; private final static String KEY_CLEAR_INPUT_BIT8 = "clearInputBit8"; @@ -69,6 +73,17 @@ public SioUnitSettings(BasicSettings settings) { this.inputToUpperCase = settings.getBoolean(KEY_INPUT_TO_UPPER_CASE, false); this.mapDeleteChar = settings.getString(KEY_MAP_DELETE_CHAR).map(MAP_CHAR::valueOf).orElse(MAP_CHAR.UNCHANGED); this.mapBackspaceChar = settings.getString(KEY_MAP_BACKSPACE_CHAR).map(MAP_CHAR::valueOf).orElse(MAP_CHAR.UNCHANGED); + this.inputInterruptVector = settings.getInt(KEY_INPUT_INTERRUPT_VECTOR).orElse(7); + this.outputInterruptVector = settings.getInt(KEY_OUTPUT_INTERRUPT_VECTOR).orElse(7); + + if (inputInterruptVector < 0 || inputInterruptVector > 7) { + LOGGER.error("Invalid inputInterruptVector setting value: " + inputInterruptVector + "; setting to default (7)"); + this.inputInterruptVector = 7; + } + if (outputInterruptVector < 0 || outputInterruptVector > 7) { + LOGGER.error("Invalid outputInterruptVector setting value: " + outputInterruptVector + "; setting to default (7)"); + this.outputInterruptVector = 7; + } RadixUtils r = RadixUtils.getInstance(); this.statusPorts = Arrays @@ -175,6 +190,9 @@ public int getInputInterruptVector() { } public void setInputInterruptVector(int vector) { + if (vector < 0 || vector > 7) { + throw new IllegalArgumentException("Allowed value for interrupt vector is 0-7"); + } this.inputInterruptVector = vector; settings.setInt(KEY_INPUT_INTERRUPT_VECTOR, vector); notifySettingsChanged(); @@ -185,6 +203,9 @@ public int getOutputInterruptVector() { } public void setOutputInterruptVector(int vector) { + if (vector < 0 || vector > 7) { + throw new IllegalArgumentException("Allowed value for interrupt vector is 0-7"); + } this.outputInterruptVector = vector; settings.setInt(KEY_OUTPUT_INTERRUPT_VECTOR, vector); notifySettingsChanged(); diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java index 02d123d31..7aa7581ac 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java @@ -19,68 +19,132 @@ package net.emustudio.plugins.device.mits88sio; import net.emustudio.plugins.cpu.intel8080.api.Context8080; +import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; +import org.junit.Before; import org.junit.Test; -import static org.easymock.EasyMock.mock; +import static org.easymock.EasyMock.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; public class UARTTest { + private SioUnitSettings settings; + private Context8080 context; + + @Before + public void setup() { + this.settings = mock(SioUnitSettings.class); + this.context = mock(Context8080.class); + } @Test public void testGetDeviceIdReturnsNotNullIfDeviceIsNotAttached() { - assertNotNull(new UART(mock(Context8080.class)).getDeviceId()); + assertNotNull(new UART(context, settings).getDeviceId()); } @Test public void testSetNullDeviceDoesNotThrow() { - new UART(mock(Context8080.class)).setDevice(null); + new UART(context, settings).setDevice(null); } @Test public void testInitialStatusIs0x02() { - assertEquals(2, new UART(mock(Context8080.class)).readStatus()); + assertEquals(2, new UART(context, settings).readStatus()); } @Test public void testResetOnEmptyBufferSetStatusTo0x02() { - UART UART = new UART(mock(Context8080.class)); - UART.reset(false); - assertEquals(0x02, UART.readStatus()); + UART uart = new UART(context, settings); + uart.reset(false); + assertEquals(0x02, uart.readStatus()); } @Test public void testWriteToStatus0x03OnEmptyBufferSetStatusTo0x02() { - UART UART = new UART(mock(Context8080.class)); - UART.setStatus((byte) 0x03); - assertEquals(0x02, UART.readStatus()); + UART uart = new UART(context, settings); + uart.setStatus((byte) 0x03); + assertEquals(0x02, uart.readStatus()); } @Test public void testWriteFromDeviceSetsInputDeviceReady() { - UART UART = new UART(mock(Context8080.class)); - UART.receiveFromDevice((byte) 5); - assertEquals(1, UART.readStatus() & 0x01); + UART uart = new UART(context, settings); + uart.receiveFromDevice((byte) 5); + assertEquals(1, uart.readStatus() & 0x01); } @Test public void testReadBufferResetInputDeviceReady() { - UART UART = new UART(mock(Context8080.class)); - UART.receiveFromDevice((byte) 5); + UART uart = new UART(context, settings); + uart.receiveFromDevice((byte) 5); - assertEquals(5, UART.readBuffer()); - assertEquals(0, UART.readStatus() & 0x01); + assertEquals(5, uart.readBuffer()); + assertEquals(0, uart.readStatus() & 0x01); } @Test public void testBufferIsFIFO() { - UART UART = new UART(mock(Context8080.class)); - UART.receiveFromDevice((byte) 1); - UART.receiveFromDevice((byte) 2); - UART.receiveFromDevice((byte) 3); - - assertEquals(1, UART.readBuffer()); - assertEquals(2, UART.readBuffer()); - assertEquals(3, UART.readBuffer()); + UART uart = new UART(context, settings); + uart.receiveFromDevice((byte) 1); + uart.receiveFromDevice((byte) 2); + uart.receiveFromDevice((byte) 3); + + assertEquals(1, uart.readBuffer()); + assertEquals(2, uart.readBuffer()); + assertEquals(3, uart.readBuffer()); + } + + @Test + public void testInputInterruptIsTriggered() { + SioUnitSettings settings = mock(SioUnitSettings.class); + expect(settings.getInputInterruptVector()).andReturn(5).once(); + + Context8080 context = mock(Context8080.class); + expect(context.isInterruptSupported()).andReturn(true).once(); + context.signalInterrupt(new byte[]{(byte) 0xEF}); + expectLastCall().once(); + + replay(settings, context); + UART uart = new UART(context, settings); + uart.setStatus((byte) 1); + uart.receiveFromDevice((byte) 1); + + verify(context); + } + + @Test + public void testOutputInterruptIsTriggered() { + SioUnitSettings settings = mock(SioUnitSettings.class); + expect(settings.getOutputInterruptVector()).andReturn(5).once(); + + Context8080 context = mock(Context8080.class); + expect(context.isInterruptSupported()).andReturn(true).once(); + context.signalInterrupt(new byte[]{(byte) 0xEF}); + expectLastCall().once(); + + replay(settings, context); + UART uart = new UART(context, settings); + uart.setStatus((byte) 2); + uart.sendToDevice((byte) 1); + + verify(context); + } + + @Test + public void testInputInterruptIsTriggeredOnNonemptyBuffer() { + SioUnitSettings settings = mock(SioUnitSettings.class); + expect(settings.getInputInterruptVector()).andReturn(5).once(); + + Context8080 context = mock(Context8080.class); + expect(context.isInterruptSupported()).andReturn(true).once(); + context.signalInterrupt(new byte[]{(byte) 0xEF}); + expectLastCall().once(); + + replay(settings, context); + UART uart = new UART(context, settings); + uart.receiveFromDevice((byte) 1); // interrupts still disabled + uart.setStatus((byte) 1); // interrupts enabled - here the interrupt happens + + verify(context); } } From 58c905e1d4dede2301142aed67b8d5719f4a1078 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 24 Nov 2022 15:06:20 +0100 Subject: [PATCH 222/314] [#163] 88-sio: fix settings in computer config files --- application/src/main/files/config/MITSAltair8800.toml | 4 ++-- application/src/main/files/config/MITSAltair8800Z80.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/application/src/main/files/config/MITSAltair8800.toml b/application/src/main/files/config/MITSAltair8800.toml index 53a2c0c03..a8bb9e9f6 100644 --- a/application/src/main/files/config/MITSAltair8800.toml +++ b/application/src/main/files/config/MITSAltair8800.toml @@ -110,8 +110,8 @@ name = "MITS Altair8800" inputToUpperCase = false mapDeleteChar = "UNCHANGED" mapBackspaceChar = "UNCHANGED" - inputInterruptVector = 0 - outputInterruptVector = 0 + inputInterruptVector = 7 + outputInterruptVector = 7 [[DEVICE]] schemaPoint = "340,60" diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index 633222b6c..f6c95a547 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -106,8 +106,8 @@ name = "MITS Altair8800 (Z80)" inputToUpperCase = false mapDeleteChar = "UNCHANGED" mapBackspaceChar = "UNCHANGED" - inputInterruptVector = 0 - outputInterruptVector = 0 + inputInterruptVector = 7 + outputInterruptVector = 7 [[DEVICE]] schemaPoint = "480,220" From 26f19ce88aec86aab2a9ca7bd999b7618255cfd5 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 24 Nov 2022 15:52:58 +0100 Subject: [PATCH 223/314] [#163] Fix interrupts on 88-sio and 8080 cpu --- .../src/main/examples/88-sio-interrupts.asm | 33 +++++++++++++++++++ .../cpu/intel8080/Context8080Impl.java | 2 +- .../plugins/cpu/intel8080/CpuImpl.java | 1 + .../plugins/cpu/intel8080/EmulatorEngine.java | 19 +++++++++-- 4 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 plugins/compiler/as-8080/src/main/examples/88-sio-interrupts.asm diff --git a/plugins/compiler/as-8080/src/main/examples/88-sio-interrupts.asm b/plugins/compiler/as-8080/src/main/examples/88-sio-interrupts.asm new file mode 100644 index 000000000..fd8691d70 --- /dev/null +++ b/plugins/compiler/as-8080/src/main/examples/88-sio-interrupts.asm @@ -0,0 +1,33 @@ +; Tests signalling interrupts on input + +lxi h, hello ; load address of 'hello' label to HL +call print ; print hello + +mvi a, 1 ; 88-SIO: input interrupts enable +out 0x10 + +ei ; enable CPU interrupts +loop: +jmp loop ; do this forever (or until...) + + +; interrupt handler +org 0x38 ; assuming interrupt vector is set to 7 +in 0x11 ; read char from 88-SIO (and ignore it) +lxi h, key ; load address of 'key' label to HL +call print ; print "key pressed" +ret ; return from the interrupt + + +hello: db 'Hello, world!',10,13,0 +key: db 'Key pressed!',10,13,0 + +; Procedure for printing text to terminal. +; Input: pair HL must contain the address of the ASCIIZ string +print: + mov a, m ; load character from HL + inx h ; increment HL + cpi 0 ; is the character = 0? + rz ; yes; quit + out 11h ; otherwise; show it + jmp print ; and repeat from the beginning diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java index 3622a46a6..df8b5d6a6 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java @@ -87,7 +87,7 @@ public byte fireIO(int port, boolean read, byte data) { @Override public boolean isInterruptSupported() { - return false; + return true; } /** diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java index 6caea3b41..1ed09c857 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java @@ -96,6 +96,7 @@ public String getDescription() { public void initialize() throws PluginInitializationException { initializer.initialize(); engine = initializer.getEngine(); + context.setCpu(engine); disassembler = initializer.getDisassembler(); statusPanel = new StatusPanel(this, context, initializer.shouldDumpInstructions()); } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java index 8696ae4a5..de9e48f33 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java @@ -31,6 +31,7 @@ import java.lang.invoke.MethodHandle; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import static net.emustudio.plugins.cpu.intel8080.DispatchTables.DISPATCH_TABLE; @@ -52,6 +53,16 @@ public class EmulatorEngine implements CpuEngine { private short b1 = 0; // the raw interrupt instruction private short b2 = 0; private short b3 = 0; + private final static Map RST_MAP = Map.of( + 0xC7, 0, + 0xCF, 0x8, + 0xD7, 0x10, + 0xDF, 0x18, + 0xE7, 0x20, + 0xEF, 0x28, + 0xF7, 0x30, + 0xFF, 0x38 + ); public int PC = 0; // program counter public int SP = 0; // stack pointer @@ -171,12 +182,14 @@ private int dispatch() throws Throwable { */ if (isINT) { if (INTE) { - if ((b1 & 0xC7) == 0xC7) { /* RST */ + isINT = false; + Integer maybeAddress = RST_MAP.get(b1 & 0xFF); + if (maybeAddress != null) { // RST SP = (SP - 2) & 0xFFFF; writeWord(SP, PC); - PC = b1 & 0x38; + PC = maybeAddress; return 11; - } else if (b1 == 0xCD) { /* CALL */ + } else if (b1 == 0xCD) { // CALL SP = (SP - 2) & 0xFFFF; writeWord(SP, (PC + 2) & 0xFFFF); PC = ((b3 & 0xFF) << 8) | (b2 & 0xFF); From 231672960b53bad06342500f0a58001db5e2830d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 24 Nov 2022 18:55:15 +0100 Subject: [PATCH 224/314] as-z80: Fix setting size of few ED instructions --- .../compiler/asZ80/visitors/CreateInstrVisitor.java | 10 +++++----- .../emustudio/plugins/compiler/asZ80/e2e/DataTest.java | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java index 5a67ee2a6..175d4781d 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java @@ -185,15 +185,15 @@ public Node visitInstrED(InstrEDContext ctx) { // | opcode=OPCODE_OTDR # instrED switch (ctx.opcode.getType()) { case OPCODE_NEG: - return new InstrED(ctx.opcode, 0, 4); + return new InstrED(ctx.opcode, 0, 4).setSizeBytes(2); case OPCODE_RETN: - return new InstrED(ctx.opcode, 0, 5); + return new InstrED(ctx.opcode, 0, 5).setSizeBytes(2); case OPCODE_RETI: - return new InstrED(ctx.opcode, 1, 5); + return new InstrED(ctx.opcode, 1, 5).setSizeBytes(2); case OPCODE_RRD: - return new InstrED(ctx.opcode, 4, 7); + return new InstrED(ctx.opcode, 4, 7).setSizeBytes(2); case OPCODE_RLD: - return new InstrED(ctx.opcode, 5, 7); + return new InstrED(ctx.opcode, 5, 7).setSizeBytes(2); } Pair yz = CompilerTables.block.get(ctx.opcode.getType()); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java index 3fe9640e0..5df2fb657 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java @@ -197,4 +197,10 @@ public void testDbOrdering() { 186, 'H', 'e', 'l', 'l', 'o', 186, 10, 13 ); } + + @Test + public void testDbLabelAddressAfterOrg() { + compile("ld hl, hello\norg 0x5\nreti\nhello: db \"Hello\", 10, 13, 0"); + assertProgram(0x21, 7, 0, 0, 0, 0xED, 0x4D, 'H', 'e', 'l', 'l', 'o', 10, 13, 0); + } } From 3190b472aba87cc9ad1c071c1f459e70e2c2bfde Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 24 Nov 2022 19:46:48 +0100 Subject: [PATCH 225/314] [#163] as-z80: add example for IM 1 --- .../as-z80/src/main/examples/im1test.asm | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 plugins/compiler/as-z80/src/main/examples/im1test.asm diff --git a/plugins/compiler/as-z80/src/main/examples/im1test.asm b/plugins/compiler/as-z80/src/main/examples/im1test.asm new file mode 100644 index 000000000..e4d0294a4 --- /dev/null +++ b/plugins/compiler/as-z80/src/main/examples/im1test.asm @@ -0,0 +1,37 @@ +; Tests signalling interrupts on input + +ld hl, hello ; load address of 'hello' label to HL +call print ; print hello + +ld a, 1 ; 88-SIO: input interrupts enable +out (0x10), a + +ei ; enable CPU interrupts +im 1 ; interrupt mode 1 + +loop: +ei +jp loop ; do this forever (or until...) + + +; interrupt handler +org 0x38 ; 88-sio interrupt vector is ignored in IM 1 mode + +in a, (0x11) ; read char from 88-SIO (and ignore it) +ld hl, key ; load address of 'key' label to HL +call print ; print "key pressed" +reti ; return from the interrupt + + +hello: db 'Hello, world!',10,13,0 +key: db 'Key pressed!',10,13,0 + +; Procedure for printing text to terminal. +; Input: pair HL must contain the address of the ASCIIZ string +print: + ld a, (hl) ; load character from HL + inc hl ; increment HL + cp 0 ; is the character = 0? + ret z ; yes; quit + out (11h), a ; otherwise; show it + jp print ; and repeat from the beginning From ab323e8fac4b2681a449d2eaa01767e8e3630222 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 2 Dec 2022 16:46:49 +0100 Subject: [PATCH 226/314] [#162] 88-disk: implemented interrupts --- .../src/main/files/config/MITSAltair8800.toml | 32 +- .../main/files/config/MITSAltair8800Z80.toml | 32 +- .../plugins/device/mits88dcdd/DeviceImpl.java | 131 ++----- .../device/mits88dcdd/DiskSettings.java | 158 +++++++++ .../device/mits88dcdd/SettingsConstants.java | 29 -- .../device/mits88dcdd/drive/Drive.java | 135 +++---- .../mits88dcdd/drive/DriveCollection.java | 110 +++++- .../device/mits88dcdd/gui/SettingsDialog.java | 329 +++++++++--------- .../device/mits88dcdd/DeviceImplTest.java | 14 +- .../plugins/device/mits88dcdd/DriveTest.java | 59 ++-- .../plugins/device/mits88sio/DataChannel.java | 1 - .../plugins/device/mits88sio/DeviceImpl.java | 1 - .../plugins/device/mits88sio/SioUnit.java | 1 - .../{settings => }/SioUnitSettings.java | 8 +- .../plugins/device/mits88sio/UART.java | 1 - .../device/mits88sio/gui/SettingsDialog.java | 2 +- .../mits88sio/settings/SettingsObserver.java | 25 -- .../device/mits88sio/DataChannelTest.java | 1 - .../plugins/device/mits88sio/SioUnitTest.java | 1 - .../plugins/device/mits88sio/UARTTest.java | 1 - 20 files changed, 593 insertions(+), 478 deletions(-) create mode 100644 plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java delete mode 100644 plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/SettingsConstants.java rename plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/{settings => }/SioUnitSettings.java (98%) delete mode 100644 plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SettingsObserver.java diff --git a/application/src/main/files/config/MITSAltair8800.toml b/application/src/main/files/config/MITSAltair8800.toml index a8bb9e9f6..baa404aea 100644 --- a/application/src/main/files/config/MITSAltair8800.toml +++ b/application/src/main/files/config/MITSAltair8800.toml @@ -59,16 +59,16 @@ name = "MITS Altair8800" [DEVICE.settings] # imageN = "..." # Load file into drive N at startup - sectorLength8 = 137 - sectorLength9 = 137 - sectorLength6 = 137 - sectorLength7 = 137 - sectorLength4 = 137 - sectorLength5 = 137 - sectorLength2 = 137 - sectorLength3 = 137 - sectorLength0 = 137 - sectorLength1 = 137 + sectorSize8 = 137 + sectorSize9 = 137 + sectorSize6 = 137 + sectorSize7 = 137 + sectorSize4 = 137 + sectorSize5 = 137 + sectorSize2 = 137 + sectorSize3 = 137 + sectorSize0 = 137 + sectorSize1 = 137 port2CPU = 9 sectorsPerTrack15 = 32 sectorsPerTrack14 = 32 @@ -88,12 +88,12 @@ name = "MITS Altair8800" sectorsPerTrack8 = 32 port1CPU = 8 port3CPU = 10 - sectorLength15 = 137 - sectorLength13 = 137 - sectorLength14 = 137 - sectorLength11 = 137 - sectorLength12 = 137 - sectorLength10 = 137 + sectorSize15 = 137 + sectorSize13 = 137 + sectorSize14 = 137 + sectorSize11 = 137 + sectorSize12 = 137 + sectorSize10 = 137 [[DEVICE]] schemaPoint = "340,180" diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index f6c95a547..0169646b4 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -55,16 +55,16 @@ name = "MITS Altair8800 (Z80)" [DEVICE.settings] # imageN = "..." # Load file into drive N at startup - sectorLength8 = 137 - sectorLength9 = 137 - sectorLength6 = 137 - sectorLength7 = 137 - sectorLength4 = 137 - sectorLength5 = 137 - sectorLength2 = 137 - sectorLength3 = 137 - sectorLength0 = 137 - sectorLength1 = 137 + sectorSize8 = 137 + sectorSize9 = 137 + sectorSize6 = 137 + sectorSize7 = 137 + sectorSize4 = 137 + sectorSize5 = 137 + sectorSize2 = 137 + sectorSize3 = 137 + sectorSize0 = 137 + sectorSize1 = 137 port2CPU = 9 sectorsPerTrack15 = 32 sectorsPerTrack14 = 32 @@ -84,12 +84,12 @@ name = "MITS Altair8800 (Z80)" sectorsPerTrack8 = 32 port1CPU = 8 port3CPU = 10 - sectorLength15 = 137 - sectorLength13 = 137 - sectorLength14 = 137 - sectorLength11 = 137 - sectorLength12 = 137 - sectorLength10 = 137 + sectorSize15 = 137 + sectorSize13 = 137 + sectorSize14 = 137 + sectorSize11 = 137 + sectorSize12 = 137 + sectorSize10 = 137 [[DEVICE]] schemaPoint = "340,220" diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java index 0b638e55a..5080ab54d 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java @@ -22,83 +22,61 @@ import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; import net.emustudio.emulib.plugins.annotations.PluginRoot; import net.emustudio.emulib.plugins.device.AbstractDevice; -import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.cpu.intel8080.api.Context8080; -import net.emustudio.plugins.device.mits88dcdd.drive.Drive; import net.emustudio.plugins.device.mits88dcdd.drive.DriveCollection; import net.emustudio.plugins.device.mits88dcdd.gui.DiskGui; import net.emustudio.plugins.device.mits88dcdd.gui.SettingsDialog; import net.emustudio.plugins.device.mits88dcdd.ports.ControlPort; import net.emustudio.plugins.device.mits88dcdd.ports.DataPort; import net.emustudio.plugins.device.mits88dcdd.ports.StatusPort; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.swing.*; -import java.io.IOException; -import java.nio.file.Path; -import java.util.*; import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; @PluginRoot( type = PLUGIN_TYPE.DEVICE, - title = "MITS 88-DCDD device" + title = "MITS 88-DCDD" ) public class DeviceImpl extends AbstractDevice { - private final static Logger LOGGER = LoggerFactory.getLogger(DeviceImpl.class); - - public final static int DEFAULT_CPU_PORT1 = 0x8; - public final static int DEFAULT_CPU_PORT2 = 0x9; - public final static int DEFAULT_CPU_PORT3 = 0xA; - - private final StatusPort statusPort; - private final ControlPort controlPort; - private final DataPort dataPort; + private final DiskSettings settings; + private final Dialogs dialogs; private final boolean guiSupported; private Context8080 cpuContext; - - private int port1CPU; - private int port2CPU; - private int port3CPU; - + private DriveCollection drives; private DiskGui gui; - private final DriveCollection drives = new DriveCollection(); public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); + this.settings = new DiskSettings(settings); this.guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); - - port1CPU = DEFAULT_CPU_PORT1; - port2CPU = DEFAULT_CPU_PORT2; - port3CPU = DEFAULT_CPU_PORT3; - - statusPort = new StatusPort(drives); - controlPort = new ControlPort(drives); - dataPort = new DataPort(drives); + this.dialogs = applicationApi.getDialogs(); } @Override public void initialize() throws PluginInitializationException { - readSettings(); - ContextPool contextPool = applicationApi.getContextPool(); - if (contextPool != null) { - cpuContext = contextPool.getCPUContext(pluginID, Context8080.class); - - // attach device to CPU - port1CPU = attachPort(1, statusPort, port1CPU); - port2CPU = attachPort(2, controlPort, port2CPU); - port3CPU = attachPort(3, dataPort, port3CPU); - } + cpuContext = applicationApi.getContextPool().getCPUContext(pluginID, Context8080.class); + drives = new DriveCollection(cpuContext, settings, dialogs); + + StatusPort statusPort = new StatusPort(drives); + ControlPort controlPort = new ControlPort(drives); + DataPort dataPort = new DataPort(drives); + drives.attach(statusPort, controlPort, dataPort); + settings.addObserver(() -> { + try { + drives.attach(statusPort, controlPort, dataPort); + drives.reset(); + } catch (PluginInitializationException e) { + throw new RuntimeException(e); + } + }); } - @Override public void showGUI(JFrame parent) { if (guiSupported) { @@ -131,6 +109,7 @@ public String getDescription() { @Override public void destroy() { + settings.clearObservers(); if (gui != null) { gui.dispose(); gui = null; @@ -154,68 +133,4 @@ public void showSettings(JFrame parent) { public boolean isShowSettingsSupported() { return guiSupported; } - - private void readSettings() { - port1CPU = settings.getInt(SettingsConstants.PORT1_CPU, DEFAULT_CPU_PORT1); - port2CPU = settings.getInt(SettingsConstants.PORT2_CPU, DEFAULT_CPU_PORT2); - port3CPU = settings.getInt(SettingsConstants.PORT3_CPU, DEFAULT_CPU_PORT3); - - drives.foreach((i, drive) -> { - int sectorLength = settings.getInt(SettingsConstants.SECTOR_LENGTH + i, Drive.DEFAULT_SECTOR_SIZE); - int sectorsCount = settings.getInt(SettingsConstants.SECTORS_COUNT + i, Drive.DEFAULT_SECTORS_PER_TRACK); - String imagePath = settings.getString(SettingsConstants.IMAGE + i, null); - - drive.setSectorSize(sectorLength); - drive.setSectorsPerTrack(sectorsCount); - Optional.ofNullable(imagePath).ifPresent(path -> { - try { - drive.mount(Path.of(path)); - } catch (IOException ex) { - LOGGER.error("Could not mount image file {}", path, ex); - applicationApi.getDialogs().showError( - "Could not mount image file: " + path + ". Please see log file for more details.", - "MITS 88-DCDD" - ); - } - }); - return null; - }); - } - - private int attachPort(int diskPortNumber, DeviceContext diskPort, int cpuPort) throws PluginInitializationException { - if (cpuContext.attachDevice(diskPort, cpuPort)) { - return cpuPort; - } else { - int portNumber = cpuPort; - boolean enteredValid = false; - Dialogs dialogs = applicationApi.getDialogs(); - - while (!enteredValid) { - try { - portNumber = dialogs.readInteger( - "Port " + diskPortNumber + " could not be attached to CPU port " + cpuPort + "." + - "\nPlease enter another CPU port:", - DIALOG_TITLE - ).orElseThrow(() -> new PluginInitializationException( - this, ": " + DIALOG_TITLE + " (port " + diskPortNumber + ") can not be attached to default CPU port " + cpuPort - )); - - enteredValid = true; - } catch (NumberFormatException e) { - dialogs.showError("Invalid number format", DIALOG_TITLE); - } - } - - if (!cpuContext.attachDevice(diskPort, portNumber)) { - dialogs.showError( - "Port " + diskPortNumber + " still cannot be attached to provided CPU port " + portNumber, - DIALOG_TITLE - ); - throw new PluginInitializationException( - this, ": " + DIALOG_TITLE + " (port " + diskPortNumber + ") can not be attached to CPU port " + portNumber - ); - } - return portNumber; - } - } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java new file mode 100644 index 000000000..c9b2f11bd --- /dev/null +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java @@ -0,0 +1,158 @@ +package net.emustudio.plugins.device.mits88dcdd; + +import net.emustudio.emulib.runtime.settings.BasicSettings; +import net.jcip.annotations.Immutable; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; + +public class DiskSettings { + public final static int DEFAULT_CPU_PORT1 = 0x8; + public final static int DEFAULT_CPU_PORT2 = 0x9; + public final static int DEFAULT_CPU_PORT3 = 0xA; + public final static int DEFAULT_INTERRUPT_VECTOR = 7; + public final static int DEFAULT_SECTORS_PER_TRACK = 32; + public final static int DEFAULT_SECTOR_SIZE = 137; + + private static final String KEY_PORT1_CPU = "port1CPU"; + private static final String KEY_PORT2_CPU = "port2CPU"; + private static final String KEY_PORT3_CPU = "port3CPU"; + private static final String KEY_SECTORS_PER_TRACK = "sectorsPerTrack"; + private static final String KEY_SECTOR_SIZE = "sectorSize"; + private static final String KEY_IMAGE = "image"; + private static final String KEY_INTERRUPT_VECTOR = "interruptVector"; + + private final BasicSettings settings; + private final List observers = new CopyOnWriteArrayList<>(); + + private volatile int port1CPU; + private volatile int port2CPU; + private volatile int port3CPU; + private volatile int interruptVector; + private final DriveSettings[] driveSettings = new DriveSettings[16]; + + @FunctionalInterface + public interface SettingsObserver { + + void settingsChanged(); + } + + @Immutable + public static class DriveSettings { + public final static DriveSettings DEFAULT = new DriveSettings( + DEFAULT_SECTOR_SIZE, DEFAULT_SECTORS_PER_TRACK, null + ); + + public final int sectorSize; + public final int sectorsPerTrack; + public final String imagePath; + + public DriveSettings(int sectorSize, int sectorsPerTrack, String imagePath) { + this.sectorSize = sectorSize; + this.sectorsPerTrack = sectorsPerTrack; + this.imagePath = imagePath; + } + } + + public DiskSettings(BasicSettings settings) { + this.settings = Objects.requireNonNull(settings); + + this.port1CPU = settings.getInt(KEY_PORT1_CPU, DEFAULT_CPU_PORT1); + this.port2CPU = settings.getInt(KEY_PORT2_CPU, DEFAULT_CPU_PORT2); + this.port3CPU = settings.getInt(KEY_PORT3_CPU, DEFAULT_CPU_PORT3); + this.interruptVector = settings.getInt(KEY_INTERRUPT_VECTOR, DEFAULT_INTERRUPT_VECTOR); + + for (int i = 0; i < driveSettings.length; i++) { + driveSettings[i] = new DriveSettings( + settings.getInt(KEY_SECTOR_SIZE + i, DEFAULT_SECTOR_SIZE), + settings.getInt(KEY_SECTORS_PER_TRACK + i, DEFAULT_SECTORS_PER_TRACK), + settings.getString(KEY_IMAGE + i, null) + ); + } + } + + public void addObserver(SettingsObserver observer) { + observers.add(observer); + } + + public void clearObservers() { + observers.clear(); + } + + public DriveSettings getDriveSettings(int drive) { + return driveSettings[drive]; + } + + public void setDriveSettings(int drive, DriveSettings driveSettings) { + if (drive < 0 || drive > 15) { + throw new IllegalArgumentException("88-DCDD: Only drive from 0-15 is allowed"); + } + + this.driveSettings[drive] = driveSettings; + settings.setInt(KEY_SECTOR_SIZE + drive, driveSettings.sectorSize); + settings.setInt(KEY_SECTORS_PER_TRACK + drive, driveSettings.sectorsPerTrack); + if (driveSettings.imagePath == null) { + settings.remove(KEY_IMAGE + drive); + } else { + settings.setString(KEY_IMAGE + drive, driveSettings.imagePath); + } + notifySettingsChanged(); + } + + public int getPort1CPU() { + return port1CPU; + } + + public void setPort1CPU(int port1CPU) { + if (port1CPU < 0 || port1CPU > 0xFF) { + throw new IllegalArgumentException("88-DCDD: CPU port 1 allowed range: 0-255"); + } + this.port1CPU = port1CPU; + settings.setInt(KEY_PORT1_CPU, port1CPU); + notifySettingsChanged(); + } + + public int getPort2CPU() { + return port2CPU; + } + + public void setPort2CPU(int port2CPU) { + if (port2CPU < 0 || port2CPU > 0xFF) { + throw new IllegalArgumentException("88-DCDD: CPU port 2 allowed range: 0-255"); + } + this.port2CPU = port2CPU; + settings.setInt(KEY_PORT2_CPU, port2CPU); + notifySettingsChanged(); + } + + public int getPort3CPU() { + return port3CPU; + } + + public void setPort3CPU(int port3CPU) { + if (port3CPU < 0 || port3CPU > 0xFF) { + throw new IllegalArgumentException("88-DCDD: CPU port 3 allowed range: 0-255"); + } + this.port3CPU = port3CPU; + settings.setInt(KEY_PORT3_CPU, port3CPU); + notifySettingsChanged(); + } + + public int getInterruptVector() { + return interruptVector; + } + + public void setInterruptVector(int interruptVector) { + if (interruptVector < 0 || interruptVector > 7) { + throw new IllegalArgumentException("88-DCDD: Interrupt vector must be in range 0-7"); + } + this.interruptVector = interruptVector; + settings.setInt(KEY_INTERRUPT_VECTOR, interruptVector); + notifySettingsChanged(); + } + + private void notifySettingsChanged() { + observers.forEach(SettingsObserver::settingsChanged); + } +} diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/SettingsConstants.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/SettingsConstants.java deleted file mode 100644 index dd840a833..000000000 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/SettingsConstants.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88dcdd; - -public class SettingsConstants { - public static final String PORT1_CPU = "port1CPU"; - public static final String PORT2_CPU = "port2CPU"; - public static final String PORT3_CPU = "port3CPU"; - public static final String SECTORS_COUNT = "sectorsPerTrack"; - public static final String SECTOR_LENGTH = "sectorLength"; - public static final String IMAGE = "image"; - -} diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java index 08faac254..75571e7d4 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java @@ -18,6 +18,8 @@ */ package net.emustudio.plugins.device.mits88dcdd.drive; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; +import net.emustudio.plugins.device.mits88dcdd.DiskSettings; import net.jcip.annotations.ThreadSafe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,13 +32,12 @@ import java.nio.file.OpenOption; import java.nio.file.Path; import java.nio.file.StandardOpenOption; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Supplier; /** * Performs disk operations on single drive. @@ -45,9 +46,6 @@ public class Drive { private static final Logger LOGGER = LoggerFactory.getLogger(Drive.class); - public final static byte DEFAULT_SECTORS_PER_TRACK = 32; - public final static int DEFAULT_SECTOR_SIZE = 137; - public static final byte DEAD_DRIVE = (byte)0b11100111; private static final byte ALIVE_DRIVE = (byte)0b11100101; private static final byte MASK_TRACK0 = (byte)0b10111111; @@ -57,14 +55,26 @@ public class Drive { private static final byte MASK_HEAD_LOAD = (byte)0b11111011; private static final byte MASK_DATA_AVAILABLE = 0b01111111; + private final static Map RST_MAP = Map.of( + 0, (byte) 0xC7, + 1, (byte) 0xCF, + 2, (byte) 0xD7, + 3, (byte) 0xDF, + 4, (byte) 0xE7, + 5, (byte) 0xEF, + 6, (byte) 0xF7, + 7, (byte) 0xFF + ); + private final int driveIndex; + private final Context8080 cpu; + private final Supplier interruptVector; private final ReadWriteLock positionLock = new ReentrantReadWriteLock(); private int track; private int sector; private int sectorOffset; - private int sectorsPerTrack = DEFAULT_SECTORS_PER_TRACK; - private int sectorSize = DEFAULT_SECTOR_SIZE; + private DiskSettings.DriveSettings driveSettings = DiskSettings.DriveSettings.DEFAULT; private Path mountedFloppy = null; private SeekableByteChannel imageChannel; @@ -74,7 +84,7 @@ public class Drive { private final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1); private boolean sectorTrue = true; // SR0 alternation - + private boolean signalInterrupts = false; /* 7 6 5 4 3 2 1 0 @@ -102,37 +112,18 @@ public class Drive { */ private byte port2status = SECTOR0; - public Drive(int driveIndex) { + public Drive(int driveIndex, Context8080 cpu, Supplier interruptVector) { this.driveIndex = driveIndex; + this.cpu = Objects.requireNonNull(cpu); + this.interruptVector = Objects.requireNonNull(interruptVector); reset(); } - public void setSectorsPerTrack(int sectorsPerTrack) { - if (sectorsPerTrack <= 0) { - LOGGER.error("[drive=" + driveIndex + "] Sectors count must be > 0"); - return; - } - inWriteLock(() -> this.sectorsPerTrack = sectorsPerTrack); - reset(); - } - - public void setSectorSize(int sectorSize) { - if (sectorSize <= 0) { - LOGGER.error("[drive=" + driveIndex + "] Sector length must be > 0"); - return; - } - inWriteLock(() -> this.sectorSize = sectorSize); + public void setDriveSettings(DiskSettings.DriveSettings driveSettings) { + this.driveSettings = Objects.requireNonNull(driveSettings); reset(); } - public int getSectorsPerTrack() { - return inReadLock(() -> sectorsPerTrack); - } - - public int getSectorSize() { - return inReadLock(() -> sectorSize); - } - public void addDriveListener(DriveListener listener) { this.listeners.add(listener); } @@ -163,7 +154,7 @@ private void selectInternal() { port1status = ALIVE_DRIVE; port2status = SECTOR0; sector = 0; - sectorOffset = sectorSize; + sectorOffset = driveSettings.sectorSize; if (track == 0) { port1status &= MASK_TRACK0; } @@ -211,10 +202,6 @@ public void umount() { } } - public Path getImagePath() { - return mountedFloppy; - } - public byte getPort1status() { return inReadLock(() -> port1status); } @@ -231,23 +218,26 @@ public byte getPort2status() { public void writeToPort2(short val) { inWriteLock(() -> { - if ((val & 0x01) != 0) { /* Step head in */ + if ((val & 0x01) != 0) { + // Step head in track++; sector = 0; - sectorOffset = sectorSize; + sectorOffset = driveSettings.sectorSize; port2status = SECTOR0; } - if ((val & 0x02) != 0) { /* Step head out */ + if ((val & 0x02) != 0) { + // Step head out track--; if (track < 0) { track = 0; port1status &= 0xBF; // head is on track 0 } sector = 0; - sectorOffset = sectorSize; + sectorOffset = driveSettings.sectorSize; port2status = SECTOR0; } - if ((val & 0x04) != 0) { /* Head load */ + if ((val & 0x04) != 0) { + // Head load port1status &= MASK_HEAD_LOAD; port1status &= MASK_DATA_AVAILABLE; port2status = (byte) ((sector << 1) & 0x3E | 0xC0); @@ -255,18 +245,27 @@ public void writeToPort2(short val) { port2status |= 1; // SR0 = false } } - if ((val & 0x08) != 0) { /* Head Unload */ - port1status |= (~MASK_HEAD_LOAD); /* turn off 'head loaded' */ - port1status |= (~MASK_DATA_AVAILABLE); /* turn off 'read data avail */ + if ((val & 0x08) != 0) { + // Head Unload + port1status |= (~MASK_HEAD_LOAD); // turn off 'head loaded' + port1status |= (~MASK_DATA_AVAILABLE); // turn off 'read data avail' sector = 0; - sectorOffset = sectorSize; + sectorOffset = driveSettings.sectorSize; port2status = SECTOR0; } - /* Interrupts & head current are ignored */ - if ((val & 0x80) != 0) { /* write sequence start */ + if ((val & 0x10) != 0) { + // interrupts enable + signalInterrupts = true; + } + if ((val & 0x20) != 0) { + // interrupts disable + signalInterrupts = false; + } + if ((val & 0x80) != 0) { + // write sequence start sectorOffset = 0; port2status &= 0xFE; // SR0 = true - port1status &= 0xFE; /* enter new write data on */ + port1status &= 0xFE; // enter new write data on } }); notifyParamsChanged(); @@ -274,10 +273,13 @@ public void writeToPort2(short val) { public void nextSectorIfHeadIsLoaded() { inWriteLock(() -> { - if (((~port1status) & (~MASK_HEAD_LOAD)) != 0) { /* head loaded? */ + if (((~port1status) & (~MASK_HEAD_LOAD)) != 0) { // head loaded? if (sectorTrue) { - sector = (byte) ((sector + 1) % sectorsPerTrack); - sectorOffset = sectorSize; + sector = (byte) ((sector + 1) % driveSettings.sectorsPerTrack); + sectorOffset = driveSettings.sectorSize; + if (signalInterrupts) { + signalInterrupt(); + } } port2status = (byte) (((sector << 1) & 0x3E) | 0xC0 | (sectorTrue ? 1 : 0)); sectorTrue = !sectorTrue; @@ -292,20 +294,20 @@ public void writeData(int data) { byteBuffer.put((byte) (data & 0xFF)); byteBuffer.flip(); - if (sectorOffset == sectorSize) { - port1status |= 1; /* ENWD off */ + if (sectorOffset == driveSettings.sectorSize) { + port1status |= 1; // ENWD off port2status &= 0xFE; // SR0 = TRUE return; } - int pos = sectorsPerTrack * sectorSize * track + sectorSize * sector + sectorOffset; + int pos = driveSettings.sectorsPerTrack * driveSettings.sectorSize * track + driveSettings.sectorSize * sector + sectorOffset; try { imageChannel.position(pos); imageChannel.write(byteBuffer); } catch (IOException ex) { throw new RuntimeException(ex); } finally { - sectorOffset = (sectorOffset == sectorSize) ? sectorSize : (sectorOffset + 1); + sectorOffset = (sectorOffset == driveSettings.sectorSize) ? driveSettings.sectorSize : (sectorOffset + 1); port2status |= 1; } }); @@ -318,8 +320,8 @@ public byte readData() { } byte result = inWriteLock(() -> { try { - int offset = (sectorOffset == sectorSize) ? 0 : sectorOffset; - imageChannel.position((long) sectorsPerTrack * sectorSize * track + (long) sectorSize * sector + offset); + int offset = (sectorOffset == driveSettings.sectorSize) ? 0 : sectorOffset; + imageChannel.position((long) driveSettings.sectorsPerTrack * driveSettings.sectorSize * track + (long) driveSettings.sectorSize * sector + offset); byteBuffer.clear(); int bytesRead = imageChannel.read(byteBuffer); if (bytesRead != byteBuffer.capacity()) { @@ -330,8 +332,8 @@ public byte readData() { } catch (IOException ex) { throw new RuntimeException(ex); } finally { - sectorOffset = (sectorOffset == sectorSize) ? 1 : (sectorOffset + 1); - if (sectorOffset == sectorSize) { + sectorOffset = (sectorOffset == driveSettings.sectorSize) ? 1 : (sectorOffset + 1); + if (sectorOffset == driveSettings.sectorSize) { port2status &= 0xFE; } else { port2status |= 1; @@ -351,16 +353,17 @@ public int getTrack() { } public int getOffset() { - return inReadLock(() -> sectorOffset == sectorSize ? 0 : sectorOffset); + return inReadLock(() -> sectorOffset == driveSettings.sectorSize ? 0 : sectorOffset); } private void reset() { inWriteLock(() -> { track = 0; sector = 0; - sectorOffset = sectorSize; + sectorOffset = driveSettings.sectorSize; port1status = DEAD_DRIVE; port2status = SECTOR0; + signalInterrupts = false; }); } @@ -378,6 +381,12 @@ private void notifyParamsChanged() { } } + private void signalInterrupt() { + if (cpu.isInterruptSupported()) { + cpu.signalInterrupt(new byte[]{RST_MAP.get(interruptVector.get())}); + } + } + private T inWriteLock(Callable action) { positionLock.writeLock().lock(); try { diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java index c78faff23..a53f7ffd9 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java @@ -18,21 +18,48 @@ */ package net.emustudio.plugins.device.mits88dcdd.drive; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; +import net.emustudio.emulib.plugins.PluginInitializationException; +import net.emustudio.emulib.plugins.device.DeviceContext; +import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; +import net.emustudio.plugins.device.mits88dcdd.DiskSettings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; +import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; + public class DriveCollection implements Iterable { - private final static int DRIVES_COUNT = 16; + private final static Logger LOGGER = LoggerFactory.getLogger(DriveCollection.class); + + public final static int DRIVES_COUNT = 16; private final List drives = new ArrayList<>(); + private final Context8080 cpu; + private final DiskSettings settings; + private final Dialogs dialogs; + + private Optional attachedCpuPort1 = Optional.empty(); + private Optional attachedCpuPort2 = Optional.empty(); + private Optional attachedCpuPort3 = Optional.empty(); + private volatile int currentDrive; + private final AtomicReference> lastAttachedPort1 = new AtomicReference<>(); + private final AtomicReference> lastAttachedPort2 = new AtomicReference<>(); + private final AtomicReference> lastAttachedPort3 = new AtomicReference<>(); + + public DriveCollection(Context8080 cpu, DiskSettings settings, Dialogs dialogs) { + this.cpu = Objects.requireNonNull(cpu); + this.settings = Objects.requireNonNull(settings); + this.dialogs = Objects.requireNonNull(dialogs); - public DriveCollection() { for (int i = 0; i < DRIVES_COUNT; i++) { - drives.add(new Drive(i)); + drives.add(new Drive(i, cpu, settings::getInterruptVector)); } this.currentDrive = DRIVES_COUNT; @@ -73,4 +100,73 @@ public void foreach(BiFunction function) { i++; } } + + public void reattach() throws PluginInitializationException { + DeviceContext port1 = lastAttachedPort1.get(); + DeviceContext port2 = lastAttachedPort2.get(); + DeviceContext port3 = lastAttachedPort3.get(); + if (port1 != null && port2 != null && port3 != null) { + attach(port1, port2, port3); + } + } + + public void attach(DeviceContext port1, DeviceContext port2, DeviceContext port3) throws PluginInitializationException { + detach(); + int port1cpu = settings.getPort1CPU(); + int port2cpu = settings.getPort2CPU(); + int port3cpu = settings.getPort3CPU(); + + if (!cpu.attachDevice(port1, port1cpu)) { + throw new PluginInitializationException( + ": " + DIALOG_TITLE + " (port 1) can not be attached to default CPU port " + port1cpu + ); + } + attachedCpuPort1 = Optional.of(port1cpu); + lastAttachedPort1.set(port1); + + if (!cpu.attachDevice(port2, port2cpu)) { + throw new PluginInitializationException( + ": " + DIALOG_TITLE + " (port 2) can not be attached to default CPU port " + port2cpu + ); + } + attachedCpuPort2 = Optional.of(port2cpu); + lastAttachedPort2.set(port2); + + if (!cpu.attachDevice(port3, port3cpu)) { + throw new PluginInitializationException( + ": " + DIALOG_TITLE + " (port 3) can not be attached to default CPU port " + port3cpu + ); + } + attachedCpuPort3 = Optional.of(port3cpu); + lastAttachedPort3.set(port3); + } + + public void detach() { + attachedCpuPort1.ifPresent(cpu::detachDevice); + attachedCpuPort2.ifPresent(cpu::detachDevice); + attachedCpuPort3.ifPresent(cpu::detachDevice); + } + + public void reset() { + foreach((i, drive) -> { + DiskSettings.DriveSettings driveSettings = settings.getDriveSettings(i); + drive.setDriveSettings(driveSettings); + + Optional + .ofNullable(driveSettings.imagePath) + .map(Path::of) + .ifPresent(path -> { + try { + drive.mount(path); + } catch (IOException ex) { + LOGGER.error("Could not mount image file {}", path, ex); + dialogs.showError( + "Could not mount image file: " + path + ". Please see log file for more details.", + "MITS 88-DCDD" + ); + } + }); + return null; + }); + } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java index bcb437f5f..7f912147a 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java @@ -18,11 +18,11 @@ */ package net.emustudio.plugins.device.mits88dcdd.gui; -import net.emustudio.emulib.runtime.settings.PluginSettings; +import net.emustudio.emulib.plugins.PluginInitializationException; import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; -import net.emustudio.plugins.device.mits88dcdd.SettingsConstants; +import net.emustudio.plugins.device.mits88dcdd.DiskSettings; import net.emustudio.plugins.device.mits88dcdd.drive.Drive; import net.emustudio.plugins.device.mits88dcdd.drive.DriveCollection; import org.slf4j.Logger; @@ -30,13 +30,15 @@ import javax.swing.*; import javax.swing.border.TitledBorder; -import java.awt.event.KeyEvent; +import java.awt.event.*; import java.io.FileNotFoundException; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.Optional; -import static net.emustudio.plugins.device.mits88dcdd.DeviceImpl.*; +import static net.emustudio.plugins.device.mits88dcdd.DiskSettings.*; import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_PLAIN; import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; @@ -44,108 +46,124 @@ public class SettingsDialog extends JDialog { private final static Logger LOGGER = LoggerFactory.getLogger(SettingsDialog.class); private final Dialogs dialogs; - private final PluginSettings settings; + private final DiskSettings settings; private final DriveCollection drives; - public SettingsDialog(JFrame parent, PluginSettings settings, DriveCollection drives, Dialogs dialogs) { + private final List sectorsPerTrack = new ArrayList<>(); + private final List sectorSizes = new ArrayList<>(); + private final List images = new ArrayList<>(); + + public SettingsDialog(JFrame parent, DiskSettings settings, DriveCollection drives, Dialogs dialogs) { super(parent, true); this.settings = Objects.requireNonNull(settings); this.drives = Objects.requireNonNull(drives); this.dialogs = Objects.requireNonNull(dialogs); + readSettings(); + initComponents(); setLocationRelativeTo(parent); - readSettings(); cmbDrive.setSelectedIndex(0); - updateGUI(drives.get(0)); + updateGUI(0); } private void readSettings() { - if (settings.contains(SettingsConstants.PORT1_CPU)) { - txtPort1.setText(String.valueOf(settings.getInt(SettingsConstants.PORT1_CPU, DEFAULT_CPU_PORT1))); - } - if (settings.contains(SettingsConstants.PORT2_CPU)) { - txtPort2.setText(String.valueOf(settings.getInt(SettingsConstants.PORT2_CPU, DEFAULT_CPU_PORT2))); - } - if (settings.contains(SettingsConstants.PORT3_CPU)) { - txtPort3.setText(String.valueOf(settings.getInt(SettingsConstants.PORT3_CPU, DEFAULT_CPU_PORT3))); - } + txtPort1.setText(String.format("0x%02X", settings.getPort1CPU())); + txtPort2.setText(String.format("0x%02X", settings.getPort2CPU())); + txtPort3.setText(String.format("0x%02X", settings.getPort3CPU())); + + sectorsPerTrack.clear(); + sectorSizes.clear(); + images.clear(); + drives.foreach((i, drive) -> { + DiskSettings.DriveSettings driveSettings = settings.getDriveSettings(i); + sectorsPerTrack.add(String.valueOf(driveSettings.sectorsPerTrack)); + sectorSizes.add(String.valueOf(driveSettings.sectorSize)); + images.add(Optional.ofNullable(driveSettings.imagePath).orElse("")); + return null; + }); } - private void writeSettings() { + private void saveSettings(int parsedPort1, int parsedPort2, int parsedPort3) { RadixUtils radixUtils = RadixUtils.getInstance(); try { - settings.setInt(SettingsConstants.PORT1_CPU, radixUtils.parseRadix(txtPort1.getText())); - settings.setInt(SettingsConstants.PORT2_CPU, radixUtils.parseRadix(txtPort2.getText())); - settings.setInt(SettingsConstants.PORT3_CPU, radixUtils.parseRadix(txtPort3.getText())); + List parsedSectorsPerTracks = new ArrayList<>(); + List parsedSectorSizes = new ArrayList<>(); drives.foreach((i, drive) -> { - settings.setInt(SettingsConstants.SECTORS_COUNT + i, drive.getSectorsPerTrack()); - settings.setInt(SettingsConstants.SECTOR_LENGTH + i, drive.getSectorSize()); - - Path imagePath = drive.getImagePath(); - if (imagePath != null) { - settings.setString(SettingsConstants.IMAGE + i, imagePath.toAbsolutePath().toString()); - } else { - settings.remove(SettingsConstants.IMAGE + i); + parsedSectorsPerTracks.add(radixUtils.parseRadix(sectorsPerTrack.get(i))); + parsedSectorSizes.add(radixUtils.parseRadix(sectorSizes.get(i))); + return null; + }); + + settings.setPort1CPU(parsedPort1); + settings.setPort2CPU(parsedPort2); + settings.setPort3CPU(parsedPort3); + + drives.foreach((i, drive) -> { + String nullablePath = images.get(i); + if (nullablePath.equals("")) { + nullablePath = null; } + DiskSettings.DriveSettings driveSettings = new DiskSettings.DriveSettings( + parsedSectorSizes.get(i), parsedSectorsPerTracks.get(i), nullablePath + ); + settings.setDriveSettings(i, driveSettings); + drive.setDriveSettings(driveSettings); return null; }); + drives.reattach(); } catch (RuntimeException e) { LOGGER.error("Could not write " + DIALOG_TITLE + " settings", e); - dialogs.showError("Could not write settings. Please see log for more details.", DIALOG_TITLE); + dialogs.showError("Could not save settings. Please see log for more details.", DIALOG_TITLE); + } catch (PluginInitializationException e) { + LOGGER.error(DIALOG_TITLE + ": Could not re-attach CPU ports", e); + dialogs.showError("Could not re-attach CPU ports. Please see log for more details.", DIALOG_TITLE); } } - private void updateGUI(Drive drive) { - txtSectorLength.setText(String.valueOf(drive.getSectorSize())); - txtSectorsCount.setText(String.valueOf(drive.getSectorsPerTrack())); - - Path imagePath = drive.getImagePath(); - Optional.ofNullable(imagePath).ifPresentOrElse(path -> { - txtImageFile.setText(path.toAbsolutePath().toString()); - btnUnmount.setEnabled(true); - }, () -> { - txtImageFile.setText(""); - btnUnmount.setEnabled(false); - }); + private void updateGUI(int index) { + txtSectorSize.setText(sectorSizes.get(index)); + txtSectorsPerTrack.setText(sectorsPerTrack.get(index)); + + Optional + .of(images.get(index)) + .filter(p -> !p.equals("")) + .map(Path::of) + .ifPresentOrElse(path -> { + txtImageFile.setText(path.toAbsolutePath().toString()); + btnUnmount.setEnabled(true); + }, () -> { + txtImageFile.setText(""); + btnUnmount.setEnabled(false); + }); } private void initComponents() { JTabbedPane jTabbedPane1 = new JTabbedPane(); JPanel panelImages = new JPanel(); - cmbDrive = new JComboBox<>(); - JLabel jLabel1 = new JLabel(); - txtImageFile = new JTextField(); - JButton btnBrowse = new JButton(); - JPanel jPanel1 = new JPanel(); - btnMount = new JButton(); - btnUnmount = new JButton(); - JLabel jLabel2 = new JLabel(); + JLabel jLabel1 = new JLabel("Image file name:"); + JButton btnBrowse = new JButton("Browse..."); + JPanel panelImage = new JPanel(); + JLabel jLabel2 = new JLabel("Disk drive:"); JPanel jPanel3 = new JPanel(); - JLabel jLabel10 = new JLabel(); - JLabel jLabel11 = new JLabel(); - JButton btnDefaultParams = new JButton(); - txtSectorsCount = new JTextField(); - txtSectorLength = new JTextField(); + JLabel jLabel10 = new JLabel("Sectors per track:"); + JLabel jLabel11 = new JLabel("Sector size:"); + JButton btnDefaultParams = new JButton("Change to Default"); JPanel panelPorts = new JPanel(); JPanel jPanel2 = new JPanel(); - JLabel jLabel3 = new JLabel(); - JLabel jLabel4 = new JLabel(); - JLabel jLabel5 = new JLabel(); - JLabel jLabel6 = new JLabel(); - txtPort1 = new JTextField(); - txtPort2 = new JTextField(); - txtPort3 = new JTextField(); - JLabel jLabel7 = new JLabel(); - JLabel jLabel8 = new JLabel(); - JLabel jLabel9 = new JLabel(); - JButton btnDefault = new JButton(); - JButton btnOK = new JButton(); - chkSaveSettings = new JCheckBox(); + JLabel jLabel3 = new JLabel("Settings in this tab will be reflected after the restart of emuStudio."); + JLabel jLabel4 = new JLabel("Port 1:"); + JLabel jLabel5 = new JLabel("Port 2:"); + JLabel jLabel6 = new JLabel("Port 3:"); + JLabel jLabel7 = new JLabel("(IN: flags, OUT: select/unselect drive)"); + JLabel jLabel8 = new JLabel("(IN: current sector, OUT: set flags)"); + JLabel jLabel9 = new JLabel("(IN: read data, OUT: write data)"); + JButton btnDefault = new JButton("Change to Default"); + JButton btnSave = new JButton("Save"); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); @@ -157,68 +175,53 @@ private void initComponents() { cmbDrive.setModel(new DefaultComboBoxModel<>(new String[]{"Drive 0 (A)", "Drive 1 (B)", "Drive 2 (C)", "Drive 3 (D)", "Drive 4 (E)", "Drive 5 (F)", "Drive 6 (G)", "Drive 7 (H)", "Drive 8 (I)", "Drive 9 (J)", "Drive 10 (K)", "Drive 11 (L)", "Drive 12 (M)", "Drive 13 (N)", "Drive 14 (O)", "Drive 15 (P)"})); cmbDrive.addItemListener(this::cmbDriveItemStateChanged); - jLabel1.setText("Image file name:"); - - txtImageFile.addInputMethodListener(new java.awt.event.InputMethodListener() { - public void inputMethodTextChanged(java.awt.event.InputMethodEvent evt) { + txtImageFile.addInputMethodListener(new InputMethodListener() { + public void inputMethodTextChanged(InputMethodEvent evt) { txtImageFileInputMethodTextChanged(); } - public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { + public void caretPositionChanged(InputMethodEvent evt) { } }); - btnBrowse.setText("Browse..."); btnBrowse.addActionListener(this::btnBrowseActionPerformed); - jPanel1.setBorder(BorderFactory.createTitledBorder( + panelImage.setBorder(BorderFactory.createTitledBorder( null, "Image operations", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, DIALOG_PLAIN )); - btnMount.setText("Mount"); btnMount.addActionListener(this::btnMountActionPerformed); - - btnUnmount.setText("Umount"); btnUnmount.addActionListener(this::btnUnmountActionPerformed); - GroupLayout jPanel1Layout = new GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() + GroupLayout panelImageLayout = new GroupLayout(panelImage); + panelImage.setLayout(panelImageLayout); + panelImageLayout.setHorizontalGroup( + panelImageLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelImageLayout.createSequentialGroup() .addContainerGap() .addComponent(btnMount) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnUnmount) .addContainerGap(23, Short.MAX_VALUE)) ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() + panelImageLayout.setVerticalGroup( + panelImageLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelImageLayout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addGroup(panelImageLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(btnMount) .addComponent(btnUnmount)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - jLabel2.setText("Disk drive:"); - jPanel3.setBorder(BorderFactory.createTitledBorder( null, "Drive parameters", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, DIALOG_PLAIN )); - jLabel10.setText("Sectors count:"); - jLabel11.setText("Sector length:"); - - btnDefaultParams.setText("Change to Default"); btnDefaultParams.addActionListener(this::btnDefaultParamsActionPerformed); - txtSectorsCount.setText("32"); - txtSectorLength.setText("137"); - GroupLayout jPanel3Layout = new GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( @@ -233,8 +236,8 @@ public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { .addComponent(jLabel11)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(txtSectorsCount) - .addComponent(txtSectorLength, GroupLayout.DEFAULT_SIZE, 121, Short.MAX_VALUE)))) + .addComponent(txtSectorsPerTrack) + .addComponent(txtSectorSize, GroupLayout.DEFAULT_SIZE, 121, Short.MAX_VALUE)))) .addContainerGap(58, Short.MAX_VALUE)) ); jPanel3Layout.setVerticalGroup( @@ -243,11 +246,11 @@ public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { .addContainerGap() .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(jLabel10) - .addComponent(txtSectorsCount, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addComponent(txtSectorsPerTrack, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(jLabel11) - .addComponent(txtSectorLength, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addComponent(txtSectorSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addComponent(btnDefaultParams) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) @@ -273,7 +276,7 @@ public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { .addGroup(panelImagesLayout.createSequentialGroup() .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(panelImage, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addContainerGap()) ); panelImagesLayout.setVerticalGroup( @@ -294,14 +297,13 @@ public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { .addGroup(panelImagesLayout.createSequentialGroup() .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(panelImage, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); jTabbedPane1.addTab("Disk Images", panelImages); jPanel2.setBorder(BorderFactory.createTitledBorder("Note")); - jLabel3.setText("Settings in this tab will be reflected after the restart of emuStudio."); GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); @@ -320,22 +322,6 @@ public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - jLabel4.setText("Port 1:"); - jLabel5.setText("Port 2:"); - jLabel5.setToolTipText(""); - jLabel6.setText("Port 3:"); - - txtPort1.setText("0x08"); - txtPort2.setText("0x09"); - txtPort2.setToolTipText(""); - - txtPort3.setText("0x0A"); - - jLabel7.setText("(IN: flags, OUT: select/unselect drive)"); - jLabel8.setText("(IN: current sector, OUT: set flags)"); - jLabel9.setText("(IN: read data, OUT: write data)"); - - btnDefault.setText("Change to Default"); btnDefault.addActionListener(this::btnDefaultActionPerformed); GroupLayout panelPortsLayout = new GroupLayout(panelPorts); @@ -398,12 +384,7 @@ public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { ); jTabbedPane1.addTab("CPU Ports", panelPorts); - - btnOK.setText("OK"); - btnOK.addActionListener(this::btnOKActionPerformed); - - chkSaveSettings.setSelected(true); - chkSaveSettings.setText("Save settings to the file"); + btnSave.addActionListener(this::btnOKActionPerformed); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); @@ -414,9 +395,7 @@ public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(jTabbedPane1) .addGroup(layout.createSequentialGroup() - .addComponent(chkSaveSettings) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnOK, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE))) + .addComponent(btnSave, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE))) .addContainerGap()) ); layout.setVerticalGroup( @@ -425,31 +404,33 @@ public void caretPositionChanged(java.awt.event.InputMethodEvent evt) { .addComponent(jTabbedPane1) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(btnOK) - .addComponent(chkSaveSettings)) + .addComponent(btnSave)) .addContainerGap()) ); pack(); } - private void cmbDriveItemStateChanged(java.awt.event.ItemEvent evt) { - updateGUI(drives.get(cmbDrive.getSelectedIndex())); + private void cmbDriveItemStateChanged(ItemEvent evt) { + updateGUI(cmbDrive.getSelectedIndex()); } private void txtImageFileInputMethodTextChanged() { btnMount.setEnabled(!txtImageFile.getText().equals("")); } - private void btnUnmountActionPerformed(java.awt.event.ActionEvent evt) { - Drive drive = drives.get(cmbDrive.getSelectedIndex()); + private void btnUnmountActionPerformed(ActionEvent evt) { + int index = cmbDrive.getSelectedIndex(); + Drive drive = drives.get(index); drive.umount(); - updateGUI(drive); + updateGUI(index); } - private void btnMountActionPerformed(java.awt.event.ActionEvent evt) { - Drive drive = drives.get(cmbDrive.getSelectedIndex()); + private void btnMountActionPerformed(ActionEvent evt) { + int index = cmbDrive.getSelectedIndex(); + Drive drive = drives.get(index); try { + images.set(index, txtImageFile.getText()); drive.mount(Path.of(txtImageFile.getText())); } catch (FileNotFoundException e) { dialogs.showError("Could not mount file. File is either not found, is directory, or is not readable.", "Mount image"); @@ -459,15 +440,14 @@ private void btnMountActionPerformed(java.awt.event.ActionEvent evt) { dialogs.showError("Could not mount file. Please see log file for details", "Mount image"); txtImageFile.grabFocus(); } - updateGUI(drive); + updateGUI(index); } - private void btnBrowseActionPerformed(java.awt.event.ActionEvent evt) { - int driveIndex = cmbDrive.getSelectedIndex(); - Path imagePath = drives.get(driveIndex).getImagePath(); - + private void btnBrowseActionPerformed(ActionEvent evt) { Path currentDirectory = Optional - .ofNullable(imagePath) + .of(images.get(cmbDrive.getSelectedIndex())) + .filter(p -> !p.isEmpty()) + .map(Path::of) .orElse(Path.of(System.getProperty("user.dir"))); dialogs.chooseFile( @@ -476,32 +456,38 @@ private void btnBrowseActionPerformed(java.awt.event.ActionEvent evt) { ).ifPresent(path -> txtImageFile.setText(path.toString())); } - private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { + private void btnOKActionPerformed(ActionEvent evt) { RadixUtils radixUtils = RadixUtils.getInstance(); JTextField textField = null; String name = ""; - Drive drive = drives.get(cmbDrive.getSelectedIndex()); + int index = cmbDrive.getSelectedIndex(); + int parsedPort1; + int parsedPort2; + int parsedPort3; + try { textField = txtPort1; name = "Port1"; - radixUtils.parseRadix(txtPort1.getText()); - + parsedPort1 = radixUtils.parseRadix(txtPort1.getText()); textField = txtPort2; name = "Port2"; - radixUtils.parseRadix(txtPort2.getText()); - + parsedPort2 = radixUtils.parseRadix(txtPort2.getText()); textField = txtPort3; name = "Port3"; - radixUtils.parseRadix(txtPort3.getText()); + parsedPort3 = radixUtils.parseRadix(txtPort3.getText()); - textField = txtSectorsCount; - name = "Sectors count"; - drive.setSectorsPerTrack(radixUtils.parseRadix(txtSectorsCount.getText())); + textField = txtSectorsPerTrack; + name = "Sectors per track"; + radixUtils.parseRadix(txtSectorsPerTrack.getText()); - textField = txtSectorLength; - name = "Sector length"; - drive.setSectorSize(radixUtils.parseRadix(txtSectorLength.getText())); + textField = txtSectorSize; + name = "Sector size"; + radixUtils.parseRadix(txtSectorSize.getText()); + + sectorsPerTrack.set(index, txtSectorsPerTrack.getText()); + sectorSizes.set(index, txtSectorSize.getText()); + images.set(index, txtImageFile.getText()); } catch (NumberFormatException e) { dialogs.showError(name + ": Invalid number format", "Save settings"); textField.grabFocus(); @@ -512,31 +498,28 @@ private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { return; } - if (chkSaveSettings.isSelected()) { - writeSettings(); - } + saveSettings(parsedPort1, parsedPort2, parsedPort3); dispose(); } - private void btnDefaultActionPerformed(java.awt.event.ActionEvent evt) { + private void btnDefaultActionPerformed(ActionEvent evt) { txtPort1.setText(String.format("0x%02X", DEFAULT_CPU_PORT1)); txtPort2.setText(String.format("0x%02X", DEFAULT_CPU_PORT2)); txtPort3.setText(String.format("0x%02X", DEFAULT_CPU_PORT3)); } - private void btnDefaultParamsActionPerformed(java.awt.event.ActionEvent evt) { - txtSectorsCount.setText(String.valueOf(Drive.DEFAULT_SECTORS_PER_TRACK)); - txtSectorLength.setText(String.valueOf(Drive.DEFAULT_SECTOR_SIZE)); + private void btnDefaultParamsActionPerformed(ActionEvent evt) { + txtSectorsPerTrack.setText(String.valueOf(DiskSettings.DEFAULT_SECTORS_PER_TRACK)); + txtSectorSize.setText(String.valueOf(DiskSettings.DEFAULT_SECTOR_SIZE)); } - private JButton btnMount; - private JButton btnUnmount; - private JCheckBox chkSaveSettings; - private JComboBox cmbDrive; - private JTextField txtImageFile; - private JTextField txtPort1; - private JTextField txtPort2; - private JTextField txtPort3; - private JTextField txtSectorLength; - private JTextField txtSectorsCount; + private final JButton btnMount = new JButton("Mount"); + private final JButton btnUnmount = new JButton("Umount"); + private final JComboBox cmbDrive = new JComboBox<>(); + private final JTextField txtImageFile = new JTextField(); + private final JTextField txtPort1 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT1)); + private final JTextField txtPort2 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT2)); + private final JTextField txtPort3 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT3)); + private final JTextField txtSectorSize = new JTextField(String.valueOf(DiskSettings.DEFAULT_SECTOR_SIZE)); + private final JTextField txtSectorsPerTrack = new JTextField(String.valueOf(DiskSettings.DEFAULT_SECTORS_PER_TRACK)); } diff --git a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DeviceImplTest.java b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DeviceImplTest.java index 1511a1553..cc973512c 100644 --- a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DeviceImplTest.java +++ b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DeviceImplTest.java @@ -18,9 +18,12 @@ */ package net.emustudio.plugins.device.mits88dcdd; +import net.emustudio.emulib.plugins.PluginInitializationException; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; +import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.settings.PluginSettings; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -33,14 +36,23 @@ public class DeviceImplTest { private DeviceImpl device; @Before - public void setup() { + public void setup() throws PluginInitializationException { + Context8080 cpu = mock(Context8080.class); + expect(cpu.attachDevice(anyObject(), anyInt())).andReturn(true).anyTimes(); + cpu.detachDevice(anyInt()); + expectLastCall().anyTimes(); + replay(cpu); + ContextPool contextPool = createNiceMock(ContextPool.class); + expect(contextPool.getCPUContext(0, Context8080.class)).andReturn(cpu).once(); replay(contextPool); ApplicationApi applicationApi = createNiceMock(ApplicationApi.class); expect(applicationApi.getContextPool()).andReturn(contextPool).anyTimes(); + expect(applicationApi.getDialogs()).andReturn(mock(Dialogs.class)).once(); replay(applicationApi); this.device = new DeviceImpl(0, applicationApi, PluginSettings.UNAVAILABLE); + device.initialize(); } @After diff --git a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java index e4391646c..321f97152 100644 --- a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java +++ b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java @@ -18,6 +18,7 @@ */ package net.emustudio.plugins.device.mits88dcdd; +import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.device.mits88dcdd.drive.Drive; import net.emustudio.plugins.device.mits88dcdd.drive.DriveListener; import net.emustudio.plugins.device.mits88dcdd.drive.DriveParameters; @@ -36,7 +37,7 @@ public class DriveTest { private final static short SECTOR_SIZE = 2; - private final static short SECTORS_COUNT = 2; + private final static short SECTORS_PER_TRACK = 2; private final static short TRACKS_COUNT = 2; @Rule @@ -47,7 +48,7 @@ public class DriveTest { public void prepareTestImage() throws Exception { testImageFile = folder.newFile().toPath(); try (RandomAccessFile raf = new RandomAccessFile(testImageFile.toFile(), "rw")) { - for (int i = 0; i < SECTOR_SIZE * SECTORS_COUNT * TRACKS_COUNT; i++) { + for (int i = 0; i < SECTOR_SIZE * SECTORS_PER_TRACK * TRACKS_COUNT; i++) { raf.write(i); } } @@ -55,7 +56,7 @@ public void prepareTestImage() throws Exception { private void assertImageContent(int dataStart) throws Exception { try (RandomAccessFile raf = new RandomAccessFile(testImageFile.toFile(), "r")) { - for (int i = 0; i < SECTOR_SIZE * SECTORS_COUNT * TRACKS_COUNT; i++) { + for (int i = 0; i < SECTOR_SIZE * SECTORS_PER_TRACK * TRACKS_COUNT; i++) { assertEquals(dataStart++, raf.read()); } } @@ -63,7 +64,7 @@ private void assertImageContent(int dataStart) throws Exception { @Test public void testInitialDriveParameters() { - Drive drive = new Drive(0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); DriveParameters params = drive.getDriveParameters(); assertEquals(0, params.sector); @@ -76,22 +77,22 @@ public void testInitialDriveParameters() { @Test public void testMountValidImage() throws IOException { - new Drive(0).mount(testImageFile); + new Drive(0, mock(Context8080.class), () -> 0).mount(testImageFile); } @Test(expected = NullPointerException.class) public void testMountImageNullArgument() throws IOException { - new Drive(0).mount(null); + new Drive(0, mock(Context8080.class), () -> 0).mount(null); } @Test public void testUnmountWithoutMountHasNoEffect() { - new Drive(0).umount(); + new Drive(0, mock(Context8080.class), () -> 0).umount(); } @Test public void testUnmountSelectedDriveDeselects() throws IOException { - Drive drive = new Drive(0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); drive.mount(testImageFile); drive.select(); @@ -101,7 +102,7 @@ public void testUnmountSelectedDriveDeselects() throws IOException { @Test public void testUmountClearsMountImageInDriveParams() throws IOException { - Drive drive = new Drive(0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); drive.mount(testImageFile); drive.umount(); @@ -111,9 +112,8 @@ public void testUmountClearsMountImageInDriveParams() throws IOException { @Test public void testDriveParametersAfterSelect() throws Exception { - Drive drive = new Drive(0); - drive.setSectorsPerTrack(SECTORS_COUNT); - drive.setSectorSize(SECTOR_SIZE); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null)); drive.mount(testImageFile); drive.select(); @@ -129,9 +129,8 @@ public void testDriveParametersAfterSelect() throws Exception { @Test public void testDriveParametersAfterSelectThenDeselect() throws Exception { - Drive drive = new Drive(0); - drive.setSectorsPerTrack(SECTORS_COUNT); - drive.setSectorSize(SECTOR_SIZE); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null)); drive.mount(testImageFile); drive.select(); @@ -148,21 +147,20 @@ public void testDriveParametersAfterSelectThenDeselect() throws Exception { @Test public void testSelectWithoutMount() { - Drive drive = new Drive(0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); drive.select(); assertFalse(drive.isSelected()); } @Test public void testDeselectWithoutSelectHasNoEffect() { - new Drive(0).deselect(); + new Drive(0, mock(Context8080.class), () -> 0).deselect(); } @Test public void testReadAllData() throws Exception { - Drive drive = new Drive(0); - drive.setSectorsPerTrack(SECTORS_COUNT); - drive.setSectorSize(SECTOR_SIZE); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null)); drive.mount(testImageFile); drive.select(); @@ -175,7 +173,7 @@ public void testReadAllData() throws Exception { // head load drive.writeToPort2((short) 0x04); - for (int sector = 0; sector < SECTORS_COUNT; sector++) { + for (int sector = 0; sector < SECTORS_PER_TRACK; sector++) { assertEquals(sector, drive.getSector()); for (int offset = 0; offset < SECTOR_SIZE; offset++) { @@ -195,9 +193,8 @@ public void testReadAllData() throws Exception { @Test public void testWriteAllData() throws Exception { - Drive drive = new Drive(0); - drive.setSectorsPerTrack(SECTORS_COUNT); - drive.setSectorSize(SECTOR_SIZE); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null)); drive.mount(testImageFile); drive.select(); @@ -212,7 +209,7 @@ public void testWriteAllData() throws Exception { drive.writeToPort2((short) 0x04); assertEquals(0, drive.getPort1status() & 0x04); // head loaded - for (int sector = 0; sector < SECTORS_COUNT; sector++) { + for (int sector = 0; sector < SECTORS_PER_TRACK; sector++) { assertEquals(sector, drive.getSector()); // write enable @@ -246,7 +243,7 @@ public void testDriveListenerIsCalledWhenDiskIsSelected() throws Exception { expectLastCall().once(); replay(listener); - Drive drive = new Drive(0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); drive.addDriveListener(listener); drive.mount(testImageFile); drive.select(); @@ -263,7 +260,7 @@ public void testDriveListenerIsCalledWhenDiskIsDeselected() throws Exception { expectLastCall().once(); replay(listener); - Drive drive = new Drive(0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); drive.mount(testImageFile); drive.select(); drive.addDriveListener(listener); @@ -279,7 +276,7 @@ public void testDriveListenerIsCalledWhenSectorNumberIsChanged() throws Exceptio expectLastCall().once(); replay(listener); - Drive drive = new Drive(0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); drive.mount(testImageFile); drive.select(); drive.addDriveListener(listener); @@ -295,7 +292,7 @@ public void testDriveListenerIsCalledWhenDataAreRead() throws Exception { expectLastCall().once(); replay(listener); - Drive drive = new Drive(0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); drive.mount(testImageFile); drive.select(); drive.writeToPort2((short) 0x04); @@ -312,7 +309,7 @@ public void testDriveListenerIsCalledWhenDataAreWritten() throws Exception { expectLastCall().once(); replay(listener); - Drive drive = new Drive(0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); drive.mount(testImageFile); drive.select(); drive.writeToPort2((short) 0x04); @@ -330,7 +327,7 @@ public void testDriveListenerIsCalledWhenFlagsAreSet() throws Exception { expectLastCall().once(); replay(listener); - Drive drive = new Drive(0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0); drive.mount(testImageFile); drive.select(); drive.addDriveListener(listener); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java index 3696f41a1..40c67832f 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java @@ -19,7 +19,6 @@ package net.emustudio.plugins.device.mits88sio; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; import java.util.Objects; diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java index 892ed8ec6..fb04a26eb 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java @@ -31,7 +31,6 @@ import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.device.mits88sio.gui.SettingsDialog; import net.emustudio.plugins.device.mits88sio.gui.SioGui; -import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java index c05a67338..6d1bc21a4 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnit.java @@ -19,7 +19,6 @@ package net.emustudio.plugins.device.mits88sio; import net.emustudio.plugins.cpu.intel8080.api.Context8080; -import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; import java.util.ArrayList; import java.util.List; diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnitSettings.java similarity index 98% rename from plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java rename to plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnitSettings.java index 99679adbb..4b24ab6c5 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SioUnitSettings.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnitSettings.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.mits88sio.settings; +package net.emustudio.plugins.device.mits88sio; import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.settings.BasicSettings; @@ -66,6 +66,12 @@ public enum MAP_CHAR { UNCHANGED } + @FunctionalInterface + public interface SettingsObserver { + + void settingsChanged(); + } + public SioUnitSettings(BasicSettings settings) { this.settings = Objects.requireNonNull(settings); this.isClearInputBit8 = settings.getBoolean(KEY_CLEAR_INPUT_BIT8, false); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java index 3db358baf..654db2aee 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java @@ -21,7 +21,6 @@ import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.cpu.intel8080.api.Context8080; -import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; import net.jcip.annotations.ThreadSafe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java index fed7e7ba5..122db0264 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; +import net.emustudio.plugins.device.mits88sio.SioUnitSettings; import javax.swing.*; import javax.swing.GroupLayout.Alignment; diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SettingsObserver.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SettingsObserver.java deleted file mode 100644 index 4b3464680..000000000 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/settings/SettingsObserver.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2022 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.device.mits88sio.settings; - -@FunctionalInterface -public interface SettingsObserver { - - void settingsChanged(); -} diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java index aafd24729..0bf7d3307 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DataChannelTest.java @@ -18,7 +18,6 @@ */ package net.emustudio.plugins.device.mits88sio; -import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; import org.junit.Test; import static org.easymock.EasyMock.*; diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java index 83bec3904..e97a46dd5 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java @@ -19,7 +19,6 @@ package net.emustudio.plugins.device.mits88sio; import net.emustudio.plugins.cpu.intel8080.api.Context8080; -import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; import org.junit.Test; import java.util.List; diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java index 7aa7581ac..c4ea24833 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java @@ -19,7 +19,6 @@ package net.emustudio.plugins.device.mits88sio; import net.emustudio.plugins.cpu.intel8080.api.Context8080; -import net.emustudio.plugins.device.mits88sio.settings.SioUnitSettings; import org.junit.Before; import org.junit.Test; From 66488ee9894f19f991b43a91263e99e823da169e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 3 Dec 2022 12:48:03 +0100 Subject: [PATCH 227/314] [#162] 88-dcdd: rewrite settings gui --- .../device/mits88dcdd/DiskSettings.java | 13 +- .../device/mits88dcdd/drive/Drive.java | 16 +- .../device/mits88dcdd/gui/DiskGui.java | 4 +- .../device/mits88dcdd/gui/DriveButton.java | 19 +- .../device/mits88dcdd/gui/SettingsDialog.java | 830 ++++++++++-------- .../plugins/device/mits88dcdd/gui/off.png | Bin 0 -> 469 bytes .../plugins/device/mits88dcdd/gui/on.png | Bin 0 -> 557 bytes .../mits88dcdd/gui/{on.gif => selected.gif} | Bin .../gui/{off.gif => unselected.gif} | Bin .../plugins/device/mits88dcdd/DriveTest.java | 8 +- .../device/mits88sio/gui/SettingsDialog.java | 2 +- 11 files changed, 507 insertions(+), 385 deletions(-) create mode 100644 plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/off.png create mode 100644 plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/on.png rename plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/{on.gif => selected.gif} (100%) rename plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/{off.gif => unselected.gif} (100%) diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java index c9b2f11bd..ac1600533 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java @@ -21,6 +21,7 @@ public class DiskSettings { private static final String KEY_SECTORS_PER_TRACK = "sectorsPerTrack"; private static final String KEY_SECTOR_SIZE = "sectorSize"; private static final String KEY_IMAGE = "image"; + private static final String KEY_IMAGE_MOUNTED = "imageMounted"; private static final String KEY_INTERRUPT_VECTOR = "interruptVector"; private final BasicSettings settings; @@ -41,17 +42,18 @@ public interface SettingsObserver { @Immutable public static class DriveSettings { public final static DriveSettings DEFAULT = new DriveSettings( - DEFAULT_SECTOR_SIZE, DEFAULT_SECTORS_PER_TRACK, null - ); + DEFAULT_SECTOR_SIZE, DEFAULT_SECTORS_PER_TRACK, null, false); public final int sectorSize; public final int sectorsPerTrack; public final String imagePath; + public final boolean mounted; - public DriveSettings(int sectorSize, int sectorsPerTrack, String imagePath) { + public DriveSettings(int sectorSize, int sectorsPerTrack, String imagePath, boolean mounted) { this.sectorSize = sectorSize; this.sectorsPerTrack = sectorsPerTrack; this.imagePath = imagePath; + this.mounted = mounted; } } @@ -67,8 +69,8 @@ public DiskSettings(BasicSettings settings) { driveSettings[i] = new DriveSettings( settings.getInt(KEY_SECTOR_SIZE + i, DEFAULT_SECTOR_SIZE), settings.getInt(KEY_SECTORS_PER_TRACK + i, DEFAULT_SECTORS_PER_TRACK), - settings.getString(KEY_IMAGE + i, null) - ); + settings.getString(KEY_IMAGE + i, null), + settings.getBoolean(KEY_IMAGE_MOUNTED + i, false)); } } @@ -97,6 +99,7 @@ public void setDriveSettings(int drive, DriveSettings driveSettings) { } else { settings.setString(KEY_IMAGE + drive, driveSettings.imagePath); } + settings.setBoolean(KEY_IMAGE_MOUNTED + drive, driveSettings.mounted); notifySettingsChanged(); } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java index 75571e7d4..ff5c2ba61 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java @@ -76,7 +76,7 @@ public class Drive { private int sectorOffset; private DiskSettings.DriveSettings driveSettings = DiskSettings.DriveSettings.DEFAULT; - private Path mountedFloppy = null; + private Path mountedImage = null; private SeekableByteChannel imageChannel; private boolean selected = false; @@ -130,7 +130,7 @@ public void addDriveListener(DriveListener listener) { public DriveParameters getDriveParameters() { return inReadLock( - () -> new DriveParameters(port1status, port2status, track, sector, getOffset(), mountedFloppy) + () -> new DriveParameters(port1status, port2status, track, sector, getOffset(), mountedImage) ); } @@ -139,7 +139,7 @@ public boolean isSelected() { } public void select() { - if (mountedFloppy == null) { + if (mountedImage == null) { LOGGER.warn("[drive={}] Could not select drive; image is not mounted", driveIndex); } else { selectInternal(); @@ -180,7 +180,7 @@ public void mount(Path imagePath) throws IOException { } umount(); - this.mountedFloppy = imagePath; + this.mountedImage = imagePath; Set optionSet = new HashSet<>(); optionSet.add(StandardOpenOption.READ); optionSet.add(StandardOpenOption.WRITE); @@ -188,11 +188,15 @@ public void mount(Path imagePath) throws IOException { imageChannel = Files.newByteChannel(imagePath, optionSet); } + public boolean isMounted() { + return mountedImage != null; + } + public void umount() { if (inReadLock(() -> selected)) { deselect(); } - mountedFloppy = null; + mountedImage = null; try { if (imageChannel != null) { imageChannel.close(); @@ -315,7 +319,7 @@ public void writeData(int data) { } public byte readData() { - if (mountedFloppy == null) { + if (mountedImage == null) { return 0; } byte result = inWriteLock(() -> { diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java index fb9da3197..fd1ed46ec 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java @@ -95,9 +95,9 @@ private void updateDriveInfo(DriveParameters parameters) { public void select(int driveIndex, boolean selected) { if (driveIndex >= 0 && driveIndex < driveButtons.length) { if (selected) { - driveButtons[driveIndex].turnOn(); + driveButtons[driveIndex].setSelected(); } else { - driveButtons[driveIndex].turnOff(); + driveButtons[driveIndex].setUnselected(); } } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DriveButton.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DriveButton.java index 2eebfa6a6..b353fb972 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DriveButton.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DriveButton.java @@ -23,20 +23,23 @@ import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.MONOSPACED_PLAIN; public class DriveButton extends JToggleButton { - private final static String ICON_OFF = "/net/emustudio/plugins/device/mits88dcdd/gui/off.gif"; - private final static String ICON_ON = "/net/emustudio/plugins/device/mits88dcdd/gui/on.gif"; + private final static ImageIcon ICON_OFF = new ImageIcon(DriveButton.class.getResource("/net/emustudio/plugins/device/mits88dcdd/gui/unselected.gif")); + private final static ImageIcon ICON_ON = new ImageIcon(DriveButton.class.getResource("/net/emustudio/plugins/device/mits88dcdd/gui/selected.gif")); public DriveButton(String text, Runnable action) { - super(text, new ImageIcon(DriveButton.class.getResource(ICON_OFF))); - addActionListener(actionEvent -> action.run()); + super(text, ICON_OFF); + setToolTipText("Disk is unselected"); setFont(MONOSPACED_PLAIN); + addActionListener(actionEvent -> action.run()); } - public void turnOn() { - setIcon(new ImageIcon(getClass().getResource(ICON_ON))); + public void setSelected() { + setIcon(ICON_ON); + setToolTipText("Disk is selected"); } - public void turnOff() { - setIcon(new ImageIcon(getClass().getResource(ICON_OFF))); + public void setUnselected() { + setIcon(ICON_OFF); + setToolTipText("Disk is unselected"); } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java index 7f912147a..a74d4b620 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java @@ -23,35 +23,58 @@ import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; import net.emustudio.plugins.device.mits88dcdd.DiskSettings; -import net.emustudio.plugins.device.mits88dcdd.drive.Drive; import net.emustudio.plugins.device.mits88dcdd.drive.DriveCollection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import javax.swing.border.TitledBorder; -import java.awt.event.*; -import java.io.FileNotFoundException; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.KeyEvent; +import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Supplier; import static net.emustudio.plugins.device.mits88dcdd.DiskSettings.*; -import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_PLAIN; import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; public class SettingsDialog extends JDialog { private final static Logger LOGGER = LoggerFactory.getLogger(SettingsDialog.class); + private final static Font DRIVE_BUTTON_FONT = new Font("Monospaced", Font.PLAIN, 14); + private final static ImageIcon OFF_ICON = new ImageIcon(SettingsDialog.class.getResource("/net/emustudio/plugins/device/mits88dcdd/gui/off.png")); + private final static ImageIcon ON_ICON = new ImageIcon(SettingsDialog.class.getResource("/net/emustudio/plugins/device/mits88dcdd/gui/on.png")); private final Dialogs dialogs; private final DiskSettings settings; private final DriveCollection drives; - private final List sectorsPerTrack = new ArrayList<>(); - private final List sectorSizes = new ArrayList<>(); - private final List images = new ArrayList<>(); + private final List driveSettingsUI = new ArrayList<>(); + private final List driveButtons = new ArrayList<>(); + private int currentDriveIndex = 0; + + static class DriveSettingsUI { + String sectorsPerTrack; + String sectorSize; + String image; + boolean mounted; + + static DriveSettingsUI fromDriveSettings(DiskSettings.DriveSettings driveSettings) { + DriveSettingsUI dsui = new DriveSettingsUI(); + dsui.sectorsPerTrack = String.valueOf(driveSettings.sectorsPerTrack); + dsui.sectorSize = String.valueOf(driveSettings.sectorSize); + dsui.image = Optional.ofNullable(driveSettings.imagePath).orElse(""); + dsui.mounted = driveSettings.mounted; + return dsui; + } + } public SettingsDialog(JFrame parent, DiskSettings settings, DriveCollection drives, Dialogs dialogs) { super(parent, true); @@ -65,7 +88,24 @@ public SettingsDialog(JFrame parent, DiskSettings settings, DriveCollection driv initComponents(); setLocationRelativeTo(parent); - cmbDrive.setSelectedIndex(0); + driveButtons.add(btnA); + driveButtons.add(btnB); + driveButtons.add(btnC); + driveButtons.add(btnD); + driveButtons.add(btnE); + driveButtons.add(btnF); + driveButtons.add(btnG); + driveButtons.add(btnH); + driveButtons.add(btnI); + driveButtons.add(btnJ); + driveButtons.add(btnK); + driveButtons.add(btnL); + driveButtons.add(btnM); + driveButtons.add(btnN); + driveButtons.add(btnO); + driveButtons.add(btnP); + + btnA.setSelected(true); updateGUI(0); } @@ -73,319 +113,370 @@ private void readSettings() { txtPort1.setText(String.format("0x%02X", settings.getPort1CPU())); txtPort2.setText(String.format("0x%02X", settings.getPort2CPU())); txtPort3.setText(String.format("0x%02X", settings.getPort3CPU())); + spnInterruptVector.setValue(settings.getInterruptVector()); - sectorsPerTrack.clear(); - sectorSizes.clear(); - images.clear(); + driveSettingsUI.clear(); drives.foreach((i, drive) -> { DiskSettings.DriveSettings driveSettings = settings.getDriveSettings(i); - sectorsPerTrack.add(String.valueOf(driveSettings.sectorsPerTrack)); - sectorSizes.add(String.valueOf(driveSettings.sectorSize)); - images.add(Optional.ofNullable(driveSettings.imagePath).orElse("")); + DriveSettingsUI dsui = DriveSettingsUI.fromDriveSettings(driveSettings); + dsui.mounted = drive.isMounted(); + driveSettingsUI.add(dsui); return null; }); } - private void saveSettings(int parsedPort1, int parsedPort2, int parsedPort3) { - RadixUtils radixUtils = RadixUtils.getInstance(); + private void saveSettings() throws PluginInitializationException, RuntimeException { + int parsedPort1 = parseInt(txtPort1, "Port1", txtPort1::getText); + int parsedPort2 = parseInt(txtPort2, "Port2", txtPort2::getText); + int parsedPort3 = parseInt(txtPort3, "Port3", txtPort3::getText); + int interruptVector = ((Number) spnInterruptVector.getValue()).intValue(); - try { - List parsedSectorsPerTracks = new ArrayList<>(); - List parsedSectorSizes = new ArrayList<>(); + List parsedSectorsPerTracks = new ArrayList<>(); + List parsedSectorSizes = new ArrayList<>(); - drives.foreach((i, drive) -> { - parsedSectorsPerTracks.add(radixUtils.parseRadix(sectorsPerTrack.get(i))); - parsedSectorSizes.add(radixUtils.parseRadix(sectorSizes.get(i))); - return null; - }); + drives.foreach((i, drive) -> { + DriveSettingsUI dsui = driveSettingsUI.get(i); + JToggleButton driveButton = driveButtons.get(i); + parsedSectorsPerTracks.add(parseInt(driveButton, txtSectorsPerTrack, "Sectors per track", () -> dsui.sectorsPerTrack)); + parsedSectorSizes.add(parseInt(driveButton, txtSectorSize, "Sector size", () -> dsui.sectorSize)); + return null; + }); - settings.setPort1CPU(parsedPort1); - settings.setPort2CPU(parsedPort2); - settings.setPort3CPU(parsedPort3); + settings.setPort1CPU(parsedPort1); + settings.setPort2CPU(parsedPort2); + settings.setPort3CPU(parsedPort3); + settings.setInterruptVector(interruptVector); - drives.foreach((i, drive) -> { - String nullablePath = images.get(i); - if (nullablePath.equals("")) { - nullablePath = null; - } - DiskSettings.DriveSettings driveSettings = new DiskSettings.DriveSettings( - parsedSectorSizes.get(i), parsedSectorsPerTracks.get(i), nullablePath - ); - settings.setDriveSettings(i, driveSettings); - drive.setDriveSettings(driveSettings); - return null; - }); - drives.reattach(); - } catch (RuntimeException e) { - LOGGER.error("Could not write " + DIALOG_TITLE + " settings", e); - dialogs.showError("Could not save settings. Please see log for more details.", DIALOG_TITLE); - } catch (PluginInitializationException e) { - LOGGER.error(DIALOG_TITLE + ": Could not re-attach CPU ports", e); - dialogs.showError("Could not re-attach CPU ports. Please see log for more details.", DIALOG_TITLE); - } + drives.foreach((i, drive) -> { + DriveSettingsUI dsui = driveSettingsUI.get(i); + String nullablePath = dsui.image; + if (nullablePath != null && nullablePath.equals("")) { + nullablePath = null; + } + DiskSettings.DriveSettings driveSettings = new DiskSettings.DriveSettings( + parsedSectorSizes.get(i), parsedSectorsPerTracks.get(i), nullablePath, dsui.mounted); + settings.setDriveSettings(i, driveSettings); + drive.setDriveSettings(driveSettings); + return null; + }); + drives.reattach(); } private void updateGUI(int index) { - txtSectorSize.setText(sectorSizes.get(index)); - txtSectorsPerTrack.setText(sectorsPerTrack.get(index)); + this.currentDriveIndex = index; + DriveSettingsUI dsui = driveSettingsUI.get(index); + txtSectorSize.setText(dsui.sectorSize); + txtSectorsPerTrack.setText(dsui.sectorsPerTrack); Optional - .of(images.get(index)) + .ofNullable(dsui.image) .filter(p -> !p.equals("")) .map(Path::of) .ifPresentOrElse(path -> { txtImageFile.setText(path.toAbsolutePath().toString()); - btnUnmount.setEnabled(true); + btnMountUnmount.setSelected(dsui.mounted); + if (dsui.mounted) { + btnMountUnmount.setText("Unmount"); + } else { + btnMountUnmount.setText("Mount"); + } + driveButtons.get(index).setIcon(ON_ICON); }, () -> { txtImageFile.setText(""); - btnUnmount.setEnabled(false); + btnMountUnmount.setSelected(false); + btnMountUnmount.setText("Mount"); + driveButtons.get(index).setIcon(OFF_ICON); }); } - private void initComponents() { - JTabbedPane jTabbedPane1 = new JTabbedPane(); - JPanel panelImages = new JPanel(); - JLabel jLabel1 = new JLabel("Image file name:"); - JButton btnBrowse = new JButton("Browse..."); - JPanel panelImage = new JPanel(); - JLabel jLabel2 = new JLabel("Disk drive:"); - JPanel jPanel3 = new JPanel(); - JLabel jLabel10 = new JLabel("Sectors per track:"); - JLabel jLabel11 = new JLabel("Sector size:"); - JButton btnDefaultParams = new JButton("Change to Default"); - JPanel panelPorts = new JPanel(); - JPanel jPanel2 = new JPanel(); - JLabel jLabel3 = new JLabel("Settings in this tab will be reflected after the restart of emuStudio."); - JLabel jLabel4 = new JLabel("Port 1:"); - JLabel jLabel5 = new JLabel("Port 2:"); - JLabel jLabel6 = new JLabel("Port 3:"); - JLabel jLabel7 = new JLabel("(IN: flags, OUT: select/unselect drive)"); - JLabel jLabel8 = new JLabel("(IN: current sector, OUT: set flags)"); - JLabel jLabel9 = new JLabel("(IN: read data, OUT: write data)"); - JButton btnDefault = new JButton("Change to Default"); - JButton btnSave = new JButton("Save"); - - setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); - - setTitle(DIALOG_TITLE + " Settings"); - - jTabbedPane1.setFont(jTabbedPane1.getFont()); - - cmbDrive.setModel(new DefaultComboBoxModel<>(new String[]{"Drive 0 (A)", "Drive 1 (B)", "Drive 2 (C)", "Drive 3 (D)", "Drive 4 (E)", "Drive 5 (F)", "Drive 6 (G)", "Drive 7 (H)", "Drive 8 (I)", "Drive 9 (J)", "Drive 10 (K)", "Drive 11 (L)", "Drive 12 (M)", "Drive 13 (N)", "Drive 14 (O)", "Drive 15 (P)"})); - cmbDrive.addItemListener(this::cmbDriveItemStateChanged); - - txtImageFile.addInputMethodListener(new InputMethodListener() { - public void inputMethodTextChanged(InputMethodEvent evt) { - txtImageFileInputMethodTextChanged(); - } - - public void caretPositionChanged(InputMethodEvent evt) { - } - }); - - btnBrowse.addActionListener(this::btnBrowseActionPerformed); - - panelImage.setBorder(BorderFactory.createTitledBorder( - null, "Image operations", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - DIALOG_PLAIN - )); + private int parseInt(JComponent component, String name, Supplier text) { + RadixUtils radixUtils = RadixUtils.getInstance(); + try { + return radixUtils.parseRadix(text.get()); + } catch (NumberFormatException e) { + dialogs.showError(name + ": Invalid number format", "Save settings"); + component.grabFocus(); + throw e; + } catch (IllegalArgumentException e) { + dialogs.showError(name + " must be greater than 0", "Save settings"); + component.grabFocus(); + throw e; + } + } - btnMount.addActionListener(this::btnMountActionPerformed); - btnUnmount.addActionListener(this::btnUnmountActionPerformed); + private int parseInt(JToggleButton driveButton, JComponent component, String name, Supplier text) { + try { + return parseInt(component, name, text); + } catch (RuntimeException e) { + driveButton.setSelected(true); + throw e; + } + } - GroupLayout panelImageLayout = new GroupLayout(panelImage); - panelImage.setLayout(panelImageLayout); - panelImageLayout.setHorizontalGroup( - panelImageLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelImageLayout.createSequentialGroup() + private void initComponents() { + ButtonGroup buttonGroup1 = new ButtonGroup(); + JPanel panelDrive = new JPanel(); + JLabel lblDrive = new JLabel("Drive:"); + JLabel lblImage = new JLabel("Image:"); + JPanel panelImageParameters = new JPanel(); + JLabel lblSpt = new JLabel("Sectors per track:"); + JLabel lblSectorSize = new JLabel("Sector size:"); + JLabel lblBytes = new JLabel("bytes"); + JPanel panelCpu = new JPanel(); + JLabel lblPort1 = new JLabel("Port 1:"); + JLabel lblPort2 = new JLabel("Port 2:"); + JLabel lblPort3 = new JLabel("Port 3:"); + JLabel lblInterruptVector = new JLabel("Interrupt vector:"); + JLabel lblPort1In = new JLabel("(IN: Get flags"); + JLabel lblPort2In = new JLabel("(IN: Current sector"); + JLabel lblPort3In = new JLabel("(IN: Read data"); + JLabel lblNote = new JLabel("Set CPU ports and interrupt vector used by this device."); + JLabel lblPort1Out = new JLabel("OUT: Select/unselect drive)"); + JLabel lblPort2Out = new JLabel("OUT: Set flags)"); + JLabel lblPort3Out = new JLabel("OUT: Write data)"); + JLabel lblRange = new JLabel("(range 0-7)"); + + setTitle("88-DCDD Settings"); + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + rootPane.registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); + + Font bold = getFont().deriveFont(Font.BOLD); + + panelDrive.setBorder(BorderFactory.createTitledBorder(null, "Drive settings", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, bold)); + + setupDriveButton(buttonGroup1, btnA, 0); + setupDriveButton(buttonGroup1, btnB, 1); + setupDriveButton(buttonGroup1, btnC, 2); + setupDriveButton(buttonGroup1, btnD, 3); + setupDriveButton(buttonGroup1, btnE, 4); + setupDriveButton(buttonGroup1, btnF, 5); + setupDriveButton(buttonGroup1, btnG, 6); + setupDriveButton(buttonGroup1, btnH, 7); + setupDriveButton(buttonGroup1, btnI, 8); + setupDriveButton(buttonGroup1, btnJ, 9); + setupDriveButton(buttonGroup1, btnK, 10); + setupDriveButton(buttonGroup1, btnL, 11); + setupDriveButton(buttonGroup1, btnM, 12); + setupDriveButton(buttonGroup1, btnN, 13); + setupDriveButton(buttonGroup1, btnO, 14); + setupDriveButton(buttonGroup1, btnP, 15); + + panelImageParameters.setBorder(BorderFactory.createTitledBorder("Parameters")); + + GroupLayout panelImageParametersLayout = new GroupLayout(panelImageParameters); + panelImageParameters.setLayout(panelImageParametersLayout); + panelImageParametersLayout.setHorizontalGroup( + panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelImageParametersLayout.createSequentialGroup() .addContainerGap() - .addComponent(btnMount) + .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblSpt) + .addComponent(lblSectorSize)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnUnmount) - .addContainerGap(23, Short.MAX_VALUE)) - ); - panelImageLayout.setVerticalGroup( - panelImageLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelImageLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelImageLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(btnMount) - .addComponent(btnUnmount)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - - jPanel3.setBorder(BorderFactory.createTitledBorder( - null, "Drive parameters", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - DIALOG_PLAIN - )); - - btnDefaultParams.addActionListener(this::btnDefaultParamsActionPerformed); - - GroupLayout jPanel3Layout = new GroupLayout(jPanel3); - jPanel3.setLayout(jPanel3Layout); - jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(btnDefaultParams) - .addGroup(jPanel3Layout.createSequentialGroup() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel10) - .addComponent(jLabel11)) + .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelImageParametersLayout.createSequentialGroup() + .addComponent(txtSectorsPerTrack, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(panelImageParametersLayout.createSequentialGroup() + .addComponent(txtSectorSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(txtSectorsPerTrack) - .addComponent(txtSectorSize, GroupLayout.DEFAULT_SIZE, 121, Short.MAX_VALUE)))) - .addContainerGap(58, Short.MAX_VALUE)) + .addComponent(lblBytes) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnDriveDefault))) + .addContainerGap()) ); - jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() + panelImageParametersLayout.setVerticalGroup( + panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelImageParametersLayout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel10) + .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblSpt) .addComponent(txtSectorsPerTrack, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel11) - .addComponent(txtSectorSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addGap(18, 18, 18) - .addComponent(btnDefaultParams) + .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblSectorSize) + .addComponent(txtSectorSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblBytes) + .addComponent(btnDriveDefault)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - GroupLayout panelImagesLayout = new GroupLayout(panelImages); - panelImages.setLayout(panelImagesLayout); - panelImagesLayout.setHorizontalGroup( - panelImagesLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelImagesLayout.createSequentialGroup() + GroupLayout panelDriveLayout = new GroupLayout(panelDrive); + panelDrive.setLayout(panelDriveLayout); + panelDriveLayout.setHorizontalGroup( + panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDriveLayout.createSequentialGroup() .addContainerGap() - .addGroup(panelImagesLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(txtImageFile) - .addGroup(GroupLayout.Alignment.TRAILING, panelImagesLayout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(btnBrowse)) - .addGroup(panelImagesLayout.createSequentialGroup() - .addGroup(panelImagesLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel1) - .addComponent(cmbDrive, GroupLayout.PREFERRED_SIZE, 277, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel2)) - .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(panelImagesLayout.createSequentialGroup() - .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, panelDriveLayout.createSequentialGroup() + .addComponent(lblImage) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDriveLayout.createSequentialGroup() + .addComponent(btnBrowse) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnMountUnmount) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnUnmountAll)) + .addComponent(panelImageParameters, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(txtImageFile, GroupLayout.Alignment.TRAILING))) + .addGroup(panelDriveLayout.createSequentialGroup() + .addComponent(lblDrive) + .addGap(22, 22, 22) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnI, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnA, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelImage, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addContainerGap()) - ); - panelImagesLayout.setVerticalGroup( - panelImagesLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelImagesLayout.createSequentialGroup() + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnJ, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnB, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnK, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnC, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnL, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnD, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnM, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnE, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnF, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnN, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnO, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnG, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnP, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnH, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap())); + panelDriveLayout.setVerticalGroup( + panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDriveLayout.createSequentialGroup() .addContainerGap() - .addComponent(jLabel2) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cmbDrive, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel1) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtImageFile, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblDrive) + .addComponent(btnA) + .addComponent(btnB) + .addComponent(btnC) + .addComponent(btnD) + .addComponent(btnE) + .addComponent(btnF) + .addComponent(btnG) + .addComponent(btnH)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnBrowse) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(btnI) + .addComponent(btnJ) + .addComponent(btnK) + .addComponent(btnL) + .addComponent(btnM) + .addComponent(btnN) + .addComponent(btnO) + .addComponent(btnP)) + .addGap(18, 18, 18) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblImage) + .addComponent(txtImageFile, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelImagesLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelImagesLayout.createSequentialGroup() - .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(panelImage, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) - ); - - jTabbedPane1.addTab("Disk Images", panelImages); - - jPanel2.setBorder(BorderFactory.createTitledBorder("Note")); - - GroupLayout jPanel2Layout = new GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel3) - .addContainerGap(90, Short.MAX_VALUE)) - ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel3) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(btnMountUnmount) + .addComponent(btnBrowse) + .addComponent(btnUnmountAll)) + .addGap(18, 18, 18) + .addComponent(panelImageParameters, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - btnDefault.addActionListener(this::btnDefaultActionPerformed); + panelCpu.setBorder(BorderFactory.createTitledBorder(null, "Connection with CPU", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, bold)); + + lblPort1.setFont(lblPort1.getFont().deriveFont(Font.BOLD)); + lblPort2.setFont(lblPort2.getFont().deriveFont(Font.BOLD)); + lblPort3.setFont(lblPort3.getFont().deriveFont(Font.BOLD)); - GroupLayout panelPortsLayout = new GroupLayout(panelPorts); - panelPorts.setLayout(panelPortsLayout); - panelPortsLayout.setHorizontalGroup( - panelPortsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelPortsLayout.createSequentialGroup() + GroupLayout panelCpuLayout = new GroupLayout(panelCpu); + panelCpu.setLayout(panelCpuLayout); + panelCpuLayout.setHorizontalGroup( + panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelCpuLayout.createSequentialGroup() .addContainerGap() - .addGroup(panelPortsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(panelPortsLayout.createSequentialGroup() - .addGroup(panelPortsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelPortsLayout.createSequentialGroup() - .addGroup(panelPortsLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addGroup(panelPortsLayout.createSequentialGroup() - .addComponent(jLabel4) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtPort1)) - .addGroup(panelPortsLayout.createSequentialGroup() - .addComponent(jLabel5) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(btnCpuDefault, GroupLayout.Alignment.TRAILING) + .addGroup(panelCpuLayout.createSequentialGroup() + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblNote) + .addGroup(panelCpuLayout.createSequentialGroup() + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(lblPort3) + .addComponent(lblPort2)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(txtPort2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtPort2, GroupLayout.PREFERRED_SIZE, 78, GroupLayout.PREFERRED_SIZE)) - .addGroup(panelPortsLayout.createSequentialGroup() - .addComponent(jLabel6) + .addComponent(lblPort2In)) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(txtPort3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtPort3, GroupLayout.PREFERRED_SIZE, 78, GroupLayout.PREFERRED_SIZE))) + .addComponent(lblPort3In))) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblPort3Out) + .addComponent(lblPort1Out) + .addComponent(lblPort2Out))) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(lblPort1) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtPort1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblPort1In)) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(lblInterruptVector) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelPortsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelPortsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel9) - .addComponent(jLabel8, GroupLayout.Alignment.TRAILING)) - .addComponent(jLabel7, GroupLayout.Alignment.TRAILING))) - .addComponent(btnDefault)) + .addComponent(spnInterruptVector, GroupLayout.PREFERRED_SIZE, 50, 50) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblRange))) .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); - panelPortsLayout.setVerticalGroup( - panelPortsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelPortsLayout.createSequentialGroup() + panelCpuLayout.setVerticalGroup( + panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, panelCpuLayout.createSequentialGroup() .addContainerGap() - .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblNote) + .addGap(18, 18, 18) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblInterruptVector) + .addComponent(spnInterruptVector, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblRange)) .addGap(18, 18, 18) - .addGroup(panelPortsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblPort1) .addComponent(txtPort1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel7)) + .addComponent(lblPort1In) + .addComponent(lblPort1Out)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelPortsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblPort2) .addComponent(txtPort2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel8)) + .addComponent(lblPort2In) + .addComponent(lblPort2Out)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelPortsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel6) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblPort3) .addComponent(txtPort3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel9)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 103, Short.MAX_VALUE) - .addComponent(btnDefault) + .addComponent(lblPort3In) + .addComponent(lblPort3Out)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnCpuDefault) .addContainerGap()) ); - jTabbedPane1.addTab("CPU Ports", panelPorts); - btnSave.addActionListener(this::btnOKActionPerformed); - GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( @@ -393,129 +484,150 @@ public void caretPositionChanged(InputMethodEvent evt) { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jTabbedPane1) - .addGroup(layout.createSequentialGroup() - .addComponent(btnSave, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE))) + .addComponent(panelDrive, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(panelCpu, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnSave) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jTabbedPane1) + .addContainerGap() + .addComponent(panelDrive, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(btnSave)) - .addContainerGap()) + .addComponent(panelCpu, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnSave) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - pack(); - } + btnMountUnmount.addItemListener(e -> { + DriveSettingsUI dsui = driveSettingsUI.get(currentDriveIndex); + if (e.getStateChange() == ItemEvent.SELECTED) { + try { + drives.get(currentDriveIndex).mount(Path.of(txtImageFile.getText())); + dsui.image = txtImageFile.getText(); + dsui.mounted = true; + } catch (IOException ex) { + LOGGER.error("88-DCDD: Could not mount image: " + txtImageFile.getText(), ex); + dialogs.showError("Could not mount image: " + ex.getMessage(), "Mount image"); + txtImageFile.grabFocus(); + } + } else if (e.getStateChange() == ItemEvent.DESELECTED) { + dsui.image = null; + dsui.mounted = false; + drives.get(currentDriveIndex).umount(); + } + updateGUI(currentDriveIndex); + }); - private void cmbDriveItemStateChanged(ItemEvent evt) { - updateGUI(cmbDrive.getSelectedIndex()); - } + btnUnmountAll.addActionListener(e -> drives.foreach((i, drive) -> { + DriveSettingsUI dsui = driveSettingsUI.get(i); + dsui.image = null; + dsui.mounted = false; + drive.umount(); + updateGUI(i); + return null; + })); + + btnBrowse.addActionListener(e -> { + Path currentDirectory = Optional + .of(driveSettingsUI.get(currentDriveIndex).image) + .filter(p -> !p.isEmpty()) + .map(Path::of) + .orElse(Path.of(System.getProperty("user.dir"))); + + dialogs.chooseFile( + "Open disk image", "Open", currentDirectory, false, + new FileExtensionsFilter("Disk images", "dsk", "bin") + ).ifPresent(path -> txtImageFile.setText(path.toString())); + }); - private void txtImageFileInputMethodTextChanged() { - btnMount.setEnabled(!txtImageFile.getText().equals("")); - } + rootPane.setDefaultButton(btnSave); + btnSave.setFont(btnSave.getFont().deriveFont(Font.BOLD)); + btnSave.addActionListener(e -> { + try { + saveSettings(); + dispose(); + } catch (PluginInitializationException ex) { + LOGGER.error(DIALOG_TITLE + ": Could not re-attach CPU ports", ex); + dialogs.showError("Could not re-attach CPU ports. Please see log for more details.", DIALOG_TITLE); + } catch (RuntimeException ignored) { + // already handled + } + }); - private void btnUnmountActionPerformed(ActionEvent evt) { - int index = cmbDrive.getSelectedIndex(); - Drive drive = drives.get(index); - drive.umount(); - updateGUI(index); - } + btnDriveDefault.addActionListener(e -> { + txtSectorsPerTrack.setText(String.valueOf(DiskSettings.DEFAULT_SECTORS_PER_TRACK)); + txtSectorSize.setText(String.valueOf(DiskSettings.DEFAULT_SECTOR_SIZE)); + }); - private void btnMountActionPerformed(ActionEvent evt) { - int index = cmbDrive.getSelectedIndex(); - Drive drive = drives.get(index); - try { - images.set(index, txtImageFile.getText()); - drive.mount(Path.of(txtImageFile.getText())); - } catch (FileNotFoundException e) { - dialogs.showError("Could not mount file. File is either not found, is directory, or is not readable.", "Mount image"); - txtImageFile.grabFocus(); - } catch (Exception ex) { - LOGGER.error("Could not mount file: " + txtImageFile.getText(), ex); - dialogs.showError("Could not mount file. Please see log file for details", "Mount image"); - txtImageFile.grabFocus(); - } - updateGUI(index); - } + btnCpuDefault.addActionListener(e -> { + txtPort1.setText(String.format("0x%02X", DEFAULT_CPU_PORT1)); + txtPort2.setText(String.format("0x%02X", DEFAULT_CPU_PORT2)); + txtPort3.setText(String.format("0x%02X", DEFAULT_CPU_PORT3)); + }); - private void btnBrowseActionPerformed(ActionEvent evt) { - Path currentDirectory = Optional - .of(images.get(cmbDrive.getSelectedIndex())) - .filter(p -> !p.isEmpty()) - .map(Path::of) - .orElse(Path.of(System.getProperty("user.dir"))); + setupTextField(txtImageFile, (dsui, value) -> dsui.image = value); + setupTextField(txtSectorsPerTrack, (dsui, value) -> dsui.sectorsPerTrack = value); + setupTextField(txtSectorSize, (dsui, value) -> dsui.sectorSize = value); - dialogs.chooseFile( - "Open disk image", "Open", currentDirectory, false, - new FileExtensionsFilter("Disk images", "dsk", "bin") - ).ifPresent(path -> txtImageFile.setText(path.toString())); + pack(); } - private void btnOKActionPerformed(ActionEvent evt) { - RadixUtils radixUtils = RadixUtils.getInstance(); - JTextField textField = null; - String name = ""; - - int index = cmbDrive.getSelectedIndex(); - int parsedPort1; - int parsedPort2; - int parsedPort3; + private void setupDriveButton(ButtonGroup group, JToggleButton button, int index) { + group.add(button); + button.setFont(DRIVE_BUTTON_FONT); + button.setIcon(OFF_ICON); + button.addActionListener(e -> updateGUI(index)); + } - try { - textField = txtPort1; - name = "Port1"; - parsedPort1 = radixUtils.parseRadix(txtPort1.getText()); - textField = txtPort2; - name = "Port2"; - parsedPort2 = radixUtils.parseRadix(txtPort2.getText()); - textField = txtPort3; - name = "Port3"; - parsedPort3 = radixUtils.parseRadix(txtPort3.getText()); - - textField = txtSectorsPerTrack; - name = "Sectors per track"; - radixUtils.parseRadix(txtSectorsPerTrack.getText()); - - textField = txtSectorSize; - name = "Sector size"; - radixUtils.parseRadix(txtSectorSize.getText()); - - sectorsPerTrack.set(index, txtSectorsPerTrack.getText()); - sectorSizes.set(index, txtSectorSize.getText()); - images.set(index, txtImageFile.getText()); - } catch (NumberFormatException e) { - dialogs.showError(name + ": Invalid number format", "Save settings"); - textField.grabFocus(); - return; - } catch (IllegalArgumentException e) { - dialogs.showError(name + " must be greater than 0", "Save settings"); - textField.grabFocus(); - return; - } + private void setupTextField(JTextField textField, BiConsumer property) { + textField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + property.accept(driveSettingsUI.get(currentDriveIndex), textField.getText()); + } - saveSettings(parsedPort1, parsedPort2, parsedPort3); - dispose(); - } + @Override + public void removeUpdate(DocumentEvent e) { + property.accept(driveSettingsUI.get(currentDriveIndex), textField.getText()); + } - private void btnDefaultActionPerformed(ActionEvent evt) { - txtPort1.setText(String.format("0x%02X", DEFAULT_CPU_PORT1)); - txtPort2.setText(String.format("0x%02X", DEFAULT_CPU_PORT2)); - txtPort3.setText(String.format("0x%02X", DEFAULT_CPU_PORT3)); + @Override + public void changedUpdate(DocumentEvent e) { + property.accept(driveSettingsUI.get(currentDriveIndex), textField.getText()); + } + }); } - private void btnDefaultParamsActionPerformed(ActionEvent evt) { - txtSectorsPerTrack.setText(String.valueOf(DiskSettings.DEFAULT_SECTORS_PER_TRACK)); - txtSectorSize.setText(String.valueOf(DiskSettings.DEFAULT_SECTOR_SIZE)); - } - private final JButton btnMount = new JButton("Mount"); - private final JButton btnUnmount = new JButton("Umount"); - private final JComboBox cmbDrive = new JComboBox<>(); + private final JToggleButton btnA = new JToggleButton("A"); + private final JToggleButton btnB = new JToggleButton("B"); + private final JToggleButton btnC = new JToggleButton("C"); + private final JToggleButton btnD = new JToggleButton("D"); + private final JToggleButton btnE = new JToggleButton("E"); + private final JToggleButton btnF = new JToggleButton("F"); + private final JToggleButton btnG = new JToggleButton("G"); + private final JToggleButton btnH = new JToggleButton("H"); + private final JToggleButton btnI = new JToggleButton("I"); + private final JToggleButton btnJ = new JToggleButton("J"); + private final JToggleButton btnK = new JToggleButton("K"); + private final JToggleButton btnL = new JToggleButton("L"); + private final JToggleButton btnM = new JToggleButton("M"); + private final JToggleButton btnN = new JToggleButton("N"); + private final JToggleButton btnO = new JToggleButton("O"); + private final JToggleButton btnP = new JToggleButton("P"); + private final JToggleButton btnMountUnmount = new JToggleButton("Mount"); + private final JButton btnUnmountAll = new JButton("Unmount all"); + private final JButton btnSave = new JButton("Save"); + private final JButton btnBrowse = new JButton("Browse..."); + private final JSpinner spnInterruptVector = new JSpinner(new SpinnerNumberModel(0, 0, 7, 1)); + private final JButton btnCpuDefault = new JButton("Set default"); + private final JButton btnDriveDefault = new JButton("Set default"); private final JTextField txtImageFile = new JTextField(); private final JTextField txtPort1 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT1)); private final JTextField txtPort2 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT2)); diff --git a/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/off.png b/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/off.png new file mode 100644 index 0000000000000000000000000000000000000000..f43233702e23e19e44d7f786e85e0e2f5767c516 GIT binary patch literal 469 zcmV;`0V@89P)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10b)r+ zK~y-6rIS5Q0#Ou&zej^E0Bxxz4D@uYz>4_Oum%_552cG>8_Y`xG#V2EiU|b)S%8T$ z{1g)BSUBP^3}WIyG0Yuo)W@1nfjRI21b{*W zVQvnbBoY8;kwR_3H}UZrK{)n&M{|^924p0W3ZLQ}*n`#iw@3l|Vb5xUr(uoof5A2 z+XkYWxR8XAgfZp-cqU;JtyT-iaTpGV3(=`u)DL z*{mGLQKeE*tyX(&x7+u=@0a3MKIY3LYgR6mNAz}+iJD?W{gofoz`qN(+0sVOeT|~PN#F{`~LfKx$J)eOpF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10lG;< zK~y-6rIWu)TVWK2pA+SxlS3PYE|S`WCUJEUoGy`GI;7HCI$2!Y%wUI75k-e|zxfAR zq*#iAG((nH(W$t&6aq~XbW!jZCX3cUj>Emin;VrDKlqmOo%8UXbKXx>mHV7_e?ZdG zLybuw3G_KZ{-AsZY@O4CrhKmgS&&icd_w3z5EOBr6i}3Ngtt1U%Pjzzm)F2oH#u;N z;yNG*qdKcA4S*}V40PO4?1h|R5Yi8N=p;Km|4T7I0Hu=)CTSE1FQCyc0I^_<{8*m+ zSf1#^Xfr|(oFTga<*^@NTQ+9M#0;6(mhD#|C{L~dHyrPFlpDMvPVmYHC4{(VZKQH3 zY|BPbQn^%Xu~PB^R#9T!HVQ`t5{rpj-wKtIj=n5-rxRN{ad}L)oX=Ir|- 0); - drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null)); + drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null, false)); drive.mount(testImageFile); drive.select(); @@ -130,7 +130,7 @@ public void testDriveParametersAfterSelect() throws Exception { @Test public void testDriveParametersAfterSelectThenDeselect() throws Exception { Drive drive = new Drive(0, mock(Context8080.class), () -> 0); - drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null)); + drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null, false)); drive.mount(testImageFile); drive.select(); @@ -160,7 +160,7 @@ public void testDeselectWithoutSelectHasNoEffect() { @Test public void testReadAllData() throws Exception { Drive drive = new Drive(0, mock(Context8080.class), () -> 0); - drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null)); + drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null, false)); drive.mount(testImageFile); drive.select(); @@ -194,7 +194,7 @@ public void testReadAllData() throws Exception { @Test public void testWriteAllData() throws Exception { Drive drive = new Drive(0, mock(Context8080.class), () -> 0); - drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null)); + drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null, false)); drive.mount(testImageFile); drive.select(); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java index 122db0264..3388b05d4 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java @@ -98,7 +98,7 @@ private void initComponents() { JButton btnSave = new JButton("Save"); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); + rootPane.registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); setTitle("MITS 88-SIO Settings"); From 4b996bd4a72030e62af1f35fe052b8bf9e505449 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 6 Dec 2022 12:00:36 +0100 Subject: [PATCH 228/314] [#162] 88-dcdd: interrupts supported + gui rewrite --- .../plugins/cpu/intel8080/EmulatorEngine.java | 8 +- .../plugins/device/mits88dcdd/DeviceImpl.java | 1 + .../device/mits88dcdd/DiskSettings.java | 14 ++++ .../device/mits88dcdd/drive/Drive.java | 24 +++--- .../mits88dcdd/drive/DriveCollection.java | 19 +---- .../device/mits88dcdd/gui/SettingsDialog.java | 75 ++++++++----------- .../plugins/device/mits88dcdd/DriveTest.java | 36 ++++----- .../device/mits88sio/ControlChannel.java | 2 +- .../plugins/device/mits88sio/UART.java | 9 ++- .../plugins/device/mits88sio/gui/SioGui.java | 41 +++++----- .../device/mits88sio/ControlChannelTest.java | 2 +- .../plugins/device/mits88sio/UARTTest.java | 10 +-- 12 files changed, 117 insertions(+), 124 deletions(-) diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java index de9e48f33..1785498e3 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java @@ -176,13 +176,12 @@ private int dispatch() throws Throwable { tmpListener.beforeDispatch(); } - /* if interrupt is waiting, instruction won't be read from memory - * but from one or all of 3 bytes (b1,b2,b3) which represents either - * rst or call instruction incomed from external peripheral device + /* if the interrupt is waiting, the instruction is represented by bytes (b1,b2,b3) which represents either + * rst or a call instruction from an external peripheral device */ if (isINT) { + isINT = false; if (INTE) { - isINT = false; Integer maybeAddress = RST_MAP.get(b1 & 0xFF); if (maybeAddress != null) { // RST SP = (SP - 2) & 0xFFFF; @@ -196,7 +195,6 @@ private int dispatch() throws Throwable { return 17; } } - isINT = false; } try { diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java index 5080ab54d..378a02371 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java @@ -75,6 +75,7 @@ public void initialize() throws PluginInitializationException { throw new RuntimeException(e); } }); + drives.reset(); } @Override diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java index ac1600533..a48e51c04 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java @@ -12,6 +12,7 @@ public class DiskSettings { public final static int DEFAULT_CPU_PORT2 = 0x9; public final static int DEFAULT_CPU_PORT3 = 0xA; public final static int DEFAULT_INTERRUPT_VECTOR = 7; + public final static boolean DEFAULT_INTERRUPTS_SUPPORTED = true; public final static int DEFAULT_SECTORS_PER_TRACK = 32; public final static int DEFAULT_SECTOR_SIZE = 137; @@ -23,6 +24,7 @@ public class DiskSettings { private static final String KEY_IMAGE = "image"; private static final String KEY_IMAGE_MOUNTED = "imageMounted"; private static final String KEY_INTERRUPT_VECTOR = "interruptVector"; + private static final String KEY_INTERRUPTS_SUPPORTED = "interruptsSupported"; private final BasicSettings settings; private final List observers = new CopyOnWriteArrayList<>(); @@ -31,6 +33,7 @@ public class DiskSettings { private volatile int port2CPU; private volatile int port3CPU; private volatile int interruptVector; + private volatile boolean interruptsSupported; private final DriveSettings[] driveSettings = new DriveSettings[16]; @FunctionalInterface @@ -64,6 +67,7 @@ public DiskSettings(BasicSettings settings) { this.port2CPU = settings.getInt(KEY_PORT2_CPU, DEFAULT_CPU_PORT2); this.port3CPU = settings.getInt(KEY_PORT3_CPU, DEFAULT_CPU_PORT3); this.interruptVector = settings.getInt(KEY_INTERRUPT_VECTOR, DEFAULT_INTERRUPT_VECTOR); + this.interruptsSupported = settings.getBoolean(KEY_INTERRUPTS_SUPPORTED, DEFAULT_INTERRUPTS_SUPPORTED); for (int i = 0; i < driveSettings.length; i++) { driveSettings[i] = new DriveSettings( @@ -155,6 +159,16 @@ public void setInterruptVector(int interruptVector) { notifySettingsChanged(); } + public boolean getInterruptsSupported() { + return interruptsSupported; + } + + public void setInterruptsSupported(boolean value) { + this.interruptsSupported = value; + settings.setBoolean(KEY_INTERRUPTS_SUPPORTED, value); + notifySettingsChanged(); + } + private void notifySettingsChanged() { observers.forEach(SettingsObserver::settingsChanged); } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java index ff5c2ba61..4a8a53216 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java @@ -46,13 +46,13 @@ public class Drive { private static final Logger LOGGER = LoggerFactory.getLogger(Drive.class); - public static final byte DEAD_DRIVE = (byte)0b11100111; - private static final byte ALIVE_DRIVE = (byte)0b11100101; - private static final byte MASK_TRACK0 = (byte)0b10111111; + public static final byte DEAD_DRIVE = (byte) 0b11100111; + private static final byte ALIVE_DRIVE = (byte) 0b11100101; + private static final byte MASK_TRACK0 = (byte) 0b10111111; - public static final byte SECTOR0 = (byte)0b11000001; + public static final byte SECTOR0 = (byte) 0b11000001; - private static final byte MASK_HEAD_LOAD = (byte)0b11111011; + private static final byte MASK_HEAD_LOAD = (byte) 0b11111011; private static final byte MASK_DATA_AVAILABLE = 0b01111111; private final static Map RST_MAP = Map.of( @@ -69,6 +69,7 @@ public class Drive { private final int driveIndex; private final Context8080 cpu; private final Supplier interruptVector; + private volatile boolean interruptsSupported; private final ReadWriteLock positionLock = new ReentrantReadWriteLock(); private int track; @@ -96,7 +97,7 @@ public class Drive { M - When 0, head movement is allowed H - When 0, indicates head is loaded for read/write X - not used (will be 0) - I - When 0, indicates interrupts enabled (not used this emulator) + I - When 0, indicates interrupts enabled Z - When 0, indicates head is on track 0 R - When 0, indicates that read circuit has new byte to read */ @@ -112,10 +113,11 @@ public class Drive { */ private byte port2status = SECTOR0; - public Drive(int driveIndex, Context8080 cpu, Supplier interruptVector) { + public Drive(int driveIndex, Context8080 cpu, Supplier interruptVector, boolean interruptsSupported) { this.driveIndex = driveIndex; this.cpu = Objects.requireNonNull(cpu); this.interruptVector = Objects.requireNonNull(interruptVector); + this.interruptsSupported = interruptsSupported; reset(); } @@ -134,6 +136,10 @@ public DriveParameters getDriveParameters() { ); } + public void setInterruptsSupported(boolean interruptsSupported) { + this.interruptsSupported = interruptsSupported; + } + public boolean isSelected() { return selected; } @@ -215,7 +221,7 @@ public byte getPort2status() { if (((~port1status) & (~MASK_HEAD_LOAD)) != 0) { return port2status; } else { - return (byte)0xFF; // When head is not loaded, real hardware returns 0xFF + return (byte) 0xFF; // When head is not loaded, real hardware returns 0xFF } }); } @@ -386,7 +392,7 @@ private void notifyParamsChanged() { } private void signalInterrupt() { - if (cpu.isInterruptSupported()) { + if (interruptsSupported && cpu.isInterruptSupported()) { cpu.signalInterrupt(new byte[]{RST_MAP.get(interruptVector.get())}); } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java index a53f7ffd9..1e482878f 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.nio.file.Path; import java.util.*; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; @@ -49,9 +48,6 @@ public class DriveCollection implements Iterable { private Optional attachedCpuPort3 = Optional.empty(); private volatile int currentDrive; - private final AtomicReference> lastAttachedPort1 = new AtomicReference<>(); - private final AtomicReference> lastAttachedPort2 = new AtomicReference<>(); - private final AtomicReference> lastAttachedPort3 = new AtomicReference<>(); public DriveCollection(Context8080 cpu, DiskSettings settings, Dialogs dialogs) { this.cpu = Objects.requireNonNull(cpu); @@ -59,7 +55,7 @@ public DriveCollection(Context8080 cpu, DiskSettings settings, Dialogs dialogs) this.dialogs = Objects.requireNonNull(dialogs); for (int i = 0; i < DRIVES_COUNT; i++) { - drives.add(new Drive(i, cpu, settings::getInterruptVector)); + drives.add(new Drive(i, cpu, settings::getInterruptVector, settings.getInterruptsSupported())); } this.currentDrive = DRIVES_COUNT; @@ -101,15 +97,6 @@ public void foreach(BiFunction function) { } } - public void reattach() throws PluginInitializationException { - DeviceContext port1 = lastAttachedPort1.get(); - DeviceContext port2 = lastAttachedPort2.get(); - DeviceContext port3 = lastAttachedPort3.get(); - if (port1 != null && port2 != null && port3 != null) { - attach(port1, port2, port3); - } - } - public void attach(DeviceContext port1, DeviceContext port2, DeviceContext port3) throws PluginInitializationException { detach(); int port1cpu = settings.getPort1CPU(); @@ -122,7 +109,6 @@ public void attach(DeviceContext port1, DeviceContext port2, DeviceC ); } attachedCpuPort1 = Optional.of(port1cpu); - lastAttachedPort1.set(port1); if (!cpu.attachDevice(port2, port2cpu)) { throw new PluginInitializationException( @@ -130,7 +116,6 @@ public void attach(DeviceContext port1, DeviceContext port2, DeviceC ); } attachedCpuPort2 = Optional.of(port2cpu); - lastAttachedPort2.set(port2); if (!cpu.attachDevice(port3, port3cpu)) { throw new PluginInitializationException( @@ -138,7 +123,6 @@ public void attach(DeviceContext port1, DeviceContext port2, DeviceC ); } attachedCpuPort3 = Optional.of(port3cpu); - lastAttachedPort3.set(port3); } public void detach() { @@ -151,6 +135,7 @@ public void reset() { foreach((i, drive) -> { DiskSettings.DriveSettings driveSettings = settings.getDriveSettings(i); drive.setDriveSettings(driveSettings); + drive.setInterruptsSupported(settings.getInterruptsSupported()); Optional .ofNullable(driveSettings.imagePath) diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java index a74d4b620..e743d2818 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java @@ -28,7 +28,6 @@ import org.slf4j.LoggerFactory; import javax.swing.*; -import javax.swing.border.TitledBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.*; @@ -114,6 +113,7 @@ private void readSettings() { txtPort2.setText(String.format("0x%02X", settings.getPort2CPU())); txtPort3.setText(String.format("0x%02X", settings.getPort3CPU())); spnInterruptVector.setValue(settings.getInterruptVector()); + chkInterruptsSupported.setSelected(settings.getInterruptsSupported()); driveSettingsUI.clear(); drives.foreach((i, drive) -> { @@ -146,6 +146,7 @@ private void saveSettings() throws PluginInitializationException, RuntimeExcepti settings.setPort2CPU(parsedPort2); settings.setPort3CPU(parsedPort3); settings.setInterruptVector(interruptVector); + settings.setInterruptsSupported(chkInterruptsSupported.isSelected()); drives.foreach((i, drive) -> { DriveSettingsUI dsui = driveSettingsUI.get(i); @@ -156,10 +157,8 @@ private void saveSettings() throws PluginInitializationException, RuntimeExcepti DiskSettings.DriveSettings driveSettings = new DiskSettings.DriveSettings( parsedSectorSizes.get(i), parsedSectorsPerTracks.get(i), nullablePath, dsui.mounted); settings.setDriveSettings(i, driveSettings); - drive.setDriveSettings(driveSettings); return null; }); - drives.reattach(); } private void updateGUI(int index) { @@ -215,10 +214,11 @@ private int parseInt(JToggleButton driveButton, JComponent component, String nam private void initComponents() { ButtonGroup buttonGroup1 = new ButtonGroup(); + JTabbedPane tabbedPane = new JTabbedPane(); JPanel panelDrive = new JPanel(); + JPanel panelImageParameters = new JPanel(); JLabel lblDrive = new JLabel("Drive:"); JLabel lblImage = new JLabel("Image:"); - JPanel panelImageParameters = new JPanel(); JLabel lblSpt = new JLabel("Sectors per track:"); JLabel lblSectorSize = new JLabel("Sector size:"); JLabel lblBytes = new JLabel("bytes"); @@ -240,10 +240,6 @@ private void initComponents() { setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); rootPane.registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); - Font bold = getFont().deriveFont(Font.BOLD); - - panelDrive.setBorder(BorderFactory.createTitledBorder(null, "Drive settings", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, bold)); - setupDriveButton(buttonGroup1, btnA, 0); setupDriveButton(buttonGroup1, btnB, 1); setupDriveButton(buttonGroup1, btnC, 2); @@ -261,8 +257,10 @@ private void initComponents() { setupDriveButton(buttonGroup1, btnO, 14); setupDriveButton(buttonGroup1, btnP, 15); - panelImageParameters.setBorder(BorderFactory.createTitledBorder("Parameters")); + tabbedPane.addTab("Drive settings", panelDrive); + tabbedPane.addTab("Connection with CPU", panelCpu); + panelImageParameters.setBorder(BorderFactory.createTitledBorder("Parameters")); GroupLayout panelImageParametersLayout = new GroupLayout(panelImageParameters); panelImageParameters.setLayout(panelImageParametersLayout); panelImageParametersLayout.setHorizontalGroup( @@ -298,7 +296,7 @@ private void initComponents() { .addComponent(txtSectorSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(lblBytes) .addComponent(btnDriveDefault)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(9, Short.MAX_VALUE)) ); GroupLayout panelDriveLayout = new GroupLayout(panelDrive); @@ -318,8 +316,7 @@ private void initComponents() { .addComponent(btnMountUnmount) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnUnmountAll)) - .addComponent(panelImageParameters, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(txtImageFile, GroupLayout.Alignment.TRAILING))) + .addComponent(txtImageFile))) .addGroup(panelDriveLayout.createSequentialGroup() .addComponent(lblDrive) .addGap(22, 22, 22) @@ -353,8 +350,10 @@ private void initComponents() { .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(btnP, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnH, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) - .addContainerGap())); + .addComponent(btnH, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(panelImageParameters, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); panelDriveLayout.setVerticalGroup( panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelDriveLayout.createSequentialGroup() @@ -389,16 +388,9 @@ private void initComponents() { .addComponent(btnBrowse) .addComponent(btnUnmountAll)) .addGap(18, 18, 18) - .addComponent(panelImageParameters, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(panelImageParameters, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - panelCpu.setBorder(BorderFactory.createTitledBorder(null, "Connection with CPU", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, bold)); - - lblPort1.setFont(lblPort1.getFont().deriveFont(Font.BOLD)); - lblPort2.setFont(lblPort2.getFont().deriveFont(Font.BOLD)); - lblPort3.setFont(lblPort3.getFont().deriveFont(Font.BOLD)); - GroupLayout panelCpuLayout = new GroupLayout(panelCpu); panelCpu.setLayout(panelCpuLayout); panelCpuLayout.setHorizontalGroup( @@ -438,10 +430,11 @@ private void initComponents() { .addGroup(panelCpuLayout.createSequentialGroup() .addComponent(lblInterruptVector) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnInterruptVector, GroupLayout.PREFERRED_SIZE, 50, 50) + .addComponent(spnInterruptVector, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblRange))) - .addGap(0, 0, Short.MAX_VALUE))) + .addComponent(lblRange)) + .addComponent(chkInterruptsSupported)) + .addGap(0, 164, Short.MAX_VALUE))) .addContainerGap()) ); panelCpuLayout.setVerticalGroup( @@ -450,11 +443,6 @@ private void initComponents() { .addContainerGap() .addComponent(lblNote) .addGap(18, 18, 18) - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblInterruptVector) - .addComponent(spnInterruptVector, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(lblRange)) - .addGap(18, 18, 18) .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(lblPort1) .addComponent(txtPort1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) @@ -472,7 +460,14 @@ private void initComponents() { .addComponent(txtPort3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(lblPort3In) .addComponent(lblPort3Out)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(32, 32, 32) + .addComponent(chkInterruptsSupported) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblInterruptVector) + .addComponent(spnInterruptVector, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblRange)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 31, Short.MAX_VALUE) .addComponent(btnCpuDefault) .addContainerGap()) ); @@ -481,12 +476,7 @@ private void initComponents() { getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(panelDrive, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(panelCpu, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(tabbedPane) .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnSave) @@ -495,13 +485,10 @@ private void initComponents() { layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(panelDrive, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelCpu, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(tabbedPane, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnSave) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); btnMountUnmount.addItemListener(e -> { @@ -625,6 +612,7 @@ public void changedUpdate(DocumentEvent e) { private final JButton btnUnmountAll = new JButton("Unmount all"); private final JButton btnSave = new JButton("Save"); private final JButton btnBrowse = new JButton("Browse..."); + private final JCheckBox chkInterruptsSupported = new JCheckBox("Interrupts supported"); private final JSpinner spnInterruptVector = new JSpinner(new SpinnerNumberModel(0, 0, 7, 1)); private final JButton btnCpuDefault = new JButton("Set default"); private final JButton btnDriveDefault = new JButton("Set default"); @@ -634,4 +622,5 @@ public void changedUpdate(DocumentEvent e) { private final JTextField txtPort3 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT3)); private final JTextField txtSectorSize = new JTextField(String.valueOf(DiskSettings.DEFAULT_SECTOR_SIZE)); private final JTextField txtSectorsPerTrack = new JTextField(String.valueOf(DiskSettings.DEFAULT_SECTORS_PER_TRACK)); + } diff --git a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java index 9ff4073df..158a022df 100644 --- a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java +++ b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DriveTest.java @@ -64,7 +64,7 @@ private void assertImageContent(int dataStart) throws Exception { @Test public void testInitialDriveParameters() { - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); DriveParameters params = drive.getDriveParameters(); assertEquals(0, params.sector); @@ -77,22 +77,22 @@ public void testInitialDriveParameters() { @Test public void testMountValidImage() throws IOException { - new Drive(0, mock(Context8080.class), () -> 0).mount(testImageFile); + new Drive(0, mock(Context8080.class), () -> 0, true).mount(testImageFile); } @Test(expected = NullPointerException.class) public void testMountImageNullArgument() throws IOException { - new Drive(0, mock(Context8080.class), () -> 0).mount(null); + new Drive(0, mock(Context8080.class), () -> 0, true).mount(null); } @Test public void testUnmountWithoutMountHasNoEffect() { - new Drive(0, mock(Context8080.class), () -> 0).umount(); + new Drive(0, mock(Context8080.class), () -> 0, true).umount(); } @Test public void testUnmountSelectedDriveDeselects() throws IOException { - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.mount(testImageFile); drive.select(); @@ -102,7 +102,7 @@ public void testUnmountSelectedDriveDeselects() throws IOException { @Test public void testUmountClearsMountImageInDriveParams() throws IOException { - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.mount(testImageFile); drive.umount(); @@ -112,7 +112,7 @@ public void testUmountClearsMountImageInDriveParams() throws IOException { @Test public void testDriveParametersAfterSelect() throws Exception { - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null, false)); drive.mount(testImageFile); @@ -129,7 +129,7 @@ public void testDriveParametersAfterSelect() throws Exception { @Test public void testDriveParametersAfterSelectThenDeselect() throws Exception { - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null, false)); drive.mount(testImageFile); @@ -147,19 +147,19 @@ public void testDriveParametersAfterSelectThenDeselect() throws Exception { @Test public void testSelectWithoutMount() { - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.select(); assertFalse(drive.isSelected()); } @Test public void testDeselectWithoutSelectHasNoEffect() { - new Drive(0, mock(Context8080.class), () -> 0).deselect(); + new Drive(0, mock(Context8080.class), () -> 0, true).deselect(); } @Test public void testReadAllData() throws Exception { - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null, false)); drive.mount(testImageFile); @@ -193,7 +193,7 @@ public void testReadAllData() throws Exception { @Test public void testWriteAllData() throws Exception { - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.setDriveSettings(new DiskSettings.DriveSettings(SECTOR_SIZE, SECTORS_PER_TRACK, null, false)); drive.mount(testImageFile); @@ -243,7 +243,7 @@ public void testDriveListenerIsCalledWhenDiskIsSelected() throws Exception { expectLastCall().once(); replay(listener); - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.addDriveListener(listener); drive.mount(testImageFile); drive.select(); @@ -260,7 +260,7 @@ public void testDriveListenerIsCalledWhenDiskIsDeselected() throws Exception { expectLastCall().once(); replay(listener); - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.mount(testImageFile); drive.select(); drive.addDriveListener(listener); @@ -276,7 +276,7 @@ public void testDriveListenerIsCalledWhenSectorNumberIsChanged() throws Exceptio expectLastCall().once(); replay(listener); - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.mount(testImageFile); drive.select(); drive.addDriveListener(listener); @@ -292,7 +292,7 @@ public void testDriveListenerIsCalledWhenDataAreRead() throws Exception { expectLastCall().once(); replay(listener); - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.mount(testImageFile); drive.select(); drive.writeToPort2((short) 0x04); @@ -309,7 +309,7 @@ public void testDriveListenerIsCalledWhenDataAreWritten() throws Exception { expectLastCall().once(); replay(listener); - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.mount(testImageFile); drive.select(); drive.writeToPort2((short) 0x04); @@ -327,7 +327,7 @@ public void testDriveListenerIsCalledWhenFlagsAreSet() throws Exception { expectLastCall().once(); replay(listener); - Drive drive = new Drive(0, mock(Context8080.class), () -> 0); + Drive drive = new Drive(0, mock(Context8080.class), () -> 0, true); drive.mount(testImageFile); drive.select(); drive.addDriveListener(listener); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java index 235fdbf1e..44fb36835 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java @@ -31,7 +31,7 @@ public ControlChannel(UART uart) { @Override public Byte readData() { - return uart.readStatus(); + return uart.getStatus(); } @Override diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java index 654db2aee..aa41255f1 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java @@ -197,10 +197,17 @@ public byte readBuffer() { } } - public byte readStatus() { + public byte getStatus() { return statusRegister; } + public boolean isInputInterruptEnabled() { + return inputInterruptEnabled; + } + + public boolean isOutputInterruptEnabled() { + return outputInterruptEnabled; + } public void addObserver(Observer observer) { observers.add(observer); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java index eabb0ed28..3bbda6a34 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java @@ -31,7 +31,7 @@ public SioGui(JFrame parent, UART uart) { initComponents(); setLocationRelativeTo(parent); - txtStatus.setText(String.format("0x%x", uart.readStatus())); + txtStatus.setText(String.format("0x%x", uart.getStatus())); lblAttachedDevice.setText(uart.getDeviceId()); uart.addObserver(new UART.Observer() { @@ -55,30 +55,24 @@ public void noData() { } private void initComponents() { - - JPanel jPanel1 = new JPanel(); - lblAttachedDevice = new JLabel(); - JPanel jPanel2 = new JPanel(); + JPanel panelDevice = new JPanel(); + JPanel panelPorts = new JPanel(); JLabel lblStatus = new JLabel("Status:"); JLabel lblData = new JLabel("Data:"); JLabel lblDataDisplay = new JLabel("Data char:"); - txtData = new JTextField(); - txtDataDisplay = new JTextField(); - txtStatus = new JTextField(); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); setTitle("MITS 88-SIO Status"); - jPanel1.setBorder(BorderFactory.createTitledBorder("Attached device")); + panelDevice.setBorder(BorderFactory.createTitledBorder("Attached device")); lblAttachedDevice.setFont(lblAttachedDevice.getFont().deriveFont(14.0f)); lblAttachedDevice.setHorizontalAlignment(SwingConstants.CENTER); - lblAttachedDevice.setText("None"); - GroupLayout jPanel1Layout = new GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); + GroupLayout jPanel1Layout = new GroupLayout(panelDevice); + panelDevice.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() @@ -94,15 +88,14 @@ private void initComponents() { .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - jPanel2.setBorder(BorderFactory.createTitledBorder("88-SIO Ports (for reading)")); + panelPorts.setBorder(BorderFactory.createTitledBorder("88-SIO Ports (for reading)")); txtDataDisplay.setEditable(false); txtStatus.setEditable(false); txtData.setEditable(false); - txtData.setText("N/A"); - GroupLayout jPanel2Layout = new GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); + GroupLayout jPanel2Layout = new GroupLayout(panelPorts); + panelPorts.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() @@ -143,27 +136,27 @@ private void initComponents() { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelDevice, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() - .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) + .addComponent(panelPorts, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(panelDevice, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(panelPorts, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); } - private JLabel lblAttachedDevice; - private JTextField txtData; - private JTextField txtDataDisplay; - private JTextField txtStatus; + private final JLabel lblAttachedDevice = new JLabel("None"); + private final JTextField txtData = new JTextField("N/A"); + private final JTextField txtDataDisplay = new JTextField(); + private final JTextField txtStatus = new JTextField(); } diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ControlChannelTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ControlChannelTest.java index 661b0bb83..36726d4e9 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ControlChannelTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/ControlChannelTest.java @@ -28,7 +28,7 @@ public class ControlChannelTest { @Test public void testReadReturnsStatus() { UART uart = mock(UART.class); - expect(uart.readStatus()).andReturn((byte) 2).once(); + expect(uart.getStatus()).andReturn((byte) 2).once(); replay(uart); ControlChannel channel = new ControlChannel(uart); diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java index c4ea24833..5cf3f3299 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java @@ -48,28 +48,28 @@ public void testSetNullDeviceDoesNotThrow() { @Test public void testInitialStatusIs0x02() { - assertEquals(2, new UART(context, settings).readStatus()); + assertEquals(2, new UART(context, settings).getStatus()); } @Test public void testResetOnEmptyBufferSetStatusTo0x02() { UART uart = new UART(context, settings); uart.reset(false); - assertEquals(0x02, uart.readStatus()); + assertEquals(0x02, uart.getStatus()); } @Test public void testWriteToStatus0x03OnEmptyBufferSetStatusTo0x02() { UART uart = new UART(context, settings); uart.setStatus((byte) 0x03); - assertEquals(0x02, uart.readStatus()); + assertEquals(0x02, uart.getStatus()); } @Test public void testWriteFromDeviceSetsInputDeviceReady() { UART uart = new UART(context, settings); uart.receiveFromDevice((byte) 5); - assertEquals(1, uart.readStatus() & 0x01); + assertEquals(1, uart.getStatus() & 0x01); } @Test @@ -78,7 +78,7 @@ public void testReadBufferResetInputDeviceReady() { uart.receiveFromDevice((byte) 5); assertEquals(5, uart.readBuffer()); - assertEquals(0, uart.readStatus() & 0x01); + assertEquals(0, uart.getStatus() & 0x01); } @Test From cd81d10a78307866dfaf062d5d40b953996eec1d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 7 Dec 2022 20:04:41 +0100 Subject: [PATCH 229/314] [#293, #163] 88-sio: rewrite gui + interrupts supported --- .../device/mits88dcdd/drive/Drive.java | 6 +- .../device/mits88dcdd/gui/DiskGui.java | 2 +- .../plugins/device/mits88sio/DeviceImpl.java | 2 +- .../device/mits88sio/SioUnitSettings.java | 13 + .../plugins/device/mits88sio/UART.java | 135 +++--- .../device/mits88sio/gui/SettingsDialog.java | 450 ++++++++++-------- .../plugins/device/mits88sio/gui/SioGui.java | 278 ++++++++--- .../plugins/device/mits88sio/SioUnitTest.java | 5 + .../plugins/device/mits88sio/UARTTest.java | 57 +-- .../device/adm3a/api/ContextAdm3A.java | 5 + 10 files changed, 550 insertions(+), 403 deletions(-) diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java index 4a8a53216..4e20b584e 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java @@ -68,7 +68,7 @@ public class Drive { private final int driveIndex; private final Context8080 cpu; - private final Supplier interruptVector; + private final byte[] rstInterrupt; private volatile boolean interruptsSupported; private final ReadWriteLock positionLock = new ReentrantReadWriteLock(); @@ -116,7 +116,7 @@ public class Drive { public Drive(int driveIndex, Context8080 cpu, Supplier interruptVector, boolean interruptsSupported) { this.driveIndex = driveIndex; this.cpu = Objects.requireNonNull(cpu); - this.interruptVector = Objects.requireNonNull(interruptVector); + this.rstInterrupt = new byte[]{RST_MAP.get(interruptVector.get())}; this.interruptsSupported = interruptsSupported; reset(); } @@ -393,7 +393,7 @@ private void notifyParamsChanged() { private void signalInterrupt() { if (interruptsSupported && cpu.isInterruptSupported()) { - cpu.signalInterrupt(new byte[]{RST_MAP.get(interruptVector.get())}); + cpu.signalInterrupt(rstInterrupt); } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java index fd1ed46ec..21865f07e 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java @@ -116,7 +116,7 @@ private void initComponents() { JLabel jLabel5 = new JLabel("Offset:"); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); + rootPane.registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); setTitle(DIALOG_TITLE); setResizable(false); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java index fb04a26eb..ccba3596c 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java @@ -41,7 +41,7 @@ @PluginRoot( type = PLUGIN_TYPE.DEVICE, - title = "MITS 88-SIO serial board" + title = "MITS 88-SIO" ) @SuppressWarnings("unused") public class DeviceImpl extends AbstractDevice { diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnitSettings.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnitSettings.java index 4b24ab6c5..0bd2a6a2f 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnitSettings.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnitSettings.java @@ -42,6 +42,7 @@ public class SioUnitSettings { private final static String KEY_INPUT_TO_UPPER_CASE = "inputToUpperCase"; private final static String KEY_MAP_DELETE_CHAR = "mapDeleteChar"; private final static String KEY_MAP_BACKSPACE_CHAR = "mapBackspaceChar"; + private final static String KEY_INTERRUPTS_SUPPORTED = "interruptsSupported"; private final static String KEY_INPUT_INTERRUPT_VECTOR = "inputInterruptVector"; private final static String KEY_OUTPUT_INTERRUPT_VECTOR = "outputInterruptVector"; @@ -54,6 +55,7 @@ public class SioUnitSettings { private volatile boolean inputToUpperCase; private volatile MAP_CHAR mapDeleteChar; private volatile MAP_CHAR mapBackspaceChar; + private boolean interruptsSupported; private volatile int inputInterruptVector; private volatile int outputInterruptVector; private volatile List statusPorts; @@ -79,6 +81,7 @@ public SioUnitSettings(BasicSettings settings) { this.inputToUpperCase = settings.getBoolean(KEY_INPUT_TO_UPPER_CASE, false); this.mapDeleteChar = settings.getString(KEY_MAP_DELETE_CHAR).map(MAP_CHAR::valueOf).orElse(MAP_CHAR.UNCHANGED); this.mapBackspaceChar = settings.getString(KEY_MAP_BACKSPACE_CHAR).map(MAP_CHAR::valueOf).orElse(MAP_CHAR.UNCHANGED); + this.interruptsSupported = settings.getBoolean(KEY_INTERRUPTS_SUPPORTED).orElse(true); this.inputInterruptVector = settings.getInt(KEY_INPUT_INTERRUPT_VECTOR).orElse(7); this.outputInterruptVector = settings.getInt(KEY_OUTPUT_INTERRUPT_VECTOR).orElse(7); @@ -191,6 +194,16 @@ public void setDataPorts(List value) { notifySettingsChanged(); } + public boolean getInterruptsSupported() { + return interruptsSupported; + } + + public void setInterruptsSupported(boolean interruptsSupported) { + this.interruptsSupported = interruptsSupported; + settings.setBoolean(KEY_INTERRUPTS_SUPPORTED, interruptsSupported); + notifySettingsChanged(); + } + public int getInputInterruptVector() { return inputInterruptVector; } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java index aa41255f1..b00848dc0 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java @@ -25,8 +25,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; -import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -48,8 +51,11 @@ @ThreadSafe public class UART { private final static Logger LOGGER = LoggerFactory.getLogger(UART.class); - private final static int SEND_DATA_READY = 2; - private final static int RECEIVE_DATA_READY = 1; + private final static int OUTPUT_DEVICE_READY = 0x80; + private final static int DATA_AVAILABLE = 0x20; + private final static int DATA_OVERFLOW = 0x10; + private final static int XMITTER_BUFFER_EMPTY = 0x2; // ready to receive data from device + private final static int INPUT_DEVICE_READY = 0x1; // ready to send data to CPU private final static Map RST_MAP = Map.of( 0, (byte) 0xC7, @@ -62,21 +68,31 @@ public class UART { 7, (byte) 0xFF ); - private final Queue bufferFromDevice = new ConcurrentLinkedQueue<>(); + private final AtomicReference bufferFromDevice = new AtomicReference<>(); private final Lock bufferAndStatusLock = new ReentrantLock(); private volatile DeviceContext device; - private byte statusRegister = SEND_DATA_READY; + private byte statusRegister = XMITTER_BUFFER_EMPTY; + private volatile boolean interruptsSupported; private volatile boolean inputInterruptEnabled; private volatile boolean outputInterruptEnabled; + private volatile byte[] inputRstInterrupt; + private volatile byte[] outputRstInterrupt; private final Context8080 cpu; - private final SioUnitSettings settings; private final List observers = new ArrayList<>(); public UART(Context8080 cpu, SioUnitSettings settings) { this.cpu = Objects.requireNonNull(cpu); - this.settings = Objects.requireNonNull(settings); + this.interruptsSupported = settings.getInterruptsSupported(); + this.inputRstInterrupt = new byte[] {RST_MAP.get(settings.getInputInterruptVector())}; + this.outputRstInterrupt = new byte[] {RST_MAP.get(settings.getOutputInterruptVector())}; + + settings.addObserver(() -> { + this.interruptsSupported = settings.getInterruptsSupported(); + this.inputRstInterrupt = new byte[] {RST_MAP.get(settings.getInputInterruptVector())}; + this.outputRstInterrupt = new byte[] {RST_MAP.get(settings.getOutputInterruptVector())}; + }); } public void setDevice(DeviceContext device) { @@ -99,61 +115,38 @@ public String getDeviceId() { void reset(boolean guiSupported) { if (guiSupported) { - bufferFromDevice.clear(); + bufferFromDevice.set(null); } setStatus((byte) 0); // disable interrupts + statusRegister = XMITTER_BUFFER_EMPTY; } - public void setStatus(byte value) { - bufferAndStatusLock.lock(); - int newStatus = statusRegister; - boolean isEmpty = true; - try { - inputInterruptEnabled = (value & 1) == 1; - outputInterruptEnabled = (value & 2) == 2; - - isEmpty = bufferFromDevice.isEmpty(); - if (isEmpty) { - this.statusRegister = SEND_DATA_READY; - } else { - this.statusRegister = SEND_DATA_READY | RECEIVE_DATA_READY; - } - newStatus = this.statusRegister; - } finally { - bufferAndStatusLock.unlock(); - if (!isEmpty && inputInterruptEnabled && cpu.isInterruptSupported()) { - cpu.signalInterrupt(new byte[]{RST_MAP.get(settings.getInputInterruptVector())}); - } - if (outputInterruptEnabled && cpu.isInterruptSupported()) { - cpu.signalInterrupt(new byte[]{RST_MAP.get(settings.getOutputInterruptVector())}); - } - - notifyStatusChanged(newStatus); - } + public void setStatus(byte status) { + inputInterruptEnabled = (status & 1) == 1; + outputInterruptEnabled = (status & 2) == 2; } public void receiveFromDevice(byte data) { - boolean wasEmpty = false; - int newStatus = statusRegister; - bufferAndStatusLock.lock(); + int status = statusRegister; + try { - if (bufferFromDevice.isEmpty()) { - wasEmpty = true; + if (bufferFromDevice.get() != null) { + status |= DATA_OVERFLOW; + } else { + status = (byte) (status & (~DATA_OVERFLOW)); } - bufferFromDevice.add(data); - statusRegister = (byte) (statusRegister | 1); - newStatus = statusRegister; + status = (byte) (status | DATA_AVAILABLE | INPUT_DEVICE_READY); + bufferFromDevice.set(data); + statusRegister = (byte) status; } finally { bufferAndStatusLock.unlock(); - if (wasEmpty) { - if (inputInterruptEnabled && cpu.isInterruptSupported()) { - cpu.signalInterrupt(new byte[]{RST_MAP.get(settings.getInputInterruptVector())}); - } - notifyNewData(data); + if (interruptsSupported && inputInterruptEnabled && cpu.isInterruptSupported()) { + cpu.signalInterrupt(inputRstInterrupt); } - notifyStatusChanged(newStatus); + notifyNewData(data); + notifyStatusChanged(status); } } @@ -161,39 +154,29 @@ public void sendToDevice(byte data) { DeviceContext tmpDevice = device; if (tmpDevice != null) { tmpDevice.writeData(data); - if (outputInterruptEnabled && cpu.isInterruptSupported()) { - cpu.signalInterrupt(new byte[]{RST_MAP.get(settings.getOutputInterruptVector())}); + if (interruptsSupported && outputInterruptEnabled && cpu.isInterruptSupported()) { + cpu.signalInterrupt(outputRstInterrupt); } } } public byte readBuffer() { - byte newData = 0; - boolean isNotEmpty = false; - int newStatus = statusRegister; // what to do.. - + Byte bufferData; + int status = 0; bufferAndStatusLock.lock(); try { - Byte result = bufferFromDevice.poll(); - - isNotEmpty = !bufferFromDevice.isEmpty(); - statusRegister = (byte) (isNotEmpty ? (statusRegister | RECEIVE_DATA_READY) : (statusRegister & 0xFE)); - newStatus = statusRegister; - - if (isNotEmpty) { - newData = bufferFromDevice.peek(); + bufferData = bufferFromDevice.get(); + bufferFromDevice.set(null); + if (bufferData == null) { + return 0; } - - return result == null ? 0 : result; + statusRegister = XMITTER_BUFFER_EMPTY; + status = statusRegister; + return bufferData; } finally { bufferAndStatusLock.unlock(); - - if (isNotEmpty) { - notifyNewData(newData); - } else { - notifyNoData(); - } - notifyStatusChanged(newStatus); + notifyNoData(); + notifyStatusChanged(status); } } @@ -201,14 +184,6 @@ public byte getStatus() { return statusRegister; } - public boolean isInputInterruptEnabled() { - return inputInterruptEnabled; - } - - public boolean isOutputInterruptEnabled() { - return outputInterruptEnabled; - } - public void addObserver(Observer observer) { observers.add(observer); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java index 3388b05d4..39f17241e 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java @@ -18,18 +18,13 @@ */ package net.emustudio.plugins.device.mits88sio.gui; -import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.plugins.device.mits88sio.SioUnitSettings; import javax.swing.*; -import javax.swing.GroupLayout.Alignment; -import java.awt.*; import java.awt.event.KeyEvent; import java.util.Objects; -import static javax.swing.GroupLayout.DEFAULT_SIZE; -import static javax.swing.GroupLayout.PREFERRED_SIZE; import static net.emustudio.plugins.device.mits88sio.gui.Constants.MONOSPACED_PLAIN; public class SettingsDialog extends JDialog { @@ -38,7 +33,6 @@ public class SettingsDialog extends JDialog { private final SioUnitSettings settings; private final PortListModel statusPortsModel = new PortListModel(); private final PortListModel dataPortsModel = new PortListModel(); - private final RadixUtils radixUtils = RadixUtils.getInstance(); public SettingsDialog(JFrame parent, SioUnitSettings settings, Dialogs dialogs) { super(parent, true); @@ -48,20 +42,24 @@ public SettingsDialog(JFrame parent, SioUnitSettings settings, Dialogs dialogs) initComponents(); setLocationRelativeTo(parent); + readSettings(); + } + + private void readSettings() { + chkAnsiMode.setSelected(settings.isClearOutputBit8()); + chkTtyMode.setSelected(settings.isClearInputBit8()); + chkToUpperCase.setSelected(settings.isInputToUpperCase()); + cmbMapDel.setSelectedIndex(settings.getMapDeleteChar().ordinal()); + cmbMapBs.setSelectedIndex(settings.getMapBackspaceChar().ordinal()); + spnInputInterrupt.setValue(settings.getInputInterruptVector()); + spnOutputInterrupt.setValue(settings.getOutputInterruptVector()); + chkInterruptsSupported.setSelected(settings.getInterruptsSupported()); + statusPortsModel.clear(); statusPortsModel.addAll(settings.getStatusPorts()); - dataPortsModel.addAll(settings.getDataPorts()); - reload(); - } - private void reload() { - chkClearInputBit8.setSelected(settings.isClearInputBit8()); - chkClearOutputBit8.setSelected(settings.isClearOutputBit8()); - chkInputToUpperCase.setSelected(settings.isInputToUpperCase()); - cmbMapBackspaceChar.setSelectedIndex(settings.getMapBackspaceChar().ordinal()); - cmbMapDeleteChar.setSelectedIndex(settings.getMapDeleteChar().ordinal()); - txtInputInterruptVector.setText(String.valueOf(settings.getInputInterruptVector())); - txtOutputInterruptVector.setText(String.valueOf(settings.getOutputInterruptVector())); + dataPortsModel.clear(); + dataPortsModel.addAll(settings.getDataPorts()); } private void setDefaultStatusPorts() { @@ -76,225 +74,250 @@ private void setDefaultDataPorts() { private void initComponents() { - JPanel panelStatusPorts = new JPanel(); - JScrollPane scrollStatusPorts = new JScrollPane(); - JButton btnStatusAdd = new JButton(); - JButton btnStatusRemove = new JButton(); - JButton btnStatusDefault = new JButton(); - - JPanel panelDataPorts = new JPanel(); - JScrollPane scrollDataPorts = new JScrollPane(); - JButton btnDataAdd = new JButton(); - JButton btnDataRemove = new JButton(); - JButton btnDataDefault = new JButton(); - - JPanel panelGeneral = new JPanel(); - JLabel lblMapDeleteChar = new JLabel("Map DEL char to:"); - JLabel lblMapBackspaceChar = new JLabel("Map BS char to:"); - JLabel lblInputInterruptVector = new JLabel("Input interrupt vector (0-7):"); - JLabel lblOutputInterruptVector = new JLabel("Output interrupt vector (0-7):"); - - JLabel lblCaution = new JLabel(); - JButton btnSave = new JButton("Save"); + JTabbedPane tabbedPane = new JTabbedPane(); + JPanel panelSettings = new JPanel(); + JLabel lblMapDel = new JLabel("Map DEL char to:"); + JLabel lblMapBs = new JLabel("Map BACKSPACE char to:"); + JPanel panelCpu = new JPanel(); + JLabel lblCpuNote = new JLabel("88-SIO has two ports/channels: Status channel and Data channel. Attach these channels to CPU ports (possibly to multiple ports). Be aware of possible CPU-port conflicts."); + JPanel panelStatusChannel = new JPanel(); + JScrollPane srlStatus = new JScrollPane(); + JPanel panelDataChannel = new JPanel(); + JScrollPane srlData = new JScrollPane(); + JPanel panelInterrupts = new JPanel(); + JLabel lblInputInterrupt = new JLabel("Input interrupt vector:"); + JLabel lblOutputInterrupt = new JLabel("Output interrupt vector:"); + JLabel lblInterruptsNote = new JLabel("88-SIO can support input and output interrupts. Input interrupt is triggered when 88-SIO received data from connected device. Output interrupt is triggered when 88-SIO receives data from CPU."); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + setTitle("88-SIO Settings"); + setResizable(false); rootPane.registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); - setTitle("MITS 88-SIO Settings"); + cmbMapBs.setEditable(false); + cmbMapDel.setEditable(false); - panelStatusPorts.setBorder(BorderFactory.createTitledBorder("Status port -> CPU")); - lstStatusPorts.setFont(MONOSPACED_PLAIN); - lstStatusPorts.setModel(statusPortsModel); - lstStatusPorts.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - scrollStatusPorts.setViewportView(lstStatusPorts); + GroupLayout panelSettingsLayout = new GroupLayout(panelSettings); + panelSettings.setLayout(panelSettingsLayout); + panelSettingsLayout.setHorizontalGroup( + panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelSettingsLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(chkTtyMode) + .addComponent(chkAnsiMode) + .addComponent(chkToUpperCase) + .addGroup(panelSettingsLayout.createSequentialGroup() + .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblMapDel) + .addComponent(lblMapBs)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(cmbMapDel, 0, 157, Short.MAX_VALUE) + .addComponent(cmbMapBs, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap(128, Short.MAX_VALUE)) + ); + panelSettingsLayout.setVerticalGroup( + panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelSettingsLayout.createSequentialGroup() + .addContainerGap() + .addComponent(chkTtyMode) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkAnsiMode) + .addGap(18, 18, 18) + .addComponent(chkToUpperCase) + .addGap(18, 18, 18) + .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblMapDel) + .addComponent(cmbMapDel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(cmbMapBs, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblMapBs)) + .addContainerGap(57, Short.MAX_VALUE)) + ); - btnStatusAdd.setText("+"); - btnStatusAdd.addActionListener(e -> addPort("status", "data", statusPortsModel, dataPortsModel)); + tabbedPane.addTab("General settings", panelSettings); - btnStatusRemove.setText("-"); - btnStatusRemove.setToolTipText(""); - btnStatusRemove.addActionListener(e -> removePort("status", lstStatusPorts, statusPortsModel)); + panelStatusChannel.setBorder(BorderFactory.createTitledBorder("Status channel ports")); - btnStatusDefault.setText("Set default"); - btnStatusDefault.addActionListener(e -> setDefaultStatusPorts()); + lstStatusPorts.setFont(MONOSPACED_PLAIN); + lstStatusPorts.setModel(statusPortsModel); + lstStatusPorts.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + srlStatus.setViewportView(lstStatusPorts); - GroupLayout layoutStatusPorts = new GroupLayout(panelStatusPorts); - panelStatusPorts.setLayout(layoutStatusPorts); - layoutStatusPorts.setHorizontalGroup( - layoutStatusPorts.createParallelGroup(Alignment.LEADING) - .addGroup(layoutStatusPorts.createSequentialGroup() + GroupLayout panelStatusChannelLayout = new GroupLayout(panelStatusChannel); + panelStatusChannel.setLayout(panelStatusChannelLayout); + panelStatusChannelLayout.setHorizontalGroup( + panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelStatusChannelLayout.createSequentialGroup() .addContainerGap() - .addGroup(layoutStatusPorts.createParallelGroup(Alignment.LEADING) - .addGroup(layoutStatusPorts.createSequentialGroup() - .addComponent(scrollStatusPorts, PREFERRED_SIZE, 173, PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layoutStatusPorts.createParallelGroup(Alignment.LEADING, false) - .addComponent(btnStatusAdd, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnStatusRemove, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))) - .addComponent(btnStatusDefault)) - .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(srlStatus, GroupLayout.PREFERRED_SIZE, 67, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 30, Short.MAX_VALUE) + .addGroup(panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnStatusAdd, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnStatusRemove, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnStatusDefaults, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); - layoutStatusPorts.setVerticalGroup( - layoutStatusPorts.createParallelGroup(Alignment.LEADING) - .addGroup(layoutStatusPorts.createSequentialGroup() + panelStatusChannelLayout.setVerticalGroup( + panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelStatusChannelLayout.createSequentialGroup() .addContainerGap() - .addGroup(layoutStatusPorts.createParallelGroup(Alignment.LEADING) - .addComponent(scrollStatusPorts, PREFERRED_SIZE, 107, PREFERRED_SIZE) - .addGroup(layoutStatusPorts.createSequentialGroup() + .addGroup(panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(srlStatus, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(panelStatusChannelLayout.createSequentialGroup() .addComponent(btnStatusAdd) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnStatusRemove))) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnStatusDefault) - .addContainerGap(16, Short.MAX_VALUE)) + .addComponent(btnStatusRemove) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE) + .addComponent(btnStatusDefaults))) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - panelDataPorts.setBorder(BorderFactory.createTitledBorder("Data port -> CPU")); + panelDataChannel.setBorder(BorderFactory.createTitledBorder("Data channel ports")); + lstDataPorts.setFont(MONOSPACED_PLAIN); lstDataPorts.setModel(dataPortsModel); lstDataPorts.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - scrollDataPorts.setViewportView(lstDataPorts); + srlData.setViewportView(lstDataPorts); - btnDataAdd.setText("+"); - btnDataAdd.addActionListener(e -> addPort("data", "status", dataPortsModel, statusPortsModel)); - - btnDataRemove.setText("-"); - btnDataRemove.setToolTipText(""); - btnDataRemove.addActionListener(e -> removePort("data", lstDataPorts, dataPortsModel)); - - btnDataDefault.setText("Set default"); - btnDataDefault.addActionListener(e -> setDefaultDataPorts()); - - GroupLayout layoutDataPorts = new GroupLayout(panelDataPorts); - panelDataPorts.setLayout(layoutDataPorts); - layoutDataPorts.setHorizontalGroup( - layoutDataPorts.createParallelGroup(Alignment.LEADING) - .addGroup(layoutDataPorts.createSequentialGroup() + GroupLayout panelDataChannelLayout = new GroupLayout(panelDataChannel); + panelDataChannel.setLayout(panelDataChannelLayout); + panelDataChannelLayout.setHorizontalGroup( + panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDataChannelLayout.createSequentialGroup() .addContainerGap() - .addGroup(layoutDataPorts.createParallelGroup(Alignment.LEADING) - .addGroup(layoutDataPorts.createSequentialGroup() - .addComponent(scrollDataPorts, PREFERRED_SIZE, 173, PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layoutDataPorts.createParallelGroup(Alignment.LEADING, false) - .addComponent(btnDataAdd, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnDataRemove, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))) - .addComponent(btnDataDefault)) - .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(srlData, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnDataRemove, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnDataAdd, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnDataDefaults, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); - layoutDataPorts.setVerticalGroup( - layoutDataPorts.createParallelGroup(Alignment.LEADING) - .addGroup(layoutDataPorts.createSequentialGroup() + panelDataChannelLayout.setVerticalGroup( + panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDataChannelLayout.createSequentialGroup() .addContainerGap() - .addGroup(layoutDataPorts.createParallelGroup(Alignment.LEADING) - .addComponent(scrollDataPorts, PREFERRED_SIZE, 107, PREFERRED_SIZE) - .addGroup(layoutDataPorts.createSequentialGroup() + .addGroup(panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(srlData, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(panelDataChannelLayout.createSequentialGroup() .addComponent(btnDataAdd) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnDataRemove))) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnDataDefault) - .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(btnDataRemove) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE) + .addComponent(btnDataDefaults))) + .addContainerGap()) ); - panelGeneral.setBorder(BorderFactory.createTitledBorder("General settings")); - GroupLayout layoutGeneral = new GroupLayout(panelGeneral); - panelGeneral.setLayout(layoutGeneral); - cmbMapBackspaceChar.setEditable(false); - cmbMapDeleteChar.setEditable(false); - - layoutGeneral.setHorizontalGroup( - layoutGeneral.createParallelGroup(Alignment.LEADING) - .addGroup(layoutGeneral.createSequentialGroup() + GroupLayout panelCpuLayout = new GroupLayout(panelCpu); + panelCpu.setLayout(panelCpuLayout); + panelCpuLayout.setHorizontalGroup( + panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelCpuLayout.createSequentialGroup() .addContainerGap() - .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) - .addComponent(chkClearInputBit8) - .addComponent(chkClearOutputBit8) - .addComponent(chkInputToUpperCase) - .addGroup(layoutGeneral.createSequentialGroup() - .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) - .addComponent(lblMapDeleteChar) - .addComponent(lblMapBackspaceChar) - .addComponent(lblInputInterruptVector) - .addComponent(lblOutputInterruptVector)) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(lblCpuNote, GroupLayout.PREFERRED_SIZE, 438, GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(panelStatusChannel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) - .addComponent(cmbMapDeleteChar) - .addComponent(cmbMapBackspaceChar) - .addComponent(txtInputInterruptVector) - .addComponent(txtOutputInterruptVector)) - .addContainerGap())))); - - layoutGeneral.setVerticalGroup( - layoutDataPorts.createParallelGroup(Alignment.LEADING) - .addGroup(layoutGeneral.createSequentialGroup() + .addComponent(panelDataChannel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addContainerGap()) + ); + panelCpuLayout.setVerticalGroup( + panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelCpuLayout.createSequentialGroup() .addContainerGap() - .addComponent(chkClearInputBit8) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkClearOutputBit8) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkInputToUpperCase) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) - .addComponent(lblMapDeleteChar) - .addComponent(cmbMapDeleteChar)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) - .addComponent(lblMapBackspaceChar) - .addComponent(cmbMapBackspaceChar)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) - .addComponent(lblInputInterruptVector) - .addComponent(txtInputInterruptVector)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layoutGeneral.createParallelGroup(Alignment.LEADING) - .addComponent(lblOutputInterruptVector) - .addComponent(txtOutputInterruptVector)) - .addContainerGap())); + .addComponent(lblCpuNote, GroupLayout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(panelStatusChannel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(panelDataChannel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + tabbedPane.addTab("Connection with CPU", panelCpu); - lblCaution.setText("Attach 88-SIO ports to one or more CPU ports." + - " Be aware of possible port conflicts with other devices."); - lblCaution.setVerticalAlignment(SwingConstants.TOP); + GroupLayout panelInterruptsLayout = new GroupLayout(panelInterrupts); + panelInterrupts.setLayout(panelInterruptsLayout); + panelInterruptsLayout.setHorizontalGroup( + panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelInterruptsLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblInterruptsNote, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(GroupLayout.Alignment.TRAILING, panelInterruptsLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(btnInterruptDefaults)) + .addGroup(panelInterruptsLayout.createSequentialGroup() + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(chkInterruptsSupported) + .addGroup(panelInterruptsLayout.createSequentialGroup() + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblInputInterrupt) + .addComponent(lblOutputInterrupt)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(spnInputInterrupt, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(spnOutputInterrupt, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))) + .addGap(0, 225, Short.MAX_VALUE))) + .addContainerGap()) + ); + panelInterruptsLayout.setVerticalGroup( + panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, panelInterruptsLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblInterruptsNote, GroupLayout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(chkInterruptsSupported) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblInputInterrupt) + .addComponent(spnInputInterrupt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblOutputInterrupt) + .addComponent(spnOutputInterrupt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 27, Short.MAX_VALUE) + .addComponent(btnInterruptDefaults) + .addContainerGap()) + ); - btnSave.setFont(btnSave.getFont().deriveFont(Font.BOLD)); - btnSave.addActionListener(this::btnSaveActionPerformed); + tabbedPane.addTab("Interrupts", panelInterrupts); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(Alignment.LEADING) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(Alignment.LEADING) - .addComponent(lblCaution, PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addGroup(layout.createSequentialGroup() - .addComponent(panelStatusPorts, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelDataPorts, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(layout.createSequentialGroup() - .addComponent(panelGeneral, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(layout.createSequentialGroup() - .addComponent(btnSave, PREFERRED_SIZE, 83, PREFERRED_SIZE))) + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(btnSave) .addContainerGap()) + .addComponent(tabbedPane) ); layout.setVerticalGroup( - layout.createParallelGroup(Alignment.LEADING) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(lblCaution, PREFERRED_SIZE, 49, PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(Alignment.LEADING, false) - .addComponent(panelStatusPorts, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(panelDataPorts, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(Alignment.LEADING, false) - .addComponent(panelGeneral, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) - .addGap(18, 18, 18) - .addGroup(layout.createParallelGroup(Alignment.TRAILING) - .addComponent(btnSave)) + .addComponent(tabbedPane) + .addGap(12, 12, 12) + .addComponent(btnSave) .addContainerGap()) ); + btnStatusAdd.addActionListener(e -> addPort("status", "data", statusPortsModel, dataPortsModel)); + btnStatusRemove.addActionListener(e -> removePort("status", lstStatusPorts, statusPortsModel)); + btnStatusDefaults.addActionListener(e -> setDefaultStatusPorts()); + + btnDataAdd.addActionListener(e -> addPort("data", "status", dataPortsModel, statusPortsModel)); + btnDataRemove.addActionListener(e -> removePort("data", lstDataPorts, dataPortsModel)); + btnDataDefaults.addActionListener(e -> setDefaultDataPorts()); + + btnSave.addActionListener(this::btnSaveActionPerformed); + pack(); } @@ -328,53 +351,68 @@ private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) { int inputInterruptVector; int outputInterruptVector; try { - inputInterruptVector = radixUtils.parseRadix(txtInputInterruptVector.getText().trim()); + inputInterruptVector = ((Number) spnInputInterrupt.getValue()).intValue(); } catch (NumberFormatException e) { dialogs.showError("Could not parse input interrupt vector", "88-SIO Settings"); + spnInputInterrupt.grabFocus(); return; } try { - outputInterruptVector = radixUtils.parseRadix(txtOutputInterruptVector.getText().trim()); + outputInterruptVector = ((Number) spnOutputInterrupt.getValue()).intValue(); } catch (NumberFormatException e) { dialogs.showError("Could not parse interrupt vector", "88-SIO Settings"); + spnOutputInterrupt.grabFocus(); return; } if (inputInterruptVector < 0 || inputInterruptVector > 7) { dialogs.showError("Allowed range of input interrupt vector is 0-7"); + spnInputInterrupt.grabFocus(); return; } if (outputInterruptVector < 0 || outputInterruptVector > 7) { dialogs.showError("Allowed range of output interrupt vector is 0-7"); + spnOutputInterrupt.grabFocus(); return; } settings.setStatusPorts(statusPortsModel.getAll()); settings.setDataPorts(dataPortsModel.getAll()); - settings.setClearInputBit8(chkClearInputBit8.isSelected()); - settings.setClearOutputBit8(chkClearOutputBit8.isSelected()); - settings.setInputToUpperCase(chkInputToUpperCase.isSelected()); + settings.setClearInputBit8(chkTtyMode.isSelected()); + settings.setClearOutputBit8(chkAnsiMode.isSelected()); + settings.setInputToUpperCase(chkToUpperCase.isSelected()); - settings.setMapBackspaceChar(cmbMapBackspaceChar.getItemAt(cmbMapBackspaceChar.getSelectedIndex())); - settings.setMapDeleteChar(cmbMapDeleteChar.getItemAt(cmbMapDeleteChar.getSelectedIndex())); + settings.setMapBackspaceChar(cmbMapBs.getItemAt(cmbMapBs.getSelectedIndex())); + settings.setMapDeleteChar(cmbMapDel.getItemAt(cmbMapDel.getSelectedIndex())); + settings.setInterruptsSupported(chkInterruptsSupported.isSelected()); settings.setInputInterruptVector(inputInterruptVector); settings.setOutputInterruptVector(outputInterruptVector); dispose(); } - private final JList lstDataPorts = new JList<>(); - private final JList lstStatusPorts = new JList<>(); - private final JCheckBox chkClearInputBit8 = new JCheckBox("TTY mode (clear bit 8 of input)"); - private final JCheckBox chkClearOutputBit8 = new JCheckBox("ANSI mode (clear bit 8 on output)"); - private final JCheckBox chkInputToUpperCase = new JCheckBox("Convert input to upper-case"); - private final JTextField txtInputInterruptVector = new JTextField(); - private final JTextField txtOutputInterruptVector = new JTextField(); - private final JComboBox cmbMapBackspaceChar = new JComboBox<>(new DefaultComboBoxModel<>( + + private final JButton btnDataAdd = new JButton("Add"); + private final JButton btnDataDefaults = new JButton("Set default"); + private final JButton btnDataRemove = new JButton("Remove"); + private final JButton btnInterruptDefaults = new JButton("Set default"); + private final JButton btnSave = new JButton("Save"); + private final JButton btnStatusAdd = new JButton("Add"); + private final JButton btnStatusDefaults = new JButton("Set default"); + private final JButton btnStatusRemove = new JButton("Remove"); + private final JCheckBox chkAnsiMode = new JCheckBox("ANSI mode (clear output bit 8)"); + private final JCheckBox chkInterruptsSupported = new JCheckBox("Interrupts supported"); + private final JCheckBox chkToUpperCase = new JCheckBox("Convert input to upper-case"); + private final JCheckBox chkTtyMode = new JCheckBox("TTY mode (clear input bit 8)"); + private final JComboBox cmbMapBs = new JComboBox<>(new DefaultComboBoxModel<>( SioUnitSettings.MAP_CHAR.values() )); - private final JComboBox cmbMapDeleteChar = new JComboBox<>(new DefaultComboBoxModel<>( + private final JComboBox cmbMapDel = new JComboBox<>(new DefaultComboBoxModel<>( SioUnitSettings.MAP_CHAR.values() )); + private final JList lstDataPorts = new JList<>(); + private final JList lstStatusPorts = new JList<>(); + private final JSpinner spnInputInterrupt = new JSpinner(new SpinnerNumberModel(0, 0, 7, 1)); + private final JSpinner spnOutputInterrupt = new JSpinner(new SpinnerNumberModel(0, 0, 7, 1)); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java index 3bbda6a34..221270102 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java @@ -21,112 +21,239 @@ import net.emustudio.plugins.device.mits88sio.UART; import javax.swing.*; +import javax.swing.border.TitledBorder; +import java.awt.*; import java.awt.event.KeyEvent; +import java.util.Objects; public class SioGui extends JDialog { + private final static Font FONT_BOLD_14 = new Font("sansserif", Font.BOLD, 14); + private final static Font FONT_BOLD_13 = new Font("sansserif", Font.BOLD, 13); + private final static Font FONT_MONOSPACED_BOLD_14 = new Font("Monospaced", Font.BOLD, 14); + + private final UART uart; public SioGui(JFrame parent, UART uart) { super(parent); + this.uart = Objects.requireNonNull(uart); + initComponents(); setLocationRelativeTo(parent); - txtStatus.setText(String.format("0x%x", uart.getStatus())); + setStatus(uart.getStatus()); - lblAttachedDevice.setText(uart.getDeviceId()); + txtAttachedDevice.setText(uart.getDeviceId()); uart.addObserver(new UART.Observer() { @Override public void statusChanged(int status) { - txtStatus.setText(Integer.toBinaryString(status)); + setStatus(status); } @Override public void dataAvailable(byte data) { - txtData.setText(String.format("0x%X", data & 0xFF)); - txtDataDisplay.setText(String.valueOf(data)); + lblData.setText(String.format("0x%x", data & 0xFF)); + lblDataAscii.setText(String.valueOf(data)); } @Override public void noData() { - txtData.setText("N/A"); - txtDataDisplay.setText(""); + lblData.setText("0x00"); + lblDataAscii.setText("empty"); } }); } + private void setStatus(int status) { + lblStatus.setText(String.format("0x%x", status)); + String r = ((status & 0x80) == 0) ? "R . " : ". . "; + String d = ((status & 0x20) == 0x20) ? "D " : ". "; + String o = ((status & 0x10) == 0x10) ? "O . . " : ". . . "; + String x = ((status & 0x2) == 0x2) ? "X " : ". "; + String i = ((status & 0x1) == 0) ? "I" : "."; + lblStatusLong.setText(r + d + o + x + i); + } + + private void initComponents() { - JPanel panelDevice = new JPanel(); - JPanel panelPorts = new JPanel(); - JLabel lblStatus = new JLabel("Status:"); - JLabel lblData = new JLabel("Data:"); - JLabel lblDataDisplay = new JLabel("Data char:"); + JPanel panelAttachedDevice = new JPanel(); + JPanel panelControl = new JPanel(); + JLabel lblNoteControl = new JLabel("Control channel shows intermal status of 88-SIO."); + JLabel lblHexControl = new JLabel("Hex value:"); + JSeparator sepControl = new JSeparator(); + JLabel lblR = new JLabel("R"); + JLabel lblD = new JLabel("D"); + JLabel lblO = new JLabel("O"); + JLabel lblX = new JLabel("X"); + JLabel lblI = new JLabel("I"); + JLabel lblNoteR = new JLabel("Output device ready"); + JLabel lblNoteD = new JLabel("Data available"); + JLabel lblNoteO = new JLabel("Data overflow"); + JLabel lblNoteX = new JLabel("Data sent to x-mitter"); + JLabel lblNoteI = new JLabel("Input device ready"); + JPanel panelData = new JPanel(); + JLabel lblHexData = new JLabel("Hex value:"); + JLabel lblNoteData = new JLabel("Data buffer is an internal buffer to be read by CPU."); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); + rootPane.registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); + setResizable(false); + setTitle("MITS 88-SIO"); - setTitle("MITS 88-SIO Status"); + panelAttachedDevice.setBorder(BorderFactory.createTitledBorder( + null, "Attached device", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, + FONT_BOLD_13)); - panelDevice.setBorder(BorderFactory.createTitledBorder("Attached device")); + txtAttachedDevice.setEditable(false); + txtAttachedDevice.setFont(FONT_BOLD_14); - lblAttachedDevice.setFont(lblAttachedDevice.getFont().deriveFont(14.0f)); - lblAttachedDevice.setHorizontalAlignment(SwingConstants.CENTER); - - GroupLayout jPanel1Layout = new GroupLayout(panelDevice); - panelDevice.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() + GroupLayout panelAttachedDeviceLayout = new GroupLayout(panelAttachedDevice); + panelAttachedDevice.setLayout(panelAttachedDeviceLayout); + panelAttachedDeviceLayout.setHorizontalGroup( + panelAttachedDeviceLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelAttachedDeviceLayout.createSequentialGroup() .addContainerGap() - .addComponent(lblAttachedDevice, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(txtAttachedDevice) .addContainerGap()) ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() + panelAttachedDeviceLayout.setVerticalGroup( + panelAttachedDeviceLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelAttachedDeviceLayout.createSequentialGroup() .addContainerGap() - .addComponent(lblAttachedDevice) + .addComponent(txtAttachedDevice, GroupLayout.PREFERRED_SIZE, 43, GroupLayout.PREFERRED_SIZE) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - panelPorts.setBorder(BorderFactory.createTitledBorder("88-SIO Ports (for reading)")); + panelControl.setBorder(BorderFactory.createTitledBorder( + null, "Control channel", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, + FONT_BOLD_13)); + + lblStatusLong.setFont(FONT_MONOSPACED_BOLD_14); + lblStatusLong.setHorizontalAlignment(SwingConstants.CENTER); + lblStatusLong.setBorder(BorderFactory.createEtchedBorder()); - txtDataDisplay.setEditable(false); - txtStatus.setEditable(false); - txtData.setEditable(false); + lblR.setFont(FONT_BOLD_14); + lblD.setFont(FONT_BOLD_14); + lblO.setFont(FONT_BOLD_14); + lblX.setFont(FONT_BOLD_14); + lblI.setFont(FONT_BOLD_14); - GroupLayout jPanel2Layout = new GroupLayout(panelPorts); - panelPorts.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() + GroupLayout panelControlLayout = new GroupLayout(panelControl); + panelControl.setLayout(panelControlLayout); + panelControlLayout.setHorizontalGroup( + panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelControlLayout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblStatus) - .addComponent(lblData) - .addComponent(lblDataDisplay)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(txtStatus) - .addComponent(txtData, GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE) - .addComponent(txtDataDisplay, GroupLayout.DEFAULT_SIZE, 124, Short.MAX_VALUE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, panelControlLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(lblStatusLong, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 238, Short.MAX_VALUE) + .addComponent(sepControl) + .addComponent(lblNoteControl, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))) + .addGroup(panelControlLayout.createSequentialGroup() + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelControlLayout.createSequentialGroup() + .addComponent(lblHexControl) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblStatus)) + .addGroup(panelControlLayout.createSequentialGroup() + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblR) + .addComponent(lblD) + .addComponent(lblO) + .addComponent(lblX) + .addComponent(lblI)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblNoteX) + .addComponent(lblNoteO) + .addComponent(lblNoteR) + .addComponent(lblNoteD) + .addComponent(lblNoteI)))) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() + panelControlLayout.setVerticalGroup( + panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelControlLayout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblStatus) - .addComponent(txtStatus, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addComponent(lblNoteControl, GroupLayout.PREFERRED_SIZE, 46, GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(lblStatusLong, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblData) - .addComponent(txtData, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblHexControl) + .addComponent(lblStatus)) + .addGap(18, 18, 18) + .addComponent(sepControl, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelControlLayout.createSequentialGroup() + .addGap(24, 24, 24) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblD) + .addComponent(lblNoteD))) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblNoteR) + .addComponent(lblR))) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblDataDisplay) - .addComponent(txtDataDisplay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblO) + .addComponent(lblNoteO)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblNoteX) + .addComponent(lblX)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblNoteI) + .addComponent(lblI)) + .addContainerGap(13, Short.MAX_VALUE)) + ); + + panelData.setBorder(BorderFactory.createTitledBorder( + null, "Data buffer", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, + FONT_BOLD_13)); + + lblDataAscii.setFont(FONT_BOLD_14); + lblDataAscii.setHorizontalAlignment(SwingConstants.CENTER); + lblDataAscii.setBorder(BorderFactory.createEtchedBorder()); + + btnClearBuffer.setDefaultCapable(false); + + GroupLayout panelDataLayout = new GroupLayout(panelData); + panelData.setLayout(panelDataLayout); + panelDataLayout.setHorizontalGroup( + panelDataLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDataLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelDataLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, panelDataLayout.createSequentialGroup() + .addGap(0, 102, Short.MAX_VALUE) + .addComponent(btnClearBuffer)) + .addGroup(panelDataLayout.createSequentialGroup() + .addComponent(lblHexData) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblData) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(lblNoteData, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addComponent(lblDataAscii, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + panelDataLayout.setVerticalGroup( + panelDataLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDataLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblNoteData, GroupLayout.PREFERRED_SIZE, 46, GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(lblDataAscii, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDataLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblHexData) + .addComponent(lblData)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnClearBuffer) + .addContainerGap()) ); GroupLayout layout = new GroupLayout(getContentPane()); @@ -135,28 +262,35 @@ private void initComponents() { layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(panelDevice, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(panelAttachedDevice, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() - .addComponent(panelPorts, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) - .addContainerGap()) + .addComponent(panelControl, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelData, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(panelDevice, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(panelAttachedDevice, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(panelPorts, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(panelControl, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelData, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); + btnClearBuffer.addActionListener(e -> uart.readBuffer()); pack(); } - private final JLabel lblAttachedDevice = new JLabel("None"); - private final JTextField txtData = new JTextField("N/A"); - private final JTextField txtDataDisplay = new JTextField(); - private final JTextField txtStatus = new JTextField(); + + private final JButton btnClearBuffer = new JButton("Clear buffer"); + private final JLabel lblData = new JLabel("0x00"); + private final JLabel lblDataAscii = new JLabel("empty"); + private final JLabel lblStatus = new JLabel("0x00"); + private final JLabel lblStatusLong = new JLabel(". . . . . . . ."); + private final JTextField txtAttachedDevice = new JTextField(); } diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java index e97a46dd5..07e8f8ac8 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java @@ -32,6 +32,11 @@ public void testCpuPortsAreReattached() { SioUnitSettings s = mock(SioUnitSettings.class); expect(s.getStatusPorts()).andReturn(List.of(1,2)).anyTimes(); expect(s.getDataPorts()).andReturn(List.of(4,5)).anyTimes(); + expect(s.getInterruptsSupported()).andReturn(true).anyTimes(); + expect(s.getInputInterruptVector()).andReturn(7).anyTimes(); + expect(s.getOutputInterruptVector()).andReturn(7).anyTimes(); + s.addObserver(anyObject()); + expectLastCall().once(); replay(s); Context8080 cpu = mock(Context8080.class); diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java index 5cf3f3299..4b3df94cc 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java @@ -18,8 +18,10 @@ */ package net.emustudio.plugins.device.mits88sio; +import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.cpu.intel8080.api.Context8080; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import static org.easymock.EasyMock.*; @@ -33,7 +35,13 @@ public class UARTTest { @Before public void setup() { this.settings = mock(SioUnitSettings.class); + expect(settings.getInterruptsSupported()).andReturn(true).anyTimes(); + expect(settings.getInputInterruptVector()).andReturn(7).anyTimes(); + expect(settings.getOutputInterruptVector()).andReturn(7).anyTimes(); + settings.addObserver(anyObject()); + expectLastCall().once(); this.context = mock(Context8080.class); + replay(settings, context); } @Test @@ -81,29 +89,14 @@ public void testReadBufferResetInputDeviceReady() { assertEquals(0, uart.getStatus() & 0x01); } - @Test - public void testBufferIsFIFO() { - UART uart = new UART(context, settings); - uart.receiveFromDevice((byte) 1); - uart.receiveFromDevice((byte) 2); - uart.receiveFromDevice((byte) 3); - - assertEquals(1, uart.readBuffer()); - assertEquals(2, uart.readBuffer()); - assertEquals(3, uart.readBuffer()); - } - @Test public void testInputInterruptIsTriggered() { - SioUnitSettings settings = mock(SioUnitSettings.class); - expect(settings.getInputInterruptVector()).andReturn(5).once(); - Context8080 context = mock(Context8080.class); expect(context.isInterruptSupported()).andReturn(true).once(); - context.signalInterrupt(new byte[]{(byte) 0xEF}); + context.signalInterrupt(new byte[]{(byte) 0xFF}); expectLastCall().once(); - replay(settings, context); + replay(context); UART uart = new UART(context, settings); uart.setStatus((byte) 1); uart.receiveFromDevice((byte) 1); @@ -113,36 +106,20 @@ public void testInputInterruptIsTriggered() { @Test public void testOutputInterruptIsTriggered() { - SioUnitSettings settings = mock(SioUnitSettings.class); - expect(settings.getOutputInterruptVector()).andReturn(5).once(); - Context8080 context = mock(Context8080.class); expect(context.isInterruptSupported()).andReturn(true).once(); - context.signalInterrupt(new byte[]{(byte) 0xEF}); + context.signalInterrupt(new byte[]{(byte) 0xFF}); expectLastCall().once(); - replay(settings, context); - UART uart = new UART(context, settings); - uart.setStatus((byte) 2); - uart.sendToDevice((byte) 1); - - verify(context); - } - - @Test - public void testInputInterruptIsTriggeredOnNonemptyBuffer() { - SioUnitSettings settings = mock(SioUnitSettings.class); - expect(settings.getInputInterruptVector()).andReturn(5).once(); - - Context8080 context = mock(Context8080.class); - expect(context.isInterruptSupported()).andReturn(true).once(); - context.signalInterrupt(new byte[]{(byte) 0xEF}); + DeviceContext device = mock(DeviceContext.class); + device.writeData((byte) 1); expectLastCall().once(); - replay(settings, context); + replay(context, device); UART uart = new UART(context, settings); - uart.receiveFromDevice((byte) 1); // interrupts still disabled - uart.setStatus((byte) 1); // interrupts enabled - here the interrupt happens + uart.setDevice(device); + uart.setStatus((byte) 2); + uart.sendToDevice((byte) 1); verify(context); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java index 15a5aacb4..30bfa8ad6 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java @@ -74,4 +74,9 @@ private void onKeyFromKeyboard(byte key) { writeData(key); } } + + @Override + public String toString() { + return "LSI ADM-3A terminal"; + } } From 10e5ba05f69c1042c746ba7366b4dcd98684b093 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 7 Dec 2022 20:12:43 +0100 Subject: [PATCH 230/314] [#293] 88-dcdd: hotfix --- .../emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java index e743d2818..c27d54f74 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java @@ -522,7 +522,7 @@ private void initComponents() { btnBrowse.addActionListener(e -> { Path currentDirectory = Optional - .of(driveSettingsUI.get(currentDriveIndex).image) + .ofNullable(driveSettingsUI.get(currentDriveIndex).image) .filter(p -> !p.isEmpty()) .map(Path::of) .orElse(Path.of(System.getProperty("user.dir"))); From 50eba265fce5b9b17edd916e066049a8f020e883 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 14 Dec 2022 22:42:28 +0100 Subject: [PATCH 231/314] 88-dcdd date format optional + little refactorings --- .../device/mits88dcdd/cpmfs/CpmFormat.java | 2 +- .../device/mits88dcdd/cpmfs/DateFormat.java | 29 ++++++++- .../plugins/device/adm3a/gui/adm-3a.ttf | Bin 36372 -> 36364 bytes resources/lsi-adm-3a/adm-3a.ttf | Bin 36372 -> 36364 bytes resources/lsi-adm-3a/adm3a.sfd | 58 +++++++++--------- 5 files changed, 56 insertions(+), 33 deletions(-) diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java index 52674ea11..fc46821a7 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java @@ -136,7 +136,7 @@ public static List fromConfig(Config config) { Optional sectorSkew = c.getOptional("sectorSkew"); Optional> sectorSkewTable = c.getOptional("sectorSkewTable"); boolean bcInterpretsAsUnused = c.getOptional("bcInterpretsAsUnused").orElse(false); - DateFormat dateFormat = c.getEnum("dateFormat", DateFormat.class); + DateFormat dateFormat = c.getEnumOrElse("dateFormat", DateFormat.class, () -> DateFormat.NOT_USED); SectorOps sectorOps = c .getOptional("sectorOps") .map(SectorOps::fromString) diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DateFormat.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DateFormat.java index 1c138d4cf..3c20f7939 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DateFormat.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DateFormat.java @@ -7,14 +7,39 @@ public enum DateFormat { /** * 21 00 C1 C1 M1 M1 M1 M1 A1 A1 A1 A1 C2 C2 M2 M2 * M2 M2 A2 A2 A2 A2 C3 C3 M3 M3 M3 M3 A3 A3 A3 A3 + *

+ * C1 = File 1 Create date + * M1 = File 1 Modify date/time + * A1 = File 1 Access date/time + * C2 = File 2 Create date + * M2 = File 2 Modify date/time + * A2 = File 2 Access date/time + * C3 = File 3 Create date + * M3 = File 3 Modify date/time + * A3 = File 3 Access date/time */ - NATIVE, // P2DOS and CP/M Plus; every 4th entry + NATIVE, // used in CP/M 2.2: Z80DOS, DOS+, P2DOS and CP/M Plus; every 4th entry /** * 21 C1 C1 C1 C1 M1 M1 M1 M1 00 00 C2 C2 C2 C2 M2 * M2 M2 M2 00 00 C3 C3 C3 C3 M3 M3 M3 M3 00 00 00 + *

+ * https://manpages.debian.org/testing/cpmtools/cpm.5.en.html + *

+ * A time stamp consists of two dates: Creation and modification date (the latter being recorded when the file is + * closed). CP/M Plus further allows optionally to record the access instead of creation date as first time stamp. + * - 2 bytes (little-endian) days starting with 1 at 01-01-1978 + * - 1 byte hour in BCD format + * - 1 byte minute in BCD format + *

+ * C1 = File 1 Create date + * M1 = File 1 Modify date/time + * C2 = File 2 Create date + * M2 = File 2 Modify date/time + * C3 = File 3 Create date + * M3 = File 3 Modify date/time */ - NATIVE2, // ZSDOS and CP/M Plus; every 4th entry + NATIVE2, // P2DOS and CP/M Plus; every 4th entry /** * CP/M 3, sometimes ZSDOS diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf index 32d74918429d412ef453ff8ee5d460812601aeb4..946d149847b1c8749c0053507e150e59f850859d 100644 GIT binary patch delta 635 zcmW+zT}V@L9R1zRt(o`ker&t@y1V!O@9xHo9GeU)m?n`n+!1JFa@zevR*_&e2`dS1TiFP#2!q_kJ(N59e(E=IB?)RPpeXCl?N~Y z(8Ca@p}n~|dT~nk>Jz}@lHzg~&NnrK35<%~826lYtSBaaz58C0M6ZJYIv+sfLuW@k zQT=7EethI)d->td;{aL@fJ)mFzuSvNU=aWdDLL^*yr<*v{gXIAbRQtF*L(9;|K;lN z2Ed~~0P3})B1)OB<99Sy$>49O(kU@Thxx+Mf7jHXp|H1_!NsZ~Zp2&g0X&C)#CHfI z5hS{a6fr|&iFKktl=Zk?)W`Ir`dNLRq{s&HHaSTyk_Adj@l=HBq+U?VRFT%vK{`Q? z(9`rLqhh>Flo@5x%oRDQ_yX9yT(_4zXFbV3y3S z<{9&rMYKdM!uJwfVigm=AwU%t6?V4@Oma}cyE%uQ8zJ1>Q&A!cPxkj#!8{=|Z z+2M7pJ9hXAp5?uKh>!7Ie2SmuvwWT}2|9rlJVH=t5!!?<;ejwIyb)G~f~XZ`@toMv zDh`Qhab8>%H^matAr{Ffh@vQo`q40Yil)#UT0;9$gLFyimL{Z}^j+F_);ZgqY3HWw zmJ@PHo|9MPAFc`)=L)*oTm!DxuFtM*x5_QM8{Dn#q&u1M>gvq_2A~r2(LUs(l~Wk{ z&#^|eveqFSD8N9oZ~ztIzkr3+u(xmwGB1VQx=KF;pa%R<`)oE=t?>tH{I!{U?93^( GGUGpN=e2?W delta 629 zcmW-eT}V>_9L4|Ja!kG7`?|Y#yI;HaGDBq>W-N?`*a}?YL&^}r8EQjx4GOUy)I`L@ zNKt%{RpP^*B&;b|i7c}95+bpu80AC75Qz~6rexiGI{)+gbKt<4O6up5dJpIT0D}=Q zKr|G(e(mu-%KUL8^caE3SQ|EpJ;U<21+T~N;S2Z%ULeW{iD)MJh$OK^6iI{(k}-0EOp&{k zk@8a!YLZ%{K2k;M#9U{NnN#MXrPeZF*|Pk!hOP6~yiISbv^5Xg#%vi|!LHid?aTH( zTBalPIK4@qII0~t921U=*&V ziu^(Tp_mjw2`W)#NO_@rRt{C8>QU>}cC}aSO;?*P+G%b2Qk|Eq5v*QPB+hB4_}^G& z@AGDo3Iu)!bY9i~$7{y-fxv_GQ~s#7)DM2B0w4Hhms%@I{QfGRFTK+mIB(Df{0H#a BvZw$6 diff --git a/resources/lsi-adm-3a/adm-3a.ttf b/resources/lsi-adm-3a/adm-3a.ttf index 32d74918429d412ef453ff8ee5d460812601aeb4..946d149847b1c8749c0053507e150e59f850859d 100644 GIT binary patch delta 635 zcmW+zT}V@L9R1zRt(o`ker&t@y1V!O@9xHo9GeU)m?n`n+!1JFa@zevR*_&e2`dS1TiFP#2!q_kJ(N59e(E=IB?)RPpeXCl?N~Y z(8Ca@p}n~|dT~nk>Jz}@lHzg~&NnrK35<%~826lYtSBaaz58C0M6ZJYIv+sfLuW@k zQT=7EethI)d->td;{aL@fJ)mFzuSvNU=aWdDLL^*yr<*v{gXIAbRQtF*L(9;|K;lN z2Ed~~0P3})B1)OB<99Sy$>49O(kU@Thxx+Mf7jHXp|H1_!NsZ~Zp2&g0X&C)#CHfI z5hS{a6fr|&iFKktl=Zk?)W`Ir`dNLRq{s&HHaSTyk_Adj@l=HBq+U?VRFT%vK{`Q? z(9`rLqhh>Flo@5x%oRDQ_yX9yT(_4zXFbV3y3S z<{9&rMYKdM!uJwfVigm=AwU%t6?V4@Oma}cyE%uQ8zJ1>Q&A!cPxkj#!8{=|Z z+2M7pJ9hXAp5?uKh>!7Ie2SmuvwWT}2|9rlJVH=t5!!?<;ejwIyb)G~f~XZ`@toMv zDh`Qhab8>%H^matAr{Ffh@vQo`q40Yil)#UT0;9$gLFyimL{Z}^j+F_);ZgqY3HWw zmJ@PHo|9MPAFc`)=L)*oTm!DxuFtM*x5_QM8{Dn#q&u1M>gvq_2A~r2(LUs(l~Wk{ z&#^|eveqFSD8N9oZ~ztIzkr3+u(xmwGB1VQx=KF;pa%R<`)oE=t?>tH{I!{U?93^( GGUGpN=e2?W delta 629 zcmW-eT}V>_9L4|Ja!kG7`?|Y#yI;HaGDBq>W-N?`*a}?YL&^}r8EQjx4GOUy)I`L@ zNKt%{RpP^*B&;b|i7c}95+bpu80AC75Qz~6rexiGI{)+gbKt<4O6up5dJpIT0D}=Q zKr|G(e(mu-%KUL8^caE3SQ|EpJ;U<21+T~N;S2Z%ULeW{iD)MJh$OK^6iI{(k}-0EOp&{k zk@8a!YLZ%{K2k;M#9U{NnN#MXrPeZF*|Pk!hOP6~yiISbv^5Xg#%vi|!LHid?aTH( zTBalPIK4@qII0~t921U=*&V ziu^(Tp_mjw2`W)#NO_@rRt{C8>QU>}cC}aSO;?*P+G%b2Qk|Eq5v*QPB+hB4_}^G& z@AGDo3Iu)!bY9i~$7{y-fxv_GQ~s#7)DM2B0w4Hhms%@I{QfGRFTK+mIB(Df{0H#a BvZw$6 diff --git a/resources/lsi-adm-3a/adm3a.sfd b/resources/lsi-adm-3a/adm3a.sfd index 0deb25dcd..4faeecb44 100644 --- a/resources/lsi-adm-3a/adm3a.sfd +++ b/resources/lsi-adm-3a/adm3a.sfd @@ -23,7 +23,7 @@ OS2Version: 0 OS2_WeightWidthSlopeOnly: 0 OS2_UseTypoMetrics: 1 CreationTime: 1663397476 -ModificationTime: 1669137465 +ModificationTime: 1671009524 PfmFamily: 49 TTFWeight: 400 TTFWidth: 5 @@ -54,7 +54,7 @@ NameList: AGL For New Fonts DisplaySize: -48 AntiAlias: 1 FitToEm: 0 -WinInfo: 0 17 19 +WinInfo: 0 25 19 BeginPrivate: 0 EndPrivate Grid @@ -1783,18 +1783,18 @@ SplineSet 832 1792 832 1792 832 1734 c 1,3,4 832 312 832 312 832 256 c 1,5,-1 1013 256 l 0,6,7 - 1088 256 1088 256 1088 128 c 132,-1,9 - 1088 0 1088 0 1013 0 c 2,10,11 - 1013 0 1013 0 395 0 c 0,12,13 - 320 0 320 0 320 127 c 0,14,15 - 320 256 320 256 395 256 c 0,16,-1 - 576 256 l 1,17,18 - 576 256 576 256 576 1280 c 1,19,20 - 538 1280 538 1280 378 1280 c 0,21,22 - 320 1280 320 1280 320 1408 c 128,-1,23 - 320 1536 320 1536 378 1536 c 0,24,-1 - 501 1536 l 0,25,26 - 576 1536 576 1536 576 1611 c 0,27,-1 + 1088 256 1088 256 1088 128 c 132,-1,8 + 1088 0 1088 0 1013 0 c 2,9,10 + 1013 0 1013 0 395 0 c 0,11,12 + 320 0 320 0 320 127 c 0,13,14 + 320 256 320 256 395 256 c 0,15,-1 + 576 256 l 1,16,17 + 576 256 576 256 576 1280 c 1,18,19 + 538 1280 538 1280 378 1280 c 0,20,21 + 320 1280 320 1280 320 1408 c 128,-1,22 + 320 1536 320 1536 378 1536 c 0,23,-1 + 501 1536 l 0,24,25 + 576 1536 576 1536 576 1611 c 0,26,-1 576 1734 l 0,0,1 EndSplineSet Validated: 1 @@ -1803,7 +1803,7 @@ EndChar StartChar: two Encoding: 50 50 48 Width: 1408 -Flags: MWO +Flags: MW LayerCount: 3 Back Image2: image/png 124 64 2048 256 256 @@ -1838,6 +1838,7 @@ SplineSet 64 1280 64 1280 64 1337 c 1,39,40 64 1337 64 1337 64 1461 c 0,0,1 EndSplineSet +Validated: 1 EndChar StartChar: three @@ -2748,7 +2749,7 @@ EndChar StartChar: N Encoding: 78 78 76 Width: 1408 -Flags: MW +Flags: MWO LayerCount: 3 Back Image2: image/png 114 64 2048 256 256 @@ -2759,21 +2760,18 @@ Fore SplineSet 320 1461 m 1,0,-1 1088 693 l 1,1,2 - 1088 693 1088 693 1088 1735 c 0,3,4 - 1088 1792 1088 1792 1216 1792 c 129,-1,5 - 1344 1792 1344 1792 1344 1735 c 1,6,7 - 1344 1735 1344 1735 1344 0 c 1,8,-1 - 1088 0 l 1,9,10 - 1088 304 1088 304 1088 331 c 1,11,-1 - 320 1099 l 1,12,13 - 320 1099 320 1099 320 0 c 1,14,-1 - 64 0 l 1,15,-1 - 64 1735 l 0,16,17 - 64 1792 64 1792 192 1792 c 129,-1,18 - 320 1792 320 1792 320 1735 c 1,19,20 - 320 1598 320 1598 320 1461 c 1,0,-1 + 1088 693 1088 693 1088 1792 c 1,3,4 + 1088 1792 1088 1792 1344 1792 c 1,5,6 + 1344 1792 1344 1792 1344 0 c 1,7,-1 + 1088 0 l 1,8,9 + 1088 0 1088 0 1088 331 c 1,10,-1 + 320 1099 l 1,11,12 + 320 1099 320 1099 320 0 c 1,13,-1 + 64 0 l 1,14,-1 + 64 1792 l 1,15,16 + 64 1792 64 1792 320 1792 c 1,17,18 + 320 1792 320 1792 320 1461 c 1,0,-1 EndSplineSet -Validated: 1 EndChar StartChar: O From 0debfb4e2281a2066851b1455b1aaa25f71511ea Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 16 Dec 2022 18:07:04 +0100 Subject: [PATCH 232/314] 88-dcdd: gui icons replacement + added missing licenses --- .../device/mits88dcdd/DiskSettings.java | 18 ++++++++++++++++ .../device/mits88dcdd/cpmfs/CpmFormat.java | 18 ++++++++++++++++ .../device/mits88dcdd/cpmfs/DateFormat.java | 18 ++++++++++++++++ .../mits88dcdd/cpmfs/DiskParameterBlock.java | 18 ++++++++++++++++ .../mits88dcdd/cpmfs/entry/CpmEntry.java | 18 ++++++++++++++++ .../mits88dcdd/cpmfs/entry/CpmNativeDate.java | 18 ++++++++++++++++ .../cpmfs/entry/CpmPlusDiscLabel.java | 18 ++++++++++++++++ .../cpmfs/entry/CpmPlusPassword.java | 18 ++++++++++++++++ .../mits88dcdd/cpmfs/entry/DateStamp.java | 18 ++++++++++++++++ .../cpmfs/sectorops/Altair8deramp.java | 18 ++++++++++++++++ .../cpmfs/sectorops/Altair8mits.java | 18 ++++++++++++++++ .../cpmfs/sectorops/AltairMinidiskDeramp.java | 18 ++++++++++++++++ .../mits88dcdd/cpmfs/sectorops/SectorOps.java | 18 ++++++++++++++++ .../device/mits88dcdd/gui/DriveButton.java | 5 +++-- .../device/mits88dcdd/gui/SettingsDialog.java | 20 ++++++++---------- .../device/mits88dcdd/gui/selected.gif | Bin 991 -> 0 bytes .../device/mits88dcdd/gui/selected.png | Bin 0 -> 481 bytes .../device/mits88dcdd/gui/unselected.gif | Bin 996 -> 0 bytes .../device/mits88dcdd/gui/unselected.png | Bin 0 -> 481 bytes .../device/mits88sio/gui/SettingsDialog.java | 2 ++ .../device/adm3a/api/ContextAdm3A.java | 18 ++++++++++++++++ .../plugins/device/adm3a/api/Keyboard.java | 18 ++++++++++++++++ .../device/adm3a/api/OutputProvider.java | 18 ++++++++++++++++ .../device/adm3a/gui/DisplayCanvas.java | 18 ++++++++++++++++ .../plugins/device/adm3a/gui/DisplayFont.java | 18 ++++++++++++++++ .../adm3a/gui/DisplayFontJComboRenderer.java | 18 ++++++++++++++++ .../plugins/device/adm3a/gui/GuiUtils.java | 18 ++++++++++++++++ 27 files changed, 374 insertions(+), 13 deletions(-) delete mode 100644 plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/selected.gif create mode 100644 plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/selected.png delete mode 100644 plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/unselected.gif create mode 100644 plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/unselected.png diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java index a48e51c04..33a44f02a 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd; import net.emustudio.emulib.runtime.settings.BasicSettings; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java index fc46821a7..3c91d687a 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs; import com.electronwill.nightconfig.core.Config; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DateFormat.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DateFormat.java index 3c20f7939..a061b7e4e 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DateFormat.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DateFormat.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs; // https://www.seasip.info/Cpm/dosses.html diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DiskParameterBlock.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DiskParameterBlock.java index ce016d5ae..85668b3e1 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DiskParameterBlock.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DiskParameterBlock.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs; import com.electronwill.nightconfig.core.Config; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmEntry.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmEntry.java index 5caeee07f..ebe782966 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmEntry.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmEntry.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs.entry; import java.nio.ByteBuffer; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmNativeDate.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmNativeDate.java index 0ad5a0bc1..61f9bcf89 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmNativeDate.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmNativeDate.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs.entry; import net.emustudio.plugins.device.mits88dcdd.cpmfs.DateFormat; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusDiscLabel.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusDiscLabel.java index 99f23f074..ddaea4820 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusDiscLabel.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusDiscLabel.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs.entry; // https://manpages.debian.org/testing/cpmtools/cpm.5.en.html diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusPassword.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusPassword.java index 4610bc653..bb39b528e 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusPassword.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusPassword.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs.entry; import java.nio.ByteBuffer; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/DateStamp.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/DateStamp.java index 9333efde4..e988cfef4 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/DateStamp.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/DateStamp.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs.entry; import java.time.LocalDate; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8deramp.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8deramp.java index aad2461d6..75e11bd17 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8deramp.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8deramp.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs.sectorops; import net.emustudio.plugins.device.mits88dcdd.cpmfs.Position; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8mits.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8mits.java index 659f1cfad..b0edce7fb 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8mits.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8mits.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs.sectorops; import net.emustudio.plugins.device.mits88dcdd.cpmfs.Position; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/AltairMinidiskDeramp.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/AltairMinidiskDeramp.java index 9b76f2394..9e4298c3e 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/AltairMinidiskDeramp.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/AltairMinidiskDeramp.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs.sectorops; import net.emustudio.plugins.device.mits88dcdd.cpmfs.Position; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/SectorOps.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/SectorOps.java index 7d2e4f432..b3f90f54b 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/SectorOps.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/SectorOps.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.mits88dcdd.cpmfs.sectorops; import net.emustudio.plugins.device.mits88dcdd.cpmfs.Position; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DriveButton.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DriveButton.java index b353fb972..93a9f26d6 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DriveButton.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DriveButton.java @@ -23,13 +23,14 @@ import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.MONOSPACED_PLAIN; public class DriveButton extends JToggleButton { - private final static ImageIcon ICON_OFF = new ImageIcon(DriveButton.class.getResource("/net/emustudio/plugins/device/mits88dcdd/gui/unselected.gif")); - private final static ImageIcon ICON_ON = new ImageIcon(DriveButton.class.getResource("/net/emustudio/plugins/device/mits88dcdd/gui/selected.gif")); + private final static ImageIcon ICON_OFF = new ImageIcon(DriveButton.class.getResource("/net/emustudio/plugins/device/mits88dcdd/gui/unselected.png")); + private final static ImageIcon ICON_ON = new ImageIcon(DriveButton.class.getResource("/net/emustudio/plugins/device/mits88dcdd/gui/selected.png")); public DriveButton(String text, Runnable action) { super(text, ICON_OFF); setToolTipText("Disk is unselected"); setFont(MONOSPACED_PLAIN); + setFocusPainted(false); addActionListener(actionEvent -> action.run()); } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java index c27d54f74..2353f5c3c 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java @@ -271,16 +271,13 @@ private void initComponents() { .addComponent(lblSpt) .addComponent(lblSectorSize)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelImageParametersLayout.createSequentialGroup() - .addComponent(txtSectorsPerTrack, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(panelImageParametersLayout.createSequentialGroup() - .addComponent(txtSectorSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblBytes) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnDriveDefault))) + .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(txtSectorSize) + .addComponent(txtSectorsPerTrack)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblBytes) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnDriveDefault) .addContainerGap()) ); panelImageParametersLayout.setVerticalGroup( @@ -388,7 +385,7 @@ private void initComponents() { .addComponent(btnBrowse) .addComponent(btnUnmountAll)) .addGap(18, 18, 18) - .addComponent(panelImageParameters, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(panelImageParameters, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); GroupLayout panelCpuLayout = new GroupLayout(panelCpu); @@ -569,6 +566,7 @@ private void setupDriveButton(ButtonGroup group, JToggleButton button, int index group.add(button); button.setFont(DRIVE_BUTTON_FONT); button.setIcon(OFF_ICON); + button.setFocusPainted(false); button.addActionListener(e -> updateGUI(index)); } diff --git a/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/selected.gif b/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/selected.gif deleted file mode 100644 index a96e1867e8a0474ac3ea9a39cbf8654e0062a9a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 991 zcmXw&VQ5oV6vzKbU)pX2*Ikn>V_{pchzoC9of&kqbWWq)B&=C^xFPRDyFJ7YZ&FH7 zDVO?)uQIbtY7OaDLK{OULyDBr4^={lB@>k}qy$;JQbsK?si7O)h%R*R?!AY?y_dr| z=YP)caJXHc9clltZwGeZ3BVoW0@wM(Y=SNaq#-H2O8H9;^@3WcC#2iHs#dh0;-atMO68~sb`zd>-uC8l^ycQF0`ur(=Zc|mK)X<_|ob~Z>cV0`(ZK+Z! zu%hK-C8?;*)} z>|)jzO-1RV-xqfmbe@`;C`s$uTqrIBVB27i!3dac@4nCQn1Sdv-~z(tp@1K#0>p5m zu3x8Vje!hf5>Np8;|V;fED>Tv-h;jqL#!)*-`Qk)ZYQlc0|ZU&{BHE(zGaV*Z*Xh_ z{{iPv97AdNSts8NP&V4;fCJ}I_kx&3U2tt;as&zm?FX}gT?V6ICix_T!a%&M?t)UObrv--&JmR8h+i_(**xYw()cWa&!pJU43}*!b_s)I@|M0(`$|UX3F@xweae`{gJ1x@WH7oo{z3^ zcSaxH#rvQC+}_`R$oA7ahYKxl&mN8(+jXQT*w>b8XnOY(Dkpo+fB%9_I9pacGq)6v x*PRajp+p>Sb~P@}>^)RaUl$VUNV3Jxz3~m-7PKC`nrq+&#g_-(>N|k_{{t4Gah3o8 diff --git a/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/selected.png b/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/selected.png new file mode 100644 index 0000000000000000000000000000000000000000..9f2243715986b112a521e009a9181f78628ab7b0 GIT binary patch literal 481 zcmV<70UrK|P)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10d7e| zK~y-6ozuT+(_s|G@z49_XJ&1S2<-*fKUYwkoq|r@fYoj;I_Mz8%p#aU1Zi%;A$4;Q z#2e7I5jt0>VvBQpo8ypQq=gh4pYiZ~AD#o}q=;}@sgu^Qq0%z41hNCgHnyT2gERg~ zKnojxR96TYhz)GmEoNy9A&s)-Ny@BdQDQLZ2Z?-9tI$a%CNEtiCq8cr_rtyC-uplI z|2rqSC!cRSdhEO&dOQG<8eSe5mQS?CdOUO|O*dk4gM(OnqIG#HMo%|oyIgC=>dnIk zX+Dvyx5@qhjg8BC9r=AUHLm0p>T;1JD)qL+>t33UFPHKOw~KDZ>2{JXiVAz=6&H;R zEA@_Sdk6hT>AnE{n5I5&)@n;!6f+e%$`f^YlKsBqIj=GuQyLs;4NtRiYU{|lJy~-# z%_r$fjF|PM$g)NkKj)#F3A!!Q&@hcel*2Z8NR&q+>9&qYkC(nn6C-JBC1=x`+qL#c zb(U3hWjw9lN7LiVwn7X~8de%?={{fF?V%x&3XmSEchG4UeZNfoz6>jHo5<~v`+YPW zBZgGU(~UTNnWPJWOsS5(NYJ88A4e3cEj=Wvm78i*P({E2Yybj^Bfqm0W?n=tXAlY( z6DA>ie+JPYL~(Ke>w8v(Q3FIgk%B%8X@VW&mp99_PDrDL_-YRZoj5ZJrdcRQw`PTd zfxY8<8Q9$Q%1q$T@UE?6ZkHhiG>5Qlg&-AjO)%ZZOcX&8;s8`F)KM^GRfV8pMnzDC z_y(%99Ew(GU$4qr5tIrH$V9R6_YObqsIaP#m|R@|x>2NIKv?5eb1)Q(U(CaK6jBHC zJ*&!jH5XI`QAO(K!Hry{AapYI!h@}DXU-rAOw-c4_?69>>68Z9CipIn+(YM16aSjz z)E20~dp((6ZsVS&*u&E-pIhB=UNet_CI>zE}E~mhQo)< zKFhW9KNu^GPnk@oUi&6wHh22oiuQ!}yf2u%x4K)ej~+1j0*~(vE=?VL)$dsPr-mOp zqPx^QckQb7VatnkpMSEYJziq(p0^y+c-tJ<0p$?7y~u&|qHawO9S|ZF6l|e7L5uCG_EAn$n8IY&N8~xcjzN P61VOKx#v!m@p$HcCoF~5 diff --git a/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/unselected.png b/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/gui/unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..fe51774c6eb2e950c0dd8251a49f0fcd1a4aceb7 GIT binary patch literal 481 zcmV<70UrK|P)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10d7e| zK~y-6ozuT+(_t9J@z49_XJ&1S2<-*fq*qX!oq|r@fYoj;I_Mz8%p#aU1W9heA$4;Q z#2e855jrbWvBf$5{5=l&rKA!e^*g>i=Wrh0^Q4F{OE0AjY!!4W)*$nxWCw$8#KG)* zni}*{YG(Qs+bfi9noIT2G4>fBQzTvn_q!3}Q-fYg%?589Y~G|;M{<_H0Y;R+`EZ%* z+Y!HV9kJhF^Daeej#&NH#vO_V*N%7w=?NS7c#GVcBb>(`UQ=Z@GPaf}*B2D4lU$mt zvXu)uZJP69|BHH^WuMQmPML^8fGf zkeOq8mC}VHp5op`$`;L)TKoeCjO*CXgGb$n@{GZhUP@PSyWmE}DyQc>!mt~0I6MCb Xf)|9U{Vc!i00000NkvXXu0mjfps~|| literal 0 HcmV?d00001 diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java index 39f17241e..0b8809c07 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java @@ -22,6 +22,7 @@ import net.emustudio.plugins.device.mits88sio.SioUnitSettings; import javax.swing.*; +import java.awt.*; import java.awt.event.KeyEvent; import java.util.Objects; @@ -316,6 +317,7 @@ private void initComponents() { btnDataRemove.addActionListener(e -> removePort("data", lstDataPorts, dataPortsModel)); btnDataDefaults.addActionListener(e -> setDefaultDataPorts()); + btnSave.setFont(btnSave.getFont().deriveFont(Font.BOLD)); btnSave.addActionListener(this::btnSaveActionPerformed); pack(); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java index 30bfa8ad6..c93f897d2 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.adm3a.api; import net.emustudio.emulib.plugins.device.DeviceContext; diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/Keyboard.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/Keyboard.java index 52e220d27..492c186f6 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/Keyboard.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/Keyboard.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.adm3a.api; import java.util.List; diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/OutputProvider.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/OutputProvider.java index 0a4a06aa1..2c4b304c0 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/OutputProvider.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/OutputProvider.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.adm3a.api; public interface OutputProvider extends AutoCloseable { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java index 325f20203..99d11b746 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.adm3a.gui; import net.emustudio.plugins.device.adm3a.interaction.Display; diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java index 0ac6d70d0..0d8c4e7b0 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.adm3a.gui; import net.emustudio.plugins.device.adm3a.TerminalSettings; diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java index 8ea2efec5..30779be6f 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.adm3a.gui; import javax.swing.*; diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/GuiUtils.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/GuiUtils.java index c36336e9b..eaf485c04 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/GuiUtils.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/GuiUtils.java @@ -1,3 +1,21 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2022 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.adm3a.gui; import java.awt.*; From e894df39f3ad01d3852c3e574d1edfcb24d4e975 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 16 Dec 2022 20:07:30 +0100 Subject: [PATCH 233/314] README --- README.md | 6 ++---- resources/logo-white.png | Bin 0 -> 28770 bytes logo.png => resources/logo.png | Bin 3 files changed, 2 insertions(+), 4 deletions(-) create mode 100644 resources/logo-white.png rename logo.png => resources/logo.png (100%) diff --git a/README.md b/README.md index 4e0a53513..80d82c08f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ![emuStudio logo](logo.png "emuStudio logo") Welcome to emuStudio +# ![emuStudio logo](resources/logo-white.png "emuStudio logo") Welcome to emuStudio ![emuStudio Build](https://github.com/emustudio/emuStudio/workflows/emuStudio%20Build/badge.svg) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) @@ -59,9 +59,7 @@ which includes information like: - Which tools to use and how to set up the environment - How to compile emuStudio and prepare local releases - Which git branch to use -- Which rules needs to be followed - -Buy Me A Coffee +- Code architecture, naming conventions, best practices ### Related projects diff --git a/resources/logo-white.png b/resources/logo-white.png new file mode 100644 index 0000000000000000000000000000000000000000..bb12d1ed87a039308d5aa5188b46d186d2b333a7 GIT binary patch literal 28770 zcmeI5X=oHl6vrnf9#P|c#w*?@(Re3BqcLF<)VP`zcRh9!)U3m)jq$#9f3a~gb|y77-96Rg*ab# zw7h-$wxpyaKR(!eE04hk5jwK<2-%(v>Bc4ziWMu&_oMY-4N?eS z{rdI$^y!n9mS)w=%=dHl>{;`jxO)g9wc?&ra2_~F$vzhcDF-Q81Z3MeJmnxIi-2r9 zho@wbvc{g09nGU1ZV<&UN38D0;?alFLwk_IXS{IX!nJGHo;-OXPi{<1Ot)^`FmdH? zv9P5*Na3k2T)6Pip+f|Ww95{f-d*#X%_)(_4$i02QZVw`Kv|{DR>G@SuLwvARzRY0w0ZXI z83)Qh@j8&rNFhpScdN`SITn~_pRr}=>#q+~I4kaCccML@Ql!&6@%QsdhF z_2Z{p0NLr=)Xw2AS>S^mDXc1rEH!~_XQvMcT@4yEU}Lp;^X5;VKCOz(4jnqQXwl;Q z`SVpZP*ZOwQn+=sYSkJ$b}R`5xGz-^T(4feMvWSgZGZz*yLNfjlr6ez-K1*LNfvkw!p-o_85>|k40++bD_3+_wLPtAjz2G{>4{SAhmt__O)x*qLsu`@%O5h>NbD= z{86JuNrs#K9m2D{3Zx!Bd`KWTAt3=Rg9ITp+DeDim=PSpfh3(G$bN~iC-HtAt3V2= zA$yNZtK{TlbQAMqBMTD&E2(A6mV)Vm@AK!+D;p3jg>~xGA@`1?Q;r2aSa?YVQrdKR z_}8yr$HD|Sxa{W5n=JWaq*w$n4({B!qa&C_kbOX1WuQ-OKnjvj@Z@Q?Yu8Rp9$Q%C z|B}_JYu2Sp7noGB6{-#?6fmZC!-fs<)AJCSx^>f zP{dPEwQt|Pf`S4t(jY*=b8N;n!8kzWj~+eRC#IG(P=OR{9JrWa9|5U}iHXgcH4`+j z>XHhix_0e~hI;hqkyVrS?59neHVCq3O@NM7AjNV{5t~i{BG1BZgFQNIA*m+2a*&b* z&_T*UN)`dxb`DR;B4y3mhoMXiWcl*tTeohN9XasrD!bNZ#@AzkGlCHr_Cq-2qbAkTuxG~sQ*s~WPMg;{dw6iBO@bX@#4j2&YU4n@WF!zW_u0A`w=+oA$A+X*$uyX^{QWQ zzlI_pRnkOy6R`lCw(|5Xt!N21*!y3KEB9&Q0r^WJg*%;wtrIp-Dr|I+!iggvTDcuE5Nh~1m3pzM>C8LYRp7`Dvus)H6osn44?&u3bt2q{!J1{h3)wq{-9 z8S?RCV!_1D-HELzEKGu%`&ABS(%9V*m@BXWqzz zr-(Z631rxZ@3fE@hZfVm+>Ei$?gNIaPagIS8CO?? z6b2^>i2UEdg9rEQ*%KDc$;pY2k4Lsy?7(Hjh!I!}#BEx)Zmlx?4xXa;M8VnyBBU@5 zP(5gLaDjbzhG;7g;X~FiKOBpC;y02=T*8cjJ}v%og3DF^-}3(vU@dt8>P>_iZ@r+} zc_R^>g}=H2 zvSrH-9z2MUvj{F&umBr})N@vDUP~uc2+u}5*cW|OgcR(9CyesO#bMEbkBBK_*Ps#k zjpfBD1-_#OR}oB=nOEvT7a_%_KKb%EcQ`Z%7bu{-fCHZD-n~28ieLk;1!3|kOBPoT zkb6WCQX@x>Y~Q{;43(6W#DWMDWo2cN76ED?1zt2@t)&6YSPDa!p}_=~y38VaTQ%{*XKnAq6@VH`yp70ManhDyacPin~n+A5;LLc`$qS z>{0waU2uYn1E-r<#onLpf^+IdK->Fs@?PA4_&6xHtwUZJ`@q20W&F+ZEJ& Date: Mon, 19 Dec 2022 12:09:09 +0100 Subject: [PATCH 234/314] 88-dcdd: some gui fixes --- .../device/mits88dcdd/gui/DiskGui.java | 130 +++++++++--------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java index 21865f07e..4d77f3517 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java @@ -106,14 +106,14 @@ private void initComponents() { ButtonGroup buttonGroup1 = new ButtonGroup(); JPanel panelDiskSelection = new JPanel(); JPanel panelFlags = new JPanel(); - JLabel jLabel1 = new JLabel("Port 1:"); - JLabel jLabel2 = new JLabel("Port 2:"); - JPanel jPanel3 = new JPanel(); + JLabel lblPort1Label = new JLabel("Port 1:"); + JLabel lblPort2Label = new JLabel("Port 2:"); + JPanel panelImage = new JPanel(); JScrollPane jScrollPane1 = new JScrollPane(); - JPanel jPanel4 = new JPanel(); - JLabel jLabel3 = new JLabel("Track:"); - JLabel jLabel4 = new JLabel("Sector:"); - JLabel jLabel5 = new JLabel("Offset:"); + JPanel panelPosition = new JPanel(); + JLabel lblTrackLabel = new JLabel("Track:"); + JLabel lblSectorLabel = new JLabel("Sector:"); + JLabel lblOffsetLabel = new JLabel("Offset:"); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); rootPane.registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); @@ -123,7 +123,7 @@ private void initComponents() { panelDiskSelection.setBorder(BorderFactory.createTitledBorder(null, "Disk selection", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | Font.BOLD) + lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) )); for (DriveButton button : driveButtons) { @@ -169,43 +169,43 @@ private void initComponents() { panelFlags.setBorder(BorderFactory.createTitledBorder( null, "Flags and settings", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | Font.BOLD) + lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) )); - GroupLayout jPanel2Layout = new GroupLayout(panelFlags); - panelFlags.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() + GroupLayout panelFlagsLayout = new GroupLayout(panelFlags); + panelFlags.setLayout(panelFlagsLayout); + panelFlagsLayout.setHorizontalGroup( + panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelFlagsLayout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(jLabel2) + .addGroup(panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelFlagsLayout.createSequentialGroup() + .addComponent(lblPort2Label) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblPort2Status)) - .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(jLabel1) + .addGroup(panelFlagsLayout.createSequentialGroup() + .addComponent(lblPort1Label) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblPort1Status))) .addContainerGap(119, Short.MAX_VALUE)) ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() + panelFlagsLayout.setVerticalGroup( + panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelFlagsLayout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) + .addGroup(panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblPort1Label) .addComponent(lblPort1Status)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2) + .addGroup(panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblPort2Label) .addComponent(lblPort2Status)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - jPanel3.setBorder(BorderFactory.createTitledBorder( + panelImage.setBorder(BorderFactory.createTitledBorder( null, "Mounted image", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | Font.BOLD) + lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) )); txtMountedImage.setEditable(false); @@ -216,59 +216,59 @@ private void initComponents() { txtMountedImage.setRows(5); jScrollPane1.setViewportView(txtMountedImage); - GroupLayout jPanel3Layout = new GroupLayout(jPanel3); - jPanel3.setLayout(jPanel3Layout); - jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() + GroupLayout panelImageLayout = new GroupLayout(panelImage); + panelImage.setLayout(panelImageLayout); + panelImageLayout.setHorizontalGroup( + panelImageLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelImageLayout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane1) .addContainerGap()) ); - jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() + panelImageLayout.setVerticalGroup( + panelImageLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelImageLayout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane1) .addContainerGap()) ); - jPanel4.setBorder(BorderFactory.createTitledBorder( + panelPosition.setBorder(BorderFactory.createTitledBorder( null, "Position", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | Font.BOLD) + lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) )); - GroupLayout jPanel4Layout = new GroupLayout(jPanel4); - jPanel4.setLayout(jPanel4Layout); - jPanel4Layout.setHorizontalGroup( - jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel4Layout.createSequentialGroup() + GroupLayout panelPositionLayout = new GroupLayout(panelPosition); + panelPosition.setLayout(panelPositionLayout); + panelPositionLayout.setHorizontalGroup( + panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelPositionLayout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel4) - .addComponent(jLabel3) - .addComponent(jLabel5)) + .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblSectorLabel) + .addComponent(lblTrackLabel) + .addComponent(lblOffsetLabel)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(lblOffset) - .addComponent(lblTrack) - .addComponent(lblSector)) + .addComponent(this.lblTrack) + .addComponent(this.lblSector)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - jPanel4Layout.setVerticalGroup( - jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel4Layout.createSequentialGroup() + panelPositionLayout.setVerticalGroup( + panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelPositionLayout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3) - .addComponent(lblTrack)) + .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblTrackLabel) + .addComponent(this.lblTrack)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4) - .addComponent(lblSector)) + .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblSectorLabel) + .addComponent(this.lblSector)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel5) + .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblOffsetLabel) .addComponent(lblOffset)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -281,11 +281,11 @@ private void initComponents() { .addContainerGap() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(panelDiskSelection, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelImage, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addComponent(panelFlags, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(panelPosition, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( @@ -295,10 +295,10 @@ private void initComponents() { .addComponent(panelDiskSelection, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(jPanel4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelPosition, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(panelFlags, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(panelImage, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); From 695ef7395527301e093957f727c3266b1cc1c1f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Jakub=C4=8Do?= Date: Mon, 26 Dec 2022 09:50:56 +0100 Subject: [PATCH 235/314] Create FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..0b3e43b20 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: vbmacher From 2732e5737afef989b839fb6b04080f94ed57e36d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 26 Dec 2022 14:34:59 +0100 Subject: [PATCH 236/314] New .editorconfig + reformatting --- .editorconfig | 317 +++- .github/ISSUE_TEMPLATE/bug_report.md | 17 +- .github/workflows/build.yml | 20 +- CODE_OF_CONDUCT.md | 6 +- CONTRIBUTING.md | 3 +- README.md | 49 +- RELEASES.md | 88 +- application/README.md | 2 +- application/build.gradle | 20 +- application/src/main/files/README.md | 14 +- .../src/main/files/config/BrainDuck.toml | 72 +- .../src/main/files/config/MITSAltair8800.toml | 267 ++- .../main/files/config/MITSAltair8800Z80.toml | 276 +-- .../files/config/RandomAccessMachineRAM.toml | 110 +- .../config/RandomAccessStoredProgramRASP.toml | 82 +- .../src/main/files/config/SSEMBaby.toml | 72 +- .../net/emustudio/application/Resources.java | 4 +- .../cmdline/AutomationCommand.java | 22 +- .../emustudio/application/cmdline/Runner.java | 56 +- .../emustudio/application/cmdline/Utils.java | 18 +- .../application/emulation/Automation.java | 13 +- .../application/gui/GuiDialogsImpl.java | 20 +- .../emustudio/application/gui/GuiUtils.java | 2 +- .../application/gui/NoGuiDialogsImpl.java | 12 +- .../java/net/emustudio/application/gui/P.java | 33 +- .../application/gui/ToolbarToggleButton.java | 3 +- .../gui/actions/CompileAction.java | 6 +- .../gui/actions/ViewComputerAction.java | 2 +- .../gui/actions/editor/FindAction.java | 3 +- .../actions/editor/FindPreviousAction.java | 2 +- .../actions/emulator/BreakpointAction.java | 4 +- .../gui/actions/emulator/JumpAction.java | 20 +- .../emulator/JumpToBeginningAction.java | 4 +- .../gui/actions/emulator/RunTimedAction.java | 4 +- .../actions/emulator/ShowMemoryAction.java | 10 +- .../opencomputer/AddNewComputerAction.java | 26 +- .../opencomputer/DeleteComputerAction.java | 26 +- .../opencomputer/EditComputerAction.java | 18 +- .../opencomputer/OpenComputerAction.java | 12 +- .../opencomputer/RenameComputerAction.java | 34 +- .../opencomputer/SaveSchemaAction.java | 4 +- .../gui/debugtable/DebugTableImpl.java | 2 +- .../gui/debugtable/DebugTableModelImpl.java | 4 +- .../gui/debugtable/PagesPanel.java | 58 +- .../debugtable/PaginatingDisassembler.java | 26 +- .../application/gui/dialogs/AboutDialog.java | 96 +- .../application/gui/dialogs/AutoDialog.java | 33 +- .../gui/dialogs/BreakpointDialog.java | 25 +- .../application/gui/dialogs/EditorPanel.java | 58 +- .../gui/dialogs/EmulatorPanel.java | 72 +- .../gui/dialogs/LoadingDialog.java | 22 +- .../gui/dialogs/OpenComputerDialog.java | 88 +- .../gui/dialogs/PluginComboModel.java | 10 +- .../gui/dialogs/SchemaEditorDialog.java | 134 +- .../application/gui/dialogs/StudioFrame.java | 41 +- .../gui/dialogs/ViewComputerDialog.java | 202 +- .../application/gui/editor/Editor.java | 4 +- .../application/gui/editor/REditor.java | 22 +- .../application/gui/editor/RTokenMaker.java | 58 +- .../application/gui/schema/DrawingModel.java | 17 +- .../application/gui/schema/DrawingPanel.java | 60 +- .../application/gui/schema/Schema.java | 70 +- .../gui/schema/SchemaPreviewPanel.java | 22 +- .../gui/schema/elements/CompilerElement.java | 10 +- .../gui/schema/elements/ConnectionLine.java | 447 +++-- .../gui/schema/elements/CpuElement.java | 10 +- .../gui/schema/elements/DeviceElement.java | 10 +- .../gui/schema/elements/Element.java | 15 +- .../gui/schema/elements/MemoryElement.java | 10 +- .../gui/schema/mode/AbstractMode.java | 1 - .../gui/schema/mode/ModeSelector.java | 17 +- .../gui/schema/mode/ModelingMode.java | 7 +- .../gui/schema/mode/MovingMode.java | 2 +- .../application/internal/Hashing.java | 2 +- .../application/internal/Unchecked.java | 2 +- .../application/settings/AppSettings.java | 12 +- .../application/settings/ComputerConfig.java | 40 +- .../application/settings/ConfigFiles.java | 38 +- .../application/settings/PluginConfig.java | 26 +- .../settings/PluginConnection.java | 20 +- .../settings/PluginSettingsImpl.java | 2 +- .../application/settings/SchemaPoint.java | 26 +- .../virtualcomputer/ContextPoolImpl.java | 72 +- .../InvalidPluginException.java | 1 - .../virtualcomputer/PluginConnections.java | 8 +- .../virtualcomputer/PluginLoader.java | 44 +- .../virtualcomputer/VirtualComputer.java | 183 +- .../emustudio/application/version.properties | 1 - .../emulation/EmulationControllerTest.java | 2 +- .../gui/debugtable/MockHelper.java | 14 +- .../PaginatingDisassemblerTest.java | 126 +- .../settings/ComputerConfigTest.java | 6 +- .../settings/PluginConfigTest.java | 6 +- .../application/settings/SchemaPointTest.java | 4 +- .../virtualcomputer/ContextPoolImplTest.java | 41 +- .../virtualcomputer/PluginLoaderTest.java | 4 +- .../virtualcomputer/stubs/CPUImplStub.java | 3 +- .../stubs/UnannotatedCPUStub.java | 3 +- build.gradle | 56 +- plugins/compiler/as-8080/build.gradle | 6 +- .../compiler/as8080/Assembler8080.java | 35 +- .../plugins/compiler/as8080/CompileError.java | 24 +- .../compiler/as8080/LexicalAnalyzerImpl.java | 17 +- .../compiler/as8080/ParserErrorListener.java | 12 +- .../compiler/as8080/ast/NameSpace.java | 4 +- .../plugins/compiler/as8080/ast/Node.java | 5 +- .../plugins/compiler/as8080/ast/Program.java | 7 +- .../compiler/as8080/ast/expr/ExprInfix.java | 5 +- .../compiler/as8080/ast/expr/ExprUnary.java | 14 +- .../compiler/as8080/ast/instr/InstrExpr.java | 7 +- .../as8080/ast/instr/InstrNoArgs.java | 3 +- .../compiler/as8080/ast/instr/InstrReg.java | 7 +- .../as8080/ast/instr/InstrRegPair.java | 8 +- .../as8080/ast/instr/InstrRegReg.java | 4 +- .../as8080/ast/pseudo/PseudoLabel.java | 2 +- .../visitors/CheckDeclarationsVisitor.java | 15 +- .../as8080/visitors/CreateLineVisitor.java | 2 +- .../as8080/visitors/CreatePseudoVisitor.java | 2 +- .../as8080/visitors/EvaluateExprVisitor.java | 53 +- .../visitors/ExpandIncludesVisitor.java | 20 +- .../as8080/visitors/ExpandMacrosVisitor.java | 2 +- .../as8080/visitors/GenerateCodeVisitor.java | 38 +- .../visitors/SortMacroArgumentsVisitor.java | 4 +- .../compiler/as8080/version.properties | 1 - .../plugins/compiler/as8080/Utils.java | 38 +- .../as8080/e2e/AbstractCompilerTest.java | 15 +- .../as8080/e2e/Assembler8080Test.java | 86 +- .../as8080/e2e/ConstantsAndVariablesTest.java | 42 +- .../plugins/compiler/as8080/e2e/DataTest.java | 72 +- .../compiler/as8080/e2e/IfNodeTest.java | 40 +- .../compiler/as8080/e2e/IncludeTest.java | 56 +- .../compiler/as8080/e2e/InstrExprTest.java | 14 +- .../compiler/as8080/e2e/InstrRegTest.java | 180 +- .../compiler/as8080/e2e/MacroTest.java | 92 +- .../compiler/as8080/e2e/PseudoOrgTest.java | 84 +- .../parser/LexicalAnalyzerImplTest.java | 22 +- .../compiler/as8080/parser/ParseDataTest.java | 78 +- .../compiler/as8080/parser/ParseExprTest.java | 240 +-- .../as8080/parser/ParseInstrTest.java | 42 +- .../as8080/parser/ParsePseudoTest.java | 114 +- .../as8080/parser/ParsingUtilsTest.java | 12 +- .../visitors/CheckExprSizesVisitorTest.java | 108 +- .../visitors/EvaluateExprVisitorTest.java | 444 ++--- .../visitors/ExpandIncludesVisitorTest.java | 20 +- .../as8080/visitors/ExpandMacrosTest.java | 58 +- .../visitors/GenerateCodeVisitorTest.java | 638 +++---- .../SortMacroArgumentsVisitorTest.java | 190 +- plugins/compiler/as-ssem/README.md | 3 +- plugins/compiler/as-ssem/build.gradle | 6 +- .../plugins/compiler/ssem/CodeGenerator.java | 2 +- .../plugins/compiler/ssem/CompilerChecks.java | 4 +- .../compiler/ssem/LexicalAnalyzerImpl.java | 4 +- .../compiler/ssem/ParserErrorListener.java | 12 +- .../plugins/compiler/ssem/SSEMCompiler.java | 14 +- .../compiler/ssem/ast/Instruction.java | 18 +- .../plugins/compiler/ssem/ast/Program.java | 5 +- .../compiler/ssem/ast/ProgramParser.java | 6 +- .../plugins/compiler/ssem/version.properties | 1 - .../plugins/compiler/ssem/ParserTest.java | 90 +- .../compiler/ssem/SSEMCompilerTest.java | 25 +- .../plugins/compiler/ssem/Utils.java | 13 +- plugins/compiler/as-z80/build.gradle | 6 +- .../plugins/compiler/asZ80/AssemblerZ80.java | 39 +- .../plugins/compiler/asZ80/CompileError.java | 36 +- .../compiler/asZ80/CompilerTables.java | 12 +- .../compiler/asZ80/LexicalAnalyzerImpl.java | 3 +- .../plugins/compiler/asZ80/Pair.java | 2 +- .../compiler/asZ80/ParserErrorListener.java | 12 +- .../plugins/compiler/asZ80/ast/NameSpace.java | 5 +- .../plugins/compiler/asZ80/ast/Node.java | 21 +- .../plugins/compiler/asZ80/ast/Program.java | 7 +- .../compiler/asZ80/ast/expr/ExprInfix.java | 5 +- .../compiler/asZ80/ast/expr/ExprString.java | 2 +- .../compiler/asZ80/ast/expr/ExprUnary.java | 14 +- .../compiler/asZ80/ast/instr/Instr.java | 4 +- .../compiler/asZ80/ast/instr/InstrCB.java | 17 +- .../compiler/asZ80/ast/instr/InstrED.java | 17 +- .../compiler/asZ80/ast/instr/InstrXD.java | 6 +- .../compiler/asZ80/ast/instr/InstrXDCB.java | 21 +- .../asZ80/ast/pseudo/PseudoLabel.java | 2 +- .../visitors/CheckDeclarationsVisitor.java | 15 +- .../visitors/CollectExprsInOpcodeVisitor.java | 42 +- .../asZ80/visitors/CreateInstrVisitor.java | 30 +- .../asZ80/visitors/CreateLineVisitor.java | 5 +- .../asZ80/visitors/CreateProgramVisitor.java | 2 +- .../asZ80/visitors/CreatePseudoVisitor.java | 2 +- .../asZ80/visitors/EvaluateExprVisitor.java | 53 +- .../asZ80/visitors/ExpandIncludesVisitor.java | 22 +- .../asZ80/visitors/ExpandMacrosVisitor.java | 2 +- .../asZ80/visitors/GenerateCodeVisitor.java | 30 +- .../visitors/SortMacroArgumentsVisitor.java | 4 +- .../plugins/compiler/asZ80/version.properties | 1 - .../plugins/compiler/asZ80/Utils.java | 62 +- .../asZ80/e2e/AbstractCompilerTest.java | 15 +- .../compiler/asZ80/e2e/AssemblerZ80Test.java | 1634 ++++++++--------- .../asZ80/e2e/ConstantsAndVariablesTest.java | 42 +- .../plugins/compiler/asZ80/e2e/DataTest.java | 72 +- .../compiler/asZ80/e2e/IfNodeTest.java | 40 +- .../compiler/asZ80/e2e/IncludeTest.java | 58 +- .../compiler/asZ80/e2e/InstrExprTest.java | 28 +- .../compiler/asZ80/e2e/InstrRegTest.java | 180 +- .../plugins/compiler/asZ80/e2e/MacroTest.java | 92 +- .../compiler/asZ80/e2e/PseudoOrgTest.java | 84 +- .../asZ80/parser/LexicalAnalyzerImplTest.java | 24 +- .../compiler/asZ80/parser/ParseDataTest.java | 78 +- .../compiler/asZ80/parser/ParseExprTest.java | 240 +-- .../compiler/asZ80/parser/ParseInstrTest.java | 44 +- .../asZ80/parser/ParsePseudoTest.java | 114 +- .../asZ80/parser/ParsingUtilsTest.java | 12 +- .../visitors/CheckExprSizesVisitorTest.java | 108 +- .../visitors/EvaluateExprVisitorTest.java | 448 ++--- .../visitors/ExpandIncludesVisitorTest.java | 20 +- .../asZ80/visitors/ExpandMacrosTest.java | 58 +- .../visitors/GenerateCodeVisitorTest.java | 54 +- .../SortMacroArgumentsVisitorTest.java | 193 +- plugins/compiler/brainc-brainduck/README.md | 3 +- .../compiler/brainc-brainduck/build.gradle | 6 +- .../compiler/brainduck/CompilerImpl.java | 2 +- .../brainduck/LexicalAnalyzerImpl.java | 4 +- .../brainduck/ParserErrorListener.java | 12 +- .../compiler/brainduck/ast/Instruction.java | 18 +- .../compiler/brainduck/version.properties | 1 - .../brainduck/AbstractCompilerTest.java | 15 +- .../compiler/brainduck/InstructionTest.java | 30 +- plugins/compiler/ramc-ram/build.gradle | 6 +- .../plugins/compiler/ram/CompilerRAM.java | 4 +- .../compiler/ram/LexicalAnalyzerImpl.java | 3 +- .../compiler/ram/ParserErrorListener.java | 12 +- .../plugins/compiler/ram/ProgramParser.java | 2 +- .../compiler/ram/SerializableOptional.java | 8 +- .../plugins/compiler/ram/ast/Instruction.java | 12 +- .../plugins/compiler/ram/ast/Label.java | 6 +- .../plugins/compiler/ram/ast/Program.java | 10 +- .../plugins/compiler/ram/ast/Value.java | 2 +- .../plugins/compiler/ram/version.properties | 1 - .../compiler/ram/AbstractCompilerTest.java | 13 +- .../plugins/compiler/ram/CompilerTest.java | 82 +- .../plugins/compiler/ram/MemoryStub.java | 8 +- plugins/compiler/raspc-rasp/README.md | 3 +- plugins/compiler/raspc-rasp/build.gradle | 6 +- .../plugins/compiler/rasp/CompilerRASP.java | 6 +- .../compiler/rasp/LexicalAnalyzerImpl.java | 3 +- .../compiler/rasp/ParserErrorListener.java | 12 +- .../plugins/compiler/rasp/ProgramParser.java | 8 +- .../compiler/rasp/ast/Instruction.java | 8 +- .../plugins/compiler/rasp/ast/Label.java | 6 +- .../plugins/compiler/rasp/version.properties | 1 - .../compiler/rasp/AbstractCompilerTest.java | 13 +- .../plugins/compiler/rasp/CompilerTest.java | 22 +- .../plugins/compiler/rasp/MemoryStub.java | 8 +- plugins/cpu/8080-cpu/build.gradle | 4 +- .../cpu/intel8080/Context8080Impl.java | 2 +- .../plugins/cpu/intel8080/CpuImpl.java | 8 +- .../plugins/cpu/intel8080/DispatchTables.java | 4 +- .../plugins/cpu/intel8080/EmulatorEngine.java | 43 +- .../plugins/cpu/intel8080/EmulatorTables.java | 134 +- .../cpu/intel8080/InstructionPrinter.java | 9 +- .../cpu/intel8080/api/DefaultInitializer.java | 6 +- .../cpu/intel8080/gui/StatusPanel.java | 136 +- .../plugins/cpu/intel8080/version.properties | 1 - .../plugins/cpu/intel8080/ArithmeticTest.java | 196 +- .../plugins/cpu/intel8080/ControlTest.java | 160 +- .../plugins/cpu/intel8080/CpuImplTest.java | 4 +- .../cpu/intel8080/InstructionsTest.java | 14 +- .../plugins/cpu/intel8080/LogicTest.java | 174 +- .../plugins/cpu/intel8080/StackTest.java | 36 +- .../plugins/cpu/intel8080/TransferTest.java | 268 +-- .../cpu/intel8080/suite/ByteTestBuilder.java | 4 +- .../cpu/intel8080/suite/CpuRunnerImpl.java | 10 +- .../cpu/intel8080/suite/CpuVerifierImpl.java | 20 +- .../cpu/intel8080/suite/FlagsCheckImpl.java | 24 +- plugins/cpu/brainduck-cpu/README.md | 3 +- plugins/cpu/brainduck-cpu/build.gradle | 4 +- .../plugins/cpu/brainduck/Profiler.java | 95 +- .../cpu/brainduck/gui/ColumnsRepainter.java | 40 +- .../cpu/brainduck/gui/StatusPanel.java | 330 ++-- .../plugins/cpu/brainduck/version.properties | 1 - .../plugins/cpu/brainduck/CpuImplTest.java | 35 +- .../cpu/brainduck/EmulatorEngineTest.java | 50 +- .../plugins/cpu/brainduck/MemoryStub.java | 4 +- plugins/cpu/ram-cpu/build.gradle | 4 +- .../emustudio/plugins/cpu/ram/CpuImpl.java | 10 +- .../plugins/cpu/ram/EmulatorEngine.java | 61 +- .../plugins/cpu/ram/RAMCpuContextImpl.java | 4 +- .../plugins/cpu/ram/gui/RAMDisassembler.java | 2 +- .../plugins/cpu/ram/gui/RAMStatusPanel.java | 155 +- .../plugins/cpu/ram/version.properties | 1 - .../plugins/cpu/ram/AbstractEngineTest.java | 1 - .../plugins/cpu/ram/CpuImplTest.java | 1 - .../plugins/cpu/ram/EmulatorEngineTest.java | 24 +- plugins/cpu/rasp-cpu/build.gradle | 4 +- .../emustudio/plugins/cpu/rasp/CpuImpl.java | 11 +- .../plugins/cpu/rasp/EmulatorEngine.java | 102 +- .../cpu/rasp/gui/RASPCpuStatusPanel.java | 89 +- .../cpu/rasp/gui/RASPDisassembler.java | 4 +- .../plugins/cpu/rasp/version.properties | 1 - .../plugins/cpu/rasp/EmulatorEngineTest.java | 28 +- .../plugins/cpu/rasp/MemoryStub.java | 8 +- .../emustudio/plugins/cpu/rasp/RASPCell.java | 16 +- plugins/cpu/ssem-cpu/build.gradle | 4 +- .../emustudio/plugins/cpu/ssem/CpuImpl.java | 12 +- .../plugins/cpu/ssem/EmulatorEngine.java | 24 +- .../plugins/cpu/ssem/TimingEstimator.java | 72 +- .../plugins/cpu/ssem/gui/CpuPanel.java | 387 ++-- .../plugins/cpu/ssem/version.properties | 1 - .../plugins/cpu/ssem/CpuImplTest.java | 1 - .../plugins/cpu/ssem/DisassemblerTest.java | 15 +- .../plugins/cpu/ssem/EmulatorEngineTest.java | 20 +- plugins/cpu/z80-cpu/build.gradle | 4 +- .../plugins/cpu/zilogZ80/ContextZ80Impl.java | 23 +- .../plugins/cpu/zilogZ80/CpuImpl.java | 8 +- .../plugins/cpu/zilogZ80/DispatchTables.java | 3 +- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 148 +- .../plugins/cpu/zilogZ80/EmulatorTables.java | 306 ++- .../cpu/zilogZ80/InstructionPrinter.java | 17 +- .../plugins/cpu/zilogZ80/api/ContextZ80.java | 2 +- .../plugins/cpu/zilogZ80/gui/StatusPanel.java | 663 ++++--- .../plugins/cpu/zilogZ80/version.properties | 1 - .../plugins/cpu/zilogZ80/ArithmeticTest.java | 856 ++++----- .../plugins/cpu/zilogZ80/BitTest.java | 798 ++++---- .../plugins/cpu/zilogZ80/ControlTest.java | 300 +-- .../plugins/cpu/zilogZ80/CpuImplTest.java | 1 - .../cpu/zilogZ80/DisassemblerTest.java | 1554 ++++++++-------- .../zilogZ80/EmulatorTablesGeneration.java | 28 +- .../plugins/cpu/zilogZ80/FakeByteDevice.java | 8 +- .../plugins/cpu/zilogZ80/IOTest.java | 340 ++-- .../cpu/zilogZ80/InstructionsTest.java | 10 +- .../plugins/cpu/zilogZ80/LogicTest.java | 1076 +++++------ .../plugins/cpu/zilogZ80/StackTest.java | 60 +- .../plugins/cpu/zilogZ80/TransferTest.java | 638 +++---- .../cpu/zilogZ80/suite/ByteTestBuilder.java | 6 +- .../cpu/zilogZ80/suite/CpuRunnerImpl.java | 10 +- .../cpu/zilogZ80/suite/CpuVerifierImpl.java | 111 +- .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 24 +- .../zilogZ80/suite/IntegerTestBuilder.java | 6 +- plugins/device/88-dcdd/build.gradle | 4 +- .../plugins/device/mits88dcdd/DeviceImpl.java | 4 +- .../device/mits88dcdd/DiskSettings.java | 59 +- .../plugins/device/mits88dcdd/Resources.java | 2 +- .../device/mits88dcdd/cmdline/Cpmfs.java | 10 +- .../device/mits88dcdd/cmdline/Runner.java | 65 +- .../mits88dcdd/cpmfs/CpmFileSystem.java | 222 ++- .../device/mits88dcdd/cpmfs/CpmFormat.java | 107 +- .../mits88dcdd/cpmfs/DiskParameterBlock.java | 46 +- .../device/mits88dcdd/cpmfs/DriveIO.java | 48 +- .../mits88dcdd/cpmfs/entry/CpmFile.java | 58 +- .../mits88dcdd/cpmfs/entry/CpmNativeDate.java | 38 +- .../cpmfs/entry/CpmPlusDiscLabel.java | 2 +- .../cpmfs/entry/CpmPlusPassword.java | 2 +- .../cpmfs/sectorops/Altair8deramp.java | 32 +- .../cpmfs/sectorops/Altair8mits.java | 52 +- .../cpmfs/sectorops/AltairMinidiskDeramp.java | 32 +- .../mits88dcdd/cpmfs/sectorops/SectorOps.java | 29 +- .../device/mits88dcdd/drive/Drive.java | 35 +- .../mits88dcdd/drive/DriveCollection.java | 37 +- .../mits88dcdd/drive/DriveParameters.java | 12 +- .../device/mits88dcdd/gui/DiskGui.java | 259 ++- .../device/mits88dcdd/gui/SettingsDialog.java | 531 +++--- .../device/mits88dcdd/ports/DataPort.java | 2 +- .../device/mits88dcdd/version.properties | 1 - .../device/mits88dcdd/DeviceImplTest.java | 1 - plugins/device/88-sio/build.gradle | 4 +- .../plugins/device/mits88sio/DeviceImpl.java | 10 +- .../device/mits88sio/SioUnitSettings.java | 58 +- .../plugins/device/mits88sio/UART.java | 40 +- .../device/mits88sio/gui/PortListModel.java | 2 +- .../device/mits88sio/gui/SettingsDialog.java | 353 ++-- .../plugins/device/mits88sio/gui/SioGui.java | 266 ++- .../device/mits88sio/version.properties | 1 - .../device/mits88sio/DeviceImplTest.java | 5 +- .../plugins/device/mits88sio/SioUnitTest.java | 6 +- .../plugins/device/mits88sio/UARTTest.java | 1 - plugins/device/abstract-tape/README.md | 2 + plugins/device/abstract-tape/build.gradle | 4 +- .../device/abstracttape/AbstractTape.java | 6 +- .../abstracttape/AbstractTapeContextImpl.java | 29 +- .../abstracttape/api/AbstractTapeContext.java | 15 +- .../device/abstracttape/api/TapeSymbol.java | 10 +- .../abstracttape/gui/SettingsDialog.java | 41 +- .../device/abstracttape/gui/TapeGui.java | 90 +- .../device/abstracttape/version.properties | 1 - plugins/device/adm3A-terminal/README.md | 3 +- plugins/device/adm3A-terminal/build.gradle | 4 +- .../plugins/device/adm3a/DeviceImpl.java | 24 +- .../device/adm3a/TerminalSettings.java | 42 +- .../emustudio/plugins/device/adm3a/Utils.java | 14 +- .../device/adm3a/gui/ConfigDialog.java | 210 ++- .../device/adm3a/gui/DisplayCanvas.java | 16 +- .../plugins/device/adm3a/gui/DisplayFont.java | 8 +- .../device/adm3a/gui/TerminalWindow.java | 1 - .../device/adm3a/interaction/Cursor.java | 11 +- .../adm3a/interaction/LoadCursorPosition.java | 11 +- .../plugins/device/adm3a/version.properties | 1 - .../plugins/device/adm3a/DeviceImplTest.java | 2 +- plugins/device/brainduck-terminal/README.md | 3 +- .../device/brainduck-terminal/build.gradle | 4 +- .../brainduck/terminal/BrainTerminalGui.java | 86 +- .../device/brainduck/terminal/io/Cursor.java | 8 +- .../device/brainduck/terminal/io/Display.java | 3 +- .../brainduck/terminal/io/FileIOProvider.java | 5 +- .../brainduck/terminal/io/Keyboard.java | 16 +- .../brainduck/terminal/version.properties | 1 - plugins/device/simh-pseudo/README.md | 3 +- plugins/device/simh-pseudo/build.gradle | 4 +- .../plugins/device/simh/Commands.java | 21 +- .../plugins/device/simh/DeviceImpl.java | 6 +- .../plugins/device/simh/PseudoContext.java | 21 +- .../device/simh/commands/AttachPTP.java | 2 +- .../device/simh/commands/GenInterrupt.java | 4 +- .../device/simh/commands/GetBankSelect.java | 2 +- .../simh/commands/GetCPUClockFrequency.java | 7 +- .../device/simh/commands/GetClockCPM3.java | 6 +- .../device/simh/commands/GetClockZSDOS.java | 2 +- .../device/simh/commands/GetCommon.java | 4 +- .../simh/commands/GetHostFilenames.java | 27 +- .../device/simh/commands/HasBankedMemory.java | 2 +- .../device/simh/commands/ReadStopWatch.java | 4 +- .../plugins/device/simh/commands/ReadURL.java | 6 +- .../device/simh/commands/SetClockCPM3.java | 16 +- .../device/simh/commands/SetClockZSDOS.java | 11 +- .../device/simh/commands/SetTimerDelta.java | 3 +- .../simh/commands/SetTimerInterruptAdr.java | 3 +- .../simh/commands/StartTimerInterrupts.java | 2 +- .../plugins/device/simh/version.properties | 1 - plugins/device/ssem-display/build.gradle | 4 +- .../device/ssem/display/DeviceImpl.java | 6 +- .../device/ssem/display/DisplayGui.java | 23 +- .../device/ssem/display/DisplayPanel.java | 8 +- .../device/ssem/display/version.properties | 1 - .../device/zxspectrum-display/build.gradle | 4 +- .../device/zxspectrum/display/DeviceImpl.java | 2 +- .../display/ZxSpectrumDisplayGui.java | 100 +- .../device/zxspectrum/display/io/Display.java | 49 +- .../zxspectrum/display/io/Keyboard.java | 2 +- .../zxspectrum/display/version.properties | 1 - plugins/memory/byte-mem/README.md | 6 +- plugins/memory/byte-mem/build.gradle | 4 +- .../memory/bytemem/MemoryContextImpl.java | 24 +- .../plugins/memory/bytemem/MemoryImpl.java | 17 +- .../memory/bytemem/api/ByteMemoryContext.java | 26 +- .../plugins/memory/bytemem/gui/Constants.java | 2 +- .../bytemem/gui/FindSequenceDialog.java | 129 +- .../plugins/memory/bytemem/gui/MemoryGui.java | 301 +-- .../bytemem/gui/SelectBankAddressDialog.java | 56 +- .../memory/bytemem/gui/SettingsDialog.java | 247 ++- .../gui/actions/FindSequenceAction.java | 3 +- .../bytemem/gui/model/FileImagesModel.java | 25 +- .../bytemem/gui/model/MemoryTableModel.java | 26 +- .../memory/bytemem/gui/model/ROMmodel.java | 2 +- .../memory/bytemem/gui/model/TableMemory.java | 8 +- .../plugins/memory/bytemem/version.properties | 1 - .../memory/bytemem/MemoryImplTest.java | 3 +- plugins/memory/ram-mem/build.gradle | 4 +- .../plugins/memory/ram/MemoryContextImpl.java | 12 +- .../plugins/memory/ram/MemoryImpl.java | 15 +- .../memory/ram/api/RAMInstruction.java | 36 +- .../memory/ram/api/RAMMemoryContext.java | 4 +- .../plugins/memory/ram/api/RAMValue.java | 14 +- .../plugins/memory/ram/gui/MemoryDialog.java | 3 +- .../plugins/memory/ram/version.properties | 1 - .../memory/ram/MemoryContextImplTest.java | 6 +- .../plugins/memory/ram/MemoryImplTest.java | 1 - plugins/memory/rasp-mem/build.gradle | 4 +- .../memory/rasp/MemoryContextImpl.java | 76 +- .../plugins/memory/rasp/MemoryImpl.java | 8 +- .../memory/rasp/api/RASPMemoryCell.java | 2 +- .../memory/rasp/api/RASPMemoryContext.java | 4 +- .../plugins/memory/rasp/gui/Disassembler.java | 3 +- .../plugins/memory/rasp/gui/MemoryDialog.java | 25 +- .../memory/rasp/gui/RASPTableModel.java | 10 +- .../plugins/memory/rasp/version.properties | 1 - .../plugins/memory/rasp/MemoryImplTest.java | 1 - plugins/memory/ssem-mem/build.gradle | 4 +- .../memory/ssem/MemoryContextImpl.java | 1 - .../plugins/memory/ssem/MemoryImpl.java | 8 +- .../plugins/memory/ssem/gui/Constants.java | 10 +- .../plugins/memory/ssem/gui/MemoryGui.java | 43 +- .../memory/ssem/gui/MemoryTableModel.java | 40 +- .../plugins/memory/ssem/version.properties | 1 - 479 files changed, 13290 insertions(+), 13121 deletions(-) diff --git a/.editorconfig b/.editorconfig index 522ec2d02..aa3f542cd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,23 +1,322 @@ root = true [*] +charset = utf-8 end_of_line = lf +indent_size = 4 +indent_style = space insert_final_newline = true +max_line_length = 120 +tab_width = 4 +trim_trailing_whitespace = true +ij_continuation_indent_size = 8 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = false +ij_smart_tabs = false +ij_visual_guides = none +ij_wrap_on_typing = false -[*.bat] -end_of_line = crlf +[*.java] +ij_java_align_consecutive_assignments = false +ij_java_align_consecutive_variable_declarations = false +ij_java_align_group_field_declarations = false +ij_java_align_multiline_annotation_parameters = false +ij_java_align_multiline_array_initializer_expression = false +ij_java_align_multiline_assignment = false +ij_java_align_multiline_binary_operation = false +ij_java_align_multiline_chained_methods = false +ij_java_align_multiline_extends_list = false +ij_java_align_multiline_for = true +ij_java_align_multiline_method_parentheses = false +ij_java_align_multiline_parameters = true +ij_java_align_multiline_parameters_in_calls = false +ij_java_align_multiline_parenthesized_expression = false +ij_java_align_multiline_records = true +ij_java_align_multiline_resources = true +ij_java_align_multiline_ternary_operation = false +ij_java_align_multiline_text_blocks = false +ij_java_align_multiline_throws_list = false +ij_java_align_subsequent_simple_methods = false +ij_java_align_throws_keyword = false +ij_java_align_types_in_multi_catch = true +ij_java_annotation_parameter_wrap = off +ij_java_array_initializer_new_line_after_left_brace = false +ij_java_array_initializer_right_brace_on_new_line = false +ij_java_array_initializer_wrap = off +ij_java_assert_statement_colon_on_next_line = false +ij_java_assert_statement_wrap = off +ij_java_assignment_wrap = off +ij_java_binary_operation_sign_on_next_line = false +ij_java_binary_operation_wrap = off +ij_java_blank_lines_after_anonymous_class_header = 0 +ij_java_blank_lines_after_class_header = 0 +ij_java_blank_lines_after_imports = 1 +ij_java_blank_lines_after_package = 1 +ij_java_blank_lines_around_class = 1 +ij_java_blank_lines_around_field = 0 +ij_java_blank_lines_around_field_in_interface = 0 +ij_java_blank_lines_around_initializer = 1 +ij_java_blank_lines_around_method = 1 +ij_java_blank_lines_around_method_in_interface = 1 +ij_java_blank_lines_before_class_end = 0 +ij_java_blank_lines_before_imports = 1 +ij_java_blank_lines_before_method_body = 0 +ij_java_blank_lines_before_package = 0 +ij_java_block_brace_style = end_of_line +ij_java_block_comment_add_space = false +ij_java_block_comment_at_first_column = true +ij_java_builder_methods = none +ij_java_call_parameters_new_line_after_left_paren = false +ij_java_call_parameters_right_paren_on_new_line = false +ij_java_call_parameters_wrap = off +ij_java_case_statement_on_separate_line = true +ij_java_catch_on_new_line = false +ij_java_class_annotation_wrap = split_into_lines +ij_java_class_brace_style = end_of_line +ij_java_class_count_to_use_import_on_demand = 5 +ij_java_class_names_in_javadoc = 1 +ij_java_do_not_indent_top_level_class_members = false +ij_java_do_not_wrap_after_single_annotation = false +ij_java_do_not_wrap_after_single_annotation_in_parameter = false +ij_java_do_while_brace_force = never +ij_java_doc_add_blank_line_after_description = true +ij_java_doc_add_blank_line_after_param_comments = false +ij_java_doc_add_blank_line_after_return = false +ij_java_doc_add_p_tag_on_empty_lines = true +ij_java_doc_align_exception_comments = true +ij_java_doc_align_param_comments = true +ij_java_doc_do_not_wrap_if_one_line = false +ij_java_doc_enable_formatting = true +ij_java_doc_enable_leading_asterisks = true +ij_java_doc_indent_on_continuation = false +ij_java_doc_keep_empty_lines = true +ij_java_doc_keep_empty_parameter_tag = true +ij_java_doc_keep_empty_return_tag = true +ij_java_doc_keep_empty_throws_tag = true +ij_java_doc_keep_invalid_tags = true +ij_java_doc_param_description_on_new_line = false +ij_java_doc_preserve_line_breaks = false +ij_java_doc_use_throws_not_exception_tag = true +ij_java_else_on_new_line = false +ij_java_entity_dd_suffix = EJB +ij_java_entity_eb_suffix = Bean +ij_java_entity_hi_suffix = Home +ij_java_entity_lhi_prefix = Local +ij_java_entity_lhi_suffix = Home +ij_java_entity_li_prefix = Local +ij_java_entity_pk_class = java.lang.String +ij_java_entity_vo_suffix = VO +ij_java_enum_constants_wrap = off +ij_java_extends_keyword_wrap = off +ij_java_extends_list_wrap = off +ij_java_field_annotation_wrap = split_into_lines +ij_java_finally_on_new_line = false +ij_java_for_brace_force = never +ij_java_for_statement_new_line_after_left_paren = false +ij_java_for_statement_right_paren_on_new_line = false +ij_java_for_statement_wrap = off +ij_java_generate_final_locals = false +ij_java_generate_final_parameters = false +ij_java_if_brace_force = never +ij_java_imports_layout = *, |, javax.**, java.**, |, $* +ij_java_indent_case_from_switch = true +ij_java_insert_inner_class_imports = false +ij_java_insert_override_annotation = true +ij_java_keep_blank_lines_before_right_brace = 2 +ij_java_keep_blank_lines_between_package_declaration_and_header = 2 +ij_java_keep_blank_lines_in_code = 2 +ij_java_keep_blank_lines_in_declarations = 2 +ij_java_keep_builder_methods_indents = false +ij_java_keep_control_statement_in_one_line = true +ij_java_keep_first_column_comment = true +ij_java_keep_indents_on_empty_lines = false +ij_java_keep_line_breaks = true +ij_java_keep_multiple_expressions_in_one_line = false +ij_java_keep_simple_blocks_in_one_line = false +ij_java_keep_simple_classes_in_one_line = false +ij_java_keep_simple_lambdas_in_one_line = false +ij_java_keep_simple_methods_in_one_line = false +ij_java_label_indent_absolute = false +ij_java_label_indent_size = 0 +ij_java_lambda_brace_style = end_of_line +ij_java_layout_static_imports_separately = true +ij_java_line_comment_add_space = false +ij_java_line_comment_add_space_on_reformat = false +ij_java_line_comment_at_first_column = true +ij_java_message_dd_suffix = EJB +ij_java_message_eb_suffix = Bean +ij_java_method_annotation_wrap = split_into_lines +ij_java_method_brace_style = end_of_line +ij_java_method_call_chain_wrap = off +ij_java_method_parameters_new_line_after_left_paren = false +ij_java_method_parameters_right_paren_on_new_line = false +ij_java_method_parameters_wrap = off +ij_java_modifier_list_wrap = false +ij_java_multi_catch_types_wrap = normal +ij_java_names_count_to_use_import_on_demand = 3 +ij_java_new_line_after_lparen_in_annotation = false +ij_java_new_line_after_lparen_in_record_header = false +ij_java_packages_to_use_import_on_demand = java.awt.*, javax.swing.* +ij_java_parameter_annotation_wrap = off +ij_java_parentheses_expression_new_line_after_left_paren = false +ij_java_parentheses_expression_right_paren_on_new_line = false +ij_java_place_assignment_sign_on_next_line = false +ij_java_prefer_longer_names = true +ij_java_prefer_parameters_wrap = false +ij_java_record_components_wrap = normal +ij_java_repeat_synchronized = true +ij_java_replace_instanceof_and_cast = false +ij_java_replace_null_check = true +ij_java_replace_sum_lambda_with_method_ref = true +ij_java_resource_list_new_line_after_left_paren = false +ij_java_resource_list_right_paren_on_new_line = false +ij_java_resource_list_wrap = off +ij_java_rparen_on_new_line_in_annotation = false +ij_java_rparen_on_new_line_in_record_header = false +ij_java_session_dd_suffix = EJB +ij_java_session_eb_suffix = Bean +ij_java_session_hi_suffix = Home +ij_java_session_lhi_prefix = Local +ij_java_session_lhi_suffix = Home +ij_java_session_li_prefix = Local +ij_java_session_si_suffix = Service +ij_java_space_after_closing_angle_bracket_in_type_argument = false +ij_java_space_after_colon = true +ij_java_space_after_comma = true +ij_java_space_after_comma_in_type_arguments = true +ij_java_space_after_for_semicolon = true +ij_java_space_after_quest = true +ij_java_space_after_type_cast = true +ij_java_space_before_annotation_array_initializer_left_brace = false +ij_java_space_before_annotation_parameter_list = false +ij_java_space_before_array_initializer_left_brace = false +ij_java_space_before_catch_keyword = true +ij_java_space_before_catch_left_brace = true +ij_java_space_before_catch_parentheses = true +ij_java_space_before_class_left_brace = true +ij_java_space_before_colon = true +ij_java_space_before_colon_in_foreach = true +ij_java_space_before_comma = false +ij_java_space_before_do_left_brace = true +ij_java_space_before_else_keyword = true +ij_java_space_before_else_left_brace = true +ij_java_space_before_finally_keyword = true +ij_java_space_before_finally_left_brace = true +ij_java_space_before_for_left_brace = true +ij_java_space_before_for_parentheses = true +ij_java_space_before_for_semicolon = false +ij_java_space_before_if_left_brace = true +ij_java_space_before_if_parentheses = true +ij_java_space_before_method_call_parentheses = false +ij_java_space_before_method_left_brace = true +ij_java_space_before_method_parentheses = false +ij_java_space_before_opening_angle_bracket_in_type_parameter = false +ij_java_space_before_quest = true +ij_java_space_before_switch_left_brace = true +ij_java_space_before_switch_parentheses = true +ij_java_space_before_synchronized_left_brace = true +ij_java_space_before_synchronized_parentheses = true +ij_java_space_before_try_left_brace = true +ij_java_space_before_try_parentheses = true +ij_java_space_before_type_parameter_list = false +ij_java_space_before_while_keyword = true +ij_java_space_before_while_left_brace = true +ij_java_space_before_while_parentheses = true +ij_java_space_inside_one_line_enum_braces = false +ij_java_space_within_empty_array_initializer_braces = false +ij_java_space_within_empty_method_call_parentheses = false +ij_java_space_within_empty_method_parentheses = false +ij_java_spaces_around_additive_operators = true +ij_java_spaces_around_annotation_eq = true +ij_java_spaces_around_assignment_operators = true +ij_java_spaces_around_bitwise_operators = true +ij_java_spaces_around_equality_operators = true +ij_java_spaces_around_lambda_arrow = true +ij_java_spaces_around_logical_operators = true +ij_java_spaces_around_method_ref_dbl_colon = false +ij_java_spaces_around_multiplicative_operators = true +ij_java_spaces_around_relational_operators = true +ij_java_spaces_around_shift_operators = true +ij_java_spaces_around_type_bounds_in_type_parameters = true +ij_java_spaces_around_unary_operator = false +ij_java_spaces_within_angle_brackets = false +ij_java_spaces_within_annotation_parentheses = false +ij_java_spaces_within_array_initializer_braces = false +ij_java_spaces_within_braces = false +ij_java_spaces_within_brackets = false +ij_java_spaces_within_cast_parentheses = false +ij_java_spaces_within_catch_parentheses = false +ij_java_spaces_within_for_parentheses = false +ij_java_spaces_within_if_parentheses = false +ij_java_spaces_within_method_call_parentheses = false +ij_java_spaces_within_method_parentheses = false +ij_java_spaces_within_parentheses = false +ij_java_spaces_within_record_header = false +ij_java_spaces_within_switch_parentheses = false +ij_java_spaces_within_synchronized_parentheses = false +ij_java_spaces_within_try_parentheses = false +ij_java_spaces_within_while_parentheses = false +ij_java_special_else_if_treatment = true +ij_java_subclass_name_suffix = Impl +ij_java_ternary_operation_signs_on_next_line = false +ij_java_ternary_operation_wrap = off +ij_java_test_name_suffix = Test +ij_java_throws_keyword_wrap = off +ij_java_throws_list_wrap = off +ij_java_use_external_annotations = false +ij_java_use_fq_class_names = false +ij_java_use_relative_indents = false +ij_java_use_single_class_imports = true +ij_java_variable_annotation_wrap = off +ij_java_visibility = public +ij_java_while_brace_force = never +ij_java_while_on_new_line = false +ij_java_wrap_comments = false +ij_java_wrap_first_method_in_call_chain = false +ij_java_wrap_long_lines = false -[*.{java, py, sh, gradle}] -charset = utf-8 +[{*.bash,*.sh,*.zsh}] +ij_shell_binary_ops_start_line = false +ij_shell_keep_column_alignment_padding = false +ij_shell_minify_program = false +ij_shell_redirect_followed_by_space = false +ij_shell_switch_cases_indented = false +ij_shell_use_unix_line_separator = true -[*.{java, py}] -indent_style = space -indent_size = 4 +[{*.markdown,*.md}] +trim_trailing_whitespace = false +ij_markdown_force_one_space_after_blockquote_symbol = true +ij_markdown_force_one_space_after_header_symbol = true +ij_markdown_force_one_space_after_list_bullet = true +ij_markdown_force_one_space_between_words = true +ij_markdown_insert_quote_arrows_on_wrap = true +ij_markdown_keep_indents_on_empty_lines = false +ij_markdown_keep_line_breaks_inside_text_blocks = true +ij_markdown_max_lines_around_block_elements = 1 +ij_markdown_max_lines_around_header = 1 +ij_markdown_max_lines_between_paragraphs = 1 +ij_markdown_min_lines_around_block_elements = 1 +ij_markdown_min_lines_around_header = 1 +ij_markdown_min_lines_between_paragraphs = 1 +ij_markdown_wrap_text_if_long = true +ij_markdown_wrap_text_inside_blockquotes = true + +[{*.properties,spring.handlers,spring.schemas}] +ij_properties_align_group_field_declarations = false +ij_properties_keep_blank_lines = false +ij_properties_key_value_delimiter = equals +ij_properties_spaces_around_key_value_delimiter = false + +[{*.toml,Cargo.lock,Cargo.toml.orig,Gopkg.lock,Pipfile,poetry.lock}] +ij_toml_keep_indents_on_empty_lines = false [build.yml] -indent_style = space indent_size = 2 [build.gradle] -indent_style = space indent_size = 2 + +[*.bat] +end_of_line = crlf + diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 81c7b58d8..897074eae 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -12,6 +12,7 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -24,15 +25,17 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] **Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] + +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] **Additional context** Add any other context about the problem here. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 246947759..0fd611247 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,6 @@ name: emuStudio Build -on: [push] +on: [ push ] jobs: build: @@ -8,12 +8,12 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - java-version: 11 - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - name: Build with Gradle - run: ./gradlew build + - uses: actions/checkout@v2 + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew build diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index e60f5cd59..a3c232750 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -23,13 +23,13 @@ include: Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or - advances + advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic - address, without explicit permission + address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a - professional setting + professional setting ## Our Responsibilities diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 69ab590ab..a58938bb7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,4 +2,5 @@ Thank you for your interest in contributing to emuStudio! -All required information regarding contributing can be found in [developer documentation](https://emustudio.github.io/documentation/developer/getting_started/contributing). +All required information regarding contributing can be found +in [developer documentation](https://emustudio.github.io/documentation/developer/getting_started/contributing). diff --git a/README.md b/README.md index 80d82c08f..6c0d5d479 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,17 @@ # ![emuStudio logo](resources/logo-white.png "emuStudio logo") Welcome to emuStudio + ![emuStudio Build](https://github.com/emustudio/emuStudio/workflows/emuStudio%20Build/badge.svg) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [emuStudio](https://www.emustudio.net/) is a desktop application used for computer emulation and writing programs for emulated computers. It extensible; it encourages developers to write their own computer emulators. -The main goal of emuStudio is to support the "compile-load-emulate" workflow, aiming at students or anyone to help to learn about older but important computers or even abstract machines. +The main goal of emuStudio is to support the "compile-load-emulate" workflow, aiming at students or anyone to help to +learn about older but important computers or even abstract machines. -emuStudio is very appropriate for use at schools, e.g. when students are doing first steps in assembler, or when they are taught about computer history. For example, emuStudio is used at the [Technical University of Košice](http://www.fei.tuke.sk/en) +emuStudio is very appropriate for use at schools, e.g. when students are doing first steps in assembler, or when they +are taught about computer history. For example, emuStudio is used at +the [Technical University of Košice](http://www.fei.tuke.sk/en) since 2007. ## Available emulators @@ -18,30 +22,51 @@ since 2007. * [Random Access Machine (RAM)](https://www.emustudio.net/documentation/user/ram/) -* [Random Access Stored Program (RASP)](https://www.emustudio.net/documentation/user/rasp/) +* [Random Access Stored Program (RASP)](https://www.emustudio.net/documentation/user/rasp/) * [BrainDuck (brainfuck interpreter)](https://www.emustudio.net/documentation/user/brainduck/) ## BIG THANKS -Big thanks goes to the one and only [simh](http://simh.trailing-edge.com/) project, which inspired me a lot, and helped -me as a student and emulator enthusiast when working on emuStudio. I wish emuStudio will reach it's simplicity and -emulators "richness" as the simh project has. +emuStudio was written based on existing emulators, sites and existing documentation of real hardware. For example: + +Projects: +- [simh](http://simh.trailing-edge.com/) project, which was the main inspiration for Altair8800 computer +- [MAME](https://www.mamedev.org/) project, which helped with resolving a lot of bugs in a correct implementation of + some 8080 and Z80 CPU instructions +- [RedCode Z80](https://github.com/redcode/Z80) project, for helping with correctly implementing some Z80 instructions +- [superzazu's Z80](https://github.com/superzazu/z80), includes test ROMs + +Sites: +- [David Sharp's SSEM site](https://www.davidsharp.com/baby/), main inspiration for SSEM implementation +- [Esolang's BrainFuck site](https://esolangs.org/wiki/Brainfuck), main inspiration for Brainfuck implementation +- [DeRamp Altair](https://deramp.com/altair.html), more inspiration for Altair8800 +- [Altair Clone](https://altairclone.com/), more inspiration for Altair8800 +- [Study of techniques for emulation programming](http://www.xsim.com/papers/Bario.2001.emubook.pdf), emulation techniques classic +- [8080 instruction table](https://tobiasvl.github.io/optable/intel-8080/classic) +- [CLR home Z80 instructions table](https://clrhome.org/table/) +- [Z80 Undocumented documented](http://www.z80.info/zip/z80-documented.pdf), undocumented behavior of Z80 CPU +- [Z80 undocumented](https://baltazarstudios.com/zilog-z80-undocumented-behavior/), another undocumented behavior of Z80 CPU + +Discord: +- [Discord Emulation Development](https://discord.com/channels/465585922579103744/channel-browser) ## Getting started At first, either compile or [download](https://www.emustudio.net/download/) emuStudio. The prerequisite is to have installed **Java, at least version 11** -(download [here](https://www.oracle.com/java/technologies/javase-downloads.html)). +(download [here](https://www.oracle.com/java/technologies/javase-downloads.html)). Then, unzip the tar/zip file (`emuStudio-xxx.zip`) and run it using command: - On Linux / Mac + ``` > ./emuStudio ``` - On Windows: + ``` > emuStudio.bat ``` @@ -64,8 +89,10 @@ which includes information like: ### Related projects There exist some additional projects, which are used by emuStudio, useful for contributors: - -- [emuLib](https://github.com/emustudio/emuLib), a run-time library -- [edigen](https://github.com/emustudio/edigen), an emulator disassembler generator -- [cpu-testsuite](https://github.com/emustudio/cpu-testsuite), a JUnit-based test suite for comfortable testing of CPU + +- [emuLib](https://github.com/emustudio/emuLib) - a shared runtime library +- [Edigen](https://github.com/emustudio/edigen) - instruction decoder and disassembler generator +- [Edigen Gradle plugin](https://github.com/emustudio/edigen-gradle-plugin) - Edigen Gradle plugin +- [CPU testing suite](https://github.com/emustudio/cpu-testsuite) - a JUnit-based test suite for comfortable testing of CPU plugins +- [emuStudio website](https://github.com/emustudio/emustudio.github.io) - emuStudio website diff --git a/RELEASES.md b/RELEASES.md index c78bfcf3c..37abc387c 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -3,16 +3,19 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuStudio/milestone/3?closed=1). ## Whole project: + - updated to Java 11 - changed build system - moved from Maven to Gradle - reorganized directory structure, introduced startup scripts - reimplemented generating of names of configuration files (to not clash with filesystem rules) - changed configuration file format to [TOML](https://github.com/toml-lang/toml) -- many GUI fixes (e.g. `ESC` closes all dialogs, source code tab displays file name, dialog modality issues, added icon to windows) +- many GUI fixes (e.g. `ESC` closes all dialogs, source code tab displays file name, dialog modality issues, added icon + to windows) - all dialogs accepting memory addresses can use various number radixes - rewritten project website ## main-module: + - removed configuration editor popup in the schema editor - reimplemented source code editor using [RSyntaxTextArea](https://github.com/bobbylight/RSyntaxTextArea) - reimplemented emulation automation (`--input` is not required anymore, introduced more command line options) @@ -41,33 +44,41 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS - fix: after saving newly created computer in schema editor, it is not shown in the list ## RASP: + - rewritten raspc-rasp grammar and compiler - raspc-rasp: implemented `` directive ## SSEM: + - fix: SSEM noodle-timer doesn't work ## adm3A-terminal: + - fix: load cursor from software - fix: keyboard does not read input - fix: "here is" does not work (in GUI) - throws some hidden exception - fix: "always on top" doesn't work ## 88-disk: + - implement reading files from CP/M filesystems - fix: settings show weird unparseable ports in text fields (e.g. `Optional[8]`, etc.) ## 88-sio: -- fix: On computer reset, 88-SIO buffer is not cleared; on automatic emulation (non-interactive), reset should not clear the buffer + +- fix: On computer reset, 88-SIO buffer is not cleared; on automatic emulation (non-interactive), reset should not clear + the buffer - fix: Removed port is not saved ## abstract-tape: + - renamed from abstractTape-ram - fix: vertical resize of abstract tape won't extend the symbols list - fix: In schema editor, abstractTape-ram is shown as "abstractTape" only - fix: Input tape (copy.ram) does not show all inputs properly (row 04 is missing) ## standard-mem: + - fix: selected value is white and has white background (invisible) - fix: Could not open memory image from "all files (.)" filter - fix: with banking: no memory content is shown in the table (e.g. loaded image) @@ -75,6 +86,7 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS - fix: Find sequence dialog does not search by pressing ENTER ## 8080-cpu: + - fix: CPU is in Stopped state initially. After clicking on "run" it won't and hang whole emuStudio # Version 0.39 @@ -82,11 +94,13 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS All issues for the milestone are listed [here](https://github.com/emustudio/emuStudio/milestone/2?closed=1). ## New computers: + - RASP (raspc-rasp, rasp-cpu, rasp-mem) - thanks to Michal Šipoš - SSEM (as-ssem, ssem-cpu, ssem-mem, ssem-display) -- re-implemented BrainDuck +- re-implemented BrainDuck ## Whole project: + - introduced logging using logback+slf4j - introduced Maven 3 for dependency and project management - new user documentation was created @@ -97,6 +111,7 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS - introduction of Travis CI ## main-module: + - rewritten debugger and disassembler - introduced pagination in debugger - introduced saving computer schema to image @@ -104,7 +119,7 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS - fixed GUI problems - "previous instruction" just decrements program counter - fixed syntax highlighting -- fixed: on breakpoint, instruction list was not pointing at current (next) instruction +- fixed: on breakpoint, instruction list was not pointing at current (next) instruction - fixed: on 'pages backwards' button when the input window is cancelled, NullPointerException appeared in log - fixed: when file was not saved before compilation, on most compilers NullPointerException appeared in log - fixed: in source code editor, when open file is cancelled, compiler output window was cleared @@ -114,6 +129,7 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS - fixed: deadlock in source code editor ## as-8080: + - fixed `db 'if'` - added command line - fixed compiling `ani` instruction @@ -121,12 +137,14 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS - fixed: relative path to include files did not work ## as-z80: + - fixed `db 'if'` does not work - added command line - better error recovery implementation - fixed: relative path to include files did not work ## 8080-cpu: + - introduced real-time program dumping - refactorted + thoroughly tested - fixed: PC change did not update the status panel GUI @@ -134,6 +152,7 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS - fixed: `inc` and `dcr` instructions ## z80-cpu: + - introduced real-time program dumping - refactorted + thoroughly tested - fixed: PC change did not update the status panel GUI @@ -141,84 +160,93 @@ All issues for the milestone are listed [here](https://github.com/emustudio/emuS - refactored GUI ## 88-disk: + - introduced Java NIO to improve performance -## 88-sio: +## 88-sio: + - fixed: status port manipulation - add ability to bind to multiple CPU ports - fixed: NPE in MITS 88-SIO ## standard-mem: + - add possibility to load image at runtime with a button - add possibility to find a sequence ## adm3A-terminal: + - fixed cursor blinking -- fixed: terminal did not accept CTRL+C +- fixed: terminal did not accept CTRL+C - fixed: terminal could load custom font ## ramc-ram + - added command line - better error recovery implementation ## ram-cpu: + - IP change does not update the status panel GUI - Introduce 'label' column in debug table ## ram-mem + - problem with loading programs ## abstractTape-ram + - canceling the edit of the symbol in the abstract tape does not work - display a number of registers it's pointing at ## brainc-brainduck + - added command line - reimplemented to real brainfuck language ## brainduck-cpu: + - fixed: when BrainDuck CPU was reset, it did not clear memory - introduced profiler for improving performance - + ## brainduck-terminal: -- reimplemented +- reimplemented # Version 0.38b All issues for the milestone are listed [here](https://github.com/emustudio/emuStudio/milestone/1?closed=1). +- Add possibility to modify settings of plug-ins in abstract schema + editor by double-clicking on an element or with using pop-up menu + with right-click on an element. -- Add possibility to modify settings of plug-ins in abstract schema - editor by double-clicking on an element or with using pop-up menu - with right-click on an element. - -- Fixed several bugs in abstract schema drawing +- Fixed several bugs in abstract schema drawing -- Added pop-up menu when user right clicks on an element in abstract schema -- Add ability to resize elements in abstract schema -- Add useGrid, gridGap and width/height of all elements into schema and configuration file +- Added pop-up menu when user right clicks on an element in abstract schema +- Add ability to resize elements in abstract schema +- Add useGrid, gridGap and width/height of all elements into schema and configuration file -- Fixed debug table column title: mnemo to opcode -- Created listener for possibility to call updates on debug table by any plugins. +- Fixed debug table column title: mnemo to opcode +- Created listener for possibility to call updates on debug table by any plugins. -- Fixed bug: when deleted last computer in computers dialog, exception was thrown -- Changed Vector to ArrayList in HighlightThread +- Fixed bug: when deleted last computer in computers dialog, exception was thrown +- Changed Vector to ArrayList in HighlightThread -- Fixed bug in text editor: file saving +- Fixed bug in text editor: file saving -- Fixed bug in 'view of computer' - devices were shown weirdly +- Fixed bug in 'view of computer' - devices were shown weirdly -- Fixed synchronization problems in automatized emulation execution -- Added new parameter "--nogui" that won't show GUI in the automatization +- Fixed synchronization problems in automatized emulation execution +- Added new parameter "--nogui" that won't show GUI in the automatization -- Fixed automatization, now "auto" setting is set to "true" if the emulation is automatized. - Plugins may read this setting to determine this. +- Fixed automatization, now "auto" setting is set to "true" if the emulation is automatized. + Plugins may read this setting to determine this. -- Fixed possible NullPointerExceptions throws when disassembler is not implemented inside a CPU +- Fixed possible NullPointerExceptions throws when disassembler is not implemented inside a CPU -- Re-implement pagination in the debug table +- Re-implement pagination in the debug table -- Next try to overcome thread deadlock bug connected with syntax highlighting :( +- Next try to overcome thread deadlock bug connected with syntax highlighting :( -- Make all rows in debug table visible +- Make all rows in debug table visible diff --git a/application/README.md b/application/README.md index 1ab7ffc78..13c99e36b 100644 --- a/application/README.md +++ b/application/README.md @@ -16,7 +16,7 @@ The application is implemented using Java and Swing for GUI. # Installation -The simplest way how to install main module is to use whole distribution. For that case, please follow +The simplest way how to install main module is to use whole distribution. For that case, please follow the instructions at [project's web page](http://net.emustudio.sourceforge.net/downloads.html). The hacker ways follows. At first, compile the project: diff --git a/application/build.gradle b/application/build.gradle index a537248bd..36163660e 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -89,8 +89,8 @@ application { applicationName = 'emuStudio' mainClassName = 'net.emustudio.application.cmdline.Runner' applicationDefaultJvmArgs = [ - '-Dawt.useSystemAAFontSettings=on', '-Dswing.aatext=true', '-Dsun.java2d.xrender=true', '-Dsun.java2d.d3d=false', - '-Dsun.java2d.noddraw=true' + '-Dawt.useSystemAAFontSettings=on', '-Dswing.aatext=true', '-Dsun.java2d.xrender=true', '-Dsun.java2d.d3d=false', + '-Dsun.java2d.noddraw=true' ] executableDir = '' } @@ -113,12 +113,12 @@ jar { archiveVersion = '' manifest { attributes( - 'Main-Class': 'net.emustudio.application.cmdline.Runner', - "Implementation-Title": archivesBaseName, - "Implementation-Version": project.version, - 'Build-Timestamp': new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()), - 'Build-Jdk': "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})", - 'Build-OS': "${System.properties['os.name']} ${System.properties['os.arch']} ${System.properties['os.version']}" + 'Main-Class': 'net.emustudio.application.cmdline.Runner', + "Implementation-Title": archivesBaseName, + "Implementation-Version": project.version, + 'Build-Timestamp': new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()), + 'Build-Jdk': "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})", + 'Build-OS': "${System.properties['os.name']} ${System.properties['os.arch']} ${System.properties['os.version']}" ) } } @@ -126,8 +126,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/application/src/main/files/README.md b/application/src/main/files/README.md index cc026bd61..225546df7 100644 --- a/application/src/main/files/README.md +++ b/application/src/main/files/README.md @@ -3,13 +3,14 @@ [emuStudio](https://www.emustudio.net/) is a desktop application used for computers emulation and writing programs for emulated computers. It extensible; it encourages developers to write their own computer emulators. -Main goal of emuStudio is support learning about older but important computers, or abstract machines, while -having fun. Nowadays the ability to write programs for old computers is probably not quite interesting for the market, -but I guess emulation has always be more about fun, trying to keeping alive something which was outstanding -in it's peak, and preserve memories. +The main goal of emuStudio is to support learning about older but important computers, or abstract machines, while +having fun. Nowadays, the ability to write programs for old computers is probably not quite interesting for the market, +but I guess emulation has always been more about fun, trying to keep alive something which was outstanding +in its peak, and preserve memories. emuStudio is very appropriate for using at schools, e.g. when students are doing first steps in assembler, or when they -are taught about computers history. For example, emuStudio is used at [Technical University of Košice](http://www.fei.tuke.sk/en) +are taught about computers history. For example, emuStudio is used +at [Technical University of Košice](http://www.fei.tuke.sk/en) since 2007. ## Available emulators @@ -20,11 +21,10 @@ since 2007. * [Random Access Machine (RAM)](https://www.emustudio.net/docuser/ram/index/) -* [Random Access Stored Program (RASP)](https://www.emustudio.net/docuser/rasp/index/) +* [Random Access Stored Program (RASP)](https://www.emustudio.net/docuser/rasp/index/) * [BrainDuck (brainfuck interpreter)](https://www.emustudio.net/docuser/brainduck/index/) - # License This project is released under GNU GPL v3 license. diff --git a/application/src/main/files/config/BrainDuck.toml b/application/src/main/files/config/BrainDuck.toml index a06568e70..42744dcd3 100644 --- a/application/src/main/files/config/BrainDuck.toml +++ b/application/src/main/files/config/BrainDuck.toml @@ -1,52 +1,52 @@ name = "BrainDuck" [MEMORY] - schemaPoint = "100,180" - path = "byte-mem.jar" - settings = {} - name = "byte-mem" - id = "300555eb-2e6b-422f-a954-cfe1905f911a" - type = "MEMORY" +schemaPoint = "100,180" +path = "byte-mem.jar" +settings = { } +name = "byte-mem" +id = "300555eb-2e6b-422f-a954-cfe1905f911a" +type = "MEMORY" [COMPILER] - schemaPoint = "100,60" - path = "brainc-brainduck.jar" - settings = {} - name = "brainc-brainduck" - id = "de251cec-e053-4e2c-a647-9b71eb0f1b70" - type = "COMPILER" +schemaPoint = "100,60" +path = "brainc-brainduck.jar" +settings = { } +name = "brainc-brainduck" +id = "de251cec-e053-4e2c-a647-9b71eb0f1b70" +type = "COMPILER" [CPU] - schemaPoint = "320,180" - path = "brainduck-cpu.jar" - settings = {} - name = "brainduck-cpu" - id = "6c5df0df-4497-4a9d-b9dd-9a3f901864c1" - type = "CPU" +schemaPoint = "320,180" +path = "brainduck-cpu.jar" +settings = { } +name = "brainduck-cpu" +id = "6c5df0df-4497-4a9d-b9dd-9a3f901864c1" +type = "CPU" [[DEVICE]] - schemaPoint = "320,60" - path = "brainduck-terminal.jar" - settings = {} - name = "brainduck-terminal" - id = "1d858668-d63d-4127-b881-226174a2b368" - type = "DEVICE" +schemaPoint = "320,60" +path = "brainduck-terminal.jar" +settings = { } +name = "brainduck-terminal" +id = "1d858668-d63d-4127-b881-226174a2b368" +type = "DEVICE" [[connections]] - bidirectional = true - from = "1d858668-d63d-4127-b881-226174a2b368" - to = "6c5df0df-4497-4a9d-b9dd-9a3f901864c1" - points = [] +bidirectional = true +from = "1d858668-d63d-4127-b881-226174a2b368" +to = "6c5df0df-4497-4a9d-b9dd-9a3f901864c1" +points = [] [[connections]] - bidirectional = true - from = "de251cec-e053-4e2c-a647-9b71eb0f1b70" - to = "300555eb-2e6b-422f-a954-cfe1905f911a" - points = [] +bidirectional = true +from = "de251cec-e053-4e2c-a647-9b71eb0f1b70" +to = "300555eb-2e6b-422f-a954-cfe1905f911a" +points = [] [[connections]] - bidirectional = true - from = "300555eb-2e6b-422f-a954-cfe1905f911a" - to = "6c5df0df-4497-4a9d-b9dd-9a3f901864c1" - points = [] +bidirectional = true +from = "300555eb-2e6b-422f-a954-cfe1905f911a" +to = "6c5df0df-4497-4a9d-b9dd-9a3f901864c1" +points = [] diff --git a/application/src/main/files/config/MITSAltair8800.toml b/application/src/main/files/config/MITSAltair8800.toml index baa404aea..f9a12cbf3 100644 --- a/application/src/main/files/config/MITSAltair8800.toml +++ b/application/src/main/files/config/MITSAltair8800.toml @@ -1,161 +1,160 @@ name = "MITS Altair8800" [MEMORY] - schemaPoint = "80,180" - path = "byte-mem.jar" - name = "byte-mem" - id = "fee24374-8d28-4472-85ef-e8ef182f44e3" - type = "MEMORY" - - [MEMORY.settings] - banksCount = 1 - commonBoundary = 0 -# memorySize = 65536 - - # ROM areas are stored as pairs ROMfromN and ROMtoN, where N is 0-based counter. There can be multiple rom areas. -# ROMfromN = someAddress -# ROMtoN = someAddress - - # Memory "images" (files) will be loaded at startup into memory. They are stored here as triplet: - # - imageNameN (file name), - # - imageAddressN (address where the file will be loaded), - # - imageBankN (if memory has >1 banksCount, then number of bank; 0 otherwise) - # - # where N is a 0-based counter -# imageNameN = imageFileName # if the suffix ends with ".hex", the format will be Intel HEX; otherwise it will be binary -# imageAddressN = ... -# imageBankN = 0 +schemaPoint = "80,180" +path = "byte-mem.jar" +name = "byte-mem" +id = "fee24374-8d28-4472-85ef-e8ef182f44e3" +type = "MEMORY" + +[MEMORY.settings] +banksCount = 1 +commonBoundary = 0 +#memorySize = 65536 + +# ROM areas are stored as pairs ROMfromN and ROMtoN, where N is 0-based counter. There can be multiple rom areas. +#ROMfromN = someAddress +#ROMtoN = someAddress + +# Memory "images" (files) will be loaded at startup into memory. They are stored here as triplet: +# - imageNameN (file name), +# - imageAddressN (address where the file will be loaded), +# - imageBankN (if memory has >1 banksCount, then number of bank; 0 otherwise) +# +# where N is a 0-based counter +#imageNameN = imageFileName # if the suffix ends with ".hex", the format will be Intel HEX; otherwise it will be binary +#imageAddressN = ... +#imageBankN = 0 [COMPILER] - schemaPoint = "80,60" - path = "as-8080.jar" - settings = {} - name = "as-8080" - id = "14a9121e-348e-48d9-90ae-05a61b6ed8a8" - type = "COMPILER" +schemaPoint = "80,60" +path = "as-8080.jar" +settings = { } +name = "as-8080" +id = "14a9121e-348e-48d9-90ae-05a61b6ed8a8" +type = "COMPILER" [CPU] - schemaPoint = "220,180" - path = "8080-cpu.jar" - settings = {} - name = "8080-cpu" - id = "0c7bc110-554b-433d-b6e2-29885379fac6" - type = "CPU" +schemaPoint = "220,180" +path = "8080-cpu.jar" +settings = { } +name = "8080-cpu" +id = "0c7bc110-554b-433d-b6e2-29885379fac6" +type = "CPU" # Uncomment the following for specific settings (and remove settings = {} above) -# [CPU.settings] -# printCode = true -# printCodeUseCache = true -# printCodeFileName = "filename" # (optional) +#[CPU.settings] +#printCode = true +#printCodeUseCache = true +#printCodeFileName = "filename" # (optional) [[DEVICE]] - schemaPoint = "220,60" - path = "88-dcdd.jar" - name = "88-dcdd" - id = "ad934179-3690-4bbc-b6ab-f4634346927a" - type = "DEVICE" - - [DEVICE.settings] - # imageN = "..." # Load file into drive N at startup - - sectorSize8 = 137 - sectorSize9 = 137 - sectorSize6 = 137 - sectorSize7 = 137 - sectorSize4 = 137 - sectorSize5 = 137 - sectorSize2 = 137 - sectorSize3 = 137 - sectorSize0 = 137 - sectorSize1 = 137 - port2CPU = 9 - sectorsPerTrack15 = 32 - sectorsPerTrack14 = 32 - sectorsPerTrack13 = 32 - sectorsPerTrack12 = 32 - sectorsPerTrack1 = 32 - sectorsPerTrack11 = 32 - sectorsPerTrack2 = 32 - sectorsPerTrack10 = 32 - sectorsPerTrack0 = 32 - sectorsPerTrack5 = 32 - sectorsPerTrack6 = 32 - sectorsPerTrack3 = 32 - sectorsPerTrack4 = 32 - sectorsPerTrack9 = 32 - sectorsPerTrack7 = 32 - sectorsPerTrack8 = 32 - port1CPU = 8 - port3CPU = 10 - sectorSize15 = 137 - sectorSize13 = 137 - sectorSize14 = 137 - sectorSize11 = 137 - sectorSize12 = 137 - sectorSize10 = 137 +schemaPoint = "220,60" +path = "88-dcdd.jar" +name = "88-dcdd" +id = "ad934179-3690-4bbc-b6ab-f4634346927a" +type = "DEVICE" + +[DEVICE.settings] +#imageN = "..." # Load file into drive N at startup +sectorSize8 = 137 +sectorSize9 = 137 +sectorSize6 = 137 +sectorSize7 = 137 +sectorSize4 = 137 +sectorSize5 = 137 +sectorSize2 = 137 +sectorSize3 = 137 +sectorSize0 = 137 +sectorSize1 = 137 +port2CPU = 9 +sectorsPerTrack15 = 32 +sectorsPerTrack14 = 32 +sectorsPerTrack13 = 32 +sectorsPerTrack12 = 32 +sectorsPerTrack1 = 32 +sectorsPerTrack11 = 32 +sectorsPerTrack2 = 32 +sectorsPerTrack10 = 32 +sectorsPerTrack0 = 32 +sectorsPerTrack5 = 32 +sectorsPerTrack6 = 32 +sectorsPerTrack3 = 32 +sectorsPerTrack4 = 32 +sectorsPerTrack9 = 32 +sectorsPerTrack7 = 32 +sectorsPerTrack8 = 32 +port1CPU = 8 +port3CPU = 10 +sectorSize15 = 137 +sectorSize13 = 137 +sectorSize14 = 137 +sectorSize11 = 137 +sectorSize12 = 137 +sectorSize10 = 137 [[DEVICE]] - schemaPoint = "340,180" - path = "88-sio.jar" - name = "88-sio" - id = "515f3dfd-5005-4b62-b002-a20f23324573" - type = "DEVICE" - - [DEVICE.settings] - statusPorts = "0x10, 0x14, 0x16, 0x18" - dataPorts = "0x11, 0x15, 0x17, 0x19" - clearInputBit8 = false - clearOutputBit8 = false - inputToUpperCase = false - mapDeleteChar = "UNCHANGED" - mapBackspaceChar = "UNCHANGED" - inputInterruptVector = 7 - outputInterruptVector = 7 +schemaPoint = "340,180" +path = "88-sio.jar" +name = "88-sio" +id = "515f3dfd-5005-4b62-b002-a20f23324573" +type = "DEVICE" + +[DEVICE.settings] +statusPorts = "0x10, 0x14, 0x16, 0x18" +dataPorts = "0x11, 0x15, 0x17, 0x19" +clearInputBit8 = false +clearOutputBit8 = false +inputToUpperCase = false +mapDeleteChar = "UNCHANGED" +mapBackspaceChar = "UNCHANGED" +inputInterruptVector = 7 +outputInterruptVector = 7 [[DEVICE]] - schemaPoint = "340,60" - path = "adm3A-terminal.jar" - name = "adm3A-terminal" - id = "654a684c-b65e-4c6d-b1f1-1371a3027a90" - type = "DEVICE" - - [DEVICE.settings] - antiAliasing = true - outputFileName = "adm3A-terminal.out" - inputFileName = "adm3A-terminal.in" - alwaysOnTop = true - inputReadDelay = 0 - halfDuplex = false - font = "original" +schemaPoint = "340,60" +path = "adm3A-terminal.jar" +name = "adm3A-terminal" +id = "654a684c-b65e-4c6d-b1f1-1371a3027a90" +type = "DEVICE" + +[DEVICE.settings] +antiAliasing = true +outputFileName = "adm3A-terminal.out" +inputFileName = "adm3A-terminal.in" +alwaysOnTop = true +inputReadDelay = 0 +halfDuplex = false +font = "original" [[connections]] - bidirectional = true - from = "14a9121e-348e-48d9-90ae-05a61b6ed8a8" - to = "fee24374-8d28-4472-85ef-e8ef182f44e3" - points = [] +bidirectional = true +from = "14a9121e-348e-48d9-90ae-05a61b6ed8a8" +to = "fee24374-8d28-4472-85ef-e8ef182f44e3" +points = [] [[connections]] - bidirectional = true - from = "fee24374-8d28-4472-85ef-e8ef182f44e3" - to = "0c7bc110-554b-433d-b6e2-29885379fac6" - points = [] +bidirectional = true +from = "fee24374-8d28-4472-85ef-e8ef182f44e3" +to = "0c7bc110-554b-433d-b6e2-29885379fac6" +points = [] [[connections]] - bidirectional = true - from = "ad934179-3690-4bbc-b6ab-f4634346927a" - to = "0c7bc110-554b-433d-b6e2-29885379fac6" - points = [] +bidirectional = true +from = "ad934179-3690-4bbc-b6ab-f4634346927a" +to = "0c7bc110-554b-433d-b6e2-29885379fac6" +points = [] [[connections]] - bidirectional = true - from = "515f3dfd-5005-4b62-b002-a20f23324573" - to = "0c7bc110-554b-433d-b6e2-29885379fac6" - points = [] +bidirectional = true +from = "515f3dfd-5005-4b62-b002-a20f23324573" +to = "0c7bc110-554b-433d-b6e2-29885379fac6" +points = [] [[connections]] - bidirectional = true - from = "654a684c-b65e-4c6d-b1f1-1371a3027a90" - to = "515f3dfd-5005-4b62-b002-a20f23324573" - points = [] +bidirectional = true +from = "654a684c-b65e-4c6d-b1f1-1371a3027a90" +to = "515f3dfd-5005-4b62-b002-a20f23324573" +points = [] diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index 0169646b4..86c98bd4a 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -1,178 +1,180 @@ name = "MITS Altair8800 (Z80)" [MEMORY] - schemaPoint = "80,220" - path = "byte-mem.jar" - name = "byte-mem" - id = "1e13a25d-fb23-4061-853a-5fe996b03281" - type = "MEMORY" +schemaPoint = "80,220" +path = "byte-mem.jar" +name = "byte-mem" +id = "1e13a25d-fb23-4061-853a-5fe996b03281" +type = "MEMORY" - [MEMORY.settings] - banksCount = 8 - commonBoundary = 49152 +[MEMORY.settings] +banksCount = 8 +commonBoundary = 49152 +#memorySize = 65536 -# memorySize = 65536 # ROM areas are stored as pairs ROMfromN and ROMtoN, where N is 0-based counter. There can be multiple rom areas. -# ROMfromN = someAddress -# ROMtoN = someAddress +#ROMfromN = someAddress +#ROMtoN = someAddress + # Memory "images" (files) will be loaded at startup into memory. They are stored here as triplet: # - imageNameN (file name), # - imageAddressN (address where the file will be loaded), # - imageBankN (if memory has >1 banksCount, then number of bank; 0 otherwise) # # where N is a 0-based counter -# imageNameN = imageFileName # if the suffix ends with ".hex", the format will be Intel HEX; otherwise it will be binary -# imageAddressN = ... -# imageBankN = 0 +#imageNameN = imageFileName # if the suffix ends with ".hex", the format will be Intel HEX; otherwise it will be binary +#imageAddressN = ... +#imageBankN = 0 + [COMPILER] - schemaPoint = "80,60" - path = "as-z80.jar" - settings = {} - name = "as-z80" - id = "9233e0c2-b53c-41e7-9eca-bbb264fcd9da" - type = "COMPILER" +schemaPoint = "80,60" +path = "as-z80.jar" +settings = { } +name = "as-z80" +id = "9233e0c2-b53c-41e7-9eca-bbb264fcd9da" +type = "COMPILER" [CPU] - schemaPoint = "220,220" - path = "z80-cpu.jar" - settings = {} - name = "z80-cpu" - id = "b86d4bc2-632c-46e3-bba1-c088c9177983" - type = "CPU" +schemaPoint = "220,220" +path = "z80-cpu.jar" +settings = { } +name = "z80-cpu" +id = "b86d4bc2-632c-46e3-bba1-c088c9177983" +type = "CPU" # Uncomment the following for specific settings (and remove settings = {} above) -# [CPU.settings] -# printCode = true -# printCodeUseCache = true -# printCodeFileName = "filename" # (optional) +#[CPU.settings] +#printCode = true +#printCodeUseCache = true +#printCodeFileName = "filename" # (optional) [[DEVICE]] - schemaPoint = "340,140" - path = "88-dcdd.jar" - name = "88-dcdd" - id = "c94d0e9b-f394-4a71-94b0-87d0f970a3fd" - type = "DEVICE" - - [DEVICE.settings] - # imageN = "..." # Load file into drive N at startup - sectorSize8 = 137 - sectorSize9 = 137 - sectorSize6 = 137 - sectorSize7 = 137 - sectorSize4 = 137 - sectorSize5 = 137 - sectorSize2 = 137 - sectorSize3 = 137 - sectorSize0 = 137 - sectorSize1 = 137 - port2CPU = 9 - sectorsPerTrack15 = 32 - sectorsPerTrack14 = 32 - sectorsPerTrack13 = 32 - sectorsPerTrack12 = 32 - sectorsPerTrack1 = 32 - sectorsPerTrack11 = 32 - sectorsPerTrack2 = 32 - sectorsPerTrack10 = 32 - sectorsPerTrack0 = 32 - sectorsPerTrack5 = 32 - sectorsPerTrack6 = 32 - sectorsPerTrack3 = 32 - sectorsPerTrack4 = 32 - sectorsPerTrack9 = 32 - sectorsPerTrack7 = 32 - sectorsPerTrack8 = 32 - port1CPU = 8 - port3CPU = 10 - sectorSize15 = 137 - sectorSize13 = 137 - sectorSize14 = 137 - sectorSize11 = 137 - sectorSize12 = 137 - sectorSize10 = 137 +schemaPoint = "340,140" +path = "88-dcdd.jar" +name = "88-dcdd" +id = "c94d0e9b-f394-4a71-94b0-87d0f970a3fd" +type = "DEVICE" + +[DEVICE.settings] +# imageN = "..." # Load file into drive N at startup +sectorSize8 = 137 +sectorSize9 = 137 +sectorSize6 = 137 +sectorSize7 = 137 +sectorSize4 = 137 +sectorSize5 = 137 +sectorSize2 = 137 +sectorSize3 = 137 +sectorSize0 = 137 +sectorSize1 = 137 +port2CPU = 9 +sectorsPerTrack15 = 32 +sectorsPerTrack14 = 32 +sectorsPerTrack13 = 32 +sectorsPerTrack12 = 32 +sectorsPerTrack1 = 32 +sectorsPerTrack11 = 32 +sectorsPerTrack2 = 32 +sectorsPerTrack10 = 32 +sectorsPerTrack0 = 32 +sectorsPerTrack5 = 32 +sectorsPerTrack6 = 32 +sectorsPerTrack3 = 32 +sectorsPerTrack4 = 32 +sectorsPerTrack9 = 32 +sectorsPerTrack7 = 32 +sectorsPerTrack8 = 32 +port1CPU = 8 +port3CPU = 10 +sectorSize15 = 137 +sectorSize13 = 137 +sectorSize14 = 137 +sectorSize11 = 137 +sectorSize12 = 137 +sectorSize10 = 137 [[DEVICE]] - schemaPoint = "340,220" - path = "88-sio.jar" - name = "88-sio" - id = "de2ce2e7-4365-406e-864a-b60f353d3fba" - type = "DEVICE" - - [DEVICE.settings] - statusPorts = "0x10, 0x14, 0x16, 0x18" - dataPorts = "0x11, 0x15, 0x17, 0x19" - clearInputBit8 = false - clearOutputBit8 = false - inputToUpperCase = false - mapDeleteChar = "UNCHANGED" - mapBackspaceChar = "UNCHANGED" - inputInterruptVector = 7 - outputInterruptVector = 7 +schemaPoint = "340,220" +path = "88-sio.jar" +name = "88-sio" +id = "de2ce2e7-4365-406e-864a-b60f353d3fba" +type = "DEVICE" + +[DEVICE.settings] +statusPorts = "0x10, 0x14, 0x16, 0x18" +dataPorts = "0x11, 0x15, 0x17, 0x19" +clearInputBit8 = false +clearOutputBit8 = false +inputToUpperCase = false +mapDeleteChar = "UNCHANGED" +mapBackspaceChar = "UNCHANGED" +inputInterruptVector = 7 +outputInterruptVector = 7 [[DEVICE]] - schemaPoint = "480,220" - path = "adm3A-terminal.jar" - name = "adm3A-terminal" - id = "0352cf74-2965-4723-bef9-3e918b1ac7c5" - type = "DEVICE" - - [DEVICE.settings] - antiAliasing = true - alwaysOnTop = true - inputReadDelay = 0 - halfDuplex = false - outputFileName = "adm3A-terminal.out" - inputFileName = "adm3A-terminal.in" - font = "original" +schemaPoint = "480,220" +path = "adm3A-terminal.jar" +name = "adm3A-terminal" +id = "0352cf74-2965-4723-bef9-3e918b1ac7c5" +type = "DEVICE" + +[DEVICE.settings] +antiAliasing = true +alwaysOnTop = true +inputReadDelay = 0 +halfDuplex = false +outputFileName = "adm3A-terminal.out" +inputFileName = "adm3A-terminal.in" +font = "original" [[DEVICE]] - schemaPoint = "220,60" - path = "simh-pseudo.jar" - settings = {} - name = "simh-pseudo" - id = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" - type = "DEVICE" +schemaPoint = "220,60" +path = "simh-pseudo.jar" +settings = { } +name = "simh-pseudo" +id = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" +type = "DEVICE" [[connections]] - bidirectional = true - from = "9233e0c2-b53c-41e7-9eca-bbb264fcd9da" - to = "1e13a25d-fb23-4061-853a-5fe996b03281" - points = [] +bidirectional = true +from = "9233e0c2-b53c-41e7-9eca-bbb264fcd9da" +to = "1e13a25d-fb23-4061-853a-5fe996b03281" +points = [] [[connections]] - bidirectional = true - from = "c94d0e9b-f394-4a71-94b0-87d0f970a3fd" - to = "b86d4bc2-632c-46e3-bba1-c088c9177983" - points = ["240,140"] +bidirectional = true +from = "c94d0e9b-f394-4a71-94b0-87d0f970a3fd" +to = "b86d4bc2-632c-46e3-bba1-c088c9177983" +points = ["240,140"] [[connections]] - bidirectional = true - from = "1e13a25d-fb23-4061-853a-5fe996b03281" - to = "b86d4bc2-632c-46e3-bba1-c088c9177983" - points = [] +bidirectional = true +from = "1e13a25d-fb23-4061-853a-5fe996b03281" +to = "b86d4bc2-632c-46e3-bba1-c088c9177983" +points = [] [[connections]] - bidirectional = true - from = "de2ce2e7-4365-406e-864a-b60f353d3fba" - to = "b86d4bc2-632c-46e3-bba1-c088c9177983" - points = [] +bidirectional = true +from = "de2ce2e7-4365-406e-864a-b60f353d3fba" +to = "b86d4bc2-632c-46e3-bba1-c088c9177983" +points = [] [[connections]] - bidirectional = true - from = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" - to = "b86d4bc2-632c-46e3-bba1-c088c9177983" - points = [] +bidirectional = true +from = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" +to = "b86d4bc2-632c-46e3-bba1-c088c9177983" +points = [] [[connections]] - bidirectional = true - from = "0352cf74-2965-4723-bef9-3e918b1ac7c5" - to = "de2ce2e7-4365-406e-864a-b60f353d3fba" - points = [] +bidirectional = true +from = "0352cf74-2965-4723-bef9-3e918b1ac7c5" +to = "de2ce2e7-4365-406e-864a-b60f353d3fba" +points = [] [[connections]] - bidirectional = true - from = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" - to = "1e13a25d-fb23-4061-853a-5fe996b03281" - points = ["200,140", "120,140"] +bidirectional = true +from = "6c07bc70-db4f-4e7a-86f3-0ba0ce9bebf9" +to = "1e13a25d-fb23-4061-853a-5fe996b03281" +points = ["200,140", "120,140"] diff --git a/application/src/main/files/config/RandomAccessMachineRAM.toml b/application/src/main/files/config/RandomAccessMachineRAM.toml index 40ee2972b..43864aae2 100644 --- a/application/src/main/files/config/RandomAccessMachineRAM.toml +++ b/application/src/main/files/config/RandomAccessMachineRAM.toml @@ -1,80 +1,82 @@ name = "Random Access Machine (RAM)" [MEMORY] - schemaPoint = "80,200" - path = "ram-mem.jar" - name = "ram-mem" - id = "98eb1bd9-52dc-4f8b-bb7c-6b1def31aa6e" - type = "MEMORY" +schemaPoint = "80,200" +path = "ram-mem.jar" +name = "ram-mem" +id = "98eb1bd9-52dc-4f8b-bb7c-6b1def31aa6e" +type = "MEMORY" [COMPILER] - schemaPoint = "80,60" - path = "ramc-ram.jar" - name = "ramc-ram" - id = "d2ef750d-6617-44a7-8f17-93ff9d791d07" - type = "COMPILER" +schemaPoint = "80,60" +path = "ramc-ram.jar" +name = "ramc-ram" +id = "d2ef750d-6617-44a7-8f17-93ff9d791d07" +type = "COMPILER" [CPU] - schemaPoint = "200,200" - path = "ram-cpu.jar" - name = "ram-cpu" - id = "e0e2e308-eee2-414e-90e5-b69caea2b032" - type = "CPU" +schemaPoint = "200,200" +path = "ram-cpu.jar" +name = "ram-cpu" +id = "e0e2e308-eee2-414e-90e5-b69caea2b032" +type = "CPU" # Uncomment to apply additional settings -# [DEVICE.settings] -# showAtStartup = false +#[DEVICE.settings] +#showAtStartup = false + [[DEVICE]] - schemaPoint = "360,60" - path = "abstract-tape.jar" - name = "abstract-tape" - id = "ba7e7035-a074-4666-b3fc-d08ca55305f7" - type = "DEVICE" +schemaPoint = "360,60" +path = "abstract-tape.jar" +name = "abstract-tape" +id = "ba7e7035-a074-4666-b3fc-d08ca55305f7" +type = "DEVICE" [[DEVICE]] - schemaPoint = "360,200" - path = "abstract-tape.jar" - name = "abstract-tape" - id = "57389401-fdf7-4bcd-8a66-f936332273bf" - type = "DEVICE" +schemaPoint = "360,200" +path = "abstract-tape.jar" +name = "abstract-tape" +id = "57389401-fdf7-4bcd-8a66-f936332273bf" +type = "DEVICE" [[DEVICE]] - schemaPoint = "200,60" - path = "abstract-tape.jar" - name = "abstract-tape" - id = "c3d76043-bb08-4711-bb8c-14f908fa763b" - type = "DEVICE" +schemaPoint = "200,60" +path = "abstract-tape.jar" +name = "abstract-tape" +id = "c3d76043-bb08-4711-bb8c-14f908fa763b" +type = "DEVICE" # Uncomment to apply additional settings -# [DEVICE.settings] -# showAtStartup = false +#[DEVICE.settings] +#showAtStartup = false + [[connections]] - bidirectional = true - from = "98eb1bd9-52dc-4f8b-bb7c-6b1def31aa6e" - to = "e0e2e308-eee2-414e-90e5-b69caea2b032" - points = [] +bidirectional = true +from = "98eb1bd9-52dc-4f8b-bb7c-6b1def31aa6e" +to = "e0e2e308-eee2-414e-90e5-b69caea2b032" +points = [] [[connections]] - bidirectional = true - from = "d2ef750d-6617-44a7-8f17-93ff9d791d07" - to = "98eb1bd9-52dc-4f8b-bb7c-6b1def31aa6e" - points = [] +bidirectional = true +from = "d2ef750d-6617-44a7-8f17-93ff9d791d07" +to = "98eb1bd9-52dc-4f8b-bb7c-6b1def31aa6e" +points = [] [[connections]] - bidirectional = true - from = "ba7e7035-a074-4666-b3fc-d08ca55305f7" - to = "e0e2e308-eee2-414e-90e5-b69caea2b032" - points = ["360,120", "220,120"] +bidirectional = true +from = "ba7e7035-a074-4666-b3fc-d08ca55305f7" +to = "e0e2e308-eee2-414e-90e5-b69caea2b032" +points = ["360,120", "220,120"] [[connections]] - bidirectional = true - from = "57389401-fdf7-4bcd-8a66-f936332273bf" - to = "e0e2e308-eee2-414e-90e5-b69caea2b032" - points = [] +bidirectional = true +from = "57389401-fdf7-4bcd-8a66-f936332273bf" +to = "e0e2e308-eee2-414e-90e5-b69caea2b032" +points = [] [[connections]] - bidirectional = true - from = "e0e2e308-eee2-414e-90e5-b69caea2b032" - to = "c3d76043-bb08-4711-bb8c-14f908fa763b" - points = [] +bidirectional = true +from = "e0e2e308-eee2-414e-90e5-b69caea2b032" +to = "c3d76043-bb08-4711-bb8c-14f908fa763b" +points = [] diff --git a/application/src/main/files/config/RandomAccessStoredProgramRASP.toml b/application/src/main/files/config/RandomAccessStoredProgramRASP.toml index fa3b0a460..63fcd7588 100644 --- a/application/src/main/files/config/RandomAccessStoredProgramRASP.toml +++ b/application/src/main/files/config/RandomAccessStoredProgramRASP.toml @@ -1,61 +1,61 @@ name = "Random-Access Stored Program (RASP)" [MEMORY] - schemaPoint = "80,180" - path = "rasp-mem.jar" - name = "rasp-mem" - id = "e0de33c4-3547-4f1b-ae1f-9b7fad88bce2" - type = "MEMORY" +schemaPoint = "80,180" +path = "rasp-mem.jar" +name = "rasp-mem" +id = "e0de33c4-3547-4f1b-ae1f-9b7fad88bce2" +type = "MEMORY" [COMPILER] - schemaPoint = "80,60" - path = "raspc-rasp.jar" - name = "raspc-rasp" - id = "20f5dc7e-e72b-4bbc-ab7a-3290a78a6f86" - type = "COMPILER" +schemaPoint = "80,60" +path = "raspc-rasp.jar" +name = "raspc-rasp" +id = "20f5dc7e-e72b-4bbc-ab7a-3290a78a6f86" +type = "COMPILER" [CPU] - schemaPoint = "220,180" - path = "rasp-cpu.jar" - name = "rasp-cpu" - id = "f6e16d46-1c77-4ac9-9029-1a8652bc0f68" - type = "CPU" +schemaPoint = "220,180" +path = "rasp-cpu.jar" +name = "rasp-cpu" +id = "f6e16d46-1c77-4ac9-9029-1a8652bc0f68" +type = "CPU" [[DEVICE]] - schemaPoint = "220,60" - path = "abstract-tape.jar" - name = "abstract-tape" - id = "d3ddf28a-b865-41af-986f-bd1b2584a1bc" - type = "DEVICE" +schemaPoint = "220,60" +path = "abstract-tape.jar" +name = "abstract-tape" +id = "d3ddf28a-b865-41af-986f-bd1b2584a1bc" +type = "DEVICE" [[DEVICE]] - schemaPoint = "380,180" - path = "abstract-tape.jar" - name = "abstract-tape" - id = "c6bbc8b5-fed7-4940-8d08-fb5ecd3f41bc" - type = "DEVICE" +schemaPoint = "380,180" +path = "abstract-tape.jar" +name = "abstract-tape" +id = "c6bbc8b5-fed7-4940-8d08-fb5ecd3f41bc" +type = "DEVICE" [[connections]] - bidirectional = true - from = "20f5dc7e-e72b-4bbc-ab7a-3290a78a6f86" - to = "e0de33c4-3547-4f1b-ae1f-9b7fad88bce2" - points = [] +bidirectional = true +from = "20f5dc7e-e72b-4bbc-ab7a-3290a78a6f86" +to = "e0de33c4-3547-4f1b-ae1f-9b7fad88bce2" +points = [] [[connections]] - bidirectional = true - from = "e0de33c4-3547-4f1b-ae1f-9b7fad88bce2" - to = "f6e16d46-1c77-4ac9-9029-1a8652bc0f68" - points = [] +bidirectional = true +from = "e0de33c4-3547-4f1b-ae1f-9b7fad88bce2" +to = "f6e16d46-1c77-4ac9-9029-1a8652bc0f68" +points = [] [[connections]] - bidirectional = true - from = "d3ddf28a-b865-41af-986f-bd1b2584a1bc" - to = "f6e16d46-1c77-4ac9-9029-1a8652bc0f68" - points = [] +bidirectional = true +from = "d3ddf28a-b865-41af-986f-bd1b2584a1bc" +to = "f6e16d46-1c77-4ac9-9029-1a8652bc0f68" +points = [] [[connections]] - bidirectional = true - from = "c6bbc8b5-fed7-4940-8d08-fb5ecd3f41bc" - to = "f6e16d46-1c77-4ac9-9029-1a8652bc0f68" - points = [] +bidirectional = true +from = "c6bbc8b5-fed7-4940-8d08-fb5ecd3f41bc" +to = "f6e16d46-1c77-4ac9-9029-1a8652bc0f68" +points = [] diff --git a/application/src/main/files/config/SSEMBaby.toml b/application/src/main/files/config/SSEMBaby.toml index 0d16b49eb..c0779337e 100644 --- a/application/src/main/files/config/SSEMBaby.toml +++ b/application/src/main/files/config/SSEMBaby.toml @@ -1,54 +1,54 @@ name = "SSEM (Baby)" [MEMORY] - schemaPoint = "80,180" - path = "ssem-mem.jar" - name = "ssem-mem" - id = "484b749c-22af-4179-90cd-e0cb1648c163" - type = "MEMORY" +schemaPoint = "80,180" +path = "ssem-mem.jar" +name = "ssem-mem" +id = "484b749c-22af-4179-90cd-e0cb1648c163" +type = "MEMORY" [COMPILER] - schemaPoint = "80,60" - path = "as-ssem.jar" - name = "as-ssem" - id = "bb2bd08e-523b-4adf-936d-df77142b91d1" - type = "COMPILER" +schemaPoint = "80,60" +path = "as-ssem.jar" +name = "as-ssem" +id = "bb2bd08e-523b-4adf-936d-df77142b91d1" +type = "COMPILER" [CPU] - schemaPoint = "220,180" - path = "ssem-cpu.jar" - name = "ssem-cpu" - id = "dd29f197-be51-4d24-b862-38db1565b4b0" - type = "CPU" +schemaPoint = "220,180" +path = "ssem-cpu.jar" +name = "ssem-cpu" +id = "dd29f197-be51-4d24-b862-38db1565b4b0" +type = "CPU" [[DEVICE]] - schemaPoint = "220,60" - path = "ssem-display.jar" - name = "ssem-display" - id = "3411f5ac-ef22-4b7f-b326-d90eab06da4a" - type = "DEVICE" +schemaPoint = "220,60" +path = "ssem-display.jar" +name = "ssem-display" +id = "3411f5ac-ef22-4b7f-b326-d90eab06da4a" +type = "DEVICE" [[connections]] - bidirectional = true - from = "bb2bd08e-523b-4adf-936d-df77142b91d1" - to = "484b749c-22af-4179-90cd-e0cb1648c163" - points = [] +bidirectional = true +from = "bb2bd08e-523b-4adf-936d-df77142b91d1" +to = "484b749c-22af-4179-90cd-e0cb1648c163" +points = [] [[connections]] - bidirectional = true - from = "484b749c-22af-4179-90cd-e0cb1648c163" - to = "dd29f197-be51-4d24-b862-38db1565b4b0" - points = [] +bidirectional = true +from = "484b749c-22af-4179-90cd-e0cb1648c163" +to = "dd29f197-be51-4d24-b862-38db1565b4b0" +points = [] [[connections]] - bidirectional = true - from = "dd29f197-be51-4d24-b862-38db1565b4b0" - to = "3411f5ac-ef22-4b7f-b326-d90eab06da4a" - points = [] +bidirectional = true +from = "dd29f197-be51-4d24-b862-38db1565b4b0" +to = "3411f5ac-ef22-4b7f-b326-d90eab06da4a" +points = [] [[connections]] - bidirectional = true - from = "484b749c-22af-4179-90cd-e0cb1648c163" - to = "3411f5ac-ef22-4b7f-b326-d90eab06da4a" - points = ["100,120", "200,120"] +bidirectional = true +from = "484b749c-22af-4179-90cd-e0cb1648c163" +to = "3411f5ac-ef22-4b7f-b326-d90eab06da4a" +points = ["100,120", "200,120"] diff --git a/application/src/main/java/net/emustudio/application/Resources.java b/application/src/main/java/net/emustudio/application/Resources.java index ef649a2fe..49951a496 100644 --- a/application/src/main/java/net/emustudio/application/Resources.java +++ b/application/src/main/java/net/emustudio/application/Resources.java @@ -34,8 +34,8 @@ public static Optional getResourceBundle() { public static String getVersion() { return getResourceBundle() - .map(b -> b.getString("version")) - .orElse(Resources.class.getPackage().getImplementationVersion()); + .map(b -> b.getString("version")) + .orElse(Resources.class.getPackage().getImplementationVersion()); } public static String getCopyright() { diff --git a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java index b86ca0b46..a7b8268ca 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java +++ b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java @@ -18,14 +18,14 @@ */ package net.emustudio.application.cmdline; -import net.emustudio.application.settings.AppSettings; -import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.emulation.Automation; import net.emustudio.application.gui.ExtendedDialogs; import net.emustudio.application.gui.GuiDialogsImpl; import net.emustudio.application.gui.NoGuiDialogsImpl; import net.emustudio.application.gui.debugtable.DebugTableModelImpl; import net.emustudio.application.gui.dialogs.LoadingDialog; +import net.emustudio.application.settings.AppSettings; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.virtualcomputer.ContextPoolImpl; import net.emustudio.application.virtualcomputer.VirtualComputer; import net.emustudio.emulib.runtime.helpers.RadixUtils; @@ -68,8 +68,8 @@ public void run() { } Optional computerConfigOpt = (runner.exclusive != null) ? - runner.exclusive.loadConfiguration() : - (gui ? loadComputerConfigFromGui(appConfig, dialogs) : Optional.empty()); + runner.exclusive.loadConfiguration() : + (gui ? loadComputerConfigFromGui(appConfig, dialogs) : Optional.empty()); if (computerConfigOpt.isEmpty()) { dialogs.showError("Virtual computer must be selected!"); @@ -83,16 +83,16 @@ public void run() { ContextPoolImpl contextPool = new ContextPoolImpl(EMUSTUDIO_ID); DebugTableModelImpl debugTableModel = new DebugTableModelImpl(); - try(VirtualComputer computer = loadComputer( - appConfig, computerConfig, dialogs, contextPool, debugTableModel + try (VirtualComputer computer = loadComputer( + appConfig, computerConfig, dialogs, contextPool, debugTableModel )) { splash.ifPresent(Window::dispose); new Automation( - computer, runner.inputFile, - appConfig, - dialogs, - waitForFinishMillis, - RadixUtils.getInstance().parseRadix(programStart) + computer, runner.inputFile, + appConfig, + dialogs, + waitForFinishMillis, + RadixUtils.getInstance().parseRadix(programStart) ).run(); } System.exit(0); diff --git a/application/src/main/java/net/emustudio/application/cmdline/Runner.java b/application/src/main/java/net/emustudio/application/cmdline/Runner.java index fe529c888..6a613f3a2 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/Runner.java +++ b/application/src/main/java/net/emustudio/application/cmdline/Runner.java @@ -19,13 +19,13 @@ package net.emustudio.application.cmdline; import net.emustudio.application.Resources; -import net.emustudio.application.settings.AppSettings; -import net.emustudio.application.settings.ComputerConfig; -import net.emustudio.application.settings.ConfigFiles; import net.emustudio.application.gui.ExtendedDialogs; import net.emustudio.application.gui.GuiDialogsImpl; import net.emustudio.application.gui.debugtable.DebugTableModelImpl; import net.emustudio.application.gui.dialogs.LoadingDialog; +import net.emustudio.application.settings.AppSettings; +import net.emustudio.application.settings.ComputerConfig; +import net.emustudio.application.settings.ConfigFiles; import net.emustudio.application.virtualcomputer.ContextPoolImpl; import net.emustudio.application.virtualcomputer.VirtualComputer; import org.slf4j.Logger; @@ -38,32 +38,28 @@ import java.util.concurrent.atomic.AtomicInteger; import static net.emustudio.application.cmdline.Utils.*; -import static net.emustudio.application.settings.ConfigFiles.listConfigurationNames; import static net.emustudio.application.gui.GuiUtils.setupLookAndFeel; +import static net.emustudio.application.settings.ConfigFiles.listConfigurationNames; @SuppressWarnings("unused") @CommandLine.Command( - name = "emuStudio", - mixinStandardHelpOptions = true, - versionProvider = Runner.VersionProvider.class, - description = "Universal emulation platform and framework", - scope = CommandLine.ScopeType.INHERIT, - subcommands = {AutomationCommand.class} + name = "emuStudio", + mixinStandardHelpOptions = true, + versionProvider = Runner.VersionProvider.class, + description = "Universal emulation platform and framework", + scope = CommandLine.ScopeType.INHERIT, + subcommands = {AutomationCommand.class} ) public class Runner implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(Runner.class); - + // if a command is being run, default behavior is: do nothing + private static boolean runsSomeCommand; @CommandLine.ArgGroup(heading = "Virtual computer%n") public Exclusive exclusive; - - @CommandLine.Option(names = {"-l", "--list-computers"}, description = "list all existing virtual computers") - private boolean listConfigs; - @CommandLine.Option(names = {"-i", "--input-file"}, description = "input file name (source code)", paramLabel = "FILE") public Path inputFile; - - // if a command is being run, default behavior is: do nothing - private static boolean runsSomeCommand; + @CommandLine.Option(names = {"-l", "--list-computers"}, description = "list all existing virtual computers") + private boolean listConfigs; public static void main(String[] args) { CommandLine cmdline = new CommandLine(new Runner()); @@ -101,8 +97,8 @@ public void run() { setupLookAndFeel(appConfig); ExtendedDialogs dialogs = new GuiDialogsImpl(); Optional computerConfigOpt = (exclusive != null) ? - exclusive.loadConfiguration() : - loadComputerConfigFromGui(appConfig, dialogs); + exclusive.loadConfiguration() : + loadComputerConfigFromGui(appConfig, dialogs); if (computerConfigOpt.isEmpty()) { System.err.println("Virtual computer must be selected!"); @@ -115,12 +111,12 @@ public void run() { ContextPoolImpl contextPool = new ContextPoolImpl(EMUSTUDIO_ID); DebugTableModelImpl debugTableModel = new DebugTableModelImpl(); VirtualComputer computer = loadComputer( - appConfig, computerConfig, dialogs, contextPool, debugTableModel + appConfig, computerConfig, dialogs, contextPool, debugTableModel ); splash.dispose(); showMainWindow( - computer, appConfig, dialogs, debugTableModel, contextPool, Optional.ofNullable(inputFile) + computer, appConfig, dialogs, debugTableModel, contextPool, Optional.ofNullable(inputFile) ); } catch (Exception e) { LOGGER.error("Unexpected error", e); @@ -131,22 +127,22 @@ public void run() { public static class Exclusive { @CommandLine.Option(names = {"-c", "--computer"}, - description = "virtual computer name (see -l for options)", - paramLabel = "NAME" + description = "virtual computer name (see -l for options)", + paramLabel = "NAME" ) public String configName; @CommandLine.Option( - names = {"-cf", "--computer-file"}, - description = "virtual computer configuration file", - paramLabel = "FILE" + names = {"-cf", "--computer-file"}, + description = "virtual computer configuration file", + paramLabel = "FILE" ) public Path configFile; @CommandLine.Option( - names = {"-cn", "--computer-index"}, - description = "virtual computer index (see -l for options)", - paramLabel = "INDEX" + names = {"-cn", "--computer-index"}, + description = "virtual computer index (see -l for options)", + paramLabel = "INDEX" ) public Integer configIndex; diff --git a/application/src/main/java/net/emustudio/application/cmdline/Utils.java b/application/src/main/java/net/emustudio/application/cmdline/Utils.java index 704045e0b..2ab6730f4 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/Utils.java +++ b/application/src/main/java/net/emustudio/application/cmdline/Utils.java @@ -19,14 +19,14 @@ package net.emustudio.application.cmdline; import net.emustudio.application.ApplicationApiImpl; -import net.emustudio.application.settings.AppSettings; -import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.ExtendedDialogs; import net.emustudio.application.gui.debugtable.DebugTableModel; import net.emustudio.application.gui.debugtable.DebugTableModelImpl; import net.emustudio.application.gui.dialogs.LoadingDialog; import net.emustudio.application.gui.dialogs.OpenComputerDialog; import net.emustudio.application.gui.dialogs.StudioFrame; +import net.emustudio.application.settings.AppSettings; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.virtualcomputer.ContextPoolImpl; import net.emustudio.application.virtualcomputer.InvalidPluginException; import net.emustudio.application.virtualcomputer.VirtualComputer; @@ -48,8 +48,8 @@ import java.util.concurrent.atomic.AtomicReference; public class Utils { - private static final Logger LOGGER = LoggerFactory.getLogger(Runner.class); public static final long EMUSTUDIO_ID = UUID.randomUUID().toString().hashCode(); + private static final Logger LOGGER = LoggerFactory.getLogger(Runner.class); public static AppSettings loadAppSettings(boolean gui, boolean auto) throws IOException { Path configFile = Path.of("emuStudio.toml"); @@ -62,11 +62,11 @@ public static AppSettings loadAppSettings(boolean gui, boolean auto) throws IOEx } public static VirtualComputer loadComputer( - AppSettings appConfig, - ComputerConfig computerConfig, - ExtendedDialogs dialogs, - ContextPoolImpl contextPool, - DebugTableModelImpl debugTableModel + AppSettings appConfig, + ComputerConfig computerConfig, + ExtendedDialogs dialogs, + ContextPoolImpl contextPool, + DebugTableModelImpl debugTableModel ) throws InvalidPluginException, IOException, PluginInitializationException { ApplicationApi applicationApi = new ApplicationApiImpl(debugTableModel, contextPool, dialogs); @@ -107,7 +107,7 @@ public static void showMainWindow(VirtualComputer computer, AppSettings appSetti } StudioFrame mainWindow = new StudioFrame( - computer, appSettings, dialogs, debugTableModel, memoryContext, inputFile + computer, appSettings, dialogs, debugTableModel, memoryContext, inputFile ); dialogs.setParent(mainWindow); diff --git a/application/src/main/java/net/emustudio/application/emulation/Automation.java b/application/src/main/java/net/emustudio/application/emulation/Automation.java index e4a5c8d55..195be0dde 100644 --- a/application/src/main/java/net/emustudio/application/emulation/Automation.java +++ b/application/src/main/java/net/emustudio/application/emulation/Automation.java @@ -18,9 +18,9 @@ */ package net.emustudio.application.emulation; -import net.emustudio.application.settings.AppSettings; import net.emustudio.application.gui.dialogs.AutoDialog; import net.emustudio.application.internal.Unchecked; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.virtualcomputer.VirtualComputer; import net.emustudio.emulib.plugins.compiler.Compiler; import net.emustudio.emulib.plugins.compiler.CompilerListener; @@ -41,18 +41,15 @@ * the emulation is started automatically and results are collected. */ public class Automation implements Runnable { - private static final Logger LOGGER = LoggerFactory.getLogger("automation"); public static final int DONT_WAIT = -1; - - private AutoDialog progressGUI; + private static final Logger LOGGER = LoggerFactory.getLogger("automation"); private final File inputFile; - private final VirtualComputer computer; private final AppSettings appSettings; private final Dialogs dialogs; private final int waitForFinishMillis; private final int programStart; - + private AutoDialog progressGUI; private volatile CPU.RunState resultState; public Automation(VirtualComputer computer, Path inputFile, AppSettings appSettings, @@ -219,7 +216,7 @@ public void run() { LOGGER.info("Starting emulation automation..."); computer.getCompiler().ifPresent( - compiler -> LOGGER.info("Compiler: " + compiler.getTitle() + ", version " + compiler.getVersion()) + compiler -> LOGGER.info("Compiler: " + compiler.getTitle() + ", version " + compiler.getVersion()) ); computer.getCPU().ifPresent(cpu -> LOGGER.info("CPU: " + cpu.getTitle() + ", version " + cpu.getVersion())); computer.getMemory().ifPresent(memory -> { @@ -227,7 +224,7 @@ public void run() { LOGGER.info("Memory size: {}", memory.getSize()); }); computer.getDevices().forEach( - device -> LOGGER.info("Device: " + device.getTitle() + ", version " + device.getVersion()) + device -> LOGGER.info("Device: " + device.getTitle() + ", version " + device.getVersion()) ); try { diff --git a/application/src/main/java/net/emustudio/application/gui/GuiDialogsImpl.java b/application/src/main/java/net/emustudio/application/gui/GuiDialogsImpl.java index 334a5f329..fa81673ef 100644 --- a/application/src/main/java/net/emustudio/application/gui/GuiDialogsImpl.java +++ b/application/src/main/java/net/emustudio/application/gui/GuiDialogsImpl.java @@ -75,7 +75,7 @@ public Optional readInteger(String message, String title) { @Override public Optional readInteger(String message, String title, int initial) { Object inputValue = JOptionPane.showInputDialog( - parent, message, title, JOptionPane.QUESTION_MESSAGE, null, null, initial + parent, message, title, JOptionPane.QUESTION_MESSAGE, null, null, initial ); return Optional.ofNullable(inputValue).map(String::valueOf).map(radixUtils::parseRadix); } @@ -93,7 +93,7 @@ public Optional readString(String message, String title) { @Override public Optional readString(String message, String title, String initial) { Object inputValue = JOptionPane.showInputDialog( - parent, message, title, JOptionPane.QUESTION_MESSAGE, null, null, initial + parent, message, title, JOptionPane.QUESTION_MESSAGE, null, null, initial ); return Optional.ofNullable(inputValue).map(String::valueOf); } @@ -111,7 +111,7 @@ public Optional readDouble(String message, String title) { @Override public Optional readDouble(String message, String title, double initial) { Object inputValue = JOptionPane.showInputDialog( - parent, message, title, JOptionPane.QUESTION_MESSAGE, null, null, initial + parent, message, title, JOptionPane.QUESTION_MESSAGE, null, null, initial ); return Optional.ofNullable(inputValue).map(String::valueOf).map(Double::parseDouble); } @@ -124,7 +124,7 @@ public DialogAnswer ask(String message) { @Override public DialogAnswer ask(String message, String title) { int answer = JOptionPane.showConfirmDialog( - parent, message, title, JOptionPane.YES_NO_CANCEL_OPTION + parent, message, title, JOptionPane.YES_NO_CANCEL_OPTION ); switch (answer) { @@ -161,12 +161,12 @@ public Optional chooseFile(String title, String approveButtonText, Path ba FileNameExtensionFilter firstFilter = null; for (FileExtensionsFilter filter : filters) { String formattedExtensions = filter.getExtensions().stream() - .map(e -> "*." + e) - .collect(Collectors.joining(", ", " (", ")")); + .map(e -> "*." + e) + .collect(Collectors.joining(", ", " (", ")")); FileNameExtensionFilter extensionFilter = new FileNameExtensionFilter( - filter.getDescription() + formattedExtensions, - filter.getExtensions().toArray(new String[0]) + filter.getDescription() + formattedExtensions, + filter.getExtensions().toArray(new String[0]) ); if (firstFilter == null) { firstFilter = extensionFilter; @@ -184,7 +184,7 @@ public Optional chooseFile(String title, String approveButtonText, Path ba List allExtensions = new ArrayList<>(); FileFilter selectedFilter = fileChooser.getFileFilter(); if (selectedFilter instanceof FileNameExtensionFilter) { - allExtensions.addAll(List.of(((FileNameExtensionFilter)selectedFilter).getExtensions())); + allExtensions.addAll(List.of(((FileNameExtensionFilter) selectedFilter).getExtensions())); } File selectedFile = fileChooser.getSelectedFile(); @@ -209,7 +209,7 @@ public Optional chooseFile(String title, String approveButtonText, Path ba public Optional chooseFile(String title, String approveButtonText, Path baseDirectory, boolean appendMissingExtension, List filters) { return chooseFile( - title, approveButtonText, baseDirectory, appendMissingExtension, filters.toArray(FileExtensionsFilter[]::new) + title, approveButtonText, baseDirectory, appendMissingExtension, filters.toArray(FileExtensionsFilter[]::new) ); } } diff --git a/application/src/main/java/net/emustudio/application/gui/GuiUtils.java b/application/src/main/java/net/emustudio/application/gui/GuiUtils.java index 9e50f825f..1d2882a95 100644 --- a/application/src/main/java/net/emustudio/application/gui/GuiUtils.java +++ b/application/src/main/java/net/emustudio/application/gui/GuiUtils.java @@ -40,7 +40,7 @@ public class GuiUtils { public static void addKeyListenerRecursively(Component c, KeyListener keyListener) { c.addKeyListener(keyListener); if (c instanceof Container) { - for (Component child : ((Container)c).getComponents()) { + for (Component child : ((Container) c).getComponents()) { addKeyListenerRecursively(child, keyListener); } } diff --git a/application/src/main/java/net/emustudio/application/gui/NoGuiDialogsImpl.java b/application/src/main/java/net/emustudio/application/gui/NoGuiDialogsImpl.java index 4834db2b1..e174bed78 100644 --- a/application/src/main/java/net/emustudio/application/gui/NoGuiDialogsImpl.java +++ b/application/src/main/java/net/emustudio/application/gui/NoGuiDialogsImpl.java @@ -28,8 +28,12 @@ import java.util.Optional; public class NoGuiDialogsImpl implements ExtendedDialogs { - private final static Logger LOGGER = LoggerFactory.getLogger(NoGuiDialogsImpl.class); public final static String INPUT_MESSAGE = "Please insert a value"; + private final static Logger LOGGER = LoggerFactory.getLogger(NoGuiDialogsImpl.class); + + public static String formatMessage(String title, String message) { + return "[" + title + "] " + message; + } @Override public void showError(String message) { @@ -58,7 +62,7 @@ public Optional readInteger(String message) { @Override public Optional readInteger(String message, String title) { - return readInteger(message, title,0); + return readInteger(message, title, 0); } @Override @@ -129,8 +133,4 @@ public Optional chooseFile(String title, String approveButtonText, Path ba boolean appendMissingExtension, List list) { return Optional.empty(); } - - public static String formatMessage(String title, String message) { - return "[" + title + "] " + message; - } } diff --git a/application/src/main/java/net/emustudio/application/gui/P.java b/application/src/main/java/net/emustudio/application/gui/P.java index a813912d3..33db2f3a7 100644 --- a/application/src/main/java/net/emustudio/application/gui/P.java +++ b/application/src/main/java/net/emustudio/application/gui/P.java @@ -32,6 +32,22 @@ private P(double x, double y) { this.y = y; } + public static P of(double x, double y) { + return new P(x, y); + } + + public static P of(int x, int y) { + return new P(x, y); + } + + public static P of(SchemaPoint schemaPoint) { + return new P(schemaPoint.x, schemaPoint.y); + } + + public static P of(Point point) { + return new P(point.getX(), point.getY()); + } + public int ix() { return (int) x; } @@ -61,24 +77,7 @@ public boolean isInRectangle(Point leftTop, Point rightBottom) { return ((x >= leftTop.x) && (x <= rightBottom.x) && (y >= leftTop.y) && (y <= rightBottom.y)); } - public SchemaPoint toSchemaPoint() { return SchemaPoint.of(ix(), iy()); } - - public static P of(double x, double y) { - return new P(x, y); - } - - public static P of(int x, int y) { - return new P(x, y); - } - - public static P of(SchemaPoint schemaPoint) { - return new P(schemaPoint.x, schemaPoint.y); - } - - public static P of(Point point) { - return new P(point.getX(), point.getY()); - } } diff --git a/application/src/main/java/net/emustudio/application/gui/ToolbarToggleButton.java b/application/src/main/java/net/emustudio/application/gui/ToolbarToggleButton.java index e4ae0f8cb..623b3baa0 100644 --- a/application/src/main/java/net/emustudio/application/gui/ToolbarToggleButton.java +++ b/application/src/main/java/net/emustudio/application/gui/ToolbarToggleButton.java @@ -44,6 +44,7 @@ public void actionPerformed(ActionEvent actionEvent) { } public ToolbarToggleButton(Consumer action, String iconResource, String tooltipText) { - this(action, (ItemEvent itemAction) -> {}, iconResource, tooltipText); + this(action, (ItemEvent itemAction) -> { + }, iconResource, tooltipText); } } diff --git a/application/src/main/java/net/emustudio/application/gui/actions/CompileAction.java b/application/src/main/java/net/emustudio/application/gui/actions/CompileAction.java index 37a589555..470b89afb 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/CompileAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/CompileAction.java @@ -44,9 +44,9 @@ public class CompileAction extends AbstractAction { public CompileAction(VirtualComputer computer, Dialogs dialogs, Editor editor, Supplier runState, JTextArea compilerOutput, Runnable updateTitle) { super("Compile", - new ImageIcon(Objects.requireNonNull( - CompileAction.class.getResource("/net/emustudio/application/gui/dialogs/compile.png") - )) + new ImageIcon(Objects.requireNonNull( + CompileAction.class.getResource("/net/emustudio/application/gui/dialogs/compile.png") + )) ); this.computer = Objects.requireNonNull(computer); diff --git a/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java index 0abb51a41..581109f8e 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/ViewComputerAction.java @@ -18,8 +18,8 @@ */ package net.emustudio.application.gui.actions; -import net.emustudio.application.settings.AppSettings; import net.emustudio.application.gui.dialogs.ViewComputerDialog; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.virtualcomputer.VirtualComputer; import net.emustudio.emulib.runtime.interaction.Dialogs; diff --git a/application/src/main/java/net/emustudio/application/gui/actions/editor/FindAction.java b/application/src/main/java/net/emustudio/application/gui/actions/editor/FindAction.java index 5c65be81c..2de94fd42 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/editor/FindAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/editor/FindAction.java @@ -19,14 +19,13 @@ package net.emustudio.application.gui.actions.editor; import org.fife.rsta.ui.search.FindDialog; +import org.fife.rsta.ui.search.ReplaceDialog; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.Objects; -import org.fife.rsta.ui.search.ReplaceDialog; - public class FindAction extends AbstractAction { private final FindDialog findDialog; private final ReplaceDialog replaceDialog; diff --git a/application/src/main/java/net/emustudio/application/gui/actions/editor/FindPreviousAction.java b/application/src/main/java/net/emustudio/application/gui/actions/editor/FindPreviousAction.java index 9071245bf..cc98db608 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/editor/FindPreviousAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/editor/FindPreviousAction.java @@ -26,7 +26,7 @@ import java.awt.event.KeyEvent; import java.util.Objects; -public class FindPreviousAction extends AbstractAction { +public class FindPreviousAction extends AbstractAction { private final Editor editor; private final Dialogs dialogs; diff --git a/application/src/main/java/net/emustudio/application/gui/actions/emulator/BreakpointAction.java b/application/src/main/java/net/emustudio/application/gui/actions/emulator/BreakpointAction.java index 5cbee253e..d0e860857 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/emulator/BreakpointAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/emulator/BreakpointAction.java @@ -35,8 +35,8 @@ public class BreakpointAction extends AbstractAction { public BreakpointAction(JFrame parent, VirtualComputer computer, Dialogs dialogs, Runnable refreshDebugTable) { super( - "Set/unset breakpoint...", - new ImageIcon(ResetAction.class.getResource("/net/emustudio/application/gui/dialogs/breakpoints.png")) + "Set/unset breakpoint...", + new ImageIcon(ResetAction.class.getResource("/net/emustudio/application/gui/dialogs/breakpoints.png")) ); this.parent = Objects.requireNonNull(parent); diff --git a/application/src/main/java/net/emustudio/application/gui/actions/emulator/JumpAction.java b/application/src/main/java/net/emustudio/application/gui/actions/emulator/JumpAction.java index a907435ce..93db3cd80 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/emulator/JumpAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/emulator/JumpAction.java @@ -45,16 +45,16 @@ public void actionPerformed(ActionEvent actionEvent) { computer.getCPU().ifPresentOrElse(cpu -> { try { dialogs - .readInteger("Memory address:", "Jump to address", 0) - .ifPresent(address -> { - if (!cpu.setInstructionLocation(address)) { - int memorySize = computer.getMemory().map(Memory::getSize).orElse(0); - String maxSizeMessage = (memorySize == 0) ? "" : "(probably accepts range from 0 to " + memorySize + ")"; - dialogs.showError("Invalid memory address" + maxSizeMessage); - } else { - refreshDebugTable.run(); - } - }); + .readInteger("Memory address:", "Jump to address", 0) + .ifPresent(address -> { + if (!cpu.setInstructionLocation(address)) { + int memorySize = computer.getMemory().map(Memory::getSize).orElse(0); + String maxSizeMessage = (memorySize == 0) ? "" : "(probably accepts range from 0 to " + memorySize + ")"; + dialogs.showError("Invalid memory address" + maxSizeMessage); + } else { + refreshDebugTable.run(); + } + }); } catch (NumberFormatException e) { dialogs.showError("Invalid address format", "Jump to address"); } diff --git a/application/src/main/java/net/emustudio/application/gui/actions/emulator/JumpToBeginningAction.java b/application/src/main/java/net/emustudio/application/gui/actions/emulator/JumpToBeginningAction.java index ddc180832..cb15c46e5 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/emulator/JumpToBeginningAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/emulator/JumpToBeginningAction.java @@ -30,8 +30,8 @@ public class JumpToBeginningAction extends AbstractAction { public JumpToBeginningAction(VirtualComputer computer, Runnable refreshDebugTable) { super( - "Jump to beginning", - new ImageIcon(JumpToBeginningAction.class.getResource("/net/emustudio/application/gui/dialogs/go-first.png")) + "Jump to beginning", + new ImageIcon(JumpToBeginningAction.class.getResource("/net/emustudio/application/gui/dialogs/go-first.png")) ); this.computer = Objects.requireNonNull(computer); diff --git a/application/src/main/java/net/emustudio/application/gui/actions/emulator/RunTimedAction.java b/application/src/main/java/net/emustudio/application/gui/actions/emulator/RunTimedAction.java index a49a826df..c72ce3342 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/emulator/RunTimedAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/emulator/RunTimedAction.java @@ -44,8 +44,8 @@ public void actionPerformed(ActionEvent actionEvent) { Optional.ofNullable(emulationController).ifPresent(c -> { try { dialogs - .readInteger("Enter time slice in milliseconds:", "Timed emulation", 500) - .ifPresent(sliceMillis -> c.step(sliceMillis, TimeUnit.MILLISECONDS)); + .readInteger("Enter time slice in milliseconds:", "Timed emulation", 500) + .ifPresent(sliceMillis -> c.step(sliceMillis, TimeUnit.MILLISECONDS)); } catch (NumberFormatException e) { dialogs.showError("Invalid number format", "Timed emulation"); } diff --git a/application/src/main/java/net/emustudio/application/gui/actions/emulator/ShowMemoryAction.java b/application/src/main/java/net/emustudio/application/gui/actions/emulator/ShowMemoryAction.java index 3dd240003..563e111e8 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/emulator/ShowMemoryAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/emulator/ShowMemoryAction.java @@ -43,10 +43,10 @@ public ShowMemoryAction(JFrame parent, VirtualComputer computer, Dialogs dialogs @Override public void actionPerformed(ActionEvent actionEvent) { computer.getMemory() - .filter(Memory::isShowSettingsSupported) - .ifPresentOrElse( - p -> p.showSettings(parent), - () -> dialogs.showInfo("Memory GUI is not supported", "Show Memory") - ); + .filter(Memory::isShowSettingsSupported) + .ifPresentOrElse( + p -> p.showSettings(parent), + () -> dialogs.showInfo("Memory GUI is not supported", "Show Memory") + ); } } diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java index 268aea3e6..1ddfc4e1a 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/AddNewComputerAction.java @@ -18,11 +18,11 @@ */ package net.emustudio.application.gui.actions.opencomputer; -import net.emustudio.application.settings.AppSettings; -import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.dialogs.SchemaEditorDialog; import net.emustudio.application.gui.schema.Schema; import net.emustudio.application.internal.Unchecked; +import net.emustudio.application.settings.AppSettings; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.emulib.runtime.interaction.Dialogs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,7 +46,7 @@ public class AddNewComputerAction extends AbstractAction { public AddNewComputerAction(Dialogs dialogs, AppSettings appSettings, Runnable update, JDialog parent) { super( - "Create new computer...", new ImageIcon(AddNewComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/list-add.png")) + "Create new computer...", new ImageIcon(AddNewComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/list-add.png")) ); this.dialogs = Objects.requireNonNull(dialogs); this.appSettings = Objects.requireNonNull(appSettings); @@ -63,16 +63,16 @@ public void actionPerformed(ActionEvent e) { } else { try { loadConfiguration(name) - .ifPresentOrElse( - c -> dialogs.showError("Computer '" + name + "' already exists, choose another name."), - () -> { - ComputerConfig newComputer = Unchecked.call(() -> createConfiguration(name)); - Schema schema = new Schema(newComputer, appSettings); - SchemaEditorDialog di = new SchemaEditorDialog(parent, schema, dialogs); - di.setVisible(true); - update.run(); - } - ); + .ifPresentOrElse( + c -> dialogs.showError("Computer '" + name + "' already exists, choose another name."), + () -> { + ComputerConfig newComputer = Unchecked.call(() -> createConfiguration(name)); + Schema schema = new Schema(newComputer, appSettings); + SchemaEditorDialog di = new SchemaEditorDialog(parent, schema, dialogs); + di.setVisible(true); + update.run(); + } + ); } catch (IOException ex) { LOGGER.error("Could not load computer with name '" + name + "'", ex); dialogs.showError("Could not load computer with name '" + name + "'. Please see log file for details."); diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/DeleteComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/DeleteComputerAction.java index ef88d20c6..3c4e8c129 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/DeleteComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/DeleteComputerAction.java @@ -40,7 +40,7 @@ public class DeleteComputerAction extends AbstractAction { public DeleteComputerAction(Dialogs dialogs, Runnable update, JList lstConfig) { super( - "Delete computer", new ImageIcon(DeleteComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/list-remove.png")) + "Delete computer", new ImageIcon(DeleteComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/list-remove.png")) ); this.dialogs = Objects.requireNonNull(dialogs); this.update = Objects.requireNonNull(update); @@ -50,18 +50,18 @@ public DeleteComputerAction(Dialogs dialogs, Runnable update, JList { - Dialogs.DialogAnswer answer = dialogs.ask("Do you really want to delete selected computer?", "Delete computer"); - if (answer == Dialogs.DialogAnswer.ANSWER_YES) { - try { - removeConfiguration(computer.getName()); - update.run(); - } catch (IOException ex) { - LOGGER.error("Could not remove computer configuration", ex); - dialogs.showError("Computer could not be deleted. Please consult log for details."); + .ofNullable(lstConfig.getSelectedValue()) + .ifPresentOrElse(computer -> { + Dialogs.DialogAnswer answer = dialogs.ask("Do you really want to delete selected computer?", "Delete computer"); + if (answer == Dialogs.DialogAnswer.ANSWER_YES) { + try { + removeConfiguration(computer.getName()); + update.run(); + } catch (IOException ex) { + LOGGER.error("Could not remove computer configuration", ex); + dialogs.showError("Computer could not be deleted. Please consult log for details."); + } } - } - }, () -> dialogs.showError("A computer has to be selected!", "Delete computer")); + }, () -> dialogs.showError("A computer has to be selected!", "Delete computer")); } } diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java index 583157f70..8a7aa1b6a 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/EditComputerAction.java @@ -18,10 +18,10 @@ */ package net.emustudio.application.gui.actions.opencomputer; -import net.emustudio.application.settings.AppSettings; -import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.dialogs.SchemaEditorDialog; import net.emustudio.application.gui.schema.Schema; +import net.emustudio.application.settings.AppSettings; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.emulib.runtime.interaction.Dialogs; import javax.swing.*; @@ -39,7 +39,7 @@ public class EditComputerAction extends AbstractAction { public EditComputerAction(Dialogs dialogs, AppSettings appSettings, Runnable update, JDialog parent, JList lstConfig) { super( - "Edit computer...", new ImageIcon(EditComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/computer.png")) + "Edit computer...", new ImageIcon(EditComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/computer.png")) ); this.dialogs = Objects.requireNonNull(dialogs); this.appSettings = Objects.requireNonNull(appSettings); @@ -51,11 +51,11 @@ public EditComputerAction(Dialogs dialogs, AppSettings appSettings, @Override public void actionPerformed(ActionEvent e) { Optional - .ofNullable(lstConfig.getSelectedValue()) - .ifPresentOrElse(computer -> { - Schema schema = new Schema(computer, appSettings); - new SchemaEditorDialog(parent, schema, dialogs).setVisible(true); - update.run(); - }, () -> dialogs.showError("A computer has to be selected!", "Edit computer")); + .ofNullable(lstConfig.getSelectedValue()) + .ifPresentOrElse(computer -> { + Schema schema = new Schema(computer, appSettings); + new SchemaEditorDialog(parent, schema, dialogs).setVisible(true); + update.run(); + }, () -> dialogs.showError("A computer has to be selected!", "Edit computer")); } } diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/OpenComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/OpenComputerAction.java index 36773132c..1d6c6c08c 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/OpenComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/OpenComputerAction.java @@ -36,7 +36,7 @@ public class OpenComputerAction extends AbstractAction { public OpenComputerAction(Dialogs dialogs, JDialog parent, JList lstConfig, Consumer selectComputer) { super( - "Create new computer...", new ImageIcon(OpenComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/list-add.png")) + "Create new computer...", new ImageIcon(OpenComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/list-add.png")) ); this.dialogs = Objects.requireNonNull(dialogs); this.parent = Objects.requireNonNull(parent); @@ -47,10 +47,10 @@ public OpenComputerAction(Dialogs dialogs, JDialog parent, JList @Override public void actionPerformed(ActionEvent e) { Optional - .ofNullable(lstConfig.getSelectedValue()) - .ifPresentOrElse(computer -> { - selectComputer.accept(computer); - parent.dispose(); - }, () -> dialogs.showError("A computer has to be selected!", "Open computer")); + .ofNullable(lstConfig.getSelectedValue()) + .ifPresentOrElse(computer -> { + selectComputer.accept(computer); + parent.dispose(); + }, () -> dialogs.showError("A computer has to be selected!", "Open computer")); } } diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/RenameComputerAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/RenameComputerAction.java index 5f4eda2c3..eaf173f5d 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/RenameComputerAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/RenameComputerAction.java @@ -42,7 +42,7 @@ public class RenameComputerAction extends AbstractAction { public RenameComputerAction(Dialogs dialogs, Runnable update, JList lstConfig) { super( - "Rename computer...", new ImageIcon(RenameComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/rename-computer.png")) + "Rename computer...", new ImageIcon(RenameComputerAction.class.getResource("/net/emustudio/application/gui/dialogs/rename-computer.png")) ); this.dialogs = Objects.requireNonNull(dialogs); this.update = Objects.requireNonNull(update); @@ -52,21 +52,21 @@ public RenameComputerAction(Dialogs dialogs, Runnable update, @Override public void actionPerformed(ActionEvent e) { Optional - .ofNullable(lstConfig.getSelectedValue()) - .ifPresentOrElse(computer -> dialogs - .readString("Enter new computer name:", "Rename computer") - .ifPresent(newName -> { - if (newName.trim().isEmpty()) { - dialogs.showError("Computer name must be non-empty", "Rename computer"); - } else { - try { - renameConfiguration(computer, newName); - update.run(); - } catch (CannotUpdateSettingException | IOException ex) { - LOGGER.error("Could not rename computer", ex); - dialogs.showError("Computer could not be renamed. Please see log file for details."); - } - } - }), () -> dialogs.showError("A computer has to be selected!", "Rename computer")); + .ofNullable(lstConfig.getSelectedValue()) + .ifPresentOrElse(computer -> dialogs + .readString("Enter new computer name:", "Rename computer") + .ifPresent(newName -> { + if (newName.trim().isEmpty()) { + dialogs.showError("Computer name must be non-empty", "Rename computer"); + } else { + try { + renameConfiguration(computer, newName); + update.run(); + } catch (CannotUpdateSettingException | IOException ex) { + LOGGER.error("Could not rename computer", ex); + dialogs.showError("Computer could not be renamed. Please see log file for details."); + } + } + }), () -> dialogs.showError("A computer has to be selected!", "Rename computer")); } } diff --git a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/SaveSchemaAction.java b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/SaveSchemaAction.java index 1bf57a015..9564f8e9f 100644 --- a/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/SaveSchemaAction.java +++ b/application/src/main/java/net/emustudio/application/gui/actions/opencomputer/SaveSchemaAction.java @@ -29,8 +29,8 @@ public class SaveSchemaAction extends AbstractAction { public SaveSchemaAction(SchemaPreviewPanel preview) { super( - "Save schema image...", - new ImageIcon(SaveSchemaAction.class.getResource("/net/emustudio/application/gui/dialogs/document-save.png")) + "Save schema image...", + new ImageIcon(SaveSchemaAction.class.getResource("/net/emustudio/application/gui/dialogs/document-save.png")) ); this.preview = Objects.requireNonNull(preview); } diff --git a/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableImpl.java b/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableImpl.java index 8e106c4e1..b7aa9158d 100644 --- a/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableImpl.java +++ b/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableImpl.java @@ -28,7 +28,7 @@ import java.awt.event.ComponentEvent; import java.util.Objects; -public class DebugTableImpl extends JTable { +public class DebugTableImpl extends JTable { private final DebugTableModel tableModel; private final BooleanCellRenderer boolRenderer = new BooleanCellRenderer(); private final TextCellRenderer textRenderer; diff --git a/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableModelImpl.java b/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableModelImpl.java index 02f2c6ecd..c8575e315 100644 --- a/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableModelImpl.java +++ b/application/src/main/java/net/emustudio/application/gui/debugtable/DebugTableModelImpl.java @@ -190,11 +190,11 @@ public final void setDefaultColumns() { Disassembler dis = cpu.getDisassembler(); if (cpu.isBreakpointSupported()) { setDebuggerColumns(Arrays.asList( - new BreakpointColumn(cpu), new AddressColumn(), new MnemoColumn(dis), new OpcodeColumn(dis) + new BreakpointColumn(cpu), new AddressColumn(), new MnemoColumn(dis), new OpcodeColumn(dis) )); } else { setDebuggerColumns(Arrays.asList( - new AddressColumn(), new MnemoColumn(dis), new OpcodeColumn(dis) + new AddressColumn(), new MnemoColumn(dis), new OpcodeColumn(dis) )); } }); diff --git a/application/src/main/java/net/emustudio/application/gui/debugtable/PagesPanel.java b/application/src/main/java/net/emustudio/application/gui/debugtable/PagesPanel.java index c00059e4c..484573530 100644 --- a/application/src/main/java/net/emustudio/application/gui/debugtable/PagesPanel.java +++ b/application/src/main/java/net/emustudio/application/gui/debugtable/PagesPanel.java @@ -42,6 +42,13 @@ private PagesPanel(DebugTableModel debugTableModel, Dialogs dialogs) { this.dialogs = Objects.requireNonNull(dialogs); } + public static PagesPanel create(DebugTableModel debugTableModel, Dialogs dialogs) { + PagesPanel pagesPanel = new PagesPanel(debugTableModel, dialogs); + pagesPanel.initComponents(); + + return pagesPanel; + } + private void initComponents() { ToolbarButton btnFirst = new ToolbarButton(evt -> gotoFirstPage(), PAGE_FIRST_PNG, "Go to the first page"); ToolbarButton btnBackward = new ToolbarButton(evt -> gotoPreviousPage(), PAGE_BACK_PNG, "Go to the previous page"); @@ -53,30 +60,30 @@ private void initComponents() { GroupLayout pagesLayout = new GroupLayout(this); setLayout(pagesLayout); pagesLayout.setHorizontalGroup( - pagesLayout.createParallelGroup(GroupLayout.Alignment.CENTER) - .addGroup(pagesLayout.createSequentialGroup() - .addComponent(btnFirst) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnSeekBackward) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnBackward) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnCurrentPage) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnForward) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnSeekForward)) + pagesLayout.createParallelGroup(GroupLayout.Alignment.CENTER) + .addGroup(pagesLayout.createSequentialGroup() + .addComponent(btnFirst) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnSeekBackward) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnBackward) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnCurrentPage) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnForward) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnSeekForward)) ); pagesLayout.setVerticalGroup( - pagesLayout.createParallelGroup(GroupLayout.Alignment.CENTER) - .addGroup(pagesLayout.createSequentialGroup() - .addGroup(pagesLayout.createParallelGroup(GroupLayout.Alignment.CENTER) - .addComponent(btnSeekBackward) - .addComponent(btnBackward) - .addComponent(btnFirst) - .addComponent(btnCurrentPage) - .addComponent(btnSeekForward) - .addComponent(btnForward))) + pagesLayout.createParallelGroup(GroupLayout.Alignment.CENTER) + .addGroup(pagesLayout.createSequentialGroup() + .addGroup(pagesLayout.createParallelGroup(GroupLayout.Alignment.CENTER) + .addComponent(btnSeekBackward) + .addComponent(btnBackward) + .addComponent(btnFirst) + .addComponent(btnCurrentPage) + .addComponent(btnSeekForward) + .addComponent(btnForward))) ); } @@ -116,11 +123,4 @@ private void seekForward() { debugTableModel.seekForwardPage(pageSeekLastValue); } } - - public static PagesPanel create(DebugTableModel debugTableModel, Dialogs dialogs) { - PagesPanel pagesPanel = new PagesPanel(debugTableModel, dialogs); - pagesPanel.initComponents(); - - return pagesPanel; - } } diff --git a/application/src/main/java/net/emustudio/application/gui/debugtable/PaginatingDisassembler.java b/application/src/main/java/net/emustudio/application/gui/debugtable/PaginatingDisassembler.java index e783625f3..71a874dd1 100644 --- a/application/src/main/java/net/emustudio/application/gui/debugtable/PaginatingDisassembler.java +++ b/application/src/main/java/net/emustudio/application/gui/debugtable/PaginatingDisassembler.java @@ -50,16 +50,16 @@ public class PaginatingDisassembler { bytesPerPageCache.put(0, currentPage); } + int getInstructionsPerPage() { + return instructionsPerPage; + } + void setInstructionsPerPage(int value) { instructionsPerPage = value; currentInstrRow = instructionsPerPage / 2; instrPerHalfPage = instructionsPerPage / 2; } - int getInstructionsPerPage() { - return instructionsPerPage; - } - int getCurrentInstructionRow() { return currentInstrRow; } @@ -366,9 +366,9 @@ private int findLocationBelowHalf(int currentLocation, int row, int half, Page t // we do not have enough instructions. This might be caused by the "half" which is not big enough, // or by the fact that we just don't know how much instructions back is known. callFlow.traverseBackForInstructionCount( - realFrom, - INSTR_PER_PAGE - loadedHalfSize + 1, - loc -> halfPage.add(0, loc) + realFrom, + INSTR_PER_PAGE - loadedHalfSize + 1, + loc -> halfPage.add(0, loc) ); loadedHalfSize = halfPage.size(); } @@ -432,12 +432,12 @@ void setLastPage(boolean lastPage) { @Override public String toString() { return "Page{" + - "index=" + index + - ", minLocation=" + minLocation + - ", maxLocation=" + maxLocation + - ", middleLocation=" + middleLocation + - ", lastPage=" + lastPage + - '}'; + "index=" + index + + ", minLocation=" + minLocation + + ", maxLocation=" + maxLocation + + ", middleLocation=" + middleLocation + + ", lastPage=" + lastPage + + '}'; } } } diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/AboutDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/AboutDialog.java index 993a4d25d..da7b21a9c 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/AboutDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/AboutDialog.java @@ -62,17 +62,17 @@ private void initComponents() { GroupLayout panelLogoLayout = new GroupLayout(panelLogo); panelLogo.setLayout(panelLogoLayout); panelLogoLayout.setHorizontalGroup( - panelLogoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelLogoLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblLogo, GroupLayout.DEFAULT_SIZE, 145, Short.MAX_VALUE)) + panelLogoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelLogoLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblLogo, GroupLayout.DEFAULT_SIZE, 145, Short.MAX_VALUE)) ); panelLogoLayout.setVerticalGroup( - panelLogoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelLogoLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblLogo, GroupLayout.DEFAULT_SIZE, 165, Short.MAX_VALUE) - .addContainerGap()) + panelLogoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelLogoLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblLogo, GroupLayout.DEFAULT_SIZE, 165, Short.MAX_VALUE) + .addContainerGap()) ); lblName.setFont(lblName.getFont().deriveFont(lblName.getFont().getStyle() | java.awt.Font.BOLD)); @@ -85,59 +85,59 @@ private void initComponents() { jLabel4.setText("Version"); jLabel1.setText( - "

This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it " + - "under certain conditions; for details see https://www.gnu.org/licenses/gpl-3.0.html.
" + - "For more information about emuStudio, see https://www.emustudio.net/.

"); + "

This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it " + + "under certain conditions; for details see https://www.gnu.org/licenses/gpl-3.0.html.
" + + "For more information about emuStudio, see https://www.emustudio.net/.

"); GroupLayout panelInfoLayout = new GroupLayout(panelInfo); panelInfo.setLayout(panelInfoLayout); panelInfoLayout.setHorizontalGroup( - panelInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelInfoLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblName) + panelInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelInfoLayout.createSequentialGroup() - .addComponent(jLabel4) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblVersion)) - .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, 400, GroupLayout.PREFERRED_SIZE) - .addComponent(lblCopyright)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(panelInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblName) + .addGroup(panelInfoLayout.createSequentialGroup() + .addComponent(jLabel4) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblVersion)) + .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, 400, GroupLayout.PREFERRED_SIZE) + .addComponent(lblCopyright)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); panelInfoLayout.setVerticalGroup( - panelInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelInfoLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblName) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(lblCopyright) - .addGap(18, 18, 18) - .addGroup(panelInfoLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblVersion) - .addComponent(jLabel4)) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel1, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) - .addContainerGap()) + panelInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelInfoLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblName) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(lblCopyright) + .addGap(18, 18, 18) + .addGroup(panelInfoLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblVersion) + .addComponent(jLabel4)) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel1, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) + .addContainerGap()) ); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(panelLogo, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(panelInfo, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(panelLogo, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(panelInfo, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(panelInfo, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) - .addComponent(panelLogo, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(panelInfo, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) + .addComponent(panelLogo, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) ); pack(); diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/AutoDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/AutoDialog.java index 428596c56..e458ac5e4 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/AutoDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/AutoDialog.java @@ -29,7 +29,6 @@ * This is the dialog form that displays when the emuStudio automatization * is running. */ -@SuppressWarnings("serial") public class AutoDialog extends JDialog { private final VirtualComputer computer; @@ -60,23 +59,23 @@ private void initComponents() { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblAction, GroupLayout.PREFERRED_SIZE, 338, GroupLayout.PREFERRED_SIZE) - .addComponent(lblPerforming) - .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(btnStop)) - ).addContainerGap()); + layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblAction, GroupLayout.PREFERRED_SIZE, 338, GroupLayout.PREFERRED_SIZE) + .addComponent(lblPerforming) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(btnStop)) + ).addContainerGap()); layout.setVerticalGroup( - layout.createSequentialGroup() - .addContainerGap() - .addComponent(lblPerforming) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(lblAction) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnStop) - .addContainerGap()); + layout.createSequentialGroup() + .addContainerGap() + .addComponent(lblPerforming) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(lblAction) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnStop) + .addContainerGap()); pack(); } diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/BreakpointDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/BreakpointDialog.java index 5d4eab171..930c7e88a 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/BreakpointDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/BreakpointDialog.java @@ -35,6 +35,7 @@ public class BreakpointDialog extends JDialog { private int address = -1; // if adr == -1 then it means cancel private boolean set = false; + private JTextField txtAddress; public BreakpointDialog(JFrame parent, Dialogs dialogs) { super(parent, true); @@ -76,18 +77,18 @@ private void initComponents() { getContentPane().setLayout(layout); layout.setHorizontalGroup(layout.createSequentialGroup().addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblSetUnset).addComponent(txtAddress) - .addGroup(GroupLayout.Alignment.CENTER, layout.createSequentialGroup() - .addComponent(btnUnset).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnSet))).addContainerGap()); + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblSetUnset).addComponent(txtAddress) + .addGroup(GroupLayout.Alignment.CENTER, layout.createSequentialGroup() + .addComponent(btnUnset).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnSet))).addContainerGap()); layout.setVerticalGroup(layout.createSequentialGroup().addContainerGap().addComponent(lblSetUnset) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtAddress, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, - GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(btnUnset).addComponent(btnSet)).addContainerGap()); + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtAddress, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(btnUnset).addComponent(btnSet)).addContainerGap()); pack(); @@ -117,6 +118,4 @@ private void btnUnsetActionPerformed(java.awt.event.ActionEvent evt) { dispose(); } } - - private JTextField txtAddress; } diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/EditorPanel.java b/application/src/main/java/net/emustudio/application/gui/dialogs/EditorPanel.java index e9dde6411..1f5968cf9 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/EditorPanel.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/EditorPanel.java @@ -76,7 +76,7 @@ public EditorPanel(JFrame parent, Dialogs dialogs, Editor editor, VirtualCompute this.newFileAction = new NewFileAction(this::confirmSave, editor, compilerOutput, updateTitle); this.openFileAction = new OpenFileAction(this::confirmSave, editor, compilerOutput, updateTitle); this.compileAction = new CompileAction( - computer, dialogs, editor, runState, compilerOutput, updateTitle + computer, dialogs, editor, runState, compilerOutput, updateTitle ); JScrollPane compilerPane = new JScrollPane(); @@ -94,22 +94,22 @@ public EditorPanel(JFrame parent, Dialogs dialogs, Editor editor, VirtualCompute GroupLayout panelSourceLayout = new GroupLayout(this); setLayout(panelSourceLayout); panelSourceLayout.setHorizontalGroup( - panelSourceLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(mainToolBar) - .addGroup( - panelSourceLayout - .createSequentialGroup() - .addContainerGap() - .addComponent(splitSource) - .addContainerGap() - ) + panelSourceLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(mainToolBar) + .addGroup( + panelSourceLayout + .createSequentialGroup() + .addContainerGap() + .addComponent(splitSource) + .addContainerGap() + ) ); panelSourceLayout.setVerticalGroup( - panelSourceLayout - .createSequentialGroup() - .addComponent(mainToolBar, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(splitSource, 10, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) - .addContainerGap() + panelSourceLayout + .createSequentialGroup() + .addComponent(mainToolBar, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(splitSource, 10, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) + .addContainerGap() ); } @@ -174,29 +174,29 @@ private JToolBar setupMainToolbar() { mainToolBar.add(new ToolbarButton(saveFileAction, "Save file")); mainToolBar.addSeparator(); mainToolBar.add(new ToolbarButton( - RTextArea.getAction(RTextArea.UNDO_ACTION), - "/net/emustudio/application/gui/dialogs/edit-undo.png", - "Undo" + RTextArea.getAction(RTextArea.UNDO_ACTION), + "/net/emustudio/application/gui/dialogs/edit-undo.png", + "Undo" )); mainToolBar.add(new ToolbarButton(RTextArea.getAction(RTextArea.REDO_ACTION), - "/net/emustudio/application/gui/dialogs/edit-redo.png", - "Redo" + "/net/emustudio/application/gui/dialogs/edit-redo.png", + "Redo" )); mainToolBar.addSeparator(); mainToolBar.add(new ToolbarButton( - RTextArea.getAction(RTextArea.CUT_ACTION), - "/net/emustudio/application/gui/dialogs/edit-cut.png", - "Cut selection" + RTextArea.getAction(RTextArea.CUT_ACTION), + "/net/emustudio/application/gui/dialogs/edit-cut.png", + "Cut selection" )); mainToolBar.add(new ToolbarButton( - RTextArea.getAction(RTextArea.COPY_ACTION), - "/net/emustudio/application/gui/dialogs/edit-copy.png", - "Copy selection" + RTextArea.getAction(RTextArea.COPY_ACTION), + "/net/emustudio/application/gui/dialogs/edit-copy.png", + "Copy selection" )); mainToolBar.add(new ToolbarButton( - RTextArea.getAction(RTextArea.PASTE_ACTION), - "/net/emustudio/application/gui/dialogs/edit-paste.png", - "Paste from clipboard" + RTextArea.getAction(RTextArea.PASTE_ACTION), + "/net/emustudio/application/gui/dialogs/edit-paste.png", + "Paste from clipboard" )); mainToolBar.addSeparator(); mainToolBar.add(new ToolbarButton(findAction, "Find text...")); diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/EmulatorPanel.java b/application/src/main/java/net/emustudio/application/gui/dialogs/EmulatorPanel.java index e9e55e174..773938a9a 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/EmulatorPanel.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/EmulatorPanel.java @@ -97,8 +97,8 @@ public void componentResized(ComponentEvent e) { statusWindow.setLayout(statusWindowLayout); computer.getCPU() - .flatMap(cpu -> Optional.ofNullable(cpu.getStatusPanel())) - .ifPresent(this::setStatusPanel); + .flatMap(cpu -> Optional.ofNullable(cpu.getStatusPanel())) + .ifPresent(this::setStatusPanel); this.stepBackAction = new StepBackAction(computer, debugTableModel, this::refreshDebugTable); this.resetAction = new ResetAction(emulationController); @@ -128,15 +128,15 @@ public void componentResized(ComponentEvent e) { debuggerPanel.setLayout(debuggerPanelLayout); debuggerPanelLayout.setHorizontalGroup( - debuggerPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(toolDebug) - .addComponent(paneDebug) - .addComponent(panelPages)); + debuggerPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(toolDebug) + .addComponent(paneDebug) + .addComponent(panelPages)); debuggerPanelLayout.setVerticalGroup( - debuggerPanelLayout.createSequentialGroup() - .addComponent(toolDebug, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(paneDebug, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(panelPages, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)); + debuggerPanelLayout.createSequentialGroup() + .addComponent(toolDebug, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(paneDebug, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelPages, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)); this.showDeviceSettingsAction = new ShowDeviceSettingsAction(parent, computer, dialogs, lstDevices::getSelectedIndex); this.showDeviceGuiAction = new ShowDeviceGuiAction(parent, computer, dialogs, lstDevices::getSelectedIndex); @@ -181,22 +181,22 @@ public void mouseClicked(MouseEvent e) { GroupLayout peripheralPanelLayout = new GroupLayout(peripheralPanel); peripheralPanel.setLayout(peripheralPanelLayout); peripheralPanelLayout.setHorizontalGroup( - peripheralPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(paneDevices) - .addGroup(GroupLayout.Alignment.TRAILING, - peripheralPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(btnShowSettings) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnShowGUI) - .addContainerGap())); + peripheralPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(paneDevices) + .addGroup(GroupLayout.Alignment.TRAILING, + peripheralPanelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(btnShowSettings) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnShowGUI) + .addContainerGap())); peripheralPanelLayout.setVerticalGroup( - peripheralPanelLayout.createSequentialGroup() - .addComponent(paneDevices) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(peripheralPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(btnShowSettings) - .addComponent(btnShowGUI))); + peripheralPanelLayout.createSequentialGroup() + .addComponent(paneDevices) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(peripheralPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(btnShowSettings) + .addComponent(btnShowGUI))); splitPerDebug.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); splitPerDebug.setDividerLocation(500); @@ -217,13 +217,13 @@ public void mouseClicked(MouseEvent e) { GroupLayout panelEmulatorLayout = new GroupLayout(this); setLayout(panelEmulatorLayout); panelEmulatorLayout.setHorizontalGroup( - panelEmulatorLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(splitLeftRight)); + panelEmulatorLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(splitLeftRight)); panelEmulatorLayout.setVerticalGroup( - panelEmulatorLayout.createSequentialGroup() - .addContainerGap() - .addComponent(splitLeftRight, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) - .addContainerGap()); + panelEmulatorLayout.createSequentialGroup() + .addContainerGap() + .addComponent(splitLeftRight, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) + .addContainerGap()); this.memoryListener = new Memory.MemoryListener() { @Override @@ -284,11 +284,11 @@ public CPU.RunState getRunState() { private void setStatusPanel(JPanel statusPanel) { statusWindowLayout.setHorizontalGroup( - statusWindowLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(statusPanel)); + statusWindowLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(statusPanel)); statusWindowLayout.setVerticalGroup( - statusWindowLayout.createSequentialGroup() - .addComponent(statusPanel)); + statusWindowLayout.createSequentialGroup() + .addComponent(statusPanel)); } private void setupDebugToolbar() { @@ -299,7 +299,7 @@ private void setupDebugToolbar() { toolDebug.add(new ToolbarButton(resetAction, "Reset emulation")); toolDebug.addSeparator(); toolDebug.add(new ToolbarButton(jumpToBeginningAction, "Jump to beginning")); - toolDebug.add(new ToolbarButton(stepBackAction,"Step back")); + toolDebug.add(new ToolbarButton(stepBackAction, "Step back")); toolDebug.add(new ToolbarButton(stopAction, "Stop emulation")); toolDebug.add(new ToolbarButton(pauseAction, "Pause emulation")); toolDebug.add(new ToolbarButton(runAction, "Run emulation")); diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/LoadingDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/LoadingDialog.java index f5e9be6d7..ad3cdda97 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/LoadingDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/LoadingDialog.java @@ -39,7 +39,7 @@ private void initComponents() { lblLoading.setFont(lblLoading.getFont().deriveFont(lblLoading.getFont().getStyle() | java.awt.Font.BOLD)); lblLoading.setIcon(new ImageIcon(getClass() - .getResource("/net/emustudio/application/gui/dialogs/loading.gif"))); + .getResource("/net/emustudio/application/gui/dialogs/loading.gif"))); lblLoading.setText("Loading computer, please wait..."); lblWarning.setText("If you see some errors, please see the log file."); @@ -47,17 +47,17 @@ private void initComponents() { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createSequentialGroup().addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblWarning, GroupLayout.PREFERRED_SIZE, 338, - GroupLayout.PREFERRED_SIZE).addComponent(lblLoading)) - .addContainerGap()); + layout.createSequentialGroup().addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblWarning, GroupLayout.PREFERRED_SIZE, 338, + GroupLayout.PREFERRED_SIZE).addComponent(lblLoading)) + .addContainerGap()); layout.setVerticalGroup( - layout.createSequentialGroup().addContainerGap() - .addComponent(lblLoading).addPreferredGap(LayoutStyle - .ComponentPlacement.UNRELATED).addComponent(lblWarning) - .addContainerGap(lblWarning.getPreferredSize().height, - lblWarning.getPreferredSize().height).addContainerGap()); + layout.createSequentialGroup().addContainerGap() + .addComponent(lblLoading).addPreferredGap(LayoutStyle + .ComponentPlacement.UNRELATED).addComponent(lblWarning) + .addContainerGap(lblWarning.getPreferredSize().height, + lblWarning.getPreferredSize().height).addContainerGap()); pack(); } diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java index 4928c5982..daeb17bf4 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/OpenComputerDialog.java @@ -18,12 +18,12 @@ */ package net.emustudio.application.gui.dialogs; -import net.emustudio.application.settings.AppSettings; -import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.gui.ToolbarButton; import net.emustudio.application.gui.actions.opencomputer.*; import net.emustudio.application.gui.schema.Schema; import net.emustudio.application.gui.schema.SchemaPreviewPanel; +import net.emustudio.application.settings.AppSettings; +import net.emustudio.application.settings.ComputerConfig; import net.emustudio.emulib.runtime.interaction.Dialogs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -136,16 +136,16 @@ public void mouseClicked(MouseEvent evt) { GroupLayout panelConfigLayout = new GroupLayout(panelConfig); panelConfig.setLayout(panelConfigLayout); panelConfigLayout.setHorizontalGroup( - panelConfigLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(toolConfig, GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE) - .addComponent(configScrollPane, GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE) + panelConfigLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(toolConfig, GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE) + .addComponent(configScrollPane, GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE) ); panelConfigLayout.setVerticalGroup( - panelConfigLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelConfigLayout.createSequentialGroup() - .addComponent(toolConfig, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(configScrollPane, GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE)) + panelConfigLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelConfigLayout.createSequentialGroup() + .addComponent(toolConfig, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(configScrollPane, GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE)) ); splitConfig.setLeftComponent(panelConfig); @@ -155,13 +155,13 @@ public void mouseClicked(MouseEvent evt) { GroupLayout panelPreviewLayout = new GroupLayout(panelPreview); panelPreview.setLayout(panelPreviewLayout); panelPreviewLayout.setHorizontalGroup( - panelPreviewLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(scrollPreview, GroupLayout.DEFAULT_SIZE, 586, Short.MAX_VALUE) + panelPreviewLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(scrollPreview, GroupLayout.DEFAULT_SIZE, 586, Short.MAX_VALUE) ); panelPreviewLayout.setVerticalGroup( - panelPreviewLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelPreviewLayout.createSequentialGroup() - .addComponent(scrollPreview, GroupLayout.DEFAULT_SIZE, 308, Short.MAX_VALUE)) + panelPreviewLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelPreviewLayout.createSequentialGroup() + .addComponent(scrollPreview, GroupLayout.DEFAULT_SIZE, 308, Short.MAX_VALUE)) ); splitConfig.setRightComponent(panelPreview); @@ -178,33 +178,33 @@ public void mouseClicked(MouseEvent evt) { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(splitConfig, GroupLayout.DEFAULT_SIZE, 797, Short.MAX_VALUE) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1) - .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(btnClose) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnOpen))) - .addContainerGap()) + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(splitConfig, GroupLayout.DEFAULT_SIZE, 797, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(btnClose) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnOpen))) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(splitConfig, GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(btnOpen) - .addComponent(btnClose)) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(splitConfig, GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(btnOpen) + .addComponent(btnClose)) + .addContainerGap()) ); pack(); @@ -218,11 +218,11 @@ private void lstConfigMouseClicked(MouseEvent evt) { private void lstConfigValueChanged(ListSelectionEvent evt) { Optional - .ofNullable(lstConfig.getSelectedValue()) - .ifPresentOrElse(computer -> { - Schema schema = new Schema(computer, appSettings); - preview.setSchema(schema); - }, () -> preview.setSchema(null)); + .ofNullable(lstConfig.getSelectedValue()) + .ifPresentOrElse(computer -> { + Schema schema = new Schema(computer, appSettings); + preview.setSchema(schema); + }, () -> preview.setSchema(null)); preview.repaint(); } diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/PluginComboModel.java b/application/src/main/java/net/emustudio/application/gui/dialogs/PluginComboModel.java index 9e9d96f84..19499de13 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/PluginComboModel.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/PluginComboModel.java @@ -46,6 +46,11 @@ public final class PluginComboModel implements ComboBoxModel { }); } + @Override + public String getSelectedItem() { + return selectedName; + } + @Override public void setSelectedItem(Object item) { if (item == null) { @@ -58,11 +63,6 @@ public void setSelectedItem(Object item) { } } - @Override - public String getSelectedItem() { - return Optional.ofNullable(selectedName).orElse(null); - } - @Override public int getSize() { return indexesByName.size(); diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/SchemaEditorDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/SchemaEditorDialog.java index a782ef7b0..81c86c693 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/SchemaEditorDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/SchemaEditorDialog.java @@ -41,8 +41,8 @@ import java.util.Objects; import java.util.Optional; -import static net.emustudio.application.settings.ConfigFiles.listPluginFiles; import static net.emustudio.application.gui.GuiUtils.addKeyListenerRecursively; +import static net.emustudio.application.settings.ConfigFiles.listPluginFiles; public class SchemaEditorDialog extends JDialog implements KeyListener { private final static Logger LOGGER = LoggerFactory.getLogger(SchemaEditorDialog.class); @@ -53,6 +53,18 @@ public class SchemaEditorDialog extends JDialog implements KeyListener { private DrawingPanel panel; private boolean buttonSelected = false; + private ToolbarToggleButton btnBidirection; + private ToolbarToggleButton btnCPU; + private ToolbarToggleButton btnCompiler; + private ToolbarToggleButton btnDelete; + private ToolbarToggleButton btnDevice; + private ToolbarToggleButton btnLine; + private ToolbarToggleButton btnRAM; + private ToolbarToggleButton btnUseGrid; + private JComboBox cmbPlugin; + private ButtonGroup groupDraw; + private JScrollPane scrollScheme; + private JSlider sliderGridGap; public SchemaEditorDialog(JDialog parent, Schema schema, Dialogs dialogs) { super(parent, true); @@ -115,61 +127,61 @@ private void initComponents() { groupDraw = new ButtonGroup(); JToolBar toolDraw = new JToolBar(); ToolbarButton btnSave = new ToolbarButton( - this::btnSaveActionPerformed, - "/net/emustudio/application/gui/dialogs/document-save.png", - "Save & Close" + this::btnSaveActionPerformed, + "/net/emustudio/application/gui/dialogs/document-save.png", + "Save & Close" ); JToolBar.Separator separator1 = new JToolBar.Separator(); btnCompiler = new ToolbarToggleButton( - this::btnCompilerActionPerformed, - this::btnCompilerItemStateChanged, - "/net/emustudio/application/gui/dialogs/compile.png", - "Set compiler" + this::btnCompilerActionPerformed, + this::btnCompilerItemStateChanged, + "/net/emustudio/application/gui/dialogs/compile.png", + "Set compiler" ); btnCPU = new ToolbarToggleButton( - this::btnCPUActionPerformed, - this::btnCPUItemStateChanged, - "/net/emustudio/application/gui/dialogs/cpu.gif", - "Set CPU" + this::btnCPUActionPerformed, + this::btnCPUItemStateChanged, + "/net/emustudio/application/gui/dialogs/cpu.gif", + "Set CPU" ); btnRAM = new ToolbarToggleButton( - this::btnRAMActionPerformed, - this::btnRAMItemStateChanged, - "/net/emustudio/application/gui/dialogs/ram.gif", - "Set operating memory" + this::btnRAMActionPerformed, + this::btnRAMItemStateChanged, + "/net/emustudio/application/gui/dialogs/ram.gif", + "Set operating memory" ); btnDevice = new ToolbarToggleButton( - this::btnDeviceActionPerformed, - this::btnDeviceItemStateChanged, - "/net/emustudio/application/gui/dialogs/device.png", - "Add device" + this::btnDeviceActionPerformed, + this::btnDeviceItemStateChanged, + "/net/emustudio/application/gui/dialogs/device.png", + "Add device" ); JToolBar.Separator separator2 = new JToolBar.Separator(); btnLine = new ToolbarToggleButton( - this::btnLineActionPerformed, - this::btnLineItemStateChanged, - "/net/emustudio/application/gui/dialogs/connection.png", - "Add connection" + this::btnLineActionPerformed, + this::btnLineItemStateChanged, + "/net/emustudio/application/gui/dialogs/connection.png", + "Add connection" ); btnBidirection = new ToolbarToggleButton( - this::btnBidirectionActionPerformed, - "/net/emustudio/application/gui/dialogs/bidirection.gif", - "Bidirectional connection" + this::btnBidirectionActionPerformed, + "/net/emustudio/application/gui/dialogs/bidirection.gif", + "Bidirectional connection" ); JToolBar.Separator separator3 = new JToolBar.Separator(); btnDelete = new ToolbarToggleButton( - this::btnDeleteActionPerformed, - this::btnDeleteItemStateChanged, - "/net/emustudio/application/gui/dialogs/edit-delete.png", - "Delete component or connection" + this::btnDeleteActionPerformed, + this::btnDeleteItemStateChanged, + "/net/emustudio/application/gui/dialogs/edit-delete.png", + "Delete component or connection" ); JToolBar.Separator separator4 = new JToolBar.Separator(); cmbPlugin = new JComboBox<>(); JToolBar.Separator separator5 = new JToolBar.Separator(); btnUseGrid = new ToolbarToggleButton( - this::btnUseGridActionPerformed, - "/net/emustudio/application/gui/dialogs/grid_memory.gif", - "Set/unset using grid" + this::btnUseGridActionPerformed, + "/net/emustudio/application/gui/dialogs/grid_memory.gif", + "Set/unset using grid" ); scrollScheme = new JScrollPane(); sliderGridGap = new JSlider(); @@ -222,28 +234,28 @@ private void initComponents() { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(toolDraw, GroupLayout.DEFAULT_SIZE, 641, Short.MAX_VALUE) - .addContainerGap()) - .addGroup(layout.createSequentialGroup() - .addComponent(scrollScheme, GroupLayout.DEFAULT_SIZE, 616, Short.MAX_VALUE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(sliderGridGap, GroupLayout.PREFERRED_SIZE, 31, GroupLayout.PREFERRED_SIZE)))) + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(toolDraw, GroupLayout.DEFAULT_SIZE, 641, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(layout.createSequentialGroup() + .addComponent(scrollScheme, GroupLayout.DEFAULT_SIZE, 616, Short.MAX_VALUE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(sliderGridGap, GroupLayout.PREFERRED_SIZE, 31, GroupLayout.PREFERRED_SIZE)))) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(toolDraw, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(sliderGridGap, GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE) - .addComponent(scrollScheme, GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE)) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(toolDraw, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(sliderGridGap, GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE) + .addComponent(scrollScheme, GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE)) + .addContainerGap()) ); pack(); @@ -268,7 +280,6 @@ private void btnCPUActionPerformed(ActionEvent evt) { } } - private void btnRAMActionPerformed(ActionEvent evt) { if (checkUnsetDrawingTool()) { buttonSelected = true; @@ -374,24 +385,9 @@ private void btnUseGridActionPerformed(ActionEvent evt) { schema.setSchemaGridGap(sliderGridGap.getValue()); } - private void btnBidirectionActionPerformed(ActionEvent evt) { panel.setFutureLineDirection(btnBidirection.isSelected()); } - - private ToolbarToggleButton btnBidirection; - private ToolbarToggleButton btnCPU; - private ToolbarToggleButton btnCompiler; - private ToolbarToggleButton btnDelete; - private ToolbarToggleButton btnDevice; - private ToolbarToggleButton btnLine; - private ToolbarToggleButton btnRAM; - private ToolbarToggleButton btnUseGrid; - private JComboBox cmbPlugin; - private ButtonGroup groupDraw; - private JScrollPane scrollScheme; - private JSlider sliderGridGap; - private void resetComboWithPluginFiles(PLUGIN_TYPE pluginType) { try { diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java b/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java index 4532c10ed..45837abe2 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/StudioFrame.java @@ -18,7 +18,6 @@ */ package net.emustudio.application.gui.dialogs; -import net.emustudio.application.settings.AppSettings; import net.emustudio.application.emulation.EmulationController; import net.emustudio.application.gui.actions.AboutAction; import net.emustudio.application.gui.actions.CompilerSettingsAction; @@ -30,6 +29,7 @@ import net.emustudio.application.gui.debugtable.DebugTableModel; import net.emustudio.application.gui.editor.Editor; import net.emustudio.application.gui.editor.REditor; +import net.emustudio.application.settings.AppSettings; import net.emustudio.application.virtualcomputer.VirtualComputer; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.interaction.Dialogs; @@ -66,18 +66,18 @@ public StudioFrame(VirtualComputer computer, AppSettings appSettings, Dialogs di Objects.requireNonNull(computer); this.editor = computer.getCompiler() - .map(compiler -> new REditor(dialogs, compiler)) - .orElse(new REditor(dialogs)); + .map(compiler -> new REditor(dialogs, compiler)) + .orElse(new REditor(dialogs)); EmulationController emulationController = computer.getCPU().map(cpu -> new EmulationController( - cpu, computer.getMemory().orElse(null), computer.getDevices() + cpu, computer.getMemory().orElse(null), computer.getDevices() )).orElse(null); this.emulatorPanel = new EmulatorPanel( - this, computer, debugTableModel, dialogs, emulationController, memoryContext + this, computer, debugTableModel, dialogs, emulationController, memoryContext ); this.editorPanel = new EditorPanel( - this, dialogs, editor, computer, this::updateTitleOfSourceCodePanel, emulatorPanel::getRunState + this, dialogs, editor, computer, this::updateTitleOfSourceCodePanel, emulatorPanel::getRunState ); this.saveFileAsAction = new SaveFileAsAction(editor, this::updateTitleOfSourceCodePanel); @@ -107,6 +107,12 @@ public void componentResized(ComponentEvent e) { editor.grabFocus(); } + private static JMenuItem createMenuItem(Action action) { + JMenuItem item = new JMenuItem(action); + item.setToolTipText(null); // Swing annoyingly adds tool tip text to the menu item + return item; + } + private void resizeComponents() { int height = getHeight(); editorPanel.resizeComponents(height); @@ -119,8 +125,8 @@ private void initComponents() { setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); getRootPane().registerKeyboardAction( - e -> editor.clearMarkedOccurences(), - KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW + e -> editor.clearMarkedOccurences(), + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW ); addWindowListener(new WindowAdapter() { @@ -140,11 +146,11 @@ public void windowClosing(WindowEvent evt) { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(tabbedPane, GroupLayout.DEFAULT_SIZE, - GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)); + layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(tabbedPane, GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(tabbedPane, GroupLayout.DEFAULT_SIZE, - GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)); + layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(tabbedPane, GroupLayout.DEFAULT_SIZE, + GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)); } private JMenuBar setupMainMenu() { @@ -190,13 +196,6 @@ private JMenuBar setupMainMenu() { return mainMenuBar; } - - private static JMenuItem createMenuItem(Action action) { - JMenuItem item = new JMenuItem(action); - item.setToolTipText(null); // Swing annoyingly adds tool tip text to the menu item - return item; - } - private void formWindowClosing() { editorPanel.dispose(); dispose(); @@ -204,8 +203,8 @@ private void formWindowClosing() { private void updateTitleOfSourceCodePanel() { editor.getCurrentFile().ifPresentOrElse( - file -> tabbedPane.setTitleAt(0, file.getName()), - () -> tabbedPane.setTitleAt(0, SOURCE_CODE_EDITOR) + file -> tabbedPane.setTitleAt(0, file.getName()), + () -> tabbedPane.setTitleAt(0, SOURCE_CODE_EDITOR) ); } } diff --git a/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java b/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java index 309a32d9a..10d284af4 100644 --- a/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java +++ b/application/src/main/java/net/emustudio/application/gui/dialogs/ViewComputerDialog.java @@ -18,10 +18,10 @@ */ package net.emustudio.application.gui.dialogs; -import net.emustudio.application.settings.AppSettings; -import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.schema.Schema; import net.emustudio.application.gui.schema.SchemaPreviewPanel; +import net.emustudio.application.settings.AppSettings; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.virtualcomputer.VirtualComputer; import net.emustudio.emulib.plugins.Plugin; import net.emustudio.emulib.plugins.device.Device; @@ -39,7 +39,18 @@ public class ViewComputerDialog extends JDialog { private final VirtualComputer computer; private final SchemaPreviewPanel panelSchema; - + private JToggleButton btnCompiler; + private JToggleButton btnDevice; + private JToggleButton btnMemory; + private JComboBox cmbDevice; + private JLabel lblComputerName; + private JLabel lblCopyright; + private JLabel lblFileName; + private JLabel lblName; + private JLabel lblSelectDevice; + private JLabel lblVersion; + private JScrollPane scrollPane; + private JTextArea txtDescription; public ViewComputerDialog(JFrame parent, VirtualComputer computer, AppSettings appSettings, Dialogs dialogs) { super(parent, true); this.computer = Objects.requireNonNull(computer); @@ -88,7 +99,7 @@ public ViewComputerDialog(JFrame parent, VirtualComputer computer, AppSettings a lblSelectDevice.setVisible(false); cmbDevice.setVisible(false); computer.getComputerConfig().getCPU().ifPresent( - conf -> computer.getCPU().ifPresent(cpu -> setInfo(cpu, conf)) + conf -> computer.getCPU().ifPresent(cpu -> setInfo(cpu, conf)) ); } @@ -199,79 +210,79 @@ private void initComponents() { GroupLayout panelDescriptionLayout = new GroupLayout(panelDescription); panelDescription.setLayout(panelDescriptionLayout); panelDescriptionLayout.setHorizontalGroup( - panelDescriptionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelDescriptionLayout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1) - .addContainerGap()) + panelDescriptionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDescriptionLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1) + .addContainerGap()) ); panelDescriptionLayout.setVerticalGroup( - panelDescriptionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelDescriptionLayout.createSequentialGroup() - .addComponent(jScrollPane1) - .addContainerGap()) + panelDescriptionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDescriptionLayout.createSequentialGroup() + .addComponent(jScrollPane1) + .addContainerGap()) ); GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(panelDescription, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(lblSelectDevice) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cmbDevice, 0, 377, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(panelDescription, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(lblSelectDevice) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cmbDevice, 0, 377, Short.MAX_VALUE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblName) + .addComponent(lblVersion) + .addComponent(lblCopyright) + .addComponent(lblFileName)) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblSelectDevice) + .addComponent(cmbDevice, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) .addComponent(lblName) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblFileName) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(lblVersion) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblCopyright) - .addComponent(lblFileName)) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) - ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblSelectDevice) - .addComponent(cmbDevice, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addGap(18, 18, 18) - .addComponent(lblName) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblFileName) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(lblVersion) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblCopyright) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(panelDescription, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(panelDescription, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) ); GroupLayout panelTabInfoLayout = new GroupLayout(panelTabInfo); panelTabInfo.setLayout(panelTabInfoLayout); panelTabInfoLayout.setHorizontalGroup( - panelTabInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelTabInfoLayout.createSequentialGroup() - .addContainerGap() - .addComponent(jToolBar1, GroupLayout.PREFERRED_SIZE, 43, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) + panelTabInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelTabInfoLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jToolBar1, GroupLayout.PREFERRED_SIZE, 43, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) ); panelTabInfoLayout.setVerticalGroup( - panelTabInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelTabInfoLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelTabInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jToolBar1, GroupLayout.DEFAULT_SIZE, 280, Short.MAX_VALUE) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + panelTabInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelTabInfoLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelTabInfoLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jToolBar1, GroupLayout.DEFAULT_SIZE, 280, Short.MAX_VALUE) + .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); jTabbedPane1.addTab("Computer info", panelTabInfo); @@ -291,22 +302,22 @@ private void initComponents() { GroupLayout jPanel1Layout = new GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jToolBar2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 505, Short.MAX_VALUE) - .addContainerGap()) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jToolBar2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 505, Short.MAX_VALUE) + .addContainerGap()) ); jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(scrollPane) - .addComponent(jToolBar2, GroupLayout.DEFAULT_SIZE, 280, Short.MAX_VALUE)) - .addContainerGap()) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(scrollPane) + .addComponent(jToolBar2, GroupLayout.DEFAULT_SIZE, 280, Short.MAX_VALUE)) + .addContainerGap()) ); jTabbedPane1.addTab("Abstract schema", jPanel1); @@ -314,22 +325,22 @@ private void initComponents() { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jTabbedPane1) - .addComponent(lblComputerName, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jTabbedPane1) + .addComponent(lblComputerName, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(6, 6, 6) - .addComponent(lblComputerName) - .addGap(18, 18, 18) - .addComponent(jTabbedPane1) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(6, 6, 6) + .addComponent(lblComputerName) + .addGap(18, 18, 18) + .addComponent(jTabbedPane1) + .addContainerGap()) ); pack(); @@ -339,7 +350,7 @@ private void btnCompilerActionPerformed(java.awt.event.ActionEvent evt) { lblSelectDevice.setVisible(false); cmbDevice.setVisible(false); computer.getComputerConfig().getCompiler().ifPresent( - conf -> computer.getCompiler().ifPresent(compiler -> setInfo(compiler, conf)) + conf -> computer.getCompiler().ifPresent(compiler -> setInfo(compiler, conf)) ); } @@ -347,7 +358,7 @@ private void btnCPUActionPerformed(java.awt.event.ActionEvent evt) { lblSelectDevice.setVisible(false); cmbDevice.setVisible(false); computer.getComputerConfig().getCPU().ifPresent( - conf -> computer.getCPU().ifPresent(cpu -> setInfo(cpu, conf)) + conf -> computer.getCPU().ifPresent(cpu -> setInfo(cpu, conf)) ); } @@ -355,7 +366,7 @@ private void btnMemoryActionPerformed(java.awt.event.ActionEvent evt) { lblSelectDevice.setVisible(false); cmbDevice.setVisible(false); computer.getComputerConfig().getMemory().ifPresent( - conf -> computer.getMemory().ifPresent(memory -> setInfo(memory, conf)) + conf -> computer.getMemory().ifPresent(memory -> setInfo(memory, conf)) ); } @@ -377,17 +388,4 @@ private void btnDeviceActionPerformed(java.awt.event.ActionEvent evt) { private void btnSaveSchemaActionPerformed(java.awt.event.ActionEvent evt) { panelSchema.saveSchemaImage(); } - - private JToggleButton btnCompiler; - private JToggleButton btnDevice; - private JToggleButton btnMemory; - private JComboBox cmbDevice; - private JLabel lblComputerName; - private JLabel lblCopyright; - private JLabel lblFileName; - private JLabel lblName; - private JLabel lblSelectDevice; - private JLabel lblVersion; - private JScrollPane scrollPane; - private JTextArea txtDescription; } diff --git a/application/src/main/java/net/emustudio/application/gui/editor/Editor.java b/application/src/main/java/net/emustudio/application/gui/editor/Editor.java index be06c3fab..813f1634a 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/Editor.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/Editor.java @@ -20,7 +20,6 @@ import org.fife.rsta.ui.search.SearchListener; -import javax.swing.*; import java.awt.*; import java.io.File; import java.nio.file.Path; @@ -54,7 +53,8 @@ public interface Editor extends SearchListener { /** * Set caret position. - * @param line line (if -1 does nothing) + * + * @param line line (if -1 does nothing) * @param column column (if -1 only sets the line) */ void setPosition(int line, int column); diff --git a/application/src/main/java/net/emustudio/application/gui/editor/REditor.java b/application/src/main/java/net/emustudio/application/gui/editor/REditor.java index 11407445a..a5ad0abc5 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/REditor.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/REditor.java @@ -185,13 +185,13 @@ public Optional getCurrentFile() { @Override public boolean saveFileAs() { List filters = sourceFileExtensions.stream() - .map(FileExtensionsFilter::new).collect(Collectors.toList()); + .map(FileExtensionsFilter::new).collect(Collectors.toList()); File currentDirectory = Optional - .ofNullable(textPane.getFileFullPath()) - .filter(p -> !isnew) - .map(File::new) - .orElse(new File(System.getProperty("user.dir"))); + .ofNullable(textPane.getFileFullPath()) + .filter(p -> !isnew) + .map(File::new) + .orElse(new File(System.getProperty("user.dir"))); Optional savedPath = dialogs.chooseFile("Save file", "Save", currentDirectory.toPath(), true, filters); if (savedPath.isPresent()) { @@ -211,19 +211,19 @@ public boolean saveFileAs() { public boolean openFile() { List filters = new ArrayList<>(); List sourceExtensions = sourceFileExtensions.stream() - .map(SourceFileExtension::getExtension).collect(Collectors.toList()); + .map(SourceFileExtension::getExtension).collect(Collectors.toList()); if (sourceExtensions.size() > 0) { filters.add(new FileExtensionsFilter("All source files", sourceExtensions)); } File currentDirectory = Optional - .ofNullable(textPane.getFileFullPath()) - .filter(p -> !isnew) - .map(File::new) - .orElse(new File(System.getProperty("user.dir"))); + .ofNullable(textPane.getFileFullPath()) + .filter(p -> !isnew) + .map(File::new) + .orElse(new File(System.getProperty("user.dir"))); Optional openedFile = dialogs.chooseFile( - "Open a file", "Open", currentDirectory.toPath(), false, filters + "Open a file", "Open", currentDirectory.toPath(), false, filters ); return openedFile.map(this::openFile).orElse(false); } diff --git a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java index ed92d3087..050e88831 100644 --- a/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java +++ b/application/src/main/java/net/emustudio/application/gui/editor/RTokenMaker.java @@ -34,6 +34,34 @@ public RTokenMaker(Compiler compiler) { this.compiler = Objects.requireNonNull(compiler); } + private static int getTokenMakerType(int emuStudioTokenType) { + switch (emuStudioTokenType) { + case net.emustudio.emulib.plugins.compiler.Token.RESERVED: + return Token.RESERVED_WORD; + case net.emustudio.emulib.plugins.compiler.Token.PREPROCESSOR: + return Token.PREPROCESSOR; + case net.emustudio.emulib.plugins.compiler.Token.REGISTER: + return Token.RESERVED_WORD_2; + case net.emustudio.emulib.plugins.compiler.Token.SEPARATOR: + return Token.SEPARATOR; + case net.emustudio.emulib.plugins.compiler.Token.OPERATOR: + return Token.OPERATOR; + case net.emustudio.emulib.plugins.compiler.Token.COMMENT: + return Token.COMMENT_MARKUP; + case net.emustudio.emulib.plugins.compiler.Token.LITERAL: + return Token.LITERAL_NUMBER_DECIMAL_INT; + case net.emustudio.emulib.plugins.compiler.Token.IDENTIFIER: + return Token.IDENTIFIER; + case net.emustudio.emulib.plugins.compiler.Token.LABEL: + return Token.ANNOTATION; + case net.emustudio.emulib.plugins.compiler.Token.ERROR: + return Token.ERROR_IDENTIFIER; + case net.emustudio.emulib.plugins.compiler.Token.EOF: + return Token.NULL; + } + return Token.WHITESPACE; + } + @Override public Token getTokenList(Segment text, int initialTokenType, int startOffset) { resetTokenList(); @@ -61,7 +89,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { } else if (previousEnd != -1 && start != (previousEnd + 1)) { // we have a gap in the middle! Let's treat this gap as ERROR addToken( - text, previousEnd + 1, start - 1, Token.ERROR_CHAR, previousStartOffset + 1 + text, previousEnd + 1, start - 1, Token.ERROR_CHAR, previousStartOffset + 1 ); } previousEnd = end; @@ -80,32 +108,4 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { public TokenMap getWordsToHighlight() { return new TokenMap(); } - - private static int getTokenMakerType(int emuStudioTokenType) { - switch (emuStudioTokenType) { - case net.emustudio.emulib.plugins.compiler.Token.RESERVED: - return Token.RESERVED_WORD; - case net.emustudio.emulib.plugins.compiler.Token.PREPROCESSOR: - return Token.PREPROCESSOR; - case net.emustudio.emulib.plugins.compiler.Token.REGISTER: - return Token.RESERVED_WORD_2; - case net.emustudio.emulib.plugins.compiler.Token.SEPARATOR: - return Token.SEPARATOR; - case net.emustudio.emulib.plugins.compiler.Token.OPERATOR: - return Token.OPERATOR; - case net.emustudio.emulib.plugins.compiler.Token.COMMENT: - return Token.COMMENT_MARKUP; - case net.emustudio.emulib.plugins.compiler.Token.LITERAL: - return Token.LITERAL_NUMBER_DECIMAL_INT; - case net.emustudio.emulib.plugins.compiler.Token.IDENTIFIER: - return Token.IDENTIFIER; - case net.emustudio.emulib.plugins.compiler.Token.LABEL: - return Token.ANNOTATION; - case net.emustudio.emulib.plugins.compiler.Token.ERROR: - return Token.ERROR_IDENTIFIER; - case net.emustudio.emulib.plugins.compiler.Token.EOF: - return Token.NULL; - } - return Token.WHITESPACE; - } } diff --git a/application/src/main/java/net/emustudio/application/gui/schema/DrawingModel.java b/application/src/main/java/net/emustudio/application/gui/schema/DrawingModel.java index ee912cc06..53f180347 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/DrawingModel.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/DrawingModel.java @@ -28,6 +28,11 @@ public class DrawingModel { + /** + * Temporary points used in the process of connection line drawing. If the line is drawn, these points are saved, + * they are cleared otherwise. + */ + public final List

tmpPoints = new ArrayList<>(); /** * Holds a point of a connection line. *

@@ -37,9 +42,7 @@ public class DrawingModel { * mouse is released, while drawing a line */ public P selectedPoint; - public DrawingPanel.Tool drawTool = DrawingPanel.Tool.TOOL_NOTHING; - /** * This variable is used when "moving" mode is active and user moves an element. It holds the moving element object. *

@@ -48,28 +51,18 @@ public class DrawingModel { * released. */ public Element tmpElem1; - /** * Used when drawing lines. It represents last element that the line is connected to. */ public Element tmpElem2; - /** * Point where the selection starts. It is set when the "selection" mode is activated. */ public Point selectionStart; - /** * Point where the selection ends. It is set when the "selection" mode is active and mouse released. */ public Point selectionEnd; - - /** - * Temporary points used in the process of connection line drawing. If the line is drawn, these points are saved, - * they are cleared otherwise. - */ - public final List

tmpPoints = new ArrayList<>(); - /** * Selected line. Used only in "moving" mode. *

diff --git a/application/src/main/java/net/emustudio/application/gui/schema/DrawingPanel.java b/application/src/main/java/net/emustudio/application/gui/schema/DrawingPanel.java index 80f2d0424..db8186f6e 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/DrawingPanel.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/DrawingPanel.java @@ -52,45 +52,26 @@ public class DrawingPanel extends JPanel implements MouseListener, MouseMotionListener { private final static float[] DASH = {10.0f}; - private final static float[] DOT = {1.0f}; - public final static BasicStroke DASHED_LINE = new BasicStroke( - 1.0f, - BasicStroke.CAP_BUTT, - BasicStroke.JOIN_MITER, - 10.0f, - DASH, - 0.0f); + 1.0f, + BasicStroke.CAP_BUTT, + BasicStroke.JOIN_MITER, + 10.0f, + DASH, + 0.0f); + private final static float[] DOT = {1.0f}; private final static BasicStroke DOTTED_LINE = new BasicStroke( - 1.0f, - BasicStroke.CAP_BUTT, - BasicStroke.JOIN_MITER, - 1.0f, - DOT, - 0.0f); - - public enum Tool { - TOOL_COMPILER, - TOOL_CPU, - TOOL_MEMORY, - TOOL_DEVICE, - TOOL_CONNECTION, - TOOL_DELETE, - TOOL_NOTHING - } - + 1.0f, + BasicStroke.CAP_BUTT, + BasicStroke.JOIN_MITER, + 1.0f, + DOT, + 0.0f); private final Color gridColor = new Color(0xDDDDDD); private final List toolListeners = new ArrayList<>(); - private final ModeSelector mode; private final DrawingModel drawingModel = new DrawingModel(); private final Schema schema; - - public interface ToolListener { - - void toolWasUsed(); - } - public DrawingPanel(Schema schema) { this.schema = Objects.requireNonNull(schema); @@ -254,4 +235,19 @@ private void correctPanelSize() { this.revalidate(); } } + + public enum Tool { + TOOL_COMPILER, + TOOL_CPU, + TOOL_MEMORY, + TOOL_DEVICE, + TOOL_CONNECTION, + TOOL_DELETE, + TOOL_NOTHING + } + + public interface ToolListener { + + void toolWasUsed(); + } } diff --git a/application/src/main/java/net/emustudio/application/gui/schema/Schema.java b/application/src/main/java/net/emustudio/application/gui/schema/Schema.java index f7193fd6b..2c06dde4d 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/Schema.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/Schema.java @@ -18,12 +18,12 @@ */ package net.emustudio.application.gui.schema; +import net.emustudio.application.gui.P; +import net.emustudio.application.gui.schema.elements.*; import net.emustudio.application.settings.AppSettings; import net.emustudio.application.settings.ComputerConfig; import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.settings.PluginConnection; -import net.emustudio.application.gui.P; -import net.emustudio.application.gui.schema.elements.*; import java.awt.*; import java.util.List; @@ -33,14 +33,13 @@ public class Schema { public final static int MIN_LEFT_MARGIN = 5; public final static int MIN_TOP_MARGIN = 5; - - private CompilerElement compilerElement; - private CpuElement cpuElement; - private MemoryElement memoryElement; private final List deviceElements = new ArrayList<>(); private final List lines = new ArrayList<>(); private final ComputerConfig config; private final AppSettings appSettings; + private CompilerElement compilerElement; + private CpuElement cpuElement; + private MemoryElement memoryElement; public Schema(ComputerConfig config, AppSettings appSettings) throws NumberFormatException { this.config = Objects.requireNonNull(config); @@ -49,6 +48,17 @@ public Schema(ComputerConfig config, AppSettings appSettings) throws NumberForma load(); } + /** + * Determine if point fits to margins. + * + * @param x new X location + * @param y new Y location + * @return true if the line point can be moved, false otherwise + */ + private static boolean doesNotFitToMargins(int x, int y) { + return (x < MIN_LEFT_MARGIN) || (y < MIN_TOP_MARGIN); + } + public ComputerConfig getComputerConfig() { return config; } @@ -152,7 +162,7 @@ public Element getCrossingElement(Point p) { int eY = elem.getY() - elem.getHeight() / 2; if ((eX <= p.getX()) && (eX + elem.getWidth() >= p.x) - && (eY <= p.getY()) && (eY + elem.getHeight() >= p.y)) { + && (eY <= p.getY()) && (eY + elem.getHeight() >= p.y)) { return elem; } } @@ -171,7 +181,7 @@ public Element getElementByBorderPoint(Point borderPoint) { List allElements = getAllElements(); for (Element element : allElements) { if (element.crossesBottomBorder(borderPoint) || (element.crossesLeftBorder(borderPoint)) - || element.crossesRightBorder(borderPoint) || element.crossesTopBorder(borderPoint)) { + || element.crossesRightBorder(borderPoint) || element.crossesTopBorder(borderPoint)) { return element; } } @@ -257,15 +267,15 @@ public void moveSelection(int diffX, int diffY) { // actual movement allElements.stream() - .filter(Element::isSelected) - .forEach(element -> { - P movedPoint = searchGridPoint(element.getX() + diffX, element.getY() + diffY); - element.move(movedPoint); - }); + .filter(Element::isSelected) + .forEach(element -> { + P movedPoint = searchGridPoint(element.getX() + diffX, element.getY() + diffY); + element.move(movedPoint); + }); lines.stream() - .filter(ConnectionLine::isSelected) - .forEach(line -> line.moveAllPoints(diffX, diffY, this::searchGridPoint)); + .filter(ConnectionLine::isSelected) + .forEach(line -> line.moveAllPoints(diffX, diffY, this::searchGridPoint)); } public void moveElement(Element element, Point newLocation) { @@ -317,32 +327,31 @@ private boolean isElementNotMovable(Element element, int newX, int newY) { // test left line if (ConnectionLine.isAreaCrossing(new Point(elem.getX() - elemW, elem.getY() - elemH), - new Point(elem.getX() - elemW, elem.getY() + elemH), elementStart, elementEnd)) { + new Point(elem.getX() - elemW, elem.getY() + elemH), elementStart, elementEnd)) { return true; } // test right line if (ConnectionLine.isAreaCrossing(new Point(elem.getX() + elemW, elem.getY() - elemH), - new Point(elem.getX() + elemW, elem.getY() + elemH), elementStart, elementEnd)) { + new Point(elem.getX() + elemW, elem.getY() + elemH), elementStart, elementEnd)) { return true; } // test top line if (ConnectionLine.isAreaCrossing(new Point(elem.getX() - elemW, elem.getY() - elemH), - new Point(elem.getX() + elemW, elem.getY() - elemH), elementStart, elementEnd)) { + new Point(elem.getX() + elemW, elem.getY() - elemH), elementStart, elementEnd)) { return true; } // test bottom line if (ConnectionLine.isAreaCrossing(new Point(elem.getX() - elemW, elem.getY() + elemH), - new Point(elem.getX() + elemW, elem.getY() + elemH), elementStart, elementEnd)) { + new Point(elem.getX() + elemW, elem.getY() + elemH), elementStart, elementEnd)) { return true; } } return false; } - private boolean isPointNotMovable(P newLocation) { return isPointNotMovable(newLocation.ix(), newLocation.iy()); } @@ -377,36 +386,25 @@ private boolean allPointMovable(List

points, int diffX, int diffY) { public void save() { List connections = lines.stream() - .map(ConnectionLine::toPluginConnection) - .collect(Collectors.toList()); + .map(ConnectionLine::toPluginConnection) + .collect(Collectors.toList()); config.setConnections(connections); Optional.ofNullable(compilerElement).ifPresentOrElse( - c -> config.setCompiler(c.save()), () -> config.setCompiler(null) + c -> config.setCompiler(c.save()), () -> config.setCompiler(null) ); Optional.ofNullable(cpuElement).ifPresentOrElse( - c -> config.setCPU(c.save()), () -> config.setCPU(null) + c -> config.setCPU(c.save()), () -> config.setCPU(null) ); Optional.ofNullable(memoryElement).ifPresentOrElse( - c -> config.setMemory(c.save()), () -> config.setMemory(null) + c -> config.setMemory(c.save()), () -> config.setMemory(null) ); List devices = deviceElements.stream().map(Element::save).collect(Collectors.toList()); config.setDevices(devices); } - /** - * Determine if point fits to margins. - * - * @param x new X location - * @param y new Y location - * @return true if the line point can be moved, false otherwise - */ - private static boolean doesNotFitToMargins(int x, int y) { - return (x < MIN_LEFT_MARGIN) || (y < MIN_TOP_MARGIN); - } - /** * Remove lines that is connected to specific element. * diff --git a/application/src/main/java/net/emustudio/application/gui/schema/SchemaPreviewPanel.java b/application/src/main/java/net/emustudio/application/gui/schema/SchemaPreviewPanel.java index d6d73c94a..f1edbbf5b 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/SchemaPreviewPanel.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/SchemaPreviewPanel.java @@ -102,14 +102,14 @@ public void paintComponent(Graphics g) { public void saveSchemaImage() { if (schema != null && panelResized) { Path currentDirectory = Optional - .ofNullable(lastImageFile) - .map(File::getParentFile) - .map(File::toPath) - .orElse(Path.of(System.getProperty("user.dir"))); + .ofNullable(lastImageFile) + .map(File::getParentFile) + .map(File::toPath) + .orElse(Path.of(System.getProperty("user.dir"))); dialogs.chooseFile( - "Save schema image", "Save", currentDirectory, true, - new FileExtensionsFilter("PNG image", "png") + "Save schema image", "Save", currentDirectory, true, + new FileExtensionsFilter("PNG image", "png") ).ifPresent(path -> { lastImageFile = path.toFile(); @@ -120,9 +120,9 @@ public void saveSchemaImage() { graphics.setBackground(Color.WHITE); graphics.fillRect(0, 0, schemaWidth, schemaHeight); RenderingHints hints = new RenderingHints(Map.of( - RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON, - RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY, - RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON + RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON, + RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY, + RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON )); graphics.setRenderingHints(hints); @@ -167,8 +167,8 @@ private void resizePanel(Graphics graphics) { topFactor = schemaRectangle.y - Schema.MIN_TOP_MARGIN; if (schemaRectangle.width != 0 && schemaRectangle.height != 0) { this.setSize( - schemaRectangle.width - leftFactor + Schema.MIN_LEFT_MARGIN, - schemaRectangle.height - topFactor + Schema.MIN_TOP_MARGIN + schemaRectangle.width - leftFactor + Schema.MIN_LEFT_MARGIN, + schemaRectangle.height - topFactor + Schema.MIN_TOP_MARGIN ); this.revalidate(); } diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/CompilerElement.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/CompilerElement.java index 1df725ff0..dcb007563 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/CompilerElement.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/CompilerElement.java @@ -19,8 +19,8 @@ package net.emustudio.application.gui.schema.elements; import com.electronwill.nightconfig.core.Config; -import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.P; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; import java.awt.*; @@ -37,15 +37,15 @@ public class CompilerElement extends Element { public CompilerElement(P schemaPoint, String pluginName, String pluginFileName) { super( - BACK_COLOR, schemaPoint, UUID.randomUUID().toString(), PLUGIN_TYPE.COMPILER, pluginName, pluginFileName, - Config.inMemory() + BACK_COLOR, schemaPoint, UUID.randomUUID().toString(), PLUGIN_TYPE.COMPILER, pluginName, pluginFileName, + Config.inMemory() ); } public CompilerElement(PluginConfig config, Function searchGridPoint) { super( - BACK_COLOR, searchGridPoint.apply(P.of(config.getSchemaPoint())), config.getPluginId(), PLUGIN_TYPE.COMPILER, - config.getPluginName(), config.getPluginFile(), config.getPluginSettings() + BACK_COLOR, searchGridPoint.apply(P.of(config.getSchemaPoint())), config.getPluginId(), PLUGIN_TYPE.COMPILER, + config.getPluginName(), config.getPluginFile(), config.getPluginSettings() ); } } diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/ConnectionLine.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/ConnectionLine.java index 2e67a0815..9b238f396 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/ConnectionLine.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/ConnectionLine.java @@ -18,10 +18,10 @@ */ package net.emustudio.application.gui.schema.elements; -import net.emustudio.application.settings.PluginConnection; -import net.emustudio.application.settings.SchemaPoint; import net.emustudio.application.gui.P; import net.emustudio.application.gui.schema.Schema; +import net.emustudio.application.settings.PluginConnection; +import net.emustudio.application.settings.SchemaPoint; import java.awt.*; import java.awt.geom.Point2D; @@ -43,30 +43,26 @@ public class ConnectionLine { private final static BasicStroke thickLine = new BasicStroke(2); private final Color lineColor = new Color(0x333333); - - private Element elementFrom; - private Element elementTo; private final List

points; private final boolean bidirectional; - + private final int[] xx1 = new int[4]; + private final int[] yy1 = new int[4]; + private final int[] xx2 = new int[4]; + private final int[] yy2 = new int[4]; + private Element elementFrom; + private Element elementTo; /** * Starting arrow point for elementFrom. The x and y values are relative to the element middle-point. */ private P arrow1; private P arrow1LeftEnd; private P arrow1RightEnd; - private final int[] xx1 = new int[4]; - private final int[] yy1 = new int[4]; - /** * Starting arrow point for elementTo. The x and y values are relative to the element middle-point. */ private P arrow2; private P arrow2LeftEnd; private P arrow2RightEnd; - private final int[] xx2 = new int[4]; - private final int[] yy2 = new int[4]; - private boolean selected = false; @@ -94,6 +90,201 @@ private static P intersection(P l1s, P l1e, P l2s, P l2e) { return P.of(p_x, p_y); } + /** + * Determine if given point crosses given area. + * + * @param selectionStart Left-top point of the area + * @param selectionEnd Bottom-right point of the area + * @param point The point + * @return true if the area covers the point, false otherwise + */ + public static boolean isAreaCrossingPoint(Point selectionStart, Point selectionEnd, Point point) { + return P.of(point).isInRectangle(selectionStart, selectionEnd); + } + + private static double dot(P v0, P v1) { + return (v0.x * v1.x) + (v0.y * v1.y); + } + + private static boolean inTriangle(P point, P pa, P pb, P pc) { + // Compute vectors + P v0 = pc.minus(pa); + P v1 = pb.minus(pa); + P v2 = point.minus(pa); + + // Compute dot products + double dot00 = dot(v0, v0); + double dot01 = dot(v0, v1); + double dot02 = dot(v0, v2); + double dot11 = dot(v1, v1); + double dot12 = dot(v1, v2); + + // Compute barycentric coordinates + double invDenom = 1 / (dot00 * dot11 - dot01 * dot01); + double u = (dot11 * dot02 - dot01 * dot12) * invDenom; + double v = (dot00 * dot12 - dot01 * dot02) * invDenom; + + // Check if point is in triangle + return (u >= 0) && (v >= 0) && (u + v < 1); + } + + /** + * Determine whether a line segment P1P2 crosses a triangle ABC. + * + * @param lineStart start point of the line segment + * @param lineEnd end point of the line segment + * @param pa first point of the triangle + * @param pb second point of the triangle + * @param pc third point of the triangle + * @return true if the line segment crosses the triangle; false otherwise + */ + private static boolean inTriangle(P lineStart, P lineEnd, P pa, P pb, P pc) { + double a = lineEnd.y - lineStart.y; + double b = lineStart.x - lineEnd.x; + double c = -a * lineStart.x - b * lineStart.y; // general line equation + + double result = a * pa.x + b * pa.y + c; + int sign = Integer.signum((int) result); + + result = a * pb.x + b * pb.y + c; + boolean is = isCrossing(sign, result); + if (!is) { + result = a * pc.x + b * pc.y + c; + is = isCrossing(sign, result); + } + + if (is) { + // now we know that line is crossing the triangle. + // we must check if the line segment crosses the triangle + + // A point is always left-top, B is always right, C is always under A + return (Math.min(lineStart.y, lineEnd.y) <= pc.y) && (Math.max(lineStart.y, lineEnd.y) >= pa.y) + && (Math.min(lineStart.x, lineEnd.x) <= pb.x) && (Math.max(lineStart.x, lineEnd.x) >= pa.x); + } else { + // last check if the line segment lies inside the triangle and does not cross it + return inTriangle(lineStart, pa, pb, pc) && inTriangle(lineEnd, pa, pb, pc); + } + + } + + private static boolean isCrossing(int sign, double result) { + if ((result > 0) && (sign != 1)) { + return true; + } else if ((result == 0) && (sign != 0)) { + return true; + } else return (result < 0) && (sign != -1); + } + + private static boolean checkValidIntersection(P v0, P v1, P v2, P v3, P lineStart, P lineEnd, P intersection) { + if (intersection != null) { + if ((intersection.x < v0.x) || (intersection.x > v2.x) + || (intersection.y < v0.y) || (intersection.y > v2.y)) { + intersection = null; + } else if (intersection.x < Math.min(lineStart.x, lineEnd.x) + || (intersection.x > Math.max(lineStart.x, lineEnd.x)) + || (intersection.y < Math.min(lineStart.y, lineEnd.y)) + || (intersection.y > Math.max(lineStart.y, lineEnd.y))) { + intersection = null; + } + } + if (intersection == null) { + // possible crossing (or overlay) can be on triangle (v0, v2, v3) + if (inTriangle(lineStart, lineEnd, v0, v2, v3)) { + return true; + } + // possible crossing (or overlay) can be on triangle (v0, v1, v2) + return inTriangle(lineStart, lineEnd, v0, v1, v2); + } else { + return true; + } + } + + /** + * Determines whether a selection area crosses or overlays a line segment. + *

+ * If at least one intersection is found, then true is returned. + * + * @param lineStart Start point of the line segment + * @param lineEnd End point of the line segment + * @param selectionStart the selection start point + * @param selectionEnd the selection end point + * @return true if the line segment is crossing the selection area; false otherwise + */ + public static boolean isAreaCrossing(Point lineStart, Point lineEnd, Point selectionStart, Point selectionEnd) { + P v1 = P.of(selectionEnd.x, selectionStart.y); + P v3 = P.of(selectionStart.x, selectionEnd.y); + + P pselectionStart = P.of(selectionStart); + P pselectionEnd = P.of(selectionEnd); + P plineEnd = P.of(lineEnd); + P plineStart = P.of(lineStart); + + P intersection = intersection(pselectionStart, pselectionEnd, plineStart, plineEnd); + return checkValidIntersection(pselectionStart, v1, pselectionEnd, v3, plineStart, plineEnd, intersection); + } + + /** + * This method draws a "sketch" line - in the process when user tries + * to draw a connection line. It is based on fixed first element ee1, where + * the line begins, and it continues through the points defined in the + * ppoints list. The last point is defined by the point ee2. + * + * @param g graphics object, where to draw the sketch line. + * @param ee1 first element + * @param ee2 last point + * @param ppoints list of middle-points + */ + public static void drawSketch(Graphics2D g, Element ee1, Point ee2, List

ppoints) { + Stroke ss = g.getStroke(); + g.setStroke(thickLine); + g.setColor(Color.GRAY); + int x1 = ee1.getX(); + int y1 = ee1.getY(); + int x2, y2; + + for (P p : ppoints) { + x2 = p.ix(); + y2 = p.iy(); + + if (x2 < Schema.MIN_LEFT_MARGIN) { + x2 = Schema.MIN_LEFT_MARGIN; + } + if (y2 < Schema.MIN_TOP_MARGIN) { + y2 = Schema.MIN_TOP_MARGIN; + } + + g.drawLine(x1, y1, x2, y2); + g.fillOval(x2 - 3, y2 - 3, 6, 6); + x1 = x2; + y1 = y2; + } + if (ee2 != null) { + x2 = (int) ee2.getX(); + y2 = (int) ee2.getY(); + g.drawLine(x1, y1, x2, y2); + } + g.setStroke(ss); + } + + /** + * Draws a small red circle around given point + * + * @param point the center of the circle + * @param g Graphics2D object + */ + public static void highlightPoint(P point, Graphics2D g) { + int xx = point.ix(); + int yy = point.iy(); + g.setColor(Color.WHITE); + g.setStroke(thickLine); + g.fillOval(xx - SELECTION_TOLERANCE - 2, yy - SELECTION_TOLERANCE - 2, (SELECTION_TOLERANCE + 2) * 2, (SELECTION_TOLERANCE + 2) * 2); + // TODO: if (selected) + // g.setColor(Color.BLUE); + g.setColor(Color.BLACK); + g.drawOval(xx - SELECTION_TOLERANCE, yy - SELECTION_TOLERANCE, SELECTION_TOLERANCE * 2, SELECTION_TOLERANCE * 2); + + } + private void computeArrows() { computeElementArrow(elementTo, elementFrom); computeElementArrow(elementFrom, elementTo); @@ -295,137 +486,12 @@ public boolean isAreaCrossingPoint(Point selectionStart, Point selectionEnd) { } /** - * Determine if given point crosses given area. - * - * @param selectionStart Left-top point of the area - * @param selectionEnd Bottom-right point of the area - * @param point The point - * @return true if the area covers the point, false otherwise - */ - public static boolean isAreaCrossingPoint(Point selectionStart, Point selectionEnd, Point point) { - return P.of(point).isInRectangle(selectionStart, selectionEnd); - } - - private static double dot(P v0, P v1) { - return (v0.x * v1.x) + (v0.y * v1.y); - } - - private static boolean inTriangle(P point, P pa, P pb, P pc) { - // Compute vectors - P v0 = pc.minus(pa); - P v1 = pb.minus(pa); - P v2 = point.minus(pa); - - // Compute dot products - double dot00 = dot(v0, v0); - double dot01 = dot(v0, v1); - double dot02 = dot(v0, v2); - double dot11 = dot(v1, v1); - double dot12 = dot(v1, v2); - - // Compute barycentric coordinates - double invDenom = 1 / (dot00 * dot11 - dot01 * dot01); - double u = (dot11 * dot02 - dot01 * dot12) * invDenom; - double v = (dot00 * dot12 - dot01 * dot02) * invDenom; - - // Check if point is in triangle - return (u >= 0) && (v >= 0) && (u + v < 1); - } - - - /** - * Determine whether a line segment P1P2 crosses a triangle ABC. - * - * @param lineStart start point of the line segment - * @param lineEnd end point of the line segment - * @param pa first point of the triangle - * @param pb second point of the triangle - * @param pc third point of the triangle - * @return true if the line segment crosses the triangle; false otherwise - */ - private static boolean inTriangle(P lineStart, P lineEnd, P pa, P pb, P pc) { - double a = lineEnd.y - lineStart.y; - double b = lineStart.x - lineEnd.x; - double c = -a * lineStart.x - b * lineStart.y; // general line equation - - double result = a * pa.x + b * pa.y + c; - int sign = Integer.signum((int) result); - - result = a * pb.x + b * pb.y + c; - boolean is = isCrossing(sign, result); - if (!is) { - result = a * pc.x + b * pc.y + c; - is = isCrossing(sign, result); - } - - if (is) { - // now we know that line is crossing the triangle. - // we must check if the line segment crosses the triangle - - // A point is always left-top, B is always right, C is always under A - return (Math.min(lineStart.y, lineEnd.y) <= pc.y) && (Math.max(lineStart.y, lineEnd.y) >= pa.y) - && (Math.min(lineStart.x, lineEnd.x) <= pb.x) && (Math.max(lineStart.x, lineEnd.x) >= pa.x); - } else { - // last check if the line segment lies inside the triangle and does not cross it - return inTriangle(lineStart, pa, pb, pc) && inTriangle(lineEnd, pa, pb, pc); - } - - } - - private static boolean isCrossing(int sign, double result) { - if ((result > 0) && (sign != 1)) { - return true; - } else if ((result == 0) && (sign != 0)) { - return true; - } else return (result < 0) && (sign != -1); - } - - private static boolean checkValidIntersection(P v0, P v1, P v2, P v3, P lineStart, P lineEnd, P intersection) { - if (intersection != null) { - if ((intersection.x < v0.x) || (intersection.x > v2.x) - || (intersection.y < v0.y) || (intersection.y > v2.y)) { - intersection = null; - } else if (intersection.x < Math.min(lineStart.x, lineEnd.x) - || (intersection.x > Math.max(lineStart.x, lineEnd.x)) - || (intersection.y < Math.min(lineStart.y, lineEnd.y)) - || (intersection.y > Math.max(lineStart.y, lineEnd.y))) { - intersection = null; - } - } - if (intersection == null) { - // possible crossing (or overlay) can be on triangle (v0, v2, v3) - if (inTriangle(lineStart, lineEnd, v0, v2, v3)) { - return true; - } - // possible crossing (or overlay) can be on triangle (v0, v1, v2) - return inTriangle(lineStart, lineEnd, v0, v1, v2); - } else { - return true; - } - } - - /** - * Determines whether a selection area crosses or overlays a line segment. - *

- * If at least one intersection is found, then true is returned. + * Get the selection status. * - * @param lineStart Start point of the line segment - * @param lineEnd End point of the line segment - * @param selectionStart the selection start point - * @param selectionEnd the selection end point - * @return true if the line segment is crossing the selection area; false otherwise + * @return true if the line is selected, false otherwise. */ - public static boolean isAreaCrossing(Point lineStart, Point lineEnd, Point selectionStart, Point selectionEnd) { - P v1 = P.of(selectionEnd.x, selectionStart.y); - P v3 = P.of(selectionStart.x, selectionEnd.y); - - P pselectionStart = P.of(selectionStart); - P pselectionEnd = P.of(selectionEnd); - P plineEnd = P.of(lineEnd); - P plineStart = P.of(lineStart); - - P intersection = intersection(pselectionStart, pselectionEnd, plineStart, plineEnd); - return checkValidIntersection(pselectionStart, v1, pselectionEnd, v3, plineStart, plineEnd, intersection); + public boolean isSelected() { + return selected; } /** @@ -437,15 +503,6 @@ public void setSelected(boolean selected) { this.selected = selected; } - /** - * Get the selection status. - * - * @return true if the line is selected, false otherwise. - */ - public boolean isSelected() { - return selected; - } - /** * Draws this connection line. * @@ -550,68 +607,6 @@ public void draw(Graphics2D g, boolean preview) { g.setStroke(ss); } - /** - * This method draws a "sketch" line - in the process when user tries - * to draw a connection line. It is based on fixed first element ee1, where - * the line begins, and it continues through the points defined in the - * ppoints list. The last point is defined by the point ee2. - * - * @param g graphics object, where to draw the sketch line. - * @param ee1 first element - * @param ee2 last point - * @param ppoints list of middle-points - */ - public static void drawSketch(Graphics2D g, Element ee1, Point ee2, List

ppoints) { - Stroke ss = g.getStroke(); - g.setStroke(thickLine); - g.setColor(Color.GRAY); - int x1 = ee1.getX(); - int y1 = ee1.getY(); - int x2, y2; - - for (P p : ppoints) { - x2 = p.ix(); - y2 = p.iy(); - - if (x2 < Schema.MIN_LEFT_MARGIN) { - x2 = Schema.MIN_LEFT_MARGIN; - } - if (y2 < Schema.MIN_TOP_MARGIN) { - y2 = Schema.MIN_TOP_MARGIN; - } - - g.drawLine(x1, y1, x2, y2); - g.fillOval(x2 - 3, y2 - 3, 6, 6); - x1 = x2; - y1 = y2; - } - if (ee2 != null) { - x2 = (int) ee2.getX(); - y2 = (int) ee2.getY(); - g.drawLine(x1, y1, x2, y2); - } - g.setStroke(ss); - } - - /** - * Draws a small red circle around given point - * - * @param point the center of the circle - * @param g Graphics2D object - */ - public static void highlightPoint(P point, Graphics2D g) { - int xx = point.ix(); - int yy = point.iy(); - g.setColor(Color.WHITE); - g.setStroke(thickLine); - g.fillOval(xx - SELECTION_TOLERANCE - 2, yy - SELECTION_TOLERANCE - 2, (SELECTION_TOLERANCE + 2) * 2, (SELECTION_TOLERANCE + 2) * 2); - // TODO: if (selected) - // g.setColor(Color.BLUE); - g.setColor(Color.BLACK); - g.drawOval(xx - SELECTION_TOLERANCE, yy - SELECTION_TOLERANCE, SELECTION_TOLERANCE * 2, SELECTION_TOLERANCE * 2); - - } - /** * Adds a middle-point to this line. * @@ -650,7 +645,7 @@ public List

getPoints() { public P findPoint(Point clickPoint) { for (P point : points) { if ((point.x >= (clickPoint.x - SELECTION_TOLERANCE)) && (point.x <= (clickPoint.x + SELECTION_TOLERANCE)) - && (point.y >= (clickPoint.y - SELECTION_TOLERANCE)) && (point.y <= (clickPoint.y + SELECTION_TOLERANCE))) { + && (point.y >= (clickPoint.y - SELECTION_TOLERANCE)) && (point.y <= (clickPoint.y + SELECTION_TOLERANCE))) { return point; } } @@ -721,7 +716,7 @@ public void replaceElement(Element origin, Element replacement) { * If yes, return index of a nearest cross point. If new point is * going to be added, it should be added to replace returned point index. * - * @param clickPoint point that is checked + * @param clickPoint point that is checked * @return 0 - if line doesn't contain any point, but point[x,y] is crossing the * line; or if point[x,y] crosses the line near the beginning of it *

@@ -772,10 +767,10 @@ public int findCrossingPoint(Point clickPoint) { */ double crossproduct = vector2.y * vector1.x - vector2.x * vector1.y; if ((Math.abs(crossproduct) * len <= SELECTION_TOLERANCE) - && (Math.min(X1.x - SELECTION_TOLERANCE, X2.x - SELECTION_TOLERANCE) <= clickPoint.x) - && (clickPoint.x <= Math.max(X1.x + SELECTION_TOLERANCE, X2.x + SELECTION_TOLERANCE)) - && (Math.min(X1.y - SELECTION_TOLERANCE, X2.y - SELECTION_TOLERANCE) <= clickPoint.y) - && (clickPoint.y <= Math.max(X1.y + SELECTION_TOLERANCE, X2.y + SELECTION_TOLERANCE))) { + && (Math.min(X1.x - SELECTION_TOLERANCE, X2.x - SELECTION_TOLERANCE) <= clickPoint.x) + && (clickPoint.x <= Math.max(X1.x + SELECTION_TOLERANCE, X2.x + SELECTION_TOLERANCE)) + && (Math.min(X1.y - SELECTION_TOLERANCE, X2.y - SELECTION_TOLERANCE) <= clickPoint.y) + && (clickPoint.y <= Math.max(X1.y + SELECTION_TOLERANCE, X2.y + SELECTION_TOLERANCE))) { return i; } X1 = X2; @@ -786,10 +781,10 @@ public int findCrossingPoint(Point clickPoint) { Point2D.Double vector2 = new Point2D.Double((clickPoint.x - X1.x) / len, (clickPoint.y - X1.y) / len); double crossProduct = vector2.y * vector1.x - vector2.x * vector1.y; if ((Math.abs(crossProduct) * len <= SELECTION_TOLERANCE) - && (Math.min(X1.x - SELECTION_TOLERANCE, X2.x - SELECTION_TOLERANCE) <= clickPoint.x) - && (clickPoint.x <= Math.max(X1.x + SELECTION_TOLERANCE, X2.x + SELECTION_TOLERANCE)) - && (Math.min(X1.y - SELECTION_TOLERANCE, X2.y - SELECTION_TOLERANCE) <= clickPoint.y) - && (clickPoint.y <= Math.max(X1.y + SELECTION_TOLERANCE, X2.y + SELECTION_TOLERANCE))) { + && (Math.min(X1.x - SELECTION_TOLERANCE, X2.x - SELECTION_TOLERANCE) <= clickPoint.x) + && (clickPoint.x <= Math.max(X1.x + SELECTION_TOLERANCE, X2.x + SELECTION_TOLERANCE)) + && (Math.min(X1.y - SELECTION_TOLERANCE, X2.y - SELECTION_TOLERANCE) <= clickPoint.y) + && (clickPoint.y <= Math.max(X1.y + SELECTION_TOLERANCE, X2.y + SELECTION_TOLERANCE))) { return pointsSize; // as new point index } return -1; @@ -799,10 +794,10 @@ public PluginConnection toPluginConnection() { List schemaPoints = points.stream().map(P::toSchemaPoint).collect(Collectors.toList()); return PluginConnection.create( - elementFrom.getPluginId(), - elementTo.getPluginId(), - bidirectional, - schemaPoints + elementFrom.getPluginId(), + elementTo.getPluginId(), + bidirectional, + schemaPoints ); } } diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/CpuElement.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/CpuElement.java index 421454904..ee2d36c4b 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/CpuElement.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/CpuElement.java @@ -19,8 +19,8 @@ package net.emustudio.application.gui.schema.elements; import com.electronwill.nightconfig.core.Config; -import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.P; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; import java.awt.*; @@ -32,15 +32,15 @@ public class CpuElement extends Element { public CpuElement(P schemaPoint, String pluginName, String pluginFileName) { super( - BACK_COLOR, schemaPoint, UUID.randomUUID().toString(), PLUGIN_TYPE.CPU, pluginName, pluginFileName, - Config.inMemory() + BACK_COLOR, schemaPoint, UUID.randomUUID().toString(), PLUGIN_TYPE.CPU, pluginName, pluginFileName, + Config.inMemory() ); } public CpuElement(PluginConfig config, Function searchGridPoint) { super( - BACK_COLOR, searchGridPoint.apply(P.of(config.getSchemaPoint())), config.getPluginId(), PLUGIN_TYPE.CPU, - config.getPluginName(), config.getPluginFile(), config.getPluginSettings() + BACK_COLOR, searchGridPoint.apply(P.of(config.getSchemaPoint())), config.getPluginId(), PLUGIN_TYPE.CPU, + config.getPluginName(), config.getPluginFile(), config.getPluginSettings() ); } } diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/DeviceElement.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/DeviceElement.java index 2e5b647f8..83381b583 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/DeviceElement.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/DeviceElement.java @@ -19,8 +19,8 @@ package net.emustudio.application.gui.schema.elements; import com.electronwill.nightconfig.core.Config; -import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.P; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; import java.awt.*; @@ -32,15 +32,15 @@ public class DeviceElement extends Element { public DeviceElement(P schemaPoint, String pluginName, String pluginFileName) { super( - BACK_COLOR, schemaPoint, UUID.randomUUID().toString(), PLUGIN_TYPE.DEVICE, pluginName, pluginFileName, - Config.inMemory() + BACK_COLOR, schemaPoint, UUID.randomUUID().toString(), PLUGIN_TYPE.DEVICE, pluginName, pluginFileName, + Config.inMemory() ); } public DeviceElement(PluginConfig config, Function searchGridPoint) { super( - BACK_COLOR, searchGridPoint.apply(P.of(config.getSchemaPoint())), config.getPluginId(), PLUGIN_TYPE.DEVICE, - config.getPluginName(), config.getPluginFile(), config.getPluginSettings() + BACK_COLOR, searchGridPoint.apply(P.of(config.getSchemaPoint())), config.getPluginId(), PLUGIN_TYPE.DEVICE, + config.getPluginName(), config.getPluginFile(), config.getPluginSettings() ); } } diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/Element.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/Element.java index e21e71098..0e797a3bc 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/Element.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/Element.java @@ -19,8 +19,8 @@ package net.emustudio.application.gui.schema.elements; import com.electronwill.nightconfig.core.Config; -import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.P; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; import java.awt.*; @@ -33,11 +33,9 @@ * It is a graphical object representing a plug-in. */ public abstract class Element { + final static int MOUSE_TOLERANCE = 5; private final static int MIN_WIDTH = 80; private final static int MIN_HEIGHT = 50; - - final static int MOUSE_TOLERANCE = 5; - private final Font pluginNameFont = new Font(Font.DIALOG, Font.BOLD, 13); private final Font pluginTypeFont = new Font(Font.MONOSPACED, Font.ITALIC, 12); @@ -205,15 +203,14 @@ private int getRightX() { return leftX + getWidth(); } + public boolean isSelected() { + return selected; + } public void setSelected(boolean selected) { this.selected = selected; } - public boolean isSelected() { - return selected; - } - /** * Determines whether a selection area crosses or overlays this element. It is assumed that the element is measured * already. @@ -233,7 +230,7 @@ public boolean crossesArea(Point selectionStart, Point selectionEnd) { int yB = getBottomY(); return (selectionStart.x <= xR) && (selectionEnd.x >= leftX) - && (selectionStart.y <= yB) && (selectionEnd.y >= topY); + && (selectionStart.y <= yB) && (selectionEnd.y >= topY); } /** diff --git a/application/src/main/java/net/emustudio/application/gui/schema/elements/MemoryElement.java b/application/src/main/java/net/emustudio/application/gui/schema/elements/MemoryElement.java index 400b07fe2..d0639852d 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/elements/MemoryElement.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/elements/MemoryElement.java @@ -19,8 +19,8 @@ package net.emustudio.application.gui.schema.elements; import com.electronwill.nightconfig.core.Config; -import net.emustudio.application.settings.PluginConfig; import net.emustudio.application.gui.P; +import net.emustudio.application.settings.PluginConfig; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; import java.awt.*; @@ -32,15 +32,15 @@ public class MemoryElement extends Element { public MemoryElement(P schemaPoint, String pluginName, String pluginFileName) { super( - BACK_COLOR, schemaPoint, UUID.randomUUID().toString(), PLUGIN_TYPE.MEMORY, pluginName, pluginFileName, - Config.inMemory() + BACK_COLOR, schemaPoint, UUID.randomUUID().toString(), PLUGIN_TYPE.MEMORY, pluginName, pluginFileName, + Config.inMemory() ); } public MemoryElement(PluginConfig config, Function searchGridPoint) { super( - BACK_COLOR, searchGridPoint.apply(P.of(config.getSchemaPoint())), config.getPluginId(), PLUGIN_TYPE.MEMORY, - config.getPluginName(), config.getPluginFile(), config.getPluginSettings() + BACK_COLOR, searchGridPoint.apply(P.of(config.getSchemaPoint())), config.getPluginId(), PLUGIN_TYPE.MEMORY, + config.getPluginName(), config.getPluginFile(), config.getPluginSettings() ); } } diff --git a/application/src/main/java/net/emustudio/application/gui/schema/mode/AbstractMode.java b/application/src/main/java/net/emustudio/application/gui/schema/mode/AbstractMode.java index 16914e29f..e80aeae2f 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/mode/AbstractMode.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/mode/AbstractMode.java @@ -22,7 +22,6 @@ import net.emustudio.application.gui.schema.DrawingPanel; import net.emustudio.application.gui.schema.Schema; -import java.awt.*; import java.util.Objects; abstract class AbstractMode implements Mode { diff --git a/application/src/main/java/net/emustudio/application/gui/schema/mode/ModeSelector.java b/application/src/main/java/net/emustudio/application/gui/schema/mode/ModeSelector.java index 2858f0f4b..8594759e8 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/mode/ModeSelector.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/mode/ModeSelector.java @@ -23,19 +23,14 @@ public class ModeSelector { - public enum SelectMode { - MOVING, MODELING, RESIZING, SELECTING - } - private final Mode[] modes; private Mode currentMode; - public ModeSelector(DrawingPanel panel, DrawingModel drawingModel) { modes = new Mode[]{ - new MovingMode(panel, drawingModel), - new ModelingMode(panel, drawingModel), - new ResizingMode(panel, drawingModel), - new SelectingMode(panel, drawingModel) + new MovingMode(panel, drawingModel), + new ModelingMode(panel, drawingModel), + new ResizingMode(panel, drawingModel), + new SelectingMode(panel, drawingModel) }; } @@ -47,4 +42,8 @@ public Mode get() { return currentMode; } + public enum SelectMode { + MOVING, MODELING, RESIZING, SELECTING + } + } diff --git a/application/src/main/java/net/emustudio/application/gui/schema/mode/ModelingMode.java b/application/src/main/java/net/emustudio/application/gui/schema/mode/ModelingMode.java index 4fa59d42a..a99f547d2 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/mode/ModelingMode.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/mode/ModelingMode.java @@ -21,7 +21,8 @@ import net.emustudio.application.gui.P; import net.emustudio.application.gui.schema.DrawingModel; import net.emustudio.application.gui.schema.DrawingPanel; -import net.emustudio.application.gui.schema.elements.*; +import net.emustudio.application.gui.schema.elements.ConnectionLine; +import net.emustudio.application.gui.schema.elements.Element; import net.emustudio.application.gui.schema.mode.ModeSelector.SelectMode; import java.awt.*; @@ -165,7 +166,7 @@ public SelectMode mouseReleased(MouseEvent e) { boolean alreadyConnected = schema.isConnected(drawingModel.tmpElem1, drawingModel.tmpElem2); if (!alreadyConnected && (drawingModel.tmpElem1 != drawingModel.tmpElem2)) { schema.addConnectionLine( - drawingModel.tmpElem1, drawingModel.tmpElem2, drawingModel.tmpPoints, drawingModel.bidirectional + drawingModel.tmpElem1, drawingModel.tmpElem2, drawingModel.tmpPoints, drawingModel.bidirectional ); } drawingModel.tmpElem1 = null; @@ -187,7 +188,7 @@ public SelectMode mouseDragged(MouseEvent e) { if (schema.getCrossingElement(clickPoint) == null) { // if user didn't clicked on an element, but on drawing area means that there a new line point // should be created. - drawingModel.selectedPoint = P.of(clickPoint); + drawingModel.selectedPoint = P.of(clickPoint); } } return SelectMode.MODELING; diff --git a/application/src/main/java/net/emustudio/application/gui/schema/mode/MovingMode.java b/application/src/main/java/net/emustudio/application/gui/schema/mode/MovingMode.java index 6f1befb16..c09ee4381 100644 --- a/application/src/main/java/net/emustudio/application/gui/schema/mode/MovingMode.java +++ b/application/src/main/java/net/emustudio/application/gui/schema/mode/MovingMode.java @@ -128,7 +128,7 @@ public SelectMode mouseReleased(MouseEvent e) { } P linePoint = drawingModel.selectedLine.findPoint(clickPoint); if ((drawingModel.selectedLine != schema.findCrossingLine(clickPoint)) - || (drawingModel.selectedPoint != linePoint)) { + || (drawingModel.selectedPoint != linePoint)) { drawingModel.selectedLine = null; drawingModel.selectedPoint = null; return SelectMode.MOVING; diff --git a/application/src/main/java/net/emustudio/application/internal/Hashing.java b/application/src/main/java/net/emustudio/application/internal/Hashing.java index 268be40b6..31a29a804 100644 --- a/application/src/main/java/net/emustudio/application/internal/Hashing.java +++ b/application/src/main/java/net/emustudio/application/internal/Hashing.java @@ -29,7 +29,7 @@ public class Hashing { /** * Compute SHA-1 hash string. - * + *

* Letters in the hash string will be in upper-case. * * @param text Data to make hash from diff --git a/application/src/main/java/net/emustudio/application/internal/Unchecked.java b/application/src/main/java/net/emustudio/application/internal/Unchecked.java index 84473a788..ce9ec4d23 100644 --- a/application/src/main/java/net/emustudio/application/internal/Unchecked.java +++ b/application/src/main/java/net/emustudio/application/internal/Unchecked.java @@ -20,7 +20,7 @@ /** * This code was borrowed from: - * + *

* http://stackoverflow.com/questions/19757300/java-8-lambda-streams-filter-by-method-with-exception */ public class Unchecked { diff --git a/application/src/main/java/net/emustudio/application/settings/AppSettings.java b/application/src/main/java/net/emustudio/application/settings/AppSettings.java index 8ec454bfc..44f1858a4 100644 --- a/application/src/main/java/net/emustudio/application/settings/AppSettings.java +++ b/application/src/main/java/net/emustudio/application/settings/AppSettings.java @@ -46,6 +46,12 @@ public AppSettings(Config config, boolean nogui, boolean auto) { this.noGUI = nogui; } + public static AppSettings fromFile(Path file, boolean nogui, boolean auto) { + FileConfig config = FileConfig.builder(file).autosave().concurrent().sync().build(); + config.load(); + return new AppSettings(config, nogui, auto); + } + @Override public boolean contains(String key) { return KEY_NOGUI.equals(key) || KEY_AUTO.equals(key) || super.contains(key); @@ -80,10 +86,4 @@ public Optional getBoolean(String key) { } return super.getBoolean(key); } - - public static AppSettings fromFile(Path file, boolean nogui, boolean auto) { - FileConfig config = FileConfig.builder(file).autosave().concurrent().sync().build(); - config.load(); - return new AppSettings(config, nogui, auto); - } } diff --git a/application/src/main/java/net/emustudio/application/settings/ComputerConfig.java b/application/src/main/java/net/emustudio/application/settings/ComputerConfig.java index b337f96aa..805431629 100644 --- a/application/src/main/java/net/emustudio/application/settings/ComputerConfig.java +++ b/application/src/main/java/net/emustudio/application/settings/ComputerConfig.java @@ -40,6 +40,24 @@ public ComputerConfig(FileConfig config) { this.config = Objects.requireNonNull(config); } + public static ComputerConfig load(Path configurationFile) { + FileConfig config = FileConfig.builder(configurationFile).concurrent().sync().autosave().build(); + config.load(); + + return new ComputerConfig(config); + } + + public static ComputerConfig create(String computerName, Path configurationFile) throws IOException { + if (Files.exists(configurationFile)) { + throw new IllegalArgumentException("Configuration already exists"); + } + Files.createFile(configurationFile); + FileConfig config = FileConfig.builder(configurationFile).concurrent().sync().autosave().build(); + config.set("name", computerName); + + return new ComputerConfig(config); + } + public FileConfig getConfig() { return config; } @@ -131,8 +149,8 @@ public List getConnections() { Optional> rawConnections = config.getOptional("connections"); return rawConnections - .map(connections -> connections.stream().map(PluginConnection::new).collect(toList())) - .orElse(Collections.emptyList()); + .map(connections -> connections.stream().map(PluginConnection::new).collect(toList())) + .orElse(Collections.emptyList()); } public void setConnections(List connections) { @@ -153,22 +171,4 @@ public void close() { public String toString() { return getName(); } - - public static ComputerConfig load(Path configurationFile) { - FileConfig config = FileConfig.builder(configurationFile).concurrent().sync().autosave().build(); - config.load(); - - return new ComputerConfig(config); - } - - public static ComputerConfig create(String computerName, Path configurationFile) throws IOException { - if (Files.exists(configurationFile)) { - throw new IllegalArgumentException("Configuration already exists"); - } - Files.createFile(configurationFile); - FileConfig config = FileConfig.builder(configurationFile).concurrent().sync().autosave().build(); - config.set("name", computerName); - - return new ComputerConfig(config); - } } diff --git a/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java b/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java index 9ef1bff68..8daf7c938 100644 --- a/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java +++ b/application/src/main/java/net/emustudio/application/settings/ConfigFiles.java @@ -37,10 +37,10 @@ public class ConfigFiles { private final static String DIR_DEVICE = "device"; private final static Map PLUGIN_SUBDIRS = Map.of( - PLUGIN_TYPE.COMPILER, DIR_COMPILER, - PLUGIN_TYPE.CPU, DIR_CPU, - PLUGIN_TYPE.MEMORY, DIR_MEMORY, - PLUGIN_TYPE.DEVICE, DIR_DEVICE + PLUGIN_TYPE.COMPILER, DIR_COMPILER, + PLUGIN_TYPE.CPU, DIR_CPU, + PLUGIN_TYPE.MEMORY, DIR_MEMORY, + PLUGIN_TYPE.DEVICE, DIR_DEVICE ); private static final Path basePath = Path.of(System.getProperty("user.dir")); @@ -70,17 +70,17 @@ public static List loadConfigurations(Path basePath) throws IOEx } try (Stream configFiles = Files.list(basePath.resolve(DIR_CONFIG))) { return configFiles - .filter(p -> !Files.isDirectory(p) && Files.isReadable(p)) - .flatMap(p -> { - try { - return Stream.of(ComputerConfig.load(p)); - } catch (Exception e) { - return Stream.empty(); - } - }) - .filter(c -> c.getName() != null) - .sorted(Comparator.comparing(ComputerConfig::getName)) - .collect(Collectors.toList()); + .filter(p -> !Files.isDirectory(p) && Files.isReadable(p)) + .flatMap(p -> { + try { + return Stream.of(ComputerConfig.load(p)); + } catch (Exception e) { + return Stream.empty(); + } + }) + .filter(c -> c.getName() != null) + .sorted(Comparator.comparing(ComputerConfig::getName)) + .collect(Collectors.toList()); } } @@ -98,10 +98,10 @@ public static List listPluginFiles(PLUGIN_TYPE pluginType) throws IOExce Path pluginBasePath = basePath.resolve(PLUGIN_SUBDIRS.get(pluginType)); try (Stream paths = Files.list(pluginBasePath)) { return paths - .filter(p -> !Files.isDirectory(p) && Files.isReadable(p)) - .map(p -> p.getFileName().toString()) - .sorted() - .collect(Collectors.toList()); + .filter(p -> !Files.isDirectory(p) && Files.isReadable(p)) + .map(p -> p.getFileName().toString()) + .sorted() + .collect(Collectors.toList()); } } diff --git a/application/src/main/java/net/emustudio/application/settings/PluginConfig.java b/application/src/main/java/net/emustudio/application/settings/PluginConfig.java index 2c660b342..f9af5475d 100644 --- a/application/src/main/java/net/emustudio/application/settings/PluginConfig.java +++ b/application/src/main/java/net/emustudio/application/settings/PluginConfig.java @@ -34,6 +34,19 @@ public PluginConfig(Config config) { this.config = Objects.requireNonNull(config); } + public static PluginConfig create(String id, PLUGIN_TYPE pluginType, String pluginName, String pluginFile, + P schemaLocation, Config pluginSettings) { + Config config = Config.inMemory(); + config.set("id", id); + config.set("type", pluginType.toString()); + config.set("name", pluginName); + config.set("path", pluginFile); + config.set("schemaPoint", schemaLocation.toSchemaPoint().toString()); + config.set("settings", pluginSettings); + + return new PluginConfig(config); + } + public String getPluginId() { return config.get("id"); } @@ -78,17 +91,4 @@ public Config getPluginSettings() { public Config getConfig() { return config; } - - public static PluginConfig create(String id, PLUGIN_TYPE pluginType, String pluginName, String pluginFile, - P schemaLocation, Config pluginSettings) { - Config config = Config.inMemory(); - config.set("id", id); - config.set("type", pluginType.toString()); - config.set("name", pluginName); - config.set("path", pluginFile); - config.set("schemaPoint", schemaLocation.toSchemaPoint().toString()); - config.set("settings", pluginSettings); - - return new PluginConfig(config); - } } diff --git a/application/src/main/java/net/emustudio/application/settings/PluginConnection.java b/application/src/main/java/net/emustudio/application/settings/PluginConnection.java index 4410ce0f4..3e88f8149 100644 --- a/application/src/main/java/net/emustudio/application/settings/PluginConnection.java +++ b/application/src/main/java/net/emustudio/application/settings/PluginConnection.java @@ -32,6 +32,16 @@ public PluginConnection(Config config) { this.config = Objects.requireNonNull(config); } + public static PluginConnection create(String fromPluginId, String toPluginId, boolean bidirectional, List schemaPoints) { + Config config = Config.inMemory(); + config.set("from", Objects.requireNonNull(fromPluginId)); + config.set("to", Objects.requireNonNull(toPluginId)); + config.set("bidirectional", bidirectional); + config.set("points", schemaPoints.stream().map(SchemaPoint::toString).collect(Collectors.toList())); + + return new PluginConnection(config); + } + public String getFromPluginId() { return config.get("from"); } @@ -52,14 +62,4 @@ public List getSchemaPoints() { public Config getConfig() { return config; } - - public static PluginConnection create(String fromPluginId, String toPluginId, boolean bidirectional, List schemaPoints) { - Config config = Config.inMemory(); - config.set("from", Objects.requireNonNull(fromPluginId)); - config.set("to", Objects.requireNonNull(toPluginId)); - config.set("bidirectional", bidirectional); - config.set("points", schemaPoints.stream().map(SchemaPoint::toString).collect(Collectors.toList())); - - return new PluginConnection(config); - } } diff --git a/application/src/main/java/net/emustudio/application/settings/PluginSettingsImpl.java b/application/src/main/java/net/emustudio/application/settings/PluginSettingsImpl.java index 5fe3cfc9f..75580eb9a 100644 --- a/application/src/main/java/net/emustudio/application/settings/PluginSettingsImpl.java +++ b/application/src/main/java/net/emustudio/application/settings/PluginSettingsImpl.java @@ -28,7 +28,7 @@ import java.util.Objects; import java.util.Optional; -public class PluginSettingsImpl extends BasicSettingsImpl implements PluginSettings { +public class PluginSettingsImpl extends BasicSettingsImpl implements PluginSettings { private final AppSettings application; public PluginSettingsImpl(Config pluginConfig, AppSettings application, Runnable save) { diff --git a/application/src/main/java/net/emustudio/application/settings/SchemaPoint.java b/application/src/main/java/net/emustudio/application/settings/SchemaPoint.java index c794b5778..062e93bff 100644 --- a/application/src/main/java/net/emustudio/application/settings/SchemaPoint.java +++ b/application/src/main/java/net/emustudio/application/settings/SchemaPoint.java @@ -32,6 +32,18 @@ private SchemaPoint(int x, int y) { this.y = y; } + public static SchemaPoint parse(String value) { + String[] xy = value.split(","); + int x = Integer.decode(xy[0].trim()); + int y = Integer.decode(xy[1].trim()); + + return new SchemaPoint(x, y); + } + + public static SchemaPoint of(int x, int y) { + return new SchemaPoint(x, y); + } + @Override public String toString() { return x + "," + y; @@ -42,23 +54,11 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SchemaPoint that = (SchemaPoint) o; - return x == that.x && y == that.y; + return x == that.x && y == that.y; } @Override public int hashCode() { return Objects.hash(x, y); } - - public static SchemaPoint parse(String value) { - String[] xy = value.split(","); - int x = Integer.decode(xy[0].trim()); - int y = Integer.decode(xy[1].trim()); - - return new SchemaPoint(x, y); - } - - public static SchemaPoint of(int x, int y) { - return new SchemaPoint(x, y); - } } diff --git a/application/src/main/java/net/emustudio/application/virtualcomputer/ContextPoolImpl.java b/application/src/main/java/net/emustudio/application/virtualcomputer/ContextPoolImpl.java index ec76857f5..10396efa6 100644 --- a/application/src/main/java/net/emustudio/application/virtualcomputer/ContextPoolImpl.java +++ b/application/src/main/java/net/emustudio/application/virtualcomputer/ContextPoolImpl.java @@ -51,6 +51,32 @@ public ContextPoolImpl(long alwaysAllowedPluginId) { this.alwaysAllowedPluginId = alwaysAllowedPluginId; } + /** + * Compute emuStudio-specific hash of the context interface. + * The name of the interface is not important, only method names and their signatures. + * + * @param contextInterface interface to compute hash of + * @return hash representing the interface + */ + private static String computeHash(Class contextInterface) throws InvalidContextException { + List contextMethods = Arrays.asList(contextInterface.getMethods()); + contextMethods.sort(Comparator.comparing(Method::getName)); + + StringBuilder hash = new StringBuilder(); + for (Method method : contextMethods.toArray(new Method[0])) { + hash.append(method.getGenericReturnType().toString()).append(" ").append(method.getName()).append("("); + for (Class param : method.getParameterTypes()) { + hash.append(param.getName()).append(","); + } + hash.append(");"); + } + try { + return Hashing.SHA1(hash.toString()); + } catch (NoSuchAlgorithmException e) { + throw new InvalidContextException("Could not compute hash for interface " + contextInterface, e); + } + } + @Override public void register(long pluginID, Context context, Class contextInterface) throws ContextAlreadyRegisteredException, InvalidContextException { verifyPluginContext(contextInterface); @@ -114,14 +140,14 @@ public boolean unregister(long pluginID, Class contextInterfa @SuppressWarnings("unchecked") @Override public T getContext(long pluginID, Class contextInterface, int index) - throws InvalidContextException, ContextNotFoundException { + throws InvalidContextException, ContextNotFoundException { verifyPluginContext(contextInterface); // find the requested context List contextsByHash = contexts.get(computeHash(contextInterface)); if ((contextsByHash == null) || contextsByHash.isEmpty()) { throw new ContextNotFoundException( - "Context " + contextInterface + " is not found in registered contexts list." + "Context " + contextInterface + " is not found in registered contexts list." ); } LOGGER.debug("Matching context " + contextInterface + " from " + contextsByHash.size() + " option(s)"); @@ -138,8 +164,8 @@ public T getContext(long pluginID, Class contextInterface currentIndex++; } throw new ContextNotFoundException( - "Plugin " + pluginID + " has either no permission to access context " + contextInterface + - " or index is out of bounds" + "Plugin " + pluginID + " has either no permission to access context " + contextInterface + + " or index is out of bounds" ); } @@ -150,14 +176,14 @@ public CPUContext getCPUContext(long pluginID) throws InvalidContextException, C @Override public T getCPUContext(long pluginID, Class contextInterface) - throws InvalidContextException, ContextNotFoundException { + throws InvalidContextException, ContextNotFoundException { return getContext(pluginID, contextInterface, -1); } @Override public T getCPUContext(long pluginID, Class contextInterface, int index) - throws InvalidContextException, ContextNotFoundException { + throws InvalidContextException, ContextNotFoundException { return getContext(pluginID, contextInterface, index); } @@ -169,19 +195,19 @@ public CompilerContext getCompilerContext(long pluginID) throws InvalidContextEx @Override public T getCompilerContext(long pluginID, Class contextInterface) - throws InvalidContextException, ContextNotFoundException { + throws InvalidContextException, ContextNotFoundException { return getContext(pluginID, contextInterface, -1); } @Override public T getCompilerContext(long pluginID, Class contextInterface, int index) - throws InvalidContextException, ContextNotFoundException { + throws InvalidContextException, ContextNotFoundException { return getContext(pluginID, contextInterface, index); } @Override public > T getMemoryContext(long pluginID, Class contextInterface) - throws InvalidContextException, ContextNotFoundException { + throws InvalidContextException, ContextNotFoundException { return getContext(pluginID, contextInterface, -1); } @@ -193,7 +219,7 @@ public > T getMemoryContext(long plu @Override public > T getDeviceContext(long pluginID, Class contextInterface) - throws InvalidContextException, ContextNotFoundException { + throws InvalidContextException, ContextNotFoundException { return getContext(pluginID, contextInterface, -1); } @@ -234,32 +260,6 @@ private Optional findContextOwner(Context context) { return Optional.ofNullable(contextOwner); } - /** - * Compute emuStudio-specific hash of the context interface. - * The name of the interface is not important, only method names and their signatures. - * - * @param contextInterface interface to compute hash of - * @return hash representing the interface - */ - private static String computeHash(Class contextInterface) throws InvalidContextException { - List contextMethods = Arrays.asList(contextInterface.getMethods()); - contextMethods.sort(Comparator.comparing(Method::getName)); - - StringBuilder hash = new StringBuilder(); - for (Method method : contextMethods.toArray(new Method[0])) { - hash.append(method.getGenericReturnType().toString()).append(" ").append(method.getName()).append("("); - for (Class param : method.getParameterTypes()) { - hash.append(param.getName()).append(","); - } - hash.append(");"); - } - try { - return Hashing.SHA1(hash.toString()); - } catch (NoSuchAlgorithmException e) { - throw new InvalidContextException("Could not compute hash for interface " + contextInterface, e); - } - } - private void verifyPluginContext(Class contextInterface) throws InvalidContextException { Objects.requireNonNull(contextInterface); diff --git a/application/src/main/java/net/emustudio/application/virtualcomputer/InvalidPluginException.java b/application/src/main/java/net/emustudio/application/virtualcomputer/InvalidPluginException.java index 03f1fb09a..c514a4005 100644 --- a/application/src/main/java/net/emustudio/application/virtualcomputer/InvalidPluginException.java +++ b/application/src/main/java/net/emustudio/application/virtualcomputer/InvalidPluginException.java @@ -21,7 +21,6 @@ /** * This class represents an exception that can be raised during PluginLoader.loadPlugin method if a main plugin class * does not meet requirements for plugin classes. - * */ public class InvalidPluginException extends Exception { diff --git a/application/src/main/java/net/emustudio/application/virtualcomputer/PluginConnections.java b/application/src/main/java/net/emustudio/application/virtualcomputer/PluginConnections.java index 22a912c7e..e39efb6f0 100644 --- a/application/src/main/java/net/emustudio/application/virtualcomputer/PluginConnections.java +++ b/application/src/main/java/net/emustudio/application/virtualcomputer/PluginConnections.java @@ -21,7 +21,7 @@ /** * Abstraction over a "connection" of computer components - i.e. plugins. - * + *

* A connection can be one-directional or bi-directional. Connections are determined solely from abstract schema * of the emulated computer. */ @@ -30,14 +30,14 @@ public interface PluginConnections { /** * Determine if two plugins are connected. - * + *

* More specifically, determines if pluginA "sees" pluginB. That means, if pluginA * can obtain and use contexts registered by pluginB in the context pool. - * + *

* Connections can be one-directional. In case of bi-directional connection, the following must hold: * * - * isConnected(pluginA, pluginB) == isConnected(pluginB, pluginA) == true + * isConnected(pluginA, pluginB) == isConnected(pluginB, pluginA) == true * * * @param pluginA first plugin ID diff --git a/application/src/main/java/net/emustudio/application/virtualcomputer/PluginLoader.java b/application/src/main/java/net/emustudio/application/virtualcomputer/PluginLoader.java index 8062a07ee..2397ddd12 100644 --- a/application/src/main/java/net/emustudio/application/virtualcomputer/PluginLoader.java +++ b/application/src/main/java/net/emustudio/application/virtualcomputer/PluginLoader.java @@ -47,10 +47,24 @@ public class PluginLoader { private final static Logger LOGGER = LoggerFactory.getLogger(PluginLoader.class); /** - * Loads emuStudio plugins. + * Check if provided class meets plugin requirements. * + * @param pluginClass the main class of the plugin + * @return true if the class meets plugin requirements; false otherwise + */ + static boolean trustedPlugin(Class pluginClass) { + Objects.requireNonNull(pluginClass); + + return !pluginClass.isInterface() && + pluginClass.isAnnotationPresent(PluginRoot.class) && + doesImplement(pluginClass, Plugin.class); + } + + /** + * Loads emuStudio plugins. + *

* This method is called by emuStudio. - * + *

* The plugins are loaded into separate class loader. * * @param pluginFiles plugin files. @@ -71,9 +85,9 @@ public List> loadPlugins(List pluginFiles) throws IOExceptio try { return pluginFiles.stream() - .map(this::findClassesInJAR) - .map(l -> findMainClass(pluginsClassLoader, l)) - .collect(toList()); + .map(this::findClassesInJAR) + .map(l -> findMainClass(pluginsClassLoader, l)) + .collect(toList()); } catch (Exception e) { // Those can be "sneaky" thrown if ((e instanceof InvalidPluginException) || (e instanceof IOException)) { @@ -140,12 +154,12 @@ private Class findMainClass(ClassLoader classLoader, List classe /** * Transform a relative file name into valid Java class name. - * + *

* For example, if the class file name is "somepackage/nextpackage/SomeClass.class", the method * will transform it to the format "somepackage.nextpackage.SomeClass". - * + *

* It doesnt't work for absolute file names. - * + *

* It doesn't hurt if the class name is already in valid Java format. * * @param classFileName File name defining class @@ -158,18 +172,4 @@ private String getValidClassName(String classFileName) { classFileName = classFileName.replace("\\\\", "/").replace('/', '.'); return classFileName.replace(File.separatorChar, '.'); } - - /** - * Check if provided class meets plugin requirements. - * - * @param pluginClass the main class of the plugin - * @return true if the class meets plugin requirements; false otherwise - */ - static boolean trustedPlugin(Class pluginClass) { - Objects.requireNonNull(pluginClass); - - return !pluginClass.isInterface() && - pluginClass.isAnnotationPresent(PluginRoot.class) && - doesImplement(pluginClass, Plugin.class); - } } diff --git a/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java b/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java index 0bd5212c3..e9c4823a0 100644 --- a/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java +++ b/application/src/main/java/net/emustudio/application/virtualcomputer/VirtualComputer.java @@ -18,8 +18,11 @@ */ package net.emustudio.application.virtualcomputer; -import net.emustudio.application.settings.*; import net.emustudio.application.internal.Unchecked; +import net.emustudio.application.settings.AppSettings; +import net.emustudio.application.settings.ComputerConfig; +import net.emustudio.application.settings.PluginConfig; +import net.emustudio.application.settings.PluginSettingsImpl; import net.emustudio.emulib.plugins.Plugin; import net.emustudio.emulib.plugins.PluginInitializationException; import net.emustudio.emulib.plugins.annotations.PLUGIN_TYPE; @@ -46,14 +49,14 @@ public class VirtualComputer implements PluginConnections, AutoCloseable { private static final Logger LOGGER = LoggerFactory.getLogger(VirtualComputer.class); private static final Map> pluginInterfaces = Map.of( - PLUGIN_TYPE.COMPILER, Compiler.class, - PLUGIN_TYPE.CPU, CPU.class, - PLUGIN_TYPE.MEMORY, Memory.class, - PLUGIN_TYPE.DEVICE, Device.class + PLUGIN_TYPE.COMPILER, Compiler.class, + PLUGIN_TYPE.CPU, CPU.class, + PLUGIN_TYPE.MEMORY, Memory.class, + PLUGIN_TYPE.DEVICE, Device.class ); // The first parameter of constructor is plug-in ID private static final Class[] PLUGIN_CONSTRUCTOR_PARAMS = { - long.class, ApplicationApi.class, PluginSettings.class + long.class, ApplicationApi.class, PluginSettings.class }; @@ -76,71 +79,6 @@ public VirtualComputer(ComputerConfig computerConfig, Map plug }); } - public ComputerConfig getComputerConfig() { - return computerConfig; - } - - public void initialize(ContextPoolImpl contextPool) throws PluginInitializationException { - contextPool.setComputer(this); - List pluginsToInitialize = Stream.of( - pluginsByType.getOrDefault(PLUGIN_TYPE.COMPILER, Collections.emptyList()), - pluginsByType.getOrDefault(PLUGIN_TYPE.MEMORY, Collections.emptyList()), - pluginsByType.getOrDefault(PLUGIN_TYPE.CPU, Collections.emptyList()), - pluginsByType.getOrDefault(PLUGIN_TYPE.DEVICE, Collections.emptyList()) - ).flatMap(Collection::stream).collect(Collectors.toList()); - - for (PluginMeta pluginMeta : pluginsToInitialize) { - pluginMeta.pluginInstance.initialize(); - } - } - - public void reset() { - getCompiler().ifPresent(Compiler::reset); - getMemory().ifPresentOrElse(memory -> { - getCPU().ifPresent(cpu -> cpu.reset(memory.getProgramLocation())); - memory.reset(); - }, () -> getCPU().ifPresent(CPU::reset)); - getDevices().forEach(Device::reset); - } - - @Override - public boolean isConnected(long pluginA, long pluginB) { - String fst = pluginsById.get(pluginA).pluginConfig.getPluginId(); - String snd = pluginsById.get(pluginB).pluginConfig.getPluginId(); - - return computerConfig.getConnections().stream().anyMatch(connection -> { - boolean oneWay = connection.getFromPluginId().equals(fst) && connection.getToPluginId().equals(snd); - boolean otherWay = connection.getFromPluginId().equals(snd) && connection.getToPluginId().equals(fst); - - return oneWay || (connection.isBidirectional() && otherWay); - }); - } - - public Optional getCompiler() { - List meta = Optional.ofNullable(pluginsByType.get(PLUGIN_TYPE.COMPILER)).orElse(Collections.emptyList()); - return meta.stream().map(m -> (Compiler) m.pluginInstance).findFirst(); - } - - public Optional getCPU() { - List meta = Optional.ofNullable(pluginsByType.get(PLUGIN_TYPE.CPU)).orElse(Collections.emptyList()); - return meta.stream().map(m -> (CPU) m.pluginInstance).findFirst(); - } - - public Optional getMemory() { - List meta = Optional.ofNullable(pluginsByType.get(PLUGIN_TYPE.MEMORY)).orElse(Collections.emptyList()); - return meta.stream().map(m -> (Memory) m.pluginInstance).findFirst(); - } - - public List getDevices() { - List meta = Optional.ofNullable(pluginsByType.get(PLUGIN_TYPE.DEVICE)).orElse(Collections.emptyList()); - return meta.stream().map(m -> (Device) m.pluginInstance).collect(Collectors.toList()); - } - - @Override - public void close() { - computerConfig.close(); - } - public static VirtualComputer create(ComputerConfig computerConfig, ApplicationApi applicationApi, AppSettings appSettings) throws IOException, InvalidPluginException { Map plugins = loadPlugins(computerConfig, applicationApi, appSettings); @@ -148,22 +86,22 @@ public static VirtualComputer create(ComputerConfig computerConfig, ApplicationA } private static Map loadPlugins( - ComputerConfig computerConfig, - ApplicationApi applicationApi, - AppSettings appSettings + ComputerConfig computerConfig, + ApplicationApi applicationApi, + AppSettings appSettings ) throws IOException, InvalidPluginException { List pluginConfigs = Stream.of( - computerConfig.getCompiler(), - computerConfig.getCPU(), - computerConfig.getMemory() - ).map(opt -> opt.map(List::of).orElse(Collections.emptyList())) - .flatMap(List::stream) - .collect(Collectors.toList()); + computerConfig.getCompiler(), + computerConfig.getCPU(), + computerConfig.getMemory() + ).map(opt -> opt.map(List::of).orElse(Collections.emptyList())) + .flatMap(List::stream) + .collect(Collectors.toList()); pluginConfigs.addAll(computerConfig.getDevices()); List filesToLoad = pluginConfigs.stream() - .map(c -> c.getPluginPath().toFile()) - .collect(Collectors.toList()); + .map(c -> c.getPluginPath().toFile()) + .collect(Collectors.toList()); LOGGER.debug("Loading plugin files: {}", filesToLoad); @@ -174,11 +112,11 @@ private static Map loadPlugins( } private static Map constructPlugins( - List> pluginClasses, - List pluginConfigs, - ApplicationApi applicationApi, - AppSettings appSettings, - Runnable save + List> pluginClasses, + List pluginConfigs, + ApplicationApi applicationApi, + AppSettings appSettings, + Runnable save ) throws InvalidPluginException { Map plugins = new HashMap<>(); @@ -188,18 +126,18 @@ private static Map constructPlugins( Class pluginClass = pluginClasses.get(i); PluginConfig pluginConfig = pluginConfigs.get(i); PluginSettings pluginSettings = new PluginSettingsImpl( - pluginConfig.getPluginSettings(), appSettings, save + pluginConfig.getPluginSettings(), appSettings, save ); if (!doesImplement(pluginClass, pluginInterfaces.get(pluginConfig.getPluginType()))) { throw new InvalidPluginException( - "Plugin" + pluginConfig.getPluginName() + " does not implement interface " + pluginClass.getName() + "Plugin" + pluginConfig.getPluginName() + " does not implement interface " + pluginClass.getName() ); } long pluginId = pluginIdCounter.getAndIncrement(); Plugin pluginInstance = Unchecked.call( - () -> createPluginInstance(pluginId, pluginClass, applicationApi, pluginSettings) + () -> createPluginInstance(pluginId, pluginClass, applicationApi, pluginSettings) ); PluginMeta pluginMeta = new PluginMeta(pluginSettings, pluginInstance, pluginConfig); @@ -223,6 +161,71 @@ private static Plugin createPluginInstance(long pluginID, Class pluginsToInitialize = Stream.of( + pluginsByType.getOrDefault(PLUGIN_TYPE.COMPILER, Collections.emptyList()), + pluginsByType.getOrDefault(PLUGIN_TYPE.MEMORY, Collections.emptyList()), + pluginsByType.getOrDefault(PLUGIN_TYPE.CPU, Collections.emptyList()), + pluginsByType.getOrDefault(PLUGIN_TYPE.DEVICE, Collections.emptyList()) + ).flatMap(Collection::stream).collect(Collectors.toList()); + + for (PluginMeta pluginMeta : pluginsToInitialize) { + pluginMeta.pluginInstance.initialize(); + } + } + + public void reset() { + getCompiler().ifPresent(Compiler::reset); + getMemory().ifPresentOrElse(memory -> { + getCPU().ifPresent(cpu -> cpu.reset(memory.getProgramLocation())); + memory.reset(); + }, () -> getCPU().ifPresent(CPU::reset)); + getDevices().forEach(Device::reset); + } + + @Override + public boolean isConnected(long pluginA, long pluginB) { + String fst = pluginsById.get(pluginA).pluginConfig.getPluginId(); + String snd = pluginsById.get(pluginB).pluginConfig.getPluginId(); + + return computerConfig.getConnections().stream().anyMatch(connection -> { + boolean oneWay = connection.getFromPluginId().equals(fst) && connection.getToPluginId().equals(snd); + boolean otherWay = connection.getFromPluginId().equals(snd) && connection.getToPluginId().equals(fst); + + return oneWay || (connection.isBidirectional() && otherWay); + }); + } + + public Optional getCompiler() { + List meta = Optional.ofNullable(pluginsByType.get(PLUGIN_TYPE.COMPILER)).orElse(Collections.emptyList()); + return meta.stream().map(m -> (Compiler) m.pluginInstance).findFirst(); + } + + public Optional getCPU() { + List meta = Optional.ofNullable(pluginsByType.get(PLUGIN_TYPE.CPU)).orElse(Collections.emptyList()); + return meta.stream().map(m -> (CPU) m.pluginInstance).findFirst(); + } + + public Optional getMemory() { + List meta = Optional.ofNullable(pluginsByType.get(PLUGIN_TYPE.MEMORY)).orElse(Collections.emptyList()); + return meta.stream().map(m -> (Memory) m.pluginInstance).findFirst(); + } + + public List getDevices() { + List meta = Optional.ofNullable(pluginsByType.get(PLUGIN_TYPE.DEVICE)).orElse(Collections.emptyList()); + return meta.stream().map(m -> (Device) m.pluginInstance).collect(Collectors.toList()); + } + + @Override + public void close() { + computerConfig.close(); + } + static class PluginMeta { final PluginSettings pluginSettings; final Plugin pluginInstance; diff --git a/application/src/main/resources/net/emustudio/application/version.properties b/application/src/main/resources/net/emustudio/application/version.properties index e606f2a3e..6592047b6 100644 --- a/application/src/main/resources/net/emustudio/application/version.properties +++ b/application/src/main/resources/net/emustudio/application/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/application/src/test/java/net/emustudio/application/emulation/EmulationControllerTest.java b/application/src/test/java/net/emustudio/application/emulation/EmulationControllerTest.java index 556469a42..da1fd5c87 100644 --- a/application/src/test/java/net/emustudio/application/emulation/EmulationControllerTest.java +++ b/application/src/test/java/net/emustudio/application/emulation/EmulationControllerTest.java @@ -215,7 +215,7 @@ public void testResetCallsDevicesReset() throws Exception { replay(dev1, dev2); EmulationController controller = new EmulationController( - cpuStub, null, Arrays.asList(dev1, dev2) + cpuStub, null, Arrays.asList(dev1, dev2) ); awaitFor(controller::reset, 1); diff --git a/application/src/test/java/net/emustudio/application/gui/debugtable/MockHelper.java b/application/src/test/java/net/emustudio/application/gui/debugtable/MockHelper.java index 0680c476c..6c608c61d 100644 --- a/application/src/test/java/net/emustudio/application/gui/debugtable/MockHelper.java +++ b/application/src/test/java/net/emustudio/application/gui/debugtable/MockHelper.java @@ -26,7 +26,7 @@ import java.util.List; import java.util.function.Consumer; -import static net.emustudio.application.gui.debugtable.PaginatingDisassembler.*; +import static net.emustudio.application.gui.debugtable.PaginatingDisassembler.INSTR_PER_PAGE; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -125,16 +125,16 @@ static PaginatingDisassembler makeDisassemblerWithFixedSizedInstructions(int cur if (maxKnownPage == 0) { when(callFlow.getLocations(pageMin, pageCurr)) - .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, pageMin)); + .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, pageMin)); when(callFlow.getLocations(pageCurr, pageMax)) - .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, pageCurr)); + .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, pageCurr)); } while (maxKnownPage != 0) { when(callFlow.getLocations(pageMin, pageCurr)) - .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, pageMin)); + .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, pageMin)); when(callFlow.getLocations(pageCurr, pageMax)) - .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, pageCurr)); + .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, pageCurr)); int nextPageMin = pageMax; int nextPageCurr = pageCurr + instructionsSize * (INSTR_PER_PAGE - 1); @@ -151,14 +151,14 @@ static PaginatingDisassembler makeDisassemblerWithFixedSizedInstructions(int cur } when(callFlow.getLocations(nextPageMin, nextPageCurr)) - .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, nextPageMin)); + .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, nextPageMin)); if (nextPageCurr > pageCurr) { expectTraverse(pageCurr, nextPageCurr, instructionsSize); } else if (nextPageCurr < pageCurr) { expectTraverse(nextPageCurr, pageCurr, instructionsSize); } when(callFlow.getLocations(nextPageCurr, nextPageCurr + instructionsSize * INSTR_PER_HALF_PAGE)) - .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, nextPageCurr)); + .thenReturn(instructions(instructionsSize, INSTR_PER_HALF_PAGE + 1, nextPageCurr)); pageMin = nextPageMin; pageCurr = nextPageCurr; diff --git a/application/src/test/java/net/emustudio/application/gui/debugtable/PaginatingDisassemblerTest.java b/application/src/test/java/net/emustudio/application/gui/debugtable/PaginatingDisassemblerTest.java index b9d39a627..36bb966fe 100644 --- a/application/src/test/java/net/emustudio/application/gui/debugtable/PaginatingDisassemblerTest.java +++ b/application/src/test/java/net/emustudio/application/gui/debugtable/PaginatingDisassemblerTest.java @@ -22,7 +22,7 @@ import org.junit.Test; import static net.emustudio.application.gui.debugtable.MockHelper.*; -import static net.emustudio.application.gui.debugtable.PaginatingDisassembler.*; +import static net.emustudio.application.gui.debugtable.PaginatingDisassembler.INSTR_PER_PAGE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; @@ -57,16 +57,16 @@ public void testPageZeroOneBelowCurrentInstructionIsUnknown() { int page0min = page0curr - HALF_PAGE_MAX_BYTES; callFlow = mockCallFlow( - page0min, - page0curr, - CURRENT_INSTR + page0min, + page0curr, + CURRENT_INSTR ); PaginatingDisassembler asm = new PaginatingDisassembler(callFlow, MEMORY_SIZE); assertEquals( - -1, - asm.rowToLocation(CURRENT_INSTR, INSTR_PER_HALF_PAGE - 1) + -1, + asm.rowToLocation(CURRENT_INSTR, INSTR_PER_HALF_PAGE - 1) ); } @@ -76,119 +76,119 @@ public void testPageZeroOneAboveCurrentInstructionIsUnknown() { int page0max = page0curr + HALF_PAGE_MAX_BYTES; callFlow = mockCallFlow( - page0curr, - page0max, - CURRENT_INSTR + page0curr, + page0max, + CURRENT_INSTR ); PaginatingDisassembler asm = new PaginatingDisassembler(callFlow, MEMORY_SIZE); assertEquals( - -1, - asm.rowToLocation(CURRENT_INSTR, INSTR_PER_HALF_PAGE + 1) + -1, + asm.rowToLocation(CURRENT_INSTR, INSTR_PER_HALF_PAGE + 1) ); } @Test public void testPageZeroOneBelowCurrentInstructionIsKnown() { PaginatingDisassembler asm = makeDisassemblerWithFixedSizedInstructions( - CURRENT_INSTR, 0, 1, true + CURRENT_INSTR, 0, 1, true ); assertEquals( - CURRENT_INSTR - 1, - asm.rowToLocation(CURRENT_INSTR, INSTR_PER_HALF_PAGE - 1) + CURRENT_INSTR - 1, + asm.rowToLocation(CURRENT_INSTR, INSTR_PER_HALF_PAGE - 1) ); } @Test public void testPageZeroFirstRow() { PaginatingDisassembler asm = makeDisassemblerWithFixedSizedInstructions( - CURRENT_INSTR, 0, LONGEST_INSTR, true + CURRENT_INSTR, 0, LONGEST_INSTR, true ); int page0min = CURRENT_INSTR - HALF_PAGE_MAX_BYTES; assertEquals( - page0min, - asm.rowToLocation(CURRENT_INSTR, 0) + page0min, + asm.rowToLocation(CURRENT_INSTR, 0) ); } @Test public void testPageZeroLastRow() { PaginatingDisassembler asm = makeDisassemblerWithFixedSizedInstructions( - CURRENT_INSTR, 0, LONGEST_INSTR, true + CURRENT_INSTR, 0, LONGEST_INSTR, true ); int page0max = CURRENT_INSTR + HALF_PAGE_MAX_BYTES; assertEquals( - page0max, - asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) + page0max, + asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) ); } @Test public void testPageOneFirstRow() { PaginatingDisassembler asm = makeDisassemblerWithFixedSizedInstructions( - CURRENT_INSTR, 1, LONGEST_INSTR, true + CURRENT_INSTR, 1, LONGEST_INSTR, true ); int page1min = CURRENT_INSTR + HALF_PAGE_MAX_BYTES; assertEquals( - page1min, // last instruction from previous page is present here - asm.rowToLocation(CURRENT_INSTR, 0) + page1min, // last instruction from previous page is present here + asm.rowToLocation(CURRENT_INSTR, 0) ); } @Test public void testPageOneLastRow() { PaginatingDisassembler asm = makeDisassemblerWithFixedSizedInstructions( - CURRENT_INSTR, 1, LONGEST_INSTR, true + CURRENT_INSTR, 1, LONGEST_INSTR, true ); int page1max = CURRENT_INSTR + LONGEST_INSTR * (INSTR_PER_PAGE - 1) + HALF_PAGE_MAX_BYTES; assertEquals( - page1max, // last instruction from previous page is present here - asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) + page1max, // last instruction from previous page is present here + asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) ); } @Test public void testPageTwoFirstRow() { PaginatingDisassembler asm = makeDisassemblerWithFixedSizedInstructions( - CURRENT_INSTR, 2, LONGEST_INSTR, true + CURRENT_INSTR, 2, LONGEST_INSTR, true ); int page2min = CURRENT_INSTR + LONGEST_INSTR * (INSTR_PER_PAGE - 1) + HALF_PAGE_MAX_BYTES; assertEquals( - page2min, - asm.rowToLocation(CURRENT_INSTR, 0) + page2min, + asm.rowToLocation(CURRENT_INSTR, 0) ); } @Test public void testPageTwoLastRow() { PaginatingDisassembler asm = makeDisassemblerWithFixedSizedInstructions( - CURRENT_INSTR, 2, LONGEST_INSTR, true + CURRENT_INSTR, 2, LONGEST_INSTR, true ); int page2max = CURRENT_INSTR + 2 * LONGEST_INSTR * (INSTR_PER_PAGE - 1) + HALF_PAGE_MAX_BYTES; assertEquals( - page2max, - asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) + page2max, + asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) ); } @Test public void testPageOneFirstRowWhenCurrentInstructionIs0AndInstructionSizeIs4() { PaginatingDisassembler asm = makeDisassemblerWithFixedSizedInstructions( - 0, 1, 4, true + 0, 1, 4, true ); int page1min = INSTR_PER_HALF_PAGE * 4; assertEquals( - page1min, - asm.rowToLocation(0, 0) + page1min, + asm.rowToLocation(0, 0) ); } @@ -198,7 +198,7 @@ public void testCurrentLocationDifferenceBetweenPagesIsCorrect() { // pagePrevMax = pageNextMin PaginatingDisassembler asm = makeDisassemblerWithFixedSizedInstructions( - CURRENT_INSTR, 2, LONGEST_INSTR, true + CURRENT_INSTR, 2, LONGEST_INSTR, true ); int page2curr = asm.rowToLocation(CURRENT_INSTR, INSTR_PER_HALF_PAGE); @@ -214,7 +214,7 @@ public void testCurrentLocationDifferenceBetweenPagesIsCorrect() { @Test public void testPageMinusOneLastRowNotEnoughInstructions() { PaginatingDisassembler asm = makeDisassemblerWithFixedSizedInstructions( - 10, -1, LONGEST_INSTR, false + 10, -1, LONGEST_INSTR, false ); int pageM1max = 10 - LONGEST_INSTR * INSTR_PER_HALF_PAGE; @@ -222,8 +222,8 @@ public void testPageMinusOneLastRowNotEnoughInstructions() { assertTrue(missingInstructions < 0); assertEquals( - pageM1max - missingInstructions, // prefer number of instructions shown must fit - asm.rowToLocation(10, INSTR_PER_PAGE - 1) + pageM1max - missingInstructions, // prefer number of instructions shown must fit + asm.rowToLocation(10, INSTR_PER_PAGE - 1) ); } @@ -237,8 +237,8 @@ public void testPageMinusOneFirstRowNotEnoughInstructions() { asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1); assertEquals( - -1, // prefer number of instructions shown must fit - asm.rowToLocation(50, 0) + -1, // prefer number of instructions shown must fit + asm.rowToLocation(50, 0) ); } @@ -246,12 +246,12 @@ public void testPageMinusOneFirstRowNotEnoughInstructions() { @Ignore public void testPageMinusOneCurrentRowNotEnoughInstructions() { PaginatingDisassembler asm = makeDisassemblerWithFixedSizedInstructions( - 10, -1, LONGEST_INSTR, false + 10, -1, LONGEST_INSTR, false ); assertEquals( - 0, - asm.rowToLocation(10, INSTR_PER_HALF_PAGE) + 0, + asm.rowToLocation(10, INSTR_PER_HALF_PAGE) ); } @@ -263,14 +263,14 @@ public void testPageZeroInstructionStepped() { assertEquals(-1, asm.rowToLocation(CURRENT_INSTR, 0)); assertEquals(CURRENT_INSTR, asm.rowToLocation(CURRENT_INSTR, INSTR_PER_HALF_PAGE)); assertEquals( - CURRENT_INSTR + INSTR_PER_HALF_PAGE, asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) + CURRENT_INSTR + INSTR_PER_HALF_PAGE, asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) ); assertEquals(CURRENT_INSTR, asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_HALF_PAGE - 1)); assertEquals(CURRENT_INSTR + 1, asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_HALF_PAGE)); assertEquals( - CURRENT_INSTR + INSTR_PER_HALF_PAGE + 1, - asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_PAGE - 1) + CURRENT_INSTR + INSTR_PER_HALF_PAGE + 1, + asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_PAGE - 1) ); } @@ -285,23 +285,23 @@ public void testPageOneInstructionStepped() { assertEquals(CURRENT_INSTR + INSTR_PER_HALF_PAGE, asm.rowToLocation(CURRENT_INSTR, 0)); assertEquals(CURRENT_INSTR + INSTR_PER_PAGE - 1, asm.rowToLocation(CURRENT_INSTR, INSTR_PER_HALF_PAGE)); assertEquals( - CURRENT_INSTR + INSTR_PER_PAGE - 1 + INSTR_PER_HALF_PAGE, - asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) + CURRENT_INSTR + INSTR_PER_PAGE - 1 + INSTR_PER_HALF_PAGE, + asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) ); // instruction step assertEquals( - CURRENT_INSTR + INSTR_PER_HALF_PAGE + 1, - asm.rowToLocation(CURRENT_INSTR + 1, 0) + CURRENT_INSTR + INSTR_PER_HALF_PAGE + 1, + asm.rowToLocation(CURRENT_INSTR + 1, 0) ); assertEquals( - CURRENT_INSTR + INSTR_PER_PAGE, - asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_HALF_PAGE) + CURRENT_INSTR + INSTR_PER_PAGE, + asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_HALF_PAGE) ); assertEquals( - CURRENT_INSTR + INSTR_PER_PAGE + INSTR_PER_HALF_PAGE, - asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_PAGE - 1) + CURRENT_INSTR + INSTR_PER_PAGE + INSTR_PER_HALF_PAGE, + asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_PAGE - 1) ); } @@ -318,22 +318,22 @@ public void testPageMinusOneInstructionStepped() { assertEquals(CURRENT_INSTR - INSTR_PER_PAGE + 1 - INSTR_PER_HALF_PAGE, asm.rowToLocation(CURRENT_INSTR, 0)); assertEquals(CURRENT_INSTR - INSTR_PER_PAGE + 1, asm.rowToLocation(CURRENT_INSTR, INSTR_PER_HALF_PAGE)); assertEquals( - CURRENT_INSTR - INSTR_PER_HALF_PAGE, - asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) + CURRENT_INSTR - INSTR_PER_HALF_PAGE, + asm.rowToLocation(CURRENT_INSTR, INSTR_PER_PAGE - 1) ); // instruction step assertEquals( - CURRENT_INSTR - INSTR_PER_PAGE + 2 - INSTR_PER_HALF_PAGE, - asm.rowToLocation(CURRENT_INSTR + 1, 0) + CURRENT_INSTR - INSTR_PER_PAGE + 2 - INSTR_PER_HALF_PAGE, + asm.rowToLocation(CURRENT_INSTR + 1, 0) ); assertEquals( - CURRENT_INSTR - INSTR_PER_PAGE + 2, - asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_HALF_PAGE) + CURRENT_INSTR - INSTR_PER_PAGE + 2, + asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_HALF_PAGE) ); assertEquals( - CURRENT_INSTR - INSTR_PER_HALF_PAGE + 1, - asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_PAGE - 1) + CURRENT_INSTR - INSTR_PER_HALF_PAGE + 1, + asm.rowToLocation(CURRENT_INSTR + 1, INSTR_PER_PAGE - 1) ); } diff --git a/application/src/test/java/net/emustudio/application/settings/ComputerConfigTest.java b/application/src/test/java/net/emustudio/application/settings/ComputerConfigTest.java index c76097ce5..09ba5617a 100644 --- a/application/src/test/java/net/emustudio/application/settings/ComputerConfigTest.java +++ b/application/src/test/java/net/emustudio/application/settings/ComputerConfigTest.java @@ -46,7 +46,7 @@ public void setup() throws IOException { Path configFile = temporaryFolder.newFile("computer.toml").toPath(); Files.deleteIfExists(configFile); config = ComputerConfig.create( - "some nice computer!! baby@#$%^&*()./<>?\"'", configFile + "some nice computer!! baby@#$%^&*()./<>?\"'", configFile ); } @@ -69,7 +69,7 @@ public void testNewConfigHasEverythingEmpty() { @Test public void testChangePluginConfig() { PluginConfig cpu = PluginConfig.create( - "someId", PLUGIN_TYPE.CPU, "cpu baby", "emptyfile.jar", P.of(10, 10), Config.inMemory() + "someId", PLUGIN_TYPE.CPU, "cpu baby", "emptyfile.jar", P.of(10, 10), Config.inMemory() ); config.setCPU(cpu); @@ -79,7 +79,7 @@ public void testChangePluginConfig() { assertEquals(cpu.getPluginFile(), "emptyfile.jar"); assertEquals(cpu.getSchemaPoint(), SchemaPoint.of(10, 10)); - SchemaPoint newSchemaPoint = SchemaPoint.of(20,30); + SchemaPoint newSchemaPoint = SchemaPoint.of(20, 30); cpu.setSchemaPoint(newSchemaPoint); assertEquals(cpu.getSchemaPoint(), newSchemaPoint); } diff --git a/application/src/test/java/net/emustudio/application/settings/PluginConfigTest.java b/application/src/test/java/net/emustudio/application/settings/PluginConfigTest.java index f558e5fb1..f836081ed 100644 --- a/application/src/test/java/net/emustudio/application/settings/PluginConfigTest.java +++ b/application/src/test/java/net/emustudio/application/settings/PluginConfigTest.java @@ -33,8 +33,8 @@ public class PluginConfigTest { @Test public void testAbsolutePathInPluginConfigWontBeRelativized() { PluginConfig config = PluginConfig.create( - "xx", PLUGIN_TYPE.CPU, "myName", System.getProperty("user.dir") + File.separator + "path.jar", - P.of(0, 0), Config.inMemory() + "xx", PLUGIN_TYPE.CPU, "myName", System.getProperty("user.dir") + File.separator + "path.jar", + P.of(0, 0), Config.inMemory() ); assertEquals(Path.of(System.getProperty("user.dir") + File.separator + "path.jar"), config.getPluginPath()); } @@ -42,7 +42,7 @@ public void testAbsolutePathInPluginConfigWontBeRelativized() { @Test public void testRelativePathInPluginConfigWillBeRelativized() { PluginConfig config = PluginConfig.create( - "xx", PLUGIN_TYPE.CPU, "myName", "relativepath.jar", P.of(0, 0), Config.inMemory() + "xx", PLUGIN_TYPE.CPU, "myName", "relativepath.jar", P.of(0, 0), Config.inMemory() ); assertEquals(Path.of(System.getProperty("user.dir"), "cpu", "relativepath.jar"), config.getPluginPath()); } diff --git a/application/src/test/java/net/emustudio/application/settings/SchemaPointTest.java b/application/src/test/java/net/emustudio/application/settings/SchemaPointTest.java index 6757b033d..16e9da72e 100644 --- a/application/src/test/java/net/emustudio/application/settings/SchemaPointTest.java +++ b/application/src/test/java/net/emustudio/application/settings/SchemaPointTest.java @@ -27,12 +27,12 @@ public class SchemaPointTest { @Test public void testParse() { - assertEquals(SchemaPoint.parse("10,56"), SchemaPoint.of(10,56)); + assertEquals(SchemaPoint.parse("10,56"), SchemaPoint.of(10, 56)); } @Test public void testParseWithSpaces() { - assertEquals(SchemaPoint.parse(" 30 , 5 "), SchemaPoint.of(30,5)); + assertEquals(SchemaPoint.parse(" 30 , 5 "), SchemaPoint.of(30, 5)); } @Test(expected = IndexOutOfBoundsException.class) diff --git a/application/src/test/java/net/emustudio/application/virtualcomputer/ContextPoolImplTest.java b/application/src/test/java/net/emustudio/application/virtualcomputer/ContextPoolImplTest.java index 20feafc6e..3ba68dfb0 100644 --- a/application/src/test/java/net/emustudio/application/virtualcomputer/ContextPoolImplTest.java +++ b/application/src/test/java/net/emustudio/application/virtualcomputer/ContextPoolImplTest.java @@ -65,10 +65,10 @@ public void setUp() { shortDeviceContextMock = EasyMock.createNiceMock(DeviceContextStub.class); shortDeviceContextMockAnother = EasyMock.createNiceMock(DeviceContextStub.class); replay( - cpuContextMock, cpuContextMockAnother, - shortMemoryContextMock, shortMemoryContextMockAnother, - compilerContextMock, compilerContextMockAnother, - shortDeviceContextMock, shortDeviceContextMockAnother + cpuContextMock, cpuContextMockAnother, + shortMemoryContextMock, shortMemoryContextMockAnother, + compilerContextMock, compilerContextMockAnother, + shortDeviceContextMock, shortDeviceContextMockAnother ); contextPool = new ContextPoolImpl(emuStudioId); @@ -371,26 +371,18 @@ public void testCannotGetGeneralInterfaceWhenNotRegisteredDevice() throws Except // - @PluginContext - interface ByteMemoryContext extends MemoryContext {} - @Test public void testRegisterWithDifferentDataTypeThanGetMemory() throws Exception { contextPool.register(0, shortMemoryContextMock, MemoryContext.class); assertEquals(shortMemoryContextMock, contextPool.getMemoryContext(1, ByteMemoryContext.class)); } - @PluginContext - interface ByteDeviceContext extends DeviceContext {} - @Test public void testRegisterWithDifferentDataTypeThanGetDevice() throws Exception { contextPool.register(0, shortDeviceContextMock, DeviceContext.class); assertEquals(shortDeviceContextMock, contextPool.getDeviceContext(1, ByteDeviceContext.class)); } - // - @Test(expected = InvalidContextException.class) public void testRegisterWrongInterfaceCPU() throws Exception { contextPool.register(1, cpuContextMock, MemoryContext.class); @@ -401,6 +393,8 @@ public void testRegisterWrongInterfaceMemory() throws Exception { contextPool.register(1, shortMemoryContextMock, CPUContext.class); } + // + @Test(expected = InvalidContextException.class) public void testRegisterWrongInterfaceCompiler() throws Exception { contextPool.register(1, compilerContextMock, CPUContext.class); @@ -411,26 +405,26 @@ public void testRegisterWrongInterfaceDevice() throws Exception { contextPool.register(1, shortDeviceContextMock, CPUContext.class); } - // - @Test(expected = InvalidContextException.class) public void testUnannotatedContextInterface() throws Exception { Context unannotatedContext = EasyMock.createNiceMock(UnannotatedContextStub.class); contextPool.register(0, unannotatedContext, UnannotatedContextStub.class); } - // - @Test(expected = NullPointerException.class) public void testGetNullCPU() throws Exception { contextPool.getCPUContext(0, null); } + // + @Test(expected = NullPointerException.class) public void testGetNullCompiler() throws Exception { contextPool.getCompilerContext(1, null); } + // + @Test(expected = NullPointerException.class) public void testGetNullMemory() throws Exception { contextPool.getMemoryContext(2, null); @@ -441,8 +435,6 @@ public void testGetNullDevice() throws Exception { contextPool.getDeviceContext(3, null); } - // - @Test public void testUnregisterDifferentContextCPU() throws Exception { contextPool.register(0, cpuContextMock, CPUContext.class); @@ -455,6 +447,8 @@ public void testUnregisterDifferentContextMemory() throws Exception { assertFalse(contextPool.unregister(0, CPUContext.class)); } + // + @Test public void testUnregisterDifferentContextCompiler() throws Exception { contextPool.register(0, compilerContextMock, CompilerContext.class); @@ -467,8 +461,6 @@ public void testUnregisterDifferentContextDevice() throws Exception { assertFalse(contextPool.unregister(0, CPUContext.class)); } - // - @Test public void testGetByEmuStudio() throws Exception { contextPool.setComputer(new ComputerStub(false)); @@ -476,6 +468,15 @@ public void testGetByEmuStudio() throws Exception { assertEquals(cpuContextMock, contextPool.getCPUContext(emuStudioId)); } + @PluginContext + interface ByteMemoryContext extends MemoryContext { + } + + // + + @PluginContext + interface ByteDeviceContext extends DeviceContext { + } private static class ComputerStub implements PluginConnections { private final boolean connected; diff --git a/application/src/test/java/net/emustudio/application/virtualcomputer/PluginLoaderTest.java b/application/src/test/java/net/emustudio/application/virtualcomputer/PluginLoaderTest.java index 5dae587f0..66dc7ed98 100644 --- a/application/src/test/java/net/emustudio/application/virtualcomputer/PluginLoaderTest.java +++ b/application/src/test/java/net/emustudio/application/virtualcomputer/PluginLoaderTest.java @@ -115,7 +115,7 @@ public void testInvalidPluginConstructorThrows() throws Exception { } private File createJar(String className, String... dependsOn) throws IOException, URISyntaxException { - File file = temporaryFolder.newFile(className.replaceAll("/",".").concat(".jar")); + File file = temporaryFolder.newFile(className.replaceAll("/", ".").concat(".jar")); JarCreator jarCreator = new JarCreator(); file.getParentFile().mkdirs(); @@ -139,7 +139,7 @@ public void testDependenciesAreLoadedCorrectly() throws Exception { Constructor constructor = cl.getDeclaredConstructor(long.class, ApplicationApi.class, PluginSettings.class); cl.getDeclaredMethod("hi").invoke(constructor.newInstance( - 0L, createNiceMock(ApplicationApi.class), createNiceMock(PluginSettings.class) + 0L, createNiceMock(ApplicationApi.class), createNiceMock(PluginSettings.class) )); } } diff --git a/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/CPUImplStub.java b/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/CPUImplStub.java index 070df0772..33d9dee86 100644 --- a/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/CPUImplStub.java +++ b/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/CPUImplStub.java @@ -31,7 +31,8 @@ @PluginRoot(title = "CPU", type = PLUGIN_TYPE.CPU) public class CPUImplStub extends AbstractCPUStub { - public CPUImplStub(long pluginID, ApplicationApi applicationApi, PluginSettings settings) {} + public CPUImplStub(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { + } @Override public void addCPUListener(CPUListener listener) { diff --git a/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/UnannotatedCPUStub.java b/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/UnannotatedCPUStub.java index 8793f22ea..05b62ab01 100644 --- a/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/UnannotatedCPUStub.java +++ b/application/src/test/java/net/emustudio/application/virtualcomputer/stubs/UnannotatedCPUStub.java @@ -27,7 +27,8 @@ public class UnannotatedCPUStub implements CPU { - public UnannotatedCPUStub(long pluginID, ApplicationApi applicationApi, PluginSettings pluginSettings) {} + public UnannotatedCPUStub(long pluginID, ApplicationApi applicationApi, PluginSettings pluginSettings) { + } @Override public void addCPUListener(CPUListener listener) { diff --git a/build.gradle b/build.gradle index e4f3b1fb3..ede389050 100644 --- a/build.gradle +++ b/build.gradle @@ -22,33 +22,33 @@ import java.text.SimpleDateFormat apply from: 'test_report.gradle' ext.versions = [ - slf4j: '1.7.30' + slf4j: '1.7.30' ] ext.libs = [ - emuLib : "net.emustudio:emulib:11.7.0-SNAPSHOT", - cpuTestSuite : "net.emustudio:cpu-testsuite_11.6:1.2.0-SNAPSHOT", + emuLib : "net.emustudio:emulib:11.7.0-SNAPSHOT", + cpuTestSuite : "net.emustudio:cpu-testsuite_11.6:1.2.0-SNAPSHOT", - javaCupRuntime : "com.github.vbmacher:java-cup-runtime:11b-20160615", - jcipAnnotations: "net.jcip:jcip-annotations:1.0", - antlrRuntime : "org.antlr:antlr4-runtime:4.9.2", + javaCupRuntime : "com.github.vbmacher:java-cup-runtime:11b-20160615", + jcipAnnotations : "net.jcip:jcip-annotations:1.0", + antlrRuntime : "org.antlr:antlr4-runtime:4.11.1", - slf4JApi : "org.slf4j:slf4j-api:${versions.slf4j}", - slf4JSimple : "org.slf4j:slf4j-simple:${versions.slf4j}", - slf4JNop : "org.slf4j:slf4j-nop:${versions.slf4j}", - logback : "ch.qos.logback:logback-classic:1.2.3", + slf4JApi : "org.slf4j:slf4j-api:${versions.slf4j}", + slf4JSimple : "org.slf4j:slf4j-simple:${versions.slf4j}", + slf4JNop : "org.slf4j:slf4j-nop:${versions.slf4j}", + logback : "ch.qos.logback:logback-classic:1.2.3", - picocli : "info.picocli:picocli:4.6.3", - picocliAnnotation: "info.picocli:picocli-codegen:4.6.3", + picocli : "info.picocli:picocli:4.7.0", + picocliAnnotation: "info.picocli:picocli-codegen:4.7.0", - tomlj : "com.electronwill.night-config:toml:3.6.5", + tomlj : "com.electronwill.night-config:toml:3.6.5", - editor : "com.fifesoft:rsyntaxtextarea:3.1.6", - editorDialogs : "com.fifesoft:rstaui:3.1.4", + editor : "com.fifesoft:rsyntaxtextarea:3.1.6", + editorDialogs : "com.fifesoft:rstaui:3.1.4", - junit : "junit:junit:4.13", - easyMock : "org.easymock:easymock:4.2", - mockito : "org.mockito:mockito-all:1.10.19" + junit : "junit:junit:4.13", + easyMock : "org.easymock:easymock:4.2", + mockito : "org.mockito:mockito-all:1.10.19" ] allprojects { @@ -68,22 +68,22 @@ allprojects { def libClassPath = { def libs = configurations.runtimeClasspath.files.collect { "lib/" + it.getName() } + - configurations.compilerLib.files.collect { "compiler/" + it.getName() } + - configurations.memoryLib.files.collect { "memory/" + it.getName() } + - configurations.deviceLib.files.collect { "device/" + it.getName() } + - configurations.cpuLib.files.collect { "cpu/" + it.getName() } + configurations.compilerLib.files.collect { "compiler/" + it.getName() } + + configurations.memoryLib.files.collect { "memory/" + it.getName() } + + configurations.deviceLib.files.collect { "device/" + it.getName() } + + configurations.cpuLib.files.collect { "cpu/" + it.getName() } return libs.join(' ') } ext.manifestAttributes = { String mainClass -> def baseAttributes = [ - 'Class-Path' : libClassPath(), - "Implementation-Title" : project.name, - "Implementation-Version": project.version, - 'Build-Timestamp' : new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()), - 'Build-Jdk' : "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})", - 'Build-OS' : "${System.properties['os.name']} ${System.properties['os.arch']} ${System.properties['os.version']}" + 'Class-Path' : libClassPath(), + "Implementation-Title" : project.name, + "Implementation-Version": project.version, + 'Build-Timestamp' : new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()), + 'Build-Jdk' : "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})", + 'Build-OS' : "${System.properties['os.name']} ${System.properties['os.arch']} ${System.properties['os.version']}" ] if (mainClass != null && mainClass != '') { diff --git a/plugins/compiler/as-8080/build.gradle b/plugins/compiler/as-8080/build.gradle index 9e1405c42..7c6dbeb91 100644 --- a/plugins/compiler/as-8080/build.gradle +++ b/plugins/compiler/as-8080/build.gradle @@ -53,7 +53,7 @@ sourceSets { } main { java.srcDirs = [ - 'src/main/java', "${buildDir}/generated-src/antlr/main" + 'src/main/java', "${buildDir}/generated-src/antlr/main" ] } } @@ -75,8 +75,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java index 0e24e15ab..62be35f35 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/Assembler8080.java @@ -30,7 +30,6 @@ import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.emulib.runtime.settings.PluginSettings; -import net.emustudio.plugins.compiler.as8080.visitors.NodeVisitor; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.exceptions.CompileException; import net.emustudio.plugins.compiler.as8080.visitors.*; @@ -47,15 +46,15 @@ import java.util.*; @PluginRoot( - type = PLUGIN_TYPE.COMPILER, - title = "Intel 8080 Assembler" + type = PLUGIN_TYPE.COMPILER, + title = "Intel 8080 Assembler" ) @SuppressWarnings("unused") public class Assembler8080 extends AbstractCompiler { private final static Logger LOGGER = LoggerFactory.getLogger(Assembler8080.class); private final static List SOURCE_FILE_EXTENSIONS = List.of( - new SourceFileExtension("asm", "Assembler source file"), - new SourceFileExtension("inc", "Include file") + new SourceFileExtension("asm", "Assembler source file"), + new SourceFileExtension("inc", "Include file") ); private MemoryContext memory; @@ -73,7 +72,7 @@ public void initialize() { memory = pool.getMemoryContext(pluginID, MemoryContext.class); if (memory.getDataType() != Byte.class) { throw new InvalidContextException( - "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() + "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() ); } } catch (InvalidContextException | ContextNotFoundException e) { @@ -123,16 +122,16 @@ public boolean compile(String inputFileName, String outputFileName) { IntelHEX hex = new IntelHEX(); NodeVisitor[] visitors = new NodeVisitor[]{ - new ExpandIncludesVisitor(), - new CheckDeclarationsVisitor(), - new ExpandMacrosVisitor(), - new SortMacroArgumentsVisitor(), - // macro expansion could bring re-definition of declarations, but we cannot check declarations again - // until the macro is properly integrated (b/c we could see multiple macro defs on multiple calls) - new CheckDeclarationsVisitor(), - new EvaluateExprVisitor(), - new CheckExprSizesVisitor(), - new GenerateCodeVisitor(hex) + new ExpandIncludesVisitor(), + new CheckDeclarationsVisitor(), + new ExpandMacrosVisitor(), + new SortMacroArgumentsVisitor(), + // macro expansion could bring re-definition of declarations, but we cannot check declarations again + // until the macro is properly integrated (b/c we could see multiple macro defs on multiple calls) + new CheckDeclarationsVisitor(), + new EvaluateExprVisitor(), + new CheckExprSizesVisitor(), + new GenerateCodeVisitor(hex) }; for (NodeVisitor visitor : visitors) { @@ -145,8 +144,8 @@ public boolean compile(String inputFileName, String outputFileName) { programLocation = hex.findProgramLocation(); notifyInfo(String.format( - "Compile was successful.\n\tOutput: %s\n\tProgram starts at 0x%s", - outputFileName, RadixUtils.formatWordHexString(programLocation) + "Compile was successful.\n\tOutput: %s\n\tProgram starts at 0x%s", + outputFileName, RadixUtils.formatWordHexString(programLocation) )); if (memory != null) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java index 951f4f8f2..a4dd39f48 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/CompileError.java @@ -63,7 +63,7 @@ public static CompileError infiniteLoopDetected(Node node, String what) { public static CompileError couldNotReadFile(Node node, String filename, IOException e) { return new CompileError( - node, ERROR_CANNOT_READ_FILE, "Could not read file: " + filename + " (" + e.getMessage() + ")" + node, ERROR_CANNOT_READ_FILE, "Could not read file: " + filename + " (" + e.getMessage() + ")" ); } @@ -77,7 +77,7 @@ public static CompileError ambiguousExpression(Node node) { public static CompileError ifExpressionReferencesOwnBlock(Node node) { return new CompileError( - node, ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK, "If expression references declaration in its own block" + node, ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK, "If expression references declaration in its own block" ); } @@ -87,15 +87,15 @@ public static CompileError declarationReferencesItself(Node node) { public static CompileError macroArgumentsDoNotMatch(Node node) { return new CompileError( - node, ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH, "Macro call arguments do not match with defined parameters" + node, ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH, "Macro call arguments do not match with defined parameters" ); } public static CompileError expressionIsBiggerThanExpected(Node node, int expectedBytes, int wasBytes) { return new CompileError( - node, - ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED, - "Expression (" + wasBytes + " bytes) is bigger than expected (" + expectedBytes + " byte(s))" + node, + ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED, + "Expression (" + wasBytes + " bytes) is bigger than expected (" + expectedBytes + " byte(s))" ); } @@ -105,17 +105,17 @@ public static CompileError valueMustBePositive(Node node) { public static CompileError valueOutOfBounds(Node node, int min, int max) { return new CompileError( - node, ERROR_VALUE_OUT_OF_BOUNDS, "Value is out of bounds (min=" + min + ", max=" + max + ")" + node, ERROR_VALUE_OUT_OF_BOUNDS, "Value is out of bounds (min=" + min + ", max=" + max + ")" ); } @Override public String toString() { return "CompileError{" + - "line=" + line + - ", column=" + column + - ", msg='" + msg + '\'' + - ", errorCode=" + errorCode + - '}'; + "line=" + line + + ", column=" + column + + ", msg='" + msg + '\'' + + ", errorCode=" + errorCode + + '}'; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java index 41271e900..f6d3d5e53 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/LexicalAnalyzerImpl.java @@ -29,7 +29,6 @@ import static net.emustudio.plugins.compiler.as8080.As8080Lexer.*; public class LexicalAnalyzerImpl implements LexicalAnalyzer { - private final As8080Lexer lexer; public static final int[] tokenMap = new int[As8080Lexer.EOL + 1]; static { @@ -169,13 +168,13 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[OP_GT] = Token.OPERATOR; tokenMap[OP_GTE] = Token.OPERATOR; - tokenMap[LIT_NUMBER] =Token.LITERAL; - tokenMap[LIT_HEXNUMBER_1] =Token.LITERAL; - tokenMap[LIT_HEXNUMBER_2] =Token.LITERAL; - tokenMap[LIT_OCTNUMBER] =Token.LITERAL; - tokenMap[LIT_BINNUMBER] =Token.LITERAL; - tokenMap[LIT_STRING_1] =Token.LITERAL; - tokenMap[LIT_STRING_2] =Token.LITERAL; + tokenMap[LIT_NUMBER] = Token.LITERAL; + tokenMap[LIT_HEXNUMBER_1] = Token.LITERAL; + tokenMap[LIT_HEXNUMBER_2] = Token.LITERAL; + tokenMap[LIT_OCTNUMBER] = Token.LITERAL; + tokenMap[LIT_BINNUMBER] = Token.LITERAL; + tokenMap[LIT_STRING_1] = Token.LITERAL; + tokenMap[LIT_STRING_2] = Token.LITERAL; tokenMap[ID_IDENTIFIER] = Token.IDENTIFIER; tokenMap[ID_LABEL] = Token.IDENTIFIER; @@ -183,6 +182,8 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[ERROR] = Token.ERROR; } + private final As8080Lexer lexer; + public LexicalAnalyzerImpl(As8080Lexer lexer) { this.lexer = Objects.requireNonNull(lexer); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java index 1bb850017..9df194578 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ParserErrorListener.java @@ -27,12 +27,12 @@ class ParserErrorListener extends BaseErrorListener { // TODO: parse message expected tokens to token categories @Override public void syntaxError( - Recognizer recognizer, - Object offendingSymbol, - int line, - int charPositionInLine, - String msg, - RecognitionException e) { + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { if (e == null) { throw new SyntaxErrorException(line, charPositionInLine, msg); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java index 15713ae76..bb9701026 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/NameSpace.java @@ -57,7 +57,7 @@ public List getErrors() { @Override public String toString() { return "NameSpace{" + - "errors=" + errors + - '}'; + "errors=" + errors + + '}'; } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java index f93ae5a68..53ca7ba0b 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Node.java @@ -25,11 +25,10 @@ import java.util.Optional; public abstract class Node { - protected Node parent; - protected final List children = new ArrayList<>(); public final int line; public final int column; - + protected final List children = new ArrayList<>(); + protected Node parent; private int address; public Node(int line, int column) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java index 8af3968dc..8b29d6340 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/Program.java @@ -40,14 +40,13 @@ public Program() { this(new NameSpace()); } - public void setFileName(String filename) { - this.filename = filename; - } - public Optional getFileName() { return Optional.ofNullable(filename); } + public void setFileName(String filename) { + this.filename = filename; + } public NameSpace env() { return env; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java index 293a8f5d4..8929f96c0 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprInfix.java @@ -34,8 +34,6 @@ public class ExprInfix extends Node { private final static Map> infixOps = new HashMap<>(); - private final BiFunction operation; - public final int operationCode; static { infixOps.put(OP_ADD, Integer::sum); @@ -61,6 +59,9 @@ public class ExprInfix extends Node { infixOps.put(OP_GTE, (x, y) -> (x >= y) ? 1 : 0); } + public final int operationCode; + private final BiFunction operation; + public ExprInfix(int line, int column, int op) { super(line, column); this.operationCode = op; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java index c4cfd5cce..2627e0bf5 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/expr/ExprUnary.java @@ -33,13 +33,13 @@ public class ExprUnary extends Node { private final static Map> unaryOps = Map.of( - OP_ADD, x -> x, - OP_SUBTRACT, x -> -x, - OP_NOT, x -> ~x, - OP_NOT_2, x -> ~x + OP_ADD, x -> x, + OP_SUBTRACT, x -> -x, + OP_NOT, x -> ~x, + OP_NOT_2, x -> ~x ); - private final Function operation; public final int operationCode; + private final Function operation; public ExprUnary(int line, int column, int op) { super(line, column); @@ -60,8 +60,8 @@ public void accept(NodeVisitor visitor) { @Override public Optional eval(Optional currentAddress, NameSpace env) { return getChild(0) - .eval(currentAddress, env) - .map(childEval -> new Evaluated(line, column, operation.apply(childEval.value))); + .eval(currentAddress, env) + .map(childEval -> new Evaluated(line, column, operation.apply(childEval.value))); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java index 3158d0f85..dd0ff0628 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrExpr.java @@ -28,7 +28,6 @@ import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; public class InstrExpr extends Node { - public final int opcode; private final static Set twoBytes = new HashSet<>(); private final static Map opcodes = new HashMap<>(); @@ -79,6 +78,8 @@ public class InstrExpr extends Node { opcodes.put(OPCODE_RST, 0xC7); } + public final int opcode; + public InstrExpr(int line, int column, int opcode) { super(line, column); this.opcode = opcode; @@ -102,8 +103,8 @@ public Optional eval() { byte result = (byte) (opcodes.get(opcode) & 0xFF); if (opcode == OPCODE_RST) { return collectChild(Evaluated.class) - .filter(e -> e.value >= 0 && e.value <= 7) - .map(e -> (byte) (result | (e.value << 3))); + .filter(e -> e.value >= 0 && e.value <= 7) + .map(e -> (byte) (result | (e.value << 3))); } return Optional.of(result); diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java index 79456b151..ae9d1ec6a 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrNoArgs.java @@ -29,7 +29,6 @@ public class InstrNoArgs extends Node { private final static Map opcodes = new HashMap<>(); - public final int opcode; static { opcodes.put(OPCODE_STC, 0x37); @@ -59,6 +58,8 @@ public class InstrNoArgs extends Node { opcodes.put(OPCODE_HLT, 0x76); } + public final int opcode; + public InstrNoArgs(int line, int column, int opcode) { super(line, column); this.opcode = opcode; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java index 803f03e90..4f8c3e50b 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrReg.java @@ -28,10 +28,8 @@ import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; public class InstrReg extends Node { - private final static Map opcodes = new HashMap<>(); public final static Map registers = new HashMap<>(); - public final int opcode; - public final int reg; + private final static Map opcodes = new HashMap<>(); static { opcodes.put(OPCODE_INR, 4); @@ -55,6 +53,9 @@ public class InstrReg extends Node { registers.put(REG_M, 6); } + public final int opcode; + public final int reg; + public InstrReg(int line, int column, int opcode, int reg) { super(line, column); this.opcode = opcode; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java index 8e67be349..632cd446d 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegPair.java @@ -28,11 +28,8 @@ import static net.emustudio.plugins.compiler.as8080.As8080Parser.*; public class InstrRegPair extends Node { - private final static Map opcodes = new HashMap<>(); public final static Map regpairs = new HashMap<>(); - - public final int opcode; - public final int regPair; + private final static Map opcodes = new HashMap<>(); static { opcodes.put(OPCODE_STAX, 2); @@ -50,6 +47,9 @@ public class InstrRegPair extends Node { regpairs.put(REG_SP, 3); } + public final int opcode; + public final int regPair; + public InstrRegPair(int line, int column, int opcode, int regPair) { super(line, column); this.opcode = opcode; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java index aabc1a1ab..8b9583d56 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/instr/InstrRegReg.java @@ -41,7 +41,7 @@ public InstrRegReg(Token opcode, Token dst, Token src) { public byte eval() { int srcRegister = InstrReg.registers.get(srcReg); int dstRegister = InstrReg.registers.get(dstReg); - return (byte)((0x40 | (dstRegister << 3) | (srcRegister)) & 0xFF); // TODO: mov M, M == HLT + return (byte) ((0x40 | (dstRegister << 3) | (srcRegister)) & 0xFF); // TODO: mov M, M == HLT } @Override @@ -51,7 +51,7 @@ public void accept(NodeVisitor visitor) { @Override protected String toStringShallow() { - return "InstrRegReg(" + opcode + ","+ dstReg +","+ srcReg +")"; + return "InstrRegReg(" + opcode + "," + dstReg + "," + srcReg + ")"; } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java index 1f7b96b5b..381a04c35 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/ast/pseudo/PseudoLabel.java @@ -53,7 +53,7 @@ public void accept(NodeVisitor visitor) { @Override protected String toStringShallow() { - return "Label(" + label +")"; + return "Label(" + label + ")"; } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java index a96c889bf..644149b98 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CheckDeclarationsVisitor.java @@ -18,9 +18,9 @@ */ package net.emustudio.plugins.compiler.as8080.visitors; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprId; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.*; import java.util.*; @@ -33,10 +33,10 @@ * - ID of constant and macro cannot reference itself in the declaration * - ID of variable cannot reference itself in the declaration only if it wasn't already declared * - macro parameters should not conflict with: - * - declarations in and out of the macro scope - * - previously declared parameters in current or parent macros if the current one is nested + * - declarations in and out of the macro scope + * - previously declared parameters in current or parent macros if the current one is nested * - if expressions should not reference declarations inside that if (including all nested ifs) - * + *

* - cyclic references will be checked in evaluator since it requires > 1 passes */ public class CheckDeclarationsVisitor extends NodeVisitor { @@ -49,13 +49,10 @@ public class CheckDeclarationsVisitor extends NodeVisitor { // for checking marco param names in nested macros private final List> macroParamsInScope = new ArrayList<>(); - - // for easier removal of current macro params from macroParamsInScope when the macro definition ends - private Set currentMacroParams; - // if expr references private final Set currentIfReferences = new HashSet<>(); - + // for easier removal of current macro params from macroParamsInScope when the macro definition ends + private Set currentMacroParams; private boolean insideMacroParameter = false; private int insideIfLevel = 0; // if nesting level, to know how long to keep currentIfReferences private boolean insideIfExpr = false; diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java index 1105cebd3..e6c3529a3 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreateLineVisitor.java @@ -20,8 +20,8 @@ import net.emustudio.plugins.compiler.as8080.As8080Parser; import net.emustudio.plugins.compiler.as8080.As8080ParserBaseVisitor; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoLabel; import net.emustudio.plugins.compiler.as8080.ast.Node; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoLabel; public class CreateLineVisitor extends As8080ParserBaseVisitor { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java index c2cf819d7..233fb39fd 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/CreatePseudoVisitor.java @@ -26,7 +26,7 @@ import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; -public class CreatePseudoVisitor extends As8080ParserBaseVisitor { +public class CreatePseudoVisitor extends As8080ParserBaseVisitor { @Override public Node visitPseudoOrg(PseudoOrgContext ctx) { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java index 1339d8402..90edb34d9 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitor.java @@ -31,7 +31,8 @@ import java.util.*; import java.util.stream.Collectors; -import static net.emustudio.plugins.compiler.as8080.CompileError.*; +import static net.emustudio.plugins.compiler.as8080.CompileError.ambiguousExpression; +import static net.emustudio.plugins.compiler.as8080.CompileError.expressionIsBiggerThanExpected; import static net.emustudio.plugins.compiler.as8080.ParsingUtils.normalizeId; /** @@ -49,16 +50,14 @@ * - no PseudoLabel */ public class EvaluateExprVisitor extends NodeVisitor { + private final Set doNotEvaluateVariables = new HashSet<>(); + private final Set forwardReferences = new HashSet<>(); + private final Map> macroArguments = new HashMap<>(); private int currentAddress = 0; private int sizeBytes = 0; private boolean doNotEvaluateCurrentAddress = false; - private final Set doNotEvaluateVariables = new HashSet<>(); - private final Set forwardReferences = new HashSet<>(); - private Optional latestEval; private Set needMorePassThings = new HashSet<>(); - - private final Map> macroArguments = new HashMap<>(); private String currentMacroId; @Override @@ -121,8 +120,8 @@ public void visit(DataDS node) { sizeBytes = 0; visitChildren(node); latestEval.ifPresentOrElse( - e -> currentAddress += e.value, - () -> doNotEvaluateCurrentAddress = true + e -> currentAddress += e.value, + () -> doNotEvaluateCurrentAddress = true ); } @@ -160,11 +159,11 @@ public void visit(PseudoLabel node) { Optional eval = node.eval(getCurrentAddress(), env); env.put(normalizeId(node.label), eval); eval.ifPresentOrElse( - e -> { - // we don't need to re-evaluate label - node.exclude(); - }, - () -> needMorePassThings.add(node) + e -> { + // we don't need to re-evaluate label + node.exclude(); + }, + () -> needMorePassThings.add(node) ); visitChildren(node); } @@ -175,8 +174,8 @@ public void visit(PseudoOrg node) { sizeBytes = 0; visitChildren(node); latestEval.ifPresentOrElse( - e -> currentAddress = e.value, - () -> doNotEvaluateCurrentAddress = true + e -> currentAddress = e.value, + () -> doNotEvaluateCurrentAddress = true ); } @@ -184,11 +183,11 @@ public void visit(PseudoOrg node) { public void visit(PseudoIf node) { sizeBytes = 0; Optional expr = node - .collectChild(PseudoIfExpression.class) - .flatMap(p -> { - visitChildren(p); - return p.collectChild(Evaluated.class); - }); + .collectChild(PseudoIfExpression.class) + .flatMap(p -> { + visitChildren(p); + return p.collectChild(Evaluated.class); + }); boolean includeBlock = expr.filter(p -> p.value != 0).isPresent(); boolean excludeBlock = expr.filter(p -> p.value == 0).isPresent(); @@ -286,11 +285,11 @@ public void visit(PseudoMacroArgument node) { visitChildren(node, 1); // expected two children: ExprId and Expr* node.collectChild(ExprId.class) - .ifPresent(exprId -> { - String macroParameter = normalizeId(exprId.id); - macroArguments.get(currentMacroId).add(macroParameter); - env.put(macroParameter, latestEval); - }); + .ifPresent(exprId -> { + String macroParameter = normalizeId(exprId.id); + macroArguments.get(currentMacroId).add(macroParameter); + env.put(macroParameter, latestEval); + }); } @Override @@ -364,8 +363,8 @@ private Optional getCurrentAddress() { private void evalExpr(Node node) { latestEval = node.eval(getCurrentAddress(), env); latestEval.ifPresentOrElse( - e -> node.remove().ifPresent(p -> p.addChild(e)), - () -> needMorePassThings.add(node) + e -> node.remove().ifPresent(p -> p.addChild(e)), + () -> needMorePassThings.add(node) ); currentAddress += sizeBytes; } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java index d7f91d957..2e5c241e4 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitor.java @@ -91,16 +91,16 @@ private String findAbsoluteFileName(String includeFileName) { } String includeFileNameNormalized = includeFileName - .replace("/", File.separator) - .replace("\\", File.separator); + .replace("/", File.separator) + .replace("\\", File.separator); return inputFileName - .map(f -> f.replace("/", File.separator)) - .map(f -> f.replace("\\", File.separator)) - .map(File::new) - .map(File::getParentFile) - .map(File::toPath) - .map(p -> p.resolve(includeFileNameNormalized)) - .map(Path::toString) - .orElse(includeFileNameNormalized); + .map(f -> f.replace("/", File.separator)) + .map(f -> f.replace("\\", File.separator)) + .map(File::new) + .map(File::getParentFile) + .map(File::toPath) + .map(p -> p.resolve(includeFileNameNormalized)) + .map(Path::toString) + .orElse(includeFileNameNormalized); } } diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java index b55d01625..30bae33cc 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosVisitor.java @@ -32,7 +32,7 @@ /** * Expands macros. It means - find macro definitions, remove them from the parent node and put them as a child under * each macro call. It supports forward references too. - * + *

* It doesn't mean the macro expansion will be used in code yet. */ public class ExpandMacrosVisitor extends NodeVisitor { diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java index 6620b929a..360b57c7f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitor.java @@ -54,24 +54,24 @@ public void visit(DataDW node) { @Override public void visit(DataDS node) { node.collectChild(Evaluated.class) - .ifPresent(e -> { - if (e.value < 0) { - error(valueMustBePositive(e)); - } else { - for (int i = 0; i < e.value; i++) { - hex.add((byte) 0); + .ifPresent(e -> { + if (e.value < 0) { + error(valueMustBePositive(e)); + } else { + for (int i = 0; i < e.value; i++) { + hex.add((byte) 0); + } } - } - }); + }); } @Override public void visit(InstrExpr node) { node.eval() - .ifPresentOrElse( - hex::add, - () -> error(valueOutOfBounds(node, 0, 7)) - ); + .ifPresentOrElse( + hex::add, + () -> error(valueOutOfBounds(node, 0, 7)) + ); expectedBytes = node.getExprSizeBytes(); visitChildren(node); } @@ -113,13 +113,13 @@ public void visit(InstrRegReg node) { @Override public void visit(PseudoOrg node) { node.collectChild(Evaluated.class) - .ifPresent(e -> { - if (e.value < 0) { - error(valueMustBePositive(node)); - } else { - hex.setNextAddress(e.value); - } - }); + .ifPresent(e -> { + if (e.value < 0) { + error(valueMustBePositive(node)); + } else { + hex.setNextAddress(e.value); + } + }); } @Override diff --git a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java index 2893a7875..d3ff4c94f 100644 --- a/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java +++ b/plugins/compiler/as-8080/src/main/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitor.java @@ -102,8 +102,8 @@ public void visit(PseudoMacroDef node) { Node macroArgument = origMacroArguments.get(i); macroParam - .collectChild(ExprId.class) - .ifPresentOrElse(macroArgument::addChildFirst, () -> error(macroArgumentsDoNotMatch(node))); + .collectChild(ExprId.class) + .ifPresentOrElse(macroArgument::addChildFirst, () -> error(macroArgumentsDoNotMatch(node))); } node.exclude(); } diff --git a/plugins/compiler/as-8080/src/main/resources/net/emustudio/plugins/compiler/as8080/version.properties b/plugins/compiler/as-8080/src/main/resources/net/emustudio/plugins/compiler/as8080/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/compiler/as-8080/src/main/resources/net/emustudio/plugins/compiler/as8080/version.properties +++ b/plugins/compiler/as-8080/src/main/resources/net/emustudio/plugins/compiler/as8080/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java index af813ec53..5d911942f 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/Utils.java @@ -41,31 +41,31 @@ public class Utils { public static Map registers = Map.of( - "a", REG_A, - "b", REG_B, - "c", REG_C, - "d", REG_D, - "e", REG_E, - "h", REG_H, - "l", REG_L, - "m", REG_M + "a", REG_A, + "b", REG_B, + "c", REG_C, + "d", REG_D, + "e", REG_E, + "h", REG_H, + "l", REG_L, + "m", REG_M ); public static Map regPairsBD = Map.of( - "b", REG_B, - "d", REG_D + "b", REG_B, + "d", REG_D ); public static Map regPairsBDHSP = Map.of( - "b", REG_B, - "d", REG_D, - "h", REG_H, - "sp", REG_SP + "b", REG_B, + "d", REG_D, + "h", REG_H, + "sp", REG_SP ); public static Map regPairsBDHPSW = Map.of( - "b", REG_B, - "d", REG_D, - "h", REG_H, - "psw", REG_PSW + "b", REG_B, + "d", REG_D, + "h", REG_H, + "psw", REG_PSW ); @@ -128,7 +128,7 @@ public static void forStringCaseVariations(String base, Consumer f) { } variations.add(new String(chars)); } - for (String variation: variations) { + for (String variation : variations) { f.accept(variation); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java index 8ac37e8d1..c28eecc07 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/AbstractCompilerTest.java @@ -25,8 +25,8 @@ import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.compiler.as8080.Assembler8080; import org.junit.Before; import org.junit.Rule; @@ -40,11 +40,10 @@ import static org.junit.Assert.assertEquals; public abstract class AbstractCompilerTest { - protected Assembler8080 compiler; - protected MemoryStub memoryStub; - @Rule public TemporaryFolder folder = new TemporaryFolder(); + protected Assembler8080 compiler; + protected MemoryStub memoryStub; @SuppressWarnings("unchecked") @Before @@ -92,14 +91,14 @@ protected void compile(String content) throws Exception { protected void assertProgram(int... bytes) { for (int i = 0; i < bytes.length; i++) { assertEquals( - String.format("[addr=%x] expected=%x, but was=%x", i, bytes[i], memoryStub.read(i)), - (byte)bytes[i], memoryStub.read(i).byteValue() + String.format("[addr=%x] expected=%x, but was=%x", i, bytes[i], memoryStub.read(i)), + (byte) bytes[i], memoryStub.read(i).byteValue() ); } for (int i = bytes.length; i < memoryStub.getSize(); i++) { assertEquals( - String.format("[addr=%x] expected=%x, but was=%x", i, 0, memoryStub.read(i)), - 0, memoryStub.read(i).byteValue() + String.format("[addr=%x] expected=%x, but was=%x", i, 0, memoryStub.read(i)), + 0, memoryStub.read(i).byteValue() ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/Assembler8080Test.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/Assembler8080Test.java index 6f63914f8..b3e28e396 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/Assembler8080Test.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/Assembler8080Test.java @@ -37,58 +37,58 @@ public void testCopyrightIsKnown() { @Test public void testForwardAbsoluteJump() throws Exception { compile( - "now: mov a,b\n" + - "cpi 'C'\n" + - "jz ler\n" + - "ler: mov m, a" + "now: mov a,b\n" + + "cpi 'C'\n" + + "jz ler\n" + + "ler: mov m, a" ); assertProgram( - 0x78, 0xFE, 0x43, 0xCA, 0x06, 0x00, 0x77 + 0x78, 0xFE, 0x43, 0xCA, 0x06, 0x00, 0x77 ); } @Test public void testBackwardAbsoluteJump() throws Exception { compile( - "now: mov a,b\n" + - "cpi 'C'\n" + - "jz now\n" + - "ler: mov m, a" + "now: mov a,b\n" + + "cpi 'C'\n" + + "jz now\n" + + "ler: mov m, a" ); assertProgram( - 0x78, 0xFE, 0x43, 0xCA, 0x00, 0x00, 0x77 + 0x78, 0xFE, 0x43, 0xCA, 0x00, 0x00, 0x77 ); } @Test public void testCallBackward() throws Exception { compile( - "dcx sp\n" + - "now: mov a,b\n" + - "cpi 'C'\n" + - "call now\n" + - "ler: mov m, a" + "dcx sp\n" + + "now: mov a,b\n" + + "cpi 'C'\n" + + "call now\n" + + "ler: mov m, a" ); assertProgram( - 0x3B, 0x78, 0xFE, 0x43, 0xCD, 0x01, 0x00, 0x77 + 0x3B, 0x78, 0xFE, 0x43, 0xCD, 0x01, 0x00, 0x77 ); } @Test public void testCallForward() throws Exception { compile( - "dcx sp\n" + - "now: mov a,b\n" + - "cpi 'C'\n" + - "call ler\n" + - "ler: mov m, a" + "dcx sp\n" + + "now: mov a,b\n" + + "cpi 'C'\n" + + "call ler\n" + + "ler: mov m, a" ); assertProgram( - 0x3B, 0x78, 0xFE, 0x43, 0xCD, 0x07, 0x00, 0x77 + 0x3B, 0x78, 0xFE, 0x43, 0xCD, 0x07, 0x00, 0x77 ); } @@ -100,48 +100,48 @@ public void testRSTtooBigArgument() throws Exception { @Test public void testDCXwithLXI() throws Exception { compile( - "dcx sp\n" - + "lxi h, text\n" - + "text:\n" - + "db 'ahoj'" + "dcx sp\n" + + "lxi h, text\n" + + "text:\n" + + "db 'ahoj'" ); assertProgram( - 0x3B, 0x21, 0x04, 0, 'a', 'h', 'o', 'j' + 0x3B, 0x21, 0x04, 0, 'a', 'h', 'o', 'j' ); } @Test public void testINthenJMP() throws Exception { compile( - "jmp sample\n" - + "in 10h\n" - + "sample:\n" - + "mov a, b\n" + "jmp sample\n" + + "in 10h\n" + + "sample:\n" + + "mov a, b\n" ); assertProgram( - 0xC3, 0x5, 0, 0xDB, 0x10, 0x78 + 0xC3, 0x5, 0, 0xDB, 0x10, 0x78 ); } @Test public void testGetChar() throws Exception { compile( - "jmp sample\n" - + "getchar:\n" - + "in 10h\n" - + "ani 1\n" - + "jz getchar\n" - + "in 11h\n" - + "out 11h\n" - + "ret\n" - + "sample:\n" - + "mov a, b" + "jmp sample\n" + + "getchar:\n" + + "in 10h\n" + + "ani 1\n" + + "jz getchar\n" + + "in 11h\n" + + "out 11h\n" + + "ret\n" + + "sample:\n" + + "mov a, b" ); assertProgram( - 0xC3, 0x0F, 0, 0xDB, 0x10, 0xE6, 1, 0xCA, 0x03, 0, 0xDB, 0x11, 0xD3, 0x11, 0xC9, 0x78 + 0xC3, 0x0F, 0, 0xDB, 0x10, 0xE6, 1, 0xCA, 0x03, 0, 0xDB, 0x11, 0xD3, 0x11, 0xC9, 0x78 ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/ConstantsAndVariablesTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/ConstantsAndVariablesTest.java index 4e16140e3..5f4527f68 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/ConstantsAndVariablesTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/ConstantsAndVariablesTest.java @@ -25,85 +25,85 @@ public class ConstantsAndVariablesTest extends AbstractCompilerTest { @Test public void testLabelAsConstantWorks() throws Exception { compile( - "here equ 0\n" - + "mov a,b\n" - + "jz here" + "here equ 0\n" + + "mov a,b\n" + + "jz here" ); assertProgram( - 0x78, 0xCA, 0, 0 + 0x78, 0xCA, 0, 0 ); } @Test public void testConstantAsLabelWorks() throws Exception { compile( - "here equ there\n" - + "there: mov a,b\n" - + "jz here" + "here equ there\n" + + "there: mov a,b\n" + + "jz here" ); assertProgram( - 0x78, 0xCA, 0, 0 + 0x78, 0xCA, 0, 0 ); } @Test(expected = Exception.class) public void testRecursiveConstantDefinitionsDoesNotWork() throws Exception { compile( - "here equ there\n" - + "there equ here\n" - + "jz here" + "here equ there\n" + + "there equ here\n" + + "jz here" ); } @Test(expected = Exception.class) public void testTwoSameLabelsDoNotWork() throws Exception { compile( - "here:\nhere:\njz here" + "here:\nhere:\njz here" ); } @Test(expected = Exception.class) public void testTwoSameConstantsDoNotWork() throws Exception { compile( - "here equ 0\nhere equ 1" + "here equ 0\nhere equ 1" ); } @Test public void testVariableCanBeOverwritten() throws Exception { compile( - "here set 0\nhere set 1\ncpi here" + "here set 0\nhere set 1\ncpi here" ); assertProgram( - 0xFE, 1 + 0xFE, 1 ); } @Test(expected = Exception.class) public void testCannotSetVariableBecauseIdentifierIsAlreadyDefined() throws Exception { compile( - "here equ 0\nhere set 1\n" + "here equ 0\nhere set 1\n" ); } @Test(expected = Exception.class) public void testCannotDefineConstantBecauseIdentifierIsAlreadyDefined() throws Exception { compile( - "here: db 4\nhere equ 1\n" + "here: db 4\nhere equ 1\n" ); } @Test public void testForwardReferenceOfConstantShouldWork() throws Exception { compile("LXI SP,STACK\n" + - "TEMPP: DW TEMP0\n" + - "TEMP0: DS 1\n" + - "STACK EQU TEMPP+256"); + "TEMPP: DW TEMP0\n" + + "TEMP0: DS 1\n" + + "STACK EQU TEMPP+256"); assertProgram( - 0x31, 0x03, 0x01, 5, 0, 0 + 0x31, 0x03, 0x01, 5, 0, 0 ); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java index b55d14f1d..f107f02a7 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/DataTest.java @@ -25,138 +25,138 @@ public class DataTest extends AbstractCompilerTest { @Test public void testDBwithNegativeValueWorks() throws Exception { compile( - "db -1" + "db -1" ); assertProgram( - 0xFF, 0 + 0xFF, 0 ); } @Test(expected = Exception.class) public void testDBwithNegativeValueHigherLowerThanMinus127doesNotWork() throws Exception { compile( - "db -1299" + "db -1299" ); } @Test public void testDBallocatesOneByte() throws Exception { compile( - "db 10\nmov a,b\n" + "db 10\nmov a,b\n" ); assertProgram( - 10, 0x78 + 10, 0x78 ); } @Test(expected = Exception.class) public void testDBbiggerThan255DoesNotWork() throws Exception { compile( - "db 256\n" + "db 256\n" ); } @Test public void testDBseveralBytesWork() throws Exception { compile( - "db 255,1,2\n" + "db 255,1,2\n" ); assertProgram( - 0xFF, 1, 2 + 0xFF, 1, 2 ); } @Test public void testDBWithInstruction() throws Exception { compile( - "db inr A\n" + "db inr A\n" ); assertProgram( - 0x3C + 0x3C ); } @Test public void testDBliteral() throws Exception { compile( - "db 'if'\n" + "db 'if'\n" ); assertProgram( - 'i', 'f' + 'i', 'f' ); } @Test public void testDBshortLiteral() throws Exception { compile( - "db 'i'\n" + "db 'i'\n" ); assertProgram( - 'i' + 'i' ); } @Test public void testDWwithNegativeValueWorks() throws Exception { compile( - "dw -1" + "dw -1" ); assertProgram( - 0xFF, 0xFF, 0 + 0xFF, 0xFF, 0 ); } @Test(expected = Exception.class) public void testDWwithNegativeValueHigherLowerThanMinus3768doesNotWork() throws Exception { compile( - "dw -32769" + "dw -32769" ); } @Test public void testDWallocatesTwoBytesInLittleEndian() throws Exception { compile( - "dw 10\nmov a,b\n" + "dw 10\nmov a,b\n" ); assertProgram( - 10, 0, 0x78 + 10, 0, 0x78 ); } @Test public void testDWseveralValuesWork() throws Exception { compile( - "dw 10,4\nmov a,b\n" + "dw 10,4\nmov a,b\n" ); assertProgram( - 10, 0, 4, 0, 0x78 + 10, 0, 4, 0, 0x78 ); } @Test(expected = Exception.class) public void testDWmoreThanFFFFdoesNotWork() throws Exception { compile( - "dw 10000h\nmov a,b\n" + "dw 10000h\nmov a,b\n" ); } @Test(expected = Exception.class) public void testDW_ValueTooBig() throws Exception { compile( - "org 0FFFFh\n" - + "rrc\n" - + "test:\n" - + "dw test" + "org 0FFFFh\n" + + "rrc\n" + + "test:\n" + + "dw test" ); } @Test(expected = Exception.class) public void testDSwithNegativeValueDoesNotWork() throws Exception { compile( - "ds -1" + "ds -1" ); } @@ -166,27 +166,27 @@ public void testDSbreaksPreviousMemoryContent() throws Exception { memoryStub.write(1, (byte) 0x11); compile( - "ds 2\n" + "now: mov a,b\n" + "ds 2\n" + "now: mov a,b\n" ); assertProgram( - 0x0, 0x0, 0x78 + 0x0, 0x0, 0x78 ); } @Test public void testJumpBackwardWithDSamong() throws Exception { compile( - "ds 2\n" + - "now: mov a,b\n" + "ds 2\n" + - "cpi 'C'\n" + - "jz now\n" + - "ler: mov m, a" + "now: mov a,b\n" + + "ds 2\n" + + "cpi 'C'\n" + + "jz now\n" + + "ler: mov m, a" ); assertProgram( - 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 + 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 ); } @@ -194,7 +194,7 @@ public void testJumpBackwardWithDSamong() throws Exception { public void testDbOrdering() throws Exception { compile("db 186, \"Hello\", 186, 10, 13"); assertProgram( - 186, 'H', 'e', 'l', 'l', 'o', 186, 10, 13 + 186, 'H', 'e', 'l', 'l', 'o', 186, 10, 13 ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IfNodeTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IfNodeTest.java index aea85eac4..1f6628f34 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IfNodeTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IfNodeTest.java @@ -25,22 +25,22 @@ public class IfNodeTest extends AbstractCompilerTest { @Test public void testIfNodeIsProcessed() throws Exception { compile( - "if 1\n" - + " rrc\n" - + "endif" + "if 1\n" + + " rrc\n" + + "endif" ); assertProgram( - 0x0F + 0x0F ); } @Test public void testIfNodeIsNotProcessed() throws Exception { compile( - "if 0\n" - + " rrc\n" - + "endif" + "if 0\n" + + " rrc\n" + + "endif" ); assertProgram(); @@ -49,37 +49,37 @@ public void testIfNodeIsNotProcessed() throws Exception { @Test public void testIfNoteIsProcessedForNegativeExpression() throws Exception { compile( - "if -1\n" - + " rrc\n" - + "endif" + "if -1\n" + + " rrc\n" + + "endif" ); assertProgram( - 0x0F + 0x0F ); } @Test public void testIfCanEvaluateBackwardReferenceInExpression() throws Exception { compile( - "present equ 1\n" - + "if present\n" - + " rrc\n" - + "endif\n" + "present equ 1\n" + + "if present\n" + + " rrc\n" + + "endif\n" ); assertProgram( - 0x0F + 0x0F ); } @Test(expected = Exception.class) public void testIfCannotRedefineIdentifierInside() throws Exception { compile( - "text: db 6\n" - + "if 554\n" - + " text: db 5\n" - + "endif" + "text: db 6\n" + + "if 554\n" + + " text: db 5\n" + + "endif" ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IncludeTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IncludeTest.java index 1ec1f3de0..1d342436d 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IncludeTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/IncludeTest.java @@ -28,8 +28,8 @@ public class IncludeTest extends AbstractCompilerTest { public void testIncludeAndForwardCall() throws Exception { File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( - "call sample\n" - + "include '" + includeFile.getAbsolutePath() + "'\n" + "call sample\n" + + "include '" + includeFile.getAbsolutePath() + "'\n" ); assertProgram(0xCD, 0x03, 0x00, 0x3E, 0, 0xC9); } @@ -38,12 +38,12 @@ public void testIncludeAndForwardCall() throws Exception { public void testCallDataInclude() throws Exception { File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( - "call sample\n" + - "label: db 'hello'\n" + - "include '" + includeFile.getAbsolutePath() + "'\n" + "call sample\n" + + "label: db 'hello'\n" + + "include '" + includeFile.getAbsolutePath() + "'\n" ); assertProgram( - 0xCD, 0x08, 0x00, 'h', 'e', 'l', 'l', 'o', 0x3E, 0, 0xC9 + 0xCD, 0x08, 0x00, 'h', 'e', 'l', 'l', 'o', 0x3E, 0, 0xC9 ); } @@ -52,13 +52,13 @@ public void testDoubleIncludeAndForwardCall() throws Exception { File first = new File(getClass().getResource("/sample.asm").toURI()); File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( - "call sample2\n" - + "include '" + first.getAbsolutePath() + "'\n" - + "include '" + second.getAbsolutePath() + "'\n" + "call sample2\n" + + "include '" + first.getAbsolutePath() + "'\n" + + "include '" + second.getAbsolutePath() + "'\n" ); assertProgram( - 0xCD, 6, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9 + 0xCD, 6, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9 ); } @@ -66,12 +66,12 @@ public void testDoubleIncludeAndForwardCall() throws Exception { public void testIncludeAndBackwardCall() throws Exception { File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( - "include '" + includeFile.getAbsolutePath() + "'\n" - + "call sample\n" + "include '" + includeFile.getAbsolutePath() + "'\n" + + "call sample\n" ); assertProgram( - 0x3E, 0, 0xC9, 0xCD, 0, 0 + 0x3E, 0, 0xC9, 0xCD, 0, 0 ); } @@ -80,13 +80,13 @@ public void testDoubleIncludeAndBackwardCall() throws Exception { File first = new File(getClass().getResource("/sample.asm").toURI()); File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( - "include '" + first.getAbsolutePath() + "'\n" - + "include '" + second.getAbsolutePath() + "'\n" - + "call sample\n" + "include '" + first.getAbsolutePath() + "'\n" + + "include '" + second.getAbsolutePath() + "'\n" + + "call sample\n" ); assertProgram( - 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0xCD, 0, 0 + 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0xCD, 0, 0 ); } @@ -94,14 +94,14 @@ public void testDoubleIncludeAndBackwardCall() throws Exception { public void testIncludeAndJMPafter() throws Exception { File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( - "jmp next\n" - + "include '" + includeFile.getAbsolutePath() + "'\n" - + "next:\n" - + "mov a, b\n" + "jmp next\n" + + "include '" + includeFile.getAbsolutePath() + "'\n" + + "next:\n" + + "mov a, b\n" ); assertProgram( - 0xC3, 0x06, 0, 0x3E, 0, 0xC9, 0x78 + 0xC3, 0x06, 0, 0x3E, 0, 0xC9, 0x78 ); } @@ -110,15 +110,15 @@ public void testDoubleIncludeAndJMPafter() throws Exception { File first = new File(getClass().getResource("/sample.asm").toURI()); File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( - "jmp next\n" - + "include '" + first.getAbsolutePath() + "'\n" - + "include '" + second.getAbsolutePath() + "'\n" - + "next:\n" - + "mov a, b\n" + "jmp next\n" + + "include '" + first.getAbsolutePath() + "'\n" + + "include '" + second.getAbsolutePath() + "'\n" + + "next:\n" + + "mov a, b\n" ); assertProgram( - 0xC3, 0x09, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0x78 + 0xC3, 0x09, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0x78 ); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrExprTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrExprTest.java index 16fb376e9..906cb9592 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrExprTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrExprTest.java @@ -7,14 +7,14 @@ public class InstrExprTest extends AbstractCompilerTest { @Test public void testRST() throws Exception { compile( - "JMP EXAMPLE\n" + - "RST 00H\n" + - "EXAMPLE:\n" + - "MVI A,01H" + "JMP EXAMPLE\n" + + "RST 00H\n" + + "EXAMPLE:\n" + + "MVI A,01H" ); assertProgram( - 0xC3, 0x04, 0x00, 0xC7, 0x3E, 0x01 + 0xC3, 0x04, 0x00, 0xC7, 0x3E, 0x01 ); } @@ -27,8 +27,8 @@ public void testCPI() throws Exception { @Test public void testForwardCall() throws Exception { compile("call sample\n" + - "label: db 'hello'\n" + - "sample: hlt"); + "label: db 'hello'\n" + + "sample: hlt"); assertProgram(0xCD, 0x08, 0x00, 'h', 'e', 'l', 'l', 'o', 0x76); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrRegTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrRegTest.java index 159c43ece..fa09c51d0 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrRegTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/InstrRegTest.java @@ -25,180 +25,180 @@ public class InstrRegTest extends AbstractCompilerTest { @Test public void testINR() throws Exception { compile( - "inr A\n" - + "inr B\n" - + "inr C\n" - + "inr D\n" - + "inr E\n" - + "inr H\n" - + "inr L\n" - + "inr M\n" + "inr A\n" + + "inr B\n" + + "inr C\n" + + "inr D\n" + + "inr E\n" + + "inr H\n" + + "inr L\n" + + "inr M\n" ); assertProgram( - 0x3C, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34 + 0x3C, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34 ); } @Test public void testDCR() throws Exception { compile( - "dcr A\n" - + "dcr B\n" - + "dcr C\n" - + "dcr D\n" - + "dcr E\n" - + "dcr H\n" - + "dcr L\n" - + "dcr M\n" + "dcr A\n" + + "dcr B\n" + + "dcr C\n" + + "dcr D\n" + + "dcr E\n" + + "dcr H\n" + + "dcr L\n" + + "dcr M\n" ); assertProgram( - 0x3D, 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, 0x35 + 0x3D, 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, 0x35 ); } @Test public void testADD() throws Exception { compile( - "add A\n" - + "add B\n" - + "add C\n" - + "add D\n" - + "add E\n" - + "add H\n" - + "add L\n" - + "add M\n" + "add A\n" + + "add B\n" + + "add C\n" + + "add D\n" + + "add E\n" + + "add H\n" + + "add L\n" + + "add M\n" ); assertProgram( - 0x87, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86 + 0x87, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86 ); } @Test public void testADC() throws Exception { compile( - "adc A\n" - + "adc B\n" - + "adc C\n" - + "adc D\n" - + "adc E\n" - + "adc H\n" - + "adc L\n" - + "adc M\n" + "adc A\n" + + "adc B\n" + + "adc C\n" + + "adc D\n" + + "adc E\n" + + "adc H\n" + + "adc L\n" + + "adc M\n" ); assertProgram( - 0x8F, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E + 0x8F, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E ); } @Test public void testSUB() throws Exception { compile( - "sub A\n" - + "sub B\n" - + "sub C\n" - + "sub D\n" - + "sub E\n" - + "sub H\n" - + "sub L\n" - + "sub M\n" + "sub A\n" + + "sub B\n" + + "sub C\n" + + "sub D\n" + + "sub E\n" + + "sub H\n" + + "sub L\n" + + "sub M\n" ); assertProgram( - 0x97, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96 + 0x97, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96 ); } @Test public void testSBB() throws Exception { compile( - "sbb A\n" - + "sbb B\n" - + "sbb C\n" - + "sbb D\n" - + "sbb E\n" - + "sbb H\n" - + "sbb L\n" - + "sbb M\n" + "sbb A\n" + + "sbb B\n" + + "sbb C\n" + + "sbb D\n" + + "sbb E\n" + + "sbb H\n" + + "sbb L\n" + + "sbb M\n" ); assertProgram( - 0x9F, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E + 0x9F, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E ); } @Test public void testANA() throws Exception { compile( - "ana A\n" - + "ana B\n" - + "ana C\n" - + "ana D\n" - + "ana E\n" - + "ana H\n" - + "ana L\n" - + "ana M\n" + "ana A\n" + + "ana B\n" + + "ana C\n" + + "ana D\n" + + "ana E\n" + + "ana H\n" + + "ana L\n" + + "ana M\n" ); assertProgram( - 0xA7, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6 + 0xA7, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6 ); } @Test public void testXRA() throws Exception { compile( - "xra A\n" - + "xra B\n" - + "xra C\n" - + "xra D\n" - + "xra E\n" - + "xra H\n" - + "xra L\n" - + "xra M\n" + "xra A\n" + + "xra B\n" + + "xra C\n" + + "xra D\n" + + "xra E\n" + + "xra H\n" + + "xra L\n" + + "xra M\n" ); assertProgram( - 0xAF, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE + 0xAF, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE ); } @Test public void testORA() throws Exception { compile( - "ora A\n" - + "ora B\n" - + "ora C\n" - + "ora D\n" - + "ora E\n" - + "ora H\n" - + "ora L\n" - + "ora M\n" + "ora A\n" + + "ora B\n" + + "ora C\n" + + "ora D\n" + + "ora E\n" + + "ora H\n" + + "ora L\n" + + "ora M\n" ); assertProgram( - 0xB7, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6 + 0xB7, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6 ); } @Test public void testCMP() throws Exception { compile( - "cmp A\n" - + "cmp B\n" - + "cmp C\n" - + "cmp D\n" - + "cmp E\n" - + "cmp H\n" - + "cmp L\n" - + "cmp M\n" + "cmp A\n" + + "cmp B\n" + + "cmp C\n" + + "cmp D\n" + + "cmp E\n" + + "cmp H\n" + + "cmp L\n" + + "cmp M\n" ); assertProgram( - 0xBF, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE + 0xBF, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/MacroTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/MacroTest.java index a7eac2971..fe702686a 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/MacroTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/MacroTest.java @@ -25,10 +25,10 @@ public class MacroTest extends AbstractCompilerTest { @Test public void testMacroWithoutCallDoesNotGenerateCode() throws Exception { compile( - "shrt macro\n" - + " rrc\n" - + " ani 7Fh\n" - + "endm\n\n" + "shrt macro\n" + + " rrc\n" + + " ani 7Fh\n" + + "endm\n\n" ); assertProgram(); } @@ -36,106 +36,106 @@ public void testMacroWithoutCallDoesNotGenerateCode() throws Exception { @Test public void testMacroWithoutParams() throws Exception { compile( - "shrt macro\n" - + " rrc\n" - + " ani 7Fh\n" - + "endm\n\n" - + "shrt\n" + "shrt macro\n" + + " rrc\n" + + " ani 7Fh\n" + + "endm\n\n" + + "shrt\n" ); assertProgram( - 0x0F, 0xE6, 0x7F + 0x0F, 0xE6, 0x7F ); } @Test public void testMacroWithParams() throws Exception { compile( - "shrt macro amount, dbsize\n" - + " rrc\n" - + " ani amount\n" - + " db dbsize\n" - + "endm\n\n" - + "shrt 7Fh, 0\n" + "shrt macro amount, dbsize\n" + + " rrc\n" + + " ani amount\n" + + " db dbsize\n" + + "endm\n\n" + + "shrt 7Fh, 0\n" ); assertProgram( - 0x0F, 0xE6, 0x7F + 0x0F, 0xE6, 0x7F ); } @Test public void testDBinMacroIsVisibleFromOutside() throws Exception { compile( - "shrt macro\n" - + " text: db 0Fh\n" - + " ani 7Fh\n" - + "endm\n\n" - + "shrt\n" - + "lxi h, text\n" + "shrt macro\n" + + " text: db 0Fh\n" + + " ani 7Fh\n" + + "endm\n\n" + + "shrt\n" + + "lxi h, text\n" ); assertProgram( - 0x0F, 0xE6, 0x7F, 0x21, 0, 0 + 0x0F, 0xE6, 0x7F, 0x21, 0, 0 ); } @Test(expected = Exception.class) public void testCannotRedefineIdentifierInMacro() throws Exception { compile( - "hello: db 0\n" - + "shrt macro\n" - + " hello equ 0Fh\n" - + "endm\n" - + "shrt\n" + "hello: db 0\n" + + "shrt macro\n" + + " hello equ 0Fh\n" + + "endm\n" + + "shrt\n" ); } @Test(expected = Exception.class) public void testMacroAlreadyDefined() throws Exception { compile( - "shrt macro\nendm\n" - + "shrt macro\nendm\n" + "shrt macro\nendm\n" + + "shrt macro\nendm\n" ); } @Test public void testMacroCanGetForwardLabelReferences() throws Exception { compile( - "shrt macro param\n" - + " lxi h, param\n" - + "endm\n" - + "shrt text\n" - + "text: db 1\n" + "shrt macro param\n" + + " lxi h, param\n" + + "endm\n" + + "shrt text\n" + + "text: db 1\n" ); assertProgram( - 0x21, 3, 0, 1 + 0x21, 3, 0, 1 ); } @Test(expected = Exception.class) public void testLessMacroParametersThanExpected() throws Exception { compile( - "shrt macro param\n" - + " lxi h, param\n" - + "endm\n" - + "shrt\n" + "shrt macro param\n" + + " lxi h, param\n" + + "endm\n" + + "shrt\n" ); } @Test(expected = Exception.class) public void testMoreMacroParametersThanExpected() throws Exception { compile( - "shrt macro param\n" - + " lxi h, param\n" - + "endm\n" - + "shrt 1, 2\n" + "shrt macro param\n" + + " lxi h, param\n" + + "endm\n" + + "shrt 1, 2\n" ); } @Test(expected = Exception.class) public void testCallUndefinedMacro() throws Exception { compile( - "shrt 1,2\n" + "shrt 1,2\n" ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/PseudoOrgTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/PseudoOrgTest.java index aa4a71d41..60a7612e6 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/PseudoOrgTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/e2e/PseudoOrgTest.java @@ -38,100 +38,100 @@ public void setup() { @Test public void testORGwithInclude() throws Exception { compile( - "org 3\n" - + "call sample\n" - + "include '" + sampleFile + "'\n" + "org 3\n" + + "call sample\n" + + "include '" + sampleFile + "'\n" ); assertProgram( - 0, 0, 0, 0xCD, 6, 0, 0x3E, 0, 0xC9 + 0, 0, 0, 0xCD, 6, 0, 0x3E, 0, 0xC9 ); } @Test public void testORGwithDoubleInclude() throws Exception { compile( - "org 3\n" - + "call sample\n" - + "include '" + sample2File + "'\n" - + "include '" + sampleFile + "'\n" + "org 3\n" + + "call sample\n" + + "include '" + sample2File + "'\n" + + "include '" + sampleFile + "'\n" ); assertProgram( - 0, 0, 0, 0xCD, 0x09, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9 + 0, 0, 0, 0xCD, 0x09, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9 ); } @Test public void testORGwithDoubleIncludeAndJMPafter() throws Exception { compile( - "org 3\n" - + "jmp next\n" - + "include '" + sampleFile + "'\n" - + "include '" + sample2File + "'\n" - + "next:\n" - + "mov a, b\n" + "org 3\n" + + "jmp next\n" + + "include '" + sampleFile + "'\n" + + "include '" + sample2File + "'\n" + + "next:\n" + + "mov a, b\n" ); assertProgram( - 0, 0, 0, 0xC3, 0x0C, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0x78 + 0, 0, 0, 0xC3, 0x0C, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0x78 ); } @Test public void testORGwithDB() throws Exception { compile( - "org 3\n" - + "lxi h, text\n" - + "text:\n" - + "db 'ahoj'" + "org 3\n" + + "lxi h, text\n" + + "text:\n" + + "db 'ahoj'" ); assertProgram( - 0, 0, 0, 0x21, 0x06, 0, 'a', 'h', 'o', 'j' + 0, 0, 0, 0x21, 0x06, 0, 'a', 'h', 'o', 'j' ); } @Test public void testORG() throws Exception { compile( - "org 2\n" + - "now: mov a,b\n" + - "ds 2\n" + - "cpi 'C'\n" + - "jz now\n" + - "ler: mov m, a" + "org 2\n" + + "now: mov a,b\n" + + "ds 2\n" + + "cpi 'C'\n" + + "jz now\n" + + "ler: mov m, a" ); assertProgram( - 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 + 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 ); } @Test public void testORGwithJumpBackwards() throws Exception { compile( - "sample:\n" - + "org 2\n" - + "jmp sample" + "sample:\n" + + "org 2\n" + + "jmp sample" ); assertProgram( - 0, 0, 0xC3, 0, 0 + 0, 0, 0xC3, 0, 0 ); } @Test public void testORGwithJumpForwards() throws Exception { compile( - "jmp sample\n" - + "org 5\n" - + "sample:\n" - + "mov a, b" + "jmp sample\n" + + "org 5\n" + + "sample:\n" + + "mov a, b" ); assertProgram( - 0xC3, 0x05, 0, 0, 0, 0x78 + 0xC3, 0x05, 0, 0, 0, 0x78 ); } @@ -141,28 +141,28 @@ public void testORGdoesNotBreakPreviousMemoryContent() throws Exception { memoryStub.write(1, (byte) 0x11); compile( - "org 2\n" + "now: mov a,b\n" + "org 2\n" + "now: mov a,b\n" ); assertProgram( - 0x10, 0x11, 0x78 + 0x10, 0x11, 0x78 ); } @Test public void testORGthenDSdoNotOverlap() throws Exception { compile( - "org 2\nds 2\nmov a,b" + "org 2\nds 2\nmov a,b" ); assertProgram( - 0, 0, 0, 0, 0x78 + 0, 0, 0, 0, 0x78 ); } @Test(expected = Exception.class) public void testORGisAmbiguous() throws Exception { compile( - "org text\nmvi a, 4\ntext: db 4\n" + "org text\nmvi a, 4\ntext: db 4\n" ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java index d73ff39be..84c9686a8 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/LexicalAnalyzerImplTest.java @@ -44,35 +44,35 @@ public void testParseError2() { @Test public void testParseHex1() { assertTokenTypes( - "0x1 0x0 -0x5f -0xFffF 0x1BC", - LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, - WS, LIT_HEXNUMBER_1, EOF + "0x1 0x0 -0x5f -0xFffF 0x1BC", + LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, + WS, LIT_HEXNUMBER_1, EOF ); } @Test public void testParseHex2() { assertTokenTypes( - "1h 0h -5Fh -FFFFh 1BCh 5h -5h", - LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, - WS, LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, EOF + "1h 0h -5Fh -FFFFh 1BCh 5h -5h", + LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, + WS, LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, EOF ); } @Test public void testParseDecimal() { assertTokenTypes( - "0 1 -2 3 -4 5 66 999", - LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, - WS, LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF + "0 1 -2 3 -4 5 66 999", + LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, + WS, LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF ); } @Test public void testParseOctal() { assertTokenTypes( - "-6o 7q 11q -345O", - OP_SUBTRACT, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, OP_SUBTRACT, LIT_OCTNUMBER, EOF); + "-6o 7q 11q -345O", + OP_SUBTRACT, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, OP_SUBTRACT, LIT_OCTNUMBER, EOF); } @Test diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseDataTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseDataTest.java index 2bce503f9..c283179a1 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseDataTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseDataTest.java @@ -39,9 +39,9 @@ public class ParseDataTest { public void testDBstring1() { Program program = parseProgram("db 'hello'"); assertTrees(new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprString(0, 0, "hello"))), - program + .addChild(new DataDB(0, 0) + .addChild(new ExprString(0, 0, "hello"))), + program ); } @@ -49,9 +49,9 @@ public void testDBstring1() { public void testDBstring2() { Program program = parseProgram("db \"hello\""); assertTrees(new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprString(0, 0, "hello"))), - program + .addChild(new DataDB(0, 0) + .addChild(new ExprString(0, 0, "hello"))), + program ); } @@ -59,10 +59,10 @@ public void testDBstring2() { public void testDBinstruction() { Program program = parseProgram("db stc"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new InstrNoArgs(0, 0, OPCODE_STC))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new InstrNoArgs(0, 0, OPCODE_STC))), + program ); } @@ -70,12 +70,12 @@ public void testDBinstruction() { public void testMultipleDB() { Program program = parseProgram("db -1,2,3"); assertTrees(new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))), - program + .addChild(new DataDB(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))), + program ); } @@ -83,10 +83,10 @@ public void testMultipleDB() { public void testDBwithNegativeValue() { Program program = parseProgram("db -1"); assertTrees(new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 1)))), - program + .addChild(new DataDB(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1)))), + program ); } @@ -94,12 +94,12 @@ public void testDBwithNegativeValue() { public void testMultipleDBstringNumberString() { Program program = parseProgram("db -1,'hello',3"); assertTrees(new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprString(0, 0, "hello")) - .addChild(new ExprNumber(0, 0, 3))), - program + .addChild(new DataDB(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprString(0, 0, "hello")) + .addChild(new ExprNumber(0, 0, 3))), + program ); } @@ -107,12 +107,12 @@ public void testMultipleDBstringNumberString() { public void testMultipleDW() { Program program = parseProgram("dw -1,2,3"); assertTrees(new Program() - .addChild(new DataDW(0, 0) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))), - program + .addChild(new DataDW(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))), + program ); } @@ -120,10 +120,10 @@ public void testMultipleDW() { public void testDWwithNegativeValue() { Program program = parseProgram("dw -1"); assertTrees(new Program() - .addChild(new DataDW(0, 0) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 1)))), - program + .addChild(new DataDW(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1)))), + program ); } @@ -131,9 +131,9 @@ public void testDWwithNegativeValue() { public void testDS() { Program program = parseProgram("ds 0x55"); assertTrees(new Program() - .addChild(new DataDS(0, 0) - .addChild(new ExprNumber(0, 0, 0x55))), - program + .addChild(new DataDS(0, 0) + .addChild(new ExprNumber(0, 0, 0x55))), + program ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java index c9b8f718b..bb2683b13 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseExprTest.java @@ -35,14 +35,14 @@ public class ParseExprTest { public void testPrioritiesAddMul() { Program program = parseProgram("db 2+3*4"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprNumber(0, 0, 3)) - .addChild(new ExprNumber(0, 0, 4))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 3)) + .addChild(new ExprNumber(0, 0, 4))))), + program ); } @@ -50,14 +50,14 @@ public void testPrioritiesAddMul() { public void testPrioritiesMulAdd() { Program program = parseProgram("db 2*3+4"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new ExprNumber(0, 0, 4)))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4)))), + program ); } @@ -65,16 +65,16 @@ public void testPrioritiesMulAdd() { public void testAssociativityPlusMinus() { Program program = parseProgram("db 2-3+4-9"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new ExprNumber(0, 0, 4))) - .addChild(new ExprNumber(0, 0, 9)))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4))) + .addChild(new ExprNumber(0, 0, 9)))), + program ); } @@ -82,16 +82,16 @@ public void testAssociativityPlusMinus() { public void testAssociativitMulDiv() { Program program = parseProgram("db 2/3*4/9"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_DIVIDE) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprInfix(0, 0, OP_DIVIDE) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new ExprNumber(0, 0, 4))) - .addChild(new ExprNumber(0, 0, 9)))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4))) + .addChild(new ExprNumber(0, 0, 9)))), + program ); } @@ -99,20 +99,20 @@ public void testAssociativitMulDiv() { public void testPrecedencePlusMinusMulDivMod() { Program program = parseProgram("db 2+3*4-9/2 mod 3"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprNumber(0, 0, 3)) - .addChild(new ExprNumber(0, 0, 4)))) - .addChild(new ExprInfix(0, 0, OP_MOD) - .addChild(new ExprInfix(0, 0, OP_DIVIDE) - .addChild(new ExprNumber(0, 0, 9)) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprNumber(0, 0, 3))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 3)) + .addChild(new ExprNumber(0, 0, 4)))) + .addChild(new ExprInfix(0, 0, OP_MOD) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprNumber(0, 0, 9)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 3))))), + program ); } @@ -120,22 +120,22 @@ public void testPrecedencePlusMinusMulDivMod() { public void testAssociativityEqual() { Program program = parseProgram("db 1 + 2 + 2 = 5 = 5 = 6 - 1"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprInfix(0, 0, OP_ADD) // 1 + 2 + 2 associates to left - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 1)) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprNumber(0, 0, 5)) // ... = 5 associates to right - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprNumber(0, 0, 5)) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) // minus has > precedence than = - .addChild(new ExprNumber(0, 0, 6)) - .addChild(new ExprNumber(0, 0, 1))))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprInfix(0, 0, OP_ADD) // 1 + 2 + 2 associates to left + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) // ... = 5 associates to right + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) // minus has > precedence than = + .addChild(new ExprNumber(0, 0, 6)) + .addChild(new ExprNumber(0, 0, 1))))))), + program ); } @@ -143,28 +143,28 @@ public void testAssociativityEqual() { public void testAndMulXorDivNotPlusMinus() { Program program = parseProgram("db not 1 and 2 or 2 xor 5 = - 5 * 6 shl 4 - 1 shr 2"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_OR) - .addChild(new ExprInfix(0, 0, OP_AND) - .addChild(new ExprUnary(0, 0, OP_NOT) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprInfix(0, 0, OP_XOR) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprNumber(0, 0, 5)) - .addChild(new ExprInfix(0, 0, OP_SHR) - .addChild(new ExprInfix(0, 0, OP_SHL) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 5))) - .addChild(new ExprNumber(0, 0, 6))) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 4)) - .addChild(new ExprNumber(0, 0, 1)))) - .addChild(new ExprNumber(0, 0, 2))))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_OR) + .addChild(new ExprInfix(0, 0, OP_AND) + .addChild(new ExprUnary(0, 0, OP_NOT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SHR) + .addChild(new ExprInfix(0, 0, OP_SHL) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))))), + program ); } @@ -172,28 +172,28 @@ public void testAndMulXorDivNotPlusMinus() { public void testAndMulXorDivNotPlusMinusWithOperators() { Program program = parseProgram("db ~1 & 2 | 2 ^ 5 = -5 * 6 << 4 - 1 >> 2"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_OR_2) - .addChild(new ExprInfix(0, 0, OP_AND_2) - .addChild(new ExprUnary(0, 0, OP_NOT_2) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprInfix(0, 0, OP_XOR_2) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprNumber(0, 0, 5)) - .addChild(new ExprInfix(0, 0, OP_SHR_2) - .addChild(new ExprInfix(0, 0, OP_SHL_2) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 5))) - .addChild(new ExprNumber(0, 0, 6))) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 4)) - .addChild(new ExprNumber(0, 0, 1)))) - .addChild(new ExprNumber(0, 0, 2))))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_OR_2) + .addChild(new ExprInfix(0, 0, OP_AND_2) + .addChild(new ExprUnary(0, 0, OP_NOT_2) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR_2) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SHR_2) + .addChild(new ExprInfix(0, 0, OP_SHL_2) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))))), + program ); } @@ -201,16 +201,16 @@ public void testAndMulXorDivNotPlusMinusWithOperators() { public void testParenthesis() { Program program = parseProgram("db (2 + 3) * (4 - 2)"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 4)) - .addChild(new ExprNumber(0, 0, 2))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 2))))), + program ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseInstrTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseInstrTest.java index 79ac8e776..31f59ae80 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseInstrTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParseInstrTest.java @@ -127,8 +127,8 @@ public void testRegPair() { @Test public void testMVI() { Node expr = new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 5)); + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); forStringCaseVariations("mvi", instrVariation -> { for (Map.Entry register : registers.entrySet()) { @@ -136,10 +136,10 @@ public void testMVI() { String row = instrVariation + " " + registerVariation + ", $ + 5"; Program program = parseProgram(row); assertTrees( - new Program() - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, register.getValue()) - .addChild(expr)), - program + new Program() + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, register.getValue()) + .addChild(expr)), + program ); }); } @@ -149,8 +149,8 @@ public void testMVI() { @Test public void testLXI() { Node expr = new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 5)); + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); forStringCaseVariations("lxi", instrVariation -> { for (Map.Entry regPair : regPairsBDHSP.entrySet()) { @@ -158,10 +158,10 @@ public void testLXI() { String row = instrVariation + " " + registerVariation + ", $ + 5"; Program program = parseProgram(row); assertTrees( - new Program() - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, regPair.getValue()) - .addChild(expr)), - program + new Program() + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, regPair.getValue()) + .addChild(expr)), + program ); }); } @@ -179,9 +179,9 @@ public void testMOV() { String row = instrVariation + " " + registerVariation1 + ", " + registerVariation2; Program program = parseProgram(row); assertTrees( - new Program() - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, register1.getValue(), register2.getValue())), - program + new Program() + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, register1.getValue(), register2.getValue())), + program ); } }); @@ -205,8 +205,8 @@ private void assertInstrReg(String instr, int instrType) { String row = instrVariation + " " + registerVariation; Program program = parseProgram(row); assertTrees( - new Program().addChild(new InstrReg(0, 0, instrType, register.getValue())), - program + new Program().addChild(new InstrReg(0, 0, instrType, register.getValue())), + program ); }); } @@ -215,8 +215,8 @@ private void assertInstrReg(String instr, int instrType) { private void assertInstrExpr(String instr, int instrType) { Node expr = new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 5)); + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); forStringCaseVariations(instr, variation -> { Program program = parseProgram(variation + " $ + 5"); @@ -231,8 +231,8 @@ private void assertInstrRegPair(String instr, int instrType, Map programs = List.of( - "if 1\n\n\nendif", - "if 1\n\nendif", - "if 1\nendif" + "if 1\n\n\nendif", + "if 1\n\nendif", + "if 1\nendif" ); for (String src : programs) { Program program = parseProgram(src); Node expected = new Program() - .addChild(new PseudoIf(0, 0) - .addChild(new PseudoIfExpression(0, 0) - .addChild(new ExprNumber(0, 0, 1)))); + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 1)))); assertTrees(expected, program); } } @@ -112,17 +112,17 @@ public void testIfEndifMustBeOnNewLine() { @Test public void testTwoLabelsInsideIf() { Program program = parseProgram("if 1\n" - + " label1:\n" - + " label2:\n" - + "endif"); + + " label1:\n" + + " label2:\n" + + "endif"); assertTrees(new Program() - .addChild(new PseudoIf(0, 0) - .addChild(new PseudoIfExpression(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoLabel(0, 0, "label1")) - .addChild(new PseudoLabel(0, 0, "label2"))), - program + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoLabel(0, 0, "label1")) + .addChild(new PseudoLabel(0, 0, "label2"))), + program ); } @@ -130,28 +130,28 @@ public void testTwoLabelsInsideIf() { public void testInclude() { Program program = parseProgram("include 'filename.asm'"); assertTrees( - new Program().addChild(new PseudoInclude(0, 0, "filename.asm")), - program + new Program().addChild(new PseudoInclude(0, 0, "filename.asm")), + program ); } @Test public void testMacroDef() { Program program = parseProgram("shrt macro param1, param2\n" - + " rrc\n" - + " heylabel: ani 7Fh\n" - + "endm\n\n"); + + " rrc\n" + + " heylabel: ani 7Fh\n" + + "endm\n\n"); Node expected = new Program() - .addChild(new PseudoMacroDef(0, 0, "shrt") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "param1"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "param2"))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) - .addChild(new PseudoLabel(0, 0, "heylabel") - .addChild(new InstrExpr(0, 0, OPCODE_ANI) - .addChild(new ExprNumber(0, 0, 0x7F))))); + .addChild(new PseudoMacroDef(0, 0, "shrt") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "param1"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "param2"))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) + .addChild(new PseudoLabel(0, 0, "heylabel") + .addChild(new InstrExpr(0, 0, OPCODE_ANI) + .addChild(new ExprNumber(0, 0, 0x7F))))); assertTrees(expected, program); } @@ -159,9 +159,9 @@ public void testMacroDef() { @Test public void testMacroDefEmpty() { List programs = List.of( - "shrt macro\n\n\nendm", - "shrt macro\n\nendm", - "shrt macro\nendm" + "shrt macro\n\n\nendm", + "shrt macro\n\nendm", + "shrt macro\nendm" ); for (String src : programs) { @@ -188,11 +188,11 @@ public void testMacroCallWithParams() { Program program = parseProgram("shrt param1, 45"); Node expected = new Program() - .addChild(new PseudoMacroCall(0, 0, "shrt") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "param1"))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 45)))); + .addChild(new PseudoMacroCall(0, 0, "shrt") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "param1"))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 45)))); assertTrees(expected, program); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsingUtilsTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsingUtilsTest.java index c6341735f..b26f34009 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsingUtilsTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/parser/ParsingUtilsTest.java @@ -61,8 +61,8 @@ public void testParseLitHex2() { public void testParseLitOct() { List tokens = getTokens("22q 55O 77Q 001o"); assertTokenTypes( - tokens, - LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, EOF + tokens, + LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, EOF ); assertEquals(18, ParsingUtils.parseLitOct(tokens.get(0))); assertEquals(45, ParsingUtils.parseLitOct(tokens.get(2))); @@ -74,8 +74,8 @@ public void testParseLitOct() { public void testParseLitDec() { List tokens = getTokens("22 55 00"); assertTokenTypes( - tokens, - LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF + tokens, + LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF ); assertEquals(22, ParsingUtils.parseLitDec(tokens.get(0))); assertEquals(55, ParsingUtils.parseLitDec(tokens.get(2))); @@ -86,8 +86,8 @@ public void testParseLitDec() { public void testParseLitBin() { List tokens = getTokens("000b 0101101b 111b"); assertTokenTypes( - tokens, - LIT_BINNUMBER, WS, LIT_BINNUMBER, WS, LIT_BINNUMBER, EOF + tokens, + LIT_BINNUMBER, WS, LIT_BINNUMBER, WS, LIT_BINNUMBER, EOF ); assertEquals(0, ParsingUtils.parseLitBin(tokens.get(0))); assertEquals(45, ParsingUtils.parseLitBin(tokens.get(2))); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java index 168297536..575974084 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/CheckExprSizesVisitorTest.java @@ -43,8 +43,8 @@ public class CheckExprSizesVisitorTest { public void testDBoneByte() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0,0, 0xFF))); + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 0xFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -56,9 +56,9 @@ public void testDBoneByte() { public void testDBtwoBytes() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0,0, 0xFF)) - .addChild(new Evaluated(0,0, 0x100))); // bad size + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 0xFF)) + .addChild(new Evaluated(0, 0, 0x100))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -70,8 +70,8 @@ public void testDBtwoBytes() { public void testDWtwoBytes() { Program program = new Program(); program - .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0,0, 0xFFFF))); + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 0xFFFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -83,9 +83,9 @@ public void testDWtwoBytes() { public void testDWthreeBytes() { Program program = new Program(); program - .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0,0, 0xFFFF)) - .addChild(new Evaluated(0,0, 0x10000))); + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 0xFFFF)) + .addChild(new Evaluated(0, 0, 0x10000))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -97,8 +97,8 @@ public void testDWthreeBytes() { public void testDStwoBytes() { Program program = new Program(); program - .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0,0, 0xFFFF))); + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 0xFFFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -110,8 +110,8 @@ public void testDStwoBytes() { public void testDSthreeBytes() { Program program = new Program(); program - .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0,0, 0x10000))); + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 0x10000))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -123,8 +123,8 @@ public void testDSthreeBytes() { public void testInstrExprTwoBytes() { Program program = new Program(); program - .addChild(new InstrExpr(0, 0, OPCODE_ADI) - .addChild(new Evaluated(0,0, 0xFF00))); + .addChild(new InstrExpr(0, 0, OPCODE_ADI) + .addChild(new Evaluated(0, 0, 0xFF00))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -136,8 +136,8 @@ public void testInstrExprTwoBytes() { public void testInstrExprThreeBytes() { Program program = new Program(); program - .addChild(new InstrExpr(0, 0, OPCODE_JMP) - .addChild(new Evaluated(0,0, 0xFF000))); + .addChild(new InstrExpr(0, 0, OPCODE_JMP) + .addChild(new Evaluated(0, 0, 0xFF000))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -149,8 +149,8 @@ public void testInstrExprThreeBytes() { public void testInstrRegExprOneByte() { Program program = new Program(); program - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0,0, 0xFF))); + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0, 0, 0xFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -162,8 +162,8 @@ public void testInstrRegExprOneByte() { public void testInstrRegExprTwoBytes() { Program program = new Program(); program - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0,0, 0x100))); // bad size + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0, 0, 0x100))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -175,8 +175,8 @@ public void testInstrRegExprTwoBytes() { public void testInstrRegPairExprTwoBytes() { Program program = new Program(); program - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0,0, 0xFFFF))); + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0xFFFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -188,8 +188,8 @@ public void testInstrRegPairExprTwoBytes() { public void testInstrRegPairExprThreeBytes() { Program program = new Program(); program - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0,0, 0x10000))); // bad size + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0x10000))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -201,8 +201,8 @@ public void testInstrRegPairExprThreeBytes() { public void testPseudoOrgTwoBytes() { Program program = new Program(); program - .addChild(new PseudoOrg(0, 0) - .addChild(new Evaluated(0,0, 0xFFFF))); + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0, 0, 0xFFFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -214,8 +214,8 @@ public void testPseudoOrgTwoBytes() { public void testPseudoOrgThreeBytes() { Program program = new Program(); program - .addChild(new PseudoOrg(0, 0) - .addChild(new Evaluated(0,0, 0x10000))); // bad size + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0, 0, 0x10000))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -227,35 +227,35 @@ public void testPseudoOrgThreeBytes() { public void testMacroArgumentsAreRemoved() { Program program = new Program(); program - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 1)))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0)))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 1)))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0)))), - program + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))), + program ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java index b04e5cd05..5131e2472 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/EvaluateExprVisitorTest.java @@ -49,30 +49,30 @@ public class EvaluateExprVisitorTest { public void testEvaluateDB() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 1)) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprNumber(0, 0, 'h')) - .addChild(new ExprNumber(0, 0, 'e')) - .addChild(new ExprNumber(0, 0, 'l')) - .addChild(new ExprNumber(0, 0, 'l')) - .addChild(new ExprNumber(0, 0, 'o')) - ); + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 'h')) + .addChild(new ExprNumber(0, 0, 'e')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'o')) + ); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 3)) - .addChild(new Evaluated(0, 0, 'h')) - .addChild(new Evaluated(0, 0, 'e')) - .addChild(new Evaluated(0, 0, 'l')) - .addChild(new Evaluated(0, 0, 'l')) - .addChild(new Evaluated(0, 0, 'o'))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 3)) + .addChild(new Evaluated(0, 0, 'h')) + .addChild(new Evaluated(0, 0, 'e')) + .addChild(new Evaluated(0, 0, 'l')) + .addChild(new Evaluated(0, 0, 'l')) + .addChild(new Evaluated(0, 0, 'o'))), + program ); } @@ -80,23 +80,23 @@ public void testEvaluateDB() { public void testEvaluateDW() { Program program = new Program(); program - .addChild(new DataDW(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 1)) - .addChild(new ExprNumber(0, 0, 2)))) - .addChild(new DataDW(0, 0) - .addChild(new ExprNumber(0, 0, 0))); + .addChild(new DataDW(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new DataDW(0, 0) + .addChild(new ExprNumber(0, 0, 0))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0, 3))) - .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0, 0))), - program + new Program() + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 3))) + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 0))), + program ); assertEquals(0, program.getChild(0).getAddress()); assertEquals(2, program.getChild(1).getAddress()); @@ -106,23 +106,23 @@ public void testEvaluateDW() { public void testEvaluateDS() { Program program = new Program(); program - .addChild(new DataDS(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 1)) - .addChild(new ExprNumber(0, 0, 2)))) - .addChild(new DataDB(0, 0) - .addChild(new ExprNumber(0, 0, 0))); + .addChild(new DataDS(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new DataDB(0, 0) + .addChild(new ExprNumber(0, 0, 0))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0, 0, 3))) - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 0))), - program + new Program() + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 3))) + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 0))), + program ); assertEquals(0, program.getChild(0).getAddress()); assertEquals(3, program.getChild(1).getAddress()); @@ -132,9 +132,9 @@ public void testEvaluateDS() { public void testEvaluateDSambiguous() { Program program = new Program(); program - .addChild(new DataDS(0, 0) - .addChild(new ExprId(0, 0, "label"))) - .addChild(new PseudoLabel(0, 0, "label")); + .addChild(new DataDS(0, 0) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new PseudoLabel(0, 0, "label")); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -146,10 +146,10 @@ public void testEvaluateDSambiguous() { public void testEvaluateDSconstReference() { Program program = new Program(); program - .addChild(new DataDS(0, 0) - .addChild(new ExprId(0, 0, "label"))) - .addChild(new PseudoEqu(0, 0, "label") - .addChild(new ExprNumber(0, 0, 5))); + .addChild(new DataDS(0, 0) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new PseudoEqu(0, 0, "label") + .addChild(new ExprNumber(0, 0, 5))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -161,10 +161,10 @@ public void testEvaluateDSconstReference() { assertEquals(0, label.get().getAddress()); assertTrees( - new Program() - .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0, 0, 5))), - program + new Program() + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 5))), + program ); } @@ -172,16 +172,16 @@ public void testEvaluateDSconstReference() { public void testEvaluateEQUfivePasses() { Program program = new Program(); program - .addChild(new PseudoEqu(0, 0, "one") - .addChild(new ExprId(0, 0, "two"))) - .addChild(new PseudoEqu(0, 0, "two") - .addChild(new ExprId(0, 0, "three"))) - .addChild(new PseudoEqu(0, 0, "three") - .addChild(new ExprId(0, 0, "four"))) - .addChild(new PseudoEqu(0, 0, "four") - .addChild(new ExprId(0, 0, "five"))) - .addChild(new PseudoEqu(0, 0, "five") - .addChild(new ExprCurrentAddress(0, 0))); + .addChild(new PseudoEqu(0, 0, "one") + .addChild(new ExprId(0, 0, "two"))) + .addChild(new PseudoEqu(0, 0, "two") + .addChild(new ExprId(0, 0, "three"))) + .addChild(new PseudoEqu(0, 0, "three") + .addChild(new ExprId(0, 0, "four"))) + .addChild(new PseudoEqu(0, 0, "four") + .addChild(new ExprId(0, 0, "five"))) + .addChild(new PseudoEqu(0, 0, "five") + .addChild(new ExprCurrentAddress(0, 0))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -202,30 +202,30 @@ public void testEvaluateEQUfivePasses() { public void testEvaluateIFwithForwardConst() { Program program = new Program(); program - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoIf(0, 0) - .addChild(new PseudoIfExpression(0, 0) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 2)))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new ExprNumber(0, 0, 0)))) - .addChild(new PseudoEqu(0, 0, "const") - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprCurrentAddress(0, 0)))); + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprCurrentAddress(0, 0)))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0, 0, 6))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 0))), - program + new Program() + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0, 0, 6))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 0))), + program ); assertEquals(0, program.getChild(0).getAddress()); assertEquals(2, program.getChild(1).getAddress()); @@ -235,17 +235,17 @@ public void testEvaluateIFwithForwardConst() { public void testEvaluateIFwithForwardAddressReference() { Program program = new Program(); program - .addChild(new PseudoIf(0, 0) - .addChild(new PseudoIfExpression(0, 0) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprId(0, 0, "const")))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new ExprNumber(0, 0, 0)))) - .addChild(new PseudoEqu(0, 0, "const") - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprCurrentAddress(0, 0)))); + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "const")))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprCurrentAddress(0, 0)))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -257,11 +257,11 @@ public void testEvaluateIFwithForwardAddressReference() { public void testEvaluateIFexcludeBlock() { Program program = new Program(); program - .addChild(new PseudoIf(0, 0) - .addChild(new PseudoIfExpression(0, 0) - .addChild(new ExprNumber(0, 0, 0))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new ExprNumber(0, 0, 0)))); + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new ExprNumber(0, 0, 0)))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -273,29 +273,29 @@ public void testEvaluateIFexcludeBlock() { public void testEvaluateSETforwardTwoTimes() { Program program = new Program(); program - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoSet(0, 0, "const") - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) - .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoSet(0, 0, "const") - .addChild(new ExprNumber(0, 0, 2))); + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new ExprNumber(0, 0, 2))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoSet(0, 0, "const") - .addChild(new Evaluated(0, 0, 1))) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoSet(0, 0, "const") - .addChild(new Evaluated(0, 0, 2))), - program + new Program() + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new Evaluated(0, 0, 1))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoSet(0, 0, "const") + .addChild(new Evaluated(0, 0, 2))), + program ); } @@ -303,27 +303,27 @@ public void testEvaluateSETforwardTwoTimes() { public void testEvaluateSETforwardMoreTimes() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new ExprId(0, 0, "id"))) - .addChild(new PseudoSet(0, 0, "id") - .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoSet(0, 0, "id") - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoEqu(0, 0, "const") - .addChild(new ExprNumber(0, 0, 1))); + .addChild(new DataDB(0, 0) + .addChild(new ExprId(0, 0, "id"))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoSet(0, 0, "id") - .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoSet(0, 0, "id") - .addChild(new Evaluated(0, 0, 2))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0, 2))), + program ); } @@ -331,27 +331,27 @@ public void testEvaluateSETforwardMoreTimes() { public void testTwoSETthenReference() { Program program = new Program(); program - .addChild(new PseudoSet(0, 0, "id") - .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoSet(0, 0, "id") - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoEqu(0, 0, "const") - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new DataDB(0, 0) - .addChild(new ExprId(0, 0, "id"))); + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new DataDB(0, 0) + .addChild(new ExprId(0, 0, "id"))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new PseudoSet(0, 0, "id") - .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoSet(0, 0, "id") - .addChild(new Evaluated(0, 0, 2))) - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 2))), - program + new Program() + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoSet(0, 0, "id") + .addChild(new Evaluated(0, 0, 2))) + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 2))), + program ); } @@ -359,28 +359,28 @@ public void testTwoSETthenReference() { public void testEvaluateLABEL() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprId(0, 0, "label"))) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprId(0, 0, "label"))) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprId(0, 0, "label")))) - .addChild(new PseudoLabel(0, 0, "label")); + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label")))) + .addChild(new PseudoLabel(0, 0, "label")); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 3)) - .addChild(new Evaluated(0, 0, 4)) - .addChild(new Evaluated(0, 0, 5))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 3)) + .addChild(new Evaluated(0, 0, 4)) + .addChild(new Evaluated(0, 0, 5))), + program ); } @@ -388,26 +388,26 @@ public void testEvaluateLABEL() { public void testEvaluateMacroCalls() { Program program = new Program(); program - .addChild(new PseudoLabel(0, 0, "label")) - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "addr")) - .addChild(new ExprId(0, 0, "label"))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new ExprId(0, 0, "addr")))); + .addChild(new PseudoLabel(0, 0, "label")) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "addr")) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "addr")))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "addr")) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0)))), - program + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "addr")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))), + program ); } @@ -415,13 +415,13 @@ public void testEvaluateMacroCalls() { public void testEvaluateMacroCallAmbiguous() { Program program = new Program(); program - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "label")) - .addChild(new ExprId(0, 0, "addr"))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new ExprId(0, 0, "addr")))) - .addChild(new PseudoLabel(0, 0, "label")); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "label")) + .addChild(new ExprId(0, 0, "addr"))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "addr")))) + .addChild(new PseudoLabel(0, 0, "label")); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -433,41 +433,41 @@ public void testEvaluateMacroCallAmbiguous() { public void testEvaluateMacroScopedArguments() { Program program = new Program(); program - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new ExprNumber(0, 0, 0))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new ExprId(0, 0, "arg"))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new ExprId(0, 0, "arg")))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new ExprId(0, 0, "arg")))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new ExprNumber(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "arg"))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "arg")))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new ExprId(0, 0, "arg")))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 1)))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0)))), - program + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0)))), + program ); } @@ -475,15 +475,15 @@ public void testEvaluateMacroScopedArguments() { public void testLabelKeepsChildren() { Program program = new Program(); program - .addChild(new PseudoLabel(0, 0, "label") - .addChild(new InstrNoArgs(0, 0, OPCODE_RET))); + .addChild(new PseudoLabel(0, 0, "label") + .addChild(new InstrNoArgs(0, 0, OPCODE_RET))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program().addChild(new InstrNoArgs(0, 0, OPCODE_RET)), - program + new Program().addChild(new InstrNoArgs(0, 0, OPCODE_RET)), + program ); } } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java index f8f32eceb..b07e8a3aa 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandIncludesVisitorTest.java @@ -18,12 +18,12 @@ */ package net.emustudio.plugins.compiler.as8080.visitors; -import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoLabel; import net.emustudio.plugins.compiler.as8080.ast.Node; import net.emustudio.plugins.compiler.as8080.ast.Program; import net.emustudio.plugins.compiler.as8080.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrNoArgs; import net.emustudio.plugins.compiler.as8080.ast.instr.InstrRegExpr; +import net.emustudio.plugins.compiler.as8080.ast.pseudo.PseudoLabel; import net.emustudio.plugins.compiler.as8080.exceptions.FatalError; import org.junit.Rule; import org.junit.Test; @@ -49,11 +49,11 @@ public void testExpandInclude() { visitor.visit(program); Node expected = new Program() - .addChild(new InstrNoArgs(0, 0, OPCODE_CMC)) - .addChild(new PseudoLabel(0, 0, "sample")) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new ExprNumber(0, 0, 0))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RET)); + .addChild(new InstrNoArgs(0, 0, OPCODE_CMC)) + .addChild(new PseudoLabel(0, 0, "sample")) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprNumber(0, 0, 0))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RET)); assertTrees(expected, program); } @@ -64,15 +64,15 @@ public void testExpandIncludeTwoTimes() throws IOException { write(file, "rrc"); Program program = parseProgram( - "include '" + file.getPath() + "'\n" + - "include '" + file.getPath() + "'" + "include '" + file.getPath() + "'\n" + + "include '" + file.getPath() + "'" ); ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); visitor.visit(program); Node expected = new Program() - .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) - .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)); + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)); assertTrees(expected, program); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java index 3c0ecbed9..98b3e7b65 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/ExpandMacrosTest.java @@ -48,9 +48,9 @@ public void testMacroDefinitionThenMacroCall() { macrosVisitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroDef(0, 0, "x"))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program ); } @@ -61,9 +61,9 @@ public void testMacroCallThenMacroDefinition() { macrosVisitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroDef(0, 0, "x"))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program ); } @@ -74,11 +74,11 @@ public void testMacroCallThenMacroDefinitionThenMacroCall() { macrosVisitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroDef(0, 0, "x"))) - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroDef(0, 0, "x"))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program ); } @@ -94,9 +94,9 @@ public void testMacroCallThenMacroDefinitionInsideInclude() throws IOException { macrosVisitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroDef(0, 0, "x"))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program ); } @@ -121,21 +121,21 @@ public void testMacroCallWithArguments() { macrosVisitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "r"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "t"))))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "r"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "t"))))), + program ); } diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java index 907be4b3b..3c5db923b 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/GenerateCodeVisitorTest.java @@ -40,22 +40,22 @@ public class GenerateCodeVisitorTest { public void testCodeGeneration() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 255)) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 4)))) - .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0, 0, 5))) - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0xFEAB))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_D) - .addChild(new Evaluated(0, 0, 1)))) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_H) - .addChild(new Evaluated(0, 0, 0x1234)))); + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 255)) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 4)))) + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 5))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0xFEAB))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_D) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_H) + .addChild(new Evaluated(0, 0, 0x1234)))); IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); @@ -86,13 +86,13 @@ public void testCodeGeneration() { public void testPseudoOrg() { Program program = new Program(); program - .addChild(new PseudoOrg(0, 0) - .addChild(new Evaluated(0, 0, 5))) - .addChild(new InstrExpr(0, 0, OPCODE_CNZ) - .addChild(new Evaluated(0, 0, 0x400))) - .addChild(new PseudoOrg(0, 0) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new InstrNoArgs(0, 0, OPCODE_XCHG)); + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0, 0, 5))) + .addChild(new InstrExpr(0, 0, OPCODE_CNZ) + .addChild(new Evaluated(0, 0, 0x400))) + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrNoArgs(0, 0, OPCODE_XCHG)); IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); @@ -109,302 +109,302 @@ public void testPseudoOrg() { public void testGenerateInstructions() { Program program = new Program(); program - .addChild(new InstrNoArgs(0, 0, OPCODE_NOP)) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrRegPair(0, 0, OPCODE_STAX, REG_B)) - .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_B)) - .addChild(new InstrReg(0, 0, OPCODE_INR, REG_B)) - .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_B)) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) - .addChild(new Evaluated(0, 0, 7))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RLC)) - .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_B)) - .addChild(new InstrRegPair(0, 0, OPCODE_LDAX, REG_B)) - .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_B)) - .addChild(new InstrReg(0, 0, OPCODE_INR, REG_C)) - .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_C)) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_C) - .addChild(new Evaluated(0, 0, 8))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_D) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrRegPair(0, 0, OPCODE_STAX, REG_D)) - .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_D)) - .addChild(new InstrReg(0, 0, OPCODE_INR, REG_D)) - .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_D)) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_D) - .addChild(new Evaluated(0, 0, 9))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RAL)) - .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_D)) - .addChild(new InstrRegPair(0, 0, OPCODE_LDAX, REG_D)) - .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_D)) - .addChild(new InstrReg(0, 0, OPCODE_INR, REG_E)) - .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_E)) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_E) - .addChild(new Evaluated(0, 0, 10))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RAR)) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_H) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrExpr(0, 0, OPCODE_SHLD) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_H)) - .addChild(new InstrReg(0, 0, OPCODE_INR, REG_H)) - .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_H)) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_H) - .addChild(new Evaluated(0, 0, 0x28))) - .addChild(new InstrNoArgs(0, 0, OPCODE_DAA)) - .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_H)) - .addChild(new InstrExpr(0, 0, OPCODE_LHLD) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_H)) - .addChild(new InstrReg(0, 0, OPCODE_INR, REG_L)) - .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_L)) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_L) - .addChild(new Evaluated(0, 0, 10))) - .addChild(new InstrNoArgs(0, 0, OPCODE_CMA)) - .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_SP) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrExpr(0, 0, OPCODE_STA) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_SP)) - .addChild(new InstrReg(0, 0, OPCODE_INR, REG_M)) - .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_M)) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_M) - .addChild(new Evaluated(0, 0, 7))) - .addChild(new InstrNoArgs(0, 0, OPCODE_STC)) - .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_SP)) - .addChild(new InstrExpr(0, 0, OPCODE_LDA) - .addChild(new Evaluated(0, 0, 0x2345))) - .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_SP)) - .addChild(new InstrReg(0, 0, OPCODE_INR, REG_A)) - .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_A)) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new Evaluated(0, 0, -128))) - .addChild(new InstrNoArgs(0, 0, OPCODE_CMC)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_B)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_C)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_D)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_E)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_H)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_L)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_M)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_A)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_B)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_C)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_D)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_E)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_H)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_L)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_M)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_A)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_B)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_C)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_D)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_E)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_H)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_L)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_M)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_A)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_B)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_C)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_D)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_E)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_H)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_L)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_M)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_A)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_B)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_C)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_D)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_E)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_H)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_L)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_M)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_A)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_B)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_C)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_D)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_E)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_H)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_L)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_M)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_A)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_B)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_C)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_D)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_E)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_H)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_L)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_M)) // HLT - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_A)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_B)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_C)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_D)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_E)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_H)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_L)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_M)) - .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_A)) - .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_B)) - .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_C)) - .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_D)) - .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_E)) - .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_H)) - .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_L)) - .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_M)) - .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_A)) - .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_B)) - .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_C)) - .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_D)) - .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_E)) - .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_H)) - .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_L)) - .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_M)) - .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_A)) - .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_B)) - .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_C)) - .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_D)) - .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_E)) - .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_H)) - .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_L)) - .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_M)) - .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_A)) - .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_B)) - .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_C)) - .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_D)) - .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_E)) - .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_H)) - .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_L)) - .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_M)) - .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_A)) - .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_B)) - .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_C)) - .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_D)) - .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_E)) - .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_H)) - .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_L)) - .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_M)) - .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_A)) - .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_B)) - .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_C)) - .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_D)) - .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_E)) - .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_H)) - .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_L)) - .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_M)) - .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_A)) - .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_B)) - .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_C)) - .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_D)) - .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_E)) - .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_H)) - .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_L)) - .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_M)) - .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_A)) - .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_B)) - .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_C)) - .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_D)) - .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_E)) - .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_H)) - .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_L)) - .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_M)) - .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_A)) - .addChild(new InstrNoArgs(0, 0, OPCODE_RNZ)) - .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_B)) - .addChild(new InstrExpr(0, 0, OPCODE_JNZ) - .addChild(new Evaluated(0, 0, 2))) - .addChild(new InstrExpr(0, 0, OPCODE_JMP) - .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new InstrExpr(0, 0, OPCODE_CNZ) - .addChild(new Evaluated(0, 0, 0xF0A0))) - .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_B)) - .addChild(new InstrExpr(0, 0, OPCODE_ADI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RZ)) - .addChild(new InstrNoArgs(0, 0, OPCODE_RET)) - .addChild(new InstrExpr(0, 0, OPCODE_JZ) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrExpr(0, 0, OPCODE_CZ) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrExpr(0, 0, OPCODE_CALL) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrExpr(0, 0, OPCODE_ACI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RNC)) - .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_D)) - .addChild(new InstrExpr(0, 0, OPCODE_JNC) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrExpr(0, 0, OPCODE_OUT) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrExpr(0, 0, OPCODE_CNC) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_D)) - .addChild(new InstrExpr(0, 0, OPCODE_SUI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 2))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RC)) - .addChild(new InstrExpr(0, 0, OPCODE_JC) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrExpr(0, 0, OPCODE_IN) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrExpr(0, 0, OPCODE_CC) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrExpr(0, 0, OPCODE_SBI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 3))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RPO)) - .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_H)) - .addChild(new InstrExpr(0, 0, OPCODE_JPO) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrNoArgs(0, 0, OPCODE_XTHL)) - .addChild(new InstrExpr(0, 0, OPCODE_CPO) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_H)) - .addChild(new InstrExpr(0, 0, OPCODE_ANI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 4))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RPE)) - .addChild(new InstrNoArgs(0, 0, OPCODE_PCHL)) - .addChild(new InstrExpr(0, 0, OPCODE_JPE) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrNoArgs(0, 0, OPCODE_XCHG)) - .addChild(new InstrExpr(0, 0, OPCODE_CPE) - .addChild(new Evaluated(0, 0, 0x1234))) - .addChild(new InstrExpr(0, 0, OPCODE_XRI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 5))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RP)) - .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_PSW)) - .addChild(new InstrExpr(0, 0, OPCODE_JP) - .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new InstrNoArgs(0, 0, OPCODE_DI)) - .addChild(new InstrExpr(0, 0, OPCODE_CP) - .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_PSW)) - .addChild(new InstrExpr(0, 0, OPCODE_ORI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 6))) - .addChild(new InstrNoArgs(0, 0, OPCODE_RM)) - .addChild(new InstrNoArgs(0, 0, OPCODE_SPHL)) - .addChild(new InstrExpr(0, 0, OPCODE_JM) - .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new InstrNoArgs(0, 0, OPCODE_EI)) - .addChild(new InstrExpr(0, 0, OPCODE_CM) - .addChild(new Evaluated(0, 0, 0x200))) - .addChild(new InstrExpr(0, 0, OPCODE_CPI) - .addChild(new Evaluated(0, 0, 0xF0))) - .addChild(new InstrExpr(0, 0, OPCODE_RST) - .addChild(new Evaluated(0, 0, 7))); + .addChild(new InstrNoArgs(0, 0, OPCODE_NOP)) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_B) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrRegPair(0, 0, OPCODE_STAX, REG_B)) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_B)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_B) + .addChild(new Evaluated(0, 0, 7))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RLC)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_B)) + .addChild(new InstrRegPair(0, 0, OPCODE_LDAX, REG_B)) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_C)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_C) + .addChild(new Evaluated(0, 0, 8))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RRC)) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_D) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_STAX, REG_D)) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_D)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_D) + .addChild(new Evaluated(0, 0, 9))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RAL)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_D)) + .addChild(new InstrRegPair(0, 0, OPCODE_LDAX, REG_D)) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_E)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_E) + .addChild(new Evaluated(0, 0, 10))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RAR)) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_H) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrExpr(0, 0, OPCODE_SHLD) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_H)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_H) + .addChild(new Evaluated(0, 0, 0x28))) + .addChild(new InstrNoArgs(0, 0, OPCODE_DAA)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_H)) + .addChild(new InstrExpr(0, 0, OPCODE_LHLD) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_L)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_L) + .addChild(new Evaluated(0, 0, 10))) + .addChild(new InstrNoArgs(0, 0, OPCODE_CMA)) + .addChild(new InstrRegPairExpr(0, 0, OPCODE_LXI, REG_SP) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrExpr(0, 0, OPCODE_STA) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_INX, REG_SP)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_M)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_M) + .addChild(new Evaluated(0, 0, 7))) + .addChild(new InstrNoArgs(0, 0, OPCODE_STC)) + .addChild(new InstrRegPair(0, 0, OPCODE_DAD, REG_SP)) + .addChild(new InstrExpr(0, 0, OPCODE_LDA) + .addChild(new Evaluated(0, 0, 0x2345))) + .addChild(new InstrRegPair(0, 0, OPCODE_DCX, REG_SP)) + .addChild(new InstrReg(0, 0, OPCODE_INR, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_DCR, REG_A)) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new Evaluated(0, 0, -128))) + .addChild(new InstrNoArgs(0, 0, OPCODE_CMC)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_B, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_C, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_D, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_E, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_H, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_L, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_M)) // HLT + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_M, REG_A)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_B)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_C)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_D)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_E)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_H)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_L)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_M)) + .addChild(new InstrRegReg(0, 0, OPCODE_MOV, REG_A, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ADD, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ADC, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_SUB, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_SBB, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ANA, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_XRA, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_ORA, REG_A)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_B)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_C)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_D)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_E)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_H)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_L)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_M)) + .addChild(new InstrReg(0, 0, OPCODE_CMP, REG_A)) + .addChild(new InstrNoArgs(0, 0, OPCODE_RNZ)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_B)) + .addChild(new InstrExpr(0, 0, OPCODE_JNZ) + .addChild(new Evaluated(0, 0, 2))) + .addChild(new InstrExpr(0, 0, OPCODE_JMP) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrExpr(0, 0, OPCODE_CNZ) + .addChild(new Evaluated(0, 0, 0xF0A0))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_B)) + .addChild(new InstrExpr(0, 0, OPCODE_ADI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RZ)) + .addChild(new InstrNoArgs(0, 0, OPCODE_RET)) + .addChild(new InstrExpr(0, 0, OPCODE_JZ) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_CZ) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_CALL) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_ACI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RNC)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_D)) + .addChild(new InstrExpr(0, 0, OPCODE_JNC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_OUT) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_CNC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_D)) + .addChild(new InstrExpr(0, 0, OPCODE_SUI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 2))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RC)) + .addChild(new InstrExpr(0, 0, OPCODE_JC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_IN) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_CC) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_SBI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 3))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RPO)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_H)) + .addChild(new InstrExpr(0, 0, OPCODE_JPO) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrNoArgs(0, 0, OPCODE_XTHL)) + .addChild(new InstrExpr(0, 0, OPCODE_CPO) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_H)) + .addChild(new InstrExpr(0, 0, OPCODE_ANI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 4))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RPE)) + .addChild(new InstrNoArgs(0, 0, OPCODE_PCHL)) + .addChild(new InstrExpr(0, 0, OPCODE_JPE) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrNoArgs(0, 0, OPCODE_XCHG)) + .addChild(new InstrExpr(0, 0, OPCODE_CPE) + .addChild(new Evaluated(0, 0, 0x1234))) + .addChild(new InstrExpr(0, 0, OPCODE_XRI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 5))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RP)) + .addChild(new InstrRegPair(0, 0, OPCODE_POP, REG_PSW)) + .addChild(new InstrExpr(0, 0, OPCODE_JP) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrNoArgs(0, 0, OPCODE_DI)) + .addChild(new InstrExpr(0, 0, OPCODE_CP) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrRegPair(0, 0, OPCODE_PUSH, REG_PSW)) + .addChild(new InstrExpr(0, 0, OPCODE_ORI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 6))) + .addChild(new InstrNoArgs(0, 0, OPCODE_RM)) + .addChild(new InstrNoArgs(0, 0, OPCODE_SPHL)) + .addChild(new InstrExpr(0, 0, OPCODE_JM) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrNoArgs(0, 0, OPCODE_EI)) + .addChild(new InstrExpr(0, 0, OPCODE_CM) + .addChild(new Evaluated(0, 0, 0x200))) + .addChild(new InstrExpr(0, 0, OPCODE_CPI) + .addChild(new Evaluated(0, 0, 0xF0))) + .addChild(new InstrExpr(0, 0, OPCODE_RST) + .addChild(new Evaluated(0, 0, 7))); IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); diff --git a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java index b26325d0b..d06f13013 100644 --- a/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java +++ b/plugins/compiler/as-8080/src/test/java/net/emustudio/plugins/compiler/as8080/visitors/SortMacroArgumentsVisitorTest.java @@ -37,113 +37,113 @@ public class SortMacroArgumentsVisitorTest { @Test public void testMacroArgumentsAreConnectedWithIds() { Node program = new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "r"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "t"))) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoEqu(0, 0, "uu") - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprId(0, 0, "r")) - .addChild(new ExprId(0, 0, "t")))))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "r"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "t"))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoEqu(0, 0, "uu") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprId(0, 0, "t")))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); visitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "q")) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "r")) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "t")) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoEqu(0, 0, "uu") - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprId(0, 0, "r")) - .addChild(new ExprId(0, 0, "t"))))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "t")) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new InstrRegExpr(0, 0, OPCODE_MVI, REG_A) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoEqu(0, 0, "uu") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprId(0, 0, "t"))))), + program ); } @Test public void testMultipleMacroCalls() { Node program = new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))))) - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); visitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "q")) - .addChild(new ExprNumber(0, 0, 1)))) - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "q")) - .addChild(new ExprNumber(0, 0, 2)))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 2)))), + program ); } @Test public void testNestedMacroCallWithSameNamedArgs() { Node program = new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroCall(0, 0, "x") .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new PseudoMacroDef(0, 0, "y") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))))))); + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "y") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "q")) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "q")) - .addChild(new ExprNumber(0, 0, 3))))), - program + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 3))))), + program ); } @@ -151,14 +151,14 @@ public void testNestedMacroCallWithSameNamedArgs() { public void testMoreMacroArgumentsThanParameters() { Program program = new Program(); program - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); visitor.visit(program); @@ -170,14 +170,14 @@ public void testMoreMacroArgumentsThanParameters() { public void testMoreMacroParametersThanArguments() { Program program = new Program(); program - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "r"))))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "r"))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); visitor.visit(program); diff --git a/plugins/compiler/as-ssem/README.md b/plugins/compiler/as-ssem/README.md index 64722b3bb..4ee48d71f 100644 --- a/plugins/compiler/as-ssem/README.md +++ b/plugins/compiler/as-ssem/README.md @@ -3,4 +3,5 @@ This project is assembler of SSEM machine language. It is part of [emuStudio](https://www.emustudio.net/). -The official documentation can be found [here](https://www.emustudio.net/docdevel/emulator_tutorial/index/#writing-a-compiler) +The official documentation can be +found [here](https://www.emustudio.net/docdevel/emulator_tutorial/index/#writing-a-compiler) diff --git a/plugins/compiler/as-ssem/build.gradle b/plugins/compiler/as-ssem/build.gradle index 538419290..9ec606245 100644 --- a/plugins/compiler/as-ssem/build.gradle +++ b/plugins/compiler/as-ssem/build.gradle @@ -53,7 +53,7 @@ sourceSets { } main { java.srcDirs = [ - 'src/main/java', "${buildDir}/generated-src/antlr/main" + 'src/main/java', "${buildDir}/generated-src/antlr/main" ] } } @@ -75,8 +75,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year" : new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java index 0d0bf1278..b70f23827 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CodeGenerator.java @@ -44,7 +44,7 @@ public ByteBuffer generateCode(Program program) { } private void writeInstruction(int opcode, long operand) { - int instruction = NumberUtils.reverseBits((int)operand & 0x1F, 32) | ((opcode & 0x07) << 16); + int instruction = NumberUtils.reverseBits((int) operand & 0x1F, 32) | ((opcode & 0x07) << 16); code.putInt(instruction); } } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java index 1562be641..530e52aa0 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/CompilerChecks.java @@ -51,7 +51,7 @@ public static void checkUnknownInstruction(boolean unknown, Position pos) { public static void checkOperandOutOfBounds(Position pos, int tokenType, long operand) { if (tokenType != SSEMLexer.BNUM && tokenType != SSEMLexer.NUM && (operand < 0 || operand > 31)) { throw new CompileException( - pos.line, pos.column, "Operand must be between <0, 31>; it was " + operand + pos.line, pos.column, "Operand must be between <0, 31>; it was " + operand ); } } @@ -61,7 +61,7 @@ public static T checkedParseNumber(Token token, Function recognizer, - Object offendingSymbol, - int line, - int charPositionInLine, - String msg, - RecognitionException e) { + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { throw new CompileException(line, charPositionInLine, msg); } } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java index d332082ca..d0617a915 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java @@ -28,9 +28,9 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextNotFoundException; import net.emustudio.emulib.runtime.InvalidContextException; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; import net.emustudio.emulib.runtime.helpers.RadixUtils; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.compiler.ssem.ast.Program; import net.emustudio.plugins.compiler.ssem.ast.ProgramParser; import org.antlr.v4.runtime.*; @@ -46,14 +46,14 @@ import java.util.*; @PluginRoot( - type = PLUGIN_TYPE.COMPILER, - title = "SSEM Assembler" + type = PLUGIN_TYPE.COMPILER, + title = "SSEM Assembler" ) @SuppressWarnings("unused") public class SSEMCompiler extends AbstractCompiler { private static final Logger LOGGER = LoggerFactory.getLogger(SSEMCompiler.class); private static final List SOURCE_FILE_EXTENSIONS = List.of( - new SourceFileExtension("ssem", "SSEM source file") + new SourceFileExtension("ssem", "SSEM source file") ); private MemoryContext memory; private int programLocation; @@ -70,7 +70,7 @@ public void initialize() { memory = pool.getMemoryContext(pluginID, MemoryContext.class); if (memory.getDataType() != Byte.class) { throw new InvalidContextException( - "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() + "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() ); } } catch (InvalidContextException | ContextNotFoundException e) { @@ -107,8 +107,8 @@ public boolean compile(String inputFileName, String outputFileName) { programLocation = program.getStartLine() * 4; notifyInfo(String.format( - "Compile was successful.\n\tOutput: %s\n\tProgram starts at 0x%s", - outputFileName, RadixUtils.formatWordHexString(programLocation) + "Compile was successful.\n\tOutput: %s\n\tProgram starts at 0x%s", + outputFileName, RadixUtils.formatWordHexString(programLocation) )); } catch (CompileException e) { notifyError(e.line, e.column, e.getMessage()); diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java index 51d5322bc..3e37a4daf 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Instruction.java @@ -31,15 +31,15 @@ @Immutable public class Instruction { private final static Map OPCODES = Map.of( - SSEMParser.JMP, (byte)0, // 000 - SSEMParser.JPR, (byte)4, // 100 - SSEMParser.LDN, (byte)2, // 010 - SSEMParser.STO, (byte)6, // 110 - SSEMParser.SUB, (byte)1, // 001 - SSEMParser.CMP, (byte)3, // 011 - SSEMParser.STP, (byte)7, // 111, - SSEMParser.NUM, (byte)0, - SSEMParser.BNUM, (byte)0 + SSEMParser.JMP, (byte) 0, // 000 + SSEMParser.JPR, (byte) 4, // 100 + SSEMParser.LDN, (byte) 2, // 010 + SSEMParser.STO, (byte) 6, // 110 + SSEMParser.SUB, (byte) 1, // 001 + SSEMParser.CMP, (byte) 3, // 011 + SSEMParser.STP, (byte) 7, // 111, + SSEMParser.NUM, (byte) 0, + SSEMParser.BNUM, (byte) 0 ); public final int tokenType; diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java index 1f8f87eb8..24318d592 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/Program.java @@ -28,11 +28,10 @@ import static net.emustudio.plugins.compiler.ssem.CompilerChecks.*; public class Program { + private final Map instructions = new HashMap<>(); private int startLine; private boolean startLineDefined; - private final Map instructions = new HashMap<>(); - public void setStartLine(int startLine, Position pos) { checkStartLineDefined(startLineDefined, pos, this.startLine); checkLineOutOfBounds(pos, startLine); @@ -54,7 +53,7 @@ public void forEach(BiConsumer processor) { instructions.forEach(processor); } - public Map getInstructions() { + public Map getInstructions() { return Collections.unmodifiableMap(instructions); } diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java index c67fb3f07..002f77f9e 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/ast/ProgramParser.java @@ -51,9 +51,9 @@ public Program visitLine(SSEMParser.LineContext ctx) { program.setStartLine(line, Position.of(ctx.linenumber)); } else { program.add( - line, - new Instruction(instrType, operand, Position.of(tokenInstr), Position.of(tokenOperand)), - Position.of(ctx.linenumber) + line, + new Instruction(instrType, operand, Position.of(tokenInstr), Position.of(tokenOperand)), + Position.of(ctx.linenumber) ); } } diff --git a/plugins/compiler/as-ssem/src/main/resources/net/emustudio/plugins/compiler/ssem/version.properties b/plugins/compiler/as-ssem/src/main/resources/net/emustudio/plugins/compiler/ssem/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/compiler/as-ssem/src/main/resources/net/emustudio/plugins/compiler/ssem/version.properties +++ b/plugins/compiler/as-ssem/src/main/resources/net/emustudio/plugins/compiler/ssem/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java index a291dbff7..c695ae351 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/ParserTest.java @@ -67,64 +67,64 @@ public void testEolOnly() { @Test public void testParseInstructions() { Program program = parseProgram( - "01 LDN 0x1F\n" + - "-- 01 ldn 30\n" + - "; 01 LDN 30\n" + - "# 01 ldn 30\n" + - "04 SUB 30 --comment1\n" + - "05 STO 31 # comment2\n" + - "06 STP ; comment3\n" + - "07 CMP\n" + - "08 NUM 4\n" + - "09 BNUM 100\n\n\n" + "01 LDN 0x1F\n" + + "-- 01 ldn 30\n" + + "; 01 LDN 30\n" + + "# 01 ldn 30\n" + + "04 SUB 30 --comment1\n" + + "05 STO 31 # comment2\n" + + "06 STP ; comment3\n" + + "07 CMP\n" + + "08 NUM 4\n" + + "09 BNUM 100\n\n\n" ); assertInstructions( - program, - new Utils.ParsedInstruction(1, SSEMParser.LDN, 0x1F), - new Utils.ParsedInstruction(4, SSEMParser.SUB, 30), - new Utils.ParsedInstruction(5, SSEMParser.STO, 31), - new Utils.ParsedInstruction(6, SSEMParser.STP, 0), - new Utils.ParsedInstruction(7, SSEMParser.CMP, 0), - new Utils.ParsedInstruction(8, SSEMParser.NUM, 4), - new Utils.ParsedInstruction(9, SSEMParser.BNUM, 4) + program, + new Utils.ParsedInstruction(1, SSEMParser.LDN, 0x1F), + new Utils.ParsedInstruction(4, SSEMParser.SUB, 30), + new Utils.ParsedInstruction(5, SSEMParser.STO, 31), + new Utils.ParsedInstruction(6, SSEMParser.STP, 0), + new Utils.ParsedInstruction(7, SSEMParser.CMP, 0), + new Utils.ParsedInstruction(8, SSEMParser.NUM, 4), + new Utils.ParsedInstruction(9, SSEMParser.BNUM, 4) ); } @Test public void testParseAllInstructions() { Program program = parseProgram( - "01 jmp 0x1F\n" + - "02 jrp 0x1F\n" + - "03 jpr 0x1F\n" + - "04 jmr 0x1F\n" + - "05 ldn 0x1F\n" + - "06 sto 0x1F\n" + - "07 sub 0x1F\n" + - "08 cmp\n" + - "09 skn\n" + - "10 stp\n" + - "11 hlt\n" + "01 jmp 0x1F\n" + + "02 jrp 0x1F\n" + + "03 jpr 0x1F\n" + + "04 jmr 0x1F\n" + + "05 ldn 0x1F\n" + + "06 sto 0x1F\n" + + "07 sub 0x1F\n" + + "08 cmp\n" + + "09 skn\n" + + "10 stp\n" + + "11 hlt\n" ); assertInstructions( - program, - new Utils.ParsedInstruction(1, SSEMParser.JMP, 0x1F), - new Utils.ParsedInstruction(2, SSEMParser.JPR, 0x1F), - new Utils.ParsedInstruction(3, SSEMParser.JPR, 0x1F), - new Utils.ParsedInstruction(4, SSEMParser.JPR, 0x1F), - new Utils.ParsedInstruction(5, SSEMParser.LDN, 0x1F), - new Utils.ParsedInstruction(6, SSEMParser.STO, 0x1F), - new Utils.ParsedInstruction(7, SSEMParser.SUB, 0x1F), - new Utils.ParsedInstruction(8, SSEMParser.CMP, 0), - new Utils.ParsedInstruction(9, SSEMParser.CMP, 0), - new Utils.ParsedInstruction(10, SSEMParser.STP, 0), - new Utils.ParsedInstruction(11, SSEMParser.STP, 0) + program, + new Utils.ParsedInstruction(1, SSEMParser.JMP, 0x1F), + new Utils.ParsedInstruction(2, SSEMParser.JPR, 0x1F), + new Utils.ParsedInstruction(3, SSEMParser.JPR, 0x1F), + new Utils.ParsedInstruction(4, SSEMParser.JPR, 0x1F), + new Utils.ParsedInstruction(5, SSEMParser.LDN, 0x1F), + new Utils.ParsedInstruction(6, SSEMParser.STO, 0x1F), + new Utils.ParsedInstruction(7, SSEMParser.SUB, 0x1F), + new Utils.ParsedInstruction(8, SSEMParser.CMP, 0), + new Utils.ParsedInstruction(9, SSEMParser.CMP, 0), + new Utils.ParsedInstruction(10, SSEMParser.STP, 0), + new Utils.ParsedInstruction(11, SSEMParser.STP, 0) ); } @Test public void testParseNegativeNumber() { Program program = parseProgram( - "01 NUM -3" + "01 NUM -3" ); assertInstructions(program, new Utils.ParsedInstruction(1, SSEMLexer.NUM, -3)); } @@ -132,9 +132,9 @@ public void testParseNegativeNumber() { @Test public void testStartingPointIsAccepted() { Program program = parseProgram( - "02 start\n" + - "01 LDN 21\n" + - "02 STP" + "02 start\n" + + "01 LDN 21\n" + + "02 STP" ); assertEquals(2, program.getStartLine()); } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java index dd11b4f4a..cf21308f5 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/SSEMCompilerTest.java @@ -23,8 +23,8 @@ import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -39,11 +39,10 @@ import static org.junit.Assert.assertNotEquals; public class SSEMCompilerTest { - private SSEMCompiler compiler; - private MemoryStub memoryStub; - @Rule public TemporaryFolder folder = new TemporaryFolder(); + private SSEMCompiler compiler; + private MemoryStub memoryStub; @SuppressWarnings("unchecked") @Before @@ -75,12 +74,12 @@ private void assertProgram(int... bytes) { Byte[] value = memoryStub.read(0, bytes.length); assertArrayEquals( - String.format( - "Expected=%x, but was=%x", - NumberUtils.readInt(bytes, NumberUtils.Strategy.BIG_ENDIAN), - NumberUtils.readInt(value, NumberUtils.Strategy.BIG_ENDIAN) - ), - NumberUtils.nativeIntsToNativeBytes(bytes), NumberUtils.numbersToNativeBytes(value) + String.format( + "Expected=%x, but was=%x", + NumberUtils.readInt(bytes, NumberUtils.Strategy.BIG_ENDIAN), + NumberUtils.readInt(value, NumberUtils.Strategy.BIG_ENDIAN) + ), + NumberUtils.nativeIntsToNativeBytes(bytes), NumberUtils.numbersToNativeBytes(value) ); } @@ -103,18 +102,18 @@ public void testSTO() throws Exception { @Test public void testLDN() throws Exception { compile("00 LDN 29"); - assertProgram(0xB8,0x2,0,0); + assertProgram(0xB8, 0x2, 0, 0); } @Test public void testSUB() throws Exception { compile("00 SUB 30"); - assertProgram(0x78,0x1,0,0); + assertProgram(0x78, 0x1, 0, 0); } @Test public void testSTP() throws Exception { compile("00 STP"); - assertProgram(0,0x7,0,0); + assertProgram(0, 0x7, 0, 0); } } diff --git a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java index 9b526e06e..414e3c16e 100644 --- a/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java +++ b/plugins/compiler/as-ssem/src/test/java/net/emustudio/plugins/compiler/ssem/Utils.java @@ -26,7 +26,10 @@ import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.ParseTree; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Random; import static org.junit.Assert.assertEquals; @@ -77,9 +80,9 @@ public static void assertTokenTypesForCaseVariations(String base, int... expecte byte[] chars = base.getBytes(); for (int j = 0; j < base.length(); j++) { if (r.nextBoolean()) { - chars[j] = Character.valueOf((char)chars[j]).toString().toUpperCase().getBytes()[0]; + chars[j] = Character.valueOf((char) chars[j]).toString().toUpperCase().getBytes()[0]; } else { - chars[j] = Character.valueOf((char)chars[j]).toString().toLowerCase().getBytes()[0]; + chars[j] = Character.valueOf((char) chars[j]).toString().toLowerCase().getBytes()[0]; } } variations.add(new String(chars)); @@ -94,8 +97,8 @@ public static void assertInstructions(Program program, ParsedInstruction... inst assertEquals(instructions.length, pinstr.size()); for (ParsedInstruction instruction : instructions) { assertEquals( - new Instruction(instruction.opcode, instruction.operand, Position.unknown(), Position.unknown()), - pinstr.get(instruction.line) + new Instruction(instruction.opcode, instruction.operand, Position.unknown(), Position.unknown()), + pinstr.get(instruction.line) ); } } diff --git a/plugins/compiler/as-z80/build.gradle b/plugins/compiler/as-z80/build.gradle index cdcc192a2..17a059b2d 100644 --- a/plugins/compiler/as-z80/build.gradle +++ b/plugins/compiler/as-z80/build.gradle @@ -52,7 +52,7 @@ sourceSets { } main { java.srcDirs = [ - 'src/main/java', "${buildDir}/generated-src/antlr/main" + 'src/main/java', "${buildDir}/generated-src/antlr/main" ] } } @@ -74,8 +74,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java index a70eb6532..43ebc2096 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java @@ -27,10 +27,9 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextNotFoundException; import net.emustudio.emulib.runtime.InvalidContextException; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.io.IntelHEX; -import net.emustudio.plugins.compiler.asZ80.visitors.NodeVisitor; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.compiler.asZ80.ast.Program; import net.emustudio.plugins.compiler.asZ80.exceptions.CompileException; import net.emustudio.plugins.compiler.asZ80.visitors.*; @@ -47,15 +46,15 @@ import java.util.*; @PluginRoot( - type = PLUGIN_TYPE.COMPILER, - title = "Zilog Z80 Assembler" + type = PLUGIN_TYPE.COMPILER, + title = "Zilog Z80 Assembler" ) @SuppressWarnings("unused") public class AssemblerZ80 extends AbstractCompiler { private final static Logger LOGGER = LoggerFactory.getLogger(AssemblerZ80.class); private final static List SOURCE_FILE_EXTENSIONS = List.of( - new SourceFileExtension("asm", "Assembler source file"), - new SourceFileExtension("inc", "Include file") + new SourceFileExtension("asm", "Assembler source file"), + new SourceFileExtension("inc", "Include file") ); private MemoryContext memory; @@ -73,7 +72,7 @@ public void initialize() { memory = pool.getMemoryContext(pluginID, MemoryContext.class); if (memory.getDataType() != Byte.class) { throw new InvalidContextException( - "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() + "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() ); } } catch (InvalidContextException | ContextNotFoundException e) { @@ -122,17 +121,17 @@ public boolean compile(String inputFileName, String outputFileName) { IntelHEX hex = new IntelHEX(); NodeVisitor[] visitors = new NodeVisitor[]{ - new ExpandIncludesVisitor(), - new CheckDeclarationsVisitor(), - new ExpandMacrosVisitor(), - new SortMacroArgumentsVisitor(), - // macro expansion could bring re-definition of declarations, but we cannot check declarations again - // until the macro is properly integrated (b/c we could see multiple macro defs on multiple calls) - new CheckDeclarationsVisitor(), - new EvaluateExprVisitor(), - new CheckExprSizesVisitor(), - new CollectExprsInOpcodeVisitor(), - new GenerateCodeVisitor(hex) + new ExpandIncludesVisitor(), + new CheckDeclarationsVisitor(), + new ExpandMacrosVisitor(), + new SortMacroArgumentsVisitor(), + // macro expansion could bring re-definition of declarations, but we cannot check declarations again + // until the macro is properly integrated (b/c we could see multiple macro defs on multiple calls) + new CheckDeclarationsVisitor(), + new EvaluateExprVisitor(), + new CheckExprSizesVisitor(), + new CollectExprsInOpcodeVisitor(), + new GenerateCodeVisitor(hex) }; for (NodeVisitor visitor : visitors) { @@ -145,8 +144,8 @@ public boolean compile(String inputFileName, String outputFileName) { programLocation = hex.findProgramLocation(); notifyInfo(String.format( - "Compile was successful.\n\tOutput: %s\n\tProgram starts at 0x%s", - outputFileName, RadixUtils.formatWordHexString(programLocation) + "Compile was successful.\n\tOutput: %s\n\tProgram starts at 0x%s", + outputFileName, RadixUtils.formatWordHexString(programLocation) )); if (memory != null) { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java index 01d398618..f7a7b0bb3 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompileError.java @@ -66,7 +66,7 @@ public static CompileError infiniteLoopDetected(Node node, String what) { public static CompileError couldNotReadFile(Node node, String filename, IOException e) { return new CompileError( - node, ERROR_CANNOT_READ_FILE, "Could not read file: " + filename + " (" + e.getMessage() + ")" + node, ERROR_CANNOT_READ_FILE, "Could not read file: " + filename + " (" + e.getMessage() + ")" ); } @@ -80,7 +80,7 @@ public static CompileError ambiguousExpression(Node node) { public static CompileError ifExpressionReferencesOwnBlock(Node node) { return new CompileError( - node, ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK, "If expression references declaration in its own block" + node, ERROR_IF_EXPRESSION_REFERENCES_OWN_BLOCK, "If expression references declaration in its own block" ); } @@ -90,15 +90,15 @@ public static CompileError declarationReferencesItself(Node node) { public static CompileError macroArgumentsDoNotMatch(Node node) { return new CompileError( - node, ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH, "Macro call arguments do not match with defined parameters" + node, ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH, "Macro call arguments do not match with defined parameters" ); } public static CompileError expressionIsBiggerThanExpected(Node node, int expectedBytes, int wasBytes) { return new CompileError( - node, - ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED, - "Expression (" + wasBytes + " bytes) is bigger than expected (" + expectedBytes + " byte(s))" + node, + ERROR_EXPRESSION_IS_BIGGER_THAN_EXPECTED, + "Expression (" + wasBytes + " bytes) is bigger than expected (" + expectedBytes + " byte(s))" ); } @@ -108,20 +108,20 @@ public static CompileError valueMustBePositive(Node node) { public static CompileError valueOutOfBounds(Node node, int min, int max) { return new CompileError( - node, ERROR_VALUE_OUT_OF_BOUNDS, "Value is out of bounds (min=" + min + ", max=" + max + ")" + node, ERROR_VALUE_OUT_OF_BOUNDS, "Value is out of bounds (min=" + min + ", max=" + max + ")" ); } public static CompileError valueOutOfBounds(Node node, Set allowedValues) { List hexaValues = allowedValues - .stream() - .sorted() - .map(Integer::toHexString) - .map(x -> "0x" + x) - .collect(Collectors.toList()); + .stream() + .sorted() + .map(Integer::toHexString) + .map(x -> "0x" + x) + .collect(Collectors.toList()); return new CompileError( - node, ERROR_VALUE_OUT_OF_BOUNDS, "Value is out of bounds (allowed values=" + hexaValues + ")" + node, ERROR_VALUE_OUT_OF_BOUNDS, "Value is out of bounds (allowed values=" + hexaValues + ")" ); } @@ -129,10 +129,10 @@ public static CompileError valueOutOfBounds(Node node, Set allowedValue @Override public String toString() { return "CompileError{" + - "line=" + line + - ", column=" + column + - ", msg='" + msg + '\'' + - ", errorCode=" + errorCode + - '}'; + "line=" + line + + ", column=" + column + + ", msg='" + msg + '\'' + + ", errorCode=" + errorCode + + '}'; } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java index ec0ad8365..113f1b184 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/CompilerTables.java @@ -36,12 +36,12 @@ public class CompilerTables { public final static Map im = new HashMap<>(); public final static Map> block = new HashMap<>(); public final static Map prefix = Map.of( - REG_IX, 0xDD, - REG_IXH, 0xDD, - REG_IXL, 0xDD, - REG_IY, 0xFD, - REG_IYH, 0xFD, - REG_IYL, 0xFD + REG_IX, 0xDD, + REG_IXH, 0xDD, + REG_IXL, 0xDD, + REG_IY, 0xFD, + REG_IYH, 0xFD, + REG_IYL, 0xFD ); static { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java index 180f65263..8d6825072 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/LexicalAnalyzerImpl.java @@ -29,7 +29,6 @@ import static net.emustudio.plugins.compiler.asZ80.AsZ80Lexer.*; public class LexicalAnalyzerImpl implements LexicalAnalyzer { - private final AsZ80Lexer lexer; public static final int[] tokenMap = new int[AsZ80Lexer.EOL + 1]; static { @@ -197,6 +196,8 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[ERROR_COND] = Token.ERROR; } + private final AsZ80Lexer lexer; + public LexicalAnalyzerImpl(AsZ80Lexer lexer) { this.lexer = Objects.requireNonNull(lexer); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Pair.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Pair.java index 1ec86fd6e..d2cdeb217 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Pair.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/Pair.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.asZ80; -public class Pair { +public class Pair { public final L l; public final R r; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParserErrorListener.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParserErrorListener.java index d8de9e866..10e897074 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParserErrorListener.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ParserErrorListener.java @@ -27,12 +27,12 @@ class ParserErrorListener extends BaseErrorListener { // TODO: parse message expected tokens to token categories @Override public void syntaxError( - Recognizer recognizer, - Object offendingSymbol, - int line, - int charPositionInLine, - String msg, - RecognitionException e) { + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { if (e == null) { throw new SyntaxErrorException(line, charPositionInLine, msg); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java index ac901dc1a..b31230581 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/NameSpace.java @@ -20,7 +20,6 @@ import net.emustudio.plugins.compiler.asZ80.CompileError; -import java.io.File; import java.util.*; public class NameSpace { @@ -58,7 +57,7 @@ public List getErrors() { @Override public String toString() { return "NameSpace{" + - "errors=" + errors + - '}'; + "errors=" + errors + + '}'; } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java index 676c4c47f..a33e2ec81 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Node.java @@ -25,11 +25,10 @@ import java.util.Optional; public abstract class Node { - protected Node parent; - protected final List children = new ArrayList<>(); public final int line; public final int column; - + protected final List children = new ArrayList<>(); + protected Node parent; private int address; private Optional maxValue = Optional.empty(); private Optional sizeBytes = Optional.empty(); @@ -130,10 +129,10 @@ private String toString(int indent) { String spaces = new String(new char[indent]).replace("\0", " "); StringBuilder builder = new StringBuilder(spaces); builder - .append(Integer.toHexString(address)) - .append("> ") - .append(toStringShallow()) - .append(sizeBytes.map(s -> "(size=" + s + ")").orElse("")); + .append(Integer.toHexString(address)) + .append("> ") + .append(toStringShallow()) + .append(sizeBytes.map(s -> "(size=" + s + ")").orElse("")); for (Node child : children) { builder.append("\n").append(child.toString(indent + 2)); @@ -166,10 +165,6 @@ public Optional getMaxValue() { return maxValue; } - public Optional getSizeBytes() { - return sizeBytes; - } - public Node setMaxValue(int maxValue) { int wasBits = (int) Math.floor(Math.log10(Math.abs(maxValue)) / Math.log10(2)) + 1; this.sizeBytes = Optional.of((int) Math.ceil(wasBits / 8.0)); @@ -177,6 +172,10 @@ public Node setMaxValue(int maxValue) { return this; } + public Optional getSizeBytes() { + return sizeBytes; + } + public Node setSizeBytes(int bytes) { int value = 0; for (int i = 0; i < bytes; i++) { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Program.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Program.java index a6466851e..b5d8a748e 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Program.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/Program.java @@ -40,14 +40,13 @@ public Program() { this(new NameSpace()); } - public void setFileName(String filename) { - this.filename = filename; - } - public Optional getFileName() { return Optional.ofNullable(filename); } + public void setFileName(String filename) { + this.filename = filename; + } public NameSpace env() { return env; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java index 44074e9aa..4ae56dbff 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprInfix.java @@ -34,8 +34,6 @@ public class ExprInfix extends Node { private final static Map> infixOps = new HashMap<>(); - private final BiFunction operation; - public final int operationCode; static { infixOps.put(OP_ADD, Integer::sum); @@ -58,6 +56,9 @@ public class ExprInfix extends Node { infixOps.put(OP_GTE, (x, y) -> (x >= y) ? 1 : 0); } + public final int operationCode; + private final BiFunction operation; + public ExprInfix(int line, int column, int op) { super(line, column); this.operationCode = op; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprString.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprString.java index e218f2764..8f9b72eb1 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprString.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprString.java @@ -58,7 +58,7 @@ public Optional eval(Optional currentAddress, NameSpace env) } return Optional.empty(); } - + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprUnary.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprUnary.java index 9b83382d4..9137b6a6d 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprUnary.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/expr/ExprUnary.java @@ -33,13 +33,13 @@ public class ExprUnary extends Node { private final static Map> unaryOps = Map.of( - OP_ADD, x -> x, - OP_SUBTRACT, x -> -x, - OP_NOT, x -> ~x, - OP_NOT_2, x -> ~x + OP_ADD, x -> x, + OP_SUBTRACT, x -> -x, + OP_NOT, x -> ~x, + OP_NOT_2, x -> ~x ); - private final Function operation; public final int operationCode; + private final Function operation; public ExprUnary(int line, int column, int op) { super(line, column); @@ -60,8 +60,8 @@ public void accept(NodeVisitor visitor) { @Override public Optional eval(Optional currentAddress, NameSpace env) { return getChild(0) - .eval(currentAddress, env) - .map(childEval -> new Evaluated(line, column, operation.apply(childEval.value))); + .eval(currentAddress, env) + .map(childEval -> new Evaluated(line, column, operation.apply(childEval.value))); } @Override diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java index e46c1c1d3..526781cec 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/Instr.java @@ -25,8 +25,8 @@ public class Instr extends Node { public final int opcode; public final int x; - private int y; public final int z; + private int y; public Instr(int line, int column, int opcode, int x, int y, int z) { super(line, column); @@ -52,7 +52,7 @@ public void setY(int y) { } public byte eval() { - return (byte)(((x << 6) | (y << 3) | (z & 7)) & 0xFF); + return (byte) (((x << 6) | (y << 3) | (z & 7)) & 0xFF); } public boolean hasRelativeAddress() { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java index 85102032c..be2ea08fe 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrCB.java @@ -28,12 +28,8 @@ import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; public class InstrCB extends Node { - public final int opcode; - public final int x; - private int y; - public final int z; - private static final Map xmap = new HashMap<>(); + static { xmap.put(OPCODE_RLC, 0); xmap.put(OPCODE_RRC, 0); @@ -48,6 +44,11 @@ public class InstrCB extends Node { xmap.put(OPCODE_SET, 3); } + public final int opcode; + public final int x; + public final int z; + private int y; + public InstrCB(int line, int column, int opcode, int y, int z) { super(line, column); this.opcode = opcode; @@ -67,9 +68,9 @@ public void setY(int bit) { } public byte[] eval() { - return new byte[] { - (byte)0xCB, - (byte)(((x << 6) | (y << 3) | (z & 7)) & 0xFF) + return new byte[]{ + (byte) 0xCB, + (byte) (((x << 6) | (y << 3) | (z & 7)) & 0xFF) }; } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java index 0d817a475..e66d28f05 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrED.java @@ -28,12 +28,8 @@ import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; public class InstrED extends Node { - public final int opcode; - public final int x; - public final int y; - public final int z; - private static final Map xmap = new HashMap<>(); + static { xmap.put(OPCODE_IN, 1); xmap.put(OPCODE_OUT, 1); @@ -64,6 +60,11 @@ public class InstrED extends Node { xmap.put(OPCODE_OTDR, 2); } + public final int opcode; + public final int x; + public final int y; + public final int z; + public InstrED(int line, int column, int opcode, int y, int z) { super(line, column); this.opcode = opcode; @@ -83,9 +84,9 @@ public InstrED(Token opcode, int p, int q, int z) { } public byte[] eval() { - return new byte[] { - (byte)0xED, - (byte)(((x << 6) | (y << 3) | (z & 7)) & 0xFF) + return new byte[]{ + (byte) 0xED, + (byte) (((x << 6) | (y << 3) | (z & 7)) & 0xFF) }; } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java index 6e401843f..6adaa042d 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXD.java @@ -50,9 +50,9 @@ public InstrXD(Token opcode, int prefix, int x, int q, int p, int z) { } public byte[] eval() { - return new byte[] { - (byte)prefix, - (byte)(((x << 6) | (y << 3) | (z & 7)) & 0xFF) + return new byte[]{ + (byte) prefix, + (byte) (((x << 6) | (y << 3) | (z & 7)) & 0xFF) }; } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java index 6eecca1aa..9165c5ee2 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/instr/InstrXDCB.java @@ -31,13 +31,8 @@ * DD or FD prefix, CB, displacement byte, opcode */ public class InstrXDCB extends Node { - public final int opcode; - public final int x; - private int y; - public final int z; - public final int prefix; - private static final Map xmap = new HashMap<>(); + static { xmap.put(OPCODE_RLC, 0); xmap.put(OPCODE_RRC, 0); @@ -52,6 +47,12 @@ public class InstrXDCB extends Node { xmap.put(OPCODE_SET, 3); } + public final int opcode; + public final int x; + public final int z; + public final int prefix; + private int y; + public InstrXDCB(int line, int column, int opcode, int prefix, int y, int z) { super(line, column); @@ -75,10 +76,10 @@ public void setY(int y) { } public byte[] eval() { - return new byte[] { - (byte)prefix, - (byte)0xCB, - (byte)(((x << 6) | (y << 3) | (z & 7)) & 0xFF) + return new byte[]{ + (byte) prefix, + (byte) 0xCB, + (byte) (((x << 6) | (y << 3) | (z & 7)) & 0xFF) }; } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java index 5b7223075..3129e09bc 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/ast/pseudo/PseudoLabel.java @@ -53,7 +53,7 @@ public void accept(NodeVisitor visitor) { @Override protected String toStringShallow() { - return "Label(" + label +")"; + return "Label(" + label + ")"; } @Override diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java index fc89ba22f..64d043970 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckDeclarationsVisitor.java @@ -18,9 +18,9 @@ */ package net.emustudio.plugins.compiler.asZ80.visitors; -import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; import net.emustudio.plugins.compiler.asZ80.ast.Node; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprId; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; import java.util.*; @@ -33,10 +33,10 @@ * - ID of constant and macro cannot reference itself in the declaration * - ID of variable cannot reference itself in the declaration only if it wasn't already declared * - macro parameters should not conflict with: - * - declarations in and out of the macro scope - * - previously declared parameters in current or parent macros if the current one is nested + * - declarations in and out of the macro scope + * - previously declared parameters in current or parent macros if the current one is nested * - if expressions should not reference declarations inside that if (including all nested ifs) - * + *

* - cyclic references will be checked in evaluator since it requires > 1 passes */ public class CheckDeclarationsVisitor extends NodeVisitor { @@ -49,13 +49,10 @@ public class CheckDeclarationsVisitor extends NodeVisitor { // for checking marco param names in nested macros private final List> macroParamsInScope = new ArrayList<>(); - - // for easier removal of current macro params from macroParamsInScope when the macro definition ends - private Set currentMacroParams; - // if expr references private final Set currentIfReferences = new HashSet<>(); - + // for easier removal of current macro params from macroParamsInScope when the macro definition ends + private Set currentMacroParams; private boolean insideMacroParameter = false; private int insideIfLevel = 0; // if nesting level, to know how long to keep currentIfReferences private boolean insideIfExpr = false; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java index d3fd69c3c..e83a535ec 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CollectExprsInOpcodeVisitor.java @@ -31,21 +31,21 @@ public class CollectExprsInOpcodeVisitor extends NodeVisitor { private final static Set allowedRstValues = Set.of( - 0, 0x8, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38 + 0, 0x8, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38 ); @Override public void visit(Instr node) { if (node.opcode == OPCODE_RST) { node - .collectChild(Evaluated.class) - .map(e -> { - e.remove(); - return e.value; - }) - .filter(allowedRstValues::contains) - .map(v -> v / 8) - .ifPresentOrElse(node::setY, () -> error(valueOutOfBounds(node, allowedRstValues))); + .collectChild(Evaluated.class) + .map(e -> { + e.remove(); + return e.value; + }) + .filter(allowedRstValues::contains) + .map(v -> v / 8) + .ifPresentOrElse(node::setY, () -> error(valueOutOfBounds(node, allowedRstValues))); } } @@ -57,12 +57,12 @@ public void visit(InstrCB node) { case OPCODE_RES: case OPCODE_BIT: node - .collectChild(Evaluated.class) - .map(e -> { - e.remove(); - return e.value; - }) - .ifPresent(node::setY); + .collectChild(Evaluated.class) + .map(e -> { + e.remove(); + return e.value; + }) + .ifPresent(node::setY); } } @@ -74,12 +74,12 @@ public void visit(InstrXDCB node) { case OPCODE_RES: case OPCODE_BIT: node - .collectChild(Evaluated.class) - .map(e -> { - e.remove(); - return e.value; - }) - .ifPresent(node::setY); + .collectChild(Evaluated.class) + .map(e -> { + e.remove(); + return e.value; + }) + .ifPresent(node::setY); } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java index 175d4781d..a8da4e1d7 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateInstrVisitor.java @@ -113,7 +113,7 @@ public Node visitInstrED_RP(InstrED_RPContext ctx) { // | opcode=OPCODE_ADC REG_HL SEP_COMMA rp=rRegPair # instrED_RP int q = (ctx.opcode.getType() == OPCODE_SBC) ? 0 : 1; int p = CompilerTables.regPairs.get(ctx.rp.start.getType()); - return new InstrED(ctx.opcode, p,q, 2).setSizeBytes(2); + return new InstrED(ctx.opcode, p, q, 2).setSizeBytes(2); } @Override @@ -615,20 +615,20 @@ public Node visitInstr(InstrContext ctx) { // | opcode=OPCODE_EI # instr // x=3, z=3, y=7 Map xyz = new HashMap<>(); - xyz.put(OPCODE_NOP, new int[] {0, 0, 0}); - xyz.put(OPCODE_RLCA, new int[] {0, 0, 7}); - xyz.put(OPCODE_RRCA, new int[] {0, 1, 7}); - xyz.put(OPCODE_RLA, new int[] {0, 2, 7}); - xyz.put(OPCODE_RRA, new int[] {0, 3, 7}); - xyz.put(OPCODE_DAA, new int[] {0, 4, 7}); - xyz.put(OPCODE_CPL, new int[] {0, 5, 7}); - xyz.put(OPCODE_SCF, new int[] {0, 6, 7}); - xyz.put(OPCODE_CCF, new int[] {0, 7, 7}); - xyz.put(OPCODE_HALT, new int[] {1, 6, 6}); - xyz.put(OPCODE_RET, new int[] {3, 1, 1}); - xyz.put(OPCODE_EXX, new int[] {3, 3, 1}); - xyz.put(OPCODE_DI, new int[] {3, 6, 3}); - xyz.put(OPCODE_EI, new int[] {3, 7, 3}); + xyz.put(OPCODE_NOP, new int[]{0, 0, 0}); + xyz.put(OPCODE_RLCA, new int[]{0, 0, 7}); + xyz.put(OPCODE_RRCA, new int[]{0, 1, 7}); + xyz.put(OPCODE_RLA, new int[]{0, 2, 7}); + xyz.put(OPCODE_RRA, new int[]{0, 3, 7}); + xyz.put(OPCODE_DAA, new int[]{0, 4, 7}); + xyz.put(OPCODE_CPL, new int[]{0, 5, 7}); + xyz.put(OPCODE_SCF, new int[]{0, 6, 7}); + xyz.put(OPCODE_CCF, new int[]{0, 7, 7}); + xyz.put(OPCODE_HALT, new int[]{1, 6, 6}); + xyz.put(OPCODE_RET, new int[]{3, 1, 1}); + xyz.put(OPCODE_EXX, new int[]{3, 3, 1}); + xyz.put(OPCODE_DI, new int[]{3, 6, 3}); + xyz.put(OPCODE_EI, new int[]{3, 7, 3}); int[] xyzValues = xyz.get(ctx.opcode.getType()); return new Instr(ctx.opcode, xyzValues[0], xyzValues[1], xyzValues[2]).setSizeBytes(1); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateLineVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateLineVisitor.java index 76b9a1964..0baca616d 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateLineVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateLineVisitor.java @@ -18,10 +18,11 @@ */ package net.emustudio.plugins.compiler.asZ80.visitors; -import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.RLineContext; +import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.RStatementContext; import net.emustudio.plugins.compiler.asZ80.AsZ80ParserBaseVisitor; -import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoLabel; import net.emustudio.plugins.compiler.asZ80.ast.Node; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoLabel; public class CreateLineVisitor extends AsZ80ParserBaseVisitor { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateProgramVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateProgramVisitor.java index 486d50d1f..74d123075 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateProgramVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreateProgramVisitor.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.asZ80.visitors; -import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import net.emustudio.plugins.compiler.asZ80.AsZ80Parser.RLineContext; import net.emustudio.plugins.compiler.asZ80.AsZ80ParserBaseVisitor; import net.emustudio.plugins.compiler.asZ80.ast.Node; import net.emustudio.plugins.compiler.asZ80.ast.Program; diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java index 911ccfe71..dc63ba3dc 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CreatePseudoVisitor.java @@ -26,7 +26,7 @@ import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; -public class CreatePseudoVisitor extends AsZ80ParserBaseVisitor { +public class CreatePseudoVisitor extends AsZ80ParserBaseVisitor { @Override public Node visitPseudoOrg(PseudoOrgContext ctx) { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java index 6efa1a709..8cdfad931 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitor.java @@ -31,7 +31,8 @@ import java.util.*; import java.util.stream.Collectors; -import static net.emustudio.plugins.compiler.asZ80.CompileError.*; +import static net.emustudio.plugins.compiler.asZ80.CompileError.ambiguousExpression; +import static net.emustudio.plugins.compiler.asZ80.CompileError.expressionIsBiggerThanExpected; import static net.emustudio.plugins.compiler.asZ80.ParsingUtils.normalizeId; /** @@ -49,16 +50,14 @@ * - no PseudoLabel */ public class EvaluateExprVisitor extends NodeVisitor { + private final Set doNotEvaluateVariables = new HashSet<>(); + private final Set forwardReferences = new HashSet<>(); + private final Map> macroArguments = new HashMap<>(); private int currentAddress = 0; private int sizeBytes = 0; private boolean doNotEvaluateCurrentAddress = false; - private final Set doNotEvaluateVariables = new HashSet<>(); - private final Set forwardReferences = new HashSet<>(); - private Optional latestEval; private Set needMorePassThings = new HashSet<>(); - - private final Map> macroArguments = new HashMap<>(); private String currentMacroId; @Override @@ -121,8 +120,8 @@ public void visit(DataDS node) { sizeBytes = 0; visitChildren(node); latestEval.ifPresentOrElse( - e -> currentAddress += e.value, - () -> doNotEvaluateCurrentAddress = true + e -> currentAddress += e.value, + () -> doNotEvaluateCurrentAddress = true ); } @@ -160,11 +159,11 @@ public void visit(PseudoLabel node) { Optional eval = node.eval(getCurrentAddress(), env); env.put(normalizeId(node.label), eval); eval.ifPresentOrElse( - e -> { - // we don't need to re-evaluate label - node.exclude(); - }, - () -> needMorePassThings.add(node) + e -> { + // we don't need to re-evaluate label + node.exclude(); + }, + () -> needMorePassThings.add(node) ); visitChildren(node); } @@ -175,8 +174,8 @@ public void visit(PseudoOrg node) { sizeBytes = 0; visitChildren(node); latestEval.ifPresentOrElse( - e -> currentAddress = e.value, - () -> doNotEvaluateCurrentAddress = true + e -> currentAddress = e.value, + () -> doNotEvaluateCurrentAddress = true ); } @@ -184,11 +183,11 @@ public void visit(PseudoOrg node) { public void visit(PseudoIf node) { sizeBytes = 0; Optional expr = node - .collectChild(PseudoIfExpression.class) - .flatMap(p -> { - visitChildren(p); - return p.collectChild(Evaluated.class); - }); + .collectChild(PseudoIfExpression.class) + .flatMap(p -> { + visitChildren(p); + return p.collectChild(Evaluated.class); + }); boolean includeBlock = expr.filter(p -> p.value != 0).isPresent(); boolean excludeBlock = expr.filter(p -> p.value == 0).isPresent(); @@ -278,11 +277,11 @@ public void visit(PseudoMacroArgument node) { visitChildren(node, 1); // expected two children: ExprId and Expr* node.collectChild(ExprId.class) - .ifPresent(exprId -> { - String macroParameter = normalizeId(exprId.id); - macroArguments.get(currentMacroId).add(macroParameter); - env.put(macroParameter, latestEval); - }); + .ifPresent(exprId -> { + String macroParameter = normalizeId(exprId.id); + macroArguments.get(currentMacroId).add(macroParameter); + env.put(macroParameter, latestEval); + }); } @Override @@ -358,8 +357,8 @@ private void evalExpr(Node node) { latestEval = node.eval(getCurrentAddress(), env); latestEval.ifPresent(e -> node.getMaxValue().ifPresent(e::setMaxValue)); latestEval.ifPresentOrElse( - e -> node.remove().ifPresent(p -> p.addChild(e)), - () -> needMorePassThings.add(node) + e -> node.remove().ifPresent(p -> p.addChild(e)), + () -> needMorePassThings.add(node) ); currentAddress += sizeBytes; } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java index 9d1e16ec9..9d9ea84a3 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitor.java @@ -40,7 +40,7 @@ public class ExpandIncludesVisitor extends NodeVisitor { private final Set includedFiles; private Optional inputFileName = Optional.empty(); - + public ExpandIncludesVisitor() { this.includedFiles = Collections.emptySet(); } @@ -91,16 +91,16 @@ private String findAbsoluteFileName(String includeFileName) { } String includeFileNameNormalized = includeFileName - .replace("/", File.separator) - .replace("\\", File.separator); + .replace("/", File.separator) + .replace("\\", File.separator); return inputFileName - .map(f -> f.replace("/", File.separator)) - .map(f -> f.replace("\\", File.separator)) - .map(File::new) - .map(File::getParentFile) - .map(File::toPath) - .map(p -> p.resolve(includeFileNameNormalized)) - .map(Path::toString) - .orElse(includeFileNameNormalized); + .map(f -> f.replace("/", File.separator)) + .map(f -> f.replace("\\", File.separator)) + .map(File::new) + .map(File::getParentFile) + .map(File::toPath) + .map(p -> p.resolve(includeFileNameNormalized)) + .map(Path::toString) + .orElse(includeFileNameNormalized); } } diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java index 77a958161..7ad84751c 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosVisitor.java @@ -32,7 +32,7 @@ /** * Expands macros. It means - find macro definitions, remove them from the parent node and put them as a child under * each macro call. It supports forward references too. - * + *

* It doesn't mean the macro expansion will be used in code yet. */ public class ExpandMacrosVisitor extends NodeVisitor { diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java index f72437858..89c73bfca 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java @@ -55,15 +55,15 @@ public void visit(DataDW node) { @Override public void visit(DataDS node) { node.collectChild(Evaluated.class) - .ifPresent(e -> { - if (e.value < 0) { - error(valueMustBePositive(e)); - } else { - for (int i = 0; i < e.value; i++) { - hex.add((byte) 0); + .ifPresent(e -> { + if (e.value < 0) { + error(valueMustBePositive(e)); + } else { + for (int i = 0; i < e.value; i++) { + hex.add((byte) 0); + } } - } - }); + }); } @Override @@ -122,13 +122,13 @@ public void visit(InstrXDCB node) { @Override public void visit(PseudoOrg node) { node.collectChild(Evaluated.class) - .ifPresent(e -> { - if (e.value < 0) { - error(valueMustBePositive(node)); - } else { - hex.setNextAddress(e.value); - } - }); + .ifPresent(e -> { + if (e.value < 0) { + error(valueMustBePositive(node)); + } else { + hex.setNextAddress(e.value); + } + }); } @Override diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitor.java index 2b88224b1..b805372cf 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitor.java @@ -102,8 +102,8 @@ public void visit(PseudoMacroDef node) { Node macroArgument = origMacroArguments.get(i); macroParam - .collectChild(ExprId.class) - .ifPresentOrElse(macroArgument::addChildFirst, () -> error(macroArgumentsDoNotMatch(node))); + .collectChild(ExprId.class) + .ifPresentOrElse(macroArgument::addChildFirst, () -> error(macroArgumentsDoNotMatch(node))); } node.exclude(); } diff --git a/plugins/compiler/as-z80/src/main/resources/net/emustudio/plugins/compiler/asZ80/version.properties b/plugins/compiler/as-z80/src/main/resources/net/emustudio/plugins/compiler/asZ80/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/compiler/as-z80/src/main/resources/net/emustudio/plugins/compiler/asZ80/version.properties +++ b/plugins/compiler/as-z80/src/main/resources/net/emustudio/plugins/compiler/asZ80/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java index 523231f13..68bc462e6 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/Utils.java @@ -41,51 +41,51 @@ public class Utils { public static Map registers = Map.of( - "a", REG_A, - "b", REG_B, - "c", REG_C, - "d", REG_D, - "e", REG_E, - "h", REG_H, - "l", REG_L, - "(HL)", REG_HL + "a", REG_A, + "b", REG_B, + "c", REG_C, + "d", REG_D, + "e", REG_E, + "h", REG_H, + "l", REG_L, + "(HL)", REG_HL ); public static Map regPairs = Map.of( - "bc", REG_BC, - "de", REG_DE, - "hl", REG_HL, - "sp", REG_SP + "bc", REG_BC, + "de", REG_DE, + "hl", REG_HL, + "sp", REG_SP ); public static Map regPairs2 = Map.of( - "bc", REG_BC, - "de", REG_DE, - "hl", REG_HL, - "af", REG_AF + "bc", REG_BC, + "de", REG_DE, + "hl", REG_HL, + "af", REG_AF ); public static Map rot = Map.of( - "rlc", OPCODE_RLC, - "rrc", OPCODE_RRC, - "rl", OPCODE_RL, - "rr", OPCODE_RR, - "sla", OPCODE_SLA, - "sra", OPCODE_SRA, - "sll", OPCODE_SLL, - "srl", OPCODE_SRL + "rlc", OPCODE_RLC, + "rrc", OPCODE_RRC, + "rl", OPCODE_RL, + "rr", OPCODE_RR, + "sla", OPCODE_SLA, + "sra", OPCODE_SRA, + "sll", OPCODE_SLL, + "srl", OPCODE_SRL ); public static Map prefixReg = Map.of( - "IX", REG_IX, - "IY", REG_IY + "IX", REG_IX, + "IY", REG_IY ); public static Map prefixReg8 = Map.of( - "IXH", REG_IXH, - "IYH", REG_IYH, - "IXL", REG_IXL, - "IYL", REG_IYL + "IXH", REG_IXH, + "IYH", REG_IYH, + "IXL", REG_IXL, + "IYL", REG_IYL ); public static List getTokens(String variation) { @@ -147,7 +147,7 @@ public static void forStringCaseVariations(String base, Consumer f) { } variations.add(new String(chars)); } - for (String variation: variations) { + for (String variation : variations) { f.accept(variation); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java index 2ba89d9f2..fb8e2f80b 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java @@ -25,8 +25,8 @@ import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.compiler.asZ80.AssemblerZ80; import org.junit.Before; import org.junit.Rule; @@ -41,11 +41,10 @@ import static org.junit.Assert.assertEquals; public abstract class AbstractCompilerTest { - protected AssemblerZ80 compiler; - protected MemoryStub memoryStub; - @Rule public TemporaryFolder folder = new TemporaryFolder(); + protected AssemblerZ80 compiler; + protected MemoryStub memoryStub; @SuppressWarnings("unchecked") @Before @@ -97,14 +96,14 @@ protected void compile(String content) { protected void assertProgram(int... bytes) { for (int i = 0; i < bytes.length; i++) { assertEquals( - String.format("[addr=%x] expected=%x, but was=%x", i, bytes[i], memoryStub.read(i)), - (byte)bytes[i], memoryStub.read(i).byteValue() + String.format("[addr=%x] expected=%x, but was=%x", i, bytes[i], memoryStub.read(i)), + (byte) bytes[i], memoryStub.read(i).byteValue() ); } for (int i = bytes.length; i < memoryStub.getSize(); i++) { assertEquals( - String.format("[addr=%x] expected=%x, but was=%x", i, 0, memoryStub.read(i)), - 0, memoryStub.read(i).byteValue() + String.format("[addr=%x] expected=%x, but was=%x", i, 0, memoryStub.read(i)), + 0, memoryStub.read(i).byteValue() ); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java index dcd9dc62e..45980e194 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AssemblerZ80Test.java @@ -37,58 +37,58 @@ public void testCopyrightIsKnown() { @Test public void testForwardAbsoluteJump() { compile( - "now: ld a,b\n" + - "cp 'C'\n" + - "jp z, ler\n" + - "ler: ld (HL), a" + "now: ld a,b\n" + + "cp 'C'\n" + + "jp z, ler\n" + + "ler: ld (HL), a" ); assertProgram( - 0x78, 0xFE, 0x43, 0xCA, 0x06, 0x00, 0x77 + 0x78, 0xFE, 0x43, 0xCA, 0x06, 0x00, 0x77 ); } @Test public void testBackwardAbsoluteJump() { compile( - "now: ld a,b\n" + - "cp 'C'\n" + - "jp z, now\n" + - "ler: ld (HL), a" + "now: ld a,b\n" + + "cp 'C'\n" + + "jp z, now\n" + + "ler: ld (HL), a" ); assertProgram( - 0x78, 0xFE, 0x43, 0xCA, 0x00, 0x00, 0x77 + 0x78, 0xFE, 0x43, 0xCA, 0x00, 0x00, 0x77 ); } @Test public void testCallBackward() { compile( - "dec sp\n" + - "now: ld a,b\n" + - "cp 'C'\n" + - "call now\n" + - "ler: ld (HL), a" + "dec sp\n" + + "now: ld a,b\n" + + "cp 'C'\n" + + "call now\n" + + "ler: ld (HL), a" ); assertProgram( - 0x3B, 0x78, 0xFE, 0x43, 0xCD, 0x01, 0x00, 0x77 + 0x3B, 0x78, 0xFE, 0x43, 0xCD, 0x01, 0x00, 0x77 ); } @Test public void testCallForward() { compile( - "dec sp\n" + - "now: ld a,b\n" + - "cp 'C'\n" + - "call ler\n" + - "ler: ld (HL), a" + "dec sp\n" + + "now: ld a,b\n" + + "cp 'C'\n" + + "call ler\n" + + "ler: ld (HL), a" ); assertProgram( - 0x3B, 0x78, 0xFE, 0x43, 0xCD, 0x07, 0x00, 0x77 + 0x3B, 0x78, 0xFE, 0x43, 0xCD, 0x07, 0x00, 0x77 ); } @@ -107,48 +107,48 @@ public void testRSTtooBigArgument() { @Test public void testDECwithLD() { compile( - "dec sp\n" - + "ld hl, text\n" - + "text:\n" - + "db 'ahoj'" + "dec sp\n" + + "ld hl, text\n" + + "text:\n" + + "db 'ahoj'" ); assertProgram( - 0x3B, 0x21, 0x04, 0, 'a', 'h', 'o', 'j' + 0x3B, 0x21, 0x04, 0, 'a', 'h', 'o', 'j' ); } @Test public void testINthenJMP() { compile( - "jp sample\n" - + "in a, (10h)\n" - + "sample:\n" - + "ld a, b\n" + "jp sample\n" + + "in a, (10h)\n" + + "sample:\n" + + "ld a, b\n" ); assertProgram( - 0xC3, 0x5, 0, 0xDB, 0x10, 0x78 + 0xC3, 0x5, 0, 0xDB, 0x10, 0x78 ); } @Test public void testGetChar() { compile( - "jp sample\n" - + "getchar:\n" - + "in a, (10h)\n" - + "and 1\n" - + "jp z, getchar\n" - + "in a, (11h)\n" - + "out (11h), a\n" - + "ret\n" - + "sample:\n" - + "ld a, b" + "jp sample\n" + + "getchar:\n" + + "in a, (10h)\n" + + "and 1\n" + + "jp z, getchar\n" + + "in a, (11h)\n" + + "out (11h), a\n" + + "ret\n" + + "sample:\n" + + "ld a, b" ); assertProgram( - 0xC3, 0x0F, 0, 0xDB, 0x10, 0xE6, 1, 0xCA, 0x03, 0, 0xDB, 0x11, 0xD3, 0x11, 0xC9, 0x78 + 0xC3, 0x0F, 0, 0xDB, 0x10, 0xE6, 1, 0xCA, 0x03, 0, 0xDB, 0x11, 0xD3, 0x11, 0xC9, 0x78 ); } @@ -173,783 +173,783 @@ public void testRET_P() { @Test public void testAllInstructions() { compile( - "nop\n" - + "ex af, af'\n" - + "djnz 20h\n" - + "jr 20h\n" - + "jr nz, 20h\n" // 6 - + "jr z, 20h\n" - + "jr nc, 20h\n" - + "jr c, 20h\n" - + "ld bc, 0x1234\n" - + "ld de, 0x1234\n" - + "ld hl, 0x1234\n" - + "ld sp, 0x1234\n" - + "add hl, bc\n" - + "add hl, de\n" - + "add hl, hl\n" - + "add hl, sp\n" - + "ld (bc), a\n" - + "ld (de), a\n" - + "ld a, (bc)\n" - + "ld a, (de)\n" - + "ld (0x1234), hl\n" // 0x22 - + "ld (0x1234), a\n" - + "ld hl, (0x1234)\n" - + "ld a, (0x1234)\n" - + "inc bc\n" - + "inc de\n" - + "inc hl\n" - + "inc sp\n" - + "dec bc\n" - + "dec de\n" - + "dec hl\n" - + "dec sp\n" - + "inc b\n" - + "inc c\n" - + "inc d\n" - + "inc e\n" - + "inc h\n" - + "inc l\n" - + "inc a\n" - + "dec b\n" - + "dec c\n" - + "dec d\n" - + "dec e\n" - + "dec h\n" - + "dec l\n" - + "dec a\n" - + "ld b, 0x20\n" - + "ld c, 0x20\n" - + "ld d, 0x20\n" - + "ld e, 0x20\n" - + "ld h, 0x20\n" - + "ld l, 0x20\n" - + "rlca\n" - + "rrca\n" - + "rla\n" - + "rra\n" - + "daa\n" - + "cpl\n" - + "scf\n" - + "ccf\n" - + "ld b, b\n" - + "ld b, c\n" - + "ld b, d\n" - + "ld b, e\n" - + "ld b, h\n" - + "ld b, l\n" - + "ld b, a\n" - + "ld (hl), b\n" - + "ld (hl), c\n" - + "ld (hl), d\n" - + "ld (hl), e\n" - + "ld (hl), h\n" - + "ld (hl), l\n" - + "ld (hl), a\n" - + "halt\n" - + "add a, b\n" - + "add a, (hl)\n" - + "adc a, c\n" - + "adc a, (hl)\n" - + "sub b\n" - + "sub (hl)\n" - + "sbc a, b\n" - + "sbc a, (hl)\n" - + "and b\n" - + "and (hl)\n" - + "xor b\n" - + "xor (hl)\n" - + "or b\n" - + "or (hl)\n" - + "cp b\n" - + "cp (hl)\n" - + "ret nz\n" - + "ret z\n" - + "ret nc\n" - + "ret c\n" - + "ret po\n" - + "ret pe\n" - + "ret p\n" - + "ret m\n" - + "pop bc\n" - + "pop de\n" - + "pop hl\n" - + "pop af\n" - + "ret\n" - + "exx\n" - + "jp hl\n" - + "jp (hl)\n" - + "ld sp, hl\n" - + "jp nz, 0x1234\n" - + "jp z, 0x1234\n" - + "jp nc, 0x1234\n" - + "jp c, 0x1234\n" - + "jp po, 0x1234\n" - + "jp pe, 0x1234\n" - + "jp p, 0x1234\n" - + "jp m, 0x1234\n" - + "jp 0x1234\n" - + "out (0x20), a\n" - + "in a, (0x20)\n" - + "ex (sp), hl\n" - + "ex de, hl\n" - + "di\n" - + "ei\n" - + "call nz, 0x1234\n" - + "call z, 0x1234\n" - + "call nc, 0x1234\n" - + "call c, 0x1234\n" - + "call po, 0x1234\n" - + "call pe, 0x1234\n" - + "call p, 0x1234\n" - + "call m, 0x1234\n" - + "push bc\n" - + "push de\n" - + "push hl\n" - + "push af\n" - + "call 0x1234\n" - + "add a, 0x20\n" - + "adc a, 0x20\n" - + "sub 0x20\n" - + "sbc a, 0x20\n" - + "and 0x20\n" - + "xor 0x20\n" - + "or 0x20\n" - + "cp 0x20\n" - + "rst 0\n" - + "rst 8\n" - + "rst 10h\n" - + "rst 18h\n" - + "rst 20h\n" - + "rst 28h\n" - + "rst 30h\n" - + "rst 38h\n" - + "rlc b\n" - + "rlc (HL)\n" - + "rrc c\n" - + "rrc (HL)\n" - + "rl d\n" - + "rl (HL)\n" - + "rr e\n" - + "rr (hl)\n" - + "sla h\n" - + "sla (hl)\n" - + "sra l\n" - + "sra (hl)\n" - + "sll b\n" - + "sll (hl)\n" - + "srl c\n" - + "srl (hl)\n" - + "bit 5, b\n" - + "bit 5, (hl)\n" - + "res 5, c\n" - + "res 6, (hl)\n" - + "set 7, d\n" - + "set 7, (hl)\n" - + "in e, (c)\n" - + "in (c)\n" - + "out (c), h\n" - + "out (c), 0\n" - + "sbc hl, bc\n" - + "sbc hl, de\n" - + "sbc hl, hl\n" - + "sbc hl, sp\n" - + "adc hl, bc\n" - + "adc hl, de\n" - + "adc hl, hl\n" - + "adc hl, sp\n" - + "ld (1234h), bc\n" - + "ld (1234h), de\n" - + "ld (1234h), hl\n" - + "ld (1234h), sp\n" - + "ld bc, (0x1234)\n" - + "ld de, (0x1234)\n" - + "ld hl, (0x1234)\n" - + "ld sp, (0x1234)\n" - + "neg\n" - + "retn\n" - + "reti\n" - + "im 0\n" - + "im 0/1\n" - + "im 1\n" - + "im 2\n" - + "ld i, a\n" - + "ld r, a\n" - + "ld a, i\n" - + "ld a, r\n" - + "rrd\n" - + "rld\n" - + "ldi\n" - + "ldd\n" - + "ldir\n" - + "lddr\n" - + "cpi\n" - + "cpd\n" - + "cpir\n" - + "cpdr\n" - + "ini\n" - + "ind\n" - + "inir\n" - + "indr\n" - + "outi\n" - + "outd\n" - + "otir\n" - + "otdr\n" - + "rlc (ix+0x20), b\n" - + "rlc (iy+0x20), b\n" - + "rlc (ix+0x20)\n" - + "rlc (iy+0x20)\n" - + "rrc (ix+0x20), c\n" - + "rrc (iy+0x20), c\n" - + "rrc (ix+0x20)\n" - + "rrc (iy+0x20)\n" - + "rl (ix+0x20), d\n" - + "rl (iy+0x20), d\n" - + "rl (ix+0x20)\n" - + "rl (iy+0x20)\n" - + "rr (ix+0x20), e\n" - + "rr (iy+0x20), e\n" - + "rr (ix+0x20)\n" - + "rr (iy+0x20)\n" - + "sla (ix+0x20), h\n" - + "sla (iy+0x20), h\n" - + "sla (ix+0x20)\n" - + "sla (iy+0x20)\n" - + "sra (ix+0x20), l\n" - + "sra (iy+0x20), l\n" - + "sra (ix+0x20)\n" - + "sra (iy+0x20)\n" - + "sll (ix+0x20), b\n" - + "sll (iy+0x20), b\n" - + "sll (ix+0x20)\n" - + "sll (iy+0x20)\n" - + "srl (ix+0x20), c\n" - + "srl (iy+0x20), c\n" - + "srl (ix+0x20)\n" - + "srl (iy+0x20)\n" - + "bit 3, (ix+0x20)\n" - + "bit 3, (iy+0x20)\n" - + "res 5, (ix+0x20), b\n" - + "res 5, (iy+0x20), b\n" - + "res 5, (ix+0x20)\n" - + "res 5, (iy+0x20)\n" - + "set 6, (ix+0x20), c\n" - + "set 6, (iy+0x20), c\n" - + "set 6, (ix+0x20)\n" - + "set 6, (iy+0x20)\n" - + "ld ix, 0x1234\n" - + "ld iy, 0x1234\n" - + "add ix, bc\n" - + "add iy, bc\n" - + "add ix, de\n" - + "add iy, de\n" - + "add ix, ix\n" - + "add iy, iy\n" - + "add ix, sp\n" - + "add iy, sp\n" - + "ld (0x1234), ix\n" - + "ld (0x1234), iy\n" - + "ld ix, (0x1234)\n" - + "ld iy, (0x1234)\n" - + "inc ix\n" - + "inc iy\n" - + "dec ix\n" - + "dec iy\n" - + "inc ixh\n" - + "inc iYh\n" - + "inc ixl\n" - + "inc iyl\n" - + "inc (ix+0x20)\n" - + "inc (iy+0x20)\n" - + "dec ixh\n" - + "dec iyh\n" - + "dec ixl\n" - + "dec iyl\n" - + "dec (ix+0x20)\n" - + "dec (iy+0x20)\n" - + "ld ixh, 0x20\n" - + "ld ixl, 0x20\n" - + "ld iyh, 0x20\n" - + "ld iyl, 0x20\n" - + "ld (ix+0x20), 0x20\n" - + "ld (iy+0x20), 0x20\n" - + "ld ixh, b\n" - + "ld ixh, ixh\n" - + "ld ixh, ixl\n" - + "ld iyh, c\n" - + "ld iyh, iyh\n" - + "ld iyh, iyl\n" - + "ld ixl, d\n" - + "ld ixl, ixh\n" - + "ld ixl, ixl\n" - + "ld iyl, e\n" - + "ld iyl, iyh\n" - + "ld iyl, iyl\n" - + "ld (ix+0x20), d\n" - + "ld (ix+0x20), h\n" - + "ld (ix+0x20), l\n" - + "ld (iy+0x20), e\n" - + "ld (iy+0x20), h\n" - + "ld (iy+0x20), l\n" - + "ld a, ixh\n" - + "ld a, iyh\n" - + "ld a, ixl\n" - + "ld a, iyl\n" - + "ld a, (ix+0x20)\n" - + "ld a, (iy+0x20)\n" - + "ld h, (ix+0x20)\n" - + "ld l, (ix+0x20)\n" - + "ld h, (iy+0x20)\n" - + "ld l, (iy+0x20)\n" - + "add a, ixh\n" - + "add a, ixl\n" - + "add a, (ix + 0x20)\n" - + "add a, iyh\n" - + "add a, iyl\n" - + "add a, (iy+0x20)\n" - + "adc a, ixh\n" - + "adc a, ixl\n" - + "adc a, (ix+0x20)\n" - + "adc a, iyh\n" - + "adc a, iyl\n" - + "adc a, (iy+0x20)\n" - + "sub ixh\n" - + "sub ixl\n" - + "sub (ix+0x20)\n" - + "sub iyh\n" - + "sub iyl\n" - + "sub (iy+0x20)\n" - + "sbc a, ixh\n" - + "sbc a, ixl\n" - + "sbc a, (ix+0x20)\n" - + "sbc a, iyh\n" - + "sbc a, iyl\n" - + "sbc a, (iy+0x20)\n" - + "and ixh\n" - + "and ixl\n" - + "and (ix+0x20)\n" - + "and iyh\n" - + "and iyl\n" - + "and (iy+0x20)\n" - + "xor ixh\n" - + "xor ixl\n" - + "xor (ix+0x20)\n" - + "xor iyh\n" - + "xor iyl\n" - + "xor (iy+0x20)\n" - + "or ixh\n" - + "or ixl\n" - + "or (ix+0x20)\n" - + "or iyh\n" - + "or iyl\n" - + "or (iy+0x20)\n" - + "cp ixh\n" - + "cp ixl\n" - + "cp (ix+0x20)\n" - + "cp iyh\n" - + "cp iyl\n" - + "cp (iy+0x20)\n" - + "pop ix\n" - + "pop iy\n" - + "jp (ix)\n" - + "jp (iy)\n" - + "ld sp, ix\n" - + "ld sp, iy\n" - + "ex (sp), ix\n" - + "ex (sp), iy\n" - + "push ix\n" - + "push iy\n" + "nop\n" + + "ex af, af'\n" + + "djnz 20h\n" + + "jr 20h\n" + + "jr nz, 20h\n" // 6 + + "jr z, 20h\n" + + "jr nc, 20h\n" + + "jr c, 20h\n" + + "ld bc, 0x1234\n" + + "ld de, 0x1234\n" + + "ld hl, 0x1234\n" + + "ld sp, 0x1234\n" + + "add hl, bc\n" + + "add hl, de\n" + + "add hl, hl\n" + + "add hl, sp\n" + + "ld (bc), a\n" + + "ld (de), a\n" + + "ld a, (bc)\n" + + "ld a, (de)\n" + + "ld (0x1234), hl\n" // 0x22 + + "ld (0x1234), a\n" + + "ld hl, (0x1234)\n" + + "ld a, (0x1234)\n" + + "inc bc\n" + + "inc de\n" + + "inc hl\n" + + "inc sp\n" + + "dec bc\n" + + "dec de\n" + + "dec hl\n" + + "dec sp\n" + + "inc b\n" + + "inc c\n" + + "inc d\n" + + "inc e\n" + + "inc h\n" + + "inc l\n" + + "inc a\n" + + "dec b\n" + + "dec c\n" + + "dec d\n" + + "dec e\n" + + "dec h\n" + + "dec l\n" + + "dec a\n" + + "ld b, 0x20\n" + + "ld c, 0x20\n" + + "ld d, 0x20\n" + + "ld e, 0x20\n" + + "ld h, 0x20\n" + + "ld l, 0x20\n" + + "rlca\n" + + "rrca\n" + + "rla\n" + + "rra\n" + + "daa\n" + + "cpl\n" + + "scf\n" + + "ccf\n" + + "ld b, b\n" + + "ld b, c\n" + + "ld b, d\n" + + "ld b, e\n" + + "ld b, h\n" + + "ld b, l\n" + + "ld b, a\n" + + "ld (hl), b\n" + + "ld (hl), c\n" + + "ld (hl), d\n" + + "ld (hl), e\n" + + "ld (hl), h\n" + + "ld (hl), l\n" + + "ld (hl), a\n" + + "halt\n" + + "add a, b\n" + + "add a, (hl)\n" + + "adc a, c\n" + + "adc a, (hl)\n" + + "sub b\n" + + "sub (hl)\n" + + "sbc a, b\n" + + "sbc a, (hl)\n" + + "and b\n" + + "and (hl)\n" + + "xor b\n" + + "xor (hl)\n" + + "or b\n" + + "or (hl)\n" + + "cp b\n" + + "cp (hl)\n" + + "ret nz\n" + + "ret z\n" + + "ret nc\n" + + "ret c\n" + + "ret po\n" + + "ret pe\n" + + "ret p\n" + + "ret m\n" + + "pop bc\n" + + "pop de\n" + + "pop hl\n" + + "pop af\n" + + "ret\n" + + "exx\n" + + "jp hl\n" + + "jp (hl)\n" + + "ld sp, hl\n" + + "jp nz, 0x1234\n" + + "jp z, 0x1234\n" + + "jp nc, 0x1234\n" + + "jp c, 0x1234\n" + + "jp po, 0x1234\n" + + "jp pe, 0x1234\n" + + "jp p, 0x1234\n" + + "jp m, 0x1234\n" + + "jp 0x1234\n" + + "out (0x20), a\n" + + "in a, (0x20)\n" + + "ex (sp), hl\n" + + "ex de, hl\n" + + "di\n" + + "ei\n" + + "call nz, 0x1234\n" + + "call z, 0x1234\n" + + "call nc, 0x1234\n" + + "call c, 0x1234\n" + + "call po, 0x1234\n" + + "call pe, 0x1234\n" + + "call p, 0x1234\n" + + "call m, 0x1234\n" + + "push bc\n" + + "push de\n" + + "push hl\n" + + "push af\n" + + "call 0x1234\n" + + "add a, 0x20\n" + + "adc a, 0x20\n" + + "sub 0x20\n" + + "sbc a, 0x20\n" + + "and 0x20\n" + + "xor 0x20\n" + + "or 0x20\n" + + "cp 0x20\n" + + "rst 0\n" + + "rst 8\n" + + "rst 10h\n" + + "rst 18h\n" + + "rst 20h\n" + + "rst 28h\n" + + "rst 30h\n" + + "rst 38h\n" + + "rlc b\n" + + "rlc (HL)\n" + + "rrc c\n" + + "rrc (HL)\n" + + "rl d\n" + + "rl (HL)\n" + + "rr e\n" + + "rr (hl)\n" + + "sla h\n" + + "sla (hl)\n" + + "sra l\n" + + "sra (hl)\n" + + "sll b\n" + + "sll (hl)\n" + + "srl c\n" + + "srl (hl)\n" + + "bit 5, b\n" + + "bit 5, (hl)\n" + + "res 5, c\n" + + "res 6, (hl)\n" + + "set 7, d\n" + + "set 7, (hl)\n" + + "in e, (c)\n" + + "in (c)\n" + + "out (c), h\n" + + "out (c), 0\n" + + "sbc hl, bc\n" + + "sbc hl, de\n" + + "sbc hl, hl\n" + + "sbc hl, sp\n" + + "adc hl, bc\n" + + "adc hl, de\n" + + "adc hl, hl\n" + + "adc hl, sp\n" + + "ld (1234h), bc\n" + + "ld (1234h), de\n" + + "ld (1234h), hl\n" + + "ld (1234h), sp\n" + + "ld bc, (0x1234)\n" + + "ld de, (0x1234)\n" + + "ld hl, (0x1234)\n" + + "ld sp, (0x1234)\n" + + "neg\n" + + "retn\n" + + "reti\n" + + "im 0\n" + + "im 0/1\n" + + "im 1\n" + + "im 2\n" + + "ld i, a\n" + + "ld r, a\n" + + "ld a, i\n" + + "ld a, r\n" + + "rrd\n" + + "rld\n" + + "ldi\n" + + "ldd\n" + + "ldir\n" + + "lddr\n" + + "cpi\n" + + "cpd\n" + + "cpir\n" + + "cpdr\n" + + "ini\n" + + "ind\n" + + "inir\n" + + "indr\n" + + "outi\n" + + "outd\n" + + "otir\n" + + "otdr\n" + + "rlc (ix+0x20), b\n" + + "rlc (iy+0x20), b\n" + + "rlc (ix+0x20)\n" + + "rlc (iy+0x20)\n" + + "rrc (ix+0x20), c\n" + + "rrc (iy+0x20), c\n" + + "rrc (ix+0x20)\n" + + "rrc (iy+0x20)\n" + + "rl (ix+0x20), d\n" + + "rl (iy+0x20), d\n" + + "rl (ix+0x20)\n" + + "rl (iy+0x20)\n" + + "rr (ix+0x20), e\n" + + "rr (iy+0x20), e\n" + + "rr (ix+0x20)\n" + + "rr (iy+0x20)\n" + + "sla (ix+0x20), h\n" + + "sla (iy+0x20), h\n" + + "sla (ix+0x20)\n" + + "sla (iy+0x20)\n" + + "sra (ix+0x20), l\n" + + "sra (iy+0x20), l\n" + + "sra (ix+0x20)\n" + + "sra (iy+0x20)\n" + + "sll (ix+0x20), b\n" + + "sll (iy+0x20), b\n" + + "sll (ix+0x20)\n" + + "sll (iy+0x20)\n" + + "srl (ix+0x20), c\n" + + "srl (iy+0x20), c\n" + + "srl (ix+0x20)\n" + + "srl (iy+0x20)\n" + + "bit 3, (ix+0x20)\n" + + "bit 3, (iy+0x20)\n" + + "res 5, (ix+0x20), b\n" + + "res 5, (iy+0x20), b\n" + + "res 5, (ix+0x20)\n" + + "res 5, (iy+0x20)\n" + + "set 6, (ix+0x20), c\n" + + "set 6, (iy+0x20), c\n" + + "set 6, (ix+0x20)\n" + + "set 6, (iy+0x20)\n" + + "ld ix, 0x1234\n" + + "ld iy, 0x1234\n" + + "add ix, bc\n" + + "add iy, bc\n" + + "add ix, de\n" + + "add iy, de\n" + + "add ix, ix\n" + + "add iy, iy\n" + + "add ix, sp\n" + + "add iy, sp\n" + + "ld (0x1234), ix\n" + + "ld (0x1234), iy\n" + + "ld ix, (0x1234)\n" + + "ld iy, (0x1234)\n" + + "inc ix\n" + + "inc iy\n" + + "dec ix\n" + + "dec iy\n" + + "inc ixh\n" + + "inc iYh\n" + + "inc ixl\n" + + "inc iyl\n" + + "inc (ix+0x20)\n" + + "inc (iy+0x20)\n" + + "dec ixh\n" + + "dec iyh\n" + + "dec ixl\n" + + "dec iyl\n" + + "dec (ix+0x20)\n" + + "dec (iy+0x20)\n" + + "ld ixh, 0x20\n" + + "ld ixl, 0x20\n" + + "ld iyh, 0x20\n" + + "ld iyl, 0x20\n" + + "ld (ix+0x20), 0x20\n" + + "ld (iy+0x20), 0x20\n" + + "ld ixh, b\n" + + "ld ixh, ixh\n" + + "ld ixh, ixl\n" + + "ld iyh, c\n" + + "ld iyh, iyh\n" + + "ld iyh, iyl\n" + + "ld ixl, d\n" + + "ld ixl, ixh\n" + + "ld ixl, ixl\n" + + "ld iyl, e\n" + + "ld iyl, iyh\n" + + "ld iyl, iyl\n" + + "ld (ix+0x20), d\n" + + "ld (ix+0x20), h\n" + + "ld (ix+0x20), l\n" + + "ld (iy+0x20), e\n" + + "ld (iy+0x20), h\n" + + "ld (iy+0x20), l\n" + + "ld a, ixh\n" + + "ld a, iyh\n" + + "ld a, ixl\n" + + "ld a, iyl\n" + + "ld a, (ix+0x20)\n" + + "ld a, (iy+0x20)\n" + + "ld h, (ix+0x20)\n" + + "ld l, (ix+0x20)\n" + + "ld h, (iy+0x20)\n" + + "ld l, (iy+0x20)\n" + + "add a, ixh\n" + + "add a, ixl\n" + + "add a, (ix + 0x20)\n" + + "add a, iyh\n" + + "add a, iyl\n" + + "add a, (iy+0x20)\n" + + "adc a, ixh\n" + + "adc a, ixl\n" + + "adc a, (ix+0x20)\n" + + "adc a, iyh\n" + + "adc a, iyl\n" + + "adc a, (iy+0x20)\n" + + "sub ixh\n" + + "sub ixl\n" + + "sub (ix+0x20)\n" + + "sub iyh\n" + + "sub iyl\n" + + "sub (iy+0x20)\n" + + "sbc a, ixh\n" + + "sbc a, ixl\n" + + "sbc a, (ix+0x20)\n" + + "sbc a, iyh\n" + + "sbc a, iyl\n" + + "sbc a, (iy+0x20)\n" + + "and ixh\n" + + "and ixl\n" + + "and (ix+0x20)\n" + + "and iyh\n" + + "and iyl\n" + + "and (iy+0x20)\n" + + "xor ixh\n" + + "xor ixl\n" + + "xor (ix+0x20)\n" + + "xor iyh\n" + + "xor iyl\n" + + "xor (iy+0x20)\n" + + "or ixh\n" + + "or ixl\n" + + "or (ix+0x20)\n" + + "or iyh\n" + + "or iyl\n" + + "or (iy+0x20)\n" + + "cp ixh\n" + + "cp ixl\n" + + "cp (ix+0x20)\n" + + "cp iyh\n" + + "cp iyl\n" + + "cp (iy+0x20)\n" + + "pop ix\n" + + "pop iy\n" + + "jp (ix)\n" + + "jp (iy)\n" + + "ld sp, ix\n" + + "ld sp, iy\n" + + "ex (sp), ix\n" + + "ex (sp), iy\n" + + "push ix\n" + + "push iy\n" ); assertProgram( - 0x00, - 0x08, - 0x10, 0x20, - 0x18, 0x20, - 0x20, 0x20, - 0x28, 0x20, - 0x30, 0x20, - 0x38, 0x20, - 0x01, 0x34, 0x12, // 10 - 0x11, 0x34, 0x12, - 0x21, 0x34, 0x12, - 0x31, 0x34, 0x12, - 0x09, - 0x19, - 0x29, - 0x39, - 0x02, - 0x12, - 0x0A, // 20 - 0x1A, - 0x22, 0x34, 0x12, - 0x32, 0x34, 0x12, - 0x2A, 0x34, 0x12, - 0x3A, 0x34, 0x12, - 0x03, - 0x13, - 0x23, // 30 - 0x33, - 0x0B, - 0x1B, - 0x2B, - 0x3B, - 0x04, - 0x0C, - 0x14, - 0x1C, - 0x24, - 0x2C, - 0x3C, - 0x05, - 0x0D, - 0x15, - 0x1D, // 40 - 0x25, - 0x2D, - 0x3D, - 0x06, 0x20, - 0x0E, 0x20, - 0x16, 0x20, - 0x1E, 0x20, - 0x26, 0x20, - 0x2E, 0x20, - 0x07, // 50 - 0x0F, - 0x17, - 0x1F, - 0x27, - 0x2F, - 0x37, - 0x3F, - 0x40, - 0x41, - 0x42, - 0x43, - 0x44, - 0x45, - 0x47, - 0x70, - 0x71, // 60 - 0x72, - 0x73, - 0x74, - 0x75, - 0x77, - 0x76, - 0x80, - 0x86, - 0x89, - 0x8E, - 0x90, - 0x96, - 0x98, - 0x9E, - 0xA0, - 0xA6, // 70 - 0xA8, - 0xAE, - 0xB0, - 0xB6, - 0xB8, - 0xBE, - 0xC0, - 0xC8, - 0xD0, - 0xD8, - 0xE0, // 7b - 0xE8, - 0xF0, - 0xF8, - 0xC1, - 0xD1, // 80 - 0xE1, - 0xF1, - 0xC9, - 0xD9, - 0xE9, - 0xE9, - 0xF9, - 0xC2, 0x34, 0x12, - 0xCA, 0x34, 0x12, - 0xD2, 0x34, 0x12, - 0xDA, 0x34, 0x12, - 0xE2, 0x34, 0x12, - 0xEA, 0x34, 0x12, - 0xF2, 0x34, 0x12, - 0xFA, 0x34, 0x12, - 0xC3, 0x34, 0x12, - 0xD3, 0x20, - 0xDB, 0x20, - 0xE3, - 0xEB, - 0xF3, - 0xFB, - 0xC4, 0x34, 0x12, - 0xCC, 0x34, 0x12, - 0xD4, 0x34, 0x12, - 0xDC, 0x34, 0x12, - 0xE4, 0x34, 0x12, - 0xEC, 0x34, 0x12, - 0xF4, 0x34, 0x12, - 0xFC, 0x34, 0x12, - 0xC5, - 0xD5, - 0xE5, - 0xF5, - 0xCD, 0x34, 0x12, - 0xC6, 0x20, - 0xCE, 0x20, - 0xD6, 0x20, - 0xDE, 0x20, - 0xE6, 0x20, - 0xEE, 0x20, - 0xF6, 0x20, - 0xFE, 0x20, - 0xC7, - 0xCF, - 0xD7, - 0xDF, - 0xE7, - 0xEF, - 0xF7, - 0xFF, - 0xCB, 0x00, - 0xCB, 0x06, - 0xCB, 0x09, - 0xCB, 0x0E, - 0xCB, 0x12, - 0xCB, 0x16, - 0xCB, 0x1B, - 0xCB, 0x1E, - 0xCB, 0x24, - 0xCB, 0x26, - 0xCB, 0x2D, - 0xCB, 0x2E, - 0xCB, 0x30, - 0xCB, 0x36, - 0xCB, 0x39, - 0xCB, 0x3E, - 0xCB, 0x68, - 0xCB, 0x6E, - 0xCB, 0xA9, - 0xCB, 0xB6, - 0xCB, 0xFA, - 0xCB, 0xFE, - 0xED, 0x58, - 0xED, 0x70, - 0xED, 0x61, - 0xED, 0x71, - 0xED, 0x42, - 0xED, 0x52, - 0xED, 0x62, - 0xED, 0x72, - 0xED, 0x4A, - 0xED, 0x5A, - 0xED, 0x6A, - 0xED, 0x7A, - 0xED, 0x43, 0x34, 0x12, - 0xED, 0x53, 0x34, 0x12, - 0x22, 0x34, 0x12, // 0xED, 0x63, 0x34, 0x12 - 0xED, 0x73, 0x34, 0x12, - 0xED, 0x4B, 0x34, 0x12, - 0xED, 0x5B, 0x34, 0x12, - 0x2A, 0x34, 0x12, // 0xED, 0x6B, 0x34, 0x12 - 0xED, 0x7B, 0x34, 0x12, - 0xED, 0x44, - 0xED, 0x45, - 0xED, 0x4D, - 0xED, 0x46, - 0xED, 0x4E, - 0xED, 0x56, - 0xED, 0x5E, - 0xED, 0x47, - 0xED, 0x4F, - 0xED, 0x57, - 0xED, 0x5F, - 0xED, 0x67, - 0xED, 0x6F, - 0xED, 0xA0, - 0xED, 0xA8, - 0xED, 0xB0, - 0xED, 0xB8, - 0xED, 0xA1, - 0xED, 0xA9, - 0xED, 0xB1, - 0xED, 0xB9, - 0xED, 0xA2, - 0xED, 0xAA, - 0xED, 0xB2, - 0xED, 0xBA, - 0xED, 0xA3, - 0xED, 0xAB, - 0xED, 0xB3, - 0xED, 0xBB, - 0xDD, 0xCB, 0x20, 0x00, - 0xFD, 0xCB, 0x20, 0x00, - 0xDD, 0xCB, 0x20, 0x06, - 0xFD, 0xCB, 0x20, 0x06, - 0xDD, 0xCB, 0x20, 0x09, - 0xFD, 0xCB, 0x20, 0x09, - 0xDD, 0xCB, 0x20, 0x0E, - 0xFD, 0xCB, 0x20, 0x0E, - 0xDD, 0xCB, 0x20, 0x12, - 0xFD, 0xCB, 0x20, 0x12, - 0xDD, 0xCB, 0x20, 0x16, - 0xFD, 0xCB, 0x20, 0x16, - 0xDD, 0xCB, 0x20, 0x1B, - 0xFD, 0xCB, 0x20, 0x1B, - 0xDD, 0xCB, 0x20, 0x1E, - 0xFD, 0xCB, 0x20, 0x1E, - 0xDD, 0xCB, 0x20, 0x24, - 0xFD, 0xCB, 0x20, 0x24, - 0xDD, 0xCB, 0x20, 0x26, - 0xFD, 0xCB, 0x20, 0x26, - 0xDD, 0xCB, 0x20, 0x2D, - 0xFD, 0xCB, 0x20, 0x2D, - 0xDD, 0xCB, 0x20, 0x2E, - 0xFD, 0xCB, 0x20, 0x2E, - 0xDD, 0xCB, 0x20, 0x30, - 0xFD, 0xCB, 0x20, 0x30, - 0xDD, 0xCB, 0x20, 0x36, - 0xFD, 0xCB, 0x20, 0x36, - 0xDD, 0xCB, 0x20, 0x39, - 0xFD, 0xCB, 0x20, 0x39, - 0xDD, 0xCB, 0x20, 0x3E, - 0xFD, 0xCB, 0x20, 0x3E, - 0xDD, 0xCB, 0x20, 0x5E, - 0xFD, 0xCB, 0x20, 0x5E, - 0xDD, 0xCB, 0x20, 0xA8, - 0xFD, 0xCB, 0x20, 0xA8, - 0xDD, 0xCB, 0x20, 0xAE, - 0xFD, 0xCB, 0x20, 0xAE, - 0xDD, 0xCB, 0x20, 0xF1, - 0xFD, 0xCB, 0x20, 0xF1, - 0xDD, 0xCB, 0x20, 0xF6, - 0xFD, 0xCB, 0x20, 0xF6, - 0xDD, 0x21, 0x34, 0x12, - 0xFD, 0x21, 0x34, 0x12, - 0xDD, 0x09, - 0xFD, 0x09, - 0xDD, 0x19, - 0xFD, 0x19, - 0xDD, 0x29, - 0xFD, 0x29, - 0xDD, 0x39, - 0xFD, 0x39, - 0xDD, 0x22, 0x34, 0x12, - 0xFD, 0x22, 0x34, 0x12, - 0xDD, 0x2A, 0x34, 0x12, - 0xFD, 0x2A, 0x34, 0x12, - 0xDD, 0x23, - 0xFD, 0x23, - 0xDD, 0x2B, - 0xFD, 0x2B, - 0xDD, 0x24, - 0xFD, 0x24, - 0xDD, 0x2C, - 0xFD, 0x2C, - 0xDD, 0x34, 0x20, - 0xFD, 0x34, 0x20, - 0xDD, 0x25, - 0xFD, 0x25, - 0xDD, 0x2D, - 0xFD, 0x2D, - 0xDD, 0x35, 0x20, - 0xFD, 0x35, 0x20, - 0xDD, 0x26, 0x20, - 0xDD, 0x2E, 0x20, - 0xFD, 0x26, 0x20, - 0xFD, 0x2E, 0x20, - 0xDD, 0x36, 0x20, 0x20, - 0xFD, 0x36, 0x20, 0x20, - 0xDD, 0x60, - 0xDD, 0x64, - 0xDD, 0x65, - 0xFD, 0x61, - 0xFD, 0x64, - 0xFD, 0x65, - 0xDD, 0x6A, - 0xDD, 0x6C, - 0xDD, 0x6D, - 0xFD, 0x6B, - 0xFD, 0x6C, - 0xFD, 0x6D, - 0xDD, 0x72, 0x20, - 0xDD, 0x74, 0x20, - 0xDD, 0x75, 0x20, - 0xFD, 0x73, 0x20, - 0xFD, 0x74, 0x20, - 0xFD, 0x75, 0x20, - 0xDD, 0x7C, - 0xFD, 0x7C, - 0xDD, 0x7D, - 0xFD, 0x7D, - 0xDD, 0x7E, 0x20, - 0xFD, 0x7E, 0x20, - 0xDD, 0x66, 0x20, - 0xDD, 0x6E, 0x20, - 0xFD, 0x66, 0x20, - 0xFD, 0x6E, 0x20, - 0xDD, 0x84, - 0xDD, 0x85, - 0xDD, 0x86, 0x20, - 0xFD, 0x84, - 0xFD, 0x85, - 0xFD, 0x86, 0x20, - 0xDD, 0x8C, - 0xDD, 0x8D, - 0xDD, 0x8E, 0x20, - 0xFD, 0x8C, - 0xFD, 0x8D, - 0xFD, 0x8E, 0x20, - 0xDD, 0x94, - 0xDD, 0x95, - 0xDD, 0x96, 0x20, - 0xFD, 0x94, - 0xFD, 0x95, - 0xFD, 0x96, 0x20, - 0xDD, 0x9C, - 0xDD, 0x9D, - 0xDD, 0x9E, 0x20, - 0xFD, 0x9C, - 0xFD, 0x9D, - 0xFD, 0x9E, 0x20, - 0xDD, 0xA4, - 0xDD, 0xA5, - 0xDD, 0xA6, 0x20, - 0xFD, 0xA4, - 0xFD, 0xA5, - 0xFD, 0xA6, 0x20, - 0xDD, 0xAC, - 0xDD, 0xAD, - 0xDD, 0xAE, 0x20, - 0xFD, 0xAC, - 0xFD, 0xAD, - 0xFD, 0xAE, 0x20, - 0xDD, 0xB4, - 0xDD, 0xB5, - 0xDD, 0xB6, 0x20, - 0xFD, 0xB4, - 0xFD, 0xB5, - 0xFD, 0xB6, 0x20, - 0xDD, 0xBC, - 0xDD, 0xBD, - 0xDD, 0xBE, 0x20, - 0xFD, 0xBC, - 0xFD, 0xBD, - 0xFD, 0xBE, 0x20, - 0xDD, 0xE1, - 0xFD, 0xE1, - 0xDD, 0xE9, - 0xFD, 0xE9, - 0xDD, 0xF9, - 0xFD, 0xF9, - 0xDD, 0xE3, - 0xFD, 0xE3, - 0xDD, 0xE5, - 0xFD, 0xE5 + 0x00, + 0x08, + 0x10, 0x20, + 0x18, 0x20, + 0x20, 0x20, + 0x28, 0x20, + 0x30, 0x20, + 0x38, 0x20, + 0x01, 0x34, 0x12, // 10 + 0x11, 0x34, 0x12, + 0x21, 0x34, 0x12, + 0x31, 0x34, 0x12, + 0x09, + 0x19, + 0x29, + 0x39, + 0x02, + 0x12, + 0x0A, // 20 + 0x1A, + 0x22, 0x34, 0x12, + 0x32, 0x34, 0x12, + 0x2A, 0x34, 0x12, + 0x3A, 0x34, 0x12, + 0x03, + 0x13, + 0x23, // 30 + 0x33, + 0x0B, + 0x1B, + 0x2B, + 0x3B, + 0x04, + 0x0C, + 0x14, + 0x1C, + 0x24, + 0x2C, + 0x3C, + 0x05, + 0x0D, + 0x15, + 0x1D, // 40 + 0x25, + 0x2D, + 0x3D, + 0x06, 0x20, + 0x0E, 0x20, + 0x16, 0x20, + 0x1E, 0x20, + 0x26, 0x20, + 0x2E, 0x20, + 0x07, // 50 + 0x0F, + 0x17, + 0x1F, + 0x27, + 0x2F, + 0x37, + 0x3F, + 0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x47, + 0x70, + 0x71, // 60 + 0x72, + 0x73, + 0x74, + 0x75, + 0x77, + 0x76, + 0x80, + 0x86, + 0x89, + 0x8E, + 0x90, + 0x96, + 0x98, + 0x9E, + 0xA0, + 0xA6, // 70 + 0xA8, + 0xAE, + 0xB0, + 0xB6, + 0xB8, + 0xBE, + 0xC0, + 0xC8, + 0xD0, + 0xD8, + 0xE0, // 7b + 0xE8, + 0xF0, + 0xF8, + 0xC1, + 0xD1, // 80 + 0xE1, + 0xF1, + 0xC9, + 0xD9, + 0xE9, + 0xE9, + 0xF9, + 0xC2, 0x34, 0x12, + 0xCA, 0x34, 0x12, + 0xD2, 0x34, 0x12, + 0xDA, 0x34, 0x12, + 0xE2, 0x34, 0x12, + 0xEA, 0x34, 0x12, + 0xF2, 0x34, 0x12, + 0xFA, 0x34, 0x12, + 0xC3, 0x34, 0x12, + 0xD3, 0x20, + 0xDB, 0x20, + 0xE3, + 0xEB, + 0xF3, + 0xFB, + 0xC4, 0x34, 0x12, + 0xCC, 0x34, 0x12, + 0xD4, 0x34, 0x12, + 0xDC, 0x34, 0x12, + 0xE4, 0x34, 0x12, + 0xEC, 0x34, 0x12, + 0xF4, 0x34, 0x12, + 0xFC, 0x34, 0x12, + 0xC5, + 0xD5, + 0xE5, + 0xF5, + 0xCD, 0x34, 0x12, + 0xC6, 0x20, + 0xCE, 0x20, + 0xD6, 0x20, + 0xDE, 0x20, + 0xE6, 0x20, + 0xEE, 0x20, + 0xF6, 0x20, + 0xFE, 0x20, + 0xC7, + 0xCF, + 0xD7, + 0xDF, + 0xE7, + 0xEF, + 0xF7, + 0xFF, + 0xCB, 0x00, + 0xCB, 0x06, + 0xCB, 0x09, + 0xCB, 0x0E, + 0xCB, 0x12, + 0xCB, 0x16, + 0xCB, 0x1B, + 0xCB, 0x1E, + 0xCB, 0x24, + 0xCB, 0x26, + 0xCB, 0x2D, + 0xCB, 0x2E, + 0xCB, 0x30, + 0xCB, 0x36, + 0xCB, 0x39, + 0xCB, 0x3E, + 0xCB, 0x68, + 0xCB, 0x6E, + 0xCB, 0xA9, + 0xCB, 0xB6, + 0xCB, 0xFA, + 0xCB, 0xFE, + 0xED, 0x58, + 0xED, 0x70, + 0xED, 0x61, + 0xED, 0x71, + 0xED, 0x42, + 0xED, 0x52, + 0xED, 0x62, + 0xED, 0x72, + 0xED, 0x4A, + 0xED, 0x5A, + 0xED, 0x6A, + 0xED, 0x7A, + 0xED, 0x43, 0x34, 0x12, + 0xED, 0x53, 0x34, 0x12, + 0x22, 0x34, 0x12, // 0xED, 0x63, 0x34, 0x12 + 0xED, 0x73, 0x34, 0x12, + 0xED, 0x4B, 0x34, 0x12, + 0xED, 0x5B, 0x34, 0x12, + 0x2A, 0x34, 0x12, // 0xED, 0x6B, 0x34, 0x12 + 0xED, 0x7B, 0x34, 0x12, + 0xED, 0x44, + 0xED, 0x45, + 0xED, 0x4D, + 0xED, 0x46, + 0xED, 0x4E, + 0xED, 0x56, + 0xED, 0x5E, + 0xED, 0x47, + 0xED, 0x4F, + 0xED, 0x57, + 0xED, 0x5F, + 0xED, 0x67, + 0xED, 0x6F, + 0xED, 0xA0, + 0xED, 0xA8, + 0xED, 0xB0, + 0xED, 0xB8, + 0xED, 0xA1, + 0xED, 0xA9, + 0xED, 0xB1, + 0xED, 0xB9, + 0xED, 0xA2, + 0xED, 0xAA, + 0xED, 0xB2, + 0xED, 0xBA, + 0xED, 0xA3, + 0xED, 0xAB, + 0xED, 0xB3, + 0xED, 0xBB, + 0xDD, 0xCB, 0x20, 0x00, + 0xFD, 0xCB, 0x20, 0x00, + 0xDD, 0xCB, 0x20, 0x06, + 0xFD, 0xCB, 0x20, 0x06, + 0xDD, 0xCB, 0x20, 0x09, + 0xFD, 0xCB, 0x20, 0x09, + 0xDD, 0xCB, 0x20, 0x0E, + 0xFD, 0xCB, 0x20, 0x0E, + 0xDD, 0xCB, 0x20, 0x12, + 0xFD, 0xCB, 0x20, 0x12, + 0xDD, 0xCB, 0x20, 0x16, + 0xFD, 0xCB, 0x20, 0x16, + 0xDD, 0xCB, 0x20, 0x1B, + 0xFD, 0xCB, 0x20, 0x1B, + 0xDD, 0xCB, 0x20, 0x1E, + 0xFD, 0xCB, 0x20, 0x1E, + 0xDD, 0xCB, 0x20, 0x24, + 0xFD, 0xCB, 0x20, 0x24, + 0xDD, 0xCB, 0x20, 0x26, + 0xFD, 0xCB, 0x20, 0x26, + 0xDD, 0xCB, 0x20, 0x2D, + 0xFD, 0xCB, 0x20, 0x2D, + 0xDD, 0xCB, 0x20, 0x2E, + 0xFD, 0xCB, 0x20, 0x2E, + 0xDD, 0xCB, 0x20, 0x30, + 0xFD, 0xCB, 0x20, 0x30, + 0xDD, 0xCB, 0x20, 0x36, + 0xFD, 0xCB, 0x20, 0x36, + 0xDD, 0xCB, 0x20, 0x39, + 0xFD, 0xCB, 0x20, 0x39, + 0xDD, 0xCB, 0x20, 0x3E, + 0xFD, 0xCB, 0x20, 0x3E, + 0xDD, 0xCB, 0x20, 0x5E, + 0xFD, 0xCB, 0x20, 0x5E, + 0xDD, 0xCB, 0x20, 0xA8, + 0xFD, 0xCB, 0x20, 0xA8, + 0xDD, 0xCB, 0x20, 0xAE, + 0xFD, 0xCB, 0x20, 0xAE, + 0xDD, 0xCB, 0x20, 0xF1, + 0xFD, 0xCB, 0x20, 0xF1, + 0xDD, 0xCB, 0x20, 0xF6, + 0xFD, 0xCB, 0x20, 0xF6, + 0xDD, 0x21, 0x34, 0x12, + 0xFD, 0x21, 0x34, 0x12, + 0xDD, 0x09, + 0xFD, 0x09, + 0xDD, 0x19, + 0xFD, 0x19, + 0xDD, 0x29, + 0xFD, 0x29, + 0xDD, 0x39, + 0xFD, 0x39, + 0xDD, 0x22, 0x34, 0x12, + 0xFD, 0x22, 0x34, 0x12, + 0xDD, 0x2A, 0x34, 0x12, + 0xFD, 0x2A, 0x34, 0x12, + 0xDD, 0x23, + 0xFD, 0x23, + 0xDD, 0x2B, + 0xFD, 0x2B, + 0xDD, 0x24, + 0xFD, 0x24, + 0xDD, 0x2C, + 0xFD, 0x2C, + 0xDD, 0x34, 0x20, + 0xFD, 0x34, 0x20, + 0xDD, 0x25, + 0xFD, 0x25, + 0xDD, 0x2D, + 0xFD, 0x2D, + 0xDD, 0x35, 0x20, + 0xFD, 0x35, 0x20, + 0xDD, 0x26, 0x20, + 0xDD, 0x2E, 0x20, + 0xFD, 0x26, 0x20, + 0xFD, 0x2E, 0x20, + 0xDD, 0x36, 0x20, 0x20, + 0xFD, 0x36, 0x20, 0x20, + 0xDD, 0x60, + 0xDD, 0x64, + 0xDD, 0x65, + 0xFD, 0x61, + 0xFD, 0x64, + 0xFD, 0x65, + 0xDD, 0x6A, + 0xDD, 0x6C, + 0xDD, 0x6D, + 0xFD, 0x6B, + 0xFD, 0x6C, + 0xFD, 0x6D, + 0xDD, 0x72, 0x20, + 0xDD, 0x74, 0x20, + 0xDD, 0x75, 0x20, + 0xFD, 0x73, 0x20, + 0xFD, 0x74, 0x20, + 0xFD, 0x75, 0x20, + 0xDD, 0x7C, + 0xFD, 0x7C, + 0xDD, 0x7D, + 0xFD, 0x7D, + 0xDD, 0x7E, 0x20, + 0xFD, 0x7E, 0x20, + 0xDD, 0x66, 0x20, + 0xDD, 0x6E, 0x20, + 0xFD, 0x66, 0x20, + 0xFD, 0x6E, 0x20, + 0xDD, 0x84, + 0xDD, 0x85, + 0xDD, 0x86, 0x20, + 0xFD, 0x84, + 0xFD, 0x85, + 0xFD, 0x86, 0x20, + 0xDD, 0x8C, + 0xDD, 0x8D, + 0xDD, 0x8E, 0x20, + 0xFD, 0x8C, + 0xFD, 0x8D, + 0xFD, 0x8E, 0x20, + 0xDD, 0x94, + 0xDD, 0x95, + 0xDD, 0x96, 0x20, + 0xFD, 0x94, + 0xFD, 0x95, + 0xFD, 0x96, 0x20, + 0xDD, 0x9C, + 0xDD, 0x9D, + 0xDD, 0x9E, 0x20, + 0xFD, 0x9C, + 0xFD, 0x9D, + 0xFD, 0x9E, 0x20, + 0xDD, 0xA4, + 0xDD, 0xA5, + 0xDD, 0xA6, 0x20, + 0xFD, 0xA4, + 0xFD, 0xA5, + 0xFD, 0xA6, 0x20, + 0xDD, 0xAC, + 0xDD, 0xAD, + 0xDD, 0xAE, 0x20, + 0xFD, 0xAC, + 0xFD, 0xAD, + 0xFD, 0xAE, 0x20, + 0xDD, 0xB4, + 0xDD, 0xB5, + 0xDD, 0xB6, 0x20, + 0xFD, 0xB4, + 0xFD, 0xB5, + 0xFD, 0xB6, 0x20, + 0xDD, 0xBC, + 0xDD, 0xBD, + 0xDD, 0xBE, 0x20, + 0xFD, 0xBC, + 0xFD, 0xBD, + 0xFD, 0xBE, 0x20, + 0xDD, 0xE1, + 0xFD, 0xE1, + 0xDD, 0xE9, + 0xFD, 0xE9, + 0xDD, 0xF9, + 0xFD, 0xF9, + 0xDD, 0xE3, + 0xFD, 0xE3, + 0xDD, 0xE5, + 0xFD, 0xE5 ); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/ConstantsAndVariablesTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/ConstantsAndVariablesTest.java index 41fffa715..6739e91d8 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/ConstantsAndVariablesTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/ConstantsAndVariablesTest.java @@ -25,85 +25,85 @@ public class ConstantsAndVariablesTest extends AbstractCompilerTest { @Test public void testLabelAsConstantWorks() throws Exception { compile( - "here equ 0\n" - + "ld a,b\n" - + "jp z, here" + "here equ 0\n" + + "ld a,b\n" + + "jp z, here" ); assertProgram( - 0x78, 0xCA, 0, 0 + 0x78, 0xCA, 0, 0 ); } @Test public void testConstantAsLabelWorks() throws Exception { compile( - "here equ there\n" - + "there: ld a,b\n" - + "jp z, here" + "here equ there\n" + + "there: ld a,b\n" + + "jp z, here" ); assertProgram( - 0x78, 0xCA, 0, 0 + 0x78, 0xCA, 0, 0 ); } @Test(expected = Exception.class) public void testRecursiveConstantDefinitionsDoesNotWork() throws Exception { compile( - "here equ there\n" - + "there equ here\n" - + "jp z, here" + "here equ there\n" + + "there equ here\n" + + "jp z, here" ); } @Test(expected = Exception.class) public void testTwoSameLabelsDoNotWork() throws Exception { compile( - "here:\nhere:\njp z, here" + "here:\nhere:\njp z, here" ); } @Test(expected = Exception.class) public void testTwoSameConstantsDoNotWork() throws Exception { compile( - "here equ 0\nhere equ 1" + "here equ 0\nhere equ 1" ); } @Test public void testVariableCanBeOverwritten() throws Exception { compile( - "here var 0\nhere var 1\ncp here" + "here var 0\nhere var 1\ncp here" ); assertProgram( - 0xFE, 1 + 0xFE, 1 ); } @Test(expected = Exception.class) public void testCannotSetVariableBecauseIdentifierIsAlreadyDefined() throws Exception { compile( - "here equ 0\nhere var 1\n" + "here equ 0\nhere var 1\n" ); } @Test(expected = Exception.class) public void testCannotDefineConstantBecauseIdentifierIsAlreadyDefined() throws Exception { compile( - "here: db 4\nhere equ 1\n" + "here: db 4\nhere equ 1\n" ); } @Test public void testForwardReferenceOfConstantShouldWork() throws Exception { compile("ld SP,STACK\n" + - "TEMPP: DW TEMP0\n" + - "TEMP0: DS 1\n" + - "STACK EQU TEMPP+256"); + "TEMPP: DW TEMP0\n" + + "TEMP0: DS 1\n" + + "STACK EQU TEMPP+256"); assertProgram( - 0x31, 0x03, 0x01, 5, 0, 0 + 0x31, 0x03, 0x01, 5, 0, 0 ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java index 5df2fb657..8f9fbff1d 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/DataTest.java @@ -25,138 +25,138 @@ public class DataTest extends AbstractCompilerTest { @Test public void testDBwithNegativeValueWorks() { compile( - "db -1" + "db -1" ); assertProgram( - 0xFF, 0 + 0xFF, 0 ); } @Test(expected = Exception.class) public void testDBwithNegativeValueHigherLowerThanMinus127doesNotWork() { compile( - "db -1299" + "db -1299" ); } @Test public void testDBallocatesOneByte() { compile( - "db 10\nld a,b\n" + "db 10\nld a,b\n" ); assertProgram( - 10, 0x78 + 10, 0x78 ); } @Test(expected = Exception.class) public void testDBbiggerThan255DoesNotWork() { compile( - "db 256\n" + "db 256\n" ); } @Test public void testDBseveralBytesWork() { compile( - "db 255,1,2\n" + "db 255,1,2\n" ); assertProgram( - 0xFF, 1, 2 + 0xFF, 1, 2 ); } @Test public void testDBWithInstruction() { compile( - "db inc A\n" + "db inc A\n" ); assertProgram( - 0x3C + 0x3C ); } @Test public void testDBliteral() { compile( - "db 'if'\n" + "db 'if'\n" ); assertProgram( - 'i', 'f' + 'i', 'f' ); } @Test public void testDBshortLiteral() { compile( - "db 'i'\n" + "db 'i'\n" ); assertProgram( - 'i' + 'i' ); } @Test public void testDWwithNegativeValueWorks() { compile( - "dw -1" + "dw -1" ); assertProgram( - 0xFF, 0xFF, 0 + 0xFF, 0xFF, 0 ); } @Test(expected = Exception.class) public void testDWwithNegativeValueHigherLowerThanMinus3768doesNotWork() { compile( - "dw -32769" + "dw -32769" ); } @Test public void testDWallocatesTwoBytesInLittleEndian() { compile( - "dw 10\nld a,b\n" + "dw 10\nld a,b\n" ); assertProgram( - 10, 0, 0x78 + 10, 0, 0x78 ); } @Test public void testDWseveralValuesWork() { compile( - "dw 10,4\nld a,b\n" + "dw 10,4\nld a,b\n" ); assertProgram( - 10, 0, 4, 0, 0x78 + 10, 0, 4, 0, 0x78 ); } @Test(expected = Exception.class) public void testDWmoreThanFFFFdoesNotWork() { compile( - "dw 10000h\nld a,b\n" + "dw 10000h\nld a,b\n" ); } @Test(expected = Exception.class) public void testDW_ValueTooBig() { compile( - "org 0FFFFh\n" - + "rrca\n" - + "test:\n" - + "dw test" + "org 0FFFFh\n" + + "rrca\n" + + "test:\n" + + "dw test" ); } @Test(expected = Exception.class) public void testDSwithNegativeValueDoesNotWork() { compile( - "ds -1" + "ds -1" ); } @@ -166,27 +166,27 @@ public void testDSbreaksPreviousMemoryContent() { memoryStub.write(1, (byte) 0x11); compile( - "ds 2\n" + "now: ld a,b\n" + "ds 2\n" + "now: ld a,b\n" ); assertProgram( - 0x0, 0x0, 0x78 + 0x0, 0x0, 0x78 ); } @Test public void testJumpBackwardWithDSamong() { compile( - "ds 2\n" + - "now: ld a,b\n" + "ds 2\n" + - "cp 'C'\n" + - "jp z, now\n" + - "ler: ld (HL), a" + "now: ld a,b\n" + + "ds 2\n" + + "cp 'C'\n" + + "jp z, now\n" + + "ler: ld (HL), a" ); assertProgram( - 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 + 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 ); } @@ -194,7 +194,7 @@ public void testJumpBackwardWithDSamong() { public void testDbOrdering() { compile("db 186, \"Hello\", 186, 10, 13"); assertProgram( - 186, 'H', 'e', 'l', 'l', 'o', 186, 10, 13 + 186, 'H', 'e', 'l', 'l', 'o', 186, 10, 13 ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IfNodeTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IfNodeTest.java index c79a557e2..79582fb83 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IfNodeTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IfNodeTest.java @@ -25,22 +25,22 @@ public class IfNodeTest extends AbstractCompilerTest { @Test public void testIfNodeIsProcessed() throws Exception { compile( - "if 1\n" - + " rrca\n" - + "endif" + "if 1\n" + + " rrca\n" + + "endif" ); assertProgram( - 0x0F + 0x0F ); } @Test public void testIfNodeIsNotProcessed() throws Exception { compile( - "if 0\n" - + " rrca\n" - + "endif" + "if 0\n" + + " rrca\n" + + "endif" ); assertProgram(); @@ -49,37 +49,37 @@ public void testIfNodeIsNotProcessed() throws Exception { @Test public void testIfNoteIsProcessedForNegativeExpression() throws Exception { compile( - "if -1\n" - + " rrca\n" - + "endif" + "if -1\n" + + " rrca\n" + + "endif" ); assertProgram( - 0x0F + 0x0F ); } @Test public void testIfCanEvaluateBackwardReferenceInExpression() throws Exception { compile( - "present equ 1\n" - + "if present\n" - + " rrca\n" - + "endif\n" + "present equ 1\n" + + "if present\n" + + " rrca\n" + + "endif\n" ); assertProgram( - 0x0F + 0x0F ); } @Test(expected = Exception.class) public void testIfCannotRedefineIdentifierInside() throws Exception { compile( - "text: db 6\n" - + "if 554\n" - + " text: db 5\n" - + "endif" + "text: db 6\n" + + "if 554\n" + + " text: db 5\n" + + "endif" ); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IncludeTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IncludeTest.java index 6b6c50bdd..c983e64d1 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IncludeTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IncludeTest.java @@ -28,12 +28,12 @@ public class IncludeTest extends AbstractCompilerTest { public void testIncludeAndForwardCall() throws Exception { File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( - "call sample\n" - + "include '" + includeFile.getAbsolutePath() + "'\n" + "call sample\n" + + "include '" + includeFile.getAbsolutePath() + "'\n" ); assertProgram( - 0xCD, 0x03, 0x00, 0x3E, 0, 0xC9 + 0xCD, 0x03, 0x00, 0x3E, 0, 0xC9 ); } @@ -41,12 +41,12 @@ public void testIncludeAndForwardCall() throws Exception { public void testCallDataInclude() throws Exception { File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( - "call sample\n" + - "label: db 'hello'\n" + - "include '" + includeFile.getAbsolutePath() + "'\n" + "call sample\n" + + "label: db 'hello'\n" + + "include '" + includeFile.getAbsolutePath() + "'\n" ); assertProgram( - 0xCD, 0x08, 0x00, 'h', 'e', 'l', 'l', 'o', 0x3E, 0, 0xC9 + 0xCD, 0x08, 0x00, 'h', 'e', 'l', 'l', 'o', 0x3E, 0, 0xC9 ); } @@ -55,13 +55,13 @@ public void testDoubleIncludeAndForwardCall() throws Exception { File first = new File(getClass().getResource("/sample.asm").toURI()); File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( - "call sample2\n" - + "include '" + first.getAbsolutePath() + "'\n" - + "include '" + second.getAbsolutePath() + "'\n" + "call sample2\n" + + "include '" + first.getAbsolutePath() + "'\n" + + "include '" + second.getAbsolutePath() + "'\n" ); assertProgram( - 0xCD, 06, 00, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9 + 0xCD, 06, 00, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9 ); } @@ -69,12 +69,12 @@ public void testDoubleIncludeAndForwardCall() throws Exception { public void testIncludeAndBackwardCall() throws Exception { File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( - "include '" + includeFile.getAbsolutePath() + "'\n" - + "call sample\n" + "include '" + includeFile.getAbsolutePath() + "'\n" + + "call sample\n" ); assertProgram( - 0x3E, 0, 0xC9, 0xCD, 0, 0 + 0x3E, 0, 0xC9, 0xCD, 0, 0 ); } @@ -83,13 +83,13 @@ public void testDoubleIncludeAndBackwardCall() throws Exception { File first = new File(getClass().getResource("/sample.asm").toURI()); File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( - "include '" + first.getAbsolutePath() + "'\n" - + "include '" + second.getAbsolutePath() + "'\n" - + "call sample\n" + "include '" + first.getAbsolutePath() + "'\n" + + "include '" + second.getAbsolutePath() + "'\n" + + "call sample\n" ); assertProgram( - 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0xCD, 0, 0 + 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0xCD, 0, 0 ); } @@ -97,14 +97,14 @@ public void testDoubleIncludeAndBackwardCall() throws Exception { public void testIncludeAndJMPafter() throws Exception { File includeFile = new File(getClass().getResource("/sample.asm").toURI()); compile( - "jp next\n" - + "include '" + includeFile.getAbsolutePath() + "'\n" - + "next:\n" - + "ld a, b\n" + "jp next\n" + + "include '" + includeFile.getAbsolutePath() + "'\n" + + "next:\n" + + "ld a, b\n" ); assertProgram( - 0xC3, 0x06, 0, 0x3E, 0, 0xC9, 0x78 + 0xC3, 0x06, 0, 0x3E, 0, 0xC9, 0x78 ); } @@ -113,15 +113,15 @@ public void testDoubleIncludeAndJMPafter() throws Exception { File first = new File(getClass().getResource("/sample.asm").toURI()); File second = new File(getClass().getResource("/sample2.asm").toURI()); compile( - "jp next\n" - + "include '" + first.getAbsolutePath() + "'\n" - + "include '" + second.getAbsolutePath() + "'\n" - + "next:\n" - + "ld a, b\n" + "jp next\n" + + "include '" + first.getAbsolutePath() + "'\n" + + "include '" + second.getAbsolutePath() + "'\n" + + "next:\n" + + "ld a, b\n" ); assertProgram( - 0xC3, 0x09, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0x78 + 0xC3, 0x09, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0x78 ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java index bee128431..99360fe3a 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrExprTest.java @@ -7,36 +7,36 @@ public class InstrExprTest extends AbstractCompilerTest { @Test public void testJump() { compile( - "JP EXAMPLE\n" + - "RST 00H\n" + - "EXAMPLE:\n" + - "ld A,01H" + "JP EXAMPLE\n" + + "RST 00H\n" + + "EXAMPLE:\n" + + "ld A,01H" ); assertProgram( - 0xC3, 0x04, 0x00, 0xC7, 0x3E, 0x01 + 0xC3, 0x04, 0x00, 0xC7, 0x3E, 0x01 ); } @Test public void testRelativeJumpLabel() { compile( - "ld A,01H\n" + - "jr z, EXAMPLE\n" + - "RST 00H\n" + - "EXAMPLE:\n" + - "halt" + "ld A,01H\n" + + "jr z, EXAMPLE\n" + + "RST 00H\n" + + "EXAMPLE:\n" + + "halt" ); assertProgram( - 0x3E, 0x01, 0x28, 0x01, 0xC7, 0x76 + 0x3E, 0x01, 0x28, 0x01, 0xC7, 0x76 ); } @Test public void testRelativeJumpCurrentAddress() { compile("halt\njr $"); // infinite loop - assertProgram(0x76, 0x18, (byte)-2); + assertProgram(0x76, 0x18, (byte) -2); } @Test @@ -54,8 +54,8 @@ public void testCP() { @Test public void testForwardCall() { compile("call sample\n" + - "label: db 'hello'\n" + - "sample: halt"); + "label: db 'hello'\n" + + "sample: halt"); assertProgram(0xCD, 0x08, 0x00, 'h', 'e', 'l', 'l', 'o', 0x76); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java index cb5a09e94..12ecf7f90 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/InstrRegTest.java @@ -25,180 +25,180 @@ public class InstrRegTest extends AbstractCompilerTest { @Test public void testINR() throws Exception { compile( - "inc A\n" - + "inc B\n" - + "inc C\n" - + "inc D\n" - + "inc E\n" - + "inc H\n" - + "inc L\n" - + "inc (HL)\n" + "inc A\n" + + "inc B\n" + + "inc C\n" + + "inc D\n" + + "inc E\n" + + "inc H\n" + + "inc L\n" + + "inc (HL)\n" ); assertProgram( - 0x3C, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34 + 0x3C, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34 ); } @Test public void testDCR() throws Exception { compile( - "dec A\n" - + "dec B\n" - + "dec C\n" - + "dec D\n" - + "dec E\n" - + "dec H\n" - + "dec L\n" - + "dec (HL)\n" + "dec A\n" + + "dec B\n" + + "dec C\n" + + "dec D\n" + + "dec E\n" + + "dec H\n" + + "dec L\n" + + "dec (HL)\n" ); assertProgram( - 0x3D, 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, 0x35 + 0x3D, 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, 0x35 ); } @Test public void testADD() throws Exception { compile( - "add A, A\n" - + "add A,B\n" - + "add A,C\n" - + "add A,D\n" - + "add A,E\n" - + "add A,H\n" - + "add A,L\n" - + "add A,(HL)\n" + "add A, A\n" + + "add A,B\n" + + "add A,C\n" + + "add A,D\n" + + "add A,E\n" + + "add A,H\n" + + "add A,L\n" + + "add A,(HL)\n" ); assertProgram( - 0x87, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86 + 0x87, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86 ); } @Test public void testADC() throws Exception { compile( - "adc A, A\n" - + "adc A,B\n" - + "adc A,C\n" - + "adc A,D\n" - + "adc A,E\n" - + "adc A,H\n" - + "adc A,L\n" - + "adc A,(HL)\n" + "adc A, A\n" + + "adc A,B\n" + + "adc A,C\n" + + "adc A,D\n" + + "adc A,E\n" + + "adc A,H\n" + + "adc A,L\n" + + "adc A,(HL)\n" ); assertProgram( - 0x8F, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E + 0x8F, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E ); } @Test public void testSUB() throws Exception { compile( - "sub A\n" - + "sub B\n" - + "sub C\n" - + "sub D\n" - + "sub E\n" - + "sub H\n" - + "sub L\n" - + "sub (HL)\n" + "sub A\n" + + "sub B\n" + + "sub C\n" + + "sub D\n" + + "sub E\n" + + "sub H\n" + + "sub L\n" + + "sub (HL)\n" ); assertProgram( - 0x97, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96 + 0x97, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96 ); } @Test public void testSBC() throws Exception { compile( - "sbc A,A\n" - + "sbc A,B\n" - + "sbc A,C\n" - + "sbc A,D\n" - + "sbc A,E\n" - + "sbc A,H\n" - + "sbc A,L\n" - + "sbc A,(HL)\n" + "sbc A,A\n" + + "sbc A,B\n" + + "sbc A,C\n" + + "sbc A,D\n" + + "sbc A,E\n" + + "sbc A,H\n" + + "sbc A,L\n" + + "sbc A,(HL)\n" ); assertProgram( - 0x9F, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E + 0x9F, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E ); } @Test public void testAND() throws Exception { compile( - "and A\n" - + "and B\n" - + "and C\n" - + "and D\n" - + "and E\n" - + "and H\n" - + "and L\n" - + "and (HL)\n" + "and A\n" + + "and B\n" + + "and C\n" + + "and D\n" + + "and E\n" + + "and H\n" + + "and L\n" + + "and (HL)\n" ); assertProgram( - 0xA7, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6 + 0xA7, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6 ); } @Test public void testXOR() throws Exception { compile( - "xor A\n" - + "xor B\n" - + "xor C\n" - + "xor D\n" - + "xor E\n" - + "xor H\n" - + "xor L\n" - + "xor (HL)\n" + "xor A\n" + + "xor B\n" + + "xor C\n" + + "xor D\n" + + "xor E\n" + + "xor H\n" + + "xor L\n" + + "xor (HL)\n" ); assertProgram( - 0xAF, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE + 0xAF, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE ); } @Test public void testOR() throws Exception { compile( - "or A\n" - + "or B\n" - + "or C\n" - + "or D\n" - + "or E\n" - + "or H\n" - + "or L\n" - + "or (HL)\n" + "or A\n" + + "or B\n" + + "or C\n" + + "or D\n" + + "or E\n" + + "or H\n" + + "or L\n" + + "or (HL)\n" ); assertProgram( - 0xB7, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6 + 0xB7, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6 ); } @Test public void testCP() throws Exception { compile( - "cp A\n" - + "cp B\n" - + "cp C\n" - + "cp D\n" - + "cp E\n" - + "cp H\n" - + "cp L\n" - + "cp (HL)\n" + "cp A\n" + + "cp B\n" + + "cp C\n" + + "cp D\n" + + "cp E\n" + + "cp H\n" + + "cp L\n" + + "cp (HL)\n" ); assertProgram( - 0xBF, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE + 0xBF, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE ); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/MacroTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/MacroTest.java index a1ea5c9e6..89b12a470 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/MacroTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/MacroTest.java @@ -25,10 +25,10 @@ public class MacroTest extends AbstractCompilerTest { @Test public void testMacroWithoutCallDoesNotGenerateCode() throws Exception { compile( - "shrt macro\n" - + " rrca\n" - + " and 7Fh\n" - + "endm\n\n" + "shrt macro\n" + + " rrca\n" + + " and 7Fh\n" + + "endm\n\n" ); assertProgram(); } @@ -36,106 +36,106 @@ public void testMacroWithoutCallDoesNotGenerateCode() throws Exception { @Test public void testMacroWithoutParams() throws Exception { compile( - "shrt macro\n" - + " rrca\n" - + " and 7Fh\n" - + "endm\n\n" - + "shrt\n" + "shrt macro\n" + + " rrca\n" + + " and 7Fh\n" + + "endm\n\n" + + "shrt\n" ); assertProgram( - 0x0F, 0xE6, 0x7F + 0x0F, 0xE6, 0x7F ); } @Test public void testMacroWithParams() throws Exception { compile( - "shrt macro amount, dbsize\n" - + " rrca\n" - + " and amount\n" - + " db dbsize\n" - + "endm\n\n" - + "shrt 7Fh, 0\n" + "shrt macro amount, dbsize\n" + + " rrca\n" + + " and amount\n" + + " db dbsize\n" + + "endm\n\n" + + "shrt 7Fh, 0\n" ); assertProgram( - 0x0F, 0xE6, 0x7F + 0x0F, 0xE6, 0x7F ); } @Test public void testDBinMacroIsVisibleFromOutside() throws Exception { compile( - "shrt macro\n" - + " text: db 0Fh\n" - + " and 7Fh\n" - + "endm\n\n" - + "shrt\n" - + "ld HL, text\n" + "shrt macro\n" + + " text: db 0Fh\n" + + " and 7Fh\n" + + "endm\n\n" + + "shrt\n" + + "ld HL, text\n" ); assertProgram( - 0x0F, 0xE6, 0x7F, 0x21, 0, 0 + 0x0F, 0xE6, 0x7F, 0x21, 0, 0 ); } @Test(expected = Exception.class) public void testCannotRedefineIdentifierInMacro() throws Exception { compile( - "hello: db 0\n" - + "shrt macro\n" - + " hello equ 0Fh\n" - + "endm\n" - + "shrt\n" + "hello: db 0\n" + + "shrt macro\n" + + " hello equ 0Fh\n" + + "endm\n" + + "shrt\n" ); } @Test(expected = Exception.class) public void testMacroAlreadyDefined() throws Exception { compile( - "shrt macro\nendm\n" - + "shrt macro\nendm\n" + "shrt macro\nendm\n" + + "shrt macro\nendm\n" ); } @Test public void testMacroCanGetForwardLabelReferences() throws Exception { compile( - "shrt macro param\n" - + " ld HL, param\n" - + "endm\n" - + "shrt text\n" - + "text: db 1\n" + "shrt macro param\n" + + " ld HL, param\n" + + "endm\n" + + "shrt text\n" + + "text: db 1\n" ); assertProgram( - 0x21, 3, 0, 1 + 0x21, 3, 0, 1 ); } @Test(expected = Exception.class) public void testLessMacroParametersThanExpected() throws Exception { compile( - "shrt macro param\n" - + " lD HL, param\n" - + "endm\n" - + "shrt\n" + "shrt macro param\n" + + " lD HL, param\n" + + "endm\n" + + "shrt\n" ); } @Test(expected = Exception.class) public void testMoreMacroParametersThanExpected() throws Exception { compile( - "shrt macro param\n" - + " ld HL, param\n" - + "endm\n" - + "shrt 1, 2\n" + "shrt macro param\n" + + " ld HL, param\n" + + "endm\n" + + "shrt 1, 2\n" ); } @Test(expected = Exception.class) public void testCallUndefinedMacro() throws Exception { compile( - "shrt 1,2\n" + "shrt 1,2\n" ); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/PseudoOrgTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/PseudoOrgTest.java index 85f424e7f..a655411ab 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/PseudoOrgTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/PseudoOrgTest.java @@ -38,100 +38,100 @@ public void setup() { @Test public void testORGwithInclude() throws Exception { compile( - "org 3\n" - + "call sample\n" - + "include '" + sampleFile + "'\n" + "org 3\n" + + "call sample\n" + + "include '" + sampleFile + "'\n" ); assertProgram( - 0, 0, 0, 0xCD, 6, 0, 0x3E, 0, 0xC9 + 0, 0, 0, 0xCD, 6, 0, 0x3E, 0, 0xC9 ); } @Test public void testORGwithDoubleInclude() throws Exception { compile( - "org 3\n" - + "call sample\n" - + "include '" + sample2File + "'\n" - + "include '" + sampleFile + "'\n" + "org 3\n" + + "call sample\n" + + "include '" + sample2File + "'\n" + + "include '" + sampleFile + "'\n" ); assertProgram( - 0, 0, 0, 0xCD, 0x09, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9 + 0, 0, 0, 0xCD, 0x09, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9 ); } @Test public void testORGwithDoubleIncludeAndJMPafter() throws Exception { compile( - "org 3\n" - + "jp next\n" - + "include '" + sampleFile + "'\n" - + "include '" + sample2File + "'\n" - + "next:\n" - + "ld a, b\n" + "org 3\n" + + "jp next\n" + + "include '" + sampleFile + "'\n" + + "include '" + sample2File + "'\n" + + "next:\n" + + "ld a, b\n" ); assertProgram( - 0, 0, 0, 0xC3, 0x0C, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0x78 + 0, 0, 0, 0xC3, 0x0C, 0, 0x3E, 0, 0xC9, 0x3E, 0, 0xC9, 0x78 ); } @Test public void testORGwithDB() throws Exception { compile( - "org 3\n" - + "ld HL, text\n" - + "text:\n" - + "db 'ahoj'" + "org 3\n" + + "ld HL, text\n" + + "text:\n" + + "db 'ahoj'" ); assertProgram( - 0, 0, 0, 0x21, 0x06, 0, 'a', 'h', 'o', 'j' + 0, 0, 0, 0x21, 0x06, 0, 'a', 'h', 'o', 'j' ); } @Test public void testORG() throws Exception { compile( - "org 2\n" + - "now: ld a,b\n" + - "ds 2\n" + - "cp 'C'\n" + - "jp z, now\n" + - "ler: ld (HL), a" + "org 2\n" + + "now: ld a,b\n" + + "ds 2\n" + + "cp 'C'\n" + + "jp z, now\n" + + "ler: ld (HL), a" ); assertProgram( - 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 + 0, 0, 0x78, 0, 0, 0xFE, 0x43, 0xCA, 0x02, 0x00, 0x77 ); } @Test public void testORGwithJumpBackwards() throws Exception { compile( - "sample:\n" - + "org 2\n" - + "jp sample" + "sample:\n" + + "org 2\n" + + "jp sample" ); assertProgram( - 0, 0, 0xC3, 0, 0 + 0, 0, 0xC3, 0, 0 ); } @Test public void testORGwithJumpForwards() throws Exception { compile( - "jp sample\n" - + "org 5\n" - + "sample:\n" - + "ld a, b" + "jp sample\n" + + "org 5\n" + + "sample:\n" + + "ld a, b" ); assertProgram( - 0xC3, 0x05, 0, 0, 0, 0x78 + 0xC3, 0x05, 0, 0, 0, 0x78 ); } @@ -141,28 +141,28 @@ public void testORGdoesNotBreakPreviousMemoryContent() throws Exception { memoryStub.write(1, (byte) 0x11); compile( - "org 2\n" + "now: ld a,b\n" + "org 2\n" + "now: ld a,b\n" ); assertProgram( - 0x10, 0x11, 0x78 + 0x10, 0x11, 0x78 ); } @Test public void testORGthenDSdoNotOverlap() throws Exception { compile( - "org 2\nds 2\nld a,b" + "org 2\nds 2\nld a,b" ); assertProgram( - 0, 0, 0, 0, 0x78 + 0, 0, 0, 0, 0x78 ); } @Test(expected = Exception.class) public void testORGisAmbiguous() throws Exception { compile( - "org text\nld a, 4\ntext: db 4\n" + "org text\nld a, 4\ntext: db 4\n" ); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java index 2b6d82fb6..dcc021801 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/LexicalAnalyzerImplTest.java @@ -44,34 +44,34 @@ public void testParseError2() { @Test public void testParseHex1() { assertTokenTypes( - "0x1 0x0 -0x5f -0xFffF 0x1BC", - LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, - WS, LIT_HEXNUMBER_1, EOF + "0x1 0x0 -0x5f -0xFffF 0x1BC", + LIT_HEXNUMBER_1, WS, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, WS, OP_SUBTRACT, LIT_HEXNUMBER_1, + WS, LIT_HEXNUMBER_1, EOF ); } @Test public void testParseHex2() { assertTokenTypes( - "1h 0h -5Fh -FFFFh 1BCh 5h -5h", - LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, - WS, LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, EOF + "1h 0h -5Fh -FFFFh 1BCh 5h -5h", + LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, + WS, LIT_HEXNUMBER_2, WS, LIT_HEXNUMBER_2, WS, OP_SUBTRACT, LIT_HEXNUMBER_2, EOF ); } @Test public void testParseDecimal() { assertTokenTypes( - "0 1 -2 3 -4 5 66 999", - LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, - WS, LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF + "0 1 -2 3 -4 5 66 999", + LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, WS, LIT_NUMBER, WS, OP_SUBTRACT, LIT_NUMBER, + WS, LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF ); } @Test public void testParseOctal() { assertTokenTypes("-6o 7q 11q -345O", - OP_SUBTRACT, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, OP_SUBTRACT, LIT_OCTNUMBER, EOF + OP_SUBTRACT, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, OP_SUBTRACT, LIT_OCTNUMBER, EOF ); } @@ -283,8 +283,8 @@ public void testSeparators() { @Test public void testOperators1() { assertTokenTypes("+-*/=<<>><><=>=^%|&", - OP_ADD, OP_SUBTRACT, OP_MULTIPLY, OP_DIVIDE, OP_EQUAL, OP_SHL_2, OP_SHR_2, OP_LT, OP_GT, OP_LTE, OP_GTE, - OP_XOR, OP_MOD_2, OP_OR, OP_AND, EOF); + OP_ADD, OP_SUBTRACT, OP_MULTIPLY, OP_DIVIDE, OP_EQUAL, OP_SHL_2, OP_SHR_2, OP_LT, OP_GT, OP_LTE, OP_GTE, + OP_XOR, OP_MOD_2, OP_OR, OP_AND, EOF); } @Test diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java index e11ce82eb..59e93b499 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseDataTest.java @@ -39,9 +39,9 @@ public class ParseDataTest { public void testDBstring1() { Program program = parseProgram("db 'hello'"); assertTrees(new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprString(0, 0, "hello"))), - program + .addChild(new DataDB(0, 0) + .addChild(new ExprString(0, 0, "hello"))), + program ); } @@ -49,9 +49,9 @@ public void testDBstring1() { public void testDBstring2() { Program program = parseProgram("db \"hello\""); assertTrees(new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprString(0, 0, "hello"))), - program + .addChild(new DataDB(0, 0) + .addChild(new ExprString(0, 0, "hello"))), + program ); } @@ -59,10 +59,10 @@ public void testDBstring2() { public void testDBinstruction() { Program program = parseProgram("db ret"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1))), + program ); } @@ -70,12 +70,12 @@ public void testDBinstruction() { public void testMultipleDB() { Program program = parseProgram("db -1,2,3"); assertTrees(new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))), - program + .addChild(new DataDB(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))), + program ); } @@ -83,10 +83,10 @@ public void testMultipleDB() { public void testDBwithNegativeValue() { Program program = parseProgram("db -1"); assertTrees(new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 1)))), - program + .addChild(new DataDB(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1)))), + program ); } @@ -94,12 +94,12 @@ public void testDBwithNegativeValue() { public void testMultipleDBstringNumberString() { Program program = parseProgram("db -1,'hello',3"); assertTrees(new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprString(0, 0, "hello")) - .addChild(new ExprNumber(0, 0, 3))), - program + .addChild(new DataDB(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprString(0, 0, "hello")) + .addChild(new ExprNumber(0, 0, 3))), + program ); } @@ -107,12 +107,12 @@ public void testMultipleDBstringNumberString() { public void testMultipleDW() { Program program = parseProgram("dw -1,2,3"); assertTrees(new Program() - .addChild(new DataDW(0, 0) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))), - program + .addChild(new DataDW(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))), + program ); } @@ -120,10 +120,10 @@ public void testMultipleDW() { public void testDWwithNegativeValue() { Program program = parseProgram("dw -1"); assertTrees(new Program() - .addChild(new DataDW(0, 0) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 1)))), - program + .addChild(new DataDW(0, 0) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 1)))), + program ); } @@ -131,9 +131,9 @@ public void testDWwithNegativeValue() { public void testDS() { Program program = parseProgram("ds 0x55"); assertTrees(new Program() - .addChild(new DataDS(0, 0) - .addChild(new ExprNumber(0, 0, 0x55))), - program + .addChild(new DataDS(0, 0) + .addChild(new ExprNumber(0, 0, 0x55))), + program ); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java index 4cf17d9ee..1db74f847 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseExprTest.java @@ -35,14 +35,14 @@ public class ParseExprTest { public void testPrioritiesAddMul() { Program program = parseProgram("db 2+3*4"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprNumber(0, 0, 3)) - .addChild(new ExprNumber(0, 0, 4))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 3)) + .addChild(new ExprNumber(0, 0, 4))))), + program ); } @@ -50,14 +50,14 @@ public void testPrioritiesAddMul() { public void testPrioritiesMulAdd() { Program program = parseProgram("db 2*3+4"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new ExprNumber(0, 0, 4)))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4)))), + program ); } @@ -65,16 +65,16 @@ public void testPrioritiesMulAdd() { public void testAssociativityPlusMinus() { Program program = parseProgram("db 2-3+4-9"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new ExprNumber(0, 0, 4))) - .addChild(new ExprNumber(0, 0, 9)))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4))) + .addChild(new ExprNumber(0, 0, 9)))), + program ); } @@ -82,16 +82,16 @@ public void testAssociativityPlusMinus() { public void testAssociativitMulDiv() { Program program = parseProgram("db 2/3*4/9"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_DIVIDE) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprInfix(0, 0, OP_DIVIDE) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new ExprNumber(0, 0, 4))) - .addChild(new ExprNumber(0, 0, 9)))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprNumber(0, 0, 4))) + .addChild(new ExprNumber(0, 0, 9)))), + program ); } @@ -99,20 +99,20 @@ public void testAssociativitMulDiv() { public void testPrecedencePlusMinusMulDivMod() { Program program = parseProgram("db 2+3*4-9/2 mod 3"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprNumber(0, 0, 3)) - .addChild(new ExprNumber(0, 0, 4)))) - .addChild(new ExprInfix(0, 0, OP_MOD) - .addChild(new ExprInfix(0, 0, OP_DIVIDE) - .addChild(new ExprNumber(0, 0, 9)) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprNumber(0, 0, 3))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprNumber(0, 0, 3)) + .addChild(new ExprNumber(0, 0, 4)))) + .addChild(new ExprInfix(0, 0, OP_MOD) + .addChild(new ExprInfix(0, 0, OP_DIVIDE) + .addChild(new ExprNumber(0, 0, 9)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 3))))), + program ); } @@ -120,22 +120,22 @@ public void testPrecedencePlusMinusMulDivMod() { public void testAssociativityEqual() { Program program = parseProgram("db 1 + 2 + 2 = 5 = 5 = 6 - 1"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprInfix(0, 0, OP_ADD) // 1 + 2 + 2 associates to left - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 1)) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprNumber(0, 0, 5)) // ... = 5 associates to right - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprNumber(0, 0, 5)) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) // minus has > precedence than = - .addChild(new ExprNumber(0, 0, 6)) - .addChild(new ExprNumber(0, 0, 1))))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprInfix(0, 0, OP_ADD) // 1 + 2 + 2 associates to left + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) // ... = 5 associates to right + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) // minus has > precedence than = + .addChild(new ExprNumber(0, 0, 6)) + .addChild(new ExprNumber(0, 0, 1))))))), + program ); } @@ -143,28 +143,28 @@ public void testAssociativityEqual() { public void testAndMulXorDivNotPlusMinus() { Program program = parseProgram("db not 1 & 2 | 2 ^ 5 = - 5 * 6 shl 4 - 1 shr 2"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_OR) - .addChild(new ExprInfix(0, 0, OP_AND) - .addChild(new ExprUnary(0, 0, OP_NOT) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprInfix(0, 0, OP_XOR) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprNumber(0, 0, 5)) - .addChild(new ExprInfix(0, 0, OP_SHR) - .addChild(new ExprInfix(0, 0, OP_SHL) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 5))) - .addChild(new ExprNumber(0, 0, 6))) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 4)) - .addChild(new ExprNumber(0, 0, 1)))) - .addChild(new ExprNumber(0, 0, 2))))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_OR) + .addChild(new ExprInfix(0, 0, OP_AND) + .addChild(new ExprUnary(0, 0, OP_NOT) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SHR) + .addChild(new ExprInfix(0, 0, OP_SHL) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))))), + program ); } @@ -173,28 +173,28 @@ public void testAndMulXorDivNotPlusMinusWithOperators() { //Program program = parseProgram("db ((~1) & 2) | (2 ^ (5 = ((((-5) * 6) << (4 - 1)) >> 2)))"); Program program = parseProgram("db ~1 & 2 | 2 ^ 5 = -5 * 6 << 4 - 1 >> 2"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_OR) - .addChild(new ExprInfix(0, 0, OP_AND) - .addChild(new ExprUnary(0, 0, OP_NOT_2) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprInfix(0, 0, OP_XOR) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprNumber(0, 0, 5)) - .addChild(new ExprInfix(0, 0, OP_SHR_2) - .addChild(new ExprInfix(0, 0, OP_SHL_2) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprUnary(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 5))) - .addChild(new ExprNumber(0, 0, 6))) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 4)) - .addChild(new ExprNumber(0, 0, 1)))) - .addChild(new ExprNumber(0, 0, 2))))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_OR) + .addChild(new ExprInfix(0, 0, OP_AND) + .addChild(new ExprUnary(0, 0, OP_NOT_2) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprInfix(0, 0, OP_XOR) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprNumber(0, 0, 5)) + .addChild(new ExprInfix(0, 0, OP_SHR_2) + .addChild(new ExprInfix(0, 0, OP_SHL_2) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprUnary(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 5))) + .addChild(new ExprNumber(0, 0, 6))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new ExprNumber(0, 0, 2))))))), + program ); } @@ -202,16 +202,16 @@ public void testAndMulXorDivNotPlusMinusWithOperators() { public void testParenthesis() { Program program = parseProgram("db (2 + 3) * (4 - 2)"); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_MULTIPLY) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 2)) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new ExprInfix(0, 0, OP_SUBTRACT) - .addChild(new ExprNumber(0, 0, 4)) - .addChild(new ExprNumber(0, 0, 2))))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_MULTIPLY) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 2)) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new ExprInfix(0, 0, OP_SUBTRACT) + .addChild(new ExprNumber(0, 0, 4)) + .addChild(new ExprNumber(0, 0, 2))))), + program ); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java index a5d8f2dad..33042cda3 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParseInstrTest.java @@ -197,10 +197,10 @@ public void testInstrExpr() { public void testCallLabelWithConditionPrefix() { Program program = parseProgram("peter: call peter"); assertTrees(new Program() - .addChild(new PseudoLabel(0, 0, "peter") - .addChild(new Instr(0, 0, OPCODE_CALL, 3, 1, 5) - .addChild(new ExprId(0, 0, "peter")))), - program + .addChild(new PseudoLabel(0, 0, "peter") + .addChild(new Instr(0, 0, OPCODE_CALL, 3, 1, 5) + .addChild(new ExprId(0, 0, "peter")))), + program ); } @@ -326,8 +326,8 @@ private void assertInstrED(String instr, int instrType, int y, int z) { private void assertInstrEDExpr(String instrPrefix, String instrPostfix, int y) { Node expr = new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 5)); + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); forStringCaseVariations(instrPrefix, prefixVariation -> forStringCaseVariations(instrPostfix, postfixVariation -> { Program program = parseProgram(prefixVariation + " $ + 5" + postfixVariation); @@ -344,8 +344,8 @@ private void assertInstrCB(String instr, int instrType, int y, int z) { private void assertInstrExpr(String instrPrefix, String instrPostfix, int instrType, int x, int y, int z) { Node expr = new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 5)); + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); forStringCaseVariations(instrPrefix, prefixVariation -> forStringCaseVariations(instrPostfix, postfixVariation -> { Program program = parseProgram(prefixVariation + " $ + 5" + postfixVariation); @@ -372,8 +372,8 @@ private void assertInstrCBExprBit(String instr, int instrType, int y, int z) { private void assertInstrXDCBExpr(String instrPrefix, String instrPostfix, int instrType, int prefix, int y, int z) { Node expr = new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 5)); + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); forStringCaseVariations(instrPrefix, instrPrefixVariation -> forStringCaseVariations(instrPostfix, instrPostfixVariation -> { Program program = parseProgram(instrPrefixVariation + " $ + 5" + instrPostfixVariation); @@ -383,17 +383,17 @@ private void assertInstrXDCBExpr(String instrPrefix, String instrPostfix, int in private void assertInstrXDCBExprBit(String instrPrefix, String instrPostfix, int instrType, int prefix, int y, int z) { Node expr = new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 5)); + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); Node yExpr = new ExprNumber(0, 0, y); forStringCaseVariations(instrPrefix, instrPrefixVariation -> forStringCaseVariations(instrPostfix, instrPostfixVariation -> { Program program = parseProgram(instrPrefixVariation + " $ + 5" + instrPostfixVariation); assertTrees(new Program() - .addChild(new InstrXDCB(0, 0, instrType, prefix, 0, z) - .addChild(yExpr) - .addChild(expr)), program); + .addChild(new InstrXDCB(0, 0, instrType, prefix, 0, z) + .addChild(yExpr) + .addChild(expr)), program); })); } @@ -410,8 +410,8 @@ private void assertInstrXD(String instr, int instrType, int prefix, int x, int p private void assertInstrXDExpr(String instrPrefix, String instrPostfix, int instrType, int prefix, int x, int y, int z) { Node expr = new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 5)); + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); forStringCaseVariations(instrPrefix, prefixVariation -> { forStringCaseVariations(instrPostfix, postfixVariation -> { @@ -423,17 +423,17 @@ private void assertInstrXDExpr(String instrPrefix, String instrPostfix, int inst private void assertInstrXDExprExpr(String instrPrefix, int prefix) { Node disp = new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 5)); + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 5)); Node expr = new ExprNumber(0, 0, 5); forStringCaseVariations(instrPrefix, prefixVariation -> { Program program = parseProgram(prefixVariation + " $ + 5), 5"); assertTrees(new Program() - .addChild(new InstrXD(0, 0, OPCODE_LD, prefix, 0, 6, 6) - .addChild(disp) - .addChild(expr)), program); + .addChild(new InstrXD(0, 0, OPCODE_LD, prefix, 0, 6, 6) + .addChild(disp) + .addChild(expr)), program); }); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java index 334ed44a4..e48816ec7 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsePseudoTest.java @@ -40,9 +40,9 @@ public class ParsePseudoTest { public void testConstant() { Program program = parseProgram("here equ 0x55"); assertTrees(new Program() - .addChild(new PseudoEqu(0, 0, "here") - .addChild(new ExprNumber(0, 0, 0x55))), - program + .addChild(new PseudoEqu(0, 0, "here") + .addChild(new ExprNumber(0, 0, 0x55))), + program ); } @@ -50,9 +50,9 @@ public void testConstant() { public void testVariable() { Program program = parseProgram("here var 0x55"); assertTrees(new Program() - .addChild(new PseudoVar(0, 0, "here") - .addChild(new ExprNumber(0, 0, 0x55))), - program + .addChild(new PseudoVar(0, 0, "here") + .addChild(new ExprNumber(0, 0, 0x55))), + program ); } @@ -60,45 +60,45 @@ public void testVariable() { public void testOrg() { Program program = parseProgram("org 55+88"); assertTrees(new Program() - .addChild(new PseudoOrg(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 55)) - .addChild(new ExprNumber(0, 0, 88)))), - program + .addChild(new PseudoOrg(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 55)) + .addChild(new ExprNumber(0, 0, 88)))), + program ); } @Test public void testIf() { Program program = parseProgram("if 1\n" - + " rrca\n" - + " rrca\n" - + "endif"); + + " rrca\n" + + " rrca\n" + + "endif"); assertTrees(new Program() - .addChild(new PseudoIf(0, 0) - .addChild(new PseudoIfExpression(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)) - .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7))), - program + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)) + .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7))), + program ); } @Test public void testIfEmpty() { List programs = List.of( - "if 1\n\n\nendif", - "if 1\n\nendif", - "if 1\nendif" + "if 1\n\n\nendif", + "if 1\n\nendif", + "if 1\nendif" ); for (String src : programs) { Program program = parseProgram(src); Node expected = new Program() - .addChild(new PseudoIf(0, 0) - .addChild(new PseudoIfExpression(0, 0) - .addChild(new ExprNumber(0, 0, 1)))); + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 1)))); assertTrees(expected, program); } } @@ -111,17 +111,17 @@ public void testIfEndifMustBeOnNewLine() { @Test public void testTwoLabelsInsideIf() { Program program = parseProgram("if 1\n" - + " label1:\n" - + " label2:\n" - + "endif"); + + " label1:\n" + + " label2:\n" + + "endif"); assertTrees(new Program() - .addChild(new PseudoIf(0, 0) - .addChild(new PseudoIfExpression(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoLabel(0, 0, "label1")) - .addChild(new PseudoLabel(0, 0, "label2"))), - program + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoLabel(0, 0, "label1")) + .addChild(new PseudoLabel(0, 0, "label2"))), + program ); } @@ -129,28 +129,28 @@ public void testTwoLabelsInsideIf() { public void testInclude() { Program program = parseProgram("include 'filename.asm'"); assertTrees( - new Program().addChild(new PseudoInclude(0, 0, "filename.asm")), - program + new Program().addChild(new PseudoInclude(0, 0, "filename.asm")), + program ); } @Test public void testMacroDef() { Program program = parseProgram("shrt macro param1, param2\n" - + " rrca\n" - + " heylabel: and 7Fh\n" - + "endm\n\n"); + + " rrca\n" + + " heylabel: and 7Fh\n" + + "endm\n\n"); Node expected = new Program() - .addChild(new PseudoMacroDef(0, 0, "shrt") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "param1"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "param2"))) - .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)) - .addChild(new PseudoLabel(0, 0, "heylabel") - .addChild(new Instr(0, 0, OPCODE_AND, 3, 4, 6) - .addChild(new ExprNumber(0, 0, 0x7F))))); + .addChild(new PseudoMacroDef(0, 0, "shrt") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "param1"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "param2"))) + .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)) + .addChild(new PseudoLabel(0, 0, "heylabel") + .addChild(new Instr(0, 0, OPCODE_AND, 3, 4, 6) + .addChild(new ExprNumber(0, 0, 0x7F))))); assertTrees(expected, program); } @@ -158,9 +158,9 @@ public void testMacroDef() { @Test public void testMacroDefEmpty() { List programs = List.of( - "shrt macro\n\n\nendm", - "shrt macro\n\nendm", - "shrt macro\nendm" + "shrt macro\n\n\nendm", + "shrt macro\n\nendm", + "shrt macro\nendm" ); for (String src : programs) { @@ -187,11 +187,11 @@ public void testMacroCallWithParams() { Program program = parseProgram("shrt param1, 45"); Node expected = new Program() - .addChild(new PseudoMacroCall(0, 0, "shrt") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "param1"))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 45)))); + .addChild(new PseudoMacroCall(0, 0, "shrt") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "param1"))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 45)))); assertTrees(expected, program); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java index 8fa1a82ec..f363fc6c9 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/parser/ParsingUtilsTest.java @@ -61,8 +61,8 @@ public void testParseLitHex2() { public void testParseLitOct() { List tokens = getTokens("22q 55O 77Q 001o"); assertTokenTypes( - tokens, - LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, EOF + tokens, + LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, WS, LIT_OCTNUMBER, EOF ); assertEquals(18, ParsingUtils.parseLitOct(tokens.get(0))); assertEquals(45, ParsingUtils.parseLitOct(tokens.get(2))); @@ -74,8 +74,8 @@ public void testParseLitOct() { public void testParseLitDec() { List tokens = getTokens("22 55 00"); assertTokenTypes( - tokens, - LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF + tokens, + LIT_NUMBER, WS, LIT_NUMBER, WS, LIT_NUMBER, EOF ); assertEquals(22, ParsingUtils.parseLitDec(tokens.get(0))); assertEquals(55, ParsingUtils.parseLitDec(tokens.get(2))); @@ -86,8 +86,8 @@ public void testParseLitDec() { public void testParseLitBin() { List tokens = getTokens("000b 0101101b 111b"); assertTokenTypes( - tokens, - LIT_BINNUMBER, WS, LIT_BINNUMBER, WS, LIT_BINNUMBER, EOF + tokens, + LIT_BINNUMBER, WS, LIT_BINNUMBER, WS, LIT_BINNUMBER, EOF ); assertEquals(0, ParsingUtils.parseLitBin(tokens.get(0))); assertEquals(45, ParsingUtils.parseLitBin(tokens.get(2))); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java index ce72bfa1c..01095f131 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitorTest.java @@ -42,8 +42,8 @@ public class CheckExprSizesVisitorTest { public void testDBoneByte() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 0xFF))); + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 0xFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -55,9 +55,9 @@ public void testDBoneByte() { public void testDBtwoBytes() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 0xFF)) - .addChild(new Evaluated(0, 0, 0x100))); // bad size + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 0xFF)) + .addChild(new Evaluated(0, 0, 0x100))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -69,8 +69,8 @@ public void testDBtwoBytes() { public void testDWtwoBytes() { Program program = new Program(); program - .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0, 0xFFFF))); + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 0xFFFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -82,9 +82,9 @@ public void testDWtwoBytes() { public void testDWthreeBytes() { Program program = new Program(); program - .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0, 0xFFFF)) - .addChild(new Evaluated(0, 0, 0x10000))); + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 0xFFFF)) + .addChild(new Evaluated(0, 0, 0x10000))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -96,8 +96,8 @@ public void testDWthreeBytes() { public void testDStwoBytes() { Program program = new Program(); program - .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0, 0, 0xFFFF))); + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 0xFFFF))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -109,8 +109,8 @@ public void testDStwoBytes() { public void testDSthreeBytes() { Program program = new Program(); program - .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0, 0, 0x10000))); + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 0x10000))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -122,8 +122,8 @@ public void testDSthreeBytes() { public void testInstrExprTwoBytes() { Program program = new Program(); program - .addChild(new Instr(0, 0, OPCODE_ADD, 3, 0, 6).setSizeBytes(2) - .addChild(new Evaluated(0, 0, 0xFF00).setSizeBytes(1))); + .addChild(new Instr(0, 0, OPCODE_ADD, 3, 0, 6).setSizeBytes(2) + .addChild(new Evaluated(0, 0, 0xFF00).setSizeBytes(1))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -135,8 +135,8 @@ public void testInstrExprTwoBytes() { public void testInstrExprThreeBytes() { Program program = new Program(); program - .addChild(new Instr(0, 0, OPCODE_JP, 3, 0, 3).setSizeBytes(3) - .addChild(new Evaluated(0, 0, 0xFF000).setSizeBytes(2))); + .addChild(new Instr(0, 0, OPCODE_JP, 3, 0, 3).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0xFF000).setSizeBytes(2))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -148,8 +148,8 @@ public void testInstrExprThreeBytes() { public void testInstrRegExprOneByte() { Program program = new Program(); program - .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6).setSizeBytes(2) - .addChild(new Evaluated(0, 0, 0xFF).setSizeBytes(1))); + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6).setSizeBytes(2) + .addChild(new Evaluated(0, 0, 0xFF).setSizeBytes(1))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -161,8 +161,8 @@ public void testInstrRegExprOneByte() { public void testInstrRegExprTwoBytes() { Program program = new Program(); program - .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6).setSizeBytes(2) - .addChild(new Evaluated(0, 0, 0x100).setSizeBytes(1))); // bad size + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6).setSizeBytes(2) + .addChild(new Evaluated(0, 0, 0x100).setSizeBytes(1))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -174,8 +174,8 @@ public void testInstrRegExprTwoBytes() { public void testInstrRegPairExprTwoBytes() { Program program = new Program(); program - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) - .addChild(new Evaluated(0, 0, 0xFFFF).setSizeBytes(2))); + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0xFFFF).setSizeBytes(2))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -187,8 +187,8 @@ public void testInstrRegPairExprTwoBytes() { public void testInstrRegPairExprThreeBytes() { Program program = new Program(); program - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) - .addChild(new Evaluated(0, 0, 0x10000).setSizeBytes(2))); // bad size + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0x10000).setSizeBytes(2))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -200,8 +200,8 @@ public void testInstrRegPairExprThreeBytes() { public void testPseudoOrgTwoBytes() { Program program = new Program(); program - .addChild(new PseudoOrg(0, 0).setSizeBytes(2) - .addChild(new Evaluated(0, 0, 0xFFFF).setSizeBytes(2))); + .addChild(new PseudoOrg(0, 0).setSizeBytes(2) + .addChild(new Evaluated(0, 0, 0xFFFF).setSizeBytes(2))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -213,8 +213,8 @@ public void testPseudoOrgTwoBytes() { public void testPseudoOrgThreeBytes() { Program program = new Program(); program - .addChild(new PseudoOrg(0, 0).setSizeBytes(2) - .addChild(new Evaluated(0, 0, 0x10000).setSizeBytes(2))); // bad size + .addChild(new PseudoOrg(0, 0).setSizeBytes(2) + .addChild(new Evaluated(0, 0, 0x10000).setSizeBytes(2))); // bad size CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); @@ -226,35 +226,35 @@ public void testPseudoOrgThreeBytes() { public void testMacroArgumentsAreRemoved() { Program program = new Program(); program - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) - .addChild(new Evaluated(0, 0, 0).setSizeBytes(2))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) - .addChild(new Evaluated(0, 0, 1).setSizeBytes(2)))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) - .addChild(new Evaluated(0, 0, 0).setSizeBytes(2)))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0).setSizeBytes(2))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 1).setSizeBytes(2)))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0).setSizeBytes(2)))); CheckExprSizesVisitor visitor = new CheckExprSizesVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) - .addChild(new Evaluated(0, 0, 0).setSizeBytes(2))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) - .addChild(new Evaluated(0, 0, 1).setSizeBytes(2)))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) - .addChild(new Evaluated(0, 0, 0).setSizeBytes(2)))), - program + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0).setSizeBytes(2))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 1).setSizeBytes(2)))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1).setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0).setSizeBytes(2)))), + program ); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java index 5cc3266e6..5b4ad9658 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/EvaluateExprVisitorTest.java @@ -46,30 +46,30 @@ public class EvaluateExprVisitorTest { public void testEvaluateDB() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 1)) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new ExprNumber(0, 0, 'h')) - .addChild(new ExprNumber(0, 0, 'e')) - .addChild(new ExprNumber(0, 0, 'l')) - .addChild(new ExprNumber(0, 0, 'l')) - .addChild(new ExprNumber(0, 0, 'o')) - ); + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new ExprNumber(0, 0, 'h')) + .addChild(new ExprNumber(0, 0, 'e')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'l')) + .addChild(new ExprNumber(0, 0, 'o')) + ); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 3)) - .addChild(new Evaluated(0, 0, 'h')) - .addChild(new Evaluated(0, 0, 'e')) - .addChild(new Evaluated(0, 0, 'l')) - .addChild(new Evaluated(0, 0, 'l')) - .addChild(new Evaluated(0, 0, 'o'))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 3)) + .addChild(new Evaluated(0, 0, 'h')) + .addChild(new Evaluated(0, 0, 'e')) + .addChild(new Evaluated(0, 0, 'l')) + .addChild(new Evaluated(0, 0, 'l')) + .addChild(new Evaluated(0, 0, 'o'))), + program ); } @@ -77,23 +77,23 @@ public void testEvaluateDB() { public void testEvaluateDW() { Program program = new Program(); program - .addChild(new DataDW(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 1)) - .addChild(new ExprNumber(0, 0, 2)))) - .addChild(new DataDW(0, 0) - .addChild(new ExprNumber(0, 0, 0))); + .addChild(new DataDW(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new DataDW(0, 0) + .addChild(new ExprNumber(0, 0, 0))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0, 3))) - .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0, 0))), - program + new Program() + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 3))) + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 0))), + program ); assertEquals(0, program.getChild(0).getAddress()); assertEquals(2, program.getChild(1).getAddress()); @@ -103,23 +103,23 @@ public void testEvaluateDW() { public void testEvaluateDS() { Program program = new Program(); program - .addChild(new DataDS(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprNumber(0, 0, 1)) - .addChild(new ExprNumber(0, 0, 2)))) - .addChild(new DataDB(0, 0) - .addChild(new ExprNumber(0, 0, 0))); + .addChild(new DataDS(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprNumber(0, 0, 1)) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new DataDB(0, 0) + .addChild(new ExprNumber(0, 0, 0))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0, 0, 3))) - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 0))), - program + new Program() + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 3))) + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 0))), + program ); assertEquals(0, program.getChild(0).getAddress()); assertEquals(3, program.getChild(1).getAddress()); @@ -129,9 +129,9 @@ public void testEvaluateDS() { public void testEvaluateDSambiguous() { Program program = new Program(); program - .addChild(new DataDS(0, 0) - .addChild(new ExprId(0, 0, "label"))) - .addChild(new PseudoLabel(0, 0, "label")); + .addChild(new DataDS(0, 0) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new PseudoLabel(0, 0, "label")); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -143,10 +143,10 @@ public void testEvaluateDSambiguous() { public void testEvaluateDSconstReference() { Program program = new Program(); program - .addChild(new DataDS(0, 0) - .addChild(new ExprId(0, 0, "label"))) - .addChild(new PseudoEqu(0, 0, "label") - .addChild(new ExprNumber(0, 0, 5))); + .addChild(new DataDS(0, 0) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new PseudoEqu(0, 0, "label") + .addChild(new ExprNumber(0, 0, 5))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -158,10 +158,10 @@ public void testEvaluateDSconstReference() { assertEquals(0, label.get().getAddress()); assertTrees( - new Program() - .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0, 0, 5))), - program + new Program() + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 5))), + program ); } @@ -169,16 +169,16 @@ public void testEvaluateDSconstReference() { public void testEvaluateEQUfivePasses() { Program program = new Program(); program - .addChild(new PseudoEqu(0, 0, "one") - .addChild(new ExprId(0, 0, "two"))) - .addChild(new PseudoEqu(0, 0, "two") - .addChild(new ExprId(0, 0, "three"))) - .addChild(new PseudoEqu(0, 0, "three") - .addChild(new ExprId(0, 0, "four"))) - .addChild(new PseudoEqu(0, 0, "four") - .addChild(new ExprId(0, 0, "five"))) - .addChild(new PseudoEqu(0, 0, "five") - .addChild(new ExprCurrentAddress(0, 0))); + .addChild(new PseudoEqu(0, 0, "one") + .addChild(new ExprId(0, 0, "two"))) + .addChild(new PseudoEqu(0, 0, "two") + .addChild(new ExprId(0, 0, "three"))) + .addChild(new PseudoEqu(0, 0, "three") + .addChild(new ExprId(0, 0, "four"))) + .addChild(new PseudoEqu(0, 0, "four") + .addChild(new ExprId(0, 0, "five"))) + .addChild(new PseudoEqu(0, 0, "five") + .addChild(new ExprCurrentAddress(0, 0))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -199,32 +199,32 @@ public void testEvaluateEQUfivePasses() { public void testEvaluateIFwithForwardConst() { Program program = new Program(); program - .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) - .setSizeBytes(2) - .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoIf(0, 0) - .addChild(new PseudoIfExpression(0, 0) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprNumber(0, 0, 2)))) - .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) - .setSizeBytes(1) - .addChild(new ExprNumber(0, 0, 0)))) - .addChild(new PseudoEqu(0, 0, "const") - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprCurrentAddress(0, 0)))); + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) + .setSizeBytes(2) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprNumber(0, 0, 2)))) + .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) + .setSizeBytes(1) + .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprCurrentAddress(0, 0)))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) - .addChild(new Evaluated(0, 0, 6))) - .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) - .addChild(new Evaluated(0, 0, 0))), - program + new Program() + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) + .addChild(new Evaluated(0, 0, 6))) + .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) + .addChild(new Evaluated(0, 0, 0))), + program ); assertEquals(0, program.getChild(0).getAddress()); assertEquals(2, program.getChild(1).getAddress()); @@ -234,17 +234,17 @@ public void testEvaluateIFwithForwardConst() { public void testEvaluateIFwithForwardAddressReference() { Program program = new Program(); program - .addChild(new PseudoIf(0, 0) - .addChild(new PseudoIfExpression(0, 0) - .addChild(new ExprInfix(0, 0, OP_EQUAL) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprId(0, 0, "const")))) - .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) - .addChild(new ExprNumber(0, 0, 0)))) - .addChild(new PseudoEqu(0, 0, "const") - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprCurrentAddress(0, 0)))); + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprInfix(0, 0, OP_EQUAL) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "const")))) + .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) + .addChild(new ExprNumber(0, 0, 0)))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprCurrentAddress(0, 0)))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -256,11 +256,11 @@ public void testEvaluateIFwithForwardAddressReference() { public void testEvaluateIFexcludeBlock() { Program program = new Program(); program - .addChild(new PseudoIf(0, 0) - .addChild(new PseudoIfExpression(0, 0) - .addChild(new ExprNumber(0, 0, 0))) - .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) - .addChild(new ExprNumber(0, 0, 0)))); + .addChild(new PseudoIf(0, 0) + .addChild(new PseudoIfExpression(0, 0) + .addChild(new ExprNumber(0, 0, 0))) + .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) + .addChild(new ExprNumber(0, 0, 0)))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -272,29 +272,29 @@ public void testEvaluateIFexcludeBlock() { public void testEvaluateSETforwardTwoTimes() { Program program = new Program(); program - .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) - .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoVar(0, 0, "const") - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 6) - .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoVar(0, 0, "const") - .addChild(new ExprNumber(0, 0, 2))); + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoVar(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 6) + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoVar(0, 0, "const") + .addChild(new ExprNumber(0, 0, 2))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoVar(0, 0, "const") - .addChild(new Evaluated(0, 0, 1))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 6) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoVar(0, 0, "const") - .addChild(new Evaluated(0, 0, 2))), - program + new Program() + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoVar(0, 0, "const") + .addChild(new Evaluated(0, 0, 1))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 6) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoVar(0, 0, "const") + .addChild(new Evaluated(0, 0, 2))), + program ); } @@ -302,27 +302,27 @@ public void testEvaluateSETforwardTwoTimes() { public void testEvaluateSETforwardMoreTimes() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new ExprId(0, 0, "id"))) - .addChild(new PseudoVar(0, 0, "id") - .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoVar(0, 0, "id") - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoEqu(0, 0, "const") - .addChild(new ExprNumber(0, 0, 1))); + .addChild(new DataDB(0, 0) + .addChild(new ExprId(0, 0, "id"))) + .addChild(new PseudoVar(0, 0, "id") + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoVar(0, 0, "id") + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoVar(0, 0, "id") - .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoVar(0, 0, "id") - .addChild(new Evaluated(0, 0, 2))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoVar(0, 0, "id") + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoVar(0, 0, "id") + .addChild(new Evaluated(0, 0, 2))), + program ); } @@ -330,27 +330,27 @@ public void testEvaluateSETforwardMoreTimes() { public void testTwoSETthenReference() { Program program = new Program(); program - .addChild(new PseudoVar(0, 0, "id") - .addChild(new ExprId(0, 0, "const"))) - .addChild(new PseudoVar(0, 0, "id") - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoEqu(0, 0, "const") - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new DataDB(0, 0) - .addChild(new ExprId(0, 0, "id"))); + .addChild(new PseudoVar(0, 0, "id") + .addChild(new ExprId(0, 0, "const"))) + .addChild(new PseudoVar(0, 0, "id") + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoEqu(0, 0, "const") + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new DataDB(0, 0) + .addChild(new ExprId(0, 0, "id"))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new PseudoVar(0, 0, "id") - .addChild(new Evaluated(0, 0, 1))) - .addChild(new PseudoVar(0, 0, "id") - .addChild(new Evaluated(0, 0, 2))) - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 2))), - program + new Program() + .addChild(new PseudoVar(0, 0, "id") + .addChild(new Evaluated(0, 0, 1))) + .addChild(new PseudoVar(0, 0, "id") + .addChild(new Evaluated(0, 0, 2))) + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 2))), + program ); } @@ -358,28 +358,28 @@ public void testTwoSETthenReference() { public void testEvaluateLABEL() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprId(0, 0, "label"))) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprId(0, 0, "label"))) - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprCurrentAddress(0, 0)) - .addChild(new ExprId(0, 0, "label")))) - .addChild(new PseudoLabel(0, 0, "label")); + .addChild(new DataDB(0, 0) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprCurrentAddress(0, 0)) + .addChild(new ExprId(0, 0, "label")))) + .addChild(new PseudoLabel(0, 0, "label")); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 3)) - .addChild(new Evaluated(0, 0, 4)) - .addChild(new Evaluated(0, 0, 5))), - program + new Program() + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 3)) + .addChild(new Evaluated(0, 0, 4)) + .addChild(new Evaluated(0, 0, 5))), + program ); } @@ -387,26 +387,26 @@ public void testEvaluateLABEL() { public void testEvaluateMacroCalls() { Program program = new Program(); program - .addChild(new PseudoLabel(0, 0, "label")) - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "addr")) - .addChild(new ExprId(0, 0, "label"))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .addChild(new ExprId(0, 0, "addr")))); + .addChild(new PseudoLabel(0, 0, "label")) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "addr")) + .addChild(new ExprId(0, 0, "label"))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) + .addChild(new ExprId(0, 0, "addr")))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "addr")) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .addChild(new Evaluated(0, 0, 0)))), - program + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "addr")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) + .addChild(new Evaluated(0, 0, 0)))), + program ); } @@ -414,13 +414,13 @@ public void testEvaluateMacroCalls() { public void testEvaluateMacroCallAmbiguous() { Program program = new Program(); program - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "label")) - .addChild(new ExprId(0, 0, "addr"))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .addChild(new ExprId(0, 0, "addr")))) - .addChild(new PseudoLabel(0, 0, "label")); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "label")) + .addChild(new ExprId(0, 0, "addr"))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) + .addChild(new ExprId(0, 0, "addr")))) + .addChild(new PseudoLabel(0, 0, "label")); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); @@ -432,41 +432,41 @@ public void testEvaluateMacroCallAmbiguous() { public void testEvaluateMacroScopedArguments() { Program program = new Program(); program - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new ExprNumber(0, 0, 0))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .addChild(new ExprId(0, 0, "arg"))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .addChild(new ExprId(0, 0, "arg")))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .addChild(new ExprId(0, 0, "arg")))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new ExprNumber(0, 0, 0))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) + .addChild(new ExprId(0, 0, "arg"))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) + .addChild(new ExprId(0, 0, "arg")))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) + .addChild(new ExprId(0, 0, "arg")))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "arg")) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .addChild(new Evaluated(0, 0, 1)))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .addChild(new Evaluated(0, 0, 0)))), - program + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "arg")) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) + .addChild(new Evaluated(0, 0, 1)))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) + .addChild(new Evaluated(0, 0, 0)))), + program ); } @@ -474,15 +474,15 @@ public void testEvaluateMacroScopedArguments() { public void testLabelKeepsChildren() { Program program = new Program(); program - .addChild(new PseudoLabel(0, 0, "label") - .addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1))); + .addChild(new PseudoLabel(0, 0, "label") + .addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1))); EvaluateExprVisitor visitor = new EvaluateExprVisitor(); visitor.visit(program); assertTrees( - new Program().addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1)), - program + new Program().addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1)), + program ); } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java index 23de5dfdc..40b6df252 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandIncludesVisitorTest.java @@ -18,11 +18,11 @@ */ package net.emustudio.plugins.compiler.asZ80.visitors; -import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoLabel; import net.emustudio.plugins.compiler.asZ80.ast.Node; import net.emustudio.plugins.compiler.asZ80.ast.Program; import net.emustudio.plugins.compiler.asZ80.ast.expr.ExprNumber; import net.emustudio.plugins.compiler.asZ80.ast.instr.Instr; +import net.emustudio.plugins.compiler.asZ80.ast.pseudo.PseudoLabel; import net.emustudio.plugins.compiler.asZ80.exceptions.FatalError; import org.junit.Rule; import org.junit.Test; @@ -48,11 +48,11 @@ public void testExpandInclude() { visitor.visit(program); Node expected = new Program() - .addChild(new Instr(0, 0, OPCODE_CCF, 0, 7, 7)) - .addChild(new PseudoLabel(0, 0, "sample")) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) - .addChild(new ExprNumber(0, 0, 0))) - .addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1)); + .addChild(new Instr(0, 0, OPCODE_CCF, 0, 7, 7)) + .addChild(new PseudoLabel(0, 0, "sample")) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) + .addChild(new ExprNumber(0, 0, 0))) + .addChild(new Instr(0, 0, OPCODE_RET, 3, 1, 1)); assertTrees(expected, program); } @@ -63,15 +63,15 @@ public void testExpandIncludeTwoTimes() throws IOException { write(file, "rrca"); Program program = parseProgram( - "include '" + file.getPath() + "'\n" + - "include '" + file.getPath() + "'" + "include '" + file.getPath() + "'\n" + + "include '" + file.getPath() + "'" ); ExpandIncludesVisitor visitor = new ExpandIncludesVisitor(); visitor.visit(program); Node expected = new Program() - .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)) - .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)); + .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)) + .addChild(new Instr(0, 0, OPCODE_RRCA, 0, 1, 7)); assertTrees(expected, program); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java index 66c82d9bd..6e3a4e786 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/ExpandMacrosTest.java @@ -48,9 +48,9 @@ public void testMacroDefinitionThenMacroCall() { macrosVisitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroDef(0, 0, "x"))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program ); } @@ -61,9 +61,9 @@ public void testMacroCallThenMacroDefinition() { macrosVisitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroDef(0, 0, "x"))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program ); } @@ -74,11 +74,11 @@ public void testMacroCallThenMacroDefinitionThenMacroCall() { macrosVisitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroDef(0, 0, "x"))) - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroDef(0, 0, "x"))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program ); } @@ -94,9 +94,9 @@ public void testMacroCallThenMacroDefinitionInsideInclude() throws IOException { macrosVisitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroDef(0, 0, "x"))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroDef(0, 0, "x"))), + program ); } @@ -121,21 +121,21 @@ public void testMacroCallWithArguments() { macrosVisitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "u"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "v"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "w"))))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "u"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "v"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "w"))))), + program ); } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java index e732f7b14..8977df411 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitorTest.java @@ -40,25 +40,25 @@ public class GenerateCodeVisitorTest { public void testCodeGeneration() { Program program = new Program(); program - .addChild(new DataDB(0, 0) - .addChild(new Evaluated(0, 0, 255)) - .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) - .addChild(new Evaluated(0, 0, 4)))) - .addChild(new DataDW(0, 0) - .addChild(new Evaluated(0, 0, 1))) - .addChild(new DataDS(0, 0) - .addChild(new Evaluated(0, 0, 5))) - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) - .setSizeBytes(3) - .addChild(new Evaluated(0, 0, 0xFEAB).setSizeBytes(2))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new Instr(0, 0, OPCODE_LD, 0, 2, 1) - .setSizeBytes(3) - .addChild(new Evaluated(0, 0, 1).setSizeBytes(2)))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 4, 1) - .setSizeBytes(3) - .addChild(new Evaluated(0, 0, 0x1234).setSizeBytes(2)))); + .addChild(new DataDB(0, 0) + .addChild(new Evaluated(0, 0, 255)) + .addChild(new Instr(0, 0, OPCODE_RST, 3, 0, 7) + .addChild(new Evaluated(0, 0, 4)))) + .addChild(new DataDW(0, 0) + .addChild(new Evaluated(0, 0, 1))) + .addChild(new DataDS(0, 0) + .addChild(new Evaluated(0, 0, 5))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new Instr(0, 0, OPCODE_LD, 0, 0, 1) + .setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0xFEAB).setSizeBytes(2))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new Instr(0, 0, OPCODE_LD, 0, 2, 1) + .setSizeBytes(3) + .addChild(new Evaluated(0, 0, 1).setSizeBytes(2)))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 4, 1) + .setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0x1234).setSizeBytes(2)))); IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); @@ -89,14 +89,14 @@ public void testCodeGeneration() { public void testPseudoOrg() { Program program = new Program(); program - .addChild(new PseudoOrg(0, 0) - .addChild(new Evaluated(0, 0, 5))) - .addChild(new Instr(0, 0, OPCODE_CALL, 3, 0, 4) - .setSizeBytes(3) - .addChild(new Evaluated(0, 0, 0x400).setSizeBytes(2))) - .addChild(new PseudoOrg(0, 0) - .addChild(new Evaluated(0, 0, 0))) - .addChild(new Instr(0, 0, OPCODE_EX, 3, 5, 3)); + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0, 0, 5))) + .addChild(new Instr(0, 0, OPCODE_CALL, 3, 0, 4) + .setSizeBytes(3) + .addChild(new Evaluated(0, 0, 0x400).setSizeBytes(2))) + .addChild(new PseudoOrg(0, 0) + .addChild(new Evaluated(0, 0, 0))) + .addChild(new Instr(0, 0, OPCODE_EX, 3, 5, 3)); IntelHEX hex = new IntelHEX(); GenerateCodeVisitor visitor = new GenerateCodeVisitor(hex); diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java index f6c53d34e..1b09c8b31 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/visitors/SortMacroArgumentsVisitorTest.java @@ -27,7 +27,8 @@ import net.emustudio.plugins.compiler.asZ80.ast.pseudo.*; import org.junit.Test; -import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.*; +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.OPCODE_LD; +import static net.emustudio.plugins.compiler.asZ80.AsZ80Parser.OP_ADD; import static net.emustudio.plugins.compiler.asZ80.CompileError.ERROR_MACRO_ARGUMENTS_DO_NOT_MATCH; import static net.emustudio.plugins.compiler.asZ80.Utils.assertTrees; import static org.junit.Assert.assertTrue; @@ -37,113 +38,113 @@ public class SortMacroArgumentsVisitorTest { @Test public void testMacroArgumentsAreConnectedWithIds() { Node program = new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "r"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "t"))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoEqu(0, 0, "uu") - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprId(0, 0, "r")) - .addChild(new ExprId(0, 0, "t")))))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "r"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "t"))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoEqu(0, 0, "uu") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprId(0, 0, "t")))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); visitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "q")) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "r")) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "t")) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoEqu(0, 0, "uu") - .addChild(new ExprInfix(0, 0, OP_ADD) - .addChild(new ExprId(0, 0, "r")) - .addChild(new ExprId(0, 0, "t"))))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "t")) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new Instr(0, 0, OPCODE_LD, 0, 7, 6) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoEqu(0, 0, "uu") + .addChild(new ExprInfix(0, 0, OP_ADD) + .addChild(new ExprId(0, 0, "r")) + .addChild(new ExprId(0, 0, "t"))))), + program ); } @Test public void testMultipleMacroCalls() { Node program = new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))))) - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); visitor.visit(program); assertTrees(new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "q")) - .addChild(new ExprNumber(0, 0, 1)))) - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "q")) - .addChild(new ExprNumber(0, 0, 2)))), - program + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1)))) + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 2)))), + program ); } @Test public void testNestedMacroCallWithSameNamedArgs() { Node program = new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroCall(0, 0, "x") .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 3))) - .addChild(new PseudoMacroDef(0, 0, "y") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))))))); + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 3))) + .addChild(new PseudoMacroDef(0, 0, "y") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); visitor.visit(program); assertTrees( - new Program() - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "q")) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroCall(0, 0, "y") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprId(0, 0, "q")) - .addChild(new ExprNumber(0, 0, 3))))), - program + new Program() + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroCall(0, 0, "y") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprId(0, 0, "q")) + .addChild(new ExprNumber(0, 0, 3))))), + program ); } @@ -151,14 +152,14 @@ public void testNestedMacroCallWithSameNamedArgs() { public void testMoreMacroArgumentsThanParameters() { Program program = new Program(); program - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 2))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 2))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); visitor.visit(program); @@ -170,14 +171,14 @@ public void testMoreMacroArgumentsThanParameters() { public void testMoreMacroParametersThanArguments() { Program program = new Program(); program - .addChild(new PseudoMacroCall(0, 0, "x") - .addChild(new PseudoMacroArgument(0, 0) - .addChild(new ExprNumber(0, 0, 1))) - .addChild(new PseudoMacroDef(0, 0, "x") - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "q"))) - .addChild(new PseudoMacroParameter(0, 0) - .addChild(new ExprId(0, 0, "r"))))); + .addChild(new PseudoMacroCall(0, 0, "x") + .addChild(new PseudoMacroArgument(0, 0) + .addChild(new ExprNumber(0, 0, 1))) + .addChild(new PseudoMacroDef(0, 0, "x") + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "q"))) + .addChild(new PseudoMacroParameter(0, 0) + .addChild(new ExprId(0, 0, "r"))))); SortMacroArgumentsVisitor visitor = new SortMacroArgumentsVisitor(); visitor.visit(program); diff --git a/plugins/compiler/brainc-brainduck/README.md b/plugins/compiler/brainc-brainduck/README.md index d8d06f2ec..e2559220b 100644 --- a/plugins/compiler/brainc-brainduck/README.md +++ b/plugins/compiler/brainc-brainduck/README.md @@ -3,4 +3,5 @@ This project is compiler of a [brainfuck](http://en.wikipedia.org/wiki/Brainfuck) language. It is part of [emuStudio](https://www.emustudio.net/). -The official documentation can be found [here](https://www.emustudio.net/docuser/brainduck/index/#compiler-code-brainc-brainduck-code) +The official documentation can be +found [here](https://www.emustudio.net/docuser/brainduck/index/#compiler-code-brainc-brainduck-code) diff --git a/plugins/compiler/brainc-brainduck/build.gradle b/plugins/compiler/brainc-brainduck/build.gradle index 921ac38f8..de230ba57 100644 --- a/plugins/compiler/brainc-brainduck/build.gradle +++ b/plugins/compiler/brainc-brainduck/build.gradle @@ -53,7 +53,7 @@ sourceSets { } main { java.srcDirs = [ - 'src/main/java', "${buildDir}/generated-src/antlr/main" + 'src/main/java', "${buildDir}/generated-src/antlr/main" ] } } @@ -75,8 +75,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerImpl.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerImpl.java index 68e7c7b09..34a07d697 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerImpl.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerImpl.java @@ -27,8 +27,8 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextNotFoundException; import net.emustudio.emulib.runtime.InvalidContextException; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.io.IntelHEX; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.compiler.brainduck.ast.Program; import net.emustudio.plugins.compiler.brainduck.ast.ProgramParser; import org.antlr.v4.runtime.CharStream; diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java index 74246ba1a..d554e0c6c 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/LexicalAnalyzerImpl.java @@ -29,8 +29,8 @@ import static net.emustudio.plugins.compiler.brainduck.BraincLexer.*; public class LexicalAnalyzerImpl implements LexicalAnalyzer { - private final BraincLexer lexer; public static final int[] tokenMap = new int[COMMENT + 1]; + static { tokenMap[COMMENT] = Token.COMMENT; tokenMap[WS] = Token.WHITESPACE; @@ -45,6 +45,8 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[ENDL] = Token.RESERVED; } + private final BraincLexer lexer; + public LexicalAnalyzerImpl(BraincLexer lexer) { this.lexer = Objects.requireNonNull(lexer); } diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ParserErrorListener.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ParserErrorListener.java index cc932ceb7..cd8559671 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ParserErrorListener.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ParserErrorListener.java @@ -25,12 +25,12 @@ class ParserErrorListener extends BaseErrorListener { @Override public void syntaxError( - Recognizer recognizer, - Object offendingSymbol, - int line, - int charPositionInLine, - String msg, - RecognitionException e) { + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { throw new CompileException(line, charPositionInLine, msg); } } diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/Instruction.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/Instruction.java index ec2cdd4c2..3fdcb403b 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/Instruction.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/ast/Instruction.java @@ -29,15 +29,15 @@ public class Instruction { public Instruction(int tokenType) { Map tokenCodes = Map.of( - BraincParser.HALT, 0, - BraincParser.INC, 1, - BraincParser.DEC, 2, - BraincParser.INCV, 3, - BraincParser.DECV, 4, - BraincParser.PRINT, 5, - BraincParser.LOAD, 6, - BraincParser.LOOP, 7, - BraincParser.ENDL, 8 + BraincParser.HALT, 0, + BraincParser.INC, 1, + BraincParser.DEC, 2, + BraincParser.INCV, 3, + BraincParser.DECV, 4, + BraincParser.PRINT, 5, + BraincParser.LOAD, 6, + BraincParser.LOOP, 7, + BraincParser.ENDL, 8 ); this.instructionCode = tokenCodes.get(tokenType); } diff --git a/plugins/compiler/brainc-brainduck/src/main/resources/net/emustudio/plugins/compiler/brainduck/version.properties b/plugins/compiler/brainc-brainduck/src/main/resources/net/emustudio/plugins/compiler/brainduck/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/compiler/brainc-brainduck/src/main/resources/net/emustudio/plugins/compiler/brainduck/version.properties +++ b/plugins/compiler/brainc-brainduck/src/main/resources/net/emustudio/plugins/compiler/brainduck/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/AbstractCompilerTest.java b/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/AbstractCompilerTest.java index be8d46252..10b90a584 100644 --- a/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/AbstractCompilerTest.java +++ b/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/AbstractCompilerTest.java @@ -25,8 +25,8 @@ import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.Before; import org.junit.Rule; import org.junit.rules.TemporaryFolder; @@ -39,11 +39,10 @@ import static org.junit.Assert.assertEquals; public abstract class AbstractCompilerTest { - protected CompilerImpl compiler; - protected MemoryStub memoryStub; - @Rule public TemporaryFolder folder = new TemporaryFolder(); + protected CompilerImpl compiler; + protected MemoryStub memoryStub; @SuppressWarnings("unchecked") @Before @@ -89,14 +88,14 @@ protected void compile(String content) throws Exception { void assertProgram(int... bytes) { for (int i = 0; i < bytes.length; i++) { assertEquals( - String.format("%d. expected=%x, but was=%x", i, bytes[i], memoryStub.read(i)), - bytes[i], (int) memoryStub.read(i) + String.format("%d. expected=%x, but was=%x", i, bytes[i], memoryStub.read(i)), + bytes[i], (int) memoryStub.read(i) ); } for (int i = bytes.length; i < memoryStub.getSize(); i++) { assertEquals( - String.format("%d. expected=%x, but was=%x", i, 0, memoryStub.read(i)), - 0, (int) memoryStub.read(i) + String.format("%d. expected=%x, but was=%x", i, 0, memoryStub.read(i)), + 0, (int) memoryStub.read(i) ); } } diff --git a/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/InstructionTest.java b/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/InstructionTest.java index 163ae4b7f..9f384f13d 100644 --- a/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/InstructionTest.java +++ b/plugins/compiler/brainc-brainduck/src/test/java/net/emustudio/plugins/compiler/brainduck/InstructionTest.java @@ -42,38 +42,38 @@ public void testCopyrightIsKnown() { @Test public void testCompile() throws Exception { compile( - ";><+-.,[]" + ";><+-.,[]" ); assertProgram( - 0, 1, 2, 3, 4, 5, 6, 7, 8 + 0, 1, 2, 3, 4, 5, 6, 7, 8 ); } @Test public void testCompileProgramWithComments() throws Exception { compile( - "Code: Pseudo code:\n" + - ">> Move the pointer to cell2\n" + - "[-] Set cell2 to 0 \n" + - "<< Move the pointer back to cell0\n" + - "[ While cell0 is not 0\n" + - " - Subtract 1 from cell0\n" + - " >> Move the pointer to cell2\n" + - " + Add 1 to cell2\n" + - " << Move the pointer back to cell0\n" + - "] End while" + "Code: Pseudo code:\n" + + ">> Move the pointer to cell2\n" + + "[-] Set cell2 to 0 \n" + + "<< Move the pointer back to cell0\n" + + "[ While cell0 is not 0\n" + + " - Subtract 1 from cell0\n" + + " >> Move the pointer to cell2\n" + + " + Add 1 to cell2\n" + + " << Move the pointer back to cell0\n" + + "] End while" ); assertProgram( - 1, 1, 7, 4, 8, 2, 2, 7, 4, 1, 1, 3, 2, 2, 8 + 1, 1, 7, 4, 8, 2, 2, 7, 4, 1, 1, 3, 2, 2, 8 ); } @Test public void testProgramAfterCommentWorks() throws Exception { compile( - "So this is the comment and program >>\n" + "So this is the comment and program >>\n" ); assertProgram(1, 1); } @@ -94,7 +94,7 @@ public void testNullProgramDoesNotChangeMemory() throws Exception { new CompilerImpl(0L, applicationApi, PluginSettings.UNAVAILABLE).compile("nonexistant"); assertProgram( - 1, 1 + 1, 1 ); } } diff --git a/plugins/compiler/ramc-ram/build.gradle b/plugins/compiler/ramc-ram/build.gradle index bd0c282c7..1b181946a 100644 --- a/plugins/compiler/ramc-ram/build.gradle +++ b/plugins/compiler/ramc-ram/build.gradle @@ -51,7 +51,7 @@ sourceSets { } main { java.srcDirs = [ - 'src/main/java', "${buildDir}/generated-src/antlr/main" + 'src/main/java', "${buildDir}/generated-src/antlr/main" ] } } @@ -73,8 +73,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java index de79be9db..72506a3e3 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java @@ -23,7 +23,9 @@ import net.emustudio.emulib.plugins.compiler.AbstractCompiler; import net.emustudio.emulib.plugins.compiler.LexicalAnalyzer; import net.emustudio.emulib.plugins.compiler.SourceFileExtension; -import net.emustudio.emulib.runtime.*; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.ContextNotFoundException; +import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.compiler.ram.ast.Program; import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java index f65df3c0f..06392ff02 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/LexicalAnalyzerImpl.java @@ -30,7 +30,6 @@ import static org.antlr.v4.runtime.Recognizer.EOF; public class LexicalAnalyzerImpl implements LexicalAnalyzer { - private final RAMLexer lexer; public static final int[] tokenMap = new int[ERROR + 1]; static { @@ -70,6 +69,8 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[ERROR] = Token.ERROR; } + private final RAMLexer lexer; + public LexicalAnalyzerImpl(RAMLexer lexer) { this.lexer = Objects.requireNonNull(lexer); diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParserErrorListener.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParserErrorListener.java index 8cd330571..82178be20 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParserErrorListener.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ParserErrorListener.java @@ -27,12 +27,12 @@ public class ParserErrorListener extends BaseErrorListener { @Override public void syntaxError( - Recognizer recognizer, - Object offendingSymbol, - int line, - int charPositionInLine, - String msg, - RecognitionException e) { + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { if (e == null) { throw new SyntaxErrorException(line, charPositionInLine, msg); diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ProgramParser.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ProgramParser.java index 6576f18bb..e8cf7e80c 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ProgramParser.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ProgramParser.java @@ -97,7 +97,7 @@ public Program visitRInstruction(RAMParser.RInstructionContext ctx) { } Instruction instruction = new Instruction( - op.getLine(), op.getCharPositionInLine(), opcode, direction, currentAddress++, Optional.ofNullable(operand) + op.getLine(), op.getCharPositionInLine(), opcode, direction, currentAddress++, Optional.ofNullable(operand) ); program.add(instruction); return program; diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/SerializableOptional.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/SerializableOptional.java index c19b2ca56..ff83c83b0 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/SerializableOptional.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/SerializableOptional.java @@ -29,10 +29,6 @@ public SerializableOptional(T value) { this.value = value; } - public Optional opt() { - return Optional.ofNullable(value); - } - public static SerializableOptional empty() { return new SerializableOptional<>(null); } @@ -45,6 +41,10 @@ public static SerializableOptional fromOpt(Optional valueOpt) { return new SerializableOptional<>(valueOpt.orElse(null)); } + public Optional opt() { + return Optional.ofNullable(value); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java index 92075da53..09ec190e7 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java @@ -113,11 +113,11 @@ public int hashCode() { @Override public String toString() { return "Instruction{" + - "address=" + address + - ", opcode=" + opcode + - ", direction=" + direction + - ", operand=" + operand + - ", label=" + label + - '}'; + "address=" + address + + ", opcode=" + opcode + + ", direction=" + direction + + ", operand=" + operand + + ", label=" + label + + '}'; } } diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java index 08775ed33..9cb8de535 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java @@ -65,8 +65,8 @@ public int hashCode() { @Override public String toString() { return "{" + - "label='" + label + '\'' + - ", address=" + address + - '}'; + "label='" + label + '\'' + + ", address=" + address + + '}'; } } diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java index 08aac8ed1..57cfce861 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java @@ -51,11 +51,11 @@ public void add(Value input) { public void assignLabels() { for (Instruction instruction : instructions) { instruction - .getOperand() - .filter(v -> v.getType() == RAMValue.Type.ID) - .map(RAMValue::getStringValue) - .flatMap(this::getLabel) - .ifPresent(instruction::setLabel); + .getOperand() + .filter(v -> v.getType() == RAMValue.Type.ID) + .map(RAMValue::getStringValue) + .flatMap(this::getLabel) + .ifPresent(instruction::setLabel); } } diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Value.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Value.java index c46af8f07..7519e4b16 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Value.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Value.java @@ -27,9 +27,9 @@ * It has the type defined in compile time, but it can be integer or a String. */ public class Value implements RAMValue { + public final Type type; private final int intValue; private final String stringValue; - public final Type type; public Value(int value) { this.intValue = value; diff --git a/plugins/compiler/ramc-ram/src/main/resources/net/emustudio/plugins/compiler/ram/version.properties b/plugins/compiler/ramc-ram/src/main/resources/net/emustudio/plugins/compiler/ram/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/compiler/ramc-ram/src/main/resources/net/emustudio/plugins/compiler/ram/version.properties +++ b/plugins/compiler/ramc-ram/src/main/resources/net/emustudio/plugins/compiler/ram/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/AbstractCompilerTest.java b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/AbstractCompilerTest.java index 954d01ffe..2e7c0c27b 100644 --- a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/AbstractCompilerTest.java +++ b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/AbstractCompilerTest.java @@ -38,11 +38,10 @@ import static org.junit.Assert.assertNull; public abstract class AbstractCompilerTest { - protected CompilerRAM compiler; - protected MemoryStub memoryStub; - @Rule public TemporaryFolder folder = new TemporaryFolder(); + protected CompilerRAM compiler; + protected MemoryStub memoryStub; @Before public void setUp() throws Exception { @@ -91,14 +90,14 @@ protected void compile(String content) throws Exception { protected void assertProgram(RAMInstruction... program) { for (int i = 0; i < program.length; i++) { assertEquals( - String.format("%d. expected=%s, but was=%s", i, program[i], memoryStub.read(i)), - program[i], memoryStub.read(i) + String.format("%d. expected=%s, but was=%s", i, program[i], memoryStub.read(i)), + program[i], memoryStub.read(i) ); } for (int i = program.length; i < memoryStub.getSize(); i++) { assertNull( - String.format("%d. expected=null, but was=%s", i, memoryStub.read(i)), - memoryStub.read(i) + String.format("%d. expected=null, but was=%s", i, memoryStub.read(i)), + memoryStub.read(i) ); } } diff --git a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/CompilerTest.java b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/CompilerTest.java index 1299fe57b..d63dab90e 100644 --- a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/CompilerTest.java +++ b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/CompilerTest.java @@ -55,8 +55,8 @@ public void testREAD() throws Exception { compile("READ 5\nREAD *6"); assertProgram( - new Instruction(0, 0, READ, RAMInstruction.Direction.DIRECT, 0, Optional.of(new Value(5))), - new Instruction(0, 0, READ, RAMInstruction.Direction.INDIRECT, 1, Optional.of(new Value(6))) + new Instruction(0, 0, READ, RAMInstruction.Direction.DIRECT, 0, Optional.of(new Value(5))), + new Instruction(0, 0, READ, RAMInstruction.Direction.INDIRECT, 1, Optional.of(new Value(6))) ); } @@ -65,9 +65,9 @@ public void testWRITE() throws Exception { compile("WRITE =3\nWRITE 4\nWRITE *8"); assertProgram( - new Instruction(0, 0, WRITE, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value(3))), - new Instruction(0, 0, WRITE, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(4))), - new Instruction(0, 0, WRITE, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(8))) + new Instruction(0, 0, WRITE, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value(3))), + new Instruction(0, 0, WRITE, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(4))), + new Instruction(0, 0, WRITE, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(8))) ); } @@ -76,9 +76,9 @@ public void testLOAD() throws Exception { compile("LOAD ='hello'\nLOAD 7\nLOAD *11"); assertProgram( - new Instruction(0, 0, LOAD, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("hello", false))), - new Instruction(0, 0, LOAD, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(7))), - new Instruction(0, 0, LOAD, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(11))) + new Instruction(0, 0, LOAD, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("hello", false))), + new Instruction(0, 0, LOAD, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(7))), + new Instruction(0, 0, LOAD, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(11))) ); } @@ -87,8 +87,8 @@ public void testSTORE() throws Exception { compile("STORE 111111112\nSTORE *55\n"); assertProgram( - new Instruction(0, 0, STORE, RAMInstruction.Direction.DIRECT, 0, Optional.of(new Value(111111112))), - new Instruction(0, 0, STORE, RAMInstruction.Direction.INDIRECT, 1, Optional.of(new Value(55))) + new Instruction(0, 0, STORE, RAMInstruction.Direction.DIRECT, 0, Optional.of(new Value(111111112))), + new Instruction(0, 0, STORE, RAMInstruction.Direction.INDIRECT, 1, Optional.of(new Value(55))) ); } @@ -97,9 +97,9 @@ public void testADD() throws Exception { compile("ADD =\"omg omg\"\nADD 99\nADD *1"); assertProgram( - new Instruction(0, 0, ADD, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), - new Instruction(0, 0, ADD, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(99))), - new Instruction(0, 0, ADD, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(1))) + new Instruction(0, 0, ADD, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), + new Instruction(0, 0, ADD, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(99))), + new Instruction(0, 0, ADD, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(1))) ); } @@ -108,9 +108,9 @@ public void testSUB() throws Exception { compile("SUB =\"omg omg\"\nSUB 229\nSUB *2453"); assertProgram( - new Instruction(0, 0, SUB, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), - new Instruction(0, 0, SUB, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), - new Instruction(0, 0, SUB, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) + new Instruction(0, 0, SUB, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), + new Instruction(0, 0, SUB, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), + new Instruction(0, 0, SUB, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) ); } @@ -119,9 +119,9 @@ public void testMUL() throws Exception { compile("MUL =\"omg omg\"\nMUL 229\nMUL *2453"); assertProgram( - new Instruction(0, 0, MUL, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), - new Instruction(0, 0, MUL, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), - new Instruction(0, 0, MUL, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) + new Instruction(0, 0, MUL, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), + new Instruction(0, 0, MUL, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), + new Instruction(0, 0, MUL, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) ); } @@ -130,9 +130,9 @@ public void testDIV() throws Exception { compile("DIV =\"omg omg\"\nDIV 229\nDIV *2453"); assertProgram( - new Instruction(0, 0, DIV, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), - new Instruction(0, 0, DIV, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), - new Instruction(0, 0, DIV, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) + new Instruction(0, 0, DIV, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), + new Instruction(0, 0, DIV, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), + new Instruction(0, 0, DIV, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) ); } @@ -141,9 +141,9 @@ public void testJMP() throws Exception { compile("here: JMP here"); assertProgram(new Instruction( - JMP, RAMInstruction.Direction.DIRECT, 0, - Optional.of(new Value("here", true)), - new Label(0, 0, "here", 0) + JMP, RAMInstruction.Direction.DIRECT, 0, + Optional.of(new Value("here", true)), + new Label(0, 0, "here", 0) )); assertEquals(Optional.of(0), memoryStub.read(0).getLabel().map(RAMLabel::getAddress)); } @@ -153,11 +153,11 @@ public void testJMP_ForwardReference() throws Exception { compile("JMP here\nhere:HALT"); assertProgram( - new Instruction( - JMP, RAMInstruction.Direction.DIRECT, 0, - Optional.of(new Value("here", true)), - new Label(0, 0, "here", 1)), - new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 1, Optional.empty()) + new Instruction( + JMP, RAMInstruction.Direction.DIRECT, 0, + Optional.of(new Value("here", true)), + new Label(0, 0, "here", 1)), + new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 1, Optional.empty()) ); assertEquals(Optional.of(1), memoryStub.read(0).getLabel().map(RAMLabel::getAddress)); } @@ -167,11 +167,11 @@ public void testJZ() throws Exception { compile("JZ here\nhere:HALT"); assertProgram( - new Instruction( - JZ, RAMInstruction.Direction.DIRECT, 0, - Optional.of(new Value("here", true)), - new Label(0, 0, "here", 1)), - new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 1, Optional.empty()) + new Instruction( + JZ, RAMInstruction.Direction.DIRECT, 0, + Optional.of(new Value("here", true)), + new Label(0, 0, "here", 1)), + new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 1, Optional.empty()) ); assertEquals(Optional.of(1), memoryStub.read(0).getLabel().map(RAMLabel::getAddress)); } @@ -181,11 +181,11 @@ public void testJGTZ() throws Exception { compile("JGTZ here\nhere:HALT"); assertProgram( - new Instruction( - JGTZ, RAMInstruction.Direction.DIRECT, 0, - Optional.of(new Value("here", true)), - new Label(0, 0, "here", 1)), - new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 1, Optional.empty()) + new Instruction( + JGTZ, RAMInstruction.Direction.DIRECT, 0, + Optional.of(new Value("here", true)), + new Label(0, 0, "here", 1)), + new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 1, Optional.empty()) ); assertEquals(Optional.of(1), memoryStub.read(0).getLabel().map(RAMLabel::getAddress)); } @@ -195,7 +195,7 @@ public void testHALT() throws Exception { compile("halt"); assertProgram( - new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 0, Optional.empty()) + new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 0, Optional.empty()) ); } diff --git a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java index 8a99726ca..e55f4b9ef 100644 --- a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java +++ b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java @@ -82,12 +82,12 @@ public Optional getLabel(int address) { } @Override - public void setInputs(List inputs) { - this.inputs.addAll(inputs); + public List getInputs() { + return inputs; } @Override - public List getInputs() { - return inputs; + public void setInputs(List inputs) { + this.inputs.addAll(inputs); } } diff --git a/plugins/compiler/raspc-rasp/README.md b/plugins/compiler/raspc-rasp/README.md index bb182b1d9..b8d05d739 100644 --- a/plugins/compiler/raspc-rasp/README.md +++ b/plugins/compiler/raspc-rasp/README.md @@ -3,4 +3,5 @@ This project is compiler of [RASP](https://en.wikipedia.org/wiki/Random-access_stored-program_machine) machine. It is part of [emuStudio](https://www.emustudio.net/). -The official documentation can be found [here](https://www.emustudio.net/docuser/rasp/index/#compiler-code-raspc-rasp-code) +The official documentation can be +found [here](https://www.emustudio.net/docuser/rasp/index/#compiler-code-raspc-rasp-code) diff --git a/plugins/compiler/raspc-rasp/build.gradle b/plugins/compiler/raspc-rasp/build.gradle index 0e9f334de..ebd6a8455 100644 --- a/plugins/compiler/raspc-rasp/build.gradle +++ b/plugins/compiler/raspc-rasp/build.gradle @@ -51,7 +51,7 @@ sourceSets { } main { java.srcDirs = [ - 'src/main/java', "${buildDir}/generated-src/antlr/main" + 'src/main/java', "${buildDir}/generated-src/antlr/main" ] } } @@ -73,8 +73,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java index 657b8cfc5..80a1bf106 100644 --- a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java @@ -43,13 +43,13 @@ import java.util.*; @PluginRoot( - type = PLUGIN_TYPE.COMPILER, - title = "RASP Machine Assembler" + type = PLUGIN_TYPE.COMPILER, + title = "RASP Machine Assembler" ) public class CompilerRASP extends AbstractCompiler { private final static Logger LOGGER = LoggerFactory.getLogger(CompilerRASP.class); private static final List SOURCE_FILE_EXTENSIONS = List.of( - new SourceFileExtension("rasp", "RASP source file") + new SourceFileExtension("rasp", "RASP source file") ); private RASPMemoryContext memory; diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/LexicalAnalyzerImpl.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/LexicalAnalyzerImpl.java index 5c5b035c8..f8c083012 100644 --- a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/LexicalAnalyzerImpl.java +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/LexicalAnalyzerImpl.java @@ -30,7 +30,6 @@ import static org.antlr.v4.runtime.Recognizer.EOF; public class LexicalAnalyzerImpl implements LexicalAnalyzer { - private final RASPLexer lexer; public static final int[] tokenMap = new int[ERROR + 1]; static { @@ -68,6 +67,8 @@ public class LexicalAnalyzerImpl implements LexicalAnalyzer { tokenMap[ERROR] = Token.ERROR; } + private final RASPLexer lexer; + public LexicalAnalyzerImpl(RASPLexer lexer) { this.lexer = Objects.requireNonNull(lexer); diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParserErrorListener.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParserErrorListener.java index efcc2f463..84071f7cd 100644 --- a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParserErrorListener.java +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ParserErrorListener.java @@ -27,12 +27,12 @@ public class ParserErrorListener extends BaseErrorListener { @Override public void syntaxError( - Recognizer recognizer, - Object offendingSymbol, - int line, - int charPositionInLine, - String msg, - RecognitionException e) { + Recognizer recognizer, + Object offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) { if (e == null) { throw new SyntaxErrorException(line, charPositionInLine, msg); diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ProgramParser.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ProgramParser.java index 4de0a9783..81bb42726 100644 --- a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ProgramParser.java +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ProgramParser.java @@ -96,7 +96,7 @@ public Program visitInstrRegister(InstrRegisterContext ctx) { int operand = parseNumber(ctx.n.n); Instruction instruction = new Instruction( - op.getLine(), op.getCharPositionInLine(), opcode, currentAddress++, Optional.of(operand) + op.getLine(), op.getCharPositionInLine(), opcode, currentAddress++, Optional.of(operand) ); currentAddress++; // operand program.add(instruction); @@ -110,7 +110,7 @@ public Program visitInstrConstant(InstrConstantContext ctx) { int operand = parseNumber(ctx.n.n); Instruction instruction = new Instruction( - op.getLine(), op.getCharPositionInLine(), opcode, currentAddress++, Optional.of(operand) + op.getLine(), op.getCharPositionInLine(), opcode, currentAddress++, Optional.of(operand) ); currentAddress++; // operand program.add(instruction); @@ -124,7 +124,7 @@ public Program visitInstrJump(InstrJumpContext ctx) { String id = ctx.id.getText(); Instruction instruction = new Instruction( - op.getLine(), op.getCharPositionInLine(), opcode, currentAddress++, id + op.getLine(), op.getCharPositionInLine(), opcode, currentAddress++, id ); currentAddress++; // operand program.add(instruction); @@ -134,7 +134,7 @@ public Program visitInstrJump(InstrJumpContext ctx) { @Override public Program visitInstrNoOperand(InstrNoOperandContext ctx) { Instruction instruction = new Instruction( - ctx.op.getLine(), ctx.op.getCharPositionInLine(), 18, currentAddress++, Optional.empty() + ctx.op.getLine(), ctx.op.getCharPositionInLine(), 18, currentAddress++, Optional.empty() ); program.add(instruction); return program; diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Instruction.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Instruction.java index 67dd741a9..10f3f030f 100644 --- a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Instruction.java +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Instruction.java @@ -72,9 +72,9 @@ public int hashCode() { @Override public String toString() { return "Instruction{" + - "address=" + address + - ", opcode=" + opcode + - ", operand=" + operand + - '}'; + "address=" + address + + ", opcode=" + opcode + + ", operand=" + operand + + '}'; } } diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java index 5b968c75c..708f20dec 100644 --- a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java @@ -65,8 +65,8 @@ public int hashCode() { @Override public String toString() { return "{" + - "label='" + label + '\'' + - ", address=" + address + - '}'; + "label='" + label + '\'' + + ", address=" + address + + '}'; } } diff --git a/plugins/compiler/raspc-rasp/src/main/resources/net/emustudio/plugins/compiler/rasp/version.properties b/plugins/compiler/raspc-rasp/src/main/resources/net/emustudio/plugins/compiler/rasp/version.properties index 5a083e1ab..330ab194e 100644 --- a/plugins/compiler/raspc-rasp/src/main/resources/net/emustudio/plugins/compiler/rasp/version.properties +++ b/plugins/compiler/raspc-rasp/src/main/resources/net/emustudio/plugins/compiler/rasp/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright="\u00A9 Copyright 2016-2017, Michal Šipoš\n\u00A9 Copyright 2006-2022, Peter Jakubčo" diff --git a/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/AbstractCompilerTest.java b/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/AbstractCompilerTest.java index c026a7f1c..3fdcd9da9 100644 --- a/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/AbstractCompilerTest.java +++ b/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/AbstractCompilerTest.java @@ -38,11 +38,10 @@ import static org.junit.Assert.assertNull; public abstract class AbstractCompilerTest { - protected CompilerRASP compiler; - protected MemoryStub memoryStub; - @Rule public TemporaryFolder folder = new TemporaryFolder(); + protected CompilerRASP compiler; + protected MemoryStub memoryStub; @Before public void setUp() throws Exception { @@ -89,14 +88,14 @@ public void onFinish() { protected void assertProgram(RASPMemoryCell... program) { for (int i = 0; i < program.length; i++) { assertEquals( - String.format("%d. expected=%s, but was=%s", i, program[i], memoryStub.read(i)), - program[i], memoryStub.read(i) + String.format("%d. expected=%s, but was=%s", i, program[i], memoryStub.read(i)), + program[i], memoryStub.read(i) ); } for (int i = program.length; i < memoryStub.getSize(); i++) { assertNull( - String.format("%d. expected=null, but was=%s", i, memoryStub.read(i)), - memoryStub.read(i) + String.format("%d. expected=null, but was=%s", i, memoryStub.read(i)), + memoryStub.read(i) ); } } diff --git a/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/CompilerTest.java b/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/CompilerTest.java index c3f1f176e..ae61933ea 100644 --- a/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/CompilerTest.java +++ b/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/CompilerTest.java @@ -28,20 +28,20 @@ public class CompilerTest extends AbstractCompilerTest { @Test public void testJmpInstruction() throws Exception { compile( - "org 2\n" + - "START: jmp HERE\n" + - "jmp START\n" + - "HERE: halt" + "org 2\n" + + "START: jmp HERE\n" + + "jmp START\n" + + "HERE: halt" ); assertProgram( - null, - null, - new RASPMemoryCellImpl(true, 15, 2), - new RASPMemoryCellImpl(false, 6, 3), - new RASPMemoryCellImpl(true, 15, 4), - new RASPMemoryCellImpl(false, 2, 5), - new RASPMemoryCellImpl(true, 18, 6) + null, + null, + new RASPMemoryCellImpl(true, 15, 2), + new RASPMemoryCellImpl(false, 6, 3), + new RASPMemoryCellImpl(true, 15, 4), + new RASPMemoryCellImpl(false, 2, 5), + new RASPMemoryCellImpl(true, 18, 6) ); } diff --git a/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/MemoryStub.java b/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/MemoryStub.java index cdea1d3ac..95e9aa320 100644 --- a/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/MemoryStub.java +++ b/plugins/compiler/raspc-rasp/src/test/java/net/emustudio/plugins/compiler/rasp/MemoryStub.java @@ -81,12 +81,12 @@ public Optional getLabel(int address) { } @Override - public void setInputs(List inputs) { - this.inputs.addAll(inputs); + public List getInputs() { + return inputs; } @Override - public List getInputs() { - return inputs; + public void setInputs(List inputs) { + this.inputs.addAll(inputs); } } diff --git a/plugins/cpu/8080-cpu/build.gradle b/plugins/cpu/8080-cpu/build.gradle index 3db29a564..1e16a7366 100644 --- a/plugins/cpu/8080-cpu/build.gradle +++ b/plugins/cpu/8080-cpu/build.gradle @@ -58,8 +58,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java index df8b5d6a6..1b3e6bb62 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java @@ -98,7 +98,7 @@ public boolean isInterruptSupported() { * during the interrupt acknowledge cycle. Subsequent bytes are read in by a * normal memory read sequence. * - * @param data instruction signaled by this interrupt + * @param data instruction signaled by this interrupt */ @Override public void signalInterrupt(byte[] data) { diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java index 1ed09c857..9f3a736d4 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java @@ -44,8 +44,8 @@ import java.util.concurrent.atomic.AtomicReference; @PluginRoot( - type = PLUGIN_TYPE.CPU, - title = "Intel 8080 CPU" + type = PLUGIN_TYPE.CPU, + title = "Intel 8080 CPU" ) @SuppressWarnings("unused") public class CpuImpl extends AbstractCPU { @@ -69,11 +69,11 @@ public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings sett } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register CPU context", e); applicationApi.getDialogs().showError( - "Could not register CPU Context. Please see log file for details.", super.getTitle() + "Could not register CPU Context. Please see log file for details.", super.getTitle() ); } initializer = new InitializerFor8080( - this, pluginID, applicationApi.getContextPool(), settings, context + this, pluginID, applicationApi.getContextPool(), settings, context ); } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/DispatchTables.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/DispatchTables.java index 73e180ce8..39deed157 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/DispatchTables.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/DispatchTables.java @@ -26,13 +26,13 @@ import java.lang.invoke.MethodType; public class DispatchTables { - private final static Logger LOGGER = LoggerFactory.getLogger(DispatchTables.class); public final static MethodHandle[] DISPATCH_TABLE = new MethodHandle[256]; + private final static Logger LOGGER = LoggerFactory.getLogger(DispatchTables.class); static { MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType retInt = MethodType.methodType(int.class); - + try { DISPATCH_TABLE[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", retInt); DISPATCH_TABLE[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_LXI", retInt); diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java index 1785498e3..46ba46019 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java @@ -37,44 +37,39 @@ import static net.emustudio.plugins.cpu.intel8080.DispatchTables.DISPATCH_TABLE; public class EmulatorEngine implements CpuEngine { - private static final Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); - public static final int REG_A = 7, REG_B = 0, REG_C = 1, REG_D = 2, REG_E = 3, REG_H = 4, REG_L = 5; public static final int FLAG_S = 0x80, FLAG_Z = 0x40, FLAG_AC = 0x10, FLAG_P = 0x4, FLAG_C = 0x1; + private static final Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); private final static int[] CONDITION = new int[]{ - FLAG_Z, FLAG_Z, FLAG_C, FLAG_C, FLAG_P, FLAG_P, FLAG_S, FLAG_S + FLAG_Z, FLAG_Z, FLAG_C, FLAG_C, FLAG_P, FLAG_P, FLAG_S, FLAG_S }; private final static int[] CONDITION_VALUES = new int[]{ - 0, FLAG_Z, 0, FLAG_C, 0, FLAG_P, 0, FLAG_S + 0, FLAG_Z, 0, FLAG_C, 0, FLAG_P, 0, FLAG_S }; - - public boolean INTE = false; // enabling / disabling of interrupts - private boolean isINT = false; - private short b1 = 0; // the raw interrupt instruction - private short b2 = 0; - private short b3 = 0; private final static Map RST_MAP = Map.of( - 0xC7, 0, - 0xCF, 0x8, - 0xD7, 0x10, - 0xDF, 0x18, - 0xE7, 0x20, - 0xEF, 0x28, - 0xF7, 0x30, - 0xFF, 0x38 + 0xC7, 0, + 0xCF, 0x8, + 0xD7, 0x10, + 0xDF, 0x18, + 0xE7, 0x20, + 0xEF, 0x28, + 0xF7, 0x30, + 0xFF, 0x38 ); - + private final MemoryContext memory; + private final Context8080Impl context; + private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); + public boolean INTE = false; // enabling / disabling of interrupts public int PC = 0; // program counter public int SP = 0; // stack pointer public int[] regs = new int[8]; public short flags = 2; // registers public volatile CPU.RunState currentRunState = CPU.RunState.STATE_STOPPED_NORMAL; + private boolean isINT = false; + private short b1 = 0; // the raw interrupt instruction + private short b2 = 0; + private short b3 = 0; private int lastOpcode; - - private final MemoryContext memory; - private final Context8080Impl context; - private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); - private long executedCycles = 0; private volatile DispatchListener dispatchListener; diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorTables.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorTables.java index 7ac29d056..baf8af88c 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorTables.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorTables.java @@ -20,82 +20,78 @@ class EmulatorTables { + final static short[] CARRY_TABLE = new short[]{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1 + }; static short[] INC_TABLE = new short[]{ - 86, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 18, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, - 6, 2, 18, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 22, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, - 6, 2, 2, 6, 18, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 22, 2, 2, 6, 2, 6, 6, 2, 2, 6, - 6, 2, 6, 2, 2, 6, 22, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 18, 6, 6, 2, 6, 2, 2, 6, - 6, 2, 2, 6, 2, 6, 6, 2, 146, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 150, 130, 130, 134, 130, 134, - 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 150, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 146, 134, 134, 130, - 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 150, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 146, 134, - 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 146, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, - 150, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134 + 86, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 18, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, + 6, 2, 18, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 22, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, + 6, 2, 2, 6, 18, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 22, 2, 2, 6, 2, 6, 6, 2, 2, 6, + 6, 2, 6, 2, 2, 6, 22, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 18, 6, 6, 2, 6, 2, 2, 6, + 6, 2, 2, 6, 2, 6, 6, 2, 146, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 150, 130, 130, 134, 130, 134, + 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 150, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 146, 134, 134, 130, + 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 150, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 146, 134, + 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 146, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, + 150, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134 }; - static short[] DEC_TABLE = new short[]{ - 86, 18, 18, 22, 18, 22, 22, 18, 18, 22, 22, 18, 22, 18, 18, 6, 18, 22, 22, 18, 22, 18, 18, 22, 22, 18, 18, 22, 18, 22, - 22, 2, 18, 22, 22, 18, 22, 18, 18, 22, 22, 18, 18, 22, 18, 22, 22, 2, 22, 18, 18, 22, 18, 22, 22, 18, 18, 22, 22, 18, - 22, 18, 18, 6, 18, 22, 22, 18, 22, 18, 18, 22, 22, 18, 18, 22, 18, 22, 22, 2, 22, 18, 18, 22, 18, 22, 22, 18, 18, 22, - 22, 18, 22, 18, 18, 6, 22, 18, 18, 22, 18, 22, 22, 18, 18, 22, 22, 18, 22, 18, 18, 6, 18, 22, 22, 18, 22, 18, 18, 22, - 22, 18, 18, 22, 18, 22, 22, 2, 146, 150, 150, 146, 150, 146, 146, 150, 150, 146, 146, 150, 146, 150, 150, 130, 150, 146, 146, 150, 146, 150, - 150, 146, 146, 150, 150, 146, 150, 146, 146, 134, 150, 146, 146, 150, 146, 150, 150, 146, 146, 150, 150, 146, 150, 146, 146, 134, 146, 150, 150, 146, - 150, 146, 146, 150, 150, 146, 146, 150, 146, 150, 150, 130, 150, 146, 146, 150, 146, 150, 150, 146, 146, 150, 150, 146, 150, 146, 146, 134, 146, 150, - 150, 146, 150, 146, 146, 150, 150, 146, 146, 150, 146, 150, 150, 130, 146, 150, 150, 146, 150, 146, 146, 150, 150, 146, 146, 150, 146, 150, 150, 130, - 150, 146, 146, 150, 146, 150, 150, 146, 146, 150, 150, 146, 150, 146, 146, 134 + 86, 18, 18, 22, 18, 22, 22, 18, 18, 22, 22, 18, 22, 18, 18, 6, 18, 22, 22, 18, 22, 18, 18, 22, 22, 18, 18, 22, 18, 22, + 22, 2, 18, 22, 22, 18, 22, 18, 18, 22, 22, 18, 18, 22, 18, 22, 22, 2, 22, 18, 18, 22, 18, 22, 22, 18, 18, 22, 22, 18, + 22, 18, 18, 6, 18, 22, 22, 18, 22, 18, 18, 22, 22, 18, 18, 22, 18, 22, 22, 2, 22, 18, 18, 22, 18, 22, 22, 18, 18, 22, + 22, 18, 22, 18, 18, 6, 22, 18, 18, 22, 18, 22, 22, 18, 18, 22, 22, 18, 22, 18, 18, 6, 18, 22, 22, 18, 22, 18, 18, 22, + 22, 18, 18, 22, 18, 22, 22, 2, 146, 150, 150, 146, 150, 146, 146, 150, 150, 146, 146, 150, 146, 150, 150, 130, 150, 146, 146, 150, 146, 150, + 150, 146, 146, 150, 150, 146, 150, 146, 146, 134, 150, 146, 146, 150, 146, 150, 150, 146, 146, 150, 150, 146, 150, 146, 146, 134, 146, 150, 150, 146, + 150, 146, 146, 150, 150, 146, 146, 150, 146, 150, 150, 130, 150, 146, 146, 150, 146, 150, 150, 146, 146, 150, 150, 146, 150, 146, 146, 134, 146, 150, + 150, 146, 150, 146, 146, 150, 150, 146, 146, 150, 146, 150, 150, 130, 146, 150, 150, 146, 150, 146, 146, 150, 150, 146, 146, 150, 146, 150, 150, 130, + 150, 146, 146, 150, 146, 150, 150, 146, 146, 150, 150, 146, 150, 146, 146, 134 }; - static short[] SIGN_ZERO_PARITY_TABLE = new short[]{ - 70, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, - 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, - 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, - 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, - 6, 2, 2, 6, 2, 6, 6, 2, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, - 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, 134, 130, - 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, - 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, - 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134 + 70, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, + 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, + 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, + 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, + 6, 2, 2, 6, 2, 6, 6, 2, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, + 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, 134, 130, + 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, + 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, + 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134 }; - static short[] SIGN_ZERO_PARITY_CARRY_TABLE = new short[]{ - 70, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, - 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, - 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, - 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, - 6, 2, 2, 6, 2, 6, 6, 2, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, - 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, 134, 130, - 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, - 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, - 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 71, 3, 3, 7, 3, 7, 7, 3, 3, 7, 7, 3, 7, 3, - 3, 7, 3, 7, 7, 3, 7, 3, 3, 7, 7, 3, 3, 7, 3, 7, 7, 3, 3, 7, 7, 3, 7, 3, 3, 7, 7, 3, 3, 7, - 3, 7, 7, 3, 7, 3, 3, 7, 3, 7, 7, 3, 3, 7, 7, 3, 7, 3, 3, 7, 3, 7, 7, 3, 7, 3, 3, 7, 7, 3, - 3, 7, 3, 7, 7, 3, 7, 3, 3, 7, 3, 7, 7, 3, 3, 7, 7, 3, 7, 3, 3, 7, 7, 3, 3, 7, 3, 7, 7, 3, - 3, 7, 7, 3, 7, 3, 3, 7, 3, 7, 7, 3, 7, 3, 3, 7, 7, 3, 3, 7, 3, 7, 7, 3, 131, 135, 135, 131, 135, 131, - 131, 135, 135, 131, 131, 135, 131, 135, 135, 131, 135, 131, 131, 135, 131, 135, 135, 131, 131, 135, 135, 131, 135, 131, 131, 135, 135, 131, 131, 135, - 131, 135, 135, 131, 131, 135, 135, 131, 135, 131, 131, 135, 131, 135, 135, 131, 135, 131, 131, 135, 135, 131, 131, 135, 131, 135, 135, 131, 135, 131, - 131, 135, 131, 135, 135, 131, 131, 135, 135, 131, 135, 131, 131, 135, 131, 135, 135, 131, 135, 131, 131, 135, 135, 131, 131, 135, 131, 135, 135, 131, - 131, 135, 135, 131, 135, 131, 131, 135, 135, 131, 131, 135, 131, 135, 135, 131, 135, 131, 131, 135, 131, 135, 135, 131, 131, 135, 135, 131, 135, 131, - 131, 135 - }; - - final static short[] CARRY_TABLE = new short[]{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1 + 70, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, + 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, + 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, + 6, 2, 6, 2, 2, 6, 6, 2, 2, 6, 2, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 6, 2, 6, 6, 2, 6, 2, 2, 6, + 6, 2, 2, 6, 2, 6, 6, 2, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, + 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, 134, 130, + 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 130, 134, + 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 134, 130, 130, 134, 130, 134, 134, 130, + 134, 130, 130, 134, 130, 134, 134, 130, 130, 134, 134, 130, 134, 130, 130, 134, 71, 3, 3, 7, 3, 7, 7, 3, 3, 7, 7, 3, 7, 3, + 3, 7, 3, 7, 7, 3, 7, 3, 3, 7, 7, 3, 3, 7, 3, 7, 7, 3, 3, 7, 7, 3, 7, 3, 3, 7, 7, 3, 3, 7, + 3, 7, 7, 3, 7, 3, 3, 7, 3, 7, 7, 3, 3, 7, 7, 3, 7, 3, 3, 7, 3, 7, 7, 3, 7, 3, 3, 7, 7, 3, + 3, 7, 3, 7, 7, 3, 7, 3, 3, 7, 3, 7, 7, 3, 3, 7, 7, 3, 7, 3, 3, 7, 7, 3, 3, 7, 3, 7, 7, 3, + 3, 7, 7, 3, 7, 3, 3, 7, 3, 7, 7, 3, 7, 3, 3, 7, 7, 3, 3, 7, 3, 7, 7, 3, 131, 135, 135, 131, 135, 131, + 131, 135, 135, 131, 131, 135, 131, 135, 135, 131, 135, 131, 131, 135, 131, 135, 135, 131, 131, 135, 135, 131, 135, 131, 131, 135, 135, 131, 131, 135, + 131, 135, 135, 131, 131, 135, 135, 131, 135, 131, 131, 135, 131, 135, 135, 131, 135, 131, 131, 135, 135, 131, 131, 135, 131, 135, 135, 131, 135, 131, + 131, 135, 131, 135, 135, 131, 131, 135, 135, 131, 135, 131, 131, 135, 131, 135, 135, 131, 135, 131, 131, 135, 135, 131, 131, 135, 131, 135, 135, 131, + 131, 135, 135, 131, 135, 131, 131, 135, 135, 131, 131, 135, 131, 135, 135, 131, 135, 131, 131, 135, 131, 135, 135, 131, 131, 135, 135, 131, 135, 131, + 131, 135 }; } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InstructionPrinter.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InstructionPrinter.java index 6afb5d056..7b6948f72 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InstructionPrinter.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/InstructionPrinter.java @@ -38,9 +38,8 @@ public class InstructionPrinter implements DispatchListener { private final List cache = new CopyOnWriteArrayList<>(); private final AtomicInteger numberOfMatch = new AtomicInteger(); - private volatile int matchPC; private final boolean useCache; - + private volatile int matchPC; private volatile long creationTimeStamp; public InstructionPrinter(Disassembler disassembler, EmulatorEngine emulatorEngine, boolean useCache, PrintStream writer) { @@ -64,7 +63,7 @@ public void beforeDispatch() { if (useCache && !cache.contains(emulatorEngine.PC)) { if (numberOfMatch.get() != 0) { writer.println(String.format("%04d | Block from %04X to %04X; count=%d", - timeStamp, matchPC, emulatorEngine.PC, numberOfMatch.get()) + timeStamp, matchPC, emulatorEngine.PC, numberOfMatch.get()) ); } else { matchPC = emulatorEngine.PC; @@ -77,7 +76,7 @@ public void beforeDispatch() { if (numberOfMatch.get() <= 1) { writer.print(String.format("%04d | PC=%04x | %12s | %10s ", - timeStamp, instr.getAddress(), instr.getMnemo(), instr.getOpCode()) + timeStamp, instr.getAddress(), instr.getMnemo(), instr.getOpCode()) ); } @@ -90,7 +89,7 @@ public void beforeDispatch() { public void afterDispatch() { if (numberOfMatch.get() <= 1) { writer.println(String.format("|| regs=%s | flags=%s | SP=%04x | PC=%04x", - regsToString(), intToFlags(emulatorEngine.flags), emulatorEngine.SP, emulatorEngine.PC) + regsToString(), intToFlags(emulatorEngine.flags), emulatorEngine.SP, emulatorEngine.PC) ); } } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/DefaultInitializer.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/DefaultInitializer.java index e4caa78f3..6cc29c3b3 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/DefaultInitializer.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/api/DefaultInitializer.java @@ -27,7 +27,9 @@ import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.settings.PluginSettings; -import java.io.*; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; import java.nio.file.Path; import java.util.Objects; import java.util.Optional; @@ -60,7 +62,7 @@ public final void initialize() throws PluginInitializationException { MemoryContext memory = contextPool.getMemoryContext(pluginId, MemoryContext.class); if (memory.getDataType() != Byte.class) { throw new InvalidContextException( - "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() + "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() ); } diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java index 9cf686bc1..252e4ed8e 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java @@ -38,8 +38,26 @@ public class StatusPanel extends JPanel { private final EmulatorEngine engine; private final Context8080 context; private final AbstractTableModel flagModel; + // Variables declaration - do not modify//GEN-BEGIN:variables + JLabel lblFrequency; + JLabel lblRun; + JSpinner spnFrequency; + JTable tblFlags; + JTextField txtFlags; + JTextField txtRegA; + JTextField txtRegB; + JTextField txtRegBC; + JTextField txtRegC; + JTextField txtRegD; + JTextField txtRegDE; + JTextField txtRegE; + JTextField txtRegH; + JTextField txtRegHL; + JTextField txtRegL; + JTextField txtRegPC; + JTextField txtRegSP; + JCheckBox chkPrintInstructions; private volatile RunState runState = RunState.STATE_STOPPED_NORMAL; - public StatusPanel(CpuImpl cpu, Context8080 context, boolean dumpInstructions) { this.cpu = cpu; this.context = context; @@ -222,16 +240,16 @@ private void initComponents() { paneRegisters.setLayout(paneRegistersLayout); paneRegistersLayout.setHorizontalGroup( - paneRegistersLayout.createSequentialGroup().addContainerGap().addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(paneRegistersLayout.createSequentialGroup().addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(lblRegB).addComponent(lblRegD).addComponent(lblRegH).addComponent(lblRegA)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(txtRegB).addComponent(txtRegD).addComponent(txtRegH).addComponent(txtRegA)).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(lblRegC).addComponent(lblRegE).addComponent(lblRegL).addComponent(lblRegF)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(txtRegC).addComponent(txtRegE).addComponent(txtRegL).addComponent(txtFlags)).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(lblRegBC).addComponent(lblRegDE).addComponent(lblRegHL).addComponent(lblRegPC).addComponent(lblRegSP)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(txtRegBC).addComponent(txtRegDE).addComponent(txtRegHL).addComponent(txtRegPC).addComponent(txtRegSP))).addComponent(lblFlags).addComponent(tblFlags)).addContainerGap()); + paneRegistersLayout.createSequentialGroup().addContainerGap().addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(paneRegistersLayout.createSequentialGroup().addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(lblRegB).addComponent(lblRegD).addComponent(lblRegH).addComponent(lblRegA)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(txtRegB).addComponent(txtRegD).addComponent(txtRegH).addComponent(txtRegA)).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(lblRegC).addComponent(lblRegE).addComponent(lblRegL).addComponent(lblRegF)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(txtRegC).addComponent(txtRegE).addComponent(txtRegL).addComponent(txtFlags)).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(lblRegBC).addComponent(lblRegDE).addComponent(lblRegHL).addComponent(lblRegPC).addComponent(lblRegSP)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(txtRegBC).addComponent(txtRegDE).addComponent(txtRegHL).addComponent(txtRegPC).addComponent(txtRegSP))).addComponent(lblFlags).addComponent(tblFlags)).addContainerGap()); paneRegistersLayout.setVerticalGroup( - paneRegistersLayout.createSequentialGroup().addContainerGap().addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(lblRegB).addComponent(txtRegB).addComponent(lblRegC).addComponent(txtRegC).addComponent(lblRegBC).addComponent(txtRegBC)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(lblRegD).addComponent(txtRegD).addComponent(lblRegE).addComponent(txtRegE).addComponent(lblRegDE).addComponent(txtRegDE)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(lblRegH).addComponent(txtRegH).addComponent(lblRegL).addComponent(txtRegL).addComponent(lblRegHL).addComponent(txtRegHL)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(lblRegA).addComponent(txtRegA).addComponent(lblRegF).addComponent(txtFlags).addComponent(lblRegPC).addComponent(txtRegPC)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(lblRegSP).addComponent(txtRegSP)).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addComponent(lblFlags).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(tblFlags)); + paneRegistersLayout.createSequentialGroup().addContainerGap().addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(lblRegB).addComponent(txtRegB).addComponent(lblRegC).addComponent(txtRegC).addComponent(lblRegBC).addComponent(txtRegBC)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(lblRegD).addComponent(txtRegD).addComponent(lblRegE).addComponent(txtRegE).addComponent(lblRegDE).addComponent(txtRegDE)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(lblRegH).addComponent(txtRegH).addComponent(lblRegL).addComponent(txtRegL).addComponent(lblRegHL).addComponent(txtRegHL)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(lblRegA).addComponent(txtRegA).addComponent(lblRegF).addComponent(txtFlags).addComponent(lblRegPC).addComponent(txtRegPC)).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addGroup(paneRegistersLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(lblRegSP).addComponent(txtRegSP)).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addComponent(lblFlags).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(tblFlags)); panelRun.setBorder(BorderFactory.createTitledBorder( - new javax.swing.border.LineBorder(new java.awt.Color(153, 153, 153), 1, true), - "Run control", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, - javax.swing.border.TitledBorder.DEFAULT_POSITION, - new java.awt.Font("DejaVu Sans", Font.BOLD, 14), - new java.awt.Color(102, 102, 102))); + new javax.swing.border.LineBorder(new java.awt.Color(153, 153, 153), 1, true), + "Run control", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, + javax.swing.border.TitledBorder.DEFAULT_POSITION, + new java.awt.Font("DejaVu Sans", Font.BOLD, 14), + new java.awt.Color(102, 102, 102))); lblRun.setFont(lblRun.getFont().deriveFont(lblRun.getFont().getStyle() | java.awt.Font.BOLD)); lblRun.setForeground(new java.awt.Color(0, 102, 0)); @@ -246,74 +264,54 @@ private void initComponents() { GroupLayout panelRunLayout = new GroupLayout(panelRun); panelRun.setLayout(panelRunLayout); panelRunLayout.setHorizontalGroup( - panelRunLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelRunLayout.createSequentialGroup() - .addContainerGap().addComponent(lblRun).addContainerGap() - ).addGroup(panelRunLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblCPUFreq) - ).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(spnFrequency) - ).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblKHZ) - ).addContainerGap() - ).addGroup(panelRunLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblRuntimeFreq) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblFrequency).addContainerGap() - ).addGroup(panelRunLayout.createSequentialGroup() - .addContainerGap() - .addComponent(chkPrintInstructions) - .addContainerGap() - ) + panelRunLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelRunLayout.createSequentialGroup() + .addContainerGap().addComponent(lblRun).addContainerGap() + ).addGroup(panelRunLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblCPUFreq) + ).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(spnFrequency) + ).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblKHZ) + ).addContainerGap() + ).addGroup(panelRunLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblRuntimeFreq) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblFrequency).addContainerGap() + ).addGroup(panelRunLayout.createSequentialGroup() + .addContainerGap() + .addComponent(chkPrintInstructions) + .addContainerGap() + ) ); panelRunLayout.setVerticalGroup( - panelRunLayout.createSequentialGroup().addContainerGap().addComponent(lblRun) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.BASELINE, false) - .addComponent(lblCPUFreq) - .addComponent(spnFrequency, GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE) - .addComponent(lblKHZ) - ).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblRuntimeFreq) - .addComponent(lblFrequency) - ).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(chkPrintInstructions) - ).addContainerGap() + panelRunLayout.createSequentialGroup().addContainerGap().addComponent(lblRun) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.BASELINE, false) + .addComponent(lblCPUFreq) + .addComponent(spnFrequency, GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE) + .addComponent(lblKHZ) + ).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblRuntimeFreq) + .addComponent(lblFrequency) + ).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(panelRunLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(chkPrintInstructions) + ).addContainerGap() ); GroupLayout layout = new GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(paneRegisters, 10, 290, Short.MAX_VALUE).addComponent(panelRun, 10, 290, Short.MAX_VALUE)); + layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(paneRegisters, 10, 290, Short.MAX_VALUE).addComponent(panelRun, 10, 290, Short.MAX_VALUE)); layout.setVerticalGroup( - layout.createSequentialGroup().addComponent(paneRegisters, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addComponent(panelRun, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addContainerGap()); - }// - - // Variables declaration - do not modify//GEN-BEGIN:variables - JLabel lblFrequency; - JLabel lblRun; - JSpinner spnFrequency; - JTable tblFlags; - JTextField txtFlags; - JTextField txtRegA; - JTextField txtRegB; - JTextField txtRegBC; - JTextField txtRegC; - JTextField txtRegD; - JTextField txtRegDE; - JTextField txtRegE; - JTextField txtRegH; - JTextField txtRegHL; - JTextField txtRegL; - JTextField txtRegPC; - JTextField txtRegSP; - JCheckBox chkPrintInstructions; + layout.createSequentialGroup().addComponent(paneRegisters, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED).addComponent(panelRun, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addContainerGap()); + }// // End of variables declaration//GEN-END:variables } diff --git a/plugins/cpu/8080-cpu/src/main/resources/net/emustudio/plugins/cpu/intel8080/version.properties b/plugins/cpu/8080-cpu/src/main/resources/net/emustudio/plugins/cpu/intel8080/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/cpu/8080-cpu/src/main/resources/net/emustudio/plugins/cpu/intel8080/version.properties +++ b/plugins/cpu/8080-cpu/src/main/resources/net/emustudio/plugins/cpu/intel8080/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/ArithmeticTest.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/ArithmeticTest.java index 17eb2b8b9..b61f6e54e 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/ArithmeticTest.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/ArithmeticTest.java @@ -31,18 +31,18 @@ public class ArithmeticTest extends InstructionsTest { private ByteTestBuilder additionTestBuilder() { return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()) + .keepCurrentInjectorsAfterRun(); } private ByteTestBuilder subtractionTestBuilder() { return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()) + .keepCurrentInjectorsAfterRun(); } @Test @@ -50,16 +50,16 @@ public void testADD() { ByteTestBuilder test = additionTestBuilder(); Generator.forSome8bitBinaryWhichEqual( - test.run(0x87) + test.run(0x87) ); Generator.forSome8bitBinary( - test.secondIsRegister(EmulatorEngine.REG_B).run(0x80), - test.secondIsRegister(EmulatorEngine.REG_C).run(0x81), - test.secondIsRegister(EmulatorEngine.REG_D).run(0x82), - test.secondIsRegister(EmulatorEngine.REG_E).run(0x83), - test.secondIsRegister(EmulatorEngine.REG_H).run(0x84), - test.secondIsRegister(EmulatorEngine.REG_L).run(0x85), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x86) + test.secondIsRegister(EmulatorEngine.REG_B).run(0x80), + test.secondIsRegister(EmulatorEngine.REG_C).run(0x81), + test.secondIsRegister(EmulatorEngine.REG_D).run(0x82), + test.secondIsRegister(EmulatorEngine.REG_E).run(0x83), + test.secondIsRegister(EmulatorEngine.REG_H).run(0x84), + test.secondIsRegister(EmulatorEngine.REG_L).run(0x85), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x86) ); } @@ -68,41 +68,41 @@ public void testADI() { ByteTestBuilder test = additionTestBuilder(); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xC6) + test.runWithSecondOperand(0xC6) ); } @Test public void testADC() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & 1)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( - test.run(0x8F) + test.run(0x8F) ); Generator.forSome8bitBinary( - test.secondIsRegister(EmulatorEngine.REG_B).run(0x88), - test.secondIsRegister(EmulatorEngine.REG_C).run(0x89), - test.secondIsRegister(EmulatorEngine.REG_D).run(0x8A), - test.secondIsRegister(EmulatorEngine.REG_E).run(0x8B), - test.secondIsRegister(EmulatorEngine.REG_H).run(0x8C), - test.secondIsRegister(EmulatorEngine.REG_L).run(0x8D), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x8E) + test.secondIsRegister(EmulatorEngine.REG_B).run(0x88), + test.secondIsRegister(EmulatorEngine.REG_C).run(0x89), + test.secondIsRegister(EmulatorEngine.REG_D).run(0x8A), + test.secondIsRegister(EmulatorEngine.REG_E).run(0x8B), + test.secondIsRegister(EmulatorEngine.REG_H).run(0x8C), + test.secondIsRegister(EmulatorEngine.REG_L).run(0x8D), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x8E) ); } @Test public void testACI() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & 1)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xCE) + test.runWithSecondOperand(0xCE) ); } @@ -111,16 +111,16 @@ public void testSUB() { ByteTestBuilder test = subtractionTestBuilder(); Generator.forSome8bitBinaryWhichEqual( - test.run(0x97) + test.run(0x97) ); Generator.forSome8bitBinary( - test.secondIsRegister(EmulatorEngine.REG_B).run(0x90), - test.secondIsRegister(EmulatorEngine.REG_C).run(0x91), - test.secondIsRegister(EmulatorEngine.REG_D).run(0x92), - test.secondIsRegister(EmulatorEngine.REG_E).run(0x93), - test.secondIsRegister(EmulatorEngine.REG_H).run(0x94), - test.secondIsRegister(EmulatorEngine.REG_L).run(0x95), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x96) + test.secondIsRegister(EmulatorEngine.REG_B).run(0x90), + test.secondIsRegister(EmulatorEngine.REG_C).run(0x91), + test.secondIsRegister(EmulatorEngine.REG_D).run(0x92), + test.secondIsRegister(EmulatorEngine.REG_E).run(0x93), + test.secondIsRegister(EmulatorEngine.REG_H).run(0x94), + test.secondIsRegister(EmulatorEngine.REG_L).run(0x95), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x96) ); } @@ -129,126 +129,126 @@ public void testSUI() { ByteTestBuilder test = subtractionTestBuilder(); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xD6) + test.runWithSecondOperand(0xD6) ); } @Test public void testSBB() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & 1)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( - test.run(0x9F) + test.run(0x9F) ); Generator.forSome8bitBinary( - test.secondIsRegister(EmulatorEngine.REG_B).run(0x98), - test.secondIsRegister(EmulatorEngine.REG_C).run(0x99), - test.secondIsRegister(EmulatorEngine.REG_D).run(0x9A), - test.secondIsRegister(EmulatorEngine.REG_E).run(0x9B), - test.secondIsRegister(EmulatorEngine.REG_H).run(0x9C), - test.secondIsRegister(EmulatorEngine.REG_L).run(0x9D), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x9E) + test.secondIsRegister(EmulatorEngine.REG_B).run(0x98), + test.secondIsRegister(EmulatorEngine.REG_C).run(0x99), + test.secondIsRegister(EmulatorEngine.REG_D).run(0x9A), + test.secondIsRegister(EmulatorEngine.REG_E).run(0x9B), + test.secondIsRegister(EmulatorEngine.REG_H).run(0x9C), + test.secondIsRegister(EmulatorEngine.REG_L).run(0x9D), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x9E) ); } @Test public void testSBI() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & 1)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().auxCarry().parity()); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xDE) + test.runWithSecondOperand(0xDE) ); } @Test public void testINR() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyFlags(new FlagsCheckImpl().sign().zero().parity().auxCarry(), context -> context.first + 1) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .verifyFlags(new FlagsCheckImpl().sign().zero().parity().auxCarry(), context -> context.first + 1) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome8bitUnary( - test.verifyRegister(EmulatorEngine.REG_B).firstIsRegister(EmulatorEngine.REG_B).run(0x04), - test.verifyRegister(EmulatorEngine.REG_C).firstIsRegister(EmulatorEngine.REG_C).run(0x0C), - test.verifyRegister(EmulatorEngine.REG_D).firstIsRegister(EmulatorEngine.REG_D).run(0x14), - test.verifyRegister(EmulatorEngine.REG_E).firstIsRegister(EmulatorEngine.REG_E).run(0x1C), - test.verifyRegister(EmulatorEngine.REG_H).firstIsRegister(EmulatorEngine.REG_H).run(0x24), - test.verifyRegister(EmulatorEngine.REG_L).firstIsRegister(EmulatorEngine.REG_L).run(0x2C), - test.verifyRegister(EmulatorEngine.REG_A).firstIsRegister(EmulatorEngine.REG_A).run(0x3C), - test.verifyByte(1).setPair(REG_PAIR_HL, 1).firstIsMemoryByteAt(1).run(0x34) + test.verifyRegister(EmulatorEngine.REG_B).firstIsRegister(EmulatorEngine.REG_B).run(0x04), + test.verifyRegister(EmulatorEngine.REG_C).firstIsRegister(EmulatorEngine.REG_C).run(0x0C), + test.verifyRegister(EmulatorEngine.REG_D).firstIsRegister(EmulatorEngine.REG_D).run(0x14), + test.verifyRegister(EmulatorEngine.REG_E).firstIsRegister(EmulatorEngine.REG_E).run(0x1C), + test.verifyRegister(EmulatorEngine.REG_H).firstIsRegister(EmulatorEngine.REG_H).run(0x24), + test.verifyRegister(EmulatorEngine.REG_L).firstIsRegister(EmulatorEngine.REG_L).run(0x2C), + test.verifyRegister(EmulatorEngine.REG_A).firstIsRegister(EmulatorEngine.REG_A).run(0x3C), + test.verifyByte(1).setPair(REG_PAIR_HL, 1).firstIsMemoryByteAt(1).run(0x34) ); } @Test public void testDCR() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyFlags(new FlagsCheckImpl().sign().zero().parity().auxCarry(), context -> context.first - 1) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .verifyFlags(new FlagsCheckImpl().sign().zero().parity().auxCarry(), context -> context.first - 1) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome8bitUnary( - test.verifyRegister(EmulatorEngine.REG_B).firstIsRegister(EmulatorEngine.REG_B).run(0x05), - test.verifyRegister(EmulatorEngine.REG_C).firstIsRegister(EmulatorEngine.REG_C).run(0x0D), - test.verifyRegister(EmulatorEngine.REG_D).firstIsRegister(EmulatorEngine.REG_D).run(0x15), - test.verifyRegister(EmulatorEngine.REG_E).firstIsRegister(EmulatorEngine.REG_E).run(0x1D), - test.verifyRegister(EmulatorEngine.REG_H).firstIsRegister(EmulatorEngine.REG_H).run(0x25), - test.verifyRegister(EmulatorEngine.REG_L).firstIsRegister(EmulatorEngine.REG_L).run(0x2D), - test.verifyRegister(EmulatorEngine.REG_A).firstIsRegister(EmulatorEngine.REG_A).run(0x3D), - test.verifyByte(1).setPair(REG_PAIR_HL, 1).firstIsMemoryByteAt(1).run(0x35) + test.verifyRegister(EmulatorEngine.REG_B).firstIsRegister(EmulatorEngine.REG_B).run(0x05), + test.verifyRegister(EmulatorEngine.REG_C).firstIsRegister(EmulatorEngine.REG_C).run(0x0D), + test.verifyRegister(EmulatorEngine.REG_D).firstIsRegister(EmulatorEngine.REG_D).run(0x15), + test.verifyRegister(EmulatorEngine.REG_E).firstIsRegister(EmulatorEngine.REG_E).run(0x1D), + test.verifyRegister(EmulatorEngine.REG_H).firstIsRegister(EmulatorEngine.REG_H).run(0x25), + test.verifyRegister(EmulatorEngine.REG_L).firstIsRegister(EmulatorEngine.REG_L).run(0x2D), + test.verifyRegister(EmulatorEngine.REG_A).firstIsRegister(EmulatorEngine.REG_A).run(0x3D), + test.verifyByte(1).setPair(REG_PAIR_HL, 1).firstIsMemoryByteAt(1).run(0x35) ); } @Test public void testINX() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .clearOtherVerifiersAfterRun(); + .clearOtherVerifiersAfterRun(); Function, Integer> verifier = context -> context.first + 1; Generator.forSome16bitUnary( - test.verifyPair(REG_PAIR_BC, verifier).firstIsPair(REG_PAIR_BC).run(0x03), - test.verifyPair(REG_PAIR_DE, verifier).firstIsPair(REG_PAIR_DE).run(0x13), - test.verifyPair(REG_PAIR_HL, verifier).firstIsPair(REG_PAIR_HL).run(0x23), - test.verifyPair(REG_SP, verifier).firstIsPair(REG_SP).run(0x33) + test.verifyPair(REG_PAIR_BC, verifier).firstIsPair(REG_PAIR_BC).run(0x03), + test.verifyPair(REG_PAIR_DE, verifier).firstIsPair(REG_PAIR_DE).run(0x13), + test.verifyPair(REG_PAIR_HL, verifier).firstIsPair(REG_PAIR_HL).run(0x23), + test.verifyPair(REG_SP, verifier).firstIsPair(REG_SP).run(0x33) ); } @Test public void testDCX() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .clearOtherVerifiersAfterRun(); + .clearOtherVerifiersAfterRun(); Function, Integer> verifier = context -> context.first - 1; Generator.forSome16bitUnary( - test.verifyPair(REG_PAIR_BC, verifier).firstIsPair(REG_PAIR_BC).run(0x0B), - test.verifyPair(REG_PAIR_DE, verifier).firstIsPair(REG_PAIR_DE).run(0x1B), - test.verifyPair(REG_PAIR_HL, verifier).firstIsPair(REG_PAIR_HL).run(0x2B), - test.verifyPair(REG_SP, verifier).firstIsPair(REG_SP).run(0x3B) + test.verifyPair(REG_PAIR_BC, verifier).firstIsPair(REG_PAIR_BC).run(0x0B), + test.verifyPair(REG_PAIR_DE, verifier).firstIsPair(REG_PAIR_DE).run(0x1B), + test.verifyPair(REG_PAIR_HL, verifier).firstIsPair(REG_PAIR_HL).run(0x2B), + test.verifyPair(REG_SP, verifier).firstIsPair(REG_SP).run(0x3B) ); } @Test public void testDAD() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsPair(REG_PAIR_HL) - .verifyPair(REG_PAIR_HL, context -> context.first + context.second) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carry15()) - .keepCurrentInjectorsAfterRun(); + .firstIsPair(REG_PAIR_HL) + .verifyPair(REG_PAIR_HL, context -> context.first + context.second) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carry15()) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( - test.run(0x29) + test.run(0x29) ); Generator.forSome16bitBinary( - test.secondIsPair(REG_PAIR_BC).run(0x09), - test.secondIsPair(REG_PAIR_DE).run(0x19), - test.secondIsPair(REG_SP).run(0x39) + test.secondIsPair(REG_PAIR_BC).run(0x09), + test.secondIsPair(REG_PAIR_DE).run(0x19), + test.secondIsPair(REG_SP).run(0x39) ); } } diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/ControlTest.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/ControlTest.java index 2db122c41..93220ef4b 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/ControlTest.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/ControlTest.java @@ -38,102 +38,102 @@ public void testEI_DI() { @Test public void testJMP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyPC(context -> context.first) - .keepCurrentInjectorsAfterRun(); + .verifyPC(context -> context.first) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitUnary( - test.runWithFirstOperand(0xC3), - test.runWithFirstOperand(0xC2), - test.setFlags(EmulatorEngine.FLAG_Z).runWithFirstOperand(0xCA), - test.runWithFirstOperand(0xD2), - test.setFlags(EmulatorEngine.FLAG_C).runWithFirstOperand(0xDA), - test.runWithFirstOperand(0xE2), - test.setFlags(EmulatorEngine.FLAG_P).runWithFirstOperand(0xEA), - test.runWithFirstOperand(0xF2), - test.setFlags(EmulatorEngine.FLAG_S).runWithFirstOperand(0xFA) + test.runWithFirstOperand(0xC3), + test.runWithFirstOperand(0xC2), + test.setFlags(EmulatorEngine.FLAG_Z).runWithFirstOperand(0xCA), + test.runWithFirstOperand(0xD2), + test.setFlags(EmulatorEngine.FLAG_C).runWithFirstOperand(0xDA), + test.runWithFirstOperand(0xE2), + test.setFlags(EmulatorEngine.FLAG_P).runWithFirstOperand(0xEA), + test.runWithFirstOperand(0xF2), + test.setFlags(EmulatorEngine.FLAG_S).runWithFirstOperand(0xFA) ); test.clearAllVerifiers().verifyPC(context -> (context.PC + 3) & 0xFFFF); Generator.forSome16bitUnary( - test.setFlags(EmulatorEngine.FLAG_Z).runWithFirstOperand(0xC2), - test.runWithFirstOperand(0xCA), - test.setFlags(EmulatorEngine.FLAG_C).runWithFirstOperand(0xD2), - test.runWithFirstOperand(0xDA), - test.setFlags(EmulatorEngine.FLAG_P).runWithFirstOperand(0xE2), - test.runWithFirstOperand(0xEA), - test.setFlags(EmulatorEngine.FLAG_S).runWithFirstOperand(0xF2), - test.runWithFirstOperand(0xFA) + test.setFlags(EmulatorEngine.FLAG_Z).runWithFirstOperand(0xC2), + test.runWithFirstOperand(0xCA), + test.setFlags(EmulatorEngine.FLAG_C).runWithFirstOperand(0xD2), + test.runWithFirstOperand(0xDA), + test.setFlags(EmulatorEngine.FLAG_P).runWithFirstOperand(0xE2), + test.runWithFirstOperand(0xEA), + test.setFlags(EmulatorEngine.FLAG_S).runWithFirstOperand(0xF2), + test.runWithFirstOperand(0xFA) ); } @Test public void testCALL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyPC(context -> context.second) - .verifyWord(context -> context.first - 2, context -> context.PC + 3) - .firstIsPair(REG_SP) - .keepCurrentInjectorsAfterRun(); + .verifyPC(context -> context.second) + .verifyWord(context -> context.first - 2, context -> context.PC + 3) + .firstIsPair(REG_SP) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(3, - test.runWithSecondOperand(0xCD), - test.runWithSecondOperand(0xC4), - test.setFlags(EmulatorEngine.FLAG_Z).runWithSecondOperand(0xCC), - test.runWithSecondOperand(0xD4), - test.setFlags(EmulatorEngine.FLAG_C).runWithSecondOperand(0xDC), - test.runWithSecondOperand(0xE4), - test.setFlags(EmulatorEngine.FLAG_P).runWithSecondOperand(0xEC), - test.runWithSecondOperand(0xF4), - test.setFlags(EmulatorEngine.FLAG_S).runWithSecondOperand(0xFC) + test.runWithSecondOperand(0xCD), + test.runWithSecondOperand(0xC4), + test.setFlags(EmulatorEngine.FLAG_Z).runWithSecondOperand(0xCC), + test.runWithSecondOperand(0xD4), + test.setFlags(EmulatorEngine.FLAG_C).runWithSecondOperand(0xDC), + test.runWithSecondOperand(0xE4), + test.setFlags(EmulatorEngine.FLAG_P).runWithSecondOperand(0xEC), + test.runWithSecondOperand(0xF4), + test.setFlags(EmulatorEngine.FLAG_S).runWithSecondOperand(0xFC) ); test.clearAllVerifiers().verifyPC(context -> (context.PC + 3) & 0xFFFF); Generator.forSome16bitBinary(3, - test.setFlags(EmulatorEngine.FLAG_Z).runWithSecondOperand(0xC4), - test.runWithSecondOperand(0xCC), - test.setFlags(EmulatorEngine.FLAG_C).runWithSecondOperand(0xD4), - test.runWithSecondOperand(0xDC), - test.setFlags(EmulatorEngine.FLAG_P).runWithSecondOperand(0xE4), - test.runWithSecondOperand(0xEC), - test.setFlags(EmulatorEngine.FLAG_S).runWithSecondOperand(0xF4), - test.runWithSecondOperand(0xFC) + test.setFlags(EmulatorEngine.FLAG_Z).runWithSecondOperand(0xC4), + test.runWithSecondOperand(0xCC), + test.setFlags(EmulatorEngine.FLAG_C).runWithSecondOperand(0xD4), + test.runWithSecondOperand(0xDC), + test.setFlags(EmulatorEngine.FLAG_P).runWithSecondOperand(0xE4), + test.runWithSecondOperand(0xEC), + test.setFlags(EmulatorEngine.FLAG_S).runWithSecondOperand(0xF4), + test.runWithSecondOperand(0xFC) ); } @Test public void testRET() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyPair(REG_SP, context -> context.first + 2) - .verifyPC(context -> context.second) - .firstIsPair(REG_SP) - .firstIsAddressAndSecondIsMemoryWord() - .keepCurrentInjectorsAfterRun(); + .verifyPair(REG_SP, context -> context.first + 2) + .verifyPC(context -> context.second) + .firstIsPair(REG_SP) + .firstIsAddressAndSecondIsMemoryWord() + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(2, - test.run(0xC9), - test.run(0xC0), - test.setFlags(EmulatorEngine.FLAG_Z).run(0xC8), - test.run(0xD0), - test.setFlags(EmulatorEngine.FLAG_C).run(0xD8), - test.run(0xE0), - test.setFlags(EmulatorEngine.FLAG_P).run(0xE8), - test.run(0xF0), - test.setFlags(EmulatorEngine.FLAG_S).run(0xF8) + test.run(0xC9), + test.run(0xC0), + test.setFlags(EmulatorEngine.FLAG_Z).run(0xC8), + test.run(0xD0), + test.setFlags(EmulatorEngine.FLAG_C).run(0xD8), + test.run(0xE0), + test.setFlags(EmulatorEngine.FLAG_P).run(0xE8), + test.run(0xF0), + test.setFlags(EmulatorEngine.FLAG_S).run(0xF8) ); // negative tests test.clearAllVerifiers() - .verifyPC(context -> 1) - .verifyPair(REG_SP, context -> context.first); + .verifyPC(context -> 1) + .verifyPair(REG_SP, context -> context.first); Generator.forSome16bitBinary(2, - test.setFlags(EmulatorEngine.FLAG_Z).run(0xC0), - test.run(0xC8), - test.setFlags(EmulatorEngine.FLAG_C).run(0xD0), - test.run(0xD8), - test.setFlags(EmulatorEngine.FLAG_P).run(0xE0), - test.run(0xE8), - test.setFlags(EmulatorEngine.FLAG_S).run(0xF0), - test.run(0xF8) + test.setFlags(EmulatorEngine.FLAG_Z).run(0xC0), + test.run(0xC8), + test.setFlags(EmulatorEngine.FLAG_C).run(0xD0), + test.run(0xD8), + test.setFlags(EmulatorEngine.FLAG_P).run(0xE0), + test.run(0xE8), + test.setFlags(EmulatorEngine.FLAG_S).run(0xF0), + test.run(0xF8) ); } @@ -141,32 +141,32 @@ public void testRET() { @Test public void testRST() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsPair(REG_SP) - .verifyPair(REG_SP, context -> context.first - 2) - .verifyWord(context -> context.SP - 2, context -> 1) - .clearOtherVerifiersAfterRun() - .keepCurrentInjectorsAfterRun(); + .firstIsPair(REG_SP) + .verifyPair(REG_SP, context -> context.first - 2) + .verifyWord(context -> context.SP - 2, context -> 1) + .clearOtherVerifiersAfterRun() + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitUnary(3, - test.verifyPC(context -> 0).run(0xC7), - test.verifyPC(context -> 0x8).run(0xCF), - test.verifyPC(context -> 0x10).run(0xD7), - test.verifyPC(context -> 0x18).run(0xDF), - test.verifyPC(context -> 0x20).run(0xE7), - test.verifyPC(context -> 0x28).run(0xEF), - test.verifyPC(context -> 0x30).run(0xF7), - test.verifyPC(context -> 0x38).run(0xFF) + test.verifyPC(context -> 0).run(0xC7), + test.verifyPC(context -> 0x8).run(0xCF), + test.verifyPC(context -> 0x10).run(0xD7), + test.verifyPC(context -> 0x18).run(0xDF), + test.verifyPC(context -> 0x20).run(0xE7), + test.verifyPC(context -> 0x28).run(0xEF), + test.verifyPC(context -> 0x30).run(0xF7), + test.verifyPC(context -> 0x38).run(0xFF) ); } @Test public void testPCHL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsPair(REG_PAIR_HL) - .verifyPC(context -> context.first); + .firstIsPair(REG_PAIR_HL) + .verifyPC(context -> context.first); Generator.forSome16bitUnary( - test.run(0xE9) + test.run(0xE9) ); } diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/CpuImplTest.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/CpuImplTest.java index 576d51990..a76cfe974 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/CpuImplTest.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/CpuImplTest.java @@ -25,9 +25,7 @@ import org.junit.Before; import org.junit.Test; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.createNiceMock; +import static org.easymock.EasyMock.*; import static org.junit.Assert.assertNotEquals; public class CpuImplTest { diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/InstructionsTest.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/InstructionsTest.java index eace29948..9d321eaf7 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/InstructionsTest.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/InstructionsTest.java @@ -24,8 +24,8 @@ import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.cpu.intel8080.suite.CpuRunnerImpl; import net.emustudio.plugins.cpu.intel8080.suite.CpuVerifierImpl; import org.junit.After; @@ -34,17 +34,15 @@ import static org.easymock.EasyMock.*; public class InstructionsTest { - private static final long PLUGIN_ID = 0L; - public static final int REG_PAIR_BC = 0; - static final int REG_PAIR_DE = 1; public static final int REG_PAIR_HL = 2; public static final int REG_SP = 3; + static final int REG_PAIR_DE = 1; static final int REG_PSW = 3; - - private CpuImpl cpu; + private static final long PLUGIN_ID = 0L; protected CpuRunnerImpl cpuRunnerImpl; protected CpuVerifierImpl cpuVerifierImpl; + private CpuImpl cpu; @SuppressWarnings("unchecked") @Before @@ -53,8 +51,8 @@ public void setUp() throws PluginInitializationException { ContextPool contextPool = createNiceMock(ContextPool.class); expect(contextPool.getMemoryContext(0, MemoryContext.class)) - .andReturn(memoryStub) - .anyTimes(); + .andReturn(memoryStub) + .anyTimes(); replay(contextPool); ApplicationApi applicationApi = createNiceMock(ApplicationApi.class); diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/LogicTest.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/LogicTest.java index dbd18da6a..5a32f205b 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/LogicTest.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/LogicTest.java @@ -30,10 +30,10 @@ public class LogicTest extends InstructionsTest { private ByteTestBuilder logicTest(Function, Integer> operation) { return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, operation) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().parity().carryIsReset().auxCarryIsReset()) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, operation) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().parity().carryIsReset().auxCarryIsReset()) + .keepCurrentInjectorsAfterRun(); } @Test @@ -41,16 +41,16 @@ public void testANA() { ByteTestBuilder test = logicTest(context -> context.first & context.second); Generator.forSome8bitBinaryWhichEqual( - test.run(0xA7) + test.run(0xA7) ); Generator.forSome8bitBinary( - test.secondIsRegister(EmulatorEngine.REG_B).run(0xA0), - test.secondIsRegister(EmulatorEngine.REG_C).run(0xA1), - test.secondIsRegister(EmulatorEngine.REG_D).run(0xA2), - test.secondIsRegister(EmulatorEngine.REG_E).run(0xA3), - test.secondIsRegister(EmulatorEngine.REG_H).run(0xA4), - test.secondIsRegister(EmulatorEngine.REG_L).run(0xA5), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0xA6) + test.secondIsRegister(EmulatorEngine.REG_B).run(0xA0), + test.secondIsRegister(EmulatorEngine.REG_C).run(0xA1), + test.secondIsRegister(EmulatorEngine.REG_D).run(0xA2), + test.secondIsRegister(EmulatorEngine.REG_E).run(0xA3), + test.secondIsRegister(EmulatorEngine.REG_H).run(0xA4), + test.secondIsRegister(EmulatorEngine.REG_L).run(0xA5), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0xA6) ); } @@ -59,7 +59,7 @@ public void testANI() { ByteTestBuilder test = logicTest(context -> context.first & context.second); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xE6) + test.runWithSecondOperand(0xE6) ); } @@ -68,16 +68,16 @@ public void testXRA() { ByteTestBuilder test = logicTest(context -> context.first ^ context.second); Generator.forSome8bitBinaryWhichEqual( - test.run(0xAF) + test.run(0xAF) ); Generator.forSome8bitBinary( - test.secondIsRegister(EmulatorEngine.REG_B).run(0xA8), - test.secondIsRegister(EmulatorEngine.REG_C).run(0xA9), - test.secondIsRegister(EmulatorEngine.REG_D).run(0xAA), - test.secondIsRegister(EmulatorEngine.REG_E).run(0xAB), - test.secondIsRegister(EmulatorEngine.REG_H).run(0xAC), - test.secondIsRegister(EmulatorEngine.REG_L).run(0xAD), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0xAE) + test.secondIsRegister(EmulatorEngine.REG_B).run(0xA8), + test.secondIsRegister(EmulatorEngine.REG_C).run(0xA9), + test.secondIsRegister(EmulatorEngine.REG_D).run(0xAA), + test.secondIsRegister(EmulatorEngine.REG_E).run(0xAB), + test.secondIsRegister(EmulatorEngine.REG_H).run(0xAC), + test.secondIsRegister(EmulatorEngine.REG_L).run(0xAD), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0xAE) ); } @@ -86,7 +86,7 @@ public void testXRI() { ByteTestBuilder test = logicTest(context -> context.first ^ context.second); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xEE) + test.runWithSecondOperand(0xEE) ); } @@ -95,16 +95,16 @@ public void testORA() { ByteTestBuilder test = logicTest(context -> context.first | context.second); Generator.forSome8bitBinaryWhichEqual( - test.run(0xB7) + test.run(0xB7) ); Generator.forSome8bitBinary( - test.secondIsRegister(EmulatorEngine.REG_B).run(0xB0), - test.secondIsRegister(EmulatorEngine.REG_C).run(0xB1), - test.secondIsRegister(EmulatorEngine.REG_D).run(0xB2), - test.secondIsRegister(EmulatorEngine.REG_E).run(0xB3), - test.secondIsRegister(EmulatorEngine.REG_H).run(0xB4), - test.secondIsRegister(EmulatorEngine.REG_L).run(0xB5), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0xB6) + test.secondIsRegister(EmulatorEngine.REG_B).run(0xB0), + test.secondIsRegister(EmulatorEngine.REG_C).run(0xB1), + test.secondIsRegister(EmulatorEngine.REG_D).run(0xB2), + test.secondIsRegister(EmulatorEngine.REG_E).run(0xB3), + test.secondIsRegister(EmulatorEngine.REG_H).run(0xB4), + test.secondIsRegister(EmulatorEngine.REG_L).run(0xB5), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0xB6) ); } @@ -113,45 +113,45 @@ public void testORI() { Function, Integer> op = context -> context.first | context.second; Generator.forSome8bitBinary( - logicTest(op).runWithSecondOperand(0xF6) + logicTest(op).runWithSecondOperand(0xF6) ); } @Test public void testDAA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(EmulatorEngine.REG_A, context -> { - int result = ((int) context.first) & 0xFF; - if (((context.flags & EmulatorEngine.FLAG_AC) == EmulatorEngine.FLAG_AC) || (result & 0x0F) > 9) { - result += 6; - } - if ((context.flags & EmulatorEngine.FLAG_C) == EmulatorEngine.FLAG_C || (result & 0xF0) > 0x90) { - result += 0x60; - } - return result; - }) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().parity().carry() - .expectFlagOnlyWhen(EmulatorEngine.FLAG_AC, (context, result) -> { - int firstInt = context.first.intValue(); - int diff = (result.intValue() - firstInt) & 0x0F; - - return ((diff == 6) && FlagsCheckImpl.isAuxCarry(firstInt, 6)); - })) - .firstIsRegister(EmulatorEngine.REG_A); + .verifyRegister(EmulatorEngine.REG_A, context -> { + int result = ((int) context.first) & 0xFF; + if (((context.flags & EmulatorEngine.FLAG_AC) == EmulatorEngine.FLAG_AC) || (result & 0x0F) > 9) { + result += 6; + } + if ((context.flags & EmulatorEngine.FLAG_C) == EmulatorEngine.FLAG_C || (result & 0xF0) > 0x90) { + result += 0x60; + } + return result; + }) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().parity().carry() + .expectFlagOnlyWhen(EmulatorEngine.FLAG_AC, (context, result) -> { + int firstInt = context.first.intValue(); + int diff = (result.intValue() - firstInt) & 0x0F; + + return ((diff == 6) && FlagsCheckImpl.isAuxCarry(firstInt, 6)); + })) + .firstIsRegister(EmulatorEngine.REG_A); Generator.forSome8bitUnary( - test.run(0x27) + test.run(0x27) ); } @Test public void testCMA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(EmulatorEngine.REG_A, context -> (~context.first) & 0xFF) - .firstIsRegister(EmulatorEngine.REG_A); + .verifyRegister(EmulatorEngine.REG_A, context -> (~context.first) & 0xFF) + .firstIsRegister(EmulatorEngine.REG_A); Generator.forSome8bitUnary( - test.run(0x2F) + test.run(0x2F) ); } @@ -178,72 +178,72 @@ public void testCMC() { @Test public void testRLC() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> (context.first << 1) | ((context.first >>> 7) & 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsFirstOperandMSB()); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> (context.first << 1) | ((context.first >>> 7) & 1)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsFirstOperandMSB()); Generator.forSome8bitUnary( - test.run(0x07) + test.run(0x07) ); } @Test public void testRRC() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> (((context.first & 0xFF) >>> 1) | ((context.first & 1) << 7)) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsFirstOperandLSB()); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> (((context.first & 0xFF) >>> 1) | ((context.first & 1) << 7)) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsFirstOperandLSB()); Generator.forSome8bitUnary( - test.run(0x0F) + test.run(0x0F) ); } @Test public void testRAL() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> (context.first << 1) | (context.flags & 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsFirstOperandMSB()); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> (context.first << 1) | (context.flags & 1)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsFirstOperandMSB()); Generator.forSome8bitUnary( - test.run(0x17) + test.run(0x17) ); } @Test public void testRAR() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> (((context.first & 0xFF) >>> 1) | ((context.flags & 1) << 7)) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsFirstOperandLSB()); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> (((context.first & 0xFF) >>> 1) | ((context.flags & 1) << 7)) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl().carryIsFirstOperandLSB()); Generator.forSome8bitUnary( - test.run(0x1F) + test.run(0x1F) ); } @Test public void testCMP() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> context.first.intValue()) - .verifyFlags( - new FlagsCheckImpl().sign().zero().carry().auxCarry().parity(), - context -> (context.first & 0xFF) - (context.second & 0xFF)) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> context.first.intValue()) + .verifyFlags( + new FlagsCheckImpl().sign().zero().carry().auxCarry().parity(), + context -> (context.first & 0xFF) - (context.second & 0xFF)) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( - test.run(0xBF) + test.run(0xBF) ); Generator.forSome8bitBinary( - test.secondIsRegister(EmulatorEngine.REG_B).run(0xB8), - test.secondIsRegister(EmulatorEngine.REG_C).run(0xB9), - test.secondIsRegister(EmulatorEngine.REG_D).run(0xBA), - test.secondIsRegister(EmulatorEngine.REG_E).run(0xBB), - test.secondIsRegister(EmulatorEngine.REG_H).run(0xBC), - test.secondIsRegister(EmulatorEngine.REG_L).run(0xBD), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0xBE) + test.secondIsRegister(EmulatorEngine.REG_B).run(0xB8), + test.secondIsRegister(EmulatorEngine.REG_C).run(0xB9), + test.secondIsRegister(EmulatorEngine.REG_D).run(0xBA), + test.secondIsRegister(EmulatorEngine.REG_E).run(0xBB), + test.secondIsRegister(EmulatorEngine.REG_H).run(0xBC), + test.secondIsRegister(EmulatorEngine.REG_L).run(0xBD), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0xBE) ); } @@ -251,12 +251,12 @@ public void testCMP() { public void testCPI() { FlagsCheckImpl flagsToCheck = new FlagsCheckImpl().sign().zero().carry().auxCarry().parity(); ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(EmulatorEngine.REG_A) - .verifyRegister(EmulatorEngine.REG_A, context -> context.first.intValue()) - .verifyFlags(flagsToCheck, context -> (context.first & 0xFF) - (context.second & 0xFF)); + .firstIsRegister(EmulatorEngine.REG_A) + .verifyRegister(EmulatorEngine.REG_A, context -> context.first.intValue()) + .verifyFlags(flagsToCheck, context -> (context.first & 0xFF) - (context.second & 0xFF)); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xFE) + test.runWithSecondOperand(0xFE) ); } } diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/StackTest.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/StackTest.java index f901e0979..84406aeac 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/StackTest.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/StackTest.java @@ -30,44 +30,44 @@ public class StackTest extends InstructionsTest { @Test public void testPUSH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsPair(REG_SP) - .verifyWord(context -> context.first - 2, context -> context.second) - .keepCurrentInjectorsAfterRun(); + .firstIsPair(REG_SP) + .verifyWord(context -> context.first - 2, context -> context.second) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(2, - test.secondIsPair(REG_PAIR_BC).run(0xC5), - test.secondIsPair(REG_PAIR_DE).run(0xD5), - test.secondIsPair(REG_PAIR_HL).run(0xE5) + test.secondIsPair(REG_PAIR_BC).run(0xC5), + test.secondIsPair(REG_PAIR_DE).run(0xD5), + test.secondIsPair(REG_PAIR_HL).run(0xE5) ); } @Test public void testPUSH_PSW() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsPair(REG_SP) - .verifyWord(context -> context.first - 2, context -> context.second & 0xFFD7 | 2) - .keepCurrentInjectorsAfterRun(); + .firstIsPair(REG_SP) + .verifyWord(context -> context.first - 2, context -> context.second & 0xFFD7 | 2) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(2, - test.secondIsRegisterPairPSW(REG_PSW).run(0xF5) + test.secondIsRegisterPairPSW(REG_PSW).run(0xF5) ); } @Test public void testPOP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsPair(REG_SP) - .firstIsAddressAndSecondIsMemoryWord() - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsPair(REG_SP) + .firstIsAddressAndSecondIsMemoryWord() + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> verifier = context -> context.second; Generator.forSome16bitBinary(2, - test.verifyPair(REG_PAIR_BC, verifier).run(0xC1), - test.verifyPair(REG_PAIR_DE, verifier).run(0xD1), - test.verifyPair(REG_PAIR_HL, verifier).run(0xE1), - test.verifyPairAndPSW(REG_PSW, context -> context.second & 0xFFD7 | 2).run(0xF1) + test.verifyPair(REG_PAIR_BC, verifier).run(0xC1), + test.verifyPair(REG_PAIR_DE, verifier).run(0xD1), + test.verifyPair(REG_PAIR_HL, verifier).run(0xE1), + test.verifyPairAndPSW(REG_PSW, context -> context.second & 0xFFD7 | 2).run(0xF1) ); } } diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/TransferTest.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/TransferTest.java index 814aa153c..3591bfe2a 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/TransferTest.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/TransferTest.java @@ -31,146 +31,146 @@ public class TransferTest extends InstructionsTest { @Test public void testMVI() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .clearOtherVerifiersAfterRun(); + .clearOtherVerifiersAfterRun(); Generator.forSome8bitUnary( - test.verifyRegister(REG_A, context -> context.first & 0xFF) - .runWithFirstOperand(0x3E), - test.verifyRegister(REG_B).runWithFirstOperand(0x06), - test.verifyRegister(REG_C).runWithFirstOperand(0x0E), - test.verifyRegister(REG_D).runWithFirstOperand(0x16), - test.verifyRegister(REG_E).runWithFirstOperand(0x1E), - test.verifyRegister(REG_H).runWithFirstOperand(0x26), - test.verifyRegister(REG_L).runWithFirstOperand(0x2E), - test.setPair(REG_PAIR_HL, 0x20) - .verifyByte(0x20, context -> context.first & 0xFF) - .runWithFirstOperand(0x36) + test.verifyRegister(REG_A, context -> context.first & 0xFF) + .runWithFirstOperand(0x3E), + test.verifyRegister(REG_B).runWithFirstOperand(0x06), + test.verifyRegister(REG_C).runWithFirstOperand(0x0E), + test.verifyRegister(REG_D).runWithFirstOperand(0x16), + test.verifyRegister(REG_E).runWithFirstOperand(0x1E), + test.verifyRegister(REG_H).runWithFirstOperand(0x26), + test.verifyRegister(REG_L).runWithFirstOperand(0x2E), + test.setPair(REG_PAIR_HL, 0x20) + .verifyByte(0x20, context -> context.first & 0xFF) + .runWithFirstOperand(0x36) ); } @Test public void testMOV_A() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(REG_A, context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .verifyRegister(REG_A, context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).run(0x7F), - test.firstIsRegister(REG_B).run(0x78), - test.firstIsRegister(REG_C).run(0x79), - test.firstIsRegister(REG_D).run(0x7A), - test.firstIsRegister(REG_E).run(0x7B), - test.firstIsRegister(REG_H).run(0x7C), - test.firstIsRegister(REG_L).run(0x7D), - test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x7E) + test.firstIsRegister(REG_A).run(0x7F), + test.firstIsRegister(REG_B).run(0x78), + test.firstIsRegister(REG_C).run(0x79), + test.firstIsRegister(REG_D).run(0x7A), + test.firstIsRegister(REG_E).run(0x7B), + test.firstIsRegister(REG_H).run(0x7C), + test.firstIsRegister(REG_L).run(0x7D), + test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x7E) ); } @Test public void testMOV_B() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(REG_B, context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .verifyRegister(REG_B, context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).run(0x47), - test.firstIsRegister(REG_B).run(0x40), - test.firstIsRegister(REG_C).run(0x41), - test.firstIsRegister(REG_D).run(0x42), - test.firstIsRegister(REG_E).run(0x43), - test.firstIsRegister(REG_H).run(0x44), - test.firstIsRegister(REG_L).run(0x45), - test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x46) + test.firstIsRegister(REG_A).run(0x47), + test.firstIsRegister(REG_B).run(0x40), + test.firstIsRegister(REG_C).run(0x41), + test.firstIsRegister(REG_D).run(0x42), + test.firstIsRegister(REG_E).run(0x43), + test.firstIsRegister(REG_H).run(0x44), + test.firstIsRegister(REG_L).run(0x45), + test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x46) ); } @Test public void testMOV_C() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(REG_C, context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .verifyRegister(REG_C, context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).run(0x4F), - test.firstIsRegister(REG_B).run(0x48), - test.firstIsRegister(REG_C).run(0x49), - test.firstIsRegister(REG_D).run(0x4A), - test.firstIsRegister(REG_E).run(0x4B), - test.firstIsRegister(REG_H).run(0x4C), - test.firstIsRegister(REG_L).run(0x4D), - test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x4E) + test.firstIsRegister(REG_A).run(0x4F), + test.firstIsRegister(REG_B).run(0x48), + test.firstIsRegister(REG_C).run(0x49), + test.firstIsRegister(REG_D).run(0x4A), + test.firstIsRegister(REG_E).run(0x4B), + test.firstIsRegister(REG_H).run(0x4C), + test.firstIsRegister(REG_L).run(0x4D), + test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x4E) ); } @Test public void testMOV_D() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(REG_D, context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .verifyRegister(REG_D, context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).run(0x57), - test.firstIsRegister(REG_B).run(0x50), - test.firstIsRegister(REG_C).run(0x51), - test.firstIsRegister(REG_D).run(0x52), - test.firstIsRegister(REG_E).run(0x53), - test.firstIsRegister(REG_H).run(0x54), - test.firstIsRegister(REG_L).run(0x55), - test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x56) + test.firstIsRegister(REG_A).run(0x57), + test.firstIsRegister(REG_B).run(0x50), + test.firstIsRegister(REG_C).run(0x51), + test.firstIsRegister(REG_D).run(0x52), + test.firstIsRegister(REG_E).run(0x53), + test.firstIsRegister(REG_H).run(0x54), + test.firstIsRegister(REG_L).run(0x55), + test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x56) ); } @Test public void testMOV_E() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(REG_E, context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .verifyRegister(REG_E, context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).run(0x5F), - test.firstIsRegister(REG_B).run(0x58), - test.firstIsRegister(REG_C).run(0x59), - test.firstIsRegister(REG_D).run(0x5A), - test.firstIsRegister(REG_E).run(0x5B), - test.firstIsRegister(REG_H).run(0x5C), - test.firstIsRegister(REG_L).run(0x5D), - test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x5E) + test.firstIsRegister(REG_A).run(0x5F), + test.firstIsRegister(REG_B).run(0x58), + test.firstIsRegister(REG_C).run(0x59), + test.firstIsRegister(REG_D).run(0x5A), + test.firstIsRegister(REG_E).run(0x5B), + test.firstIsRegister(REG_H).run(0x5C), + test.firstIsRegister(REG_L).run(0x5D), + test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x5E) ); } @Test public void testMOV_H() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(REG_H, context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .verifyRegister(REG_H, context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).run(0x67), - test.firstIsRegister(REG_B).run(0x60), - test.firstIsRegister(REG_C).run(0x61), - test.firstIsRegister(REG_D).run(0x62), - test.firstIsRegister(REG_E).run(0x63), - test.firstIsRegister(REG_H).run(0x64), - test.firstIsRegister(REG_L).run(0x65), - test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x66) + test.firstIsRegister(REG_A).run(0x67), + test.firstIsRegister(REG_B).run(0x60), + test.firstIsRegister(REG_C).run(0x61), + test.firstIsRegister(REG_D).run(0x62), + test.firstIsRegister(REG_E).run(0x63), + test.firstIsRegister(REG_H).run(0x64), + test.firstIsRegister(REG_L).run(0x65), + test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x66) ); } @Test public void testMOV_L() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(REG_L, context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .verifyRegister(REG_L, context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).run(0x6F), - test.firstIsRegister(REG_B).run(0x68), - test.firstIsRegister(REG_C).run(0x69), - test.firstIsRegister(REG_D).run(0x6A), - test.firstIsRegister(REG_E).run(0x6B), - test.firstIsRegister(REG_H).run(0x6C), - test.firstIsRegister(REG_L).run(0x6D), - test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x6E) + test.firstIsRegister(REG_A).run(0x6F), + test.firstIsRegister(REG_B).run(0x68), + test.firstIsRegister(REG_C).run(0x69), + test.firstIsRegister(REG_D).run(0x6A), + test.firstIsRegister(REG_E).run(0x6B), + test.firstIsRegister(REG_H).run(0x6C), + test.firstIsRegister(REG_L).run(0x6D), + test.setPair(REG_PAIR_HL, 0x20).firstIsMemoryByteAt(0x20).run(0x6E) ); } @@ -179,15 +179,15 @@ public void testMOV_M_r() { final int address = 0x35; ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyByte(address, context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .verifyByte(address, context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_A).run(0x77), - test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_B).run(0x70), - test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_C).run(0x71), - test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_D).run(0x72), - test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_E).run(0x73) + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_A).run(0x77), + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_B).run(0x70), + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_C).run(0x71), + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_D).run(0x72), + test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_E).run(0x73) ); test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_H).run(0x74).accept((byte) 0, (byte) 0); test.setPair(REG_PAIR_HL, address).firstIsRegister(REG_L).run(0x75).accept((byte) address, (byte) 0); @@ -198,13 +198,13 @@ public void testLDAX() { final int value = 0x25; IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(REG_A, context -> value) - .firstIsMemoryAddressByte(value) - .keepCurrentInjectorsAfterRun(); + .verifyRegister(REG_A, context -> value) + .firstIsMemoryAddressByte(value) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitUnary(3, - test.firstIsPair(REG_PAIR_BC).run(0x0A), - test.firstIsPair(REG_PAIR_DE).run(0x1A) + test.firstIsPair(REG_PAIR_BC).run(0x0A), + test.firstIsPair(REG_PAIR_DE).run(0x1A) ); } @@ -213,13 +213,13 @@ public void testSTAX() { final int value = 0x25; IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyByte(context -> context.first, context -> value) - .setRegister(REG_A, value) - .keepCurrentInjectorsAfterRun(); + .verifyByte(context -> context.first, context -> value) + .setRegister(REG_A, value) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitUnary(3, - test.firstIsPair(REG_PAIR_BC).run(0x02), - test.firstIsPair(REG_PAIR_DE).run(0x12) + test.firstIsPair(REG_PAIR_BC).run(0x02), + test.firstIsPair(REG_PAIR_DE).run(0x12) ); } @@ -228,11 +228,11 @@ public void testLDA() { byte value = -120; IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyRegister(REG_A, context -> value & 0xFF) - .firstIsMemoryAddressByte(value); + .verifyRegister(REG_A, context -> value & 0xFF) + .firstIsMemoryAddressByte(value); Generator.forSome16bitUnary(3, - test.runWithFirstOperand(0x3A) + test.runWithFirstOperand(0x3A) ); } @@ -241,11 +241,11 @@ public void testSTA() { byte value = -120; IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyByte(context -> context.first, context -> value & 0xFF) - .setRegister(REG_A, value); + .verifyByte(context -> context.first, context -> value & 0xFF) + .setRegister(REG_A, value); Generator.forSome16bitUnary(3, - test.runWithFirstOperand(0x32) + test.runWithFirstOperand(0x32) ); } @@ -254,11 +254,11 @@ public void testLHLD() { int value = 0x1234; IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyPair(REG_PAIR_HL, context -> value) - .firstIsMemoryAddressWord(value); + .verifyPair(REG_PAIR_HL, context -> value) + .firstIsMemoryAddressWord(value); Generator.forSome16bitUnary(3, - test.runWithFirstOperand(0x2A) + test.runWithFirstOperand(0x2A) ); } @@ -267,75 +267,75 @@ public void testSHLD() { int value = 0x1236; IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyWord(context -> context.first, context -> value) - .setPair(REG_PAIR_HL, value); + .verifyWord(context -> context.first, context -> value) + .setPair(REG_PAIR_HL, value); Generator.forSome16bitUnary(3, - test.runWithFirstOperand(0x22) + test.runWithFirstOperand(0x22) ); } @Test public void testLXI_B() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyPair(REG_PAIR_BC, context -> context.first); + .verifyPair(REG_PAIR_BC, context -> context.first); Generator.forSome16bitUnary( - test.runWithFirstOperand(0x01) + test.runWithFirstOperand(0x01) ); } @Test public void testLXI_D() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyPair(REG_PAIR_DE, context -> context.first); + .verifyPair(REG_PAIR_DE, context -> context.first); Generator.forSome16bitUnary( - test.runWithFirstOperand(0x11) + test.runWithFirstOperand(0x11) ); } @Test public void testLXI_H() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyPair(REG_PAIR_HL, context -> context.first); + .verifyPair(REG_PAIR_HL, context -> context.first); Generator.forSome16bitUnary( - test.runWithFirstOperand(0x21) + test.runWithFirstOperand(0x21) ); } @Test public void testLXI_SP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyPair(REG_SP, context -> context.first); + .verifyPair(REG_SP, context -> context.first); Generator.forSome16bitUnary( - test.runWithFirstOperand(0x31) + test.runWithFirstOperand(0x31) ); } @Test public void testSPHL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyPair(REG_SP, context -> context.first); + .verifyPair(REG_SP, context -> context.first); Generator.forSome16bitUnary( - test.firstIsPair(REG_PAIR_HL).run(0xF9) + test.firstIsPair(REG_PAIR_HL).run(0xF9) ); } @Test public void testXCHG() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsPair(REG_PAIR_HL) - .secondIsPair(REG_PAIR_DE) - .verifyPair(REG_PAIR_DE, context -> context.first) - .verifyPair(REG_PAIR_HL, context -> context.second) - .keepCurrentInjectorsAfterRun(); + .firstIsPair(REG_PAIR_HL) + .secondIsPair(REG_PAIR_DE) + .verifyPair(REG_PAIR_DE, context -> context.first) + .verifyPair(REG_PAIR_HL, context -> context.second) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary( - test.run(0xEB) + test.run(0xEB) ); } @@ -344,15 +344,15 @@ public void testXTHL() { int address = 0x23; IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsMemoryWordAt(address) - .secondIsPair(REG_PAIR_HL) - .setPair(REG_SP, address) - .verifyWord(context -> address, context -> context.second) - .verifyPair(REG_PAIR_HL, context -> context.first) - .keepCurrentInjectorsAfterRun(); + .firstIsMemoryWordAt(address) + .secondIsPair(REG_PAIR_HL) + .setPair(REG_SP, address) + .verifyWord(context -> address, context -> context.second) + .verifyPair(REG_PAIR_HL, context -> context.first) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary( - test.run(0xE3) + test.run(0xE3) ); } diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/ByteTestBuilder.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/ByteTestBuilder.java index 8d1189887..265b93841 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/ByteTestBuilder.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/ByteTestBuilder.java @@ -42,8 +42,8 @@ public ByteTestBuilder secondIsRegister(int register) { public ByteTestBuilder setPair(int registerPair, int value) { runner.injectFirst( - (tmpRunner, argument) -> tmpRunner.ensureProgramSize(value + 1), - (tmpRunner, argument) -> cpuRunner.setRegisterPair(registerPair, value) + (tmpRunner, argument) -> tmpRunner.ensureProgramSize(value + 1), + (tmpRunner, argument) -> cpuRunner.setRegisterPair(registerPair, value) ); return this; } diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuRunnerImpl.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuRunnerImpl.java index ea3a1f7db..b18eb38ab 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuRunnerImpl.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuRunnerImpl.java @@ -68,7 +68,7 @@ public void setRegisterPairPSW(int registerPair, int value) { if (registerPair < 3) { setRegisterPair(registerPair, value); } else if (registerPair == 3) { - cpu.getEngine().regs[REG_A] = (byte)((value >>> 8) & 0xFF); + cpu.getEngine().regs[REG_A] = (byte) ((value >>> 8) & 0xFF); cpu.getEngine().flags = (short) (value & 0xD7 | 2); } else { throw new IllegalArgumentException("Expected value between <0,3> !"); @@ -86,13 +86,13 @@ public int getSP() { } @Override - public void setFlags(int mask) { - cpu.getEngine().flags |= mask; + public int getFlags() { + return cpu.getEngine().flags; } @Override - public int getFlags() { - return cpu.getEngine().flags; + public void setFlags(int mask) { + cpu.getEngine().flags |= mask; } @Override diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuVerifierImpl.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuVerifierImpl.java index 9b15e2800..59344efbb 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuVerifierImpl.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/CpuVerifierImpl.java @@ -39,8 +39,8 @@ public void checkRegister(int register, int expected) { expected &= 0xFF; int actual = cpu.getEngine().regs[register] & 0xFF; assertEquals( - String.format("Expected reg[%02x]=%02x, but was %02x", register, expected, actual), - expected, actual + String.format("Expected reg[%02x]=%02x, but was %02x", register, expected, actual), + expected, actual ); } @@ -66,8 +66,8 @@ public void checkRegisterPair(int registerPair, int value) { } assertEquals( - String.format("Expected regPair[%02x]=%04x, but was %04x", registerPair, value, realValue), - value, realValue + String.format("Expected regPair[%02x]=%04x, but was %04x", registerPair, value, realValue), + value, realValue ); } @@ -77,8 +77,8 @@ public void checkRegisterPairPSW(int registerPair, int value) { } else if (registerPair == 3) { int realValue = (cpu.getEngine().regs[EmulatorEngine.REG_A] << 8) | (cpu.getEngine().flags & 0xD7 | 2); assertEquals( - String.format("Expected regPair[%02x]=%04x, but was %04x", registerPair, value, realValue), - value, realValue + String.format("Expected regPair[%02x]=%04x, but was %04x", registerPair, value, realValue), + value, realValue ); } else { throw new IllegalArgumentException("Expected value between <0,3> !"); @@ -87,8 +87,8 @@ public void checkRegisterPairPSW(int registerPair, int value) { public void checkPC(int PC) { assertEquals( - String.format("Expected PC=%04x, but was %04x", PC, cpu.getEngine().PC), - PC, cpu.getEngine().PC + String.format("Expected PC=%04x, but was %04x", PC, cpu.getEngine().PC), + PC, cpu.getEngine().PC ); } @@ -123,12 +123,12 @@ public String intToFlags(int flags) { @Override public void checkFlags(int mask) { assertEquals(String.format("Expected flags=%s, but was %s", - intToFlags(mask), intToFlags(cpu.getEngine().flags)), (cpu.getEngine().flags & mask), mask); + intToFlags(mask), intToFlags(cpu.getEngine().flags)), (cpu.getEngine().flags & mask), mask); } @Override public void checkNotFlags(int mask) { assertEquals(String.format("Expected NOT flags=%s, but was %s", - intToFlags(mask), intToFlags(cpu.getEngine().flags)), 0, (cpu.getEngine().flags & mask)); + intToFlags(mask), intToFlags(cpu.getEngine().flags)), 0, (cpu.getEngine().flags & mask)); } } diff --git a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/FlagsCheckImpl.java b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/FlagsCheckImpl.java index 5067a445c..21373d0a8 100644 --- a/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/FlagsCheckImpl.java +++ b/plugins/cpu/8080-cpu/src/test/java/net/emustudio/plugins/cpu/intel8080/suite/FlagsCheckImpl.java @@ -23,6 +23,18 @@ public class FlagsCheckImpl extends FlagsCheck> { + public static boolean isAuxCarry(int first, int sumWith) { + int mask = sumWith & first; + int xormask = sumWith ^ first; + + int C0 = mask & 1; + int C1 = ((mask >>> 1) ^ (C0 & (xormask >>> 1))) & 1; + int C2 = ((mask >>> 2) ^ (C1 & (xormask >>> 2))) & 1; + int C3 = ((mask >>> 3) ^ (C2 & (xormask >>> 3))) & 1; + + return (C3 != 0); + } + public FlagsCheckImpl sign() { evaluators.add((context, result) -> { if (result.byteValue() < 0) { @@ -115,18 +127,6 @@ public FlagsCheckImpl carryIsReset() { return this; } - public static boolean isAuxCarry(int first, int sumWith) { - int mask = sumWith & first; - int xormask = sumWith ^ first; - - int C0 = mask & 1; - int C1 = ((mask >>> 1) ^ (C0 & (xormask >>> 1))) & 1; - int C2 = ((mask >>> 2) ^ (C1 & (xormask >>> 2))) & 1; - int C3 = ((mask >>> 3) ^ (C2 & (xormask >>> 3))) & 1; - - return (C3 != 0); - } - public FlagsCheckImpl auxCarry() { evaluators.add((context, result) -> { int firstInt = context.first.intValue(); diff --git a/plugins/cpu/brainduck-cpu/README.md b/plugins/cpu/brainduck-cpu/README.md index 8c56b9622..43f820fda 100644 --- a/plugins/cpu/brainduck-cpu/README.md +++ b/plugins/cpu/brainduck-cpu/README.md @@ -4,4 +4,5 @@ This project is emulator of abstract BrainDuck computer architecture, basically [brainfuck](https://en.wikipedia.org/wiki/Brainfuck) language. It is part of [emuStudio](https://www.emustudio.net/). -The official documentation can be found [here](https://www.emustudio.net/docuser/brainduck/index/#cpu-code-brainduck-cpu-code) +The official documentation can be +found [here](https://www.emustudio.net/docuser/brainduck/index/#cpu-code-brainduck-cpu-code) diff --git a/plugins/cpu/brainduck-cpu/build.gradle b/plugins/cpu/brainduck-cpu/build.gradle index 046c5acf7..10552b06d 100644 --- a/plugins/cpu/brainduck-cpu/build.gradle +++ b/plugins/cpu/brainduck-cpu/build.gradle @@ -50,8 +50,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java index b678df685..235ffbe02 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/Profiler.java @@ -41,52 +41,6 @@ public class Profiler { private int copyLoopsCount = 0; private int scanLoopsCount = 0; - public static final class CachedOperation { - public enum TYPE {COPYLOOP, REPEAT, SCANLOOP} - - final TYPE type; - int nextIP; - - CachedOperation(TYPE type) { - this.type = type; - } - - // for repeats - int argument; - short operation; - - // for copyloops - List copyLoops; - - @Override - public String toString() { - switch (type) { - case COPYLOOP: - return type + copyLoops.toString(); - case REPEAT: - return type + "[op=" + operation + ", arg=" + argument + "]"; - } - return "UNKNOWN"; - } - } - - public final static class CopyLoop { - int factor; - int relativePosition; - - short specialOP; - - CopyLoop(int factor, int relativePosition) { - this.factor = factor; - this.relativePosition = relativePosition; - } - - @Override - public String toString() { - return "[f=" + factor + ",pos=" + relativePosition + "]"; - } - } - Profiler(ByteMemoryContext memory) { this.memory = Objects.requireNonNull(memory.getRawMemory())[0]; @@ -315,8 +269,51 @@ Integer findLoopEnd(int address) { public String toString() { int total = repeatedOptsCount + copyLoopsCount + scanLoopsCount; return "Profiler{optimizations=" + total - + ", repeatedOps=" + repeatedOptsCount + ", copyLoops=" + copyLoopsCount - + ", scanLoops=" + scanLoopsCount - + "}"; + + ", repeatedOps=" + repeatedOptsCount + ", copyLoops=" + copyLoopsCount + + ", scanLoops=" + scanLoopsCount + + "}"; + } + + public static final class CachedOperation { + final TYPE type; + int nextIP; + // for repeats + int argument; + short operation; + // for copyloops + List copyLoops; + CachedOperation(TYPE type) { + this.type = type; + } + + @Override + public String toString() { + switch (type) { + case COPYLOOP: + return type + copyLoops.toString(); + case REPEAT: + return type + "[op=" + operation + ", arg=" + argument + "]"; + } + return "UNKNOWN"; + } + + public enum TYPE {COPYLOOP, REPEAT, SCANLOOP} + } + + public final static class CopyLoop { + int factor; + int relativePosition; + + short specialOP; + + CopyLoop(int factor, int relativePosition) { + this.factor = factor; + this.relativePosition = relativePosition; + } + + @Override + public String toString() { + return "[f=" + factor + ",pos=" + relativePosition + "]"; + } } } diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/ColumnsRepainter.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/ColumnsRepainter.java index c9535866b..1f01161e0 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/ColumnsRepainter.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/ColumnsRepainter.java @@ -31,6 +31,26 @@ public class ColumnsRepainter { + public void setMainColumn(int column, JTable table) { + TableColumn tableColumn = table.getColumnModel().getColumn(table.convertColumnIndexToModel(column)); + if (tableColumn != null) { + tableColumn.setHeaderRenderer(new MainRenderer(false)); + tableColumn.setCellRenderer(new MainRenderer(true)); + } + } + + public void repaint(JTable table) { + TableModel tableModel = table.getModel(); + Enumeration columns = table.getColumnModel().getColumns(); + while (columns.hasMoreElements()) { + TableColumn column = columns.nextElement(); + column.setHeaderValue(tableModel.getColumnName(column.getModelIndex())); + } + JTableHeader header = table.getTableHeader(); + header.revalidate(); + header.repaint(); + } + private static class UBorder extends LineBorder { private final boolean upper; private final Stroke stroke; @@ -87,24 +107,4 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole } - public void setMainColumn(int column, JTable table) { - TableColumn tableColumn = table.getColumnModel().getColumn(table.convertColumnIndexToModel(column)); - if (tableColumn != null) { - tableColumn.setHeaderRenderer(new MainRenderer(false)); - tableColumn.setCellRenderer(new MainRenderer(true)); - } - } - - public void repaint(JTable table) { - TableModel tableModel = table.getModel(); - Enumeration columns = table.getColumnModel().getColumns(); - while (columns.hasMoreElements()) { - TableColumn column = columns.nextElement(); - column.setHeaderValue(tableModel.getColumnName(column.getModelIndex())); - } - JTableHeader header = table.getTableHeader(); - header.revalidate(); - header.repaint(); - } - } diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java index 0c8042f17..5bce9f861 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/gui/StatusPanel.java @@ -33,60 +33,13 @@ public class StatusPanel extends JPanel { private final MemoryTableModel tableModel; private final Byte[] memory; private final EmulatorEngine cpu; - - private class CPUStatusListener implements CPU.CPUListener { - private volatile long nanoStartTime; - - @Override - public void runStateChanged(CPU.RunState state) { - switch (state) { - case STATE_RUNNING: - lblRunState.setText("running"); - lblTime.setText("N/A"); - nanoStartTime = System.nanoTime(); - break; - case STATE_STOPPED_NORMAL: - lblRunState.setText("stopped (normal)"); - break; - case STATE_STOPPED_BREAK: - lblRunState.setText("breakpoint"); - break; - case STATE_STOPPED_ADDR_FALLOUT: - lblRunState.setText("stopped (address fallout)"); - break; - case STATE_STOPPED_BAD_INSTR: - lblRunState.setText("stopped (instruction fallout)"); - break; - } - long tmpNanoTime = 0; - if (state != CPU.RunState.STATE_RUNNING && nanoStartTime != 0) { - tmpNanoTime = System.nanoTime() - nanoStartTime; - nanoStartTime = 0; - } - lblTime.setText(String.format("%.2f ms", (double) tmpNanoTime / 1000000.0)); - } - - @Override - public void internalStateChanged() { - int P = cpu.getP(); - - txtP.setText(String.format("%04X", P)); - txtIP.setText(String.format("%04X", cpu.IP)); - lblLoopLevel.setText(String.valueOf(cpu.getLoopLevel())); - try { - txtMemP.setText(String.format("%02X", memory[P] & 0xFF)); - } catch (ArrayIndexOutOfBoundsException e) { - txtMemP.setText("[unreachable]"); - } finally { - tableModel.setP(P); - columnsRepainter.repaint(tblMemory); - tblMemory.revalidate(); - tblMemory.repaint(); - } - } - - } - + private JLabel lblLoopLevel; + private JLabel lblRunState; + private JLabel lblTime; + private JTable tblMemory; + private JTextField txtIP; + private JTextField txtMemP; + private JTextField txtP; public StatusPanel(ByteMemoryContext memory, CpuImpl cpu) { this.memory = memory.getRawMemory()[0]; this.cpu = cpu.getEngine(); @@ -157,72 +110,72 @@ private void initComponents() { GroupLayout jPanel1Layout = new GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel3) - .addComponent(jLabel2) - .addComponent(jLabel1)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(txtIP) - .addComponent(txtP) - .addComponent(txtMemP)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel4) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addComponent(jLabel5) - .addContainerGap())) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addComponent(jLabel6) - .addContainerGap()))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jLabel3) + .addComponent(jLabel2) + .addComponent(jLabel1)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(txtIP) + .addComponent(txtP) + .addComponent(txtMemP)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jLabel4) + .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addComponent(jLabel5) + .addContainerGap())) + .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addComponent(jLabel6) + .addContainerGap()))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jSeparator1) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jLabel7) + .addComponent(jLabel8)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblLoopLevel) + .addComponent(lblTime)) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()))) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jSeparator1) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(txtIP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2) + .addComponent(txtP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3) + .addComponent(txtMemP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSeparator1, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(jLabel7) - .addComponent(jLabel8)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblLoopLevel) .addComponent(lblTime)) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()))) - ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) - .addComponent(txtIP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel4)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2) - .addComponent(txtP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel5)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3) - .addComponent(txtMemP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel6)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSeparator1, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel7) - .addComponent(lblTime)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel8) - .addComponent(lblLoopLevel))) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel8) + .addComponent(lblLoopLevel))) ); jPanel2.setBorder(BorderFactory.createTitledBorder("Run state")); @@ -234,18 +187,18 @@ private void initComponents() { GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(lblRunState, GroupLayout.DEFAULT_SIZE, 283, Short.MAX_VALUE) - .addContainerGap()) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(lblRunState, GroupLayout.DEFAULT_SIZE, 283, Short.MAX_VALUE) + .addContainerGap()) ); jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(lblRunState) - .addContainerGap(21, Short.MAX_VALUE)) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(lblRunState) + .addContainerGap(21, Short.MAX_VALUE)) ); jPanel3.setBorder(BorderFactory.createTitledBorder("Memory view")); @@ -254,15 +207,15 @@ private void initComponents() { tblMemory.setFont(MONOSPACED_PLAIN); tblMemory.setModel(new DefaultTableModel( - new Object[][]{ - {null, null, null, null, null} - }, - new String[]{ - "00", "01", "02", "03", "04" - } + new Object[][]{ + {null, null, null, null, null} + }, + new String[]{ + "00", "01", "02", "03", "04" + } ) { final Class[] types = new Class[]{ - java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class + java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class, java.lang.Byte.class }; public Class getColumnClass(int columnIndex) { @@ -275,50 +228,95 @@ public Class getColumnClass(int columnIndex) { GroupLayout jPanel3Layout = new GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addContainerGap()) + jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addContainerGap()) ); jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 63, Short.MAX_VALUE) - .addContainerGap()) + jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 63, Short.MAX_VALUE) + .addContainerGap()) ); GroupLayout layout = new GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel2, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel2, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); } - private JLabel lblLoopLevel; - private JLabel lblRunState; - private JLabel lblTime; - private JTable tblMemory; - private JTextField txtIP; - private JTextField txtMemP; - private JTextField txtP; + private class CPUStatusListener implements CPU.CPUListener { + private volatile long nanoStartTime; + + @Override + public void runStateChanged(CPU.RunState state) { + switch (state) { + case STATE_RUNNING: + lblRunState.setText("running"); + lblTime.setText("N/A"); + nanoStartTime = System.nanoTime(); + break; + case STATE_STOPPED_NORMAL: + lblRunState.setText("stopped (normal)"); + break; + case STATE_STOPPED_BREAK: + lblRunState.setText("breakpoint"); + break; + case STATE_STOPPED_ADDR_FALLOUT: + lblRunState.setText("stopped (address fallout)"); + break; + case STATE_STOPPED_BAD_INSTR: + lblRunState.setText("stopped (instruction fallout)"); + break; + } + long tmpNanoTime = 0; + if (state != CPU.RunState.STATE_RUNNING && nanoStartTime != 0) { + tmpNanoTime = System.nanoTime() - nanoStartTime; + nanoStartTime = 0; + } + lblTime.setText(String.format("%.2f ms", (double) tmpNanoTime / 1000000.0)); + } + + @Override + public void internalStateChanged() { + int P = cpu.getP(); + + txtP.setText(String.format("%04X", P)); + txtIP.setText(String.format("%04X", cpu.IP)); + lblLoopLevel.setText(String.valueOf(cpu.getLoopLevel())); + try { + txtMemP.setText(String.format("%02X", memory[P] & 0xFF)); + } catch (ArrayIndexOutOfBoundsException e) { + txtMemP.setText("[unreachable]"); + } finally { + tableModel.setP(P); + columnsRepainter.repaint(tblMemory); + tblMemory.revalidate(); + tblMemory.repaint(); + } + } + + } } diff --git a/plugins/cpu/brainduck-cpu/src/main/resources/net/emustudio/plugins/cpu/brainduck/version.properties b/plugins/cpu/brainduck-cpu/src/main/resources/net/emustudio/plugins/cpu/brainduck/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/cpu/brainduck-cpu/src/main/resources/net/emustudio/plugins/cpu/brainduck/version.properties +++ b/plugins/cpu/brainduck-cpu/src/main/resources/net/emustudio/plugins/cpu/brainduck/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java index 52a8c32dc..f4b9f8e4a 100644 --- a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java +++ b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/CpuImplTest.java @@ -34,7 +34,6 @@ import static org.easymock.EasyMock.*; import static org.junit.Assert.*; -import static org.junit.Assert.assertNotEquals; public class CpuImplTest { private CpuImpl cpu; @@ -185,8 +184,8 @@ public void testCopyCell() { public void testCopyCell2() { // [->+>+<<]>>[-<<+>>] byte[] program = new byte[]{ - 7, 4, 1, 3, 1, 3, 2, 2, 8, 1, 1, 7, 4, 2, 2, 3, - 1, 1, 8 + 7, 4, 1, 3, 1, 3, 2, 2, 8, 1, 1, 7, 4, 2, 2, 3, + 1, 1, 8 }; byte[] data = new byte[]{4}; @@ -202,9 +201,9 @@ public void testCopyCell2() { public void testAddition() { // ,>++++++[<-------->-],[<+>-],<.>. byte[] program = new byte[]{ - 6, 1, 3, 3, 3, 3, 3, 3, 7, 2, 4, 4, 4, 4, 4, 4, - 4, 4, 1, 4, 8, 6, 7, 2, 3, 1, 4, 8, 6, 2, 5, 1, - 5 + 6, 1, 3, 3, 3, 3, 3, 3, 7, 2, 4, 4, 4, 4, 4, 4, + 4, 4, 1, 4, 8, 6, 7, 2, 3, 1, 4, 8, 6, 2, 5, 1, + 5 }; byte[] input = new byte[]{'4', '4', '\n'}; @@ -226,9 +225,9 @@ public void testAddition() { public void testMoreAddition() { // ,>++++++[<-------->-],[<+>-],<.>. byte[] program = new byte[]{ - 6, 1, 3, 3, 3, 3, 3, 3, 7, 2, 4, 4, 4, 4, 4, 4, - 4, 4, 1, 4, 8, 6, 7, 2, 3, 1, 4, 8, 6, 2, 5, 1, - 5}; + 6, 1, 3, 3, 3, 3, 3, 3, 7, 2, 4, 4, 4, 4, 4, 4, + 4, 4, 1, 4, 8, 6, 7, 2, 3, 1, 4, 8, 6, 2, 5, 1, + 5}; byte[] input = new byte[]{'8', '8', 'a'}; emulate(program, null, input); @@ -262,11 +261,11 @@ public void testMultiply() { // [>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[<<+>>-]<-] byte[] program = new byte[]{ - 7, 1, 1, 1, 3, 1, 3, 2, 2, 2, 2, 4, 8, 1, 1, 1, - 1, 7, 2, 2, 2, 2, 3, 1, 1, 1, 1, 4, 8, 2, 7, 2, - 2, 7, 1, 1, 1, 3, 1, 3, 2, 2, 2, 2, 4, 8, 1, 1, - 1, 1, 7, 2, 2, 2, 2, 3, 1, 1, 1, 1, 4, 8, 2, 7, - 2, 2, 3, 1, 1, 4, 8, 2, 4, 8 + 7, 1, 1, 1, 3, 1, 3, 2, 2, 2, 2, 4, 8, 1, 1, 1, + 1, 7, 2, 2, 2, 2, 3, 1, 1, 1, 1, 4, 8, 2, 7, 2, + 2, 7, 1, 1, 1, 3, 1, 3, 2, 2, 2, 2, 4, 8, 1, 1, + 1, 1, 7, 2, 2, 2, 2, 3, 1, 1, 1, 1, 4, 8, 2, 7, + 2, 2, 3, 1, 1, 4, 8, 2, 4, 8 }; byte[] data = new byte[]{20, 5}; @@ -311,10 +310,10 @@ public void testMinusPlusGivesZero() { public void testSelfPrint() { // +++++[>+++++++++<-],[[>--.++>+<<-]>+.->[<.>-]<<,] byte[] program = new byte[]{ - 3, 3, 3, 3, 3, 7, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 4, 8, 6, 7, 7, 1, 4, 4, 5, 3, 3, 1, 3, 2, 2, - 4, 8, 1, 3, 5, 4, 1, 7, 2, 5, 1, 4, 8, 2, 2, 6, - 8 + 3, 3, 3, 3, 3, 7, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 4, 8, 6, 7, 7, 1, 4, 4, 5, 3, 3, 1, 3, 2, 2, + 4, 8, 1, 3, 5, 4, 1, 7, 2, 5, 1, 4, 8, 2, 2, 6, + 8 }; byte[] input = new byte[]{1, 0}; diff --git a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngineTest.java b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngineTest.java index 8170b9c7e..84b0fff6b 100644 --- a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngineTest.java +++ b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngineTest.java @@ -65,13 +65,13 @@ public void testCellClear() throws Exception { @Test public void testCopyLoop() throws Exception { resetProgram( - I_LOOP_START, - I_INC, I_INCV, I_INCV, - I_INC, I_INCV, I_DECV, - I_INC, I_INC, I_DECV, I_DECV, - I_DEC, I_DEC, I_DEC, I_DEC, - I_DECV, - I_LOOP_END + I_LOOP_START, + I_INC, I_INCV, I_INCV, + I_INC, I_INCV, I_DECV, + I_INC, I_INC, I_DECV, I_DECV, + I_DEC, I_DEC, I_DEC, I_DEC, + I_DECV, + I_LOOP_END ); // [>++>+->>++<<<<-] checkProfilerCopyLoop(17, new int[]{2, 0, -2}, new int[]{1, 2, 4}); @@ -81,10 +81,10 @@ public void testCopyLoop() throws Exception { @Test public void testCopyLoopWeird() { resetProgram( - I_LOOP_START, - I_DECV, - I_DEC, I_INC, I_DECV, - I_LOOP_END + I_LOOP_START, + I_DECV, + I_DEC, I_INC, I_DECV, + I_LOOP_END ); // [-<>-] engine.reset(0); @@ -94,14 +94,14 @@ public void testCopyLoopWeird() { @Test public void testCopyLoopWithPrints() throws Exception { resetProgram( - I_LOOP_START, - I_DECV, - I_INC, I_INCV, - I_PRINT, - I_INC, I_INCV, I_INCV, - I_PRINT, - I_DEC, I_DEC, - I_LOOP_END + I_LOOP_START, + I_DECV, + I_INC, I_INCV, + I_PRINT, + I_INC, I_INCV, I_INCV, + I_PRINT, + I_DEC, I_DEC, + I_LOOP_END ); // [->+.>++.<<] checkProfilerCopyLoop(12, new int[]{1, 0, 2, 0}, new int[]{1, 0, 2, 0}); @@ -112,11 +112,11 @@ public void testCopyLoopWithPrints() throws Exception { @Test public void testScanloop() throws Exception { resetProgram( - I_LOOP_START, - I_DEC, - I_INC, - I_INC, - I_LOOP_END + I_LOOP_START, + I_DEC, + I_INC, + I_INC, + I_LOOP_END ); // [<>>] engine.reset(0); @@ -160,7 +160,7 @@ private void runAndCheckCopyLoop(int start, int valueP, int[] resultValues, int[ for (int i = 0; i < resultValues.length; i++) { assertEquals("Expected res[" + i + "]=" + resultValues[i] + " at " + (start + relPositions[i]), - resultValues[i], memory.read(start + relPositions[i]) & 0xFF); + resultValues[i], memory.read(start + relPositions[i]) & 0xFF); } assertEquals(0, memory.read(engine.P) & 0xFF); } diff --git a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java index 76f657b65..27b956c1c 100644 --- a/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java +++ b/plugins/cpu/brainduck-cpu/src/test/java/net/emustudio/plugins/cpu/brainduck/MemoryStub.java @@ -63,12 +63,12 @@ public List getReadOnly() { } @Override - public void setReadWrite(AddressRange range) { + public void setReadOnly(AddressRange range) { } @Override - public void setReadOnly(AddressRange range) { + public void setReadWrite(AddressRange range) { } diff --git a/plugins/cpu/ram-cpu/build.gradle b/plugins/cpu/ram-cpu/build.gradle index 71926f577..a7795a647 100644 --- a/plugins/cpu/ram-cpu/build.gradle +++ b/plugins/cpu/ram-cpu/build.gradle @@ -52,8 +52,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year" : new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/CpuImpl.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/CpuImpl.java index 923025674..05d8bb662 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/CpuImpl.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/CpuImpl.java @@ -27,10 +27,10 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; import net.emustudio.emulib.runtime.InvalidContextException; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.debugger.BreakpointColumn; import net.emustudio.emulib.runtime.interaction.debugger.DebuggerTable; import net.emustudio.emulib.runtime.interaction.debugger.MnemoColumn; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.cpu.ram.gui.LabelDebugColumn; import net.emustudio.plugins.cpu.ram.gui.RAMDisassembler; import net.emustudio.plugins.cpu.ram.gui.RAMStatusPanel; @@ -48,8 +48,8 @@ import java.util.ResourceBundle; @PluginRoot( - type = PLUGIN_TYPE.CPU, - title = "Random Access Machine (RAM)" + type = PLUGIN_TYPE.CPU, + title = "Random Access Machine (RAM)" ) @SuppressWarnings("unused") public class CpuImpl extends AbstractCPU { @@ -71,7 +71,7 @@ public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings sett } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register RAM CPU context", e); applicationApi.getDialogs().showError( - "Could not register RAM CPU Context. Please see log file for details.", super.getTitle() + "Could not register RAM CPU Context. Please see log file for details.", super.getTitle() ); } } @@ -105,7 +105,7 @@ public JPanel getStatusPanel() { DebuggerTable debugTable = applicationApi.getDebuggerTable(); if (debugTable != null) { debugTable.setDebuggerColumns(Arrays.asList( - new BreakpointColumn(this), new LabelDebugColumn(memory), new MnemoColumn(disassembler) + new BreakpointColumn(this), new LabelDebugColumn(memory), new MnemoColumn(disassembler) )); } debugTableInitialized = true; diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java index ddfc92d9b..b43351b70 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java @@ -32,12 +32,11 @@ import java.util.function.BiFunction; public class EmulatorEngine { + public final AtomicInteger IP = new AtomicInteger(); private final AbstractTapeContext inputTape; private final AbstractTapeContext outputTape; private final AbstractTapeContext storageTape; - private final RAMMemoryContext memory; - public final AtomicInteger IP = new AtomicInteger(); public EmulatorEngine(AbstractTapeContext inputTape, AbstractTapeContext outputTape, AbstractTapeContext storageTape, RAMMemoryContext memory) { @@ -87,7 +86,7 @@ public CPU.RunState step() throws IOException { break; case STORE: getRegister(instr) - .ifPresent(o -> storageTape.getSymbolAt(0).ifPresent(r -> storageTape.setSymbolAt(o, r))); + .ifPresent(o -> storageTape.getSymbolAt(0).ifPresent(r -> storageTape.setSymbolAt(o, r))); break; case ADD: getValue(instr).ifPresent(op -> arithmetic(op, Integer::sum)); @@ -103,19 +102,19 @@ public CPU.RunState step() throws IOException { break; case JMP: instr - .getLabel() - .ifPresentOrElse(o -> IP.set(o.getAddress()), () -> { - throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); - }); + .getLabel() + .ifPresentOrElse(o -> IP.set(o.getAddress()), () -> { + throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); + }); break; case JZ: { int r0 = getR0(); if (r0 == 0) { instr - .getLabel() - .ifPresentOrElse(o -> IP.set(o.getAddress()), () -> { - throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); - }); + .getLabel() + .ifPresentOrElse(o -> IP.set(o.getAddress()), () -> { + throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); + }); } break; } @@ -123,10 +122,10 @@ public CPU.RunState step() throws IOException { int r0 = getR0(); if (r0 > 0) { instr - .getLabel() - .ifPresentOrElse(o -> IP.set(o.getAddress()), () -> { - throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); - }); + .getLabel() + .ifPresentOrElse(o -> IP.set(o.getAddress()), () -> { + throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); + }); } break; } @@ -140,14 +139,14 @@ public CPU.RunState step() throws IOException { private int getR0() { return storageTape - .getSymbolAt(0) - .filter(r0 -> r0 != TapeSymbol.EMPTY) - .map(r0 -> { - if (r0.type != TapeSymbol.Type.NUMBER) { - throw new RuntimeException("Register 0 contains non-numeric value: " + r0); - } - return r0.number; - }).orElse(0); + .getSymbolAt(0) + .filter(r0 -> r0 != TapeSymbol.EMPTY) + .map(r0 -> { + if (r0.type != TapeSymbol.Type.NUMBER) { + throw new RuntimeException("Register 0 contains non-numeric value: " + r0); + } + return r0.number; + }).orElse(0); } private void arithmetic(TapeSymbol operand, BiFunction operation) { @@ -184,13 +183,13 @@ private Optional getRegister(RAMInstruction instruction) { throw new RuntimeException("Instruction has non-numeric operand: " + instruction); } return storageTape - .getSymbolAt(r.getNumberValue()) - .map(rr -> { - if (rr.type != TapeSymbol.Type.NUMBER) { - throw new RuntimeException("Value of register " + rr + " is non-numeric"); - } - return rr.number; - }); + .getSymbolAt(r.getNumberValue()) + .map(rr -> { + if (rr.type != TapeSymbol.Type.NUMBER) { + throw new RuntimeException("Value of register " + rr + " is non-numeric"); + } + return rr.number; + }); }); } throw new IllegalStateException("Unexpected direction: " + instruction.getDirection()); @@ -198,6 +197,6 @@ private Optional getRegister(RAMInstruction instruction) { private TapeSymbol toSymbol(RAMValue value) { return (value.getType() == RAMValue.Type.NUMBER) ? - new TapeSymbol(value.getNumberValue()) : new TapeSymbol(value.getStringValue()); + new TapeSymbol(value.getNumberValue()) : new TapeSymbol(value.getStringValue()); } } diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/RAMCpuContextImpl.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/RAMCpuContextImpl.java index 5de4219b8..4539515ed 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/RAMCpuContextImpl.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/RAMCpuContextImpl.java @@ -27,10 +27,10 @@ import java.util.Optional; public class RAMCpuContextImpl implements RAMCpuContext { + private final ContextPool contextPool; private AbstractTapeContext inputTape; private AbstractTapeContext outputTape; private AbstractTapeContext storageTape; - private final ContextPool contextPool; public RAMCpuContextImpl(ContextPool contextPool) { this.contextPool = Objects.requireNonNull(contextPool); @@ -44,7 +44,7 @@ public void init(long pluginID) throws PluginInitializationException { private AbstractTapeContext setupTape(long pluginID, String title, boolean clearAfterReset, boolean posVisible, boolean editable, int index) - throws PluginInitializationException { + throws PluginInitializationException { AbstractTapeContext tape = contextPool.getDeviceContext(pluginID, AbstractTapeContext.class, index); if (tape == null) { diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java index 8f80fe1de..926fa8f83 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java @@ -43,7 +43,7 @@ public DisassembledInstruction disassemble(int memLocation) { return new DisassembledInstruction(memLocation, mnemo, oper); } mnemo = in.getOpcode().toString() + " " + in.getDirection().value() + - in.getOperand().map(RAMValue::getStringRepresentation).orElse(""); + in.getOperand().map(RAMValue::getStringRepresentation).orElse(""); return new DisassembledInstruction(memLocation, mnemo, oper); } diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMStatusPanel.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMStatusPanel.java index e54a17790..c69a0b64b 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMStatusPanel.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMStatusPanel.java @@ -30,6 +30,11 @@ public class RAMStatusPanel extends JPanel { + private JLabel lblStatus; + private JTextField txtIP; + private JTextField txtInput; + private JTextField txtOutput; + private JTextField txtR0; public RAMStatusPanel(final CpuImpl cpu, AbstractTapeContext input, AbstractTapeContext output) { initComponents(); @@ -91,32 +96,32 @@ private void initComponents() { GroupLayout jPanel1Layout = new GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel1) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtR0, GroupLayout.PREFERRED_SIZE, 120, GroupLayout.PREFERRED_SIZE)) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel2) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtIP))) - .addContainerGap(64, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel1) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtR0, GroupLayout.PREFERRED_SIZE, 120, GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel2) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtIP))) + .addContainerGap(64, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) - .addComponent(txtR0, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2) - .addComponent(txtIP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(txtR0, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2) + .addComponent(txtIP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel2.setBorder(BorderFactory.createTitledBorder("Run state")); @@ -129,18 +134,18 @@ private void initComponents() { GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(lblStatus, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(lblStatus, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) ); jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(lblStatus) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(lblStatus) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel3.setBorder(BorderFactory.createTitledBorder("Input / output")); @@ -159,60 +164,54 @@ private void initComponents() { GroupLayout jPanel3Layout = new GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel5) - .addComponent(jLabel4)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(txtOutput, GroupLayout.DEFAULT_SIZE, 109, Short.MAX_VALUE) - .addComponent(txtInput)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jLabel5) + .addComponent(jLabel4)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(txtOutput, GroupLayout.DEFAULT_SIZE, 109, Short.MAX_VALUE) + .addComponent(txtInput)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4) - .addComponent(txtInput, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5) - .addComponent(txtOutput, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4) + .addComponent(txtInput, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5) + .addComponent(txtOutput, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); GroupLayout layout = new GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); } - - private JLabel lblStatus; - private JTextField txtIP; - private JTextField txtInput; - private JTextField txtOutput; - private JTextField txtR0; } diff --git a/plugins/cpu/ram-cpu/src/main/resources/net/emustudio/plugins/cpu/ram/version.properties b/plugins/cpu/ram-cpu/src/main/resources/net/emustudio/plugins/cpu/ram/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/cpu/ram-cpu/src/main/resources/net/emustudio/plugins/cpu/ram/version.properties +++ b/plugins/cpu/ram-cpu/src/main/resources/net/emustudio/plugins/cpu/ram/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/AbstractEngineTest.java b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/AbstractEngineTest.java index aea9a5258..655fe533c 100644 --- a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/AbstractEngineTest.java +++ b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/AbstractEngineTest.java @@ -25,7 +25,6 @@ import net.emustudio.plugins.memory.ram.api.RAMValue; import org.junit.Before; -import java.util.List; import java.util.Optional; import static org.easymock.EasyMock.*; diff --git a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/CpuImplTest.java b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/CpuImplTest.java index 0a76aa245..25a04bf8b 100644 --- a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/CpuImplTest.java +++ b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/CpuImplTest.java @@ -26,7 +26,6 @@ import org.junit.Test; import static org.easymock.EasyMock.*; -import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertNotEquals; public class CpuImplTest { diff --git a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java index 435babe44..7777a399b 100644 --- a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java +++ b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java @@ -177,10 +177,10 @@ public void testSTORE_INDIRECT() throws IOException { @Test public void testArith_CONSTANT() throws IOException { setProgram( - instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.CONSTANT, 5), - instr(RAMInstruction.Opcode.SUB, RAMInstruction.Direction.CONSTANT, -1), - instr(RAMInstruction.Opcode.MUL, RAMInstruction.Direction.CONSTANT, 2), - instr(RAMInstruction.Opcode.DIV, RAMInstruction.Direction.CONSTANT, 3) + instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.CONSTANT, 5), + instr(RAMInstruction.Opcode.SUB, RAMInstruction.Direction.CONSTANT, -1), + instr(RAMInstruction.Opcode.MUL, RAMInstruction.Direction.CONSTANT, 2), + instr(RAMInstruction.Opcode.DIV, RAMInstruction.Direction.CONSTANT, 3) ); expect(storage.getSymbolAt(0)).andReturn(Optional.of(new TapeSymbol(-3))).once(); expect(storage.getSymbolAt(0)).andReturn(Optional.of(new TapeSymbol(2))).once(); @@ -209,10 +209,10 @@ public void testArith_CONSTANT() throws IOException { @Test public void testADD_DIRECT() throws IOException { setProgram( - instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.DIRECT, 3), - instr(RAMInstruction.Opcode.SUB, RAMInstruction.Direction.DIRECT, 4), - instr(RAMInstruction.Opcode.MUL, RAMInstruction.Direction.DIRECT, 5), - instr(RAMInstruction.Opcode.DIV, RAMInstruction.Direction.DIRECT, 6) + instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.DIRECT, 3), + instr(RAMInstruction.Opcode.SUB, RAMInstruction.Direction.DIRECT, 4), + instr(RAMInstruction.Opcode.MUL, RAMInstruction.Direction.DIRECT, 5), + instr(RAMInstruction.Opcode.DIV, RAMInstruction.Direction.DIRECT, 6) ); expect(storage.getSymbolAt(3)).andReturn(Optional.of(new TapeSymbol(5))).once(); expect(storage.getSymbolAt(4)).andReturn(Optional.of(new TapeSymbol(-1))).once(); @@ -245,10 +245,10 @@ public void testADD_DIRECT() throws IOException { @Test public void testADD_INDIRECT() throws IOException { setProgram( - instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.INDIRECT, 3), - instr(RAMInstruction.Opcode.SUB, RAMInstruction.Direction.INDIRECT, 4), - instr(RAMInstruction.Opcode.MUL, RAMInstruction.Direction.INDIRECT, 5), - instr(RAMInstruction.Opcode.DIV, RAMInstruction.Direction.INDIRECT, 6) + instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.INDIRECT, 3), + instr(RAMInstruction.Opcode.SUB, RAMInstruction.Direction.INDIRECT, 4), + instr(RAMInstruction.Opcode.MUL, RAMInstruction.Direction.INDIRECT, 5), + instr(RAMInstruction.Opcode.DIV, RAMInstruction.Direction.INDIRECT, 6) ); expect(storage.getSymbolAt(3)).andReturn(Optional.of(new TapeSymbol(8))).once(); diff --git a/plugins/cpu/rasp-cpu/build.gradle b/plugins/cpu/rasp-cpu/build.gradle index 3f54ca3e6..a09efd21e 100644 --- a/plugins/cpu/rasp-cpu/build.gradle +++ b/plugins/cpu/rasp-cpu/build.gradle @@ -51,8 +51,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/CpuImpl.java b/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/CpuImpl.java index bcd5092c2..5605ae257 100644 --- a/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/CpuImpl.java +++ b/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/CpuImpl.java @@ -26,7 +26,10 @@ import net.emustudio.emulib.plugins.cpu.AbstractCPU; import net.emustudio.emulib.plugins.cpu.CPUContext; import net.emustudio.emulib.plugins.cpu.Disassembler; -import net.emustudio.emulib.runtime.*; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; +import net.emustudio.emulib.runtime.ContextPool; +import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.interaction.debugger.BreakpointColumn; import net.emustudio.emulib.runtime.interaction.debugger.DebuggerColumn; import net.emustudio.emulib.runtime.interaction.debugger.DebuggerTable; @@ -47,8 +50,8 @@ import java.util.ResourceBundle; @PluginRoot( - type = PLUGIN_TYPE.CPU, - title = "Random Access Stored Program (RASP)" + type = PLUGIN_TYPE.CPU, + title = "Random Access Stored Program (RASP)" ) public class CpuImpl extends AbstractCPU { private final static Logger LOGGER = LoggerFactory.getLogger(CpuImpl.class); @@ -72,7 +75,7 @@ public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings sett } catch (InvalidContextException | ContextAlreadyRegisteredException ex) { LOGGER.error("Could not register RASP CPU context", ex); applicationApi.getDialogs().showError( - "Could not register RASP CPU context. Please see log file for more details", getTitle() + "Could not register RASP CPU context. Please see log file for more details", getTitle() ); } } diff --git a/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/EmulatorEngine.java b/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/EmulatorEngine.java index 5784f9e97..0a38416c4 100644 --- a/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/EmulatorEngine.java +++ b/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/EmulatorEngine.java @@ -29,64 +29,32 @@ import java.util.concurrent.atomic.AtomicInteger; public class EmulatorEngine { + public final AtomicInteger IP = new AtomicInteger(); private final AbstractTapeContext inputTape; private final AbstractTapeContext outputTape; - private final RASPMemoryContext memory; private final Instruction[] dispatcher = new Instruction[]{ - null, - this::read, - this::write_c, - this::write, - this::load_c, - this::load, - this::store, - this::add_c, - this::add, - this::sub_c, - this::sub, - this::mul_c, - this::mul, - this::div_c, - this::div, - this::jmp, - this::jz, - this::jgtz, - this::halt + null, + this::read, + this::write_c, + this::write, + this::load_c, + this::load, + this::store, + this::add_c, + this::add, + this::sub_c, + this::sub, + this::mul_c, + this::mul, + this::div_c, + this::div, + this::jmp, + this::jz, + this::jgtz, + this::halt }; - public final AtomicInteger IP = new AtomicInteger(); - - private static class Cell implements RASPMemoryCell { - private final int address; - private final int value; - - Cell(int address, int value) { - this.address = address; - this.value = value; - } - - @Override - public boolean isInstruction() { - return false; - } - - @Override - public int getAddress() { - return address; - } - - @Override - public int getValue() { - return value; - } - } - - @FunctionalInterface - private interface Instruction { - CPU.RunState execute() throws IOException; - } - public EmulatorEngine(RASPMemoryContext memory, AbstractTapeContext inputTape, AbstractTapeContext outputTape) { this.inputTape = Objects.requireNonNull(inputTape); this.outputTape = Objects.requireNonNull(outputTape); @@ -258,4 +226,34 @@ private CPU.RunState jgtz() { private CPU.RunState halt() { return CPU.RunState.STATE_STOPPED_NORMAL; } + + @FunctionalInterface + private interface Instruction { + CPU.RunState execute() throws IOException; + } + + private static class Cell implements RASPMemoryCell { + private final int address; + private final int value; + + Cell(int address, int value) { + this.address = address; + this.value = value; + } + + @Override + public boolean isInstruction() { + return false; + } + + @Override + public int getAddress() { + return address; + } + + @Override + public int getValue() { + return value; + } + } } diff --git a/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/RASPCpuStatusPanel.java b/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/RASPCpuStatusPanel.java index 0aece1687..0596f3dcb 100644 --- a/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/RASPCpuStatusPanel.java +++ b/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/RASPCpuStatusPanel.java @@ -28,6 +28,9 @@ public class RASPCpuStatusPanel extends JPanel { + private javax.swing.JTextPane accValue; + private javax.swing.JTextPane instrPointerValue; + private javax.swing.JLabel runState; public RASPCpuStatusPanel(CpuImpl cpu) { initComponents(); cpu.addCPUListener(new CPU.CPUListener() { @@ -58,7 +61,6 @@ public void internalStateChanged() { }); } - private void initComponents() { runState = new javax.swing.JLabel(); @@ -85,30 +87,30 @@ private void initComponents() { javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(accValue) - .addComponent(instrPointerValue) + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel1) - .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 203, Short.MAX_VALUE)) - .addContainerGap()) + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(accValue) + .addComponent(instrPointerValue) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel1) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 203, Short.MAX_VALUE)) + .addContainerGap()) ); jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(accValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel2) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(instrPointerValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(accValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(instrPointerValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jLabel3.setText("RUNNING STATUS:"); @@ -116,32 +118,27 @@ private void initComponents() { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(0, 60, Short.MAX_VALUE)) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel3) - .addComponent(runState)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(0, 60, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3) + .addComponent(runState)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(9, 9, 9) - .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel3) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(runState) - .addContainerGap(186, Short.MAX_VALUE)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(9, 9, 9) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel3) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(runState) + .addContainerGap(186, Short.MAX_VALUE)) ); } - - - private javax.swing.JTextPane accValue; - private javax.swing.JTextPane instrPointerValue; - private javax.swing.JLabel runState; } diff --git a/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/RASPDisassembler.java b/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/RASPDisassembler.java index 602c68337..889c64621 100644 --- a/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/RASPDisassembler.java +++ b/plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/RASPDisassembler.java @@ -45,8 +45,8 @@ public DisassembledInstruction disassemble(int address) { if (opcode != 18) { int operand = memory.read(address + 1).getValue(); String operandStr = isJump ? - memory.getLabel(operand).map(RASPLabel::getLabel).orElse(String.valueOf(operand)) : - String.valueOf(operand); + memory.getLabel(operand).map(RASPLabel::getLabel).orElse(String.valueOf(operand)) : + String.valueOf(operand); mnemo += " " + operandStr; } diff --git a/plugins/cpu/rasp-cpu/src/main/resources/net/emustudio/plugins/cpu/rasp/version.properties b/plugins/cpu/rasp-cpu/src/main/resources/net/emustudio/plugins/cpu/rasp/version.properties index 5a083e1ab..330ab194e 100644 --- a/plugins/cpu/rasp-cpu/src/main/resources/net/emustudio/plugins/cpu/rasp/version.properties +++ b/plugins/cpu/rasp-cpu/src/main/resources/net/emustudio/plugins/cpu/rasp/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright="\u00A9 Copyright 2016-2017, Michal Šipoš\n\u00A9 Copyright 2006-2022, Peter Jakubčo" diff --git a/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/EmulatorEngineTest.java b/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/EmulatorEngineTest.java index 73313ae44..dd7c1011f 100644 --- a/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/EmulatorEngineTest.java +++ b/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/EmulatorEngineTest.java @@ -36,23 +36,23 @@ public class EmulatorEngineTest { @Test public void testJumpInstruction() throws IOException { EmulatorEngine engine = setup(List.of( - RASPCell.instruction(0, 15), - RASPCell.operand(1, 4), - RASPCell.instruction(2, 15), - RASPCell.operand(3, 0), - RASPCell.instruction(4, 18) + RASPCell.instruction(0, 15), + RASPCell.operand(1, 4), + RASPCell.instruction(2, 15), + RASPCell.operand(3, 0), + RASPCell.instruction(4, 18) ), List.of( - new RASPLabel() { - @Override - public int getAddress() { - return 4; - } + new RASPLabel() { + @Override + public int getAddress() { + return 4; + } - @Override - public String getLabel() { - return "HERE"; + @Override + public String getLabel() { + return "HERE"; + } } - } )); engine.reset(0); diff --git a/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/MemoryStub.java b/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/MemoryStub.java index afc56e450..0e07f24d5 100644 --- a/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/MemoryStub.java +++ b/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/MemoryStub.java @@ -81,12 +81,12 @@ public Optional getLabel(int address) { } @Override - public void setInputs(List inputs) { - this.inputs.addAll(inputs); + public List getInputs() { + return inputs; } @Override - public List getInputs() { - return inputs; + public void setInputs(List inputs) { + this.inputs.addAll(inputs); } } diff --git a/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/RASPCell.java b/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/RASPCell.java index 9ed65f358..cecd43ca8 100644 --- a/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/RASPCell.java +++ b/plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/RASPCell.java @@ -31,6 +31,14 @@ private RASPCell(boolean isInstruction, int address, int value) { this.value = value; } + public static RASPCell instruction(int address, int opcode) { + return new RASPCell(true, address, opcode); + } + + public static RASPCell operand(int address, int value) { + return new RASPCell(false, address, value); + } + @Override public boolean isInstruction() { return isInstruction; @@ -45,12 +53,4 @@ public int getAddress() { public int getValue() { return value; } - - public static RASPCell instruction(int address, int opcode) { - return new RASPCell(true, address, opcode); - } - - public static RASPCell operand(int address, int value) { - return new RASPCell(false, address, value); - } } diff --git a/plugins/cpu/ssem-cpu/build.gradle b/plugins/cpu/ssem-cpu/build.gradle index 13f7e7112..5168419c7 100644 --- a/plugins/cpu/ssem-cpu/build.gradle +++ b/plugins/cpu/ssem-cpu/build.gradle @@ -63,8 +63,8 @@ edigen { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/CpuImpl.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/CpuImpl.java index 07516f548..d79106004 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/CpuImpl.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/CpuImpl.java @@ -26,11 +26,11 @@ import net.emustudio.emulib.plugins.cpu.Disassembler; import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.debugger.BreakpointColumn; import net.emustudio.emulib.runtime.interaction.debugger.DebuggerTable; import net.emustudio.emulib.runtime.interaction.debugger.MnemoColumn; import net.emustudio.emulib.runtime.interaction.debugger.OpcodeColumn; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.cpu.ssem.gui.CpuPanel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,8 +42,8 @@ import java.util.ResourceBundle; @PluginRoot( - type = PLUGIN_TYPE.CPU, - title = "SSEM CPU" + type = PLUGIN_TYPE.CPU, + title = "SSEM CPU" ) @SuppressWarnings("unused") public class CpuImpl extends AbstractCPU { @@ -65,7 +65,7 @@ public void initialize() throws PluginInitializationException { memory = applicationApi.getContextPool().getMemoryContext(pluginID, MemoryContext.class); if (memory.getDataType() != Byte.class) { throw new PluginInitializationException( - "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() + "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() ); } Decoder decoder = new DecoderImpl(memory); @@ -99,8 +99,8 @@ public JPanel getStatusPanel() { DebuggerTable debugTable = applicationApi.getDebuggerTable(); if (debugTable != null) { debugTable.setDebuggerColumns(Arrays.asList( - new BreakpointColumn(this), new LineColumn(), new MnemoColumn(disassembler), - new OpcodeColumn(disassembler) + new BreakpointColumn(this), new LineColumn(), new MnemoColumn(disassembler), + new OpcodeColumn(disassembler) )); } diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java index 4d8364405..92a781f6c 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/EmulatorEngine.java @@ -40,23 +40,10 @@ import static net.emustudio.plugins.cpu.ssem.DecoderImpl.LINE; public class EmulatorEngine { - private final static Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); - public final static int INSTRUCTIONS_PER_SECOND = 700; final static int LINE_MASK = 0b11111000; - - private final TimingEstimator estimator = new TimingEstimator(); - private volatile long waitNanos = -1; - - private final MemoryContext memory; - private final Decoder decoder; - private final Function isBreakpointSet; - - public final AtomicInteger Acc = new AtomicInteger(); - public final AtomicInteger CI = new AtomicInteger(); - + private final static Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); private static final Method[] DISPATCH_TABLE = new Method[8]; - private final Bits emptyBits = new Bits(0, 0); static { try { @@ -72,6 +59,15 @@ public class EmulatorEngine { } } + public final AtomicInteger Acc = new AtomicInteger(); + public final AtomicInteger CI = new AtomicInteger(); + private final TimingEstimator estimator = new TimingEstimator(); + private final MemoryContext memory; + private final Decoder decoder; + private final Function isBreakpointSet; + private final Bits emptyBits = new Bits(0, 0); + private volatile long waitNanos = -1; + EmulatorEngine(MemoryContext memory, Function isBreakpointSet) { this.memory = Objects.requireNonNull(memory); this.isBreakpointSet = Objects.requireNonNull(isBreakpointSet); diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/TimingEstimator.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/TimingEstimator.java index f0b9580fd..c7b76ac8a 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/TimingEstimator.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/TimingEstimator.java @@ -27,38 +27,38 @@ public class TimingEstimator { private final short[] memory = new short[]{ - 0x06, 0xA4, 0x41, 0x04, - 0x9B, 0xF2, 0x20, 0x88, - 0x82, 0x16, 0x88, 0x50, - 0x02, 0x13, 0x42, 0x60, - 0xEB, 0xF1, 0xAA, 0x94, - 0x80, 0xC1, 0x10, 0xA9, - 0x81, 0xE1, 0x09, 0x0C, - 0x81, 0xE1, 0x06, 0x02, - 0x98, 0x06, 0x86, 0x41, - 0xA9, 0xE2, 0x49, 0x02, - 0x01, 0xE3, 0x34, 0x84, - 0x69, 0xE1, 0x30, 0x48, - 0xE9, 0xE1, 0x48, 0x30, - 0xA8, 0xC6, 0x84, 0x30, - 0xA1, 0xE1, 0x02, 0x48, - 0x13, 0xF6, 0x01, 0x84, - 0x07, 0xF9, 0x00, 0x82, - 0x83, 0xF6, 0xFF, 0xFF, - 0xA9, 0xE2, 0x66, 0x66, - 0xA8, 0xC6, 0xFF, 0xFF, - 0x18, 0xC0, 0xFF, 0xFF, - 0x60, 0x00, 0x00, 0x00, - 0xE0, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0xF0, 0x20, - 0x00, 0x02, 0x08, 0x50, - 0x00, 0x02, 0x28, 0x20, - 0x01, 0xFA, 0x08, 0x38, - 0x02, 0x01, 0xF0, 0x20, - 0x1E, 0x78, 0x80, 0x20, - 0x3F, 0xFF, 0xE0, 0x50 + 0x06, 0xA4, 0x41, 0x04, + 0x9B, 0xF2, 0x20, 0x88, + 0x82, 0x16, 0x88, 0x50, + 0x02, 0x13, 0x42, 0x60, + 0xEB, 0xF1, 0xAA, 0x94, + 0x80, 0xC1, 0x10, 0xA9, + 0x81, 0xE1, 0x09, 0x0C, + 0x81, 0xE1, 0x06, 0x02, + 0x98, 0x06, 0x86, 0x41, + 0xA9, 0xE2, 0x49, 0x02, + 0x01, 0xE3, 0x34, 0x84, + 0x69, 0xE1, 0x30, 0x48, + 0xE9, 0xE1, 0x48, 0x30, + 0xA8, 0xC6, 0x84, 0x30, + 0xA1, 0xE1, 0x02, 0x48, + 0x13, 0xF6, 0x01, 0x84, + 0x07, 0xF9, 0x00, 0x82, + 0x83, 0xF6, 0xFF, 0xFF, + 0xA9, 0xE2, 0x66, 0x66, + 0xA8, 0xC6, 0xFF, 0xFF, + 0x18, 0xC0, 0xFF, 0xFF, + 0x60, 0x00, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xF0, 0x20, + 0x00, 0x02, 0x08, 0x50, + 0x00, 0x02, 0x28, 0x20, + 0x01, 0xFA, 0x08, 0x38, + 0x02, 0x01, 0xF0, 0x20, + 0x1E, 0x78, 0x80, 0x20, + 0x3F, 0xFF, 0xE0, 0x50 }; private final MemoryContext memoryContext = new AbstractMemoryContext<>() { @@ -103,8 +103,8 @@ public long estimateWaitNanos(int instructionsPerSecond) { EmulatorEngine engine = new EmulatorEngine(memoryContext, position -> false); int testInstructionsCount = 5000; - assert(testInstructionsCount > instructionsPerSecond); - double coeff = (double)instructionsPerSecond / testInstructionsCount; + assert (testInstructionsCount > instructionsPerSecond); + double coeff = (double) instructionsPerSecond / testInstructionsCount; long start = System.nanoTime(); for (int i = 0; i < testInstructionsCount; i++) { @@ -122,7 +122,7 @@ public long estimateWaitNanos(int instructionsPerSecond) { // T2 = T1 * 700 / X double t2 = t1 * coeff; - assert(t1 > t2); + assert (t1 > t2); // T2 is the real time needed to perform 700 instructions, it it much less than 1 second @@ -132,6 +132,6 @@ public long estimateWaitNanos(int instructionsPerSecond) { // If we wanted to wait after each instruction (more smooth), then: // wait = (1 second - T2) / 700 - return (long)((TimeUnit.SECONDS.toNanos(1) - t2) / instructionsPerSecond); + return (long) ((TimeUnit.SECONDS.toNanos(1) - t2) / instructionsPerSecond); } } diff --git a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java index 1f2d8383e..e2d08bd27 100644 --- a/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java +++ b/plugins/cpu/ssem-cpu/src/main/java/net/emustudio/plugins/cpu/ssem/gui/CpuPanel.java @@ -34,7 +34,23 @@ public class CpuPanel extends JPanel { private final EmulatorEngine engine; private final MemoryContext memory; - + private JLabel lblRunState; + private JLabel lblSpeed; + private JTextField txtA; + private JTextField txtDecA; + private JTextField txtBinA; + private JTextField txtBinLine; + private JTextField txtBinMCI; + private JTextField txtBinMLine; + private JTextField txtCI; + private JTextField txtDecCI; + private JTextField txtBinCI; + private JTextField txtLine; + private JTextField txtDecLine; + private JTextField txtMCI; + private JTextField txtDecMCI; + private JTextField txtMLine; + private JTextField txtDecMLine; public CpuPanel(CPU cpu, EmulatorEngine engine, MemoryContext memory) { this.engine = Objects.requireNonNull(engine); this.memory = Objects.requireNonNull(memory); @@ -44,63 +60,6 @@ public CpuPanel(CPU cpu, EmulatorEngine engine, MemoryContext memory) { lblSpeed.setText(String.valueOf(EmulatorEngine.INSTRUCTIONS_PER_SECOND)); } - private final class Updater implements CPU.CPUListener { - - @Override - public void runStateChanged(CPU.RunState rs) { - lblRunState.setText(rs.toString().toUpperCase()); - } - - @Override - public void internalStateChanged() { - int acc = engine.Acc.get(); - int ci = engine.CI.get(); - - txtA.setText(String.format("%08x", acc)); - txtDecA.setText(String.format("%d", acc)); - txtCI.setText(String.format("%08x", ci / 4)); - txtDecCI.setText(String.format("%d", ci / 4)); - txtBinA.setText(formatBinary(acc)); - txtBinCI.setText(formatBinary(ci)); - - try { - Byte[] mCI = memory.read(ci, 4); - byte line = (byte) NumberUtils.reverseBits(mCI[0] & 0b11111000, 8); - Byte[] mLine = memory.read(line * 4, 4); - - txtMCI.setText(String.format("%08x", NumberUtils.readInt(mCI, NumberUtils.Strategy.REVERSE_BITS))); - txtLine.setText(String.format("%02x", line)); - txtMLine.setText(String.format("%08x", NumberUtils.readInt(mLine, NumberUtils.Strategy.REVERSE_BITS))); - - txtDecMCI.setText(String.format("%d", NumberUtils.readInt(mCI, NumberUtils.Strategy.REVERSE_BITS))); - txtDecLine.setText(String.format("%d", line)); - txtDecMLine.setText(String.format("%d", NumberUtils.readInt(mLine, NumberUtils.Strategy.REVERSE_BITS))); - - txtBinMCI.setText(formatBinary(NumberUtils.readInt(mCI, NumberUtils.Strategy.BIG_ENDIAN))); - txtBinLine.setText(formatBinary(line, 8)); - txtBinMLine.setText(formatBinary(NumberUtils.readInt(mLine, NumberUtils.Strategy.BIG_ENDIAN))); - } catch (IndexOutOfBoundsException e) { - txtLine.setText("?"); - txtDecLine.setText("?"); - txtMCI.setText("?"); - txtDecMCI.setText("?"); - txtMLine.setText("?"); - txtDecMLine.setText("?"); - txtBinMCI.setText("?"); - txtBinMLine.setText("?"); - } - } - - private String formatBinary(int number) { - return formatBinary(number, 32); - } - - private String formatBinary(int number, int length) { - return formatBinaryString(number, length, 4, true); - } - - } - /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -152,25 +111,25 @@ private void initComponents() { GroupLayout jPanel1Layout = new GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(lblRunState) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(lblSpeed) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel7) - .addContainerGap()) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(lblRunState) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lblSpeed) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel7) + .addContainerGap()) ); jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblRunState) - .addComponent(jLabel7) - .addComponent(lblSpeed)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblRunState) + .addComponent(jLabel7) + .addComponent(lblSpeed)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel2.setBorder(BorderFactory.createTitledBorder("Registers")); @@ -216,42 +175,42 @@ private void initComponents() { GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addGap(47, 47, 47) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel3, GroupLayout.Alignment.TRAILING) - .addComponent(jLabel2)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(txtA, GroupLayout.DEFAULT_SIZE, 81, Short.MAX_VALUE) - .addComponent(txtCI)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(txtDecA, GroupLayout.DEFAULT_SIZE, 81, Short.MAX_VALUE) - .addComponent(txtDecCI)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(txtBinCI) - .addComponent(txtBinA)) - .addContainerGap()) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(47, 47, 47) + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jLabel3, GroupLayout.Alignment.TRAILING) + .addComponent(jLabel2)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(txtA, GroupLayout.DEFAULT_SIZE, 81, Short.MAX_VALUE) + .addComponent(txtCI)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(txtDecA, GroupLayout.DEFAULT_SIZE, 81, Short.MAX_VALUE) + .addComponent(txtDecCI)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(txtBinCI) + .addComponent(txtBinA)) + .addContainerGap()) ); jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2) - .addComponent(txtA, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE) - .addComponent(txtDecA, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE) - .addComponent(txtBinA, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3) - .addComponent(txtCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtDecCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtBinCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2) + .addComponent(txtA, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDecA, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE) + .addComponent(txtBinA, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3) + .addComponent(txtCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDecCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtBinCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel3.setBorder(BorderFactory.createTitledBorder("Memory snippet")); @@ -316,105 +275,143 @@ private void initComponents() { GroupLayout jPanel3Layout = new GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(jLabel5) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtMLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtDecMLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtBinMLine)) - .addGroup(jPanel3Layout.createSequentialGroup() - .addGap(14, 14, 14) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(jLabel6) - .addComponent(jLabel4)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(txtMCI, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtDecMCI, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtBinMCI)) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(txtLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtDecLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtBinLine))))) - .addContainerGap()) + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jLabel5) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtMLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtDecMLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtBinMLine)) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGap(14, 14, 14) + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(jLabel6) + .addComponent(jLabel4)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(txtMCI, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtDecMCI, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtBinMCI)) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(txtLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtDecLine, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtBinLine))))) + .addContainerGap()) ); jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4) - .addComponent(txtMCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtDecMCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtBinMCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel6) - .addComponent(txtLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtDecLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtBinLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5) - .addComponent(txtMLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtDecMLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtBinMLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4) + .addComponent(txtMCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDecMCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtBinMCI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6) + .addComponent(txtLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDecLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtBinLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5) + .addComponent(txtMLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDecMLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtBinMLine, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); GroupLayout layout = new GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); }// //GEN-END:initComponents + private final class Updater implements CPU.CPUListener { - private JLabel lblRunState; - private JLabel lblSpeed; - private JTextField txtA; - private JTextField txtDecA; - private JTextField txtBinA; - private JTextField txtBinLine; - private JTextField txtBinMCI; - private JTextField txtBinMLine; - private JTextField txtCI; - private JTextField txtDecCI; - private JTextField txtBinCI; - private JTextField txtLine; - private JTextField txtDecLine; - private JTextField txtMCI; - private JTextField txtDecMCI; - private JTextField txtMLine; - private JTextField txtDecMLine; + @Override + public void runStateChanged(CPU.RunState rs) { + lblRunState.setText(rs.toString().toUpperCase()); + } + + @Override + public void internalStateChanged() { + int acc = engine.Acc.get(); + int ci = engine.CI.get(); + + txtA.setText(String.format("%08x", acc)); + txtDecA.setText(String.format("%d", acc)); + txtCI.setText(String.format("%08x", ci / 4)); + txtDecCI.setText(String.format("%d", ci / 4)); + txtBinA.setText(formatBinary(acc)); + txtBinCI.setText(formatBinary(ci)); + + try { + Byte[] mCI = memory.read(ci, 4); + byte line = (byte) NumberUtils.reverseBits(mCI[0] & 0b11111000, 8); + Byte[] mLine = memory.read(line * 4, 4); + + txtMCI.setText(String.format("%08x", NumberUtils.readInt(mCI, NumberUtils.Strategy.REVERSE_BITS))); + txtLine.setText(String.format("%02x", line)); + txtMLine.setText(String.format("%08x", NumberUtils.readInt(mLine, NumberUtils.Strategy.REVERSE_BITS))); + + txtDecMCI.setText(String.format("%d", NumberUtils.readInt(mCI, NumberUtils.Strategy.REVERSE_BITS))); + txtDecLine.setText(String.format("%d", line)); + txtDecMLine.setText(String.format("%d", NumberUtils.readInt(mLine, NumberUtils.Strategy.REVERSE_BITS))); + + txtBinMCI.setText(formatBinary(NumberUtils.readInt(mCI, NumberUtils.Strategy.BIG_ENDIAN))); + txtBinLine.setText(formatBinary(line, 8)); + txtBinMLine.setText(formatBinary(NumberUtils.readInt(mLine, NumberUtils.Strategy.BIG_ENDIAN))); + } catch (IndexOutOfBoundsException e) { + txtLine.setText("?"); + txtDecLine.setText("?"); + txtMCI.setText("?"); + txtDecMCI.setText("?"); + txtMLine.setText("?"); + txtDecMLine.setText("?"); + txtBinMCI.setText("?"); + txtBinMLine.setText("?"); + } + } + + private String formatBinary(int number) { + return formatBinary(number, 32); + } + + private String formatBinary(int number, int length) { + return formatBinaryString(number, length, 4, true); + } + + } // End of variables declaration//GEN-END:variables } diff --git a/plugins/cpu/ssem-cpu/src/main/resources/net/emustudio/plugins/cpu/ssem/version.properties b/plugins/cpu/ssem-cpu/src/main/resources/net/emustudio/plugins/cpu/ssem/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/cpu/ssem-cpu/src/main/resources/net/emustudio/plugins/cpu/ssem/version.properties +++ b/plugins/cpu/ssem-cpu/src/main/resources/net/emustudio/plugins/cpu/ssem/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/CpuImplTest.java b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/CpuImplTest.java index 75b38f820..312c19f78 100644 --- a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/CpuImplTest.java +++ b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/CpuImplTest.java @@ -26,7 +26,6 @@ import org.junit.Test; import static org.easymock.EasyMock.*; -import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertNotEquals; public class CpuImplTest { diff --git a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DisassemblerTest.java b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DisassemblerTest.java index 87cb75d96..84be6c050 100644 --- a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DisassemblerTest.java +++ b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/DisassemblerTest.java @@ -19,19 +19,10 @@ package net.emustudio.plugins.cpu.ssem; import net.emustudio.cpu.testsuite.memory.ByteMemoryStub; -import net.emustudio.emulib.plugins.cpu.DecodedInstruction; import net.emustudio.emulib.plugins.cpu.DisassembledInstruction; -import net.emustudio.emulib.plugins.cpu.InvalidInstructionException; -import net.emustudio.emulib.runtime.ApplicationApi; -import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.settings.PluginSettings; -import net.emustudio.emulib.runtime.helpers.Bits; import net.emustudio.emulib.runtime.helpers.NumberUtils; import org.junit.Test; -import static net.emustudio.plugins.cpu.ssem.DecoderImpl.LINE; -import static org.easymock.EasyMock.*; -import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertEquals; public class DisassemblerTest { @@ -42,7 +33,7 @@ public class DisassemblerTest { @Test public void testLDN() { memory.setMemory(new short[]{ - 0x9B, 0xE2, 0xFC, 0x3F + 0x9B, 0xE2, 0xFC, 0x3F }); DisassembledInstruction instr = disassembler.disassemble(0); @@ -53,8 +44,8 @@ public void testLDN() { @Test public void testSTO() { memory.setMemory(new short[]{ - 0,0,0,0, - 0x68, 0x06, 0x00, 0x00 + 0, 0, 0, 0, + 0x68, 0x06, 0x00, 0x00 }); DisassembledInstruction instr = disassembler.disassemble(4); diff --git a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java index ea48f167b..a5f2c7643 100644 --- a/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java +++ b/plugins/cpu/ssem-cpu/src/test/java/net/emustudio/plugins/cpu/ssem/EmulatorEngineTest.java @@ -52,17 +52,17 @@ public void testAddition() { 31: -- Sum Result will appear here */ memoryStub.setMemory(new short[]{ - 0, 0, 0, 0, - 0xB8, 0x02, 0, 0, - 0x78, 0x01, 0, 0, - 0xF8, 0x06, 0, 0, - 0xF8, 0x02, 0, 0, - 0xF8, 0x06, 0, 0, - 0x00, 0x07, 0, 0, + 0, 0, 0, 0, + 0xB8, 0x02, 0, 0, + 0x78, 0x01, 0, 0, + 0xF8, 0x06, 0, 0, + 0xF8, 0x02, 0, 0, + 0xF8, 0x06, 0, 0, + 0x00, 0x07, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0xA0, 0, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0xA0, 0, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); engine.reset(0); diff --git a/plugins/cpu/z80-cpu/build.gradle b/plugins/cpu/z80-cpu/build.gradle index 5620fc376..501e382d4 100644 --- a/plugins/cpu/z80-cpu/build.gradle +++ b/plugins/cpu/z80-cpu/build.gradle @@ -58,8 +58,8 @@ edigen { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java index 914059478..b7c5a78e7 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java @@ -31,15 +31,13 @@ @ThreadSafe public final class ContextZ80Impl implements ContextZ80 { - private final static byte NO_DATA = (byte)0xFF; public final static int DEFAULT_FREQUENCY_KHZ = 20000; - + private final static byte NO_DATA = (byte) 0xFF; private final static Logger LOGGER = LoggerFactory.getLogger(ContextZ80Impl.class); private final ConcurrentMap> devices = new ConcurrentHashMap<>(); - + private final TimedEventsProcessor tep = new TimedEventsProcessor(); private volatile EmulatorEngine engine; private volatile int clockFrequency = DEFAULT_FREQUENCY_KHZ; - private final TimedEventsProcessor tep = new TimedEventsProcessor(); public void setEngine(EmulatorEngine engine) { this.engine = engine; @@ -89,15 +87,6 @@ public boolean isInterruptSupported() { return true; } - @Override - public void setCPUFrequency(int frequency) { - if (frequency <= 0) { - throw new IllegalArgumentException("Invalid CPU frequency (expected > 0): " + frequency); - } - clockFrequency = frequency; - } - - @Override public void signalInterrupt(byte[] data) { engine.requestMaskableInterrupt(data); @@ -108,6 +97,14 @@ public int getCPUFrequency() { return clockFrequency; } + @Override + public void setCPUFrequency(int frequency) { + if (frequency <= 0) { + throw new IllegalArgumentException("Invalid CPU frequency (expected > 0): " + frequency); + } + clockFrequency = frequency; + } + @Override public void signalNonMaskableInterrupt() { engine.requestNonMaskableInterrupt(); diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java index 5eb100bbf..6c33097c2 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java @@ -44,8 +44,8 @@ import java.util.concurrent.atomic.AtomicReference; @PluginRoot( - type = PLUGIN_TYPE.CPU, - title = "Zilog Z80 CPU" + type = PLUGIN_TYPE.CPU, + title = "Zilog Z80 CPU" ) @SuppressWarnings("unused") public class CpuImpl extends AbstractCPU { @@ -71,12 +71,12 @@ public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings sett } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register Z80 CPU context", e); applicationApi.getDialogs().showError( - "Could not register Z80 CPU context. Please see log file for more details.", getTitle() + "Could not register Z80 CPU context. Please see log file for more details.", getTitle() ); } initializer = new InitializerZ80( - this, pluginID, applicationApi.getContextPool(), settings, context + this, pluginID, applicationApi.getContextPool(), settings, context ); } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java index 7d1ed8271..a0f4b2eff 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java @@ -26,8 +26,6 @@ import java.lang.invoke.MethodType; public class DispatchTables { - private final static Logger LOGGER = LoggerFactory.getLogger(DispatchTables.class); - public final static MethodHandle[] DISPATCH_TABLE = new MethodHandle[256]; public final static MethodHandle[] DISPATCH_TABLE_ED = new MethodHandle[256]; public final static MethodHandle[] DISPATCH_TABLE_CB = new MethodHandle[256]; @@ -35,6 +33,7 @@ public class DispatchTables { public final static MethodHandle[] DISPATCH_TABLE_DD_CB = new MethodHandle[256]; public final static MethodHandle[] DISPATCH_TABLE_FD = new MethodHandle[256]; public final static MethodHandle[] DISPATCH_TABLE_FD_CB = new MethodHandle[256]; + private final static Logger LOGGER = LoggerFactory.getLogger(DispatchTables.class); static { MethodHandles.Lookup lookup = MethodHandles.lookup(); diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index bd61e95ed..423a02fa4 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -47,44 +47,35 @@ */ // TODO: set frequency runtime public class EmulatorEngine implements CpuEngine { - private final static Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); - public static final int REG_A = 7, REG_B = 0, REG_C = 1, REG_D = 2, REG_E = 3, REG_H = 4, REG_L = 5; public static final int FLAG_S = 0x80, FLAG_Z = 0x40, FLAG_Y = 0x20, FLAG_H = 0x10, FLAG_X = 0x8, FLAG_PV = 0x4, FLAG_N = 0x02, FLAG_C = 0x1; - public static final int FLAG_SZP = FLAG_S | FLAG_Z | FLAG_PV; - + private final static Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); private final static int[] CONDITION = new int[]{ - FLAG_Z, FLAG_Z, FLAG_C, FLAG_C, FLAG_PV, FLAG_PV, FLAG_S, FLAG_S + FLAG_Z, FLAG_Z, FLAG_C, FLAG_C, FLAG_PV, FLAG_PV, FLAG_S, FLAG_S }; private final static int[] CONDITION_VALUES = new int[]{ - 0, FLAG_Z, 0, FLAG_C, 0, FLAG_PV, 0, FLAG_S + 0, FLAG_Z, 0, FLAG_C, 0, FLAG_PV, 0, FLAG_S }; - + public final int[] regs = new int[8]; + public final int[] regs2 = new int[8]; + public final boolean[] IFF = new boolean[2]; // interrupt enable flip-flops private final ContextZ80Impl context; private final TimedEventsProcessor tep; private final MemoryContext memory; private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); - - private int lastOpcode; - - public final int[] regs = new int[8]; - public final int[] regs2 = new int[8]; + private final Queue pendingInterrupts = new ConcurrentLinkedQueue<>(); // must be thread-safe; can cause stack overflow + // non-maskable interrupts are always executed + private final AtomicBoolean pendingNonMaskableInterrupt = new AtomicBoolean(); public int flags = 2; public int flags2 = 2; - // special registers public int PC = 0, SP = 0, IX = 0, IY = 0; public int I = 0, R = 0; // interrupt r., refresh r. public int memptr = 0; // internal register, https://gist.github.com/drhelius/8497817 - - public final boolean[] IFF = new boolean[2]; // interrupt enable flip-flops - private boolean interruptSkip; // when EI enabled, skip next instruction interrupt public byte interruptMode = 0; - private final Queue pendingInterrupts = new ConcurrentLinkedQueue<>(); // must be thread-safe; can cause stack overflow - // non-maskable interrupts are always executed - private final AtomicBoolean pendingNonMaskableInterrupt = new AtomicBoolean(); - + private int lastOpcode; + private boolean interruptSkip; // when EI enabled, skip next instruction interrupt private RunState currentRunState = RunState.STATE_STOPPED_NORMAL; private volatile long executedCycles = 0; @@ -97,6 +88,35 @@ public EmulatorEngine(MemoryContext memory, ContextZ80Impl context) { LOGGER.info("Sleep precision: " + SleepUtils.SLEEP_PRECISION + " nanoseconds."); } + public static String intToFlags(int flags) { + String flagsString = ""; + if ((flags & FLAG_S) == FLAG_S) { + flagsString += "S"; + } + if ((flags & FLAG_Z) == FLAG_Z) { + flagsString += "Z"; + } + if ((flags & FLAG_Y) == FLAG_Y) { + flagsString += "Y"; + } + if ((flags & FLAG_H) == FLAG_H) { + flagsString += "H"; + } + if ((flags & FLAG_X) == FLAG_X) { + flagsString += "X"; + } + if ((flags & FLAG_PV) == FLAG_PV) { + flagsString += "P"; + } + if ((flags & FLAG_N) == FLAG_N) { + flagsString += "N"; + } + if ((flags & FLAG_C) == FLAG_C) { + flagsString += "C"; + } + return flagsString; + } + @Override public void setDispatchListener(DispatchListener dispatchListener) { this.dispatchListener = dispatchListener; @@ -399,7 +419,6 @@ private void incrementR() { R = (R & 0x80) | (((R & 0x7F) + 1) & 0x7F); } - int I_NOP() { return 4; } @@ -424,8 +443,8 @@ int I_ADD_HL_RP() { int res = hl + rp; flags = (flags & FLAG_SZP) | - (((hl ^ res ^ rp) >>> 8) & FLAG_H) | - ((res >>> 16) & FLAG_C) | TABLE_XY[(res >>> 8) & 0xFF]; + (((hl ^ res ^ rp) >>> 8) & FLAG_H) | + ((res >>> 16) & FLAG_C) | TABLE_XY[(res >>> 8) & 0xFF]; regs[REG_H] = (res >>> 8) & 0xFF; regs[REG_L] = res & 0xFF; @@ -733,19 +752,19 @@ int I_DAA() { regs[REG_A] = ((flags & FLAG_N) != 0 ? regs[REG_A] - d : regs[REG_A] + d) & 0xFF; flags = TABLE_SZ[regs[REG_A]] - | PARITY_TABLE[regs[REG_A]] - | TABLE_XY[regs[REG_A]] - | ((regs[REG_A] ^ a) & FLAG_H) - | (flags & FLAG_N) - | c; + | PARITY_TABLE[regs[REG_A]] + | TABLE_XY[regs[REG_A]] + | ((regs[REG_A] ^ a) & FLAG_H) + | (flags & FLAG_N) + | c; return 4; } int I_CPL() { regs[REG_A] = (~regs[REG_A]) & 0xFF; flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV | FLAG_C)) - | FLAG_H | FLAG_N - | TABLE_XY[regs[REG_A]]; + | FLAG_H | FLAG_N + | TABLE_XY[regs[REG_A]]; return 4; } @@ -757,8 +776,8 @@ int I_SCF() { int I_CCF() { int c = flags & FLAG_C; flags = (flags & FLAG_SZP) | (c << 4) - | TABLE_XY[regs[REG_A]] - | (c ^ FLAG_C); + | TABLE_XY[regs[REG_A]] + | (c ^ FLAG_C); return 4; } @@ -872,10 +891,10 @@ int I_SBC_HL_RP() { int res = hl - rp - (flags & FLAG_C); flags = (((hl ^ res ^ rp) >>> 8) & FLAG_H) | FLAG_N | - ((res >>> 16) & FLAG_C) | - ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | - (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | - (((rp ^ hl) & (hl ^ res) & 0x8000) >>> 13); + ((res >>> 16) & FLAG_C) | + ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | + (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | + (((rp ^ hl) & (hl ^ res) & 0x8000) >>> 13); regs[REG_H] = (res >>> 8) & 0xFF; regs[REG_L] = res & 0xFF; @@ -889,10 +908,10 @@ int I_ADC_HL_RP() { int res = hl + rp + (flags & FLAG_C); flags = (((hl ^ res ^ rp) >>> 8) & FLAG_H) | - ((res >>> 16) & FLAG_C) | - ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | - (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | - (((rp ^ hl ^ 0x8000) & (rp ^ res) & 0x8000) >>> 13); + ((res >>> 16) & FLAG_C) | + ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | + (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | + (((rp ^ hl ^ 0x8000) & (rp ^ res) & 0x8000) >>> 13); regs[REG_H] = (res >>> 8) & 0xFF; regs[REG_L] = (res & 0xFF); @@ -1130,7 +1149,7 @@ int I_LDD() { int result = regs[REG_A] + io; flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | - ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); + ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); return 16; } @@ -1186,7 +1205,7 @@ int I_LDI() { int result = regs[REG_A] + (io & 0xFF); flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | - ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); + ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); return 16; } @@ -1223,35 +1242,6 @@ int I_LDIR() { return 16; } - public static String intToFlags(int flags) { - String flagsString = ""; - if ((flags & FLAG_S) == FLAG_S) { - flagsString += "S"; - } - if ((flags & FLAG_Z) == FLAG_Z) { - flagsString += "Z"; - } - if ((flags & FLAG_Y) == FLAG_Y) { - flagsString += "Y"; - } - if ((flags & FLAG_H) == FLAG_H) { - flagsString += "H"; - } - if ((flags & FLAG_X) == FLAG_X) { - flagsString += "X"; - } - if ((flags & FLAG_PV) == FLAG_PV) { - flagsString += "P"; - } - if ((flags & FLAG_N) == FLAG_N) { - flagsString += "N"; - } - if ((flags & FLAG_C) == FLAG_C) { - flagsString += "C"; - } - return flagsString; - } - int I_INI() { byte value = context.readIO(regs[REG_C]); int address = (regs[REG_H] << 8) | regs[REG_L]; @@ -1756,9 +1746,9 @@ int I_BIT_N_R() { int result = (1 << bit) & regValue; flags = ((result != 0) ? (result & FLAG_S) : (FLAG_Z | FLAG_PV)) - | TABLE_XY[regValue] - | FLAG_H - | (flags & FLAG_C); + | TABLE_XY[regValue] + | FLAG_H + | (flags & FLAG_C); if (reg == 6) { flags &= (~FLAG_X); @@ -1825,8 +1815,8 @@ int I_ADD_II_RP(int special) { int res = special + dstRp; flags = (flags & FLAG_SZP) | - (((dstRp ^ res ^ special) >>> 8) & FLAG_H) | - ((res >>> 16) & FLAG_C) | TABLE_XY[(res >>> 8) & 0xFF]; + (((dstRp ^ res ^ special) >>> 8) & FLAG_H) | + ((res >>> 16) & FLAG_C) | TABLE_XY[(res >>> 8) & 0xFF]; return res & 0xFFFF; } @@ -2424,9 +2414,9 @@ int I_BIT_N_REF_II_N(byte operand, int special) { int result = (1 << bit) & addrValue; flags = ((flags & FLAG_C) - | FLAG_H - | ((result == 0) ? (FLAG_Z | FLAG_PV) : 0)) - | TABLE_XY[special & 0xFF]; + | FLAG_H + | ((result == 0) ? (FLAG_Z | FLAG_PV) : 0)) + | TABLE_XY[special & 0xFF]; if (bit == 7) { flags |= ((result == 0x80) ? FLAG_S : 0); } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java index f60164596..7ea55b3ff 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTables.java @@ -21,173 +21,169 @@ class EmulatorTables { public final static int[] TABLE_SUB = new int[]{ - 0x42, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x82, 0x82, 0x82, 0x82, - 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, - 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, - 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, - 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, - 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, - 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, - 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, - 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82 + 0x42, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82 }; public final static int[] TABLE_CHP = new int[]{ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, + 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, + 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, + 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }; public final static int[] TABLE_HP = new int[]{ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }; public final static int[] TABLE_SZ = new int[]{ - 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; - - final static short[] PARITY_TABLE = { - 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, - 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, - 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, - 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4 - }; - public final static int[] TABLE_XY = new int[]{ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, }; - - public final static int[] TABLE_RRCA = new int[] { - 0x0, 0x80, 0x1, 0x81, 0x2, 0x82, 0x3, 0x83, 0x4, 0x84, 0x5, 0x85, 0x6, 0x86, 0x7, 0x87, - 0x8, 0x88, 0x9, 0x89, 0xa, 0x8a, 0xb, 0x8b, 0xc, 0x8c, 0xd, 0x8d, 0xe, 0x8e, 0xf, 0x8f, - 0x10, 0x90, 0x11, 0x91, 0x12, 0x92, 0x13, 0x93, 0x14, 0x94, 0x15, 0x95, 0x16, 0x96, 0x17, 0x97, - 0x18, 0x98, 0x19, 0x99, 0x1a, 0x9a, 0x1b, 0x9b, 0x1c, 0x9c, 0x1d, 0x9d, 0x1e, 0x9e, 0x1f, 0x9f, - 0x20, 0xa0, 0x21, 0xa1, 0x22, 0xa2, 0x23, 0xa3, 0x24, 0xa4, 0x25, 0xa5, 0x26, 0xa6, 0x27, 0xa7, - 0x28, 0xa8, 0x29, 0xa9, 0x2a, 0xaa, 0x2b, 0xab, 0x2c, 0xac, 0x2d, 0xad, 0x2e, 0xae, 0x2f, 0xaf, - 0x30, 0xb0, 0x31, 0xb1, 0x32, 0xb2, 0x33, 0xb3, 0x34, 0xb4, 0x35, 0xb5, 0x36, 0xb6, 0x37, 0xb7, - 0x38, 0xb8, 0x39, 0xb9, 0x3a, 0xba, 0x3b, 0xbb, 0x3c, 0xbc, 0x3d, 0xbd, 0x3e, 0xbe, 0x3f, 0xbf, - 0x40, 0xc0, 0x41, 0xc1, 0x42, 0xc2, 0x43, 0xc3, 0x44, 0xc4, 0x45, 0xc5, 0x46, 0xc6, 0x47, 0xc7, - 0x48, 0xc8, 0x49, 0xc9, 0x4a, 0xca, 0x4b, 0xcb, 0x4c, 0xcc, 0x4d, 0xcd, 0x4e, 0xce, 0x4f, 0xcf, - 0x50, 0xd0, 0x51, 0xd1, 0x52, 0xd2, 0x53, 0xd3, 0x54, 0xd4, 0x55, 0xd5, 0x56, 0xd6, 0x57, 0xd7, - 0x58, 0xd8, 0x59, 0xd9, 0x5a, 0xda, 0x5b, 0xdb, 0x5c, 0xdc, 0x5d, 0xdd, 0x5e, 0xde, 0x5f, 0xdf, - 0x60, 0xe0, 0x61, 0xe1, 0x62, 0xe2, 0x63, 0xe3, 0x64, 0xe4, 0x65, 0xe5, 0x66, 0xe6, 0x67, 0xe7, - 0x68, 0xe8, 0x69, 0xe9, 0x6a, 0xea, 0x6b, 0xeb, 0x6c, 0xec, 0x6d, 0xed, 0x6e, 0xee, 0x6f, 0xef, - 0x70, 0xf0, 0x71, 0xf1, 0x72, 0xf2, 0x73, 0xf3, 0x74, 0xf4, 0x75, 0xf5, 0x76, 0xf6, 0x77, 0xf7, - 0x78, 0xf8, 0x79, 0xf9, 0x7a, 0xfa, 0x7b, 0xfb, 0x7c, 0xfc, 0x7d, 0xfd, 0x7e, 0xfe, 0x7f, 0xff, + public final static int[] TABLE_RRCA = new int[]{ + 0x0, 0x80, 0x1, 0x81, 0x2, 0x82, 0x3, 0x83, 0x4, 0x84, 0x5, 0x85, 0x6, 0x86, 0x7, 0x87, + 0x8, 0x88, 0x9, 0x89, 0xa, 0x8a, 0xb, 0x8b, 0xc, 0x8c, 0xd, 0x8d, 0xe, 0x8e, 0xf, 0x8f, + 0x10, 0x90, 0x11, 0x91, 0x12, 0x92, 0x13, 0x93, 0x14, 0x94, 0x15, 0x95, 0x16, 0x96, 0x17, 0x97, + 0x18, 0x98, 0x19, 0x99, 0x1a, 0x9a, 0x1b, 0x9b, 0x1c, 0x9c, 0x1d, 0x9d, 0x1e, 0x9e, 0x1f, 0x9f, + 0x20, 0xa0, 0x21, 0xa1, 0x22, 0xa2, 0x23, 0xa3, 0x24, 0xa4, 0x25, 0xa5, 0x26, 0xa6, 0x27, 0xa7, + 0x28, 0xa8, 0x29, 0xa9, 0x2a, 0xaa, 0x2b, 0xab, 0x2c, 0xac, 0x2d, 0xad, 0x2e, 0xae, 0x2f, 0xaf, + 0x30, 0xb0, 0x31, 0xb1, 0x32, 0xb2, 0x33, 0xb3, 0x34, 0xb4, 0x35, 0xb5, 0x36, 0xb6, 0x37, 0xb7, + 0x38, 0xb8, 0x39, 0xb9, 0x3a, 0xba, 0x3b, 0xbb, 0x3c, 0xbc, 0x3d, 0xbd, 0x3e, 0xbe, 0x3f, 0xbf, + 0x40, 0xc0, 0x41, 0xc1, 0x42, 0xc2, 0x43, 0xc3, 0x44, 0xc4, 0x45, 0xc5, 0x46, 0xc6, 0x47, 0xc7, + 0x48, 0xc8, 0x49, 0xc9, 0x4a, 0xca, 0x4b, 0xcb, 0x4c, 0xcc, 0x4d, 0xcd, 0x4e, 0xce, 0x4f, 0xcf, + 0x50, 0xd0, 0x51, 0xd1, 0x52, 0xd2, 0x53, 0xd3, 0x54, 0xd4, 0x55, 0xd5, 0x56, 0xd6, 0x57, 0xd7, + 0x58, 0xd8, 0x59, 0xd9, 0x5a, 0xda, 0x5b, 0xdb, 0x5c, 0xdc, 0x5d, 0xdd, 0x5e, 0xde, 0x5f, 0xdf, + 0x60, 0xe0, 0x61, 0xe1, 0x62, 0xe2, 0x63, 0xe3, 0x64, 0xe4, 0x65, 0xe5, 0x66, 0xe6, 0x67, 0xe7, + 0x68, 0xe8, 0x69, 0xe9, 0x6a, 0xea, 0x6b, 0xeb, 0x6c, 0xec, 0x6d, 0xed, 0x6e, 0xee, 0x6f, 0xef, + 0x70, 0xf0, 0x71, 0xf1, 0x72, 0xf2, 0x73, 0xf3, 0x74, 0xf4, 0x75, 0xf5, 0x76, 0xf6, 0x77, 0xf7, + 0x78, 0xf8, 0x79, 0xf9, 0x7a, 0xfa, 0x7b, 0xfb, 0x7c, 0xfc, 0x7d, 0xfd, 0x7e, 0xfe, 0x7f, 0xff, }; - - public final static int[] TABLE_RLCA = new int[] { - 0x0, 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, - 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, - 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, - 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, - 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, - 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, - 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, - 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, - 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f, - 0x21, 0x23, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b, 0x3d, 0x3f, - 0x41, 0x43, 0x45, 0x47, 0x49, 0x4b, 0x4d, 0x4f, 0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, 0x5f, - 0x61, 0x63, 0x65, 0x67, 0x69, 0x6b, 0x6d, 0x6f, 0x71, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d, 0x7f, - 0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9f, - 0xa1, 0xa3, 0xa5, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb1, 0xb3, 0xb5, 0xb7, 0xb9, 0xbb, 0xbd, 0xbf, - 0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf, 0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf, - 0xe1, 0xe3, 0xe5, 0xe7, 0xe9, 0xeb, 0xed, 0xef, 0xf1, 0xf3, 0xf5, 0xf7, 0xf9, 0xfb, 0xfd, 0xff, + public final static int[] TABLE_RLCA = new int[]{ + 0x0, 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, + 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, + 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, + 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, + 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, + 0x1, 0x3, 0x5, 0x7, 0x9, 0xb, 0xd, 0xf, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f, + 0x21, 0x23, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b, 0x3d, 0x3f, + 0x41, 0x43, 0x45, 0x47, 0x49, 0x4b, 0x4d, 0x4f, 0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, 0x5f, + 0x61, 0x63, 0x65, 0x67, 0x69, 0x6b, 0x6d, 0x6f, 0x71, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d, 0x7f, + 0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9f, + 0xa1, 0xa3, 0xa5, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb1, 0xb3, 0xb5, 0xb7, 0xb9, 0xbb, 0xbd, 0xbf, + 0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf, 0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf, + 0xe1, 0xe3, 0xe5, 0xe7, 0xe9, 0xeb, 0xed, 0xef, 0xf1, 0xf3, 0xf5, 0xf7, 0xf9, 0xfb, 0xfd, 0xff, + }; + final static short[] PARITY_TABLE = { + 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, + 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, + 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, + 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4 }; } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InstructionPrinter.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InstructionPrinter.java index 2504cdc7f..02580126c 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InstructionPrinter.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/InstructionPrinter.java @@ -40,9 +40,8 @@ public class InstructionPrinter implements DispatchListener { private final List cache = new CopyOnWriteArrayList<>(); private final AtomicInteger numberOfMatch = new AtomicInteger(); - private volatile int matchPC; private final boolean useCache; - + private volatile int matchPC; private volatile long creationTimeStamp; public InstructionPrinter(Disassembler disassembler, EmulatorEngine emulatorEngine, boolean useCache, PrintStream writer) { @@ -67,7 +66,7 @@ public void beforeDispatch() { if (useCache && !cache.contains(PC)) { if (numberOfMatch.get() != 0) { writer.println(String.format("%04d | Block from %04X to %04X; count=%d", - timeStamp, matchPC, PC, numberOfMatch.get()) + timeStamp, matchPC, PC, numberOfMatch.get()) ); } else { matchPC = PC; @@ -80,7 +79,7 @@ public void beforeDispatch() { if (numberOfMatch.get() <= 1) { writer.print(String.format("%04d | PC=%04x | %15s | %10s ", - timeStamp, instr.getAddress(), instr.getMnemo(), instr.getOpCode()) + timeStamp, instr.getAddress(), instr.getMnemo(), instr.getOpCode()) ); } } catch (InvalidInstructionException e) { @@ -92,11 +91,11 @@ public void beforeDispatch() { public void afterDispatch() { if (numberOfMatch.get() <= 1) { writer.println(String.format("|| regs=%s IX=%04x IY=%04x IFF=%1x I=%02x R=%02x | flags=%s | SP=%04x | PC=%04x", - regsToString(), emulatorEngine.IX, emulatorEngine.IY, - emulatorEngine.IFF[0] ? 1 : 0, - emulatorEngine.I, emulatorEngine.R, - intToFlags(emulatorEngine.flags), - emulatorEngine.SP, emulatorEngine.PC) + regsToString(), emulatorEngine.IX, emulatorEngine.IY, + emulatorEngine.IFF[0] ? 1 : 0, + emulatorEngine.I, emulatorEngine.R, + intToFlags(emulatorEngine.flags), + emulatorEngine.SP, emulatorEngine.PC) ); } } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/api/ContextZ80.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/api/ContextZ80.java index 4c6558b07..649280693 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/api/ContextZ80.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/api/ContextZ80.java @@ -7,7 +7,7 @@ public interface ContextZ80 extends Context8080 { /** * Signals a non-maskable interrupt. - * + *

* On the interrupt execution, CPU ignores the next instruction and instead performs a restart * at address 0066h. Routines should exit with RETN instruction. */ diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java index 2a7a6c804..2aa9134f4 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java @@ -38,7 +38,41 @@ public class StatusPanel extends JPanel { private final FlagsModel flagModel2; private volatile CPU.RunState runState = CPU.RunState.STATE_STOPPED_NORMAL; - + // Variables declaration - do not modify//GEN-BEGIN:variables + private JCheckBox chkPrintInstructions; + private JLabel lblFrequency; + private JLabel lblRunState; + private JSpinner spnFrequency; + private JTable tblFlags1; + private JTable tblFlags2; + private JTextField txtA1; + private JTextField txtA2; + private JTextField txtB1; + private JTextField txtB2; + private JTextField txtBC1; + private JTextField txtBC2; + private JTextField txtC1; + private JTextField txtC2; + private JTextField txtD1; + private JTextField txtD2; + private JTextField txtDE1; + private JTextField txtDE2; + private JTextField txtE1; + private JTextField txtE2; + private JTextField txtF1; + private JTextField txtF2; + private JTextField txtH1; + private JTextField txtH2; + private JTextField txtHL1; + private JTextField txtHL2; + private JTextField txtI; + private JTextField txtIX; + private JTextField txtIY; + private JTextField txtL1; + private JTextField txtL2; + private JTextField txtPC; + private JTextField txtR; + private JTextField txtSP; public StatusPanel(CpuImpl cpu, Context8080 context, boolean dumpInstructions) { this.cpu = cpu; this.context = context; @@ -127,7 +161,7 @@ public void updateGUI() { spnFrequency.setEnabled(true); } } - + private void initComponents() { JTabbedPane jTabbedPane1 = new JTabbedPane(); JPanel panelSet1 = new JPanel(); @@ -285,12 +319,12 @@ private void initComponents() { jScrollPane2.setBorder(null); tblFlags1.setModel(new DefaultTableModel( - new Object[][]{ + new Object[][]{ - }, - new String[]{ + }, + new String[]{ - } + } )); tblFlags1.setRowSelectionAllowed(false); jScrollPane2.setViewportView(tblFlags1); @@ -300,100 +334,100 @@ private void initComponents() { GroupLayout panelSet1Layout = new GroupLayout(panelSet1); panelSet1.setLayout(panelSet1Layout); panelSet1Layout.setHorizontalGroup( - panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelSet1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addGroup(panelSet1Layout.createSequentialGroup() - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(jLabel17) - .addComponent(jLabel14)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addGroup(panelSet1Layout.createSequentialGroup() - .addComponent(txtB1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel16)) - .addGroup(panelSet1Layout.createSequentialGroup() - .addComponent(txtD1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel20))) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(txtC1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addComponent(txtE1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(jLabel21) - .addComponent(jLabel22)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(txtBC1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addComponent(txtDE1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE))) - .addGroup(panelSet1Layout.createSequentialGroup() - .addComponent(jLabel18) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtH1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel19) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtL1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel23) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtHL1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) + panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelSet1Layout.createSequentialGroup() - .addComponent(jLabel13) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtA1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel15) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtF1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) - .addComponent(jLabel24)) - .addContainerGap(24, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(panelSet1Layout.createSequentialGroup() + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(jLabel17) + .addComponent(jLabel14)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addGroup(panelSet1Layout.createSequentialGroup() + .addComponent(txtB1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel16)) + .addGroup(panelSet1Layout.createSequentialGroup() + .addComponent(txtD1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel20))) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(txtC1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addComponent(txtE1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(jLabel21) + .addComponent(jLabel22)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(txtBC1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDE1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE))) + .addGroup(panelSet1Layout.createSequentialGroup() + .addComponent(jLabel18) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtH1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel19) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtL1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel23) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtHL1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) + .addGroup(panelSet1Layout.createSequentialGroup() + .addComponent(jLabel13) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtA1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel15) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtF1, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel24)) + .addContainerGap(24, Short.MAX_VALUE)) ); panelSet1Layout.setVerticalGroup( - panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelSet1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel13) - .addComponent(txtA1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel15) - .addComponent(txtF1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel14) - .addComponent(txtB1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel16) - .addComponent(txtC1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel21) - .addComponent(txtBC1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel17) - .addComponent(txtD1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(txtE1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel20) - .addComponent(txtDE1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel22))) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel18) - .addComponent(txtH1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel19) - .addComponent(txtL1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtHL1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel23)) - .addGap(9, 9, 9) - .addComponent(jLabel24) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 54, GroupLayout.PREFERRED_SIZE) - .addContainerGap(20, Short.MAX_VALUE)) + panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelSet1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel13) + .addComponent(txtA1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel15) + .addComponent(txtF1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel14) + .addComponent(txtB1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel16) + .addComponent(txtC1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel21) + .addComponent(txtBC1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel17) + .addComponent(txtD1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(txtE1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel20) + .addComponent(txtDE1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel22))) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel18) + .addComponent(txtH1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel19) + .addComponent(txtL1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtHL1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel23)) + .addGap(9, 9, 9) + .addComponent(jLabel24) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 54, GroupLayout.PREFERRED_SIZE) + .addContainerGap(20, Short.MAX_VALUE)) ); jTabbedPane1.addTab("Set 1", panelSet1); @@ -478,12 +512,12 @@ private void initComponents() { jScrollPane1.setBorder(null); tblFlags2.setModel(new DefaultTableModel( - new Object[][]{ + new Object[][]{ - }, - new String[]{ + }, + new String[]{ - } + } )); tblFlags2.setRowSelectionAllowed(false); jScrollPane1.setViewportView(tblFlags2); @@ -493,100 +527,100 @@ private void initComponents() { GroupLayout panelSet2Layout = new GroupLayout(panelSet2); panelSet2.setLayout(panelSet2Layout); panelSet2Layout.setHorizontalGroup( - panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelSet2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addGroup(panelSet2Layout.createSequentialGroup() - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(jLabel4) - .addComponent(jLabel1)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addGroup(panelSet2Layout.createSequentialGroup() - .addComponent(txtB2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel2)) - .addGroup(panelSet2Layout.createSequentialGroup() - .addComponent(txtD2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel5))) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(txtC2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addComponent(txtE2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(jLabel3) - .addComponent(jLabel6)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(txtBC2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addComponent(txtDE2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE))) + panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelSet2Layout.createSequentialGroup() - .addComponent(jLabel7) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtH2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel8) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtL2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel9) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtHL2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) - .addGroup(panelSet2Layout.createSequentialGroup() - .addComponent(jLabel10) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtA2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel11) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtF2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) - .addComponent(jLabel12)) - .addContainerGap(24, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(panelSet2Layout.createSequentialGroup() + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(jLabel4) + .addComponent(jLabel1)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addGroup(panelSet2Layout.createSequentialGroup() + .addComponent(txtB2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2)) + .addGroup(panelSet2Layout.createSequentialGroup() + .addComponent(txtD2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel5))) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(txtC2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addComponent(txtE2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(jLabel3) + .addComponent(jLabel6)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(txtBC2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addComponent(txtDE2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE))) + .addGroup(panelSet2Layout.createSequentialGroup() + .addComponent(jLabel7) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtH2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel8) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtL2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel9) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtHL2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) + .addGroup(panelSet2Layout.createSequentialGroup() + .addComponent(jLabel10) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtA2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel11) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtF2, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel12)) + .addContainerGap(24, Short.MAX_VALUE)) ); panelSet2Layout.setVerticalGroup( - panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelSet2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel10) - .addComponent(txtA2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel11) - .addComponent(txtF2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) - .addComponent(txtB2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel2) - .addComponent(txtC2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel3) - .addComponent(txtBC2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4) - .addComponent(txtD2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(txtE2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel5) - .addComponent(txtDE2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel6))) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel7) - .addComponent(txtH2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel8) - .addComponent(txtL2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtHL2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel9)) - .addGap(9, 9, 9) - .addComponent(jLabel12) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 54, GroupLayout.PREFERRED_SIZE) - .addContainerGap(20, Short.MAX_VALUE)) + panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelSet2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel10) + .addComponent(txtA2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel11) + .addComponent(txtF2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(txtB2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2) + .addComponent(txtC2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel3) + .addComponent(txtBC2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel4) + .addComponent(txtD2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(txtE2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel5) + .addComponent(txtDE2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6))) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSet2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel7) + .addComponent(txtH2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel8) + .addComponent(txtL2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtHL2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel9)) + .addGap(9, 9, 9) + .addComponent(jLabel12) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 54, GroupLayout.PREFERRED_SIZE) + .addContainerGap(20, Short.MAX_VALUE)) ); jTabbedPane1.addTab("Set 2", panelSet2); @@ -636,58 +670,58 @@ private void initComponents() { GroupLayout jPanel1Layout = new GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel25) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtSP, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addGap(10, 10, 10) - .addComponent(jLabel28) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtIY, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel26) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtPC, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addGap(10, 10, 10) - .addComponent(jLabel27) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtIX, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE))) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel29) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtI, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel30) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtR, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE))) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel25) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtSP, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(jLabel28) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtIY, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel26) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtPC, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(jLabel27) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtIX, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel29) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtI, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(jLabel30) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtR, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE))) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel26) - .addComponent(txtPC, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtIX, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel27) - .addComponent(jLabel29) - .addComponent(txtI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel28) - .addComponent(txtIY, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtSP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel25) - .addComponent(jLabel30) - .addComponent(txtR, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel26) + .addComponent(txtPC, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtIX, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel27) + .addComponent(jLabel29) + .addComponent(txtI, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel28) + .addComponent(txtIY, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtSP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel25) + .addComponent(jLabel30) + .addComponent(txtR, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel2.setBorder(BorderFactory.createTitledBorder("Run control")); @@ -715,71 +749,71 @@ private void initComponents() { GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jSeparator1) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblRunState) - .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(jLabel31) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnFrequency, GroupLayout.PREFERRED_SIZE, 91, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel33)) - .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(jLabel35) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblFrequency)) - .addComponent(chkPrintInstructions)) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jSeparator1) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblRunState) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel31) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnFrequency, GroupLayout.PREFERRED_SIZE, 91, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel33)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel35) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblFrequency)) + .addComponent(chkPrintInstructions)) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) ); jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(lblRunState) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSeparator1, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel31) - .addComponent(spnFrequency, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel33)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel35) - .addComponent(lblFrequency)) - .addGap(18, 18, 18) - .addComponent(chkPrintInstructions) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(lblRunState) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSeparator1, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel31) + .addComponent(spnFrequency, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel33)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel35) + .addComponent(lblFrequency)) + .addGap(18, 18, 18) + .addComponent(chkPrintInstructions) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); GroupLayout layout = new GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jTabbedPane1, GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jTabbedPane1, GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jTabbedPane1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jTabbedPane1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -790,42 +824,5 @@ private void chkPrintInstructionsActionPerformed(java.awt.event.ActionEvent evt) cpu.getEngine().setDispatchListener(null); } }//GEN-LAST:event_chkPrintInstructionsActionPerformed - - - // Variables declaration - do not modify//GEN-BEGIN:variables - private JCheckBox chkPrintInstructions; - private JLabel lblFrequency; - private JLabel lblRunState; - private JSpinner spnFrequency; - private JTable tblFlags1; - private JTable tblFlags2; - private JTextField txtA1; - private JTextField txtA2; - private JTextField txtB1; - private JTextField txtB2; - private JTextField txtBC1; - private JTextField txtBC2; - private JTextField txtC1; - private JTextField txtC2; - private JTextField txtD1; - private JTextField txtD2; - private JTextField txtDE1; - private JTextField txtDE2; - private JTextField txtE1; - private JTextField txtE2; - private JTextField txtF1; - private JTextField txtF2; - private JTextField txtH1; - private JTextField txtH2; - private JTextField txtHL1; - private JTextField txtHL2; - private JTextField txtI; - private JTextField txtIX; - private JTextField txtIY; - private JTextField txtL1; - private JTextField txtL2; - private JTextField txtPC; - private JTextField txtR; - private JTextField txtSP; // End of variables declaration//GEN-END:variables } diff --git a/plugins/cpu/z80-cpu/src/main/resources/net/emustudio/plugins/cpu/zilogZ80/version.properties b/plugins/cpu/z80-cpu/src/main/resources/net/emustudio/plugins/cpu/zilogZ80/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/cpu/z80-cpu/src/main/resources/net/emustudio/plugins/cpu/zilogZ80/version.properties +++ b/plugins/cpu/z80-cpu/src/main/resources/net/emustudio/plugins/cpu/zilogZ80/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java index 3e2bd611b..190430ecd 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java @@ -38,16 +38,16 @@ public void testADD_A_R() { ByteTestBuilder test = additionTestBuilder(); Generator.forSome8bitBinaryWhichEqual( - test.run(0x87) + test.run(0x87) ); Generator.forSome8bitBinary( - test.secondIsRegister(REG_B).run(0x80), - test.secondIsRegister(REG_C).run(0x81), - test.secondIsRegister(REG_D).run(0x82), - test.secondIsRegister(REG_E).run(0x83), - test.secondIsRegister(REG_H).run(0x84), - test.secondIsRegister(REG_L).run(0x85), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x86) + test.secondIsRegister(REG_B).run(0x80), + test.secondIsRegister(REG_C).run(0x81), + test.secondIsRegister(REG_D).run(0x82), + test.secondIsRegister(REG_E).run(0x83), + test.secondIsRegister(REG_H).run(0x84), + test.secondIsRegister(REG_L).run(0x85), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x86) ); } @@ -56,41 +56,41 @@ public void testADD_A_N() { ByteTestBuilder test = additionTestBuilder(); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xC6) + test.runWithSecondOperand(0xC6) ); } @Test public void testADC_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( - test.run(0x8F) + test.run(0x8F) ); Generator.forSome8bitBinary( - test.secondIsRegister(REG_B).run(0x88), - test.secondIsRegister(REG_C).run(0x89), - test.secondIsRegister(REG_D).run(0x8A), - test.secondIsRegister(REG_E).run(0x8B), - test.secondIsRegister(REG_H).run(0x8C), - test.secondIsRegister(REG_L).run(0x8D), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x8E) + test.secondIsRegister(REG_B).run(0x88), + test.secondIsRegister(REG_C).run(0x89), + test.secondIsRegister(REG_D).run(0x8A), + test.secondIsRegister(REG_E).run(0x8B), + test.secondIsRegister(REG_H).run(0x8C), + test.secondIsRegister(REG_L).run(0x8D), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x8E) ); } @Test public void testADC_A_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xCE) + test.runWithSecondOperand(0xCE) ); } @@ -99,16 +99,16 @@ public void testSUB_R() { ByteTestBuilder test = subtractionTestBuilder(); Generator.forSome8bitBinaryWhichEqual( - test.run(0x97) + test.run(0x97) ); Generator.forSome8bitBinary( - test.secondIsRegister(REG_B).run(0x90), - test.secondIsRegister(REG_C).run(0x91), - test.secondIsRegister(REG_D).run(0x92), - test.secondIsRegister(REG_E).run(0x93), - test.secondIsRegister(REG_H).run(0x94), - test.secondIsRegister(REG_L).run(0x95), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x96) + test.secondIsRegister(REG_B).run(0x90), + test.secondIsRegister(REG_C).run(0x91), + test.secondIsRegister(REG_D).run(0x92), + test.secondIsRegister(REG_E).run(0x93), + test.secondIsRegister(REG_H).run(0x94), + test.secondIsRegister(REG_L).run(0x95), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x96) ); } @@ -117,146 +117,146 @@ public void testSUB_N() { ByteTestBuilder test = subtractionTestBuilder(); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xD6) + test.runWithSecondOperand(0xD6) ); } @Test public void testSBC_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> ((context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> ((context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( - test.run(0x9F) + test.run(0x9F) ); Generator.forSome8bitBinary( - test.secondIsRegister(REG_B).run(0x98), - test.secondIsRegister(REG_C).run(0x99), - test.secondIsRegister(REG_D).run(0x9A), - test.secondIsRegister(REG_E).run(0x9B), - test.secondIsRegister(REG_H).run(0x9C), - test.secondIsRegister(REG_L).run(0x9D), - test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x9E) + test.secondIsRegister(REG_B).run(0x98), + test.secondIsRegister(REG_C).run(0x99), + test.secondIsRegister(REG_D).run(0x9A), + test.secondIsRegister(REG_E).run(0x9B), + test.secondIsRegister(REG_H).run(0x9C), + test.secondIsRegister(REG_L).run(0x9D), + test.setPair(REG_PAIR_HL, 1).secondIsMemoryByteAt(1).run(0x9E) ); } @Test public void testSBC_A_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xDE) + test.runWithSecondOperand(0xDE) ); } @Test public void testINC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyFlags(new FlagsCheckImpl() - .sign().zero().overflow().halfCarry() - .subtractionIsReset() - .carryIsPreserved(), - context -> context.first + 1) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .verifyFlags(new FlagsCheckImpl() + .sign().zero().overflow().halfCarry() + .subtractionIsReset() + .carryIsPreserved(), + context -> context.first + 1) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_B).verifyRegister(REG_B).run(0x04), - test.firstIsRegister(REG_C).verifyRegister(REG_C).run(0x0C), - test.firstIsRegister(REG_D).verifyRegister(REG_D).run(0x14), - test.firstIsRegister(REG_E).verifyRegister(REG_E).run(0x1C), - test.firstIsRegister(REG_H).verifyRegister(REG_H).run(0x24), - test.firstIsRegister(REG_L).verifyRegister(REG_L).run(0x2C), - test.firstIsRegister(REG_A).verifyRegister(REG_A).run(0x3C), - test.firstIsMemoryByteAt(1).setPair(REG_PAIR_HL, 1).verifyByte(1).run(0x34) + test.firstIsRegister(REG_B).verifyRegister(REG_B).run(0x04), + test.firstIsRegister(REG_C).verifyRegister(REG_C).run(0x0C), + test.firstIsRegister(REG_D).verifyRegister(REG_D).run(0x14), + test.firstIsRegister(REG_E).verifyRegister(REG_E).run(0x1C), + test.firstIsRegister(REG_H).verifyRegister(REG_H).run(0x24), + test.firstIsRegister(REG_L).verifyRegister(REG_L).run(0x2C), + test.firstIsRegister(REG_A).verifyRegister(REG_A).run(0x3C), + test.firstIsMemoryByteAt(1).setPair(REG_PAIR_HL, 1).verifyByte(1).run(0x34) ); } @Test public void testDEC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyFlags(new FlagsCheckImpl() - .setSecond(c -> 1) - .sign().zero().overflowSub().halfBorrow() - .subtractionIsSet() - .carryIsPreserved(), - context -> context.first - 1) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .verifyFlags(new FlagsCheckImpl() + .setSecond(c -> 1) + .sign().zero().overflowSub().halfBorrow() + .subtractionIsSet() + .carryIsPreserved(), + context -> context.first - 1) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_B).verifyRegister(REG_B).run(0x05), - test.firstIsRegister(REG_C).verifyRegister(REG_C).run(0x0D), - test.firstIsRegister(REG_D).verifyRegister(REG_D).run(0x15), - test.firstIsRegister(REG_E).verifyRegister(REG_E).run(0x1D), - test.firstIsRegister(REG_H).verifyRegister(REG_H).run(0x25), - test.firstIsRegister(REG_L).verifyRegister(REG_L).run(0x2D), - test.firstIsRegister(REG_A).verifyRegister(REG_A).run(0x3D), - test.firstIsMemoryByteAt(1).setPair(REG_PAIR_HL, 1).verifyByte(1).run(0x35) + test.firstIsRegister(REG_B).verifyRegister(REG_B).run(0x05), + test.firstIsRegister(REG_C).verifyRegister(REG_C).run(0x0D), + test.firstIsRegister(REG_D).verifyRegister(REG_D).run(0x15), + test.firstIsRegister(REG_E).verifyRegister(REG_E).run(0x1D), + test.firstIsRegister(REG_H).verifyRegister(REG_H).run(0x25), + test.firstIsRegister(REG_L).verifyRegister(REG_L).run(0x2D), + test.firstIsRegister(REG_A).verifyRegister(REG_A).run(0x3D), + test.firstIsMemoryByteAt(1).setPair(REG_PAIR_HL, 1).verifyByte(1).run(0x35) ); } @Test public void testINC_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .clearOtherVerifiersAfterRun(); + .clearOtherVerifiersAfterRun(); Function, Integer> verifier = context -> context.first + 1; Generator.forSome16bitUnary( - test.firstIsPair(REG_PAIR_BC).verifyPair(REG_PAIR_BC, verifier).run(0x03), - test.firstIsPair(REG_PAIR_DE).verifyPair(REG_PAIR_DE, verifier).run(0x13), - test.firstIsPair(REG_PAIR_HL).verifyPair(REG_PAIR_HL, verifier).run(0x23), - test.firstIsPair(REG_SP).verifyPair(REG_SP, verifier).run(0x33) + test.firstIsPair(REG_PAIR_BC).verifyPair(REG_PAIR_BC, verifier).run(0x03), + test.firstIsPair(REG_PAIR_DE).verifyPair(REG_PAIR_DE, verifier).run(0x13), + test.firstIsPair(REG_PAIR_HL).verifyPair(REG_PAIR_HL, verifier).run(0x23), + test.firstIsPair(REG_SP).verifyPair(REG_SP, verifier).run(0x33) ); } @Test public void testDEC_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .clearOtherVerifiersAfterRun(); + .clearOtherVerifiersAfterRun(); Function, Integer> verifier = context -> context.first - 1; Generator.forSome16bitUnary( - test.firstIsPair(REG_PAIR_BC).verifyPair(REG_PAIR_BC, verifier).run(0x0B), - test.firstIsPair(REG_PAIR_DE).verifyPair(REG_PAIR_DE, verifier).run(0x1B), - test.firstIsPair(REG_PAIR_HL).verifyPair(REG_PAIR_HL, verifier).run(0x2B), - test.firstIsPair(REG_SP).verifyPair(REG_SP, verifier).run(0x3B) + test.firstIsPair(REG_PAIR_BC).verifyPair(REG_PAIR_BC, verifier).run(0x0B), + test.firstIsPair(REG_PAIR_DE).verifyPair(REG_PAIR_DE, verifier).run(0x1B), + test.firstIsPair(REG_PAIR_HL).verifyPair(REG_PAIR_HL, verifier).run(0x2B), + test.firstIsPair(REG_SP).verifyPair(REG_SP, verifier).run(0x3B) ); } @Test public void testADD_HL_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .firstIsPair(REG_PAIR_HL) - .verifyPair(REG_PAIR_HL, context -> context.first + context.second) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .signIsPreserved() - .zeroIsPreserved() - .parityIsPreserved() - .carry15() - .halfCarry11() - .subtractionIsReset() - ) - .keepCurrentInjectorsAfterRun(); + .setFlags(0xFF) + .firstIsPair(REG_PAIR_HL) + .verifyPair(REG_PAIR_HL, context -> context.first + context.second) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .signIsPreserved() + .zeroIsPreserved() + .parityIsPreserved() + .carry15() + .halfCarry11() + .subtractionIsReset() + ) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( - test.run(0x29) + test.run(0x29) ); Generator.forSome16bitBinary( - test.secondIsPair(REG_PAIR_BC).run(0x09), - test.secondIsPair(REG_PAIR_DE).run(0x19), - test.secondIsPair(REG_SP).run(0x39) + test.secondIsPair(REG_PAIR_BC).run(0x09), + test.secondIsPair(REG_PAIR_DE).run(0x19), + test.secondIsPair(REG_SP).run(0x39) ); } @@ -265,628 +265,628 @@ public void testADD_HL_RP() { @Test public void testADD_A_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8LSBisRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8LSBisRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x86), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x86) + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x86), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x86) ); } @Test public void testADC_A_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8LSBisRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8LSBisRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x8E), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x8E) + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x8E), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x8E) ); } @Test public void testSUB_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8LSBisRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet()) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8LSBisRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet()) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x96), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x96) + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x96), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x96) ); } @Test public void testSBC_A_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8LSBisRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().borrow().halfBorrow().overflowSubCarry().subtractionIsSet()) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8LSBisRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().borrow().halfBorrow().overflowSubCarry().subtractionIsSet()) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x9E), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x9E) + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x9E), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x9E) ); } @Test public void testINC_II() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .clearOtherVerifiersAfterRun(); + .clearOtherVerifiersAfterRun(); Generator.forSome16bitUnary( - test.firstIsIX().verifyIX(context -> context.first + 1).run(0xDD, 0x23), - test.firstIsIY().verifyIY(context -> context.first + 1).run(0xFD, 0x23) + test.firstIsIX().verifyIX(context -> context.first + 1).run(0xDD, 0x23), + test.firstIsIY().verifyIY(context -> context.first + 1).run(0xFD, 0x23) ); } @Test public void testDEC_II() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .clearOtherVerifiersAfterRun(); + .clearOtherVerifiersAfterRun(); Generator.forSome16bitUnary( - test.firstIsIX().verifyIX(context -> context.first - 1).run(0xDD, 0x2B), - test.firstIsIY().verifyIY(context -> context.first - 1).run(0xFD, 0x2B) + test.firstIsIX().verifyIX(context -> context.first - 1).run(0xDD, 0x2B), + test.firstIsIY().verifyIY(context -> context.first - 1).run(0xFD, 0x2B) ); } @Test public void testINC_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .verifyByte(context -> get8MSBplus8LSB(context.first), context -> (context.second + 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond() - .setSecond(c -> 1) - .sign().zero().halfCarry().overflow().subtractionIsReset().carryIsPreserved() - ) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .verifyByte(context -> get8MSBplus8LSB(context.first), context -> (context.second + 1)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .switchFirstAndSecond() + .setSecond(c -> 1) + .sign().zero().halfCarry().overflow().subtractionIsReset().carryIsPreserved() + ) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x34), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x34) + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x34), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x34) ); } @Test public void testDEC_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .verifyByte(context -> get8MSBplus8LSB(context.first), context -> (context.second - 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond() - .setSecond(c -> 1) - .sign().zero().halfBorrow().overflowSub() - .subtractionIsSet() - .carryIsPreserved() - ) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .verifyByte(context -> get8MSBplus8LSB(context.first), context -> (context.second - 1)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .switchFirstAndSecond() + .setSecond(c -> 1) + .sign().zero().halfBorrow().overflowSub() + .subtractionIsSet() + .carryIsPreserved() + ) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x35), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x35) + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0x35), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0x35) ); } @Test public void testADD_IX_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .firstIsIX() - .verifyIX(context -> context.first + context.second) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .signIsPreserved().zeroIsPreserved().parityIsPreserved() - .halfCarry11().carry15().subtractionIsReset()) - .keepCurrentInjectorsAfterRun(); + .setFlags(0xFF) + .firstIsIX() + .verifyIX(context -> context.first + context.second) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .signIsPreserved().zeroIsPreserved().parityIsPreserved() + .halfCarry11().carry15().subtractionIsReset()) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( - test.run(0xDD, 0x29) + test.run(0xDD, 0x29) ); Generator.forSome16bitBinary( - test.secondIsPair(REG_PAIR_BC).run(0xDD, 0x09), - test.secondIsPair(REG_PAIR_DE).run(0xDD, 0x19), - test.secondIsPair(REG_SP).run(0xDD, 0x39) + test.secondIsPair(REG_PAIR_BC).run(0xDD, 0x09), + test.secondIsPair(REG_PAIR_DE).run(0xDD, 0x19), + test.secondIsPair(REG_SP).run(0xDD, 0x39) ); } @Test public void testADD_IY_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .firstIsIY() - .verifyIY(context -> context.first + context.second) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .signIsPreserved().zeroIsPreserved().parityIsPreserved() - .halfCarry11().carry15().subtractionIsReset()) - .keepCurrentInjectorsAfterRun(); + .setFlags(0xFF) + .firstIsIY() + .verifyIY(context -> context.first + context.second) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .signIsPreserved().zeroIsPreserved().parityIsPreserved() + .halfCarry11().carry15().subtractionIsReset()) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( - test.run(0xFD, 0x29) + test.run(0xFD, 0x29) ); Generator.forSome16bitBinary( - test.secondIsPair(REG_PAIR_BC).run(0xFD, 0x09), - test.secondIsPair(REG_PAIR_DE).run(0xFD, 0x19), - test.secondIsPair(REG_SP).run(0xFD, 0x39) + test.secondIsPair(REG_PAIR_BC).run(0xFD, 0x09), + test.secondIsPair(REG_PAIR_DE).run(0xFD, 0x19), + test.secondIsPair(REG_SP).run(0xFD, 0x39) ); } @Test public void testADC_HL_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .firstIsPair(REG_PAIR_HL) - .verifyPair(REG_PAIR_HL, context -> context.first + context.second + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .overflow16bit().sign16bit().zero16bit() - .carry15().halfCarry11().subtractionIsReset()) - .keepCurrentInjectorsAfterRun(); + .setFlags(0xFF) + .firstIsPair(REG_PAIR_HL) + .verifyPair(REG_PAIR_HL, context -> context.first + context.second + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .overflow16bit().sign16bit().zero16bit() + .carry15().halfCarry11().subtractionIsReset()) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( - test.run(0xED, 0x6A) + test.run(0xED, 0x6A) ); Generator.forSome16bitBinary( - test.secondIsPair(REG_PAIR_BC).run(0xED, 0x4A), - test.secondIsPair(REG_PAIR_DE).run(0xED, 0x5A), - test.secondIsPair(REG_SP).run(0xED, 0x7A) + test.secondIsPair(REG_PAIR_BC).run(0xED, 0x4A), + test.secondIsPair(REG_PAIR_DE).run(0xED, 0x5A), + test.secondIsPair(REG_SP).run(0xED, 0x7A) ); } @Test public void testSBC_HL_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .firstIsPair(REG_PAIR_HL) - .verifyPair(REG_PAIR_HL, context -> - (context.first - context.second - (context.flags & FLAG_C))) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign16bit().zero16bit().borrow16bit().carry15().halfCarry11().subtractionIsSet()) - .keepCurrentInjectorsAfterRun(); + .setFlags(0xFF) + .firstIsPair(REG_PAIR_HL) + .verifyPair(REG_PAIR_HL, context -> + (context.first - context.second - (context.flags & FLAG_C))) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign16bit().zero16bit().borrow16bit().carry15().halfCarry11().subtractionIsSet()) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( - test.run(0xED, 0x62) + test.run(0xED, 0x62) ); Generator.forSome16bitBinary( - test.secondIsPair(REG_PAIR_BC).run(0xED, 0x42), - test.secondIsPair(REG_PAIR_DE).run(0xED, 0x52), - test.secondIsPair(REG_SP).run(0xED, 0x72) + test.secondIsPair(REG_PAIR_BC).run(0xED, 0x42), + test.secondIsPair(REG_PAIR_DE).run(0xED, 0x52), + test.secondIsPair(REG_SP).run(0xED, 0x72) ); } @Test public void testINC_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8MSB() - .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), - context -> ((context.first >>> 8) + 1) & 0xFF) - .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); + .firstIsIX() + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8MSB() + .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), + context -> ((context.first >>> 8) + 1) & 0xFF) + .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); Generator.forSome16bitUnary( - test.run(0xDD, 0x24) + test.run(0xDD, 0x24) ); } @Test public void testINC_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIY() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8MSB() - .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), - context -> ((context.first >>> 8) + 1) & 0xFF) - .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); + .firstIsIY() + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8MSB() + .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), + context -> ((context.first >>> 8) + 1) & 0xFF) + .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); Generator.forSome16bitUnary( - test.run(0xFD, 0x24) + test.run(0xFD, 0x24) ); } @Test public void testDEC_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8MSB() - .setSecond(c -> 1) - .overflowSub().halfBorrow() - .subtractionIsSet() - .carryIsPreserved(), - context -> ((context.first >>> 8) - 1) & 0xFF) - .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); + .firstIsIX() + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8MSB() + .setSecond(c -> 1) + .overflowSub().halfBorrow() + .subtractionIsSet() + .carryIsPreserved(), + context -> ((context.first >>> 8) - 1) & 0xFF) + .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); Generator.forSome16bitUnary( - test.run(0xDD, 0x25) + test.run(0xDD, 0x25) ); } @Test public void testDEC_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIY() - .verifyFlags(new FlagsCheckImpl() - .setFirst8MSB() - .sign().zero() - .setSecond(c -> 1) - .overflowSub().halfBorrow() - .subtractionIsSet() - .carryIsPreserved(), - context -> ((context.first >>> 8) - 1) & 0xFF) - .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); + .firstIsIY() + .verifyFlags(new FlagsCheckImpl() + .setFirst8MSB() + .sign().zero() + .setSecond(c -> 1) + .overflowSub().halfBorrow() + .subtractionIsSet() + .carryIsPreserved(), + context -> ((context.first >>> 8) - 1) & 0xFF) + .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); Generator.forSome16bitUnary( - test.run(0xFD, 0x25) + test.run(0xFD, 0x25) ); } @Test public void testINC_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8LSB() - .setSecond(c -> 1) - .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), - context -> ((context.first & 0xFF) + 1) & 0xFF) - .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) + 1) & 0xFF)); + .firstIsIX() + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8LSB() + .setSecond(c -> 1) + .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), + context -> ((context.first & 0xFF) + 1) & 0xFF) + .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) + 1) & 0xFF)); Generator.forSome16bitUnary( - test.run(0xDD, 0x2C) + test.run(0xDD, 0x2C) ); } @Test public void testINC_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIY() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8LSB() - .setSecond(c -> 1) - .overflow().halfCarry().subtractionIsReset(), - context -> ((context.first & 0xFF) + 1) & 0xFF) - .verifyIY(context -> (context.first & 0xFF00) | (((context.first & 0xFF) + 1) & 0xFF)); + .firstIsIY() + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8LSB() + .setSecond(c -> 1) + .overflow().halfCarry().subtractionIsReset(), + context -> ((context.first & 0xFF) + 1) & 0xFF) + .verifyIY(context -> (context.first & 0xFF00) | (((context.first & 0xFF) + 1) & 0xFF)); Generator.forSome16bitUnary( - test.run(0xFD, 0x2C) + test.run(0xFD, 0x2C) ); } @Test public void testDEC_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8LSB() - .setSecond(c -> 1) - .overflowSub().halfBorrow() - .subtractionIsSet() - .carryIsPreserved(), - context -> ((context.first & 0xFF) - 1) & 0xFF) - .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); + .firstIsIX() + .verifyFlags(new FlagsCheckImpl().sign().zero() + .setFirst8LSB() + .setSecond(c -> 1) + .overflowSub().halfBorrow() + .subtractionIsSet() + .carryIsPreserved(), + context -> ((context.first & 0xFF) - 1) & 0xFF) + .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); Generator.forSome16bitUnary( - test.run(0xDD, 0x2D) + test.run(0xDD, 0x2D) ); } @Test public void testDEC_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIY() - .verifyFlags(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond(c -> 1) - .sign().zero() - .overflowSub().halfBorrow() - .subtractionIsSet() - .carryIsPreserved(), - context -> ((context.first & 0xFF) - 1) & 0xFF) - .verifyIY(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); + .firstIsIY() + .verifyFlags(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond(c -> 1) + .sign().zero() + .overflowSub().halfBorrow() + .subtractionIsSet() + .carryIsPreserved(), + context -> ((context.first & 0xFF) - 1) & 0xFF) + .verifyIY(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); Generator.forSome16bitUnary( - test.run(0xFD, 0x2D) + test.run(0xFD, 0x2D) ); } @Test public void testADD_A_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond8MSB() - .sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond8MSB() + .sign().zero().carry().halfCarry().overflow().subtractionIsReset()); Generator.forSome16bitBinary( - test.run(0xDD, 0x84) + test.run(0xDD, 0x84) ); } @Test public void testADD_A_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond8MSB() - .sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond8MSB() + .sign().zero().carry().halfCarry().overflow().subtractionIsReset()); Generator.forSome16bitBinary( - test.run(0xFD, 0x84) + test.run(0xFD, 0x84) ); } @Test public void testADD_A_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); Generator.forSome16bitBinary( - test.run(0xDD, 0x85) + test.run(0xDD, 0x85) ); } @Test public void testADD_A_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); Generator.forSome16bitBinary( - test.run(0xFD, 0x85) + test.run(0xFD, 0x85) ); } @Test public void testADC_A_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() - .setFirst8LSB() - .setSecond8MSB() - .halfCarry() - .overflow().subtractionIsReset()); + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() + .setFirst8LSB() + .setSecond8MSB() + .halfCarry() + .overflow().subtractionIsReset()); Generator.forSome16bitBinary( - test.run(0xDD, 0x8C) + test.run(0xDD, 0x8C) ); } @Test public void testADC_A_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() - .setFirst8LSB() - .setSecond8MSB() - .halfCarry() - .overflow().subtractionIsReset()); + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() + .setFirst8LSB() + .setSecond8MSB() + .halfCarry() + .overflow().subtractionIsReset()); Generator.forSome16bitBinary( - test.run(0xFD, 0x8C) + test.run(0xFD, 0x8C) ); } @Test public void testADC_A_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() - .setFirst8LSB() - .setSecond8LSB() - .halfCarry() - .overflow().subtractionIsReset()); + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() + .setFirst8LSB() + .setSecond8LSB() + .halfCarry() + .overflow().subtractionIsReset()); Generator.forSome16bitBinary( - test.run(0xDD, 0x8D) + test.run(0xDD, 0x8D) ); } @Test public void testADC_A_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() - .setFirst8LSB() - .setSecond8LSB() - .halfCarry() - .overflow().subtractionIsReset()); + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() + .setFirst8LSB() + .setSecond8LSB() + .halfCarry() + .overflow().subtractionIsReset()); Generator.forSome16bitBinary( - test.run(0xFD, 0x8D) + test.run(0xFD, 0x8D) ); } @Test public void testSUB_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero() - .setSecond8MSB() - .borrow() - .halfBorrow() - .overflowSub().subtractionIsSet()); + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero() + .setSecond8MSB() + .borrow() + .halfBorrow() + .overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( - test.run(0xDD, 0x94) + test.run(0xDD, 0x94) ); } @Test public void testSUB_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero() - .setSecond8MSB() - .borrow() - .halfBorrow() - .overflowSub().subtractionIsSet()); + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero() + .setSecond8MSB() + .borrow() + .halfBorrow() + .overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( - test.run(0xFD, 0x94) + test.run(0xFD, 0x94) ); } @Test public void testSUB_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero() - .borrow() - .halfBorrow() - .overflowSub().subtractionIsSet()); + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero() + .borrow() + .halfBorrow() + .overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( - test.run(0xDD, 0x95) + test.run(0xDD, 0x95) ); } @Test public void testSUB_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero() - .borrow() - .halfBorrow() - .overflowSub().subtractionIsSet()); + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero() + .borrow() + .halfBorrow() + .overflowSub().subtractionIsSet()); Generator.forSome16bitBinary( - test.run(0xFD, 0x95) + test.run(0xFD, 0x95) ); } @Test public void testSBC_A_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond8MSB() - .sign().zero() - .borrowWithCarry() - .halfBorrow() - .overflowSubCarry().subtractionIsSet()); + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond8MSB() + .sign().zero() + .borrowWithCarry() + .halfBorrow() + .overflowSubCarry().subtractionIsSet()); Generator.forSome16bitBinary( - test.run(0xDD, 0x9C) + test.run(0xDD, 0x9C) ); } @Test public void testSBC_A_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .setSecond8MSB() - .sign().zero() - .borrowWithCarry() - .halfBorrow() - .overflowSubCarry().subtractionIsSet()); + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .setSecond8MSB() + .sign().zero() + .borrowWithCarry() + .halfBorrow() + .overflowSubCarry().subtractionIsSet()); Generator.forSome16bitBinary( - test.run(0xFD, 0x9C) + test.run(0xFD, 0x9C) ); } @Test public void testSBC_A_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond8LSB() - .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond8LSB() + .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); Generator.forSome16bitBinary( - test.run(0xDD, 0x9D) + test.run(0xDD, 0x9D) ); } @Test public void testSBC_A_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); Generator.forSome16bitBinary( - test.run(0xFD, 0x9D) + test.run(0xFD, 0x9D) ); } private ByteTestBuilder additionTestBuilder() { return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) + .keepCurrentInjectorsAfterRun(); } private ByteTestBuilder subtractionTestBuilder() { return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().borrow() - .halfBorrow() - .overflowSub().subtractionIsSet()) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().borrow() + .halfBorrow() + .overflowSub().subtractionIsSet()) + .keepCurrentInjectorsAfterRun(); } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/BitTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/BitTest.java index 44e05130b..cf80f2c6e 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/BitTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/BitTest.java @@ -34,10 +34,10 @@ public class BitTest extends InstructionsTest { private ByteTestBuilder prepareBITtest(int register) { return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(register) - .setFlags(FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsRegister(register) + .setFlags(FLAG_N) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); } private ByteTestBuilder verifyFlags(ByteTestBuilder test, FlagsCheckImpl flagsBuilder, int bitShift) { @@ -53,18 +53,18 @@ public void testBIT_b__A() { ByteTestBuilder test = prepareBITtest(REG_A); FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); + .parity(); FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); + .zero().parity(); Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x47), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4F), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x57), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5F), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x67), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6F), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x77), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7F) + verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x47), + verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4F), + verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x57), + verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5F), + verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x67), + verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6F), + verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x77), + verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7F) ); } @@ -73,18 +73,18 @@ public void testBIT_b__B() { ByteTestBuilder test = prepareBITtest(REG_B); FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); + .parity(); FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); + .zero().parity(); Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x40), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x48), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x50), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x58), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x60), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x68), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x70), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x78) + verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x40), + verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x48), + verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x50), + verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x58), + verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x60), + verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x68), + verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x70), + verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x78) ); } @@ -93,18 +93,18 @@ public void testBIT_b__C() { ByteTestBuilder test = prepareBITtest(REG_C); FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); + .parity(); FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); + .zero().parity(); Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x41), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x49), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x51), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x59), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x61), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x69), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x71), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x79) + verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x41), + verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x49), + verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x51), + verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x59), + verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x61), + verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x69), + verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x71), + verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x79) ); } @@ -113,18 +113,18 @@ public void testBIT_b__D() { ByteTestBuilder test = prepareBITtest(REG_D); FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); + .parity(); FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); + .zero().parity(); Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x42), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4A), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x52), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5A), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x62), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6A), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x72), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7A) + verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x42), + verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4A), + verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x52), + verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5A), + verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x62), + verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6A), + verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x72), + verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7A) ); } @@ -133,18 +133,18 @@ public void testBIT_b__E() { ByteTestBuilder test = prepareBITtest(REG_E); FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); + .parity(); FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); + .zero().parity(); Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x43), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4B), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x53), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5B), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x63), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6B), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x73), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7B) + verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x43), + verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4B), + verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x53), + verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5B), + verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x63), + verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6B), + verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x73), + verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7B) ); } @@ -153,18 +153,18 @@ public void testBIT_b__H() { ByteTestBuilder test = prepareBITtest(REG_H); FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); + .parity(); FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); + .zero().parity(); Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x44), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4C), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x54), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5C), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x64), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6C), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x74), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7C) + verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x44), + verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4C), + verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x54), + verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5C), + verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x64), + verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6C), + verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x74), + verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7C) ); } @@ -173,116 +173,116 @@ public void testBIT_b__L() { ByteTestBuilder test = prepareBITtest(REG_L); FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); + .parity(); FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); + .zero().parity(); Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x45), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4D), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x55), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5D), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x65), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6D), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x75), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7D) + verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x45), + verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4D), + verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x55), + verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5D), + verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x65), + verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6D), + verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x75), + verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7D) ); } @Test public void testBIT_b__mHL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .setFlags(FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .setFlags(FLAG_N) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); + .parity(); FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); + .zero().parity(); Generator.forSome16bitBinary(2, - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x46), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4E), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x56), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5E), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x66), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6E), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x76), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7E) + verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x46), + verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4E), + verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x56), + verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5E), + verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x66), + verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6E), + verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x76), + verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7E) ); } @Test public void testBIT_b__IX_plus_d() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8MSBisIX() - .setFlags(FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8MSBisIX() + .setFlags(FLAG_N) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); + .parity(); FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); + .zero().parity(); Generator.forSome16bitBinary(0x100, - verifyFlags(test, flagsBuilder, 0).runWithFirst8bitOperandWithOpcodeAfter(0x46, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 1).runWithFirst8bitOperandWithOpcodeAfter(0x4E, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 2).runWithFirst8bitOperandWithOpcodeAfter(0x56, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 3).runWithFirst8bitOperandWithOpcodeAfter(0x5E, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 4).runWithFirst8bitOperandWithOpcodeAfter(0x66, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 5).runWithFirst8bitOperandWithOpcodeAfter(0x6E, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 6).runWithFirst8bitOperandWithOpcodeAfter(0x76, 0xDD, 0xCB), - verifyFlags(test, signFlagBuilder, 7).runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xDD, 0xCB) + verifyFlags(test, flagsBuilder, 0).runWithFirst8bitOperandWithOpcodeAfter(0x46, 0xDD, 0xCB), + verifyFlags(test, flagsBuilder, 1).runWithFirst8bitOperandWithOpcodeAfter(0x4E, 0xDD, 0xCB), + verifyFlags(test, flagsBuilder, 2).runWithFirst8bitOperandWithOpcodeAfter(0x56, 0xDD, 0xCB), + verifyFlags(test, flagsBuilder, 3).runWithFirst8bitOperandWithOpcodeAfter(0x5E, 0xDD, 0xCB), + verifyFlags(test, flagsBuilder, 4).runWithFirst8bitOperandWithOpcodeAfter(0x66, 0xDD, 0xCB), + verifyFlags(test, flagsBuilder, 5).runWithFirst8bitOperandWithOpcodeAfter(0x6E, 0xDD, 0xCB), + verifyFlags(test, flagsBuilder, 6).runWithFirst8bitOperandWithOpcodeAfter(0x76, 0xDD, 0xCB), + verifyFlags(test, signFlagBuilder, 7).runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xDD, 0xCB) ); } @Test public void testBIT_b__IX_plus_d_undocumented() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8MSBisIX() - .setFlags(FLAG_N) - .verifyFlags(new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero().parity().sign(), - context -> (context.second & (1 << 7))) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8MSBisIX() + .setFlags(FLAG_N) + .verifyFlags(new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero().parity().sign(), + context -> (context.second & (1 << 7))) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome16bitBinary(0x100, - test.runWithFirst8bitOperandWithOpcodeAfter(0x78, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x79, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7A, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7B, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7C, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7D, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7F, 0xDD, 0xCB) + test.runWithFirst8bitOperandWithOpcodeAfter(0x78, 0xDD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x79, 0xDD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7A, 0xDD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7B, 0xDD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7C, 0xDD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7D, 0xDD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xDD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7F, 0xDD, 0xCB) ); } @Test public void testBIT_b__IY_plus_d() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8MSBisIY() - .setFlags(FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8MSBisIY() + .setFlags(FLAG_N) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); + .parity(); FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); + .zero().parity(); Generator.forSome16bitBinary(0x100, - verifyFlags(test, flagsBuilder, 0).runWithFirst8bitOperandWithOpcodeAfter(0x46, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 1).runWithFirst8bitOperandWithOpcodeAfter(0x4E, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 2).runWithFirst8bitOperandWithOpcodeAfter(0x56, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 3).runWithFirst8bitOperandWithOpcodeAfter(0x5E, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 4).runWithFirst8bitOperandWithOpcodeAfter(0x66, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 5).runWithFirst8bitOperandWithOpcodeAfter(0x6E, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 6).runWithFirst8bitOperandWithOpcodeAfter(0x76, 0xFD, 0xCB), - verifyFlags(test, signFlagBuilder, 7).runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xFD, 0xCB) + verifyFlags(test, flagsBuilder, 0).runWithFirst8bitOperandWithOpcodeAfter(0x46, 0xFD, 0xCB), + verifyFlags(test, flagsBuilder, 1).runWithFirst8bitOperandWithOpcodeAfter(0x4E, 0xFD, 0xCB), + verifyFlags(test, flagsBuilder, 2).runWithFirst8bitOperandWithOpcodeAfter(0x56, 0xFD, 0xCB), + verifyFlags(test, flagsBuilder, 3).runWithFirst8bitOperandWithOpcodeAfter(0x5E, 0xFD, 0xCB), + verifyFlags(test, flagsBuilder, 4).runWithFirst8bitOperandWithOpcodeAfter(0x66, 0xFD, 0xCB), + verifyFlags(test, flagsBuilder, 5).runWithFirst8bitOperandWithOpcodeAfter(0x6E, 0xFD, 0xCB), + verifyFlags(test, flagsBuilder, 6).runWithFirst8bitOperandWithOpcodeAfter(0x76, 0xFD, 0xCB), + verifyFlags(test, signFlagBuilder, 7).runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xFD, 0xCB) ); } @@ -290,156 +290,156 @@ public void testBIT_b__IY_plus_d() { @Test public void testBIT_b__IY_plus_d_undocumented() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8MSBisIY() - .setFlags(FLAG_N) - .verifyFlags(new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero().parity().sign(), - context -> (context.second & (1 << 7))) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8MSBisIY() + .setFlags(FLAG_N) + .verifyFlags(new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero().parity().sign(), + context -> (context.second & (1 << 7))) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome16bitBinary(0x100, - test.runWithFirst8bitOperandWithOpcodeAfter(0x78, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x79, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7A, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7B, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7C, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7D, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7F, 0xFD, 0xCB) + test.runWithFirst8bitOperandWithOpcodeAfter(0x78, 0xFD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x79, 0xFD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7A, 0xFD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7B, 0xFD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7C, 0xFD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7D, 0xFD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xFD, 0xCB), + test.runWithFirst8bitOperandWithOpcodeAfter(0x7F, 0xFD, 0xCB) ); } @Test public void testSET_b__A() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_A, 0) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_A, 0) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_A, context -> 1).run(0xCB, 0xC7), - test.verifyRegister(REG_A, context -> 2).run(0xCB, 0xCF), - test.verifyRegister(REG_A, context -> 4).run(0xCB, 0xD7), - test.verifyRegister(REG_A, context -> 8).run(0xCB, 0xDF), - test.verifyRegister(REG_A, context -> 16).run(0xCB, 0xE7), - test.verifyRegister(REG_A, context -> 32).run(0xCB, 0xEF), - test.verifyRegister(REG_A, context -> 64).run(0xCB, 0xF7), - test.verifyRegister(REG_A, context -> 128).run(0xCB, 0xFF) + test.verifyRegister(REG_A, context -> 1).run(0xCB, 0xC7), + test.verifyRegister(REG_A, context -> 2).run(0xCB, 0xCF), + test.verifyRegister(REG_A, context -> 4).run(0xCB, 0xD7), + test.verifyRegister(REG_A, context -> 8).run(0xCB, 0xDF), + test.verifyRegister(REG_A, context -> 16).run(0xCB, 0xE7), + test.verifyRegister(REG_A, context -> 32).run(0xCB, 0xEF), + test.verifyRegister(REG_A, context -> 64).run(0xCB, 0xF7), + test.verifyRegister(REG_A, context -> 128).run(0xCB, 0xFF) ); } @Test public void testSET_b__B() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_B, 0) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_B, 0) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_B, context -> 1).run(0xCB, 0xC0), - test.verifyRegister(REG_B, context -> 2).run(0xCB, 0xC8), - test.verifyRegister(REG_B, context -> 4).run(0xCB, 0xD0), - test.verifyRegister(REG_B, context -> 8).run(0xCB, 0xD8), - test.verifyRegister(REG_B, context -> 16).run(0xCB, 0xE0), - test.verifyRegister(REG_B, context -> 32).run(0xCB, 0xE8), - test.verifyRegister(REG_B, context -> 64).run(0xCB, 0xF0), - test.verifyRegister(REG_B, context -> 128).run(0xCB, 0xF8) + test.verifyRegister(REG_B, context -> 1).run(0xCB, 0xC0), + test.verifyRegister(REG_B, context -> 2).run(0xCB, 0xC8), + test.verifyRegister(REG_B, context -> 4).run(0xCB, 0xD0), + test.verifyRegister(REG_B, context -> 8).run(0xCB, 0xD8), + test.verifyRegister(REG_B, context -> 16).run(0xCB, 0xE0), + test.verifyRegister(REG_B, context -> 32).run(0xCB, 0xE8), + test.verifyRegister(REG_B, context -> 64).run(0xCB, 0xF0), + test.verifyRegister(REG_B, context -> 128).run(0xCB, 0xF8) ); } @Test public void testSET_b__C() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_C, 0) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_C, 0) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_C, context -> 1).run(0xCB, 0xC1), - test.verifyRegister(REG_C, context -> 2).run(0xCB, 0xC9), - test.verifyRegister(REG_C, context -> 4).run(0xCB, 0xD1), - test.verifyRegister(REG_C, context -> 8).run(0xCB, 0xD9), - test.verifyRegister(REG_C, context -> 16).run(0xCB, 0xE1), - test.verifyRegister(REG_C, context -> 32).run(0xCB, 0xE9), - test.verifyRegister(REG_C, context -> 64).run(0xCB, 0xF1), - test.verifyRegister(REG_C, context -> 128).run(0xCB, 0xF9) + test.verifyRegister(REG_C, context -> 1).run(0xCB, 0xC1), + test.verifyRegister(REG_C, context -> 2).run(0xCB, 0xC9), + test.verifyRegister(REG_C, context -> 4).run(0xCB, 0xD1), + test.verifyRegister(REG_C, context -> 8).run(0xCB, 0xD9), + test.verifyRegister(REG_C, context -> 16).run(0xCB, 0xE1), + test.verifyRegister(REG_C, context -> 32).run(0xCB, 0xE9), + test.verifyRegister(REG_C, context -> 64).run(0xCB, 0xF1), + test.verifyRegister(REG_C, context -> 128).run(0xCB, 0xF9) ); } @Test public void testSET_b__D() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_D, 0) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_D, 0) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_D, context -> 1).run(0xCB, 0xC2), - test.verifyRegister(REG_D, context -> 2).run(0xCB, 0xCA), - test.verifyRegister(REG_D, context -> 4).run(0xCB, 0xD2), - test.verifyRegister(REG_D, context -> 8).run(0xCB, 0xDA), - test.verifyRegister(REG_D, context -> 16).run(0xCB, 0xE2), - test.verifyRegister(REG_D, context -> 32).run(0xCB, 0xEA), - test.verifyRegister(REG_D, context -> 64).run(0xCB, 0xF2), - test.verifyRegister(REG_D, context -> 128).run(0xCB, 0xFA) + test.verifyRegister(REG_D, context -> 1).run(0xCB, 0xC2), + test.verifyRegister(REG_D, context -> 2).run(0xCB, 0xCA), + test.verifyRegister(REG_D, context -> 4).run(0xCB, 0xD2), + test.verifyRegister(REG_D, context -> 8).run(0xCB, 0xDA), + test.verifyRegister(REG_D, context -> 16).run(0xCB, 0xE2), + test.verifyRegister(REG_D, context -> 32).run(0xCB, 0xEA), + test.verifyRegister(REG_D, context -> 64).run(0xCB, 0xF2), + test.verifyRegister(REG_D, context -> 128).run(0xCB, 0xFA) ); } @Test public void testSET_b__E() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_E, 0) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_E, 0) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_E, context -> 1).run(0xCB, 0xC3), - test.verifyRegister(REG_E, context -> 2).run(0xCB, 0xCB), - test.verifyRegister(REG_E, context -> 4).run(0xCB, 0xD3), - test.verifyRegister(REG_E, context -> 8).run(0xCB, 0xDB), - test.verifyRegister(REG_E, context -> 16).run(0xCB, 0xE3), - test.verifyRegister(REG_E, context -> 32).run(0xCB, 0xEB), - test.verifyRegister(REG_E, context -> 64).run(0xCB, 0xF3), - test.verifyRegister(REG_E, context -> 128).run(0xCB, 0xFB) + test.verifyRegister(REG_E, context -> 1).run(0xCB, 0xC3), + test.verifyRegister(REG_E, context -> 2).run(0xCB, 0xCB), + test.verifyRegister(REG_E, context -> 4).run(0xCB, 0xD3), + test.verifyRegister(REG_E, context -> 8).run(0xCB, 0xDB), + test.verifyRegister(REG_E, context -> 16).run(0xCB, 0xE3), + test.verifyRegister(REG_E, context -> 32).run(0xCB, 0xEB), + test.verifyRegister(REG_E, context -> 64).run(0xCB, 0xF3), + test.verifyRegister(REG_E, context -> 128).run(0xCB, 0xFB) ); } @Test public void testSET_b__H() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_H, 0) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_H, 0) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_H, context -> 1).run(0xCB, 0xC4), - test.verifyRegister(REG_H, context -> 2).run(0xCB, 0xCC), - test.verifyRegister(REG_H, context -> 4).run(0xCB, 0xD4), - test.verifyRegister(REG_H, context -> 8).run(0xCB, 0xDC), - test.verifyRegister(REG_H, context -> 16).run(0xCB, 0xE4), - test.verifyRegister(REG_H, context -> 32).run(0xCB, 0xEC), - test.verifyRegister(REG_H, context -> 64).run(0xCB, 0xF4), - test.verifyRegister(REG_H, context -> 128).run(0xCB, 0xFC) + test.verifyRegister(REG_H, context -> 1).run(0xCB, 0xC4), + test.verifyRegister(REG_H, context -> 2).run(0xCB, 0xCC), + test.verifyRegister(REG_H, context -> 4).run(0xCB, 0xD4), + test.verifyRegister(REG_H, context -> 8).run(0xCB, 0xDC), + test.verifyRegister(REG_H, context -> 16).run(0xCB, 0xE4), + test.verifyRegister(REG_H, context -> 32).run(0xCB, 0xEC), + test.verifyRegister(REG_H, context -> 64).run(0xCB, 0xF4), + test.verifyRegister(REG_H, context -> 128).run(0xCB, 0xFC) ); } @Test public void testSET_b__L() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_L, 0) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_L, 0) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_L, context -> 1).run(0xCB, 0xC5), - test.verifyRegister(REG_L, context -> 2).run(0xCB, 0xCD), - test.verifyRegister(REG_L, context -> 4).run(0xCB, 0xD5), - test.verifyRegister(REG_L, context -> 8).run(0xCB, 0xDD), - test.verifyRegister(REG_L, context -> 16).run(0xCB, 0xE5), - test.verifyRegister(REG_L, context -> 32).run(0xCB, 0xED), - test.verifyRegister(REG_L, context -> 64).run(0xCB, 0xF5), - test.verifyRegister(REG_L, context -> 128).run(0xCB, 0xFD) + test.verifyRegister(REG_L, context -> 1).run(0xCB, 0xC5), + test.verifyRegister(REG_L, context -> 2).run(0xCB, 0xCD), + test.verifyRegister(REG_L, context -> 4).run(0xCB, 0xD5), + test.verifyRegister(REG_L, context -> 8).run(0xCB, 0xDD), + test.verifyRegister(REG_L, context -> 16).run(0xCB, 0xE5), + test.verifyRegister(REG_L, context -> 32).run(0xCB, 0xED), + test.verifyRegister(REG_L, context -> 64).run(0xCB, 0xF5), + test.verifyRegister(REG_L, context -> 128).run(0xCB, 0xFD) ); } @@ -447,83 +447,83 @@ public void testSET_b__L() { @Test public void testSET_b__mHL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsMemoryAddressByte(0) - .firstIsPair(REG_PAIR_HL) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsMemoryAddressByte(0) + .firstIsPair(REG_PAIR_HL) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> address = context -> context.first; Generator.forSome16bitUnary(2, - test.verifyByte(address, context -> 1).run(0xCB, 0xC6), - test.verifyByte(address, context -> 2).run(0xCB, 0xCE), - test.verifyByte(address, context -> 4).run(0xCB, 0xD6), - test.verifyByte(address, context -> 8).run(0xCB, 0xDE), - test.verifyByte(address, context -> 16).run(0xCB, 0xE6), - test.verifyByte(address, context -> 32).run(0xCB, 0xEE), - test.verifyByte(address, context -> 64).run(0xCB, 0xF6), - test.verifyByte(address, context -> 128).run(0xCB, 0xFE) + test.verifyByte(address, context -> 1).run(0xCB, 0xC6), + test.verifyByte(address, context -> 2).run(0xCB, 0xCE), + test.verifyByte(address, context -> 4).run(0xCB, 0xD6), + test.verifyByte(address, context -> 8).run(0xCB, 0xDE), + test.verifyByte(address, context -> 16).run(0xCB, 0xE6), + test.verifyByte(address, context -> 32).run(0xCB, 0xEE), + test.verifyByte(address, context -> 64).run(0xCB, 0xF6), + test.verifyByte(address, context -> 128).run(0xCB, 0xFE) ); } @Test public void testSET_b__IX_plus_d() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisIX() - .first8MSBplus8LSBisMemoryByte(0) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .first8MSBisIX() + .first8MSBplus8LSBisMemoryByte(0) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> address = context -> get8MSBplus8LSB(context.first); Generator.forSome16bitUnary(0x100, - test.verifyByte(address, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC6, 0xDD, 0xCB), - test.verifyByte(address, context -> 2).runWithFirst8bitOperandWithOpcodeAfter(0xCE, 0xDD, 0xCB), - test.verifyByte(address, context -> 4).runWithFirst8bitOperandWithOpcodeAfter(0xD6, 0xDD, 0xCB), - test.verifyByte(address, context -> 8).runWithFirst8bitOperandWithOpcodeAfter(0xDE, 0xDD, 0xCB), - test.verifyByte(address, context -> 16).runWithFirst8bitOperandWithOpcodeAfter(0xE6, 0xDD, 0xCB), - test.verifyByte(address, context -> 32).runWithFirst8bitOperandWithOpcodeAfter(0xEE, 0xDD, 0xCB), - test.verifyByte(address, context -> 64).runWithFirst8bitOperandWithOpcodeAfter(0xF6, 0xDD, 0xCB), - test.verifyByte(address, context -> 128).runWithFirst8bitOperandWithOpcodeAfter(0xFE, 0xDD, 0xCB) + test.verifyByte(address, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC6, 0xDD, 0xCB), + test.verifyByte(address, context -> 2).runWithFirst8bitOperandWithOpcodeAfter(0xCE, 0xDD, 0xCB), + test.verifyByte(address, context -> 4).runWithFirst8bitOperandWithOpcodeAfter(0xD6, 0xDD, 0xCB), + test.verifyByte(address, context -> 8).runWithFirst8bitOperandWithOpcodeAfter(0xDE, 0xDD, 0xCB), + test.verifyByte(address, context -> 16).runWithFirst8bitOperandWithOpcodeAfter(0xE6, 0xDD, 0xCB), + test.verifyByte(address, context -> 32).runWithFirst8bitOperandWithOpcodeAfter(0xEE, 0xDD, 0xCB), + test.verifyByte(address, context -> 64).runWithFirst8bitOperandWithOpcodeAfter(0xF6, 0xDD, 0xCB), + test.verifyByte(address, context -> 128).runWithFirst8bitOperandWithOpcodeAfter(0xFE, 0xDD, 0xCB) ); } @Test public void testSET_b__IX_plus_d_undocumented() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisIX() - .first8MSBplus8LSBisMemoryByte(0) - .verifyByte(context -> get8MSBplus8LSB(context.first), context -> 1) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .first8MSBisIX() + .first8MSBplus8LSBisMemoryByte(0) + .verifyByte(context -> get8MSBplus8LSB(context.first), context -> 1) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome16bitUnary(0x100, - test.verifyRegister(REG_B, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC0, 0xDD, 0xCB), - test.verifyRegister(REG_C, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC1, 0xDD, 0xCB), - test.verifyRegister(REG_D, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC2, 0xDD, 0xCB), - test.verifyRegister(REG_E, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC3, 0xDD, 0xCB), - test.verifyRegister(REG_H, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC4, 0xDD, 0xCB), - test.verifyRegister(REG_L, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC5, 0xDD, 0xCB), - test.verifyRegister(REG_A, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC7, 0xDD, 0xCB) + test.verifyRegister(REG_B, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC0, 0xDD, 0xCB), + test.verifyRegister(REG_C, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC1, 0xDD, 0xCB), + test.verifyRegister(REG_D, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC2, 0xDD, 0xCB), + test.verifyRegister(REG_E, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC3, 0xDD, 0xCB), + test.verifyRegister(REG_H, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC4, 0xDD, 0xCB), + test.verifyRegister(REG_L, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC5, 0xDD, 0xCB), + test.verifyRegister(REG_A, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC7, 0xDD, 0xCB) ); } @Test public void testSET_b__IY_plus_d() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisIY() - .first8MSBplus8LSBisMemoryByte(0) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .first8MSBisIY() + .first8MSBplus8LSBisMemoryByte(0) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> address = context -> get8MSBplus8LSB(context.first); Generator.forSome16bitUnary(0x100, - test.verifyByte(address, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC6, 0xFD, 0xCB), - test.verifyByte(address, context -> 2).runWithFirst8bitOperandWithOpcodeAfter(0xCE, 0xFD, 0xCB), - test.verifyByte(address, context -> 4).runWithFirst8bitOperandWithOpcodeAfter(0xD6, 0xFD, 0xCB), - test.verifyByte(address, context -> 8).runWithFirst8bitOperandWithOpcodeAfter(0xDE, 0xFD, 0xCB), - test.verifyByte(address, context -> 16).runWithFirst8bitOperandWithOpcodeAfter(0xE6, 0xFD, 0xCB), - test.verifyByte(address, context -> 32).runWithFirst8bitOperandWithOpcodeAfter(0xEE, 0xFD, 0xCB), - test.verifyByte(address, context -> 64).runWithFirst8bitOperandWithOpcodeAfter(0xF6, 0xFD, 0xCB), - test.verifyByte(address, context -> 128).runWithFirst8bitOperandWithOpcodeAfter(0xFE, 0xFD, 0xCB) + test.verifyByte(address, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC6, 0xFD, 0xCB), + test.verifyByte(address, context -> 2).runWithFirst8bitOperandWithOpcodeAfter(0xCE, 0xFD, 0xCB), + test.verifyByte(address, context -> 4).runWithFirst8bitOperandWithOpcodeAfter(0xD6, 0xFD, 0xCB), + test.verifyByte(address, context -> 8).runWithFirst8bitOperandWithOpcodeAfter(0xDE, 0xFD, 0xCB), + test.verifyByte(address, context -> 16).runWithFirst8bitOperandWithOpcodeAfter(0xE6, 0xFD, 0xCB), + test.verifyByte(address, context -> 32).runWithFirst8bitOperandWithOpcodeAfter(0xEE, 0xFD, 0xCB), + test.verifyByte(address, context -> 64).runWithFirst8bitOperandWithOpcodeAfter(0xF6, 0xFD, 0xCB), + test.verifyByte(address, context -> 128).runWithFirst8bitOperandWithOpcodeAfter(0xFE, 0xFD, 0xCB) ); } @@ -531,216 +531,216 @@ public void testSET_b__IY_plus_d() { @Test public void testSET_b__IY_plus_d_undocumented() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisIY() - .first8MSBplus8LSBisMemoryByte(0) - .verifyByte(context -> get8MSBplus8LSB(context.first), context -> 1) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .first8MSBisIY() + .first8MSBplus8LSBisMemoryByte(0) + .verifyByte(context -> get8MSBplus8LSB(context.first), context -> 1) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome16bitUnary(0x100, - test.verifyRegister(REG_B, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC0, 0xFD, 0xCB), - test.verifyRegister(REG_C, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC1, 0xFD, 0xCB), - test.verifyRegister(REG_D, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC2, 0xFD, 0xCB), - test.verifyRegister(REG_E, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC3, 0xFD, 0xCB), - test.verifyRegister(REG_H, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC4, 0xFD, 0xCB), - test.verifyRegister(REG_L, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC5, 0xFD, 0xCB), - test.verifyRegister(REG_A, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC7, 0xFD, 0xCB) + test.verifyRegister(REG_B, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC0, 0xFD, 0xCB), + test.verifyRegister(REG_C, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC1, 0xFD, 0xCB), + test.verifyRegister(REG_D, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC2, 0xFD, 0xCB), + test.verifyRegister(REG_E, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC3, 0xFD, 0xCB), + test.verifyRegister(REG_H, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC4, 0xFD, 0xCB), + test.verifyRegister(REG_L, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC5, 0xFD, 0xCB), + test.verifyRegister(REG_A, context -> 1).runWithFirst8bitOperandWithOpcodeAfter(0xC7, 0xFD, 0xCB) ); } @Test public void testRES_b__A() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_A, 0xFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_A, 0xFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_A, context -> 0xFE).run(0xCB, 0x87), - test.verifyRegister(REG_A, context -> 0xFD).run(0xCB, 0x8F), - test.verifyRegister(REG_A, context -> 0xFB).run(0xCB, 0x97), - test.verifyRegister(REG_A, context -> 0xF7).run(0xCB, 0x9F), - test.verifyRegister(REG_A, context -> 0xEF).run(0xCB, 0xA7), - test.verifyRegister(REG_A, context -> 0xDF).run(0xCB, 0xAF), - test.verifyRegister(REG_A, context -> 0xBF).run(0xCB, 0xB7), - test.verifyRegister(REG_A, context -> 0x7F).run(0xCB, 0xBF) + test.verifyRegister(REG_A, context -> 0xFE).run(0xCB, 0x87), + test.verifyRegister(REG_A, context -> 0xFD).run(0xCB, 0x8F), + test.verifyRegister(REG_A, context -> 0xFB).run(0xCB, 0x97), + test.verifyRegister(REG_A, context -> 0xF7).run(0xCB, 0x9F), + test.verifyRegister(REG_A, context -> 0xEF).run(0xCB, 0xA7), + test.verifyRegister(REG_A, context -> 0xDF).run(0xCB, 0xAF), + test.verifyRegister(REG_A, context -> 0xBF).run(0xCB, 0xB7), + test.verifyRegister(REG_A, context -> 0x7F).run(0xCB, 0xBF) ); } @Test public void testRES_b__B() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_B, 0xFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_B, 0xFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_B, context -> 0xFE).run(0xCB, 0x80), - test.verifyRegister(REG_B, context -> 0xFD).run(0xCB, 0x88), - test.verifyRegister(REG_B, context -> 0xFB).run(0xCB, 0x90), - test.verifyRegister(REG_B, context -> 0xF7).run(0xCB, 0x98), - test.verifyRegister(REG_B, context -> 0xEF).run(0xCB, 0xA0), - test.verifyRegister(REG_B, context -> 0xDF).run(0xCB, 0xA8), - test.verifyRegister(REG_B, context -> 0xBF).run(0xCB, 0xB0), - test.verifyRegister(REG_B, context -> 0x7F).run(0xCB, 0xB8) + test.verifyRegister(REG_B, context -> 0xFE).run(0xCB, 0x80), + test.verifyRegister(REG_B, context -> 0xFD).run(0xCB, 0x88), + test.verifyRegister(REG_B, context -> 0xFB).run(0xCB, 0x90), + test.verifyRegister(REG_B, context -> 0xF7).run(0xCB, 0x98), + test.verifyRegister(REG_B, context -> 0xEF).run(0xCB, 0xA0), + test.verifyRegister(REG_B, context -> 0xDF).run(0xCB, 0xA8), + test.verifyRegister(REG_B, context -> 0xBF).run(0xCB, 0xB0), + test.verifyRegister(REG_B, context -> 0x7F).run(0xCB, 0xB8) ); } @Test public void testRES_b__C() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_C, 0xFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_C, 0xFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_C, context -> 0xFE).run(0xCB, 0x81), - test.verifyRegister(REG_C, context -> 0xFD).run(0xCB, 0x89), - test.verifyRegister(REG_C, context -> 0xFB).run(0xCB, 0x91), - test.verifyRegister(REG_C, context -> 0xF7).run(0xCB, 0x99), - test.verifyRegister(REG_C, context -> 0xEF).run(0xCB, 0xA1), - test.verifyRegister(REG_C, context -> 0xDF).run(0xCB, 0xA9), - test.verifyRegister(REG_C, context -> 0xBF).run(0xCB, 0xB1), - test.verifyRegister(REG_C, context -> 0x7F).run(0xCB, 0xB9) + test.verifyRegister(REG_C, context -> 0xFE).run(0xCB, 0x81), + test.verifyRegister(REG_C, context -> 0xFD).run(0xCB, 0x89), + test.verifyRegister(REG_C, context -> 0xFB).run(0xCB, 0x91), + test.verifyRegister(REG_C, context -> 0xF7).run(0xCB, 0x99), + test.verifyRegister(REG_C, context -> 0xEF).run(0xCB, 0xA1), + test.verifyRegister(REG_C, context -> 0xDF).run(0xCB, 0xA9), + test.verifyRegister(REG_C, context -> 0xBF).run(0xCB, 0xB1), + test.verifyRegister(REG_C, context -> 0x7F).run(0xCB, 0xB9) ); } @Test public void testRES_b__D() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_D, 0xFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_D, 0xFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_D, context -> 0xFE).run(0xCB, 0x82), - test.verifyRegister(REG_D, context -> 0xFD).run(0xCB, 0x8A), - test.verifyRegister(REG_D, context -> 0xFB).run(0xCB, 0x92), - test.verifyRegister(REG_D, context -> 0xF7).run(0xCB, 0x9A), - test.verifyRegister(REG_D, context -> 0xEF).run(0xCB, 0xA2), - test.verifyRegister(REG_D, context -> 0xDF).run(0xCB, 0xAA), - test.verifyRegister(REG_D, context -> 0xBF).run(0xCB, 0xB2), - test.verifyRegister(REG_D, context -> 0x7F).run(0xCB, 0xBA) + test.verifyRegister(REG_D, context -> 0xFE).run(0xCB, 0x82), + test.verifyRegister(REG_D, context -> 0xFD).run(0xCB, 0x8A), + test.verifyRegister(REG_D, context -> 0xFB).run(0xCB, 0x92), + test.verifyRegister(REG_D, context -> 0xF7).run(0xCB, 0x9A), + test.verifyRegister(REG_D, context -> 0xEF).run(0xCB, 0xA2), + test.verifyRegister(REG_D, context -> 0xDF).run(0xCB, 0xAA), + test.verifyRegister(REG_D, context -> 0xBF).run(0xCB, 0xB2), + test.verifyRegister(REG_D, context -> 0x7F).run(0xCB, 0xBA) ); } @Test public void testRES_b__E() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_E, 0xFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_E, 0xFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_E, context -> 0xFE).run(0xCB, 0x83), - test.verifyRegister(REG_E, context -> 0xFD).run(0xCB, 0x8B), - test.verifyRegister(REG_E, context -> 0xFB).run(0xCB, 0x93), - test.verifyRegister(REG_E, context -> 0xF7).run(0xCB, 0x9B), - test.verifyRegister(REG_E, context -> 0xEF).run(0xCB, 0xA3), - test.verifyRegister(REG_E, context -> 0xDF).run(0xCB, 0xAB), - test.verifyRegister(REG_E, context -> 0xBF).run(0xCB, 0xB3), - test.verifyRegister(REG_E, context -> 0x7F).run(0xCB, 0xBB) + test.verifyRegister(REG_E, context -> 0xFE).run(0xCB, 0x83), + test.verifyRegister(REG_E, context -> 0xFD).run(0xCB, 0x8B), + test.verifyRegister(REG_E, context -> 0xFB).run(0xCB, 0x93), + test.verifyRegister(REG_E, context -> 0xF7).run(0xCB, 0x9B), + test.verifyRegister(REG_E, context -> 0xEF).run(0xCB, 0xA3), + test.verifyRegister(REG_E, context -> 0xDF).run(0xCB, 0xAB), + test.verifyRegister(REG_E, context -> 0xBF).run(0xCB, 0xB3), + test.verifyRegister(REG_E, context -> 0x7F).run(0xCB, 0xBB) ); } @Test public void testRES_b__H() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_H, 0xFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_H, 0xFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_H, context -> 0xFE).run(0xCB, 0x84), - test.verifyRegister(REG_H, context -> 0xFD).run(0xCB, 0x8C), - test.verifyRegister(REG_H, context -> 0xFB).run(0xCB, 0x94), - test.verifyRegister(REG_H, context -> 0xF7).run(0xCB, 0x9C), - test.verifyRegister(REG_H, context -> 0xEF).run(0xCB, 0xA4), - test.verifyRegister(REG_H, context -> 0xDF).run(0xCB, 0xAC), - test.verifyRegister(REG_H, context -> 0xBF).run(0xCB, 0xB4), - test.verifyRegister(REG_H, context -> 0x7F).run(0xCB, 0xBC) + test.verifyRegister(REG_H, context -> 0xFE).run(0xCB, 0x84), + test.verifyRegister(REG_H, context -> 0xFD).run(0xCB, 0x8C), + test.verifyRegister(REG_H, context -> 0xFB).run(0xCB, 0x94), + test.verifyRegister(REG_H, context -> 0xF7).run(0xCB, 0x9C), + test.verifyRegister(REG_H, context -> 0xEF).run(0xCB, 0xA4), + test.verifyRegister(REG_H, context -> 0xDF).run(0xCB, 0xAC), + test.verifyRegister(REG_H, context -> 0xBF).run(0xCB, 0xB4), + test.verifyRegister(REG_H, context -> 0x7F).run(0xCB, 0xBC) ); } @Test public void testRES_b__L() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setRegister(REG_L, 0xFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setRegister(REG_L, 0xFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forGivenOperandsAndSingleRun((byte) 0, - test.verifyRegister(REG_L, context -> 0xFE).run(0xCB, 0x85), - test.verifyRegister(REG_L, context -> 0xFD).run(0xCB, 0x8D), - test.verifyRegister(REG_L, context -> 0xFB).run(0xCB, 0x95), - test.verifyRegister(REG_L, context -> 0xF7).run(0xCB, 0x9D), - test.verifyRegister(REG_L, context -> 0xEF).run(0xCB, 0xA5), - test.verifyRegister(REG_L, context -> 0xDF).run(0xCB, 0xAD), - test.verifyRegister(REG_L, context -> 0xBF).run(0xCB, 0xB5), - test.verifyRegister(REG_L, context -> 0x7F).run(0xCB, 0xBD) + test.verifyRegister(REG_L, context -> 0xFE).run(0xCB, 0x85), + test.verifyRegister(REG_L, context -> 0xFD).run(0xCB, 0x8D), + test.verifyRegister(REG_L, context -> 0xFB).run(0xCB, 0x95), + test.verifyRegister(REG_L, context -> 0xF7).run(0xCB, 0x9D), + test.verifyRegister(REG_L, context -> 0xEF).run(0xCB, 0xA5), + test.verifyRegister(REG_L, context -> 0xDF).run(0xCB, 0xAD), + test.verifyRegister(REG_L, context -> 0xBF).run(0xCB, 0xB5), + test.verifyRegister(REG_L, context -> 0x7F).run(0xCB, 0xBD) ); } @Test public void testRES_b__mHL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsMemoryAddressByte(0xFF) - .firstIsPair(REG_PAIR_HL) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsMemoryAddressByte(0xFF) + .firstIsPair(REG_PAIR_HL) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> address = context -> context.first; Generator.forSome16bitUnary(2, - test.verifyByte(address, context -> 0xFE).run(0xCB, 0x86), - test.verifyByte(address, context -> 0xFD).run(0xCB, 0x8E), - test.verifyByte(address, context -> 0xFB).run(0xCB, 0x96), - test.verifyByte(address, context -> 0xF7).run(0xCB, 0x9E), - test.verifyByte(address, context -> 0xEF).run(0xCB, 0xA6), - test.verifyByte(address, context -> 0xDF).run(0xCB, 0xAE), - test.verifyByte(address, context -> 0xBF).run(0xCB, 0xB6), - test.verifyByte(address, context -> 0x7F).run(0xCB, 0xBE) + test.verifyByte(address, context -> 0xFE).run(0xCB, 0x86), + test.verifyByte(address, context -> 0xFD).run(0xCB, 0x8E), + test.verifyByte(address, context -> 0xFB).run(0xCB, 0x96), + test.verifyByte(address, context -> 0xF7).run(0xCB, 0x9E), + test.verifyByte(address, context -> 0xEF).run(0xCB, 0xA6), + test.verifyByte(address, context -> 0xDF).run(0xCB, 0xAE), + test.verifyByte(address, context -> 0xBF).run(0xCB, 0xB6), + test.verifyByte(address, context -> 0x7F).run(0xCB, 0xBE) ); } @Test public void testRES_b__IX_plus_d() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisIX() - .first8MSBplus8LSBisMemoryByte(0xFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .first8MSBisIX() + .first8MSBplus8LSBisMemoryByte(0xFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> address = context -> get8MSBplus8LSB(context.first); Generator.forSome16bitUnary(0x100, - test.verifyByte(address, context -> 0xFE).runWithFirst8bitOperandWithOpcodeAfter(0x86, 0xDD, 0xCB), - test.verifyByte(address, context -> 0xFD).runWithFirst8bitOperandWithOpcodeAfter(0x8E, 0xDD, 0xCB), - test.verifyByte(address, context -> 0xFB).runWithFirst8bitOperandWithOpcodeAfter(0x96, 0xDD, 0xCB), - test.verifyByte(address, context -> 0xF7).runWithFirst8bitOperandWithOpcodeAfter(0x9E, 0xDD, 0xCB), - test.verifyByte(address, context -> 0xEF).runWithFirst8bitOperandWithOpcodeAfter(0xA6, 0xDD, 0xCB), - test.verifyByte(address, context -> 0xDF).runWithFirst8bitOperandWithOpcodeAfter(0xAE, 0xDD, 0xCB), - test.verifyByte(address, context -> 0xBF).runWithFirst8bitOperandWithOpcodeAfter(0xB6, 0xDD, 0xCB), - test.verifyByte(address, context -> 0x7F).runWithFirst8bitOperandWithOpcodeAfter(0xBE, 0xDD, 0xCB) + test.verifyByte(address, context -> 0xFE).runWithFirst8bitOperandWithOpcodeAfter(0x86, 0xDD, 0xCB), + test.verifyByte(address, context -> 0xFD).runWithFirst8bitOperandWithOpcodeAfter(0x8E, 0xDD, 0xCB), + test.verifyByte(address, context -> 0xFB).runWithFirst8bitOperandWithOpcodeAfter(0x96, 0xDD, 0xCB), + test.verifyByte(address, context -> 0xF7).runWithFirst8bitOperandWithOpcodeAfter(0x9E, 0xDD, 0xCB), + test.verifyByte(address, context -> 0xEF).runWithFirst8bitOperandWithOpcodeAfter(0xA6, 0xDD, 0xCB), + test.verifyByte(address, context -> 0xDF).runWithFirst8bitOperandWithOpcodeAfter(0xAE, 0xDD, 0xCB), + test.verifyByte(address, context -> 0xBF).runWithFirst8bitOperandWithOpcodeAfter(0xB6, 0xDD, 0xCB), + test.verifyByte(address, context -> 0x7F).runWithFirst8bitOperandWithOpcodeAfter(0xBE, 0xDD, 0xCB) ); } @Test public void testRES_b__IY_plus_d() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisIY() - .first8MSBplus8LSBisMemoryByte(0xFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .first8MSBisIY() + .first8MSBplus8LSBisMemoryByte(0xFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> address = context -> get8MSBplus8LSB(context.first); Generator.forSome16bitUnary(0x100, - test.verifyByte(address, context -> 0xFE).runWithFirst8bitOperandWithOpcodeAfter(0x86, 0xFD, 0xCB), - test.verifyByte(address, context -> 0xFD).runWithFirst8bitOperandWithOpcodeAfter(0x8E, 0xFD, 0xCB), - test.verifyByte(address, context -> 0xFB).runWithFirst8bitOperandWithOpcodeAfter(0x96, 0xFD, 0xCB), - test.verifyByte(address, context -> 0xF7).runWithFirst8bitOperandWithOpcodeAfter(0x9E, 0xFD, 0xCB), - test.verifyByte(address, context -> 0xEF).runWithFirst8bitOperandWithOpcodeAfter(0xA6, 0xFD, 0xCB), - test.verifyByte(address, context -> 0xDF).runWithFirst8bitOperandWithOpcodeAfter(0xAE, 0xFD, 0xCB), - test.verifyByte(address, context -> 0xBF).runWithFirst8bitOperandWithOpcodeAfter(0xB6, 0xFD, 0xCB), - test.verifyByte(address, context -> 0x7F).runWithFirst8bitOperandWithOpcodeAfter(0xBE, 0xFD, 0xCB) + test.verifyByte(address, context -> 0xFE).runWithFirst8bitOperandWithOpcodeAfter(0x86, 0xFD, 0xCB), + test.verifyByte(address, context -> 0xFD).runWithFirst8bitOperandWithOpcodeAfter(0x8E, 0xFD, 0xCB), + test.verifyByte(address, context -> 0xFB).runWithFirst8bitOperandWithOpcodeAfter(0x96, 0xFD, 0xCB), + test.verifyByte(address, context -> 0xF7).runWithFirst8bitOperandWithOpcodeAfter(0x9E, 0xFD, 0xCB), + test.verifyByte(address, context -> 0xEF).runWithFirst8bitOperandWithOpcodeAfter(0xA6, 0xFD, 0xCB), + test.verifyByte(address, context -> 0xDF).runWithFirst8bitOperandWithOpcodeAfter(0xAE, 0xFD, 0xCB), + test.verifyByte(address, context -> 0xBF).runWithFirst8bitOperandWithOpcodeAfter(0xB6, 0xFD, 0xCB), + test.verifyByte(address, context -> 0x7F).runWithFirst8bitOperandWithOpcodeAfter(0xBE, 0xFD, 0xCB) ); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java index 13d370000..5efce3965 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ControlTest.java @@ -44,163 +44,163 @@ public void testEI_DI() { @Test public void testJP__nn__AND__JP_cc__nn() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsMemoryAddressWord(0) - .verifyPC(context -> context.first) - .verifyPair(REG_SP, context -> 0xFFFF) - .keepCurrentInjectorsAfterRun(); + .firstIsMemoryAddressWord(0) + .verifyPC(context -> context.first) + .verifyPair(REG_SP, context -> 0xFFFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitUnary(3, - test.runWithFirstOperand(0xC3), - test.runWithFirstOperand(0xC2), - test.setFlags(FLAG_Z).runWithFirstOperand(0xCA), - test.runWithFirstOperand(0xD2), - test.setFlags(FLAG_C).runWithFirstOperand(0xDA), - test.runWithFirstOperand(0xE2), - test.setFlags(FLAG_PV).runWithFirstOperand(0xEA), - test.runWithFirstOperand(0xF2), - test.setFlags(FLAG_S).runWithFirstOperand(0xFA) + test.runWithFirstOperand(0xC3), + test.runWithFirstOperand(0xC2), + test.setFlags(FLAG_Z).runWithFirstOperand(0xCA), + test.runWithFirstOperand(0xD2), + test.setFlags(FLAG_C).runWithFirstOperand(0xDA), + test.runWithFirstOperand(0xE2), + test.setFlags(FLAG_PV).runWithFirstOperand(0xEA), + test.runWithFirstOperand(0xF2), + test.setFlags(FLAG_S).runWithFirstOperand(0xFA) ); } @Test public void testNegative_JP_cc__nn() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsMemoryAddressWord(0) - .verifyPC(context -> context.PC + 3) - .verifyPair(REG_SP, context -> 0xFFFF) - .keepCurrentInjectorsAfterRun(); + .firstIsMemoryAddressWord(0) + .verifyPC(context -> context.PC + 3) + .verifyPair(REG_SP, context -> 0xFFFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitUnary(3, - test.setFlags(FLAG_Z).runWithFirstOperand(0xC2), - test.runWithFirstOperand(0xCA), - test.setFlags(FLAG_C).runWithFirstOperand(0xD2), - test.runWithFirstOperand(0xDA), - test.setFlags(FLAG_PV).runWithFirstOperand(0xE2), - test.runWithFirstOperand(0xEA), - test.setFlags(FLAG_S).runWithFirstOperand(0xF2), - test.runWithFirstOperand(0xFA) + test.setFlags(FLAG_Z).runWithFirstOperand(0xC2), + test.runWithFirstOperand(0xCA), + test.setFlags(FLAG_C).runWithFirstOperand(0xD2), + test.runWithFirstOperand(0xDA), + test.setFlags(FLAG_PV).runWithFirstOperand(0xE2), + test.runWithFirstOperand(0xEA), + test.setFlags(FLAG_S).runWithFirstOperand(0xF2), + test.runWithFirstOperand(0xFA) ); } @Test public void testJP__mHL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsMemoryAddressWord(0) - .firstIsPair(REG_PAIR_HL) - .verifyPC(context -> context.first); + .firstIsMemoryAddressWord(0) + .firstIsPair(REG_PAIR_HL) + .verifyPC(context -> context.first); Generator.forSome16bitUnary(1, - test.run(0xE9) + test.run(0xE9) ); } @Test public void testCALL__nn__AND__CALL_cc__nn() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsMemoryAddressWord(0) - .secondIsPair(REG_SP) - .verifyPair(REG_SP, context -> (context.second - 2) & 0xFFFF) - .verifyPC(context -> context.first) - .verifyWord(context -> (context.second - 2) & 0xFFFF, context -> context.PC + 3) - .keepCurrentInjectorsAfterRun(); + .firstIsMemoryAddressWord(0) + .secondIsPair(REG_SP) + .verifyPair(REG_SP, context -> (context.second - 2) & 0xFFFF) + .verifyPC(context -> context.first) + .verifyWord(context -> (context.second - 2) & 0xFFFF, context -> context.PC + 3) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(3, 5, - test.runWithFirstOperand(0xCD), - test.runWithFirstOperand(0xC4), - test.setFlags(FLAG_Z).runWithFirstOperand(0xCC), - test.runWithFirstOperand(0xD4), - test.setFlags(FLAG_C).runWithFirstOperand(0xDC), - test.runWithFirstOperand(0xE4), - test.setFlags(FLAG_PV).runWithFirstOperand(0xEC), - test.runWithFirstOperand(0xF4), - test.setFlags(FLAG_S).runWithFirstOperand(0xFC) + test.runWithFirstOperand(0xCD), + test.runWithFirstOperand(0xC4), + test.setFlags(FLAG_Z).runWithFirstOperand(0xCC), + test.runWithFirstOperand(0xD4), + test.setFlags(FLAG_C).runWithFirstOperand(0xDC), + test.runWithFirstOperand(0xE4), + test.setFlags(FLAG_PV).runWithFirstOperand(0xEC), + test.runWithFirstOperand(0xF4), + test.setFlags(FLAG_S).runWithFirstOperand(0xFC) ); } @Test public void testNegative_CALL_cc__nn() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsMemoryAddressWord(0) - .secondIsPair(REG_SP) - .verifyPair(REG_SP, context -> context.second) - .verifyPC(context -> context.PC + 3) - .verifyWord(context -> context.second, context -> 0) - .keepCurrentInjectorsAfterRun(); + .firstIsMemoryAddressWord(0) + .secondIsPair(REG_SP) + .verifyPair(REG_SP, context -> context.second) + .verifyPC(context -> context.PC + 3) + .verifyWord(context -> context.second, context -> 0) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(3, 5, - test.setFlags(FLAG_Z).runWithFirstOperand(0xC4), - test.runWithFirstOperand(0xCC), - test.setFlags(FLAG_C).runWithFirstOperand(0xD4), - test.runWithFirstOperand(0xDC), - test.setFlags(FLAG_PV).runWithFirstOperand(0xE4), - test.runWithFirstOperand(0xEC), - test.setFlags(FLAG_S).runWithFirstOperand(0xF4), - test.runWithFirstOperand(0xFC) + test.setFlags(FLAG_Z).runWithFirstOperand(0xC4), + test.runWithFirstOperand(0xCC), + test.setFlags(FLAG_C).runWithFirstOperand(0xD4), + test.runWithFirstOperand(0xDC), + test.setFlags(FLAG_PV).runWithFirstOperand(0xE4), + test.runWithFirstOperand(0xEC), + test.setFlags(FLAG_S).runWithFirstOperand(0xF4), + test.runWithFirstOperand(0xFC) ); } @Test public void testRET__AND__RET__cc() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .firstIsPair(REG_SP) - .verifyPC(context -> context.second) - .verifyPair(REG_SP, context -> (context.first + 2) & 0xFFFF) - .keepCurrentInjectorsAfterRun(); + .firstIsAddressAndSecondIsMemoryWord() + .firstIsPair(REG_SP) + .verifyPC(context -> context.second) + .verifyPair(REG_SP, context -> (context.first + 2) & 0xFFFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(1, - test.run(0xC9), - test.run(0xC0), - test.setFlags(FLAG_Z).run(0xC8), - test.run(0xD0), - test.setFlags(FLAG_C).run(0xD8), - test.run(0xE0), - test.setFlags(FLAG_PV).run(0xE8), - test.run(0xF0), - test.setFlags(FLAG_S).run(0xF8) + test.run(0xC9), + test.run(0xC0), + test.setFlags(FLAG_Z).run(0xC8), + test.run(0xD0), + test.setFlags(FLAG_C).run(0xD8), + test.run(0xE0), + test.setFlags(FLAG_PV).run(0xE8), + test.run(0xF0), + test.setFlags(FLAG_S).run(0xF8) ); } @Test public void testNegative_RET__cc() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .firstIsPair(REG_SP) - .verifyPC(context -> context.PC + 1) - .verifyPair(REG_SP, context -> context.first) - .keepCurrentInjectorsAfterRun(); + .firstIsAddressAndSecondIsMemoryWord() + .firstIsPair(REG_SP) + .verifyPC(context -> context.PC + 1) + .verifyPair(REG_SP, context -> context.first) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(1, - test.setFlags(FLAG_Z).run(0xC0), - test.run(0xC8), - test.setFlags(FLAG_C).run(0xD0), - test.run(0xD8), - test.setFlags(FLAG_PV).run(0xE0), - test.run(0xE8), - test.setFlags(FLAG_S).run(0xF0), - test.run(0xF8) + test.setFlags(FLAG_Z).run(0xC0), + test.run(0xC8), + test.setFlags(FLAG_C).run(0xD0), + test.run(0xD8), + test.setFlags(FLAG_PV).run(0xE0), + test.run(0xE8), + test.setFlags(FLAG_S).run(0xF0), + test.run(0xF8) ); } @Test public void testRST() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsMemoryAddressWord(0) - .firstIsPair(REG_SP) - .verifyPair(REG_SP, context -> (context.first - 2) & 0xFFFF) - .verifyWord(context -> (context.first - 2) & 0xFFFF, context -> context.PC + 1) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsMemoryAddressWord(0) + .firstIsPair(REG_SP) + .verifyPair(REG_SP, context -> (context.first - 2) & 0xFFFF) + .verifyWord(context -> (context.first - 2) & 0xFFFF, context -> context.PC + 1) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome16bitUnary(3, - test.verifyPC(context -> 0).run(0xC7), - test.verifyPC(context -> 8).run(0xCF), - test.verifyPC(context -> 0x10).run(0xD7), - test.verifyPC(context -> 0x18).run(0xDF), - test.verifyPC(context -> 0x20).run(0xE7), - test.verifyPC(context -> 0x28).run(0xEF), - test.verifyPC(context -> 0x30).run(0xF7), - test.verifyPC(context -> 0x38).run(0xFF) + test.verifyPC(context -> 0).run(0xC7), + test.verifyPC(context -> 8).run(0xCF), + test.verifyPC(context -> 0x10).run(0xD7), + test.verifyPC(context -> 0x18).run(0xDF), + test.verifyPC(context -> 0x20).run(0xE7), + test.verifyPC(context -> 0x28).run(0xEF), + test.verifyPC(context -> 0x30).run(0xF7), + test.verifyPC(context -> 0x38).run(0xFF) ); } @@ -277,107 +277,107 @@ public void testIM__2() { @Test public void testJR__e__AND__JR__cc() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .expandMemory(first -> cpuRunnerImpl.getPC() + first.intValue() & 0xFF) - .verifyPC(context -> (context.PC + context.first + 2) & 0xFFFF) - .keepCurrentInjectorsAfterRun(); + .expandMemory(first -> cpuRunnerImpl.getPC() + first.intValue() & 0xFF) + .verifyPC(context -> (context.PC + context.first + 2) & 0xFFFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.runWithFirstOperand(0x18), // jr * - test.runWithFirstOperand(0x20), // jr nz, * - test.setFlags(FLAG_Z).runWithFirstOperand(0x28), // jr z, * - test.runWithFirstOperand(0x30), // jr nc, * - test.setFlags(FLAG_C).runWithFirstOperand(0x38) // jr c, * + test.runWithFirstOperand(0x18), // jr * + test.runWithFirstOperand(0x20), // jr nz, * + test.setFlags(FLAG_Z).runWithFirstOperand(0x28), // jr z, * + test.runWithFirstOperand(0x30), // jr nc, * + test.setFlags(FLAG_C).runWithFirstOperand(0x38) // jr c, * ); } @Test public void testNegative__JR__e__AND__JR__cc() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .expandMemory(first -> cpuRunnerImpl.getPC() + first.intValue()) - .verifyPC(context -> (context.PC + 2) & 0xFFFF) - .keepCurrentInjectorsAfterRun(); + .expandMemory(first -> cpuRunnerImpl.getPC() + first.intValue()) + .verifyPC(context -> (context.PC + 2) & 0xFFFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.setFlags(FLAG_Z).runWithFirstOperand(0x20), - test.runWithFirstOperand(0x28), - test.setFlags(FLAG_C).runWithFirstOperand(0x30), - test.runWithFirstOperand(0x38) + test.setFlags(FLAG_Z).runWithFirstOperand(0x20), + test.runWithFirstOperand(0x28), + test.setFlags(FLAG_C).runWithFirstOperand(0x30), + test.runWithFirstOperand(0x38) ); } @Test public void testJP__IX() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIX() - .verifyPC(context -> context.first); + .firstIsIX() + .verifyPC(context -> context.first); Generator.forSome16bitUnary( - test.run(0xDD, 0xE9) + test.run(0xDD, 0xE9) ); } @Test public void testJP__IY() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIY() - .verifyPC(context -> context.first); + .firstIsIY() + .verifyPC(context -> context.first); Generator.forSome16bitUnary( - test.run(0xFD, 0xE9) + test.run(0xFD, 0xE9) ); } @Test public void testDJNZ__e() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .secondIsRegister(REG_B) - .expandMemory(first -> cpuRunnerImpl.getPC() + first.intValue()) - .verifyPC(context -> { - if (((context.second - 1) & 0xFF) == 0) { - return context.PC + 2; - } - return (context.PC + context.first + 2) & 0xFFFF; - }) - .verifyRegister(REG_B, context -> (context.second - 1) & 0xFF); + .secondIsRegister(REG_B) + .expandMemory(first -> cpuRunnerImpl.getPC() + first.intValue()) + .verifyPC(context -> { + if (((context.second - 1) & 0xFF) == 0) { + return context.PC + 2; + } + return (context.PC + context.first + 2) & 0xFFFF; + }) + .verifyRegister(REG_B, context -> (context.second - 1) & 0xFF); Generator.forSome8bitBinary( - test.runWithFirstOperand(0x10) + test.runWithFirstOperand(0x10) ); } @Test public void testRETI() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .firstIsPair(REG_SP) - .verifyPC(context -> context.second) - .verifyPair(REG_SP, context -> (context.first + 2) & 0xFFFF); + .firstIsAddressAndSecondIsMemoryWord() + .firstIsPair(REG_SP) + .verifyPC(context -> context.second) + .verifyPair(REG_SP, context -> (context.first + 2) & 0xFFFF); Generator.forSome16bitBinary(2, - test.run(0xED, 0x4D) + test.run(0xED, 0x4D) ); } @Test public void testRETN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .firstIsPair(REG_SP) - .verifyPC(context -> context.second) - .verifyPair(REG_SP, context -> (context.first + 2) & 0xFFFF) - .enableIFF2() - .disableIFF1() - .verifyIFF1isEnabled() - .keepCurrentInjectorsAfterRun(); + .firstIsAddressAndSecondIsMemoryWord() + .firstIsPair(REG_SP) + .verifyPC(context -> context.second) + .verifyPair(REG_SP, context -> (context.first + 2) & 0xFFFF) + .enableIFF2() + .disableIFF1() + .verifyIFF1isEnabled() + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(2, - test.run(0xED, 0x45), - test.run(0xED, 0x55), - test.run(0xED, 0x5D), - test.run(0xED, 0x65), - test.run(0xED, 0x6D), - test.run(0xED, 0x75), - test.run(0xED, 0x7D) + test.run(0xED, 0x45), + test.run(0xED, 0x55), + test.run(0xED, 0x5D), + test.run(0xED, 0x65), + test.run(0xED, 0x6D), + test.run(0xED, 0x75), + test.run(0xED, 0x7D) ); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/CpuImplTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/CpuImplTest.java index 921bab092..7d7eb20c3 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/CpuImplTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/CpuImplTest.java @@ -26,7 +26,6 @@ import org.junit.Test; import static org.easymock.EasyMock.*; -import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertNotEquals; public class CpuImplTest { diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java index 9309e1e3c..c78c9fd17 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java @@ -48,393 +48,393 @@ public void setUp() { @Test public void testDisassemble() throws InvalidInstructionException { memoryStub.setMemory(new short[]{ - 0, // nop - 0x08, // ex af, af' - 0x10, 0x20, // djnz 20 - 0x18, 0x20, // jr 20 - 0x20, 0x20, // jr nz, 20 - 0x28, 0x20, // jr z, 20h - 0x30, 0x20, // jr nc, 20h - 0x38, 0x20, // jr c, 20h - 0x01, 0x34, 0x12, // 10 // ld bc, 0x1234 - 0x11, 0x34, 0x12, // ld de, 0x1234 - 0x21, 0x34, 0x12, // ld hl, 0x1234 - 0x31, 0x34, 0x12, // ld sp, 0x1234 - 0x09, // add hl, bc - 0x19, // add hl, de - 0x29, // add hl, hl - 0x39, // add hl, sp - 0x02, // ld (bc), a - 0x12, // ld (de), a - 0x0A, // 20 // ld a, (bc) - 0x1A, // ld a, (de) - 0x22, 0x34, 0x12, // ld (0x1234), hl\n" // 0 - 0x32, 0x34, 0x12, // ld (0x1234), a - 0x2A, 0x34, 0x12, // ld hl, (0x1234) - 0x3A, 0x34, 0x12, // ld a, (0x1234) - 0x03, // inc bc - 0x13, // inc de - 0x23, // 30 // inc hl - 0x33, // inc sp - 0x0B, // dec bc - 0x1B, // dec de - 0x2B, // dec hl - 0x3B, // dec sp - 0x04, // inc b - 0x0C, // inc c - 0x14, // inc d - 0x1C, // inc e - 0x24, // inc h - 0x2C, // inc l - 0x3C, // inc a - 0x05, // dec b - 0x0D, // dec c - 0x15, // dec d - 0x1D, // 40 // dec e - 0x25, // dec h - 0x2D, // dec l - 0x3D, // dec a - 0x06, 0x20, // ld b, 0x20 - 0x0E, 0x20, // ld c, 0x20 - 0x16, 0x20, // ld d, 0x20 - 0x1E, 0x20, // ld e, 0x20 - 0x26, 0x20, // ld h, 0x20 - 0x2E, 0x20, // ld l, 0x20 - 0x07, // 50 // rlca - 0x0F, // rrca - 0x17, // rla - 0x1F, // rra - 0x27, // daa - 0x2F, // cpl - 0x37, // scf - 0x3F, // ccf - 0x40, // ld b, b - 0x41, // ld b, c - 0x42, // ld b, d - 0x43, // ld b, e - 0x44, // ld b, h - 0x45, // ld b, l - 0x47, // ld b, a - 0x70, // ld (hl), b - 0x71, // 60 // ld (hl), c - 0x72, // ld (hl), d - 0x73, // ld (hl), e - 0x74, // ld (hl), h - 0x75, // ld (hl), l - 0x77, // ld (hl), a - 0x76, // halt - 0x80, // add a, b - 0x86, // add a, (hl) - 0x89, // adc a, c - 0x8E, // adc a, (hl) - 0x90, // sub b - 0x96, // sub (hl) - 0x98, // sbc a, b - 0x9E, // sbc a, (hl) - 0xA0, // and b - 0xA6, // 70 // and (hl) - 0xA8, // xor b - 0xAE, // xor (hl) - 0xB0, // or b - 0xB6, // or (hl) - 0xB8, // cp b - 0xBE, // cp (hl) - 0xC0, // ret nz - 0xC8, // ret z - 0xD0, // ret nc - 0xD8, // ret c - 0xE0, // 7b // ret po - 0xE8, // ret pe - 0xF0, // ret p - 0xF8, // ret m - 0xC1, // pop bc - 0xD1, // 80 // pop de - 0xE1, // pop hl - 0xF1, // pop af - 0xC9, // ret - 0xD9, // exx - 0xE9, // jp hl - 0xE9, // jp (hl) - 0xF9, // ld sp, hl - 0xC2, 0x34, 0x12, // jp nz, 0x1234 - 0xCA, 0x34, 0x12, // jp z, 0x1234 - 0xD2, 0x34, 0x12, // jp nc, 0x1234 - 0xDA, 0x34, 0x12, // jp c, 0x1234 - 0xE2, 0x34, 0x12, // jp po, 0x1234 - 0xEA, 0x34, 0x12, // jp pe, 0x1234 - 0xF2, 0x34, 0x12, // jp p, 0x1234 - 0xFA, 0x34, 0x12, // jp m, 0x1234 - 0xC3, 0x34, 0x12, // jp 0x1234 - 0xD3, 0x20, // out (0x20), a - 0xDB, 0x20, // in a, (0x20) - 0xE3, // ex (sp), hl - 0xEB, // ex de, hl - 0xF3, // di - 0xFB, // ei - 0xC4, 0x34, 0x12, // call nz, 0x1234 - 0xCC, 0x34, 0x12, // call z, 0x1234 - 0xD4, 0x34, 0x12, // call nc, 0x1234 - 0xDC, 0x34, 0x12, // call c, 0x1234 - 0xE4, 0x34, 0x12, // call po, 0x1234 - 0xEC, 0x34, 0x12, // call pe, 0x1234 - 0xF4, 0x34, 0x12, // call p, 0x1234 - 0xFC, 0x34, 0x12, // call m, 0x1234 - 0xC5, // push bc - 0xD5, // push de - 0xE5, // push hl - 0xF5, // push af - 0xCD, 0x34, 0x12, // call 0x1234 - 0xC6, 0x20, // add a, 0x20 - 0xCE, 0x20, // adc a, 0x20 - 0xD6, 0x20, // sub 0x20 - 0xDE, 0x20, // sbc a, 0x20 - 0xE6, 0x20, // and 0x20 - 0xEE, 0x20, // xor 0x20 - 0xF6, 0x20, // or 0x20 - 0xFE, 0x20, // cp 0x20 - 0xC7, // rst 0 - 0xCF, // rst 8 - 0xD7, // rst 10h - 0xDF, // rst 18h - 0xE7, // rst 20h - 0xEF, // rst 28h - 0xF7, // rst 30h - 0xFF, // rst 38h - 0xCB, 0x00, // rlc b - 0xCB, 0x06, // rlc (HL) - 0xCB, 0x09, // rrc c - 0xCB, 0x0E, // rrc (HL) - 0xCB, 0x12, // rl d - 0xCB, 0x16, // rl (HL) - 0xCB, 0x1B, // rr e - 0xCB, 0x1E, // rr (hl) - 0xCB, 0x24, // sla h - 0xCB, 0x26, // sla (hl) - 0xCB, 0x2D, // sra l - 0xCB, 0x2E, // sra (hl) - 0xCB, 0x30, // sll b - 0xCB, 0x36, // sll (hl) - 0xCB, 0x39, // srl c - 0xCB, 0x3E, // srl (hl) - 0xCB, 0x68, // bit 5, b - 0xCB, 0x6E, // bit 5, (hl) - 0xCB, 0xA9, // res 5, c - 0xCB, 0xB6, // res 6, (hl) - 0xCB, 0xFA, // set 7, d - 0xCB, 0xFE, // set 7, (hl) - 0xED, 0x58, // in e, (c) - 0xED, 0x70, // in (c) - 0xED, 0x61, // out (c), h - 0xED, 0x71, // out (c), 0 - 0xED, 0x42, // sbc hl, bc - 0xED, 0x52, // sbc hl, de - 0xED, 0x62, // sbc hl, hl - 0xED, 0x72, // sbc hl, sp - 0xED, 0x4A, // adc hl, bc - 0xED, 0x5A, // adc hl, de - 0xED, 0x6A, // adc hl, hl - 0xED, 0x7A, // adc hl, sp - 0xED, 0x43, 0x34, 0x12, // ld (1234h), bc - 0xED, 0x53, 0x34, 0x12, // ld (1234h), de - 0x22, 0x34, 0x12, // 0xED, 0x63, 0x34, 0x12 // ld (1234h), hl - 0xED, 0x73, 0x34, 0x12, // ld (1234h), sp - 0xED, 0x4B, 0x34, 0x12, // ld bc, (0x1234) - 0xED, 0x5B, 0x34, 0x12, // ld de, (0x1234) - 0x2A, 0x34, 0x12, // 0xED, 0x6B, 0x34, 0x12 // ld hl, (0x1234) - 0xED, 0x7B, 0x34, 0x12, // ld sp, (0x1234) - 0xED, 0x44, // neg - 0xED, 0x45, // retn - 0xED, 0x4D, // reti - 0xED, 0x46, // im 0 - 0xED, 0x4E, // im 0/1 - 0xED, 0x56, // im 1 - 0xED, 0x5E, // im 2 - 0xED, 0x47, // ld i, a - 0xED, 0x4F, // ld r, a - 0xED, 0x57, // ld a, i - 0xED, 0x5F, // ld a, r - 0xED, 0x67, // rrd - 0xED, 0x6F, // rld - 0xED, 0xA0, // ldi - 0xED, 0xA8, // ldd - 0xED, 0xB0, // ldir - 0xED, 0xB8, // lddr - 0xED, 0xA1, // cpi - 0xED, 0xA9, // cpd - 0xED, 0xB1, // cpir - 0xED, 0xB9, // cpdr - 0xED, 0xA2, // ini - 0xED, 0xAA, // ind - 0xED, 0xB2, // inir - 0xED, 0xBA, // indr - 0xED, 0xA3, // outi - 0xED, 0xAB, // outd - 0xED, 0xB3, // otir - 0xED, 0xBB, // otdr - 0xDD, 0xCB, 0x20, 0x00, // rlc (ix+0x20), b - 0xFD, 0xCB, 0x20, 0x00, // rlc (iy+0x20), b - 0xDD, 0xCB, 0x20, 0x06, // rlc (ix+0x20) - 0xFD, 0xCB, 0x20, 0x06, // rlc (iy+0x20) - 0xDD, 0xCB, 0x20, 0x09, // rrc (ix+0x20), c - 0xFD, 0xCB, 0x20, 0x09, // rrc (iy+0x20), c - 0xDD, 0xCB, 0x20, 0x0E, // rrc (ix+0x20) - 0xFD, 0xCB, 0x20, 0x0E, // rrc (iy+0x20) - 0xDD, 0xCB, 0x20, 0x12, // rl (ix+0x20), d - 0xFD, 0xCB, 0x20, 0x12, // rl (iy+0x20), d - 0xDD, 0xCB, 0x20, 0x16, // rl (ix+0x20) - 0xFD, 0xCB, 0x20, 0x16, // rl (iy+0x20) - 0xDD, 0xCB, 0x20, 0x1B, // rr (ix+0x20), e - 0xFD, 0xCB, 0x20, 0x1B, // rr (iy+0x20), e - 0xDD, 0xCB, 0x20, 0x1E, // rr (ix+0x20) - 0xFD, 0xCB, 0x20, 0x1E, // rr (iy+0x20) - 0xDD, 0xCB, 0x20, 0x24, // sla (ix+0x20), h - 0xFD, 0xCB, 0x20, 0x24, // sla (iy+0x20), h - 0xDD, 0xCB, 0x20, 0x26, // sla (ix+0x20) - 0xFD, 0xCB, 0x20, 0x26, // sla (iy+0x20) - 0xDD, 0xCB, 0x20, 0x2D, // sra (ix+0x20), l - 0xFD, 0xCB, 0x20, 0x2D, // sra (iy+0x20), l - 0xDD, 0xCB, 0x20, 0x2E, // sra (ix+0x20) - 0xFD, 0xCB, 0x20, 0x2E, // sra (iy+0x20) - 0xDD, 0xCB, 0x20, 0x30, // sll (ix+0x20), b - 0xFD, 0xCB, 0x20, 0x30, // sll (iy+0x20), b - 0xDD, 0xCB, 0x20, 0x36, // sll (ix+0x20) - 0xFD, 0xCB, 0x20, 0x36, // sll (iy+0x20) - 0xDD, 0xCB, 0x20, 0x39, // srl (ix+0x20), c - 0xFD, 0xCB, 0x20, 0x39, // srl (iy+0x20), c - 0xDD, 0xCB, 0x20, 0x3E, // srl (ix+0x20) - 0xFD, 0xCB, 0x20, 0x3E, // srl (iy+0x20) - 0xDD, 0xCB, 0x20, 0x5E, // bit 3, (ix+0x20) - 0xFD, 0xCB, 0x20, 0x5E, // bit 3, (iy+0x20) - 0xDD, 0xCB, 0x20, 0xA8, // res 5, (ix+0x20), b - 0xFD, 0xCB, 0x20, 0xA8, // res 5, (iy+0x20), b - 0xDD, 0xCB, 0x20, 0xAE, // res 5, (ix+0x20) - 0xFD, 0xCB, 0x20, 0xAE, // res 5, (iy+0x20) - 0xDD, 0xCB, 0x20, 0xF1, // set 6, (ix+0x20), c - 0xFD, 0xCB, 0x20, 0xF1, // set 6, (iy+0x20), c - 0xDD, 0xCB, 0x20, 0xF6, // set 6, (ix+0x20) - 0xFD, 0xCB, 0x20, 0xF6, // set 6, (iy+0x20) - 0xDD, 0x21, 0x34, 0x12, // ld ix, 0x1234 - 0xFD, 0x21, 0x34, 0x12, // ld iy, 0x1234 - 0xDD, 0x09, // add ix, bc - 0xFD, 0x09, // add iy, bc - 0xDD, 0x19, // add ix, de - 0xFD, 0x19, // add iy, de - 0xDD, 0x29, // add ix, ix - 0xFD, 0x29, // add iy, iy - 0xDD, 0x39, // add ix, sp - 0xFD, 0x39, // add iy, sp - 0xDD, 0x22, 0x34, 0x12, // ld (0x1234), ix - 0xFD, 0x22, 0x34, 0x12, // ld (0x1234), iy - 0xDD, 0x2A, 0x34, 0x12, // ld ix, (0x1234) - 0xFD, 0x2A, 0x34, 0x12, // ld iy, (0x1234) - 0xDD, 0x23, // inc ix - 0xFD, 0x23, // inc iy - 0xDD, 0x2B, // dec ix - 0xFD, 0x2B, // dec iy - 0xDD, 0x24, // inc ixh - 0xFD, 0x24, // inc iyh - 0xDD, 0x2C, // inc ixl - 0xFD, 0x2C, // inc iyl - 0xDD, 0x34, 0x20, // inc (ix+0x20) - 0xFD, 0x34, 0x20, // inc (iy+0x20) - 0xDD, 0x25, // dec ixh - 0xFD, 0x25, // dec iyh - 0xDD, 0x2D, // dec ixl - 0xFD, 0x2D, // dec iyl - 0xDD, 0x35, 0x20, // dec (ix+0x20) - 0xFD, 0x35, 0x20, // dec (iy+0x20) - 0xDD, 0x26, 0x20, // ld ixh, 0x20 - 0xDD, 0x2E, 0x20, // ld ixl, 0x20 - 0xFD, 0x26, 0x20, // ld iyh, 0x20 - 0xFD, 0x2E, 0x20, // ld iyl, 0x20 - 0xDD, 0x36, 0x20, 0x20, // ld (ix+0x20), 0x20 - 0xFD, 0x36, 0x20, 0x20, // ld (iy+0x20), 0x20 - 0xDD, 0x60, // ld ixh, b - 0xDD, 0x64, // ld ixh, ixh - 0xDD, 0x65, // ld ixh, ixl - 0xFD, 0x61, // ld iyh, c - 0xFD, 0x64, // ld iyh, iyh - 0xFD, 0x65, // ld iyh, iyl - 0xDD, 0x6A, // ld ixl, d - 0xDD, 0x6C, // ld ixl, ixh - 0xDD, 0x6D, // ld ixl, ixl - 0xFD, 0x6B, // ld iyl, e - 0xFD, 0x6C, // ld iyl, iyh - 0xFD, 0x6D, // ld iyl, iyl - 0xDD, 0x72, 0x20, // ld (ix+0x20), d - 0xDD, 0x74, 0x20, // ld (ix+0x20), h - 0xDD, 0x75, 0x20, // ld (ix+0x20), l - 0xFD, 0x73, 0x20, // ld (iy+0x20), e - 0xFD, 0x74, 0x20, // ld (iy+0x20), h - 0xFD, 0x75, 0x20, // ld (iy+0x20), l - 0xDD, 0x7C, // ld a, ixh - 0xFD, 0x7C, // ld a, iyh - 0xDD, 0x7D, // ld a, ixl - 0xFD, 0x7D, // ld a, iyl - 0xDD, 0x7E, 0x20, // ld a, (ix+0x20) - 0xFD, 0x7E, 0x20, // ld a, (iy+0x20) - 0xDD, 0x66, 0x20, // ld h, (ix+0x20) - 0xDD, 0x6E, 0x20, // ld l, (ix+0x20) - 0xFD, 0x66, 0x20, // ld h, (iy+0x20) - 0xFD, 0x6E, 0x20, // ld l, (iy+0x20) - 0xDD, 0x84, // add a, ixh - 0xDD, 0x85, // add a, ixl - 0xDD, 0x86, 0x20, // add a, (ix + 0x20) - 0xFD, 0x84, // add a, iyh - 0xFD, 0x85, // add a, iyl - 0xFD, 0x86, 0x20, // add a, (iy+0x20) - 0xDD, 0x8C, // adc a, ixh - 0xDD, 0x8D, // adc a, ixl - 0xDD, 0x8E, 0x20, // adc a, (ix+0x20) - 0xFD, 0x8C, // adc a, iyh - 0xFD, 0x8D, // adc a, iyl - 0xFD, 0x8E, 0x20, // adc a, (iy+0x20) - 0xDD, 0x94, // sub ixh - 0xDD, 0x95, // sub ixl - 0xDD, 0x96, 0x20, // sub (ix+0x20) - 0xFD, 0x94, // sub iyh - 0xFD, 0x95, // sub iyl - 0xFD, 0x96, 0x20, // sub (iy+0x20) - 0xDD, 0x9C, // sbc a, ixh - 0xDD, 0x9D, // sbc a, ixl - 0xDD, 0x9E, 0x20, // sbc a, (ix+0x20) - 0xFD, 0x9C, // sbc a, iyh - 0xFD, 0x9D, // sbc a, iyl - 0xFD, 0x9E, 0x20, // sbc a, (iy+0x20) - 0xDD, 0xA4, // and ixh - 0xDD, 0xA5, // and ixl - 0xDD, 0xA6, 0x20, // and (ix+0x20) - 0xFD, 0xA4, // and iyh - 0xFD, 0xA5, // and iyl - 0xFD, 0xA6, 0x20, // and (iy+0x20) - 0xDD, 0xAC, // xor ixh - 0xDD, 0xAD, // xor ixl - 0xDD, 0xAE, 0x20, // xor (ix+0x20) - 0xFD, 0xAC, // xor iyh - 0xFD, 0xAD, // xor iyl - 0xFD, 0xAE, 0x20, // xor (iy+0x20) - 0xDD, 0xB4, // or ixh - 0xDD, 0xB5, // or ixl - 0xDD, 0xB6, 0x20, // or (ix+0x20) - 0xFD, 0xB4, // or iyh - 0xFD, 0xB5, // or iyl - 0xFD, 0xB6, 0x20, // or (iy+0x20) - 0xDD, 0xBC, // cp ixh - 0xDD, 0xBD, // cp ixl - 0xDD, 0xBE, 0x20, // cp (ix+0x20) - 0xFD, 0xBC, // cp iyh - 0xFD, 0xBD, // cp iyl - 0xFD, 0xBE, 0x20, // cp (iy+0x20) - 0xDD, 0xE1, // pop ix - 0xFD, 0xE1, // pop iy - 0xDD, 0xE9, // jp (ix) - 0xFD, 0xE9, // jp (iy) - 0xDD, 0xF9, // ld sp, ix - 0xFD, 0xF9, // ld sp, iy - 0xDD, 0xE3, // ex (sp), ix - 0xFD, 0xE3, // ex (sp), iy - 0xDD, 0xE5, // push ix - 0xFD, 0xE5 // push iy + 0, // nop + 0x08, // ex af, af' + 0x10, 0x20, // djnz 20 + 0x18, 0x20, // jr 20 + 0x20, 0x20, // jr nz, 20 + 0x28, 0x20, // jr z, 20h + 0x30, 0x20, // jr nc, 20h + 0x38, 0x20, // jr c, 20h + 0x01, 0x34, 0x12, // 10 // ld bc, 0x1234 + 0x11, 0x34, 0x12, // ld de, 0x1234 + 0x21, 0x34, 0x12, // ld hl, 0x1234 + 0x31, 0x34, 0x12, // ld sp, 0x1234 + 0x09, // add hl, bc + 0x19, // add hl, de + 0x29, // add hl, hl + 0x39, // add hl, sp + 0x02, // ld (bc), a + 0x12, // ld (de), a + 0x0A, // 20 // ld a, (bc) + 0x1A, // ld a, (de) + 0x22, 0x34, 0x12, // ld (0x1234), hl\n" // 0 + 0x32, 0x34, 0x12, // ld (0x1234), a + 0x2A, 0x34, 0x12, // ld hl, (0x1234) + 0x3A, 0x34, 0x12, // ld a, (0x1234) + 0x03, // inc bc + 0x13, // inc de + 0x23, // 30 // inc hl + 0x33, // inc sp + 0x0B, // dec bc + 0x1B, // dec de + 0x2B, // dec hl + 0x3B, // dec sp + 0x04, // inc b + 0x0C, // inc c + 0x14, // inc d + 0x1C, // inc e + 0x24, // inc h + 0x2C, // inc l + 0x3C, // inc a + 0x05, // dec b + 0x0D, // dec c + 0x15, // dec d + 0x1D, // 40 // dec e + 0x25, // dec h + 0x2D, // dec l + 0x3D, // dec a + 0x06, 0x20, // ld b, 0x20 + 0x0E, 0x20, // ld c, 0x20 + 0x16, 0x20, // ld d, 0x20 + 0x1E, 0x20, // ld e, 0x20 + 0x26, 0x20, // ld h, 0x20 + 0x2E, 0x20, // ld l, 0x20 + 0x07, // 50 // rlca + 0x0F, // rrca + 0x17, // rla + 0x1F, // rra + 0x27, // daa + 0x2F, // cpl + 0x37, // scf + 0x3F, // ccf + 0x40, // ld b, b + 0x41, // ld b, c + 0x42, // ld b, d + 0x43, // ld b, e + 0x44, // ld b, h + 0x45, // ld b, l + 0x47, // ld b, a + 0x70, // ld (hl), b + 0x71, // 60 // ld (hl), c + 0x72, // ld (hl), d + 0x73, // ld (hl), e + 0x74, // ld (hl), h + 0x75, // ld (hl), l + 0x77, // ld (hl), a + 0x76, // halt + 0x80, // add a, b + 0x86, // add a, (hl) + 0x89, // adc a, c + 0x8E, // adc a, (hl) + 0x90, // sub b + 0x96, // sub (hl) + 0x98, // sbc a, b + 0x9E, // sbc a, (hl) + 0xA0, // and b + 0xA6, // 70 // and (hl) + 0xA8, // xor b + 0xAE, // xor (hl) + 0xB0, // or b + 0xB6, // or (hl) + 0xB8, // cp b + 0xBE, // cp (hl) + 0xC0, // ret nz + 0xC8, // ret z + 0xD0, // ret nc + 0xD8, // ret c + 0xE0, // 7b // ret po + 0xE8, // ret pe + 0xF0, // ret p + 0xF8, // ret m + 0xC1, // pop bc + 0xD1, // 80 // pop de + 0xE1, // pop hl + 0xF1, // pop af + 0xC9, // ret + 0xD9, // exx + 0xE9, // jp hl + 0xE9, // jp (hl) + 0xF9, // ld sp, hl + 0xC2, 0x34, 0x12, // jp nz, 0x1234 + 0xCA, 0x34, 0x12, // jp z, 0x1234 + 0xD2, 0x34, 0x12, // jp nc, 0x1234 + 0xDA, 0x34, 0x12, // jp c, 0x1234 + 0xE2, 0x34, 0x12, // jp po, 0x1234 + 0xEA, 0x34, 0x12, // jp pe, 0x1234 + 0xF2, 0x34, 0x12, // jp p, 0x1234 + 0xFA, 0x34, 0x12, // jp m, 0x1234 + 0xC3, 0x34, 0x12, // jp 0x1234 + 0xD3, 0x20, // out (0x20), a + 0xDB, 0x20, // in a, (0x20) + 0xE3, // ex (sp), hl + 0xEB, // ex de, hl + 0xF3, // di + 0xFB, // ei + 0xC4, 0x34, 0x12, // call nz, 0x1234 + 0xCC, 0x34, 0x12, // call z, 0x1234 + 0xD4, 0x34, 0x12, // call nc, 0x1234 + 0xDC, 0x34, 0x12, // call c, 0x1234 + 0xE4, 0x34, 0x12, // call po, 0x1234 + 0xEC, 0x34, 0x12, // call pe, 0x1234 + 0xF4, 0x34, 0x12, // call p, 0x1234 + 0xFC, 0x34, 0x12, // call m, 0x1234 + 0xC5, // push bc + 0xD5, // push de + 0xE5, // push hl + 0xF5, // push af + 0xCD, 0x34, 0x12, // call 0x1234 + 0xC6, 0x20, // add a, 0x20 + 0xCE, 0x20, // adc a, 0x20 + 0xD6, 0x20, // sub 0x20 + 0xDE, 0x20, // sbc a, 0x20 + 0xE6, 0x20, // and 0x20 + 0xEE, 0x20, // xor 0x20 + 0xF6, 0x20, // or 0x20 + 0xFE, 0x20, // cp 0x20 + 0xC7, // rst 0 + 0xCF, // rst 8 + 0xD7, // rst 10h + 0xDF, // rst 18h + 0xE7, // rst 20h + 0xEF, // rst 28h + 0xF7, // rst 30h + 0xFF, // rst 38h + 0xCB, 0x00, // rlc b + 0xCB, 0x06, // rlc (HL) + 0xCB, 0x09, // rrc c + 0xCB, 0x0E, // rrc (HL) + 0xCB, 0x12, // rl d + 0xCB, 0x16, // rl (HL) + 0xCB, 0x1B, // rr e + 0xCB, 0x1E, // rr (hl) + 0xCB, 0x24, // sla h + 0xCB, 0x26, // sla (hl) + 0xCB, 0x2D, // sra l + 0xCB, 0x2E, // sra (hl) + 0xCB, 0x30, // sll b + 0xCB, 0x36, // sll (hl) + 0xCB, 0x39, // srl c + 0xCB, 0x3E, // srl (hl) + 0xCB, 0x68, // bit 5, b + 0xCB, 0x6E, // bit 5, (hl) + 0xCB, 0xA9, // res 5, c + 0xCB, 0xB6, // res 6, (hl) + 0xCB, 0xFA, // set 7, d + 0xCB, 0xFE, // set 7, (hl) + 0xED, 0x58, // in e, (c) + 0xED, 0x70, // in (c) + 0xED, 0x61, // out (c), h + 0xED, 0x71, // out (c), 0 + 0xED, 0x42, // sbc hl, bc + 0xED, 0x52, // sbc hl, de + 0xED, 0x62, // sbc hl, hl + 0xED, 0x72, // sbc hl, sp + 0xED, 0x4A, // adc hl, bc + 0xED, 0x5A, // adc hl, de + 0xED, 0x6A, // adc hl, hl + 0xED, 0x7A, // adc hl, sp + 0xED, 0x43, 0x34, 0x12, // ld (1234h), bc + 0xED, 0x53, 0x34, 0x12, // ld (1234h), de + 0x22, 0x34, 0x12, // 0xED, 0x63, 0x34, 0x12 // ld (1234h), hl + 0xED, 0x73, 0x34, 0x12, // ld (1234h), sp + 0xED, 0x4B, 0x34, 0x12, // ld bc, (0x1234) + 0xED, 0x5B, 0x34, 0x12, // ld de, (0x1234) + 0x2A, 0x34, 0x12, // 0xED, 0x6B, 0x34, 0x12 // ld hl, (0x1234) + 0xED, 0x7B, 0x34, 0x12, // ld sp, (0x1234) + 0xED, 0x44, // neg + 0xED, 0x45, // retn + 0xED, 0x4D, // reti + 0xED, 0x46, // im 0 + 0xED, 0x4E, // im 0/1 + 0xED, 0x56, // im 1 + 0xED, 0x5E, // im 2 + 0xED, 0x47, // ld i, a + 0xED, 0x4F, // ld r, a + 0xED, 0x57, // ld a, i + 0xED, 0x5F, // ld a, r + 0xED, 0x67, // rrd + 0xED, 0x6F, // rld + 0xED, 0xA0, // ldi + 0xED, 0xA8, // ldd + 0xED, 0xB0, // ldir + 0xED, 0xB8, // lddr + 0xED, 0xA1, // cpi + 0xED, 0xA9, // cpd + 0xED, 0xB1, // cpir + 0xED, 0xB9, // cpdr + 0xED, 0xA2, // ini + 0xED, 0xAA, // ind + 0xED, 0xB2, // inir + 0xED, 0xBA, // indr + 0xED, 0xA3, // outi + 0xED, 0xAB, // outd + 0xED, 0xB3, // otir + 0xED, 0xBB, // otdr + 0xDD, 0xCB, 0x20, 0x00, // rlc (ix+0x20), b + 0xFD, 0xCB, 0x20, 0x00, // rlc (iy+0x20), b + 0xDD, 0xCB, 0x20, 0x06, // rlc (ix+0x20) + 0xFD, 0xCB, 0x20, 0x06, // rlc (iy+0x20) + 0xDD, 0xCB, 0x20, 0x09, // rrc (ix+0x20), c + 0xFD, 0xCB, 0x20, 0x09, // rrc (iy+0x20), c + 0xDD, 0xCB, 0x20, 0x0E, // rrc (ix+0x20) + 0xFD, 0xCB, 0x20, 0x0E, // rrc (iy+0x20) + 0xDD, 0xCB, 0x20, 0x12, // rl (ix+0x20), d + 0xFD, 0xCB, 0x20, 0x12, // rl (iy+0x20), d + 0xDD, 0xCB, 0x20, 0x16, // rl (ix+0x20) + 0xFD, 0xCB, 0x20, 0x16, // rl (iy+0x20) + 0xDD, 0xCB, 0x20, 0x1B, // rr (ix+0x20), e + 0xFD, 0xCB, 0x20, 0x1B, // rr (iy+0x20), e + 0xDD, 0xCB, 0x20, 0x1E, // rr (ix+0x20) + 0xFD, 0xCB, 0x20, 0x1E, // rr (iy+0x20) + 0xDD, 0xCB, 0x20, 0x24, // sla (ix+0x20), h + 0xFD, 0xCB, 0x20, 0x24, // sla (iy+0x20), h + 0xDD, 0xCB, 0x20, 0x26, // sla (ix+0x20) + 0xFD, 0xCB, 0x20, 0x26, // sla (iy+0x20) + 0xDD, 0xCB, 0x20, 0x2D, // sra (ix+0x20), l + 0xFD, 0xCB, 0x20, 0x2D, // sra (iy+0x20), l + 0xDD, 0xCB, 0x20, 0x2E, // sra (ix+0x20) + 0xFD, 0xCB, 0x20, 0x2E, // sra (iy+0x20) + 0xDD, 0xCB, 0x20, 0x30, // sll (ix+0x20), b + 0xFD, 0xCB, 0x20, 0x30, // sll (iy+0x20), b + 0xDD, 0xCB, 0x20, 0x36, // sll (ix+0x20) + 0xFD, 0xCB, 0x20, 0x36, // sll (iy+0x20) + 0xDD, 0xCB, 0x20, 0x39, // srl (ix+0x20), c + 0xFD, 0xCB, 0x20, 0x39, // srl (iy+0x20), c + 0xDD, 0xCB, 0x20, 0x3E, // srl (ix+0x20) + 0xFD, 0xCB, 0x20, 0x3E, // srl (iy+0x20) + 0xDD, 0xCB, 0x20, 0x5E, // bit 3, (ix+0x20) + 0xFD, 0xCB, 0x20, 0x5E, // bit 3, (iy+0x20) + 0xDD, 0xCB, 0x20, 0xA8, // res 5, (ix+0x20), b + 0xFD, 0xCB, 0x20, 0xA8, // res 5, (iy+0x20), b + 0xDD, 0xCB, 0x20, 0xAE, // res 5, (ix+0x20) + 0xFD, 0xCB, 0x20, 0xAE, // res 5, (iy+0x20) + 0xDD, 0xCB, 0x20, 0xF1, // set 6, (ix+0x20), c + 0xFD, 0xCB, 0x20, 0xF1, // set 6, (iy+0x20), c + 0xDD, 0xCB, 0x20, 0xF6, // set 6, (ix+0x20) + 0xFD, 0xCB, 0x20, 0xF6, // set 6, (iy+0x20) + 0xDD, 0x21, 0x34, 0x12, // ld ix, 0x1234 + 0xFD, 0x21, 0x34, 0x12, // ld iy, 0x1234 + 0xDD, 0x09, // add ix, bc + 0xFD, 0x09, // add iy, bc + 0xDD, 0x19, // add ix, de + 0xFD, 0x19, // add iy, de + 0xDD, 0x29, // add ix, ix + 0xFD, 0x29, // add iy, iy + 0xDD, 0x39, // add ix, sp + 0xFD, 0x39, // add iy, sp + 0xDD, 0x22, 0x34, 0x12, // ld (0x1234), ix + 0xFD, 0x22, 0x34, 0x12, // ld (0x1234), iy + 0xDD, 0x2A, 0x34, 0x12, // ld ix, (0x1234) + 0xFD, 0x2A, 0x34, 0x12, // ld iy, (0x1234) + 0xDD, 0x23, // inc ix + 0xFD, 0x23, // inc iy + 0xDD, 0x2B, // dec ix + 0xFD, 0x2B, // dec iy + 0xDD, 0x24, // inc ixh + 0xFD, 0x24, // inc iyh + 0xDD, 0x2C, // inc ixl + 0xFD, 0x2C, // inc iyl + 0xDD, 0x34, 0x20, // inc (ix+0x20) + 0xFD, 0x34, 0x20, // inc (iy+0x20) + 0xDD, 0x25, // dec ixh + 0xFD, 0x25, // dec iyh + 0xDD, 0x2D, // dec ixl + 0xFD, 0x2D, // dec iyl + 0xDD, 0x35, 0x20, // dec (ix+0x20) + 0xFD, 0x35, 0x20, // dec (iy+0x20) + 0xDD, 0x26, 0x20, // ld ixh, 0x20 + 0xDD, 0x2E, 0x20, // ld ixl, 0x20 + 0xFD, 0x26, 0x20, // ld iyh, 0x20 + 0xFD, 0x2E, 0x20, // ld iyl, 0x20 + 0xDD, 0x36, 0x20, 0x20, // ld (ix+0x20), 0x20 + 0xFD, 0x36, 0x20, 0x20, // ld (iy+0x20), 0x20 + 0xDD, 0x60, // ld ixh, b + 0xDD, 0x64, // ld ixh, ixh + 0xDD, 0x65, // ld ixh, ixl + 0xFD, 0x61, // ld iyh, c + 0xFD, 0x64, // ld iyh, iyh + 0xFD, 0x65, // ld iyh, iyl + 0xDD, 0x6A, // ld ixl, d + 0xDD, 0x6C, // ld ixl, ixh + 0xDD, 0x6D, // ld ixl, ixl + 0xFD, 0x6B, // ld iyl, e + 0xFD, 0x6C, // ld iyl, iyh + 0xFD, 0x6D, // ld iyl, iyl + 0xDD, 0x72, 0x20, // ld (ix+0x20), d + 0xDD, 0x74, 0x20, // ld (ix+0x20), h + 0xDD, 0x75, 0x20, // ld (ix+0x20), l + 0xFD, 0x73, 0x20, // ld (iy+0x20), e + 0xFD, 0x74, 0x20, // ld (iy+0x20), h + 0xFD, 0x75, 0x20, // ld (iy+0x20), l + 0xDD, 0x7C, // ld a, ixh + 0xFD, 0x7C, // ld a, iyh + 0xDD, 0x7D, // ld a, ixl + 0xFD, 0x7D, // ld a, iyl + 0xDD, 0x7E, 0x20, // ld a, (ix+0x20) + 0xFD, 0x7E, 0x20, // ld a, (iy+0x20) + 0xDD, 0x66, 0x20, // ld h, (ix+0x20) + 0xDD, 0x6E, 0x20, // ld l, (ix+0x20) + 0xFD, 0x66, 0x20, // ld h, (iy+0x20) + 0xFD, 0x6E, 0x20, // ld l, (iy+0x20) + 0xDD, 0x84, // add a, ixh + 0xDD, 0x85, // add a, ixl + 0xDD, 0x86, 0x20, // add a, (ix + 0x20) + 0xFD, 0x84, // add a, iyh + 0xFD, 0x85, // add a, iyl + 0xFD, 0x86, 0x20, // add a, (iy+0x20) + 0xDD, 0x8C, // adc a, ixh + 0xDD, 0x8D, // adc a, ixl + 0xDD, 0x8E, 0x20, // adc a, (ix+0x20) + 0xFD, 0x8C, // adc a, iyh + 0xFD, 0x8D, // adc a, iyl + 0xFD, 0x8E, 0x20, // adc a, (iy+0x20) + 0xDD, 0x94, // sub ixh + 0xDD, 0x95, // sub ixl + 0xDD, 0x96, 0x20, // sub (ix+0x20) + 0xFD, 0x94, // sub iyh + 0xFD, 0x95, // sub iyl + 0xFD, 0x96, 0x20, // sub (iy+0x20) + 0xDD, 0x9C, // sbc a, ixh + 0xDD, 0x9D, // sbc a, ixl + 0xDD, 0x9E, 0x20, // sbc a, (ix+0x20) + 0xFD, 0x9C, // sbc a, iyh + 0xFD, 0x9D, // sbc a, iyl + 0xFD, 0x9E, 0x20, // sbc a, (iy+0x20) + 0xDD, 0xA4, // and ixh + 0xDD, 0xA5, // and ixl + 0xDD, 0xA6, 0x20, // and (ix+0x20) + 0xFD, 0xA4, // and iyh + 0xFD, 0xA5, // and iyl + 0xFD, 0xA6, 0x20, // and (iy+0x20) + 0xDD, 0xAC, // xor ixh + 0xDD, 0xAD, // xor ixl + 0xDD, 0xAE, 0x20, // xor (ix+0x20) + 0xFD, 0xAC, // xor iyh + 0xFD, 0xAD, // xor iyl + 0xFD, 0xAE, 0x20, // xor (iy+0x20) + 0xDD, 0xB4, // or ixh + 0xDD, 0xB5, // or ixl + 0xDD, 0xB6, 0x20, // or (ix+0x20) + 0xFD, 0xB4, // or iyh + 0xFD, 0xB5, // or iyl + 0xFD, 0xB6, 0x20, // or (iy+0x20) + 0xDD, 0xBC, // cp ixh + 0xDD, 0xBD, // cp ixl + 0xDD, 0xBE, 0x20, // cp (ix+0x20) + 0xFD, 0xBC, // cp iyh + 0xFD, 0xBD, // cp iyl + 0xFD, 0xBE, 0x20, // cp (iy+0x20) + 0xDD, 0xE1, // pop ix + 0xFD, 0xE1, // pop iy + 0xDD, 0xE9, // jp (ix) + 0xFD, 0xE9, // jp (iy) + 0xDD, 0xF9, // ld sp, ix + 0xFD, 0xF9, // ld sp, iy + 0xDD, 0xE3, // ex (sp), ix + 0xFD, 0xE3, // ex (sp), iy + 0xDD, 0xE5, // push ix + 0xFD, 0xE5 // push iy }); StringBuilder builder = new StringBuilder(); @@ -443,401 +443,401 @@ public void testDisassemble() throws InvalidInstructionException { } String result = builder.toString(); assertEquals( - "nop" + - "ex af, af'" + - "djnz 20h" + - "jr 20h" + - "jr nz, 20h" + - "jr z, 20h" + - "jr nc, 20h" + - "jr c, 20h" + - "ld bc, 1234h" + - "ld de, 1234h" + - "ld hl, 1234h" + - "ld sp, 1234h" + - "add hl, bc" + - "add hl, de" + - "add hl, hl" + - "add hl, sp" + - "ld (bc), a" + - "ld (de), a" + - "ld a, (bc)" + - "ld a, (de)" + - "ld (1234h), hl" + - "ld (1234h), a" + - "ld hl, (1234h)" + - "ld a, (1234h)" + - "inc bc" + - "inc de" + - "inc hl" + - "inc sp" + - "dec bc" + - "dec de" + - "dec hl" + - "dec sp" + - "inc b" + - "inc c" + - "inc d" + - "inc e" + - "inc h" + - "inc l" + - "inc a" + - "dec b" + - "dec c" + - "dec d" + - "dec e" + - "dec h" + - "dec l" + - "dec a" + - "ld b, 20h" + - "ld c, 20h" + - "ld d, 20h" + - "ld e, 20h" + - "ld h, 20h" + - "ld l, 20h" + - "rlca" + - "rrca" + - "rla" + - "rra" + - "daa" + - "cpl" + - "scf" + - "ccf" + - "ld b, b" + - "ld b, c" + - "ld b, d" + - "ld b, e" + - "ld b, h" + - "ld b, l" + - "ld b, a" + - "ld (hl), b" + - "ld (hl), c" + - "ld (hl), d" + - "ld (hl), e" + - "ld (hl), h" + - "ld (hl), l" + - "ld (hl), a" + - "halt" + - "add a, b" + - "add a, (hl)" + - "adc a, c" + - "adc a, (hl)" + - "sub b" + - "sub (hl)" + - "sbc a, b" + - "sbc a, (hl)" + - "and b" + - "and (hl)" + - "xor b" + - "xor (hl)" + - "or b" + - "or (hl)" + - "cp b" + - "cp (hl)" + - "ret nz" + - "ret z" + - "ret nc" + - "ret c" + - "ret po" + - "ret pe" + - "ret p" + - "ret m" + - "pop bc" + - "pop de" + - "pop hl" + - "pop af" + - "ret" + - "exx" + - "jp (hl)" + - "jp (hl)" + - "ld sp, hl" + - "jp nz, 1234h" + - "jp z, 1234h" + - "jp nc, 1234h" + - "jp c, 1234h" + - "jp po, 1234h" + - "jp pe, 1234h" + - "jp p, 1234h" + - "jp m, 1234h" + - "jp 1234h" + - "out (20h), a" + - "in a, (20h)" + - "ex (sp), hl" + - "ex de, hl" + - "di" + - "ei" + - "call nz, 1234h" + - "call z, 1234h" + - "call nc, 1234h" + - "call c, 1234h" + - "call po, 1234h" + - "call pe, 1234h" + - "call p, 1234h" + - "call m, 1234h" + - "push bc" + - "push de" + - "push hl" + - "push af" + - "call 1234h" + - "add a, 20h" + - "adc a, 20h" + - "sub 20h" + - "sbc a, 20h" + - "and 20h" + - "xor 20h" + - "or 20h" + - "cp 20h" + - "rst 00h" + - "rst 08h" + - "rst 10h" + - "rst 18h" + - "rst 20h" + - "rst 28h" + - "rst 30h" + - "rst 38h" + - "rlc b" + - "rlc (hl)" + - "rrc c" + - "rrc (hl)" + - "rl d" + - "rl (hl)" + - "rr e" + - "rr (hl)" + - "sla h" + - "sla (hl)" + - "sra l" + - "sra (hl)" + - "sll b" + - "sll (hl)" + - "srl c" + - "srl (hl)" + - "bit 5, b" + - "bit 5, (hl)" + - "res 5, c" + - "res 6, (hl)" + - "set 7, d" + - "set 7, (hl)" + - "in e, (c)" + - "in (c)" + - "out (c), h" + - "out (c), 0" + - "sbc hl, bc" + - "sbc hl, de" + - "sbc hl, hl" + - "sbc hl, sp" + - "adc hl, bc" + - "adc hl, de" + - "adc hl, hl" + - "adc hl, sp" + - "ld (1234h), bc" + - "ld (1234h), de" + - "ld (1234h), hl" + - "ld (1234h), sp" + - "ld bc, (1234h)" + - "ld de, (1234h)" + - "ld hl, (1234h)" + - "ld sp, (1234h)" + - "neg" + - "retn" + - "reti" + - "im 0" + - "im 0/1" + - "im 1" + - "im 2" + - "ld i, a" + - "ld r, a" + - "ld a, i" + - "ld a, r" + - "rrd" + - "rld" + - "ldi" + - "ldd" + - "ldir" + - "lddr" + - "cpi" + - "cpd" + - "cpir" + - "cpdr" + - "ini" + - "ind" + - "inir" + - "indr" + - "outi" + - "outd" + - "otir" + - "otdr" + - "rlc (ix+20h), b" + - "rlc (iy+20h), b" + - "rlc (ix+20h)" + - "rlc (iy+20h)" + - "rrc (ix+20h), c" + - "rrc (iy+20h), c" + - "rrc (ix+20h)" + - "rrc (iy+20h)" + - "rl (ix+20h), d" + - "rl (iy+20h), d" + - "rl (ix+20h)" + - "rl (iy+20h)" + - "rr (ix+20h), e" + - "rr (iy+20h), e" + - "rr (ix+20h)" + - "rr (iy+20h)" + - "sla (ix+20h), h" + - "sla (iy+20h), h" + - "sla (ix+20h)" + - "sla (iy+20h)" + - "sra (ix+20h), l" + - "sra (iy+20h), l" + - "sra (ix+20h)" + - "sra (iy+20h)" + - "sll (ix+20h), b" + - "sll (iy+20h), b" + - "sll (ix+20h)" + - "sll (iy+20h)" + - "srl (ix+20h), c" + - "srl (iy+20h), c" + - "srl (ix+20h)" + - "srl (iy+20h)" + - "bit 3, (ix+20h)" + - "bit 3, (iy+20h)" + - "res 5, (ix+20h), b" + - "res 5, (iy+20h), b" + - "res 5, (ix+20h)" + - "res 5, (iy+20h)" + - "set 6, (ix+20h), c" + - "set 6, (iy+20h), c" + - "set 6, (ix+20h)" + - "set 6, (iy+20h)" + - "ld ix, 1234h" + - "ld iy, 1234h" + - "add ix, bc" + - "add iy, bc" + - "add ix, de" + - "add iy, de" + - "add ix, ix" + - "add iy, iy" + - "add ix, sp" + - "add iy, sp" + - "ld (1234h), ix" + - "ld (1234h), iy" + - "ld ix, (1234h)" + - "ld iy, (1234h)" + - "inc ix" + - "inc iy" + - "dec ix" + - "dec iy" + - "inc ixh" + - "inc iyh" + - "inc ixl" + - "inc iyl" + - "inc (ix+20h)" + - "inc (iy+20h)" + - "dec ixh" + - "dec iyh" + - "dec ixl" + - "dec iyl" + - "dec (ix+20h)" + - "dec (iy+20h)" + - "ld ixh, 20h" + - "ld ixl, 20h" + - "ld iyh, 20h" + - "ld iyl, 20h" + - "ld (ix+20h), 20h" + - "ld (iy+20h), 20h" + - "ld ixh, b" + - "ld ixh, ixh" + - "ld ixh, ixl" + - "ld iyh, c" + - "ld iyh, iyh" + - "ld iyh, iyl" + - "ld ixl, d" + - "ld ixl, ixh" + - "ld ixl, ixl" + - "ld iyl, e" + - "ld iyl, iyh" + - "ld iyl, iyl" + - "ld (ix+20h), d" + - "ld (ix+20h), h" + - "ld (ix+20h), l" + - "ld (iy+20h), e" + - "ld (iy+20h), h" + - "ld (iy+20h), l" + - "ld a, ixh" + - "ld a, iyh" + - "ld a, ixl" + - "ld a, iyl" + - "ld a, (ix+20h)" + - "ld a, (iy+20h)" + - "ld h, (ix+20h)" + - "ld l, (ix+20h)" + - "ld h, (iy+20h)" + - "ld l, (iy+20h)" + - "add a, ixh" + - "add a, ixl" + - "add a, (ix+20h)" + - "add a, iyh" + - "add a, iyl" + - "add a, (iy+20h)" + - "adc a, ixh" + - "adc a, ixl" + - "adc a, (ix+20h)" + - "adc a, iyh" + - "adc a, iyl" + - "adc a, (iy+20h)" + - "sub ixh" + - "sub ixl" + - "sub (ix+20h)" + - "sub iyh" + - "sub iyl" + - "sub (iy+20h)" + - "sbc a, ixh" + - "sbc a, ixl" + - "sbc a, (ix+20h)" + - "sbc a, iyh" + - "sbc a, iyl" + - "sbc a, (iy+20h)" + - "and ixh" + - "and ixl" + - "and (ix+20h)" + - "and iyh" + - "and iyl" + - "and (iy+20h)" + - "xor ixh" + - "xor ixl" + - "xor (ix+20h)" + - "xor iyh" + - "xor iyl" + - "xor (iy+20h)" + - "or ixh" + - "or ixl" + - "or (ix+20h)" + - "or iyh" + - "or iyl" + - "or (iy+20h)" + - "cp ixh" + - "cp ixl" + - "cp (ix+20h)" + - "cp iyh" + - "cp iyl" + - "cp (iy+20h)" + - "pop ix" + - "pop iy" + - "jp (ix)" + - "jp (iy)" + - "ld sp, ix" + - "ld sp, iy" + - "ex (sp), ix" + - "ex (sp), iy" + - "push ix" + - "push iy", - result + "nop" + + "ex af, af'" + + "djnz 20h" + + "jr 20h" + + "jr nz, 20h" + + "jr z, 20h" + + "jr nc, 20h" + + "jr c, 20h" + + "ld bc, 1234h" + + "ld de, 1234h" + + "ld hl, 1234h" + + "ld sp, 1234h" + + "add hl, bc" + + "add hl, de" + + "add hl, hl" + + "add hl, sp" + + "ld (bc), a" + + "ld (de), a" + + "ld a, (bc)" + + "ld a, (de)" + + "ld (1234h), hl" + + "ld (1234h), a" + + "ld hl, (1234h)" + + "ld a, (1234h)" + + "inc bc" + + "inc de" + + "inc hl" + + "inc sp" + + "dec bc" + + "dec de" + + "dec hl" + + "dec sp" + + "inc b" + + "inc c" + + "inc d" + + "inc e" + + "inc h" + + "inc l" + + "inc a" + + "dec b" + + "dec c" + + "dec d" + + "dec e" + + "dec h" + + "dec l" + + "dec a" + + "ld b, 20h" + + "ld c, 20h" + + "ld d, 20h" + + "ld e, 20h" + + "ld h, 20h" + + "ld l, 20h" + + "rlca" + + "rrca" + + "rla" + + "rra" + + "daa" + + "cpl" + + "scf" + + "ccf" + + "ld b, b" + + "ld b, c" + + "ld b, d" + + "ld b, e" + + "ld b, h" + + "ld b, l" + + "ld b, a" + + "ld (hl), b" + + "ld (hl), c" + + "ld (hl), d" + + "ld (hl), e" + + "ld (hl), h" + + "ld (hl), l" + + "ld (hl), a" + + "halt" + + "add a, b" + + "add a, (hl)" + + "adc a, c" + + "adc a, (hl)" + + "sub b" + + "sub (hl)" + + "sbc a, b" + + "sbc a, (hl)" + + "and b" + + "and (hl)" + + "xor b" + + "xor (hl)" + + "or b" + + "or (hl)" + + "cp b" + + "cp (hl)" + + "ret nz" + + "ret z" + + "ret nc" + + "ret c" + + "ret po" + + "ret pe" + + "ret p" + + "ret m" + + "pop bc" + + "pop de" + + "pop hl" + + "pop af" + + "ret" + + "exx" + + "jp (hl)" + + "jp (hl)" + + "ld sp, hl" + + "jp nz, 1234h" + + "jp z, 1234h" + + "jp nc, 1234h" + + "jp c, 1234h" + + "jp po, 1234h" + + "jp pe, 1234h" + + "jp p, 1234h" + + "jp m, 1234h" + + "jp 1234h" + + "out (20h), a" + + "in a, (20h)" + + "ex (sp), hl" + + "ex de, hl" + + "di" + + "ei" + + "call nz, 1234h" + + "call z, 1234h" + + "call nc, 1234h" + + "call c, 1234h" + + "call po, 1234h" + + "call pe, 1234h" + + "call p, 1234h" + + "call m, 1234h" + + "push bc" + + "push de" + + "push hl" + + "push af" + + "call 1234h" + + "add a, 20h" + + "adc a, 20h" + + "sub 20h" + + "sbc a, 20h" + + "and 20h" + + "xor 20h" + + "or 20h" + + "cp 20h" + + "rst 00h" + + "rst 08h" + + "rst 10h" + + "rst 18h" + + "rst 20h" + + "rst 28h" + + "rst 30h" + + "rst 38h" + + "rlc b" + + "rlc (hl)" + + "rrc c" + + "rrc (hl)" + + "rl d" + + "rl (hl)" + + "rr e" + + "rr (hl)" + + "sla h" + + "sla (hl)" + + "sra l" + + "sra (hl)" + + "sll b" + + "sll (hl)" + + "srl c" + + "srl (hl)" + + "bit 5, b" + + "bit 5, (hl)" + + "res 5, c" + + "res 6, (hl)" + + "set 7, d" + + "set 7, (hl)" + + "in e, (c)" + + "in (c)" + + "out (c), h" + + "out (c), 0" + + "sbc hl, bc" + + "sbc hl, de" + + "sbc hl, hl" + + "sbc hl, sp" + + "adc hl, bc" + + "adc hl, de" + + "adc hl, hl" + + "adc hl, sp" + + "ld (1234h), bc" + + "ld (1234h), de" + + "ld (1234h), hl" + + "ld (1234h), sp" + + "ld bc, (1234h)" + + "ld de, (1234h)" + + "ld hl, (1234h)" + + "ld sp, (1234h)" + + "neg" + + "retn" + + "reti" + + "im 0" + + "im 0/1" + + "im 1" + + "im 2" + + "ld i, a" + + "ld r, a" + + "ld a, i" + + "ld a, r" + + "rrd" + + "rld" + + "ldi" + + "ldd" + + "ldir" + + "lddr" + + "cpi" + + "cpd" + + "cpir" + + "cpdr" + + "ini" + + "ind" + + "inir" + + "indr" + + "outi" + + "outd" + + "otir" + + "otdr" + + "rlc (ix+20h), b" + + "rlc (iy+20h), b" + + "rlc (ix+20h)" + + "rlc (iy+20h)" + + "rrc (ix+20h), c" + + "rrc (iy+20h), c" + + "rrc (ix+20h)" + + "rrc (iy+20h)" + + "rl (ix+20h), d" + + "rl (iy+20h), d" + + "rl (ix+20h)" + + "rl (iy+20h)" + + "rr (ix+20h), e" + + "rr (iy+20h), e" + + "rr (ix+20h)" + + "rr (iy+20h)" + + "sla (ix+20h), h" + + "sla (iy+20h), h" + + "sla (ix+20h)" + + "sla (iy+20h)" + + "sra (ix+20h), l" + + "sra (iy+20h), l" + + "sra (ix+20h)" + + "sra (iy+20h)" + + "sll (ix+20h), b" + + "sll (iy+20h), b" + + "sll (ix+20h)" + + "sll (iy+20h)" + + "srl (ix+20h), c" + + "srl (iy+20h), c" + + "srl (ix+20h)" + + "srl (iy+20h)" + + "bit 3, (ix+20h)" + + "bit 3, (iy+20h)" + + "res 5, (ix+20h), b" + + "res 5, (iy+20h), b" + + "res 5, (ix+20h)" + + "res 5, (iy+20h)" + + "set 6, (ix+20h), c" + + "set 6, (iy+20h), c" + + "set 6, (ix+20h)" + + "set 6, (iy+20h)" + + "ld ix, 1234h" + + "ld iy, 1234h" + + "add ix, bc" + + "add iy, bc" + + "add ix, de" + + "add iy, de" + + "add ix, ix" + + "add iy, iy" + + "add ix, sp" + + "add iy, sp" + + "ld (1234h), ix" + + "ld (1234h), iy" + + "ld ix, (1234h)" + + "ld iy, (1234h)" + + "inc ix" + + "inc iy" + + "dec ix" + + "dec iy" + + "inc ixh" + + "inc iyh" + + "inc ixl" + + "inc iyl" + + "inc (ix+20h)" + + "inc (iy+20h)" + + "dec ixh" + + "dec iyh" + + "dec ixl" + + "dec iyl" + + "dec (ix+20h)" + + "dec (iy+20h)" + + "ld ixh, 20h" + + "ld ixl, 20h" + + "ld iyh, 20h" + + "ld iyl, 20h" + + "ld (ix+20h), 20h" + + "ld (iy+20h), 20h" + + "ld ixh, b" + + "ld ixh, ixh" + + "ld ixh, ixl" + + "ld iyh, c" + + "ld iyh, iyh" + + "ld iyh, iyl" + + "ld ixl, d" + + "ld ixl, ixh" + + "ld ixl, ixl" + + "ld iyl, e" + + "ld iyl, iyh" + + "ld iyl, iyl" + + "ld (ix+20h), d" + + "ld (ix+20h), h" + + "ld (ix+20h), l" + + "ld (iy+20h), e" + + "ld (iy+20h), h" + + "ld (iy+20h), l" + + "ld a, ixh" + + "ld a, iyh" + + "ld a, ixl" + + "ld a, iyl" + + "ld a, (ix+20h)" + + "ld a, (iy+20h)" + + "ld h, (ix+20h)" + + "ld l, (ix+20h)" + + "ld h, (iy+20h)" + + "ld l, (iy+20h)" + + "add a, ixh" + + "add a, ixl" + + "add a, (ix+20h)" + + "add a, iyh" + + "add a, iyl" + + "add a, (iy+20h)" + + "adc a, ixh" + + "adc a, ixl" + + "adc a, (ix+20h)" + + "adc a, iyh" + + "adc a, iyl" + + "adc a, (iy+20h)" + + "sub ixh" + + "sub ixl" + + "sub (ix+20h)" + + "sub iyh" + + "sub iyl" + + "sub (iy+20h)" + + "sbc a, ixh" + + "sbc a, ixl" + + "sbc a, (ix+20h)" + + "sbc a, iyh" + + "sbc a, iyl" + + "sbc a, (iy+20h)" + + "and ixh" + + "and ixl" + + "and (ix+20h)" + + "and iyh" + + "and iyl" + + "and (iy+20h)" + + "xor ixh" + + "xor ixl" + + "xor (ix+20h)" + + "xor iyh" + + "xor iyl" + + "xor (iy+20h)" + + "or ixh" + + "or ixl" + + "or (ix+20h)" + + "or iyh" + + "or iyl" + + "or (iy+20h)" + + "cp ixh" + + "cp ixl" + + "cp (ix+20h)" + + "cp iyh" + + "cp iyl" + + "cp (iy+20h)" + + "pop ix" + + "pop iy" + + "jp (ix)" + + "jp (iy)" + + "ld sp, ix" + + "ld sp, iy" + + "ex (sp), ix" + + "ex (sp), iy" + + "push ix" + + "push iy", + result ); } @Test public void testDecoder() throws InvalidInstructionException { - memoryStub.setMemory(new short[] { - 0xED, 0xB0 + memoryStub.setMemory(new short[]{ + 0xED, 0xB0 }); DecodedInstruction instr = decoder.decode(0); assertEquals(2, instr.getLength()); diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java index 7da1a6583..9274625f2 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorTablesGeneration.java @@ -34,8 +34,8 @@ public void generateTableSub() { int flagZ = (sum == 0 ? FLAG_Z : 0); int flags = flagZ | (sum & 0x80) | FLAG_N; table.append("0x") - .append(Integer.toHexString(flags)) - .append(", "); + .append(Integer.toHexString(flags)) + .append(", "); } table.append("};\n"); System.out.println(table); @@ -52,8 +52,8 @@ public void generateTableCHP() { int flagP = (carryIns == 0) ? 0 : FLAG_PV; int flags = flagC | flagH | flagP; table.append("0x") - .append(Integer.toHexString(flags)) - .append(", "); + .append(Integer.toHexString(flags)) + .append(", "); } table.append("};\n"); System.out.println(table); @@ -68,8 +68,8 @@ public void generateTableSZ() { int flagZ = (sum == 0 ? FLAG_Z : 0); int flags = flagZ | (sum & 0x80); table.append("0x") - .append(Integer.toHexString(flags)) - .append(", "); + .append(Integer.toHexString(flags)) + .append(", "); if (i++ == 15) { table.append("\n "); i = 0; @@ -91,8 +91,8 @@ public void generateTableHP() { int flagP = (carryIns == 0) ? 0 : FLAG_PV; int flags = flagH | flagP; table.append("0x") - .append(Integer.toHexString(flags)) - .append(", "); + .append(Integer.toHexString(flags)) + .append(", "); if (i++ == 15) { table.append("\n "); i = 0; @@ -110,8 +110,8 @@ public void generateTableXY() { for (int sum = 0; sum <= 0xFF; sum++) { int flagXY = sum & (FLAG_X | FLAG_Y); table.append("0x") - .append(Integer.toHexString(flagXY)) - .append(", "); + .append(Integer.toHexString(flagXY)) + .append(", "); if (i++ == 15) { table.append("\n "); i = 0; @@ -129,8 +129,8 @@ public void generateRrcaTable() { for (int value = 0; value <= 0xFF; value++) { int rrca = ((value >>> 1) | (value << 7)) & 0xFF; table.append("0x") - .append(Integer.toHexString(rrca)) - .append(", "); + .append(Integer.toHexString(rrca)) + .append(", "); if (i++ == 15) { table.append("\n "); i = 0; @@ -148,8 +148,8 @@ public void generateRlcaTable() { for (int value = 0; value <= 0xFF; value++) { int rrca = ((value << 1) | (value >>> 7)) & 0xFF; table.append("0x") - .append(Integer.toHexString(rrca)) - .append(", "); + .append(Integer.toHexString(rrca)) + .append(", "); if (i++ == 15) { table.append("\n "); i = 0; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeByteDevice.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeByteDevice.java index 5412c1b9d..022fc93fa 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeByteDevice.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/FakeByteDevice.java @@ -23,14 +23,14 @@ public class FakeByteDevice implements DeviceContext { private byte value; - public void setValue(byte value) { - this.value = value; - } - public byte getValue() { return value; } + public void setValue(byte value) { + this.value = value; + } + @Override public Byte readData() { return (byte) (value & 0xFF); diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java index 4366cb3a3..d3ea5b353 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java @@ -34,12 +34,12 @@ public class IOTest extends InstructionsTest { @Test public void testIN_A_REF_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsDeviceAndSecondIsPort() - .secondIsRegister(REG_A) - .verifyRegister(REG_A, context -> context.first & 0xFF); + .firstIsDeviceAndSecondIsPort() + .secondIsRegister(REG_A) + .verifyRegister(REG_A, context -> context.first & 0xFF); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xDB) + test.runWithSecondOperand(0xDB) ); } @@ -48,21 +48,21 @@ public void testIN_R_REF_C() { Function, Integer> operation = context -> context.first & 0xFF; ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsDeviceAndSecondIsPort() - .secondIsRegister(REG_C) - .verifyFlags(new FlagsCheckImpl().sign().zero().parity().halfCarryIsReset().subtractionIsReset(), - operation) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsDeviceAndSecondIsPort() + .secondIsRegister(REG_C) + .verifyFlags(new FlagsCheckImpl().sign().zero().parity().halfCarryIsReset().subtractionIsReset(), + operation) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome8bitBinary( - test.verifyRegister(REG_A, operation).runWithSecondOperand(0xED, 0x78), - test.verifyRegister(REG_B, operation).runWithSecondOperand(0xED, 0x40), - test.verifyRegister(REG_C, operation).runWithSecondOperand(0xED, 0x48), - test.verifyRegister(REG_D, operation).runWithSecondOperand(0xED, 0x50), - test.verifyRegister(REG_E, operation).runWithSecondOperand(0xED, 0x58), - test.verifyRegister(REG_H, operation).runWithSecondOperand(0xED, 0x60), - test.verifyRegister(REG_L, operation).runWithSecondOperand(0xED, 0x68) + test.verifyRegister(REG_A, operation).runWithSecondOperand(0xED, 0x78), + test.verifyRegister(REG_B, operation).runWithSecondOperand(0xED, 0x40), + test.verifyRegister(REG_C, operation).runWithSecondOperand(0xED, 0x48), + test.verifyRegister(REG_D, operation).runWithSecondOperand(0xED, 0x50), + test.verifyRegister(REG_E, operation).runWithSecondOperand(0xED, 0x58), + test.verifyRegister(REG_H, operation).runWithSecondOperand(0xED, 0x60), + test.verifyRegister(REG_L, operation).runWithSecondOperand(0xED, 0x68) ); } @@ -71,252 +71,252 @@ public void testIN_REF_C() { Function, Integer> operation = context -> context.first & 0xFF; ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsDeviceAndSecondIsPort() - .secondIsRegister(REG_C) - .verifyFlags(new FlagsCheckImpl().sign().zero().parity().halfCarryIsReset().subtractionIsReset(), - operation) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsDeviceAndSecondIsPort() + .secondIsRegister(REG_C) + .verifyFlags(new FlagsCheckImpl().sign().zero().parity().halfCarryIsReset().subtractionIsReset(), + operation) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xED, 0x70) + test.runWithSecondOperand(0xED, 0x70) ); } @Test public void testINI() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisDeviceAndFirst8LSBIsPort() - .first8LSBisRegister(REG_C) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8MSBisRegister(REG_B) - .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) - .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() - .carryIsPreserved() - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) - ); + .first8MSBisDeviceAndFirst8LSBIsPort() + .first8LSBisRegister(REG_C) + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8MSBisRegister(REG_B) + .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) + .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() + .carryIsPreserved() + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) + ); Generator.forSome16bitBinary(2, - test.run(0xED, 0xA2) + test.run(0xED, 0xA2) ); } @Test public void testINIR() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisDeviceAndFirst8LSBIsPort() - .first8LSBisRegister(REG_C) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8MSBisRegister(REG_B) - .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) - .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .zeroIsSet() - .subtractionIsSet() - .carryIsPreserved() - ) - .verifyPC(context -> { - if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { - return context.PC; - } - return context.PC + 2; - }); + .first8MSBisDeviceAndFirst8LSBIsPort() + .first8LSBisRegister(REG_C) + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8MSBisRegister(REG_B) + .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) + .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .zeroIsSet() + .subtractionIsSet() + .carryIsPreserved() + ) + .verifyPC(context -> { + if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { + return context.PC; + } + return context.PC + 2; + }); Generator.forSome16bitBinary(2, - test.run(0xED, 0xB2) + test.run(0xED, 0xB2) ); } @Test public void testIND() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisDeviceAndFirst8LSBIsPort() - .first8LSBisRegister(REG_C) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8MSBisRegister(REG_B) - .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) - .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() - .subtractionIsSet() - .carryIsPreserved() - ); + .first8MSBisDeviceAndFirst8LSBIsPort() + .first8LSBisRegister(REG_C) + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8MSBisRegister(REG_B) + .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) + .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() + .subtractionIsSet() + .carryIsPreserved() + ); Generator.forSome16bitBinary(2, - test.run(0xED, 0xAA) + test.run(0xED, 0xAA) ); } @Test public void testINDR() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisDeviceAndFirst8LSBIsPort() - .first8LSBisRegister(REG_C) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8MSBisRegister(REG_B) - .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) - .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .zeroIsSet() - .subtractionIsSet() - .carryIsPreserved()) - .verifyPC(context -> { - if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { - return context.PC; - } - return context.PC + 2; - }); + .first8MSBisDeviceAndFirst8LSBIsPort() + .first8LSBisRegister(REG_C) + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8MSBisRegister(REG_B) + .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) + .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .zeroIsSet() + .subtractionIsSet() + .carryIsPreserved()) + .verifyPC(context -> { + if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { + return context.PC; + } + return context.PC + 2; + }); Generator.forSome16bitBinary(2, - test.run(0xED, 0xBA) + test.run(0xED, 0xBA) ); } @Test public void testOUT_REF_N_A() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyDeviceWhenSecondIsPort(context -> context.first & 0xFF); + .firstIsRegister(REG_A) + .verifyDeviceWhenSecondIsPort(context -> context.first & 0xFF); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xD3) + test.runWithSecondOperand(0xD3) ); } @Test public void testOUT_REF_C_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .secondIsRegister(REG_C) - .verifyDeviceWhenSecondIsPort(context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .secondIsRegister(REG_C) + .verifyDeviceWhenSecondIsPort(context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( - test.firstIsRegister(REG_C).run(0xED, 0x49) + test.firstIsRegister(REG_C).run(0xED, 0x49) ); Generator.forSome8bitBinary( - test.firstIsRegister(REG_B).run(0xED, 0x41), - test.firstIsRegister(REG_D).run(0xED, 0x51), - test.firstIsRegister(REG_E).run(0xED, 0x59), - test.firstIsRegister(REG_H).run(0xED, 0x61), - test.firstIsRegister(REG_L).run(0xED, 0x69), - test.firstIsRegister(REG_A).run(0xED, 0x79) + test.firstIsRegister(REG_B).run(0xED, 0x41), + test.firstIsRegister(REG_D).run(0xED, 0x51), + test.firstIsRegister(REG_E).run(0xED, 0x59), + test.firstIsRegister(REG_H).run(0xED, 0x61), + test.firstIsRegister(REG_L).run(0xED, 0x69), + test.firstIsRegister(REG_A).run(0xED, 0x79) ); } @Test public void testOUT_REF_C_0() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .secondIsRegister(REG_C) - .verifyDeviceWhenSecondIsPort(context -> 0) - .keepCurrentInjectorsAfterRun(); + .secondIsRegister(REG_C) + .verifyDeviceWhenSecondIsPort(context -> 0) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( - test.firstIsRegister(REG_C).run(0xED, 0x71) + test.firstIsRegister(REG_C).run(0xED, 0x71) ); } @Test public void testOUTI() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8LSBisRegister(REG_C) - .first8MSBisRegister(REG_B) - .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) - .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) - ); + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8LSBisRegister(REG_C) + .first8MSBisRegister(REG_B) + .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) + .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) + ); Generator.forSome16bitBinary(2, - test.run(0xED, 0xA3) + test.run(0xED, 0xA3) ); } @Test public void testOTIR() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8LSBisRegister(REG_C) - .first8MSBisRegister(REG_B) - .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) - .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) - ) - .verifyPC(context -> { - if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { - return context.PC; - } - return context.PC + 2; - }); + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8LSBisRegister(REG_C) + .first8MSBisRegister(REG_B) + .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) + .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) + ) + .verifyPC(context -> { + if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { + return context.PC; + } + return context.PC + 2; + }); Generator.forSome16bitBinary(2, - test.run(0xED, 0xB3) + test.run(0xED, 0xB3) ); } @Test public void testOUTD() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8LSBisRegister(REG_C) - .first8MSBisRegister(REG_B) - .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) - .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() - .subtractionIsSet() - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) - ); + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8LSBisRegister(REG_C) + .first8MSBisRegister(REG_B) + .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) + .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() + .subtractionIsSet() + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) + ); Generator.forSome16bitBinary(2, - test.run(0xED, 0xAB) + test.run(0xED, 0xAB) ); } @Test public void testOTDR() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8LSBisRegister(REG_C) - .first8MSBisRegister(REG_B) - .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) - .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) - ) - .verifyPC(context -> { - if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { - return context.PC; - } - return context.PC + 2; - }); + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8LSBisRegister(REG_C) + .first8MSBisRegister(REG_B) + .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) + .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) + .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) + ) + .verifyPC(context -> { + if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { + return context.PC; + } + return context.PC + 2; + }); Generator.forSome16bitBinary(2, - test.run(0xED, 0xBB) + test.run(0xED, 0xBB) ); } } - + diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java index b054b5a3f..28439b7c2 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java @@ -23,8 +23,8 @@ import net.emustudio.emulib.plugins.memory.MemoryContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.helpers.NumberUtils; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.cpu.intel8080.api.Context8080; import net.emustudio.plugins.cpu.zilogZ80.suite.CpuRunnerImpl; import net.emustudio.plugins.cpu.zilogZ80.suite.CpuVerifierImpl; @@ -40,17 +40,15 @@ import static org.junit.Assert.assertTrue; public class InstructionsTest { - private static final long PLUGIN_ID = 0L; - static final int REG_PAIR_BC = 0; static final int REG_PAIR_DE = 1; static final int REG_PAIR_HL = 2; static final int REG_SP = 3; - - private CpuImpl cpu; + private static final long PLUGIN_ID = 0L; + private final List devices = new ArrayList<>(); CpuRunnerImpl cpuRunnerImpl; CpuVerifierImpl cpuVerifierImpl; - private final List devices = new ArrayList<>(); + private CpuImpl cpu; @SuppressWarnings("unchecked") @Before diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java index 966dcfc2e..7c0ecaabc 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java @@ -36,40 +36,40 @@ public class LogicTest extends InstructionsTest { @Test public void testAND_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> context.first & context.second) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()) - .keepCurrentInjectorsAfterRun(); + .setFlags(0xFF) + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> context.first & context.second) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( - test.run(0xA7) + test.run(0xA7) ); Generator.forSome8bitBinary( - test.secondIsRegister(REG_B).run(0xA0), - test.secondIsRegister(REG_C).run(0xA1), - test.secondIsRegister(REG_D).run(0xA2), - test.secondIsRegister(REG_E).run(0xA3), - test.secondIsRegister(REG_H).run(0xA4), - test.secondIsRegister(REG_L).run(0xA5), - test.secondIsMemoryByteAt(0x0320).setPair(REG_PAIR_HL, 0x0320).run(0xA6) + test.secondIsRegister(REG_B).run(0xA0), + test.secondIsRegister(REG_C).run(0xA1), + test.secondIsRegister(REG_D).run(0xA2), + test.secondIsRegister(REG_E).run(0xA3), + test.secondIsRegister(REG_H).run(0xA4), + test.secondIsRegister(REG_L).run(0xA5), + test.secondIsMemoryByteAt(0x0320).setPair(REG_PAIR_HL, 0x0320).run(0xA6) ); } @Test public void testAND_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> context.first & context.second) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()) - .keepCurrentInjectorsAfterRun(); + .setFlags(0xFF) + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> context.first & context.second) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xE6) + test.runWithSecondOperand(0xE6) ); } @@ -78,17 +78,17 @@ public void testOR_R() { ByteTestBuilder test = getLogicTestBuilder(context -> context.first | context.second); Generator.forSome8bitBinaryWhichEqual( - test.run(0xB7) + test.run(0xB7) ); Generator.forSome8bitBinary( - test.secondIsRegister(REG_B).run(0xB0), - test.secondIsRegister(REG_C).run(0xB1), - test.secondIsRegister(REG_D).run(0xB2), - test.secondIsRegister(REG_E).run(0xB3), - test.secondIsRegister(REG_H).run(0xB4), - test.secondIsRegister(REG_L).run(0xB5), - test.secondIsMemoryByteAt(0x0320).setPair(REG_PAIR_HL, 0x0320).run(0xB6) + test.secondIsRegister(REG_B).run(0xB0), + test.secondIsRegister(REG_C).run(0xB1), + test.secondIsRegister(REG_D).run(0xB2), + test.secondIsRegister(REG_E).run(0xB3), + test.secondIsRegister(REG_H).run(0xB4), + test.secondIsRegister(REG_L).run(0xB5), + test.secondIsMemoryByteAt(0x0320).setPair(REG_PAIR_HL, 0x0320).run(0xB6) ); } @@ -97,7 +97,7 @@ public void testOR_N() { ByteTestBuilder test = getLogicTestBuilder(context -> context.first | context.second); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xF6) + test.runWithSecondOperand(0xF6) ); } @@ -106,17 +106,17 @@ public void testXOR_R() { ByteTestBuilder test = getLogicTestBuilder(context -> context.first ^ context.second); Generator.forSome8bitBinaryWhichEqual( - test.run(0xAF) + test.run(0xAF) ); Generator.forSome8bitBinary( - test.secondIsRegister(REG_B).run(0xA8), - test.secondIsRegister(REG_C).run(0xA9), - test.secondIsRegister(REG_D).run(0xAA), - test.secondIsRegister(REG_E).run(0xAB), - test.secondIsRegister(REG_H).run(0xAC), - test.secondIsRegister(REG_L).run(0xAD), - test.secondIsMemoryByteAt(0x0320).setPair(REG_PAIR_HL, 0x0320).run(0xAE) + test.secondIsRegister(REG_B).run(0xA8), + test.secondIsRegister(REG_C).run(0xA9), + test.secondIsRegister(REG_D).run(0xAA), + test.secondIsRegister(REG_E).run(0xAB), + test.secondIsRegister(REG_H).run(0xAC), + test.secondIsRegister(REG_L).run(0xAD), + test.secondIsMemoryByteAt(0x0320).setPair(REG_PAIR_HL, 0x0320).run(0xAE) ); } @@ -125,117 +125,117 @@ public void testXOR_N() { ByteTestBuilder test = getLogicTestBuilder(context -> context.first ^ context.second); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xEE) + test.runWithSecondOperand(0xEE) ); } @Test public void testCP_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow() - .overflowSub().subtractionIsSet(), - context -> (context.first & 0xFF) + (((~context.second) + 1) & 0xFF)) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> context.first & 0xFF) + .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow() + .overflowSub().subtractionIsSet(), + context -> (context.first & 0xFF) + (((~context.second) + 1) & 0xFF)) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( - test.run(0xBF) + test.run(0xBF) ); Generator.forSome8bitBinary( - test.secondIsRegister(REG_B).run(0xB8), - test.secondIsRegister(REG_C).run(0xB9), - test.secondIsRegister(REG_D).run(0xBA), - test.secondIsRegister(REG_E).run(0xBB), - test.secondIsRegister(REG_H).run(0xBC), - test.secondIsRegister(REG_L).run(0xBD), - test.setPair(REG_PAIR_HL, 0x0320).secondIsMemoryByteAt(0x0320).run(0xBE) + test.secondIsRegister(REG_B).run(0xB8), + test.secondIsRegister(REG_C).run(0xB9), + test.secondIsRegister(REG_D).run(0xBA), + test.secondIsRegister(REG_E).run(0xBB), + test.secondIsRegister(REG_H).run(0xBC), + test.secondIsRegister(REG_L).run(0xBD), + test.setPair(REG_PAIR_HL, 0x0320).secondIsMemoryByteAt(0x0320).run(0xBE) ); } @Test public void testCP_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet(), - context -> (context.first & 0xFF) - (byte) (context.second & 0xFF)); + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> context.first & 0xFF) + .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet(), + context -> (context.first & 0xFF) - (byte) (context.second & 0xFF)); Generator.forSome8bitBinary( - test.runWithSecondOperand(0xFE) + test.runWithSecondOperand(0xFE) ); } @Test public void testDAA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .secondIsFlags() - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(REG_A) + .secondIsFlags() + .keepCurrentInjectorsAfterRun(); int[][] params = new int[][]{ - new int[]{0xAA, 0x7D, 0x10, 0x11}, - new int[]{0xAA, 0x7E, 0x44, 0x7}, - new int[]{0xAA, 0x7F, 0x44, 0x7}, - new int[]{0xAD, 0x7E, 0x47, 0x7}, - new int[]{0xAD, 0x7F, 0x47, 0x7}, - new int[]{0xAC, 0x6C, 0x12, 0x15}, - new int[]{0xA6, 0x7E, 0x40, 0x3}, - new int[]{0xA6, 0x7F, 0x40, 0x3}, - new int[]{0xA1, 0x6C, 0x1, 0x1}, - new int[]{0xA1, 0x6D, 0x1, 0x1}, - new int[]{0xB8, 0x6F, 0x58, 0xB}, - new int[]{0xB8, 0x7C, 0x1E, 0xD}, - new int[]{0xB8, 0x7D, 0x1E, 0xD}, - new int[]{0xB8, 0x7E, 0x52, 0x3}, - new int[]{0x95, 0xE4, 0x95, 0x84}, - new int[]{0x95, 0xE5, 0xF5, 0xA5}, - new int[]{0x95, 0xE6, 0x95, 0x86}, - new int[]{0x95, 0xE7, 0x35, 0x27}, - new int[]{0x28, 0xE9, 0x88, 0x8D}, - new int[]{0x28, 0xEA, 0x28, 0x2E}, - new int[]{0x28, 0xEB, 0xC8, 0x8B}, - new int[]{0x28, 0xF8, 0x2E, 0x2C}, - new int[]{0x53, 0xF8, 0x59, 0xC}, - new int[]{0x53, 0xF9, 0xB9, 0xA9}, - new int[]{0x53, 0xFA, 0x4D, 0x1E}, - new int[]{0x53, 0xFB, 0xED, 0xBF}, - new int[]{0xEF, 0xEF, 0x89, 0x8B}, - new int[]{0xEF, 0xFC, 0x55, 0x15}, - new int[]{0xEF, 0xFD, 0x55, 0x15}, - new int[]{0xEF, 0xFE, 0x89, 0x8B}, - new int[]{0x20, 0xFD, 0x86, 0x81}, - new int[]{0x20, 0xFE, 0x1A, 0x1A}, - new int[]{0x20, 0xFF, 0xBA, 0xBB}, - new int[]{0x1C, 0xEF, 0xB6, 0xA3}, - new int[]{0x1C, 0xFC, 0x22, 0x34}, - new int[]{0x1C, 0xFD, 0x82, 0x95}, - new int[]{0x16, 0xFF, 0xB0, 0xA3}, - new int[]{0x11, 0xEC, 0x11, 0x4}, - new int[]{0x11, 0xED, 0x71, 0x25}, - new int[]{0x11, 0xEE, 0x11, 0x6}, - new int[]{0x55, 0xEC, 0x55, 0x4}, - new int[]{0x55, 0xED, 0xB5, 0xA1}, - new int[]{0x55, 0xEE, 0x55, 0x6}, + new int[]{0xAA, 0x7D, 0x10, 0x11}, + new int[]{0xAA, 0x7E, 0x44, 0x7}, + new int[]{0xAA, 0x7F, 0x44, 0x7}, + new int[]{0xAD, 0x7E, 0x47, 0x7}, + new int[]{0xAD, 0x7F, 0x47, 0x7}, + new int[]{0xAC, 0x6C, 0x12, 0x15}, + new int[]{0xA6, 0x7E, 0x40, 0x3}, + new int[]{0xA6, 0x7F, 0x40, 0x3}, + new int[]{0xA1, 0x6C, 0x1, 0x1}, + new int[]{0xA1, 0x6D, 0x1, 0x1}, + new int[]{0xB8, 0x6F, 0x58, 0xB}, + new int[]{0xB8, 0x7C, 0x1E, 0xD}, + new int[]{0xB8, 0x7D, 0x1E, 0xD}, + new int[]{0xB8, 0x7E, 0x52, 0x3}, + new int[]{0x95, 0xE4, 0x95, 0x84}, + new int[]{0x95, 0xE5, 0xF5, 0xA5}, + new int[]{0x95, 0xE6, 0x95, 0x86}, + new int[]{0x95, 0xE7, 0x35, 0x27}, + new int[]{0x28, 0xE9, 0x88, 0x8D}, + new int[]{0x28, 0xEA, 0x28, 0x2E}, + new int[]{0x28, 0xEB, 0xC8, 0x8B}, + new int[]{0x28, 0xF8, 0x2E, 0x2C}, + new int[]{0x53, 0xF8, 0x59, 0xC}, + new int[]{0x53, 0xF9, 0xB9, 0xA9}, + new int[]{0x53, 0xFA, 0x4D, 0x1E}, + new int[]{0x53, 0xFB, 0xED, 0xBF}, + new int[]{0xEF, 0xEF, 0x89, 0x8B}, + new int[]{0xEF, 0xFC, 0x55, 0x15}, + new int[]{0xEF, 0xFD, 0x55, 0x15}, + new int[]{0xEF, 0xFE, 0x89, 0x8B}, + new int[]{0x20, 0xFD, 0x86, 0x81}, + new int[]{0x20, 0xFE, 0x1A, 0x1A}, + new int[]{0x20, 0xFF, 0xBA, 0xBB}, + new int[]{0x1C, 0xEF, 0xB6, 0xA3}, + new int[]{0x1C, 0xFC, 0x22, 0x34}, + new int[]{0x1C, 0xFD, 0x82, 0x95}, + new int[]{0x16, 0xFF, 0xB0, 0xA3}, + new int[]{0x11, 0xEC, 0x11, 0x4}, + new int[]{0x11, 0xED, 0x71, 0x25}, + new int[]{0x11, 0xEE, 0x11, 0x6}, + new int[]{0x55, 0xEC, 0x55, 0x4}, + new int[]{0x55, 0xED, 0xB5, 0xA1}, + new int[]{0x55, 0xEE, 0x55, 0x6}, }; for (int[] p : params) { test.verifyRegister(REG_A, c -> p[2]) - .verifyFlags(new FlagsCheckImpl().exact(p[3]), c -> c.flags) - .run(0x27) - .accept((byte) p[0], (byte) p[1]); + .verifyFlags(new FlagsCheckImpl().exact(p[3]), c -> c.flags) + .run(0x27) + .accept((byte) p[0], (byte) p[1]); } } @Test public void testCPL() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> ~context.first) - .verifyFlagsOfLastOp(new FlagsCheckImpl().halfCarryIsSet().subtractionIsSet()); + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> ~context.first) + .verifyFlagsOfLastOp(new FlagsCheckImpl().halfCarryIsSet().subtractionIsSet()); Generator.forSome8bitUnary( - test.run(0x2F) + test.run(0x2F) ); } @@ -263,250 +263,250 @@ public void testCCF() { @Test public void testRLCA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .setFlags(FLAG_N | FLAG_H) - .verifyRegister(REG_A, context -> ((context.first << 1) & 0xFF) | (context.first >>> 7) & 1) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsFirstOperandMSB().halfCarryIsReset().subtractionIsReset()); + .firstIsRegister(REG_A) + .setFlags(FLAG_N | FLAG_H) + .verifyRegister(REG_A, context -> ((context.first << 1) & 0xFF) | (context.first >>> 7) & 1) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsFirstOperandMSB().halfCarryIsReset().subtractionIsReset()); Generator.forSome8bitUnary( - test.run(0x07) + test.run(0x07) ); } @Test public void testRRCA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .setFlags(FLAG_N | FLAG_H) - .verifyRegister(REG_A, context -> (((context.first & 0xFF) >>> 1) | (context.first << 7)) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .signIsPreserved() - .zeroIsPreserved() - .parityIsPreserved() - .carryIsFirstOperandLSB() - .halfCarryIsReset() - .subtractionIsReset()); + .firstIsRegister(REG_A) + .setFlags(FLAG_N | FLAG_H) + .verifyRegister(REG_A, context -> (((context.first & 0xFF) >>> 1) | (context.first << 7)) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .signIsPreserved() + .zeroIsPreserved() + .parityIsPreserved() + .carryIsFirstOperandLSB() + .halfCarryIsReset() + .subtractionIsReset()); Generator.forSome8bitUnary( - test.run(0x0F) + test.run(0x0F) ); } @Test public void testRLA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .setFlags(FLAG_N | FLAG_H) - .verifyRegister(REG_A, context -> ((context.first << 1) & 0xFE) | (context.flags & 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsFirstOperandMSB().halfCarryIsReset().subtractionIsReset()); + .firstIsRegister(REG_A) + .setFlags(FLAG_N | FLAG_H) + .verifyRegister(REG_A, context -> ((context.first << 1) & 0xFE) | (context.flags & 1)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsFirstOperandMSB().halfCarryIsReset().subtractionIsReset()); Generator.forSome8bitUnary( - test.run(0x17) + test.run(0x17) ); } @Test public void testRRA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .setFlags(FLAG_N | FLAG_H) - .verifyRegister(REG_A, context -> ((context.first >> 1) & 0x7F) | ((context.flags & 1) << 7)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsFirstOperandLSB().halfCarryIsReset().subtractionIsReset()); + .firstIsRegister(REG_A) + .setFlags(FLAG_N | FLAG_H) + .verifyRegister(REG_A, context -> ((context.first >> 1) & 0x7F) | ((context.flags & 1) << 7)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsFirstOperandLSB().halfCarryIsReset().subtractionIsReset()); Generator.forSome8bitUnary( - test.run(0x1F) + test.run(0x1F) ); } @Test public void testCPI() { IntegerTestBuilder test = prepareCPxTest(context -> - ((context.getRegister(REG_H) << 8 | context.getRegister(REG_L)) + 1)); + ((context.getRegister(REG_H) << 8 | context.getRegister(REG_L)) + 1)); Generator.forSome16bitBinary(3, - test.run(0xED, 0xA1) + test.run(0xED, 0xA1) ); } @Test public void testCPIR() { IntegerTestBuilder test = prepareCPxTest(context -> - ((context.getRegister(REG_H) << 8 | context.getRegister(REG_L)) + 1)) - .verifyPC(context -> { - boolean regAzero = (context.registers.get(REG_A) == (context.second & 0xFF)); - boolean BCzero = ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) == 0; - if (regAzero || BCzero) { - return context.PC + 2; - } - return context.PC; - }); + ((context.getRegister(REG_H) << 8 | context.getRegister(REG_L)) + 1)) + .verifyPC(context -> { + boolean regAzero = (context.registers.get(REG_A) == (context.second & 0xFF)); + boolean BCzero = ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) == 0; + if (regAzero || BCzero) { + return context.PC + 2; + } + return context.PC; + }); Generator.forSome16bitBinary(3, - test.run(0xED, 0xB1) + test.run(0xED, 0xB1) ); } @Test public void testCPD() { IntegerTestBuilder test = prepareCPxTest(context -> - ((context.getRegister(REG_H) << 8 | context.getRegister(REG_L)) - 1)); + ((context.getRegister(REG_H) << 8 | context.getRegister(REG_L)) - 1)); Generator.forSome16bitBinary(3, - test.run(0xED, 0xA9) + test.run(0xED, 0xA9) ); } @Test public void testCPDR() { IntegerTestBuilder test = prepareCPxTest(context -> - ((context.getRegister(REG_H) << 8 | context.getRegister(REG_L)) - 1)) - .verifyPC(context -> { - boolean regAzero = (context.registers.get(REG_A) == (context.second & 0xFF)); - boolean BCzero = ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) == 0; - if (regAzero || BCzero) { - return context.PC + 2; - } - return context.PC; - }); + ((context.getRegister(REG_H) << 8 | context.getRegister(REG_L)) - 1)) + .verifyPC(context -> { + boolean regAzero = (context.registers.get(REG_A) == (context.second & 0xFF)); + boolean BCzero = ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) == 0; + if (regAzero || BCzero) { + return context.PC + 2; + } + return context.PC; + }); Generator.forSome16bitBinary(3, - test.run(0xED, 0xB9) + test.run(0xED, 0xB9) ); } @Test public void testAND_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8LSBisRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().parity().carryIsReset().halfCarryIsSet().subtractionIsReset()) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8LSBisRegister(REG_A) + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.second & 0xFF)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().parity().carryIsReset().halfCarryIsSet().subtractionIsReset()) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0xA6), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0xA6) + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0xA6), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0xA6) ); } @Test public void testOR_REF_II_N() { IntegerTestBuilder test = prepareLogicIXYtest(context -> (context.first & 0xFF) | (context.second & 0xFF)) - .keepCurrentInjectorsAfterRun(); + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0xB6), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0xB6) + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0xB6), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0xB6) ); } @Test public void testXOR_REF_II_N() { IntegerTestBuilder test = prepareLogicIXYtest(context -> (context.first & 0xFF) ^ (context.second & 0xFF)) - .keepCurrentInjectorsAfterRun(); + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0xAE), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0xAE) + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0xAE), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0xAE) ); } @Test public void testCP_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8LSBisRegister(REG_A) - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet(), - context -> (context.first & 0xFF) - (context.second & 0xFF) - ) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8LSBisRegister(REG_A) + .verifyRegister(REG_A, context -> context.first & 0xFF) + .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet(), + context -> (context.first & 0xFF) - (context.second & 0xFF) + ) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0xBE), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0xBE) + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, 0xBE), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, 0xBE) ); } @Test public void testNEG() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (-context.first) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero() - .expectFlagOnlyWhen(FLAG_C, (c, result) -> c.first != 0) - .expectFlagOnlyWhen(FLAG_PV, (c, result) -> (c.first & 0xff) == 0x80) - .halfBorrow() - .subtractionIsSet() - ) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(REG_A) + .verifyRegister(REG_A, context -> (-context.first) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero() + .expectFlagOnlyWhen(FLAG_C, (c, result) -> c.first != 0) + .expectFlagOnlyWhen(FLAG_PV, (c, result) -> (c.first & 0xff) == 0x80) + .halfBorrow() + .subtractionIsSet() + ) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( - test.run(0xED, 0x44), - test.run(0xED, 0x4C), - test.run(0xED, 0x54), - test.run(0xED, 0x5C), - test.run(0xED, 0x64), - test.run(0xED, 0x6C), - test.run(0xED, 0x74), - test.run(0xED, 0x7C) + test.run(0xED, 0x44), + test.run(0xED, 0x4C), + test.run(0xED, 0x54), + test.run(0xED, 0x5C), + test.run(0xED, 0x64), + test.run(0xED, 0x6C), + test.run(0xED, 0x74), + test.run(0xED, 0x7C) ); } @Test public void testRLC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(FLAG_H | FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setFlags(FLAG_H | FLAG_N) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> - ((context.first << 1) & 0xFF) | (context.first >>> 7) & 1; + ((context.first << 1) & 0xFF) | (context.first >>> 7) & 1; FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); + .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x07), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x00), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x01), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x02), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x03), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x04), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x05), - test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x06) + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x07), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x00), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x01), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x02), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x03), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x04), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x05), + test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) + .verifyFlagsOfLastOp(flags).run(0xCB, 0x06) ); } @Test public void testRLC_REF_II_N() { IntegerTestBuilder test = prepareIIRotationMSBTest( - context -> ((context.second << 1) & 0xFF) | (context.second >>> 7) & 1 + context -> ((context.second << 1) & 0xFF) | (context.second >>> 7) & 1 ).keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), - test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(6, 0xDD, 0xCB), - test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(6, 0xFD, 0xCB) + test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(6, 0xDD, 0xCB), + test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(6, 0xFD, 0xCB) ); } @Test public void testRLC_REF_II_N_R() { Function, Integer> operation = - context -> ((context.second << 1) & 0xFF) | (context.second >>> 7) & 1; + context -> ((context.second << 1) & 0xFF) | (context.second >>> 7) & 1; IntegerTestBuilder test = prepareIIRotationMSBTest(operation) - .verifyRegister(REG_B, operation) - .keepCurrentInjectorsAfterRun(); + .verifyRegister(REG_B, operation) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), - test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0, 0xDD, 0xCB), - test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0, 0xFD, 0xCB) + test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0, 0xDD, 0xCB), + test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0, 0xFD, 0xCB) ); } @@ -514,612 +514,612 @@ public void testRLC_REF_II_N_R() { @Test public void testRL_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(FLAG_H | FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setFlags(FLAG_H | FLAG_N) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> - ((context.first << 1) & 0xFF) | (context.flags & FLAG_C); + ((context.first << 1) & 0xFF) | (context.flags & FLAG_C); FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); + .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x17), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x10), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x11), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x12), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x13), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x14), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x15), - test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x16) + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x17), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x10), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x11), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x12), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x13), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x14), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x15), + test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) + .verifyFlagsOfLastOp(flags).run(0xCB, 0x16) ); } @Test public void testRL_REF_II_N() { IntegerTestBuilder test = prepareIIRotationMSBTest( - context -> ((context.second << 1) & 0xFF) | (context.flags & FLAG_C) + context -> ((context.second << 1) & 0xFF) | (context.flags & FLAG_C) ).keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), - test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x16, 0xDD, 0xCB), - test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x16, 0xFD, 0xCB) + test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x16, 0xDD, 0xCB), + test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x16, 0xFD, 0xCB) ); } @Test public void testRRC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(FLAG_H | FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setFlags(FLAG_H | FLAG_N) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> - ((context.first >>> 1) & 0x7F) | (((context.first & 1) << 7)); + ((context.first >>> 1) & 0x7F) | (((context.first & 1) << 7)); FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); + .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0F), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x08), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x09), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0A), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0B), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0C), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0D), - test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x0E) + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0F), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x08), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x09), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0A), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0B), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0C), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0D), + test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) + .verifyFlagsOfLastOp(flags).run(0xCB, 0x0E) ); } @Test public void testRRC_REF_II_N() { IntegerTestBuilder test = prepareIIRotationLSBTest( - context -> ((context.second >>> 1) & 0x7F) | (((context.second & 1) << 7)) + context -> ((context.second >>> 1) & 0x7F) | (((context.second & 1) << 7)) ).keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), - test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x0E, 0xDD, 0xCB), - test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x0E, 0xFD, 0xCB) + test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x0E, 0xDD, 0xCB), + test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x0E, 0xFD, 0xCB) ); } @Test public void testRR_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(FLAG_H | FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setFlags(FLAG_H | FLAG_N) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> - ((context.first >> 1) & 0x7F) | ((context.flags & FLAG_C) << 7); + ((context.first >> 1) & 0x7F) | ((context.flags & FLAG_C) << 7); FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); + .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1F), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x18), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x19), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1A), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1B), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1C), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1D), - test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x1E) + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1F), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x18), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x19), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1A), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1B), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1C), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1D), + test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) + .verifyFlagsOfLastOp(flags).run(0xCB, 0x1E) ); } @Test public void testRR_REF_II_N() { IntegerTestBuilder test = prepareIIRotationLSBTest( - context -> ((context.second >> 1) & 0x7F) | ((context.flags & FLAG_C) << 7) + context -> ((context.second >> 1) & 0x7F) | ((context.flags & FLAG_C) << 7) ).keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), - test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x1E, 0xDD, 0xCB), - test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x1E, 0xFD, 0xCB) + test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x1E, 0xDD, 0xCB), + test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x1E, 0xFD, 0xCB) ); } @Test public void testSLA_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(FLAG_H | FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setFlags(FLAG_H | FLAG_N) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> (context.first << 1) & 0xFE; FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); + .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x27), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x20), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x21), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x22), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x23), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x24), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x25), - test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x26) + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x27), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x20), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x21), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x22), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x23), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x24), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x25), + test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) + .verifyFlagsOfLastOp(flags).run(0xCB, 0x26) ); } @Test public void testSLA_REF_II_N() { IntegerTestBuilder test = prepareIIRotationMSBTest(context -> (context.second << 1) & 0xFE) - .keepCurrentInjectorsAfterRun(); + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), - test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x26, 0xDD, 0xCB), - test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x26, 0xFD, 0xCB) + test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x26, 0xDD, 0xCB), + test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x26, 0xFD, 0xCB) ); } @Test public void testSRA_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(FLAG_H | FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setFlags(FLAG_H | FLAG_N) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> (context.first >> 1) & 0xFF | (context.first & 0x80); FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); + .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2F), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x28), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x29), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2A), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2B), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2C), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2D), - test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x2E) + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2F), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x28), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x29), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2A), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2B), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2C), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2D), + test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) + .verifyFlagsOfLastOp(flags).run(0xCB, 0x2E) ); } @Test public void testSRA_REF_II_N() { IntegerTestBuilder test = prepareIIRotationLSBTest( - context -> ((context.second & 0xFF) >>> 1) & 0xFF | (context.second & 0x80) + context -> ((context.second & 0xFF) >>> 1) & 0xFF | (context.second & 0x80) ).keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), - test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x2E, 0xDD, 0xCB), - test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x2E, 0xFD, 0xCB) + test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x2E, 0xDD, 0xCB), + test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x2E, 0xFD, 0xCB) ); } @Test public void testSRL_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(FLAG_H | FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setFlags(FLAG_H | FLAG_N) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> (context.first >>> 1) & 0x7F; FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); + .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3F), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x38), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x39), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3A), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3B), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3C), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3D), - test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x3E) + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3F), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x38), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x39), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3A), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3B), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3C), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3D), + test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) + .verifyFlagsOfLastOp(flags).run(0xCB, 0x3E) ); } @Test public void testSRL_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .verifyByte(context -> get8MSBplus8LSB(context.first), context -> ((context.second & 0xFF) >>> 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().carryIsFirstOperandLSB().sign().zero().halfCarryIsReset().parity() - .subtractionIsReset()) - .setFlags(0xFF) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .verifyByte(context -> get8MSBplus8LSB(context.first), context -> ((context.second & 0xFF) >>> 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .switchFirstAndSecond().carryIsFirstOperandLSB().sign().zero().halfCarryIsReset().parity() + .subtractionIsReset()) + .setFlags(0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), - test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x3E, 0xDD, 0xCB), - test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x3E, 0xFD, 0xCB) + test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x3E, 0xDD, 0xCB), + test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x3E, 0xFD, 0xCB) ); } @Test public void testSLL_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .setFlags(0xFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> (context.first << 1) & 0xFF | 1; FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); + .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x37), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x30), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x31), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x32), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x33), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x34), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x35), - test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x36) + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x37), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x30), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x31), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x32), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x33), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x34), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x35), + test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) + .verifyFlagsOfLastOp(flags).run(0xCB, 0x36) ); } @Test public void testSLL_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .verifyByte( - context -> get8MSBplus8LSB(context.first), - context -> ((context.second << 1) | 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().carryIsFirstOperandMSB().sign().zero().halfCarryIsReset().parity() - .subtractionIsReset()) - .setFlags(0xFF) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .verifyByte( + context -> get8MSBplus8LSB(context.first), + context -> ((context.second << 1) | 1) & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .switchFirstAndSecond().carryIsFirstOperandMSB().sign().zero().halfCarryIsReset().parity() + .subtractionIsReset()) + .setFlags(0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), - test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x36, 0xDD, 0xCB), - test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x36, 0xFD, 0xCB) + test.first8MSBisIX().runWithFirst8bitOperandWithOpcodeAfter(0x36, 0xDD, 0xCB), + test.first8MSBisIY().runWithFirst8bitOperandWithOpcodeAfter(0x36, 0xFD, 0xCB) ); } @Test public void testRLD() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8LSBisRegister(REG_A) - .verifyByte(context -> context.first, context -> (context.second << 4) & 0xF0 | context.first & 0x0F) - .verifyRegister(REG_A, context -> (context.first & 0xF0) | (context.second >>> 4) & 0x0F) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().parity().subtractionIsReset().halfCarryIsReset()); + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8LSBisRegister(REG_A) + .verifyByte(context -> context.first, context -> (context.second << 4) & 0xF0 | context.first & 0x0F) + .verifyRegister(REG_A, context -> (context.first & 0xF0) | (context.second >>> 4) & 0x0F) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().parity().subtractionIsReset().halfCarryIsReset()); Generator.forSome16bitBinary( - test.run(0xED, 0x6F) + test.run(0xED, 0x6F) ); } @Test public void testRRD() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8LSBisRegister(REG_A) - .verifyByte(context -> context.first, context -> (context.first << 4) & 0xF0 | (context.second >>> 4) & 0x0F) - .verifyRegister(REG_A, context -> (context.first & 0xF0) | context.second & 0x0F) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().parity().subtractionIsReset().halfCarryIsReset()); + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8LSBisRegister(REG_A) + .verifyByte(context -> context.first, context -> (context.first << 4) & 0xF0 | (context.second >>> 4) & 0x0F) + .verifyRegister(REG_A, context -> (context.first & 0xF0) | context.second & 0x0F) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().parity().subtractionIsReset().halfCarryIsReset()); Generator.forSome16bitBinary( - test.run(0xED, 0x67) + test.run(0xED, 0x67) ); } @Test public void testAND_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .first8LSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xDD, 0xA4) + test.run(0xDD, 0xA4) ); } @Test public void testAND_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisRegister(REG_A) - .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .first8MSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xDD, 0xA5) + test.run(0xDD, 0xA5) ); } @Test public void testAND_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .first8LSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xFD, 0xA4) + test.run(0xFD, 0xA4) ); } @Test public void testAND_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBisRegister(REG_A) - .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .first8MSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xFD, 0xA5) + test.run(0xFD, 0xA5) ); } @Test public void testXOR_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .first8LSBisRegister(REG_A) - .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .setFlags(0xFF) + .first8LSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xDD, 0xAC) + test.run(0xDD, 0xAC) ); } @Test public void testXOR_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .first8MSBisRegister(REG_A) - .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .setFlags(0xFF) + .first8MSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xDD, 0xAD) + test.run(0xDD, 0xAD) ); } @Test public void testXOR_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .first8LSBisRegister(REG_A) - .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .setFlags(0xFF) + .first8LSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xFD, 0xAC) + test.run(0xFD, 0xAC) ); } @Test public void testXOR_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .first8MSBisRegister(REG_A) - .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .setFlags(0xFF) + .first8MSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xFD, 0xAD) + test.run(0xFD, 0xAD) ); } @Test public void testOR_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .first8LSBisRegister(REG_A) - .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .setFlags(0xFF) + .first8LSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xDD, 0xB4) + test.run(0xDD, 0xB4) ); } @Test public void testOR_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .first8MSBisRegister(REG_A) - .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .setFlags(0xFF) + .first8MSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xDD, 0xB5) + test.run(0xDD, 0xB5) ); } @Test public void testOR_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .first8LSBisRegister(REG_A) - .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .setFlags(0xFF) + .first8LSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xFD, 0xB4) + test.run(0xFD, 0xB4) ); } @Test public void testOR_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .first8MSBisRegister(REG_A) - .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .setFlags(0xFF) + .first8MSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); Generator.forSome16bitUnary( - test.run(0xFD, 0xB5) + test.run(0xFD, 0xB5) ); } @Test public void testCP_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .firstIsIX() - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond(c -> c.first >>> 8) - .sign().zero() - .borrow() - .halfBorrow() - .overflowSub() - .subtractionIsSet(), - context -> (context.first & 0xFF) + (((~(context.first >>> 8)) + 1) & 0xFF)); + .first8LSBisRegister(REG_A) + .firstIsIX() + .verifyRegister(REG_A, context -> context.first & 0xFF) + .verifyFlags(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond(c -> c.first >>> 8) + .sign().zero() + .borrow() + .halfBorrow() + .overflowSub() + .subtractionIsSet(), + context -> (context.first & 0xFF) + (((~(context.first >>> 8)) + 1) & 0xFF)); Generator.forSome16bitUnary( - test.run(0xDD, 0xBC) + test.run(0xDD, 0xBC) ); } @Test public void testCP_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .firstIsIY() - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond(c -> c.first >>> 8) - .sign().zero() - .borrow() - .halfBorrow() - .overflowSub() - .subtractionIsSet(), - context -> (context.first & 0xFF) + (((~(context.first >>> 8)) + 1) & 0xFF)); + .first8LSBisRegister(REG_A) + .firstIsIY() + .verifyRegister(REG_A, context -> context.first & 0xFF) + .verifyFlags(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond(c -> c.first >>> 8) + .sign().zero() + .borrow() + .halfBorrow() + .overflowSub() + .subtractionIsSet(), + context -> (context.first & 0xFF) + (((~(context.first >>> 8)) + 1) & 0xFF)); Generator.forSome16bitUnary( - test.run(0xFD, 0xBC) + test.run(0xFD, 0xBC) ); } @Test public void testCP_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIX() - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl() - .sign().zero() - .borrow() - .halfBorrow() - .overflowSub() - .subtractionIsSet(), - context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); + .first8LSBisRegister(REG_A) + .secondIsIX() + .verifyRegister(REG_A, context -> context.first & 0xFF) + .verifyFlags(new FlagsCheckImpl() + .sign().zero() + .borrow() + .halfBorrow() + .overflowSub() + .subtractionIsSet(), + context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); Generator.forSome16bitBinary( - test.run(0xDD, 0xBD) + test.run(0xDD, 0xBD) ); } @Test public void testCP_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8LSBisRegister(REG_A) - .secondIsIY() - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond8LSB() - .sign() - .zero() - .borrow() - .halfBorrow() - .overflowSub() - .subtractionIsSet(), - context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); + .first8LSBisRegister(REG_A) + .secondIsIY() + .verifyRegister(REG_A, context -> context.first & 0xFF) + .verifyFlags(new FlagsCheckImpl() + .setFirst8LSB() + .setSecond8LSB() + .sign() + .zero() + .borrow() + .halfBorrow() + .overflowSub() + .subtractionIsSet(), + context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); Generator.forSome16bitBinary( - test.run(0xFD, 0xBD) + test.run(0xFD, 0xBD) ); } private ByteTestBuilder getLogicTestBuilder(Function, Integer> operator) { return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .setFlags(0xFF) - .firstIsRegister(REG_A) - .verifyRegister(REG_A, operator) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()) - .keepCurrentInjectorsAfterRun(); + .setFlags(0xFF) + .firstIsRegister(REG_A) + .verifyRegister(REG_A, operator) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()) + .keepCurrentInjectorsAfterRun(); } private IntegerTestBuilder prepareCPxTest(Function, Integer> hlOperation) { return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .first8LSBisRegister(REG_A) - .registerIsRandom(REG_B, 0xFF) - .registerIsRandom(REG_C, 0xFF) - .verifyPair(REG_PAIR_HL, hlOperation) - .verifyPair(REG_PAIR_BC, context -> - ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) - ) - .verifyFlags(new FlagsCheckImpl() - .sign().zero().subtractionIsSet().halfBorrow() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> - ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) != 0 - ), context -> context.registers.get(REG_A) - (context.second & 0xFF)); + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .first8LSBisRegister(REG_A) + .registerIsRandom(REG_B, 0xFF) + .registerIsRandom(REG_C, 0xFF) + .verifyPair(REG_PAIR_HL, hlOperation) + .verifyPair(REG_PAIR_BC, context -> + ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) + ) + .verifyFlags(new FlagsCheckImpl() + .sign().zero().subtractionIsSet().halfBorrow() + .expectFlagOnlyWhen(FLAG_PV, (context, result) -> + ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) != 0 + ), context -> context.registers.get(REG_A) - (context.second & 0xFF)); } private IntegerTestBuilder prepareLogicIXYtest(Function, Integer> operation) { return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8LSBisRegister(REG_A) - .verifyRegister(REG_A, operation) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().parity().carryIsReset().halfCarryIsReset().subtractionIsReset()); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8LSBisRegister(REG_A) + .verifyRegister(REG_A, operation) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .sign().zero().parity().carryIsReset().halfCarryIsReset().subtractionIsReset()); } private IntegerTestBuilder prepareIIRotationMSBTest(Function, Integer> operator) { return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .verifyByte(context -> get8MSBplus8LSB(context.first), operator) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().carryIsFirstOperandMSB().sign().zero().halfCarryIsReset().parity() - .subtractionIsReset()) - .setFlags(FLAG_H | FLAG_N); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .verifyByte(context -> get8MSBplus8LSB(context.first), operator) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .switchFirstAndSecond().carryIsFirstOperandMSB().sign().zero().halfCarryIsReset().parity() + .subtractionIsReset()) + .setFlags(FLAG_H | FLAG_N); } private IntegerTestBuilder prepareIIRotationLSBTest(Function, Integer> operator) { return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .verifyByte(context -> get8MSBplus8LSB(context.first), operator) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().carryIsFirstOperandLSB().sign().zero().halfCarryIsReset().parity() - .subtractionIsReset()) - .setFlags(FLAG_H | FLAG_N); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .verifyByte(context -> get8MSBplus8LSB(context.first), operator) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .switchFirstAndSecond().carryIsFirstOperandLSB().sign().zero().halfCarryIsReset().parity() + .subtractionIsReset()) + .setFlags(FLAG_H | FLAG_N); } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/StackTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/StackTest.java index 447e6eba0..5f48c065d 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/StackTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/StackTest.java @@ -27,62 +27,62 @@ public class StackTest extends InstructionsTest { @Test public void testPUSH_qq() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .secondIsPair(REG_SP) - .verifyPair(REG_SP, context -> (context.SP - 2) & 0xFFFF) - .verifyWord(context -> (context.second - 2) & 0xFFFF, context -> context.first) - .keepCurrentInjectorsAfterRun(); + .secondIsPair(REG_SP) + .verifyPair(REG_SP, context -> (context.SP - 2) & 0xFFFF) + .verifyWord(context -> (context.second - 2) & 0xFFFF, context -> context.first) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary( - test.firstIsPair(REG_PAIR_BC).run(0xC5), - test.firstIsPair(REG_PAIR_DE).run(0xD5), - test.firstIsPair(REG_PAIR_HL).run(0xE5), - test.firstIsPSW().run(0xF5) + test.firstIsPair(REG_PAIR_BC).run(0xC5), + test.firstIsPair(REG_PAIR_DE).run(0xD5), + test.firstIsPair(REG_PAIR_HL).run(0xE5), + test.firstIsPSW().run(0xF5) ); } @Test public void testPUSH_IX_IY() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsPair(REG_SP) - .verifyPair(REG_SP, context -> (context.first - 2) & 0xFFFF) - .verifyWord(context -> (context.first - 2) & 0xFFFF, context -> context.second) - .keepCurrentInjectorsAfterRun(); + .firstIsPair(REG_SP) + .verifyPair(REG_SP, context -> (context.first - 2) & 0xFFFF) + .verifyWord(context -> (context.first - 2) & 0xFFFF, context -> context.second) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary( - test.secondIsIX().run(0xDD, 0xE5), - test.secondIsIY().run(0xFD, 0xE5) + test.secondIsIX().run(0xDD, 0xE5), + test.secondIsIY().run(0xFD, 0xE5) ); } @Test public void testPOP_qq() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .firstIsPair(REG_SP) - .verifyPair(REG_SP, context -> (context.first + 2) & 0xFFFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsAddressAndSecondIsMemoryWord() + .firstIsPair(REG_SP) + .verifyPair(REG_SP, context -> (context.first + 2) & 0xFFFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome16bitBinary(3, - test.secondIsPair(REG_PAIR_BC).verifyPair(REG_PAIR_BC, context -> context.second).run(0xC1), - test.secondIsPair(REG_PAIR_DE).verifyPair(REG_PAIR_DE, context -> context.second).run(0xD1), - test.secondIsPair(REG_PAIR_HL).verifyPair(REG_PAIR_HL, context -> context.second).run(0xE1), - test.secondIsPSW().verifyPSW(context -> context.second).run(0xF1) + test.secondIsPair(REG_PAIR_BC).verifyPair(REG_PAIR_BC, context -> context.second).run(0xC1), + test.secondIsPair(REG_PAIR_DE).verifyPair(REG_PAIR_DE, context -> context.second).run(0xD1), + test.secondIsPair(REG_PAIR_HL).verifyPair(REG_PAIR_HL, context -> context.second).run(0xE1), + test.secondIsPSW().verifyPSW(context -> context.second).run(0xF1) ); } @Test public void testPOP_IX_IY() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .firstIsPair(REG_SP) - .verifyPair(REG_SP, context -> (context.first + 2) & 0xFFFF) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsAddressAndSecondIsMemoryWord() + .firstIsPair(REG_SP) + .verifyPair(REG_SP, context -> (context.first + 2) & 0xFFFF) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome16bitBinary(3, - test.verifyIX(context -> context.second).run(0xDD, 0xE1), - test.verifyIY(context -> context.second).run(0xFD, 0xE1) + test.verifyIX(context -> context.second).run(0xDD, 0xE1), + test.verifyIY(context -> context.second).run(0xFD, 0xE1) ); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java index adf11141e..be2b44326 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java @@ -55,44 +55,44 @@ public void testLD_R_N() { @Test public void testLD_REF_HL_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsMemoryByteAt(0x303) - .setPair(REG_PAIR_HL, 0x303) - .verifyByte(0x303, context -> context.second & 0xFF) - .keepCurrentInjectorsAfterRun(); + .firstIsMemoryByteAt(0x303) + .setPair(REG_PAIR_HL, 0x303) + .verifyByte(0x303, context -> context.second & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinary( - test.runWithSecondOperand(0x36) + test.runWithSecondOperand(0x36) ); } @Test public void testLD_REF_HL_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsMemoryByteAt(0x303) - .setPair(REG_PAIR_HL, 0x303) - .verifyByte(0x303, context -> context.second & 0xFF) - .keepCurrentInjectorsAfterRun(); + .firstIsMemoryByteAt(0x303) + .setPair(REG_PAIR_HL, 0x303) + .verifyByte(0x303, context -> context.second & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinary( - test.secondIsRegister(REG_B).run(0x70), - test.secondIsRegister(REG_C).run(0x71), - test.secondIsRegister(REG_D).run(0x72), - test.secondIsRegister(REG_E).run(0x73), - test.secondIsRegister(REG_A).run(0x77) + test.secondIsRegister(REG_B).run(0x70), + test.secondIsRegister(REG_C).run(0x71), + test.secondIsRegister(REG_D).run(0x72), + test.secondIsRegister(REG_E).run(0x73), + test.secondIsRegister(REG_A).run(0x77) ); } @Test public void testLD_REF_HL_HL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsAddressAndSecondIsMemoryByte() + .firstIsPair(REG_PAIR_HL) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome16bitBinary(1, - test.verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF).run(0x74), - test.verifyByte(context -> context.first, context -> context.first & 0xFF).run(0x75) + test.verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF).run(0x74), + test.verifyByte(context -> context.first, context -> context.first & 0xFF).run(0x75) ); } @@ -110,359 +110,359 @@ public void testLD_R_REF_II_N() { @Test public void testLD_REF_IX_N_R() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8MSBisIX() - .verifyByte(context -> Utils.get8MSBplus8LSB(context.first), context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8MSBisIX() + .verifyByte(context -> Utils.get8MSBplus8LSB(context.first), context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8LSBisRegister(REG_A).runWithFirst8bitOperand(0xDD, 0x77), - test.first8LSBisRegister(REG_B).runWithFirst8bitOperand(0xDD, 0x70), - test.first8LSBisRegister(REG_C).runWithFirst8bitOperand(0xDD, 0x71), - test.first8LSBisRegister(REG_D).runWithFirst8bitOperand(0xDD, 0x72), - test.first8LSBisRegister(REG_E).runWithFirst8bitOperand(0xDD, 0x73), - test.first8LSBisRegister(REG_H).runWithFirst8bitOperand(0xDD, 0x74), - test.first8LSBisRegister(REG_L).runWithFirst8bitOperand(0xDD, 0x75) + test.first8LSBisRegister(REG_A).runWithFirst8bitOperand(0xDD, 0x77), + test.first8LSBisRegister(REG_B).runWithFirst8bitOperand(0xDD, 0x70), + test.first8LSBisRegister(REG_C).runWithFirst8bitOperand(0xDD, 0x71), + test.first8LSBisRegister(REG_D).runWithFirst8bitOperand(0xDD, 0x72), + test.first8LSBisRegister(REG_E).runWithFirst8bitOperand(0xDD, 0x73), + test.first8LSBisRegister(REG_H).runWithFirst8bitOperand(0xDD, 0x74), + test.first8LSBisRegister(REG_L).runWithFirst8bitOperand(0xDD, 0x75) ); } @Test public void testLD_REF_IY_N_R() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8MSBisIY() - .verifyByte(context -> Utils.get8MSBplus8LSB(context.first), context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8MSBisIY() + .verifyByte(context -> Utils.get8MSBplus8LSB(context.first), context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8LSBisRegister(REG_A).runWithFirst8bitOperand(0xFD, 0x77), - test.first8LSBisRegister(REG_B).runWithFirst8bitOperand(0xFD, 0x70), - test.first8LSBisRegister(REG_C).runWithFirst8bitOperand(0xFD, 0x71), - test.first8LSBisRegister(REG_D).runWithFirst8bitOperand(0xFD, 0x72), - test.first8LSBisRegister(REG_E).runWithFirst8bitOperand(0xFD, 0x73), - test.first8LSBisRegister(REG_H).runWithFirst8bitOperand(0xFD, 0x74), - test.first8LSBisRegister(REG_L).runWithFirst8bitOperand(0xFD, 0x75) + test.first8LSBisRegister(REG_A).runWithFirst8bitOperand(0xFD, 0x77), + test.first8LSBisRegister(REG_B).runWithFirst8bitOperand(0xFD, 0x70), + test.first8LSBisRegister(REG_C).runWithFirst8bitOperand(0xFD, 0x71), + test.first8LSBisRegister(REG_D).runWithFirst8bitOperand(0xFD, 0x72), + test.first8LSBisRegister(REG_E).runWithFirst8bitOperand(0xFD, 0x73), + test.first8LSBisRegister(REG_H).runWithFirst8bitOperand(0xFD, 0x74), + test.first8LSBisRegister(REG_L).runWithFirst8bitOperand(0xFD, 0x75) ); } @Test public void testLD_REF_II_N_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .verifyByte(context -> Utils.get8MSBplus8LSB(context.first), context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .verifyByte(context -> Utils.get8MSBplus8LSB(context.first), context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(4), - test.first8MSBisIX().runWithFirst8bitOperandTwoTimes(0xDD, 0x36), - test.first8MSBisIY().runWithFirst8bitOperandTwoTimes(0xFD, 0x36) + test.first8MSBisIX().runWithFirst8bitOperandTwoTimes(0xDD, 0x36), + test.first8MSBisIY().runWithFirst8bitOperandTwoTimes(0xFD, 0x36) ); } @Test public void testLD_A_REF_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .verifyRegister(REG_A, context -> context.second & 0xFF) - .keepCurrentInjectorsAfterRun(); + .firstIsAddressAndSecondIsMemoryByte() + .verifyRegister(REG_A, context -> context.second & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(1, - test.firstIsPair(REG_PAIR_BC).run(0x0A), - test.firstIsPair(REG_PAIR_DE).run(0x1A) + test.firstIsPair(REG_PAIR_BC).run(0x0A), + test.firstIsPair(REG_PAIR_DE).run(0x1A) ); } @Test public void testLD_A_REF_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .verifyRegister(REG_A, context -> context.second & 0xFF); + .firstIsAddressAndSecondIsMemoryByte() + .verifyRegister(REG_A, context -> context.second & 0xFF); Generator.forSome16bitBinary(3, - test.runWithFirstOperand(0x3A) + test.runWithFirstOperand(0x3A) ); } @Test public void testLD_REF_RP_A() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .first8LSBisRegister(REG_A) - .verifyByte(context -> context.first, context -> context.first & 0xFF) - .keepCurrentInjectorsAfterRun(); + .firstIsAddressAndSecondIsMemoryByte() + .first8LSBisRegister(REG_A) + .verifyByte(context -> context.first, context -> context.first & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(1, - test.firstIsPair(REG_PAIR_BC).run(0x02), - test.firstIsPair(REG_PAIR_DE).run(0x12) + test.firstIsPair(REG_PAIR_BC).run(0x02), + test.firstIsPair(REG_PAIR_DE).run(0x12) ); } @Test public void testLD_REF_NN_A() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .first8LSBisRegister(REG_A) - .verifyByte(context -> context.first, context -> context.first & 0xFF); + .firstIsAddressAndSecondIsMemoryByte() + .first8LSBisRegister(REG_A) + .verifyByte(context -> context.first, context -> context.first & 0xFF); Generator.forSome16bitBinary( - test.runWithFirstOperand(0x32) + test.runWithFirstOperand(0x32) ); } @Test public void testLD_A_I() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .secondIsRegisterI() - .setFlags(FLAG_H | FLAG_N) - .verifyRegister(REG_A, context -> context.second & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> cpuRunnerImpl.getIFF(1)) - ); + .firstIsRegister(REG_A) + .secondIsRegisterI() + .setFlags(FLAG_H | FLAG_N) + .verifyRegister(REG_A, context -> context.second & 0xFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().halfCarryIsReset().subtractionIsReset() + .expectFlagOnlyWhen(FLAG_PV, (context, result) -> cpuRunnerImpl.getIFF(1)) + ); Generator.forSome8bitBinary( - test.run(0xED, 0x57) + test.run(0xED, 0x57) ); } @Test public void testLD_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(REG_A) - .secondIsRegisterR() - .setFlags(FLAG_H | FLAG_N) - .verifyRegister(REG_A, context -> (context.second & 0x80) | ((context.second & 0x7F) + 2) & 0x7F) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> cpuRunnerImpl.getIFF(1)) - ); + .firstIsRegister(REG_A) + .secondIsRegisterR() + .setFlags(FLAG_H | FLAG_N) + .verifyRegister(REG_A, context -> (context.second & 0x80) | ((context.second & 0x7F) + 2) & 0x7F) + .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().halfCarryIsReset().subtractionIsReset() + .expectFlagOnlyWhen(FLAG_PV, (context, result) -> cpuRunnerImpl.getIFF(1)) + ); Generator.forSome8bitBinary( - test.run(0xED, 0x5F) + test.run(0xED, 0x5F) ); } @Test public void testLD_I_A() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegisterI() - .secondIsRegister(REG_A) - .verifyRegisterI(context -> context.second & 0xFF); + .firstIsRegisterI() + .secondIsRegister(REG_A) + .verifyRegisterI(context -> context.second & 0xFF); Generator.forSome8bitBinary( - test.run(0xED, 0x47) + test.run(0xED, 0x47) ); } @Test public void testLD_R_A() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegisterR() - .secondIsRegister(REG_A) - .verifyRegisterR(context -> context.second & 0xFF); + .firstIsRegisterR() + .secondIsRegister(REG_A) + .verifyRegisterR(context -> context.second & 0xFF); Generator.forSome8bitBinary( - test.run(0xED, 0x4F) + test.run(0xED, 0x4F) ); } @Test public void testLD_RP_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .clearOtherVerifiersAfterRun(); + .clearOtherVerifiersAfterRun(); Generator.forSome16bitUnary( - test.verifyPair(REG_PAIR_BC, context -> context.first).runWithFirstOperand(0x01), - test.verifyPair(REG_PAIR_DE, context -> context.first).runWithFirstOperand(0x11), - test.verifyPair(REG_PAIR_HL, context -> context.first).runWithFirstOperand(0x21), - test.verifyPair(REG_SP, context -> context.first).runWithFirstOperand(0x31) + test.verifyPair(REG_PAIR_BC, context -> context.first).runWithFirstOperand(0x01), + test.verifyPair(REG_PAIR_DE, context -> context.first).runWithFirstOperand(0x11), + test.verifyPair(REG_PAIR_HL, context -> context.first).runWithFirstOperand(0x21), + test.verifyPair(REG_SP, context -> context.first).runWithFirstOperand(0x31) ); } @Test public void testLD_II_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .clearOtherVerifiersAfterRun(); + .clearOtherVerifiersAfterRun(); Generator.forSome16bitUnary( - test.verifyIX(context -> context.first).runWithFirstOperand(0xDD, 0x21), - test.verifyIY(context -> context.first).runWithFirstOperand(0xFD, 0x21) + test.verifyIX(context -> context.first).runWithFirstOperand(0xDD, 0x21), + test.verifyIY(context -> context.first).runWithFirstOperand(0xFD, 0x21) ); } @Test public void testLD_HL_REF_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .verifyPair(REG_PAIR_HL, context -> context.second); + .firstIsAddressAndSecondIsMemoryWord() + .verifyPair(REG_PAIR_HL, context -> context.second); Generator.forSome16bitBinary(3, - test.runWithFirstOperand(0x2A) + test.runWithFirstOperand(0x2A) ); } @Test public void testLD_RP_REF_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsAddressAndSecondIsMemoryWord() + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome16bitBinary(4, - test.verifyPair(REG_PAIR_BC, context -> context.second).runWithFirstOperand(0xED, 0x4B), - test.verifyPair(REG_PAIR_DE, context -> context.second).runWithFirstOperand(0xED, 0x5B), - test.verifyPair(REG_PAIR_HL, context -> context.second).runWithFirstOperand(0xED, 0x6B), - test.verifyPair(REG_SP, context -> context.second).runWithFirstOperand(0xED, 0x7B) + test.verifyPair(REG_PAIR_BC, context -> context.second).runWithFirstOperand(0xED, 0x4B), + test.verifyPair(REG_PAIR_DE, context -> context.second).runWithFirstOperand(0xED, 0x5B), + test.verifyPair(REG_PAIR_HL, context -> context.second).runWithFirstOperand(0xED, 0x6B), + test.verifyPair(REG_SP, context -> context.second).runWithFirstOperand(0xED, 0x7B) ); } @Test public void testLD_II_REF_NN() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsAddressAndSecondIsMemoryWord() + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome16bitBinary(4, - test.verifyIX(context -> context.second).runWithFirstOperand(0xDD, 0x2A), - test.verifyIY(context -> context.second).runWithFirstOperand(0xFD, 0x2A) + test.verifyIX(context -> context.second).runWithFirstOperand(0xDD, 0x2A), + test.verifyIY(context -> context.second).runWithFirstOperand(0xFD, 0x2A) ); } @Test public void testLD_REF_NN_HL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .firstIsPair(REG_PAIR_HL) - .verifyWord(context -> context.first, context -> context.first); + .firstIsAddressAndSecondIsMemoryWord() + .firstIsPair(REG_PAIR_HL) + .verifyWord(context -> context.first, context -> context.first); Generator.forSome16bitBinary(3, - test.runWithFirstOperand(0x22) + test.runWithFirstOperand(0x22) ); } @Test public void testLD_REF_NN_RP() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .verifyWord(context -> context.first, context -> context.first) - .keepCurrentInjectorsAfterRun(); + .firstIsAddressAndSecondIsMemoryWord() + .verifyWord(context -> context.first, context -> context.first) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(4, - test.firstIsPair(REG_PAIR_BC).runWithFirstOperand(0xED, 0x43), - test.firstIsPair(REG_PAIR_DE).runWithFirstOperand(0xED, 0x53), - test.firstIsPair(REG_PAIR_HL).runWithFirstOperand(0xED, 0x63), - test.firstIsPair(REG_SP).runWithFirstOperand(0xED, 0x73) + test.firstIsPair(REG_PAIR_BC).runWithFirstOperand(0xED, 0x43), + test.firstIsPair(REG_PAIR_DE).runWithFirstOperand(0xED, 0x53), + test.firstIsPair(REG_PAIR_HL).runWithFirstOperand(0xED, 0x63), + test.firstIsPair(REG_SP).runWithFirstOperand(0xED, 0x73) ); } @Test public void testLD_REF_NN_II() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .verifyWord(context -> context.first, context -> context.first) - .keepCurrentInjectorsAfterRun(); + .firstIsAddressAndSecondIsMemoryWord() + .verifyWord(context -> context.first, context -> context.first) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinary(4, - test.firstIsIX().runWithFirstOperand(0xDD, 0x22), - test.firstIsIY().runWithFirstOperand(0xFD, 0x22) + test.firstIsIX().runWithFirstOperand(0xDD, 0x22), + test.firstIsIY().runWithFirstOperand(0xFD, 0x22) ); } @Test public void testLD_SP_HL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsPair(REG_PAIR_HL) - .verifyPair(REG_SP, context -> context.first); + .firstIsPair(REG_PAIR_HL) + .verifyPair(REG_SP, context -> context.first); Generator.forSome16bitUnary( - test.run(0xF9) + test.run(0xF9) ); } @Test public void testLD_SP_II() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyPair(REG_SP, context -> context.first) - .clearOtherVerifiersAfterRun(); + .verifyPair(REG_SP, context -> context.first) + .clearOtherVerifiersAfterRun(); Generator.forSome16bitUnary( - test.firstIsIX().run(0xDD, 0xF9), - test.firstIsIY().run(0xFD, 0xF9) + test.firstIsIX().run(0xDD, 0xF9), + test.firstIsIY().run(0xFD, 0xF9) ); } @Test public void testEX_DE_HL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsPair(REG_PAIR_DE) - .secondIsPair(REG_PAIR_HL) - .verifyPair(REG_PAIR_DE, context -> context.second) - .verifyPair(REG_PAIR_HL, context -> context.first); + .firstIsPair(REG_PAIR_DE) + .secondIsPair(REG_PAIR_HL) + .verifyPair(REG_PAIR_DE, context -> context.second) + .verifyPair(REG_PAIR_HL, context -> context.first); Generator.forSome16bitBinary( - test.run(0xEB) + test.run(0xEB) ); } @Test public void testEX_AF_AF2() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAF() - .secondIsAF2() - .verifyAF(context -> context.second) - .verifyAF2(context -> context.first); + .firstIsAF() + .secondIsAF2() + .verifyAF(context -> context.second) + .verifyAF2(context -> context.first); Generator.forSome16bitBinary( - test.run(0x08) + test.run(0x08) ); } @Test public void testEXX() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsPair(REG_PAIR_BC) - .firstIsPair(REG_PAIR_DE) - .firstIsPair(REG_PAIR_HL) - .secondIsPair2(REG_PAIR_BC) - .secondIsPair2(REG_PAIR_DE) - .secondIsPair2(REG_PAIR_HL) - .verifyPair(REG_PAIR_BC, context -> context.second) - .verifyPair(REG_PAIR_DE, context -> context.second) - .verifyPair(REG_PAIR_HL, context -> context.second) - .verifyPair2(REG_PAIR_BC, context -> context.first) - .verifyPair2(REG_PAIR_DE, context -> context.first) - .verifyPair2(REG_PAIR_HL, context -> context.first); + .firstIsPair(REG_PAIR_BC) + .firstIsPair(REG_PAIR_DE) + .firstIsPair(REG_PAIR_HL) + .secondIsPair2(REG_PAIR_BC) + .secondIsPair2(REG_PAIR_DE) + .secondIsPair2(REG_PAIR_HL) + .verifyPair(REG_PAIR_BC, context -> context.second) + .verifyPair(REG_PAIR_DE, context -> context.second) + .verifyPair(REG_PAIR_HL, context -> context.second) + .verifyPair2(REG_PAIR_BC, context -> context.first) + .verifyPair2(REG_PAIR_DE, context -> context.first) + .verifyPair2(REG_PAIR_HL, context -> context.first); Generator.forSome16bitBinary( - test.run(0xD9) + test.run(0xD9) ); } @Test public void testEX_REF_SP_HL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .firstIsPair(REG_SP) - .firstIsPair(REG_PAIR_HL) - .verifyPair(REG_PAIR_HL, context -> context.second) - .verifyWord(context -> context.first, context -> context.first); + .firstIsAddressAndSecondIsMemoryWord() + .firstIsPair(REG_SP) + .firstIsPair(REG_PAIR_HL) + .verifyPair(REG_PAIR_HL, context -> context.second) + .verifyWord(context -> context.first, context -> context.first); Generator.forSome16bitBinary(1, - test.run(0xE3) + test.run(0xE3) ); } @Test public void testEX_REF_SP_II() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryWord() - .firstIsPair(REG_SP) - .verifyWord(context -> context.first, context -> context.first) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); + .firstIsAddressAndSecondIsMemoryWord() + .firstIsPair(REG_SP) + .verifyWord(context -> context.first, context -> context.first) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); Generator.forSome16bitBinary(2, - test.firstIsIX().verifyIX(context -> context.second).run(0xDD, 0xE3), - test.firstIsIY().verifyIY(context -> context.second).run(0xFD, 0xE3) + test.firstIsIX().verifyIX(context -> context.second).run(0xDD, 0xE3), + test.firstIsIY().verifyIY(context -> context.second).run(0xFD, 0xE3) ); } @@ -470,162 +470,162 @@ public void testEX_REF_SP_II() { @Test public void testLDI() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .secondIsAddressAndFirstIsMemoryByte() - .firstIsPair(REG_PAIR_DE) - .secondIsPair(REG_PAIR_HL) - .firstIsPair(REG_PAIR_BC) - .verifyByte(context -> context.first, context -> context.first & 0xFF) - .verifyPair(REG_PAIR_DE, context -> (context.first + 1) & 0xFFFF) - .verifyPair(REG_PAIR_HL, context -> (context.second + 1) & 0xFFFF) - .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsPreserved() - .zeroIsPreserved() - .signIsPreserved() - .halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) - ); + .firstIsAddressAndSecondIsMemoryByte() + .secondIsAddressAndFirstIsMemoryByte() + .firstIsPair(REG_PAIR_DE) + .secondIsPair(REG_PAIR_HL) + .firstIsPair(REG_PAIR_BC) + .verifyByte(context -> context.first, context -> context.first & 0xFF) + .verifyPair(REG_PAIR_DE, context -> (context.first + 1) & 0xFFFF) + .verifyPair(REG_PAIR_HL, context -> (context.second + 1) & 0xFFFF) + .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsPreserved() + .zeroIsPreserved() + .signIsPreserved() + .halfCarryIsReset().subtractionIsReset() + .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) + ); Generator.forSome16bitBinary(2, 2, - test.run(0xED, 0xA0) + test.run(0xED, 0xA0) ); } @Test public void testLDIR() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .secondIsAddressAndFirstIsMemoryByte() - .firstIsPair(REG_PAIR_DE) - .secondIsPair(REG_PAIR_HL) - .firstIsPair(REG_PAIR_BC) - .verifyByte(context -> context.first, context -> context.first & 0xFF) - .verifyPair(REG_PAIR_DE, context -> (context.first + 1) & 0xFFFF) - .verifyPair(REG_PAIR_HL, context -> (context.second + 1) & 0xFFFF) - .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) - .verifyR(context -> 2) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsPreserved() - .zeroIsPreserved() - .signIsPreserved() - .halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) - ).verifyPC(context -> { - if (((context.first - 1) & 0xFFFF) != 0) { - return context.PC; - } - return (context.PC + 2) & 0xFFFF; - }); + .firstIsAddressAndSecondIsMemoryByte() + .secondIsAddressAndFirstIsMemoryByte() + .firstIsPair(REG_PAIR_DE) + .secondIsPair(REG_PAIR_HL) + .firstIsPair(REG_PAIR_BC) + .verifyByte(context -> context.first, context -> context.first & 0xFF) + .verifyPair(REG_PAIR_DE, context -> (context.first + 1) & 0xFFFF) + .verifyPair(REG_PAIR_HL, context -> (context.second + 1) & 0xFFFF) + .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) + .verifyR(context -> 2) + .verifyFlagsOfLastOp(new FlagsCheckImpl() + .carryIsPreserved() + .zeroIsPreserved() + .signIsPreserved() + .halfCarryIsReset().subtractionIsReset() + .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) + ).verifyPC(context -> { + if (((context.first - 1) & 0xFFFF) != 0) { + return context.PC; + } + return (context.PC + 2) & 0xFFFF; + }); Generator.forSome16bitBinary(2, 2, - test.run(0xED, 0xB0) + test.run(0xED, 0xB0) ); } @Test public void testLDD() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .secondIsAddressAndFirstIsMemoryByte() - .firstIsPair(REG_PAIR_DE) - .secondIsPair(REG_PAIR_HL) - .firstIsPair(REG_PAIR_BC) - .verifyByte(context -> context.first, context -> context.first & 0xFF) - .verifyPair(REG_PAIR_DE, context -> (context.first - 1) & 0xFFFF) - .verifyPair(REG_PAIR_HL, context -> (context.second - 1) & 0xFFFF) - .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) - ); + .firstIsAddressAndSecondIsMemoryByte() + .secondIsAddressAndFirstIsMemoryByte() + .firstIsPair(REG_PAIR_DE) + .secondIsPair(REG_PAIR_HL) + .firstIsPair(REG_PAIR_BC) + .verifyByte(context -> context.first, context -> context.first & 0xFF) + .verifyPair(REG_PAIR_DE, context -> (context.first - 1) & 0xFFFF) + .verifyPair(REG_PAIR_HL, context -> (context.second - 1) & 0xFFFF) + .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl().halfCarryIsReset().subtractionIsReset() + .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) + ); Generator.forSome16bitBinary(2, 2, - test.run(0xED, 0xA8) + test.run(0xED, 0xA8) ); } @Test public void testLDDR() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .secondIsAddressAndFirstIsMemoryByte() - .firstIsPair(REG_PAIR_DE) - .secondIsPair(REG_PAIR_HL) - .firstIsPair(REG_PAIR_BC) - .verifyByte(context -> context.first, context -> context.first & 0xFF) - .verifyPair(REG_PAIR_DE, context -> (context.first - 1) & 0xFFFF) - .verifyPair(REG_PAIR_HL, context -> (context.second - 1) & 0xFFFF) - .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) - ).verifyPC(context -> { - if (((context.first - 1) & 0xFFFF) != 0) { - return context.PC; - } - return (context.PC + 2) & 0xFFFF; - }); + .firstIsAddressAndSecondIsMemoryByte() + .secondIsAddressAndFirstIsMemoryByte() + .firstIsPair(REG_PAIR_DE) + .secondIsPair(REG_PAIR_HL) + .firstIsPair(REG_PAIR_BC) + .verifyByte(context -> context.first, context -> context.first & 0xFF) + .verifyPair(REG_PAIR_DE, context -> (context.first - 1) & 0xFFFF) + .verifyPair(REG_PAIR_HL, context -> (context.second - 1) & 0xFFFF) + .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) + .verifyFlagsOfLastOp(new FlagsCheckImpl().halfCarryIsReset().subtractionIsReset() + .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) + ).verifyPC(context -> { + if (((context.first - 1) & 0xFFFF) != 0) { + return context.PC; + } + return (context.PC + 2) & 0xFFFF; + }); Generator.forSome16bitBinary(2, 2, - test.run(0xED, 0xB8) + test.run(0xED, 0xB8) ); } @Test public void testLD_IXH_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .secondIsIX() - .verifyIX(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); + .secondIsIX() + .verifyIX(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); Generator.forSome16bitBinary( - test.runWithFirst8bitOperand(0xDD, 0x26) + test.runWithFirst8bitOperand(0xDD, 0x26) ); } @Test public void testLD_IYH_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .secondIsIY() - .verifyIY(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); + .secondIsIY() + .verifyIY(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); Generator.forSome16bitBinary( - test.runWithFirst8bitOperand(0xFD, 0x26) + test.runWithFirst8bitOperand(0xFD, 0x26) ); } @Test public void testLD_IXL_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .secondIsIX() - .verifyIX(context -> (context.second & 0xFF00) | (context.first & 0xFF)); + .secondIsIX() + .verifyIX(context -> (context.second & 0xFF00) | (context.first & 0xFF)); Generator.forSome16bitBinary( - test.runWithFirst8bitOperand(0xDD, 0x2E) + test.runWithFirst8bitOperand(0xDD, 0x2E) ); } @Test public void testLD_IYL_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .secondIsIY() - .verifyIY(context -> (context.second & 0xFF00) | (context.first & 0xFF)); + .secondIsIY() + .verifyIY(context -> (context.second & 0xFF00) | (context.first & 0xFF)); Generator.forSome16bitBinary( - test.runWithFirst8bitOperand(0xFD, 0x2E) + test.runWithFirst8bitOperand(0xFD, 0x2E) ); } @Test public void testLD_R_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); - int[][] regOpcodes = { {REG_B, 0x44}, {REG_C, 0x4C}, {REG_D, 0x54}, {REG_E, 0x5C}, {REG_A, 0x7C} }; + int[][] regOpcodes = {{REG_B, 0x44}, {REG_C, 0x4C}, {REG_D, 0x54}, {REG_E, 0x5C}, {REG_A, 0x7C}}; for (int[] regOpcode : regOpcodes) { test.secondIsIX() - .first8LSBisRegister(regOpcode[0]) - .verifyRegister(regOpcode[0], context -> (context.second >>> 8) & 0xFF); + .first8LSBisRegister(regOpcode[0]) + .verifyRegister(regOpcode[0], context -> (context.second >>> 8) & 0xFF); Generator.forSome16bitBinary( - test.run(0xDD, regOpcode[1]) + test.run(0xDD, regOpcode[1]) ); } } @@ -633,15 +633,15 @@ public void testLD_R_IXH() { @Test public void testLD_R_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); - int[][] regOpcodes = { {REG_B, 0x45}, {REG_C, 0x4D}, {REG_D, 0x55}, {REG_E, 0x5D}, {REG_A, 0x7D} }; + int[][] regOpcodes = {{REG_B, 0x45}, {REG_C, 0x4D}, {REG_D, 0x55}, {REG_E, 0x5D}, {REG_A, 0x7D}}; for (int[] regOpcode : regOpcodes) { test.secondIsIX() - .first8LSBisRegister(regOpcode[0]) - .verifyRegister(regOpcode[0], context -> context.second & 0xFF); + .first8LSBisRegister(regOpcode[0]) + .verifyRegister(regOpcode[0], context -> context.second & 0xFF); Generator.forSome16bitBinary( - test.run(0xDD, regOpcode[1]) + test.run(0xDD, regOpcode[1]) ); } } @@ -649,15 +649,15 @@ public void testLD_R_IXL() { @Test public void testLD_R_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); - int[][] regOpcodes = { {REG_B, 0x44}, {REG_C, 0x4C}, {REG_D, 0x54}, {REG_E, 0x5C}, {REG_A, 0x7C} }; + int[][] regOpcodes = {{REG_B, 0x44}, {REG_C, 0x4C}, {REG_D, 0x54}, {REG_E, 0x5C}, {REG_A, 0x7C}}; for (int[] regOpcode : regOpcodes) { test.secondIsIY() - .first8LSBisRegister(regOpcode[0]) - .verifyRegister(regOpcode[0], context -> (context.second >>> 8) & 0xFF); + .first8LSBisRegister(regOpcode[0]) + .verifyRegister(regOpcode[0], context -> (context.second >>> 8) & 0xFF); Generator.forSome16bitBinary( - test.run(0xFD, regOpcode[1]) + test.run(0xFD, regOpcode[1]) ); } } @@ -665,15 +665,15 @@ public void testLD_R_IYH() { @Test public void testLD_R_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); - int[][] regOpcodes = { {REG_B, 0x45}, {REG_C, 0x4D}, {REG_D, 0x55}, {REG_E, 0x5D}, {REG_A, 0x7D} }; + int[][] regOpcodes = {{REG_B, 0x45}, {REG_C, 0x4D}, {REG_D, 0x55}, {REG_E, 0x5D}, {REG_A, 0x7D}}; for (int[] regOpcode : regOpcodes) { test.secondIsIY() - .first8LSBisRegister(regOpcode[0]) - .verifyRegister(regOpcode[0], context -> context.second & 0xFF); + .first8LSBisRegister(regOpcode[0]) + .verifyRegister(regOpcode[0], context -> context.second & 0xFF); Generator.forSome16bitBinary( - test.run(0xFD, regOpcode[1]) + test.run(0xFD, regOpcode[1]) ); } } @@ -681,15 +681,15 @@ public void testLD_R_IYL() { @Test public void testLD_IXH_R() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); - int[][] regOpcodes = { {REG_B, 0x60}, {REG_C, 0x61}, {REG_D, 0x62}, {REG_E, 0x63}, {REG_A, 0x67} }; + int[][] regOpcodes = {{REG_B, 0x60}, {REG_C, 0x61}, {REG_D, 0x62}, {REG_E, 0x63}, {REG_A, 0x67}}; for (int[] regOpcode : regOpcodes) { test.secondIsIX() - .first8LSBisRegister(regOpcode[0]) - .verifyIX(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); + .first8LSBisRegister(regOpcode[0]) + .verifyIX(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); Generator.forSome16bitBinary( - test.run(0xDD, regOpcode[1]) + test.run(0xDD, regOpcode[1]) ); } } @@ -697,15 +697,15 @@ public void testLD_IXH_R() { @Test public void testLD_IYH_R() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); - int[][] regOpcodes = { {REG_B, 0x60}, {REG_C, 0x61}, {REG_D, 0x62}, {REG_E, 0x63}, {REG_A, 0x67} }; + int[][] regOpcodes = {{REG_B, 0x60}, {REG_C, 0x61}, {REG_D, 0x62}, {REG_E, 0x63}, {REG_A, 0x67}}; for (int[] regOpcode : regOpcodes) { test.secondIsIY() - .first8LSBisRegister(regOpcode[0]) - .verifyIY(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); + .first8LSBisRegister(regOpcode[0]) + .verifyIY(context -> (context.second & 0xFF) | ((context.first << 8) & 0xFF00)); Generator.forSome16bitBinary( - test.run(0xFD, regOpcode[1]) + test.run(0xFD, regOpcode[1]) ); } } @@ -713,37 +713,37 @@ public void testLD_IYH_R() { @Test public void testLD_IXH_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIX() - .verifyIX(context -> ((context.first << 8) & 0xFF00) | (context.first & 0xFF)); + .firstIsIX() + .verifyIX(context -> ((context.first << 8) & 0xFF00) | (context.first & 0xFF)); Generator.forSome16bitBinary( - test.run(0xDD, 0x65) + test.run(0xDD, 0x65) ); } @Test public void testLD_IYH_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIY() - .verifyIY(context -> ((context.first << 8) & 0xFF00) | (context.first & 0xFF)); + .firstIsIY() + .verifyIY(context -> ((context.first << 8) & 0xFF00) | (context.first & 0xFF)); Generator.forSome16bitBinary( - test.run(0xFD, 0x65) + test.run(0xFD, 0x65) ); } @Test public void testLD_IXL_R() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); - int[][] regOpcodes = { {REG_B, 0x68}, {REG_C, 0x69}, {REG_D, 0x6A}, {REG_E, 0x6B}, {REG_A, 0x6F} }; + int[][] regOpcodes = {{REG_B, 0x68}, {REG_C, 0x69}, {REG_D, 0x6A}, {REG_E, 0x6B}, {REG_A, 0x6F}}; for (int[] regOpcode : regOpcodes) { test.secondIsIX() - .first8LSBisRegister(regOpcode[0]) - .verifyIX(context -> (context.second & 0xFF00) | (context.first & 0xFF)); + .first8LSBisRegister(regOpcode[0]) + .verifyIX(context -> (context.second & 0xFF00) | (context.first & 0xFF)); Generator.forSome16bitBinary( - test.run(0xDD, regOpcode[1]) + test.run(0xDD, regOpcode[1]) ); } } @@ -751,15 +751,15 @@ public void testLD_IXL_R() { @Test public void testLD_IYL_R() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl); - int[][] regOpcodes = { {REG_B, 0x68}, {REG_C, 0x69}, {REG_D, 0x6A}, {REG_E, 0x6B}, {REG_A, 0x6F} }; + int[][] regOpcodes = {{REG_B, 0x68}, {REG_C, 0x69}, {REG_D, 0x6A}, {REG_E, 0x6B}, {REG_A, 0x6F}}; for (int[] regOpcode : regOpcodes) { test.secondIsIY() - .first8LSBisRegister(regOpcode[0]) - .verifyIY(context -> (context.second & 0xFF00) | (context.first & 0xFF)); + .first8LSBisRegister(regOpcode[0]) + .verifyIY(context -> (context.second & 0xFF00) | (context.first & 0xFF)); Generator.forSome16bitBinary( - test.run(0xFD, regOpcode[1]) + test.run(0xFD, regOpcode[1]) ); } } @@ -767,65 +767,65 @@ public void testLD_IYL_R() { @Test public void testLD_IXL_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIX() - .verifyIX(context -> (context.first >>> 8) | (context.first & 0xFF00)); + .firstIsIX() + .verifyIX(context -> (context.first >>> 8) | (context.first & 0xFF00)); Generator.forSome16bitBinary( - test.run(0xDD, 0x6C) + test.run(0xDD, 0x6C) ); } @Test public void testLD_IYL_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsIY() - .verifyIY(context -> (context.first >>> 8) | (context.first & 0xFF00)); + .firstIsIY() + .verifyIY(context -> (context.first >>> 8) | (context.first & 0xFF00)); Generator.forSome16bitBinary( - test.run(0xFD, 0x6C) + test.run(0xFD, 0x6C) ); } private void runLD_R_R_test(int register, int... opcodes) { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(register) - .verifyRegister(register, context -> context.second & 0xFF) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(register) + .verifyRegister(register, context -> context.second & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinary( - test.secondIsRegister(REG_B).run(opcodes[0]), - test.secondIsRegister(REG_C).run(opcodes[1]), - test.secondIsRegister(REG_D).run(opcodes[2]), - test.secondIsRegister(REG_E).run(opcodes[3]), - test.secondIsRegister(REG_H).run(opcodes[4]), - test.secondIsRegister(REG_L).run(opcodes[5]), - test.secondIsMemoryByteAt(0x303).setPair(REG_PAIR_HL, 0x303).run(opcodes[6]), - test.secondIsRegister(REG_A).run(opcodes[7]) + test.secondIsRegister(REG_B).run(opcodes[0]), + test.secondIsRegister(REG_C).run(opcodes[1]), + test.secondIsRegister(REG_D).run(opcodes[2]), + test.secondIsRegister(REG_E).run(opcodes[3]), + test.secondIsRegister(REG_H).run(opcodes[4]), + test.secondIsRegister(REG_L).run(opcodes[5]), + test.secondIsMemoryByteAt(0x303).setPair(REG_PAIR_HL, 0x303).run(opcodes[6]), + test.secondIsRegister(REG_A).run(opcodes[7]) ); } private void runLD_R_N_test(int register, int opcode) { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(register) - .verifyRegister(register, context -> context.second & 0xFF) - .keepCurrentInjectorsAfterRun(); + .firstIsRegister(register) + .verifyRegister(register, context -> context.second & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinary( - test.runWithSecondOperand(opcode) + test.runWithSecondOperand(opcode) ); } private void runLD_R_REF_II_N(int register, int opcode) { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8LSBisRegister(register) - .verifyRegister(register, context -> context.second & 0xFF) - .keepCurrentInjectorsAfterRun(); + .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() + .first8LSBisRegister(register) + .verifyRegister(register, context -> context.second & 0xFF) + .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), - test.first8MSBisIX().runWithFirst8bitOperand(0xDD, opcode), - test.first8MSBisIY().runWithFirst8bitOperand(0xFD, opcode) + test.first8MSBisIX().runWithFirst8bitOperand(0xDD, opcode), + test.first8MSBisIY().runWithFirst8bitOperand(0xFD, opcode) ); } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java index 9dbe763b9..ca9a83541 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java @@ -68,7 +68,7 @@ public ByteTestBuilder secondIsFlags() { public ByteTestBuilder firstIsDeviceAndSecondIsPort() { runner.injectTwoOperands((tmpRunner, first, second) -> - cpuRunner.getDevice(second.intValue() & 0xFF).setValue(first)); + cpuRunner.getDevice(second.intValue() & 0xFF).setValue(first)); return this; } @@ -79,8 +79,8 @@ public ByteTestBuilder setRegister(int register, int value) { public ByteTestBuilder setPair(int registerPair, int value) { runner.injectFirst( - (tmpRunner, argument) -> tmpRunner.ensureProgramSize(value + 1), - (tmpRunner, argument) -> cpuRunner.setRegisterPair(registerPair, value) + (tmpRunner, argument) -> tmpRunner.ensureProgramSize(value + 1), + (tmpRunner, argument) -> cpuRunner.setRegisterPair(registerPair, value) ); return this; } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java index aebb41b9f..b654b23a1 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java @@ -124,11 +124,6 @@ public int getSP() { return cpu.getEngine().SP; } - @Override - public void setFlags(int mask) { - cpu.getEngine().flags |= mask; - } - public void setFlags2(int mask) { cpu.getEngine().flags2 |= mask; } @@ -146,6 +141,11 @@ public int getFlags() { return cpu.getEngine().flags; } + @Override + public void setFlags(int mask) { + cpu.getEngine().flags |= mask; + } + public void setIX(int ix) { cpu.getEngine().IX = ix; } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java index 7a155f853..db26d1d68 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuVerifierImpl.java @@ -39,11 +39,40 @@ public CpuVerifierImpl(CpuImpl cpu, ByteMemoryStub memoryStub, List !"); @@ -143,8 +171,8 @@ public void checkRegisterPairPSW(int registerPair, int value) { public void checkPC(int PC) { assertEquals( - String.format("Expected PC=%04x, but was %04x", PC, cpu.getEngine().PC), - PC, cpu.getEngine().PC + String.format("Expected PC=%04x, but was %04x", PC, cpu.getEngine().PC), + PC, cpu.getEngine().PC ); } @@ -160,58 +188,29 @@ public void checkIntMode(int mode) { assertEquals(mode, cpu.getEngine().interruptMode); } - public static String intToFlags(int flags) { - String flagsString = ""; - if ((flags & FLAG_S) == FLAG_S) { - flagsString += "S"; - } - if ((flags & FLAG_Z) == FLAG_Z) { - flagsString += "Z"; - } - if ((flags & FLAG_Y) == FLAG_Y) { - flagsString += "Y"; - } - if ((flags & FLAG_H) == FLAG_H) { - flagsString += "H"; - } - if ((flags & FLAG_X) == FLAG_X) { - flagsString += "X"; - } - if ((flags & FLAG_PV) == FLAG_PV) { - flagsString += "P"; - } - if ((flags & FLAG_N) == FLAG_N) { - flagsString += "N"; - } - if ((flags & FLAG_C) == FLAG_C) { - flagsString += "C"; - } - return flagsString; - } - @Override public void checkFlags(int mask) { assertEquals(String.format("Expected flags=%s, but was %s", - intToFlags(mask), intToFlags(cpu.getEngine().flags)), mask, (cpu.getEngine().flags & mask)); + intToFlags(mask), intToFlags(cpu.getEngine().flags)), mask, (cpu.getEngine().flags & mask)); } @Override public void checkNotFlags(int mask) { assertEquals(String.format("Expected NOT flags=%s, but was %s", - intToFlags(mask), intToFlags(cpu.getEngine().flags)), 0, (cpu.getEngine().flags & mask)); + intToFlags(mask), intToFlags(cpu.getEngine().flags)), 0, (cpu.getEngine().flags & mask)); } public void checkI(int value) { assertEquals( - String.format("Expected I=%02x, but was %02x", value, cpu.getEngine().I), - value, cpu.getEngine().I + String.format("Expected I=%02x, but was %02x", value, cpu.getEngine().I), + value, cpu.getEngine().I ); } public void checkR(int value) { assertEquals( - String.format("Expected R=%02x, but was %02x", value, cpu.getEngine().R), - value, cpu.getEngine().R + String.format("Expected R=%02x, but was %02x", value, cpu.getEngine().R), + value, cpu.getEngine().R ); } @@ -219,8 +218,8 @@ public void checkAF(int value) { int af = (cpu.getEngine().regs[REG_A] << 8) | cpu.getEngine().flags; assertEquals( - String.format("Expected AF=%04x, but was %04x", value, af), - value, af + String.format("Expected AF=%04x, but was %04x", value, af), + value, af ); } @@ -229,16 +228,16 @@ public void checkAF2(int value) { int af = (cpu.getEngine().regs2[REG_A] << 8) | cpu.getEngine().flags2; assertEquals( - String.format("Expected AF2=%04x, but was %04x", value, af), - value, af + String.format("Expected AF2=%04x, but was %04x", value, af), + value, af ); } public void checkDeviceValue(int port, int expected) { int value = devices.get(port & 0xFF).getValue() & 0xFF; assertEquals( - String.format("Expected device[%02x]=%02x, but was %02x", port, expected, value), - expected, value + String.format("Expected device[%02x]=%02x, but was %02x", port, expected, value), + expected, value ); } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java index 43f0e1c1f..eeb528475 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java @@ -30,6 +30,18 @@ public class FlagsCheckImpl extends FlagsCheck, Integer> first = context -> context.first.intValue(); private Function, Integer> second = context -> context.second.intValue(); + public static boolean isParity(int value) { + int numberOfOnes = 0; + + for (int i = 0; i < 8; i++) { + if ((value & 1) == 1) { + numberOfOnes++; + } + value = value >>> 1; + } + return numberOfOnes % 2 == 0; + } + public FlagsCheckImpl setFirst(Function, Integer> first) { this.first = Objects.requireNonNull(first); return this; @@ -390,16 +402,4 @@ public FlagsCheckImpl signIsPreserved() { }); return this; } - - public static boolean isParity(int value) { - int numberOfOnes = 0; - - for (int i = 0; i < 8; i++) { - if ((value & 1) == 1) { - numberOfOnes++; - } - value = value >>> 1; - } - return numberOfOnes % 2 == 0; - } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/IntegerTestBuilder.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/IntegerTestBuilder.java index bc53930ab..28fb008aa 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/IntegerTestBuilder.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/IntegerTestBuilder.java @@ -100,14 +100,14 @@ public IntegerTestBuilder first8MSBisIY() { public IntegerTestBuilder first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() { runner.injectTwoOperands((tmpRunner, first, second) -> - new MemoryByte<>(get8MSBplus8LSB(first)).accept(tmpRunner, second.byteValue()) + new MemoryByte<>(get8MSBplus8LSB(first)).accept(tmpRunner, second.byteValue()) ); return this; } public IntegerTestBuilder first8MSBplus8LSBisMemoryByte(int value) { runner.injectTwoOperands((tmpRunner, first, second) -> - new MemoryByte<>(get8MSBplus8LSB(first)).accept(tmpRunner, (byte) value) + new MemoryByte<>(get8MSBplus8LSB(first)).accept(tmpRunner, (byte) value) ); return this; } @@ -137,7 +137,7 @@ public IntegerTestBuilder secondIsAF2() { public IntegerTestBuilder first8MSBisDeviceAndFirst8LSBIsPort() { runner.injectFirst((tmpRunner, first) -> - cpuRunner.getDevice(first & 0xFF).setValue((byte) ((first >>> 8) & 0xFF))); + cpuRunner.getDevice(first & 0xFF).setValue((byte) ((first >>> 8) & 0xFF))); return this; } diff --git a/plugins/device/88-dcdd/build.gradle b/plugins/device/88-dcdd/build.gradle index 6ad58cc1d..22ef8f82a 100644 --- a/plugins/device/88-dcdd/build.gradle +++ b/plugins/device/88-dcdd/build.gradle @@ -49,8 +49,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java index 378a02371..39c6d8c8a 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DeviceImpl.java @@ -38,8 +38,8 @@ import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; @PluginRoot( - type = PLUGIN_TYPE.DEVICE, - title = "MITS 88-DCDD" + type = PLUGIN_TYPE.DEVICE, + title = "MITS 88-DCDD" ) public class DeviceImpl extends AbstractDevice { private final DiskSettings settings; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java index 33a44f02a..c8486d0b3 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/DiskSettings.java @@ -46,37 +46,12 @@ public class DiskSettings { private final BasicSettings settings; private final List observers = new CopyOnWriteArrayList<>(); - + private final DriveSettings[] driveSettings = new DriveSettings[16]; private volatile int port1CPU; private volatile int port2CPU; private volatile int port3CPU; private volatile int interruptVector; private volatile boolean interruptsSupported; - private final DriveSettings[] driveSettings = new DriveSettings[16]; - - @FunctionalInterface - public interface SettingsObserver { - - void settingsChanged(); - } - - @Immutable - public static class DriveSettings { - public final static DriveSettings DEFAULT = new DriveSettings( - DEFAULT_SECTOR_SIZE, DEFAULT_SECTORS_PER_TRACK, null, false); - - public final int sectorSize; - public final int sectorsPerTrack; - public final String imagePath; - public final boolean mounted; - - public DriveSettings(int sectorSize, int sectorsPerTrack, String imagePath, boolean mounted) { - this.sectorSize = sectorSize; - this.sectorsPerTrack = sectorsPerTrack; - this.imagePath = imagePath; - this.mounted = mounted; - } - } public DiskSettings(BasicSettings settings) { this.settings = Objects.requireNonNull(settings); @@ -89,10 +64,10 @@ public DiskSettings(BasicSettings settings) { for (int i = 0; i < driveSettings.length; i++) { driveSettings[i] = new DriveSettings( - settings.getInt(KEY_SECTOR_SIZE + i, DEFAULT_SECTOR_SIZE), - settings.getInt(KEY_SECTORS_PER_TRACK + i, DEFAULT_SECTORS_PER_TRACK), - settings.getString(KEY_IMAGE + i, null), - settings.getBoolean(KEY_IMAGE_MOUNTED + i, false)); + settings.getInt(KEY_SECTOR_SIZE + i, DEFAULT_SECTOR_SIZE), + settings.getInt(KEY_SECTORS_PER_TRACK + i, DEFAULT_SECTORS_PER_TRACK), + settings.getString(KEY_IMAGE + i, null), + settings.getBoolean(KEY_IMAGE_MOUNTED + i, false)); } } @@ -190,4 +165,28 @@ public void setInterruptsSupported(boolean value) { private void notifySettingsChanged() { observers.forEach(SettingsObserver::settingsChanged); } + + @FunctionalInterface + public interface SettingsObserver { + + void settingsChanged(); + } + + @Immutable + public static class DriveSettings { + public final static DriveSettings DEFAULT = new DriveSettings( + DEFAULT_SECTOR_SIZE, DEFAULT_SECTORS_PER_TRACK, null, false); + + public final int sectorSize; + public final int sectorsPerTrack; + public final String imagePath; + public final boolean mounted; + + public DriveSettings(int sectorSize, int sectorsPerTrack, String imagePath, boolean mounted) { + this.sectorSize = sectorSize; + this.sectorsPerTrack = sectorsPerTrack; + this.imagePath = imagePath; + this.mounted = mounted; + } + } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Resources.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Resources.java index 2f360cdd1..8d72c2ca6 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Resources.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/Resources.java @@ -22,7 +22,7 @@ import java.util.Optional; import java.util.ResourceBundle; -public class Resources{ +public class Resources { public static Optional getResourceBundle() { try { diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cmdline/Cpmfs.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cmdline/Cpmfs.java index e0f8a7e5b..cd283d259 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cmdline/Cpmfs.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cmdline/Cpmfs.java @@ -41,8 +41,8 @@ public class Cpmfs { @Command(header = "Show file content", name = "cat", description = "Prints the file in CP/M disk image") public void cat( - @Parameters(paramLabel = "FILE", description = "file name in CP/M disk image") - String fileName) throws IOException { + @Parameters(paramLabel = "FILE", description = "file name in CP/M disk image") + String fileName) throws IOException { System.out.println(cpmfs().readFile(cpmfile(fileName))); } @@ -50,8 +50,8 @@ public void cat( public void ls() { System.out.println(CpmFile.getLongHeader()); cpmfs() - .listExistingFiles() - .forEach(f -> System.out.println(f.toLongString())); + .listExistingFiles() + .forEach(f -> System.out.println(f.toLongString())); } @Command(header = "Show files dates", name = "dates", description = "Prints all valid file names in CP/M disk image with dates") @@ -61,7 +61,7 @@ public void dates() { cpmfs().listNativeDates().forEach(System.out::println); } - @Command(header = "Copy files", name = "copy", aliases = { "cp"}, description = "Copy a file between CP/M disk image and host") + @Command(header = "Copy files", name = "copy", aliases = {"cp"}, description = "Copy a file between CP/M disk image and host") public void copy(@Parameters(paramLabel = "SRC_FILE", index = "0", description = "source file (cpm:// prefix if in CP/M disk image)") String src, @Parameters(paramLabel = "DST_FILE", index = "1", description = "destination file (cpm:// prefix if in CP/M disk image") diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cmdline/Runner.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cmdline/Runner.java index 4f70d6a8b..be787d6fa 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cmdline/Runner.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cmdline/Runner.java @@ -24,9 +24,9 @@ import net.emustudio.plugins.device.mits88dcdd.cpmfs.CpmFormat; import net.emustudio.plugins.device.mits88dcdd.cpmfs.DriveIO; import picocli.CommandLine; -import picocli.CommandLine.Option; import picocli.CommandLine.Command; import picocli.CommandLine.IVersionProvider; +import picocli.CommandLine.Option; import java.io.File; import java.io.IOException; @@ -39,26 +39,24 @@ @SuppressWarnings("unused") @Command( - name = "88-dcdd", - mixinStandardHelpOptions = true, - versionProvider = Runner.VersionProvider.class, - description = "88-DCDD Altair floppy disk drive", - scope = CommandLine.ScopeType.INHERIT, - subcommands = {Cpmfs.class} + name = "88-dcdd", + mixinStandardHelpOptions = true, + versionProvider = Runner.VersionProvider.class, + description = "88-DCDD Altair floppy disk drive", + scope = CommandLine.ScopeType.INHERIT, + subcommands = {Cpmfs.class} ) public class Runner implements Runnable { - @Option(names = {"-F", "--format-file"}, description = "disk format file (TOML)", paramLabel = "FILE") - private Path formatFile = new File(System.getProperty("user.dir")) - .toPath() - .resolve("examples") - .resolve("altair8800") - .resolve("cpm-formats.toml"); - @CommandLine.ArgGroup(multiplicity = "1") public Exclusive exclusive; - public CpmFileSystem cpmfs; + @Option(names = {"-F", "--format-file"}, description = "disk format file (TOML)", paramLabel = "FILE") + private Path formatFile = new File(System.getProperty("user.dir")) + .toPath() + .resolve("examples") + .resolve("altair8800") + .resolve("cpm-formats.toml"); public static void main(String[] args) { CommandLine cmdline = new CommandLine(new Runner()); @@ -77,19 +75,19 @@ public static void main(String[] args) { @Override public void run() { Optional - .ofNullable(exclusive) - .ifPresent(e -> { - if (e.listFormats) { - loadFormats().stream().map(f -> f.id).forEach(System.out::println); - return; - } - CpmFormat cpmFormat = findFormat(); - try { - cpmfs = new CpmFileSystem(new DriveIO(exclusive.dependent.imageFile, cpmFormat, READ, WRITE)); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - }); + .ofNullable(exclusive) + .ifPresent(e -> { + if (e.listFormats) { + loadFormats().stream().map(f -> f.id).forEach(System.out::println); + return; + } + CpmFormat cpmFormat = findFormat(); + try { + cpmfs = new CpmFileSystem(new DriveIO(exclusive.dependent.imageFile, cpmFormat, READ, WRITE)); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + }); } public List loadFormats() { @@ -101,9 +99,9 @@ public List loadFormats() { public CpmFormat findFormat() { Optional format = loadFormats() - .stream() - .filter(f -> f.id.equals(exclusive.dependent.formatId)) - .findAny(); + .stream() + .filter(f -> f.id.equals(exclusive.dependent.formatId)) + .findAny(); if (format.isEmpty()) { throw new IllegalArgumentException("Unknown CP/M disk format ID!"); } @@ -119,11 +117,10 @@ public String[] getVersion() { } static class Exclusive { - @Option(names = {"-l", "--list-formats"}, description = "lists available disk format IDs") - private boolean listFormats; - @CommandLine.ArgGroup(exclusive = false, multiplicity = "1") public Dependent dependent; + @Option(names = {"-l", "--list-formats"}, description = "lists available disk format IDs") + private boolean listFormats; } static class Dependent { diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFileSystem.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFileSystem.java index 06812a0a4..f05c47c7a 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFileSystem.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFileSystem.java @@ -31,11 +31,11 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import static net.emustudio.plugins.device.mits88dcdd.cpmfs.CpmFormat.ENTRIES_PER_RECORD; +import static net.emustudio.plugins.device.mits88dcdd.cpmfs.CpmFormat.RECORD_SIZE; import static net.emustudio.plugins.device.mits88dcdd.cpmfs.DateFormat.*; import static net.emustudio.plugins.device.mits88dcdd.cpmfs.entry.CpmFile.ENTRY_SIZE; import static net.emustudio.plugins.device.mits88dcdd.cpmfs.entry.CpmFile.RAW_BLOCK_POINTERS_COUNT; -import static net.emustudio.plugins.device.mits88dcdd.cpmfs.CpmFormat.ENTRIES_PER_RECORD; -import static net.emustudio.plugins.device.mits88dcdd.cpmfs.CpmFormat.RECORD_SIZE; import static net.emustudio.plugins.device.mits88dcdd.cpmfs.entry.CpmNativeDate.*; import static net.emustudio.plugins.device.mits88dcdd.cpmfs.entry.CpmPlusDiscLabel.STATUS_LABEL; @@ -46,36 +46,41 @@ public class CpmFileSystem { private final static int MAX_USER_NUMBER = 0x0F; private final static Format format = DateTimeFormatter.ofPattern("dd-MMM-yy HH.mma").toFormat(); - - private final DriveIO driveIO; public final CpmFormat cpmFormat; + private final DriveIO driveIO; public CpmFileSystem(DriveIO driveIO) { this.driveIO = Objects.requireNonNull(driveIO); this.cpmFormat = driveIO.cpmFormat; } + private static String getContent(ByteBuffer buffer, int extentBc) { + byte[] b = new byte[Math.min(extentBc == 0 ? RECORD_SIZE : extentBc, buffer.remaining())]; + buffer.get(b); + return new String(b); + } + public Stream listExistingFiles() { return listValidFiles().filter(file -> file.ex == 0); } public boolean exists(String fileName) { return listExistingFiles() - .anyMatch(file -> file.getFileName().toUpperCase().equals(fileName.toUpperCase(Locale.ENGLISH))); + .anyMatch(file -> file.getFileName().toUpperCase().equals(fileName.toUpperCase(Locale.ENGLISH))); } public String getLabel() { return readDirectoryBlocks() - .flatMap(i -> i.v.flatMap(this::getEntries)) - .filter(entry -> (CpmEntry.getStatus(entry) & 0xFF) == STATUS_LABEL) - .map(entry -> CpmPlusDiscLabel.fromEntry(entry).toString()) - .findAny().orElse(""); + .flatMap(i -> i.v.flatMap(this::getEntries)) + .filter(entry -> (CpmEntry.getStatus(entry) & 0xFF) == STATUS_LABEL) + .map(entry -> CpmPlusDiscLabel.fromEntry(entry).toString()) + .findAny().orElse(""); } public String readFile(String fileName) throws IOException { List entries = listValidFiles() - .filter(file -> file.getFileName().toUpperCase().equals(fileName.toUpperCase(Locale.ENGLISH))) - .collect(Collectors.toList()); + .filter(file -> file.getFileName().toUpperCase().equals(fileName.toUpperCase(Locale.ENGLISH))) + .collect(Collectors.toList()); if (entries.isEmpty()) { throw new IllegalArgumentException("File '" + fileName + "' not found!"); @@ -102,8 +107,8 @@ public String readFile(String fileName) throws IOException { int recordsCount = records.size(); records.stream() - .limit(recordsLeft) - .forEach(b -> content.append(getContent(b, extent.bc & 0xFF))); + .limit(recordsLeft) + .forEach(b -> content.append(getContent(b, extent.bc & 0xFF))); recordsLeft -= recordsCount; } @@ -174,13 +179,13 @@ public void writeFile(String fileName, String content) throws IOException { byte rc = (byte) lastBlock.size(); // assuming > 0 ByteBuffer lastRecord = lastBlock.get(lastBlock.size() - 1); byte bc = cpmFormat.bcInterpretsAsUnused ? - (byte) (RECORD_SIZE - lastRecord.remaining()) : - (byte) lastRecord.remaining(); + (byte) (RECORD_SIZE - lastRecord.remaining()) : + (byte) lastRecord.remaining(); // no flags setting supported yet CpmFile file = new CpmFile( - (byte) 0, fileName, 0, - extentIndex++, cpmFormat.dpb.exm, bc, rc, bpPerExtent + (byte) 0, fileName, 0, + extentIndex++, cpmFormat.dpb.exm, bc, rc, bpPerExtent ); // write extent to the directory block @@ -201,25 +206,25 @@ public void writeFile(String fileName, String content) throws IOException { */ public void removeFile(String fileName) { readDirectoryBlocks() - .map(i -> new I<>(i.index, i.v.map(this::getEntries))) - .map(i -> new I<>(i.index, i.v.map(entries -> entries.map(e -> { - CpmFile f = CpmFile.fromEntry(e, cpmFormat.dpb.exm); - boolean nameMatch = f.getFileName().toUpperCase(Locale.ENGLISH).equals(fileName.toUpperCase(Locale.ENGLISH)); - if ((f.status & 0xFF) != STATUS_UNUSED && nameMatch) { - return f.toEntry((byte) STATUS_UNUSED); - } else { - e.position(0); - } - return e; - })))) - .map(i -> new I<>(i.index, i.v.map(this::toRecord))) - .forEach(i -> { - try { - driveIO.writeBlock(i.index, i.v.collect(Collectors.toList())); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); + .map(i -> new I<>(i.index, i.v.map(this::getEntries))) + .map(i -> new I<>(i.index, i.v.map(entries -> entries.map(e -> { + CpmFile f = CpmFile.fromEntry(e, cpmFormat.dpb.exm); + boolean nameMatch = f.getFileName().toUpperCase(Locale.ENGLISH).equals(fileName.toUpperCase(Locale.ENGLISH)); + if ((f.status & 0xFF) != STATUS_UNUSED && nameMatch) { + return f.toEntry((byte) STATUS_UNUSED); + } else { + e.position(0); + } + return e; + })))) + .map(i -> new I<>(i.index, i.v.map(this::toRecord))) + .forEach(i -> { + try { + driveIO.writeBlock(i.index, i.v.collect(Collectors.toList())); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); } /** @@ -236,35 +241,35 @@ public List listNativeDates() { List previousFiles = new ArrayList<>(); return readDirectoryBlocks() - .flatMap(i -> i.v.flatMap(this::getEntries)) - .limit(cpmFormat.dpb.drm + 1) - .flatMap(entry -> { - int status = CpmEntry.getStatus(entry) & 0xFF; - if (status != STATUS_DATESTAMP) { - // even for labels and passwords. Every extent has it's datestamp. - previousFiles.add(CpmFile.fromEntry(entry, cpmFormat.dpb.exm)); - return Stream.empty(); - } else { - DateStamp[][] datestamps = CpmNativeDate.fromEntry(entry, cpmFormat.dateFormat).datestamps; - List sb = new ArrayList<>(); - - for (int j = 0; j < datestamps.length; j++) { - CpmFile prev = previousFiles.get(j); - if ((prev.status & 0xFF) <= MAX_USER_NUMBER && prev.ex == 0) { - String dates = - dformat(datestamps[j][CREATE].dateTime) + - " | " + dformat(datestamps[j][MODIFY].dateTime) + - " | " + dformat(datestamps[j][ACCESS].dateTime); - - sb.add(String.format("%12s : %s", prev.getFileName(), dates)); + .flatMap(i -> i.v.flatMap(this::getEntries)) + .limit(cpmFormat.dpb.drm + 1) + .flatMap(entry -> { + int status = CpmEntry.getStatus(entry) & 0xFF; + if (status != STATUS_DATESTAMP) { + // even for labels and passwords. Every extent has it's datestamp. + previousFiles.add(CpmFile.fromEntry(entry, cpmFormat.dpb.exm)); + return Stream.empty(); + } else { + DateStamp[][] datestamps = CpmNativeDate.fromEntry(entry, cpmFormat.dateFormat).datestamps; + List sb = new ArrayList<>(); + + for (int j = 0; j < datestamps.length; j++) { + CpmFile prev = previousFiles.get(j); + if ((prev.status & 0xFF) <= MAX_USER_NUMBER && prev.ex == 0) { + String dates = + dformat(datestamps[j][CREATE].dateTime) + + " | " + dformat(datestamps[j][MODIFY].dateTime) + + " | " + dformat(datestamps[j][ACCESS].dateTime); + + sb.add(String.format("%12s : %s", prev.getFileName(), dates)); + } } + previousFiles.clear(); + return sb.stream(); } - previousFiles.clear(); - return sb.stream(); - } - }) - .filter(str -> !str.trim().isEmpty()) - .collect(Collectors.toList()); + }) + .filter(str -> !str.trim().isEmpty()) + .collect(Collectors.toList()); } private String dformat(LocalDateTime time) { @@ -273,14 +278,14 @@ private String dformat(LocalDateTime time) { public List listPasswords() { return readDirectoryBlocks() - .flatMap(i -> i.v.flatMap(this::getEntries)) - .limit(cpmFormat.dpb.drm + 1) - .filter(entry -> { - int status = CpmEntry.getStatus(entry) & 0xFF; - return status > 0x0F && status <= (0x0F + 15); - }) - .map(entry -> CpmPlusPassword.fromEntry(entry).toString()) - .collect(Collectors.toList()); + .flatMap(i -> i.v.flatMap(this::getEntries)) + .limit(cpmFormat.dpb.drm + 1) + .filter(entry -> { + int status = CpmEntry.getStatus(entry) & 0xFF; + return status > 0x0F && status <= (0x0F + 15); + }) + .map(entry -> CpmPlusPassword.fromEntry(entry).toString()) + .collect(Collectors.toList()); } private List> writeContent(List> contentInBlocks) throws IOException { @@ -335,21 +340,20 @@ private List> splitToExtents(List contentInBlocks) { return extents; } - private Stream findFreeBlocks() { Set reservedBlocks = listValidFiles() - .flatMap(f -> { - List extents = new ArrayList<>(); - if (cpmFormat.blockPointerIsWord) { - for (int i = 0; i < RAW_BLOCK_POINTERS_COUNT; i += 2) { - extents.add((f.al.get(i + 1) << 8) | f.al.get(i)); + .flatMap(f -> { + List extents = new ArrayList<>(); + if (cpmFormat.blockPointerIsWord) { + for (int i = 0; i < RAW_BLOCK_POINTERS_COUNT; i += 2) { + extents.add((f.al.get(i + 1) << 8) | f.al.get(i)); + } + } else { + extents.addAll(f.al.stream().mapToInt(Byte::intValue).boxed().collect(Collectors.toList())); } - } else { - extents.addAll(f.al.stream().mapToInt(Byte::intValue).boxed().collect(Collectors.toList())); - } - return extents.stream(); - }).filter(b -> b != 0) - .collect(Collectors.toSet()); + return extents.stream(); + }).filter(b -> b != 0) + .collect(Collectors.toSet()); // first data block is located after directory blocks int firstBlock = cpmFormat.directoryBlocks.stream().max(Comparator.naturalOrder()).orElse(0) + 1; @@ -372,17 +376,17 @@ private Stream>>>> findFreeDataExtents() { return readDirectoryBlocks().map(block -> { AtomicInteger sectorIndex = new AtomicInteger(); return new I<>(block.index, block.v - .map(this::getEntries) - .map(filesInSector -> { - sectorIndex.set(0); - AtomicInteger entryIndex = new AtomicInteger(); - return new I<>(sectorIndex.getAndIncrement(), filesInSector - .map(f -> new I<>(entryIndex.getAndIncrement(), f)) - .filter(f -> (cpmFormat.dateFormat != NATIVE && cpmFormat.dateFormat != NATIVE2) || ((f.index + 1) % 4 != 0)) - .filter(f -> cpmFormat.dateFormat != DATE_STAMPER || (f.index != 0)) - .filter(f -> (CpmEntry.getStatus(f.v) & 0xFF) == STATUS_UNUSED) - .map(f -> f.index)); - })); + .map(this::getEntries) + .map(filesInSector -> { + sectorIndex.set(0); + AtomicInteger entryIndex = new AtomicInteger(); + return new I<>(sectorIndex.getAndIncrement(), filesInSector + .map(f -> new I<>(entryIndex.getAndIncrement(), f)) + .filter(f -> (cpmFormat.dateFormat != NATIVE && cpmFormat.dateFormat != NATIVE2) || ((f.index + 1) % 4 != 0)) + .filter(f -> cpmFormat.dateFormat != DATE_STAMPER || (f.index != 0)) + .filter(f -> (CpmEntry.getStatus(f.v) & 0xFF) == STATUS_UNUSED) + .map(f -> f.index)); + })); }); } @@ -424,14 +428,14 @@ record = ByteBuffer.allocate(RECORD_SIZE); */ private Stream>> readDirectoryBlocks() { return cpmFormat.directoryBlocks - .stream() - .map(d -> { - try { - return new I<>(d, driveIO.readBlock(d).stream()); - } catch (IOException e) { - throw new IllegalStateException(e); - } - }); + .stream() + .map(d -> { + try { + return new I<>(d, driveIO.readBlock(d).stream()); + } catch (IOException e) { + throw new IllegalStateException(e); + } + }); } private Stream getEntries(ByteBuffer record) { @@ -452,18 +456,12 @@ private ByteBuffer toRecord(Stream entries) { return record; } - private static String getContent(ByteBuffer buffer, int extentBc) { - byte[] b = new byte[Math.min(extentBc == 0 ? RECORD_SIZE : extentBc, buffer.remaining())]; - buffer.get(b); - return new String(b); - } - public Stream listValidFiles() { return readDirectoryBlocks() - .flatMap(i -> i.v.flatMap(this::getEntries)) - .limit(cpmFormat.dpb.drm + 1) - .filter(entry -> (CpmEntry.getStatus(entry) & 0xFF) <= MAX_USER_NUMBER) - .map(entry -> CpmFile.fromEntry(entry, cpmFormat.dpb.exm)); + .flatMap(i -> i.v.flatMap(this::getEntries)) + .limit(cpmFormat.dpb.drm + 1) + .filter(entry -> (CpmEntry.getStatus(entry) & 0xFF) <= MAX_USER_NUMBER) + .map(entry -> CpmFile.fromEntry(entry, cpmFormat.dpb.exm)); } /** diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java index 3c91d687a..b79183e7a 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/CpmFormat.java @@ -73,10 +73,10 @@ public CpmFormat(String id, this.dateFormat = Objects.requireNonNull(dateFormat, "Unknown date format"); this.sectorSkew = sectorSkew; this.sectorSkewTable = sectorSkew - .map(integer -> computeSectorSkewTable(integer, dpb.spt)) - .orElseGet(() -> sectorSkewTable - .map(NumberUtils::listToNativeInts) - .orElseGet(() -> computeSectorSkewTable(1, dpb.spt))); + .map(integer -> computeSectorSkewTable(integer, dpb.spt)) + .orElseGet(() -> sectorSkewTable + .map(NumberUtils::listToNativeInts) + .orElseGet(() -> computeSectorSkewTable(1, dpb.spt))); this.blockSize = RECORD_SIZE * (dpb.blm + 1); @@ -105,23 +105,6 @@ public CpmFormat(String id, this.bcInterpretsAsUnused = bcInterpretsAsUnused; } - public long positionToOffset(Position position) { - return (long) dpb.driveSpt * sectorSize * position.track + (long) sectorSize * sectorSkewTable[position.sector]; - } - - // so far it is not allowed to write to system/boot tracks - // block 0 is basically the first data block - public Position blockToPosition(int blockNumber) { - if (blockNumber > dpb.dsm) { - throw new IllegalArgumentException("Too big block number"); - } - int linearSector = blockNumber * recordsPerBlock + dpb.spt * dpb.ofs; - int sector = linearSector % dpb.spt; - int track = linearSector / dpb.spt; - return new Position(track, sector); - } - - private static int[] computeSectorSkewTable(int sectorSkew, int sectorsPerTrack) { int[] skewTable = new int[sectorsPerTrack]; int currentSkew = 0; @@ -146,43 +129,59 @@ private static int[] computeSectorSkewTable(int sectorSkew, int sectorsPerTrack) public static List fromConfig(Config config) { Optional> formats = config.getOptional("format"); return formats - .orElse(Collections.emptyList()) - .stream() - .map(c -> { - String id = c.get("id"); - int sectorSize = c.get("sectorSize"); - Optional sectorSkew = c.getOptional("sectorSkew"); - Optional> sectorSkewTable = c.getOptional("sectorSkewTable"); - boolean bcInterpretsAsUnused = c.getOptional("bcInterpretsAsUnused").orElse(false); - DateFormat dateFormat = c.getEnumOrElse("dateFormat", DateFormat.class, () -> DateFormat.NOT_USED); - SectorOps sectorOps = c - .getOptional("sectorOps") - .map(SectorOps::fromString) - .orElse(SectorOps.DUMMY); - - DiskParameterBlock dpb = DiskParameterBlock.fromConfig(c.get("dpb")); - - return new CpmFormat( - id, dpb, sectorSize, sectorSkew, sectorSkewTable, sectorOps, bcInterpretsAsUnused, dateFormat - ); - }).collect(Collectors.toList()); + .orElse(Collections.emptyList()) + .stream() + .map(c -> { + String id = c.get("id"); + int sectorSize = c.get("sectorSize"); + Optional sectorSkew = c.getOptional("sectorSkew"); + Optional> sectorSkewTable = c.getOptional("sectorSkewTable"); + boolean bcInterpretsAsUnused = c.getOptional("bcInterpretsAsUnused").orElse(false); + DateFormat dateFormat = c.getEnumOrElse("dateFormat", DateFormat.class, () -> DateFormat.NOT_USED); + SectorOps sectorOps = c + .getOptional("sectorOps") + .map(SectorOps::fromString) + .orElse(SectorOps.DUMMY); + + DiskParameterBlock dpb = DiskParameterBlock.fromConfig(c.get("dpb")); + + return new CpmFormat( + id, dpb, sectorSize, sectorSkew, sectorSkewTable, sectorOps, bcInterpretsAsUnused, dateFormat + ); + }).collect(Collectors.toList()); + } + + public long positionToOffset(Position position) { + return (long) dpb.driveSpt * sectorSize * position.track + (long) sectorSize * sectorSkewTable[position.sector]; + } + + // so far it is not allowed to write to system/boot tracks + // block 0 is basically the first data block + public Position blockToPosition(int blockNumber) { + if (blockNumber > dpb.dsm) { + throw new IllegalArgumentException("Too big block number"); + } + int linearSector = blockNumber * recordsPerBlock + dpb.spt * dpb.ofs; + int sector = linearSector % dpb.spt; + int track = linearSector / dpb.spt; + return new Position(track, sector); } @Override public String toString() { return "CP/M Format:\n" + - " ID: " + id + "\n" + - " tracks: " + tracks + "\n" + - " sectors per track (cp/m): " + dpb.spt + "\n" + - " sectors per track (drive): " + dpb.driveSpt + "\n" + - " sector size: " + sectorSize + "\n" + - " sector skew:" + sectorSkew + "\n" + - " sector skew table:" + Arrays.toString(sectorSkewTable) + "\n" + - " block size: " + blockSize + "\n" + - " block pointer is word: " + blockPointerIsWord + "\n" + - " records per block: " + recordsPerBlock + "\n" + - " entries per block: " + entriesPerBlock + "\n" + - " directory blocks: " + directoryBlocks + "\n" + - " date format: " + dateFormat; + " ID: " + id + "\n" + + " tracks: " + tracks + "\n" + + " sectors per track (cp/m): " + dpb.spt + "\n" + + " sectors per track (drive): " + dpb.driveSpt + "\n" + + " sector size: " + sectorSize + "\n" + + " sector skew:" + sectorSkew + "\n" + + " sector skew table:" + Arrays.toString(sectorSkewTable) + "\n" + + " block size: " + blockSize + "\n" + + " block pointer is word: " + blockPointerIsWord + "\n" + + " records per block: " + recordsPerBlock + "\n" + + " entries per block: " + entriesPerBlock + "\n" + + " directory blocks: " + directoryBlocks + "\n" + + " date format: " + dateFormat; } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DiskParameterBlock.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DiskParameterBlock.java index 85668b3e1..7e8d1b3d6 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DiskParameterBlock.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DiskParameterBlock.java @@ -32,16 +32,16 @@ public class DiskParameterBlock { /** * No. of Logical (128-byte) Sectors per Logical Track - * + *

* This may be used to find the capacity of a disk - but the calculation must allow for the fact that in some * cases a 'Logical Track' is limited to ONE SIDE of a disk, but in other cases it extends over BOTH SIDES of a * disk. - * + *

* For example in Xtal's '35-track' CP/M for the MZ-80K a 'Logical Track' is limited to ONE side of the disk; * there are therefore 35 'Logical tracks' on each side of a disk, and 70 'Logical Tracks' on the disk as a whole. * The capacity of a disk is therefore * 128 * 16 * 70 = 143,360 Bytes ( 140K ). - * + *

* But in M-T's '35-track' CP/M 2.2 for the MZ-80B a 'Logical Track' extends over BOTH sides of a disk; there are * therefore 35 'Logical Tracks' on the whole of a disk, and the disk capacity is * 128 * 80 * 35 = 358,400 ( 350K ). @@ -62,12 +62,12 @@ public class DiskParameterBlock { /** * Extent Mask - * + *

* Large CP/M files are divided into EXTENTS of 16K. In early versions of CP/M 'Logical and 'Physical' Extents * were both 16K; but in CP/M 2.2 and later a 'Logical' extent is 16K but a 'Physical' extent can be 16K, 32K, 64K, * 128K or 256K, and this is indicated by setting EXM to either 0, 1, 3, 7, or 15 ( i.e. EXM is set to 1 less than * the number of 'Logical' extents in a 'Physical' extent ). - * + *

* It is used for computing total number of records: (EX & exm) * 128 + RC * Also, extent number = ((32*S2)+EX) / (exm + 1) */ @@ -89,16 +89,16 @@ public class DiskParameterBlock { /** * AL0 - AL1 16-bit Directory Allocation Pattern - * + *

* These parameters, taken BITWISE, indicate which of the first 16 CP/M blocks ( numbered 00 - 15 ) are allocated * to the Directory. For example:- - * + *

* $80 00 = 10000000 00000000 i.e. the Directory is allocated BLOCK 00 only * $C0 00= 11000000 00000000 i.e. the Directory is allocated BLOCKS 00 & 01 - * + *

* al0 al1 * b7b6b5b4b3b2b1b0 b7b6b5b4b3b2b1b0 - * 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 + * 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 */ public final int al0; public final int al1; @@ -121,12 +121,12 @@ public DiskParameterBlock(int driveSpt, int spt, int bsh, int blm, int dsm, int } if (dsm <= 255) { - this.exm = (byte)((1 << (bsh - 3)) - 1); + this.exm = (byte) ((1 << (bsh - 3)) - 1); } else { if (bsh == 3) { throw new IllegalArgumentException("For given BSH, DSM must be < 256"); } - this.exm = (byte)((1 << (bsh - 4)) - 1); + this.exm = (byte) ((1 << (bsh - 4)) - 1); } this.driveSpt = driveSpt; @@ -142,13 +142,13 @@ public DiskParameterBlock(int driveSpt, int spt, int bsh, int blm, int dsm, int public static DiskParameterBlock fromBSH(int driveSpt, int spt, int bsh, int dsm, int drm, int al0, int al1, int ofs) { return new DiskParameterBlock( - driveSpt, spt, bsh, (1 << bsh) - 1, dsm, drm, al0, al1, ofs + driveSpt, spt, bsh, (1 << bsh) - 1, dsm, drm, al0, al1, ofs ); } public static DiskParameterBlock fromBLM(int driveSpt, int spt, int blm, int dsm, int drm, int al0, int al1, int ofs) { return new DiskParameterBlock( - driveSpt, spt, (int)(Math.log(blm + 1) / Math.log(2)), blm, dsm, drm, al0, al1, ofs + driveSpt, spt, (int) (Math.log(blm + 1) / Math.log(2)), blm, dsm, drm, al0, al1, ofs ); } @@ -172,15 +172,15 @@ public static DiskParameterBlock fromConfig(Config config) { @Override public String toString() { return "DPB:\n" + - " driveSpt=" + driveSpt + "\n" + - " spt=" + spt + "\n" + - " bsh=" + bsh + "\n" + - " blm=" + blm + "\n" + - " exm=" + exm + "\n" + - " dsm=" + dsm + "\n" + - " drm=" + drm + "\n" + - " al0=" + (Integer.toBinaryString(al0 & 0xFF)) + "\n" + - " al1=" + (Integer.toBinaryString(al1 & 0xFF)) + "\n" + - " ofs=" + ofs + "\n"; + " driveSpt=" + driveSpt + "\n" + + " spt=" + spt + "\n" + + " bsh=" + bsh + "\n" + + " blm=" + blm + "\n" + + " exm=" + exm + "\n" + + " dsm=" + dsm + "\n" + + " drm=" + drm + "\n" + + " al0=" + (Integer.toBinaryString(al0 & 0xFF)) + "\n" + + " al1=" + (Integer.toBinaryString(al1 & 0xFF)) + "\n" + + " ofs=" + ofs + "\n"; } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DriveIO.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DriveIO.java index e19cb05ea..11da94e9c 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DriveIO.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/DriveIO.java @@ -52,6 +52,30 @@ public DriveIO(Path imageFile, CpmFormat cpmFormat, OpenOption... openOptions) t this.channel = FileChannel.open(Objects.requireNonNull(imageFile, "Image file is not set"), openOptions); } + /** + * Formats disk (creates new disk image file). + * + * @param imageFile disk image file name + * @param cpmFormat CP/M format + */ + public static void format(Path imageFile, CpmFormat cpmFormat) throws IOException { + if (Files.exists(imageFile)) { + throw new IllegalArgumentException("File already exists"); + } + int fileSize = cpmFormat.tracks * cpmFormat.sectorSize * cpmFormat.dpb.spt; + System.out.println("File size: " + fileSize); + System.out.println("Sector size: " + cpmFormat.sectorSize); + System.out.println("Sectors per track: " + cpmFormat.dpb.spt); + System.out.println("Tracks: " + cpmFormat.tracks); + + try (FileChannel channel = FileChannel.open(imageFile, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW)) { + MappedByteBuffer out = channel.map(READ_WRITE, 0, fileSize); + for (int i = 0; i < fileSize; i++) { + out.put((byte) STATUS_UNUSED); + } + } + } + /** * Reads a CP/M "record". *

@@ -128,28 +152,4 @@ public void writeBlock(int blockNumber, List records) throws IOExcep public void close() throws Exception { channel.close(); } - - /** - * Formats disk (creates new disk image file). - * - * @param imageFile disk image file name - * @param cpmFormat CP/M format - */ - public static void format(Path imageFile, CpmFormat cpmFormat) throws IOException { - if (Files.exists(imageFile)) { - throw new IllegalArgumentException("File already exists"); - } - int fileSize = cpmFormat.tracks * cpmFormat.sectorSize * cpmFormat.dpb.spt; - System.out.println("File size: " + fileSize); - System.out.println("Sector size: " + cpmFormat.sectorSize); - System.out.println("Sectors per track: " + cpmFormat.dpb.spt); - System.out.println("Tracks: " + cpmFormat.tracks); - - try (FileChannel channel = FileChannel.open(imageFile, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW)) { - MappedByteBuffer out = channel.map(READ_WRITE, 0, fileSize); - for (int i = 0; i < fileSize; i++) { - out.put((byte) STATUS_UNUSED); - } - } - } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmFile.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmFile.java index 9d57dd2c1..081232eb5 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmFile.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmFile.java @@ -26,7 +26,7 @@ /** * CP/M file entry. - * + *

* Valid for all versions of CP/M. * *

@@ -145,16 +145,6 @@ private CpmFile(byte status, String fileName, String fileExt, int flags, this.numberOfRecords = USE_EX_LSB ? ((ex & 1) << 8 + (rc & 0xFF)) : (rc & 0xFF); } - public String getFileName() { - String result = fileName.trim(); - - String ext = fileExt.trim(); - if (!ext.equals("")) { - result += "." + ext; - } - return result; - } - public static CpmFile fromEntry(ByteBuffer entry, byte exm) { byte status = entry.get(); @@ -192,6 +182,21 @@ public static CpmFile fromEntry(ByteBuffer entry, byte exm) { return new CpmFile(status, fileName, fileExt, flags, ex, s2, exm, bc, rc, extents); } + public static String getLongHeader() { + return "St |File name |Flags |Ex |S2 |Rc |Bc |Al\n" + + "---------------------------------------------"; + } + + public String getFileName() { + String result = fileName.trim(); + + String ext = fileExt.trim(); + if (!ext.equals("")) { + result += "." + ext; + } + return result; + } + public ByteBuffer toEntry() { return toEntry(status); } @@ -233,30 +238,25 @@ public ByteBuffer toEntry(byte newStatus) { return entry; } - public static String getLongHeader() { - return "St |File name |Flags |Ex |S2 |Rc |Bc |Al\n" + - "---------------------------------------------"; - } - public String getFlagsString() { return ((flags & (1 << FLAG_WHEEL_REQUIRED)) != 0 ? "W" : " ") + - ((flags & (1 << FLAG_PUBLIC_FILE)) != 0 ? "P" : " ") + - ((flags & (1 << FLAG_DATE_STAMP)) != 0 ? "D" : " ") + - ((flags & (1 << FLAG_WHEEL_PROTECT)) != 0 ? "w" : " ") + - ((flags & (1 << FLAG_READ_ONLY)) != 0 ? "R" : " ") + - ((flags & (1 << FLAG_INVISIBLE)) != 0 ? "I" : " ") + - ((flags & (1 << FLAG_ARCHIVED)) != 0 ? "A" : " "); + ((flags & (1 << FLAG_PUBLIC_FILE)) != 0 ? "P" : " ") + + ((flags & (1 << FLAG_DATE_STAMP)) != 0 ? "D" : " ") + + ((flags & (1 << FLAG_WHEEL_PROTECT)) != 0 ? "w" : " ") + + ((flags & (1 << FLAG_READ_ONLY)) != 0 ? "R" : " ") + + ((flags & (1 << FLAG_INVISIBLE)) != 0 ? "I" : " ") + + ((flags & (1 << FLAG_ARCHIVED)) != 0 ? "A" : " "); } public String toLongString() { return String.format("%02x |", status & 0xFF) + - String.format("%12s |", getFileName()) + - String.format("%7s |", getFlagsString()) + - String.format("%02x |", ex & 0xFF) + - String.format("%02x |", s2 & 0xFF) + - String.format("%02x |", rc & 0xFF) + - String.format("%02x |", bc & 0xFF) + - al.stream().map(b -> String.format("%02X", b & 0xFF)).collect(Collectors.joining(" ")); + String.format("%12s |", getFileName()) + + String.format("%7s |", getFlagsString()) + + String.format("%02x |", ex & 0xFF) + + String.format("%02x |", s2 & 0xFF) + + String.format("%02x |", rc & 0xFF) + + String.format("%02x |", bc & 0xFF) + + al.stream().map(b -> String.format("%02X", b & 0xFF)).collect(Collectors.joining(" ")); } @Override diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmNativeDate.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmNativeDate.java index 61f9bcf89..79a370201 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmNativeDate.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmNativeDate.java @@ -110,23 +110,12 @@ public CpmNativeDate(DateStamp[] file1, DateStamp[] file2, DateStamp[] file3, Da this.format = Objects.requireNonNull(format); this.datestamps = new DateStamp[][]{ - Objects.requireNonNull(file1), - Objects.requireNonNull(file2), - Objects.requireNonNull(file3) + Objects.requireNonNull(file1), + Objects.requireNonNull(file2), + Objects.requireNonNull(file3) }; } - public ByteBuffer toEntry() { - switch (format) { - case NATIVE: - return toEntryNative(); - case NATIVE2: - return toEntryNative2(); - default: - throw new IllegalStateException("This entry can be just NATIVE or NATIVE2"); - } - } - public static CpmNativeDate fromEntry(ByteBuffer entry, DateFormat format) { switch (format) { case NATIVE: @@ -166,8 +155,8 @@ private static CpmNativeDate fromEntryNative2(ByteBuffer entry) { private static DateStamp[] parseNativeFile(ByteBuffer entry) { DateStamp create = new DateStamp( - (entry.get() | (entry.get() << 8)) & 0xFF, - 0, 0 + (entry.get() | (entry.get() << 8)) & 0xFF, + 0, 0 ); DateStamp modify = parseDateStamp(entry); DateStamp access = parseDateStamp(entry); @@ -184,12 +173,23 @@ private static DateStamp[] parseNative2File(ByteBuffer entry) { private static DateStamp parseDateStamp(ByteBuffer entry) { return new DateStamp( - (entry.get() | (entry.get() << 8)) & 0xFF, - bcd2bin(entry.get() & 0xFF), - bcd2bin(entry.get() & 0xFF) + (entry.get() | (entry.get() << 8)) & 0xFF, + bcd2bin(entry.get() & 0xFF), + bcd2bin(entry.get() & 0xFF) ); } + public ByteBuffer toEntry() { + switch (format) { + case NATIVE: + return toEntryNative(); + case NATIVE2: + return toEntryNative2(); + default: + throw new IllegalStateException("This entry can be just NATIVE or NATIVE2"); + } + } + private ByteBuffer toEntryNative() { ByteBuffer entry = ByteBuffer.allocate(ENTRY_SIZE); entry.put((byte) STATUS_DATESTAMP); diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusDiscLabel.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusDiscLabel.java index ddaea4820..5e0ce5541 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusDiscLabel.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusDiscLabel.java @@ -97,6 +97,6 @@ public ByteBuffer toEntry() { @Override public String toString() { return "'" + label + "'; mode=" + Integer.toHexString(mode) + "; passwordByte=" + - Integer.toHexString(passwordDecodeByte); + Integer.toHexString(passwordDecodeByte); } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusPassword.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusPassword.java index bb39b528e..6494bc49f 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusPassword.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/entry/CpmPlusPassword.java @@ -121,6 +121,6 @@ public String getFileName() { @Override public String toString() { return "'" + getFileName() + "'; mode=" + Integer.toHexString(mode) + "; passwordByte=" + - Integer.toHexString(passwordDecodeByte) + "; password='" + passwordString + "'"; + Integer.toHexString(passwordDecodeByte) + "; password='" + passwordString + "'"; } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8deramp.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8deramp.java index 75e11bd17..8e8e68e72 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8deramp.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8deramp.java @@ -26,28 +26,28 @@ /** * https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%203.0/BIOS.ASM - * + *

* Altair 8" floppy disk (from deramp.com) - * + *

* Tracks 0-5 are formatted as "System Tracks" (regardless of how they are actually used). Sectors on these tracks are * formatted as follows: - * - * Byte Value - * 0 0 - * 1 1 - * 2-130 Data (128 bytes) - * 131 0FFh (Stop Byte) - * 132 Checksum of 2-130 (sum of the 128 byte payload) + *

+ * Byte Value + * 0 0 + * 1 1 + * 2-130 Data (128 bytes) + * 131 0FFh (Stop Byte) + * 132 Checksum of 2-130 (sum of the 128 byte payload) * 133-136 Not used - * + *

* Tracks 6-76 (except track 70) are "Data Tracks." Sectors on these tracks are formatted as follows: - * - * Byte Value - * 0 Logical sector number (not skewed) - * 1-5 0 + *

+ * Byte Value + * 0 Logical sector number (not skewed) + * 1-5 0 * 6-134 Data (128 bytes) - * 135 0FFh (Stop Byte) - * 136 Checksum of 6-134 (sum of the 128 byte payload) + * 135 0FFh (Stop Byte) + * 136 Checksum of 6-134 (sum of the 128 byte payload) */ public class Altair8deramp implements SectorOps { public static final int SECTOR_SIZE = 137; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8mits.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8mits.java index b0edce7fb..f8887242c 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8mits.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/Altair8mits.java @@ -27,38 +27,38 @@ /** * MITS 88-DCDD sector ops. - * + *

* Sector has 137 bytes, and the record (128 bytes) was placed inside, possibly with some offset. * The rest of bytes (prefix and suffix of the record) had often a special meaning. However all this * prefixing/postfixing was performed in software; it depends on specific CP/M implementation. - * - * - * + *

+ *

+ *

* Tracks 0-5 are formatted as "System Tracks" (regardless of how they are actually used). Sectors on these tracks are * formatted as follows: - * - * Byte Value - * 0 Track number + 80h - * 1-2 Sixteen bit address in memory of the end of the bootloader (0x100). This same value is set in all - * sectors of tracks 0‐5. - * 3-130 Data (128 bytes) - * 131 0FFh (Stop Byte) - * 132 Checksum of 3-130 (sum of the 128 byte payload) - * 133-136 Not used - * + *

+ * Byte Value + * 0 Track number + 80h + * 1-2 Sixteen bit address in memory of the end of the bootloader (0x100). This same value is set in all + * sectors of tracks 0‐5. + * 3-130 Data (128 bytes) + * 131 0FFh (Stop Byte) + * 132 Checksum of 3-130 (sum of the 128 byte payload) + * 133-136 Not used + *

* Tracks 6-76 (except track 70) are "Data Tracks." Sectors on these tracks are formatted as follows: - * - * Byte Value - * 0 Track number + 80h - * 1 Skewed sector = (Sector number * 17) MOD 32 - * 2 File number in directory (or not used) - * 3 Data byte count (or not used) - * 4 Checksum of 2-3 & 5-134 - * 5-6 Pointer to next data group (or not used) - * 7-134 Data (128 bytes) - * 135 0FFh (Stop Byte) - * 136 00h (Stop byte) - * + *

+ * Byte Value + * 0 Track number + 80h + * 1 Skewed sector = (Sector number * 17) MOD 32 + * 2 File number in directory (or not used) + * 3 Data byte count (or not used) + * 4 Checksum of 2-3 & 5-134 + * 5-6 Pointer to next data group (or not used) + * 7-134 Data (128 bytes) + * 135 0FFh (Stop Byte) + * 136 00h (Stop byte) + *

* Track 70 is the Altair Basic/DOS directory track. It is formatted the same as the Data Tracks, except that each Data * field is divided into 8 16-byte directory entries. The last 5 of these 16 bytes are written as 0 by most versions of Altair * Basic and DOS, but are used as a password by Multiuser Basic, where five 0's means "no password". Unfortunately, single- diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/AltairMinidiskDeramp.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/AltairMinidiskDeramp.java index 9e4298c3e..1851f1331 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/AltairMinidiskDeramp.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/AltairMinidiskDeramp.java @@ -26,28 +26,28 @@ /** * https://deramp.com/downloads/altair/software/8_inch_floppy/CPM/CPM%203.0/BIOS.ASM - * + *

* Altair 5.25" floppy disk (from deramp.com) - * + *

* Tracks 0-5 are formatted as "System Tracks" (regardless of how they are actually used). Sectors on these tracks are * formatted as follows: - * - * Byte Value - * 0 0 - * 1 1 - * 2-130 Data (128 bytes) - * 131 0FFh (Stop Byte) - * 132 Checksum of 2-130 (sum of the 128 byte payload) + *

+ * Byte Value + * 0 0 + * 1 1 + * 2-130 Data (128 bytes) + * 131 0FFh (Stop Byte) + * 132 Checksum of 2-130 (sum of the 128 byte payload) * 133-136 Not used - * + *

* Tracks 6-76 (except track 70) are "Data Tracks." Sectors on these tracks are formatted as follows: - * - * Byte Value - * 0 Logical sector number (not skewed) - * 1-5 0 + *

+ * Byte Value + * 0 Logical sector number (not skewed) + * 1-5 0 * 6-134 Data (128 bytes) - * 135 0FFh (Stop Byte) - * 136 Checksum of 6-134 (sum of the 128 byte payload) + * 135 0FFh (Stop Byte) + * 136 Checksum of 6-134 (sum of the 128 byte payload) */ public class AltairMinidiskDeramp implements SectorOps { public static final int SECTOR_SIZE = 137; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/SectorOps.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/SectorOps.java index b3f90f54b..f0eded88a 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/SectorOps.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/cpmfs/sectorops/SectorOps.java @@ -39,6 +39,20 @@ public ByteBuffer toRecord(ByteBuffer sector, Position position) { } }; + static SectorOps fromString(String name) { + switch (name.toLowerCase(Locale.ENGLISH)) { + case "altair-floppy-mits": + return Altair8mits.INSTANCE; + case "altair-floppy-deramp": + return Altair8deramp.INSTANCE; + case "altair-minidisk-deramp": + return AltairMinidiskDeramp.INSTANCE; + default: + return DUMMY; + } + + } + /** * Converts record of max RECORD_SIZE bytes to raw sector. * the record size might be less than RECORD_SIZE. @@ -57,19 +71,4 @@ public ByteBuffer toRecord(ByteBuffer sector, Position position) { * @return record */ ByteBuffer toRecord(ByteBuffer sector, Position position); - - - static SectorOps fromString(String name) { - switch (name.toLowerCase(Locale.ENGLISH)) { - case "altair-floppy-mits": - return Altair8mits.INSTANCE; - case "altair-floppy-deramp": - return Altair8deramp.INSTANCE; - case "altair-minidisk-deramp": - return AltairMinidiskDeramp.INSTANCE; - default: - return DUMMY; - } - - } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java index 4e20b584e..f606e836c 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/Drive.java @@ -44,46 +44,39 @@ */ @ThreadSafe public class Drive { - private static final Logger LOGGER = LoggerFactory.getLogger(Drive.class); - public static final byte DEAD_DRIVE = (byte) 0b11100111; + public static final byte SECTOR0 = (byte) 0b11000001; + private static final Logger LOGGER = LoggerFactory.getLogger(Drive.class); private static final byte ALIVE_DRIVE = (byte) 0b11100101; private static final byte MASK_TRACK0 = (byte) 0b10111111; - - public static final byte SECTOR0 = (byte) 0b11000001; - private static final byte MASK_HEAD_LOAD = (byte) 0b11111011; private static final byte MASK_DATA_AVAILABLE = 0b01111111; private final static Map RST_MAP = Map.of( - 0, (byte) 0xC7, - 1, (byte) 0xCF, - 2, (byte) 0xD7, - 3, (byte) 0xDF, - 4, (byte) 0xE7, - 5, (byte) 0xEF, - 6, (byte) 0xF7, - 7, (byte) 0xFF + 0, (byte) 0xC7, + 1, (byte) 0xCF, + 2, (byte) 0xD7, + 3, (byte) 0xDF, + 4, (byte) 0xE7, + 5, (byte) 0xEF, + 6, (byte) 0xF7, + 7, (byte) 0xFF ); private final int driveIndex; private final Context8080 cpu; private final byte[] rstInterrupt; - private volatile boolean interruptsSupported; - private final ReadWriteLock positionLock = new ReentrantReadWriteLock(); + private final List listeners = new CopyOnWriteArrayList<>(); + private final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1); + private volatile boolean interruptsSupported; private int track; private int sector; private int sectorOffset; private DiskSettings.DriveSettings driveSettings = DiskSettings.DriveSettings.DEFAULT; - private Path mountedImage = null; private SeekableByteChannel imageChannel; private boolean selected = false; - - private final List listeners = new CopyOnWriteArrayList<>(); - private final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1); - private boolean sectorTrue = true; // SR0 alternation private boolean signalInterrupts = false; @@ -132,7 +125,7 @@ public void addDriveListener(DriveListener listener) { public DriveParameters getDriveParameters() { return inReadLock( - () -> new DriveParameters(port1status, port2status, track, sector, getOffset(), mountedImage) + () -> new DriveParameters(port1status, port2status, track, sector, getOffset(), mountedImage) ); } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java index 1e482878f..f56cb7b9d 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveCollection.java @@ -34,9 +34,8 @@ import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.DIALOG_TITLE; public class DriveCollection implements Iterable { - private final static Logger LOGGER = LoggerFactory.getLogger(DriveCollection.class); - public final static int DRIVES_COUNT = 16; + private final static Logger LOGGER = LoggerFactory.getLogger(DriveCollection.class); private final List drives = new ArrayList<>(); private final Context8080 cpu; @@ -67,7 +66,7 @@ public void destroy() { public Optional getCurrentDrive() { return (currentDrive >= DRIVES_COUNT || currentDrive < 0) ? - Optional.empty() : Optional.of(drives.get(currentDrive)); + Optional.empty() : Optional.of(drives.get(currentDrive)); } public void setCurrentDrive(int index) { @@ -105,21 +104,21 @@ public void attach(DeviceContext port1, DeviceContext port2, DeviceC if (!cpu.attachDevice(port1, port1cpu)) { throw new PluginInitializationException( - ": " + DIALOG_TITLE + " (port 1) can not be attached to default CPU port " + port1cpu + ": " + DIALOG_TITLE + " (port 1) can not be attached to default CPU port " + port1cpu ); } attachedCpuPort1 = Optional.of(port1cpu); if (!cpu.attachDevice(port2, port2cpu)) { throw new PluginInitializationException( - ": " + DIALOG_TITLE + " (port 2) can not be attached to default CPU port " + port2cpu + ": " + DIALOG_TITLE + " (port 2) can not be attached to default CPU port " + port2cpu ); } attachedCpuPort2 = Optional.of(port2cpu); if (!cpu.attachDevice(port3, port3cpu)) { throw new PluginInitializationException( - ": " + DIALOG_TITLE + " (port 3) can not be attached to default CPU port " + port3cpu + ": " + DIALOG_TITLE + " (port 3) can not be attached to default CPU port " + port3cpu ); } attachedCpuPort3 = Optional.of(port3cpu); @@ -138,19 +137,19 @@ public void reset() { drive.setInterruptsSupported(settings.getInterruptsSupported()); Optional - .ofNullable(driveSettings.imagePath) - .map(Path::of) - .ifPresent(path -> { - try { - drive.mount(path); - } catch (IOException ex) { - LOGGER.error("Could not mount image file {}", path, ex); - dialogs.showError( - "Could not mount image file: " + path + ". Please see log file for more details.", - "MITS 88-DCDD" - ); - } - }); + .ofNullable(driveSettings.imagePath) + .map(Path::of) + .ifPresent(path -> { + try { + drive.mount(path); + } catch (IOException ex) { + LOGGER.error("Could not mount image file {}", path, ex); + dialogs.showError( + "Could not mount image file: " + path + ". Please see log file for more details.", + "MITS 88-DCDD" + ); + } + }); return null; }); } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveParameters.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveParameters.java index 0a7e0bd3d..c4f5602ec 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveParameters.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/drive/DriveParameters.java @@ -79,16 +79,16 @@ public static String port2StatusString(int status) { boolean sr0 = (status & 1) == 0; int offset = (status >>> 1) & 0b11111; - return (sr0 ? "(SR0) " : " ") + "0x" + RadixUtils.formatByteHexString(offset); + return (sr0 ? "(SR0) " : " ") + "0x" + RadixUtils.formatByteHexString(offset); } @Override public String toString() { return - "T=" + RadixUtils.formatByteHexString(track) + - "; S=" + RadixUtils.formatByteHexString(sector) + - "; O=" + RadixUtils.formatByteHexString(sectorOffset) + - "; port1=[" + port1statusString + "]" + - "; port2=[" + port2statusString + "]"; + "T=" + RadixUtils.formatByteHexString(track) + + "; S=" + RadixUtils.formatByteHexString(sector) + + "; O=" + RadixUtils.formatByteHexString(sectorOffset) + + "; port1=[" + port1statusString + "]" + + "; port2=[" + port2statusString + "]"; } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java index 4d77f3517..f49661fff 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/DiskGui.java @@ -33,32 +33,31 @@ import static net.emustudio.plugins.device.mits88dcdd.gui.Constants.MONOSPACED_PLAIN; public class DiskGui extends JDialog { - private final DriveButton[] driveButtons = new DriveButton[]{ - new DriveButton("A", () -> updateDriveInfo(0)), - new DriveButton("B", () -> updateDriveInfo(1)), - new DriveButton("C", () -> updateDriveInfo(2)), - new DriveButton("D", () -> updateDriveInfo(3)), - new DriveButton("E", () -> updateDriveInfo(4)), - new DriveButton("F", () -> updateDriveInfo(5)), - new DriveButton("G", () -> updateDriveInfo(6)), - new DriveButton("H", () -> updateDriveInfo(7)), - new DriveButton("I", () -> updateDriveInfo(8)), - new DriveButton("J", () -> updateDriveInfo(9)), - new DriveButton("K", () -> updateDriveInfo(10)), - new DriveButton("L", () -> updateDriveInfo(11)), - new DriveButton("M", () -> updateDriveInfo(12)), - new DriveButton("N", () -> updateDriveInfo(13)), - new DriveButton("O", () -> updateDriveInfo(14)), - new DriveButton("P", () -> updateDriveInfo(15)), - }; private final DriveCollection drives; - private final JLabel lblOffset = createMonospacedLabel("0"); private final JLabel lblSector = createMonospacedLabel("0"); private final JLabel lblTrack = createMonospacedLabel("0"); private final JLabel lblPort1Status = createMonospacedLabel(DriveParameters.port1StatusString(Drive.DEAD_DRIVE)); private final JLabel lblPort2Status = createMonospacedLabel(DriveParameters.port2StatusString(Drive.SECTOR0)); private final JTextArea txtMountedImage = new JTextArea(); + private final DriveButton[] driveButtons = new DriveButton[]{ + new DriveButton("A", () -> updateDriveInfo(0)), + new DriveButton("B", () -> updateDriveInfo(1)), + new DriveButton("C", () -> updateDriveInfo(2)), + new DriveButton("D", () -> updateDriveInfo(3)), + new DriveButton("E", () -> updateDriveInfo(4)), + new DriveButton("F", () -> updateDriveInfo(5)), + new DriveButton("G", () -> updateDriveInfo(6)), + new DriveButton("H", () -> updateDriveInfo(7)), + new DriveButton("I", () -> updateDriveInfo(8)), + new DriveButton("J", () -> updateDriveInfo(9)), + new DriveButton("K", () -> updateDriveInfo(10)), + new DriveButton("L", () -> updateDriveInfo(11)), + new DriveButton("M", () -> updateDriveInfo(12)), + new DriveButton("N", () -> updateDriveInfo(13)), + new DriveButton("O", () -> updateDriveInfo(14)), + new DriveButton("P", () -> updateDriveInfo(15)), + }; public DiskGui(JFrame parent, DriveCollection drives) { super(parent); @@ -73,6 +72,12 @@ public DiskGui(JFrame parent, DriveCollection drives) { }); } + private static JLabel createMonospacedLabel(String text) { + JLabel label = new JLabel(text); + label.setFont(MONOSPACED_PLAIN); + return label; + } + private void updateDriveInfo(int index) { updateDriveInfo(drives.get(index).getDriveParameters()); } @@ -122,8 +127,8 @@ private void initComponents() { setResizable(false); panelDiskSelection.setBorder(BorderFactory.createTitledBorder(null, "Disk selection", - TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) + TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, + lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) )); for (DriveButton button : driveButtons) { @@ -137,10 +142,10 @@ private void initComponents() { GroupLayout.ParallelGroup upperParallelGroup = diskSelectionLayout.createParallelGroup(GroupLayout.Alignment.BASELINE); for (int i = 0; i < 8; i++) { upperSequentialGroup - .addGroup(diskSelectionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(driveButtons[i]) - .addComponent(driveButtons[i + 8]) - ).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED); + .addGroup(diskSelectionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(driveButtons[i]) + .addComponent(driveButtons[i + 8]) + ).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED); upperParallelGroup.addComponent(driveButtons[i]); } @@ -152,60 +157,60 @@ private void initComponents() { } diskSelectionLayout.setHorizontalGroup( - diskSelectionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(diskSelectionLayout.createSequentialGroup() - .addContainerGap() - .addGroup(upperSequentialGroup) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + diskSelectionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(diskSelectionLayout.createSequentialGroup() + .addContainerGap() + .addGroup(upperSequentialGroup) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); diskSelectionLayout.setVerticalGroup( - diskSelectionLayout.createSequentialGroup() - .addContainerGap() - .addGroup(upperParallelGroup) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(lowerParallelGroup) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + diskSelectionLayout.createSequentialGroup() + .addContainerGap() + .addGroup(upperParallelGroup) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(lowerParallelGroup) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); panelFlags.setBorder(BorderFactory.createTitledBorder( - null, "Flags and settings", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) + null, "Flags and settings", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, + lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) )); GroupLayout panelFlagsLayout = new GroupLayout(panelFlags); panelFlags.setLayout(panelFlagsLayout); panelFlagsLayout.setHorizontalGroup( - panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelFlagsLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelFlagsLayout.createSequentialGroup() - .addComponent(lblPort2Label) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblPort2Status)) + panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelFlagsLayout.createSequentialGroup() - .addComponent(lblPort1Label) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblPort1Status))) - .addContainerGap(119, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelFlagsLayout.createSequentialGroup() + .addComponent(lblPort2Label) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblPort2Status)) + .addGroup(panelFlagsLayout.createSequentialGroup() + .addComponent(lblPort1Label) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblPort1Status))) + .addContainerGap(119, Short.MAX_VALUE)) ); panelFlagsLayout.setVerticalGroup( - panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelFlagsLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblPort1Label) - .addComponent(lblPort1Status)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblPort2Label) - .addComponent(lblPort2Status)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelFlagsLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblPort1Label) + .addComponent(lblPort1Status)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelFlagsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblPort2Label) + .addComponent(lblPort2Status)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); panelImage.setBorder(BorderFactory.createTitledBorder( - null, "Mounted image", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) + null, "Mounted image", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, + lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) )); txtMountedImage.setEditable(false); @@ -219,98 +224,92 @@ private void initComponents() { GroupLayout panelImageLayout = new GroupLayout(panelImage); panelImage.setLayout(panelImageLayout); panelImageLayout.setHorizontalGroup( - panelImageLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelImageLayout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1) - .addContainerGap()) + panelImageLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelImageLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1) + .addContainerGap()) ); panelImageLayout.setVerticalGroup( - panelImageLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelImageLayout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1) - .addContainerGap()) + panelImageLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelImageLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1) + .addContainerGap()) ); panelPosition.setBorder(BorderFactory.createTitledBorder( - null, "Position", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) + null, "Position", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, + lblPort1Label.getFont().deriveFont(lblPort1Label.getFont().getStyle() | Font.BOLD) )); GroupLayout panelPositionLayout = new GroupLayout(panelPosition); panelPosition.setLayout(panelPositionLayout); panelPositionLayout.setHorizontalGroup( - panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelPositionLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblSectorLabel) - .addComponent(lblTrackLabel) - .addComponent(lblOffsetLabel)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblOffset) - .addComponent(this.lblTrack) - .addComponent(this.lblSector)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelPositionLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblSectorLabel) + .addComponent(lblTrackLabel) + .addComponent(lblOffsetLabel)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblOffset) + .addComponent(this.lblTrack) + .addComponent(this.lblSector)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); panelPositionLayout.setVerticalGroup( - panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelPositionLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblTrackLabel) - .addComponent(this.lblTrack)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblSectorLabel) - .addComponent(this.lblSector)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblOffsetLabel) - .addComponent(lblOffset)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelPositionLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblTrackLabel) + .addComponent(this.lblTrack)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblSectorLabel) + .addComponent(this.lblSector)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelPositionLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblOffsetLabel) + .addComponent(lblOffset)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(panelDiskSelection, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(panelImage, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(panelFlags, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelPosition, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addContainerGap()) + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(panelDiskSelection, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelImage, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(panelFlags, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelPosition, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(panelDiskSelection, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(panelPosition, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(panelFlags, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelImage, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(panelDiskSelection, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(panelPosition, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelFlags, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelImage, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); } - private static JLabel createMonospacedLabel(String text) { - JLabel label = new JLabel(text); - label.setFont(MONOSPACED_PLAIN); - return label; - } - private class GUIDriveListener implements DriveListener { private final int index; diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java index 2353f5c3c..db2e09a91 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java @@ -57,24 +57,37 @@ public class SettingsDialog extends JDialog { private final List driveSettingsUI = new ArrayList<>(); private final List driveButtons = new ArrayList<>(); + private final JToggleButton btnA = new JToggleButton("A"); + private final JToggleButton btnB = new JToggleButton("B"); + private final JToggleButton btnC = new JToggleButton("C"); + private final JToggleButton btnD = new JToggleButton("D"); + private final JToggleButton btnE = new JToggleButton("E"); + private final JToggleButton btnF = new JToggleButton("F"); + private final JToggleButton btnG = new JToggleButton("G"); + private final JToggleButton btnH = new JToggleButton("H"); + private final JToggleButton btnI = new JToggleButton("I"); + private final JToggleButton btnJ = new JToggleButton("J"); + private final JToggleButton btnK = new JToggleButton("K"); + private final JToggleButton btnL = new JToggleButton("L"); + private final JToggleButton btnM = new JToggleButton("M"); + private final JToggleButton btnN = new JToggleButton("N"); + private final JToggleButton btnO = new JToggleButton("O"); + private final JToggleButton btnP = new JToggleButton("P"); + private final JToggleButton btnMountUnmount = new JToggleButton("Mount"); + private final JButton btnUnmountAll = new JButton("Unmount all"); + private final JButton btnSave = new JButton("Save"); + private final JButton btnBrowse = new JButton("Browse..."); + private final JCheckBox chkInterruptsSupported = new JCheckBox("Interrupts supported"); + private final JSpinner spnInterruptVector = new JSpinner(new SpinnerNumberModel(0, 0, 7, 1)); + private final JButton btnCpuDefault = new JButton("Set default"); + private final JButton btnDriveDefault = new JButton("Set default"); + private final JTextField txtImageFile = new JTextField(); + private final JTextField txtPort1 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT1)); + private final JTextField txtPort2 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT2)); + private final JTextField txtPort3 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT3)); + private final JTextField txtSectorSize = new JTextField(String.valueOf(DiskSettings.DEFAULT_SECTOR_SIZE)); + private final JTextField txtSectorsPerTrack = new JTextField(String.valueOf(DiskSettings.DEFAULT_SECTORS_PER_TRACK)); private int currentDriveIndex = 0; - - static class DriveSettingsUI { - String sectorsPerTrack; - String sectorSize; - String image; - boolean mounted; - - static DriveSettingsUI fromDriveSettings(DiskSettings.DriveSettings driveSettings) { - DriveSettingsUI dsui = new DriveSettingsUI(); - dsui.sectorsPerTrack = String.valueOf(driveSettings.sectorsPerTrack); - dsui.sectorSize = String.valueOf(driveSettings.sectorSize); - dsui.image = Optional.ofNullable(driveSettings.imagePath).orElse(""); - dsui.mounted = driveSettings.mounted; - return dsui; - } - } - public SettingsDialog(JFrame parent, DiskSettings settings, DriveCollection drives, Dialogs dialogs) { super(parent, true); @@ -155,7 +168,7 @@ private void saveSettings() throws PluginInitializationException, RuntimeExcepti nullablePath = null; } DiskSettings.DriveSettings driveSettings = new DiskSettings.DriveSettings( - parsedSectorSizes.get(i), parsedSectorsPerTracks.get(i), nullablePath, dsui.mounted); + parsedSectorSizes.get(i), parsedSectorsPerTracks.get(i), nullablePath, dsui.mounted); settings.setDriveSettings(i, driveSettings); return null; }); @@ -168,24 +181,24 @@ private void updateGUI(int index) { txtSectorsPerTrack.setText(dsui.sectorsPerTrack); Optional - .ofNullable(dsui.image) - .filter(p -> !p.equals("")) - .map(Path::of) - .ifPresentOrElse(path -> { - txtImageFile.setText(path.toAbsolutePath().toString()); - btnMountUnmount.setSelected(dsui.mounted); - if (dsui.mounted) { - btnMountUnmount.setText("Unmount"); - } else { + .ofNullable(dsui.image) + .filter(p -> !p.equals("")) + .map(Path::of) + .ifPresentOrElse(path -> { + txtImageFile.setText(path.toAbsolutePath().toString()); + btnMountUnmount.setSelected(dsui.mounted); + if (dsui.mounted) { + btnMountUnmount.setText("Unmount"); + } else { + btnMountUnmount.setText("Mount"); + } + driveButtons.get(index).setIcon(ON_ICON); + }, () -> { + txtImageFile.setText(""); + btnMountUnmount.setSelected(false); btnMountUnmount.setText("Mount"); - } - driveButtons.get(index).setIcon(ON_ICON); - }, () -> { - txtImageFile.setText(""); - btnMountUnmount.setSelected(false); - btnMountUnmount.setText("Mount"); - driveButtons.get(index).setIcon(OFF_ICON); - }); + driveButtons.get(index).setIcon(OFF_ICON); + }); } private int parseInt(JComponent component, String name, Supplier text) { @@ -264,228 +277,228 @@ private void initComponents() { GroupLayout panelImageParametersLayout = new GroupLayout(panelImageParameters); panelImageParameters.setLayout(panelImageParametersLayout); panelImageParametersLayout.setHorizontalGroup( - panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelImageParametersLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblSpt) - .addComponent(lblSectorSize)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(txtSectorSize) - .addComponent(txtSectorsPerTrack)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblBytes) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnDriveDefault) - .addContainerGap()) + panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelImageParametersLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblSpt) + .addComponent(lblSectorSize)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(txtSectorSize) + .addComponent(txtSectorsPerTrack)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblBytes) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnDriveDefault) + .addContainerGap()) ); panelImageParametersLayout.setVerticalGroup( - panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelImageParametersLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblSpt) - .addComponent(txtSectorsPerTrack, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblSectorSize) - .addComponent(txtSectorSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(lblBytes) - .addComponent(btnDriveDefault)) - .addContainerGap(9, Short.MAX_VALUE)) + panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelImageParametersLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblSpt) + .addComponent(txtSectorsPerTrack, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelImageParametersLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblSectorSize) + .addComponent(txtSectorSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblBytes) + .addComponent(btnDriveDefault)) + .addContainerGap(9, Short.MAX_VALUE)) ); GroupLayout panelDriveLayout = new GroupLayout(panelDrive); panelDrive.setLayout(panelDriveLayout); panelDriveLayout.setHorizontalGroup( - panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelDriveLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, panelDriveLayout.createSequentialGroup() - .addComponent(lblImage) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelDriveLayout.createSequentialGroup() - .addComponent(btnBrowse) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnMountUnmount) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnUnmountAll)) - .addComponent(txtImageFile))) + panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelDriveLayout.createSequentialGroup() - .addComponent(lblDrive) - .addGap(22, 22, 22) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnI, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnA, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnJ, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnB, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnK, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnC, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnL, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnD, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnM, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnE, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnF, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnN, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnO, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnG, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnP, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnH, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addComponent(panelImageParameters, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + .addContainerGap() + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, panelDriveLayout.createSequentialGroup() + .addComponent(lblImage) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDriveLayout.createSequentialGroup() + .addComponent(btnBrowse) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnMountUnmount) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnUnmountAll)) + .addComponent(txtImageFile))) + .addGroup(panelDriveLayout.createSequentialGroup() + .addComponent(lblDrive) + .addGap(22, 22, 22) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnI, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnA, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnJ, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnB, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnK, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnC, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnL, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnD, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnM, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnE, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnF, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnN, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnO, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnG, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnP, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnH, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(panelImageParameters, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); panelDriveLayout.setVerticalGroup( - panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelDriveLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblDrive) - .addComponent(btnA) - .addComponent(btnB) - .addComponent(btnC) - .addComponent(btnD) - .addComponent(btnE) - .addComponent(btnF) - .addComponent(btnG) - .addComponent(btnH)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(btnI) - .addComponent(btnJ) - .addComponent(btnK) - .addComponent(btnL) - .addComponent(btnM) - .addComponent(btnN) - .addComponent(btnO) - .addComponent(btnP)) - .addGap(18, 18, 18) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblImage) - .addComponent(txtImageFile, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(btnMountUnmount) - .addComponent(btnBrowse) - .addComponent(btnUnmountAll)) - .addGap(18, 18, 18) - .addComponent(panelImageParameters, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + panelDriveLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDriveLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblDrive) + .addComponent(btnA) + .addComponent(btnB) + .addComponent(btnC) + .addComponent(btnD) + .addComponent(btnE) + .addComponent(btnF) + .addComponent(btnG) + .addComponent(btnH)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(btnI) + .addComponent(btnJ) + .addComponent(btnK) + .addComponent(btnL) + .addComponent(btnM) + .addComponent(btnN) + .addComponent(btnO) + .addComponent(btnP)) + .addGap(18, 18, 18) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblImage) + .addComponent(txtImageFile, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDriveLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(btnMountUnmount) + .addComponent(btnBrowse) + .addComponent(btnUnmountAll)) + .addGap(18, 18, 18) + .addComponent(panelImageParameters, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); GroupLayout panelCpuLayout = new GroupLayout(panelCpu); panelCpu.setLayout(panelCpuLayout); panelCpuLayout.setHorizontalGroup( - panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelCpuLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(btnCpuDefault, GroupLayout.Alignment.TRAILING) + panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelCpuLayout.createSequentialGroup() - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblNote) - .addGroup(panelCpuLayout.createSequentialGroup() - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(lblPort3) - .addComponent(lblPort2)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addContainerGap() + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(btnCpuDefault, GroupLayout.Alignment.TRAILING) .addGroup(panelCpuLayout.createSequentialGroup() - .addComponent(txtPort2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblPort2In)) - .addGroup(panelCpuLayout.createSequentialGroup() - .addComponent(txtPort3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblPort3In))) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblPort3Out) - .addComponent(lblPort1Out) - .addComponent(lblPort2Out))) - .addGroup(panelCpuLayout.createSequentialGroup() - .addComponent(lblPort1) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtPort1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblPort1In)) - .addGroup(panelCpuLayout.createSequentialGroup() - .addComponent(lblInterruptVector) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnInterruptVector, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblRange)) - .addComponent(chkInterruptsSupported)) - .addGap(0, 164, Short.MAX_VALUE))) - .addContainerGap()) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblNote) + .addGroup(panelCpuLayout.createSequentialGroup() + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(lblPort3) + .addComponent(lblPort2)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(txtPort2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblPort2In)) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(txtPort3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblPort3In))) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblPort3Out) + .addComponent(lblPort1Out) + .addComponent(lblPort2Out))) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(lblPort1) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtPort1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblPort1In)) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(lblInterruptVector) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnInterruptVector, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblRange)) + .addComponent(chkInterruptsSupported)) + .addGap(0, 164, Short.MAX_VALUE))) + .addContainerGap()) ); panelCpuLayout.setVerticalGroup( - panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, panelCpuLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblNote) - .addGap(18, 18, 18) - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblPort1) - .addComponent(txtPort1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(lblPort1In) - .addComponent(lblPort1Out)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblPort2) - .addComponent(txtPort2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(lblPort2In) - .addComponent(lblPort2Out)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblPort3) - .addComponent(txtPort3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(lblPort3In) - .addComponent(lblPort3Out)) - .addGap(32, 32, 32) - .addComponent(chkInterruptsSupported) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblInterruptVector) - .addComponent(spnInterruptVector, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(lblRange)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 31, Short.MAX_VALUE) - .addComponent(btnCpuDefault) - .addContainerGap()) + panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, panelCpuLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblNote) + .addGap(18, 18, 18) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblPort1) + .addComponent(txtPort1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblPort1In) + .addComponent(lblPort1Out)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblPort2) + .addComponent(txtPort2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblPort2In) + .addComponent(lblPort2Out)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblPort3) + .addComponent(txtPort3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblPort3In) + .addComponent(lblPort3Out)) + .addGap(32, 32, 32) + .addComponent(chkInterruptsSupported) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblInterruptVector) + .addComponent(spnInterruptVector, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblRange)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 31, Short.MAX_VALUE) + .addComponent(btnCpuDefault) + .addContainerGap()) ); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(tabbedPane) - .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnSave) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(tabbedPane) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnSave) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(tabbedPane, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnSave) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(tabbedPane, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnSave) + .addContainerGap()) ); btnMountUnmount.addItemListener(e -> { @@ -519,14 +532,14 @@ private void initComponents() { btnBrowse.addActionListener(e -> { Path currentDirectory = Optional - .ofNullable(driveSettingsUI.get(currentDriveIndex).image) - .filter(p -> !p.isEmpty()) - .map(Path::of) - .orElse(Path.of(System.getProperty("user.dir"))); + .ofNullable(driveSettingsUI.get(currentDriveIndex).image) + .filter(p -> !p.isEmpty()) + .map(Path::of) + .orElse(Path.of(System.getProperty("user.dir"))); dialogs.chooseFile( - "Open disk image", "Open", currentDirectory, false, - new FileExtensionsFilter("Disk images", "dsk", "bin") + "Open disk image", "Open", currentDirectory, false, + new FileExtensionsFilter("Disk images", "dsk", "bin") ).ifPresent(path -> txtImageFile.setText(path.toString())); }); @@ -589,36 +602,20 @@ public void changedUpdate(DocumentEvent e) { }); } + static class DriveSettingsUI { + String sectorsPerTrack; + String sectorSize; + String image; + boolean mounted; - private final JToggleButton btnA = new JToggleButton("A"); - private final JToggleButton btnB = new JToggleButton("B"); - private final JToggleButton btnC = new JToggleButton("C"); - private final JToggleButton btnD = new JToggleButton("D"); - private final JToggleButton btnE = new JToggleButton("E"); - private final JToggleButton btnF = new JToggleButton("F"); - private final JToggleButton btnG = new JToggleButton("G"); - private final JToggleButton btnH = new JToggleButton("H"); - private final JToggleButton btnI = new JToggleButton("I"); - private final JToggleButton btnJ = new JToggleButton("J"); - private final JToggleButton btnK = new JToggleButton("K"); - private final JToggleButton btnL = new JToggleButton("L"); - private final JToggleButton btnM = new JToggleButton("M"); - private final JToggleButton btnN = new JToggleButton("N"); - private final JToggleButton btnO = new JToggleButton("O"); - private final JToggleButton btnP = new JToggleButton("P"); - private final JToggleButton btnMountUnmount = new JToggleButton("Mount"); - private final JButton btnUnmountAll = new JButton("Unmount all"); - private final JButton btnSave = new JButton("Save"); - private final JButton btnBrowse = new JButton("Browse..."); - private final JCheckBox chkInterruptsSupported = new JCheckBox("Interrupts supported"); - private final JSpinner spnInterruptVector = new JSpinner(new SpinnerNumberModel(0, 0, 7, 1)); - private final JButton btnCpuDefault = new JButton("Set default"); - private final JButton btnDriveDefault = new JButton("Set default"); - private final JTextField txtImageFile = new JTextField(); - private final JTextField txtPort1 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT1)); - private final JTextField txtPort2 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT2)); - private final JTextField txtPort3 = new JTextField(String.format("0x%02X", DEFAULT_CPU_PORT3)); - private final JTextField txtSectorSize = new JTextField(String.valueOf(DiskSettings.DEFAULT_SECTOR_SIZE)); - private final JTextField txtSectorsPerTrack = new JTextField(String.valueOf(DiskSettings.DEFAULT_SECTORS_PER_TRACK)); + static DriveSettingsUI fromDriveSettings(DiskSettings.DriveSettings driveSettings) { + DriveSettingsUI dsui = new DriveSettingsUI(); + dsui.sectorsPerTrack = String.valueOf(driveSettings.sectorsPerTrack); + dsui.sectorSize = String.valueOf(driveSettings.sectorSize); + dsui.image = Optional.ofNullable(driveSettings.imagePath).orElse(""); + dsui.mounted = driveSettings.mounted; + return dsui; + } + } } diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/DataPort.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/DataPort.java index 49a416af3..d43ffff37 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/DataPort.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/ports/DataPort.java @@ -41,7 +41,7 @@ public DataPort(DriveCollection disk) { @Override public Byte readData() { - return disk.getCurrentDrive().map(Drive::readData).orElse((byte)0); + return disk.getCurrentDrive().map(Drive::readData).orElse((byte) 0); } @Override diff --git a/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/version.properties b/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/version.properties +++ b/plugins/device/88-dcdd/src/main/resources/net/emustudio/plugins/device/mits88dcdd/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DeviceImplTest.java b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DeviceImplTest.java index cc973512c..0c56e2f8f 100644 --- a/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DeviceImplTest.java +++ b/plugins/device/88-dcdd/src/test/java/net/emustudio/plugins/device/mits88dcdd/DeviceImplTest.java @@ -29,7 +29,6 @@ import org.junit.Test; import static org.easymock.EasyMock.*; -import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertNotEquals; public class DeviceImplTest { diff --git a/plugins/device/88-sio/build.gradle b/plugins/device/88-sio/build.gradle index 53074bbbe..7ce439c4e 100644 --- a/plugins/device/88-sio/build.gradle +++ b/plugins/device/88-sio/build.gradle @@ -46,8 +46,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java index ccba3596c..aa4402de1 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DeviceImpl.java @@ -40,8 +40,8 @@ import java.util.ResourceBundle; @PluginRoot( - type = PLUGIN_TYPE.DEVICE, - title = "MITS 88-SIO" + type = PLUGIN_TYPE.DEVICE, + title = "MITS 88-SIO" ) @SuppressWarnings("unused") public class DeviceImpl extends AbstractDevice { @@ -49,9 +49,9 @@ public class DeviceImpl extends AbstractDevice { private final SioUnitSettings sioSettings; private final UART.DeviceChannel deviceChannel; + private final boolean guiSupported; private SioUnit sioUnit; private UART uart; - private final boolean guiSupported; private SioGui gui; public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { @@ -65,7 +65,7 @@ public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register 88-SIO device context", e); applicationApi.getDialogs().showError( - "Could not register 88-SIO device channel. Please see log file for details.", super.getTitle() + "Could not register 88-SIO device channel. Please see log file for details.", super.getTitle() ); } } @@ -103,7 +103,7 @@ public void initialize() throws PluginInitializationException { DeviceContext device = applicationApi.getContextPool().getDeviceContext(pluginID, DeviceContext.class); if (device.getDataType() != Byte.class) { throw new PluginInitializationException( - "Unexpected device data type. Expected Byte but was: " + device.getDataType() + "Unexpected device data type. Expected Byte but was: " + device.getDataType() ); } uart.setDevice(device); diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnitSettings.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnitSettings.java index 0bd2a6a2f..8a89dc6d1 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnitSettings.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/SioUnitSettings.java @@ -61,19 +61,6 @@ public class SioUnitSettings { private volatile List statusPorts; private volatile List dataPorts; - public enum MAP_CHAR { - BACKSPACE, - DELETE, - UNDERSCORE, - UNCHANGED - } - - @FunctionalInterface - public interface SettingsObserver { - - void settingsChanged(); - } - public SioUnitSettings(BasicSettings settings) { this.settings = Objects.requireNonNull(settings); this.isClearInputBit8 = settings.getBoolean(KEY_CLEAR_INPUT_BIT8, false); @@ -96,18 +83,18 @@ public SioUnitSettings(BasicSettings settings) { RadixUtils r = RadixUtils.getInstance(); this.statusPorts = Arrays - .stream(settings.getString(KEY_STATUS_PORTS, "").split(",")) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .map(r::parseRadix) - .collect(Collectors.toList()); + .stream(settings.getString(KEY_STATUS_PORTS, "").split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .map(r::parseRadix) + .collect(Collectors.toList()); this.dataPorts = Arrays - .stream(settings.getString(KEY_DATA_PORTS, "").split(",")) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .map(r::parseRadix) - .collect(Collectors.toList()); + .stream(settings.getString(KEY_DATA_PORTS, "").split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .map(r::parseRadix) + .collect(Collectors.toList()); } public void addObserver(SettingsObserver observer) { @@ -175,9 +162,9 @@ public List getStatusPorts() { public void setStatusPorts(List value) { this.statusPorts = value; settings.setString(KEY_STATUS_PORTS, value.stream() - .map(i -> "0x" + Integer.toHexString(i)) - .reduce((s, s2) -> s + "," + s2) - .orElse("")); + .map(i -> "0x" + Integer.toHexString(i)) + .reduce((s, s2) -> s + "," + s2) + .orElse("")); notifySettingsChanged(); } @@ -188,9 +175,9 @@ public List getDataPorts() { public void setDataPorts(List value) { this.dataPorts = value; settings.setString(KEY_DATA_PORTS, value.stream() - .map(i -> "0x" + Integer.toHexString(i)) - .reduce((s, s2) -> s + "," + s2) - .orElse("")); + .map(i -> "0x" + Integer.toHexString(i)) + .reduce((s, s2) -> s + "," + s2) + .orElse("")); notifySettingsChanged(); } @@ -241,4 +228,17 @@ public List getDefaultDataPorts() { private void notifySettingsChanged() { observers.forEach(SettingsObserver::settingsChanged); } + + public enum MAP_CHAR { + BACKSPACE, + DELETE, + UNDERSCORE, + UNCHANGED + } + + @FunctionalInterface + public interface SettingsObserver { + + void settingsChanged(); + } } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java index b00848dc0..739364aaf 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java @@ -58,19 +58,20 @@ public class UART { private final static int INPUT_DEVICE_READY = 0x1; // ready to send data to CPU private final static Map RST_MAP = Map.of( - 0, (byte) 0xC7, - 1, (byte) 0xCF, - 2, (byte) 0xD7, - 3, (byte) 0xDF, - 4, (byte) 0xE7, - 5, (byte) 0xEF, - 6, (byte) 0xF7, - 7, (byte) 0xFF + 0, (byte) 0xC7, + 1, (byte) 0xCF, + 2, (byte) 0xD7, + 3, (byte) 0xDF, + 4, (byte) 0xE7, + 5, (byte) 0xEF, + 6, (byte) 0xF7, + 7, (byte) 0xFF ); private final AtomicReference bufferFromDevice = new AtomicReference<>(); private final Lock bufferAndStatusLock = new ReentrantLock(); - + private final Context8080 cpu; + private final List observers = new ArrayList<>(); private volatile DeviceContext device; private byte statusRegister = XMITTER_BUFFER_EMPTY; private volatile boolean interruptsSupported; @@ -78,20 +79,17 @@ public class UART { private volatile boolean outputInterruptEnabled; private volatile byte[] inputRstInterrupt; private volatile byte[] outputRstInterrupt; - private final Context8080 cpu; - - private final List observers = new ArrayList<>(); public UART(Context8080 cpu, SioUnitSettings settings) { this.cpu = Objects.requireNonNull(cpu); this.interruptsSupported = settings.getInterruptsSupported(); - this.inputRstInterrupt = new byte[] {RST_MAP.get(settings.getInputInterruptVector())}; - this.outputRstInterrupt = new byte[] {RST_MAP.get(settings.getOutputInterruptVector())}; + this.inputRstInterrupt = new byte[]{RST_MAP.get(settings.getInputInterruptVector())}; + this.outputRstInterrupt = new byte[]{RST_MAP.get(settings.getOutputInterruptVector())}; settings.addObserver(() -> { this.interruptsSupported = settings.getInterruptsSupported(); - this.inputRstInterrupt = new byte[] {RST_MAP.get(settings.getInputInterruptVector())}; - this.outputRstInterrupt = new byte[] {RST_MAP.get(settings.getOutputInterruptVector())}; + this.inputRstInterrupt = new byte[]{RST_MAP.get(settings.getInputInterruptVector())}; + this.outputRstInterrupt = new byte[]{RST_MAP.get(settings.getOutputInterruptVector())}; }); } @@ -121,11 +119,6 @@ void reset(boolean guiSupported) { statusRegister = XMITTER_BUFFER_EMPTY; } - public void setStatus(byte status) { - inputInterruptEnabled = (status & 1) == 1; - outputInterruptEnabled = (status & 2) == 2; - } - public void receiveFromDevice(byte data) { bufferAndStatusLock.lock(); int status = statusRegister; @@ -184,6 +177,11 @@ public byte getStatus() { return statusRegister; } + public void setStatus(byte status) { + inputInterruptEnabled = (status & 1) == 1; + outputInterruptEnabled = (status & 2) == 2; + } + public void addObserver(Observer observer) { observers.add(observer); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/PortListModel.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/PortListModel.java index 7c95071fd..35cbeed9a 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/PortListModel.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/PortListModel.java @@ -48,7 +48,7 @@ public List getAll() { public void clear() { ports.clear(); - fireContentsChanged(this, 0, - 1); + fireContentsChanged(this, 0, -1); } public void removeAt(int index) { diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java index 0b8809c07..c3a548b26 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SettingsDialog.java @@ -34,7 +34,28 @@ public class SettingsDialog extends JDialog { private final SioUnitSettings settings; private final PortListModel statusPortsModel = new PortListModel(); private final PortListModel dataPortsModel = new PortListModel(); - + private final JButton btnDataAdd = new JButton("Add"); + private final JButton btnDataDefaults = new JButton("Set default"); + private final JButton btnDataRemove = new JButton("Remove"); + private final JButton btnInterruptDefaults = new JButton("Set default"); + private final JButton btnSave = new JButton("Save"); + private final JButton btnStatusAdd = new JButton("Add"); + private final JButton btnStatusDefaults = new JButton("Set default"); + private final JButton btnStatusRemove = new JButton("Remove"); + private final JCheckBox chkAnsiMode = new JCheckBox("ANSI mode (clear output bit 8)"); + private final JCheckBox chkInterruptsSupported = new JCheckBox("Interrupts supported"); + private final JCheckBox chkToUpperCase = new JCheckBox("Convert input to upper-case"); + private final JCheckBox chkTtyMode = new JCheckBox("TTY mode (clear input bit 8)"); + private final JComboBox cmbMapBs = new JComboBox<>(new DefaultComboBoxModel<>( + SioUnitSettings.MAP_CHAR.values() + )); + private final JComboBox cmbMapDel = new JComboBox<>(new DefaultComboBoxModel<>( + SioUnitSettings.MAP_CHAR.values() + )); + private final JList lstDataPorts = new JList<>(); + private final JList lstStatusPorts = new JList<>(); + private final JSpinner spnInputInterrupt = new JSpinner(new SpinnerNumberModel(0, 0, 7, 1)); + private final JSpinner spnOutputInterrupt = new JSpinner(new SpinnerNumberModel(0, 0, 7, 1)); public SettingsDialog(JFrame parent, SioUnitSettings settings, Dialogs dialogs) { super(parent, true); @@ -73,7 +94,6 @@ private void setDefaultDataPorts() { dataPortsModel.addAll(settings.getDefaultDataPorts()); } - private void initComponents() { JTabbedPane tabbedPane = new JTabbedPane(); JPanel panelSettings = new JPanel(); @@ -101,41 +121,41 @@ private void initComponents() { GroupLayout panelSettingsLayout = new GroupLayout(panelSettings); panelSettings.setLayout(panelSettingsLayout); panelSettingsLayout.setHorizontalGroup( - panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelSettingsLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(chkTtyMode) - .addComponent(chkAnsiMode) - .addComponent(chkToUpperCase) + panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelSettingsLayout.createSequentialGroup() - .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblMapDel) - .addComponent(lblMapBs)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(cmbMapDel, 0, 157, Short.MAX_VALUE) - .addComponent(cmbMapBs, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) - .addContainerGap(128, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(chkTtyMode) + .addComponent(chkAnsiMode) + .addComponent(chkToUpperCase) + .addGroup(panelSettingsLayout.createSequentialGroup() + .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblMapDel) + .addComponent(lblMapBs)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(cmbMapDel, 0, 157, Short.MAX_VALUE) + .addComponent(cmbMapBs, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap(128, Short.MAX_VALUE)) ); panelSettingsLayout.setVerticalGroup( - panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelSettingsLayout.createSequentialGroup() - .addContainerGap() - .addComponent(chkTtyMode) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkAnsiMode) - .addGap(18, 18, 18) - .addComponent(chkToUpperCase) - .addGap(18, 18, 18) - .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblMapDel) - .addComponent(cmbMapDel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(cmbMapBs, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(lblMapBs)) - .addContainerGap(57, Short.MAX_VALUE)) + panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelSettingsLayout.createSequentialGroup() + .addContainerGap() + .addComponent(chkTtyMode) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkAnsiMode) + .addGap(18, 18, 18) + .addComponent(chkToUpperCase) + .addGap(18, 18, 18) + .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblMapDel) + .addComponent(cmbMapDel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSettingsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(cmbMapBs, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblMapBs)) + .addContainerGap(57, Short.MAX_VALUE)) ); tabbedPane.addTab("General settings", panelSettings); @@ -150,30 +170,30 @@ private void initComponents() { GroupLayout panelStatusChannelLayout = new GroupLayout(panelStatusChannel); panelStatusChannel.setLayout(panelStatusChannelLayout); panelStatusChannelLayout.setHorizontalGroup( - panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelStatusChannelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(srlStatus, GroupLayout.PREFERRED_SIZE, 67, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 30, Short.MAX_VALUE) - .addGroup(panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnStatusAdd, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnStatusRemove, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnStatusDefaults, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelStatusChannelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(srlStatus, GroupLayout.PREFERRED_SIZE, 67, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 30, Short.MAX_VALUE) + .addGroup(panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnStatusAdd, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnStatusRemove, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnStatusDefaults, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); panelStatusChannelLayout.setVerticalGroup( - panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelStatusChannelLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(srlStatus, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelStatusChannelLayout.createSequentialGroup() - .addComponent(btnStatusAdd) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnStatusRemove) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE) - .addComponent(btnStatusDefaults))) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(panelStatusChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(srlStatus, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(panelStatusChannelLayout.createSequentialGroup() + .addComponent(btnStatusAdd) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnStatusRemove) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE) + .addComponent(btnStatusDefaults))) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); panelDataChannel.setBorder(BorderFactory.createTitledBorder("Data channel ports")); @@ -186,58 +206,58 @@ private void initComponents() { GroupLayout panelDataChannelLayout = new GroupLayout(panelDataChannel); panelDataChannel.setLayout(panelDataChannelLayout); panelDataChannelLayout.setHorizontalGroup( - panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelDataChannelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(srlData, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnDataRemove, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnDataAdd, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnDataDefaults, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDataChannelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(srlData, GroupLayout.PREFERRED_SIZE, 66, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnDataRemove, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnDataAdd, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnDataDefaults, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); panelDataChannelLayout.setVerticalGroup( - panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelDataChannelLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(srlData, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelDataChannelLayout.createSequentialGroup() - .addComponent(btnDataAdd) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnDataRemove) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE) - .addComponent(btnDataDefaults))) - .addContainerGap()) + .addContainerGap() + .addGroup(panelDataChannelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(srlData, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(panelDataChannelLayout.createSequentialGroup() + .addComponent(btnDataAdd) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnDataRemove) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE) + .addComponent(btnDataDefaults))) + .addContainerGap()) ); GroupLayout panelCpuLayout = new GroupLayout(panelCpu); panelCpu.setLayout(panelCpuLayout); panelCpuLayout.setHorizontalGroup( - panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelCpuLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelCpuLayout.createSequentialGroup() - .addComponent(lblCpuNote, GroupLayout.PREFERRED_SIZE, 438, GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(panelCpuLayout.createSequentialGroup() - .addComponent(panelStatusChannel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelDataChannel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addContainerGap()) + .addContainerGap() + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(lblCpuNote, GroupLayout.PREFERRED_SIZE, 438, GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(panelCpuLayout.createSequentialGroup() + .addComponent(panelStatusChannel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelDataChannel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addContainerGap()) ); panelCpuLayout.setVerticalGroup( - panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelCpuLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblCpuNote, GroupLayout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(panelStatusChannel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(panelDataChannel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelCpuLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblCpuNote, GroupLayout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addGroup(panelCpuLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(panelStatusChannel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(panelDataChannel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); tabbedPane.addTab("Connection with CPU", panelCpu); @@ -245,46 +265,46 @@ private void initComponents() { GroupLayout panelInterruptsLayout = new GroupLayout(panelInterrupts); panelInterrupts.setLayout(panelInterruptsLayout); panelInterruptsLayout.setHorizontalGroup( - panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelInterruptsLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblInterruptsNote, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addGroup(GroupLayout.Alignment.TRAILING, panelInterruptsLayout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(btnInterruptDefaults)) + panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelInterruptsLayout.createSequentialGroup() - .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(chkInterruptsSupported) - .addGroup(panelInterruptsLayout.createSequentialGroup() - .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblInputInterrupt) - .addComponent(lblOutputInterrupt)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(spnInputInterrupt, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(spnOutputInterrupt, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))) - .addGap(0, 225, Short.MAX_VALUE))) - .addContainerGap()) + .addContainerGap() + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblInterruptsNote, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(GroupLayout.Alignment.TRAILING, panelInterruptsLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(btnInterruptDefaults)) + .addGroup(panelInterruptsLayout.createSequentialGroup() + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(chkInterruptsSupported) + .addGroup(panelInterruptsLayout.createSequentialGroup() + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblInputInterrupt) + .addComponent(lblOutputInterrupt)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(spnInputInterrupt, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(spnOutputInterrupt, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))) + .addGap(0, 225, Short.MAX_VALUE))) + .addContainerGap()) ); panelInterruptsLayout.setVerticalGroup( - panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, panelInterruptsLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblInterruptsNote, GroupLayout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(chkInterruptsSupported) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblInputInterrupt) - .addComponent(spnInputInterrupt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblOutputInterrupt) - .addComponent(spnOutputInterrupt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 27, Short.MAX_VALUE) - .addComponent(btnInterruptDefaults) - .addContainerGap()) + panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, panelInterruptsLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblInterruptsNote, GroupLayout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(chkInterruptsSupported) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblInputInterrupt) + .addComponent(spnInputInterrupt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelInterruptsLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblOutputInterrupt) + .addComponent(spnOutputInterrupt, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 27, Short.MAX_VALUE) + .addComponent(btnInterruptDefaults) + .addContainerGap()) ); tabbedPane.addTab("Interrupts", panelInterrupts); @@ -292,21 +312,21 @@ private void initComponents() { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(btnSave) - .addContainerGap()) - .addComponent(tabbedPane) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(btnSave) + .addContainerGap()) + .addComponent(tabbedPane) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(tabbedPane) - .addGap(12, 12, 12) - .addComponent(btnSave) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(tabbedPane) + .addGap(12, 12, 12) + .addComponent(btnSave) + .addContainerGap()) ); btnStatusAdd.addActionListener(e -> addPort("status", "data", statusPortsModel, dataPortsModel)); @@ -323,18 +343,17 @@ private void initComponents() { pack(); } - private void addPort(String nameAdd, String nameCheck, PortListModel portModelAdd, PortListModel portModelCheck) { try { dialogs - .readInteger("Enter port number:", "Add " + nameAdd + " port", 0) - .ifPresent(port -> { - if (portModelCheck.contains(port)) { - dialogs.showError("Port number is already taken by " + nameCheck + " port"); - } else { - portModelAdd.add(port); - } - }); + .readInteger("Enter port number:", "Add " + nameAdd + " port", 0) + .ifPresent(port -> { + if (portModelCheck.contains(port)) { + dialogs.showError("Port number is already taken by " + nameCheck + " port"); + } else { + portModelAdd.add(port); + } + }); } catch (NumberFormatException e) { dialogs.showError("Invalid number format", "Add " + nameAdd + " port"); } @@ -393,28 +412,4 @@ private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) { dispose(); } - - - private final JButton btnDataAdd = new JButton("Add"); - private final JButton btnDataDefaults = new JButton("Set default"); - private final JButton btnDataRemove = new JButton("Remove"); - private final JButton btnInterruptDefaults = new JButton("Set default"); - private final JButton btnSave = new JButton("Save"); - private final JButton btnStatusAdd = new JButton("Add"); - private final JButton btnStatusDefaults = new JButton("Set default"); - private final JButton btnStatusRemove = new JButton("Remove"); - private final JCheckBox chkAnsiMode = new JCheckBox("ANSI mode (clear output bit 8)"); - private final JCheckBox chkInterruptsSupported = new JCheckBox("Interrupts supported"); - private final JCheckBox chkToUpperCase = new JCheckBox("Convert input to upper-case"); - private final JCheckBox chkTtyMode = new JCheckBox("TTY mode (clear input bit 8)"); - private final JComboBox cmbMapBs = new JComboBox<>(new DefaultComboBoxModel<>( - SioUnitSettings.MAP_CHAR.values() - )); - private final JComboBox cmbMapDel = new JComboBox<>(new DefaultComboBoxModel<>( - SioUnitSettings.MAP_CHAR.values() - )); - private final JList lstDataPorts = new JList<>(); - private final JList lstStatusPorts = new JList<>(); - private final JSpinner spnInputInterrupt = new JSpinner(new SpinnerNumberModel(0, 0, 7, 1)); - private final JSpinner spnOutputInterrupt = new JSpinner(new SpinnerNumberModel(0, 0, 7, 1)); } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java index 221270102..edad26b14 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/gui/SioGui.java @@ -32,7 +32,12 @@ public class SioGui extends JDialog { private final static Font FONT_MONOSPACED_BOLD_14 = new Font("Monospaced", Font.BOLD, 14); private final UART uart; - + private final JButton btnClearBuffer = new JButton("Clear buffer"); + private final JLabel lblData = new JLabel("0x00"); + private final JLabel lblDataAscii = new JLabel("empty"); + private final JLabel lblStatus = new JLabel("0x00"); + private final JLabel lblStatusLong = new JLabel(". . . . . . . ."); + private final JTextField txtAttachedDevice = new JTextField(); public SioGui(JFrame parent, UART uart) { super(parent); @@ -74,7 +79,6 @@ private void setStatus(int status) { lblStatusLong.setText(r + d + o + x + i); } - private void initComponents() { JPanel panelAttachedDevice = new JPanel(); JPanel panelControl = new JPanel(); @@ -101,8 +105,8 @@ private void initComponents() { setTitle("MITS 88-SIO"); panelAttachedDevice.setBorder(BorderFactory.createTitledBorder( - null, "Attached device", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - FONT_BOLD_13)); + null, "Attached device", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, + FONT_BOLD_13)); txtAttachedDevice.setEditable(false); txtAttachedDevice.setFont(FONT_BOLD_14); @@ -110,23 +114,23 @@ private void initComponents() { GroupLayout panelAttachedDeviceLayout = new GroupLayout(panelAttachedDevice); panelAttachedDevice.setLayout(panelAttachedDeviceLayout); panelAttachedDeviceLayout.setHorizontalGroup( - panelAttachedDeviceLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelAttachedDeviceLayout.createSequentialGroup() - .addContainerGap() - .addComponent(txtAttachedDevice) - .addContainerGap()) + panelAttachedDeviceLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelAttachedDeviceLayout.createSequentialGroup() + .addContainerGap() + .addComponent(txtAttachedDevice) + .addContainerGap()) ); panelAttachedDeviceLayout.setVerticalGroup( - panelAttachedDeviceLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelAttachedDeviceLayout.createSequentialGroup() - .addContainerGap() - .addComponent(txtAttachedDevice, GroupLayout.PREFERRED_SIZE, 43, GroupLayout.PREFERRED_SIZE) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + panelAttachedDeviceLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelAttachedDeviceLayout.createSequentialGroup() + .addContainerGap() + .addComponent(txtAttachedDevice, GroupLayout.PREFERRED_SIZE, 43, GroupLayout.PREFERRED_SIZE) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); panelControl.setBorder(BorderFactory.createTitledBorder( - null, "Control channel", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - FONT_BOLD_13)); + null, "Control channel", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, + FONT_BOLD_13)); lblStatusLong.setFont(FONT_MONOSPACED_BOLD_14); lblStatusLong.setHorizontalAlignment(SwingConstants.CENTER); @@ -141,79 +145,79 @@ private void initComponents() { GroupLayout panelControlLayout = new GroupLayout(panelControl); panelControl.setLayout(panelControlLayout); panelControlLayout.setHorizontalGroup( - panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelControlLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, panelControlLayout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(lblStatusLong, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 238, Short.MAX_VALUE) - .addComponent(sepControl) - .addComponent(lblNoteControl, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))) + panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelControlLayout.createSequentialGroup() - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelControlLayout.createSequentialGroup() - .addComponent(lblHexControl) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblStatus)) - .addGroup(panelControlLayout.createSequentialGroup() - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblR) - .addComponent(lblD) - .addComponent(lblO) - .addComponent(lblX) - .addComponent(lblI)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblNoteX) - .addComponent(lblNoteO) - .addComponent(lblNoteR) - .addComponent(lblNoteD) - .addComponent(lblNoteI)))) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) + .addContainerGap() + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, panelControlLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(lblStatusLong, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 238, Short.MAX_VALUE) + .addComponent(sepControl) + .addComponent(lblNoteControl, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))) + .addGroup(panelControlLayout.createSequentialGroup() + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelControlLayout.createSequentialGroup() + .addComponent(lblHexControl) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblStatus)) + .addGroup(panelControlLayout.createSequentialGroup() + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblR) + .addComponent(lblD) + .addComponent(lblO) + .addComponent(lblX) + .addComponent(lblI)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblNoteX) + .addComponent(lblNoteO) + .addComponent(lblNoteR) + .addComponent(lblNoteD) + .addComponent(lblNoteI)))) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) ); panelControlLayout.setVerticalGroup( - panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelControlLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblNoteControl, GroupLayout.PREFERRED_SIZE, 46, GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(lblStatusLong, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblHexControl) - .addComponent(lblStatus)) - .addGap(18, 18, 18) - .addComponent(sepControl, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE) - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelControlLayout.createSequentialGroup() - .addGap(24, 24, 24) - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblD) - .addComponent(lblNoteD))) - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblNoteR) - .addComponent(lblR))) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblO) - .addComponent(lblNoteO)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblNoteX) - .addComponent(lblX)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblNoteI) - .addComponent(lblI)) - .addContainerGap(13, Short.MAX_VALUE)) + .addContainerGap() + .addComponent(lblNoteControl, GroupLayout.PREFERRED_SIZE, 46, GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(lblStatusLong, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblHexControl) + .addComponent(lblStatus)) + .addGap(18, 18, 18) + .addComponent(sepControl, GroupLayout.PREFERRED_SIZE, 10, GroupLayout.PREFERRED_SIZE) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelControlLayout.createSequentialGroup() + .addGap(24, 24, 24) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblD) + .addComponent(lblNoteD))) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblNoteR) + .addComponent(lblR))) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblO) + .addComponent(lblNoteO)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblNoteX) + .addComponent(lblX)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelControlLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblNoteI) + .addComponent(lblI)) + .addContainerGap(13, Short.MAX_VALUE)) ); panelData.setBorder(BorderFactory.createTitledBorder( - null, "Data buffer", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, - FONT_BOLD_13)); + null, "Data buffer", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, + FONT_BOLD_13)); lblDataAscii.setFont(FONT_BOLD_14); lblDataAscii.setHorizontalAlignment(SwingConstants.CENTER); @@ -224,73 +228,65 @@ private void initComponents() { GroupLayout panelDataLayout = new GroupLayout(panelData); panelData.setLayout(panelDataLayout); panelDataLayout.setHorizontalGroup( - panelDataLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelDataLayout.createSequentialGroup() - .addContainerGap() - .addGroup(panelDataLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, panelDataLayout.createSequentialGroup() - .addGap(0, 102, Short.MAX_VALUE) - .addComponent(btnClearBuffer)) + panelDataLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(panelDataLayout.createSequentialGroup() - .addComponent(lblHexData) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblData) - .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(lblNoteData, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addComponent(lblDataAscii, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + .addContainerGap() + .addGroup(panelDataLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, panelDataLayout.createSequentialGroup() + .addGap(0, 102, Short.MAX_VALUE) + .addComponent(btnClearBuffer)) + .addGroup(panelDataLayout.createSequentialGroup() + .addComponent(lblHexData) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblData) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(lblNoteData, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addComponent(lblDataAscii, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); panelDataLayout.setVerticalGroup( - panelDataLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelDataLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblNoteData, GroupLayout.PREFERRED_SIZE, 46, GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(lblDataAscii, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(panelDataLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblHexData) - .addComponent(lblData)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnClearBuffer) - .addContainerGap()) + panelDataLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelDataLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblNoteData, GroupLayout.PREFERRED_SIZE, 46, GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(lblDataAscii, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelDataLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblHexData) + .addComponent(lblData)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnClearBuffer) + .addContainerGap()) ); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(panelAttachedDevice, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(panelControl, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelData, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(panelAttachedDevice, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(panelControl, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelData, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(panelAttachedDevice, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(panelControl, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(panelData, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(panelAttachedDevice, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(panelControl, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelData, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); btnClearBuffer.addActionListener(e -> uart.readBuffer()); pack(); } - - - private final JButton btnClearBuffer = new JButton("Clear buffer"); - private final JLabel lblData = new JLabel("0x00"); - private final JLabel lblDataAscii = new JLabel("empty"); - private final JLabel lblStatus = new JLabel("0x00"); - private final JLabel lblStatusLong = new JLabel(". . . . . . . ."); - private final JTextField txtAttachedDevice = new JTextField(); } diff --git a/plugins/device/88-sio/src/main/resources/net/emustudio/plugins/device/mits88sio/version.properties b/plugins/device/88-sio/src/main/resources/net/emustudio/plugins/device/mits88sio/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/device/88-sio/src/main/resources/net/emustudio/plugins/device/mits88sio/version.properties +++ b/plugins/device/88-sio/src/main/resources/net/emustudio/plugins/device/mits88sio/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java index f1e56d2f5..460e442fe 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/DeviceImplTest.java @@ -30,7 +30,6 @@ import org.junit.Test; import static org.easymock.EasyMock.*; -import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertNotEquals; public class DeviceImplTest { @@ -41,9 +40,9 @@ public class DeviceImplTest { public void setup() throws PluginInitializationException { ContextPool contextPool = createNiceMock(ContextPool.class); expect(contextPool.getCPUContext(0, Context8080.class)) - .andReturn(createNiceMock(Context8080.class)).anyTimes(); + .andReturn(createNiceMock(Context8080.class)).anyTimes(); expect(contextPool.getDeviceContext(0, DeviceContext.class)) - .andThrow(new ContextNotFoundException("")).anyTimes(); + .andThrow(new ContextNotFoundException("")).anyTimes(); replay(contextPool); ApplicationApi applicationApi = createNiceMock(ApplicationApi.class); expect(applicationApi.getContextPool()).andReturn(contextPool).anyTimes(); diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java index 07e8f8ac8..6b6fa6d62 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/SioUnitTest.java @@ -30,8 +30,8 @@ public class SioUnitTest { @Test public void testCpuPortsAreReattached() { SioUnitSettings s = mock(SioUnitSettings.class); - expect(s.getStatusPorts()).andReturn(List.of(1,2)).anyTimes(); - expect(s.getDataPorts()).andReturn(List.of(4,5)).anyTimes(); + expect(s.getStatusPorts()).andReturn(List.of(1, 2)).anyTimes(); + expect(s.getDataPorts()).andReturn(List.of(4, 5)).anyTimes(); expect(s.getInterruptsSupported()).andReturn(true).anyTimes(); expect(s.getInputInterruptVector()).andReturn(7).anyTimes(); expect(s.getOutputInterruptVector()).andReturn(7).anyTimes(); @@ -55,7 +55,7 @@ public void testCpuPortsAreReattached() { expectLastCall().times(2); replay(cpu); - try(SioUnit sio = new SioUnit(s, cpu)) { + try (SioUnit sio = new SioUnit(s, cpu)) { sio.attach(); sio.attach(); } diff --git a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java index 4b3df94cc..1ee40a146 100644 --- a/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java +++ b/plugins/device/88-sio/src/test/java/net/emustudio/plugins/device/mits88sio/UARTTest.java @@ -21,7 +21,6 @@ import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.cpu.intel8080.api.Context8080; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import static org.easymock.EasyMock.*; diff --git a/plugins/device/abstract-tape/README.md b/plugins/device/abstract-tape/README.md index 2d6ed01d0..84db07551 100644 --- a/plugins/device/abstract-tape/README.md +++ b/plugins/device/abstract-tape/README.md @@ -7,5 +7,7 @@ The official documentation can be found [here][doc]. [RAM]: https://en.wikipedia.org/wiki/Random-access_machine + [RASP]: https://en.wikipedia.org/wiki/Random-access_stored-program_machine + [doc]: https://www.emustudio.net/docuser/ram/index/#ABSTRRACT_TAPE diff --git a/plugins/device/abstract-tape/build.gradle b/plugins/device/abstract-tape/build.gradle index dce1ecd04..505dcbcbd 100644 --- a/plugins/device/abstract-tape/build.gradle +++ b/plugins/device/abstract-tape/build.gradle @@ -43,8 +43,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java index c3dcdcccb..4c8e0d9a2 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java @@ -38,8 +38,8 @@ import java.util.ResourceBundle; @PluginRoot( - type = PLUGIN_TYPE.DEVICE, - title = "Abstract tape" + type = PLUGIN_TYPE.DEVICE, + title = "Abstract tape" ) @SuppressWarnings("unused") public class AbstractTape extends AbstractDevice { @@ -64,7 +64,7 @@ public AbstractTape(long pluginID, ApplicationApi applicationApi, PluginSettings } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register Abstract tape context", e); applicationApi.getDialogs().showError( - "Could not register abstract tape context. Please see log file for details.", super.getTitle() + "Could not register abstract tape context. Please see log file for details.", super.getTitle() ); } } diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java index 8acf82450..7ccd43939 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java @@ -38,7 +38,7 @@ public class AbstractTapeContextImpl implements AbstractTapeContext { private final AtomicReference symbolLog = new AtomicReference<>(); private final Map content = new HashMap<>(); private final Set acceptedTypes = new HashSet<>(Set.of( - TapeSymbol.Type.NUMBER, TapeSymbol.Type.STRING + TapeSymbol.Type.NUMBER, TapeSymbol.Type.STRING )); private final ReadWriteLock rwl = new ReentrantReadWriteLock(); @@ -53,11 +53,6 @@ public class AbstractTapeContextImpl implements AbstractTapeContext { private boolean displayRowNumbers = false; private TapeListener listener; - public interface TapeListener extends EventListener { - - void tapeChanged(); - } - AbstractTapeContextImpl(AbstractTape tape) { this.tape = Objects.requireNonNull(tape); leftBounded = false; @@ -121,13 +116,13 @@ void reset() { } @Override - public void setLeftBounded(boolean bounded) { - this.leftBounded = bounded; + public boolean isLeftBounded() { + return leftBounded; } @Override - public boolean isLeftBounded() { - return leftBounded; + public void setLeftBounded(boolean bounded) { + this.leftBounded = bounded; } @Override @@ -208,15 +203,15 @@ public void removeSymbolAt(int position) { fireChange(); } + public boolean getEditable() { + return editable; + } + @Override public void setEditable(boolean editable) { this.editable = editable; } - public boolean getEditable() { - return editable; - } - @Override public Optional getSymbolAt(int position) { rwl.readLock().lock(); @@ -354,7 +349,6 @@ private void writeSynchronized(Runnable r) { } } - private void fireChange() { if (listener != null) { listener.tapeChanged(); @@ -386,4 +380,9 @@ private void incrementContentPositions() { content.clear(); content.putAll(newContent); } + + public interface TapeListener extends EventListener { + + void tapeChanged(); + } } diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java index 075fa0e30..55cd961fd 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java @@ -59,19 +59,19 @@ public interface AbstractTapeContext extends DeviceContext { Set getAcceptedTypes(); /** - * Set this tape to left-bounded or unbounded. + * Determine if the tape is left-bounded. * - * @param bounded true if the tape should be left-bounded, - * false if unbounded. + * @return true - left-bounded, false - unbounded. */ - void setLeftBounded(boolean bounded); + boolean isLeftBounded(); /** - * Determine if the tape is left-bounded. + * Set this tape to left-bounded or unbounded. * - * @return true - left-bounded, false - unbounded. + * @param bounded true if the tape should be left-bounded, + * false if unbounded. */ - boolean isLeftBounded(); + void setLeftBounded(boolean bounded); /** * Move the tape one symbol to the left. @@ -182,6 +182,7 @@ public interface AbstractTapeContext extends DeviceContext { /** * {@inheritDoc} + * * @throws IllegalArgumentException if the symbol type is not among accepted ones */ void writeData(TapeSymbol value); diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java index 9881255a0..11083ad90 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java @@ -24,16 +24,10 @@ import static net.emustudio.plugins.device.abstracttape.api.TapeSymbol.Type.STRING; public class TapeSymbol { - public enum Type { - NUMBER, STRING - } - public final static TapeSymbol EMPTY = new TapeSymbol(""); - public final int number; public final String string; public final Type type; - public TapeSymbol(String string) { this.string = Objects.requireNonNullElse(string, ""); this.number = 0; @@ -72,4 +66,8 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(number, string, type); } + + public enum Type { + NUMBER, STRING + } } diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/SettingsDialog.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/SettingsDialog.java index 1dec42a87..4a510a723 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/SettingsDialog.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/SettingsDialog.java @@ -18,9 +18,9 @@ */ package net.emustudio.plugins.device.abstracttape.gui; +import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; import net.emustudio.emulib.runtime.settings.PluginSettings; -import net.emustudio.emulib.runtime.interaction.Dialogs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,6 +35,8 @@ public class SettingsDialog extends JDialog { private final PluginSettings settings; private final Dialogs dialogs; private final TapeGui gui; + private JCheckBox chkAlwaysOnTop; + private JCheckBox chkShowAtStartup; public SettingsDialog(JFrame parent, PluginSettings settings, Dialogs dialogs, TapeGui gui, String title) { super(parent, true); @@ -85,27 +87,24 @@ private void initComponents() { pane.setLayout(layout); layout.setHorizontalGroup( - layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(chkAlwaysOnTop) - .addComponent(chkShowAtStartup) - .addGroup(layout.createSequentialGroup() - .addContainerGap(-1, Short.MAX_VALUE) - .addComponent(btnSave))) - .addContainerGap()); + layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(chkAlwaysOnTop) + .addComponent(chkShowAtStartup) + .addGroup(layout.createSequentialGroup() + .addContainerGap(-1, Short.MAX_VALUE) + .addComponent(btnSave))) + .addContainerGap()); layout.setVerticalGroup( - layout.createSequentialGroup() - .addContainerGap() - .addComponent(chkAlwaysOnTop) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkShowAtStartup) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(btnSave) - .addContainerGap()); + layout.createSequentialGroup() + .addContainerGap() + .addComponent(chkAlwaysOnTop) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkShowAtStartup) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(btnSave) + .addContainerGap()); pack(); } - - private JCheckBox chkAlwaysOnTop; - private JCheckBox chkShowAtStartup; } diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java index 26cdf5cb7..d42510580 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeGui.java @@ -89,27 +89,27 @@ private void initComponents() { btnAddFirst.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/device/abstracttape/gui/go-up.png"))); btnAddFirst.addActionListener(e -> dialogs - .readString("Symbol value:", "Add symbol (on top)") - .map(TapeSymbol::guess) - .ifPresent(s -> { - try { - tapeContext.addFirst(s); - } catch (IllegalArgumentException ignored) { - dialogs.showError("Unexpected symbol type. Supported types: " + tapeContext.getAcceptedTypes()); - } - })); + .readString("Symbol value:", "Add symbol (on top)") + .map(TapeSymbol::guess) + .ifPresent(s -> { + try { + tapeContext.addFirst(s); + } catch (IllegalArgumentException ignored) { + dialogs.showError("Unexpected symbol type. Supported types: " + tapeContext.getAcceptedTypes()); + } + })); btnAddLast.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/device/abstracttape/gui/go-down.png"))); btnAddLast.addActionListener(e -> dialogs - .readString("Symbol value:", "Add symbol (on bottom)") - .map(TapeSymbol::guess) - .ifPresent(s -> { - try { - tapeContext.addLast(s); - } catch (IllegalArgumentException ignored) { - dialogs.showError("Unexpected symbol type. Supported types: " + tapeContext.getAcceptedTypes()); - } - })); + .readString("Symbol value:", "Add symbol (on bottom)") + .map(TapeSymbol::guess) + .ifPresent(s -> { + try { + tapeContext.addLast(s); + } catch (IllegalArgumentException ignored) { + dialogs.showError("Unexpected symbol type. Supported types: " + tapeContext.getAcceptedTypes()); + } + })); btnEdit.addActionListener(e -> { int symbolIndex = lstTape.getSelectedIndex(); @@ -117,9 +117,9 @@ private void initComponents() { dialogs.showError("A symbol must be selected"); } else { dialogs - .readString("Enter symbol value:", "Edit symbol", tapeContext.getSymbolAt(symbolIndex).toString()) - .map(TapeSymbol::guess) - .ifPresent(symbol -> tapeContext.setSymbolAt(symbolIndex, symbol)); + .readString("Enter symbol value:", "Edit symbol", tapeContext.getSymbolAt(symbolIndex).toString()) + .map(TapeSymbol::guess) + .ifPresent(symbol -> tapeContext.setSymbolAt(symbolIndex, symbol)); } }); btnRemove.addActionListener(e -> { @@ -135,31 +135,31 @@ private void initComponents() { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(btnEdit, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnClear, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnRemove, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnAddLast, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnAddFirst, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(scrollTape, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 148, Short.MAX_VALUE) - ).addContainerGap()); + layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(btnEdit, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnClear, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnRemove, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnAddLast, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnAddFirst, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(scrollTape, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 148, Short.MAX_VALUE) + ).addContainerGap()); layout.setVerticalGroup( - layout.createSequentialGroup() - .addContainerGap() - .addComponent(btnAddFirst) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(scrollTape, GroupLayout.PREFERRED_SIZE, 200, Short.MAX_VALUE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnAddLast) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(btnRemove) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnEdit) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnClear) - .addContainerGap()); + layout.createSequentialGroup() + .addContainerGap() + .addComponent(btnAddFirst) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(scrollTape, GroupLayout.PREFERRED_SIZE, 200, Short.MAX_VALUE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnAddLast) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(btnRemove) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnEdit) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnClear) + .addContainerGap()); pack(); } } diff --git a/plugins/device/abstract-tape/src/main/resources/net/emustudio/plugins/device/abstracttape/version.properties b/plugins/device/abstract-tape/src/main/resources/net/emustudio/plugins/device/abstracttape/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/device/abstract-tape/src/main/resources/net/emustudio/plugins/device/abstracttape/version.properties +++ b/plugins/device/abstract-tape/src/main/resources/net/emustudio/plugins/device/abstracttape/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/device/adm3A-terminal/README.md b/plugins/device/adm3A-terminal/README.md index 6cda2a47f..6ed6e4d1f 100644 --- a/plugins/device/adm3A-terminal/README.md +++ b/plugins/device/adm3A-terminal/README.md @@ -3,7 +3,8 @@ This project is emulator of device [LSI ADM-3A](http://en.wikipedia.org/wiki/ADM-3A) terminal. It is part of [emuStudio](https://www.emustudio.net/). -The official documentation can be found [here](https://www.emustudio.net/docuser/mits_altair_8800/index/#terminal-code-adm3a-terminal-code) +The official documentation can be +found [here](https://www.emustudio.net/docuser/mits_altair_8800/index/#terminal-code-adm3a-terminal-code) ## Additional credits diff --git a/plugins/device/adm3A-terminal/build.gradle b/plugins/device/adm3A-terminal/build.gradle index c852898f2..9b2dcbeae 100644 --- a/plugins/device/adm3A-terminal/build.gradle +++ b/plugins/device/adm3A-terminal/build.gradle @@ -44,8 +44,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index 9389fea58..8f21fa2ba 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -23,14 +23,20 @@ import net.emustudio.emulib.plugins.annotations.PluginRoot; import net.emustudio.emulib.plugins.device.AbstractDevice; import net.emustudio.emulib.plugins.device.DeviceContext; -import net.emustudio.emulib.runtime.*; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; +import net.emustudio.emulib.runtime.ContextNotFoundException; +import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.device.adm3a.api.ContextAdm3A; import net.emustudio.plugins.device.adm3a.api.Keyboard; import net.emustudio.plugins.device.adm3a.gui.ConfigDialog; import net.emustudio.plugins.device.adm3a.gui.GuiUtils; import net.emustudio.plugins.device.adm3a.gui.TerminalWindow; -import net.emustudio.plugins.device.adm3a.interaction.*; +import net.emustudio.plugins.device.adm3a.interaction.Cursor; +import net.emustudio.plugins.device.adm3a.interaction.Display; +import net.emustudio.plugins.device.adm3a.interaction.KeyboardFromFile; +import net.emustudio.plugins.device.adm3a.interaction.KeyboardGui; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,8 +48,8 @@ import static net.emustudio.plugins.device.adm3a.gui.DisplayFont.fromTerminalFont; @PluginRoot( - type = PLUGIN_TYPE.DEVICE, - title = "LSI ADM-3A terminal" + type = PLUGIN_TYPE.DEVICE, + title = "LSI ADM-3A terminal" ) public class DeviceImpl extends AbstractDevice implements TerminalSettings.ChangedObserver { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceImpl.class); @@ -53,10 +59,8 @@ public class DeviceImpl extends AbstractDevice implements TerminalSettings.Chang private final TerminalSettings terminalSettings; private final ContextAdm3A terminalContext; private final Keyboard keyboard; - - private boolean guiIOset = false; private final Display display; - + private boolean guiIOset = false; private TerminalWindow terminalGUI; public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { @@ -78,7 +82,7 @@ public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register ADM-3A terminal", e); applicationApi.getDialogs().showError( - "Could not register ADM-3A terminal. Please see log file for more details", getTitle() + "Could not register ADM-3A terminal. Please see log file for more details", getTitle() ); } } @@ -89,11 +93,11 @@ public void initialize() throws PluginInitializationException { try { // get serial I/O board DeviceContext device = applicationApi.getContextPool().getDeviceContext( - pluginID, DeviceContext.class, terminalSettings.getDeviceIndex() + pluginID, DeviceContext.class, terminalSettings.getDeviceIndex() ); if (device.getDataType() != Byte.class) { throw new PluginInitializationException( - "Unexpected device data type. Expected Byte but was: " + device.getDataType() + "Unexpected device data type. Expected Byte but was: " + device.getDataType() ); } terminalContext.setExternalDevice(device); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java index 89e62cfcd..1a868afa0 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java @@ -18,9 +18,9 @@ */ package net.emustudio.plugins.device.adm3a; +import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; import net.emustudio.emulib.runtime.settings.PluginSettings; -import net.emustudio.emulib.runtime.interaction.Dialogs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,10 +31,9 @@ import java.util.Objects; public class TerminalSettings { - private final static Logger LOGGER = LoggerFactory.getLogger(TerminalSettings.class); - public final static String DEFAULT_INPUT_FILE_NAME = "adm3A-terminal.in"; public final static String DEFAULT_OUTPUT_FILE_NAME = "adm3A-terminal.out"; + private final static Logger LOGGER = LoggerFactory.getLogger(TerminalSettings.class); private final static String ANTI_ALIASING = "antiAliasing"; private final static String HALF_DUPLEX = "halfDuplex"; private final static String ALWAYS_ON_TOP = "alwaysOnTop"; @@ -43,22 +42,10 @@ public class TerminalSettings { private final static String INPUT_READ_DELAY = "inputReadDelay"; private final static String DEVICE_INDEX = "deviceIndex"; private final static String FONT = "font"; - - public enum TerminalFont { - ORIGINAL("original"), - MODERN("modern"); - - public final String name; - - TerminalFont(String name) { - this.name = Objects.requireNonNull(name); - } - } - private final Dialogs dialogs; private final PluginSettings settings; private final boolean guiSupported; - + private final List observers = new ArrayList<>(); private boolean halfDuplex = false; private boolean antiAliasing = true; private boolean alwaysOnTop = false; @@ -68,12 +55,6 @@ public enum TerminalFont { private int deviceIndex = 0; private TerminalFont font = TerminalFont.ORIGINAL; - private final List observers = new ArrayList<>(); - - public interface ChangedObserver { - void settingsChanged() throws IOException; - } - TerminalSettings(PluginSettings settings, Dialogs dialogs) { this.dialogs = Objects.requireNonNull(dialogs); this.settings = Objects.requireNonNull(settings); @@ -194,7 +175,7 @@ private void readSettings() { } catch (NumberFormatException e) { inputReadDelay = 0; LOGGER.error( - "Could not read '" + INPUT_READ_DELAY + "' setting. Using default value ({})", inputReadDelay, e + "Could not read '" + INPUT_READ_DELAY + "' setting. Using default value ({})", inputReadDelay, e ); } font = TerminalFont.valueOf(settings.getString(FONT, TerminalFont.ORIGINAL.name).toUpperCase()); @@ -216,4 +197,19 @@ private void notifyObserversAndIgnoreError() { } } } + + public enum TerminalFont { + ORIGINAL("original"), + MODERN("modern"); + + public final String name; + + TerminalFont(String name) { + this.name = Objects.requireNonNull(name); + } + } + + public interface ChangedObserver { + void settingsChanged() throws IOException; + } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/Utils.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/Utils.java index dc9288c1f..b1aacf858 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/Utils.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/Utils.java @@ -42,10 +42,10 @@ public static FontRenderContext getDefaultFrc() { tx = new AffineTransform(); } else { tx = GraphicsEnvironment - .getLocalGraphicsEnvironment() - .getDefaultScreenDevice() - .getDefaultConfiguration() - .getDefaultTransform(); + .getLocalGraphicsEnvironment() + .getDefaultScreenDevice() + .getDefaultConfiguration() + .getDefaultTransform(); } DEFAULT_FRC = new FontRenderContext(tx, false, false); } @@ -58,9 +58,9 @@ public static Font loadFont(DisplayFont displayFont) { try (InputStream fin = Utils.class.getResourceAsStream(displayFont.path)) { Font font = Font - .createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(fin)) - .deriveFont(Font.PLAIN, displayFont.fontSize) - .deriveFont(attrs); + .createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(fin)) + .deriveFont(Font.PLAIN, displayFont.fontSize) + .deriveFont(attrs); GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font); return font; } catch (Exception e) { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java index f7c664def..d813c09b0 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java @@ -35,7 +35,14 @@ public class ConfigDialog extends JDialog { private final TerminalSettings settings; private final TerminalWindow window; private final Dialogs dialogs; - + private final JCheckBox chkAlwaysOnTop = new JCheckBox("Display always on top"); + private final JCheckBox chkAntiAliasing = new JCheckBox("Use anti-aliasing"); + private final JCheckBox chkHalfDuplex = new JCheckBox("Half duplex mode"); + private final JCheckBox chkSaveSettings = new JCheckBox("Save settings"); + private final JSpinner spnInputDelay = new JSpinner(); + private final JTextField txtInputFileName = new JTextField(DEFAULT_INPUT_FILE_NAME); + private final JTextField txtOutputFileName = new JTextField(DEFAULT_OUTPUT_FILE_NAME); + private final JComboBox cmbFont = new JComboBox<>(); public ConfigDialog(JFrame parent, TerminalSettings settings, TerminalWindow window, Dialogs dialogs) { super(parent, true); @@ -90,8 +97,8 @@ private void initComponents() { setTitle("Configuration of the terminal"); panelRedirectIO.setBorder(BorderFactory.createTitledBorder( - null, "Redirect I/O", 0, 0, - lblInputFileName.getFont().deriveFont(lblInputFileName.getFont().getStyle() | Font.BOLD) + null, "Redirect I/O", 0, 0, + lblInputFileName.getFont().deriveFont(lblInputFileName.getFont().getStyle() | Font.BOLD) )); cmbFont.setModel(new DefaultComboBoxModel<>(new String[]{"Original", "Modern"})); @@ -108,122 +115,122 @@ private void initComponents() { GroupLayout layoutRedirectIO = new GroupLayout(panelRedirectIO); panelRedirectIO.setLayout(layoutRedirectIO); layoutRedirectIO.setHorizontalGroup( - layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layoutRedirectIO.createSequentialGroup() - .addContainerGap() - .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblNote) + layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layoutRedirectIO.createSequentialGroup() - .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) + .addContainerGap() .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblInputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(lblOutputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)) - .addComponent(lblInputDelay)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layoutRedirectIO.createSequentialGroup() - .addComponent(txtOutputFileName, GroupLayout.PREFERRED_SIZE, 241, Short.MAX_VALUE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnOutputBrowse)) - .addGroup(GroupLayout.Alignment.TRAILING, layoutRedirectIO.createSequentialGroup() - .addComponent(txtInputFileName, GroupLayout.PREFERRED_SIZE, 241, Short.MAX_VALUE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnInputBrowse)) - .addGroup(layoutRedirectIO.createSequentialGroup() - .addComponent(spnInputDelay, GroupLayout.PREFERRED_SIZE, 73, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblMs))))) - .addContainerGap()) + .addComponent(lblNote) + .addGroup(layoutRedirectIO.createSequentialGroup() + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblInputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblOutputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)) + .addComponent(lblInputDelay)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutRedirectIO.createSequentialGroup() + .addComponent(txtOutputFileName, GroupLayout.PREFERRED_SIZE, 241, Short.MAX_VALUE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnOutputBrowse)) + .addGroup(GroupLayout.Alignment.TRAILING, layoutRedirectIO.createSequentialGroup() + .addComponent(txtInputFileName, GroupLayout.PREFERRED_SIZE, 241, Short.MAX_VALUE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnInputBrowse)) + .addGroup(layoutRedirectIO.createSequentialGroup() + .addComponent(spnInputDelay, GroupLayout.PREFERRED_SIZE, 73, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblMs))))) + .addContainerGap()) ); layoutRedirectIO.setVerticalGroup( - layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, layoutRedirectIO.createSequentialGroup() - .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblInputFileName) - .addComponent(txtInputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(btnInputBrowse)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblOutputFileName) - .addComponent(txtOutputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(btnOutputBrowse)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblInputDelay) - .addComponent(spnInputDelay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(lblMs)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 21, Short.MAX_VALUE) - .addComponent(lblNote)) + layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, layoutRedirectIO.createSequentialGroup() + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblInputFileName) + .addComponent(txtInputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(btnInputBrowse)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblOutputFileName) + .addComponent(txtOutputFileName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(btnOutputBrowse)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layoutRedirectIO.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblInputDelay) + .addComponent(spnInputDelay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblMs)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 21, Short.MAX_VALUE) + .addComponent(lblNote)) ); panelTerminal.setBorder(BorderFactory.createTitledBorder( - null, "Terminal", 0, 0, - lblInputFileName.getFont().deriveFont(lblInputFileName.getFont().getStyle() | Font.BOLD) + null, "Terminal", 0, 0, + lblInputFileName.getFont().deriveFont(lblInputFileName.getFont().getStyle() | Font.BOLD) )); GroupLayout layoutTerminal = new GroupLayout(panelTerminal); panelTerminal.setLayout(layoutTerminal); layoutTerminal.setHorizontalGroup( - layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layoutTerminal.createSequentialGroup() - .addContainerGap() - .addGroup(layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) + layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layoutTerminal.createSequentialGroup() - .addComponent(lblFont) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(cmbFont)) - .addComponent(chkHalfDuplex) - .addComponent(chkAlwaysOnTop) - .addComponent(chkAntiAliasing)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutTerminal.createSequentialGroup() + .addComponent(lblFont) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cmbFont)) + .addComponent(chkHalfDuplex) + .addComponent(chkAlwaysOnTop) + .addComponent(chkAntiAliasing)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layoutTerminal.setVerticalGroup( - layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layoutTerminal.createSequentialGroup() - .addGroup(layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblFont) - .addComponent(cmbFont)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkHalfDuplex) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkAlwaysOnTop) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkAntiAliasing) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layoutTerminal.createSequentialGroup() + .addGroup(layoutTerminal.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblFont) + .addComponent(cmbFont)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkHalfDuplex) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkAlwaysOnTop) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkAntiAliasing) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(panelRedirectIO, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(panelTerminal, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) - .addGroup(layout.createSequentialGroup() - .addComponent(chkSaveSettings)))) - .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnOK, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(panelRedirectIO, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(layout.createSequentialGroup() + .addComponent(panelTerminal, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(layout.createSequentialGroup() + .addComponent(chkSaveSettings)))) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnOK, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(18, 18, 18) - .addComponent(panelRedirectIO, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelTerminal, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkSaveSettings) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnOK) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(18, 18, 18) + .addComponent(panelRedirectIO, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelTerminal, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(chkSaveSettings) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnOK) + .addContainerGap()) ); pack(); @@ -233,7 +240,7 @@ private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { if (window != null) { window.setAlwaysOnTop(chkAlwaysOnTop.isSelected()); window.setDisplayFont(DisplayFont.fromTerminalFont( - TerminalSettings.TerminalFont.valueOf(cmbFont.getSelectedItem().toString().toUpperCase()))); + TerminalSettings.TerminalFont.valueOf(cmbFont.getSelectedItem().toString().toUpperCase()))); } try { updateSettings(chkSaveSettings.isSelected()); @@ -242,13 +249,4 @@ private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { dialogs.showError("Input or output file names (or both) do not exist. Please make sure they do.", "ADM-3A Terminal"); } } - - private final JCheckBox chkAlwaysOnTop = new JCheckBox("Display always on top"); - private final JCheckBox chkAntiAliasing = new JCheckBox("Use anti-aliasing"); - private final JCheckBox chkHalfDuplex = new JCheckBox("Half duplex mode"); - private final JCheckBox chkSaveSettings = new JCheckBox("Save settings"); - private final JSpinner spnInputDelay = new JSpinner(); - private final JTextField txtInputFileName = new JTextField(DEFAULT_INPUT_FILE_NAME); - private final JTextField txtOutputFileName = new JTextField(DEFAULT_OUTPUT_FILE_NAME); - private final JComboBox cmbFont = new JComboBox<>(); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java index 99d11b746..765deb217 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java @@ -33,12 +33,10 @@ public class DisplayCanvas extends Canvas implements AutoCloseable { private static final Color FOREGROUND = new Color(255, 255, 255); private static final Color BACKGROUND = Color.BLACK; - - private volatile DisplayFont displayFont; private final Timer repaintTimer; private final Display display; - private final AtomicBoolean painting = new AtomicBoolean(false); + private volatile DisplayFont displayFont; private volatile Dimension size = new Dimension(0, 0); public DisplayCanvas(DisplayFont displayFont, Display display) { @@ -128,11 +126,11 @@ protected void paint() { graphics.setRenderingHint(KEY_STROKE_CONTROL, VALUE_STROKE_NORMALIZE); for (int y = 0; y < display.rows; y++) { graphics.drawChars( - display.videoMemory, - y * display.columns, - display.columns, - 1, - (y + 1) * lineHeight); + display.videoMemory, + y * display.columns, + display.columns, + 1, + (y + 1) * lineHeight); } paintCursor(graphics, lineHeight); graphics.dispose(); @@ -152,7 +150,7 @@ private void paintCursor(Graphics graphics, int lineHeight) { Rectangle2D fontRectangle = getFont().getMaxCharBounds(graphics.getFontMetrics().getFontRenderContext()); int x = displayFont.xCursorOffset - + (int) (cursorPoint.x * (fontRectangle.getWidth() + displayFont.xCursorMultiplierOffset)); + + (int) (cursorPoint.x * (fontRectangle.getWidth() + displayFont.xCursorMultiplierOffset)); int y = displayFont.yCursorOffset + (cursorPoint.y * lineHeight); graphics.fillRect(x, y, (int) fontRectangle.getWidth(), (int) fontRectangle.getHeight() + displayFont.yCursorExtend); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java index 0d8c4e7b0..3fcbadb1f 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java @@ -25,13 +25,13 @@ public class DisplayFont { public static final DisplayFont FONT_ORIGINAL = new DisplayFont( - "/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf", - 2, 0.3, 3, 5, 15, 5 + "/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf", + 2, 0.3, 3, 5, 15, 5 ); public static final DisplayFont FONT_MODERN = new DisplayFont( - "/net/emustudio/plugins/device/adm3a/gui/terminal.ttf", - 2, 0, 3, 0, 15, 0 + "/net/emustudio/plugins/device/adm3a/gui/terminal.ttf", + 2, 0, 3, 0, 15, 0 ); public final String path; diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java index a52f0c9ef..249015b61 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java @@ -21,7 +21,6 @@ import net.emustudio.plugins.device.adm3a.interaction.Display; import javax.swing.*; -import javax.swing.border.TitledBorder; import java.awt.*; import java.util.Objects; diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java index 2e01ed1d3..78d44f041 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java @@ -31,11 +31,6 @@ public class Cursor { private final AtomicReference cursorPoint = new AtomicReference<>(new Point()); - interface LineRoller { - - void rollLine(); - } - public Cursor(int columns, int rows) { this.columns = columns; this.rows = rows; @@ -121,7 +116,6 @@ void moveDown(LineRoller lineRoller) { }); } - void carriageReturn() { setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); @@ -141,4 +135,9 @@ private void setCursorPoint(Function changer) { newPoint = changer.apply(oldPoint); } while (!cursorPoint.compareAndSet(oldPoint, newPoint)); } + + interface LineRoller { + + void rollLine(); + } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java index b01238611..cecf0855a 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java @@ -28,16 +28,9 @@ public class LoadCursorPosition { private static final int ASCII_ESC = 0x1B; // Offset in ASCII for X and Y coordinate private static final int ASCII_COORDINATE_OFFSET = 32; - - enum ExpectedSequence { - ESCAPE, ASSIGN, X, Y - } - private final Cursor cursor; - private volatile ExpectedSequence expect = ESCAPE; private int cursorY; - public LoadCursorPosition(Cursor cursor) { this.cursor = Objects.requireNonNull(cursor); } @@ -82,4 +75,8 @@ boolean notAccepted(byte data) { return true; } + + enum ExpectedSequence { + ESCAPE, ASSIGN, X, Y + } } diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/version.properties b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/version.properties index 7bbe30011..3e3d2e76c 100644 --- a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/version.properties +++ b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo; \u00A9 Copyright 2020, Marcin Wieczorek diff --git a/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/DeviceImplTest.java b/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/DeviceImplTest.java index 9651d106b..c8ae1b2b8 100644 --- a/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/DeviceImplTest.java +++ b/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/DeviceImplTest.java @@ -20,8 +20,8 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/plugins/device/brainduck-terminal/README.md b/plugins/device/brainduck-terminal/README.md index b47462a87..ac57ef033 100644 --- a/plugins/device/brainduck-terminal/README.md +++ b/plugins/device/brainduck-terminal/README.md @@ -3,4 +3,5 @@ This project is emulator of abstract device - terminal for BrainDuck architecture. It is part of [emuStudio](https://www.emustudio.net/). -The official documentation can be found [here](https://www.emustudio.net/docuser/brainduck/index/#terminal-code-brainduck-terminal-code) +The official documentation can be +found [here](https://www.emustudio.net/docuser/brainduck/index/#terminal-code-brainduck-terminal-code) diff --git a/plugins/device/brainduck-terminal/build.gradle b/plugins/device/brainduck-terminal/build.gradle index a6138eb4c..8e547f8e7 100644 --- a/plugins/device/brainduck-terminal/build.gradle +++ b/plugins/device/brainduck-terminal/build.gradle @@ -46,8 +46,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/BrainTerminalGui.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/BrainTerminalGui.java index a6a6ab518..d65fcd701 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/BrainTerminalGui.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/BrainTerminalGui.java @@ -37,6 +37,10 @@ class BrainTerminalGui extends JDialog implements OutputProvider, Keyboard.Keybo private final Display canvas; private final Keyboard keyboard; + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnASCII; + private javax.swing.JLabel lblStatusIcon; + private javax.swing.JScrollPane scrollPane; private BrainTerminalGui(JFrame parent, Keyboard keyboard, Dialogs dialogs) { super(parent); @@ -67,6 +71,13 @@ private BrainTerminalGui(JFrame parent, Keyboard keyboard, Dialogs dialogs) { canvas.start(); } + static BrainTerminalGui create(JFrame parent, Keyboard keyboard, Dialogs dialogs) { + BrainTerminalGui dialog = new BrainTerminalGui(parent, keyboard, dialogs); + GUIUtils.addListenerRecursively(dialog, dialog.keyboard); + dialog.keyboard.addListener(dialog); + return dialog; + } + @Override public void readStarted() { lblStatusIcon.setIcon(greenIcon); @@ -129,14 +140,6 @@ public void close() { dispose(); } - - static BrainTerminalGui create(JFrame parent, Keyboard keyboard, Dialogs dialogs) { - BrainTerminalGui dialog = new BrainTerminalGui(parent, keyboard, dialogs); - GUIUtils.addListenerRecursively(dialog, dialog.keyboard); - dialog.keyboard.addListener(dialog); - return dialog; - } - private void writeStarted() { lblStatusIcon.setIcon(redIcon); lblStatusIcon.repaint(); @@ -171,18 +174,18 @@ private void initComponents() { javax.swing.GroupLayout panelStatusLayout = new javax.swing.GroupLayout(panelStatus); panelStatus.setLayout(panelStatusLayout); panelStatusLayout.setHorizontalGroup( - panelStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(panelStatusLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblStatusIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnASCII) - .addContainerGap(664, Short.MAX_VALUE)) + panelStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelStatusLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblStatusIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnASCII) + .addContainerGap(664, Short.MAX_VALUE)) ); panelStatusLayout.setVerticalGroup( - panelStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(lblStatusIcon, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnASCII, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE) + panelStatusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lblStatusIcon, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnASCII, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE) ); scrollPane.setBackground(new java.awt.Color(255, 255, 255)); @@ -190,16 +193,16 @@ private void initComponents() { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(panelStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(scrollPane) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(panelStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(scrollPane) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 407, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 407, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); pack(); @@ -207,26 +210,21 @@ private void initComponents() { private void btnASCIIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnASCIIActionPerformed dialogs - .readString("Enter ASCII codes separated with spaces:", "Add ASCII codes") - .ifPresent(asciiCodes -> { - StringTokenizer tokenizer = new StringTokenizer(asciiCodes); - - RadixUtils radixUtils = RadixUtils.getInstance(); - try { - while (tokenizer.hasMoreTokens()) { - int ascii = radixUtils.parseRadix(tokenizer.nextToken()); - keyboard.keyPressed(new KeyEvent(this, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, ascii, (char) ascii)); + .readString("Enter ASCII codes separated with spaces:", "Add ASCII codes") + .ifPresent(asciiCodes -> { + StringTokenizer tokenizer = new StringTokenizer(asciiCodes); + + RadixUtils radixUtils = RadixUtils.getInstance(); + try { + while (tokenizer.hasMoreTokens()) { + int ascii = radixUtils.parseRadix(tokenizer.nextToken()); + keyboard.keyPressed(new KeyEvent(this, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, ascii, (char) ascii)); + } + } catch (NumberFormatException ex) { + dialogs.showError("Invalid number format in the input: " + ex.getMessage(), "Add ASCII codes"); } - } catch (NumberFormatException ex) { - dialogs.showError("Invalid number format in the input: " + ex.getMessage(), "Add ASCII codes"); - } - }); + }); }//GEN-LAST:event_btnASCIIActionPerformed - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton btnASCII; - private javax.swing.JLabel lblStatusIcon; - private javax.swing.JScrollPane scrollPane; // End of variables declaration//GEN-END:variables } diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Cursor.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Cursor.java index 25f6204db..6461bfc1e 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Cursor.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Cursor.java @@ -31,16 +31,12 @@ public class Cursor { private final int howOften; private final TimeUnit timeUnit; - + private final AtomicReference cursorPoint = new AtomicReference<>(new Point()); + private final ScheduledExecutorService repaintScheduler = Executors.newSingleThreadScheduledExecutor(); private volatile Display canvas; - private volatile int charWidth; private volatile int charHeight; - private final AtomicReference cursorPoint = new AtomicReference<>(new Point()); - - private final ScheduledExecutorService repaintScheduler = Executors.newSingleThreadScheduledExecutor(); - Cursor(int howOften, TimeUnit timeUnit) { this.howOften = howOften; this.timeUnit = Objects.requireNonNull(timeUnit); diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Display.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Display.java index a9eb7eecd..51e0320e8 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Display.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Display.java @@ -35,12 +35,11 @@ public class Display extends JPanel { private final ConcurrentMap memory = new ConcurrentHashMap<>(); private final net.emustudio.plugins.device.brainduck.terminal.io.Cursor cursor; + private final Font textFont = new Font("Monospaced", Font.PLAIN, 14); private volatile boolean needMeasure; private volatile int charWidth; private volatile int charHeight; - private final Font textFont = new Font("Monospaced", Font.PLAIN, 14); - public Display() { this.cursor = new net.emustudio.plugins.device.brainduck.terminal.io.Cursor(1, TimeUnit.SECONDS); diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/FileIOProvider.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/FileIOProvider.java index 93b624fcd..3b1226633 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/FileIOProvider.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/FileIOProvider.java @@ -24,10 +24,9 @@ import java.io.*; public class FileIOProvider implements InputProvider, OutputProvider { - private static final Logger LOGGER = LoggerFactory.getLogger(FileIOProvider.class); public static final File OUTPUT_FILE_NAME = new File("brainduck-terminal.out"); public static final File INPUT_FILE_NAME = new File("brainduck-terminal.in"); - + private static final Logger LOGGER = LoggerFactory.getLogger(FileIOProvider.class); private final Reader reader; private final FileWriter writer; @@ -58,7 +57,7 @@ public byte read() { if (character == -1) { return EOF; } - return (byte)(character & 0xFF); + return (byte) (character & 0xFF); } catch (IOException e) { LOGGER.error("Could not read from input file: " + INPUT_FILE_NAME, e); return EOF; diff --git a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Keyboard.java b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Keyboard.java index 180e2c1b5..8b4fc051c 100644 --- a/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Keyboard.java +++ b/plugins/device/brainduck-terminal/src/main/java/net/emustudio/plugins/device/brainduck/terminal/io/Keyboard.java @@ -32,13 +32,6 @@ public class Keyboard implements InputProvider, KeyListener { private final BlockingQueue inputBuffer = new LinkedBlockingQueue<>(); private final List listeners = new CopyOnWriteArrayList<>(); - @ThreadSafe - public interface KeyboardListener { - void readStarted(); - - void readEnded(); - } - public void addListener(KeyboardListener listener) { listeners.add(listener); } @@ -83,7 +76,7 @@ public void keyPressed(KeyEvent e) { if (keycode == KeyEvent.VK_ESCAPE) { inputBuffer.add((byte) EOF); } else if (!((keycode == KeyEvent.VK_SHIFT || keycode == KeyEvent.VK_CONTROL || - keycode == KeyEvent.VK_ALT || keycode == KeyEvent.VK_META))) { + keycode == KeyEvent.VK_ALT || keycode == KeyEvent.VK_META))) { inputBuffer.add((byte) (e.getKeyChar() & 0xFF)); } } @@ -92,4 +85,11 @@ public void keyPressed(KeyEvent e) { public void keyReleased(KeyEvent e) { } + + @ThreadSafe + public interface KeyboardListener { + void readStarted(); + + void readEnded(); + } } diff --git a/plugins/device/brainduck-terminal/src/main/resources/net/emustudio/plugins/device/brainduck/terminal/version.properties b/plugins/device/brainduck-terminal/src/main/resources/net/emustudio/plugins/device/brainduck/terminal/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/device/brainduck-terminal/src/main/resources/net/emustudio/plugins/device/brainduck/terminal/version.properties +++ b/plugins/device/brainduck-terminal/src/main/resources/net/emustudio/plugins/device/brainduck/terminal/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/device/simh-pseudo/README.md b/plugins/device/simh-pseudo/README.md index 035a862cd..b56d45f46 100644 --- a/plugins/device/simh-pseudo/README.md +++ b/plugins/device/simh-pseudo/README.md @@ -3,4 +3,5 @@ This project is an emulator of a pseudo-device - "SIMH", used in AltairZ80 simh emulator, specifically in 88-SIO. It is part of [emuStudio](https://www.emustudio.net/). -The official documentation can be found [here](https://www.emustudio.net/docuser/mits_altair_8800/index/#virtual-device-code-simhpseudo-z80-code) +The official documentation can be +found [here](https://www.emustudio.net/docuser/mits_altair_8800/index/#virtual-device-code-simhpseudo-z80-code) diff --git a/plugins/device/simh-pseudo/build.gradle b/plugins/device/simh-pseudo/build.gradle index fec6e3354..c9eac9871 100644 --- a/plugins/device/simh-pseudo/build.gradle +++ b/plugins/device/simh-pseudo/build.gradle @@ -47,8 +47,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java index 21dda314d..d079600e9 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java @@ -20,7 +20,8 @@ import net.emustudio.plugins.device.simh.commands.*; -import java.util.*; +import java.util.HashMap; +import java.util.Map; // do not change order or remove commands, add only at the end public enum Commands { @@ -60,15 +61,6 @@ public enum Commands { genInterruptCmd, // 33 generate interrupt, unknownCmd; - public static Commands fromInt(int number) { - for (Commands c : Commands.values()) { - if (c.ordinal() == number) { - return c; - } - } - throw new IllegalArgumentException("Unknown command"); - } - public final static Map COMMANDS_MAP = new HashMap<>(); static { @@ -107,4 +99,13 @@ public static Commands fromInt(int number) { COMMANDS_MAP.put(setCPUClockFrequency.ordinal(), SetCPUClockFrequency.INS); COMMANDS_MAP.put(genInterruptCmd.ordinal(), GenInterrupt.INS); } + + public static Commands fromInt(int number) { + for (Commands c : Commands.values()) { + if (c.ordinal() == number) { + return c; + } + } + throw new IllegalArgumentException("Unknown command"); + } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java index 717b38fb5..23f3a7a7a 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/DeviceImpl.java @@ -37,8 +37,8 @@ * SIMH emulator's pseudo device. */ @PluginRoot( - type = PLUGIN_TYPE.DEVICE, - title = "SIMH pseudo device" + type = PLUGIN_TYPE.DEVICE, + title = "SIMH pseudo device" ) @SuppressWarnings("unused") public class DeviceImpl extends AbstractDevice { @@ -61,7 +61,7 @@ public void initialize() throws PluginInitializationException { // attach IO port if (!cpu.attachDevice(context, 0xFE)) { throw new PluginInitializationException( - this, "SIMH device cannot be attached to CPU (maybe there is a hardware conflict?)" + this, "SIMH device cannot be attached to CPU (maybe there is a hardware conflict?)" ); } reset(); diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java index bdce0a6ba..9617247c1 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/PseudoContext.java @@ -20,10 +20,11 @@ import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.plugins.cpu.intel8080.api.Context8080; -import net.emustudio.plugins.device.simh.commands.*; +import net.emustudio.plugins.device.simh.commands.Command; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; -import static net.emustudio.plugins.device.simh.Commands.*; +import static net.emustudio.plugins.device.simh.Commands.COMMANDS_MAP; +import static net.emustudio.plugins.device.simh.Commands.unknownCmd; /** * SIMH PseudoContext @@ -88,24 +89,24 @@ public ByteMemoryContext getMemory() { return memory; } + void setMemory(ByteMemoryContext mem) { + this.memory = mem; + } + @Override public Context8080 getCpu() { return cpu; } + void setCpu(Context8080 cpu) { + this.cpu = cpu; + } + @Override public DeviceContext getDevice() { return this; } - void setMemory(ByteMemoryContext mem) { - this.memory = mem; - } - - void setCpu(Context8080 cpu) { - this.cpu = cpu; - } - void reset() { clearCommand(); COMMANDS_MAP.values().forEach(c -> c.reset(this)); diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java index 6fd28bbb6..5d28d932c 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/AttachPTP.java @@ -36,7 +36,7 @@ public byte read(Control control) { @Override public void start(Control control) { - // attachCPM( & ptp_unit); + // attachCPM( & ptp_unit); control.clearWriteCommand(); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java index 32a7cf344..1ef04c62e 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GenInterrupt.java @@ -35,8 +35,8 @@ public void write(byte data, Control control) { genInterruptPos = 0; control.clearCommand(); System.out.printf( - "genInterruptVec=%d vectorInterrupt=%X dataBus=%02X genInterruptPos=%d\n", - genInterruptVec, 1 << genInterruptVec, data, genInterruptPos); + "genInterruptVec=%d vectorInterrupt=%X dataBus=%02X genInterruptPos=%d\n", + genInterruptVec, 1 << genInterruptVec, data, genInterruptPos); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java index becc4ea75..9156d175f 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetBankSelect.java @@ -23,7 +23,7 @@ public class GetBankSelect implements Command { @Override public byte read(Control control) { - byte result = (byte)control.getMemory().getSelectedBank(); + byte result = (byte) control.getMemory().getSelectedBank(); control.clearCommand(); return result; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java index 33f55e8c3..76603d688 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCPUClockFrequency.java @@ -22,9 +22,8 @@ public class GetCPUClockFrequency implements Command { public final static GetCPUClockFrequency INS = new GetCPUClockFrequency(); - - private int getClockFrequencyPos = 0; // determines state for receiving the clock frequency private final AtomicInteger cpuFreq = new AtomicInteger(); + private int getClockFrequencyPos = 0; // determines state for receiving the clock frequency @Override public void reset(Control control) { @@ -36,10 +35,10 @@ public byte read(Control control) { byte result; if (getClockFrequencyPos == 0) { cpuFreq.set(control.getCpu().getCPUFrequency()); - result = (byte)(cpuFreq.get() & 0xff); + result = (byte) (cpuFreq.get() & 0xff); getClockFrequencyPos = 1; } else { - result = (byte)((cpuFreq.get() >> 8) & 0xff); + result = (byte) ((cpuFreq.get() >> 8) & 0xff); getClockFrequencyPos = 0; control.clearCommand(); } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java index ef9779465..a7a65fbac 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockCPM3.java @@ -28,8 +28,8 @@ public class GetClockCPM3 implements Command { public static final GetClockCPM3 INS = new GetClockCPM3(); public final static long CPM3_ORIGIN = LocalDateTime - .of(1977, 12, 31, 0, 0, 0) - .toEpochSecond(ZoneOffset.UTC); + .of(1977, 12, 31, 0, 0, 0) + .toEpochSecond(ZoneOffset.UTC); public final static int SECONDS_PER_MINUTE = 60; public final static int SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE; public final static int SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR; @@ -91,7 +91,7 @@ public void start(Control control) { int delta = SetClockCPM3.INS.ClockCPM3Delta; currentTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(Instant.now().getEpochSecond() + delta), ZoneOffset.UTC); currentTimeValid = true; - daysCPM3SinceOrg = (int)((currentTime.toEpochSecond(ZoneOffset.UTC) - CPM3_ORIGIN) / SECONDS_PER_DAY); + daysCPM3SinceOrg = (int) ((currentTime.toEpochSecond(ZoneOffset.UTC) - CPM3_ORIGIN) / SECONDS_PER_DAY); getClockCPM3Pos = 0; control.clearWriteCommand(); } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java index e72b0f554..b375f704a 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetClockZSDOS.java @@ -31,7 +31,7 @@ public class GetClockZSDOS implements Command { private LocalDateTime currentTime; // ZSDOS clock definitions - // private int ClockZSDOSDelta = 0; // delta between real clock and Altair clock + // private int ClockZSDOSDelta = 0; // delta between real clock and Altair clock private int getClockZSDOSPos = 0; // determines state for sending clock information @Override diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java index 0db983ecc..421f60b2d 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetCommon.java @@ -32,10 +32,10 @@ public void reset(Control control) { public byte read(Control control) { byte result; if (getCommonPos == 0) { - result = (byte)(control.getMemory().getCommonBoundary() & 0xff); + result = (byte) (control.getMemory().getCommonBoundary() & 0xff); getCommonPos = 1; } else { - result = (byte)((control.getMemory().getCommonBoundary() >> 8) & 0xff); + result = (byte) ((control.getMemory().getCommonBoundary() >> 8) & 0xff); getCommonPos = 0; control.clearCommand(); } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java index 80c7ea6e8..794a37726 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/GetHostFilenames.java @@ -21,43 +21,28 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.naming.Name; import java.io.File; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import static net.emustudio.plugins.device.simh.CpmUtils.cpmCommandLine; import static net.emustudio.plugins.device.simh.CpmUtils.readCPMCommandLine; public class GetHostFilenames implements Command { public final static GetHostFilenames INS = new GetHostFilenames(); - - private final static Logger LOGGER = LoggerFactory.getLogger(GetHostFilenames.class); - // support for wild card file expansion public final static char hostPathSeparator = File.separatorChar; public final static String hostPathSeparatorStr = String.valueOf(hostPathSeparator); - + private final static Logger LOGGER = LoggerFactory.getLogger(GetHostFilenames.class); private NameNode nameListHead; private NameNode currentName; private int currentNameIndex = 0; private int lastPathSeparatorIndex = 0; private int firstPathCharacterIndex = 0; - static class NameNode { - char[] name; - NameNode next; - - public NameNode(char[] name, NameNode next) { - this.name = name; - this.next = next; - } - } - @Override public void reset(Control control) { deleteNameList(); @@ -148,4 +133,14 @@ private String cpmCmdLineToString() { } return pb.toString(); } + + static class NameNode { + char[] name; + NameNode next; + + public NameNode(char[] name, NameNode next) { + this.name = name; + this.next = next; + } + } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java index d40a0fe30..86d1ec17b 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/HasBankedMemory.java @@ -23,7 +23,7 @@ public class HasBankedMemory implements Command { @Override public byte read(Control control) { - byte result = (byte)control.getMemory().getBanksCount(); + byte result = (byte) control.getMemory().getBanksCount(); control.clearCommand(); return result; } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java index 84dea967c..25e003daa 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadStopWatch.java @@ -20,11 +20,9 @@ public class ReadStopWatch implements Command { public final static ReadStopWatch INS = new ReadStopWatch(); - + public long stopWatchNow = 0; // stores starting time of stop watch private int getStopWatchDeltaPos = 0; // determines the state for receiving stopWatchDelta private long stopWatchDelta = 0; // stores elapsed time of stop watch - public long stopWatchNow = 0; // stores starting time of stop watch - @Override public void reset(Control control) { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java index 0192803ed..0d338b15d 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/ReadURL.java @@ -47,11 +47,11 @@ public byte read(Control control) { if (resultPointer < resultLength) result = 1; else { - Arrays.fill(urlResult, (char)0); + Arrays.fill(urlResult, (char) 0); control.clearCommand(); } } else if (resultPointer < resultLength) { - result = (byte)urlResult[resultPointer++]; + result = (byte) urlResult[resultPointer++]; } showAvailability = !showAvailability; } else { @@ -88,7 +88,7 @@ public void start(Control control) { private void setURLContent() { String str = "URL is not supported on this platform. START URL \"" + - String.valueOf(urlStore, 0, urlPointer) + "\" URL END."; + String.valueOf(urlStore, 0, urlPointer) + "\" URL END."; resultLength = Math.min(URL_MAX_LENGTH, str.length()); System.arraycopy(str.toCharArray(), 0, urlResult, 0, resultLength); } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java index f9671600a..14b0b35be 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockCPM3.java @@ -65,17 +65,17 @@ public void start(Control control) { 4 BCD byte: SS */ private void setClockCPM3(ByteMemoryContext mem) { long targetSeconds = CPM3_ORIGIN + - (mem.read(setClockCPM3Adr) + mem.read(setClockCPM3Adr + 1) * 256) * SECONDS_PER_DAY + - (long) bcd2bin(mem.read(setClockCPM3Adr + 2)) * SECONDS_PER_HOUR + - (long) bcd2bin(mem.read(setClockCPM3Adr + 3)) * SECONDS_PER_MINUTE + - bcd2bin(mem.read(setClockCPM3Adr + 4)); + (mem.read(setClockCPM3Adr) + mem.read(setClockCPM3Adr + 1) * 256) * SECONDS_PER_DAY + + (long) bcd2bin(mem.read(setClockCPM3Adr + 2)) * SECONDS_PER_HOUR + + (long) bcd2bin(mem.read(setClockCPM3Adr + 3)) * SECONDS_PER_MINUTE + + bcd2bin(mem.read(setClockCPM3Adr + 4)); // compute target year, month and day and replace hour, minute and second fields LocalDateTime targetDate = LocalDateTime - .ofEpochSecond(targetSeconds, 0, ZoneOffset.UTC) - .withHour(bcd2bin(mem.read(setClockCPM3Adr + 2))) - .withMinute(bcd2bin(mem.read(setClockCPM3Adr + 3))) - .withSecond(bcd2bin(mem.read(setClockCPM3Adr + 4))); + .ofEpochSecond(targetSeconds, 0, ZoneOffset.UTC) + .withHour(bcd2bin(mem.read(setClockCPM3Adr + 2))) + .withMinute(bcd2bin(mem.read(setClockCPM3Adr + 3))) + .withSecond(bcd2bin(mem.read(setClockCPM3Adr + 4))); ClockCPM3Delta = (int) (targetDate.toEpochSecond(ZoneOffset.UTC) - LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java index 068d1ec52..4f395a606 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetClockZSDOS.java @@ -27,10 +27,9 @@ public class SetClockZSDOS implements Command { public final static SetClockZSDOS INS = new SetClockZSDOS(); - + public int ClockZSDOSDelta = 0; // delta between real clock and Altair clock private int setClockZSDOSPos = 0; // determines state for receiving address of parameter block private int setClockZSDOSAdr = 0; // address in M of 6 byte parameter block for setting time - public int ClockZSDOSDelta = 0; // delta between real clock and Altair clock @Override public void reset(Control control) { @@ -61,13 +60,13 @@ public void start(Control control) { private void setClockZSDOS(ByteMemoryContext mem) { int year = bcd2bin(mem.read(setClockZSDOSAdr)); int tm_year = (year < 50 ? year + 100 : year) + 1900; - int tm_mon = bcd2bin(mem.read(setClockZSDOSAdr + 1)); + int tm_mon = bcd2bin(mem.read(setClockZSDOSAdr + 1)); int tm_mday = bcd2bin(mem.read(setClockZSDOSAdr + 2)); int tm_hour = bcd2bin(mem.read(setClockZSDOSAdr + 3)); - int tm_min = bcd2bin(mem.read(setClockZSDOSAdr + 4)); - int tm_sec = bcd2bin(mem.read(setClockZSDOSAdr + 5)); + int tm_min = bcd2bin(mem.read(setClockZSDOSAdr + 4)); + int tm_sec = bcd2bin(mem.read(setClockZSDOSAdr + 5)); LocalDateTime newTime = LocalDateTime.of(tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec); - ClockZSDOSDelta = (int)(newTime.toEpochSecond(ZoneOffset.UTC) - LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)); + ClockZSDOSDelta = (int) (newTime.toEpochSecond(ZoneOffset.UTC) - LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)); } } diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java index 8036f4cea..fe64b17ab 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerDelta.java @@ -22,9 +22,8 @@ public class SetTimerDelta implements Command { public final static SetTimerDelta INS = new SetTimerDelta(); private final static int DEFAULT_TIMER_DELTA = 100; // default value for timer delta in ms - - private int setTimerDeltaPos = 0; // determines state for receiving timerDelta public int timerDelta = DEFAULT_TIMER_DELTA; // interrupt every 100 ms + private int setTimerDeltaPos = 0; // determines state for receiving timerDelta @Override public void reset(Control control) { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java index 98de73288..551ec9ddc 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/SetTimerInterruptAdr.java @@ -20,9 +20,8 @@ public class SetTimerInterruptAdr implements Command { public static final SetTimerInterruptAdr INS = new SetTimerInterruptAdr(); - - private int setTimerInterruptAdrPos = 0; // determines state for receiving timerInterruptHandler public int timerInterruptHandler = 0x0fc00; // default address of interrupt handling routine + private int setTimerInterruptAdrPos = 0; // determines state for receiving timerInterruptHandler @Override public void reset(Control control) { diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java index 24ff9c6fc..ceeed2aeb 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/commands/StartTimerInterrupts.java @@ -50,8 +50,8 @@ public void start(Control control) { } private static class TimerInterruptCallback implements Runnable { - private volatile long startTime = System.nanoTime(); private final Context8080 cpu; + private volatile long startTime = System.nanoTime(); private TimerInterruptCallback(Context8080 cpu) { this.cpu = Objects.requireNonNull(cpu); diff --git a/plugins/device/simh-pseudo/src/main/resources/net/emustudio/plugins/device/simh/version.properties b/plugins/device/simh-pseudo/src/main/resources/net/emustudio/plugins/device/simh/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/device/simh-pseudo/src/main/resources/net/emustudio/plugins/device/simh/version.properties +++ b/plugins/device/simh-pseudo/src/main/resources/net/emustudio/plugins/device/simh/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/device/ssem-display/build.gradle b/plugins/device/ssem-display/build.gradle index a899f7091..c48e9b6d2 100644 --- a/plugins/device/ssem-display/build.gradle +++ b/plugins/device/ssem-display/build.gradle @@ -42,8 +42,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java index 9cabdb048..8a6c92b92 100644 --- a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java +++ b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DeviceImpl.java @@ -32,8 +32,8 @@ import java.util.ResourceBundle; @PluginRoot( - type = PLUGIN_TYPE.DEVICE, - title = "SSEM CRT display" + type = PLUGIN_TYPE.DEVICE, + title = "SSEM CRT display" ) @SuppressWarnings("unused") public class DeviceImpl extends AbstractDevice { @@ -53,7 +53,7 @@ public void initialize() throws PluginInitializationException { memory = applicationApi.getContextPool().getMemoryContext(pluginID, MemoryContext.class); if (memory.getDataType() != Byte.class) { throw new PluginInitializationException( - "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() + "Unexpected memory cell type. Expected Byte but was: " + memory.getDataType() ); } } diff --git a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java index cea4fdfd0..034b03506 100644 --- a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java +++ b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayGui.java @@ -27,6 +27,7 @@ class DisplayGui extends JDialog { private final MemoryContext memory; private final DisplayPanel displayPanel; + private final JScrollPane scrollPane = new JScrollPane(); DisplayGui(JFrame parent, MemoryContext memory, DisplayPanel displayPanel) { super(parent); @@ -69,22 +70,20 @@ private void initComponents() { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 432, Short.MAX_VALUE) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 432, Short.MAX_VALUE) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 416, Short.MAX_VALUE) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 416, Short.MAX_VALUE) + .addContainerGap()) ); pack(); } - - private final JScrollPane scrollPane = new JScrollPane(); } diff --git a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java index d1e35a109..d07264d8d 100644 --- a/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java +++ b/plugins/device/ssem-display/src/main/java/net/emustudio/plugins/device/ssem/display/DisplayPanel.java @@ -77,10 +77,10 @@ public void paintComponent(Graphics g) { g.setColor(Color.DARK_GRAY); } g.fillRect( - startX + j * PIXEL_SIZE_WITH_GAP, - startY + i * PIXEL_SIZE_WITH_GAP, - PIXEL_SIZE, - PIXEL_SIZE + startX + j * PIXEL_SIZE_WITH_GAP, + startY + i * PIXEL_SIZE_WITH_GAP, + PIXEL_SIZE, + PIXEL_SIZE ); } } diff --git a/plugins/device/ssem-display/src/main/resources/net/emustudio/plugins/device/ssem/display/version.properties b/plugins/device/ssem-display/src/main/resources/net/emustudio/plugins/device/ssem/display/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/device/ssem-display/src/main/resources/net/emustudio/plugins/device/ssem/display/version.properties +++ b/plugins/device/ssem-display/src/main/resources/net/emustudio/plugins/device/ssem/display/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/device/zxspectrum-display/build.gradle b/plugins/device/zxspectrum-display/build.gradle index c852898f2..9b2dcbeae 100644 --- a/plugins/device/zxspectrum-display/build.gradle +++ b/plugins/device/zxspectrum-display/build.gradle @@ -44,8 +44,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java index 3154624fa..b6124a2e5 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java @@ -49,7 +49,7 @@ public void initialize() throws PluginInitializationException { DeviceContext device = applicationApi.getContextPool().getDeviceContext(pluginID, DeviceContext.class); if (device.getDataType() != Byte.class) { throw new PluginInitializationException( - "Unexpected device data type. Expected Byte but was: " + device.getDataType() + "Unexpected device data type. Expected Byte but was: " + device.getDataType() ); } keyboard.connect(device); diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java index ef885c9b5..e11f6834a 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/ZxSpectrumDisplayGui.java @@ -18,16 +18,24 @@ class ZxSpectrumDisplayGui extends JDialog implements OutputProvider { private final Display canvas; private final Keyboard keyboard; + boolean ignoreNext = false; + int ignoreCount = 0; + boolean sposx = false; + boolean sposy = false; + int posX = 0; + int posY = 0; + private JLabel lblStatusIcon; + private JScrollPane scrollPane; private ZxSpectrumDisplayGui(JFrame parent, Keyboard keyboard, Dialogs dialogs) { super(parent); this.dialogs = Objects.requireNonNull(dialogs); URL blueIconURL = getClass().getResource( - "/net/emustudio/plugins/device/zxspectrum/display/16_circle_blue.png" + "/net/emustudio/plugins/device/zxspectrum/display/16_circle_blue.png" ); URL redIconURL = getClass().getResource( - "/net/emustudio/plugins/device/zxspectrum/display/16_circle_red.png" + "/net/emustudio/plugins/device/zxspectrum/display/16_circle_red.png" ); blueIcon = new ImageIcon(Objects.requireNonNull(blueIconURL)); @@ -44,19 +52,17 @@ private ZxSpectrumDisplayGui(JFrame parent, Keyboard keyboard, Dialogs dialogs) canvas.start(); } + static ZxSpectrumDisplayGui create(JFrame parent, Keyboard keyboard, Dialogs dialogs) { + ZxSpectrumDisplayGui dialog = new ZxSpectrumDisplayGui(parent, keyboard, dialogs); + GUIUtils.addListenerRecursively(dialog, dialog.keyboard); + return dialog; + } + @Override public void reset() { canvas.clearScreen(); } - boolean ignoreNext = false; - int ignoreCount = 0; - - boolean sposx = false; - boolean sposy = false; - int posX = 0; - int posY = 0; - @Override public void write(int character) { if (ignoreNext && (--ignoreCount) > 0) { @@ -76,7 +82,7 @@ public void write(int character) { if (sposx) { posX = character; sposx = false; - // cursor.set(posX, posY); + // cursor.set(posX, posY); return; } @@ -184,13 +190,6 @@ public void close() { dispose(); } - - static ZxSpectrumDisplayGui create(JFrame parent, Keyboard keyboard, Dialogs dialogs) { - ZxSpectrumDisplayGui dialog = new ZxSpectrumDisplayGui(parent, keyboard, dialogs); - GUIUtils.addListenerRecursively(dialog, dialog.keyboard); - return dialog; - } - private void writeStarted() { lblStatusIcon.setIcon(redIcon); lblStatusIcon.repaint(); @@ -223,18 +222,18 @@ private void initComponents() { GroupLayout panelStatusLayout = new GroupLayout(panelStatus); panelStatus.setLayout(panelStatusLayout); panelStatusLayout.setHorizontalGroup( - panelStatusLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(panelStatusLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblStatusIcon, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnASCII) - .addContainerGap(1000, Short.MAX_VALUE)) + panelStatusLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelStatusLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblStatusIcon, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnASCII) + .addContainerGap(1000, Short.MAX_VALUE)) ); panelStatusLayout.setVerticalGroup( - panelStatusLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblStatusIcon, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnASCII, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE) + panelStatusLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblStatusIcon, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnASCII, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE) ); scrollPane.setBackground(new java.awt.Color(255, 255, 255)); @@ -242,16 +241,16 @@ private void initComponents() { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(panelStatus, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(scrollPane) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(panelStatus, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(scrollPane) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(panelStatus, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(panelStatus, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) ); pack(); @@ -259,22 +258,19 @@ private void initComponents() { private void btnASCIIActionPerformed(java.awt.event.ActionEvent evt) { dialogs - .readString("Enter ASCII codes separated with spaces:", "Add ASCII codes") - .ifPresent(asciiCodes -> { - StringTokenizer tokenizer = new StringTokenizer(asciiCodes); - - RadixUtils radixUtils = RadixUtils.getInstance(); - try { - while (tokenizer.hasMoreTokens()) { - int ascii = radixUtils.parseRadix(tokenizer.nextToken()); - keyboard.keyPressed(new KeyEvent(this, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, ascii, (char) ascii)); + .readString("Enter ASCII codes separated with spaces:", "Add ASCII codes") + .ifPresent(asciiCodes -> { + StringTokenizer tokenizer = new StringTokenizer(asciiCodes); + + RadixUtils radixUtils = RadixUtils.getInstance(); + try { + while (tokenizer.hasMoreTokens()) { + int ascii = radixUtils.parseRadix(tokenizer.nextToken()); + keyboard.keyPressed(new KeyEvent(this, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, ascii, (char) ascii)); + } + } catch (NumberFormatException ex) { + dialogs.showError("Invalid number format in the input: " + ex.getMessage(), "Add ASCII codes"); } - } catch (NumberFormatException ex) { - dialogs.showError("Invalid number format in the input: " + ex.getMessage(), "Add ASCII codes"); - } - }); + }); } - - private JLabel lblStatusIcon; - private JScrollPane scrollPane; } diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java index 4e821c01c..ef909ff54 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Display.java @@ -14,19 +14,17 @@ @ThreadSafe public class Display extends JPanel implements LineRoller, ActionListener { - private final static int DEFAULT_COLUMNS = 120; static final Color FOREGROUND = new Color(255, 255, 255); static final Color BACKGROUND = Color.BLACK; + private final static int DEFAULT_COLUMNS = 120; + private static FontRenderContext DEFAULT_FRC; private final Font terminalFont = new Font("Monospaced", Font.PLAIN, 14); - private final char[] videoMemory; private final int columns; private final int rows; - private final Cursor cursor; - private volatile boolean cursorShouldBePainted; private final Timer cursorTimer = new Timer(800, this); - + private volatile boolean cursorShouldBePainted; private volatile Dimension size; public Display() { @@ -44,6 +42,23 @@ public Display() { this.size = new Dimension(displayParameters.maxWidth, displayParameters.maxHeight); } + public static FontRenderContext getDefaultFrc() { + if (DEFAULT_FRC == null) { + AffineTransform tx; + if (GraphicsEnvironment.isHeadless()) { + tx = new AffineTransform(); + } else { + tx = GraphicsEnvironment + .getLocalGraphicsEnvironment() + .getDefaultScreenDevice() + .getDefaultConfiguration() + .getDefaultTransform(); + } + DEFAULT_FRC = new FontRenderContext(tx, false, false); + } + return DEFAULT_FRC; + } + public synchronized void start() { cursorTimer.restart(); } @@ -74,7 +89,6 @@ public Dimension getMinimumSize() { return this.size; } - public final void clearScreen() { fillWithSpaces(); cursor.home(); @@ -170,10 +184,10 @@ private void paintCursor(Graphics graphics) { Rectangle2D fontRectangle = terminalFont.getStringBounds("W", getDefaultFrc()); int lineHeight = graphics.getFontMetrics().getHeight(); - int x = 2 + (int)(paintPoint.x * fontRectangle.getWidth()); + int x = 2 + (int) (paintPoint.x * fontRectangle.getWidth()); int y = 3 + (paintPoint.y * lineHeight); - graphics.fillRect(x, y, (int)fontRectangle.getWidth(), (int)fontRectangle.getHeight()); + graphics.fillRect(x, y, (int) fontRectangle.getWidth(), (int) fontRectangle.getHeight()); graphics.setPaintMode(); cursorShouldBePainted = true; @@ -195,23 +209,4 @@ private DisplayParameters measure() { return new DisplayParameters(maxWidth, maxHeight, charWidth); } - - private static FontRenderContext DEFAULT_FRC; - - public static FontRenderContext getDefaultFrc() { - if (DEFAULT_FRC == null) { - AffineTransform tx; - if (GraphicsEnvironment.isHeadless()) { - tx = new AffineTransform(); - } else { - tx = GraphicsEnvironment - .getLocalGraphicsEnvironment() - .getDefaultScreenDevice() - .getDefaultConfiguration() - .getDefaultTransform(); - } - DEFAULT_FRC = new FontRenderContext(tx, false, false); - } - return DEFAULT_FRC; - } } diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java index cfa5d89e8..7d8422a18 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/io/Keyboard.java @@ -24,7 +24,7 @@ public void keyTyped(KeyEvent e) { public void keyPressed(KeyEvent e) { int keycode = e.getKeyCode(); if (!((keycode == KeyEvent.VK_SHIFT || keycode == KeyEvent.VK_CONTROL || - keycode == KeyEvent.VK_ALT || keycode == KeyEvent.VK_META))) { + keycode == KeyEvent.VK_ALT || keycode == KeyEvent.VK_META))) { keycode = (e.getKeyChar() & 0xFF); } inputReceived((byte) keycode); diff --git a/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/version.properties b/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/version.properties +++ b/plugins/device/zxspectrum-display/src/main/resources/net/emustudio/plugins/device/zxspectrum/display/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/memory/byte-mem/README.md b/plugins/memory/byte-mem/README.md index 029f7a4de..0a02eeaf5 100644 --- a/plugins/memory/byte-mem/README.md +++ b/plugins/memory/byte-mem/README.md @@ -1,5 +1,7 @@ # byte-mem -This project is emulator of "byte" operating memory for various machines (memory operating on byte cells). It is part of [emuStudio](https://www.emustudio.net/). +This project is emulator of "byte" operating memory for various machines (memory operating on byte cells). It is part +of [emuStudio](https://www.emustudio.net/). -The official documentation can be found [here](https://www.emustudio.net/docuser/mits_altair_8800/index/#operating-memory-code-standard-mem-code) +The official documentation can be +found [here](https://www.emustudio.net/docuser/mits_altair_8800/index/#operating-memory-code-standard-mem-code) diff --git a/plugins/memory/byte-mem/build.gradle b/plugins/memory/byte-mem/build.gradle index dce1ecd04..505dcbcbd 100644 --- a/plugins/memory/byte-mem/build.gradle +++ b/plugins/memory/byte-mem/build.gradle @@ -43,8 +43,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java index 98502150a..8f8a41610 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java @@ -38,16 +38,14 @@ public class MemoryContextImpl extends AbstractMemoryContext implements By private final RangeTree romRanges = new RangeTree(); private final Dialogs dialogs; - - public MemoryContextImpl(Dialogs dialogs) { - this.dialogs = Objects.requireNonNull(dialogs); - } - int lastImageStart = 0; private Byte[][] mem = new Byte[1][0]; private int banksCount; private int bankSelect = 0; private int bankCommon = 0; + public MemoryContextImpl(Dialogs dialogs) { + this.dialogs = Objects.requireNonNull(dialogs); + } void init(int size, int banks, int bankCommon) { if (banks <= 0) { @@ -195,14 +193,6 @@ public void setReadWrite(AddressRange range) { removeROMRange(range); } - @Override - public void setReadOnly(AddressRange range) { - if (range.getStartAddress() > range.getStopAddress()) { - throw new IllegalArgumentException("Range stop address must be > than start address!"); - } - addRomRange(range); - } - @Override public boolean isReadOnly(int address) { return romRanges.isIn(address); @@ -213,6 +203,14 @@ public List getReadOnly() { return romRanges.getRanges(); } + @Override + public void setReadOnly(AddressRange range) { + if (range.getStartAddress() > range.getStopAddress()) { + throw new IllegalArgumentException("Range stop address must be > than start address!"); + } + addRomRange(range); + } + @Override public Byte[][] getRawMemory() { return mem; diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java index 8bacb83bc..2bff33d3c 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java @@ -23,7 +23,10 @@ import net.emustudio.emulib.plugins.annotations.PluginRoot; import net.emustudio.emulib.plugins.memory.AbstractMemory; import net.emustudio.emulib.plugins.memory.MemoryContext; -import net.emustudio.emulib.runtime.*; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; +import net.emustudio.emulib.runtime.ContextPool; +import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import net.emustudio.plugins.memory.bytemem.gui.MemoryGui; @@ -38,16 +41,16 @@ import java.util.ResourceBundle; @PluginRoot( - type = PLUGIN_TYPE.MEMORY, - title = "Byte-cell based operating memory" + type = PLUGIN_TYPE.MEMORY, + title = "Byte-cell based operating memory" ) @SuppressWarnings("unused") public class MemoryImpl extends AbstractMemory { private final static Logger LOGGER = LoggerFactory.getLogger(MemoryImpl.class); private final MemoryContextImpl context; - private MemoryGui gui; private final boolean guiNotSupported; + private MemoryGui gui; public MemoryImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); @@ -61,7 +64,7 @@ public MemoryImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register memory context", e); applicationApi.getDialogs().showError( - "Could not register memory. Please see log file for more details", getTitle() + "Could not register memory. Please see log file for more details", getTitle() ); } } @@ -177,7 +180,7 @@ public void saveCoreSettings(int banksCount, int commonBoundary, List im settings.setInt("banksCount", banksCount); settings.setInt("commonBoundary", commonBoundary); - for (int i = 0; settings.contains( "imageName" + i); i++) { + for (int i = 0; settings.contains("imageName" + i); i++) { settings.remove("imageName" + i); settings.remove("imageAddress" + i); } @@ -194,7 +197,7 @@ public void saveCoreSettings(int banksCount, int commonBoundary, List im * directly from memory context. */ public void saveROMRanges() { - for (int i = 0; settings.contains("ROMfrom" + i) ; i++) { + for (int i = 0; settings.contains("ROMfrom" + i); i++) { settings.remove("ROMfrom" + i); settings.remove("ROMto" + i); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java index 35c6d19a0..d9e141894 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/api/ByteMemoryContext.java @@ -32,15 +32,6 @@ @PluginContext(id = "Byte memory") public interface ByteMemoryContext extends MemoryContext { - /** - * This interface represents a range of addresses in the memory. - */ - interface AddressRange { - int getStartAddress(); - - int getStopAddress(); - } - /** * Determine whether specified memory position is read-only. * @@ -57,18 +48,18 @@ interface AddressRange { List getReadOnly(); /** - * Set specified memory range as RAM (Random Access Memory). + * Set specified memory range as ROM (Read Only Memory). * * @param range address range */ - void setReadWrite(AddressRange range); + void setReadOnly(AddressRange range); /** - * Set specified memory range as ROM (Read Only Memory). + * Set specified memory range as RAM (Random Access Memory). * * @param range address range */ - void setReadOnly(AddressRange range); + void setReadWrite(AddressRange range); /** * Get number of available memory banks. @@ -108,4 +99,13 @@ interface AddressRange { * @return raw memory */ Byte[][] getRawMemory(); + + /** + * This interface represents a range of addresses in the memory. + */ + interface AddressRange { + int getStartAddress(); + + int getStopAddress(); + } } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java index 8486f39ff..149efd5f7 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java @@ -27,6 +27,6 @@ public class Constants { public final static Font MEMORY_CELLS_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 12); public final static FileExtensionsFilter IMAGE_EXTENSION_FILTER = new FileExtensionsFilter( - "Memory image", "hex", "bin", "com", "out" + "Memory image", "hex", "bin", "com", "out" ); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java index a29567510..7102b514d 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java @@ -28,15 +28,18 @@ public class FindSequenceDialog extends JDialog { private final FindSequenceAction findSequenceAction; - + private final JRadioButton radioCurrentPage = new JRadioButton(); + private final JRadioButton radioPlainText = new JRadioButton(); + private final JTextField txtPosition = new JTextField(); + private final JTextField txtSequence = new JTextField(); public FindSequenceDialog(Dialogs dialogs, JDialog parent, MemoryTableModel tableModel, int currentAddress, Consumer setFoundAddress) { super(parent, true); setLocationRelativeTo(parent); this.findSequenceAction = new FindSequenceAction( - dialogs, this::dispose, tableModel, setFoundAddress, radioCurrentPage::isSelected, - radioPlainText::isSelected, currentAddress, txtPosition, txtSequence + dialogs, this::dispose, tableModel, setFoundAddress, radioCurrentPage::isSelected, + radioPlainText::isSelected, currentAddress, txtPosition, txtSequence ); initComponents(); } @@ -70,25 +73,25 @@ private void initComponents() { GroupLayout jPanel1Layout = new GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(radioBytes, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(radioPlainText) - .addComponent(txtSequence)) - .addContainerGap(42, Short.MAX_VALUE)) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(radioBytes, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(radioPlainText) + .addComponent(txtSequence)) + .addContainerGap(42, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(txtSequence, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(radioPlainText) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(radioBytes) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(txtSequence, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(radioPlainText) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(radioBytes) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel2.setBorder(BorderFactory.createTitledBorder("Start position")); @@ -103,63 +106,57 @@ private void initComponents() { GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addGap(21, 21, 21) - .addComponent(txtPosition)) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(radioCurrentPage) - .addComponent(radioSpecificPosition)) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addGap(21, 21, 21) + .addComponent(txtPosition)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(radioCurrentPage) + .addComponent(radioSpecificPosition)) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap()) ); jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(radioCurrentPage) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(radioSpecificPosition) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(txtPosition, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE) - .addContainerGap(24, Short.MAX_VALUE)) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(radioCurrentPage) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(radioSpecificPosition) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(txtPosition, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE) + .addContainerGap(24, Short.MAX_VALUE)) ); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(btnFind, GroupLayout.PREFERRED_SIZE, 92, GroupLayout.PREFERRED_SIZE)) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap())); + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(btnFind, GroupLayout.PREFERRED_SIZE, 92, GroupLayout.PREFERRED_SIZE)) + .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap())); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(btnFind) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(btnFind) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); } - - - private final JRadioButton radioCurrentPage = new JRadioButton(); - private final JRadioButton radioPlainText = new JRadioButton(); - private final JTextField txtPosition = new JTextField(); - private final JTextField txtSequence = new JTextField(); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java index 1da30e531..3f601e593 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java @@ -18,19 +18,22 @@ */ package net.emustudio.plugins.memory.bytemem.gui; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; -import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; -import net.emustudio.plugins.memory.bytemem.gui.model.TableMemory; +import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; import net.emustudio.plugins.memory.bytemem.MemoryImpl; +import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; +import net.emustudio.plugins.memory.bytemem.gui.model.TableMemory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import java.awt.*; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.io.*; import java.nio.file.Path; import java.util.Objects; @@ -49,6 +52,19 @@ public class MemoryGui extends JDialog { private final TableMemory table; private final MemoryTableModel tableModel; + private final JLabel lblBanksCount = new JLabel(); + private final JLabel lblPageCount = new JLabel(); + private final JScrollPane paneMemory = new JScrollPane(); + private final JSpinner spnBank = new JSpinner(); + private final JSpinner spnPage = new JSpinner(); + private final JTextField txtAddress = new JTextField(); + private final JTextField txtChar = new JTextField(); + private final JTextField txtValueBin = new JTextField(); + private final JTextField txtValueDec = new JTextField(); + private final JTextField txtValueHex = new JTextField(); + private final JTextField txtValueOct = new JTextField(); + private final JToggleButton btnAsciiMode = new JToggleButton(); + public MemoryGui(JFrame parent, MemoryImpl memory, MemoryContextImpl context, PluginSettings settings, Dialogs dialogs) { super(parent); @@ -100,7 +116,7 @@ public void windowClosing(WindowEvent e) { updateMemVal(row, column); }); MouseHandler mouseHandler = new MouseHandler( - tableModel, () -> updateMemVal(table.getSelectedRow(), table.getSelectedColumn())); + tableModel, () -> updateMemVal(table.getSelectedRow(), table.getSelectedColumn())); table.addMouseListener(mouseHandler); table.addMouseWheelListener(mouseHandler); table.addKeyListener(new KeyboardHandler(table, spnPage.getModel(), this)); @@ -111,7 +127,7 @@ public void updateMemVal(int row, int column) { return; } int address = tableModel.getRowCount() * tableModel.getColumnCount() - * tableModel.getPage() + row * tableModel.getColumnCount() + column; + * tableModel.getPage() + row * tableModel.getColumnCount() + column; int data = tableModel.getRawValueAt(row, column); txtAddress.setText(String.format("%04X", address)); @@ -122,7 +138,6 @@ public void updateMemVal(int row, int column) { txtValueBin.setText(formatBinaryString(data, 8)); } - private void initComponents() { JToolBar toolBar = new JToolBar(); JButton btnLoadImage = new JButton(); @@ -245,40 +260,40 @@ private void initComponents() { GroupLayout jPanel3Layout = new GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnPage, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel2) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblPageCount) - .addGap(54, 54, 54) - .addComponent(jLabel3) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(spnBank, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel4) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lblBanksCount) - .addContainerGap(283, Short.MAX_VALUE)) + jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnPage, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblPageCount) + .addGap(54, 54, 54) + .addComponent(jLabel3) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spnBank, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel4) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblBanksCount) + .addContainerGap(283, Short.MAX_VALUE)) ); jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) - .addComponent(spnPage, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel2) - .addComponent(lblPageCount) - .addComponent(jLabel3) - .addComponent(spnBank, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel4) - .addComponent(lblBanksCount)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(spnPage, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel2) + .addComponent(lblPageCount) + .addComponent(jLabel3) + .addComponent(spnBank, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4) + .addComponent(lblBanksCount)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel4.setBorder(BorderFactory.createTitledBorder("Selected value")); @@ -327,91 +342,91 @@ private void initComponents() { GroupLayout jPanel4Layout = new GroupLayout(jPanel4); jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( - jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel4Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel5) - .addComponent(jLabel6)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(txtChar, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE) - .addComponent(txtAddress, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSeparator4, GroupLayout.PREFERRED_SIZE, 13, GroupLayout.PREFERRED_SIZE) - .addGap(2, 2, 2) - .addComponent(jLabel7) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(txtValueHex) - .addComponent(txtValueDec, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel8) - .addComponent(jLabel9)) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(txtValueBin) - .addComponent(txtValueOct, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE)) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel10)) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup() - .addGap(7, 7, 7) - .addComponent(jLabel11))) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jLabel5) + .addComponent(jLabel6)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(txtChar, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE) + .addComponent(txtAddress, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSeparator4, GroupLayout.PREFERRED_SIZE, 13, GroupLayout.PREFERRED_SIZE) + .addGap(2, 2, 2) + .addComponent(jLabel7) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(txtValueHex) + .addComponent(txtValueDec, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jLabel8) + .addComponent(jLabel9)) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(txtValueBin) + .addComponent(txtValueOct, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE)) + .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel10)) + .addGroup(GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup() + .addGap(7, 7, 7) + .addComponent(jLabel11))) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel4Layout.setVerticalGroup( - jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel4Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel7) - .addComponent(txtValueDec, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel8) - .addComponent(txtValueOct, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel10)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(txtValueHex, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel9) - .addComponent(txtValueBin, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel11))) - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addGroup(jPanel4Layout.createSequentialGroup() - .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5) - .addComponent(txtAddress, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addContainerGap() .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel6) - .addComponent(txtChar, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) - .addComponent(jSeparator4))) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel7) + .addComponent(txtValueDec, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel8) + .addComponent(txtValueOct, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel10)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(txtValueHex, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel9) + .addComponent(txtValueBin, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel11))) + .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5) + .addComponent(txtAddress, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jLabel6) + .addComponent(txtChar, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) + .addComponent(jSeparator4))) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jPanel4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap()) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jPanel4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) ); jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); splitPane.setBottomComponent(jPanel2); @@ -422,16 +437,16 @@ private void initComponents() { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(toolBar, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(splitPane) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(toolBar, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(splitPane) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(toolBar, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(splitPane, GroupLayout.DEFAULT_SIZE, 598, Short.MAX_VALUE)) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(toolBar, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(splitPane, GroupLayout.DEFAULT_SIZE, 598, Short.MAX_VALUE)) ); pack(); @@ -439,7 +454,7 @@ private void initComponents() { private void btnLoadImageActionPerformed(ActionEvent evt) { dialogs.chooseFile( - "Load memory image", "Load", Path.of(System.getProperty("user.dir")), false, IMAGE_EXTENSION_FILTER + "Load memory image", "Load", Path.of(System.getProperty("user.dir")), false, IMAGE_EXTENSION_FILTER ).ifPresent(path -> { boolean isHex = path.toString().toLowerCase().endsWith(".hex"); boolean hasBanks = context.getBanksCount() > 1; @@ -450,7 +465,7 @@ private void btnLoadImageActionPerformed(ActionEvent evt) { if (!isHex || hasBanks) { SelectBankAddressDialog dialog = new SelectBankAddressDialog( - this, hasBanks, !isHex, dialogs + this, hasBanks, !isHex, dialogs ); dialog.setVisible(true); ok = dialog.isOk(); @@ -478,16 +493,16 @@ private void btnCleanActionPerformed(ActionEvent evt) { private void btnGotoAddressActionPerformed(ActionEvent evt) { try { dialogs - .readInteger("Enter memory address:", "Go to address") - .ifPresent(address -> { - if (address < 0 || address >= context.getSize()) { - dialogs.showError( - "Address out of bounds (min=0, max=" + (context.getSize() - 1) + ")", "Go to address" - ); - } else { - setPageFromAddress(address); - } - }); + .readInteger("Enter memory address:", "Go to address") + .ifPresent(address -> { + if (address < 0 || address >= context.getSize()) { + dialogs.showError( + "Address out of bounds (min=0, max=" + (context.getSize() - 1) + ")", "Go to address" + ); + } else { + setPageFromAddress(address); + } + }); } catch (NumberFormatException e) { dialogs.showError("Invalid number format", "Go to address"); } @@ -496,7 +511,7 @@ private void btnGotoAddressActionPerformed(ActionEvent evt) { private void btnFindActionPerformed(ActionEvent evt) { AtomicInteger foundAddress = new AtomicInteger(-1); FindSequenceDialog dialog = new FindSequenceDialog( - dialogs, this, tableModel, getCurrentAddress(), foundAddress::set + dialogs, this, tableModel, getCurrentAddress(), foundAddress::set ); dialog.setVisible(true); @@ -518,9 +533,9 @@ private void btnSettingsActionPerformed(ActionEvent evt) { private void btnDumpActionPerformed(ActionEvent evt) { Path currentDirectory = Path.of(System.getProperty("user.dir")); dialogs.chooseFile( - "Dump memory content into a file", "Save", currentDirectory, true, - new FileExtensionsFilter("Human-readable dump", "txt"), - new FileExtensionsFilter("Binary dump", "bin") + "Dump memory content into a file", "Save", currentDirectory, true, + new FileExtensionsFilter("Human-readable dump", "txt"), + new FileExtensionsFilter("Binary dump", "bin") ).ifPresent(path -> { try { if (path.toString().toLowerCase().endsWith(".txt")) { @@ -559,18 +574,4 @@ private void setPageFromAddress(int address) { } catch (RuntimeException ignored) { } } - - - private final JLabel lblBanksCount = new JLabel(); - private final JLabel lblPageCount = new JLabel(); - private final JScrollPane paneMemory = new JScrollPane(); - private final JSpinner spnBank = new JSpinner(); - private final JSpinner spnPage = new JSpinner(); - private final JTextField txtAddress = new JTextField(); - private final JTextField txtChar = new JTextField(); - private final JTextField txtValueBin = new JTextField(); - private final JTextField txtValueDec = new JTextField(); - private final JTextField txtValueHex = new JTextField(); - private final JTextField txtValueOct = new JTextField(); - private final JToggleButton btnAsciiMode = new JToggleButton(); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java index 3dc6185bd..c016f6df7 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java @@ -70,36 +70,36 @@ private void initComponents() { getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(lblBank) - .addComponent(lblAddress)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(txtAddress, 64, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtBank, 64, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnOK) - .addContainerGap())); + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(lblBank) + .addComponent(lblAddress)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(txtAddress, 64, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtBank, 64, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnOK) + .addContainerGap())); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblBank) - .addComponent(txtBank, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(lblAddress) - .addComponent(txtAddress, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addGap(18, 18, 18) - .addComponent(btnOK) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))); + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblBank) + .addComponent(txtBank, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblAddress) + .addComponent(txtAddress, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addGap(18, 18, 18) + .addComponent(btnOK) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))); pack(); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java index 69e466d47..4b0a73c69 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java @@ -48,6 +48,11 @@ public class SettingsDialog extends JDialog { private final FileImagesModel imagesModel; private final ROMmodel romModel; private final Dialogs dialogs; + private JCheckBox chkApplyROMatStartup; + private JTable tblImages; + private JTable tblROM; + private JTextField txtBanksCount; + private JTextField txtCommonBoundary; public SettingsDialog(JDialog parent, MemoryImpl memory, MemoryContextImpl context, TableMemory tblMem, PluginSettings settings, Dialogs dialogs) { @@ -125,33 +130,33 @@ private void initComponents() { GroupLayout jPanel1Layout = new GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(chkApplyROMatStartup) - .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(btnRemoveRange) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnAddRange)) - .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) - .addContainerGap()) + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(chkApplyROMatStartup) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(btnRemoveRange) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnAddRange)) + .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addContainerGap()) ); jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 116, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(btnAddRange) - .addComponent(btnRemoveRange)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(chkApplyROMatStartup) - .addContainerGap()) + jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 116, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(btnAddRange) + .addComponent(btnRemoveRange)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(chkApplyROMatStartup) + .addContainerGap()) ); jPanel3.setBorder(BorderFactory.createTitledBorder("Bank-switching")); @@ -173,52 +178,52 @@ private void initComponents() { GroupLayout jPanel3Layout = new GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addComponent(jLabel8, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addComponent(jSeparator2, GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.LEADING, jPanel3Layout.createSequentialGroup() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel6) - .addComponent(jLabel7)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(txtBanksCount) - .addComponent(txtCommonBoundary)))) - .addContainerGap()) + jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel10, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, Short.MAX_VALUE)))) + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addComponent(jLabel8, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addComponent(jSeparator2, GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.LEADING, jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jLabel6) + .addComponent(jLabel7)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(txtBanksCount) + .addComponent(txtCommonBoundary)))) + .addContainerGap()) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jLabel9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel10, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, Short.MAX_VALUE)))) ); jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel6) - .addComponent(txtBanksCount, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel7) - .addComponent(txtCommonBoundary, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSeparator2, GroupLayout.PREFERRED_SIZE, 2, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel8, GroupLayout.PREFERRED_SIZE, 64, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel10, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6) + .addComponent(txtBanksCount, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(jLabel7) + .addComponent(txtCommonBoundary, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSeparator2, GroupLayout.PREFERRED_SIZE, 2, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel8, GroupLayout.PREFERRED_SIZE, 64, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel10, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(jLabel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel2.setBorder(BorderFactory.createTitledBorder("Files to load at startup")); @@ -238,30 +243,30 @@ private void initComponents() { GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 498, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(btnLoadNow, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnRemoveImage, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnAddImage, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 498, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(btnLoadNow, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnRemoveImage, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnAddImage, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(btnAddImage) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(btnRemoveImage) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(btnLoadNow)) - .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 117, GroupLayout.PREFERRED_SIZE)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(btnAddImage) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnRemoveImage) + .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(btnLoadNow)) + .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 117, GroupLayout.PREFERRED_SIZE)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); btnOK.setText("OK"); @@ -270,32 +275,32 @@ private void initComponents() { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(btnOK, GroupLayout.PREFERRED_SIZE, 99, GroupLayout.PREFERRED_SIZE))) - .addContainerGap()) + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(btnOK, GroupLayout.PREFERRED_SIZE, 99, GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnOK) - .addContainerGap()) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnOK) + .addContainerGap()) ); pack(); @@ -371,8 +376,8 @@ private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { int bCount = getPositiveIntegerOrThrow("Banks count", txtBanksCount); int bCommon = getPositiveIntegerOrThrow("Common boundary", txtCommonBoundary); memory.saveCoreSettings( - bCount, bCommon, imagesModel.getImageFullNames(), imagesModel.getImageAddresses(), - imagesModel.getImageBanks() + bCount, bCommon, imagesModel.getImageFullNames(), imagesModel.getImageAddresses(), + imagesModel.getImageBanks() ); if (chkApplyROMatStartup.isSelected()) { memory.saveROMRanges(); @@ -388,7 +393,7 @@ private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { private void btnAddImageActionPerformed(java.awt.event.ActionEvent evt) { dialogs.chooseFile( - "Add memory image", "Add", Path.of(System.getProperty("user.dir")), false, IMAGE_EXTENSION_FILTER + "Add memory image", "Add", Path.of(System.getProperty("user.dir")), false, IMAGE_EXTENSION_FILTER ).ifPresent(path -> { boolean isHex = path.toString().toLowerCase().endsWith(".hex"); boolean hasBanks = context.getBanksCount() > 1; @@ -399,7 +404,7 @@ private void btnAddImageActionPerformed(java.awt.event.ActionEvent evt) { if (!isHex || hasBanks) { SelectBankAddressDialog dialog = new SelectBankAddressDialog( - this, hasBanks, !isHex, dialogs + this, hasBanks, !isHex, dialogs ); dialog.setVisible(true); ok = dialog.isOk(); @@ -419,7 +424,7 @@ private void btnRemoveImageActionPerformed(java.awt.event.ActionEvent evt) { dialogs.showError("Image has to be selected", "Remove image"); } else { Dialogs.DialogAnswer answer = dialogs.ask( - "Are you sure to remove selected image from the list?", "Remove image" + "Are you sure to remove selected image from the list?", "Remove image" ); if (answer == Dialogs.DialogAnswer.ANSWER_YES) { imagesModel.removeImageAt(index); @@ -433,16 +438,10 @@ private void btnLoadNowActionPerformed(java.awt.event.ActionEvent evt) { dialogs.showError("Image has to be selected", "Load image now"); } else { memory.loadImage( - Path.of(imagesModel.getFileNameAtRow(index)), imagesModel.getImageAddressAtRow(index), - imagesModel.getImageBankAtRow(index) + Path.of(imagesModel.getFileNameAtRow(index)), imagesModel.getImageAddressAtRow(index), + imagesModel.getImageBankAtRow(index) ); tblMem.getTableModel().fireTableDataChanged(); } } - - private JCheckBox chkApplyROMatStartup; - private JTable tblImages; - private JTable tblROM; - private JTextField txtBanksCount; - private JTextField txtCommonBoundary; } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/FindSequenceAction.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/FindSequenceAction.java index eb639caea..43fce307a 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/FindSequenceAction.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/FindSequenceAction.java @@ -35,9 +35,8 @@ import java.util.stream.Stream; public class FindSequenceAction extends AbstractAction { - private final static Logger LOGGER = LoggerFactory.getLogger(FindSequenceAction.class); public final static String ERROR_NUMBER_FORMAT = "Cannot parse sequence of bytes. Bytes (in correct radix format) must be separated with spaces."; - + private final static Logger LOGGER = LoggerFactory.getLogger(FindSequenceAction.class); private final Dialogs dialogs; private final Runnable dispose; private final MemoryTableModel tableModel; diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/FileImagesModel.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/FileImagesModel.java index 662bb993d..716271cbe 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/FileImagesModel.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/FileImagesModel.java @@ -18,8 +18,8 @@ */ package net.emustudio.plugins.memory.bytemem.gui.model; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,7 +60,7 @@ public FileImagesModel(PluginSettings settings, Dialogs dialogs) { } catch (NumberFormatException e) { LOGGER.error("Invalid number format of setting 'imageAddress" + i + "'", e); dialogs.showError( - "Invalid number format of setting 'imageAddress" + i + "'. Please see log file for more details" + "Invalid number format of setting 'imageAddress" + i + "'. Please see log file for more details" ); } } @@ -79,10 +79,14 @@ public int getColumnCount() { @Override public String getColumnName(int columnIndex) { switch (columnIndex) { - case 0: return "File name"; - case 1: return "Address"; - case 2: return "Bank"; - default: return ""; + case 0: + return "File name"; + case 1: + return "Address"; + case 2: + return "Bank"; + default: + return ""; } } @@ -103,9 +107,12 @@ public boolean isCellEditable(int row, int col) { @Override public Object getValueAt(int rowIndex, int columnIndex) { switch (columnIndex) { - case 0: return imageShortFileNames.get(rowIndex); - case 1: return String.format("0x%04X", imageAddresses.get(rowIndex)); - case 2: return imageBanks.get(rowIndex); + case 0: + return imageShortFileNames.get(rowIndex); + case 1: + return String.format("0x%04X", imageAddresses.get(rowIndex)); + case 2: + return imageBanks.get(rowIndex); } return null; } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java index 6eca9f5e6..a210b148c 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/MemoryTableModel.java @@ -92,7 +92,7 @@ public void setValueAt(Object value, int rowIndex, int columnIndex) { fireTableCellUpdated(rowIndex, columnIndex); } catch (NumberFormatException e) { LOGGER.error( - "Could not set memory cell at address 0x" + Integer.toHexString(address) + " to value " + value, e + "Could not set memory cell at address 0x" + Integer.toHexString(address) + " to value " + value, e ); } } @@ -102,14 +102,6 @@ public boolean isCellEditable(int rowIndex, int columnIndex) { return true; } - public void setPage(int page) throws IndexOutOfBoundsException { - if (page >= getPageCount() || page < 0) { - throw new IndexOutOfBoundsException(); - } - currentPage = page; - fireTableDataChanged(); - } - public Optional findSequence(byte[] sequence, int from) { final int size = memory.getSize(); int offset = 0; @@ -137,10 +129,22 @@ public int getPage() { return currentPage; } + public void setPage(int page) throws IndexOutOfBoundsException { + if (page >= getPageCount() || page < 0) { + throw new IndexOutOfBoundsException(); + } + currentPage = page; + fireTableDataChanged(); + } + public int getPageCount() { return memory.getSize() / (ROW_COUNT * COLUMN_COUNT); } + public int getCurrentBank() { + return currentBank; + } + public void setCurrentBank(int bank) { if (bank >= memory.getBanksCount() || bank < 0) { throw new IndexOutOfBoundsException(); @@ -149,10 +153,6 @@ public void setCurrentBank(int bank) { fireTableDataChanged(); } - public int getCurrentBank() { - return currentBank; - } - public int toAddress(int row, int column) { return ROW_COUNT * COLUMN_COUNT * currentPage + row * COLUMN_COUNT + column; } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/ROMmodel.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/ROMmodel.java index 97cac0970..4a63b306f 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/ROMmodel.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/ROMmodel.java @@ -18,8 +18,8 @@ */ package net.emustudio.plugins.memory.bytemem.gui.model; -import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext.AddressRange; import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext.AddressRange; import javax.swing.table.AbstractTableModel; import java.util.Objects; diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/TableMemory.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/TableMemory.java index 2e0456a2d..9c857d6d9 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/TableMemory.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/model/TableMemory.java @@ -84,8 +84,8 @@ public Component getListCellRendererComponent(JList list, String value, private class MemCellRenderer extends JLabel implements TableCellRenderer { private final JList rowHeader; private final String[] addresses; - private int currentPage; private final Color romColor = new Color(0xE8, 0x68, 0x50); + private int currentPage; MemCellRenderer() { setOpaque(true); @@ -96,7 +96,7 @@ private class MemCellRenderer extends JLabel implements TableCellRenderer { addresses = new String[tableModel.getRowCount()]; for (int i = 0; i < addresses.length; i++) { addresses[i] = RadixUtils.formatWordHexString(tableModel.getColumnCount() * i - + tableModel.getColumnCount() * tableModel.getRowCount() * currentPage) + "h"; + + tableModel.getColumnCount() * tableModel.getRowCount() * currentPage) + "h"; } rowHeader = new JList<>(addresses); this.setFont(MEMORY_CELLS_FONT); @@ -121,8 +121,8 @@ private void remakeAddresses() { currentPage = tableModel.getPage(); for (int i = 0; i < addresses.length; i++) { addresses[i] = String.format("%1$04Xh", - tableModel.getColumnCount() * i + tableModel.getColumnCount() - * tableModel.getRowCount() * currentPage); + tableModel.getColumnCount() * i + tableModel.getColumnCount() + * tableModel.getRowCount() * currentPage); } rowHeader.setListData(addresses); } diff --git a/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/version.properties b/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/version.properties +++ b/plugins/memory/byte-mem/src/main/resources/net/emustudio/plugins/memory/bytemem/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/MemoryImplTest.java b/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/MemoryImplTest.java index 4af757d63..dd93dcd2d 100644 --- a/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/MemoryImplTest.java +++ b/plugins/memory/byte-mem/src/test/java/net/emustudio/plugins/memory/bytemem/MemoryImplTest.java @@ -20,14 +20,13 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; -import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.emulib.runtime.settings.PluginSettings; import org.junit.After; import org.junit.Before; import org.junit.Test; import static org.easymock.EasyMock.*; -import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertNotEquals; public class MemoryImplTest { diff --git a/plugins/memory/ram-mem/build.gradle b/plugins/memory/ram-mem/build.gradle index dce1ecd04..505dcbcbd 100644 --- a/plugins/memory/ram-mem/build.gradle +++ b/plugins/memory/ram-mem/build.gradle @@ -43,8 +43,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java index 632b9500f..2344ddeb8 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryContextImpl.java @@ -94,7 +94,7 @@ public Class getDataType() { @Override public synchronized void setLabels(List labels) { this.labels.clear(); - for (RAMLabel label: labels) { + for (RAMLabel label : labels) { this.labels.put(label.getAddress(), label); } } @@ -105,14 +105,14 @@ public Optional getLabel(int address) { } @Override - public synchronized void setInputs(List inputs) { - clearInputs(); - this.inputs.addAll(inputs); + public List getInputs() { + return Collections.unmodifiableList(inputs); } @Override - public List getInputs() { - return Collections.unmodifiableList(inputs); + public synchronized void setInputs(List inputs) { + clearInputs(); + this.inputs.addAll(inputs); } @SuppressWarnings("unchecked") diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java index 21a1028b2..fb3b82b3a 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/MemoryImpl.java @@ -22,7 +22,10 @@ import net.emustudio.emulib.plugins.annotations.PluginRoot; import net.emustudio.emulib.plugins.memory.AbstractMemory; import net.emustudio.emulib.plugins.memory.MemoryContext; -import net.emustudio.emulib.runtime.*; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; +import net.emustudio.emulib.runtime.ContextPool; +import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; import net.emustudio.plugins.memory.ram.gui.MemoryDialog; @@ -36,8 +39,8 @@ @SuppressWarnings("unused") public class MemoryImpl extends AbstractMemory { private final MemoryContextImpl context; - private MemoryDialog gui; private final boolean guiNotSupported; + private MemoryDialog gui; public MemoryImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); @@ -74,13 +77,13 @@ public int getProgramLocation() { } @Override - public int getSize() { - return context.getSize(); + public void setProgramLocation(int location) { + // Program start is always 0 } @Override - public void setProgramLocation(int location) { - // Program start is always 0 + public int getSize() { + return context.getSize(); } @Override diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMInstruction.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMInstruction.java index 828eebe5a..ed5cb53cc 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMInstruction.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMInstruction.java @@ -28,24 +28,6 @@ */ public interface RAMInstruction extends Serializable { - enum Opcode { - READ, WRITE, LOAD, STORE, ADD, SUB, MUL, DIV, JMP, JZ, JGTZ, HALT - } - - enum Direction { - CONSTANT("="), DIRECT(""), INDIRECT("*"); - - private final String value; - - Direction(String value) { - this.value = Objects.requireNonNull(value); - } - - public String value() { - return value; - } - } - /** * Get address of this instruction * @@ -81,4 +63,22 @@ public String value() { * @return label operand */ Optional getLabel(); + + enum Opcode { + READ, WRITE, LOAD, STORE, ADD, SUB, MUL, DIV, JMP, JZ, JGTZ, HALT + } + + enum Direction { + CONSTANT("="), DIRECT(""), INDIRECT("*"); + + private final String value; + + Direction(String value) { + this.value = Objects.requireNonNull(value); + } + + public String value() { + return value; + } + } } diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java index 3f1e57dc8..8695195e3 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMMemoryContext.java @@ -31,7 +31,7 @@ public interface RAMMemoryContext extends MemoryContext { Optional getLabel(int address); - void setInputs(List inputs); - List getInputs(); + + void setInputs(List inputs); } diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMValue.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMValue.java index 8c818ab37..18f36058f 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMValue.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/RAMValue.java @@ -26,13 +26,6 @@ */ public interface RAMValue extends Serializable { - /** - * Value type - */ - enum Type { - NUMBER, STRING, ID - } - /** * Whether this value is an integer number * @@ -62,4 +55,11 @@ enum Type { * @return string representation of this value */ String getStringRepresentation(); + + /** + * Value type + */ + enum Type { + NUMBER, STRING, ID + } } diff --git a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/MemoryDialog.java b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/MemoryDialog.java index 756c9d15d..c20e80057 100644 --- a/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/MemoryDialog.java +++ b/plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/MemoryDialog.java @@ -41,6 +41,7 @@ public class MemoryDialog extends JDialog { private final MemoryContextImpl memory; private final RAMTableModel tableModel; private File lastOpenedFile; + private JTable tableProgram; public MemoryDialog(JFrame parent, MemoryContextImpl memory, Dialogs dialogs) { super(parent, false); @@ -124,6 +125,4 @@ private void btnOpenActionPerformed(java.awt.event.ActionEvent evt) { private void btnClearActionPerformed(java.awt.event.ActionEvent evt) { memory.clear(); } - - private JTable tableProgram; } diff --git a/plugins/memory/ram-mem/src/main/resources/net/emustudio/plugins/memory/ram/version.properties b/plugins/memory/ram-mem/src/main/resources/net/emustudio/plugins/memory/ram/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/memory/ram-mem/src/main/resources/net/emustudio/plugins/memory/ram/version.properties +++ b/plugins/memory/ram-mem/src/main/resources/net/emustudio/plugins/memory/ram/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryContextImplTest.java b/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryContextImplTest.java index 90e6d9092..eb61fcb98 100644 --- a/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryContextImplTest.java +++ b/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryContextImplTest.java @@ -60,8 +60,8 @@ public void memorySizeChanged() { } }); - memory.write(0, (RAMInstruction)createNiceMock(RAMInstruction.class)); - memory.write(0, (RAMInstruction)createNiceMock(RAMInstruction.class)); + memory.write(0, (RAMInstruction) createNiceMock(RAMInstruction.class)); + memory.write(0, (RAMInstruction) createNiceMock(RAMInstruction.class)); assertEquals(1, memorySizeChanges.get()); assertEquals(2, memoryChanges.get()); @@ -84,7 +84,7 @@ public void memorySizeChanged() { } }); - memory.write(0, new RAMInstruction[] { createNiceMock(RAMInstruction.class), createNiceMock(RAMInstruction.class)}, 2); + memory.write(0, new RAMInstruction[]{createNiceMock(RAMInstruction.class), createNiceMock(RAMInstruction.class)}, 2); assertEquals(1, memorySizeChanges.get()); assertEquals(2, memoryChanges.get()); diff --git a/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryImplTest.java b/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryImplTest.java index 90445be9c..7d9f60af2 100644 --- a/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryImplTest.java +++ b/plugins/memory/ram-mem/src/test/java/net/emustudio/plugins/memory/ram/MemoryImplTest.java @@ -26,7 +26,6 @@ import org.junit.Test; import static org.easymock.EasyMock.*; -import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertNotEquals; public class MemoryImplTest { diff --git a/plugins/memory/rasp-mem/build.gradle b/plugins/memory/rasp-mem/build.gradle index dce1ecd04..505dcbcbd 100644 --- a/plugins/memory/rasp-mem/build.gradle +++ b/plugins/memory/rasp-mem/build.gradle @@ -43,8 +43,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryContextImpl.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryContextImpl.java index c9ea1e5ff..e7b8e4547 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryContextImpl.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryContextImpl.java @@ -21,43 +21,17 @@ package net.emustudio.plugins.memory.rasp; import net.emustudio.emulib.plugins.memory.AbstractMemoryContext; -import net.emustudio.plugins.memory.rasp.api.*; +import net.emustudio.plugins.memory.rasp.api.RASPLabel; +import net.emustudio.plugins.memory.rasp.api.RASPMemoryCell; +import net.emustudio.plugins.memory.rasp.api.RASPMemoryContext; import java.io.*; import java.util.*; public class MemoryContextImpl extends AbstractMemoryContext implements RASPMemoryContext { - private final static class EmptyCell implements RASPMemoryCell { - private final int address; - - private EmptyCell(int address) { - this.address = address; - } - - @Override - public boolean isInstruction() { - return false; - } - - @Override - public int getAddress() { - return address; - } - - @Override - public int getValue() { - return 0; - } - - static EmptyCell at(int address) { - return new EmptyCell(address); - } - } - private final Map memory = new HashMap<>(); private final Map labels = new HashMap<>(); private final List inputs = new ArrayList<>(); - private int programLocation; @Override @@ -124,7 +98,7 @@ public Class getDataType() { @Override public synchronized void setLabels(List labels) { this.labels.clear(); - for (RASPLabel label: labels) { + for (RASPLabel label : labels) { this.labels.put(label.getAddress(), label); } } @@ -134,25 +108,24 @@ public Optional getLabel(int address) { return Optional.ofNullable(labels.get(address)); } - @Override - public synchronized void setInputs(List inputs) { - clearInputs(); - this.inputs.addAll(inputs); - } - @Override public List getInputs() { return Collections.unmodifiableList(inputs); } - public void setProgramLocation(int location) { - this.programLocation = location; + @Override + public synchronized void setInputs(List inputs) { + clearInputs(); + this.inputs.addAll(inputs); } public int getProgramLocation() { return programLocation; } + public void setProgramLocation(int location) { + this.programLocation = location; + } @SuppressWarnings("unchecked") public void deserialize(String filename) throws IOException, ClassNotFoundException { @@ -180,4 +153,31 @@ public void deserialize(String filename) throws IOException, ClassNotFoundExcept public void destroy() { clear(); } + + private final static class EmptyCell implements RASPMemoryCell { + private final int address; + + private EmptyCell(int address) { + this.address = address; + } + + static EmptyCell at(int address) { + return new EmptyCell(address); + } + + @Override + public boolean isInstruction() { + return false; + } + + @Override + public int getAddress() { + return address; + } + + @Override + public int getValue() { + return 0; + } + } } diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java index 64f1b36f3..79c984e1c 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/MemoryImpl.java @@ -40,15 +40,15 @@ @SuppressWarnings("unused") @PluginRoot( - type = PLUGIN_TYPE.MEMORY, - title = "RASP Memory" + type = PLUGIN_TYPE.MEMORY, + title = "RASP Memory" ) public class MemoryImpl extends AbstractMemory { private final static Logger LOGGER = LoggerFactory.getLogger(MemoryImpl.class); private final MemoryContextImpl context; - private MemoryDialog gui; private final boolean guiNotSupported; + private MemoryDialog gui; public MemoryImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); @@ -62,7 +62,7 @@ public MemoryImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s } catch (InvalidContextException | ContextAlreadyRegisteredException ex) { LOGGER.error("Could not register RASP memory context", ex); applicationApi.getDialogs().showError( - "Could not register RASP memory context. Please see log file for details.", super.getTitle() + "Could not register RASP memory context. Please see log file for details.", super.getTitle() ); } }); diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryCell.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryCell.java index ac94e62dc..81449deef 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryCell.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryCell.java @@ -20,7 +20,7 @@ import java.io.Serializable; -public interface RASPMemoryCell extends Serializable { +public interface RASPMemoryCell extends Serializable { boolean isInstruction(); diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryContext.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryContext.java index c438f138d..bc6cd4bbc 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryContext.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/RASPMemoryContext.java @@ -38,10 +38,10 @@ public interface RASPMemoryContext extends MemoryContext { Optional getLabel(int address); - void setInputs(List inputs); - List getInputs(); + void setInputs(List inputs); + default Optional disassemble(int opcode) { return Disassembler.disassemble(opcode); } diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/Disassembler.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/Disassembler.java index 5a354ca07..b1063bc67 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/Disassembler.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/Disassembler.java @@ -23,11 +23,10 @@ import java.util.Optional; public class Disassembler { - private final static Map instructions = new HashMap<>(); - public final static int JMP = 15; public final static int JZ = 16; public final static int JGTZ = 17; + private final static Map instructions = new HashMap<>(); static { instructions.put(1, "READ"); diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/MemoryDialog.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/MemoryDialog.java index 7d7b4b7fc..0af4d6bb7 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/MemoryDialog.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/MemoryDialog.java @@ -41,6 +41,7 @@ public class MemoryDialog extends JDialog { private final MemoryContextImpl memory; private final RASPTableModel tableModel; private File recentOpenPath; + private javax.swing.JTable memoryTable; public MemoryDialog(JFrame parent, MemoryContextImpl context, Dialogs dialogs) { super(parent, false); @@ -113,27 +114,26 @@ public void mouseClicked(java.awt.event.MouseEvent evt) { javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 265, Short.MAX_VALUE) - .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 265, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 491, Short.MAX_VALUE)) + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 491, Short.MAX_VALUE)) ); pack(); } - private void onOpenClick(java.awt.event.ActionEvent evt) { File currentDirectory = Objects.requireNonNullElse(recentOpenPath, new File(System.getProperty("user.dir"))); dialogs.chooseFile( - "Load compiled RASP program", "Load", currentDirectory.toPath(), false, - new FileExtensionsFilter("RASP compiler file", "bin") + "Load compiled RASP program", "Load", currentDirectory.toPath(), false, + new FileExtensionsFilter("RASP compiler file", "bin") ).ifPresent(path -> { recentOpenPath = path.toFile().getParentFile(); try { @@ -164,7 +164,4 @@ private void memoryTableMouseClicked(java.awt.event.MouseEvent evt) { memoryTable.editCellAt(row, 1); } } - - - private javax.swing.JTable memoryTable; } diff --git a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/RASPTableModel.java b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/RASPTableModel.java index fc0d2f2bf..9caa48dce 100644 --- a/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/RASPTableModel.java +++ b/plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/RASPTableModel.java @@ -20,7 +20,9 @@ package net.emustudio.plugins.memory.rasp.gui; -import net.emustudio.plugins.memory.rasp.api.*; +import net.emustudio.plugins.memory.rasp.api.RASPLabel; +import net.emustudio.plugins.memory.rasp.api.RASPMemoryCell; +import net.emustudio.plugins.memory.rasp.api.RASPMemoryContext; import javax.swing.table.AbstractTableModel; @@ -111,9 +113,9 @@ private String getMnemonicColumnValue(int rowIndex) { case JZ: case JGTZ: return memory - .getLabel(item.getValue()) - .map(RASPLabel::getLabel) - .orElse(String.valueOf(item.getValue())); + .getLabel(item.getValue()) + .map(RASPLabel::getLabel) + .orElse(String.valueOf(item.getValue())); } } } diff --git a/plugins/memory/rasp-mem/src/main/resources/net/emustudio/plugins/memory/rasp/version.properties b/plugins/memory/rasp-mem/src/main/resources/net/emustudio/plugins/memory/rasp/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/memory/rasp-mem/src/main/resources/net/emustudio/plugins/memory/rasp/version.properties +++ b/plugins/memory/rasp-mem/src/main/resources/net/emustudio/plugins/memory/rasp/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo diff --git a/plugins/memory/rasp-mem/src/test/java/net/emustudio/plugins/memory/rasp/MemoryImplTest.java b/plugins/memory/rasp-mem/src/test/java/net/emustudio/plugins/memory/rasp/MemoryImplTest.java index 191214a8d..681a568ca 100644 --- a/plugins/memory/rasp-mem/src/test/java/net/emustudio/plugins/memory/rasp/MemoryImplTest.java +++ b/plugins/memory/rasp-mem/src/test/java/net/emustudio/plugins/memory/rasp/MemoryImplTest.java @@ -26,7 +26,6 @@ import org.junit.Test; import static org.easymock.EasyMock.*; -import static org.easymock.EasyMock.replay; import static org.junit.Assert.assertNotEquals; public class MemoryImplTest { diff --git a/plugins/memory/ssem-mem/build.gradle b/plugins/memory/ssem-mem/build.gradle index 7fb6d4874..f8f351124 100644 --- a/plugins/memory/ssem-mem/build.gradle +++ b/plugins/memory/ssem-mem/build.gradle @@ -44,8 +44,8 @@ jar { processResources { filesMatching("**/*.properties") { filter ReplaceTokens, tokens: [ - "project.version": project.version, - "today.year": new Date().format("yyyy") + "project.version": project.version, + "today.year" : new Date().format("yyyy") ] } } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java index 4788566b6..c401cc2b6 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryContextImpl.java @@ -19,7 +19,6 @@ package net.emustudio.plugins.memory.ssem; import net.emustudio.emulib.plugins.memory.AbstractMemoryContext; -import net.emustudio.emulib.runtime.helpers.NumberUtils; import net.jcip.annotations.ThreadSafe; import java.util.Arrays; diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java index 97f5d69b4..071c88b0e 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java @@ -36,16 +36,16 @@ import java.util.ResourceBundle; @PluginRoot( - type = PLUGIN_TYPE.MEMORY, - title = "SSEM memory (Williams-Kilburn Tube)" + type = PLUGIN_TYPE.MEMORY, + title = "SSEM memory (Williams-Kilburn Tube)" ) @SuppressWarnings("unused") public class MemoryImpl extends AbstractMemory { private final static Logger LOGGER = LoggerFactory.getLogger(MemoryImpl.class); private final MemoryContextImpl memContext = new MemoryContextImpl(); - private MemoryGui memoryGUI; private final boolean guiNotSupported; + private MemoryGui memoryGUI; public MemoryImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); @@ -56,7 +56,7 @@ public MemoryImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register SSEM memory context", e); applicationApi.getDialogs().showError( - "Could not register SSEM memory. Please see log file for more details.", getTitle() + "Could not register SSEM memory. Please see log file for more details.", getTitle() ); } } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/Constants.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/Constants.java index 89681549e..708edd152 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/Constants.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/Constants.java @@ -36,10 +36,10 @@ public final class Constants { public final static int TWO_CHARS = 2 * CHAR_WIDTH; public final static int[] COLUMN_WIDTH = new int[]{ - TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, - TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, - TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, - TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, - 10 * CHAR_WIDTH, 10 * CHAR_WIDTH, 5 * CHAR_WIDTH + TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, + TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, + TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, + TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, TWO_CHARS, + 10 * CHAR_WIDTH, 10 * CHAR_WIDTH, 5 * CHAR_WIDTH }; } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java index 0139a1282..e3b104485 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java @@ -26,19 +26,7 @@ public class MemoryGui extends JDialog { private final MemoryTableModel tableModel; - - private class MemoryListenerImpl implements Memory.MemoryListener { - - @Override - public void memoryChanged(int memoryPosition) { - tableModel.dataChangedAt(memoryPosition); - } - - @Override - public void memorySizeChanged() { - tableModel.fireTableDataChanged(); - } - } + private JScrollPane scrollPane; public MemoryGui(JFrame parent, MemoryContext memory) { super(parent); @@ -84,16 +72,16 @@ private void initComponents() { GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 965, Short.MAX_VALUE) - .addComponent(toolBar, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 965, Short.MAX_VALUE) + .addComponent(toolBar, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(toolBar, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 455, Short.MAX_VALUE)) + layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(toolBar, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 455, Short.MAX_VALUE)) ); pack(); @@ -103,5 +91,16 @@ private void btnClearActionPerformed(java.awt.event.ActionEvent evt) { tableModel.clear(); } - private JScrollPane scrollPane; + private class MemoryListenerImpl implements Memory.MemoryListener { + + @Override + public void memoryChanged(int memoryPosition) { + tableModel.dataChangedAt(memoryPosition); + } + + @Override + public void memorySizeChanged() { + tableModel.fireTableDataChanged(); + } + } } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java index 63cad35b2..21c098ed1 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryTableModel.java @@ -28,12 +28,10 @@ import java.util.Objects; public class MemoryTableModel extends AbstractTableModel { - private final static Logger LOGGER = LoggerFactory.getLogger(MemoryTableModel.class); - final static int COLUMN_HEX_VALUE = 32; final static int COLUMN_DEC_VALUE = 33; final static int COLUMN_RAW_VALUE = 34; - + private final static Logger LOGGER = LoggerFactory.getLogger(MemoryTableModel.class); private final static int ROW_COUNT = 32; private final static int COLUMN_COUNT = 3 + 32; @@ -43,23 +41,6 @@ public class MemoryTableModel extends AbstractTableModel { this.memory = Objects.requireNonNull(memory); } - public void dump() { - for (int i = 0; i < 32; i++) { - Byte[] v = memory.read(i * 4, 4); - System.out.printf("0x%02X, 0x%02X, 0x%02X, 0x%02X,\n", v[0], v[1], v[2], v[3]); - } - } - - @Override - public int getRowCount() { - return ROW_COUNT; - } - - @Override - public int getColumnCount() { - return COLUMN_COUNT; - } - /** * Determine if a column index points at a bit which is part of the 3 bits in a memory cell representing a SSEM * instruction. @@ -82,6 +63,23 @@ static boolean isBitLine(int column) { return column >= 0 && column < 5; } + public void dump() { + for (int i = 0; i < 32; i++) { + Byte[] v = memory.read(i * 4, 4); + System.out.printf("0x%02X, 0x%02X, 0x%02X, 0x%02X,\n", v[0], v[1], v[2], v[3]); + } + } + + @Override + public int getRowCount() { + return ROW_COUNT; + } + + @Override + public int getColumnCount() { + return COLUMN_COUNT; + } + @Override public String getColumnName(int columnIndex) { switch (columnIndex) { @@ -126,7 +124,7 @@ public Object getValueAt(int rowIndex, int columnIndex) { return String.valueOf(value); case COLUMN_RAW_VALUE: return "" + (char) ((value >>> 24) & 0xFF) + (char) ((value >>> 16) & 0xFF) - + (char) ((value >>> 8) & 0xFF) + (char) (value & 0xFF); + + (char) ((value >>> 8) & 0xFF) + (char) (value & 0xFF); default: byte[] lineBits = readLineBits(row); return lineBits[columnIndex]; diff --git a/plugins/memory/ssem-mem/src/main/resources/net/emustudio/plugins/memory/ssem/version.properties b/plugins/memory/ssem-mem/src/main/resources/net/emustudio/plugins/memory/ssem/version.properties index e606f2a3e..6592047b6 100644 --- a/plugins/memory/ssem-mem/src/main/resources/net/emustudio/plugins/memory/ssem/version.properties +++ b/plugins/memory/ssem-mem/src/main/resources/net/emustudio/plugins/memory/ssem/version.properties @@ -16,6 +16,5 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # - version=@project.version@ copyright=\u00A9 Copyright 2006-@today.year@, Peter Jakubčo From e0e88327dc076a8ebbb602b337d3951e1bcb1704 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 29 Dec 2022 09:56:44 +0100 Subject: [PATCH 237/314] Update ADM-3A settings --- .../plugins/compiler/asZ80/AssemblerZ80.java | 2 +- .../plugins/device/adm3a/DeviceImpl.java | 4 +- .../device/adm3a/TerminalSettings.java | 30 ++++---- .../adm3a/gui/DisplayFontJComboRenderer.java | 9 +-- ...{ConfigDialog.java => SettingsDialog.java} | 68 +++++++++---------- 5 files changed, 58 insertions(+), 55 deletions(-) rename plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/{ConfigDialog.java => SettingsDialog.java} (85%) diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java index 43ebc2096..0974d87d4 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/AssemblerZ80.java @@ -108,7 +108,7 @@ public boolean compile(String inputFileName, String outputFileName) { notifyInfo(getTitle() + ", version " + getVersion()); try (Reader reader = new FileReader(inputFileName)) { - org.antlr.v4.runtime.Lexer lexer = createLexer(CharStreams.fromReader(reader)); + AsZ80Lexer lexer = createLexer(CharStreams.fromReader(reader)); lexer.addErrorListener(new ParserErrorListener()); CommonTokenStream tokens = new CommonTokenStream(lexer); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index 8f21fa2ba..e26cc3273 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -30,7 +30,7 @@ import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.device.adm3a.api.ContextAdm3A; import net.emustudio.plugins.device.adm3a.api.Keyboard; -import net.emustudio.plugins.device.adm3a.gui.ConfigDialog; +import net.emustudio.plugins.device.adm3a.gui.SettingsDialog; import net.emustudio.plugins.device.adm3a.gui.GuiUtils; import net.emustudio.plugins.device.adm3a.gui.TerminalWindow; import net.emustudio.plugins.device.adm3a.interaction.Cursor; @@ -165,7 +165,7 @@ public void destroy() { @Override public void showSettings(JFrame parent) { if (isShowSettingsSupported()) { - new ConfigDialog(parent, terminalSettings, terminalGUI, applicationApi.getDialogs()).setVisible(true); + new SettingsDialog(parent, terminalSettings, terminalGUI, applicationApi.getDialogs()).setVisible(true); } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java index 1a868afa0..bf4890d93 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java @@ -34,7 +34,6 @@ public class TerminalSettings { public final static String DEFAULT_INPUT_FILE_NAME = "adm3A-terminal.in"; public final static String DEFAULT_OUTPUT_FILE_NAME = "adm3A-terminal.out"; private final static Logger LOGGER = LoggerFactory.getLogger(TerminalSettings.class); - private final static String ANTI_ALIASING = "antiAliasing"; private final static String HALF_DUPLEX = "halfDuplex"; private final static String ALWAYS_ON_TOP = "alwaysOnTop"; private final static String INPUT_FILE_NAME = "inputFileName"; @@ -47,7 +46,6 @@ public class TerminalSettings { private final boolean guiSupported; private final List observers = new ArrayList<>(); private boolean halfDuplex = false; - private boolean antiAliasing = true; private boolean alwaysOnTop = false; private volatile Path inputPath = Path.of(DEFAULT_INPUT_FILE_NAME); private volatile Path outputPath = Path.of(DEFAULT_OUTPUT_FILE_NAME); @@ -111,15 +109,6 @@ public void setOutputPath(Path outputFileName) throws IOException { notifyObservers(); } - public boolean isAntiAliasing() { - return antiAliasing; - } - - public void setAntiAliasing(boolean antiAliasing) { - this.antiAliasing = antiAliasing; - notifyObserversAndIgnoreError(); - } - public boolean isAlwaysOnTop() { return alwaysOnTop; } @@ -150,7 +139,6 @@ public void write() { settings.setInt(INPUT_READ_DELAY, inputReadDelay); settings.setBoolean(HALF_DUPLEX, halfDuplex); settings.setBoolean(ALWAYS_ON_TOP, alwaysOnTop); - settings.setBoolean(ANTI_ALIASING, antiAliasing); settings.setString(OUTPUT_FILE_NAME, outputPath.toString()); settings.setString(INPUT_FILE_NAME, inputPath.toString()); settings.setInt(DEVICE_INDEX, deviceIndex); @@ -166,7 +154,6 @@ public void write() { private void readSettings() { halfDuplex = settings.getBoolean(HALF_DUPLEX, false); alwaysOnTop = settings.getBoolean(ALWAYS_ON_TOP, false); - antiAliasing = settings.getBoolean(ANTI_ALIASING, true); inputPath = Path.of(settings.getString(INPUT_FILE_NAME, DEFAULT_INPUT_FILE_NAME)); outputPath = Path.of(settings.getString(OUTPUT_FILE_NAME, DEFAULT_OUTPUT_FILE_NAME)); deviceIndex = settings.getInt(DEVICE_INDEX, 0); @@ -179,6 +166,13 @@ private void readSettings() { ); } font = TerminalFont.valueOf(settings.getString(FONT, TerminalFont.ORIGINAL.name).toUpperCase()); + + if (inputPath.toString().equals(outputPath.toString())) { + LOGGER.error("ADM-3A settings: Input path is not allowed to be equal to the output path. Setting to default."); + inputPath = Path.of(DEFAULT_INPUT_FILE_NAME); + outputPath = Path.of(DEFAULT_OUTPUT_FILE_NAME); + } + notifyObserversAndIgnoreError(); } @@ -207,6 +201,16 @@ public enum TerminalFont { TerminalFont(String name) { this.name = Objects.requireNonNull(name); } + + public static TerminalFont valueOf(int index) { + if (index == 0) { + return ORIGINAL; + } else if (index == 1) { + return MODERN; + } else { + throw new RuntimeException("Unknown font index: " + index); + } + } } public interface ChangedObserver { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java index 30779be6f..3e0f1de95 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java @@ -23,7 +23,7 @@ import static net.emustudio.plugins.device.adm3a.Utils.loadFont; -public class DisplayFontJComboRenderer extends JLabel implements ListCellRenderer { +public class DisplayFontJComboRenderer extends JLabel implements ListCellRenderer { private final Font originalFont = loadFont(DisplayFont.FONT_ORIGINAL); private final Font modernFont = loadFont(DisplayFont.FONT_MODERN); @@ -32,9 +32,8 @@ public DisplayFontJComboRenderer() { } @Override - public Component getListCellRendererComponent(JList list, String value, int index, + public Component getListCellRendererComponent(JList list, Integer value, int index, boolean isSelected, boolean cellHasFocus) { - setText(value); if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); @@ -42,12 +41,14 @@ public Component getListCellRendererComponent(JList list, Stri setBackground(list.getBackground()); setForeground(list.getForeground()); } - switch (index) { + switch (value) { case 0: setFont(originalFont); + setText("Original"); break; case 1: setFont(modernFont); + setText("Modern"); break; default: } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/SettingsDialog.java similarity index 85% rename from plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java rename to plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/SettingsDialog.java index d813c09b0..52f073845 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/ConfigDialog.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/SettingsDialog.java @@ -27,23 +27,23 @@ import java.io.IOException; import java.nio.file.Path; import java.util.Objects; +import java.util.Optional; import static net.emustudio.plugins.device.adm3a.TerminalSettings.DEFAULT_INPUT_FILE_NAME; import static net.emustudio.plugins.device.adm3a.TerminalSettings.DEFAULT_OUTPUT_FILE_NAME; -public class ConfigDialog extends JDialog { +public class SettingsDialog extends JDialog { private final TerminalSettings settings; private final TerminalWindow window; private final Dialogs dialogs; private final JCheckBox chkAlwaysOnTop = new JCheckBox("Display always on top"); - private final JCheckBox chkAntiAliasing = new JCheckBox("Use anti-aliasing"); private final JCheckBox chkHalfDuplex = new JCheckBox("Half duplex mode"); - private final JCheckBox chkSaveSettings = new JCheckBox("Save settings"); private final JSpinner spnInputDelay = new JSpinner(); private final JTextField txtInputFileName = new JTextField(DEFAULT_INPUT_FILE_NAME); private final JTextField txtOutputFileName = new JTextField(DEFAULT_OUTPUT_FILE_NAME); - private final JComboBox cmbFont = new JComboBox<>(); - public ConfigDialog(JFrame parent, TerminalSettings settings, TerminalWindow window, Dialogs dialogs) { + private final JComboBox cmbFont = new JComboBox<>(new Integer[]{0, 1}); + + public SettingsDialog(JFrame parent, TerminalSettings settings, TerminalWindow window, Dialogs dialogs) { super(parent, true); this.dialogs = Objects.requireNonNull(dialogs); @@ -59,23 +59,20 @@ public ConfigDialog(JFrame parent, TerminalSettings settings, TerminalWindow win private void readSettings() { chkHalfDuplex.setSelected(settings.isHalfDuplex()); chkAlwaysOnTop.setSelected(settings.isAlwaysOnTop()); - chkAntiAliasing.setSelected(settings.isAntiAliasing()); txtInputFileName.setText(settings.getInputPath().toString()); txtOutputFileName.setText(settings.getOutputPath().toString()); spnInputDelay.setValue(settings.getInputReadDelay()); } - private void updateSettings(boolean save) throws IOException { + private void updateSettings() throws IOException { settings.setHalfDuplex(chkHalfDuplex.isSelected()); settings.setAlwaysOnTop(chkAlwaysOnTop.isSelected()); - settings.setAntiAliasing(chkAntiAliasing.isSelected()); settings.setInputPath(Path.of(txtInputFileName.getText())); settings.setOutputPath(Path.of(txtOutputFileName.getText())); settings.setInputReadDelay((Integer) spnInputDelay.getValue()); - settings.setFont(TerminalSettings.TerminalFont.valueOf(cmbFont.getSelectedItem().toString().toUpperCase())); - if (save) { - settings.write(); - } + getSelectedFont().ifPresent(settings::setFont); + + settings.write(); } private void initComponents() { @@ -84,33 +81,31 @@ private void initComponents() { JButton btnInputBrowse = new JButton("Browse..."); JLabel lblOutputFileName = new JLabel("Output file name:"); JButton btnOutputBrowse = new JButton("Browse..."); - JLabel lblNote = new JLabel("Note: I/O redirection will be used only if No GUI mode is enabled."); + JLabel lblNote = new JLabel("Note: I/O redirection will be used only in case of No GUI mode."); JLabel lblInputDelay = new JLabel("Input delay:"); JLabel lblMs = new JLabel("ms"); JPanel panelTerminal = new JPanel(); - JButton btnOK = new JButton("OK"); + JButton btnSave = new JButton("Save"); JLabel lblFont = new JLabel("Font"); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); - setTitle("Configuration of the terminal"); + setTitle("LSI ADM-3A Settings"); panelRedirectIO.setBorder(BorderFactory.createTitledBorder( null, "Redirect I/O", 0, 0, lblInputFileName.getFont().deriveFont(lblInputFileName.getFont().getStyle() | Font.BOLD) )); - cmbFont.setModel(new DefaultComboBoxModel<>(new String[]{"Original", "Modern"})); cmbFont.setRenderer(new DisplayFontJComboRenderer()); - cmbFont.setPrototypeDisplayValue("Original original"); cmbFont.setSelectedIndex(settings.getFont().ordinal()); spnInputDelay.setModel(new SpinnerNumberModel(0, 0, null, 100)); - chkSaveSettings.setSelected(true); - btnOK.addActionListener(this::btnOKActionPerformed); - btnOK.setDefaultCapable(true); + btnSave.addActionListener(this::btnSaveActionPerformed); + btnSave.setFont(btnSave.getFont().deriveFont(Font.BOLD)); + btnSave.setDefaultCapable(true); GroupLayout layoutRedirectIO = new GroupLayout(panelRedirectIO); panelRedirectIO.setLayout(layoutRedirectIO); @@ -180,8 +175,7 @@ private void initComponents() { .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(cmbFont)) .addComponent(chkHalfDuplex) - .addComponent(chkAlwaysOnTop) - .addComponent(chkAntiAliasing)) + .addComponent(chkAlwaysOnTop)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); layoutTerminal.setVerticalGroup( @@ -194,8 +188,6 @@ private void initComponents() { .addComponent(chkHalfDuplex) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(chkAlwaysOnTop) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkAntiAliasing) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -211,12 +203,10 @@ private void initComponents() { .addContainerGap()) .addGroup(layout.createSequentialGroup() .addComponent(panelTerminal, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addContainerGap()) - .addGroup(layout.createSequentialGroup() - .addComponent(chkSaveSettings)))) + .addContainerGap()))) .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnOK, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) + .addComponent(btnSave, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); layout.setVerticalGroup( @@ -226,27 +216,35 @@ private void initComponents() { .addComponent(panelRedirectIO, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(panelTerminal, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(chkSaveSettings) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnOK) + .addComponent(btnSave) .addContainerGap()) ); pack(); } - private void btnOKActionPerformed(java.awt.event.ActionEvent evt) { + private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) { + if (txtInputFileName.getText().trim().equals(txtOutputFileName.getText().trim())) { + dialogs.showError("Input and output file names cannot point to the same file"); + txtInputFileName.grabFocus(); + return; + } if (window != null) { window.setAlwaysOnTop(chkAlwaysOnTop.isSelected()); - window.setDisplayFont(DisplayFont.fromTerminalFont( - TerminalSettings.TerminalFont.valueOf(cmbFont.getSelectedItem().toString().toUpperCase()))); + getSelectedFont().ifPresent(f -> window.setDisplayFont(DisplayFont.fromTerminalFont(f))); } try { - updateSettings(chkSaveSettings.isSelected()); + updateSettings(); dispose(); } catch (IOException e) { dialogs.showError("Input or output file names (or both) do not exist. Please make sure they do.", "ADM-3A Terminal"); } } + + private Optional getSelectedFont() { + return Optional.ofNullable(cmbFont.getSelectedItem()) + .map(p -> (Integer) p) + .map(TerminalSettings.TerminalFont::valueOf); + } } From 6e861242f16c0ce1441fc0ffde45e7b6d74fada1 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 29 Dec 2022 12:44:51 +0100 Subject: [PATCH 238/314] Dialog title --- .../net/emustudio/plugins/device/adm3a/TerminalSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java index bf4890d93..95037e244 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/TerminalSettings.java @@ -145,7 +145,7 @@ public void write() { settings.setString(FONT, font.name); } catch (CannotUpdateSettingException e) { LOGGER.error("Could not update settings", e); - dialogs.showError("Could not save settings. Please see log file for details.", "ADM 3A"); + dialogs.showError("Could not save settings. Please see log file for details.", "LSI ADM-3A"); } finally { notifyObserversAndIgnoreError(); } From 7e97ddd53a26802f3d5271dc79bb6b0203c39884 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 31 Dec 2022 08:35:04 +0100 Subject: [PATCH 239/314] Upgraded few dependencies --- application/build.gradle | 1 - build.gradle | 11 +- .../plugins/device/adm3a/gui/adm-3a.ttf | Bin 36364 -> 36364 bytes resources/lsi-adm-3a/adm-3a.ttf | Bin 36364 -> 36364 bytes resources/lsi-adm-3a/adm3a.sfd | 524 +++++++++--------- 5 files changed, 266 insertions(+), 270 deletions(-) diff --git a/application/build.gradle b/application/build.gradle index 36163660e..9fa63532b 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -49,7 +49,6 @@ dependencies { extraLibs libs.logback extraLibs libs.slf4JApi - extraLibsRuntime libs.javaCupRuntime providedRuntime project(":plugins:compiler:as-8080") providedRuntime project(":plugins:compiler:as-ssem") providedRuntime project(":plugins:compiler:as-z80") diff --git a/build.gradle b/build.gradle index ede389050..214bc3be2 100644 --- a/build.gradle +++ b/build.gradle @@ -22,29 +22,28 @@ import java.text.SimpleDateFormat apply from: 'test_report.gradle' ext.versions = [ - slf4j: '1.7.30' + slf4j: '2.0.6' ] ext.libs = [ emuLib : "net.emustudio:emulib:11.7.0-SNAPSHOT", cpuTestSuite : "net.emustudio:cpu-testsuite_11.6:1.2.0-SNAPSHOT", - javaCupRuntime : "com.github.vbmacher:java-cup-runtime:11b-20160615", jcipAnnotations : "net.jcip:jcip-annotations:1.0", antlrRuntime : "org.antlr:antlr4-runtime:4.11.1", slf4JApi : "org.slf4j:slf4j-api:${versions.slf4j}", slf4JSimple : "org.slf4j:slf4j-simple:${versions.slf4j}", slf4JNop : "org.slf4j:slf4j-nop:${versions.slf4j}", - logback : "ch.qos.logback:logback-classic:1.2.3", + logback : "ch.qos.logback:logback-classic:1.4.5", picocli : "info.picocli:picocli:4.7.0", picocliAnnotation: "info.picocli:picocli-codegen:4.7.0", - tomlj : "com.electronwill.night-config:toml:3.6.5", + tomlj : "com.electronwill.night-config:toml:3.6.6", - editor : "com.fifesoft:rsyntaxtextarea:3.1.6", - editorDialogs : "com.fifesoft:rstaui:3.1.4", + editor : "com.fifesoft:rsyntaxtextarea:3.3.1", + editorDialogs : "com.fifesoft:rstaui:3.3.0", junit : "junit:junit:4.13", easyMock : "org.easymock:easymock:4.2", diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf index 946d149847b1c8749c0053507e150e59f850859d..8ea6efb9b3e833f4f897983e15265904280593f9 100644 GIT binary patch delta 99 zcmeB~!_+f}NrZusfq{XKp@D&!A;HZp#CM+D@0f`qxy+w`ADGzU!}8~7f5OBo3NlYk zEPluH+k9o<<^ZZ^V7Tus_XJE|o$`IN0Apt;voV9=YEcqa+&Y0v7OlB!}9-df8xX|3NrU6 zmb1q5+k9o<<^ZZ^V7Tus_XJGucP-g0z}OkeY{+0Tc}|!eM@vYEcqa+&Y0v7OlB!}9-df8xX|3NrU6 zmb1q5+k9o<<^ZZ^V7Tus_XJGucP-g0z}OkeY{+0Tc}|!eM@va @@ -806,7 +804,7 @@ StartChar: DC3 Encoding: 19 19 18 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9N3T>a @@ -847,7 +845,7 @@ StartChar: DC4 Encoding: 20 20 19 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 122 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -886,7 +884,7 @@ StartChar: NAK Encoding: 21 21 20 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 115 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8CJNffG9Xot.% @@ -920,7 +918,7 @@ StartChar: SYN Encoding: 22 22 21 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -953,7 +951,7 @@ StartChar: ETB Encoding: 23 23 22 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 115 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -997,7 +995,7 @@ StartChar: CAN Encoding: 24 24 23 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 126 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W77fm5<#?L$:.Z&u+:&>Ss5t#,..n,f @@ -1036,7 +1034,7 @@ StartChar: EM Encoding: 25 25 24 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8C%,9r(&3hH^h @@ -1069,7 +1067,7 @@ StartChar: SUB Encoding: 26 26 25 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 109 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8sb%RU9&*Yr8r @@ -1101,7 +1099,7 @@ StartChar: ESC Encoding: 27 27 26 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 118 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%RU9&*YsiL @@ -1135,7 +1133,7 @@ StartChar: FS Encoding: 28 28 27 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8C%,9n7D"pQE9 @@ -1163,7 +1161,7 @@ StartChar: GS Encoding: 29 29 28 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 115 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8+BNffG9Xor#n @@ -1193,7 +1191,7 @@ StartChar: RS Encoding: 30 30 29 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 118 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns2BO@1f( @@ -1220,7 +1218,7 @@ StartChar: US Encoding: 31 31 30 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8Dg*$Z[QM@bLD @@ -1251,7 +1249,7 @@ StartChar: exclam Encoding: 33 33 31 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 96 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -1277,7 +1275,7 @@ StartChar: quotedbl Encoding: 34 34 32 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 103 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8CJNffG9X9;!; @@ -1303,7 +1301,7 @@ StartChar: numbersign Encoding: 35 35 33 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 107 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CJNffG9X9;!; @@ -1353,7 +1351,7 @@ StartChar: dollar Encoding: 36 36 34 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 127 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W7S-!6<#?L$bs;]P5R^!,B't03:)+gl @@ -1410,7 +1408,7 @@ StartChar: percent Encoding: 37 37 35 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$N_p8d+:(< @@ -1498,7 +1496,7 @@ StartChar: quotesingle Encoding: 39 39 37 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 100 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -1519,7 +1517,7 @@ StartChar: parenleft Encoding: 40 40 38 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 111 320 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8CNNffG9`^HN: @@ -1546,7 +1544,7 @@ StartChar: parenright Encoding: 41 41 39 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 113 -192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -1573,7 +1571,7 @@ StartChar: asterisk Encoding: 42 42 40 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NS=d?+:(?(s8UE1_?!r( @@ -1613,7 +1611,7 @@ StartChar: plus Encoding: 43 43 41 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3&!@&g6 @@ -1642,7 +1640,7 @@ StartChar: comma Encoding: 44 44 42 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 91 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2\'ehBu @@ -1667,7 +1665,7 @@ StartChar: hyphen Encoding: 45 45 43 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 94 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns4Z$5e?V @@ -1688,7 +1686,7 @@ StartChar: period Encoding: 46 46 44 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 84 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[;S^Ap @@ -1709,7 +1707,7 @@ StartChar: slash Encoding: 47 47 45 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns3P!_,XK @@ -1732,7 +1730,7 @@ StartChar: zero Encoding: 48 48 46 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8+BNffG9Xor#n @@ -1770,7 +1768,7 @@ StartChar: one Encoding: 49 49 47 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 107 64.0271 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CNNffG9`^HN: @@ -1804,7 +1802,7 @@ StartChar: two Encoding: 50 50 48 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 124 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?K_r!ro=GQ8+BNffG9Xor#n @@ -1845,7 +1843,7 @@ StartChar: three Encoding: 51 51 49 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 123 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?K_r!ro=GQ8sb%RU9&*Yr8r @@ -1891,7 +1889,7 @@ StartChar: four Encoding: 52 52 50 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -1925,7 +1923,7 @@ StartChar: five Encoding: 53 53 51 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8sb%RU9&*YsiL @@ -1964,7 +1962,7 @@ StartChar: six Encoding: 54 54 52 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+FNffG9`ah?c @@ -2004,7 +2002,7 @@ StartChar: seven Encoding: 55 55 53 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8sb%RU9&*Yr8r @@ -2032,7 +2030,7 @@ StartChar: eight Encoding: 56 56 54 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 100 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2081,7 +2079,7 @@ StartChar: nine Encoding: 57 57 55 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 123 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2121,7 +2119,7 @@ StartChar: colon Encoding: 58 58 56 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns4f$5aWu @@ -2147,7 +2145,7 @@ StartChar: semicolon Encoding: 59 59 57 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 104 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns4f$5aWu @@ -2177,7 +2175,7 @@ StartChar: less Encoding: 60 60 58 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 116 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -2203,7 +2201,7 @@ StartChar: equal Encoding: 61 61 59 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 96 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8Bu3Ns2`"cP]X @@ -2229,7 +2227,7 @@ StartChar: greater Encoding: 62 62 60 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 114 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?L$c9Vp?+:&'8li7!DD@\!2 @@ -2255,7 +2253,7 @@ StartChar: question Encoding: 63 63 61 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2293,7 +2291,7 @@ StartChar: at Encoding: 64 64 62 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 124 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$N^4!P+:&,)nGcju-;[[9 @@ -2337,7 +2335,7 @@ StartChar: A Encoding: 65 65 63 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 119 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8CNNffG9`^HN: @@ -2374,7 +2372,7 @@ StartChar: B Encoding: 66 66 64 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 96 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8sb%RgE0H5;TS @@ -2414,7 +2412,7 @@ StartChar: C Encoding: 67 67 65 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2453,7 +2451,7 @@ StartChar: D Encoding: 68 68 66 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 98 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.7lon<#?K_r!ro=GQ8sb%RgE0H5;TS @@ -2483,7 +2481,7 @@ StartChar: E Encoding: 69 69 67 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 102 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8sb%RU9&*YsiL @@ -2512,7 +2510,7 @@ StartChar: F Encoding: 70 70 68 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 100 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8sb%RU9&*YsiL @@ -2539,7 +2537,7 @@ StartChar: G Encoding: 71 71 69 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8+BNffG971$7@ @@ -2573,7 +2571,7 @@ StartChar: H Encoding: 72 72 70 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 105 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -2602,7 +2600,7 @@ StartChar: I Encoding: 73 73 71 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 106 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2631,7 +2629,7 @@ StartChar: J Encoding: 74 74 72 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 100 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8Dg*$Z[QM@bLD @@ -2660,7 +2658,7 @@ StartChar: K Encoding: 75 75 73 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 118 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8C%,9r(&3hH^] @@ -2692,7 +2690,7 @@ StartChar: L Encoding: 76 76 74 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 94 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8C%,9n7D"pQEe @@ -2715,7 +2713,7 @@ StartChar: M Encoding: 77 77 75 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8C%,9r(&3hH^( @@ -2749,8 +2747,8 @@ EndChar StartChar: N Encoding: 78 78 76 Width: 1408 -Flags: MWO -LayerCount: 3 +Flags: MW +LayerCount: 2 Back Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -2778,7 +2776,7 @@ StartChar: O Encoding: 79 79 77 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 103 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2815,7 +2813,7 @@ StartChar: P Encoding: 80 80 78 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 103 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8sb%RgE0H5;TS @@ -2847,7 +2845,7 @@ StartChar: Q Encoding: 81 81 79 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2889,7 +2887,7 @@ StartChar: R Encoding: 82 82 80 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 118 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%RgE0H5;TS @@ -2926,7 +2924,7 @@ StartChar: S Encoding: 83 83 81 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n @@ -2973,7 +2971,7 @@ StartChar: T Encoding: 84 84 82 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8sb%RU9&*YoTJ @@ -2998,7 +2996,7 @@ StartChar: U Encoding: 85 85 83 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 95 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -3027,7 +3025,7 @@ StartChar: V Encoding: 86 86 84 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 103 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -3055,7 +3053,7 @@ StartChar: W Encoding: 87 87 85 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 110 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -3088,7 +3086,7 @@ StartChar: X Encoding: 88 88 86 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L,:Kn/++:)bps..=>UQd0V @@ -3126,7 +3124,7 @@ StartChar: Y Encoding: 89 89 87 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 110 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8C%,9r(&3hH^I @@ -3156,7 +3154,7 @@ StartChar: Z Encoding: 90 90 88 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8sb%RU9&*Yr8r @@ -3186,7 +3184,7 @@ StartChar: bracketleft Encoding: 91 91 89 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8sb%RU9&*Yt,T @@ -3211,7 +3209,7 @@ StartChar: backslash Encoding: 92 92 90 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 110 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns22,9nF> @@ -3234,7 +3232,7 @@ StartChar: bracketright Encoding: 93 93 91 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 100 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8sb%RU9&*Yr8r @@ -3259,7 +3257,7 @@ StartChar: asciicircum Encoding: 94 94 92 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 110 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns4f$5aWu @@ -3285,7 +3283,7 @@ StartChar: underscore Encoding: 95 95 93 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y @@ -3306,7 +3304,7 @@ StartChar: grave Encoding: 96 96 94 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 106 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8CJNffG9V\638 @@ -3329,7 +3327,7 @@ StartChar: a Encoding: 97 97 95 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 119 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -3369,7 +3367,7 @@ StartChar: b Encoding: 98 98 96 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9V\638 @@ -3406,7 +3404,7 @@ StartChar: c Encoding: 99 99 97 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 113 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns2*9E?@_ @@ -3437,7 +3435,7 @@ StartChar: d Encoding: 100 100 98 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 120 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8D_*$Z[Q1)J/( @@ -3474,7 +3472,7 @@ StartChar: e Encoding: 101 101 99 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 115 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3&!@&g6 @@ -3514,7 +3512,7 @@ StartChar: f Encoding: 102 102 100 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 122 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -3554,7 +3552,7 @@ StartChar: g Encoding: 103 103 101 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 123 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?L$N<'@d+:&'To`$RG-VQk$ @@ -3594,7 +3592,7 @@ StartChar: h Encoding: 104 104 102 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 110 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8CJNffG9V\638 @@ -3624,7 +3622,7 @@ StartChar: i Encoding: 105 105 103 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -3657,7 +3655,7 @@ StartChar: j Encoding: 106 106 104 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8D_*$Z[Q1)J/( @@ -3693,7 +3691,7 @@ StartChar: k Encoding: 107 107 105 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 116 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9V\638 @@ -3725,7 +3723,7 @@ StartChar: l Encoding: 108 108 106 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 108 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8CJNffG9N3T>a @@ -3752,7 +3750,7 @@ StartChar: m Encoding: 109 109 107 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns22,9nE8 @@ -3789,7 +3787,7 @@ StartChar: n Encoding: 110 110 108 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 110 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -3816,7 +3814,7 @@ StartChar: o Encoding: 111 111 109 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 119 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8Bu3Ns3&!@&g6 @@ -3850,7 +3848,7 @@ StartChar: p Encoding: 112 112 110 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 118 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -3882,7 +3880,7 @@ StartChar: q Encoding: 113 113 111 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -3918,7 +3916,7 @@ StartChar: r Encoding: 114 114 112 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 114 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3"!@&g6 @@ -3945,7 +3943,7 @@ StartChar: s Encoding: 115 115 113 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 122 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -3985,7 +3983,7 @@ StartChar: t Encoding: 116 116 114 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CNNffG9`^HN: @@ -4021,7 +4019,7 @@ StartChar: u Encoding: 117 117 115 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 113 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns3"!@&g6 @@ -4050,7 +4048,7 @@ StartChar: v Encoding: 118 118 116 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns22,9nFj @@ -4078,7 +4076,7 @@ StartChar: w Encoding: 119 119 117 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 108 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8Bu3Ns22,9nFj @@ -4120,7 +4118,7 @@ StartChar: x Encoding: 120 120 118 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 124 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$O22;+0EaaEs8UE72JImJ @@ -4150,7 +4148,7 @@ StartChar: y Encoding: 121 121 119 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 118 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns3"!@&g6 @@ -4186,7 +4184,7 @@ StartChar: z Encoding: 122 122 120 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 111 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8Bu3Ns2BOMigR @@ -4218,7 +4216,7 @@ StartChar: braceleft Encoding: 123 123 121 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -4257,7 +4255,7 @@ StartChar: bar Encoding: 124 124 122 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 96 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -4283,7 +4281,7 @@ StartChar: braceright Encoding: 125 125 123 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?L$c7oA#+:(<]kl,cY@:8B` @@ -4322,7 +4320,7 @@ StartChar: asciitilde Encoding: 126 126 124 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 105 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8Bu3Ns4^$5aWu @@ -4351,7 +4349,7 @@ StartChar: uni007F Encoding: 127 127 125 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 91 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2`"cP]X @@ -4372,7 +4370,7 @@ StartChar: uni0080 Encoding: 128 128 126 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 125 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$Na!+r&.AZ[o_qq3)XZ$a @@ -4418,7 +4416,7 @@ StartChar: uni0081 Encoding: 129 129 127 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 104 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9Xot.% @@ -4455,7 +4453,7 @@ StartChar: uni0082 Encoding: 130 130 128 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 121 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8D_*$Z[Q!sg+R @@ -4501,7 +4499,7 @@ StartChar: uni0083 Encoding: 131 131 129 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 123 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?L$NWBIe+:&',qYun_#oBn? @@ -4552,7 +4550,7 @@ StartChar: uni0084 Encoding: 132 132 130 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 121 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9X9;!; @@ -4603,7 +4601,7 @@ StartChar: uni0085 Encoding: 133 133 131 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 123 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?L$Nf+5E+:&'Ro`)[2:,ig- @@ -4651,7 +4649,7 @@ StartChar: uni0086 Encoding: 134 134 132 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 124 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$N_'QX+:J@3q#<"J$)@]t @@ -4705,7 +4703,7 @@ StartChar: uni0087 Encoding: 135 135 133 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 121 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+FNffG9`ah?c @@ -4743,7 +4741,7 @@ StartChar: uni0088 Encoding: 136 136 134 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 122 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?L4NWBIe+:&'Tq#r<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -6270,7 +6268,7 @@ StartChar: registered Encoding: 174 174 172 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 115 35 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3"!@&g6 @@ -6314,7 +6312,7 @@ StartChar: macron Encoding: 175 175 173 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 114 93 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns22,9nF< @@ -6358,7 +6356,7 @@ StartChar: degree Encoding: 176 176 174 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 107 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CJNffG9Xot.% @@ -6400,7 +6398,7 @@ StartChar: plusminus Encoding: 177 177 175 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 102 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8C%,9p;/SVHB; @@ -6501,7 +6499,7 @@ StartChar: uni00B2 Encoding: 178 178 176 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$N6qt4+:Ja @@ -6559,7 +6557,7 @@ StartChar: acute Encoding: 180 180 178 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 93 320 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,Y:Bi<#?K_r!ro=GQ8CJNffG9N3T>a @@ -6582,7 +6580,7 @@ StartChar: mu Encoding: 181 181 179 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 101 320 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8CJNffG9N3T>a @@ -6609,7 +6607,7 @@ StartChar: paragraph Encoding: 182 182 180 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 95 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -6637,7 +6635,7 @@ StartChar: periodcentered Encoding: 183 183 181 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y @@ -6658,7 +6656,7 @@ StartChar: cedilla Encoding: 184 184 182 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 104 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns2<'JKS? @@ -6683,7 +6681,7 @@ StartChar: uni00B9 Encoding: 185 185 183 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 105 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -6716,7 +6714,7 @@ StartChar: ordmasculine Encoding: 186 186 184 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 91 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -6742,7 +6740,7 @@ StartChar: guillemotright Encoding: 187 187 185 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 104 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns2<'JKS? @@ -6770,7 +6768,7 @@ StartChar: onequarter Encoding: 188 188 186 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 102 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -6800,7 +6798,7 @@ StartChar: onehalf Encoding: 189 189 187 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 99 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -6827,7 +6825,7 @@ StartChar: threequarters Encoding: 190 190 188 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 101 320 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8CJNffG9N3T>a @@ -6854,7 +6852,7 @@ StartChar: questiondown Encoding: 191 191 189 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y @@ -6875,7 +6873,7 @@ StartChar: Agrave Encoding: 192 192 190 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 92 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a @@ -6898,7 +6896,7 @@ StartChar: Aacute Encoding: 193 193 191 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8CJNffG9N3T>a @@ -6923,7 +6921,7 @@ StartChar: Acircumflex Encoding: 194 194 192 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y @@ -6944,7 +6942,7 @@ StartChar: Atilde Encoding: 195 195 193 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 92 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a @@ -6967,7 +6965,7 @@ StartChar: Adieresis Encoding: 196 196 194 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y @@ -6988,7 +6986,7 @@ StartChar: Aring Encoding: 197 197 195 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8CJNffG9N3T>a @@ -7013,7 +7011,7 @@ StartChar: AE Encoding: 198 198 196 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 104 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a @@ -7040,7 +7038,7 @@ StartChar: Ccedilla Encoding: 199 199 197 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 95 -192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -7068,7 +7066,7 @@ StartChar: Egrave Encoding: 200 200 198 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 100 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -7096,7 +7094,7 @@ StartChar: Eacute Encoding: 201 201 199 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 102 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8Bu3Ns2<'X3*= @@ -7124,7 +7122,7 @@ StartChar: Ecircumflex Encoding: 202 202 200 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 105 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -7157,7 +7155,7 @@ StartChar: Edieresis Encoding: 203 203 201 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 102 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8Bu3Ns2<'JKS? @@ -7188,7 +7186,7 @@ StartChar: Igrave Encoding: 204 204 202 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 99 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -7219,7 +7217,7 @@ StartChar: Iacute Encoding: 205 205 203 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 94 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns2<'JKS? @@ -7245,7 +7243,7 @@ StartChar: Icircumflex Encoding: 206 206 204 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 109 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -7283,7 +7281,7 @@ StartChar: Idieresis Encoding: 207 207 205 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 106 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8CJNffG9N3T>a @@ -7313,7 +7311,7 @@ StartChar: space Encoding: 32 32 206 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 79 2112 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(.gn[<#?K_r!ro=GQ8Bu3O%$&:]LJ7 @@ -7327,7 +7325,7 @@ StartChar: uni0000 Encoding: 0 0 207 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 81 704 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(eI+]<#?K_A7/g?&&^F.'2BFD`:-S' @@ -7341,7 +7339,7 @@ StartChar: Eth Encoding: 208 208 208 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 99 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -7368,7 +7366,7 @@ StartChar: Ntilde Encoding: 209 209 209 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 94 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns2<'JKS? @@ -7394,7 +7392,7 @@ StartChar: Ograve Encoding: 210 210 210 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y @@ -7416,7 +7414,7 @@ StartChar: Oacute Encoding: 211 211 211 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 95 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -7441,7 +7439,7 @@ StartChar: Ocircumflex Encoding: 212 212 212 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 104 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a @@ -7468,7 +7466,7 @@ StartChar: Otilde Encoding: 213 213 213 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 87 -448 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%!u-t$Rr @@ -7489,7 +7487,7 @@ StartChar: Odieresis Encoding: 214 214 214 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 84 -448 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr @@ -7510,7 +7508,7 @@ StartChar: multiply Encoding: 215 215 215 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 99 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 @@ -7537,7 +7535,7 @@ StartChar: Oslash Encoding: 216 216 216 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 101 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8Dg*$Z[QM@bLD @@ -7564,7 +7562,7 @@ StartChar: Ugrave Encoding: 217 217 217 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 93 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,Y:Bi<#?K_r!ro=GQ8Dg*$Z[QM@bLD @@ -7587,7 +7585,7 @@ StartChar: Uacute Encoding: 218 218 218 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 84 -448 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr @@ -7608,7 +7606,7 @@ StartChar: Ucircumflex Encoding: 219 219 219 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 86 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*D&Xb<#?K_r!ro=GQ8sb%RU9&*[X"< @@ -7629,7 +7627,7 @@ StartChar: Udieresis Encoding: 220 220 220 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 87 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y @@ -7650,7 +7648,7 @@ StartChar: Yacute Encoding: 221 221 221 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 86 320 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*D&Xb<#?K_r!ro=GQ8sb%^#f$=scA# @@ -7671,7 +7669,7 @@ StartChar: Thorn Encoding: 222 222 222 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 89 -192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W+A"se<#?K_r!ro=GQ8+FNffG9`ah?c @@ -7692,7 +7690,7 @@ StartChar: germandbls Encoding: 223 223 223 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 94 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8sb%RU9&*[X"< @@ -7713,7 +7711,7 @@ StartChar: agrave Encoding: 224 224 224 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?L,NA1nC0F._Qs8Q^H&iQI8 @@ -7757,7 +7755,7 @@ StartChar: aacute Encoding: 225 225 225 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 112 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8sb%^#f$=sf>C @@ -7803,7 +7801,7 @@ StartChar: acircumflex Encoding: 226 226 226 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 107 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8sb%RU9&*YsiL @@ -7828,7 +7826,7 @@ StartChar: atilde Encoding: 227 227 227 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 106 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8Bu3Ns2`"cP]X @@ -7857,7 +7855,7 @@ StartChar: adieresis Encoding: 228 228 228 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 125 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$NmS16+:&'JqYsnT:U#R> @@ -7892,7 +7890,7 @@ StartChar: aring Encoding: 229 229 229 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 124 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$N^4!P+:&*+r;W+a&N8(3 @@ -7931,7 +7929,7 @@ StartChar: ae Encoding: 230 230 230 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns3+"cSD! @@ -7964,7 +7962,7 @@ StartChar: ccedilla Encoding: 231 231 231 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 106 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8Bu3Ns2`"cP]X @@ -7989,7 +7987,7 @@ StartChar: egrave Encoding: 232 232 232 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 126 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W77fm5<#?L,N^4-T+:,lTiW!7c7P\42 @@ -8032,7 +8030,7 @@ StartChar: eacute Encoding: 233 233 233 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -8066,7 +8064,7 @@ StartChar: ecircumflex Encoding: 234 234 234 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 115 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns2*Lh(%, @@ -8107,7 +8105,7 @@ StartChar: edieresis Encoding: 235 235 235 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 112 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8CJNffG9N3T?l @@ -8150,7 +8148,7 @@ StartChar: igrave Encoding: 236 236 236 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 110 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns3"!@&g6 @@ -8199,7 +8197,7 @@ StartChar: iacute Encoding: 237 237 237 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 121 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$:'h7-+:*&es3Ke[NKS6' @@ -8244,7 +8242,7 @@ StartChar: icircumflex Encoding: 238 238 238 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 113 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8+BNffG9Xor#n @@ -8277,7 +8275,7 @@ StartChar: idieresis Encoding: 239 239 239 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8+BNffG9Xor#n @@ -8306,7 +8304,7 @@ StartChar: eth Encoding: 240 240 240 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 91 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2BOMigR @@ -8337,7 +8335,7 @@ StartChar: ntilde Encoding: 241 241 241 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 114 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -8371,7 +8369,7 @@ StartChar: ograve Encoding: 242 242 242 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 113 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8C%,9n7D"pQE9 @@ -8399,7 +8397,7 @@ StartChar: oacute Encoding: 243 243 243 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 116 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?L$:.Z&u+:&>Ss5s_"%Pf=X @@ -8427,7 +8425,7 @@ StartChar: ocircumflex Encoding: 244 244 244 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 106 -192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8D_*$Z[Q1)J/h @@ -8456,7 +8454,7 @@ StartChar: otilde Encoding: 245 245 245 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 103 320 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8CNNffG9`^HNZ @@ -8485,7 +8483,7 @@ StartChar: odieresis Encoding: 246 246 246 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 104 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns3&!@&g6 @@ -8516,7 +8514,7 @@ StartChar: divide Encoding: 247 247 247 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 100 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8Dg*$Z[QM@^/O @@ -8558,7 +8556,7 @@ StartChar: oslash Encoding: 248 248 248 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 115 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8CJNffG9N3T?l @@ -8592,7 +8590,7 @@ StartChar: ugrave Encoding: 249 249 249 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 116 -64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8Bu3Ns4f$5aWu @@ -8621,7 +8619,7 @@ StartChar: uacute Encoding: 250 250 250 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 97 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns24'ehBu @@ -8642,7 +8640,7 @@ StartChar: ucircumflex Encoding: 251 251 251 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 117 64 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+FNffG9`ah?c @@ -8673,7 +8671,7 @@ StartChar: udieresis Encoding: 252 252 252 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 111 192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8Bu3Ns2`"cP]X @@ -8700,7 +8698,7 @@ StartChar: yacute Encoding: 253 253 253 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 110 448 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?L$N'RdN0FYgqo`&:TWj&8\ @@ -8729,7 +8727,7 @@ StartChar: thorn Encoding: 254 254 254 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 103 -192 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8Bu3Ns2`"Y;>@ @@ -8750,7 +8748,7 @@ StartChar: ydieresis Encoding: 255 255 255 Width: 1408 Flags: MW -LayerCount: 3 +LayerCount: 2 Back Image2: image/png 79 1472 2048 256 256 M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(.gn[<#?K_r!ro=GQ8Bu3O%$&:]LJ7 From 80bfb88a4de3ce2d651aeb1f397c64e1e3d94c7e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 31 Dec 2022 08:44:18 +0100 Subject: [PATCH 240/314] Fixed dependencies --- build.gradle | 3 ++- plugins/compiler/as-8080/build.gradle | 4 ++-- plugins/compiler/as-ssem/build.gradle | 4 ++-- plugins/compiler/as-z80/build.gradle | 4 ++-- plugins/compiler/brainc-brainduck/build.gradle | 4 ++-- plugins/compiler/ramc-ram/build.gradle | 5 +++-- plugins/compiler/raspc-rasp/build.gradle | 5 +++-- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 214bc3be2..1a1acdc16 100644 --- a/build.gradle +++ b/build.gradle @@ -30,6 +30,7 @@ ext.libs = [ cpuTestSuite : "net.emustudio:cpu-testsuite_11.6:1.2.0-SNAPSHOT", jcipAnnotations : "net.jcip:jcip-annotations:1.0", + antlr : "org.antlr:antlr4:4.11.1", antlrRuntime : "org.antlr:antlr4-runtime:4.11.1", slf4JApi : "org.slf4j:slf4j-api:${versions.slf4j}", @@ -45,7 +46,7 @@ ext.libs = [ editor : "com.fifesoft:rsyntaxtextarea:3.3.1", editorDialogs : "com.fifesoft:rstaui:3.3.0", - junit : "junit:junit:4.13", + junit : "junit:junit:4.13.1", easyMock : "org.easymock:easymock:4.2", mockito : "org.mockito:mockito-all:1.10.19" ] diff --git a/plugins/compiler/as-8080/build.gradle b/plugins/compiler/as-8080/build.gradle index 7c6dbeb91..f6b9621ed 100644 --- a/plugins/compiler/as-8080/build.gradle +++ b/plugins/compiler/as-8080/build.gradle @@ -27,8 +27,8 @@ plugins { } dependencies { - antlr "org.antlr:antlr4:4.9.2" - implementation "org.antlr:antlr4-runtime:4.9.2" + antlr libs.antlr + implementation libs.antlrRuntime implementation libs.emuLib implementation libs.slf4JApi diff --git a/plugins/compiler/as-ssem/build.gradle b/plugins/compiler/as-ssem/build.gradle index 9ec606245..5b4dcd424 100644 --- a/plugins/compiler/as-ssem/build.gradle +++ b/plugins/compiler/as-ssem/build.gradle @@ -27,8 +27,8 @@ plugins { } dependencies { - antlr "org.antlr:antlr4:4.9.2" - implementation "org.antlr:antlr4-runtime:4.9.2" + antlr libs.antlr + implementation libs.antlrRuntime implementation libs.emuLib implementation libs.slf4JApi diff --git a/plugins/compiler/as-z80/build.gradle b/plugins/compiler/as-z80/build.gradle index 17a059b2d..9f9c300d1 100644 --- a/plugins/compiler/as-z80/build.gradle +++ b/plugins/compiler/as-z80/build.gradle @@ -27,8 +27,8 @@ plugins { } dependencies { - antlr "org.antlr:antlr4:4.9.2" - implementation "org.antlr:antlr4-runtime:4.9.2" + antlr libs.antlr + implementation libs.antlrRuntime implementation libs.emuLib implementation libs.slf4JApi diff --git a/plugins/compiler/brainc-brainduck/build.gradle b/plugins/compiler/brainc-brainduck/build.gradle index de230ba57..7a69d93d6 100644 --- a/plugins/compiler/brainc-brainduck/build.gradle +++ b/plugins/compiler/brainc-brainduck/build.gradle @@ -27,8 +27,8 @@ plugins { } dependencies { - antlr "org.antlr:antlr4:4.9.2" - implementation "org.antlr:antlr4-runtime:4.9.2" + antlr libs.antlr + implementation libs.antlrRuntime implementation libs.emuLib implementation libs.slf4JApi diff --git a/plugins/compiler/ramc-ram/build.gradle b/plugins/compiler/ramc-ram/build.gradle index 1b181946a..8cab44725 100644 --- a/plugins/compiler/ramc-ram/build.gradle +++ b/plugins/compiler/ramc-ram/build.gradle @@ -27,8 +27,9 @@ plugins { } dependencies { - antlr "org.antlr:antlr4:4.9.2" - implementation "org.antlr:antlr4-runtime:4.9.2" + antlr libs.antlr + implementation libs.antlrRuntime + implementation libs.emuLib implementation project.rootProject.project(":plugins:memory:ram-mem") implementation libs.slf4JApi diff --git a/plugins/compiler/raspc-rasp/build.gradle b/plugins/compiler/raspc-rasp/build.gradle index ebd6a8455..4e6ef81ec 100644 --- a/plugins/compiler/raspc-rasp/build.gradle +++ b/plugins/compiler/raspc-rasp/build.gradle @@ -27,8 +27,9 @@ plugins { } dependencies { - antlr "org.antlr:antlr4:4.9.2" - implementation "org.antlr:antlr4-runtime:4.9.2" + antlr libs.antlr + implementation libs.antlrRuntime + implementation libs.emuLib implementation project.rootProject.project(":plugins:memory:rasp-mem") implementation libs.slf4JApi From 2e356e35b5db2db68fb55d85dc113ee9afbb1701 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 31 Dec 2022 08:53:53 +0100 Subject: [PATCH 241/314] Copyright years to 2023 --- application/build.gradle | 2 +- application/src/main/files/logback.xml | 2 +- .../application/ApplicationApiImpl.java | 2 +- .../net/emustudio/application/Constants.java | 2 +- .../net/emustudio/application/Resources.java | 2 +- .../cmdline/AutomationCommand.java | 2 +- .../emustudio/application/cmdline/Runner.java | 2 +- .../emustudio/application/cmdline/Utils.java | 2 +- .../application/emulation/Automation.java | 2 +- .../emulation/AutomationException.java | 2 +- .../emulation/EmulationController.java | 2 +- .../application/gui/ConstantSizeButton.java | 2 +- .../application/gui/ExtendedDialogs.java | 2 +- .../application/gui/GuiDialogsImpl.java | 2 +- .../emustudio/application/gui/GuiUtils.java | 2 +- .../application/gui/NoGuiDialogsImpl.java | 2 +- .../java/net/emustudio/application/gui/P.java | 2 +- .../application/gui/ToolbarButton.java | 2 +- .../application/gui/ToolbarToggleButton.java | 2 +- .../application/gui/actions/AboutAction.java | 2 +- .../gui/actions/CompileAction.java | 2 +- .../gui/actions/CompilerSettingsAction.java | 2 +- .../application/gui/actions/ExitAction.java | 2 +- .../gui/actions/ViewComputerAction.java | 2 +- .../gui/actions/editor/FindAction.java | 2 +- .../gui/actions/editor/FindNextAction.java | 2 +- .../actions/editor/FindPreviousAction.java | 2 +- .../gui/actions/editor/NewFileAction.java | 2 +- .../gui/actions/editor/OpenFileAction.java | 2 +- .../gui/actions/editor/ReplaceAction.java | 2 +- .../gui/actions/editor/SaveFileAction.java | 2 +- .../gui/actions/editor/SaveFileAsAction.java | 2 +- .../actions/emulator/BreakpointAction.java | 2 +- .../gui/actions/emulator/JumpAction.java | 2 +- .../emulator/JumpToBeginningAction.java | 2 +- .../gui/actions/emulator/PauseAction.java | 2 +- .../gui/actions/emulator/ResetAction.java | 2 +- .../gui/actions/emulator/RunAction.java | 2 +- .../gui/actions/emulator/RunTimedAction.java | 2 +- .../actions/emulator/ShowDeviceGuiAction.java | 2 +- .../emulator/ShowDeviceSettingsAction.java | 2 +- .../actions/emulator/ShowMemoryAction.java | 2 +- .../gui/actions/emulator/StepAction.java | 2 +- .../gui/actions/emulator/StepBackAction.java | 2 +- .../gui/actions/emulator/StopAction.java | 2 +- .../opencomputer/AddNewComputerAction.java | 2 +- .../opencomputer/DeleteComputerAction.java | 2 +- .../opencomputer/EditComputerAction.java | 2 +- .../opencomputer/OpenComputerAction.java | 2 +- .../opencomputer/RenameComputerAction.java | 2 +- .../opencomputer/SaveSchemaAction.java | 2 +- .../gui/debugtable/BooleanCellEditor.java | 2 +- .../gui/debugtable/BooleanCellRenderer.java | 2 +- .../gui/debugtable/BooleanComponent.java | 2 +- .../application/gui/debugtable/CallFlow.java | 2 +- .../gui/debugtable/DebugTableImpl.java | 2 +- .../gui/debugtable/DebugTableModel.java | 2 +- .../gui/debugtable/DebugTableModelImpl.java | 2 +- .../gui/debugtable/PagesPanel.java | 2 +- .../debugtable/PaginatingDisassembler.java | 2 +- .../gui/debugtable/TextCellRenderer.java | 2 +- .../application/gui/dialogs/AboutDialog.java | 2 +- .../application/gui/dialogs/AutoDialog.java | 2 +- .../gui/dialogs/BreakpointDialog.java | 2 +- .../application/gui/dialogs/EditorPanel.java | 2 +- .../gui/dialogs/EmulatorPanel.java | 2 +- .../gui/dialogs/LoadingDialog.java | 2 +- .../gui/dialogs/OpenComputerDialog.java | 2 +- .../gui/dialogs/PluginComboModel.java | 2 +- .../gui/dialogs/SchemaEditorDialog.java | 2 +- .../application/gui/dialogs/StudioFrame.java | 2 +- .../gui/dialogs/ViewComputerDialog.java | 2 +- .../application/gui/editor/Editor.java | 2 +- .../application/gui/editor/REditor.java | 2 +- .../application/gui/editor/RTokenMaker.java | 2 +- .../gui/editor/RTokenMakerWrapper.java | 2 +- .../application/gui/schema/DrawingModel.java | 2 +- .../application/gui/schema/DrawingPanel.java | 2 +- .../application/gui/schema/Schema.java | 2 +- .../gui/schema/SchemaPreviewPanel.java | 2 +- .../gui/schema/elements/CompilerElement.java | 2 +- .../gui/schema/elements/ConnectionLine.java | 2 +- .../gui/schema/elements/CpuElement.java | 2 +- .../gui/schema/elements/DeviceElement.java | 2 +- .../gui/schema/elements/Element.java | 2 +- .../gui/schema/elements/MemoryElement.java | 2 +- .../gui/schema/mode/AbstractMode.java | 2 +- .../application/gui/schema/mode/Mode.java | 2 +- .../gui/schema/mode/ModeSelector.java | 2 +- .../gui/schema/mode/ModelingMode.java | 2 +- .../gui/schema/mode/MovingMode.java | 2 +- .../gui/schema/mode/ResizingMode.java | 2 +- .../gui/schema/mode/SelectingMode.java | 2 +- .../application/internal/Hashing.java | 2 +- .../application/internal/Reflection.java | 2 +- .../application/internal/Unchecked.java | 2 +- .../application/settings/AppSettings.java | 2 +- .../settings/BasicSettingsImpl.java | 18 ++++++++++++++++++ .../application/settings/ComputerConfig.java | 2 +- .../application/settings/ConfigFiles.java | 2 +- .../application/settings/PluginConfig.java | 2 +- .../settings/PluginConnection.java | 2 +- .../settings/PluginSettingsImpl.java | 2 +- .../application/settings/SchemaPoint.java | 2 +- .../virtualcomputer/ContextPoolImpl.java | 2 +- .../InvalidPluginException.java | 2 +- .../virtualcomputer/PluginConnections.java | 2 +- .../virtualcomputer/PluginLoader.java | 2 +- .../PluginLoadingException.java | 2 +- .../virtualcomputer/VirtualComputer.java | 2 +- .../emustudio/application/version.properties | 2 +- .../emulation/EmulationControllerTest.java | 2 +- .../gui/debugtable/CallFlowTest.java | 2 +- .../gui/debugtable/DisassemblerStub.java | 2 +- .../gui/debugtable/MockHelper.java | 2 +- .../PaginatingDisassemblerTest.java | 2 +- .../gui/dialogs/PluginComboModelTest.java | 2 +- .../application/settings/AppSettingsTest.java | 2 +- .../settings/ComputerConfigTest.java | 2 +- .../application/settings/ConfigFilesTest.java | 2 +- .../settings/PluginConfigTest.java | 2 +- .../application/settings/SchemaPointTest.java | 2 +- .../virtualcomputer/ContextPoolImplTest.java | 2 +- .../virtualcomputer/ContextStubs.java | 2 +- .../virtualcomputer/JarCreator.java | 2 +- .../virtualcomputer/PluginLoaderTest.java | 2 +- .../virtualcomputer/VirtualComputerTest.java | 2 +- .../stubs/AbstractCPUStub.java | 2 +- .../virtualcomputer/stubs/CPUContextStub.java | 2 +- .../virtualcomputer/stubs/CPUImplStub.java | 2 +- .../stubs/CPUListenerStub.java | 2 +- .../stubs/CompilerContextStub.java | 2 +- .../stubs/DeviceContextStub.java | 2 +- .../stubs/ShortMemoryContextStub.java | 2 +- .../stubs/UnannotatedCPUStub.java | 2 +- .../stubs/UnannotatedContextStub.java | 2 +- build.gradle | 2 +- plugins/compiler/as-8080/build.gradle | 2 +- .../as-8080/src/main/antlr/As8080Lexer.g4 | 2 +- .../as-8080/src/main/antlr/As8080Parser.g4 | 2 +- .../compiler/as8080/Assembler8080.java | 2 +- .../plugins/compiler/as8080/CompileError.java | 2 +- .../compiler/as8080/LexicalAnalyzerImpl.java | 2 +- .../compiler/as8080/ParserErrorListener.java | 2 +- .../plugins/compiler/as8080/ParsingUtils.java | 2 +- .../plugins/compiler/as8080/Runner.java | 2 +- .../compiler/as8080/ast/Evaluated.java | 2 +- .../compiler/as8080/ast/NameSpace.java | 2 +- .../plugins/compiler/as8080/ast/Node.java | 2 +- .../plugins/compiler/as8080/ast/Program.java | 2 +- .../compiler/as8080/ast/data/DataDB.java | 2 +- .../compiler/as8080/ast/data/DataDS.java | 2 +- .../compiler/as8080/ast/data/DataDW.java | 2 +- .../as8080/ast/expr/ExprCurrentAddress.java | 2 +- .../compiler/as8080/ast/expr/ExprId.java | 2 +- .../compiler/as8080/ast/expr/ExprInfix.java | 2 +- .../compiler/as8080/ast/expr/ExprNumber.java | 2 +- .../compiler/as8080/ast/expr/ExprString.java | 2 +- .../compiler/as8080/ast/expr/ExprUnary.java | 2 +- .../compiler/as8080/ast/instr/InstrExpr.java | 2 +- .../as8080/ast/instr/InstrNoArgs.java | 2 +- .../compiler/as8080/ast/instr/InstrReg.java | 2 +- .../as8080/ast/instr/InstrRegExpr.java | 2 +- .../as8080/ast/instr/InstrRegPair.java | 2 +- .../as8080/ast/instr/InstrRegPairExpr.java | 2 +- .../as8080/ast/instr/InstrRegReg.java | 2 +- .../compiler/as8080/ast/pseudo/PseudoEqu.java | 2 +- .../compiler/as8080/ast/pseudo/PseudoIf.java | 2 +- .../as8080/ast/pseudo/PseudoIfExpression.java | 2 +- .../as8080/ast/pseudo/PseudoInclude.java | 2 +- .../as8080/ast/pseudo/PseudoLabel.java | 2 +- .../ast/pseudo/PseudoMacroArgument.java | 2 +- .../as8080/ast/pseudo/PseudoMacroCall.java | 2 +- .../as8080/ast/pseudo/PseudoMacroDef.java | 2 +- .../ast/pseudo/PseudoMacroParameter.java | 2 +- .../compiler/as8080/ast/pseudo/PseudoOrg.java | 2 +- .../compiler/as8080/ast/pseudo/PseudoSet.java | 2 +- .../as8080/exceptions/CompileException.java | 2 +- .../as8080/exceptions/FatalError.java | 2 +- .../exceptions/SyntaxErrorException.java | 2 +- .../visitors/CheckDeclarationsVisitor.java | 2 +- .../visitors/CheckExprSizesVisitor.java | 2 +- .../as8080/visitors/CreateDataVisitor.java | 2 +- .../as8080/visitors/CreateExprVisitor.java | 2 +- .../as8080/visitors/CreateInstrVisitor.java | 2 +- .../as8080/visitors/CreateLineVisitor.java | 2 +- .../as8080/visitors/CreateProgramVisitor.java | 2 +- .../as8080/visitors/CreatePseudoVisitor.java | 2 +- .../as8080/visitors/CreateVisitors.java | 2 +- .../as8080/visitors/EvaluateExprVisitor.java | 2 +- .../visitors/ExpandIncludesVisitor.java | 2 +- .../as8080/visitors/ExpandMacrosVisitor.java | 2 +- .../as8080/visitors/GenerateCodeVisitor.java | 2 +- .../compiler/as8080/visitors/NodeVisitor.java | 2 +- .../visitors/SortMacroArgumentsVisitor.java | 2 +- .../compiler/as8080/version.properties | 2 +- .../as8080/LexicalAnalyzerImplTest.java | 18 ++++++++++++++++++ .../plugins/compiler/as8080/RunnerTest.java | 2 +- .../plugins/compiler/as8080/Utils.java | 2 +- .../as8080/e2e/AbstractCompilerTest.java | 2 +- .../as8080/e2e/Assembler8080Test.java | 2 +- .../as8080/e2e/ConstantsAndVariablesTest.java | 2 +- .../plugins/compiler/as8080/e2e/DataTest.java | 2 +- .../compiler/as8080/e2e/IfNodeTest.java | 2 +- .../compiler/as8080/e2e/IncludeTest.java | 2 +- .../compiler/as8080/e2e/InstrExprTest.java | 18 ++++++++++++++++++ .../compiler/as8080/e2e/InstrRegTest.java | 2 +- .../compiler/as8080/e2e/MacroTest.java | 2 +- .../compiler/as8080/e2e/PseudoOrgTest.java | 2 +- .../parser/LexicalAnalyzerImplTest.java | 2 +- .../compiler/as8080/parser/ParseDataTest.java | 2 +- .../compiler/as8080/parser/ParseExprTest.java | 2 +- .../as8080/parser/ParseInstrTest.java | 2 +- .../as8080/parser/ParsePseudoTest.java | 2 +- .../as8080/parser/ParsingUtilsTest.java | 2 +- .../CheckDeclarationsVisitorTest.java | 2 +- .../visitors/CheckExprSizesVisitorTest.java | 2 +- .../visitors/EvaluateExprVisitorTest.java | 2 +- .../visitors/ExpandIncludesVisitorTest.java | 2 +- .../as8080/visitors/ExpandMacrosTest.java | 2 +- .../visitors/GenerateCodeVisitorTest.java | 2 +- .../SortMacroArgumentsVisitorTest.java | 2 +- plugins/compiler/as-ssem/build.gradle | 2 +- .../as-ssem/src/main/antlr/SSEMLexer.g4 | 2 +- .../as-ssem/src/main/antlr/SSEMParser.g4 | 2 +- .../plugins/compiler/ssem/CodeGenerator.java | 2 +- .../compiler/ssem/CompileException.java | 2 +- .../plugins/compiler/ssem/CompilerChecks.java | 2 +- .../compiler/ssem/LexicalAnalyzerImpl.java | 2 +- .../compiler/ssem/ParserErrorListener.java | 2 +- .../plugins/compiler/ssem/Position.java | 2 +- .../plugins/compiler/ssem/Runner.java | 2 +- .../plugins/compiler/ssem/SSEMCompiler.java | 2 +- .../compiler/ssem/ast/Instruction.java | 2 +- .../plugins/compiler/ssem/ast/Program.java | 2 +- .../compiler/ssem/ast/ProgramParser.java | 2 +- .../plugins/compiler/ssem/version.properties | 2 +- .../plugins/compiler/ssem/LexerTest.java | 2 +- .../ssem/LexicalAnalyzerImplTest.java | 18 ++++++++++++++++++ .../plugins/compiler/ssem/ParserTest.java | 2 +- .../plugins/compiler/ssem/RunnerTest.java | 2 +- .../compiler/ssem/SSEMCompilerTest.java | 2 +- .../plugins/compiler/ssem/Utils.java | 2 +- plugins/compiler/as-z80/build.gradle | 2 +- .../as-z80/src/main/antlr/AsZ80Lexer.g4 | 2 +- .../as-z80/src/main/antlr/AsZ80Parser.g4 | 2 +- .../plugins/compiler/asZ80/AssemblerZ80.java | 2 +- .../plugins/compiler/asZ80/CompileError.java | 2 +- .../compiler/asZ80/CompilerTables.java | 2 +- .../compiler/asZ80/LexicalAnalyzerImpl.java | 2 +- .../plugins/compiler/asZ80/Pair.java | 2 +- .../compiler/asZ80/ParserErrorListener.java | 2 +- .../plugins/compiler/asZ80/ParsingUtils.java | 2 +- .../plugins/compiler/asZ80/Runner.java | 2 +- .../plugins/compiler/asZ80/ast/Evaluated.java | 2 +- .../plugins/compiler/asZ80/ast/NameSpace.java | 2 +- .../plugins/compiler/asZ80/ast/Node.java | 2 +- .../plugins/compiler/asZ80/ast/Program.java | 2 +- .../compiler/asZ80/ast/data/DataDB.java | 2 +- .../compiler/asZ80/ast/data/DataDS.java | 2 +- .../compiler/asZ80/ast/data/DataDW.java | 2 +- .../asZ80/ast/expr/ExprCurrentAddress.java | 2 +- .../compiler/asZ80/ast/expr/ExprId.java | 2 +- .../compiler/asZ80/ast/expr/ExprInfix.java | 2 +- .../compiler/asZ80/ast/expr/ExprNumber.java | 2 +- .../compiler/asZ80/ast/expr/ExprString.java | 2 +- .../compiler/asZ80/ast/expr/ExprUnary.java | 2 +- .../compiler/asZ80/ast/instr/Instr.java | 2 +- .../compiler/asZ80/ast/instr/InstrCB.java | 2 +- .../compiler/asZ80/ast/instr/InstrED.java | 2 +- .../compiler/asZ80/ast/instr/InstrXD.java | 2 +- .../compiler/asZ80/ast/instr/InstrXDCB.java | 2 +- .../compiler/asZ80/ast/pseudo/PseudoEqu.java | 2 +- .../compiler/asZ80/ast/pseudo/PseudoIf.java | 2 +- .../asZ80/ast/pseudo/PseudoIfExpression.java | 2 +- .../asZ80/ast/pseudo/PseudoInclude.java | 2 +- .../asZ80/ast/pseudo/PseudoLabel.java | 2 +- .../asZ80/ast/pseudo/PseudoMacroArgument.java | 2 +- .../asZ80/ast/pseudo/PseudoMacroCall.java | 2 +- .../asZ80/ast/pseudo/PseudoMacroDef.java | 2 +- .../ast/pseudo/PseudoMacroParameter.java | 2 +- .../compiler/asZ80/ast/pseudo/PseudoOrg.java | 2 +- .../compiler/asZ80/ast/pseudo/PseudoVar.java | 2 +- .../asZ80/exceptions/CompileException.java | 2 +- .../compiler/asZ80/exceptions/FatalError.java | 2 +- .../exceptions/SyntaxErrorException.java | 2 +- .../visitors/CheckDeclarationsVisitor.java | 2 +- .../asZ80/visitors/CheckExprSizesVisitor.java | 2 +- .../visitors/CollectExprsInOpcodeVisitor.java | 2 +- .../asZ80/visitors/CreateDataVisitor.java | 2 +- .../asZ80/visitors/CreateExprVisitor.java | 2 +- .../asZ80/visitors/CreateInstrVisitor.java | 2 +- .../asZ80/visitors/CreateLineVisitor.java | 2 +- .../asZ80/visitors/CreateProgramVisitor.java | 2 +- .../asZ80/visitors/CreatePseudoVisitor.java | 2 +- .../asZ80/visitors/CreateVisitors.java | 2 +- .../asZ80/visitors/EvaluateExprVisitor.java | 2 +- .../asZ80/visitors/ExpandIncludesVisitor.java | 2 +- .../asZ80/visitors/ExpandMacrosVisitor.java | 2 +- .../asZ80/visitors/GenerateCodeVisitor.java | 2 +- .../compiler/asZ80/visitors/NodeVisitor.java | 2 +- .../visitors/SortMacroArgumentsVisitor.java | 2 +- .../plugins/compiler/asZ80/version.properties | 2 +- .../asZ80/LexicalAnalyzerImplTest.java | 18 ++++++++++++++++++ .../plugins/compiler/asZ80/RunnerTest.java | 2 +- .../plugins/compiler/asZ80/Utils.java | 2 +- .../asZ80/e2e/AbstractCompilerTest.java | 2 +- .../compiler/asZ80/e2e/AssemblerZ80Test.java | 2 +- .../asZ80/e2e/ConstantsAndVariablesTest.java | 2 +- .../plugins/compiler/asZ80/e2e/DataTest.java | 2 +- .../compiler/asZ80/e2e/IfNodeTest.java | 2 +- .../compiler/asZ80/e2e/IncludeTest.java | 2 +- .../compiler/asZ80/e2e/InstrExprTest.java | 18 ++++++++++++++++++ .../compiler/asZ80/e2e/InstrRegTest.java | 2 +- .../plugins/compiler/asZ80/e2e/MacroTest.java | 2 +- .../compiler/asZ80/e2e/PseudoOrgTest.java | 2 +- .../asZ80/parser/LexicalAnalyzerImplTest.java | 2 +- .../compiler/asZ80/parser/ParseDataTest.java | 2 +- .../compiler/asZ80/parser/ParseExprTest.java | 2 +- .../compiler/asZ80/parser/ParseInstrTest.java | 2 +- .../asZ80/parser/ParsePseudoTest.java | 2 +- .../asZ80/parser/ParsingUtilsTest.java | 2 +- .../CheckDeclarationsVisitorTest.java | 2 +- .../visitors/CheckExprSizesVisitorTest.java | 2 +- .../visitors/EvaluateExprVisitorTest.java | 2 +- .../visitors/ExpandIncludesVisitorTest.java | 2 +- .../asZ80/visitors/ExpandMacrosTest.java | 2 +- .../visitors/GenerateCodeVisitorTest.java | 2 +- .../SortMacroArgumentsVisitorTest.java | 2 +- .../compiler/brainc-brainduck/build.gradle | 2 +- .../src/main/antlr/BraincLexer.g4 | 2 +- .../src/main/antlr/BraincParser.g4 | 2 +- .../compiler/brainduck/CompileException.java | 2 +- .../compiler/brainduck/CompilerImpl.java | 2 +- .../brainduck/LexicalAnalyzerImpl.java | 2 +- .../brainduck/ParserErrorListener.java | 2 +- .../plugins/compiler/brainduck/Runner.java | 2 +- .../compiler/brainduck/ast/Instruction.java | 2 +- .../compiler/brainduck/ast/Program.java | 2 +- .../compiler/brainduck/ast/ProgramParser.java | 2 +- .../compiler/brainduck/version.properties | 2 +- .../brainduck/AbstractCompilerTest.java | 2 +- .../compiler/brainduck/InstructionTest.java | 2 +- .../brainduck/LexicalAnalyzerImplTest.java | 18 ++++++++++++++++++ .../compiler/brainduck/RunnerTest.java | 2 +- plugins/compiler/ramc-ram/build.gradle | 2 +- .../ramc-ram/src/main/antlr/RAMLexer.g4 | 2 +- .../ramc-ram/src/main/antlr/RAMParser.g4 | 2 +- .../plugins/compiler/ram/CompilerRAM.java | 2 +- .../compiler/ram/LexicalAnalyzerImpl.java | 2 +- .../compiler/ram/ParserErrorListener.java | 2 +- .../plugins/compiler/ram/ParsingUtils.java | 2 +- .../plugins/compiler/ram/ProgramParser.java | 2 +- .../plugins/compiler/ram/Runner.java | 2 +- .../compiler/ram/SerializableOptional.java | 2 +- .../plugins/compiler/ram/ast/Instruction.java | 2 +- .../plugins/compiler/ram/ast/Label.java | 2 +- .../plugins/compiler/ram/ast/Program.java | 2 +- .../plugins/compiler/ram/ast/Value.java | 2 +- .../ram/exceptions/CompileException.java | 2 +- .../ram/exceptions/SyntaxErrorException.java | 2 +- .../plugins/compiler/ram/version.properties | 2 +- .../compiler/ram/AbstractCompilerTest.java | 2 +- .../plugins/compiler/ram/CompilerTest.java | 2 +- .../compiler/ram/LexicalAnalyzerImplTest.java | 18 ++++++++++++++++++ .../plugins/compiler/ram/MemoryStub.java | 2 +- .../plugins/compiler/ram/RunnerTest.java | 2 +- plugins/compiler/raspc-rasp/build.gradle | 2 +- .../raspc-rasp/src/main/antlr/RASPLexer.g4 | 2 +- .../raspc-rasp/src/main/antlr/RASPParser.g4 | 2 +- .../plugins/compiler/rasp/CompilerRASP.java | 2 +- .../compiler/rasp/LexicalAnalyzerImpl.java | 2 +- .../compiler/rasp/ParserErrorListener.java | 2 +- .../plugins/compiler/rasp/ParsingUtils.java | 2 +- .../plugins/compiler/rasp/ProgramParser.java | 2 +- .../plugins/compiler/rasp/Runner.java | 2 +- .../compiler/rasp/ast/Instruction.java | 2 +- .../plugins/compiler/rasp/ast/Label.java | 2 +- .../plugins/compiler/rasp/ast/Program.java | 2 +- .../rasp/exceptions/CompileException.java | 2 +- .../rasp/exceptions/SyntaxErrorException.java | 2 +- .../plugins/compiler/rasp/version.properties | 2 +- .../compiler/rasp/AbstractCompilerTest.java | 2 +- .../plugins/compiler/rasp/CompilerTest.java | 2 +- .../rasp/LexicalAnalyzerImplTest.java | 18 ++++++++++++++++++ .../plugins/compiler/rasp/MemoryStub.java | 2 +- plugins/cpu/8080-cpu/build.gradle | 2 +- plugins/cpu/8080-cpu/src/main/edigen/cpu.eds | 2 +- .../plugins/cpu/intel8080/Breakpoint.java | 2 +- .../cpu/intel8080/Context8080Impl.java | 2 +- .../plugins/cpu/intel8080/CpuImpl.java | 2 +- .../plugins/cpu/intel8080/DispatchTables.java | 2 +- .../plugins/cpu/intel8080/EmulatorEngine.java | 2 +- .../plugins/cpu/intel8080/EmulatorTables.java | 2 +- .../cpu/intel8080/InitializerFor8080.java | 2 +- .../cpu/intel8080/InstructionPrinter.java | 2 +- .../cpu/intel8080/api/Context8080.java | 2 +- .../plugins/cpu/intel8080/api/CpuEngine.java | 2 +- .../cpu/intel8080/api/DefaultInitializer.java | 2 +- .../cpu/intel8080/api/DispatchListener.java | 2 +- .../api/FrequencyChangedListener.java | 2 +- .../cpu/intel8080/api/FrequencyUpdater.java | 2 +- .../plugins/cpu/intel8080/gui/FlagsModel.java | 2 +- .../cpu/intel8080/gui/StatusPanel.java | 2 +- .../plugins/cpu/intel8080/version.properties | 2 +- .../plugins/cpu/intel8080/ArithmeticTest.java | 2 +- .../plugins/cpu/intel8080/ControlTest.java | 2 +- .../plugins/cpu/intel8080/CpuImplTest.java | 2 +- .../cpu/intel8080/InstructionsTest.java | 2 +- .../plugins/cpu/intel8080/LogicTest.java | 2 +- .../plugins/cpu/intel8080/StackTest.java | 2 +- .../plugins/cpu/intel8080/TransferTest.java | 2 +- .../intel8080/api/FrequencyUpdaterTest.java | 2 +- .../cpu/intel8080/suite/ByteTestBuilder.java | 2 +- .../cpu/intel8080/suite/CpuRunnerImpl.java | 2 +- .../cpu/intel8080/suite/CpuVerifierImpl.java | 2 +- .../cpu/intel8080/suite/FlagsCheckImpl.java | 2 +- .../intel8080/suite/IntegerTestBuilder.java | 2 +- .../intel8080/suite/injectors/Register.java | 2 +- .../suite/injectors/RegisterPair.java | 2 +- .../suite/injectors/RegisterPairPSW.java | 2 +- plugins/cpu/brainduck-cpu/build.gradle | 2 +- .../cpu/brainduck-cpu/src/main/edigen/cpu.eds | 2 +- .../cpu/brainduck/BrainCPUContext.java | 2 +- .../cpu/brainduck/BrainCPUContextImpl.java | 2 +- .../plugins/cpu/brainduck/Breakpoint.java | 2 +- .../plugins/cpu/brainduck/CpuImpl.java | 2 +- .../plugins/cpu/brainduck/EmulatorEngine.java | 2 +- .../plugins/cpu/brainduck/Profiler.java | 2 +- .../cpu/brainduck/gui/ColumnsRepainter.java | 2 +- .../plugins/cpu/brainduck/gui/Constants.java | 2 +- .../cpu/brainduck/gui/MemoryTableModel.java | 2 +- .../cpu/brainduck/gui/StatusPanel.java | 2 +- .../plugins/cpu/brainduck/version.properties | 2 +- .../plugins/cpu/brainduck/CpuImplTest.java | 2 +- .../plugins/cpu/brainduck/DeviceStub.java | 2 +- .../cpu/brainduck/EmulatorEngineTest.java | 2 +- .../plugins/cpu/brainduck/MemoryStub.java | 2 +- plugins/cpu/ram-cpu/build.gradle | 2 +- .../emustudio/plugins/cpu/ram/Breakpoint.java | 2 +- .../emustudio/plugins/cpu/ram/CpuImpl.java | 2 +- .../plugins/cpu/ram/EmulatorEngine.java | 2 +- .../plugins/cpu/ram/RAMCpuContextImpl.java | 2 +- .../plugins/cpu/ram/api/RAMCpuContext.java | 2 +- .../plugins/cpu/ram/gui/Constants.java | 2 +- .../plugins/cpu/ram/gui/LabelDebugColumn.java | 2 +- .../plugins/cpu/ram/gui/RAMDisassembler.java | 2 +- .../plugins/cpu/ram/gui/RAMStatusPanel.java | 2 +- .../plugins/cpu/ram/version.properties | 2 +- .../plugins/cpu/ram/AbstractEngineTest.java | 2 +- .../plugins/cpu/ram/CpuImplTest.java | 2 +- .../plugins/cpu/ram/EmulatorEngineTest.java | 2 +- plugins/cpu/rasp-cpu/build.gradle | 2 +- .../plugins/cpu/rasp/Breakpoint.java | 2 +- .../emustudio/plugins/cpu/rasp/CpuImpl.java | 2 +- .../plugins/cpu/rasp/EmulatorEngine.java | 2 +- .../plugins/cpu/rasp/RASPCpuContextImpl.java | 2 +- .../plugins/cpu/rasp/api/RASPCpuContext.java | 2 +- .../cpu/rasp/gui/LabelDebugColumn.java | 2 +- .../cpu/rasp/gui/RASPCpuStatusPanel.java | 2 +- .../cpu/rasp/gui/RASPDisassembler.java | 2 +- .../plugins/cpu/rasp/version.properties | 2 +- .../plugins/cpu/rasp/CpuImplTest.java | 2 +- .../plugins/cpu/rasp/EmulatorEngineTest.java | 2 +- .../plugins/cpu/rasp/MemoryStub.java | 2 +- .../emustudio/plugins/cpu/rasp/RASPCell.java | 2 +- plugins/cpu/ssem-cpu/build.gradle | 2 +- plugins/cpu/ssem-cpu/src/main/edigen/cpu.eds | 2 +- .../plugins/cpu/ssem/AutomaticEmulation.java | 2 +- .../emustudio/plugins/cpu/ssem/CpuImpl.java | 2 +- .../plugins/cpu/ssem/EmulatorEngine.java | 2 +- .../plugins/cpu/ssem/LineColumn.java | 2 +- .../plugins/cpu/ssem/TimingEstimator.java | 2 +- .../plugins/cpu/ssem/gui/Constants.java | 2 +- .../plugins/cpu/ssem/gui/CpuPanel.java | 2 +- .../plugins/cpu/ssem/version.properties | 2 +- .../plugins/cpu/ssem/CpuImplTest.java | 2 +- .../plugins/cpu/ssem/DisassemblerTest.java | 2 +- .../plugins/cpu/ssem/EmulatorEngineTest.java | 2 +- plugins/cpu/z80-cpu/build.gradle | 2 +- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 2 +- .../plugins/cpu/zilogZ80/Breakpoint.java | 2 +- .../plugins/cpu/zilogZ80/ContextZ80Impl.java | 2 +- .../plugins/cpu/zilogZ80/CpuImpl.java | 2 +- .../plugins/cpu/zilogZ80/DispatchTables.java | 2 +- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 2 +- .../plugins/cpu/zilogZ80/EmulatorTables.java | 2 +- .../plugins/cpu/zilogZ80/InitializerZ80.java | 2 +- .../cpu/zilogZ80/InstructionPrinter.java | 2 +- .../plugins/cpu/zilogZ80/api/ContextZ80.java | 18 ++++++++++++++++++ .../plugins/cpu/zilogZ80/gui/Constants.java | 2 +- .../plugins/cpu/zilogZ80/gui/FlagsModel.java | 2 +- .../plugins/cpu/zilogZ80/gui/StatusPanel.java | 2 +- .../plugins/cpu/zilogZ80/version.properties | 2 +- .../plugins/cpu/zilogZ80/ArithmeticTest.java | 2 +- .../plugins/cpu/zilogZ80/BitTest.java | 2 +- .../plugins/cpu/zilogZ80/ControlTest.java | 2 +- .../plugins/cpu/zilogZ80/CpuImplTest.java | 2 +- .../cpu/zilogZ80/DisassemblerTest.java | 2 +- .../zilogZ80/EmulatorTablesGeneration.java | 2 +- .../plugins/cpu/zilogZ80/FakeByteDevice.java | 2 +- .../plugins/cpu/zilogZ80/IOTest.java | 2 +- .../cpu/zilogZ80/InstructionsTest.java | 2 +- .../plugins/cpu/zilogZ80/LogicTest.java | 2 +- .../plugins/cpu/zilogZ80/StackTest.java | 2 +- .../plugins/cpu/zilogZ80/TransferTest.java | 2 +- .../cpu/zilogZ80/suite/ByteTestBuilder.java | 2 +- .../cpu/zilogZ80/suite/CpuRunnerImpl.java | 2 +- .../cpu/zilogZ80/suite/CpuVerifierImpl.java | 2 +- .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 2 +- .../zilogZ80/suite/IntegerTestBuilder.java | 2 +- .../plugins/cpu/zilogZ80/suite/Utils.java | 2 +- .../zilogZ80/suite/injectors/Register.java | 2 +- .../suite/injectors/RegisterPair.java | 2 +- .../suite/injectors/RegisterPair2.java | 2 +- .../suite/injectors/RegisterPairPSW.java | 2 +- plugins/device/88-dcdd/build.gradle | 2 +- .../plugins/device/mits88dcdd/DeviceImpl.java | 2 +- .../device/mits88dcdd/DiskSettings.java | 2 +- .../plugins/device/mits88dcdd/Resources.java | 2 +- .../device/mits88dcdd/cmdline/Cpmfs.java | 2 +- .../device/mits88dcdd/cmdline/Runner.java | 2 +- .../mits88dcdd/cpmfs/CpmFileSystem.java | 2 +- .../device/mits88dcdd/cpmfs/CpmFormat.java | 2 +- .../device/mits88dcdd/cpmfs/DateFormat.java | 2 +- .../mits88dcdd/cpmfs/DiskParameterBlock.java | 2 +- .../device/mits88dcdd/cpmfs/DriveIO.java | 2 +- .../device/mits88dcdd/cpmfs/Position.java | 2 +- .../mits88dcdd/cpmfs/entry/CpmEntry.java | 2 +- .../mits88dcdd/cpmfs/entry/CpmFile.java | 2 +- .../mits88dcdd/cpmfs/entry/CpmNativeDate.java | 2 +- .../cpmfs/entry/CpmPlusDiscLabel.java | 2 +- .../cpmfs/entry/CpmPlusPassword.java | 2 +- .../mits88dcdd/cpmfs/entry/DateStamp.java | 2 +- .../cpmfs/sectorops/Altair8deramp.java | 2 +- .../cpmfs/sectorops/Altair8mits.java | 2 +- .../cpmfs/sectorops/AltairMinidiskDeramp.java | 2 +- .../mits88dcdd/cpmfs/sectorops/SectorOps.java | 2 +- .../device/mits88dcdd/drive/Drive.java | 2 +- .../mits88dcdd/drive/DriveCollection.java | 2 +- .../mits88dcdd/drive/DriveListener.java | 2 +- .../mits88dcdd/drive/DriveParameters.java | 2 +- .../device/mits88dcdd/gui/Constants.java | 2 +- .../device/mits88dcdd/gui/DiskGui.java | 2 +- .../device/mits88dcdd/gui/DriveButton.java | 2 +- .../device/mits88dcdd/gui/SettingsDialog.java | 2 +- .../device/mits88dcdd/ports/ControlPort.java | 2 +- .../device/mits88dcdd/ports/DataPort.java | 2 +- .../device/mits88dcdd/ports/StatusPort.java | 2 +- .../device/mits88dcdd/version.properties | 2 +- .../device/mits88dcdd/DeviceImplTest.java | 2 +- .../plugins/device/mits88dcdd/DriveTest.java | 2 +- plugins/device/88-sio/build.gradle | 2 +- .../device/mits88sio/ControlChannel.java | 2 +- .../plugins/device/mits88sio/DataChannel.java | 2 +- .../plugins/device/mits88sio/DeviceImpl.java | 2 +- .../plugins/device/mits88sio/SioUnit.java | 2 +- .../device/mits88sio/SioUnitSettings.java | 2 +- .../plugins/device/mits88sio/UART.java | 2 +- .../device/mits88sio/gui/Constants.java | 2 +- .../device/mits88sio/gui/PortListModel.java | 2 +- .../device/mits88sio/gui/SettingsDialog.java | 2 +- .../plugins/device/mits88sio/gui/SioGui.java | 2 +- .../device/mits88sio/version.properties | 2 +- .../device/mits88sio/ControlChannelTest.java | 2 +- .../device/mits88sio/DataChannelTest.java | 2 +- .../device/mits88sio/DeviceChannelTest.java | 2 +- .../device/mits88sio/DeviceImplTest.java | 2 +- .../plugins/device/mits88sio/SioUnitTest.java | 2 +- .../plugins/device/mits88sio/UARTTest.java | 2 +- plugins/device/abstract-tape/build.gradle | 2 +- .../device/abstracttape/AbstractTape.java | 2 +- .../abstracttape/AbstractTapeContextImpl.java | 2 +- .../abstracttape/api/AbstractTapeContext.java | 2 +- .../device/abstracttape/api/TapeSymbol.java | 2 +- .../device/abstracttape/gui/NiceButton.java | 2 +- .../abstracttape/gui/SettingsDialog.java | 2 +- .../abstracttape/gui/TapeCellRenderer.java | 2 +- .../device/abstracttape/gui/TapeGui.java | 2 +- .../device/abstracttape/gui/TapeModel.java | 2 +- .../device/abstracttape/version.properties | 2 +- .../device/abstracttape/AbstractTapeTest.java | 2 +- plugins/device/adm3A-terminal/build.gradle | 2 +- .../plugins/device/adm3a/DeviceImpl.java | 2 +- .../device/adm3a/TerminalSettings.java | 2 +- .../emustudio/plugins/device/adm3a/Utils.java | 2 +- .../device/adm3a/api/ContextAdm3A.java | 2 +- .../plugins/device/adm3a/api/Keyboard.java | 2 +- .../device/adm3a/api/OutputProvider.java | 2 +- .../device/adm3a/gui/DisplayCanvas.java | 2 +- .../plugins/device/adm3a/gui/DisplayFont.java | 2 +- .../adm3a/gui/DisplayFontJComboRenderer.java | 2 +- .../plugins/device/adm3a/gui/GuiUtils.java | 2 +- .../device/adm3a/gui/SettingsDialog.java | 2 +- .../device/adm3a/gui/TerminalWindow.java | 2 +- .../device/adm3a/interaction/Cursor.java | 2 +- .../device/adm3a/interaction/Display.java | 2 +- .../adm3a/interaction/KeyboardFromFile.java | 2 +- .../device/adm3a/interaction/KeyboardGui.java | 2 +- .../adm3a/interaction/LoadCursorPosition.java | 2 +- .../plugins/device/adm3a/version.properties | 2 +- .../plugins/device/adm3a/DeviceImplTest.java | 2 +- .../device/brainduck-terminal/build.gradle | 2 +- .../terminal/BrainTerminalContext.java | 2 +- .../brainduck/terminal/BrainTerminalGui.java | 2 +- .../device/brainduck/terminal/DeviceImpl.java | 2 +- .../device/brainduck/terminal/io/Cursor.java | 2 +- .../device/brainduck/terminal/io/Display.java | 2 +- .../brainduck/terminal/io/FileIOProvider.java | 2 +- .../brainduck/terminal/io/GUIUtils.java | 2 +- .../brainduck/terminal/io/IOProvider.java | 2 +- .../brainduck/terminal/io/InputProvider.java | 2 +- .../brainduck/terminal/io/Keyboard.java | 2 +- .../brainduck/terminal/io/OutputProvider.java | 2 +- .../brainduck/terminal/version.properties | 2 +- .../brainduck/terminal/DeviceImplTest.java | 2 +- plugins/device/simh-pseudo/build.gradle | 2 +- .../plugins/device/simh/Commands.java | 2 +- .../plugins/device/simh/CpmUtils.java | 2 +- .../plugins/device/simh/DeviceImpl.java | 2 +- .../plugins/device/simh/PseudoContext.java | 2 +- .../device/simh/commands/AttachPTP.java | 2 +- .../device/simh/commands/AttachPTR.java | 2 +- .../plugins/device/simh/commands/Command.java | 2 +- .../device/simh/commands/DetachPTP.java | 2 +- .../device/simh/commands/DetachPTR.java | 2 +- .../device/simh/commands/GenInterrupt.java | 2 +- .../device/simh/commands/GetBankSelect.java | 2 +- .../simh/commands/GetCPUClockFrequency.java | 2 +- .../device/simh/commands/GetClockCPM3.java | 2 +- .../device/simh/commands/GetClockZSDOS.java | 2 +- .../device/simh/commands/GetCommon.java | 2 +- .../simh/commands/GetHostFilenames.java | 2 +- .../simh/commands/GetHostOSPathSeparator.java | 2 +- .../device/simh/commands/GetSimhVersion.java | 2 +- .../device/simh/commands/HasBankedMemory.java | 2 +- .../device/simh/commands/PrintTime.java | 2 +- .../device/simh/commands/ReadStopWatch.java | 2 +- .../plugins/device/simh/commands/ReadURL.java | 2 +- .../device/simh/commands/ResetPTR.java | 2 +- .../simh/commands/ResetSimhInterface.java | 2 +- .../device/simh/commands/ResetStopWatch.java | 2 +- .../device/simh/commands/SIMHSleep.java | 2 +- .../device/simh/commands/Set8080CPU.java | 2 +- .../device/simh/commands/SetBankSelect.java | 2 +- .../simh/commands/SetCPUClockFrequency.java | 2 +- .../device/simh/commands/SetClockCPM3.java | 2 +- .../device/simh/commands/SetClockZSDOS.java | 2 +- .../device/simh/commands/SetTimerDelta.java | 2 +- .../simh/commands/SetTimerInterruptAdr.java | 2 +- .../device/simh/commands/SetZ80CPU.java | 2 +- .../device/simh/commands/ShowTimer.java | 2 +- .../device/simh/commands/StartTimer.java | 2 +- .../simh/commands/StartTimerInterrupts.java | 2 +- .../device/simh/commands/StopTimer.java | 2 +- .../simh/commands/StopTimerInterrupts.java | 2 +- .../plugins/device/simh/version.properties | 2 +- .../plugins/device/simh/DeviceImplTest.java | 2 +- plugins/device/ssem-display/build.gradle | 2 +- .../device/ssem/display/DeviceImpl.java | 2 +- .../device/ssem/display/DisplayGui.java | 2 +- .../device/ssem/display/DisplayPanel.java | 2 +- .../device/ssem/display/version.properties | 2 +- .../device/ssem/display/DeviceImplTest.java | 2 +- .../device/zxspectrum-display/build.gradle | 2 +- .../device/zxspectrum/display/DeviceImpl.java | 18 ++++++++++++++++++ .../display/ZxSpectrumDisplayContext.java | 19 ++++++++++++++++++- .../display/ZxSpectrumDisplayGui.java | 18 ++++++++++++++++++ .../device/zxspectrum/display/io/Cursor.java | 18 ++++++++++++++++++ .../device/zxspectrum/display/io/Display.java | 18 ++++++++++++++++++ .../display/io/DisplayParameters.java | 18 ++++++++++++++++++ .../zxspectrum/display/io/GUIUtils.java | 18 ++++++++++++++++++ .../zxspectrum/display/io/IOProvider.java | 18 ++++++++++++++++++ .../zxspectrum/display/io/Keyboard.java | 18 ++++++++++++++++++ .../zxspectrum/display/io/LineRoller.java | 18 ++++++++++++++++++ .../zxspectrum/display/io/OutputProvider.java | 18 ++++++++++++++++++ .../zxspectrum/display/version.properties | 2 +- plugins/memory/byte-mem/build.gradle | 2 +- .../memory/bytemem/MemoryContextImpl.java | 2 +- .../plugins/memory/bytemem/MemoryImpl.java | 2 +- .../plugins/memory/bytemem/RangeTree.java | 2 +- .../memory/bytemem/api/ByteMemoryContext.java | 2 +- .../plugins/memory/bytemem/gui/Constants.java | 2 +- .../bytemem/gui/FindSequenceDialog.java | 2 +- .../memory/bytemem/gui/KeyboardHandler.java | 2 +- .../plugins/memory/bytemem/gui/MemoryGui.java | 2 +- .../memory/bytemem/gui/MouseHandler.java | 18 ++++++++++++++++++ .../bytemem/gui/SelectBankAddressDialog.java | 18 ++++++++++++++++++ .../memory/bytemem/gui/SettingsDialog.java | 2 +- .../gui/actions/FindSequenceAction.java | 2 +- .../bytemem/gui/model/FileImagesModel.java | 2 +- .../bytemem/gui/model/MemoryTableModel.java | 2 +- .../memory/bytemem/gui/model/ROMmodel.java | 2 +- .../memory/bytemem/gui/model/TableMemory.java | 2 +- .../plugins/memory/bytemem/version.properties | 2 +- .../memory/bytemem/MemoryImplTest.java | 2 +- .../plugins/memory/bytemem/RangeTreeTest.java | 2 +- plugins/memory/ram-mem/build.gradle | 2 +- .../plugins/memory/ram/MemoryContextImpl.java | 2 +- .../plugins/memory/ram/MemoryImpl.java | 2 +- .../memory/ram/api/RAMInstruction.java | 2 +- .../plugins/memory/ram/api/RAMLabel.java | 2 +- .../memory/ram/api/RAMMemoryContext.java | 2 +- .../plugins/memory/ram/api/RAMValue.java | 2 +- .../plugins/memory/ram/gui/Constants.java | 2 +- .../plugins/memory/ram/gui/MemoryDialog.java | 2 +- .../plugins/memory/ram/gui/RAMTableModel.java | 2 +- .../plugins/memory/ram/version.properties | 2 +- .../memory/ram/MemoryContextImplTest.java | 2 +- .../plugins/memory/ram/MemoryImplTest.java | 2 +- plugins/memory/rasp-mem/build.gradle | 2 +- .../memory/rasp/MemoryContextImpl.java | 2 +- .../plugins/memory/rasp/MemoryImpl.java | 2 +- .../plugins/memory/rasp/api/RASPLabel.java | 2 +- .../memory/rasp/api/RASPMemoryCell.java | 2 +- .../memory/rasp/api/RASPMemoryContext.java | 2 +- .../plugins/memory/rasp/gui/Disassembler.java | 2 +- .../plugins/memory/rasp/gui/MemoryDialog.java | 2 +- .../memory/rasp/gui/RASPTableModel.java | 2 +- .../plugins/memory/rasp/version.properties | 2 +- .../plugins/memory/rasp/MemoryImplTest.java | 2 +- plugins/memory/ssem-mem/build.gradle | 2 +- .../memory/ssem/MemoryContextImpl.java | 2 +- .../plugins/memory/ssem/MemoryImpl.java | 2 +- .../plugins/memory/ssem/gui/CellEditor.java | 2 +- .../plugins/memory/ssem/gui/CellRenderer.java | 2 +- .../plugins/memory/ssem/gui/Constants.java | 2 +- .../plugins/memory/ssem/gui/MemoryGui.java | 2 +- .../plugins/memory/ssem/gui/MemoryTable.java | 2 +- .../memory/ssem/gui/MemoryTableModel.java | 2 +- .../memory/ssem/gui/RowHeaderRenderer.java | 2 +- .../plugins/memory/ssem/version.properties | 2 +- .../memory/ssem/MemoryContextImplTest.java | 2 +- .../plugins/memory/ssem/MemoryImplTest.java | 2 +- .../memory/ssem/gui/MemoryTableModelTest.java | 2 +- settings.gradle | 2 +- test_report.gradle | 19 +++++++++++++++++++ 737 files changed, 1146 insertions(+), 714 deletions(-) diff --git a/application/build.gradle b/application/build.gradle index 9fa63532b..23e84f399 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -1,7 +1,7 @@ /* * This file is part of emuStudio. * - * Copyright (C) 2006-2022 Peter Jakubčo + * Copyright (C) 2006-2023 Peter Jakubčo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/application/src/main/files/logback.xml b/application/src/main/files/logback.xml index 47aed4020..9f60853e7 100644 --- a/application/src/main/files/logback.xml +++ b/application/src/main/files/logback.xml @@ -1,7 +1,7 @@ + + logs/emuStudio.log diff --git a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java index 1f177ae4a..e677624b6 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java +++ b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java @@ -50,8 +50,9 @@ public class AutomationCommand implements Runnable { @CommandLine.Option(names = {"-w", "--waitmax"}, paramLabel = "MILLIS", description = "limit emulation time to max MILLIS (force kill afterwards)") private int waitForFinishMillis = Automation.DONT_WAIT; - @CommandLine.Option(names = "--gui", negatable = true, description = "show/don't show GUI during automation") - private boolean gui = true; + @CommandLine.Option(names = "--gui", negatable = true, defaultValue = "true", fallbackValue = "true", + description = "show/don't show GUI during automation") + private boolean gui; @CommandLine.Option(names = {"-s", "--start-address"}, description = "program start address", paramLabel = "ADDRESS") private String programStart = "0"; From 5f614ae6b032781d695045c75510dc17b6630d0e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 13 Jan 2023 13:41:07 +0100 Subject: [PATCH 249/314] 88-sio,adm3a: buffer is now a queue, update on reset --- .../plugins/device/mits88sio/UART.java | 24 +++++++++---------- .../plugins/device/adm3a/DeviceImpl.java | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java index 29970da63..71dc50933 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/UART.java @@ -25,11 +25,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicReference; +import java.util.*; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -68,7 +65,7 @@ public class UART { 7, (byte) 0xFF ); - private final AtomicReference bufferFromDevice = new AtomicReference<>(); + private final Queue bufferFromDevice = new ConcurrentLinkedQueue<>(); private final Lock bufferAndStatusLock = new ReentrantLock(); private final Context8080 cpu; private final List observers = new ArrayList<>(); @@ -113,7 +110,7 @@ public String getDeviceId() { void reset(boolean guiSupported) { if (guiSupported) { - bufferFromDevice.set(null); + bufferFromDevice.clear(); } setStatus((byte) 0); // disable interrupts statusRegister = XMITTER_BUFFER_EMPTY; @@ -124,13 +121,13 @@ public void receiveFromDevice(byte data) { int status = statusRegister; try { - if (bufferFromDevice.get() != null) { + if (bufferFromDevice.isEmpty()) { status |= DATA_OVERFLOW; } else { status = (byte) (status & (~DATA_OVERFLOW)); } status = (byte) (status | DATA_AVAILABLE | INPUT_DEVICE_READY); - bufferFromDevice.set(data); + bufferFromDevice.add(data); statusRegister = (byte) status; } finally { bufferAndStatusLock.unlock(); @@ -158,12 +155,15 @@ public byte readBuffer() { int status = 0; bufferAndStatusLock.lock(); try { - bufferData = bufferFromDevice.get(); - bufferFromDevice.set(null); + bufferData = bufferFromDevice.poll(); if (bufferData == null) { return 0; } - statusRegister = XMITTER_BUFFER_EMPTY; + if (bufferFromDevice.isEmpty()) { + statusRegister = XMITTER_BUFFER_EMPTY; + } else { + statusRegister = (byte) (XMITTER_BUFFER_EMPTY | DATA_AVAILABLE | INPUT_DEVICE_READY); + } status = statusRegister; return bufferData; } finally { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index 5c2c83a57..f9689b5db 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -136,6 +136,7 @@ public void reset() { if (terminalGUI != null) { terminalGUI.clearScreen(); } + keyboard.process(); } @Override From e1431b9ebf7b9811cad9539664f347582aff1ba7 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 14 Jan 2023 11:27:26 +0100 Subject: [PATCH 250/314] [#305] VT100 can now be used also in Altair8800 computer --- .../plugins/device/vt100/DeviceImpl.java | 18 +++++++++++++++--- .../plugins/device/vt100/api/ContextVt100.java | 11 +++++++++++ .../device/zxspectrum/display/DeviceImpl.java | 4 ++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java index 83c80f1a4..39964ada8 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java @@ -25,6 +25,7 @@ import net.emustudio.emulib.plugins.device.DeviceContext; import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextAlreadyRegisteredException; +import net.emustudio.emulib.runtime.ContextNotFoundException; import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.interaction.GuiUtils; import net.emustudio.emulib.runtime.settings.PluginSettings; @@ -99,10 +100,21 @@ public String getDescription() { return "BrainDuck terminal device"; } + @SuppressWarnings("unchecked") @Override public void initialize() throws PluginInitializationException { - BrainCPUContext cpu = applicationApi.getContextPool().getCPUContext(pluginID, BrainCPUContext.class); - cpu.attachDevice(terminalContext); + try { + BrainCPUContext cpu = applicationApi.getContextPool().getCPUContext(pluginID, BrainCPUContext.class); + cpu.attachDevice(terminalContext); + } catch (ContextNotFoundException e) { + DeviceContext device = applicationApi.getContextPool().getDeviceContext(pluginID, DeviceContext.class); + if (device.getDataType() != Byte.class) { + throw new PluginInitializationException( + "Unexpected device data type. Expected Byte but was: " + device.getDataType() + ); + } + terminalContext.setExternalDevice(device); + } terminalContext.setDisplay(display); keyboard.process(); @@ -118,7 +130,7 @@ public void destroy() { try { terminalContext.close(); } catch (Exception e) { - LOGGER.error("Could not close BrainTerminal context", e); + LOGGER.error("Could not close VT100-terminal context", e); } if (terminalGUI != null) { terminalGUI.destroy(); diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/ContextVt100.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/ContextVt100.java index 937889e6a..13c2b22dc 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/ContextVt100.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/ContextVt100.java @@ -18,6 +18,7 @@ */ package net.emustudio.plugins.device.vt100.api; +import net.emustudio.emulib.plugins.device.Device; import net.emustudio.emulib.plugins.device.DeviceContext; import net.jcip.annotations.ThreadSafe; @@ -25,6 +26,7 @@ import java.util.Objects; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.atomic.AtomicReference; @ThreadSafe public class ContextVt100 implements DeviceContext, AutoCloseable { @@ -33,6 +35,7 @@ public class ContextVt100 implements DeviceContext, AutoCloseable { private final Keyboard keyboard; private final BlockingQueue inputBuffer = new LinkedBlockingDeque<>(); + private final AtomicReference> externalDevice = new AtomicReference<>(); private volatile OutputProvider display = OutputProvider.DUMMY; public ContextVt100(Keyboard keyboard) { @@ -44,6 +47,10 @@ public void setDisplay(OutputProvider display) { this.display = display; } + public void setExternalDevice(DeviceContext device) { + this.externalDevice.set(device); + } + public void reset() { OutputProvider tmp = display; if (tmp != null) { @@ -93,5 +100,9 @@ public void close() throws Exception { private void onKeyFromKeyboard(byte key) { inputBuffer.add(key); + DeviceContext device = externalDevice.get(); + if (device != null) { + device.writeData(key); + } } } diff --git a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java index ed1ed768d..69e89f282 100644 --- a/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java +++ b/plugins/device/zxspectrum-display/src/main/java/net/emustudio/plugins/device/zxspectrum/display/DeviceImpl.java @@ -55,7 +55,7 @@ public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s try { applicationApi.getContextPool().register(pluginID, terminal, DeviceContext.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { - LOGGER.error("Could not register BrainTerminal context", e); + LOGGER.error("Could not register ZX Spectrum display context", e); applicationApi.getDialogs().showError("Could not register BrainDuck terminal. Please see log file for more details.", getTitle()); } } @@ -133,7 +133,7 @@ public String getCopyright() { @Override public String getDescription() { - return "BrainDuck terminal device"; + return "ZX Spectrum display draft"; } From c463c6d8f3a45cbb89cc329e94a88128fbcd935b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 15 Jan 2023 10:45:19 +0100 Subject: [PATCH 251/314] [#305] Implement settings dialog --- .../plugins/device/vt100/DeviceImpl.java | 13 +- .../device/vt100/gui/SettingsDialog.java | 167 ++++++++++++++++++ 2 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/SettingsDialog.java diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java index 39964ada8..c6cc6c156 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java @@ -32,6 +32,7 @@ import net.emustudio.plugins.cpu.brainduck.BrainCPUContext; import net.emustudio.plugins.device.vt100.api.ContextVt100; import net.emustudio.plugins.device.vt100.api.Keyboard; +import net.emustudio.plugins.device.vt100.gui.SettingsDialog; import net.emustudio.plugins.device.vt100.gui.TerminalWindow; import net.emustudio.plugins.device.vt100.interaction.Cursor; import net.emustudio.plugins.device.vt100.interaction.Display; @@ -81,7 +82,7 @@ public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s applicationApi.getContextPool().register(pluginID, terminalContext, DeviceContext.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register BrainTerminal context", e); - applicationApi.getDialogs().showError("Could not register BrainDuck terminal. Please see log file for more details.", getTitle()); + applicationApi.getDialogs().showError("Could not register VT100-terminal. Please see log file for more details.", getTitle()); } } @@ -97,7 +98,7 @@ public String getCopyright() { @Override public String getDescription() { - return "BrainDuck terminal device"; + return "VT100-terminal device"; } @SuppressWarnings("unchecked") @@ -138,13 +139,15 @@ public void destroy() { } @Override - public void showSettings(JFrame jFrame) { - // we don't have settings GUI + public void showSettings(JFrame parent) { + if (isShowSettingsSupported()) { + new SettingsDialog(parent, terminalSettings, applicationApi.getDialogs()).setVisible(true); + } } @Override public boolean isShowSettingsSupported() { - return false; + return terminalSettings.isGuiSupported(); } @Override diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/SettingsDialog.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/SettingsDialog.java new file mode 100644 index 000000000..d1d4f0089 --- /dev/null +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/SettingsDialog.java @@ -0,0 +1,167 @@ +package net.emustudio.plugins.device.vt100.gui; + +import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.plugins.device.vt100.TerminalSettings; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Objects; +import javax.swing.*; +import javax.swing.GroupLayout; +import javax.swing.LayoutStyle; +import javax.swing.border.*; + + +public class SettingsDialog extends JDialog { + private final TerminalSettings settings; + private final Dialogs dialogs; + + public SettingsDialog(JFrame parent, TerminalSettings settings, Dialogs dialogs) { + super(parent, true); + + this.settings = Objects.requireNonNull(settings); + this.dialogs = Objects.requireNonNull(dialogs); + initComponents(); + + readSettings(); + } + + private void readSettings() { + txtInputFile.setText(settings.getInputPath().toString()); + txtOutputFile.setText(settings.getOutputPath().toString()); + spnInputDelay.setValue(settings.getInputReadDelayMillis()); + } + + private void updateSettings() throws IOException { + settings.setInputPath(Path.of(txtInputFile.getText())); + settings.setOutputPath(Path.of(txtOutputFile.getText())); + settings.setInputReadDelayMillis((Integer) spnInputDelay.getValue()); + settings.write(); + } + + private void initComponents() { + JPanel panelRedirectIO = new JPanel(); + JLabel lblInputFile = new JLabel("Input file:"); + JLabel lblOutputFile = new JLabel("Output file:"); + JLabel lblRedirectIoNote = new JLabel("In No GUI mode, input/output will be redirected to files."); + JLabel lblInputDelay = new JLabel("Input delay:"); + JLabel lblMs = new JLabel("ms"); + + setTitle("VT100 Terminal Settings"); + setModal(true); + Container contentPane = getContentPane(); + + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); + + btnSave.addActionListener(this::btnSaveActionPerformed); + btnSave.setFont(btnSave.getFont().deriveFont(Font.BOLD)); + btnSave.setDefaultCapable(true); + + panelRedirectIO.setBorder(new TitledBorder(null, "Redirect I/O", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, + new Font("sansserif", Font.BOLD, 13))); + + GroupLayout panelIOLayout = new GroupLayout(panelRedirectIO); + panelRedirectIO.setLayout(panelIOLayout); + panelIOLayout.setHorizontalGroup( + panelIOLayout.createParallelGroup() + .addGroup(panelIOLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelIOLayout.createParallelGroup() + .addComponent(lblRedirectIoNote) + .addGroup(panelIOLayout.createSequentialGroup() + .addGroup(panelIOLayout.createParallelGroup() + .addComponent(lblInputFile) + .addComponent(lblOutputFile) + .addComponent(lblInputDelay)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelIOLayout.createParallelGroup() + .addGroup(panelIOLayout.createSequentialGroup() + .addComponent(spnInputDelay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lblMs)) + .addGroup(panelIOLayout.createSequentialGroup() + .addGroup(panelIOLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(txtInputFile, GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE) + .addComponent(txtOutputFile)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelIOLayout.createParallelGroup() + .addComponent(btnBrowseInputFile) + .addComponent(btnBrowseOutputFile)))))) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + panelIOLayout.setVerticalGroup( + panelIOLayout.createParallelGroup() + .addGroup(GroupLayout.Alignment.TRAILING, panelIOLayout.createSequentialGroup() + .addComponent(lblRedirectIoNote, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelIOLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblInputFile) + .addComponent(txtInputFile, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(btnBrowseInputFile)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelIOLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblOutputFile) + .addComponent(txtOutputFile, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(btnBrowseOutputFile)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelIOLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblInputDelay) + .addComponent(spnInputDelay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblMs)) + .addContainerGap()) + ); + + GroupLayout contentPaneLayout = new GroupLayout(contentPane); + contentPane.setLayout(contentPaneLayout); + contentPaneLayout.setHorizontalGroup( + contentPaneLayout.createParallelGroup() + .addGroup(contentPaneLayout.createSequentialGroup() + .addGroup(contentPaneLayout.createParallelGroup() + .addGroup(contentPaneLayout.createSequentialGroup() + .addContainerGap() + .addComponent(panelRedirectIO, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(GroupLayout.Alignment.TRAILING, contentPaneLayout.createSequentialGroup() + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(btnSave, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + + ); + contentPaneLayout.setVerticalGroup( + contentPaneLayout.createParallelGroup() + .addGroup(contentPaneLayout.createSequentialGroup() + .addContainerGap() + .addComponent(panelRedirectIO, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnSave) + .addContainerGap()) + ); + pack(); + setLocationRelativeTo(getOwner()); + } + + private void btnSaveActionPerformed(ActionEvent evt) { + if (txtInputFile.getText().trim().equals(txtOutputFile.getText().trim())) { + dialogs.showError("Input and output file names cannot point to the same file"); + txtInputFile.grabFocus(); + return; + } + try { + updateSettings(); + dispose(); + } catch (IOException e) { + dialogs.showError("Input or output file names (or both) do not exist. Please make sure they do.", "VT100 Terminal"); + } + } + + private final JButton btnSave = new JButton("Save"); + private final JTextField txtInputFile = new JTextField(); + private final JTextField txtOutputFile = new JTextField(); + private final JButton btnBrowseInputFile = new JButton("Browse..."); + private final JButton btnBrowseOutputFile = new JButton("Browse..."); + private final JSpinner spnInputDelay = new JSpinner(); +} From 188e296b6485df85d20f201c48e6fd65901f99b0 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 15 Jan 2023 11:43:03 +0100 Subject: [PATCH 252/314] [#305] VT100-terminal: allow resizing dynamically --- .../plugins/device/vt100/DeviceImpl.java | 2 + .../device/vt100/TerminalSettings.java | 136 +++++++++++------- .../device/vt100/gui/SettingsDialog.java | 132 ++++++++++++++--- .../device/vt100/interaction/Cursor.java | 26 ++-- .../device/vt100/interaction/Display.java | 41 +++--- 5 files changed, 240 insertions(+), 97 deletions(-) diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java index c6cc6c156..3314ef512 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java @@ -117,6 +117,7 @@ public void initialize() throws PluginInitializationException { terminalContext.setExternalDevice(device); } terminalContext.setDisplay(display); + terminalSettings.addSizeChangedObserver(display::setSize); keyboard.process(); } @@ -128,6 +129,7 @@ public void reset() { @Override public void destroy() { + terminalSettings.destroy(); try { terminalContext.close(); } catch (Exception e) { diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/TerminalSettings.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/TerminalSettings.java index 90d5a68e2..e22b606f7 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/TerminalSettings.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/TerminalSettings.java @@ -1,8 +1,27 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.vt100; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.settings.CannotUpdateSettingException; import net.emustudio.emulib.runtime.settings.PluginSettings; +import net.jcip.annotations.NotThreadSafe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,23 +30,39 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; +@NotThreadSafe public class TerminalSettings { private final static Logger LOGGER = LoggerFactory.getLogger(TerminalSettings.class); public final static String DEFAULT_INPUT_FILE_NAME = "vt100-terminal.in"; public final static String DEFAULT_OUTPUT_FILE_NAME = "vt100-terminal.out"; - private final static String INPUT_FILE_NAME = "inputFileName"; - private final static String OUTPUT_FILE_NAME = "outputFileName"; - private final static String INPUT_READ_DELAY_MILLIS = "inputReadDelayMillis"; + public final static int DEFAULT_COLUMNS = 80; + public final static int DEFAULT_ROWS = 24; + public final static int DEFAULT_INPUT_READ_DELAY_MILLIS = 0; + + private final static String KEY_INPUT_FILE_NAME = "inputFileName"; + private final static String KEY_OUTPUT_FILE_NAME = "outputFileName"; + private final static String KEY_INPUT_READ_DELAY_MILLIS = "inputReadDelayMillis"; + private final static String KEY_COLUMNS = "columns"; + private final static String KEY_ROWS = "rows"; private final Dialogs dialogs; private final PluginSettings settings; private final boolean guiSupported; - private final List observers = new ArrayList<>(); + + private final List sizeChangedObservers = new ArrayList<>(); + private volatile Path inputPath = Path.of(DEFAULT_INPUT_FILE_NAME); private volatile Path outputPath = Path.of(DEFAULT_OUTPUT_FILE_NAME); - private int inputReadDelayMillis = 0; + private int inputReadDelayMillis = DEFAULT_INPUT_READ_DELAY_MILLIS; + private int columns = DEFAULT_COLUMNS; + private int rows = DEFAULT_ROWS; + + public interface SizeChangedObserver { + void sizeChanged(int columns, int rows); + } TerminalSettings(PluginSettings settings, Dialogs dialogs) { this.dialogs = Objects.requireNonNull(dialogs); @@ -37,12 +72,12 @@ public class TerminalSettings { readSettings(); } - public void addChangedObserver(ChangedObserver observer) { - observers.add(observer); + public void addSizeChangedObserver(SizeChangedObserver observer) { + this.sizeChangedObservers.add(observer); } - public void removeChangedObserver(ChangedObserver observer) { - observers.remove(observer); + public void destroy() { + sizeChangedObservers.clear(); } public boolean isGuiSupported() { @@ -55,78 +90,83 @@ public int getInputReadDelayMillis() { public void setInputReadDelayMillis(int inputReadDelayMillis) { this.inputReadDelayMillis = inputReadDelayMillis; - notifyObserversAndIgnoreError(); } public Path getInputPath() { return inputPath; } - public void setInputPath(Path inputPath) throws IOException { + public void setInputPath(Path inputPath) { this.inputPath = inputPath; - notifyObservers(); } public Path getOutputPath() { return outputPath; } - public void setOutputPath(Path outputFileName) throws IOException { + public void setOutputPath(Path outputFileName) { this.outputPath = outputFileName; - notifyObservers(); + } + + public int getColumns() { + return columns; + } + + public int getRows() { + return rows; + } + + public void setSize(int columns, int rows) { + this.columns = columns; + this.rows = rows; + sizeChangedObservers.forEach(a -> a.sizeChanged(columns, rows)); } public void write() { try { - settings.setInt(INPUT_READ_DELAY_MILLIS, inputReadDelayMillis); - settings.setString(OUTPUT_FILE_NAME, outputPath.toString()); - settings.setString(INPUT_FILE_NAME, inputPath.toString()); + settings.setInt(KEY_INPUT_READ_DELAY_MILLIS, inputReadDelayMillis); + settings.setString(KEY_OUTPUT_FILE_NAME, outputPath.toString()); + settings.setString(KEY_INPUT_FILE_NAME, inputPath.toString()); + settings.setInt(KEY_COLUMNS, columns); + settings.setInt(KEY_ROWS, rows); } catch (CannotUpdateSettingException e) { LOGGER.error("Could not update settings", e); dialogs.showError("Could not save settings. Please see log file for details.", "VT100 Terminal"); - } finally { - notifyObserversAndIgnoreError(); } } private void readSettings() { - inputPath = Path.of(settings.getString(INPUT_FILE_NAME, DEFAULT_INPUT_FILE_NAME)); - outputPath = Path.of(settings.getString(OUTPUT_FILE_NAME, DEFAULT_OUTPUT_FILE_NAME)); + this.inputPath = Path.of(settings.getString(KEY_INPUT_FILE_NAME, DEFAULT_INPUT_FILE_NAME)); + this.outputPath = Path.of(settings.getString(KEY_OUTPUT_FILE_NAME, DEFAULT_OUTPUT_FILE_NAME)); try { - inputReadDelayMillis = settings.getInt(INPUT_READ_DELAY_MILLIS, 0); + this.inputReadDelayMillis = settings.getInt(KEY_INPUT_READ_DELAY_MILLIS, DEFAULT_INPUT_READ_DELAY_MILLIS); } catch (NumberFormatException e) { - inputReadDelayMillis = 0; + this.inputReadDelayMillis = DEFAULT_INPUT_READ_DELAY_MILLIS; LOGGER.error( - "Could not read '" + INPUT_READ_DELAY_MILLIS + "' setting. Using default value ({})", inputReadDelayMillis, e + "Could not read '" + KEY_INPUT_READ_DELAY_MILLIS + "' setting. Using default value ({})", inputReadDelayMillis, e ); } - - if (inputPath.toString().equals(outputPath.toString())) { - LOGGER.error("VT100 Terminal settings: Input path is not allowed to be equal to the output path. Setting to default."); - inputPath = Path.of(DEFAULT_INPUT_FILE_NAME); - outputPath = Path.of(DEFAULT_OUTPUT_FILE_NAME); + try { + this.columns = settings.getInt(KEY_COLUMNS, DEFAULT_COLUMNS); + } catch (NumberFormatException e) { + this.columns = DEFAULT_COLUMNS; + LOGGER.error( + "Could not read '" + KEY_COLUMNS + "' setting. Using default value ({})", columns, e + ); } - - notifyObserversAndIgnoreError(); - } - - private void notifyObservers() throws IOException { - for (ChangedObserver observer : observers) { - observer.settingsChanged(); + try { + this.rows = settings.getInt(KEY_ROWS, DEFAULT_ROWS); + } catch (NumberFormatException e) { + this.rows = DEFAULT_ROWS; + LOGGER.error( + "Could not read '" + KEY_ROWS + "' setting. Using default value ({})", rows, e + ); } - } - private void notifyObserversAndIgnoreError() { - for (ChangedObserver observer : observers) { - try { - observer.settingsChanged(); - } catch (IOException e) { - LOGGER.error("Observer is not happy about the new settings", e); - } + if (inputPath.toString().equals(outputPath.toString())) { + LOGGER.error("VT100 Terminal settings: Input path is not allowed to be equal to the output path. Setting to default."); + this.inputPath = Path.of(DEFAULT_INPUT_FILE_NAME); + this.outputPath = Path.of(DEFAULT_OUTPUT_FILE_NAME); } } - - public interface ChangedObserver { - void settingsChanged() throws IOException; - } } diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/SettingsDialog.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/SettingsDialog.java index d1d4f0089..0d90eef09 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/SettingsDialog.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/SettingsDialog.java @@ -1,12 +1,30 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package net.emustudio.plugins.device.vt100.gui; +import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.plugins.device.vt100.TerminalSettings; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; -import java.io.IOException; import java.nio.file.Path; import java.util.Objects; import javax.swing.*; @@ -30,18 +48,13 @@ public SettingsDialog(JFrame parent, TerminalSettings settings, Dialogs dialogs) } private void readSettings() { + txtColumns.setText(String.valueOf(settings.getColumns())); + txtRows.setText(String.valueOf(settings.getRows())); txtInputFile.setText(settings.getInputPath().toString()); txtOutputFile.setText(settings.getOutputPath().toString()); spnInputDelay.setValue(settings.getInputReadDelayMillis()); } - private void updateSettings() throws IOException { - settings.setInputPath(Path.of(txtInputFile.getText())); - settings.setOutputPath(Path.of(txtOutputFile.getText())); - settings.setInputReadDelayMillis((Integer) spnInputDelay.getValue()); - settings.write(); - } - private void initComponents() { JPanel panelRedirectIO = new JPanel(); JLabel lblInputFile = new JLabel("Input file:"); @@ -49,6 +62,10 @@ private void initComponents() { JLabel lblRedirectIoNote = new JLabel("In No GUI mode, input/output will be redirected to files."); JLabel lblInputDelay = new JLabel("Input delay:"); JLabel lblMs = new JLabel("ms"); + JPanel panelSize = new JPanel(); + JLabel lblColumns = new JLabel("Columns:"); + JLabel lblRows = new JLabel("Rows:"); + JLabel lblSizeNote = new JLabel("Terminal size changes will clear current content."); setTitle("VT100 Terminal Settings"); setModal(true); @@ -56,14 +73,62 @@ private void initComponents() { setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); + setResizable(false); btnSave.addActionListener(this::btnSaveActionPerformed); btnSave.setFont(btnSave.getFont().deriveFont(Font.BOLD)); btnSave.setDefaultCapable(true); + btnRowsDefault.addActionListener(e -> txtRows.setText(String.valueOf(TerminalSettings.DEFAULT_ROWS))); + btnColumnsDefault.addActionListener(e -> txtColumns.setText(String.valueOf(TerminalSettings.DEFAULT_COLUMNS))); + panelRedirectIO.setBorder(new TitledBorder(null, "Redirect I/O", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, new Font("sansserif", Font.BOLD, 13))); + panelSize.setBorder(new TitledBorder(null, "Terminal size", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, + new Font("sansserif", Font.BOLD, 13))); + + GroupLayout panelSizeLayout = new GroupLayout(panelSize); + panelSize.setLayout(panelSizeLayout); + panelSizeLayout.setHorizontalGroup( + panelSizeLayout.createParallelGroup() + .addGroup(panelSizeLayout.createSequentialGroup() + .addContainerGap() + .addGroup(panelSizeLayout.createParallelGroup() + .addGroup(panelSizeLayout.createSequentialGroup() + .addGroup(panelSizeLayout.createParallelGroup() + .addComponent(lblColumns) + .addComponent(lblRows)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSizeLayout.createParallelGroup() + .addGroup(panelSizeLayout.createSequentialGroup() + .addComponent(txtRows, GroupLayout.PREFERRED_SIZE, 64, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnRowsDefault)) + .addGroup(panelSizeLayout.createSequentialGroup() + .addComponent(txtColumns, GroupLayout.PREFERRED_SIZE, 64, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(btnColumnsDefault)))) + .addComponent(lblSizeNote)) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + panelSizeLayout.setVerticalGroup( + panelSizeLayout.createParallelGroup() + .addGroup(panelSizeLayout.createSequentialGroup() + .addComponent(lblSizeNote) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSizeLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblColumns) + .addComponent(txtColumns, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(btnColumnsDefault)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelSizeLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblRows) + .addComponent(txtRows, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(btnRowsDefault)) + .addContainerGap(19, Short.MAX_VALUE)) + ); + GroupLayout panelIOLayout = new GroupLayout(panelRedirectIO); panelRedirectIO.setLayout(panelIOLayout); panelIOLayout.setHorizontalGroup( @@ -80,7 +145,7 @@ private void initComponents() { .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(panelIOLayout.createParallelGroup() .addGroup(panelIOLayout.createSequentialGroup() - .addComponent(spnInputDelay, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(spnInputDelay, GroupLayout.PREFERRED_SIZE, 64, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblMs)) .addGroup(panelIOLayout.createSequentialGroup() @@ -121,20 +186,22 @@ private void initComponents() { contentPaneLayout.createParallelGroup() .addGroup(contentPaneLayout.createSequentialGroup() .addGroup(contentPaneLayout.createParallelGroup() - .addGroup(contentPaneLayout.createSequentialGroup() + .addGroup(GroupLayout.Alignment.TRAILING, contentPaneLayout.createSequentialGroup() .addContainerGap() - .addComponent(panelRedirectIO, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(GroupLayout.Alignment.TRAILING, contentPaneLayout.createSequentialGroup() - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(btnSave, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) + .addComponent(panelSize, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(GroupLayout.Alignment.TRAILING, contentPaneLayout.createSequentialGroup() + .addContainerGap() + .addComponent(panelRedirectIO, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(GroupLayout.Alignment.TRAILING, contentPaneLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(btnSave, GroupLayout.PREFERRED_SIZE, 82, GroupLayout.PREFERRED_SIZE))) .addContainerGap()) - ); contentPaneLayout.setVerticalGroup( contentPaneLayout.createParallelGroup() .addGroup(contentPaneLayout.createSequentialGroup() - .addContainerGap() + .addComponent(panelSize, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(panelRedirectIO, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnSave) @@ -150,18 +217,41 @@ private void btnSaveActionPerformed(ActionEvent evt) { txtInputFile.grabFocus(); return; } + + int rows; try { - updateSettings(); - dispose(); - } catch (IOException e) { - dialogs.showError("Input or output file names (or both) do not exist. Please make sure they do.", "VT100 Terminal"); + rows = RadixUtils.getInstance().parseRadix(txtRows.getText()); + } catch (NumberFormatException e) { + dialogs.showError("Could not parse rows (expected integer number)", "VT100-terminal settings"); + txtRows.grabFocus(); + return; } + + int columns; + try { + columns = RadixUtils.getInstance().parseRadix(txtColumns.getText()); + } catch (NumberFormatException e) { + dialogs.showError("Could not parse columns (expected integer number)", "VT100-terminal settings"); + txtColumns.grabFocus(); + return; + } + + settings.setInputPath(Path.of(txtInputFile.getText())); + settings.setOutputPath(Path.of(txtOutputFile.getText())); + settings.setInputReadDelayMillis((Integer) spnInputDelay.getValue()); + settings.setSize(columns, rows); + settings.write(); + dispose(); } private final JButton btnSave = new JButton("Save"); private final JTextField txtInputFile = new JTextField(); private final JTextField txtOutputFile = new JTextField(); + private final JTextField txtColumns = new JTextField(); + private final JTextField txtRows = new JTextField(); private final JButton btnBrowseInputFile = new JButton("Browse..."); private final JButton btnBrowseOutputFile = new JButton("Browse..."); + private final JButton btnRowsDefault = new JButton("Set default"); + private final JButton btnColumnsDefault = new JButton("Set default"); private final JSpinner spnInputDelay = new JSpinner(); } diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Cursor.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Cursor.java index e3a5aab64..0cba4a015 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Cursor.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Cursor.java @@ -26,8 +26,8 @@ @ThreadSafe public class Cursor { - public final int columns; - public final int rows; + public volatile int columns; + public volatile int rows; private final AtomicReference cursorPoint = new AtomicReference<>(new Point()); @@ -36,6 +36,11 @@ public Cursor(int columns, int rows) { this.rows = rows; } + public void setSize(int columns, int rows) { + this.columns = columns; + this.rows = rows; + } + public void home() { cursorPoint.set(new Point()); } @@ -48,14 +53,16 @@ public void moveForwardsRolling(LineRoller lineRoller) { setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); + int tmpRows = rows - 1; + newPoint.x++; if (newPoint.x > (columns - 1)) { newPoint.x = 0; newPoint.y++; // automatic line rolling - if (newPoint.y > (rows - 1)) { + if (newPoint.y > tmpRows) { lineRoller.rollUp(); - newPoint.y = (rows - 1); + newPoint.y = tmpRows; } } return newPoint; @@ -69,11 +76,12 @@ public void moveForwards() { public void moveForwards(int count) { setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); + int tmpColumns = columns - 1; - if ((newPoint.x + count) <= (columns - 1)) { + if ((newPoint.x + count) <= tmpColumns) { newPoint.x += count; } else { - newPoint.x = columns - 1; + newPoint.x = tmpColumns; } return newPoint; }); @@ -144,10 +152,12 @@ public void moveDown(int lines) { setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); - if (newPoint.y < (rows - lines)) { + int tmpRows = rows; + + if (newPoint.y < (tmpRows - lines)) { newPoint.y += lines; } else { - newPoint.y = rows - 1; + newPoint.y = tmpRows - 1; } return newPoint; }); diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Display.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Display.java index 393b03121..3a872bdf1 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Display.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Display.java @@ -39,9 +39,9 @@ public class Display implements OutputProvider, net.emustudio.plugins.device.vt100.interaction.Cursor.LineRoller, Vt100StateMachine.Vt100Dispatcher { private final static Logger LOGGER = LoggerFactory.getLogger(Display.class); - public final char[] videoMemory; - public final int columns; - public final int rows; + public char[] videoMemory; + public volatile int columns; + public volatile int rows; private final TerminalSettings settings; private final Cursor cursor; @@ -70,6 +70,13 @@ public void reset() { clearScreen(); } + public synchronized void setSize(int columns, int rows) { + this.columns = columns; + this.rows = rows; + this.cursor.setSize(columns, rows); + this.videoMemory = new char[rows * columns]; + } + @Override public synchronized void close() { if (outputWriter != null) { @@ -91,22 +98,18 @@ public void clearScreen() { } @Override - public void rollUp() { - synchronized (videoMemory) { - System.arraycopy(videoMemory, columns, videoMemory, 0, columns * rows - columns); - for (int i = columns * rows - columns; i < (columns * rows); i++) { - videoMemory[i] = ' '; - } + public synchronized void rollUp() { + System.arraycopy(videoMemory, columns, videoMemory, 0, columns * rows - columns); + for (int i = columns * rows - columns; i < (columns * rows); i++) { + videoMemory[i] = ' '; } } @Override - public void rollDown() { - synchronized (videoMemory) { - System.arraycopy(videoMemory, 0, videoMemory, columns, columns * rows - columns); - for (int i = 0; i < columns; i++) { - videoMemory[i] = ' '; - } + public synchronized void rollDown() { + System.arraycopy(videoMemory, 0, videoMemory, columns, columns * rows - columns); + for (int i = 0; i < columns; i++) { + videoMemory[i] = ' '; } } @@ -204,7 +207,7 @@ public void execute(int data) { @Override public void print(int data) { Point point = cursor.getCursorPoint(); - synchronized (videoMemory) { + synchronized (this) { videoMemory[point.y * columns + point.x] = (char) data; } cursor.moveForwards(); @@ -401,10 +404,8 @@ private void cursorDown() { } } - private void fillWithSpaces() { - synchronized (videoMemory) { - Arrays.fill(videoMemory, ' '); - } + private synchronized void fillWithSpaces() { + Arrays.fill(videoMemory, ' '); } private void openOutputWriter() { From 703ba85736a0ea2bc745187092df32f20b076914 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Mon, 16 Jan 2023 12:13:50 +0100 Subject: [PATCH 253/314] adm3a-terminal: tests --- .../plugins/device/adm3a/DeviceImpl.java | 37 +++-- .../device/adm3a/api/ContextAdm3A.java | 40 ++--- .../api/{OutputProvider.java => Display.java} | 56 ++++++- .../device/adm3a/gui/DisplayCanvas.java | 15 +- .../adm3a/gui/DisplayFontJComboRenderer.java | 2 +- .../adm3a/{Utils.java => gui/GuiUtils.java} | 29 +--- .../device/adm3a/gui/TerminalWindow.java | 6 +- .../device/adm3a/interaction/Cursor.java | 18 ++- .../{Display.java => DisplayImpl.java} | 52 ++++-- .../adm3a/interaction/KeyboardFromFile.java | 4 +- .../adm3a/interaction/LoadCursorPosition.java | 2 +- .../device/adm3a/api/ContextAdm3ATest.java | 139 ++++++++++++++++ .../device/adm3a/interaction/CursorTest.java | 150 ++++++++++++++++++ .../vt100/interaction/KeyboardFromFile.java | 4 +- 14 files changed, 450 insertions(+), 104 deletions(-) rename plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/{OutputProvider.java => Display.java} (51%) rename plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/{Utils.java => gui/GuiUtils.java} (64%) rename plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/{Display.java => DisplayImpl.java} (76%) create mode 100644 plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3ATest.java create mode 100644 plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/interaction/CursorTest.java diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index f9689b5db..fe87a04a7 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -30,11 +30,12 @@ import net.emustudio.emulib.runtime.interaction.GuiUtils; import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.device.adm3a.api.ContextAdm3A; +import net.emustudio.plugins.device.adm3a.api.Display; import net.emustudio.plugins.device.adm3a.api.Keyboard; import net.emustudio.plugins.device.adm3a.gui.SettingsDialog; import net.emustudio.plugins.device.adm3a.gui.TerminalWindow; import net.emustudio.plugins.device.adm3a.interaction.Cursor; -import net.emustudio.plugins.device.adm3a.interaction.Display; +import net.emustudio.plugins.device.adm3a.interaction.DisplayImpl; import net.emustudio.plugins.device.adm3a.interaction.KeyboardFromFile; import net.emustudio.plugins.device.adm3a.interaction.KeyboardGui; import org.slf4j.Logger; @@ -53,11 +54,11 @@ ) public class DeviceImpl extends AbstractDevice implements TerminalSettings.ChangedObserver { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceImpl.class); - private static final int DEFAULT_COLUMNS = 80; - private static final int DEFAULT_ROWS = 24; + public static final int DEFAULT_COLUMNS = 80; + public static final int DEFAULT_ROWS = 24; private final TerminalSettings terminalSettings; - private final ContextAdm3A terminalContext; + private final ContextAdm3A context; private final Keyboard keyboard; private final Display display; private boolean guiIOset = false; @@ -68,7 +69,7 @@ public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s this.terminalSettings = new TerminalSettings(settings, applicationApi.getDialogs()); Cursor cursor = new Cursor(DEFAULT_COLUMNS, DEFAULT_ROWS); - this.display = new Display(cursor, terminalSettings); + this.display = new DisplayImpl(cursor, terminalSettings); if (terminalSettings.isGuiSupported()) { LOGGER.debug("Creating GUI-based keyboard"); @@ -77,10 +78,11 @@ public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s LOGGER.debug("Creating file-based keyboard ({})", terminalSettings.getInputPath()); this.keyboard = new KeyboardFromFile(terminalSettings); } - this.terminalContext = new ContextAdm3A(this.keyboard, terminalSettings); + this.context = new ContextAdm3A(terminalSettings::isHalfDuplex); + this.keyboard.addOnKeyHandler(context::onKeyFromKeyboard); try { - applicationApi.getContextPool().register(pluginID, terminalContext, DeviceContext.class); + applicationApi.getContextPool().register(pluginID, context, DeviceContext.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register ADM-3A terminal", e); applicationApi.getDialogs().showError( @@ -102,10 +104,10 @@ public void initialize() throws PluginInitializationException { "Unexpected device data type. Expected Byte but was: " + device.getDataType() ); } - terminalContext.setExternalDevice(device); - terminalContext.setDisplay(display); + context.setExternalDevice(device); + context.setDisplay(display); } catch (ContextNotFoundException e) { - LOGGER.warn("The terminal is not connected to any I/O device."); + LOGGER.warn("The terminal is not connected to any I/O device.", e); } keyboard.process(); @@ -157,12 +159,20 @@ public String getDescription() { @Override public void destroy() { terminalSettings.removeChangedObserver(this); - if (keyboard != null) { - keyboard.close(); - } if (terminalGUI != null) { terminalGUI.destroy(); } + keyboard.close(); + try { + display.close(); + } catch (Exception e) { + LOGGER.error("Could not close ADM-3A display", e); + } + try { + context.close(); + } catch (Exception e) { + LOGGER.error("Could not close ADM-3A context", e); + } } @Override @@ -188,6 +198,7 @@ private Optional getResourceBundle() { try { return Optional.of(ResourceBundle.getBundle("net.emustudio.plugins.device.adm3a.version")); } catch (MissingResourceException e) { + LOGGER.error("Could not find resource bundle", e); return Optional.empty(); } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java index b9717aefc..97795a048 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java @@ -23,47 +23,40 @@ import net.jcip.annotations.ThreadSafe; import java.util.Objects; +import java.util.function.Supplier; @ThreadSafe public class ContextAdm3A implements DeviceContext, AutoCloseable { - private final Keyboard keyboard; - private final TerminalSettings settings; + private final Supplier isHalfDuplex; private volatile DeviceContext externalDevice; - private volatile OutputProvider display = OutputProvider.DUMMY; + private volatile Display display = Display.DUMMY; // is never null; and this context is not an owner of display - public ContextAdm3A(Keyboard keyboard, TerminalSettings settings) { - this.keyboard = Objects.requireNonNull(keyboard); - this.settings = Objects.requireNonNull(settings); - keyboard.addOnKeyHandler(this::onKeyFromKeyboard); + public ContextAdm3A(Supplier isHalfDuplex) { + this.isHalfDuplex = Objects.requireNonNull(isHalfDuplex); } public void setExternalDevice(DeviceContext externalDevice) { this.externalDevice = Objects.requireNonNull(externalDevice); } - public void setDisplay(OutputProvider outputProvider) { - this.display = Objects.requireNonNull(outputProvider); + public void setDisplay(Display display) { + this.display = Objects.requireNonNull(display); } public void reset() { - OutputProvider tmp = display; - if (tmp != null) { - tmp.reset(); - } + display.reset(); } @Override public Byte readData() { + // All data is immediately sent to externalDevice. We're not buffering anything. return 0; } @Override public void writeData(Byte data) { - OutputProvider tmpOutputProvider = display; - if (tmpOutputProvider != null) { - tmpOutputProvider.write(data); - } + display.write(data); } @Override @@ -73,22 +66,15 @@ public Class getDataType() { @Override public void close() throws Exception { - Keyboard tmpKeyboard = keyboard; - if (tmpKeyboard != null) { - tmpKeyboard.close(); - } - OutputProvider tmpOutputProvider = display; - if (tmpOutputProvider != null) { - tmpOutputProvider.close(); - } + externalDevice = null; } - private void onKeyFromKeyboard(byte key) { + public void onKeyFromKeyboard(byte key) { DeviceContext device = externalDevice; if (device != null) { device.writeData(key); } - if (settings.isHalfDuplex()) { + if (isHalfDuplex.get()) { writeData(key); } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/OutputProvider.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/Display.java similarity index 51% rename from plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/OutputProvider.java rename to plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/Display.java index 3e34ca14e..c96aed533 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/OutputProvider.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/Display.java @@ -18,13 +18,55 @@ */ package net.emustudio.plugins.device.adm3a.api; -public interface OutputProvider extends AutoCloseable { - OutputProvider DUMMY = new OutputProvider() { +import net.emustudio.plugins.device.adm3a.interaction.Cursor; + +import java.awt.*; + +/** + * Display interface. + */ +public interface Display extends AutoCloseable, Cursor.LineRoller { + + /** + * Dummy display (does nothing useful). + */ + Display DUMMY = new Display() { + @Override + public void rollLine() { + + } + + private final Point point = new Point(0, 0); @Override public void write(byte data) { } + @Override + public Point getCursorPoint() { + return point; + } + + @Override + public int getRows() { + return 0; + } + + @Override + public int getColumns() { + return 0; + } + + @Override + public char[] getVideoMemory() { + return new char[0]; + } + + @Override + public void clearScreen() { + + } + @Override public void reset() { } @@ -37,4 +79,14 @@ public void close() { void reset(); void write(byte data); + + Point getCursorPoint(); + + int getRows(); + + int getColumns(); + + char[] getVideoMemory(); + + void clearScreen(); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java index eeaedd6af..f089209d4 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.device.adm3a.gui; -import net.emustudio.plugins.device.adm3a.interaction.Display; +import net.emustudio.plugins.device.adm3a.api.Display; import javax.swing.*; import java.awt.*; @@ -28,13 +28,13 @@ import java.util.concurrent.atomic.AtomicBoolean; import static java.awt.RenderingHints.*; -import static net.emustudio.plugins.device.adm3a.Utils.loadFont; +import static net.emustudio.plugins.device.adm3a.gui.GuiUtils.loadFont; public class DisplayCanvas extends Canvas implements AutoCloseable { private static final Color FOREGROUND = new Color(255, 255, 255); private static final Color BACKGROUND = Color.BLACK; private final Timer repaintTimer; - private final Display display; + private final Display display; // Canvas is not owning display! private final AtomicBoolean painting = new AtomicBoolean(false); private volatile DisplayFont displayFont; private volatile Dimension size = new Dimension(0, 0); @@ -91,7 +91,6 @@ public synchronized void setDisplayFont(DisplayFont font) { @Override public void close() { repaintTimer.stop(); - display.close(); painting.set(false); } @@ -124,11 +123,11 @@ protected void paint() { graphics.setRenderingHint(KEY_TEXT_ANTIALIASING, VALUE_TEXT_ANTIALIAS_ON); graphics.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON); graphics.setRenderingHint(KEY_STROKE_CONTROL, VALUE_STROKE_NORMALIZE); - for (int y = 0; y < display.rows; y++) { + for (int y = 0; y < display.getRows(); y++) { graphics.drawChars( - display.videoMemory, - y * display.columns, - display.columns, + display.getVideoMemory(), + y * display.getColumns(), + display.getColumns(), 1, (y + 1) * lineHeight); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java index a6adf0901..37b71e71d 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFontJComboRenderer.java @@ -21,7 +21,7 @@ import javax.swing.*; import java.awt.*; -import static net.emustudio.plugins.device.adm3a.Utils.loadFont; +import static net.emustudio.plugins.device.adm3a.gui.GuiUtils.loadFont; public class DisplayFontJComboRenderer extends JLabel implements ListCellRenderer { private final Font originalFont = loadFont(DisplayFont.FONT_ORIGINAL); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/Utils.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/GuiUtils.java similarity index 64% rename from plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/Utils.java rename to plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/GuiUtils.java index 89fac2c3e..943b234c8 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/Utils.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/GuiUtils.java @@ -16,47 +16,26 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.emustudio.plugins.device.adm3a; +package net.emustudio.plugins.device.adm3a.gui; -import net.emustudio.plugins.device.adm3a.gui.DisplayFont; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.awt.*; -import java.awt.font.FontRenderContext; import java.awt.font.TextAttribute; -import java.awt.geom.AffineTransform; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Objects; -public class Utils { - private final static Logger LOGGER = LoggerFactory.getLogger(Utils.class); - private static FontRenderContext DEFAULT_FRC; - - public static FontRenderContext getDefaultFrc() { - if (DEFAULT_FRC == null) { - AffineTransform tx; - if (GraphicsEnvironment.isHeadless()) { - tx = new AffineTransform(); - } else { - tx = GraphicsEnvironment - .getLocalGraphicsEnvironment() - .getDefaultScreenDevice() - .getDefaultConfiguration() - .getDefaultTransform(); - } - DEFAULT_FRC = new FontRenderContext(tx, false, false); - } - return DEFAULT_FRC; - } +public class GuiUtils { + private final static Logger LOGGER = LoggerFactory.getLogger(GuiUtils.class); public static Font loadFont(DisplayFont displayFont) { Map attrs = new HashMap<>(); attrs.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); - try (InputStream fin = Utils.class.getResourceAsStream(displayFont.path)) { + try (InputStream fin = GuiUtils.class.getResourceAsStream(displayFont.path)) { Font font = Font .createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(fin)) .deriveFont(Font.PLAIN, displayFont.fontSize) diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java index d498648b7..2e8047259 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java @@ -18,7 +18,8 @@ */ package net.emustudio.plugins.device.adm3a.gui; -import net.emustudio.plugins.device.adm3a.interaction.Display; +import net.emustudio.plugins.device.adm3a.api.Display; +import net.emustudio.plugins.device.adm3a.interaction.DisplayImpl; import javax.swing.*; import java.awt.*; @@ -54,9 +55,8 @@ public void clearScreen() { } public void destroy() { - this.canvas.close(); - this.display.close(); this.dispose(); + this.canvas.close(); } public void rollLine() { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java index 56366ad45..c44295ffe 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Cursor.java @@ -40,7 +40,17 @@ void home() { cursorPoint.set(new Point()); } - void set(int x, int y) { + void move(int x, int y) { + if (x < 0) { + x = 0; + } else if (x >= columns) { + x = columns - 1; + } + if (y < 0) { + y = 0; + } else if (y >= rows) { + y = rows - 1; + } cursorPoint.set(new Point(x, y)); } @@ -49,11 +59,11 @@ void moveForwardsRolling(LineRoller lineRoller) { Point newPoint = new Point(oldPoint); newPoint.x++; - if (newPoint.x > (columns - 1)) { + if (newPoint.x >= columns) { newPoint.x = 0; newPoint.y++; // automatic line rolling - if (newPoint.y > (rows - 1)) { + if (newPoint.y >= rows) { lineRoller.rollLine(); newPoint.y = (rows - 1); } @@ -128,7 +138,7 @@ private void setCursorPoint(Function changer) { } while (!cursorPoint.compareAndSet(oldPoint, newPoint)); } - interface LineRoller { + public interface LineRoller { void rollLine(); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/DisplayImpl.java similarity index 76% rename from plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java rename to plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/DisplayImpl.java index 11f4da2ca..7b1ea9a15 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/Display.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/DisplayImpl.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.plugins.device.adm3a.TerminalSettings; -import net.emustudio.plugins.device.adm3a.api.OutputProvider; +import net.emustudio.plugins.device.adm3a.api.Display; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,31 +31,35 @@ import java.util.Objects; /** - * Terminal can interpret ASCII codes from 0-127. Some have special purpose (0-31). + * Display implementation. + * A display is not a canvas! It's a visual "controller" of the terminal, but does not perform rendering. + *

+ * It can interpret ASCII codes from 0-127. Some have special purpose (0-31). */ @PluginContext(id = "LSI ADM-3A Terminal") -public class Display implements OutputProvider, Cursor.LineRoller { - private static final Logger LOGGER = LoggerFactory.getLogger(Display.class); - private static final String HERE_IS_CONSTANT = Display.class.getAnnotation(PluginContext.class).id(); +public class DisplayImpl implements Display, Cursor.LineRoller { + private static final Logger LOGGER = LoggerFactory.getLogger(DisplayImpl.class); + private static final String HERE_IS_CONSTANT = DisplayImpl.class.getAnnotation(PluginContext.class).id(); // must be synchronized on this object - public final char[] videoMemory; - public final int columns; - public final int rows; + private final char[] videoMemory; private final TerminalSettings settings; private final Cursor cursor; private final LoadCursorPosition loadCursorPosition; + private final int lastRowStartIndex; + private final int lastRowEndIndex; + private FileWriter outputWriter = null; - public Display(Cursor cursor, TerminalSettings settings) { + public DisplayImpl(Cursor cursor, TerminalSettings settings) { this.settings = Objects.requireNonNull(settings); this.cursor = Objects.requireNonNull(cursor); this.loadCursorPosition = new LoadCursorPosition(cursor); - this.columns = cursor.columns; - this.rows = cursor.rows; - this.videoMemory = new char[rows * columns]; + this.videoMemory = new char[cursor.rows * cursor.columns]; + this.lastRowStartIndex = cursor.columns * cursor.rows - cursor.columns; + this.lastRowEndIndex = cursor.columns * cursor.rows; fillWithSpaces(); if (!settings.isGuiSupported()) { @@ -79,10 +83,26 @@ public synchronized void close() { outputWriter = null; } + @Override public Point getCursorPoint() { return cursor.getCursorPoint(); } + @Override + public int getRows() { + return cursor.rows; + } + + @Override + public int getColumns() { + return cursor.columns; + } + + @Override + public char[] getVideoMemory() { + return videoMemory; // I should be punished for this + } + public void clearScreen() { fillWithSpaces(); cursor.home(); @@ -91,8 +111,8 @@ public void clearScreen() { @Override public void rollLine() { synchronized (videoMemory) { - System.arraycopy(videoMemory, columns, videoMemory, 0, columns * rows - columns); - for (int i = columns * rows - columns; i < (columns * rows); i++) { + System.arraycopy(videoMemory, cursor.columns, videoMemory, 0, lastRowStartIndex); + for (int i = lastRowStartIndex; i < lastRowEndIndex; i++) { videoMemory[i] = ' '; } } @@ -150,7 +170,7 @@ public void write(byte data) { } private void insertHereIs() { - for (char c : Display.HERE_IS_CONSTANT.toCharArray()) { + for (char c : DisplayImpl.HERE_IS_CONSTANT.toCharArray()) { drawChar(c); cursor.moveForwardsRolling(this); } @@ -159,7 +179,7 @@ private void insertHereIs() { private void drawChar(char c) { Point cursorPoint = cursor.getCursorPoint(); synchronized (videoMemory) { - videoMemory[cursorPoint.y * columns + cursorPoint.x] = c; + videoMemory[cursorPoint.y * cursor.columns + cursorPoint.x] = c; } } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java index b39311996..88c3add0a 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java @@ -18,6 +18,7 @@ */ package net.emustudio.plugins.device.adm3a.interaction; +import net.emustudio.emulib.runtime.helpers.SleepUtils; import net.emustudio.plugins.device.adm3a.TerminalSettings; import net.emustudio.plugins.device.adm3a.api.Keyboard; import org.slf4j.Logger; @@ -26,7 +27,6 @@ import java.io.FileInputStream; import java.nio.file.Path; import java.util.Objects; -import java.util.concurrent.locks.LockSupport; public class KeyboardFromFile extends Keyboard { private final static Logger LOGGER = LoggerFactory.getLogger(KeyboardFromFile.class); @@ -46,7 +46,7 @@ public void process() { while ((key = in.read()) != -1) { notifyOnKey((byte) key); if (delayNanos > 0) { - LockSupport.parkNanos(delayNanos); + SleepUtils.preciseSleepNanos(delayNanos); } } } catch (Exception e) { diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java index 190b98a03..03d25dea8 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/LoadCursorPosition.java @@ -65,7 +65,7 @@ boolean notAccepted(byte data) { int cursorX = data - ASCII_COORDINATE_OFFSET; expect = ESCAPE; if (checkBounds(data)) { - cursor.set(cursorX, cursorY); + cursor.move(cursorX, cursorY); return false; } return true; diff --git a/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3ATest.java b/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3ATest.java new file mode 100644 index 000000000..b6331a1aa --- /dev/null +++ b/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3ATest.java @@ -0,0 +1,139 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.adm3a.api; + +import net.emustudio.emulib.plugins.device.DeviceContext; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertEquals; + +public class ContextAdm3ATest { + + private ContextAdm3A context; + + @Before + public void setUp() { + this.context = new ContextAdm3A(() -> false); + } + + @After + public void tearDown() throws Exception { + this.context.close(); + } + + @Test + public void testNoExceptionThrownOnResetWithoutSettingDisplay() { + context.reset(); + } + + @Test(expected = NullPointerException.class) + public void testSetNullDisplayThrows() { + context.setDisplay(null); + } + + @Test + public void testResetCallsDisplayReset() { + Display display = mock(Display.class); + display.reset(); + expectLastCall().once(); + replay(display); + + context.setDisplay(display); + context.reset(); + verify(display); + } + + @Test + public void testWriteDataCallsDisplayWrite() { + Display display = mock(Display.class); + display.write((byte) 0xFF); + expectLastCall().once(); + replay(display); + + context.setDisplay(display); + context.writeData((byte) 0xFF); + verify(display); + } + + @Test + public void testGetDataTypeIsByte() { + assertEquals(Byte.class, context.getDataType()); + } + + @Test + public void testCloseDoesNotCloseDisplay() throws Exception { + // Display is not owned by context + + Display display = mock(Display.class); + replay(display); + context.setDisplay(display); + context.close(); + verify(display); + } + + @Test + public void testCloseSetsExternalDeviceToNull() throws Exception { + DeviceContext device = mock(DeviceContext.class); + replay(device); + + context.setExternalDevice(device); + context.close(); + + context.onKeyFromKeyboard((byte) 0xFF); + verify(device); + } + + @Test(expected = NullPointerException.class) + public void testSetNullExternalDeviceThrows() { + context.setExternalDevice(null); + } + + @Test + public void testReadDataReturns0() { + assertEquals((byte) 0, context.readData().byteValue()); + } + + @Test + public void testOnKeyFromKeyboardSendsDataToDevice() { + DeviceContext device = mock(DeviceContext.class); + device.writeData((byte) 0xFF); + replay(device); + + context.setExternalDevice(device); + context.onKeyFromKeyboard((byte) 0xFF); + verify(device); + } + + @Test + public void testHalfDuplex() throws Exception { + Display display = mock(Display.class); + display.write((byte) 0xFF); + expectLastCall().once(); + replay(display); + + try (ContextAdm3A tmpContext = new ContextAdm3A(() -> true)) { + tmpContext.setDisplay(display); + tmpContext.onKeyFromKeyboard((byte) 0xFF); + } + verify(display); + } +} diff --git a/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/interaction/CursorTest.java b/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/interaction/CursorTest.java new file mode 100644 index 000000000..82f57a6a2 --- /dev/null +++ b/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/interaction/CursorTest.java @@ -0,0 +1,150 @@ +package net.emustudio.plugins.device.adm3a.interaction; + +import org.junit.Before; +import org.junit.Test; + +import java.awt.*; + +import static net.emustudio.plugins.device.adm3a.DeviceImpl.DEFAULT_COLUMNS; +import static net.emustudio.plugins.device.adm3a.DeviceImpl.DEFAULT_ROWS; +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertEquals; + +public class CursorTest { + private Cursor cursor; + + @Before + public void setUp() { + this.cursor = new Cursor(DEFAULT_COLUMNS, DEFAULT_ROWS); + } + + @Test + public void testHome() { + cursor.home(); + assertEquals(new Point(), cursor.getCursorPoint()); + } + + @Test + public void testMove() { + Point expected = new Point(DEFAULT_COLUMNS - 1, DEFAULT_ROWS - 1); + cursor.move(expected.x, expected.y); + assertEquals(expected, cursor.getCursorPoint()); + } + + @Test + public void testMoveOutOfBounds() { + Point point = new Point(DEFAULT_COLUMNS + 1, DEFAULT_ROWS + 1); + cursor.move(point.x, point.y); + assertEquals(new Point(DEFAULT_COLUMNS - 1, DEFAULT_ROWS - 1), cursor.getCursorPoint()); + } + + @Test + public void testMoveOutOfBounds2() { + Point point = new Point(-1, -1); + cursor.move(point.x, point.y); + assertEquals(new Point(0, 0), cursor.getCursorPoint()); + } + + @Test + public void testMoveForwards() { + cursor.moveForwards(); + assertEquals(new Point(1, 0), cursor.getCursorPoint()); + } + + @Test + public void testMoveForwardsOutOfBounds() { + cursor.move(DEFAULT_COLUMNS - 1, 0); + cursor.moveForwards(); + assertEquals(new Point(DEFAULT_COLUMNS - 1, 0), cursor.getCursorPoint()); + } + + @Test + public void testMoveBackwards() { + cursor.move(1, 0); + cursor.moveBackwards(); + assertEquals(new Point(0, 0), cursor.getCursorPoint()); + } + + @Test + public void testMoveBackwardsOutOfBounds() { + cursor.moveBackwards(); + assertEquals(new Point(0, 0), cursor.getCursorPoint()); + } + + @Test + public void testMoveForwardsNoRolling() { + Cursor.LineRoller lineRoller = mock(Cursor.LineRoller.class); + replay(lineRoller); + + cursor.moveForwardsRolling(lineRoller); + assertEquals(new Point(1, 0), cursor.getCursorPoint()); + verify(lineRoller); + } + + @Test + public void testMoveForwardsNoRolling2() { + Cursor.LineRoller lineRoller = mock(Cursor.LineRoller.class); + replay(lineRoller); + + cursor.move(DEFAULT_COLUMNS - 1, 0); + cursor.moveForwardsRolling(lineRoller); + assertEquals(new Point(0, 1), cursor.getCursorPoint()); + verify(lineRoller); + } + + @Test + public void testMoveForwardsRolling() { + Cursor.LineRoller lineRoller = mock(Cursor.LineRoller.class); + lineRoller.rollLine(); + expectLastCall().once(); + replay(lineRoller); + + cursor.move(DEFAULT_COLUMNS - 1, DEFAULT_ROWS - 1); + cursor.moveForwardsRolling(lineRoller); + assertEquals(new Point(0, DEFAULT_ROWS - 1), cursor.getCursorPoint()); + verify(lineRoller); + } + + @Test + public void testMoveUp() { + cursor.move(0, 1); + cursor.moveUp(); + assertEquals(new Point(0, 0), cursor.getCursorPoint()); + } + + @Test + public void testMoveUpOutOfBounds() { + cursor.moveUp(); + assertEquals(new Point(0, 0), cursor.getCursorPoint()); + } + + @Test + public void testMoveDownNoRolling() { + Cursor.LineRoller lineRoller = mock(Cursor.LineRoller.class); + replay(lineRoller); + + cursor.moveDown(lineRoller); + assertEquals(new Point(0, 1), cursor.getCursorPoint()); + verify(lineRoller); + } + + @Test + public void testMoveDownRolling() { + Cursor.LineRoller lineRoller = mock(Cursor.LineRoller.class); + lineRoller.rollLine(); + expectLastCall().once(); + replay(lineRoller); + + cursor.move(0, DEFAULT_ROWS - 1); + cursor.moveDown(lineRoller); + assertEquals(new Point(0, DEFAULT_ROWS - 1), cursor.getCursorPoint()); + verify(lineRoller); + } + + @Test + public void testCarriageReturn() { + cursor.move(DEFAULT_COLUMNS - 1, 0); + cursor.carriageReturn(); + assertEquals(new Point(0, 0), cursor.getCursorPoint()); + } +} diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/KeyboardFromFile.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/KeyboardFromFile.java index a04afe48a..b583dce36 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/KeyboardFromFile.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/KeyboardFromFile.java @@ -18,6 +18,7 @@ */ package net.emustudio.plugins.device.vt100.interaction; +import net.emustudio.emulib.runtime.helpers.SleepUtils; import net.emustudio.plugins.device.vt100.TerminalSettings; import net.emustudio.plugins.device.vt100.api.Keyboard; import org.slf4j.Logger; @@ -26,7 +27,6 @@ import java.io.FileInputStream; import java.nio.file.Path; import java.util.Objects; -import java.util.concurrent.locks.LockSupport; public class KeyboardFromFile extends Keyboard { private final static Logger LOGGER = LoggerFactory.getLogger(KeyboardFromFile.class); @@ -45,7 +45,7 @@ public void process() { while ((key = in.read()) != -1) { notifyOnKey((byte) key); if (delayNanos > 0) { - LockSupport.parkNanos(delayNanos); + SleepUtils.preciseSleepNanos(delayNanos); } } } catch (Exception e) { From df0b8a83a08e212edb02e6e3aaefdd7223bcf6e6 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 18 Jan 2023 16:12:59 +0100 Subject: [PATCH 254/314] [#305] vt100-terminal: some tests --- .../plugins/device/adm3a/DeviceImpl.java | 5 - .../device/adm3a/api/ContextAdm3A.java | 7 +- .../device/adm3a/api/ContextAdm3ATest.java | 39 +---- .../plugins/device/vt100/DeviceImpl.java | 35 ++-- .../device/vt100/api/ContextVt100.java | 46 ++---- .../api/{OutputProvider.java => Display.java} | 53 +++++- .../plugins/device/vt100/api/Keyboard.java | 4 +- .../device/vt100/gui/DisplayCanvas.java | 13 +- .../device/vt100/gui/TerminalWindow.java | 7 +- .../device/vt100/interaction/Cursor.java | 87 ++++++---- .../{Display.java => DisplayImpl.java} | 129 ++++++++------- .../device/vt100/api/ContextVt100Test.java | 95 +++++++++++ .../device/vt100/interaction/CursorTest.java | 151 ++++++++++++++++++ 13 files changed, 473 insertions(+), 198 deletions(-) rename plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/{OutputProvider.java => Display.java} (55%) rename plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/{Display.java => DisplayImpl.java} (85%) create mode 100644 plugins/device/vt100-terminal/src/test/java/net/emustudio/plugins/device/vt100/api/ContextVt100Test.java create mode 100644 plugins/device/vt100-terminal/src/test/java/net/emustudio/plugins/device/vt100/interaction/CursorTest.java diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index fe87a04a7..0d95907a4 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -168,11 +168,6 @@ public void destroy() { } catch (Exception e) { LOGGER.error("Could not close ADM-3A display", e); } - try { - context.close(); - } catch (Exception e) { - LOGGER.error("Could not close ADM-3A context", e); - } } @Override diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java index 97795a048..e953bbdd8 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3A.java @@ -26,7 +26,7 @@ import java.util.function.Supplier; @ThreadSafe -public class ContextAdm3A implements DeviceContext, AutoCloseable { +public class ContextAdm3A implements DeviceContext { private final Supplier isHalfDuplex; private volatile DeviceContext externalDevice; @@ -64,11 +64,6 @@ public Class getDataType() { return Byte.class; } - @Override - public void close() throws Exception { - externalDevice = null; - } - public void onKeyFromKeyboard(byte key) { DeviceContext device = externalDevice; if (device != null) { diff --git a/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3ATest.java b/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3ATest.java index b6331a1aa..cd0cfb73f 100644 --- a/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3ATest.java +++ b/plugins/device/adm3A-terminal/src/test/java/net/emustudio/plugins/device/adm3a/api/ContextAdm3ATest.java @@ -19,7 +19,6 @@ package net.emustudio.plugins.device.adm3a.api; import net.emustudio.emulib.plugins.device.DeviceContext; -import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -35,11 +34,6 @@ public void setUp() { this.context = new ContextAdm3A(() -> false); } - @After - public void tearDown() throws Exception { - this.context.close(); - } - @Test public void testNoExceptionThrownOnResetWithoutSettingDisplay() { context.reset(); @@ -79,29 +73,6 @@ public void testGetDataTypeIsByte() { assertEquals(Byte.class, context.getDataType()); } - @Test - public void testCloseDoesNotCloseDisplay() throws Exception { - // Display is not owned by context - - Display display = mock(Display.class); - replay(display); - context.setDisplay(display); - context.close(); - verify(display); - } - - @Test - public void testCloseSetsExternalDeviceToNull() throws Exception { - DeviceContext device = mock(DeviceContext.class); - replay(device); - - context.setExternalDevice(device); - context.close(); - - context.onKeyFromKeyboard((byte) 0xFF); - verify(device); - } - @Test(expected = NullPointerException.class) public void testSetNullExternalDeviceThrows() { context.setExternalDevice(null); @@ -124,16 +95,16 @@ public void testOnKeyFromKeyboardSendsDataToDevice() { } @Test - public void testHalfDuplex() throws Exception { + public void testHalfDuplex() { Display display = mock(Display.class); display.write((byte) 0xFF); expectLastCall().once(); replay(display); - try (ContextAdm3A tmpContext = new ContextAdm3A(() -> true)) { - tmpContext.setDisplay(display); - tmpContext.onKeyFromKeyboard((byte) 0xFF); - } + ContextAdm3A tmpContext = new ContextAdm3A(() -> true); + tmpContext.setDisplay(display); + tmpContext.onKeyFromKeyboard((byte) 0xFF); + verify(display); } } diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java index 3314ef512..b2b57386c 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/DeviceImpl.java @@ -35,7 +35,7 @@ import net.emustudio.plugins.device.vt100.gui.SettingsDialog; import net.emustudio.plugins.device.vt100.gui.TerminalWindow; import net.emustudio.plugins.device.vt100.interaction.Cursor; -import net.emustudio.plugins.device.vt100.interaction.Display; +import net.emustudio.plugins.device.vt100.interaction.DisplayImpl; import net.emustudio.plugins.device.vt100.interaction.KeyboardFromFile; import net.emustudio.plugins.device.vt100.interaction.KeyboardGui; import org.slf4j.Logger; @@ -51,13 +51,10 @@ public class DeviceImpl extends AbstractDevice { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceImpl.class); - private static final int DEFAULT_COLUMNS = 120; - private static final int DEFAULT_ROWS = 60; - private final TerminalSettings terminalSettings; - private final ContextVt100 terminalContext; + private final ContextVt100 context; private final Keyboard keyboard; - private final Display display; + private final DisplayImpl display; private boolean guiIOset = false; private TerminalWindow terminalGUI; @@ -66,20 +63,20 @@ public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s super(pluginID, applicationApi, settings); this.terminalSettings = new TerminalSettings(settings, applicationApi.getDialogs()); - Cursor cursor = new Cursor(DEFAULT_COLUMNS, DEFAULT_ROWS); - this.display = new Display(cursor, terminalSettings); + Cursor cursor = new Cursor(terminalSettings.getColumns(), terminalSettings.getRows()); + this.display = new DisplayImpl(cursor, terminalSettings); if (terminalSettings.isGuiSupported()) { LOGGER.debug("Creating GUI-based keyboard"); this.keyboard = new KeyboardGui(); } else { - LOGGER.debug("Creating file-based keyboard ({})", ContextVt100.INPUT_FILE_NAME); + LOGGER.debug("Creating file-based keyboard ({})", terminalSettings.getInputPath()); this.keyboard = new KeyboardFromFile(terminalSettings); } - this.terminalContext = new ContextVt100(this.keyboard); + this.context = new ContextVt100(keyboard); try { - applicationApi.getContextPool().register(pluginID, terminalContext, DeviceContext.class); + applicationApi.getContextPool().register(pluginID, context, DeviceContext.class); } catch (InvalidContextException | ContextAlreadyRegisteredException e) { LOGGER.error("Could not register BrainTerminal context", e); applicationApi.getDialogs().showError("Could not register VT100-terminal. Please see log file for more details.", getTitle()); @@ -106,7 +103,7 @@ public String getDescription() { public void initialize() throws PluginInitializationException { try { BrainCPUContext cpu = applicationApi.getContextPool().getCPUContext(pluginID, BrainCPUContext.class); - cpu.attachDevice(terminalContext); + cpu.attachDevice(context); } catch (ContextNotFoundException e) { DeviceContext device = applicationApi.getContextPool().getDeviceContext(pluginID, DeviceContext.class); if (device.getDataType() != Byte.class) { @@ -114,30 +111,26 @@ public void initialize() throws PluginInitializationException { "Unexpected device data type. Expected Byte but was: " + device.getDataType() ); } - terminalContext.setExternalDevice(device); + context.setExternalDevice(device); } - terminalContext.setDisplay(display); + context.setDisplay(display); terminalSettings.addSizeChangedObserver(display::setSize); - keyboard.process(); } @Override public void reset() { - terminalContext.reset(); + context.reset(); } @Override public void destroy() { terminalSettings.destroy(); - try { - terminalContext.close(); - } catch (Exception e) { - LOGGER.error("Could not close VT100-terminal context", e); - } + keyboard.close(); if (terminalGUI != null) { terminalGUI.destroy(); } + display.close(); } @Override diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/ContextVt100.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/ContextVt100.java index 13c2b22dc..cda7bdeb3 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/ContextVt100.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/ContextVt100.java @@ -18,33 +18,34 @@ */ package net.emustudio.plugins.device.vt100.api; -import net.emustudio.emulib.plugins.device.Device; import net.emustudio.emulib.plugins.device.DeviceContext; import net.jcip.annotations.ThreadSafe; -import java.io.File; import java.util.Objects; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.atomic.AtomicReference; +/** + * VT100 device context. + *

+ * Enables sending data to a connected device, but if a device is not available, buffers the data and makes it + * available by reading. + */ @ThreadSafe -public class ContextVt100 implements DeviceContext, AutoCloseable { - public static final File OUTPUT_FILE_NAME = new File("vt100-terminal.out"); - public static final File INPUT_FILE_NAME = new File("vt100-terminal.in"); - +public class ContextVt100 implements DeviceContext { private final Keyboard keyboard; private final BlockingQueue inputBuffer = new LinkedBlockingDeque<>(); private final AtomicReference> externalDevice = new AtomicReference<>(); - private volatile OutputProvider display = OutputProvider.DUMMY; + private volatile Display display = Display.DUMMY; public ContextVt100(Keyboard keyboard) { this.keyboard = Objects.requireNonNull(keyboard); keyboard.addOnKeyHandler(this::onKeyFromKeyboard); } - public void setDisplay(OutputProvider display) { - this.display = display; + public void setDisplay(Display display) { + this.display = Objects.requireNonNull(display); } public void setExternalDevice(DeviceContext device) { @@ -52,10 +53,7 @@ public void setExternalDevice(DeviceContext device) { } public void reset() { - OutputProvider tmp = display; - if (tmp != null) { - tmp.reset(); - } + display.reset(); } @Override @@ -75,10 +73,7 @@ public Byte readData() { @Override public void writeData(Byte data) { - OutputProvider tmpOutputProvider = display; - if (tmpOutputProvider != null) { - tmpOutputProvider.write(data); - } + display.write(data); } @Override @@ -86,22 +81,11 @@ public Class getDataType() { return Byte.class; } - @Override - public void close() throws Exception { - Keyboard tmpKeyboard = keyboard; - if (tmpKeyboard != null) { - tmpKeyboard.close(); - } - OutputProvider tmpOutputProvider = display; - if (tmpOutputProvider != null) { - tmpOutputProvider.close(); - } - } - private void onKeyFromKeyboard(byte key) { - inputBuffer.add(key); DeviceContext device = externalDevice.get(); - if (device != null) { + if (device == null) { + inputBuffer.add(key); + } else { device.writeData(key); } } diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/OutputProvider.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/Display.java similarity index 55% rename from plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/OutputProvider.java rename to plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/Display.java index bfb071418..c2b354d2b 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/OutputProvider.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/Display.java @@ -18,8 +18,17 @@ */ package net.emustudio.plugins.device.vt100.api; -public interface OutputProvider extends AutoCloseable { - OutputProvider DUMMY = new OutputProvider() { +import java.awt.*; + +/** + * Display interface. + */ +public interface Display extends AutoCloseable { + + /** + * Dummy display (does nothing useful). + */ + Display DUMMY = new Display() { @Override public void write(byte data) { @@ -32,9 +41,49 @@ public void reset() { @Override public void close() { } + + @Override + public int getRows() { + return 0; + } + + @Override + public int getColumns() { + return 0; + } + + @Override + public Point getCursorPoint() { + return null; + } + + @Override + public char[] getVideoMemory() { + return new char[0]; + } + + @Override + public void rollUp() { + } + + @Override + public void rollDown() { + } }; void reset(); + int getRows(); + + int getColumns(); + + Point getCursorPoint(); + + char[] getVideoMemory(); + + void rollUp(); + + void rollDown(); + void write(byte data); } diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/Keyboard.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/Keyboard.java index a47f2a36b..5a230f2a7 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/Keyboard.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/api/Keyboard.java @@ -24,8 +24,8 @@ import java.util.function.Consumer; public abstract class Keyboard implements AutoCloseable { - private List> onKeyHandlers = new CopyOnWriteArrayList<>(); - private List> onInputRequestHandlers = new CopyOnWriteArrayList<>(); + private final List> onKeyHandlers = new CopyOnWriteArrayList<>(); + private final List> onInputRequestHandlers = new CopyOnWriteArrayList<>(); /** * Automatic processing of input if this keyboard is capable of doing so. diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/DisplayCanvas.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/DisplayCanvas.java index b0f73a1f3..1cca26364 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/DisplayCanvas.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/DisplayCanvas.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.device.vt100.gui; -import net.emustudio.plugins.device.vt100.interaction.Display; +import net.emustudio.plugins.device.vt100.api.Display; import javax.swing.*; import java.awt.*; @@ -28,13 +28,12 @@ import java.util.concurrent.atomic.AtomicBoolean; import static java.awt.RenderingHints.*; -import static java.awt.RenderingHints.VALUE_STROKE_NORMALIZE; public class DisplayCanvas extends Canvas implements AutoCloseable { private static final Color FOREGROUND = new Color(255, 255, 255); private static final Color BACKGROUND = Color.BLACK; private final Timer repaintTimer; - private final Display display; + private final Display display; // not owning this private final AtomicBoolean painting = new AtomicBoolean(false); private volatile Dimension size = new Dimension(0, 0); @@ -116,11 +115,11 @@ protected void paint() { graphics.setRenderingHint(KEY_TEXT_ANTIALIASING, VALUE_TEXT_ANTIALIAS_ON); graphics.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON); graphics.setRenderingHint(KEY_STROKE_CONTROL, VALUE_STROKE_NORMALIZE); - for (int y = 0; y < display.rows; y++) { + for (int y = 0; y < display.getRows(); y++) { graphics.drawChars( - display.videoMemory, - y * display.columns, - display.columns, + display.getVideoMemory(), + y * display.getColumns(), + display.getColumns(), 1, (y + 1) * lineHeight); } diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/TerminalWindow.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/TerminalWindow.java index c57ad8c9c..7272cdec0 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/TerminalWindow.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/gui/TerminalWindow.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.plugins.device.vt100.interaction.Display; +import net.emustudio.plugins.device.vt100.interaction.DisplayImpl; import net.emustudio.plugins.device.vt100.interaction.KeyboardGui; import javax.swing.*; @@ -35,13 +35,11 @@ public class TerminalWindow extends JDialog { private final ImageIcon blueIcon; // not waiting for input private final ImageIcon redIcon; // waiting for input - private final Display display; private final DisplayCanvas canvas; private final KeyboardGui keyboard; - public TerminalWindow(JFrame parent, Display display, Dialogs dialogs, KeyboardGui keyboard) { + public TerminalWindow(JFrame parent, DisplayImpl display, Dialogs dialogs, KeyboardGui keyboard) { super(parent); - this.display = Objects.requireNonNull(display); this.canvas = new DisplayCanvas(display); this.keyboard = Objects.requireNonNull(keyboard); this.dialogs = Objects.requireNonNull(dialogs); @@ -78,7 +76,6 @@ public void startPainting() { public void destroy() { this.canvas.close(); - this.display.close(); this.dispose(); } diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Cursor.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Cursor.java index 0cba4a015..7838e25c2 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Cursor.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Cursor.java @@ -18,6 +18,7 @@ */ package net.emustudio.plugins.device.vt100.interaction; +import net.emustudio.plugins.device.vt100.api.Display; import net.jcip.annotations.ThreadSafe; import java.awt.*; @@ -26,8 +27,8 @@ @ThreadSafe public class Cursor { - public volatile int columns; - public volatile int rows; + private volatile int columns; + private volatile int rows; private final AtomicReference cursorPoint = new AtomicReference<>(new Point()); @@ -36,7 +37,7 @@ public Cursor(int columns, int rows) { this.rows = rows; } - public void setSize(int columns, int rows) { + public synchronized void setSize(int columns, int rows) { this.columns = columns; this.rows = rows; } @@ -45,23 +46,49 @@ public void home() { cursorPoint.set(new Point()); } - public void set(int x, int y) { - cursorPoint.set(new Point(x, y)); + public void move(int x, int y) { + Point oldPoint; + Point newPoint; + + do { + oldPoint = cursorPoint.get(); + if (x < 0) { + x = 0; + } else if (x >= columns) { + x = columns - 1; + } + if (y < 0) { + y = 0; + } else if (y >= rows) { + y = rows - 1; + } + newPoint = new Point(x, y); + } while (!cursorPoint.compareAndSet(oldPoint, newPoint)); + } + + public void move(Point point) { + cursorPoint.set(point); } - public void moveForwardsRolling(LineRoller lineRoller) { + public void moveForwardsRolling(Display display) { + int tmpRows; + int tmpColumns; + + synchronized (this) { + tmpRows = rows - 1; + tmpColumns = columns - 1; + } + setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); - int tmpRows = rows - 1; - newPoint.x++; - if (newPoint.x > (columns - 1)) { + if (newPoint.x > tmpColumns) { newPoint.x = 0; newPoint.y++; // automatic line rolling if (newPoint.y > tmpRows) { - lineRoller.rollUp(); + display.rollUp(); newPoint.y = tmpRows; } } @@ -74,9 +101,13 @@ public void moveForwards() { } public void moveForwards(int count) { + int tmpColumns; + synchronized (this) { + tmpColumns = columns - 1; + } + setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); - int tmpColumns = columns - 1; if ((newPoint.x + count) <= tmpColumns) { newPoint.x += count; @@ -105,14 +136,14 @@ public void moveBackwards(int count) { } - public void moveUpRolling(LineRoller lineRoller) { + public void moveUpRolling(Display display) { setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); if (newPoint.y > 0) { newPoint.y--; } else { - lineRoller.rollDown(); + display.rollDown(); } return newPoint; }); @@ -131,12 +162,17 @@ public void moveUp(int lines) { }); } - public void moveDownRolling(LineRoller lineRoller) { + public void moveDownRolling(Display display) { + int tmpRows; + synchronized (this) { + tmpRows = rows - 1; + } + setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); - if (newPoint.y == (rows - 1)) { - lineRoller.rollUp(); + if (newPoint.y == tmpRows) { + display.rollUp(); } else { newPoint.y++; } @@ -149,11 +185,14 @@ public void moveDown() { } public void moveDown(int lines) { + int tmpRows; + synchronized (this) { + tmpRows = rows; + } + setCursorPoint(oldPoint -> { Point newPoint = new Point(oldPoint); - int tmpRows = rows; - if (newPoint.y < (tmpRows - lines)) { newPoint.y += lines; } else { @@ -171,8 +210,9 @@ public void carriageReturn() { }); } - public Point getCursorPoint() { - return cursorPoint.get(); + public synchronized Rectangle getRect() { + Point point = cursorPoint.get(); + return new Rectangle(point.x, point.y, columns, rows); } private void setCursorPoint(Function changer) { @@ -182,11 +222,4 @@ private void setCursorPoint(Function changer) { newPoint = changer.apply(oldPoint); } while (!cursorPoint.compareAndSet(oldPoint, newPoint)); } - - interface LineRoller { - - void rollUp(); - - void rollDown(); - } } diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Display.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/DisplayImpl.java similarity index 85% rename from plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Display.java rename to plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/DisplayImpl.java index 3a872bdf1..5c6f169d1 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/Display.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/DisplayImpl.java @@ -20,7 +20,7 @@ import net.emustudio.plugins.device.vt100.TerminalSettings; import net.emustudio.plugins.device.vt100.Vt100StateMachine; -import net.emustudio.plugins.device.vt100.api.OutputProvider; +import net.emustudio.plugins.device.vt100.api.Display; import net.jcip.annotations.ThreadSafe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,37 +31,43 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; // https://vt100.net/docs/vt220-rm/chapter4.html @ThreadSafe -public class Display implements OutputProvider, net.emustudio.plugins.device.vt100.interaction.Cursor.LineRoller, Vt100StateMachine.Vt100Dispatcher { - private final static Logger LOGGER = LoggerFactory.getLogger(Display.class); +public class DisplayImpl implements Display, Vt100StateMachine.Vt100Dispatcher { + private final static Logger LOGGER = LoggerFactory.getLogger(DisplayImpl.class); public char[] videoMemory; - public volatile int columns; - public volatile int rows; private final TerminalSettings settings; private final Cursor cursor; private final Vt100StateMachine vt100; - private FileWriter outputWriter = null; - private Point savedCursorPosition = new Point(); + private final FileWriter outputWriter; + private final AtomicReference savedCursorPosition = new AtomicReference<>(new Point()); - public Display(Cursor cursor, TerminalSettings settings) { + public DisplayImpl(Cursor cursor, TerminalSettings settings) { this.settings = Objects.requireNonNull(settings); this.cursor = Objects.requireNonNull(cursor); - this.columns = cursor.columns; - this.rows = cursor.rows; - this.videoMemory = new char[rows * columns]; + Rectangle rect = cursor.getRect(); + this.videoMemory = new char[rect.height * rect.width]; fillWithSpaces(); this.vt100 = new Vt100StateMachine(this); if (!settings.isGuiSupported()) { - openOutputWriter(); + FileWriter fw = null; + try { + fw = new FileWriter(settings.getOutputPath().toFile()); + } catch (IOException e) { + LOGGER.error("Could not open file for writing output: {}", settings.getOutputPath(), e); + } + this.outputWriter = fw; + } else { + this.outputWriter = null; } } @@ -71,25 +77,40 @@ public void reset() { } public synchronized void setSize(int columns, int rows) { - this.columns = columns; - this.rows = rows; this.cursor.setSize(columns, rows); this.videoMemory = new char[rows * columns]; } @Override - public synchronized void close() { - if (outputWriter != null) { + public void close() { + FileWriter fw = outputWriter; + if (fw != null) { try { - outputWriter.close(); - } catch (IOException ignored) { + fw.close(); + } catch (IOException e) { + LOGGER.error("Could not close output file", e); } } - outputWriter = null; } + @Override public Point getCursorPoint() { - return cursor.getCursorPoint(); + return cursor.getRect().getLocation(); + } + + @Override + public int getRows() { + return cursor.getRect().height; + } + + @Override + public int getColumns() { + return cursor.getRect().width; + } + + @Override + public char[] getVideoMemory() { + return videoMemory; // I should be punished for this } public void clearScreen() { @@ -98,18 +119,24 @@ public void clearScreen() { } @Override - public synchronized void rollUp() { - System.arraycopy(videoMemory, columns, videoMemory, 0, columns * rows - columns); - for (int i = columns * rows - columns; i < (columns * rows); i++) { - videoMemory[i] = ' '; + public void rollUp() { + Rectangle rect = cursor.getRect(); + synchronized (this) { + System.arraycopy(videoMemory, rect.width, videoMemory, 0, rect.width * rect.height - rect.width); + for (int i = rect.width * rect.height - rect.width; i < (rect.width * rect.height); i++) { + videoMemory[i] = ' '; + } } } @Override - public synchronized void rollDown() { - System.arraycopy(videoMemory, 0, videoMemory, columns, columns * rows - columns); - for (int i = 0; i < columns; i++) { - videoMemory[i] = ' '; + public void rollDown() { + Rectangle rect = cursor.getRect(); + synchronized (this) { + System.arraycopy(videoMemory, 0, videoMemory, rect.width, rect.width * rect.height - rect.width); + for (int i = 0; i < rect.width; i++) { + videoMemory[i] = ' '; + } } } @@ -182,11 +209,11 @@ public void execute(int data) { case 0x84: // Index // Moves cursor down one line in same column. If cursor is at bottom margin, screen performs a scroll up. // https://vt100.net/docs/vt220-rm/chapter4.html - cursorDown(); + cursor.moveDownRolling(this); break; case 0x85: // Next line // Moves cursor to first position on next line. If cursor is at bottom margin, screen performs a scroll up. - cursorDown(); + cursor.moveDownRolling(this); cursor.carriageReturn(); break; case 0x88: // Horizontal tab set @@ -197,20 +224,19 @@ public void execute(int data) { // Moves cursor up one line in same column. If cursor is at top margin, screen performs a scroll down. cursor.moveUpRolling(this); break; - - } + // missing: 0,1,2,3,4,6,0x12,0x14,0x15,0x16,0x17 // data >= 0 && data <= 0x17 || data == 0x19 || data >= 0x1C && data <= 0x1F } @Override public void print(int data) { - Point point = cursor.getCursorPoint(); + Rectangle rect = cursor.getRect(); synchronized (this) { - videoMemory[point.y * columns + point.x] = (char) data; + videoMemory[rect.y * rect.width + rect.x] = (char) data; } - cursor.moveForwards(); + cursor.moveForwardsRolling(this); } @Override @@ -247,13 +273,14 @@ public void escDispatch(int data, List collected) { // - state of wrap flag // - state of origin mode // - state of selective erase - savedCursorPosition = cursor.getCursorPoint(); + savedCursorPosition.set(cursor.getRect().getLocation()); break; case 0x38: // Restore Cursor (DECRC) // Restores the states described for (DECSC) above. If none of these characteristics were saved, the // cursor moves to home position; origin mode is reset; no character attributes are assigned; and the // default character set mapping is established. - cursor.set(savedCursorPosition.x, savedCursorPosition.y); + Point point = savedCursorPosition.get(); + cursor.move(point); break; } } @@ -283,11 +310,11 @@ public void csiDispatch(int data, List collected, List params) // Moves the cursor to line Pl, column Pc. The numbering of the lines and columns depends on the state // (set/reset) of origin mode (DECOM). Digital recommends using CUP instead of HVP. if (params.size() == 0) { - cursor.set(0, 0); + cursor.move(0, 0); } else if (params.size() == 1) { - cursor.set(0, params.get(0)); + cursor.move(0, params.get(0)); } else { - cursor.set(params.get(1), params.get(0)); + cursor.move(params.get(1), params.get(0)); } break; case 0x4C: // Insert Line (IL) @@ -396,31 +423,17 @@ private void write(String string) { string.chars().forEach(vt100::accept); } - private void cursorDown() { - if (cursor.getCursorPoint().y == columns - 1) { - rollUp(); - } else { - cursor.moveDown(); - } - } - private synchronized void fillWithSpaces() { Arrays.fill(videoMemory, ' '); } - private void openOutputWriter() { - try { - outputWriter = new FileWriter(settings.getOutputPath().toFile()); - } catch (IOException e) { - LOGGER.error("Could not open file for writing output: {}", settings.getOutputPath(), e); - } - } private void writeToOutput(byte data) { - if (outputWriter != null) { + FileWriter fw = outputWriter; + if (fw != null) { try { - outputWriter.write((char) data); - outputWriter.flush(); + fw.write((char) data); + fw.flush(); } catch (IOException e) { LOGGER.error("Could not write to file: {}", settings.getOutputPath(), e); } diff --git a/plugins/device/vt100-terminal/src/test/java/net/emustudio/plugins/device/vt100/api/ContextVt100Test.java b/plugins/device/vt100-terminal/src/test/java/net/emustudio/plugins/device/vt100/api/ContextVt100Test.java new file mode 100644 index 000000000..3eab0a812 --- /dev/null +++ b/plugins/device/vt100-terminal/src/test/java/net/emustudio/plugins/device/vt100/api/ContextVt100Test.java @@ -0,0 +1,95 @@ +package net.emustudio.plugins.device.vt100.api; + +import net.emustudio.emulib.plugins.device.DeviceContext; +import org.easymock.Capture; +import org.junit.Before; +import org.junit.Test; + +import java.util.function.Consumer; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertEquals; + +public class ContextVt100Test { + + private ContextVt100 context; + private final Capture> captureOnKey = Capture.newInstance(); + + @Before + public void setUp() { + Keyboard keyboard = mock(Keyboard.class); + this.captureOnKey.reset(); + keyboard.addOnKeyHandler(capture(captureOnKey)); + expectLastCall().once(); + replay(keyboard); + this.context = new ContextVt100(keyboard); + } + + @Test + public void testNoExceptionThrownOnResetWithoutSettingDisplay() { + context.reset(); + } + + @Test(expected = NullPointerException.class) + public void testSetNullDisplayThrows() { + context.setDisplay(null); + } + + @Test + public void testResetCallsDisplayReset() { + Display display = mock(Display.class); + display.reset(); + expectLastCall().once(); + replay(display); + + context.setDisplay(display); + context.reset(); + verify(display); + } + + @Test + public void testWriteDataCallsDisplayWrite() { + Display display = mock(Display.class); + display.write((byte) 0xFF); + expectLastCall().once(); + replay(display); + + context.setDisplay(display); + context.writeData((byte) 0xFF); + verify(display); + } + + @Test + public void testGetDataTypeIsByte() { + assertEquals(Byte.class, context.getDataType()); + } + + @Test + public void testReadDataWhenDeviceIsNull() { + Keyboard keyboard = mock(Keyboard.class); + this.captureOnKey.reset(); + keyboard.addOnKeyHandler(capture(captureOnKey)); + expectLastCall().once(); + keyboard.inputRequested(false); + expectLastCall().once(); + replay(keyboard); + + this.context = new ContextVt100(keyboard); + + captureOnKey.getValue().accept((byte) 0xFF); + assertEquals((byte) 0xFF, context.readData().byteValue()); + verify(keyboard); + } + + @Test + public void testOnKeyFromKeyboardSendsDataToDevice() { + DeviceContext device = mock(DeviceContext.class); + device.writeData((byte) 0xFF); + replay(device); + + context.setExternalDevice(device); + captureOnKey.getValue().accept((byte) 0xFF); + verify(device); + } + +} diff --git a/plugins/device/vt100-terminal/src/test/java/net/emustudio/plugins/device/vt100/interaction/CursorTest.java b/plugins/device/vt100-terminal/src/test/java/net/emustudio/plugins/device/vt100/interaction/CursorTest.java new file mode 100644 index 000000000..f72c53ed6 --- /dev/null +++ b/plugins/device/vt100-terminal/src/test/java/net/emustudio/plugins/device/vt100/interaction/CursorTest.java @@ -0,0 +1,151 @@ +package net.emustudio.plugins.device.vt100.interaction; + +import net.emustudio.plugins.device.vt100.api.Display; +import org.junit.Before; +import org.junit.Test; + +import java.awt.*; + +import static net.emustudio.plugins.device.vt100.TerminalSettings.DEFAULT_COLUMNS; +import static net.emustudio.plugins.device.vt100.TerminalSettings.DEFAULT_ROWS; +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertEquals; + +public class CursorTest { + private Cursor cursor; + + @Before + public void setUp() { + this.cursor = new Cursor(DEFAULT_COLUMNS, DEFAULT_ROWS); + } + + @Test + public void testHome() { + cursor.home(); + assertEquals(new Point(), cursor.getRect().getLocation()); + } + + @Test + public void testMove() { + Point expected = new Point(DEFAULT_COLUMNS - 1, DEFAULT_ROWS - 1); + cursor.move(expected.x, expected.y); + assertEquals(expected, cursor.getRect().getLocation()); + } + + @Test + public void testMoveOutOfBounds() { + Point point = new Point(DEFAULT_COLUMNS + 1, DEFAULT_ROWS + 1); + cursor.move(point.x, point.y); + assertEquals(new Point(DEFAULT_COLUMNS - 1, DEFAULT_ROWS - 1), cursor.getRect().getLocation()); + } + + @Test + public void testMoveOutOfBounds2() { + Point point = new Point(-1, -1); + cursor.move(point.x, point.y); + assertEquals(new Point(0, 0), cursor.getRect().getLocation()); + } + + @Test + public void testMoveForwards() { + cursor.moveForwards(); + assertEquals(new Point(1, 0), cursor.getRect().getLocation()); + } + + @Test + public void testMoveForwardsOutOfBounds() { + cursor.move(DEFAULT_COLUMNS - 1, 0); + cursor.moveForwards(); + assertEquals(new Point(DEFAULT_COLUMNS - 1, 0), cursor.getRect().getLocation()); + } + + @Test + public void testMoveBackwards() { + cursor.move(1, 0); + cursor.moveBackwards(); + assertEquals(new Point(0, 0), cursor.getRect().getLocation()); + } + + @Test + public void testMoveBackwardsOutOfBounds() { + cursor.moveBackwards(); + assertEquals(new Point(0, 0), cursor.getRect().getLocation()); + } + + @Test + public void testMoveForwardsNoRolling() { + Display display = mock(Display.class); + replay(display); + + cursor.moveForwardsRolling(display); + assertEquals(new Point(1, 0), cursor.getRect().getLocation()); + verify(display); + } + + @Test + public void testMoveForwardsNoRolling2() { + Display display = mock(Display.class); + replay(display); + + cursor.move(DEFAULT_COLUMNS - 1, 0); + cursor.moveForwardsRolling(display); + assertEquals(new Point(0, 1), cursor.getRect().getLocation()); + verify(display); + } + + @Test + public void testMoveForwardsRolling() { + Display display = mock(Display.class); + display.rollUp(); + expectLastCall().once(); + replay(display); + + cursor.move(DEFAULT_COLUMNS - 1, DEFAULT_ROWS - 1); + cursor.moveForwardsRolling(display); + assertEquals(new Point(0, DEFAULT_ROWS - 1), cursor.getRect().getLocation()); + verify(display); + } + + @Test + public void testMoveUp() { + cursor.move(0, 1); + cursor.moveUp(1); + assertEquals(new Point(0, 0), cursor.getRect().getLocation()); + } + + @Test + public void testMoveUpOutOfBounds() { + cursor.moveUp(1); + assertEquals(new Point(0, 0), cursor.getRect().getLocation()); + } + + @Test + public void testMoveDownNoRolling() { + Display display = mock(Display.class); + replay(display); + + cursor.moveDownRolling(display); + assertEquals(new Point(0, 1), cursor.getRect().getLocation()); + verify(display); + } + + @Test + public void testMoveDownRolling() { + Display display = mock(Display.class); + display.rollUp(); + expectLastCall().once(); + replay(display); + + cursor.move(0, DEFAULT_ROWS - 1); + cursor.moveDownRolling(display); + assertEquals(new Point(0, DEFAULT_ROWS - 1), cursor.getRect().getLocation()); + verify(display); + } + + @Test + public void testCarriageReturn() { + cursor.move(DEFAULT_COLUMNS - 1, 0); + cursor.carriageReturn(); + assertEquals(new Point(0, 0), cursor.getRect().getLocation()); + } +} From 9ab4972bd99c7f910a15304177858a8795f64e81 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 27 Jan 2023 22:43:39 +0100 Subject: [PATCH 255/314] [#315] emuLib + cpu-testsuite non-snapshot versions --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 3459d6d70..d98f4948d 100644 --- a/build.gradle +++ b/build.gradle @@ -26,8 +26,8 @@ ext.versions = [ ] ext.libs = [ - emuLib : "net.emustudio:emulib:11.7.0-SNAPSHOT", - cpuTestSuite : "net.emustudio:cpu-testsuite_11.6:1.2.0-SNAPSHOT", + emuLib : "net.emustudio:emulib:11.7.0", + cpuTestSuite : "net.emustudio:cpu-testsuite_11.7:1.2.0", jcipAnnotations : "net.jcip:jcip-annotations:1.0", antlr : "org.antlr:antlr4:4.11.1", From a20aea4a8bf7e6c0554c47fc5f639cf2fb4fed61 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 3 Feb 2023 10:55:54 +0100 Subject: [PATCH 256/314] [#315] z80-cpu: make z80tests-full pass --- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 466 ++++++++++++------ 1 file changed, 312 insertions(+), 154 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index bc2a40dca..81734b5bc 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -37,6 +37,7 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; import static net.emustudio.plugins.cpu.zilogZ80.DispatchTables.*; import static net.emustudio.plugins.cpu.zilogZ80.EmulatorTables.*; @@ -57,27 +58,36 @@ public class EmulatorEngine implements CpuEngine { private final static int[] CONDITION_VALUES = new int[]{ 0, FLAG_Z, 0, FLAG_C, 0, FLAG_PV, 0, FLAG_S }; - public final int[] regs = new int[8]; - public final int[] regs2 = new int[8]; - public final boolean[] IFF = new boolean[2]; // interrupt enable flip-flops + private final ContextZ80Impl context; private final TimedEventsProcessor tep; private final MemoryContext memory; private final List frequencyChangedListeners = new CopyOnWriteArrayList<>(); - private final Queue pendingInterrupts = new ConcurrentLinkedQueue<>(); // must be thread-safe; can cause stack overflow - // non-maskable interrupts are always executed - private final AtomicBoolean pendingNonMaskableInterrupt = new AtomicBoolean(); + private final AtomicLong executedCycles = new AtomicLong(0); + + public final int[] regs = new int[8]; + public final int[] regs2 = new int[8]; + public final boolean[] IFF = new boolean[2]; // interrupt enable flip-flops + public int flags = 2; public int flags2 = 2; + // special registers public int PC = 0, SP = 0, IX = 0, IY = 0; public int I = 0, R = 0; // interrupt r., refresh r. public int memptr = 0; // internal register, https://gist.github.com/drhelius/8497817 + public int Q = 0; // internal register + public int lastQ = 0; // internal register + + private final Queue pendingInterrupts = new ConcurrentLinkedQueue<>(); // must be thread-safe; can cause stack overflow + // non-maskable interrupts are always executed + private final AtomicBoolean pendingNonMaskableInterrupt = new AtomicBoolean(); + public byte interruptMode = 0; - private int lastOpcode; private boolean interruptSkip; // when EI enabled, skip next instruction interrupt + + private int lastOpcode; private RunState currentRunState = RunState.STATE_STOPPED_NORMAL; - private volatile long executedCycles = 0; private volatile DispatchListener dispatchListener; @@ -88,6 +98,7 @@ public EmulatorEngine(MemoryContext memory, ContextZ80Impl context) { LOGGER.info("Sleep precision: " + SleepUtils.SLEEP_PRECISION + " nanoseconds."); } + @SuppressWarnings("unused") public static String intToFlags(int flags) { String flagsString = ""; if ((flags & FLAG_S) == FLAG_S) { @@ -124,9 +135,7 @@ public void setDispatchListener(DispatchListener dispatchListener) { @Override public long getAndResetExecutedCycles() { - long tmpExecutedCycles = executedCycles; - executedCycles = 0; - return tmpExecutedCycles; + return executedCycles.getAndSet(0); } public void addFrequencyChangedListener(FrequencyChangedListener listener) { @@ -156,6 +165,7 @@ void reset(int startPos) { flags = 0xFF; I = R = 0; memptr = 0; + Q = lastQ = 0; Arrays.fill(regs, 0); Arrays.fill(regs2, 0); flags = 0; @@ -199,7 +209,7 @@ public CPU.RunState run(CPU cpu) { try { cycles = dispatch(); cycles_executed += cycles; - executedCycles += cycles; + executedCycles.addAndGet(cycles); tep.advanceClock(cycles); if (cpu.isBreakpointSet(PC)) { throw new Breakpoint(); @@ -230,6 +240,8 @@ private int dispatch() throws Throwable { } try { + lastQ = Q; + Q = 0; if (pendingNonMaskableInterrupt.getAndSet(false)) { writeWord((SP - 2) & 0xFFFF, PC); SP = (SP - 2) & 0xffff; @@ -305,7 +317,6 @@ private int doInterrupt() throws Throwable { int cycles = 0; IFF[0] = IFF[1] = false; - //System.out.println("z80: interrupt! im=" + interruptMode + ", dataBus=" + Arrays.toString(dataBus)); switch (interruptMode) { case 0: cycles += 11; @@ -445,6 +456,7 @@ int I_ADD_HL_RP() { flags = (flags & FLAG_SZP) | (((hl ^ res ^ rp) >>> 8) & FLAG_H) | ((res >>> 16) & FLAG_C) | TABLE_XY[(res >>> 8) & 0xFF]; + Q = flags; regs[REG_H] = (res >>> 8) & 0xFF; regs[REG_L] = res & 0xFF; @@ -491,6 +503,7 @@ int I_INC_R() { int sum = (regValue + 1) & 0x1FF; int sumByte = sum & 0xFF; flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C) | TABLE_XY[sumByte]; + Q = flags; putreg(reg, sumByte); return (reg == 6) ? 11 : 4; } @@ -501,6 +514,7 @@ int I_DEC_R() { int sum = (regValue - 1) & 0x1FF; int sumByte = sum & 0xFF; flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C) | TABLE_XY[sumByte]; + Q = flags; putreg(reg, sumByte); return (reg == 6) ? 11 : 4; } @@ -529,6 +543,7 @@ int I_ADD_A_R() { int sum = (oldA + value) & 0x1FF; regs[REG_A] = sum & 0xFF; flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + Q = flags; return (lastOpcode == 0x86) ? 7 : 4; } @@ -539,6 +554,7 @@ int I_ADD_A_N() { int sum = (oldA + value) & 0x1FF; regs[REG_A] = sum & 0xFF; flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + Q = flags; return 7; } @@ -548,6 +564,7 @@ int I_ADC_A_R() { int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + Q = flags; return (lastOpcode == 0x8E) ? 7 : 4; } @@ -558,6 +575,7 @@ int I_ADC_A_N() { int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + Q = flags; return 7; } @@ -569,6 +587,7 @@ int I_SUB_R() { regs[REG_A] = sum & 0xFF; flags = TABLE_SUB[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + Q = flags; return (lastOpcode == 0x96) ? 7 : 4; } @@ -580,6 +599,7 @@ int I_SBC_A_R() { regs[REG_A] = sum & 0xFF; flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; + Q = flags; return (lastOpcode == 0x9E) ? 7 : 4; } @@ -592,12 +612,14 @@ int I_SBC_A_N() { regs[REG_A] = sum & 0xFF; flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; + Q = flags; return 7; } int I_AND_R() { regs[REG_A] = (regs[REG_A] & getreg(lastOpcode & 7)) & 0xFF; flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; return (lastOpcode == 0xA6) ? 7 : 4; } @@ -607,12 +629,14 @@ int I_AND_N() { regs[REG_A] = (regs[REG_A] & tmp) & 0xFF; flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; return 7; } int I_XOR_R() { regs[REG_A] = ((regs[REG_A] ^ getreg(lastOpcode & 7)) & 0xff); flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; return (lastOpcode == 0xAE) ? 7 : 4; } @@ -622,12 +646,14 @@ int I_XOR_N() { regs[REG_A] = ((regs[REG_A] ^ tmp) & 0xFF); flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; return 7; } int I_OR_R() { regs[REG_A] = (regs[REG_A] | getreg(lastOpcode & 7)) & 0xFF; flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; return (lastOpcode == 0xB6) ? 7 : 4; } @@ -637,6 +663,7 @@ int I_OR_N() { regs[REG_A] = (regs[REG_A] | tmp) & 0xFF; flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; return 7; } @@ -647,6 +674,7 @@ int I_CP_R() { int result = sum & 0xFF; // F5 and F3 flags are set from the subtrahend instead of from the result. flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[value]; + Q = flags; return (lastOpcode == 0xBE) ? 7 : 4; } @@ -658,12 +686,14 @@ int I_CP_N() { int sum = (oldA - value) & 0x1FF; int result = sum & 0xFF; flags = (TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA])) | TABLE_XY[value]; + Q = flags; return 7; } int I_RLCA() { regs[REG_A] = TABLE_RLCA[regs[REG_A]]; flags = (flags & FLAG_SZP) | (regs[REG_A] & (FLAG_X | FLAG_Y | FLAG_C)); + Q = flags; return 4; } @@ -688,6 +718,7 @@ int I_RRCA() { flags = (flags & FLAG_SZP) | (regs[REG_A] & FLAG_C); regs[REG_A] = TABLE_RRCA[regs[REG_A]]; flags |= TABLE_XY[regs[REG_A]]; + Q = flags; return 4; } @@ -716,6 +747,7 @@ int I_RLA() { int flagC = ((regs[REG_A] & 0x80) == 0x80) ? FLAG_C : 0; regs[REG_A] = res; flags = (flags & FLAG_SZP) | flagC | TABLE_XY[res]; + Q = flags; return 4; } @@ -730,6 +762,7 @@ int I_RRA() { int res = ((regs[REG_A] >>> 1) | (flags << 7)) & 0xFF; int flagC = regs[REG_A] & FLAG_C; flags = (flags & FLAG_SZP) | flagC | TABLE_XY[res]; + Q = flags; regs[REG_A] = res; return 4; } @@ -757,27 +790,41 @@ int I_DAA() { | ((regs[REG_A] ^ a) & FLAG_H) | (flags & FLAG_N) | c; + Q = flags; return 4; } int I_CPL() { regs[REG_A] = (~regs[REG_A]) & 0xFF; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_PV | FLAG_C)) + flags = (flags & (FLAG_SZP | FLAG_C)) | FLAG_H | FLAG_N - | TABLE_XY[regs[REG_A]]; + | (regs[REG_A] & (FLAG_X | FLAG_Y)); + Q = flags; + +// flags = (flags & (FLAG_SZP | FLAG_C)) +// | FLAG_H | FLAG_N +// | TABLE_XY[regs[REG_A]]; return 4; } int I_SCF() { - flags = (flags & FLAG_SZP) | TABLE_XY[regs[REG_A]] | FLAG_C; + flags = (flags & FLAG_SZP) | (((lastQ ^ flags) | regs[REG_A]) & (FLAG_X | FLAG_Y)) | FLAG_C; + Q = flags; + + //flags = (flags & FLAG_SZP) | TABLE_XY[regs[REG_A]] | FLAG_C; return 4; } int I_CCF() { - int c = flags & FLAG_C; - flags = (flags & FLAG_SZP) | (c << 4) - | TABLE_XY[regs[REG_A]] - | (c ^ FLAG_C); + flags = (flags & FLAG_SZP) + | ((flags & FLAG_C) == 0 ? FLAG_C : FLAG_H) + | (((lastQ ^ flags) | regs[REG_A]) & (FLAG_X | FLAG_Y)); + Q = flags; + +// int c = flags & FLAG_C; + // flags = (flags & FLAG_SZP) | (c << 4) + // | TABLE_XY[regs[REG_A]] + // | (c ^ FLAG_C); return 4; } @@ -867,20 +914,17 @@ int I_EI() { int I_IN_R_REF_C() { int reg = (lastOpcode >>> 3) & 0x7; - putreg(reg, context.readIO(regs[REG_C])); - if (reg == REG_A) { - memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; - } + putreg(reg, context.readIO((regs[REG_B] << 8) | regs[REG_C])); + memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; flags = (flags & FLAG_C) | TABLE_SZ[regs[reg]] | PARITY_TABLE[regs[reg]] | TABLE_XY[regs[reg]]; + Q = flags; return 12; } int I_OUT_REF_C_R() { int reg = (lastOpcode >>> 3) & 0x7; - if (reg == REG_A) { - memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; - } - context.writeIO(regs[REG_C], (byte) getreg(reg)); + memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; + context.writeIO((regs[REG_B] << 8) | regs[REG_C], (byte) getreg(reg)); return 12; } @@ -895,6 +939,7 @@ int I_SBC_HL_RP() { ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | (((rp ^ hl) & (hl ^ res) & 0x8000) >>> 13); + Q = flags; regs[REG_H] = (res >>> 8) & 0xFF; regs[REG_L] = res & 0xFF; @@ -912,6 +957,7 @@ int I_ADC_HL_RP() { ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | (((rp ^ hl ^ 0x8000) & (rp ^ res) & 0x8000) >>> 13); + Q = flags; regs[REG_H] = (res >>> 8) & 0xFF; regs[REG_L] = (res & 0xFF); @@ -967,12 +1013,14 @@ int I_IM_2() { int I_LD_A_I() { regs[REG_A] = I & 0xFF; flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; + Q = flags; return 9; } int I_LD_A_R() { regs[REG_A] = R & 0xFF; flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; + Q = flags; return 9; } @@ -985,6 +1033,7 @@ int I_RRD() { value = ((value >>> 4) & 0x0F) | (regA << 4); memory.write(hl, (byte) (value & 0xff)); flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; + Q = flags; return 18; } @@ -997,17 +1046,18 @@ int I_RLD() { regs[REG_A] = ((regs[REG_A] & 0xF0) | tmp1); memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) (value & 0xff)); flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; + Q = flags; return 18; } int I_IN_REF_C() { - int tmp = context.readIO(regs[REG_C]) & 0xFF; + int tmp = context.readIO((regs[REG_B] << 8) | regs[REG_C]) & 0xFF; flags = TABLE_SZ[tmp] | PARITY_TABLE[tmp] | (flags & FLAG_C) | TABLE_XY[tmp]; return 12; } int I_OUT_REF_C_0() { - context.writeIO(regs[REG_C], (byte) 0); + context.writeIO((regs[REG_B] << 8) | regs[REG_C], (byte) 0); return 12; } @@ -1036,6 +1086,7 @@ int I_CPI() { f |= TABLE_SZ[z & 0xFF]; f |= (bc != 0) ? FLAG_PV : 0; flags = f | FLAG_N | (flags & FLAG_C); + Q = flags; return 16; } @@ -1068,6 +1119,7 @@ int I_CPIR() { f |= (bc != 0) ? FLAG_PV : 0; flags = f | FLAG_N | (flags & FLAG_C); + Q = flags; return cycles; } @@ -1094,6 +1146,7 @@ int I_CPD() { f |= TABLE_SZ[z & 0xFF]; f |= (bc != 0) ? FLAG_PV : 0; flags = f | FLAG_N | (flags & FLAG_C); + Q = flags; return 16; } @@ -1127,6 +1180,7 @@ int I_CPDR() { f |= (bc != 0) ? FLAG_PV : 0; flags = f | FLAG_N | (flags & FLAG_C); + Q = flags; return cycles; } @@ -1150,6 +1204,7 @@ int I_LDD() { flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); + Q = flags; return 16; } @@ -1178,11 +1233,13 @@ int I_LDDR() { PC = (PC - 2) & 0xFFFF; memptr = (PC + 1) & 0xFFFF; flags |= TABLE_XY[PC >>> 8]; + Q = flags; return 21; } value += regs[REG_A]; flags |= (value & FLAG_X) | ((value & 0x02) != 0 ? FLAG_Y : 0); + Q = flags; return 16; } @@ -1206,6 +1263,7 @@ int I_LDI() { flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); + Q = flags; return 16; } @@ -1234,209 +1292,302 @@ int I_LDIR() { PC = (PC - 2) & 0xFFFF; memptr = (PC + 1) & 0xFFFF; flags |= TABLE_XY[PC >>> 8]; + Q = flags; return 21; } value += regs[REG_A]; flags |= (value & FLAG_X) | ((value & 0x02) != 0 ? FLAG_Y : 0); + Q = flags; return 16; } int I_INI() { - byte value = context.readIO(regs[REG_C]); - int address = (regs[REG_H] << 8) | regs[REG_L]; - memory.write(address, value); - memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; - - regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - address++; - - regs[REG_H] = (address >>> 8) & 0xFF; - regs[REG_L] = address & 0xFF; + int bc = (regs[REG_B] << 8) | regs[REG_C]; + byte value = context.readIO(bc); + int hl = (regs[REG_H] << 8) | regs[REG_L]; + memory.write(hl, value); - int flagZ = (regs[REG_B] == 0) ? FLAG_Z : 0; - flags = flagZ | (flags & FLAG_C) | FLAG_N | (flags & FLAG_S) | (flags & FLAG_H) | (flags & FLAG_PV); + hl++; + int decB = (regs[REG_B] - 1) & 0xFF; + regs[REG_B] = decB; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + memptr = (bc + 1) & 0xFFFF; + + // from zxpoly + int tmp = (value + regs[REG_C] + 1) & 0xFF; + flags = ((value & 0x80) >>> 6) // N + | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[regs[REG_B]] + | TABLE_XY[regs[REG_B]] + | PARITY_TABLE[(tmp & 7) ^ decB]; + Q = flags; return 16; } int I_INIR() { - byte value = context.readIO(regs[REG_C]); - int address = (regs[REG_H] << 8) | regs[REG_L]; - memory.write(address, value); - memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; - - regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - address++; - - regs[REG_H] = (address >>> 8) & 0xFF; - regs[REG_L] = address & 0xFF; + int bc = (regs[REG_B] << 8) | regs[REG_C]; + int hl = (regs[REG_H] << 8) | regs[REG_L]; - flags |= FLAG_Z | FLAG_N; // FLAG_Z is set b/c it is expected that INIR will be repeated until B=0 + byte value = context.readIO(bc); + memory.write(hl, value); - if (regs[REG_B] == 0) { + hl = (hl + 1) & 0xFFFF; + int decB = (regs[REG_B] - 1) & 0xFF; + regs[REG_B] = decB; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + memptr = (bc + 1) & 0xFFFF; + + // from zxpoly + int tmp = (value + regs[REG_C] + 1) & 0xFF; + flags = ((value & 0x80) >>> 6) // N + | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[regs[REG_B]] + | TABLE_XY[regs[REG_B]] + | PARITY_TABLE[(tmp & 7) ^ decB]; + Q = flags; + + if (decB == 0) { return 16; } PC = (PC - 2) & 0xFFFF; + flags = (flags & ~(FLAG_X | FLAG_Y)) | ((PC >>> 8) & (FLAG_X | FLAG_Y)); + + int flagP = flags & FLAG_PV; + int flagH = flags & FLAG_H; - flags &= 0xD7; // reset X, Y - flags |= TABLE_XY[PC >>> 8]; if ((flags & FLAG_C) == FLAG_C) { - flags &= (~FLAG_H); - if ((value & 0x80) != 0) { - flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] - 1) & 0x7] ^ FLAG_PV; - flags |= ((regs[REG_B] & 0x0F) == 0 ? FLAG_H : 0); + if ((value & 0x80) == 0) { + flagP = flagP ^ PARITY_TABLE[(decB + 1) & 0x7] ^ FLAG_PV; + flagH = (decB & 0x0F) == 0x0F ? FLAG_H : 0; } else { - flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] + 1) & 0x7] ^ FLAG_PV; - flags |= ((regs[REG_B] & 0x0F) == 0x0F ? FLAG_H : 0); + flagP = flagP ^ PARITY_TABLE[(decB - 1) & 0x7] ^ FLAG_PV; + flagH = (decB & 0x0F) == 0 ? FLAG_H : 0; } + } else { + flagP = flagP ^ PARITY_TABLE[decB & 0x07] ^ FLAG_PV; } - + flags = ((flags & ~(FLAG_PV | FLAG_H)) | flagP | flagH); return 21; } int I_IND() { - byte value = context.readIO(regs[REG_C]); + int bc = (regs[REG_B] << 8) | regs[REG_C]; + byte value = context.readIO(bc); int hl = (regs[REG_H] << 8) | regs[REG_L]; memory.write(hl, value); - memptr = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; - regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); hl = (hl - 1) & 0xFFFF; - + int decB = (regs[REG_B] - 1) & 0xFF; + regs[REG_B] = decB; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; + memptr = (bc - 1) & 0xFFFF; + + // from zxpoly + int tmp = (value + regs[REG_C] - 1) & 0xFF; + flags = ((value & 0x80) >>> 6) // N + | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[regs[REG_B]] + | TABLE_XY[regs[REG_B]] + | PARITY_TABLE[(tmp & 7) ^ decB]; - flags = FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0) | (flags & FLAG_C) | (flags & FLAG_S) | (flags & FLAG_PV) | (flags & FLAG_H); + Q = flags; return 16; } int I_INDR() { - byte value = context.readIO(regs[REG_C]); + int bc = (regs[REG_B] << 8) | regs[REG_C]; int hl = (regs[REG_H] << 8) | regs[REG_L]; + + byte value = context.readIO(bc); memory.write(hl, value); - memptr = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; - regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); hl = (hl - 1) & 0xFFFF; - + int decB = (regs[REG_B] - 1) & 0xFF; + regs[REG_B] = decB; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; - - flags |= FLAG_Z | FLAG_N; // FLAG_Z is set b/c it is expected that INIR will be repeated until B=0 - - if (regs[REG_B] == 0) { + memptr = (bc - 1) & 0xFFFF; + + // from zxpoly + int tmp = (value + regs[REG_C] - 1) & 0xFF; + flags = ((value & 0x80) >>> 6) // N + | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[regs[REG_B]] + | TABLE_XY[regs[REG_B]] + | PARITY_TABLE[(tmp & 7) ^ decB]; + Q = flags; + + if (decB == 0) { return 16; } PC = (PC - 2) & 0xFFFF; + flags = (flags & ~(FLAG_X | FLAG_Y)) | ((PC >>> 8) & (FLAG_X | FLAG_Y)); + + int flagP = flags & FLAG_PV; + int flagH = flags & FLAG_H; - flags &= 0xD7; // reset X, Y - flags |= TABLE_XY[PC >>> 8]; if ((flags & FLAG_C) == FLAG_C) { - flags &= (~FLAG_H); - if ((value & 0x80) != 0) { - flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] - 1) & 0x7] ^ FLAG_PV; - flags |= ((regs[REG_B] & 0x0F) == 0 ? FLAG_H : 0); + if ((value & 0x80) == 0) { + flagP = flagP ^ PARITY_TABLE[(decB + 1) & 0x7] ^ FLAG_PV; + flagH = (decB & 0x0F) == 0x0F ? FLAG_H : 0; } else { - flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] + 1) & 0x7] ^ FLAG_PV; - flags |= ((regs[REG_B] & 0x0F) == 0x0F ? FLAG_H : 0); + flagP = flagP ^ PARITY_TABLE[(decB - 1) & 0x7] ^ FLAG_PV; + flagH = (decB & 0x0F) == 0 ? FLAG_H : 0; } + } else { + flagP = flagP ^ PARITY_TABLE[decB & 0x07] ^ FLAG_PV; } + flags = ((flags & ~(FLAG_PV | FLAG_H)) | flagP | flagH); return 21; } int I_OUTI() { - int address = (regs[REG_H] << 8) | regs[REG_L]; - byte value = memory.read(address); - context.writeIO(regs[REG_C], value); + int hl = (regs[REG_H] << 8) | regs[REG_L]; + byte value = memory.read(hl); + int B = regs[REG_B]; + int decB = (B - 1) & 0xFF; - address++; - regs[REG_H] = (address >>> 8) & 0xFF; - regs[REG_L] = address & 0xFF; - regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; + context.writeIO((decB << 8) | regs[REG_C], value); - flags = FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0) | (flags & FLAG_C) | (flags & FLAG_S) | (flags & FLAG_PV) | (flags & FLAG_H); + hl++; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_B] = decB; + memptr = (((decB << 8) | regs[REG_C]) + 1) & 0xFFFF; + + // from zxpoly + int tmp = (value + regs[REG_L]) & 0xFF; + flags = ((value & 0x80) >>> 6) // N + | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[regs[REG_B]] + | TABLE_XY[regs[REG_B]] + | PARITY_TABLE[(tmp & 7) ^ decB]; + + Q = flags; return 16; } int I_OTIR() { - int address = (regs[REG_H] << 8) | regs[REG_L]; - byte value = memory.read(address); - context.writeIO(regs[REG_C], value); - - address++; - regs[REG_H] = (address >>> 8) & 0xFF; - regs[REG_L] = address & 0xFF; - regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; + int hl = (regs[REG_H] << 8) | regs[REG_L]; + byte value = memory.read(hl); + int B = regs[REG_B]; + int decB = (B - 1) & 0xFF; - flags |= FLAG_Z | FLAG_N; // FLAG_Z is set b/c it is expected that OTIR will be repeated until B=0 + context.writeIO((decB << 8) | regs[REG_C], value); - if (regs[REG_B] == 0) { + hl++; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_B] = decB; + memptr = (((decB << 8) | regs[REG_C]) + 1) & 0xFFFF; + + // from zxpoly + int tmp = (value + regs[REG_L]) & 0xFF; + flags = ((value & 0x80) >>> 6) // N + | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[decB] + | TABLE_XY[decB] + | PARITY_TABLE[(tmp & 7) ^ decB]; + Q = flags; + + if (decB == 0) { return 16; } PC = (PC - 2) & 0xFFFF; + flags = (flags & ~(FLAG_X | FLAG_Y)) | ((PC >>> 8) & (FLAG_X | FLAG_Y)); + + int flagP = flags & FLAG_PV; + int flagH = flags & FLAG_H; - flags &= 0xD7; // reset X, Y - flags |= TABLE_XY[PC >>> 8]; if ((flags & FLAG_C) == FLAG_C) { - flags &= (~FLAG_H); - if ((value & 0x80) != 0) { - flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] - 1) & 0x7] ^ FLAG_PV; - flags |= ((regs[REG_B] & 0x0F) == 0 ? FLAG_H : 0); + if ((value & 0x80) == 0) { + flagP = flagP ^ PARITY_TABLE[(decB + 1) & 0x7] ^ FLAG_PV; + flagH = (decB & 0x0F) == 0x0F ? FLAG_H : 0; } else { - flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] + 1) & 0x7] ^ FLAG_PV; - flags |= ((regs[REG_B] & 0x0F) == 0x0F ? FLAG_H : 0); + flagP = flagP ^ PARITY_TABLE[(decB - 1) & 0x7] ^ FLAG_PV; + flagH = (decB & 0x0F) == 0 ? FLAG_H : 0; } + } else { + flagP = flagP ^ PARITY_TABLE[decB & 0x07] ^ FLAG_PV; } + flags = ((flags & ~(FLAG_PV | FLAG_H)) | flagP | flagH); return 21; } int I_OUTD() { - int address = (regs[REG_H] << 8) | regs[REG_L]; - byte value = memory.read(address); - context.writeIO(regs[REG_C], value); + int hl = (regs[REG_H] << 8) | regs[REG_L]; + byte value = memory.read(hl); + int B = regs[REG_B]; + int decB = (B - 1) & 0xFF; - address--; - regs[REG_H] = (address >>> 8) & 0xFF; - regs[REG_L] = address & 0xFF; - regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - memptr = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; + context.writeIO((decB << 8) | regs[REG_C], value); - flags = FLAG_N | (regs[REG_B] == 0 ? FLAG_Z : 0) | (flags & FLAG_C) | (flags & FLAG_S) | (flags & FLAG_PV) | (flags & FLAG_H); + hl--; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_B] = decB; + memptr = (((decB << 8) | regs[REG_C]) + 1) & 0xFFFF; + + // from zxpoly + int tmp = (value + regs[REG_L]) & 0xFF; + flags = ((value & 0x80) >>> 6) // N + | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[decB] + | TABLE_XY[decB] + | PARITY_TABLE[(tmp & 7) ^ decB]; + Q = flags; return 16; } int I_OTDR() { - int address = (regs[REG_H] << 8) | regs[REG_L]; - byte value = memory.read(address); - context.writeIO(regs[REG_C], value); - - address--; - regs[REG_H] = (address >>> 8) & 0xFF; - regs[REG_L] = address & 0xFF; - regs[REG_B] = ((regs[REG_B] - 1) & 0xFF); - memptr = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; + int hl = (regs[REG_H] << 8) | regs[REG_L]; + byte value = memory.read(hl); + int B = regs[REG_B]; + int decB = (B - 1) & 0xFF; - flags |= FLAG_Z | FLAG_N; + context.writeIO((decB << 8) | regs[REG_C], value); - if (regs[REG_B] == 0) { + hl--; + regs[REG_H] = (hl >>> 8) & 0xFF; + regs[REG_L] = hl & 0xFF; + regs[REG_B] = decB; + memptr = (((decB << 8) | regs[REG_C]) + 1) & 0xFFFF; + + // from zxpoly + int tmp = (value + regs[REG_L]) & 0xFF; + flags = ((value & 0x80) >>> 6) // N + | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[decB] + | TABLE_XY[decB] + | PARITY_TABLE[(tmp & 7) ^ decB]; + Q = flags; + + if (decB == 0) { return 16; } PC = (PC - 2) & 0xFFFF; - flags &= 0xD7; // reset X, Y - flags |= TABLE_XY[PC >>> 8]; + flags = (flags & ~(FLAG_X | FLAG_Y)) | ((PC >>> 8) & (FLAG_X | FLAG_Y)); + + int flagP = flags & FLAG_PV; + int flagH = flags & FLAG_H; + if ((flags & FLAG_C) == FLAG_C) { - flags &= (~FLAG_H); - if ((value & 0x80) != 0) { - flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] - 1) & 0x7] ^ FLAG_PV; - flags |= ((regs[REG_B] & 0x0F) == 0 ? FLAG_H : 0); + if ((value & 0x80) == 0) { + flagP = flagP ^ PARITY_TABLE[(decB + 1) & 0x7] ^ FLAG_PV; + flagH = (decB & 0x0F) == 0x0F ? FLAG_H : 0; } else { - flags |= (flags & FLAG_PV) ^ PARITY_TABLE[(regs[REG_B] + 1) & 0x7] ^ FLAG_PV; - flags |= ((regs[REG_B] & 0x0F) == 0x0F ? FLAG_H : 0); + flagP = flagP ^ PARITY_TABLE[(decB - 1) & 0x7] ^ FLAG_PV; + flagH = (decB & 0x0F) == 0 ? FLAG_H : 0; } + } else { + flagP = flagP ^ PARITY_TABLE[decB & 0x07] ^ FLAG_PV; } + flags = ((flags & ~(FLAG_PV | FLAG_H)) | flagP | flagH); return 21; } @@ -1463,7 +1614,6 @@ int I_LD_RP_REF_NN() { int I_JR_CC_N() { int addr = memory.read(PC); PC = (PC + 1) & 0xFFFF; - memptr = PC; if (getCC1((lastOpcode >>> 3) & 3)) { PC = (PC + (byte) addr) & 0xFFFF; @@ -1485,7 +1635,7 @@ int I_OUT_REF_N_A() { PC = (PC + 1) & 0xFFFF; memptr = (regs[REG_A] << 8) | ((port + 1) & 0xFF); // Note for *BM1: MEMPTR_low = (port + 1) & #FF, MEMPTR_hi = 0 - context.writeIO(port, (byte) regs[REG_A]); + context.writeIO((regs[REG_A] << 8) | port, (byte) regs[REG_A]); return 11; } @@ -1493,8 +1643,9 @@ int I_IN_A_REF_N() { int port = memory.read(PC) & 0xFF; PC = (PC + 1) & 0xFFFF; //_memPtr = (A << 8) + _memory.ReadByte(PC) + _memory.ReadByte(PC + 1) * 256 + 1; - memptr = ((regs[REG_A] << 8) + port + 1) & 0xFFFF; - regs[REG_A] = (context.readIO(port) & 0xFF); + int aport = (regs[REG_A] << 8) | port; + regs[REG_A] = context.readIO(aport) & 0xFF; + memptr = (aport + 1) & 0xFFFF; return 11; } @@ -1625,6 +1776,7 @@ int I_RLC_R() { regValue = ((regValue << 1) | (regValue >>> 7)) & 0xFF; putreg(reg, regValue); flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; if (reg == 6) { return 15; @@ -1640,6 +1792,7 @@ int I_RRC_R() { regValue = ((regValue >>> 1) | (regValue << 7)) & 0xFF; putreg(reg, regValue); flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; if (reg == 6) { return 15; @@ -1655,6 +1808,7 @@ int I_RL_R() { regValue = ((regValue << 1) | (flags & FLAG_C)) & 0xFF; putreg(reg, regValue); flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; if (reg == 6) { return 15; @@ -1670,6 +1824,7 @@ int I_RR_R() { regValue = ((regValue >>> 1) | (flags << 7)) & 0xFF; putreg(reg, regValue); flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; if (reg == 6) { return 15; @@ -1686,6 +1841,7 @@ int I_SLA_R() { regValue = (regValue << 1) & 0xFF; putreg(reg, regValue); flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; if (reg == 6) { return 15; @@ -1701,6 +1857,7 @@ int I_SRA_R() { regValue = ((regValue >>> 1) | (regValue & 0x80)) & 0xFF; putreg(reg, regValue); flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; if (reg == 6) { return 15; @@ -1716,6 +1873,7 @@ int I_SLL_R() { regValue = ((regValue << 1) | 0x01) & 0xFF; putreg(reg, regValue); flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; if (reg == 6) { return 15; @@ -1731,6 +1889,7 @@ int I_SRL_R() { regValue = (regValue >>> 1) & 0xFF; putreg(reg, regValue); flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; if (reg == 6) { return 15; @@ -1753,9 +1912,11 @@ int I_BIT_N_R() { if (reg == 6) { flags &= (~FLAG_X); flags &= (~FLAG_Y); - flags |= ((memptr >>> 8) & FLAG_X) | ((memptr >>> 8) & FLAG_Y); + flags |= ((memptr >>> 8) & (FLAG_X | FLAG_Y)); + Q = flags; return 12; } else { + Q = flags; return 8; } } @@ -1997,7 +2158,6 @@ int I_ADD_A_REF_II_N(int special) { int address = (special + disp) & 0xFFFF; memptr = address; int value = memory.read(address) & 0xFF; - int oldA = regs[REG_A]; int sum = (oldA + value) & 0x1FF; regs[REG_A] = sum & 0xFF; @@ -2019,7 +2179,6 @@ int I_ADC_A_REF_II_N(int special) { int address = (special + disp) & 0xFFFF; memptr = address; int value = memory.read(address) & 0xFF; - int oldA = regs[REG_A]; int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; @@ -2041,11 +2200,9 @@ int I_SUB_REF_II_N(int special) { int address = (special + disp) & 0xFFFF; memptr = address; int value = memory.read(address) & 0xFF; - int oldA = regs[REG_A]; int sum = (oldA - value) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; return 19; } @@ -2064,11 +2221,9 @@ int I_SBC_A_REF_II_N(int special) { int address = (special + disp) & 0xFFFF; memptr = address; int value = memory.read(address) & 0xFF; - int oldA = regs[REG_A]; int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; return 19; } @@ -2144,10 +2299,9 @@ int I_CP_REF_II_N(int special) { int address = (special + disp) & 0xFFFF; memptr = address; int value = memory.read(address) & 0xFF; - int oldA = regs[REG_A]; - int sum = (oldA - value) & 0x1FF; + int sum = (regs[REG_A] - value) & 0x1FF; int result = sum & 0xFF; - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ regs[REG_A]]) | TABLE_XY[value]; return 19; } @@ -2489,6 +2643,7 @@ int I_INC(int value) { int sum = (value + 1) & 0x1FF; int sumByte = sum & 0xFF; flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | TABLE_XY[sumByte]; + Q = flags; return sumByte; } @@ -2507,6 +2662,7 @@ int I_DEC_IIH(int special) { int sum = (reg - 1) & 0x1FF; int sumByte = sum & 0xFF; flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C) | TABLE_XY[sumByte]; + Q = flags; return sumByte; } @@ -2525,6 +2681,7 @@ int I_DEC_IIL(int special) { int sum = (reg - 1) & 0x1FF; int sumByte = sum & 0xFF; flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C) | TABLE_XY[sumByte]; + Q = flags; return sumByte; } @@ -2702,6 +2859,7 @@ int I_SUB(int value) { regs[REG_A] = sum & 0xFF; flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; + Q = flags; return 8; } From bbd9d13f4d84f584396f249091ceeff513ac3bce Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 3 Feb 2023 11:09:18 +0100 Subject: [PATCH 257/314] [#315] z80-cpu: Fix port reading + freq 4 KHz + 88-sio: named channels --- .../net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java | 6 +++--- .../net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java | 2 ++ .../emustudio/plugins/device/mits88sio/ControlChannel.java | 5 +++++ .../net/emustudio/plugins/device/mits88sio/DataChannel.java | 5 +++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java index 232ee9d4e..6fd5f164f 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/ContextZ80Impl.java @@ -31,7 +31,7 @@ @ThreadSafe public final class ContextZ80Impl implements ContextZ80 { - public final static int DEFAULT_FREQUENCY_KHZ = 20000; + public final static int DEFAULT_FREQUENCY_KHZ = 4000; private final static byte NO_DATA = (byte) 0xFF; private final static Logger LOGGER = LoggerFactory.getLogger(ContextZ80Impl.class); private final ConcurrentMap> devices = new ConcurrentHashMap<>(); @@ -68,14 +68,14 @@ void clearDevices() { } void writeIO(int port, byte val) { - DeviceContext device = devices.get(port); + DeviceContext device = devices.get(port & 0xFF); if (device != null) { device.writeData(val); } } byte readIO(int port) { - DeviceContext device = devices.get(port); + DeviceContext device = devices.get(port & 0xFF); if (device != null) { return device.readData(); } diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 81734b5bc..e06a45835 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -252,6 +252,8 @@ private int dispatch() throws Throwable { interruptSkip = false; // See EI } else if (IFF[0] && !pendingInterrupts.isEmpty()) { return doInterrupt(); + } else if (!pendingInterrupts.isEmpty()) { + pendingInterrupts.poll(); // if interrupts are disabled, ignore it; otherwise stack overflow } return DISPATCH(DISPATCH_TABLE); } finally { diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java index f49a92a72..66100a337 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/ControlChannel.java @@ -43,4 +43,9 @@ public void writeData(Byte data) { public Class getDataType() { return Byte.class; } + + @Override + public String toString() { + return "88-SIO Control Channel"; + } } diff --git a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java index 5f5774bd9..2d8311094 100644 --- a/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java +++ b/plugins/device/88-sio/src/main/java/net/emustudio/plugins/device/mits88sio/DataChannel.java @@ -62,4 +62,9 @@ private byte mapCharacter(byte data) { } return data; } + + @Override + public String toString() { + return "88 SIO Data Channel"; + } } From 28f329d989aa13f18e80fc63468ca0db7b43c440 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 3 Feb 2023 11:13:40 +0100 Subject: [PATCH 258/314] [#315] z80-cpu,8080-cpu: freq in settings --- .../net/emustudio/plugins/cpu/intel8080/Context8080Impl.java | 3 ++- .../main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java | 1 + .../net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java | 2 +- .../main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java | 1 + .../net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java | 2 +- 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java index d9d914046..9ec2c2476 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/Context8080Impl.java @@ -29,12 +29,13 @@ @ThreadSafe public class Context8080Impl implements Context8080 { + public final static int DEFAULT_FREQUENCY_KHZ = 2000; private final static Logger LOGGER = LoggerFactory.getLogger(Context8080Impl.class); private final ConcurrentMap> devices = new ConcurrentHashMap<>(); private volatile EmulatorEngine cpu; - private volatile int clockFrequency = 2000; // kHz + private volatile int clockFrequency = DEFAULT_FREQUENCY_KHZ; public void setCpu(EmulatorEngine cpu) { this.cpu = cpu; diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java index 65ef6f054..4248cf132 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/CpuImpl.java @@ -72,6 +72,7 @@ public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings sett "Could not register CPU Context. Please see log file for details.", super.getTitle() ); } + context.setCPUFrequency(settings.getInt("frequency_khz", Context8080Impl.DEFAULT_FREQUENCY_KHZ)); initializer = new InitializerFor8080( this, pluginID, applicationApi.getContextPool(), settings, context ); diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java index b4df22d6d..012f4fb46 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/gui/StatusPanel.java @@ -255,7 +255,7 @@ private void initComponents() { lblRun.setForeground(new java.awt.Color(0, 102, 0)); SpinnerNumberModel spFrequencyModel = new SpinnerNumberModel(); - spFrequencyModel.setValue(2000); + spFrequencyModel.setValue(context.getCPUFrequency()); spFrequencyModel.setStepSize(100); spnFrequency.setModel(spFrequencyModel); lblKHZ.setFont(lblKHZ.getFont().deriveFont(lblKHZ.getFont().getStyle() | java.awt.Font.BOLD)); diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java index b2d20cffe..93f92a2a7 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/CpuImpl.java @@ -74,6 +74,7 @@ public CpuImpl(long pluginID, ApplicationApi applicationApi, PluginSettings sett "Could not register Z80 CPU context. Please see log file for more details.", getTitle() ); } + context.setCPUFrequency(settings.getInt("frequency_khz", ContextZ80Impl.DEFAULT_FREQUENCY_KHZ)); initializer = new InitializerZ80( this, pluginID, applicationApi.getContextPool(), settings, context diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java index 52bce665e..d69ac47ab 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/gui/StatusPanel.java @@ -732,7 +732,7 @@ private void initComponents() { jLabel31.setText("CPU Frequency:"); - spnFrequency.setModel(new SpinnerNumberModel(20000, 1, null, 100)); + spnFrequency.setModel(new SpinnerNumberModel(context.getCPUFrequency(), 1, null, 100)); spnFrequency.setName("CPU frequency"); jLabel33.setFont(jLabel33.getFont().deriveFont(jLabel33.getFont().getStyle() | java.awt.Font.BOLD)); From 7119e5b5300aeaecbfccb57f0b4d2e388a7a4905 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 3 Feb 2023 12:06:54 +0100 Subject: [PATCH 259/314] [#315] z80-cpu: flags XY test checker impl --- .../plugins/cpu/zilogZ80/ArithmeticTest.java | 11 +++++++++-- .../emustudio/plugins/cpu/zilogZ80/IOTest.java | 1 + .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java index db7cc1269..8b0c9047a 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java @@ -872,10 +872,15 @@ public void testSBC_A_IYL() { private ByteTestBuilder additionTestBuilder() { + FlagsCheckImpl flagsCheck = new FlagsCheckImpl() + .sign().zero().carry().halfCarry().overflow() + .subtractionIsReset() + .xy(); + return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) + .verifyFlagsOfLastOp(flagsCheck) .keepCurrentInjectorsAfterRun(); } @@ -886,7 +891,9 @@ private ByteTestBuilder subtractionTestBuilder() { .verifyFlagsOfLastOp(new FlagsCheckImpl() .sign().zero().borrow() .halfBorrow() - .overflowSub().subtractionIsSet()) + .overflowSub() + .subtractionIsSet() + .xy()) .keepCurrentInjectorsAfterRun(); } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java index d0aafa7c7..9aa679dca 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java @@ -18,6 +18,7 @@ */ package net.emustudio.plugins.cpu.zilogZ80; +import net.emustudio.cpu.testsuite.FlagsCheck; import net.emustudio.cpu.testsuite.Generator; import net.emustudio.cpu.testsuite.RunnerContext; import net.emustudio.plugins.cpu.zilogZ80.suite.ByteTestBuilder; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java index 749bc3212..07f10618b 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java @@ -402,4 +402,21 @@ public FlagsCheckImpl signIsPreserved() { }); return this; } + + public FlagsCheckImpl xy() { + evaluators.add((context, result) -> { + int flagxy = result & (FLAG_X | FLAG_Y); + if ((flagxy & FLAG_X) == FLAG_X) { + expectedFlags |= FLAG_X; + } else { + expectedNotFlags |= FLAG_X; + } + if ((flagxy & FLAG_Y) == FLAG_Y) { + expectedFlags |= FLAG_Y; + } else { + expectedNotFlags |= FLAG_Y; + } + }); + return this; + } } From 58f09374708e1fb4e73d5be6aea44d30b9e3f9d8 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 14 Feb 2023 11:37:46 +0100 Subject: [PATCH 260/314] [#315] Upgrade edigen-gradle-plugin to 1.5.2 --- plugins/cpu/8080-cpu/build.gradle | 2 +- plugins/cpu/brainduck-cpu/build.gradle | 2 +- plugins/cpu/ssem-cpu/build.gradle | 2 +- plugins/cpu/z80-cpu/build.gradle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/cpu/8080-cpu/build.gradle b/plugins/cpu/8080-cpu/build.gradle index 42fb2efac..96f353364 100644 --- a/plugins/cpu/8080-cpu/build.gradle +++ b/plugins/cpu/8080-cpu/build.gradle @@ -28,7 +28,7 @@ buildscript { plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.5.1' + id 'net.emustudio.edigen-plugin' version '1.5.2' id 'com.adarshr.test-logger' version '3.1.0' } diff --git a/plugins/cpu/brainduck-cpu/build.gradle b/plugins/cpu/brainduck-cpu/build.gradle index 56d00ff49..5bc60f82f 100644 --- a/plugins/cpu/brainduck-cpu/build.gradle +++ b/plugins/cpu/brainduck-cpu/build.gradle @@ -21,7 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.5.1' + id 'net.emustudio.edigen-plugin' version '1.5.2' id 'com.adarshr.test-logger' version '3.1.0' } diff --git a/plugins/cpu/ssem-cpu/build.gradle b/plugins/cpu/ssem-cpu/build.gradle index 9b0c6b234..3b81bf472 100644 --- a/plugins/cpu/ssem-cpu/build.gradle +++ b/plugins/cpu/ssem-cpu/build.gradle @@ -28,7 +28,7 @@ buildscript { plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.5.1' + id 'net.emustudio.edigen-plugin' version '1.5.2' id 'com.adarshr.test-logger' version '3.1.0' } diff --git a/plugins/cpu/z80-cpu/build.gradle b/plugins/cpu/z80-cpu/build.gradle index 23e7aa4e8..55f124fbb 100644 --- a/plugins/cpu/z80-cpu/build.gradle +++ b/plugins/cpu/z80-cpu/build.gradle @@ -21,7 +21,7 @@ import org.apache.tools.ant.filters.ReplaceTokens plugins { id 'java' - id 'net.emustudio.edigen-plugin' version '1.5.1' + id 'net.emustudio.edigen-plugin' version '1.5.2' id 'com.adarshr.test-logger' version '3.1.0' } From 06c9f0cf8b37246dc5307fe1f329a9e7d154648e Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 14 Feb 2023 14:31:02 +0100 Subject: [PATCH 261/314] [#260, #315] Fix Z80 disassembler, add missing instructions --- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 531 ++- .../plugins/cpu/zilogZ80/DispatchTables.java | 1028 +++-- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 3525 +++++++++++------ .../plugins/cpu/zilogZ80/ArithmeticTest.java | 230 +- .../plugins/cpu/zilogZ80/BitTest.java | 279 -- .../cpu/zilogZ80/DisassemblerTest.java | 32 +- .../plugins/cpu/zilogZ80/IOTest.java | 52 +- .../cpu/zilogZ80/InstructionsTest.java | 12 +- .../plugins/cpu/zilogZ80/LogicTest.java | 315 +- .../plugins/cpu/zilogZ80/TransferTest.java | 37 +- .../plugins/cpu/zilogZ80/Z80Tests.java | 421 ++ .../cpu/zilogZ80/suite/ByteTestBuilder.java | 34 + .../cpu/zilogZ80/suite/CpuRunnerImpl.java | 4 + .../cpu/zilogZ80/suite/FlagsCheckImpl.java | 422 -- .../plugins/cpu/zilogZ80/suite/Utils.java | 7 + 15 files changed, 3769 insertions(+), 3160 deletions(-) create mode 100644 plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/Z80Tests.java delete mode 100644 plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index 85d979742..b3ce3c27a 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -84,165 +84,251 @@ instruction = "call %Xh": 11 001 101 imm16 | # x=3, p=0, q=1, z=5 0xDD ddInstruction | - - "in %s, (c)": 0xED 01 0 r_bcde(2) 000 | # x=1, y=0 r_bcde, z=0 - "in %s, (c)": 0xED 01 10 r_h_l(1) 000 | # x=1, y=10 r_h_l, z=0 - "in a, (c)": 0xED 01 111 000 | # x=1, y=7, z=0 - "in (c)": 0xED 01 110 000 | # x=1, y=6, z=0 - "out (c), %s": 0xED 01 0 r_bcde(2) 001 | # x=1, y=0 r_bcde, z=1 - "out (c), %s": 0xED 01 10 r_h_l(1) 001 | # x=1, y=10 r_h_l, z=1 - "out (c), a": 0xED 01 111 001 | # x=1, y=7, z=1 - "out (c), 0": 0xED 01 110 001 | # x=1, y=6, z=1 - "sbc hl, %s": 0xED 01 rp(2) 0 010 | # x=1, p=rp, q=0, z=2 - "adc hl, %s": 0xED 01 rp(2) 1 010 | # x=1, p=rp, q=1, z=2 - "ld (%Xh), %s": 0xED 01 rp(2) 0 011 ref16_2 | # x=1, p=rp, q=0, z=3 - "ld %s, (%Xh)": 0xED 01 rp(2) 1 011 ref16 | # x=1, p=rp, q=1, z=3 - "neg": 0xED 01 any(3) 100 | # x=1, y=any, z=4 - "reti": 0xED 01 001 101 | # x=1, y=1, z=5 - "retn": 0xED 01 any2(2) 0 101 | # x=1, y!=1, z=5 - "retn": 0xED 01 10 1 101 | # x=1, y!=1, z=5 - "retn": 0xED 01 01 1 101 | # x=1, y!=1, z=5 - "retn": 0xED 01 11 1 101 | # x=1, y!=1, z=5 - "im %s": 0xED 01 im(3) 110 | # x=1, y=im, z=6 - "ld i, a": 0xED 01 000 111 | # x=1, y=0, z=7 - "ld r, a": 0xED 01 001 111 | # x=1, y=1, z=7 - "ld a, i": 0xED 01 010 111 | # x=1, y=2, z=7 - "ld a, r": 0xED 01 011 111 | # x=1, y=3, z=7 - "rrd": 0xED 01 100 111 | # x=1, y=4, z=7 - "rld": 0xED 01 101 111 | # x=1, y=5, z=7 - "nop": 0xED 01 110 111 | # x=1, y=6, z=7 - "nop": 0xED 01 111 111 | # x=1, y=7, z=7 - - "ldi": 0xED 10 100 000 | # x=2, y=4, z=0 - "ldd": 0xED 10 101 000 | # x=2, y=5, z=0 - "ldir": 0xED 10 110 000 | # x=2, y=6, z=0 - "lddr": 0xED 10 111 000 | # x=2, y=7, z=0 - - "cpi": 0xED 10 100 001 | # x=2, y=4, z=1 - "cpd": 0xED 10 101 001 | # x=2, y=5, z=1 - "cpir": 0xED 10 110 001 | # x=2, y=6, z=1 - "cpdr": 0xED 10 111 001 | # x=2, y=7, z=1 - - "ini": 0xED 10 100 010 | # x=2, y=4, z=2 - "ind": 0xED 10 101 010 | # x=2, y=5, z=2 - "inir": 0xED 10 110 010 | # x=2, y=6, z=2 - "indr": 0xED 10 111 010 | # x=2, y=7, z=2 - - "outi": 0xED 10 100 011 | # x=2, y=4, z=3 - "outd": 0xED 10 101 011 | # x=2, y=5, z=3 - "otir": 0xED 10 110 011 | # x=2, y=6, z=3 - "otdr": 0xED 10 111 011 | # x=2, y=7, z=3 - - "nop": 0xED 00 any6(6) | - "nop": 0xED 11 any6(6) | - "nop": 0xED 10 0 any5(5) | - "nop": 0xED 10 1 001 any2(2) | - "nop": 0xED 10 1 011 any2(2) | - "nop": 0xED 10 1 101 any2(2) | - "nop": 0xED 10 1 111 any2(2) | - + 0xED edInstruction | 0xFD fdInstruction | "%s %Xh": 11 alu(3) 110 imm8 | # x=3, y=alu, z=6 "rst %sh": 11 rst(3) 111 ; # x=3, y=rst, z=7 +edInstruction = + "in %s, (c)": 01 0 r_bcde(2) 000 | # x=1, y=0 r_bcde, z=0 + "in %s, (c)": 01 10 r_h_l(1) 000 | # x=1, y=10 r_h_l, z=0 + "in a, (c)": 01 111 000 | # x=1, y=7, z=0 + "in (c)": 01 110 000 | # x=1, y=6, z=0 + "out (c), %s": 01 0 r_bcde(2) 001 | # x=1, y=0 r_bcde, z=1 + "out (c), %s": 01 10 r_h_l(1) 001 | # x=1, y=10 r_h_l, z=1 + "out (c), a": 01 111 001 | # x=1, y=7, z=1 + "out (c), 0": 01 110 001 | # x=1, y=6, z=1 + "sbc hl, %s": 01 rp(2) 0 010 | # x=1, p=rp, q=0, z=2 + "adc hl, %s": 01 rp(2) 1 010 | # x=1, p=rp, q=1, z=2 + "ld (%Xh), %s": 01 rp(2) 0 011 ref16_2 | # x=1, p=rp, q=0, z=3 + "ld %s, (%Xh)": 01 rp(2) 1 011 ref16 | # x=1, p=rp, q=1, z=3 + "neg": 01 any(3) 100 | # x=1, y=any, z=4 + "reti": 01 001 101 | # x=1, y=1, z=5 + "retn": 01 any2(2) 0 101 | # x=1, y!=1, z=5 + "retn": 01 10 1 101 | # x=1, y!=1, z=5 + "retn": 01 01 1 101 | # x=1, y!=1, z=5 + "retn": 01 11 1 101 | # x=1, y!=1, z=5 + "im %s": 01 im(3) 110 | # x=1, y=im, z=6 + "ld i, a": 01 000 111 | # x=1, y=0, z=7 + "ld r, a": 01 001 111 | # x=1, y=1, z=7 + "ld a, i": 01 010 111 | # x=1, y=2, z=7 + "ld a, r": 01 011 111 | # x=1, y=3, z=7 + "rrd": 01 100 111 | # x=1, y=4, z=7 + "rld": 01 101 111 | # x=1, y=5, z=7 + "nop": 01 110 111 | # x=1, y=6, z=7 + "nop": 01 111 111 | # x=1, y=7, z=7 + + "ldi": 10 100 000 | # x=2, y=4, z=0 + "ldd": 10 101 000 | # x=2, y=5, z=0 + "ldir": 10 110 000 | # x=2, y=6, z=0 + "lddr": 10 111 000 | # x=2, y=7, z=0 + + "cpi": 10 100 001 | # x=2, y=4, z=1 + "cpd": 10 101 001 | # x=2, y=5, z=1 + "cpir": 10 110 001 | # x=2, y=6, z=1 + "cpdr": 10 111 001 | # x=2, y=7, z=1 + + "ini": 10 100 010 | # x=2, y=4, z=2 + "ind": 10 101 010 | # x=2, y=5, z=2 + "inir": 10 110 010 | # x=2, y=6, z=2 + "indr": 10 111 010 | # x=2, y=7, z=2 + + "outi": 10 100 011 | # x=2, y=4, z=3 + "outd": 10 101 011 | # x=2, y=5, z=3 + "otir": 10 110 011 | # x=2, y=6, z=3 + "otdr": 10 111 011 | # x=2, y=7, z=3 + + "nop": 00 any6(6) | + "nop": 11 any6(6) | + "nop": 10 0 any5(5) | + "nop": 10 1 001 any2(2) | + "nop": 10 1 011 any2(2) | + "nop": 10 1 101 any2(2) | + "nop": 10 1 111 any2(2); + ddInstruction = - "ld ix, %Xh": 00 100 001 imm16 | # x=0, p=2, q=0, z=1 - "add ix, %s": 00 rp_ix(2) 1 001 | # x=0, p=rp_ix, q=1, z=1 - "ld (%Xh), ix": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 - "ld ix, (%Xh)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 - "inc ix": 00 100 011 | # x=0, p=2, q=0, z=3 - "dec ix": 00 101 011 | # x=0, p=2, q=1, z=3 - "inc %s": 00 10 r_ixhl(1) 100 | # x=0, y=r_ixhl, z=4 - "inc (ix+%Xh)": 00 110 100 disp | # x=0, y=6, z=4 - "dec %s": 00 10 r_ixhl(1) 101 | # x=0, y=r_ixhl, z=5 - "dec (ix+%Xh)": 00 110 101 disp | # x=0, y=6, z=5 - "ld %s, %Xh": 00 10 r_ixhl(1) 110 imm8 | # x=0, y=r_ixhl, z=6 - "ld (ix+%Xh), %Xh": 00 110 110 disp(8) imm8 | # x=0, y=6, z=6 - "ld %s, %s": 01 10 r_ixhl(1) 0 r_bcde(2) | # x=1, y=r_ixhl, z=r_bcde - "ld %s, %s": 01 10 r_ixhl(1) 10 r_ixhl2(1) | # x=1, y=r_ixhl, z=r_ixhl2 - "ld %s, a": 01 10 r_ixhl(1) 111 | # x=1, y=r_ixhl, z=a - "ld a, %s": 01 111 10 r_ixhl(1) | # x=1, y=7, z=r_ixhl - "ld a, %s": 01 111 0 r_bcde(2) | # x=1, y=7, z=r_bcde - "ld a, a": 01 111 111 | # x=1, y=7, z=a - "ld %s, a": 01 0 r_bcde(2) 111 | # x=1, y=r_bcde, z=a - "ld %s, %s": 01 0 r_bcde(2) 0 r_bcde2(2) | # x=1, y=r_bcde, z=r_bcde2 - "ld %s, %s": 01 0 r_bcde(2) 10 r_ixhl2(1) | # x=1, y=r_bcde, z=r_ixhl2 - "ld (ix+%Xh), %s": 01 110 r_no_hl(3) disp | # x=1, y=6, z=r_no_hl - "ld %s, (ix+%Xh)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 - "ld %s, (ix+%Xh)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l, z=6 - "ld a, (ix+%Xh)": 01 111 110 disp | # x=1, y=7, z=6 - - "%s %s": 10 alu(3) 0 r_bcde(2) | # x=2, y=alu, z=r_bcde - "%s a": 10 alu(3) 111 | # x=2, y=alu, z=a - "%s %s": 10 alu(3) 10 r_ixhl(1) | # x=2, y=alu, z=r_ixhl - "%s (ix+%Xh)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 - - "pop ix": 11 100 001 | # x=3, p=2, q=0, z=1 - "jp (ix)": 11 101 001 | # x=3, p=2, q=1, z=1 - "ld sp, ix": 11 111 001 | # x=3, p=3, q=1, z=1 - - "nop": 00 000 any3(3) | - "nop": 00 001 1 any2(2) | - "nop": 00 010 any3(3) | - "nop": 00 011 1 any2(2) | - "nop": 00 100000 | - "nop": 11 01 any4(4) | - "nop": 11 100000 | - - 0xCB disp(8) ddcbInstruction | - - "ex (sp), ix": 11 100 011 | # x=3, y=4, z=3 - "push ix": 11 100 101 ; # x=3, p=2, q=0, z=5 + "nop": 00 000 000 | # x=0, y=0, z=0 + "ex af, af'": 00 001 000 | # x=0, y=1, z=0 + "djnz %Xh": 00 010 000 imm8 | # x=0, y=2, z=0 + "jr %Xh": 00 011 000 imm8 | # x=0, y=3, z=0 + "jr %s, %Xh": 00 1 cc_jr(2) 000 imm8 | # x=0, y=4..7, z=0 + "ld %s, %Xh": 00 rp_ix(2) 0 001 imm16 | # x=0, p=rp, q=0, z=1 + "add ix, %s": 00 rp_ix(2) 1 001 | # x=0, p=rp, q=1, z=1 + "ld (bc), a": 00 000 010 | # x=0, p=0, q=0, z=2 + "ld (de), a": 00 010 010 | # x=0, p=1, q=0, z=2 + "ld (%Xh), ix": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 + "ld (%Xh), a": 00 110 010 ref16 | # x=0, p=3, q=0, z=2 + "ld a, (bc)": 00 001 010 | # x=0, p=0, q=1, z=2 + "ld a, (de)": 00 011 010 | # x=0, p=1, q=1, z=2 + "ld ix, (%Xh)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 + "ld a, (%Xh)": 00 111 010 ref16 | # x=0, p=3, q=1, z=2 + "inc %s": 00 rp_ix(2) 0 011 | # x=0, p=rp, q=0, z=3 + "dec %s": 00 rp_ix(2) 1 011 | # x=0, p=rp, q=1, z=3 + "inc %s": 00 0 r_bcde(2) 100 | # x=0, y=r, z=4 + "inc %s": 00 10 r_ixhl(1) 100 | # x=0, y=r, z=4 + "inc (ix+%Xh)": 00 110 100 disp | # x=0, y=6, z=4 + "inc a": 00 111 100 | # x=0, y=r, z=4 + "dec %s": 00 0 r_bcde(2) 101 | # x=0, y=r, z=5 + "dec %s": 00 10 r_ixhl(1) 101 | # x=0, y=r, z=5 + "dec (ix+%Xh)": 00 110 101 disp | # x=0, y=6, z=5 + "dec a": 00 111 101 | # x=0, y=r, z=5 + "ld %s, %Xh": 00 0 r_bcde(2) 110 imm8 | # x=0, y=r, z=6 + "ld %s, %Xh": 00 10 r_ixhl(1) 110 imm8 | # x=0, y=r, z=6 + "ld (ix+%Xh), %Xh": 00 110 110 disp(8) imm8 | # x=0, y=r, z=6 + "ld a, %Xh": 00 111 110 imm8 | # x=0, y=r, z=6 + "rlca": 00 000 111 | # x=0, y=0, z=7 + "rrca": 00 001 111 | # x=0, y=1, z=7 + "rla": 00 010 111 | # x=0, y=2, z=7 + "rra": 00 011 111 | # x=0, y=3, z=7 + "daa": 00 100 111 | # x=0, y=4, z=7 + "cpl": 00 101 111 | # x=0, y=5, z=7 + "scf": 00 110 111 | # x=0, y=6, z=7 + "ccf": 00 111 111 | # x=0, y=7, z=7 + + "halt": 01 110 110 | # x=1, y=6, z=6 + "ld %s, %s": 01 0 r_bcde(2) 0 r_bcde2(2) | # x=1, y=0 r_bcde, z=0 r_bcde2 + "ld %s, %s": 01 0 r_bcde(2) 10 r_ixhl(1) | # x=1, y=0 r_bcde, z=10 r_ixhl + "ld %s, a": 01 0 r_bcde(2) 111 | # x=1, y=0 r_bcde, z=7 + "ld %s, (ix+%Xh)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 + "ld %s, %s": 01 10 r_ixhl(1) 0 r_bcde2(2) | # x=1, y=10 r_ixhl(1), z=0 r_bcde2 + "ld %s, %s": 01 10 r_ixhl(1) 10 r_ixhl2(1) | # x=1, y=10 r_ixhl(1), z=10 r_ixhl2 + "ld %s, a": 01 10 r_ixhl(1) 111 | # x=1, y=10 r_ixhl(1), z=7 + "ld %s, (ix+%Xh)": 01 10 r_ixhl(1) 110 disp | # x=1, y=10 r_ixhl(1), z=6 + "ld a, %s": 01 111 0 r_bcde(2) | # x=1, y=7, z=0 r_bcde + "ld a, %s": 01 111 10 r_ixhl(1) | # x=1, y=7, z=10 r_ixhl + "ld a, a": 01 111 111 | # x=1, y=7, z=7 + "ld a, (ix+%Xh)": 01 111 110 disp | # x=1, y=7, z=6 + "ld (ix+%Xh), %s": 01 110 0 r_bcde(2) disp | # x=1, y=6, z=0 r_bcde + "ld (ix+%Xh), %s": 01 110 10 r_ixhl2(1) disp | # x=1, y=6, z=10 r_ixhl2 + "ld (ix+%Xh), a": 01 110 111 disp | # x=1, y=6, z=7 + + "%s %s": 10 alu(3) 0 r_bcde(2) | # x=2, y=alu, z=r + "%s %s": 10 alu(3) 10 r_ixhl(1) | # x=2, y=alu, z=r + "%s a": 10 alu(3) 111 | # x=2, y=alu, z=r + "%s (ix+%Xh)": 10 alu(3) 110 disp | # x=2, y=alu, z=r + + "ret %s": 11 cc(3) 000 | # x=3, y=cc, z=0 + "pop %s": 11 rpx2(2) 0 001 | # x=3, p=rpx2, q=0, z=1 + "ret": 11 001 001 | # x=3, p=0, q=1, z=1 + "exx": 11 011 001 | # x=3, p=1, q=1, z=1 + "jp (ix)": 11 101 001 | # x=3, p=2, q=1, z=1 + "ld sp, ix": 11 111 001 | # x=3, p=3, q=1, z=1 + "jp %s, %Xh": 11 cc(3) 010 imm16 | # x=3, y=cc, z=2 + "jp %Xh": 11 000 011 imm16 | # x=3, y=0, z=3 + + 0xCB disp(8) ddcbInstruction | + + "out (%Xh), a": 11 010 011 ref8 | # x=3, y=2, z=3 + "in a, (%Xh)": 11 011 011 ref8 | # x=3, y=3, z=3 + "ex (sp), ix": 11 100 011 | # x=3, y=4, z=3 + "ex de, hl": 11 101 011 | # x=3, y=5, z=3 + "di": 11 110 011 | # x=3, y=6, z=3 + "ei": 11 111 011 | # x=3, y=7, z=3 + "call %s, %Xh": 11 cc(3) 100 imm16 | # x=3, y=cc, z=4 + "push %s": 11 rpx2(2) 0 101 | # x=3, p=rpx2, q=0, z=5 + "call %Xh": 11 001 101 imm16 | # x=3, p=0, q=1, z=5 + + // Stack overflow + // 0xDD ddInstruction | + // 0xFD fdInstruction | + 0xED edInstruction | + + "%s %Xh": 11 alu(3) 110 imm8 | # x=3, y=alu, z=6 + "rst %sh": 11 rst(3) 111 ; # x=3, y=rst, z=7 + fdInstruction = - "ld iy, %Xh": 00 100 001 imm16 | # x=0, p=2, q=0, z=1 - "add iy, %s": 00 rp_iy(2) 1 001 | # x=0, p=rp_iy, q=1, z=1 - "ld (%Xh), iy": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 - "ld iy, (%Xh)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 - "inc iy": 00 100 011 | # x=0, p=2, q=0, z=3 - "dec iy": 00 101 011 | # x=0, p=2, q=1, z=3 - "inc %s": 00 10 r_iyhl(1) 100 | # x=0, y=r_iyhl, z=4 - "inc (iy+%Xh)": 00 110 100 disp | # x=0, y=6, z=4 - "dec %s": 00 10 r_iyhl(1) 101 | # x=0, y=r_iyhl, z=5 - "dec (iy+%Xh)": 00 110 101 disp | # x=0, y=6, z=5 - "ld %s, %Xh": 00 10 r_iyhl(1) 110 imm8 | # x=0, y=r_iyhl, z=6 - "ld (iy+%Xh), %Xh": 00 110 110 disp(8) imm8 | # x=0, y=6, z=6 - "ld %s, %s": 01 10 r_iyhl(1) 0 r_bcde(2) | # x=1, y=r_iyhl, z=r_bcde - "ld %s, %s": 01 10 r_iyhl(1) 10 r_iyhl2(1) | # x=1, y=r_iyhl, z=r_iyhl2 - "ld %s, a": 01 10 r_iyhl(1) 111 | # x=1, y=r_iyhl, z=7 - "ld a, %s": 01 111 10 r_iyhl(1) | # x=1, y=7, z=r_iyhl - "ld a, %s": 01 111 0 r_bcde(2) | # x=1, y=7, z=r_bcde - "ld a, a": 01 111 111 | # x=1, y=7, z=a - "ld %s, a": 01 0 r_bcde(2) 111 | # x=1, y=r_bcde, z=a - "ld %s, %s": 01 0 r_bcde(2) 0 r_bcde2(2) | # x=1, y=r_bcde, z=r_iyhl2 - "ld %s, %s": 01 0 r_bcde(2) 10 r_iyhl2(1) | # x=1, y=r_bcde, z=r_iyhl2 - "ld (iy+%Xh), %s": 01 110 r_no_hl(3) disp | # x=1, y=6, z=r_no_hl - "ld %s, (iy+%Xh)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 - "ld %s, (iy+%Xh)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l, z=6 - "ld a, (iy+%Xh)": 01 111 110 disp | # x=1, y=7, z=6 - - "%s %s": 10 alu(3) 0 r_bcde(2) | # x=2, y=alu, z=r_bcde - "%s a": 10 alu(3) 111 | # x=2, y=alu, z=a - "%s %s": 10 alu(3) 10 r_iyhl(1) | # x=2, y=alu, z=r_iyhl - "%s (iy+%Xh)": 10 alu(3) 110 disp | # x=2, y=alu, z=6 - - "pop iy": 11 100 001 | # x=3, p=2, q=0, z=1 - "jp (iy)": 11 101 001 | # x=3, p=2, q=1, z=1 - "ld sp, iy": 11 111 001 | # x=3, p=3, q=1, z=1 - - "nop": 00 000 any3(3) | - "nop": 00 001 1 any2(2) | - "nop": 00 010 any3(3) | - "nop": 00 011 1 any2(2) | - "nop": 00 100000 | - "nop": 11 01 any4(4) | - "nop": 11 100000 | - - 0xCB disp(8) fdcbInstruction | - - "ex (sp), iy": 11 100 011 | # x=3, y=4, z=3 - "push iy": 11 100 101 ; # x=3, p=2, q=0, z=5 + "nop": 00 000 000 | # x=0, y=0, z=0 + "ex af, af'": 00 001 000 | # x=0, y=1, z=0 + "djnz %Xh": 00 010 000 imm8 | # x=0, y=2, z=0 + "jr %Xh": 00 011 000 imm8 | # x=0, y=3, z=0 + "jr %s, %Xh": 00 1 cc_jr(2) 000 imm8 | # x=0, y=4..7, z=0 + "ld %s, %Xh": 00 rp_iy(2) 0 001 imm16 | # x=0, p=rp, q=0, z=1 + "add iy, %s": 00 rp_iy(2) 1 001 | # x=0, p=rp, q=1, z=1 + "ld (bc), a": 00 000 010 | # x=0, p=0, q=0, z=2 + "ld (de), a": 00 010 010 | # x=0, p=1, q=0, z=2 + "ld (%Xh), iy": 00 100 010 ref16 | # x=0, p=2, q=0, z=2 + "ld (%Xh), a": 00 110 010 ref16 | # x=0, p=3, q=0, z=2 + "ld a, (bc)": 00 001 010 | # x=0, p=0, q=1, z=2 + "ld a, (de)": 00 011 010 | # x=0, p=1, q=1, z=2 + "ld iy, (%Xh)": 00 101 010 ref16 | # x=0, p=2, q=1, z=2 + "ld a, (%Xh)": 00 111 010 ref16 | # x=0, p=3, q=1, z=2 + "inc %s": 00 rp_iy(2) 0 011 | # x=0, p=rp, q=0, z=3 + "dec %s": 00 rp_iy(2) 1 011 | # x=0, p=rp, q=1, z=3 + "inc %s": 00 0 r_bcde(2) 100 | # x=0, y=r, z=4 + "inc %s": 00 10 r_iyhl(1) 100 | # x=0, y=r, z=4 + "inc (iy+%Xh)": 00 110 100 disp | # x=0, y=6, z=4 + "inc a": 00 111 100 | # x=0, y=r, z=4 + "dec %s": 00 0 r_bcde(2) 101 | # x=0, y=r, z=5 + "dec %s": 00 10 r_iyhl(1) 101 | # x=0, y=r, z=5 + "dec (iy+%Xh)": 00 110 101 disp | # x=0, y=6, z=5 + "dec a": 00 111 101 | # x=0, y=r, z=5 + "ld %s, %Xh": 00 0 r_bcde(2) 110 imm8 | # x=0, y=r, z=6 + "ld %s, %Xh": 00 10 r_iyhl(1) 110 imm8 | # x=0, y=r, z=6 + "ld (iy+%Xh), %Xh": 00 110 110 disp(8) imm8 | # x=0, y=r, z=6 + "ld a, %Xh": 00 111 110 imm8 | # x=0, y=r, z=6 + "rlca": 00 000 111 | # x=0, y=0, z=7 + "rrca": 00 001 111 | # x=0, y=1, z=7 + "rla": 00 010 111 | # x=0, y=2, z=7 + "rra": 00 011 111 | # x=0, y=3, z=7 + "daa": 00 100 111 | # x=0, y=4, z=7 + "cpl": 00 101 111 | # x=0, y=5, z=7 + "scf": 00 110 111 | # x=0, y=6, z=7 + "ccf": 00 111 111 | # x=0, y=7, z=7 + + "halt": 01 110 110 | # x=1, y=6, z=6 + "ld %s, %s": 01 0 r_bcde(2) 0 r_bcde2(2) | # x=1, y=0 r_bcde, z=0 r_bcde2 + "ld %s, %s": 01 0 r_bcde(2) 10 r_iyhl(1) | # x=1, y=0 r_bcde, z=10 r_iyhl + "ld %s, a": 01 0 r_bcde(2) 111 | # x=1, y=0 r_bcde, z=7 + "ld %s, (iy+%Xh)": 01 0 r_bcde(2) 110 disp | # x=1, y=0 r_bcde, z=6 + "ld %s, %s": 01 10 r_iyhl(1) 0 r_bcde2(2) | # x=1, y=10 r_iyhl(1), z=0 r_bcde2 + "ld %s, %s": 01 10 r_iyhl(1) 10 r_iyhl2(1) | # x=1, y=10 r_iyhl(1), z=10 r_iyhl2 + "ld %s, a": 01 10 r_iyhl(1) 111 | # x=1, y=10 r_iyhl(1), z=7 + "ld %s, (iy+%Xh)": 01 10 r_iyhl(1) 110 disp | # x=1, y=10 r_iyhl(1), z=6 + "ld a, %s": 01 111 0 r_bcde(2) | # x=1, y=7, z=0 r_bcde + "ld a, %s": 01 111 10 r_iyhl(1) | # x=1, y=7, z=10 r_iyhl + "ld a, a": 01 111 111 | # x=1, y=7, z=7 + "ld a, (iy+%Xh)": 01 111 110 disp | # x=1, y=7, z=6 + "ld (iy+%Xh), %s": 01 110 0 r_bcde(2) disp | # x=1, y=6, z=0 r_bcde + "ld (iy+%Xh), %s": 01 110 10 r_iyhl2(1) disp | # x=1, y=6, z=10 r_iyhl2 + "ld (iy+%Xh), a": 01 110 111 disp | # x=1, y=6, z=7 + + "%s %s": 10 alu(3) 0 r_bcde(2) | # x=2, y=alu, z=r + "%s %s": 10 alu(3) 10 r_iyhl(1) | # x=2, y=alu, z=r + "%s a": 10 alu(3) 111 | # x=2, y=alu, z=r + "%s (iy+%Xh)": 10 alu(3) 110 disp | # x=2, y=alu, z=r + + "ret %s": 11 cc(3) 000 | # x=3, y=cc, z=0 + "pop %s": 11 rpy2(2) 0 001 | # x=3, p=rpy2, q=0, z=1 + "ret": 11 001 001 | # x=3, p=0, q=1, z=1 + "exx": 11 011 001 | # x=3, p=1, q=1, z=1 + "jp (iy)": 11 101 001 | # x=3, p=2, q=1, z=1 + "ld sp, iy": 11 111 001 | # x=3, p=3, q=1, z=1 + "jp %s, %Xh": 11 cc(3) 010 imm16 | # x=3, y=cc, z=2 + "jp %Xh": 11 000 011 imm16 | # x=3, y=0, z=3 + + 0xCB disp(8) fdcbInstruction | + + "out (%Xh), a": 11 010 011 ref8 | # x=3, y=2, z=3 + "in a, (%Xh)": 11 011 011 ref8 | # x=3, y=3, z=3 + "ex (sp), iy": 11 100 011 | # x=3, y=4, z=3 + "ex de, hl": 11 101 011 | # x=3, y=5, z=3 + "di": 11 110 011 | # x=3, y=6, z=3 + "ei": 11 111 011 | # x=3, y=7, z=3 + "call %s, %Xh": 11 cc(3) 100 imm16 | # x=3, y=cc, z=4 + "push %s": 11 rpy2(2) 0 101 | # x=3, p=rpy2, q=0, z=5 + "call %Xh": 11 001 101 imm16 | # x=3, p=0, q=1, z=5 + + // Stack overflow + // 0xDD ddInstruction | + // 0xFD fdInstruction | + + 0xED edInstruction | + + "%s %Xh": 11 alu(3) 110 imm8 | # x=3, y=alu, z=6 + "rst %sh": 11 rst(3) 111 ; # x=3, y=rst, z=7 + ddcbInstruction = "%s (ix+%Xh), %s": 00 rot(3) 0 r_bcde(2) | # x=0, y=rot, z=0 r_bcde @@ -303,6 +389,18 @@ rp2 = "hl": 10 | "af": 11 ; +rpx2 = + "bc": 00 | + "de": 01 | + "ix": 10 | + "af": 11 ; + +rpy2 = + "bc": 00 | + "de": 01 | + "iy": 10 | + "af": 11 ; + rp_ix = "bc": 00 | "de": 01 | @@ -325,7 +423,7 @@ r = "(hl)": 110 | "a": 111 ; -r_bcde = +r_bcde,r_bcde2 = "b": 00 | "c": 01 | "d": 10 | @@ -338,15 +436,6 @@ r_h_l = r_ixhl,r_ixhl2 = "ixh": 0 | "ixl": 1; r_iyhl,r_iyhl2 = "iyh": 0 | "iyl": 1; -r_no_hl = - "b": 000 | - "c": 001 | - "d": 010 | - "e": 011 | - "h": 100 | - "l": 101 | - "a": 111 ; - alu = "add a,": 000 | "adc a,": 001 | @@ -379,7 +468,10 @@ im = bit,any = bit: bit(3); imm8,ref8,disp = imm8: imm8(8); + +// Use with (reverse_bytes) imm16,ref16,ref16_2 = imm16: imm16(16); + rst = "00": 000 | "08": 001 | "10": 010 | "18": 011 | "20": 100 | "28": 101 | "30": 110 | "38": 111; any2 = 00 | 01 | 10 | 11; @@ -401,78 +493,99 @@ any2 = 00 | 01 | 10 | 11; "%s" = fdcbInstruction bit disp r_h_l; "%s" = fdcbInstruction bit disp; -"%s" = ddInstruction imm16(reverse_bytes); -"%s" = ddInstruction ref16(reverse_bytes); -"%s" = ddInstruction r_ixhl; -"%s" = ddInstruction disp; -"%s" = ddInstruction r_ixhl imm8; -"%s" = ddInstruction disp imm8; -"%s" = ddInstruction r_ixhl r_bcde; -"%s" = ddInstruction r_bcde; "%s" = ddInstruction r_bcde r_bcde2; -"%s" = ddInstruction r_bcde r_ixhl2; +"%s" = ddInstruction r_bcde r_ixhl; +"%s" = ddInstruction disp r_bcde; +"%s" = ddInstruction r_ixhl r_bcde2; "%s" = ddInstruction r_ixhl r_ixhl2; -"%s" = ddInstruction r_bcde disp; -"%s" = ddInstruction r_h_l disp; -"%s" = ddInstruction disp r_no_hl; +"%s" = ddInstruction r_ixhl disp; +"%s" = ddInstruction disp r_ixhl2; +"%s" = ddInstruction cc_jr imm8; +"%s" = ddInstruction rp_ix imm16(reverse_bytes); +"%s" = ddInstruction r_bcde imm8; +"%s" = ddInstruction r_ixhl imm8; +"%s" = ddInstruction disp imm8; +"%s" = ddInstruction cc imm16(reverse_bytes); +"%s" = ddInstruction alu imm8; +"%s" = ddInstruction alu disp; "%s" = ddInstruction alu r_bcde; "%s" = ddInstruction alu r_ixhl; -"%s" = ddInstruction alu disp; "%s" = ddInstruction alu; +"%s" = ddInstruction imm8; "%s" = ddInstruction rp_ix; -"%s" = ddInstruction any4; -"%s" = ddInstruction any3; +"%s" = ddInstruction ref8; +"%s" = ddInstruction ref16(reverse_bytes); +"%s" = ddInstruction r_bcde; +"%s" = ddInstruction r_ixhl; +"%s" = ddInstruction disp; +"%s" = ddInstruction cc; +"%s" = ddInstruction rpx2; +"%s" = ddInstruction imm16(reverse_bytes); +"%s" = ddInstruction rst; "%s" = ddInstruction; -"%s" = fdInstruction imm16(reverse_bytes); -"%s" = fdInstruction ref16(reverse_bytes); -"%s" = fdInstruction r_iyhl; -"%s" = fdInstruction disp; -"%s" = fdInstruction r_iyhl imm8; -"%s" = fdInstruction disp imm8; -"%s" = fdInstruction r_iyhl r_bcde; -"%s" = fdInstruction r_bcde r_iyhl2; -"%s" = fdInstruction r_bcde; "%s" = fdInstruction r_bcde r_bcde2; +"%s" = fdInstruction r_bcde r_iyhl; +"%s" = fdInstruction disp r_bcde; +"%s" = fdInstruction r_iyhl r_bcde2; "%s" = fdInstruction r_iyhl r_iyhl2; -"%s" = fdInstruction disp r_no_hl; -"%s" = fdInstruction r_bcde disp; -"%s" = fdInstruction r_h_l disp; +"%s" = fdInstruction r_iyhl disp; +"%s" = fdInstruction disp r_iyhl2; +"%s" = fdInstruction cc_jr imm8; +"%s" = fdInstruction rp_iy imm16(reverse_bytes); +"%s" = fdInstruction r_bcde imm8; +"%s" = fdInstruction r_iyhl imm8; +"%s" = fdInstruction disp imm8; +"%s" = fdInstruction cc imm16(reverse_bytes); +"%s" = fdInstruction alu imm8; +"%s" = fdInstruction alu disp; "%s" = fdInstruction alu r_bcde; "%s" = fdInstruction alu r_iyhl; -"%s" = fdInstruction alu disp; "%s" = fdInstruction alu; +"%s" = fdInstruction imm8; "%s" = fdInstruction rp_iy; -"%s" = fdInstruction any4; -"%s" = fdInstruction any3; +"%s" = fdInstruction ref8; +"%s" = fdInstruction ref16(reverse_bytes); +"%s" = fdInstruction r_bcde; +"%s" = fdInstruction r_iyhl; +"%s" = fdInstruction disp; +"%s" = fdInstruction cc; +"%s" = fdInstruction rpy2; +"%s" = fdInstruction imm16(reverse_bytes); +"%s" = fdInstruction rst; "%s" = fdInstruction; -"%s" = instruction rp imm16(reverse_bytes); -"%s" = instruction rp ref16(reverse_bytes); -"%s" = instruction ref16_2(reverse_bytes) rp; -"%s" = instruction cc imm16(reverse_bytes); +"%s" = edInstruction r_bcde; +"%s" = edInstruction r_h_l; +"%s" = edInstruction rp; +"%s" = edInstruction ref16_2(reverse_bytes) rp; +"%s" = edInstruction rp ref16(reverse_bytes); +"%s" = edInstruction any; +"%s" = edInstruction im; +"%s" = edInstruction any6; +"%s" = edInstruction any5; +"%s" = edInstruction; + + "%s" = instruction cc_jr imm8; +"%s" = instruction rp imm16(reverse_bytes); +"%s" = instruction r imm8; "%s" = instruction r_bcde r; "%s" = instruction r_h_l r; -"%s" = instruction r imm8; -"%s" = instruction alu r; -"%s" = instruction alu imm8; +"%s" = instruction cc imm16(reverse_bytes); "%s" = instruction rot r; "%s" = instruction bit r; -"%s" = instruction r_bcde; -"%s" = instruction r_h_l; +"%s" = instruction alu imm8; +"%s" = instruction alu r; "%s" = instruction imm8; -"%s" = instruction ref8; -"%s" = instruction imm16(reverse_bytes); -"%s" = instruction ref16(reverse_bytes); "%s" = instruction rp; -"%s" = instruction rp2; +"%s" = instruction ref16(reverse_bytes); "%s" = instruction r; +"%s" = instruction r_bcde; +"%s" = instruction r_h_l; "%s" = instruction cc; -"%s" = instruction im; +"%s" = instruction rp2; +"%s" = instruction ref8; +"%s" = instruction imm16(reverse_bytes); "%s" = instruction rst; -"%s" = instruction any; -"%s" = instruction any6; -"%s" = instruction any5; "%s" = instruction; - diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java index eacf2904c..60c7de252 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java @@ -42,203 +42,203 @@ public class DispatchTables { try { DISPATCH_TABLE[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", retInt); - DISPATCH_TABLE[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", retInt); + DISPATCH_TABLE[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_LD_BC_NN", retInt); DISPATCH_TABLE[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_BC_A", retInt); - DISPATCH_TABLE[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", retInt); - DISPATCH_TABLE[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); - DISPATCH_TABLE[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); - DISPATCH_TABLE[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_INC_BC", retInt); + DISPATCH_TABLE[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_INC_B", retInt); + DISPATCH_TABLE[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_B", retInt); + DISPATCH_TABLE[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_N", retInt); DISPATCH_TABLE[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLCA", retInt); DISPATCH_TABLE[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_EX_AF_AFF", retInt); - DISPATCH_TABLE[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", retInt); + DISPATCH_TABLE[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_BC", retInt); DISPATCH_TABLE[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_BC", retInt); - DISPATCH_TABLE[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", retInt); - DISPATCH_TABLE[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); - DISPATCH_TABLE[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); - DISPATCH_TABLE[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_BC", retInt); + DISPATCH_TABLE[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_C", retInt); + DISPATCH_TABLE[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_C", retInt); + DISPATCH_TABLE[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_N", retInt); DISPATCH_TABLE[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRCA", retInt); DISPATCH_TABLE[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_DJNZ", retInt); - DISPATCH_TABLE[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", retInt); + DISPATCH_TABLE[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_LD_DE_NN", retInt); DISPATCH_TABLE[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_DE_A", retInt); - DISPATCH_TABLE[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", retInt); - DISPATCH_TABLE[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); - DISPATCH_TABLE[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); - DISPATCH_TABLE[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_INC_DE", retInt); + DISPATCH_TABLE[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_INC_D", retInt); + DISPATCH_TABLE[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_D", retInt); + DISPATCH_TABLE[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_N", retInt); DISPATCH_TABLE[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RLA", retInt); DISPATCH_TABLE[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_JR_N", retInt); - DISPATCH_TABLE[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", retInt); + DISPATCH_TABLE[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_DE", retInt); DISPATCH_TABLE[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_DE", retInt); - DISPATCH_TABLE[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", retInt); - DISPATCH_TABLE[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); - DISPATCH_TABLE[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); - DISPATCH_TABLE[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_DE", retInt); + DISPATCH_TABLE[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_E", retInt); + DISPATCH_TABLE[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_E", retInt); + DISPATCH_TABLE[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_N", retInt); DISPATCH_TABLE[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RRA", retInt); DISPATCH_TABLE[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); - DISPATCH_TABLE[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", retInt); + DISPATCH_TABLE[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_HL_NN", retInt); DISPATCH_TABLE[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_HL", retInt); - DISPATCH_TABLE[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", retInt); - DISPATCH_TABLE[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); - DISPATCH_TABLE[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); - DISPATCH_TABLE[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_HL", retInt); + DISPATCH_TABLE[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_H", retInt); + DISPATCH_TABLE[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_H", retInt); + DISPATCH_TABLE[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_H_N", retInt); DISPATCH_TABLE[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_DAA", retInt); DISPATCH_TABLE[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); - DISPATCH_TABLE[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", retInt); + DISPATCH_TABLE[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_HL", retInt); DISPATCH_TABLE[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_HL_REF_NN", retInt); - DISPATCH_TABLE[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", retInt); - DISPATCH_TABLE[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); - DISPATCH_TABLE[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); - DISPATCH_TABLE[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_HL", retInt); + DISPATCH_TABLE[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_L", retInt); + DISPATCH_TABLE[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_L", retInt); + DISPATCH_TABLE[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_L_N", retInt); DISPATCH_TABLE[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_CPL", retInt); DISPATCH_TABLE[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); - DISPATCH_TABLE[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_NN", retInt); + DISPATCH_TABLE[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_NN", retInt); DISPATCH_TABLE[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_A", retInt); - DISPATCH_TABLE[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_INC_RP", retInt); - DISPATCH_TABLE[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); - DISPATCH_TABLE[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); - DISPATCH_TABLE[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_INC_SP", retInt); + DISPATCH_TABLE[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_REF_HL", retInt); + DISPATCH_TABLE[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_HL", retInt); + DISPATCH_TABLE[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_HL_N", retInt); DISPATCH_TABLE[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SCF", retInt); DISPATCH_TABLE[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); - DISPATCH_TABLE[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_RP", retInt); + DISPATCH_TABLE[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_HL_SP", retInt); DISPATCH_TABLE[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_NN", retInt); - DISPATCH_TABLE[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_RP", retInt); - DISPATCH_TABLE[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_R", retInt); - DISPATCH_TABLE[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_R", retInt); - DISPATCH_TABLE[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_N", retInt); + DISPATCH_TABLE[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_SP", retInt); + DISPATCH_TABLE[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_A", retInt); + DISPATCH_TABLE[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_A", retInt); + DISPATCH_TABLE[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_N", retInt); DISPATCH_TABLE[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_CCF", retInt); - DISPATCH_TABLE[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); + DISPATCH_TABLE[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_B", retInt); + DISPATCH_TABLE[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_C", retInt); + DISPATCH_TABLE[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_D", retInt); + DISPATCH_TABLE[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_E", retInt); + DISPATCH_TABLE[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_H", retInt); + DISPATCH_TABLE[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_L", retInt); + DISPATCH_TABLE[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_REF_HL", retInt); + DISPATCH_TABLE[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_A", retInt); + DISPATCH_TABLE[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_B", retInt); + DISPATCH_TABLE[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_C", retInt); + DISPATCH_TABLE[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_D", retInt); + DISPATCH_TABLE[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_E", retInt); + DISPATCH_TABLE[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_H", retInt); + DISPATCH_TABLE[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_L", retInt); + DISPATCH_TABLE[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_REF_HL", retInt); + DISPATCH_TABLE[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_A", retInt); + DISPATCH_TABLE[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_B", retInt); + DISPATCH_TABLE[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_C", retInt); + DISPATCH_TABLE[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_D", retInt); + DISPATCH_TABLE[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_E", retInt); + DISPATCH_TABLE[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_H", retInt); + DISPATCH_TABLE[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_L", retInt); + DISPATCH_TABLE[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_REF_HL", retInt); + DISPATCH_TABLE[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_A", retInt); + DISPATCH_TABLE[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_B", retInt); + DISPATCH_TABLE[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_C", retInt); + DISPATCH_TABLE[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_D", retInt); + DISPATCH_TABLE[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_E", retInt); + DISPATCH_TABLE[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_H", retInt); + DISPATCH_TABLE[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_L", retInt); + DISPATCH_TABLE[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_REF_HL", retInt); + DISPATCH_TABLE[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_A", retInt); + DISPATCH_TABLE[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_H_B", retInt); + DISPATCH_TABLE[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_H_C", retInt); + DISPATCH_TABLE[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_H_D", retInt); + DISPATCH_TABLE[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_H_E", retInt); + DISPATCH_TABLE[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_H_H", retInt); + DISPATCH_TABLE[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_H_L", retInt); + DISPATCH_TABLE[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_H_REF_HL", retInt); + DISPATCH_TABLE[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_H_A", retInt); + DISPATCH_TABLE[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_L_B", retInt); + DISPATCH_TABLE[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_L_C", retInt); + DISPATCH_TABLE[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_L_D", retInt); + DISPATCH_TABLE[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_L_E", retInt); + DISPATCH_TABLE[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_L_H", retInt); + DISPATCH_TABLE[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_L_L", retInt); + DISPATCH_TABLE[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_L_REF_HL", retInt); + DISPATCH_TABLE[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_L_A", retInt); + DISPATCH_TABLE[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_HL_B", retInt); + DISPATCH_TABLE[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_HL_C", retInt); + DISPATCH_TABLE[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_HL_D", retInt); + DISPATCH_TABLE[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_HL_E", retInt); + DISPATCH_TABLE[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_HL_H", retInt); + DISPATCH_TABLE[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_HL_L", retInt); DISPATCH_TABLE[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_HALT", retInt); - DISPATCH_TABLE[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_HL_A", retInt); + DISPATCH_TABLE[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_B", retInt); + DISPATCH_TABLE[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_C", retInt); + DISPATCH_TABLE[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_D", retInt); + DISPATCH_TABLE[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_E", retInt); + DISPATCH_TABLE[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_H", retInt); + DISPATCH_TABLE[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_L", retInt); + DISPATCH_TABLE[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_HL", retInt); + DISPATCH_TABLE[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_A", retInt); + DISPATCH_TABLE[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_B", retInt); + DISPATCH_TABLE[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_C", retInt); + DISPATCH_TABLE[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_D", retInt); + DISPATCH_TABLE[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_E", retInt); + DISPATCH_TABLE[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_H", retInt); + DISPATCH_TABLE[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_L", retInt); + DISPATCH_TABLE[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_HL", retInt); + DISPATCH_TABLE[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_A", retInt); + DISPATCH_TABLE[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_B", retInt); + DISPATCH_TABLE[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_C", retInt); + DISPATCH_TABLE[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_D", retInt); + DISPATCH_TABLE[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_E", retInt); + DISPATCH_TABLE[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_H", retInt); + DISPATCH_TABLE[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_L", retInt); + DISPATCH_TABLE[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_HL", retInt); + DISPATCH_TABLE[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_A", retInt); + DISPATCH_TABLE[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_B", retInt); + DISPATCH_TABLE[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_C", retInt); + DISPATCH_TABLE[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_D", retInt); + DISPATCH_TABLE[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_E", retInt); + DISPATCH_TABLE[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_H", retInt); + DISPATCH_TABLE[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_L", retInt); + DISPATCH_TABLE[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_HL", retInt); + DISPATCH_TABLE[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_A", retInt); + DISPATCH_TABLE[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_B", retInt); + DISPATCH_TABLE[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_C", retInt); + DISPATCH_TABLE[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_D", retInt); + DISPATCH_TABLE[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_E", retInt); + DISPATCH_TABLE[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_H", retInt); + DISPATCH_TABLE[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_L", retInt); + DISPATCH_TABLE[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_HL", retInt); + DISPATCH_TABLE[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_A", retInt); + DISPATCH_TABLE[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_AND_B", retInt); + DISPATCH_TABLE[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_AND_C", retInt); + DISPATCH_TABLE[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_AND_D", retInt); + DISPATCH_TABLE[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_AND_E", retInt); + DISPATCH_TABLE[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_H", retInt); + DISPATCH_TABLE[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_L", retInt); + DISPATCH_TABLE[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_HL", retInt); + DISPATCH_TABLE[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_AND_A", retInt); + DISPATCH_TABLE[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_B", retInt); + DISPATCH_TABLE[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_C", retInt); + DISPATCH_TABLE[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_D", retInt); + DISPATCH_TABLE[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_E", retInt); + DISPATCH_TABLE[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_H", retInt); + DISPATCH_TABLE[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_L", retInt); + DISPATCH_TABLE[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_HL", retInt); + DISPATCH_TABLE[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_A", retInt); + DISPATCH_TABLE[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_OR_B", retInt); + DISPATCH_TABLE[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_OR_C", retInt); + DISPATCH_TABLE[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_OR_D", retInt); + DISPATCH_TABLE[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OR_E", retInt); + DISPATCH_TABLE[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_H", retInt); + DISPATCH_TABLE[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_L", retInt); + DISPATCH_TABLE[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_HL", retInt); + DISPATCH_TABLE[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_OR_A", retInt); + DISPATCH_TABLE[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CP_B", retInt); + DISPATCH_TABLE[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CP_C", retInt); + DISPATCH_TABLE[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CP_D", retInt); + DISPATCH_TABLE[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CP_E", retInt); + DISPATCH_TABLE[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_H", retInt); + DISPATCH_TABLE[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_L", retInt); + DISPATCH_TABLE[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_HL", retInt); + DISPATCH_TABLE[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CP_A", retInt); DISPATCH_TABLE[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); - DISPATCH_TABLE[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", retInt); + DISPATCH_TABLE[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_BC", retInt); DISPATCH_TABLE[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); DISPATCH_TABLE[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_JP_NN", retInt); DISPATCH_TABLE[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); - DISPATCH_TABLE[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", retInt); + DISPATCH_TABLE[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_BC", retInt); DISPATCH_TABLE[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_N", retInt); DISPATCH_TABLE[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); DISPATCH_TABLE[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); @@ -250,11 +250,11 @@ public class DispatchTables { DISPATCH_TABLE[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_N", retInt); DISPATCH_TABLE[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); DISPATCH_TABLE[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); - DISPATCH_TABLE[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", retInt); + DISPATCH_TABLE[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_DE", retInt); DISPATCH_TABLE[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); DISPATCH_TABLE[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_N_A", retInt); DISPATCH_TABLE[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); - DISPATCH_TABLE[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", retInt); + DISPATCH_TABLE[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_DE", retInt); DISPATCH_TABLE[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_N", retInt); DISPATCH_TABLE[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); DISPATCH_TABLE[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); @@ -266,11 +266,11 @@ public class DispatchTables { DISPATCH_TABLE[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_N", retInt); DISPATCH_TABLE[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); DISPATCH_TABLE[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); - DISPATCH_TABLE[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", retInt); + DISPATCH_TABLE[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_HL", retInt); DISPATCH_TABLE[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); DISPATCH_TABLE[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_HL", retInt); DISPATCH_TABLE[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); - DISPATCH_TABLE[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", retInt); + DISPATCH_TABLE[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_HL", retInt); DISPATCH_TABLE[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_N", retInt); DISPATCH_TABLE[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); DISPATCH_TABLE[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); @@ -282,11 +282,11 @@ public class DispatchTables { DISPATCH_TABLE[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_N", retInt); DISPATCH_TABLE[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); DISPATCH_TABLE[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); - DISPATCH_TABLE[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_RP", retInt); + DISPATCH_TABLE[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_AF", retInt); DISPATCH_TABLE[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); DISPATCH_TABLE[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_DI", retInt); DISPATCH_TABLE[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); - DISPATCH_TABLE[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_RP", retInt); + DISPATCH_TABLE[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_AF", retInt); DISPATCH_TABLE[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_N", retInt); DISPATCH_TABLE[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); DISPATCH_TABLE[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); @@ -301,7 +301,7 @@ public class DispatchTables { DISPATCH_TABLE_ED[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); DISPATCH_TABLE_ED[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); DISPATCH_TABLE_ED[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", retInt); - DISPATCH_TABLE_ED[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", retInt); + DISPATCH_TABLE_ED[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_BC", retInt); DISPATCH_TABLE_ED[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); DISPATCH_TABLE_ED[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); @@ -312,12 +312,12 @@ public class DispatchTables { DISPATCH_TABLE_ED[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", retInt); DISPATCH_TABLE_ED[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_RETI", retInt); - DISPATCH_TABLE_ED[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); // im 0/1 + DISPATCH_TABLE_ED[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); DISPATCH_TABLE_ED[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_A", retInt); DISPATCH_TABLE_ED[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); DISPATCH_TABLE_ED[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); DISPATCH_TABLE_ED[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", retInt); - DISPATCH_TABLE_ED[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", retInt); + DISPATCH_TABLE_ED[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_DE", retInt); DISPATCH_TABLE_ED[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); DISPATCH_TABLE_ED[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_IM_1", retInt); @@ -333,7 +333,7 @@ public class DispatchTables { DISPATCH_TABLE_ED[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); DISPATCH_TABLE_ED[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); DISPATCH_TABLE_ED[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", retInt); - DISPATCH_TABLE_ED[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", retInt); + DISPATCH_TABLE_ED[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_ED_LD_REF_NN_HL", retInt); DISPATCH_TABLE_ED[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); DISPATCH_TABLE_ED[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); @@ -344,12 +344,12 @@ public class DispatchTables { DISPATCH_TABLE_ED[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", retInt); DISPATCH_TABLE_ED[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); - DISPATCH_TABLE_ED[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); // im 0/1 + DISPATCH_TABLE_ED[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); DISPATCH_TABLE_ED[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_RLD", retInt); DISPATCH_TABLE_ED[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_IN_REF_C", retInt); DISPATCH_TABLE_ED[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_0", retInt); DISPATCH_TABLE_ED[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", retInt); - DISPATCH_TABLE_ED[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_RP", retInt); + DISPATCH_TABLE_ED[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_SP", retInt); DISPATCH_TABLE_ED[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); DISPATCH_TABLE_ED[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_IM_1", retInt); @@ -634,309 +634,519 @@ public class DispatchTables { DISPATCH_TABLE_CB[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); DISPATCH_TABLE_CB[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_SET_N_R", retInt); - DISPATCH_TABLE_DD[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", retInt); - DISPATCH_TABLE_DD[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", retInt); + DISPATCH_TABLE_DD[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", retInt); + DISPATCH_TABLE_DD[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_LD_BC_NN", retInt); + DISPATCH_TABLE_DD[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_BC_A", retInt); + DISPATCH_TABLE_DD[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_INC_BC", retInt); + DISPATCH_TABLE_DD[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_INC_B", retInt); + DISPATCH_TABLE_DD[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_B", retInt); + DISPATCH_TABLE_DD[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_N", retInt); + DISPATCH_TABLE_DD[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLCA", retInt); + DISPATCH_TABLE_DD[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_EX_AF_AFF", retInt); + DISPATCH_TABLE_DD[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_BC", retInt); + DISPATCH_TABLE_DD[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_BC", retInt); + DISPATCH_TABLE_DD[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_BC", retInt); + DISPATCH_TABLE_DD[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_C", retInt); + DISPATCH_TABLE_DD[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_C", retInt); + DISPATCH_TABLE_DD[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_N", retInt); + DISPATCH_TABLE_DD[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRCA", retInt); + DISPATCH_TABLE_DD[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_DJNZ", retInt); + DISPATCH_TABLE_DD[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_LD_DE_NN", retInt); + DISPATCH_TABLE_DD[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_DE_A", retInt); + DISPATCH_TABLE_DD[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_INC_DE", retInt); + DISPATCH_TABLE_DD[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_INC_D", retInt); + DISPATCH_TABLE_DD[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_D", retInt); + DISPATCH_TABLE_DD[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_N", retInt); + DISPATCH_TABLE_DD[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RLA", retInt); + DISPATCH_TABLE_DD[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_JR_N", retInt); + DISPATCH_TABLE_DD[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_DE", retInt); + DISPATCH_TABLE_DD[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_DE", retInt); + DISPATCH_TABLE_DD[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_DE", retInt); + DISPATCH_TABLE_DD[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_E", retInt); + DISPATCH_TABLE_DD[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_E", retInt); + DISPATCH_TABLE_DD[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_N", retInt); + DISPATCH_TABLE_DD[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RRA", retInt); + DISPATCH_TABLE_DD[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); DISPATCH_TABLE_DD[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IX_NN", retInt); DISPATCH_TABLE_DD[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_IX", retInt); DISPATCH_TABLE_DD[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IX", retInt); DISPATCH_TABLE_DD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IXH", retInt); DISPATCH_TABLE_DD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IXH", retInt); DISPATCH_TABLE_DD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_N", retInt); - DISPATCH_TABLE_DD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", retInt); + DISPATCH_TABLE_DD[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_DAA", retInt); + DISPATCH_TABLE_DD[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); + DISPATCH_TABLE_DD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_IX", retInt); DISPATCH_TABLE_DD[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IX_REF_NN", retInt); DISPATCH_TABLE_DD[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IX", retInt); DISPATCH_TABLE_DD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IXL", retInt); DISPATCH_TABLE_DD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IXL", retInt); DISPATCH_TABLE_DD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_N", retInt); + DISPATCH_TABLE_DD[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_CPL", retInt); + DISPATCH_TABLE_DD[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); + DISPATCH_TABLE_DD[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_NN", retInt); + DISPATCH_TABLE_DD[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_A", retInt); + DISPATCH_TABLE_DD[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_INC_SP", retInt); DISPATCH_TABLE_DD[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_REF_IX_N", retInt); DISPATCH_TABLE_DD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_N", retInt); - DISPATCH_TABLE_DD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_RP", retInt); - DISPATCH_TABLE_DD[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); - DISPATCH_TABLE_DD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); - DISPATCH_TABLE_DD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); - DISPATCH_TABLE_DD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); - DISPATCH_TABLE_DD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); - DISPATCH_TABLE_DD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); - DISPATCH_TABLE_DD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); - DISPATCH_TABLE_DD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); - DISPATCH_TABLE_DD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); - DISPATCH_TABLE_DD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); - DISPATCH_TABLE_DD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); - DISPATCH_TABLE_DD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); - DISPATCH_TABLE_DD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIH_IIH", retInt); + DISPATCH_TABLE_DD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_N", retInt); + DISPATCH_TABLE_DD[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SCF", retInt); + DISPATCH_TABLE_DD[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); + DISPATCH_TABLE_DD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IX_SP", retInt); + DISPATCH_TABLE_DD[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_NN", retInt); + DISPATCH_TABLE_DD[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_SP", retInt); + DISPATCH_TABLE_DD[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_A", retInt); + DISPATCH_TABLE_DD[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_A", retInt); + DISPATCH_TABLE_DD[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_N", retInt); + DISPATCH_TABLE_DD[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_CCF", retInt); + DISPATCH_TABLE_DD[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_B", retInt); + DISPATCH_TABLE_DD[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_C", retInt); + DISPATCH_TABLE_DD[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_D", retInt); + DISPATCH_TABLE_DD[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_E", retInt); + DISPATCH_TABLE_DD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_IXH", retInt); + DISPATCH_TABLE_DD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_IXL", retInt); + DISPATCH_TABLE_DD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_A", retInt); + DISPATCH_TABLE_DD[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_B", retInt); + DISPATCH_TABLE_DD[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_C", retInt); + DISPATCH_TABLE_DD[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_D", retInt); + DISPATCH_TABLE_DD[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_E", retInt); + DISPATCH_TABLE_DD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_IXH", retInt); + DISPATCH_TABLE_DD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_IXL", retInt); + DISPATCH_TABLE_DD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_A", retInt); + DISPATCH_TABLE_DD[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_B", retInt); + DISPATCH_TABLE_DD[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_C", retInt); + DISPATCH_TABLE_DD[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_D", retInt); + DISPATCH_TABLE_DD[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_E", retInt); + DISPATCH_TABLE_DD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_IXH", retInt); + DISPATCH_TABLE_DD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_IXL", retInt); + DISPATCH_TABLE_DD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_A", retInt); + DISPATCH_TABLE_DD[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_B", retInt); + DISPATCH_TABLE_DD[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_C", retInt); + DISPATCH_TABLE_DD[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_D", retInt); + DISPATCH_TABLE_DD[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_E", retInt); + DISPATCH_TABLE_DD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_IXH", retInt); + DISPATCH_TABLE_DD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_IXL", retInt); + DISPATCH_TABLE_DD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_A", retInt); + DISPATCH_TABLE_DD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_B", retInt); + DISPATCH_TABLE_DD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_C", retInt); + DISPATCH_TABLE_DD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_D", retInt); + DISPATCH_TABLE_DD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_E", retInt); + DISPATCH_TABLE_DD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_IXH", retInt); DISPATCH_TABLE_DD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_IXL", retInt); - DISPATCH_TABLE_DD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_R", retInt); - DISPATCH_TABLE_DD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", retInt); - DISPATCH_TABLE_DD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", retInt); - DISPATCH_TABLE_DD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", retInt); - DISPATCH_TABLE_DD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", retInt); + DISPATCH_TABLE_DD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_H_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXH_A", retInt); + DISPATCH_TABLE_DD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_B", retInt); + DISPATCH_TABLE_DD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_C", retInt); + DISPATCH_TABLE_DD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_D", retInt); + DISPATCH_TABLE_DD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_E", retInt); DISPATCH_TABLE_DD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_IXH", retInt); - DISPATCH_TABLE_DD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIL_IIL", retInt); - DISPATCH_TABLE_DD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_R", retInt); - DISPATCH_TABLE_DD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); - DISPATCH_TABLE_DD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); - DISPATCH_TABLE_DD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); - DISPATCH_TABLE_DD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); - DISPATCH_TABLE_DD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); - DISPATCH_TABLE_DD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); - DISPATCH_TABLE_DD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_N_R", retInt); - DISPATCH_TABLE_DD[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXH", retInt); - DISPATCH_TABLE_DD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IXL", retInt); - DISPATCH_TABLE_DD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_DD[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE_DD[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE_DD[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE_DD[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE_DD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_IXL", retInt); + DISPATCH_TABLE_DD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_L_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IXL_A", retInt); + DISPATCH_TABLE_DD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_B", retInt); + DISPATCH_TABLE_DD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_C", retInt); + DISPATCH_TABLE_DD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_D", retInt); + DISPATCH_TABLE_DD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_E", retInt); + DISPATCH_TABLE_DD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_IXH", retInt); + DISPATCH_TABLE_DD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_IXL", retInt); + DISPATCH_TABLE_DD[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_HALT", retInt); + DISPATCH_TABLE_DD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_A", retInt); + DISPATCH_TABLE_DD[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_B", retInt); + DISPATCH_TABLE_DD[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_C", retInt); + DISPATCH_TABLE_DD[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_D", retInt); + DISPATCH_TABLE_DD[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_E", retInt); + DISPATCH_TABLE_DD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_IXH", retInt); + DISPATCH_TABLE_DD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_IXL", retInt); + DISPATCH_TABLE_DD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_A", retInt); + DISPATCH_TABLE_DD[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_B", retInt); + DISPATCH_TABLE_DD[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_C", retInt); + DISPATCH_TABLE_DD[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_D", retInt); + DISPATCH_TABLE_DD[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_E", retInt); DISPATCH_TABLE_DD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IXH", retInt); DISPATCH_TABLE_DD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IXL", retInt); - DISPATCH_TABLE_DD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE_DD[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE_DD[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE_DD[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE_DD[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE_DD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_A", retInt); + DISPATCH_TABLE_DD[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_B", retInt); + DISPATCH_TABLE_DD[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_C", retInt); + DISPATCH_TABLE_DD[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_D", retInt); + DISPATCH_TABLE_DD[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_E", retInt); DISPATCH_TABLE_DD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IXH", retInt); DISPATCH_TABLE_DD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IXL", retInt); - DISPATCH_TABLE_DD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE_DD[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE_DD[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE_DD[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE_DD[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE_DD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_A", retInt); + DISPATCH_TABLE_DD[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_B", retInt); + DISPATCH_TABLE_DD[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_C", retInt); + DISPATCH_TABLE_DD[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_D", retInt); + DISPATCH_TABLE_DD[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_E", retInt); DISPATCH_TABLE_DD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IXH", retInt); DISPATCH_TABLE_DD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IXL", retInt); - DISPATCH_TABLE_DD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE_DD[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE_DD[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE_DD[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE_DD[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE_DD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_A", retInt); + DISPATCH_TABLE_DD[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_B", retInt); + DISPATCH_TABLE_DD[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_C", retInt); + DISPATCH_TABLE_DD[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_D", retInt); + DISPATCH_TABLE_DD[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_E", retInt); DISPATCH_TABLE_DD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IXH", retInt); DISPATCH_TABLE_DD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IXL", retInt); - DISPATCH_TABLE_DD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE_DD[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE_DD[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE_DD[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE_DD[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE_DD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_A", retInt); + DISPATCH_TABLE_DD[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_AND_B", retInt); + DISPATCH_TABLE_DD[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_AND_C", retInt); + DISPATCH_TABLE_DD[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_AND_D", retInt); + DISPATCH_TABLE_DD[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_AND_E", retInt); DISPATCH_TABLE_DD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IXH", retInt); DISPATCH_TABLE_DD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IXL", retInt); - DISPATCH_TABLE_DD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE_DD[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE_DD[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE_DD[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE_DD[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE_DD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_AND_A", retInt); + DISPATCH_TABLE_DD[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_B", retInt); + DISPATCH_TABLE_DD[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_C", retInt); + DISPATCH_TABLE_DD[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_D", retInt); + DISPATCH_TABLE_DD[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_E", retInt); DISPATCH_TABLE_DD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IXH", retInt); DISPATCH_TABLE_DD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IXL", retInt); - DISPATCH_TABLE_DD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE_DD[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE_DD[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE_DD[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE_DD[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE_DD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_A", retInt); + DISPATCH_TABLE_DD[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_OR_B", retInt); + DISPATCH_TABLE_DD[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_OR_C", retInt); + DISPATCH_TABLE_DD[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_OR_D", retInt); + DISPATCH_TABLE_DD[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OR_E", retInt); DISPATCH_TABLE_DD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IXH", retInt); DISPATCH_TABLE_DD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IXL", retInt); - DISPATCH_TABLE_DD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE_DD[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE_DD[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE_DD[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE_DD[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE_DD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_OR_A", retInt); + DISPATCH_TABLE_DD[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CP_B", retInt); + DISPATCH_TABLE_DD[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CP_C", retInt); + DISPATCH_TABLE_DD[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CP_D", retInt); + DISPATCH_TABLE_DD[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CP_E", retInt); DISPATCH_TABLE_DD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IXH", retInt); DISPATCH_TABLE_DD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IXL", retInt); - DISPATCH_TABLE_DD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IX_N", retInt); - DISPATCH_TABLE_DD[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE_DD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IX_D", retInt); + DISPATCH_TABLE_DD[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CP_A", retInt); + DISPATCH_TABLE_DD[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE_DD[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_BC", retInt); + DISPATCH_TABLE_DD[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_DD[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_JP_NN", retInt); + DISPATCH_TABLE_DD[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_DD[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_BC", retInt); + DISPATCH_TABLE_DD[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_N", retInt); + DISPATCH_TABLE_DD[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_DD[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE_DD[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_RET", retInt); + DISPATCH_TABLE_DD[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); DISPATCH_TABLE_DD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "DD_CB_DISPATCH", retInt); + DISPATCH_TABLE_DD[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_DD[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_NN", retInt); + DISPATCH_TABLE_DD[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_N", retInt); + DISPATCH_TABLE_DD[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_DD[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE_DD[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_DE", retInt); + DISPATCH_TABLE_DD[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_DD[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_N_A", retInt); + DISPATCH_TABLE_DD[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_DD[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_DE", retInt); + DISPATCH_TABLE_DD[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_N", retInt); + DISPATCH_TABLE_DD[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_DD[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE_DD[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_EXX", retInt); + DISPATCH_TABLE_DD[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_DD[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_IN_A_REF_N", retInt); + DISPATCH_TABLE_DD[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_DD[0xDD] = lookup.findVirtual(EmulatorEngine.class, "DD_DISPATCH", retInt); + DISPATCH_TABLE_DD[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_N", retInt); + DISPATCH_TABLE_DD[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_DD[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); DISPATCH_TABLE_DD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IX", retInt); + DISPATCH_TABLE_DD[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); DISPATCH_TABLE_DD[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_IX", retInt); + DISPATCH_TABLE_DD[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); DISPATCH_TABLE_DD[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_IX", retInt); + DISPATCH_TABLE_DD[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_N", retInt); + DISPATCH_TABLE_DD[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_DD[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); DISPATCH_TABLE_DD[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_IX", retInt); + DISPATCH_TABLE_DD[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_DD[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_EX_DE_HL", retInt); + DISPATCH_TABLE_DD[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_DD[0xED] = lookup.findVirtual(EmulatorEngine.class, "ED_DISPATCH", retInt); + DISPATCH_TABLE_DD[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_N", retInt); + DISPATCH_TABLE_DD[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_DD[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE_DD[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_AF", retInt); + DISPATCH_TABLE_DD[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_DD[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_DI", retInt); + DISPATCH_TABLE_DD[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_DD[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_AF", retInt); + DISPATCH_TABLE_DD[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_N", retInt); + DISPATCH_TABLE_DD[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_DD[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); DISPATCH_TABLE_DD[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_IX", retInt); + DISPATCH_TABLE_DD[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_DD[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_EI", retInt); + DISPATCH_TABLE_DD[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_DD[0xFD] = lookup.findVirtual(EmulatorEngine.class, "FD_DISPATCH", retInt); + DISPATCH_TABLE_DD[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_N", retInt); + DISPATCH_TABLE_DD[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); - DISPATCH_TABLE_FD[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", retInt); - DISPATCH_TABLE_FD[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", retInt); + DISPATCH_TABLE_FD[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_NOP", retInt); + DISPATCH_TABLE_FD[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_LD_BC_NN", retInt); + DISPATCH_TABLE_FD[0x02] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_BC_A", retInt); + DISPATCH_TABLE_FD[0x03] = lookup.findVirtual(EmulatorEngine.class, "I_INC_BC", retInt); + DISPATCH_TABLE_FD[0x04] = lookup.findVirtual(EmulatorEngine.class, "I_INC_B", retInt); + DISPATCH_TABLE_FD[0x05] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_B", retInt); + DISPATCH_TABLE_FD[0x06] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_N", retInt); + DISPATCH_TABLE_FD[0x07] = lookup.findVirtual(EmulatorEngine.class, "I_RLCA", retInt); + DISPATCH_TABLE_FD[0x08] = lookup.findVirtual(EmulatorEngine.class, "I_EX_AF_AFF", retInt); + DISPATCH_TABLE_FD[0x09] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_BC", retInt); + DISPATCH_TABLE_FD[0x0A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_BC", retInt); + DISPATCH_TABLE_FD[0x0B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_BC", retInt); + DISPATCH_TABLE_FD[0x0C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_C", retInt); + DISPATCH_TABLE_FD[0x0D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_C", retInt); + DISPATCH_TABLE_FD[0x0E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_N", retInt); + DISPATCH_TABLE_FD[0x0F] = lookup.findVirtual(EmulatorEngine.class, "I_RRCA", retInt); + DISPATCH_TABLE_FD[0x10] = lookup.findVirtual(EmulatorEngine.class, "I_DJNZ", retInt); + DISPATCH_TABLE_FD[0x11] = lookup.findVirtual(EmulatorEngine.class, "I_LD_DE_NN", retInt); + DISPATCH_TABLE_FD[0x12] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_DE_A", retInt); + DISPATCH_TABLE_FD[0x13] = lookup.findVirtual(EmulatorEngine.class, "I_INC_DE", retInt); + DISPATCH_TABLE_FD[0x14] = lookup.findVirtual(EmulatorEngine.class, "I_INC_D", retInt); + DISPATCH_TABLE_FD[0x15] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_D", retInt); + DISPATCH_TABLE_FD[0x16] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_N", retInt); + DISPATCH_TABLE_FD[0x17] = lookup.findVirtual(EmulatorEngine.class, "I_RLA", retInt); + DISPATCH_TABLE_FD[0x18] = lookup.findVirtual(EmulatorEngine.class, "I_JR_N", retInt); + DISPATCH_TABLE_FD[0x19] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_DE", retInt); + DISPATCH_TABLE_FD[0x1A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_DE", retInt); + DISPATCH_TABLE_FD[0x1B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_DE", retInt); + DISPATCH_TABLE_FD[0x1C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_E", retInt); + DISPATCH_TABLE_FD[0x1D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_E", retInt); + DISPATCH_TABLE_FD[0x1E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_N", retInt); + DISPATCH_TABLE_FD[0x1F] = lookup.findVirtual(EmulatorEngine.class, "I_RRA", retInt); + DISPATCH_TABLE_FD[0x20] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); DISPATCH_TABLE_FD[0x21] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IY_NN", retInt); DISPATCH_TABLE_FD[0x22] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_IY", retInt); DISPATCH_TABLE_FD[0x23] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IY", retInt); DISPATCH_TABLE_FD[0x24] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IYH", retInt); DISPATCH_TABLE_FD[0x25] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IYH", retInt); DISPATCH_TABLE_FD[0x26] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_N", retInt); - DISPATCH_TABLE_FD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", retInt); + DISPATCH_TABLE_FD[0x27] = lookup.findVirtual(EmulatorEngine.class, "I_DAA", retInt); + DISPATCH_TABLE_FD[0x28] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); + DISPATCH_TABLE_FD[0x29] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_IY", retInt); DISPATCH_TABLE_FD[0x2A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IY_REF_NN", retInt); DISPATCH_TABLE_FD[0x2B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IY", retInt); DISPATCH_TABLE_FD[0x2C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_IYL", retInt); DISPATCH_TABLE_FD[0x2D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_IYL", retInt); DISPATCH_TABLE_FD[0x2E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_N", retInt); + DISPATCH_TABLE_FD[0x2F] = lookup.findVirtual(EmulatorEngine.class, "I_CPL", retInt); + DISPATCH_TABLE_FD[0x30] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); + DISPATCH_TABLE_FD[0x31] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_NN", retInt); + DISPATCH_TABLE_FD[0x32] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_A", retInt); + DISPATCH_TABLE_FD[0x33] = lookup.findVirtual(EmulatorEngine.class, "I_INC_SP", retInt); DISPATCH_TABLE_FD[0x34] = lookup.findVirtual(EmulatorEngine.class, "I_INC_REF_IY_N", retInt); DISPATCH_TABLE_FD[0x35] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_N", retInt); - DISPATCH_TABLE_FD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_RP", retInt); - DISPATCH_TABLE_FD[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); - DISPATCH_TABLE_FD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); - DISPATCH_TABLE_FD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); - DISPATCH_TABLE_FD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); - DISPATCH_TABLE_FD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); - DISPATCH_TABLE_FD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); - DISPATCH_TABLE_FD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); - DISPATCH_TABLE_FD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); - DISPATCH_TABLE_FD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); - DISPATCH_TABLE_FD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); - DISPATCH_TABLE_FD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); - DISPATCH_TABLE_FD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); - DISPATCH_TABLE_FD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIH_IIH", retInt); + DISPATCH_TABLE_FD[0x36] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_N", retInt); + DISPATCH_TABLE_FD[0x37] = lookup.findVirtual(EmulatorEngine.class, "I_SCF", retInt); + DISPATCH_TABLE_FD[0x38] = lookup.findVirtual(EmulatorEngine.class, "I_JR_CC_N", retInt); + DISPATCH_TABLE_FD[0x39] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_IY_SP", retInt); + DISPATCH_TABLE_FD[0x3A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_NN", retInt); + DISPATCH_TABLE_FD[0x3B] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_SP", retInt); + DISPATCH_TABLE_FD[0x3C] = lookup.findVirtual(EmulatorEngine.class, "I_INC_A", retInt); + DISPATCH_TABLE_FD[0x3D] = lookup.findVirtual(EmulatorEngine.class, "I_DEC_A", retInt); + DISPATCH_TABLE_FD[0x3E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_N", retInt); + DISPATCH_TABLE_FD[0x3F] = lookup.findVirtual(EmulatorEngine.class, "I_CCF", retInt); + DISPATCH_TABLE_FD[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_B", retInt); + DISPATCH_TABLE_FD[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_C", retInt); + DISPATCH_TABLE_FD[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_D", retInt); + DISPATCH_TABLE_FD[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_E", retInt); + DISPATCH_TABLE_FD[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_IYH", retInt); + DISPATCH_TABLE_FD[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_IYL", retInt); + DISPATCH_TABLE_FD[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_B_A", retInt); + DISPATCH_TABLE_FD[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_B", retInt); + DISPATCH_TABLE_FD[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_C", retInt); + DISPATCH_TABLE_FD[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_D", retInt); + DISPATCH_TABLE_FD[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_E", retInt); + DISPATCH_TABLE_FD[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_IYH", retInt); + DISPATCH_TABLE_FD[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_IYL", retInt); + DISPATCH_TABLE_FD[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_C_A", retInt); + DISPATCH_TABLE_FD[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_B", retInt); + DISPATCH_TABLE_FD[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_C", retInt); + DISPATCH_TABLE_FD[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_D", retInt); + DISPATCH_TABLE_FD[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_E", retInt); + DISPATCH_TABLE_FD[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_IYH", retInt); + DISPATCH_TABLE_FD[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_IYL", retInt); + DISPATCH_TABLE_FD[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_D_A", retInt); + DISPATCH_TABLE_FD[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_B", retInt); + DISPATCH_TABLE_FD[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_C", retInt); + DISPATCH_TABLE_FD[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_D", retInt); + DISPATCH_TABLE_FD[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_E", retInt); + DISPATCH_TABLE_FD[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_IYH", retInt); + DISPATCH_TABLE_FD[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_IYL", retInt); + DISPATCH_TABLE_FD[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_E_A", retInt); + DISPATCH_TABLE_FD[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_B", retInt); + DISPATCH_TABLE_FD[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_C", retInt); + DISPATCH_TABLE_FD[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_D", retInt); + DISPATCH_TABLE_FD[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_E", retInt); + DISPATCH_TABLE_FD[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_IYH", retInt); DISPATCH_TABLE_FD[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_IYL", retInt); - DISPATCH_TABLE_FD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_R", retInt); - DISPATCH_TABLE_FD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", retInt); - DISPATCH_TABLE_FD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", retInt); - DISPATCH_TABLE_FD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", retInt); - DISPATCH_TABLE_FD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", retInt); + DISPATCH_TABLE_FD[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_LD_H_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYH_A", retInt); + DISPATCH_TABLE_FD[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_B", retInt); + DISPATCH_TABLE_FD[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_C", retInt); + DISPATCH_TABLE_FD[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_D", retInt); + DISPATCH_TABLE_FD[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_E", retInt); DISPATCH_TABLE_FD[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_IYH", retInt); - DISPATCH_TABLE_FD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IIL_IIL", retInt); - DISPATCH_TABLE_FD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_R", retInt); - DISPATCH_TABLE_FD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); - DISPATCH_TABLE_FD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); - DISPATCH_TABLE_FD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); - DISPATCH_TABLE_FD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); - DISPATCH_TABLE_FD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); - DISPATCH_TABLE_FD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); - DISPATCH_TABLE_FD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_N_R", retInt); - DISPATCH_TABLE_FD[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYH", retInt); - DISPATCH_TABLE_FD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_IYL", retInt); - DISPATCH_TABLE_FD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_R", retInt); - DISPATCH_TABLE_FD[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE_FD[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE_FD[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE_FD[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); + DISPATCH_TABLE_FD[0x6D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_IYL", retInt); + DISPATCH_TABLE_FD[0x6E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_L_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0x6F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_IYL_A", retInt); + DISPATCH_TABLE_FD[0x70] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_B", retInt); + DISPATCH_TABLE_FD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_C", retInt); + DISPATCH_TABLE_FD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_D", retInt); + DISPATCH_TABLE_FD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_E", retInt); + DISPATCH_TABLE_FD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_IYH", retInt); + DISPATCH_TABLE_FD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_IYL", retInt); + DISPATCH_TABLE_FD[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_HALT", retInt); + DISPATCH_TABLE_FD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_A", retInt); + DISPATCH_TABLE_FD[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_B", retInt); + DISPATCH_TABLE_FD[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_C", retInt); + DISPATCH_TABLE_FD[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_D", retInt); + DISPATCH_TABLE_FD[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_E", retInt); + DISPATCH_TABLE_FD[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_IYH", retInt); + DISPATCH_TABLE_FD[0x7D] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_IYL", retInt); + DISPATCH_TABLE_FD[0x7E] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0x7F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_A", retInt); + DISPATCH_TABLE_FD[0x80] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_B", retInt); + DISPATCH_TABLE_FD[0x81] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_C", retInt); + DISPATCH_TABLE_FD[0x82] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_D", retInt); + DISPATCH_TABLE_FD[0x83] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_E", retInt); DISPATCH_TABLE_FD[0x84] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IYH", retInt); DISPATCH_TABLE_FD[0x85] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_IYL", retInt); - DISPATCH_TABLE_FD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_R", retInt); - DISPATCH_TABLE_FD[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE_FD[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE_FD[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE_FD[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); + DISPATCH_TABLE_FD[0x86] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0x87] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_A", retInt); + DISPATCH_TABLE_FD[0x88] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_B", retInt); + DISPATCH_TABLE_FD[0x89] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_C", retInt); + DISPATCH_TABLE_FD[0x8A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_D", retInt); + DISPATCH_TABLE_FD[0x8B] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_E", retInt); DISPATCH_TABLE_FD[0x8C] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IYH", retInt); DISPATCH_TABLE_FD[0x8D] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_IYL", retInt); - DISPATCH_TABLE_FD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_R", retInt); - DISPATCH_TABLE_FD[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE_FD[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE_FD[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE_FD[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); + DISPATCH_TABLE_FD[0x8E] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0x8F] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_A", retInt); + DISPATCH_TABLE_FD[0x90] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_B", retInt); + DISPATCH_TABLE_FD[0x91] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_C", retInt); + DISPATCH_TABLE_FD[0x92] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_D", retInt); + DISPATCH_TABLE_FD[0x93] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_E", retInt); DISPATCH_TABLE_FD[0x94] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IYH", retInt); DISPATCH_TABLE_FD[0x95] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_IYL", retInt); - DISPATCH_TABLE_FD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_R", retInt); - DISPATCH_TABLE_FD[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE_FD[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE_FD[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE_FD[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); + DISPATCH_TABLE_FD[0x96] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0x97] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_A", retInt); + DISPATCH_TABLE_FD[0x98] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_B", retInt); + DISPATCH_TABLE_FD[0x99] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_C", retInt); + DISPATCH_TABLE_FD[0x9A] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_D", retInt); + DISPATCH_TABLE_FD[0x9B] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_E", retInt); DISPATCH_TABLE_FD[0x9C] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IYH", retInt); DISPATCH_TABLE_FD[0x9D] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_IYL", retInt); - DISPATCH_TABLE_FD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_R", retInt); - DISPATCH_TABLE_FD[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE_FD[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE_FD[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE_FD[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); + DISPATCH_TABLE_FD[0x9E] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0x9F] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_A", retInt); + DISPATCH_TABLE_FD[0xA0] = lookup.findVirtual(EmulatorEngine.class, "I_AND_B", retInt); + DISPATCH_TABLE_FD[0xA1] = lookup.findVirtual(EmulatorEngine.class, "I_AND_C", retInt); + DISPATCH_TABLE_FD[0xA2] = lookup.findVirtual(EmulatorEngine.class, "I_AND_D", retInt); + DISPATCH_TABLE_FD[0xA3] = lookup.findVirtual(EmulatorEngine.class, "I_AND_E", retInt); DISPATCH_TABLE_FD[0xA4] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IYH", retInt); DISPATCH_TABLE_FD[0xA5] = lookup.findVirtual(EmulatorEngine.class, "I_AND_IYL", retInt); - DISPATCH_TABLE_FD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_AND_R", retInt); - DISPATCH_TABLE_FD[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE_FD[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE_FD[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE_FD[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); + DISPATCH_TABLE_FD[0xA6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0xA7] = lookup.findVirtual(EmulatorEngine.class, "I_AND_A", retInt); + DISPATCH_TABLE_FD[0xA8] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_B", retInt); + DISPATCH_TABLE_FD[0xA9] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_C", retInt); + DISPATCH_TABLE_FD[0xAA] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_D", retInt); + DISPATCH_TABLE_FD[0xAB] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_E", retInt); DISPATCH_TABLE_FD[0xAC] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IYH", retInt); DISPATCH_TABLE_FD[0xAD] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_IYL", retInt); - DISPATCH_TABLE_FD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_R", retInt); - DISPATCH_TABLE_FD[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE_FD[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE_FD[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE_FD[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); + DISPATCH_TABLE_FD[0xAE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0xAF] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_A", retInt); + DISPATCH_TABLE_FD[0xB0] = lookup.findVirtual(EmulatorEngine.class, "I_OR_B", retInt); + DISPATCH_TABLE_FD[0xB1] = lookup.findVirtual(EmulatorEngine.class, "I_OR_C", retInt); + DISPATCH_TABLE_FD[0xB2] = lookup.findVirtual(EmulatorEngine.class, "I_OR_D", retInt); + DISPATCH_TABLE_FD[0xB3] = lookup.findVirtual(EmulatorEngine.class, "I_OR_E", retInt); DISPATCH_TABLE_FD[0xB4] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IYH", retInt); DISPATCH_TABLE_FD[0xB5] = lookup.findVirtual(EmulatorEngine.class, "I_OR_IYL", retInt); - DISPATCH_TABLE_FD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_OR_R", retInt); - DISPATCH_TABLE_FD[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE_FD[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE_FD[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); - DISPATCH_TABLE_FD[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE_FD[0xB6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0xB7] = lookup.findVirtual(EmulatorEngine.class, "I_OR_A", retInt); + DISPATCH_TABLE_FD[0xB8] = lookup.findVirtual(EmulatorEngine.class, "I_CP_B", retInt); + DISPATCH_TABLE_FD[0xB9] = lookup.findVirtual(EmulatorEngine.class, "I_CP_C", retInt); + DISPATCH_TABLE_FD[0xBA] = lookup.findVirtual(EmulatorEngine.class, "I_CP_D", retInt); + DISPATCH_TABLE_FD[0xBB] = lookup.findVirtual(EmulatorEngine.class, "I_CP_E", retInt); DISPATCH_TABLE_FD[0xBC] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IYH", retInt); DISPATCH_TABLE_FD[0xBD] = lookup.findVirtual(EmulatorEngine.class, "I_CP_IYL", retInt); - DISPATCH_TABLE_FD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IY_N", retInt); - DISPATCH_TABLE_FD[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CP_R", retInt); + DISPATCH_TABLE_FD[0xBE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_REF_IY_D", retInt); + DISPATCH_TABLE_FD[0xBF] = lookup.findVirtual(EmulatorEngine.class, "I_CP_A", retInt); + DISPATCH_TABLE_FD[0xC0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE_FD[0xC1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_BC", retInt); + DISPATCH_TABLE_FD[0xC2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_FD[0xC3] = lookup.findVirtual(EmulatorEngine.class, "I_JP_NN", retInt); + DISPATCH_TABLE_FD[0xC4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_FD[0xC5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_BC", retInt); + DISPATCH_TABLE_FD[0xC6] = lookup.findVirtual(EmulatorEngine.class, "I_ADD_A_N", retInt); + DISPATCH_TABLE_FD[0xC7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_FD[0xC8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE_FD[0xC9] = lookup.findVirtual(EmulatorEngine.class, "I_RET", retInt); + DISPATCH_TABLE_FD[0xCA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); DISPATCH_TABLE_FD[0xCB] = lookup.findVirtual(EmulatorEngine.class, "FD_CB_DISPATCH", retInt); + DISPATCH_TABLE_FD[0xCC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_FD[0xCD] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_NN", retInt); + DISPATCH_TABLE_FD[0xCE] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_A_N", retInt); + DISPATCH_TABLE_FD[0xCF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_FD[0xD0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE_FD[0xD1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_DE", retInt); + DISPATCH_TABLE_FD[0xD2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_FD[0xD3] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_N_A", retInt); + DISPATCH_TABLE_FD[0xD4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_FD[0xD5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_DE", retInt); + DISPATCH_TABLE_FD[0xD6] = lookup.findVirtual(EmulatorEngine.class, "I_SUB_N", retInt); + DISPATCH_TABLE_FD[0xD7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_FD[0xD8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE_FD[0xD9] = lookup.findVirtual(EmulatorEngine.class, "I_EXX", retInt); + DISPATCH_TABLE_FD[0xDA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_FD[0xDB] = lookup.findVirtual(EmulatorEngine.class, "I_IN_A_REF_N", retInt); + DISPATCH_TABLE_FD[0xDC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_FD[0xDD] = lookup.findVirtual(EmulatorEngine.class, "DD_DISPATCH", retInt); + DISPATCH_TABLE_FD[0xDE] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_A_N", retInt); + DISPATCH_TABLE_FD[0xDF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_FD[0xE0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); DISPATCH_TABLE_FD[0xE1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_IY", retInt); + DISPATCH_TABLE_FD[0xE2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); DISPATCH_TABLE_FD[0xE3] = lookup.findVirtual(EmulatorEngine.class, "I_EX_REF_SP_IY", retInt); + DISPATCH_TABLE_FD[0xE4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); DISPATCH_TABLE_FD[0xE5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_IY", retInt); + DISPATCH_TABLE_FD[0xE6] = lookup.findVirtual(EmulatorEngine.class, "I_AND_N", retInt); + DISPATCH_TABLE_FD[0xE7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_FD[0xE8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); DISPATCH_TABLE_FD[0xE9] = lookup.findVirtual(EmulatorEngine.class, "I_JP_REF_IY", retInt); + DISPATCH_TABLE_FD[0xEA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_FD[0xEB] = lookup.findVirtual(EmulatorEngine.class, "I_EX_DE_HL", retInt); + DISPATCH_TABLE_FD[0xEC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_FD[0xED] = lookup.findVirtual(EmulatorEngine.class, "ED_DISPATCH", retInt); + DISPATCH_TABLE_FD[0xEE] = lookup.findVirtual(EmulatorEngine.class, "I_XOR_N", retInt); + DISPATCH_TABLE_FD[0xEF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_FD[0xF0] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); + DISPATCH_TABLE_FD[0xF1] = lookup.findVirtual(EmulatorEngine.class, "I_POP_AF", retInt); + DISPATCH_TABLE_FD[0xF2] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_FD[0xF3] = lookup.findVirtual(EmulatorEngine.class, "I_DI", retInt); + DISPATCH_TABLE_FD[0xF4] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_FD[0xF5] = lookup.findVirtual(EmulatorEngine.class, "I_PUSH_AF", retInt); + DISPATCH_TABLE_FD[0xF6] = lookup.findVirtual(EmulatorEngine.class, "I_OR_N", retInt); + DISPATCH_TABLE_FD[0xF7] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); + DISPATCH_TABLE_FD[0xF8] = lookup.findVirtual(EmulatorEngine.class, "I_RET_CC", retInt); DISPATCH_TABLE_FD[0xF9] = lookup.findVirtual(EmulatorEngine.class, "I_LD_SP_IY", retInt); + DISPATCH_TABLE_FD[0xFA] = lookup.findVirtual(EmulatorEngine.class, "I_JP_CC_NN", retInt); + DISPATCH_TABLE_FD[0xFB] = lookup.findVirtual(EmulatorEngine.class, "I_EI", retInt); + DISPATCH_TABLE_FD[0xFC] = lookup.findVirtual(EmulatorEngine.class, "I_CALL_CC_NN", retInt); + DISPATCH_TABLE_FD[0xFD] = lookup.findVirtual(EmulatorEngine.class, "FD_DISPATCH", retInt); + DISPATCH_TABLE_FD[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_N", retInt); + DISPATCH_TABLE_FD[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); DISPATCH_TABLE_DD_CB[0x00] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", retIntByte); DISPATCH_TABLE_DD_CB[0x01] = lookup.findVirtual(EmulatorEngine.class, "I_RLC_REF_IX_N_R", retIntByte); diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index e06a45835..02c3289db 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -437,610 +437,1522 @@ int I_NOP() { } int I_LD_REF_BC_A() { - memory.write(getpair(0, false), (byte) regs[REG_A]); + memory.write(regs[REG_B] << 8 | regs[REG_C], (byte) regs[REG_A]); memptr = (regs[REG_A] << 8) | 1; // Note for *BM1: MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = 0 return 7; } - int I_INC_RP() { - int tmp = (lastOpcode >>> 4) & 0x03; - putpair(tmp, (getpair(tmp, true) + 1) & 0xFFFF, true); - return 6; + int I_LD_BC_NN() { + return I_LD_RP_NN(REG_C, REG_B); } - int I_ADD_HL_RP() { - int rp = getpair((lastOpcode >>> 4) & 0x03, true); - int hl = (regs[REG_H] << 8) | regs[REG_L]; - memptr = (hl + 1) & 0xFFFF; - - int res = hl + rp; - flags = (flags & FLAG_SZP) | - (((hl ^ res ^ rp) >>> 8) & FLAG_H) | - ((res >>> 16) & FLAG_C) | TABLE_XY[(res >>> 8) & 0xFF]; - Q = flags; - - regs[REG_H] = (res >>> 8) & 0xFF; - regs[REG_L] = res & 0xFF; + int I_LD_DE_NN() { + return I_LD_RP_NN(REG_E, REG_D); + } - return 11; + int I_LD_HL_NN() { + return I_LD_RP_NN(REG_L, REG_H); } - int I_DEC_RP() { - int regPair = (lastOpcode >>> 4) & 0x03; - putpair(regPair, (getpair(regPair, true) - 1) & 0xFFFF, true); - return 6; + int I_LD_SP_NN() { + SP = readWord(PC); + PC = (PC + 2) & 0xFFFF; + return 10; } - int I_POP_RP() { - int regPair = (lastOpcode >>> 4) & 0x03; - int value = readWord(SP); - SP = (SP + 2) & 0xffff; - putpair(regPair, value, false); + int I_LD_RP_NN(int low, int high) { + int tmp = readWord(PC); + PC = (PC + 2) & 0xFFFF; + regs[high] = tmp >>> 8; + regs[low] = tmp & 0xFF; return 10; } - int I_PUSH_RP() { - int regPair = (lastOpcode >>> 4) & 0x03; - int value = getpair(regPair, false); - SP = (SP - 2) & 0xffff; - writeWord(SP, value); - return 11; + int I_INC_BC() { + return I_INC_RP(REG_C, REG_B, regs[REG_B] << 8 | regs[REG_C]); } - int I_LD_R_N() { - int reg = (lastOpcode >>> 3) & 0x07; - putreg(reg, memory.read(PC)); - PC = (PC + 1) & 0xFFFF; - if (reg == 6) { - return 10; - } else { - return 7; - } + int I_INC_DE() { + return I_INC_RP(REG_E, REG_D, regs[REG_D] << 8 | regs[REG_E]); } - int I_INC_R() { - int reg = (lastOpcode >>> 3) & 0x07; - int regValue = getreg(reg); - int sum = (regValue + 1) & 0x1FF; - int sumByte = sum & 0xFF; - flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C) | TABLE_XY[sumByte]; - Q = flags; - putreg(reg, sumByte); - return (reg == 6) ? 11 : 4; + int I_INC_HL() { + return I_INC_RP(REG_L, REG_H, regs[REG_H] << 8 | regs[REG_L]); } - int I_DEC_R() { - int reg = (lastOpcode >>> 3) & 0x07; - int regValue = getreg(reg); - int sum = (regValue - 1) & 0x1FF; - int sumByte = sum & 0xFF; - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ regValue]) | (flags & FLAG_C) | TABLE_XY[sumByte]; - Q = flags; - putreg(reg, sumByte); - return (reg == 6) ? 11 : 4; + int I_INC_SP() { + SP = (SP + 1) & 0xFFFF; + return 6; } - int I_RET_CC() { - int cc = (lastOpcode >>> 3) & 7; - if ((flags & CONDITION[cc]) == CONDITION_VALUES[cc]) { - PC = readWord(SP); - SP = (SP + 2) & 0xffff; - return 11; - } - return 5; + int I_INC_IX() { + IX = (IX + 1) & 0xFFFF; + return 10; } - int I_RST() { - SP = (SP - 2) & 0xffff; - writeWord(SP, PC); - PC = lastOpcode & 0x38; - memptr = PC; - return 11; + int I_INC_IY() { + IY = (IY + 1) & 0xFFFF; + return 10; } - int I_ADD_A_R() { - int value = getreg(lastOpcode & 0x07); - int oldA = regs[REG_A]; - int sum = (oldA + value) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; - Q = flags; - return (lastOpcode == 0x86) ? 7 : 4; + int I_INC_RP(int low, int high, int value) { + int result = (value + 1) & 0xFFFF; + regs[high] = result >>> 8; + regs[low] = result & 0xFF; + return 6; } - int I_ADD_A_N() { - int value = memory.read(PC) & 0xFF; - PC = (PC + 1) & 0xFFFF; - int oldA = regs[REG_A]; - int sum = (oldA + value) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; - Q = flags; - return 7; + int I_INC_B() { + regs[REG_B] = I_INC(regs[REG_B]); + return 4; } - int I_ADC_A_R() { - int value = getreg(lastOpcode & 0x07); - int oldA = regs[REG_A]; - int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; - Q = flags; - return (lastOpcode == 0x8E) ? 7 : 4; + int I_INC_C() { + regs[REG_C] = I_INC(regs[REG_C]); + return 4; } - int I_ADC_A_N() { - int value = memory.read(PC) & 0xFF; - PC = (PC + 1) & 0xFFFF; - int oldA = regs[REG_A]; - int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; - Q = flags; - return 7; + int I_INC_D() { + regs[REG_D] = I_INC(regs[REG_D]); + return 4; } - int I_SUB_R() { - int value = getreg(lastOpcode & 0x07); + int I_INC_E() { + regs[REG_E] = I_INC(regs[REG_E]); + return 4; + } - int oldA = regs[REG_A]; - int sum = (oldA - value) & 0x1FF; - regs[REG_A] = sum & 0xFF; + int I_INC_H() { + regs[REG_H] = I_INC(regs[REG_H]); + return 4; + } - flags = TABLE_SUB[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; - Q = flags; - return (lastOpcode == 0x96) ? 7 : 4; + int I_INC_L() { + regs[REG_L] = I_INC(regs[REG_L]); + return 4; } - int I_SBC_A_R() { - int value = getreg(lastOpcode & 0x07); + int I_INC_A() { + regs[REG_A] = I_INC(regs[REG_A]); + return 4; + } - int oldA = regs[REG_A]; - int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; - regs[REG_A] = sum & 0xFF; + int I_INC_REF_HL() { + int value = memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF; + memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) I_INC(value)); + return 11; + } - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; - Q = flags; - return (lastOpcode == 0x9E) ? 7 : 4; + int I_INC_IXH() { + IX = ((I_INC(IX >>> 8) << 8) | (IX & 0xFF)) & 0xFFFF; + return 8; } - int I_SBC_A_N() { - int value = memory.read(PC) & 0xFF; - PC = (PC + 1) & 0xFFFF; + int I_INC_IYH() { + IY = ((I_INC(IY >>> 8) << 8) | (IY & 0xFF)) & 0xFFFF; + return 8; + } - int oldA = regs[REG_A]; - int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; - regs[REG_A] = sum & 0xFF; + int I_INC_IXL() { + IX = ((IX & 0xFF00) | I_INC(IX & 0xFF)) & 0xFFFF; + return 8; + } - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; - Q = flags; - return 7; + int I_INC_IYL() { + IY = ((IY & 0xFF00) | I_INC(IY & 0xFF)) & 0xFFFF; + return 8; } - int I_AND_R() { - regs[REG_A] = (regs[REG_A] & getreg(lastOpcode & 7)) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + int I_INC(int value) { + int sum = (value + 1) & 0x1FF; + int sumByte = sum & 0xFF; + flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | TABLE_XY[sumByte]; Q = flags; - return (lastOpcode == 0xA6) ? 7 : 4; + return sumByte; } - int I_AND_N() { - int tmp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - - regs[REG_A] = (regs[REG_A] & tmp) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; - Q = flags; - return 7; + int I_DEC_BC() { + return I_DEC_RP(REG_C, REG_B, regs[REG_B] << 8 | regs[REG_C]); } - int I_XOR_R() { - regs[REG_A] = ((regs[REG_A] ^ getreg(lastOpcode & 7)) & 0xff); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; - Q = flags; - return (lastOpcode == 0xAE) ? 7 : 4; + int I_DEC_DE() { + return I_DEC_RP(REG_E, REG_D, regs[REG_D] << 8 | regs[REG_E]); } - int I_XOR_N() { - int tmp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; + int I_DEC_HL() { + return I_DEC_RP(REG_L, REG_H, regs[REG_H] << 8 | regs[REG_L]); + } - regs[REG_A] = ((regs[REG_A] ^ tmp) & 0xFF); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; - Q = flags; - return 7; + int I_DEC_SP() { + SP = (SP - 1) & 0xFFFF; + return 6; } - int I_OR_R() { - regs[REG_A] = (regs[REG_A] | getreg(lastOpcode & 7)) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; - Q = flags; - return (lastOpcode == 0xB6) ? 7 : 4; + int I_DEC_IX() { + IX = (IX - 1) & 0xFFFF; + return 10; } - int I_OR_N() { - int tmp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; + int I_DEC_IY() { + IY = (IY - 1) & 0xFFFF; + return 10; + } - regs[REG_A] = (regs[REG_A] | tmp) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; - Q = flags; - return 7; + int I_DEC_RP(int low, int high, int value) { + value = (value - 1) & 0xFFFF; + regs[high] = value >>> 8; + regs[low] = value & 0xFF; + return 6; } - int I_CP_R() { - int value = getreg(lastOpcode & 7); - int oldA = regs[REG_A]; - int sum = (oldA - value) & 0x1FF; - int result = sum & 0xFF; - // F5 and F3 flags are set from the subtrahend instead of from the result. - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[value]; - Q = flags; - return (lastOpcode == 0xBE) ? 7 : 4; + int I_DEC_B() { + regs[REG_B] = I_DEC(regs[REG_B]); + return 4; } - int I_CP_N() { - int value = memory.read(PC) & 0xFF; - PC = (PC + 1) & 0xFFFF; + int I_DEC_C() { + regs[REG_C] = I_DEC(regs[REG_C]); + return 4; + } - int oldA = regs[REG_A]; - int sum = (oldA - value) & 0x1FF; - int result = sum & 0xFF; - flags = (TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA])) | TABLE_XY[value]; - Q = flags; - return 7; + int I_DEC_D() { + regs[REG_D] = I_DEC(regs[REG_D]); + return 4; } - int I_RLCA() { - regs[REG_A] = TABLE_RLCA[regs[REG_A]]; - flags = (flags & FLAG_SZP) | (regs[REG_A] & (FLAG_X | FLAG_Y | FLAG_C)); - Q = flags; + int I_DEC_E() { + regs[REG_E] = I_DEC(regs[REG_E]); return 4; } - int I_EX_AF_AFF() { - regs[REG_A] ^= regs2[REG_A]; - regs2[REG_A] ^= regs[REG_A]; - regs[REG_A] ^= regs2[REG_A]; - flags ^= flags2; - flags2 ^= flags; - flags ^= flags2; + int I_DEC_H() { + regs[REG_H] = I_DEC(regs[REG_H]); return 4; } - int I_LD_A_REF_BC() { - int bc = regs[REG_B] << 8 | regs[REG_C]; - regs[REG_A] = memory.read(bc) & 0xFF; - memptr = bc; - return 7; + int I_DEC_L() { + regs[REG_L] = I_DEC(regs[REG_L]); + return 4; } - int I_RRCA() { - flags = (flags & FLAG_SZP) | (regs[REG_A] & FLAG_C); - regs[REG_A] = TABLE_RRCA[regs[REG_A]]; - flags |= TABLE_XY[regs[REG_A]]; - Q = flags; + int I_DEC_A() { + regs[REG_A] = I_DEC(regs[REG_A]); return 4; } - int I_DJNZ() { - byte addr = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - regs[REG_B] = (regs[REG_B] - 1) & 0xFF; - if (regs[REG_B] != 0) { - PC = (PC + addr) & 0xFFFF; - memptr = PC; - return 13; - } + int I_DEC_REF_HL() { + int value = memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF; + memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) I_DEC(value)); + return 11; + } + + int I_DEC_IXH() { + IX = ((I_DEC(IX >>> 8) << 8) | (IX & 0xFF)) & 0xFFFF; return 8; } - int I_LD_REF_DE_A() { - memory.write(getpair(1, false), (byte) regs[REG_A]); - memptr = (regs[REG_A] << 8) | 2; - //_memPtr = A * 256 + ((DE + 1) & 0xFF); - // Note for *BM1: MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = 0 - return 7; + int I_DEC_IYH() { + IY = ((I_DEC(IY >>> 8) << 8) | (IY & 0xFF)) & 0xFFFF; + return 8; } - int I_RLA() { - int res = ((regs[REG_A] << 1) | (flags & FLAG_C)) & 0xFF; - int flagC = ((regs[REG_A] & 0x80) == 0x80) ? FLAG_C : 0; - regs[REG_A] = res; - flags = (flags & FLAG_SZP) | flagC | TABLE_XY[res]; - Q = flags; - return 4; + int I_DEC_IXL() { + IX = ((IX & 0xFF00) | (I_DEC(IX & 0xFF) & 0xFF)) & 0xFFFF; + return 8; } - int I_LD_A_REF_DE() { - int de = regs[REG_D] << 8 | regs[REG_E]; - regs[REG_A] = memory.read(de) & 0xFF; - memptr = de; - return 7; + int I_DEC_IYL() { + IY = ((IY & 0xFF00) | (I_DEC(IY & 0xFF) & 0xFF)) & 0xFFFF; + return 8; } - int I_RRA() { - int res = ((regs[REG_A] >>> 1) | (flags << 7)) & 0xFF; - int flagC = regs[REG_A] & FLAG_C; - flags = (flags & FLAG_SZP) | flagC | TABLE_XY[res]; - Q = flags; - regs[REG_A] = res; - return 4; + int I_DEC_REF_IX_N() { + return I_DEC_REF_II_N(IX); } - int I_DAA() { - // The following algorithm is from comp.sys.sinclair's FAQ. - int c, d; - - int a = regs[REG_A]; - if (a > 0x99 || ((flags & FLAG_C) != 0)) { - c = FLAG_C; - d = 0x60; - } else { - c = d = 0; - } - - if ((a & 0x0f) > 0x09 || ((flags & FLAG_H) != 0)) { - d += 0x06; - } + int I_DEC_REF_IY_N() { + return I_DEC_REF_II_N(IY); + } - regs[REG_A] = ((flags & FLAG_N) != 0 ? regs[REG_A] - d : regs[REG_A] + d) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] - | PARITY_TABLE[regs[REG_A]] - | TABLE_XY[regs[REG_A]] - | ((regs[REG_A] ^ a) & FLAG_H) - | (flags & FLAG_N) - | c; + int I_DEC(int value) { + int sum = (value - 1) & 0x1FF; + int sumByte = sum & 0xFF; + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | TABLE_XY[sumByte]; Q = flags; - return 4; + return sumByte; } - int I_CPL() { - regs[REG_A] = (~regs[REG_A]) & 0xFF; - flags = (flags & (FLAG_SZP | FLAG_C)) - | FLAG_H | FLAG_N - | (regs[REG_A] & (FLAG_X | FLAG_Y)); - Q = flags; + int I_DEC_REF_II_N(int special) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (special + disp) & 0xFFFF; + int value = memory.read(address) & 0xFF; + memptr = address; -// flags = (flags & (FLAG_SZP | FLAG_C)) -// | FLAG_H | FLAG_N -// | TABLE_XY[regs[REG_A]]; - return 4; + int sum = (value - 1) & 0x1FF; + int sumByte = sum & 0xFF; + + flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | TABLE_XY[sumByte]; + memory.write(address, (byte) sumByte); + return 23; } - int I_SCF() { - flags = (flags & FLAG_SZP) | (((lastQ ^ flags) | regs[REG_A]) & (FLAG_X | FLAG_Y)) | FLAG_C; - Q = flags; + int I_LD_B_N() { + return I_LD_R_N(REG_B); + } - //flags = (flags & FLAG_SZP) | TABLE_XY[regs[REG_A]] | FLAG_C; - return 4; + int I_LD_C_N() { + return I_LD_R_N(REG_C); } - int I_CCF() { - flags = (flags & FLAG_SZP) - | ((flags & FLAG_C) == 0 ? FLAG_C : FLAG_H) - | (((lastQ ^ flags) | regs[REG_A]) & (FLAG_X | FLAG_Y)); - Q = flags; + int I_LD_D_N() { + return I_LD_R_N(REG_D); + } -// int c = flags & FLAG_C; - // flags = (flags & FLAG_SZP) | (c << 4) - // | TABLE_XY[regs[REG_A]] - // | (c ^ FLAG_C); - return 4; + int I_LD_E_N() { + return I_LD_R_N(REG_E); } - int I_RET() { - PC = readWord(SP); - memptr = PC; - SP = (SP + 2) & 0xFFFF; - return 10; + int I_LD_H_N() { + return I_LD_R_N(REG_H); } - int I_EXX() { - // https://www.baeldung.com/java-swap-two-variables - regs[REG_B] ^= regs2[REG_B]; - regs2[REG_B] ^= regs[REG_B]; - regs[REG_B] ^= regs2[REG_B]; + int I_LD_L_N() { + return I_LD_R_N(REG_L); + } - regs[REG_C] ^= regs2[REG_C]; - regs2[REG_C] ^= regs[REG_C]; - regs[REG_C] ^= regs2[REG_C]; + int I_LD_A_N() { + return I_LD_R_N(REG_A); + } - regs[REG_D] ^= regs2[REG_D]; - regs2[REG_D] ^= regs[REG_D]; - regs[REG_D] ^= regs2[REG_D]; + int I_LD_REF_HL_N() { + memory.write((regs[REG_H] << 8) | regs[REG_L], memory.read(PC)); + PC = (PC + 1) & 0xFFFF; + return 10; + } - regs[REG_E] ^= regs2[REG_E]; - regs2[REG_E] ^= regs[REG_E]; - regs[REG_E] ^= regs2[REG_E]; + int I_LD_R_N(int reg) { + regs[reg] = memory.read(PC) & 0xFF; + PC = (PC + 1) & 0xFFFF; + return 7; + } - regs[REG_H] ^= regs2[REG_H]; - regs2[REG_H] ^= regs[REG_H]; - regs[REG_H] ^= regs2[REG_H]; + int I_LD_REF_IX_D_N() { + return I_LD_REF_II_D_N(IX); + } - regs[REG_L] ^= regs2[REG_L]; - regs2[REG_L] ^= regs[REG_L]; - regs[REG_L] ^= regs2[REG_L]; - return 4; + int I_LD_REF_IY_D_N() { + return I_LD_REF_II_D_N(IY); } - int I_EX_REF_SP_HL() { - byte value = memory.read(SP); - int SP_plus1 = (SP + 1) & 0xFFFF; - byte value1 = memory.read(SP_plus1); - memory.write(SP, (byte) regs[REG_L]); - memory.write(SP_plus1, (byte) regs[REG_H]); - regs[REG_L] = value & 0xFF; - regs[REG_H] = value1 & 0xFF; - memptr = (regs[REG_H] << 8) | regs[REG_L]; + int I_LD_REF_II_D_N(int special) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + byte number = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (special + disp) & 0xFFFF; + memptr = address; + memory.write(address, number); return 19; } - int I_JP_REF_HL() { - PC = ((regs[REG_H] << 8) | regs[REG_L]); - return 4; + int I_ADD_HL_BC() { + return I_ADD_HL_RP(regs[REG_B] << 8 | regs[REG_C]); } - int I_EX_DE_HL() { - regs[REG_D] ^= regs[REG_H]; - regs[REG_H] ^= regs[REG_D]; - regs[REG_D] ^= regs[REG_H]; + int I_ADD_HL_DE() { + return I_ADD_HL_RP(regs[REG_D] << 8 | regs[REG_E]); + } - regs[REG_E] ^= regs[REG_L]; - regs[REG_L] ^= regs[REG_E]; - regs[REG_E] ^= regs[REG_L]; - return 4; + int I_ADD_HL_HL() { + return I_ADD_HL_RP(regs[REG_H] << 8 | regs[REG_L]); } - int I_DI() { - IFF[0] = IFF[1] = false; - return 4; + int I_ADD_HL_SP() { + return I_ADD_HL_RP(SP); } - int I_LD_SP_HL() { - SP = ((regs[REG_H] << 8) | regs[REG_L]); - return 6; + int I_ADD_IX_BC() { + return I_ADD_IX_RP(regs[REG_B] << 8 | regs[REG_C]); } - int I_EI() { - // https://www.smspower.org/forums/2511-LDILDIRLDDLDDRCRCInZEXALL - // interrupts are not allowed until after the *next* instruction after EI. - // This is used to prevent interrupts from occurring between an EI/RETI pair used at the end of interrupt handlers. - if (!IFF[0]) { - interruptSkip = true; - } - IFF[0] = IFF[1] = true; - return 4; + int I_ADD_IX_DE() { + return I_ADD_IX_RP(regs[REG_D] << 8 | regs[REG_E]); } - int I_IN_R_REF_C() { - int reg = (lastOpcode >>> 3) & 0x7; - putreg(reg, context.readIO((regs[REG_B] << 8) | regs[REG_C])); - memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; - flags = (flags & FLAG_C) | TABLE_SZ[regs[reg]] | PARITY_TABLE[regs[reg]] | TABLE_XY[regs[reg]]; - Q = flags; - return 12; + int I_ADD_IX_IX() { + return I_ADD_IX_RP(IX); } - int I_OUT_REF_C_R() { - int reg = (lastOpcode >>> 3) & 0x7; - memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; - context.writeIO((regs[REG_B] << 8) | regs[REG_C], (byte) getreg(reg)); - return 12; + int I_ADD_IX_SP() { + return I_ADD_IX_RP(SP); } - int I_SBC_HL_RP() { - int rp = getpair((lastOpcode >>> 4) & 0x03, true); - int hl = ((regs[REG_H] << 8) | regs[REG_L]) & 0xFFFF; - memptr = (hl + 1) & 0xFFFF; - int res = hl - rp - (flags & FLAG_C); + int I_ADD_IY_BC() { + return I_ADD_IY_RP(regs[REG_B] << 8 | regs[REG_C]); + } - flags = (((hl ^ res ^ rp) >>> 8) & FLAG_H) | FLAG_N | - ((res >>> 16) & FLAG_C) | - ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | - (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | - (((rp ^ hl) & (hl ^ res) & 0x8000) >>> 13); - Q = flags; + int I_ADD_IY_DE() { + return I_ADD_IY_RP(regs[REG_D] << 8 | regs[REG_E]); + } + + int I_ADD_IY_IY() { + return I_ADD_IY_RP(IY); + } + + int I_ADD_IY_SP() { + return I_ADD_IY_RP(SP); + } + int I_ADD_HL_RP(int rp) { + int res = I_ADD_SRC_RP((regs[REG_H] << 8) | regs[REG_L], rp); regs[REG_H] = (res >>> 8) & 0xFF; regs[REG_L] = res & 0xFF; + return 11; + } + + int I_ADD_IX_RP(int rp) { + memptr = (IX + 1) & 0xFFFF; + IX = I_ADD_SRC_RP2(IX, rp); return 15; } - int I_ADC_HL_RP() { - int rp = getpair((lastOpcode >>> 4) & 0x03, true); - int hl = (regs[REG_H] << 8 | regs[REG_L]) & 0xFFFF; - memptr = (hl + 1) & 0xFFFF; - int res = hl + rp + (flags & FLAG_C); + int I_ADD_IY_RP(int rp) { + memptr = (IY + 1) & 0xFFFF; + IY = I_ADD_SRC_RP2(IY, rp); + return 15; + } - flags = (((hl ^ res ^ rp) >>> 8) & FLAG_H) | - ((res >>> 16) & FLAG_C) | - ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | - (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | - (((rp ^ hl ^ 0x8000) & (rp ^ res) & 0x8000) >>> 13); + int I_ADD_SRC_RP(int src, int rp) { + int res = I_ADD_SRC_RP2(src, rp); Q = flags; + return res & 0xFFFF; + } - regs[REG_H] = (res >>> 8) & 0xFF; - regs[REG_L] = (res & 0xFF); - return 11; + int I_ADD_SRC_RP2(int src, int rp) { + memptr = (src + 1) & 0xFFFF; + int res = src + rp; + flags = (flags & FLAG_SZP) | + (((src ^ res ^ rp) >>> 8) & FLAG_H) | + ((res >>> 16) & FLAG_C) | TABLE_XY[(res >>> 8) & 0xFF]; + return res & 0xFFFF; } - int I_NEG() { - int v = regs[REG_A]; - regs[REG_A] = 0; - return I_SUB(v); + int I_POP_BC() { + return I_POP_RP(REG_C, REG_B); } - int I_RETN() { - IFF[0] = IFF[1]; - PC = readWord(SP); - SP = (SP + 2) & 0xffff; - return 14; + int I_POP_DE() { + return I_POP_RP(REG_E, REG_D); } - int I_IM_0() { - interruptMode = 0; - return 8; + int I_POP_HL() { + return I_POP_RP(REG_L, REG_H); } - int I_LD_I_A() { - I = regs[REG_A]; - return 9; + int I_POP_AF() { + int value = readWord(SP); + SP = (SP + 2) & 0xFFFF; + regs[REG_A] = value >>> 8; + flags = value & 0xFF; + return 10; } - int I_RETI() { - IFF[0] = IFF[1]; - PC = readWord(SP); - memptr = PC; - SP = (SP + 2) & 0xffff; + int I_POP_IX() { + IX = readWord(SP); + SP = (SP + 2) & 0xFFFF; return 14; } - int I_LD_R_A() { - R = regs[REG_A]; - return 9; + int I_POP_IY() { + IY = readWord(SP); + SP = (SP + 2) & 0xFFFF; + return 14; } - int I_IM_1() { - interruptMode = 1; - return 8; + int I_POP_RP(int low, int high) { + int value = readWord(SP); + SP = (SP + 2) & 0xFFFF; + regs[low] = value & 0xFF; + regs[high] = value >>> 8; + return 10; } - int I_IM_2() { - interruptMode = 2; - return 8; + int I_PUSH_BC() { + return I_PUSH_RP((regs[REG_B] << 8) | regs[REG_C]); } - int I_LD_A_I() { - regs[REG_A] = I & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; - Q = flags; - return 9; + int I_PUSH_DE() { + return I_PUSH_RP((regs[REG_D] << 8) | regs[REG_E]); } - int I_LD_A_R() { - regs[REG_A] = R & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; - Q = flags; - return 9; + int I_PUSH_HL() { + return I_PUSH_RP((regs[REG_H] << 8) | regs[REG_L]); } - int I_RRD() { - int regA = regs[REG_A] & 0x0F; - int hl = (regs[REG_H] << 8) | regs[REG_L]; - memptr = (hl + 1) & 0xFFFF; - int value = memory.read(hl); - regs[REG_A] = ((regs[REG_A] & 0xF0) | (value & 0x0F)); - value = ((value >>> 4) & 0x0F) | (regA << 4); - memory.write(hl, (byte) (value & 0xff)); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; - Q = flags; - return 18; + int I_PUSH_AF() { + return I_PUSH_RP((regs[REG_A] << 8) | (flags & 0xFF)); } - int I_RLD() { - int hl = (regs[REG_H] << 8) | regs[REG_L]; + int I_PUSH_IX() { + SP = (SP - 2) & 0xFFFF; + writeWord(SP, IX); + return 15; + } + + int I_PUSH_IY() { + SP = (SP - 2) & 0xFFFF; + writeWord(SP, IY); + return 15; + } + + int I_PUSH_RP(int value) { + SP = (SP - 2) & 0xffff; + writeWord(SP, value); + return 11; + } + + int I_RET_CC() { + int cc = (lastOpcode >>> 3) & 7; + if ((flags & CONDITION[cc]) == CONDITION_VALUES[cc]) { + PC = readWord(SP); + SP = (SP + 2) & 0xffff; + return 11; + } + return 5; + } + + int I_RST() { + SP = (SP - 2) & 0xffff; + writeWord(SP, PC); + PC = lastOpcode & 0x38; + memptr = PC; + return 11; + } + + int I_ADD_A_B() { + return I_ADD_A(regs[REG_B]); + } + + int I_ADD_A_C() { + return I_ADD_A(regs[REG_C]); + } + + int I_ADD_A_D() { + return I_ADD_A(regs[REG_D]); + } + + int I_ADD_A_E() { + return I_ADD_A(regs[REG_E]); + } + + int I_ADD_A_H() { + return I_ADD_A(regs[REG_H]); + } + + int I_ADD_A_IXH() { + return I_ADD_A(IX >>> 8) + 4; + } + + int I_ADD_A_IYH() { + return I_ADD_A(IY >>> 8) + 4; + } + + int I_ADD_A_L() { + return I_ADD_A(regs[REG_L]); + } + + int I_ADD_A_IXL() { + return I_ADD_A(IX & 0xFF) + 4; + } + + int I_ADD_A_IYL() { + return I_ADD_A(IY & 0xFF) + 4; + } + + int I_ADD_A_REF_HL() { + return I_ADD_A(memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF) + 3; + } + + int I_ADD_A_REF_IX_D() { + return I_ADD_A_REF_XY_D(IX); + } + + int I_ADD_A_REF_IY_D() { + return I_ADD_A_REF_XY_D(IY); + } + + int I_ADD_A_A() { + return I_ADD_A(regs[REG_A]); + } + + int I_ADD_A(int value) { + int oldA = regs[REG_A]; + int sum = (oldA + value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + Q = flags; + return 4; + } + + int I_ADD_A_REF_XY_D(int xy) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (xy + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address) & 0xFF; + int oldA = regs[REG_A]; + int sum = (oldA + value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + return 19; + } + + + int I_ADC_A_B() { + return I_ADC_A(regs[REG_B]); + } + + int I_ADC_A_C() { + return I_ADC_A(regs[REG_C]); + } + + int I_ADC_A_D() { + return I_ADC_A(regs[REG_D]); + } + + int I_ADC_A_E() { + return I_ADC_A(regs[REG_E]); + } + + int I_ADC_A_H() { + return I_ADC_A(regs[REG_H]); + } + + int I_ADC_A_IXH() { + return I_ADC_A(IX >>> 8) + 4; + } + + int I_ADC_A_IYH() { + return I_ADC_A(IY >>> 8) + 4; + } + + int I_ADC_A_L() { + return I_ADC_A(regs[REG_L]); + } + + int I_ADC_A_IXL() { + return I_ADC_A(IX & 0xFF) + 4; + } + + int I_ADC_A_IYL() { + return I_ADC_A(IY & 0xFF) + 4; + } + + int I_ADC_A_REF_HL() { + return I_ADC_A(memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF) + 3; + } + + int I_ADC_A_REF_IX_D() { + return I_ADC_A_REF_XY_D(IX); + } + + int I_ADC_A_REF_IY_D() { + return I_ADC_A_REF_XY_D(IY); + } + + int I_ADC_A_A() { + return I_ADC_A(regs[REG_A]); + } + + int I_ADC_A(int value) { + int oldA = regs[REG_A]; + int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + Q = flags; + return 4; + } + + int I_ADC_A_REF_XY_D(int xy) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (xy + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address) & 0xFF; + int oldA = regs[REG_A]; + int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + return 19; + } + + int I_SUB_B() { + return I_SUB(regs[REG_B]); + } + + int I_SUB_C() { + return I_SUB(regs[REG_C]); + } + + int I_SUB_D() { + return I_SUB(regs[REG_D]); + } + + int I_SUB_E() { + return I_SUB(regs[REG_E]); + } + + int I_SUB_H() { + return I_SUB(regs[REG_H]); + } + + int I_SUB_IXH() { + return I_SUB(IX >>> 8) + 4; + } + + int I_SUB_IYH() { + return I_SUB(IY >>> 8) + 4; + } + + int I_SUB_L() { + return I_SUB(regs[REG_L]); + } + + int I_SUB_IXL() { + return I_SUB(IX & 0xFF) + 4; + } + + int I_SUB_IYL() { + return I_SUB(IY & 0xFF) + 4; + } + + int I_SUB_REF_HL() { + return I_SUB(memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF) + 3; + } + + int I_SUB_REF_IX_D() { + return I_SUB_REF_XY_D(IX); + } + + int I_SUB_REF_IY_D() { + return I_SUB_REF_XY_D(IY); + } + + int I_SUB_A() { + return I_SUB(regs[REG_A]); + } + + int I_SUB(int value) { + int oldA = regs[REG_A]; + int sum = (oldA - value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SUB[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + Q = flags; + return 4; + } + + int I_SUB_REF_XY_D(int xy) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (xy + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address) & 0xFF; + int oldA = regs[REG_A]; + int sum = (oldA - value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; + return 19; + } + + int I_SBC_A_B() { + return I_SBC_A(regs[REG_B]); + } + + int I_SBC_A_C() { + return I_SBC_A(regs[REG_C]); + } + + int I_SBC_A_D() { + return I_SBC_A(regs[REG_D]); + } + + int I_SBC_A_E() { + return I_SBC_A(regs[REG_E]); + } + + int I_SBC_A_H() { + return I_SBC_A(regs[REG_H]); + } + + int I_SBC_A_IXH() { + return I_SBC_A(IX >>> 8) + 4; + } + + int I_SBC_A_IYH() { + return I_SBC_A(IY >>> 8) + 4; + } + + int I_SBC_A_L() { + return I_SBC_A(regs[REG_L]); + } + + int I_SBC_A_IXL() { + return I_SBC_A(IX & 0xFF) + 4; + } + + int I_SBC_A_IYL() { + return I_SBC_A(IY & 0xFF) + 4; + } + + int I_SBC_A_REF_HL() { + return I_SBC_A(memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF) + 3; + } + + int I_SBC_A_REF_IX_D() { + return I_SBC_A_REF_XY_D(IX); + } + + int I_SBC_A_REF_IY_D() { + return I_SBC_A_REF_XY_D(IY); + } + + int I_SBC_A_A() { + return I_SBC_A(regs[REG_A]); + } + + int I_SBC_A(int value) { + int oldA = regs[REG_A]; + int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; + Q = flags; + return 4; + } + + int I_SBC_A_REF_XY_D(int xy) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (xy + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address) & 0xFF; + int oldA = regs[REG_A]; + int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; + return 19; + } + + int I_AND_B() { + return I_AND(regs[REG_B]); + } + + int I_AND_C() { + return I_AND(regs[REG_C]); + } + + int I_AND_D() { + return I_AND(regs[REG_D]); + } + + int I_AND_E() { + return I_AND(regs[REG_E]); + } + + int I_AND_H() { + return I_AND(regs[REG_H]); + } + + int I_AND_IXH() { + return I_AND(IX >>> 8) + 4; // TODO: not Q + } + + int I_AND_IYH() { + return I_AND(IY >>> 8) + 4; // TODO: not Q + } + + int I_AND_L() { + return I_AND(regs[REG_L]); + } + + int I_AND_IXL() { + return I_AND(IX & 0xFF) + 4; // TODO: not Q + } + + int I_AND_IYL() { + return I_AND(IY & 0xFF) + 4; // TODO: not Q + } + + int I_AND_REF_HL() { + return I_AND(memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF) + 3; + } + + int I_AND_REF_IX_D() { + return I_AND_REF_XY_D(IX); + } + + int I_AND_REF_IY_D() { + return I_AND_REF_XY_D(IY); + } + + int I_AND_A() { + return I_AND(regs[REG_A]); + } + + int I_AND(int value) { + regs[REG_A] = (regs[REG_A] & value) & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; + return 4; + } + + int I_AND_REF_XY_D(int xy) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (xy + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address) & 0xFF; + regs[REG_A] = (regs[REG_A] & value) & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + return 19; + } + + int I_XOR_B() { + return I_XOR(regs[REG_B]); + } + + int I_XOR_C() { + return I_XOR(regs[REG_C]); + } + + int I_XOR_D() { + return I_XOR(regs[REG_D]); + } + + int I_XOR_E() { + return I_XOR(regs[REG_E]); + } + + int I_XOR_H() { + return I_XOR(regs[REG_H]); + } + + int I_XOR_IXH() { + return I_XOR(IX >>> 8) + 4; // TODO: not Q + } + + int I_XOR_IYH() { + return I_XOR(IY >>> 8) + 4; // TODO: not Q + } + + int I_XOR_L() { + return I_XOR(regs[REG_L]); + } + + int I_XOR_IXL() { + return I_XOR(IX & 0xFF) + 4; // TODO: not Q + } + + int I_XOR_IYL() { + return I_XOR(IY & 0xFF) + 4; // TODO: not Q + } + + int I_XOR_REF_HL() { + return I_XOR(memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF) + 3; + } + + int I_XOR_REF_IX_D() { + return I_XOR_REF_XY_D(IX); + } + + int I_XOR_REF_IY_D() { + return I_XOR_REF_XY_D(IY); + } + + int I_XOR_A() { + return I_XOR(regs[REG_A]); + } + + int I_XOR(int value) { + regs[REG_A] = ((regs[REG_A] ^ value) & 0xff); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; + return 4; + } + + int I_XOR_REF_XY_D(int xy) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (xy + disp) & 0xFFFF; + memptr = address; + byte value = memory.read(address); + regs[REG_A] = ((regs[REG_A] ^ value) & 0xff); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + return 19; + } + + int I_OR_B() { + return I_OR(regs[REG_B]); + } + + int I_OR_C() { + return I_OR(regs[REG_C]); + } + + int I_OR_D() { + return I_OR(regs[REG_D]); + } + + int I_OR_E() { + return I_OR(regs[REG_E]); + } + + int I_OR_H() { + return I_OR(regs[REG_H]); + } + + int I_OR_IXH() { + return I_OR(IX >>> 8) + 4; + } + + int I_OR_IXL() { + return I_OR(IX & 0xFF) + 4; + } + + int I_OR_L() { + return I_OR(regs[REG_L]); + } + + int I_OR_IYH() { + return I_OR(IY >>> 8) + 4; + } + + int I_OR_IYL() { + return I_OR(IY & 0xFF) + 4; + } + + int I_OR_REF_HL() { + return I_OR(memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF) + 3; + } + + int I_OR_REF_IX_D() { + return I_OR_REF_XY_D(IX); + } + + int I_OR_REF_IY_D() { + return I_OR_REF_XY_D(IY); + } + + int I_OR_A() { + return I_OR(regs[REG_A]); + } + + int I_OR(int value) { + regs[REG_A] = (regs[REG_A] | value) & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; + return 4; + } + + int I_OR_REF_XY_D(int xy) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (xy + disp) & 0xFFFF; + memptr = address; + byte value = memory.read(address); + regs[REG_A] = ((regs[REG_A] | value) & 0xff); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + return 19; + } + + int I_CP_B() { + return I_CP_R(regs[REG_B]); + } + + int I_CP_C() { + return I_CP_R(regs[REG_C]); + } + + int I_CP_D() { + return I_CP_R(regs[REG_D]); + } + + int I_CP_E() { + return I_CP_R(regs[REG_E]); + } + + int I_CP_H() { + return I_CP_R(regs[REG_H]); + } + + int I_CP_IXH() { + return I_CP_R(IX >>> 8) + 4; + } + + int I_CP_IYH() { + return I_CP_R(IY >>> 8) + 4; + } + + int I_CP_L() { + return I_CP_R(regs[REG_L]); + } + + int I_CP_IXL() { + return I_CP_R(IX & 0xFF) + 4; + } + + int I_CP_IYL() { + return I_CP_R(IY & 0xFF) + 4; + } + + int I_CP_REF_HL() { + return I_CP_R(memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF) + 3; + } + + int I_CP_REF_IX_D() { + return I_CP_REF_XY_D(IX); + } + + int I_CP_REF_IY_D() { + return I_CP_REF_XY_D(IY); + } + + int I_CP_A() { + return I_CP_R(regs[REG_A]); + } + + int I_CP_R(int value) { + int oldA = regs[REG_A]; + int sum = (oldA - value) & 0x1FF; + int result = sum & 0xFF; + // F5 and F3 flags are set from the subtrahend instead of from the result. + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[value]; + Q = flags; + return 4; + } + + int I_CP_REF_XY_D(int xy) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (xy + disp) & 0xFFFF; + memptr = address; + int value = memory.read(address) & 0xFF; + int sum = (regs[REG_A] - value) & 0x1FF; + int result = sum & 0xFF; + flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ regs[REG_A]]) | TABLE_XY[value]; + return 19; + } + + int I_ADD_A_N() { + int value = memory.read(PC) & 0xFF; + PC = (PC + 1) & 0xFFFF; + int oldA = regs[REG_A]; + int sum = (oldA + value) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + Q = flags; + return 7; + } + + int I_ADC_A_N() { + int value = memory.read(PC) & 0xFF; + PC = (PC + 1) & 0xFFFF; + int oldA = regs[REG_A]; + int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; + Q = flags; + return 7; + } + + int I_SBC_A_N() { + int value = memory.read(PC) & 0xFF; + PC = (PC + 1) & 0xFFFF; + int oldA = regs[REG_A]; + int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; + regs[REG_A] = sum & 0xFF; + flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; + Q = flags; + return 7; + } + + int I_AND_N() { + int tmp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + regs[REG_A] = (regs[REG_A] & tmp) & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; + return 7; + } + + int I_XOR_N() { + int tmp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + regs[REG_A] = ((regs[REG_A] ^ tmp) & 0xFF); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; + return 7; + } + + int I_OR_N() { + int tmp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + regs[REG_A] = (regs[REG_A] | tmp) & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + Q = flags; + return 7; + } + + int I_CP_N() { + int value = memory.read(PC) & 0xFF; + PC = (PC + 1) & 0xFFFF; + int oldA = regs[REG_A]; + int sum = (oldA - value) & 0x1FF; + int result = sum & 0xFF; + flags = (TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA])) | TABLE_XY[value]; + Q = flags; + return 7; + } + + int I_RLCA() { + regs[REG_A] = TABLE_RLCA[regs[REG_A]]; + flags = (flags & FLAG_SZP) | (regs[REG_A] & (FLAG_X | FLAG_Y | FLAG_C)); + Q = flags; + return 4; + } + + int I_EX_AF_AFF() { + regs[REG_A] ^= regs2[REG_A]; + regs2[REG_A] ^= regs[REG_A]; + regs[REG_A] ^= regs2[REG_A]; + flags ^= flags2; + flags2 ^= flags; + flags ^= flags2; + return 4; + } + + int I_LD_A_REF_BC() { + int bc = regs[REG_B] << 8 | regs[REG_C]; + regs[REG_A] = memory.read(bc) & 0xFF; + memptr = bc; + return 7; + } + + int I_RRCA() { + flags = (flags & FLAG_SZP) | (regs[REG_A] & FLAG_C); + regs[REG_A] = TABLE_RRCA[regs[REG_A]]; + flags |= TABLE_XY[regs[REG_A]]; + Q = flags; + return 4; + } + + int I_DJNZ() { + byte addr = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + regs[REG_B] = (regs[REG_B] - 1) & 0xFF; + if (regs[REG_B] != 0) { + PC = (PC + addr) & 0xFFFF; + memptr = PC; + return 13; + } + return 8; + } + + int I_LD_REF_DE_A() { + memory.write(getpair(1, false), (byte) regs[REG_A]); + memptr = (regs[REG_A] << 8) | 2; + //_memPtr = A * 256 + ((DE + 1) & 0xFF); + // Note for *BM1: MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = 0 + return 7; + } + + int I_RLA() { + int res = ((regs[REG_A] << 1) | (flags & FLAG_C)) & 0xFF; + int flagC = ((regs[REG_A] & 0x80) == 0x80) ? FLAG_C : 0; + regs[REG_A] = res; + flags = (flags & FLAG_SZP) | flagC | TABLE_XY[res]; + Q = flags; + return 4; + } + + int I_LD_A_REF_DE() { + int de = regs[REG_D] << 8 | regs[REG_E]; + regs[REG_A] = memory.read(de) & 0xFF; + memptr = de; + return 7; + } + + int I_RRA() { + int res = ((regs[REG_A] >>> 1) | (flags << 7)) & 0xFF; + int flagC = regs[REG_A] & FLAG_C; + flags = (flags & FLAG_SZP) | flagC | TABLE_XY[res]; + Q = flags; + regs[REG_A] = res; + return 4; + } + + int I_DAA() { + // The following algorithm is from comp.sys.sinclair's FAQ. + int c, d; + + int a = regs[REG_A]; + if (a > 0x99 || ((flags & FLAG_C) != 0)) { + c = FLAG_C; + d = 0x60; + } else { + c = d = 0; + } + + if ((a & 0x0f) > 0x09 || ((flags & FLAG_H) != 0)) { + d += 0x06; + } + + regs[REG_A] = ((flags & FLAG_N) != 0 ? regs[REG_A] - d : regs[REG_A] + d) & 0xFF; + flags = TABLE_SZ[regs[REG_A]] + | PARITY_TABLE[regs[REG_A]] + | TABLE_XY[regs[REG_A]] + | ((regs[REG_A] ^ a) & FLAG_H) + | (flags & FLAG_N) + | c; + Q = flags; + return 4; + } + + int I_CPL() { + regs[REG_A] = (~regs[REG_A]) & 0xFF; + flags = (flags & (FLAG_SZP | FLAG_C)) + | FLAG_H | FLAG_N + | (regs[REG_A] & (FLAG_X | FLAG_Y)); + Q = flags; + return 4; + } + + int I_SCF() { + flags = (flags & FLAG_SZP) | (((lastQ ^ flags) | regs[REG_A]) & (FLAG_X | FLAG_Y)) | FLAG_C; + Q = flags; + return 4; + } + + int I_CCF() { + flags = (flags & FLAG_SZP) + | ((flags & FLAG_C) == 0 ? FLAG_C : FLAG_H) + | (((lastQ ^ flags) | regs[REG_A]) & (FLAG_X | FLAG_Y)); + Q = flags; + return 4; + } + + int I_RET() { + PC = readWord(SP); + memptr = PC; + SP = (SP + 2) & 0xFFFF; + return 10; + } + + int I_EXX() { + // https://www.baeldung.com/java-swap-two-variables + regs[REG_B] ^= regs2[REG_B]; + regs2[REG_B] ^= regs[REG_B]; + regs[REG_B] ^= regs2[REG_B]; + + regs[REG_C] ^= regs2[REG_C]; + regs2[REG_C] ^= regs[REG_C]; + regs[REG_C] ^= regs2[REG_C]; + + regs[REG_D] ^= regs2[REG_D]; + regs2[REG_D] ^= regs[REG_D]; + regs[REG_D] ^= regs2[REG_D]; + + regs[REG_E] ^= regs2[REG_E]; + regs2[REG_E] ^= regs[REG_E]; + regs[REG_E] ^= regs2[REG_E]; + + regs[REG_H] ^= regs2[REG_H]; + regs2[REG_H] ^= regs[REG_H]; + regs[REG_H] ^= regs2[REG_H]; + + regs[REG_L] ^= regs2[REG_L]; + regs2[REG_L] ^= regs[REG_L]; + regs[REG_L] ^= regs2[REG_L]; + return 4; + } + + int I_EX_REF_SP_HL() { + byte value = memory.read(SP); + int SP_plus1 = (SP + 1) & 0xFFFF; + byte value1 = memory.read(SP_plus1); + memory.write(SP, (byte) regs[REG_L]); + memory.write(SP_plus1, (byte) regs[REG_H]); + regs[REG_L] = value & 0xFF; + regs[REG_H] = value1 & 0xFF; + memptr = (regs[REG_H] << 8) | regs[REG_L]; + return 19; + } + + int I_JP_REF_HL() { + PC = ((regs[REG_H] << 8) | regs[REG_L]); + return 4; + } + + int I_EX_DE_HL() { + regs[REG_D] ^= regs[REG_H]; + regs[REG_H] ^= regs[REG_D]; + regs[REG_D] ^= regs[REG_H]; + + regs[REG_E] ^= regs[REG_L]; + regs[REG_L] ^= regs[REG_E]; + regs[REG_E] ^= regs[REG_L]; + return 4; + } + + int I_DI() { + IFF[0] = IFF[1] = false; + return 4; + } + + int I_LD_SP_HL() { + SP = ((regs[REG_H] << 8) | regs[REG_L]); + return 6; + } + + int I_EI() { + // https://www.smspower.org/forums/2511-LDILDIRLDDLDDRCRCInZEXALL + // interrupts are not allowed until after the *next* instruction after EI. + // This is used to prevent interrupts from occurring between an EI/RETI pair used at the end of interrupt handlers. + if (!IFF[0]) { + interruptSkip = true; + } + IFF[0] = IFF[1] = true; + return 4; + } + + int I_IN_R_REF_C() { + int reg = (lastOpcode >>> 3) & 0x7; + putreg(reg, context.readIO((regs[REG_B] << 8) | regs[REG_C])); + memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; + flags = (flags & FLAG_C) | TABLE_SZ[regs[reg]] | PARITY_TABLE[regs[reg]] | TABLE_XY[regs[reg]]; + Q = flags; + return 12; + } + + int I_OUT_REF_C_R() { + int reg = (lastOpcode >>> 3) & 0x7; + memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; + context.writeIO((regs[REG_B] << 8) | regs[REG_C], (byte) getreg(reg)); + return 12; + } + + int I_SBC_HL_RP() { + int rp = getpair((lastOpcode >>> 4) & 0x03, true); + int hl = ((regs[REG_H] << 8) | regs[REG_L]) & 0xFFFF; + memptr = (hl + 1) & 0xFFFF; + int res = hl - rp - (flags & FLAG_C); + + flags = (((hl ^ res ^ rp) >>> 8) & FLAG_H) | FLAG_N | + ((res >>> 16) & FLAG_C) | + ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | + (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | + (((rp ^ hl) & (hl ^ res) & 0x8000) >>> 13); + Q = flags; + + regs[REG_H] = (res >>> 8) & 0xFF; + regs[REG_L] = res & 0xFF; + return 15; + } + + int I_ADC_HL_RP() { + int rp = getpair((lastOpcode >>> 4) & 0x03, true); + int hl = (regs[REG_H] << 8 | regs[REG_L]) & 0xFFFF; + memptr = (hl + 1) & 0xFFFF; + int res = hl + rp + (flags & FLAG_C); + + flags = (((hl ^ res ^ rp) >>> 8) & FLAG_H) | + ((res >>> 16) & FLAG_C) | + ((res >>> 8) & (FLAG_S | FLAG_Y | FLAG_X)) | + (((res & 0xFFFF) != 0) ? 0 : FLAG_Z) | + (((rp ^ hl ^ 0x8000) & (rp ^ res) & 0x8000) >>> 13); + Q = flags; + + regs[REG_H] = (res >>> 8) & 0xFF; + regs[REG_L] = (res & 0xFF); + return 11; + } + + int I_NEG() { + int v = regs[REG_A]; + regs[REG_A] = 0; + return I_SUB(v) + 4; + } + + int I_RETN() { + IFF[0] = IFF[1]; + PC = readWord(SP); + SP = (SP + 2) & 0xffff; + return 14; + } + + int I_IM_0() { + interruptMode = 0; + return 8; + } + + int I_LD_I_A() { + I = regs[REG_A]; + return 9; + } + + int I_RETI() { + IFF[0] = IFF[1]; + PC = readWord(SP); + memptr = PC; + SP = (SP + 2) & 0xffff; + return 14; + } + + int I_LD_R_A() { + R = regs[REG_A]; + return 9; + } + + int I_IM_1() { + interruptMode = 1; + return 8; + } + + int I_IM_2() { + interruptMode = 2; + return 8; + } + + int I_LD_A_I() { + regs[REG_A] = I & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; + Q = flags; + return 9; + } + + int I_LD_A_R() { + regs[REG_A] = R & 0xFF; + flags = TABLE_SZ[regs[REG_A]] | (IFF[1] ? FLAG_PV : 0) | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; + Q = flags; + return 9; + } + + int I_RRD() { + int regA = regs[REG_A] & 0x0F; + int hl = (regs[REG_H] << 8) | regs[REG_L]; + memptr = (hl + 1) & 0xFFFF; + int value = memory.read(hl); + regs[REG_A] = ((regs[REG_A] & 0xF0) | (value & 0x0F)); + value = ((value >>> 4) & 0x0F) | (regA << 4); + memory.write(hl, (byte) (value & 0xff)); + flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | (flags & FLAG_C) | TABLE_XY[regs[REG_A]]; + Q = flags; + return 18; + } + + int I_RLD() { + int hl = (regs[REG_H] << 8) | regs[REG_L]; int value = memory.read(hl); memptr = (hl + 1) & 0xFFFF; int tmp1 = (value >>> 4) & 0x0F; @@ -1593,15 +2505,59 @@ int I_OTDR() { return 21; } - int I_LD_REF_NN_RP() { + int I_LD_REF_NN_BC() { int addr = readWord(PC); memptr = (addr + 1) & 0xFFFF; PC = (PC + 2) & 0xFFFF; - - int tmp1 = getpair((lastOpcode >>> 4) & 3, true); - writeWord(addr, tmp1); + writeWord(addr, (regs[REG_B] << 8) | regs[REG_C]); + return 20; + } + int I_LD_REF_NN_DE() { + int addr = readWord(PC); + memptr = (addr + 1) & 0xFFFF; + PC = (PC + 2) & 0xFFFF; + writeWord(addr, (regs[REG_D] << 8) | regs[REG_E]); + return 20; + } + int I_LD_REF_NN_HL() { + int addr = readWord(PC); + memptr = (addr + 1) & 0xFFFF; + PC = (PC + 2) & 0xFFFF; + writeWord(addr, (regs[REG_H] << 8) | regs[REG_L]); + return 16; + } + int I_ED_LD_REF_NN_HL() { + return I_LD_REF_NN_HL() + 4; + } + int I_LD_REF_NN_SP() { + int addr = readWord(PC); + memptr = (addr + 1) & 0xFFFF; + PC = (PC + 2) & 0xFFFF; + writeWord(addr, SP); return 20; } + int I_LD_REF_NN_A() { + int addr = readWord(PC); + PC = (PC + 2) & 0xFFFF; + memptr = (regs[REG_A] << 8) | ((addr + 1) & 0xFF); + // Note for *BM1: MEMPTR_low = (addr + 1) & #FF, MEMPTR_hi = 0 + memory.write(addr, (byte) regs[REG_A]); + return 13; + } + int I_LD_REF_NN_IX() { + return I_LD_REF_NN_XY(IX); + } + int I_LD_REF_NN_IY() { + return I_LD_REF_NN_XY(IY); + } + + int I_LD_REF_NN_XY(int xy) { + int tmp = readWord(PC); + PC = (PC + 2) & 0xFFFF; + writeWord(tmp, xy); + return 16; + } + int I_LD_RP_REF_NN() { int addr = readWord(PC); @@ -1663,14 +2619,6 @@ int I_SUB_N() { return 7; } - int I_LD_RP_NN() { - int tmp = readWord(PC); - PC = (PC + 2) & 0xFFFF; - - putpair((lastOpcode >>> 4) & 3, tmp, true); - return 10; - } - int I_JP_CC_NN() { int addr = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1699,15 +2647,6 @@ int I_CALL_CC_NN() { return 10; } - int I_LD_REF_NN_HL() { - int tmp = readWord(PC); - PC = (PC + 2) & 0xFFFF; - - int tmp1 = getpair(2, false); - writeWord(tmp, tmp1); - return 16; - } - int I_LD_HL_REF_NN() { int addr = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1717,15 +2656,6 @@ int I_LD_HL_REF_NN() { return 16; } - int I_LD_REF_NN_A() { - int addr = readWord(PC); - PC = (PC + 2) & 0xFFFF; - memptr = (regs[REG_A] << 8) | ((addr + 1) & 0xFF); - // Note for *BM1: MEMPTR_low = (addr + 1) & #FF, MEMPTR_hi = 0 - memory.write(addr, (byte) regs[REG_A]); - return 13; - } - int I_LD_A_REF_NN() { int addr = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -1750,1232 +2680,1209 @@ int I_CALL_NN() { return 17; } - int I_LD_R_R() { - int tmp = (lastOpcode >>> 3) & 0x07; - int tmp1 = lastOpcode & 0x07; - putreg(tmp, getreg(tmp1)); - if ((tmp1 == 6) || (tmp == 6)) { - return 7; - } else { - return 4; - } + int I_LD_B_B() { + return I_LD_R_R(REG_B, REG_B); } - int I_HALT() { - if (IFF[0]) { - PC = (PC - 1) & 0xFFFF; // endless loop if interrupts are enabled - } else { - currentRunState = RunState.STATE_STOPPED_NORMAL; - } - return 4; + int I_LD_B_C() { + return I_LD_R_R(REG_B, REG_C); } - int I_RLC_R() { - int reg = lastOpcode & 7; - int regValue = getreg(reg) & 0xFF; + int I_LD_B_D() { + return I_LD_R_R(REG_B, REG_D); + } - int flagC = ((regValue & 0x80) != 0) ? FLAG_C : 0; - regValue = ((regValue << 1) | (regValue >>> 7)) & 0xFF; - putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; - Q = flags; + int I_LD_B_E() { + return I_LD_R_R(REG_B, REG_E); + } - if (reg == 6) { - return 15; - } else { - return 8; - } + int I_LD_B_H() { + return I_LD_R_R(REG_B, REG_H); } - int I_RRC_R() { - int reg = lastOpcode & 7; - int regValue = getreg(reg) & 0xFF; - int flagC = regValue & FLAG_C; - regValue = ((regValue >>> 1) | (regValue << 7)) & 0xFF; - putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; - Q = flags; + int I_LD_B_L() { + return I_LD_R_R(REG_B, REG_L); + } - if (reg == 6) { - return 15; - } else { - return 8; - } + int I_LD_B_A() { + return I_LD_R_R(REG_B, REG_A); } - int I_RL_R() { - int reg = lastOpcode & 7; - int regValue = getreg(reg) & 0xFF; - int flagC = ((regValue & 0x80) == 0x80) ? FLAG_C : 0; - regValue = ((regValue << 1) | (flags & FLAG_C)) & 0xFF; - putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; - Q = flags; + int I_LD_B_REF_HL() { + return I_LD_R_REF_HL(REG_B); + } - if (reg == 6) { - return 15; - } else { - return 8; - } + int I_LD_B_IXH() { + regs[REG_B] = (IX >>> 8); + return 8; } - int I_RR_R() { - int reg = lastOpcode & 7; - int regValue = getreg(reg) & 0xFF; - int flagC = regValue & FLAG_C; - regValue = ((regValue >>> 1) | (flags << 7)) & 0xFF; - putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; - Q = flags; + int I_LD_B_IXL() { + regs[REG_B] = (IX & 0xFF); + return 8; + } - if (reg == 6) { - return 15; - } else { - return 8; - } + int I_LD_B_IYH() { + regs[REG_B] = (IY >>> 8); + return 8; } - int I_SLA_R() { - int reg = lastOpcode & 7; - int regValue = getreg(reg) & 0xFF; + int I_LD_B_IYL() { + regs[REG_B] = (IY & 0xFF); + return 8; + } - int flagC = ((regValue & 0x80) == 0x80) ? FLAG_C : 0; - regValue = (regValue << 1) & 0xFF; - putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; - Q = flags; + int I_LD_B_REF_IX_D() { + return I_LD_R_REF_XY_D(REG_B, IX); + } - if (reg == 6) { - return 15; - } else { - return 8; - } + int I_LD_B_REF_IY_D() { + return I_LD_R_REF_XY_D(REG_B, IY); } - int I_SRA_R() { - int reg = lastOpcode & 7; - int regValue = getreg(reg) & 0xFF; - int flagC = regValue & FLAG_C; - regValue = ((regValue >>> 1) | (regValue & 0x80)) & 0xFF; - putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; - Q = flags; + int I_LD_C_B() { + return I_LD_R_R(REG_C, REG_B); + } - if (reg == 6) { - return 15; - } else { - return 8; - } + int I_LD_C_C() { + return I_LD_R_R(REG_C, REG_C); } - int I_SLL_R() { - int reg = lastOpcode & 7; - int regValue = getreg(reg) & 0xFF; - int flagC = ((regValue & 0x80) != 0) ? FLAG_C : 0; - regValue = ((regValue << 1) | 0x01) & 0xFF; - putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; - Q = flags; + int I_LD_C_D() { + return I_LD_R_R(REG_C, REG_D); + } - if (reg == 6) { - return 15; - } else { - return 8; - } + int I_LD_C_E() { + return I_LD_R_R(REG_C, REG_E); } - int I_SRL_R() { - int reg = lastOpcode & 7; - int regValue = getreg(reg) & 0xFF; - int flagC = regValue & FLAG_C; - regValue = (regValue >>> 1) & 0xFF; - putreg(reg, regValue); - flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; - Q = flags; + int I_LD_C_H() { + return I_LD_R_R(REG_C, REG_H); + } - if (reg == 6) { - return 15; - } else { - return 8; - } + int I_LD_C_L() { + return I_LD_R_R(REG_C, REG_L); } - int I_BIT_N_R() { - int bit = (lastOpcode >>> 3) & 7; - int reg = lastOpcode & 7; - int regValue = getreg(reg) & 0xFF; - int result = (1 << bit) & regValue; + int I_LD_C_A() { + return I_LD_R_R(REG_C, REG_A); + } + + int I_LD_C_REF_HL() { + return I_LD_R_REF_HL(REG_C); + } + + int I_LD_C_IXH() { + regs[REG_C] = (IX >>> 8); + return 8; + } + + int I_LD_C_IXL() { + regs[REG_C] = (IX & 0xFF); + return 8; + } + + int I_LD_C_IYH() { + regs[REG_C] = (IY >>> 8); + return 8; + } + + int I_LD_C_IYL() { + regs[REG_C] = (IY & 0xFF); + return 8; + } + + int I_LD_C_REF_IX_D() { + return I_LD_R_REF_XY_D(REG_C, IX); + } + + int I_LD_C_REF_IY_D() { + return I_LD_R_REF_XY_D(REG_C, IY); + } + + int I_LD_D_B() { + return I_LD_R_R(REG_D, REG_B); + } + + int I_LD_D_C() { + return I_LD_R_R(REG_D, REG_C); + } + + int I_LD_D_D() { + return I_LD_R_R(REG_D, REG_D); + } + + int I_LD_D_E() { + return I_LD_R_R(REG_D, REG_E); + } + + int I_LD_D_H() { + return I_LD_R_R(REG_D, REG_H); + } + + int I_LD_D_L() { + return I_LD_R_R(REG_D, REG_L); + } + + int I_LD_D_A() { + return I_LD_R_R(REG_D, REG_A); + } + + int I_LD_D_REF_HL() { + return I_LD_R_REF_HL(REG_D); + } + + int I_LD_D_IXH() { + regs[REG_D] = (IX >>> 8); + return 8; + } + + int I_LD_D_IXL() { + regs[REG_D] = (IX & 0xFF); + return 8; + } + + int I_LD_D_IYH() { + regs[REG_D] = (IY >>> 8); + return 8; + } + + int I_LD_D_IYL() { + regs[REG_D] = (IY & 0xFF); + return 8; + } + + int I_LD_D_REF_IX_D() { + return I_LD_R_REF_XY_D(REG_D, IX); + } + + int I_LD_D_REF_IY_D() { + return I_LD_R_REF_XY_D(REG_D, IY); + } + + int I_LD_E_B() { + return I_LD_R_R(REG_E, REG_B); + } + + int I_LD_E_C() { + return I_LD_R_R(REG_E, REG_C); + } - flags = ((result != 0) ? (result & FLAG_S) : (FLAG_Z | FLAG_PV)) - | TABLE_XY[regValue] - | FLAG_H - | (flags & FLAG_C); + int I_LD_E_D() { + return I_LD_R_R(REG_E, REG_D); + } - if (reg == 6) { - flags &= (~FLAG_X); - flags &= (~FLAG_Y); - flags |= ((memptr >>> 8) & (FLAG_X | FLAG_Y)); - Q = flags; - return 12; - } else { - Q = flags; - return 8; - } + int I_LD_E_E() { + return I_LD_R_R(REG_E, REG_E); } - int I_RES_N_R() { - int bit = (lastOpcode >>> 3) & 7; - int reg = lastOpcode & 7; - int regValue = getreg(reg) & 0xFF; - regValue = (regValue & (~(1 << bit))); - putreg(reg, regValue); - if (reg == 6) { - return 15; - } else { - return 8; - } + int I_LD_E_H() { + return I_LD_R_R(REG_E, REG_H); } - int I_SET_N_R() { - int tmp = (lastOpcode >>> 3) & 7; - int tmp2 = lastOpcode & 7; - int tmp1 = getreg(tmp2) & 0xFF; - tmp1 = (tmp1 | (1 << tmp)); - putreg(tmp2, tmp1); - if (tmp2 == 6) { - return 15; - } else { - return 8; - } + int I_LD_E_L() { + return I_LD_R_R(REG_E, REG_L); } - int I_ADD_IX_RP() { - memptr = (IX + 1) & 0xFFFF; - IX = I_ADD_II_RP(IX); - return 15; + int I_LD_E_A() { + return I_LD_R_R(REG_E, REG_A); } - int I_ADD_IY_RP() { - memptr = (IY + 1) & 0xFFFF; - IY = I_ADD_II_RP(IY); - return 15; + int I_LD_E_REF_HL() { + return I_LD_R_REF_HL(REG_E); } - int I_ADD_II_RP(int special) { - int dstRp; - int rp = (lastOpcode >>> 4) & 0x03; - switch (rp) { - case 3: - dstRp = SP; - break; - case 2: - dstRp = special; - break; - default: - int index = rp * 2; - dstRp = regs[index] << 8 | regs[index + 1]; - } + int I_LD_E_IXH() { + regs[REG_E] = (IX >>> 8); + return 8; + } - int res = special + dstRp; - flags = (flags & FLAG_SZP) | - (((dstRp ^ res ^ special) >>> 8) & FLAG_H) | - ((res >>> 16) & FLAG_C) | TABLE_XY[(res >>> 8) & 0xFF]; - return res & 0xFFFF; + int I_LD_E_IXL() { + regs[REG_E] = (IX & 0xFF); + return 8; } - int I_LD_IX_NN() { - IX = readWord(PC); - PC = (PC + 2) & 0xFFFF; - return 14; + int I_LD_E_IYH() { + regs[REG_E] = (IY >>> 8); + return 8; } - int I_LD_IY_NN() { - IY = readWord(PC); - PC = (PC + 2) & 0xFFFF; - return 14; + int I_LD_E_IYL() { + regs[REG_E] = (IY & 0xFF); + return 8; } - int I_LD_REF_NN_IX() { - return I_LD_REF_NN_II(IX); + int I_LD_E_REF_IX_D() { + return I_LD_R_REF_XY_D(REG_E, IX); } - int I_LD_REF_NN_IY() { - return I_LD_REF_NN_II(IY); + int I_LD_E_REF_IY_D() { + return I_LD_R_REF_XY_D(REG_E, IY); } - int I_LD_REF_NN_II(int special) { - int tmp = readWord(PC); - PC = (PC + 2) & 0xFFFF; - writeWord(tmp, special); - return 16; + int I_LD_H_B() { + return I_LD_R_R(REG_H, REG_B); } - int I_INC_IX() { - IX = (IX + 1) & 0xFFFF; - return 10; + int I_LD_H_C() { + return I_LD_R_R(REG_H, REG_C); } - int I_INC_IY() { - IY = (IY + 1) & 0xFFFF; - return 10; + int I_LD_H_D() { + return I_LD_R_R(REG_H, REG_D); } - int I_LD_IX_REF_NN() { - IX = I_LD_II_REF_NN(); - return 20; + int I_LD_H_E() { + return I_LD_R_R(REG_H, REG_E); } - int I_LD_IY_REF_NN() { - IY = I_LD_II_REF_NN(); - return 20; + int I_LD_H_H() { + return I_LD_R_R(REG_H, REG_H); } - int I_LD_II_REF_NN() { - int tmp = readWord(PC); - PC = (PC + 2) & 0xFFFF; - return readWord(tmp); + int I_LD_H_L() { + return I_LD_R_R(REG_H, REG_L); } - int I_DEC_IX() { - IX = (IX - 1) & 0xFFFF; - return 10; + int I_LD_H_A() { + return I_LD_R_R(REG_H, REG_A); } - int I_DEC_IY() { - IY = (IY - 1) & 0xFFFF; - return 10; + int I_LD_H_REF_HL() { + return I_LD_R_REF_HL(REG_H); } - int I_INC_REF_IX_N() { - return I_INC_REF_II_N(IX); + int I_LD_IXH_B() { + IX = (regs[REG_B] << 8) | (IX & 0xFF); + return 8; } - int I_INC_REF_IY_N() { - return I_INC_REF_II_N(IY); + int I_LD_IXH_C() { + IX = (regs[REG_C] << 8) | (IX & 0xFF); + return 8; } - int I_INC_REF_II_N(int special) { - byte disp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; - int value = memory.read(address) & 0xFF; - memptr = address; + int I_LD_IXH_D() { + IX = (regs[REG_D] << 8) | (IX & 0xFF); + return 8; + } - int sum = (value + 1) & 0x1FF; - int sumByte = sum & 0xFF; - flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | TABLE_XY[sumByte]; + int I_LD_IXH_E() { + IX = (regs[REG_E] << 8) | (IX & 0xFF); + return 8; + } - memory.write(address, (byte) sumByte); - return 23; + int I_LD_IXH_IXH() { + return 8; } - int I_DEC_REF_IX_N() { - return I_DEC_REF_II_N(IX); + int I_LD_IXH_IXL() { + IX = (IX & 0xFF) | ((IX << 8) & 0xFF00); + return 8; } - int I_DEC_REF_IY_N() { - return I_DEC_REF_II_N(IY); + int I_LD_IXH_A() { + IX = (regs[REG_A] << 8) | (IX & 0xFF); + return 8; } - int I_DEC_REF_II_N(int special) { - byte disp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; - int value = memory.read(address) & 0xFF; - memptr = address; + int I_LD_IYH_B() { + IY = (regs[REG_B] << 8) | (IY & 0xFF); + return 8; + } - int sum = (value - 1) & 0x1FF; - int sumByte = sum & 0xFF; + int I_LD_IYH_C() { + IY = (regs[REG_C] << 8) | (IY & 0xFF); + return 8; + } - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | TABLE_XY[sumByte]; - memory.write(address, (byte) sumByte); - return 23; + int I_LD_IYH_D() { + IY = (regs[REG_D] << 8) | (IY & 0xFF); + return 8; } - int I_LD_REF_IX_N_N() { - return I_LD_REF_II_N_N(IX); + int I_LD_IYH_E() { + IY = (regs[REG_E] << 8) | (IY & 0xFF); + return 8; } - int I_LD_REF_IY_N_N() { - return I_LD_REF_II_N_N(IY); + int I_LD_IYH_A() { + IY = (regs[REG_A] << 8) | (IY & 0xFF); + return 8; } - int I_LD_REF_II_N_N(int special) { - byte disp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - byte number = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; - memptr = address; - memory.write(address, number); - return 19; + int I_LD_IYH_IYH() { + return 8; } - int I_LD_R_REF_IX_N() { - return I_LD_R_REF_II_N(IX); + int I_LD_IYH_IYL() { + IY = (IY & 0xFF) | ((IY << 8) & 0xFF00); + return 8; } - int I_LD_R_REF_IY_N() { - return I_LD_R_REF_II_N(IY); + int I_LD_H_REF_IX_D() { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (IX + disp) & 0xFFFF; + memptr = address; + regs[REG_H] = (memory.read(address) & 0xFF); + return 19; } - int I_LD_R_REF_II_N(int special) { + int I_LD_H_REF_IY_D() { byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int tmp1 = (lastOpcode >>> 3) & 7; - int address = (special + disp) & 0xFFFF; + int address = (IY + disp) & 0xFFFF; memptr = address; - putreg(tmp1, memory.read(address)); + regs[REG_H] = (memory.read(address) & 0xFF); return 19; } - int I_LD_REF_IX_N_R() { - return I_LD_REF_II_N_R(IX); + int I_LD_L_B() { + return I_LD_R_R(REG_L, REG_B); } - int I_LD_REF_IY_N_R() { - return I_LD_REF_II_N_R(IY); + int I_LD_L_C() { + return I_LD_R_R(REG_L, REG_C); } - int I_LD_REF_II_N_R(int special) { - byte disp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; - memptr = address; - memory.write(address, (byte) getreg(lastOpcode & 7)); - return 19; + int I_LD_L_D() { + return I_LD_R_R(REG_L, REG_D); } - int I_ADD_A_REF_IX_N() { - return I_ADD_A_REF_II_N(IX); + int I_LD_L_E() { + return I_LD_R_R(REG_L, REG_E); } - int I_ADD_A_REF_IY_N() { - return I_ADD_A_REF_II_N(IY); + int I_LD_L_H() { + return I_LD_R_R(REG_L, REG_H); } - int I_ADD_A_REF_II_N(int special) { - byte disp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; - memptr = address; - int value = memory.read(address) & 0xFF; - int oldA = regs[REG_A]; - int sum = (oldA + value) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; - return 19; + int I_LD_L_L() { + return I_LD_R_R(REG_L, REG_L); } - int I_ADC_A_REF_IX_N() { - return I_ADC_A_REF_II_N(IX); + int I_LD_L_A() { + return I_LD_R_R(REG_L, REG_A); } - int I_ADC_A_REF_IY_N() { - return I_ADC_A_REF_II_N(IY); + int I_LD_L_REF_HL() { + return I_LD_R_REF_HL(REG_L); } - int I_ADC_A_REF_II_N(int special) { - byte disp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; - memptr = address; - int value = memory.read(address) & 0xFF; - int oldA = regs[REG_A]; - int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; - return 19; + int I_LD_IXL_B() { + IX = regs[REG_B] | (IX & 0xFF00); + return 8; } - int I_SUB_REF_IX_N() { - return I_SUB_REF_II_N(IX); + int I_LD_IXL_C() { + IX = regs[REG_C] | (IX & 0xFF00); + return 8; } - int I_SUB_REF_IY_N() { - return I_SUB_REF_II_N(IY); + int I_LD_IXL_D() { + IX = regs[REG_D] | (IX & 0xFF00); + return 8; } - int I_SUB_REF_II_N(int special) { - byte disp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; - memptr = address; - int value = memory.read(address) & 0xFF; - int oldA = regs[REG_A]; - int sum = (oldA - value) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; - return 19; + int I_LD_IXL_E() { + IX = regs[REG_E] | (IX & 0xFF00); + return 8; } - int I_SBC_A_REF_IX_N() { - return I_SBC_A_REF_II_N(IX); + int I_LD_IXL_IXH() { + IX = (IX & 0xFF00) | (IX >>> 8); + return 8; } - int I_SBC_A_REF_IY_N() { - return I_SBC_A_REF_II_N(IY); + int I_LD_IXL_IXL() { + return 8; } - int I_SBC_A_REF_II_N(int special) { + int I_LD_L_REF_IX_D() { byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; + int address = (IX + disp) & 0xFFFF; memptr = address; - int value = memory.read(address) & 0xFF; - int oldA = regs[REG_A]; - int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; + regs[REG_L] = (memory.read(address) & 0xFF); return 19; } - int I_AND_REF_IX_N() { - return I_AND_REF_II_N(IX); + int I_LD_IXL_A() { + IX = regs[REG_A] | (IX & 0xFF00); + return 8; } - int I_AND_REF_IY_N() { - return I_AND_REF_II_N(IY); + int I_LD_IYL_B() { + IY = regs[REG_B] | (IY & 0xFF00); + return 8; } - int I_AND_REF_II_N(int special) { - byte disp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; - memptr = address; - int value = memory.read(address); - regs[REG_A] = (regs[REG_A] & value) & 0xFF; - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H | TABLE_XY[regs[REG_A]]; - return 19; + int I_LD_IYL_C() { + IY = regs[REG_C] | (IY & 0xFF00); + return 8; } - int I_XOR_REF_IX_N() { - return I_XOR_REF_II_N(IX); + int I_LD_IYL_D() { + IY = regs[REG_D] | (IY & 0xFF00); + return 8; } - int I_XOR_REF_IY_N() { - return I_XOR_REF_II_N(IY); + int I_LD_IYL_E() { + IY = regs[REG_E] | (IY & 0xFF00); + return 8; } - int I_XOR_REF_II_N(int special) { - byte disp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; - memptr = address; - byte value = memory.read(address); - regs[REG_A] = ((regs[REG_A] ^ value) & 0xff); - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | TABLE_XY[regs[REG_A]]; - return 19; + int I_LD_IYL_IYH() { + IY = (IY & 0xFF00) | (IY >>> 8); + return 8; } - int I_OR_REF_IX_N() { - return I_OR_REF_II_N(IX); + int I_LD_IYL_IYL() { + return 8; } - int I_OR_REF_IY_N() { - return I_OR_REF_II_N(IY); + int I_LD_IYL_A() { + IY = regs[REG_A] | (IY & 0xFF00); + return 8; } - int I_OR_REF_II_N(int special) { + int I_LD_L_REF_IY_D() { byte disp = memory.read(PC); PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; + int address = (IY + disp) & 0xFFFF; memptr = address; - byte value = memory.read(address); - regs[REG_A] = ((regs[REG_A] | value) & 0xff); - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; + regs[REG_L] = (memory.read(address) & 0xFF); return 19; } - int I_CP_REF_IX_N() { - return I_CP_REF_II_N(IX); + int I_LD_A_B() { + return I_LD_R_R(REG_A, REG_B); } - int I_CP_REF_IY_N() { - return I_CP_REF_II_N(IY); + int I_LD_A_C() { + return I_LD_R_R(REG_A, REG_C); } - int I_CP_REF_II_N(int special) { - byte disp = memory.read(PC); - PC = (PC + 1) & 0xFFFF; - int address = (special + disp) & 0xFFFF; - memptr = address; - int value = memory.read(address) & 0xFF; - int sum = (regs[REG_A] - value) & 0x1FF; - int result = sum & 0xFF; - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ regs[REG_A]]) | TABLE_XY[value]; - return 19; + int I_LD_A_D() { + return I_LD_R_R(REG_A, REG_D); } - int I_POP_IX() { - IX = readWord(SP); - SP = (SP + 2) & 0xFFFF; - return 14; + int I_LD_A_E() { + return I_LD_R_R(REG_A, REG_E); } - int I_POP_IY() { - IY = readWord(SP); - SP = (SP + 2) & 0xFFFF; - return 14; + int I_LD_A_H() { + return I_LD_R_R(REG_A, REG_H); } - int I_EX_REF_SP_IX() { - int tmp = readWord(SP); - int tmp1 = IX; - IX = tmp; - memptr = IX; - writeWord(SP, tmp1); - return 23; + int I_LD_A_L() { + return I_LD_R_R(REG_A, REG_L); } - int I_EX_REF_SP_IY() { - int tmp = readWord(SP); - int tmp1 = IY; - IY = tmp; - memptr = IY; - writeWord(SP, tmp1); - return 23; + int I_LD_A_A() { + return I_LD_R_R(REG_A, REG_A); } - int I_PUSH_IX() { - SP = (SP - 2) & 0xFFFF; - writeWord(SP, IX); - return 15; + int I_LD_A_REF_HL() { + return I_LD_R_REF_HL(REG_A); } - int I_PUSH_IY() { - SP = (SP - 2) & 0xFFFF; - writeWord(SP, IY); - return 15; + int I_LD_A_IXH() { + regs[REG_A] = (IX >>> 8); + return 8; } - int I_JP_REF_IX() { - PC = IX; + int I_LD_A_IXL() { + regs[REG_A] = (IX & 0xFF); return 8; } - int I_JP_REF_IY() { - PC = IY; + int I_LD_A_IYH() { + regs[REG_A] = (IY >>> 8); return 8; } - int I_LD_SP_IX() { - SP = IX; - return 10; + int I_LD_A_IYL() { + regs[REG_A] = (IY & 0xFF); + return 8; } - int I_LD_SP_IY() { - SP = IY; - return 10; + int I_LD_A_REF_IX_D() { + return I_LD_R_REF_XY_D(REG_A, IX); } - int I_RLC_REF_IX_N_R(byte operand) { - return I_RLC_REF_II_N_R(operand, IX); + int I_LD_A_REF_IY_D() { + return I_LD_R_REF_XY_D(REG_A, IY); } - int I_RLC_REF_IY_N_R(byte operand) { - return I_RLC_REF_II_N_R(operand, IY); + int I_LD_REF_HL_B() { + return I_LD_REF_HL_R(REG_B); } - int I_RLC_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xFFFF; - memptr = addr; - int addrValue = memory.read(addr) & 0xFF; + int I_LD_REF_HL_C() { + return I_LD_REF_HL_R(REG_C); + } - int c = ((addrValue & 0x80) != 0) ? FLAG_C : 0; - int res = ((addrValue << 1) | (addrValue >>> 7)) & 0xFF; - memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | TABLE_XY[res]; + int I_LD_REF_HL_D() { + return I_LD_REF_HL_R(REG_D); + } - // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = res & 0xFF; - return 23; + int I_LD_REF_HL_E() { + return I_LD_REF_HL_R(REG_E); } - int I_RRC_REF_IX_N_R(byte operand) { - return I_RRC_REF_II_N_R(operand, IX); + int I_LD_REF_HL_H() { + return I_LD_REF_HL_R(REG_H); } - int I_RRC_REF_IY_N_R(byte operand) { - return I_RRC_REF_II_N_R(operand, IY); + int I_LD_REF_HL_L() { + return I_LD_REF_HL_R(REG_L); } - int I_RRC_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xffff; - memptr = addr; - int addrValue = memory.read(addr) & 0xFF; + int I_LD_REF_HL_A() { + return I_LD_REF_HL_R(REG_A); + } - int c = addrValue & 1; - int res = (((addrValue >>> 1) & 0x7F) | (c << 7)) & 0xFF; - memory.write(addr, (byte) (res & 0xFF)); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; + int I_LD_R_R(int dstReg, int srcReg) { + regs[dstReg] = regs[srcReg]; + return 4; + } - // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = res & 0xFF; - return 23; + int I_LD_R_REF_HL(int dstReg) { + regs[dstReg] = memory.read((regs[REG_H] << 8) | regs[REG_L]) & 0xFF; + return 7; } - int I_RL_REF_IX_N_R(byte operand) { - return I_RL_REF_II_N_R(operand, IX); + int I_LD_REF_HL_R(int srcReg) { + memory.write((regs[REG_H] << 8) | regs[REG_L], (byte) regs[srcReg]); + return 7; } - int I_RL_REF_IY_N_R(byte operand) { - return I_RL_REF_II_N_R(operand, IY); + int I_LD_R_REF_XY_D(int reg, int xy) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (xy + disp) & 0xFFFF; + memptr = address; + regs[reg] = memory.read(address) & 0xFF; + return 19; } - int I_RL_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xffff; - memptr = addr; - int addrValue = memory.read(addr) & 0xFF; + int I_LD_REF_IX_D_B() { + return I_LD_REF_XY_D_R(regs[REG_B], IX); + } - int c = (addrValue >>> 7) & 1; - int res = ((((addrValue << 1) & 0xFF) | flags & FLAG_C) & 0xFF); - memory.write(addr, (byte) (res & 0xFF)); + int I_LD_REF_IX_D_C() { + return I_LD_REF_XY_D_R(regs[REG_C], IX); + } - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; - // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = res & 0xFF; - return 23; + int I_LD_REF_IX_D_D() { + return I_LD_REF_XY_D_R(regs[REG_D], IX); } - int I_RR_REF_IX_N_R(byte operand) { - return I_RR_REF_II_N_R(operand, IX); + int I_LD_REF_IX_D_E() { + return I_LD_REF_XY_D_R(regs[REG_E], IX); } - int I_RR_REF_IY_N_R(byte operand) { - return I_RR_REF_II_N_R(operand, IY); + int I_LD_REF_IX_D_IXH() { + return I_LD_REF_XY_D_R(IX >>> 8, IX); } - int I_RR_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xFFFF; - memptr = addr; - int addrValue = memory.read(addr) & 0xFF; + int I_LD_REF_IX_D_IXL() { + return I_LD_REF_XY_D_R(IX & 0xFF, IX); + } - int c = addrValue & 1; - int res = ((((addrValue >> 1) & 0xFF) | (flags & FLAG_C) << 7) & 0xFF); - memory.write(addr, (byte) (res & 0xFF)); + int I_LD_REF_IX_D_A() { + return I_LD_REF_XY_D_R(regs[REG_A], IX); + } - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; - // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = res & 0xFF; - return 23; + int I_LD_REF_IY_D_B() { + return I_LD_REF_XY_D_R(regs[REG_B], IY); } - int I_SLA_REF_IX_N_R(byte operand) { - return I_SLA_REF_II_N_R(operand, IX); + int I_LD_REF_IY_D_C() { + return I_LD_REF_XY_D_R(regs[REG_C], IY); } - int I_SLA_REF_IY_N_R(byte operand) { - return I_SLA_REF_II_N_R(operand, IY); + int I_LD_REF_IY_D_D() { + return I_LD_REF_XY_D_R(regs[REG_D], IY); } - int I_SLA_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xFFFF; - memptr = addr; - int addrValue = memory.read(addr) & 0xFF; + int I_LD_REF_IY_D_E() { + return I_LD_REF_XY_D_R(regs[REG_E], IY); + } - int c = (addrValue >>> 7) & 1; - int res = (addrValue << 1) & 0xFE; - memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; + int I_LD_REF_IY_D_IYH() { + return I_LD_REF_XY_D_R(IY >>> 8, IY); + } - // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = res & 0xFF; - return 23; + int I_LD_REF_IY_D_IYL() { + return I_LD_REF_XY_D_R(IY & 0xFF, IY); } - int I_SRA_REF_IX_N_R(byte operand) { - return I_SRA_REF_II_N_R(operand, IX); + int I_LD_REF_IY_D_A() { + return I_LD_REF_XY_D_R(regs[REG_A], IY); } - int I_SRA_REF_IY_N_R(byte operand) { - return I_SRA_REF_II_N_R(operand, IY); + int I_LD_REF_XY_D_R(int value, int xy) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (xy + disp) & 0xFFFF; + memptr = address; + memory.write(address, (byte) value); + return 19; } - int I_SRA_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xFFFF; - memptr = addr; - int addrValue = memory.read(addr) & 0xFF; + int I_HALT() { + if (IFF[0]) { + PC = (PC - 1) & 0xFFFF; // endless loop if interrupts are enabled + } else { + currentRunState = RunState.STATE_STOPPED_NORMAL; + } + return 4; + } - int c = addrValue & 1; - int res = (addrValue >> 1) & 0xFF | (addrValue & 0x80); - memory.write(addr, (byte) res); + int I_RLC_R() { + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; - flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; - // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = res & 0xFF; - return 23; - } + int flagC = ((regValue & 0x80) != 0) ? FLAG_C : 0; + regValue = ((regValue << 1) | (regValue >>> 7)) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; - int I_SLL_REF_IX_N_R(byte operand) { - return I_SLL_REF_II_N_R(operand, IX); + if (reg == 6) { + return 15; + } else { + return 8; + } } - int I_SLL_REF_IY_N_R(byte operand) { - return I_SLL_REF_II_N_R(operand, IY); + int I_RRC_R() { + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int flagC = regValue & FLAG_C; + regValue = ((regValue >>> 1) | (regValue << 7)) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; + + if (reg == 6) { + return 15; + } else { + return 8; + } } - int I_SLL_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xFFFF; - memptr = addr; - int addrValue = memory.read(addr) & 0xFF; + int I_RL_R() { + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int flagC = ((regValue & 0x80) == 0x80) ? FLAG_C : 0; + regValue = ((regValue << 1) | (flags & FLAG_C)) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; - int c = ((addrValue & 0x80) != 0) ? FLAG_C : 0; - int res = ((addrValue << 1) | 0x01) & 0xFF; + if (reg == 6) { + return 15; + } else { + return 8; + } + } - memory.write(addr, (byte) res); - flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | TABLE_XY[res]; + int I_RR_R() { + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int flagC = regValue & FLAG_C; + regValue = ((regValue >>> 1) | (flags << 7)) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; - // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = res; - return 23; + if (reg == 6) { + return 15; + } else { + return 8; + } } - int I_SRL_REF_IX_N_R(byte operand) { - return I_SRL_REF_II_N_R(operand, IX); - } + int I_SLA_R() { + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; - int I_SRL_REF_IY_N_R(byte operand) { - return I_SRL_REF_II_N_R(operand, IY); - } + int flagC = ((regValue & 0x80) == 0x80) ? FLAG_C : 0; + regValue = (regValue << 1) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; - int I_SRL_REF_II_N_R(byte operand, int special) { - int addr = (special + operand) & 0xFFFF; - memptr = addr; - int addrValue = memory.read(addr) & 0xFF; + if (reg == 6) { + return 15; + } else { + return 8; + } + } - int c = ((addrValue & 0x01) != 0) ? FLAG_C : 0; - int res = (addrValue >>> 1) & 0xFF; - memory.write(addr, (byte) res); + int I_SRA_R() { + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int flagC = regValue & FLAG_C; + regValue = ((regValue >>> 1) | (regValue & 0x80)) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; - flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | TABLE_XY[res]; - // regs[6] is unused, so it's ok to set it - regs[lastOpcode & 7] = res; - return 23; + if (reg == 6) { + return 15; + } else { + return 8; + } } - int I_BIT_N_REF_IX_N(byte operand) { - return I_BIT_N_REF_II_N(operand, IX); + int I_SLL_R() { + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int flagC = ((regValue & 0x80) != 0) ? FLAG_C : 0; + regValue = ((regValue << 1) | 0x01) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; + + if (reg == 6) { + return 15; + } else { + return 8; + } } - int I_BIT_N_REF_IY_N(byte operand) { - return I_BIT_N_REF_II_N(operand, IY); + int I_SRL_R() { + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int flagC = regValue & FLAG_C; + regValue = (regValue >>> 1) & 0xFF; + putreg(reg, regValue); + flags = TABLE_SZ[regValue] | PARITY_TABLE[regValue] | flagC | TABLE_XY[regValue]; + Q = flags; + + if (reg == 6) { + return 15; + } else { + return 8; + } } - int I_BIT_N_REF_II_N(byte operand, int special) { + int I_BIT_N_R() { int bit = (lastOpcode >>> 3) & 7; - int address = (special + operand) & 0xFFFF; - memptr = address; - byte addrValue = memory.read(address); - int result = (1 << bit) & addrValue; + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + int result = (1 << bit) & regValue; - flags = ((flags & FLAG_C) + flags = ((result != 0) ? (result & FLAG_S) : (FLAG_Z | FLAG_PV)) + | TABLE_XY[regValue] | FLAG_H - | ((result == 0) ? (FLAG_Z | FLAG_PV) : 0)) - | TABLE_XY[special & 0xFF]; - if (bit == 7) { - flags |= ((result == 0x80) ? FLAG_S : 0); + | (flags & FLAG_C); + + if (reg == 6) { + flags &= (~FLAG_X); + flags &= (~FLAG_Y); + flags |= ((memptr >>> 8) & (FLAG_X | FLAG_Y)); + Q = flags; + return 12; + } else { + Q = flags; + return 8; } - return 20; } - int I_RES_N_REF_IX_N_R(byte operand) { - return I_RES_N_REF_II_N_R(operand, IX); + int I_RES_N_R() { + int bit = (lastOpcode >>> 3) & 7; + int reg = lastOpcode & 7; + int regValue = getreg(reg) & 0xFF; + regValue = (regValue & (~(1 << bit))); + putreg(reg, regValue); + if (reg == 6) { + return 15; + } else { + return 8; + } } - int I_RES_N_REF_IY_N_R(byte operand) { - return I_RES_N_REF_II_N_R(operand, IY); + int I_SET_N_R() { + int tmp = (lastOpcode >>> 3) & 7; + int tmp2 = lastOpcode & 7; + int tmp1 = getreg(tmp2) & 0xFF; + tmp1 = (tmp1 | (1 << tmp)); + putreg(tmp2, tmp1); + if (tmp2 == 6) { + return 15; + } else { + return 8; + } } - int I_RES_N_REF_II_N_R(byte operand, int special) { - int bitNumber = (lastOpcode >>> 3) & 7; - int addr = (special + operand) & 0xFFFF; - memptr = addr; - int addrValue = memory.read(addr) & 0xFF; - int res = (addrValue & (~(1 << bitNumber))); - memory.write(addr, (byte) (res & 0xff)); - // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = res & 0xFF; - return 23; + int I_LD_IX_NN() { + IX = readWord(PC); + PC = (PC + 2) & 0xFFFF; + return 14; } - int I_SET_N_REF_IX_N_R(byte operand) { - return I_SET_N_REF_II_N_R(operand, IX); + int I_LD_IY_NN() { + IY = readWord(PC); + PC = (PC + 2) & 0xFFFF; + return 14; } - int I_SET_N_REF_IY_N_R(byte operand) { - return I_SET_N_REF_II_N_R(operand, IY); + int I_LD_IX_REF_NN() { + IX = I_LD_II_REF_NN(); + return 20; } - int I_SET_N_REF_II_N_R(byte operand, int special) { - int bitNumber = (lastOpcode >>> 3) & 7; - int addr = (special + operand) & 0xFFFF; - memptr = addr; - int addrValue = memory.read(addr) & 0xFF; - - int res = (addrValue | (1 << bitNumber)) & 0xFF; - memory.write(addr, (byte) res); - - // regs[6] is unused, so it's ok - regs[lastOpcode & 7] = res; - return 23; + int I_LD_IY_REF_NN() { + IY = I_LD_II_REF_NN(); + return 20; } - int I_INC_IXH() { - IX = ((I_INC(IX >>> 8) << 8) | (IX & 0xFF)) & 0xFFFF; - return 8; + int I_LD_II_REF_NN() { + int tmp = readWord(PC); + PC = (PC + 2) & 0xFFFF; + return readWord(tmp); } - int I_INC_IYH() { - IY = ((I_INC(IY >>> 8) << 8) | (IY & 0xFF)) & 0xFFFF; - return 8; + int I_INC_REF_IX_N() { + return I_INC_REF_II_N(IX); } - int I_INC_IXL() { - IX = ((IX & 0xFF00) | I_INC(IX & 0xFF)) & 0xFFFF; - return 8; + int I_INC_REF_IY_N() { + return I_INC_REF_II_N(IY); } - int I_INC_IYL() { - IY = ((IY & 0xFF00) | I_INC(IY & 0xFF)) & 0xFFFF; - return 8; - } + int I_INC_REF_II_N(int special) { + byte disp = memory.read(PC); + PC = (PC + 1) & 0xFFFF; + int address = (special + disp) & 0xFFFF; + int value = memory.read(address) & 0xFF; + memptr = address; - int I_INC(int value) { int sum = (value + 1) & 0x1FF; int sumByte = sum & 0xFF; flags = TABLE_SZ[sumByte] | (TABLE_HP[sum ^ 1 ^ value]) | (flags & FLAG_C) | TABLE_XY[sumByte]; - Q = flags; - return sumByte; - } - int I_DEC_IXH() { - IX = ((I_DEC_IIH(IX) << 8) | (IX & 0xFF)) & 0xFFFF; - return 8; + memory.write(address, (byte) sumByte); + return 23; } - int I_DEC_IYH() { - IY = ((I_DEC_IIH(IY) << 8) | (IY & 0xFF)) & 0xFFFF; - return 8; + int I_EX_REF_SP_IX() { + int tmp = readWord(SP); + int tmp1 = IX; + IX = tmp; + memptr = IX; + writeWord(SP, tmp1); + return 23; } - int I_DEC_IIH(int special) { - int reg = special >>> 8; - int sum = (reg - 1) & 0x1FF; - int sumByte = sum & 0xFF; - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C) | TABLE_XY[sumByte]; - Q = flags; - return sumByte; + int I_EX_REF_SP_IY() { + int tmp = readWord(SP); + int tmp1 = IY; + IY = tmp; + memptr = IY; + writeWord(SP, tmp1); + return 23; } - int I_DEC_IXL() { - IX = ((IX & 0xFF00) | (I_DEC_IIL(IX) & 0xFF)) & 0xFFFF; + int I_JP_REF_IX() { + PC = IX; return 8; } - int I_DEC_IYL() { - IY = ((IY & 0xFF00) | (I_DEC_IIL(IY) & 0xFF)) & 0xFFFF; + int I_JP_REF_IY() { + PC = IY; return 8; } - int I_DEC_IIL(int special) { - int reg = special & 0xFF; - int sum = (reg - 1) & 0x1FF; - int sumByte = sum & 0xFF; - flags = TABLE_SUB[sumByte] | (TABLE_HP[sum ^ 1 ^ reg]) | (flags & FLAG_C) | TABLE_XY[sumByte]; - Q = flags; - return sumByte; - } - - int I_LD_IXH_N() { - IX = (((memory.read(PC) & 0xFF) << 8) | (IX & 0xFF)) & 0xFFFF; - PC = (PC + 1) & 0xFFFF; - return 11; - } - - int I_LD_IYH_N() { - IY = (((memory.read(PC) & 0xFF) << 8) | (IY & 0xFF)) & 0xFFFF; - PC = (PC + 1) & 0xFFFF; - return 11; + int I_LD_SP_IX() { + SP = IX; + return 10; } - int I_LD_IXL_N() { - IX = ((IX & 0xFF00) | (memory.read(PC) & 0xFF)) & 0xFFFF; - PC = (PC + 1) & 0xFFFF; - return 11; + int I_LD_SP_IY() { + SP = IY; + return 10; } - int I_LD_IYL_N() { - IY = ((IY & 0xFF00) | (memory.read(PC) & 0xFF)) & 0xFFFF; - PC = (PC + 1) & 0xFFFF; - return 11; + int I_RLC_REF_IX_N_R(byte operand) { + return I_RLC_REF_II_N_R(operand, IX); } - int I_LD_R_IXH() { - return I_LD_R_IIH(IX); + int I_RLC_REF_IY_N_R(byte operand) { + return I_RLC_REF_II_N_R(operand, IY); } - int I_LD_R_IYH() { - return I_LD_R_IIH(IY); - } + int I_RLC_REF_II_N_R(byte operand, int special) { + int addr = (special + operand) & 0xFFFF; + memptr = addr; + int addrValue = memory.read(addr) & 0xFF; - int I_LD_R_IIH(int special) { - int reg = ((lastOpcode >>> 2) & 0x0F) / 2; // 4,5,6 not supported - regs[reg] = special >>> 8; - return 8; - } + int c = ((addrValue & 0x80) != 0) ? FLAG_C : 0; + int res = ((addrValue << 1) | (addrValue >>> 7)) & 0xFF; + memory.write(addr, (byte) res); + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | TABLE_XY[res]; - int I_LD_R_IXL() { - return I_LD_R_IIL(IX); + // regs[6] is unused, so it's ok + regs[lastOpcode & 7] = res & 0xFF; + return 23; } - int I_LD_R_IYL() { - return I_LD_R_IIL(IY); + int I_RRC_REF_IX_N_R(byte operand) { + return I_RRC_REF_II_N_R(operand, IX); } - int I_LD_R_IIL(int special) { - int reg = ((lastOpcode >>> 2) & 0x0F) / 2; // 4,5,6 not supported - regs[reg] = special & 0xFF; - return 8; + int I_RRC_REF_IY_N_R(byte operand) { + return I_RRC_REF_II_N_R(operand, IY); } - int I_LD_IXH_R() { - int reg = lastOpcode & 7; // 4,5,6 not supported - IX = (IX & 0xFF) | ((regs[reg] << 8) & 0xFF00); - return 8; - } + int I_RRC_REF_II_N_R(byte operand, int special) { + int addr = (special + operand) & 0xffff; + memptr = addr; + int addrValue = memory.read(addr) & 0xFF; - int I_LD_IYH_R() { - int reg = lastOpcode & 7; // 4,5,6 not supported - IY = (IY & 0xFF) | ((regs[reg] << 8) & 0xFF00); - return 8; - } + int c = addrValue & 1; + int res = (((addrValue >>> 1) & 0x7F) | (c << 7)) & 0xFF; + memory.write(addr, (byte) (res & 0xFF)); + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; - int I_LD_IIH_IIH() { - return 8; + // regs[6] is unused, so it's ok + regs[lastOpcode & 7] = res & 0xFF; + return 23; } - int I_LD_IXH_IXL() { - IX = (IX & 0xFF) | ((IX << 8) & 0xFF00); - return 8; + int I_RL_REF_IX_N_R(byte operand) { + return I_RL_REF_II_N_R(operand, IX); } - int I_LD_IYH_IYL() { - IY = (IY & 0xFF) | ((IY << 8) & 0xFF00); - return 8; + int I_RL_REF_IY_N_R(byte operand) { + return I_RL_REF_II_N_R(operand, IY); } - int I_LD_IXL_R() { - int reg = lastOpcode & 7; // 4,5,6 not supported - IX = (IX & 0xFF00) | (regs[reg] & 0xFF); - return 8; - } + int I_RL_REF_II_N_R(byte operand, int special) { + int addr = (special + operand) & 0xffff; + memptr = addr; + int addrValue = memory.read(addr) & 0xFF; - int I_LD_IYL_R() { - int reg = lastOpcode & 7; // 4,5,6 not supported - IY = (IY & 0xFF00) | (regs[reg] & 0xFF); - return 8; - } + int c = (addrValue >>> 7) & 1; + int res = ((((addrValue << 1) & 0xFF) | flags & FLAG_C) & 0xFF); + memory.write(addr, (byte) (res & 0xFF)); - int I_LD_IXL_IXH() { - IX = (IX & 0xFF00) | (IX >>> 8); - return 8; + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; + // regs[6] is unused, so it's ok + regs[lastOpcode & 7] = res & 0xFF; + return 23; } - int I_LD_IYL_IYH() { - IY = (IY & 0xFF00) | (IY >>> 8); - return 8; + int I_RR_REF_IX_N_R(byte operand) { + return I_RR_REF_II_N_R(operand, IX); } - int I_LD_IIL_IIL() { - return 8; + int I_RR_REF_IY_N_R(byte operand) { + return I_RR_REF_II_N_R(operand, IY); } - int I_ADD_A_IXH() { - return I_ADD_A(IX >>> 8); - } + int I_RR_REF_II_N_R(byte operand, int special) { + int addr = (special + operand) & 0xFFFF; + memptr = addr; + int addrValue = memory.read(addr) & 0xFF; - int I_ADD_A_IYH() { - return I_ADD_A(IY >>> 8); - } + int c = addrValue & 1; + int res = ((((addrValue >> 1) & 0xFF) | (flags & FLAG_C) << 7) & 0xFF); + memory.write(addr, (byte) (res & 0xFF)); - int I_ADD_A_IXL() { - return I_ADD_A(IX & 0xFF); + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; + // regs[6] is unused, so it's ok + regs[lastOpcode & 7] = res & 0xFF; + return 23; } - int I_ADD_A_IYL() { - return I_ADD_A(IY & 0xFF); + int I_SLA_REF_IX_N_R(byte operand) { + return I_SLA_REF_II_N_R(operand, IX); } - int I_ADD_A(int value) { - int oldA = regs[REG_A]; - int sum = (oldA + value) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; - return 8; + int I_SLA_REF_IY_N_R(byte operand) { + return I_SLA_REF_II_N_R(operand, IY); } - int I_ADC_A_IXH() { - return I_ADC_A(IX >>> 8); - } + int I_SLA_REF_II_N_R(byte operand, int special) { + int addr = (special + operand) & 0xFFFF; + memptr = addr; + int addrValue = memory.read(addr) & 0xFF; - int I_ADC_A_IYH() { - return I_ADC_A(IY >>> 8); - } + int c = (addrValue >>> 7) & 1; + int res = (addrValue << 1) & 0xFE; + memory.write(addr, (byte) res); + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; - int I_ADC_A_IXL() { - return I_ADC_A(IX & 0xFF); + // regs[6] is unused, so it's ok + regs[lastOpcode & 7] = res & 0xFF; + return 23; } - int I_ADC_A_IYL() { - return I_ADC_A(IY & 0xFF); + int I_SRA_REF_IX_N_R(byte operand) { + return I_SRA_REF_II_N_R(operand, IX); } - int I_ADC_A(int value) { - int oldA = regs[REG_A]; - int sum = (oldA + value + (flags & FLAG_C)) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[regs[REG_A]]; - return 8; + int I_SRA_REF_IY_N_R(byte operand) { + return I_SRA_REF_II_N_R(operand, IY); } - int I_SUB_IXH() { - return I_SUB(IX >>> 8); - } + int I_SRA_REF_II_N_R(byte operand, int special) { + int addr = (special + operand) & 0xFFFF; + memptr = addr; + int addrValue = memory.read(addr) & 0xFF; - int I_SUB_IYH() { - return I_SUB(IY >>> 8); - } + int c = addrValue & 1; + int res = (addrValue >> 1) & 0xFF | (addrValue & 0x80); + memory.write(addr, (byte) res); - int I_SUB_IXL() { - return I_SUB(IX & 0xFF); + flags = TABLE_SZ[res] | EmulatorTables.PARITY_TABLE[res] | c | TABLE_XY[res]; + // regs[6] is unused, so it's ok + regs[lastOpcode & 7] = res & 0xFF; + return 23; } - int I_SUB_IYL() { - return I_SUB(IY & 0xFF); + int I_SLL_REF_IX_N_R(byte operand) { + return I_SLL_REF_II_N_R(operand, IX); } - int I_SUB(int value) { - int oldA = regs[REG_A]; - int sum = (oldA - value) & 0x1FF; - regs[REG_A] = sum & 0xFF; - - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; - Q = flags; - return 8; + int I_SLL_REF_IY_N_R(byte operand) { + return I_SLL_REF_II_N_R(operand, IY); } - int I_SBC_A_IXH() { - return I_SBC_A(IX >>> 8); - } + int I_SLL_REF_II_N_R(byte operand, int special) { + int addr = (special + operand) & 0xFFFF; + memptr = addr; + int addrValue = memory.read(addr) & 0xFF; - int I_SBC_A_IYH() { - return I_SBC_A(IY >>> 8); - } + int c = ((addrValue & 0x80) != 0) ? FLAG_C : 0; + int res = ((addrValue << 1) | 0x01) & 0xFF; - int I_SBC_A_IXL() { - return I_SBC_A(IX & 0xFF); - } + memory.write(addr, (byte) res); + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | TABLE_XY[res]; - int I_SBC_A_IYL() { - return I_SBC_A(IY & 0xFF); + // regs[6] is unused, so it's ok + regs[lastOpcode & 7] = res; + return 23; } - int I_SBC_A(int value) { - int oldA = regs[REG_A]; - int sum = (oldA - value - (flags & FLAG_C)) & 0x1FF; - regs[REG_A] = sum & 0xFF; - flags = TABLE_SUB[regs[REG_A]] | TABLE_CHP[sum ^ value ^ oldA] | TABLE_XY[regs[REG_A]]; - return 8; + int I_SRL_REF_IX_N_R(byte operand) { + return I_SRL_REF_II_N_R(operand, IX); } - int I_AND_IXH() { - return I_AND(IX >>> 8); + int I_SRL_REF_IY_N_R(byte operand) { + return I_SRL_REF_II_N_R(operand, IY); } - int I_AND_IYH() { - return I_AND(IY >>> 8); - } + int I_SRL_REF_II_N_R(byte operand, int special) { + int addr = (special + operand) & 0xFFFF; + memptr = addr; + int addrValue = memory.read(addr) & 0xFF; - int I_AND_IXL() { - return I_AND(IX & 0xFF); - } + int c = ((addrValue & 0x01) != 0) ? FLAG_C : 0; + int res = (addrValue >>> 1) & 0xFF; + memory.write(addr, (byte) res); - int I_AND_IYL() { - return I_AND(IY & 0xFF); + flags = TABLE_SZ[res] | PARITY_TABLE[res] | c | TABLE_XY[res]; + // regs[6] is unused, so it's ok to set it + regs[lastOpcode & 7] = res; + return 23; } - int I_AND(int value) { - regs[REG_A] = (regs[REG_A] & value) & 0xFF; - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | FLAG_H | TABLE_XY[regs[REG_A]]; - return 8; + int I_BIT_N_REF_IX_N(byte operand) { + return I_BIT_N_REF_II_N(operand, IX); } - int I_XOR_IXH() { - return I_XOR(IX >>> 8); + int I_BIT_N_REF_IY_N(byte operand) { + return I_BIT_N_REF_II_N(operand, IY); } - int I_XOR_IYH() { - return I_XOR(IY >>> 8); - } + int I_BIT_N_REF_II_N(byte operand, int special) { + int bit = (lastOpcode >>> 3) & 7; + int address = (special + operand) & 0xFFFF; + memptr = address; + byte addrValue = memory.read(address); + int result = (1 << bit) & addrValue; - int I_XOR_IXL() { - return I_XOR(IX & 0xFF); + flags = ((flags & FLAG_C) + | FLAG_H + | ((result == 0) ? (FLAG_Z | FLAG_PV) : 0)) + | TABLE_XY[special & 0xFF]; + if (bit == 7) { + flags |= ((result == 0x80) ? FLAG_S : 0); + } + return 20; } - int I_XOR_IYL() { - return I_XOR(IY & 0xFF); + int I_RES_N_REF_IX_N_R(byte operand) { + return I_RES_N_REF_II_N_R(operand, IX); } - int I_XOR(int value) { - regs[REG_A] = (regs[REG_A] ^ value) & 0xFF; - flags = PARITY_TABLE[regs[REG_A]] | TABLE_SZ[regs[REG_A]] | TABLE_XY[regs[REG_A]]; - return 8; + int I_RES_N_REF_IY_N_R(byte operand) { + return I_RES_N_REF_II_N_R(operand, IY); } - int I_OR_IXH() { - return I_OR(IX >>> 8); + int I_RES_N_REF_II_N_R(byte operand, int special) { + int bitNumber = (lastOpcode >>> 3) & 7; + int addr = (special + operand) & 0xFFFF; + memptr = addr; + int addrValue = memory.read(addr) & 0xFF; + int res = (addrValue & (~(1 << bitNumber))); + memory.write(addr, (byte) (res & 0xff)); + // regs[6] is unused, so it's ok + regs[lastOpcode & 7] = res & 0xFF; + return 23; } - int I_OR_IXL() { - return I_OR(IX & 0xFF); + int I_SET_N_REF_IX_N_R(byte operand) { + return I_SET_N_REF_II_N_R(operand, IX); } - int I_OR_IYH() { - return I_OR(IY >>> 8); + int I_SET_N_REF_IY_N_R(byte operand) { + return I_SET_N_REF_II_N_R(operand, IY); } - int I_OR_IYL() { - return I_OR(IY & 0xFF); - } + int I_SET_N_REF_II_N_R(byte operand, int special) { + int bitNumber = (lastOpcode >>> 3) & 7; + int addr = (special + operand) & 0xFFFF; + memptr = addr; + int addrValue = memory.read(addr) & 0xFF; - int I_OR(int value) { - regs[REG_A] = (regs[REG_A] | value) & 0xFF; - flags = TABLE_SZ[regs[REG_A]] | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; - return 8; - } + int res = (addrValue | (1 << bitNumber)) & 0xFF; + memory.write(addr, (byte) res); - int I_CP_IXH() { - return I_CP(IX >>> 8); + // regs[6] is unused, so it's ok + regs[lastOpcode & 7] = res; + return 23; } - int I_CP_IXL() { - return I_CP(IX & 0xFF); + int I_LD_IXH_N() { + IX = (((memory.read(PC) & 0xFF) << 8) | (IX & 0xFF)) & 0xFFFF; + PC = (PC + 1) & 0xFFFF; + return 11; } - int I_CP_IYH() { - return I_CP(IY >>> 8); + int I_LD_IYH_N() { + IY = (((memory.read(PC) & 0xFF) << 8) | (IY & 0xFF)) & 0xFFFF; + PC = (PC + 1) & 0xFFFF; + return 11; } - int I_CP_IYL() { - return I_CP(IY & 0xFF); + int I_LD_IXL_N() { + IX = ((IX & 0xFF00) | (memory.read(PC) & 0xFF)) & 0xFFFF; + PC = (PC + 1) & 0xFFFF; + return 11; } - int I_CP(int value) { - int oldA = regs[REG_A]; - int sum = (oldA - value) & 0x1FF; - int result = sum & 0xFF; - flags = TABLE_SUB[result] | (TABLE_CHP[sum ^ value ^ oldA]) | TABLE_XY[value & 0xFF]; - return 8; + int I_LD_IYL_N() { + IY = ((IY & 0xFF00) | (memory.read(PC) & 0xFF)) & 0xFFFF; + PC = (PC + 1) & 0xFFFF; + return 11; } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java index 8b0c9047a..4d5b6f174 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/ArithmeticTest.java @@ -21,7 +21,6 @@ import net.emustudio.cpu.testsuite.Generator; import net.emustudio.cpu.testsuite.RunnerContext; import net.emustudio.plugins.cpu.zilogZ80.suite.ByteTestBuilder; -import net.emustudio.plugins.cpu.zilogZ80.suite.FlagsCheckImpl; import net.emustudio.plugins.cpu.zilogZ80.suite.IntegerTestBuilder; import org.junit.Test; @@ -65,7 +64,6 @@ public void testADC_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( @@ -86,8 +84,7 @@ public void testADC_A_R() { public void testADC_A_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)); Generator.forSome8bitBinary( test.runWithSecondOperand(0xCE) @@ -126,8 +123,6 @@ public void testSBC_A_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> ((context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( @@ -148,9 +143,7 @@ public void testSBC_A_R() { public void testSBC_A_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)); Generator.forSome8bitBinary( test.runWithSecondOperand(0xDE) @@ -160,16 +153,12 @@ public void testSBC_A_N() { @Test public void testINC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyFlags(new FlagsCheckImpl() - .sign().zero().overflow().halfCarry() - .subtractionIsReset() - .carryIsPreserved(), - context -> context.first + 1) - .keepCurrentInjectorsAfterRun() .clearOtherVerifiersAfterRun(); + Function, Integer> incOperation = context -> (context.first + 1) & 0xFF; + Generator.forSome8bitUnary( - test.firstIsRegister(REG_B).verifyRegister(REG_B).run(0x04), + test.firstIsRegister(REG_B).verifyRegister(REG_B, incOperation).run(0x04), test.firstIsRegister(REG_C).verifyRegister(REG_C).run(0x0C), test.firstIsRegister(REG_D).verifyRegister(REG_D).run(0x14), test.firstIsRegister(REG_E).verifyRegister(REG_E).run(0x1C), @@ -183,17 +172,13 @@ public void testINC_R() { @Test public void testDEC_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .verifyFlags(new FlagsCheckImpl() - .setSecond(c -> 1) - .sign().zero().overflowSub().halfBorrow() - .subtractionIsSet() - .carryIsPreserved(), - context -> context.first - 1) .keepCurrentInjectorsAfterRun() .clearOtherVerifiersAfterRun(); + Function, Integer> decOperation = context -> (context.first - 1) & 0xFF; + Generator.forSome8bitUnary( - test.firstIsRegister(REG_B).verifyRegister(REG_B).run(0x05), + test.firstIsRegister(REG_B).verifyRegister(REG_B, decOperation).run(0x05), test.firstIsRegister(REG_C).verifyRegister(REG_C).run(0x0D), test.firstIsRegister(REG_D).verifyRegister(REG_D).run(0x15), test.firstIsRegister(REG_E).verifyRegister(REG_E).run(0x1D), @@ -240,14 +225,6 @@ public void testADD_HL_RP() { .setFlags(0xFF) .firstIsPair(REG_PAIR_HL) .verifyPair(REG_PAIR_HL, context -> context.first + context.second) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .signIsPreserved() - .zeroIsPreserved() - .parityIsPreserved() - .carry15() - .halfCarry11() - .subtractionIsReset() - ) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( @@ -268,7 +245,6 @@ public void testADD_A_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -283,7 +259,6 @@ public void testADC_A_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -298,7 +273,6 @@ public void testSUB_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -313,8 +287,6 @@ public void testSBC_A_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().borrow().halfBorrow().overflowSubCarry().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -350,11 +322,6 @@ public void testINC_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .verifyByte(context -> get8MSBplus8LSB(context.first), context -> (context.second + 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond() - .setSecond(c -> 1) - .sign().zero().halfCarry().overflow().subtractionIsReset().carryIsPreserved() - ) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -368,13 +335,6 @@ public void testDEC_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .verifyByte(context -> get8MSBplus8LSB(context.first), context -> (context.second - 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond() - .setSecond(c -> 1) - .sign().zero().halfBorrow().overflowSub() - .subtractionIsSet() - .carryIsPreserved() - ) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -389,9 +349,6 @@ public void testADD_IX_RP() { .setFlags(0xFF) .firstIsIX() .verifyIX(context -> context.first + context.second) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .signIsPreserved().zeroIsPreserved().parityIsPreserved() - .halfCarry11().carry15().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( @@ -411,9 +368,6 @@ public void testADD_IY_RP() { .setFlags(0xFF) .firstIsIY() .verifyIY(context -> context.first + context.second) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .signIsPreserved().zeroIsPreserved().parityIsPreserved() - .halfCarry11().carry15().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( @@ -433,9 +387,6 @@ public void testADC_HL_RP() { .setFlags(0xFF) .firstIsPair(REG_PAIR_HL) .verifyPair(REG_PAIR_HL, context -> context.first + context.second + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .overflow16bit().sign16bit().zero16bit() - .carry15().halfCarry11().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( @@ -456,8 +407,6 @@ public void testSBC_HL_RP() { .firstIsPair(REG_PAIR_HL) .verifyPair(REG_PAIR_HL, context -> (context.first - context.second - (context.flags & FLAG_C))) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign16bit().zero16bit().borrow16bit().carry15().halfCarry11().subtractionIsSet()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryWhichEqual( @@ -475,10 +424,6 @@ public void testSBC_HL_RP() { public void testINC_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8MSB() - .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), - context -> ((context.first >>> 8) + 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); Generator.forSome16bitUnary( @@ -490,10 +435,6 @@ public void testINC_IXH() { public void testINC_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIY() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8MSB() - .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), - context -> ((context.first >>> 8) + 1) & 0xFF) .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) + 1) & 0xFF) << 8)); Generator.forSome16bitUnary( @@ -505,13 +446,6 @@ public void testINC_IYH() { public void testDEC_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8MSB() - .setSecond(c -> 1) - .overflowSub().halfBorrow() - .subtractionIsSet() - .carryIsPreserved(), - context -> ((context.first >>> 8) - 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); Generator.forSome16bitUnary( @@ -523,14 +457,6 @@ public void testDEC_IXH() { public void testDEC_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIY() - .verifyFlags(new FlagsCheckImpl() - .setFirst8MSB() - .sign().zero() - .setSecond(c -> 1) - .overflowSub().halfBorrow() - .subtractionIsSet() - .carryIsPreserved(), - context -> ((context.first >>> 8) - 1) & 0xFF) .verifyIY(context -> (context.first & 0xFF) | ((((context.first >>> 8) - 1) & 0xFF) << 8)); Generator.forSome16bitUnary( @@ -542,11 +468,6 @@ public void testDEC_IYH() { public void testINC_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8LSB() - .setSecond(c -> 1) - .overflow().halfCarry().subtractionIsReset().carryIsPreserved(), - context -> ((context.first & 0xFF) + 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) + 1) & 0xFF)); Generator.forSome16bitUnary( @@ -558,11 +479,6 @@ public void testINC_IXL() { public void testINC_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIY() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8LSB() - .setSecond(c -> 1) - .overflow().halfCarry().subtractionIsReset(), - context -> ((context.first & 0xFF) + 1) & 0xFF) .verifyIY(context -> (context.first & 0xFF00) | (((context.first & 0xFF) + 1) & 0xFF)); Generator.forSome16bitUnary( @@ -574,13 +490,6 @@ public void testINC_IYL() { public void testDEC_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIX() - .verifyFlags(new FlagsCheckImpl().sign().zero() - .setFirst8LSB() - .setSecond(c -> 1) - .overflowSub().halfBorrow() - .subtractionIsSet() - .carryIsPreserved(), - context -> ((context.first & 0xFF) - 1) & 0xFF) .verifyIX(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); Generator.forSome16bitUnary( @@ -592,14 +501,6 @@ public void testDEC_IXL() { public void testDEC_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsIY() - .verifyFlags(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond(c -> 1) - .sign().zero() - .overflowSub().halfBorrow() - .subtractionIsSet() - .carryIsPreserved(), - context -> ((context.first & 0xFF) - 1) & 0xFF) .verifyIY(context -> (context.first & 0xFF00) | (((context.first & 0xFF) - 1) & 0xFF)); Generator.forSome16bitUnary( @@ -612,11 +513,7 @@ public void testADD_A_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond8MSB() - .sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)); Generator.forSome16bitBinary( test.run(0xDD, 0x84) @@ -628,11 +525,7 @@ public void testADD_A_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond8MSB() - .sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8)); Generator.forSome16bitBinary( test.run(0xFD, 0x84) @@ -644,8 +537,7 @@ public void testADD_A_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)); Generator.forSome16bitBinary( test.run(0xDD, 0x85) @@ -657,8 +549,7 @@ public void testADD_A_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry().halfCarry().overflow().subtractionIsReset()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)); Generator.forSome16bitBinary( test.run(0xFD, 0x85) @@ -670,12 +561,7 @@ public void testADC_A_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() - .setFirst8LSB() - .setSecond8MSB() - .halfCarry() - .overflow().subtractionIsReset()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)); Generator.forSome16bitBinary( test.run(0xDD, 0x8C) @@ -687,12 +573,7 @@ public void testADC_A_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() - .setFirst8LSB() - .setSecond8MSB() - .halfCarry() - .overflow().subtractionIsReset()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second >>> 8) + (context.flags & FLAG_C)); Generator.forSome16bitBinary( test.run(0xFD, 0x8C) @@ -704,12 +585,7 @@ public void testADC_A_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() - .setFirst8LSB() - .setSecond8LSB() - .halfCarry() - .overflow().subtractionIsReset()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)); Generator.forSome16bitBinary( test.run(0xDD, 0x8D) @@ -721,12 +597,7 @@ public void testADC_A_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().carry() - .setFirst8LSB() - .setSecond8LSB() - .halfCarry() - .overflow().subtractionIsReset()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF) + (context.flags & FLAG_C)); Generator.forSome16bitBinary( test.run(0xFD, 0x8D) @@ -738,13 +609,7 @@ public void testSUB_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero() - .setSecond8MSB() - .borrow() - .halfBorrow() - .overflowSub().subtractionIsSet()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)); Generator.forSome16bitBinary( test.run(0xDD, 0x94) @@ -756,13 +621,7 @@ public void testSUB_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero() - .setSecond8MSB() - .borrow() - .halfBorrow() - .overflowSub().subtractionIsSet()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF)); Generator.forSome16bitBinary( test.run(0xFD, 0x94) @@ -774,12 +633,7 @@ public void testSUB_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero() - .borrow() - .halfBorrow() - .overflowSub().subtractionIsSet()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); Generator.forSome16bitBinary( test.run(0xDD, 0x95) @@ -791,12 +645,7 @@ public void testSUB_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero() - .borrow() - .halfBorrow() - .overflowSub().subtractionIsSet()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); Generator.forSome16bitBinary( test.run(0xFD, 0x95) @@ -808,14 +657,7 @@ public void testSBC_A_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond8MSB() - .sign().zero() - .borrowWithCarry() - .halfBorrow() - .overflowSubCarry().subtractionIsSet()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)); Generator.forSome16bitBinary( test.run(0xDD, 0x9C) @@ -827,13 +669,7 @@ public void testSBC_A_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .setSecond8MSB() - .sign().zero() - .borrowWithCarry() - .halfBorrow() - .overflowSubCarry().subtractionIsSet()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second >>> 8)) + 1) & 0xFF) - (context.flags & FLAG_C)); Generator.forSome16bitBinary( test.run(0xFD, 0x9C) @@ -845,11 +681,7 @@ public void testSBC_A_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond8LSB() - .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)); Generator.forSome16bitBinary( test.run(0xDD, 0x9D) @@ -861,9 +693,7 @@ public void testSBC_A_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().borrowWithCarry().halfBorrow().overflowSubCarry().subtractionIsSet()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF) - (context.flags & FLAG_C)); Generator.forSome16bitBinary( test.run(0xFD, 0x9D) @@ -872,15 +702,9 @@ public void testSBC_A_IYL() { private ByteTestBuilder additionTestBuilder() { - FlagsCheckImpl flagsCheck = new FlagsCheckImpl() - .sign().zero().carry().halfCarry().overflow() - .subtractionIsReset() - .xy(); - return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) + (context.second & 0xFF)) - .verifyFlagsOfLastOp(flagsCheck) .keepCurrentInjectorsAfterRun(); } @@ -888,12 +712,6 @@ private ByteTestBuilder subtractionTestBuilder() { return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) - (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().borrow() - .halfBorrow() - .overflowSub() - .subtractionIsSet() - .xy()) .keepCurrentInjectorsAfterRun(); } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/BitTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/BitTest.java index 6109bacc3..8e688886d 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/BitTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/BitTest.java @@ -21,7 +21,6 @@ import net.emustudio.cpu.testsuite.Generator; import net.emustudio.cpu.testsuite.RunnerContext; import net.emustudio.plugins.cpu.zilogZ80.suite.ByteTestBuilder; -import net.emustudio.plugins.cpu.zilogZ80.suite.FlagsCheckImpl; import net.emustudio.plugins.cpu.zilogZ80.suite.IntegerTestBuilder; import org.junit.Test; @@ -32,284 +31,6 @@ public class BitTest extends InstructionsTest { - private ByteTestBuilder prepareBITtest(int register) { - return new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsRegister(register) - .setFlags(FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); - } - - private ByteTestBuilder verifyFlags(ByteTestBuilder test, FlagsCheckImpl flagsBuilder, int bitShift) { - return test.verifyFlags(flagsBuilder, context -> (context.first & (1 << bitShift))); - } - - private IntegerTestBuilder verifyFlags(IntegerTestBuilder test, FlagsCheckImpl flagsBuilder, int bitShift) { - return test.verifyFlags(flagsBuilder, context -> (context.second & (1 << bitShift))); - } - - @Test - public void testBIT_b__A() { - ByteTestBuilder test = prepareBITtest(REG_A); - - FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); - FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); - Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x47), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4F), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x57), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5F), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x67), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6F), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x77), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7F) - ); - } - - @Test - public void testBIT_b__B() { - ByteTestBuilder test = prepareBITtest(REG_B); - - FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); - FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); - Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x40), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x48), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x50), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x58), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x60), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x68), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x70), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x78) - ); - } - - @Test - public void testBIT_b__C() { - ByteTestBuilder test = prepareBITtest(REG_C); - - FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); - FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); - Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x41), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x49), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x51), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x59), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x61), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x69), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x71), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x79) - ); - } - - @Test - public void testBIT_b__D() { - ByteTestBuilder test = prepareBITtest(REG_D); - - FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); - FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); - Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x42), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4A), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x52), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5A), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x62), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6A), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x72), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7A) - ); - } - - @Test - public void testBIT_b__E() { - ByteTestBuilder test = prepareBITtest(REG_E); - - FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); - FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); - Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x43), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4B), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x53), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5B), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x63), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6B), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x73), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7B) - ); - } - - @Test - public void testBIT_b__H() { - ByteTestBuilder test = prepareBITtest(REG_H); - - FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); - FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); - Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x44), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4C), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x54), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5C), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x64), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6C), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x74), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7C) - ); - } - - @Test - public void testBIT_b__L() { - ByteTestBuilder test = prepareBITtest(REG_L); - - FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); - FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); - Generator.forSome8bitUnary( - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x45), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4D), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x55), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5D), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x65), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6D), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x75), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7D) - ); - } - - @Test - public void testBIT_b__mHL() { - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .firstIsAddressAndSecondIsMemoryByte() - .firstIsPair(REG_PAIR_HL) - .setFlags(FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); - - FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); - FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); - Generator.forSome16bitBinary(2, - verifyFlags(test, flagsBuilder, 0).run(0xCB, 0x46), - verifyFlags(test, flagsBuilder, 1).run(0xCB, 0x4E), - verifyFlags(test, flagsBuilder, 2).run(0xCB, 0x56), - verifyFlags(test, flagsBuilder, 3).run(0xCB, 0x5E), - verifyFlags(test, flagsBuilder, 4).run(0xCB, 0x66), - verifyFlags(test, flagsBuilder, 5).run(0xCB, 0x6E), - verifyFlags(test, flagsBuilder, 6).run(0xCB, 0x76), - verifyFlags(test, signFlagBuilder, 7).run(0xCB, 0x7E) - ); - } - - @Test - public void testBIT_b__IX_plus_d() { - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8MSBisIX() - .setFlags(FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); - - FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); - FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); - Generator.forSome16bitBinary(0x100, - verifyFlags(test, flagsBuilder, 0).runWithFirst8bitOperandWithOpcodeAfter(0x46, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 1).runWithFirst8bitOperandWithOpcodeAfter(0x4E, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 2).runWithFirst8bitOperandWithOpcodeAfter(0x56, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 3).runWithFirst8bitOperandWithOpcodeAfter(0x5E, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 4).runWithFirst8bitOperandWithOpcodeAfter(0x66, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 5).runWithFirst8bitOperandWithOpcodeAfter(0x6E, 0xDD, 0xCB), - verifyFlags(test, flagsBuilder, 6).runWithFirst8bitOperandWithOpcodeAfter(0x76, 0xDD, 0xCB), - verifyFlags(test, signFlagBuilder, 7).runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xDD, 0xCB) - ); - } - - @Test - public void testBIT_b__IX_plus_d_undocumented() { - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8MSBisIX() - .setFlags(FLAG_N) - .verifyFlags(new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero().parity().sign(), - context -> (context.second & (1 << 7))) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); - - Generator.forSome16bitBinary(0x100, - test.runWithFirst8bitOperandWithOpcodeAfter(0x78, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x79, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7A, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7B, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7C, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7D, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xDD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7F, 0xDD, 0xCB) - ); - } - - @Test - public void testBIT_b__IY_plus_d() { - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8MSBisIY() - .setFlags(FLAG_N) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); - - FlagsCheckImpl flagsBuilder = new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero() - .parity(); - FlagsCheckImpl signFlagBuilder = new FlagsCheckImpl().sign().halfCarryIsSet().subtractionIsReset() - .zero().parity(); - Generator.forSome16bitBinary(0x100, - verifyFlags(test, flagsBuilder, 0).runWithFirst8bitOperandWithOpcodeAfter(0x46, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 1).runWithFirst8bitOperandWithOpcodeAfter(0x4E, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 2).runWithFirst8bitOperandWithOpcodeAfter(0x56, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 3).runWithFirst8bitOperandWithOpcodeAfter(0x5E, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 4).runWithFirst8bitOperandWithOpcodeAfter(0x66, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 5).runWithFirst8bitOperandWithOpcodeAfter(0x6E, 0xFD, 0xCB), - verifyFlags(test, flagsBuilder, 6).runWithFirst8bitOperandWithOpcodeAfter(0x76, 0xFD, 0xCB), - verifyFlags(test, signFlagBuilder, 7).runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xFD, 0xCB) - ); - } - - - @Test - public void testBIT_b__IY_plus_d_undocumented() { - IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) - .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() - .first8MSBisIY() - .setFlags(FLAG_N) - .verifyFlags(new FlagsCheckImpl().halfCarryIsSet().subtractionIsReset().zero().parity().sign(), - context -> (context.second & (1 << 7))) - .keepCurrentInjectorsAfterRun() - .clearOtherVerifiersAfterRun(); - - Generator.forSome16bitBinary(0x100, - test.runWithFirst8bitOperandWithOpcodeAfter(0x78, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x79, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7A, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7B, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7C, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7D, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7E, 0xFD, 0xCB), - test.runWithFirst8bitOperandWithOpcodeAfter(0x7F, 0xFD, 0xCB) - ); - } - @Test public void testSET_b__A() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java index c2701d301..04b658808 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java @@ -362,21 +362,21 @@ public void testDisassemble() throws InvalidInstructionException { 0xFD, 0x6C, // ld iyl, iyh 0xFD, 0x6D, // ld iyl, iyl 0xDD, 0x72, 0x20, // ld (ix+0x20), d - 0xDD, 0x74, 0x20, // ld (ix+0x20), h - 0xDD, 0x75, 0x20, // ld (ix+0x20), l + 0xDD, 0x74, 0x20, // ld (ix+0x20), ixh + 0xDD, 0x75, 0x20, // ld (ix+0x20), ixl 0xFD, 0x73, 0x20, // ld (iy+0x20), e - 0xFD, 0x74, 0x20, // ld (iy+0x20), h - 0xFD, 0x75, 0x20, // ld (iy+0x20), l + 0xFD, 0x74, 0x20, // ld (iy+0x20), iyh + 0xFD, 0x75, 0x20, // ld (iy+0x20), iyl 0xDD, 0x7C, // ld a, ixh 0xFD, 0x7C, // ld a, iyh 0xDD, 0x7D, // ld a, ixl 0xFD, 0x7D, // ld a, iyl 0xDD, 0x7E, 0x20, // ld a, (ix+0x20) 0xFD, 0x7E, 0x20, // ld a, (iy+0x20) - 0xDD, 0x66, 0x20, // ld h, (ix+0x20) - 0xDD, 0x6E, 0x20, // ld l, (ix+0x20) - 0xFD, 0x66, 0x20, // ld h, (iy+0x20) - 0xFD, 0x6E, 0x20, // ld l, (iy+0x20) + 0xDD, 0x66, 0x20, // ld ixh, (ix+0x20) + 0xDD, 0x6E, 0x20, // ld ixl, (ix+0x20) + 0xFD, 0x66, 0x20, // ld iyh, (iy+0x20) + 0xFD, 0x6E, 0x20, // ld iyl, (iy+0x20) 0xDD, 0x84, // add a, ixh 0xDD, 0x85, // add a, ixl 0xDD, 0x86, 0x20, // add a, (ix + 0x20) @@ -757,21 +757,21 @@ public void testDisassemble() throws InvalidInstructionException { "ld iyl, iyh" + "ld iyl, iyl" + "ld (ix+20h), d" + - "ld (ix+20h), h" + - "ld (ix+20h), l" + + "ld (ix+20h), ixh" + + "ld (ix+20h), ixl" + "ld (iy+20h), e" + - "ld (iy+20h), h" + - "ld (iy+20h), l" + + "ld (iy+20h), iyh" + + "ld (iy+20h), iyl" + "ld a, ixh" + "ld a, iyh" + "ld a, ixl" + "ld a, iyl" + "ld a, (ix+20h)" + "ld a, (iy+20h)" + - "ld h, (ix+20h)" + - "ld l, (ix+20h)" + - "ld h, (iy+20h)" + - "ld l, (iy+20h)" + + "ld ixh, (ix+20h)" + + "ld ixl, (ix+20h)" + + "ld iyh, (iy+20h)" + + "ld iyl, (iy+20h)" + "add a, ixh" + "add a, ixl" + "add a, (ix+20h)" + diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java index 9aa679dca..cf20ed9fe 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/IOTest.java @@ -18,11 +18,9 @@ */ package net.emustudio.plugins.cpu.zilogZ80; -import net.emustudio.cpu.testsuite.FlagsCheck; import net.emustudio.cpu.testsuite.Generator; import net.emustudio.cpu.testsuite.RunnerContext; import net.emustudio.plugins.cpu.zilogZ80.suite.ByteTestBuilder; -import net.emustudio.plugins.cpu.zilogZ80.suite.FlagsCheckImpl; import net.emustudio.plugins.cpu.zilogZ80.suite.IntegerTestBuilder; import org.junit.Test; @@ -51,8 +49,6 @@ public void testIN_R_REF_C() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsDeviceAndSecondIsPort() .secondIsRegister(REG_C) - .verifyFlags(new FlagsCheckImpl().sign().zero().parity().halfCarryIsReset().subtractionIsReset(), - operation) .keepCurrentInjectorsAfterRun() .clearOtherVerifiersAfterRun(); @@ -69,13 +65,9 @@ public void testIN_R_REF_C() { @Test public void testIN_REF_C() { - Function, Integer> operation = context -> context.first & 0xFF; - ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsDeviceAndSecondIsPort() .secondIsRegister(REG_C) - .verifyFlags(new FlagsCheckImpl().sign().zero().parity().halfCarryIsReset().subtractionIsReset(), - operation) .keepCurrentInjectorsAfterRun() .clearOtherVerifiersAfterRun(); @@ -94,12 +86,7 @@ public void testINI() { .first8MSBisRegister(REG_B) .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() - .carryIsPreserved() - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) - ); + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF); Generator.forSome16bitBinary(2, test.run(0xED, 0xA2) @@ -117,11 +104,6 @@ public void testINIR() { .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .zeroIsSet() - .subtractionIsSet() - .carryIsPreserved() - ) .verifyPC(context -> { if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { return context.PC; @@ -144,11 +126,7 @@ public void testIND() { .first8MSBisRegister(REG_B) .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() - .subtractionIsSet() - .carryIsPreserved() - ); + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF); Generator.forSome16bitBinary(2, test.run(0xED, 0xAA) @@ -166,10 +144,6 @@ public void testINDR() { .verifyByte(context -> context.first, context -> (context.first >>> 8) & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .zeroIsSet() - .subtractionIsSet() - .carryIsPreserved()) .verifyPC(context -> { if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { return context.PC; @@ -235,11 +209,7 @@ public void testOUTI() { .first8MSBisRegister(REG_B) .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) - ); + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF); Generator.forSome16bitBinary(2, test.run(0xED, 0xA3) @@ -256,11 +226,6 @@ public void testOTIR() { .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first + 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) - ) .verifyPC(context -> { if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { return context.PC; @@ -282,11 +247,7 @@ public void testOUTD() { .first8MSBisRegister(REG_B) .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) - .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().zero() - .subtractionIsSet() - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) - ); + .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF); Generator.forSome16bitBinary(2, test.run(0xED, 0xAB) @@ -303,11 +264,6 @@ public void testOTDR() { .verifyDeviceWhenFirst8LSBisPort(context -> context.second & 0xFF) .verifyPair(REG_PAIR_HL, context -> (context.first - 1) & 0xFFFF) .verifyRegister(REG_B, context -> (((context.first >>> 8) & 0xFF) - 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .expectFlagOnlyWhen(FLAG_N, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_Z, (context, result) -> true) - .expectFlagOnlyWhen(FLAG_C, (context, result) -> (context.flags & FLAG_C) == FLAG_C) - ) .verifyPC(context -> { if (((((context.first >>> 8) & 0xFF) - 1) & 0xFF) != 0) { return context.PC; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java index d4f851bc9..5003845c6 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/InstructionsTest.java @@ -48,16 +48,16 @@ public class InstructionsTest { private final List devices = new ArrayList<>(); CpuRunnerImpl cpuRunnerImpl; CpuVerifierImpl cpuVerifierImpl; - private CpuImpl cpu; + protected CpuImpl cpu; + protected ByteMemoryStub memory; @SuppressWarnings("unchecked") @Before public void setUp() throws Exception { - ByteMemoryStub memoryStub = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); - + memory = new ByteMemoryStub(NumberUtils.Strategy.LITTLE_ENDIAN); Capture cpuContext = Capture.newInstance(); ContextPool contextPool = EasyMock.createNiceMock(ContextPool.class); - expect(contextPool.getMemoryContext(0, MemoryContext.class)).andReturn(memoryStub).anyTimes(); + expect(contextPool.getMemoryContext(0, MemoryContext.class)).andReturn(memory).anyTimes(); contextPool.register(anyLong(), capture(cpuContext), same(Context8080.class)); expectLastCall().anyTimes(); replay(contextPool); @@ -78,8 +78,8 @@ public void setUp() throws Exception { cpu.initialize(); - cpuRunnerImpl = new CpuRunnerImpl(cpu, memoryStub, devices); - cpuVerifierImpl = new CpuVerifierImpl(cpu, memoryStub, devices); + cpuRunnerImpl = new CpuRunnerImpl(cpu, memory, devices); + cpuVerifierImpl = new CpuVerifierImpl(cpu, memory, devices); Generator.setRandomTestsCount(10); } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java index 4b489160a..38e746dfe 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/LogicTest.java @@ -21,7 +21,6 @@ import net.emustudio.cpu.testsuite.Generator; import net.emustudio.cpu.testsuite.RunnerContext; import net.emustudio.plugins.cpu.zilogZ80.suite.ByteTestBuilder; -import net.emustudio.plugins.cpu.zilogZ80.suite.FlagsCheckImpl; import net.emustudio.plugins.cpu.zilogZ80.suite.IntegerTestBuilder; import org.junit.Test; @@ -39,8 +38,6 @@ public void testAND_R() { .setFlags(0xFF) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> context.first & context.second) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( @@ -64,8 +61,6 @@ public void testAND_N() { .setFlags(0xFF) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> context.first & context.second) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinary( @@ -134,9 +129,6 @@ public void testCP_R() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow() - .overflowSub().subtractionIsSet(), - context -> (context.first & 0xFF) + (((~context.second) + 1) & 0xFF)) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitBinaryWhichEqual( @@ -157,9 +149,7 @@ public void testCP_R() { public void testCP_N() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet(), - context -> (context.first & 0xFF) - (byte) (context.second & 0xFF)); + .verifyRegister(REG_A, context -> context.first & 0xFF); Generator.forSome8bitBinary( test.runWithSecondOperand(0xFE) @@ -221,7 +211,6 @@ public void testDAA() { for (int[] p : params) { test.verifyRegister(REG_A, c -> p[2]) - .verifyFlags(new FlagsCheckImpl().exact(p[3]), c -> c.flags) .run(0x27) .accept((byte) p[0], (byte) p[1]); } @@ -231,8 +220,7 @@ public void testDAA() { public void testCPL() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) - .verifyRegister(REG_A, context -> ~context.first) - .verifyFlagsOfLastOp(new FlagsCheckImpl().halfCarryIsSet().subtractionIsSet()); + .verifyRegister(REG_A, context -> ~context.first); Generator.forSome8bitUnary( test.run(0x2F) @@ -265,9 +253,7 @@ public void testRLCA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .setFlags(FLAG_N | FLAG_H) - .verifyRegister(REG_A, context -> ((context.first << 1) & 0xFF) | (context.first >>> 7) & 1) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsFirstOperandMSB().halfCarryIsReset().subtractionIsReset()); + .verifyRegister(REG_A, context -> ((context.first << 1) & 0xFF) | (context.first >>> 7) & 1); Generator.forSome8bitUnary( test.run(0x07) @@ -279,14 +265,7 @@ public void testRRCA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .setFlags(FLAG_N | FLAG_H) - .verifyRegister(REG_A, context -> (((context.first & 0xFF) >>> 1) | (context.first << 7)) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .signIsPreserved() - .zeroIsPreserved() - .parityIsPreserved() - .carryIsFirstOperandLSB() - .halfCarryIsReset() - .subtractionIsReset()); + .verifyRegister(REG_A, context -> (((context.first & 0xFF) >>> 1) | (context.first << 7)) & 0xFF); Generator.forSome8bitUnary( test.run(0x0F) @@ -298,9 +277,7 @@ public void testRLA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .setFlags(FLAG_N | FLAG_H) - .verifyRegister(REG_A, context -> ((context.first << 1) & 0xFE) | (context.flags & 1)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsFirstOperandMSB().halfCarryIsReset().subtractionIsReset()); + .verifyRegister(REG_A, context -> ((context.first << 1) & 0xFE) | (context.flags & 1)); Generator.forSome8bitUnary( test.run(0x17) @@ -312,9 +289,7 @@ public void testRRA() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .setFlags(FLAG_N | FLAG_H) - .verifyRegister(REG_A, context -> ((context.first >> 1) & 0x7F) | ((context.flags & 1) << 7)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsFirstOperandLSB().halfCarryIsReset().subtractionIsReset()); + .verifyRegister(REG_A, context -> ((context.first >> 1) & 0x7F) | ((context.flags & 1) << 7)); Generator.forSome8bitUnary( test.run(0x1F) @@ -383,8 +358,6 @@ public void testAND_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.second & 0xFF)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().parity().carryIsReset().halfCarryIsSet().subtractionIsReset()) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -421,9 +394,6 @@ public void testCP_REF_II_N() { .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl().sign().zero().borrow().halfBorrow().overflowSub().subtractionIsSet(), - context -> (context.first & 0xFF) - (context.second & 0xFF) - ) .keepCurrentInjectorsAfterRun(); Generator.forSome16bitBinaryFirstSatisfying(predicate8MSBplus8LSB(3), @@ -437,13 +407,6 @@ public void testNEG() { ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .firstIsRegister(REG_A) .verifyRegister(REG_A, context -> (-context.first) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero() - .expectFlagOnlyWhen(FLAG_C, (c, result) -> c.first != 0) - .expectFlagOnlyWhen(FLAG_PV, (c, result) -> (c.first & 0xff) == 0x80) - .halfBorrow() - .subtractionIsSet() - ) .keepCurrentInjectorsAfterRun(); Generator.forSome8bitUnary( @@ -467,19 +430,17 @@ public void testRLC_R() { Function, Integer> operator = context -> ((context.first << 1) & 0xFF) | (context.first >>> 7) & 1; - FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x07), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x00), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x01), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x02), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x03), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x04), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x05), + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).run(0xCB, 0x07), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).run(0xCB, 0x00), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).run(0xCB, 0x01), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).run(0xCB, 0x02), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).run(0xCB, 0x03), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).run(0xCB, 0x04), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).run(0xCB, 0x05), test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x06) + .run(0xCB, 0x06) ); } @@ -520,19 +481,17 @@ public void testRL_R() { Function, Integer> operator = context -> ((context.first << 1) & 0xFF) | (context.flags & FLAG_C); - FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x17), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x10), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x11), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x12), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x13), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x14), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x15), + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).run(0xCB, 0x17), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).run(0xCB, 0x10), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).run(0xCB, 0x11), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).run(0xCB, 0x12), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).run(0xCB, 0x13), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).run(0xCB, 0x14), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).run(0xCB, 0x15), test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x16) + .run(0xCB, 0x16) ); } @@ -557,19 +516,17 @@ public void testRRC_R() { Function, Integer> operator = context -> ((context.first >>> 1) & 0x7F) | (((context.first & 1) << 7)); - FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0F), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x08), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x09), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0A), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0B), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0C), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x0D), + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).run(0xCB, 0x0F), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).run(0xCB, 0x08), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).run(0xCB, 0x09), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).run(0xCB, 0x0A), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).run(0xCB, 0x0B), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).run(0xCB, 0x0C), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).run(0xCB, 0x0D), test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x0E) + .run(0xCB, 0x0E) ); } @@ -594,19 +551,17 @@ public void testRR_R() { Function, Integer> operator = context -> ((context.first >> 1) & 0x7F) | ((context.flags & FLAG_C) << 7); - FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1F), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x18), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x19), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1A), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1B), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1C), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x1D), + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).run(0xCB, 0x1F), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).run(0xCB, 0x18), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).run(0xCB, 0x19), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).run(0xCB, 0x1A), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).run(0xCB, 0x1B), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).run(0xCB, 0x1C), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).run(0xCB, 0x1D), test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x1E) + .run(0xCB, 0x1E) ); } @@ -630,19 +585,17 @@ public void testSLA_R() { .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> (context.first << 1) & 0xFE; - FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x27), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x20), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x21), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x22), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x23), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x24), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x25), + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).run(0xCB, 0x27), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).run(0xCB, 0x20), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).run(0xCB, 0x21), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).run(0xCB, 0x22), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).run(0xCB, 0x23), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).run(0xCB, 0x24), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).run(0xCB, 0x25), test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x26) + .run(0xCB, 0x26) ); } @@ -665,19 +618,17 @@ public void testSRA_R() { .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> (context.first >> 1) & 0xFF | (context.first & 0x80); - FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2F), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x28), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x29), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2A), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2B), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2C), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x2D), + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).run(0xCB, 0x2F), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).run(0xCB, 0x28), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).run(0xCB, 0x29), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).run(0xCB, 0x2A), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).run(0xCB, 0x2B), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).run(0xCB, 0x2C), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).run(0xCB, 0x2D), test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x2E) + .run(0xCB, 0x2E) ); } @@ -701,19 +652,17 @@ public void testSRL_R() { .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> (context.first >>> 1) & 0x7F; - FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandLSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3F), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x38), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x39), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3A), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3B), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3C), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x3D), + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).run(0xCB, 0x3F), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).run(0xCB, 0x38), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).run(0xCB, 0x39), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).run(0xCB, 0x3A), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).run(0xCB, 0x3B), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).run(0xCB, 0x3C), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).run(0xCB, 0x3D), test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x3E) + .run(0xCB, 0x3E) ); } @@ -722,9 +671,6 @@ public void testSRL_REF_II_N() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .verifyByte(context -> get8MSBplus8LSB(context.first), context -> ((context.second & 0xFF) >>> 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().carryIsFirstOperandLSB().sign().zero().halfCarryIsReset().parity() - .subtractionIsReset()) .setFlags(0xFF) .keepCurrentInjectorsAfterRun(); @@ -742,19 +688,17 @@ public void testSLL_R() { .clearOtherVerifiersAfterRun(); Function, Integer> operator = context -> (context.first << 1) & 0xFF | 1; - FlagsCheckImpl flags = new FlagsCheckImpl() - .carryIsFirstOperandMSB().sign().zero().parity().halfCarryIsReset().subtractionIsReset(); Generator.forSome8bitUnary( - test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x37), - test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x30), - test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x31), - test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x32), - test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x33), - test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x34), - test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).verifyFlagsOfLastOp(flags).run(0xCB, 0x35), + test.firstIsRegister(REG_A).verifyRegister(REG_A, operator).run(0xCB, 0x37), + test.firstIsRegister(REG_B).verifyRegister(REG_B, operator).run(0xCB, 0x30), + test.firstIsRegister(REG_C).verifyRegister(REG_C, operator).run(0xCB, 0x31), + test.firstIsRegister(REG_D).verifyRegister(REG_D, operator).run(0xCB, 0x32), + test.firstIsRegister(REG_E).verifyRegister(REG_E, operator).run(0xCB, 0x33), + test.firstIsRegister(REG_H).verifyRegister(REG_H, operator).run(0xCB, 0x34), + test.firstIsRegister(REG_L).verifyRegister(REG_L, operator).run(0xCB, 0x35), test.setPair(REG_PAIR_HL, 0x301).firstIsMemoryByteAt(0x301).verifyByte(0x301, operator) - .verifyFlagsOfLastOp(flags).run(0xCB, 0x36) + .run(0xCB, 0x36) ); } @@ -765,9 +709,6 @@ public void testSLL_REF_II_N() { .verifyByte( context -> get8MSBplus8LSB(context.first), context -> ((context.second << 1) | 1) & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().carryIsFirstOperandMSB().sign().zero().halfCarryIsReset().parity() - .subtractionIsReset()) .setFlags(0xFF) .keepCurrentInjectorsAfterRun(); @@ -784,8 +725,7 @@ public void testRLD() { .firstIsPair(REG_PAIR_HL) .first8LSBisRegister(REG_A) .verifyByte(context -> context.first, context -> (context.second << 4) & 0xF0 | context.first & 0x0F) - .verifyRegister(REG_A, context -> (context.first & 0xF0) | (context.second >>> 4) & 0x0F) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().parity().subtractionIsReset().halfCarryIsReset()); + .verifyRegister(REG_A, context -> (context.first & 0xF0) | (context.second >>> 4) & 0x0F); Generator.forSome16bitBinary( test.run(0xED, 0x6F) @@ -799,8 +739,7 @@ public void testRRD() { .firstIsPair(REG_PAIR_HL) .first8LSBisRegister(REG_A) .verifyByte(context -> context.first, context -> (context.first << 4) & 0xF0 | (context.second >>> 4) & 0x0F) - .verifyRegister(REG_A, context -> (context.first & 0xF0) | context.second & 0x0F) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().parity().subtractionIsReset().halfCarryIsReset()); + .verifyRegister(REG_A, context -> (context.first & 0xF0) | context.second & 0x0F); Generator.forSome16bitBinary( test.run(0xED, 0x67) @@ -812,9 +751,7 @@ public void testAND_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xDD, 0xA4) @@ -826,9 +763,7 @@ public void testAND_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBisRegister(REG_A) .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xDD, 0xA5) @@ -840,9 +775,7 @@ public void testAND_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xFD, 0xA4) @@ -854,9 +787,7 @@ public void testAND_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBisRegister(REG_A) .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsSet().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) & (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xFD, 0xA5) @@ -869,9 +800,7 @@ public void testXOR_IXH() { .setFlags(0xFF) .first8LSBisRegister(REG_A) .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xDD, 0xAC) @@ -884,9 +813,7 @@ public void testXOR_IXL() { .setFlags(0xFF) .first8MSBisRegister(REG_A) .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xDD, 0xAD) @@ -899,9 +826,7 @@ public void testXOR_IYH() { .setFlags(0xFF) .first8LSBisRegister(REG_A) .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xFD, 0xAC) @@ -914,9 +839,7 @@ public void testXOR_IYL() { .setFlags(0xFF) .first8MSBisRegister(REG_A) .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) ^ (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xFD, 0xAD) @@ -929,9 +852,7 @@ public void testOR_IXH() { .setFlags(0xFF) .first8LSBisRegister(REG_A) .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xDD, 0xB4) @@ -944,9 +865,7 @@ public void testOR_IXL() { .setFlags(0xFF) .first8MSBisRegister(REG_A) .firstIsIX() - .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xDD, 0xB5) @@ -959,9 +878,7 @@ public void testOR_IYH() { .setFlags(0xFF) .first8LSBisRegister(REG_A) .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xFD, 0xB4) @@ -974,9 +891,7 @@ public void testOR_IYL() { .setFlags(0xFF) .first8MSBisRegister(REG_A) .firstIsIY() - .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()); + .verifyRegister(REG_A, context -> (context.first & 0xFF) | (context.first >>> 8)); Generator.forSome16bitUnary( test.run(0xFD, 0xB5) @@ -988,16 +903,7 @@ public void testCP_IXH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .firstIsIX() - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond(c -> c.first >>> 8) - .sign().zero() - .borrow() - .halfBorrow() - .overflowSub() - .subtractionIsSet(), - context -> (context.first & 0xFF) + (((~(context.first >>> 8)) + 1) & 0xFF)); + .verifyRegister(REG_A, context -> context.first & 0xFF); Generator.forSome16bitUnary( test.run(0xDD, 0xBC) @@ -1009,16 +915,7 @@ public void testCP_IYH() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .firstIsIY() - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond(c -> c.first >>> 8) - .sign().zero() - .borrow() - .halfBorrow() - .overflowSub() - .subtractionIsSet(), - context -> (context.first & 0xFF) + (((~(context.first >>> 8)) + 1) & 0xFF)); + .verifyRegister(REG_A, context -> context.first & 0xFF); Generator.forSome16bitUnary( test.run(0xFD, 0xBC) @@ -1030,14 +927,7 @@ public void testCP_IXL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIX() - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl() - .sign().zero() - .borrow() - .halfBorrow() - .overflowSub() - .subtractionIsSet(), - context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); + .verifyRegister(REG_A, context -> context.first & 0xFF); Generator.forSome16bitBinary( test.run(0xDD, 0xBD) @@ -1049,17 +939,7 @@ public void testCP_IYL() { IntegerTestBuilder test = new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8LSBisRegister(REG_A) .secondIsIY() - .verifyRegister(REG_A, context -> context.first & 0xFF) - .verifyFlags(new FlagsCheckImpl() - .setFirst8LSB() - .setSecond8LSB() - .sign() - .zero() - .borrow() - .halfBorrow() - .overflowSub() - .subtractionIsSet(), - context -> (context.first & 0xFF) + (((~(context.second & 0xFF)) + 1) & 0xFF)); + .verifyRegister(REG_A, context -> context.first & 0xFF); Generator.forSome16bitBinary( test.run(0xFD, 0xBD) @@ -1071,8 +951,6 @@ private ByteTestBuilder getLogicTestBuilder(Function, Intege .setFlags(0xFF) .firstIsRegister(REG_A) .verifyRegister(REG_A, operator) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsReset().subtractionIsReset().halfCarryIsReset().parity().sign().zero()) .keepCurrentInjectorsAfterRun(); } @@ -1086,30 +964,20 @@ private IntegerTestBuilder prepareCPxTest(Function, Integ .verifyPair(REG_PAIR_HL, hlOperation) .verifyPair(REG_PAIR_BC, context -> ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) - ) - .verifyFlags(new FlagsCheckImpl() - .sign().zero().subtractionIsSet().halfBorrow() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> - ((context.getRegister(REG_B) << 8 | context.getRegister(REG_C)) - 1) != 0 - ), context -> context.registers.get(REG_A) - (context.second & 0xFF)); + ); } private IntegerTestBuilder prepareLogicIXYtest(Function, Integer> operation) { return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .first8LSBisRegister(REG_A) - .verifyRegister(REG_A, operation) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .sign().zero().parity().carryIsReset().halfCarryIsReset().subtractionIsReset()); + .verifyRegister(REG_A, operation); } private IntegerTestBuilder prepareIIRotationMSBTest(Function, Integer> operator) { return new IntegerTestBuilder(cpuRunnerImpl, cpuVerifierImpl) .first8MSBplus8LSBisMemoryAddressAndSecondIsMemoryByte() .verifyByte(context -> get8MSBplus8LSB(context.first), operator) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().carryIsFirstOperandMSB().sign().zero().halfCarryIsReset().parity() - .subtractionIsReset()) .setFlags(FLAG_H | FLAG_N); } @@ -1117,9 +985,6 @@ private IntegerTestBuilder prepareIIRotationLSBTest(Function get8MSBplus8LSB(context.first), operator) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .switchFirstAndSecond().carryIsFirstOperandLSB().sign().zero().halfCarryIsReset().parity() - .subtractionIsReset()) .setFlags(FLAG_H | FLAG_N); } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java index 3b92fcd5c..3ba8ac1bb 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/TransferTest.java @@ -20,7 +20,6 @@ import net.emustudio.cpu.testsuite.Generator; import net.emustudio.plugins.cpu.zilogZ80.suite.ByteTestBuilder; -import net.emustudio.plugins.cpu.zilogZ80.suite.FlagsCheckImpl; import net.emustudio.plugins.cpu.zilogZ80.suite.IntegerTestBuilder; import net.emustudio.plugins.cpu.zilogZ80.suite.Utils; import org.junit.Test; @@ -214,10 +213,7 @@ public void testLD_A_I() { .firstIsRegister(REG_A) .secondIsRegisterI() .setFlags(FLAG_H | FLAG_N) - .verifyRegister(REG_A, context -> context.second & 0xFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> cpuRunnerImpl.getIFF(1)) - ); + .verifyRegister(REG_A, context -> context.second & 0xFF); Generator.forSome8bitBinary( test.run(0xED, 0x57) @@ -230,10 +226,7 @@ public void testLD_A_R() { .firstIsRegister(REG_A) .secondIsRegisterR() .setFlags(FLAG_H | FLAG_N) - .verifyRegister(REG_A, context -> (context.second & 0x80) | ((context.second & 0x7F) + 2) & 0x7F) - .verifyFlagsOfLastOp(new FlagsCheckImpl().sign().zero().halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> cpuRunnerImpl.getIFF(1)) - ); + .verifyRegister(REG_A, context -> (context.second & 0x80) | ((context.second & 0x7F) + 2) & 0x7F); Generator.forSome8bitBinary( test.run(0xED, 0x5F) @@ -478,14 +471,7 @@ public void testLDI() { .verifyByte(context -> context.first, context -> context.first & 0xFF) .verifyPair(REG_PAIR_DE, context -> (context.first + 1) & 0xFFFF) .verifyPair(REG_PAIR_HL, context -> (context.second + 1) & 0xFFFF) - .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsPreserved() - .zeroIsPreserved() - .signIsPreserved() - .halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) - ); + .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF); Generator.forSome16bitBinary(2, 2, test.run(0xED, 0xA0) @@ -505,13 +491,7 @@ public void testLDIR() { .verifyPair(REG_PAIR_HL, context -> (context.second + 1) & 0xFFFF) .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) .verifyR(context -> 2) - .verifyFlagsOfLastOp(new FlagsCheckImpl() - .carryIsPreserved() - .zeroIsPreserved() - .signIsPreserved() - .halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) - ).verifyPC(context -> { + .verifyPC(context -> { if (((context.first - 1) & 0xFFFF) != 0) { return context.PC; } @@ -534,10 +514,7 @@ public void testLDD() { .verifyByte(context -> context.first, context -> context.first & 0xFF) .verifyPair(REG_PAIR_DE, context -> (context.first - 1) & 0xFFFF) .verifyPair(REG_PAIR_HL, context -> (context.second - 1) & 0xFFFF) - .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) - ); + .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF); Generator.forSome16bitBinary(2, 2, test.run(0xED, 0xA8) @@ -556,9 +533,7 @@ public void testLDDR() { .verifyPair(REG_PAIR_DE, context -> (context.first - 1) & 0xFFFF) .verifyPair(REG_PAIR_HL, context -> (context.second - 1) & 0xFFFF) .verifyPair(REG_PAIR_BC, context -> (context.first - 1) & 0xFFFF) - .verifyFlagsOfLastOp(new FlagsCheckImpl().halfCarryIsReset().subtractionIsReset() - .expectFlagOnlyWhen(FLAG_PV, (context, result) -> ((context.first - 1) & 0xFFFF) != 0) - ).verifyPC(context -> { + .verifyPC(context -> { if (((context.first - 1) & 0xFFFF) != 0) { return context.PC; } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/Z80Tests.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/Z80Tests.java new file mode 100644 index 000000000..1e1dab587 --- /dev/null +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/Z80Tests.java @@ -0,0 +1,421 @@ +package net.emustudio.plugins.cpu.zilogZ80; + +import net.emustudio.plugins.cpu.zilogZ80.suite.ByteTestBuilder; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.*; +import static net.emustudio.plugins.cpu.zilogZ80.Z80Tests.InstrTest.mk; +import static net.emustudio.plugins.cpu.zilogZ80.suite.Utils.crc16; +import static org.junit.Assert.assertEquals; + +// inspired by: +// http://www.z80.info/decoding.htm +// https://github.com/raxoft/z80test +public class Z80Tests extends InstructionsTest { + + private final static int[] TEST_VALUES = new int[]{ + 0, 1, 0x7F, 0x80, 0x81, 0xFF, 0x28, 0x88 + }; + + static class InstrTest { + int bc = 0xBBCC; + int de = 0xDDEE; + int hl = 0x4411; + int ix = 0xDD88; + int iy = 0xFD77; + int sp = 0xC000; + int hl_mem = 0; + int instr_y_from = 0; + int instr_y_to = 0; + int instr_z_from = 0; + int instr_z_to = 0; + int instr_p_from = 0; + int instr_p_to = 0; + + final int opcode; + final int crc; + + InstrTest(int opcode, int crc) { + this.opcode = opcode; + this.crc = crc; + } + + InstrTest y(int from, int to) { + instr_y_from = from; + instr_y_to = to; + return this; + } + + InstrTest z(int from, int to) { + instr_z_from = from; + instr_z_to = to; + return this; + } + + InstrTest all_p() { + instr_p_from = 0; + instr_p_to = 3; + return this; + } + + InstrTest hl_mem(int value) { + hl_mem = value; + return this; + } + + InstrTest hl_to_ix() { + ix = hl; + return this; + } + + InstrTest hl_to_iy() { + iy = hl; + return this; + } + + InstrTest hl_to_bc() { + bc = hl; + return this; + } + + InstrTest hl_to_de() { + de = hl; + return this; + } + + static InstrTest mk(int opcode, int crc) { + return new InstrTest(opcode, crc); + } + + @Override + public String toString() { + return "opcode=" + Integer.toHexString(opcode); + } + } + + private final static List testData = Arrays.asList( + mk(0x00, 0x4f43b66a), // NOP + mk(0x08, 0x71be4764), // EX AF, AF' + mk(0x0210, 0xfcace674), // DJNZ 2 + mk(0x0218, 0xad876a20), // JR 2 + mk(0x0220, 0x77bd64ba).y(4, 7), // JR cc[y-4], 2 + mk(0x441101, 0xe931407a).all_p().hl_mem(0x1234), // LD rp[p], 0x4020 + mk(0x09, 0x71104d77).all_p(), // ADD HL, rp[p] + mk(0x02, 0x81f2817c).hl_to_bc(), // LD (BC), A + mk(0x12, 0xdb06c840).hl_to_de(), // LD (DE), A + mk(0x0A, 0xf9d52bc1).hl_to_bc().hl_mem(0x1234), // LD A, (BC) + mk(0x1A, 0xa32162fd).hl_to_de().hl_mem(0x1234), // LD A, (DE) + mk(0x441122, 0x9f8737bc), // LD (0x4411), HL + mk(0x441132, 0xd4053ee8), // LD (0x4411), A + mk(0x44112A, 0xc28558a5).hl_mem(0x1234), // LD HL, (0x4411) + mk(0x44113A, 0x7c7f7e07), // LD A, (0x4411) + mk(0x03, 0xc597e625).all_p(), // INC rp[p] + mk(0x0B, 0x7660db66).all_p(), // DEC rp[p] + mk(0x04, 0xab3517e).y(0, 7), // INC r[y] + mk(0x05, 0x499dc529).y(0, 7), // DEC r[y] + mk(0x2006, 0xcdd91784).y(0, 7), // LD r[y], 0x20 + mk(0x07, 0x244d0ca2), // RLCA + mk(0x0F, 0xa9a239b7), // RRCA + mk(0x17, 0xf6e55742), // RLA + mk(0x1F, 0x811179f2), // RRA + mk(0x27, 0x27ae1abd), // DAA + mk(0x2F, 0x5148ce04), // CPL + mk(0x37, 0x49b08399), // SCF + mk(0x3F, 0x67dcdcb), // CCF + mk(0x40, 0xcb9bb6eb).y(0, 5).z(0, 7), // LD r[y], r[z] + mk(0x40, 0x38184ac8).y(7, 7).z(0, 7), // LD r[y], r[z] + mk(0x40, 0x6ca8fc02).y(0, 7).z(0, 5), // LD r[y], r[z] + mk(0x40, 0x8dcdede9).y(0, 7).z(7, 7), // LD r[y], r[z] + mk(0x80, 0x75a3c6e0).hl_mem(0x20).y(0, 7).z(0, 7), // ALU[y] r[z] + mk(0xC0, 0x750da6d8).y(0, 7), // RET cc[y] + mk(0xC1, 0xc425c2f2).all_p(), // POP rp2[p] + mk(0xC9, 0x44fe3276), // RET + mk(0xD9, 0x4c7da35d), // EXX + mk(0xE9, 0xb898651b), // JP (HL) + mk(0xF9, 0x21a9c873), // LD SP, HL + mk(0x4020C2, 0xc8433837).y(0, 7), // JP cc[y], 0x2040 + mk(0x4020C3, 0x9f7eba7c), // JP 0x2040 + mk(0xE3, 0x57421926), // EX (SP), HL + mk(0xEB, 0x295b7243), // EX DE, HL + mk(0xF3, 0x4f43b66a), // DI + mk(0xFB, 0x4f43b66a), // EI + mk(0x20D3, 0x34fd8b43), // OUT (0x20), A + mk(0x20DB, 0x4e98bcbb), // IN A, (0x20) + mk(0x4020C4, 0x9a1c9e4a).y(0, 7), // CALL cc[y], 0x2040 + mk(0xC5, 0xca10f000).all_p(), // PUSH rp2[p] + mk(0x4020CD, 0xdbc967ee), // CALL 0x2040 + mk(0x20C6, 0x83bda0dc).y(0, 7), // ALU[y], 0x20 + mk(0xC7, 0x8f156d7d).y(0, 7), // RST y*8 + + mk(0x00CB, 0x698143a3).y(0, 7).z(0, 7), // ROT[y] r[z] + mk(0x40CB, 0xeab2f4b0).y(0, 7).z(0, 7), // BIT y, r[z] + mk(0x80CB, 0x55ef5e5f).y(0, 7).z(0, 7), // RES y, r[z] + mk(0xC0CB, 0x8b940665).y(0, 7).z(0, 7), // SET y, r[z] + + mk(0x40ED, 0x750b0ff6).y(0, 7), // IN r[y], (C) + mk(0x41ED, 0x3a3319c8).y(0, 7), // OUT (C), r[y] + mk(0x42ED, 0x8594fc6f).all_p(), // SBC HL, rp[p] + mk(0x4AED, 0x799953a7).all_p(), // ADC HL, rp[p] + mk(0x204043ED, 0xeb62b193).all_p(), // LD (0x4020), rp[p] + mk(0x20404BED, 0xcaf555af).all_p(), // LD rp[p], (0x4020) + mk(0x44ED, 0x98e9e83f), // NEG + mk(0x45ED, 0x44fe3276), // RETN + mk(0x45ED, 0xde97cc1e).y(2, 7), // RETN + mk(0x4DED, 0x44fe3276), // RETI + mk(0x46ED, 0x3a3319c8).y(0, 7), // IM im[y] + mk(0x47ED, 0x34fd8b43), // LD I, A + mk(0x4FED, 0x34fd8b43), // LD R, A + mk(0x57ED, 0x9f4b7aeb), // LD A, I + mk(0x5FED, 0x6a66dfb1), // LD A, R + mk(0x67ED, 0x7d7eb93d).hl_mem(0x2F), // RRD + mk(0x6FED, 0x8cd2dc37).hl_mem(0x2F), // RLD + mk(0x77ED, 0x34fd8b43), // NOP + mk(0x7FED, 0x34fd8b43), // NOP + mk(0x80ED, 0x2c7aa213).hl_mem(0x2F).y(4, 7).z(0, 3), // bli[y, z] + + mk(0x00DD, 0x34fd8b43), // NOP + mk(0x08DD, 0xa007a4d), // EX AF, AF' + mk(0x0210DD, 0xa48e8209), // DJNZ 2 + mk(0x0218DD, 0xf5a50e5d), // JR 2 + mk(0x0220DD, 0x8b9bcfc5).y(4, 7), // JR cc[y-4], 2 + mk(0x204001DD, 0x4ef83004).all_p(), // LD rpx[p], 0x4020 + mk(0x09DD, 0xc5a4aaf5).all_p(), // ADD IX, rpx[p] + mk(0x02DD, 0xfa4cbc55).hl_to_bc(), // LD (BC), A + mk(0x12DD, 0xa0b8f569).hl_to_de(), // LD (DE), A + mk(0x0ADD, 0x826b16e8).hl_to_bc().hl_mem(0x1234), // LD A, (BC) + mk(0x1ADD, 0xd89f5fd4).hl_to_de().hl_mem(0x1234), // LD A, (DE) + mk(0x441122DD, 0x6181e97c), // LD (0x4411), IX + mk(0x441132DD, 0x155dbbf6), // LD (0x4411), A + mk(0x44112ADD, 0x8584a86f).hl_mem(0x1234), // LD IX, (0x4411) + mk(0x44113ADD, 0x6d7a114b).hl_mem(0x1234), // LD A, (0x4411) + mk(0x03DD, 0x3e100736).all_p(), // INC rpx[p] + mk(0x0BDD, 0x8de73a75).all_p(), // DEC rpx[p] + mk(0x04DD, 0xfa2233d6).y(0, 7), // INC rx[y] + mk(0x05DD, 0x84ef4132).y(0, 7), // DEC rx[y] + mk(0x2006DD, 0x2db8dd4b).y(0, 5), // LD rx[y], N + mk(0x203EDD, 0x11251bb8), // LD a, N + mk(0x200036DD, 0x3fd402c).hl_to_ix().hl_mem(0x3F), // LD (IX+0), 0x20 + mk(0x07DD, 0x5ff3318b), // RLCA + mk(0x0FDD, 0xd21c049e), // RRCA + mk(0x17DD, 0x8d5b6a6b), // RLA + mk(0x1FDD, 0xfaaf44db), // RRA + mk(0x27DD, 0x5c102794), // DAA + mk(0x2FDD, 0x2af6f32d), // CPL + mk(0x37DD, 0x320ebeb0), // SCF + mk(0x3FDD, 0x7dc3f0e2), // CCF + mk(0x40DD, 0xb424694a).y(0, 5).z(0, 5), // LD rx[y], rx[z] + mk(0x40DD, 0x6e4e6fc).y(7, 7).z(0, 5), // LD rx[y], rx[z] + mk(0x40DD, 0xb8737a6b).y(0, 5).z(7, 7), // LD rx[y], rx[z] + mk(0x4000DD, 0x67dc5aac).hl_to_ix().hl_mem(0x3F).y(6, 6).z(0, 5), // LD (IX+0), rx[z] + mk(0x4000DD, 0x55d7a4a).hl_to_ix().hl_mem(0x3F).y(6, 6).z(7, 7), // LD (IX+0), A + mk(0x4000DD, 0x67dc5aac).hl_to_ix().hl_mem(0x3F).y(0, 5).z(6, 6), // LD rx[y], (IX+0) + mk(0x4000DD, 0x55d7a4a).hl_to_ix().hl_mem(0x3F).y(7, 7).z(6, 6), // LD A, (IX+0) + mk(0x80DD, 0xa660387e).hl_mem(0x20).y(0, 7).z(0, 5), // ALU[y], rx[z] + mk(0x80DD, 0x3931e915).hl_mem(0x20).y(0, 7).z(7, 7), // ALU[y], A + mk(0x8000DD, 0xa4e7c045).hl_to_ix().hl_mem(0x20).y(0, 7).z(6, 6), // ALU[y], (IX+0) + mk(0xC0DD, 0xa4c0ec82).y(0, 7), // RET cc[y] + mk(0xC1DD, 0x1b5c411e).all_p(), // POP rp2x[p] + mk(0xC9DD, 0x44fe3276), // RET + mk(0xD9DD, 0x37c39e74), // EXX + mk(0xE9DD, 0x75b2a18), // JP (IX) + mk(0xF9DD, 0xe2b9e4bc), // LD SP, IX + mk(0x4020C2DD, 0x6740e7e4).y(0, 7), // JP cc[y], 0x2040 + mk(0x4020C3DD, 0x9f7eba7c), // JP 0x2040 + mk(0xE3DD, 0xce792a84), // EX (SP), IX + mk(0xEBDD, 0x52e54f6a), // EX DE, HL + mk(0xF3DD, 0x34fd8b43), // DI + mk(0xFBDD, 0x34fd8b43), // EI + mk(0x20D3DD, 0x6cdfef3e), // OUT (0x20), A + mk(0x20DBDD, 0x16bad8c6), // IN A, (0x20) + mk(0x4020C4DD, 0x351f4199).y(0, 7), // CALL cc[y], 0x2040 + mk(0xC5DD, 0x15a7524b).all_p(), // PUSH rp2x[p] + mk(0x4020CDDD, 0xdbc967ee), // CALL 0x2040 + mk(0x20C6DD, 0xad3982c0).y(0, 7), // ALU[y], 0x20 + mk(0xC7DD, 0x8f156d7d).y(0, 7), // RST y*8 + + mk(0x00FD, 0x34fd8b43), // NOP + mk(0x08FD, 0xa007a4d), // EX AF, AF' + mk(0x0210FD, 0xa48e8209), // DJNZ 2 + mk(0x0218FD, 0xf5a50e5d), // JR 2 + mk(0x0220FD, 0x8b9bcfc5).y(4, 7), // JR cc[y-4], 2 + mk(0x204001FD, 0x4ef83004).all_p(), // LD rpy[p], 0x4020 + mk(0x09FD, 0x3e95b0dd).all_p(), // ADD IY, rpy[p] + mk(0x02FD, 0xfa4cbc55).hl_to_bc().hl_mem(0x20), // LD (BC), A + mk(0x12FD, 0xa0b8f569).hl_to_de().hl_mem(0x20), // LD (DE), A + mk(0x0AFD, 0x16ad4a47).hl_to_bc().hl_mem(0x20), // LD A, (BC) + mk(0x1AFD, 0x4c59037b).hl_to_de().hl_mem(0x20), // LD A, (DE) + mk(0x441122FD, 0x9c46b95a), // LD (0x4411), IY + mk(0x441132FD, 0x155dbbf6), // LD (0x4411), A + mk(0x44112AFD, 0xc8da9877).hl_mem(0x1234), // LD IY, (0x4411) + mk(0x44113AFD, 0x6d7a114b).hl_mem(0x1234), // LD A, (0x4411) + mk(0x03FD, 0x903b0268).all_p(), // INC rpy[p] + mk(0x0BFD, 0x23cc3f2b).all_p(), // DEC rpy[p] + mk(0x04FD, 0xb685baf).y(0, 7), // INC ry[y] + mk(0x05FD, 0xc4ef58b5).y(0, 7), // DEC ry[y] + mk(0x2006FD, 0x2db8dd4b).y(0, 5), // LD ry[y], N + mk(0x203EFD, 0x11251bb8), // LD a, N + mk(0x200036FD, 0x92b41b2d).hl_to_iy().hl_mem(0x3F), // LD (IY+0), 0x20 + mk(0x07FD, 0x5ff3318b), // RLCA + mk(0x0FFD, 0xd21c049e), // RRCA + mk(0x17FD, 0x8d5b6a6b), // RLA + mk(0x1FFD, 0xfaaf44db), // RRA + mk(0x27FD, 0x5c102794), // DAA + mk(0x2FFD, 0x2af6f32d), // CPL + mk(0x37FD, 0x320ebeb0), // SCF + mk(0x3FFD, 0x7dc3f0e2), // CCF + mk(0x40FD, 0x39c76988).y(0, 5).z(0, 5), // LD ry[y], ry[z] + mk(0x40FD, 0xbc8753bd).y(7, 7).z(0, 5), // LD ry[y], ry[z] + mk(0x40FD, 0x474fdbe8).y(0, 5).z(7, 7), // LD ry[y], ry[z] + mk(0x4000FD, 0x25039149).hl_to_iy().hl_mem(0x3F).y(6, 6).z(0, 5), // LD (IY+0), ry[z] + mk(0x4000FD, 0x9414214b).hl_to_iy().hl_mem(0x3F).y(6, 6).z(7, 7), // LD (IY+0), A + mk(0x4000FD, 0x25039149).hl_to_iy().hl_mem(0x3F).y(0, 5).z(6, 6), // LD ry[y], (IY+0) + mk(0x4000FD, 0x9414214b).hl_to_iy().hl_mem(0x3F).y(7, 7).z(6, 6), // LD A, (IY+0) + mk(0x80FD, 0x808ba661).hl_mem(0x20).y(0, 7).z(0, 5), // ALU[y], ry[z] + mk(0x80FD, 0x3931e915).hl_mem(0x20).y(0, 7).z(7, 7), // ALU[y], A + mk(0x8000FD, 0x4fb2a057).hl_to_iy().hl_mem(0x20).y(0, 7).z(6, 6), // ALU[y], (IY+0) + mk(0xC0FD, 0xa4c0ec82).y(0, 7), // RET cc[y] + mk(0xC1FD, 0x38906d13).all_p(), // POP rp2y[p] + mk(0xC9FD, 0x44fe3276), // RET + mk(0xD9FD, 0x37c39e74), // EXX + mk(0xE9FD, 0x6c06b1fa), // JP (IY) + mk(0xF9FD, 0xa09c9fdb), // LD SP, IY + mk(0x4020C2FD, 0x6740e7e4).y(0, 7), // JP cc[y], 0x2040 + mk(0x4020C3FD, 0x9f7eba7c), // JP 0x2040 + mk(0xE3FD, 0xc20e919e), // EX (SP), IY + mk(0xEBFD, 0x52e54f6a), // EX DE, HL + mk(0xF3FD, 0x34fd8b43), // DI + mk(0xFBFD, 0x34fd8b43), // EI + mk(0x20D3FD, 0x6cdfef3e), // OUT (0x20), A + mk(0x20DBFD, 0x16bad8c6), // IN A, (0x20) + mk(0x4020C4FD, 0x351f4199).y(0, 7), // CALL cc[y], 0x2040 + mk(0xC5FD, 0x15a7524b).all_p(), // PUSH rp2y[p] + mk(0x4020CDFD, 0xdbc967ee), // CALL 0x2040 + mk(0x20C6FD, 0xad3982c0).y(0, 7), // ALU[y], 0x20 + mk(0xC7FD, 0x8f156d7d).y(0, 7), // RST y*8 + + mk(0x0000CBDD, 0x4074cb3).hl_to_ix().hl_mem(0x20).y(0, 7).z(0, 5), // LD r[z], rot[y] (IX+0) + mk(0x0000CBDD, 0xb5e1b6e5).hl_to_ix().hl_mem(0x20).y(0, 7).z(7, 7), // LD r[z], rot[y] (IX+0) + mk(0x0600CBDD, 0xdd8ba49f).hl_to_ix().hl_mem(0x20).y(0, 7), // rot[y] (IX+0) + mk(0x4000CBDD, 0xefa606ad).hl_to_ix().hl_mem(0xAA).y(0, 7).z(0, 7), // BIT y, (IX+0) + mk(0x8000CBDD, 0x9999c088).hl_to_ix().hl_mem(0xAA).y(0, 7).z(0, 5), // LD r[z], RES y, (IX+0) + mk(0x8700CBDD, 0xbcfac0c8).hl_to_ix().hl_mem(0xAA).y(0, 7), // LD A, RES y, (IX+0) + mk(0x8600CBDD, 0x9135f49b).hl_to_ix().hl_mem(0xAA).y(0, 7), // RES y, (IX+0) + mk(0xC000CBDD, 0x891c1517).hl_to_ix().y(0, 7).z(0, 5), // LD r[z], SET y, (IX+0) + mk(0xC600CBDD, 0x82698d7e).hl_to_ix().y(0, 7), // SET y, (IX+d) + mk(0xC700CBDD, 0x47fd2fab).hl_to_ix().y(0, 7), // LD A, SET y, (IX+0) + + mk(0x0000CBFD, 0x4118ee7).hl_to_iy().hl_mem(0x20).y(0, 7).z(0, 5), // LD r[z], rot[y] (IX+0) + mk(0x0000CBFD, 0x5eb4d6f7).hl_to_iy().hl_mem(0x20).y(0, 7).z(7, 7), // LD r[z], rot[y] (IX+0) + mk(0x0600CBFD, 0x36dec48d).hl_to_iy().hl_mem(0x20).y(0, 7), // rot[y] (IX+0) + mk(0x4000CBFD, 0x75efe92).hl_to_iy().hl_mem(0xAA).y(0, 7).z(0, 7), // BIT y, (IX+0) + mk(0x8000CBFD, 0x92e9f47d).hl_to_iy().hl_mem(0xAA).y(0, 7).z(0, 5), // LD r[z], RES y, (IX+0) + mk(0x8700CBFD, 0x57afa0da).hl_to_iy().hl_mem(0xAA).y(0, 7), // LD A, RES y, (IX+0) + mk(0x8600CBFD, 0x7a609489).hl_to_iy().hl_mem(0xAA).y(0, 7), // RES y, (IX+0) + mk(0xC000CBFD, 0x826c21e2).hl_to_iy().y(0, 7).z(0, 5), // LD r[z], SET y, (IX+0) + mk(0xC600CBFD, 0x693ced6c).hl_to_iy().y(0, 7), // SET y, (IX+d) + mk(0xC700CBFD, 0xaca84fb9).hl_to_iy().y(0, 7) // LD A, SET y, (IX+0) + ); + + @Test + public void testInstructions() { + testData.forEach(this::testInstruction); + } + + public void testInstruction(InstrTest instrTest) { + // reg A is repeated with TEST_VALUES + // flags are flipped from 0 and 0xFF + final AtomicInteger crc = new AtomicInteger(); + for (int a : TEST_VALUES) { + ByteTestBuilder test = new ByteTestBuilder(cpuRunnerImpl, cpuVerifierImpl) + .firstIsFlags() + .setRegister(REG_A, a) + .setPair(REG_PAIR_BC, instrTest.bc) + .setPair(REG_PAIR_DE, instrTest.de) + .setPair(REG_PAIR_HL, instrTest.hl) + .setIX(instrTest.ix) + .setIY(instrTest.iy) + .setSP(instrTest.sp) + .setMemoryByteAt(instrTest.hl, (byte) instrTest.hl_mem) + .verify(context -> crc.set(updateCrc(crc.get(), instrTest.hl))) + .keepCurrentInjectorsAfterRun() + .clearOtherVerifiersAfterRun(); // keeps current ones + + int y_from = instrTest.instr_y_from; + int y_to = instrTest.instr_y_to; + int y_mask = 7; + if (instrTest.instr_p_to > 0) { + y_from = instrTest.instr_p_from << 1; + y_to = instrTest.instr_p_to << 1; + y_mask = 6; + } + + int[] opcodes = new int[5]; + int opcode = instrTest.opcode; + int lastOpcodeIndex = 0; + while (opcode != 0) { + opcodes[lastOpcodeIndex++] = opcode & 0xFF; + opcode = opcode >>> 8; + } + if (lastOpcodeIndex > 0) { + lastOpcodeIndex--; + } + + for (int y = y_from; y <= y_to; y++) { + for (int z = instrTest.instr_z_from; z <= instrTest.instr_z_to; z++) { + int yreal = y & y_mask; + if (yreal > 0) { + opcodes[lastOpcodeIndex] = (opcodes[lastOpcodeIndex] & 0xC7) | ((yreal & 7) << 3); + } + if (z > 0) { + opcodes[lastOpcodeIndex] = (opcodes[lastOpcodeIndex] & 0xF8) | (z & 7); + } + test.run(opcodes[0], opcodes[1], opcodes[2], opcodes[3], opcodes[4]).accept((byte) 0, (byte) 0); // flags 00 + test.run(opcodes[0], opcodes[1], opcodes[2], opcodes[3], opcodes[4]).accept((byte) 0xFF, (byte) 0); // flags 0xFF + } + } + } + //System.out.println("0x" + Integer.toHexString(cpu.getEngine().crc)); + assertEquals(instrTest.crc, crc.get()); + } + + public int updateCrc(int crc, int rHL) { + EmulatorEngine engine = cpu.getEngine(); + + int rrAF = (engine.regs[REG_A] << 8) | engine.flags; + int rrBC = (engine.regs[REG_B] << 8) | engine.regs[REG_C]; + int rrDE = (engine.regs[REG_D] << 8) | engine.regs[REG_E]; + int rrHL = (engine.regs[REG_H] << 8) | engine.regs[REG_L]; + int rrIX = engine.IX; + int rrIY = engine.IY; + int rrPC = engine.PC; + int rrSP = engine.SP; + int rrMemHL = memory.read(rHL) & 0xFF; + + return (int) crc16(new byte[]{ + (byte) ((crc >>> 8) & 0xFF), + (byte) ((crc) & 0xFF), + (byte) ((rrAF >>> 8) & 0xFF), + (byte) ((rrAF) & 0xFF), + (byte) ((rrBC >>> 8) & 0xFF), + (byte) ((rrBC) & 0xFF), + (byte) ((rrDE >>> 8) & 0xFF), + (byte) ((rrDE) & 0xFF), + (byte) ((rrHL >>> 8) & 0xFF), + (byte) ((rrHL) & 0xFF), + (byte) ((rrIX >>> 8) & 0xFF), + (byte) ((rrIX) & 0xFF), + (byte) ((rrIY >>> 8) & 0xFF), + (byte) ((rrIY) & 0xFF), + (byte) ((rrPC >>> 8) & 0xFF), + (byte) ((rrPC) & 0xFF), + (byte) ((rrSP >>> 8) & 0xFF), + (byte) ((rrSP) & 0xFF), + (byte) ((rrMemHL) & 0xFF) + }); + } + +} diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java index 7a7625396..01ee17fce 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/ByteTestBuilder.java @@ -23,6 +23,7 @@ import net.emustudio.plugins.cpu.zilogZ80.suite.injectors.Register; import java.util.Objects; +import java.util.function.Consumer; import java.util.function.Function; public class ByteTestBuilder extends TestBuilder { @@ -31,6 +32,14 @@ public ByteTestBuilder(CpuRunnerImpl cpuRunner, CpuVerifierImpl cpuVerifier) { super(cpuRunner, cpuVerifier); } + public ByteTestBuilder firstIsFlags() { + runner.injectFirst((runner, argument) -> { + runner.resetFlags(); + runner.setFlags(argument); + }); + return this; + } + public ByteTestBuilder firstIsRegister(int register) { runner.injectFirst(new Register(register)); return this; @@ -85,6 +94,26 @@ public ByteTestBuilder setPair(int registerPair, int value) { return this; } + public ByteTestBuilder setIX(int ix) { + runner.injectFirst((runner, argument) -> runner.setIX(ix)); + return this; + } + + public ByteTestBuilder setIY(int iy) { + runner.injectFirst((runner, argument) -> runner.setIY(iy)); + return this; + } + + public ByteTestBuilder setSP(int sp) { + runner.injectFirst((runner, argument) -> runner.setSP(sp)); + return this; + } + + public ByteTestBuilder setMemoryByteAt(int address, byte value) { + runner.injectFirst((runner, argument) -> runner.setByte(address, value)); + return this; + } + public ByteTestBuilder verifyRegister(int register, Function, Integer> operation) { lastOperation = Objects.requireNonNull(operation); return verifyRegister(register); @@ -122,4 +151,9 @@ public ByteTestBuilder verifyDeviceWhenSecondIsPort(Function runner.verifyAfterTest(context -> cpuVerifier.checkDeviceValue(context.second, operation.apply(context))); return this; } + + public ByteTestBuilder verify(Consumer> verifier) { + runner.verifyAfterTest(verifier); + return this; + } } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java index bdb5cbd14..960b4a870 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/CpuRunnerImpl.java @@ -162,6 +162,10 @@ public void setIY(int iy) { cpu.getEngine().IY = iy; } + public void setSP(int sp) { + cpu.getEngine().SP = sp; + } + public void enableIFF2() { cpu.getEngine().IFF[1] = true; } diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java deleted file mode 100644 index 07f10618b..000000000 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/FlagsCheckImpl.java +++ /dev/null @@ -1,422 +0,0 @@ -/* - * This file is part of emuStudio. - * - * Copyright (C) 2006-2023 Peter Jakubčo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package net.emustudio.plugins.cpu.zilogZ80.suite; - -import net.emustudio.cpu.testsuite.FlagsCheck; -import net.emustudio.cpu.testsuite.RunnerContext; - -import java.util.Objects; -import java.util.function.Function; - -import static net.emustudio.plugins.cpu.zilogZ80.EmulatorEngine.*; - -public class FlagsCheckImpl extends FlagsCheck> { - private Function, Integer> first = context -> context.first.intValue(); - private Function, Integer> second = context -> context.second.intValue(); - - public static boolean isParity(int value) { - int numberOfOnes = 0; - - for (int i = 0; i < 8; i++) { - if ((value & 1) == 1) { - numberOfOnes++; - } - value = value >>> 1; - } - return numberOfOnes % 2 == 0; - } - - public FlagsCheckImpl setFirst(Function, Integer> first) { - this.first = Objects.requireNonNull(first); - return this; - } - - public FlagsCheckImpl setSecond(Function, Integer> second) { - this.second = Objects.requireNonNull(second); - return this; - } - - public FlagsCheckImpl setFirst8MSB() { - this.first = context -> context.first.intValue() >>> 8; - return this; - } - - public FlagsCheckImpl setFirst8LSB() { - this.first = context -> context.first.intValue() & 0xFF; - return this; - } - - public FlagsCheckImpl setSecond8MSB() { - this.second = context -> context.second.intValue() >>> 8; - return this; - } - - public FlagsCheckImpl setSecond8LSB() { - this.second = context -> context.second.intValue() & 0xFF; - return this; - } - - public FlagsCheckImpl exact(int flags) { - evaluators.add((context, result) -> { - expectedFlags = flags; - expectedNotFlags = flags ^ 0xFF; - }); - return this; - } - - public FlagsCheckImpl sign() { - evaluators.add((context, result) -> { - if ((result & 0x80) == 0x80) { - expectedFlags |= FLAG_S; - } else { - expectedNotFlags |= FLAG_S; - } - }); - return this; - } - - public FlagsCheckImpl sign16bit() { - evaluators.add((context, result) -> { - if ((result & 0x8000) == 0x8000) { - expectedFlags |= FLAG_S; - } else { - expectedNotFlags |= FLAG_S; - } - }); - return this; - } - - public FlagsCheckImpl zero() { - evaluators.add((context, result) -> { - if (result.byteValue() == 0) { - expectedFlags |= FLAG_Z; - } else { - expectedNotFlags |= FLAG_Z; - } - }); - return this; - } - - public FlagsCheckImpl zero16bit() { - evaluators.add((context, result) -> { - if ((result & 0xFFFF) == 0) { - expectedFlags |= FLAG_Z; - } else { - expectedNotFlags |= FLAG_Z; - } - }); - return this; - } - - public FlagsCheckImpl subtractionIsReset() { - evaluators.add((context, result) -> expectedNotFlags |= FLAG_N); - return this; - } - - public FlagsCheckImpl subtractionIsSet() { - evaluators.add((context, result) -> expectedFlags |= FLAG_N); - return this; - } - - public FlagsCheckImpl overflow() { - evaluators.add((context, result) -> { - int firstInt = first.apply(context) & 0xFF; - int secondInt = second.apply(context) & 0xFF; - - int carryIns = ((firstInt ^ secondInt) ^ 0x80) & 0x80; - if (carryIns != 0) { // if addend signs are the same - // overflow if the sum sign differs from the sign of either of addends - carryIns = ((result ^ firstInt) & 0x80); - } - if (carryIns != 0) { - expectedFlags |= FLAG_PV; - } else { - expectedNotFlags |= FLAG_PV; - } - }); - return this; - } - - public FlagsCheckImpl overflowSub() { - evaluators.add((context, result) -> { - int fst = first.apply(context) & 0xFF; - int snd = second.apply(context) & 0xFF; - - int sum = (fst - snd) & 0x1FF; - int flagC = (sum & 0x100) == 0x100 ? FLAG_C : 0; - int carryIns = (result & 0xFF) ^ fst ^ snd; - carryIns = (carryIns >>> 7) ^ flagC; - int flagP = (carryIns == 0) ? 0 : FLAG_PV; - - if (flagP == FLAG_PV) { - expectedFlags |= FLAG_PV; - } else { - expectedNotFlags |= FLAG_PV; - } - }); - return this; - } - - public FlagsCheckImpl overflowSubCarry() { - evaluators.add((context, result) -> { - int firstInt = first.apply(context) & 0xFF; - int inversedSecond = (~second.apply(context) & 0xFF); - - int carryIns = ((firstInt ^ inversedSecond) ^ 0x80) & 0x80; - if (carryIns != 0) { // if addend signs are the same - // overflow if the sum sign differs from the sign of either of addends - carryIns = ((result ^ firstInt) & 0x80); - } - if (carryIns != 0) { - expectedFlags |= FLAG_PV; - } else { - expectedNotFlags |= FLAG_PV; - } - }); - return this; - } - - public FlagsCheckImpl overflow16bit() { - evaluators.add((context, result) -> { - int fst = context.first.intValue(); - int snd = context.second.intValue(); - int ov = (((snd ^ fst ^ 0x8000) & (snd ^ result) & 0x8000) >>> 13); - if (ov != 0) { - expectedFlags |= FLAG_PV; - } else { - expectedNotFlags |= FLAG_PV; - } - }); - return this; - } - - public FlagsCheckImpl borrow16bit() { - evaluators.add((context, result) -> { - int fst = context.first.intValue(); - int snd = context.second.intValue(); - int ov = (((snd ^ fst) & (snd ^ result) & 0x8000) >>> 13); - if (ov != 0) { - expectedFlags |= FLAG_PV; - } else { - expectedNotFlags |= FLAG_PV; - } - }); - return this; - } - - public FlagsCheckImpl parity() { - evaluators.add((context, result) -> { - if (isParity(result & 0xFF)) { - expectedFlags |= FLAG_PV; - } else { - expectedNotFlags |= FLAG_PV; - } - }); - return this; - } - - public FlagsCheckImpl parityIsPreserved() { - evaluators.add((context, result) -> { - if ((context.flags & FLAG_PV) == FLAG_PV) { - expectedFlags |= FLAG_PV; - } else { - expectedNotFlags |= FLAG_PV; - } - }); - return this; - } - - public FlagsCheckImpl carry15() { - evaluators.add((context, result) -> { - if ((result & 0x10000) == 0x10000) { - expectedFlags |= FLAG_C; - } else { - expectedNotFlags |= FLAG_C; - } - }); - return this; - } - - public FlagsCheckImpl carry() { - evaluators.add((context, result) -> { - if ((result & 0x100) == 0x100) { - expectedFlags |= FLAG_C; - } else { - expectedNotFlags |= FLAG_C; - } - }); - return this; - } - - public FlagsCheckImpl borrow() { - evaluators.add((context, result) -> { - int fst = first.apply(context) & 0xFF; - int snd = second.apply(context) & 0xFF; - - int r = (fst - snd) & 0x1FF; - int flagC = (r & 0x100) == 0x100 ? FLAG_C : 0; - - if (flagC != 0) { - expectedFlags |= FLAG_C; - } else { - expectedNotFlags |= FLAG_C; - } - }); - return this; - } - - public FlagsCheckImpl borrowWithCarry() { - evaluators.add((context, result) -> { - int fst = first.apply(context) & 0xFF; - int snd = second.apply(context) & 0xFF; - - int r = (fst - snd - (context.flags & FLAG_C)) & 0x1FF; - int flagC = (r & 0x100) == 0x100 ? FLAG_C : 0; - if (flagC != 0) { - expectedFlags |= FLAG_C; - } else { - expectedNotFlags |= FLAG_C; - } - }); - return this; - } - - public FlagsCheckImpl carryIsFirstOperandMSB() { - evaluators.add((context, result) -> { - if ((first.apply(context) & 0x80) == 0x80) { - expectedFlags |= FLAG_C; - } else { - expectedNotFlags |= FLAG_C; - } - }); - return this; - } - - public FlagsCheckImpl carryIsFirstOperandLSB() { - evaluators.add((context, result) -> { - if ((first.apply(context) & 1) == 1) { - expectedFlags |= FLAG_C; - } else { - expectedNotFlags |= FLAG_C; - } - }); - return this; - } - - public FlagsCheckImpl carryIsReset() { - evaluators.add((context, result) -> expectedNotFlags |= FLAG_C); - return this; - } - - public FlagsCheckImpl carryIsPreserved() { - evaluators.add((context, result) -> { - if ((context.flags & FLAG_C) == FLAG_C) { - expectedFlags |= FLAG_C; - } else { - expectedNotFlags |= FLAG_C; - } - }); - return this; - } - - public FlagsCheckImpl halfCarry() { - evaluators.add((context, result) -> { - int carryIns = result ^ (first.apply(context) & 0xFF) ^ (second.apply(context) & 0xFF); - if ((carryIns & FLAG_H) == FLAG_H) { - expectedFlags |= FLAG_H; - } else { - expectedNotFlags |= FLAG_H; - } - }); - return this; - } - - public FlagsCheckImpl halfBorrow() { - return halfCarry(); // it's really the same for sub - } - - public FlagsCheckImpl halfCarry11() { - evaluators.add((context, result) -> { - int fst = first.apply(context); - int snd = second.apply(context); - int hc = ((result ^ fst ^ snd) >>> 8) & FLAG_H; - - if (hc != 0) { - expectedFlags |= FLAG_H; - } else { - expectedNotFlags |= FLAG_H; - } - }); - return this; - } - - public FlagsCheckImpl halfCarryIsReset() { - evaluators.add((context, result) -> expectedNotFlags |= FLAG_H); - return this; - } - - public FlagsCheckImpl halfCarryIsSet() { - evaluators.add((context, result) -> expectedFlags |= FLAG_H); - return this; - } - - public FlagsCheckImpl zeroIsSet() { - evaluators.add((context, result) -> expectedFlags |= FLAG_Z); - return this; - } - - public FlagsCheckImpl zeroIsPreserved() { - evaluators.add((context, result) -> { - if ((context.flags & FLAG_Z) == FLAG_Z) { - expectedFlags |= FLAG_Z; - } else { - expectedNotFlags |= FLAG_Z; - } - }); - return this; - } - - public FlagsCheckImpl signIsPreserved() { - evaluators.add((context, result) -> { - if ((context.flags & FLAG_S) == FLAG_S) { - expectedFlags |= FLAG_S; - } else { - expectedNotFlags |= FLAG_S; - } - }); - return this; - } - - public FlagsCheckImpl xy() { - evaluators.add((context, result) -> { - int flagxy = result & (FLAG_X | FLAG_Y); - if ((flagxy & FLAG_X) == FLAG_X) { - expectedFlags |= FLAG_X; - } else { - expectedNotFlags |= FLAG_X; - } - if ((flagxy & FLAG_Y) == FLAG_Y) { - expectedFlags |= FLAG_Y; - } else { - expectedNotFlags |= FLAG_Y; - } - }); - return this; - } -} diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/Utils.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/Utils.java index 951598d4a..3e59e8fcd 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/Utils.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/suite/Utils.java @@ -19,6 +19,7 @@ package net.emustudio.plugins.cpu.zilogZ80.suite; import java.util.function.Predicate; +import java.util.zip.CRC32; public class Utils { @@ -29,4 +30,10 @@ public static int get8MSBplus8LSB(int value) { public static Predicate predicate8MSBplus8LSB(int minimum) { return value -> get8MSBplus8LSB(value) > minimum; } + + public static long crc16(final byte[] bytes) { + CRC32 crc = new CRC32(); + crc.update(bytes); + return crc.getValue(); + } } From ffb06d0ef64aed4ddd2c6a1d858931a10e8f32f2 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 14 Feb 2023 14:43:27 +0100 Subject: [PATCH 262/314] [#260] Fix disassembler H+(HL) --- plugins/cpu/z80-cpu/src/main/edigen/cpu.eds | 18 +++++----- .../cpu/zilogZ80/DisassemblerTest.java | 34 +++++++++---------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds index b3ce3c27a..e08149565 100644 --- a/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds +++ b/plugins/cpu/z80-cpu/src/main/edigen/cpu.eds @@ -194,13 +194,13 @@ ddInstruction = "ld %s, %s": 01 10 r_ixhl(1) 0 r_bcde2(2) | # x=1, y=10 r_ixhl(1), z=0 r_bcde2 "ld %s, %s": 01 10 r_ixhl(1) 10 r_ixhl2(1) | # x=1, y=10 r_ixhl(1), z=10 r_ixhl2 "ld %s, a": 01 10 r_ixhl(1) 111 | # x=1, y=10 r_ixhl(1), z=7 - "ld %s, (ix+%Xh)": 01 10 r_ixhl(1) 110 disp | # x=1, y=10 r_ixhl(1), z=6 + "ld %s, (ix+%Xh)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l(1), z=6 "ld a, %s": 01 111 0 r_bcde(2) | # x=1, y=7, z=0 r_bcde "ld a, %s": 01 111 10 r_ixhl(1) | # x=1, y=7, z=10 r_ixhl "ld a, a": 01 111 111 | # x=1, y=7, z=7 "ld a, (ix+%Xh)": 01 111 110 disp | # x=1, y=7, z=6 "ld (ix+%Xh), %s": 01 110 0 r_bcde(2) disp | # x=1, y=6, z=0 r_bcde - "ld (ix+%Xh), %s": 01 110 10 r_ixhl2(1) disp | # x=1, y=6, z=10 r_ixhl2 + "ld (ix+%Xh), %s": 01 110 10 r_h_l2(1) disp | # x=1, y=6, z=10 r_h_l2 "ld (ix+%Xh), a": 01 110 111 disp | # x=1, y=6, z=7 "%s %s": 10 alu(3) 0 r_bcde(2) | # x=2, y=alu, z=r @@ -285,13 +285,13 @@ fdInstruction = "ld %s, %s": 01 10 r_iyhl(1) 0 r_bcde2(2) | # x=1, y=10 r_iyhl(1), z=0 r_bcde2 "ld %s, %s": 01 10 r_iyhl(1) 10 r_iyhl2(1) | # x=1, y=10 r_iyhl(1), z=10 r_iyhl2 "ld %s, a": 01 10 r_iyhl(1) 111 | # x=1, y=10 r_iyhl(1), z=7 - "ld %s, (iy+%Xh)": 01 10 r_iyhl(1) 110 disp | # x=1, y=10 r_iyhl(1), z=6 + "ld %s, (iy+%Xh)": 01 10 r_h_l(1) 110 disp | # x=1, y=10 r_h_l(1), z=6 "ld a, %s": 01 111 0 r_bcde(2) | # x=1, y=7, z=0 r_bcde "ld a, %s": 01 111 10 r_iyhl(1) | # x=1, y=7, z=10 r_iyhl "ld a, a": 01 111 111 | # x=1, y=7, z=7 "ld a, (iy+%Xh)": 01 111 110 disp | # x=1, y=7, z=6 "ld (iy+%Xh), %s": 01 110 0 r_bcde(2) disp | # x=1, y=6, z=0 r_bcde - "ld (iy+%Xh), %s": 01 110 10 r_iyhl2(1) disp | # x=1, y=6, z=10 r_iyhl2 + "ld (iy+%Xh), %s": 01 110 10 r_h_l2(1) disp | # x=1, y=6, z=10 r_h_l2 "ld (iy+%Xh), a": 01 110 111 disp | # x=1, y=6, z=7 "%s %s": 10 alu(3) 0 r_bcde(2) | # x=2, y=alu, z=r @@ -429,7 +429,7 @@ r_bcde,r_bcde2 = "d": 10 | "e": 11 ; -r_h_l = +r_h_l,r_h_l2 = "h": 0 | "l": 1 ; @@ -498,8 +498,8 @@ any2 = 00 | 01 | 10 | 11; "%s" = ddInstruction disp r_bcde; "%s" = ddInstruction r_ixhl r_bcde2; "%s" = ddInstruction r_ixhl r_ixhl2; -"%s" = ddInstruction r_ixhl disp; -"%s" = ddInstruction disp r_ixhl2; +"%s" = ddInstruction r_h_l disp; +"%s" = ddInstruction disp r_h_l2; "%s" = ddInstruction cc_jr imm8; "%s" = ddInstruction rp_ix imm16(reverse_bytes); "%s" = ddInstruction r_bcde imm8; @@ -529,8 +529,8 @@ any2 = 00 | 01 | 10 | 11; "%s" = fdInstruction disp r_bcde; "%s" = fdInstruction r_iyhl r_bcde2; "%s" = fdInstruction r_iyhl r_iyhl2; -"%s" = fdInstruction r_iyhl disp; -"%s" = fdInstruction disp r_iyhl2; +"%s" = fdInstruction r_h_l disp; +"%s" = fdInstruction disp r_h_l2; "%s" = fdInstruction cc_jr imm8; "%s" = fdInstruction rp_iy imm16(reverse_bytes); "%s" = fdInstruction r_bcde imm8; diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java index 04b658808..b932b181e 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/DisassemblerTest.java @@ -68,7 +68,7 @@ public void testDisassemble() throws InvalidInstructionException { 0x12, // ld (de), a 0x0A, // 20 // ld a, (bc) 0x1A, // ld a, (de) - 0x22, 0x34, 0x12, // ld (0x1234), hl\n" // 0 + 0x22, 0x34, 0x12, // ld (0x1234), hl 0x32, 0x34, 0x12, // ld (0x1234), a 0x2A, 0x34, 0x12, // ld hl, (0x1234) 0x3A, 0x34, 0x12, // ld a, (0x1234) @@ -362,21 +362,21 @@ public void testDisassemble() throws InvalidInstructionException { 0xFD, 0x6C, // ld iyl, iyh 0xFD, 0x6D, // ld iyl, iyl 0xDD, 0x72, 0x20, // ld (ix+0x20), d - 0xDD, 0x74, 0x20, // ld (ix+0x20), ixh - 0xDD, 0x75, 0x20, // ld (ix+0x20), ixl + 0xDD, 0x74, 0x20, // ld (ix+0x20), h + 0xDD, 0x75, 0x20, // ld (ix+0x20), l 0xFD, 0x73, 0x20, // ld (iy+0x20), e - 0xFD, 0x74, 0x20, // ld (iy+0x20), iyh - 0xFD, 0x75, 0x20, // ld (iy+0x20), iyl + 0xFD, 0x74, 0x20, // ld (iy+0x20), h + 0xFD, 0x75, 0x20, // ld (iy+0x20), l 0xDD, 0x7C, // ld a, ixh 0xFD, 0x7C, // ld a, iyh 0xDD, 0x7D, // ld a, ixl 0xFD, 0x7D, // ld a, iyl 0xDD, 0x7E, 0x20, // ld a, (ix+0x20) 0xFD, 0x7E, 0x20, // ld a, (iy+0x20) - 0xDD, 0x66, 0x20, // ld ixh, (ix+0x20) - 0xDD, 0x6E, 0x20, // ld ixl, (ix+0x20) - 0xFD, 0x66, 0x20, // ld iyh, (iy+0x20) - 0xFD, 0x6E, 0x20, // ld iyl, (iy+0x20) + 0xDD, 0x66, 0x20, // ld h, (ix+0x20) + 0xDD, 0x6E, 0x20, // ld l, (ix+0x20) + 0xFD, 0x66, 0x20, // ld h, (iy+0x20) + 0xFD, 0x6E, 0x20, // ld l, (iy+0x20) 0xDD, 0x84, // add a, ixh 0xDD, 0x85, // add a, ixl 0xDD, 0x86, 0x20, // add a, (ix + 0x20) @@ -757,21 +757,21 @@ public void testDisassemble() throws InvalidInstructionException { "ld iyl, iyh" + "ld iyl, iyl" + "ld (ix+20h), d" + - "ld (ix+20h), ixh" + - "ld (ix+20h), ixl" + + "ld (ix+20h), h" + + "ld (ix+20h), l" + "ld (iy+20h), e" + - "ld (iy+20h), iyh" + - "ld (iy+20h), iyl" + + "ld (iy+20h), h" + + "ld (iy+20h), l" + "ld a, ixh" + "ld a, iyh" + "ld a, ixl" + "ld a, iyl" + "ld a, (ix+20h)" + "ld a, (iy+20h)" + - "ld ixh, (ix+20h)" + - "ld ixl, (ix+20h)" + - "ld iyh, (iy+20h)" + - "ld iyl, (iy+20h)" + + "ld h, (ix+20h)" + + "ld l, (ix+20h)" + + "ld h, (iy+20h)" + + "ld l, (iy+20h)" + "add a, ixh" + "add a, ixl" + "add a, (ix+20h)" + From a40f87bb22c0a090b283a48a095f53a2e272bddd Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 19 Feb 2023 14:38:19 +0100 Subject: [PATCH 263/314] [#318, #315] Refactoring of byte-mem --- .../memory/bytemem/MemoryContextImpl.java | 47 ----- .../plugins/memory/bytemem/MemoryImpl.java | 24 +-- .../plugins/memory/bytemem/gui/Constants.java | 5 +- .../bytemem/gui/FindSequenceDialog.java | 8 +- .../plugins/memory/bytemem/gui/MemoryGui.java | 166 +++--------------- .../memory/bytemem/gui/SettingsDialog.java | 17 +- .../memory/bytemem/gui/ToolbarButton.java | 61 +++++++ .../bytemem/gui/actions/DumpMemoryAction.java | 83 +++++++++ .../gui/actions/FindSequenceAction.java | 100 +++-------- .../gui/actions/GotoAddressAction.java | 67 +++++++ .../bytemem/gui/actions/LoadImageAction.java | 90 ++++++++++ .../PerformFindSequenceAction.java | 120 +++++++++++++ .../memory/bytemem/loaders/BinaryLoader.java | 47 +++++ .../memory/bytemem/loaders/HexLoader.java | 44 +++++ .../memory/bytemem/loaders/Loader.java | 81 +++++++++ 15 files changed, 670 insertions(+), 290 deletions(-) create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/ToolbarButton.java create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/DumpMemoryAction.java create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/GotoAddressAction.java create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/LoadImageAction.java create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/find_sequence/PerformFindSequenceAction.java create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/BinaryLoader.java create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/HexLoader.java create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/Loader.java diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java index 6fb2d07f3..fd8e2b666 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryContextImpl.java @@ -20,32 +20,20 @@ import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.memory.AbstractMemoryContext; -import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.emulib.runtime.io.IntelHEX; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; -import java.io.EOFException; -import java.io.FileNotFoundException; -import java.io.RandomAccessFile; -import java.nio.file.Path; import java.util.Arrays; import java.util.List; -import java.util.Objects; @PluginContext(id = "Byte Memory") public class MemoryContextImpl extends AbstractMemoryContext implements ByteMemoryContext { final static int DEFAULT_MEM_SIZE = 65536; private final RangeTree romRanges = new RangeTree(); - private final Dialogs dialogs; - int lastImageStart = 0; private Byte[][] mem = new Byte[1][0]; private int banksCount; private int bankSelect = 0; private int bankCommon = 0; - public MemoryContextImpl(Dialogs dialogs) { - this.dialogs = Objects.requireNonNull(dialogs); - } void init(int size, int banks, int bankCommon) { if (banks <= 0) { @@ -63,7 +51,6 @@ public void clear() { for (Byte[] bank : mem) { Arrays.fill(bank, (byte) 0); } - lastImageStart = 0; notifyMemoryChanged(-1); } @@ -95,40 +82,6 @@ public int getCommonBoundary() { return bankCommon; } - public void loadHex(Path hexFile, int bank) { - int currentBank = bankSelect; - try { - bankSelect = (short) bank; - lastImageStart = IntelHEX.loadIntoMemory(hexFile.toFile(), this, p -> p); - } catch (FileNotFoundException ex) { - dialogs.showError("File not found: " + hexFile); - } catch (Exception e) { - dialogs.showError("Error opening file: " + hexFile); - } finally { - bankSelect = currentBank; - notifyMemoryChanged(-1); - } - } - - public void loadBin(Path binFile, int address, int bank) { - lastImageStart = 0; - try (RandomAccessFile binaryFile = new RandomAccessFile(binFile.toFile(), "r")) { - long position = 0, length = binaryFile.length(); - while (position < length) { - mem[bank][address++] = (byte) (binaryFile.readUnsignedByte() & 0xFF); - position++; - } - } catch (EOFException ignored) { - // ignored intentionally - } catch (FileNotFoundException ex) { - dialogs.showError("File not found: " + binFile); - } catch (Exception e) { - dialogs.showError("Error opening file: " + binFile); - } finally { - notifyMemoryChanged(-1); - } - } - @Override public Byte read(int from) { int activeBank = (from < bankCommon) ? bankSelect : 0; diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java index 166e64765..51f848189 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/MemoryImpl.java @@ -30,6 +30,7 @@ import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; import net.emustudio.plugins.memory.bytemem.gui.MemoryGui; +import net.emustudio.plugins.memory.bytemem.loaders.Loader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,7 +49,7 @@ public class MemoryImpl extends AbstractMemory { private final static Logger LOGGER = LoggerFactory.getLogger(MemoryImpl.class); - private final MemoryContextImpl context; + private final MemoryContextImpl context = new MemoryContextImpl(); private final boolean guiNotSupported; private MemoryGui gui; @@ -56,7 +57,6 @@ public MemoryImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s super(pluginID, applicationApi, settings); this.guiNotSupported = settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); - this.context = new MemoryContextImpl(applicationApi.getDialogs()); try { ContextPool contextPool = applicationApi.getContextPool(); contextPool.register(pluginID, context, ByteMemoryContext.class); @@ -157,17 +157,17 @@ private void loadImages() throws PluginInitializationException { break; } } catch (NumberFormatException e) { - throw new PluginInitializationException(this, "Could not parse image address", e); + throw new PluginInitializationException(this, "Could not parse image address or bank", e); + } catch (Exception e) { + throw new PluginInitializationException(this, e); } } } - public void loadImage(Path imagePath, int address, int bank) { - if (imagePath.toString().toLowerCase().endsWith(".hex")) { - context.loadHex(imagePath, bank); - } else { - context.loadBin(imagePath, address, bank); - } + public void loadImage(Path imagePath, int address, int bank) throws Exception { + Loader.MemoryBank memoryBank = Loader.MemoryBank.of(bank, address); + Loader loader = Loader.createLoader(imagePath); + loader.load(imagePath, context, memoryBank); } /* @@ -210,12 +210,6 @@ public void saveROMRanges() { } } - @Override - public void setProgramLocation(int location) { - super.setProgramLocation(location); - context.lastImageStart = location; - } - @Override public void showSettings(JFrame parent) { if (!guiNotSupported) { diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java index 7f9266df2..a02698806 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/Constants.java @@ -21,12 +21,15 @@ import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; import java.awt.*; +import java.util.List; + +import static net.emustudio.plugins.memory.bytemem.loaders.Loader.IMAGE_LOADERS; public class Constants { public final static Font MEMORY_CELLS_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 12); public final static FileExtensionsFilter IMAGE_EXTENSION_FILTER = new FileExtensionsFilter( - "Memory image", "hex", "bin", "com", "out" + "Memory image", List.copyOf(IMAGE_LOADERS.keySet()) ); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java index fc98f890c..1b54dbf43 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java @@ -19,7 +19,7 @@ package net.emustudio.plugins.memory.bytemem.gui; import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.plugins.memory.bytemem.gui.actions.FindSequenceAction; +import net.emustudio.plugins.memory.bytemem.gui.actions.find_sequence.PerformFindSequenceAction; import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; import javax.swing.*; @@ -27,7 +27,7 @@ import java.util.function.Consumer; public class FindSequenceDialog extends JDialog { - private final FindSequenceAction findSequenceAction; + private final PerformFindSequenceAction performFindSequenceAction; private final JRadioButton radioCurrentPage = new JRadioButton(); private final JRadioButton radioPlainText = new JRadioButton(); private final JTextField txtPosition = new JTextField(); @@ -37,7 +37,7 @@ public FindSequenceDialog(Dialogs dialogs, JDialog parent, MemoryTableModel tabl super(parent, true); setLocationRelativeTo(parent); - this.findSequenceAction = new FindSequenceAction( + this.performFindSequenceAction = new PerformFindSequenceAction( dialogs, this::dispose, tableModel, setFoundAddress, radioCurrentPage::isSelected, radioPlainText::isSelected, currentAddress, txtPosition, txtSequence ); @@ -51,7 +51,7 @@ private void initComponents() { JRadioButton radioBytes = new JRadioButton(); JPanel jPanel2 = new JPanel(); JRadioButton radioSpecificPosition = new JRadioButton(); - JButton btnFind = new JButton(findSequenceAction); + JButton btnFind = new JButton(performFindSequenceAction); btnGroupSequenceToFind.add(radioPlainText); btnGroupSequenceToFind.add(radioBytes); diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java index 11427fa6f..88bdb7945 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java @@ -19,14 +19,15 @@ package net.emustudio.plugins.memory.bytemem.gui; import net.emustudio.emulib.runtime.interaction.Dialogs; -import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; import net.emustudio.plugins.memory.bytemem.MemoryImpl; +import net.emustudio.plugins.memory.bytemem.gui.actions.DumpMemoryAction; +import net.emustudio.plugins.memory.bytemem.gui.actions.FindSequenceAction; +import net.emustudio.plugins.memory.bytemem.gui.actions.GotoAddressAction; +import net.emustudio.plugins.memory.bytemem.gui.actions.LoadImageAction; import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; import net.emustudio.plugins.memory.bytemem.gui.model.TableMemory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.swing.*; import java.awt.*; @@ -34,17 +35,11 @@ import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.io.*; -import java.nio.file.Path; import java.util.Objects; -import java.util.concurrent.atomic.AtomicInteger; import static net.emustudio.emulib.runtime.helpers.RadixUtils.formatBinaryString; -import static net.emustudio.plugins.memory.bytemem.gui.Constants.IMAGE_EXTENSION_FILTER; public class MemoryGui extends JDialog { - private final static Logger LOGGER = LoggerFactory.getLogger(MemoryGui.class); - private final MemoryContextImpl context; private final MemoryImpl memory; private final PluginSettings settings; @@ -65,6 +60,11 @@ public class MemoryGui extends JDialog { private final JTextField txtValueOct = new JTextField(); private final JToggleButton btnAsciiMode = new JToggleButton(); + private final LoadImageAction loadImageAction; + private final DumpMemoryAction dumpMemoryAction; + private final GotoAddressAction gotoAddressAction; + private final FindSequenceAction findSequenceAction; + public MemoryGui(JFrame parent, MemoryImpl memory, MemoryContextImpl context, PluginSettings settings, Dialogs dialogs) { super(parent); @@ -74,11 +74,20 @@ public MemoryGui(JFrame parent, MemoryImpl memory, MemoryContextImpl context, Pl this.settings = Objects.requireNonNull(settings); this.dialogs = Objects.requireNonNull(dialogs); this.tableModel = new MemoryTableModel(context); + this.table = new TableMemory(tableModel, paneMemory); + + this.loadImageAction = new LoadImageAction(dialogs, context, this, () -> { + table.revalidate(); + table.repaint(); + }); + this.dumpMemoryAction = new DumpMemoryAction(dialogs, context); + this.gotoAddressAction = new GotoAddressAction(dialogs, context, this::setPageFromAddress); + this.findSequenceAction = new FindSequenceAction(dialogs, this::setPageFromAddress, tableModel, + this::getCurrentAddress, this); initComponents(); super.setLocationRelativeTo(parent); - table = new TableMemory(tableModel, paneMemory); paneMemory.setViewportView(table); tableModel.addTableModelListener(e -> spnPage.getModel().setValue(tableModel.getPage())); @@ -140,10 +149,6 @@ public void updateMemVal(int row, int column) { private void initComponents() { JToolBar toolBar = new JToolBar(); - JButton btnLoadImage = new JButton(); - JButton btnDump = new JButton(); - JButton btnGotoAddress = new JButton(); - JButton btnFind = new JButton(); JButton btnClean = new JButton(); JButton btnSettings = new JButton(); JSplitPane splitPane = new JSplitPane(); @@ -171,43 +176,11 @@ private void initComponents() { toolBar.setFloatable(false); toolBar.setRollover(true); - - btnLoadImage.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/document-open.png"))); - btnLoadImage.setToolTipText("Load image..."); - btnLoadImage.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - btnLoadImage.setFocusable(false); - btnLoadImage.setHorizontalTextPosition(SwingConstants.CENTER); - btnLoadImage.setVerticalTextPosition(SwingConstants.BOTTOM); - btnLoadImage.addActionListener(this::btnLoadImageActionPerformed); - toolBar.add(btnLoadImage); - - btnDump.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/document-save.png"))); - btnDump.setToolTipText("Dump (save) memory..."); - btnDump.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - btnDump.setFocusable(false); - btnDump.setHorizontalTextPosition(SwingConstants.CENTER); - btnDump.setVerticalTextPosition(SwingConstants.BOTTOM); - btnDump.addActionListener(this::btnDumpActionPerformed); - toolBar.add(btnDump); + toolBar.add(new ToolbarButton(loadImageAction)); + toolBar.add(new ToolbarButton(dumpMemoryAction)); toolBar.addSeparator(); - - btnGotoAddress.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/format-indent-more.png"))); - btnGotoAddress.setToolTipText("Go to address..."); - btnGotoAddress.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - btnGotoAddress.setFocusable(false); - btnGotoAddress.setHorizontalTextPosition(SwingConstants.CENTER); - btnGotoAddress.setVerticalTextPosition(SwingConstants.BOTTOM); - btnGotoAddress.addActionListener(this::btnGotoAddressActionPerformed); - toolBar.add(btnGotoAddress); - - btnFind.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/edit-find.png"))); - btnFind.setToolTipText("Find sequence..."); - btnFind.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - btnFind.setFocusable(false); - btnFind.setHorizontalTextPosition(SwingConstants.CENTER); - btnFind.setVerticalTextPosition(SwingConstants.BOTTOM); - btnFind.addActionListener(this::btnFindActionPerformed); - toolBar.add(btnFind); + toolBar.add(new ToolbarButton(gotoAddressAction)); + toolBar.add(new ToolbarButton(findSequenceAction)); toolBar.addSeparator(); btnAsciiMode.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/ascii-mode.png"))); @@ -452,76 +425,11 @@ private void initComponents() { pack(); } - private void btnLoadImageActionPerformed(ActionEvent evt) { - dialogs.chooseFile( - "Load memory image", "Load", Path.of(System.getProperty("user.dir")), false, IMAGE_EXTENSION_FILTER - ).ifPresent(path -> { - boolean isHex = path.toString().toLowerCase().endsWith(".hex"); - boolean hasBanks = context.getBanksCount() > 1; - - int bank = 0; - int address = 0; - boolean ok = true; - - if (!isHex || hasBanks) { - SelectBankAddressDialog dialog = new SelectBankAddressDialog( - this, hasBanks, !isHex, dialogs - ); - dialog.setVisible(true); - ok = dialog.isOk(); - bank = dialog.getBank(); - address = dialog.getAddress(); - } - - if (isHex && ok) { - context.loadHex(path, bank); - } - if (!isHex && ok) { - context.loadBin(path, address, bank); - } - - table.revalidate(); - table.repaint(); - }); - } - private void btnCleanActionPerformed(ActionEvent evt) { context.clear(); tableModel.fireTableDataChanged(); } - private void btnGotoAddressActionPerformed(ActionEvent evt) { - try { - dialogs - .readInteger("Enter memory address:", "Go to address") - .ifPresent(address -> { - if (address < 0 || address >= context.getSize()) { - dialogs.showError( - "Address out of bounds (min=0, max=" + (context.getSize() - 1) + ")", "Go to address" - ); - } else { - setPageFromAddress(address); - } - }); - } catch (NumberFormatException e) { - dialogs.showError("Invalid number format", "Go to address"); - } - } - - private void btnFindActionPerformed(ActionEvent evt) { - AtomicInteger foundAddress = new AtomicInteger(-1); - FindSequenceDialog dialog = new FindSequenceDialog( - dialogs, this, tableModel, getCurrentAddress(), foundAddress::set - ); - - dialog.setVisible(true); - - int address = foundAddress.get(); - if (address != -1) { - setPageFromAddress(address); - } - } - private void btnSymbolModeActionPerformed(ActionEvent evt) { tableModel.setAsciiMode(btnAsciiMode.isSelected()); } @@ -530,34 +438,6 @@ private void btnSettingsActionPerformed(ActionEvent evt) { new SettingsDialog(this, memory, context, table, settings, dialogs).setVisible(true); } - private void btnDumpActionPerformed(ActionEvent evt) { - Path currentDirectory = Path.of(System.getProperty("user.dir")); - dialogs.chooseFile( - "Dump memory content into a file", "Save", currentDirectory, true, - new FileExtensionsFilter("Human-readable dump", "txt"), - new FileExtensionsFilter("Binary dump", "bin") - ).ifPresent(path -> { - try { - if (path.toString().toLowerCase().endsWith(".txt")) { - try (BufferedWriter out = new BufferedWriter(new FileWriter(path.toFile()))) { - for (int i = 0; i < context.getSize(); i++) { - out.write(String.format("%X:\t%02X\n", i, context.read(i))); - } - } - } else { - try (DataOutputStream ds = new DataOutputStream(new FileOutputStream(path.toFile()))) { - for (int i = 0; i < context.getSize(); i++) { - ds.writeByte(context.read(i) & 0xff); - } - } - } - } catch (IOException e) { - LOGGER.error("Memory dump could not be created", e); - dialogs.showError("Memory dump could not be created. Please see log file for more details."); - } - }); - } - private int getCurrentAddress() { return tableModel.getPage() * (tableModel.getRowCount() * tableModel.getColumnCount()); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java index f8a109bfa..0ba7fe203 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SettingsDialog.java @@ -437,11 +437,18 @@ private void btnLoadNowActionPerformed(java.awt.event.ActionEvent evt) { if (index == -1) { dialogs.showError("Image has to be selected", "Load image now"); } else { - memory.loadImage( - Path.of(imagesModel.getFileNameAtRow(index)), imagesModel.getImageAddressAtRow(index), - imagesModel.getImageBankAtRow(index) - ); - tblMem.getTableModel().fireTableDataChanged(); + Path imagePath = Path.of(imagesModel.getFileNameAtRow(index)); + try { + + memory.loadImage( + imagePath, imagesModel.getImageAddressAtRow(index), + imagesModel.getImageBankAtRow(index) + ); + tblMem.getTableModel().fireTableDataChanged(); + } catch (Exception e) { + dialogs.showError("Could not load image: " + e.getMessage() + ". Please see log file for details."); + LOGGER.error("Could not load memory image " + imagePath, e); + } } } } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/ToolbarButton.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/ToolbarButton.java new file mode 100644 index 000000000..e00f31b9e --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/ToolbarButton.java @@ -0,0 +1,61 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.bytemem.gui; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.util.function.Consumer; + +import static javax.swing.Action.SHORT_DESCRIPTION; + +public class ToolbarButton extends JButton { + + public ToolbarButton(Action action, String iconResource) { + super(action); + setHideActionText(true); + setIcon(new ImageIcon(getClass().getResource(iconResource))); + setToolTipText(String.valueOf(action.getValue(SHORT_DESCRIPTION))); + setFocusable(false); + } + + public ToolbarButton(Action action, String iconResource, String tooltipText) { + super(action); + setHideActionText(true); + setIcon(new ImageIcon(getClass().getResource(iconResource))); + setToolTipText(tooltipText); + setFocusable(false); + } + + public ToolbarButton(Action action) { + super(action); + setHideActionText(true); + setToolTipText(String.valueOf(action.getValue(SHORT_DESCRIPTION))); + setFocusable(false); + } + + public ToolbarButton(Consumer action, String iconResource, String tooltipText) { + this(new AbstractAction() { + + @Override + public void actionPerformed(ActionEvent actionEvent) { + action.accept(actionEvent); + } + }, iconResource, tooltipText); + } +} diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/DumpMemoryAction.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/DumpMemoryAction.java new file mode 100644 index 000000000..769a8b1c6 --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/DumpMemoryAction.java @@ -0,0 +1,83 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.bytemem.gui.actions; + +import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.*; +import java.nio.file.Path; +import java.util.Locale; +import java.util.Objects; +import java.util.Optional; + +public class DumpMemoryAction extends AbstractAction { + private final static Logger LOGGER = LoggerFactory.getLogger(DumpMemoryAction.class); + private final static String ICON_FILE = "/net/emustudio/plugins/memory/bytemem/gui/document-save.png"; + private final Dialogs dialogs; + private final ByteMemoryContext context; + + public DumpMemoryAction(Dialogs dialogs, ByteMemoryContext context) { + super("Dump (save) memory to a file...", new ImageIcon(DumpMemoryAction.class.getResource(ICON_FILE))); + + this.dialogs = Objects.requireNonNull(dialogs); + this.context = Objects.requireNonNull(context); + + putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); + putValue(SHORT_DESCRIPTION, "Dump (save) memory to a file..."); + putValue(MNEMONIC_KEY, KeyEvent.VK_S); + } + + @Override + public void actionPerformed(ActionEvent e) { + Path currentDirectory = Path.of(System.getProperty("user.dir")); + Optional dumpPath = dialogs.chooseFile( + "Dump memory content into a file", "Save", currentDirectory, true, + new FileExtensionsFilter("Human-readable dump", "txt"), + new FileExtensionsFilter("Binary dump", "bin")); + + dumpPath.ifPresent(path -> { + try { + if (path.toString().toLowerCase(Locale.ENGLISH).endsWith(".txt")) { + try (BufferedWriter out = new BufferedWriter(new FileWriter(path.toFile()))) { + for (int i = 0; i < context.getSize(); i++) { + out.write(String.format("%X:\t%02X\n", i, context.read(i))); + } + } + } else { + try (DataOutputStream ds = new DataOutputStream(new FileOutputStream(path.toFile()))) { + for (int i = 0; i < context.getSize(); i++) { + ds.writeByte(context.read(i) & 0xff); + } + } + } + } catch (IOException ex) { + LOGGER.error("Memory dump could not be created", ex); + dialogs.showError("Memory dump could not be created: " + ex.getMessage() + ". Please see log file for more details."); + } + }); + } +} diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/FindSequenceAction.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/FindSequenceAction.java index fb35e53d5..d5bec0e89 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/FindSequenceAction.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/FindSequenceAction.java @@ -18,104 +18,54 @@ */ package net.emustudio.plugins.memory.bytemem.gui.actions; -import net.emustudio.emulib.runtime.helpers.RadixUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.plugins.memory.bytemem.gui.FindSequenceDialog; import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.swing.*; -import javax.swing.text.JTextComponent; import java.awt.event.ActionEvent; -import java.util.List; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; public class FindSequenceAction extends AbstractAction { - public final static String ERROR_NUMBER_FORMAT = "Cannot parse sequence of bytes. Bytes (in correct radix format) must be separated with spaces."; - private final static Logger LOGGER = LoggerFactory.getLogger(FindSequenceAction.class); + private final static String ICON_FILE = "/net/emustudio/plugins/memory/bytemem/gui/edit-find.png"; private final Dialogs dialogs; - private final Runnable dispose; + private final Consumer setPageFromAddress; private final MemoryTableModel tableModel; + private final Supplier getCurrentAddress; + private final JDialog parent; - private final Consumer setFoundAddress; - - private final Supplier isCurrentPage; - private final Supplier isPlainText; - private final int currentAddress; - private final JTextComponent txtPosition; - private final JTextComponent txtFindText; - - private final RadixUtils radixUtils = RadixUtils.getInstance(); - - public FindSequenceAction(Dialogs dialogs, Runnable dispose, - MemoryTableModel tableModel, - Consumer setFoundAddress, - Supplier isCurrentPage, - Supplier isPlainText, - int currentAddress, - JTextComponent txtPosition, - JTextComponent txtFindText) { - super("Find"); + public FindSequenceAction(Dialogs dialogs, Consumer setPageFromAddress, MemoryTableModel tableModel, + Supplier getCurrentAddress, JDialog parent) { + super("Find sequence...", new ImageIcon(FindSequenceAction.class.getResource(ICON_FILE))); this.dialogs = Objects.requireNonNull(dialogs); - this.dispose = Objects.requireNonNull(dispose); + this.setPageFromAddress = Objects.requireNonNull(setPageFromAddress); this.tableModel = Objects.requireNonNull(tableModel); + this.getCurrentAddress = Objects.requireNonNull(getCurrentAddress); + this.parent = Objects.requireNonNull(parent); - this.setFoundAddress = Objects.requireNonNull(setFoundAddress); - - this.currentAddress = currentAddress; - this.isCurrentPage = Objects.requireNonNull(isCurrentPage); - this.isPlainText = Objects.requireNonNull(isPlainText); - this.txtPosition = Objects.requireNonNull(txtPosition); - this.txtFindText = Objects.requireNonNull(txtFindText); + putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_DOWN_MASK)); + putValue(SHORT_DESCRIPTION, "Find sequence..."); + putValue(MNEMONIC_KEY, KeyEvent.VK_F); } @Override public void actionPerformed(ActionEvent e) { - LastError lastError = new LastError(); - - try { - lastError.component = txtPosition; - lastError.message = ERROR_NUMBER_FORMAT; - int from = isCurrentPage.get() ? currentAddress : radixUtils.parseRadix(txtPosition.getText().trim()); + AtomicInteger foundAddress = new AtomicInteger(-1); + FindSequenceDialog dialog = new FindSequenceDialog( + dialogs, parent, tableModel, getCurrentAddress.get(), foundAddress::set + ); - lastError.component = txtFindText; - lastError.message = "Sequence cannot be empty"; - String text = txtFindText.getText(); - if (text.isEmpty()) { - throw new Exception(); - } + dialog.setVisible(true); - final byte[] sequenceToFind; - if (isPlainText.get()) { - sequenceToFind = text.getBytes(); - } else { - lastError.message = ERROR_NUMBER_FORMAT; - - List mapped = Stream.of(text.split(" ")).map(radixUtils::parseRadix).collect(Collectors.toList()); - sequenceToFind = new byte[mapped.size()]; - for (int i = 0; i < sequenceToFind.length; i++) { - sequenceToFind[i] = mapped.get(i).byteValue(); // NOTE: if integer is > than byte, the rest is cut off. - } - } - - tableModel.findSequence(sequenceToFind, from).ifPresent(setFoundAddress); - dispose.run(); - } catch (Exception ex) { - LOGGER.debug(lastError.message, ex); - dialogs.showError(lastError.message, "Find sequence"); - - lastError.component.selectAll(); - lastError.component.requestFocus(); + int address = foundAddress.get(); + if (address != -1) { + setPageFromAddress.accept(address); } } - - private final static class LastError { - JTextComponent component; - String message; - } } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/GotoAddressAction.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/GotoAddressAction.java new file mode 100644 index 000000000..574a629e5 --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/GotoAddressAction.java @@ -0,0 +1,67 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.bytemem.gui.actions; + +import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.util.Objects; +import java.util.function.Consumer; + +public class GotoAddressAction extends AbstractAction { + private final static String ICON_FILE = "/net/emustudio/plugins/memory/bytemem/gui/format-indent-more.png"; + private final Dialogs dialogs; + private final ByteMemoryContext context; + private final Consumer setPageFromAddress; + + public GotoAddressAction(Dialogs dialogs, ByteMemoryContext context, Consumer setPageFromAddress) { + super("Go to address...", new ImageIcon(GotoAddressAction.class.getResource(ICON_FILE))); + + this.dialogs = Objects.requireNonNull(dialogs); + this.context = Objects.requireNonNull(context); + this.setPageFromAddress = Objects.requireNonNull(setPageFromAddress); + + putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_DOWN_MASK)); + putValue(SHORT_DESCRIPTION, "Go to address..."); + putValue(MNEMONIC_KEY, KeyEvent.VK_G); + } + + @Override + public void actionPerformed(ActionEvent e) { + try { + dialogs + .readInteger("Enter memory address:", "Go to address") + .ifPresent(address -> { + if (address < 0 || address >= context.getSize()) { + dialogs.showError( + "Address out of bounds (min=0, max=" + (context.getSize() - 1) + ")", "Go to address" + ); + } else { + setPageFromAddress.accept(address); + } + }); + } catch (NumberFormatException ex) { + dialogs.showError("Invalid number format", "Go to address"); + } + } +} diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/LoadImageAction.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/LoadImageAction.java new file mode 100644 index 000000000..f79b873dd --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/LoadImageAction.java @@ -0,0 +1,90 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.bytemem.gui.actions; + +import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; +import net.emustudio.plugins.memory.bytemem.gui.SelectBankAddressDialog; +import net.emustudio.plugins.memory.bytemem.loaders.Loader; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.nio.file.Path; +import java.util.Objects; +import java.util.Optional; + +import static net.emustudio.plugins.memory.bytemem.gui.Constants.IMAGE_EXTENSION_FILTER; + +public class LoadImageAction extends AbstractAction { + private final static String ICON_FILE = "/net/emustudio/application/gui/dialogs/document-open.png"; + private final Dialogs dialogs; + private final ByteMemoryContext context; + private final JDialog parent; + private final Runnable repaint; + + public LoadImageAction(Dialogs dialogs, ByteMemoryContext context, JDialog parent, Runnable repaint) { + super("Load image file...", new ImageIcon(LoadImageAction.class.getResource(ICON_FILE))); + + this.dialogs = Objects.requireNonNull(dialogs); + this.context = Objects.requireNonNull(context); + this.parent = Objects.requireNonNull(parent); + this.repaint = Objects.requireNonNull(repaint); + + putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK)); + putValue(SHORT_DESCRIPTION, "Load image file..."); + putValue(MNEMONIC_KEY, KeyEvent.VK_O); + } + + @Override + public void actionPerformed(ActionEvent e) { + Optional imagePath = dialogs.chooseFile( + "Load image file", "Load", Path.of(System.getProperty("user.dir")), + false, IMAGE_EXTENSION_FILTER); + imagePath.ifPresent(path -> { + Loader loader = Loader.createLoader(path); + Loader.MemoryBank bank = askForMemoryBank(!loader.isMemoryAddressAware()); + try { + loader.load(path, context, bank); + repaint.run(); + } catch (Exception ex) { + dialogs.showError("Could not load selected image file: " + ex.getMessage(), "Load image file"); + + ex.printStackTrace(); + } + }); + } + + private Loader.MemoryBank askForMemoryBank(boolean canSelectAddress) { + boolean hasMultipleBanks = context.getBanksCount() > 1; + Loader.MemoryBank bank = Loader.MemoryBank.of(0, 0); + + if (hasMultipleBanks || canSelectAddress) { + SelectBankAddressDialog dialog = new SelectBankAddressDialog( + parent, hasMultipleBanks, canSelectAddress, dialogs); + dialog.setVisible(true); + + if (dialog.isOk()) { + bank = Loader.MemoryBank.of(dialog.getBank(), dialog.getAddress()); + } + } + return bank; + } +} diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/find_sequence/PerformFindSequenceAction.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/find_sequence/PerformFindSequenceAction.java new file mode 100644 index 000000000..792f0a75f --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/find_sequence/PerformFindSequenceAction.java @@ -0,0 +1,120 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.bytemem.gui.actions.find_sequence; + +import net.emustudio.emulib.runtime.helpers.RadixUtils; +import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.*; +import javax.swing.text.JTextComponent; +import java.awt.event.ActionEvent; +import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class PerformFindSequenceAction extends AbstractAction { + public final static String ERROR_NUMBER_FORMAT = "Cannot parse sequence of bytes. Bytes (in correct radix format) must be separated with spaces."; + private final static Logger LOGGER = LoggerFactory.getLogger(PerformFindSequenceAction.class); + private final Dialogs dialogs; + private final Runnable dispose; + private final MemoryTableModel tableModel; + + private final Consumer setFoundAddress; + + private final Supplier isCurrentPage; + private final Supplier isPlainText; + private final int currentAddress; + private final JTextComponent txtPosition; + private final JTextComponent txtFindText; + + private final RadixUtils radixUtils = RadixUtils.getInstance(); + + public PerformFindSequenceAction(Dialogs dialogs, Runnable dispose, + MemoryTableModel tableModel, + Consumer setFoundAddress, + Supplier isCurrentPage, + Supplier isPlainText, + int currentAddress, + JTextComponent txtPosition, + JTextComponent txtFindText) { + + this.dialogs = Objects.requireNonNull(dialogs); + this.dispose = Objects.requireNonNull(dispose); + this.tableModel = Objects.requireNonNull(tableModel); + + this.setFoundAddress = Objects.requireNonNull(setFoundAddress); + + this.currentAddress = currentAddress; + this.isCurrentPage = Objects.requireNonNull(isCurrentPage); + this.isPlainText = Objects.requireNonNull(isPlainText); + this.txtPosition = Objects.requireNonNull(txtPosition); + this.txtFindText = Objects.requireNonNull(txtFindText); + } + + @Override + public void actionPerformed(ActionEvent e) { + LastError lastError = new LastError(); + + try { + lastError.component = txtPosition; + lastError.message = ERROR_NUMBER_FORMAT; + int from = isCurrentPage.get() ? currentAddress : radixUtils.parseRadix(txtPosition.getText().trim()); + + lastError.component = txtFindText; + lastError.message = "Sequence cannot be empty"; + String text = txtFindText.getText(); + if (text.isEmpty()) { + throw new Exception(); + } + + final byte[] sequenceToFind; + if (isPlainText.get()) { + sequenceToFind = text.getBytes(); + } else { + lastError.message = ERROR_NUMBER_FORMAT; + + List mapped = Stream.of(text.split(" ")).map(radixUtils::parseRadix).collect(Collectors.toList()); + sequenceToFind = new byte[mapped.size()]; + for (int i = 0; i < sequenceToFind.length; i++) { + sequenceToFind[i] = mapped.get(i).byteValue(); // NOTE: if integer is > than byte, the rest is cut off. + } + } + + tableModel.findSequence(sequenceToFind, from).ifPresent(setFoundAddress); + dispose.run(); + } catch (Exception ex) { + LOGGER.debug(lastError.message, ex); + dialogs.showError(lastError.message, "Find sequence"); + + lastError.component.selectAll(); + lastError.component.requestFocus(); + } + } + + private final static class LastError { + JTextComponent component; + String message; + } +} diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/BinaryLoader.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/BinaryLoader.java new file mode 100644 index 000000000..62c31c1b6 --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/BinaryLoader.java @@ -0,0 +1,47 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.bytemem.loaders; + +import net.emustudio.emulib.runtime.helpers.NumberUtils; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; + +import java.io.FileInputStream; +import java.nio.file.Path; + +public class BinaryLoader implements Loader { + + @Override + public boolean isMemoryAddressAware() { + return false; + } + + @Override + public void load(Path path, ByteMemoryContext memory, MemoryBank bank) throws Exception { + int oldBank = memory.getSelectedBank(); + + try (FileInputStream stream = new FileInputStream(path.toFile())) { + memory.selectBank(bank.bank); + byte[] content = stream.readAllBytes(); + memory.write(bank.address, NumberUtils.nativeBytesToBytes(content)); + } catch (Exception e) { + memory.selectBank(oldBank); + throw e; + } + } +} diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/HexLoader.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/HexLoader.java new file mode 100644 index 000000000..49ecb9fd2 --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/HexLoader.java @@ -0,0 +1,44 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.bytemem.loaders; + +import net.emustudio.emulib.runtime.io.IntelHEX; +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; + +import java.nio.file.Path; + +public class HexLoader implements Loader { + + @Override + public boolean isMemoryAddressAware() { + return true; + } + + @Override + public void load(Path path, ByteMemoryContext memory, MemoryBank bank) throws Exception { + int oldBank = memory.getSelectedBank(); + try { + memory.selectBank(bank.bank); // need to do it before loading + IntelHEX.loadIntoMemory(path.toFile(), memory, p -> p); + } catch (Exception e) { + memory.selectBank(oldBank); + throw e; + } + } +} diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/Loader.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/Loader.java new file mode 100644 index 000000000..c488a7f29 --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/loaders/Loader.java @@ -0,0 +1,81 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.bytemem.loaders; + +import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; + +import java.nio.file.Path; +import java.util.Locale; +import java.util.Map; + +public interface Loader { + + Map IMAGE_LOADERS = Map.of( + "hex", new HexLoader(), + "bin", new BinaryLoader(), + "com", new BinaryLoader(), + "out", new BinaryLoader() + ); + + /** + * Determines if this loader/format is aware of memory addresses (so user is or is not allowed to choose memory + * address when loading the file). + * + * @return true if the loader is aware of memory addresses; false otherwise + */ + boolean isMemoryAddressAware(); + + /** + * Loads an image file to memory + * + * @param path image file path + * @param memory memory context + * @param bank memory bank + address + */ + void load(Path path, ByteMemoryContext memory, MemoryBank bank) throws Exception; + + class MemoryBank { + final int bank; + final int address; + + public MemoryBank(int bank, int address) { + this.bank = bank; + this.address = address; + } + + public static MemoryBank of(int bank, int address) { + return new MemoryBank(bank, address); + } + } + + + static Loader createLoader(Path path) { + int index = path.toString().lastIndexOf("."); + String extension = (index == -1) ? + "" : path.toString().substring(index + 1).toLowerCase(Locale.ENGLISH); + + return IMAGE_LOADERS + .entrySet() + .stream() + .filter(l -> l.getKey().equals(extension)) + .findFirst() + .map(Map.Entry::getValue) + .orElse(new BinaryLoader()); // unknown/no extension + } +} From f757dedf331cb0e778188be3dc440fcea6b247ef Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 19 Feb 2023 14:54:38 +0100 Subject: [PATCH 264/314] [#315] byte-mem: gui actions --- .../plugins/memory/bytemem/gui/MemoryGui.java | 73 ++++--------------- .../bytemem/gui/actions/AsciiModeAction.java | 42 +++++++++++ .../gui/actions/EraseMemoryAction.java | 44 +++++++++++ .../bytemem/gui/actions/SettingsAction.java | 56 ++++++++++++++ 4 files changed, 158 insertions(+), 57 deletions(-) create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/AsciiModeAction.java create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/EraseMemoryAction.java create mode 100644 plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/SettingsAction.java diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java index 88bdb7945..40727d8ca 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java @@ -22,16 +22,12 @@ import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; import net.emustudio.plugins.memory.bytemem.MemoryImpl; -import net.emustudio.plugins.memory.bytemem.gui.actions.DumpMemoryAction; -import net.emustudio.plugins.memory.bytemem.gui.actions.FindSequenceAction; -import net.emustudio.plugins.memory.bytemem.gui.actions.GotoAddressAction; -import net.emustudio.plugins.memory.bytemem.gui.actions.LoadImageAction; +import net.emustudio.plugins.memory.bytemem.gui.actions.*; import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; import net.emustudio.plugins.memory.bytemem.gui.model.TableMemory; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; @@ -40,10 +36,6 @@ import static net.emustudio.emulib.runtime.helpers.RadixUtils.formatBinaryString; public class MemoryGui extends JDialog { - private final MemoryContextImpl context; - private final MemoryImpl memory; - private final PluginSettings settings; - private final Dialogs dialogs; private final TableMemory table; private final MemoryTableModel tableModel; @@ -58,21 +50,24 @@ public class MemoryGui extends JDialog { private final JTextField txtValueDec = new JTextField(); private final JTextField txtValueHex = new JTextField(); private final JTextField txtValueOct = new JTextField(); - private final JToggleButton btnAsciiMode = new JToggleButton(); private final LoadImageAction loadImageAction; private final DumpMemoryAction dumpMemoryAction; private final GotoAddressAction gotoAddressAction; private final FindSequenceAction findSequenceAction; + private final AsciiModeAction asciiModeAction; + private final EraseMemoryAction eraseMemoryAction; + private final SettingsAction settingsAction; public MemoryGui(JFrame parent, MemoryImpl memory, MemoryContextImpl context, PluginSettings settings, Dialogs dialogs) { super(parent); - this.context = Objects.requireNonNull(context); - this.memory = Objects.requireNonNull(memory); - this.settings = Objects.requireNonNull(settings); - this.dialogs = Objects.requireNonNull(dialogs); + Objects.requireNonNull(context); + Objects.requireNonNull(memory); + Objects.requireNonNull(settings); + Objects.requireNonNull(dialogs); + this.tableModel = new MemoryTableModel(context); this.table = new TableMemory(tableModel, paneMemory); @@ -84,6 +79,10 @@ public MemoryGui(JFrame parent, MemoryImpl memory, MemoryContextImpl context, Pl this.gotoAddressAction = new GotoAddressAction(dialogs, context, this::setPageFromAddress); this.findSequenceAction = new FindSequenceAction(dialogs, this::setPageFromAddress, tableModel, this::getCurrentAddress, this); + JToggleButton btnAsciiMode = new JToggleButton(); + this.asciiModeAction = new AsciiModeAction(tableModel, btnAsciiMode); + this.eraseMemoryAction = new EraseMemoryAction(tableModel, context); + this.settingsAction = new SettingsAction(dialogs, this, memory, context, table, settings); initComponents(); super.setLocationRelativeTo(parent); @@ -149,8 +148,6 @@ public void updateMemVal(int row, int column) { private void initComponents() { JToolBar toolBar = new JToolBar(); - JButton btnClean = new JButton(); - JButton btnSettings = new JButton(); JSplitPane splitPane = new JSplitPane(); JPanel jPanel2 = new JPanel(); JPanel jPanel3 = new JPanel(); @@ -182,36 +179,11 @@ private void initComponents() { toolBar.add(new ToolbarButton(gotoAddressAction)); toolBar.add(new ToolbarButton(findSequenceAction)); toolBar.addSeparator(); - - btnAsciiMode.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/ascii-mode.png"))); - btnAsciiMode.setToolTipText("Toggle ASCII mode..."); - btnAsciiMode.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - btnAsciiMode.setFocusable(false); - btnAsciiMode.setHorizontalTextPosition(SwingConstants.CENTER); - btnAsciiMode.setVerticalTextPosition(SwingConstants.BOTTOM); - btnAsciiMode.setSelected(false); - btnAsciiMode.addActionListener(this::btnSymbolModeActionPerformed); - toolBar.add(btnAsciiMode); + toolBar.add(new ToolbarButton(asciiModeAction)); toolBar.addSeparator(); - - btnClean.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/edit-clear.png"))); - btnClean.setToolTipText("Erase memory"); - btnClean.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - btnClean.setFocusable(false); - btnClean.setHorizontalTextPosition(SwingConstants.CENTER); - btnClean.setVerticalTextPosition(SwingConstants.BOTTOM); - btnClean.addActionListener(this::btnCleanActionPerformed); - toolBar.add(btnClean); + toolBar.add(new ToolbarButton(eraseMemoryAction)); toolBar.addSeparator(); - - btnSettings.setIcon(new ImageIcon(getClass().getResource("/net/emustudio/plugins/memory/bytemem/gui/preferences-system.png"))); - btnSettings.setToolTipText("Settings..."); - btnSettings.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - btnSettings.setFocusable(false); - btnSettings.setHorizontalTextPosition(SwingConstants.CENTER); - btnSettings.setVerticalTextPosition(SwingConstants.BOTTOM); - btnSettings.addActionListener(this::btnSettingsActionPerformed); - toolBar.add(btnSettings); + toolBar.add(new ToolbarButton(settingsAction)); splitPane.setDividerLocation(390); splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); @@ -425,19 +397,6 @@ private void initComponents() { pack(); } - private void btnCleanActionPerformed(ActionEvent evt) { - context.clear(); - tableModel.fireTableDataChanged(); - } - - private void btnSymbolModeActionPerformed(ActionEvent evt) { - tableModel.setAsciiMode(btnAsciiMode.isSelected()); - } - - private void btnSettingsActionPerformed(ActionEvent evt) { - new SettingsDialog(this, memory, context, table, settings, dialogs).setVisible(true); - } - private int getCurrentAddress() { return tableModel.getPage() * (tableModel.getRowCount() * tableModel.getColumnCount()); } diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/AsciiModeAction.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/AsciiModeAction.java new file mode 100644 index 000000000..da4b89784 --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/AsciiModeAction.java @@ -0,0 +1,42 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.bytemem.gui.actions; + +import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.util.Objects; + +public class AsciiModeAction extends AbstractAction { + private final static String ICON_FILE = "/net/emustudio/plugins/memory/bytemem/gui/ascii-mode.png"; + private final MemoryTableModel tableModel; + private final JToggleButton btnAsciiMode; + + public AsciiModeAction(MemoryTableModel tableModel, JToggleButton btnAsciiMode) { + super("Toggle ASCII mode", new ImageIcon(AsciiModeAction.class.getResource(ICON_FILE))); + this.tableModel = Objects.requireNonNull(tableModel); + this.btnAsciiMode = Objects.requireNonNull(btnAsciiMode); + } + + @Override + public void actionPerformed(ActionEvent e) { + tableModel.setAsciiMode(btnAsciiMode.isSelected()); + } +} diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/EraseMemoryAction.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/EraseMemoryAction.java new file mode 100644 index 000000000..06749d0fe --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/EraseMemoryAction.java @@ -0,0 +1,44 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.bytemem.gui.actions; + +import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; +import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.util.Objects; + +public class EraseMemoryAction extends AbstractAction { + private final static String ICON_FILE = "/net/emustudio/plugins/memory/bytemem/gui/edit-clear.png"; + private final MemoryTableModel tableModel; + private final MemoryContextImpl context; + + public EraseMemoryAction(MemoryTableModel tableModel, MemoryContextImpl context) { + super("Erase memory", new ImageIcon(EraseMemoryAction.class.getResource(ICON_FILE))); + this.tableModel = Objects.requireNonNull(tableModel); + this.context = Objects.requireNonNull(context); + } + + @Override + public void actionPerformed(ActionEvent e) { + context.clear(); + tableModel.fireTableDataChanged(); + } +} diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/SettingsAction.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/SettingsAction.java new file mode 100644 index 000000000..383e2e80e --- /dev/null +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/actions/SettingsAction.java @@ -0,0 +1,56 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.bytemem.gui.actions; + +import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.emulib.runtime.settings.PluginSettings; +import net.emustudio.plugins.memory.bytemem.MemoryContextImpl; +import net.emustudio.plugins.memory.bytemem.MemoryImpl; +import net.emustudio.plugins.memory.bytemem.gui.SettingsDialog; +import net.emustudio.plugins.memory.bytemem.gui.model.TableMemory; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.util.Objects; + +public class SettingsAction extends AbstractAction { + private final static String ICON_FILE = "/net/emustudio/plugins/memory/bytemem/gui/preferences-system.png"; + private final Dialogs dialogs; + private final JDialog parent; + private final MemoryContextImpl context; + private final MemoryImpl memory; + private final TableMemory table; + private final PluginSettings settings; + + public SettingsAction(Dialogs dialogs, JDialog parent, MemoryImpl memory, MemoryContextImpl context, + TableMemory table, PluginSettings settings) { + super("Erase memory", new ImageIcon(SettingsAction.class.getResource(ICON_FILE))); + this.memory = Objects.requireNonNull(memory); + this.context = Objects.requireNonNull(context); + this.table = Objects.requireNonNull(table); + this.settings = Objects.requireNonNull(settings); + this.dialogs = Objects.requireNonNull(dialogs); + this.parent = Objects.requireNonNull(parent); + } + + @Override + public void actionPerformed(ActionEvent e) { + new SettingsDialog(parent, memory, context, table, settings, dialogs).setVisible(true); + } +} From 142ab0cf0eca97f02f47f779103e3cc6d45196a2 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 19 Feb 2023 14:57:19 +0100 Subject: [PATCH 265/314] [#315] byte-mem: gui tiny refactoring --- .../plugins/memory/bytemem/gui/MemoryGui.java | 88 +++++++++---------- .../bytemem/gui/SelectBankAddressDialog.java | 4 +- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java index 40727d8ca..4761e3ca3 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java @@ -151,19 +151,19 @@ private void initComponents() { JSplitPane splitPane = new JSplitPane(); JPanel jPanel2 = new JPanel(); JPanel jPanel3 = new JPanel(); - JLabel jLabel1 = new JLabel(); - JLabel jLabel2 = new JLabel(); - JLabel jLabel3 = new JLabel(); - JLabel jLabel4 = new JLabel(); + JLabel lblPageNumber = new JLabel(); + JLabel lblPageFrom = new JLabel(); + JLabel lblMemoryBank = new JLabel(); + JLabel lblMemoryBankFrom = new JLabel(); JPanel jPanel4 = new JPanel(); - JLabel jLabel5 = new JLabel(); - JLabel jLabel6 = new JLabel(); + JLabel lblAddress = new JLabel(); + JLabel lblSymbol = new JLabel(); JSeparator jSeparator4 = new JSeparator(); - JLabel jLabel7 = new JLabel(); - JLabel jLabel8 = new JLabel(); - JLabel jLabel9 = new JLabel(); - JLabel jLabel10 = new JLabel(); - JLabel jLabel11 = new JLabel(); + JLabel lblValue = new JLabel(); + JLabel lblValueDec = new JLabel(); + JLabel lblValueHex = new JLabel(); + JLabel lblValueOct = new JLabel(); + JLabel lblValueBin = new JLabel(); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); @@ -191,14 +191,14 @@ private void initComponents() { jPanel3.setBorder(BorderFactory.createTitledBorder("Memory control")); - jLabel1.setText("Page number:"); - jLabel2.setText("/"); + lblPageNumber.setText("Page number:"); + lblPageFrom.setText("/"); lblPageCount.setFont(lblPageCount.getFont().deriveFont(lblPageCount.getFont().getStyle() | java.awt.Font.BOLD)); lblPageCount.setText("0"); - jLabel3.setText("Memory bank:"); - jLabel4.setText("/"); + lblMemoryBank.setText("Memory bank:"); + lblMemoryBankFrom.setText("/"); lblBanksCount.setText("0"); @@ -208,19 +208,19 @@ private void initComponents() { jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() - .addComponent(jLabel1) + .addComponent(lblPageNumber) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(spnPage, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel2) + .addComponent(lblPageFrom) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblPageCount) .addGap(54, 54, 54) - .addComponent(jLabel3) + .addComponent(lblMemoryBank) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(spnBank, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel4) + .addComponent(lblMemoryBankFrom) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblBanksCount) .addContainerGap(283, Short.MAX_VALUE)) @@ -230,59 +230,59 @@ private void initComponents() { .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) + .addComponent(lblPageNumber) .addComponent(spnPage, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel2) + .addComponent(lblPageFrom) .addComponent(lblPageCount) - .addComponent(jLabel3) + .addComponent(lblMemoryBank) .addComponent(spnBank, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel4) + .addComponent(lblMemoryBankFrom) .addComponent(lblBanksCount)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel4.setBorder(BorderFactory.createTitledBorder("Selected value")); - jLabel5.setText("Address:"); + lblAddress.setText("Address:"); txtAddress.setEditable(false); txtAddress.setHorizontalAlignment(JTextField.RIGHT); txtAddress.setText("0000"); - jLabel6.setText("Symbol:"); + lblSymbol.setText("Symbol:"); txtChar.setEditable(false); txtChar.setHorizontalAlignment(JTextField.RIGHT); jSeparator4.setOrientation(SwingConstants.VERTICAL); - jLabel7.setText("Value:"); + lblValue.setText("Value:"); txtValueDec.setEditable(false); txtValueDec.setHorizontalAlignment(JTextField.RIGHT); txtValueDec.setText("00"); txtValueDec.setToolTipText(""); - jLabel8.setText("(dec)"); + lblValueDec.setText("(dec)"); txtValueHex.setEditable(false); txtValueHex.setHorizontalAlignment(JTextField.RIGHT); txtValueHex.setText("00"); - jLabel9.setText("(hex)"); + lblValueHex.setText("(hex)"); txtValueOct.setEditable(false); txtValueOct.setHorizontalAlignment(JTextField.RIGHT); txtValueOct.setText("000"); - jLabel10.setText("(oct)"); + lblValueOct.setText("(oct)"); txtValueBin.setEditable(false); txtValueBin.setHorizontalAlignment(JTextField.RIGHT); txtValueBin.setText("0000 0000"); txtValueBin.setToolTipText(""); - jLabel11.setText("(bin)"); + lblValueBin.setText("(bin)"); GroupLayout jPanel4Layout = new GroupLayout(jPanel4); jPanel4.setLayout(jPanel4Layout); @@ -291,8 +291,8 @@ private void initComponents() { .addGroup(jPanel4Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel5) - .addComponent(jLabel6)) + .addComponent(lblAddress) + .addComponent(lblSymbol)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(txtChar, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE) @@ -300,15 +300,15 @@ private void initComponents() { .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(jSeparator4, GroupLayout.PREFERRED_SIZE, 13, GroupLayout.PREFERRED_SIZE) .addGap(2, 2, 2) - .addComponent(jLabel7) + .addComponent(lblValue) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(txtValueHex) .addComponent(txtValueDec, GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel8) - .addComponent(jLabel9)) + .addComponent(lblValueDec) + .addComponent(lblValueHex)) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(txtValueBin) @@ -316,10 +316,10 @@ private void initComponents() { .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel10)) + .addComponent(lblValueOct)) .addGroup(GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup() .addGap(7, 7, 7) - .addComponent(jLabel11))) + .addComponent(lblValueBin))) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel4Layout.setVerticalGroup( @@ -329,25 +329,25 @@ private void initComponents() { .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel7) + .addComponent(lblValue) .addComponent(txtValueDec, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel8) + .addComponent(lblValueDec) .addComponent(txtValueOct, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel10)) + .addComponent(lblValueOct)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(txtValueHex, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel9) + .addComponent(lblValueHex) .addComponent(txtValueBin, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel11))) + .addComponent(lblValueBin))) .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addGroup(jPanel4Layout.createSequentialGroup() .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5) + .addComponent(lblAddress) .addComponent(txtAddress, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel4Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel6) + .addComponent(lblSymbol) .addComponent(txtChar, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) .addComponent(jSeparator4))) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java index f27c066d5..b4f3a4bbc 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/SelectBankAddressDialog.java @@ -96,8 +96,8 @@ private void initComponents() { .addComponent(lblAddress)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(txtAddress, 64, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(txtBank, 64, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addComponent(txtAddress, 128, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(txtBank, 128, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) From ce2b80d86ae75ea3a1c401306c5d03fcedb12f29 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 19 Feb 2023 15:11:03 +0100 Subject: [PATCH 266/314] [#315] z80-cpu: fasten LD X,X --- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index 02c3289db..eeaa80d80 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -2681,7 +2681,7 @@ int I_CALL_NN() { } int I_LD_B_B() { - return I_LD_R_R(REG_B, REG_B); + return 4; } int I_LD_B_C() { @@ -2745,7 +2745,7 @@ int I_LD_C_B() { } int I_LD_C_C() { - return I_LD_R_R(REG_C, REG_C); + return 4; } int I_LD_C_D() { @@ -2809,7 +2809,7 @@ int I_LD_D_C() { } int I_LD_D_D() { - return I_LD_R_R(REG_D, REG_D); + return 4; } int I_LD_D_E() { @@ -2873,7 +2873,7 @@ int I_LD_E_D() { } int I_LD_E_E() { - return I_LD_R_R(REG_E, REG_E); + return 4; } int I_LD_E_H() { @@ -2937,7 +2937,7 @@ int I_LD_H_E() { } int I_LD_H_H() { - return I_LD_R_R(REG_H, REG_H); + return 4; } int I_LD_H_L() { @@ -3059,7 +3059,7 @@ int I_LD_L_H() { } int I_LD_L_L() { - return I_LD_R_R(REG_L, REG_L); + return 4; } int I_LD_L_A() { @@ -3181,7 +3181,7 @@ int I_LD_A_L() { } int I_LD_A_A() { - return I_LD_R_R(REG_A, REG_A); + return 4; } int I_LD_A_REF_HL() { From 5accf64a7760f15bd2f8cf6726a697bb2c7b232b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Wed, 22 Feb 2023 12:48:36 +0100 Subject: [PATCH 267/314] [#315, #260] z80-cpu: fixes --- .../plugins/cpu/zilogZ80/DispatchTables.java | 36 +- .../plugins/cpu/zilogZ80/EmulatorEngine.java | 462 ++++++++++-------- .../plugins/cpu/zilogZ80/Z80Tests.java | 4 +- 3 files changed, 269 insertions(+), 233 deletions(-) diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java index 60c7de252..db3dcc5aa 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/DispatchTables.java @@ -298,48 +298,48 @@ public class DispatchTables { DISPATCH_TABLE[0xFE] = lookup.findVirtual(EmulatorEngine.class, "I_CP_N", retInt); DISPATCH_TABLE[0xFF] = lookup.findVirtual(EmulatorEngine.class, "I_RST", retInt); - DISPATCH_TABLE_ED[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); - DISPATCH_TABLE_ED[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x40] = lookup.findVirtual(EmulatorEngine.class, "I_IN_B_REF_C", retInt); + DISPATCH_TABLE_ED[0x41] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_B", retInt); DISPATCH_TABLE_ED[0x42] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", retInt); DISPATCH_TABLE_ED[0x43] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_BC", retInt); DISPATCH_TABLE_ED[0x44] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x45] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); DISPATCH_TABLE_ED[0x46] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); DISPATCH_TABLE_ED[0x47] = lookup.findVirtual(EmulatorEngine.class, "I_LD_I_A", retInt); - DISPATCH_TABLE_ED[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); - DISPATCH_TABLE_ED[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x48] = lookup.findVirtual(EmulatorEngine.class, "I_IN_C_REF_C", retInt); + DISPATCH_TABLE_ED[0x49] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_C", retInt); DISPATCH_TABLE_ED[0x4A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", retInt); DISPATCH_TABLE_ED[0x4B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", retInt); DISPATCH_TABLE_ED[0x4C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x4D] = lookup.findVirtual(EmulatorEngine.class, "I_RETI", retInt); DISPATCH_TABLE_ED[0x4E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); DISPATCH_TABLE_ED[0x4F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_R_A", retInt); - DISPATCH_TABLE_ED[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); - DISPATCH_TABLE_ED[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x50] = lookup.findVirtual(EmulatorEngine.class, "I_IN_D_REF_C", retInt); + DISPATCH_TABLE_ED[0x51] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_D", retInt); DISPATCH_TABLE_ED[0x52] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", retInt); DISPATCH_TABLE_ED[0x53] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_NN_DE", retInt); DISPATCH_TABLE_ED[0x54] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x55] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); DISPATCH_TABLE_ED[0x56] = lookup.findVirtual(EmulatorEngine.class, "I_IM_1", retInt); DISPATCH_TABLE_ED[0x57] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_I", retInt); - DISPATCH_TABLE_ED[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); - DISPATCH_TABLE_ED[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x58] = lookup.findVirtual(EmulatorEngine.class, "I_IN_E_REF_C", retInt); + DISPATCH_TABLE_ED[0x59] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_E", retInt); DISPATCH_TABLE_ED[0x5A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", retInt); DISPATCH_TABLE_ED[0x5B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", retInt); DISPATCH_TABLE_ED[0x5C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x5D] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); DISPATCH_TABLE_ED[0x5E] = lookup.findVirtual(EmulatorEngine.class, "I_IM_2", retInt); DISPATCH_TABLE_ED[0x5F] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_R", retInt); - DISPATCH_TABLE_ED[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); - DISPATCH_TABLE_ED[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x60] = lookup.findVirtual(EmulatorEngine.class, "I_IN_H_REF_C", retInt); + DISPATCH_TABLE_ED[0x61] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_H", retInt); DISPATCH_TABLE_ED[0x62] = lookup.findVirtual(EmulatorEngine.class, "I_SBC_HL_RP", retInt); DISPATCH_TABLE_ED[0x63] = lookup.findVirtual(EmulatorEngine.class, "I_ED_LD_REF_NN_HL", retInt); DISPATCH_TABLE_ED[0x64] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x65] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); DISPATCH_TABLE_ED[0x66] = lookup.findVirtual(EmulatorEngine.class, "I_IM_0", retInt); DISPATCH_TABLE_ED[0x67] = lookup.findVirtual(EmulatorEngine.class, "I_RRD", retInt); - DISPATCH_TABLE_ED[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); - DISPATCH_TABLE_ED[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x68] = lookup.findVirtual(EmulatorEngine.class, "I_IN_L_REF_C", retInt); + DISPATCH_TABLE_ED[0x69] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_L", retInt); DISPATCH_TABLE_ED[0x6A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", retInt); DISPATCH_TABLE_ED[0x6B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", retInt); DISPATCH_TABLE_ED[0x6C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); @@ -353,8 +353,8 @@ public class DispatchTables { DISPATCH_TABLE_ED[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); DISPATCH_TABLE_ED[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_RETN", retInt); DISPATCH_TABLE_ED[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_IM_1", retInt); - DISPATCH_TABLE_ED[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_IN_R_REF_C", retInt); - DISPATCH_TABLE_ED[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_R", retInt); + DISPATCH_TABLE_ED[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_IN_A_REF_C", retInt); + DISPATCH_TABLE_ED[0x79] = lookup.findVirtual(EmulatorEngine.class, "I_OUT_REF_C_A", retInt); DISPATCH_TABLE_ED[0x7A] = lookup.findVirtual(EmulatorEngine.class, "I_ADC_HL_RP", retInt); DISPATCH_TABLE_ED[0x7B] = lookup.findVirtual(EmulatorEngine.class, "I_LD_RP_REF_NN", retInt); DISPATCH_TABLE_ED[0x7C] = lookup.findVirtual(EmulatorEngine.class, "I_NEG", retInt); @@ -750,8 +750,8 @@ public class DispatchTables { DISPATCH_TABLE_DD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_C", retInt); DISPATCH_TABLE_DD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_D", retInt); DISPATCH_TABLE_DD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_E", retInt); - DISPATCH_TABLE_DD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_IXH", retInt); - DISPATCH_TABLE_DD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_IXL", retInt); + DISPATCH_TABLE_DD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_H", retInt); + DISPATCH_TABLE_DD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_L", retInt); DISPATCH_TABLE_DD[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_HALT", retInt); DISPATCH_TABLE_DD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IX_D_A", retInt); DISPATCH_TABLE_DD[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_B", retInt); @@ -1007,8 +1007,8 @@ public class DispatchTables { DISPATCH_TABLE_FD[0x71] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_C", retInt); DISPATCH_TABLE_FD[0x72] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_D", retInt); DISPATCH_TABLE_FD[0x73] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_E", retInt); - DISPATCH_TABLE_FD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_IYH", retInt); - DISPATCH_TABLE_FD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_IYL", retInt); + DISPATCH_TABLE_FD[0x74] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_H", retInt); + DISPATCH_TABLE_FD[0x75] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_L", retInt); DISPATCH_TABLE_FD[0x76] = lookup.findVirtual(EmulatorEngine.class, "I_HALT", retInt); DISPATCH_TABLE_FD[0x77] = lookup.findVirtual(EmulatorEngine.class, "I_LD_REF_IY_D_A", retInt); DISPATCH_TABLE_FD[0x78] = lookup.findVirtual(EmulatorEngine.class, "I_LD_A_B", retInt); diff --git a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java index eeaa80d80..c78da7146 100644 --- a/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java +++ b/plugins/cpu/z80-cpu/src/main/java/net/emustudio/plugins/cpu/zilogZ80/EmulatorEngine.java @@ -49,8 +49,12 @@ // TODO: set frequency runtime public class EmulatorEngine implements CpuEngine { public static final int REG_A = 7, REG_B = 0, REG_C = 1, REG_D = 2, REG_E = 3, REG_H = 4, REG_L = 5; + public static final int FLAG_S = 0x80, FLAG_Z = 0x40, FLAG_Y = 0x20, FLAG_H = 0x10, FLAG_X = 0x8, FLAG_PV = 0x4, FLAG_N = 0x02, FLAG_C = 0x1; public static final int FLAG_SZP = FLAG_S | FLAG_Z | FLAG_PV; + private static final int FLAG_SZC = FLAG_S | FLAG_Z | FLAG_C; + private static final int FLAG_XY = FLAG_X | FLAG_Y; + private final static Logger LOGGER = LoggerFactory.getLogger(EmulatorEngine.class); private final static int[] CONDITION = new int[]{ FLAG_Z, FLAG_Z, FLAG_C, FLAG_C, FLAG_PV, FLAG_PV, FLAG_S, FLAG_S @@ -162,7 +166,6 @@ public void requestNonMaskableInterrupt() { void reset(int startPos) { IX = IY = 0; SP = 0xFFFF; - flags = 0xFF; I = R = 0; memptr = 0; Q = lastQ = 0; @@ -379,27 +382,22 @@ private void putreg(int reg, int val) { } } - private void putpair(int reg, int val, boolean reg3IsSP) { + private void putpair(int reg, int val) { int high = (val >>> 8) & 0xFF; int low = val & 0xFF; int index = reg * 2; if (reg == 3) { - if (reg3IsSP) { - SP = val; - } else { - regs[REG_A] = high; - flags = (short) low; - } + SP = val; } else { regs[index] = high; regs[index + 1] = low; } } - private int getpair(int reg, boolean reg3IsSP) { + private int getpair(int reg) { if (reg == 3) { - return reg3IsSP ? SP : (regs[REG_A] << 8 | (flags & 0xFF)); + return SP; } int index = reg * 2; return regs[index] << 8 | regs[index + 1]; @@ -437,9 +435,9 @@ int I_NOP() { } int I_LD_REF_BC_A() { - memory.write(regs[REG_B] << 8 | regs[REG_C], (byte) regs[REG_A]); - memptr = (regs[REG_A] << 8) | 1; - // Note for *BM1: MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = 0 + int bc = regs[REG_B] << 8 | regs[REG_C]; + memory.write(bc, (byte) regs[REG_A]); + memptr = (regs[REG_A] << 8) | ((bc + 1) & 0xFF); return 7; } @@ -917,6 +915,7 @@ int I_RET_CC() { int cc = (lastOpcode >>> 3) & 7; if ((flags & CONDITION[cc]) == CONDITION_VALUES[cc]) { PC = readWord(SP); + memptr = PC; SP = (SP + 2) & 0xffff; return 11; } @@ -1301,7 +1300,7 @@ int I_AND_A() { } int I_AND(int value) { - regs[REG_A] = (regs[REG_A] & value) & 0xFF; + regs[REG_A] = regs[REG_A] & value; flags = TABLE_SZ[regs[REG_A]] | FLAG_H | PARITY_TABLE[regs[REG_A]] | TABLE_XY[regs[REG_A]]; Q = flags; return 4; @@ -1660,10 +1659,9 @@ int I_DJNZ() { } int I_LD_REF_DE_A() { - memory.write(getpair(1, false), (byte) regs[REG_A]); - memptr = (regs[REG_A] << 8) | 2; - //_memPtr = A * 256 + ((DE + 1) & 0xFF); - // Note for *BM1: MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = 0 + int de = regs[REG_D] << 8 | regs[REG_E]; + memory.write(de, (byte) regs[REG_A]); + memptr = (regs[REG_A] << 8) | ((de + 1) & 0xFF); return 7; } @@ -1679,7 +1677,7 @@ int I_RLA() { int I_LD_A_REF_DE() { int de = regs[REG_D] << 8 | regs[REG_E]; regs[REG_A] = memory.read(de) & 0xFF; - memptr = de; + memptr = (de + 1) & 0xFFFF; return 7; } @@ -1723,13 +1721,13 @@ int I_CPL() { regs[REG_A] = (~regs[REG_A]) & 0xFF; flags = (flags & (FLAG_SZP | FLAG_C)) | FLAG_H | FLAG_N - | (regs[REG_A] & (FLAG_X | FLAG_Y)); + | (regs[REG_A] & FLAG_XY); Q = flags; return 4; } int I_SCF() { - flags = (flags & FLAG_SZP) | (((lastQ ^ flags) | regs[REG_A]) & (FLAG_X | FLAG_Y)) | FLAG_C; + flags = (flags & FLAG_SZP) | (((lastQ ^ flags) | regs[REG_A]) & FLAG_XY) | FLAG_C; Q = flags; return 4; } @@ -1737,7 +1735,7 @@ int I_SCF() { int I_CCF() { flags = (flags & FLAG_SZP) | ((flags & FLAG_C) == 0 ? FLAG_C : FLAG_H) - | (((lastQ ^ flags) | regs[REG_A]) & (FLAG_X | FLAG_Y)); + | (((lastQ ^ flags) | regs[REG_A]) & FLAG_XY); Q = flags; return 4; } @@ -1826,24 +1824,76 @@ int I_EI() { return 4; } - int I_IN_R_REF_C() { - int reg = (lastOpcode >>> 3) & 0x7; - putreg(reg, context.readIO((regs[REG_B] << 8) | regs[REG_C])); - memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; - flags = (flags & FLAG_C) | TABLE_SZ[regs[reg]] | PARITY_TABLE[regs[reg]] | TABLE_XY[regs[reg]]; + int I_IN_B_REF_C() { + return I_IN_R_REF_C(REG_B); + } + + int I_IN_C_REF_C() { + return I_IN_R_REF_C(REG_C); + } + + int I_IN_D_REF_C() { + return I_IN_R_REF_C(REG_D); + } + + int I_IN_E_REF_C() { + return I_IN_R_REF_C(REG_E); + } + + int I_IN_H_REF_C() { + return I_IN_R_REF_C(REG_H); + } + + int I_IN_L_REF_C() { + return I_IN_R_REF_C(REG_L); + } + + int I_IN_A_REF_C() { + return I_IN_R_REF_C(REG_A); + } + + int I_IN_R_REF_C(int reg) { + int bc = (regs[REG_B] << 8) | regs[REG_C]; + memptr = (bc + 1) & 0xFFFF; + int tmp = context.readIO(bc) & 0xFF; + regs[reg] = tmp; + flags = TABLE_SZ[tmp] | TABLE_XY[tmp] | PARITY_TABLE[tmp] | (flags & FLAG_C); Q = flags; return 12; } - int I_OUT_REF_C_R() { - int reg = (lastOpcode >>> 3) & 0x7; - memptr = (((regs[REG_B] << 8) | regs[REG_C]) + 1) & 0xFFFF; - context.writeIO((regs[REG_B] << 8) | regs[REG_C], (byte) getreg(reg)); + + int I_OUT_REF_C_B() { + return I_OUT_REF_C_R(regs[REG_B]); + } + int I_OUT_REF_C_C() { + return I_OUT_REF_C_R(regs[REG_C]); + } + int I_OUT_REF_C_D() { + return I_OUT_REF_C_R(regs[REG_D]); + } + int I_OUT_REF_C_E() { + return I_OUT_REF_C_R(regs[REG_E]); + } + int I_OUT_REF_C_H() { + return I_OUT_REF_C_R(regs[REG_H]); + } + int I_OUT_REF_C_L() { + return I_OUT_REF_C_R(regs[REG_L]); + } + int I_OUT_REF_C_A() { + return I_OUT_REF_C_R(regs[REG_A]); + } + int I_OUT_REF_C_R(int reg) { + memptr = (regs[REG_B] << 8) | regs[REG_C]; + context.writeIO(memptr, (byte) reg); + memptr++; return 12; } + int I_SBC_HL_RP() { - int rp = getpair((lastOpcode >>> 4) & 0x03, true); + int rp = getpair((lastOpcode >>> 4) & 0x03); int hl = ((regs[REG_H] << 8) | regs[REG_L]) & 0xFFFF; memptr = (hl + 1) & 0xFFFF; int res = hl - rp - (flags & FLAG_C); @@ -1861,7 +1911,7 @@ int I_SBC_HL_RP() { } int I_ADC_HL_RP() { - int rp = getpair((lastOpcode >>> 4) & 0x03, true); + int rp = getpair((lastOpcode >>> 4) & 0x03); int hl = (regs[REG_H] << 8 | regs[REG_L]) & 0xFFFF; memptr = (hl + 1) & 0xFFFF; int res = hl + rp + (flags & FLAG_C); @@ -1887,6 +1937,7 @@ int I_NEG() { int I_RETN() { IFF[0] = IFF[1]; PC = readWord(SP); + memptr = PC; SP = (SP + 2) & 0xffff; return 14; } @@ -1965,76 +2016,74 @@ int I_RLD() { } int I_IN_REF_C() { - int tmp = context.readIO((regs[REG_B] << 8) | regs[REG_C]) & 0xFF; - flags = TABLE_SZ[tmp] | PARITY_TABLE[tmp] | (flags & FLAG_C) | TABLE_XY[tmp]; + int bc = (regs[REG_B] << 8) | regs[REG_C]; + memptr = (bc + 1) & 0xFFFF; + int io = context.readIO(bc) & 0xFF; + flags = TABLE_SZ[io] | PARITY_TABLE[io] | (flags & FLAG_C) | TABLE_XY[io]; + Q = flags; return 12; } int I_OUT_REF_C_0() { - context.writeIO((regs[REG_B] << 8) | regs[REG_C], (byte) 0); + int bc = (regs[REG_B] << 8) | regs[REG_C]; + memptr = (bc + 1) & 0xFFFF; + context.writeIO(bc, (byte) 0); return 12; } int I_CPI() { - int a, n, z, f, hl, bc; - a = regs[REG_A]; - hl = (regs[REG_H] << 8) | regs[REG_L]; - bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; - - n = memory.read(hl) & 0xFF; - z = a - n; - - hl = (hl + 1) & 0xFFFF; + int a = regs[REG_A]; + int hl = (regs[REG_H] << 8) | regs[REG_L]; + int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; + int n = memory.read(hl++) & 0xFF; + int z = a - n; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - f = (a ^ n ^ z) & FLAG_H; - + int f = (a ^ n ^ z) & FLAG_H; n = z - (f >> 4); f |= (n << 4) & FLAG_Y; f |= n & FLAG_X; - f |= TABLE_SZ[z & 0xFF]; f |= (bc != 0) ? FLAG_PV : 0; flags = f | FLAG_N | (flags & FLAG_C); Q = flags; + memptr = (memptr + 1) & 0xFFFF; return 16; } int I_CPIR() { - int bc = (regs[REG_B] << 8) | regs[REG_C]; + int a = regs[REG_A]; int hl = (regs[REG_H] << 8) | regs[REG_L]; - - int n = memory.read(hl) & 0xFF; - int z = regs[REG_A] - n; - - hl = (hl + 1) & 0xFFFF; - int cycles; - if ((--bc) != 0 && (z != 0)) { - cycles = 21; - PC = (PC - 2) & 0xFFFF; - } else { - cycles = 16; - } + int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; + int n = memory.read(hl++) & 0xFF; + int z = a - n; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; - int f = (regs[REG_A] ^ n ^ z) & FLAG_H; - n = z - (f >>> 4); - f |= ((n << 4) & FLAG_Y); - f |= (n & FLAG_X); + int f = (a ^ n ^ z) & FLAG_H; + n = z - (f >> 4); + f |= (n << 4) & FLAG_Y; + f |= n & FLAG_X; f |= TABLE_SZ[z & 0xFF]; f |= (bc != 0) ? FLAG_PV : 0; - flags = f | FLAG_N | (flags & FLAG_C); Q = flags; - return cycles; + memptr = (memptr + 1) & 0xFFFF; + + if (bc != 0 && (z != 0)) { + PC = (PC - 2) & 0xFFFF; + memptr = (PC + 1) & 0xFFFF; + flags = ((flags & (~FLAG_XY)) | ((PC >>> 8) & FLAG_XY)) & 0xFF; + return 21; + } + return 16; } int I_CPD() { @@ -2042,8 +2091,7 @@ int I_CPD() { int hl = (regs[REG_H] << 8) | regs[REG_L]; int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; - int n = memory.read(hl) & 0xFF; - hl = (hl - 1) & 0xFFFF; + int n = memory.read(hl--) & 0xFF; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; @@ -2052,61 +2100,57 @@ int I_CPD() { int z = a - n; int f = (a ^ n ^ z) & FLAG_H; - - n = z - (f >> 4); + n = z - (f >>> 4); f |= (n << 4) & FLAG_Y; f |= n & FLAG_X; - f |= TABLE_SZ[z & 0xFF]; f |= (bc != 0) ? FLAG_PV : 0; flags = f | FLAG_N | (flags & FLAG_C); Q = flags; + memptr = (memptr - 1) & 0xFFFF; return 16; } int I_CPDR() { int a = regs[REG_A]; - int bc = (regs[REG_B] << 8) | regs[REG_C]; int hl = (regs[REG_H] << 8) | regs[REG_L]; + int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; - int n = memory.read(hl) & 0xFF; - int z = a - n; - - hl = (hl - 1) & 0xFFFF; - int cycles; - if ((--bc) != 0 && (z != 0)) { - cycles = 21; - PC = (PC - 2) & 0xFFFF; - } else { - cycles = 16; - } + int n = memory.read(hl--) & 0xFF; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_B] = (bc >>> 8) & 0xFF; regs[REG_C] = bc & 0xFF; + int z = a - n; int f = (a ^ n ^ z) & FLAG_H; n = z - (f >>> 4); - f |= ((n << 4) & FLAG_Y); - f |= (n & FLAG_X); + f |= (n << 4) & FLAG_Y; + f |= n & FLAG_X; f |= TABLE_SZ[z & 0xFF]; f |= (bc != 0) ? FLAG_PV : 0; - flags = f | FLAG_N | (flags & FLAG_C); Q = flags; - return cycles; + memptr = (memptr - 1) & 0xFFFF; + + if (bc != 0 && (z != 0)) { + PC = (PC - 2) & 0xFFFF; + memptr = (PC + 1) & 0xFFFF; + flags = ((flags & (~FLAG_XY)) | ((PC >>> 8) & FLAG_XY)) & 0xFF; + return 21; + } + return 16; } int I_LDD() { + int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; int hl = (regs[REG_H] << 8) | regs[REG_L]; int de = (regs[REG_D] << 8) | regs[REG_E]; byte io = memory.read(hl--); memory.write(de--, io); - int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; - regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_D] = (de >>> 8) & 0xFF; @@ -2116,55 +2160,52 @@ int I_LDD() { int result = regs[REG_A] + io; - flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | + flags = (flags & FLAG_SZC) | ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); Q = flags; return 16; } int I_LDDR() { - int bc = (regs[REG_B] << 8) | regs[REG_C]; + int bc = (((regs[REG_B] << 8) | regs[REG_C]) - 1) & 0xFFFF; int de = (regs[REG_D] << 8) | regs[REG_E]; int hl = (regs[REG_H] << 8) | regs[REG_L]; - byte value = memory.read(hl); - memory.write(de, value); - - bc = (bc - 1) & 0xFFFF; - regs[REG_B] = (bc >>> 8) & 0xFF; - regs[REG_C] = bc & 0xFF; + byte io = memory.read(hl--); + memory.write(de--, io); - hl = (hl - 1) & 0xFFFF; - de = (de - 1) & 0xFFFF; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_D] = (de >>> 8) & 0xFF; regs[REG_E] = de & 0xFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; + + int result = regs[REG_A] + io; + + flags = (flags & FLAG_SZC) | + ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); + Q = flags; // https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags#interrupted-block-instructions - flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | (bc != 0 ? FLAG_PV : 0); if (bc != 0) { PC = (PC - 2) & 0xFFFF; memptr = (PC + 1) & 0xFFFF; - flags |= TABLE_XY[PC >>> 8]; - Q = flags; + flags = ((flags & (~FLAG_XY)) | ((PC >>> 8) & FLAG_XY)) & 0xFF; return 21; } - - value += regs[REG_A]; - flags |= (value & FLAG_X) | ((value & 0x02) != 0 ? FLAG_Y : 0); - Q = flags; return 16; } int I_LDI() { + int bc = (regs[REG_B] << 8) | regs[REG_C]; int hl = (regs[REG_H] << 8) | regs[REG_L]; int de = (regs[REG_D] << 8) | regs[REG_E]; byte io = memory.read(hl++); memory.write(de++, io); - int bc = ((((regs[REG_B] << 8) | regs[REG_C]) & 0xFFFF) - 1) & 0xFFFF; + bc = (bc - 1) & 0xFFFF; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; @@ -2175,7 +2216,7 @@ int I_LDI() { int result = regs[REG_A] + (io & 0xFF); - flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | + flags = (flags & FLAG_SZC) | ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); Q = flags; return 16; @@ -2186,94 +2227,89 @@ int I_LDIR() { int de = (regs[REG_D] << 8) | regs[REG_E]; int hl = (regs[REG_H] << 8) | regs[REG_L]; - byte value = memory.read(hl); - memory.write(de, value); + byte io = memory.read(hl++); + memory.write(de++, io); bc = (bc - 1) & 0xFFFF; - regs[REG_B] = (bc >>> 8) & 0xFF; - regs[REG_C] = bc & 0xFF; - hl = (hl + 1) & 0xFFFF; - de = (de + 1) & 0xFFFF; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_D] = (de >>> 8) & 0xFF; regs[REG_E] = de & 0xFF; + regs[REG_B] = (bc >>> 8) & 0xFF; + regs[REG_C] = bc & 0xFF; + + int result = regs[REG_A] + (io & 0xFF); + + flags = (flags & FLAG_SZC) | + ((result << 4) & FLAG_Y) | (result & FLAG_X) | (bc != 0 ? FLAG_PV : 0); + Q = flags; // https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags#interrupted-block-instructions - flags = (flags & (FLAG_S | FLAG_Z | FLAG_C)) | (bc != 0 ? FLAG_PV : 0); if (bc != 0) { PC = (PC - 2) & 0xFFFF; memptr = (PC + 1) & 0xFFFF; - flags |= TABLE_XY[PC >>> 8]; - Q = flags; + flags = (flags & (~FLAG_XY) | ((PC >>> 8) & FLAG_XY)) & 0xFF; return 21; } - - value += regs[REG_A]; - flags |= (value & FLAG_X) | ((value & 0x02) != 0 ? FLAG_Y : 0); - Q = flags; return 16; } int I_INI() { - int bc = (regs[REG_B] << 8) | regs[REG_C]; - byte value = context.readIO(bc); int hl = (regs[REG_H] << 8) | regs[REG_L]; - memory.write(hl, value); + int bc = (regs[REG_B] << 8) | regs[REG_C]; + byte io = context.readIO(bc); + memory.write(hl++, io); - hl++; int decB = (regs[REG_B] - 1) & 0xFF; regs[REG_B] = decB; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; - memptr = (bc + 1) & 0xFFFF; // from zxpoly - int tmp = (value + regs[REG_C] + 1) & 0xFF; - flags = ((value & 0x80) >>> 6) // N - | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) - | TABLE_SZ[regs[REG_B]] - | TABLE_XY[regs[REG_B]] + int tmp = (io + regs[REG_C] + 1) & 0xFF; + flags = ((io & 0x80) >>> 6) // N + | (tmp < (io & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[decB] + | TABLE_XY[decB] | PARITY_TABLE[(tmp & 7) ^ decB]; Q = flags; + memptr = (bc + 1) & 0xFFFF; return 16; } int I_INIR() { - int bc = (regs[REG_B] << 8) | regs[REG_C]; int hl = (regs[REG_H] << 8) | regs[REG_L]; + int bc = (regs[REG_B] << 8) | regs[REG_C]; + byte io = context.readIO(bc); + memory.write(hl++, io); - byte value = context.readIO(bc); - memory.write(hl, value); - - hl = (hl + 1) & 0xFFFF; int decB = (regs[REG_B] - 1) & 0xFF; regs[REG_B] = decB; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; - memptr = (bc + 1) & 0xFFFF; // from zxpoly - int tmp = (value + regs[REG_C] + 1) & 0xFF; - flags = ((value & 0x80) >>> 6) // N - | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) - | TABLE_SZ[regs[REG_B]] - | TABLE_XY[regs[REG_B]] + int tmp = (io + regs[REG_C] + 1) & 0xFF; + flags = ((io & 0x80) >>> 6) // N + | (tmp < (io & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[decB] + | TABLE_XY[decB] | PARITY_TABLE[(tmp & 7) ^ decB]; Q = flags; + memptr = (bc + 1) & 0xFFFF; if (decB == 0) { return 16; } PC = (PC - 2) & 0xFFFF; - flags = (flags & ~(FLAG_X | FLAG_Y)) | ((PC >>> 8) & (FLAG_X | FLAG_Y)); + flags = ((flags & ~FLAG_XY) | ((PC >>> 8) & FLAG_XY)) & 0xFF; int flagP = flags & FLAG_PV; int flagH = flags & FLAG_H; if ((flags & FLAG_C) == FLAG_C) { - if ((value & 0x80) == 0) { + if ((io & 0x80) == 0) { flagP = flagP ^ PARITY_TABLE[(decB + 1) & 0x7] ^ FLAG_PV; flagH = (decB & 0x0F) == 0x0F ? FLAG_H : 0; } else { @@ -2283,69 +2319,65 @@ int I_INIR() { } else { flagP = flagP ^ PARITY_TABLE[decB & 0x07] ^ FLAG_PV; } - flags = ((flags & ~(FLAG_PV | FLAG_H)) | flagP | flagH); + flags = ((flags & ~(FLAG_PV | FLAG_H)) | flagP | flagH) & 0xFF; return 21; } int I_IND() { - int bc = (regs[REG_B] << 8) | regs[REG_C]; - byte value = context.readIO(bc); int hl = (regs[REG_H] << 8) | regs[REG_L]; - memory.write(hl, value); + int bc = (regs[REG_B] << 8) | regs[REG_C]; + byte io = context.readIO(bc); + memory.write(hl--, io); - hl = (hl - 1) & 0xFFFF; int decB = (regs[REG_B] - 1) & 0xFF; regs[REG_B] = decB; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; - memptr = (bc - 1) & 0xFFFF; // from zxpoly - int tmp = (value + regs[REG_C] - 1) & 0xFF; - flags = ((value & 0x80) >>> 6) // N - | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) - | TABLE_SZ[regs[REG_B]] - | TABLE_XY[regs[REG_B]] + int tmp = (io + regs[REG_C] - 1) & 0xFF; + flags = ((io & 0x80) >>> 6) // N + | (tmp < (io & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[decB] + | TABLE_XY[decB] | PARITY_TABLE[(tmp & 7) ^ decB]; - Q = flags; + memptr = (bc + 1) & 0xFFFF; return 16; } int I_INDR() { - int bc = (regs[REG_B] << 8) | regs[REG_C]; int hl = (regs[REG_H] << 8) | regs[REG_L]; + int bc = (regs[REG_B] << 8) | regs[REG_C]; + byte io = context.readIO(bc); + memory.write(hl--, io); - byte value = context.readIO(bc); - memory.write(hl, value); - - hl = (hl - 1) & 0xFFFF; int decB = (regs[REG_B] - 1) & 0xFF; regs[REG_B] = decB; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; - memptr = (bc - 1) & 0xFFFF; // from zxpoly - int tmp = (value + regs[REG_C] - 1) & 0xFF; - flags = ((value & 0x80) >>> 6) // N - | (tmp < (value & 0xFF) ? (FLAG_H | FLAG_C) : 0) - | TABLE_SZ[regs[REG_B]] - | TABLE_XY[regs[REG_B]] + int tmp = (io + regs[REG_C] - 1) & 0xFF; + flags = ((io & 0x80) >>> 6) // N + | (tmp < (io & 0xFF) ? (FLAG_H | FLAG_C) : 0) + | TABLE_SZ[decB] + | TABLE_XY[decB] | PARITY_TABLE[(tmp & 7) ^ decB]; Q = flags; + memptr = (bc + 1) & 0xFFFF; if (decB == 0) { return 16; } PC = (PC - 2) & 0xFFFF; - flags = (flags & ~(FLAG_X | FLAG_Y)) | ((PC >>> 8) & (FLAG_X | FLAG_Y)); + flags = ((flags & ~FLAG_XY) | ((PC >>> 8) & FLAG_XY)) & 0xFF; int flagP = flags & FLAG_PV; int flagH = flags & FLAG_H; if ((flags & FLAG_C) == FLAG_C) { - if ((value & 0x80) == 0) { + if ((io & 0x80) == 0) { flagP = flagP ^ PARITY_TABLE[(decB + 1) & 0x7] ^ FLAG_PV; flagH = (decB & 0x0F) == 0x0F ? FLAG_H : 0; } else { @@ -2355,7 +2387,7 @@ int I_INDR() { } else { flagP = flagP ^ PARITY_TABLE[decB & 0x07] ^ FLAG_PV; } - flags = ((flags & ~(FLAG_PV | FLAG_H)) | flagP | flagH); + flags = ((flags & ~(FLAG_PV | FLAG_H)) | flagP | flagH) & 0xFF; return 21; } @@ -2412,7 +2444,7 @@ int I_OTIR() { return 16; } PC = (PC - 2) & 0xFFFF; - flags = (flags & ~(FLAG_X | FLAG_Y)) | ((PC >>> 8) & (FLAG_X | FLAG_Y)); + flags = (flags & ~FLAG_XY) | ((PC >>> 8) & FLAG_XY); int flagP = flags & FLAG_PV; int flagH = flags & FLAG_H; @@ -2434,17 +2466,14 @@ int I_OTIR() { int I_OUTD() { int hl = (regs[REG_H] << 8) | regs[REG_L]; - byte value = memory.read(hl); - int B = regs[REG_B]; - int decB = (B - 1) & 0xFF; + byte value = memory.read(hl--); + int decB = (regs[REG_B] - 1) & 0xFF; context.writeIO((decB << 8) | regs[REG_C], value); - hl--; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_B] = decB; - memptr = (((decB << 8) | regs[REG_C]) + 1) & 0xFFFF; // from zxpoly int tmp = (value + regs[REG_L]) & 0xFF; @@ -2454,22 +2483,20 @@ int I_OUTD() { | TABLE_XY[decB] | PARITY_TABLE[(tmp & 7) ^ decB]; Q = flags; + memptr = (((decB << 8) | regs[REG_C]) - 1) & 0xFFFF; return 16; } int I_OTDR() { int hl = (regs[REG_H] << 8) | regs[REG_L]; - byte value = memory.read(hl); - int B = regs[REG_B]; - int decB = (B - 1) & 0xFF; + byte value = memory.read(hl--); + int decB = (regs[REG_B] - 1) & 0xFF; context.writeIO((decB << 8) | regs[REG_C], value); - hl--; regs[REG_H] = (hl >>> 8) & 0xFF; regs[REG_L] = hl & 0xFF; regs[REG_B] = decB; - memptr = (((decB << 8) | regs[REG_C]) + 1) & 0xFFFF; // from zxpoly int tmp = (value + regs[REG_L]) & 0xFF; @@ -2479,13 +2506,14 @@ int I_OTDR() { | TABLE_XY[decB] | PARITY_TABLE[(tmp & 7) ^ decB]; Q = flags; + memptr = (((decB << 8) | regs[REG_C]) - 1) & 0xFFFF; if (decB == 0) { return 16; } PC = (PC - 2) & 0xFFFF; - flags = (flags & ~(FLAG_X | FLAG_Y)) | ((PC >>> 8) & (FLAG_X | FLAG_Y)); + flags = ((flags & (~FLAG_XY)) | ((PC >>> 8) & FLAG_XY)) & 0xFF; int flagP = flags & FLAG_PV; int flagH = flags & FLAG_H; @@ -2501,7 +2529,7 @@ int I_OTDR() { } else { flagP = flagP ^ PARITY_TABLE[decB & 0x07] ^ FLAG_PV; } - flags = ((flags & ~(FLAG_PV | FLAG_H)) | flagP | flagH); + flags = ((flags & ~(FLAG_PV | FLAG_H)) | flagP | flagH) & 0xFF; return 21; } @@ -2512,6 +2540,7 @@ int I_LD_REF_NN_BC() { writeWord(addr, (regs[REG_B] << 8) | regs[REG_C]); return 20; } + int I_LD_REF_NN_DE() { int addr = readWord(PC); memptr = (addr + 1) & 0xFFFF; @@ -2519,6 +2548,7 @@ int I_LD_REF_NN_DE() { writeWord(addr, (regs[REG_D] << 8) | regs[REG_E]); return 20; } + int I_LD_REF_NN_HL() { int addr = readWord(PC); memptr = (addr + 1) & 0xFFFF; @@ -2526,9 +2556,11 @@ int I_LD_REF_NN_HL() { writeWord(addr, (regs[REG_H] << 8) | regs[REG_L]); return 16; } + int I_ED_LD_REF_NN_HL() { return I_LD_REF_NN_HL() + 4; } + int I_LD_REF_NN_SP() { int addr = readWord(PC); memptr = (addr + 1) & 0xFFFF; @@ -2536,6 +2568,7 @@ int I_LD_REF_NN_SP() { writeWord(addr, SP); return 20; } + int I_LD_REF_NN_A() { int addr = readWord(PC); PC = (PC + 2) & 0xFFFF; @@ -2544,17 +2577,20 @@ int I_LD_REF_NN_A() { memory.write(addr, (byte) regs[REG_A]); return 13; } + int I_LD_REF_NN_IX() { return I_LD_REF_NN_XY(IX); } + int I_LD_REF_NN_IY() { return I_LD_REF_NN_XY(IY); } int I_LD_REF_NN_XY(int xy) { - int tmp = readWord(PC); + int address = readWord(PC); PC = (PC + 2) & 0xFFFF; - writeWord(tmp, xy); + writeWord(address, xy); + memptr = (address + 1) & 0xFFFF; return 16; } @@ -2565,16 +2601,16 @@ int I_LD_RP_REF_NN() { PC = (PC + 2) & 0xFFFF; int tmp1 = readWord(addr); - putpair((lastOpcode >>> 4) & 3, tmp1, true); + putpair((lastOpcode >>> 4) & 3, tmp1); return 20; } int I_JR_CC_N() { - int addr = memory.read(PC); + byte offset = memory.read(PC); PC = (PC + 1) & 0xFFFF; if (getCC1((lastOpcode >>> 3) & 3)) { - PC = (PC + (byte) addr) & 0xFFFF; + PC = (PC + offset) & 0xFFFF; memptr = PC; return 12; } @@ -2621,27 +2657,26 @@ int I_SUB_N() { int I_JP_CC_NN() { int addr = readWord(PC); + memptr = addr; PC = (PC + 2) & 0xFFFF; int tmp1 = (lastOpcode >>> 3) & 7; if ((flags & CONDITION[tmp1]) == CONDITION_VALUES[tmp1]) { PC = addr; } - memptr = PC; return 10; } int I_CALL_CC_NN() { int addr = readWord(PC); + memptr = addr; PC = (PC + 2) & 0xFFFF; - memptr = PC; int tmp1 = (lastOpcode >>> 3) & 7; if ((flags & CONDITION[tmp1]) == CONDITION_VALUES[tmp1]) { SP = (SP - 2) & 0xffff; writeWord(SP, PC); PC = addr; - memptr = PC; return 17; } return 10; @@ -2650,9 +2685,10 @@ int I_CALL_CC_NN() { int I_LD_HL_REF_NN() { int addr = readWord(PC); PC = (PC + 2) & 0xFFFF; - int tmp1 = readWord(addr); - putpair(2, tmp1, false); + memptr = (addr + 1) & 0xFFFF; + regs[REG_H] = (tmp1 >>> 8) & 0xFF; + regs[REG_L] = tmp1 & 0xFF; return 16; } @@ -2953,22 +2989,22 @@ int I_LD_H_REF_HL() { } int I_LD_IXH_B() { - IX = (regs[REG_B] << 8) | (IX & 0xFF); + IX = ((regs[REG_B] << 8) | (IX & 0xFF)) & 0xFFFF; return 8; } int I_LD_IXH_C() { - IX = (regs[REG_C] << 8) | (IX & 0xFF); + IX = ((regs[REG_C] << 8) | (IX & 0xFF)) & 0xFFFF; return 8; } int I_LD_IXH_D() { - IX = (regs[REG_D] << 8) | (IX & 0xFF); + IX = ((regs[REG_D] << 8) | (IX & 0xFF)) & 0xFFFF; return 8; } int I_LD_IXH_E() { - IX = (regs[REG_E] << 8) | (IX & 0xFF); + IX = ((regs[REG_E] << 8) | (IX & 0xFF)) & 0xFFFF; return 8; } @@ -2982,32 +3018,32 @@ int I_LD_IXH_IXL() { } int I_LD_IXH_A() { - IX = (regs[REG_A] << 8) | (IX & 0xFF); + IX = ((regs[REG_A] << 8) | (IX & 0xFF)) & 0xFFFF; return 8; } int I_LD_IYH_B() { - IY = (regs[REG_B] << 8) | (IY & 0xFF); + IY = ((regs[REG_B] << 8) | (IY & 0xFF)) & 0xFFFF; return 8; } int I_LD_IYH_C() { - IY = (regs[REG_C] << 8) | (IY & 0xFF); + IY = ((regs[REG_C] << 8) | (IY & 0xFF)) & 0xFFFF; return 8; } int I_LD_IYH_D() { - IY = (regs[REG_D] << 8) | (IY & 0xFF); + IY = ((regs[REG_D] << 8) | (IY & 0xFF)) & 0xFFFF; return 8; } int I_LD_IYH_E() { - IY = (regs[REG_E] << 8) | (IY & 0xFF); + IY = ((regs[REG_E] << 8) | (IY & 0xFF)) & 0xFFFF; return 8; } int I_LD_IYH_A() { - IY = (regs[REG_A] << 8) | (IY & 0xFF); + IY = ((regs[REG_A] << 8) | (IY & 0xFF)) & 0xFFFF; return 8; } @@ -3284,12 +3320,12 @@ int I_LD_REF_IX_D_E() { return I_LD_REF_XY_D_R(regs[REG_E], IX); } - int I_LD_REF_IX_D_IXH() { - return I_LD_REF_XY_D_R(IX >>> 8, IX); + int I_LD_REF_IX_D_H() { + return I_LD_REF_XY_D_R(regs[REG_H], IX); } - int I_LD_REF_IX_D_IXL() { - return I_LD_REF_XY_D_R(IX & 0xFF, IX); + int I_LD_REF_IX_D_L() { + return I_LD_REF_XY_D_R(regs[REG_L], IX); } int I_LD_REF_IX_D_A() { @@ -3312,12 +3348,12 @@ int I_LD_REF_IY_D_E() { return I_LD_REF_XY_D_R(regs[REG_E], IY); } - int I_LD_REF_IY_D_IYH() { - return I_LD_REF_XY_D_R(IY >>> 8, IY); + int I_LD_REF_IY_D_H() { + return I_LD_REF_XY_D_R(regs[REG_H], IY); } - int I_LD_REF_IY_D_IYL() { - return I_LD_REF_XY_D_R(IY & 0xFF, IY); + int I_LD_REF_IY_D_L() { + return I_LD_REF_XY_D_R(regs[REG_L], IY); } int I_LD_REF_IY_D_A() { @@ -3486,7 +3522,7 @@ int I_BIT_N_R() { if (reg == 6) { flags &= (~FLAG_X); flags &= (~FLAG_Y); - flags |= ((memptr >>> 8) & (FLAG_X | FLAG_Y)); + flags |= ((memptr >>> 8) & FLAG_XY); Q = flags; return 12; } else { diff --git a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/Z80Tests.java b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/Z80Tests.java index 1e1dab587..429d08380 100644 --- a/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/Z80Tests.java +++ b/plugins/cpu/z80-cpu/src/test/java/net/emustudio/plugins/cpu/zilogZ80/Z80Tests.java @@ -175,7 +175,7 @@ public String toString() { mk(0x6FED, 0x8cd2dc37).hl_mem(0x2F), // RLD mk(0x77ED, 0x34fd8b43), // NOP mk(0x7FED, 0x34fd8b43), // NOP - mk(0x80ED, 0x2c7aa213).hl_mem(0x2F).y(4, 7).z(0, 3), // bli[y, z] + mk(0x80ED, 0xe5555767).hl_mem(0x2F).y(4, 7).z(0, 3), // bli[y, z] mk(0x00DD, 0x34fd8b43), // NOP mk(0x08DD, 0xa007a4d), // EX AF, AF' @@ -378,7 +378,7 @@ public void testInstruction(InstrTest instrTest) { } } } - //System.out.println("0x" + Integer.toHexString(cpu.getEngine().crc)); + // System.out.println("0x" + Integer.toHexString(crc.get())); assertEquals(instrTest.crc, crc.get()); } From b266665e9bf94b6e2829f6f8ca4f8a006d97dfaa Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 23 Feb 2023 12:24:51 +0100 Subject: [PATCH 268/314] [#315, #257] Fix Altair8800 bootloader sources --- .../files/examples/altair8800/boot/README | 2 - .../files/examples/altair8800/boot/cdbl.asm | 611 ------------------ .../files/examples/altair8800/boot/dbl.asm | 134 ++-- .../files/examples/altair8800/boot/mdbl.asm | 250 +++---- .../plugins/device/simh/Commands.java | 2 +- 5 files changed, 204 insertions(+), 795 deletions(-) delete mode 100644 application/src/main/files/examples/altair8800/boot/cdbl.asm diff --git a/application/src/main/files/examples/altair8800/boot/README b/application/src/main/files/examples/altair8800/boot/README index f753d4b45..6d2158b3b 100644 --- a/application/src/main/files/examples/altair8800/boot/README +++ b/application/src/main/files/examples/altair8800/boot/README @@ -3,5 +3,3 @@ mdbl.bin: 88-disk modified boot loader; extracted from simh emulator dbl.asm : 88-disk boot loader; reverse-engineered from simh emulator dbl.bin : 88-disk boot loader; extracted from simh emulator - -cdbl.adm: common disk boot loader 3.0; https://deramp.com/downloads/altair/software/roms/custom_roms/M%20Eberhard%20Improved%20ROMs/CDBL%20Manual.pdf diff --git a/application/src/main/files/examples/altair8800/boot/cdbl.asm b/application/src/main/files/examples/altair8800/boot/cdbl.asm deleted file mode 100644 index f6f275b6b..000000000 --- a/application/src/main/files/examples/altair8800/boot/cdbl.asm +++ /dev/null @@ -1,611 +0,0 @@ -;============================================================== -;= CDBL - Combo Disk Boot Loader ROM = -;= For the Altair 88-DCDD 8" disk system and = -;= the Altair 88-MDS Minidisk system = -;= By Martin Eberhard = -;= = -;= CDBL loads software (e.g. Altair Disk BASIC) from an = -;= Altair 88-DCDD 8" disk or an 88-MDS 5-1/4" minidisk, = -;= automatically detecting which kind of drive is attached. = -;============================================================== -;= NOTES = -;= = -;= Like DBL and MDBL, CDBL fits in one (256-byte) 1702A = -;= EPROM and execution begins at address FF00h. However, = -;= since version 3.00, the PROM is position independent = -;= and can run at most any 256 byte boundary. = -;= = -;= Because of the slow 1702A EPROM access time, and because = -;= some versions of MITS's 8800b Turnkey Module disable PROM = -;= when any IN instruction is executed, CDBL copies itself = -;= into RAM at 4C00h (RAMADR), and executes there. CDBL = -;= therefore requres 512 bytes of 0-wait state RAM, starting = -;= at RAMADR. = -;= = -;= Minidisks have 16 sectors/track, numbered 0 through 15. = -;= 8" disks have 32 sectors/track, numbered 0 through 31. = -;= CDBL figures out which kind of disk drive is attached, = -;= based on the existance of sector number 16. = -;= = -;= ALTAIR DISK SECTOR FORMAT (FOR BOOT SECTORS) = -;= = -;= BYTE(s) FUNCTION BUFFER ADDRESS = -;= 0 Track number+80h (sync) RAMADR+7Bh = -;= 1 File size low byte RAMADR+7Ch = -;= 2 File size High Byte RAMADR+7Dh = -;= 3-130 Sector data RAMADR+7Eh to RAMADR+FDh = -;= 131 Marker Byte (0FFh) RAMADR+FEh = -;= 132 Checksum RAMADR+FFh = -;= 133-136 Spare not read = -;= = -;= Each sector header contains a 16-bit file-size value: = -;= this many bytes (rounded up to an exact sector) are read = -;= from the disk and written to RAM, starting at address 0. = -;= When done (assuming no errors), CDBL then jumps to = -;= address 0 (DMAADR) to execute the loaded code. = -;= = -;= Sectors are interleaved 2:1. CDBL reads the even sectors = -;= on each track first (starting with track 0, sector 0) = -;= followed by the odd sectors (starting with sector 1), = -;= continuing through the interleaved sectors of each track = -;= until the specified number of bytes have been read. = -;= = -;= CDBL first reads each sector (including the actual data = -;= payload, as well as the 3 header and the first 2 trailer = -;= bytes) from disk into the RAM buffer (SECBUF). Next, CDBL = -;= checks to see if this sector would overwrite the RAM = -;= portion of CDBL, and aborts with an 'O' error if so. It = -;= then copies the data payload portion from the buffer to = -;= its final RAM location, calculating the checksum along the = -;= way. During the copy, each byte is read back, to verify = -;= correct writes. Any write-verify failure will immediately = -;= abort the load with an 'M' error. = -;= = -;= Any disk read error (a checksum error or an incorrect = -;= marker byte) will cause a retry of that sector read. After = -;= 16 retries on the same sector, CDBL will abort the load = -;= with a 'C' error. = -;= = -;= If the load aborts with any error, then CDBL will turn on = -;= the INTE LED on the front panel (as an indicator), write = -;= the error code ('C', 'M', or 'O') to RAM address 0, write = -;= the offending memory address to RAM addresses 1 and 2, and = -;= then hang forever in a loop, printing the error code to = -;= all known Altair Terminal output ports. = -;============================================================== -;= REVISION HISTORY = -;= = -;= 1.00 05May2014 M.Eberhard = -;= Combined MDBL and DBLme code, with assembly options to = -;= create exactly both of these boot loaders = -;= 2.00 08May2014 M.Eberhard = -;= Restructure and squeeze the code. Automatic 8"/Minidisk = -;= detection. Select boot disk from the sense switches. = -;= Improve track 0 seek by waiting for -MVHEAD before = -;= testing TRACK0. Detect memory overrun errors. Verify = -;= copy of CDBL code into RAM. = -;= 2.01 15May2014 M.Eberhard = -;= Step in once before seeking track 0. Restart 6.4 Sec = -;= motor shutoff timer on retries. = -;= 2.02 04Jun2014 M. Eberhard = -;= Eliminate booting from other than drive 0 because Basic = -;= and Burcon CP/M just load a 2-sector boot loader, and = -;= that boot loader loads the rest, always from drive 0. = -;= 2.03 17Jan2015 M. Douglas = -;= Force 43ms minimum delay when changing seek direction = -;= to meet/exceed 8" drive requirements. = -;= 2.04 12Mar2015 M. Douglas = -;= Change 2SIO init constant (ACINIT) from 21h (7E2, xmit = -;= interrupts on) to 11h (8N2) = -;= 2.05 11Jan2016 M. Eberhard = -;= No IN or OUT instructions until code is moved to RAM = -;= (for compatibility with some Turnkey Modules). This = -;= increased the RAM footprint from 256 to 512 bytes. Also = -;= fixed a bug when reporting overlay errors. = -;= 3.00 12Jan2016 M. Douglas = -;= Make the PROM position independent by making the = -;= routine that copies PROM to RAM position independent. = -;============================================================== - -;----------------- -; Disk Parameters -;----------------- -BPS equ 128 ;data bytes/sector -MDSPT equ 16 ;Minidisk sectors/track - -;this code assumes SPT for 8" -;disks = MDSPT * 2. -HDRSIZ equ 3 ;header bytes before data -TLRSIZ equ 2 ;trailer bytes read after data - -SECSIZ equ BPS+HDRSIZ+TLRSIZ ;total bytes/sector - -RETRYS equ 16 ;max retries per sector - -;-------------------------------------------------------------- -; Memory Parameters. To keep code short, several assumptions -; about these values are embedded in the code: -; 1) RAMADR and PROM low address byte = 0 -; 2) The address of the last byte of SECBUF (the SECSIZ-sized -; sector buffer) must be XXFF. -; 3) The ls bit of the high byte of RAMADR must be 0 -; 4) The value of DMAADR is assumed to be 0 -;-------------------------------------------------------------- -RAMADR equ 4C00H ;Address for code copied to RAM -SECBUF equ RAMADR+512-SECSIZ -STACK equ SECBUF ;grows down from here -DMAADR equ 0 ;Disk load/execution address - -;---------------------------------------------- -; Addresses of sector components within SECBUF -;---------------------------------------------- -SFSIZE equ SECBUF+1 ;address of file size -SDATA equ SECBUF+HDRSIZ ;address of sector data -SMARKR equ SDATA+BPS ;address of marker byte -SCKSUM equ SMARKR+1 ;address of checksum byte - -;---------------- -; 88-SIO Equates -;---------------- -SIOCTL EQU 00 ;Control -SIOSTA EQU 00 ;Status -SIODAT EQU 01 ;Rx/Tx Data - -;----------------------------------------------- -; 88-2SIO's port 0, Turnkey Module, and 88-UIO -; Equates (all based on the Motorola 6850 ACIA) -;----------------------------------------------- -ACCTRL equ 10h ;ACIA Control output port -ACSTAT equ 10h ;ACIA Status input port -ACDATA equ 11h ;ACIA Tx/Rx Data register - -ACRST equ 03h ;Master reset -ACINIT equ 11h ;/16, 8bit, No Parity, 2Stops - -;---------------- -; 88-PIO Equates -;---------------- -PIOCTL EQU 04 ;Control -PIOSTA EQU 04 ;Status -PIODAT EQU 05 ;Tx/Rx Data - -;----------------- -; 88-4PIO equates -;----------------- -P4CA0 equ 20h ;Port 0 Section A Ctrl/Status -P4DA0 equ 21h ;Port 0 Section A Data -P4CB0 equ 22h ;Port 0 Section B Ctrl/Status -P4DB0 equ 23h ;Port 0 Section B Data - -P4CINI equ 2Ch ;Control/status initialization - -;---------------------------------------------------------- -; Altair 8800 Disk Controller Equates (These are the same -; for the 88-DCDD controller and the 88-MDS controller.) -;---------------------------------------------------------- -DENABL equ 08H ;Drive Enable output -DDISBL equ 80h ;disable disk controller -DSTAT equ 08H ;Status input (active low) -ENWDAT equ 01h ;-Enter Write Data -MVHEAD equ 02h ;-Move Head OK -HDSTAT equ 04h ;-Head Status -DRVRDY equ 08h ;-Drive Ready -INTSTA equ 20h ;-Interrupts Enabled -TRACK0 equ 40h ;-Track 0 detected -NRDA equ 80h ;-New Read Data Available - -DCTRL equ 09h ;Drive Control output -STEPIN equ 01H ;Step-In -STPOUT equ 02H ;Step-Out -HDLOAD equ 04H ;8" disk: load head - -;Minidisk: restart 6.4 S timer -HDUNLD equ 08h ;unload head (8" only) -IENABL equ 10h ;Enable sector interrupt -IDSABL equ 20h ;Disable interrupts -WENABL equ 80h ;Enable drive write circuits - -DSECTR equ 09h ;Sector Position input -SVALID equ 01h ;Sector Valid (1st 30 uS of sector pulse) -SECMSK equ 3Eh ;Sector mask for MDSEC - -DDATA equ 0Ah ;Disk Data (input/output) - -;---------------------------- -; Single-byte error messages -;---------------------------- -CERMSG equ 'C' ;checksum/marker byte error -MERMSG equ 'M' ;memory write verify error -OERMSG equ 'O' ;Memory overlay error message - -;============================================================== -ORG RAMADR ;assemble at dest RAM address -;============================================================== - -di ;turn off INTE (no error yet) - -;-------------------------------------------------------------- -; Copy the PROM content to RAM for execution. This copy routine -; is position independent so the boot PROM can be at most any -; address. The LSB of the PROM address and RAMADR must be 0. -;-------------------------------------------------------------- -lxi d,MLOOP ;DE->MLOOP in RAM - -lxi sp,STACK -lxi h,0E9E1h ;H=PCHL,L=POP H -push h ;POP H, PCHL at STACK-2, STACK-1 -call STACK-2 ;addr of MLOOP in HL and stack RAM - -MLOOP: dcx sp ;point SP to MLOOP address -dcx sp ; in stack memory - -mov a,m ;get next EPROM byte -stax d ;store it in RAM - -inr e ;bump pointers -inr l -rnz ;copy to end of 256 byte page - -jmp RAMIMG ;jump to code now in RAM - -; e=l=0 - -;============================================================== -; RAM Code Image -; All of the following code gets copied into RAM at RAMADR, -; and run there. -;============================================================== -RAMIMG: - -;------------------------------------------------------------- -; Wait for user to insert a diskette into the drive 0, and -; then load that drive's head. Do this first so that the disk -; has plenty of time to settle. Note that a minidisk will -; always report that it is ready. Minidisks will hang (later -; on) waiting for sector 0F, until a few seconds after the -; user inserts a disk. -; -; On Entry: -; l = 0 -;------------------------------------------------------------- - -WAITEN: xra a ;boot from disk 0 -out DENABL ;enable disk 0 -in DSTAT ;Read drive status -ani DRVRDY ;Diskette in drive? -jnz WAITEN ;no: wait for drive ready - -mvi a,HDLOAD ;Load 8" disk head, or enable -out DCTRL ;..minidisk for 6.4 Sec - -;------------------------------------------------------- -; Step in once, then step out until track 0 is detected -; On Exit: b=0 -;------------------------------------------------------- -lxi b,20000/12 ;20 mS delay 1st time thru -mvi a,STEPIN ;step in once first - -SKTRK0: out DCTRL ;issue step command - -; The first time through, delay at least 20ms to force a -; minimum 43 ms step wait instead of 10ms. This meets -; the 8" spec for changing seek direction. The minidisk -; step time is always 50ms. - -DELAY: dcx b ;(5) -mov a,b ;(5) -ora c ;(4) -jnz DELAY ;(10)12 uS/pass - -inr c ;from now on, the above loop goes 1 time. -WSTEP: in DSTAT ;wait for step to complete -rrc ;put MVHEAD bit in carry -rrc ;is the servo stable? -jc WSTEP ;no: wait for servo to settle - -ani TRACK0/4 ;Are we at track 00? -mvi a,STPOUT ;STEP-OUT command -jnz SKTRK0 ;no: step out another track - -;Exit with b=0 -;-------------------------------------------------------- -; Determine if this is an 8" disk or a minidisk, and set -; c to the correct sectors/track for the detected disk. -; An 8" disk has 20h sectors, numbered 0-1Fh. A minidisk -; has 10h sectors, numbered 0-0Fh. -;-------------------------------------------------------- - -; wait for the highest minidisk sector, sector number 0Fh - -CKDSK1: in DSECTR ;Read the sector position - -ani SECMSK+SVALID ;Mask sector bits, and hunt -cpi (MDSPT-1)*2 ;..for minidisk last sector -jnz CKDSK1 ;..only while SVALID is 0 - -; wait for this sector to pass - -CKDSK2: in DSECTR ;Read the sector position -rrc ;wait for invalid sector -jnc CKDSK2 - -; wait for and get the next sector number - -CKDSK3: in DSECTR ;Read the sector position -rrc ;put SVALID in carry -jc CKDSK3 ;wait for sector to be valid - -; The next sector after sector 0Fh will be 0 for a minidisk, -; and 10h for an 8" disk. Adding MDSPT (10h) to that value -; will compute c=10h (for minidisks) or c=20h (for 8" disks). - -ani SECMSK/2 ;Mask sector bits -adi MDSPT ;compute SPT -mov c,a ;..and save SPT in c - -;------------------------------------------------------------ -; Initialize the ACIA (2SIO port 0/Turnkey/UIO). Do this -; late in the initialization, so that e.g. the 'B' character -; from UBMON won't get eaten by resetting the ACIA. -;------------------------------------------------------------ -mvi a,ACRST ;reset first -out ACCTRL - -mvi a,ACINIT ;then initialize -out ACCTRL - -;--------------------- -; Initialize the 4PIO -;--------------------- -xra a -out P4CB0 ;Port 0 section B is output -cma ;All output bits high -out P4DB0 -mvi a,P4CINI ;set up handshake bits -out P4CB0 - -;-------------------------------------------- -; Set up to load -; On Entry: -; b = 0 (initial sector number) -; c = SPT (for either minidisk or 8" disk) -; l = 0 (part of DMA address) -;-------------------------------------------- -mov h,l ;initial DMA address=0000 - -;-------------------------------------------------------- -; Read current sector over and over, until either the -; checksum is right, or there have been too many retries -; b = current sector number -; c = sectors/track for this kind of disk -; hl = current DMA address -;-------------------------------------------------------- -NXTSEC: mvi a,RETRYS ;(7)Initialize sector retries - -;------------------------------------------------------ -; Begin Sector Read -; a = Remaining retries for this sector -; b = Current sector number -; c = Sectors/track for this kind of disk -; hl = current DMA address -;------------------------------------------------------ -RDSECT: lxi sp,STACK ;(10)(re)initialize the stack -push psw ;(11)Remaining retry count - -;----------------------------------------------------------- -; Sector Read: Step 1. Hunt for sector specified in b. Data -; will become avaiable 250 uS after -SVALID -; goes low. -SVALID is low for 30 uS. -;----------------------------------------------------------- -FNDSEC: in DSECTR ;(10)Read the sector position - -ani SECMSK+SVALID ;(7)yes: Mask sector bits -;..along with -SVALID bit -rrc ;(4)sector bits to bits <4:0> -cmp b ;(4)Found the desired sector -;..with -SVALID low? -jnz FNDSEC ;(10)no: wait for it - -;------------------------------------------------------------ -; Test for DMA address that would overwrite this RAM code -; or the next page (which contains the sector buffer stack) -; Do this here, while we have some time. -;------------------------------------------------------------ -lxi d,SECBUF ;(10)Sector buffer address - -mov a,h ;(5)high byte of DMA address -xra d ;(4)high byte of RAM code addr -ani 0FEh ;(7)ignore lsb -mvi a,OERMSG ;(7)overlay error message -jz RPTERR ;(10)report overlay error - -;---------------------------------------- -; Set up for the upcoming data move -; Do this here, while we have some time. -;---------------------------------------- -push h ;(11)Current DMA address -push b ;(11)Current sector & SPT -lxi b,BPS ;(10)b= init checksum, -;c= byte count for MOVLUP -;------------------------------------------------------------- -; Sector Read: Step 2. Read sector data into SECBUF at de. -; SECBUF is positioned in memory such that e -; overflows at the end of the buffer. Read data -; becomes available 250 uS after -SVALID becomes -; true (0).This loop must be << 32 uS per pass. -;------------------------------------------------------------- -DATLUP: in DSTAT ;(10)Read the drive status -rlc ;(4)New Read Data Available? -jc DATLUP ;(10)no: wait for data - -in DDATA ;(10)Read data byte -stax d ;(7)Store it in sector buffer -inr e ;(5)Move to next buffer address -;..and test for end -jnz DATLUP ;(10)Loop if more data - -;-------------------------------------------------------- -; Sector Read: Step 3. Move sector data from SECBUF into -; memory at hl. Compute checksum as we go. -; -; 8327 cycles for this section -;-------------------------------------------------------- -mvi e,SDATA and 0FFh ;(7)de= address of sector data -;..within the sector buffer -MOVLUP: ldax d ;(7)Get sector buffer byte -mov m,a ;(7)Store it at the destination -cmp m ;(7)Did it store correctly? -jnz MEMERR ;(10)no: abort w/ memory error - -add b ;(4)update checksum -mov b,a ;(5)Save the updated checksum - -inx d ;(5)Bump sector buffer pointer -inx h ;(5)Bump DMA pointer -dcr c ;(5)More data bytes to copy? -jnz MOVLUP ;(10)yes: loop - -;-------------------------------------------------------------- -; Sector Read: Step 4. Check Marker byte and compare computed -; checksum against sector's checksum. Retry/abort -; if wrong Marker byte or checksum mismatch. -; -; a=computed checksum -; 98 cycles for for this section -;-------------------------------------------------------------- -xchg ;(4)hl=1st trailer byte address -;de=DMA address -mov c,m ;(7)get marker, should be FFh -inr c ;(5)c should be 0 now - -inx h ;(5)(hl)=checksum byte -xra m ;(7)compare to computed cksum -ora c ;(4)..and test marker=ff - -pop b ;(10)Current sector & SPT -jnz BADSEC ;(10)NZ: checksum error - -; Compare next DMA address to the file byte count that came -; from the sector header. Done of DMA address is greater. - -lhld SFSIZE ;(16)hl gets file size -xchg ;(4)put DMA address back in hl -;..and file size into de -mov a,l ;(4)16-bit subtraction -sub e ;(4) -mov a,h ;(4)..throw away the result -sbb d ;(4)..but keep carry (borrow) - -jnc LDDONE ;(10)done loading if hl >= de -;carry will be clear at LDDONE -;------------------------------------------------------------ -; Next Sector: The sectors are interleaved by two. Read all -; the even sectors first, then the odd sectors. -; Note that NXTSEC will repair the stack. -; -; 44 cycles for the next even or next odd sector -;------------------------------------------------------------ -lxi d,NXTSEC ;(10)for compact jumps -push d ;(10) - -inr b ;(5)sector = sector + 2 -inr b ;(5) - -mov a,b ;(5)even or odd sectors done? -cmp c ;(4)c=SPT -rc ;(5/11)no: go read next sector -;..at NXTSEC -; Total sector-to-sector = 28+8327+98+44=8497 cycles=4248.5 uS -; one 8" sector time = 5208 uS, so with 2:1 interleave, we will -; make the next sector, no problem. - -mvi b,01H ;1st odd sector number -rz ;Z: must read odd sectors now -;..at NXTSEC -;-------------------------------------------------------------- -; Next Track: Step in, and read again. -; Don't wait for the head to be ready (-MVHEAD), -; since we just read the entire previous track. -; Don't need to wait for this step-in to complete -; either, because we will definitely blow a -; revolution going from the track's last sector to -; sector 0. (One revolution takes 167 mS, and one -; step takes a a maximum of 40 uS.) -; Note that NXTRAC will repair the stack. -;-------------------------------------------------------------- -mov a,b ;STEPIN happens to be 01h -out DCTRL - -dcr b ;start with b=0 for sector 0 -ret ;go to NXTSEC - -;***Error Routine********************************************** -; Checksum error: attempt retry if not too many retries -; already. Otherwise, abort, reporting the error -; On Entry: -; Top of stack = adress for first byte of the failing sector -; Next on stack = retry count -;************************************************************** -BADSEC: mvi a,HDLOAD ;Restart Minidisk 6.4 uS timer -out DCTRL - -pop h ;Restore DMA address -pop psw ;Get retry count -dcr a ;Any more retries left? -jnz RDSECT ;yes: try reading it again -;------------------------------------------------------ -; Irrecoverable error in one sector: too many retries. -; These errors may be either incorrect marker bytes, -; wrong checksums, or a combination of both. -; On Entry: -; hl=RAM adress for first byte of the failing sector -;------------------------------------------------------ -mvi a,CERMSG ;Checksum error message -db 11H ;'lxi d' opcode to skip -;..MEMERR and go to RPTERR -;***Error Routine********************** -; Memory error: memory readback failed -; On Entry: -; hl = offending RAM address -;************************************** -MEMERR: mvi a,MERMSG ;Memory Error message - -; Fall into RPTERR - -;***CDBL Termination******************************************* -; Entry at RPTERR: -; Report an error: turn the disk controller off, turn the -; INTE light on, record the error in RAM at 0000h-0002h, and -; then loop forever writing the error code (in register a) -; to all known Terminal ports. -; On Entry: -; a = error code -; hl = offending RAM address -; -; Entry at LDDONE: -; Normal exit: Disable the disk controller and go execute -; the loaded code at DMAADR. -; On Entry: -; Carry bit is cleared -;************************************************************** -RPTERR: mov b,a ;error code -stc ;remember we had an error - -LDDONE: mvi a,DDISBL ;Disable the disk controller -out DENABL - -jnc DMAADR ;normal exit: go execute the -;..loaded program -ei ;Signal error on the INTE LED - -shld 1 ;Store the bad address -mov a,b ;recover the error code -sta 0 ;Store the error code - -ERHANG: out SIODAT ;SIO -out ACDATA ;2SIO port 0/Turnkey/UIO -out PIODAT ;PIO -out P4DB0 ;4PIO -jmp ERHANG ;Keep printing error code - -end diff --git a/application/src/main/files/examples/altair8800/boot/dbl.asm b/application/src/main/files/examples/altair8800/boot/dbl.asm index bdad56a6d..981d03d5a 100644 --- a/application/src/main/files/examples/altair8800/boot/dbl.asm +++ b/application/src/main/files/examples/altair8800/boot/dbl.asm @@ -1,4 +1,7 @@ -; THE ALTAIR 88-DSK ROM MOVES THIS CODE TO 4C00H THEN +; Disk Boot Loader (DBL) +; Compilable by emuStudio (emuStudio doesn't support ORG without code relocation yet) + +;THE ALTAIR 88-DSK ROM MOVES THIS CODE TO 4C00H THEN ; JUMPS TO IT. POSSIBLE ERRORS ARE: ; C CRC ON DISK DOESN'T MATCH CALCULATED CRC ; M MEMORY ERROR READ/BACK FROM MEMORY DOESN'T MATCH WRITE TO MEMORY (NO RAM, BAD RAM, OR WPROT) @@ -7,185 +10,190 @@ ORG 0FF00h ; RELOCATE $E6 BYTES REMAINING OF LOADER TO 4C00 (19456D) -LXI H, 4C00h -LXI D, here ;0FF18h -MVI C, 0E6h +LXI H, 0x4C00 +LXI D, 0xFF18 +MVI C, 0xE6 -XFF08: +lFF08: LDAX D MOV M,A INX D INX H DCR C -JNZ XFF08 -JMP 4C00h +JNZ lFF08 +JMP 0x4C00 + +nop +nop +nop +nop +nop -here: -;ORG 4C00h +lFF18: DI ; DISABLE INTERRUPTS -LXI SP,4D62h ; LOAD STACK POINTER +LXI SP,0x4D62 ; LOAD STACK POINTER XRA A ; ZERO IN A OUT 08h ; SELECT DRIVE 0 MVI A,04h ; HEAD DOWN CMD OUT 09h ; SEND HEAD DOWN -JMP TTRK0 ; GO TEST FOR TRACK ZERO +JMP 0x4C19 ; (TTRK0); GO TEST FOR TRACK ZERO -TMVOK: +TMVOK: ; at 0x4C0E IN 08h ; GET STATUS ANI 02h ; TEST FOR MOVE OK -JNZ TMVOK ; JMP MOVE NOT OK +JNZ 0x4C0E ; (TMVOK) JMP MOVE NOT OK MVI A,02h ; STEP OUT CMD OUT 09h ; SEND STEP OUT -TTRK0: +TTRK0: ; at 0x4C19 IN 08h ; GET STATUS ANI 40h ; TEST FOR TRACK ZERO -JNZ TMVOK ; JMP NOT TRACK ZERO +JNZ 0x4C0E ; (TMVOK) JMP NOT TRACK ZERO LXI D,0000 ; DE->0000H -NXTTK: +NXTTK: ; at 0x4C23 MVI B,00 ; B=0 -THDDN: +THDDN: ; at 0x4C25 IN 08h ; GET STATUS ANI 04h ; TEST FOR HEAD DOWN -JNZ THDDN ; JMP NOT HEAD DOWN +JNZ 0x4C25 ; (THDDN) JMP NOT HEAD DOWN ;SEEK TO SECTOR IN B -NXTSEC: +NXTSEC: ; at 0x4C2C MVI A,10h ; A=10H 16D RETRY COUNT -RETRY: +RETRY: ; at 0x4C2E PUSH PSW ; SAVE RETRY COUNT PUSH D ; NXTMEM PUSH B ; B=SECTOR PUSH D ; NXTMEM LXI D,8086h ; D=80(UNUSED?) E=128=COUNT -LXI H,VAR1 ; M=POINTER TO INBUFFER +LXI H,0x4CD4 ; (VAR1) M=POINTER TO INBUFFER -TSECT: +TSECT: ; at 0x4C38 IN 09h ; GET SECTOR# UNDER HEAD AND STATUS RAR ; TEST SECTOR TRUE -JC TSECT ; JMP TSECT IF NOT TRUE +JC 0x4C38 ; (TSECT) JMP TSECT IF NOT TRUE ANI 1Fh ; AND SECTOR MASK 31D CMP B ; DESIRED SECTOR -JNZ TSECT ; JMP TSECT IF NOT EQUAL +JNZ 0x4C38 ; (TSECT) JMP TSECT IF NOT EQUAL ;READ 134 BYTES TWO AT A TIME INTO INBUFFER -TRDOK: +TRDOK: ; at 0x4C44 IN 08h ; GET STATUS ORA A ; SET FLAGS TEST FOR READ OK -JM TRDOK ; JMP TRDOK IF NOT READ OK +JM 0x4C44 ; (TRDOK) JMP TRDOK IF NOT READ OK IN 0Ah ; GET DATA BYTE1 MOV M,A ; MOVE BYTE TO INBUFF INX H ; BUMP INPOINTER DCR E ; DECREMENT COUNT -JZ MVBYTS ; JMP MVBYTS IF DONE +JZ 0x4C5A ; (MVBYTS) JMP MVBYTS IF DONE DCR E ; DEC COUNT IN 0Ah ; GET DATA BYTE2 MOV M,A ; MOVE TO INBUFF INX H ; INCREMENT POINTER -JNZ TRDOK ; JMP TRDOK IF COUNT IN E IS NOT ZERO +JNZ 0x4C44 ; (TRDOK) JMP TRDOK IF COUNT IN E IS NOT ZERO ;MOVE 128 DATA BYTES FROM BUFF TO MEMORY MAKE A CRC -MVBYTS: +MVBYTS: ; at 0x4C5A POP H ; HL (M)=0000H FIRST TIME -LXI D,VAR3 ; DE POINTS TO BUFFER + 3 -LXI B,0080h ; B=0=CRC C=128 COUNT +LXI D,0x4CD7 ; (VAR3) DE POINTS TO BUFFER + 3 +LXI B,0x80 ; B=0=CRC C=128 COUNT -MVBYT2: +MVBYT2: ; at 0x4C61 LDAX D ; GET BYTE FROM BUFFER MOV M,A ; MOVE TO DESTINATION CMP M ; CHECK FOR MEMORY PROBLEM -JNZ MERROR ; JMP MERROR IF PROBLEM +JNZ 0x4CC1 ; (MERROR) JMP MERROR IF PROBLEM ADD B ; MAKE A CRC MOV B,A ; SAVE IN B INX D ; INC SRC INX H ; INC DEST DCR C ; DEC COUNT -JNZ MVBYT2 ; JMP MVBYT2 UNTIL COUNT = 0 +JNZ 0x4C61 ; (MVBYT2) JMP MVBYT2 UNTIL COUNT = 0 ;CHECK CRC LDAX D ; DE POINTS TO BUFFER + 131 CPI 0FFh ; COMPARE THAT BYTE TO 255 -JNZ FFERR ; JMP FFERR IF NOT EQUAL +JNZ 0x4C78 ; (FFERR) JMP FFERR IF NOT EQUAL INX D ; INC DE POINTS TO BUFF+132 LDAX D ; GET THAT BYTE CMP B ; COMPARE TO CRC -FFERR: +FFERR: ; at 0x4C78 POP B ; B=SECTOR XCHG ; DE->NEXT DEST HL->BUFF+132 -JNZ CRCERR ; CRC ERROR GO CRCERR +JNZ 0x4CB5 ; (CRCERR) CRC ERROR GO CRCERR ;CHECK FOR OUT OF MEMORY CHECK DONE LOADING POP PSW ; 0000H FIRST TIME POP PSW ; ACC=16 -LHLD VAR2 ; L=BUFF+1 H=BUFF+2 +LHLD 0x4CD5 ; (VAR2) L=BUFF+1 H=BUFF+2 PUSH D ; SAVE NEXT DEST 0080 FIRST TIME LXI D,0FF00h ; DE->BOOTROM(END OF MEMORY) -CALL SUB1 ; COMPARE1 FF00H,HL OUT OF MEMORY (HL GREATER THAN FF00H) +CALL 0x4CCE ; (SUB1) COMPARE1 FF00H,HL OUT OF MEMORY (HL GREATER THAN FF00H) POP D ; NEXT DEST -JC OERROR ; JMP 'O'UT OF RAM ERROR (HL GREATER THAN FFOOH) -CALL SUB1 ; COMPARE2 DE,HL ARE WE DONE LOADING? -JNC EXIT1 ; IF NO CARRY (HL <= NEXT DEST)WE'RE DONE GO EXECUTE +JC 0x4CBE ; (OERROR) JMP 'O'UT OF RAM ERROR (HL GREATER THAN FFOOH) +CALL 0x4CCE ; (SUB1) COMPARE2 DE,HL ARE WE DONE LOADING? +JNC 0x4CAE ; (EXIT1) IF NO CARRY (HL <= NEXT DEST)WE'RE DONE GO EXECUTE -;CALCULATE NEXT SECTOR AND TRACK +;CALCULATE NEXT SECTOR AND TRACK INR B ; ADD 2 TO SECTOR# INR B ; MOV A,B ; DESIRED NEXT SECTORA -CPI 20h ; TEST IF SECTORA LESS THAN 32 -JC NXTSEC ; IF LESS GO GET IT +CPI 0x20 ; TEST IF SECTORA LESS THAN 32 +JC 0x4C2C ; (NXTSEC) IF LESS GO GET IT MVI B,01h ; IF NOT LESS MAKE DESIRED SECTORB=1 -JZ NXTSEC ; IF SECTORA EQUALED 32 GO GET SECTORB=1 +JZ 0x4C2C ; (NXTSEC) IF SECTORA EQUALED 32 GO GET SECTORB=1 -LOOP7: +LOOP7: ; at 0x4CA0 IN 08h ; ELSE GET STATUS ANI 02h ; TEST MOVE OK -JNZ LOOP7 ; UNTIL MOVE IS OK +JNZ 0x4CA0 ; (LOOP7) UNTIL MOVE IS OK MVI A,01h ; STEP IN CMD OUT 09h ; SEND STEP IN CMD -JMP NXTTK ; START LOADING FROM NEXT TRACK SECTORB=0 +JMP 0x4C23 ; (NXTTK) START LOADING FROM NEXT TRACK SECTORB=0 ;LOAD THE EVEN SECTORS ON A TRACK FIRST ;THEN THE ODD SECTORS ;DONE -EXIT1: +EXIT1: ; at 0x4CAE MVI A,80h ; OUT 08h ; CLEAR CONTROLLER JMP 0000h ; GO ;CRC ERROR RETRY PSW TIMES -CRCERR: +CRCERR: ; at 0x4CB5 POP D POP PSW ; DCR A ; DECREMENT RETRY COUNT -JNZ RETRY ; IF NOT 0 GO RETRY +JNZ 0x4C2E ; (RETRY) IF NOT 0 GO RETRY -;CLEAR CONTROLLER SEND TO CONSOLE ERROR MESSAGE +;CLEAR CONTROLLER SEND TO CONSOLE ERROR MESSAGE MVI A,43h ; ELSE LOAD A WITH CHAR 'C'RC ERROR DB 01h ;4CBD LXI B,4F3E ;GARBAGE - SKIP TRICK BD-BF -OERROR: +OERROR: ; at 0x4CBE MVI A,4Fh ; LOAD A WITH CHAR 'O'VERFLOW DB 01h ;4CC0 LXI B,4D3E ;GARBAGE - SKIP TRICK C0-C2 -MERROR: +MERROR: ; at 0x4CC1 MVI A,4D ; LOAD A WITH CHAR 'M'EMORY ERROR MOV B,A ; SAVE CHAR MVI A,80h ; CLEAR CONTROLLER OUT 08h ; SEND CLEAR MOV A,B ; GET CHAR -CONOUT: -OUT 11h ; SEND ERROR CHAR TO CONSOLE -JMP CONOUT ; OVER AND OVER AND OVER... +CONOUT: ; at 0x4CC9 +OUT 11h ; SEND ERROR CHAR TO CONSOLE (originally 1h) +JMP 0x4CC9 ; (CONOUT) OVER AND OVER AND OVER... ;TEST FOR OVERFLOW, TEST LOAD LIMIT, COMPARE HL,DE -SUB1: +SUB1: ; at 0x4CCE MOV A,D ; CMP H ; RNZ ; @@ -193,15 +201,15 @@ MOV A,E ; CMP L ; RET -;BEGINNING OF IN BUFFER -VAR1: +;BEGINNING OF IN BUFFER +VAR1: ; at 0x4CD4 DB 84h ; ADD H -VAR2: +VAR2: ; at 0x4CD5 DB 0 ; NOP DB 4Ch ; MOV C,H -VAR3: +VAR3: ; at 0x4CD7 DB 24h ; INR H DB 0D6h, 56h ; SUI $56 DB 16h, 0 ; MVI D,0 diff --git a/application/src/main/files/examples/altair8800/boot/mdbl.asm b/application/src/main/files/examples/altair8800/boot/mdbl.asm index b21df40ec..4c490e565 100644 --- a/application/src/main/files/examples/altair8800/boot/mdbl.asm +++ b/application/src/main/files/examples/altair8800/boot/mdbl.asm @@ -1,118 +1,132 @@ -; reverse-engineered modified disk boot loader (mdbl.bin) from simh emulator - -org 0FF00h - -di -ld b, 80h - -ld a, 0Eh - -l1: -out (0FEh), a -dec b -jp nz, l1 - -ld a, 16h -out (0FEh), a -ld a, 12h -out (0FEh), a - -in a, (0FEh) -or a -jp z, l2 -ld a, 0Ch -out (0FEh), a -xor a -out (0FEh), a - -l2: -ld hl, 5C00h -ld de, l4 -ld c, 88h - -l3: -ld a, (de) -ld (hl), a -inc de -inc hl -dec c -jp nz, l3 -jp 5C00h - -l4: -ld sp, 5D21h -ld a, 0 -out (8h), a -ld a, 4 -out (9h), a -jp 5C19h - -in a, (8h) -and 2 -jp nz, 5C0Eh -ld a, 2 -out (9h), a -in a, (8h) -and 40h -jp nz, 5C0Eh -ld de, 0h -ld b, 8 -push bc -push de - -ld de, 8086h -ld hl, 5C88h - -in a, (9h) -rra -jp c, 5C2Dh -and 1Fh - -cp b -jp nz, 5C2Dh -in a, (8h) -or a -jp m, 5C39h -in a, (0Ah) - -ld (hl), a -inc hl -dec e -jp nz, 5C39h -pop de -ld hl, 5C8Bh -ld b, 80h -ld a, (hl) -ld (de), a -inc hl -inc de -dec b -jp nz, 5C4Dh -pop bc -ld hl, 5C00h -ld a, d -cp h -jp nz, 5C60h -ld a, e -cp l -jp nc, 5C80h -inc b -inc b - -ld a, b -cp 20h -jp c, 5C25h -ld b, 1 -jp z, 5C25h - -in a, (8h) -and 2h -jp nz, 5C70h -ld a, 1 -out (9h), a -ld b, 0 -jp 5C25h -ld a, 80h -out (8h), a -ei -jp 0 +; Modified Disk Boot Loader (MDBL) +; reverse-engineered from simh emulator +; only use with simh-formatted disk images + +org 0xFF00 + +di ; Disable interrupts +mvi b, 0x80 +mvi a, 0x0E ; Reset the SIMH pseudo device + +reset: +out 0xFE +dcr b +jnz reset ; Do it for 128 times + +mvi a, 0x16 ; Stop timer interrupts +out 0xFE +mvi a, 0x12 ; Determines whether machine has banked memory +out 0xFE +in 0xFE ; Number of banks +ora a ; zero=no banks +jz copy_ourselves + +mvi a, 0x0C ; Select bank +out 0xFE +xra a ; bank=0 +out 0xFE + +copy_ourselves: +lxi h, 0x5C00 ; destination address +lxi d, start ; source address +mvi c, 0x88 ; 136 times (bytes) + +do_copy: +ldax d ; A <- source +mov m, a ; dest <- A +inx d +inx h +dcr c +jnz do_copy +jmp 0x5C00 + +; ORG 0x5C00 ; cannot do that in emuStudio +start: ; at 0x5C00 +lxi sp, 0x5D21 +mvi a, 0 ; drive 0 +out 0x8 ; select (track = sector = 0) +mvi a, 4 ; head load +out 0x9 +jmp 0x5C19 + +in 0x8 ; at 0x5C0E; read status port +ani 2 ; when 0, head movement allowed +jnz 0x5C0E ; repeat until head movement allowed + +mvi a, 2 ; head out +out 0x9 +in 0x8 ; at 0x5C19; read status port +ani 0x40 ; when 0, indicates head is on track 0 +jnz 0x5C0E ; repeat until head is on track 0 + +lxi d, 0 +mvi b, 0x8 ; boot sector number + +push b ; at 0x5C25 +push d + +lxi d, 0x8086 ; data read count: D=unimportant, E=data count (0x86 = 134 bytes = 1 sector) +lxi h, 0x5C88 ; destination where to read disk data + +in 0x9 ; at 0x5C2D; next sector if head is loaded, read sector number +rar ; port2: x x n n n n n t; where x-unused, n-sector number, t-sector true +jc 0x5C2D ; repeat until "sector true" + +ani 0x1F ; get just sector number +cmp b ; is it the one we requested? +jnz 0x5C2D ; if not, repeat with next sector + +in 0x8 ; at 0x5C39; read status port +ora a ; test 0x80 bit (sign flag will be set in this case) +jm 0x5C39 ; When bit7=0, indicates that read circuit has new byte to read, otherwise repeat + +in 0x0A ; read data from disk +mov m, a ; (hl) <- data byte +inx h +dcr e ; count-- +jnz 0x5C39 ; if count!=0, repeat + +pop d ; DE=0 +lxi h, 0x5C8B ; source address (where the sector is loaded), ignore first 3 bytes +mvi b, 0x80 ; data count (=128 bytes sector) + +mov a, m ; at 0x5C4D; A <- (HL) +stax d ; (DE) <- A +inx h +inx d +dcr b +jnz 0x5C4D ; repeat until 128 bytes are read + +pop b ; B=sector number +lxi h, 0x5C00 ; our code start address +mov a, d ; latest dest address high byte (where the copy ended so far) +cmp h ; are we crossing 0x5C00 boundary? +jnz 0x5C60 ; jump if H != D + +mov a, e ; latest dest address low byte +cmp l ; are we crossing 0x00 boundary ? (only if D=0x5C) + +jnc 0x5C80 ; at 0x5C60 - CY=H>D or (H=D and L>E); if H<=D or (H=D and L<=E) - we're DONE. + ; that means we are copying at least 5C00 data since initially D=0 +inr b ; sector++ +inr b ; sector++ (continue skewed sector line) +mov a, b +cpi 0x20 ; sector < 32 ? +jc 0x5C25 ; if yes, jump to read next sector + +mvi b, 1 ; new sector number (new skewed sector line) +jz 0x5C25 ; sector == 32 (the last one); if yes jump to read sector "line" starting at B + +in 0x8 ; at 0x5C70; here the sector number > 32 (must increment track); read status port +ani 2 ; when 0, head movement is allowed +jnz 0x5C70 ; repeat until head movement is allowed + +mvi a, 1 ; head in (track++; sector=0) +out 0x9 +mvi b, 0 ; new sector number (new skewed sector line) +jmp 0x5C25 ; read the "line" + +mvi a, 0x80 ; at 0x5C80; unselect drive +out 0x8 +ei ; enable interrupts +jmp 0 ; jump to CP/M "kernel" diff --git a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java index 00825eb04..293c401fc 100644 --- a/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java +++ b/plugins/device/simh-pseudo/src/main/java/net/emustudio/plugins/device/simh/Commands.java @@ -37,7 +37,7 @@ public enum Commands { getClockCPM3Cmd, // 9 get the current time in CP/M 3 format setClockCPM3Cmd, // 10 set the current time in CP/M 3 format getBankSelectCmd, // 11 get the selected bank - setBankSelectCmd, // 12 set the selected bank + setBankSelectCmd, // 12 select bank getCommonCmd, // 13 get the base address of the common memory segment resetSIMHInterfaceCmd, // 14 reset the SIMH pseudo device showTimerCmd, // 15 show time difference to timer on top of stack From 7159733b8bb05491d6ba0eb3611274625921faec Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 23 Feb 2023 14:05:32 +0100 Subject: [PATCH 269/314] [#315] 88-sio in Altair8800: disable interrupts by default --- application/src/main/files/config/MITSAltair8800.toml | 1 + application/src/main/files/config/MITSAltair8800Z80.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/application/src/main/files/config/MITSAltair8800.toml b/application/src/main/files/config/MITSAltair8800.toml index 719be7e08..141dce695 100644 --- a/application/src/main/files/config/MITSAltair8800.toml +++ b/application/src/main/files/config/MITSAltair8800.toml @@ -109,6 +109,7 @@ clearOutputBit8 = false inputToUpperCase = false mapDeleteChar = "UNCHANGED" mapBackspaceChar = "UNCHANGED" +interruptsSupported = false inputInterruptVector = 7 outputInterruptVector = 7 diff --git a/application/src/main/files/config/MITSAltair8800Z80.toml b/application/src/main/files/config/MITSAltair8800Z80.toml index d3ddb974a..cad2bf3b6 100644 --- a/application/src/main/files/config/MITSAltair8800Z80.toml +++ b/application/src/main/files/config/MITSAltair8800Z80.toml @@ -108,6 +108,7 @@ clearOutputBit8 = false inputToUpperCase = false mapDeleteChar = "UNCHANGED" mapBackspaceChar = "UNCHANGED" +interruptsSupported = true inputInterruptVector = 7 outputInterruptVector = 7 From f65a8e316ae061e15ef908d80bbe0eef7a85a1db Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 23 Feb 2023 14:10:42 +0100 Subject: [PATCH 270/314] [#315] Fix equal_count.ram --- .../ramc-ram/src/main/examples/equal_count.ram | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram index 227365766..a95600fc3 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram @@ -12,22 +12,22 @@ read_next: jz final_test sub=1 jz increment - load1 + load 1 sub=2 jz decrement jmp read_next increment: - load2 + load 2 add=1 - store2 + store 2 jmp read_next decrement: load 2 sub=1 - store2 + store 2 jmp read_next final_test: - load2 + load 2 jz print_one write=0 halt From b61b1c8e315a44dcbb9133988c11eaae5dd55e21 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 23 Feb 2023 14:16:39 +0100 Subject: [PATCH 271/314] [#315] ramc-ram: Fix examples --- plugins/compiler/ramc-ram/src/main/examples/copy.ram | 4 ++-- plugins/compiler/ramc-ram/src/main/examples/reverse.ram | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/compiler/ramc-ram/src/main/examples/copy.ram b/plugins/compiler/ramc-ram/src/main/examples/copy.ram index d6f876ac7..cecd23d01 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/copy.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/copy.ram @@ -1,4 +1,4 @@ - 3 4 ignored world hello + 3 4 'ignored' 'world' 'hello' ; COPY(X,Y) ; @@ -11,7 +11,7 @@ ; reg.Y: (reg.Y) - sss + 'sss' ; load X,Y read 1 read 2 diff --git a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram index 516f942dc..2227e78d5 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram @@ -1,7 +1,7 @@ ; input : X0 - string X zero-ended, X in {1,2,3,....}*, on the input tape ; output: XR - reverse of X - 1 2 3 3 2 1 2 3 5.5 3 4 5 53 34 2 34 + 1 2 3 3 2 1 2 3 '5.5' 3 4 5 53 34 2 34 load =10 store 2 From c3f5fdf3aa84f8c40c427e7b5d04fa92c0fa0108 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 24 Feb 2023 12:03:43 +0100 Subject: [PATCH 272/314] [#315] ram-cpu, abstract-tape: Fix RAM emulator + change cmdline args in emuStudio app --- .../emustudio/application/cmdline/Runner.java | 10 +- .../plugins/cpu/intel8080/EmulatorEngine.java | 4 +- .../plugins/cpu/ram/EmulatorEngine.java | 110 ++++++++---------- .../plugins/cpu/ram/EmulatorEngineTest.java | 53 +++++---- .../abstracttape/AbstractTapeContextImpl.java | 6 + .../abstracttape/api/AbstractTapeContext.java | 12 +- .../device/abstracttape/api/TapeSymbol.java | 10 ++ .../device/abstracttape/gui/TapeModel.java | 8 +- 8 files changed, 115 insertions(+), 98 deletions(-) diff --git a/application/src/main/java/net/emustudio/application/cmdline/Runner.java b/application/src/main/java/net/emustudio/application/cmdline/Runner.java index 420ff8375..3a4a2a4de 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/Runner.java +++ b/application/src/main/java/net/emustudio/application/cmdline/Runner.java @@ -58,7 +58,7 @@ public class Runner implements Runnable { public Exclusive exclusive; @CommandLine.Option(names = {"-i", "--input-file"}, description = "input file name (source code)", paramLabel = "FILE") public Path inputFile; - @CommandLine.Option(names = {"-l", "--list-computers"}, description = "list all existing virtual computers") + @CommandLine.Option(names = {"-cl", "--computers-list"}, description = "list all existing virtual computers") private boolean listConfigs; public static void main(String[] args) { @@ -126,8 +126,8 @@ public void run() { } public static class Exclusive { - @CommandLine.Option(names = {"-c", "--computer"}, - description = "virtual computer name (see -l for options)", + @CommandLine.Option(names = {"-cn", "--computer-name"}, + description = "virtual computer name (see -cl for options)", paramLabel = "NAME" ) public String configName; @@ -140,8 +140,8 @@ public static class Exclusive { public Path configFile; @CommandLine.Option( - names = {"-cn", "--computer-index"}, - description = "virtual computer index (see -l for options)", + names = {"-ci", "--computer-index"}, + description = "virtual computer index (see -cl for options)", paramLabel = "INDEX" ) public Integer configIndex; diff --git a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java index f82b15136..4a7978dc5 100644 --- a/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java +++ b/plugins/cpu/8080-cpu/src/main/java/net/emustudio/plugins/cpu/intel8080/EmulatorEngine.java @@ -509,7 +509,7 @@ public int I_ACI() { return 7; } - public int I_OUT() throws IOException { + public int I_OUT() { int DAR = readByte(PC); PC = (PC + 1) & 0xFFFF; context.fireIO(DAR, false, (byte) regs[REG_A]); @@ -529,7 +529,7 @@ public int I_SUI() { return 7; } - public int I_IN() throws IOException { + public int I_IN() { int DAR = readByte(PC); PC = (PC + 1) & 0xFFFF; regs[REG_A] = context.fireIO(DAR, true, (byte) 0) & 0xFF; diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java index c8ca08f3b..12ff7bce9 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/EmulatorEngine.java @@ -25,7 +25,6 @@ import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; import net.emustudio.plugins.memory.ram.api.RAMValue; -import java.io.IOException; import java.util.Objects; import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; @@ -65,66 +64,64 @@ public void reset(int location) { outputTape.clear(); } - public CPU.RunState step() throws IOException { - RAMInstruction instr = memory.read(IP.getAndIncrement()); - if (instr == null) { + public CPU.RunState step() { + RAMInstruction instruction = memory.read(IP.getAndIncrement()); + if (instruction == null) { return CPU.RunState.STATE_STOPPED_BAD_INSTR; } - switch (instr.getOpcode()) { + switch (instruction.getOpcode()) { case READ: TapeSymbol input = inputTape.readData(); inputTape.moveRight(); - getRegister(instr).ifPresent(r -> storageTape.setSymbolAt(r, input)); + getRegisterNumber(instruction).ifPresent(r -> storageTape.setSymbolAt(r, input)); break; case WRITE: - getValue(instr).ifPresent(outputTape::writeData); + evaluateOperand(instruction).ifPresent(outputTape::writeData); outputTape.moveRight(); break; case LOAD: - getValue(instr).ifPresent(s -> storageTape.setSymbolAt(0, s)); + evaluateOperand(instruction).ifPresent(v -> storageTape.setSymbolAt(0, v)); break; case STORE: - getRegister(instr) - .ifPresent(o -> storageTape.getSymbolAt(0).ifPresent(r -> storageTape.setSymbolAt(o, r))); + TapeSymbol r0 = storageTape.getSymbolAt(0).orElse(TapeSymbol.EMPTY); + getRegisterNumber(instruction).ifPresent(r -> storageTape.setSymbolAt(r, r0)); break; case ADD: - getValue(instr).ifPresent(op -> arithmetic(op, Integer::sum)); + evaluateOperand(instruction).ifPresent(v -> arithmetic(v, Integer::sum)); break; case SUB: - getValue(instr).ifPresent(op -> arithmetic(op, (a, b) -> a - b)); + evaluateOperand(instruction).ifPresent(v -> arithmetic(v, (a, b) -> a - b)); break; case MUL: - getValue(instr).ifPresent(op -> arithmetic(op, (a, b) -> a * b)); + evaluateOperand(instruction).ifPresent(v -> arithmetic(v, (a, b) -> a * b)); break; case DIV: - getValue(instr).ifPresent(op -> arithmetic(op, (a, b) -> a / b)); + evaluateOperand(instruction).ifPresent(v -> arithmetic(v, (a, b) -> a / b)); break; case JMP: - instr + instruction .getLabel() .ifPresentOrElse(o -> IP.set(o.getAddress()), () -> { - throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); + throw new RuntimeException("Instruction operand contains non-numeric value: " + instruction); }); break; case JZ: { - int r0 = getR0(); - if (r0 == 0) { - instr + if (isEmpty(storageTape.getSymbolAt(0).orElse(TapeSymbol.EMPTY))) { + instruction .getLabel() .ifPresentOrElse(o -> IP.set(o.getAddress()), () -> { - throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); + throw new RuntimeException("Instruction operand contains non-numeric value: " + instruction); }); } break; } case JGTZ: { - int r0 = getR0(); - if (r0 > 0) { - instr + if (getR0() > 0) { + instruction .getLabel() .ifPresentOrElse(o -> IP.set(o.getAddress()), () -> { - throw new RuntimeException("Instruction operand contains non-numeric value: " + instr); + throw new RuntimeException("Instruction operand contains non-numeric value: " + instruction); }); } break; @@ -140,57 +137,50 @@ public CPU.RunState step() throws IOException { private int getR0() { return storageTape .getSymbolAt(0) - .filter(r0 -> r0 != TapeSymbol.EMPTY) - .map(r0 -> { - if (r0.type != TapeSymbol.Type.NUMBER) { - throw new RuntimeException("Register 0 contains non-numeric value: " + r0); - } - return r0.number; - }).orElse(0); + .orElse(TapeSymbol.EMPTY) + .number; } - private void arithmetic(TapeSymbol operand, BiFunction operation) { - if (operand.type != TapeSymbol.Type.NUMBER) { - throw new RuntimeException("Operand is non-numeric: " + operand); + private boolean isEmpty(TapeSymbol s) { + switch (s.type) { + case NUMBER: + return s.number == 0; + case STRING: + return s.string == null || s.string.isEmpty(); } - int r0 = getR0(); - storageTape.setSymbolAt(0, new TapeSymbol(operation.apply(r0, operand.number))); + throw new RuntimeException("Unexpected symbol type: " + s); + } + + private void arithmetic(TapeSymbol operand, BiFunction operation) { + storageTape.setSymbolAt(0, TapeSymbol.fromInt(operation.apply(getR0(), operand.number))); } - private Optional getValue(RAMInstruction instruction) { + private Optional getRegisterNumber(RAMInstruction instruction) { + Optional operand = instruction.getOperand(); switch (instruction.getDirection()) { case CONSTANT: - return instruction.getOperand().map(this::toSymbol); case DIRECT: + return operand.map(RAMValue::getNumberValue); case INDIRECT: - return getRegister(instruction).flatMap(storageTape::getSymbolAt); + return operand.map(RAMValue::getNumberValue) + .flatMap(storageTape::getSymbolAt) + .map(t -> t.number); } - throw new IllegalStateException("Unexpected direction: " + instruction.getDirection()); + throw new RuntimeException("Unexpected direction: " + instruction.getDirection()); } - private Optional getRegister(RAMInstruction instruction) { + private Optional evaluateOperand(RAMInstruction instruction) { + Optional operand = instruction.getOperand(); switch (instruction.getDirection()) { + case CONSTANT: + return operand.map(this::toSymbol); case DIRECT: - return instruction.getOperand().map(r -> { - if (r.getType() != RAMValue.Type.NUMBER) { - throw new RuntimeException("Instruction has non-numeric operand: " + instruction); - } - return r.getNumberValue(); - }); + return operand.map(RAMValue::getNumberValue).flatMap(storageTape::getSymbolAt); case INDIRECT: - return instruction.getOperand().flatMap(r -> { - if (r.getType() != RAMValue.Type.NUMBER) { - throw new RuntimeException("Instruction has non-numeric operand: " + instruction); - } - return storageTape - .getSymbolAt(r.getNumberValue()) - .map(rr -> { - if (rr.type != TapeSymbol.Type.NUMBER) { - throw new RuntimeException("Value of register " + rr + " is non-numeric"); - } - return rr.number; - }); - }); + return operand.map(RAMValue::getNumberValue) + .flatMap(storageTape::getSymbolAt) + .map(t -> t.number) + .flatMap(storageTape::getSymbolAt); } throw new IllegalStateException("Unexpected direction: " + instruction.getDirection()); } diff --git a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java index 841de3905..ccd224c6f 100644 --- a/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java +++ b/plugins/cpu/ram-cpu/src/test/java/net/emustudio/plugins/cpu/ram/EmulatorEngineTest.java @@ -24,7 +24,6 @@ import net.emustudio.plugins.memory.ram.api.RAMInstruction; import org.junit.Test; -import java.io.IOException; import java.util.Optional; import static org.easymock.EasyMock.*; @@ -33,7 +32,7 @@ public class EmulatorEngineTest extends AbstractEngineTest { @Test - public void testREAD_DIRECT() throws IOException { + public void testREAD_DIRECT() { setProgram(instr(RAMInstruction.Opcode.READ, RAMInstruction.Direction.DIRECT, 5)); TapeSymbol symbol = new TapeSymbol("hello"); @@ -48,7 +47,7 @@ public void testREAD_DIRECT() throws IOException { } @Test - public void testREAD_INDIRECT() throws IOException { + public void testREAD_INDIRECT() { setProgram(instr(RAMInstruction.Opcode.READ, RAMInstruction.Direction.INDIRECT, 3)); TapeSymbol symbol = new TapeSymbol("hello"); @@ -64,7 +63,7 @@ public void testREAD_INDIRECT() throws IOException { } @Test - public void testWRITE_CONSTANT() throws IOException { + public void testWRITE_CONSTANT() { setProgram(instr(RAMInstruction.Opcode.WRITE, RAMInstruction.Direction.CONSTANT, "yoohoo")); output.writeData(eq(new TapeSymbol("yoohoo"))); expectLastCall().once(); @@ -76,7 +75,7 @@ public void testWRITE_CONSTANT() throws IOException { } @Test - public void testWRITE_DIRECT() throws IOException { + public void testWRITE_DIRECT() { setProgram(instr(RAMInstruction.Opcode.WRITE, RAMInstruction.Direction.DIRECT, 3)); expect(storage.getSymbolAt(3)).andReturn(Optional.of(new TapeSymbol("yoohoo"))).once(); @@ -90,7 +89,7 @@ public void testWRITE_DIRECT() throws IOException { } @Test - public void testWRITE_INDIRECT() throws IOException { + public void testWRITE_INDIRECT() { setProgram(instr(RAMInstruction.Opcode.WRITE, RAMInstruction.Direction.INDIRECT, 3)); expect(storage.getSymbolAt(3)).andReturn(Optional.of(new TapeSymbol(5))).once(); @@ -105,7 +104,7 @@ public void testWRITE_INDIRECT() throws IOException { } @Test - public void testLOAD_CONSTANT() throws IOException { + public void testLOAD_CONSTANT() { setProgram(instr(RAMInstruction.Opcode.LOAD, RAMInstruction.Direction.CONSTANT, "yoohoo")); storage.setSymbolAt(eq(0), eq(new TapeSymbol("yoohoo"))); expectLastCall().once(); @@ -117,7 +116,7 @@ public void testLOAD_CONSTANT() throws IOException { } @Test - public void testLOAD_DIRECT() throws IOException { + public void testLOAD_DIRECT() { setProgram(instr(RAMInstruction.Opcode.LOAD, RAMInstruction.Direction.DIRECT, 3)); expect(storage.getSymbolAt(3)).andReturn(Optional.of(new TapeSymbol("yoohoo"))).once(); storage.setSymbolAt(eq(0), eq(new TapeSymbol("yoohoo"))); @@ -130,7 +129,7 @@ public void testLOAD_DIRECT() throws IOException { } @Test - public void testLOAD_INDIRECT() throws IOException { + public void testLOAD_INDIRECT() { setProgram(instr(RAMInstruction.Opcode.LOAD, RAMInstruction.Direction.INDIRECT, 5)); expect(storage.getSymbolAt(5)).andReturn(Optional.of(new TapeSymbol(3))).once(); expect(storage.getSymbolAt(3)).andReturn(Optional.of(new TapeSymbol("yoohoo"))).once(); @@ -144,7 +143,7 @@ public void testLOAD_INDIRECT() throws IOException { } @Test - public void testSTORE_DIRECT() throws IOException { + public void testSTORE_DIRECT() { setProgram(instr(RAMInstruction.Opcode.STORE, RAMInstruction.Direction.DIRECT, 5)); TapeSymbol symbol = new TapeSymbol("yoohoo"); @@ -159,7 +158,7 @@ public void testSTORE_DIRECT() throws IOException { } @Test - public void testSTORE_INDIRECT() throws IOException { + public void testSTORE_INDIRECT() { setProgram(instr(RAMInstruction.Opcode.STORE, RAMInstruction.Direction.INDIRECT, 3)); TapeSymbol symbol = new TapeSymbol("yoohoo"); @@ -175,7 +174,7 @@ public void testSTORE_INDIRECT() throws IOException { } @Test - public void testArith_CONSTANT() throws IOException { + public void testArith_CONSTANT() { setProgram( instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.CONSTANT, 5), instr(RAMInstruction.Opcode.SUB, RAMInstruction.Direction.CONSTANT, -1), @@ -207,7 +206,7 @@ public void testArith_CONSTANT() throws IOException { } @Test - public void testADD_DIRECT() throws IOException { + public void testADD_DIRECT() { setProgram( instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.DIRECT, 3), instr(RAMInstruction.Opcode.SUB, RAMInstruction.Direction.DIRECT, 4), @@ -243,7 +242,7 @@ public void testADD_DIRECT() throws IOException { } @Test - public void testADD_INDIRECT() throws IOException { + public void testADD_INDIRECT() { setProgram( instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.INDIRECT, 3), instr(RAMInstruction.Opcode.SUB, RAMInstruction.Direction.INDIRECT, 4), @@ -284,30 +283,30 @@ public void testADD_INDIRECT() throws IOException { verify(storage); } - @Test(expected = RuntimeException.class) - public void testADD_NON_NUMERIC_OPERAND() throws IOException { + @Test + public void testADD_NON_NUMERIC_OPERAND() { setProgram(instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.CONSTANT, "not allowed")); expect(storage.getSymbolAt(0)).andReturn(Optional.of(new TapeSymbol(-3))).once(); replay(storage); - assertEquals(CPU.RunState.STATE_STOPPED_BAD_INSTR, engine.step()); + assertEquals(CPU.RunState.STATE_STOPPED_BREAK, engine.step()); assertEquals(1, engine.IP.get()); verify(storage); } - @Test(expected = RuntimeException.class) - public void testADD_NON_NUMERIC_R0() throws IOException { + @Test + public void testADD_NON_NUMERIC_R0() { setProgram(instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.CONSTANT, 5)); expect(storage.getSymbolAt(0)).andReturn(Optional.of(new TapeSymbol("haha"))).once(); replay(storage); - assertEquals(CPU.RunState.STATE_STOPPED_BAD_INSTR, engine.step()); + assertEquals(CPU.RunState.STATE_STOPPED_BREAK, engine.step()); assertEquals(1, engine.IP.get()); verify(storage); } @Test - public void testADD_EMPTY_R0() throws IOException { + public void testADD_EMPTY_R0() { setProgram(instr(RAMInstruction.Opcode.ADD, RAMInstruction.Direction.CONSTANT, 5)); expect(storage.getSymbolAt(0)).andReturn(Optional.of(TapeSymbol.EMPTY)).once(); storage.setSymbolAt(eq(0), eq(new TapeSymbol(5))); @@ -320,14 +319,14 @@ public void testADD_EMPTY_R0() throws IOException { } @Test - public void testJMP() throws IOException { + public void testJMP() { setProgram(instr(RAMInstruction.Opcode.JMP, label(100, "here"))); assertEquals(CPU.RunState.STATE_STOPPED_BREAK, engine.step()); assertEquals(100, engine.IP.get()); } @Test - public void testJZ() throws IOException { + public void testJZ() { setProgram(instr(RAMInstruction.Opcode.JZ, label(0, "here"))); expect(storage.getSymbolAt(0)).andReturn(Optional.empty()).times(2); @@ -340,7 +339,7 @@ public void testJZ() throws IOException { } @Test - public void testJNZ() throws IOException { + public void testJNZ() { setProgram(instr(RAMInstruction.Opcode.JZ, RAMInstruction.Direction.DIRECT, 0)); expect(storage.getSymbolAt(0)).andReturn(Optional.of(TapeSymbol.guess("2"))).once(); @@ -352,7 +351,7 @@ public void testJNZ() throws IOException { } @Test - public void testJGTZ() throws IOException { + public void testJGTZ() { setProgram(instr(RAMInstruction.Opcode.JGTZ, label(0, "here"))); expect(storage.getSymbolAt(0)).andReturn(Optional.of(TapeSymbol.guess("2"))).times(2); @@ -365,7 +364,7 @@ public void testJGTZ() throws IOException { } @Test - public void testNotJGTZ() throws IOException { + public void testNotJGTZ() { setProgram(instr(RAMInstruction.Opcode.JGTZ, RAMInstruction.Direction.DIRECT, 0)); expect(storage.getSymbolAt(0)).andReturn(Optional.of(TapeSymbol.EMPTY)).once(); @@ -377,7 +376,7 @@ public void testNotJGTZ() throws IOException { } @Test - public void testHALT() throws IOException { + public void testHALT() { setProgram(instr(RAMInstruction.Opcode.HALT, RAMInstruction.Direction.DIRECT)); assertEquals(CPU.RunState.STATE_STOPPED_NORMAL, engine.step()); assertEquals(1, engine.IP.get()); diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java index 0478d3401..6e09fe78d 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java @@ -212,6 +212,12 @@ public void setEditable(boolean editable) { this.editable = editable; } + @Override + public List getNonEmptyPositions() { + return List.copyOf(content.keySet()); + } + + @Override public Optional getSymbolAt(int position) { rwl.readLock().lock(); diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java index 6af846d2b..49732280e 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java @@ -21,6 +21,7 @@ import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.device.DeviceContext; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -92,12 +93,21 @@ public interface AbstractTapeContext extends DeviceContext { * Allow or disallow to edit the tape. *

* If the tape is editable, the user (in GUI) can add, modify or remove symbols from the tape. - * Otherwise it is driven only by the CPU. + * Otherwise, it is driven only by the CPU. * * @param editable true if yes, false if not. */ void setEditable(boolean editable); + /** + * Get positions of non-empty (or existing) symbols. + * It is assumed tape contains infinite number of symbols, but it's not true. This method allows to retrieve + * positions which were once set, so they really exists. Size of returned list equals to the getSize() method. + * + * @return list of non-empty (existing) symbol positions + */ + List getNonEmptyPositions(); + /** * Get symbol at the specified position. * diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java index 9caff3608..71aabda43 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java @@ -23,11 +23,13 @@ import static net.emustudio.plugins.device.abstracttape.api.TapeSymbol.Type.NUMBER; import static net.emustudio.plugins.device.abstracttape.api.TapeSymbol.Type.STRING; +@SuppressWarnings("unused") public class TapeSymbol { public final static TapeSymbol EMPTY = new TapeSymbol(""); public final int number; public final String string; public final Type type; + public TapeSymbol(String string) { this.string = Objects.requireNonNullElse(string, ""); this.number = 0; @@ -49,6 +51,14 @@ public static TapeSymbol guess(String s) { } } + public static TapeSymbol fromInt(int number) { + return new TapeSymbol(number); + } + + public static TapeSymbol fromString(String s) { + return new TapeSymbol(s); + } + @Override public String toString() { return (type == NUMBER) ? String.valueOf(number) : string; diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java index ff62eecd8..881dc733d 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java @@ -35,11 +35,13 @@ public TapeModel(AbstractTapeContextImpl tapeContext) { @Override public String getElementAt(int index) { String element = ""; + int position = tapeContext.getNonEmptyPositions().get(index); if (tapeContext.getShowPositions()) { - element += String.format("%02d: ", index); + element += String.format("%02d: ", position); } - String symbolAtIndex = tapeContext.getSymbolAt(index).map(TapeSymbol::toString).orElse(""); - element += symbolAtIndex; + element += tapeContext.getSymbolAt(position) + .map(TapeSymbol::toString) + .orElse(""); return element; } From b486016465bb6155688c54119d406d96b8e78475 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 24 Feb 2023 15:58:06 +0100 Subject: [PATCH 273/314] [#315] Fix broken abstract tape --- .../ramc-ram/src/main/examples/copy.ram | 17 +- .../ramc-ram/src/main/examples/reverse.ram | 9 +- .../plugins/cpu/ram/gui/RAMDisassembler.java | 4 +- .../plugins/cpu/ram/gui/RAMStatusPanel.java | 89 +++---- plugins/device/abstract-tape/build.gradle | 1 + .../device/abstracttape/AbstractTape.java | 2 +- .../abstracttape/AbstractTapeContextImpl.java | 238 +++++++++--------- .../abstracttape/api/AbstractTapeContext.java | 22 +- .../device/abstracttape/api/TapeSymbol.java | 4 + .../device/abstracttape/gui/TapeModel.java | 21 +- 10 files changed, 200 insertions(+), 207 deletions(-) diff --git a/plugins/compiler/ramc-ram/src/main/examples/copy.ram b/plugins/compiler/ramc-ram/src/main/examples/copy.ram index cecd23d01..e6c1cc363 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/copy.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/copy.ram @@ -1,17 +1,16 @@ - 3 4 'ignored' 'world' 'hello' - -; COPY(X,Y) +; Copy R(X) to R(Y) ; -; input: -; reg.1: X -; reg.2: Y +; input tape: +; destination register: X +; source register: Y ; ; output: -; reg.X: (reg.Y) -; reg.Y: (reg.Y) +; R(X) = R(Y) +; R(Y) = R(Y) + + 3 4 'hello' 'world' - 'sss' ; load X,Y read 1 read 2 diff --git a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram index 2227e78d5..e1ae07be2 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/reverse.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/reverse.ram @@ -1,9 +1,10 @@ -; input : X0 - string X zero-ended, X in {1,2,3,....}*, on the input tape -; output: XR - reverse of X +; Reverses symbols sequence on input tape +; input: symbols, zero-ended (will work also on empty input) +; output: reverse of input - 1 2 3 3 2 1 2 3 '5.5' 3 4 5 53 34 2 34 + 1 2 3 3 2 1 2 3 '5.5' 3 4 5 53 0 34 2 34 -load =10 +load =10 ; "stack" begins here store 2 read_next: diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java index 540fc08de..cf29cfd49 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java @@ -39,11 +39,11 @@ public DisassembledInstruction disassemble(int memLocation) { RAMInstruction in = memory.read(memLocation); if (in == null) { - mnemo = "unknown instruction"; + mnemo = "none"; return new DisassembledInstruction(memLocation, mnemo, oper); } mnemo = in.getOpcode().toString() + " " + in.getDirection().value() + - in.getOperand().map(RAMValue::getStringRepresentation).orElse(""); + in.getOperand().map(RAMValue::getStringRepresentation).orElse(""); return new DisassembledInstruction(memLocation, mnemo, oper); } diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMStatusPanel.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMStatusPanel.java index 3e7f6faed..465384e68 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMStatusPanel.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMStatusPanel.java @@ -29,12 +29,12 @@ import static net.emustudio.plugins.cpu.ram.gui.Constants.MONOSPACED_PLAIN; public class RAMStatusPanel extends JPanel { + private final JLabel lblStatus = new JLabel("breakpoint"); + private final JTextField txtIP = new JTextField("0"); + private final JTextField txtInput = new JTextField("N/A"); + private final JTextField txtOutput = new JTextField("N/A"); + private final JTextField txtR0 = new JTextField("0"); - private JLabel lblStatus; - private JTextField txtIP; - private JTextField txtInput; - private JTextField txtOutput; - private JTextField txtR0; public RAMStatusPanel(final CpuImpl cpu, AbstractTapeContext input, AbstractTapeContext output) { initComponents(); @@ -63,63 +63,52 @@ public void internalStateChanged() { } private void initComponents() { - JPanel jPanel1 = new JPanel(); - JLabel jLabel1 = new JLabel(); - JLabel jLabel2 = new JLabel(); - txtR0 = new JTextField(); - txtIP = new JTextField(); + JPanel panelInternalState = new JPanel(); + JLabel lblR0 = new JLabel("R0"); + JLabel lblIP = new JLabel("IP"); JPanel jPanel2 = new JPanel(); - lblStatus = new JLabel(); JPanel jPanel3 = new JPanel(); - JLabel jLabel4 = new JLabel(); - JLabel jLabel5 = new JLabel(); - txtOutput = new JTextField(); - txtInput = new JTextField(); + JLabel lblNextInput = new JLabel("Next Input:"); + JLabel lblLastOutput = new JLabel("Last Output:"); - jPanel1.setBorder(BorderFactory.createTitledBorder("Internal state")); + panelInternalState.setBorder(BorderFactory.createTitledBorder("Internal state")); - jLabel1.setFont(MONOSPACED_PLAIN); - jLabel1.setText("R0"); - - jLabel2.setFont(MONOSPACED_PLAIN); - jLabel2.setText("IP"); - jLabel2.setToolTipText(""); + lblR0.setFont(MONOSPACED_PLAIN); + lblIP.setFont(MONOSPACED_PLAIN); txtR0.setEditable(false); txtR0.setFont(MONOSPACED_PLAIN); - txtR0.setText("0"); txtIP.setEditable(false); txtIP.setFont(MONOSPACED_PLAIN); - txtIP.setText("0"); - GroupLayout jPanel1Layout = new GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() + GroupLayout panelInternalStateLayout = new GroupLayout(panelInternalState); + panelInternalState.setLayout(panelInternalStateLayout); + panelInternalStateLayout.setHorizontalGroup( + panelInternalStateLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelInternalStateLayout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel1) + .addGroup(panelInternalStateLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addGroup(panelInternalStateLayout.createSequentialGroup() + .addComponent(lblR0) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(txtR0, GroupLayout.PREFERRED_SIZE, 120, GroupLayout.PREFERRED_SIZE)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel2) + .addGroup(panelInternalStateLayout.createSequentialGroup() + .addComponent(lblIP) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(txtIP))) .addContainerGap(64, Short.MAX_VALUE)) ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() + panelInternalStateLayout.setVerticalGroup( + panelInternalStateLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(panelInternalStateLayout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) + .addGroup(panelInternalStateLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblR0) .addComponent(txtR0, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2) + .addGroup(panelInternalStateLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(lblIP) .addComponent(txtIP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -129,7 +118,6 @@ private void initComponents() { lblStatus.setFont(MONOSPACED_BIG_BOLD); lblStatus.setForeground(new java.awt.Color(0, 153, 51)); lblStatus.setHorizontalAlignment(SwingConstants.CENTER); - lblStatus.setText("breakpoint"); GroupLayout jPanel2Layout = new GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); @@ -150,16 +138,11 @@ private void initComponents() { jPanel3.setBorder(BorderFactory.createTitledBorder("Input / output")); - jLabel4.setText("Next Input:"); - jLabel5.setText("Last Output:"); - txtOutput.setEditable(false); txtOutput.setFont(MONOSPACED_PLAIN); - txtOutput.setText("N/A"); txtInput.setEditable(false); txtInput.setFont(MONOSPACED_PLAIN); - txtInput.setText("N/A"); GroupLayout jPanel3Layout = new GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); @@ -168,8 +151,8 @@ private void initComponents() { .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jLabel5) - .addComponent(jLabel4)) + .addComponent(lblLastOutput) + .addComponent(lblNextInput)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) .addComponent(txtOutput, GroupLayout.DEFAULT_SIZE, 109, Short.MAX_VALUE) @@ -181,11 +164,11 @@ private void initComponents() { .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4) + .addComponent(lblNextInput) .addComponent(txtInput, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5) + .addComponent(lblLastOutput) .addComponent(txtOutput, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -197,7 +180,7 @@ private void initComponents() { .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelInternalState, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) @@ -206,7 +189,7 @@ private void initComponents() { layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(jPanel1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(panelInternalState, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) diff --git a/plugins/device/abstract-tape/build.gradle b/plugins/device/abstract-tape/build.gradle index 1f4ce3cf0..a98bd8f9d 100644 --- a/plugins/device/abstract-tape/build.gradle +++ b/plugins/device/abstract-tape/build.gradle @@ -27,6 +27,7 @@ plugins { dependencies { implementation libs.emuLib implementation libs.slf4JApi + implementation libs.jcipAnnotations testImplementation libs.junit testImplementation libs.slf4JSimple diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java index 45ad9bb8d..d50d9f840 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTape.java @@ -55,9 +55,9 @@ public class AbstractTape extends AbstractDevice { public AbstractTape(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); - this.context = new AbstractTapeContextImpl(this); this.guiSupported = !settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false); this.automaticEmulation = settings.getBoolean(PluginSettings.EMUSTUDIO_AUTO, false); + this.context = new AbstractTapeContextImpl(this::setGUITitle); try { applicationApi.getContextPool().register(pluginID, context, AbstractTapeContext.class); diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java index 6e09fe78d..157b78ca8 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java @@ -20,6 +20,8 @@ import net.emustudio.plugins.device.abstracttape.api.AbstractTapeContext; import net.emustudio.plugins.device.abstracttape.api.TapeSymbol; +import net.jcip.annotations.GuardedBy; +import net.jcip.annotations.ThreadSafe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,65 +34,66 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Consumer; +import java.util.function.Supplier; +@ThreadSafe public class AbstractTapeContextImpl implements AbstractTapeContext { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTapeContextImpl.class); - private final AtomicReference symbolLog = new AtomicReference<>(); - private final Map content = new HashMap<>(); - private final Set acceptedTypes = new HashSet<>(Set.of( + + private final AtomicReference> acceptedTypes = new AtomicReference<>(Set.of( TapeSymbol.Type.NUMBER, TapeSymbol.Type.STRING )); + private final Consumer titleSetter; + private final AtomicReference title = new AtomicReference<>("abstract-tape"); + + private final AtomicBoolean leftBounded = new AtomicBoolean(); + private final AtomicBoolean editable = new AtomicBoolean(true); + private final AtomicBoolean highlightCurrentPosition = new AtomicBoolean(true); + private final AtomicBoolean clearAtReset = new AtomicBoolean(true); + private final AtomicBoolean displayRowNumbers = new AtomicBoolean(); + private final AtomicReference listener = new AtomicReference<>(); + private final AtomicReference symbolWriter = new AtomicReference<>(); private final ReadWriteLock rwl = new ReentrantReadWriteLock(); + @GuardedBy("rwl") + private final SortedMap content = new TreeMap<>(); + @GuardedBy("rwl") + private int position = 0; - private final AbstractTape tape; + public interface TapeListener { - private int position = 0; - private boolean leftBounded; - private boolean editable; - private boolean highlightCurrentPosition; - private boolean clearAtReset = true; - private boolean displayRowNumbers = false; - private TapeListener listener; + void tapeChanged(); + } - AbstractTapeContextImpl(AbstractTape tape) { - this.tape = Objects.requireNonNull(tape); - leftBounded = false; - editable = true; - highlightCurrentPosition = true; + AbstractTapeContextImpl(Consumer titleSetter) { + this.titleSetter = Objects.requireNonNull(titleSetter); } @Override public void setAcceptTypes(TapeSymbol.Type... types) { - writeSynchronized(() -> { - acceptedTypes.clear(); - acceptedTypes.addAll(Arrays.asList(types)); - }); + acceptedTypes.set(Set.of(types)); } @Override public Set getAcceptedTypes() { - rwl.readLock().lock(); - try { - return Collections.unmodifiableSet(acceptedTypes); - } finally { - rwl.readLock().unlock(); - } + return acceptedTypes.get(); } @Override public void setTitle(String title) { - tape.setGUITitle(title); + titleSetter.accept(title); + this.title.set(title); } @Override public boolean getShowPositions() { - return displayRowNumbers; + return displayRowNumbers.get(); } @Override public void setShowPositions(boolean showPositions) { - this.displayRowNumbers = showPositions; + displayRowNumbers.set(showPositions); fireChange(); } @@ -107,7 +110,7 @@ public void clear() { } void reset() { - if (clearAtReset) { + if (clearAtReset.get()) { clear(); } else { writeSynchronized(() -> position = 0); @@ -117,28 +120,35 @@ void reset() { @Override public boolean isLeftBounded() { - return leftBounded; + return leftBounded.get(); } @Override public void setLeftBounded(boolean bounded) { - this.leftBounded = bounded; + this.leftBounded.set(bounded); } @Override public boolean moveLeft() { AtomicBoolean moved = new AtomicBoolean(false); writeSynchronized(() -> { + boolean tmpLeftBounded = leftBounded.get(); if (position > 0) { position--; moved.set(true); - } else if (!leftBounded) { + } else if (!tmpLeftBounded) { + Map newContent = incrementContentPositions(); + content.clear(); + content.putAll(newContent); position = 0; moved.set(true); } }); - fireChange(); - return moved.get(); + if (moved.get()) { + fireChange(); + return true; + } + return false; } @Override @@ -149,22 +159,24 @@ public void moveRight() { /** * Adds symbol to the beginning of this tape. + * Head position is preserved on the symbol before adding. * * @param symbol tape symbol * @throws IllegalArgumentException if the symbol type is not among accepted ones */ public void addFirst(TapeSymbol symbol) { - if (leftBounded) { - return; + if (!acceptedTypes.get().contains(symbol.type)) { + throw new IllegalArgumentException("Tape symbol type is not accepted"); } writeSynchronized(() -> { - if (!acceptedTypes.contains(symbol.type)) { - throw new IllegalArgumentException("Tape symbol type is not accepted"); + if (!leftBounded.get()) { + Map newContent = incrementContentPositions(); + content.clear(); + content.putAll(newContent); + content.put(0, symbol); + position++; + logSymbol(0, symbol); } - incrementContentPositions(); - content.put(0, symbol); - logSymbol(0, symbol); - position++; }); fireChange(); } @@ -172,18 +184,19 @@ public void addFirst(TapeSymbol symbol) { /** * Adds symbol at the end of this tape. * The "end" is computed as the highest position + 1. + * Head position is preserved on the symbol before adding. * * @param symbol tape symbol * @throws IllegalArgumentException if the symbol type is not among accepted ones */ public void addLast(TapeSymbol symbol) { + if (!acceptedTypes.get().contains(symbol.type)) { + throw new IllegalArgumentException("Tape symbol type is not accepted"); + } writeSynchronized(() -> { - if (!acceptedTypes.contains(symbol.type)) { - throw new IllegalArgumentException("Tape symbol type is not accepted"); - } int index = position; if (!content.isEmpty()) { - index = Collections.max(content.keySet()) + 1; + index = content.lastKey() + 1; } content.put(index, symbol); logSymbol(index, symbol); @@ -193,50 +206,51 @@ public void addLast(TapeSymbol symbol) { @Override public void removeSymbolAt(int position) { + if (position < 0) { + throw new IllegalArgumentException("Position must be >= 0. Was: " + position); + } writeSynchronized(() -> { content.remove(position); logSymbol(position, TapeSymbol.EMPTY); - if (this.position >= position) { - this.position = (position > 0) ? position - 1 : 0; - } }); fireChange(); } public boolean getEditable() { - return editable; + return editable.get(); } @Override public void setEditable(boolean editable) { - this.editable = editable; + this.editable.set(editable); } - @Override - public List getNonEmptyPositions() { - return List.copyOf(content.keySet()); + public Map.Entry getSymbolAtIndex(int index) { + return readSynchronized(() -> { + Iterator> it = content.entrySet().iterator(); + int i = 0; + Map.Entry symbol = Map.entry(0, TapeSymbol.EMPTY); + while (i++ <= index && it.hasNext()) { + symbol = it.next(); + } + return symbol; + }); } - @Override public Optional getSymbolAt(int position) { - rwl.readLock().lock(); - try { - return Optional.ofNullable(content.get(position)); - } finally { - rwl.readLock().unlock(); - } + return readSynchronized(() -> Optional.ofNullable(content.get(position))); } @Override public void setSymbolAt(int position, TapeSymbol symbol) { if (position < 0) { - return; + throw new IllegalArgumentException("Position must be >= 0. Was: " + position); + } + if (!acceptedTypes.get().contains(symbol.type)) { + throw new IllegalArgumentException("Tape symbol type is not accepted"); } writeSynchronized(() -> { - if (!acceptedTypes.contains(symbol.type)) { - throw new IllegalArgumentException("Tape symbol type is not accepted"); - } content.put(position, symbol); logSymbol(position, symbol); }); @@ -245,56 +259,36 @@ public void setSymbolAt(int position, TapeSymbol symbol) { @Override public void setHighlightHeadPosition(boolean highlight) { - highlightCurrentPosition = highlight; + highlightCurrentPosition.set(highlight); } @Override public void setClearAtReset(boolean clear) { - this.clearAtReset = clear; + this.clearAtReset.set(clear); } public boolean highlightCurrentPosition() { - return highlightCurrentPosition; + return highlightCurrentPosition.get(); } @Override public int getSize() { - rwl.readLock().lock(); - try { - return content.size(); - } finally { - rwl.readLock().unlock(); - } + return readSynchronized(content::size); } @Override public int getHeadPosition() { - rwl.readLock().lock(); - try { - return position; - } finally { - rwl.readLock().unlock(); - } + return readSynchronized(() -> position); } @Override public boolean isEmpty() { - rwl.readLock().lock(); - try { - return content.isEmpty(); - } finally { - rwl.readLock().unlock(); - } + return readSynchronized(content::isEmpty); } @Override public TapeSymbol readData() { - rwl.readLock().lock(); - try { - return content.getOrDefault(position, TapeSymbol.EMPTY); - } finally { - rwl.readLock().unlock(); - } + return readSynchronized(() -> content.getOrDefault(position, TapeSymbol.EMPTY)); } @Override @@ -316,9 +310,10 @@ public Class getDataType() { */ void setLogSymbols(boolean logSymbols) { // should be called in a synchronized context + String tmpTitle = title.get(); if (!logSymbols) { - Writer w = symbolLog.getAndSet(null); + Writer w = symbolWriter.getAndSet(null); if (w != null) { LOGGER.info("Stopping logging symbols changes"); try { @@ -328,13 +323,14 @@ void setLogSymbols(boolean logSymbols) { } } } else { - String fileName = createValidFileName(tape.getTitle().trim()) + ".out"; + String fileName = createValidFileName(tmpTitle.trim()) + ".out"; File file = new File(fileName + ".out"); LOGGER.info("Starting logging symbols changes to a file:" + fileName); try { Writer w = new FileWriter(file); - if (!symbolLog.compareAndSet(null, w)) { - w.close(); + Writer old = symbolWriter.getAndSet(w); + if (old != null) { + old.close(); } } catch (IOException e) { LOGGER.error("Could not create the symbol log file", e); @@ -343,30 +339,23 @@ void setLogSymbols(boolean logSymbols) { } public void setListener(TapeListener listener) { - this.listener = listener; + this.listener.set(listener); } - private void writeSynchronized(Runnable r) { - rwl.writeLock().lock(); - try { - r.run(); - } finally { - rwl.writeLock().unlock(); - } - } private void fireChange() { - if (listener != null) { - listener.tapeChanged(); + TapeListener tmp = listener.get(); + if (tmp != null) { + tmp.tapeChanged(); } } private void logSymbol(int position, TapeSymbol symbol) { - Writer w = symbolLog.get(); - if (w != null) { + Writer tmp = symbolWriter.get(); + if (tmp != null) { try { - w.write(position + " " + symbol + "\n"); - w.flush(); + tmp.write(position + " " + symbol + "\n"); + tmp.flush(); } catch (IOException e) { LOGGER.error("Could not write a symbol to symbol log", e); } @@ -377,18 +366,29 @@ private String createValidFileName(String str) { return str.trim().toLowerCase().replaceAll("[*.#%&\\s+!~/?<>,|{}\\[\\]\\\\\"'`=]", "_"); } - // should be called in a synchronized context - private void incrementContentPositions() { - Map newContent = new HashMap<>(); + private Map incrementContentPositions() { + SortedMap newContent = new TreeMap<>(); for (int position : content.keySet()) { newContent.put(position + 1, content.get(position)); } - content.clear(); - content.putAll(newContent); + return newContent; } - public interface TapeListener extends EventListener { + private T readSynchronized(Supplier s) { + rwl.writeLock().lock(); + try { + return s.get(); + } finally { + rwl.writeLock().unlock(); + } + } - void tapeChanged(); + private void writeSynchronized(Runnable r) { + rwl.writeLock().lock(); + try { + r.run(); + } finally { + rwl.writeLock().unlock(); + } } } diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java index 49732280e..e7fb0b598 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/AbstractTapeContext.java @@ -20,8 +20,9 @@ import net.emustudio.emulib.plugins.annotations.PluginContext; import net.emustudio.emulib.plugins.device.DeviceContext; +import net.jcip.annotations.ThreadSafe; -import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; @@ -31,9 +32,11 @@ * The tape head can move to the left, or to the right. If a tape is left-bounded, it cannot move to the left * beyond the first symbol. *

- * A CPU must setup the tape. + * Symbols are indexed from 0. + * A CPU must set up the tape (set the title, etc.). */ @SuppressWarnings("unused") +@ThreadSafe @PluginContext public interface AbstractTapeContext extends DeviceContext { @@ -100,13 +103,12 @@ public interface AbstractTapeContext extends DeviceContext { void setEditable(boolean editable); /** - * Get positions of non-empty (or existing) symbols. - * It is assumed tape contains infinite number of symbols, but it's not true. This method allows to retrieve - * positions which were once set, so they really exists. Size of returned list equals to the getSize() method. + * Get symbol at index. * - * @return list of non-empty (existing) symbol positions + * @param index 0-based index; max value = Math.max(0, getSize() - 1) + * @return symbol at index */ - List getNonEmptyPositions(); + Map.Entry getSymbolAtIndex(int index); /** * Get symbol at the specified position. @@ -118,19 +120,19 @@ public interface AbstractTapeContext extends DeviceContext { /** * Set symbol at the specified position. - *

- * If the position is < 0, then no symbol will be set. * * @param position position in the tape, starting from 0 * @param symbol symbol value - * @throws IllegalArgumentException if the symbol type is not among accepted ones + * @throws IllegalArgumentException if the symbol type is not among accepted ones, or position is < 0 */ void setSymbolAt(int position, TapeSymbol symbol); /** * Remove symbol at given position + * Head position is preserved. * * @param position symbol position in the tape + * @throws IllegalArgumentException if position < 0 */ void removeSymbolAt(int position); diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java index 71aabda43..d54f3f392 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/api/TapeSymbol.java @@ -18,14 +18,18 @@ */ package net.emustudio.plugins.device.abstracttape.api; +import net.jcip.annotations.Immutable; + import java.util.Objects; import static net.emustudio.plugins.device.abstracttape.api.TapeSymbol.Type.NUMBER; import static net.emustudio.plugins.device.abstracttape.api.TapeSymbol.Type.STRING; @SuppressWarnings("unused") +@Immutable public class TapeSymbol { public final static TapeSymbol EMPTY = new TapeSymbol(""); + public final int number; public final String string; public final Type type; diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java index 881dc733d..37b16ef3f 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/gui/TapeModel.java @@ -23,35 +23,38 @@ import net.emustudio.plugins.device.abstracttape.api.TapeSymbol; import javax.swing.*; +import java.util.Map; import java.util.Objects; -public class TapeModel extends AbstractListModel { +public class TapeModel extends DefaultListModel { private final AbstractTapeContext tapeContext; + private volatile int currentSize; public TapeModel(AbstractTapeContextImpl tapeContext) { this.tapeContext = Objects.requireNonNull(tapeContext); + this.currentSize = tapeContext.getSize(); } @Override public String getElementAt(int index) { + Map.Entry symbol = tapeContext.getSymbolAtIndex(index); + String element = ""; - int position = tapeContext.getNonEmptyPositions().get(index); if (tapeContext.getShowPositions()) { - element += String.format("%02d: ", position); + element = String.format("%02d: ", symbol.getKey()); } - element += tapeContext.getSymbolAt(position) - .map(TapeSymbol::toString) - .orElse(""); - + element += symbol.getValue().toString(); return element; } @Override public int getSize() { - return tapeContext.getSize(); + return currentSize; } public void fireChange() { - this.fireContentsChanged(this, 0, tapeContext.getSize() - 1); + int newSize = tapeContext.getSize(); + currentSize = newSize; + this.fireContentsChanged(this, 0, newSize - 1); } } From 3222364da5f9778a93a51fa176b0c6b444af8aa8 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 24 Feb 2023 16:13:00 +0100 Subject: [PATCH 274/314] [#315] ram-cpu: improve disassembler --- .../src/main/examples/equal_count.ram | 20 ++++++++++--------- .../plugins/cpu/ram/gui/RAMDisassembler.java | 12 +++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram index a95600fc3..e8681b086 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/equal_count.ram @@ -1,36 +1,38 @@ -; input: X0 - string X zero-ended, X in {1,2,3,....}*, on the input tape +; Equal Count of 1s and 2s +; input: symbols (string "X"), zero-ended ; output: 1 if N1(X) = N2(X) (i.e. if X contains equal number of "1" and "2") ; 0 otherwise - 1 2 3 3 2 1 1 33 21 1 2 1 2 112 2 1 2 11 2 1 2 21 2 1 + 1 2 3 3 2 1 1 33 21 1 2 1 2 112 2 1 2 11 2 1 2 21 1 0 -load=0 +load =0 store 2 + read_next: read 1 load 1 jz final_test - sub=1 + sub =1 jz increment load 1 - sub=2 + sub =2 jz decrement jmp read_next increment: load 2 - add=1 + add =1 store 2 jmp read_next decrement: load 2 - sub=1 + sub =1 store 2 jmp read_next final_test: load 2 jz print_one - write=0 + write =0 halt print_one: - write=1 + write =1 halt diff --git a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java index cf29cfd49..781777273 100644 --- a/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java +++ b/plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/RAMDisassembler.java @@ -35,16 +35,14 @@ public RAMDisassembler(RAMMemoryContext memory) { @Override public DisassembledInstruction disassemble(int memLocation) { - String mnemo, oper = ""; - RAMInstruction in = memory.read(memLocation); if (in == null) { - mnemo = "none"; - return new DisassembledInstruction(memLocation, mnemo, oper); + return new DisassembledInstruction(memLocation, "", ""); } - mnemo = in.getOpcode().toString() + " " + in.getDirection().value() + - in.getOperand().map(RAMValue::getStringRepresentation).orElse(""); - return new DisassembledInstruction(memLocation, mnemo, oper); + String mnemo = String.format("%s %s%s", + in.getOpcode().toString().toLowerCase(), in.getDirection().value(), + in.getOperand().map(RAMValue::getStringRepresentation).orElse("").toUpperCase()); + return new DisassembledInstruction(memLocation, mnemo, ""); } @Override From 3e9c49bf0fbaeae3d75a81b348b59cebde471019 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 24 Feb 2023 16:18:32 +0100 Subject: [PATCH 275/314] [#315] ramc-ram: doc example --- .../compiler/ramc-ram/src/main/examples/ones_count.ram | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram b/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram index 3410ade4f..eb19b0297 100644 --- a/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram +++ b/plugins/compiler/ramc-ram/src/main/examples/ones_count.ram @@ -1,11 +1,13 @@ -; input : X0 - string X zero-ended, X in {1,2,3,....}*, on the input tape -; output: N1(X) - number of ones in X. +; Counts 1s +; input : symbols (string "X"), zero-ended +; output: number of ones in X + 1 2 3 4 5 6 7 1 1 1 2 5 0 load =0 store 2 -read_next: +read_next: read 1 load 1 jz print From 18b2952b2f6a9718795a62e6ca80bea9f60e299d Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Fri, 24 Feb 2023 16:45:11 +0100 Subject: [PATCH 276/314] [#315] rasp-cpu: Redesign status panel + refactorings --- .../plugins/compiler/ram/CompilerRAM.java | 6 +- .../plugins/compiler/ram/ProgramParser.java | 36 ++-- .../plugins/compiler/ram/ast/Instruction.java | 24 +-- .../plugins/compiler/ram/ast/Label.java | 4 +- .../plugins/compiler/ram/ast/Program.java | 14 +- .../plugins/compiler/ram/ast/Value.java | 4 +- .../compiler/ram/AbstractCompilerTest.java | 8 +- .../plugins/compiler/ram/CompilerTest.java | 78 +++---- .../plugins/compiler/ram/MemoryStub.java | 38 ++-- .../plugins/compiler/rasp/CompilerRASP.java | 10 +- .../plugins/compiler/rasp/ast/Label.java | 4 +- .../plugins/compiler/rasp/ast/Program.java | 28 +-- .../compiler/rasp/AbstractCompilerTest.java | 8 +- .../plugins/compiler/rasp/CompilerTest.java | 12 +- .../plugins/compiler/rasp/MemoryStub.java | 30 +-- plugins/cpu/ram-cpu/build.gradle | 1 + .../emustudio/plugins/cpu/ram/CpuImpl.java | 20 +- .../plugins/cpu/ram/EmulatorEngine.java | 34 +-- ...ontextImpl.java => RamCpuContextImpl.java} | 6 +- ...{RAMCpuContext.java => RamCpuContext.java} | 2 +- .../plugins/cpu/ram/gui/LabelDebugColumn.java | 10 +- ...Disassembler.java => RamDisassembler.java} | 16 +- ...AMStatusPanel.java => RamStatusPanel.java} | 13 +- .../plugins/cpu/ram/AbstractEngineTest.java | 50 ++--- .../plugins/cpu/ram/EmulatorEngineTest.java | 64 +++--- plugins/cpu/rasp-cpu/build.gradle | 1 + .../emustudio/plugins/cpu/rasp/CpuImpl.java | 20 +- .../plugins/cpu/rasp/EmulatorEngine.java | 12 +- ...ntextImpl.java => RaspCpuContextImpl.java} | 4 +- ...ASPCpuContext.java => RaspCpuContext.java} | 2 +- .../plugins/cpu/rasp/gui/Constants.java | 8 + .../cpu/rasp/gui/LabelDebugColumn.java | 10 +- .../cpu/rasp/gui/RASPCpuStatusPanel.java | 144 ------------- ...isassembler.java => RaspDisassembler.java} | 44 ++-- .../plugins/cpu/rasp/gui/RaspStatusPanel.java | 196 ++++++++++++++++++ .../plugins/cpu/rasp/EmulatorEngineTest.java | 24 +-- .../plugins/cpu/rasp/MemoryStub.java | 30 +-- ...{RASPCell.java => RaspMemoryCellImpl.java} | 16 +- .../plugins/memory/ram/MemoryContextImpl.java | 48 ++--- .../plugins/memory/ram/MemoryImpl.java | 4 +- ...AMInstruction.java => RamInstruction.java} | 6 +- .../ram/api/{RAMLabel.java => RamLabel.java} | 2 +- ...moryContext.java => RamMemoryContext.java} | 10 +- .../ram/api/{RAMValue.java => RamValue.java} | 2 +- .../plugins/memory/ram/gui/MemoryDialog.java | 4 +- ...{RAMTableModel.java => RamTableModel.java} | 20 +- .../memory/ram/MemoryContextImplTest.java | 8 +- .../memory/rasp/MemoryContextImpl.java | 44 ++-- .../plugins/memory/rasp/MemoryImpl.java | 4 +- .../api/{RASPLabel.java => RaspLabel.java} | 2 +- ...ASPMemoryCell.java => RaspMemoryCell.java} | 2 +- ...oryContext.java => RaspMemoryContext.java} | 6 +- .../plugins/memory/rasp/gui/Disassembler.java | 3 +- .../plugins/memory/rasp/gui/MemoryDialog.java | 6 +- ...ASPTableModel.java => RaspTableModel.java} | 26 ++- 55 files changed, 646 insertions(+), 582 deletions(-) rename plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/{RAMCpuContextImpl.java => RamCpuContextImpl.java} (94%) rename plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/api/{RAMCpuContext.java => RamCpuContext.java} (95%) rename plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/{RAMDisassembler.java => RamDisassembler.java} (77%) rename plugins/cpu/ram-cpu/src/main/java/net/emustudio/plugins/cpu/ram/gui/{RAMStatusPanel.java => RamStatusPanel.java} (97%) rename plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/{RASPCpuContextImpl.java => RaspCpuContextImpl.java} (95%) rename plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/api/{RASPCpuContext.java => RaspCpuContext.java} (95%) create mode 100644 plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/Constants.java delete mode 100644 plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/RASPCpuStatusPanel.java rename plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/{RASPDisassembler.java => RaspDisassembler.java} (54%) create mode 100644 plugins/cpu/rasp-cpu/src/main/java/net/emustudio/plugins/cpu/rasp/gui/RaspStatusPanel.java rename plugins/cpu/rasp-cpu/src/test/java/net/emustudio/plugins/cpu/rasp/{RASPCell.java => RaspMemoryCellImpl.java} (70%) rename plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/{RAMInstruction.java => RamInstruction.java} (94%) rename plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/{RAMLabel.java => RamLabel.java} (95%) rename plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/{RAMMemoryContext.java => RamMemoryContext.java} (81%) rename plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/api/{RAMValue.java => RamValue.java} (97%) rename plugins/memory/ram-mem/src/main/java/net/emustudio/plugins/memory/ram/gui/{RAMTableModel.java => RamTableModel.java} (77%) rename plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/{RASPLabel.java => RaspLabel.java} (95%) rename plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/{RASPMemoryCell.java => RaspMemoryCell.java} (94%) rename plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/api/{RASPMemoryContext.java => RaspMemoryContext.java} (89%) rename plugins/memory/rasp-mem/src/main/java/net/emustudio/plugins/memory/rasp/gui/{RASPTableModel.java => RaspTableModel.java} (87%) diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java index 1840c0f0c..82a11805b 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/CompilerRAM.java @@ -28,7 +28,7 @@ import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.compiler.ram.ast.Program; -import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; +import net.emustudio.plugins.memory.ram.api.RamMemoryContext; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; @@ -46,7 +46,7 @@ public class CompilerRAM extends AbstractCompiler { private final static Logger LOGGER = LoggerFactory.getLogger(CompilerRAM.class); private static final List SOURCE_FILE_EXTENSIONS = List.of(new SourceFileExtension("ram", "Random Access Machine source")); - private RAMMemoryContext memory; + private RamMemoryContext memory; public CompilerRAM(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { super(pluginID, applicationApi, settings); @@ -70,7 +70,7 @@ public String getDescription() { public void initialize() { Optional.ofNullable(applicationApi.getContextPool()).ifPresent(pool -> { try { - memory = pool.getMemoryContext(pluginID, RAMMemoryContext.class); + memory = pool.getMemoryContext(pluginID, RamMemoryContext.class); } catch (InvalidContextException | ContextNotFoundException e) { LOGGER.warn("Memory is not available", e); } diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ProgramParser.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ProgramParser.java index 97f4f3c00..8bbf319c8 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ProgramParser.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ProgramParser.java @@ -22,7 +22,7 @@ import net.emustudio.plugins.compiler.ram.ast.Label; import net.emustudio.plugins.compiler.ram.ast.Program; import net.emustudio.plugins.compiler.ram.ast.Value; -import net.emustudio.plugins.memory.ram.api.RAMInstruction; +import net.emustudio.plugins.memory.ram.api.RamInstruction; import org.antlr.v4.runtime.Token; import java.util.HashMap; @@ -34,21 +34,21 @@ import static net.emustudio.plugins.compiler.ram.RAMParser.*; public class ProgramParser extends RAMParserBaseVisitor { - private final static Map tokenOpcodes = new HashMap<>(); + private final static Map tokenOpcodes = new HashMap<>(); static { - tokenOpcodes.put(OPCODE_READ, RAMInstruction.Opcode.READ); - tokenOpcodes.put(OPCODE_WRITE, RAMInstruction.Opcode.WRITE); - tokenOpcodes.put(OPCODE_LOAD, RAMInstruction.Opcode.LOAD); - tokenOpcodes.put(OPCODE_STORE, RAMInstruction.Opcode.STORE); - tokenOpcodes.put(OPCODE_ADD, RAMInstruction.Opcode.ADD); - tokenOpcodes.put(OPCODE_SUB, RAMInstruction.Opcode.SUB); - tokenOpcodes.put(OPCODE_MUL, RAMInstruction.Opcode.MUL); - tokenOpcodes.put(OPCODE_DIV, RAMInstruction.Opcode.DIV); - tokenOpcodes.put(OPCODE_JMP, RAMInstruction.Opcode.JMP); - tokenOpcodes.put(OPCODE_JZ, RAMInstruction.Opcode.JZ); - tokenOpcodes.put(OPCODE_JGTZ, RAMInstruction.Opcode.JGTZ); - tokenOpcodes.put(OPCODE_HALT, RAMInstruction.Opcode.HALT); + tokenOpcodes.put(OPCODE_READ, RamInstruction.Opcode.READ); + tokenOpcodes.put(OPCODE_WRITE, RamInstruction.Opcode.WRITE); + tokenOpcodes.put(OPCODE_LOAD, RamInstruction.Opcode.LOAD); + tokenOpcodes.put(OPCODE_STORE, RamInstruction.Opcode.STORE); + tokenOpcodes.put(OPCODE_ADD, RamInstruction.Opcode.ADD); + tokenOpcodes.put(OPCODE_SUB, RamInstruction.Opcode.SUB); + tokenOpcodes.put(OPCODE_MUL, RamInstruction.Opcode.MUL); + tokenOpcodes.put(OPCODE_DIV, RamInstruction.Opcode.DIV); + tokenOpcodes.put(OPCODE_JMP, RamInstruction.Opcode.JMP); + tokenOpcodes.put(OPCODE_JZ, RamInstruction.Opcode.JZ); + tokenOpcodes.put(OPCODE_JGTZ, RamInstruction.Opcode.JGTZ); + tokenOpcodes.put(OPCODE_HALT, RamInstruction.Opcode.HALT); } private final Program program; @@ -78,13 +78,13 @@ public Program visitRLine(RAMParser.RLineContext ctx) { @Override public Program visitRInstruction(RAMParser.RInstructionContext ctx) { Token op = ctx.op; - RAMInstruction.Opcode opcode = tokenOpcodes.get(op.getType()); - RAMInstruction.Direction direction = RAMInstruction.Direction.DIRECT; + RamInstruction.Opcode opcode = tokenOpcodes.get(op.getType()); + RamInstruction.Direction direction = RamInstruction.Direction.DIRECT; if (ctx.d != null) { if (ctx.d.getType() == OP_CONSTANT) { - direction = RAMInstruction.Direction.CONSTANT; + direction = RamInstruction.Direction.CONSTANT; } else if (ctx.d.getType() == OP_INDIRECT) { - direction = RAMInstruction.Direction.INDIRECT; + direction = RamInstruction.Direction.INDIRECT; } } Value operand = null; diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java index 02e80027f..51f3d9815 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Instruction.java @@ -19,30 +19,30 @@ package net.emustudio.plugins.compiler.ram.ast; import net.emustudio.plugins.compiler.ram.SerializableOptional; -import net.emustudio.plugins.memory.ram.api.RAMInstruction; -import net.emustudio.plugins.memory.ram.api.RAMLabel; -import net.emustudio.plugins.memory.ram.api.RAMValue; +import net.emustudio.plugins.memory.ram.api.RamInstruction; +import net.emustudio.plugins.memory.ram.api.RamLabel; +import net.emustudio.plugins.memory.ram.api.RamValue; import java.util.Objects; import java.util.Optional; -public class Instruction implements RAMInstruction { +public class Instruction implements RamInstruction { public final int line; public final int column; private final int address; private final Opcode opcode; private final Direction direction; - private final SerializableOptional operand; - private SerializableOptional label; + private final SerializableOptional operand; + private SerializableOptional label; public Instruction(int line, int column, Opcode opcode, Direction direction, - int address, Optional operand) { + int address, Optional operand) { this(line, column, opcode, direction, address, operand, null); } public Instruction(int line, int column, Opcode opcode, Direction direction, - int address, Optional operand, RAMLabel label) { + int address, Optional operand, RamLabel label) { this.opcode = opcode; this.direction = direction; this.address = address; @@ -53,7 +53,7 @@ public Instruction(int line, int column, Opcode opcode, Direction direction, } public Instruction(Opcode opcode, Direction direction, - int address, Optional operand, RAMLabel label) { + int address, Optional operand, RamLabel label) { this(0, 0, opcode, direction, address, operand, label); } @@ -68,7 +68,7 @@ public Direction getDirection() { } @Override - public Optional getOperand() { + public Optional getOperand() { return operand.opt(); } @@ -78,11 +78,11 @@ public int getAddress() { } @Override - public Optional getLabel() { + public Optional getLabel() { return label.opt(); } - public void setLabel(RAMLabel label) { + public void setLabel(RamLabel label) { this.label = SerializableOptional.ofNullable(label); } diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java index 29df8e969..79ed6ef32 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Label.java @@ -18,9 +18,9 @@ */ package net.emustudio.plugins.compiler.ram.ast; -import net.emustudio.plugins.memory.ram.api.RAMLabel; +import net.emustudio.plugins.memory.ram.api.RamLabel; -public class Label implements RAMLabel { +public class Label implements RamLabel { public final int line; public final int column; diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java index cfddcc853..890969ede 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Program.java @@ -20,9 +20,9 @@ import net.emustudio.plugins.compiler.ram.ParsingUtils; import net.emustudio.plugins.compiler.ram.exceptions.CompileException; -import net.emustudio.plugins.memory.ram.api.RAMInstruction; -import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; -import net.emustudio.plugins.memory.ram.api.RAMValue; +import net.emustudio.plugins.memory.ram.api.RamInstruction; +import net.emustudio.plugins.memory.ram.api.RamMemoryContext; +import net.emustudio.plugins.memory.ram.api.RamValue; import java.io.*; import java.util.*; @@ -52,17 +52,17 @@ public void assignLabels() { for (Instruction instruction : instructions) { instruction .getOperand() - .filter(v -> v.getType() == RAMValue.Type.ID) - .map(RAMValue::getStringValue) + .filter(v -> v.getType() == RamValue.Type.ID) + .map(RamValue::getStringValue) .flatMap(this::getLabel) .ifPresent(instruction::setLabel); } } - public void loadIntoMemory(RAMMemoryContext memory) { + public void loadIntoMemory(RamMemoryContext memory) { memory.setLabels(new ArrayList<>(labels.values())); memory.setInputs(new ArrayList<>(inputs)); - for (RAMInstruction instruction : instructions) { + for (RamInstruction instruction : instructions) { memory.write(instruction.getAddress(), instruction); } } diff --git a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Value.java b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Value.java index 9dc558860..33ff86efb 100644 --- a/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Value.java +++ b/plugins/compiler/ramc-ram/src/main/java/net/emustudio/plugins/compiler/ram/ast/Value.java @@ -18,7 +18,7 @@ */ package net.emustudio.plugins.compiler.ram.ast; -import net.emustudio.plugins.memory.ram.api.RAMValue; +import net.emustudio.plugins.memory.ram.api.RamValue; import java.util.Objects; @@ -26,7 +26,7 @@ * The "Value" is a polymorphic value. * It has the type defined in compile time, but it can be integer or a String. */ -public class Value implements RAMValue { +public class Value implements RamValue { public final Type type; private final int intValue; private final String stringValue; diff --git a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/AbstractCompilerTest.java b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/AbstractCompilerTest.java index 8eb42ce53..5623d0287 100644 --- a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/AbstractCompilerTest.java +++ b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/AbstractCompilerTest.java @@ -23,8 +23,8 @@ import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.ContextPool; import net.emustudio.emulib.runtime.settings.PluginSettings; -import net.emustudio.plugins.memory.ram.api.RAMInstruction; -import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; +import net.emustudio.plugins.memory.ram.api.RamInstruction; +import net.emustudio.plugins.memory.ram.api.RamMemoryContext; import org.junit.Before; import org.junit.Rule; import org.junit.rules.TemporaryFolder; @@ -48,7 +48,7 @@ public void setUp() throws Exception { memoryStub = new MemoryStub(); ContextPool pool = createNiceMock(ContextPool.class); - expect(pool.getMemoryContext(0, RAMMemoryContext.class)).andReturn(memoryStub).anyTimes(); + expect(pool.getMemoryContext(0, RamMemoryContext.class)).andReturn(memoryStub).anyTimes(); replay(pool); ApplicationApi applicationApi = createNiceMock(ApplicationApi.class); @@ -87,7 +87,7 @@ protected void compile(String content) throws Exception { } } - protected void assertProgram(RAMInstruction... program) { + protected void assertProgram(RamInstruction... program) { for (int i = 0; i < program.length; i++) { assertEquals( String.format("%d. expected=%s, but was=%s", i, program[i], memoryStub.read(i)), diff --git a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/CompilerTest.java b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/CompilerTest.java index b488b16cf..62baf7460 100644 --- a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/CompilerTest.java +++ b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/CompilerTest.java @@ -24,9 +24,9 @@ import net.emustudio.plugins.compiler.ram.ast.Instruction; import net.emustudio.plugins.compiler.ram.ast.Label; import net.emustudio.plugins.compiler.ram.ast.Value; -import net.emustudio.plugins.memory.ram.api.RAMInstruction; -import net.emustudio.plugins.memory.ram.api.RAMLabel; -import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; +import net.emustudio.plugins.memory.ram.api.RamInstruction; +import net.emustudio.plugins.memory.ram.api.RamLabel; +import net.emustudio.plugins.memory.ram.api.RamMemoryContext; import org.junit.Test; import java.io.File; @@ -34,7 +34,7 @@ import java.nio.file.StandardOpenOption; import java.util.Optional; -import static net.emustudio.plugins.memory.ram.api.RAMInstruction.Opcode.*; +import static net.emustudio.plugins.memory.ram.api.RamInstruction.Opcode.*; import static org.easymock.EasyMock.*; import static org.junit.Assert.*; @@ -55,8 +55,8 @@ public void testREAD() throws Exception { compile("READ 5\nREAD *6"); assertProgram( - new Instruction(0, 0, READ, RAMInstruction.Direction.DIRECT, 0, Optional.of(new Value(5))), - new Instruction(0, 0, READ, RAMInstruction.Direction.INDIRECT, 1, Optional.of(new Value(6))) + new Instruction(0, 0, READ, RamInstruction.Direction.DIRECT, 0, Optional.of(new Value(5))), + new Instruction(0, 0, READ, RamInstruction.Direction.INDIRECT, 1, Optional.of(new Value(6))) ); } @@ -65,9 +65,9 @@ public void testWRITE() throws Exception { compile("WRITE =3\nWRITE 4\nWRITE *8"); assertProgram( - new Instruction(0, 0, WRITE, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value(3))), - new Instruction(0, 0, WRITE, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(4))), - new Instruction(0, 0, WRITE, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(8))) + new Instruction(0, 0, WRITE, RamInstruction.Direction.CONSTANT, 0, Optional.of(new Value(3))), + new Instruction(0, 0, WRITE, RamInstruction.Direction.DIRECT, 1, Optional.of(new Value(4))), + new Instruction(0, 0, WRITE, RamInstruction.Direction.INDIRECT, 2, Optional.of(new Value(8))) ); } @@ -76,9 +76,9 @@ public void testLOAD() throws Exception { compile("LOAD ='hello'\nLOAD 7\nLOAD *11"); assertProgram( - new Instruction(0, 0, LOAD, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("hello", false))), - new Instruction(0, 0, LOAD, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(7))), - new Instruction(0, 0, LOAD, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(11))) + new Instruction(0, 0, LOAD, RamInstruction.Direction.CONSTANT, 0, Optional.of(new Value("hello", false))), + new Instruction(0, 0, LOAD, RamInstruction.Direction.DIRECT, 1, Optional.of(new Value(7))), + new Instruction(0, 0, LOAD, RamInstruction.Direction.INDIRECT, 2, Optional.of(new Value(11))) ); } @@ -87,8 +87,8 @@ public void testSTORE() throws Exception { compile("STORE 111111112\nSTORE *55\n"); assertProgram( - new Instruction(0, 0, STORE, RAMInstruction.Direction.DIRECT, 0, Optional.of(new Value(111111112))), - new Instruction(0, 0, STORE, RAMInstruction.Direction.INDIRECT, 1, Optional.of(new Value(55))) + new Instruction(0, 0, STORE, RamInstruction.Direction.DIRECT, 0, Optional.of(new Value(111111112))), + new Instruction(0, 0, STORE, RamInstruction.Direction.INDIRECT, 1, Optional.of(new Value(55))) ); } @@ -97,9 +97,9 @@ public void testADD() throws Exception { compile("ADD =\"omg omg\"\nADD 99\nADD *1"); assertProgram( - new Instruction(0, 0, ADD, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), - new Instruction(0, 0, ADD, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(99))), - new Instruction(0, 0, ADD, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(1))) + new Instruction(0, 0, ADD, RamInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), + new Instruction(0, 0, ADD, RamInstruction.Direction.DIRECT, 1, Optional.of(new Value(99))), + new Instruction(0, 0, ADD, RamInstruction.Direction.INDIRECT, 2, Optional.of(new Value(1))) ); } @@ -108,9 +108,9 @@ public void testSUB() throws Exception { compile("SUB =\"omg omg\"\nSUB 229\nSUB *2453"); assertProgram( - new Instruction(0, 0, SUB, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), - new Instruction(0, 0, SUB, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), - new Instruction(0, 0, SUB, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) + new Instruction(0, 0, SUB, RamInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), + new Instruction(0, 0, SUB, RamInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), + new Instruction(0, 0, SUB, RamInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) ); } @@ -119,9 +119,9 @@ public void testMUL() throws Exception { compile("MUL =\"omg omg\"\nMUL 229\nMUL *2453"); assertProgram( - new Instruction(0, 0, MUL, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), - new Instruction(0, 0, MUL, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), - new Instruction(0, 0, MUL, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) + new Instruction(0, 0, MUL, RamInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), + new Instruction(0, 0, MUL, RamInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), + new Instruction(0, 0, MUL, RamInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) ); } @@ -130,9 +130,9 @@ public void testDIV() throws Exception { compile("DIV =\"omg omg\"\nDIV 229\nDIV *2453"); assertProgram( - new Instruction(0, 0, DIV, RAMInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), - new Instruction(0, 0, DIV, RAMInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), - new Instruction(0, 0, DIV, RAMInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) + new Instruction(0, 0, DIV, RamInstruction.Direction.CONSTANT, 0, Optional.of(new Value("omg omg", false))), + new Instruction(0, 0, DIV, RamInstruction.Direction.DIRECT, 1, Optional.of(new Value(229))), + new Instruction(0, 0, DIV, RamInstruction.Direction.INDIRECT, 2, Optional.of(new Value(2453))) ); } @@ -141,11 +141,11 @@ public void testJMP() throws Exception { compile("here: JMP here"); assertProgram(new Instruction( - JMP, RAMInstruction.Direction.DIRECT, 0, + JMP, RamInstruction.Direction.DIRECT, 0, Optional.of(new Value("here", true)), new Label(0, 0, "here", 0) )); - assertEquals(Optional.of(0), memoryStub.read(0).getLabel().map(RAMLabel::getAddress)); + assertEquals(Optional.of(0), memoryStub.read(0).getLabel().map(RamLabel::getAddress)); } @Test @@ -154,12 +154,12 @@ public void testJMP_ForwardReference() throws Exception { assertProgram( new Instruction( - JMP, RAMInstruction.Direction.DIRECT, 0, + JMP, RamInstruction.Direction.DIRECT, 0, Optional.of(new Value("here", true)), new Label(0, 0, "here", 1)), - new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 1, Optional.empty()) + new Instruction(0, 0, HALT, RamInstruction.Direction.DIRECT, 1, Optional.empty()) ); - assertEquals(Optional.of(1), memoryStub.read(0).getLabel().map(RAMLabel::getAddress)); + assertEquals(Optional.of(1), memoryStub.read(0).getLabel().map(RamLabel::getAddress)); } @Test @@ -168,12 +168,12 @@ public void testJZ() throws Exception { assertProgram( new Instruction( - JZ, RAMInstruction.Direction.DIRECT, 0, + JZ, RamInstruction.Direction.DIRECT, 0, Optional.of(new Value("here", true)), new Label(0, 0, "here", 1)), - new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 1, Optional.empty()) + new Instruction(0, 0, HALT, RamInstruction.Direction.DIRECT, 1, Optional.empty()) ); - assertEquals(Optional.of(1), memoryStub.read(0).getLabel().map(RAMLabel::getAddress)); + assertEquals(Optional.of(1), memoryStub.read(0).getLabel().map(RamLabel::getAddress)); } @Test @@ -182,12 +182,12 @@ public void testJGTZ() throws Exception { assertProgram( new Instruction( - JGTZ, RAMInstruction.Direction.DIRECT, 0, + JGTZ, RamInstruction.Direction.DIRECT, 0, Optional.of(new Value("here", true)), new Label(0, 0, "here", 1)), - new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 1, Optional.empty()) + new Instruction(0, 0, HALT, RamInstruction.Direction.DIRECT, 1, Optional.empty()) ); - assertEquals(Optional.of(1), memoryStub.read(0).getLabel().map(RAMLabel::getAddress)); + assertEquals(Optional.of(1), memoryStub.read(0).getLabel().map(RamLabel::getAddress)); } @Test @@ -195,7 +195,7 @@ public void testHALT() throws Exception { compile("halt"); assertProgram( - new Instruction(0, 0, HALT, RAMInstruction.Direction.DIRECT, 0, Optional.empty()) + new Instruction(0, 0, HALT, RamInstruction.Direction.DIRECT, 0, Optional.empty()) ); } @@ -207,7 +207,7 @@ public void testNegativeRegistersAreNotSupported() throws Exception { @Test public void testCompileWithoutSpecifyingOutputDoesNotOverwriteSource() throws Exception { ContextPool tmpContextPool = createMock(ContextPool.class); - expect(tmpContextPool.getMemoryContext(0L, RAMMemoryContext.class)).andReturn(memoryStub).anyTimes(); + expect(tmpContextPool.getMemoryContext(0L, RamMemoryContext.class)).andReturn(memoryStub).anyTimes(); replay(tmpContextPool); ApplicationApi applicationApi = createNiceMock(ApplicationApi.class); diff --git a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java index 1c46226c3..ff320d7b0 100644 --- a/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java +++ b/plugins/compiler/ramc-ram/src/test/java/net/emustudio/plugins/compiler/ram/MemoryStub.java @@ -19,41 +19,41 @@ package net.emustudio.plugins.compiler.ram; import net.emustudio.emulib.plugins.memory.AbstractMemoryContext; -import net.emustudio.plugins.memory.ram.api.RAMInstruction; -import net.emustudio.plugins.memory.ram.api.RAMLabel; -import net.emustudio.plugins.memory.ram.api.RAMMemoryContext; -import net.emustudio.plugins.memory.ram.api.RAMValue; +import net.emustudio.plugins.memory.ram.api.RamInstruction; +import net.emustudio.plugins.memory.ram.api.RamLabel; +import net.emustudio.plugins.memory.ram.api.RamMemoryContext; +import net.emustudio.plugins.memory.ram.api.RamValue; import java.util.*; -public class MemoryStub extends AbstractMemoryContext implements RAMMemoryContext { - private final RAMInstruction[] memory = new RAMInstruction[1000]; - private final Map labels = new HashMap<>(); - private final List inputs = new ArrayList<>(); +public class MemoryStub extends AbstractMemoryContext implements RamMemoryContext { + private final RamInstruction[] memory = new RamInstruction[1000]; + private final Map labels = new HashMap<>(); + private final List inputs = new ArrayList<>(); @Override - public RAMInstruction read(int address) { + public RamInstruction read(int address) { return memory[address]; } @Override - public RAMInstruction[] read(int address, int count) { + public RamInstruction[] read(int address, int count) { return Arrays.copyOfRange(memory, address, count); } @Override - public void write(int address, RAMInstruction value) { + public void write(int address, RamInstruction value) { memory[address] = value; } @Override - public void write(int address, RAMInstruction[] instructions, int count) { + public void write(int address, RamInstruction[] instructions, int count) { System.arraycopy(instructions, 0, this.memory, address, count); } @Override - public Class getDataType() { - return RAMInstruction.class; + public Class getDataType() { + return RamInstruction.class; } @Override @@ -69,25 +69,25 @@ public int getSize() { } @Override - public void setLabels(List labels) { + public void setLabels(List labels) { this.labels.clear(); - for (RAMLabel label : labels) { + for (RamLabel label : labels) { this.labels.put(label.getAddress(), label); } } @Override - public Optional getLabel(int address) { + public Optional getLabel(int address) { return Optional.ofNullable(labels.get(address)); } @Override - public List getInputs() { + public List getInputs() { return inputs; } @Override - public void setInputs(List inputs) { + public void setInputs(List inputs) { this.inputs.addAll(inputs); } } diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java index 776fd1a4a..98a5a1f7f 100644 --- a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/CompilerRASP.java @@ -29,8 +29,8 @@ import net.emustudio.emulib.runtime.InvalidContextException; import net.emustudio.emulib.runtime.settings.PluginSettings; import net.emustudio.plugins.compiler.rasp.ast.Program; -import net.emustudio.plugins.memory.rasp.api.RASPMemoryCell; -import net.emustudio.plugins.memory.rasp.api.RASPMemoryContext; +import net.emustudio.plugins.memory.rasp.api.RaspMemoryCell; +import net.emustudio.plugins.memory.rasp.api.RaspMemoryContext; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; @@ -52,7 +52,7 @@ public class CompilerRASP extends AbstractCompiler { new SourceFileExtension("rasp", "RASP source file") ); - private RASPMemoryContext memory; + private RaspMemoryContext memory; private int programLocation; public CompilerRASP(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { @@ -63,7 +63,7 @@ public CompilerRASP(long pluginID, ApplicationApi applicationApi, PluginSettings public void initialize() { Optional.ofNullable(applicationApi.getContextPool()).ifPresent(pool -> { try { - memory = pool.getMemoryContext(pluginID, RASPMemoryContext.class); + memory = pool.getMemoryContext(pluginID, RaspMemoryContext.class); } catch (InvalidContextException | ContextNotFoundException e) { LOGGER.warn("Memory is not available", e); } @@ -87,7 +87,7 @@ public boolean compile(String inputFileName, String outputFileName) { Program program = new Program(); new ProgramParser(program).visit(parser.rStart()); - Map compiled = program.compile(); + Map compiled = program.compile(); this.programLocation = program.getProgramLocation(compiled); program.saveToFile(outputFileName, compiled); diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java index 7a0dfa3cb..143caa73b 100644 --- a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Label.java @@ -18,9 +18,9 @@ */ package net.emustudio.plugins.compiler.rasp.ast; -import net.emustudio.plugins.memory.rasp.api.RASPLabel; +import net.emustudio.plugins.memory.rasp.api.RaspLabel; -public class Label implements RASPLabel { +public class Label implements RaspLabel { public final int line; public final int column; diff --git a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Program.java b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Program.java index 031b62bf2..4b53cda47 100644 --- a/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Program.java +++ b/plugins/compiler/raspc-rasp/src/main/java/net/emustudio/plugins/compiler/rasp/ast/Program.java @@ -20,8 +20,8 @@ import net.emustudio.plugins.compiler.rasp.ParsingUtils; import net.emustudio.plugins.compiler.rasp.exceptions.CompileException; -import net.emustudio.plugins.memory.rasp.api.RASPMemoryCell; -import net.emustudio.plugins.memory.rasp.api.RASPMemoryContext; +import net.emustudio.plugins.memory.rasp.api.RaspMemoryCell; +import net.emustudio.plugins.memory.rasp.api.RaspMemoryContext; import java.io.*; import java.util.*; @@ -47,14 +47,14 @@ public void add(int input) { this.inputs.add(input); } - public Map compile() { - Map compiled = new HashMap<>(); + public Map compile() { + Map compiled = new HashMap<>(); for (Instruction instruction : instructions) { - RASPMemoryCell instrCell = new RASPMemoryCellImpl(true, instruction.opcode, instruction.address); + RaspMemoryCell instrCell = new RaspMemoryCellImpl(true, instruction.opcode, instruction.address); compiled.put(instrCell.getAddress(), instrCell); instruction.operand.ifPresent(o -> { - RASPMemoryCell cell = new RASPMemoryCellImpl(false, o, instruction.address + 1); + RaspMemoryCell cell = new RaspMemoryCellImpl(false, o, instruction.address + 1); compiled.put(cell.getAddress(), cell); }); instruction.id.ifPresent(id -> { @@ -62,22 +62,22 @@ public Map compile() { if (label.isEmpty()) { throw new CompileException(instruction.line, instruction.column, "Label is not defined"); } - RASPMemoryCell cell = new RASPMemoryCellImpl(false, label.get().getAddress(), instruction.address + 1); + RaspMemoryCell cell = new RaspMemoryCellImpl(false, label.get().getAddress(), instruction.address + 1); compiled.put(cell.getAddress(), cell); }); } return compiled; } - public void loadIntoMemory(RASPMemoryContext memory, Map compiled) { + public void loadIntoMemory(RaspMemoryContext memory, Map compiled) { memory.setLabels(new ArrayList<>(labels.values())); memory.setInputs(new ArrayList<>(inputs)); - for (RASPMemoryCell cell : compiled.values()) { + for (RaspMemoryCell cell : compiled.values()) { memory.write(cell.getAddress(), cell); } } - public void saveToFile(String filename, Map compiled) throws IOException { + public void saveToFile(String filename, Map compiled) throws IOException { Map labels = new HashMap<>(); for (Label label : this.labels.values()) { labels.put(label.getAddress(), label.getLabel()); @@ -93,7 +93,7 @@ public void saveToFile(String filename, Map compiled) t } } - public int getProgramLocation(Map compiled) { + public int getProgramLocation(Map compiled) { return compiled.keySet().stream().min(Comparator.naturalOrder()).orElse(0); } @@ -102,12 +102,12 @@ private Optional

* The log file name will be derived from a tape title: [tape-title].out - * - * @param logSymbols whether to log symbols in a file */ - void setLogSymbols(boolean logSymbols) { + public void startLoggingSymbols() { // should be called in a synchronized context String tmpTitle = title.get(); - - if (!logSymbols) { - Writer w = symbolWriter.getAndSet(null); - if (w != null) { - LOGGER.info("Stopping logging symbols changes"); - try { - w.close(); - } catch (IOException e) { - LOGGER.error("Could not close the symbol log", e); - } + String fileName = createValidFileName(tmpTitle.trim()) + ".out"; + File file = new File(fileName); + LOGGER.info("Starting logging symbols changes to a file:" + fileName); + try { + Writer w = new FileWriter(file); + Writer old = symbolWriter.getAndSet(w); + if (old != null) { + old.close(); } - } else { - String fileName = createValidFileName(tmpTitle.trim()) + ".out"; - File file = new File(fileName + ".out"); - LOGGER.info("Starting logging symbols changes to a file:" + fileName); + } catch (IOException e) { + LOGGER.error("Could not create the symbol log file", e); + } + } + + public void stopLoggingSymbols() { + Writer w = symbolWriter.getAndSet(null); + if (w != null) { + LOGGER.info("Stopping logging symbols changes"); try { - Writer w = new FileWriter(file); - Writer old = symbolWriter.getAndSet(w); - if (old != null) { - old.close(); - } + w.close(); } catch (IOException e) { - LOGGER.error("Could not create the symbol log file", e); + LOGGER.error("Could not close the symbol log", e); } } } From a19faf06c93829db814dadb261ea6492162a9ee1 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 16 Mar 2023 09:13:37 +0100 Subject: [PATCH 300/314] [#315] automation: log computer name --- .../application/emulation/Automation.java | 104 +++++++++--------- .../abstracttape/AbstractTapeContextImpl.java | 2 +- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/application/src/main/java/net/emustudio/application/emulation/Automation.java b/application/src/main/java/net/emustudio/application/emulation/Automation.java index 4cccbe061..cbbf5ff92 100644 --- a/application/src/main/java/net/emustudio/application/emulation/Automation.java +++ b/application/src/main/java/net/emustudio/application/emulation/Automation.java @@ -75,6 +75,58 @@ public Automation(VirtualComputer computer, Path inputFile, AppSettings appSetti } } + /** + * Executes automatic emulation. + *

+ * It assumes that the virtual computer is loaded. + *

+ * All output is saved into output file. + */ + @Override + public void run() { + if (progressGUI != null) { + progressGUI.setVisible(true); + } + + LOGGER.info("Starting emulation automation..."); + LOGGER.info("Emulating computer: " + computer.getComputerConfig().getName()); + + computer.getCompiler().ifPresent( + compiler -> LOGGER.info("Compiler: " + compiler.getTitle() + ", version " + compiler.getVersion()) + ); + computer.getCPU().ifPresent(cpu -> LOGGER.info("CPU: " + cpu.getTitle() + ", version " + cpu.getVersion())); + computer.getMemory().ifPresent(memory -> { + LOGGER.info("Memory: " + memory.getTitle() + ", version " + memory.getVersion()); + LOGGER.info("Memory size: {}", memory.getSize()); + }); + computer.getDevices().forEach( + device -> LOGGER.info("Device: " + device.getTitle() + ", version " + device.getVersion()) + ); + + try { + computer.getCompiler().ifPresent(compiler -> { + Unchecked.run(() -> autoCompile(compiler)); + }); + + computer.getCPU().ifPresent(cpu -> { + setProgress("Resetting CPU...", false); + programLocation.ifPresentOrElse(l -> { + setProgress("Program start location: " + String.format("%04Xh", l), false); + cpu.reset(l); + }, cpu::reset); + autoEmulate(cpu); + }); + } catch (Exception e) { + LOGGER.error("Error during automation", e); + dialogs.showError("Error during automation. Please consult log file for details.", "Emulation automation"); + } finally { + if (progressGUI != null) { + progressGUI.dispose(); + progressGUI = null; + } + } + } + private void setProgress(String msg, boolean stopEnabled) { LOGGER.info(msg); if (progressGUI != null) { @@ -188,56 +240,4 @@ public void internalStateChanged() { setProgress("Emulation completed", false); } - - - /** - * Executes automatic emulation. - *

- * It assumes that the virtual computer is loaded. - *

- * All output is saved into output file. - */ - @Override - public void run() { - if (progressGUI != null) { - progressGUI.setVisible(true); - } - - LOGGER.info("Starting emulation automation..."); - - computer.getCompiler().ifPresent( - compiler -> LOGGER.info("Compiler: " + compiler.getTitle() + ", version " + compiler.getVersion()) - ); - computer.getCPU().ifPresent(cpu -> LOGGER.info("CPU: " + cpu.getTitle() + ", version " + cpu.getVersion())); - computer.getMemory().ifPresent(memory -> { - LOGGER.info("Memory: " + memory.getTitle() + ", version " + memory.getVersion()); - LOGGER.info("Memory size: {}", memory.getSize()); - }); - computer.getDevices().forEach( - device -> LOGGER.info("Device: " + device.getTitle() + ", version " + device.getVersion()) - ); - - try { - computer.getCompiler().ifPresent(compiler -> { - Unchecked.run(() -> autoCompile(compiler)); - }); - - computer.getCPU().ifPresent(cpu -> { - setProgress("Resetting CPU...", false); - programLocation.ifPresentOrElse(l -> { - setProgress("Program start location: " + String.format("%04Xh", l), false); - cpu.reset(l); - }, cpu::reset); - autoEmulate(cpu); - }); - } catch (Exception e) { - LOGGER.error("Error during automation", e); - dialogs.showError("Error during automation. Please consult log file for details.", "Emulation automation"); - } finally { - if (progressGUI != null) { - progressGUI.dispose(); - progressGUI = null; - } - } - } } diff --git a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java index eab30d3cd..64800b482 100644 --- a/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java +++ b/plugins/device/abstract-tape/src/main/java/net/emustudio/plugins/device/abstracttape/AbstractTapeContextImpl.java @@ -309,7 +309,7 @@ public void startLoggingSymbols() { String tmpTitle = title.get(); String fileName = createValidFileName(tmpTitle.trim()) + ".out"; File file = new File(fileName); - LOGGER.info("Starting logging symbols changes to a file:" + fileName); + LOGGER.info("Starting logging symbols changes to a file: " + fileName); try { Writer w = new FileWriter(file); Writer old = symbolWriter.getAndSet(w); From 6d1104c48bd8db12b4be2e5adbe94c0d7f3c9847 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 16 Mar 2023 11:01:01 +0100 Subject: [PATCH 301/314] [#315] automation: let gui live --- .../net/emustudio/application/cmdline/AutomationCommand.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java index 04355650e..a45dea5b0 100644 --- a/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java +++ b/application/src/main/java/net/emustudio/application/cmdline/AutomationCommand.java @@ -100,7 +100,10 @@ public void run() { splash.ifPresent(Window::dispose); automation.run(); } - System.exit(0); + if (!gui) { + // Let GUI live! + System.exit(0); + } } catch (Exception e) { LOGGER.error("Unexpected error during automation", e); dialogs.showError("Unexpected error during automation. Please see log file for details."); From cf996dcdb99f41f694eadc7f17032d2a11ba3126 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 16 Mar 2023 11:24:08 +0100 Subject: [PATCH 302/314] [#315] brainduck: change default columns,rows for vt100terminal --- application/src/main/files/config/BrainDuck.toml | 3 ++- .../compiler/brainc-brainduck/src/main/examples/mandelbrot.b | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/application/src/main/files/config/BrainDuck.toml b/application/src/main/files/config/BrainDuck.toml index 63f417ff5..b121b1026 100644 --- a/application/src/main/files/config/BrainDuck.toml +++ b/application/src/main/files/config/BrainDuck.toml @@ -27,7 +27,6 @@ type = "CPU" [[DEVICE]] schemaPoint = "320,60" path = "vt100-terminal.jar" -settings = { } name = "VT100-terminal" id = "1d858668-d63d-4127-b881-226174a2b368" type = "DEVICE" @@ -36,6 +35,8 @@ type = "DEVICE" outputFileName = "vt100-terminal.out" inputFileName = "vt100-terminal.in" inputReadDelayMillis = 0 +columns = 130 +rows = 50 [[connections]] bidirectional = true diff --git a/plugins/compiler/brainc-brainduck/src/main/examples/mandelbrot.b b/plugins/compiler/brainc-brainduck/src/main/examples/mandelbrot.b index 5e253e105..fdd1e9e8f 100644 --- a/plugins/compiler/brainc-brainduck/src/main/examples/mandelbrot.b +++ b/plugins/compiler/brainc-brainduck/src/main/examples/mandelbrot.b @@ -1,4 +1,5 @@ A mandelbrot set fractal viewer in brainf*** written by Erik Bosman + Requires terminal with at least 130 columns, 50 rows +++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[ >>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+ <<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>> From 31646f58d8fddf64bf0b887338e5f01ec0df818a Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 16 Mar 2023 11:33:44 +0100 Subject: [PATCH 303/314] [#315] adm3a, vt100: do not exception when input file doesnt exist --- .../plugins/device/adm3a/DeviceImpl.java | 2 -- .../adm3a/interaction/KeyboardFromFile.java | 20 +++++++++++-------- .../vt100/interaction/KeyboardFromFile.java | 20 +++++++++++-------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java index 78fa02eee..52f6f3c94 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/DeviceImpl.java @@ -109,8 +109,6 @@ public void initialize() throws PluginInitializationException { } catch (ContextNotFoundException e) { LOGGER.warn("The terminal is not connected to any I/O device.", e); } - - keyboard.process(); terminalSettings.addChangedObserver(this); } diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java index 88c3add0a..3e4a76c62 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/interaction/KeyboardFromFile.java @@ -41,16 +41,20 @@ public KeyboardFromFile(TerminalSettings settings) { @Override public void process() { - try (FileInputStream in = new FileInputStream(inputFile.toFile())) { - int key; - while ((key = in.read()) != -1) { - notifyOnKey((byte) key); - if (delayNanos > 0) { - SleepUtils.preciseSleepNanos(delayNanos); + if (!inputFile.toFile().exists()) { + LOGGER.warn("Input file {} does not exist", inputFile); + } else { + try (FileInputStream in = new FileInputStream(inputFile.toFile())) { + int key; + while ((key = in.read()) != -1) { + notifyOnKey((byte) key); + if (delayNanos > 0) { + SleepUtils.preciseSleepNanos(delayNanos); + } } + } catch (Exception e) { + LOGGER.error("Could not process input file", e); } - } catch (Exception e) { - LOGGER.error("Could not process input file", e); } } } diff --git a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/KeyboardFromFile.java b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/KeyboardFromFile.java index b583dce36..ee254bace 100644 --- a/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/KeyboardFromFile.java +++ b/plugins/device/vt100-terminal/src/main/java/net/emustudio/plugins/device/vt100/interaction/KeyboardFromFile.java @@ -40,16 +40,20 @@ public KeyboardFromFile(TerminalSettings settings) { } public void process() { - try (FileInputStream in = new FileInputStream(inputFile.toFile())) { - int key; - while ((key = in.read()) != -1) { - notifyOnKey((byte) key); - if (delayNanos > 0) { - SleepUtils.preciseSleepNanos(delayNanos); + if (!inputFile.toFile().exists()) { + LOGGER.warn("Input file {} does not exist", inputFile); + } else { + try (FileInputStream in = new FileInputStream(inputFile.toFile())) { + int key; + while ((key = in.read()) != -1) { + notifyOnKey((byte) key); + if (delayNanos > 0) { + SleepUtils.preciseSleepNanos(delayNanos); + } } + } catch (Exception e) { + LOGGER.error("Could not process input file", e); } - } catch (Exception e) { - LOGGER.error("Could not process input file", e); } } } From 428a47192e59cecbd00b72179626a41558e0f700 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Thu, 16 Mar 2023 11:41:05 +0100 Subject: [PATCH 304/314] [#315] as-ssem: examples --- plugins/compiler/as-ssem/src/main/examples/noodle-timer.ssem | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/compiler/as-ssem/src/main/examples/noodle-timer.ssem b/plugins/compiler/as-ssem/src/main/examples/noodle-timer.ssem index 635591f46..ebee543d1 100644 --- a/plugins/compiler/as-ssem/src/main/examples/noodle-timer.ssem +++ b/plugins/compiler/as-ssem/src/main/examples/noodle-timer.ssem @@ -38,5 +38,5 @@ 27 BNUM 11111111111111111111111111111111 29 BNUM 00000000000000000000001000111111 30 BNUM 01111011111000101111110000111111 -31 BNUM 00001011011000000000000000000001 -- timing counter for original machine +; 31 BNUM 00001011011000000000000000000001 -- timing counter for original machine 31 BNUM 01000000000000000000000000000001 -- timing counter to speed up simulation From 71c77636ab18065bf1fef214f443e852d5f6e137 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 18 Mar 2023 09:38:57 +0100 Subject: [PATCH 305/314] [#315] ssem-mem: fixed loading / dumping bssem --- .../plugins/compiler/ssem/SSEMCompiler.java | 10 ++++++---- .../plugins/memory/ssem/MemoryImpl.java | 2 +- .../plugins/memory/ssem/gui/MemoryGui.java | 8 ++++---- .../ssem/gui/actions/DumpMemoryAction.java | 9 +++++++-- .../ssem/gui/actions/LoadImageAction.java | 17 +++++++++++++---- 5 files changed, 31 insertions(+), 15 deletions(-) diff --git a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java index bb5e90a32..4ae776a38 100644 --- a/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java +++ b/plugins/compiler/as-ssem/src/main/java/net/emustudio/plugins/compiler/ssem/SSEMCompiler.java @@ -42,8 +42,10 @@ import java.io.IOException; import java.io.Reader; import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.util.*; +import java.util.List; +import java.util.MissingResourceException; +import java.util.Optional; +import java.util.ResourceBundle; import static net.emustudio.emulib.plugins.compiler.FileExtension.stripKnownExtension; @@ -128,8 +130,8 @@ public boolean compile(String inputFileName, String outputFileName) { private void writeToFile(ByteBuffer code, String outputFileName) throws IOException { code.rewind(); - try (FileChannel channel = new FileOutputStream(outputFileName, false).getChannel()) { - channel.write(code); + try (FileOutputStream fos = new FileOutputStream(outputFileName, false)) { + fos.getChannel().write(code); } } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java index cf1cbed28..ef7b67eac 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/MemoryImpl.java @@ -89,7 +89,7 @@ public int getSize() { public void showSettings(JFrame parent) { if (!guiNotSupported) { if (memoryGUI == null) { - memoryGUI = new MemoryGui(parent, memContext, applicationApi.getDialogs()); + memoryGUI = new MemoryGui(parent, memContext, applicationApi); } memoryGUI.setVisible(true); } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java index 050870588..732c5449f 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/MemoryGui.java @@ -20,7 +20,7 @@ import net.emustudio.emulib.plugins.memory.Memory; import net.emustudio.emulib.plugins.memory.MemoryContext; -import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.interaction.ToolbarButton; import net.emustudio.plugins.memory.ssem.gui.actions.DumpMemoryAction; import net.emustudio.plugins.memory.ssem.gui.actions.EraseMemoryAction; @@ -39,17 +39,17 @@ public class MemoryGui extends JDialog { private final DumpMemoryAction dumpMemoryAction; private final EraseMemoryAction eraseMemoryAction; - public MemoryGui(JFrame parent, MemoryContext memory, Dialogs dialogs) { + public MemoryGui(JFrame parent, MemoryContext memory, ApplicationApi api) { super(parent); this.tableModel = new MemoryTableModel(memory); MemoryTable table = new MemoryTable(tableModel, scrollPane); - this.loadImageAction = new LoadImageAction(dialogs, memory, () -> { + this.loadImageAction = new LoadImageAction(api, memory, () -> { table.revalidate(); table.repaint(); }); - this.dumpMemoryAction = new DumpMemoryAction(dialogs, memory); + this.dumpMemoryAction = new DumpMemoryAction(api, memory); this.eraseMemoryAction = new EraseMemoryAction(tableModel, memory); initComponents(); diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/DumpMemoryAction.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/DumpMemoryAction.java index 27312b40b..d52dcc2f3 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/DumpMemoryAction.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/DumpMemoryAction.java @@ -19,6 +19,7 @@ package net.emustudio.plugins.memory.ssem.gui.actions; import net.emustudio.emulib.plugins.memory.MemoryContext; +import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; import org.slf4j.Logger; @@ -37,13 +38,15 @@ public class DumpMemoryAction extends AbstractAction { private final static Logger LOGGER = LoggerFactory.getLogger(DumpMemoryAction.class); private final static String ICON_FILE = "/net/emustudio/plugins/memory/ssem/gui/document-save.png"; + private final ApplicationApi api; private final Dialogs dialogs; private final MemoryContext context; - public DumpMemoryAction(Dialogs dialogs, MemoryContext context) { + public DumpMemoryAction(ApplicationApi api, MemoryContext context) { super("Dump (save) memory to a file...", new ImageIcon(DumpMemoryAction.class.getResource(ICON_FILE))); - this.dialogs = Objects.requireNonNull(dialogs); + this.api = Objects.requireNonNull(api); + this.dialogs = api.getDialogs(); this.context = Objects.requireNonNull(context); putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); @@ -70,6 +73,8 @@ public void actionPerformed(ActionEvent e) { } } else { try (DataOutputStream ds = new DataOutputStream(new FileOutputStream(path.toFile()))) { + int programLocation = api.getProgramLocation() / 4; + ds.writeInt(programLocation); for (int i = 0; i < context.getSize(); i++) { ds.writeByte(context.read(i) & 0xff); } diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageAction.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageAction.java index 63dd89fda..a3d43facc 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageAction.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageAction.java @@ -19,6 +19,7 @@ package net.emustudio.plugins.memory.ssem.gui.actions; import net.emustudio.emulib.plugins.memory.MemoryContext; +import net.emustudio.emulib.runtime.ApplicationApi; import net.emustudio.emulib.runtime.helpers.NumberUtils; import net.emustudio.emulib.runtime.interaction.Dialogs; import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; @@ -29,21 +30,24 @@ import java.awt.event.KeyEvent; import java.io.File; import java.io.FileInputStream; +import java.nio.ByteBuffer; import java.nio.file.Path; import java.util.Objects; import java.util.Optional; public class LoadImageAction extends AbstractAction { private final static String ICON_FILE = "/net/emustudio/plugins/memory/ssem/gui/document-open.png"; + private final ApplicationApi api; private final Dialogs dialogs; private final MemoryContext context; private final Runnable repaint; private Path recentOpenPath; - public LoadImageAction(Dialogs dialogs, MemoryContext context, Runnable repaint) { + public LoadImageAction(ApplicationApi api, MemoryContext context, Runnable repaint) { super("Load image file...", new ImageIcon(LoadImageAction.class.getResource(ICON_FILE))); - this.dialogs = Objects.requireNonNull(dialogs); + this.api = Objects.requireNonNull(api); + this.dialogs = Objects.requireNonNull(api.getDialogs()); this.context = Objects.requireNonNull(context); this.repaint = Objects.requireNonNull(repaint); @@ -62,8 +66,13 @@ public void actionPerformed(ActionEvent e) { recentOpenPath = path; try { try (FileInputStream stream = new FileInputStream(path.toFile())) { - byte[] content = stream.readAllBytes(); - context.write(0, NumberUtils.nativeBytesToBytes(content)); + ByteBuffer code = ByteBuffer.wrap(stream.readAllBytes()); + int startLine = code.getInt(); + byte[] data = new byte[code.remaining()]; + code.get(data); + + api.setProgramLocation(startLine * 4); + context.write(0, NumberUtils.nativeBytesToBytes(data)); } repaint.run(); } catch (Exception ex) { From d931844e6f0a18fd4bb8f1f4b914aa1245062738 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 18 Mar 2023 10:27:08 +0100 Subject: [PATCH 306/314] [#315] ssem-mem: unit tests --- .../ssem/gui/actions/EraseMemoryAction.java | 6 +- .../ssem/gui/actions/LoadImageAction.java | 2 + .../gui/actions/DumpMemoryActionTest.java | 146 ++++++++++++++++++ .../gui/actions/EraseMemoryActionTest.java | 45 ++++++ .../ssem/gui/actions/LoadImageActionTest.java | 88 +++++++++++ 5 files changed, 284 insertions(+), 3 deletions(-) create mode 100644 plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/DumpMemoryActionTest.java create mode 100644 plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/EraseMemoryActionTest.java create mode 100644 plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageActionTest.java diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/EraseMemoryAction.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/EraseMemoryAction.java index 6ddbfd1e6..70a690d9b 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/EraseMemoryAction.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/EraseMemoryAction.java @@ -19,18 +19,18 @@ package net.emustudio.plugins.memory.ssem.gui.actions; import net.emustudio.emulib.plugins.memory.MemoryContext; -import net.emustudio.plugins.memory.ssem.gui.table.MemoryTableModel; import javax.swing.*; +import javax.swing.table.AbstractTableModel; import java.awt.event.ActionEvent; import java.util.Objects; public class EraseMemoryAction extends AbstractAction { private final static String ICON_FILE = "/net/emustudio/plugins/memory/ssem/gui/clear.png"; - private final MemoryTableModel tableModel; + private final AbstractTableModel tableModel; private final MemoryContext context; - public EraseMemoryAction(MemoryTableModel tableModel, MemoryContext context) { + public EraseMemoryAction(AbstractTableModel tableModel, MemoryContext context) { super("Erase memory", new ImageIcon(EraseMemoryAction.class.getResource(ICON_FILE))); this.tableModel = Objects.requireNonNull(tableModel); this.context = Objects.requireNonNull(context); diff --git a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageAction.java b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageAction.java index a3d43facc..6f0e67be7 100644 --- a/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageAction.java +++ b/plugins/memory/ssem-mem/src/main/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageAction.java @@ -62,6 +62,8 @@ public void actionPerformed(ActionEvent e) { Optional imagePath = dialogs.chooseFile( "Load image file", "Load", currentDirectory, false, new FileExtensionsFilter("Memory image", "bssem")); + + System.out.println(imagePath); imagePath.ifPresent(path -> { recentOpenPath = path; try { diff --git a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/DumpMemoryActionTest.java b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/DumpMemoryActionTest.java new file mode 100644 index 000000000..9e3a7b6cb --- /dev/null +++ b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/DumpMemoryActionTest.java @@ -0,0 +1,146 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.ssem.gui.actions; + +import net.emustudio.emulib.plugins.memory.MemoryContext; +import net.emustudio.emulib.runtime.ApplicationApi; +import net.emustudio.emulib.runtime.interaction.Dialogs; +import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter; +import net.emustudio.plugins.memory.ssem.MemoryContextImpl; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.file.Path; +import java.util.Optional; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class DumpMemoryActionTest { + private final static int PROGRAM_LOCATION = 4; + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void testNoFileIsChosen() { + DumpMemoryAction action = new DumpMemoryAction(mockApi(), new MemoryContextImpl()); + action.actionPerformed(null); + } + + @Test + public void testHumanReadableDump() throws IOException { + Path output = folder.newFolder().toPath().resolve("human-readable.txt"); + DumpMemoryAction action = new DumpMemoryAction(mockApi(output), prepareMemory()); + action.actionPerformed(null); + + String content = new String(read(output).array()); + assertEquals("0x00, 0x01, 0x02, 0x03\n" + + "0x04, 0x05, 0x06, 0x07\n" + + "0x08, 0x09, 0x0A, 0x0B\n" + + "0x0C, 0x0D, 0x0E, 0x0F\n" + + "0x10, 0x11, 0x12, 0x13\n" + + "0x14, 0x15, 0x16, 0x17\n" + + "0x18, 0x19, 0x1A, 0x1B\n" + + "0x1C, 0x1D, 0x1E, 0x1F\n" + + "0x20, 0x21, 0x22, 0x23\n" + + "0x24, 0x25, 0x26, 0x27\n" + + "0x28, 0x29, 0x2A, 0x2B\n" + + "0x2C, 0x2D, 0x2E, 0x2F\n" + + "0x30, 0x31, 0x32, 0x33\n" + + "0x34, 0x35, 0x36, 0x37\n" + + "0x38, 0x39, 0x3A, 0x3B\n" + + "0x3C, 0x3D, 0x3E, 0x3F\n" + + "0x40, 0x41, 0x42, 0x43\n" + + "0x44, 0x45, 0x46, 0x47\n" + + "0x48, 0x49, 0x4A, 0x4B\n" + + "0x4C, 0x4D, 0x4E, 0x4F\n" + + "0x50, 0x51, 0x52, 0x53\n" + + "0x54, 0x55, 0x56, 0x57\n" + + "0x58, 0x59, 0x5A, 0x5B\n" + + "0x5C, 0x5D, 0x5E, 0x5F\n" + + "0x60, 0x61, 0x62, 0x63\n" + + "0x64, 0x65, 0x66, 0x67\n" + + "0x68, 0x69, 0x6A, 0x6B\n" + + "0x6C, 0x6D, 0x6E, 0x6F\n" + + "0x70, 0x71, 0x72, 0x73\n" + + "0x74, 0x75, 0x76, 0x77\n" + + "0x78, 0x79, 0x7A, 0x7B\n" + + "0x7C, 0x7D, 0x7E, 0x7F\n", content); + } + + @Test + public void testBSSEM() throws IOException { + Path output = folder.newFolder().toPath().resolve("binary.bsem"); + DumpMemoryAction action = new DumpMemoryAction(mockApi(output), prepareMemory()); + action.actionPerformed(null); + + ByteBuffer data = read(output); + assertEquals(PROGRAM_LOCATION, data.getInt() * 4); + + for (int i = 0; i < 32 * 4; i += 4) { + byte[] row = new byte[4]; + data.get(row); + assertArrayEquals(new byte[] { (byte)i, (byte)(i+1), (byte)(i+2), (byte)(i+3) }, row); + } + } + + public static ApplicationApi mockApi() { + return mockApi(null); + } + + public static ApplicationApi mockApi(Path chosenPath) { + Dialogs dialogs = createNiceMock(Dialogs.class); + expect(dialogs.chooseFile(anyString(), anyString(), anyObject(Path.class), + eq(true), anyObject(FileExtensionsFilter.class), anyObject(FileExtensionsFilter.class))) + .andReturn(Optional.ofNullable(chosenPath)) + .anyTimes(); + expect(dialogs.chooseFile(anyString(), anyString(), anyObject(Path.class), + eq(false), anyObject(FileExtensionsFilter.class))) + .andReturn(Optional.ofNullable(chosenPath)) + .anyTimes(); + replay(dialogs); + + ApplicationApi api = createNiceMock(ApplicationApi.class); + expect(api.getDialogs()).andReturn(dialogs).anyTimes(); + expect(api.getProgramLocation()).andReturn(PROGRAM_LOCATION).anyTimes(); + replay(api); + + return api; + } + + public static ByteBuffer read(Path path) throws IOException { + try (FileInputStream stream = new FileInputStream(path.toFile())) { + return ByteBuffer.wrap(stream.readAllBytes()); + } + } + + private MemoryContext prepareMemory() { + MemoryContextImpl mem = new MemoryContextImpl(); + for (int i = 0; i < 32 * 4; i += 4) { + mem.write(i, new Byte[] { (byte)i, (byte)(i+1), (byte)(i+2), (byte)(i+3) }); + } + return mem; + } +} diff --git a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/EraseMemoryActionTest.java b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/EraseMemoryActionTest.java new file mode 100644 index 000000000..b3f81f44e --- /dev/null +++ b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/EraseMemoryActionTest.java @@ -0,0 +1,45 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.ssem.gui.actions; + +import net.emustudio.emulib.plugins.memory.MemoryContext; +import org.junit.Test; + +import javax.swing.table.AbstractTableModel; + +import static org.easymock.EasyMock.*; + +public class EraseMemoryActionTest { + + @Test + public void testEraseMemoryAction() { + AbstractTableModel tableModel = createMock(AbstractTableModel.class); + tableModel.fireTableDataChanged(); + expectLastCall().once(); + replay(tableModel); + + MemoryContext memory = createMock(MemoryContext.class); + memory.clear(); + expectLastCall().once(); + replay(memory); + + EraseMemoryAction action = new EraseMemoryAction(tableModel, memory); + action.actionPerformed(null); + } +} diff --git a/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageActionTest.java b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageActionTest.java new file mode 100644 index 000000000..a3147c417 --- /dev/null +++ b/plugins/memory/ssem-mem/src/test/java/net/emustudio/plugins/memory/ssem/gui/actions/LoadImageActionTest.java @@ -0,0 +1,88 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2023 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.memory.ssem.gui.actions; + +import net.emustudio.emulib.plugins.memory.MemoryContext; +import net.emustudio.plugins.memory.ssem.MemoryContextImpl; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.file.Path; + +import static net.emustudio.plugins.memory.ssem.gui.actions.DumpMemoryActionTest.mockApi; +import static org.easymock.EasyMock.*; + +public class LoadImageActionTest { + private final static int PROGRAM_LOCATION = 4; + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void testNoFileIsChosenWorks() { + Runnable repaint = createMock(Runnable.class); + replay(repaint); + new LoadImageAction(mockApi(), new MemoryContextImpl(), repaint).actionPerformed(null); + verify(repaint); + } + + @Test + public void testLoadBSSEM() throws IOException { + Path path = folder.newFolder().toPath().resolve("binary.bssem"); + write(path); + MemoryContext memory = createMock(MemoryContext.class); + Byte[] toWrite = new Byte[32 * 4]; + for (int i = 0; i < 32 * 4; i += 4) { + toWrite[i] = (byte) i; + toWrite[i + 1] = (byte) (i + 1); + toWrite[i + 2] = (byte) (i + 2); + toWrite[i + 3] = (byte) (i + 3); + } + memory.write(0, toWrite); + expectLastCall().once(); + replay(memory); + + Runnable repaint = createMock(Runnable.class); + repaint.run(); + expectLastCall().once(); + replay(repaint); + + LoadImageAction action = new LoadImageAction(mockApi(path), memory, repaint); + action.actionPerformed(null); + + verify(memory, repaint); + } + + + private void write(Path path) throws IOException { + ByteBuffer buffer = ByteBuffer.allocate(33 * 4); + buffer.putInt(PROGRAM_LOCATION / 4); + for (int i = 0; i < 32 * 4; i += 4) { + buffer.put(new byte[]{(byte) i, (byte) (i + 1), (byte) (i + 2), (byte) (i + 3)}); + } + buffer.flip(); + try (FileOutputStream fos = new FileOutputStream(path.toFile())) { + fos.getChannel().write(buffer); + } + } +} From b76a9a385acde7161eac9f8a9d280b4e629f61d7 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 18 Mar 2023 12:38:46 +0100 Subject: [PATCH 307/314] [#315] emuLib: 12.0.0 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 5cb2569cc..27e8de680 100644 --- a/build.gradle +++ b/build.gradle @@ -26,8 +26,8 @@ ext.versions = [ ] ext.libs = [ - emuLib : "net.emustudio:emulib:12.0.0-SNAPSHOT", - cpuTestSuite : "net.emustudio:cpu-testsuite_11.7:1.2.0", + emuLib : "net.emustudio:emulib:12.0.0", + cpuTestSuite : "net.emustudio:cpu-testsuite_12.0:1.2.0", jcipAnnotations : "net.jcip:jcip-annotations:1.0", antlr : "org.antlr:antlr4:4.11.1", From 5719631a0ea75b2bd0ed38a00a30485cbfd4aeea Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 18 Mar 2023 12:49:02 +0100 Subject: [PATCH 308/314] [#315] brainDuck: fixed compile/emulate/load/compile/reset/emulate --- .../plugins/compiler/brainduck/CompilerBrainduck.java | 2 ++ .../net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerBrainduck.java b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerBrainduck.java index a6bb2afc5..210f86c40 100644 --- a/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerBrainduck.java +++ b/plugins/compiler/brainc-brainduck/src/main/java/net/emustudio/plugins/compiler/brainduck/CompilerBrainduck.java @@ -110,6 +110,8 @@ public boolean compile(String inputFileName, String outputFileName) { )); if (memory != null) { + memory.clear(); + notifyInfo("Memory has been cleared."); hex.loadIntoMemory(memory, b -> b); notifyInfo("Compiled file was loaded into operating memory."); } else { diff --git a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java index 6876c3abd..e9c6665a6 100644 --- a/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java +++ b/plugins/cpu/brainduck-cpu/src/main/java/net/emustudio/plugins/cpu/brainduck/EmulatorEngine.java @@ -22,7 +22,6 @@ import net.emustudio.emulib.plugins.cpu.CPU; import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext; -import java.io.IOException; import java.util.ArrayDeque; import java.util.Deque; import java.util.Objects; @@ -55,6 +54,8 @@ public class EmulatorEngine { public void reset(int adr) { IP = adr; // initialize program counter + loopPointers.clear(); + profiler.reset(); // find closest "free" address which does not contain a program try { From a227182848829b9757f931978c143dcd10dfa032 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sun, 19 Mar 2023 11:55:08 +0100 Subject: [PATCH 309/314] [#315] adm-3A: shrink original font width by 75% --- .../device/adm3a/gui/DisplayCanvas.java | 3 +- .../plugins/device/adm3a/gui/DisplayFont.java | 8 +- .../device/adm3a/gui/TerminalWindow.java | 4 +- .../plugins/device/adm3a/gui/adm-3a.ttf | Bin 36924 -> 35976 bytes resources/lsi-adm-3a/adm-3a-smaller.sfd | 8964 +++++++++++++++++ resources/lsi-adm-3a/adm-3a.sfd | 50 +- resources/lsi-adm-3a/adm-3a.ttf | Bin 36924 -> 35976 bytes 7 files changed, 8992 insertions(+), 37 deletions(-) create mode 100644 resources/lsi-adm-3a/adm-3a-smaller.sfd diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java index be12cfb46..81efd5ce2 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayCanvas.java @@ -146,8 +146,7 @@ private void paintCursor(Graphics graphics, int lineHeight) { Rectangle2D fontRectangle = getFont().getMaxCharBounds(graphics.getFontMetrics().getFontRenderContext()); - int x = displayFont.xCursorOffset - + (int) (cursorPoint.x * (fontRectangle.getWidth() + displayFont.xCursorMultiplierOffset)); + int x = displayFont.xCursorOffset + (int) (cursorPoint.x * fontRectangle.getWidth()); int y = displayFont.yCursorOffset + (cursorPoint.y * lineHeight); graphics.fillRect(x, y, (int) fontRectangle.getWidth(), (int) fontRectangle.getHeight() + displayFont.yCursorExtend); diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java index aebd628b8..c256da720 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/DisplayFont.java @@ -26,27 +26,25 @@ public class DisplayFont { public static final DisplayFont FONT_ORIGINAL = new DisplayFont( "/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf", - 2, 0.3, 3, 5, 14, 5 + 2, 2, 5, 14, 5 ); public static final DisplayFont FONT_MODERN = new DisplayFont( "/net/emustudio/plugins/device/adm3a/gui/terminal.ttf", - 2, 0, 3, 0, 15, 0 + 2, 3, 0, 15, 0 ); public final String path; public final int xCursorOffset; - public final double xCursorMultiplierOffset; public final int yCursorOffset; public final int yCursorExtend; public final int yLineHeightMultiplierOffset; public final int fontSize; - public DisplayFont(String path, int xCursorOffset, double xCursorMultiplierOffset, int yCursorOffset, + public DisplayFont(String path, int xCursorOffset, int yCursorOffset, int yCursorExtend, int fontSize, int yLineHeightMultiplierOffset) { this.path = Objects.requireNonNull(path); this.xCursorOffset = xCursorOffset; - this.xCursorMultiplierOffset = xCursorMultiplierOffset; this.yCursorOffset = yCursorOffset; this.yCursorExtend = yCursorExtend; this.fontSize = fontSize; diff --git a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java index 2e8047259..080881188 100644 --- a/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java +++ b/plugins/device/adm3A-terminal/src/main/java/net/emustudio/plugins/device/adm3a/gui/TerminalWindow.java @@ -19,7 +19,6 @@ package net.emustudio.plugins.device.adm3a.gui; import net.emustudio.plugins.device.adm3a.api.Display; -import net.emustudio.plugins.device.adm3a.interaction.DisplayImpl; import javax.swing.*; import java.awt.*; @@ -76,7 +75,8 @@ private void initComponents() { setTitle("LSI ADM-3A"); setResizable(false); - canvas.setBounds(100, 170, 830, 530); + // 14pt original font: 9px 1 glyph + canvas.setBounds(150, 170, 725, 530); lblBack.setLocation(0, 0); lblBack.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 16)); diff --git a/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf b/plugins/device/adm3A-terminal/src/main/resources/net/emustudio/plugins/device/adm3a/gui/adm-3a.ttf index 4da285c7f922db3771f1be055807fe96c0400dcf..8579e7f824fb4f5a4f8d2db4d73aa6976f236425 100644 GIT binary patch delta 17334 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 Ap#T5? diff --git a/resources/lsi-adm-3a/adm-3a-smaller.sfd b/resources/lsi-adm-3a/adm-3a-smaller.sfd new file mode 100644 index 000000000..bac902816 --- /dev/null +++ b/resources/lsi-adm-3a/adm-3a-smaller.sfd @@ -0,0 +1,8964 @@ +SplineFontDB: 3.2 +FontName: ADM-3A +FullName: ADM-3A Regular +FamilyName: ADM-3A +Weight: Regular +Copyright: Copyright (c) 2022, Peter Jakubco +UComments: "2022-9-17: Created with FontForge (http://fontforge.org)" +Version: 1.0 +ItalicAngle: 0 +UnderlinePosition: 0 +UnderlineWidth: 1792 +Ascent: 1792 +Descent: 0 +InvalidEm: 0 +LayerCount: 2 +Layer: 0 1 "Back" 1 +Layer: 1 1 "Fore" 0 +XUID: [1021 261 208283644 15436461] +StyleMap: 0x0040 +FSType: 0 +OS2Version: 0 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 0 +CreationTime: 1663397476 +ModificationTime: 1679221643 +PfmFamily: 49 +TTFWeight: 400 +TTFWidth: 5 +LineGap: 0 +VLineGap: 0 +OS2TypoAscent: 1792 +OS2TypoAOffset: 0 +OS2TypoDescent: 0 +OS2TypoDOffset: 0 +OS2TypoLinegap: 0 +OS2WinAscent: 1792 +OS2WinAOffset: 0 +OS2WinDescent: 0 +OS2WinDOffset: 0 +HheadAscent: 1792 +HheadAOffset: 0 +HheadDescent: 0 +HheadDOffset: 0 +OS2Vendor: 'PfEd' +MarkAttachClasses: 1 +DEI: 91125 +LangName: 1033 "" "" "" "" "" "" "" "" "" "" "" "" "" "This Font Software is licensed under the SIL Open Font License, Version 1.1.+AAoA-This license is copied below, and is also available with a FAQ at:+AAoA-http://scripts.sil.org/OFL+AAoACgAK------------------------------------------------------------+AAoA-SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007+AAoA------------------------------------------------------------+AAoACgAA-PREAMBLE+AAoA-The goals of the Open Font License (OFL) are to stimulate worldwide+AAoA-development of collaborative font projects, to support the font creation+AAoA-efforts of academic and linguistic communities, and to provide a free and+AAoA-open framework in which fonts may be shared and improved in partnership+AAoA-with others.+AAoACgAA-The OFL allows the licensed fonts to be used, studied, modified and+AAoA-redistributed freely as long as they are not sold by themselves. The+AAoA-fonts, including any derivative works, can be bundled, embedded, +AAoA-redistributed and/or sold with any software provided that any reserved+AAoA-names are not used by derivative works. The fonts and derivatives,+AAoA-however, cannot be released under any other type of license. The+AAoA-requirement for fonts to remain under this license does not apply+AAoA-to any document created using the fonts or their derivatives.+AAoACgAA-DEFINITIONS+AAoAIgAA-Font Software+ACIA refers to the set of files released by the Copyright+AAoA-Holder(s) under this license and clearly marked as such. This may+AAoA-include source files, build scripts and documentation.+AAoACgAi-Reserved Font Name+ACIA refers to any names specified as such after the+AAoA-copyright statement(s).+AAoACgAi-Original Version+ACIA refers to the collection of Font Software components as+AAoA-distributed by the Copyright Holder(s).+AAoACgAi-Modified Version+ACIA refers to any derivative made by adding to, deleting,+AAoA-or substituting -- in part or in whole -- any of the components of the+AAoA-Original Version, by changing formats or by porting the Font Software to a+AAoA-new environment.+AAoACgAi-Author+ACIA refers to any designer, engineer, programmer, technical+AAoA-writer or other person who contributed to the Font Software.+AAoACgAA-PERMISSION & CONDITIONS+AAoA-Permission is hereby granted, free of charge, to any person obtaining+AAoA-a copy of the Font Software, to use, study, copy, merge, embed, modify,+AAoA-redistribute, and sell modified and unmodified copies of the Font+AAoA-Software, subject to the following conditions:+AAoACgAA-1) Neither the Font Software nor any of its individual components,+AAoA-in Original or Modified Versions, may be sold by itself.+AAoACgAA-2) Original or Modified Versions of the Font Software may be bundled,+AAoA-redistributed and/or sold with any software, provided that each copy+AAoA-contains the above copyright notice and this license. These can be+AAoA-included either as stand-alone text files, human-readable headers or+AAoA-in the appropriate machine-readable metadata fields within text or+AAoA-binary files as long as those fields can be easily viewed by the user.+AAoACgAA-3) No Modified Version of the Font Software may use the Reserved Font+AAoA-Name(s) unless explicit written permission is granted by the corresponding+AAoA-Copyright Holder. This restriction only applies to the primary font name as+AAoA-presented to the users.+AAoACgAA-4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font+AAoA-Software shall not be used to promote, endorse or advertise any+AAoA-Modified Version, except to acknowledge the contribution(s) of the+AAoA-Copyright Holder(s) and the Author(s) or with their explicit written+AAoA-permission.+AAoACgAA-5) The Font Software, modified or unmodified, in part or in whole,+AAoA-must be distributed entirely under this license, and must not be+AAoA-distributed under any other license. The requirement for fonts to+AAoA-remain under this license does not apply to any document created+AAoA-using the Font Software.+AAoACgAA-TERMINATION+AAoA-This license becomes null and void if any of the above conditions are+AAoA-not met.+AAoACgAA-DISCLAIMER+AAoA-THE FONT SOFTWARE IS PROVIDED +ACIA-AS IS+ACIA, WITHOUT WARRANTY OF ANY KIND,+AAoA-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF+AAoA-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT+AAoA-OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE+AAoA-COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+AAoA-INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL+AAoA-DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING+AAoA-FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM+AAoA-OTHER DEALINGS IN THE FONT SOFTWARE." "http://scripts.sil.org/OFL" +GaspTable: 2 8 2 65535 3 0 +Encoding: Custom +UnicodeInterp: none +NameList: AGL For New Fonts +DisplaySize: -48 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 0 51 19 +BeginPrivate: 0 +EndPrivate +Grid +960 2688 m 0 + 960 -896 l 1024 +-1344 2304 m 0 + 2688 2304 l 1024 +-1344 2048 m 0 + 2688 2048 l 1024 +863.912109375 3072 m 0 + 863.912109375 -1024 l 1024 +95.9580078125 3072 m 0 + 95.9580078125 -1024 l 1024 +-1536 1408 m 0 + 3072 1408 l 1024 +287.817382812 2688 m 0 + 287.817382812 -896 l 1024 +-1344 896.1171875 m 0 + 2688 896.1171875 l 1024 +-1344 640 m 0 + 2688 640 l 1024 +148.397460938 2688 m 0 + 148.397460938 -896 l 1024 +135.647460938 2688 m 0 + 135.647460938 -896 l 1024 +43.4912109375 2688 m 0 + 43.4912109375 -896 l 1024 +56.2412109375 2688 m 0 + 56.2412109375 -896 l 1024 +-1344 384 m 0 + 2688 384 l 1024 +-1344 128 m 0 + 2688 128 l 1024 +-1344 1337 m 0 + 2688 1337 l 1024 +-1344 1355 m 0 + 2688 1355 l 1024 +-1344 711 m 0 + 2688 711 l 1024 +-1344 693 m 0 + 2688 693 l 1024 +-1344 455 m 0 + 2688 455 l 1024 +-1344 437 m 0 + 2688 437 l 1024 +341.25 2688 m 0 + 341.25 -896 l 1024 +327.75 2688 m 0 + 327.75 -896 l 1024 +533.215820312 2688 m 0 + 533.215820312 -896 l 1024 +519.715820312 2688 m 0 + 519.715820312 -896 l 1024 +-1344 825 m 0 + 2688 825 l 1024 +-1344 843 m 0 + 2688 843 l 1024 +-1344 1479 m 0 + 2688 1479 l 1024 +-1344 1461 m 0 + 2688 1461 l 1024 +-1344 1223 m 0 + 2688 1223 l 1024 +-1344 1205 m 0 + 2688 1205 l 1024 +810.733398438 2688 m 0 + 810.733398438 -896 l 1024 +824.233398438 2688 m 0 + 824.233398438 -896 l 1024 +-1344 57 m 0 + 2688 57 l 1024 +-1344 199 m 0 + 2688 199 l 1024 +-1344 181 m 0 + 2688 181 l 1024 +-1344 75 m 0 + 2688 75 l 1024 +234.658203125 2688 m 0 + 234.658203125 -896 l 1024 +248.158203125 2688 m 0 + 248.158203125 -896 l 1024 +426.658203125 2688 m 0 + 426.658203125 -896 l 1024 +440.158203125 2688 m 0 + 440.158203125 -896 l 1024 +-1344 1717 m 0 + 2688 1717 l 1024 +-1344 1735 m 0 + 2688 1735 l 1024 +-1344 1593 m 0 + 2688 1593 l 1024 +-1344 1611 m 0 + 2688 1611 l 1024 +-1344 1081 m 0 + 2688 1081 l 1024 +-1344 1099 m 0 + 2688 1099 l 1024 +-1344 569 m 0 + 2688 569 l 1024 +-1344 587 m 0 + 2688 587 l 1024 +-1344 313 m 0 + 2688 313 l 1024 +-1344 331 m 0 + 2688 331 l 1024 +-1344 967 m 0 + 2688 967 l 1024 +-1344 949 m 0 + 2688 949 l 1024 +725.162109375 2688 m 0 + 725.162109375 -896 l 1024 +711.662109375 2688 m 0 + 711.662109375 -896 l 1024 +618.693359375 2688 m 0 + 618.693359375 -896 l 1024 +632.193359375 2688 m 0 + 632.193359375 -896 l 1024 +917.229492188 2688 m 0 + 917.229492188 -896 l 1024 +903.729492188 2688 m 0 + 903.729492188 -896 l 1024 +-1344 256 m 0 + 2688 256 l 1024 +-1344 512.000976562 m 0 + 2688 512.000976562 l 1024 +-1344 768 m 0 + 2688 768 l 1024 +-1344 1024 m 0 + 2688 1024 l 1024 +-1344 1279.99902344 m 0 + 2688 1279.99902344 l 1024 +-1344 1536.00097656 m 0 + 2688 1536.00097656 l 1024 +192 2688 m 0 + 192 -896 l 1024 +383.999023438 2688 m 0 + 383.999023438 -896 l 1024 +576 2688 m 0 + 576 -896 l 1024 +768 2688 m 0 + 768 -896 l 1024 +EndSplineSet +TeXData: 1 0 0 -256901 920125 613417 -256901 -50332 613417 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144 +BeginChars: 257 256 + +StartChar: SOH +Encoding: 1 1 0 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$:C.@.+:*&9s1_f6R)B%2 +,.L"Z8]6-*%R@6<,p:#HQA`0k:2&K7PTW<+"WDVU3l`mup*Y)J(Pf@7#9eh@AH2]1!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +384 1280 m 25,0,-1 + 768 1280 l 25,1,2 + 768 1408 768 1408 768 1461 c 0,3,4 + 768 1536 768 1536 712 1536 c 24,5,-1 + 440 1536 l 0,6,7 + 384 1536 384 1536 384 1461 c 24,8,9 + 384 1461 384 1461 384 1280 c 25,0,-1 +712 1792 m 0,10,11 + 960 1792 960 1792 960 1461 c 24,12,13 + 960 1461 960 1461 960 512 c 25,14,-1 + 768 512 l 24,15,-1 + 768 1024 l 25,16,-1 + 384 1024 l 25,17,-1 + 384 512 l 25,18,-1 + 192 512 l 25,19,20 + 192 1152 192 1152 192 1461 c 0,21,22 + 192 1792 192 1792 440 1792 c 24,23,24 + 440 1792 440 1792 712 1792 c 0,10,11 +0 256 m 25,25,-1 + 960 256 l 25,26,-1 + 960 0 l 25,27,-1 + 0 0 l 25,28,-1 + 0 256 l 25,25,-1 +EndSplineSet +EndChar + +StartChar: STX +Encoding: 2 2 1 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CJNffG9V\638 +I#?hhE%++NJ5$W1!d$Ar-pX+%R0ZlE9bO6%!;2fj%l9/)_#OH8!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +136 1792 m 9,0,-1 + 768 949 l 25,1,-1 + 768 843 l 25,2,-1 + 136 0 l 24,3,-1 + 0 0 l 25,4,-1 + 0 1792 l 25,5,6 + 0 1792 0 1792 136 1792 c 9,0,-1 +EndSplineSet +EndChar + +StartChar: ETX +Encoding: 3 3 2 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 108 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8D_*$Z[Q1)J/h +/&3J<;?9gK9+n<+T-RM>!B3?H^o%J+86h#P4d$6bQD(fZz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +768 1792 m 25,0,-1 + 768 0 l 24,1,-1 + 632 0 l 24,2,-1 + 0 843 l 25,3,-1 + 0 949 l 25,4,-1 + 632 1792 l 24,5,6 + 632 1792 632 1792 768 1792 c 25,0,-1 +EndSplineSet +EndChar + +StartChar: EOT +Encoding: 4 4 3 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG9Xor#n +'2/TU!Q)p86#poJ0SS^I5m:XTJ98Vd7X"r:!P0DZ2'D'lGS=3^!8HZQ#82Hl\GuU0!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +384 1536 m 24,0,-1 + 384 768 l 24,1,-1 + 712 768 l 0,2,3 + 768 768 768 768 768 843 c 24,4,5 + 768 1190 768 1190 768 1461 c 0,6,7 + 768 1536 768 1536 712 1536 c 24,8,9 + 712 1536 712 1536 384 1536 c 24,0,-1 +712 1792 m 0,10,11 + 960 1792 960 1792 960 1461 c 24,12,13 + 960 986 960 986 960 843 c 0,14,15 + 960 512 960 512 712 512 c 24,16,-1 + 192 512 l 25,17,-1 + 192 1792 l 25,18,19 + 192 1792 192 1792 712 1792 c 0,10,11 +0 256 m 25,20,-1 + 960 256 l 25,21,-1 + 960 0 l 25,22,-1 + 0 0 l 25,23,-1 + 0 256 l 25,20,-1 +EndSplineSet +EndChar + +StartChar: ENQ +Encoding: 5 5 4 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG971$7@ +YQBn;Z66Gf-5Ztu$G&eO3J&Tn'd2g3[LTA==TE%[N!;9a_je^c!"R$c%];No&HDe2!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +0 256 m 29,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 29,0,-1 +192 512 m 25,4,-1 + 192 1792 l 25,5,-1 + 960 1792 l 25,6,-1 + 960 1536 l 25,7,-1 + 384 1536 l 25,8,-1 + 384 1280 l 25,9,-1 + 768 1280 l 25,10,-1 + 768 1024 l 25,11,-1 + 384 1024 l 25,12,-1 + 384 768 l 25,13,-1 + 960 768 l 25,14,-1 + 960 512 l 25,15,-1 + 192 512 l 25,4,-1 +EndSplineSet +EndChar + +StartChar: ACK +Encoding: 6 6 5 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8+BNffG971$7@ +YQBn;Z66Gf-5Ztu$G&eO3TTFF!JmI,gB^Dg^9E8F9Neb@sAYi0`YMc'G#dIl9YIN!!#SZ:.26O +@"J@Y +EndImage2 +Fore +SplineSet +576 1461 m 0,0,1 + 576 1536 576 1536 520 1536 c 24,2,3 + 480 1536 480 1536 440 1536 c 0,4,5 + 384 1536 384 1536 384 1461 c 24,6,7 + 384 1114 384 1114 384 843 c 0,8,9 + 384 768 384 768 440 768 c 24,10,11 + 440 768 440 768 520 768 c 0,12,13 + 576 768 576 768 576 843 c 24,14,15 + 576 843 576 843 576 1461 c 0,0,1 +520 1792 m 0,16,17 + 768 1792 768 1792 768 1461 c 24,18,-1 + 768 1099 l 0,19,20 + 768 1024 768 1024 824 1024 c 24,21,-1 + 917 1024 l 0,22,23 + 960 960 960 960 960 896 c 128,-1,24 + 960 832 960 832 917 768 c 8,25,-1 + 632 768 l 0,26,27 + 576 768 576 768 576 693 c 24,28,-1 + 576 569 l 0,29,30 + 528 512 528 512 479 512 c 0,31,32 + 447 512 447 512 384 569 c 1,33,-1 + 384 693 l 0,34,35 + 384 768 384 768 328 768 c 24,36,-1 + 43 768 l 0,37,38 + 0 832 0 832 0 896 c 128,-1,39 + 0 960 0 960 43 1024 c 8,40,-1 + 136 1024 l 0,41,42 + 192 1024 192 1024 192 1099 c 24,43,-1 + 192 1461 l 0,44,45 + 192 1792 192 1792 440 1792 c 24,46,47 + 440 1792 440 1792 520 1792 c 0,16,17 +0 256 m 25,48,-1 + 960 256 l 25,49,-1 + 960 0 l 25,50,-1 + 0 0 l 25,51,-1 + 0 256 l 25,48,-1 +EndSplineSet +EndChar + +StartChar: BS +Encoding: 8 8 7 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +)i_Z=3>,I+h9B=X@"L'NaU&Ap2dhgP.0KVu`tSdDpboV^!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +576 1792 m 25,0,-1 + 576 693 l 24,1,-1 + 824 1024 l 24,2,-1 + 960 1024 l 25,3,-1 + 960 843 l 25,4,-1 + 520 256 l 25,5,-1 + 440 256 l 24,6,-1 + 0 843 l 25,7,-1 + 0 1024 l 25,8,-1 + 136 1024 l 24,9,-1 + 384 693 l 24,10,-1 + 384 1792 l 25,11,-1 + 576 1792 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: VT +Encoding: 11 11 10 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +BF +EndImage2 +Fore +SplineSet +520 1536 m 25,0,-1 + 960 949 l 25,1,-1 + 960 768 l 24,2,-1 + 824 768 l 24,3,-1 + 576 1099 l 25,4,-1 + 576 0 l 25,5,-1 + 384 0 l 25,6,-1 + 384 1099 l 25,7,-1 + 136 768 l 24,8,-1 + 0 768 l 24,9,-1 + 0 949 l 25,10,-1 + 440 1536 l 24,11,12 + 440 1536 440 1536 520 1536 c 25,0,-1 +EndSplineSet +EndChar + +StartChar: FF +Encoding: 12 12 11 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +dNM)#3z8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +632 1536 m 9,0,-1 + 192 949 l 25,1,-1 + 192 843 l 25,2,-1 + 632 256 l 24,3,-1 + 768 256 l 25,4,-1 + 768 437 l 24,5,-1 + 440 843 l 25,6,-1 + 440 949 l 25,7,-1 + 768 1355 l 25,8,-1 + 768 1536 l 17,9,10 + 768 1536 768 1536 632 1536 c 9,0,-1 +0 1792 m 25,11,-1 + 960 1792 l 25,12,-1 + 960 0 l 25,13,-1 + 0 0 l 25,14,-1 + 0 1792 l 25,11,-1 +EndSplineSet +EndChar + +StartChar: SO +Encoding: 14 14 13 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 124 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$NmS16+:&(=s8UEqUl0oQ +LKs2CC@3!7"eHuMkm?#7THE5sf`KBbhuqL+047'Q#W'0mZn#,22gY)t;6V5H/(OK:z8OZBB +Y!QNJ +EndImage2 +Fore +SplineSet +479 715 m 1,0,1 + 479 715 479 715 136 256 c 1,2,3 + 136 256 136 256 0 256 c 25,4,5 + 0 256 0 256 0 437 c 9,6,7 + 0 437 0 437 440 1024 c 24,8,9 + 440 1024 440 1024 520 1024 c 25,10,11 + 520 1024 520 1024 960 437 c 1,12,13 + 960 437 960 437 960 256 c 25,14,15 + 960 256 960 256 824 256 c 1,16,-1 + 479 715 l 1,0,1 +479 1483 m 1,17,18 + 479 1483 479 1483 136 1024 c 1,19,20 + 136 1024 136 1024 0 1024 c 25,21,22 + 0 1024 0 1024 0 1205 c 9,23,24 + 0 1205 0 1205 440 1792 c 24,25,26 + 440 1792 440 1792 520 1792 c 25,27,28 + 520 1792 520 1792 960 1205 c 1,29,30 + 960 1205 960 1205 960 1024 c 25,31,32 + 960 1024 960 1024 824 1024 c 1,33,-1 + 479 1483 l 1,17,18 +EndSplineSet +EndChar + +StartChar: SI +Encoding: 15 15 14 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8C%,9r(&3hH^h +!)*qlUDq8WdLK3//d[\n>60q@R0JfW!@h1P0aQbK(`SkI!(.8@$q!`Nd/X.H!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +479 1333 m 129,-1,1 + 479 1333 479 1333 824 1792 c 1,2,-1 + 960 1792 l 25,3,4 + 960 1611 960 1611 960 1611 c 1,5,6 + 520 1024 520 1024 520 1024 c 25,7,8 + 440 1024 440 1024 440 1024 c 24,9,10 + 0 1611 0 1611 0 1611 c 17,11,12 + 0 1792 0 1792 0 1792 c 25,13,14 + 136 1792 136 1792 136 1792 c 1,15,0 + 479 1333 479 1333 479 1333 c 129,-1,1 +479 565 m 129,-1,17 + 479 565 479 565 824 1024 c 1,18,-1 + 960 1024 l 25,19,20 + 960 843 960 843 960 843 c 1,21,22 + 520 256 520 256 520 256 c 25,23,24 + 440 256 440 256 440 256 c 24,25,26 + 0 843 0 843 0 843 c 17,27,28 + 0 1024 0 1024 0 1024 c 25,29,30 + 136 1024 136 1024 136 1024 c 1,31,16 + 479 565 479 565 479 565 c 129,-1,17 +EndSplineSet +EndChar + +StartChar: DLE +Encoding: 16 16 15 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 125 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$NmS16+:&'Ro`)[29fN`Y +p*+D;;#>!T[%'][V"7?e"L(4V;hm6G&)\0@P5D5ed9GVPDAkq5,R^q"*(*=ArjbLg]`8$4!(fUS +7'8jaJcGcN +EndImage2 +Fore +SplineSet +328 768 m 1,0,1 + 328 768 328 768 712 768 c 0,2,3 + 768 768 768 768 768 843 c 0,4,5 + 768 843 768 843 768 1355 c 0,6,7 + 768 1355 768 1355 328 768 c 1,0,1 +192 949 m 129,-1,9 + 192 949 192 949 632 1536 c 1,10,11 + 632 1536 632 1536 248 1536 c 0,12,13 + 192 1536 192 1536 192 1461 c 0,14,8 + 192 949 192 949 192 949 c 129,-1,9 +0 256 m 25,15,-1 + 960 255 l 25,16,-1 + 960 0 l 25,17,-1 + 0 0 l 25,18,-1 + 0 256 l 25,15,-1 +712 1792 m 0,19,20 + 960 1792 960 1792 960 1461 c 24,21,22 + 960 1461 960 1461 960 843 c 0,23,24 + 960 512 960 512 712 512 c 24,25,-1 + 248 512 l 0,26,27 + 0 512 0 512 0 843 c 24,28,29 + 0 843 0 843 0 1461 c 0,30,31 + 0 1792 0 1792 248 1792 c 24,32,33 + 248 1792 248 1792 712 1792 c 0,19,20 +EndSplineSet +EndChar + +StartChar: DC1 +Encoding: 17 17 16 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HN: +$?/Rg<.YkCZNY4MMRc7t'J$Cj`<&qrcO,c_0t`@E!a +.f^Fg_B=Qr!3?/G#a3,<)r(d:Os#`4-=F03"f)KlDNGjZ<>aR\ec5]\B,;(H"(9UY!!!!j78?7R +6=>BF +EndImage2 +Fore +SplineSet +0 256 m 1,0,1 + 0 256 0 256 960 256 c 1,2,3 + 960 256 960 256 960 0 c 1,4,5 + 960 0 960 0 0 0 c 1,6,7 + 0 0 0 0 0 256 c 1,0,1 +533 1792 m 0,8,9 + 768 1792 768 1792 768 1461 c 0,10,11 + 768 1461 768 1461 768 1355 c 1,12,-1 + 384 843 l 0,13,14 + 384 768 384 768 440 768 c 0,15,-1 + 712 768 l 0,16,17 + 768 768 768 768 768 640 c 0,18,19 + 768 513 768 513 712 512 c 0,20,21 + 712 512 712 512 192 512 c 0,22,23 + 192 512 192 512 194 948 c 0,24,-1 + 577 1460 l 0,25,26 + 576 1536 576 1536 533 1536 c 0,27,-1 + 192 1536 l 0,28,29 + 192 1536 192 1536 192 1792 c 0,30,31 + 192 1792 192 1792 533 1792 c 0,8,9 +EndSplineSet +EndChar + +StartChar: DC3 +Encoding: 19 19 18 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9N3T>a +.f^Fg_B=QrJ-@3K9`h1'`<;PN16#`E2YVe<@$?,/!cf$12j#rt!,QWn$?T36%fcS0!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +0 256 m 1,0,1 + 0 256 0 256 960 256 c 0,2,3 + 960 256 960 256 960 0 c 0,4,5 + 960 0 960 0 0 0 c 0,6,7 + 0 0 0 0 0 256 c 1,0,1 +533 1792 m 256,8,9 + 768 1792 768 1792 768 1465 c 0,10,11 + 768 1465 768 1465 768 843 c 0,12,13 + 768 512 768 512 520 512 c 1,14,15 + 520 512 520 512 192 512 c 0,16,17 + 192 512 192 512 192 768 c 0,18,-1 + 520 768 l 0,19,20 + 576 768 576 768 576 843 c 1,21,-1 + 576 949 l 0,22,23 + 576 1024 576 1024 520 1024 c 24,24,-1 + 192 1024 l 0,25,26 + 192 1024 192 1024 192 1280 c 0,27,-1 + 520 1280 l 0,28,29 + 576 1280 576 1280 576 1355 c 24,30,31 + 576 1410 576 1410 576 1465 c 0,32,33 + 576 1536 576 1536 520 1536 c 0,34,-1 + 192 1536 l 0,35,36 + 192 1536 192 1536 192 1792 c 257,37,38 + 192 1792 192 1792 533 1792 c 256,8,9 +EndSplineSet +EndChar + +StartChar: DC4 +Encoding: 20 20 19 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 122 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8D_*$Z[Q1)J/h +/&3J<;?9euP/LoFL'd&jJJE]W_b>U.0ZUt'!"#;kK#Bq"`pb=\63,n&(C(FW?:"Vl!!#SZ:.26O +@"J@Y +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +576 1355 m 0,4,-1 + 328 1024 l 0,5,-1 + 576 1024 l 0,6,7 + 576 1024 576 1024 576 1355 c 0,4,-1 +768 1792 m 0,8,-1 + 768 1024 l 0,9,-1 + 917 1024 l 1,10,11 + 960 1024 960 1024 960 896 c 128,-1,12 + 960 768 960 768 917 768 c 1,13,-1 + 768 768 l 0,14,-1 + 768 512 l 0,15,16 + 768 512 768 512 576 512 c 0,17,-1 + 576 768 l 0,18,-1 + 192 768 l 0,19,20 + 192 768 192 768 192 1205 c 0,21,22 + 192 1205 192 1205 632 1792 c 0,23,24 + 632 1792 632 1792 768 1792 c 0,8,-1 +EndSplineSet +EndChar + +StartChar: NAK +Encoding: 21 21 20 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8CJNffG9Xot.% +&d0_8b@4mVY(-[d.`e/7]@#FC,^>Ae.*+!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +960 1792 m 25,4,5 + 960 1792 960 1792 960 843 c 0,6,7 + 960 512 960 512 712 512 c 16,8,9 + 712 512 712 512 440 512 c 0,10,11 + 192 512 192 512 192 843 c 24,12,13 + 192 843 192 843 192 1792 c 25,14,-1 + 384 1792 l 25,15,-1 + 384 843 l 0,16,17 + 384 768 384 768 440 768 c 24,18,-1 + 712 768 l 2,19,20 + 768 768 768 768 768 843 c 10,21,-1 + 768 1792 l 24,22,23 + 768 1792 768 1792 960 1792 c 25,4,5 +EndSplineSet +EndChar + +StartChar: SYN +Encoding: 22 22 21 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8C%,9r(&3hH^I +((5m(A-5LALdnk9YR)FN@A]^`#0F\U^a9@c!:g2G2j"gW!5.A/#EmW9`rH)>!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +480 852 m 1,4,5 + 480 852 480 852 768 1461 c 1,6,7 + 768 1461 768 1461 768 1792 c 0,8,9 + 768 1792 768 1792 960 1792 c 1,10,-1 + 960 1355 l 1,11,-1 + 520 512 l 1,12,13 + 520 512 520 512 440 512 c 0,14,15 + 440 512 440 512 0 1355 c 1,16,-1 + 0 1792 l 1,17,18 + 0 1792 0 1792 192 1792 c 0,19,20 + 192 1628 192 1628 192 1465 c 1,21,22 + 192 1465 192 1465 480 852 c 1,4,5 +EndSplineSet +EndChar + +StartChar: ETB +Encoding: 23 23 22 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8C%,9r(&3hH^I +((1AM!*psG/R/BF +EndImage2 +Fore +SplineSet +0 256 m 1,0,-1 + 960 256 l 1,1,-1 + 960 0 l 1,2,-1 + 0 0 l 1,3,4 + 0 0 0 0 0 256 c 1,0,-1 +479 625 m 1,5,6 + 479 512 479 512 328 512 c 0,7,8 + 328 512 328 512 248 512 c 0,9,10 + 0 512 0 512 0 843 c 0,11,12 + 0 843 0 843 0 1792 c 1,13,14 + 0 1792 0 1792 192 1792 c 1,15,-1 + 192 843 l 1,16,17 + 192 768 192 768 248 768 c 0,18,19 + 328 768 328 768 328 768 c 0,20,21 + 384 768 384 768 384 843 c 0,22,23 + 384 1223 384 1223 384 1223 c 0,24,25 + 384 1280 384 1280 479 1280 c 0,26,27 + 576 1280 576 1280 576 1223 c 0,28,29 + 576 843 576 843 576 843 c 1,30,31 + 576 768 576 768 632 768 c 0,32,33 + 712 768 712 768 712 768 c 0,34,35 + 768 768 768 768 768 843 c 0,36,37 + 768 1792 768 1792 768 1792 c 129,-1,38 + 768 1792 768 1792 960 1792 c 1,39,40 + 960 1792 960 1792 960 843 c 0,41,42 + 960 512 960 512 712 512 c 0,43,44 + 712 512 712 512 632 512 c 0,45,46 + 479 512 479 512 479 625 c 1,5,6 +EndSplineSet +EndChar + +StartChar: CAN +Encoding: 24 24 23 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 126 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W77fm5<#?L$:.Z&u+:&>Ss5t#,..n,f +7@"NIYs&En9qFILi$7D9%*!.Q+uL7.F;"h1%qP2.C%F2=e^lS,:q5*1GQ9@X+p4-_J"coC!!#SZ +:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 256 m 1,0,-1 + 960 256 l 1,1,-1 + 960 0 l 1,2,-1 + 0 0 l 1,3,-1 + 0 256 l 1,0,-1 +479 1330 m 1,4,5 + 479 1330 479 1330 825 1792 c 0,6,7 + 825 1792 825 1792 960 1792 c 1,8,9 + 960 1792 960 1792 960 1611 c 1,10,11 + 960 1611 960 1611 626 1147 c 1,12,13 + 626 1147 626 1147 960 693 c 0,14,-1 + 960 512 l 1,15,-1 + 824 512 l 0,16,-1 + 479 951 l 1,17,18 + 479 951 479 951 136 512 c 0,19,20 + 136 512 136 512 0 512 c 1,21,22 + 0 512 0 512 0 693 c 0,23,24 + 0 693 0 693 344 1152 c 1,25,26 + 344 1152 344 1152 0 1611 c 1,27,-1 + 0 1792 l 1,28,29 + 0 1792 0 1792 136 1792 c 0,30,31 + 135 1792 135 1792 479 1330 c 1,4,5 +EndSplineSet +EndChar + +StartChar: EM +Encoding: 25 25 24 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8C%,9r(&3hH^h +!)*qlUDq8WdLK3//d[[C.f_;C!TFi%1EL'Va9rjA6rj]r%SITCDP?uKz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +480 1333 m 1,4,5 + 824 1792 824 1792 824 1792 c 0,6,7 + 960 1792 960 1792 960 1792 c 129,-1,8 + 960 1792 960 1792 960 1611 c 1,9,-1 + 576 1099 l 1,10,-1 + 576 512 l 1,11,-1 + 384 512 l 1,12,-1 + 384 1099 l 1,13,-1 + 0 1611 l 1,14,-1 + 0 1792 l 1,15,16 + 136 1792 136 1792 136 1792 c 0,17,18 + 480 1333 480 1333 480 1333 c 1,4,5 +EndSplineSet +EndChar + +StartChar: SUB +Encoding: 26 26 25 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8sb%RU9&*Yr8r +,9nE81*:$\'?kQ7P<7,XDc.Es'WIA=B.t!(mqHqrZ$u-ia5I!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +0 1792 m 24,4,-1 + 960 1792 l 25,5,-1 + 960 1611 l 25,6,-1 + 328 768 l 24,7,-1 + 960 768 l 24,8,-1 + 960 512 l 25,9,-1 + 0 512 l 25,10,-1 + 0 693 l 24,11,-1 + 632 1536 l 24,12,-1 + 0 1536 l 24,13,14 + 0 1536 0 1536 0 1792 c 24,4,-1 +EndSplineSet +EndChar + +StartChar: ESC +Encoding: 27 27 26 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%RU9&*YsiL +A-#.hO<+N).faS:-"'?4?jpRE?t(5sY(.o6YaGQ9""rCP.fa&r'FgPi7r\M/!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +768 1536 m 24,0,-1 + 192 1536 l 24,1,-1 + 192 256 l 25,2,-1 + 768 256 l 24,3,-1 + 768 512 l 25,4,-1 + 384 512 l 25,5,-1 + 384 768 l 24,6,-1 + 576 768 l 24,7,-1 + 576 1024 l 25,8,-1 + 384 1024 l 25,9,-1 + 384 1280 l 25,10,-1 + 768 1280 l 24,11,12 + 768 1280 768 1280 768 1536 c 24,0,-1 +0 1792 m 25,13,-1 + 960 1792 l 25,14,-1 + 960 0 l 25,15,-1 + 0 0 l 25,16,-1 + 0 1792 l 25,13,-1 +EndSplineSet +EndChar + +StartChar: FS +Encoding: 28 28 27 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8C%,9n7D"pQE9 +!Vd?`J[FH9"BL%K&R5>h748LNMEj!,J@pEk9k9ju!.ec!#8A0)mJm4e!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +136 1792 m 24,4,-1 + 960 693 l 24,5,-1 + 960 512 l 25,6,-1 + 824 512 l 24,7,-1 + 0 1611 l 25,8,-1 + 0 1792 l 25,9,10 + 0 1792 0 1792 136 1792 c 24,4,-1 +EndSplineSet +EndChar + +StartChar: GS +Encoding: 29 29 28 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8+BNffG9Xor#n +'1`BF +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +192 1792 m 25,4,-1 + 768 1792 l 25,5,-1 + 768 512 l 24,6,-1 + 192 512 l 25,7,-1 + 192 768 l 24,8,-1 + 576 768 l 24,9,-1 + 576 1536 l 24,10,-1 + 192 1536 l 24,11,12 + 192 1536 192 1536 192 1792 c 25,4,-1 +EndSplineSet +EndChar + +StartChar: RS +Encoding: 30 30 29 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns2BO@1f( +h*;aC$0W!UENg0#8Oc12@@.&_#$d%QOH%8W#]9^fE+BD#0`]\&)?>?3fNeIW!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 1536 m 24,0,-1 + 768 1536 l 24,1,-1 + 768 1280 l 25,2,-1 + 328 1280 l 24,3,-1 + 960 437 l 24,4,-1 + 960 256 l 25,5,-1 + 824 256 l 24,6,-1 + 192 1099 l 25,7,-1 + 192 512 l 25,8,-1 + 0 512 l 25,9,10 + 0 512 0 512 0 1536 c 24,0,-1 +EndSplineSet +EndChar + +StartChar: US +Encoding: 31 31 30 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8Dg*$Z[QM@bLD +'NlO`XoM`T9HdL=8.q7f5Sdfg&m6psLkF"VYSAi\0RJpr!/i!7$j7etH2mpF!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +960 1792 m 25,0,-1 + 960 512 l 25,1,-1 + 328 512 l 24,2,-1 + 576 181 l 24,3,-1 + 576 0 l 25,4,-1 + 440 0 l 24,5,-1 + 0 587 l 25,6,-1 + 0 693 l 24,7,-1 + 440 1280 l 24,8,-1 + 576 1280 l 25,9,-1 + 576 1099 l 25,10,-1 + 328 768 l 24,11,-1 + 768 768 l 24,12,-1 + 768 1792 l 24,13,14 + 768 1792 768 1792 960 1792 c 25,0,-1 +EndSplineSet +EndChar + +StartChar: exclam +Encoding: 33 33 31 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 96 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ +$;a-Q3:p1#b;4)ri:7$O`M*SJUBW=Iz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 256 m 29,0,-1 + 384 256 l 25,1,-1 + 384 0 l 25,2,-1 + 192 0 l 25,3,-1 + 192 256 l 29,0,-1 +192 1792 m 25,4,-1 + 384 1792 l 25,5,-1 + 384 512 l 25,6,-1 + 192 512 l 25,7,-1 + 192 1792 l 25,4,-1 +EndSplineSet +EndChar + +StartChar: quotedbl +Encoding: 34 34 32 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 103 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8CJNffG9X9;!; +Ws:.?(-lLG<5;%h)pjR5jqG+RTE5*=0F/+t#&COF!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +384 1792 m 24,0,-1 + 576 1792 l 24,1,-1 + 576 1024 l 25,2,-1 + 384 1024 l 25,3,4 + 384 1024 384 1024 384 1792 c 24,0,-1 +0 1792 m 24,5,-1 + 192 1792 l 24,6,-1 + 192 1024 l 25,7,-1 + 0 1024 l 25,8,9 + 0 1024 0 1024 0 1792 c 24,5,-1 +EndSplineSet +EndChar + +StartChar: numbersign +Encoding: 35 35 33 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 107 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CJNffG9X9;!; +Ws:.?(-lMbZsm-gCb$0XK20,m'NW]@K732)-<;#GT!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +576 1024 m 25,0,-1 + 384 1024 l 25,1,-1 + 384 768 l 24,2,-1 + 576 768 l 17,3,4 + 576 768 576 768 576 1024 c 25,0,-1 +768 1792 m 25,5,-1 + 768 1280 l 24,6,-1 + 960 1280 l 25,7,-1 + 960 1024 l 25,8,-1 + 768 1024 l 24,9,-1 + 768 768 l 24,10,-1 + 960 768 l 24,11,-1 + 960 512 l 25,12,-1 + 768 512 l 24,13,-1 + 768 0 l 24,14,-1 + 576 0 l 25,15,-1 + 576 512 l 25,16,-1 + 384 512 l 25,17,-1 + 384 0 l 25,18,-1 + 192 0 l 25,19,-1 + 192 512 l 25,20,-1 + 0 512 l 25,21,-1 + 0 768 l 24,22,-1 + 192 768 l 24,23,-1 + 192 1024 l 25,24,-1 + 0 1024 l 25,25,-1 + 0 1280 l 25,26,-1 + 192 1280 l 25,27,-1 + 192 1792 l 25,28,-1 + 384 1792 l 25,29,-1 + 384 1280 l 25,30,-1 + 576 1280 l 25,31,-1 + 576 1792 l 25,32,-1 + 768 1792 l 25,5,-1 +EndSplineSet +EndChar + +StartChar: dollar +Encoding: 36 36 34 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 127 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W7S-!6<#?L$bs;]P5R^!,B't03:)+gl +TJW.17)c^/\UJ/BF +EndImage2 +Fore +SplineSet +576 768 m 9,0,-1 + 576 512 l 25,1,2 + 576 512 576 512 712 512 c 0,3,4 + 768 512 768 512 768 587 c 24,5,6 + 768 678 768 678 768 693 c 0,7,8 + 768 768 768 768 712 768 c 16,9,10 + 644 768 644 768 576 768 c 9,0,-1 +248 1280 m 0,11,12 + 192 1280 192 1280 192 1205 c 16,13,14 + 192 1114 192 1114 192 1099 c 0,15,16 + 192 1024 192 1024 247 1024 c 0,17,18 + 248 1024 248 1024 248 1024 c 8,19,-1 + 384 1024 l 25,20,-1 + 384 1280 l 25,21,22 + 384 1280 384 1280 248 1280 c 0,11,12 +248 768 m 16,23,24 + 0 768 0 768 0 1099 c 24,25,26 + 0 1099 0 1099 0 1205 c 0,27,28 + 0 1536 0 1536 248 1536 c 24,29,-1 + 384 1536 l 24,30,-1 + 384 1792 l 25,31,-1 + 576 1792 l 25,32,-1 + 576 1536 l 24,33,-1 + 960 1536 l 24,34,35 + 960 1536 960 1536 960 1280 c 25,36,-1 + 576 1280 l 25,37,-1 + 576 1024 l 25,38,-1 + 712 1024 l 0,39,40 + 960 1024 960 1024 960 693 c 24,41,42 + 960 693 960 693 960 587 c 0,43,44 + 960 256 960 256 712 256 c 24,45,-1 + 576 256 l 25,46,-1 + 576 0 l 25,47,-1 + 384 0 l 25,48,-1 + 384 256 l 25,49,-1 + 0 256 l 25,50,-1 + 0 512 l 25,51,-1 + 384 512 l 25,52,53 + 384 512 384 512 384 768 c 24,54,-1 + 248 768 l 16,23,24 +EndSplineSet +EndChar + +StartChar: percent +Encoding: 37 37 35 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$N_p8d+:(< +,fgO%MSLRse..^NK'C;:'FZM=Xb'c.b9XS4\/YkV3U.S!$>mtlz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +808 384 m 1,0,1 + 960 182 960 182 960 182 c 128,-1,2 + 960 182 960 182 960 0 c 25,3,4 + 960 0 960 0 824 0 c 0,5,6 + 824 0 824 0 673 204 c 1,7,8 + 673 204 673 204 520 0 c 1,9,10 + 520 0 520 0 248 0 c 0,11,12 + 0 0 0 0 0 331 c 25,13,14 + 0 331 0 331 0 693 c 0,15,16 + 0 693 0 693 152 896 c 9,17,-1 + 0 1099 l 1,18,-1 + 0 1461 l 17,19,20 + 0 1792 0 1792 248 1792 c 24,21,22 + 248 1792 248 1792 328 1792 c 0,23,24 + 576 1792 576 1792 576 1469 c 0,25,26 + 576 1465 576 1465 576 1461 c 9,27,28 + 576 1461 576 1461 576 1099 c 1,29,-1 + 424 896 l 1,30,31 + 424 896 424 896 672 565 c 1,32,33 + 672 565 672 565 824 768 c 0,34,35 + 824 768 824 768 960 768 c 1,36,37 + 960 768 960 768 960 587 c 1,38,39 + 808 384 808 384 808 384 c 1,0,1 +537 385 m 1,40,41 + 537 385 537 385 290 717 c 1,42,43 + 290 717 290 717 192 587 c 9,44,45 + 192 422 192 422 192 331 c 0,46,47 + 192 256 192 256 248 256 c 24,48,49 + 358 256 358 256 440 256 c 0,50,51 + 440 256 440 256 537 385 c 1,40,41 +288 1077 m 16,52,-1 + 384 1205 l 1,53,54 + 384 1373 384 1373 384 1461 c 0,55,56 + 384 1536 384 1536 328 1536 c 24,57,-1 + 248 1536 l 0,58,59 + 192 1536 192 1536 192 1461 c 24,60,61 + 192 1461 192 1461 192 1205 c 0,62,-1 + 288 1077 l 16,52,-1 +EndSplineSet +EndChar + +StartChar: quotesingle +Encoding: 39 39 37 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 100 -384 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CNNffG9`^HNZ +$;a-Q35d>_jV6]K5dD/Z8^IS?MP^UeJpj^tz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +384 1792 m 29,0,-1 + 576 1792 l 29,1,-1 + 576 1024 l 29,2,-1 + 384 1024 l 29,3,-1 + 384 1792 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: parenleft +Encoding: 40 40 38 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 111 192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8CNNffG9`^HN: +$:'ca$j(.\CCAo)'Q]BrKGB%(`oTII6!tAq.09M++V>%^+Bg&k!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +768 1792 m 25,0,-1 + 768 1611 l 1,1,-1 + 384 1099 l 0,2,3 + 384 1099 384 1099 384 693 c 1,4,-1 + 768 181 l 0,5,6 + 768 181 768 181 768 0 c 25,7,8 + 768 0 768 0 632 0 c 24,9,10 + 632 0 632 0 192 587 c 25,11,12 + 192 1190 192 1190 192 1205 c 28,13,14 + 192 1205 192 1205 632 1792 c 28,15,16 + 700 1792 700 1792 768 1792 c 25,0,-1 +EndSplineSet +EndChar + +StartChar: parenright +Encoding: 41 41 39 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8CNNffG9`^HNZ +$:"f(;Zp/%dY:I.M?4KuTcDJpJD>\C.C]]:,XJj=!8p-S&*9"7QiI*d!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +341 1792 m 25,0,-1 + 768 1205 l 24,1,-1 + 768 587 l 25,2,-1 + 328 0 l 25,3,-1 + 192 0 l 25,4,-1 + 192 182 l 24,5,-1 + 576 693 l 24,6,-1 + 576 1099 l 25,7,-1 + 192 1611 l 25,8,-1 + 192 1792 l 25,9,-1 + 341 1792 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: asterisk +Encoding: 42 42 40 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NS=d?+:(?(s8UE1_?!r( +0@O3sp7:lE5a0,I0O/kjXQZH=DE#=``RHUM5,j"b$(RZ9N"(d-mz8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +616 896 m 1,0,1 + 954 454 954 454 960 437 c 0,2,3 + 960 437 960 437 960 256 c 25,4,5 + 960 256 960 256 824 256 c 24,6,7 + 824 256 824 256 576 587 c 25,8,-1 + 576 0 l 25,9,-1 + 384 0 l 25,10,-1 + 384 587 l 25,11,-1 + 136 256 l 17,12,13 + 0 256 0 256 0 256 c 25,14,15 + 0 437 0 437 0 437 c 130,-1,16 + 0 437 0 437 344 896 c 1,17,18 + 344 896 344 896 0 1355 c 1,19,20 + 0 1536 0 1536 0 1536 c 152,-1,21 + 0 1536 0 1536 136 1536 c 24,22,23 + 136 1536 136 1536 384 1205 c 24,24,25 + 384 1205 384 1205 384 1792 c 25,26,-1 + 576 1792 l 25,27,-1 + 576 1205 l 0,28,-1 + 824 1536 l 24,29,30 + 824 1536 824 1536 960 1536 c 0,31,32 + 960 1536 960 1536 960 1355 c 1,33,34 + 960 1355 960 1355 616 896 c 1,0,1 +EndSplineSet +EndChar + +StartChar: plus +Encoding: 43 43 41 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +!WYmi&I*SHfQ[Ar!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +384 1536 m 29,0,-1 + 576 1536 l 25,1,-1 + 576 1024 l 25,2,-1 + 960 1024 l 25,3,-1 + 960 768 l 24,4,-1 + 576 768 l 24,5,-1 + 576 256 l 25,6,-1 + 384 256 l 25,7,-1 + 384 768 l 24,8,-1 + 0 768 l 24,9,-1 + 0 1024 l 25,10,-1 + 384 1024 l 25,11,-1 + 384 1536 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: comma +Encoding: 44 44 42 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 91 96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2\'ehBu +@W`0#D?/q@j]_^nKa/-g/b(@l!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +672 331 m 0,0,1 + 672 0 672 0 424 0 c 24,2,-1 + 288 0 l 25,3,-1 + 288 256 l 25,4,-1 + 424 256 l 0,5,6 + 480 256 480 256 480 331 c 24,7,-1 + 480 768 l 24,8,-1 + 672 768 l 24,9,10 + 672 384 672 384 672 331 c 0,0,1 +EndSplineSet +EndChar + +StartChar: hyphen +Encoding: 45 45 43 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 94 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns4Z$5e?V +@(66j=Y.W6D!n"P%0-S$$O.#5I6.E/!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 1024 m 25,0,-1 + 960 1024 l 25,1,-1 + 960 768 l 24,2,-1 + 0 768 l 24,3,4 + 0 768 0 768 0 1024 c 25,0,-1 +EndSplineSet +EndChar + +StartChar: period +Encoding: 46 46 44 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 84 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[;S^Ap +Lt+im)m]YX6<>Toz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 256 m 29,0,-1 + 384 256 l 25,1,-1 + 384 0 l 25,2,-1 + 192 0 l 25,3,-1 + 192 256 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: slash +Encoding: 47 47 45 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns3P!_,XK +'KmiO5a(=h_A-IB";qADJ4gNN!+[6ZO"d9^$.=M9!0Lq/#JY@cIfKHK!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +149 256 m 25,0,-1 + 0 256 l 25,1,-1 + 0 455 l 24,2,-1 + 811 1536 l 25,3,-1 + 960 1536 l 25,4,-1 + 960 1337 l 25,5,6 + 960 1337 960 1337 149 256 c 25,0,-1 +EndSplineSet +EndChar + +StartChar: zero +Encoding: 48 48 46 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7+I-GdXZ$IEpi.)7,8;?SlYfhRo0(sN,F`9.L.=*kqn*O=h/z8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +768 331 m 9,0,-1 + 768 1099 l 1,1,2 + 768 1099 768 1099 192 331 c 1,3,4 + 192 256 192 256 248 256 c 24,5,-1 + 712 256 l 0,6,7 + 768 256 768 256 768 331 c 9,0,-1 +768 1461 m 0,8,9 + 768 1536 768 1536 712 1536 c 0,10,-1 + 248 1536 l 0,11,12 + 192 1536 192 1536 192 1461 c 24,13,14 + 192 1461 192 1461 192 693 c 0,15,16 + 192 693 192 693 768 1461 c 0,8,9 +712 1792 m 0,17,18 + 960 1792 960 1792 960 1461 c 24,19,20 + 960 730 960 730 960 331 c 0,21,22 + 960 0 960 0 712 0 c 24,23,-1 + 248 0 l 0,24,25 + 0 0 0 0 0 331 c 24,26,27 + 0 1062 0 1062 0 1461 c 0,28,29 + 0 1792 0 1792 248 1792 c 24,30,31 + 248 1792 248 1792 712 1792 c 0,17,18 +EndSplineSet +EndChar + +StartChar: one +Encoding: 49 49 47 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 107 0.020325 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8CNNffG9`^HN: +$?/Rg<.YkCZNY4MMRc7t.Ofm.&k4,!^]4B4!='>cmbYYX!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +384 1734 m 0,0,1 + 384 1792 384 1792 480 1792 c 128,-1,2 + 576 1792 576 1792 576 1734 c 1,3,4 + 576 312 576 312 576 256 c 1,5,-1 + 712 256 l 0,6,7 + 768 256 768 256 768 128 c 132,-1,8 + 768 0 768 0 712 0 c 2,9,10 + 712 0 712 0 248 0 c 0,11,12 + 192 0 192 0 192 127 c 0,13,14 + 192 256 192 256 248 256 c 0,15,-1 + 384 256 l 1,16,17 + 384 256 384 256 384 1280 c 1,18,19 + 356 1280 356 1280 236 1280 c 0,20,21 + 192 1280 192 1280 192 1408 c 128,-1,22 + 192 1536 192 1536 236 1536 c 0,23,-1 + 328 1536 l 0,24,25 + 384 1536 384 1536 384 1611 c 0,26,-1 + 384 1734 l 0,0,1 +EndSplineSet +EndChar + +StartChar: two +Encoding: 50 50 48 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 124 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9ZS3`0h;_W'd,]a)KZF-2kWgZ%)Hlb9EI\9'u2d_)VHqI,MaFADrB5Wz8OZBB +Y!QNJ +EndImage2 +Fore +SplineSet +0 1461 m 0,0,1 + 0 1792 0 1792 248 1792 c 0,2,-1 + 712 1792 l 0,3,4 + 960 1792 960 1792 960 1461 c 0,5,6 + 960 1114 960 1114 960 1099 c 0,7,8 + 960 1099 960 1099 712 768 c 0,9,-1 + 520 768 l 1,10,11 + 520 768 520 768 144 256 c 1,12,13 + 144 256 144 256 904 256 c 0,14,15 + 960 256 960 256 960 128 c 128,-1,16 + 960 0 960 0 904 0 c 2,17,18 + 904 0 904 0 0 0 c 1,19,20 + 0 218 0 218 0 437 c 0,21,22 + 0 437 0 437 440 1024 c 2,23,24 + 440 1024 440 1024 632 1024 c 0,25,26 + 632 1024 632 1024 768 1205 c 0,27,28 + 768 1205 768 1205 768 1461 c 0,29,30 + 768 1536 768 1536 712 1536 c 0,31,-1 + 248 1536 l 0,32,33 + 192 1536 192 1536 192 1461 c 0,34,-1 + 192 1337 l 0,35,36 + 192 1280 192 1280 97 1280 c 1,37,38 + 0 1280 0 1280 0 1337 c 1,39,40 + 0 1337 0 1337 0 1461 c 0,0,1 +EndSplineSet +EndChar + +StartChar: three +Encoding: 51 51 49 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 123 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?K_r!ro=GQ8sb%RU9&*Yr8r +a<3rAO<+O4680RGkSi@dcum2^_A.TCJhXc&-?K9U:)FF`,dJV92ZNga:DsTEXUAD7!!!!j78?7R +6=>BF +EndImage2 +Fore +SplineSet +56 1792 m 0,0,1 + 508 1792 508 1792 960 1792 c 25,2,3 + 960 1792 960 1792 960 1355 c 1,4,5 + 960 1355 960 1355 768 1099 c 0,6,7 + 768 1099 768 1099 768 1024 c 1,8,9 + 960 1024 960 1024 960 696 c 0,10,11 + 960 694 960 694 960 693 c 0,12,13 + 960 693 960 693 960 331 c 17,14,15 + 960 0 960 0 712 0 c 24,16,17 + 257 0 257 0 248 0 c 0,18,19 + 0 0 0 0 0 331 c 25,20,21 + 0 455 0 455 0 455 c 0,22,23 + 0 512 0 512 96 512 c 128,-1,24 + 192 512 192 512 192 455 c 0,25,-1 + 192 331 l 17,26,27 + 192 256 192 256 248 256 c 24,28,29 + 248 256 248 256 712 256 c 0,30,31 + 768 256 768 256 768 331 c 25,32,33 + 768 550 768 550 768 693 c 0,34,35 + 768 768 768 768 712 768 c 24,36,-1 + 427 768 l 0,37,38 + 384 768 384 768 384 896 c 128,-1,39 + 384 1024 384 1024 427 1024 c 8,40,-1 + 440 1024 l 24,41,42 + 440 1024 440 1024 768 1461 c 17,43,44 + 768 1536 768 1536 712 1536 c 24,45,-1 + 56 1536 l 0,46,47 + 0 1536 0 1536 0 1664 c 128,-1,48 + 0 1792 0 1792 56 1792 c 0,0,1 +EndSplineSet +EndChar + +StartChar: four +Encoding: 52 52 50 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h +/&3J<;?9euP/LoF'0]!L#p;kq*/SJM$ShsVBlHRoN5Gi"s0i[Nd4O_kz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +576 768 m 24,0,-1 + 576 1355 l 25,1,-1 + 192 843 l 25,2,-1 + 192 768 l 24,3,4 + 192 768 192 768 576 768 c 24,0,-1 +768 1792 m 24,5,-1 + 768 768 l 24,6,-1 + 917 768 l 0,7,8 + 960 768 960 768 960 640 c 128,-1,9 + 960 512 960 512 917 512 c 8,10,-1 + 768 512 l 25,11,-1 + 768 0 l 25,12,-1 + 576 0 l 25,13,-1 + 576 512 l 25,14,-1 + 0 512 l 25,15,-1 + 0 949 l 25,16,-1 + 632 1792 l 24,17,18 + 632 1792 632 1792 768 1792 c 24,5,-1 +EndSplineSet +EndChar + +StartChar: five +Encoding: 53 53 51 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8sb%RU9&*YsiL +A-$ei0MF`5b^qI_aN00H+qqPMk^4_=%X\7m"gT=o.fit&)ZhRQ%hJ^@!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +917 1792 m 0,0,1 + 960 1792 960 1792 960 1664 c 128,-1,2 + 960 1536 960 1536 917 1536 c 8,3,-1 + 192 1536 l 24,4,-1 + 192 1280 l 25,5,-1 + 712 1280 l 0,6,7 + 960 1280 960 1280 960 949 c 24,8,9 + 960 331 960 331 960 331 c 0,10,11 + 960 0 960 0 712 0 c 24,12,-1 + 248 0 l 0,13,14 + 0 0 0 0 0 331 c 24,15,16 + 0 455 0 455 0 455 c 0,17,18 + 0 512 0 512 96 512 c 128,-1,19 + 192 512 192 512 192 455 c 8,20,-1 + 192 331 l 0,21,22 + 192 256 192 256 248 256 c 24,23,-1 + 712 256 l 0,24,25 + 768 256 768 256 768 331 c 24,26,27 + 768 949 768 949 768 949 c 0,28,29 + 768 1024 768 1024 712 1024 c 24,30,-1 + 0 1024 l 25,31,-1 + 0 1792 l 18,32,33 + 0 1792 0 1792 917 1792 c 0,0,1 +EndSplineSet +EndChar + +StartChar: six +Encoding: 54 54 52 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+FNffG9`ah?c +"',Db6l(HV">W6rnCdqEJ?/k/,d8$)K':c?+m[.fAc_/9jTCSK!1`*k"G(^D63$uc!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +192 331 m 0,0,1 + 192 256 192 256 248 256 c 24,2,-1 + 712 256 l 0,3,4 + 768 256 768 256 768 331 c 24,5,6 + 768 550 768 550 768 693 c 0,7,8 + 768 768 768 768 712 768 c 24,9,10 + 712 768 712 768 192 768 c 24,11,12 + 192 768 192 768 192 331 c 0,0,1 +917 1792 m 0,13,14 + 960 1792 960 1792 960 1664 c 128,-1,15 + 960 1536 960 1536 917 1536 c 0,16,-1 + 520 1536 l 25,17,-1 + 192 1099 l 25,18,-1 + 192 1024 l 25,19,-1 + 712 1024 l 0,20,21 + 960 1024 960 1024 960 693 c 24,22,23 + 960 346 960 346 960 331 c 0,24,25 + 960 0 960 0 712 0 c 24,26,-1 + 248 0 l 0,27,28 + 0 0 0 0 0 331 c 24,29,30 + 0 331 0 331 0 1205 c 24,31,32 + 0 1205 0 1205 440 1792 c 24,33,34 + 440 1792 440 1792 917 1792 c 0,13,14 +EndSplineSet +EndChar + +StartChar: seven +Encoding: 55 55 53 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8sb%RU9&*Yr8r +a<3rAO<+O4680RGkSi@d5W[:=6(5UsE(Rn]+BsKDL0K3]!TO7^iA_MXMbJN[z8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +0 1792 m 25,0,-1 + 960 1792 l 25,1,-1 + 960 1355 l 25,2,-1 + 384 587 l 25,3,-1 + 384 0 l 25,4,-1 + 192 0 l 25,5,-1 + 192 693 l 24,6,-1 + 768 1461 l 25,7,-1 + 768 1536 l 25,8,-1 + 0 1536 l 17,9,10 + 0 1536 0 1536 0 1792 c 25,0,-1 +EndSplineSet +EndChar + +StartChar: eight +Encoding: 56 56 54 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 100 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7*n(b?f[")J,@Ce5cOVrrF"z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 331 m 0,0,1 + 192 256 192 256 248 256 c 24,2,-1 + 712 256 l 0,3,4 + 768 256 768 256 768 331 c 24,5,6 + 768 693 768 693 768 693 c 1,7,8 + 768 768 768 768 712 768 c 1,9,10 + 712 768 712 768 248 768 c 0,11,12 + 192 768 192 768 192 693 c 24,13,14 + 192 608 192 608 192 331 c 0,0,1 +192 1099 m 0,15,16 + 192 1024 192 1024 248 1024 c 24,17,-1 + 712 1024 l 0,18,19 + 768 1024 768 1024 768 1099 c 24,20,21 + 768 1318 768 1318 768 1461 c 0,22,23 + 768 1536 768 1536 712 1536 c 24,24,-1 + 248 1536 l 0,25,26 + 192 1536 192 1536 192 1461 c 24,27,28 + 192 1389 192 1389 192 1099 c 0,15,16 +876 896 m 1,29,30 + 960 839 960 839 960 693 c 0,31,32 + 960 331 960 331 960 331 c 0,33,34 + 960 0 960 0 712 0 c 24,35,36 + 248 0 248 0 248 0 c 0,37,38 + 0 0 0 0 0 331 c 24,39,40 + 0 331 0 331 0 693 c 0,41,42 + 1 834 1 834 84 896 c 1,43,44 + 0 957 0 957 0 1099 c 0,45,46 + 0 1461 0 1461 0 1461 c 0,47,48 + 0 1792 0 1792 248 1792 c 24,49,50 + 712 1792 712 1792 712 1792 c 0,51,52 + 960 1792 960 1792 960 1461 c 24,53,54 + 960 1446 960 1446 960 1099 c 0,55,56 + 960 954 960 954 876 896 c 1,29,30 +EndSplineSet +EndChar + +StartChar: nine +Encoding: 57 57 55 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 123 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7*n(b?f[aB"t7"1nTe89Dg!BF +EndImage2 +Fore +SplineSet +768 1461 m 0,0,1 + 768 1536 768 1536 712 1536 c 24,2,-1 + 248 1536 l 0,3,4 + 192 1536 192 1536 192 1461 c 24,5,6 + 192 1242 192 1242 192 1099 c 0,7,8 + 192 1024 192 1024 248 1024 c 24,9,-1 + 768 1024 l 25,10,11 + 768 1280 768 1280 768 1461 c 0,0,1 +712 1792 m 0,12,13 + 960 1792 960 1792 960 1461 c 24,14,15 + 960 1461 960 1461 960 587 c 25,16,-1 + 520 0 l 1,17,-1 + 43 0 l 17,18,19 + 0 0 0 0 0 128 c 128,-1,20 + 0 256 0 256 43 256 c 0,21,-1 + 440 256 l 24,22,23 + 440 256 440 256 768 693 c 24,24,25 + 768 693 768 693 768 768 c 24,26,-1 + 248 768 l 0,27,28 + 0 768 0 768 0 1099 c 24,29,30 + 0 1446 0 1446 0 1461 c 0,31,32 + 0 1792 0 1792 248 1792 c 24,33,34 + 248 1792 248 1792 712 1792 c 0,12,13 +EndSplineSet +EndChar + +StartChar: colon +Encoding: 58 58 56 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns4f$5aWu +Yo3g*!LHaC$7Ih6Wrmm(!&@FZ$m].ZLh)ch@bW1UUYoz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +672 768 m 24,0,1 + 672 768 672 768 672 331 c 0,2,3 + 672 0 672 0 424 0 c 24,4,-1 + 288 0 l 25,5,-1 + 288 256 l 25,6,-1 + 424 256 l 0,7,8 + 480 256 480 256 480 331 c 24,9,-1 + 480 768 l 24,10,11 + 480 768 480 768 672 768 c 24,0,1 +480 1280 m 25,12,-1 + 672 1280 l 25,13,-1 + 672 1024 l 25,14,-1 + 480 1024 l 25,15,-1 + 480 1280 l 25,12,-1 +EndSplineSet +EndChar + +StartChar: less +Encoding: 60 60 58 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h +.f`.M1CU>bQR'WXOI:?a_#uM/S)%HW!"#kEp_:ObM+\E\.d%TT%fbVFz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +232 896 m 1,0,1 + 232 896 232 896 768 182 c 0,2,3 + 768 182 768 182 768 0 c 25,4,5 + 768 0 768 0 632 0 c 24,6,7 + 632 0 632 0 0 843 c 25,8,-1 + 0 949 l 25,9,10 + 0 949 0 949 632 1792 c 24,11,12 + 632 1792 632 1792 768 1792 c 24,13,14 + 768 1792 768 1792 768 1611 c 1,15,-1 + 232 896 l 1,0,1 +EndSplineSet +EndChar + +StartChar: equal +Encoding: 61 61 59 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 96 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd6b(@jRAf]t[&9K/tn7*(2lS*^gz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +0 768 m 24,0,-1 + 960 768 l 24,1,-1 + 960 512 l 25,2,-1 + 0 512 l 25,3,4 + 0 512 0 512 0 768 c 24,0,-1 +0 1280 m 25,5,-1 + 960 1280 l 25,6,-1 + 960 1024 l 25,7,-1 + 0 1024 l 25,8,-1 + 0 1280 l 25,5,-1 +EndSplineSet +EndChar + +StartChar: greater +Encoding: 62 62 60 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?L$c9Vp?+:&'8li7!DD@\!2 +/(Y77eXll!"%j1]?p11f#p"OPpWj:T+ftqt">",1((Z@:V:5JF!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +536 896 m 129,-1,1 + 536 896 536 896 0 1611 c 1,2,-1 + 0 1792 l 25,3,4 + 136 1792 136 1792 136 1792 c 24,5,6 + 768 949 768 949 768 949 c 25,7,8 + 768 843 768 843 768 843 c 25,9,10 + 136 0 136 0 136 0 c 24,11,12 + 0 0 0 0 0 0 c 25,13,14 + 0 181 0 181 0 181 c 0,15,0 + 536 896 536 896 536 896 c 129,-1,1 +EndSplineSet +EndChar + +StartChar: question +Encoding: 63 63 61 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9ZS2q8W^2N0XJ#UU*tO@7&Suj+BsQ$#d+0\-ccVp@J)Z[b`.KE;r1Z)!B$?j@tkj!!;``sDh9cj5nz8OZBB +Y!QNJ +EndImage2 +Fore +SplineSet +768 1461 m 1,0,1 + 768 1536 768 1536 712 1536 c 0,2,3 + 480 1536 480 1536 248 1536 c 1,4,5 + 192 1536 192 1536 192 1461 c 1,6,7 + 192 1461 192 1461 192 331 c 1,8,9 + 192 256 192 256 248 256 c 1,10,11 + 248 256 248 256 917 256 c 0,12,13 + 960 256 960 256 960 128 c 128,-1,14 + 960 0 960 0 917 0 c 0,15,16 + 917 0 917 0 235 0 c 0,17,18 + 0 0 0 0 0 327 c 1,19,20 + 0 1026 0 1026 0 1461 c 0,21,22 + 0 1792 0 1792 248 1792 c 0,23,24 + 248 1792 248 1792 712 1792 c 0,25,26 + 960 1792 960 1792 960 1461 c 0,27,28 + 960 986 960 986 960 839 c 0,29,30 + 960 512 960 512 712 512 c 0,31,32 + 712 512 712 512 632 512 c 0,33,34 + 384 512 384 512 384 843 c 0,35,36 + 384 1213 384 1213 384 1223 c 0,37,38 + 384 1280 384 1280 480 1280 c 128,-1,39 + 576 1280 576 1280 576 1223 c 0,40,-1 + 576 896 l 0,41,42 + 576 825 576 825 632 825 c 0,43,44 + 632 825 632 825 712 825 c 0,45,46 + 768 825 768 825 768 896 c 0,47,48 + 768 896 768 896 768 1461 c 1,0,1 +EndSplineSet +EndChar + +StartChar: A +Encoding: 65 65 63 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 119 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8CNNffG9`^HN: +$:'asKBF +EndImage2 +Fore +SplineSet +480 1483 m 1,0,1 + 480 1483 480 1483 192 1099 c 1,2,-1 + 192 825 l 0,3,4 + 192 768 192 768 235 768 c 24,5,6 + 235 768 235 768 725 768 c 0,7,8 + 768 768 768 768 768 825 c 24,9,10 + 768 825 768 825 768 1099 c 0,11,-1 + 480 1483 l 1,0,1 +520 1792 m 17,12,13 + 520 1792 520 1792 960 1205 c 24,14,-1 + 960 0 l 25,15,-1 + 768 0 l 25,16,-1 + 768 455 l 0,17,18 + 768 512 768 512 725 512 c 24,19,20 + 480 512 480 512 235 512 c 24,21,22 + 192 512 192 512 192 455 c 24,23,-1 + 192 0 l 25,24,-1 + 0 0 l 25,25,-1 + 0 1205 l 24,26,-1 + 440 1792 l 24,27,28 + 440 1792 440 1792 520 1792 c 17,12,13 +EndSplineSet +EndChar + +StartChar: B +Encoding: 66 66 64 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 96 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8sb%RgE0H5;TS +A3i[S7MJ$"*n.r'K>@lpj;8j5Q?;#Rz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 768 m 0,0,-1 + 192 256 l 1,1,-1 + 725 256 l 0,2,3 + 768 256 768 256 768 313 c 1,4,5 + 768 640 768 640 768 711 c 0,6,7 + 768 768 768 768 725 768 c 1,8,9 + 192 768 192 768 192 768 c 0,0,-1 +725 1024 m 1,10,11 + 768 1024 768 1024 768 1081 c 0,12,-1 + 768 1465 l 1,13,14 + 768 1536 768 1536 725 1536 c 0,15,-1 + 192 1536 l 1,16,-1 + 192 1024 l 1,17,-1 + 725 1024 l 1,10,11 +725 1792 m 0,18,19 + 960 1792 960 1792 960 1465 c 1,20,21 + 960 1180 960 1180 960 1081 c 0,22,23 + 960 896 960 896 864 896 c 1,24,25 + 960 896 960 896 960 710 c 0,26,-1 + 960 313 l 1,27,28 + 960 0 960 0 725 0 c 0,29,-1 + 0 0 l 1,30,-1 + 0 1792 l 1,31,32 + 0 1792 0 1792 725 1792 c 0,18,19 +EndSplineSet +EndChar + +StartChar: C +Encoding: 67 67 65 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7+1#-oLF#X\X(#1=5/3uDKH$cl(R6$,$c!::.1#VQD@0)ttP!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +192 313 m 1,0,1 + 192 256 192 256 235 256 c 0,2,3 + 480 256 480 256 725 256 c 0,4,5 + 768 256 768 256 768 313 c 0,6,7 + 768 313 768 313 768 512 c 1,8,9 + 768 512 768 512 960 512 c 1,10,-1 + 960 313 l 1,11,12 + 960 0 960 0 725 0 c 0,13,14 + 480 0 480 0 235 0 c 0,15,16 + 0 0 0 0 0 313 c 1,17,18 + 0 313 0 313 0 512 c 1,19,20 + 0 512 0 512 0 1280 c 1,21,-1 + 0 1465 l 1,22,23 + 0 1792 0 1792 235 1792 c 0,24,25 + 480 1792 480 1792 725 1792 c 0,26,27 + 960 1792 960 1792 960 1465 c 1,28,29 + 960 1465 960 1465 960 1280 c 1,30,-1 + 768 1279 l 1,31,32 + 768 1464 768 1464 768 1465 c 0,33,34 + 768 1536 768 1536 725 1536 c 0,35,36 + 725 1536 725 1536 235 1536 c 1,37,38 + 192 1536 192 1536 192 1465 c 1,39,40 + 192 889 192 889 192 313 c 1,0,1 +EndSplineSet +EndChar + +StartChar: D +Encoding: 68 68 66 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 98 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.7lon<#?K_r!ro=GQ8sb%RgE0H5;TS +A3i[S7MJ$"*n.r'FAP6L(B>)*&cj#e^:jRI!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +725 256 m 0,0,1 + 768 256 768 256 768 313 c 1,2,3 + 768 313 768 313 768 1465 c 1,4,5 + 768 1536 768 1536 725 1536 c 1,6,7 + 725 1536 725 1536 192 1536 c 1,8,-1 + 192 256 l 1,9,10 + 459 256 459 256 725 256 c 0,0,1 +725 1792 m 0,11,12 + 960 1789 960 1789 960 1465 c 0,13,14 + 960 1236 960 1236 960 313 c 0,15,16 + 960 0 960 0 725 0 c 1,17,18 + 725 0 725 0 0 0 c 1,19,20 + 0 0 0 0 0 1792 c 0,21,22 + 0 1792 0 1792 725 1792 c 0,11,12 +EndSplineSet +EndChar + +StartChar: E +Encoding: 69 69 67 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8sb%RU9&*YsiL +A-$eiR*Z#`q&!/*RmmK15]/iq"p!0=(&Pfd:+cMH!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 0 m 29,0,-1 + 0 1792 l 25,1,-1 + 960 1792 l 25,2,-1 + 960 1536 l 25,3,-1 + 192 1536 l 25,4,-1 + 192 1024 l 25,5,-1 + 768 1024 l 25,6,-1 + 768 768 l 25,7,-1 + 192 768 l 25,8,-1 + 192 256 l 25,9,-1 + 960 256 l 25,10,-1 + 960 0 l 25,11,-1 + 0 0 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: F +Encoding: 70 70 68 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 100 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8sb%RU9&*YsiL +A-$eiR*Z#`q&!/*Rmsq'"Pj%XQV%kjh$9`\z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +0 0 m 29,0,-1 + 0 1792 l 25,1,-1 + 960 1792 l 25,2,-1 + 960 1536 l 25,3,-1 + 192 1536 l 25,4,-1 + 192 1024 l 25,5,-1 + 768 1024 l 25,6,-1 + 768 768 l 25,7,-1 + 192 768 l 25,8,-1 + 192 0 l 25,9,-1 + 0 0 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: G +Encoding: 71 71 69 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8+BNffG971$7@ +O:5G_Qr(/!iK0o:j;)k3TU:8r31+P6+@1*T0M)fb!/ZRF%f-o69)nql!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 1465 m 1,0,1 + 0 1792 0 1792 235 1792 c 1,2,3 + 235 1792 235 1792 960 1792 c 25,4,-1 + 960 1536 l 1,5,-1 + 235 1536 l 1,6,7 + 192 1536 192 1536 192 1465 c 1,8,9 + 192 1465 192 1465 192 313 c 1,10,11 + 192 256 192 256 235 256 c 1,12,13 + 235 256 235 256 768 256 c 1,14,-1 + 768 512 l 1,15,-1 + 618 512 l 0,16,17 + 576 569 576 569 576 667 c 0,18,19 + 576 711 576 711 618 768 c 0,20,21 + 618 768 618 768 960 768 c 1,22,23 + 960 768 960 768 960 0 c 25,24,-1 + 235 0 l 0,25,26 + 0 0 0 0 0 313 c 1,27,28 + 0 610 0 610 0 1465 c 1,0,1 +EndSplineSet +EndChar + +StartChar: H +Encoding: 72 72 70 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 105 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8C%,9r(&3hH^I +((5nj!Z$kEFCUFB!\6NZ-b!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 0 m 29,0,-1 + 0 1792 l 25,1,-1 + 192 1792 l 25,2,-1 + 192 1024 l 25,3,-1 + 768 1024 l 25,4,-1 + 768 1792 l 25,5,-1 + 960 1792 l 25,6,-1 + 960 0 l 25,7,-1 + 768 0 l 25,8,-1 + 768 768 l 25,9,-1 + 192 768 l 25,10,-1 + 192 0 l 25,11,-1 + 0 0 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: I +Encoding: 73 73 71 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8+BNffG9Xor#n +'1`([DE!FS&-nOG\/TB9!W_>;(CfiO*cD#Y!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +424 896 m 1,0,1 + 424 896 424 896 960 182 c 0,2,3 + 960 182 960 182 960 0 c 25,4,5 + 960 0 960 0 824 0 c 24,6,-1 + 248 768 l 24,7,8 + 248 768 248 768 192 768 c 24,9,-1 + 192 0 l 25,10,-1 + 0 0 l 25,11,-1 + 0 1792 l 25,12,-1 + 192 1792 l 25,13,-1 + 192 1024 l 25,14,15 + 192 1024 192 1024 248 1024 c 24,16,-1 + 824 1792 l 24,17,18 + 824 1792 824 1792 960 1792 c 25,19,-1 + 960 1611 l 1,20,-1 + 424 896 l 1,0,1 +EndSplineSet +EndChar + +StartChar: L +Encoding: 76 76 74 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 94 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8C%,9n7D"pQEe +Z9ZOJTE+$V$u[?e)us3W#R[5_a@?41!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 0 m 29,0,-1 + 0 1792 l 25,1,-1 + 192 1792 l 25,2,-1 + 192 256 l 25,3,-1 + 960 256 l 25,4,-1 + 960 0 l 25,5,-1 + 0 0 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: M +Encoding: 77 77 75 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8C%,9r(&3hH^( +$PS3@a?%*D5dl1gZ.T=^J?/jD%9J'S2b5Z.!P2#CT:c5ccX[ItTT5+(z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +480 1333 m 1,0,1 + 480 1333 480 1333 824 1792 c 0,2,3 + 824 1792 824 1792 960 1792 c 25,4,-1 + 960 0 l 25,5,-1 + 768 0 l 1,6,-1 + 768 1355 l 25,7,8 + 768 1355 768 1355 576 1099 c 1,9,-1 + 576 768 l 1,10,11 + 576 768 576 768 384 768 c 1,12,-1 + 384 1099 l 1,13,14 + 384 1099 384 1099 192 1355 c 25,15,-1 + 192 0 l 1,16,-1 + 0 0 l 25,17,-1 + 0 1792 l 25,18,19 + 0 1792 0 1792 136 1792 c 0,20,-1 + 480 1333 l 1,0,1 +EndSplineSet +EndChar + +StartChar: N +Encoding: 78 78 76 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8C%,9r(&3hH^I +((1AK!*pDH3j8[I1N4dp>CfEZ>QMoJC`Yo?J8@0'%0/`c%2/03a,U-"!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +192 1461 m 1,0,-1 + 768 693 l 1,1,2 + 768 693 768 693 768 1792 c 1,3,4 + 768 1792 768 1792 960 1792 c 1,5,6 + 960 1792 960 1792 960 0 c 1,7,-1 + 768 0 l 1,8,9 + 768 0 768 0 768 331 c 1,10,-1 + 192 1099 l 1,11,12 + 192 1099 192 1099 192 0 c 1,13,-1 + 0 0 l 1,14,-1 + 0 1792 l 1,15,16 + 0 1792 0 1792 192 1792 c 1,17,18 + 192 1792 192 1792 192 1461 c 1,0,-1 +EndSplineSet +EndChar + +StartChar: O +Encoding: 79 79 77 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 103 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7*n(j&Ti!cei9?N:'`,npVAI9l+BF +EndImage2 +Fore +SplineSet +712 1536 m 0,0,1 + 712 1536 712 1536 248 1536 c 1,2,3 + 192 1536 192 1536 192 1461 c 1,4,5 + 192 1461 192 1461 192 331 c 1,6,7 + 192 256 192 256 248 256 c 0,8,9 + 248 256 248 256 712 256 c 0,10,11 + 768 256 768 256 768 331 c 1,12,13 + 768 331 768 331 768 1280 c 1,14,15 + 768 1536 768 1536 712 1536 c 0,0,1 +960 512 m 2,16,-1 + 960 331 l 1,17,18 + 960 0 960 0 712 0 c 0,19,20 + 248 0 248 0 248 0 c 0,21,22 + 0 0 0 0 0 331 c 1,23,24 + 0 331 0 331 0 512 c 1,25,26 + 0 512 0 512 0 1280 c 1,27,-1 + 0 1461 l 1,28,29 + 0 1790 0 1790 248 1792 c 0,30,31 + 248 1792 248 1792 712 1792 c 0,32,33 + 960 1792 960 1792 960 1461 c 1,34,35 + 960 657 960 657 960 512 c 2,16,-1 +EndSplineSet +EndChar + +StartChar: P +Encoding: 80 80 78 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 103 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8sb%RgE0H5;TS +A3i[S7MJ$"*n.r'Ug&Cf,!d^b.KBITBGCO-o@;t'!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +712 1792 m 0,0,1 + 960 1792 960 1792 960 1461 c 1,2,3 + 960 1188 960 1188 960 1099 c 1,4,5 + 960 768 960 768 712 768 c 0,6,7 + 712 768 712 768 192 768 c 1,8,-1 + 192 0 l 25,9,-1 + 0 0 l 25,10,-1 + 0 1792 l 1,11,12 + 18 1792 18 1792 712 1792 c 0,0,1 +712 1024 m 0,13,14 + 768 1024 768 1024 768 1099 c 1,15,16 + 768 1408 768 1408 768 1461 c 0,17,18 + 768 1536 768 1536 712 1536 c 1,19,20 + 712 1536 712 1536 192 1536 c 1,21,-1 + 192 1024 l 1,22,23 + 192 1024 192 1024 712 1024 c 0,13,14 +EndSplineSet +EndChar + +StartChar: Q +Encoding: 81 81 79 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7*n(rRpiFpG<]E"bM1U>$2Va97]W8YV[W!-uU'$t5_L%KHJ/!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +384 587 m 1,0,-1 + 384 768 l 0,1,-1 + 520 768 l 1,2,-1 + 960 181 l 0,3,-1 + 960 0 l 1,4,-1 + 824 0 l 0,5,6 + 824 0 824 0 384 587 c 1,0,-1 +248 0 m 1,7,8 + 0 0 0 0 0 331 c 1,9,10 + 0 331 0 331 0 1461 c 0,11,12 + 0 1792 0 1792 248 1792 c 1,13,-1 + 712 1792 l 2,14,15 + 960 1792 960 1792 960 1461 c 1,16,-1 + 960 569 l 1,17,18 + 960 512 960 512 864 512 c 129,-1,19 + 768 512 768 512 768 569 c 1,20,-1 + 768 1461 l 2,21,22 + 768 1536 768 1536 712 1536 c 1,23,24 + 712 1536 712 1536 248 1536 c 1,25,26 + 192 1536 192 1536 192 1461 c 2,27,28 + 192 1461 192 1461 192 331 c 2,29,30 + 192 256 192 256 248 256 c 1,31,32 + 248 256 248 256 548 256 c 0,33,34 + 576 256 576 256 576 128 c 128,-1,35 + 576 0 576 0 548 0 c 0,36,37 + 548 0 548 0 248 0 c 1,7,8 +EndSplineSet +EndChar + +StartChar: R +Encoding: 82 82 80 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%RgE0H5;TS +A3i[S7MJ$"*n.r'"K_Zn!4)_r,F]%L![J)X+!&-3J0_?J!W\@^*W&Fp/p[Kt!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +768 1461 m 0,0,1 + 768 1536 768 1536 712 1536 c 24,2,-1 + 192 1536 l 24,3,-1 + 192 1024 l 25,4,-1 + 712 1024 l 0,5,6 + 768 1024 768 1024 768 1099 c 24,7,8 + 768 1099 768 1099 768 1461 c 0,0,1 +520 768 m 25,9,10 + 520 768 520 768 960 181 c 24,11,12 + 960 181 960 181 960 0 c 25,13,14 + 960 0 960 0 824 0 c 0,15,-1 + 248 768 l 24,16,17 + 248 768 248 768 192 768 c 0,18,-1 + 192 0 l 25,19,-1 + 0 0 l 25,20,-1 + 0 1792 l 1,21,-1 + 712 1792 l 1,22,23 + 960 1792 960 1792 960 1461 c 8,24,25 + 960 1461 960 1461 960 1099 c 2,26,27 + 960 768 960 768 712 768 c 8,28,29 + 616 768 616 768 520 768 c 25,9,10 +EndSplineSet +EndChar + +StartChar: S +Encoding: 83 83 81 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+BNffG9Xor#n +8-[$EOCD`h9Q7+1#-oLFL]o&ScO-lqOEFu6JZKgH3hi\U!641H#5#FNLB%;S!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +712 1792 m 0,0,1 + 960 1792 960 1792 960 1461 c 0,2,3 + 960 1337 960 1337 960 1337 c 0,4,5 + 917 1280 917 1280 864 1280 c 129,-1,6 + 811 1280 811 1280 768 1337 c 1,7,-1 + 768 1461 l 0,8,9 + 768 1536 768 1536 712 1536 c 24,10,-1 + 248 1536 l 0,11,12 + 192 1536 192 1536 192 1461 c 24,13,14 + 192 1218 192 1218 192 1099 c 0,15,16 + 192 1024 192 1024 248 1024 c 24,17,-1 + 712 1024 l 0,18,19 + 960 1024 960 1024 960 693 c 24,20,21 + 960 346 960 346 960 331 c 0,22,23 + 960 0 960 0 712 0 c 24,24,-1 + 248 0 l 0,25,26 + 0 0 0 0 0 331 c 0,27,28 + 0 455 0 455 0 455 c 0,29,30 + 49 512 49 512 97 512 c 128,-1,31 + 145 512 145 512 192 455 c 8,32,-1 + 192 331 l 0,33,34 + 192 256 192 256 248 256 c 24,35,-1 + 712 256 l 0,36,37 + 768 256 768 256 768 331 c 24,38,39 + 768 550 768 550 768 693 c 0,40,41 + 768 768 768 768 712 768 c 24,42,-1 + 248 768 l 0,43,44 + 0 768 0 768 0 1099 c 24,45,46 + 0 1446 0 1446 0 1461 c 0,47,48 + 0 1792 0 1792 248 1792 c 24,49,50 + 480 1792 480 1792 712 1792 c 0,0,1 +EndSplineSet +EndChar + +StartChar: T +Encoding: 84 84 82 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8sb%RU9&*YoTJ +Ocbb,`^VkJ$(6F*4W"k5!8uuL"pBF +EndImage2 +Fore +SplineSet +192 1792 m 25,0,-1 + 192 331 l 0,1,2 + 192 256 192 256 248 256 c 24,3,-1 + 712 256 l 0,4,5 + 768 256 768 256 768 331 c 24,6,-1 + 768 1792 l 24,7,-1 + 960 1792 l 25,8,9 + 960 1792 960 1792 960 331 c 0,10,11 + 960 0 960 0 712 0 c 24,12,-1 + 248 0 l 0,13,14 + 0 0 0 0 0 331 c 24,15,16 + 0 331 0 331 0 1792 c 25,17,-1 + 192 1792 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: V +Encoding: 86 86 84 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 103 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/kJGs<#?K_r!ro=GQ8C%,9r(&3hH^I +((5m=$:(253=JBF +EndImage2 +Fore +SplineSet +480 309 m 1,0,1 + 480 309 480 309 768 693 c 0,2,-1 + 768 1792 l 24,3,4 + 768 1792 768 1792 960 1792 c 25,5,-1 + 960 587 l 25,6,-1 + 520 0 l 25,7,8 + 520 0 520 0 440 0 c 24,9,10 + 440 0 440 0 0 587 c 25,11,-1 + 0 1792 l 25,12,-1 + 192 1792 l 25,13,-1 + 192 693 l 0,14,-1 + 480 309 l 1,0,1 +EndSplineSet +EndChar + +StartChar: W +Encoding: 87 87 85 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8C%,9r(&3hH^I +((5nB"mAFn$mX%#OD^.mYaGPN!Tm;t%5T%n!ru:Z%2(b=8,WDf!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +480 459 m 1,0,1 + 136 0 136 0 136 0 c 0,2,3 + 0 0 0 0 0 0 c 153,-1,4 + 0 0 0 0 0 1792 c 25,5,-1 + 192 1792 l 25,6,-1 + 192 437 l 24,7,-1 + 384 693 l 0,8,-1 + 384 1024 l 1,9,10 + 384 1024 384 1024 576 1024 c 1,11,12 + 576 1024 576 1024 576 693 c 0,13,-1 + 768 437 l 24,14,-1 + 768 1792 l 25,15,-1 + 960 1792 l 25,16,-1 + 960 0 l 25,17,18 + 824 0 824 0 824 0 c 0,19,20 + 480 459 480 459 480 459 c 1,0,1 +EndSplineSet +EndChar + +StartChar: X +Encoding: 88 88 86 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L,:Kn/++:)bps..=>UQd0V +7.q0\H1/*:bFuki:0SK<8P>1n>>TT7N% +2,#,3n0nECJPQm5%Cd+g'n@9U9bE6aQm-'B!ruA_\La!3?7A:)L&ch"J&dT5?Ho:s)!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +480 971 m 1,0,1 + 480 971 480 971 136 512 c 0,2,3 + 136 512 136 512 0 512 c 25,4,5 + 0 512 0 512 0 693 c 24,6,7 + 0 693 0 693 440 1280 c 24,8,9 + 440 1280 440 1280 520 1280 c 25,10,11 + 520 1280 520 1280 960 693 c 24,12,13 + 960 693 960 693 960 512 c 25,14,15 + 960 512 960 512 824 512 c 0,16,-1 + 480 971 l 1,0,1 +EndSplineSet +EndChar + +StartChar: underscore +Encoding: 95 95 93 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +0 256 m 29,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: grave +Encoding: 96 96 94 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8CJNffG9V\638 +OBF +EndImage2 +Fore +SplineSet +480 768 m 1,0,1 + 480 768 480 768 331 768 c 1,2,3 + 288 768 288 768 288 711 c 1,4,5 + 288 711 288 711 288 569 c 1,6,7 + 288 512 288 512 331 512 c 1,8,9 + 331 512 331 512 480 512 c 1,10,11 + 480 512 480 512 480 768 c 1,0,1 +331 256 m 2,12,13 + 96 256 96 256 96 569 c 0,14,15 + 96 640 96 640 96 711 c 0,16,17 + 96 1024 96 1024 331 1024 c 2,18,19 + 331 1024 331 1024 480 1024 c 1,20,21 + 480 1024 480 1024 480 1223 c 1,22,23 + 480 1280 480 1280 437 1280 c 1,24,25 + 437 1280 437 1280 139 1280 c 0,26,27 + 96 1280 96 1280 96 1408 c 0,28,29 + 97 1536 97 1536 139 1536 c 0,30,31 + 288 1536 288 1536 437 1536 c 0,32,33 + 672 1536 672 1536 672 1223 c 0,34,35 + 672 1223 672 1223 672 512 c 1,36,-1 + 821 512 l 0,37,38 + 864 512 864 512 864 384 c 128,-1,39 + 864 256 864 256 821 256 c 0,40,-1 + 331 256 l 2,12,13 +EndSplineSet +EndChar + +StartChar: b +Encoding: 98 98 96 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9V\638 +S?bBd\,qa@fM$lI!'(49d1sJ4i3ERJ3YYqoH\qu4!8Sn#)En`A2-]*Pz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +725 1280 m 0,0,1 + 960 1280 960 1280 960 967 c 0,2,3 + 960 868 960 868 960 768 c 1,4,5 + 960 256 960 256 725 256 c 0,6,7 + 725 256 725 256 43 256 c 0,8,9 + 0 256 0 256 0 384 c 128,-1,10 + 0 512 0 512 43 512 c 0,11,-1 + 192 512 l 1,12,-1 + 192 1734 l 0,13,14 + 192 1792 192 1792 288 1792 c 128,-1,15 + 384 1792 384 1792 384 1734 c 0,16,-1 + 384 1280 l 1,17,-1 + 725 1280 l 0,0,1 +725 512 m 0,18,19 + 768 512 768 512 768 565 c 0,20,21 + 768 567 768 567 768 569 c 1,22,23 + 768 896 768 896 768 967 c 0,24,25 + 768 1024 768 1024 725 1024 c 1,26,27 + 725 1024 725 1024 384 1024 c 1,28,-1 + 384 512 l 1,29,30 + 555 512 555 512 725 512 c 0,18,19 +EndSplineSet +EndChar + +StartChar: c +Encoding: 99 99 97 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns2*9E?@_ +,E0`pCa`Bd8.o&:XqJeuBE^[*?n4L^j)kIF:0_Z:!.;!a%Z2pI[/^1,!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +96 1223 m 1,0,1 + 96 1536 96 1536 331 1536 c 1,2,3 + 331 1536 331 1536 821 1536 c 0,4,5 + 864 1536 864 1536 864 1408 c 128,-1,6 + 864 1280 864 1280 821 1280 c 0,7,-1 + 331 1280 l 1,8,9 + 288 1280 288 1280 288 1223 c 1,10,11 + 288 1223 288 1223 288 569 c 1,12,13 + 288 512 288 512 331 512 c 1,14,15 + 331 512 331 512 821 512 c 0,16,17 + 864 512 864 512 864 384 c 128,-1,18 + 864 256 864 256 821 256 c 0,19,-1 + 331 256 l 0,20,21 + 96 256 96 256 96 569 c 1,22,23 + 96 569 96 569 96 1223 c 1,0,1 +EndSplineSet +EndChar + +StartChar: d +Encoding: 100 100 98 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?K_r!ro=GQ8D_*$Z[Q1)J/( +;1Ket'OUqJ@abW^bQO(33aJOOEJ1L],)b'o0g"R2KXB25:z8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +235 256 m 0,0,1 + 0 256 0 256 0 512 c 0,2,3 + 0 512 0 512 0 967 c 1,4,5 + 0 1280 0 1280 235 1280 c 0,6,7 + 235 1280 235 1280 576 1280 c 1,8,-1 + 576 1735 l 0,9,10 + 576 1792 576 1792 672 1792 c 128,-1,11 + 768 1792 768 1792 768 1735 c 0,12,-1 + 768 512 l 1,13,-1 + 917 512 l 0,14,15 + 960 512 960 512 960 384 c 128,-1,16 + 960 256 960 256 917 256 c 0,17,18 + 917 256 917 256 235 256 c 0,0,1 +235 1024 m 1,19,20 + 191 1024 191 1024 191 967 c 1,21,22 + 192 569 192 569 192 569 c 0,23,24 + 192 512 192 512 235 512 c 0,25,26 + 235 512 235 512 576 512 c 0,27,28 + 576 512 576 512 576 1024 c 1,29,-1 + 235 1024 l 1,19,20 +EndSplineSet +EndChar + +StartChar: e +Encoding: 101 101 99 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +!skY(YQBmhaBF +EndImage2 +Fore +SplineSet +616 1024 m 0,0,1 + 672 1024 672 1024 672 1099 c 2,2,3 + 672 1099 672 1099 672 1205 c 1,4,5 + 672 1280 672 1280 616 1280 c 1,6,7 + 616 1280 616 1280 344 1280 c 0,8,9 + 288 1280 288 1280 288 1205 c 1,10,11 + 288 1205 288 1205 288 1081 c 0,12,13 + 288 1024 288 1024 331 1024 c 1,14,15 + 331 1024 331 1024 616 1024 c 0,0,1 +96 1205 m 0,16,17 + 96 1536 96 1536 344 1536 c 1,18,19 + 344 1536 344 1536 616 1536 c 1,20,21 + 864 1536 864 1536 864 1205 c 0,22,23 + 864 1205 864 1205 864 1099 c 0,24,25 + 864 768 864 768 616 768 c 0,26,-1 + 288 768 l 1,27,28 + 288 595 288 595 288 587 c 0,29,30 + 288 512 288 512 344 512 c 1,31,32 + 629 512 629 512 629 512 c 0,33,34 + 672 512 672 512 672 384 c 128,-1,35 + 672 256 672 256 629 256 c 0,36,-1 + 344 256 l 0,37,38 + 96 256 96 256 96 587 c 1,39,40 + 96 587 96 587 96 1205 c 0,16,17 +EndSplineSet +EndChar + +StartChar: f +Encoding: 102 102 100 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 122 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8D_*$Z[Q1)J/h +.f`.m$q")!&*pF_RK]>[bNg-Et!!nC@e,oG/"i0\g1=!!!!j78?7R +6=>BF +EndImage2 +Fore +SplineSet +672 1223 m 1,0,1 + 672 1280 672 1280 629 1280 c 1,2,3 + 629 1280 629 1280 331 1280 c 0,4,5 + 288 1280 288 1280 288 1223 c 1,6,7 + 288 1223 288 1223 288 825 c 1,8,9 + 288 768 288 768 331 768 c 1,10,11 + 629 768 629 768 629 768 c 0,12,13 + 672 768 672 768 672 825 c 1,14,15 + 672 825 672 825 672 1223 c 1,0,1 +331 512 m 2,16,17 + 96 512 96 512 96 825 c 0,18,19 + 96 825 96 825 96 1223 c 0,20,21 + 96 1536 96 1536 331 1536 c 0,22,23 + 480 1536 480 1536 629 1536 c 1,24,25 + 864 1536 864 1536 864 1223 c 0,26,27 + 864 612 864 612 864 313 c 0,28,29 + 864 0 864 0 629 0 c 1,30,31 + 629 0 629 0 288 0 c 1,32,-1 + 288 256 l 1,33,-1 + 629 256 l 1,34,35 + 672 256 672 256 672 313 c 1,36,37 + 672 413 672 413 672 512 c 1,38,-1 + 331 512 l 2,16,17 +EndSplineSet +EndChar + +StartChar: h +Encoding: 104 104 102 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8CJNffG9V\638 +S?bBd\,qa@fM$lI!'(49d1sJ4i3J*1!_,N5"9Oqn#t!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +629 1280 m 17,0,1 + 864 1280 864 1280 864 967 c 0,2,3 + 864 836 864 836 864 256 c 25,4,-1 + 672 256 l 1,5,-1 + 672 967 l 1,6,7 + 672 1024 672 1024 629 1024 c 1,8,9 + 629 1024 629 1024 288 1024 c 1,10,-1 + 288 256 l 25,11,-1 + 96 256 l 1,12,-1 + 96 1734 l 0,13,14 + 96 1792 96 1792 192 1792 c 128,-1,15 + 288 1792 288 1792 288 1734 c 8,16,-1 + 288 1280 l 1,17,-1 + 629 1280 l 17,0,1 +EndSplineSet +EndChar + +StartChar: i +Encoding: 105 105 103 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HNZ +$?-jc=$Y+8'Q]BrE"e>O:mbVo0]QRuZ3h?Y#F>NYEWDm9$5>J927EPc!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +384 1223 m 4,0,1 + 384 1280 384 1280 480 1280 c 129,-1,2 + 576 1280 576 1280 576 1223 c 1,3,-1 + 576 569 l 0,4,5 + 576 512 576 512 618 512 c 0,6,-1 + 768 512 l 1,7,-1 + 768 256 l 1,8,-1 + 192 256 l 1,9,-1 + 192 512 l 1,10,-1 + 340 512 l 0,11,12 + 384 512 384 512 384 569 c 4,13,14 + 384 569 384 569 384 1223 c 4,0,1 +384 1792 m 0,15,-1 + 576 1792 l 0,16,-1 + 576 1536 l 1,17,-1 + 384 1536 l 1,18,19 + 384 1536 384 1536 384 1792 c 0,15,-1 +EndSplineSet +EndChar + +StartChar: j +Encoding: 106 106 104 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8D_*$Z[Q1)J/( +;1QnF'EnV6^b?iYJ78RT"k\cg.0c7AEZ@U^2FdfKcm&u1G:MDDz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +576 1792 m 1,0,-1 + 768 1792 l 1,1,-1 + 768 1536 l 1,2,-1 + 576 1536 l 1,3,-1 + 576 1792 l 1,0,-1 +768 331 m 0,4,5 + 768 0 768 0 520 0 c 0,6,7 + 520 0 520 0 440 0 c 0,8,9 + 192 0 192 0 192 331 c 0,10,11 + 192 331 192 331 192 455 c 0,12,13 + 192 512 192 512 288 512 c 128,-1,14 + 384 512 384 512 384 455 c 0,15,-1 + 384 331 l 0,16,17 + 384 256 384 256 440 256 c 0,18,19 + 440 256 440 256 520 256 c 0,20,21 + 576 256 576 256 576 331 c 0,22,23 + 576 331 576 331 576 1223 c 0,24,25 + 576 1280 576 1280 670 1280 c 0,26,27 + 768 1280 768 1280 768 1223 c 0,28,29 + 768 1223 768 1223 768 331 c 0,4,5 +EndSplineSet +EndChar + +StartChar: k +Encoding: 107 107 105 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9V\638 +A6F#n-ji5&kVg9m@$:_]$s*GWM/GG5!Y>U+,"A4J?>flF>MTu&gl3mSz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +331 1024 m 17,0,1 + 331 1024 331 1024 715 1536 c 1,2,-1 + 864 1536 l 1,3,-1 + 864 1337 l 1,4,-1 + 533 896 l 1,5,6 + 533 896 533 896 864 455 c 1,7,-1 + 864 256 l 1,8,-1 + 715 256 l 1,9,-1 + 331 768 l 1,10,11 + 331 768 331 768 288 768 c 25,12,-1 + 288 256 l 25,13,-1 + 96 256 l 25,14,-1 + 96 1792 l 25,15,-1 + 288 1792 l 25,16,-1 + 288 1024 l 25,17,-1 + 331 1024 l 17,0,1 +EndSplineSet +EndChar + +StartChar: l +Encoding: 108 108 106 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 108 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1J'u#<#?K_r!ro=GQ8CJNffG9N3T>a +/&5d'=91=N0JP%+!'(Yp?o6)P&Bt8#n2V*]Yf@(bT*B[=z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 1792 m 24,0,-1 + 576 1792 l 24,1,-1 + 576 512 l 25,2,-1 + 768 512 l 25,3,-1 + 768 256 l 25,4,-1 + 192 256 l 25,5,-1 + 192 512 l 25,6,-1 + 384 512 l 25,7,-1 + 384 1536 l 25,8,-1 + 192 1536 l 25,9,10 + 192 1536 192 1536 192 1792 c 24,0,-1 +EndSplineSet +EndChar + +StartChar: m +Encoding: 109 109 107 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns22,9nE8 +#_N,9#'6F?fE@9f+A!E0T`A3qSP@`GkW7)dN.ehM!'R@m&B%c/r;Zft!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +340 1536 m 2,0,1 + 479 1536 479 1536 479 1280 c 1,2,3 + 479 1536 479 1536 618 1536 c 0,4,5 + 618 1536 618 1536 725 1536 c 0,6,7 + 960 1536 960 1536 960 1223 c 1,8,9 + 960 740 960 740 960 256 c 1,10,11 + 960 256 960 256 768 256 c 1,12,-1 + 768 1223 l 2,13,14 + 768 1280 768 1280 725 1280 c 1,15,16 + 725 1280 725 1280 618 1280 c 0,17,18 + 576 1280 576 1280 576 1223 c 0,19,20 + 576 1223 576 1223 576 256 c 1,21,-1 + 384 256 l 1,22,-1 + 384 1223 l 2,23,24 + 384 1280 384 1280 340 1280 c 0,25,26 + 340 1280 340 1280 235 1280 c 0,27,28 + 192 1280 192 1280 192 1223 c 2,29,-1 + 192 256 l 1,30,-1 + 0 256 l 25,31,-1 + 0 1536 l 1,32,-1 + 340 1536 l 2,0,1 +EndSplineSet +EndChar + +StartChar: n +Encoding: 110 110 108 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns2*Lh(%, +KW@I!&8hP?!ec[NK64pE^l:Th:p,<\BJ3\1!WY^j&I&QkSpLG;!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +629 1536 m 17,0,1 + 864 1536 864 1536 864 1223 c 1,2,3 + 864 683 864 683 864 256 c 25,4,-1 + 672 256 l 1,5,-1 + 672 1223 l 1,6,7 + 672 1280 672 1280 629 1280 c 1,8,9 + 629 1280 629 1280 288 1280 c 1,10,-1 + 288 256 l 25,11,-1 + 96 256 l 25,12,-1 + 96 1536 l 1,13,-1 + 629 1536 l 17,0,1 +EndSplineSet +EndChar + +StartChar: o +Encoding: 111 111 109 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 119 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +!skY(YQBmhapkS,:]Uqp-*kq^ScUEm.=rFq9EP8Yq@aDRRWI9b!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +672 1205 m 1,0,1 + 672 1280 672 1280 616 1280 c 1,2,3 + 616 1280 616 1280 344 1280 c 0,4,5 + 288 1280 288 1280 288 1205 c 1,6,7 + 288 1205 288 1205 288 587 c 1,8,9 + 288 512 288 512 344 512 c 1,10,11 + 344 512 344 512 616 512 c 0,12,13 + 672 512 672 512 672 587 c 1,14,15 + 672 587 672 587 672 1205 c 1,0,1 +96 1205 m 0,16,17 + 96 1536 96 1536 344 1536 c 1,18,19 + 344 1536 344 1536 616 1536 c 1,20,21 + 864 1536 864 1536 864 1205 c 0,22,23 + 864 730 864 730 864 587 c 0,24,25 + 864 256 864 256 616 256 c 1,26,27 + 616 256 616 256 344 256 c 1,28,29 + 96 256 96 256 96 587 c 0,30,31 + 96 659 96 659 96 1205 c 0,16,17 +EndSplineSet +EndChar + +StartChar: p +Encoding: 112 112 110 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns2*Lh(%, +KW@I!&8hP?!ec[NK64pE^l:ThJ?8g._/uDU!EXe(!AfP)'`_rY'+E&U*NK/?!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +616 768 m 1,0,1 + 672 768 672 768 672 843 c 1,2,3 + 672 843 672 843 672 1205 c 1,4,5 + 672 1280 672 1280 616 1280 c 1,6,7 + 616 1280 616 1280 288 1280 c 1,8,9 + 288 1024 288 1024 288 768 c 0,10,11 + 288 768 288 768 616 768 c 1,0,1 +616 1536 m 1,12,13 + 864 1536 864 1536 864 1205 c 0,14,15 + 864 858 864 858 864 843 c 0,16,17 + 864 512 864 512 616 512 c 1,18,19 + 616 512 616 512 288 512 c 1,20,-1 + 288 0 l 1,21,-1 + 96 0 l 1,22,-1 + 96 1536 l 1,23,-1 + 616 1536 l 1,12,13 +EndSplineSet +EndChar + +StartChar: q +Encoding: 113 113 111 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns2*Lh(%, +KW@I!O9m0=&k&(:koadG811\X0V'm9C][1/TUQ,cA6]lWK/u9:z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +248 1280 m 1,0,1 + 192 1280 192 1280 192 1205 c 1,2,3 + 192 1205 192 1205 192 843 c 1,4,5 + 192 768 192 768 248 768 c 1,6,7 + 248 768 248 768 576 768 c 1,8,-1 + 576 1280 l 1,9,-1 + 248 1280 l 1,0,1 +248 512 m 1,10,11 + 0 512 0 512 0 843 c 0,12,13 + 0 1023 0 1023 0 1205 c 0,14,15 + 0 1536 0 1536 248 1536 c 1,16,17 + 248 1536 248 1536 542 1536 c 0,18,-1 + 768 1536 l 1,19,-1 + 768 256 l 1,20,-1 + 917 256 l 0,21,22 + 960 256 960 256 960 128 c 128,-1,23 + 960 0 960 0 917 0 c 0,24,-1 + 576 0 l 1,25,-1 + 576 512 l 1,26,-1 + 248 512 l 1,10,11 +EndSplineSet +EndChar + +StartChar: r +Encoding: 114 114 112 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +Qij'kCm[[-(]u%7br3'HfH`bOiU!pq/^h#XL1]XA\%2#Am_)hVs!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +288 1280 m 1,0,1 + 288 1536 288 1536 522 1536 c 1,2,3 + 522 1536 522 1536 864 1536 c 1,4,-1 + 864 1280 l 1,5,-1 + 522 1280 l 1,6,7 + 288 1280 288 1280 288 1024 c 1,8,9 + 288 1024 288 1024 288 256 c 1,10,-1 + 96 256 l 25,11,-1 + 96 1536 l 25,12,-1 + 288 1536 l 25,13,-1 + 288 1280 l 1,0,1 +EndSplineSet +EndChar + +StartChar: s +Encoding: 115 115 113 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 122 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?K_r!ro=GQ8Bu3Ns2*Lh(%, +6rA_U-s-L@(0M2O2:r7t,fg[AP<]K6D?),;.7?&pWuE`,i3FH#&-14%((g]?(5Mqj!!#SZ:.26O +@"J@Y +EndImage2 +Fore +SplineSet +864 693 m 0,0,1 + 864 640 864 640 864 587 c 0,2,3 + 864 256 864 256 616 256 c 0,4,-1 + 140 256 l 0,5,6 + 96 256 96 256 96 384 c 128,-1,7 + 96 512 96 512 140 512 c 0,8,-1 + 616 512 l 0,9,10 + 672 512 672 512 672 587 c 0,11,12 + 672 678 672 678 672 693 c 0,13,14 + 672 768 672 768 616 768 c 0,15,-1 + 344 768 l 0,16,17 + 96 768 96 768 96 1099 c 0,18,19 + 96 1099 96 1099 96 1205 c 0,20,21 + 96 1536 96 1536 344 1536 c 1,22,23 + 344 1536 344 1536 821 1536 c 0,24,25 + 864 1536 864 1536 864 1408 c 128,-1,26 + 864 1280 864 1280 821 1280 c 1,27,-1 + 344 1280 l 0,28,29 + 288 1280 288 1280 288 1205 c 0,30,31 + 288 1114 288 1114 288 1099 c 0,32,33 + 288 1024 288 1024 344 1024 c 0,34,-1 + 616 1024 l 0,35,36 + 864 1024 864 1024 864 693 c 0,0,1 +EndSplineSet +EndChar + +StartChar: t +Encoding: 116 116 114 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CNNffG9`^HN: +$=K#N)Hd5G!R);rNM->T!1aRC"1eVo%p&`d*iBrbWj0)8!277@%#@LO^An66!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +480 587 m 1,0,1 + 480 512 480 512 536 512 c 0,2,3 + 536 512 536 512 672 512 c 1,4,5 + 672 512 672 512 672 256 c 1,6,-1 + 536 256 l 1,7,8 + 288 256 288 256 288 587 c 1,9,10 + 288 934 288 934 288 1280 c 1,11,-1 + 140 1280 l 0,12,13 + 96 1280 96 1280 96 1408 c 128,-1,14 + 96 1536 96 1536 140 1536 c 0,15,-1 + 288 1536 l 1,16,-1 + 288 1735 l 0,17,18 + 288 1792 288 1792 384 1792 c 128,-1,19 + 480 1792 480 1792 480 1735 c 0,20,-1 + 480 1536 l 1,21,-1 + 629 1536 l 0,22,23 + 672 1536 672 1536 672 1408 c 128,-1,24 + 672 1280 672 1280 629 1280 c 0,25,-1 + 480 1280 l 1,26,-1 + 480 587 l 1,0,1 +EndSplineSet +EndChar + +StartChar: u +Encoding: 117 117 115 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +>TGR=,Y4F3E:$aE"AN8)B``P_h/8Tg?j/5Q0L94f!#\N='5qJ>+ohTC!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +288 587 m 1,0,1 + 288 512 288 512 344 512 c 1,2,3 + 344 512 344 512 672 512 c 1,4,-1 + 672 1479 l 0,5,6 + 672 1536 672 1536 768 1536 c 128,-1,7 + 864 1536 864 1536 864 1479 c 0,8,-1 + 864 256 l 1,9,-1 + 344 256 l 1,10,11 + 96 256 96 256 96 587 c 1,12,13 + 96 1403 96 1403 96 1479 c 0,14,15 + 96 1536 96 1536 192 1536 c 128,-1,16 + 288 1536 288 1536 288 1479 c 0,17,-1 + 288 587 l 1,0,1 +EndSplineSet +EndChar + +StartChar: v +Encoding: 118 118 116 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns22,9nFj +)K\/O'0oSktT]l#NXfm`3:CAe_QB1QT#rk1AhRHz8OZBB +Y!QNJ +EndImage2 +Fore +SplineSet +479 714 m 129,-1,1 + 479 714 479 714 136 256 c 1,2,3 + 0 256 0 256 0 437 c 1,4,5 + 343 896 343 896 343 896 c 129,-1,6 + 343 896 343 896 0 1355 c 1,7,8 + 0 1536 0 1536 136 1536 c 1,9,10 + 480 1077 480 1077 480 1077 c 129,-1,11 + 480 1077 480 1077 824 1536 c 1,12,13 + 960 1536 960 1536 960 1355 c 1,14,15 + 616 897 616 897 616 897 c 129,-1,16 + 616 897 616 897 960 437 c 1,17,18 + 960 256 960 256 824 256 c 1,19,0 + 479 714 479 714 479 714 c 129,-1,1 +EndSplineSet +EndChar + +StartChar: y +Encoding: 121 121 119 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +>TGR=,Y4F3E:$aE/0H[/440%BWJ+OW;M<:^?kYf*@4%Wt!W]..&.jd;TcO16!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +288 843 m 1,0,1 + 288 768 288 768 344 768 c 1,2,3 + 344 768 344 768 672 768 c 1,4,-1 + 672 1479 l 0,5,6 + 672 1536 672 1536 768 1536 c 129,-1,7 + 864 1536 864 1536 864 1479 c 1,8,-1 + 864 331 l 0,9,10 + 864 0 864 0 616 0 c 1,11,-1 + 331 0 l 0,12,13 + 288 0 288 0 288 128 c 128,-1,14 + 288 256 288 256 331 256 c 0,15,-1 + 616 256 l 1,16,17 + 672 256 672 256 672 331 c 1,18,19 + 672 331 672 331 672 512 c 0,20,-1 + 344 512 l 1,21,22 + 96 512 96 512 96 843 c 1,23,24 + 96 843 96 843 96 1479 c 0,25,26 + 96 1536 96 1536 192 1536 c 128,-1,27 + 288 1536 288 1536 288 1479 c 0,28,-1 + 288 843 l 1,0,1 +EndSplineSet +EndChar + +StartChar: z +Encoding: 122 122 120 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 111 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8Bu3Ns2BOMigR +fh`Gp%O32C"#:s/"Pa?#P<7,XDc.Es"r<3WK-qdMi2GrhD[X!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +904 1280 m 0,0,1 + 904 1280 904 1280 328 512 c 1,2,3 + 328 512 328 512 917 512 c 0,4,5 + 960 512 960 512 960 384 c 128,-1,6 + 960 256 960 256 917 256 c 0,7,8 + 918 256 918 256 44 256 c 0,9,10 + 0 256 0 256 0 384 c 128,-1,11 + 0 512 0 512 44 512 c 0,12,-1 + 56 512 l 1,13,14 + 56 512 56 512 632 1280 c 1,15,16 + 632 1280 632 1280 44 1280 c 0,17,18 + 0 1280 0 1280 0 1408 c 128,-1,19 + 0 1536 0 1536 44 1536 c 0,20,21 + 44 1536 44 1536 904 1536 c 0,22,23 + 960 1536 960 1536 960 1408 c 128,-1,24 + 960 1280 960 1280 904 1280 c 0,0,1 +EndSplineSet +EndChar + +StartChar: braceleft +Encoding: 123 123 121 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8D_*$Z[Q1)J/h +.f`.M1CUDd6Ru+9X8nT)O;b>)OO;_ILF[nDL6[A&!LG58&4@'?qd>sHz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +384 1461 m 1,0,1 + 384 1792 384 1792 632 1792 c 1,2,3 + 632 1792 632 1792 768 1792 c 1,4,-1 + 768 1536 l 1,5,-1 + 632 1536 l 1,6,7 + 576 1536 576 1536 576 1461 c 1,8,9 + 576 1280 576 1280 576 1099 c 0,10,11 + 576 896 576 896 500 896 c 1,12,13 + 576 896 576 896 576 693 c 0,14,15 + 576 693 576 693 576 331 c 1,16,17 + 576 256 576 256 632 256 c 1,18,19 + 768 256 768 256 768 256 c 1,20,-1 + 768 0 l 1,21,-1 + 632 0 l 0,22,23 + 384 0 384 0 384 331 c 1,24,25 + 384 331 384 331 384 693 c 1,26,27 + 384 768 384 768 328 768 c 0,28,29 + 328 768 328 768 236 768 c 0,30,31 + 192 768 192 768 192 896 c 128,-1,32 + 192 1024 192 1024 236 1024 c 0,33,34 + 236 1024 236 1024 328 1024 c 1,35,36 + 384 1024 384 1024 384 1099 c 1,37,38 + 384 1280 384 1280 384 1461 c 1,0,1 +EndSplineSet +EndChar + +StartChar: bar +Encoding: 124 124 122 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 96 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-V6]l<#?K_r!ro=GQ8CNNffG9`^HNZ +$;a-Q35d>_jV532ZuZhP5\Z!+&6obWr%P+Tz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +576 1461 m 1,0,1 + 576 1280 576 1280 576 1099 c 1,2,3 + 576 1024 576 1024 632 1024 c 1,4,5 + 632 1024 632 1024 725 1024 c 1,6,7 + 768 1024 768 1024 768 896 c 128,-1,8 + 768 768 768 768 725 768 c 1,9,10 + 725 768 725 768 632 768 c 1,11,12 + 576 768 576 768 576 693 c 1,13,14 + 576 512 576 512 576 331 c 1,15,16 + 576 0 576 0 328 0 c 0,17,18 + 328 0 328 0 192 0 c 1,19,-1 + 192 256 l 1,20,21 + 328 256 328 256 328 256 c 1,22,23 + 384 256 384 256 384 331 c 1,24,25 + 384 331 384 331 384 693 c 0,26,27 + 384 896 384 896 460 896 c 1,28,29 + 384 896 384 896 384 1099 c 0,30,31 + 384 1099 384 1099 384 1461 c 1,32,33 + 384 1536 384 1536 328 1536 c 1,34,35 + 328 1536 328 1536 192 1536 c 1,36,-1 + 192 1792 l 1,37,-1 + 328 1792 l 1,38,39 + 576 1792 576 1792 576 1461 c 1,0,1 +EndSplineSet +EndChar + +StartChar: asciitilde +Encoding: 126 126 124 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 105 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8Bu3Ns4^$5aWu +;%.":nW3q%SHMiNf:>V!3`+$*EX4]=!2nui$0`_sf`2!P!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +960 1099 m 0,0,1 + 960 768 960 768 712 768 c 24,2,-1 + 248 768 l 0,3,4 + 192 768 192 768 192 693 c 24,5,-1 + 192 512 l 25,6,-1 + 0 512 l 25,7,8 + 0 514 0 514 0 693 c 0,9,10 + 0 1024 0 1024 248 1024 c 24,11,-1 + 712 1024 l 0,12,13 + 768 1024 768 1024 768 1099 c 24,14,-1 + 768 1280 l 25,15,-1 + 960 1280 l 25,16,17 + 960 1280 960 1280 960 1099 c 0,0,1 +EndSplineSet +EndChar + +StartChar: uni007F +Encoding: 127 127 125 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 91 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd69$d]%-ia6ZR0X$I$,$09!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +0 1280 m 29,0,-1 + 960 1280 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 1280 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: uni0080 +Encoding: 128 128 126 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 125 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$Na!+r&.AZ[o_qq3)XZ$a +jG,(OU,Gt71,;FPS34p%"?8b+Wp>g8X:*+q!>pf44u^"9-V`4j,f;.Nmj\#SrL?s7HN4$G!(fUS +7'8jaJcGcN +EndImage2 +Fore +SplineSet +712 1792 m 0,0,1 + 960 1792 960 1792 960 1461 c 0,2,3 + 960 1461 960 1461 960 1280 c 1,4,5 + 960 1280 960 1280 768 1280 c 0,6,-1 + 768 1461 l 0,7,8 + 768 1536 768 1536 712 1536 c 0,9,-1 + 248 1536 l 0,10,11 + 192 1536 192 1536 192 1461 c 0,12,13 + 192 1461 192 1461 192 843 c 0,14,15 + 192 768 192 768 248 768 c 0,16,-1 + 712 768 l 2,17,18 + 768 768 768 768 768 843 c 2,19,-1 + 768 1024 l 0,20,21 + 768 1024 768 1024 960 1024 c 1,22,23 + 960 1024 960 1024 960 843 c 0,24,25 + 960 512 960 512 712 512 c 0,26,-1 + 576 512 l 25,27,-1 + 576 331 l 0,28,29 + 576 0 576 0 328 0 c 0,30,31 + 328 0 328 0 0 0 c 1,32,-1 + 0 256 l 1,33,-1 + 328 256 l 0,34,35 + 384 256 384 256 384 331 c 0,36,37 + 384 331 384 331 384 512 c 1,38,39 + 384 512 384 512 248 512 c 0,40,41 + 0 512 0 512 0 843 c 0,42,43 + 0 843 0 843 0 1461 c 0,44,45 + 0 1792 0 1792 248 1792 c 0,46,47 + 248 1792 248 1792 712 1792 c 0,0,1 +EndSplineSet +EndChar + +StartChar: uni0081 +Encoding: 129 129 127 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9Xot.% +QD<(8YSD-KYqRS-^]H8+jAU0P_e]DTJ$fY!QI[jFz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +288 1280 m 25,0,-1 + 288 331 l 0,1,2 + 288 256 288 256 344 256 c 24,3,-1 + 672 256 l 24,4,-1 + 672 1280 l 25,5,-1 + 864 1280 l 25,6,-1 + 864 0 l 25,7,-1 + 344 0 l 0,8,9 + 96 0 96 0 96 331 c 24,10,11 + 96 331 96 331 96 1280 c 25,12,-1 + 288 1280 l 25,0,-1 +672 1792 m 24,13,-1 + 864 1792 l 25,14,-1 + 864 1536 l 24,15,-1 + 672 1536 l 24,16,17 + 672 1536 672 1536 672 1792 c 24,13,-1 +96 1792 m 25,18,-1 + 288 1792 l 25,19,-1 + 288 1536 l 24,20,-1 + 96 1536 l 24,21,22 + 96 1536 96 1536 96 1792 c 25,18,-1 +EndSplineSet +EndChar + +StartChar: uni0082 +Encoding: 130 130 128 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8D_*$Z[Q!sg+R +()R9%J^#kW'4;_d1fscP2ol-7BF +EndImage2 +Fore +SplineSet +344 512 m 0,0,1 + 288 512 288 512 288 437 c 0,2,3 + 288 331 288 331 288 331 c 0,4,5 + 288 256 288 256 344 256 c 0,6,7 + 344 256 344 256 480 256 c 1,8,9 + 480 256 480 256 480 512 c 1,10,11 + 480 512 480 512 344 512 c 0,0,1 +672 1461 m 1,12,13 + 672 1536 672 1536 616 1536 c 24,14,15 + 616 1536 616 1536 344 1536 c 0,16,17 + 288 1536 288 1536 288 1461 c 1,18,19 + 288 1461 288 1461 288 1280 c 1,20,21 + 288 1280 288 1280 616 1280 c 0,22,23 + 672 1280 672 1280 672 1355 c 0,24,25 + 672 1355 672 1355 672 1461 c 1,12,13 +616 1792 m 0,26,27 + 864 1792 864 1792 864 1461 c 24,28,29 + 864 1461 864 1461 864 1355 c 0,30,31 + 864 1024 864 1024 672 1024 c 0,32,33 + 672 640 672 640 672 331 c 0,34,35 + 672 256 672 256 728 256 c 24,36,-1 + 821 256 l 0,37,38 + 864 256 864 256 864 127 c 0,39,40 + 864 0 864 0 821 0 c 24,41,42 + 821 0 821 0 232 0 c 0,43,44 + 96 0 96 0 96 181 c 24,45,46 + 96 181 96 181 96 587 c 0,47,48 + 96 768 96 768 232 768 c 24,49,-1 + 480 768 l 25,50,-1 + 480 1024 l 24,51,-1 + 96 1024 l 24,52,53 + 96 1408 96 1408 96 1461 c 0,54,55 + 96 1792 96 1792 344 1792 c 24,56,57 + 344 1792 344 1792 616 1792 c 0,26,27 +EndSplineSet +EndChar + +StartChar: uni0084 +Encoding: 132 132 130 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9X9;!; +X(N\g!Xl:?+?$fj?n4KokRoRb0MI!g^hBqY+:^";i!NjUJC-%a!-E&l&P`+b4obQ_!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +344 512 m 0,0,1 + 288 512 288 512 288 437 c 24,2,3 + 288 363 288 363 288 331 c 0,4,5 + 288 256 288 256 344 256 c 24,6,-1 + 480 256 l 25,7,-1 + 480 512 l 17,8,9 + 480 512 480 512 344 512 c 0,0,1 +96 1280 m 24,10,11 + 96 1280 96 1280 480 1280 c 0,12,13 + 672 1280 672 1280 672 1024 c 24,14,-1 + 672 331 l 0,15,16 + 672 256 672 256 728 256 c 24,17,-1 + 821 256 l 0,18,19 + 864 256 864 256 864 127 c 0,20,21 + 864 0 864 0 821 0 c 24,22,23 + 821 0 821 0 288 0 c 0,24,25 + 96 0 96 0 96 256 c 24,26,27 + 96 256 96 256 96 512 c 128,-1,28 + 96 768 96 768 288 768 c 24,29,-1 + 480 768 l 25,30,31 + 480 898 480 898 480 949 c 0,32,33 + 480 1024 480 1024 424 1024 c 24,34,-1 + 96 1024 l 24,35,36 + 96 1152 96 1152 96 1280 c 24,10,11 +480 1792 m 25,37,-1 + 672 1792 l 25,38,-1 + 672 1536 l 25,39,-1 + 480 1536 l 17,40,41 + 480 1536 480 1536 480 1792 c 25,37,-1 +96 1792 m 9,42,-1 + 288 1792 l 25,43,-1 + 288 1536 l 25,44,-1 + 96 1536 l 17,45,46 + 96 1536 96 1536 96 1792 c 9,42,-1 +EndSplineSet +EndChar + +StartChar: uni0085 +Encoding: 133 133 131 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 123 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6:jR2<#?L$Nf+5E+:&'Ro`)[2:,ig- +#3'.E838Xl;KrLigpH%'bhedP@F?Zl!%HH+?63E+!A_Jaqaj=VkhH]N],(kp9",<2!!!!j78?7R +6=>BF +EndImage2 +Fore +SplineSet +440 512 m 0,0,1 + 384 512 384 512 384 437 c 0,2,3 + 384 346 384 346 384 331 c 0,4,5 + 384 256 384 256 440 256 c 0,6,7 + 440 256 440 256 576 256 c 24,8,9 + 576 256 576 256 576 512 c 24,10,11 + 576 512 576 512 440 512 c 0,0,1 +0 1792 m 25,12,13 + 2 1792 2 1792 328 1792 c 0,14,15 + 576 1792 576 1792 576 1461 c 24,16,-1 + 576 1280 l 0,17,-1 + 632 1280 l 0,18,19 + 768 1280 768 1280 768 1099 c 1,20,-1 + 768 256 l 0,21,-1 + 917 256 l 0,22,23 + 960 256 960 256 960 127 c 17,24,25 + 960 0 960 0 917 0 c 0,26,27 + 622 0 622 0 328 0 c 0,28,29 + 192 0 192 0 192 181 c 1,30,-1 + 192 587 l 1,31,32 + 192 768 192 768 328 768 c 0,33,-1 + 576 768 l 1,34,-1 + 576 949 l 17,35,36 + 576 1024 576 1024 520 1024 c 24,37,-1 + 192 1024 l 24,38,39 + 192 1024 192 1024 192 1280 c 24,40,-1 + 384 1280 l 24,41,42 + 384 1282 384 1282 384 1461 c 0,43,44 + 384 1536 384 1536 328 1536 c 24,45,-1 + 0 1536 l 24,46,47 + 0 1536 0 1536 0 1792 c 25,12,13 +EndSplineSet +EndChar + +StartChar: uni0086 +Encoding: 134 134 132 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 124 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6V0[3<#?L$N_'QX+:J@3q#<"J$)@]t +pZ@+3S;se'nECd)3;rME"cVsJC-(:i/RpHTM'mT!&S7)$go"b$NrrXke_RMi+2)FlSN("#8$-k"jq*#S+AB?^DV!!#SZ:.26O +@"J@Y +EndImage2 +Fore +SplineSet +616 1280 m 0,0,1 + 672 1280 672 1280 672 1355 c 24,2,3 + 672 1446 672 1446 672 1461 c 0,4,5 + 672 1536 672 1536 616 1536 c 24,6,-1 + 344 1536 l 0,7,8 + 288 1536 288 1536 288 1461 c 24,9,10 + 288 1370 288 1370 288 1355 c 0,11,12 + 288 1280 288 1280 344 1280 c 24,13,14 + 344 1280 344 1280 616 1280 c 0,0,1 +808 1154 m 1,15,16 + 864 1105 864 1105 864 967 c 0,17,18 + 864 967 864 967 864 843 c 0,19,20 + 864 512 864 512 616 512 c 0,21,22 + 616 512 616 512 288 512 c 1,23,24 + 288 384 288 384 288 331 c 0,25,26 + 288 256 288 256 344 256 c 1,27,28 + 486 256 486 256 629 256 c 0,29,30 + 672 256 672 256 672 127 c 0,31,32 + 672 0 672 0 629 0 c 0,33,34 + 487 0 487 0 344 0 c 0,35,36 + 96 0 96 0 96 331 c 1,37,38 + 96 649 96 649 96 967 c 0,39,40 + 96 1102 96 1102 151 1154 c 1,41,42 + 96 1207 96 1207 96 1355 c 0,43,44 + 96 1458 96 1458 96 1461 c 0,45,46 + 96 1792 96 1792 344 1792 c 24,47,48 + 616 1792 616 1792 616 1792 c 0,49,50 + 864 1792 864 1792 864 1461 c 24,51,52 + 864 1461 864 1461 864 1355 c 0,53,54 + 864 1211 864 1211 808 1154 c 1,15,16 +616 768 m 0,55,56 + 672 768 672 768 672 843 c 2,57,58 + 672 843 672 843 672 949 c 1,59,60 + 672 1024 672 1024 616 1024 c 1,61,62 + 344 1024 344 1024 344 1024 c 0,63,64 + 288 1024 288 1024 288 949 c 1,65,66 + 288 858 288 858 288 843 c 0,67,68 + 288 768 288 768 344 768 c 1,69,70 + 344 768 344 768 616 768 c 0,55,56 +EndSplineSet +EndChar + +StartChar: uni0089 +Encoding: 137 137 135 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9Xot.% +Q6XNTQmq716/li65Y_>gF@@`'/mNJ1JFs)6ai0UTp3g!;V?`)AUn4]`8$4!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +672 1792 m 25,0,-1 + 864 1792 l 25,1,-1 + 864 1536 l 24,2,-1 + 672 1536 l 24,3,4 + 672 1536 672 1536 672 1792 c 25,0,-1 +96 1792 m 24,5,-1 + 288 1792 l 24,6,-1 + 288 1536 l 24,7,-1 + 96 1536 l 24,8,9 + 96 1536 96 1536 96 1792 c 24,5,-1 +616 768 m 0,10,11 + 672 768 672 768 672 843 c 2,12,13 + 672 843 672 843 672 949 c 1,14,15 + 672 1024 672 1024 616 1024 c 1,16,17 + 344 1024 344 1024 344 1024 c 0,18,19 + 288 1024 288 1024 288 949 c 1,20,21 + 288 858 288 858 288 843 c 0,22,23 + 288 768 288 768 344 768 c 1,24,25 + 344 768 344 768 616 768 c 0,10,11 +96 967 m 0,26,27 + 96 1280 96 1280 331 1280 c 1,28,29 + 331 1280 331 1280 629 1280 c 1,30,31 + 864 1280 864 1280 864 967 c 0,32,33 + 864 825 864 825 864 825 c 0,34,35 + 864 512 864 512 629 512 c 24,36,-1 + 288 512 l 1,37,38 + 288 384 288 384 288 331 c 0,39,40 + 288 256 288 256 344 256 c 1,41,42 + 344 256 344 256 629 256 c 0,43,44 + 672 256 672 256 672 127 c 0,45,46 + 672 0 672 0 629 0 c 0,47,-1 + 331 0 l 0,48,49 + 96 0 96 0 96 313 c 1,50,51 + 96 960 96 960 96 967 c 0,26,27 +EndSplineSet +EndChar + +StartChar: uni008A +Encoding: 138 138 136 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8sb%]fYs3[Tpk +#W"5fe7&J+A0GcH^^<=>\4g@_R=J!j8.Md&V^"L-@#i0;$398b)@k'giG8Jo!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +725 768 m 0,0,1 + 768 768 768 768 768 825 c 2,2,3 + 768 825 768 825 768 949 c 1,4,5 + 768 1024 768 1024 712 1024 c 1,6,7 + 576 1024 576 1024 440 1024 c 0,8,9 + 384 1024 384 1024 384 949 c 1,10,11 + 384 858 384 858 384 843 c 0,12,13 + 384 768 384 768 440 768 c 1,14,15 + 583 768 583 768 725 768 c 0,0,1 +712 1280 m 1,16,17 + 960 1280 960 1280 960 949 c 0,18,19 + 960 949 960 949 960 825 c 0,20,21 + 960 512 960 512 725 512 c 24,22,-1 + 384 512 l 1,23,24 + 384 384 384 384 384 331 c 0,25,26 + 384 256 384 256 440 256 c 1,27,28 + 440 256 440 256 725 256 c 0,29,30 + 768 256 768 256 768 127 c 0,31,32 + 768 0 768 0 725 0 c 0,33,-1 + 440 0 l 0,34,35 + 192 0 192 0 192 331 c 1,36,37 + 192 640 192 640 192 949 c 0,38,39 + 192 1280 192 1280 384 1280 c 1,40,41 + 384 1280 384 1280 384 1461 c 0,42,43 + 384 1536 384 1536 328 1536 c 24,44,-1 + 0 1536 l 24,45,46 + 0 1536 0 1536 0 1792 c 25,47,48 + 328 1792 328 1792 328 1792 c 0,49,50 + 576 1792 576 1792 576 1461 c 24,51,-1 + 576 1280 l 0,52,-1 + 712 1280 l 1,16,17 +EndSplineSet +EndChar + +StartChar: uni008B +Encoding: 139 139 137 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +Qij+G2),_\"ZG0ZPDF8^ZCU2qJrTs6W4`HPT/+OBz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +384 1024 m 24,0,-1 + 576 1024 l 24,1,-1 + 576 256 l 24,2,-1 + 768 256 l 24,3,-1 + 768 0 l 25,4,-1 + 192 0 l 25,5,-1 + 192 256 l 24,6,-1 + 384 256 l 24,7,-1 + 384 1024 l 24,0,-1 +576 1536 m 24,8,-1 + 768 1536 l 24,9,-1 + 768 1280 l 24,10,-1 + 576 1280 l 24,11,12 + 576 1280 576 1280 576 1536 c 24,8,-1 +192 1536 m 24,13,-1 + 384 1536 l 24,14,-1 + 384 1280 l 24,15,-1 + 192 1280 l 24,16,17 + 192 1280 192 1280 192 1536 c 24,13,-1 +EndSplineSet +EndChar + +StartChar: uni008C +Encoding: 140 140 138 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CNNffG9`^HN: +$:'asK=[=RMQ[l)Y@#0!!!!j +78?7R6=>BF +EndImage2 +Fore +SplineSet +768 1792 m 25,0,-1 + 960 1792 l 25,1,-1 + 960 1536 l 24,2,-1 + 768 1536 l 24,3,4 + 768 1536 768 1536 768 1792 c 25,0,-1 +0 1792 m 25,5,-1 + 192 1792 l 25,6,-1 + 192 1536 l 24,7,-1 + 0 1536 l 24,8,9 + 0 1536 0 1536 0 1792 c 25,5,-1 +480 1227 m 1,10,11 + 480 1227 480 1227 192 843 c 1,12,-1 + 192 768 l 25,13,-1 + 768 768 l 25,14,-1 + 768 843 l 1,15,-1 + 480 1227 l 1,10,11 +0 0 m 25,16,-1 + 0 949 l 25,17,-1 + 440 1536 l 24,18,-1 + 520 1536 l 24,19,-1 + 960 949 l 25,20,-1 + 960 0 l 25,21,-1 + 768 0 l 25,22,-1 + 768 512 l 24,23,-1 + 192 512 l 24,24,-1 + 192 0 l 25,25,-1 + 0 0 l 25,16,-1 +EndSplineSet +EndChar + +StartChar: uni008F +Encoding: 143 143 141 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 126 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W77fm5<#?L$N_p8d+:(sR)$@mKYCcfT!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 1280 m 24,0,-1 + 384 1280 l 24,1,-1 + 384 1461 l 0,2,3 + 384 1792 384 1792 632 1792 c 24,4,-1 + 960 1792 l 25,5,-1 + 960 1536 l 24,6,-1 + 632 1536 l 0,7,8 + 576 1536 576 1536 576 1461 c 24,9,10 + 576 1461 576 1461 576 1280 c 24,11,-1 + 960 1280 l 24,12,-1 + 960 1024 l 24,13,-1 + 192 1024 l 24,14,-1 + 192 768 l 25,15,-1 + 768 768 l 25,16,-1 + 768 512 l 24,17,-1 + 192 512 l 24,18,-1 + 192 256 l 24,19,-1 + 960 256 l 24,20,-1 + 960 0 l 25,21,-1 + 0 0 l 25,22,23 + 0 0 0 0 0 1280 c 24,0,-1 +EndSplineSet +EndChar + +StartChar: uni0091 +Encoding: 145 145 143 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8Bu3Ns2BOMigR +fha",#:9GGO\I-1B-aIG?;[Ai-!n.V-JPH:I>Gib3E2&,1z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 587 m 0,0,1 + 192 512 192 512 248 512 c 24,2,-1 + 384 512 l 24,3,-1 + 384 768 l 25,4,-1 + 248 768 l 0,5,6 + 192 768 192 768 192 693 c 24,7,8 + 192 685 192 685 192 587 c 0,0,1 +576 1280 m 24,9,-1 + 576 1024 l 24,10,-1 + 712 1024 l 0,11,12 + 768 1024 768 1024 768 1099 c 24,13,14 + 768 1190 768 1190 768 1205 c 0,15,16 + 768 1280 768 1280 712 1280 c 24,17,18 + 712 1280 712 1280 576 1280 c 24,9,-1 +0 1536 m 24,19,-1 + 824 1536 l 0,20,21 + 960 1536 960 1536 960 1355 c 24,22,23 + 960 1062 960 1062 960 949 c 0,24,25 + 960 768 960 768 824 768 c 24,26,-1 + 576 768 l 25,27,-1 + 576 512 l 24,28,-1 + 960 512 l 24,29,-1 + 960 256 l 24,30,-1 + 136 256 l 0,31,32 + 0 256 0 256 0 437 c 24,33,34 + 0 747 0 747 0 843 c 0,35,36 + 0 1024 0 1024 136 1024 c 24,37,-1 + 384 1024 l 24,38,-1 + 384 1280 l 24,39,-1 + 0 1280 l 24,40,41 + 0 1280 0 1280 0 1536 c 24,19,-1 +EndSplineSet +EndChar + +StartChar: uni0092 +Encoding: 146 146 144 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NmS=:+:&%fs8V6p2qg%3 +=,mrq3;]4%"#(qEOHKoBKBe+>8GCfabt3P>g8=[l+]'g6T\H[Op1=mP5H,2#z8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +192 1024 m 24,0,-1 + 384 1024 l 24,1,2 + 384 1024 384 1024 384 1461 c 0,3,4 + 384 1536 384 1536 328 1536 c 24,5,6 + 328 1536 328 1536 248 1536 c 0,7,8 + 192 1536 192 1536 192 1461 c 24,9,10 + 192 1461 192 1461 192 1024 c 24,0,-1 +0 1461 m 0,11,12 + 0 1792 0 1792 248 1792 c 24,13,14 + 248 1792 248 1792 328 1792 c 0,15,16 + 576 1792 576 1792 576 1461 c 24,17,-1 + 576 1280 l 24,18,-1 + 960 1280 l 24,19,-1 + 960 1024 l 24,20,-1 + 576 1024 l 24,21,-1 + 576 768 l 25,22,-1 + 768 768 l 25,23,-1 + 768 512 l 24,24,-1 + 576 512 l 24,25,-1 + 576 256 l 24,26,-1 + 960 256 l 24,27,-1 + 960 0 l 25,28,-1 + 384 0 l 24,29,-1 + 384 768 l 25,30,-1 + 192 768 l 25,31,-1 + 192 0 l 25,32,-1 + 0 0 l 25,33,34 + 0 896 0 896 0 1461 c 0,11,12 +EndSplineSet +EndChar + +StartChar: uni0093 +Encoding: 147 147 145 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CNNffHd!JJi$ +=91qoA.T$A.q/PD5aF[EOe<#"2k\n7itJd$X8qAmQnDnf!,J_Z&,&Qt?N:'+!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +248 1024 m 0,0,1 + 192 1024 192 1024 192 949 c 24,2,3 + 192 730 192 730 192 587 c 0,4,5 + 192 512 192 512 248 512 c 24,6,-1 + 520 512 l 0,7,8 + 576 512 576 512 576 587 c 24,9,10 + 576 806 576 806 576 949 c 0,11,12 + 576 1024 576 1024 520 1024 c 24,13,14 + 520 1024 520 1024 248 1024 c 0,0,1 +248 1536 m 0,15,16 + 192 1536 192 1536 192 1461 c 24,17,18 + 192 1370 192 1370 192 1355 c 0,19,20 + 192 1280 192 1280 248 1280 c 24,21,-1 + 520 1280 l 0,22,23 + 576 1280 576 1280 576 1355 c 24,24,25 + 576 1446 576 1446 576 1461 c 0,26,27 + 576 1536 576 1536 520 1536 c 24,28,29 + 520 1536 520 1536 248 1536 c 0,15,16 +711 1152 m 1,30,31 + 768 1106 768 1106 768 949 c 0,32,33 + 768 616 768 616 768 587 c 0,34,35 + 768 256 768 256 520 256 c 24,36,37 + 248 256 248 256 248 256 c 0,38,39 + 0 256 0 256 0 587 c 24,40,41 + 0 846 0 846 0 949 c 0,42,43 + 0 1100 0 1100 56 1151 c 1,44,45 + 0 1196 0 1196 0 1355 c 0,46,47 + 0 1437 0 1437 0 1461 c 0,48,49 + 0 1792 0 1792 248 1792 c 24,50,51 + 517 1792 517 1792 520 1792 c 0,52,53 + 766 1792 766 1792 768 1461 c 24,54,55 + 768 1461 768 1461 768 1355 c 0,56,57 + 768 1201 768 1201 711 1152 c 1,30,31 +EndSplineSet +EndChar + +StartChar: uni0094 +Encoding: 148 148 146 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8CJNffG9Xot.% +Q6XNTQmq716/li65Y_>gF@BR@+I0G:$V1>%-]!`j^^=J,OBQFqYl">.e9oz8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +440 1024 m 0,0,1 + 384 1024 384 1024 384 949 c 24,2,3 + 384 949 384 949 384 587 c 0,4,5 + 384 512 384 512 440 512 c 24,6,-1 + 712 512 l 0,7,8 + 768 512 768 512 768 587 c 24,9,10 + 768 587 768 587 768 949 c 2,11,12 + 768 1024 768 1024 712 1024 c 8,13,14 + 576 1024 576 1024 440 1024 c 0,0,1 +712 1280 m 2,15,16 + 960 1280 960 1280 960 949 c 0,17,18 + 960 949 960 949 960 587 c 0,19,20 + 960 256 960 256 712 256 c 10,21,-1 + 440 256 l 0,22,23 + 192 256 192 256 192 587 c 24,24,25 + 192 587 192 587 192 949 c 1,26,27 + 192 1280 192 1280 384 1280 c 0,28,29 + 384 1280 384 1280 384 1461 c 0,30,31 + 384 1536 384 1536 328 1536 c 24,32,-1 + 0 1536 l 24,33,34 + 0 1536 0 1536 0 1792 c 25,35,36 + 1 1792 1 1792 328 1792 c 0,37,38 + 576 1792 576 1792 576 1461 c 24,39,-1 + 576 1280 l 24,40,-1 + 712 1280 l 2,15,16 +EndSplineSet +EndChar + +StartChar: uni0096 +Encoding: 150 150 148 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8CJNffG9N3T?l +":E!T!@^DqO9m04OoPMn2HTrMJ?=?AYgJ[c?i_.'c#/nk!'65V&'==Aec5[M!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +576 1461 m 0,0,1 + 576 1536 576 1536 520 1536 c 24,2,-1 + 248 1536 l 0,3,4 + 192 1536 192 1536 192 1461 c 24,5,6 + 192 1461 192 1461 192 1337 c 25,7,-1 + 235 1280 l 24,8,-1 + 384 1280 l 24,9,-1 + 384 331 l 0,10,11 + 384 256 384 256 440 256 c 24,12,-1 + 768 256 l 24,13,-1 + 768 1280 l 24,14,-1 + 576 1280 l 24,15,-1 + 576 1461 l 0,0,1 +0 1461 m 0,16,17 + 0 1792 0 1792 248 1792 c 24,18,-1 + 520 1792 l 0,19,20 + 768 1792 768 1792 768 1461 c 24,21,-1 + 768 1337 l 0,22,23 + 768 1280 768 1280 811 1280 c 24,24,-1 + 960 1280 l 24,25,-1 + 960 0 l 25,26,-1 + 440 0 l 0,27,28 + 192 0 192 0 192 331 c 24,29,-1 + 192 1280 l 24,30,-1 + 0 1280 l 24,31,32 + 0 1287 0 1287 0 1461 c 0,16,17 +EndSplineSet +EndChar + +StartChar: uni0097 +Encoding: 151 151 149 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 111 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8sb%]fYs3[Tpk +#W"5fe7&J+O:XqqAcfP1YQ@LH#SG2oY^d/"k=>S;7MH1/$/OGBF +EndImage2 +Fore +SplineSet +960 1280 m 24,0,-1 + 960 0 l 25,1,2 + 960 0 960 0 440 0 c 24,3,4 + 192 0 192 0 192 331 c 0,5,6 + 192 640 192 640 192 1280 c 24,7,8 + 192 1280 192 1280 341 1280 c 24,9,10 + 384 1280 384 1280 384 1337 c 0,11,12 + 384 1461 384 1461 384 1461 c 24,13,14 + 384 1536 384 1536 328 1536 c 0,15,16 + 328 1536 328 1536 0 1536 c 24,17,-1 + 0 1792 l 25,18,-1 + 328 1792 l 24,19,20 + 576 1792 576 1792 576 1461 c 0,21,22 + 576 1281 576 1281 576 1280 c 24,23,24 + 576 1280 576 1280 384 1280 c 24,25,-1 + 384 331 l 24,26,27 + 384 256 384 256 440 256 c 0,28,29 + 440 256 440 256 768 256 c 24,30,-1 + 768 1280 l 24,31,-1 + 960 1280 l 24,0,-1 +EndSplineSet +EndChar + +StartChar: uni0098 +Encoding: 152 152 150 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8CJNffG9Xot.% +QD<(8YSD-KYqT9F@N]lhgC7'h2Z]][Rtnd+J5jE[5Z\'g[VZ]jUha3>z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +672 1792 m 25,0,-1 + 864 1792 l 25,1,-1 + 864 1536 l 24,2,-1 + 672 1536 l 24,3,4 + 672 1536 672 1536 672 1792 c 25,0,-1 +288 1792 m 24,5,-1 + 288 1536 l 24,6,-1 + 96 1536 l 24,7,-1 + 96 1792 l 25,8,9 + 96 1792 96 1792 288 1792 c 24,5,-1 +864 1280 m 24,10,11 + 864 1280 864 1280 864 331 c 0,12,13 + 864 0 864 0 616 0 c 24,14,-1 + 288 0 l 24,15,-1 + 288 256 l 24,16,-1 + 616 256 l 0,17,18 + 672 256 672 256 672 331 c 24,19,20 + 672 331 672 331 672 512 c 24,21,-1 + 344 512 l 0,22,23 + 96 512 96 512 96 843 c 24,24,25 + 96 843 96 843 96 1280 c 24,26,-1 + 288 1280 l 24,27,-1 + 288 843 l 0,28,29 + 288 768 288 768 344 768 c 24,30,-1 + 672 768 l 25,31,-1 + 672 1280 l 24,32,33 + 672 1280 672 1280 864 1280 c 24,10,11 +EndSplineSet +EndChar + +StartChar: uni0099 +Encoding: 153 153 151 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8C%,9r(&#+pt` +/0O?$]$P9sR?(e_827Co-56\mi=Ju(!\t7X)Z[-3(^ZKQ:]LIq!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +768 1792 m 25,0,-1 + 960 1792 l 25,1,-1 + 960 1536 l 24,2,-1 + 768 1536 l 24,3,4 + 768 1536 768 1536 768 1792 c 25,0,-1 +0 1792 m 25,5,-1 + 192 1792 l 25,6,-1 + 192 1536 l 24,7,-1 + 0 1536 l 24,8,9 + 0 1536 0 1536 0 1792 c 25,5,-1 +768 949 m 0,10,11 + 768 1024 768 1024 712 1024 c 24,12,-1 + 248 1024 l 0,13,14 + 192 1024 192 1024 192 949 c 24,15,16 + 192 602 192 602 192 331 c 0,17,18 + 192 256 192 256 248 256 c 24,19,-1 + 712 256 l 0,20,21 + 768 256 768 256 768 331 c 24,22,23 + 768 467 768 467 768 949 c 0,10,11 +712 1280 m 0,24,25 + 960 1280 960 1280 960 949 c 24,26,27 + 960 474 960 474 960 331 c 0,28,29 + 960 0 960 0 712 0 c 24,30,-1 + 248 0 l 0,31,32 + 0 0 0 0 0 331 c 24,33,34 + 0 806 0 806 0 949 c 0,35,36 + 0 1280 0 1280 248 1280 c 24,37,38 + 248 1280 248 1280 712 1280 c 0,24,25 +EndSplineSet +EndChar + +StartChar: uni009A +Encoding: 154 154 152 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8C%,9r(&#+o?< +Qr)#I_P(38$cn[U/k>Xn!4\[3&p%V?i;`iX!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +768 1792 m 25,0,-1 + 960 1792 l 25,1,-1 + 960 1536 l 24,2,-1 + 768 1536 l 24,3,4 + 768 1536 768 1536 768 1792 c 25,0,-1 +192 1792 m 25,5,-1 + 192 1536 l 24,6,-1 + 0 1536 l 24,7,-1 + 0 1792 l 25,8,-1 + 192 1792 l 25,5,-1 +960 1280 m 24,9,10 + 960 1280 960 1280 960 331 c 0,11,12 + 960 0 960 0 712 0 c 24,13,-1 + 248 0 l 0,14,15 + 0 0 0 0 0 331 c 24,16,17 + 0 331 0 331 0 1280 c 24,18,-1 + 192 1280 l 24,19,-1 + 192 331 l 0,20,21 + 192 256 192 256 248 256 c 24,22,-1 + 712 256 l 0,23,24 + 768 256 768 256 768 331 c 24,25,-1 + 768 1280 l 24,26,27 + 768 1280 768 1280 960 1280 c 24,9,10 +EndSplineSet +EndChar + +StartChar: uni009B +Encoding: 155 155 153 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 122 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5tOI1<#?L$NR8(5+:&'Rs8UE2K+e@/ +Q`3';in!tUm[g4<\h=$sKf"laP0aGAR'\%a1Ns&o/_MNWomponhuM-h'+]WtMlHaW!!#SZ:.26O +@"J@Y +EndImage2 +Fore +SplineSet +384 1280 m 24,0,-1 + 248 1280 l 0,1,2 + 192 1280 192 1280 192 1205 c 24,3,4 + 192 858 192 858 192 587 c 0,5,6 + 192 512 192 512 248 512 c 24,7,-1 + 384 512 l 24,8,9 + 384 512 384 512 384 1280 c 24,0,-1 +768 1536 m 24,10,-1 + 768 1280 l 24,11,-1 + 576 1280 l 24,12,-1 + 576 512 l 24,13,-1 + 768 512 l 24,14,-1 + 768 256 l 24,15,-1 + 576 256 l 24,16,-1 + 576 0 l 25,17,-1 + 384 0 l 25,18,-1 + 384 256 l 24,19,-1 + 248 256 l 0,20,21 + 0 256 0 256 0 587 c 24,22,23 + 0 1062 0 1062 0 1205 c 0,24,25 + 0 1536 0 1536 248 1536 c 24,26,-1 + 384 1536 l 24,27,-1 + 384 1792 l 25,28,-1 + 576 1792 l 25,29,-1 + 576 1536 l 24,30,-1 + 768 1536 l 24,10,-1 +EndSplineSet +EndChar + +StartChar: uni009C +Encoding: 156 156 154 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8CNNffHd!JJi$ +$V17CJ]f1G$0XEYI*rb&]*%+D'ORNFK`t`^AiGYQ!.c.#&Hl>:i;`iX!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +768 1792 m 25,0,-1 + 768 1536 l 24,1,-1 + 440 1536 l 0,2,3 + 384 1536 384 1536 384 1461 c 24,4,5 + 384 1461 384 1461 384 512 c 24,6,-1 + 712 512 l 0,7,8 + 768 512 768 512 768 587 c 24,9,-1 + 768 768 l 25,10,-1 + 960 768 l 25,11,12 + 960 768 960 768 960 587 c 0,13,14 + 960 256 960 256 712 256 c 24,15,-1 + 0 256 l 24,16,-1 + 0 512 l 24,17,-1 + 192 512 l 24,18,-1 + 192 1461 l 0,19,20 + 192 1792 192 1792 440 1792 c 24,21,22 + 440 1792 440 1792 768 1792 c 25,0,-1 +EndSplineSet +EndChar + +StartChar: uni009D +Encoding: 157 157 155 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8C%,9r(&3hH^I +((5m(A-5LALdnicA3P_eO;5%937r>*Co#hh!!@3^#&lu5f)PdN!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +480 1077 m 1,0,1 + 480 1077 480 1077 768 1461 c 1,2,-1 + 768 1792 l 25,3,-1 + 960 1792 l 0,4,5 + 960 1792 960 1792 960 1355 c 8,6,-1 + 712 1024 l 24,7,-1 + 960 1024 l 24,8,9 + 960 1024 960 1024 960 768 c 25,10,-1 + 576 768 l 25,11,12 + 576 768 576 768 576 512 c 24,13,-1 + 960 512 l 24,14,15 + 960 512 960 512 960 256 c 24,16,-1 + 576 256 l 24,17,-1 + 576 0 l 25,18,19 + 576 0 576 0 384 0 c 24,20,-1 + 384 256 l 24,21,-1 + 0 256 l 24,22,23 + 0 256 0 256 0 512 c 24,24,-1 + 384 512 l 24,25,26 + 384 512 384 512 384 768 c 25,27,-1 + 0 768 l 25,28,29 + 0 768 0 768 0 1024 c 24,30,-1 + 248 1024 l 24,31,-1 + 0 1355 l 25,32,-1 + 0 1792 l 25,33,-1 + 192 1792 l 1,34,-1 + 192 1461 l 1,35,-1 + 480 1077 l 1,0,1 +EndSplineSet +EndChar + +StartChar: uni009E +Encoding: 158 158 156 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8sb%RgE0H5;TS +A3i[S7MJ$"*n.r'Ug&Cf,1m>I6'0nVJF"Vm)dn7O)Q">OWN@3=kt"tbz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +384 512 m 24,0,-1 + 960 512 l 24,1,-1 + 960 256 l 24,2,-1 + 768 256 l 24,3,-1 + 768 0 l 25,4,-1 + 576 0 l 25,5,-1 + 576 256 l 24,6,-1 + 384 256 l 24,7,8 + 384 256 384 256 384 512 c 24,0,-1 +768 1461 m 0,9,10 + 768 1536 768 1536 712 1536 c 24,11,-1 + 192 1536 l 24,12,-1 + 192 1024 l 24,13,-1 + 712 1024 l 0,14,15 + 768 1024 768 1024 768 1099 c 24,16,17 + 768 1171 768 1171 768 1461 c 0,9,10 +0 1792 m 25,18,-1 + 712 1792 l 0,19,20 + 960 1792 960 1792 960 1461 c 24,21,22 + 960 1114 960 1114 960 1099 c 0,23,24 + 960 768 960 768 712 768 c 24,25,-1 + 192 768 l 25,26,-1 + 192 0 l 25,27,-1 + 0 0 l 25,28,-1 + 0 1792 l 25,18,-1 +EndSplineSet +EndChar + +StartChar: uni009F +Encoding: 159 159 157 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8D_*$Z[Q!sg+R +()R9%J^#k_'4?][Bs7Z+YqR(`!R,3oNM->T!1aR>1>&)KFFt80!5ad/%nR=YNrT.[!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +960 1792 m 25,0,1 + 960 1792 960 1792 960 1536 c 24,2,-1 + 632 1536 l 0,3,4 + 576 1536 576 1536 576 1461 c 25,5,6 + 576 1461 576 1461 576 1024 c 24,7,-1 + 768 1024 l 24,8,9 + 768 1024 768 1024 768 768 c 25,10,-1 + 576 768 l 25,11,-1 + 576 331 l 0,12,13 + 576 0 576 0 328 0 c 24,14,15 + 328 0 328 0 0 0 c 25,16,17 + 0 0 0 0 0 256 c 24,18,-1 + 328 256 l 0,19,20 + 384 256 384 256 384 331 c 24,21,22 + 384 331 384 331 384 768 c 25,23,-1 + 192 768 l 25,24,25 + 192 768 192 768 192 1024 c 0,26,-1 + 384 1024 l 25,27,28 + 384 1024 384 1024 384 1461 c 17,29,30 + 384 1792 384 1792 632 1792 c 24,31,32 + 632 1792 632 1792 960 1792 c 25,0,1 +EndSplineSet +EndChar + +StartChar: uni00A0 +Encoding: 160 160 158 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 125 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$N_p,`+:LRo])S$G(QNpF +KTOPnE?4#5;)=B^WLCOLkf.)JPhhE`$6hQ8Km9=:'h\;Df0U7c@_Y%0!Sk=!*9^"N?iU0,!(fUS +7'8jaJcGcN +EndImage2 +Fore +SplineSet +480 437 m 0,0,1 + 480 512 480 512 424 512 c 0,2,-1 + 344 512 l 0,3,4 + 288 512 288 512 288 437 c 0,5,6 + 288 346 288 346 288 331 c 0,7,8 + 288 256 288 256 344 256 c 0,9,10 + 344 256 344 256 424 256 c 0,11,12 + 480 256 480 256 480 331 c 0,13,14 + 480 331 480 331 480 437 c 0,0,1 +480 1280 m 1,15,16 + 672 1280 672 1280 672 949 c 1,17,-1 + 672 256 l 24,18,-1 + 821 256 l 0,19,20 + 864 256 864 256 864 127 c 0,21,22 + 864 0 864 0 821 0 c 24,23,24 + 821 0 821 0 344 0 c 0,25,26 + 96 0 96 0 96 331 c 24,27,28 + 96 331 96 331 96 437 c 0,29,30 + 96 768 96 768 344 768 c 24,31,-1 + 480 768 l 25,32,33 + 480 900 480 900 480 949 c 0,34,35 + 480 1024 480 1024 424 1024 c 24,36,-1 + 96 1024 l 24,37,38 + 96 1024 96 1024 96 1280 c 24,39,-1 + 288 1280 l 24,40,-1 + 288 1461 l 0,41,42 + 288 1792 288 1792 536 1792 c 24,43,44 + 536 1792 536 1792 864 1792 c 25,45,46 + 864 1792 864 1792 864 1536 c 24,47,-1 + 536 1536 l 0,48,49 + 480 1536 480 1536 480 1461 c 24,50,51 + 480 1461 480 1461 480 1280 c 1,15,16 +EndSplineSet +EndChar + +StartChar: exclamdown +Encoding: 161 161 159 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8D_*$Z[Q!sg+R +()R9%J^#mY$.pLhRc+V#NJBF +EndImage2 +Fore +SplineSet +288 256 m 24,0,-1 + 288 1024 l 24,1,2 + 288 1024 288 1024 480 1024 c 24,3,-1 + 480 256 l 24,4,-1 + 672 256 l 24,5,6 + 672 256 672 256 672 0 c 25,7,-1 + 96 0 l 25,8,-1 + 96 256 l 24,9,-1 + 288 256 l 24,0,-1 +288 1280 m 24,10,11 + 288 1280 288 1280 288 1461 c 17,12,13 + 288 1792 288 1792 536 1792 c 0,14,15 + 536 1792 536 1792 864 1792 c 0,16,17 + 864 1792 864 1792 864 1536 c 0,18,-1 + 536 1536 l 1,19,20 + 480 1536 480 1536 480 1461 c 8,21,-1 + 480 1280 l 24,22,23 + 480 1280 480 1280 288 1280 c 24,10,11 +EndSplineSet +EndChar + +StartChar: cent +Encoding: 162 162 160 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 118 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4\8%-<#?K_r!ro=GQ8D_*$Z[Q!sg+R +()R9%J^#kW'4;_d1fscP2ol,D.o8oiksD6R.KDOCfk>J_!W\Z<',H#YRNqk5!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +344 1024 m 0,0,1 + 288 1024 288 1024 288 949 c 24,2,3 + 288 949 288 949 288 331 c 0,4,5 + 288 256 288 256 344 256 c 24,6,-1 + 616 256 l 0,7,8 + 672 256 672 256 672 331 c 24,9,10 + 672 949 672 949 672 949 c 2,11,12 + 672 1024 672 1024 616 1024 c 8,13,14 + 480 1024 480 1024 344 1024 c 0,0,1 +616 1280 m 0,15,16 + 864 1280 864 1280 864 949 c 24,17,18 + 864 949 864 949 864 331 c 0,19,20 + 864 0 864 0 616 0 c 24,21,-1 + 344 0 l 0,22,23 + 96 0 96 0 96 331 c 24,24,25 + 96 806 96 806 96 949 c 0,26,27 + 96 1280 96 1280 288 1280 c 1,28,-1 + 288 1461 l 0,29,30 + 288 1792 288 1792 536 1792 c 24,31,32 + 536 1792 536 1792 864 1792 c 25,33,34 + 864 1792 864 1792 864 1536 c 24,35,-1 + 536 1536 l 0,36,37 + 480 1536 480 1536 480 1461 c 24,38,39 + 480 1461 480 1461 480 1280 c 24,40,-1 + 616 1280 l 0,15,16 +EndSplineSet +EndChar + +StartChar: sterling +Encoding: 163 163 161 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8D_*$Z[Q!sg+R +()R9%J^#mQ$-8:n-D4HA1C]bL>QNK>+NL21%C66=DFY-R6K,CSz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +864 1280 m 24,0,-1 + 864 0 l 25,1,-1 + 344 0 l 0,2,3 + 96 0 96 0 96 331 c 24,4,5 + 96 331 96 331 96 1205 c 25,6,-1 + 536 1792 l 24,7,-1 + 864 1792 l 25,8,-1 + 864 1536 l 24,9,-1 + 629 1536 l 24,10,-1 + 288 1099 l 25,11,12 + 288 678 288 678 288 331 c 0,13,14 + 288 256 288 256 344 256 c 24,15,-1 + 672 256 l 24,16,-1 + 672 1280 l 24,17,18 + 672 1280 672 1280 864 1280 c 24,0,-1 +EndSplineSet +EndChar + +StartChar: currency +Encoding: 164 164 162 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 119 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5"S..<#?K_r!ro=GQ8C%,9n7D"pPj) +!Q^/F%:fKR7hu4V7co=BF +EndImage2 +Fore +SplineSet +909 902 m 1,0,1 + 960 838 960 838 960 693 c 0,2,3 + 960 693 960 693 960 0 c 25,4,5 + 960 0 960 0 768 0 c 25,6,-1 + 768 768 l 25,7,-1 + 384 768 l 25,8,-1 + 384 0 l 1,9,10 + 192 0 192 0 192 0 c 25,11,12 + 192 1024 192 1024 192 1024 c 1,13,14 + 768 1024 768 1024 768 1024 c 24,15,16 + 768 1088 768 1088 768 1205 c 0,17,18 + 768 1280 768 1280 712 1280 c 24,19,20 + 248 1280 248 1280 248 1280 c 0,21,22 + 0 1280 0 1280 0 1611 c 0,23,24 + 0 1790 0 1790 0 1792 c 25,25,26 + 0 1792 0 1792 192 1792 c 25,27,-1 + 192 1611 l 0,28,29 + 192 1536 192 1536 248 1536 c 24,30,31 + 712 1536 712 1536 712 1536 c 0,32,33 + 960 1536 960 1536 960 1205 c 24,34,35 + 960 1205 960 1205 960 1099 c 0,36,37 + 960 952 960 952 909 902 c 1,0,1 +EndSplineSet +EndChar + +StartChar: yen +Encoding: 165 165 163 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$bu"fJ+:&'G-f+gFeV%B@ +d]^aTL:J\#8H@!r@PC'0#P.e,+]aiOf*(Omi&-B!nDf9V3(U7K?Df4j$$E!f`rH)>!(fUS7'8ja +JcGcN +EndImage2 +Fore +SplineSet +768 1205 m 17,0,1 + 768 1280 768 1280 712 1280 c 24,2,3 + 712 1280 712 1280 248 1280 c 0,4,5 + 192 1280 192 1280 192 1205 c 1,6,7 + 192 1205 192 1205 768 437 c 1,8,-1 + 768 1205 l 17,0,1 +93 1487 m 1,9,10 + 93 1487 93 1487 0 1611 c 1,11,-1 + 0 1792 l 25,12,13 + 136 1792 136 1792 136 1792 c 152,-1,14 + 136 1792 136 1792 328 1536 c 25,15,-1 + 712 1536 l 0,16,17 + 960 1536 960 1536 960 1205 c 0,18,19 + 960 0 960 0 960 0 c 153,-1,20 + 960 0 960 0 768 0 c 25,21,-1 + 768 75 l 25,22,-1 + 192 843 l 25,23,-1 + 192 0 l 25,24,-1 + 0 0 l 25,25,26 + 0 1205 0 1205 0 1205 c 0,27,28 + 0 1420 0 1420 93 1487 c 1,9,10 +EndSplineSet +EndChar + +StartChar: brokenbar +Encoding: 166 166 164 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 -96 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?K_r!ro=GQ8+BNffG9Xor#n +'1`BF +EndImage2 +Fore +SplineSet +384 1792 m 24,0,-1 + 576 1792 l 25,1,-1 + 576 1536 l 24,2,-1 + 384 1536 l 24,3,4 + 384 1536 384 1536 384 1792 c 24,0,-1 +960 512 m 1,5,6 + 960 512 960 512 960 331 c 0,7,8 + 960 0 960 0 712 0 c 24,9,-1 + 248 0 l 0,10,11 + 0 0 0 0 0 331 c 24,12,13 + 0 331 0 331 0 437 c 25,14,-1 + 384 949 l 25,15,-1 + 384 1280 l 24,16,-1 + 576 1280 l 24,17,-1 + 576 843 l 25,18,-1 + 192 331 l 0,19,20 + 192 256 192 256 248 256 c 24,21,-1 + 712 256 l 0,22,23 + 768 256 768 256 768 331 c 24,24,-1 + 768 512 l 17,25,26 + 768 512 768 512 960 512 c 1,5,6 +EndSplineSet +EndChar + +StartChar: copyright +Encoding: 169 169 167 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 105 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd6aoX='=TE7j'#B5s&u:P\)[Inn!!4kb"&IJB(]XO9!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 1280 m 24,0,-1 + 960 1280 l 24,1,-1 + 960 1024 l 24,2,-1 + 192 1024 l 24,3,-1 + 192 768 l 25,4,-1 + 0 768 l 25,5,6 + 0 768 0 768 0 1280 c 24,0,-1 +EndSplineSet +EndChar + +StartChar: ordfeminine +Encoding: 170 170 168 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd6b(@hz8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +440 256 m 1,1,2 + 440 256 440 256 768 693 c 0,3,4 + 768 768 768 768 712 768 c 24,5,6 + 712 768 712 768 520 768 c 24,7,-1 + 136 256 l 24,8,9 + 136 256 136 256 0 256 c 24,10,11 + 0 256 0 256 0 437 c 25,12,13 + 0 437 0 437 824 1536 c 1,14,15 + 824 1536 824 1536 960 1536 c 1,16,17 + 960 1536 960 1536 960 1355 c 9,18,-1 + 768 1099 l 25,19,20 + 768 1099 768 1099 768 1024 c 1,21,22 + 960 1024 960 1024 960 693 c 0,23,24 + 960 640 960 640 960 587 c 0,25,26 + 960 587 960 587 712 256 c 1,27,28 + 712 256 712 256 960 256 c 24,29,30 + 960 256 960 256 960 0 c 25,31,32 + 960 0 960 0 384 0 c 0,33,34 + 384 0 384 0 384 256 c 0,35,0 + 384 256 384 256 440 256 c 1,1,2 +0 1792 m 25,36,-1 + 192 1792 l 25,37,-1 + 192 1024 l 24,38,-1 + 0 1024 l 24,39,40 + 0 1024 0 1024 0 1792 c 25,36,-1 +EndSplineSet +EndChar + +StartChar: logicalnot +Encoding: 172 172 170 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 120 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5=n7/<#?L$NDU#_0F1!$G5j(21C0M0 +r2Q>,p/MMn!!A6PV]L'kK`3_'n:PP\#-HFDL8@Ise^,tZkffSY%)itrG2h[*z8OZBBY!QNJ + +EndImage2 +Fore +SplineSet +520 768 m 1,0,1 + 520 768 520 768 576 768 c 1,2,-1 + 576 587 l 0,3,4 + 576 512 576 512 632 512 c 24,5,6 + 632 512 632 512 768 512 c 24,7,8 + 768 512 768 512 768 768 c 25,9,-1 + 960 768 l 25,10,-1 + 960 0 l 25,11,-1 + 768 0 l 25,12,-1 + 768 256 l 24,13,-1 + 632 256 l 1,14,15 + 384 256 384 256 384 587 c 1,16,17 + 384 587 384 587 136 256 c 0,18,19 + 136 256 136 256 0 256 c 24,20,21 + 0 256 0 256 0 437 c 25,22,23 + 0 437 0 437 824 1536 c 24,24,25 + 824 1536 824 1536 960 1537 c 0,26,27 + 960 1537 960 1537 960 1355 c 1,28,29 + 960 1355 960 1355 520 768 c 1,0,1 +0 1792 m 25,30,-1 + 192 1792 l 25,31,-1 + 192 1024 l 24,32,-1 + 0 1024 l 24,33,34 + 0 1024 0 1024 0 1792 c 25,30,-1 +EndSplineSet +EndChar + +StartChar: uni00AD +Encoding: 173 173 171 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8CNNffG9`^HNZ +$?-jc=$Y+8'Q]BrE"e>O:mdIt!!#m3#7ii8+`m\a!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +384 1280 m 24,0,-1 + 576 1280 l 24,1,-1 + 576 0 l 25,2,-1 + 384 0 l 24,3,4 + 384 0 384 0 384 1280 c 24,0,-1 +384 1792 m 24,5,-1 + 576 1792 l 25,6,-1 + 576 1536 l 24,7,-1 + 384 1536 l 24,8,9 + 384 1536 384 1536 384 1792 c 24,5,-1 +EndSplineSet +EndChar + +StartChar: registered +Encoding: 174 174 172 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 -43.5 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +>TGR=,Y68bOB/kI5e>@6_up^')2l^nfh'g'\G7g1BJ]\prtPfbo^aa:!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +781 896 m 1,0,1 + 916 896 916 896 916 693 c 0,2,3 + 916 693 916 693 916 313 c 0,4,5 + 916 256 916 256 820 256 c 144,-1,6 + 724 256 724 256 724 313 c 24,7,-1 + 724 693 l 1,8,9 + 724 843 724 843 576 843 c 0,10,11 + 576 843 576 843 576 949 c 1,12,13 + 724 949 724 949 724 1099 c 1,14,-1 + 724 1479 l 0,15,16 + 724 1536 724 1536 820 1536 c 128,-1,17 + 916 1536 916 1536 916 1479 c 8,18,19 + 916 1188 916 1188 916 1099 c 0,20,21 + 916 896 916 896 781 896 c 1,0,1 +205 896 m 1,22,23 + 340 896 340 896 340 693 c 0,24,25 + 340 474 340 474 340 313 c 0,26,27 + 340 256 340 256 244 256 c 144,-1,28 + 148 256 148 256 148 313 c 24,29,-1 + 148 693 l 1,30,31 + 148 843 148 843 0 843 c 0,32,33 + 0 843 0 843 0 949 c 1,34,35 + 148 949 148 949 148 1099 c 1,36,-1 + 148 1479 l 0,37,38 + 148 1536 148 1536 244 1536 c 128,-1,39 + 340 1536 340 1536 340 1479 c 8,40,41 + 340 1362 340 1362 340 1099 c 0,42,43 + 340 896 340 896 205 896 c 1,22,23 +EndSplineSet +EndChar + +StartChar: macron +Encoding: 175 175 173 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8Bu3Ns22,9nF< +%5JkL8D"','4K!lfs6#;QBF +EndImage2 +Fore +SplineSet +768 2048 m 25,0,-1 + 960 2048 l 25,1,-1 + 960 1792 l 25,2,-1 + 768 1792 l 25,3,-1 + 768 2048 l 25,0,-1 +384 2304 m 25,4,-1 + 576 2304 l 25,5,-1 + 576 2048 l 25,6,-1 + 384 2048 l 25,7,-1 + 384 2304 l 25,4,-1 +0 2048 m 25,8,-1 + 192 2048 l 25,9,-1 + 192 1792 l 25,10,-1 + 0 1792 l 25,11,-1 + 0 2048 l 25,8,-1 +768 512 m 25,12,-1 + 960 512 l 25,13,-1 + 960 256 l 25,14,-1 + 768 256 l 25,15,-1 + 768 512 l 25,12,-1 +768 1024 m 25,16,-1 + 960 1024 l 25,17,-1 + 960 768 l 25,18,-1 + 768 768 l 25,19,-1 + 768 1024 l 25,16,-1 +768 1536 m 25,20,-1 + 960 1536 l 25,21,-1 + 960 1280 l 25,22,-1 + 768 1280 l 25,23,-1 + 768 1536 l 25,20,-1 +384 256 m 25,24,-1 + 576 256 l 25,25,-1 + 576 0 l 25,26,-1 + 384 0 l 25,27,-1 + 384 256 l 25,24,-1 +384 768 m 25,28,-1 + 576 768 l 25,29,-1 + 576 512 l 25,30,-1 + 384 512 l 25,31,-1 + 384 768 l 25,28,-1 +384 1280 m 25,32,-1 + 576 1280 l 25,33,-1 + 576 1024 l 25,34,-1 + 384 1024 l 25,35,-1 + 384 1280 l 25,32,-1 +384 1792 m 25,36,-1 + 576 1792 l 25,37,-1 + 576 1536 l 25,38,-1 + 384 1536 l 25,39,-1 + 384 1792 l 25,36,-1 +0 512 m 25,40,-1 + 192 512 l 25,41,-1 + 192 256 l 25,42,-1 + 0 256 l 25,43,-1 + 0 512 l 25,40,-1 +0 1024 m 25,44,-1 + 192 1024 l 25,45,-1 + 192 768 l 25,46,-1 + 0 768 l 25,47,-1 + 0 1024 l 25,44,-1 +0 1536 m 25,48,-1 + 192 1536 l 25,49,-1 + 192 1280 l 25,50,-1 + 0 1280 l 25,51,-1 + 0 1536 l 25,48,-1 +EndSplineSet +EndChar + +StartChar: plusminus +Encoding: 177 177 175 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8C%,9p;/SVHB; +!Z;!$7&FCU+<#%tZ6[X>R%hE)!WYS80bpR=__(oh!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +768 2304 m 25,0,-1 + 960 2304 l 25,1,-1 + 960 2048 l 25,2,-1 + 768 2048 l 25,3,-1 + 768 2304 l 25,0,-1 +576 2048 m 25,4,-1 + 768 2048 l 25,5,-1 + 768 1792 l 25,6,-1 + 576 1792 l 25,7,-1 + 576 2048 l 25,4,-1 +384 2304 m 25,8,-1 + 576 2304 l 25,9,-1 + 576 2048 l 25,10,-1 + 384 2048 l 25,11,-1 + 384 2304 l 25,8,-1 +192 2048 m 25,12,-1 + 384 2048 l 25,13,-1 + 384 1792 l 25,14,-1 + 192 1792 l 25,15,-1 + 192 2048 l 25,12,-1 +0 2304 m 25,16,-1 + 192 2304 l 25,17,-1 + 192 2048 l 25,18,-1 + 0 2048 l 25,19,-1 + 0 2304 l 25,16,-1 +768 256 m 25,20,-1 + 960 256 l 25,21,-1 + 960 0 l 25,22,-1 + 768 0 l 25,23,-1 + 768 256 l 25,20,-1 +384 256 m 25,24,-1 + 576 256 l 25,25,-1 + 576 0 l 25,26,-1 + 384 0 l 25,27,-1 + 384 256 l 25,24,-1 +0 256 m 25,28,-1 + 192 256 l 25,29,-1 + 192 0 l 25,30,-1 + 0 0 l 25,31,-1 + 0 256 l 25,28,-1 +576 512 m 25,32,-1 + 768 512 l 25,33,-1 + 768 256 l 25,34,-1 + 576 256 l 25,35,-1 + 576 512 l 25,32,-1 +192 512 m 25,36,-1 + 384 512 l 25,37,-1 + 384 256 l 25,38,-1 + 192 256 l 25,39,-1 + 192 512 l 25,36,-1 +768 768 m 25,40,-1 + 960 768 l 25,41,-1 + 960 512 l 25,42,-1 + 768 512 l 25,43,-1 + 768 768 l 25,40,-1 +384 768 m 25,44,-1 + 576 768 l 25,45,-1 + 576 512 l 25,46,-1 + 384 512 l 25,47,-1 + 384 768 l 25,44,-1 +0 768 m 25,48,-1 + 192 768 l 25,49,-1 + 192 512 l 25,50,-1 + 0 512 l 25,51,-1 + 0 768 l 25,48,-1 +576 1024 m 25,52,-1 + 768 1024 l 25,53,-1 + 768 768 l 25,54,-1 + 576 768 l 25,55,-1 + 576 1024 l 25,52,-1 +192 1024 m 25,56,-1 + 384 1024 l 25,57,-1 + 384 768 l 25,58,-1 + 192 768 l 25,59,-1 + 192 1024 l 25,56,-1 +768 1280 m 25,60,-1 + 960 1280 l 25,61,-1 + 960 1024 l 25,62,-1 + 768 1024 l 25,63,-1 + 768 1280 l 25,60,-1 +384 1280 m 25,64,-1 + 576 1280 l 25,65,-1 + 576 1024 l 25,66,-1 + 384 1024 l 25,67,-1 + 384 1280 l 25,64,-1 +0 1280 m 25,68,-1 + 192 1280 l 25,69,-1 + 192 1024 l 25,70,-1 + 0 1024 l 25,71,-1 + 0 1280 l 25,68,-1 +576 1536 m 25,72,-1 + 768 1536 l 25,73,-1 + 768 1280 l 25,74,-1 + 576 1280 l 25,75,-1 + 576 1536 l 25,72,-1 +192 1536 m 25,76,-1 + 384 1536 l 25,77,-1 + 384 1280 l 25,78,-1 + 192 1280 l 25,79,-1 + 192 1536 l 25,76,-1 +768 1792 m 25,80,-1 + 960 1792 l 25,81,-1 + 960 1536 l 25,82,-1 + 768 1536 l 25,83,-1 + 768 1792 l 25,80,-1 +384 1792 m 25,84,-1 + 576 1792 l 25,85,-1 + 576 1536 l 25,86,-1 + 384 1536 l 25,87,-1 + 384 1792 l 25,84,-1 +0 1792 m 25,88,-1 + 192 1792 l 25,89,-1 + 192 1536 l 25,90,-1 + 0 1536 l 25,91,-1 + 0 1792 l 25,88,-1 +EndSplineSet +EndChar + +StartChar: uni00B2 +Encoding: 178 178 176 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$N6qt4+:Ja +/&3J4',qPk!$J3C'$J7Wkl:\`!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +192 2304 m 25,0,-1 + 384 2304 l 25,1,-1 + 384 0 l 25,2,-1 + 192 0 l 25,3,-1 + 192 2304 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: acute +Encoding: 180 180 178 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 93 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,Y:Bi<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4',qVm5X)sg!$MLK'r$fZcN!qF!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +192 2304 m 29,0,-1 + 384 2304 l 29,1,-1 + 384 0 l 29,2,-1 + 192 0 l 29,3,-1 + 192 768 l 29,4,-1 + 0 768 l 29,5,-1 + 0 1024 l 29,6,-1 + 192 1024 l 29,7,-1 + 192 2304 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: mu +Encoding: 181 181 179 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 101 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4';L-\OT"qS'*1l_0G-&@!9%Sr't*9^b5_MB!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +384 2304 m 29,0,-1 + 384 0 l 29,1,-1 + 192 0 l 29,2,-1 + 192 768 l 29,3,-1 + 0 768 l 29,4,-1 + 0 1024 l 29,5,-1 + 192 1024 l 29,6,-1 + 192 1280 l 29,7,-1 + 0 1280 l 29,8,-1 + 0 1536 l 29,9,-1 + 192 1536 l 29,10,-1 + 192 2304 l 29,11,-1 + 384 2304 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: paragraph +Encoding: 182 182 180 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 95 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pJu:T`F-UHiO-kKEN.@)qT34!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +576 2304 m 29,0,-1 + 768 2304 l 29,1,-1 + 768 0 l 29,2,-1 + 576 0 l 29,3,-1 + 576 2304 l 29,0,-1 +192 2304 m 29,4,-1 + 384 2304 l 29,5,-1 + 384 0 l 29,6,-1 + 192 0 l 29,7,-1 + 192 768 l 29,8,-1 + 0 768 l 29,9,-1 + 0 1024 l 29,10,-1 + 192 1024 l 29,11,-1 + 192 2304 l 29,4,-1 +EndSplineSet +EndChar + +StartChar: periodcentered +Encoding: 183 183 181 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +384 768 m 21,0,-1 + 384 0 l 5,1,-1 + 192 0 l 29,2,-1 + 192 768 l 29,3,-1 + 0 768 l 29,4,-1 + 0 1024 l 5,5,-1 + 768 1024 l 21,6,7 + 768 1024 768 1024 768 0 c 5,8,-1 + 576 0 l 5,9,-1 + 576 768 l 13,10,11 + 576 768 576 768 384 768 c 21,0,-1 +EndSplineSet +EndChar + +StartChar: cedilla +Encoding: 184 184 182 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns2<'JKS? +_Jgd+]314U+BL9QK(L/c$b?=)$GliE+P$o1*lXZMz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 1024 m 137,-1,1 + 192 1024 192 1024 192 1280 c 25,2,-1 + 0 1280 l 25,3,-1 + 0 1536 l 25,4,-1 + 384 1536 l 1,5,6 + 384 1536 384 1536 384 0 c 1,7,-1 + 192 0 l 25,8,-1 + 192 768 l 25,9,-1 + 0 768 l 25,10,-1 + 0 1024 l 1,11,0 + 192 1024 192 1024 192 1024 c 137,-1,1 +EndSplineSet +EndChar + +StartChar: uni00B9 +Encoding: 185 185 183 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 105 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pFGM-ihq]&$QW7"9T%;$.opo!$-\!)&6YA2ZNgX!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 1280 m 25,0,-1 + 0 1536 l 25,1,-1 + 192 1536 l 25,2,-1 + 192 2304 l 25,3,-1 + 384 2304 l 25,4,-1 + 384 1280 l 25,5,-1 + 0 1280 l 25,0,-1 +576 2304 m 25,6,-1 + 768 2304 l 25,7,-1 + 768 0 l 25,8,-1 + 576 0 l 25,9,-1 + 576 2304 l 25,6,-1 +384 1024 m 25,10,-1 + 384 0 l 1,11,-1 + 192 0 l 25,12,-1 + 192 768 l 25,13,-1 + 0 768 l 25,14,-1 + 0 1024 l 1,15,-1 + 384 1024 l 25,10,-1 +EndSplineSet +EndChar + +StartChar: ordmasculine +Encoding: 186 186 184 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 91 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,"Y0g<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pJtoT`>';-Nk/O`Y'Ep!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +192 2304 m 25,0,-1 + 384 2304 l 25,1,-1 + 384 0 l 25,2,-1 + 192 0 l 25,3,-1 + 192 2304 l 25,0,-1 +576 2304 m 25,4,-1 + 768 2304 l 25,5,-1 + 768 0 l 25,6,-1 + 576 0 l 25,7,-1 + 576 2304 l 25,4,-1 +EndSplineSet +EndChar + +StartChar: guillemotright +Encoding: 187 187 185 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns2<'JKS? +_Jgd+]314U+BL9QK(L/c$aKcD@ZW>F=e-$1?1ZPNz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +384 1024 m 17,0,1 + 384 1024 384 1024 384 0 c 1,2,-1 + 192 0 l 25,3,-1 + 192 768 l 25,4,-1 + 0 768 l 25,5,-1 + 0 1024 l 1,6,7 + 192 1024 192 1024 384 1024 c 17,0,1 +0 1280 m 25,8,-1 + 0 1536 l 25,9,-1 + 768 1536 l 25,10,11 + 768 1024 768 1024 768 0 c 1,12,-1 + 576 0 l 1,13,-1 + 576 1280 l 1,14,15 + 576 1280 576 1280 0 1280 c 25,8,-1 +EndSplineSet +EndChar + +StartChar: onequarter +Encoding: 188 188 186 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pFGM-ihq]&$QW7"9T#T'*.*q#9;f]U)a46!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +384 2304 m 25,0,-1 + 384 1280 l 25,1,-1 + 0 1280 l 25,2,-1 + 0 1536 l 25,3,-1 + 192 1536 l 25,4,-1 + 192 2304 l 25,5,-1 + 384 2304 l 25,0,-1 +0 768 m 25,6,-1 + 0 1024 l 25,7,-1 + 576 1024 l 25,8,-1 + 576 2304 l 25,9,-1 + 768 2304 l 25,10,-1 + 768 768 l 25,11,-1 + 0 768 l 25,6,-1 +EndSplineSet +EndChar + +StartChar: onehalf +Encoding: 189 189 187 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 99 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +192 1024 m 9,0,-1 + 192 2304 l 1,1,-1 + 384 2304 l 1,2,-1 + 384 1024 l 17,3,4 + 384 1024 384 1024 576 1024 c 1,5,-1 + 576 2304 l 25,6,-1 + 768 2304 l 25,7,-1 + 768 768 l 25,8,-1 + 0 768 l 25,9,-1 + 0 1024 l 1,10,-1 + 192 1024 l 9,0,-1 +EndSplineSet +EndChar + +StartChar: threequarters +Encoding: 190 190 188 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 101 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4';L-\OT"qS'*1l_0G-&@!9%Sr't*9^b5_MB!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +192 1536 m 17,0,1 + 192 1536 192 1536 192 2304 c 1,2,-1 + 384 2304 l 1,3,4 + 384 1536 384 1536 384 768 c 25,5,6 + 0 768 0 768 0 768 c 1,7,-1 + 0 1024 l 1,8,-1 + 192 1024 l 1,9,-1 + 192 1280 l 1,10,11 + 192 1280 192 1280 0 1280 c 25,12,-1 + 0 1536 l 25,13,-1 + 192 1536 l 17,0,1 +EndSplineSet +EndChar + +StartChar: questiondown +Encoding: 191 191 189 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +384 1024 m 17,0,1 + 384 1024 384 1024 384 0 c 1,2,-1 + 192 0 l 25,3,-1 + 192 768 l 25,4,-1 + 0 768 l 25,5,-1 + 0 1024 l 1,6,7 + 192 1024 192 1024 384 1024 c 17,0,1 +EndSplineSet +EndChar + +StartChar: Agrave +Encoding: 192 192 190 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 92 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4',u$#Yk\J'+V"VlN61l:z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 2304 m 5,0,-1 + 384 2304 l 5,1,-1 + 384 1024 l 5,2,-1 + 1056 1024 l 5,3,-1 + 1056 768 l 5,4,-1 + 192 768 l 5,5,-1 + 192 2304 l 5,0,-1 +EndSplineSet +EndChar + +StartChar: Aacute +Encoding: 193 193 191 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4',q>e(kI^`n0YHe!FA>'%B8fCrr<$!!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +192 1024 m 21,0,1 + 192 1024 192 1024 192 2304 c 5,2,-1 + 384 2304 l 5,3,-1 + 384 1024 l 5,4,-1 + 1056 1024 l 5,5,-1 + 1056 768 l 5,6,-1 + 0 768 l 13,7,-1 + 0 1024 l 29,8,-1 + 192 1024 l 21,0,1 +EndSplineSet +EndChar + +StartChar: Acircumflex +Encoding: 194 194 192 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +192 768 m 1,0,1 + 192 768 192 768 0 768 c 25,2,-1 + 0 1024 l 17,3,-1 + 1056 1024 l 1,4,-1 + 1056 768 l 1,5,-1 + 384 768 l 1,6,-1 + 384 0 l 1,7,-1 + 192 0 l 1,8,-1 + 192 768 l 1,0,1 +EndSplineSet +EndChar + +StartChar: Atilde +Encoding: 195 195 193 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 92 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,=t9h<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4',u$#Yk\J'+V"VlN61l:z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +384 2304 m 25,0,-1 + 384 1024 l 1,1,-1 + 1056 1024 l 1,2,-1 + 1056 768 l 1,3,-1 + 384 768 l 1,4,-1 + 384 0 l 25,5,-1 + 192 0 l 25,6,-1 + 192 2304 l 25,7,-1 + 384 2304 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: Adieresis +Encoding: 196 196 194 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +0 1024 m 17,0,-1 + 1056 1024 l 1,1,-1 + 1056 768 l 1,2,-1 + 0 768 l 9,3,-1 + 0 1024 l 17,0,-1 +EndSplineSet +EndChar + +StartChar: Aring +Encoding: 197 197 195 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4',q>e(kI^`n0YHe!FA>'%B8fCrr<$!!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +192 1024 m 17,0,1 + 192 1024 192 1024 192 2304 c 1,2,-1 + 384 2304 l 25,3,-1 + 384 1024 l 1,4,-1 + 1056 1024 l 1,5,-1 + 1056 768 l 1,6,-1 + 384 768 l 1,7,-1 + 384 0 l 25,8,-1 + 192 0 l 1,9,-1 + 192 768 l 9,10,11 + 192 768 192 768 0 768 c 25,12,-1 + 0 1024 l 25,13,-1 + 192 1024 l 17,0,1 +EndSplineSet +EndChar + +StartChar: AE +Encoding: 198 198 196 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4';Mi7Ci3[4f`e+TGmM@ufLu8F^?>eBB4:K7z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 2304 m 25,0,-1 + 384 2304 l 25,1,-1 + 384 1536 l 1,2,-1 + 1056 1536 l 1,3,-1 + 1056 1280 l 1,4,-1 + 384 1280 l 1,5,-1 + 384 1024 l 1,6,-1 + 1056 1024 l 1,7,-1 + 1056 768 l 1,8,-1 + 384 768 l 1,9,-1 + 384 0 l 25,10,-1 + 192 0 l 25,11,-1 + 192 2304 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: Ccedilla +Encoding: 199 199 197 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 95 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pJu:WrV32(]XO\8-Be-C[o1?!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +384 2304 m 1,0,-1 + 384 0 l 1,1,-1 + 192 0 l 1,2,-1 + 192 2304 l 1,3,-1 + 384 2304 l 1,0,-1 +768 2304 m 1,4,-1 + 768 1024 l 1,5,-1 + 1056 1024 l 1,6,-1 + 1056 768 l 1,7,-1 + 768 768 l 1,8,-1 + 768 0 l 1,9,-1 + 576 0 l 1,10,-1 + 576 2304 l 1,11,-1 + 768 2304 l 1,4,-1 +EndSplineSet +EndChar + +StartChar: Egrave +Encoding: 200 200 198 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 100 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.nN,p<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pK!%:k7s_'K703#3K"fZMb"F3oa6rz8OZBBY!QNJ +EndImage2 +Fore +SplineSet +576 2304 m 25,0,-1 + 768 2304 l 25,1,-1 + 768 1536 l 1,2,-1 + 1056 1536 l 1,3,-1 + 1056 1280 l 1,4,-1 + 576 1280 l 1,5,-1 + 576 2304 l 25,0,-1 +1056 768 m 1,6,-1 + 192 768 l 1,7,-1 + 192 2304 l 25,8,-1 + 384 2304 l 25,9,-1 + 384 1024 l 1,10,-1 + 1056 1024 l 1,11,-1 + 1056 768 l 1,6,-1 +EndSplineSet +EndChar + +StartChar: Eacute +Encoding: 201 201 199 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8Bu3Ns2<'X3*= +@Us";E=0"`_$XSUa:^0]$qI%]"ot9O$4t0"i%tE6!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +576 1024 m 1,0,1 + 816 1024 816 1024 1056 1024 c 1,2,3 + 1056 1024 1056 1024 1056 768 c 1,4,-1 + 768 768 l 1,5,-1 + 768 0 l 25,6,-1 + 576 0 l 1,7,-1 + 576 1024 l 1,0,1 +1056 1280 m 1,8,-1 + 384 1280 l 1,9,10 + 384 1280 384 1280 384 0 c 1,11,-1 + 192 0 l 1,12,-1 + 192 1536 l 1,13,14 + 192 1536 192 1536 1056 1536 c 1,15,-1 + 1056 1280 l 1,8,-1 +EndSplineSet +EndChar + +StartChar: Ecircumflex +Encoding: 202 202 200 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 105 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0M+Yu<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pFGM-ihq]%knXe"\:_02j&Lu!+*5F%a\Tq3<0$Z!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +576 2304 m 25,0,-1 + 768 2304 l 25,1,-1 + 768 1536 l 25,2,-1 + 1056 1536 l 25,3,-1 + 1056 1280 l 25,4,-1 + 576 1280 l 25,5,-1 + 576 2304 l 25,0,-1 +0 1536 m 17,6,-1 + 192 1536 l 1,7,-1 + 192 2304 l 1,8,-1 + 384 2304 l 25,9,-1 + 384 1280 l 25,10,-1 + 0 1280 l 25,11,-1 + 0 1536 l 17,6,-1 +0 768 m 25,12,-1 + 0 1024 l 25,13,-1 + 1056 1024 l 25,14,-1 + 1056 768 l 25,15,-1 + 0 768 l 25,12,-1 +EndSplineSet +EndChar + +StartChar: Edieresis +Encoding: 203 203 201 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 102 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/P/>r<#?K_r!ro=GQ8Bu3Ns2<'JKS? +_Jgd+]314UfGoiZ!_>$j,9m;r-30>o&cjm'^*3OW!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +576 0 m 25,0,-1 + 576 1024 l 25,1,-1 + 1056 1024 l 25,2,-1 + 1056 768 l 25,3,-1 + 768 768 l 25,4,-1 + 768 0 l 25,5,-1 + 576 0 l 25,0,-1 +0 768 m 9,6,-1 + 0 1024 l 25,7,-1 + 384 1024 l 25,8,-1 + 384 0 l 25,9,-1 + 192 0 l 1,10,-1 + 192 768 l 1,11,-1 + 0 768 l 9,6,-1 +0 1536 m 25,12,-1 + 1056 1536 l 25,13,-1 + 1056 1280 l 25,14,-1 + 0 1280 l 25,15,-1 + 0 1536 l 25,12,-1 +EndSplineSet +EndChar + +StartChar: Igrave +Encoding: 204 204 202 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 99 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pK!%:k7s_$o`]aKF@jd`!7$Wg'U=M!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +1056 1280 m 1,0,-1 + 576 1280 l 1,1,-1 + 576 2304 l 25,2,-1 + 768 2304 l 25,3,-1 + 768 1536 l 1,4,-1 + 1056 1536 l 1,5,-1 + 1056 1280 l 1,0,-1 +384 2304 m 25,6,-1 + 384 0 l 25,7,-1 + 192 0 l 25,8,-1 + 192 2304 l 25,9,-1 + 384 2304 l 25,6,-1 +576 1024 m 1,10,-1 + 1056 1024 l 1,11,-1 + 1056 768 l 1,12,-1 + 768 768 l 1,13,-1 + 768 0 l 25,14,-1 + 576 0 l 1,15,-1 + 576 1024 l 1,10,-1 +EndSplineSet +EndChar + +StartChar: Iacute +Encoding: 205 205 203 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 94 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns2<'JKS? +_Jgd+]314UfGmT3"9;^u%fm;4_$'f=!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 1024 m 1,0,-1 + 1056 1024 l 1,1,-1 + 1056 768 l 1,2,-1 + 0 768 l 1,3,-1 + 0 1024 l 1,0,-1 +0 1536 m 1,4,-1 + 1056 1536 l 1,5,-1 + 1056 1280 l 1,6,-1 + 0 1280 l 1,7,-1 + 0 1536 l 1,4,-1 +EndSplineSet +EndChar + +StartChar: Icircumflex +Encoding: 206 206 204 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 109 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1eC)$<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pFGM-ihq]%knXe"\:`1Riif*9LSS7!10i!%](Uh2ZNgX!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 1280 m 1,0,-1 + 0 1536 l 1,1,-1 + 192 1536 l 1,2,-1 + 192 2304 l 25,3,-1 + 384 2304 l 25,4,-1 + 384 1280 l 1,5,-1 + 0 1280 l 1,0,-1 +384 1024 m 1,6,-1 + 384 0 l 1,7,-1 + 192 0 l 25,8,-1 + 192 768 l 1,9,-1 + 0 768 l 1,10,-1 + 0 1024 l 1,11,-1 + 384 1024 l 1,6,-1 +1056 1280 m 1,12,-1 + 576 1280 l 1,13,-1 + 576 2304 l 25,14,-1 + 768 2304 l 25,15,-1 + 768 1536 l 1,16,-1 + 1056 1536 l 1,17,-1 + 1056 1280 l 1,12,-1 +576 1024 m 1,18,-1 + 1056 1024 l 1,19,-1 + 1056 768 l 1,20,-1 + 768 768 l 1,21,-1 + 768 0 l 25,22,-1 + 576 0 l 1,23,-1 + 576 1024 l 1,18,-1 +EndSplineSet +EndChar + +StartChar: Idieresis +Encoding: 207 207 205 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4';Je5,L@hI7j>R7"doJ!(RZU`!WZ\]%gVktrYPV8!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 1024 m 1,0,-1 + 1056 1024 l 1,1,-1 + 1056 768 l 1,2,-1 + 0 768 l 1,3,-1 + 0 1024 l 1,0,-1 +192 2304 m 1,4,-1 + 384 2304 l 1,5,-1 + 384 1536 l 1,6,-1 + 1056 1536 l 1,7,-1 + 1056 1280 l 1,8,-1 + 0 1280 l 1,9,-1 + 0 1536 l 1,10,-1 + 192 1536 l 1,11,-1 + 192 2304 l 1,4,-1 +EndSplineSet +EndChar + +StartChar: space +Encoding: 32 32 206 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 79 1584 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(.gn[<#?K_r!ro=GQ8Bu3O%$&:]LJ7 +D?LB^-QJHQ!!!!j78?7R6=>BF +EndImage2 +EndChar + +StartChar: uni0000 +Encoding: 0 0 207 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 81 528 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(eI+]<#?K_A7/g?&&^F.'2BFD`:-S' +!";d,&&iB0%KHJ/!(fUS7'8jaJcGcN +EndImage2 +EndChar + +StartChar: Eth +Encoding: 208 208 208 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 99 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +576 2304 m 25,0,-1 + 768 2304 l 1,1,-1 + 768 1024 l 17,2,-1 + 1056 1024 l 1,3,-1 + 1056 768 l 1,4,-1 + 0 768 l 1,5,-1 + 0 1024 l 1,6,7 + 192 1024 192 1024 192 1024 c 129,-1,8 + 192 1024 192 1024 192 2304 c 1,9,-1 + 384 2304 l 1,10,-1 + 384 1024 l 1,11,-1 + 576 1024 l 9,12,13 + 576 1024 576 1024 576 2304 c 25,0,-1 +EndSplineSet +EndChar + +StartChar: Ntilde +Encoding: 209 209 209 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 94 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,tUKj<#?K_r!ro=GQ8Bu3Ns2<'JKS? +_Jgd+]314UfGmT3"9;^u%fm;4_$'f=!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 1280 m 1,0,-1 + 0 1536 l 1,1,-1 + 1056 1536 l 1,2,-1 + 1056 1280 l 1,3,-1 + 0 1280 l 1,0,-1 +192 0 m 1,4,-1 + 192 768 l 1,5,-1 + 0 768 l 1,6,-1 + 0 1024 l 1,7,-1 + 1056 1024 l 1,8,-1 + 1056 768 l 1,9,-1 + 384 768 l 1,10,-1 + 384 0 l 1,11,-1 + 192 0 l 1,4,-1 +EndSplineSet +EndChar + +StartChar: Ograve +Encoding: 210 210 210 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%"p:r!?Y +.Y]mEI1?6[%gWD#G;E1u!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +576 0 m 1,0,-1 + 576 768 l 1,1,2 + 576 768 576 768 384 768 c 1,3,-1 + 384 0 l 1,4,-1 + 192 0 l 1,5,6 + 192 379 192 379 192 768 c 1,7,8 + 0 768 0 768 0 768 c 129,-1,9 + 0 768 0 768 0 1024 c 1,10,-1 + 1056 1024 l 1,11,-1 + 1056 768 l 1,12,-1 + 768 768 l 1,13,-1 + 768 0 l 1,14,-1 + 576 0 l 1,0,-1 +2151 -1048 m 1049,15,-1 +EndSplineSet +EndChar + +StartChar: Oacute +Encoding: 211 211 211 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 95 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-:pTk<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pJu:VZ>csF8u:c?j%;QoDu8u!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +768 1024 m 1,0,-1 + 1056 1024 l 1,1,-1 + 1056 768 l 1,2,-1 + 192 768 l 1,3,-1 + 192 2304 l 25,4,-1 + 384 2304 l 25,5,-1 + 384 1024 l 1,6,7 + 576 1024 576 1024 576 1024 c 137,-1,8 + 576 1024 576 1024 576 2304 c 1,9,-1 + 768 2304 l 1,10,-1 + 768 1024 l 1,0,-1 +EndSplineSet +EndChar + +StartChar: Ocircumflex +Encoding: 212 212 212 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8CJNffG9N3T>a +/&3J4';Mi7Ci3[4f`e+TGmM@ufLu8F^?>eBB4:K7z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +384 1536 m 1,0,1 + 384 1536 384 1536 1056 1536 c 1,2,-1 + 1056 1280 l 1,3,-1 + 384 1280 l 1,4,5 + 384 1280 384 1280 384 1024 c 1,6,-1 + 1056 1024 l 1,7,-1 + 1056 768 l 1,8,9 + 624 768 624 768 192 768 c 1,10,11 + 192 1536 192 1536 192 2304 c 1,12,13 + 192 2304 192 2304 384 2304 c 1,14,-1 + 384 1536 l 1,0,1 +EndSplineSet +EndChar + +StartChar: Otilde +Encoding: 213 213 213 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 87 -768 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*_Aac<#?K_r!ro=GQ8Bu3O%!u-t$Rr +6ua"(D?'YV@0@+u1K<94!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +384 1024 m 1,0,1 + 384 1024 384 1024 1056 1024 c 1,2,3 + 1056 1024 1056 1024 1056 768 c 1,4,-1 + 384 768 l 1,5,-1 + 384 0 l 25,6,-1 + 192 0 l 1,7,-1 + 192 1536 l 1,8,9 + 192 1536 192 1536 1056 1536 c 1,10,-1 + 1056 1280 l 1,11,-1 + 384 1280 l 1,12,-1 + 384 1024 l 1,0,1 +EndSplineSet +EndChar + +StartChar: Odieresis +Encoding: 214 214 214 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 84 -768 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr +LuL,h)k-s@YSsU1z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +576 768 m 9,0,-1 + 384 768 l 17,1,2 + 384 768 384 768 384 0 c 1,3,-1 + 192 0 l 1,4,-1 + 192 1024 l 1,5,6 + 192 1024 192 1024 1056 1024 c 1,7,-1 + 1056 768 l 1,8,-1 + 768 768 l 1,9,-1 + 768 0 l 25,10,-1 + 576 0 l 1,11,-1 + 576 768 l 9,0,-1 +EndSplineSet +EndChar + +StartChar: multiply +Encoding: 215 215 215 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 99 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W.S3#o<#?K_r!ro=GQ8CJNffG9N+$O5 +oj@sE!pK!eTR[X<-k(#TVC"h6!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +576 1024 m 17,0,1 + 576 1024 576 1024 576 2304 c 1,2,-1 + 768 2304 l 1,3,-1 + 768 1024 l 1,4,-1 + 1056 1024 l 1,5,-1 + 1056 768 l 1,6,-1 + 768 768 l 1,7,-1 + 768 0 l 1,8,-1 + 576 0 l 1,9,-1 + 576 768 l 1,10,11 + 576 768 576 768 384 768 c 1,12,13 + 384 768 384 768 384 0 c 1,14,-1 + 192 0 l 1,15,-1 + 192 768 l 1,16,17 + 192 768 192 768 0 768 c 25,18,-1 + 0 1024 l 25,19,-1 + 192 1024 l 1,20,21 + 192 1024 192 1024 192 2304 c 1,22,-1 + 384 2304 l 1,23,-1 + 384 1024 l 9,24,-1 + 576 1024 l 17,0,1 +EndSplineSet +EndChar + +StartChar: Oslash +Encoding: 216 216 216 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 101 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W/4i5q<#?K_r!ro=GQ8Dg*$Z[QM@bLD +'NlQ6EWn#XG+r3WK'iqe%0TB*!8ts()gOU!N;rqY!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +384 1280 m 17,0,1 + 384 1280 384 1280 384 1024 c 1,2,3 + 720 1024 720 1024 1056 1024 c 1,4,-1 + 1056 768 l 1,5,6 + 1056 768 1056 768 384 768 c 1,7,8 + 384 768 384 768 384 0 c 1,9,-1 + 192 0 l 1,10,-1 + 192 768 l 1,11,12 + 192 768 192 768 0 768 c 25,13,-1 + 0 1024 l 25,14,-1 + 192 1024 l 1,15,16 + 192 1024 192 1024 192 1280 c 1,17,18 + 192 1280 192 1280 0 1280 c 25,19,-1 + 0 1536 l 25,20,-1 + 192 1536 l 17,21,22 + 192 1536 192 1536 192 2304 c 1,23,-1 + 384 2304 l 1,24,-1 + 384 1536 l 1,25,26 + 384 1536 384 1536 1056 1536 c 25,27,-1 + 1056 1280 l 25,28,-1 + 384 1280 l 17,0,1 +EndSplineSet +EndChar + +StartChar: Ugrave +Encoding: 217 217 217 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 93 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W,Y:Bi<#?K_r!ro=GQ8Dg*$Z[QM@bLD +'NlPk0IUVQiI*d!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +192 2304 m 1,0,-1 + 384 2304 l 1,1,-1 + 384 768 l 1,2,-1 + 0 768 l 1,3,-1 + 0 1024 l 1,4,-1 + 192 1024 l 1,5,-1 + 192 2304 l 1,0,-1 +EndSplineSet +EndChar + +StartChar: Uacute +Encoding: 218 218 218 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 84 -768 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W)bEF`<#?K_r!ro=GQ8Bu3O%#[<5?Sr +LuL,h)k-s@YSsU1z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 1024 m 1,0,-1 + 1056 1024 l 1,1,-1 + 1056 768 l 1,2,-1 + 384 768 l 1,3,-1 + 384 0 l 1,4,-1 + 192 0 l 1,5,-1 + 192 1024 l 1,0,-1 +EndSplineSet +EndChar + +StartChar: Ucircumflex +Encoding: 219 219 219 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 86 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*D&Xb<#?K_r!ro=GQ8sb%RU9&*[X"< +_,BF +EndImage2 +Fore +SplineSet +0 1024 m 1,0,-1 + 1056 1024 l 5,1,-1 + 1056 0 l 1,2,-1 + 0 0 l 1,3,-1 + 0 1024 l 1,0,-1 +EndSplineSet +EndChar + +StartChar: Yacute +Encoding: 221 221 221 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 86 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W*D&Xb<#?K_r!ro=GQ8sb%^#f$=scA# +_,6*`gl;[=2_b#`BT:ma%`@oq.KBGK!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +248 1024 m 0,0,1 + 192 1024 192 1024 192 949 c 0,2,3 + 192 949 192 949 192 587 c 0,4,5 + 192 512 192 512 248 512 c 24,6,7 + 248 512 248 512 328 512 c 0,8,9 + 384 512 384 512 384 587 c 24,10,11 + 384 587 384 587 384 949 c 0,12,13 + 384 1024 384 1024 328 1024 c 0,14,15 + 328 1024 328 1024 248 1024 c 0,0,1 +480 332 m 1,16,17 + 440 256 440 256 328 256 c 0,18,19 + 328 256 328 256 248 256 c 0,20,21 + 0 256 0 256 0 587 c 24,22,23 + 0 934 0 934 0 949 c 0,24,25 + 0 1280 0 1280 248 1280 c 24,26,27 + 248 1280 248 1280 328 1280 c 0,28,29 + 444 1280 444 1280 480 1204 c 1,30,31 + 520 1280 520 1280 632 1280 c 0,32,33 + 632 1280 632 1280 960 1280 c 1,34,35 + 960 1280 960 1280 960 1024 c 9,36,-1 + 632 1024 l 0,37,38 + 576 1024 576 1024 576 949 c 24,39,40 + 576 730 576 730 576 587 c 0,41,42 + 576 512 576 512 632 512 c 24,43,-1 + 960 512 l 25,44,45 + 960 512 960 512 960 256 c 1,46,47 + 960 256 960 256 632 256 c 0,48,49 + 522 256 522 256 480 332 c 1,16,17 +EndSplineSet +EndChar + +StartChar: aacute +Encoding: 225 225 225 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8sb%^#f$=sf>C +O9>hF14n#N!m44;>Ck%4QpksQJ/$sa,Y0dN8WYn3ei4fJ=9.5"z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 768 m 25,0,-1 + 192 512 l 25,1,-1 + 384 512 l 25,2,-1 + 384 331 l 0,3,4 + 384 256 384 256 440 256 c 24,5,6 + 440 256 440 256 520 256 c 0,7,8 + 576 256 576 256 576 331 c 24,9,10 + 576 331 576 331 576 693 c 0,11,12 + 576 768 576 768 520 768 c 24,13,14 + 520 768 520 768 192 768 c 25,0,-1 +192 1280 m 25,15,-1 + 192 1024 l 25,16,17 + 192 1024 192 1024 520 1024 c 0,18,19 + 576 1024 576 1024 576 1099 c 24,20,21 + 576 1099 576 1099 576 1205 c 0,22,23 + 576 1280 576 1280 520 1280 c 24,24,25 + 520 1280 520 1280 192 1280 c 25,15,-1 +711 896 m 1,26,27 + 768 842 768 842 768 693 c 0,28,29 + 768 693 768 693 768 331 c 0,30,31 + 768 0 768 0 520 0 c 24,32,33 + 520 0 520 0 440 0 c 1,34,35 + 192 0 192 0 192 256 c 1,36,-1 + 192 -256 l 25,37,-1 + 0 -256 l 25,38,-1 + 0 1536 l 25,39,40 + 2 1536 2 1536 520 1536 c 0,41,42 + 768 1536 768 1536 768 1205 c 24,43,44 + 768 1205 768 1205 768 1099 c 0,45,46 + 768 946 768 946 711 896 c 1,26,27 +EndSplineSet +EndChar + +StartChar: acircumflex +Encoding: 226 226 226 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 107 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W1.al"<#?K_r!ro=GQ8sb%RU9&*YsiL +A-#.hO<+O4685[N0GGY!#1A*s!8SX;'`\49X:>FZOH&o5!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +0 1536 m 25,0,-1 + 960 1536 l 25,1,-1 + 960 768 l 25,2,-1 + 768 768 l 25,3,-1 + 768 1280 l 25,4,-1 + 192 1280 l 25,5,-1 + 192 -256 l 25,6,-1 + 0 -256 l 25,7,-1 + 0 1536 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: atilde +Encoding: 227 227 227 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd6aopatdkIg/>!Ysc,LC*42o(@Wd/YKm'_qdrA2aJg!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 1024 m 25,0,-1 + 960 1024 l 25,1,-1 + 960 768 l 25,2,-1 + 768 768 l 25,3,-1 + 768 0 l 25,4,-1 + 576 0 l 25,5,-1 + 576 768 l 25,6,-1 + 384 768 l 25,7,-1 + 384 0 l 25,8,-1 + 192 0 l 25,9,-1 + 192 768 l 25,10,-1 + 0 768 l 25,11,-1 + 0 1024 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: adieresis +Encoding: 228 228 228 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 125 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W6qKd4<#?L$NmS16+:&'JqYsnT:U#R> +HVi@4QEAO/ai!o+2:#'fHA[3!]Kabmt6t]^qt2z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +0 1024 m 25,0,-1 + 192 1024 l 25,1,-1 + 192 331 l 0,2,3 + 192 256 192 256 248 256 c 24,4,5 + 248 256 248 256 520 256 c 0,6,7 + 576 256 576 256 576 331 c 24,8,-1 + 576 512 l 25,9,-1 + 768 512 l 25,10,-1 + 768 1024 l 25,11,-1 + 960 1024 l 25,12,-1 + 960 -256 l 25,13,-1 + 768 -256 l 25,14,-1 + 768 256 l 17,15,16 + 768 0 768 0 520 0 c 8,17,18 + 520 0 520 0 248 0 c 0,19,20 + 0 0 0 0 0 331 c 24,21,22 + 0 331 0 331 0 1024 c 25,0,-1 +EndSplineSet +EndChar + +StartChar: ccedilla +Encoding: 231 231 231 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8Bu3Ns2`"cP]X +(fhd6ao^TW1,:W#fZ;VV["BF +EndImage2 +Fore +SplineSet +712 1536 m 0,0,1 + 960 1536 960 1536 960 1205 c 24,2,3 + 960 1205 960 1205 960 768 c 0,4,5 + 960 512 960 512 768 512 c 9,6,7 + 768 512 768 512 768 256 c 25,8,9 + 768 256 768 256 960 256 c 1,10,-1 + 960 0 l 25,11,-1 + 576 0 l 25,12,13 + 576 0 576 0 576 512 c 17,14,15 + 576 768 576 768 768 768 c 8,16,17 + 768 768 768 768 768 1205 c 0,18,19 + 768 1280 768 1280 712 1280 c 24,20,21 + 712 1280 712 1280 248 1280 c 0,22,23 + 192 1280 192 1280 192 1205 c 24,24,25 + 192 1205 192 1205 192 768 c 17,26,27 + 384 768 384 768 384 512 c 8,28,29 + 384 512 384 512 384 0 c 25,30,-1 + 0 0 l 25,31,-1 + 0 256 l 25,32,-1 + 192 256 l 25,33,34 + 192 256 192 256 192 512 c 17,35,36 + 0 512 0 512 0 768 c 8,37,38 + 0 768 0 768 0 1205 c 0,39,40 + 0 1536 0 1536 248 1536 c 24,41,42 + 248 1536 248 1536 712 1536 c 0,0,1 +EndSplineSet +EndChar + +StartChar: edieresis +Encoding: 235 235 235 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 112 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2b?D'<#?K_r!ro=GQ8CJNffG9N3T?l +":F-GKEYlga93>F[h6L\OCD`h?oPlCA"s>[+Qs"0N05+aQb:>%z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +768 949 m 0,0,1 + 768 1024 768 1024 712 1024 c 24,2,3 + 712 1024 712 1024 248 1024 c 0,4,5 + 192 1024 192 1024 192 949 c 24,6,7 + 192 949 192 949 192 331 c 0,8,9 + 192 256 192 256 248 256 c 24,10,11 + 248 256 248 256 712 256 c 0,12,13 + 768 256 768 256 768 331 c 24,14,15 + 768 331 768 331 768 949 c 0,0,1 +576 1792 m 25,16,-1 + 576 1536 l 25,17,-1 + 248 1536 l 0,18,19 + 192 1536 192 1536 192 1461 c 24,20,21 + 192 1461 192 1461 192 1355 c 0,22,23 + 192 1280 192 1280 248 1280 c 24,24,-1 + 712 1280 l 0,25,26 + 960 1280 960 1280 960 949 c 24,27,28 + 960 949 960 949 960 331 c 0,29,30 + 960 0 960 0 712 0 c 24,31,32 + 712 0 712 0 248 0 c 0,33,34 + 0 0 0 0 0 331 c 24,35,36 + 0 331 0 331 0 949 c 17,37,38 + 0 1280 0 1280 192 1280 c 9,39,-1 + 0 1280 l 25,40,41 + 0 1282 0 1282 0 1461 c 0,42,43 + 0 1792 0 1792 248 1792 c 24,44,45 + 248 1792 248 1792 576 1792 c 25,16,-1 +EndSplineSet +EndChar + +StartChar: igrave +Encoding: 236 236 236 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?K_r!ro=GQ8Bu3Ns3"!@&g6 +Qij+G2)0Xb6+.ob-jl%rf[rm]]$]?X#S`rU(BEC4(C_Jt"T8<#!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +768 1205 m 0,0,1 + 768 1280 768 1280 712 1280 c 24,2,3 + 712 1280 712 1280 632 1280 c 0,4,5 + 576 1280 576 1280 576 1205 c 24,6,7 + 576 1205 576 1205 576 843 c 0,8,9 + 576 768 576 768 632 768 c 24,10,11 + 632 768 632 768 712 768 c 0,12,13 + 768 768 768 768 768 843 c 24,14,15 + 768 843 768 843 768 1205 c 0,0,1 +248 1280 m 0,16,17 + 192 1280 192 1280 192 1205 c 24,18,19 + 192 1205 192 1205 192 843 c 0,20,21 + 192 768 192 768 248 768 c 24,22,23 + 248 768 248 768 328 768 c 0,24,25 + 384 768 384 768 384 843 c 24,26,27 + 384 843 384 843 384 1205 c 0,28,29 + 384 1280 384 1280 328 1280 c 24,30,31 + 328 1280 328 1280 248 1280 c 0,16,17 +480 588 m 1,32,33 + 442 512 442 512 328 512 c 0,34,35 + 248 512 248 512 248 512 c 0,36,37 + 0 512 0 512 0 843 c 0,38,39 + 0 1205 0 1205 0 1205 c 0,40,41 + 0 1536 0 1536 248 1536 c 24,42,43 + 328 1536 328 1536 328 1536 c 0,44,45 + 444 1536 444 1536 480 1460 c 1,46,47 + 517 1536 517 1536 632 1536 c 0,48,49 + 712 1536 712 1536 712 1536 c 0,50,51 + 960 1536 960 1536 960 1205 c 24,52,53 + 960 843 960 843 960 843 c 0,54,55 + 960 512 960 512 712 512 c 0,56,57 + 632 512 632 512 632 512 c 0,58,59 + 518 512 518 512 480 588 c 1,32,33 +EndSplineSet +EndChar + +StartChar: iacute +Encoding: 237 237 237 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 121 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W5Y4@0<#?L$:'h7-+:*&es3Ke[NKS6' +,.kcg`.0^a7?mjBF +EndImage2 +Fore +SplineSet +0 512 m 25,0,-1 + 960 512 l 25,1,-1 + 960 256 l 25,2,-1 + 0 256 l 25,3,-1 + 0 512 l 25,0,-1 +0 1024 m 25,4,-1 + 960 1024 l 25,5,-1 + 960 768 l 25,6,-1 + 0 768 l 25,7,-1 + 0 1024 l 25,4,-1 +0 1536 m 25,8,-1 + 960 1536 l 25,9,-1 + 960 1280 l 25,10,-1 + 0 1280 l 25,11,-1 + 0 1536 l 25,8,-1 +EndSplineSet +EndChar + +StartChar: ntilde +Encoding: 241 241 241 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 114 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3CuV)<#?K_r!ro=GQ8CNNffG9`^HNZ +$;a-Q3$<&T!ong4J?b4F?m'+d>QHb=+Hm)B!<>"K'`g-2+2\'Y!!#SZ:.26O@"J@Y +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +384 1792 m 25,4,-1 + 576 1792 l 25,5,-1 + 576 1280 l 25,6,-1 + 960 1280 l 25,7,-1 + 960 1024 l 25,8,-1 + 576 1024 l 25,9,-1 + 576 512 l 25,10,-1 + 384 512 l 25,11,-1 + 384 1024 l 25,12,-1 + 0 1024 l 25,13,-1 + 0 1280 l 25,14,-1 + 384 1280 l 25,15,-1 + 384 1792 l 25,4,-1 +EndSplineSet +EndChar + +StartChar: ograve +Encoding: 242 242 242 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 113 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3(ZM(<#?K_r!ro=GQ8C%,9n7D"pQE9 +!Vd?`J[FH9"BL%K&R5>h748LNMEj!,J@pEk9k9ju!.ec!#8A0)mJm4e!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +136 1792 m 25,4,-1 + 960 693 l 25,5,-1 + 960 512 l 25,6,-1 + 824 512 l 25,7,-1 + 0 1611 l 25,8,-1 + 0 1792 l 25,9,-1 + 136 1792 l 25,4,-1 +EndSplineSet +EndChar + +StartChar: oacute +Encoding: 243 243 243 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?L$:.Z&u+:&>Ss5s_"%Pf=X +LK3]!2'?-+d&:QLk_3SmM6'=e:S`Poj.G;"9I[85$/QR]hLZRG"t\K.z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +0 256 m 25,0,-1 + 960 256 l 25,1,-1 + 960 0 l 25,2,-1 + 0 0 l 25,3,-1 + 0 256 l 25,0,-1 +0 693 m 25,4,-1 + 824 1792 l 25,5,-1 + 960 1792 l 25,6,-1 + 960 1611 l 25,7,-1 + 136 512 l 25,8,-1 + 0 512 l 25,9,-1 + 0 693 l 25,4,-1 +EndSplineSet +EndChar + +StartChar: ocircumflex +Encoding: 244 244 244 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 106 -384 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W0hFc!<#?K_r!ro=GQ8D_*$Z[Q1)J/h +.f`.m$q")!=+HtZ.Y+2mh+8FjcqU6>!%hZBF +EndImage2 +Fore +SplineSet +248 0 m 0,0,1 + 0 0 0 0 0 331 c 24,2,3 + 0 331 0 331 0 768 c 25,4,-1 + 192 768 l 25,5,-1 + 192 331 l 0,6,7 + 192 256 192 256 248 256 c 24,8,9 + 248 256 248 256 328 256 c 0,10,11 + 384 256 384 256 384 331 c 24,12,-1 + 384 1792 l 25,13,-1 + 576 1792 l 25,14,15 + 576 1792 576 1792 576 331 c 0,16,17 + 576 0 576 0 328 0 c 24,18,19 + 328 0 328 0 248 0 c 0,0,1 +EndSplineSet +EndChar + +StartChar: odieresis +Encoding: 246 246 246 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 104 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W01ePt<#?K_r!ro=GQ8Bu3Ns3&!@&g6 +F7*dd,#*D0*"!4IN'+.>uci6z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +0 437 m 0,0,1 + 0 768 0 768 248 768 c 24,2,-1 + 712 768 l 0,3,4 + 768 768 768 768 768 843 c 24,5,-1 + 768 1024 l 25,6,-1 + 960 1024 l 25,7,8 + 960 1024 960 1024 960 843 c 0,9,10 + 960 512 960 512 712 512 c 24,11,-1 + 248 512 l 0,12,13 + 192 512 192 512 192 437 c 24,14,-1 + 192 256 l 25,15,-1 + 0 256 l 25,16,17 + 0 256 0 256 0 437 c 0,0,1 +0 1205 m 0,18,19 + 0 1536 0 1536 248 1536 c 24,20,-1 + 712 1536 l 0,21,22 + 768 1536 768 1536 768 1611 c 24,23,-1 + 768 1792 l 25,24,-1 + 960 1792 l 25,25,26 + 960 1792 960 1792 960 1611 c 0,27,28 + 960 1280 960 1280 712 1280 c 24,29,-1 + 248 1280 l 0,30,31 + 192 1280 192 1280 192 1205 c 24,32,-1 + 192 1024 l 25,33,-1 + 0 1024 l 25,34,35 + 0 1024 0 1024 0 1205 c 0,18,19 +EndSplineSet +EndChar + +StartChar: oslash +Encoding: 248 248 248 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 115 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W3_;_*<#?K_r!ro=GQ8CJNffG9N3T?l +":E!T!@^DqO9Hm0OoPN)8WXbs/d[V!#_:_2@:CT5fEr&3)!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +520 1536 m 0,0,1 + 520 1536 520 1536 248 1536 c 0,2,3 + 192 1536 192 1536 192 1461 c 24,4,5 + 192 1461 192 1461 192 1355 c 0,6,7 + 192 1280 192 1280 248 1280 c 24,8,9 + 248 1280 248 1280 520 1280 c 0,10,11 + 576 1280 576 1280 576 1355 c 24,12,13 + 576 1355 576 1355 576 1461 c 0,14,15 + 576 1536 576 1536 520 1536 c 0,0,1 +520 1792 m 0,16,17 + 768 1792 768 1792 768 1461 c 24,18,19 + 768 1461 768 1461 768 1355 c 0,20,21 + 768 1024 768 1024 520 1024 c 24,22,23 + 520 1024 520 1024 248 1024 c 0,24,25 + 0 1024 0 1024 0 1355 c 24,26,27 + 0 1355 0 1355 0 1461 c 0,28,29 + 0 1792 0 1792 248 1792 c 24,30,31 + 248 1792 248 1792 520 1792 c 0,16,17 +EndSplineSet +EndChar + +StartChar: ugrave +Encoding: 249 249 249 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 116 -192 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4%Vh+<#?K_r!ro=GQ8Bu3Ns4f$5aWu +)*f#ZJ5&:p5\>W_K,#N@':B;-^]G]F!*oXM$8hk(_+"M,dDQJ+QNPW^z8OZBBY!QNJ +EndImage2 +Fore +SplineSet +192 1280 m 25,0,-1 + 576 1280 l 25,1,-1 + 576 1024 l 25,2,-1 + 768 1024 l 25,3,-1 + 768 768 l 25,4,-1 + 576 768 l 25,5,-1 + 576 512 l 25,6,-1 + 192 512 l 25,7,-1 + 192 768 l 25,8,-1 + 0 768 l 25,9,-1 + 0 1024 l 25,10,-1 + 192 1024 l 25,11,-1 + 192 1280 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: uacute +Encoding: 250 250 250 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 97 -384 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W-qQfm<#?K_r!ro=GQ8Bu3Ns24'ehBu +@^QY_"YR:$'k#Q%'I9UW!%-V/$md\(4TGH^!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +0 1024 m 29,0,-1 + 192 1024 l 25,1,-1 + 192 768 l 25,2,-1 + 0 768 l 25,3,-1 + 0 1024 l 29,0,-1 +EndSplineSet +EndChar + +StartChar: ucircumflex +Encoding: 251 251 251 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 117 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W4@qq,<#?K_r!ro=GQ8+FNffG9`ah?c +"'5Jc7@&J'AqDaVd7hVN@oGeJ"H^;>;m=pc1(e=(/kM-+!-+VE$NJqlp](9o!(fUS7'8jaJcGcN +EndImage2 +Fore +SplineSet +384 1792 m 25,0,-1 + 960 1792 l 25,1,-1 + 960 1536 l 25,2,-1 + 576 1536 l 25,3,-1 + 576 587 l 0,4,5 + 576 256 576 256 328 256 c 24,6,7 + 328 256 328 256 248 256 c 0,8,9 + 0 256 0 256 0 587 c 16,10,11 + 0 587 0 587 0 1024 c 9,12,-1 + 192 1024 l 25,13,-1 + 192 587 l 0,14,15 + 192 512 192 512 248 512 c 24,16,17 + 248 512 248 512 328 512 c 0,18,19 + 384 512 384 512 384 587 c 24,20,-1 + 384 1792 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: udieresis +Encoding: 252 252 252 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 111 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2G$;&<#?K_r!ro=GQ8Bu3Ns2`"cP]X +E%A0G"uZK-!Q'eS+SD[`TG7SE0ER5g])gH$#S-plN=l21\-JE%!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +0 1280 m 25,0,1 + 0 1280 0 1280 520 1280 c 0,2,3 + 768 1280 768 1280 768 949 c 24,4,5 + 768 949 768 949 768 256 c 25,6,-1 + 576 256 l 25,7,-1 + 576 949 l 0,8,9 + 576 1024 576 1024 520 1024 c 24,10,11 + 520 1024 520 1024 192 1024 c 25,12,-1 + 192 256 l 25,13,-1 + 0 256 l 25,14,-1 + 0 1280 l 25,0,1 +EndSplineSet +EndChar + +StartChar: yacute +Encoding: 253 253 253 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 110 0 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W2+^2%<#?L$N'RdN0FYgqo`&:TWj&8\ +<%ndLEXLID6LpLu+!mRNL72;b6E@ +(`=3"9Eo$3$(=,i!k922m=dV+a8c2MpBh@PrMsB-!!!!j78?7R6=>BF +EndImage2 +Fore +SplineSet +0 1280 m 25,0,-1 + 576 1280 l 25,1,-1 + 576 256 l 25,2,-1 + 0 256 l 25,3,-1 + 0 1280 l 25,0,-1 +EndSplineSet +EndChar + +StartChar: ydieresis +Encoding: 255 255 255 +Width: 1152 +VWidth: 2048 +Flags: MW +LayerCount: 2 +Back +Image2: image/png 79 1104 2048 192 256 +M,6r;%14!\!!!!.8Ou6I!!!!)!!!!)#R18/!5oD^MZ<_W(.gn[<#?K_r!ro=GQ8Bu3O%$&:]LJ7 +D?LB^-QJHQ!!!!j78?7R6=>BF +EndImage2 +EndChar +EndChars +EndSplineFont diff --git a/resources/lsi-adm-3a/adm-3a.sfd b/resources/lsi-adm-3a/adm-3a.sfd index 1e82d176f..2561df5d7 100644 --- a/resources/lsi-adm-3a/adm-3a.sfd +++ b/resources/lsi-adm-3a/adm-3a.sfd @@ -22,7 +22,7 @@ OS2Version: 0 OS2_WeightWidthSlopeOnly: 0 OS2_UseTypoMetrics: 0 CreationTime: 1663397476 -ModificationTime: 1678351325 +ModificationTime: 1679220896 PfmFamily: 49 TTFWeight: 400 TTFWidth: 5 @@ -52,7 +52,7 @@ NameList: AGL For New Fonts DisplaySize: -48 AntiAlias: 1 FitToEm: 0 -WinInfo: 0 17 19 +WinInfo: 0 51 19 BeginPrivate: 0 EndPrivate Grid @@ -2805,23 +2805,19 @@ SplineSet 640 1333 640 1333 1099 1792 c 0,2,3 1099 1792 1099 1792 1280 1792 c 25,4,-1 1280 0 l 25,5,-1 - 1024 0 l 25,6,-1 - 1024 1280 l 24,7,8 - 1024 1280 1024 1280 949 1280 c 24,9,10 - 949 1280 949 1280 768 1099 c 1,11,-1 - 768 825 l 0,12,13 - 768 768 768 768 640 768 c 128,-1,14 - 512 768 512 768 512 825 c 0,15,-1 - 512 1099 l 1,16,17 - 512 1099 512 1099 331 1280 c 24,18,19 - 331 1280 331 1280 256 1280 c 25,20,-1 - 256 0 l 25,21,-1 - 0 0 l 25,22,-1 - 0 1792 l 25,23,24 - 0 1792 0 1792 181 1792 c 0,25,-1 + 1024 0 l 1,6,-1 + 1024 1355 l 25,7,8 + 1024 1355 1024 1355 768 1099 c 1,9,-1 + 768 768 l 1,10,11 + 768 768 768 768 512 768 c 1,12,-1 + 512 1099 l 1,13,14 + 512 1099 512 1099 256 1355 c 25,15,-1 + 256 0 l 1,16,-1 + 0 0 l 25,17,-1 + 0 1792 l 25,18,19 + 0 1792 0 1792 181 1792 c 0,20,-1 640 1333 l 1,0,1 EndSplineSet -Validated: 1 EndChar StartChar: N @@ -3159,18 +3155,16 @@ SplineSet 256 1792 l 25,6,-1 256 437 l 24,7,-1 512 693 l 0,8,-1 - 512 967 l 16,9,10 - 575 1024 575 1024 639 1024 c 128,-1,11 - 703 1024 703 1024 768 967 c 0,12,13 - 768 967 768 967 768 693 c 0,14,-1 - 1024 437 l 24,15,-1 - 1024 1792 l 25,16,-1 - 1280 1792 l 25,17,-1 - 1280 0 l 25,18,19 - 1099 0 1099 0 1099 0 c 0,20,21 + 512 1024 l 1,9,10 + 512 1024 512 1024 768 1024 c 1,11,12 + 768 1024 768 1024 768 693 c 0,13,-1 + 1024 437 l 24,14,-1 + 1024 1792 l 25,15,-1 + 1280 1792 l 25,16,-1 + 1280 0 l 25,17,18 + 1099 0 1099 0 1099 0 c 0,19,20 640 459 640 459 640 459 c 1,0,1 EndSplineSet -Validated: 1 EndChar StartChar: X @@ -7707,7 +7701,7 @@ StartChar: Eth Encoding: 208 208 208 Width: 1408 VWidth: 2048 -Flags: MWO +Flags: MW LayerCount: 2 Back Image2: image/png 99 0 2048 256 256 diff --git a/resources/lsi-adm-3a/adm-3a.ttf b/resources/lsi-adm-3a/adm-3a.ttf index 4da285c7f922db3771f1be055807fe96c0400dcf..8579e7f824fb4f5a4f8d2db4d73aa6976f236425 100644 GIT binary patch delta 17334 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 Ap#T5? From a2b218de5368a2e405e12b850979ddd35baa4e87 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 21 Mar 2023 09:15:10 +0100 Subject: [PATCH 310/314] [#315] byte-mem: fix ASCII mode --- .../plugins/memory/bytemem/gui/MemoryGui.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java index 8af78aa96..6b4f72c55 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/MemoryGui.java @@ -34,6 +34,7 @@ import java.awt.event.WindowEvent; import java.util.Objects; +import static javax.swing.Action.SHORT_DESCRIPTION; import static net.emustudio.emulib.runtime.helpers.RadixUtils.formatBinaryString; public class MemoryGui extends JDialog { @@ -51,12 +52,12 @@ public class MemoryGui extends JDialog { private final JTextField txtValueDec = new JTextField("00"); private final JTextField txtValueHex = new JTextField("00"); private final JTextField txtValueOct = new JTextField("000"); + private final JToggleButton btnAsciiMode = new JToggleButton(); private final LoadImageAction loadImageAction; private final DumpMemoryAction dumpMemoryAction; private final GotoAddressAction gotoAddressAction; private final FindSequenceAction findSequenceAction; - private final AsciiModeAction asciiModeAction; private final EraseMemoryAction eraseMemoryAction; private final SettingsAction settingsAction; @@ -80,8 +81,13 @@ public MemoryGui(JFrame parent, MemoryImpl memory, MemoryContextImpl context, Pl this.gotoAddressAction = new GotoAddressAction(dialogs, context, this::setPageFromAddress); this.findSequenceAction = new FindSequenceAction(dialogs, this::setPageFromAddress, tableModel, this::getCurrentAddress, this); - JToggleButton btnAsciiMode = new JToggleButton(); - this.asciiModeAction = new AsciiModeAction(tableModel, btnAsciiMode); + + AsciiModeAction asciiModeAction = new AsciiModeAction(tableModel, btnAsciiMode); + btnAsciiMode.setAction(asciiModeAction); + btnAsciiMode.setHideActionText(true); + btnAsciiMode.setToolTipText(String.valueOf(asciiModeAction.getValue(SHORT_DESCRIPTION))); + btnAsciiMode.setFocusable(false); + this.eraseMemoryAction = new EraseMemoryAction(tableModel, context); this.settingsAction = new SettingsAction(dialogs, this, memory, context, table, settings); @@ -180,7 +186,7 @@ private void initComponents() { toolBar.add(new ToolbarButton(gotoAddressAction)); toolBar.add(new ToolbarButton(findSequenceAction)); toolBar.addSeparator(); - toolBar.add(new ToolbarButton(asciiModeAction)); + toolBar.add(btnAsciiMode); toolBar.addSeparator(); toolBar.add(new ToolbarButton(eraseMemoryAction)); toolBar.addSeparator(); From 2041ea59ce00a67975322638e8bbfa74682ae253 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 21 Mar 2023 09:19:44 +0100 Subject: [PATCH 311/314] [#315] byte-mem: Fixed find sequence button --- .../plugins/memory/bytemem/gui/FindSequenceDialog.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java index 41c3d1953..81dfda61c 100644 --- a/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java +++ b/plugins/memory/byte-mem/src/main/java/net/emustudio/plugins/memory/bytemem/gui/FindSequenceDialog.java @@ -32,6 +32,7 @@ public class FindSequenceDialog extends JDialog { private final JRadioButton radioPlainText = new JRadioButton(); private final JTextField txtPosition = new JTextField(); private final JTextField txtSequence = new JTextField(); + public FindSequenceDialog(Dialogs dialogs, JDialog parent, MemoryTableModel tableModel, int currentAddress, Consumer setFoundAddress) { super(parent, true); @@ -59,6 +60,9 @@ private void initComponents() { btnGroupStartPosition.add(radioSpecificPosition); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + + btnFind.setText("Find"); + getRootPane().setDefaultButton(btnFind); getRootPane().registerKeyboardAction(e -> dispose(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); setTitle("Find sequence"); From b1f9844fbc13b6275c964fbd302c32af65859778 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 25 Mar 2023 07:39:42 +0100 Subject: [PATCH 312/314] [#315] update 88-dcdd icons on startup --- .../device/mits88dcdd/gui/SettingsDialog.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java index 8626f962d..b8525ffd4 100644 --- a/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java +++ b/plugins/device/88-dcdd/src/main/java/net/emustudio/plugins/device/mits88dcdd/gui/SettingsDialog.java @@ -118,6 +118,18 @@ public SettingsDialog(JFrame parent, DiskSettings settings, DriveCollection driv driveButtons.add(btnP); btnA.setSelected(true); + // update icons + drives.foreach((i, drive) -> { + DriveSettingsUI dsui = driveSettingsUI.get(i); + Optional + .ofNullable(dsui.image) + .filter(p -> !p.equals("")) + .map(Path::of) + .ifPresentOrElse( + path -> driveButtons.get(i).setIcon(ON_ICON), + () -> driveButtons.get(i).setIcon(OFF_ICON)); + return null; + }); updateGUI(0); } From b744944cfde108c6a3d20793833dab72d3ab6d2b Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 25 Mar 2023 10:34:58 +0100 Subject: [PATCH 313/314] [#315] automation: instruction location 0x --- .../java/net/emustudio/application/emulation/Automation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/net/emustudio/application/emulation/Automation.java b/application/src/main/java/net/emustudio/application/emulation/Automation.java index cbbf5ff92..41ed7f8bf 100644 --- a/application/src/main/java/net/emustudio/application/emulation/Automation.java +++ b/application/src/main/java/net/emustudio/application/emulation/Automation.java @@ -236,7 +236,7 @@ public void internalStateChanged() { LOGGER.error("Invalid state (" + resultState + ")"); break; } - LOGGER.info("Instruction location = " + String.format("%04Xh", cpu.getInstructionLocation())); + LOGGER.info("Instruction location = " + String.format("0x%04X", cpu.getInstructionLocation())); setProgress("Emulation completed", false); } From 91f5d158bef9a6be5b13c9955a80bb105839d941 Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Sat, 25 Mar 2023 10:50:01 +0100 Subject: [PATCH 314/314] [#334] Remove .SNAPSHOT --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 27e8de680..488c5e17a 100644 --- a/build.gradle +++ b/build.gradle @@ -52,7 +52,7 @@ ext.libs = [ ] allprojects { - version = '0.41-SNAPSHOT' + version = '0.41' configurations { compilerLib